V_01-00-24

1. Runtime configuration of EEE supported and LPI interrupts disabled by default.
2. Module param added to configure EEE and LPI timer.
3. Driver name corrected in ethtool display.
This commit is contained in:
TC956X 2021-11-24 22:58:55 +09:00 committed by jianzhou
parent 941a48f811
commit cfb73b838f
9 changed files with 611 additions and 145 deletions

View File

@ -1,7 +1,7 @@
# Toshiba Electronic Devices & Storage Corporation TC956X PCIe Ethernet Host Driver
Release Date: 24 Nov 2021
Release Version: V_01-00-23 : Limited-tested version
Release Version: V_01-00-24 : Limited-tested version
TC956X PCIe EMAC driver is based on "Fedora 30, kernel-5.4.19".
@ -168,17 +168,39 @@ TC956X PCIe EMAC driver is based on "Fedora 30, kernel-5.4.19".
12. WOL command Usage :
#ethtool -s <interface> wol <type - p/g/d>.
Supported WOL options and meaning:
----------------------------------
Option | Meaning
----------------------------------
p | Wake on phy activity
g | Wake on MagicPacket(tm)
d | Disable (wake on nothing). (Default)
----------------------------------
Example - To wake on phy activity and magic packet use :
ethtool -s eth0 wol pg
Supported WOL options and meaning:
Option | Meaning
p | Wake on phy activity
g | Wake on MagicPacket(tm)
d | Disable (wake on nothing). (Default)
Example - To wake on phy activity and magic packet use :
ethtool -s eth0 wol pg
13. Please use the below command to insert the kernel module to enable EEE and configure LPI Auto Entry timer:
#insmod tc956x_pcie_eth.ko tc956x_port0_enable_eee=X tc956x_port0_lpi_auto_entry_timer=Y tc956x_port1_enable_eee=X tc956x_port1_lpi_auto_entry_timer=Y
argument info:
tc956x_port0_enable_eee: For PORT0
tc956x_port1_enable_eee: For PORT1
X = [0: DISABLE (default), 1: ENABLE]
This module parameter is to Enable/Disable EEE for Port 0/1 - default is 0.
If invalid values are passed as kernel module parameter, the default value will be selected.
tc956x_port0_lpi_auto_entry_timer: For PORT0
tc956x_port1_lpi_auto_entry_timer: For PORT1
Y = [0..1048568 (us)]
This module parameter is to configure LPI Automatic Entry Timer for Port 0/1 - default is 600 (us).
If invalid values are passed as kernel module parameter, the default value will be selected.
In addition to above module parameter, use below ethtool command to configure EEE and LPI auto entry timer.
#ethtool --set-eee <interfcae> eee <on/off> tx-timer <time in us>
Example: #ethtool --set-eee enp7s0f0 eee on tx-timer 10000
Use below command to check the status of EEE configuration
#ethtool --show-eee <interface>
# Release Versions:
@ -302,3 +324,9 @@ ethtool -s eth0 wol pg
1. Restricted MDIO access when no PHY found or MDIO registration fails
2. Added mdio lock for making mii bus of private member to null to avoid parallel accessing to MDIO bus
## TC956X_Host_Driver_20211124_V_01-00-24:
1. Runtime configuration of EEE supported and LPI interrupts disabled by default.
2. Module param added to configure EEE and LPI timer.
3. Driver name corrected in ethtool display.

View File

