From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ouyang Changchun Subject: =?utf-8?q?=5BPATCH_17/18=5D_ixgbe=3A_Support_X550_in_I?= =?utf-8?q?XGBE_base_code?= Date: Thu, 25 Sep 2014 22:19:03 +0800 Message-ID: <1411654744-9460-18-git-send-email-changchun.ouyang@intel.com> References: <1411654744-9460-1-git-send-email-changchun.ouyang@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable To: dev-VfR2kkLFssw@public.gmane.org Return-path: In-Reply-To: <1411654744-9460-1-git-send-email-changchun.ouyang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces-VfR2kkLFssw@public.gmane.org Sender: "dev" This patch adds new file to support controller X550, therefore update the= Makefile and README file. It also updates the API functions, DCB related functions, mailbox related= functions etc to support X550. In addition, some new MACROs used by X550 are added. Signed-off-by: Changchun Ouyang --- lib/librte_pmd_ixgbe/Makefile | 2 + lib/librte_pmd_ixgbe/ixgbe/README | 3 +- lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.c | 9 + lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.c | 25 + lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.h | 2 + lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.c | 12 +- lib/librte_pmd_ixgbe/ixgbe/ixgbe_dcb.c | 20 + lib/librte_pmd_ixgbe/ixgbe/ixgbe_mbx.c | 4 + lib/librte_pmd_ixgbe/ixgbe/ixgbe_osdep.h | 2 + lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.c | 1 + lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.h | 5 + lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h | 267 ++++- lib/librte_pmd_ixgbe/ixgbe/ixgbe_vf.h | 3 + lib/librte_pmd_ixgbe/ixgbe/ixgbe_x550.c | 1809 +++++++++++++++++++++++= ++++++ lib/librte_pmd_ixgbe/ixgbe/ixgbe_x550.h | 88 ++ 15 files changed, 2246 insertions(+), 6 deletions(-) create mode 100644 lib/librte_pmd_ixgbe/ixgbe/ixgbe_x550.c create mode 100644 lib/librte_pmd_ixgbe/ixgbe/ixgbe_x550.h diff --git a/lib/librte_pmd_ixgbe/Makefile b/lib/librte_pmd_ixgbe/Makefil= e index 00ccedb..0b647bd 100644 --- a/lib/librte_pmd_ixgbe/Makefile +++ b/lib/librte_pmd_ixgbe/Makefile @@ -64,6 +64,7 @@ CFLAGS_BASE_DRIVER +=3D -Wno-strict-aliasing -Wno-forma= t-extra-args =20 ifeq ($(shell test $(GCC_MAJOR_VERSION) -ge 4 -a $(GCC_MINOR_VERSION) -g= e 6 && echo 1), 1) CFLAGS_ixgbe_common.o +=3D -Wno-unused-but-set-variable +CFLAGS_ixgbe_x550.o +=3D -Wno-unused-but-set-variable -Wno-maybe-uniniti= alized endif endif =20 @@ -83,6 +84,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) +=3D ixgbe_common.c SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) +=3D ixgbe_82598.c SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) +=3D ixgbe_82599.c SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) +=3D ixgbe_x540.c +SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) +=3D ixgbe_x550.c SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) +=3D ixgbe_phy.c SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) +=3D ixgbe_api.c SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) +=3D ixgbe_vf.c diff --git a/lib/librte_pmd_ixgbe/ixgbe/README b/lib/librte_pmd_ixgbe/ixg= be/README index fc71e85..e0e5f0d 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/README +++ b/lib/librte_pmd_ixgbe/ixgbe/README @@ -34,7 +34,7 @@ Intel=C2=AE IXGBE driver =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 This directory contains source code of FreeBSD ixgbe driver of version -cid-10g-shared-code.2014.03.13 released by LAD. The sub-directory of lad= / +cid-10g-shared-code.2014.09.04 released by LAD. The sub-directory of lad= / contains the original source package. This driver is valid for the product(s) listed below =20 @@ -50,6 +50,7 @@ This driver is valid for the product(s) listed below * Intel=C2=AE Ethernet Controller X540-AT2 * Intel=C2=AE Ethernet Server Adapter X520 Series * Intel=C2=AE Ethernet Server Adapter X520-T2 +* Intel=C2=AE Ethernet Controller X550-BT2 =20 Updating driver =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.c b/lib/librte_pmd_ix= gbe/ixgbe/ixgbe_82599.c index 2b74374..a06b57c 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.c +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.c @@ -1918,6 +1918,15 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_h= w *hw, /* write both the same so that UDP and TCP use the same mask */ IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, ~fdirtcpm); IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, ~fdirtcpm); + /* also use it for SCTP */ + switch (hw->mac.type) { + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + IXGBE_WRITE_REG(hw, IXGBE_FDIRSCTPM, ~fdirtcpm); + break; + default: + break; + } =20 /* store source and destination IP masks (big-endian) */ IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIP4M, diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.c b/lib/librte_pmd_ixgb= e/ixgbe/ixgbe_api.c index b3e89c5..1802760 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.c +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.c @@ -81,8 +81,16 @@ s32 ixgbe_init_shared_code(struct ixgbe_hw *hw) case ixgbe_mac_X540: status =3D ixgbe_init_ops_X540(hw); break; + case ixgbe_mac_X550: + status =3D ixgbe_init_ops_X550(hw); + break; + case ixgbe_mac_X550EM_x: + status =3D ixgbe_init_ops_X550EM(hw); + break; case ixgbe_mac_82599_vf: case ixgbe_mac_X540_vf: + case ixgbe_mac_X550_vf: + case ixgbe_mac_X550EM_x_vf: status =3D ixgbe_init_ops_vf(hw); break; default: @@ -157,6 +165,23 @@ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw) case IXGBE_DEV_ID_X540T1: hw->mac.type =3D ixgbe_mac_X540; break; + case IXGBE_DEV_ID_X550T: + hw->mac.type =3D ixgbe_mac_X550; + break; + case IXGBE_DEV_ID_X550EM_X: + case IXGBE_DEV_ID_X550EM_X_KX4: + case IXGBE_DEV_ID_X550EM_X_KR: + case IXGBE_DEV_ID_X550EM_X_SFP: + hw->mac.type =3D ixgbe_mac_X550EM_x; + break; + case IXGBE_DEV_ID_X550_VF: + case IXGBE_DEV_ID_X550_VF_HV: + hw->mac.type =3D ixgbe_mac_X550_vf; + break; + case IXGBE_DEV_ID_X550EM_X_VF: + case IXGBE_DEV_ID_X550EM_X_VF_HV: + hw->mac.type =3D ixgbe_mac_X550EM_x_vf; + break; default: ret_val =3D IXGBE_ERR_DEVICE_NOT_SUPPORTED; ERROR_REPORT2(IXGBE_ERROR_UNSUPPORTED, diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.h b/lib/librte_pmd_ixgb= e/ixgbe/ixgbe_api.h index c63664a..1c12ff6 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.h +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.h @@ -44,6 +44,8 @@ s32 ixgbe_init_shared_code(struct ixgbe_hw *hw); extern s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw); extern s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw); extern s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw); +extern s32 ixgbe_init_ops_X550(struct ixgbe_hw *hw); +extern s32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw); extern s32 ixgbe_init_ops_vf(struct ixgbe_hw *hw); =20 s32 ixgbe_set_mac_type(struct ixgbe_hw *hw); diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.c b/lib/librte_pmd_i= xgbe/ixgbe/ixgbe_common.c index a799b40..37e5bae 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.c +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.c @@ -184,6 +184,7 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw= *hw) case IXGBE_DEV_ID_82599_T3_LOM: case IXGBE_DEV_ID_X540T: case IXGBE_DEV_ID_X540T1: + case IXGBE_DEV_ID_X550T: supported =3D true; break; default: @@ -563,7 +564,7 @@ s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw) } } =20 - if (hw->mac.type =3D=3D ixgbe_mac_X540) { + if (hw->mac.type =3D=3D ixgbe_mac_X550 || hw->mac.type =3D=3D ixgbe_mac= _X540) { if (hw->phy.id =3D=3D 0) ixgbe_identify_phy(hw); hw->phy.ops.read_reg(hw, IXGBE_PCRC8ECL, @@ -3567,6 +3568,8 @@ u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_= hw *hw) break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: pcie_offset =3D IXGBE_PCIE_MSIX_82599_CAPS; max_msix_count =3D IXGBE_MAX_MSIX_VECTORS_82599; break; @@ -4080,8 +4083,13 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *= hw, ixgbe_link_speed *speed, } =20 if ((links_reg & IXGBE_LINKS_SPEED_82599) =3D=3D - IXGBE_LINKS_SPEED_10G_82599) + IXGBE_LINKS_SPEED_10G_82599) { *speed =3D IXGBE_LINK_SPEED_10GB_FULL; + if (hw->mac.type > ixgbe_mac_X550) { + if (links_reg & IXGBE_LINKS_SPEED_NON_STD) + *speed =3D IXGBE_LINK_SPEED_2_5GB_FULL; + } + } else if ((links_reg & IXGBE_LINKS_SPEED_82599) =3D=3D IXGBE_LINKS_SPEED_1G_82599) *speed =3D IXGBE_LINK_SPEED_1GB_FULL; diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_dcb.c b/lib/librte_pmd_ixgb= e/ixgbe/ixgbe_dcb.c index 1c2459b..2245f27 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_dcb.c +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_dcb.c @@ -394,6 +394,8 @@ s32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *hw, struc= t ixgbe_hw_stats *stats, break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: ret =3D ixgbe_dcb_get_tc_stats_82599(hw, stats, tc_count); break; default: @@ -420,6 +422,8 @@ s32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *hw, stru= ct ixgbe_hw_stats *stats, break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: ret =3D ixgbe_dcb_get_pfc_stats_82599(hw, stats, tc_count); break; default: @@ -457,6 +461,8 @@ s32 ixgbe_dcb_config_rx_arbiter_cee(struct ixgbe_hw *= hw, break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: ret =3D ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwgid, tsa, map); break; @@ -494,6 +500,8 @@ s32 ixgbe_dcb_config_tx_desc_arbiter_cee(struct ixgbe= _hw *hw, break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: ret =3D ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, bwgid, tsa); break; @@ -533,6 +541,8 @@ s32 ixgbe_dcb_config_tx_data_arbiter_cee(struct ixgbe= _hw *hw, break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: ret =3D ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwgid, tsa, map); @@ -566,6 +576,8 @@ s32 ixgbe_dcb_config_pfc_cee(struct ixgbe_hw *hw, break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: ret =3D ixgbe_dcb_config_pfc_82599(hw, pfc_en, map); break; default: @@ -590,6 +602,8 @@ s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *hw) break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: ret =3D ixgbe_dcb_config_tc_stats_82599(hw, NULL); break; default: @@ -630,6 +644,8 @@ s32 ixgbe_dcb_hw_config_cee(struct ixgbe_hw *hw, break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: ixgbe_dcb_config_82599(hw, dcb_config); ret =3D ixgbe_dcb_hw_config_82599(hw, dcb_config->link_speed, refill, max, bwgid, @@ -660,6 +676,8 @@ s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *hw, u8 pfc_= en, u8 *map) break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: ret =3D ixgbe_dcb_config_pfc_82599(hw, pfc_en, map); break; default: @@ -681,6 +699,8 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, u16 *ref= ill, u16 *max, break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id, tsa, map); ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, bwg_id, diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_mbx.c b/lib/librte_pmd_ixgb= e/ixgbe/ixgbe_mbx.c index 9389861..c00c2f7 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_mbx.c +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_mbx.c @@ -615,6 +615,8 @@ STATIC s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw= , u16 vf_number) case ixgbe_mac_82599EB: vflre =3D IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset)); break; + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: case ixgbe_mac_X540: vflre =3D IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset)); break; @@ -761,6 +763,8 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw) struct ixgbe_mbx_info *mbx =3D &hw->mbx; =20 if (hw->mac.type !=3D ixgbe_mac_82599EB && + hw->mac.type !=3D ixgbe_mac_X550 && + hw->mac.type !=3D ixgbe_mac_X550EM_x && hw->mac.type !=3D ixgbe_mac_X540) return; =20 diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_osdep.h b/lib/librte_pmd_ix= gbe/ixgbe/ixgbe_osdep.h index ba25972..2a7f10a 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_osdep.h +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_osdep.h @@ -97,6 +97,8 @@ enum { #define IXGBE_NTOHS(_i) rte_be_to_cpu_16(_i) #define IXGBE_CPU_TO_LE32(_i) rte_cpu_to_le_32(_i) #define IXGBE_LE32_TO_CPUS(_i) rte_le_to_cpu_32(_i) +#define IXGBE_CPU_TO_BE16(_i) rte_cpu_to_be_16(_i) +#define IXGBE_CPU_TO_BE32(_i) rte_cpu_to_be_32(_i) =20 typedef uint8_t u8; typedef int8_t s8; diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.c b/lib/librte_pmd_ixgb= e/ixgbe/ixgbe_phy.c index e1e560b..2305448 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.c +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.c @@ -428,6 +428,7 @@ enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 ph= y_id) case TN1010_PHY_ID: phy_type =3D ixgbe_phy_tn; break; + case X550_PHY_ID: case X540_PHY_ID: phy_type =3D ixgbe_phy_aq; break; diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.h b/lib/librte_pmd_ixgb= e/ixgbe/ixgbe_phy.h index c47812b..e262cc4 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.h +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.h @@ -82,6 +82,11 @@ POSSIBILITY OF SUCH DAMAGE. #define IXGBE_I2C_EEPROM_STATUS_FAIL 0x2 #define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS 0x3 =20 +#define IXGBE_CS4227 0x9E /* CS4227 address */ +#define IXGBE_CS4227_SPARE24_LSB 0x12B0 /* Reg to program EDC */ +#define IXGBE_CS4227_EDC_MODE_CX1 0x0002 +#define IXGBE_CS4227_EDC_MODE_SR 0x0004 + /* Flow control defines */ #define IXGBE_TAF_SYM_PAUSE 0x400 #define IXGBE_TAF_ASM_PAUSE 0x800 diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h b/lib/librte_pmd_ixg= be/ixgbe/ixgbe_type.h index 40ebed9..c67d462 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h @@ -126,6 +126,15 @@ POSSIBILITY OF SUCH DAMAGE. #define IXGBE_DEV_ID_X540_VF 0x1515 #define IXGBE_DEV_ID_X540_VF_HV 0x1530 #define IXGBE_DEV_ID_X540T1 0x1560 +#define IXGBE_DEV_ID_X550EM_X 0x15A7 +#define IXGBE_DEV_ID_X550EM_X_SFP 0x15AC +#define IXGBE_DEV_ID_X550T 0x1563 +#define IXGBE_DEV_ID_X550EM_X_KX4 0x15AA +#define IXGBE_DEV_ID_X550EM_X_KR 0x15AB +#define IXGBE_DEV_ID_X550_VF_HV 0x1564 +#define IXGBE_DEV_ID_X550_VF 0x1565 +#define IXGBE_DEV_ID_X550EM_X_VF 0x15A8 +#define IXGBE_DEV_ID_X550EM_X_VF_HV 0x15A9 =20 /* General Registers */ #define IXGBE_CTRL 0x00000 @@ -333,6 +342,8 @@ struct ixgbe_thermal_sensor_data { #define IXGBE_VLVF(_i) (0x0F100 + ((_i) * 4)) /* 64 of these (0-63) */ #define IXGBE_VLVFB(_i) (0x0F200 + ((_i) * 4)) /* 128 of these (0-127) = */ #define IXGBE_VMVIR(_i) (0x08000 + ((_i) * 4)) /* 64 of these (0-63) */ +#define IXGBE_PFFLPL 0x050B0 +#define IXGBE_PFFLPH 0x050B4 #define IXGBE_VT_CTL 0x051B0 #define IXGBE_PFMAILBOX(_i) (0x04B00 + (4 * (_i))) /* 64 total */ /* 64 Mailboxes, 16 DW each */ @@ -349,6 +360,12 @@ struct ixgbe_thermal_sensor_data { #define IXGBE_MRCTL(_i) (0x0F600 + ((_i) * 4)) #define IXGBE_VMRVLAN(_i) (0x0F610 + ((_i) * 4)) #define IXGBE_VMRVM(_i) (0x0F630 + ((_i) * 4)) +#define IXGBE_LVMMC_RX 0x2FA8 +#define IXGBE_LVMMC_TX 0x8108 +#define IXGBE_LMVM_RX 0x2FA4 +#define IXGBE_LMVM_TX 0x8124 +#define IXGBE_WQBR_RX(_i) (0x2FB0 + ((_i) * 4)) /* 4 total */ +#define IXGBE_WQBR_TX(_i) (0x8130 + ((_i) * 4)) /* 4 total */ #define IXGBE_L34T_IMIR(_i) (0x0E800 + ((_i) * 4)) /*128 of these (0-127= )*/ #define IXGBE_RXFECCERR0 0x051B8 #define IXGBE_LLITHRESH 0x0EC90 @@ -357,8 +374,16 @@ struct ixgbe_thermal_sensor_data { #define IXGBE_IMIRVP 0x05AC0 #define IXGBE_VMD_CTL 0x0581C #define IXGBE_RETA(_i) (0x05C00 + ((_i) * 4)) /* 32 of these (0-31) */ +#define IXGBE_ERETA(_i) (0x0EE80 + ((_i) * 4)) /* 96 of these (0-95) *= / #define IXGBE_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* 10 of these (0-9) */ =20 +/* Registers for setting up RSS on X550 with SRIOV + * _p - pool number (0..63) + * _i - index (0..10 for PFVFRSSRK, 0..15 for PFVFRETA) + */ +#define IXGBE_PFVFMRQC(_p) (0x03400 + ((_p) * 4)) +#define IXGBE_PFVFRSSRK(_i, _p) (0x018000 + ((_i) * 4) + ((_p) * 0x40)) +#define IXGBE_PFVFRETA(_i, _p) (0x019000 + ((_i) * 4) + ((_p) * 0x40)) =20 /* Flow Director registers */ #define IXGBE_FDIRCTRL 0x0EE00 @@ -412,6 +437,8 @@ struct ixgbe_thermal_sensor_data { #define IXGBE_DMATXCTL_TE 0x1 /* Transmit Enable */ #define IXGBE_DMATXCTL_NS 0x2 /* No Snoop LSO hdr buffer */ #define IXGBE_DMATXCTL_GDV 0x8 /* Global Double VLAN */ +#define IXGBE_DMATXCTL_MDP_EN 0x20 /* Bit 5 */ +#define IXGBE_DMATXCTL_MBINTEN 0x40 /* Bit 6 */ #define IXGBE_DMATXCTL_VT_SHIFT 16 /* VLAN EtherType */ =20 #define IXGBE_PFDTXGSWC_VT_LBEN 0x1 /* Local L2 VT switch enable */ @@ -443,16 +470,22 @@ struct ixgbe_thermal_sensor_data { =20 #define IXGBE_WUPL 0x05900 #define IXGBE_WUPM 0x05A00 /* wake up pkt memory 0x5A00-0x5A7C */ +#define IXGBE_PROXYS 0x05F60 /* Proxying Status Register */ +#define IXGBE_PROXYFC 0x05F64 /* Proxying Filter Control Register */ +#define IXGBE_VXLANCTRL 0x0000507C /* Rx filter VXLAN UDPPORT Register *= / =20 -#define IXGBE_FHFT(_n) (0x09000 + (_n * 0x100)) /* Flex host filter tabl= e */ +#define IXGBE_FHFT(_n) (0x09000 + ((_n) * 0x100)) /* Flex host filter ta= ble */ /* Ext Flexible Host Filter Table */ -#define IXGBE_FHFT_EXT(_n) (0x09800 + (_n * 0x100)) +#define IXGBE_FHFT_EXT(_n) (0x09800 + ((_n) * 0x100)) +#define IXGBE_FHFT_EXT_X550(_n) (0x09600 + ((_n) * 0x100)) =20 /* Four Flexible Filters are supported */ #define IXGBE_FLEXIBLE_FILTER_COUNT_MAX 4 =20 /* Six Flexible Filters are supported */ #define IXGBE_FLEXIBLE_FILTER_COUNT_MAX_6 6 +/* Eight Flexible Filters are supported */ +#define IXGBE_FLEXIBLE_FILTER_COUNT_MAX_8 8 #define IXGBE_EXT_FLEXIBLE_FILTER_COUNT_MAX 2 =20 /* Each Flexible Filter is at most 128 (0x80) bytes in length */ @@ -485,10 +518,14 @@ struct ixgbe_thermal_sensor_data { #define IXGBE_WUFC_FLX4 0x00100000 /* Flexible Filter 4 Enable */ #define IXGBE_WUFC_FLX5 0x00200000 /* Flexible Filter 5 Enable */ #define IXGBE_WUFC_FLX_FILTERS 0x000F0000 /* Mask for 4 flex filters */ +#define IXGBE_WUFC_FLX_FILTERS_6 0x003F0000 /* Mask for 6 flex filters *= / +#define IXGBE_WUFC_FLX_FILTERS_8 0x00FF0000 /* Mask for 8 flex filters *= / +#define IXGBE_WUFC_FW_RST_WK 0x80000000 /* Ena wake on FW reset assertio= n */ /* Mask for Ext. flex filters */ #define IXGBE_WUFC_EXT_FLX_FILTERS 0x00300000 #define IXGBE_WUFC_ALL_FILTERS 0x000F00FF /* Mask all 4 flex filters */ #define IXGBE_WUFC_ALL_FILTERS_6 0x003F00FF /* Mask all 6 flex filters *= / +#define IXGBE_WUFC_ALL_FILTERS_8 0x00FF00FF /* Mask all 8 flex filters *= / #define IXGBE_WUFC_FLX_OFFSET 16 /* Offset to the Flexible Filters bits = */ =20 /* Wake Up Status */ @@ -508,6 +545,23 @@ struct ixgbe_thermal_sensor_data { #define IXGBE_WUS_FLX4 IXGBE_WUFC_FLX4 #define IXGBE_WUS_FLX5 IXGBE_WUFC_FLX5 #define IXGBE_WUS_FLX_FILTERS IXGBE_WUFC_FLX_FILTERS +#define IXGBE_WUS_FW_RST_WK IXGBE_WUFC_FW_RST_WK +/* Proxy Status */ +#define IXGBE_PROXYS_EX 0x00000004 /* Exact packet received */ +#define IXGBE_PROXYS_ARP_DIR 0x00000020 /* ARP w/filter match received *= / +#define IXGBE_PROXYS_NS 0x00000200 /* IPV6 NS received */ +#define IXGBE_PROXYS_NS_DIR 0x00000400 /* IPV6 NS w/DA match received */ +#define IXGBE_PROXYS_ARP 0x00000800 /* ARP request packet received */ +#define IXGBE_PROXYS_MLD 0x00001000 /* IPv6 MLD packet received */ + +/* Proxying Filter Control */ +#define IXGBE_PROXYFC_ENABLE 0x00000001 /* Port Proxying Enable */ +#define IXGBE_PROXYFC_EX 0x00000004 /* Directed Exact Proxy Enable */ +#define IXGBE_PROXYFC_ARP_DIR 0x00000020 /* Directed ARP Proxy Enable */ +#define IXGBE_PROXYFC_NS 0x00000200 /* IPv6 Neighbor Solicitation */ +#define IXGBE_PROXYFC_ARP 0x00000800 /* ARP Request Proxy Enable */ +#define IXGBE_PROXYFC_MLD 0x00000800 /* IPv6 MLD Proxy Enable */ +#define IXGBE_PROXYFC_NO_TCO 0x00008000 /* Ignore TCO packets */ =20 #define IXGBE_WUPL_LENGTH_MASK 0xFFFF =20 @@ -715,6 +769,8 @@ struct ixgbe_dmac_config { =20 =20 /* FCoE DMA Context Registers */ +/* FCoE Direct DMA Context */ +#define IXGBE_FCDDC(_i, _j) (0x20000 + ((_i) * 0x4) + ((_j) * 0x10)) #define IXGBE_FCPTRL 0x02410 /* FC User Desc. PTR Low */ #define IXGBE_FCPTRH 0x02414 /* FC USer Desc. PTR High */ #define IXGBE_FCBUFF 0x02418 /* FC Buffer Control */ @@ -738,6 +794,12 @@ struct ixgbe_dmac_config { #define IXGBE_REOFF 0x05158 /* Rx FC EOF */ #define IXGBE_RSOFF 0x051F8 /* Rx FC SOF */ /* FCoE Filter Context Registers */ +#define IXGBE_FCD_ID 0x05114 /* FCoE D_ID */ +#define IXGBE_FCSMAC 0x0510C /* FCoE Source MAC */ +#define IXGBE_FCFLTRW_SMAC_HIGH_SHIFT 16 +/* FCoE Direct Filter Context */ +#define IXGBE_FCDFC(_i, _j) (0x28000 + ((_i) * 0x4) + ((_j) * 0x10)) +#define IXGBE_FCDFCD(_i) (0x30000 + ((_i) * 0x4)) #define IXGBE_FCFLT 0x05108 /* FC FLT Context */ #define IXGBE_FCFLTRW 0x05110 /* FC Filter RW Control */ #define IXGBE_FCPARAM 0x051d8 /* FC Offset Parameter */ @@ -768,6 +830,10 @@ struct ixgbe_dmac_config { #define IXGBE_FCRETASEL_ENA 0x2 /* FCoE FCRETASEL bit */ #define IXGBE_FCRETA_SIZE 8 /* Max entries in FCRETA */ #define IXGBE_FCRETA_ENTRY_MASK 0x0000007f /* 7 bits for the queue index= */ +#define IXGBE_FCRETA_SIZE_X550 32 /* Max entries in FCRETA */ +/* Higher 7 bits for the queue index */ +#define IXGBE_FCRETA_ENTRY_HIGH_MASK 0x007F0000 +#define IXGBE_FCRETA_ENTRY_HIGH_SHIFT 16 =20 /* Stats registers */ #define IXGBE_CRCERRS 0x04000 @@ -887,6 +953,7 @@ struct ixgbe_dmac_config { #define IXGBE_BMCIP_IPADDR_VALID 0x00000002 =20 /* Management Bit Fields and Masks */ +#define IXGBE_MANC_MPROXYE 0x40000000 /* Management Proxy Enable */ #define IXGBE_MANC_RCV_TCO_EN 0x00020000 /* Rcv TCO packet enable */ #define IXGBE_MANC_EN_BMC2OS 0x10000000 /* Ena BMC2OS and OS2BMC traffic= */ #define IXGBE_MANC_EN_BMC2OS_SHIFT 28 @@ -949,6 +1016,12 @@ struct ixgbe_dmac_config { #define IXGBE_PBACLR_82599 0x11068 #define IXGBE_CIAA_82599 0x11088 #define IXGBE_CIAD_82599 0x1108C +#define IXGBE_CIAA_X550 0x11508 +#define IXGBE_CIAD_X550 0x11510 +#define IXGBE_CIAA_BY_MAC(_hw) ((((_hw)->mac.type >=3D ixgbe_mac_X550) ?= \ + IXGBE_CIAA_X550 : IXGBE_CIAA_82599)) +#define IXGBE_CIAD_BY_MAC(_hw) ((((_hw)->mac.type >=3D ixgbe_mac_X550) ?= \ + IXGBE_CIAD_X550 : IXGBE_CIAD_82599)) #define IXGBE_PICAUSE 0x110B0 #define IXGBE_PIENA 0x110B8 #define IXGBE_CDQ_MBR_82599 0x110B4 @@ -985,6 +1058,7 @@ struct ixgbe_dmac_config { #define IXGBE_TXSTMPH 0x08C08 /* Tx timestamp value High - RO */ #define IXGBE_SYSTIML 0x08C0C /* System time register Low - RO */ #define IXGBE_SYSTIMH 0x08C10 /* System time register High - RO */ +#define IXGBE_SYSTIMR 0x08C58 /* System time register Residue - RO */ #define IXGBE_TIMINCA 0x08C14 /* Increment attributes register - RW */ #define IXGBE_TIMADJL 0x08C18 /* Time Adjustment Offset register Low - R= W */ #define IXGBE_TIMADJH 0x08C1C /* Time Adjustment Offset register High - = RW */ @@ -1001,6 +1075,9 @@ struct ixgbe_dmac_config { #define IXGBE_AUXSTMPH0 0x08C40 /* Auxiliary Time Stamp 0 register High = - RO */ #define IXGBE_AUXSTMPL1 0x08C44 /* Auxiliary Time Stamp 1 register Low -= RO */ #define IXGBE_AUXSTMPH1 0x08C48 /* Auxiliary Time Stamp 1 register High = - RO */ +#define IXGBE_TSIM 0x08C68 /* TimeSync Interrupt Mask Register - RW */ +#define IXGBE_TSICR 0x08C60 /* TimeSync Interrupt Cause Register - WO */ +#define IXGBE_TSSDP 0x0003C /* TimeSync SDP Configuration Register - RW = */ =20 /* Diagnostic Registers */ #define IXGBE_RDSTATCTL 0x02C20 @@ -1157,6 +1234,7 @@ struct ixgbe_dmac_config { /* RDRXCTL Bit Masks */ #define IXGBE_RDRXCTL_RDMTS_1_2 0x00000000 /* Rx Desc Min THLD Size */ #define IXGBE_RDRXCTL_CRCSTRIP 0x00000002 /* CRC Strip */ +#define IXGBE_RDRXCTL_PSP 0x00000004 /* Pad Small Packet */ #define IXGBE_RDRXCTL_MVMEN 0x00000020 #define IXGBE_RDRXCTL_RSC_PUSH_DIS 0x00000020 #define IXGBE_RDRXCTL_DMAIDONE 0x00000008 /* DMA init cycle done */ @@ -1166,6 +1244,8 @@ struct ixgbe_dmac_config { #define IXGBE_RDRXCTL_RSCLLIDIS 0x00800000 /* Disable RSC compl on LLI*= / #define IXGBE_RDRXCTL_RSCACKC 0x02000000 /* must set 1 when RSC ena */ #define IXGBE_RDRXCTL_FCOE_WRFIX 0x04000000 /* must set 1 when RSC ena *= / +#define IXGBE_RDRXCTL_MBINTEN 0x10000000 +#define IXGBE_RDRXCTL_MDP_EN 0x20000000 =20 /* RQTC Bit Masks and Shifts */ #define IXGBE_RQTC_SHIFT_TC(_i) ((_i) * 4) @@ -1344,6 +1424,7 @@ struct ixgbe_dmac_config { #define TN1010_PHY_ID 0x00A19410 #define TNX_FW_REV 0xB #define X540_PHY_ID 0x01540200 +#define X550_PHY_ID 0x01540220 #define AQ_FW_REV 0x20 #define QT2022_PHY_ID 0x0043A400 #define ATH_PHY_ID 0x03429050 @@ -1699,12 +1780,14 @@ enum { * 1588 (0x88f7): Filter 3 * FIP (0x8914): Filter 4 * LLDP (0x88CC): Filter 5 + * LACP (0x8809): Filter 6 */ #define IXGBE_ETQF_FILTER_EAPOL 0 #define IXGBE_ETQF_FILTER_FCOE 2 #define IXGBE_ETQF_FILTER_1588 3 #define IXGBE_ETQF_FILTER_FIP 4 #define IXGBE_ETQF_FILTER_LLDP 5 +#define IXGBE_ETQF_FILTER_LACP 6 /* VLAN Control Bit Masks */ #define IXGBE_VLNCTRL_VET 0x0000FFFF /* bits 0-15 */ #define IXGBE_VLNCTRL_CFI 0x10000000 /* bit 28 */ @@ -1849,6 +1932,7 @@ enum { #define IXGBE_LINKS_TL_FAULT 0x00001000 #define IXGBE_LINKS_SIGNAL 0x00000F00 =20 +#define IXGBE_LINKS_SPEED_NON_STD 0x08000000 #define IXGBE_LINKS_SPEED_82599 0x30000000 #define IXGBE_LINKS_SPEED_10G_82599 0x30000000 #define IXGBE_LINKS_SPEED_1G_82599 0x20000000 @@ -1929,6 +2013,9 @@ enum { #define IXGBE_EEPROM_WORD_SIZE_SHIFT 6 #define IXGBE_EEPROM_OPCODE_BITS 8 =20 +/* FLA Register */ +#define IXGBE_FLA_LOCKED 0x00000040 + /* Part Number String Length */ #define IXGBE_PBANUM_LENGTH 11 =20 @@ -1950,12 +2037,31 @@ enum { #define IXGBE_MAC1_PTR 0x0C #define IXGBE_CSR0_CONFIG_PTR 0x0D #define IXGBE_CSR1_CONFIG_PTR 0x0E +#define IXGBE_PCIE_ANALOG_PTR_X550 0x02 +#define IXGBE_SHADOW_RAM_SIZE_X550 0x4000 +#define IXGBE_IXGBE_PCIE_GENERAL_SIZE 0x24 +#define IXGBE_PCIE_CONFIG_SIZE 0x08 +#define IXGBE_EEPROM_LAST_WORD 0x41 #define IXGBE_FW_PTR 0x0F #define IXGBE_PBANUM0_PTR 0x15 #define IXGBE_PBANUM1_PTR 0x16 #define IXGBE_ALT_MAC_ADDR_PTR 0x37 #define IXGBE_FREE_SPACE_PTR 0X3E =20 +/* External Thermal Sensor Config */ +#define IXGBE_ETS_CFG 0x26 +#define IXGBE_ETS_LTHRES_DELTA_MASK 0x07C0 +#define IXGBE_ETS_LTHRES_DELTA_SHIFT 6 +#define IXGBE_ETS_TYPE_MASK 0x0038 +#define IXGBE_ETS_TYPE_SHIFT 3 +#define IXGBE_ETS_TYPE_EMC 0x000 +#define IXGBE_ETS_NUM_SENSORS_MASK 0x0007 +#define IXGBE_ETS_DATA_LOC_MASK 0x3C00 +#define IXGBE_ETS_DATA_LOC_SHIFT 10 +#define IXGBE_ETS_DATA_INDEX_MASK 0x0300 +#define IXGBE_ETS_DATA_INDEX_SHIFT 8 +#define IXGBE_ETS_DATA_HTHRESH_MASK 0x00FF + #define IXGBE_SAN_MAC_ADDR_PTR 0x28 #define IXGBE_DEVICE_CAPS 0x2C #define IXGBE_SERIAL_NUMBER_MAC_ADDR 0x11 @@ -2148,6 +2254,14 @@ enum { #define IXGBE_TSAUXC_EN_CLK 0x00000004 #define IXGBE_TSAUXC_SYNCLK 0x00000008 #define IXGBE_TSAUXC_SDP0_INT 0x00000040 +#define IXGBE_TSAUXC_EN_TT0 0x00000001 +#define IXGBE_TSAUXC_EN_TT1 0x00000002 +#define IXGBE_TSAUXC_ST0 0x00000010 +#define IXGBE_TSAUXC_DISABLE_SYSTIME 0x80000000 + +#define IXGBE_TSSDP_TS_SDP0_SEL_MASK 0x000000C0 +#define IXGBE_TSSDP_TS_SDP0_CLK0 0x00000080 +#define IXGBE_TSSDP_TS_SDP0_EN 0x00000100 =20 #define IXGBE_TSYNCTXCTL_VALID 0x00000001 /* Tx timestamp valid */ #define IXGBE_TSYNCTXCTL_ENABLED 0x00000010 /* Tx timestamping enabled *= / @@ -2157,8 +2271,19 @@ enum { #define IXGBE_TSYNCRXCTL_TYPE_L2_V2 0x00 #define IXGBE_TSYNCRXCTL_TYPE_L4_V1 0x02 #define IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2 0x04 +#define IXGBE_TSYNCRXCTL_TYPE_ALL 0x08 #define IXGBE_TSYNCRXCTL_TYPE_EVENT_V2 0x0A #define IXGBE_TSYNCRXCTL_ENABLED 0x00000010 /* Rx Timestamping enabled *= / +#define IXGBE_TSYNCRXCTL_TSIP_UT_EN 0x00800000 /* Rx Timestamp in Packet= */ +#define IXGBE_TSYNCRXCTL_TSIP_UP_MASK 0xFF000000 /* Rx Timestamp UP Mask= */ + +#define IXGBE_TSIM_SYS_WRAP 0x00000001 +#define IXGBE_TSIM_TXTS 0x00000002 +#define IXGBE_TSIM_TADJ 0x00000080 + +#define IXGBE_TSICR_SYS_WRAP IXGBE_TSIM_SYS_WRAP +#define IXGBE_TSICR_TXTS IXGBE_TSIM_TXTS +#define IXGBE_TSICR_TADJ IXGBE_TSIM_TADJ =20 #define IXGBE_RXMTRL_V1_CTRLT_MASK 0x000000FF #define IXGBE_RXMTRL_V1_SYNC_MSG 0x00 @@ -2217,10 +2342,12 @@ enum { #define IXGBE_MRQC_RSS_FIELD_IPV4_UDP 0x00400000 #define IXGBE_MRQC_RSS_FIELD_IPV6_UDP 0x00800000 #define IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP 0x01000000 +#define IXGBE_MRQC_MULTIPLE_RSS 0x00002000 #define IXGBE_MRQC_L3L4TXSWEN 0x00008000 =20 /* Queue Drop Enable */ #define IXGBE_QDE_ENABLE 0x00000001 +#define IXGBE_QDE_HIDE_VLAN 0x00000002 #define IXGBE_QDE_IDX_MASK 0x00007F00 #define IXGBE_QDE_IDX_SHIFT 8 #define IXGBE_QDE_WRITE 0x00010000 @@ -2262,10 +2389,12 @@ enum { #define IXGBE_RXD_STAT_IPCS 0x40 /* IP xsum calculated */ #define IXGBE_RXD_STAT_PIF 0x80 /* passed in-exact filter */ #define IXGBE_RXD_STAT_CRCV 0x100 /* Speculative CRC Valid */ +#define IXGBE_RXD_STAT_OUTERIPCS 0x100 /* Cloud IP xsum calculated */ #define IXGBE_RXD_STAT_VEXT 0x200 /* 1st VLAN found */ #define IXGBE_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */ #define IXGBE_RXD_STAT_DYNINT 0x800 /* Pkt caused INT via DYNINT */ #define IXGBE_RXD_STAT_LLINT 0x800 /* Pkt caused Low Latency Interrupt *= / +#define IXGBE_RXD_STAT_TSIP 0x08000 /* Time Stamp in packet buffer */ #define IXGBE_RXD_STAT_TS 0x10000 /* Time Stamp */ #define IXGBE_RXD_STAT_SECP 0x20000 /* Security Processing */ #define IXGBE_RXD_STAT_LB 0x40000 /* Loopback Status */ @@ -2279,6 +2408,7 @@ enum { #define IXGBE_RXD_ERR_IPE 0x80 /* IP Checksum Error */ #define IXGBE_RXDADV_ERR_MASK 0xfff00000 /* RDESC.ERRORS mask */ #define IXGBE_RXDADV_ERR_SHIFT 20 /* RDESC.ERRORS shift */ +#define IXGBE_RXDADV_ERR_OUTERIPER 0x04000000 /* CRC IP Header error */ #define IXGBE_RXDADV_ERR_RXE 0x20000000 /* Any MAC Error */ #define IXGBE_RXDADV_ERR_FCEOFE 0x80000000 /* FCoEFe/IPE */ #define IXGBE_RXDADV_ERR_FCERR 0x00700000 /* FCERR/FDIRERR */ @@ -2311,6 +2441,7 @@ enum { #define IXGBE_RXDADV_STAT_FCSTAT_FCPRSP 0x00000020 /* 10: Recv. FCP_RSP = */ #define IXGBE_RXDADV_STAT_FCSTAT_DDP 0x00000030 /* 11: Ctxt w/ DDP */ #define IXGBE_RXDADV_STAT_TS 0x00010000 /* IEEE1588 Time Stamp */ +#define IXGBE_RXDADV_STAT_TSIP 0x00008000 /* Time Stamp in packet buffe= r */ =20 /* PSRTYPE bit definitions */ #define IXGBE_PSRTYPE_TCPHDR 0x00000010 @@ -2321,6 +2452,10 @@ enum { =20 /* SRRCTL bit definitions */ #define IXGBE_SRRCTL_BSIZEPKT_SHIFT 10 /* so many KBs */ +#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* 64byte resolution (>> 6) + * + at bit 8 offset (<< 8) + * =3D (<< 2) + */ #define IXGBE_SRRCTL_RDMTS_SHIFT 22 #define IXGBE_SRRCTL_RDMTS_MASK 0x01C00000 #define IXGBE_SRRCTL_DROP_EN 0x10000000 @@ -2368,6 +2503,8 @@ enum { #define IXGBE_RXDADV_PKTTYPE_UDP 0x00000200 /* UDP hdr present */ #define IXGBE_RXDADV_PKTTYPE_SCTP 0x00000400 /* SCTP hdr present */ #define IXGBE_RXDADV_PKTTYPE_NFS 0x00000800 /* NFS hdr present */ +#define IXGBE_RXDADV_PKTTYPE_VXLAN 0x00000800 /* VXLAN hdr present */ +#define IXGBE_RXDADV_PKTTYPE_TUNNEL 0x00010000 /* Tunnel type */ #define IXGBE_RXDADV_PKTTYPE_IPSEC_ESP 0x00001000 /* IPSec ESP */ #define IXGBE_RXDADV_PKTTYPE_IPSEC_AH 0x00002000 /* IPSec AH */ #define IXGBE_RXDADV_PKTTYPE_LINKSEC 0x00004000 /* LinkSec Encap */ @@ -2418,6 +2555,68 @@ enum { #define IXGBE_MBVFICR(_i) (0x00710 + ((_i) * 4)) #define IXGBE_VFLRE(_i) (((_i & 1) ? 0x001C0 : 0x00600)) #define IXGBE_VFLREC(_i) (0x00700 + ((_i) * 4)) +/* Translated register #defines */ +#define IXGBE_PVFCTRL(P) (0x00300 + (4 * (P))) +#define IXGBE_PVFSTATUS(P) (0x00008 + (0 * (P))) +#define IXGBE_PVFLINKS(P) (0x042A4 + (0 * (P))) +#define IXGBE_PVFRTIMER(P) (0x00048 + (0 * (P))) +#define IXGBE_PVFMAILBOX(P) (0x04C00 + (4 * (P))) +#define IXGBE_PVFRXMEMWRAP(P) (0x03190 + (0 * (P))) +#define IXGBE_PVTEICR(P) (0x00B00 + (4 * (P))) +#define IXGBE_PVTEICS(P) (0x00C00 + (4 * (P))) +#define IXGBE_PVTEIMS(P) (0x00D00 + (4 * (P))) +#define IXGBE_PVTEIMC(P) (0x00E00 + (4 * (P))) +#define IXGBE_PVTEIAC(P) (0x00F00 + (4 * (P))) +#define IXGBE_PVTEIAM(P) (0x04D00 + (4 * (P))) +#define IXGBE_PVTEITR(P) (((P) < 24) ? (0x00820 + ((P) * 4)) : \ + (0x012300 + (((P) - 24) * 4))) +#define IXGBE_PVTIVAR(P) (0x12500 + (4 * (P))) +#define IXGBE_PVTIVAR_MISC(P) (0x04E00 + (4 * (P))) +#define IXGBE_PVTRSCINT(P) (0x12000 + (4 * (P))) +#define IXGBE_VFPBACL(P) (0x110C8 + (4 * (P))) +#define IXGBE_PVFRDBAL(P) ((P < 64) ? (0x01000 + (0x40 * (P))) \ + : (0x0D000 + (0x40 * ((P) - 64)))) +#define IXGBE_PVFRDBAH(P) ((P < 64) ? (0x01004 + (0x40 * (P))) \ + : (0x0D004 + (0x40 * ((P) - 64)))) +#define IXGBE_PVFRDLEN(P) ((P < 64) ? (0x01008 + (0x40 * (P))) \ + : (0x0D008 + (0x40 * ((P) - 64)))) +#define IXGBE_PVFRDH(P) ((P < 64) ? (0x01010 + (0x40 * (P))) \ + : (0x0D010 + (0x40 * ((P) - 64)))) +#define IXGBE_PVFRDT(P) ((P < 64) ? (0x01018 + (0x40 * (P))) \ + : (0x0D018 + (0x40 * ((P) - 64)))) +#define IXGBE_PVFRXDCTL(P) ((P < 64) ? (0x01028 + (0x40 * (P))) \ + : (0x0D028 + (0x40 * ((P) - 64)))) +#define IXGBE_PVFSRRCTL(P) ((P < 64) ? (0x01014 + (0x40 * (P))) \ + : (0x0D014 + (0x40 * ((P) - 64)))) +#define IXGBE_PVFPSRTYPE(P) (0x0EA00 + (4 * (P))) +#define IXGBE_PVFTDBAL(P) (0x06000 + (0x40 * (P))) +#define IXGBE_PVFTDBAH(P) (0x06004 + (0x40 * (P))) +#define IXGBE_PVFTTDLEN(P) (0x06008 + (0x40 * (P))) +#define IXGBE_PVFTDH(P) (0x06010 + (0x40 * (P))) +#define IXGBE_PVFTDT(P) (0x06018 + (0x40 * (P))) +#define IXGBE_PVFTXDCTL(P) (0x06028 + (0x40 * (P))) +#define IXGBE_PVFTDWBAL(P) (0x06038 + (0x40 * (P))) +#define IXGBE_PVFTDWBAH(P) (0x0603C + (0x40 * (P))) +#define IXGBE_PVFDCA_RXCTRL(P) (((P) < 64) ? (0x0100C + (0x40 * (P))) \ + : (0x0D00C + (0x40 * ((P) - 64)))) +#define IXGBE_PVFDCA_TXCTRL(P) (0x0600C + (0x40 * (P))) +#define IXGBE_PVFGPRC(x) (0x0101C + (0x40 * (x))) +#define IXGBE_PVFGPTC(x) (0x08300 + (0x04 * (x))) +#define IXGBE_PVFGORC_LSB(x) (0x01020 + (0x40 * (x))) +#define IXGBE_PVFGORC_MSB(x) (0x0D020 + (0x40 * (x))) +#define IXGBE_PVFGOTC_LSB(x) (0x08400 + (0x08 * (x))) +#define IXGBE_PVFGOTC_MSB(x) (0x08404 + (0x08 * (x))) +#define IXGBE_PVFMPRC(x) (0x0D01C + (0x40 * (x))) + +#define IXGBE_PVFTDWBALn(q_per_pool, vf_number, vf_q_index) \ + (IXGBE_PVFTDWBAL((q_per_pool)*(vf_number) + (vf_q_index))) +#define IXGBE_PVFTDWBAHn(q_per_pool, vf_number, vf_q_index) \ + (IXGBE_PVFTDWBAH((q_per_pool)*(vf_number) + (vf_q_index))) + +#define IXGBE_PVFTDHn(q_per_pool, vf_number, vf_q_index) \ + (IXGBE_PVFTDH((q_per_pool)*(vf_number) + (vf_q_index))) +#define IXGBE_PVFTDTn(q_per_pool, vf_number, vf_q_index) \ + (IXGBE_PVFTDT((q_per_pool)*(vf_number) + (vf_q_index))) =20 /* Little Endian defines */ #ifndef __le16 @@ -2541,7 +2740,17 @@ enum ixgbe_fdir_pballoc_type { #define FW_CEM_UNUSED_VER 0x0 #define FW_CEM_MAX_RETRIES 3 #define FW_CEM_RESP_STATUS_SUCCESS 0x1 - +#define FW_READ_SHADOW_RAM_CMD 0x31 +#define FW_READ_SHADOW_RAM_LEN 0x6 +#define FW_WRITE_SHADOW_RAM_CMD 0x33 +#define FW_WRITE_SHADOW_RAM_LEN 0xA /* 8 plus 1 WORD to write */ +#define FW_SHADOW_RAM_DUMP_CMD 0x36 +#define FW_SHADOW_RAM_DUMP_LEN 0 +#define FW_DEFAULT_CHECKSUM 0xFF /* checksum always 0xFF */ +#define FW_NVM_DATA_OFFSET 3 +#define FW_MAX_READ_BUFFER_SIZE 1024 +#define FW_DISABLE_RXEN_CMD 0xDE +#define FW_DISABLE_RXEN_LEN 0x1 /* Host Interface Command Structures */ =20 struct ixgbe_hic_hdr { @@ -2554,6 +2763,13 @@ struct ixgbe_hic_hdr { u8 checksum; }; =20 +struct ixgbe_hic_hdr2 { + u8 cmd; + u8 buf_len1; + u8 buf_len2; + u8 checksum; +}; + struct ixgbe_hic_drv_info { struct ixgbe_hic_hdr hdr; u8 port_num; @@ -2565,6 +2781,33 @@ struct ixgbe_hic_drv_info { u16 pad2; /* end spacing to ensure length is mult. of dword2 */ }; =20 +/* These need to be dword aligned */ +struct ixgbe_hic_read_shadow_ram { + struct ixgbe_hic_hdr2 hdr; + u32 address; + u16 length; + u16 pad2; + u16 data; + u16 pad3; +}; + +struct ixgbe_hic_write_shadow_ram { + struct ixgbe_hic_hdr2 hdr; + u32 address; + u16 length; + u16 pad2; + u16 data; + u16 pad3; +}; + +struct ixgbe_hic_disable_rxen { + struct ixgbe_hic_hdr hdr; + u8 port_number; + u8 pad2; + u16 pad3; +}; + + /* Transmit Descriptor - Legacy */ struct ixgbe_legacy_tx_desc { u64 buffer_addr; /* Address of the descriptor's data buffer */ @@ -2706,6 +2949,12 @@ struct ixgbe_adv_tx_context_desc { #define IXGBE_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */ #define IXGBE_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */ =20 +#define IXGBE_ADVTXD_OUTER_IPLEN 16 /* Adv ctxt OUTERIPLEN shift */ +#define IXGBE_ADVTXD_TUNNEL_LEN 24 /* Adv ctxt TUNNELLEN shift */ +#define IXGBE_ADVTXD_TUNNEL_TYPE_SHIFT 16 /* Adv Tx Desc Tunnel Type shi= ft */ +#define IXGBE_ADVTXD_OUTERIPCS_SHIFT 17 /* Adv Tx Desc OUTERIPCS Shift *= / +#define IXGBE_ADVTXD_TUNNEL_TYPE_NVGRE 1 /* Adv Tx Desc Tunnel Type NVG= RE */ + /* Autonegotiation advertised speeds */ typedef u32 ixgbe_autoneg_advertised; /* Link speed */ @@ -2713,6 +2962,7 @@ typedef u32 ixgbe_link_speed; #define IXGBE_LINK_SPEED_UNKNOWN 0 #define IXGBE_LINK_SPEED_100_FULL 0x0008 #define IXGBE_LINK_SPEED_1GB_FULL 0x0020 +#define IXGBE_LINK_SPEED_2_5GB_FULL 0x0040 #define IXGBE_LINK_SPEED_10GB_FULL 0x0080 #define IXGBE_LINK_SPEED_82598_AUTONEG (IXGBE_LINK_SPEED_1GB_FULL | \ IXGBE_LINK_SPEED_10GB_FULL) @@ -2909,6 +3159,15 @@ enum ixgbe_mac_type { ixgbe_mac_82599_vf, ixgbe_mac_X540, ixgbe_mac_X540_vf, + /* + * X550EM MAC type decoder: + * ixgbe_mac_X550EM_x: "x" =3D Xeon + * ixgbe_mac_X550EM_a: "a" =3D Atom + */ + ixgbe_mac_X550, + ixgbe_mac_X550EM_x, + ixgbe_mac_X550_vf, + ixgbe_mac_X550EM_x_vf, ixgbe_num_macs }; =20 @@ -2917,6 +3176,8 @@ enum ixgbe_phy_type { ixgbe_phy_none, ixgbe_phy_tn, ixgbe_phy_aq, + ixgbe_phy_x550em_kr, + ixgbe_phy_x550em_kx4, ixgbe_phy_cu_unknown, ixgbe_phy_qt, ixgbe_phy_xaui, diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_vf.h b/lib/librte_pmd_ixgbe= /ixgbe/ixgbe_vf.h index b84b4ba..3c1c168 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_vf.h +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_vf.h @@ -84,6 +84,9 @@ POSSIBILITY OF SUCH DAMAGE. #define IXGBE_VFGOTC_LSB 0x02020 #define IXGBE_VFGOTC_MSB 0x02024 #define IXGBE_VFMPRC 0x01034 +#define IXGBE_VFMRQC 0x3000 +#define IXGBE_VFRSSRK(x) (0x3100 + ((x) * 4)) +#define IXGBE_VFRETA(x) (0x3200 + ((x) * 4)) =20 =20 struct ixgbevf_hw_stats { diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x550.c b/lib/librte_pmd_ixg= be/ixgbe/ixgbe_x550.c new file mode 100644 index 0000000..06d66dd --- /dev/null +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x550.c @@ -0,0 +1,1809 @@ +/***********************************************************************= ******** + +Copyright (c) 2001-2014, Intel Corporation +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are m= et: + + 1. Redistributions of source code must retain the above copyright notic= e, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS = IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, TH= E +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPO= SE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF T= HE +POSSIBILITY OF SUCH DAMAGE. + +************************************************************************= ***/ + +#include "ixgbe_x550.h" +#include "ixgbe_x540.h" +#include "ixgbe_type.h" +#include "ixgbe_api.h" +#include "ixgbe_common.h" +#include "ixgbe_phy.h" + +/** + * ixgbe_init_ops_X550 - Inits func ptrs and MAC type + * @hw: pointer to hardware structure + * + * Initialize the function pointers and assign the MAC type for X550. + * Does not touch the hardware. + **/ +s32 ixgbe_init_ops_X550(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac =3D &hw->mac; + struct ixgbe_eeprom_info *eeprom =3D &hw->eeprom; + s32 ret_val; + + DEBUGFUNC("ixgbe_init_ops_X550"); + + ret_val =3D ixgbe_init_ops_X540(hw); + mac->ops.dmac_config =3D &ixgbe_dmac_config_X550; + mac->ops.dmac_config_tcs =3D &ixgbe_dmac_config_tcs_X550; + mac->ops.dmac_update_tcs =3D &ixgbe_dmac_update_tcs_X550; + mac->ops.setup_eee =3D &ixgbe_setup_eee_X550; + mac->ops.set_source_address_pruning =3D + &ixgbe_set_source_address_pruning_X550; + mac->ops.set_ethertype_anti_spoofing =3D + &ixgbe_set_ethertype_anti_spoofing_X550; + + mac->ops.get_rtrup2tc =3D &ixgbe_dcb_get_rtrup2tc_generic; + eeprom->ops.init_params =3D &ixgbe_init_eeprom_params_X550; + eeprom->ops.calc_checksum =3D &ixgbe_calc_eeprom_checksum_X550; + eeprom->ops.read =3D &ixgbe_read_ee_hostif_X550; + eeprom->ops.read_buffer =3D &ixgbe_read_ee_hostif_buffer_X550; + eeprom->ops.write =3D &ixgbe_write_ee_hostif_X550; + eeprom->ops.write_buffer =3D &ixgbe_write_ee_hostif_buffer_X550; + eeprom->ops.update_checksum =3D &ixgbe_update_eeprom_checksum_X550; + eeprom->ops.validate_checksum =3D &ixgbe_validate_eeprom_checksum_X550; + + mac->ops.disable_mdd =3D &ixgbe_disable_mdd_X550; + mac->ops.enable_mdd =3D &ixgbe_enable_mdd_X550; + mac->ops.mdd_event =3D &ixgbe_mdd_event_X550; + mac->ops.restore_mdd_vf =3D &ixgbe_restore_mdd_vf_X550; + mac->ops.disable_rx =3D &ixgbe_disable_rx_x550; + return ret_val; +} + +/** + * ixgbe_identify_phy_x550em - Get PHY type based on device id + * @hw: pointer to hardware structure + * + * Returns error code + */ +STATIC s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw) +{ + u32 esdp =3D IXGBE_READ_REG(hw, IXGBE_ESDP); + + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_X_SFP: + /* set up for CS4227 usage */ + hw->phy.lan_id =3D IXGBE_READ_REG(hw, IXGBE_STATUS) & + IXGBE_STATUS_LAN_ID_1; + hw->phy.phy_semaphore_mask =3D IXGBE_GSSR_SHARED_I2C_SM; + if (hw->phy.lan_id) { + + esdp &=3D ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1); + esdp |=3D IXGBE_ESDP_SDP1_DIR; + } + esdp &=3D ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR); + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + + return ixgbe_identify_module_generic(hw); + break; + case IXGBE_DEV_ID_X550EM_X_KX4: + hw->phy.type =3D ixgbe_phy_x550em_kx4; + break; + case IXGBE_DEV_ID_X550EM_X_KR: + case IXGBE_DEV_ID_X550EM_X: + hw->phy.type =3D ixgbe_phy_x550em_kr; + break; + default: + break; + } + return IXGBE_SUCCESS; +} + +STATIC s32 ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 *phy_data) +{ + UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, *phy_data); + return IXGBE_NOT_IMPLEMENTED; +} + +STATIC s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 phy_data) +{ + UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, phy_data); + return IXGBE_NOT_IMPLEMENTED; +} + +/** +* ixgbe_init_ops_X550EM - Inits func ptrs and MAC type +* @hw: pointer to hardware structure +* +* Initialize the function pointers and for MAC type X550EM. +* Does not touch the hardware. +**/ +s32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac =3D &hw->mac; + struct ixgbe_eeprom_info *eeprom =3D &hw->eeprom; + struct ixgbe_phy_info *phy =3D &hw->phy; + s32 ret_val; + + DEBUGFUNC("ixgbe_init_ops_X550EM"); + + /* Similar to X550 so start there. */ + ret_val =3D ixgbe_init_ops_X550(hw); + + /* Since this function eventually calls + * ixgbe_init_ops_540 by design, we are setting + * the pointers to NULL explicitly here to overwrite + * the values being set in the x540 function. + */ + /* Thermal sensor not supported in x550EM */ + mac->ops.get_thermal_sensor_data =3D NULL; + mac->ops.init_thermal_sensor_thresh =3D NULL; + mac->thermal_sensor_enabled =3D false; + + /* FCOE not supported in x550EM */ + mac->ops.get_san_mac_addr =3D NULL; + mac->ops.set_san_mac_addr =3D NULL; + mac->ops.get_wwn_prefix =3D NULL; + mac->ops.get_fcoe_boot_status =3D NULL; + + /* IPsec not supported in x550EM */ + mac->ops.disable_sec_rx_path =3D NULL; + mac->ops.enable_sec_rx_path =3D NULL; + + /* PCIe bus info not supported in X550EM */ + mac->ops.get_bus_info =3D NULL; + + mac->ops.read_iosf_sb_reg =3D ixgbe_read_iosf_sb_reg_x550; + mac->ops.write_iosf_sb_reg =3D ixgbe_write_iosf_sb_reg_x550; + mac->ops.get_media_type =3D &ixgbe_get_media_type_X550em; + mac->ops.setup_sfp =3D &ixgbe_setup_sfp_modules_X550em; + mac->ops.get_link_capabilities =3D &ixgbe_get_link_capabilities_X550em; + mac->ops.reset_hw =3D &ixgbe_reset_hw_X550em; + mac->ops.get_supported_physical_layer =3D + &ixgbe_get_supported_physical_layer_X550em; + + /* PHY */ + phy->ops.init =3D &ixgbe_init_phy_ops_X550em; + phy->ops.identify =3D &ixgbe_identify_phy_x550em; + phy->ops.read_reg =3D ixgbe_read_phy_reg_x550em; + phy->ops.write_reg =3D ixgbe_write_phy_reg_x550em; + phy->ops.setup_link =3D ixgbe_setup_kr_x550em; + + + /* EEPROM */ + eeprom->ops.init_params =3D &ixgbe_init_eeprom_params_X540; + eeprom->ops.read =3D &ixgbe_read_ee_hostif_X550; + eeprom->ops.read_buffer =3D &ixgbe_read_ee_hostif_buffer_X550; + eeprom->ops.write =3D &ixgbe_write_ee_hostif_X550; + eeprom->ops.write_buffer =3D &ixgbe_write_ee_hostif_buffer_X550; + eeprom->ops.update_checksum =3D &ixgbe_update_eeprom_checksum_X550; + eeprom->ops.validate_checksum =3D &ixgbe_validate_eeprom_checksum_X550; + eeprom->ops.calc_checksum =3D &ixgbe_calc_eeprom_checksum_X550; + + return ret_val; +} + +/** + * ixgbe_dmac_config_X550 + * @hw: pointer to hardware structure + * + * Configure DMA coalescing. If enabling dmac, dmac is activated. + * When disabling dmac, dmac enable dmac bit is cleared. + **/ +s32 ixgbe_dmac_config_X550(struct ixgbe_hw *hw) +{ + u32 reg, high_pri_tc; + + DEBUGFUNC("ixgbe_dmac_config_X550"); + + /* Disable DMA coalescing before configuring */ + reg =3D IXGBE_READ_REG(hw, IXGBE_DMACR); + reg &=3D ~IXGBE_DMACR_DMAC_EN; + IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg); + + /* Disable DMA Coalescing if the watchdog timer is 0 */ + if (!hw->mac.dmac_config.watchdog_timer) + goto out; + + ixgbe_dmac_config_tcs_X550(hw); + + /* Configure DMA Coalescing Control Register */ + reg =3D IXGBE_READ_REG(hw, IXGBE_DMACR); + + /* Set the watchdog timer in units of 40.96 usec */ + reg &=3D ~IXGBE_DMACR_DMACWT_MASK; + reg |=3D (hw->mac.dmac_config.watchdog_timer * 100) / 4096; + + reg &=3D ~IXGBE_DMACR_HIGH_PRI_TC_MASK; + /* If fcoe is enabled, set high priority traffic class */ + if (hw->mac.dmac_config.fcoe_en) { + high_pri_tc =3D 1 << hw->mac.dmac_config.fcoe_tc; + reg |=3D ((high_pri_tc << IXGBE_DMACR_HIGH_PRI_TC_SHIFT) & + IXGBE_DMACR_HIGH_PRI_TC_MASK); + } + reg |=3D IXGBE_DMACR_EN_MNG_IND; + + /* Enable DMA coalescing after configuration */ + reg |=3D IXGBE_DMACR_DMAC_EN; + IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg); + +out: + return IXGBE_SUCCESS; +} + +/** + * ixgbe_dmac_config_tcs_X550 + * @hw: pointer to hardware structure + * + * Configure DMA coalescing threshold per TC. The dmac enable bit must + * be cleared before configuring. + **/ +s32 ixgbe_dmac_config_tcs_X550(struct ixgbe_hw *hw) +{ + u32 tc, reg, pb_headroom, rx_pb_size, maxframe_size_kb; + + DEBUGFUNC("ixgbe_dmac_config_tcs_X550"); + + /* Configure DMA coalescing enabled */ + switch (hw->mac.dmac_config.link_speed) { + case IXGBE_LINK_SPEED_100_FULL: + pb_headroom =3D IXGBE_DMACRXT_100M; + break; + case IXGBE_LINK_SPEED_1GB_FULL: + pb_headroom =3D IXGBE_DMACRXT_1G; + break; + default: + pb_headroom =3D IXGBE_DMACRXT_10G; + break; + } + + maxframe_size_kb =3D ((IXGBE_READ_REG(hw, IXGBE_MAXFRS) >> + IXGBE_MHADD_MFS_SHIFT) / 1024); + + /* Set the per Rx packet buffer receive threshold */ + for (tc =3D 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) { + reg =3D IXGBE_READ_REG(hw, IXGBE_DMCTH(tc)); + reg &=3D ~IXGBE_DMCTH_DMACRXT_MASK; + + if (tc < hw->mac.dmac_config.num_tcs) { + /* Get Rx PB size */ + rx_pb_size =3D IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(tc)); + rx_pb_size =3D (rx_pb_size & IXGBE_RXPBSIZE_MASK) >> + IXGBE_RXPBSIZE_SHIFT; + + /* Calculate receive buffer threshold in kilobytes */ + if (rx_pb_size > pb_headroom) + rx_pb_size =3D rx_pb_size - pb_headroom; + else + rx_pb_size =3D 0; + + /* Minimum of MFS shall be set for DMCTH */ + reg |=3D (rx_pb_size > maxframe_size_kb) ? + rx_pb_size : maxframe_size_kb; + } + IXGBE_WRITE_REG(hw, IXGBE_DMCTH(tc), reg); + } + return IXGBE_SUCCESS; +} + +/** + * ixgbe_dmac_update_tcs_X550 + * @hw: pointer to hardware structure + * + * Disables dmac, updates per TC settings, and then enables dmac. + **/ +s32 ixgbe_dmac_update_tcs_X550(struct ixgbe_hw *hw) +{ + u32 reg; + + DEBUGFUNC("ixgbe_dmac_update_tcs_X550"); + + /* Disable DMA coalescing before configuring */ + reg =3D IXGBE_READ_REG(hw, IXGBE_DMACR); + reg &=3D ~IXGBE_DMACR_DMAC_EN; + IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg); + + ixgbe_dmac_config_tcs_X550(hw); + + /* Enable DMA coalescing after configuration */ + reg =3D IXGBE_READ_REG(hw, IXGBE_DMACR); + reg |=3D IXGBE_DMACR_DMAC_EN; + IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_init_eeprom_params_X550 - Initialize EEPROM params + * @hw: pointer to hardware structure + * + * Initializes the EEPROM parameters ixgbe_eeprom_info within the + * ixgbe_hw struct in order to set up EEPROM access. + **/ +s32 ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw) +{ + struct ixgbe_eeprom_info *eeprom =3D &hw->eeprom; + u32 eec; + u16 eeprom_size; + + DEBUGFUNC("ixgbe_init_eeprom_params_X550"); + + if (eeprom->type =3D=3D ixgbe_eeprom_uninitialized) { + eeprom->semaphore_delay =3D 10; + eeprom->type =3D ixgbe_flash; + + eec =3D IXGBE_READ_REG(hw, IXGBE_EEC); + eeprom_size =3D (u16)((eec & IXGBE_EEC_SIZE) >> + IXGBE_EEC_SIZE_SHIFT); + eeprom->word_size =3D 1 << (eeprom_size + + IXGBE_EEPROM_WORD_SIZE_SHIFT); + + DEBUGOUT2("Eeprom params: type =3D %d, size =3D %d\n", + eeprom->type, eeprom->word_size); + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_setup_eee_X550 - Enable/disable EEE support + * @hw: pointer to the HW structure + * @enable_eee: boolean flag to enable EEE + * + * Enable/disable EEE based on enable_eee flag. + * Auto-negotiation must be started after BASE-T EEE bits in PHY regist= er 7.3C + * are modified. + * + **/ +s32 ixgbe_setup_eee_X550(struct ixgbe_hw *hw, bool enable_eee) +{ + u32 eeer; + u16 autoneg_eee_reg; + u32 link_reg; + s32 status; + + DEBUGFUNC("ixgbe_setup_eee_X550"); + + eeer =3D IXGBE_READ_REG(hw, IXGBE_EEER); + /* Enable or disable EEE per flag */ + if (enable_eee) { + eeer |=3D (IXGBE_EEER_TX_LPI_EN | IXGBE_EEER_RX_LPI_EN); + + if (hw->device_id =3D=3D IXGBE_DEV_ID_X550T) { + /* Advertise EEE capability */ + hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_EEE_ADVT, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_eee_reg); + + autoneg_eee_reg |=3D (IXGBE_AUTO_NEG_10GBASE_EEE_ADVT | + IXGBE_AUTO_NEG_1000BASE_EEE_ADVT | + IXGBE_AUTO_NEG_100BASE_EEE_ADVT); + + hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_EEE_ADVT, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_eee_reg); + } else if (hw->device_id =3D=3D IXGBE_DEV_ID_X550EM_X_KR || + hw->device_id =3D=3D IXGBE_DEV_ID_X550EM_X) { + status =3D ixgbe_read_iosf_sb_reg_x550(hw, + IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &link_reg); + if (status !=3D IXGBE_SUCCESS) + return status; + + link_reg |=3D IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KR | + IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KX; + + status =3D ixgbe_write_iosf_sb_reg_x550(hw, + IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, link_reg); + if (status !=3D IXGBE_SUCCESS) + return status; + } + } else { + eeer &=3D ~(IXGBE_EEER_TX_LPI_EN | IXGBE_EEER_RX_LPI_EN); + + if (hw->device_id =3D=3D IXGBE_DEV_ID_X550T) { + /* Disable advertised EEE capability */ + hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_EEE_ADVT, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_eee_reg); + + autoneg_eee_reg &=3D ~(IXGBE_AUTO_NEG_10GBASE_EEE_ADVT | + IXGBE_AUTO_NEG_1000BASE_EEE_ADVT | + IXGBE_AUTO_NEG_100BASE_EEE_ADVT); + + hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_EEE_ADVT, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_eee_reg); + } else if (hw->device_id =3D=3D IXGBE_DEV_ID_X550EM_X_KR || + hw->device_id =3D=3D IXGBE_DEV_ID_X550EM_X) { + status =3D ixgbe_read_iosf_sb_reg_x550(hw, + IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, &link_reg); + if (status !=3D IXGBE_SUCCESS) + return status; + + link_reg &=3D ~(IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KR | + IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KX); + + status =3D ixgbe_write_iosf_sb_reg_x550(hw, + IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, link_reg); + if (status !=3D IXGBE_SUCCESS) + return status; + } + } + IXGBE_WRITE_REG(hw, IXGBE_EEER, eeer); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_set_source_address_pruning_X550 - Enable/Disbale source address= pruning + * @hw: pointer to hardware structure + * @enable: enable or disable source address pruning + * @pool: Rx pool to set source address pruning for + **/ +void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, bool ena= ble, + unsigned int pool) +{ + u64 pfflp; + + /* max rx pool is 63 */ + if (pool > 63) + return; + + pfflp =3D (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPL); + pfflp |=3D (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPH) << 32; + + if (enable) + pfflp |=3D (1ULL << pool); + else + pfflp &=3D ~(1ULL << pool); + + IXGBE_WRITE_REG(hw, IXGBE_PFFLPL, (u32)pfflp); + IXGBE_WRITE_REG(hw, IXGBE_PFFLPH, (u32)(pfflp >> 32)); +} + +/** + * ixgbe_set_ethertype_anti_spoofing_X550 - Enable/Disable Ethertype an= ti-spoofing + * @hw: pointer to hardware structure + * @enable: enable or disable switch for Ethertype anti-spoofing + * @vf: Virtual Function pool - VF Pool to set for Ethertype anti-spoof= ing + * + **/ +void ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw, + bool enable, int vf) +{ + int vf_target_reg =3D vf >> 3; + int vf_target_shift =3D vf % 8 + IXGBE_SPOOF_ETHERTYPEAS_SHIFT; + u32 pfvfspoof; + + DEBUGFUNC("ixgbe_set_ethertype_anti_spoofing_X550"); + + pfvfspoof =3D IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg)); + if (enable) + pfvfspoof |=3D (1 << vf_target_shift); + else + pfvfspoof &=3D ~(1 << vf_target_shift); + + IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof); +} + +/** + * ixgbe_write_iosf_sb_reg_x550 - Writes a value to specified register = of the IOSF + * device + * @hw: pointer to hardware structure + * @reg_addr: 32 bit PHY register to write + * @device_type: 3 bit device type + * @data: Data to write to the register + **/ +s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u32 data) +{ + u32 i, command, error; + + command =3D ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) | + (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT)); + + /* Write IOSF control register */ + IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command); + + /* Write IOSF data register */ + IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA, data); + /* + * Check every 10 usec to see if the address cycle completed. + * The SB IOSF BUSY bit will clear when the operation is + * complete + */ + for (i =3D 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { + usec_delay(10); + + command =3D IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL); + if ((command & IXGBE_SB_IOSF_CTRL_BUSY) =3D=3D 0) + break; + } + + if ((command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) !=3D 0) { + error =3D (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >> + IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT; + ERROR_REPORT2(IXGBE_ERROR_POLLING, + "Failed to write, error %x\n", error); + return IXGBE_ERR_PHY; + } + + if (i =3D=3D IXGBE_MDIO_COMMAND_TIMEOUT) { + ERROR_REPORT1(IXGBE_ERROR_POLLING, "Write timed out\n"); + return IXGBE_ERR_PHY; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_read_iosf_sb_reg_x550 - Writes a value to specified register o= f the IOSF + * device + * @hw: pointer to hardware structure + * @reg_addr: 32 bit PHY register to write + * @device_type: 3 bit device type + * @phy_data: Pointer to read data from the register + **/ +s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u32 *data) +{ + u32 i, command, error; + + command =3D ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) | + (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT)); + + /* Write IOSF control register */ + IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command); + + /* + * Check every 10 usec to see if the address cycle completed. + * The SB IOSF BUSY bit will clear when the operation is + * complete + */ + for (i =3D 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { + usec_delay(10); + + command =3D IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL); + if ((command & IXGBE_SB_IOSF_CTRL_BUSY) =3D=3D 0) + break; + } + + if ((command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) !=3D 0) { + error =3D (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >> + IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT; + ERROR_REPORT2(IXGBE_ERROR_POLLING, + "Failed to read, error %x\n", error); + return IXGBE_ERR_PHY; + } + + if (i =3D=3D IXGBE_MDIO_COMMAND_TIMEOUT) { + ERROR_REPORT1(IXGBE_ERROR_POLLING, "Read timed out\n"); + return IXGBE_ERR_PHY; + } + + *data =3D IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_disable_mdd_X550 + * @hw: pointer to hardware structure + * + * Disable malicious driver detection + **/ +void ixgbe_disable_mdd_X550(struct ixgbe_hw *hw) +{ + u32 reg; + + DEBUGFUNC("ixgbe_disable_mdd_X550"); + + /* Disable MDD for TX DMA and interrupt */ + reg =3D IXGBE_READ_REG(hw, IXGBE_DMATXCTL); + reg &=3D ~(IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN); + IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg); + + /* Disable MDD for RX and interrupt */ + reg =3D IXGBE_READ_REG(hw, IXGBE_RDRXCTL); + reg &=3D ~(IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN); + IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg); +} + +/** + * ixgbe_enable_mdd_X550 + * @hw: pointer to hardware structure + * + * Enable malicious driver detection + **/ +void ixgbe_enable_mdd_X550(struct ixgbe_hw *hw) +{ + u32 reg; + + DEBUGFUNC("ixgbe_enable_mdd_X550"); + + /* Enable MDD for TX DMA and interrupt */ + reg =3D IXGBE_READ_REG(hw, IXGBE_DMATXCTL); + reg |=3D (IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN); + IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg); + + /* Enable MDD for RX and interrupt */ + reg =3D IXGBE_READ_REG(hw, IXGBE_RDRXCTL); + reg |=3D (IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN); + IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg); +} + +/** + * ixgbe_restore_mdd_vf_X550 + * @hw: pointer to hardware structure + * @vf: vf index + * + * Restore VF that was disabled during malicious driver detection event + **/ +void ixgbe_restore_mdd_vf_X550(struct ixgbe_hw *hw, u32 vf) +{ + u32 idx, reg, num_qs, start_q, bitmask; + + DEBUGFUNC("ixgbe_restore_mdd_vf_X550"); + + /* Map VF to queues */ + reg =3D IXGBE_READ_REG(hw, IXGBE_MRQC); + switch (reg & IXGBE_MRQC_MRQE_MASK) { + case IXGBE_MRQC_VMDQRT8TCEN: + num_qs =3D 8; /* 16 VFs / pools */ + bitmask =3D 0x000000FF; + break; + case IXGBE_MRQC_VMDQRSS32EN: + case IXGBE_MRQC_VMDQRT4TCEN: + num_qs =3D 4; /* 32 VFs / pools */ + bitmask =3D 0x0000000F; + break; + default: /* 64 VFs / pools */ + num_qs =3D 2; + bitmask =3D 0x00000003; + break; + } + start_q =3D vf * num_qs; + + /* Release vf's queues by clearing WQBR_TX and WQBR_RX (RW1C) */ + idx =3D start_q / 32; + reg =3D 0; + reg |=3D (bitmask << (start_q % 32)); + IXGBE_WRITE_REG(hw, IXGBE_WQBR_TX(idx), reg); + IXGBE_WRITE_REG(hw, IXGBE_WQBR_RX(idx), reg); +} + +/** + * ixgbe_mdd_event_X550 + * @hw: pointer to hardware structure + * @vf_bitmap: vf bitmap of malicious vfs + * + * Handle malicious driver detection event. + **/ +void ixgbe_mdd_event_X550(struct ixgbe_hw *hw, u32 *vf_bitmap) +{ + u32 wqbr; + u32 i, j, reg, q, shift, vf, idx; + + DEBUGFUNC("ixgbe_mdd_event_X550"); + + /* figure out pool size for mapping to vf's */ + reg =3D IXGBE_READ_REG(hw, IXGBE_MRQC); + switch (reg & IXGBE_MRQC_MRQE_MASK) { + case IXGBE_MRQC_VMDQRT8TCEN: + shift =3D 3; /* 16 VFs / pools */ + break; + case IXGBE_MRQC_VMDQRSS32EN: + case IXGBE_MRQC_VMDQRT4TCEN: + shift =3D 2; /* 32 VFs / pools */ + break; + default: + shift =3D 1; /* 64 VFs / pools */ + break; + } + + /* Read WQBR_TX and WQBR_RX and check for malicious queues */ + for (i =3D 0; i < 4; i++) { + wqbr =3D IXGBE_READ_REG(hw, IXGBE_WQBR_TX(i)); + wqbr |=3D IXGBE_READ_REG(hw, IXGBE_WQBR_RX(i)); + + if (!wqbr) + continue; + + /* Get malicious queue */ + for (j =3D 0; j < 32 && wqbr; j++) { + + if (!(wqbr & (1 << j))) + continue; + + /* Get queue from bitmask */ + q =3D j + (i * 32); + + /* Map queue to vf */ + vf =3D (q >> shift); + + /* Set vf bit in vf_bitmap */ + idx =3D vf / 32; + vf_bitmap[idx] |=3D (1 << (vf % 32)); + wqbr &=3D ~(1 << j); + } + } +} + +/** + * ixgbe_get_media_type_X550em - Get media type + * @hw: pointer to hardware structure + * + * Returns the media type (fiber, copper, backplane) + */ +enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw) +{ + enum ixgbe_media_type media_type; + + DEBUGFUNC("ixgbe_get_media_type_X550em"); + + /* Detect if there is a copper PHY attached. */ + switch (hw->device_id) { + case IXGBE_DEV_ID_X550EM_X: + case IXGBE_DEV_ID_X550EM_X_KR: + case IXGBE_DEV_ID_X550EM_X_KX4: + media_type =3D ixgbe_media_type_backplane; + break; + case IXGBE_DEV_ID_X550EM_X_SFP: + media_type =3D ixgbe_media_type_fiber; + break; + default: + media_type =3D ixgbe_media_type_unknown; + break; + } + return media_type; +} + +/** + * ixgbe_setup_sfp_modules_X550em - Setup SFP module + * @hw: pointer to hardware structure + */ +s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw) +{ + bool setup_linear; + u16 reg_slice, edc_mode; + + DEBUGFUNC("ixgbe_setup_sfp_modules_X550em"); + + switch (hw->phy.sfp_type) { + case ixgbe_sfp_type_unknown: + return IXGBE_SUCCESS; + case ixgbe_sfp_type_not_present: + return IXGBE_ERR_SFP_NOT_PRESENT; + case ixgbe_sfp_type_da_cu_core0: + case ixgbe_sfp_type_da_cu_core1: + setup_linear =3D true; + break; + case ixgbe_sfp_type_srlr_core0: + case ixgbe_sfp_type_srlr_core1: + case ixgbe_sfp_type_da_act_lmt_core0: + case ixgbe_sfp_type_da_act_lmt_core1: + case ixgbe_sfp_type_1g_sx_core0: + case ixgbe_sfp_type_1g_sx_core1: + case ixgbe_sfp_type_1g_lx_core0: + case ixgbe_sfp_type_1g_lx_core1: + setup_linear =3D false; + break; + default: + return IXGBE_ERR_SFP_NOT_SUPPORTED; + } + + ixgbe_init_mac_link_ops_X550em(hw); + hw->phy.ops.reset =3D NULL; + + /* The CS4227 slice address is the base address + the port-pair reg + * offset. I.e. Slice 0 =3D 0x0000 and slice 1 =3D 0x1000. + */ + reg_slice =3D IXGBE_CS4227_SPARE24_LSB + (hw->phy.lan_id << 12); + + if (setup_linear) + edc_mode =3D (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1; + else + edc_mode =3D (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1; + + /* Configure CS4227 for connection type. */ + return hw->phy.ops.write_i2c_combined(hw, IXGBE_CS4227, + reg_slice, edc_mode); +} + +/** + * ixgbe_init_mac_link_ops_X550em - init mac link function pointers + * @hw: pointer to hardware structure + */ +void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac =3D &hw->mac; + + DEBUGFUNC("ixgbe_init_mac_link_ops_X550em"); + + /* CS4227 does not support autoneg, so disable the laser control + * functions for SFP+ fiber + */ + if (hw->device_id =3D=3D IXGBE_DEV_ID_X550EM_X_SFP) { + mac->ops.disable_tx_laser =3D NULL; + mac->ops.enable_tx_laser =3D NULL; + mac->ops.flap_tx_laser =3D NULL; + } +} + +/** + * ixgbe_get_link_capabilities_x550em - Determines link capabilities + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @autoneg: true when autoneg or autotry is enabled + */ +s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg) +{ + DEBUGFUNC("ixgbe_get_link_capabilities_X550em"); + + /* SFP */ + if (hw->phy.media_type =3D=3D ixgbe_media_type_fiber) { + + /* CS4227 SFP must not enable auto-negotiation */ + *autoneg =3D false; + + /* Check if 1G SFP module. */ + if (hw->phy.sfp_type =3D=3D ixgbe_sfp_type_1g_sx_core0 || + hw->phy.sfp_type =3D=3D ixgbe_sfp_type_1g_sx_core1 + || hw->phy.sfp_type =3D=3D ixgbe_sfp_type_1g_lx_core0 || + hw->phy.sfp_type =3D=3D ixgbe_sfp_type_1g_lx_core1) { + *speed =3D IXGBE_LINK_SPEED_1GB_FULL; + return IXGBE_SUCCESS; + } + + /* Link capabilities are based on SFP */ + if (hw->phy.multispeed_fiber) + *speed |=3D IXGBE_LINK_SPEED_10GB_FULL | + IXGBE_LINK_SPEED_1GB_FULL; + else + *speed =3D IXGBE_LINK_SPEED_10GB_FULL; + } else { + *speed |=3D IXGBE_LINK_SPEED_10GB_FULL | + IXGBE_LINK_SPEED_1GB_FULL; + *autoneg =3D true; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_init_phy_ops_X550em - PHY/SFP specific init + * @hw: pointer to hardware structure + * + * Initialize any function pointers that were not able to be + * set during init_shared_code because the PHY/SFP type was + * not known. Perform the SFP init if necessary. + */ +s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw) +{ + struct ixgbe_phy_info *phy =3D &hw->phy; + s32 ret_val; + u32 esdp; + + DEBUGFUNC("ixgbe_init_phy_ops_X550em"); + + if (hw->device_id =3D=3D IXGBE_DEV_ID_X550EM_X_SFP) { + esdp =3D IXGBE_READ_REG(hw, IXGBE_ESDP); + phy->lan_id =3D IXGBE_READ_REG(hw, IXGBE_STATUS) & + IXGBE_STATUS_LAN_ID_1; + phy->phy_semaphore_mask =3D IXGBE_GSSR_SHARED_I2C_SM; + if (phy->lan_id) { + esdp &=3D ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1); + esdp |=3D IXGBE_ESDP_SDP1_DIR; + } + esdp &=3D ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR); + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + } + + /* Identify the PHY or SFP module */ + ret_val =3D phy->ops.identify(hw); + if (ret_val =3D=3D IXGBE_ERR_SFP_NOT_SUPPORTED) + return ret_val; + + /* Setup function pointers based on detected SFP module and speeds */ + ixgbe_init_mac_link_ops_X550em(hw); + if (phy->sfp_type !=3D ixgbe_sfp_type_unknown) + phy->ops.reset =3D NULL; + + /* Set functions pointers based on phy type */ + switch (hw->phy.type) { + case ixgbe_phy_x550em_kr: + phy->ops.setup_link =3D ixgbe_setup_kr_x550em; + break; + default: + break; + } + return ret_val; +} + +/** + * ixgbe_reset_hw_X550em - Perform hardware reset + * @hw: pointer to hardware structure + * + * Resets the hardware by resetting the transmit and receive units, mas= ks + * and clears all interrupts, perform a PHY reset, and perform a link (= MAC) + * reset. + */ +s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw) +{ + ixgbe_link_speed link_speed; + s32 status; + u32 ctrl =3D 0; + u32 i; + bool link_up =3D false; + + DEBUGFUNC("ixgbe_reset_hw_X550em"); + + /* Call adapter stop to disable Tx/Rx and clear interrupts */ + status =3D hw->mac.ops.stop_adapter(hw); + if (status !=3D IXGBE_SUCCESS) + return status; + + /* flush pending Tx transactions */ + ixgbe_clear_tx_pending(hw); + + /* PHY ops must be identified and initialized prior to reset */ + + /* Identify PHY and related function pointers */ + status =3D hw->phy.ops.init(hw); + + if (status =3D=3D IXGBE_ERR_SFP_NOT_SUPPORTED) + return status; + + /* Setup SFP module if there is one present. */ + if (hw->phy.sfp_setup_needed) { + status =3D hw->mac.ops.setup_sfp(hw); + hw->phy.sfp_setup_needed =3D false; + } + + if (status =3D=3D IXGBE_ERR_SFP_NOT_SUPPORTED) + return status; + + /* Reset PHY */ + if (!hw->phy.reset_disable && hw->phy.ops.reset) + hw->phy.ops.reset(hw); + +mac_reset_top: + /* Issue global reset to the MAC. Needs to be SW reset if link is up. + * If link reset is used when link is up, it might reset the PHY when + * mng is using it. If link is down or the flag to force full link + * reset is set, then perform link reset. + */ + ctrl =3D IXGBE_CTRL_LNK_RST; + if (!hw->force_full_reset) { + hw->mac.ops.check_link(hw, &link_speed, &link_up, false); + if (link_up) + ctrl =3D IXGBE_CTRL_RST; + } + + ctrl |=3D IXGBE_READ_REG(hw, IXGBE_CTRL); + IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); + IXGBE_WRITE_FLUSH(hw); + + /* Poll for reset bit to self-clear meaning reset is complete */ + for (i =3D 0; i < 10; i++) { + usec_delay(1); + ctrl =3D IXGBE_READ_REG(hw, IXGBE_CTRL); + if (!(ctrl & IXGBE_CTRL_RST_MASK)) + break; + } + + if (ctrl & IXGBE_CTRL_RST_MASK) { + status =3D IXGBE_ERR_RESET_FAILED; + DEBUGOUT("Reset polling failed to complete.\n"); + } + + msec_delay(50); + + /* Double resets are required for recovery from certain error + * conditions. Between resets, it is necessary to stall to + * allow time for any pending HW events to complete. + */ + if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { + hw->mac.flags &=3D ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; + goto mac_reset_top; + } + + /* Store the permanent mac address */ + hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); + + /* Store MAC address from RAR0, clear receive address registers, and + * clear the multicast table. Also reset num_rar_entries to 128, + * since we modify this value when programming the SAN MAC address. + */ + hw->mac.num_rar_entries =3D 128; + hw->mac.ops.init_rx_addrs(hw); + + return status; +} + +/** + * ixgbe_setup_kr_x550em - Configure the KR PHY. + * @hw: pointer to hardware structure + * + * Configures the integrated KR PHY. + **/ +s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw) +{ + s32 status; + u32 reg_val; + + status =3D ixgbe_read_iosf_sb_reg_x550(hw, + IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + + reg_val |=3D IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; + reg_val |=3D IXGBE_KRM_LINK_CTRL_1_TETH_AN_FEC_REQ; + reg_val |=3D IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_FEC; + reg_val &=3D ~(IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR | + IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX); + + /* Advertise 10G support. */ + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) + reg_val |=3D IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR; + + /* Advertise 1G support. */ + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) + reg_val |=3D IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX; + + /* Restart auto-negotiation. */ + reg_val |=3D IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART; + status =3D ixgbe_write_iosf_sb_reg_x550(hw, + IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + + return status; +} + +/** + * ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI. + * @hw: pointer to hardware structure + * + * Configures the integrated KR PHY to use iXFI mode. + **/ +s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw) +{ + s32 status; + u32 reg_val; + + /* Disable AN and force speed to 10G Serial. */ + status =3D ixgbe_read_iosf_sb_reg_x550(hw, + IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status !=3D IXGBE_SUCCESS) + return status; + reg_val &=3D ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; + reg_val &=3D ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK; + reg_val |=3D IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G; + status =3D ixgbe_write_iosf_sb_reg_x550(hw, + IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + if (status !=3D IXGBE_SUCCESS) + return status; + + /* Disable training protocol FSM. */ + status =3D ixgbe_read_iosf_sb_reg_x550(hw, + IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status !=3D IXGBE_SUCCESS) + return status; + reg_val |=3D IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL; + status =3D ixgbe_write_iosf_sb_reg_x550(hw, + IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + if (status !=3D IXGBE_SUCCESS) + return status; + + /* Disable Flex from training TXFFE. */ + status =3D ixgbe_read_iosf_sb_reg_x550(hw, + IXGBE_KRM_DSP_TXFFE_STATE_4(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status !=3D IXGBE_SUCCESS) + return status; + reg_val &=3D ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN; + reg_val &=3D ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN; + reg_val &=3D ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN; + status =3D ixgbe_write_iosf_sb_reg_x550(hw, + IXGBE_KRM_DSP_TXFFE_STATE_4(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + if (status !=3D IXGBE_SUCCESS) + return status; + status =3D ixgbe_read_iosf_sb_reg_x550(hw, + IXGBE_KRM_DSP_TXFFE_STATE_5(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status !=3D IXGBE_SUCCESS) + return status; + reg_val &=3D ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN; + reg_val &=3D ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN; + reg_val &=3D ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN; + status =3D ixgbe_write_iosf_sb_reg_x550(hw, + IXGBE_KRM_DSP_TXFFE_STATE_5(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + if (status !=3D IXGBE_SUCCESS) + return status; + + /* Enable override for coefficients. */ + status =3D ixgbe_read_iosf_sb_reg_x550(hw, + IXGBE_KRM_TX_COEFF_CTRL_1(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status !=3D IXGBE_SUCCESS) + return status; + reg_val |=3D IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN; + reg_val |=3D IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN; + reg_val |=3D IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN; + reg_val |=3D IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN; + status =3D ixgbe_write_iosf_sb_reg_x550(hw, + IXGBE_KRM_TX_COEFF_CTRL_1(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + if (status !=3D IXGBE_SUCCESS) + return status; + + /* Toggle port SW reset by AN reset. */ + status =3D ixgbe_read_iosf_sb_reg_x550(hw, + IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status !=3D IXGBE_SUCCESS) + return status; + reg_val |=3D IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART; + status =3D ixgbe_write_iosf_sb_reg_x550(hw, + IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + + return status; +} + +/** + * ixgbe_setup_phy_loopback_x550em - Configure the KR PHY for loopback. + * @hw: pointer to hardware structure + * + * Configures the integrated KR PHY to use internal loopback mode. + **/ +s32 ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw) +{ + s32 status; + u32 reg_val; + + /* Disable AN and force speed to 10G Serial. */ + status =3D ixgbe_read_iosf_sb_reg_x550(hw, + IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status !=3D IXGBE_SUCCESS) + return status; + reg_val &=3D ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE; + reg_val &=3D ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK; + reg_val |=3D IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G; + status =3D ixgbe_write_iosf_sb_reg_x550(hw, + IXGBE_KRM_LINK_CTRL_1(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + if (status !=3D IXGBE_SUCCESS) + return status; + + /* Set near-end loopback clocks. */ + status =3D ixgbe_read_iosf_sb_reg_x550(hw, + IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status !=3D IXGBE_SUCCESS) + return status; + reg_val |=3D IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_32B; + reg_val |=3D IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_KRPCS; + status =3D ixgbe_write_iosf_sb_reg_x550(hw, + IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + if (status !=3D IXGBE_SUCCESS) + return status; + + /* Set loopback enable. */ + status =3D ixgbe_read_iosf_sb_reg_x550(hw, + IXGBE_KRM_PMD_DFX_BURNIN(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status !=3D IXGBE_SUCCESS) + return status; + reg_val |=3D IXGBE_KRM_PMD_DFX_BURNIN_TX_RX_KR_LB_MASK; + status =3D ixgbe_write_iosf_sb_reg_x550(hw, + IXGBE_KRM_PMD_DFX_BURNIN(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + if (status !=3D IXGBE_SUCCESS) + return status; + + /* Training bypass. */ + status =3D ixgbe_read_iosf_sb_reg_x550(hw, + IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val); + if (status !=3D IXGBE_SUCCESS) + return status; + reg_val |=3D IXGBE_KRM_RX_TRN_LINKUP_CTRL_PROTOCOL_BYPASS; + status =3D ixgbe_write_iosf_sb_reg_x550(hw, + IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->phy.lan_id), + IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val); + + return status; +} + +/** + * ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface = command + * assuming that the semaphore is already obtained. + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to read + * @data: word read from the EEPROM + * + * Reads a 16 bit word from the EEPROM using the hostif. + **/ +s32 ixgbe_read_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset, + u16 *data) +{ + s32 status; + struct ixgbe_hic_read_shadow_ram buffer; + + DEBUGFUNC("ixgbe_read_ee_hostif_data_X550"); + buffer.hdr.cmd =3D FW_READ_SHADOW_RAM_CMD; + buffer.hdr.buf_len1 =3D 0; + buffer.hdr.buf_len2 =3D FW_READ_SHADOW_RAM_LEN; + buffer.hdr.checksum =3D FW_DEFAULT_CHECKSUM; + + /* convert offset from words to bytes */ + buffer.address =3D IXGBE_CPU_TO_BE32(offset * 2); + /* one word */ + buffer.length =3D IXGBE_CPU_TO_BE16(sizeof(u16)); + + status =3D ixgbe_host_interface_command(hw, (u32 *)&buffer, + sizeof(buffer), false); + + if (status) + return status; + + *data =3D (u16)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, + FW_NVM_DATA_OFFSET); + + return 0; +} + +/** + * ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface = command + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to read + * @data: word read from the EEPROM + * + * Reads a 16 bit word from the EEPROM using the hostif. + **/ +s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, + u16 *data) +{ + s32 status =3D IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_read_ee_hostif_X550"); + + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) =3D=3D + IXGBE_SUCCESS) { + status =3D ixgbe_read_ee_hostif_data_X550(hw, offset, data); + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + } else { + status =3D IXGBE_ERR_SWFW_SYNC; + } + + return status; +} + +/** + * ixgbe_read_ee_hostif_buffer_X550- Read EEPROM word(s) using hostif + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to read + * @words: number of words + * @data: word(s) read from the EEPROM + * + * Reads a 16 bit word(s) from the EEPROM using the hostif. + **/ +s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw, + u16 offset, u16 words, u16 *data) +{ + struct ixgbe_hic_read_shadow_ram buffer; + u32 current_word =3D 0; + u16 words_to_read; + s32 status; + u32 i; + + DEBUGFUNC("ixgbe_read_ee_hostif_buffer_X550"); + + /* Take semaphore for the entire operation. */ + status =3D hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + if (status) { + DEBUGOUT("EEPROM read buffer - semaphore failed\n"); + return status; + } + while (words) { + if (words > FW_MAX_READ_BUFFER_SIZE / 2) + words_to_read =3D FW_MAX_READ_BUFFER_SIZE / 2; + else + words_to_read =3D words; + + buffer.hdr.cmd =3D FW_READ_SHADOW_RAM_CMD; + buffer.hdr.buf_len1 =3D 0; + buffer.hdr.buf_len2 =3D FW_READ_SHADOW_RAM_LEN; + buffer.hdr.checksum =3D FW_DEFAULT_CHECKSUM; + + /* convert offset from words to bytes */ + buffer.address =3D IXGBE_CPU_TO_BE32((offset + current_word) * 2); + buffer.length =3D IXGBE_CPU_TO_BE16(words_to_read * 2); + + status =3D ixgbe_host_interface_command(hw, (u32 *)&buffer, + sizeof(buffer), false); + + if (status) { + DEBUGOUT("Host interface command failed\n"); + goto out; + } + + for (i =3D 0; i < words_to_read; i++) { + u32 reg =3D IXGBE_FLEX_MNG + (FW_NVM_DATA_OFFSET << 2) + + 2 * i; + u32 value =3D IXGBE_READ_REG(hw, reg); + + data[current_word] =3D (u16)(value & 0xffff); + current_word++; + i++; + if (i < words_to_read) { + value >>=3D 16; + data[current_word] =3D (u16)(value & 0xffff); + current_word++; + } + } + words -=3D words_to_read; + } + +out: + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + return status; +} + +/** + * ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to write + * @data: word write to the EEPROM + * + * Write a 16 bit word to the EEPROM using the hostif. + **/ +s32 ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset, + u16 data) +{ + s32 status; + struct ixgbe_hic_write_shadow_ram buffer; + + DEBUGFUNC("ixgbe_write_ee_hostif_data_X550"); + + buffer.hdr.cmd =3D FW_WRITE_SHADOW_RAM_CMD; + buffer.hdr.buf_len1 =3D 0; + buffer.hdr.buf_len2 =3D FW_WRITE_SHADOW_RAM_LEN; + buffer.hdr.checksum =3D FW_DEFAULT_CHECKSUM; + + /* one word */ + buffer.length =3D IXGBE_CPU_TO_BE16(sizeof(u16)); + buffer.data =3D data; + buffer.address =3D IXGBE_CPU_TO_BE32(offset * 2); + + status =3D ixgbe_host_interface_command(hw, (u32 *)&buffer, + sizeof(buffer), false); + + return status; +} + +/** + * ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to write + * @data: word write to the EEPROM + * + * Write a 16 bit word to the EEPROM using the hostif. + **/ +s32 ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, + u16 data) +{ + s32 status =3D IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_write_ee_hostif_X550"); + + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) =3D=3D + IXGBE_SUCCESS) { + status =3D ixgbe_write_ee_hostif_data_X550(hw, offset, data); + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + } else { + DEBUGOUT("write ee hostif failed to get semaphore"); + status =3D IXGBE_ERR_SWFW_SYNC; + } + + return status; +} + +/** + * ixgbe_write_ee_hostif_buffer_X550 - Write EEPROM word(s) using hosti= f + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to write + * @words: number of words + * @data: word(s) write to the EEPROM + * + * Write a 16 bit word(s) to the EEPROM using the hostif. + **/ +s32 ixgbe_write_ee_hostif_buffer_X550(struct ixgbe_hw *hw, + u16 offset, u16 words, u16 *data) +{ + s32 status =3D IXGBE_SUCCESS; + u32 i =3D 0; + + DEBUGFUNC("ixgbe_write_ee_hostif_buffer_X550"); + + /* Take semaphore for the entire operation. */ + status =3D hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + if (status !=3D IXGBE_SUCCESS) { + DEBUGOUT("EEPROM write buffer - semaphore failed\n"); + goto out; + } + + for (i =3D 0; i < words; i++) { + status =3D ixgbe_write_ee_hostif_data_X550(hw, offset + i, + data[i]); + + if (status !=3D IXGBE_SUCCESS) { + DEBUGOUT("Eeprom buffered write failed\n"); + break; + } + } + + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); +out: + + return status; +} + +/** + * ixgbe_checksum_ptr_x550 - Checksum one pointer region + * @hw: pointer to hardware structure + * @ptr: pointer offset in eeprom + * @size: size of section pointed by ptr, if 0 first word will be used a= s size + * @csum: address of checksum to update + * + * Returns error status for any failure + */ +STATIC s32 ixgbe_checksum_ptr_x550(struct ixgbe_hw *hw, u16 ptr, + u16 size, u16 *csum) +{ + u16 buf[256]; + s32 status; + u16 length, bufsz, i, start; + + bufsz =3D sizeof(buf) / sizeof(buf[0]); + + /* Read a chunk at the pointer location */ + status =3D ixgbe_read_ee_hostif_buffer_X550(hw, ptr, bufsz, buf); + if (status) { + DEBUGOUT("Failed to read EEPROM image\n"); + return status; + } + + if (size) { + start =3D 0; + length =3D size; + } else { + start =3D 1; + length =3D buf[0]; + + /* Skip pointer section if length is invalid. */ + if (length =3D=3D 0xFFFF || length =3D=3D 0 || + (ptr + length) >=3D hw->eeprom.word_size) + return IXGBE_SUCCESS; + } + + for (i =3D start; length; i++, length--) { + if (i =3D=3D bufsz) { + ptr +=3D bufsz; + i =3D 0; + if (length < bufsz) + bufsz =3D length; + + /* Read a chunk at the pointer location */ + status =3D ixgbe_read_ee_hostif_buffer_X550(hw, ptr, + bufsz, buf); + if (status) { + DEBUGOUT("Failed to read EEPROM image\n"); + return status; + } + } + *csum +=3D buf[i]; + } + return IXGBE_SUCCESS; +} + +/** + * ixgbe_calc_eeprom_checksum_X550 - Calculates and returns the checksu= m + * @hw: pointer to hardware structure + * + * Returns a negative error code on error, or the 16-bit checksum + **/ +s32 ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw) +{ + u16 eeprom_ptrs[IXGBE_EEPROM_LAST_WORD + 1]; + s32 status; + u16 checksum =3D 0; + u16 pointer, i, size; + + DEBUGFUNC("ixgbe_calc_eeprom_checksum_X550"); + + hw->eeprom.ops.init_params(hw); + + /* Read pointer area */ + status =3D ixgbe_read_ee_hostif_buffer_X550(hw, 0, + IXGBE_EEPROM_LAST_WORD + 1, + eeprom_ptrs); + if (status) { + DEBUGOUT("Failed to read EEPROM image\n"); + return status; + } + + /* + * For X550 hardware include 0x0-0x41 in the checksum, skip the + * checksum word itself + */ + for (i =3D 0; i <=3D IXGBE_EEPROM_LAST_WORD; i++) + if (i !=3D IXGBE_EEPROM_CHECKSUM) + checksum +=3D eeprom_ptrs[i]; + + /* + * Include all data from pointers 0x3, 0x6-0xE. This excludes the + * FW, PHY module, and PCIe Expansion/Option ROM pointers. + */ + for (i =3D IXGBE_PCIE_ANALOG_PTR_X550; i < IXGBE_FW_PTR; i++) { + if (i =3D=3D IXGBE_PHY_PTR || i =3D=3D IXGBE_OPTION_ROM_PTR) + continue; + + pointer =3D eeprom_ptrs[i]; + + /* Skip pointer section if the pointer is invalid. */ + if (pointer =3D=3D 0xFFFF || pointer =3D=3D 0 || + pointer >=3D hw->eeprom.word_size) + continue; + + switch (i) { + case IXGBE_PCIE_GENERAL_PTR: + size =3D IXGBE_IXGBE_PCIE_GENERAL_SIZE; + break; + case IXGBE_PCIE_CONFIG0_PTR: + case IXGBE_PCIE_CONFIG1_PTR: + size =3D IXGBE_PCIE_CONFIG_SIZE; + break; + default: + size =3D 0; + break; + } + + status =3D ixgbe_checksum_ptr_x550(hw, pointer, size, &checksum); + if (status) + return status; + } + + checksum =3D (u16)IXGBE_EEPROM_SUM - checksum; + + return (s32)checksum; +} + +/** + * ixgbe_validate_eeprom_checksum_X550 - Validate EEPROM checksum + * @hw: pointer to hardware structure + * @checksum_val: calculated checksum + * + * Performs checksum calculation and validates the EEPROM checksum. If= the + * caller does not need checksum_val, the value can be NULL. + **/ +s32 ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw, + u16 *checksum_val) +{ + s32 status; + u16 checksum; + u16 read_checksum =3D 0; + + DEBUGFUNC("ixgbe_validate_eeprom_checksum_X550"); + + /* Read the first word from the EEPROM. If this times out or fails, do + * not continue or we could be in for a very long wait while every + * EEPROM read fails + */ + status =3D hw->eeprom.ops.read(hw, 0, &checksum); + if (status) { + DEBUGOUT("EEPROM read failed\n"); + return status; + } + + status =3D hw->eeprom.ops.calc_checksum(hw); + if (status < 0) + return status; + + checksum =3D (u16)(status & 0xffff); + + status =3D ixgbe_read_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM, + &read_checksum); + if (status) + return status; + + /* Verify read checksum from EEPROM is the same as + * calculated checksum + */ + if (read_checksum !=3D checksum) { + status =3D IXGBE_ERR_EEPROM_CHECKSUM; + ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE, + "Invalid EEPROM checksum"); + } + + /* If the user cares, return the calculated checksum */ + if (checksum_val) + *checksum_val =3D checksum; + + return status; +} + +/** + * ixgbe_update_eeprom_checksum_X550 - Updates the EEPROM checksum and f= lash + * @hw: pointer to hardware structure + * + * After writing EEPROM to shadow RAM using EEWR register, software calc= ulates + * checksum and updates the EEPROM and instructs the hardware to update + * the flash. + **/ +s32 ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw) +{ + s32 status; + u16 checksum =3D 0; + + DEBUGFUNC("ixgbe_update_eeprom_checksum_X550"); + + /* Read the first word from the EEPROM. If this times out or fails, do + * not continue or we could be in for a very long wait while every + * EEPROM read fails + */ + status =3D ixgbe_read_ee_hostif_X550(hw, 0, &checksum); + if (status) { + DEBUGOUT("EEPROM read failed\n"); + return status; + } + + status =3D ixgbe_calc_eeprom_checksum_X550(hw); + if (status < 0) + return status; + + checksum =3D (u16)(status & 0xffff); + + status =3D ixgbe_write_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM, + checksum); + if (status) + return status; + + status =3D ixgbe_update_flash_X550(hw); + + return status; +} + +/** + * ixgbe_update_flash_X550 - Instruct HW to copy EEPROM to Flash device + * @hw: pointer to hardware structure + * + * Issue a shadow RAM dump to FW to copy EEPROM from shadow RAM to the = flash. + **/ +s32 ixgbe_update_flash_X550(struct ixgbe_hw *hw) +{ + s32 status =3D IXGBE_SUCCESS; + struct ixgbe_hic_hdr2 buffer; + + DEBUGFUNC("ixgbe_update_flash_X550"); + + buffer.cmd =3D FW_SHADOW_RAM_DUMP_CMD; + buffer.buf_len1 =3D 0; + buffer.buf_len2 =3D FW_SHADOW_RAM_DUMP_LEN; + buffer.checksum =3D FW_DEFAULT_CHECKSUM; + + status =3D ixgbe_host_interface_command(hw, (u32 *)&buffer, + sizeof(buffer), false); + + return status; +} + +/** + * ixgbe_get_supported_physical_layer_X550em - Returns physical layer t= ype + * @hw: pointer to hardware structure + * + * Determines physical layer capabilities of the current configuration. + **/ +u32 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw) +{ + u32 physical_layer =3D IXGBE_PHYSICAL_LAYER_UNKNOWN; + + DEBUGFUNC("ixgbe_get_supported_physical_layer_X550em"); + + hw->phy.ops.identify(hw); + + switch (hw->phy.type) { + case ixgbe_phy_x550em_kr: + physical_layer =3D IXGBE_PHYSICAL_LAYER_10GBASE_KR | + IXGBE_PHYSICAL_LAYER_1000BASE_KX; + break; + case ixgbe_phy_x550em_kx4: + physical_layer =3D IXGBE_PHYSICAL_LAYER_10GBASE_KX4 | + IXGBE_PHYSICAL_LAYER_1000BASE_KX; + break; + default: + break; + } + + if (hw->mac.ops.get_media_type(hw) =3D=3D ixgbe_media_type_fiber) + physical_layer =3D ixgbe_get_supported_phy_sfp_layer_generic(hw); + + return physical_layer; +} + +/** + * ixgbe_disable_rx_x550 - Disable RX unit + * + * Enables the Rx DMA unit for x550 + **/ +void ixgbe_disable_rx_x550(struct ixgbe_hw *hw) +{ + u32 rxctrl, pfdtxgswc; + s32 status; + struct ixgbe_hic_disable_rxen fw_cmd; + + DEBUGFUNC("ixgbe_enable_rx_dma_x550"); + + rxctrl =3D IXGBE_READ_REG(hw, IXGBE_RXCTRL); + if (rxctrl & IXGBE_RXCTRL_RXEN) { + pfdtxgswc =3D IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC); + if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) { + pfdtxgswc &=3D ~IXGBE_PFDTXGSWC_VT_LBEN; + IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc); + hw->mac.set_lben =3D true; + } else { + hw->mac.set_lben =3D false; + } + + fw_cmd.hdr.cmd =3D FW_DISABLE_RXEN_CMD; + fw_cmd.hdr.buf_len =3D FW_DISABLE_RXEN_LEN; + fw_cmd.hdr.checksum =3D FW_DEFAULT_CHECKSUM; + fw_cmd.port_number =3D hw->phy.lan_id; + + status =3D ixgbe_host_interface_command(hw, (u32 *)&fw_cmd, + sizeof(struct ixgbe_hic_disable_rxen), + true); + + /* If we fail - disable RX using register write */ + if (status) { + rxctrl =3D IXGBE_READ_REG(hw, IXGBE_RXCTRL); + if (rxctrl & IXGBE_RXCTRL_RXEN) { + rxctrl &=3D ~IXGBE_RXCTRL_RXEN; + IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl); + } + } + } +} diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x550.h b/lib/librte_pmd_ixg= be/ixgbe/ixgbe_x550.h new file mode 100644 index 0000000..e8de134 --- /dev/null +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x550.h @@ -0,0 +1,88 @@ +/***********************************************************************= ******** + +Copyright (c) 2001-2014, Intel Corporation +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are m= et: + + 1. Redistributions of source code must retain the above copyright notic= e, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS = IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, TH= E +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPO= SE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF T= HE +POSSIBILITY OF SUCH DAMAGE. + +************************************************************************= ***/ + +#ifndef _IXGBE_X550_H_ +#define _IXGBE_X550_H_ + +#include "ixgbe_type.h" + +s32 ixgbe_dmac_config_X550(struct ixgbe_hw *hw); +s32 ixgbe_dmac_config_tcs_X550(struct ixgbe_hw *hw); +s32 ixgbe_dmac_update_tcs_X550(struct ixgbe_hw *hw); + +s32 ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw); +s32 ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw); +s32 ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw); +s32 ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw, + u16 *checksum_val); +s32 ixgbe_update_flash_X550(struct ixgbe_hw *hw); +s32 ixgbe_write_ee_hostif_buffer_X550(struct ixgbe_hw *hw, + u16 offset, u16 words, u16 *data); +s32 ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, + u16 data); +s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw, + u16 offset, u16 words, u16 *data); +s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset, +u16 *data); +s32 ixgbe_read_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset, + u16 *data); +s32 ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset, + u16 data); +s32 ixgbe_set_eee_X550(struct ixgbe_hw *hw, bool enable_eee); +s32 ixgbe_setup_eee_X550(struct ixgbe_hw *hw, bool enable_eee); +void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, bool ena= ble, + unsigned int pool); +void ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw, + bool enable, int vf); +s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u32 data); +s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u32 *data); +void ixgbe_disable_mdd_X550(struct ixgbe_hw *hw); +void ixgbe_enable_mdd_X550(struct ixgbe_hw *hw); +void ixgbe_mdd_event_X550(struct ixgbe_hw *hw, u32 *vf_bitmap); +void ixgbe_restore_mdd_vf_X550(struct ixgbe_hw *hw, u32 vf); +enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw); +s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw); +s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, bool *autoneg); +void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw); +s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw); +s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw); +s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw); +s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw); +s32 ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw); +u32 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw); +void ixgbe_disable_rx_x550(struct ixgbe_hw *hw); +#endif /* _IXGBE_X550_H_ */ + --=20 1.8.4.2