Add files via upload

This commit is contained in:
TC956X 2021-07-15 20:32:11 +09:00 committed by jianzhou
parent 4059938c56
commit 992d2b8e09
14 changed files with 382 additions and 301 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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);

View File

@ -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)

View File

@ -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,

View File

@ -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);

View File

@ -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 */

View File

@ -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");

View File

@ -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

View File

@ -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__

View File

@ -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. */

View File

@ -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);

View File

@ -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

View File

@ -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
}