Add files via upload
This commit is contained in:
parent
4059938c56
commit
992d2b8e09
25
Readme.md
25
Readme.md
@ -1,7 +1,7 @@
|
||||
# Toshiba Electronic Devices & Storage Corporation TC956X PCIe Ethernet Host Driver
|
||||
Release Date: 05 Jul 2021
|
||||
Release Date: 15 Jul 2021
|
||||
|
||||
Release Version: V_01-00-01 : Limited-tested version
|
||||
Release Version: V_01-00-02 : Limited-tested version
|
||||
|
||||
TC956X PCIe EMAC driver is based on "Fedora 30, kernel-5.4.19".
|
||||
|
||||
@ -40,6 +40,12 @@ TC956X PCIe EMAC driver is based on "Fedora 30, kernel-5.4.19".
|
||||
5. API to print IPA DMA channel statistics supported
|
||||
6. Correction of print statement about selection of C45 PHY for Port0 interface
|
||||
|
||||
## TC956X_Host_Driver_20210705_V_01-00-02:
|
||||
|
||||
1. XFI interface supported through compile time macro.
|
||||
2. Removed module parameters for selection of Port0 and Port1 interface
|
||||
3. Debugfs support for IPA statistics
|
||||
|
||||
# Note:
|
||||
|
||||
1. Use below commands to advertise with Autonegotiation ON for speeds 10Gbps, 5Gbps, 2.5Gbps, 1Gbps, 100Mbps and 10Mbps as ethtool speed command does not support.
|
||||
@ -56,17 +62,8 @@ TC956X PCIe EMAC driver is based on "Fedora 30, kernel-5.4.19".
|
||||
|
||||
ethtool -s <interface> advertise 0x002 autoneg on --> changes the advertisement 10Mbps
|
||||
|
||||
2. Use the below command to insert the kernel module with specific modes for interfaces:
|
||||
|
||||
#insmod tc956x_pcie_eth.ko tc956x_port0_interface=x tc956x_port1_interface=y
|
||||
|
||||
argument info:
|
||||
tc956x_port0_interface: For PORT0 interface mode setting
|
||||
tc956x_port1_interface: For PORT1 interface mode setting
|
||||
x = [0: USXGMII, 1: XFI (default), 2: RGMII (unsupported), 3: SGMII]
|
||||
y = [0: USXGMII (unsupported), 1: XFI (unsupported), 2: RGMII, 3: SGMII(default)]
|
||||
|
||||
If invalid and unsupported modes are passed as kernel module parameter, the default interface mode will be selected.
|
||||
2. To select XFI interface, enable macro "#define TC956X_USXGMII_XFI_MODE" in tc956xmac_inc.h.
|
||||
If undefined, USXGMII interface will be selected. By default this macro is defined.
|
||||
|
||||
3. Regarding the performance, use the below command to increase the dynamic byte queue limit
|
||||
|
||||
@ -91,4 +88,4 @@ TC956X PCIe EMAC driver is based on "Fedora 30, kernel-5.4.19".
|
||||
tx_intr_n = No of. Tx interrupts originating from eMAC
|
||||
sw_msi_n = No. of SW MSIs triggered by Systick Handler as part of optimized Tx Timer based on Systick approach.
|
||||
So total number of interrupts for Tx = tx_intr_n + sw_msi_n
|
||||
Please note that whenever Rx interruts are generated, the Host ISR will process the Tx completed descriptors too.
|
||||
Please note that whenever Rx interruts are generated, the Host ISR will process the Tx completed descriptors too.
|
12
common.h
12
common.h
@ -34,6 +34,8 @@
|
||||
* 05 Jul 2021 : 1. Used Systick handler instead of Driver kernel timer to process transmitted Tx descriptors.
|
||||
* 2. XFI interface support and module parameters for selection of Port0 and Port1 interface
|
||||
* VERSION : 01-00-01
|
||||
* 15 Jul 2021 : 1. USXGMII/XFI/SGMII/RGMII interface supported without module parameter
|
||||
* VERSION : 01-00-02
|
||||
*/
|
||||
|
||||
#ifndef __COMMON_H__
|
||||
@ -99,7 +101,9 @@
|
||||
#define ETH_CORE_DUMP_OFFSET6 (0x1140 / 4)
|
||||
#define ETH_CORE_DUMP_OFFSET6_END (0x1174 / 4)
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#define CONFIG_DEBUG_FS_TC956X
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS_TC956X
|
||||
|
||||
#ifdef TC956X
|
||||
int tc956xmac_init(void);
|
||||
@ -1287,7 +1291,11 @@ enum dma_irq_status {
|
||||
handle_rx = 0x4,
|
||||
handle_tx = 0x8,
|
||||
};
|
||||
|
||||
enum SGMII_2P5G_SUPPORT {
|
||||
SGMII_2P5G_DISABLED = 0, /* For SGMII Speed 1G */
|
||||
SGMII_2P5G_ENABLED = 1, /* For SGMII Speed 2.5G */
|
||||
SGMII_DISABLED = 3, /* For other interfaces (USXGMII/RGMII) */
|
||||
};
|
||||
/* EEE and LPI defines */
|
||||
#define CORE_IRQ_TX_PATH_IN_LPI_MODE (1 << 0)
|
||||
#define CORE_IRQ_TX_PATH_EXIT_LPI_MODE (1 << 1)
|
||||
|
@ -34,6 +34,8 @@
|
||||
* 05 Jul 2021 : 1. Used Systick handler instead of Driver kernel timer to process transmitted Tx descriptors.
|
||||
* 2. XFI interface support and module parameters for selection of Port0 and Port1 interface
|
||||
* VERSION : 01-00-01
|
||||
* 15 Jul 2021 : 1. USXGMII/XFI/SGMII/RGMII interface supported without module parameter
|
||||
* VERSION : 01-00-02
|
||||
*/
|
||||
|
||||
#include <linux/bitrev.h>
|
||||
@ -68,8 +70,7 @@ static void dwxgmac2_core_init(struct tc956xmac_priv *priv,
|
||||
tx |= hw->link.xgmii.speed10000;
|
||||
break;
|
||||
case SPEED_2500:
|
||||
if (priv->plat->interface == PHY_INTERFACE_MODE_SGMII)
|
||||
tx |= hw->link.speed2500;
|
||||
tx |= hw->link.speed2500;
|
||||
break;
|
||||
case SPEED_1000:
|
||||
default:
|
||||
@ -82,8 +83,7 @@ static void dwxgmac2_core_init(struct tc956xmac_priv *priv,
|
||||
tx |= hw->link.speed1000;
|
||||
else if (priv->plat->interface == PHY_INTERFACE_MODE_SGMII)
|
||||
tx |= hw->link.speed2500;
|
||||
else if ((priv->plat->interface == PHY_INTERFACE_MODE_USXGMII) ||
|
||||
(priv->plat->interface == PHY_INTERFACE_MODE_10GKR))
|
||||
else if (priv->plat->interface == PHY_INTERFACE_MODE_USXGMII)
|
||||
tx |= hw->link.xgmii.speed10000;
|
||||
#endif
|
||||
writel(tx, ioaddr + XGMAC_TX_CONFIG);
|
||||
|
@ -30,6 +30,8 @@
|
||||
*
|
||||
* 15 Mar 2021 : Base lined
|
||||
* VERSION : 01-00
|
||||
* 15 Jul 2021 : 1. USXGMII/XFI/SGMII/RGMII interface supported without module parameter
|
||||
* VERSION : 01-00-02
|
||||
*/
|
||||
|
||||
#include "tc956xmac_inc.h"
|
||||
@ -330,6 +332,8 @@ static void dwxgmac2_get_addr(struct tc956xmac_priv *priv,
|
||||
static void dwxgmac2_set_addr(struct tc956xmac_priv *priv,
|
||||
struct dma_desc *p, dma_addr_t addr)
|
||||
{
|
||||
u64 target_addrs;
|
||||
|
||||
//printk("%s, buff addr = 0x%llx\n",__func__, addr);
|
||||
p->des0 = cpu_to_le32(lower_32_bits(addr));
|
||||
#ifdef TC956X
|
||||
@ -341,6 +345,13 @@ static void dwxgmac2_set_addr(struct tc956xmac_priv *priv,
|
||||
#endif
|
||||
|
||||
//printk(" pdes0 = 0x%x. pdes1 = 0x%x\n", p->des0, p->des1);
|
||||
target_addrs = (u64)(TC956X_HOST_PHYSICAL_ADRS_MASK | (upper_32_bits(addr) & 0xF));
|
||||
|
||||
target_addrs = (u64)lower_32_bits(target_addrs) << 32;
|
||||
target_addrs |= cpu_to_le32(lower_32_bits(addr));
|
||||
|
||||
if (target_addrs < 0x1000000000 || target_addrs > 0x1FFFFFFFFF)
|
||||
printk("Address out of range. Trsl Addr = 0x%llx, eMAC target addr = 0x%llx\n", (u64)addr, target_addrs);
|
||||
}
|
||||
|
||||
static void dwxgmac2_clear(struct tc956xmac_priv *priv, struct dma_desc *p)
|
||||
|
@ -30,6 +30,8 @@
|
||||
*
|
||||
* 15 Mar 2021 : Base lined
|
||||
* VERSION : 01-00
|
||||
* 15 Jul 2021 : 1. USXGMII/XFI/SGMII/RGMII interface supported without module parameter
|
||||
* VERSION : 01-00-02
|
||||
*/
|
||||
|
||||
#include <linux/iopoll.h>
|
||||
@ -88,6 +90,7 @@ static void dwxgmac2_dma_init_rx_chan(struct tc956xmac_priv *priv,
|
||||
u32 rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;
|
||||
u32 value;
|
||||
|
||||
u64 target_addrs;
|
||||
value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
|
||||
value &= ~XGMAC_RxPBL;
|
||||
value |= (rxpbl << XGMAC_RxPBL_SHIFT) & XGMAC_RxPBL;
|
||||
@ -107,6 +110,13 @@ static void dwxgmac2_dma_init_rx_chan(struct tc956xmac_priv *priv,
|
||||
writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_HADDR(chan));
|
||||
#endif
|
||||
writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_LADDR(chan));
|
||||
target_addrs = (u64)(TC956X_HOST_PHYSICAL_ADRS_MASK | (upper_32_bits(phy) & 0xF));
|
||||
|
||||
target_addrs = (u64)lower_32_bits(target_addrs) << 32;
|
||||
target_addrs |= cpu_to_le32(lower_32_bits(phy));
|
||||
|
||||
if (target_addrs < 0x1000000000 || target_addrs > 0x1FFFFFFFFF)
|
||||
printk("Address out of range. Trsl Addr = 0x%llx, eMAC target addr = 0x%llx\n", (u64)phy, target_addrs);
|
||||
}
|
||||
|
||||
static void dwxgmac2_dma_init_tx_chan(struct tc956xmac_priv *priv,
|
||||
@ -116,6 +126,7 @@ static void dwxgmac2_dma_init_tx_chan(struct tc956xmac_priv *priv,
|
||||
{
|
||||
u32 txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
|
||||
u32 value;
|
||||
u64 target_addrs;
|
||||
|
||||
value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
|
||||
value &= ~XGMAC_TxPBL;
|
||||
@ -133,6 +144,13 @@ static void dwxgmac2_dma_init_tx_chan(struct tc956xmac_priv *priv,
|
||||
XGMAC_DMA_CH_TxDESC_HADDR(chan));
|
||||
#endif
|
||||
writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_LADDR(chan));
|
||||
target_addrs = (u64)(TC956X_HOST_PHYSICAL_ADRS_MASK | (upper_32_bits(phy) & 0xF));
|
||||
|
||||
target_addrs = (u64)lower_32_bits(target_addrs) << 32;
|
||||
target_addrs |= cpu_to_le32(lower_32_bits(phy));
|
||||
|
||||
if (target_addrs < 0x1000000000 || target_addrs > 0x1FFFFFFFFF)
|
||||
printk("Address out of range. Trsl Addr = 0x%llx, eMAC target addr = 0x%llx\n", (u64)phy, target_addrs);
|
||||
}
|
||||
|
||||
static void dwxgmac2_dma_axi(struct tc956xmac_priv *priv, void __iomem *ioaddr,
|
||||
|
@ -31,6 +31,8 @@
|
||||
* 05 Jul 2021 : 1. Used Systick handler instead of Driver kernel timer to process transmitted Tx descriptors.
|
||||
* 2. XFI interface support and module parameters for selection of Port0 and Port1 interface
|
||||
* VERSION : 01-00-01
|
||||
* 15 Jul 2021 : 1. USXGMII/XFI/SGMII/RGMII interface supported without module parameter
|
||||
* VERSION : 01-00-02
|
||||
*/
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
@ -1453,7 +1455,7 @@ EXPORT_SYMBOL_GPL(stop_channel);
|
||||
/*!
|
||||
* \brief This API will print EMAC-IPA offload DMA channel stats
|
||||
*
|
||||
* \details This function will read and prints DMA Descriptor stats
|
||||
* \details This function will read and prints DMA Descriptor stats
|
||||
* used by IPA.
|
||||
*
|
||||
* \param[in] ndev : TC956x netdev data structure.
|
||||
@ -1461,60 +1463,67 @@ EXPORT_SYMBOL_GPL(stop_channel);
|
||||
* \return : Return 0 on success, -ve value on error
|
||||
* -ENODEV if ndev is NULL, tc956xmac_priv extracted from ndev is NULL
|
||||
*/
|
||||
int read_ipa_desc_stats(struct net_device *ndev)
|
||||
int read_ipa_desc_stats(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
unsigned int buf_len = 4000;
|
||||
unsigned int len = 0;
|
||||
int chno = 0;
|
||||
struct tc956xmac_priv *priv;
|
||||
|
||||
if (!ndev) {
|
||||
pr_err("%s: ERROR: Invalid netdevice pointer\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
priv = netdev_priv(ndev);
|
||||
char *buf;
|
||||
ssize_t ret_cnt;
|
||||
struct tc956xmac_priv *priv = file->private_data;
|
||||
|
||||
if (!priv) {
|
||||
pr_err("%s: ERROR: Invalid private data pointer\n", __func__);
|
||||
return -ENODEV;
|
||||
printk(KERN_ERR "%s: Error priv is null\n", __func__);
|
||||
return count;
|
||||
}
|
||||
|
||||
buf = kzalloc(buf_len, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
len += scnprintf(buf + len, buf_len - len,
|
||||
"\n************* READ IPA DESC STATS *************\n");
|
||||
|
||||
/* TX DMA Descriptors Status for all channels */
|
||||
for (chno = 0; chno < priv->plat->tx_queues_to_use; chno++) {
|
||||
for(chno = 0; chno < priv->plat->tx_queues_to_use; chno++) {
|
||||
|
||||
if (priv->plat->tx_dma_ch_owner[chno] != USE_IN_OFFLOADER)
|
||||
continue;
|
||||
|
||||
netdev_info(priv->dev, "%s : txch_status[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_STATUS(chno)));
|
||||
netdev_info(priv->dev, "%s : txch_control[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_TX_CONTROL(chno)));
|
||||
netdev_info(priv->dev, "%s : txch_desc_list_haddr[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_TxDESC_HADDR(chno)));
|
||||
netdev_info(priv->dev, "%s : txch_desc_list_laddr[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_TxDESC_LADDR(chno)));
|
||||
netdev_info(priv->dev, "%s : txch_desc_ring_len[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_TX_CONTROL2(chno)));
|
||||
netdev_info(priv->dev, "%s : txch_desc_curr_haddr[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_Cur_TxDESC_HADDR(chno)));
|
||||
netdev_info(priv->dev, "%s : txch_desc_curr_laddr[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_Cur_TxDESC_LADDR(chno)));
|
||||
netdev_info(priv->dev, "%s : txch_desc_tail[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_TxDESC_TAIL_LPTR(chno)));
|
||||
netdev_info(priv->dev, "%s : txch_desc_buf_haddr[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_Cur_TxBuff_HADDR(chno)));
|
||||
netdev_info(priv->dev, "%s : txch_desc_buf_laddr[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_Cur_TxBuff_LADDR(chno)));
|
||||
netdev_info(priv->dev, "%s : txch_dma_interrupt_en[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_INT_EN(chno)));
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "txch_status[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_STATUS(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "txch_control[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_TX_CONTROL(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "txch_desc_list_haddr[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_TxDESC_HADDR(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "txch_desc_list_laddr[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_TxDESC_LADDR(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "txch_desc_ring_len[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_TX_CONTROL2(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "txch_desc_curr_haddr[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_Cur_TxDESC_HADDR(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "txch_desc_curr_laddr[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_Cur_TxDESC_LADDR(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "txch_desc_tail[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_TxDESC_TAIL_LPTR(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "txch_desc_buf_haddr[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_Cur_TxBuff_HADDR(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "txch_desc_buf_laddr[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_Cur_TxBuff_LADDR(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "txch_dma_interrupt_en[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_INT_EN(chno)));
|
||||
}
|
||||
|
||||
/* RX DMA Descriptors Status for all channels */
|
||||
for (chno = 0; chno < TC956XMAC_CH_MAX; chno++) {
|
||||
for(chno = 0; chno < TC956XMAC_CH_MAX; chno++) {
|
||||
|
||||
if (priv->plat->rx_dma_ch_owner[chno] != USE_IN_OFFLOADER)
|
||||
continue;
|
||||
|
||||
netdev_info(priv->dev, "%s : rxch_status[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_STATUS(chno)));
|
||||
netdev_info(priv->dev, "%s : rxch_control[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_RX_CONTROL(chno)));
|
||||
netdev_info(priv->dev, "%s : rxch_desc_list_haddr[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_RxDESC_HADDR(chno)));
|
||||
netdev_info(priv->dev, "%s : rxch_desc_list_laddr[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_RxDESC_LADDR(chno)));
|
||||
netdev_info(priv->dev, "%s : rxch_desc_ring_len[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_RX_CONTROL2(chno)));
|
||||
netdev_info(priv->dev, "%s : rxch_desc_curr_haddr[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_Cur_RxDESC_HADDR(chno)));
|
||||
netdev_info(priv->dev, "%s : rxch_desc_curr_laddr[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_Cur_RxDESC_LADDR(chno)));
|
||||
netdev_info(priv->dev, "%s : rxch_desc_tail[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_RxDESC_TAIL_LPTR(chno)));
|
||||
netdev_info(priv->dev, "%s : rxch_desc_buf_haddr[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_Cur_RxBuff_HADDR(chno)));
|
||||
netdev_info(priv->dev, "%s : rxch_desc_buf_laddr[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_Cur_RxBuff_LADDR(chno)));
|
||||
netdev_info(priv->dev, "%s : rxch_dma_interrupt_en[%d] : 0x%08x", __func__, chno, readl(priv->ioaddr + XGMAC_DMA_CH_INT_EN(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "rxch_status[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_STATUS(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "rxch_control[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_RX_CONTROL(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "rxch_desc_list_haddr[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_RxDESC_HADDR(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "rxch_desc_list_laddr[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_RxDESC_LADDR(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "rxch_desc_ring_len[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_RX_CONTROL2(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "rxch_desc_curr_haddr[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_Cur_RxDESC_HADDR(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "rxch_desc_curr_laddr[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_Cur_RxDESC_LADDR(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "rxch_desc_tail[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_RxDESC_TAIL_LPTR(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "rxch_desc_buf_haddr[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_Cur_RxBuff_HADDR(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "rxch_desc_buf_laddr[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_Cur_RxBuff_LADDR(chno)));
|
||||
len += scnprintf(buf + len, buf_len - len, "rxch_dma_interrupt_en[%d] : 0x%08x\n", chno, readl(priv->ioaddr + XGMAC_DMA_CH_INT_EN(chno)));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
kfree(buf);
|
||||
return ret_cnt;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(read_ipa_desc_stats);
|
||||
|
@ -33,6 +33,8 @@
|
||||
* 05 Jul 2021 : 1. Used Systick handler instead of Driver kernel timer to process transmitted Tx descriptors.
|
||||
* 2. XFI interface support and module parameters for selection of Port0 and Port1 interface
|
||||
* VERSION : 01-00-01
|
||||
* 15 Jul 2021 : 1. USXGMII/XFI/SGMII/RGMII interface supported without module parameter
|
||||
* VERSION : 01-00-02
|
||||
*/
|
||||
|
||||
#ifndef __TC956x_IPA_INTF_H
|
||||
@ -370,7 +372,7 @@ int stop_channel(struct net_device *ndev, struct channel_info *channel);
|
||||
/*!
|
||||
* \brief This API will print EMAC-IPA offload DMA channel stats
|
||||
*
|
||||
* \details This function will read and prints DMA Descriptor stats
|
||||
* \details This function will read and prints DMA Descriptor stats
|
||||
* used by IPA.
|
||||
*
|
||||
* \param[i] ndev : TC956x netdev data structure.
|
||||
@ -379,7 +381,9 @@ int stop_channel(struct net_device *ndev, struct channel_info *channel);
|
||||
* -ENODEV if ndev is NULL, tc956xmac_priv extracted from ndev is NULL
|
||||
*
|
||||
*/
|
||||
int read_ipa_desc_stats(struct net_device *ndev);
|
||||
int read_ipa_desc_stats(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
|
||||
|
||||
#endif /* __TC956x_IPA_INTF_H */
|
||||
|
||||
|
98
tc956x_pci.c
98
tc956x_pci.c
@ -34,6 +34,8 @@
|
||||
* 05 Jul 2021 : 1. Used Systick handler instead of Driver kernel timer to process transmitted Tx descriptors.
|
||||
* 2. XFI interface support and module parameters for selection of Port0 and Port1 interface
|
||||
* VERSION : 01-00-01
|
||||
* 15 Jul 2021 : 1. USXGMII/XFI/SGMII/RGMII interface supported without module parameter
|
||||
* VERSION : 01-00-02
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
@ -60,10 +62,9 @@
|
||||
#ifdef TC956X_PCIE_GEN3_SETTING
|
||||
static unsigned int tc956x_speed = 3;
|
||||
#endif
|
||||
static unsigned int tc956x_port0_interface = ENABLE_XFI_INTERFACE;
|
||||
static unsigned int tc956x_port1_interface = ENABLE_SGMII_INTERFACE;
|
||||
|
||||
static const struct tc956x_version tc956x_drv_version = {0, 1, 0, 0, 0, 1};
|
||||
|
||||
static const struct tc956x_version tc956x_drv_version = {0, 1, 0, 0, 0, 2};
|
||||
|
||||
/*
|
||||
* This struct is used to associate PCI Function of MAC controller on a board,
|
||||
@ -679,15 +680,17 @@ static void xgmac_default_data(struct plat_tc956xmacenet_data *plat)
|
||||
plat->has_gmac4 = 0;
|
||||
plat->force_thresh_dma_mode = 0;
|
||||
plat->mdio_bus_data->needs_reset = false;
|
||||
if ((plat->port_interface == ENABLE_USXGMII_INTERFACE) ||
|
||||
(plat->port_interface == ENABLE_XFI_INTERFACE))
|
||||
if (INTERFACE_SELECTED(plat->port_num) == ENABLE_USXGMII_INTERFACE)
|
||||
plat->mac_port_sel_speed = 10000;
|
||||
|
||||
if (plat->port_interface == ENABLE_RGMII_INTERFACE)
|
||||
|
||||
if (INTERFACE_SELECTED(plat->port_num) == ENABLE_RGMII_INTERFACE)
|
||||
plat->mac_port_sel_speed = 1000;
|
||||
|
||||
if (plat->port_interface == ENABLE_SGMII_INTERFACE)
|
||||
|
||||
if (INTERFACE_SELECTED(plat->port_num) == ENABLE_SGMII_INTERFACE) {
|
||||
plat->mac_port_sel_speed = 2500;
|
||||
}
|
||||
|
||||
plat->riwt_off = 0;
|
||||
plat->rss_en = 0;
|
||||
@ -723,19 +726,17 @@ static int tc956xmac_xgmac3_default_data(struct pci_dev *pdev,
|
||||
plat->pdev = pdev;
|
||||
|
||||
#ifdef TC956X
|
||||
if (plat->port_interface == ENABLE_USXGMII_INTERFACE) {
|
||||
if (INTERFACE_SELECTED(plat->port_num) == ENABLE_USXGMII_INTERFACE) {
|
||||
plat->interface = PHY_INTERFACE_MODE_USXGMII;
|
||||
plat->max_speed = 10000;
|
||||
}
|
||||
if (plat->port_interface == ENABLE_XFI_INTERFACE) {
|
||||
plat->interface = PHY_INTERFACE_MODE_10GKR;
|
||||
plat->max_speed = 10000;
|
||||
}
|
||||
if (plat->port_interface == ENABLE_RGMII_INTERFACE) {
|
||||
|
||||
if (INTERFACE_SELECTED(plat->port_num) == ENABLE_RGMII_INTERFACE) {
|
||||
plat->interface = PHY_INTERFACE_MODE_RGMII;
|
||||
plat->max_speed = 1000;
|
||||
}
|
||||
if (plat->port_interface == ENABLE_SGMII_INTERFACE) {
|
||||
|
||||
if (INTERFACE_SELECTED(plat->port_num) == ENABLE_SGMII_INTERFACE) {
|
||||
plat->interface = PHY_INTERFACE_MODE_SGMII;
|
||||
plat->max_speed = 2500;
|
||||
}
|
||||
@ -1894,26 +1895,6 @@ static int tc956xmac_pci_probe(struct pci_dev *pdev,
|
||||
plat->c45_needed = PORT1_C45_STATE;
|
||||
}
|
||||
|
||||
if (res.port_num == RM_PF0_ID) {
|
||||
/* Set the PORT0 interface mode to default, in case of invalid input */
|
||||
if ((tc956x_port0_interface == ENABLE_RGMII_INTERFACE) ||
|
||||
(tc956x_port0_interface > ENABLE_SGMII_INTERFACE))
|
||||
tc956x_port0_interface = ENABLE_XFI_INTERFACE;
|
||||
|
||||
res.port_interface = tc956x_port0_interface;
|
||||
}
|
||||
|
||||
if (res.port_num == RM_PF1_ID) {
|
||||
/* Set the PORT1 interface mode to default, in case of invalid input */
|
||||
if ((tc956x_port1_interface < ENABLE_RGMII_INTERFACE) ||
|
||||
(tc956x_port1_interface > ENABLE_SGMII_INTERFACE))
|
||||
tc956x_port1_interface = ENABLE_SGMII_INTERFACE;
|
||||
|
||||
res.port_interface = tc956x_port1_interface;
|
||||
}
|
||||
|
||||
plat->port_interface = res.port_interface;
|
||||
|
||||
ret = info->setup(pdev, plat);
|
||||
|
||||
if (ret)
|
||||
@ -1993,7 +1974,8 @@ static int tc956xmac_pci_probe(struct pci_dev *pdev,
|
||||
|
||||
ret |= ((NCLKCTRL0_MAC0TXCEN | NCLKCTRL0_MAC0ALLCLKEN | NCLKCTRL0_MAC0RXCEN));
|
||||
/* Only if "current" port is SGMII 2.5G, configure below clocks. */
|
||||
if (res.port_interface == ENABLE_SGMII_INTERFACE) {
|
||||
if (PORT0_INTERFACE == ENABLE_SGMII_INTERFACE) {
|
||||
/* XPCS doesn't support Auto Negotiation for 2.5Gbps SGMII */
|
||||
ret &= ~NCLKCTRL0_POEPLLCEN;
|
||||
ret &= ~NCLKCTRL0_SGMPCIEN;
|
||||
ret &= ~NCLKCTRL0_REFCLKOCEN;
|
||||
@ -2005,10 +1987,9 @@ static int tc956xmac_pci_probe(struct pci_dev *pdev,
|
||||
/* Interface configuration for port0*/
|
||||
ret = readl(res.addr + NEMAC0CTL_OFFSET);
|
||||
ret &= ~(NEMACCTL_SP_SEL_MASK | NEMACCTL_PHY_INF_SEL_MASK);
|
||||
if (res.port_interface == ENABLE_SGMII_INTERFACE)
|
||||
if (PORT0_INTERFACE == ENABLE_SGMII_INTERFACE)
|
||||
ret |= NEMACCTL_SP_SEL_SGMII_2500M;
|
||||
else if ((res.port_interface == ENABLE_USXGMII_INTERFACE) ||
|
||||
(res.port_interface == ENABLE_XFI_INTERFACE))
|
||||
else if (PORT0_INTERFACE == ENABLE_USXGMII_INTERFACE)
|
||||
ret |= NEMACCTL_SP_SEL_USXGMII_10G_10G;
|
||||
|
||||
ret &= ~(0x00000040); /* Mask Polarity */
|
||||
@ -2037,7 +2018,7 @@ static int tc956xmac_pci_probe(struct pci_dev *pdev,
|
||||
|
||||
ret |= ((NCLKCTRL1_MAC1TXCEN | NCLKCTRL1_MAC1RXCEN |
|
||||
NCLKCTRL1_MAC1ALLCLKEN1 | 1 << 15));
|
||||
if (res.port_interface == ENABLE_SGMII_INTERFACE) {
|
||||
if (PORT1_INTERFACE == ENABLE_SGMII_INTERFACE) {
|
||||
ret &= ~NCLKCTRL1_MAC1125CLKEN1;
|
||||
ret &= ~NCLKCTRL1_MAC1312CLKEN1;
|
||||
}
|
||||
@ -2046,12 +2027,11 @@ static int tc956xmac_pci_probe(struct pci_dev *pdev,
|
||||
/* Interface configuration for port1*/
|
||||
ret = readl(res.addr + NEMAC1CTL_OFFSET);
|
||||
ret &= ~(NEMACCTL_SP_SEL_MASK | NEMACCTL_PHY_INF_SEL_MASK);
|
||||
if (res.port_interface == ENABLE_RGMII_INTERFACE)
|
||||
if (PORT1_INTERFACE == ENABLE_RGMII_INTERFACE)
|
||||
ret |= NEMACCTL_SP_SEL_RGMII_1000M;
|
||||
else if (res.port_interface == ENABLE_SGMII_INTERFACE)
|
||||
else if (PORT1_INTERFACE == ENABLE_SGMII_INTERFACE)
|
||||
ret |= NEMACCTL_SP_SEL_SGMII_2500M;
|
||||
else if ((res.port_interface == ENABLE_USXGMII_INTERFACE) ||
|
||||
(res.port_interface == ENABLE_XFI_INTERFACE))
|
||||
else if (PORT1_INTERFACE == ENABLE_USXGMII_INTERFACE)
|
||||
ret |= NEMACCTL_SP_SEL_USXGMII_10G_10G;
|
||||
|
||||
ret &= ~(0x00000040); /* Mask Polarity */
|
||||
@ -2080,7 +2060,7 @@ static int tc956xmac_pci_probe(struct pci_dev *pdev,
|
||||
goto err_dvr_probe;
|
||||
}
|
||||
#ifdef TC956X
|
||||
if ((res.port_num == RM_PF1_ID) && (res.port_interface == ENABLE_RGMII_INTERFACE)) {
|
||||
if ((res.port_num == RM_PF1_ID) && (PORT1_INTERFACE == ENABLE_RGMII_INTERFACE)) {
|
||||
writel(0x00000000, res.addr + 0x1050);
|
||||
writel(0xF300F300, res.addr + 0x107C);
|
||||
}
|
||||
@ -2263,8 +2243,8 @@ static int tc956x_pcie_resume_config(struct pci_dev *pdev)
|
||||
ret = readl(priv->tc956x_SFR_pci_base_addr + NCLKCTRL0_OFFSET);
|
||||
|
||||
ret |= ((NCLKCTRL0_MAC0TXCEN | NCLKCTRL0_MAC0ALLCLKEN | NCLKCTRL0_MAC0RXCEN));
|
||||
if (priv->port_interface == ENABLE_SGMII_INTERFACE) {
|
||||
/* Disable Clocks for 2.5Gbps SGMII */
|
||||
if (PORT0_INTERFACE == ENABLE_SGMII_INTERFACE) {
|
||||
/* XPCS doesn't support Auto Negotiation for 2.5Gbps SGMII */
|
||||
ret &= ~NCLKCTRL0_POEPLLCEN;
|
||||
ret &= ~NCLKCTRL0_SGMPCIEN;
|
||||
ret &= ~NCLKCTRL0_REFCLKOCEN;
|
||||
@ -2276,10 +2256,9 @@ static int tc956x_pcie_resume_config(struct pci_dev *pdev)
|
||||
/* Interface configuration for port0*/
|
||||
ret = readl(priv->tc956x_SFR_pci_base_addr + NEMAC0CTL_OFFSET);
|
||||
ret &= ~(NEMACCTL_SP_SEL_MASK | NEMACCTL_PHY_INF_SEL_MASK);
|
||||
if (priv->port_interface == ENABLE_SGMII_INTERFACE)
|
||||
if (PORT0_INTERFACE == ENABLE_SGMII_INTERFACE)
|
||||
ret |= NEMACCTL_SP_SEL_SGMII_2500M;
|
||||
else if ((priv->port_interface == ENABLE_USXGMII_INTERFACE) ||
|
||||
(priv->port_interface == ENABLE_XFI_INTERFACE))
|
||||
else if (PORT0_INTERFACE == ENABLE_USXGMII_INTERFACE)
|
||||
ret |= NEMACCTL_SP_SEL_USXGMII_10G_10G;
|
||||
|
||||
ret &= ~(0x00000040); /* Mask Polarity */
|
||||
@ -2308,7 +2287,7 @@ static int tc956x_pcie_resume_config(struct pci_dev *pdev)
|
||||
|
||||
ret |= ((NCLKCTRL1_MAC1TXCEN | NCLKCTRL1_MAC1RXCEN |
|
||||
NCLKCTRL1_MAC1ALLCLKEN1 | 1 << 15));
|
||||
if (priv->port_interface == ENABLE_SGMII_INTERFACE) {
|
||||
if(PORT1_INTERFACE == ENABLE_SGMII_INTERFACE) {
|
||||
ret &= ~NCLKCTRL1_MAC1125CLKEN1;
|
||||
ret &= ~NCLKCTRL1_MAC1312CLKEN1;
|
||||
}
|
||||
@ -2317,12 +2296,11 @@ static int tc956x_pcie_resume_config(struct pci_dev *pdev)
|
||||
/* Interface configuration for port1*/
|
||||
ret = readl(priv->tc956x_SFR_pci_base_addr + NEMAC1CTL_OFFSET);
|
||||
ret &= ~(NEMACCTL_SP_SEL_MASK | NEMACCTL_PHY_INF_SEL_MASK);
|
||||
if (priv->port_interface == ENABLE_RGMII_INTERFACE)
|
||||
if (PORT1_INTERFACE == ENABLE_RGMII_INTERFACE)
|
||||
ret |= NEMACCTL_SP_SEL_RGMII_1000M;
|
||||
else if (priv->port_interface == ENABLE_SGMII_INTERFACE)
|
||||
else if (PORT1_INTERFACE == ENABLE_SGMII_INTERFACE)
|
||||
ret |= NEMACCTL_SP_SEL_SGMII_2500M;
|
||||
else if ((priv->port_interface == ENABLE_USXGMII_INTERFACE) ||
|
||||
(priv->port_interface == ENABLE_XFI_INTERFACE))
|
||||
else if (PORT1_INTERFACE == ENABLE_USXGMII_INTERFACE)
|
||||
ret |= NEMACCTL_SP_SEL_USXGMII_10G_10G;
|
||||
|
||||
ret &= ~(0x00000040); /* Mask Polarity */
|
||||
@ -2447,7 +2425,7 @@ static s32 tc956x_pcie_resume(struct pci_dev *pdev)
|
||||
/* Call tc956xmac_resume() */
|
||||
tc956xmac_resume(&pdev->dev);
|
||||
#ifdef TC956X
|
||||
if ((priv->port_num == RM_PF1_ID) && (priv->port_interface == ENABLE_RGMII_INTERFACE)) {
|
||||
if ((priv->port_num == RM_PF1_ID) && (PORT1_INTERFACE == ENABLE_RGMII_INTERFACE)) {
|
||||
writel(NEMACTXCDLY_DEFAULT, priv->ioaddr + TC9563_CFG_NEMACTXCDLY);
|
||||
writel(NEMACIOCTL_DEFAULT, priv->ioaddr + TC9563_CFG_NEMACIOCTL);
|
||||
}
|
||||
@ -2677,16 +2655,6 @@ MODULE_PARM_DESC(tc956x_speed,
|
||||
"PCIe speed Gen TC9563_64 - default is 3, [1..3]");
|
||||
#endif
|
||||
|
||||
module_param(tc956x_port0_interface, uint, 0444);
|
||||
MODULE_PARM_DESC(tc956x_port0_interface,
|
||||
"PORT0 interface mode TC9563_64 - default is 1,\
|
||||
[0: USXGMII, 1: XFI, 2: RGMII(not supported), 3: SGMII]");
|
||||
|
||||
module_param(tc956x_port1_interface, uint, 0444);
|
||||
MODULE_PARM_DESC(tc956x_port1_interface,
|
||||
"PORT1 interface mode TC9563_64 - default is 3,\
|
||||
[0: USXGMII(not supported), 1: XFI(not supported), 2: RGMII, 3: SGMII]");
|
||||
|
||||
MODULE_DESCRIPTION("TC956X PCI Express Ethernet Network Driver");
|
||||
MODULE_AUTHOR("Toshiba Electronic Devices & Storage Corporation");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -31,6 +31,8 @@
|
||||
* 05 Jul 2021 : 1. Used Systick handler instead of Driver kernel timer to process transmitted Tx descriptors.
|
||||
* 2. XFI interface support and module parameters for selection of Port0 and Port1 interface
|
||||
* VERSION : 01-00-01
|
||||
* 15 Jul 2021 : 1. USXGMII/XFI/SGMII/RGMII interface supported without module parameter
|
||||
* VERSION : 01-00-02
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
@ -97,7 +99,7 @@ int tc956x_xpcs_init(struct tc956xmac_priv *priv, void __iomem *xpcsaddr)
|
||||
reg_value |= XGMAC_SGMII_MODE;/*SGMII PCS MODE*/
|
||||
tc956x_xpcs_write(xpcsaddr, XGMAC_VR_MII_AN_CTRL, reg_value);
|
||||
|
||||
if (priv->is_sgmii_2p5g == true) {
|
||||
if (priv->is_sgmii_2p5g == SGMII_2P5G_ENABLED) {
|
||||
reg_value = tc956x_xpcs_read(xpcsaddr, XGMAC_VR_XS_PCS_DIG_CTRL1);
|
||||
reg_value &= ~(0x4);
|
||||
/* Enable only if SGMII 2.5G is enabled */
|
||||
@ -105,18 +107,16 @@ int tc956x_xpcs_init(struct tc956xmac_priv *priv, void __iomem *xpcsaddr)
|
||||
tc956x_xpcs_write(xpcsaddr, XGMAC_VR_XS_PCS_DIG_CTRL1, reg_value);
|
||||
}
|
||||
}
|
||||
if ((priv->plat->interface == PHY_INTERFACE_MODE_USXGMII) ||
|
||||
(priv->plat->interface == PHY_INTERFACE_MODE_10GKR)) {
|
||||
|
||||
if (priv->plat->interface == PHY_INTERFACE_MODE_USXGMII) {
|
||||
reg_value = tc956x_xpcs_read(xpcsaddr, XGMAC_SR_XS_PCS_CTRL2);
|
||||
reg_value &= XGMAC_PCS_TYPE_SEL;/*PCS_TYPE_SEL as 10GBASE-R PCS */
|
||||
tc956x_xpcs_write(xpcsaddr, XGMAC_SR_XS_PCS_CTRL2, reg_value);
|
||||
|
||||
reg_value = tc956x_xpcs_read(xpcsaddr, XGMAC_VR_XS_PCS_DIG_CTRL1);
|
||||
if (priv->plat->interface == PHY_INTERFACE_MODE_10GKR)
|
||||
reg_value &= (~XGMAC_USXG_EN); /*Disable USXG_EN*/
|
||||
else
|
||||
reg_value |= XGMAC_USXG_EN; /*set USXG_EN*/
|
||||
|
||||
#ifndef TC956X_USXGMII_XFI_MODE
|
||||
reg_value |= XGMAC_USXG_EN;/*set USXG_EN*/
|
||||
#endif
|
||||
tc956x_xpcs_write(xpcsaddr, XGMAC_VR_XS_PCS_DIG_CTRL1, reg_value);
|
||||
|
||||
reg_value = tc956x_xpcs_read(xpcsaddr, XGMAC_VR_XS_PCS_KR_CTRL);
|
||||
@ -141,7 +141,7 @@ int tc956x_xpcs_init(struct tc956xmac_priv *priv, void __iomem *xpcsaddr)
|
||||
|
||||
reg_value = tc956x_xpcs_read(xpcsaddr, XGMAC_VR_MII_DIG_CTRL1);
|
||||
reg_value &= ~XGMAC_MAC_AUTO_SW_EN;/*MAC_AUTO_SW enable*/
|
||||
if (priv->is_sgmii_2p5g != true)
|
||||
if (priv->is_sgmii_2p5g != SGMII_2P5G_ENABLED)
|
||||
/* Enable only if SGMII 2.5G is not enabled. */
|
||||
reg_value |= XGMAC_MAC_AUTO_SW_EN;
|
||||
tc956x_xpcs_write(xpcsaddr, XGMAC_VR_MII_DIG_CTRL1, reg_value);
|
||||
@ -155,12 +155,17 @@ void tc956x_xpcs_ctrl_ane(struct tc956xmac_priv *priv, bool ane)
|
||||
|
||||
reg_value = tc956x_xpcs_read(priv->xpcsaddr, XGMAC_SR_MII_CTRL);
|
||||
if (ane) {
|
||||
reg_value |= XGMAC_AN_37_ENABLE;
|
||||
KPRINT_INFO("%s Enable AN", __func__);
|
||||
if (priv->is_sgmii_2p5g == SGMII_2P5G_ENABLED)
|
||||
/* XPCS doesn't support AN for 2.5G SGMII.
|
||||
Disable AN only if SGMII 2.5G is Enabled. */
|
||||
reg_value &= (~XGMAC_AN_37_ENABLE);
|
||||
else
|
||||
reg_value |= XGMAC_AN_37_ENABLE;
|
||||
|
||||
} else {
|
||||
reg_value &= (~XGMAC_AN_37_ENABLE);
|
||||
KPRINT_INFO("%s Disable AN", __func__);
|
||||
}
|
||||
tc956x_xpcs_write(priv->xpcsaddr, XGMAC_SR_MII_CTRL, reg_value);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
@ -31,6 +31,8 @@
|
||||
* 05 Jul 2021 : 1. Used Systick handler instead of Driver kernel timer to process transmitted Tx descriptors.
|
||||
* 2. XFI interface support and module parameters for selection of Port0 and Port1 interface
|
||||
* VERSION : 01-00-01
|
||||
* 15 Jul 2021 : 1. USXGMII/XFI/SGMII/RGMII interface supported without module parameter
|
||||
* VERSION : 01-00-02
|
||||
*/
|
||||
|
||||
#ifndef __TC956X_XPCS_H__
|
||||
|
22
tc956xmac.h
22
tc956xmac.h
@ -34,6 +34,8 @@
|
||||
* 05 Jul 2021 : 1. Used Systick handler instead of Driver kernel timer to process transmitted Tx descriptors.
|
||||
* 2. XFI interface support and module parameters for selection of Port0 and Port1 interface
|
||||
* VERSION : 01-00-01
|
||||
* 15 Jul 2021 : 1. USXGMII/XFI/SGMII/RGMII interface supported without module parameter
|
||||
* VERSION : 01-00-02
|
||||
*/
|
||||
|
||||
#ifndef __TC956XMAC_H__
|
||||
@ -81,7 +83,7 @@
|
||||
#ifdef TC956X
|
||||
|
||||
#define TC956X_RESOURCE_NAME "tc956x_pci-eth"
|
||||
#define DRV_MODULE_VERSION "V_01-00-01"
|
||||
#define DRV_MODULE_VERSION "V_01-00-02"
|
||||
#define TC956X_FW_MAX_SIZE (64*1024)
|
||||
|
||||
#define ATR_AXI4_SLV_BASE 0x0800
|
||||
@ -180,9 +182,15 @@
|
||||
#define TC956X_M3_DBG_VER_START 0x4F900
|
||||
|
||||
#define ENABLE_USXGMII_INTERFACE 0
|
||||
#define ENABLE_XFI_INTERFACE 1 /* XFI/SFI, this is same as USXGMII, except XPCS autoneg disabled */
|
||||
#define ENABLE_RGMII_INTERFACE 2
|
||||
#define ENABLE_SGMII_INTERFACE 3
|
||||
#define ENABLE_RGMII_INTERFACE 1
|
||||
#define ENABLE_SGMII_INTERFACE 2
|
||||
|
||||
/* Only SGMII and USXGMII allowed for Port0 */
|
||||
#define PORT0_INTERFACE ENABLE_USXGMII_INTERFACE
|
||||
//#define PORT0_INTERFACE ENABLE_SGMII_INTERFACE
|
||||
#define PORT1_INTERFACE ENABLE_RGMII_INTERFACE
|
||||
|
||||
#define INTERFACE_SELECTED(p) (((p) == RM_PF0_ID) ? (PORT0_INTERFACE) : (PORT1_INTERFACE))
|
||||
|
||||
#define MTL_FPE_AFSZ_64 0
|
||||
#define MTL_FPE_AFSZ_128 1
|
||||
@ -206,7 +214,6 @@ struct tc956xmac_resources {
|
||||
int irq;
|
||||
#ifdef TC956X
|
||||
unsigned int port_num;
|
||||
unsigned int port_interface; /* Kernel module parameter variable for interface */
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -443,7 +450,7 @@ struct tc956xmac_priv {
|
||||
#endif
|
||||
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#ifdef CONFIG_DEBUG_FS_TC956X
|
||||
struct dentry *dbgfs_dir;
|
||||
#endif
|
||||
|
||||
@ -482,8 +489,7 @@ struct tc956xmac_priv {
|
||||
u32 port_num;
|
||||
u32 mac_loopback_mode;
|
||||
u32 phy_loopback_mode;
|
||||
bool is_sgmii_2p5g; /* For 2.5G SGMI, XPCS doesn't support AN. This flag is to identify 2.5G Speed for SGMII interface. */
|
||||
u32 port_interface; /* Kernel module parameter variable for interface */
|
||||
enum SGMII_2P5G_SUPPORT is_sgmii_2p5g; /* For 2.5G SGMI, XPCS doesn't support AN. This flag is to identify 2.5G Speed for SGMII interface. */
|
||||
#endif
|
||||
|
||||
/* set to 1 when ptp offload is enabled, else 0. */
|
||||
|
@ -34,6 +34,8 @@
|
||||
* 05 Jul 2021 : 1. Used Systick handler instead of Driver kernel timer to process transmitted Tx descriptors.
|
||||
* 2. XFI interface support and module parameters for selection of Port0 and Port1 interface
|
||||
* VERSION : 01-00-01
|
||||
* 15 Jul 2021 : 1. USXGMII/XFI/SGMII/RGMII interface supported without module parameter
|
||||
* VERSION : 01-00-02
|
||||
*/
|
||||
|
||||
#include <linux/etherdevice.h>
|
||||
@ -861,11 +863,13 @@ tc956xmac_ethtool_set_link_ksettings(struct net_device *dev,
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* Temporary fix (phy dependent code): In case of AQR phy, auto negotiation OFF is not supported, return error for it */
|
||||
#ifdef TC956X_USXGMII_XFI_MODE
|
||||
/* In case of AQR phy, auto negotiation OFF is not supported, return error for it */
|
||||
if (priv->port_num == RM_PF0_ID) {
|
||||
if (cmd->base.autoneg != AUTONEG_ENABLE)
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
if (!dev->phydev)
|
||||
return -ENODEV;
|
||||
return phylink_ethtool_ksettings_set(priv->phylink, cmd);
|
||||
|
@ -34,6 +34,8 @@
|
||||
* 05 Jul 2021 : 1. Used Systick handler instead of Driver kernel timer to process transmitted Tx descriptors.
|
||||
* 2. XFI interface support and module parameters for selection of Port0 and Port1 interface
|
||||
* VERSION : 01-00-01
|
||||
* 15 Jul 2021 : 1. USXGMII/XFI/SGMII/RGMII interface supported without module parameter
|
||||
* VERSION : 01-00-02
|
||||
*/
|
||||
|
||||
#ifndef __TC956XMAC_PLATFORM_DATA
|
||||
@ -47,6 +49,7 @@
|
||||
//#define TC956X_IOCTL_REG_RD_WR_ENABLE
|
||||
//#define TC956X_WITHOUT_MDIO
|
||||
#define TC956X_PCIE_GEN3_SETTING
|
||||
//#define TC956X_SGMII_2P5_GBPS_TEST /*Enable this macro to test SGMII 2.5Gbps*/
|
||||
//#define TC956X_PCIE_DISABLE_DSP1 /*Enable this macro to disable DSP1 port*/
|
||||
//#define TC956X_PCIE_DISABLE_DSP2 /*Enable this macro to disable DSP2 port*/
|
||||
|
||||
@ -59,6 +62,7 @@
|
||||
|
||||
/* By default macro is defined and code coverage this macro to be disabled */
|
||||
#define TC956X_UNSUPPORTED_UNTESTED_FEATURE
|
||||
#define TC956X_USXGMII_XFI_MODE /*Enable this macro to support USXGMII through XFI mode*/
|
||||
|
||||
//#define EEPROM_MAC_ADDR
|
||||
|
||||
@ -290,6 +294,5 @@ struct plat_tc956xmacenet_data {
|
||||
enum ch_owner tx_dma_ch_owner[MTL_MAX_TX_QUEUES];
|
||||
enum ch_owner rx_dma_ch_owner[MTL_MAX_RX_QUEUES];
|
||||
u32 port_num;
|
||||
u32 port_interface; /* Kernel module parameter variable for interface */
|
||||
};
|
||||
#endif
|
||||
|
352
tc956xmac_main.c
352
tc956xmac_main.c
@ -34,6 +34,8 @@
|
||||
* 05 Jul 2021 : 1. Used Systick handler instead of Driver kernel timer to process transmitted Tx descriptors.
|
||||
* 2. XFI interface support and module parameters for selection of Port0 and Port1 interface
|
||||
* VERSION : 01-00-01
|
||||
* 15 Jul 2021 : 1. USXGMII/XFI/SGMII/RGMII interface supported without module parameter
|
||||
* VERSION : 01-00-02
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
@ -53,10 +55,6 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/prefetch.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
#include <linux/net_tstamp.h>
|
||||
#include <linux/phylink.h>
|
||||
#include <linux/udp.h>
|
||||
@ -71,6 +69,11 @@
|
||||
#include "hwif.h"
|
||||
#include "common.h"
|
||||
#include "tc956xmac_ioctl.h"
|
||||
#include "tc956x_ipa_intf.h"
|
||||
#ifdef CONFIG_DEBUG_FS_TC956X
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#endif /* CONFIG_DEBUG_FS_TC956X */
|
||||
|
||||
#ifdef TC956X_PCIE_LOGSTAT
|
||||
#include "tc956x_pcie_logstat.h"
|
||||
@ -137,7 +140,7 @@ MODULE_PARM_DESC(chain_mode, "To use chain instead of ring mode");
|
||||
|
||||
static irqreturn_t tc956xmac_interrupt(int irq, void *dev_id);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#ifdef CONFIG_DEBUG_FS_TC956X
|
||||
static const struct net_device_ops tc956xmac_netdev_ops;
|
||||
static void tc956xmac_init_fs(struct net_device *dev);
|
||||
static void tc956xmac_exit_fs(struct net_device *dev);
|
||||
@ -1252,8 +1255,7 @@ static void tc956xmac_mac_pcs_get_state(struct phylink_config *config,
|
||||
reg_value = tc956x_xpcs_read(priv->xpcsaddr, XGMAC_VR_MII_AN_INTR_STS);
|
||||
if (reg_value & XGMAC_C37_AN_COMPL) {/*check if AN 37 is complete CL37_ANCMPLT_INTR*/
|
||||
KPRINT_INFO("AN clause 37 completed");
|
||||
if ((priv->plat->interface == PHY_INTERFACE_MODE_USXGMII) ||
|
||||
(priv->plat->interface == PHY_INTERFACE_MODE_10GKR)) {
|
||||
if (priv->plat->interface == PHY_INTERFACE_MODE_USXGMII) {
|
||||
if (reg_value & XGMAC_USXG_AN_STS_LINK_MASK) {/*check link status*/
|
||||
state->link = 1;
|
||||
KPRINT_INFO("XPCS USXGMII link up");
|
||||
@ -1285,10 +1287,10 @@ static void tc956xmac_mac_pcs_get_state(struct phylink_config *config,
|
||||
state->duplex = DUPLEX_HALF;
|
||||
|
||||
if (((reg_value & XGMAC_SGM_STS_SPEED_MASK) >> 2) == 0x2) {/*SGMII autonegotiated speed */
|
||||
if (priv->is_sgmii_2p5g == true)
|
||||
state->speed = SPEED_2500; /*There is no seperate bit check for 2.5Gbps, so set here */
|
||||
else
|
||||
if (priv->is_sgmii_2p5g == SGMII_2P5G_DISABLED)
|
||||
state->speed = SPEED_1000;
|
||||
else
|
||||
state->speed = SPEED_2500; /*There is no seperate bit check for 2.5Gbps, so set here */
|
||||
} else if (((reg_value & XGMAC_SGM_STS_SPEED_MASK) >> 2) == 0x1)
|
||||
state->speed = SPEED_100;
|
||||
} else {
|
||||
@ -1312,8 +1314,7 @@ static int tc956xmac_mac_link_state(struct phylink_config *config,
|
||||
reg_value = tc956x_xpcs_read(priv->xpcsaddr, XGMAC_VR_MII_AN_INTR_STS);
|
||||
if (reg_value & XGMAC_C37_AN_COMPL) {/*check if AN 37 is complete CL37_ANCMPLT_INTR*/
|
||||
KPRINT_INFO("AN clause 37 completed");
|
||||
if ((priv->plat->interface == PHY_INTERFACE_MODE_USXGMII) ||
|
||||
(priv->plat->interface == PHY_INTERFACE_MODE_10GKR)) {
|
||||
if (priv->plat->interface == PHY_INTERFACE_MODE_USXGMII) {
|
||||
if (reg_value & XGMAC_USXG_AN_STS_LINK_MASK) {/*check link status*/
|
||||
state->link = 1;
|
||||
KPRINT_INFO("XPCS USXGMII link up");
|
||||
@ -1349,10 +1350,11 @@ static int tc956xmac_mac_link_state(struct phylink_config *config,
|
||||
state->duplex = DUPLEX_HALF;
|
||||
/*SGMII autonegotiated speed */
|
||||
if (((reg_value & XGMAC_SGM_STS_SPEED_MASK) >> 2) == 0x2) {
|
||||
if (priv->is_sgmii_2p5g == true)
|
||||
state->speed = SPEED_2500; /*There is no seperate bit check for 2.5Gbps, so set here */
|
||||
else
|
||||
if (priv->is_sgmii_2p5g == SGMII_2P5G_DISABLED)
|
||||
state->speed = SPEED_1000;
|
||||
else
|
||||
/*There is no seperate bit check for 2.5Gbps, so set here */
|
||||
state->speed = SPEED_2500;
|
||||
} else if (((reg_value & XGMAC_SGM_STS_SPEED_MASK) >> 2) == 0x1)
|
||||
state->speed = SPEED_100;
|
||||
} else {
|
||||
@ -1368,72 +1370,71 @@ static int tc956xmac_mac_link_state(struct phylink_config *config,
|
||||
#endif
|
||||
|
||||
/**
|
||||
* tc956xmac_speed_change_init_mac - Initialize MAC during speed change.
|
||||
* tc956xmac_sgmii_init_mac - Initialize MAC during speed change.
|
||||
* @priv: driver private structure
|
||||
* @state : phy state structure
|
||||
* Description: It is used for initializing MAC during speed change of
|
||||
* USXGMII and SGMII.
|
||||
* @is_2p5g: is speed 2.5G
|
||||
* Description: It is used for initializing MAC during speed change.
|
||||
*/
|
||||
void tc956xmac_speed_change_init_mac(struct tc956xmac_priv *priv,
|
||||
const struct phylink_link_state *state)
|
||||
void tc956xmac_sgmii_init_mac(struct tc956xmac_priv *priv)
|
||||
{
|
||||
/* use signal from EMSPHY */
|
||||
uint8_t SgmSigPol = 0;
|
||||
int ret = 0;
|
||||
bool enable_an = true;
|
||||
|
||||
if (priv->port_num == RM_PF0_ID) {
|
||||
/* Enable all clocks to eMAC Port0 */
|
||||
ret = readl(priv->tc956x_SFR_pci_base_addr + NCLKCTRL0_OFFSET);
|
||||
if ((state->interface == PHY_INTERFACE_MODE_SGMII) &&
|
||||
(state->speed == SPEED_2500)) {
|
||||
if (priv->is_sgmii_2p5g) {
|
||||
ret &= ~NCLKCTRL0_MAC0125CLKEN;
|
||||
ret &= ~NCLKCTRL0_MAC0312CLKEN;
|
||||
} else {
|
||||
ret &= ~NCLKCTRL0_MAC0312CLKEN;
|
||||
ret |= NCLKCTRL0_MAC0125CLKEN;
|
||||
}
|
||||
writel(ret, priv->tc956x_SFR_pci_base_addr + NCLKCTRL0_OFFSET);
|
||||
|
||||
/* Interface configuration for port0*/
|
||||
ret = readl(priv->tc956x_SFR_pci_base_addr + NEMAC0CTL_OFFSET);
|
||||
ret &= ~(NEMACCTL_SP_SEL_MASK | NEMACCTL_PHY_INF_SEL_MASK);
|
||||
if (state->interface == PHY_INTERFACE_MODE_SGMII) {
|
||||
if (state->speed == SPEED_2500)
|
||||
ret |= NEMACCTL_SP_SEL_SGMII_2500M;
|
||||
else
|
||||
ret |= NEMACCTL_SP_SEL_SGMII_1000M;
|
||||
}
|
||||
if (priv->is_sgmii_2p5g == SGMII_2P5G_ENABLED)
|
||||
ret |= NEMACCTL_SP_SEL_SGMII_2500M;
|
||||
else
|
||||
ret |= NEMACCTL_SP_SEL_SGMII_1000M;
|
||||
|
||||
ret &= ~(0x00000040); /* Mask Polarity */
|
||||
if (SgmSigPol == 1)
|
||||
ret |= 0x00000040; /* Set Active low */
|
||||
ret |= (NEMACCTL_PHY_INF_SEL | NEMACCTL_LPIHWCLKEN);
|
||||
|
||||
ret |= NEMACCTL_PHY_INF_SEL | NEMACCTL_LPIHWCLKEN;
|
||||
writel(ret, priv->tc956x_SFR_pci_base_addr + NEMAC0CTL_OFFSET);
|
||||
}
|
||||
if (priv->port_num == RM_PF1_ID) {
|
||||
/* Enable all clocks to eMAC Port1 */
|
||||
ret = readl(priv->tc956x_SFR_pci_base_addr + NCLKCTRL1_OFFSET);
|
||||
if ((state->interface == PHY_INTERFACE_MODE_SGMII) &&
|
||||
(state->speed == SPEED_2500)) {
|
||||
|
||||
if (priv->is_sgmii_2p5g == SGMII_2P5G_ENABLED) {
|
||||
ret &= ~NCLKCTRL1_MAC1125CLKEN1;
|
||||
ret &= ~NCLKCTRL1_MAC1312CLKEN1;
|
||||
} else {
|
||||
ret &= ~NCLKCTRL1_MAC1312CLKEN1;
|
||||
ret |= NCLKCTRL1_MAC1125CLKEN1;
|
||||
}
|
||||
|
||||
writel(ret, priv->tc956x_SFR_pci_base_addr + NCLKCTRL1_OFFSET);
|
||||
|
||||
/* Interface configuration for port1*/
|
||||
ret = readl(priv->tc956x_SFR_pci_base_addr + NEMAC1CTL_OFFSET);
|
||||
ret &= ~(NEMACCTL_SP_SEL_MASK | NEMACCTL_PHY_INF_SEL_MASK);
|
||||
if (state->interface == PHY_INTERFACE_MODE_SGMII) {
|
||||
if (state->speed == SPEED_2500)
|
||||
ret |= NEMACCTL_SP_SEL_SGMII_2500M;
|
||||
else
|
||||
ret |= NEMACCTL_SP_SEL_SGMII_1000M;
|
||||
}
|
||||
if (priv->is_sgmii_2p5g == SGMII_2P5G_ENABLED)
|
||||
ret |= NEMACCTL_SP_SEL_SGMII_2500M;
|
||||
else
|
||||
ret |= NEMACCTL_SP_SEL_SGMII_1000M;
|
||||
|
||||
ret &= ~(0x00000040); /* Mask Polarity */
|
||||
if (SgmSigPol == 1)
|
||||
ret |= 0x00000040; /* Set Active low */
|
||||
ret |= (NEMACCTL_PHY_INF_SEL | NEMACCTL_LPIHWCLKEN);
|
||||
|
||||
ret |= NEMACCTL_PHY_INF_SEL | NEMACCTL_LPIHWCLKEN;
|
||||
writel(ret, priv->tc956x_SFR_pci_base_addr + NEMAC1CTL_OFFSET);
|
||||
}
|
||||
|
||||
@ -1454,7 +1455,7 @@ void tc956xmac_speed_change_init_mac(struct tc956xmac_priv *priv,
|
||||
|
||||
ret = tc956x_pma_setup(priv, priv->pmaaddr);
|
||||
if (ret < 0)
|
||||
KPRINT_ERR("PMA switching to internal clock Failed\n");
|
||||
printk("PMA switching to internal clock Failed\n");
|
||||
|
||||
if (priv->port_num == RM_PF0_ID) {
|
||||
/* De-assertion of PMA & XPCS reset software Reset*/
|
||||
@ -1479,23 +1480,13 @@ void tc956xmac_speed_change_init_mac(struct tc956xmac_priv *priv,
|
||||
ret = readl(priv->ioaddr + NEMAC1CTL_OFFSET);
|
||||
} while ((NEMACCTL_INIT_DONE & ret) != NEMACCTL_INIT_DONE);
|
||||
}
|
||||
if ((state->interface == PHY_INTERFACE_MODE_SGMII)
|
||||
&& (state->speed == SPEED_2500)) {
|
||||
/* XPCS doesn't support AN for 2.5G SGMII.
|
||||
* Disable AN only if SGMII 2.5G is Enabled.
|
||||
*/
|
||||
priv->is_sgmii_2p5g = true;
|
||||
enable_an = false;
|
||||
} else {
|
||||
priv->is_sgmii_2p5g = false;
|
||||
enable_an = true;
|
||||
}
|
||||
|
||||
ret = tc956x_xpcs_init(priv, priv->xpcsaddr);
|
||||
if (ret < 0)
|
||||
KPRINT_INFO("XPCS initialization error\n");
|
||||
tc956x_xpcs_ctrl_ane(priv, enable_an);
|
||||
|
||||
tc956x_xpcs_ctrl_ane(priv, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void tc956xmac_mac_config(struct phylink_config *config, unsigned int mode,
|
||||
@ -1507,7 +1498,7 @@ static void tc956xmac_mac_config(struct phylink_config *config, unsigned int mod
|
||||
bool config_done = false;
|
||||
|
||||
#ifdef TC956X
|
||||
u32 reg_value;
|
||||
u32 reg_val1, reg_val2;
|
||||
|
||||
ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
|
||||
ctrl &= ~priv->hw->link.speed_mask;
|
||||
@ -1516,15 +1507,34 @@ static void tc956xmac_mac_config(struct phylink_config *config, unsigned int mod
|
||||
emac_ctrl &= ~NEMACCTL_SP_SEL_MASK;
|
||||
|
||||
if (priv->hw->xpcs) {
|
||||
reg_value = tc956x_xpcs_read(priv->xpcsaddr, XGMAC_VR_MII_AN_INTR_STS);
|
||||
if (reg_value & XGMAC_C37_AN_COMPL) {/*check if AN 37 is complete CL37_ANCMPLT_INTR*/
|
||||
KPRINT_INFO("AN clause 37 completed");
|
||||
reg_value &= ~(XGMAC_C37_AN_COMPL);
|
||||
tc956x_xpcs_write(priv->xpcsaddr, XGMAC_VR_MII_AN_INTR_STS, reg_value);
|
||||
KPRINT_INFO("AN clause 37 complete bit cleared");
|
||||
if (state->interface == PHY_INTERFACE_MODE_SGMII) {
|
||||
if (state->speed == SPEED_2500)
|
||||
priv->is_sgmii_2p5g = SGMII_2P5G_ENABLED;
|
||||
else
|
||||
priv->is_sgmii_2p5g = SGMII_2P5G_DISABLED;
|
||||
if((state->speed != SPEED_UNKNOWN) || (state->speed != 0)) {
|
||||
if(state->speed != priv->speed){
|
||||
tc956xmac_sgmii_init_mac(priv);
|
||||
}
|
||||
}
|
||||
}
|
||||
reg_val1 = tc956x_xpcs_read(priv->xpcsaddr, XGMAC_SR_MII_CTRL);
|
||||
reg_val2 = tc956x_xpcs_read(priv->xpcsaddr, XGMAC_VR_MII_AN_INTR_STS);
|
||||
/*if (!((reg_val1 & XGMAC_AN_37_ENABLE) && !(reg_val2 & XGMAC_C37_AN_COMPL))) { */
|
||||
/* Enter always if AN Disabled. */
|
||||
/* And enter only if AN Enabled and AN37 is complete.*/
|
||||
if (1) {
|
||||
/* Enter Always */
|
||||
reg_val2 = tc956x_xpcs_read(priv->xpcsaddr, XGMAC_VR_MII_AN_INTR_STS);
|
||||
if (reg_val2 & XGMAC_C37_AN_COMPL) {
|
||||
/* Clear only if AN Completion Bit is Enabled */
|
||||
KPRINT_INFO("AN clause 37 completed");
|
||||
reg_val2 &= ~(XGMAC_C37_AN_COMPL);
|
||||
tc956x_xpcs_write(priv->xpcsaddr, XGMAC_VR_MII_AN_INTR_STS, reg_val2);
|
||||
KPRINT_INFO("AN clause 37 complete bit cleared");
|
||||
}
|
||||
|
||||
if (state->interface == PHY_INTERFACE_MODE_USXGMII) {
|
||||
|
||||
/* Program autonegotiated speed to SR_MII_CTRL */
|
||||
val = tc956x_xpcs_read(priv->xpcsaddr, XGMAC_SR_MII_CTRL);
|
||||
val &= ~XGMAC_SR_MII_CTRL_SPEED; /* Mask speed ss13, ss6, ss5 */
|
||||
@ -1555,53 +1565,46 @@ static void tc956xmac_mac_config(struct phylink_config *config, unsigned int mod
|
||||
val = tc956x_xpcs_read(priv->xpcsaddr, XGMAC_VR_XS_PCS_DIG_CTRL1);
|
||||
val |= XGMAC_USRA_RST;
|
||||
tc956x_xpcs_write(priv->xpcsaddr, XGMAC_VR_XS_PCS_DIG_CTRL1, val);
|
||||
config_done = true;
|
||||
}
|
||||
}
|
||||
if (state->interface == PHY_INTERFACE_MODE_SGMII) { /* Autonegotiation not supported for SGMII */
|
||||
reg_value = tc956x_xpcs_read(priv->xpcsaddr, XGMAC_VR_MII_AN_INTR_STS);
|
||||
/* Clear autonegotiation only if completed. As for XPCS, 2.5G autonegotiation is not supported */
|
||||
/* Switching from SGMII 2.5G to any speed doesn't cause AN completion */
|
||||
if (reg_value & XGMAC_C37_AN_COMPL) {/*check if AN 37 is complete CL37_ANCMPLT_INTR*/
|
||||
KPRINT_INFO("AN clause 37 completed");
|
||||
reg_value &= ~(XGMAC_C37_AN_COMPL);
|
||||
tc956x_xpcs_write(priv->xpcsaddr, XGMAC_VR_MII_AN_INTR_STS, reg_value);
|
||||
KPRINT_INFO("AN clause 37 complete bit cleared");
|
||||
}
|
||||
/* Invoke this only during speed change */
|
||||
if ((state->speed != SPEED_UNKNOWN) || (state->speed != 0)) {
|
||||
if (state->speed != priv->speed) {
|
||||
tc956xmac_speed_change_init_mac(priv, state);
|
||||
|
||||
} else if (state->interface == PHY_INTERFACE_MODE_SGMII) {
|
||||
switch (state->speed) {
|
||||
case SPEED_2500:
|
||||
ctrl |= priv->hw->link.speed2500;
|
||||
/* Program autonegotiated speed to SR_MII_CTRL */
|
||||
val = tc956x_xpcs_read(priv->xpcsaddr, XGMAC_SR_MII_CTRL);
|
||||
val &= ~XGMAC_SR_MII_CTRL_SPEED; /* Mask speed ss13, ss6, ss5 */
|
||||
val |= XPCS_SS_SGMII_1G; /*1000 Mbps setting only available, so set the same*/
|
||||
tc956x_xpcs_write(priv->xpcsaddr, XGMAC_SR_MII_CTRL, val);
|
||||
emac_ctrl |= NEMACCTL_SP_SEL_SGMII_2500M;
|
||||
break;
|
||||
case SPEED_1000:
|
||||
ctrl |= priv->hw->link.speed1000;
|
||||
val = tc956x_xpcs_read(priv->xpcsaddr, XGMAC_SR_MII_CTRL);
|
||||
val &= ~XGMAC_SR_MII_CTRL_SPEED; /* Mask speed ss13, ss6, ss5 */
|
||||
val |= XPCS_SS_SGMII_1G; /*1000 Mbps setting only available, so set the same*/
|
||||
tc956x_xpcs_write(priv->xpcsaddr, XGMAC_SR_MII_CTRL, val);
|
||||
emac_ctrl |= NEMACCTL_SP_SEL_SGMII_1000M;
|
||||
break;
|
||||
case SPEED_100:
|
||||
ctrl |= priv->hw->link.speed100;
|
||||
val = tc956x_xpcs_read(priv->xpcsaddr, XGMAC_SR_MII_CTRL);
|
||||
val &= ~XGMAC_SR_MII_CTRL_SPEED; /* Mask speed ss13, ss6, ss5 */
|
||||
val |= XPCS_SS_SGMII_100M; /*100 Mbps setting */
|
||||
tc956x_xpcs_write(priv->xpcsaddr, XGMAC_SR_MII_CTRL, val);
|
||||
emac_ctrl |= NEMACCTL_SP_SEL_SGMII_100M;
|
||||
break;
|
||||
case SPEED_10:
|
||||
ctrl |= priv->hw->link.speed10;
|
||||
val = tc956x_xpcs_read(priv->xpcsaddr, XGMAC_SR_MII_CTRL);
|
||||
val &= ~XGMAC_SR_MII_CTRL_SPEED; /* Mask speed ss13, ss6, ss5 */
|
||||
val |= XPCS_SS_SGMII_10M; /*10 Mbps setting */
|
||||
tc956x_xpcs_write(priv->xpcsaddr, XGMAC_SR_MII_CTRL, val);
|
||||
emac_ctrl |= NEMACCTL_SP_SEL_SGMII_10M;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
val = tc956x_xpcs_read(priv->xpcsaddr, XGMAC_SR_MII_CTRL);
|
||||
val &= ~XGMAC_SR_MII_CTRL_SPEED; /* Mask speed ss13, ss6, ss5 */
|
||||
switch (state->speed) {
|
||||
case SPEED_2500:
|
||||
ctrl |= priv->hw->link.speed2500;
|
||||
/* Program autonegotiated speed to SR_MII_CTRL */
|
||||
val |= XPCS_SS_SGMII_1G; /*1000 Mbps setting only available, so set the same*/
|
||||
emac_ctrl |= NEMACCTL_SP_SEL_SGMII_2500M;
|
||||
break;
|
||||
case SPEED_1000:
|
||||
ctrl |= priv->hw->link.speed1000;
|
||||
val |= XPCS_SS_SGMII_1G; /*1000 Mbps setting only available, so set the same*/
|
||||
emac_ctrl |= NEMACCTL_SP_SEL_SGMII_1000M;
|
||||
break;
|
||||
case SPEED_100:
|
||||
ctrl |= priv->hw->link.speed100;
|
||||
val |= XPCS_SS_SGMII_100M; /*100 Mbps setting */
|
||||
emac_ctrl |= NEMACCTL_SP_SEL_SGMII_100M;
|
||||
break;
|
||||
case SPEED_10:
|
||||
ctrl |= priv->hw->link.speed10;
|
||||
val |= XPCS_SS_SGMII_10M; /*10 Mbps setting */
|
||||
emac_ctrl |= NEMACCTL_SP_SEL_SGMII_10M;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
tc956x_xpcs_write(priv->xpcsaddr, XGMAC_SR_MII_CTRL, val);
|
||||
config_done = true;
|
||||
}
|
||||
} else if (state->interface == PHY_INTERFACE_MODE_RGMII) {
|
||||
@ -1667,26 +1670,10 @@ static void tc956xmac_mac_an_restart(struct phylink_config *config)
|
||||
{
|
||||
#ifdef TC956X
|
||||
struct tc956xmac_priv *priv = netdev_priv(to_net_dev(config->dev));
|
||||
bool enable_en = true;
|
||||
|
||||
if (priv->hw->xpcs) {
|
||||
/*Enable XPCS Autoneg*/
|
||||
if (priv->plat->interface == PHY_INTERFACE_MODE_10GKR) {
|
||||
enable_en = false;
|
||||
KPRINT_INFO("%s :Port %d AN Enable:%d", __func__, priv->port_num, enable_en);
|
||||
} else if (priv->plat->interface == PHY_INTERFACE_MODE_SGMII) {
|
||||
if (priv->is_sgmii_2p5g == true) {
|
||||
enable_en = false;
|
||||
KPRINT_INFO("%s : Port %d AN Enable:%d", __func__, priv->port_num, enable_en);
|
||||
} else {
|
||||
enable_en = true;
|
||||
KPRINT_INFO("%s : Port %d AN Enable:%d", __func__, priv->port_num, enable_en);
|
||||
}
|
||||
} else {
|
||||
enable_en = true;
|
||||
KPRINT_INFO("%s : Port %d AN Enable:%d", __func__, priv->port_num, enable_en);
|
||||
}
|
||||
tc956x_xpcs_ctrl_ane(priv, enable_en);
|
||||
tc956x_xpcs_ctrl_ane(priv, 1);
|
||||
}
|
||||
#else
|
||||
/*Not supported*/
|
||||
@ -1758,9 +1745,8 @@ static void tc956xmac_check_pcs_mode(struct tc956xmac_priv *priv)
|
||||
#ifdef TC956X
|
||||
priv->hw->pcs = TC956XMAC_PCS_SGMII;
|
||||
#endif
|
||||
} else if ((interface == PHY_INTERFACE_MODE_USXGMII) ||
|
||||
(interface == PHY_INTERFACE_MODE_10GKR)) {
|
||||
netdev_dbg(priv->dev, "PCS USXGMII/XFI support enabled\n");
|
||||
} else if (interface == PHY_INTERFACE_MODE_USXGMII) {
|
||||
netdev_dbg(priv->dev, "PCS USXGMII support enabled\n");
|
||||
#ifdef TC956X
|
||||
priv->hw->pcs = TC956XMAC_PCS_USXGMII;
|
||||
#endif
|
||||
@ -1773,8 +1759,7 @@ static void tc956xmac_check_pcs_mode(struct tc956xmac_priv *priv)
|
||||
} else if (interface == PHY_INTERFACE_MODE_SGMII) {
|
||||
netdev_dbg(priv->dev, "PCS SGMII support enabled\n");
|
||||
priv->hw->xpcs = TC956XMAC_PCS_SGMII;
|
||||
} else if ((interface == PHY_INTERFACE_MODE_USXGMII) ||
|
||||
(interface == PHY_INTERFACE_MODE_10GKR)) {
|
||||
} else if (interface == PHY_INTERFACE_MODE_USXGMII) {
|
||||
netdev_dbg(priv->dev, "PCS USXGMII support enabled\n");
|
||||
priv->hw->xpcs = TC956XMAC_PCS_USXGMII;
|
||||
}
|
||||
@ -3610,7 +3595,6 @@ static int tc956xmac_hw_setup(struct net_device *dev, bool init_ptp)
|
||||
struct tc956xmac_priv *priv = netdev_priv(dev);
|
||||
#ifdef TC956X
|
||||
u32 rx_cnt = priv->plat->rx_queues_to_use;
|
||||
bool enable_en = true;
|
||||
#endif
|
||||
|
||||
u32 tx_cnt = priv->plat->tx_queues_to_use;
|
||||
@ -3703,19 +3687,9 @@ static int tc956xmac_hw_setup(struct net_device *dev, bool init_ptp)
|
||||
}
|
||||
|
||||
#ifdef TC956X
|
||||
if (priv->hw->xpcs) {
|
||||
if (priv->hw->xpcs)
|
||||
/*C37 AN enable*/
|
||||
if (priv->plat->interface == PHY_INTERFACE_MODE_10GKR)
|
||||
enable_en = false;
|
||||
else if (priv->plat->interface == PHY_INTERFACE_MODE_SGMII) {
|
||||
if (priv->is_sgmii_2p5g == true)
|
||||
enable_en = false;
|
||||
else
|
||||
enable_en = true;
|
||||
} else
|
||||
enable_en = true;
|
||||
tc956x_xpcs_ctrl_ane(priv, enable_en);
|
||||
}
|
||||
tc956x_xpcs_ctrl_ane(priv, 1);
|
||||
#else
|
||||
if (priv->hw->pcs)
|
||||
tc956xmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, priv->hw->ps, 0);
|
||||
@ -8956,9 +8930,73 @@ static int tc956xmac_set_mac_address(struct net_device *ndev, void *addr)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#ifdef CONFIG_DEBUG_FS_TC956X
|
||||
static struct dentry *tc956xmac_fs_dir;
|
||||
|
||||
int read_rxp_stats(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
int i;
|
||||
unsigned int buf_len = 4000;
|
||||
unsigned int len = 0;
|
||||
char *buf;
|
||||
ssize_t ret_cnt;
|
||||
struct tc956xmac_priv *priv = file->private_data;
|
||||
struct tc956xmac_rx_parser_cfg *cfg;
|
||||
if (!priv) {
|
||||
printk(KERN_ERR "%s, Error: priv is null\n", __func__);
|
||||
return count;
|
||||
}
|
||||
|
||||
cfg = &priv->plat->rxp_cfg;
|
||||
if (!cfg) {
|
||||
printk(KERN_ERR "%s, Error: cfg is null\n", __func__);
|
||||
return count;
|
||||
}
|
||||
|
||||
buf = kzalloc(buf_len, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
len += scnprintf(buf + len, buf_len - len,
|
||||
"\n************* READ RXP STATS *************\n");
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "est_enabled = %x \n", priv->rxp_enabled);
|
||||
len += scnprintf(buf + len, buf_len - len, "frpes = %x \n", priv->dma_cap.frpes);
|
||||
len += scnprintf(buf + len, buf_len - len, "nve = %x \n", cfg->nve);
|
||||
len += scnprintf(buf + len, buf_len - len, "npe = %x \n", cfg->npe);
|
||||
|
||||
for(i = 0; i < cfg->nve; i++ ) {
|
||||
len += scnprintf(buf + len, buf_len - len, "cfg.entries[%d].match_data= %x \n", i, cfg->entries[i].match_data);
|
||||
len += scnprintf(buf + len, buf_len - len, "cfg.entries[%d].match_en= %x \n",i,cfg->entries[i].match_en);
|
||||
len += scnprintf(buf + len, buf_len - len, "cfg.entries[%d].af = %x \n",i,cfg->entries[i].af);
|
||||
len += scnprintf(buf + len, buf_len - len, "cfg.entries[%d].rf = %x \n",i,cfg->entries[i].rf);
|
||||
len += scnprintf(buf + len, buf_len - len, "cfg.entries[%d].im = %x \n",i,cfg->entries[i].im);
|
||||
len += scnprintf(buf + len, buf_len - len, "cfg.entries[%d].nc = %x \n",i,cfg->entries[i].nc);
|
||||
len += scnprintf(buf + len, buf_len - len, "cfg.entries[%d].res1 = %x \n",i,cfg->entries[i].res1);
|
||||
len += scnprintf(buf + len, buf_len - len, "cfg.entries[%d].frame_offset= %x \n",i,cfg->entries[i].frame_offset);
|
||||
len += scnprintf(buf + len, buf_len - len, "cfg.entries[%d].ok_index= %x \n",i,cfg->entries[i].ok_index);
|
||||
len += scnprintf(buf + len, buf_len - len, "cfg.entries[%d].dma_ch_no= %x \n",i,cfg->entries[i].dma_ch_no);
|
||||
len += scnprintf(buf + len, buf_len - len, "cfg.entries[%d].res2= %x \n",i,cfg->entries[i].res2);
|
||||
}
|
||||
ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
kfree(buf);
|
||||
return ret_cnt;
|
||||
}
|
||||
|
||||
#ifdef DMA_OFFLOAD_ENABLE
|
||||
static const struct file_operations tc956xmac_ipa_stats_fops = {
|
||||
.read = read_ipa_desc_stats,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
#endif
|
||||
static const struct file_operations tc956xmac_rxp_stats_fops = {
|
||||
.read = read_rxp_stats,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
#ifdef TC956X_UNSUPPORTED_UNTESETD_FEATURE
|
||||
static void sysfs_display_ring(void *head, int size, int extend_desc,
|
||||
struct seq_file *seq)
|
||||
@ -9168,14 +9206,15 @@ static struct notifier_block tc956xmac_notifier = {
|
||||
.notifier_call = tc956xmac_device_event,
|
||||
};
|
||||
#endif
|
||||
|
||||
static void tc956xmac_init_fs(struct net_device *dev)
|
||||
{
|
||||
struct tc956xmac_priv *priv = netdev_priv(dev);
|
||||
|
||||
#ifndef TC956X
|
||||
/* Create per netdev entries */
|
||||
priv->dbgfs_dir = debugfs_create_dir(dev->name, tc956xmac_fs_dir);
|
||||
|
||||
#ifndef TC956X
|
||||
/* Entry to report DMA RX/TX rings */
|
||||
debugfs_create_file("descriptors_status", 0444, priv->dbgfs_dir, dev,
|
||||
&tc956xmac_rings_status_fops);
|
||||
@ -9185,6 +9224,14 @@ static void tc956xmac_init_fs(struct net_device *dev)
|
||||
&tc956xmac_dma_cap_fops);
|
||||
|
||||
register_netdevice_notifier(&tc956xmac_notifier);
|
||||
#else
|
||||
priv->dbgfs_dir = debugfs_create_dir(dev->name, NULL);
|
||||
#ifdef DMA_OFFLOAD_ENABLE
|
||||
debugfs_create_file("ipa_stats", S_IRUSR, priv->dbgfs_dir, priv,
|
||||
&tc956xmac_ipa_stats_fops);
|
||||
#endif
|
||||
debugfs_create_file("rxp_stats", S_IRUSR, priv->dbgfs_dir, priv,
|
||||
&tc956xmac_rxp_stats_fops);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -9196,7 +9243,7 @@ static void tc956xmac_exit_fs(struct net_device *dev)
|
||||
#endif
|
||||
debugfs_remove_recursive(priv->dbgfs_dir);
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
#endif /* CONFIG_DEBUG_FS_TC956X */
|
||||
|
||||
#ifndef TC956X
|
||||
static u32 tc956xmac_vid_crc32_le(__le16 vid_le)
|
||||
@ -9720,13 +9767,13 @@ int tc956xmac_dvr_probe(struct device *device,
|
||||
priv->port_num = res->port_num;
|
||||
priv->dev->base_addr = (unsigned long)res->addr;
|
||||
if (priv->plat->interface == PHY_INTERFACE_MODE_SGMII)
|
||||
priv->is_sgmii_2p5g = true;
|
||||
priv->is_sgmii_2p5g = SGMII_2P5G_ENABLED;
|
||||
else
|
||||
priv->is_sgmii_2p5g = false;
|
||||
priv->is_sgmii_2p5g = SGMII_DISABLED;
|
||||
priv->dev->irq = res->irq;
|
||||
priv->wol_irq = res->wol_irq;
|
||||
priv->lpi_irq = res->lpi_irq;
|
||||
priv->port_interface = res->port_interface;
|
||||
|
||||
#ifdef DMA_OFFLOAD_ENABLE
|
||||
priv->client_priv = NULL;
|
||||
#endif
|
||||
@ -10063,10 +10110,9 @@ int tc956xmac_dvr_probe(struct device *device,
|
||||
goto error_netdev_register;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#ifdef CONFIG_DEBUG_FS_TC956X
|
||||
tc956xmac_init_fs(ndev);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
|
||||
error_netdev_register:
|
||||
@ -10110,7 +10156,7 @@ int tc956xmac_dvr_remove(struct device *dev)
|
||||
|
||||
netdev_info(priv->dev, "%s: removing driver", __func__);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#ifdef CONFIG_DEBUG_FS_TC956X
|
||||
tc956xmac_exit_fs(ndev);
|
||||
#endif
|
||||
tc956xmac_stop_all_dma(priv);
|
||||
@ -10403,7 +10449,7 @@ __setup("tc956xmaceth=", tc956xmac_cmdline_opt);
|
||||
#ifdef TC956X
|
||||
int tc956xmac_init(void)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#ifdef CONFIG_DEBUG_FS_TC956X
|
||||
/* Create debugfs main directory if it doesn't exist yet */
|
||||
if (!tc956xmac_fs_dir)
|
||||
tc956xmac_fs_dir = debugfs_create_dir(TC956X_RESOURCE_NAME, NULL);
|
||||
@ -10414,7 +10460,7 @@ int tc956xmac_init(void)
|
||||
|
||||
void tc956xmac_exit(void)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#ifdef CONFIG_DEBUG_FS_TC956X
|
||||
debugfs_remove_recursive(tc956xmac_fs_dir);
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user