net/ice/base: add helper function to redirect flags
[dpdk.git] / drivers / net / txgbe / base / txgbe_hw.c
index c357c86..00a8db7 100644 (file)
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2015-2020
+ * Copyright(c) 2015-2020 Beijing WangXun Technology Co., Ltd.
+ * Copyright(c) 2010-2017 Intel Corporation
  */
 
 #include "txgbe_type.h"
@@ -60,9 +61,9 @@ bool txgbe_device_supports_autoneg_fc(struct txgbe_hw *hw)
                break;
        case txgbe_media_type_copper:
                /* only some copper devices support flow control autoneg */
-               switch (hw->device_id) {
-               case TXGBE_DEV_ID_RAPTOR_XAUI:
-               case TXGBE_DEV_ID_RAPTOR_SGMII:
+               switch (hw->subsystem_device_id & 0xFF) {
+               case TXGBE_DEV_ID_XAUI:
+               case TXGBE_DEV_ID_SGMII:
                        supported = true;
                        break;
                default:
@@ -91,7 +92,6 @@ s32 txgbe_setup_fc(struct txgbe_hw *hw)
        u16 reg_cu = 0;
        u32 value = 0;
        u64 reg_bp = 0;
-       bool locked = false;
 
        DEBUGFUNC("txgbe_setup_fc");
 
@@ -109,29 +109,6 @@ s32 txgbe_setup_fc(struct txgbe_hw *hw)
        if (hw->fc.requested_mode == txgbe_fc_default)
                hw->fc.requested_mode = txgbe_fc_full;
 
-       /*
-        * Set up the 1G and 10G flow control advertisement registers so the
-        * HW will be able to do fc autoneg once the cable is plugged in.  If
-        * we link at 10G, the 1G advertisement is harmless and vice versa.
-        */
-       switch (hw->phy.media_type) {
-       case txgbe_media_type_backplane:
-               /* some MAC's need RMW protection on AUTOC */
-               err = hw->mac.prot_autoc_read(hw, &locked, &reg_bp);
-               if (err != 0)
-                       goto out;
-
-               /* fall through - only backplane uses autoc */
-       case txgbe_media_type_fiber_qsfp:
-       case txgbe_media_type_fiber:
-       case txgbe_media_type_copper:
-               hw->phy.read_reg(hw, TXGBE_MD_AUTO_NEG_ADVT,
-                                    TXGBE_MD_DEV_AUTO_NEG, &reg_cu);
-               break;
-       default:
-               break;
-       }
-
        /*
         * The possible values of fc.requested_mode are:
         * 0: Flow control is completely disabled
@@ -145,13 +122,6 @@ s32 txgbe_setup_fc(struct txgbe_hw *hw)
        switch (hw->fc.requested_mode) {
        case txgbe_fc_none:
                /* Flow control completely disabled by software override. */
-               reg &= ~(SR_MII_MMD_AN_ADV_PAUSE_SYM |
-                       SR_MII_MMD_AN_ADV_PAUSE_ASM);
-               if (hw->phy.media_type == txgbe_media_type_backplane)
-                       reg_bp &= ~(TXGBE_AUTOC_SYM_PAUSE |
-                                   TXGBE_AUTOC_ASM_PAUSE);
-               else if (hw->phy.media_type == txgbe_media_type_copper)
-                       reg_cu &= ~(TXGBE_TAF_SYM_PAUSE | TXGBE_TAF_ASM_PAUSE);
                break;
        case txgbe_fc_tx_pause:
                /*
@@ -159,15 +129,6 @@ s32 txgbe_setup_fc(struct txgbe_hw *hw)
                 * disabled by software override.
                 */
                reg |= SR_MII_MMD_AN_ADV_PAUSE_ASM;
-               reg &= ~SR_MII_MMD_AN_ADV_PAUSE_SYM;
-               if (hw->phy.media_type == txgbe_media_type_backplane) {
-                       reg_bp |= TXGBE_AUTOC_ASM_PAUSE;
-                       reg_bp &= ~TXGBE_AUTOC_SYM_PAUSE;
-               } else if (hw->phy.media_type == txgbe_media_type_copper) {
-                       reg_cu |= TXGBE_TAF_ASM_PAUSE;
-                       reg_cu &= ~TXGBE_TAF_SYM_PAUSE;
-               }
-               reg |= SR_MII_MMD_AN_ADV_PAUSE_ASM;
                reg_bp |= SR_AN_MMD_ADV_REG1_PAUSE_ASM;
                break;
        case txgbe_fc_rx_pause:
@@ -182,13 +143,6 @@ s32 txgbe_setup_fc(struct txgbe_hw *hw)
                 */
        case txgbe_fc_full:
                /* Flow control (both Rx and Tx) is enabled by SW override. */
-               reg |= SR_MII_MMD_AN_ADV_PAUSE_SYM |
-                       SR_MII_MMD_AN_ADV_PAUSE_ASM;
-               if (hw->phy.media_type == txgbe_media_type_backplane)
-                       reg_bp |= TXGBE_AUTOC_SYM_PAUSE |
-                                 TXGBE_AUTOC_ASM_PAUSE;
-               else if (hw->phy.media_type == txgbe_media_type_copper)
-                       reg_cu |= TXGBE_TAF_SYM_PAUSE | TXGBE_TAF_ASM_PAUSE;
                reg |= SR_MII_MMD_AN_ADV_PAUSE_SYM |
                        SR_MII_MMD_AN_ADV_PAUSE_ASM;
                reg_bp |= SR_AN_MMD_ADV_REG1_PAUSE_SYM |
@@ -323,6 +277,9 @@ s32 txgbe_init_hw(struct txgbe_hw *hw)
 
        DEBUGFUNC("txgbe_init_hw");
 
+       /* Get firmware version */
+       hw->phy.get_fw_version(hw, &hw->fw_version);
+
        /* Reset the hardware */
        status = hw->mac.reset_hw(hw);
        if (status == 0 || status == TXGBE_ERR_SFP_NOT_PRESENT) {
@@ -2525,26 +2482,12 @@ s32 txgbe_set_mac_type(struct txgbe_hw *hw)
        }
 
        switch (hw->device_id) {
-       case TXGBE_DEV_ID_RAPTOR_KR_KX_KX4:
-               hw->phy.media_type = txgbe_media_type_backplane;
-               hw->mac.type = txgbe_mac_raptor;
-               break;
-       case TXGBE_DEV_ID_RAPTOR_XAUI:
-       case TXGBE_DEV_ID_RAPTOR_SGMII:
-               hw->phy.media_type = txgbe_media_type_copper;
-               hw->mac.type = txgbe_mac_raptor;
-               break;
-       case TXGBE_DEV_ID_RAPTOR_SFP:
-       case TXGBE_DEV_ID_WX1820_SFP:
-               hw->phy.media_type = txgbe_media_type_fiber;
-               hw->mac.type = txgbe_mac_raptor;
-               break;
-       case TXGBE_DEV_ID_RAPTOR_QSFP:
-               hw->phy.media_type = txgbe_media_type_fiber_qsfp;
+       case TXGBE_DEV_ID_SP1000:
+       case TXGBE_DEV_ID_WX1820:
                hw->mac.type = txgbe_mac_raptor;
                break;
-       case TXGBE_DEV_ID_RAPTOR_VF:
-       case TXGBE_DEV_ID_RAPTOR_VF_HV:
+       case TXGBE_DEV_ID_SP1000_VF:
+       case TXGBE_DEV_ID_WX1820_VF:
                hw->phy.media_type = txgbe_media_type_virtual;
                hw->mac.type = txgbe_mac_raptor_vf;
                break;
@@ -2554,8 +2497,8 @@ s32 txgbe_set_mac_type(struct txgbe_hw *hw)
                break;
        }
 
-       DEBUGOUT("found mac: %d media: %d, returns: %d\n",
-                 hw->mac.type, hw->phy.media_type, err);
+       DEBUGOUT("found mac: %d, returns: %d\n",
+                 hw->mac.type, err);
        return err;
 }
 
@@ -2586,13 +2529,9 @@ void txgbe_init_mac_link_ops(struct txgbe_hw *hw)
                mac->setup_link = txgbe_setup_mac_link_multispeed_fiber;
                mac->setup_mac_link = txgbe_setup_mac_link;
                mac->set_rate_select_speed = txgbe_set_hard_rate_select_speed;
-       } else if ((hw->phy.media_type == txgbe_media_type_backplane) &&
-                   (hw->phy.smart_speed == txgbe_smart_speed_auto ||
-                    hw->phy.smart_speed == txgbe_smart_speed_on) &&
-                    !txgbe_verify_lesm_fw_enabled_raptor(hw)) {
-               mac->setup_link = txgbe_setup_mac_link_smartspeed;
        } else {
                mac->setup_link = txgbe_setup_mac_link;
+               mac->set_rate_select_speed = txgbe_set_hard_rate_select_speed;
        }
 }
 
