1b94b013eSDave Ertman // SPDX-License-Identifier: GPL-2.0 2b94b013eSDave Ertman /* Copyright (c) 2019, Intel Corporation. */ 3b94b013eSDave Ertman 4b94b013eSDave Ertman #include "ice.h" 5b94b013eSDave Ertman #include "ice_dcb.h" 6b94b013eSDave Ertman #include "ice_dcb_lib.h" 7b94b013eSDave Ertman #include "ice_dcb_nl.h" 8b94b013eSDave Ertman #include <net/dcbnl.h> 9b94b013eSDave Ertman 10b94b013eSDave Ertman /** 11b94b013eSDave Ertman * ice_dcbnl_devreset - perform enough of a ifdown/ifup to sync DCBNL info 12b94b013eSDave Ertman * @netdev: device associated with interface that needs reset 13b94b013eSDave Ertman */ 14b94b013eSDave Ertman static void ice_dcbnl_devreset(struct net_device *netdev) 15b94b013eSDave Ertman { 16b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 17b94b013eSDave Ertman 18b94b013eSDave Ertman while (ice_is_reset_in_progress(pf->state)) 19b94b013eSDave Ertman usleep_range(1000, 2000); 20b94b013eSDave Ertman 21b94b013eSDave Ertman dev_close(netdev); 22b94b013eSDave Ertman netdev_state_change(netdev); 23b94b013eSDave Ertman dev_open(netdev, NULL); 24b94b013eSDave Ertman netdev_state_change(netdev); 25b94b013eSDave Ertman } 26b94b013eSDave Ertman 27b94b013eSDave Ertman /** 28b94b013eSDave Ertman * ice_dcbnl_getets - retrieve local ETS configuration 29b94b013eSDave Ertman * @netdev: the relevant netdev 30b94b013eSDave Ertman * @ets: struct to hold ETS configuration 31b94b013eSDave Ertman */ 32b94b013eSDave Ertman static int ice_dcbnl_getets(struct net_device *netdev, struct ieee_ets *ets) 33b94b013eSDave Ertman { 34b94b013eSDave Ertman struct ice_dcbx_cfg *dcbxcfg; 35b94b013eSDave Ertman struct ice_pf *pf; 36b94b013eSDave Ertman 37b94b013eSDave Ertman pf = ice_netdev_to_pf(netdev); 38fc2d1165SChinh T Cao dcbxcfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg; 39b94b013eSDave Ertman 40b94b013eSDave Ertman ets->willing = dcbxcfg->etscfg.willing; 41b94b013eSDave Ertman ets->ets_cap = dcbxcfg->etscfg.maxtcs; 42b94b013eSDave Ertman ets->cbs = dcbxcfg->etscfg.cbs; 43b94b013eSDave Ertman memcpy(ets->tc_tx_bw, dcbxcfg->etscfg.tcbwtable, sizeof(ets->tc_tx_bw)); 44b94b013eSDave Ertman memcpy(ets->tc_rx_bw, dcbxcfg->etscfg.tcbwtable, sizeof(ets->tc_rx_bw)); 45b94b013eSDave Ertman memcpy(ets->tc_tsa, dcbxcfg->etscfg.tsatable, sizeof(ets->tc_tsa)); 46b94b013eSDave Ertman memcpy(ets->prio_tc, dcbxcfg->etscfg.prio_table, sizeof(ets->prio_tc)); 47b94b013eSDave Ertman memcpy(ets->tc_reco_bw, dcbxcfg->etsrec.tcbwtable, 48b94b013eSDave Ertman sizeof(ets->tc_reco_bw)); 49b94b013eSDave Ertman memcpy(ets->tc_reco_tsa, dcbxcfg->etsrec.tsatable, 50b94b013eSDave Ertman sizeof(ets->tc_reco_tsa)); 51b94b013eSDave Ertman memcpy(ets->reco_prio_tc, dcbxcfg->etscfg.prio_table, 52b94b013eSDave Ertman sizeof(ets->reco_prio_tc)); 53b94b013eSDave Ertman 54b94b013eSDave Ertman return 0; 55b94b013eSDave Ertman } 56b94b013eSDave Ertman 57b94b013eSDave Ertman /** 58b94b013eSDave Ertman * ice_dcbnl_setets - set IEEE ETS configuration 59b94b013eSDave Ertman * @netdev: pointer to relevant netdev 60b94b013eSDave Ertman * @ets: struct to hold ETS configuration 61b94b013eSDave Ertman */ 62b94b013eSDave Ertman static int ice_dcbnl_setets(struct net_device *netdev, struct ieee_ets *ets) 63b94b013eSDave Ertman { 64b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 65b94b013eSDave Ertman struct ice_dcbx_cfg *new_cfg; 66b94b013eSDave Ertman int bwcfg = 0, bwrec = 0; 672a87bd73SDave Ertman int err, i; 68b94b013eSDave Ertman 69b94b013eSDave Ertman if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 70b94b013eSDave Ertman !(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) 71b94b013eSDave Ertman return -EINVAL; 72b94b013eSDave Ertman 73fc2d1165SChinh T Cao new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg; 74b94b013eSDave Ertman 75b94b013eSDave Ertman mutex_lock(&pf->tc_mutex); 76b94b013eSDave Ertman 77b94b013eSDave Ertman new_cfg->etscfg.willing = ets->willing; 78b94b013eSDave Ertman new_cfg->etscfg.cbs = ets->cbs; 79b94b013eSDave Ertman ice_for_each_traffic_class(i) { 80b94b013eSDave Ertman new_cfg->etscfg.tcbwtable[i] = ets->tc_tx_bw[i]; 81b94b013eSDave Ertman bwcfg += ets->tc_tx_bw[i]; 82b94b013eSDave Ertman new_cfg->etscfg.tsatable[i] = ets->tc_tsa[i]; 832a87bd73SDave Ertman if (new_cfg->pfc_mode == ICE_QOS_MODE_VLAN) { 842a87bd73SDave Ertman /* in DSCP mode up->tc mapping cannot change */ 85b94b013eSDave Ertman new_cfg->etscfg.prio_table[i] = ets->prio_tc[i]; 862a87bd73SDave Ertman new_cfg->etsrec.prio_table[i] = ets->reco_prio_tc[i]; 872a87bd73SDave Ertman } 88b94b013eSDave Ertman new_cfg->etsrec.tcbwtable[i] = ets->tc_reco_bw[i]; 89b94b013eSDave Ertman bwrec += ets->tc_reco_bw[i]; 90b94b013eSDave Ertman new_cfg->etsrec.tsatable[i] = ets->tc_reco_tsa[i]; 91b94b013eSDave Ertman } 92b94b013eSDave Ertman 93a29a912dSAvinash Dayanand if (ice_dcb_bwchk(pf, new_cfg)) { 94a29a912dSAvinash Dayanand err = -EINVAL; 95a29a912dSAvinash Dayanand goto ets_out; 96a29a912dSAvinash Dayanand } 97a29a912dSAvinash Dayanand 982a87bd73SDave Ertman new_cfg->etscfg.maxtcs = pf->hw.func_caps.common_cap.maxtc; 99b94b013eSDave Ertman 100b94b013eSDave Ertman if (!bwrec) 101b94b013eSDave Ertman new_cfg->etsrec.tcbwtable[0] = 100; 102b94b013eSDave Ertman 103b94b013eSDave Ertman err = ice_pf_dcb_cfg(pf, new_cfg, true); 104b94b013eSDave Ertman /* return of zero indicates new cfg applied */ 105b94b013eSDave Ertman if (err == ICE_DCB_HW_CHG_RST) 106b94b013eSDave Ertman ice_dcbnl_devreset(netdev); 107b94b013eSDave Ertman if (err == ICE_DCB_NO_HW_CHG) 108b94b013eSDave Ertman err = ICE_DCB_HW_CHG_RST; 109b94b013eSDave Ertman 110a29a912dSAvinash Dayanand ets_out: 111b94b013eSDave Ertman mutex_unlock(&pf->tc_mutex); 112b94b013eSDave Ertman return err; 113b94b013eSDave Ertman } 114b94b013eSDave Ertman 115b94b013eSDave Ertman /** 116b94b013eSDave Ertman * ice_dcbnl_getnumtcs - Get max number of traffic classes supported 117b94b013eSDave Ertman * @dev: pointer to netdev struct 118b94b013eSDave Ertman * @tcid: TC ID 119b94b013eSDave Ertman * @num: total number of TCs supported by the adapter 120b94b013eSDave Ertman * 121b94b013eSDave Ertman * Return the total number of TCs supported 122b94b013eSDave Ertman */ 123b94b013eSDave Ertman static int 124b94b013eSDave Ertman ice_dcbnl_getnumtcs(struct net_device *dev, int __always_unused tcid, u8 *num) 125b94b013eSDave Ertman { 126b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(dev); 127b94b013eSDave Ertman 128b94b013eSDave Ertman if (!test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags)) 129b94b013eSDave Ertman return -EINVAL; 130b94b013eSDave Ertman 1317dcf7aa0SDave Ertman *num = pf->hw.func_caps.common_cap.maxtc; 132b94b013eSDave Ertman return 0; 133b94b013eSDave Ertman } 134b94b013eSDave Ertman 135b94b013eSDave Ertman /** 136b94b013eSDave Ertman * ice_dcbnl_getdcbx - retrieve current DCBX capability 137b94b013eSDave Ertman * @netdev: pointer to the netdev struct 138b94b013eSDave Ertman */ 139b94b013eSDave Ertman static u8 ice_dcbnl_getdcbx(struct net_device *netdev) 140b94b013eSDave Ertman { 141b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 142b94b013eSDave Ertman 143b94b013eSDave Ertman return pf->dcbx_cap; 144b94b013eSDave Ertman } 145b94b013eSDave Ertman 146b94b013eSDave Ertman /** 147b94b013eSDave Ertman * ice_dcbnl_setdcbx - set required DCBX capability 148b94b013eSDave Ertman * @netdev: the corresponding netdev 149b94b013eSDave Ertman * @mode: required mode 150b94b013eSDave Ertman */ 151b94b013eSDave Ertman static u8 ice_dcbnl_setdcbx(struct net_device *netdev, u8 mode) 152b94b013eSDave Ertman { 153b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 154fc2d1165SChinh T Cao struct ice_qos_cfg *qos_cfg; 155b94b013eSDave Ertman 1560d4907f6SDave Ertman /* if FW LLDP agent is running, DCBNL not allowed to change mode */ 1570d4907f6SDave Ertman if (test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags)) 1580d4907f6SDave Ertman return ICE_DCB_NO_HW_CHG; 1590d4907f6SDave Ertman 160b94b013eSDave Ertman /* No support for LLD_MANAGED modes or CEE+IEEE */ 161b94b013eSDave Ertman if ((mode & DCB_CAP_DCBX_LLD_MANAGED) || 162b94b013eSDave Ertman ((mode & DCB_CAP_DCBX_VER_IEEE) && (mode & DCB_CAP_DCBX_VER_CEE)) || 163b94b013eSDave Ertman !(mode & DCB_CAP_DCBX_HOST)) 164b94b013eSDave Ertman return ICE_DCB_NO_HW_CHG; 165b94b013eSDave Ertman 166b94b013eSDave Ertman /* Already set to the given mode no change */ 167b94b013eSDave Ertman if (mode == pf->dcbx_cap) 168b94b013eSDave Ertman return ICE_DCB_NO_HW_CHG; 169b94b013eSDave Ertman 170b94b013eSDave Ertman pf->dcbx_cap = mode; 171fc2d1165SChinh T Cao qos_cfg = &pf->hw.port_info->qos_cfg; 1722a87bd73SDave Ertman if (mode & DCB_CAP_DCBX_VER_CEE) { 1732a87bd73SDave Ertman if (qos_cfg->local_dcbx_cfg.pfc_mode == ICE_QOS_MODE_DSCP) 1742a87bd73SDave Ertman return ICE_DCB_NO_HW_CHG; 175fc2d1165SChinh T Cao qos_cfg->local_dcbx_cfg.dcbx_mode = ICE_DCBX_MODE_CEE; 1762a87bd73SDave Ertman } else { 177fc2d1165SChinh T Cao qos_cfg->local_dcbx_cfg.dcbx_mode = ICE_DCBX_MODE_IEEE; 1782a87bd73SDave Ertman } 179b94b013eSDave Ertman 1804015d11eSBrett Creeley dev_info(ice_pf_to_dev(pf), "DCBx mode = 0x%x\n", mode); 181b94b013eSDave Ertman return ICE_DCB_HW_CHG_RST; 182b94b013eSDave Ertman } 183b94b013eSDave Ertman 184b94b013eSDave Ertman /** 185b94b013eSDave Ertman * ice_dcbnl_get_perm_hw_addr - MAC address used by DCBX 186b94b013eSDave Ertman * @netdev: pointer to netdev struct 187b94b013eSDave Ertman * @perm_addr: buffer to return permanent MAC address 188b94b013eSDave Ertman */ 189b94b013eSDave Ertman static void ice_dcbnl_get_perm_hw_addr(struct net_device *netdev, u8 *perm_addr) 190b94b013eSDave Ertman { 191b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 192b94b013eSDave Ertman struct ice_port_info *pi = pf->hw.port_info; 193b94b013eSDave Ertman int i, j; 194b94b013eSDave Ertman 195b94b013eSDave Ertman memset(perm_addr, 0xff, MAX_ADDR_LEN); 196b94b013eSDave Ertman 197b94b013eSDave Ertman for (i = 0; i < netdev->addr_len; i++) 198b94b013eSDave Ertman perm_addr[i] = pi->mac.perm_addr[i]; 199b94b013eSDave Ertman 200b94b013eSDave Ertman for (j = 0; j < netdev->addr_len; j++, i++) 201b94b013eSDave Ertman perm_addr[i] = pi->mac.perm_addr[j]; 202b94b013eSDave Ertman } 203b94b013eSDave Ertman 204b94b013eSDave Ertman /** 205b94b013eSDave Ertman * ice_get_pfc_delay - Retrieve PFC Link Delay 206b94b013eSDave Ertman * @hw: pointer to HW struct 207b94b013eSDave Ertman * @delay: holds the PFC Link Delay value 208b94b013eSDave Ertman */ 209b94b013eSDave Ertman static void ice_get_pfc_delay(struct ice_hw *hw, u16 *delay) 210b94b013eSDave Ertman { 211b94b013eSDave Ertman u32 val; 212b94b013eSDave Ertman 213b94b013eSDave Ertman val = rd32(hw, PRTDCB_GENC); 214b94b013eSDave Ertman *delay = (u16)((val & PRTDCB_GENC_PFCLDA_M) >> PRTDCB_GENC_PFCLDA_S); 215b94b013eSDave Ertman } 216b94b013eSDave Ertman 217b94b013eSDave Ertman /** 218b94b013eSDave Ertman * ice_dcbnl_getpfc - retrieve local IEEE PFC config 219b94b013eSDave Ertman * @netdev: pointer to netdev struct 220b94b013eSDave Ertman * @pfc: struct to hold PFC info 221b94b013eSDave Ertman */ 222b94b013eSDave Ertman static int ice_dcbnl_getpfc(struct net_device *netdev, struct ieee_pfc *pfc) 223b94b013eSDave Ertman { 224b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 225b94b013eSDave Ertman struct ice_port_info *pi = pf->hw.port_info; 226b94b013eSDave Ertman struct ice_dcbx_cfg *dcbxcfg; 227b94b013eSDave Ertman int i; 228b94b013eSDave Ertman 229fc2d1165SChinh T Cao dcbxcfg = &pi->qos_cfg.local_dcbx_cfg; 230b94b013eSDave Ertman pfc->pfc_cap = dcbxcfg->pfc.pfccap; 231b94b013eSDave Ertman pfc->pfc_en = dcbxcfg->pfc.pfcena; 232b94b013eSDave Ertman pfc->mbc = dcbxcfg->pfc.mbc; 233b94b013eSDave Ertman ice_get_pfc_delay(&pf->hw, &pfc->delay); 234b94b013eSDave Ertman 235b94b013eSDave Ertman ice_for_each_traffic_class(i) { 236b94b013eSDave Ertman pfc->requests[i] = pf->stats.priority_xoff_tx[i]; 237b94b013eSDave Ertman pfc->indications[i] = pf->stats.priority_xoff_rx[i]; 238b94b013eSDave Ertman } 239b94b013eSDave Ertman 240b94b013eSDave Ertman return 0; 241b94b013eSDave Ertman } 242b94b013eSDave Ertman 243b94b013eSDave Ertman /** 244b94b013eSDave Ertman * ice_dcbnl_setpfc - set local IEEE PFC config 245b94b013eSDave Ertman * @netdev: pointer to relevant netdev 246b94b013eSDave Ertman * @pfc: pointer to struct holding PFC config 247b94b013eSDave Ertman */ 248b94b013eSDave Ertman static int ice_dcbnl_setpfc(struct net_device *netdev, struct ieee_pfc *pfc) 249b94b013eSDave Ertman { 250b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 251b94b013eSDave Ertman struct ice_dcbx_cfg *new_cfg; 252b94b013eSDave Ertman int err; 253b94b013eSDave Ertman 254b94b013eSDave Ertman if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 255b94b013eSDave Ertman !(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) 256b94b013eSDave Ertman return -EINVAL; 257b94b013eSDave Ertman 258b94b013eSDave Ertman mutex_lock(&pf->tc_mutex); 259b94b013eSDave Ertman 260fc2d1165SChinh T Cao new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg; 261b94b013eSDave Ertman 262b94b013eSDave Ertman if (pfc->pfc_cap) 263b94b013eSDave Ertman new_cfg->pfc.pfccap = pfc->pfc_cap; 264b94b013eSDave Ertman else 265b94b013eSDave Ertman new_cfg->pfc.pfccap = pf->hw.func_caps.common_cap.maxtc; 266b94b013eSDave Ertman 267b94b013eSDave Ertman new_cfg->pfc.pfcena = pfc->pfc_en; 268b94b013eSDave Ertman 269b94b013eSDave Ertman err = ice_pf_dcb_cfg(pf, new_cfg, true); 270b94b013eSDave Ertman if (err == ICE_DCB_HW_CHG_RST) 271b94b013eSDave Ertman ice_dcbnl_devreset(netdev); 272b94b013eSDave Ertman if (err == ICE_DCB_NO_HW_CHG) 273b94b013eSDave Ertman err = ICE_DCB_HW_CHG_RST; 274b94b013eSDave Ertman mutex_unlock(&pf->tc_mutex); 275b94b013eSDave Ertman return err; 276b94b013eSDave Ertman } 277b94b013eSDave Ertman 278b94b013eSDave Ertman /** 279b94b013eSDave Ertman * ice_dcbnl_get_pfc_cfg - Get CEE PFC config 280b94b013eSDave Ertman * @netdev: pointer to netdev struct 281b94b013eSDave Ertman * @prio: corresponding user priority 282b94b013eSDave Ertman * @setting: the PFC setting for given priority 283b94b013eSDave Ertman */ 284b94b013eSDave Ertman static void 285b94b013eSDave Ertman ice_dcbnl_get_pfc_cfg(struct net_device *netdev, int prio, u8 *setting) 286b94b013eSDave Ertman { 287b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 288b94b013eSDave Ertman struct ice_port_info *pi = pf->hw.port_info; 289b94b013eSDave Ertman 290b94b013eSDave Ertman if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 291b94b013eSDave Ertman !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 292b94b013eSDave Ertman return; 293b94b013eSDave Ertman 294b94b013eSDave Ertman if (prio >= ICE_MAX_USER_PRIORITY) 295b94b013eSDave Ertman return; 296b94b013eSDave Ertman 297fc2d1165SChinh T Cao *setting = (pi->qos_cfg.local_dcbx_cfg.pfc.pfcena >> prio) & 0x1; 29819cce2c6SAnirudh Venkataramanan dev_dbg(ice_pf_to_dev(pf), "Get PFC Config up=%d, setting=%d, pfcenable=0x%x\n", 299fc2d1165SChinh T Cao prio, *setting, pi->qos_cfg.local_dcbx_cfg.pfc.pfcena); 300b94b013eSDave Ertman } 301b94b013eSDave Ertman 302b94b013eSDave Ertman /** 303b94b013eSDave Ertman * ice_dcbnl_set_pfc_cfg - Set CEE PFC config 304b94b013eSDave Ertman * @netdev: the corresponding netdev 305b94b013eSDave Ertman * @prio: User Priority 306b94b013eSDave Ertman * @set: PFC setting to apply 307b94b013eSDave Ertman */ 308b94b013eSDave Ertman static void ice_dcbnl_set_pfc_cfg(struct net_device *netdev, int prio, u8 set) 309b94b013eSDave Ertman { 310b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 311b94b013eSDave Ertman struct ice_dcbx_cfg *new_cfg; 312b94b013eSDave Ertman 313b94b013eSDave Ertman if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 314b94b013eSDave Ertman !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 315b94b013eSDave Ertman return; 316b94b013eSDave Ertman 317b94b013eSDave Ertman if (prio >= ICE_MAX_USER_PRIORITY) 318b94b013eSDave Ertman return; 319b94b013eSDave Ertman 320fc2d1165SChinh T Cao new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg; 321b94b013eSDave Ertman 322b94b013eSDave Ertman new_cfg->pfc.pfccap = pf->hw.func_caps.common_cap.maxtc; 323b94b013eSDave Ertman if (set) 324b94b013eSDave Ertman new_cfg->pfc.pfcena |= BIT(prio); 325b94b013eSDave Ertman else 326b94b013eSDave Ertman new_cfg->pfc.pfcena &= ~BIT(prio); 327b94b013eSDave Ertman 3284015d11eSBrett Creeley dev_dbg(ice_pf_to_dev(pf), "Set PFC config UP:%d set:%d pfcena:0x%x\n", 329b94b013eSDave Ertman prio, set, new_cfg->pfc.pfcena); 330b94b013eSDave Ertman } 331b94b013eSDave Ertman 332b94b013eSDave Ertman /** 333b94b013eSDave Ertman * ice_dcbnl_getpfcstate - get CEE PFC mode 334b94b013eSDave Ertman * @netdev: pointer to netdev struct 335b94b013eSDave Ertman */ 336b94b013eSDave Ertman static u8 ice_dcbnl_getpfcstate(struct net_device *netdev) 337b94b013eSDave Ertman { 338b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 339b94b013eSDave Ertman struct ice_port_info *pi = pf->hw.port_info; 340b94b013eSDave Ertman 341b94b013eSDave Ertman /* Return enabled if any UP enabled for PFC */ 342fc2d1165SChinh T Cao if (pi->qos_cfg.local_dcbx_cfg.pfc.pfcena) 343b94b013eSDave Ertman return 1; 344b94b013eSDave Ertman 345b94b013eSDave Ertman return 0; 346b94b013eSDave Ertman } 347b94b013eSDave Ertman 348b94b013eSDave Ertman /** 349b94b013eSDave Ertman * ice_dcbnl_getstate - get DCB enabled state 350b94b013eSDave Ertman * @netdev: pointer to netdev struct 351b94b013eSDave Ertman */ 352b94b013eSDave Ertman static u8 ice_dcbnl_getstate(struct net_device *netdev) 353b94b013eSDave Ertman { 354b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 355b94b013eSDave Ertman u8 state = 0; 356b94b013eSDave Ertman 357b94b013eSDave Ertman state = test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags); 358b94b013eSDave Ertman 3594015d11eSBrett Creeley dev_dbg(ice_pf_to_dev(pf), "DCB enabled state = %d\n", state); 360b94b013eSDave Ertman return state; 361b94b013eSDave Ertman } 362b94b013eSDave Ertman 363b94b013eSDave Ertman /** 364b94b013eSDave Ertman * ice_dcbnl_setstate - Set CEE DCB state 365b94b013eSDave Ertman * @netdev: pointer to relevant netdev 366b94b013eSDave Ertman * @state: state value to set 367b94b013eSDave Ertman */ 368b94b013eSDave Ertman static u8 ice_dcbnl_setstate(struct net_device *netdev, u8 state) 369b94b013eSDave Ertman { 370b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 371b94b013eSDave Ertman 372b94b013eSDave Ertman if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 373b94b013eSDave Ertman !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 374b94b013eSDave Ertman return ICE_DCB_NO_HW_CHG; 375b94b013eSDave Ertman 376b94b013eSDave Ertman /* Nothing to do */ 377b94b013eSDave Ertman if (!!state == test_bit(ICE_FLAG_DCB_ENA, pf->flags)) 378b94b013eSDave Ertman return ICE_DCB_NO_HW_CHG; 379b94b013eSDave Ertman 380b94b013eSDave Ertman if (state) { 381b94b013eSDave Ertman set_bit(ICE_FLAG_DCB_ENA, pf->flags); 382fc2d1165SChinh T Cao memcpy(&pf->hw.port_info->qos_cfg.desired_dcbx_cfg, 383fc2d1165SChinh T Cao &pf->hw.port_info->qos_cfg.local_dcbx_cfg, 384b94b013eSDave Ertman sizeof(struct ice_dcbx_cfg)); 385b94b013eSDave Ertman } else { 386b94b013eSDave Ertman clear_bit(ICE_FLAG_DCB_ENA, pf->flags); 387b94b013eSDave Ertman } 388b94b013eSDave Ertman 389b94b013eSDave Ertman return ICE_DCB_HW_CHG; 390b94b013eSDave Ertman } 391b94b013eSDave Ertman 392b94b013eSDave Ertman /** 393b94b013eSDave Ertman * ice_dcbnl_get_pg_tc_cfg_tx - get CEE PG Tx config 394b94b013eSDave Ertman * @netdev: pointer to netdev struct 395b94b013eSDave Ertman * @prio: the corresponding user priority 396b94b013eSDave Ertman * @prio_type: traffic priority type 397b94b013eSDave Ertman * @pgid: the BW group ID the traffic class belongs to 398b94b013eSDave Ertman * @bw_pct: BW percentage for the corresponding BWG 399b94b013eSDave Ertman * @up_map: prio mapped to corresponding TC 400b94b013eSDave Ertman */ 401b94b013eSDave Ertman static void 402b94b013eSDave Ertman ice_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int prio, 403b94b013eSDave Ertman u8 __always_unused *prio_type, u8 *pgid, 404b94b013eSDave Ertman u8 __always_unused *bw_pct, 405b94b013eSDave Ertman u8 __always_unused *up_map) 406b94b013eSDave Ertman { 407b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 408b94b013eSDave Ertman struct ice_port_info *pi = pf->hw.port_info; 409b94b013eSDave Ertman 410b94b013eSDave Ertman if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 411b94b013eSDave Ertman !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 412b94b013eSDave Ertman return; 413b94b013eSDave Ertman 414b94b013eSDave Ertman if (prio >= ICE_MAX_USER_PRIORITY) 415b94b013eSDave Ertman return; 416b94b013eSDave Ertman 417fc2d1165SChinh T Cao *pgid = pi->qos_cfg.local_dcbx_cfg.etscfg.prio_table[prio]; 41819cce2c6SAnirudh Venkataramanan dev_dbg(ice_pf_to_dev(pf), "Get PG config prio=%d tc=%d\n", prio, 41919cce2c6SAnirudh Venkataramanan *pgid); 420b94b013eSDave Ertman } 421b94b013eSDave Ertman 422b94b013eSDave Ertman /** 423b94b013eSDave Ertman * ice_dcbnl_set_pg_tc_cfg_tx - set CEE PG Tx config 424b94b013eSDave Ertman * @netdev: pointer to relevant netdev 425b94b013eSDave Ertman * @tc: the corresponding traffic class 426b94b013eSDave Ertman * @prio_type: the traffic priority type 427b94b013eSDave Ertman * @bwg_id: the BW group ID the TC belongs to 428b94b013eSDave Ertman * @bw_pct: the BW perventage for the BWG 429b94b013eSDave Ertman * @up_map: prio mapped to corresponding TC 430b94b013eSDave Ertman */ 431b94b013eSDave Ertman static void 432b94b013eSDave Ertman ice_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc, 433b94b013eSDave Ertman u8 __always_unused prio_type, 434b94b013eSDave Ertman u8 __always_unused bwg_id, 435b94b013eSDave Ertman u8 __always_unused bw_pct, u8 up_map) 436b94b013eSDave Ertman { 437b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 438b94b013eSDave Ertman struct ice_dcbx_cfg *new_cfg; 439b94b013eSDave Ertman int i; 440b94b013eSDave Ertman 441b94b013eSDave Ertman if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 442b94b013eSDave Ertman !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 443b94b013eSDave Ertman return; 444b94b013eSDave Ertman 445b94b013eSDave Ertman if (tc >= ICE_MAX_TRAFFIC_CLASS) 446b94b013eSDave Ertman return; 447b94b013eSDave Ertman 448fc2d1165SChinh T Cao new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg; 449b94b013eSDave Ertman 450b94b013eSDave Ertman /* prio_type, bwg_id and bw_pct per UP are not supported */ 451b94b013eSDave Ertman 452b94b013eSDave Ertman ice_for_each_traffic_class(i) { 453b94b013eSDave Ertman if (up_map & BIT(i)) 454b94b013eSDave Ertman new_cfg->etscfg.prio_table[i] = tc; 455b94b013eSDave Ertman } 456b94b013eSDave Ertman new_cfg->etscfg.tsatable[tc] = ICE_IEEE_TSA_ETS; 457b94b013eSDave Ertman } 458b94b013eSDave Ertman 459b94b013eSDave Ertman /** 460b94b013eSDave Ertman * ice_dcbnl_get_pg_bwg_cfg_tx - Get CEE PGBW config 461b94b013eSDave Ertman * @netdev: pointer to the netdev struct 462b94b013eSDave Ertman * @pgid: corresponding traffic class 463b94b013eSDave Ertman * @bw_pct: the BW percentage for the corresponding TC 464b94b013eSDave Ertman */ 465b94b013eSDave Ertman static void 466b94b013eSDave Ertman ice_dcbnl_get_pg_bwg_cfg_tx(struct net_device *netdev, int pgid, u8 *bw_pct) 467b94b013eSDave Ertman { 468b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 469b94b013eSDave Ertman struct ice_port_info *pi = pf->hw.port_info; 470b94b013eSDave Ertman 471b94b013eSDave Ertman if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 472b94b013eSDave Ertman !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 473b94b013eSDave Ertman return; 474b94b013eSDave Ertman 475b94b013eSDave Ertman if (pgid >= ICE_MAX_TRAFFIC_CLASS) 476b94b013eSDave Ertman return; 477b94b013eSDave Ertman 478fc2d1165SChinh T Cao *bw_pct = pi->qos_cfg.local_dcbx_cfg.etscfg.tcbwtable[pgid]; 4794015d11eSBrett Creeley dev_dbg(ice_pf_to_dev(pf), "Get PG BW config tc=%d bw_pct=%d\n", 480b94b013eSDave Ertman pgid, *bw_pct); 481b94b013eSDave Ertman } 482b94b013eSDave Ertman 483b94b013eSDave Ertman /** 484b94b013eSDave Ertman * ice_dcbnl_set_pg_bwg_cfg_tx - set CEE PG Tx BW config 485b94b013eSDave Ertman * @netdev: the corresponding netdev 486b94b013eSDave Ertman * @pgid: Correspongind traffic class 487b94b013eSDave Ertman * @bw_pct: the BW percentage for the specified TC 488b94b013eSDave Ertman */ 489b94b013eSDave Ertman static void 490b94b013eSDave Ertman ice_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int pgid, u8 bw_pct) 491b94b013eSDave Ertman { 492b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 493b94b013eSDave Ertman struct ice_dcbx_cfg *new_cfg; 494b94b013eSDave Ertman 495b94b013eSDave Ertman if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 496b94b013eSDave Ertman !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 497b94b013eSDave Ertman return; 498b94b013eSDave Ertman 499b94b013eSDave Ertman if (pgid >= ICE_MAX_TRAFFIC_CLASS) 500b94b013eSDave Ertman return; 501b94b013eSDave Ertman 502fc2d1165SChinh T Cao new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg; 503b94b013eSDave Ertman 504b94b013eSDave Ertman new_cfg->etscfg.tcbwtable[pgid] = bw_pct; 505b94b013eSDave Ertman } 506b94b013eSDave Ertman 507b94b013eSDave Ertman /** 508b94b013eSDave Ertman * ice_dcbnl_get_pg_tc_cfg_rx - Get CEE PG Rx config 509b94b013eSDave Ertman * @netdev: pointer to netdev struct 510b94b013eSDave Ertman * @prio: the corresponding user priority 511b94b013eSDave Ertman * @prio_type: the traffic priority type 512b94b013eSDave Ertman * @pgid: the PG ID 513b94b013eSDave Ertman * @bw_pct: the BW percentage for the corresponding BWG 514b94b013eSDave Ertman * @up_map: prio mapped to corresponding TC 515b94b013eSDave Ertman */ 516b94b013eSDave Ertman static void 517b94b013eSDave Ertman ice_dcbnl_get_pg_tc_cfg_rx(struct net_device *netdev, int prio, 518b94b013eSDave Ertman u8 __always_unused *prio_type, u8 *pgid, 519b94b013eSDave Ertman u8 __always_unused *bw_pct, 520b94b013eSDave Ertman u8 __always_unused *up_map) 521b94b013eSDave Ertman { 522b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 523b94b013eSDave Ertman struct ice_port_info *pi = pf->hw.port_info; 524b94b013eSDave Ertman 525b94b013eSDave Ertman if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 526b94b013eSDave Ertman !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 527b94b013eSDave Ertman return; 528b94b013eSDave Ertman 529b94b013eSDave Ertman if (prio >= ICE_MAX_USER_PRIORITY) 530b94b013eSDave Ertman return; 531b94b013eSDave Ertman 532fc2d1165SChinh T Cao *pgid = pi->qos_cfg.local_dcbx_cfg.etscfg.prio_table[prio]; 533b94b013eSDave Ertman } 534b94b013eSDave Ertman 535b94b013eSDave Ertman /** 536c8608b50SAvinash JD * ice_dcbnl_set_pg_tc_cfg_rx 537c8608b50SAvinash JD * @netdev: relevant netdev struct 538c8608b50SAvinash JD * @prio: corresponding user priority 539c8608b50SAvinash JD * @prio_type: the traffic priority type 540c8608b50SAvinash JD * @pgid: the PG ID 541c8608b50SAvinash JD * @bw_pct: BW percentage for corresponding BWG 542c8608b50SAvinash JD * @up_map: prio mapped to corresponding TC 543c8608b50SAvinash JD * 544c8608b50SAvinash JD * lldpad requires this function pointer to be non-NULL to complete CEE config. 545c8608b50SAvinash JD */ 546c8608b50SAvinash JD static void 547c8608b50SAvinash JD ice_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, 548c8608b50SAvinash JD int __always_unused prio, 549c8608b50SAvinash JD u8 __always_unused prio_type, 550c8608b50SAvinash JD u8 __always_unused pgid, 551c8608b50SAvinash JD u8 __always_unused bw_pct, 552c8608b50SAvinash JD u8 __always_unused up_map) 553c8608b50SAvinash JD { 554c8608b50SAvinash JD struct ice_pf *pf = ice_netdev_to_pf(netdev); 555c8608b50SAvinash JD 556c8608b50SAvinash JD dev_dbg(ice_pf_to_dev(pf), "Rx TC PG Config Not Supported.\n"); 557c8608b50SAvinash JD } 558c8608b50SAvinash JD 559c8608b50SAvinash JD /** 560b94b013eSDave Ertman * ice_dcbnl_get_pg_bwg_cfg_rx - Get CEE PG BW Rx config 561b94b013eSDave Ertman * @netdev: pointer to netdev struct 562b94b013eSDave Ertman * @pgid: the corresponding traffic class 563b94b013eSDave Ertman * @bw_pct: the BW percentage for the corresponding TC 564b94b013eSDave Ertman */ 565b94b013eSDave Ertman static void 566b94b013eSDave Ertman ice_dcbnl_get_pg_bwg_cfg_rx(struct net_device *netdev, int __always_unused pgid, 567b94b013eSDave Ertman u8 *bw_pct) 568b94b013eSDave Ertman { 569b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 570b94b013eSDave Ertman 571b94b013eSDave Ertman if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 572b94b013eSDave Ertman !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 573b94b013eSDave Ertman return; 574b94b013eSDave Ertman 575b94b013eSDave Ertman *bw_pct = 0; 576b94b013eSDave Ertman } 577b94b013eSDave Ertman 578b94b013eSDave Ertman /** 579c8608b50SAvinash JD * ice_dcbnl_set_pg_bwg_cfg_rx 580c8608b50SAvinash JD * @netdev: the corresponding netdev 581c8608b50SAvinash JD * @pgid: corresponding TC 582c8608b50SAvinash JD * @bw_pct: BW percentage for given TC 583c8608b50SAvinash JD * 584c8608b50SAvinash JD * lldpad requires this function pointer to be non-NULL to complete CEE config. 585c8608b50SAvinash JD */ 586c8608b50SAvinash JD static void 587c8608b50SAvinash JD ice_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int __always_unused pgid, 588c8608b50SAvinash JD u8 __always_unused bw_pct) 589c8608b50SAvinash JD { 590c8608b50SAvinash JD struct ice_pf *pf = ice_netdev_to_pf(netdev); 591c8608b50SAvinash JD 592c8608b50SAvinash JD dev_dbg(ice_pf_to_dev(pf), "Rx BWG PG Config Not Supported.\n"); 593c8608b50SAvinash JD } 594c8608b50SAvinash JD 595c8608b50SAvinash JD /** 596b94b013eSDave Ertman * ice_dcbnl_get_cap - Get DCBX capabilities of adapter 597b94b013eSDave Ertman * @netdev: pointer to netdev struct 598b94b013eSDave Ertman * @capid: the capability type 599b94b013eSDave Ertman * @cap: the capability value 600b94b013eSDave Ertman */ 601b94b013eSDave Ertman static u8 ice_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap) 602b94b013eSDave Ertman { 603b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 604b94b013eSDave Ertman 605b94b013eSDave Ertman if (!(test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags))) 606b94b013eSDave Ertman return ICE_DCB_NO_HW_CHG; 607b94b013eSDave Ertman 608b94b013eSDave Ertman switch (capid) { 609b94b013eSDave Ertman case DCB_CAP_ATTR_PG: 610b94b013eSDave Ertman *cap = true; 611b94b013eSDave Ertman break; 612b94b013eSDave Ertman case DCB_CAP_ATTR_PFC: 613b94b013eSDave Ertman *cap = true; 614b94b013eSDave Ertman break; 615b94b013eSDave Ertman case DCB_CAP_ATTR_UP2TC: 616b94b013eSDave Ertman *cap = false; 617b94b013eSDave Ertman break; 618b94b013eSDave Ertman case DCB_CAP_ATTR_PG_TCS: 619b94b013eSDave Ertman *cap = 0x80; 620b94b013eSDave Ertman break; 621b94b013eSDave Ertman case DCB_CAP_ATTR_PFC_TCS: 622b94b013eSDave Ertman *cap = 0x80; 623b94b013eSDave Ertman break; 624b94b013eSDave Ertman case DCB_CAP_ATTR_GSP: 625b94b013eSDave Ertman *cap = false; 626b94b013eSDave Ertman break; 627b94b013eSDave Ertman case DCB_CAP_ATTR_BCN: 628b94b013eSDave Ertman *cap = false; 629b94b013eSDave Ertman break; 630b94b013eSDave Ertman case DCB_CAP_ATTR_DCBX: 631b94b013eSDave Ertman *cap = pf->dcbx_cap; 632b94b013eSDave Ertman break; 633b94b013eSDave Ertman default: 634b94b013eSDave Ertman *cap = false; 635b94b013eSDave Ertman break; 636b94b013eSDave Ertman } 637b94b013eSDave Ertman 6384015d11eSBrett Creeley dev_dbg(ice_pf_to_dev(pf), "DCBX Get Capability cap=%d capval=0x%x\n", 639b94b013eSDave Ertman capid, *cap); 640b94b013eSDave Ertman return 0; 641b94b013eSDave Ertman } 642b94b013eSDave Ertman 643b94b013eSDave Ertman /** 644b94b013eSDave Ertman * ice_dcbnl_getapp - get CEE APP 645b94b013eSDave Ertman * @netdev: pointer to netdev struct 646b94b013eSDave Ertman * @idtype: the App selector 647b94b013eSDave Ertman * @id: the App ethtype or port number 648b94b013eSDave Ertman */ 649b94b013eSDave Ertman static int ice_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id) 650b94b013eSDave Ertman { 651b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 652b94b013eSDave Ertman struct dcb_app app = { 653b94b013eSDave Ertman .selector = idtype, 654b94b013eSDave Ertman .protocol = id, 655b94b013eSDave Ertman }; 656b94b013eSDave Ertman 657b94b013eSDave Ertman if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 658b94b013eSDave Ertman !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 659b94b013eSDave Ertman return -EINVAL; 660b94b013eSDave Ertman 661b94b013eSDave Ertman return dcb_getapp(netdev, &app); 662b94b013eSDave Ertman } 663b94b013eSDave Ertman 664b94b013eSDave Ertman /** 665b94b013eSDave Ertman * ice_dcbnl_find_app - Search for APP in given DCB config 666b94b013eSDave Ertman * @cfg: struct to hold DCBX config 667b94b013eSDave Ertman * @app: struct to hold app data to look for 668b94b013eSDave Ertman */ 669b94b013eSDave Ertman static bool 670b94b013eSDave Ertman ice_dcbnl_find_app(struct ice_dcbx_cfg *cfg, 671b94b013eSDave Ertman struct ice_dcb_app_priority_table *app) 672b94b013eSDave Ertman { 673c1e08830SJesse Brandeburg unsigned int i; 674b94b013eSDave Ertman 675b94b013eSDave Ertman for (i = 0; i < cfg->numapps; i++) { 676b94b013eSDave Ertman if (app->selector == cfg->app[i].selector && 677b94b013eSDave Ertman app->prot_id == cfg->app[i].prot_id && 678b94b013eSDave Ertman app->priority == cfg->app[i].priority) 679b94b013eSDave Ertman return true; 680b94b013eSDave Ertman } 681b94b013eSDave Ertman 682b94b013eSDave Ertman return false; 683b94b013eSDave Ertman } 684b94b013eSDave Ertman 6852a87bd73SDave Ertman #define ICE_BYTES_PER_DSCP_VAL 8 6862a87bd73SDave Ertman 687b94b013eSDave Ertman /** 688b94b013eSDave Ertman * ice_dcbnl_setapp - set local IEEE App config 689b94b013eSDave Ertman * @netdev: relevant netdev struct 690b94b013eSDave Ertman * @app: struct to hold app config info 691b94b013eSDave Ertman */ 692b94b013eSDave Ertman static int ice_dcbnl_setapp(struct net_device *netdev, struct dcb_app *app) 693b94b013eSDave Ertman { 694b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 695b94b013eSDave Ertman struct ice_dcb_app_priority_table new_app; 696b94b013eSDave Ertman struct ice_dcbx_cfg *old_cfg, *new_cfg; 6972a87bd73SDave Ertman u8 max_tc; 698b94b013eSDave Ertman int ret; 699b94b013eSDave Ertman 7002a87bd73SDave Ertman /* ONLY DSCP APP TLVs have operational significance */ 7012a87bd73SDave Ertman if (app->selector != IEEE_8021QAZ_APP_SEL_DSCP) 702b94b013eSDave Ertman return -EINVAL; 703b94b013eSDave Ertman 7042a87bd73SDave Ertman /* only allow APP TLVs in SW Mode */ 7052a87bd73SDave Ertman if (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) { 7062a87bd73SDave Ertman netdev_err(netdev, "can't do DSCP QoS when FW DCB agent active\n"); 7072a87bd73SDave Ertman return -EINVAL; 7082a87bd73SDave Ertman } 7092a87bd73SDave Ertman 7102a87bd73SDave Ertman if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) 7112a87bd73SDave Ertman return -EINVAL; 7122a87bd73SDave Ertman 713*40b24760SAnirudh Venkataramanan if (!ice_is_feature_supported(pf, ICE_F_DSCP)) 714*40b24760SAnirudh Venkataramanan return -EOPNOTSUPP; 715*40b24760SAnirudh Venkataramanan 7162a87bd73SDave Ertman if (app->protocol >= ICE_DSCP_NUM_VAL) { 7172a87bd73SDave Ertman netdev_err(netdev, "DSCP value 0x%04X out of range\n", 7182a87bd73SDave Ertman app->protocol); 7192a87bd73SDave Ertman return -EINVAL; 7202a87bd73SDave Ertman } 7212a87bd73SDave Ertman 7222a87bd73SDave Ertman max_tc = pf->hw.func_caps.common_cap.maxtc; 7232a87bd73SDave Ertman if (app->priority >= max_tc) { 7242a87bd73SDave Ertman netdev_err(netdev, "TC %d out of range, max TC %d\n", 7252a87bd73SDave Ertman app->priority, max_tc); 7262a87bd73SDave Ertman return -EINVAL; 7272a87bd73SDave Ertman } 7282a87bd73SDave Ertman 7292a87bd73SDave Ertman /* grab TC mutex */ 730b94b013eSDave Ertman mutex_lock(&pf->tc_mutex); 731b94b013eSDave Ertman 732fc2d1165SChinh T Cao new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg; 733fc2d1165SChinh T Cao old_cfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg; 734b94b013eSDave Ertman 735b94b013eSDave Ertman ret = dcb_ieee_setapp(netdev, app); 736b94b013eSDave Ertman if (ret) 737b94b013eSDave Ertman goto setapp_out; 738b94b013eSDave Ertman 7392a87bd73SDave Ertman if (test_and_set_bit(app->protocol, new_cfg->dscp_mapped)) { 7402a87bd73SDave Ertman netdev_err(netdev, "DSCP value 0x%04X already user mapped\n", 7412a87bd73SDave Ertman app->protocol); 7422a87bd73SDave Ertman ret = dcb_ieee_delapp(netdev, app); 7432a87bd73SDave Ertman if (ret) 7442a87bd73SDave Ertman netdev_err(netdev, "Failed to delete re-mapping TLV\n"); 7452a87bd73SDave Ertman ret = -EINVAL; 746b94b013eSDave Ertman goto setapp_out; 747b94b013eSDave Ertman } 748b94b013eSDave Ertman 7492a87bd73SDave Ertman new_app.selector = app->selector; 7502a87bd73SDave Ertman new_app.prot_id = app->protocol; 7512a87bd73SDave Ertman new_app.priority = app->priority; 7522a87bd73SDave Ertman 7532a87bd73SDave Ertman /* If port is not in DSCP mode, need to set */ 7542a87bd73SDave Ertman if (old_cfg->pfc_mode == ICE_QOS_MODE_VLAN) { 7552a87bd73SDave Ertman int i, j; 7562a87bd73SDave Ertman 7572a87bd73SDave Ertman /* set DSCP mode */ 7582a87bd73SDave Ertman ret = ice_aq_set_pfc_mode(&pf->hw, ICE_AQC_PFC_DSCP_BASED_PFC, 7592a87bd73SDave Ertman NULL); 7602a87bd73SDave Ertman if (ret) { 7612a87bd73SDave Ertman netdev_err(netdev, "Failed to set DSCP PFC mode %d\n", 7622a87bd73SDave Ertman ret); 7632a87bd73SDave Ertman goto setapp_out; 7642a87bd73SDave Ertman } 7652a87bd73SDave Ertman netdev_info(netdev, "Switched QoS to L3 DSCP mode\n"); 7662a87bd73SDave Ertman 7672a87bd73SDave Ertman new_cfg->pfc_mode = ICE_QOS_MODE_DSCP; 7682a87bd73SDave Ertman 7692a87bd73SDave Ertman /* set default DSCP QoS values */ 7702a87bd73SDave Ertman new_cfg->etscfg.willing = 0; 7712a87bd73SDave Ertman new_cfg->pfc.pfccap = max_tc; 7722a87bd73SDave Ertman new_cfg->pfc.willing = 0; 7732a87bd73SDave Ertman 7742a87bd73SDave Ertman for (i = 0; i < max_tc; i++) 7752a87bd73SDave Ertman for (j = 0; j < ICE_BYTES_PER_DSCP_VAL; j++) { 7762a87bd73SDave Ertman int dscp, offset; 7772a87bd73SDave Ertman 7782a87bd73SDave Ertman dscp = (i * max_tc) + j; 7792a87bd73SDave Ertman offset = max_tc * ICE_BYTES_PER_DSCP_VAL; 7802a87bd73SDave Ertman 7812a87bd73SDave Ertman new_cfg->dscp_map[dscp] = i; 7822a87bd73SDave Ertman /* if less that 8 TCs supported */ 7832a87bd73SDave Ertman if (max_tc < ICE_MAX_TRAFFIC_CLASS) 7842a87bd73SDave Ertman new_cfg->dscp_map[dscp + offset] = i; 7852a87bd73SDave Ertman } 7862a87bd73SDave Ertman 7872a87bd73SDave Ertman new_cfg->etscfg.tcbwtable[0] = 100; 7882a87bd73SDave Ertman new_cfg->etscfg.tsatable[0] = ICE_IEEE_TSA_ETS; 7892a87bd73SDave Ertman new_cfg->etscfg.prio_table[0] = 0; 7902a87bd73SDave Ertman 7912a87bd73SDave Ertman for (i = 1; i < max_tc; i++) { 7922a87bd73SDave Ertman new_cfg->etscfg.tcbwtable[i] = 0; 7932a87bd73SDave Ertman new_cfg->etscfg.tsatable[i] = ICE_IEEE_TSA_ETS; 7942a87bd73SDave Ertman new_cfg->etscfg.prio_table[i] = i; 7952a87bd73SDave Ertman } 7962a87bd73SDave Ertman } /* end of switching to DSCP mode */ 7972a87bd73SDave Ertman 7982a87bd73SDave Ertman /* apply new mapping for this DSCP value */ 7992a87bd73SDave Ertman new_cfg->dscp_map[app->protocol] = app->priority; 800b94b013eSDave Ertman new_cfg->app[new_cfg->numapps++] = new_app; 8012a87bd73SDave Ertman 802b94b013eSDave Ertman ret = ice_pf_dcb_cfg(pf, new_cfg, true); 803b94b013eSDave Ertman /* return of zero indicates new cfg applied */ 804b94b013eSDave Ertman if (ret == ICE_DCB_HW_CHG_RST) 805b94b013eSDave Ertman ice_dcbnl_devreset(netdev); 8062a87bd73SDave Ertman else 8072a87bd73SDave Ertman ret = ICE_DCB_NO_HW_CHG; 808b94b013eSDave Ertman 809b94b013eSDave Ertman setapp_out: 810b94b013eSDave Ertman mutex_unlock(&pf->tc_mutex); 811b94b013eSDave Ertman return ret; 812b94b013eSDave Ertman } 813b94b013eSDave Ertman 814b94b013eSDave Ertman /** 815b94b013eSDave Ertman * ice_dcbnl_delapp - Delete local IEEE App config 816b94b013eSDave Ertman * @netdev: relevant netdev 817b94b013eSDave Ertman * @app: struct to hold app too delete 818b94b013eSDave Ertman * 819b94b013eSDave Ertman * Will not delete first application required by the FW 820b94b013eSDave Ertman */ 821b94b013eSDave Ertman static int ice_dcbnl_delapp(struct net_device *netdev, struct dcb_app *app) 822b94b013eSDave Ertman { 823b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 824b94b013eSDave Ertman struct ice_dcbx_cfg *old_cfg, *new_cfg; 825c1e08830SJesse Brandeburg unsigned int i, j; 826c1e08830SJesse Brandeburg int ret = 0; 827b94b013eSDave Ertman 8282a87bd73SDave Ertman if (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) { 8292a87bd73SDave Ertman netdev_err(netdev, "can't delete DSCP netlink app when FW DCB agent is active\n"); 830b94b013eSDave Ertman return -EINVAL; 8312a87bd73SDave Ertman } 832b94b013eSDave Ertman 833b94b013eSDave Ertman mutex_lock(&pf->tc_mutex); 834fc2d1165SChinh T Cao old_cfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg; 835b94b013eSDave Ertman 83653977ee4SDave Ertman ret = dcb_ieee_delapp(netdev, app); 83753977ee4SDave Ertman if (ret) 838b94b013eSDave Ertman goto delapp_out; 839b94b013eSDave Ertman 840fc2d1165SChinh T Cao new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg; 841b94b013eSDave Ertman 8422a87bd73SDave Ertman for (i = 0; i < new_cfg->numapps; i++) { 843b94b013eSDave Ertman if (app->selector == new_cfg->app[i].selector && 844b94b013eSDave Ertman app->protocol == new_cfg->app[i].prot_id && 845b94b013eSDave Ertman app->priority == new_cfg->app[i].priority) { 846b94b013eSDave Ertman new_cfg->app[i].selector = 0; 847b94b013eSDave Ertman new_cfg->app[i].prot_id = 0; 848b94b013eSDave Ertman new_cfg->app[i].priority = 0; 849b94b013eSDave Ertman break; 850b94b013eSDave Ertman } 851b94b013eSDave Ertman } 852b94b013eSDave Ertman 853b94b013eSDave Ertman /* Did not find DCB App */ 854b94b013eSDave Ertman if (i == new_cfg->numapps) { 855b94b013eSDave Ertman ret = -EINVAL; 856b94b013eSDave Ertman goto delapp_out; 857b94b013eSDave Ertman } 858b94b013eSDave Ertman 859b94b013eSDave Ertman new_cfg->numapps--; 860b94b013eSDave Ertman 861b94b013eSDave Ertman for (j = i; j < new_cfg->numapps; j++) { 8622a87bd73SDave Ertman new_cfg->app[j].selector = old_cfg->app[j + 1].selector; 8632a87bd73SDave Ertman new_cfg->app[j].prot_id = old_cfg->app[j + 1].prot_id; 8642a87bd73SDave Ertman new_cfg->app[j].priority = old_cfg->app[j + 1].priority; 865b94b013eSDave Ertman } 866b94b013eSDave Ertman 867*40b24760SAnirudh Venkataramanan /* if not a DSCP APP TLV or DSCP is not supported, we are done */ 868*40b24760SAnirudh Venkataramanan if (app->selector != IEEE_8021QAZ_APP_SEL_DSCP || 869*40b24760SAnirudh Venkataramanan !ice_is_feature_supported(pf, ICE_F_DSCP)) { 8702a87bd73SDave Ertman ret = ICE_DCB_HW_CHG; 8712a87bd73SDave Ertman goto delapp_out; 8722a87bd73SDave Ertman } 8732a87bd73SDave Ertman 8742a87bd73SDave Ertman /* if DSCP TLV, then need to address change in mapping */ 8752a87bd73SDave Ertman clear_bit(app->protocol, new_cfg->dscp_mapped); 8762a87bd73SDave Ertman /* remap this DSCP value to default value */ 8772a87bd73SDave Ertman new_cfg->dscp_map[app->protocol] = app->protocol % 8782a87bd73SDave Ertman ICE_BYTES_PER_DSCP_VAL; 8792a87bd73SDave Ertman 8802a87bd73SDave Ertman /* if the last DSCP mapping just got deleted, need to switch 8812a87bd73SDave Ertman * to L2 VLAN QoS mode 8822a87bd73SDave Ertman */ 8832a87bd73SDave Ertman if (bitmap_empty(new_cfg->dscp_mapped, ICE_DSCP_NUM_VAL) && 8842a87bd73SDave Ertman new_cfg->pfc_mode == ICE_QOS_MODE_DSCP) { 8852a87bd73SDave Ertman ret = ice_aq_set_pfc_mode(&pf->hw, 8862a87bd73SDave Ertman ICE_AQC_PFC_VLAN_BASED_PFC, 8872a87bd73SDave Ertman NULL); 8882a87bd73SDave Ertman if (ret) { 8892a87bd73SDave Ertman netdev_info(netdev, "Failed to set VLAN PFC mode %d\n", 8902a87bd73SDave Ertman ret); 8912a87bd73SDave Ertman goto delapp_out; 8922a87bd73SDave Ertman } 8932a87bd73SDave Ertman netdev_info(netdev, "Switched QoS to L2 VLAN mode\n"); 8942a87bd73SDave Ertman 8952a87bd73SDave Ertman new_cfg->pfc_mode = ICE_QOS_MODE_VLAN; 8962a87bd73SDave Ertman 8972a87bd73SDave Ertman ret = ice_dcb_sw_dflt_cfg(pf, true, true); 8982a87bd73SDave Ertman } else { 899b94b013eSDave Ertman ret = ice_pf_dcb_cfg(pf, new_cfg, true); 9002a87bd73SDave Ertman } 9012a87bd73SDave Ertman 9022a87bd73SDave Ertman /* return of ICE_DCB_HW_CHG_RST indicates new cfg applied 9032a87bd73SDave Ertman * and reset needs to be performed 9042a87bd73SDave Ertman */ 905b94b013eSDave Ertman if (ret == ICE_DCB_HW_CHG_RST) 906b94b013eSDave Ertman ice_dcbnl_devreset(netdev); 9072a87bd73SDave Ertman 9082a87bd73SDave Ertman /* if the change was not siginificant enough to actually call 9092a87bd73SDave Ertman * the reconfiguration flow, we still need to tell caller that 9102a87bd73SDave Ertman * their request was successfully handled 9112a87bd73SDave Ertman */ 912b94b013eSDave Ertman if (ret == ICE_DCB_NO_HW_CHG) 9132a87bd73SDave Ertman ret = ICE_DCB_HW_CHG; 914b94b013eSDave Ertman 915b94b013eSDave Ertman delapp_out: 916b94b013eSDave Ertman mutex_unlock(&pf->tc_mutex); 917b94b013eSDave Ertman return ret; 918b94b013eSDave Ertman } 919b94b013eSDave Ertman 920b94b013eSDave Ertman /** 921b94b013eSDave Ertman * ice_dcbnl_cee_set_all - Commit CEE DCB settings to HW 922b94b013eSDave Ertman * @netdev: the corresponding netdev 923b94b013eSDave Ertman */ 924b94b013eSDave Ertman static u8 ice_dcbnl_cee_set_all(struct net_device *netdev) 925b94b013eSDave Ertman { 926b94b013eSDave Ertman struct ice_pf *pf = ice_netdev_to_pf(netdev); 927b94b013eSDave Ertman struct ice_dcbx_cfg *new_cfg; 928b94b013eSDave Ertman int err; 929b94b013eSDave Ertman 930b94b013eSDave Ertman if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 931b94b013eSDave Ertman !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 932b94b013eSDave Ertman return ICE_DCB_NO_HW_CHG; 933b94b013eSDave Ertman 934fc2d1165SChinh T Cao new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg; 935b94b013eSDave Ertman 936b94b013eSDave Ertman mutex_lock(&pf->tc_mutex); 937b94b013eSDave Ertman 938b94b013eSDave Ertman err = ice_pf_dcb_cfg(pf, new_cfg, true); 939b94b013eSDave Ertman 940b94b013eSDave Ertman mutex_unlock(&pf->tc_mutex); 941b94b013eSDave Ertman return (err != ICE_DCB_HW_CHG_RST) ? ICE_DCB_NO_HW_CHG : err; 942b94b013eSDave Ertman } 943b94b013eSDave Ertman 944b94b013eSDave Ertman static const struct dcbnl_rtnl_ops dcbnl_ops = { 945b94b013eSDave Ertman /* IEEE 802.1Qaz std */ 946b94b013eSDave Ertman .ieee_getets = ice_dcbnl_getets, 947b94b013eSDave Ertman .ieee_setets = ice_dcbnl_setets, 948b94b013eSDave Ertman .ieee_getpfc = ice_dcbnl_getpfc, 949b94b013eSDave Ertman .ieee_setpfc = ice_dcbnl_setpfc, 950b94b013eSDave Ertman .ieee_setapp = ice_dcbnl_setapp, 951b94b013eSDave Ertman .ieee_delapp = ice_dcbnl_delapp, 952b94b013eSDave Ertman 953b94b013eSDave Ertman /* CEE std */ 954b94b013eSDave Ertman .getstate = ice_dcbnl_getstate, 955b94b013eSDave Ertman .setstate = ice_dcbnl_setstate, 956b94b013eSDave Ertman .getpermhwaddr = ice_dcbnl_get_perm_hw_addr, 957b94b013eSDave Ertman .setpgtccfgtx = ice_dcbnl_set_pg_tc_cfg_tx, 958b94b013eSDave Ertman .setpgbwgcfgtx = ice_dcbnl_set_pg_bwg_cfg_tx, 959c8608b50SAvinash JD .setpgtccfgrx = ice_dcbnl_set_pg_tc_cfg_rx, 960c8608b50SAvinash JD .setpgbwgcfgrx = ice_dcbnl_set_pg_bwg_cfg_rx, 961b94b013eSDave Ertman .getpgtccfgtx = ice_dcbnl_get_pg_tc_cfg_tx, 962b94b013eSDave Ertman .getpgbwgcfgtx = ice_dcbnl_get_pg_bwg_cfg_tx, 963b94b013eSDave Ertman .getpgtccfgrx = ice_dcbnl_get_pg_tc_cfg_rx, 964b94b013eSDave Ertman .getpgbwgcfgrx = ice_dcbnl_get_pg_bwg_cfg_rx, 965b94b013eSDave Ertman .setpfccfg = ice_dcbnl_set_pfc_cfg, 966b94b013eSDave Ertman .getpfccfg = ice_dcbnl_get_pfc_cfg, 967b94b013eSDave Ertman .setall = ice_dcbnl_cee_set_all, 968b94b013eSDave Ertman .getcap = ice_dcbnl_get_cap, 969b94b013eSDave Ertman .getnumtcs = ice_dcbnl_getnumtcs, 970b94b013eSDave Ertman .getpfcstate = ice_dcbnl_getpfcstate, 971b94b013eSDave Ertman .getapp = ice_dcbnl_getapp, 972b94b013eSDave Ertman 973b94b013eSDave Ertman /* DCBX configuration */ 974b94b013eSDave Ertman .getdcbx = ice_dcbnl_getdcbx, 975b94b013eSDave Ertman .setdcbx = ice_dcbnl_setdcbx, 976b94b013eSDave Ertman }; 977b94b013eSDave Ertman 978b94b013eSDave Ertman /** 979b94b013eSDave Ertman * ice_dcbnl_set_all - set all the apps and ieee data from DCBX config 980b94b013eSDave Ertman * @vsi: pointer to VSI struct 981b94b013eSDave Ertman */ 982b94b013eSDave Ertman void ice_dcbnl_set_all(struct ice_vsi *vsi) 983b94b013eSDave Ertman { 984b94b013eSDave Ertman struct net_device *netdev = vsi->netdev; 985b94b013eSDave Ertman struct ice_dcbx_cfg *dcbxcfg; 986b94b013eSDave Ertman struct ice_port_info *pi; 987b94b013eSDave Ertman struct dcb_app sapp; 988b94b013eSDave Ertman struct ice_pf *pf; 989c1e08830SJesse Brandeburg unsigned int i; 990b94b013eSDave Ertman 991b94b013eSDave Ertman if (!netdev) 992b94b013eSDave Ertman return; 993b94b013eSDave Ertman 994b94b013eSDave Ertman pf = ice_netdev_to_pf(netdev); 995b94b013eSDave Ertman pi = pf->hw.port_info; 996b94b013eSDave Ertman 997b94b013eSDave Ertman /* SW DCB taken care of by SW Default Config */ 998b94b013eSDave Ertman if (pf->dcbx_cap & DCB_CAP_DCBX_HOST) 999b94b013eSDave Ertman return; 1000b94b013eSDave Ertman 1001b94b013eSDave Ertman /* DCB not enabled */ 1002b94b013eSDave Ertman if (!test_bit(ICE_FLAG_DCB_ENA, pf->flags)) 1003b94b013eSDave Ertman return; 1004b94b013eSDave Ertman 1005fc2d1165SChinh T Cao dcbxcfg = &pi->qos_cfg.local_dcbx_cfg; 1006b94b013eSDave Ertman 1007b94b013eSDave Ertman for (i = 0; i < dcbxcfg->numapps; i++) { 1008b94b013eSDave Ertman u8 prio, tc_map; 1009b94b013eSDave Ertman 1010b94b013eSDave Ertman prio = dcbxcfg->app[i].priority; 1011b94b013eSDave Ertman tc_map = BIT(dcbxcfg->etscfg.prio_table[prio]); 1012b94b013eSDave Ertman 1013b94b013eSDave Ertman /* Add APP only if the TC is enabled for this VSI */ 1014b94b013eSDave Ertman if (tc_map & vsi->tc_cfg.ena_tc) { 1015b94b013eSDave Ertman sapp.selector = dcbxcfg->app[i].selector; 1016b94b013eSDave Ertman sapp.protocol = dcbxcfg->app[i].prot_id; 1017b94b013eSDave Ertman sapp.priority = prio; 1018b94b013eSDave Ertman dcb_ieee_setapp(netdev, &sapp); 1019b94b013eSDave Ertman } 1020b94b013eSDave Ertman } 1021b94b013eSDave Ertman /* Notify user-space of the changes */ 1022b94b013eSDave Ertman dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_SET, 0, 0); 1023b94b013eSDave Ertman } 1024b94b013eSDave Ertman 1025b94b013eSDave Ertman /** 1026b94b013eSDave Ertman * ice_dcbnl_vsi_del_app - Delete APP on all VSIs 1027b94b013eSDave Ertman * @vsi: pointer to the main VSI 1028b94b013eSDave Ertman * @app: APP to delete 1029b94b013eSDave Ertman * 1030b94b013eSDave Ertman * Delete given APP from all the VSIs for given PF 1031b94b013eSDave Ertman */ 1032b94b013eSDave Ertman static void 1033b94b013eSDave Ertman ice_dcbnl_vsi_del_app(struct ice_vsi *vsi, 1034b94b013eSDave Ertman struct ice_dcb_app_priority_table *app) 1035b94b013eSDave Ertman { 1036b94b013eSDave Ertman struct dcb_app sapp; 1037b94b013eSDave Ertman int err; 1038b94b013eSDave Ertman 1039b94b013eSDave Ertman sapp.selector = app->selector; 1040b94b013eSDave Ertman sapp.protocol = app->prot_id; 1041b94b013eSDave Ertman sapp.priority = app->priority; 1042b94b013eSDave Ertman err = ice_dcbnl_delapp(vsi->netdev, &sapp); 104319cce2c6SAnirudh Venkataramanan dev_dbg(ice_pf_to_dev(vsi->back), "Deleting app for VSI idx=%d err=%d sel=%d proto=0x%x, prio=%d\n", 1044b94b013eSDave Ertman vsi->idx, err, app->selector, app->prot_id, app->priority); 1045b94b013eSDave Ertman } 1046b94b013eSDave Ertman 1047b94b013eSDave Ertman /** 1048b94b013eSDave Ertman * ice_dcbnl_flush_apps - Delete all removed APPs 1049b94b013eSDave Ertman * @pf: the corresponding PF 1050b94b013eSDave Ertman * @old_cfg: old DCBX configuration data 1051b94b013eSDave Ertman * @new_cfg: new DCBX configuration data 1052b94b013eSDave Ertman * 1053b94b013eSDave Ertman * Find and delete all APPS that are not present in the passed 1054b94b013eSDave Ertman * DCB configuration 1055b94b013eSDave Ertman */ 1056b94b013eSDave Ertman void 1057b94b013eSDave Ertman ice_dcbnl_flush_apps(struct ice_pf *pf, struct ice_dcbx_cfg *old_cfg, 1058b94b013eSDave Ertman struct ice_dcbx_cfg *new_cfg) 1059b94b013eSDave Ertman { 1060b94b013eSDave Ertman struct ice_vsi *main_vsi = ice_get_main_vsi(pf); 1061c1e08830SJesse Brandeburg unsigned int i; 1062b94b013eSDave Ertman 1063b94b013eSDave Ertman if (!main_vsi) 1064b94b013eSDave Ertman return; 1065b94b013eSDave Ertman 1066b94b013eSDave Ertman for (i = 0; i < old_cfg->numapps; i++) { 1067b94b013eSDave Ertman struct ice_dcb_app_priority_table app = old_cfg->app[i]; 1068b94b013eSDave Ertman 1069b94b013eSDave Ertman /* The APP is not available anymore delete it */ 1070b94b013eSDave Ertman if (!ice_dcbnl_find_app(new_cfg, &app)) 1071b94b013eSDave Ertman ice_dcbnl_vsi_del_app(main_vsi, &app); 1072b94b013eSDave Ertman } 1073b94b013eSDave Ertman } 1074b94b013eSDave Ertman 1075b94b013eSDave Ertman /** 1076b94b013eSDave Ertman * ice_dcbnl_setup - setup DCBNL 1077b94b013eSDave Ertman * @vsi: VSI to get associated netdev from 1078b94b013eSDave Ertman */ 1079b94b013eSDave Ertman void ice_dcbnl_setup(struct ice_vsi *vsi) 1080b94b013eSDave Ertman { 1081b94b013eSDave Ertman struct net_device *netdev = vsi->netdev; 1082b94b013eSDave Ertman struct ice_pf *pf; 1083b94b013eSDave Ertman 1084b94b013eSDave Ertman pf = ice_netdev_to_pf(netdev); 1085b94b013eSDave Ertman if (!test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags)) 1086b94b013eSDave Ertman return; 1087b94b013eSDave Ertman 1088b94b013eSDave Ertman netdev->dcbnl_ops = &dcbnl_ops; 1089b94b013eSDave Ertman ice_dcbnl_set_all(vsi); 1090b94b013eSDave Ertman } 1091