i40e: Support for NPAR iSCSI partition with DCB
authorNeerav Parikh <neerav.parikh@intel.com>
Sun, 14 Dec 2014 01:55:16 +0000 (01:55 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Fri, 16 Jan 2015 13:21:04 +0000 (05:21 -0800)
Add parsing and reporting of iSCSI capability for a given device or
function.

Also add support for iSCSI partition type with DCB in NPAR mode.
In this mode it is expected that software would configure both the LAN
and iSCSI traffic classes for the iSCSI partition; whereas all the NIC
type partitions will use LAN TC (TC0) only.
Hence, the patch enables querying of DCB configuration in MFP mode and
configures TCs for iSCSI partition type.

Though NIC type partitions may not have more than 1 TC enabled for them
the port may have multiple TCs enabled and hence I40E_FLAG_DCB_ENABLED
will be set/reset on all the partitions based on number of TCs on the
port. This is required as in DCB environment it is expected that all
traffic will be priority tagged.

Change-ID: I8c6e1cfd46c46d8a39c57d9020d9ff8d42ed8a7d
Signed-off-by: Neerav Parikh <neerav.parikh@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40e/i40e_common.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_type.h
drivers/net/ethernet/intel/i40evf/i40e_type.h

index 4f4d9d16bddbe9d871e20d4261de69c7e51f7440..5669bfa39f146bff7f52277468fbcd77348ee011 100644 (file)
@@ -2360,6 +2360,7 @@ i40e_aq_erase_nvm_exit:
 #define I40E_DEV_FUNC_CAP_VSI          0x17
 #define I40E_DEV_FUNC_CAP_DCB          0x18
 #define I40E_DEV_FUNC_CAP_FCOE         0x21
+#define I40E_DEV_FUNC_CAP_ISCSI                0x22
 #define I40E_DEV_FUNC_CAP_RSS          0x40
 #define I40E_DEV_FUNC_CAP_RX_QUEUES    0x41
 #define I40E_DEV_FUNC_CAP_TX_QUEUES    0x42
@@ -2459,6 +2460,10 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
                        if (number == 1)
                                p->fcoe = true;
                        break;
+               case I40E_DEV_FUNC_CAP_ISCSI:
+                       if (number == 1)
+                               p->iscsi = true;
+                       break;
                case I40E_DEV_FUNC_CAP_RSS:
                        p->rss = true;
                        p->rss_table_size = number;
index d7efc1cd0732f5832b65adb58818d7e1255a3c90..f1256f96944d603e046f7d8305202b7aeddb998d 100644 (file)
@@ -4001,6 +4001,35 @@ static int i40e_pf_wait_txq_disabled(struct i40e_pf *pf)
 }
 
 #endif
+/**
+ * i40e_get_iscsi_tc_map - Return TC map for iSCSI APP
+ * @pf: pointer to pf
+ *
+ * Get TC map for ISCSI PF type that will include iSCSI TC
+ * and LAN TC.
+ **/
+static u8 i40e_get_iscsi_tc_map(struct i40e_pf *pf)
+{
+       struct i40e_dcb_app_priority_table app;
+       struct i40e_hw *hw = &pf->hw;
+       u8 enabled_tc = 1; /* TC0 is always enabled */
+       u8 tc, i;
+       /* Get the iSCSI APP TLV */
+       struct i40e_dcbx_config *dcbcfg = &hw->local_dcbx_config;
+
+       for (i = 0; i < dcbcfg->numapps; i++) {
+               app = dcbcfg->app[i];
+               if (app.selector == I40E_APP_SEL_TCPIP &&
+                   app.protocolid == I40E_APP_PROTOID_ISCSI) {
+                       tc = dcbcfg->etscfg.prioritytable[app.priority];
+                       enabled_tc |= (1 << tc);
+                       break;
+               }
+       }
+
+       return enabled_tc;
+}
+
 /**
  * i40e_dcb_get_num_tc -  Get the number of TCs from DCBx config
  * @dcbcfg: the corresponding DCBx configuration structure
@@ -4064,18 +4093,23 @@ static u8 i40e_pf_get_num_tc(struct i40e_pf *pf)
        if (!(pf->flags & I40E_FLAG_DCB_ENABLED))
                return 1;
 
+       /* SFP mode will be enabled for all TCs on port */
+       if (!(pf->flags & I40E_FLAG_MFP_ENABLED))
+               return i40e_dcb_get_num_tc(dcbcfg);
+
        /* MFP mode return count of enabled TCs for this PF */
