ixgbe_dcb_nl.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright(c) 1999 - 2018 Intel Corporation. */
  3. #include "ixgbe.h"
  4. #include <linux/dcbnl.h>
  5. #include "ixgbe_dcb_82598.h"
  6. #include "ixgbe_dcb_82599.h"
  7. #include "ixgbe_sriov.h"
  8. /* Callbacks for DCB netlink in the kernel */
  9. #define BIT_DCB_MODE 0x01
  10. #define BIT_PFC 0x02
  11. #define BIT_PG_RX 0x04
  12. #define BIT_PG_TX 0x08
  13. #define BIT_APP_UPCHG 0x10
  14. #define BIT_LINKSPEED 0x80
  15. /* Responses for the DCB_C_SET_ALL command */
  16. #define DCB_HW_CHG_RST 0 /* DCB configuration changed with reset */
  17. #define DCB_NO_HW_CHG 1 /* DCB configuration did not change */
  18. #define DCB_HW_CHG 2 /* DCB configuration changed, no reset */
  19. static int ixgbe_copy_dcb_cfg(struct ixgbe_adapter *adapter, int tc_max)
  20. {
  21. struct ixgbe_dcb_config *scfg = &adapter->temp_dcb_cfg;
  22. struct ixgbe_dcb_config *dcfg = &adapter->dcb_cfg;
  23. struct tc_configuration *src = NULL;
  24. struct tc_configuration *dst = NULL;
  25. int i, j;
  26. int tx = DCB_TX_CONFIG;
  27. int rx = DCB_RX_CONFIG;
  28. int changes = 0;
  29. #ifdef IXGBE_FCOE
  30. struct dcb_app app = {
  31. .selector = DCB_APP_IDTYPE_ETHTYPE,
  32. .protocol = ETH_P_FCOE,
  33. };
  34. u8 up = dcb_getapp(adapter->netdev, &app);
  35. if (up && !(up & BIT(adapter->fcoe.up)))
  36. changes |= BIT_APP_UPCHG;
  37. #endif
  38. for (i = DCB_PG_ATTR_TC_0; i < tc_max + DCB_PG_ATTR_TC_0; i++) {
  39. src = &scfg->tc_config[i - DCB_PG_ATTR_TC_0];
  40. dst = &dcfg->tc_config[i - DCB_PG_ATTR_TC_0];
  41. if (dst->path[tx].prio_type != src->path[tx].prio_type) {
  42. dst->path[tx].prio_type = src->path[tx].prio_type;
  43. changes |= BIT_PG_TX;
  44. }
  45. if (dst->path[tx].bwg_id != src->path[tx].bwg_id) {
  46. dst->path[tx].bwg_id = src->path[tx].bwg_id;
  47. changes |= BIT_PG_TX;
  48. }
  49. if (dst->path[tx].bwg_percent != src->path[tx].bwg_percent) {
  50. dst->path[tx].bwg_percent = src->path[tx].bwg_percent;
  51. changes |= BIT_PG_TX;
  52. }
  53. if (dst->path[tx].up_to_tc_bitmap !=
  54. src->path[tx].up_to_tc_bitmap) {
  55. dst->path[tx].up_to_tc_bitmap =
  56. src->path[tx].up_to_tc_bitmap;
  57. changes |= (BIT_PG_TX | BIT_PFC | BIT_APP_UPCHG);
  58. }
  59. if (dst->path[rx].prio_type != src->path[rx].prio_type) {
  60. dst->path[rx].prio_type = src->path[rx].prio_type;
  61. changes |= BIT_PG_RX;
  62. }
  63. if (dst->path[rx].bwg_id != src->path[rx].bwg_id) {
  64. dst->path[rx].bwg_id = src->path[rx].bwg_id;
  65. changes |= BIT_PG_RX;
  66. }
  67. if (dst->path[rx].bwg_percent != src->path[rx].bwg_percent) {
  68. dst->path[rx].bwg_percent = src->path[rx].bwg_percent;
  69. changes |= BIT_PG_RX;
  70. }
  71. if (dst->path[rx].up_to_tc_bitmap !=
  72. src->path[rx].up_to_tc_bitmap) {
  73. dst->path[rx].up_to_tc_bitmap =
  74. src->path[rx].up_to_tc_bitmap;
  75. changes |= (BIT_PG_RX | BIT_PFC | BIT_APP_UPCHG);
  76. }
  77. }
  78. for (i = DCB_PG_ATTR_BW_ID_0; i < DCB_PG_ATTR_BW_ID_MAX; i++) {
  79. j = i - DCB_PG_ATTR_BW_ID_0;
  80. if (dcfg->bw_percentage[tx][j] != scfg->bw_percentage[tx][j]) {
  81. dcfg->bw_percentage[tx][j] = scfg->bw_percentage[tx][j];
  82. changes |= BIT_PG_TX;
  83. }
  84. if (dcfg->bw_percentage[rx][j] != scfg->bw_percentage[rx][j]) {
  85. dcfg->bw_percentage[rx][j] = scfg->bw_percentage[rx][j];
  86. changes |= BIT_PG_RX;
  87. }
  88. }
  89. for (i = DCB_PFC_UP_ATTR_0; i < DCB_PFC_UP_ATTR_MAX; i++) {
  90. j = i - DCB_PFC_UP_ATTR_0;
  91. if (dcfg->tc_config[j].dcb_pfc != scfg->tc_config[j].dcb_pfc) {
  92. dcfg->tc_config[j].dcb_pfc = scfg->tc_config[j].dcb_pfc;
  93. changes |= BIT_PFC;
  94. }
  95. }
  96. if (dcfg->pfc_mode_enable != scfg->pfc_mode_enable) {
  97. dcfg->pfc_mode_enable = scfg->pfc_mode_enable;
  98. changes |= BIT_PFC;
  99. }
  100. return changes;
  101. }
  102. static u8 ixgbe_dcbnl_get_state(struct net_device *netdev)
  103. {
  104. struct ixgbe_adapter *adapter = netdev_priv(netdev);
  105. return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED);
  106. }
  107. static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
  108. {
  109. struct ixgbe_adapter *adapter = netdev_priv(netdev);
  110. /* Fail command if not in CEE mode */
  111. if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
  112. return 1;
  113. /* verify there is something to do, if not then exit */
  114. if (!state == !(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
  115. return 0;
  116. return !!ixgbe_setup_tc(netdev,
  117. state ? adapter->dcb_cfg.num_tcs.pg_tcs : 0);
  118. }
  119. static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev,
  120. u8 *perm_addr)
  121. {
  122. struct ixgbe_adapter *adapter = netdev_priv(netdev);
  123. int i, j;
  124. memset(perm_addr, 0xff, MAX_ADDR_LEN);
  125. for (i = 0; i < netdev->addr_len; i++)
  126. perm_addr[i] = adapter->hw.mac.perm_addr[i];
  127. switch (adapter->hw.mac.type) {
  128. case ixgbe_mac_82599EB:
  129. case ixgbe_mac_X540:
  130. case ixgbe_mac_X550:
  131. for (j = 0; j < netdev->addr_len; j++, i++)
  132. perm_addr[i] = adapter->hw.mac.san_addr[j];
  133. break;
  134. default:
  135. break;
  136. }
  137. }
  138. static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
  139. u8 prio, u8 bwg_id, u8 bw_pct,
  140. u8 up_map)
  141. {
  142. struct ixgbe_adapter *adapter = netdev_priv(netdev);
  143. if (prio != DCB_ATTR_VALUE_UNDEFINED)
  144. adapter->temp_dcb_cfg.tc_config[tc].path[0].prio_type = prio;
  145. if (bwg_id != DCB_ATTR_VALUE_UNDEFINED)
  146. adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_id = bwg_id;
  147. if (bw_pct != DCB_ATTR_VALUE_UNDEFINED)
  148. adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_percent =
  149. bw_pct;
  150. if (up_map != DCB_ATTR_VALUE_UNDEFINED)
  151. adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap =
  152. up_map;
  153. }
  154. static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id,
  155. u8 bw_pct)
  156. {
  157. struct ixgbe_adapter *adapter = netdev_priv(netdev);
  158. adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] = bw_pct;
  159. }
  160. static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc,
  161. u8 prio, u8 bwg_id, u8 bw_pct,
  162. u8 up_map)
  163. {
  164. struct ixgbe_adapter *adapter = netdev_priv(netdev);
  165. if (prio != DCB_ATTR_VALUE_UNDEFINED)
  166. adapter->temp_dcb_cfg.tc_config[tc].path[1].prio_type = prio;
  167. if (bwg_id != DCB_ATTR_VALUE_UNDEFINED)
  168. adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_id = bwg_id;
  169. if (bw_pct != DCB_ATTR_VALUE_UNDEFINED)
  170. adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_percent =
  171. bw_pct;
  172. if (up_map != DCB_ATTR_VALUE_UNDEFINED)
  173. adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap =
  174. up_map;
  175. }
  176. static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id,
  177. u8 bw_pct)
  178. {
  179. struct ixgbe_adapter *adapter = netdev_priv(netdev);
  180. adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] = bw_pct;
  181. }
  182. static void ixgbe_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int tc,
  183. u8 *prio, u8 *bwg_id, u8 *bw_pct,
  184. u8 *up_map)
  185. {
  186. struct ixgbe_adapter *adapter = netdev_priv(netdev);
  187. *prio = adapter->dcb_cfg.tc_config[tc].path[0].prio_type;
  188. *bwg_id = adapter->dcb_cfg.tc_config[tc].path[0].bwg_id;
  189. *bw_pct = adapter->dcb_cfg.tc_config[tc].path[0].bwg_percent;
  190. *up_map = adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap;
  191. }
  192. static void ixgbe_dcbnl_get_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id,
  193. u8 *bw_pct)
  194. {
  195. struct ixgbe_adapter *adapter = netdev_priv(netdev);
  196. *bw_pct = adapter->dcb_cfg.bw_percentage[0][bwg_id];
  197. }
  198. static void ixgbe_dcbnl_get_pg_tc_cfg_rx(struct net_device *netdev, int tc,
  199. u8 *prio, u8 *bwg_id, u8 *bw_pct,
  200. u8 *up_map)
  201. {
  202. struct ixgbe_adapter *adapter = netdev_priv(netdev);
  203. *prio = adapter->dcb_cfg.tc_config[tc].path[1].prio_type;
  204. *bwg_id = adapter->dcb_cfg.tc_config[tc].path[1].bwg_id;
  205. *bw_pct = adapter->dcb_cfg.tc_config[tc].path[1].bwg_percent;
  206. *up_map = adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap;
  207. }
  208. static void ixgbe_dcbnl_get_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id,
  209. u8 *bw_pct)
  210. {
  211. struct ixgbe_adapter *adapter = netdev_priv(netdev);
  212. *bw_pct = adapter->dcb_cfg.bw_percentage[1][bwg_id];
  213. }
  214. static void ixgbe_dcbnl_set_pfc_cfg(struct net_device *netdev, int priority,
  215. u8 setting)
  216. {
  217. struct ixgbe_adapter *adapter = netdev_priv(netdev);
  218. adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc = setting;
  219. if (adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc !=
  220. adapter->dcb_cfg.tc_config[priority].dcb_pfc)
  221. adapter->temp_dcb_cfg.pfc_mode_enable = true;
  222. }
  223. static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority,
  224. u8 *setting)
  225. {
  226. struct ixgbe_adapter *adapter = netdev_priv(netdev);
  227. *setting = adapter->dcb_cfg.tc_config[priority].dcb_pfc;
  228. }
  229. static void ixgbe_dcbnl_devreset(struct net_device *dev)
  230. {
  231. struct ixgbe_adapter *adapter = netdev_priv(dev);
  232. while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
  233. usleep_range(1000, 2000);
  234. if (netif_running(dev))
  235. dev->netdev_ops->ndo_stop(dev);
  236. ixgbe_clear_interrupt_scheme(adapter);
  237. ixgbe_init_interrupt_scheme(adapter);
  238. if (netif_running(dev))
  239. dev->netdev_ops->ndo_open(dev);
  240. clear_bit(__IXGBE_RESETTING, &adapter->state);
  241. }
  242. static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
  243. {
  244. struct ixgbe_adapter *adapter = netdev_priv(netdev);
  245. struct ixgbe_dcb_config *dcb_cfg = &adapter->dcb_cfg;
  246. struct ixgbe_hw *hw = &adapter->hw;
  247. int ret = DCB_NO_HW_CHG;
  248. int i;
  249. /* Fail command if not in CEE mode */
  250. if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
  251. return DCB_NO_HW_CHG;
  252. adapter->dcb_set_bitmap |= ixgbe_copy_dcb_cfg(adapter,
  253. MAX_TRAFFIC_CLASS);
  254. if (!adapter->dcb_set_bitmap)
  255. return DCB_NO_HW_CHG;
  256. if (adapter->dcb_set_bitmap & (BIT_PG_TX|BIT_PG_RX)) {
  257. u16 refill[MAX_TRAFFIC_CLASS], max[MAX_TRAFFIC_CLASS];
  258. u8 bwg_id[MAX_TRAFFIC_CLASS], prio_type[MAX_TRAFFIC_CLASS];
  259. /* Priority to TC mapping in CEE case default to 1:1 */
  260. u8 prio_tc[MAX_USER_PRIORITY];
  261. int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
  262. #ifdef IXGBE_FCOE
  263. if (adapter->netdev->features & NETIF_F_FCOE_MTU)
  264. max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE);
  265. #endif
  266. ixgbe_dcb_calculate_tc_credits(hw, dcb_cfg, max_frame,
  267. DCB_TX_CONFIG);
  268. ixgbe_dcb_calculate_tc_credits(hw, dcb_cfg, max_frame,
  269. DCB_RX_CONFIG);
  270. ixgbe_dcb_unpack_refill(dcb_cfg, DCB_TX_CONFIG, refill);
  271. ixgbe_dcb_unpack_max(dcb_cfg, max);
  272. ixgbe_dcb_unpack_bwgid(dcb_cfg, DCB_TX_CONFIG, bwg_id);
  273. ixgbe_dcb_unpack_prio(dcb_cfg, DCB_TX_CONFIG, prio_type);
  274. ixgbe_dcb_unpack_map(dcb_cfg, DCB_TX_CONFIG, prio_tc);
  275. ixgbe_dcb_hw_ets_config(hw, refill, max, bwg_id,
  276. prio_type, prio_tc);
  277. for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
  278. netdev_set_prio_tc_map(netdev, i, prio_tc[i]);
  279. ret = DCB_HW_CHG_RST;
  280. }
  281. if (adapter->dcb_set_bitmap & BIT_PFC) {
  282. if (dcb_cfg->pfc_mode_enable) {
  283. u8 pfc_en;
  284. u8 prio_tc[MAX_USER_PRIORITY];
  285. ixgbe_dcb_unpack_map(dcb_cfg, DCB_TX_CONFIG, prio_tc);
  286. ixgbe_dcb_unpack_pfc(dcb_cfg, &pfc_en);
  287. ixgbe_dcb_hw_pfc_config(hw, pfc_en, prio_tc);
  288. } else {
  289. hw->mac.ops.fc_enable(hw);
  290. }
  291. ixgbe_set_rx_drop_en(adapter);
  292. ret = DCB_HW_CHG;
  293. }
  294. #ifdef IXGBE_FCOE
  295. /* Reprogam FCoE hardware offloads when the traffic class
  296. * FCoE is using changes. This happens if the APP info
  297. * changes or the up2tc mapping is updated.
  298. */
  299. if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
  300. struct dcb_app app = {
  301. .selector = DCB_APP_IDTYPE_ETHTYPE,
  302. .protocol = ETH_P_FCOE,
  303. };
  304. u8 up = dcb_getapp(netdev, &app);
  305. adapter->fcoe.up = ffs(up) - 1;
  306. ixgbe_dcbnl_devreset(netdev);
  307. ret = DCB_HW_CHG_RST;
  308. }
  309. #endif
  310. adapter->dcb_set_bitmap = 0x00;
  311. return ret;
  312. }
  313. static u8 ixgbe_dcbnl_getcap(struct net_device *netdev, int capid, u8 *cap)
  314. {
  315. struct ixgbe_adapter *adapter = netdev_priv(netdev);
  316. switch (capid) {
  317. case DCB_CAP_ATTR_PG:
  318. *cap = true;
  319. break;
  320. case DCB_CAP_ATTR_PFC:
  321. *cap = true;
  322. break;
  323. case DCB_CAP_ATTR_UP2TC:
  324. *cap = false;
  325. break;
  326. case DCB_CAP_ATTR_PG_TCS:
  327. *cap = 0x80;
  328. break;
  329. case DCB_CAP_ATTR_PFC_TCS:
  330. *cap = 0x80;
  331. break;
  332. case DCB_CAP_ATTR_GSP:
  333. *cap = true;
  334. break;
  335. case DCB_CAP_ATTR_BCN:
  336. *cap = false;
  337. break;
  338. case DCB_CAP_ATTR_DCBX:
  339. *cap = adapter->dcbx_cap;
  340. break;
  341. default:
  342. *cap = false;
  343. break;
  344. }
  345. return 0;
  346. }
  347. static int ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num)
  348. {
  349. struct ixgbe_adapter *adapter = netdev_priv(netdev);
  350. if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
  351. switch (tcid) {
  352. case DCB_NUMTCS_ATTR_PG:
  353. *num = adapter->dcb_cfg.num_tcs.pg_tcs;
  354. break;
  355. case DCB_NUMTCS_ATTR_PFC:
  356. *num = adapter->dcb_cfg.num_tcs.pfc_tcs;
  357. break;
  358. default:
  359. return -EINVAL;
  360. }
  361. } else {
  362. return -EINVAL;
  363. }
  364. return 0;
  365. }
  366. static int ixgbe_dcbnl_setnumtcs(struct net_device *netdev, int tcid, u8 num)
  367. {
  368. return -EINVAL;
  369. }
  370. static u8 ixgbe_dcbnl_getpfcstate(struct net_device *netdev)
  371. {
  372. struct ixgbe_adapter *adapter = netdev_priv(netdev);
  373. return adapter->dcb_cfg.pfc_mode_enable;
  374. }
  375. static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
  376. {
  377. struct ixgbe_adapter *adapter = netdev_priv(netdev);
  378. adapter->temp_dcb_cfg.pfc_mode_enable = state;
  379. }
  380. /**
  381. * ixgbe_dcbnl_getapp - retrieve the DCBX application user priority
  382. * @netdev : the corresponding netdev
  383. * @idtype : identifies the id as ether type or TCP/UDP port number
  384. * @id: id is either ether type or TCP/UDP port number
  385. *
  386. * Returns : on success, returns a non-zero 802.1p user priority bitmap
  387. * otherwise returns -EINVAL as the invalid user priority bitmap to indicate an
  388. * error.
  389. */
  390. static int ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
  391. {
  392. struct ixgbe_adapter *adapter = netdev_priv(netdev);
  393. struct dcb_app app = {
  394. .selector = idtype,
  395. .protocol = id,
  396. };
  397. if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
  398. return -EINVAL;
  399. return dcb_getapp(netdev, &app);
  400. }
  401. static int ixgbe_dcbnl_ieee_getets(struct net_device *dev,
  402. struct ieee_ets *ets)
  403. {
  404. struct ixgbe_adapter *adapter = netdev_priv(dev);
  405. struct ieee_ets *my_ets = adapter->ixgbe_ieee_ets;
  406. ets->ets_cap = adapter->dcb_cfg.num_tcs.pg_tcs;
  407. /* No IEEE PFC settings available */
  408. if (!my_ets)
  409. return 0;
  410. ets->cbs = my_ets->cbs;
  411. memcpy(ets->tc_tx_bw, my_ets->tc_tx_bw, sizeof(ets->tc_tx_bw));
  412. memcpy(ets->tc_rx_bw, my_ets->tc_rx_bw, sizeof(ets->tc_rx_bw));
  413. memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa));
  414. memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc));
  415. return 0;
  416. }
  417. static int ixgbe_dcbnl_ieee_setets(struct net_device *dev,
  418. struct ieee_ets *ets)
  419. {
  420. struct ixgbe_adapter *adapter = netdev_priv(dev);
  421. int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN;
  422. int i, err;
  423. __u8 max_tc = 0;
  424. __u8 map_chg = 0;
  425. if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
  426. return -EINVAL;
  427. if (!adapter->ixgbe_ieee_ets) {
  428. adapter->ixgbe_ieee_ets = kmalloc(sizeof(struct ieee_ets),
  429. GFP_KERNEL);
  430. if (!adapter->ixgbe_ieee_ets)
  431. return -ENOMEM;
  432. /* initialize UP2TC mappings to invalid value */
  433. for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
  434. adapter->ixgbe_ieee_ets->prio_tc[i] =
  435. IEEE_8021QAZ_MAX_TCS;
  436. /* if possible update UP2TC mappings from HW */
  437. ixgbe_dcb_read_rtrup2tc(&adapter->hw,
  438. adapter->ixgbe_ieee_ets->prio_tc);
  439. }
  440. for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
  441. if (ets->prio_tc[i] > max_tc)
  442. max_tc = ets->prio_tc[i];
  443. if (ets->prio_tc[i] != adapter->ixgbe_ieee_ets->prio_tc[i])
  444. map_chg = 1;
  445. }
  446. memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets));
  447. if (max_tc)
  448. max_tc++;
  449. if (max_tc > adapter->dcb_cfg.num_tcs.pg_tcs)
  450. return -EINVAL;
  451. if (max_tc != adapter->hw_tcs) {
  452. err = ixgbe_setup_tc(dev, max_tc);
  453. if (err)
  454. return err;
  455. } else if (map_chg) {
  456. ixgbe_dcbnl_devreset(dev);
  457. }
  458. return ixgbe_dcb_hw_ets(&adapter->hw, ets, max_frame);
  459. }
  460. static int ixgbe_dcbnl_ieee_getpfc(struct net_device *dev,
  461. struct ieee_pfc *pfc)
  462. {
  463. struct ixgbe_adapter *adapter = netdev_priv(dev);
  464. struct ieee_pfc *my_pfc = adapter->ixgbe_ieee_pfc;
  465. int i;
  466. pfc->pfc_cap = adapter->dcb_cfg.num_tcs.pfc_tcs;
  467. /* No IEEE PFC settings available */
  468. if (!my_pfc)
  469. return 0;
  470. pfc->pfc_en = my_pfc->pfc_en;
  471. pfc->mbc = my_pfc->mbc;
  472. pfc->delay = my_pfc->delay;
  473. for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
  474. pfc->requests[i] = adapter->stats.pxoffrxc[i];
  475. pfc->indications[i] = adapter->stats.pxofftxc[i];
  476. }
  477. return 0;
  478. }
  479. static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev,
  480. struct ieee_pfc *pfc)
  481. {
  482. struct ixgbe_adapter *adapter = netdev_priv(dev);
  483. struct ixgbe_hw *hw = &adapter->hw;
  484. u8 *prio_tc;
  485. int err;
  486. if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
  487. return -EINVAL;
  488. if (!adapter->ixgbe_ieee_pfc) {
  489. adapter->ixgbe_ieee_pfc = kmalloc(sizeof(struct ieee_pfc),
  490. GFP_KERNEL);
  491. if (!adapter->ixgbe_ieee_pfc)
  492. return -ENOMEM;
  493. }
  494. prio_tc = adapter->ixgbe_ieee_ets->prio_tc;
  495. memcpy(adapter->ixgbe_ieee_pfc, pfc, sizeof(*adapter->ixgbe_ieee_pfc));
  496. /* Enable link flow control parameters if PFC is disabled */
  497. if (pfc->pfc_en)
  498. err = ixgbe_dcb_hw_pfc_config(hw, pfc->pfc_en, prio_tc);
  499. else
  500. err = hw->mac.ops.fc_enable(hw);
  501. ixgbe_set_rx_drop_en(adapter);
  502. return err;
  503. }
  504. static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev,
  505. struct dcb_app *app)
  506. {
  507. struct ixgbe_adapter *adapter = netdev_priv(dev);
  508. int err;
  509. if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
  510. return -EINVAL;
  511. err = dcb_ieee_setapp(dev, app);
  512. if (err)
  513. return err;
  514. #ifdef IXGBE_FCOE
  515. if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
  516. app->protocol == ETH_P_FCOE) {
  517. u8 app_mask = dcb_ieee_getapp_mask(dev, app);
  518. if (app_mask & BIT(adapter->fcoe.up))
  519. return 0;
  520. adapter->fcoe.up = app->priority;
  521. ixgbe_dcbnl_devreset(dev);
  522. }
  523. #endif
  524. /* VF devices should use default UP when available */
  525. if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
  526. app->protocol == 0) {
  527. int vf;
  528. adapter->default_up = app->priority;
  529. for (vf = 0; vf < adapter->num_vfs; vf++) {
  530. struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
  531. if (!vfinfo->pf_qos)
  532. ixgbe_set_vmvir(adapter, vfinfo->pf_vlan,
  533. app->priority, vf);
  534. }
  535. }
  536. return 0;
  537. }
  538. static int ixgbe_dcbnl_ieee_delapp(struct net_device *dev,
  539. struct dcb_app *app)
  540. {
  541. struct ixgbe_adapter *adapter = netdev_priv(dev);
  542. int err;
  543. if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
  544. return -EINVAL;
  545. err = dcb_ieee_delapp(dev, app);
  546. #ifdef IXGBE_FCOE
  547. if (!err && app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
  548. app->protocol == ETH_P_FCOE) {
  549. u8 app_mask = dcb_ieee_getapp_mask(dev, app);
  550. if (app_mask & BIT(adapter->fcoe.up))
  551. return 0;
  552. adapter->fcoe.up = app_mask ?
  553. ffs(app_mask) - 1 : IXGBE_FCOE_DEFTC;
  554. ixgbe_dcbnl_devreset(dev);
  555. }
  556. #endif
  557. /* IF default priority is being removed clear VF default UP */
  558. if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
  559. app->protocol == 0 && adapter->default_up == app->priority) {
  560. int vf;
  561. long unsigned int app_mask = dcb_ieee_getapp_mask(dev, app);
  562. int qos = app_mask ? find_first_bit(&app_mask, 8) : 0;
  563. adapter->default_up = qos;
  564. for (vf = 0; vf < adapter->num_vfs; vf++) {
  565. struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
  566. if (!vfinfo->pf_qos)
  567. ixgbe_set_vmvir(adapter, vfinfo->pf_vlan,
  568. qos, vf);
  569. }
  570. }
  571. return err;
  572. }
  573. static u8 ixgbe_dcbnl_getdcbx(struct net_device *dev)
  574. {
  575. struct ixgbe_adapter *adapter = netdev_priv(dev);
  576. return adapter->dcbx_cap;
  577. }
  578. static u8 ixgbe_dcbnl_setdcbx(struct net_device *dev, u8 mode)
  579. {
  580. struct ixgbe_adapter *adapter = netdev_priv(dev);
  581. struct ieee_ets ets = {0};
  582. struct ieee_pfc pfc = {0};
  583. int err = 0;
  584. /* no support for LLD_MANAGED modes or CEE+IEEE */
  585. if ((mode & DCB_CAP_DCBX_LLD_MANAGED) ||
  586. ((mode & DCB_CAP_DCBX_VER_IEEE) && (mode & DCB_CAP_DCBX_VER_CEE)) ||
  587. !(mode & DCB_CAP_DCBX_HOST))
  588. return 1;
  589. if (mode == adapter->dcbx_cap)
  590. return 0;
  591. adapter->dcbx_cap = mode;
  592. /* ETS and PFC defaults */
  593. ets.ets_cap = 8;
  594. pfc.pfc_cap = 8;
  595. if (mode & DCB_CAP_DCBX_VER_IEEE) {
  596. ixgbe_dcbnl_ieee_setets(dev, &ets);
  597. ixgbe_dcbnl_ieee_setpfc(dev, &pfc);
  598. } else if (mode & DCB_CAP_DCBX_VER_CEE) {
  599. u8 mask = BIT_PFC | BIT_PG_TX | BIT_PG_RX | BIT_APP_UPCHG;
  600. adapter->dcb_set_bitmap |= mask;
  601. ixgbe_dcbnl_set_all(dev);
  602. } else {
  603. /* Drop into single TC mode strict priority as this
  604. * indicates CEE and IEEE versions are disabled
  605. */
  606. ixgbe_dcbnl_ieee_setets(dev, &ets);
  607. ixgbe_dcbnl_ieee_setpfc(dev, &pfc);
  608. err = ixgbe_setup_tc(dev, 0);
  609. }
  610. return err ? 1 : 0;
  611. }
  612. const struct dcbnl_rtnl_ops ixgbe_dcbnl_ops = {
  613. .ieee_getets = ixgbe_dcbnl_ieee_getets,
  614. .ieee_setets = ixgbe_dcbnl_ieee_setets,
  615. .ieee_getpfc = ixgbe_dcbnl_ieee_getpfc,
  616. .ieee_setpfc = ixgbe_dcbnl_ieee_setpfc,
  617. .ieee_setapp = ixgbe_dcbnl_ieee_setapp,
  618. .ieee_delapp = ixgbe_dcbnl_ieee_delapp,
  619. .getstate = ixgbe_dcbnl_get_state,
  620. .setstate = ixgbe_dcbnl_set_state,
  621. .getpermhwaddr = ixgbe_dcbnl_get_perm_hw_addr,
  622. .setpgtccfgtx = ixgbe_dcbnl_set_pg_tc_cfg_tx,
  623. .setpgbwgcfgtx = ixgbe_dcbnl_set_pg_bwg_cfg_tx,
  624. .setpgtccfgrx = ixgbe_dcbnl_set_pg_tc_cfg_rx,
  625. .setpgbwgcfgrx = ixgbe_dcbnl_set_pg_bwg_cfg_rx,
  626. .getpgtccfgtx = ixgbe_dcbnl_get_pg_tc_cfg_tx,
  627. .getpgbwgcfgtx = ixgbe_dcbnl_get_pg_bwg_cfg_tx,
  628. .getpgtccfgrx = ixgbe_dcbnl_get_pg_tc_cfg_rx,
  629. .getpgbwgcfgrx = ixgbe_dcbnl_get_pg_bwg_cfg_rx,
  630. .setpfccfg = ixgbe_dcbnl_set_pfc_cfg,
  631. .getpfccfg = ixgbe_dcbnl_get_pfc_cfg,
  632. .setall = ixgbe_dcbnl_set_all,
  633. .getcap = ixgbe_dcbnl_getcap,
  634. .getnumtcs = ixgbe_dcbnl_getnumtcs,
  635. .setnumtcs = ixgbe_dcbnl_setnumtcs,
  636. .getpfcstate = ixgbe_dcbnl_getpfcstate,
  637. .setpfcstate = ixgbe_dcbnl_setpfcstate,
  638. .getapp = ixgbe_dcbnl_getapp,
  639. .getdcbx = ixgbe_dcbnl_getdcbx,
  640. .setdcbx = ixgbe_dcbnl_setdcbx,
  641. };