diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe.h b/drivers/net/ethernet/wangxun/txgbe/txgbe.h index 68ae39ff2f2c7e79177134627ba00bd9818d4e3a..29fce194a8abae601f1c6c6ba956880710c9aaf4 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe.h +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe.h @@ -47,7 +47,8 @@ DECLARE_STATIC_KEY_FALSE(txgbe_xdp_locking_key); #define TXGBE_DEFAULT_TXD 1024 #define TXGBE_DEFAULT_TX_WORK 256 #define TXGBE_MAX_TXD 8192 -#define TXGBE_MIN_TXD 128 +#define TXGBE_MIN_TXD 256 +#define TXGBE_MIN_TXD_AML 512 #define TXGBE_MAX_TX_WORK 65535 #if (PAGE_SIZE < 8192) @@ -199,6 +200,7 @@ struct txgbe_tx_buffer { union txgbe_tx_desc *next_to_watch; u32 next_eop; unsigned long time_stamp; + u64 done_time; union { struct sk_buff *skb; /* XDP uses address ptr on irq_clean */ @@ -678,6 +680,7 @@ struct txgbe_therm_proc_data { **/ #define TXGBE_FLAG2_RSC_CAPABLE BIT(0) #define TXGBE_FLAG2_RSC_ENABLED BIT(1) +#define TXGBE_FLAG2_DMA_RESET_REQUESTED BIT(2) #define TXGBE_FLAG2_TEMP_SENSOR_CAPABLE BIT(3) #define TXGBE_FLAG2_TEMP_SENSOR_EVENT BIT(4) #define TXGBE_FLAG2_SEARCH_FOR_SFP BIT(5) @@ -686,8 +689,9 @@ struct txgbe_therm_proc_data { #define TXGBE_FLAG2_FDIR_REQUIRES_REINIT BIT(8) #define TXGBE_FLAG2_RSS_FIELD_IPV4_UDP BIT(9) #define TXGBE_FLAG2_RSS_FIELD_IPV6_UDP BIT(10) -#define TXGBE_FLAG2_RSS_ENABLED BIT(12) #define TXGBE_FLAG2_PTP_PPS_ENABLED BIT(11) +#define TXGBE_FLAG2_RSS_ENABLED BIT(12) +#define TXGBE_FLAG2_RING_DUMP BIT(13) #define TXGBE_FLAG2_EEE_CAPABLE BIT(14) #define TXGBE_FLAG2_EEE_ENABLED BIT(15) #define TXGBE_FLAG2_VXLAN_REREG_NEEDED BIT(16) @@ -705,11 +709,6 @@ struct txgbe_therm_proc_data { #define TXGBE_FLAG2_ECC_ERR_RESET BIT(29) #define TXGBE_FLAG2_RX_LEGACY BIT(30) #define TXGBE_FLAG2_PCIE_NEED_RECOVER BIT(31) -#define TXGBE_FLAG2_PCIE_NEED_Q_RESET BIT(30) -#define TXGBE_FLAG2_SERVICE_RUNNING BIT(13) - -/* amlite: dma reset */ -#define TXGBE_FLAG2_DMA_RESET_REQUESTED BIT(2) #define TXGBE_FLAG3_PHY_EVENT BIT(0) #define TXGBE_FLAG3_TEMP_SENSOR_INPROGRESS BIT(1) @@ -856,6 +855,7 @@ struct txgbe_adapter { struct mutex e56_lock; struct timer_list service_timer; + struct timer_list irq_timer; struct work_struct service_task; struct work_struct sfp_sta_task; struct work_struct temp_task; @@ -963,6 +963,7 @@ struct txgbe_adapter { u16 num_xsk_pools; bool cmplt_to_dis; + bool io_err; u8 i2c_eeprom[512]; u32 eeprom_len; u32 eeprom_type; diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c index 8376fc61763d84ce9f561f0347714b67b6c19ded..7e5b4ba1f4691d0e3ad6035f2860f4be6615ce72 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c @@ -122,11 +122,15 @@ static s32 txgbe_setup_mac_link_aml(struct txgbe_hw *hw, goto out; if (ret_status == TXGBE_ERR_TIMEOUT) { + adapter->link_valid = false; adapter->flags |= TXGBE_FLAG_NEED_LINK_CONFIG; goto out; + } else { + adapter->link_valid = true; } - if (speed == TXGBE_LINK_SPEED_25GB_FULL) { + if (speed == TXGBE_LINK_SPEED_25GB_FULL && + adapter->fec_link_mode == TXGBE_PHY_FEC_AUTO) { txgbe_e56_fec_mode_polling(hw, &link_up); } else { for (i = 0; i < 4; i++) { @@ -337,8 +341,20 @@ static s32 txgbe_setup_mac_link_multispeed_fiber_aml(struct txgbe_hw *hw, txgbe_e56_check_phy_link(hw, &link_speed, &link_up); if (link_up) { - adapter->flags &= ~TXGBE_FLAG_NEED_LINK_CONFIG; - goto out; + int i = 0; + + for (; i < 10; i++) { + int rdata = rd32(hw, 0x14404); + + if (rdata & 0x1) { + adapter->flags &= ~TXGBE_FLAG_NEED_LINK_CONFIG; + mutex_lock(&adapter->e56_lock); + txgbe_wr32_ephy(hw, E56PHY_INTR_1_ADDR, E56PHY_INTR_1_IDLE_EXIT1); + mutex_unlock(&adapter->e56_lock); + goto out; + } + msleep(100); + } } } diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_dcb.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_dcb.c index aff3ff47505acc4c8992c977e049c075d33d2714..16000cbeb17cef638b932e641dd974c49aeb1a48 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_dcb.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_dcb.c @@ -355,6 +355,9 @@ s32 txgbe_dcb_config_pfc(struct txgbe_hw *hw, u8 pfc_en, u8 *map) for (i = 0; i < (TXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++) wr32(hw, TXGBE_RDB_RFCV(i), reg); + if (hw->mac.type == txgbe_mac_aml || hw->mac.type == txgbe_mac_aml40) + wr32m(hw, TXGBE_PFC_DIS_MASK, TXGBE_PFC_DIS_MASK_VAL, ~pfc_en); + /* Configure flow control refresh threshold value */ wr32(hw, TXGBE_RDB_RFCRT, hw->fc.pause_time / 2); diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_e56.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_e56.c index e9f65652273aad3c2eb20561f1f42f28bac7141f..070ebd7c47634eb06011dbc293f00614918aaa65 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_e56.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_e56.c @@ -139,6 +139,34 @@ int txgbe_e56_get_temp(struct txgbe_hw *hw, int *temp) return 0; } +static void txgbe_e56_ovrd_symdata(struct txgbe_hw *hw) +{ + u32 addr; + u32 rdata = 0; + int i; + + for (i = 0; i < 4; i++) { + addr = E56PHY_TXS_PIN_OVRDEN_0_ADDR + (E56PHY_TXS_OFFSET * i); + rdata = rd32_ephy(hw, addr); + txgbe_field_set(&rdata, E56PHY_TXS_PIN_OVRDEN_0_OVRD_EN_TX0_SYMDATA_I, 0x1); + txgbe_wr32_ephy(hw, addr, rdata); + } +} + +static void txgbe_e56_clear_symdata(struct txgbe_hw *hw) +{ + u32 addr; + u32 rdata = 0; + int i; + + for (i = 0; i < 4; i++) { + addr = E56PHY_TXS_PIN_OVRDEN_0_ADDR + (E56PHY_TXS_OFFSET * i); + rdata = rd32_ephy(hw, addr); + txgbe_field_set(&rdata, E56PHY_TXS_PIN_OVRDEN_0_OVRD_EN_TX0_SYMDATA_I, 0x0); + txgbe_wr32_ephy(hw, addr, rdata); + } +} + u32 txgbe_e56_cfg_40g(struct txgbe_hw *hw) { u32 addr; @@ -2853,11 +2881,8 @@ static int txgbe_e56_rxs_calib_adapt_seq(struct txgbe_hw *hw, u32 speed) u32 rdata = 0x0; u32 bypass_ctle = true; - if (hw->phy.sfp_type == txgbe_sfp_type_da_cu_core0 || - hw->phy.sfp_type == txgbe_sfp_type_da_cu_core1) + if (hw->dac_sfp) bypass_ctle = false; - else - bypass_ctle = true; if (hw->mac.type == txgbe_mac_aml) { msleep(350); @@ -2945,15 +2970,8 @@ static int txgbe_e56_rxs_calib_adapt_seq(struct txgbe_hw *hw, u32 speed) rdata = rd32_ephy(hw, addr); usleep_range(500, 1000); EPHY_RREG(E56G__PMD_CTRL_FSM_RX_STAT_0); - if (timer++ > PHYINIT_TIMEOUT) { - //Do SEQ::RX_DISABLE - rdata = 0; - addr = E56PHY_PMD_CFG_0_ADDR; - rdata = rd32_ephy(hw, addr); - txgbe_field_set(&rdata, E56PHY_PMD_CFG_0_RX_EN_CFG, 0x0); - txgbe_wr32_ephy(hw, addr, rdata); + if (timer++ > PHYINIT_TIMEOUT) return TXGBE_ERR_TIMEOUT; - } } //RXS ADC adaptation sequence @@ -3632,8 +3650,11 @@ int txgbe_set_link_to_amlite(struct txgbe_hw *hw, u32 speed) ~TXGBE_MAC_TX_CFG_TE); wr32m(hw, TXGBE_MAC_RX_CFG, TXGBE_MAC_RX_CFG_RE, ~TXGBE_MAC_RX_CFG_RE); + hw->mac.ops.disable_sec_tx_path(hw); } + hw->mac.ops.disable_tx_laser(hw); + if (hw->bus.lan_id == 0) reset = TXGBE_MIS_RST_LAN0_EPHY_RST; else @@ -3652,10 +3673,12 @@ int txgbe_set_link_to_amlite(struct txgbe_hw *hw, u32 speed) value = txgbe_rd32_epcs(hw, VR_PCS_DIG_CTRL1); if ((value & 0x8000)) { status = TXGBE_ERR_PHY_INIT_NOT_DONE; - ; + hw->mac.ops.enable_tx_laser(hw); goto out; } + txgbe_e56_ovrd_symdata(hw); + value = txgbe_rd32_epcs(hw, SR_AN_CTRL); txgbe_field_set(&value, 12, 12, 0); txgbe_wr32_epcs(hw, SR_AN_CTRL, value); @@ -3909,6 +3932,14 @@ int txgbe_set_link_to_amlite(struct txgbe_hw *hw, u32 speed) txgbe_wr32_ephy(hw, PMD_CFG0, value); } + txgbe_e56_clear_symdata(hw); + + if (adapter->fec_link_mode != TXGBE_PHY_FEC_AUTO && + speed == TXGBE_LINK_SPEED_25GB_FULL) { + adapter->cur_fec_link = adapter->fec_link_mode; + txgbe_e56_set_fec_mode(hw, adapter->cur_fec_link); + } + hw->mac.ops.enable_tx_laser(hw); status = txgbe_e56_config_rx(hw, speed); @@ -3925,11 +3956,6 @@ int txgbe_set_link_to_amlite(struct txgbe_hw *hw, u32 speed) txgbe_wr32_ephy(hw, E56PHY_INTR_1_ENABLE_ADDR, E56PHY_INTR_1_IDLE_EXIT1); - if (adapter->fec_link_mode != TXGBE_PHY_FEC_AUTO) { - adapter->cur_fec_link = adapter->fec_link_mode; - txgbe_e56_set_fec_mode(hw, adapter->cur_fec_link); - } - if (status) goto out; @@ -4024,17 +4050,18 @@ int txgbe_e56_fec_mode_polling(struct txgbe_hw *hw, bool *link_up) u32 speed; do { - if (!(adapter->fec_link_mode & BIT(j))) { + if (!(adapter->fec_link_mode & BIT(j % 3))) { j += 1; continue; } - adapter->cur_fec_link = adapter->fec_link_mode & BIT(j); + adapter->cur_fec_link = adapter->fec_link_mode & BIT(j % 3); mutex_lock(&adapter->e56_lock); txgbe_e56_set_fec_mode(hw, adapter->cur_fec_link); mutex_unlock(&adapter->e56_lock); + for (i = 0; i < 4; i++) { msleep(250); txgbe_e56_check_phy_link(hw, &speed, link_up); @@ -4043,7 +4070,7 @@ int txgbe_e56_fec_mode_polling(struct txgbe_hw *hw, bool *link_up) } j += 1; - } while (j < 3); + } while (j < 4); return 0; } diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_e56.h b/drivers/net/ethernet/wangxun/txgbe/txgbe_e56.h index 381565570eb04907662372c1654f75ab6d1e15d3..f1b03b66e2329060b28f4251297006753238b756 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_e56.h +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_e56.h @@ -179,6 +179,7 @@ union txgbe_e56_cms_ana_ovrdval0 { #define E56PHY_TXS_WKUP_CNTDCC_WKUP_CNT_X32 FORMAT_NOPARENTHERSES(15, 8) #define E56PHY_TXS_PIN_OVRDEN_0_ADDR (E56PHY_TXS_BASE_ADDR + 0x0C) +#define E56PHY_TXS_PIN_OVRDEN_0_OVRD_EN_TX0_SYMDATA_I FORMAT_NOPARENTHERSES(19, 19) #define E56PHY_TXS_PIN_OVRDEN_0_OVRD_EN_TX0_EFUSE_BITS_I \ FORMAT_NOPARENTHERSES(28, 28) diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c index 9a87fa1b6af8cd68d1341faa7d15d001355a21a7..d257353bb4c62a848cd5497ea7a966a3c5f6332a 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c @@ -905,20 +905,22 @@ static int txgbe_get_fec_param(struct net_device *netdev, } hw->mac.ops.check_link(hw, &speed, &link_up, false); fecparam->fec = 0; - if (speed == TXGBE_LINK_SPEED_10GB_FULL) { + if (supported_link == TXGBE_LINK_SPEED_10GB_FULL) { fecparam->fec |= ETHTOOL_FEC_OFF; + } else { + if (adapter->fec_link_mode == TXGBE_PHY_FEC_AUTO) + fecparam->fec |= ETHTOOL_FEC_AUTO; + else if (adapter->fec_link_mode & TXGBE_PHY_FEC_BASER) + fecparam->fec |= ETHTOOL_FEC_BASER; + else if (adapter->fec_link_mode & TXGBE_PHY_FEC_RS) + fecparam->fec |= ETHTOOL_FEC_RS; + else + fecparam->fec |= ETHTOOL_FEC_OFF; + } + if (speed == TXGBE_LINK_SPEED_10GB_FULL) { fecparam->active_fec = ETHTOOL_FEC_OFF; goto done; } - if (adapter->fec_link_mode == TXGBE_PHY_FEC_AUTO) - fecparam->fec |= ETHTOOL_FEC_AUTO; - else if (adapter->fec_link_mode & TXGBE_PHY_FEC_BASER) - fecparam->fec |= ETHTOOL_FEC_BASER; - else if (adapter->fec_link_mode & TXGBE_PHY_FEC_RS) - fecparam->fec |= ETHTOOL_FEC_RS; - else - fecparam->fec |= ETHTOOL_FEC_OFF; - if (!link_up) { fecparam->active_fec = ETHTOOL_FEC_OFF; goto done; @@ -979,9 +981,61 @@ static int txgbe_set_fec_param(struct net_device *netdev, goto done; } if (cur_fec_mode != adapter->fec_link_mode) { - /* reset link */ - adapter->flags |= TXGBE_FLAG_NEED_LINK_CONFIG; - txgbe_service_event_schedule(adapter); + int status, i; + u32 link_speed = TXGBE_LINK_SPEED_UNKNOWN; + bool link_up = false; + + if (hw->phy.multispeed_fiber && + (hw->phy.autoneg_advertised == + (TXGBE_LINK_SPEED_10GB_FULL | + TXGBE_LINK_SPEED_25GB_FULL)) && + adapter->fec_link_mode != TXGBE_PHY_FEC_AUTO) { + while (test_and_set_bit(__TXGBE_IN_SFP_INIT, &adapter->state)) + usleep_range(1000, 2000); + status = hw->mac.ops.setup_mac_link(hw, + TXGBE_LINK_SPEED_25GB_FULL, 0); + if (status != 0) + return status; + for (i = 0; i < 30; i++) { + txgbe_e56_check_phy_link(hw, &link_speed, &link_up); + if (link_up) + goto out; + msleep(200); + } + msec_delay(100); + status = hw->mac.ops.setup_mac_link(hw, + TXGBE_LINK_SPEED_10GB_FULL, 0); + if (status != 0) + return status; + for (i = 0; i < 35; i++) { + u32 link_speed; + bool link_up = 0; + + txgbe_e56_check_phy_link(hw, &link_speed, &link_up); + if (link_up) { + if (rd32(hw, 0x14404) & 0x1) { + adapter->flags &= ~TXGBE_FLAG_NEED_LINK_CONFIG; + mutex_lock(&adapter->e56_lock); + txgbe_wr32_ephy(hw, E56PHY_INTR_1_ADDR, E56PHY_INTR_1_IDLE_EXIT1); + mutex_unlock(&adapter->e56_lock); + goto out; + } + } + msleep(200); + } + adapter->flags |= TXGBE_FLAG_NEED_LINK_CONFIG; + txgbe_service_event_schedule(adapter); +out: + clear_bit(__TXGBE_IN_SFP_INIT, &adapter->state); + } else if (hw->phy.multispeed_fiber) { + while (test_and_set_bit(__TXGBE_IN_SFP_INIT, &adapter->state)) + usleep_range(1000, 2000); + hw->mac.ops.setup_link(hw, hw->phy.autoneg_advertised, true); + clear_bit(__TXGBE_IN_SFP_INIT, &adapter->state); + } else { + adapter->flags |= TXGBE_FLAG_NEED_LINK_CONFIG; + txgbe_service_event_schedule(adapter); + } } done: return err; @@ -1576,15 +1630,22 @@ static int txgbe_set_ringparam(struct net_device *netdev, { struct txgbe_ring *tx_ring = NULL, *rx_ring = NULL; struct txgbe_adapter *adapter = netdev_priv(netdev); + struct txgbe_hw *hw = &adapter->hw; u32 new_rx_count, new_tx_count; int i, j, err = 0; if (ring->rx_mini_pending || ring->rx_jumbo_pending) return -EINVAL; - new_tx_count = clamp_t(u32, ring->tx_pending, - TXGBE_MIN_TXD, TXGBE_MAX_TXD); - new_tx_count = ALIGN(new_tx_count, TXGBE_REQ_TX_DESCRIPTOR_MULTIPLE); + if (hw->mac.type == txgbe_mac_aml || hw->mac.type == txgbe_mac_aml40) { + new_tx_count = clamp_t(u32, ring->tx_pending, + TXGBE_MIN_TXD_AML, TXGBE_MAX_TXD); + new_tx_count = ALIGN(new_tx_count, TXGBE_REQ_TX_DESCRIPTOR_MULTIPLE); + } else { + new_tx_count = clamp_t(u32, ring->tx_pending, + TXGBE_MIN_TXD, TXGBE_MAX_TXD); + new_tx_count = ALIGN(new_tx_count, TXGBE_REQ_TX_DESCRIPTOR_MULTIPLE); + } new_rx_count = clamp_t(u32, ring->rx_pending, TXGBE_MIN_RXD, TXGBE_MAX_RXD); @@ -2948,14 +3009,15 @@ static void txgbe_get_wol(struct net_device *netdev, struct txgbe_adapter *adapter = netdev_priv(netdev); struct txgbe_hw *hw = &adapter->hw; - wol->supported = WAKE_UCAST | WAKE_MCAST | - WAKE_BCAST | WAKE_MAGIC; + wol->supported = 0; wol->wolopts = 0; - if (!device_can_wakeup(pci_dev_to_dev(adapter->pdev))) + if ((hw->subsystem_device_id & TXGBE_WOL_MASK) != TXGBE_WOL_SUP) return; - if ((hw->subsystem_device_id & TXGBE_WOL_MASK) != TXGBE_WOL_SUP) + wol->supported = WAKE_MAGIC; + + if (!device_can_wakeup(pci_dev_to_dev(adapter->pdev))) return; if (adapter->wol & TXGBE_PSR_WKUP_CTL_EX) @@ -2981,12 +3043,6 @@ static int txgbe_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) adapter->wol = 0; - if (wol->wolopts & WAKE_UCAST) - adapter->wol |= TXGBE_PSR_WKUP_CTL_EX; - if (wol->wolopts & WAKE_MCAST) - adapter->wol |= TXGBE_PSR_WKUP_CTL_MC; - if (wol->wolopts & WAKE_BCAST) - adapter->wol |= TXGBE_PSR_WKUP_CTL_BC; if (wol->wolopts & WAKE_MAGIC) adapter->wol |= TXGBE_PSR_WKUP_CTL_MAG; diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_hw.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_hw.c index 5fc14df3e80c8069223dd6d0f8b5517f91e1cbc9..5c627f99dcf09deb49c799513b519b5ea77dfa0d 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_hw.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_hw.c @@ -186,10 +186,8 @@ s32 txgbe_clear_hw_cntrs(struct txgbe_hw *hw) rd32(hw, TXGBE_MAC_LXOFFRXC); for (i = 0; i < 8; i++) { - rd32(hw, TXGBE_RDB_PXONTXC(i)); - rd32(hw, TXGBE_RDB_PXOFFTXC(i)); rd32(hw, TXGBE_MAC_PXONRXC(i)); - wr32m(hw, TXGBE_MMC_CONTROL, TXGBE_MMC_CONTROL_UP, i << 16); + wr32m(hw, TXGBE_MMC_CONTROL, TXGBE_MMC_CONTROL_UP, i<<16); rd32(hw, TXGBE_MAC_PXOFFRXC); } for (i = 0; i < 8; i++) @@ -2044,8 +2042,7 @@ s32 txgbe_set_vfta(struct txgbe_hw *hw, u32 vlan, u32 vind, regindex = (vlan >> 5) & 0x7F; bitindex = vlan & 0x1F; targetbit = (1 << bitindex); - /* errata 5 */ - vfta = hw->mac.vft_shadow[regindex]; + vfta = rd32(hw, TXGBE_PSR_VLAN_TBL(regindex)); if (vlan_on) { if (!(vfta & targetbit)) { vfta |= targetbit; @@ -2068,8 +2065,6 @@ s32 txgbe_set_vfta(struct txgbe_hw *hw, u32 vlan, u32 vind, if (vfta_changed) wr32(hw, TXGBE_PSR_VLAN_TBL(regindex), vfta); - /* errata 5 */ - hw->mac.vft_shadow[regindex] = vfta; return 0; } @@ -2193,8 +2188,6 @@ s32 txgbe_clear_vfta(struct txgbe_hw *hw) for (offset = 0; offset < hw->mac.vft_size; offset++) { wr32(hw, TXGBE_PSR_VLAN_TBL(offset), 0); - /* errata 5 */ - hw->mac.vft_shadow[offset] = 0; } for (offset = 0; offset < TXGBE_PSR_VLAN_SWC_ENTRIES; offset++) { @@ -2549,7 +2542,7 @@ s32 txgbe_host_interface_command(struct txgbe_hw *hw, u32 *buffer, buf[0] = rd32(hw, TXGBE_MNG_MBOX); if ((buf[0] & 0xff0000) >> 16 == 0x80) { - ERROR_REPORT1(TXGBE_ERROR_CAUTION, "It's unknown cmd.\n"); + ERROR_REPORT1(TXGBE_ERROR_UNSUPPORTED, "It's unknown cmd.\n"); status = TXGBE_ERR_MNG_ACCESS_FAILED; goto rel_out; } diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c index 1a365c39cda7f5e19230a0d0b30da6ba404549b7..a13a4d4e73b70c325ec5fadc65e0498552bfc633 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "txgbe.h" #include "txgbe_dcb.h" @@ -48,7 +49,7 @@ char txgbe_driver_name[32] = TXGBE_NAME; static const char txgbe_driver_string[] = "WangXun RP1000/RP2000/FF50XX PCI Express Network Driver"; -#define DRV_VERSION __stringify(2.1.1oe) +#define DRV_VERSION __stringify(2.1.1.3oe) const char txgbe_driver_version[32] = DRV_VERSION; static const char txgbe_copyright[] = @@ -165,10 +166,10 @@ static void txgbe_dump_all_ring_desc(struct txgbe_adapter *adapter) if (!netif_msg_tx_err(adapter)) return; - e_warn(tx_err, "Dump desc base addr\n"); + e_warn(tx_err, "Dump desc base addr.\n"); for (i = 0; i < adapter->num_tx_queues; i++) - e_warn(tx_err, "q_%d:0x%x%x\n", i, rd32(hw, TXGBE_PX_TR_BAH(i)), + e_warn(tx_err, "txq_%d:0x%x%x\n", i, rd32(hw, TXGBE_PX_TR_BAH(i)), rd32(hw, TXGBE_PX_TR_BAL(i))); for (i = 0; i < adapter->num_tx_queues; i++) { @@ -181,6 +182,12 @@ static void txgbe_dump_all_ring_desc(struct txgbe_adapter *adapter) tx_desc->read.cmd_type_len, tx_desc->read.olinfo_status); } + + e_warn(drv, "tx ring %d next_to_use is %d, next_to_clean is %d\n", + i, tx_ring->next_to_use, tx_ring->next_to_clean); + e_warn(drv, "tx ring %d hw rp is 0x%x, wp is 0x%x\n", + i, rd32(hw, TXGBE_PX_TR_RP(tx_ring->reg_idx)), + rd32(hw, TXGBE_PX_TR_WP(tx_ring->reg_idx))); } } @@ -458,12 +465,20 @@ static void txgbe_update_xoff_received(struct txgbe_adapter *adapter) for (i = 0; i < MAX_TX_PACKET_BUFFERS; i++) { u32 pxoffrxc; - wr32m(hw, TXGBE_MMC_CONTROL, TXGBE_MMC_CONTROL_UP, i << 16); - pxoffrxc = rd32(hw, TXGBE_MAC_PXOFFRXC); - hwstats->pxoffrxc[i] += pxoffrxc; - /* Get the TC for given UP */ - tc = netdev_get_prio_tc_map(adapter->netdev, i); - xoff[tc] += pxoffrxc; + if (hw->mac.type == txgbe_mac_aml || hw->mac.type == txgbe_mac_aml40) { + pxoffrxc = rd32(hw, TXGBE_AML_MAC_PXOFFRXC(i)); + hwstats->pxoffrxc[i] = pxoffrxc; + /* Get the TC for given UP */ + tc = netdev_get_prio_tc_map(adapter->netdev, i); + xoff[tc] = pxoffrxc; + } else { + wr32m(hw, TXGBE_MMC_CONTROL, TXGBE_MMC_CONTROL_UP, i<<16); + pxoffrxc = rd32(hw, TXGBE_MAC_PXOFFRXC); + hwstats->pxoffrxc[i] += pxoffrxc; + /* Get the TC for given UP */ + tc = netdev_get_prio_tc_map(adapter->netdev, i); + xoff[tc] += pxoffrxc; + } } /* disarm tx queues that have received xoff frames */ @@ -539,12 +554,7 @@ static inline bool txgbe_check_tx_hang(struct txgbe_ring *tx_ring) static void txgbe_tx_timeout_dorecovery(struct txgbe_adapter *adapter) { - /* schedule immediate reset if we believe we hung */ - - if (adapter->hw.bus.lan_id == 0) - adapter->flags2 |= TXGBE_FLAG2_PCIE_NEED_RECOVER; - else - wr32(&adapter->hw, TXGBE_MIS_PF_SM, 1); + adapter->flags2 |= TXGBE_FLAG2_RING_DUMP; txgbe_service_event_schedule(adapter); } @@ -674,12 +684,17 @@ static bool txgbe_clean_tx_irq(struct txgbe_q_vector *q_vector, u32 size; unsigned int ntf; struct txgbe_tx_buffer *free_tx_buffer; - u32 unmapped_descs = 0; + s32 unmapped_descs = 0; bool first_dma; + ktime_t now; + u64 ms; if (test_bit(__TXGBE_DOWN, &adapter->state)) return true; + now = ktime_get(); + ms = ktime_to_ms(now); + tx_buffer = &tx_ring->tx_buffer_info[i]; tx_desc = TXGBE_TX_DESC(tx_ring, i); i -= tx_ring->count; @@ -712,6 +727,7 @@ static bool txgbe_clean_tx_irq(struct txgbe_q_vector *q_vector, /* clear next_to_watch to prevent false hangs */ tx_buffer->next_to_watch = NULL; + tx_buffer->done_time = ms; /* update the statistics for this packet */ total_bytes += tx_buffer->bytecount; @@ -734,6 +750,8 @@ static bool txgbe_clean_tx_irq(struct txgbe_q_vector *q_vector, tx_buffer = tx_ring->tx_buffer_info; tx_desc = TXGBE_TX_DESC(tx_ring, 0); } + + tx_buffer->done_time = ms; } /* move us one more past the eop_desc for start of next pkt */ tx_buffer++; @@ -744,7 +762,6 @@ static bool txgbe_clean_tx_irq(struct txgbe_q_vector *q_vector, tx_buffer = tx_ring->tx_buffer_info; tx_desc = TXGBE_TX_DESC(tx_ring, 0); } - /* issue prefetch for next Tx descriptor */ prefetch(tx_desc); @@ -759,7 +776,8 @@ static bool txgbe_clean_tx_irq(struct txgbe_q_vector *q_vector, free_tx_buffer = &tx_ring->tx_buffer_info[ntf]; ntf -= tx_ring->count; unmapped_descs = txgbe_desc_buf_unmapped(tx_ring, i, tx_ring->next_to_free); - while (unmapped_descs > adapter->desc_reserved) { + while ((unmapped_descs > adapter->desc_reserved) || + ((ms - free_tx_buffer->done_time >= 150) && (free_tx_buffer->done_time != 0))) { if (ring_is_xdp(tx_ring)) { if (free_tx_buffer->xdpf) { xdp_return_frame(free_tx_buffer->xdpf); @@ -788,6 +806,7 @@ static bool txgbe_clean_tx_irq(struct txgbe_q_vector *q_vector, dma_unmap_len_set(free_tx_buffer, len, 0); free_tx_buffer->va = NULL; + free_tx_buffer->done_time = 0; first_dma = false; } else { /* unmap any remaining paged data */ @@ -799,6 +818,7 @@ static bool txgbe_clean_tx_irq(struct txgbe_q_vector *q_vector, dma_unmap_len_set(free_tx_buffer, len, 0); free_tx_buffer->va = NULL; } + free_tx_buffer->done_time = 0; } free_tx_buffer++; @@ -2656,7 +2676,6 @@ static void txgbe_tx_ring_recovery(struct txgbe_adapter *adapter) for (i = 0; i < adapter->num_tx_queues; i++) { if (desc_error[i / 32] & (1 << i % 32)) { - adapter->flags2 |= TXGBE_FLAG2_PCIE_NEED_Q_RESET; e_err(drv, "TDM non-fatal error, queue[%d]", i); } } @@ -2669,7 +2688,6 @@ static irqreturn_t txgbe_msix_other(int __always_unused irq, void *data) u32 eicr; u32 ecc; u32 value = 0; - u16 vid; eicr = txgbe_misc_isb(adapter, TXGBE_ISB_MISC); @@ -2696,19 +2714,8 @@ static irqreturn_t txgbe_msix_other(int __always_unused irq, void *data) if (eicr & TXGBE_PX_MISC_IC_PCIE_REQ_ERR) { ERROR_REPORT1(TXGBE_ERROR_POLLING, "lan id %d, PCIe request error founded.\n", hw->bus.lan_id); - pci_read_config_word(adapter->pdev, PCI_VENDOR_ID, &vid); - if (vid == TXGBE_FAILED_READ_CFG_WORD) { - ERROR_REPORT1(TXGBE_ERROR_POLLING, "PCIe link is lost.\n"); - /*when pci lose link, not check over heat*/ - if (hw->bus.lan_id == 0) { - adapter->flags2 |= TXGBE_FLAG2_PCIE_NEED_RECOVER; - txgbe_service_event_schedule(adapter); - } else { - wr32(&adapter->hw, TXGBE_MIS_PF_SM, 1); - } - } else { - adapter->flags2 |= TXGBE_FLAG2_DMA_RESET_REQUESTED; - } + + txgbe_tx_timeout_dorecovery(adapter); } if (eicr & TXGBE_PX_MISC_IC_INT_ERR) { @@ -4052,16 +4059,21 @@ int txgbe_write_mc_addr_list(struct net_device *netdev) struct netdev_hw_addr *ha; u8 *addr_list = NULL; int addr_count = 0; + bool clear = false; if (!hw->mac.ops.update_mc_addr_list) return -ENOMEM; if (!netif_running(netdev)) return 0; - +#ifdef CONFIG_PCI_IOV + txgbe_restore_vf_multicasts(adapter); +#else + clear = true; +#endif if (netdev_mc_empty(netdev)) { hw->mac.ops.update_mc_addr_list(hw, NULL, 0, - txgbe_addr_list_itr, true); + txgbe_addr_list_itr, clear); } else { ha = list_first_entry(&netdev->mc.list, struct netdev_hw_addr, list); @@ -4070,12 +4082,9 @@ int txgbe_write_mc_addr_list(struct net_device *netdev) addr_count = netdev_mc_count(netdev); hw->mac.ops.update_mc_addr_list(hw, addr_list, addr_count, - txgbe_addr_list_itr, true); + txgbe_addr_list_itr, clear); } -#ifdef CONFIG_PCI_IOV - txgbe_restore_vf_multicasts(adapter); -#endif return addr_count; } @@ -4362,7 +4371,14 @@ static void txgbe_scrub_vfta(struct txgbe_adapter *adapter) /* extract values from vft_shadow and write back to VFTA */ for (i = 0; i < hw->mac.vft_size; i++) { - vfta = hw->mac.vft_shadow[i]; +#ifdef CONFIG_64BIT + if (i % 2) + vfta = (u32)((adapter->active_vlans[i / 2] >> 32) & U32_MAX); + else + vfta = (u32)((adapter->active_vlans[i / 2]) & U32_MAX); +#else + vfta = (u32)((adapter->active_vlans[i]) & U32_MAX); +#endif wr32(hw, TXGBE_PSR_VLAN_TBL(i), vfta); } } @@ -5237,6 +5253,7 @@ static void txgbe_up_complete(struct txgbe_adapter *adapter) adapter->link_check_timeout = jiffies; hw->f2c_mod_status = false; mod_timer(&adapter->service_timer, jiffies); + mod_timer(&adapter->irq_timer, jiffies); /* PCIE recovery: record lan status */ if (hw->bus.lan_id == 0) { @@ -5270,8 +5287,6 @@ void txgbe_reinit_locked(struct txgbe_adapter *adapter) /* put off any impending NetWatchDogTimeout */ netif_trans_update(adapter->netdev); - adapter->flags2 |= TXGBE_FLAG2_SERVICE_RUNNING; - while (test_and_set_bit(__TXGBE_RESETTING, &adapter->state)) usleep_range(1000, 2000); txgbe_down(adapter); @@ -5372,7 +5387,8 @@ void txgbe_reset(struct txgbe_adapter *adapter) break; case TXGBE_ERR_MASTER_REQUESTS_PENDING: e_dev_err("master disable timed out\n"); - txgbe_tx_timeout_dorecovery(adapter); + if (!adapter->io_err) + txgbe_tx_timeout_dorecovery(adapter); break; case TXGBE_ERR_EEPROM_VERSION: /* We are running on a pre-production device, log a warning */ @@ -5598,7 +5614,7 @@ static void txgbe_disable_device(struct txgbe_adapter *adapter) adapter->flags &= ~TXGBE_FLAG_NEED_LINK_UPDATE; del_timer_sync(&adapter->service_timer); - adapter->flags2 &= ~TXGBE_FLAG2_SERVICE_RUNNING; + del_timer_sync(&adapter->irq_timer); hw->f2c_mod_status = false; cancel_work_sync(&adapter->sfp_sta_task); @@ -6390,6 +6406,21 @@ static void txgbe_close_suspend(struct txgbe_adapter *adapter) txgbe_free_all_tx_resources(adapter); } + +static void txgbe_down_suspend(struct txgbe_adapter *adapter) +{ +#ifdef HAVE_PTP_1588_CLOCK + txgbe_ptp_suspend(adapter); +#endif + + txgbe_down(adapter); + txgbe_free_irq(adapter); + + txgbe_free_isb_resources(adapter); + txgbe_free_all_rx_resources(adapter); + txgbe_free_all_tx_resources(adapter); +} + /** * txgbe_close - Disables a network interface * @netdev: network interface device structure @@ -6414,12 +6445,8 @@ int txgbe_close(struct net_device *netdev) txgbe_ptp_stop(adapter); - txgbe_down(adapter); - txgbe_free_irq(adapter); - - txgbe_free_isb_resources(adapter); - txgbe_free_all_rx_resources(adapter); - txgbe_free_all_tx_resources(adapter); + if (netif_device_present(netdev)) + txgbe_down_suspend(adapter); txgbe_fdir_filter_exit(adapter); memset(&adapter->ft_filter_info, 0, @@ -6469,14 +6496,11 @@ static int txgbe_resume(struct device *dev) if (!err && netif_running(netdev)) err = txgbe_open(netdev); + if (!err) + netif_device_attach(netdev); rtnl_unlock(); - if (err) - return err; - - netif_device_attach(netdev); - - return 0; + return err; } /** @@ -6542,16 +6566,16 @@ static int __txgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) int retval = 0; #endif + rtnl_lock(); netif_device_detach(netdev); txgbe_mac_set_default_filter(adapter, hw->mac.perm_addr); - rtnl_lock(); if (netif_running(netdev)) txgbe_close_suspend(adapter); - rtnl_unlock(); txgbe_clear_interrupt_scheme(adapter); + rtnl_unlock(); #ifdef CONFIG_PM retval = pci_save_state(pdev); if (retval) @@ -6784,7 +6808,10 @@ void txgbe_update_stats(struct txgbe_adapter *adapter) hwstats->pxontxc[i] += rd32(hw, TXGBE_RDB_PXONTXC(i)); hwstats->pxofftxc[i] += rd32(hw, TXGBE_RDB_PXOFFTXC(i)); - hwstats->pxonrxc[i] += rd32(hw, TXGBE_MAC_PXONRXC(i)); + if (hw->mac.type == txgbe_mac_aml || hw->mac.type == txgbe_mac_aml40) + hwstats->pxonrxc[i] = rd32(hw, TXGBE_AML_MAC_PXONRXC(i)); + else + hwstats->pxonrxc[i] += rd32(hw, TXGBE_MAC_PXONRXC(i)); } hwstats->gprc += rd32(hw, TXGBE_PX_GPRC); @@ -6912,7 +6939,7 @@ static void txgbe_fdir_reinit_subtask(struct txgbe_adapter *adapter) } } -void txgbe_irq_rearm_queues(struct txgbe_adapter *adapter, +static void txgbe_irq_rearm_queues(struct txgbe_adapter *adapter, u64 qmask) { u32 mask; @@ -6938,7 +6965,6 @@ void txgbe_irq_rearm_queues(struct txgbe_adapter *adapter, static void txgbe_check_hang_subtask(struct txgbe_adapter *adapter) { int i; - u64 eics = 0; /* If we're down or resetting, just bail */ if (test_bit(__TXGBE_DOWN, &adapter->state) || @@ -6953,6 +6979,18 @@ static void txgbe_check_hang_subtask(struct txgbe_adapter *adapter) for (i = 0; i < adapter->num_xdp_queues; i++) set_check_for_tx_hang(adapter->xdp_ring[i]); } +} + +static void txgbe_trigger_irq_subtask(struct txgbe_adapter *adapter) +{ + int i; + u64 eics = 0; + + /* If we're down or resetting, just bail */ + if (test_bit(__TXGBE_DOWN, &adapter->state) || + test_bit(__TXGBE_REMOVING, &adapter->state) || + test_bit(__TXGBE_RESETTING, &adapter->state)) + return; if (adapter->flags & TXGBE_FLAG_MSIX_ENABLED) { /* get one bit for every active tx/rx interrupt vector */ @@ -7369,6 +7407,35 @@ static void txgbe_spoof_check(struct txgbe_adapter *adapter) #endif /* CONFIG_PCI_IOV */ +/** + * txgbe_watchdog_subtask - check and bring link up + * @adapter - pointer to the device adapter structure + **/ +static void txgbe_linkdown_subtask(struct txgbe_adapter *adapter) +{ + u32 __maybe_unused value = 0; + + /* if interface is down do nothing */ + if (test_bit(__TXGBE_DOWN, &adapter->state) || + test_bit(__TXGBE_REMOVING, &adapter->state) || + test_bit(__TXGBE_RESETTING, &adapter->state)) + return; + + if (!(adapter->flags2 & TXGBE_FLAG2_LINK_DOWN)) + txgbe_watchdog_update_link(adapter); + + if (!adapter->link_up) + txgbe_watchdog_link_is_down(adapter); + +#ifdef CONFIG_PCI_IOV + txgbe_spoof_check(adapter); +#endif /* CONFIG_PCI_IOV */ + + txgbe_update_stats(adapter); + + txgbe_watchdog_flush_tx(adapter); +} + /** * txgbe_watchdog_subtask - check and bring link up * @adapter - pointer to the device adapter structure @@ -7574,6 +7641,8 @@ static void txgbe_sfp_link_config_subtask(struct txgbe_adapter *adapter) else if (speed & TXGBE_LINK_SPEED_10GB_FULL) speed = TXGBE_LINK_SPEED_10GB_FULL; } + + adapter->autoneg = autoneg; } } @@ -7771,6 +7840,16 @@ static void txgbe_amlit_temp_subtask(struct txgbe_adapter *adapter) mutex_unlock(&adapter->e56_lock); } +static void txgbe_irq_timer(struct timer_list *t) +{ + struct txgbe_adapter *adapter = from_timer(adapter, t, irq_timer); + unsigned long next_event_offset = HZ / 4; + + mod_timer(&adapter->irq_timer, next_event_offset + jiffies); + + txgbe_trigger_irq_subtask(adapter); +} + static void txgbe_reset_subtask(struct txgbe_adapter *adapter) { u32 reset_flag = 0; @@ -7938,15 +8017,43 @@ static void txgbe_reset_subtask(struct txgbe_adapter *adapter) rtnl_unlock(); } -static void txgbe_check_pcie_subtask(struct txgbe_adapter *adapter) +static void txgbe_check_ring_dump_subtask(struct txgbe_adapter *adapter) { - bool status; + struct txgbe_hw *hw = &adapter->hw; + u32 val; - if (!(adapter->flags2 & TXGBE_FLAG2_PCIE_NEED_RECOVER)) + if (!(adapter->flags2 & TXGBE_FLAG2_RING_DUMP)) return; txgbe_print_tx_hang_status(adapter); txgbe_dump_all_ring_desc(adapter); + wr32(&adapter->hw, TXGBE_MIS_PF_SM, 1); + adapter->flags2 &= ~TXGBE_FLAG2_RING_DUMP; + + /* record which func to provoke PCIE recovery */ + if (rd32(&adapter->hw, TXGBE_MIS_PF_SM) == 1) { + val = rd32m(&adapter->hw, TXGBE_MIS_PRB_CTL, TXGBE_MIS_PRB_CTL_LAN0_UP | + TXGBE_MIS_PRB_CTL_LAN1_UP); + if (val & TXGBE_MIS_PRB_CTL_LAN0_UP) { + if (hw->bus.lan_id == 0) { + adapter->flags2 |= TXGBE_FLAG2_PCIE_NEED_RECOVER; + e_info(probe, "check_ring_dump_subtask: set recover on Lan0\n"); + } + } else if (val & TXGBE_MIS_PRB_CTL_LAN1_UP) { + if (hw->bus.lan_id == 1) { + adapter->flags2 |= TXGBE_FLAG2_PCIE_NEED_RECOVER; + e_info(probe, "check_ring_dump_subtask: set recover on Lan1\n"); + } + } + } +} + +static void txgbe_check_pcie_subtask(struct txgbe_adapter *adapter) +{ + bool status; + + if (!(adapter->flags2 & TXGBE_FLAG2_PCIE_NEED_RECOVER)) + return; wr32m(&adapter->hw, TXGBE_MIS_PF_SM, TXGBE_MIS_PF_SM_SM, 0); @@ -7973,6 +8080,9 @@ static void txgbe_tx_queue_clear_error_task(struct txgbe_adapter *adapter) struct txgbe_tx_buffer *tx_buffer; u32 size; + if (test_bit(__TXGBE_DOWN, &adapter->state)) + return; + for (i = 0; i < 4; i++) desc_error[i] = rd32(hw, TXGBE_TDM_DESC_NONFATAL(i)); @@ -7986,6 +8096,8 @@ static void txgbe_tx_queue_clear_error_task(struct txgbe_adapter *adapter) rd32(&adapter->hw, TXGBE_PX_TR_RP(adapter->tx_ring[i]->reg_idx))); for (j = 0; j < tx_ring->count; j++) { tx_desc = TXGBE_TX_DESC(tx_ring, j); + if (!tx_desc) + return; if (tx_desc->read.olinfo_status != 0x1) e_warn(tx_err, "queue[%d][%d]:0x%llx, 0x%x, 0x%x\n", i, j, tx_desc->read.buffer_addr, tx_desc->read.cmd_type_len, @@ -8049,6 +8161,7 @@ static void txgbe_service_task(struct work_struct *work) return; } + txgbe_check_ring_dump_subtask(adapter); txgbe_check_pcie_subtask(adapter); txgbe_reset_subtask(adapter); txgbe_phy_event_subtask(adapter); @@ -8059,7 +8172,7 @@ static void txgbe_service_task(struct work_struct *work) hw->phy.sfp_type == txgbe_qsfp_type_40g_cu_core0 || hw->phy.sfp_type == txgbe_qsfp_type_40g_cu_core1 || txgbe_is_backplane(hw))) - txgbe_watchdog_subtask(adapter); + txgbe_linkdown_subtask(adapter); txgbe_sfp_link_config_subtask(adapter); txgbe_sfp_reset_eth_phy_subtask(adapter); txgbe_check_overtemp_subtask(adapter); @@ -10532,6 +10645,7 @@ static int txgbe_probe(struct pci_dev *pdev, sizeof(struct txgbe_5tuple_filter_info)); timer_setup(&adapter->service_timer, txgbe_service_timer, 0); + timer_setup(&adapter->irq_timer, txgbe_irq_timer, 0); if (TXGBE_REMOVED(hw->hw_addr)) { err = -EIO; @@ -10992,14 +11106,16 @@ static pci_ers_result_t txgbe_io_error_detected(struct pci_dev *pdev, rtnl_lock(); netif_device_detach(netdev); + adapter->io_err = true; + + if (netif_running(netdev)) + txgbe_down_suspend(adapter); + if (state == pci_channel_io_perm_failure) { rtnl_unlock(); return PCI_ERS_RESULT_DISCONNECT; } - if (netif_running(netdev)) - txgbe_close(netdev); - if (!test_and_set_bit(__TXGBE_DISABLED, &adapter->state)) pci_disable_device(pdev); rtnl_unlock(); @@ -11077,6 +11193,8 @@ static void txgbe_io_resume(struct pci_dev *pdev) if (netif_running(netdev)) txgbe_open(netdev); + adapter->io_err = false; + netif_device_attach(netdev); rtnl_unlock(); } diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c index 07a835757226e6bd39c2e077db1348b4a1c44f35..2d642dff805c628402ccf0e9d60cac18751b6ac1 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c @@ -568,6 +568,9 @@ s32 txgbe_identify_sfp_module(struct txgbe_hw *hw) if (status != 0) goto err_read_i2c_eeprom; + hw->bypass_ctle = true; + hw->dac_sfp = false; + /* ID Module * ========= * 0 SFP_DA_CU @@ -812,7 +815,7 @@ s32 txgbe_identify_sfp_module(struct txgbe_hw *hw) if (cable_tech & (TXGBE_SFF_DA_PASSIVE_CABLE | TXGBE_SFF_DA_ACTIVE_CABLE)) { status = 0; - goto out; + goto sp_record; } /* Verify supported 1G SFP modules */ @@ -828,50 +831,53 @@ s32 txgbe_identify_sfp_module(struct txgbe_hw *hw) goto out; } } - /*record eeprom info*/ - status = hw->phy.ops.read_i2c_eeprom(hw, - TXGBE_SFF_SFF_8472_COMP, - &sff8472_rev); - if (status != 0) - goto err_read_i2c_eeprom; +sp_record: + if (hw->mac.type == txgbe_mac_sp && + !test_bit(__TXGBE_DOWN, &adapter->state)) { + /*record eeprom info*/ + status = hw->phy.ops.read_i2c_eeprom(hw, + TXGBE_SFF_SFF_8472_COMP, + &sff8472_rev); + if (status != 0) + goto err_read_i2c_eeprom; - /* addressing mode is not supported */ - status = hw->phy.ops.read_i2c_eeprom(hw, - TXGBE_SFF_SFF_8472_SWAP, - &addr_mode); - if (status != 0) - goto err_read_i2c_eeprom; + /* addressing mode is not supported */ + status = hw->phy.ops.read_i2c_eeprom(hw, + TXGBE_SFF_SFF_8472_SWAP, + &addr_mode); + if (status != 0) + goto err_read_i2c_eeprom; - if (addr_mode & TXGBE_SFF_ADDRESSING_MODE) { - e_err(drv, "Address change required to access page 0xA2,"); - e_err(drv, "but not supported. Please report the module type to the driver maintainers.\n"); - page_swap = true; - } + if (addr_mode & TXGBE_SFF_ADDRESSING_MODE) { + e_err(drv, "Address change required to access page 0xA2,"); + e_err(drv, "but not supported. Please report the module type to the driver maintainers.\n"); + page_swap = true; + } - if (sff8472_rev == TXGBE_SFF_SFF_8472_UNSUP || page_swap || - !(addr_mode & TXGBE_SFF_DDM_IMPLEMENTED)) { - /* We have a SFP, but it does not support SFF-8472 */ - adapter->eeprom_type = ETH_MODULE_SFF_8079; - adapter->eeprom_len = ETH_MODULE_SFF_8079_LEN; - } else { - /* We have a SFP which supports a revision of SFF-8472. */ - adapter->eeprom_type = ETH_MODULE_SFF_8472; - adapter->eeprom_len = ETH_MODULE_SFF_8472_LEN; - } - for (i = 0; i < adapter->eeprom_len; i++) { - if (i < ETH_MODULE_SFF_8079_LEN) - status = hw->phy.ops.read_i2c_eeprom(hw, i, - &databyte); - else - status = hw->phy.ops.read_i2c_sff8472(hw, i, - &databyte); + if (sff8472_rev == TXGBE_SFF_SFF_8472_UNSUP || page_swap || + !(addr_mode & TXGBE_SFF_DDM_IMPLEMENTED)) { + /* We have a SFP, but it does not support SFF-8472 */ + adapter->eeprom_type = ETH_MODULE_SFF_8079; + adapter->eeprom_len = ETH_MODULE_SFF_8079_LEN; + } else { + /* We have a SFP which supports a revision of SFF-8472. */ + adapter->eeprom_type = ETH_MODULE_SFF_8472; + adapter->eeprom_len = ETH_MODULE_SFF_8472_LEN; + } + for (i = 0; i < adapter->eeprom_len; i++) { + if (i < ETH_MODULE_SFF_8079_LEN) + status = hw->phy.ops.read_i2c_eeprom(hw, i, + &databyte); + else + status = hw->phy.ops.read_i2c_sff8472(hw, i, + &databyte); - if (status != 0) - goto err_read_i2c_eeprom; + if (status != 0) + goto err_read_i2c_eeprom; - adapter->i2c_eeprom[i] = databyte; + adapter->i2c_eeprom[i] = databyte; + } } - out: hw->mac.ops.release_swfw_sync(hw, swfw_mask); diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_sriov.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_sriov.c index c467be6b1be3826a2ed9937e068e5c741d13a4a1..4ad7c28260481f75c1cfdf7cccc0d481d3d43b6d 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_sriov.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_sriov.c @@ -337,9 +337,6 @@ static int txgbe_set_vf_multicasts(struct txgbe_adapter *adapter, struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; struct txgbe_hw *hw = &adapter->hw; int i; - u32 vector_bit; - u32 vector_reg; - u32 mta_reg; u32 vmolr = rd32(hw, TXGBE_PSR_VM_L2CTL(vf)); /* only so many hash values supported */ @@ -357,18 +354,12 @@ static int txgbe_set_vf_multicasts(struct txgbe_adapter *adapter, for (i = 0; i < entries; i++) vfinfo->vf_mc_hashes[i] = hash_list[i]; - for (i = 0; i < vfinfo->num_vf_mc_hashes; i++) { - vector_reg = (vfinfo->vf_mc_hashes[i] >> 5) & 0x7F; - vector_bit = vfinfo->vf_mc_hashes[i] & 0x1F; - /* errata 5: maintain a copy of the register table conf */ - mta_reg = hw->mac.mta_shadow[vector_reg]; - mta_reg |= (1 << vector_bit); - hw->mac.mta_shadow[vector_reg] = mta_reg; - wr32(hw, TXGBE_PSR_MC_TBL(vector_reg), mta_reg); - } vmolr |= TXGBE_PSR_VM_L2CTL_ROMPE; wr32(hw, TXGBE_PSR_VM_L2CTL(vf), vmolr); + /* Sync up the PF and VF in the same MTA table */ + txgbe_write_mc_addr_list(adapter->netdev); + return 0; } @@ -380,6 +371,9 @@ void txgbe_restore_vf_multicasts(struct txgbe_adapter *adapter) u32 vector_bit; u32 vector_reg; + /* Clear mta_shadow */ + memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow)); + for (i = 0; i < adapter->num_vfs; i++) { u32 vmolr = rd32(hw, TXGBE_PSR_VM_L2CTL(i)); diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h index 451c5936c662c26b3fd4ab29f3193181862182ea..3ba1eccdacce413f0d3d976c70c9ddd3fc8e5eef 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h @@ -956,6 +956,8 @@ struct txgbe_thermal_sensor_data { #define TXGBE_RDB_PFCMACDAH 0x19214 #define TXGBE_RDB_TXSWERR 0x1906C #define TXGBE_RDB_TXSWERR_TB_FREE 0x3FF +#define TXGBE_PFC_DIS_MASK 0x11F6c +#define TXGBE_PFC_DIS_MASK_VAL 0xff /* rdb_pl_cfg reg mask */ #define TXGBE_RDB_PL_CFG_L4HDR 0x2 #define TXGBE_RDB_PL_CFG_L3HDR 0x4 @@ -1634,6 +1636,8 @@ enum TXGBE_MSCA_CMD_value { #define TXGBE_MAC_LXOFFRXC 0x11988 #define TXGBE_MAC_PXONRXC(_i) (0x11E30 + ((_i) * 4)) /* 8 of these */ #define TXGBE_MAC_PXOFFRXC 0x119DC +#define TXGBE_AML_MAC_PXONRXC(_i) (0x11FC0 + ((_i) * 4)) /* 8 of these */ +#define TXGBE_AML_MAC_PXOFFRXC(_i) (0x11FA0 + ((_i) * 4)) /* 8 of these */ #define TXGBE_RX_BC_FRAMES_GOOD_LOW 0x11918 #define TXGBE_RX_CRC_ERROR_FRAMES_LOW 0x11928 #define TXGBE_RX_LEN_ERROR_FRAMES_LOW 0x11978 @@ -1645,7 +1649,7 @@ enum TXGBE_MSCA_CMD_value { #define TXGBE_TX_BC_FRAMES_GOOD_LOW 0x11824 #define TXGBE_MMC_CONTROL 0x11800 #define TXGBE_MMC_CONTROL_RSTONRD 0x4 /* reset on read */ -#define TXGBE_MMC_CONTROL_UP 0x700 +#define TXGBE_MMC_CONTROL_UP 0x70000 /********************************* BAR registers ***************************/ /* Interrupt Registers */ @@ -3246,7 +3250,6 @@ struct txgbe_mac_info { u32 mta_shadow[TXGBE_MAX_MTA]; s32 mc_filter_type; u32 mcft_size; - u32 vft_shadow[TXGBE_MAX_VFTA_ENTRIES]; u32 vft_size; u32 num_rar_entries; u32 rar_highwater;