@@ -2613,7 +2552,7 @@ s32 txgbe_init_phy_raptor(struct txgbe_hw *hw)
 
        DEBUGFUNC("txgbe_init_phy_raptor");
 
-       if (hw->device_id == TXGBE_DEV_ID_RAPTOR_QSFP) {
+       if ((hw->device_id & 0xFF) == TXGBE_DEV_ID_QSFP) {
                /* Store flag indicating I2C bus access control unit. */
                hw->phy.qsfp_shared_i2c_bus = TRUE;
 
@@ -2636,6 +2575,11 @@ s32 txgbe_init_phy_raptor(struct txgbe_hw *hw)
                                  txgbe_get_copper_link_capabilities;
        }
 
+       if (phy->media_type == txgbe_media_type_backplane) {
+               mac->kr_handle = txgbe_kr_handle;
+               mac->bp_down_event = txgbe_bp_down_event;
+       }
+
        /* Set necessary function pointers based on PHY type */
        switch (hw->phy.type) {
        case txgbe_phy_tn:
@@ -2788,6 +2732,7 @@ s32 txgbe_init_ops_pf(struct txgbe_hw *hw)
        phy->write_reg_mdi = txgbe_write_phy_reg_mdi;
        phy->setup_link = txgbe_setup_phy_link;
        phy->setup_link_speed = txgbe_setup_phy_link_speed;
+       phy->get_fw_version = txgbe_get_phy_fw_version;
        phy->read_i2c_byte = txgbe_read_i2c_byte;
        phy->write_i2c_byte = txgbe_write_i2c_byte;
        phy->read_i2c_sff8472 = txgbe_read_i2c_sff8472;
@@ -2808,6 +2753,7 @@ s32 txgbe_init_ops_pf(struct txgbe_hw *hw)
        mac->acquire_swfw_sync = txgbe_acquire_swfw_sync;
        mac->release_swfw_sync = txgbe_release_swfw_sync;
        mac->reset_hw = txgbe_reset_hw;
+       mac->update_mc_addr_list = txgbe_update_mc_addr_list;
 
        mac->disable_sec_rx_path = txgbe_disable_sec_rx_path;
        mac->enable_sec_rx_path = txgbe_enable_sec_rx_path;
@@ -3006,6 +2952,9 @@ u32 txgbe_get_media_type_raptor(struct txgbe_hw *hw)
 
        DEBUGFUNC("txgbe_get_media_type_raptor");
 
+       if (hw->phy.ffe_set)
+               txgbe_bp_mode_set(hw);
+
        /* Detect if there is a copper PHY attached. */
        switch (hw->phy.type) {
        case txgbe_phy_cu_unknown:
@@ -3016,22 +2965,29 @@ u32 txgbe_get_media_type_raptor(struct txgbe_hw *hw)
                break;
        }
 
-       switch (hw->device_id) {
-       case TXGBE_DEV_ID_RAPTOR_KR_KX_KX4:
+       switch (hw->subsystem_device_id & 0xFF) {
+       case TXGBE_DEV_ID_KR_KX_KX4:
+       case TXGBE_DEV_ID_MAC_SGMII:
+       case TXGBE_DEV_ID_MAC_XAUI:
                /* Default device ID is mezzanine card KX/KX4 */
                media_type = txgbe_media_type_backplane;
                break;
-       case TXGBE_DEV_ID_RAPTOR_SFP:
-       case TXGBE_DEV_ID_WX1820_SFP:
+       case TXGBE_DEV_ID_SFP:
                media_type = txgbe_media_type_fiber;
                break;
-       case TXGBE_DEV_ID_RAPTOR_QSFP:
+       case TXGBE_DEV_ID_QSFP:
                media_type = txgbe_media_type_fiber_qsfp;
                break;
-       case TXGBE_DEV_ID_RAPTOR_XAUI:
-       case TXGBE_DEV_ID_RAPTOR_SGMII:
+       case TXGBE_DEV_ID_XAUI:
+       case TXGBE_DEV_ID_SGMII:
                media_type = txgbe_media_type_copper;
                break;
+       case TXGBE_DEV_ID_SFI_XAUI:
+               if (hw->bus.lan_id == 0)
+                       media_type = txgbe_media_type_fiber;
+               else
+                       media_type = txgbe_media_type_copper;
+               break;
        default:
                media_type = txgbe_media_type_unknown;
                break;
@@ -3311,13 +3267,11 @@ s32 txgbe_setup_mac_link(struct txgbe_hw *hw,
        u64 pma_pmd_10gs = autoc & TXGBE_AUTOC_10GS_PMA_PMD_MASK;
        u64 pma_pmd_1g = autoc & TXGBE_AUTOC_1G_PMA_PMD_MASK;
        u64 link_mode = autoc & TXGBE_AUTOC_LMS_MASK;
-       u64 current_autoc = autoc;
        u64 orig_autoc = 0;
-       u32 links_reg;
-       u32 i;
        u32 link_capabilities = TXGBE_LINK_SPEED_UNKNOWN;
 
        DEBUGFUNC("txgbe_setup_mac_link");
+       UNREFERENCED_PARAMETER(autoneg_wait_to_complete);
 
        /* Check to see if speed passed in is supported. */
        status = hw->mac.get_link_capabilities(hw,
@@ -3348,8 +3302,7 @@ s32 txgbe_setup_mac_link(struct txgbe_hw *hw,
                if (speed & TXGBE_LINK_SPEED_10GB_FULL) {
                        if (orig_autoc & TXGBE_AUTOC_KX4_SUPP)
                                autoc |= TXGBE_AUTOC_KX4_SUPP;
-                       if ((orig_autoc & TXGBE_AUTOC_KR_SUPP) &&
-                           !hw->phy.smart_speed_active)
+                       if (orig_autoc & TXGBE_AUTOC_KR_SUPP)
                                autoc |= TXGBE_AUTOC_KR_SUPP;
                }
                if (speed & TXGBE_LINK_SPEED_1GB_FULL)
@@ -3376,35 +3329,14 @@ s32 txgbe_setup_mac_link(struct txgbe_hw *hw,
                }
        }
 
-       if (autoc == current_autoc)
-               return status;
-
        autoc &= ~TXGBE_AUTOC_SPEED_MASK;
        autoc |= TXGBE_AUTOC_SPEED(speed);
+       autoc &= ~TXGBE_AUTOC_AUTONEG;
        autoc |= (autoneg ? TXGBE_AUTOC_AUTONEG : 0);
 
        /* Restart link */
        hw->mac.autoc_write(hw, autoc);
 
-       /* Only poll for autoneg to complete if specified to do so */
-       if (autoneg_wait_to_complete) {
-               if (link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR ||
-                   link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
-                   link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
-                       links_reg = 0; /*Just in case Autoneg time=0*/
-                       for (i = 0; i < TXGBE_AUTO_NEG_TIME; i++) {
-                               links_reg = rd32(hw, TXGBE_PORTSTAT);
-                               if (links_reg & TXGBE_PORTSTAT_UP)
-                                       break;
-                               msec_delay(100);
-                       }
-                       if (!(links_reg & TXGBE_PORTSTAT_UP)) {
-                               status = TXGBE_ERR_AUTONEG_NOT_COMPLETE;
-                               DEBUGOUT("Autoneg did not complete.\n");
-                       }
-               }
-       }
-
        /* Add delay to filter out noises during initial link setup */
        msec_delay(50);
 
@@ -3517,6 +3449,7 @@ txgbe_reset_misc(struct txgbe_hw *hw)
        /* enable mac transmitter */
        wr32m(hw, TXGBE_MACTXCFG, TXGBE_MACTXCFG_TXE, TXGBE_MACTXCFG_TXE);
 
+       hw->mac.autoc = hw->mac.orig_autoc;
        for (i = 0; i < 4; i++)
                wr32m(hw, TXGBE_IVAR(i), 0x80808080, 0);
 }
@@ -3610,12 +3543,19 @@ mac_reset_top:
         */
        if (!hw->mac.orig_link_settings_stored) {
                hw->mac.orig_autoc = hw->mac.autoc_read(hw);
-               hw->mac.autoc_write(hw, hw->mac.orig_autoc);
                hw->mac.orig_link_settings_stored = true;
        } else {
                hw->mac.orig_autoc = autoc;
        }
 
+       if (hw->phy.ffe_set) {
+               /* Make sure phy power is up */
+               msec_delay(50);
+
+               /* A temporary solution to set phy */
+               txgbe_set_phy_temp(hw);
+       }
+
        /* Store the permanent mac address */
        hw->mac.get_mac_addr(hw, hw->mac.perm_addr);