qlcnic_dcb.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179
  1. /*
  2. * QLogic qlcnic NIC Driver
  3. * Copyright (c) 2009-2013 QLogic Corporation
  4. *
  5. * See LICENSE.qlcnic for copyright and licensing details.
  6. */
  7. #include <linux/types.h>
  8. #include "qlcnic.h"
  9. #define QLC_DCB_NUM_PARAM 3
  10. #define QLC_DCB_LOCAL_IDX 0
  11. #define QLC_DCB_OPER_IDX 1
  12. #define QLC_DCB_PEER_IDX 2
  13. #define QLC_DCB_GET_MAP(V) (1 << V)
  14. #define QLC_DCB_AEN_BIT 0x2
  15. #define QLC_DCB_FW_VER 0x2
  16. #define QLC_DCB_MAX_TC 0x8
  17. #define QLC_DCB_MAX_APP 0x8
  18. #define QLC_DCB_MAX_PRIO QLC_DCB_MAX_TC
  19. #define QLC_DCB_MAX_PG QLC_DCB_MAX_TC
  20. #define QLC_DCB_TSA_SUPPORT(V) (V & 0x1)
  21. #define QLC_DCB_ETS_SUPPORT(V) ((V >> 1) & 0x1)
  22. #define QLC_DCB_VERSION_SUPPORT(V) ((V >> 2) & 0xf)
  23. #define QLC_DCB_MAX_NUM_TC(V) ((V >> 20) & 0xf)
  24. #define QLC_DCB_MAX_NUM_ETS_TC(V) ((V >> 24) & 0xf)
  25. #define QLC_DCB_MAX_NUM_PFC_TC(V) ((V >> 28) & 0xf)
  26. #define QLC_DCB_GET_TC_PRIO(X, P) ((X >> (P * 3)) & 0x7)
  27. #define QLC_DCB_GET_PGID_PRIO(X, P) ((X >> (P * 8)) & 0xff)
  28. #define QLC_DCB_GET_BWPER_PG(X, P) ((X >> (P * 8)) & 0xff)
  29. #define QLC_DCB_GET_TSA_PG(X, P) ((X >> (P * 8)) & 0xff)
  30. #define QLC_DCB_GET_PFC_PRIO(X, P) (((X >> 24) >> P) & 0x1)
  31. #define QLC_DCB_GET_PROTO_ID_APP(X) ((X >> 8) & 0xffff)
  32. #define QLC_DCB_GET_SELECTOR_APP(X) (X & 0xff)
  33. #define QLC_DCB_LOCAL_PARAM_FWID 0x3
  34. #define QLC_DCB_OPER_PARAM_FWID 0x1
  35. #define QLC_DCB_PEER_PARAM_FWID 0x2
  36. #define QLC_83XX_DCB_GET_NUMAPP(X) ((X >> 2) & 0xf)
  37. #define QLC_83XX_DCB_TSA_VALID(X) (X & 0x1)
  38. #define QLC_83XX_DCB_PFC_VALID(X) ((X >> 1) & 0x1)
  39. #define QLC_83XX_DCB_GET_PRIOMAP_APP(X) (X >> 24)
  40. #define QLC_82XX_DCB_GET_NUMAPP(X) ((X >> 12) & 0xf)
  41. #define QLC_82XX_DCB_TSA_VALID(X) ((X >> 4) & 0x1)
  42. #define QLC_82XX_DCB_PFC_VALID(X) ((X >> 5) & 0x1)
  43. #define QLC_82XX_DCB_GET_PRIOVAL_APP(X) ((X >> 24) & 0x7)
  44. #define QLC_82XX_DCB_GET_PRIOMAP_APP(X) (1 << X)
  45. #define QLC_82XX_DCB_PRIO_TC_MAP (0x76543210)
  46. static const struct dcbnl_rtnl_ops qlcnic_dcbnl_ops;
  47. static void qlcnic_dcb_aen_work(struct work_struct *);
  48. static void qlcnic_dcb_data_cee_param_map(struct qlcnic_adapter *);
  49. static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_adapter *);
  50. static void __qlcnic_dcb_free(struct qlcnic_adapter *);
  51. static int __qlcnic_dcb_attach(struct qlcnic_adapter *);
  52. static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *, char *);
  53. static void __qlcnic_dcb_get_info(struct qlcnic_adapter *);
  54. static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter *);
  55. static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_adapter *, char *, u8);
  56. static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_adapter *);
  57. static void qlcnic_82xx_dcb_handle_aen(struct qlcnic_adapter *, void *);
  58. static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter *);
  59. static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_adapter *, char *, u8);
  60. static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_adapter *);
  61. static int qlcnic_83xx_dcb_register_aen(struct qlcnic_adapter *, bool);
  62. static void qlcnic_83xx_dcb_handle_aen(struct qlcnic_adapter *, void *);
  63. struct qlcnic_dcb_capability {
  64. bool tsa_capability;
  65. bool ets_capability;
  66. u8 max_num_tc;
  67. u8 max_ets_tc;
  68. u8 max_pfc_tc;
  69. u8 dcb_capability;
  70. };
  71. struct qlcnic_dcb_param {
  72. u32 hdr_prio_pfc_map[2];
  73. u32 prio_pg_map[2];
  74. u32 pg_bw_map[2];
  75. u32 pg_tsa_map[2];
  76. u32 app[QLC_DCB_MAX_APP];
  77. };
  78. struct qlcnic_dcb_mbx_params {
  79. /* 1st local, 2nd operational 3rd remote */
  80. struct qlcnic_dcb_param type[3];
  81. u32 prio_tc_map;
  82. };
  83. struct qlcnic_82xx_dcb_param_mbx_le {
  84. __le32 hdr_prio_pfc_map[2];
  85. __le32 prio_pg_map[2];
  86. __le32 pg_bw_map[2];
  87. __le32 pg_tsa_map[2];
  88. __le32 app[QLC_DCB_MAX_APP];
  89. };
  90. enum qlcnic_dcb_selector {
  91. QLC_SELECTOR_DEF = 0x0,
  92. QLC_SELECTOR_ETHER,
  93. QLC_SELECTOR_TCP,
  94. QLC_SELECTOR_UDP,
  95. };
  96. enum qlcnic_dcb_prio_type {
  97. QLC_PRIO_NONE = 0,
  98. QLC_PRIO_GROUP,
  99. QLC_PRIO_LINK,
  100. };
  101. enum qlcnic_dcb_pfc_type {
  102. QLC_PFC_DISABLED = 0,
  103. QLC_PFC_FULL,
  104. QLC_PFC_TX,
  105. QLC_PFC_RX
  106. };
  107. struct qlcnic_dcb_prio_cfg {
  108. bool valid;
  109. enum qlcnic_dcb_pfc_type pfc_type;
  110. };
  111. struct qlcnic_dcb_pg_cfg {
  112. bool valid;
  113. u8 total_bw_percent; /* of Link/ port BW */
  114. u8 prio_count;
  115. u8 tsa_type;
  116. };
  117. struct qlcnic_dcb_tc_cfg {
  118. bool valid;
  119. struct qlcnic_dcb_prio_cfg prio_cfg[QLC_DCB_MAX_PRIO];
  120. enum qlcnic_dcb_prio_type prio_type; /* always prio_link */
  121. u8 link_percent; /* % of link bandwidth */
  122. u8 bwg_percent; /* % of BWG's bandwidth */
  123. u8 up_tc_map;
  124. u8 pgid;
  125. };
  126. struct qlcnic_dcb_app {
  127. bool valid;
  128. enum qlcnic_dcb_selector selector;
  129. u16 protocol;
  130. u8 priority;
  131. };
  132. struct qlcnic_dcb_cee {
  133. struct qlcnic_dcb_tc_cfg tc_cfg[QLC_DCB_MAX_TC];
  134. struct qlcnic_dcb_pg_cfg pg_cfg[QLC_DCB_MAX_PG];
  135. struct qlcnic_dcb_app app[QLC_DCB_MAX_APP];
  136. bool tc_param_valid;
  137. bool pfc_mode_enable;
  138. };
  139. struct qlcnic_dcb_cfg {
  140. /* 0 - local, 1 - operational, 2 - remote */
  141. struct qlcnic_dcb_cee type[QLC_DCB_NUM_PARAM];
  142. struct qlcnic_dcb_capability capability;
  143. u32 version;
  144. };
  145. static struct qlcnic_dcb_ops qlcnic_83xx_dcb_ops = {
  146. .init_dcbnl_ops = __qlcnic_init_dcbnl_ops,
  147. .free = __qlcnic_dcb_free,
  148. .attach = __qlcnic_dcb_attach,
  149. .query_hw_capability = __qlcnic_dcb_query_hw_capability,
  150. .get_info = __qlcnic_dcb_get_info,
  151. .get_hw_capability = qlcnic_83xx_dcb_get_hw_capability,
  152. .query_cee_param = qlcnic_83xx_dcb_query_cee_param,
  153. .get_cee_cfg = qlcnic_83xx_dcb_get_cee_cfg,
  154. .register_aen = qlcnic_83xx_dcb_register_aen,
  155. .handle_aen = qlcnic_83xx_dcb_handle_aen,
  156. };
  157. static struct qlcnic_dcb_ops qlcnic_82xx_dcb_ops = {
  158. .init_dcbnl_ops = __qlcnic_init_dcbnl_ops,
  159. .free = __qlcnic_dcb_free,
  160. .attach = __qlcnic_dcb_attach,
  161. .query_hw_capability = __qlcnic_dcb_query_hw_capability,
  162. .get_info = __qlcnic_dcb_get_info,
  163. .get_hw_capability = qlcnic_82xx_dcb_get_hw_capability,
  164. .query_cee_param = qlcnic_82xx_dcb_query_cee_param,
  165. .get_cee_cfg = qlcnic_82xx_dcb_get_cee_cfg,
  166. .handle_aen = qlcnic_82xx_dcb_handle_aen,
  167. };
  168. static u8 qlcnic_dcb_get_num_app(struct qlcnic_adapter *adapter, u32 val)
  169. {
  170. if (qlcnic_82xx_check(adapter))
  171. return QLC_82XX_DCB_GET_NUMAPP(val);
  172. else
  173. return QLC_83XX_DCB_GET_NUMAPP(val);
  174. }
  175. static inline u8 qlcnic_dcb_pfc_hdr_valid(struct qlcnic_adapter *adapter,
  176. u32 val)
  177. {
  178. if (qlcnic_82xx_check(adapter))
  179. return QLC_82XX_DCB_PFC_VALID(val);
  180. else
  181. return QLC_83XX_DCB_PFC_VALID(val);
  182. }
  183. static inline u8 qlcnic_dcb_tsa_hdr_valid(struct qlcnic_adapter *adapter,
  184. u32 val)
  185. {
  186. if (qlcnic_82xx_check(adapter))
  187. return QLC_82XX_DCB_TSA_VALID(val);
  188. else
  189. return QLC_83XX_DCB_TSA_VALID(val);
  190. }
  191. static inline u8 qlcnic_dcb_get_prio_map_app(struct qlcnic_adapter *adapter,
  192. u32 val)
  193. {
  194. if (qlcnic_82xx_check(adapter))
  195. return QLC_82XX_DCB_GET_PRIOMAP_APP(val);
  196. else
  197. return QLC_83XX_DCB_GET_PRIOMAP_APP(val);
  198. }
  199. static int qlcnic_dcb_prio_count(u8 up_tc_map)
  200. {
  201. int j;
  202. for (j = 0; j < QLC_DCB_MAX_TC; j++)
  203. if (up_tc_map & QLC_DCB_GET_MAP(j))
  204. break;
  205. return j;
  206. }
  207. static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_adapter *adapter)
  208. {
  209. if (test_bit(__QLCNIC_DCB_STATE, &adapter->state))
  210. adapter->netdev->dcbnl_ops = &qlcnic_dcbnl_ops;
  211. }
  212. static void qlcnic_set_dcb_ops(struct qlcnic_adapter *adapter)
  213. {
  214. if (qlcnic_82xx_check(adapter))
  215. adapter->dcb->ops = &qlcnic_82xx_dcb_ops;
  216. else if (qlcnic_83xx_check(adapter))
  217. adapter->dcb->ops = &qlcnic_83xx_dcb_ops;
  218. }
  219. int __qlcnic_register_dcb(struct qlcnic_adapter *adapter)
  220. {
  221. struct qlcnic_dcb *dcb;
  222. dcb = kzalloc(sizeof(struct qlcnic_dcb), GFP_ATOMIC);
  223. if (!dcb)
  224. return -ENOMEM;
  225. adapter->dcb = dcb;
  226. dcb->adapter = adapter;
  227. qlcnic_set_dcb_ops(adapter);
  228. return 0;
  229. }
  230. static void __qlcnic_dcb_free(struct qlcnic_adapter *adapter)
  231. {
  232. struct qlcnic_dcb *dcb = adapter->dcb;
  233. if (!dcb)
  234. return;
  235. qlcnic_dcb_register_aen(adapter, 0);
  236. while (test_bit(__QLCNIC_DCB_IN_AEN, &adapter->state))
  237. usleep_range(10000, 11000);
  238. cancel_delayed_work_sync(&dcb->aen_work);
  239. if (dcb->wq) {
  240. destroy_workqueue(dcb->wq);
  241. dcb->wq = NULL;
  242. }
  243. kfree(dcb->cfg);
  244. dcb->cfg = NULL;
  245. kfree(dcb->param);
  246. dcb->param = NULL;
  247. kfree(dcb);
  248. adapter->dcb = NULL;
  249. }
  250. static void __qlcnic_dcb_get_info(struct qlcnic_adapter *adapter)
  251. {
  252. qlcnic_dcb_get_hw_capability(adapter);
  253. qlcnic_dcb_get_cee_cfg(adapter);
  254. qlcnic_dcb_register_aen(adapter, 1);
  255. }
  256. static int __qlcnic_dcb_attach(struct qlcnic_adapter *adapter)
  257. {
  258. struct qlcnic_dcb *dcb = adapter->dcb;
  259. int err = 0;
  260. INIT_DELAYED_WORK(&dcb->aen_work, qlcnic_dcb_aen_work);
  261. dcb->wq = create_singlethread_workqueue("qlcnic-dcb");
  262. if (!dcb->wq) {
  263. dev_err(&adapter->pdev->dev,
  264. "DCB workqueue allocation failed. DCB will be disabled\n");
  265. return -1;
  266. }
  267. dcb->cfg = kzalloc(sizeof(struct qlcnic_dcb_cfg), GFP_ATOMIC);
  268. if (!dcb->cfg) {
  269. err = -ENOMEM;
  270. goto out_free_wq;
  271. }
  272. dcb->param = kzalloc(sizeof(struct qlcnic_dcb_mbx_params), GFP_ATOMIC);
  273. if (!dcb->param) {
  274. err = -ENOMEM;
  275. goto out_free_cfg;
  276. }
  277. qlcnic_dcb_get_info(adapter);
  278. return 0;
  279. out_free_cfg:
  280. kfree(dcb->cfg);
  281. dcb->cfg = NULL;
  282. out_free_wq:
  283. destroy_workqueue(dcb->wq);
  284. dcb->wq = NULL;
  285. return err;
  286. }
  287. static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter *adapter,
  288. char *buf)
  289. {
  290. struct qlcnic_cmd_args cmd;
  291. u32 mbx_out;
  292. int err;
  293. err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DCB_QUERY_CAP);
  294. if (err)
  295. return err;
  296. err = qlcnic_issue_cmd(adapter, &cmd);
  297. if (err) {
  298. dev_err(&adapter->pdev->dev,
  299. "Failed to query DCBX capability, err %d\n", err);
  300. } else {
  301. mbx_out = cmd.rsp.arg[1];
  302. if (buf)
  303. memcpy(buf, &mbx_out, sizeof(u32));
  304. }
  305. qlcnic_free_mbx_args(&cmd);
  306. return err;
  307. }
  308. static int __qlcnic_dcb_get_capability(struct qlcnic_adapter *adapter, u32 *val)
  309. {
  310. struct qlcnic_dcb_capability *cap = &adapter->dcb->cfg->capability;
  311. u32 mbx_out;
  312. int err;
  313. memset(cap, 0, sizeof(struct qlcnic_dcb_capability));
  314. err = qlcnic_dcb_query_hw_capability(adapter, (char *)val);
  315. if (err)
  316. return err;
  317. mbx_out = *val;
  318. if (QLC_DCB_TSA_SUPPORT(mbx_out))
  319. cap->tsa_capability = true;
  320. if (QLC_DCB_ETS_SUPPORT(mbx_out))
  321. cap->ets_capability = true;
  322. cap->max_num_tc = QLC_DCB_MAX_NUM_TC(mbx_out);
  323. cap->max_ets_tc = QLC_DCB_MAX_NUM_ETS_TC(mbx_out);
  324. cap->max_pfc_tc = QLC_DCB_MAX_NUM_PFC_TC(mbx_out);
  325. if (cap->max_num_tc > QLC_DCB_MAX_TC ||
  326. cap->max_ets_tc > cap->max_num_tc ||
  327. cap->max_pfc_tc > cap->max_num_tc) {
  328. dev_err(&adapter->pdev->dev, "Invalid DCB configuration\n");
  329. return -EINVAL;
  330. }
  331. return err;
  332. }
  333. static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
  334. {
  335. struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
  336. struct qlcnic_dcb_capability *cap;
  337. u32 mbx_out;
  338. int err;
  339. err = __qlcnic_dcb_get_capability(adapter, &mbx_out);
  340. if (err)
  341. return err;
  342. cap = &cfg->capability;
  343. cap->dcb_capability = DCB_CAP_DCBX_VER_CEE | DCB_CAP_DCBX_LLD_MANAGED;
  344. if (cap->dcb_capability && cap->tsa_capability && cap->ets_capability)
  345. set_bit(__QLCNIC_DCB_STATE, &adapter->state);
  346. return err;
  347. }
  348. static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_adapter *adapter,
  349. char *buf, u8 type)
  350. {
  351. u16 size = sizeof(struct qlcnic_82xx_dcb_param_mbx_le);
  352. struct qlcnic_82xx_dcb_param_mbx_le *prsp_le;
  353. struct device *dev = &adapter->pdev->dev;
  354. dma_addr_t cardrsp_phys_addr;
  355. struct qlcnic_dcb_param rsp;
  356. struct qlcnic_cmd_args cmd;
  357. u64 phys_addr;
  358. void *addr;
  359. int err, i;
  360. switch (type) {
  361. case QLC_DCB_LOCAL_PARAM_FWID:
  362. case QLC_DCB_OPER_PARAM_FWID:
  363. case QLC_DCB_PEER_PARAM_FWID:
  364. break;
  365. default:
  366. dev_err(dev, "Invalid parameter type %d\n", type);
  367. return -EINVAL;
  368. }
  369. addr = dma_alloc_coherent(&adapter->pdev->dev, size, &cardrsp_phys_addr,
  370. GFP_KERNEL);
  371. if (addr == NULL)
  372. return -ENOMEM;
  373. prsp_le = addr;
  374. err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DCB_QUERY_PARAM);
  375. if (err)
  376. goto out_free_rsp;
  377. phys_addr = cardrsp_phys_addr;
  378. cmd.req.arg[1] = size | (type << 16);
  379. cmd.req.arg[2] = MSD(phys_addr);
  380. cmd.req.arg[3] = LSD(phys_addr);
  381. err = qlcnic_issue_cmd(adapter, &cmd);
  382. if (err) {
  383. dev_err(dev, "Failed to query DCBX parameter, err %d\n", err);
  384. goto out;
  385. }
  386. memset(&rsp, 0, sizeof(struct qlcnic_dcb_param));
  387. rsp.hdr_prio_pfc_map[0] = le32_to_cpu(prsp_le->hdr_prio_pfc_map[0]);
  388. rsp.hdr_prio_pfc_map[1] = le32_to_cpu(prsp_le->hdr_prio_pfc_map[1]);
  389. rsp.prio_pg_map[0] = le32_to_cpu(prsp_le->prio_pg_map[0]);
  390. rsp.prio_pg_map[1] = le32_to_cpu(prsp_le->prio_pg_map[1]);
  391. rsp.pg_bw_map[0] = le32_to_cpu(prsp_le->pg_bw_map[0]);
  392. rsp.pg_bw_map[1] = le32_to_cpu(prsp_le->pg_bw_map[1]);
  393. rsp.pg_tsa_map[0] = le32_to_cpu(prsp_le->pg_tsa_map[0]);
  394. rsp.pg_tsa_map[1] = le32_to_cpu(prsp_le->pg_tsa_map[1]);
  395. for (i = 0; i < QLC_DCB_MAX_APP; i++)
  396. rsp.app[i] = le32_to_cpu(prsp_le->app[i]);
  397. if (buf)
  398. memcpy(buf, &rsp, size);
  399. out:
  400. qlcnic_free_mbx_args(&cmd);
  401. out_free_rsp:
  402. dma_free_coherent(&adapter->pdev->dev, size, addr, cardrsp_phys_addr);
  403. return err;
  404. }
  405. static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_adapter *adapter)
  406. {
  407. struct qlcnic_dcb_mbx_params *mbx;
  408. int err;
  409. mbx = adapter->dcb->param;
  410. if (!mbx)
  411. return 0;
  412. err = qlcnic_dcb_query_cee_param(adapter, (char *)&mbx->type[0],
  413. QLC_DCB_LOCAL_PARAM_FWID);
  414. if (err)
  415. return err;
  416. err = qlcnic_dcb_query_cee_param(adapter, (char *)&mbx->type[1],
  417. QLC_DCB_OPER_PARAM_FWID);
  418. if (err)
  419. return err;
  420. err = qlcnic_dcb_query_cee_param(adapter, (char *)&mbx->type[2],
  421. QLC_DCB_PEER_PARAM_FWID);
  422. if (err)
  423. return err;
  424. mbx->prio_tc_map = QLC_82XX_DCB_PRIO_TC_MAP;
  425. qlcnic_dcb_data_cee_param_map(adapter);
  426. return err;
  427. }
  428. static void qlcnic_dcb_aen_work(struct work_struct *work)
  429. {
  430. struct qlcnic_adapter *adapter;
  431. struct qlcnic_dcb *dcb;
  432. dcb = container_of(work, struct qlcnic_dcb, aen_work.work);
  433. adapter = dcb->adapter;
  434. qlcnic_dcb_get_cee_cfg(adapter);
  435. clear_bit(__QLCNIC_DCB_IN_AEN, &adapter->state);
  436. }
  437. static void qlcnic_82xx_dcb_handle_aen(struct qlcnic_adapter *adapter,
  438. void *data)
  439. {
  440. struct qlcnic_dcb *dcb = adapter->dcb;
  441. if (test_and_set_bit(__QLCNIC_DCB_IN_AEN, &adapter->state))
  442. return;
  443. queue_delayed_work(dcb->wq, &dcb->aen_work, 0);
  444. }
  445. static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter *adapter)
  446. {
  447. struct qlcnic_dcb_capability *cap = &adapter->dcb->cfg->capability;
  448. u32 mbx_out;
  449. int err;
  450. err = __qlcnic_dcb_get_capability(adapter, &mbx_out);
  451. if (err)
  452. return err;
  453. if (mbx_out & BIT_2)
  454. cap->dcb_capability = DCB_CAP_DCBX_VER_CEE;
  455. if (mbx_out & BIT_3)
  456. cap->dcb_capability |= DCB_CAP_DCBX_VER_IEEE;
  457. if (cap->dcb_capability)
  458. cap->dcb_capability |= DCB_CAP_DCBX_LLD_MANAGED;
  459. if (cap->dcb_capability && cap->tsa_capability && cap->ets_capability)
  460. set_bit(__QLCNIC_DCB_STATE, &adapter->state);
  461. return err;
  462. }
  463. static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_adapter *adapter,
  464. char *buf, u8 idx)
  465. {
  466. struct qlcnic_dcb_mbx_params mbx_out;
  467. int err, i, j, k, max_app, size;
  468. struct qlcnic_dcb_param *each;
  469. struct qlcnic_cmd_args cmd;
  470. u32 val;
  471. char *p;
  472. size = 0;
  473. memset(&mbx_out, 0, sizeof(struct qlcnic_dcb_mbx_params));
  474. memset(buf, 0, sizeof(struct qlcnic_dcb_mbx_params));
  475. err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DCB_QUERY_PARAM);
  476. if (err)
  477. return err;
  478. cmd.req.arg[0] |= QLC_DCB_FW_VER << 29;
  479. err = qlcnic_issue_cmd(adapter, &cmd);
  480. if (err) {
  481. dev_err(&adapter->pdev->dev,
  482. "Failed to query DCBX param, err %d\n", err);
  483. goto out;
  484. }
  485. mbx_out.prio_tc_map = cmd.rsp.arg[1];
  486. p = memcpy(buf, &mbx_out, sizeof(u32));
  487. k = 2;
  488. p += sizeof(u32);
  489. for (j = 0; j < QLC_DCB_NUM_PARAM; j++) {
  490. each = &mbx_out.type[j];
  491. each->hdr_prio_pfc_map[0] = cmd.rsp.arg[k++];
  492. each->hdr_prio_pfc_map[1] = cmd.rsp.arg[k++];
  493. each->prio_pg_map[0] = cmd.rsp.arg[k++];
  494. each->prio_pg_map[1] = cmd.rsp.arg[k++];
  495. each->pg_bw_map[0] = cmd.rsp.arg[k++];
  496. each->pg_bw_map[1] = cmd.rsp.arg[k++];
  497. each->pg_tsa_map[0] = cmd.rsp.arg[k++];
  498. each->pg_tsa_map[1] = cmd.rsp.arg[k++];
  499. val = each->hdr_prio_pfc_map[0];
  500. max_app = qlcnic_dcb_get_num_app(adapter, val);
  501. for (i = 0; i < max_app; i++)
  502. each->app[i] = cmd.rsp.arg[i + k];
  503. size = 16 * sizeof(u32);
  504. memcpy(p, &each->hdr_prio_pfc_map[0], size);
  505. p += size;
  506. if (j == 0)
  507. k = 18;
  508. else
  509. k = 34;
  510. }
  511. out:
  512. qlcnic_free_mbx_args(&cmd);
  513. return err;
  514. }
  515. static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_adapter *adapter)
  516. {
  517. struct qlcnic_dcb *dcb = adapter->dcb;
  518. int err;
  519. err = qlcnic_dcb_query_cee_param(adapter, (char *)dcb->param, 0);
  520. if (err)
  521. return err;
  522. qlcnic_dcb_data_cee_param_map(adapter);
  523. return err;
  524. }
  525. static int qlcnic_83xx_dcb_register_aen(struct qlcnic_adapter *adapter,
  526. bool flag)
  527. {
  528. u8 val = (flag ? QLCNIC_CMD_INIT_NIC_FUNC : QLCNIC_CMD_STOP_NIC_FUNC);
  529. struct qlcnic_cmd_args cmd;
  530. int err;
  531. err = qlcnic_alloc_mbx_args(&cmd, adapter, val);
  532. if (err)
  533. return err;
  534. cmd.req.arg[1] = QLC_DCB_AEN_BIT;
  535. err = qlcnic_issue_cmd(adapter, &cmd);
  536. if (err)
  537. dev_err(&adapter->pdev->dev, "Failed to %s DCBX AEN, err %d\n",
  538. (flag ? "register" : "unregister"), err);
  539. qlcnic_free_mbx_args(&cmd);
  540. return err;
  541. }
  542. static void qlcnic_83xx_dcb_handle_aen(struct qlcnic_adapter *adapter,
  543. void *data)
  544. {
  545. struct qlcnic_dcb *dcb = adapter->dcb;
  546. u32 *val = data;
  547. if (test_and_set_bit(__QLCNIC_DCB_IN_AEN, &adapter->state))
  548. return;
  549. if (*val & BIT_8)
  550. set_bit(__QLCNIC_DCB_STATE, &adapter->state);
  551. else
  552. clear_bit(__QLCNIC_DCB_STATE, &adapter->state);
  553. queue_delayed_work(dcb->wq, &dcb->aen_work, 0);
  554. }
  555. static void qlcnic_dcb_fill_cee_tc_params(struct qlcnic_dcb_mbx_params *mbx,
  556. struct qlcnic_dcb_param *each,
  557. struct qlcnic_dcb_cee *type)
  558. {
  559. struct qlcnic_dcb_tc_cfg *tc_cfg;
  560. u8 i, tc, pgid;
  561. for (i = 0; i < QLC_DCB_MAX_PRIO; i++) {
  562. tc = QLC_DCB_GET_TC_PRIO(mbx->prio_tc_map, i);
  563. tc_cfg = &type->tc_cfg[tc];
  564. tc_cfg->valid = true;
  565. tc_cfg->up_tc_map |= QLC_DCB_GET_MAP(i);
  566. if (QLC_DCB_GET_PFC_PRIO(each->hdr_prio_pfc_map[1], i) &&
  567. type->pfc_mode_enable) {
  568. tc_cfg->prio_cfg[i].valid = true;
  569. tc_cfg->prio_cfg[i].pfc_type = QLC_PFC_FULL;
  570. }
  571. if (i < 4)
  572. pgid = QLC_DCB_GET_PGID_PRIO(each->prio_pg_map[0], i);
  573. else
  574. pgid = QLC_DCB_GET_PGID_PRIO(each->prio_pg_map[1], i);
  575. tc_cfg->pgid = pgid;
  576. tc_cfg->prio_type = QLC_PRIO_LINK;
  577. type->pg_cfg[tc_cfg->pgid].prio_count++;
  578. }
  579. }
  580. static void qlcnic_dcb_fill_cee_pg_params(struct qlcnic_dcb_param *each,
  581. struct qlcnic_dcb_cee *type)
  582. {
  583. struct qlcnic_dcb_pg_cfg *pg_cfg;
  584. u8 i, tsa, bw_per;
  585. for (i = 0; i < QLC_DCB_MAX_PG; i++) {
  586. pg_cfg = &type->pg_cfg[i];
  587. pg_cfg->valid = true;
  588. if (i < 4) {
  589. bw_per = QLC_DCB_GET_BWPER_PG(each->pg_bw_map[0], i);
  590. tsa = QLC_DCB_GET_TSA_PG(each->pg_tsa_map[0], i);
  591. } else {
  592. bw_per = QLC_DCB_GET_BWPER_PG(each->pg_bw_map[1], i);
  593. tsa = QLC_DCB_GET_TSA_PG(each->pg_tsa_map[1], i);
  594. }
  595. pg_cfg->total_bw_percent = bw_per;
  596. pg_cfg->tsa_type = tsa;
  597. }
  598. }
  599. static void
  600. qlcnic_dcb_fill_cee_app_params(struct qlcnic_adapter *adapter, u8 idx,
  601. struct qlcnic_dcb_param *each,
  602. struct qlcnic_dcb_cee *type)
  603. {
  604. struct qlcnic_dcb_app *app;
  605. u8 i, num_app, map, cnt;
  606. struct dcb_app new_app;
  607. num_app = qlcnic_dcb_get_num_app(adapter, each->hdr_prio_pfc_map[0]);
  608. for (i = 0; i < num_app; i++) {
  609. app = &type->app[i];
  610. app->valid = true;
  611. /* Only for CEE (-1) */
  612. app->selector = QLC_DCB_GET_SELECTOR_APP(each->app[i]) - 1;
  613. new_app.selector = app->selector;
  614. app->protocol = QLC_DCB_GET_PROTO_ID_APP(each->app[i]);
  615. new_app.protocol = app->protocol;
  616. map = qlcnic_dcb_get_prio_map_app(adapter, each->app[i]);
  617. cnt = qlcnic_dcb_prio_count(map);
  618. if (cnt >= QLC_DCB_MAX_TC)
  619. cnt = 0;
  620. app->priority = cnt;
  621. new_app.priority = cnt;
  622. if (idx == QLC_DCB_OPER_IDX && adapter->netdev->dcbnl_ops)
  623. dcb_setapp(adapter->netdev, &new_app);
  624. }
  625. }
  626. static void qlcnic_dcb_map_cee_params(struct qlcnic_adapter *adapter, u8 idx)
  627. {
  628. struct qlcnic_dcb_mbx_params *mbx = adapter->dcb->param;
  629. struct qlcnic_dcb_param *each = &mbx->type[idx];
  630. struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
  631. struct qlcnic_dcb_cee *type = &cfg->type[idx];
  632. type->tc_param_valid = false;
  633. type->pfc_mode_enable = false;
  634. memset(type->tc_cfg, 0,
  635. sizeof(struct qlcnic_dcb_tc_cfg) * QLC_DCB_MAX_TC);
  636. memset(type->pg_cfg, 0,
  637. sizeof(struct qlcnic_dcb_pg_cfg) * QLC_DCB_MAX_TC);
  638. if (qlcnic_dcb_pfc_hdr_valid(adapter, each->hdr_prio_pfc_map[0]) &&
  639. cfg->capability.max_pfc_tc)
  640. type->pfc_mode_enable = true;
  641. if (qlcnic_dcb_tsa_hdr_valid(adapter, each->hdr_prio_pfc_map[0]) &&
  642. cfg->capability.max_ets_tc)
  643. type->tc_param_valid = true;
  644. qlcnic_dcb_fill_cee_tc_params(mbx, each, type);
  645. qlcnic_dcb_fill_cee_pg_params(each, type);
  646. qlcnic_dcb_fill_cee_app_params(adapter, idx, each, type);
  647. }
  648. static void qlcnic_dcb_data_cee_param_map(struct qlcnic_adapter *adapter)
  649. {
  650. int i;
  651. for (i = 0; i < QLC_DCB_NUM_PARAM; i++)
  652. qlcnic_dcb_map_cee_params(adapter, i);
  653. dcbnl_cee_notify(adapter->netdev, RTM_GETDCB, DCB_CMD_CEE_GET, 0, 0);
  654. }
  655. static u8 qlcnic_dcb_get_state(struct net_device *netdev)
  656. {
  657. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  658. return test_bit(__QLCNIC_DCB_STATE, &adapter->state);
  659. }
  660. static void qlcnic_dcb_get_perm_hw_addr(struct net_device *netdev, u8 *addr)
  661. {
  662. memcpy(addr, netdev->dev_addr, netdev->addr_len);
  663. }
  664. static void
  665. qlcnic_dcb_get_pg_tc_cfg_tx(struct net_device *netdev, int tc, u8 *prio,
  666. u8 *pgid, u8 *bw_per, u8 *up_tc_map)
  667. {
  668. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  669. struct qlcnic_dcb_tc_cfg *tc_cfg, *temp;
  670. struct qlcnic_dcb_cee *type;
  671. u8 i, cnt, pg;
  672. type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
  673. *prio = *pgid = *bw_per = *up_tc_map = 0;
  674. if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state) ||
  675. !type->tc_param_valid)
  676. return;
  677. if (tc < 0 || (tc > QLC_DCB_MAX_TC))
  678. return;
  679. tc_cfg = &type->tc_cfg[tc];
  680. if (!tc_cfg->valid)
  681. return;
  682. *pgid = tc_cfg->pgid;
  683. *prio = tc_cfg->prio_type;
  684. *up_tc_map = tc_cfg->up_tc_map;
  685. pg = *pgid;
  686. for (i = 0, cnt = 0; i < QLC_DCB_MAX_TC; i++) {
  687. temp = &type->tc_cfg[i];
  688. if (temp->valid && (pg == temp->pgid))
  689. cnt++;
  690. }
  691. tc_cfg->bwg_percent = (100 / cnt);
  692. *bw_per = tc_cfg->bwg_percent;
  693. }
  694. static void qlcnic_dcb_get_pg_bwg_cfg_tx(struct net_device *netdev, int pgid,
  695. u8 *bw_pct)
  696. {
  697. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  698. struct qlcnic_dcb_pg_cfg *pgcfg;
  699. struct qlcnic_dcb_cee *type;
  700. *bw_pct = 0;
  701. type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
  702. if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state) ||
  703. !type->tc_param_valid)
  704. return;
  705. if (pgid < 0 || pgid > QLC_DCB_MAX_PG)
  706. return;
  707. pgcfg = &type->pg_cfg[pgid];
  708. if (!pgcfg->valid)
  709. return;
  710. *bw_pct = pgcfg->total_bw_percent;
  711. }
  712. static void qlcnic_dcb_get_pfc_cfg(struct net_device *netdev, int prio,
  713. u8 *setting)
  714. {
  715. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  716. struct qlcnic_dcb_tc_cfg *tc_cfg;
  717. u8 val = QLC_DCB_GET_MAP(prio);
  718. struct qlcnic_dcb_cee *type;
  719. u8 i;
  720. *setting = 0;
  721. type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
  722. if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state) ||
  723. !type->pfc_mode_enable)
  724. return;
  725. for (i = 0; i < QLC_DCB_MAX_TC; i++) {
  726. tc_cfg = &type->tc_cfg[i];
  727. if (!tc_cfg->valid)
  728. continue;
  729. if ((val & tc_cfg->up_tc_map) && (tc_cfg->prio_cfg[prio].valid))
  730. *setting = tc_cfg->prio_cfg[prio].pfc_type;
  731. }
  732. }
  733. static u8 qlcnic_dcb_get_capability(struct net_device *netdev, int capid,
  734. u8 *cap)
  735. {
  736. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  737. if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
  738. return 0;
  739. switch (capid) {
  740. case DCB_CAP_ATTR_PG:
  741. case DCB_CAP_ATTR_UP2TC:
  742. case DCB_CAP_ATTR_PFC:
  743. case DCB_CAP_ATTR_GSP:
  744. *cap = true;
  745. break;
  746. case DCB_CAP_ATTR_PG_TCS:
  747. case DCB_CAP_ATTR_PFC_TCS:
  748. *cap = 0x80; /* 8 priorities for PGs */
  749. break;
  750. case DCB_CAP_ATTR_DCBX:
  751. *cap = adapter->dcb->cfg->capability.dcb_capability;
  752. break;
  753. default:
  754. *cap = false;
  755. }
  756. return 0;
  757. }
  758. static int qlcnic_dcb_get_num_tcs(struct net_device *netdev, int attr, u8 *num)
  759. {
  760. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  761. struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
  762. if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
  763. return -EINVAL;
  764. switch (attr) {
  765. case DCB_NUMTCS_ATTR_PG:
  766. *num = cfg->capability.max_ets_tc;
  767. return 0;
  768. case DCB_NUMTCS_ATTR_PFC:
  769. *num = cfg->capability.max_pfc_tc;
  770. return 0;
  771. default:
  772. return -EINVAL;
  773. }
  774. }
  775. static u8 qlcnic_dcb_get_app(struct net_device *netdev, u8 idtype, u16 id)
  776. {
  777. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  778. struct dcb_app app = {
  779. .selector = idtype,
  780. .protocol = id,
  781. };
  782. if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
  783. return 0;
  784. return dcb_getapp(netdev, &app);
  785. }
  786. static u8 qlcnic_dcb_get_pfc_state(struct net_device *netdev)
  787. {
  788. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  789. struct qlcnic_dcb *dcb = adapter->dcb;
  790. if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
  791. return 0;
  792. return dcb->cfg->type[QLC_DCB_OPER_IDX].pfc_mode_enable;
  793. }
  794. static u8 qlcnic_dcb_get_dcbx(struct net_device *netdev)
  795. {
  796. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  797. struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
  798. if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
  799. return 0;
  800. return cfg->capability.dcb_capability;
  801. }
  802. static u8 qlcnic_dcb_get_feat_cfg(struct net_device *netdev, int fid, u8 *flag)
  803. {
  804. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  805. struct qlcnic_dcb_cee *type;
  806. if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
  807. return 1;
  808. type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
  809. *flag = 0;
  810. switch (fid) {
  811. case DCB_FEATCFG_ATTR_PG:
  812. if (type->tc_param_valid)
  813. *flag |= DCB_FEATCFG_ENABLE;
  814. else
  815. *flag |= DCB_FEATCFG_ERROR;
  816. break;
  817. case DCB_FEATCFG_ATTR_PFC:
  818. if (type->pfc_mode_enable) {
  819. if (type->tc_cfg[0].prio_cfg[0].pfc_type)
  820. *flag |= DCB_FEATCFG_ENABLE;
  821. } else {
  822. *flag |= DCB_FEATCFG_ERROR;
  823. }
  824. break;
  825. case DCB_FEATCFG_ATTR_APP:
  826. *flag |= DCB_FEATCFG_ENABLE;
  827. break;
  828. default:
  829. netdev_err(netdev, "Invalid Feature ID %d\n", fid);
  830. return 1;
  831. }
  832. return 0;
  833. }
  834. static inline void
  835. qlcnic_dcb_get_pg_tc_cfg_rx(struct net_device *netdev, int prio, u8 *prio_type,
  836. u8 *pgid, u8 *bw_pct, u8 *up_map)
  837. {
  838. *prio_type = *pgid = *bw_pct = *up_map = 0;
  839. }
  840. static inline void
  841. qlcnic_dcb_get_pg_bwg_cfg_rx(struct net_device *netdev, int pgid, u8 *bw_pct)
  842. {
  843. *bw_pct = 0;
  844. }
  845. static int qlcnic_dcb_peer_app_info(struct net_device *netdev,
  846. struct dcb_peer_app_info *info,
  847. u16 *app_count)
  848. {
  849. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  850. struct qlcnic_dcb_cee *peer;
  851. int i;
  852. *app_count = 0;
  853. if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
  854. return 0;
  855. peer = &adapter->dcb->cfg->type[QLC_DCB_PEER_IDX];
  856. for (i = 0; i < QLC_DCB_MAX_APP; i++) {
  857. if (peer->app[i].valid)
  858. (*app_count)++;
  859. }
  860. return 0;
  861. }
  862. static int qlcnic_dcb_peer_app_table(struct net_device *netdev,
  863. struct dcb_app *table)
  864. {
  865. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  866. struct qlcnic_dcb_cee *peer;
  867. struct qlcnic_dcb_app *app;
  868. int i, j;
  869. if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
  870. return 0;
  871. peer = &adapter->dcb->cfg->type[QLC_DCB_PEER_IDX];
  872. for (i = 0, j = 0; i < QLC_DCB_MAX_APP; i++) {
  873. app = &peer->app[i];
  874. if (!app->valid)
  875. continue;
  876. table[j].selector = app->selector;
  877. table[j].priority = app->priority;
  878. table[j++].protocol = app->protocol;
  879. }
  880. return 0;
  881. }
  882. static int qlcnic_dcb_cee_peer_get_pg(struct net_device *netdev,
  883. struct cee_pg *pg)
  884. {
  885. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  886. struct qlcnic_dcb_cee *peer;
  887. u8 i, j, k, map;
  888. if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
  889. return 0;
  890. peer = &adapter->dcb->cfg->type[QLC_DCB_PEER_IDX];
  891. for (i = 0, j = 0; i < QLC_DCB_MAX_PG; i++) {
  892. if (!peer->pg_cfg[i].valid)
  893. continue;
  894. pg->pg_bw[j] = peer->pg_cfg[i].total_bw_percent;
  895. for (k = 0; k < QLC_DCB_MAX_TC; k++) {
  896. if (peer->tc_cfg[i].valid &&
  897. (peer->tc_cfg[i].pgid == i)) {
  898. map = peer->tc_cfg[i].up_tc_map;
  899. pg->prio_pg[j++] = map;
  900. break;
  901. }
  902. }
  903. }
  904. return 0;
  905. }
  906. static int qlcnic_dcb_cee_peer_get_pfc(struct net_device *netdev,
  907. struct cee_pfc *pfc)
  908. {
  909. struct qlcnic_adapter *adapter = netdev_priv(netdev);
  910. struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
  911. struct qlcnic_dcb_tc_cfg *tc;
  912. struct qlcnic_dcb_cee *peer;
  913. u8 i, setting, prio;
  914. pfc->pfc_en = 0;
  915. if (!test_bit(__QLCNIC_DCB_STATE, &adapter->state))
  916. return 0;
  917. peer = &cfg->type[QLC_DCB_PEER_IDX];
  918. for (i = 0; i < QLC_DCB_MAX_TC; i++) {
  919. tc = &peer->tc_cfg[i];
  920. prio = qlcnic_dcb_prio_count(tc->up_tc_map);
  921. setting = 0;
  922. qlcnic_dcb_get_pfc_cfg(netdev, prio, &setting);
  923. if (setting)
  924. pfc->pfc_en |= QLC_DCB_GET_MAP(i);
  925. }
  926. pfc->tcs_supported = cfg->capability.max_pfc_tc;
  927. return 0;
  928. }
  929. static const struct dcbnl_rtnl_ops qlcnic_dcbnl_ops = {
  930. .getstate = qlcnic_dcb_get_state,
  931. .getpermhwaddr = qlcnic_dcb_get_perm_hw_addr,
  932. .getpgtccfgtx = qlcnic_dcb_get_pg_tc_cfg_tx,
  933. .getpgbwgcfgtx = qlcnic_dcb_get_pg_bwg_cfg_tx,
  934. .getpfccfg = qlcnic_dcb_get_pfc_cfg,
  935. .getcap = qlcnic_dcb_get_capability,
  936. .getnumtcs = qlcnic_dcb_get_num_tcs,
  937. .getapp = qlcnic_dcb_get_app,
  938. .getpfcstate = qlcnic_dcb_get_pfc_state,
  939. .getdcbx = qlcnic_dcb_get_dcbx,
  940. .getfeatcfg = qlcnic_dcb_get_feat_cfg,
  941. .getpgtccfgrx = qlcnic_dcb_get_pg_tc_cfg_rx,
  942. .getpgbwgcfgrx = qlcnic_dcb_get_pg_bwg_cfg_rx,
  943. .peer_getappinfo = qlcnic_dcb_peer_app_info,
  944. .peer_getapptable = qlcnic_dcb_peer_app_table,
  945. .cee_peer_getpg = qlcnic_dcb_cee_peer_get_pg,
  946. .cee_peer_getpfc = qlcnic_dcb_cee_peer_get_pfc,
  947. };