@ -63,6 +63,8 @@
* VERSION : 01-00-21
* 24 Nov 2021 : 1. Single Port Suspend/Resume supported
* VERSION : 01-00-22
* 24 Nov 2021 : 1. EEE update for runtime configuration and LPI interrupt disabled.
* VERSION : 01-00-24
*/
#ifndef __COMMON_H__
@ -88,7 +90,7 @@
/* Enable DMA IPA offload */
#define DMA_OFFLOAD_ENABLE
//#define TC956X_LPI_INTERRUPT
/* Indepenedent Suspend/Resume Debug */
#undef TC956X_PM_DEBUG
#define TC956X_MAX_PORT 2
@ -116,7 +118,7 @@ enum TC956X_PORT_PM_STATE {
#define DWXGMAC_CORE_3_01 0x30
//#define DISABLE_EMAC_PORT1
//#define EEE /* Enable for EEE support */
#define EEE /* Enable for EEE support */
/* Note: Multiple macro definitions for TC956X_PCIE_LOGSTAT.
* Please also define/undefine same macro in tc956xmac_ioctl.h, if changing in this file
@ -1055,7 +1057,11 @@ entry delay = n * 256 ns */
#define TC956X_MSI_PF1 (0x000)
#endif
#ifdef TC956X_LPI_INTERRUPT
#define ENABLE_MSI_INTR (0x17FFFD)
#else
#define ENABLE_MSI_INTR (0x17FFFC)
#endif
#define TC956X_MSI_OUT_EN_OFFSET(pf_id) (TC956X_MSI_BASE + \
(pf_id * TC956X_MSI_PF1) + (0x0000))
@ -1585,6 +1591,9 @@ struct dma_features {
#define TC956X_SIXTEEN 16
#define TC956X_TWENTY_FOUR 24
#define TC956X_MIN_LPI_AUTO_ENTRY_TIMER 0
#define TC956X_MAX_LPI_AUTO_ENTRY_TIMER 0xFFFF8 /* LPI Entry timer is in the units of 8 micro second granularity. So mask the last 3 bits. */
extern const struct tc956xmac_desc_ops enh_desc_ops;
extern const struct tc956xmac_desc_ops ndesc_ops;

View File

@ -54,6 +54,9 @@
* VERSION : 01-00-19
* 04 Nov 2021 : 1. Added separate control functons for MAC TX and RX start/stop
* VERSION : 01-00-20
* 24 Nov 2021 : 1. EEE update for runtime configuration and LPI interrupt disabled.
2. USXGMII support during link change
* VERSION : 01-00-24
*/
#include <linux/bitrev.h>
@ -101,8 +104,14 @@ static void dwxgmac2_core_init(struct tc956xmac_priv *priv,
case SPEED_10000:
tx |= hw->link.xgmii.speed10000;
break;
case SPEED_5000:
if (priv->plat->interface == PHY_INTERFACE_MODE_USXGMII)
tx |= hw->link.xgmii.speed5000;
break;
case SPEED_2500:
if (priv->plat->interface == PHY_INTERFACE_MODE_SGMII)
if (priv->plat->interface == PHY_INTERFACE_MODE_USXGMII)
tx |= hw->link.xgmii.speed2500;
else
tx |= hw->link.speed2500;
break;
case SPEED_1000:
@ -122,8 +131,9 @@ static void dwxgmac2_core_init(struct tc956xmac_priv *priv,
#endif
writel(tx, ioaddr + XGMAC_TX_CONFIG);
writel(rx, ioaddr + XGMAC_RX_CONFIG);
#ifdef TC956X_LPI_INTERRUPT
writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN);
#endif
netdev_dbg(priv->dev, "%s: MAC TX Config = 0x%x", __func__,
readl(ioaddr + XGMAC_TX_CONFIG));
@ -642,6 +652,9 @@ static void dwxgmac2_reset_eee_mode(struct tc956xmac_priv *priv,
value = readl(ioaddr + XGMAC_LPI_CTRL);
value &= ~(XGMAC_LPITXEN | XGMAC_LPITXA | XGMAC_TXCGE);
#ifdef EEE_MAC_CONTROLLED_MODE
value &= ~(XGMAC_PLS | XGMAC_PLSDIS | XGMAC_LPIATE);
#endif
writel(value, ioaddr + XGMAC_LPI_CTRL);
}
@ -2169,7 +2182,7 @@ static void dwxgmac2_disable_tx_vlan(struct tc956xmac_priv *priv,
value = readl(ioaddr + XGMAC_VLAN_INCL);
value &= ~XGMAC_VLAN_VLTI;
value &= ~XGMAC_VLAN_VLC;
writel(value, ioaddr + XGMAC_VLAN_INCL);
writel(value, ioaddr + XGMAC_VLAN_INCL);
}
static void dwxgmac2_enable_rx_vlan_stripping(struct tc956xmac_priv *priv,

4
mmc.h
View File

@ -32,6 +32,8 @@
* VERSION : 01-00
* 26 Oct 2021 : 1. Added EEE mmc counters for MAC COntrolled mode.
* VERSION : 01-00-19
* 24 Nov 2021 : 1. EEE update for runtime configuration and LPI interrupt disabled.
* VERSION : 01-00-24
*/
#ifndef __MMC_H__
@ -83,12 +85,10 @@ struct tc956xmac_counters {
u64 mmc_tx_excessdef;
u64 mmc_tx_pause_frame;
u64 mmc_tx_vlan_frame_g;
#ifdef EEE_MAC_CONTROLLED_MODE
u64 mmc_tx_lpi_us_cntr;
u64 mmc_tx_lpi_tran_cntr;
u64 mmc_rx_lpi_us_cntr;
u64 mmc_rx_lpi_tran_cntr;
#endif
u64 mmc_tx_per_priority_pkt;
u64 mmc_tx_per_priority_pfc_pkt;
u64 mmc_tx_per_priority_gpfc_pkt;

View File

@ -30,6 +30,8 @@
*
* 15 Mar 2021 : Base lined
* VERSION : 01-00
* 24 Nov 2021 : 1. EEE HW counter support.
* VERSION : 01-00-24
*/
#include <linux/kernel.h>
@ -464,6 +466,10 @@ static void dwxgmac_mmc_read(struct tc956xmac_priv *priv, void __iomem *mmcaddr,
dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_TX_PER_PRIOR_OCTET_GB,
&mmc->mmc_tx_per_priority_octet_gb);
/* MMC EEE registers */
mmc->mmc_tx_lpi_tran_cntr += readl(mmcaddr + MMC_XGMAC_TX_LPI_TRAN);
mmc->mmc_rx_lpi_tran_cntr += readl(mmcaddr + MMC_XGMAC_RX_LPI_TRAN);
/* MMC RX counter registers */
dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_PKT_GB,
&mmc->mmc_rx_framecount_gb);

View File

@ -89,6 +89,9 @@
* VERSION : 01-00-22
* 24 Nov 2021 : 1. Version update
* VERSION : 01-00-23
* 24 Nov 2021 : 1. Module param support for EEE enable/disable and LPI timer configuration.
2. Version update
* VERSION : 01-00-24
*/
#include <linux/clk-provider.h>
@ -121,7 +124,12 @@ static unsigned int tc956x_port1_interface = ENABLE_SGMII_INTERFACE;
unsigned int tc956x_port0_filter_phy_pause_frames = DISABLE;
unsigned int tc956x_port1_filter_phy_pause_frames = DISABLE;
static const struct tc956x_version tc956x_drv_version = {0, 1, 0, 0, 2, 3};
static unsigned int tc956x_port0_enable_eee = DISABLE;
static unsigned int tc956x_port0_lpi_auto_entry_timer = TC956XMAC_LPIET_600US;
static unsigned int tc956x_port1_enable_eee = DISABLE;
static unsigned int tc956x_port1_lpi_auto_entry_timer = TC956XMAC_LPIET_600US;
static const struct tc956x_version tc956x_drv_version = {0, 1, 0, 0, 2, 4};
static int tc956xmac_pm_usage_counter; /* Device Usage Counter */
struct mutex tc956x_pm_suspend_lock; /* This mutex is shared between all available EMAC ports. */
@ -2073,6 +2081,44 @@ static int tc956xmac_pci_probe(struct pci_dev *pdev,
plat->port_interface = res.port_interface;
if (res.port_num == RM_PF0_ID) {
if ((tc956x_port0_enable_eee != DISABLE) &&
(tc956x_port0_enable_eee != ENABLE)) {
tc956x_port0_enable_eee = DISABLE;
NMSGPR_INFO(&(pdev->dev), "%s: ERROR Invalid tc956x_port0_enable_eee parameter passed. Restoring default to %d. Supported Values are 0 and 1.\n",
__func__, tc956x_port1_enable_eee);
}
if ((tc956x_port0_enable_eee == ENABLE) &&
(tc956x_port0_lpi_auto_entry_timer > TC956X_MAX_LPI_AUTO_ENTRY_TIMER)) {
tc956x_port0_lpi_auto_entry_timer = TC956XMAC_LPIET_600US;
NMSGPR_INFO(&(pdev->dev), "%s: ERROR Invalid tc956x_port0_lpi_auto_entry_timer parameter passed. Restoring default to %d. Supported Values between %d and %d.\n",
__func__, tc956x_port1_lpi_auto_entry_timer,
TC956X_MIN_LPI_AUTO_ENTRY_TIMER, TC956X_MAX_LPI_AUTO_ENTRY_TIMER);
}
res.eee_enabled = tc956x_port0_enable_eee;
res.tx_lpi_timer = tc956x_port0_lpi_auto_entry_timer;
}
if (res.port_num == RM_PF1_ID) {
if ((tc956x_port1_enable_eee != DISABLE) &&
(tc956x_port1_enable_eee != ENABLE)) {
tc956x_port1_enable_eee = DISABLE;
NMSGPR_INFO(&(pdev->dev), "%s: ERROR Invalid tc956x_port1_enable_eee parameter passed. Restoring default to %d. Supported Values are 0 and 1.\n",
__func__, tc956x_port1_enable_eee);
}
if ((tc956x_port0_enable_eee == ENABLE) &&
(tc956x_port1_lpi_auto_entry_timer > TC956X_MAX_LPI_AUTO_ENTRY_TIMER)) {
tc956x_port1_lpi_auto_entry_timer = TC956XMAC_LPIET_600US;
NMSGPR_INFO(&(pdev->dev), "%s: ERROR Invalid tc956x_port1_lpi_auto_entry_timer parameter passed. Restoring default to %d. Supported Values between %d and %d.\n",
__func__, tc956x_port1_lpi_auto_entry_timer,
TC956X_MIN_LPI_AUTO_ENTRY_TIMER, TC956X_MAX_LPI_AUTO_ENTRY_TIMER);
}
res.eee_enabled = tc956x_port1_enable_eee;
res.tx_lpi_timer = tc956x_port1_lpi_auto_entry_timer;
}
ret = info->setup(pdev, plat);
if (ret)
@ -3061,6 +3107,26 @@ MODULE_PARM_DESC(tc956x_port1_filter_phy_pause_frames,
"Filter PHY pause frames alone and pass Link partner pause frames to application in PORT1 - default is 0,\
[0: DISABLE, 1: ENABLE]");
module_param(tc956x_port0_enable_eee, uint, 0444);
MODULE_PARM_DESC(tc956x_port0_enable_eee,
"Enable/Disable EEE for Port 0 - default is 0,\
[0: DISABLE, 1: ENABLE]");
module_param(tc956x_port0_lpi_auto_entry_timer, uint, 0444);
MODULE_PARM_DESC(tc956x_port0_lpi_auto_entry_timer,
"LPI Automatic Entry Timer for Port 0 - default is 600 (us),\
[Range Supported : 0..1048568 (us)]");
module_param(tc956x_port1_enable_eee, uint, 0444);
MODULE_PARM_DESC(tc956x_port1_enable_eee,
"Enable/Disable EEE for Port 1 - default is 0,\
[0: DISABLE, 1: ENABLE]");
module_param(tc956x_port1_lpi_auto_entry_timer, uint, 0444);
MODULE_PARM_DESC(tc956x_port1_lpi_auto_entry_timer,
"LPI Automatic Entry Timer for Port 1 - default is 600 (us),\
[Range Supported : 0..1048568 (us)]");
MODULE_DESCRIPTION("TC956X PCI Express Ethernet Network Driver");
MODULE_AUTHOR("Toshiba Electronic Devices & Storage Corporation");
MODULE_LICENSE("GPL v2");

View File

@ -88,6 +88,10 @@
* VERSION : 01-00-22
* 24 Nov 2021 : 1. Version update
* VERSION : 01-00-23
* 24 Nov 2021 : 1. EEE macro enabled by default.
2. Module param support for EEE configuration
3. Version update
* VERSION : 01-00-24
*/
#ifndef __TC956XMAC_H__
@ -110,9 +114,9 @@
#define PF_DRIVER 4
/* Uncomment EEE_MAC_CONTROLLED_MODE macro for MAC controlled EEE Mode & comment for PHY controlled EEE mode */
//#define EEE_MAC_CONTROLLED_MODE
#define EEE_MAC_CONTROLLED_MODE
/* Uncomment TC956X_5_G_2_5_G_EEE_SUPPORT macro for enabling EEE support for 5G and 2.5G */
//#define TC956X_5_G_2_5_G_EEE_SUPPORT
#define TC956X_5_G_2_5_G_EEE_SUPPORT
// #define CONFIG_TC956XMAC_SELFTESTS /*Enable this macro to test Feature selftest*/
#ifdef TC956X
@ -140,7 +144,7 @@
#ifdef TC956X
#define TC956X_RESOURCE_NAME "tc956x_pci-eth"
#define DRV_MODULE_VERSION "V_01-00-23"
#define DRV_MODULE_VERSION "V_01-00-24"
#define TC956X_FW_MAX_SIZE (64*1024)
#define ATR_AXI4_SLV_BASE 0x0800
@ -311,6 +315,8 @@ struct tc956xmac_resources {
#ifdef TC956X
unsigned int port_num;
unsigned int port_interface; /* Kernel module parameter variable for interface */
unsigned int eee_enabled; /* Parameter to store kernel module parameter to enable/disable EEE */
unsigned int tx_lpi_timer; /* Parameter to store kernel module parameter for LPI Auto Entry Timer */
#endif
};
@ -525,11 +531,10 @@ struct tc956xmac_priv {
int wolopts;
int wol_irq;
int clk_csr;
struct timer_list eee_ctrl_timer;
int lpi_irq;
int eee_enabled;
unsigned int eee_enabled;
int eee_active;
int tx_lpi_timer;
unsigned int tx_lpi_timer;
unsigned int mode;
unsigned int chain_mode;
int extend_desc;

View File

@ -43,6 +43,9 @@
* VERSION : 01-00-17
* 26 Oct 2021 : 1. Added set_wol and get_wol support using ethtool.
* VERSION : 01-00-19
* 24 Nov 2021 : 1. EEE update for runtime configuration through ethtool.
2. ethtool driver name display corrected
* VERSION : 01-00-24
*/
#include <linux/etherdevice.h>
@ -59,7 +62,7 @@
#define REG_SPACE_SIZE 11512/*Total Reg Len*/
#define MAC100_ETHTOOL_NAME "tc956x_mac100"
#define GMAC_ETHTOOL_NAME "tc956x_gmac"
#define XGMAC_ETHTOOL_NAME "tc956x_xgmac"
#define XGMAC_ETHTOOL_NAME TC956X_RESOURCE_NAME
#define ETHTOOL_DMA_OFFSET 55
@ -697,6 +700,8 @@ static const struct tc956xmac_stats tc956xmac_mmc[] = {
TC956XMAC_MMC_STAT(mmc_tx_excessdef),
TC956XMAC_MMC_STAT(mmc_tx_pause_frame),
TC956XMAC_MMC_STAT(mmc_tx_vlan_frame_g),
TC956XMAC_MMC_STAT(mmc_tx_lpi_tran_cntr),
TC956XMAC_MMC_STAT(mmc_rx_lpi_tran_cntr),
TC956XMAC_MMC_STAT(mmc_rx_framecount_gb),
TC956XMAC_MMC_STAT(mmc_rx_octetcount_gb),
TC956XMAC_MMC_STAT(mmc_rx_octetcount_g),
@ -1286,10 +1291,188 @@ static int tc956xmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol
return ret;
}
#ifdef DEBUG_EEE
int phy_ethtool_get_eee_local(struct phy_device *phydev, struct ethtool_eee *data)
{
int val;
if (!phydev->drv)
return -EIO;
/* Get Supported EEE */
val = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
KPRINT_INFO("%s --- cap: 0x%x\n",__func__,val);
if (val < 0)
return val;
data->supported = mmd_eee_cap_to_ethtool_sup_t(val);
/* Get advertisement EEE */
val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
if (val < 0)
return val;
KPRINT_INFO("%s --- adv: 0x%x\n",__func__,val);
data->advertised = mmd_eee_adv_to_ethtool_adv_t(val);
data->eee_enabled = !!data->advertised;
/* Get LP advertisement EEE */
val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE);
if (val < 0)
return val;
KPRINT_INFO("%s --- lp_adv: 0x%x\n",__func__,val);
data->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(val);
KPRINT_INFO("%s --- data->advertised: 0x%x\n",__func__,data->advertised);
KPRINT_INFO("%s --- data->lp_advertised: 0x%x\n",__func__,data->lp_advertised);
data->eee_active = !!(data->advertised & data->lp_advertised);
KPRINT_INFO("%s --- data->eee_enabled: 0x%x\n",__func__,data->eee_enabled);
KPRINT_INFO("%s --- data->eee_active: 0x%x\n",__func__,data->eee_active);
return 0;
}
int phy_ethtool_set_eee_local(struct phy_device *phydev, struct ethtool_eee *data)
{
int cap, old_adv, adv = 0, ret;
#ifdef TC956X_5_G_2_5_G_EEE_SUPPORT
int cap2p5, old_adv_2p5, adv_2p5 = 0;
#endif
if (!phydev->drv)
return -EIO;
/* Get Supported EEE */
cap = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
KPRINT_INFO("%s --- cap: 0x%x\n",__func__,cap);
if (cap < 0)
return cap;
old_adv = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
KPRINT_INFO("%s --- old_adv:0x%x\n",__func__,old_adv);
if (old_adv < 0)
return old_adv;
if (data->eee_enabled) {
adv = !data->advertised ? cap :
ethtool_adv_to_mmd_eee_adv_t(data->advertised) & cap;
/* Mask prohibited EEE modes */
adv &= ~phydev->eee_broken_modes;
}
KPRINT_INFO("%s --- adv:0x%x\n",__func__,adv);
if (old_adv != adv) {
ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, adv);
if (ret < 0)
return ret;
ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
KPRINT_INFO("%s --- readback adv:0x%x\n",__func__,ret);
if (ret < 0)
return ret;
/* Restart autonegotiation so the new modes get sent to the
* link partner.
*/
if (phydev->autoneg == AUTONEG_ENABLE) {
ret = phy_restart_aneg(phydev);
if (ret < 0)
return ret;
}
}
#ifdef TC956X_5_G_2_5_G_EEE_SUPPORT
cap2p5 = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE2);
KPRINT_INFO("%s --- cap2p5: 0x%x\n",__func__,cap2p5);
if (cap < 0)
return cap;
old_adv_2p5 = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV2);
KPRINT_INFO("%s --- old_adv_2p5:0x%x\n",__func__,old_adv_2p5);
if (old_adv_2p5 < 0)
return old_adv_2p5;
if (data->eee_enabled) {
adv_2p5 = !data->advertised ? cap2p5 :
ethtool_adv_to_mmd_eee_adv_t(data->advertised) & cap2p5;
/* Mask prohibited EEE modes */
adv_2p5 &= ~phydev->eee_broken_modes;
}
KPRINT_INFO("%s --- adv_2p5:0x%x\n",__func__,adv_2p5);
if (old_adv_2p5 != adv_2p5) {
ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV2, adv_2p5);
if (ret < 0)
return ret;
/* Restart autonegotiation so the new modes get sent to the
* link partner.
*/
if (phydev->autoneg == AUTONEG_ENABLE) {
ret = phy_restart_aneg(phydev);
if (ret < 0)
return ret;
}
}
#endif
return 0;
}
#endif
#ifdef TC956X_5_G_2_5_G_EEE_SUPPORT
int phy_ethtool_set_eee_2p5(struct phy_device *phydev, struct ethtool_eee *data)
{
int ret;
int cap2p5, old_adv_2p5, adv_2p5 = 0;
if (!phydev->drv)
return -EIO;
cap2p5 = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE2);
KPRINT_INFO("%s --- cap2p5: 0x%x\n",__func__,cap2p5);
if (cap2p5 < 0)
return cap2p5;
old_adv_2p5 = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV2);
KPRINT_INFO("%s --- old_adv_2p5:0x%x\n",__func__,old_adv_2p5);
if (old_adv_2p5 < 0)
return old_adv_2p5;
if (data->eee_enabled) {
adv_2p5 = !data->advertised ? cap2p5 :
ethtool_adv_to_mmd_eee_adv_t(data->advertised) & cap2p5;
/* Mask prohibited EEE modes */
adv_2p5 &= ~phydev->eee_broken_modes;
}
KPRINT_INFO("%s --- adv_2p5:0x%x\n",__func__,adv_2p5);
if (old_adv_2p5 != adv_2p5) {
ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV2, adv_2p5);
if (ret < 0)
return ret;
/* Restart autonegotiation so the new modes get sent to the
* link partner.
*/
if (phydev->autoneg == AUTONEG_ENABLE) {
ret = phy_restart_aneg(phydev);
if (ret < 0)
return ret;
}
}
return 0;
}
#endif
static int tc956xmac_ethtool_op_get_eee(struct net_device *dev,
struct ethtool_eee *edata)
{
struct tc956xmac_priv *priv = netdev_priv(dev);
int ret;
if (!priv->dma_cap.eee)
return -EOPNOTSUPP;
@ -1298,7 +1481,21 @@ static int tc956xmac_ethtool_op_get_eee(struct net_device *dev,
edata->eee_active = priv->eee_active;
edata->tx_lpi_timer = priv->tx_lpi_timer;
return phylink_ethtool_get_eee(priv->phylink, edata);
DBGPR_FUNC(priv->device, "1--> %s edata->eee_active: %d\n", __func__, edata->eee_active);
#ifndef DEBUG_EEE
ret = phylink_ethtool_get_eee(priv->phylink, edata);
#else
ret = phy_ethtool_get_eee_local(priv->dev->phydev, edata);
#endif
edata->eee_enabled = priv->eee_enabled;
edata->eee_active = priv->eee_active;
edata->tx_lpi_timer = priv->tx_lpi_timer;
edata->tx_lpi_enabled = edata->eee_enabled;
DBGPR_FUNC(priv->device, "2--> %s edata->eee_active: %d\n", __func__, edata->eee_active);
return ret;
}
static int tc956xmac_ethtool_op_set_eee(struct net_device *dev,
@ -1308,26 +1505,43 @@ static int tc956xmac_ethtool_op_set_eee(struct net_device *dev,
int ret;
if (!edata->eee_enabled) {
DBGPR_FUNC(priv->device, "%s Disable EEE\n", __func__);
tc956xmac_disable_eee_mode(priv);
} else {
DBGPR_FUNC(priv->device, "%s Enable EEE\n", __func__);
/* We are asking for enabling the EEE but it is safe
* to verify all by invoking the eee_init function.
* In case of failure it will return an error.
*/
if (priv->tx_lpi_timer != edata->tx_lpi_timer)
if (priv->tx_lpi_timer != edata->tx_lpi_timer) {
if (edata->tx_lpi_timer > TC956X_MAX_LPI_AUTO_ENTRY_TIMER) {
DBGPR_FUNC(priv->device, "%s Error : Maximum LPI Auto Entry Time Supported %d\n",
__func__, TC956X_MAX_LPI_AUTO_ENTRY_TIMER);
return -EINVAL;
}
priv->tx_lpi_timer = edata->tx_lpi_timer;
}
edata->eee_enabled = tc956xmac_eee_init(priv);
if (!edata->eee_enabled)
return -EOPNOTSUPP;
}
#ifndef DEBUG_EEE
ret = phylink_ethtool_set_eee(priv->phylink, edata);
ret |= phy_ethtool_set_eee_2p5(priv->dev->phydev, edata);
#else
ret = phy_ethtool_set_eee_local(priv->dev->phydev, edata);
#endif
if (ret)
return ret;
priv->eee_enabled = edata->eee_enabled;
priv->tx_lpi_timer = edata->tx_lpi_timer;
DBGPR_FUNC(priv->device, "1--> %s priv->eee_enabled: %d\n", __func__, priv->eee_enabled);
return 0;
}

View File

@ -71,6 +71,10 @@
* VERSION : 01-00-21
* 24 Nov 2021 : 1. Private member used instead of global for wol interrupt indication
* VERSION : 01-00-22
* 24 Nov 2021 : 1. EEE update for runtime configuration and LPI interrupt disabled.
2. EEE SW timers removed. Only HW timers used to control EEE LPI entry/exit
3. USXGMII support during link change
* VERSION : 01-00-24
*/
#include <linux/clk.h>
@ -588,21 +592,8 @@ static inline u32 tc956xmac_rx_dirty(struct tc956xmac_priv *priv, u32 queue)
*/
static void tc956xmac_enable_eee_mode(struct tc956xmac_priv *priv)
{
u32 tx_cnt = priv->plat->tx_queues_to_use;
u32 queue;
/* check if all TX queues have the work finished */
for (queue = 0; queue < tx_cnt; queue++) {
struct tc956xmac_tx_queue *tx_q = &priv->tx_queue[queue];
if (tx_q->dirty_tx != tx_q->cur_tx)
return; /* still unfinished work */
}
/* Check and enter in LPI mode */
if (!priv->tx_path_in_lpi_mode)
tc956xmac_set_eee_mode(priv, priv->hw,
priv->plat->en_tx_lpi_clockgating);
tc956xmac_set_eee_mode(priv, priv->hw,
priv->plat->en_tx_lpi_clockgating);
}
/**
@ -614,23 +605,6 @@ static void tc956xmac_enable_eee_mode(struct tc956xmac_priv *priv)
void tc956xmac_disable_eee_mode(struct tc956xmac_priv *priv)
{
tc956xmac_reset_eee_mode(priv, priv->hw);
del_timer_sync(&priv->eee_ctrl_timer);
priv->tx_path_in_lpi_mode = false;
}
/**
* tc956xmac_eee_ctrl_timer - EEE TX SW timer.
* @arg : data hook
* Description:
* if there is no data transfer and if we are not in LPI state,
* then MAC Transmitter can be moved to LPI state.
*/
static void tc956xmac_eee_ctrl_timer(struct timer_list *t)
{
struct tc956xmac_priv *priv = from_timer(priv, t, eee_ctrl_timer);
tc956xmac_enable_eee_mode(priv);
mod_timer(&priv->eee_ctrl_timer, TC956XMAC_LPI_T(eee_timer));
}
/**
@ -644,7 +618,6 @@ static void tc956xmac_eee_ctrl_timer(struct timer_list *t)
bool tc956xmac_eee_init(struct tc956xmac_priv *priv)
{
#ifdef EEE_MAC_CONTROLLED_MODE
int tx_lpi_timer = priv->tx_lpi_timer;
int value;
#endif
@ -662,34 +635,21 @@ bool tc956xmac_eee_init(struct tc956xmac_priv *priv)
mutex_lock(&priv->lock);
/* Check if it needs to be deactivated */
if (!priv->eee_active) {
if (priv->eee_enabled) {
netdev_dbg(priv->dev, "disable EEE\n");
del_timer_sync(&priv->eee_ctrl_timer);
tc956xmac_enable_eee_mode(priv);
#ifdef EEE_MAC_CONTROLLED_MODE
tc956xmac_set_eee_timer(priv, priv->hw, 0, tx_lpi_timer);
tc956xmac_set_eee_timer(priv, priv->hw, TC956XMAC_LIT_LS, TC956XMAC_TWT_LS);
value = TC956XMAC_TIC_1US_CNTR;
writel(value, priv->ioaddr + XGMAC_LPI_1US_Tic_Counter);
value = readl(priv->ioaddr + XGMAC_LPI_Auto_Entry_Timer);
/* Setting LPIET bit [19...3] */
value &= ~(XGMAC_LPIET);
/* LPI Entry timer is in the units of 8 micro second granularity considering last reserved 2:0 bits as zero
* So mask the last 3 bits
*/
value |= (priv->tx_lpi_timer & XGMAC_LPIET);
DBGPR_FUNC(priv->device, "%s Writing LPI timer value of [%d]\n", __func__, value);
writel(value, priv->ioaddr + XGMAC_LPI_Auto_Entry_Timer);
#endif
}
mutex_unlock(&priv->lock);
return false;
}
if (priv->eee_active && !priv->eee_enabled) {
timer_setup(&priv->eee_ctrl_timer, tc956xmac_eee_ctrl_timer, 0);
mod_timer(&priv->eee_ctrl_timer, TC956XMAC_LPI_T(eee_timer));
#ifdef EEE_MAC_CONTROLLED_MODE
tc956xmac_set_eee_timer(priv, priv->hw, TC956XMAC_LIT_LS, TC956XMAC_TWT_LS);
value = TC956XMAC_TIC_1US_CNTR;
writel(value, priv->ioaddr + XGMAC_LPI_1US_Tic_Counter);
value = readl(priv->ioaddr + XGMAC_LPI_Auto_Entry_Timer);
/* Setting LPIET bit [19...3] */
value &= ~(XGMAC_LPIET);
value |= (TC956XMAC_LPIET_600US << 3);
writel(value, priv->ioaddr + XGMAC_LPI_Auto_Entry_Timer);
#endif
}
mutex_unlock(&priv->lock);
netdev_dbg(priv->dev, "Energy-Efficient Ethernet initialized\n");
return true;
@ -1284,6 +1244,18 @@ static void tc956xmac_validate(struct phylink_config *config,
phylink_set(mac_supported, Asym_Pause);
phylink_set_port_modes(mac_supported);
/*USXGMII interface does not support speed of 1000/100/10*/
if (priv->plat->interface == PHY_INTERFACE_MODE_USXGMII) {
phylink_set(mask, 10baseT_Half);
phylink_set(mask, 10baseT_Full);
phylink_set(mask, 100baseT_Half);
phylink_set(mask, 100baseT_Full);
phylink_set(mask, 1000baseT_Half);
phylink_set(mask, 1000baseT_Full);
phylink_set(mask, 1000baseKX_Full);
}
/* Cut down 1G if asked to */
if ((max_speed > 0) && (max_speed < 1000)) {
phylink_set(mask, 1000baseT_Full);
@ -1491,6 +1463,14 @@ void tc956xmac_speed_change_init_mac(struct tc956xmac_priv *priv,
ret |= NEMACCTL_SP_SEL_SGMII_2500M;
else
ret |= NEMACCTL_SP_SEL_SGMII_1000M;
} else {
/*else if ((PORT0_INTERFACE == ENABLE_USXGMII_INTERFACE)*/
if (state->speed == SPEED_10000)
ret |= NEMACCTL_SP_SEL_USXGMII_10G_10G;
else if (state->speed == SPEED_5000)
ret |= NEMACCTL_SP_SEL_USXGMII_5G_10G;
else if (state->speed == SPEED_2500)
ret |= NEMACCTL_SP_SEL_USXGMII_2_5G_10G;
}
ret &= ~(0x00000040); /* Mask Polarity */
if (SgmSigPol == 1)
@ -1613,40 +1593,49 @@ static void tc956xmac_mac_config(struct phylink_config *config, unsigned int mod
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_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 */
switch (state->speed) {
case SPEED_10000:
ctrl |= priv->hw->link.xgmii.speed10000;
emac_ctrl |= NEMACCTL_SP_SEL_USXGMII_10G_10G;
val |= XGMAC_SR_MII_CTRL_SPEED_10G;
break;
case SPEED_5000:
ctrl |= priv->hw->link.xgmii.speed5000;
emac_ctrl |= NEMACCTL_SP_SEL_USXGMII_5G_5G;
val |= XGMAC_SR_MII_CTRL_SPEED_5G;
break;
case SPEED_2500:
ctrl |= priv->hw->link.xgmii.speed2500;
emac_ctrl |= NEMACCTL_SP_SEL_USXGMII_2_5G_2_5G;
val |= XGMAC_SR_MII_CTRL_SPEED_2_5G;
break;
default:
return;
if (state->interface == PHY_INTERFACE_MODE_USXGMII) {
/* 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);
}
tc956x_xpcs_write(priv->xpcsaddr, XGMAC_SR_MII_CTRL, val);
/* USRA_RST set to 1 */
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;
} else {
return;
}
/* 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 */
switch (state->speed) {
case SPEED_10000:
ctrl |= priv->hw->link.xgmii.speed10000;
emac_ctrl |= NEMACCTL_SP_SEL_USXGMII_10G_10G;
val |= XGMAC_SR_MII_CTRL_SPEED_10G;
break;
case SPEED_5000:
ctrl |= priv->hw->link.xgmii.speed5000;
emac_ctrl |= NEMACCTL_SP_SEL_USXGMII_5G_10G;
val |= XGMAC_SR_MII_CTRL_SPEED_5G;
break;
case SPEED_2500:
ctrl |= priv->hw->link.xgmii.speed2500;
emac_ctrl |= NEMACCTL_SP_SEL_USXGMII_2_5G_10G;
val |= XGMAC_SR_MII_CTRL_SPEED_2_5G;
break;
default:
return;
}
tc956x_xpcs_write(priv->xpcsaddr, XGMAC_SR_MII_CTRL, val);
/* USRA_RST set to 1 */
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);
@ -1659,9 +1648,11 @@ static void tc956xmac_mac_config(struct phylink_config *config, unsigned int mod
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 != SPEED_UNKNOWN) && (state->speed != 0)) {
if (state->speed != priv->speed)
tc956xmac_speed_change_init_mac(priv, state);
} else {
return;
}
val = tc956x_xpcs_read(priv->xpcsaddr, XGMAC_SR_MII_CTRL);
val &= ~XGMAC_SR_MII_CTRL_SPEED; /* Mask speed ss13, ss6, ss5 */
@ -1790,7 +1781,8 @@ static void tc956xmac_mac_link_down(struct phylink_config *config,
tc956xmac_mac_set_rx(priv, priv->ioaddr, false);
#ifdef EEE
priv->eee_active = false;
priv->eee_enabled = tc956xmac_eee_init(priv);
DBGPR_FUNC(priv->device, "%s Disable EEE\n", __func__);
tc956xmac_disable_eee_mode(priv);
tc956xmac_set_eee_pls(priv, priv->hw, false);
#endif
#ifdef TC956X_PM_DEBUG
@ -1822,6 +1814,8 @@ int tc956x_phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
if (!phydev->drv)
return -EIO;
KPRINT_INFO("%s EEE phy init for 5G/2.5G\n", __func__);
/* According to 802.3az,the EEE is supported only in full duplex-mode.
*/
if (phydev->duplex == DUPLEX_FULL) {
@ -1834,35 +1828,47 @@ int tc956x_phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
/* Read phy status to properly get the right settings */
status = phy_read_status(phydev);
if (status)
if (status) {
KPRINT_ERR("Error 0: %d\n", status);
return status;
}
/* First check if the EEE ability is supported */
eee_cap = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
if (eee_cap <= 0)
eee_cap = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE2);
if (eee_cap <= 0) {
KPRINT_ERR("Error 2\n");
goto eee_exit_err;
}
cap = mmd_eee_cap_to_ethtool_sup_t(eee_cap);
if (!cap)
if (!cap) {
KPRINT_ERR("Error 3\n");
goto eee_exit_err;
}
/* Check which link settings negotiated and verify it in
* the EEE advertising registers.
*/
eee_lp = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE2);
if (eee_lp <= 0)
if (eee_lp <= 0) {
KPRINT_ERR("Error 4\n");
goto eee_exit_err;
}
eee_adv = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV2);
if (eee_adv <= 0)
if (eee_adv <= 0) {
KPRINT_ERR("Error 5\n");
goto eee_exit_err;
}
tc956x_mmd_eee_adv_to_linkmode_5G_2_5G(adv, eee_adv);
tc956x_mmd_eee_adv_to_linkmode_5G_2_5G(lp, eee_lp);
linkmode_and(common, adv, lp);
if (!tc956x_phy_check_valid(phydev->speed, phydev->duplex, common))
if (!tc956x_phy_check_valid(phydev->speed, phydev->duplex, common)) {
KPRINT_ERR("Error 6\n");
goto eee_exit_err;
}
if (clk_stop_enable)
phy_set_bits_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1,
@ -1875,6 +1881,117 @@ int tc956x_phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
}
#endif
#ifdef DEBUG_EEE
static void mmd_eee_adv_to_linkmode_local(unsigned long *advertising, u16 eee_adv)
{
linkmode_zero(advertising);
if (eee_adv & MDIO_EEE_100TX)
linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
advertising);
if (eee_adv & MDIO_EEE_1000T)
linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
advertising);
if (eee_adv & MDIO_EEE_10GT)
linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
advertising);
if (eee_adv & MDIO_EEE_1000KX)
linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
advertising);
if (eee_adv & MDIO_EEE_10GKX4)
linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
advertising);
if (eee_adv & MDIO_EEE_10GKR)
linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
advertising);
}
int phy_init_eee_local(struct phy_device *phydev, bool clk_stop_enable)
{
if (!phydev->drv)
return -EIO;
KPRINT_INFO("----> %s\n", __func__);
/* According to 802.3az,the EEE is supported only in full duplex-mode.
*/
if (phydev->duplex == DUPLEX_FULL) {
__ETHTOOL_DECLARE_LINK_MODE_MASK(common);
__ETHTOOL_DECLARE_LINK_MODE_MASK(lp);
__ETHTOOL_DECLARE_LINK_MODE_MASK(adv);
int eee_lp, eee_cap, eee_adv;
int status;
u32 cap;
/* Read phy status to properly get the right settings */
status = phy_read_status(phydev);
if (status) {
KPRINT_ERR("Error 0: %d\n", status);
return status;
}
/* First check if the EEE ability is supported */
eee_cap = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
if (eee_cap <= 0) {
KPRINT_ERR("Error 1\n");
goto eee_exit_err;
}
cap = mmd_eee_cap_to_ethtool_sup_t(eee_cap);
if (!cap) {
KPRINT_ERR("Error 2\n");
goto eee_exit_err;
}
/* Check which link settings negotiated and verify it in
* the EEE advertising registers.
*/
eee_lp = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE);
if (eee_lp <= 0) {
KPRINT_ERR("Error 3\n");
goto eee_exit_err;
}
eee_adv = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
if (eee_adv <= 0) {
KPRINT_ERR("Error 4\n");
goto eee_exit_err;
}
KPRINT_INFO("%s eee_adv: 0x%x\n", __func__, eee_adv);
KPRINT_INFO("%s eee_lp: 0x%x\n", __func__, eee_lp);
mmd_eee_adv_to_linkmode_local(adv, eee_adv);
mmd_eee_adv_to_linkmode_local(lp, eee_lp);
KPRINT_INFO("%s adv: 0x%x\n", __func__, adv);
KPRINT_INFO("%s eee_lp: 0x%x\n", __func__, lp);
linkmode_and(common, adv, lp);
KPRINT_INFO("%s common: 0x%x\n", __func__, common);
if (!tc956x_phy_check_valid(phydev->speed, phydev->duplex, common)) {
KPRINT_ERR("Error 5\n");
goto eee_exit_err;
}
if (clk_stop_enable)
/* Configure the PHY to stop receiving xMII
* clock while it is signaling LPI.
*/
phy_set_bits_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1,
MDIO_PCS_CTRL1_CLKSTOP_EN);
return 0; /* EEE supported */
}
eee_exit_err:
return -EPROTONOSUPPORT;
}
#endif
static void tc956xmac_mac_link_up(struct phylink_config *config,
unsigned int mode, phy_interface_t interface,
struct phy_device *phy)
@ -1883,20 +2000,33 @@ static void tc956xmac_mac_link_up(struct phylink_config *config,
tc956xmac_mac_set_rx(priv, priv->ioaddr, true);
#ifdef EEE
if (phy && priv->dma_cap.eee) {
if (phy && priv->dma_cap.eee && priv->eee_enabled) {
DBGPR_FUNC(priv->device, "%s EEE Enable, checking to enable acive\n", __func__);
#ifdef TC956X_5_G_2_5_G_EEE_SUPPORT
if(phy->speed == TC956X_PHY_SPEED_5G || phy->speed == TC956X_PHY_SPEED_2_5G) {
priv->eee_active = tc956x_phy_init_eee(phy, 1) >= 0;
} else {
#ifndef DEBUG_EEE
priv->eee_active = phy_init_eee(phy, 1) >= 0;
#else
priv->eee_active = phy_init_eee_local(phy, 1) >= 0;
#endif
}
#else
#ifndef DEBUG_EEE
priv->eee_active = phy_init_eee(phy, 1) >= 0;
#else
priv->eee_active = phy_init_eee_local(phy, 1) >= 0;
#endif
priv->eee_enabled = tc956xmac_eee_init(priv);
tc956xmac_set_eee_pls(priv, priv->hw, true);
#endif
if (priv->eee_active) {
tc956xmac_eee_init(priv);
tc956xmac_set_eee_pls(priv, priv->hw, true);
}
}
#endif
DBGPR_FUNC(priv->device, "%s priv->eee_enabled: %d priv->eee_active: %d\n", __func__, priv->eee_enabled, priv->eee_active);
#ifdef TC956X_PM_DEBUG
pm_generic_resume(priv->device);
#endif
@ -2014,6 +2144,7 @@ static int tc956xmac_init_phy(struct net_device *dev)
int ret;
struct phy_device *phydev;
int addr = priv->plat->phy_addr;
struct ethtool_eee edata;
node = priv->plat->phylink_node;
@ -2078,7 +2209,13 @@ static int tc956xmac_init_phy(struct net_device *dev)
KPRINT_ERR("Failed to configure PHY interrupt port number is %d", priv->port_num);
}
}
/* Enable or disable EEE Advertisement based on eee_enabled settings which might be set using module param */
edata.eee_enabled = priv->eee_enabled;
edata.advertised = 0;
if (priv->phylink) {
phylink_ethtool_set_eee(priv->phylink, &edata);
}
return ret;
}
@ -3164,12 +3301,6 @@ static int tc956xmac_tx_clean(struct tc956xmac_priv *priv, int budget, u32 queue
"%s: restart transmit\n", __func__);
netif_tx_wake_queue(netdev_get_tx_queue(priv->dev, queue));
}
if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) {
tc956xmac_enable_eee_mode(priv);
mod_timer(&priv->eee_ctrl_timer, TC956XMAC_LPI_T(eee_timer));
}
#ifdef ENABLE_TX_TIMER
/* We still have pending packets, let's call for a new scheduling */
if (tx_q->dirty_tx != tx_q->cur_tx)
@ -3941,8 +4072,6 @@ static int tc956xmac_hw_setup(struct net_device *dev, bool init_ptp)
netdev_warn(priv->dev, "PTP init failed\n");
}
priv->tx_lpi_timer = TC956XMAC_DEFAULT_TWT_LS;
if (priv->use_riwt) {
if (!priv->rx_riwt)
priv->rx_riwt = DEF_DMA_RIWT;
@ -4111,7 +4240,6 @@ static int tc956xmac_open(struct net_device *dev)
goto init_error;
}
#ifdef TC956X
if (priv->port_num == RM_PF0_ID) {
/* mask all eMAC interrupts for MCU */
@ -4312,9 +4440,6 @@ static int tc956xmac_release(struct net_device *dev)
+ TX_TIMER_SRAM_OFFSET(priv->port_num));
#endif
if (priv->eee_enabled)
del_timer_sync(&priv->eee_ctrl_timer);
/* Stop and disconnect the PHY */
if (priv->phylink) {
phylink_stop(priv->phylink);
@ -4746,9 +4871,6 @@ static netdev_tx_t tc956xmac_xmit(struct sk_buff *skb, struct net_device *dev)
tx_q = &priv->tx_queue[queue];
first_tx = tx_q->cur_tx;
if (priv->tx_path_in_lpi_mode)
tc956xmac_disable_eee_mode(priv);
KPRINT_DEBUG1("tso en = %d\n", priv->tso);
KPRINT_DEBUG1("skb tso en = %d\n", skb_is_gso(skb));
/* Manage oversized TCP frames for GMAC4 device */
@ -10172,6 +10294,9 @@ int tc956xmac_dvr_probe(struct device *device,
priv->wol_irq = res->wol_irq;
priv->lpi_irq = res->lpi_irq;
priv->port_interface = res->port_interface;
priv->eee_enabled = res->eee_enabled;
priv->tx_lpi_timer = res->tx_lpi_timer;
#ifdef DMA_OFFLOAD_ENABLE
priv->client_priv = NULL;
memset(priv->cm3_tamap, 0, sizeof(struct tc956xmac_cm3_tamap) * MAX_CM3_TAMAP_ENTRIES);