qlcnic_dcb.c 28 KB

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