-       if (pf->flags & I40E_FLAG_MFP_ENABLED) {
+       if (pf->hw.func_caps.iscsi)
+               enabled_tc =  i40e_get_iscsi_tc_map(pf);
+       else
                enabled_tc = pf->hw.func_caps.enabled_tcmap;
-               for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
-                       if (enabled_tc & (1 << i))
-                               num_tc++;
-               }
-               return num_tc;
-       }
 
-       /* SFP mode will be enabled for all TCs on port */
-       return i40e_dcb_get_num_tc(dcbcfg);
+       /* At least have TC0 */
+       enabled_tc = (enabled_tc ? enabled_tc : 0x1);
+       for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
+               if (enabled_tc & (1 << i))
+                       num_tc++;
+       }
+       return num_tc;
 }
 
 /**
@@ -4113,12 +4147,15 @@ static u8 i40e_pf_get_tc_map(struct i40e_pf *pf)
        if (!(pf->flags & I40E_FLAG_DCB_ENABLED))
                return i40e_pf_get_default_tc(pf);
 
-       /* MFP mode will have enabled TCs set by FW */
-       if (pf->flags & I40E_FLAG_MFP_ENABLED)
-               return pf->hw.func_caps.enabled_tcmap;
-
        /* SFP mode we want PF to be enabled for all TCs */
-       return i40e_dcb_get_enabled_tc(&pf->hw.local_dcbx_config);
+       if (!(pf->flags & I40E_FLAG_MFP_ENABLED))
+               return i40e_dcb_get_enabled_tc(&pf->hw.local_dcbx_config);
+
+       /* MPF enabled and iSCSI PF type */
+       if (pf->hw.func_caps.iscsi)
+               return i40e_get_iscsi_tc_map(pf);
+       else
+               return pf->hw.func_caps.enabled_tcmap;
 }
 
 /**
@@ -4508,9 +4545,6 @@ static int i40e_init_pf_dcb(struct i40e_pf *pf)
        struct i40e_hw *hw = &pf->hw;
        int err = 0;
 
-       if (pf->hw.func_caps.npar_enable)
-               goto out;
-
        /* Get the initial DCB configuration */
        err = i40e_init_dcb(hw);
        if (!err) {
@@ -7784,7 +7818,8 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
                enabled_tc = i40e_pf_get_tc_map(pf);
 
                /* MFP mode setup queue map and update VSI */
-               if (pf->flags & I40E_FLAG_MFP_ENABLED) {
+               if ((pf->flags & I40E_FLAG_MFP_ENABLED) &&
+                   !(pf->hw.func_caps.iscsi)) { /* NIC type PF */
                        memset(&ctxt, 0, sizeof(ctxt));
                        ctxt.seid = pf->main_vsi_seid;
                        ctxt.pf_num = pf->hw.pf_id;
@@ -7805,6 +7840,8 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
                        /* Default/Main VSI is only enabled for TC0
                         * reconfigure it to enable all TCs that are
                         * available on the port in SFP mode.
+                        * For MFP case the iSCSI PF would use this
+                        * flow to enable LAN+iSCSI TC.
                         */
                        ret = i40e_vsi_config_tc(vsi, enabled_tc);
                        if (ret) {
index ff121fe98dd4d5282f2f4428ceab07a5158515d3..e9901ef06a6361f9e2a1f56004764eb51ed60513 100644 (file)
@@ -211,6 +211,7 @@ struct i40e_hw_capabilities {
        bool evb_802_1_qbh; /* Bridge Port Extension */
        bool dcb;
        bool fcoe;
+       bool iscsi; /* Indicates iSCSI enabled */
        bool mfp_mode_1;
        bool mgmt_cem;
        bool ieee_1588;
index d1c2b5a6e6482ac0a665a2caaa890a6c616ff888..3d0fdaab5cc8404e242b8ecfb0e12e12198f41cc 100644 (file)
@@ -211,6 +211,7 @@ struct i40e_hw_capabilities {
        bool evb_802_1_qbh; /* Bridge Port Extension */
        bool dcb;
        bool fcoe;
+       bool iscsi; /* Indicates iSCSI enabled */
        bool mfp_mode_1;
        bool mgmt_cem;
        bool ieee_1588;