diff options
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c')
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c | 130 |
1 files changed, 86 insertions, 44 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c index d74116441d1c..c2f8189a0738 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c @@ -774,7 +774,7 @@ static void ixgbe_parse_vf_func_caps(struct ixgbe_hw *hw, * from parsing capabilities and use this to calculate the number of resources * per PF based on the max value passed in. * - * Return: the number of resources per PF or 0, if no PH are available. + * Return: the number of resources per PF or 0, if no PFs are available. */ static u32 ixgbe_get_num_per_func(struct ixgbe_hw *hw, u32 max) { @@ -1953,6 +1953,16 @@ int ixgbe_identify_phy_e610(struct ixgbe_hw *hw) phy_type_low & IXGBE_PHY_TYPE_LOW_1G_SGMII || phy_type_high & IXGBE_PHY_TYPE_HIGH_1G_USXGMII) hw->phy.speeds_supported |= IXGBE_LINK_SPEED_1GB_FULL; + if (phy_type_low & IXGBE_PHY_TYPE_LOW_2500BASE_T || + phy_type_low & IXGBE_PHY_TYPE_LOW_2500BASE_X || + phy_type_low & IXGBE_PHY_TYPE_LOW_2500BASE_KX || + phy_type_high & IXGBE_PHY_TYPE_HIGH_2500M_SGMII || + phy_type_high & IXGBE_PHY_TYPE_HIGH_2500M_USXGMII) + hw->phy.speeds_supported |= IXGBE_LINK_SPEED_2_5GB_FULL; + if (phy_type_low & IXGBE_PHY_TYPE_LOW_5GBASE_T || + phy_type_low & IXGBE_PHY_TYPE_LOW_5GBASE_KR || + phy_type_high & IXGBE_PHY_TYPE_HIGH_5G_USXGMII) + hw->phy.speeds_supported |= IXGBE_LINK_SPEED_5GB_FULL; if (phy_type_low & IXGBE_PHY_TYPE_LOW_10GBASE_T || phy_type_low & IXGBE_PHY_TYPE_LOW_10G_SFI_DA || phy_type_low & IXGBE_PHY_TYPE_LOW_10GBASE_SR || @@ -1963,31 +1973,10 @@ int ixgbe_identify_phy_e610(struct ixgbe_hw *hw) phy_type_high & IXGBE_PHY_TYPE_HIGH_10G_USXGMII) hw->phy.speeds_supported |= IXGBE_LINK_SPEED_10GB_FULL; - /* 2.5 and 5 Gbps link speeds must be excluded from the - * auto-negotiation set used during driver initialization due to - * compatibility issues with certain switches. Those issues do not - * exist in case of E610 2.5G SKU device (0x57b1). - */ - if (!hw->phy.autoneg_advertised && - hw->device_id != IXGBE_DEV_ID_E610_2_5G_T) - hw->phy.autoneg_advertised = hw->phy.speeds_supported; - - if (phy_type_low & IXGBE_PHY_TYPE_LOW_2500BASE_T || - phy_type_low & IXGBE_PHY_TYPE_LOW_2500BASE_X || - phy_type_low & IXGBE_PHY_TYPE_LOW_2500BASE_KX || - phy_type_high & IXGBE_PHY_TYPE_HIGH_2500M_SGMII || - phy_type_high & IXGBE_PHY_TYPE_HIGH_2500M_USXGMII) - hw->phy.speeds_supported |= IXGBE_LINK_SPEED_2_5GB_FULL; - - if (!hw->phy.autoneg_advertised && - hw->device_id == IXGBE_DEV_ID_E610_2_5G_T) + /* Initialize autoneg speeds */ + if (!hw->phy.autoneg_advertised) hw->phy.autoneg_advertised = hw->phy.speeds_supported; - if (phy_type_low & IXGBE_PHY_TYPE_LOW_5GBASE_T || - phy_type_low & IXGBE_PHY_TYPE_LOW_5GBASE_KR || - phy_type_high & IXGBE_PHY_TYPE_HIGH_5G_USXGMII) - hw->phy.speeds_supported |= IXGBE_LINK_SPEED_5GB_FULL; - /* Set PHY ID */ memcpy(&hw->phy.id, pcaps.phy_id_oui, sizeof(u32)); @@ -3008,50 +2997,71 @@ static int ixgbe_get_nvm_srev(struct ixgbe_hw *hw, * Searches through the Option ROM flash contents to locate the CIVD data for * the image. * - * Return: the exit code of the operation. + * Return: -ENOMEM when cannot allocate memory, -EDOM for checksum violation, + * -ENODATA when cannot find proper data, -EIO for faulty read or + * 0 on success. + * + * On success @civd stores collected data. */ static int ixgbe_get_orom_civd_data(struct ixgbe_hw *hw, enum ixgbe_bank_select bank, struct ixgbe_orom_civd_info *civd) { - struct ixgbe_orom_civd_info tmp; + u32 orom_size = hw->flash.banks.orom_size; + u8 *orom_data; u32 offset; int err; + orom_data = kzalloc(orom_size, GFP_KERNEL); + if (!orom_data) + return -ENOMEM; + + err = ixgbe_read_flash_module(hw, bank, + IXGBE_E610_SR_1ST_OROM_BANK_PTR, 0, + orom_data, orom_size); + if (err) { + err = -EIO; + goto cleanup; + } + /* The CIVD section is located in the Option ROM aligned to 512 bytes. * The first 4 bytes must contain the ASCII characters "$CIV". * A simple modulo 256 sum of all of the bytes of the structure must * equal 0. */ - for (offset = 0; (offset + SZ_512) <= hw->flash.banks.orom_size; - offset += SZ_512) { + for (offset = 0; offset + SZ_512 <= orom_size; offset += SZ_512) { + struct ixgbe_orom_civd_info *tmp; u8 sum = 0; u32 i; - err = ixgbe_read_flash_module(hw, bank, - IXGBE_E610_SR_1ST_OROM_BANK_PTR, - offset, - (u8 *)&tmp, sizeof(tmp)); - if (err) - return err; + BUILD_BUG_ON(sizeof(*tmp) > SZ_512); + + tmp = (struct ixgbe_orom_civd_info *)&orom_data[offset]; /* Skip forward until we find a matching signature */ - if (memcmp(IXGBE_OROM_CIV_SIGNATURE, tmp.signature, - sizeof(tmp.signature))) + if (memcmp(IXGBE_OROM_CIV_SIGNATURE, tmp->signature, + sizeof(tmp->signature))) continue; /* Verify that the simple checksum is zero */ - for (i = 0; i < sizeof(tmp); i++) - sum += ((u8 *)&tmp)[i]; + for (i = 0; i < sizeof(*tmp); i++) + sum += ((u8 *)tmp)[i]; + + if (sum) { + err = -EDOM; + goto cleanup; + } - if (sum) - return -EDOM; + *civd = *tmp; + err = 0; - *civd = tmp; - return 0; + goto cleanup; } - return -ENODATA; + err = -ENODATA; +cleanup: + kfree(orom_data); + return err; } /** @@ -3125,7 +3135,7 @@ static int ixgbe_get_orom_ver_info(struct ixgbe_hw *hw, if (err) return err; - combo_ver = le32_to_cpu(civd.combo_ver); + combo_ver = get_unaligned_le32(&civd.combo_ver); orom->major = (u8)FIELD_GET(IXGBE_OROM_VER_MASK, combo_ver); orom->patch = (u8)FIELD_GET(IXGBE_OROM_VER_PATCH_MASK, combo_ver); @@ -3911,6 +3921,38 @@ static int ixgbe_read_pba_string_e610(struct ixgbe_hw *hw, u8 *pba_num, return err; } +static int __fwlog_send_cmd(void *priv, struct libie_aq_desc *desc, void *buf, + u16 size) +{ + struct ixgbe_hw *hw = priv; + + return ixgbe_aci_send_cmd(hw, desc, buf, size); +} + +int ixgbe_fwlog_init(struct ixgbe_hw *hw) +{ + struct ixgbe_adapter *adapter = hw->back; + struct libie_fwlog_api api = { + .pdev = adapter->pdev, + .send_cmd = __fwlog_send_cmd, + .debugfs_root = adapter->ixgbe_dbg_adapter, + .priv = hw, + }; + + if (hw->mac.type != ixgbe_mac_e610) + return -EOPNOTSUPP; + + return libie_fwlog_init(&hw->fwlog, &api); +} + +void ixgbe_fwlog_deinit(struct ixgbe_hw *hw) +{ + if (hw->mac.type != ixgbe_mac_e610) + return; + + libie_fwlog_deinit(&hw->fwlog); +} + static const struct ixgbe_mac_operations mac_ops_e610 = { .init_hw = ixgbe_init_hw_generic, .start_hw = ixgbe_start_hw_e610, |