net/i40e/base: fix partition id calculation for X722
authorQi Zhang <qi.z.zhang@intel.com>
Tue, 25 Sep 2018 02:34:24 +0000 (10:34 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Thu, 11 Oct 2018 16:53:47 +0000 (18:53 +0200)
This patch overwrites number of ports for X722 devices with support for
OCP PHY mezzanine. The old method with checking if port is disabled in
the PRTGEN_CNF register cannot be used in this case. When the OCP is
removed, ports were seen as disabled, which resulted in wrong calculation
of partition id, that caused WoL to be disabled on certain ports.

Fixes: 3c89193a36fd ("i40e/base: support WOL config for X722")
Cc: stable@dpdk.org
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
Acked-by: Beilei Xing <beilei.xing@intel.com>
drivers/net/i40e/base/i40e_common.c
drivers/net/i40e/base/i40e_type.h

index dce5c39..ee117bd 100644 (file)
@@ -3678,9 +3678,10 @@ STATIC void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
        u32 valid_functions, num_functions;
        u32 number, logical_id, phys_id;
        struct i40e_hw_capabilities *p;
+       enum i40e_status_code status;
+       u16 id, ocp_cfg_word0;
        u8 major_rev;
        u32 i = 0;
-       u16 id;
 
        cap = (struct i40e_aqc_list_capabilities_element_resp *) buff;
 
@@ -3972,6 +3973,26 @@ STATIC void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
                        hw->num_ports++;
        }
 
+       /* OCP cards case: if a mezz is removed the ethernet port is at
+        * disabled state in PRTGEN_CNF register. Additional NVM read is
+        * needed in order to check if we are dealing with OCP card.
+        * Those cards have 4 PFs at minimum, so using PRTGEN_CNF for counting
+        * physical ports results in wrong partition id calculation and thus
+        * not supporting WoL.
+        */
+       if (hw->mac.type == I40E_MAC_X722) {
+               if (i40e_acquire_nvm(hw, I40E_RESOURCE_READ) == I40E_SUCCESS) {
+                       status = i40e_aq_read_nvm(hw, I40E_SR_EMP_MODULE_PTR,
+                                                 2 * I40E_SR_OCP_CFG_WORD0,
+                                                 sizeof(ocp_cfg_word0),
+                                                 &ocp_cfg_word0, true, NULL);
+                       if (status == I40E_SUCCESS &&
+                           (ocp_cfg_word0 & I40E_SR_OCP_ENABLED))
+                               hw->num_ports = 4;
+                       i40e_release_nvm(hw);
+               }
+       }
+
        valid_functions = p->valid_functions;
        num_functions = 0;
        while (valid_functions) {
index 55acc14..7dde3bf 100644 (file)
@@ -1512,7 +1512,9 @@ struct i40e_hw_port_stats {
 #define I40E_SR_CONTROL_WORD_1_MASK    (0x03 << I40E_SR_CONTROL_WORD_1_SHIFT)
 #define I40E_SR_CONTROL_WORD_1_NVM_BANK_VALID  BIT(5)
 #define I40E_SR_NVM_MAP_STRUCTURE_TYPE         BIT(12)
-#define I40E_PTR_TYPE                           BIT(15)
+#define I40E_PTR_TYPE                          BIT(15)
+#define I40E_SR_OCP_CFG_WORD0                  0x2B
+#define I40E_SR_OCP_ENABLED                    BIT(15)
 
 /* Shadow RAM related */
 #define I40E_SR_SECTOR_SIZE_IN_WORDS   0x800