1ae06c70bSJeff Kirsher // SPDX-License-Identifier: GPL-2.0
25effa78eSArkadiusz Kubalewski /* Copyright(c) 2013 - 2021 Intel Corporation. */
34e3b35b0SNeerav Parikh
44e3b35b0SNeerav Parikh #ifdef CONFIG_I40E_DCB
54e3b35b0SNeerav Parikh #include <net/dcbnl.h>
6*e77220eeSIvan Vecera #include "i40e.h"
74e3b35b0SNeerav Parikh
85effa78eSArkadiusz Kubalewski #define I40E_DCBNL_STATUS_SUCCESS 0
95effa78eSArkadiusz Kubalewski #define I40E_DCBNL_STATUS_ERROR 1
105effa78eSArkadiusz Kubalewski static bool i40e_dcbnl_find_app(struct i40e_dcbx_config *cfg,
115effa78eSArkadiusz Kubalewski struct i40e_dcb_app_priority_table *app);
124e3b35b0SNeerav Parikh /**
134e3b35b0SNeerav Parikh * i40e_get_pfc_delay - retrieve PFC Link Delay
144e3b35b0SNeerav Parikh * @hw: pointer to hardware struct
154e3b35b0SNeerav Parikh * @delay: holds the PFC Link delay value
164e3b35b0SNeerav Parikh *
174e3b35b0SNeerav Parikh * Returns PFC Link Delay from the PRTDCB_GENC.PFCLDA
184e3b35b0SNeerav Parikh **/
i40e_get_pfc_delay(struct i40e_hw * hw,u16 * delay)194e3b35b0SNeerav Parikh static void i40e_get_pfc_delay(struct i40e_hw *hw, u16 *delay)
204e3b35b0SNeerav Parikh {
214e3b35b0SNeerav Parikh u32 val;
224e3b35b0SNeerav Parikh
234e3b35b0SNeerav Parikh val = rd32(hw, I40E_PRTDCB_GENC);
24de78fc5aSShannon Nelson *delay = (u16)((val & I40E_PRTDCB_GENC_PFCLDA_MASK) >>
254e3b35b0SNeerav Parikh I40E_PRTDCB_GENC_PFCLDA_SHIFT);
264e3b35b0SNeerav Parikh }
274e3b35b0SNeerav Parikh
284e3b35b0SNeerav Parikh /**
294e3b35b0SNeerav Parikh * i40e_dcbnl_ieee_getets - retrieve local IEEE ETS configuration
30f5254429SJacob Keller * @dev: the corresponding netdev
314e3b35b0SNeerav Parikh * @ets: structure to hold the ETS information
324e3b35b0SNeerav Parikh *
334e3b35b0SNeerav Parikh * Returns local IEEE ETS configuration
344e3b35b0SNeerav Parikh **/
i40e_dcbnl_ieee_getets(struct net_device * dev,struct ieee_ets * ets)354e3b35b0SNeerav Parikh static int i40e_dcbnl_ieee_getets(struct net_device *dev,
364e3b35b0SNeerav Parikh struct ieee_ets *ets)
374e3b35b0SNeerav Parikh {
384e3b35b0SNeerav Parikh struct i40e_pf *pf = i40e_netdev_to_pf(dev);
394e3b35b0SNeerav Parikh struct i40e_dcbx_config *dcbxcfg;
404e3b35b0SNeerav Parikh
414e3b35b0SNeerav Parikh if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
424e3b35b0SNeerav Parikh return -EINVAL;
434e3b35b0SNeerav Parikh
445effa78eSArkadiusz Kubalewski dcbxcfg = &pf->hw.local_dcbx_config;
454e3b35b0SNeerav Parikh ets->willing = dcbxcfg->etscfg.willing;
465effa78eSArkadiusz Kubalewski ets->ets_cap = I40E_MAX_TRAFFIC_CLASS;
474e3b35b0SNeerav Parikh ets->cbs = dcbxcfg->etscfg.cbs;
484e3b35b0SNeerav Parikh memcpy(ets->tc_tx_bw, dcbxcfg->etscfg.tcbwtable,
494e3b35b0SNeerav Parikh sizeof(ets->tc_tx_bw));
504e3b35b0SNeerav Parikh memcpy(ets->tc_rx_bw, dcbxcfg->etscfg.tcbwtable,
514e3b35b0SNeerav Parikh sizeof(ets->tc_rx_bw));
524e3b35b0SNeerav Parikh memcpy(ets->tc_tsa, dcbxcfg->etscfg.tsatable,
534e3b35b0SNeerav Parikh sizeof(ets->tc_tsa));
544e3b35b0SNeerav Parikh memcpy(ets->prio_tc, dcbxcfg->etscfg.prioritytable,
554e3b35b0SNeerav Parikh sizeof(ets->prio_tc));
564e3b35b0SNeerav Parikh memcpy(ets->tc_reco_bw, dcbxcfg->etsrec.tcbwtable,
574e3b35b0SNeerav Parikh sizeof(ets->tc_reco_bw));
584e3b35b0SNeerav Parikh memcpy(ets->tc_reco_tsa, dcbxcfg->etsrec.tsatable,
594e3b35b0SNeerav Parikh sizeof(ets->tc_reco_tsa));
604e3b35b0SNeerav Parikh memcpy(ets->reco_prio_tc, dcbxcfg->etscfg.prioritytable,
614e3b35b0SNeerav Parikh sizeof(ets->reco_prio_tc));
624e3b35b0SNeerav Parikh
634e3b35b0SNeerav Parikh return 0;
644e3b35b0SNeerav Parikh }
654e3b35b0SNeerav Parikh
664e3b35b0SNeerav Parikh /**
674e3b35b0SNeerav Parikh * i40e_dcbnl_ieee_getpfc - retrieve local IEEE PFC configuration
68f5254429SJacob Keller * @dev: the corresponding netdev
69f5254429SJacob Keller * @pfc: structure to hold the PFC information
704e3b35b0SNeerav Parikh *
714e3b35b0SNeerav Parikh * Returns local IEEE PFC configuration
724e3b35b0SNeerav Parikh **/
i40e_dcbnl_ieee_getpfc(struct net_device * dev,struct ieee_pfc * pfc)734e3b35b0SNeerav Parikh static int i40e_dcbnl_ieee_getpfc(struct net_device *dev,
744e3b35b0SNeerav Parikh struct ieee_pfc *pfc)
754e3b35b0SNeerav Parikh {
764e3b35b0SNeerav Parikh struct i40e_pf *pf = i40e_netdev_to_pf(dev);
774e3b35b0SNeerav Parikh struct i40e_dcbx_config *dcbxcfg;
784e3b35b0SNeerav Parikh struct i40e_hw *hw = &pf->hw;
794e3b35b0SNeerav Parikh int i;
804e3b35b0SNeerav Parikh
814e3b35b0SNeerav Parikh if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
824e3b35b0SNeerav Parikh return -EINVAL;
834e3b35b0SNeerav Parikh
844e3b35b0SNeerav Parikh dcbxcfg = &hw->local_dcbx_config;
854e3b35b0SNeerav Parikh pfc->pfc_cap = dcbxcfg->pfc.pfccap;
864e3b35b0SNeerav Parikh pfc->pfc_en = dcbxcfg->pfc.pfcenable;
874e3b35b0SNeerav Parikh pfc->mbc = dcbxcfg->pfc.mbc;
884e3b35b0SNeerav Parikh i40e_get_pfc_delay(hw, &pfc->delay);
894e3b35b0SNeerav Parikh
905effa78eSArkadiusz Kubalewski /* Get Requests/Indications */
914e3b35b0SNeerav Parikh for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
924e3b35b0SNeerav Parikh pfc->requests[i] = pf->stats.priority_xoff_tx[i];
934e3b35b0SNeerav Parikh pfc->indications[i] = pf->stats.priority_xoff_rx[i];
944e3b35b0SNeerav Parikh }
954e3b35b0SNeerav Parikh
964e3b35b0SNeerav Parikh return 0;
974e3b35b0SNeerav Parikh }
984e3b35b0SNeerav Parikh
994e3b35b0SNeerav Parikh /**
1005effa78eSArkadiusz Kubalewski * i40e_dcbnl_ieee_setets - set IEEE ETS configuration
1015effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
1025effa78eSArkadiusz Kubalewski * @ets: structure to hold the ETS information
1035effa78eSArkadiusz Kubalewski *
1045effa78eSArkadiusz Kubalewski * Set IEEE ETS configuration
1055effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_ieee_setets(struct net_device * netdev,struct ieee_ets * ets)1065effa78eSArkadiusz Kubalewski static int i40e_dcbnl_ieee_setets(struct net_device *netdev,
1075effa78eSArkadiusz Kubalewski struct ieee_ets *ets)
1085effa78eSArkadiusz Kubalewski {
1095effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
1105effa78eSArkadiusz Kubalewski struct i40e_dcbx_config *old_cfg;
1115effa78eSArkadiusz Kubalewski int i, ret;
1125effa78eSArkadiusz Kubalewski
1135effa78eSArkadiusz Kubalewski if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
1145effa78eSArkadiusz Kubalewski (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
1155effa78eSArkadiusz Kubalewski return -EINVAL;
1165effa78eSArkadiusz Kubalewski
1175effa78eSArkadiusz Kubalewski old_cfg = &pf->hw.local_dcbx_config;
1185effa78eSArkadiusz Kubalewski /* Copy current config into temp */
1195effa78eSArkadiusz Kubalewski pf->tmp_cfg = *old_cfg;
1205effa78eSArkadiusz Kubalewski
1215effa78eSArkadiusz Kubalewski /* Update the ETS configuration for temp */
1225effa78eSArkadiusz Kubalewski pf->tmp_cfg.etscfg.willing = ets->willing;
1235effa78eSArkadiusz Kubalewski pf->tmp_cfg.etscfg.maxtcs = I40E_MAX_TRAFFIC_CLASS;
1245effa78eSArkadiusz Kubalewski pf->tmp_cfg.etscfg.cbs = ets->cbs;
1255effa78eSArkadiusz Kubalewski for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
1265effa78eSArkadiusz Kubalewski pf->tmp_cfg.etscfg.tcbwtable[i] = ets->tc_tx_bw[i];
1275effa78eSArkadiusz Kubalewski pf->tmp_cfg.etscfg.tsatable[i] = ets->tc_tsa[i];
1285effa78eSArkadiusz Kubalewski pf->tmp_cfg.etscfg.prioritytable[i] = ets->prio_tc[i];
1295effa78eSArkadiusz Kubalewski pf->tmp_cfg.etsrec.tcbwtable[i] = ets->tc_reco_bw[i];
1305effa78eSArkadiusz Kubalewski pf->tmp_cfg.etsrec.tsatable[i] = ets->tc_reco_tsa[i];
1315effa78eSArkadiusz Kubalewski pf->tmp_cfg.etsrec.prioritytable[i] = ets->reco_prio_tc[i];
1325effa78eSArkadiusz Kubalewski }
1335effa78eSArkadiusz Kubalewski
1345effa78eSArkadiusz Kubalewski /* Commit changes to HW */
1355effa78eSArkadiusz Kubalewski ret = i40e_hw_dcb_config(pf, &pf->tmp_cfg);
1365effa78eSArkadiusz Kubalewski if (ret) {
1375effa78eSArkadiusz Kubalewski dev_info(&pf->pdev->dev,
138d5ba1842SJan Sokolowski "Failed setting DCB ETS configuration err %pe aq_err %s\n",
139d5ba1842SJan Sokolowski ERR_PTR(ret),
1405effa78eSArkadiusz Kubalewski i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
1415effa78eSArkadiusz Kubalewski return -EINVAL;
1425effa78eSArkadiusz Kubalewski }
1435effa78eSArkadiusz Kubalewski
1445effa78eSArkadiusz Kubalewski return 0;
1455effa78eSArkadiusz Kubalewski }
1465effa78eSArkadiusz Kubalewski
1475effa78eSArkadiusz Kubalewski /**
1485effa78eSArkadiusz Kubalewski * i40e_dcbnl_ieee_setpfc - set local IEEE PFC configuration
1495effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
1505effa78eSArkadiusz Kubalewski * @pfc: structure to hold the PFC information
1515effa78eSArkadiusz Kubalewski *
1525effa78eSArkadiusz Kubalewski * Sets local IEEE PFC configuration
1535effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_ieee_setpfc(struct net_device * netdev,struct ieee_pfc * pfc)1545effa78eSArkadiusz Kubalewski static int i40e_dcbnl_ieee_setpfc(struct net_device *netdev,
1555effa78eSArkadiusz Kubalewski struct ieee_pfc *pfc)
1565effa78eSArkadiusz Kubalewski {
1575effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
1585effa78eSArkadiusz Kubalewski struct i40e_dcbx_config *old_cfg;
1595effa78eSArkadiusz Kubalewski int ret;
1605effa78eSArkadiusz Kubalewski
1615effa78eSArkadiusz Kubalewski if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
1625effa78eSArkadiusz Kubalewski (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
1635effa78eSArkadiusz Kubalewski return -EINVAL;
1645effa78eSArkadiusz Kubalewski
1655effa78eSArkadiusz Kubalewski old_cfg = &pf->hw.local_dcbx_config;
1665effa78eSArkadiusz Kubalewski /* Copy current config into temp */
1675effa78eSArkadiusz Kubalewski pf->tmp_cfg = *old_cfg;
1685effa78eSArkadiusz Kubalewski if (pfc->pfc_cap)
1695effa78eSArkadiusz Kubalewski pf->tmp_cfg.pfc.pfccap = pfc->pfc_cap;
1705effa78eSArkadiusz Kubalewski else
1715effa78eSArkadiusz Kubalewski pf->tmp_cfg.pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
1725effa78eSArkadiusz Kubalewski pf->tmp_cfg.pfc.pfcenable = pfc->pfc_en;
1735effa78eSArkadiusz Kubalewski
1745effa78eSArkadiusz Kubalewski ret = i40e_hw_dcb_config(pf, &pf->tmp_cfg);
1755effa78eSArkadiusz Kubalewski if (ret) {
1765effa78eSArkadiusz Kubalewski dev_info(&pf->pdev->dev,
177d5ba1842SJan Sokolowski "Failed setting DCB PFC configuration err %pe aq_err %s\n",
178d5ba1842SJan Sokolowski ERR_PTR(ret),
1795effa78eSArkadiusz Kubalewski i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
1805effa78eSArkadiusz Kubalewski return -EINVAL;
1815effa78eSArkadiusz Kubalewski }
1825effa78eSArkadiusz Kubalewski
1835effa78eSArkadiusz Kubalewski return 0;
1845effa78eSArkadiusz Kubalewski }
1855effa78eSArkadiusz Kubalewski
1865effa78eSArkadiusz Kubalewski /**
1875effa78eSArkadiusz Kubalewski * i40e_dcbnl_ieee_setapp - set local IEEE App configuration
1885effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
1895effa78eSArkadiusz Kubalewski * @app: structure to hold the Application information
1905effa78eSArkadiusz Kubalewski *
1915effa78eSArkadiusz Kubalewski * Sets local IEEE App configuration
1925effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_ieee_setapp(struct net_device * netdev,struct dcb_app * app)1935effa78eSArkadiusz Kubalewski static int i40e_dcbnl_ieee_setapp(struct net_device *netdev,
1945effa78eSArkadiusz Kubalewski struct dcb_app *app)
1955effa78eSArkadiusz Kubalewski {
1965effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
1975effa78eSArkadiusz Kubalewski struct i40e_dcb_app_priority_table new_app;
1985effa78eSArkadiusz Kubalewski struct i40e_dcbx_config *old_cfg;
1995effa78eSArkadiusz Kubalewski int ret;
2005effa78eSArkadiusz Kubalewski
2015effa78eSArkadiusz Kubalewski if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
2025effa78eSArkadiusz Kubalewski (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
2035effa78eSArkadiusz Kubalewski return -EINVAL;
2045effa78eSArkadiusz Kubalewski
2055effa78eSArkadiusz Kubalewski old_cfg = &pf->hw.local_dcbx_config;
2065effa78eSArkadiusz Kubalewski if (old_cfg->numapps == I40E_DCBX_MAX_APPS)
2075effa78eSArkadiusz Kubalewski return -EINVAL;
2085effa78eSArkadiusz Kubalewski
2095effa78eSArkadiusz Kubalewski ret = dcb_ieee_setapp(netdev, app);
2105effa78eSArkadiusz Kubalewski if (ret)
2115effa78eSArkadiusz Kubalewski return ret;
2125effa78eSArkadiusz Kubalewski
2135effa78eSArkadiusz Kubalewski new_app.selector = app->selector;
2145effa78eSArkadiusz Kubalewski new_app.protocolid = app->protocol;
2155effa78eSArkadiusz Kubalewski new_app.priority = app->priority;
2165effa78eSArkadiusz Kubalewski /* Already internally available */
2175effa78eSArkadiusz Kubalewski if (i40e_dcbnl_find_app(old_cfg, &new_app))
2185effa78eSArkadiusz Kubalewski return 0;
2195effa78eSArkadiusz Kubalewski
2205effa78eSArkadiusz Kubalewski /* Copy current config into temp */
2215effa78eSArkadiusz Kubalewski pf->tmp_cfg = *old_cfg;
2225effa78eSArkadiusz Kubalewski /* Add the app */
2235effa78eSArkadiusz Kubalewski pf->tmp_cfg.app[pf->tmp_cfg.numapps++] = new_app;
2245effa78eSArkadiusz Kubalewski
2255effa78eSArkadiusz Kubalewski ret = i40e_hw_dcb_config(pf, &pf->tmp_cfg);
2265effa78eSArkadiusz Kubalewski if (ret) {
2275effa78eSArkadiusz Kubalewski dev_info(&pf->pdev->dev,
228d5ba1842SJan Sokolowski "Failed setting DCB configuration err %pe aq_err %s\n",
229d5ba1842SJan Sokolowski ERR_PTR(ret),
2305effa78eSArkadiusz Kubalewski i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
2315effa78eSArkadiusz Kubalewski return -EINVAL;
2325effa78eSArkadiusz Kubalewski }
2335effa78eSArkadiusz Kubalewski
2345effa78eSArkadiusz Kubalewski return 0;
2355effa78eSArkadiusz Kubalewski }
2365effa78eSArkadiusz Kubalewski
2375effa78eSArkadiusz Kubalewski /**
2385effa78eSArkadiusz Kubalewski * i40e_dcbnl_ieee_delapp - delete local IEEE App configuration
2395effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
2405effa78eSArkadiusz Kubalewski * @app: structure to hold the Application information
2415effa78eSArkadiusz Kubalewski *
2425effa78eSArkadiusz Kubalewski * Deletes local IEEE App configuration other than the first application
2435effa78eSArkadiusz Kubalewski * required by firmware
2445effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_ieee_delapp(struct net_device * netdev,struct dcb_app * app)2455effa78eSArkadiusz Kubalewski static int i40e_dcbnl_ieee_delapp(struct net_device *netdev,
2465effa78eSArkadiusz Kubalewski struct dcb_app *app)
2475effa78eSArkadiusz Kubalewski {
2485effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
2495effa78eSArkadiusz Kubalewski struct i40e_dcbx_config *old_cfg;
2505effa78eSArkadiusz Kubalewski int i, j, ret;
2515effa78eSArkadiusz Kubalewski
2525effa78eSArkadiusz Kubalewski if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
2535effa78eSArkadiusz Kubalewski (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
2545effa78eSArkadiusz Kubalewski return -EINVAL;
2555effa78eSArkadiusz Kubalewski
2565effa78eSArkadiusz Kubalewski ret = dcb_ieee_delapp(netdev, app);
2575effa78eSArkadiusz Kubalewski if (ret)
2585effa78eSArkadiusz Kubalewski return ret;
2595effa78eSArkadiusz Kubalewski
2605effa78eSArkadiusz Kubalewski old_cfg = &pf->hw.local_dcbx_config;
2615effa78eSArkadiusz Kubalewski /* Need one app for FW so keep it */
2625effa78eSArkadiusz Kubalewski if (old_cfg->numapps == 1)
2635effa78eSArkadiusz Kubalewski return 0;
2645effa78eSArkadiusz Kubalewski
2655effa78eSArkadiusz Kubalewski /* Copy current config into temp */
2665effa78eSArkadiusz Kubalewski pf->tmp_cfg = *old_cfg;
2675effa78eSArkadiusz Kubalewski
2685effa78eSArkadiusz Kubalewski /* Find and reset the app */
2695effa78eSArkadiusz Kubalewski for (i = 1; i < pf->tmp_cfg.numapps; i++) {
2705effa78eSArkadiusz Kubalewski if (app->selector == pf->tmp_cfg.app[i].selector &&
2715effa78eSArkadiusz Kubalewski app->protocol == pf->tmp_cfg.app[i].protocolid &&
2725effa78eSArkadiusz Kubalewski app->priority == pf->tmp_cfg.app[i].priority) {
2735effa78eSArkadiusz Kubalewski /* Reset the app data */
2745effa78eSArkadiusz Kubalewski pf->tmp_cfg.app[i].selector = 0;
2755effa78eSArkadiusz Kubalewski pf->tmp_cfg.app[i].protocolid = 0;
2765effa78eSArkadiusz Kubalewski pf->tmp_cfg.app[i].priority = 0;
2775effa78eSArkadiusz Kubalewski break;
2785effa78eSArkadiusz Kubalewski }
2795effa78eSArkadiusz Kubalewski }
2805effa78eSArkadiusz Kubalewski
2815effa78eSArkadiusz Kubalewski /* If the specific DCB app not found */
2825effa78eSArkadiusz Kubalewski if (i == pf->tmp_cfg.numapps)
2835effa78eSArkadiusz Kubalewski return -EINVAL;
2845effa78eSArkadiusz Kubalewski
2855effa78eSArkadiusz Kubalewski pf->tmp_cfg.numapps--;
2865effa78eSArkadiusz Kubalewski /* Overwrite the tmp_cfg app */
2875effa78eSArkadiusz Kubalewski for (j = i; j < pf->tmp_cfg.numapps; j++)
2885effa78eSArkadiusz Kubalewski pf->tmp_cfg.app[j] = old_cfg->app[j + 1];
2895effa78eSArkadiusz Kubalewski
2905effa78eSArkadiusz Kubalewski ret = i40e_hw_dcb_config(pf, &pf->tmp_cfg);
2915effa78eSArkadiusz Kubalewski if (ret) {
2925effa78eSArkadiusz Kubalewski dev_info(&pf->pdev->dev,
293d5ba1842SJan Sokolowski "Failed setting DCB configuration err %pe aq_err %s\n",
294d5ba1842SJan Sokolowski ERR_PTR(ret),
2955effa78eSArkadiusz Kubalewski i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
2965effa78eSArkadiusz Kubalewski return -EINVAL;
2975effa78eSArkadiusz Kubalewski }
2985effa78eSArkadiusz Kubalewski
2995effa78eSArkadiusz Kubalewski return 0;
3005effa78eSArkadiusz Kubalewski }
3015effa78eSArkadiusz Kubalewski
3025effa78eSArkadiusz Kubalewski /**
3035effa78eSArkadiusz Kubalewski * i40e_dcbnl_getstate - Get DCB enabled state
3045effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
3055effa78eSArkadiusz Kubalewski *
3065effa78eSArkadiusz Kubalewski * Get the current DCB enabled state
3075effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_getstate(struct net_device * netdev)3085effa78eSArkadiusz Kubalewski static u8 i40e_dcbnl_getstate(struct net_device *netdev)
3095effa78eSArkadiusz Kubalewski {
3105effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
3115effa78eSArkadiusz Kubalewski
3125effa78eSArkadiusz Kubalewski dev_dbg(&pf->pdev->dev, "DCB state=%d\n",
3135effa78eSArkadiusz Kubalewski !!(pf->flags & I40E_FLAG_DCB_ENABLED));
3145effa78eSArkadiusz Kubalewski return !!(pf->flags & I40E_FLAG_DCB_ENABLED);
3155effa78eSArkadiusz Kubalewski }
3165effa78eSArkadiusz Kubalewski
3175effa78eSArkadiusz Kubalewski /**
3185effa78eSArkadiusz Kubalewski * i40e_dcbnl_setstate - Set DCB state
3195effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
3205effa78eSArkadiusz Kubalewski * @state: enable or disable
3215effa78eSArkadiusz Kubalewski *
3225effa78eSArkadiusz Kubalewski * Set the DCB state
3235effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_setstate(struct net_device * netdev,u8 state)3245effa78eSArkadiusz Kubalewski static u8 i40e_dcbnl_setstate(struct net_device *netdev, u8 state)
3255effa78eSArkadiusz Kubalewski {
3265effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
3275effa78eSArkadiusz Kubalewski int ret = I40E_DCBNL_STATUS_SUCCESS;
3285effa78eSArkadiusz Kubalewski
3295effa78eSArkadiusz Kubalewski if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
3305effa78eSArkadiusz Kubalewski (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
3315effa78eSArkadiusz Kubalewski return ret;
3325effa78eSArkadiusz Kubalewski
3335effa78eSArkadiusz Kubalewski dev_dbg(&pf->pdev->dev, "new state=%d current state=%d\n",
3345effa78eSArkadiusz Kubalewski state, (pf->flags & I40E_FLAG_DCB_ENABLED) ? 1 : 0);
3355effa78eSArkadiusz Kubalewski /* Nothing to do */
3365effa78eSArkadiusz Kubalewski if (!state == !(pf->flags & I40E_FLAG_DCB_ENABLED))
3375effa78eSArkadiusz Kubalewski return ret;
3385effa78eSArkadiusz Kubalewski
3395effa78eSArkadiusz Kubalewski if (i40e_is_sw_dcb(pf)) {
3405effa78eSArkadiusz Kubalewski if (state) {
3415effa78eSArkadiusz Kubalewski pf->flags |= I40E_FLAG_DCB_ENABLED;
3425effa78eSArkadiusz Kubalewski memcpy(&pf->hw.desired_dcbx_config,
3435effa78eSArkadiusz Kubalewski &pf->hw.local_dcbx_config,
3445effa78eSArkadiusz Kubalewski sizeof(struct i40e_dcbx_config));
3455effa78eSArkadiusz Kubalewski } else {
3465effa78eSArkadiusz Kubalewski pf->flags &= ~I40E_FLAG_DCB_ENABLED;
3475effa78eSArkadiusz Kubalewski }
3485effa78eSArkadiusz Kubalewski } else {
3495effa78eSArkadiusz Kubalewski /* Cannot directly manipulate FW LLDP Agent */
3505effa78eSArkadiusz Kubalewski ret = I40E_DCBNL_STATUS_ERROR;
3515effa78eSArkadiusz Kubalewski }
3525effa78eSArkadiusz Kubalewski return ret;
3535effa78eSArkadiusz Kubalewski }
3545effa78eSArkadiusz Kubalewski
3555effa78eSArkadiusz Kubalewski /**
3565effa78eSArkadiusz Kubalewski * i40e_dcbnl_set_pg_tc_cfg_tx - Set CEE PG Tx config
3575effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
3585effa78eSArkadiusz Kubalewski * @tc: the corresponding traffic class
3595effa78eSArkadiusz Kubalewski * @prio_type: the traffic priority type
3605effa78eSArkadiusz Kubalewski * @bwg_id: the BW group id the traffic class belongs to
3615effa78eSArkadiusz Kubalewski * @bw_pct: the BW percentage for the corresponding BWG
3625effa78eSArkadiusz Kubalewski * @up_map: prio mapped to corresponding tc
3635effa78eSArkadiusz Kubalewski *
3645effa78eSArkadiusz Kubalewski * Set Tx PG settings for CEE mode
3655effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_set_pg_tc_cfg_tx(struct net_device * netdev,int tc,u8 prio_type,u8 bwg_id,u8 bw_pct,u8 up_map)3665effa78eSArkadiusz Kubalewski static void i40e_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
3675effa78eSArkadiusz Kubalewski u8 prio_type, u8 bwg_id, u8 bw_pct,
3685effa78eSArkadiusz Kubalewski u8 up_map)
3695effa78eSArkadiusz Kubalewski {
3705effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
3715effa78eSArkadiusz Kubalewski int i;
3725effa78eSArkadiusz Kubalewski
3735effa78eSArkadiusz Kubalewski if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
3745effa78eSArkadiusz Kubalewski (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
3755effa78eSArkadiusz Kubalewski return;
3765effa78eSArkadiusz Kubalewski
3775effa78eSArkadiusz Kubalewski /* LLTC not supported yet */
3785effa78eSArkadiusz Kubalewski if (tc >= I40E_MAX_TRAFFIC_CLASS)
3795effa78eSArkadiusz Kubalewski return;
3805effa78eSArkadiusz Kubalewski
3815effa78eSArkadiusz Kubalewski /* prio_type, bwg_id and bw_pct per UP are not supported */
3825effa78eSArkadiusz Kubalewski
3835effa78eSArkadiusz Kubalewski /* Use only up_map to map tc */
3845effa78eSArkadiusz Kubalewski for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
3855effa78eSArkadiusz Kubalewski if (up_map & BIT(i))
3865effa78eSArkadiusz Kubalewski pf->tmp_cfg.etscfg.prioritytable[i] = tc;
3875effa78eSArkadiusz Kubalewski }
3885effa78eSArkadiusz Kubalewski pf->tmp_cfg.etscfg.tsatable[tc] = I40E_IEEE_TSA_ETS;
3895effa78eSArkadiusz Kubalewski dev_dbg(&pf->pdev->dev,
3905effa78eSArkadiusz Kubalewski "Set PG config tc=%d bwg_id=%d prio_type=%d bw_pct=%d up_map=%d\n",
3915effa78eSArkadiusz Kubalewski tc, bwg_id, prio_type, bw_pct, up_map);
3925effa78eSArkadiusz Kubalewski }
3935effa78eSArkadiusz Kubalewski
3945effa78eSArkadiusz Kubalewski /**
395262de08fSJesse Brandeburg * i40e_dcbnl_set_pg_bwg_cfg_tx - Set CEE PG Tx BW config
3965effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
3975effa78eSArkadiusz Kubalewski * @pgid: the corresponding traffic class
3985effa78eSArkadiusz Kubalewski * @bw_pct: the BW percentage for the specified traffic class
3995effa78eSArkadiusz Kubalewski *
4005effa78eSArkadiusz Kubalewski * Set Tx BW settings for CEE mode
4015effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_set_pg_bwg_cfg_tx(struct net_device * netdev,int pgid,u8 bw_pct)4025effa78eSArkadiusz Kubalewski static void i40e_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int pgid,
4035effa78eSArkadiusz Kubalewski u8 bw_pct)
4045effa78eSArkadiusz Kubalewski {
4055effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
4065effa78eSArkadiusz Kubalewski
4075effa78eSArkadiusz Kubalewski if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
4085effa78eSArkadiusz Kubalewski (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
4095effa78eSArkadiusz Kubalewski return;
4105effa78eSArkadiusz Kubalewski
4115effa78eSArkadiusz Kubalewski /* LLTC not supported yet */
4125effa78eSArkadiusz Kubalewski if (pgid >= I40E_MAX_TRAFFIC_CLASS)
4135effa78eSArkadiusz Kubalewski return;
4145effa78eSArkadiusz Kubalewski
4155effa78eSArkadiusz Kubalewski pf->tmp_cfg.etscfg.tcbwtable[pgid] = bw_pct;
4165effa78eSArkadiusz Kubalewski dev_dbg(&pf->pdev->dev, "Set PG BW config tc=%d bw_pct=%d\n",
4175effa78eSArkadiusz Kubalewski pgid, bw_pct);
4185effa78eSArkadiusz Kubalewski }
4195effa78eSArkadiusz Kubalewski
4205effa78eSArkadiusz Kubalewski /**
4215effa78eSArkadiusz Kubalewski * i40e_dcbnl_set_pg_tc_cfg_rx - Set CEE PG Rx config
4225effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
4235effa78eSArkadiusz Kubalewski * @prio: the corresponding traffic class
4245effa78eSArkadiusz Kubalewski * @prio_type: the traffic priority type
4255effa78eSArkadiusz Kubalewski * @pgid: the BW group id the traffic class belongs to
4265effa78eSArkadiusz Kubalewski * @bw_pct: the BW percentage for the corresponding BWG
4275effa78eSArkadiusz Kubalewski * @up_map: prio mapped to corresponding tc
4285effa78eSArkadiusz Kubalewski *
4295effa78eSArkadiusz Kubalewski * Set Rx BW settings for CEE mode. The hardware does not support this
4305effa78eSArkadiusz Kubalewski * so we won't allow setting of this parameter.
4315effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_set_pg_tc_cfg_rx(struct net_device * netdev,int __always_unused prio,u8 __always_unused prio_type,u8 __always_unused pgid,u8 __always_unused bw_pct,u8 __always_unused up_map)4325effa78eSArkadiusz Kubalewski static void i40e_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev,
4335effa78eSArkadiusz Kubalewski int __always_unused prio,
4345effa78eSArkadiusz Kubalewski u8 __always_unused prio_type,
4355effa78eSArkadiusz Kubalewski u8 __always_unused pgid,
4365effa78eSArkadiusz Kubalewski u8 __always_unused bw_pct,
4375effa78eSArkadiusz Kubalewski u8 __always_unused up_map)
4385effa78eSArkadiusz Kubalewski {
4395effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
4405effa78eSArkadiusz Kubalewski
4415effa78eSArkadiusz Kubalewski dev_dbg(&pf->pdev->dev, "Rx TC PG Config Not Supported.\n");
4425effa78eSArkadiusz Kubalewski }
4435effa78eSArkadiusz Kubalewski
4445effa78eSArkadiusz Kubalewski /**
4455effa78eSArkadiusz Kubalewski * i40e_dcbnl_set_pg_bwg_cfg_rx - Set CEE PG Rx config
4465effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
4475effa78eSArkadiusz Kubalewski * @pgid: the corresponding traffic class
4485effa78eSArkadiusz Kubalewski * @bw_pct: the BW percentage for the specified traffic class
4495effa78eSArkadiusz Kubalewski *
4505effa78eSArkadiusz Kubalewski * Set Rx BW settings for CEE mode. The hardware does not support this
4515effa78eSArkadiusz Kubalewski * so we won't allow setting of this parameter.
4525effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_set_pg_bwg_cfg_rx(struct net_device * netdev,int pgid,u8 bw_pct)4535effa78eSArkadiusz Kubalewski static void i40e_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int pgid,
4545effa78eSArkadiusz Kubalewski u8 bw_pct)
4555effa78eSArkadiusz Kubalewski {
4565effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
4575effa78eSArkadiusz Kubalewski
4585effa78eSArkadiusz Kubalewski dev_dbg(&pf->pdev->dev, "Rx BWG PG Config Not Supported.\n");
4595effa78eSArkadiusz Kubalewski }
4605effa78eSArkadiusz Kubalewski
4615effa78eSArkadiusz Kubalewski /**
4625effa78eSArkadiusz Kubalewski * i40e_dcbnl_get_pg_tc_cfg_tx - Get CEE PG Tx config
4635effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
4645effa78eSArkadiusz Kubalewski * @prio: the corresponding user priority
4655effa78eSArkadiusz Kubalewski * @prio_type: traffic priority type
4665effa78eSArkadiusz Kubalewski * @pgid: the BW group ID the traffic class belongs to
4675effa78eSArkadiusz Kubalewski * @bw_pct: BW percentage for the corresponding BWG
4685effa78eSArkadiusz Kubalewski * @up_map: prio mapped to corresponding TC
4695effa78eSArkadiusz Kubalewski *
4705effa78eSArkadiusz Kubalewski * Get Tx PG settings for CEE mode
4715effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_get_pg_tc_cfg_tx(struct net_device * netdev,int prio,u8 __always_unused * prio_type,u8 * pgid,u8 __always_unused * bw_pct,u8 __always_unused * up_map)4725effa78eSArkadiusz Kubalewski static void i40e_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int prio,
4735effa78eSArkadiusz Kubalewski u8 __always_unused *prio_type,
4745effa78eSArkadiusz Kubalewski u8 *pgid,
4755effa78eSArkadiusz Kubalewski u8 __always_unused *bw_pct,
4765effa78eSArkadiusz Kubalewski u8 __always_unused *up_map)
4775effa78eSArkadiusz Kubalewski {
4785effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
4795effa78eSArkadiusz Kubalewski
4805effa78eSArkadiusz Kubalewski if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
4815effa78eSArkadiusz Kubalewski (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
4825effa78eSArkadiusz Kubalewski return;
4835effa78eSArkadiusz Kubalewski
4845effa78eSArkadiusz Kubalewski if (prio >= I40E_MAX_USER_PRIORITY)
4855effa78eSArkadiusz Kubalewski return;
4865effa78eSArkadiusz Kubalewski
4875effa78eSArkadiusz Kubalewski *pgid = pf->hw.local_dcbx_config.etscfg.prioritytable[prio];
4885effa78eSArkadiusz Kubalewski dev_dbg(&pf->pdev->dev, "Get PG config prio=%d tc=%d\n",
4895effa78eSArkadiusz Kubalewski prio, *pgid);
4905effa78eSArkadiusz Kubalewski }
4915effa78eSArkadiusz Kubalewski
4925effa78eSArkadiusz Kubalewski /**
4935effa78eSArkadiusz Kubalewski * i40e_dcbnl_get_pg_bwg_cfg_tx - Get CEE PG BW config
4945effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
4955effa78eSArkadiusz Kubalewski * @pgid: the corresponding traffic class
4965effa78eSArkadiusz Kubalewski * @bw_pct: the BW percentage for the corresponding TC
4975effa78eSArkadiusz Kubalewski *
4985effa78eSArkadiusz Kubalewski * Get Tx BW settings for given TC in CEE mode
4995effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_get_pg_bwg_cfg_tx(struct net_device * netdev,int pgid,u8 * bw_pct)5005effa78eSArkadiusz Kubalewski static void i40e_dcbnl_get_pg_bwg_cfg_tx(struct net_device *netdev, int pgid,
5015effa78eSArkadiusz Kubalewski u8 *bw_pct)
5025effa78eSArkadiusz Kubalewski {
5035effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
5045effa78eSArkadiusz Kubalewski
5055effa78eSArkadiusz Kubalewski if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
5065effa78eSArkadiusz Kubalewski (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
5075effa78eSArkadiusz Kubalewski return;
5085effa78eSArkadiusz Kubalewski
5095effa78eSArkadiusz Kubalewski if (pgid >= I40E_MAX_TRAFFIC_CLASS)
5105effa78eSArkadiusz Kubalewski return;
5115effa78eSArkadiusz Kubalewski
5125effa78eSArkadiusz Kubalewski *bw_pct = pf->hw.local_dcbx_config.etscfg.tcbwtable[pgid];
5135effa78eSArkadiusz Kubalewski dev_dbg(&pf->pdev->dev, "Get PG BW config tc=%d bw_pct=%d\n",
5145effa78eSArkadiusz Kubalewski pgid, *bw_pct);
5155effa78eSArkadiusz Kubalewski }
5165effa78eSArkadiusz Kubalewski
5175effa78eSArkadiusz Kubalewski /**
5185effa78eSArkadiusz Kubalewski * i40e_dcbnl_get_pg_tc_cfg_rx - Get CEE PG Rx config
5195effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
5205effa78eSArkadiusz Kubalewski * @prio: the corresponding user priority
5215effa78eSArkadiusz Kubalewski * @prio_type: the traffic priority type
5225effa78eSArkadiusz Kubalewski * @pgid: the PG ID
5235effa78eSArkadiusz Kubalewski * @bw_pct: the BW percentage for the corresponding BWG
5245effa78eSArkadiusz Kubalewski * @up_map: prio mapped to corresponding TC
5255effa78eSArkadiusz Kubalewski *
5265effa78eSArkadiusz Kubalewski * Get Rx PG settings for CEE mode. The UP2TC map is applied in same
5275effa78eSArkadiusz Kubalewski * manner for Tx and Rx (symmetrical) so return the TC information for
5285effa78eSArkadiusz Kubalewski * given priority accordingly.
5295effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_get_pg_tc_cfg_rx(struct net_device * netdev,int prio,u8 * prio_type,u8 * pgid,u8 * bw_pct,u8 * up_map)5305effa78eSArkadiusz Kubalewski static void i40e_dcbnl_get_pg_tc_cfg_rx(struct net_device *netdev, int prio,
5315effa78eSArkadiusz Kubalewski u8 *prio_type, u8 *pgid, u8 *bw_pct,
5325effa78eSArkadiusz Kubalewski u8 *up_map)
5335effa78eSArkadiusz Kubalewski {
5345effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
5355effa78eSArkadiusz Kubalewski
5365effa78eSArkadiusz Kubalewski if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
5375effa78eSArkadiusz Kubalewski (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
5385effa78eSArkadiusz Kubalewski return;
5395effa78eSArkadiusz Kubalewski
5405effa78eSArkadiusz Kubalewski if (prio >= I40E_MAX_USER_PRIORITY)
5415effa78eSArkadiusz Kubalewski return;
5425effa78eSArkadiusz Kubalewski
5435effa78eSArkadiusz Kubalewski *pgid = pf->hw.local_dcbx_config.etscfg.prioritytable[prio];
5445effa78eSArkadiusz Kubalewski }
5455effa78eSArkadiusz Kubalewski
5465effa78eSArkadiusz Kubalewski /**
5475effa78eSArkadiusz Kubalewski * i40e_dcbnl_get_pg_bwg_cfg_rx - Get CEE PG BW Rx config
5485effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
5495effa78eSArkadiusz Kubalewski * @pgid: the corresponding traffic class
5505effa78eSArkadiusz Kubalewski * @bw_pct: the BW percentage for the corresponding TC
5515effa78eSArkadiusz Kubalewski *
5525effa78eSArkadiusz Kubalewski * Get Rx BW settings for given TC in CEE mode
5535effa78eSArkadiusz Kubalewski * The adapter doesn't support Rx ETS and runs in strict priority
5545effa78eSArkadiusz Kubalewski * mode in Rx path and hence just return 0.
5555effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_get_pg_bwg_cfg_rx(struct net_device * netdev,int pgid,u8 * bw_pct)5565effa78eSArkadiusz Kubalewski static void i40e_dcbnl_get_pg_bwg_cfg_rx(struct net_device *netdev, int pgid,
5575effa78eSArkadiusz Kubalewski u8 *bw_pct)
5585effa78eSArkadiusz Kubalewski {
5595effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
5605effa78eSArkadiusz Kubalewski
5615effa78eSArkadiusz Kubalewski if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
5625effa78eSArkadiusz Kubalewski (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
5635effa78eSArkadiusz Kubalewski return;
5645effa78eSArkadiusz Kubalewski *bw_pct = 0;
5655effa78eSArkadiusz Kubalewski }
5665effa78eSArkadiusz Kubalewski
5675effa78eSArkadiusz Kubalewski /**
5685effa78eSArkadiusz Kubalewski * i40e_dcbnl_set_pfc_cfg - Set CEE PFC configuration
5695effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
5705effa78eSArkadiusz Kubalewski * @prio: the corresponding user priority
5715effa78eSArkadiusz Kubalewski * @setting: the PFC setting for given priority
5725effa78eSArkadiusz Kubalewski *
5735effa78eSArkadiusz Kubalewski * Set the PFC enabled/disabled setting for given user priority
5745effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_set_pfc_cfg(struct net_device * netdev,int prio,u8 setting)5755effa78eSArkadiusz Kubalewski static void i40e_dcbnl_set_pfc_cfg(struct net_device *netdev, int prio,
5765effa78eSArkadiusz Kubalewski u8 setting)
5775effa78eSArkadiusz Kubalewski {
5785effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
5795effa78eSArkadiusz Kubalewski
5805effa78eSArkadiusz Kubalewski if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
5815effa78eSArkadiusz Kubalewski (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
5825effa78eSArkadiusz Kubalewski return;
5835effa78eSArkadiusz Kubalewski
5845effa78eSArkadiusz Kubalewski if (prio >= I40E_MAX_USER_PRIORITY)
5855effa78eSArkadiusz Kubalewski return;
5865effa78eSArkadiusz Kubalewski
5875effa78eSArkadiusz Kubalewski pf->tmp_cfg.pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
5885effa78eSArkadiusz Kubalewski if (setting)
5895effa78eSArkadiusz Kubalewski pf->tmp_cfg.pfc.pfcenable |= BIT(prio);
5905effa78eSArkadiusz Kubalewski else
5915effa78eSArkadiusz Kubalewski pf->tmp_cfg.pfc.pfcenable &= ~BIT(prio);
5925effa78eSArkadiusz Kubalewski dev_dbg(&pf->pdev->dev,
5935effa78eSArkadiusz Kubalewski "Set PFC Config up=%d setting=%d pfcenable=0x%x\n",
5945effa78eSArkadiusz Kubalewski prio, setting, pf->tmp_cfg.pfc.pfcenable);
5955effa78eSArkadiusz Kubalewski }
5965effa78eSArkadiusz Kubalewski
5975effa78eSArkadiusz Kubalewski /**
5985effa78eSArkadiusz Kubalewski * i40e_dcbnl_get_pfc_cfg - Get CEE PFC configuration
5995effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
6005effa78eSArkadiusz Kubalewski * @prio: the corresponding user priority
6015effa78eSArkadiusz Kubalewski * @setting: the PFC setting for given priority
6025effa78eSArkadiusz Kubalewski *
6035effa78eSArkadiusz Kubalewski * Get the PFC enabled/disabled setting for given user priority
6045effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_get_pfc_cfg(struct net_device * netdev,int prio,u8 * setting)6055effa78eSArkadiusz Kubalewski static void i40e_dcbnl_get_pfc_cfg(struct net_device *netdev, int prio,
6065effa78eSArkadiusz Kubalewski u8 *setting)
6075effa78eSArkadiusz Kubalewski {
6085effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
6095effa78eSArkadiusz Kubalewski
6105effa78eSArkadiusz Kubalewski if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
6115effa78eSArkadiusz Kubalewski (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
6125effa78eSArkadiusz Kubalewski return;
6135effa78eSArkadiusz Kubalewski
6145effa78eSArkadiusz Kubalewski if (prio >= I40E_MAX_USER_PRIORITY)
6155effa78eSArkadiusz Kubalewski return;
6165effa78eSArkadiusz Kubalewski
6175effa78eSArkadiusz Kubalewski *setting = (pf->hw.local_dcbx_config.pfc.pfcenable >> prio) & 0x1;
6185effa78eSArkadiusz Kubalewski dev_dbg(&pf->pdev->dev,
6195effa78eSArkadiusz Kubalewski "Get PFC Config up=%d setting=%d pfcenable=0x%x\n",
6205effa78eSArkadiusz Kubalewski prio, *setting, pf->hw.local_dcbx_config.pfc.pfcenable);
6215effa78eSArkadiusz Kubalewski }
6225effa78eSArkadiusz Kubalewski
6235effa78eSArkadiusz Kubalewski /**
6245effa78eSArkadiusz Kubalewski * i40e_dcbnl_cee_set_all - Commit CEE DCB settings to hardware
6255effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
6265effa78eSArkadiusz Kubalewski *
6275effa78eSArkadiusz Kubalewski * Commit the current DCB configuration to hardware
6285effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_cee_set_all(struct net_device * netdev)6295effa78eSArkadiusz Kubalewski static u8 i40e_dcbnl_cee_set_all(struct net_device *netdev)
6305effa78eSArkadiusz Kubalewski {
6315effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
6325effa78eSArkadiusz Kubalewski int err;
6335effa78eSArkadiusz Kubalewski
6345effa78eSArkadiusz Kubalewski if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
6355effa78eSArkadiusz Kubalewski (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
6365effa78eSArkadiusz Kubalewski return I40E_DCBNL_STATUS_ERROR;
6375effa78eSArkadiusz Kubalewski
6385effa78eSArkadiusz Kubalewski dev_dbg(&pf->pdev->dev, "Commit DCB Configuration to the hardware\n");
6395effa78eSArkadiusz Kubalewski err = i40e_hw_dcb_config(pf, &pf->tmp_cfg);
6405effa78eSArkadiusz Kubalewski
6415effa78eSArkadiusz Kubalewski return err ? I40E_DCBNL_STATUS_ERROR : I40E_DCBNL_STATUS_SUCCESS;
6425effa78eSArkadiusz Kubalewski }
6435effa78eSArkadiusz Kubalewski
6445effa78eSArkadiusz Kubalewski /**
6455effa78eSArkadiusz Kubalewski * i40e_dcbnl_get_cap - Get DCBX capabilities of adapter
6465effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
6475effa78eSArkadiusz Kubalewski * @capid: the capability type
6485effa78eSArkadiusz Kubalewski * @cap: the capability value
6495effa78eSArkadiusz Kubalewski *
6505effa78eSArkadiusz Kubalewski * Return the capability value for a given capability type
6515effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_get_cap(struct net_device * netdev,int capid,u8 * cap)6525effa78eSArkadiusz Kubalewski static u8 i40e_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap)
6535effa78eSArkadiusz Kubalewski {
6545effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
6555effa78eSArkadiusz Kubalewski
6565effa78eSArkadiusz Kubalewski if (!(pf->flags & I40E_FLAG_DCB_CAPABLE))
6575effa78eSArkadiusz Kubalewski return I40E_DCBNL_STATUS_ERROR;
6585effa78eSArkadiusz Kubalewski
6595effa78eSArkadiusz Kubalewski switch (capid) {
6605effa78eSArkadiusz Kubalewski case DCB_CAP_ATTR_PG:
6615effa78eSArkadiusz Kubalewski case DCB_CAP_ATTR_PFC:
6625effa78eSArkadiusz Kubalewski *cap = true;
6635effa78eSArkadiusz Kubalewski break;
6645effa78eSArkadiusz Kubalewski case DCB_CAP_ATTR_PG_TCS:
6655effa78eSArkadiusz Kubalewski case DCB_CAP_ATTR_PFC_TCS:
6665effa78eSArkadiusz Kubalewski *cap = 0x80;
6675effa78eSArkadiusz Kubalewski break;
6685effa78eSArkadiusz Kubalewski case DCB_CAP_ATTR_DCBX:
6695effa78eSArkadiusz Kubalewski *cap = pf->dcbx_cap;
6705effa78eSArkadiusz Kubalewski break;
6715effa78eSArkadiusz Kubalewski case DCB_CAP_ATTR_UP2TC:
6725effa78eSArkadiusz Kubalewski case DCB_CAP_ATTR_GSP:
6735effa78eSArkadiusz Kubalewski case DCB_CAP_ATTR_BCN:
6745effa78eSArkadiusz Kubalewski default:
6755effa78eSArkadiusz Kubalewski *cap = false;
6765effa78eSArkadiusz Kubalewski break;
6775effa78eSArkadiusz Kubalewski }
6785effa78eSArkadiusz Kubalewski
6795effa78eSArkadiusz Kubalewski dev_dbg(&pf->pdev->dev, "Get Capability cap=%d capval=0x%x\n",
6805effa78eSArkadiusz Kubalewski capid, *cap);
6815effa78eSArkadiusz Kubalewski return I40E_DCBNL_STATUS_SUCCESS;
6825effa78eSArkadiusz Kubalewski }
6835effa78eSArkadiusz Kubalewski
6845effa78eSArkadiusz Kubalewski /**
6855effa78eSArkadiusz Kubalewski * i40e_dcbnl_getnumtcs - Get max number of traffic classes supported
6865effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
6875effa78eSArkadiusz Kubalewski * @tcid: the TC id
6885effa78eSArkadiusz Kubalewski * @num: total number of TCs supported by the device
6895effa78eSArkadiusz Kubalewski *
6905effa78eSArkadiusz Kubalewski * Return the total number of TCs supported by the adapter
6915effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_getnumtcs(struct net_device * netdev,int tcid,u8 * num)6925effa78eSArkadiusz Kubalewski static int i40e_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num)
6935effa78eSArkadiusz Kubalewski {
6945effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
6955effa78eSArkadiusz Kubalewski
6965effa78eSArkadiusz Kubalewski if (!(pf->flags & I40E_FLAG_DCB_CAPABLE))
6975effa78eSArkadiusz Kubalewski return -EINVAL;
6985effa78eSArkadiusz Kubalewski
6995effa78eSArkadiusz Kubalewski *num = I40E_MAX_TRAFFIC_CLASS;
7005effa78eSArkadiusz Kubalewski return 0;
7015effa78eSArkadiusz Kubalewski }
7025effa78eSArkadiusz Kubalewski
7035effa78eSArkadiusz Kubalewski /**
7045effa78eSArkadiusz Kubalewski * i40e_dcbnl_setnumtcs - Set CEE number of traffic classes
7055effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
7065effa78eSArkadiusz Kubalewski * @tcid: the TC id
7075effa78eSArkadiusz Kubalewski * @num: total number of TCs
7085effa78eSArkadiusz Kubalewski *
7095effa78eSArkadiusz Kubalewski * Set the total number of TCs (Unsupported)
7105effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_setnumtcs(struct net_device * netdev,int tcid,u8 num)7115effa78eSArkadiusz Kubalewski static int i40e_dcbnl_setnumtcs(struct net_device *netdev, int tcid, u8 num)
7125effa78eSArkadiusz Kubalewski {
7135effa78eSArkadiusz Kubalewski return -EINVAL;
7145effa78eSArkadiusz Kubalewski }
7155effa78eSArkadiusz Kubalewski
7165effa78eSArkadiusz Kubalewski /**
7175effa78eSArkadiusz Kubalewski * i40e_dcbnl_getpfcstate - Get CEE PFC mode
7185effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
7195effa78eSArkadiusz Kubalewski *
7205effa78eSArkadiusz Kubalewski * Get the current PFC enabled state
7215effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_getpfcstate(struct net_device * netdev)7225effa78eSArkadiusz Kubalewski static u8 i40e_dcbnl_getpfcstate(struct net_device *netdev)
7235effa78eSArkadiusz Kubalewski {
7245effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
7255effa78eSArkadiusz Kubalewski
7265effa78eSArkadiusz Kubalewski /* Return enabled if any PFC enabled UP */
7275effa78eSArkadiusz Kubalewski if (pf->hw.local_dcbx_config.pfc.pfcenable)
7285effa78eSArkadiusz Kubalewski return 1;
7295effa78eSArkadiusz Kubalewski else
7305effa78eSArkadiusz Kubalewski return 0;
7315effa78eSArkadiusz Kubalewski }
7325effa78eSArkadiusz Kubalewski
7335effa78eSArkadiusz Kubalewski /**
7345effa78eSArkadiusz Kubalewski * i40e_dcbnl_setpfcstate - Set CEE PFC mode
7355effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
7365effa78eSArkadiusz Kubalewski * @state: required state
7375effa78eSArkadiusz Kubalewski *
7385effa78eSArkadiusz Kubalewski * The PFC state to be set; this is enabled/disabled based on the PFC
7395effa78eSArkadiusz Kubalewski * priority settings and not via this call for i40e driver
7405effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_setpfcstate(struct net_device * netdev,u8 state)7415effa78eSArkadiusz Kubalewski static void i40e_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
7425effa78eSArkadiusz Kubalewski {
7435effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
7445effa78eSArkadiusz Kubalewski
7455effa78eSArkadiusz Kubalewski dev_dbg(&pf->pdev->dev, "PFC State is modified via PFC config.\n");
7465effa78eSArkadiusz Kubalewski }
7475effa78eSArkadiusz Kubalewski
7485effa78eSArkadiusz Kubalewski /**
7495effa78eSArkadiusz Kubalewski * i40e_dcbnl_getapp - Get CEE APP
7505effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
7515effa78eSArkadiusz Kubalewski * @idtype: the App selector
7525effa78eSArkadiusz Kubalewski * @id: the App ethtype or port number
7535effa78eSArkadiusz Kubalewski *
7545effa78eSArkadiusz Kubalewski * Return the CEE mode app for the given idtype and id
7555effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_getapp(struct net_device * netdev,u8 idtype,u16 id)7565effa78eSArkadiusz Kubalewski static int i40e_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
7575effa78eSArkadiusz Kubalewski {
7585effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
7595effa78eSArkadiusz Kubalewski struct dcb_app app = {
7605effa78eSArkadiusz Kubalewski .selector = idtype,
7615effa78eSArkadiusz Kubalewski .protocol = id,
7625effa78eSArkadiusz Kubalewski };
7635effa78eSArkadiusz Kubalewski
7645effa78eSArkadiusz Kubalewski if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
7655effa78eSArkadiusz Kubalewski (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
7665effa78eSArkadiusz Kubalewski return -EINVAL;
7675effa78eSArkadiusz Kubalewski
7685effa78eSArkadiusz Kubalewski return dcb_getapp(netdev, &app);
7695effa78eSArkadiusz Kubalewski }
7705effa78eSArkadiusz Kubalewski
7715effa78eSArkadiusz Kubalewski /**
7725effa78eSArkadiusz Kubalewski * i40e_dcbnl_setdcbx - set required DCBx capability
7735effa78eSArkadiusz Kubalewski * @netdev: the corresponding netdev
7745effa78eSArkadiusz Kubalewski * @mode: new DCB mode managed or CEE+IEEE
7755effa78eSArkadiusz Kubalewski *
7765effa78eSArkadiusz Kubalewski * Set DCBx capability features
7775effa78eSArkadiusz Kubalewski **/
i40e_dcbnl_setdcbx(struct net_device * netdev,u8 mode)7785effa78eSArkadiusz Kubalewski static u8 i40e_dcbnl_setdcbx(struct net_device *netdev, u8 mode)
7795effa78eSArkadiusz Kubalewski {
7805effa78eSArkadiusz Kubalewski struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
7815effa78eSArkadiusz Kubalewski
7825effa78eSArkadiusz Kubalewski /* Do not allow to set mode if managed by Firmware */
7835effa78eSArkadiusz Kubalewski if (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED)
7845effa78eSArkadiusz Kubalewski return I40E_DCBNL_STATUS_ERROR;
7855effa78eSArkadiusz Kubalewski
7865effa78eSArkadiusz Kubalewski /* No support for LLD_MANAGED modes or CEE+IEEE */
7875effa78eSArkadiusz Kubalewski if ((mode & DCB_CAP_DCBX_LLD_MANAGED) ||
7885effa78eSArkadiusz Kubalewski ((mode & DCB_CAP_DCBX_VER_IEEE) && (mode & DCB_CAP_DCBX_VER_CEE)) ||
7895effa78eSArkadiusz Kubalewski !(mode & DCB_CAP_DCBX_HOST))
7905effa78eSArkadiusz Kubalewski return I40E_DCBNL_STATUS_ERROR;
7915effa78eSArkadiusz Kubalewski
7925effa78eSArkadiusz Kubalewski /* Already set to the given mode no change */
7935effa78eSArkadiusz Kubalewski if (mode == pf->dcbx_cap)
7945effa78eSArkadiusz Kubalewski return I40E_DCBNL_STATUS_SUCCESS;
7955effa78eSArkadiusz Kubalewski
7965effa78eSArkadiusz Kubalewski pf->dcbx_cap = mode;
7975effa78eSArkadiusz Kubalewski if (mode & DCB_CAP_DCBX_VER_CEE)
7985effa78eSArkadiusz Kubalewski pf->hw.local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
7995effa78eSArkadiusz Kubalewski else
8005effa78eSArkadiusz Kubalewski pf->hw.local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_IEEE;
8015effa78eSArkadiusz Kubalewski
8025effa78eSArkadiusz Kubalewski dev_dbg(&pf->pdev->dev, "mode=%d\n", mode);
8035effa78eSArkadiusz Kubalewski return I40E_DCBNL_STATUS_SUCCESS;
8045effa78eSArkadiusz Kubalewski }
8055effa78eSArkadiusz Kubalewski
8065effa78eSArkadiusz Kubalewski /**
8074e3b35b0SNeerav Parikh * i40e_dcbnl_getdcbx - retrieve current DCBx capability
808f5254429SJacob Keller * @dev: the corresponding netdev
8094e3b35b0SNeerav Parikh *
8104e3b35b0SNeerav Parikh * Returns DCBx capability features
8114e3b35b0SNeerav Parikh **/
i40e_dcbnl_getdcbx(struct net_device * dev)8124e3b35b0SNeerav Parikh static u8 i40e_dcbnl_getdcbx(struct net_device *dev)
8134e3b35b0SNeerav Parikh {
8144e3b35b0SNeerav Parikh struct i40e_pf *pf = i40e_netdev_to_pf(dev);
8154e3b35b0SNeerav Parikh
8164e3b35b0SNeerav Parikh return pf->dcbx_cap;
8174e3b35b0SNeerav Parikh }
8184e3b35b0SNeerav Parikh
8194e3b35b0SNeerav Parikh /**
8204e3b35b0SNeerav Parikh * i40e_dcbnl_get_perm_hw_addr - MAC address used by DCBx
821f5254429SJacob Keller * @dev: the corresponding netdev
822f5254429SJacob Keller * @perm_addr: buffer to store the MAC address
8234e3b35b0SNeerav Parikh *
8244e3b35b0SNeerav Parikh * Returns the SAN MAC address used for LLDP exchange
8254e3b35b0SNeerav Parikh **/
i40e_dcbnl_get_perm_hw_addr(struct net_device * dev,u8 * perm_addr)8264e3b35b0SNeerav Parikh static void i40e_dcbnl_get_perm_hw_addr(struct net_device *dev,
8274e3b35b0SNeerav Parikh u8 *perm_addr)
8284e3b35b0SNeerav Parikh {
8294e3b35b0SNeerav Parikh struct i40e_pf *pf = i40e_netdev_to_pf(dev);
8304e3b35b0SNeerav Parikh int i, j;
8314e3b35b0SNeerav Parikh
8324e3b35b0SNeerav Parikh memset(perm_addr, 0xff, MAX_ADDR_LEN);
8334e3b35b0SNeerav Parikh
8344e3b35b0SNeerav Parikh for (i = 0; i < dev->addr_len; i++)
8354e3b35b0SNeerav Parikh perm_addr[i] = pf->hw.mac.perm_addr[i];
8364e3b35b0SNeerav Parikh
8374e3b35b0SNeerav Parikh for (j = 0; j < dev->addr_len; j++, i++)
8384e3b35b0SNeerav Parikh perm_addr[i] = pf->hw.mac.san_addr[j];
8394e3b35b0SNeerav Parikh }
8404e3b35b0SNeerav Parikh
8414e3b35b0SNeerav Parikh static const struct dcbnl_rtnl_ops dcbnl_ops = {
8424e3b35b0SNeerav Parikh .ieee_getets = i40e_dcbnl_ieee_getets,
8434e3b35b0SNeerav Parikh .ieee_getpfc = i40e_dcbnl_ieee_getpfc,
8444e3b35b0SNeerav Parikh .getdcbx = i40e_dcbnl_getdcbx,
8454e3b35b0SNeerav Parikh .getpermhwaddr = i40e_dcbnl_get_perm_hw_addr,
8465effa78eSArkadiusz Kubalewski .ieee_setets = i40e_dcbnl_ieee_setets,
8475effa78eSArkadiusz Kubalewski .ieee_setpfc = i40e_dcbnl_ieee_setpfc,
8485effa78eSArkadiusz Kubalewski .ieee_setapp = i40e_dcbnl_ieee_setapp,
8495effa78eSArkadiusz Kubalewski .ieee_delapp = i40e_dcbnl_ieee_delapp,
8505effa78eSArkadiusz Kubalewski .getstate = i40e_dcbnl_getstate,
8515effa78eSArkadiusz Kubalewski .setstate = i40e_dcbnl_setstate,
8525effa78eSArkadiusz Kubalewski .setpgtccfgtx = i40e_dcbnl_set_pg_tc_cfg_tx,
8535effa78eSArkadiusz Kubalewski .setpgbwgcfgtx = i40e_dcbnl_set_pg_bwg_cfg_tx,
8545effa78eSArkadiusz Kubalewski .setpgtccfgrx = i40e_dcbnl_set_pg_tc_cfg_rx,
8555effa78eSArkadiusz Kubalewski .setpgbwgcfgrx = i40e_dcbnl_set_pg_bwg_cfg_rx,
8565effa78eSArkadiusz Kubalewski .getpgtccfgtx = i40e_dcbnl_get_pg_tc_cfg_tx,
8575effa78eSArkadiusz Kubalewski .getpgbwgcfgtx = i40e_dcbnl_get_pg_bwg_cfg_tx,
8585effa78eSArkadiusz Kubalewski .getpgtccfgrx = i40e_dcbnl_get_pg_tc_cfg_rx,
8595effa78eSArkadiusz Kubalewski .getpgbwgcfgrx = i40e_dcbnl_get_pg_bwg_cfg_rx,
8605effa78eSArkadiusz Kubalewski .setpfccfg = i40e_dcbnl_set_pfc_cfg,
8615effa78eSArkadiusz Kubalewski .getpfccfg = i40e_dcbnl_get_pfc_cfg,
8625effa78eSArkadiusz Kubalewski .setall = i40e_dcbnl_cee_set_all,
8635effa78eSArkadiusz Kubalewski .getcap = i40e_dcbnl_get_cap,
8645effa78eSArkadiusz Kubalewski .getnumtcs = i40e_dcbnl_getnumtcs,
8655effa78eSArkadiusz Kubalewski .setnumtcs = i40e_dcbnl_setnumtcs,
8665effa78eSArkadiusz Kubalewski .getpfcstate = i40e_dcbnl_getpfcstate,
8675effa78eSArkadiusz Kubalewski .setpfcstate = i40e_dcbnl_setpfcstate,
8685effa78eSArkadiusz Kubalewski .getapp = i40e_dcbnl_getapp,
8695effa78eSArkadiusz Kubalewski .setdcbx = i40e_dcbnl_setdcbx,
8704e3b35b0SNeerav Parikh };
8714e3b35b0SNeerav Parikh
8724e3b35b0SNeerav Parikh /**
8734e3b35b0SNeerav Parikh * i40e_dcbnl_set_all - set all the apps and ieee data from DCBx config
8744e3b35b0SNeerav Parikh * @vsi: the corresponding vsi
8754e3b35b0SNeerav Parikh *
8764e3b35b0SNeerav Parikh * Set up all the IEEE APPs in the DCBNL App Table and generate event for
8774e3b35b0SNeerav Parikh * other settings
8784e3b35b0SNeerav Parikh **/
i40e_dcbnl_set_all(struct i40e_vsi * vsi)8794e3b35b0SNeerav Parikh void i40e_dcbnl_set_all(struct i40e_vsi *vsi)
8804e3b35b0SNeerav Parikh {
8814e3b35b0SNeerav Parikh struct net_device *dev = vsi->netdev;
8824e3b35b0SNeerav Parikh struct i40e_pf *pf = i40e_netdev_to_pf(dev);
8834e3b35b0SNeerav Parikh struct i40e_dcbx_config *dcbxcfg;
8844e3b35b0SNeerav Parikh struct i40e_hw *hw = &pf->hw;
8854e3b35b0SNeerav Parikh struct dcb_app sapp;
8864e3b35b0SNeerav Parikh u8 prio, tc_map;
8874e3b35b0SNeerav Parikh int i;
8884e3b35b0SNeerav Parikh
8895effa78eSArkadiusz Kubalewski /* SW DCB taken care by DCBNL set calls */
8905effa78eSArkadiusz Kubalewski if (pf->dcbx_cap & DCB_CAP_DCBX_HOST)
8915effa78eSArkadiusz Kubalewski return;
8925effa78eSArkadiusz Kubalewski
8934e3b35b0SNeerav Parikh /* DCB not enabled */
8944e3b35b0SNeerav Parikh if (!(pf->flags & I40E_FLAG_DCB_ENABLED))
8954e3b35b0SNeerav Parikh return;
8964e3b35b0SNeerav Parikh
897c142b1dcSNeerav Parikh /* MFP mode but not an iSCSI PF so return */
8985effa78eSArkadiusz Kubalewski if ((pf->flags & I40E_FLAG_MFP_ENABLED) && !(hw->func_caps.iscsi))
899c142b1dcSNeerav Parikh return;
900c142b1dcSNeerav Parikh
9014e3b35b0SNeerav Parikh dcbxcfg = &hw->local_dcbx_config;
9024e3b35b0SNeerav Parikh
9034e3b35b0SNeerav Parikh /* Set up all the App TLVs if DCBx is negotiated */
9044e3b35b0SNeerav Parikh for (i = 0; i < dcbxcfg->numapps; i++) {
9054e3b35b0SNeerav Parikh prio = dcbxcfg->app[i].priority;
90641a1d04bSJesse Brandeburg tc_map = BIT(dcbxcfg->etscfg.prioritytable[prio]);
9074e3b35b0SNeerav Parikh
9084e3b35b0SNeerav Parikh /* Add APP only if the TC is enabled for this VSI */
9094e3b35b0SNeerav Parikh if (tc_map & vsi->tc_config.enabled_tc) {
9104e3b35b0SNeerav Parikh sapp.selector = dcbxcfg->app[i].selector;
9114e3b35b0SNeerav Parikh sapp.protocol = dcbxcfg->app[i].protocolid;
9124e3b35b0SNeerav Parikh sapp.priority = prio;
9134e3b35b0SNeerav Parikh dcb_ieee_setapp(dev, &sapp);
9144e3b35b0SNeerav Parikh }
9154e3b35b0SNeerav Parikh }
9164e3b35b0SNeerav Parikh
9174e3b35b0SNeerav Parikh /* Notify user-space of the changes */
9184e3b35b0SNeerav Parikh dcbnl_ieee_notify(dev, RTM_SETDCB, DCB_CMD_IEEE_SET, 0, 0);
9194e3b35b0SNeerav Parikh }
9204e3b35b0SNeerav Parikh
9214e3b35b0SNeerav Parikh /**
9224e3b35b0SNeerav Parikh * i40e_dcbnl_vsi_del_app - Delete APP for given VSI
9234e3b35b0SNeerav Parikh * @vsi: the corresponding vsi
9244e3b35b0SNeerav Parikh * @app: APP to delete
9254e3b35b0SNeerav Parikh *
9264e3b35b0SNeerav Parikh * Delete given APP from the DCBNL APP table for given
9274e3b35b0SNeerav Parikh * VSI
9284e3b35b0SNeerav Parikh **/
i40e_dcbnl_vsi_del_app(struct i40e_vsi * vsi,struct i40e_dcb_app_priority_table * app)9294e3b35b0SNeerav Parikh static int i40e_dcbnl_vsi_del_app(struct i40e_vsi *vsi,
9309fa61dd2SNeerav Parikh struct i40e_dcb_app_priority_table *app)
9314e3b35b0SNeerav Parikh {
9324e3b35b0SNeerav Parikh struct net_device *dev = vsi->netdev;
9334e3b35b0SNeerav Parikh struct dcb_app sapp;
9344e3b35b0SNeerav Parikh
9354e3b35b0SNeerav Parikh if (!dev)
9364e3b35b0SNeerav Parikh return -EINVAL;
9374e3b35b0SNeerav Parikh
9384e3b35b0SNeerav Parikh sapp.selector = app->selector;
9394e3b35b0SNeerav Parikh sapp.protocol = app->protocolid;
9404e3b35b0SNeerav Parikh sapp.priority = app->priority;
9414e3b35b0SNeerav Parikh return dcb_ieee_delapp(dev, &sapp);
9424e3b35b0SNeerav Parikh }
9434e3b35b0SNeerav Parikh
9444e3b35b0SNeerav Parikh /**
9454e3b35b0SNeerav Parikh * i40e_dcbnl_del_app - Delete APP on all VSIs
946b40c82e6SJeff Kirsher * @pf: the corresponding PF
9474e3b35b0SNeerav Parikh * @app: APP to delete
9484e3b35b0SNeerav Parikh *
9494e3b35b0SNeerav Parikh * Delete given APP from all the VSIs for given PF
9504e3b35b0SNeerav Parikh **/
i40e_dcbnl_del_app(struct i40e_pf * pf,struct i40e_dcb_app_priority_table * app)9514e3b35b0SNeerav Parikh static void i40e_dcbnl_del_app(struct i40e_pf *pf,
9529fa61dd2SNeerav Parikh struct i40e_dcb_app_priority_table *app)
9534e3b35b0SNeerav Parikh {
9544e3b35b0SNeerav Parikh int v, err;
9556995b36cSJesse Brandeburg
956505682cdSMitch Williams for (v = 0; v < pf->num_alloc_vsi; v++) {
9574e3b35b0SNeerav Parikh if (pf->vsi[v] && pf->vsi[v]->netdev) {
9584e3b35b0SNeerav Parikh err = i40e_dcbnl_vsi_del_app(pf->vsi[v], app);
9598279e495SNeerav Parikh dev_dbg(&pf->pdev->dev, "Deleting app for VSI seid=%d err=%d sel=%d proto=0x%x prio=%d\n",
960fb43201fSShannon Nelson pf->vsi[v]->seid, err, app->selector,
9614e3b35b0SNeerav Parikh app->protocolid, app->priority);
9624e3b35b0SNeerav Parikh }
9634e3b35b0SNeerav Parikh }
9644e3b35b0SNeerav Parikh }
9654e3b35b0SNeerav Parikh
9664e3b35b0SNeerav Parikh /**
9674e3b35b0SNeerav Parikh * i40e_dcbnl_find_app - Search APP in given DCB config
9684e3b35b0SNeerav Parikh * @cfg: DCBX configuration data
9694e3b35b0SNeerav Parikh * @app: APP to search for
9704e3b35b0SNeerav Parikh *
9714e3b35b0SNeerav Parikh * Find given APP in the DCB configuration
9724e3b35b0SNeerav Parikh **/
i40e_dcbnl_find_app(struct i40e_dcbx_config * cfg,struct i40e_dcb_app_priority_table * app)9734e3b35b0SNeerav Parikh static bool i40e_dcbnl_find_app(struct i40e_dcbx_config *cfg,
9749fa61dd2SNeerav Parikh struct i40e_dcb_app_priority_table *app)
9754e3b35b0SNeerav Parikh {
9764e3b35b0SNeerav Parikh int i;
9774e3b35b0SNeerav Parikh
9784e3b35b0SNeerav Parikh for (i = 0; i < cfg->numapps; i++) {
9794e3b35b0SNeerav Parikh if (app->selector == cfg->app[i].selector &&
9804e3b35b0SNeerav Parikh app->protocolid == cfg->app[i].protocolid &&
9814e3b35b0SNeerav Parikh app->priority == cfg->app[i].priority)
9824e3b35b0SNeerav Parikh return true;
9834e3b35b0SNeerav Parikh }
9844e3b35b0SNeerav Parikh
9854e3b35b0SNeerav Parikh return false;
9864e3b35b0SNeerav Parikh }
9874e3b35b0SNeerav Parikh
9884e3b35b0SNeerav Parikh /**
9894e3b35b0SNeerav Parikh * i40e_dcbnl_flush_apps - Delete all removed APPs
990b40c82e6SJeff Kirsher * @pf: the corresponding PF
991750fcbcfSNeerav Parikh * @old_cfg: old DCBX configuration data
9924e3b35b0SNeerav Parikh * @new_cfg: new DCBX configuration data
9934e3b35b0SNeerav Parikh *
9944e3b35b0SNeerav Parikh * Find and delete all APPs that are not present in the passed
9954e3b35b0SNeerav Parikh * DCB configuration
9964e3b35b0SNeerav Parikh **/
i40e_dcbnl_flush_apps(struct i40e_pf * pf,struct i40e_dcbx_config * old_cfg,struct i40e_dcbx_config * new_cfg)9974e3b35b0SNeerav Parikh void i40e_dcbnl_flush_apps(struct i40e_pf *pf,
998750fcbcfSNeerav Parikh struct i40e_dcbx_config *old_cfg,
9994e3b35b0SNeerav Parikh struct i40e_dcbx_config *new_cfg)
10004e3b35b0SNeerav Parikh {
10019fa61dd2SNeerav Parikh struct i40e_dcb_app_priority_table app;
10024e3b35b0SNeerav Parikh int i;
10034e3b35b0SNeerav Parikh
1004c142b1dcSNeerav Parikh /* MFP mode but not an iSCSI PF so return */
1005c142b1dcSNeerav Parikh if ((pf->flags & I40E_FLAG_MFP_ENABLED) && !(pf->hw.func_caps.iscsi))
1006c142b1dcSNeerav Parikh return;
1007c142b1dcSNeerav Parikh
1008750fcbcfSNeerav Parikh for (i = 0; i < old_cfg->numapps; i++) {
1009750fcbcfSNeerav Parikh app = old_cfg->app[i];
10104e3b35b0SNeerav Parikh /* The APP is not available anymore delete it */
10114e3b35b0SNeerav Parikh if (!i40e_dcbnl_find_app(new_cfg, &app))
10124e3b35b0SNeerav Parikh i40e_dcbnl_del_app(pf, &app);
10134e3b35b0SNeerav Parikh }
10144e3b35b0SNeerav Parikh }
10154e3b35b0SNeerav Parikh
10164e3b35b0SNeerav Parikh /**
10174e3b35b0SNeerav Parikh * i40e_dcbnl_setup - DCBNL setup
10184e3b35b0SNeerav Parikh * @vsi: the corresponding vsi
10194e3b35b0SNeerav Parikh *
10204e3b35b0SNeerav Parikh * Set up DCBNL ops and initial APP TLVs
10214e3b35b0SNeerav Parikh **/
i40e_dcbnl_setup(struct i40e_vsi * vsi)10224e3b35b0SNeerav Parikh void i40e_dcbnl_setup(struct i40e_vsi *vsi)
10234e3b35b0SNeerav Parikh {
10244e3b35b0SNeerav Parikh struct net_device *dev = vsi->netdev;
10254e3b35b0SNeerav Parikh struct i40e_pf *pf = i40e_netdev_to_pf(dev);
10264e3b35b0SNeerav Parikh
10274d9b6043SNeerav Parikh /* Not DCB capable */
10284d9b6043SNeerav Parikh if (!(pf->flags & I40E_FLAG_DCB_CAPABLE))
10294e3b35b0SNeerav Parikh return;
10304e3b35b0SNeerav Parikh
10314e3b35b0SNeerav Parikh dev->dcbnl_ops = &dcbnl_ops;
10324e3b35b0SNeerav Parikh
10334e3b35b0SNeerav Parikh /* Set initial IEEE DCB settings */
10344e3b35b0SNeerav Parikh i40e_dcbnl_set_all(vsi);
10354e3b35b0SNeerav Parikh }
10364e3b35b0SNeerav Parikh #endif /* CONFIG_I40E_DCB */
1037