net/qede/base: fix to support OVLAN mode
authorRasesh Mody <rasesh.mody@cavium.com>
Mon, 9 Apr 2018 04:48:08 +0000 (21:48 -0700)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 13 Apr 2018 22:41:44 +0000 (00:41 +0200)
This fix allows driver to program NIC configuration to support OVLAN
mode in multi-function scenario

Signed-off-by: Rasesh Mody <rasesh.mody@cavium.com>
drivers/net/qede/base/ecore.h
drivers/net/qede/base/ecore_dcbx.c
drivers/net/qede/base/ecore_dcbx_api.h
drivers/net/qede/base/ecore_dev.c
drivers/net/qede/base/ecore_sp_commands.c

index 7c642af..c8e6311 100644 (file)
@@ -536,6 +536,12 @@ enum ecore_mf_mode_bit {
        ECORE_MF_UFP_SPECIFIC,
 
        ECORE_MF_DISABLE_ARFS,
+
+       /* Use vlan for steering */
+       ECORE_MF_8021Q_TAGGING,
+
+       /* Use stag for steering */
+       ECORE_MF_8021AD_TAGGING,
 };
 
 enum ecore_ufp_mode {
index fe9d5c0..93262ee 100644 (file)
@@ -149,6 +149,10 @@ ecore_dcbx_set_params(struct ecore_dcbx_results *p_data,
        }
        p_data->arr[type].update = UPDATE_DCB_DSCP;
 
+       /* Do not add valn tag 0 when DCB is enabled and port is in UFP mode */
+       if (OSAL_TEST_BIT(ECORE_MF_UFP_SPECIFIC, &p_hwfn->p_dev->mf_bits))
+               p_data->arr[type].dont_add_vlan0 = true;
+
        /* QM reconf data */
        if (p_hwfn->hw_info.personality == personality)
                p_hwfn->hw_info.offload_tc = tc;
@@ -935,6 +939,7 @@ static void ecore_dcbx_update_protocol_data(struct protocol_dcb_data *p_data,
        p_data->dcb_tc = p_src->arr[type].tc;
        p_data->dscp_enable_flag = p_src->arr[type].dscp_enable;
        p_data->dscp_val = p_src->arr[type].dscp_val;
+       p_data->dcb_dont_add_vlan0 = p_src->arr[type].dont_add_vlan0;
 }
 
 /* Set pf update ramrod command params */
index 9ff4df4..4df99ae 100644 (file)
@@ -29,6 +29,7 @@ struct ecore_dcbx_app_data {
        u8 tc;                  /* Traffic Class */
        bool dscp_enable;       /* DSCP enabled */
        u8 dscp_val;            /* DSCP value */
+       bool dont_add_vlan0;    /* Do not insert a vlan tag with id 0 */
 };
 
 #ifndef __EXTRACT__LINUX__
index a85d26d..112f854 100644 (file)
@@ -3588,9 +3588,14 @@ ecore_hw_get_nvm_info(struct ecore_hwfn *p_hwfn,
                break;
        case NVM_CFG1_GLOB_MF_MODE_UFP:
                p_hwfn->p_dev->mf_bits = 1 << ECORE_MF_OVLAN_CLSS |
-                                        1 << ECORE_MF_UFP_SPECIFIC;
+                                        1 << ECORE_MF_UFP_SPECIFIC |
+                                        1 << ECORE_MF_8021Q_TAGGING;
+               break;
+       case NVM_CFG1_GLOB_MF_MODE_BD:
+               p_hwfn->p_dev->mf_bits = 1 << ECORE_MF_OVLAN_CLSS |
+                                        1 << ECORE_MF_LLH_PROTO_CLSS |
+                                        1 << ECORE_MF_8021AD_TAGGING;
                break;
-
        case NVM_CFG1_GLOB_MF_MODE_NPAR1_0:
                p_hwfn->p_dev->mf_bits = 1 << ECORE_MF_LLH_MAC_CLSS |
                                         1 << ECORE_MF_LLH_PROTO_CLSS |
@@ -3619,6 +3624,7 @@ ecore_hw_get_nvm_info(struct ecore_hwfn *p_hwfn,
         */
        switch (mf_mode) {
        case NVM_CFG1_GLOB_MF_MODE_MF_ALLOWED:
+       case NVM_CFG1_GLOB_MF_MODE_BD:
                p_hwfn->p_dev->mf_mode = ECORE_MF_OVLAN;
                break;
        case NVM_CFG1_GLOB_MF_MODE_NPAR1_0:
index 7598e7a..83705b8 100644 (file)
@@ -295,6 +295,7 @@ ecore_tunn_set_pf_start_params(struct ecore_hwfn *p_hwfn,
 }
 
 #define ETH_P_8021Q 0x8100
+#define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN         */
 
 enum _ecore_status_t ecore_sp_pf_start(struct ecore_hwfn *p_hwfn,
                                       struct ecore_ptt *p_ptt,
@@ -308,7 +309,7 @@ enum _ecore_status_t ecore_sp_pf_start(struct ecore_hwfn *p_hwfn,
        struct ecore_sp_init_data init_data;
        enum _ecore_status_t rc = ECORE_NOTIMPL;
        u8 page_cnt;
-       int i;
+       u8 i;
 
        /* update initial eq producer */
        ecore_eq_prod_update(p_hwfn,
@@ -343,18 +344,27 @@ enum _ecore_status_t ecore_sp_pf_start(struct ecore_hwfn *p_hwfn,
 
        p_ramrod->outer_tag_config.outer_tag.tci =
                OSAL_CPU_TO_LE16(p_hwfn->hw_info.ovlan);
+       if (OSAL_TEST_BIT(ECORE_MF_8021Q_TAGGING, &p_hwfn->p_dev->mf_bits)) {
+               p_ramrod->outer_tag_config.outer_tag.tpid = ETH_P_8021Q;
+       } else if (OSAL_TEST_BIT(ECORE_MF_8021AD_TAGGING,
+                &p_hwfn->p_dev->mf_bits)) {
+               p_ramrod->outer_tag_config.outer_tag.tpid = ETH_P_8021AD;
+               p_ramrod->outer_tag_config.enable_stag_pri_change = 1;
+       }
+
+       p_ramrod->outer_tag_config.pri_map_valid = 1;
+       for (i = 0; i < ECORE_MAX_PFC_PRIORITIES; i++)
+               p_ramrod->outer_tag_config.inner_to_outer_pri_map[i] = i;
 
+       /* enable_stag_pri_change should be set if port is in BD mode or,
+        * UFP with Host Control mode or, UFP with DCB over base interface.
+        */
        if (OSAL_TEST_BIT(ECORE_MF_UFP_SPECIFIC, &p_hwfn->p_dev->mf_bits)) {
-               p_ramrod->outer_tag_config.outer_tag.tpid =
-                       OSAL_CPU_TO_LE16(ETH_P_8021Q);
-               if (p_hwfn->ufp_info.pri_type == ECORE_UFP_PRI_OS)
+               if ((p_hwfn->ufp_info.pri_type == ECORE_UFP_PRI_OS) ||
+                   (p_hwfn->p_dcbx_info->results.dcbx_enabled))
                        p_ramrod->outer_tag_config.enable_stag_pri_change = 1;
                else
                        p_ramrod->outer_tag_config.enable_stag_pri_change = 0;
-               p_ramrod->outer_tag_config.pri_map_valid = 1;
-               for (i = 0; i < 8; i++)
-                       p_ramrod->outer_tag_config.inner_to_outer_pri_map[i] =
-                                                                         (u8)i;
        }
 
        /* Place EQ address in RAMROD */
@@ -451,7 +461,8 @@ enum _ecore_status_t ecore_sp_pf_update_ufp(struct ecore_hwfn *p_hwfn)
                return rc;
 
        p_ent->ramrod.pf_update.update_enable_stag_pri_change = true;
-       if (p_hwfn->ufp_info.pri_type == ECORE_UFP_PRI_OS)
+       if ((p_hwfn->ufp_info.pri_type == ECORE_UFP_PRI_OS) ||
+           (p_hwfn->p_dcbx_info->results.dcbx_enabled))
                p_ent->ramrod.pf_update.enable_stag_pri_change = 1;
        else
                p_ent->ramrod.pf_update.enable_stag_pri_change = 0;