diff --git a/Readme.md b/Readme.md index af45801c3e54..fbe49ea88b3a 100644 --- a/Readme.md +++ b/Readme.md @@ -1,7 +1,7 @@ # Toshiba Electronic Devices & Storage Corporation TC956X PCIe Ethernet Host Driver -Release Date: 07 Jan 2022 +Release Date: 11 Jan 2022 -Release Version: V_01-00-34 : Limited-tested version +Release Version: V_01-00-35 : Limited-tested version TC956X PCIe EMAC driver is based on "Fedora 30, kernel-5.4.19". @@ -427,3 +427,8 @@ TC956X PCIe EMAC driver is based on "Fedora 30, kernel-5.4.19". ## TC956X_Host_Driver_20220107_V_01-00-34: 1. During emac resume, attach the net device after initializing the queues + +## TC956X_Host_Driver_20220111_V_01-00-35: + +1. Fixed phy mode support +2. Error return when no phy driver found during ISR work queue execution \ No newline at end of file diff --git a/tc956x_pci.c b/tc956x_pci.c index 190e45756683..35d83d773594 100644 --- a/tc956x_pci.c +++ b/tc956x_pci.c @@ -121,6 +121,9 @@ * VERSION : 01-00-33 * 07 Jan 2022 : 1. Version update * VERSION : 01-00-34 + * 11 Jan 2022 : 1. Module parameter added to configure fixed phy mode + * 2. Version update. + * VERSION : 01-00-35 */ #include @@ -147,6 +150,12 @@ #ifdef TC956X_PCIE_GEN3_SETTING static unsigned int pcie_link_speed = 3; #endif + +unsigned int mac0_force_speed_mode = DISABLE; +unsigned int mac1_force_speed_mode = DISABLE; +unsigned int mac0_force_config_speed = 3; /* 1Gbps */ +unsigned int mac1_force_config_speed = 3; /* 1Gbps */ + static unsigned int mac0_interface = ENABLE_XFI_INTERFACE; static unsigned int mac1_interface = ENABLE_SGMII_INTERFACE; @@ -179,7 +188,7 @@ static unsigned int mac1_txq1_size = TX_QUEUE1_SIZE; unsigned int mac0_en_lp_pause_frame_cnt = DISABLE; unsigned int mac1_en_lp_pause_frame_cnt = DISABLE; -static const struct tc956x_version tc956x_drv_version = {0, 1, 0, 0, 3, 4}; +static const struct tc956x_version tc956x_drv_version = {0, 1, 0, 0, 3, 5}; static int tc956xmac_pm_usage_counter; /* Device Usage Counter */ struct mutex tc956x_pm_suspend_lock; /* This mutex is shared between all available EMAC ports. */ @@ -936,6 +945,8 @@ static int tc956xmac_xgmac3_default_data(struct pci_dev *pdev, { unsigned int queue0_rfd = 0, queue1_rfd = 0, queue0_rfa = 0, queue1_rfa = 0, temp_var = 0; unsigned int rxqueue0_size = 0, rxqueue1_size = 0, txqueue0_size = 0, txqueue1_size = 0; + unsigned int forced_speed = 3; /* default 1Gbps */ + /* Set common default data first */ xgmac_default_data(plat); @@ -971,6 +982,39 @@ static int tc956xmac_xgmac3_default_data(struct pci_dev *pdev, #endif plat->phy_interface = plat->interface; + /* Configure forced speed based on the module param. + * This is applicable only for fixed phy mode. + */ + if (plat->port_num == RM_PF0_ID) + forced_speed = mac0_force_config_speed; + + if (plat->port_num == RM_PF1_ID) + forced_speed = mac1_force_config_speed; + + switch (forced_speed) { + case 0: + plat->forced_speed = SPEED_10000; + break; + case 1: + plat->forced_speed = SPEED_5000; + break; + case 2: + plat->forced_speed = SPEED_2500; + break; + case 3: + plat->forced_speed = SPEED_1000; + break; + case 4: + plat->forced_speed = SPEED_100; + break; + case 5: + plat->forced_speed = SPEED_10; + break; + default: + plat->forced_speed = SPEED_1000; + break; + } + #ifdef TC956X plat->clk_ptp_rate = TC956X_TARGET_PTP_CLK; #else @@ -2294,6 +2338,8 @@ static int tc956xmac_pci_probe(struct pci_dev *pdev, #ifdef TC956X_PCIE_GEN3_SETTING NMSGPR_INFO(&pdev->dev, "pcie_link_speed = %d \n", pcie_link_speed); #endif + NMSGPR_INFO(&pdev->dev, "mac0_force_speed_mode = %d \n", mac0_force_speed_mode); + NMSGPR_INFO(&pdev->dev, "mac0_force_config_speed = %d \n", mac0_force_config_speed); NMSGPR_INFO(&pdev->dev, "mac0_interface = %d \n", mac0_interface); NMSGPR_INFO(&pdev->dev, "mac0_eee_enable = %d \n", mac0_eee_enable); NMSGPR_INFO(&pdev->dev, "mac0_lpi_timer = %d \n", mac0_lpi_timer); @@ -2308,6 +2354,8 @@ static int tc956xmac_pci_probe(struct pci_dev *pdev, NMSGPR_INFO(&pdev->dev, "mac0_txq1_size = %d \n", mac0_txq1_size); NMSGPR_INFO(&pdev->dev, "mac0_en_lp_pause_frame_cnt = %d \n", mac0_en_lp_pause_frame_cnt); } else if (plat->port_num == RM_PF1_ID) { + NMSGPR_INFO(&pdev->dev, "mac1_force_speed_mode = %d \n", mac1_force_speed_mode); + NMSGPR_INFO(&pdev->dev, "mac1_force_config_speed = %d \n", mac1_force_config_speed); NMSGPR_INFO(&pdev->dev, "mac1_interface = %d \n", mac1_interface); NMSGPR_INFO(&pdev->dev, "mac1_eee_enable = %d \n", mac1_eee_enable); NMSGPR_INFO(&pdev->dev, "mac1_filter_phy_pause = %d \n", mac1_filter_phy_pause); @@ -2354,6 +2402,19 @@ static int tc956xmac_pci_probe(struct pci_dev *pdev, plat->port_interface = res.port_interface; if (res.port_num == RM_PF0_ID) { + + if ((mac0_force_speed_mode != DISABLE) && (mac0_force_speed_mode != ENABLE)) { + mac0_force_speed_mode = DISABLE; + NMSGPR_INFO(&(pdev->dev), "%s: ERROR Invalid mac0_force_speed_mode parameter passed. Restoring default to %d. Supported Values are 0 and 1.\n", + __func__, mac0_force_speed_mode); + } + if (mac0_force_speed_mode == ENABLE) { + if (mac0_force_config_speed > 5) { /*Configuring default value on error*/ + mac0_force_config_speed = 3; + NMSGPR_INFO(&(pdev->dev), "%s: ERROR Invalid mac0_force_config_speed parameter passed. Restoring default to %d. Supported Values are 0 to 5.\n", + __func__, mac0_force_config_speed); + } + } if ((mac0_eee_enable != DISABLE) && (mac0_eee_enable != ENABLE)) { mac0_eee_enable = DISABLE; @@ -2373,6 +2434,20 @@ static int tc956xmac_pci_probe(struct pci_dev *pdev, } if (res.port_num == RM_PF1_ID) { + + if ((mac1_force_speed_mode != DISABLE) && (mac1_force_speed_mode != ENABLE)) { + mac1_force_speed_mode = DISABLE; + NMSGPR_INFO(&(pdev->dev), "%s: ERROR Invalid mac1_force_speed_mode parameter passed. Restoring default to %d. Supported Values are 0 and 1.\n", + __func__, mac1_force_speed_mode); + } + if (mac1_force_speed_mode == ENABLE) { + if (mac1_force_config_speed > 5) { /*Configuring default value on error*/ + mac1_force_config_speed = 3; + NMSGPR_INFO(&(pdev->dev), "%s: ERROR Invalid mac1_force_config_speed parameter passed. Restoring default to %d. Supported Values are 0 to 5.\n", + __func__, mac1_force_config_speed); + } + } + if ((mac1_eee_enable != DISABLE) && (mac1_eee_enable != ENABLE)) { mac1_eee_enable = DISABLE; @@ -3482,6 +3557,26 @@ MODULE_PARM_DESC(mac1_en_lp_pause_frame_cnt, "Enable counter to count Link Partner pause frames in PORT1 - default is 0,\ [0: DISABLE, 1: ENABLE]"); +module_param(mac0_force_speed_mode, uint, 0444); +MODULE_PARM_DESC(mac0_force_speed_mode, + "Enable MAC0 force speed mode - default is 0,\ + [0: DISABLE, 1: ENABLE]"); + +module_param(mac0_force_config_speed, uint, 0444); +MODULE_PARM_DESC(mac0_force_config_speed, + "Configure MAC0 force speed - default is 3,\ + [0: 10G, 1: 5G, 2: 2.5G, 3: 1G, 4: 100M, 5: 10M]"); + +module_param(mac1_force_speed_mode, uint, 0444); +MODULE_PARM_DESC(mac1_force_speed_mode, + "Enable MAC1 force speed mode - default is 0,\ + [0: DISABLE, 1: ENABLE]"); + +module_param(mac1_force_config_speed, uint, 0444); +MODULE_PARM_DESC(mac1_force_config_speed, + "Configure MAC1 force speed - default is 3,\ + [0: 10G, 1: 5G, 2: 2.5G, 3: 1G, 4: 100M, 5: 10M]"); + MODULE_DESCRIPTION("TC956X PCI Express Ethernet Network Driver"); MODULE_AUTHOR("Toshiba Electronic Devices & Storage Corporation"); MODULE_LICENSE("GPL v2"); diff --git a/tc956xmac.h b/tc956xmac.h index 6ab64039b9f1..951ec155d15b 100644 --- a/tc956xmac.h +++ b/tc956xmac.h @@ -113,6 +113,8 @@ * VERSION : 01-00-33 * 07 Jan 2022 : 1. Version update * VERSION : 01-00-34 + * 11 Jan 2022 : 1. Version update + * VERSION : 01-00-35 */ #ifndef __TC956XMAC_H__ @@ -165,7 +167,7 @@ #ifdef TC956X #define TC956X_RESOURCE_NAME "tc956x_pci-eth" -#define DRV_MODULE_VERSION "V_01-00-34" +#define DRV_MODULE_VERSION "V_01-00-35" #define TC956X_FW_MAX_SIZE (64*1024) #define ATR_AXI4_SLV_BASE 0x0800 diff --git a/tc956xmac_inc.h b/tc956xmac_inc.h index f8e0b4473ddf..1783bc630d6d 100644 --- a/tc956xmac_inc.h +++ b/tc956xmac_inc.h @@ -44,6 +44,8 @@ * VERSION : 01-00-10 * 08 Dec 2021 : 1. Added Module parameters for Flow control thresholds per Queue. * VERSION : 01-00-30 + * 11 Jan 2022 : 1. Forced speed mode parameter added for fixed phy mode. + * VERSION : 01-00-35 */ #ifndef __TC956XMAC_PLATFORM_DATA @@ -310,5 +312,6 @@ struct plat_tc956xmacenet_data { u32 port_num; u32 port_interface; /* Kernel module parameter variable for interface */ bool phy_interrupt_mode; /* For Handling of PHY Operating mode */ + int forced_speed; /* applicable only in case of fixed phy mode */ }; #endif diff --git a/tc956xmac_main.c b/tc956xmac_main.c index a87e055dffac..ada2cfdf2c48 100644 --- a/tc956xmac_main.c +++ b/tc956xmac_main.c @@ -94,6 +94,9 @@ * VERSION : 01-00-33 * 07 Jan 2022 : 1. During emac resume, attach the net device after initializing the queues * VERSION : 01-00-34 + * 11 Jan 2022 : 1. Fixed phymode support added + * 2. Error return when no phy driver found during ISR work queue execution + * VERSION : 01-00-35 */ #include @@ -256,6 +259,9 @@ static u8 phy_sa_addr[2][6] = { extern unsigned int mac0_en_lp_pause_frame_cnt; extern unsigned int mac1_en_lp_pause_frame_cnt; +extern unsigned int mac0_force_speed_mode; +extern unsigned int mac1_force_speed_mode; + /** * tc956x_GPIO_OutputConfigPin - to configure GPIO as output and write the value * @priv: driver private structure @@ -2142,6 +2148,12 @@ static void tc956xmac_defer_phy_isr_work(struct work_struct *work) netdev_err(priv->dev, "no phy at addr %d\n", addr); return; } + + if(!phydev->drv) { + netdev_err(priv->dev, "no phy driver\n"); + return; + } + /* Call ack interrupt to clear the WOL interrupt status fields */ if (phydev->drv->ack_interrupt) phydev->drv->ack_interrupt(phydev); @@ -2243,9 +2255,27 @@ static int tc956xmac_init_phy(struct net_device *dev) if (priv->phylink) { phylink_ethtool_set_eee(priv->phylink, &edata); } + /* In forced speed mode, donot return error here */ + if (((priv->port_num == RM_PF1_ID) && (mac1_force_speed_mode == ENABLE)) || + ((priv->port_num == RM_PF0_ID) && (mac0_force_speed_mode == ENABLE))) + ret = 0; + return ret; } +static void tc956xmac_phylink_fixed_state(struct net_device *dev, struct phylink_link_state *state) +{ + struct tc956xmac_priv *priv = netdev_priv(dev); + + state->link = 1; + state->duplex = DUPLEX_FULL; + state->speed = priv->plat->forced_speed; + + DBGPR_FUNC(priv->device, "%s state->speed: %d\n", __func__, state->speed); + + return; +} + static int tc956xmac_phy_setup(struct tc956xmac_priv *priv) { struct fwnode_handle *fwnode = of_fwnode_handle(priv->plat->phylink_node); @@ -2253,12 +2283,18 @@ static int tc956xmac_phy_setup(struct tc956xmac_priv *priv) struct phylink *phylink; priv->phylink_config.dev = &priv->dev->dev; - priv->phylink_config.type = PHYLINK_NETDEV; + priv->phylink_config.type = PHYLINK_NETDEV; + + phylink = phylink_create(&priv->phylink_config, fwnode, + mode, &tc956xmac_phylink_mac_ops); + if (IS_ERR(phylink)) + return PTR_ERR(phylink); + + /* Fixed phy mode should be set using device tree, driver just registers callback here */ + if (((priv->port_num == RM_PF1_ID) && (mac1_force_speed_mode == ENABLE)) || + ((priv->port_num == RM_PF0_ID) && (mac0_force_speed_mode == ENABLE))) + phylink_fixed_state_cb(phylink, tc956xmac_phylink_fixed_state); - phylink = phylink_create(&priv->phylink_config, fwnode, - mode, &tc956xmac_phylink_mac_ops); - if (IS_ERR(phylink)) - return PTR_ERR(phylink); priv->phylink = phylink; return 0; }