ice_dcb_nl.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright (c) 2019, Intel Corporation. */
  3. #include "ice.h"
  4. #include "ice_dcb.h"
  5. #include "ice_dcb_lib.h"
  6. #include "ice_dcb_nl.h"
  7. #include <net/dcbnl.h>
  8. /**
  9. * ice_dcbnl_devreset - perform enough of a ifdown/ifup to sync DCBNL info
  10. * @netdev: device associated with interface that needs reset
  11. */
  12. static void ice_dcbnl_devreset(struct net_device *netdev)
  13. {
  14. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  15. while (ice_is_reset_in_progress(pf->state))
  16. usleep_range(1000, 2000);
  17. dev_close(netdev);
  18. netdev_state_change(netdev);
  19. dev_open(netdev, NULL);
  20. netdev_state_change(netdev);
  21. }
  22. /**
  23. * ice_dcbnl_getets - retrieve local ETS configuration
  24. * @netdev: the relevant netdev
  25. * @ets: struct to hold ETS configuration
  26. */
  27. static int ice_dcbnl_getets(struct net_device *netdev, struct ieee_ets *ets)
  28. {
  29. struct ice_dcbx_cfg *dcbxcfg;
  30. struct ice_pf *pf;
  31. pf = ice_netdev_to_pf(netdev);
  32. dcbxcfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg;
  33. ets->willing = dcbxcfg->etscfg.willing;
  34. ets->ets_cap = dcbxcfg->etscfg.maxtcs;
  35. ets->cbs = dcbxcfg->etscfg.cbs;
  36. memcpy(ets->tc_tx_bw, dcbxcfg->etscfg.tcbwtable, sizeof(ets->tc_tx_bw));
  37. memcpy(ets->tc_rx_bw, dcbxcfg->etscfg.tcbwtable, sizeof(ets->tc_rx_bw));
  38. memcpy(ets->tc_tsa, dcbxcfg->etscfg.tsatable, sizeof(ets->tc_tsa));
  39. memcpy(ets->prio_tc, dcbxcfg->etscfg.prio_table, sizeof(ets->prio_tc));
  40. memcpy(ets->tc_reco_bw, dcbxcfg->etsrec.tcbwtable,
  41. sizeof(ets->tc_reco_bw));
  42. memcpy(ets->tc_reco_tsa, dcbxcfg->etsrec.tsatable,
  43. sizeof(ets->tc_reco_tsa));
  44. memcpy(ets->reco_prio_tc, dcbxcfg->etscfg.prio_table,
  45. sizeof(ets->reco_prio_tc));
  46. return 0;
  47. }
  48. /**
  49. * ice_dcbnl_setets - set IEEE ETS configuration
  50. * @netdev: pointer to relevant netdev
  51. * @ets: struct to hold ETS configuration
  52. */
  53. static int ice_dcbnl_setets(struct net_device *netdev, struct ieee_ets *ets)
  54. {
  55. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  56. struct ice_dcbx_cfg *new_cfg;
  57. int bwcfg = 0, bwrec = 0;
  58. int err, i;
  59. if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
  60. !(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
  61. return -EINVAL;
  62. if (pf->lag && pf->lag->bonded) {
  63. netdev_err(netdev, "DCB changes not allowed when in a bond\n");
  64. return -EINVAL;
  65. }
  66. new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;
  67. mutex_lock(&pf->tc_mutex);
  68. new_cfg->etscfg.willing = ets->willing;
  69. new_cfg->etscfg.cbs = ets->cbs;
  70. ice_for_each_traffic_class(i) {
  71. new_cfg->etscfg.tcbwtable[i] = ets->tc_tx_bw[i];
  72. bwcfg += ets->tc_tx_bw[i];
  73. new_cfg->etscfg.tsatable[i] = ets->tc_tsa[i];
  74. if (new_cfg->pfc_mode == ICE_QOS_MODE_VLAN) {
  75. /* in DSCP mode up->tc mapping cannot change */
  76. new_cfg->etscfg.prio_table[i] = ets->prio_tc[i];
  77. new_cfg->etsrec.prio_table[i] = ets->reco_prio_tc[i];
  78. }
  79. new_cfg->etsrec.tcbwtable[i] = ets->tc_reco_bw[i];
  80. bwrec += ets->tc_reco_bw[i];
  81. new_cfg->etsrec.tsatable[i] = ets->tc_reco_tsa[i];
  82. }
  83. if (ice_dcb_bwchk(pf, new_cfg)) {
  84. err = -EINVAL;
  85. goto ets_out;
  86. }
  87. new_cfg->etscfg.maxtcs = pf->hw.func_caps.common_cap.maxtc;
  88. if (!bwcfg)
  89. new_cfg->etscfg.tcbwtable[0] = 100;
  90. if (!bwrec)
  91. new_cfg->etsrec.tcbwtable[0] = 100;
  92. err = ice_pf_dcb_cfg(pf, new_cfg, true);
  93. /* return of zero indicates new cfg applied */
  94. if (err == ICE_DCB_HW_CHG_RST)
  95. ice_dcbnl_devreset(netdev);
  96. if (err == ICE_DCB_NO_HW_CHG)
  97. err = ICE_DCB_HW_CHG_RST;
  98. ets_out:
  99. mutex_unlock(&pf->tc_mutex);
  100. return err;
  101. }
  102. /**
  103. * ice_dcbnl_getnumtcs - Get max number of traffic classes supported
  104. * @dev: pointer to netdev struct
  105. * @tcid: TC ID
  106. * @num: total number of TCs supported by the adapter
  107. *
  108. * Return the total number of TCs supported
  109. */
  110. static int
  111. ice_dcbnl_getnumtcs(struct net_device *dev, int __always_unused tcid, u8 *num)
  112. {
  113. struct ice_pf *pf = ice_netdev_to_pf(dev);
  114. if (!test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags))
  115. return -EINVAL;
  116. *num = pf->hw.func_caps.common_cap.maxtc;
  117. return 0;
  118. }
  119. /**
  120. * ice_dcbnl_getdcbx - retrieve current DCBX capability
  121. * @netdev: pointer to the netdev struct
  122. */
  123. static u8 ice_dcbnl_getdcbx(struct net_device *netdev)
  124. {
  125. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  126. return pf->dcbx_cap;
  127. }
  128. /**
  129. * ice_dcbnl_setdcbx - set required DCBX capability
  130. * @netdev: the corresponding netdev
  131. * @mode: required mode
  132. */
  133. static u8 ice_dcbnl_setdcbx(struct net_device *netdev, u8 mode)
  134. {
  135. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  136. struct ice_qos_cfg *qos_cfg;
  137. /* if FW LLDP agent is running, DCBNL not allowed to change mode */
  138. if (test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags))
  139. return ICE_DCB_NO_HW_CHG;
  140. /* No support for LLD_MANAGED modes or CEE+IEEE */
  141. if ((mode & DCB_CAP_DCBX_LLD_MANAGED) ||
  142. ((mode & DCB_CAP_DCBX_VER_IEEE) && (mode & DCB_CAP_DCBX_VER_CEE)) ||
  143. !(mode & DCB_CAP_DCBX_HOST))
  144. return ICE_DCB_NO_HW_CHG;
  145. /* Already set to the given mode no change */
  146. if (mode == pf->dcbx_cap)
  147. return ICE_DCB_NO_HW_CHG;
  148. if (pf->lag && pf->lag->bonded) {
  149. netdev_err(netdev, "DCB changes not allowed when in a bond\n");
  150. return ICE_DCB_NO_HW_CHG;
  151. }
  152. qos_cfg = &pf->hw.port_info->qos_cfg;
  153. /* DSCP configuration is not DCBx negotiated */
  154. if (qos_cfg->local_dcbx_cfg.pfc_mode == ICE_QOS_MODE_DSCP)
  155. return ICE_DCB_NO_HW_CHG;
  156. pf->dcbx_cap = mode;
  157. if (mode & DCB_CAP_DCBX_VER_CEE)
  158. qos_cfg->local_dcbx_cfg.dcbx_mode = ICE_DCBX_MODE_CEE;
  159. else
  160. qos_cfg->local_dcbx_cfg.dcbx_mode = ICE_DCBX_MODE_IEEE;
  161. dev_info(ice_pf_to_dev(pf), "DCBx mode = 0x%x\n", mode);
  162. return ICE_DCB_HW_CHG_RST;
  163. }
  164. /**
  165. * ice_dcbnl_get_perm_hw_addr - MAC address used by DCBX
  166. * @netdev: pointer to netdev struct
  167. * @perm_addr: buffer to return permanent MAC address
  168. */
  169. static void ice_dcbnl_get_perm_hw_addr(struct net_device *netdev, u8 *perm_addr)
  170. {
  171. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  172. struct ice_port_info *pi = pf->hw.port_info;
  173. int i, j;
  174. memset(perm_addr, 0xff, MAX_ADDR_LEN);
  175. for (i = 0; i < netdev->addr_len; i++)
  176. perm_addr[i] = pi->mac.perm_addr[i];
  177. for (j = 0; j < netdev->addr_len; j++, i++)
  178. perm_addr[i] = pi->mac.perm_addr[j];
  179. }
  180. /**
  181. * ice_get_pfc_delay - Retrieve PFC Link Delay
  182. * @hw: pointer to HW struct
  183. * @delay: holds the PFC Link Delay value
  184. */
  185. static void ice_get_pfc_delay(struct ice_hw *hw, u16 *delay)
  186. {
  187. u32 val;
  188. val = rd32(hw, PRTDCB_GENC);
  189. *delay = FIELD_GET(PRTDCB_GENC_PFCLDA_M, val);
  190. }
  191. /**
  192. * ice_dcbnl_getpfc - retrieve local IEEE PFC config
  193. * @netdev: pointer to netdev struct
  194. * @pfc: struct to hold PFC info
  195. */
  196. static int ice_dcbnl_getpfc(struct net_device *netdev, struct ieee_pfc *pfc)
  197. {
  198. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  199. struct ice_port_info *pi = pf->hw.port_info;
  200. struct ice_dcbx_cfg *dcbxcfg;
  201. int i;
  202. dcbxcfg = &pi->qos_cfg.local_dcbx_cfg;
  203. pfc->pfc_cap = dcbxcfg->pfc.pfccap;
  204. pfc->pfc_en = dcbxcfg->pfc.pfcena;
  205. pfc->mbc = dcbxcfg->pfc.mbc;
  206. ice_get_pfc_delay(&pf->hw, &pfc->delay);
  207. ice_for_each_traffic_class(i) {
  208. pfc->requests[i] = pf->stats.priority_xoff_tx[i];
  209. pfc->indications[i] = pf->stats.priority_xoff_rx[i];
  210. }
  211. return 0;
  212. }
  213. /**
  214. * ice_dcbnl_setpfc - set local IEEE PFC config
  215. * @netdev: pointer to relevant netdev
  216. * @pfc: pointer to struct holding PFC config
  217. */
  218. static int ice_dcbnl_setpfc(struct net_device *netdev, struct ieee_pfc *pfc)
  219. {
  220. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  221. struct ice_dcbx_cfg *new_cfg;
  222. int err;
  223. if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
  224. !(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
  225. return -EINVAL;
  226. if (pf->lag && pf->lag->bonded) {
  227. netdev_err(netdev, "DCB changes not allowed when in a bond\n");
  228. return -EINVAL;
  229. }
  230. mutex_lock(&pf->tc_mutex);
  231. new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;
  232. if (pfc->pfc_cap)
  233. new_cfg->pfc.pfccap = pfc->pfc_cap;
  234. else
  235. new_cfg->pfc.pfccap = pf->hw.func_caps.common_cap.maxtc;
  236. new_cfg->pfc.pfcena = pfc->pfc_en;
  237. err = ice_pf_dcb_cfg(pf, new_cfg, true);
  238. if (err == ICE_DCB_HW_CHG_RST)
  239. ice_dcbnl_devreset(netdev);
  240. if (err == ICE_DCB_NO_HW_CHG)
  241. err = ICE_DCB_HW_CHG_RST;
  242. mutex_unlock(&pf->tc_mutex);
  243. return err;
  244. }
  245. /**
  246. * ice_dcbnl_get_pfc_cfg - Get CEE PFC config
  247. * @netdev: pointer to netdev struct
  248. * @prio: corresponding user priority
  249. * @setting: the PFC setting for given priority
  250. */
  251. static void
  252. ice_dcbnl_get_pfc_cfg(struct net_device *netdev, int prio, u8 *setting)
  253. {
  254. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  255. struct ice_port_info *pi = pf->hw.port_info;
  256. if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
  257. !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
  258. return;
  259. if (prio >= ICE_MAX_USER_PRIORITY)
  260. return;
  261. *setting = (pi->qos_cfg.local_dcbx_cfg.pfc.pfcena >> prio) & 0x1;
  262. dev_dbg(ice_pf_to_dev(pf), "Get PFC Config up=%d, setting=%d, pfcenable=0x%x\n",
  263. prio, *setting, pi->qos_cfg.local_dcbx_cfg.pfc.pfcena);
  264. }
  265. /**
  266. * ice_dcbnl_set_pfc_cfg - Set CEE PFC config
  267. * @netdev: the corresponding netdev
  268. * @prio: User Priority
  269. * @set: PFC setting to apply
  270. */
  271. static void ice_dcbnl_set_pfc_cfg(struct net_device *netdev, int prio, u8 set)
  272. {
  273. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  274. struct ice_dcbx_cfg *new_cfg;
  275. if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
  276. !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
  277. return;
  278. if (prio >= ICE_MAX_USER_PRIORITY)
  279. return;
  280. if (pf->lag && pf->lag->bonded) {
  281. netdev_err(netdev, "DCB changes not allowed when in a bond\n");
  282. return;
  283. }
  284. new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;
  285. new_cfg->pfc.pfccap = pf->hw.func_caps.common_cap.maxtc;
  286. if (set)
  287. new_cfg->pfc.pfcena |= BIT(prio);
  288. else
  289. new_cfg->pfc.pfcena &= ~BIT(prio);
  290. dev_dbg(ice_pf_to_dev(pf), "Set PFC config UP:%d set:%d pfcena:0x%x\n",
  291. prio, set, new_cfg->pfc.pfcena);
  292. }
  293. /**
  294. * ice_dcbnl_getpfcstate - get CEE PFC mode
  295. * @netdev: pointer to netdev struct
  296. */
  297. static u8 ice_dcbnl_getpfcstate(struct net_device *netdev)
  298. {
  299. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  300. struct ice_port_info *pi = pf->hw.port_info;
  301. /* Return enabled if any UP enabled for PFC */
  302. if (pi->qos_cfg.local_dcbx_cfg.pfc.pfcena)
  303. return 1;
  304. return 0;
  305. }
  306. /**
  307. * ice_dcbnl_getstate - get DCB enabled state
  308. * @netdev: pointer to netdev struct
  309. */
  310. static u8 ice_dcbnl_getstate(struct net_device *netdev)
  311. {
  312. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  313. u8 state = 0;
  314. state = test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags);
  315. dev_dbg(ice_pf_to_dev(pf), "DCB enabled state = %d\n", state);
  316. return state;
  317. }
  318. /**
  319. * ice_dcbnl_setstate - Set CEE DCB state
  320. * @netdev: pointer to relevant netdev
  321. * @state: state value to set
  322. */
  323. static u8 ice_dcbnl_setstate(struct net_device *netdev, u8 state)
  324. {
  325. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  326. if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
  327. !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
  328. return ICE_DCB_NO_HW_CHG;
  329. if (pf->lag && pf->lag->bonded) {
  330. netdev_err(netdev, "DCB changes not allowed when in a bond\n");
  331. return ICE_DCB_NO_HW_CHG;
  332. }
  333. /* Nothing to do */
  334. if (!!state == test_bit(ICE_FLAG_DCB_ENA, pf->flags))
  335. return ICE_DCB_NO_HW_CHG;
  336. if (state) {
  337. set_bit(ICE_FLAG_DCB_ENA, pf->flags);
  338. memcpy(&pf->hw.port_info->qos_cfg.desired_dcbx_cfg,
  339. &pf->hw.port_info->qos_cfg.local_dcbx_cfg,
  340. sizeof(struct ice_dcbx_cfg));
  341. } else {
  342. clear_bit(ICE_FLAG_DCB_ENA, pf->flags);
  343. }
  344. return ICE_DCB_HW_CHG;
  345. }
  346. /**
  347. * ice_dcbnl_get_pg_tc_cfg_tx - get CEE PG Tx config
  348. * @netdev: pointer to netdev struct
  349. * @prio: the corresponding user priority
  350. * @prio_type: traffic priority type
  351. * @pgid: the BW group ID the traffic class belongs to
  352. * @bw_pct: BW percentage for the corresponding BWG
  353. * @up_map: prio mapped to corresponding TC
  354. */
  355. static void
  356. ice_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int prio,
  357. u8 __always_unused *prio_type, u8 *pgid,
  358. u8 __always_unused *bw_pct,
  359. u8 __always_unused *up_map)
  360. {
  361. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  362. struct ice_port_info *pi = pf->hw.port_info;
  363. if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
  364. !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
  365. return;
  366. if (prio >= ICE_MAX_USER_PRIORITY)
  367. return;
  368. *pgid = pi->qos_cfg.local_dcbx_cfg.etscfg.prio_table[prio];
  369. dev_dbg(ice_pf_to_dev(pf), "Get PG config prio=%d tc=%d\n", prio,
  370. *pgid);
  371. }
  372. /**
  373. * ice_dcbnl_set_pg_tc_cfg_tx - set CEE PG Tx config
  374. * @netdev: pointer to relevant netdev
  375. * @tc: the corresponding traffic class
  376. * @prio_type: the traffic priority type
  377. * @bwg_id: the BW group ID the TC belongs to
  378. * @bw_pct: the BW perventage for the BWG
  379. * @up_map: prio mapped to corresponding TC
  380. */
  381. static void
  382. ice_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
  383. u8 __always_unused prio_type,
  384. u8 __always_unused bwg_id,
  385. u8 __always_unused bw_pct, u8 up_map)
  386. {
  387. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  388. struct ice_dcbx_cfg *new_cfg;
  389. int i;
  390. if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
  391. !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
  392. return;
  393. if (tc >= ICE_MAX_TRAFFIC_CLASS)
  394. return;
  395. if (pf->lag && pf->lag->bonded) {
  396. netdev_err(netdev, "DCB changes not allowed when in a bond\n");
  397. return;
  398. }
  399. new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;
  400. /* prio_type, bwg_id and bw_pct per UP are not supported */
  401. ice_for_each_traffic_class(i) {
  402. if (up_map & BIT(i))
  403. new_cfg->etscfg.prio_table[i] = tc;
  404. }
  405. new_cfg->etscfg.tsatable[tc] = ICE_IEEE_TSA_ETS;
  406. }
  407. /**
  408. * ice_dcbnl_get_pg_bwg_cfg_tx - Get CEE PGBW config
  409. * @netdev: pointer to the netdev struct
  410. * @pgid: corresponding traffic class
  411. * @bw_pct: the BW percentage for the corresponding TC
  412. */
  413. static void
  414. ice_dcbnl_get_pg_bwg_cfg_tx(struct net_device *netdev, int pgid, u8 *bw_pct)
  415. {
  416. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  417. struct ice_port_info *pi = pf->hw.port_info;
  418. if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
  419. !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
  420. return;
  421. if (pgid >= ICE_MAX_TRAFFIC_CLASS)
  422. return;
  423. *bw_pct = pi->qos_cfg.local_dcbx_cfg.etscfg.tcbwtable[pgid];
  424. dev_dbg(ice_pf_to_dev(pf), "Get PG BW config tc=%d bw_pct=%d\n",
  425. pgid, *bw_pct);
  426. }
  427. /**
  428. * ice_dcbnl_set_pg_bwg_cfg_tx - set CEE PG Tx BW config
  429. * @netdev: the corresponding netdev
  430. * @pgid: Correspongind traffic class
  431. * @bw_pct: the BW percentage for the specified TC
  432. */
  433. static void
  434. ice_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int pgid, u8 bw_pct)
  435. {
  436. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  437. struct ice_dcbx_cfg *new_cfg;
  438. if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
  439. !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
  440. return;
  441. if (pgid >= ICE_MAX_TRAFFIC_CLASS)
  442. return;
  443. if (pf->lag && pf->lag->bonded) {
  444. netdev_err(netdev, "DCB changes not allowed when in a bond\n");
  445. return;
  446. }
  447. new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;
  448. new_cfg->etscfg.tcbwtable[pgid] = bw_pct;
  449. }
  450. /**
  451. * ice_dcbnl_get_pg_tc_cfg_rx - Get CEE PG Rx config
  452. * @netdev: pointer to netdev struct
  453. * @prio: the corresponding user priority
  454. * @prio_type: the traffic priority type
  455. * @pgid: the PG ID
  456. * @bw_pct: the BW percentage for the corresponding BWG
  457. * @up_map: prio mapped to corresponding TC
  458. */
  459. static void
  460. ice_dcbnl_get_pg_tc_cfg_rx(struct net_device *netdev, int prio,
  461. u8 __always_unused *prio_type, u8 *pgid,
  462. u8 __always_unused *bw_pct,
  463. u8 __always_unused *up_map)
  464. {
  465. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  466. struct ice_port_info *pi = pf->hw.port_info;
  467. if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
  468. !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
  469. return;
  470. if (prio >= ICE_MAX_USER_PRIORITY)
  471. return;
  472. *pgid = pi->qos_cfg.local_dcbx_cfg.etscfg.prio_table[prio];
  473. }
  474. /**
  475. * ice_dcbnl_set_pg_tc_cfg_rx
  476. * @netdev: relevant netdev struct
  477. * @prio: corresponding user priority
  478. * @prio_type: the traffic priority type
  479. * @pgid: the PG ID
  480. * @bw_pct: BW percentage for corresponding BWG
  481. * @up_map: prio mapped to corresponding TC
  482. *
  483. * lldpad requires this function pointer to be non-NULL to complete CEE config.
  484. */
  485. static void
  486. ice_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev,
  487. int __always_unused prio,
  488. u8 __always_unused prio_type,
  489. u8 __always_unused pgid,
  490. u8 __always_unused bw_pct,
  491. u8 __always_unused up_map)
  492. {
  493. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  494. dev_dbg(ice_pf_to_dev(pf), "Rx TC PG Config Not Supported.\n");
  495. }
  496. /**
  497. * ice_dcbnl_get_pg_bwg_cfg_rx - Get CEE PG BW Rx config
  498. * @netdev: pointer to netdev struct
  499. * @pgid: the corresponding traffic class
  500. * @bw_pct: the BW percentage for the corresponding TC
  501. */
  502. static void
  503. ice_dcbnl_get_pg_bwg_cfg_rx(struct net_device *netdev, int __always_unused pgid,
  504. u8 *bw_pct)
  505. {
  506. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  507. if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
  508. !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
  509. return;
  510. *bw_pct = 0;
  511. }
  512. /**
  513. * ice_dcbnl_set_pg_bwg_cfg_rx
  514. * @netdev: the corresponding netdev
  515. * @pgid: corresponding TC
  516. * @bw_pct: BW percentage for given TC
  517. *
  518. * lldpad requires this function pointer to be non-NULL to complete CEE config.
  519. */
  520. static void
  521. ice_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int __always_unused pgid,
  522. u8 __always_unused bw_pct)
  523. {
  524. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  525. dev_dbg(ice_pf_to_dev(pf), "Rx BWG PG Config Not Supported.\n");
  526. }
  527. /**
  528. * ice_dcbnl_get_cap - Get DCBX capabilities of adapter
  529. * @netdev: pointer to netdev struct
  530. * @capid: the capability type
  531. * @cap: the capability value
  532. */
  533. static u8 ice_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap)
  534. {
  535. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  536. if (!(test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags)))
  537. return ICE_DCB_NO_HW_CHG;
  538. switch (capid) {
  539. case DCB_CAP_ATTR_PG:
  540. *cap = true;
  541. break;
  542. case DCB_CAP_ATTR_PFC:
  543. *cap = true;
  544. break;
  545. case DCB_CAP_ATTR_UP2TC:
  546. *cap = false;
  547. break;
  548. case DCB_CAP_ATTR_PG_TCS:
  549. *cap = 0x80;
  550. break;
  551. case DCB_CAP_ATTR_PFC_TCS:
  552. *cap = 0x80;
  553. break;
  554. case DCB_CAP_ATTR_GSP:
  555. *cap = false;
  556. break;
  557. case DCB_CAP_ATTR_BCN:
  558. *cap = false;
  559. break;
  560. case DCB_CAP_ATTR_DCBX:
  561. *cap = pf->dcbx_cap;
  562. break;
  563. default:
  564. *cap = false;
  565. break;
  566. }
  567. dev_dbg(ice_pf_to_dev(pf), "DCBX Get Capability cap=%d capval=0x%x\n",
  568. capid, *cap);
  569. return 0;
  570. }
  571. /**
  572. * ice_dcbnl_getapp - get CEE APP
  573. * @netdev: pointer to netdev struct
  574. * @idtype: the App selector
  575. * @id: the App ethtype or port number
  576. */
  577. static int ice_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
  578. {
  579. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  580. struct dcb_app app = {
  581. .selector = idtype,
  582. .protocol = id,
  583. };
  584. if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
  585. !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
  586. return -EINVAL;
  587. return dcb_getapp(netdev, &app);
  588. }
  589. /**
  590. * ice_dcbnl_find_app - Search for APP in given DCB config
  591. * @cfg: struct to hold DCBX config
  592. * @app: struct to hold app data to look for
  593. */
  594. static bool
  595. ice_dcbnl_find_app(struct ice_dcbx_cfg *cfg,
  596. struct ice_dcb_app_priority_table *app)
  597. {
  598. unsigned int i;
  599. for (i = 0; i < cfg->numapps; i++) {
  600. if (app->selector == cfg->app[i].selector &&
  601. app->prot_id == cfg->app[i].prot_id &&
  602. app->priority == cfg->app[i].priority)
  603. return true;
  604. }
  605. return false;
  606. }
  607. #define ICE_BYTES_PER_DSCP_VAL 8
  608. /**
  609. * ice_dcbnl_setapp - set local IEEE App config
  610. * @netdev: relevant netdev struct
  611. * @app: struct to hold app config info
  612. */
  613. static int ice_dcbnl_setapp(struct net_device *netdev, struct dcb_app *app)
  614. {
  615. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  616. struct ice_dcb_app_priority_table new_app;
  617. struct ice_dcbx_cfg *old_cfg, *new_cfg;
  618. u8 max_tc;
  619. int ret;
  620. /* ONLY DSCP APP TLVs have operational significance */
  621. if (app->selector != IEEE_8021QAZ_APP_SEL_DSCP)
  622. return -EINVAL;
  623. /* only allow APP TLVs in SW Mode */
  624. if (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) {
  625. netdev_err(netdev, "can't do DSCP QoS when FW DCB agent active\n");
  626. return -EINVAL;
  627. }
  628. if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
  629. return -EINVAL;
  630. if (!ice_is_feature_supported(pf, ICE_F_DSCP))
  631. return -EOPNOTSUPP;
  632. if (app->protocol >= ICE_DSCP_NUM_VAL) {
  633. netdev_err(netdev, "DSCP value 0x%04X out of range\n",
  634. app->protocol);
  635. return -EINVAL;
  636. }
  637. if (pf->lag && pf->lag->bonded) {
  638. netdev_err(netdev, "DCB changes not allowed when in a bond\n");
  639. return -EINVAL;
  640. }
  641. max_tc = pf->hw.func_caps.common_cap.maxtc;
  642. if (app->priority >= max_tc) {
  643. netdev_err(netdev, "TC %d out of range, max TC %d\n",
  644. app->priority, max_tc);
  645. return -EINVAL;
  646. }
  647. /* grab TC mutex */
  648. mutex_lock(&pf->tc_mutex);
  649. new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;
  650. old_cfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg;
  651. ret = dcb_ieee_setapp(netdev, app);
  652. if (ret)
  653. goto setapp_out;
  654. if (test_and_set_bit(app->protocol, new_cfg->dscp_mapped)) {
  655. netdev_err(netdev, "DSCP value 0x%04X already user mapped\n",
  656. app->protocol);
  657. ret = dcb_ieee_delapp(netdev, app);
  658. if (ret)
  659. netdev_err(netdev, "Failed to delete re-mapping TLV\n");
  660. ret = -EINVAL;
  661. goto setapp_out;
  662. }
  663. new_app.selector = app->selector;
  664. new_app.prot_id = app->protocol;
  665. new_app.priority = app->priority;
  666. /* If port is not in DSCP mode, need to set */
  667. if (old_cfg->pfc_mode == ICE_QOS_MODE_VLAN) {
  668. int i, j;
  669. /* set DSCP mode */
  670. ret = ice_aq_set_pfc_mode(&pf->hw, ICE_AQC_PFC_DSCP_BASED_PFC,
  671. NULL);
  672. if (ret) {
  673. netdev_err(netdev, "Failed to set DSCP PFC mode %d\n",
  674. ret);
  675. goto setapp_out;
  676. }
  677. netdev_info(netdev, "Switched QoS to L3 DSCP mode\n");
  678. new_cfg->pfc_mode = ICE_QOS_MODE_DSCP;
  679. /* set default DSCP QoS values */
  680. new_cfg->etscfg.willing = 0;
  681. new_cfg->pfc.pfccap = max_tc;
  682. new_cfg->pfc.willing = 0;
  683. for (i = 0; i < max_tc; i++)
  684. for (j = 0; j < ICE_BYTES_PER_DSCP_VAL; j++) {
  685. int dscp, offset;
  686. dscp = (i * max_tc) + j;
  687. offset = max_tc * ICE_BYTES_PER_DSCP_VAL;
  688. new_cfg->dscp_map[dscp] = i;
  689. /* if less that 8 TCs supported */
  690. if (max_tc < ICE_MAX_TRAFFIC_CLASS)
  691. new_cfg->dscp_map[dscp + offset] = i;
  692. }
  693. new_cfg->etscfg.tcbwtable[0] = 100;
  694. new_cfg->etscfg.tsatable[0] = ICE_IEEE_TSA_ETS;
  695. new_cfg->etscfg.prio_table[0] = 0;
  696. for (i = 1; i < max_tc; i++) {
  697. new_cfg->etscfg.tcbwtable[i] = 0;
  698. new_cfg->etscfg.tsatable[i] = ICE_IEEE_TSA_ETS;
  699. new_cfg->etscfg.prio_table[i] = i;
  700. }
  701. } /* end of switching to DSCP mode */
  702. /* apply new mapping for this DSCP value */
  703. new_cfg->dscp_map[app->protocol] = app->priority;
  704. new_cfg->app[new_cfg->numapps++] = new_app;
  705. ret = ice_pf_dcb_cfg(pf, new_cfg, true);
  706. /* return of zero indicates new cfg applied */
  707. if (ret == ICE_DCB_HW_CHG_RST)
  708. ice_dcbnl_devreset(netdev);
  709. else
  710. ret = ICE_DCB_NO_HW_CHG;
  711. setapp_out:
  712. mutex_unlock(&pf->tc_mutex);
  713. return ret;
  714. }
  715. /**
  716. * ice_dcbnl_delapp - Delete local IEEE App config
  717. * @netdev: relevant netdev
  718. * @app: struct to hold app too delete
  719. *
  720. * Will not delete first application required by the FW
  721. */
  722. static int ice_dcbnl_delapp(struct net_device *netdev, struct dcb_app *app)
  723. {
  724. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  725. struct ice_dcbx_cfg *old_cfg, *new_cfg;
  726. unsigned int i, j;
  727. int ret = 0;
  728. if (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) {
  729. netdev_err(netdev, "can't delete DSCP netlink app when FW DCB agent is active\n");
  730. return -EINVAL;
  731. }
  732. if (pf->lag && pf->lag->bonded) {
  733. netdev_err(netdev, "DCB changes not allowed when in a bond\n");
  734. return -EINVAL;
  735. }
  736. mutex_lock(&pf->tc_mutex);
  737. old_cfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg;
  738. ret = dcb_ieee_delapp(netdev, app);
  739. if (ret)
  740. goto delapp_out;
  741. new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;
  742. for (i = 0; i < new_cfg->numapps; i++) {
  743. if (app->selector == new_cfg->app[i].selector &&
  744. app->protocol == new_cfg->app[i].prot_id &&
  745. app->priority == new_cfg->app[i].priority) {
  746. new_cfg->app[i].selector = 0;
  747. new_cfg->app[i].prot_id = 0;
  748. new_cfg->app[i].priority = 0;
  749. break;
  750. }
  751. }
  752. /* Did not find DCB App */
  753. if (i == new_cfg->numapps) {
  754. ret = -EINVAL;
  755. goto delapp_out;
  756. }
  757. new_cfg->numapps--;
  758. for (j = i; j < new_cfg->numapps; j++) {
  759. new_cfg->app[j].selector = old_cfg->app[j + 1].selector;
  760. new_cfg->app[j].prot_id = old_cfg->app[j + 1].prot_id;
  761. new_cfg->app[j].priority = old_cfg->app[j + 1].priority;
  762. }
  763. /* if not a DSCP APP TLV or DSCP is not supported, we are done */
  764. if (app->selector != IEEE_8021QAZ_APP_SEL_DSCP ||
  765. !ice_is_feature_supported(pf, ICE_F_DSCP)) {
  766. ret = ICE_DCB_HW_CHG;
  767. goto delapp_out;
  768. }
  769. /* if DSCP TLV, then need to address change in mapping */
  770. clear_bit(app->protocol, new_cfg->dscp_mapped);
  771. /* remap this DSCP value to default value */
  772. new_cfg->dscp_map[app->protocol] = app->protocol %
  773. ICE_BYTES_PER_DSCP_VAL;
  774. /* if the last DSCP mapping just got deleted, need to switch
  775. * to L2 VLAN QoS mode
  776. */
  777. if (bitmap_empty(new_cfg->dscp_mapped, ICE_DSCP_NUM_VAL) &&
  778. new_cfg->pfc_mode == ICE_QOS_MODE_DSCP) {
  779. ret = ice_aq_set_pfc_mode(&pf->hw,
  780. ICE_AQC_PFC_VLAN_BASED_PFC,
  781. NULL);
  782. if (ret) {
  783. netdev_info(netdev, "Failed to set VLAN PFC mode %d\n",
  784. ret);
  785. goto delapp_out;
  786. }
  787. netdev_info(netdev, "Switched QoS to L2 VLAN mode\n");
  788. new_cfg->pfc_mode = ICE_QOS_MODE_VLAN;
  789. ret = ice_dcb_sw_dflt_cfg(pf, true, true);
  790. } else {
  791. ret = ice_pf_dcb_cfg(pf, new_cfg, true);
  792. }
  793. /* return of ICE_DCB_HW_CHG_RST indicates new cfg applied
  794. * and reset needs to be performed
  795. */
  796. if (ret == ICE_DCB_HW_CHG_RST)
  797. ice_dcbnl_devreset(netdev);
  798. /* if the change was not siginificant enough to actually call
  799. * the reconfiguration flow, we still need to tell caller that
  800. * their request was successfully handled
  801. */
  802. if (ret == ICE_DCB_NO_HW_CHG)
  803. ret = ICE_DCB_HW_CHG;
  804. delapp_out:
  805. mutex_unlock(&pf->tc_mutex);
  806. return ret;
  807. }
  808. /**
  809. * ice_dcbnl_cee_set_all - Commit CEE DCB settings to HW
  810. * @netdev: the corresponding netdev
  811. */
  812. static u8 ice_dcbnl_cee_set_all(struct net_device *netdev)
  813. {
  814. struct ice_pf *pf = ice_netdev_to_pf(netdev);
  815. struct ice_dcbx_cfg *new_cfg;
  816. int err;
  817. if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
  818. !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
  819. return ICE_DCB_NO_HW_CHG;
  820. if (pf->lag && pf->lag->bonded) {
  821. netdev_err(netdev, "DCB changes not allowed when in a bond\n");
  822. return ICE_DCB_NO_HW_CHG;
  823. }
  824. new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;
  825. mutex_lock(&pf->tc_mutex);
  826. err = ice_pf_dcb_cfg(pf, new_cfg, true);
  827. mutex_unlock(&pf->tc_mutex);
  828. return (err != ICE_DCB_HW_CHG_RST) ? ICE_DCB_NO_HW_CHG : err;
  829. }
  830. static const struct dcbnl_rtnl_ops dcbnl_ops = {
  831. /* IEEE 802.1Qaz std */
  832. .ieee_getets = ice_dcbnl_getets,
  833. .ieee_setets = ice_dcbnl_setets,
  834. .ieee_getpfc = ice_dcbnl_getpfc,
  835. .ieee_setpfc = ice_dcbnl_setpfc,
  836. .ieee_setapp = ice_dcbnl_setapp,
  837. .ieee_delapp = ice_dcbnl_delapp,
  838. /* CEE std */
  839. .getstate = ice_dcbnl_getstate,
  840. .setstate = ice_dcbnl_setstate,
  841. .getpermhwaddr = ice_dcbnl_get_perm_hw_addr,
  842. .setpgtccfgtx = ice_dcbnl_set_pg_tc_cfg_tx,
  843. .setpgbwgcfgtx = ice_dcbnl_set_pg_bwg_cfg_tx,
  844. .setpgtccfgrx = ice_dcbnl_set_pg_tc_cfg_rx,
  845. .setpgbwgcfgrx = ice_dcbnl_set_pg_bwg_cfg_rx,
  846. .getpgtccfgtx = ice_dcbnl_get_pg_tc_cfg_tx,
  847. .getpgbwgcfgtx = ice_dcbnl_get_pg_bwg_cfg_tx,
  848. .getpgtccfgrx = ice_dcbnl_get_pg_tc_cfg_rx,
  849. .getpgbwgcfgrx = ice_dcbnl_get_pg_bwg_cfg_rx,
  850. .setpfccfg = ice_dcbnl_set_pfc_cfg,
  851. .getpfccfg = ice_dcbnl_get_pfc_cfg,
  852. .setall = ice_dcbnl_cee_set_all,
  853. .getcap = ice_dcbnl_get_cap,
  854. .getnumtcs = ice_dcbnl_getnumtcs,
  855. .getpfcstate = ice_dcbnl_getpfcstate,
  856. .getapp = ice_dcbnl_getapp,
  857. /* DCBX configuration */
  858. .getdcbx = ice_dcbnl_getdcbx,
  859. .setdcbx = ice_dcbnl_setdcbx,
  860. };
  861. /**
  862. * ice_dcbnl_set_all - set all the apps and ieee data from DCBX config
  863. * @vsi: pointer to VSI struct
  864. */
  865. void ice_dcbnl_set_all(struct ice_vsi *vsi)
  866. {
  867. struct net_device *netdev = vsi->netdev;
  868. struct ice_dcbx_cfg *dcbxcfg;
  869. struct ice_port_info *pi;
  870. struct dcb_app sapp;
  871. struct ice_pf *pf;
  872. unsigned int i;
  873. if (!netdev)
  874. return;
  875. pf = ice_netdev_to_pf(netdev);
  876. pi = pf->hw.port_info;
  877. /* SW DCB taken care of by SW Default Config */
  878. if (pf->dcbx_cap & DCB_CAP_DCBX_HOST)
  879. return;
  880. /* DCB not enabled */
  881. if (!test_bit(ICE_FLAG_DCB_ENA, pf->flags))
  882. return;
  883. dcbxcfg = &pi->qos_cfg.local_dcbx_cfg;
  884. for (i = 0; i < dcbxcfg->numapps; i++) {
  885. u8 prio, tc_map;
  886. prio = dcbxcfg->app[i].priority;
  887. tc_map = BIT(dcbxcfg->etscfg.prio_table[prio]);
  888. /* Add APP only if the TC is enabled for this VSI */
  889. if (tc_map & vsi->tc_cfg.ena_tc) {
  890. sapp.selector = dcbxcfg->app[i].selector;
  891. sapp.protocol = dcbxcfg->app[i].prot_id;
  892. sapp.priority = prio;
  893. dcb_ieee_setapp(netdev, &sapp);
  894. }
  895. }
  896. /* Notify user-space of the changes */
  897. dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_SET, 0, 0);
  898. }
  899. /**
  900. * ice_dcbnl_vsi_del_app - Delete APP on all VSIs
  901. * @vsi: pointer to the main VSI
  902. * @app: APP to delete
  903. *
  904. * Delete given APP from all the VSIs for given PF
  905. */
  906. static void
  907. ice_dcbnl_vsi_del_app(struct ice_vsi *vsi,
  908. struct ice_dcb_app_priority_table *app)
  909. {
  910. struct dcb_app sapp;
  911. int err;
  912. sapp.selector = app->selector;
  913. sapp.protocol = app->prot_id;
  914. sapp.priority = app->priority;
  915. err = ice_dcbnl_delapp(vsi->netdev, &sapp);
  916. dev_dbg(ice_pf_to_dev(vsi->back), "Deleting app for VSI idx=%d err=%d sel=%d proto=0x%x, prio=%d\n",
  917. vsi->idx, err, app->selector, app->prot_id, app->priority);
  918. }
  919. /**
  920. * ice_dcbnl_flush_apps - Delete all removed APPs
  921. * @pf: the corresponding PF
  922. * @old_cfg: old DCBX configuration data
  923. * @new_cfg: new DCBX configuration data
  924. *
  925. * Find and delete all APPS that are not present in the passed
  926. * DCB configuration
  927. */
  928. void
  929. ice_dcbnl_flush_apps(struct ice_pf *pf, struct ice_dcbx_cfg *old_cfg,
  930. struct ice_dcbx_cfg *new_cfg)
  931. {
  932. struct ice_vsi *main_vsi = ice_get_main_vsi(pf);
  933. unsigned int i;
  934. if (!main_vsi)
  935. return;
  936. for (i = 0; i < old_cfg->numapps; i++) {
  937. struct ice_dcb_app_priority_table app = old_cfg->app[i];
  938. /* The APP is not available anymore delete it */
  939. if (!ice_dcbnl_find_app(new_cfg, &app))
  940. ice_dcbnl_vsi_del_app(main_vsi, &app);
  941. }
  942. }
  943. /**
  944. * ice_dcbnl_setup - setup DCBNL
  945. * @vsi: VSI to get associated netdev from
  946. */
  947. void ice_dcbnl_setup(struct ice_vsi *vsi)
  948. {
  949. struct net_device *netdev = vsi->netdev;
  950. struct ice_pf *pf;
  951. pf = ice_netdev_to_pf(netdev);
  952. if (!test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags))
  953. return;
  954. netdev->dcbnl_ops = &dcbnl_ops;
  955. ice_dcbnl_set_all(vsi);
  956. }