root/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. i40e_get_pfc_delay
  2. i40e_dcbnl_ieee_getets
  3. i40e_dcbnl_ieee_getpfc
  4. i40e_dcbnl_getdcbx
  5. i40e_dcbnl_get_perm_hw_addr
  6. i40e_dcbnl_set_all
  7. i40e_dcbnl_vsi_del_app
  8. i40e_dcbnl_del_app
  9. i40e_dcbnl_find_app
  10. i40e_dcbnl_flush_apps
  11. i40e_dcbnl_setup

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* Copyright(c) 2013 - 2018 Intel Corporation. */
   3 
   4 #ifdef CONFIG_I40E_DCB
   5 #include "i40e.h"
   6 #include <net/dcbnl.h>
   7 
   8 /**
   9  * i40e_get_pfc_delay - retrieve PFC Link Delay
  10  * @hw: pointer to hardware struct
  11  * @delay: holds the PFC Link delay value
  12  *
  13  * Returns PFC Link Delay from the PRTDCB_GENC.PFCLDA
  14  **/
  15 static void i40e_get_pfc_delay(struct i40e_hw *hw, u16 *delay)
  16 {
  17         u32 val;
  18 
  19         val = rd32(hw, I40E_PRTDCB_GENC);
  20         *delay = (u16)((val & I40E_PRTDCB_GENC_PFCLDA_MASK) >>
  21                        I40E_PRTDCB_GENC_PFCLDA_SHIFT);
  22 }
  23 
  24 /**
  25  * i40e_dcbnl_ieee_getets - retrieve local IEEE ETS configuration
  26  * @dev: the corresponding netdev
  27  * @ets: structure to hold the ETS information
  28  *
  29  * Returns local IEEE ETS configuration
  30  **/
  31 static int i40e_dcbnl_ieee_getets(struct net_device *dev,
  32                                   struct ieee_ets *ets)
  33 {
  34         struct i40e_pf *pf = i40e_netdev_to_pf(dev);
  35         struct i40e_dcbx_config *dcbxcfg;
  36         struct i40e_hw *hw = &pf->hw;
  37 
  38         if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
  39                 return -EINVAL;
  40 
  41         dcbxcfg = &hw->local_dcbx_config;
  42         ets->willing = dcbxcfg->etscfg.willing;
  43         ets->ets_cap = dcbxcfg->etscfg.maxtcs;
  44         ets->cbs = dcbxcfg->etscfg.cbs;
  45         memcpy(ets->tc_tx_bw, dcbxcfg->etscfg.tcbwtable,
  46                 sizeof(ets->tc_tx_bw));
  47         memcpy(ets->tc_rx_bw, dcbxcfg->etscfg.tcbwtable,
  48                 sizeof(ets->tc_rx_bw));
  49         memcpy(ets->tc_tsa, dcbxcfg->etscfg.tsatable,
  50                 sizeof(ets->tc_tsa));
  51         memcpy(ets->prio_tc, dcbxcfg->etscfg.prioritytable,
  52                 sizeof(ets->prio_tc));
  53         memcpy(ets->tc_reco_bw, dcbxcfg->etsrec.tcbwtable,
  54                 sizeof(ets->tc_reco_bw));
  55         memcpy(ets->tc_reco_tsa, dcbxcfg->etsrec.tsatable,
  56                 sizeof(ets->tc_reco_tsa));
  57         memcpy(ets->reco_prio_tc, dcbxcfg->etscfg.prioritytable,
  58                 sizeof(ets->reco_prio_tc));
  59 
  60         return 0;
  61 }
  62 
  63 /**
  64  * i40e_dcbnl_ieee_getpfc - retrieve local IEEE PFC configuration
  65  * @dev: the corresponding netdev
  66  * @pfc: structure to hold the PFC information
  67  *
  68  * Returns local IEEE PFC configuration
  69  **/
  70 static int i40e_dcbnl_ieee_getpfc(struct net_device *dev,
  71                                   struct ieee_pfc *pfc)
  72 {
  73         struct i40e_pf *pf = i40e_netdev_to_pf(dev);
  74         struct i40e_dcbx_config *dcbxcfg;
  75         struct i40e_hw *hw = &pf->hw;
  76         int i;
  77 
  78         if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
  79                 return -EINVAL;
  80 
  81         dcbxcfg = &hw->local_dcbx_config;
  82         pfc->pfc_cap = dcbxcfg->pfc.pfccap;
  83         pfc->pfc_en = dcbxcfg->pfc.pfcenable;
  84         pfc->mbc = dcbxcfg->pfc.mbc;
  85         i40e_get_pfc_delay(hw, &pfc->delay);
  86 
  87         /* Get Requests/Indicatiosn */
  88         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
  89                 pfc->requests[i] = pf->stats.priority_xoff_tx[i];
  90                 pfc->indications[i] = pf->stats.priority_xoff_rx[i];
  91         }
  92 
  93         return 0;
  94 }
  95 
  96 /**
  97  * i40e_dcbnl_getdcbx - retrieve current DCBx capability
  98  * @dev: the corresponding netdev
  99  *
 100  * Returns DCBx capability features
 101  **/
 102 static u8 i40e_dcbnl_getdcbx(struct net_device *dev)
 103 {
 104         struct i40e_pf *pf = i40e_netdev_to_pf(dev);
 105 
 106         return pf->dcbx_cap;
 107 }
 108 
 109 /**
 110  * i40e_dcbnl_get_perm_hw_addr - MAC address used by DCBx
 111  * @dev: the corresponding netdev
 112  * @perm_addr: buffer to store the MAC address
 113  *
 114  * Returns the SAN MAC address used for LLDP exchange
 115  **/
 116 static void i40e_dcbnl_get_perm_hw_addr(struct net_device *dev,
 117                                         u8 *perm_addr)
 118 {
 119         struct i40e_pf *pf = i40e_netdev_to_pf(dev);
 120         int i, j;
 121 
 122         memset(perm_addr, 0xff, MAX_ADDR_LEN);
 123 
 124         for (i = 0; i < dev->addr_len; i++)
 125                 perm_addr[i] = pf->hw.mac.perm_addr[i];
 126 
 127         for (j = 0; j < dev->addr_len; j++, i++)
 128                 perm_addr[i] = pf->hw.mac.san_addr[j];
 129 }
 130 
 131 static const struct dcbnl_rtnl_ops dcbnl_ops = {
 132         .ieee_getets    = i40e_dcbnl_ieee_getets,
 133         .ieee_getpfc    = i40e_dcbnl_ieee_getpfc,
 134         .getdcbx        = i40e_dcbnl_getdcbx,
 135         .getpermhwaddr  = i40e_dcbnl_get_perm_hw_addr,
 136 };
 137 
 138 /**
 139  * i40e_dcbnl_set_all - set all the apps and ieee data from DCBx config
 140  * @vsi: the corresponding vsi
 141  *
 142  * Set up all the IEEE APPs in the DCBNL App Table and generate event for
 143  * other settings
 144  **/
 145 void i40e_dcbnl_set_all(struct i40e_vsi *vsi)
 146 {
 147         struct net_device *dev = vsi->netdev;
 148         struct i40e_pf *pf = i40e_netdev_to_pf(dev);
 149         struct i40e_dcbx_config *dcbxcfg;
 150         struct i40e_hw *hw = &pf->hw;
 151         struct dcb_app sapp;
 152         u8 prio, tc_map;
 153         int i;
 154 
 155         /* DCB not enabled */
 156         if (!(pf->flags & I40E_FLAG_DCB_ENABLED))
 157                 return;
 158 
 159         /* MFP mode but not an iSCSI PF so return */
 160         if ((pf->flags & I40E_FLAG_MFP_ENABLED) && !(pf->hw.func_caps.iscsi))
 161                 return;
 162 
 163         dcbxcfg = &hw->local_dcbx_config;
 164 
 165         /* Set up all the App TLVs if DCBx is negotiated */
 166         for (i = 0; i < dcbxcfg->numapps; i++) {
 167                 prio = dcbxcfg->app[i].priority;
 168                 tc_map = BIT(dcbxcfg->etscfg.prioritytable[prio]);
 169 
 170                 /* Add APP only if the TC is enabled for this VSI */
 171                 if (tc_map & vsi->tc_config.enabled_tc) {
 172                         sapp.selector = dcbxcfg->app[i].selector;
 173                         sapp.protocol = dcbxcfg->app[i].protocolid;
 174                         sapp.priority = prio;
 175                         dcb_ieee_setapp(dev, &sapp);
 176                 }
 177         }
 178 
 179         /* Notify user-space of the changes */
 180         dcbnl_ieee_notify(dev, RTM_SETDCB, DCB_CMD_IEEE_SET, 0, 0);
 181 }
 182 
 183 /**
 184  * i40e_dcbnl_vsi_del_app - Delete APP for given VSI
 185  * @vsi: the corresponding vsi
 186  * @app: APP to delete
 187  *
 188  * Delete given APP from the DCBNL APP table for given
 189  * VSI
 190  **/
 191 static int i40e_dcbnl_vsi_del_app(struct i40e_vsi *vsi,
 192                                   struct i40e_dcb_app_priority_table *app)
 193 {
 194         struct net_device *dev = vsi->netdev;
 195         struct dcb_app sapp;
 196 
 197         if (!dev)
 198                 return -EINVAL;
 199 
 200         sapp.selector = app->selector;
 201         sapp.protocol = app->protocolid;
 202         sapp.priority = app->priority;
 203         return dcb_ieee_delapp(dev, &sapp);
 204 }
 205 
 206 /**
 207  * i40e_dcbnl_del_app - Delete APP on all VSIs
 208  * @pf: the corresponding PF
 209  * @app: APP to delete
 210  *
 211  * Delete given APP from all the VSIs for given PF
 212  **/
 213 static void i40e_dcbnl_del_app(struct i40e_pf *pf,
 214                                struct i40e_dcb_app_priority_table *app)
 215 {
 216         int v, err;
 217 
 218         for (v = 0; v < pf->num_alloc_vsi; v++) {
 219                 if (pf->vsi[v] && pf->vsi[v]->netdev) {
 220                         err = i40e_dcbnl_vsi_del_app(pf->vsi[v], app);
 221                         dev_dbg(&pf->pdev->dev, "Deleting app for VSI seid=%d err=%d sel=%d proto=0x%x prio=%d\n",
 222                                 pf->vsi[v]->seid, err, app->selector,
 223                                 app->protocolid, app->priority);
 224                 }
 225         }
 226 }
 227 
 228 /**
 229  * i40e_dcbnl_find_app - Search APP in given DCB config
 230  * @cfg: DCBX configuration data
 231  * @app: APP to search for
 232  *
 233  * Find given APP in the DCB configuration
 234  **/
 235 static bool i40e_dcbnl_find_app(struct i40e_dcbx_config *cfg,
 236                                 struct i40e_dcb_app_priority_table *app)
 237 {
 238         int i;
 239 
 240         for (i = 0; i < cfg->numapps; i++) {
 241                 if (app->selector == cfg->app[i].selector &&
 242                     app->protocolid == cfg->app[i].protocolid &&
 243                     app->priority == cfg->app[i].priority)
 244                         return true;
 245         }
 246 
 247         return false;
 248 }
 249 
 250 /**
 251  * i40e_dcbnl_flush_apps - Delete all removed APPs
 252  * @pf: the corresponding PF
 253  * @old_cfg: old DCBX configuration data
 254  * @new_cfg: new DCBX configuration data
 255  *
 256  * Find and delete all APPs that are not present in the passed
 257  * DCB configuration
 258  **/
 259 void i40e_dcbnl_flush_apps(struct i40e_pf *pf,
 260                            struct i40e_dcbx_config *old_cfg,
 261                            struct i40e_dcbx_config *new_cfg)
 262 {
 263         struct i40e_dcb_app_priority_table app;
 264         int i;
 265 
 266         /* MFP mode but not an iSCSI PF so return */
 267         if ((pf->flags & I40E_FLAG_MFP_ENABLED) && !(pf->hw.func_caps.iscsi))
 268                 return;
 269 
 270         for (i = 0; i < old_cfg->numapps; i++) {
 271                 app = old_cfg->app[i];
 272                 /* The APP is not available anymore delete it */
 273                 if (!i40e_dcbnl_find_app(new_cfg, &app))
 274                         i40e_dcbnl_del_app(pf, &app);
 275         }
 276 }
 277 
 278 /**
 279  * i40e_dcbnl_setup - DCBNL setup
 280  * @vsi: the corresponding vsi
 281  *
 282  * Set up DCBNL ops and initial APP TLVs
 283  **/
 284 void i40e_dcbnl_setup(struct i40e_vsi *vsi)
 285 {
 286         struct net_device *dev = vsi->netdev;
 287         struct i40e_pf *pf = i40e_netdev_to_pf(dev);
 288 
 289         /* Not DCB capable */
 290         if (!(pf->flags & I40E_FLAG_DCB_CAPABLE))
 291                 return;
 292 
 293         dev->dcbnl_ops = &dcbnl_ops;
 294 
 295         /* Set initial IEEE DCB settings */
 296         i40e_dcbnl_set_all(vsi);
 297 }
 298 #endif /* CONFIG_I40E_DCB */

/* [<][>][^][v][top][bottom][index][help] */