cxgb4_dcb.c 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267
  1. /*
  2. * Copyright (C) 2013-2014 Chelsio Communications. All rights reserved.
  3. *
  4. * Written by Anish Bhatt (anish@chelsio.com)
  5. * Casey Leedom (leedom@chelsio.com)
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms and conditions of the GNU General Public License,
  9. * version 2, as published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope it will be useful, but WITHOUT
  12. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  14. * more details.
  15. *
  16. * The full GNU General Public License is included in this distribution in
  17. * the file called "COPYING".
  18. *
  19. */
  20. #include "cxgb4.h"
  21. /* DCBx version control
  22. */
  23. const char * const dcb_ver_array[] = {
  24. "Unknown",
  25. "DCBx-CIN",
  26. "DCBx-CEE 1.01",
  27. "DCBx-IEEE",
  28. "", "", "",
  29. "Auto Negotiated"
  30. };
  31. static inline bool cxgb4_dcb_state_synced(enum cxgb4_dcb_state state)
  32. {
  33. if (state == CXGB4_DCB_STATE_FW_ALLSYNCED ||
  34. state == CXGB4_DCB_STATE_HOST)
  35. return true;
  36. else
  37. return false;
  38. }
  39. /* Initialize a port's Data Center Bridging state.
  40. */
  41. void cxgb4_dcb_state_init(struct net_device *dev)
  42. {
  43. struct port_info *pi = netdev2pinfo(dev);
  44. struct port_dcb_info *dcb = &pi->dcb;
  45. int version_temp = dcb->dcb_version;
  46. memset(dcb, 0, sizeof(struct port_dcb_info));
  47. dcb->state = CXGB4_DCB_STATE_START;
  48. if (version_temp)
  49. dcb->dcb_version = version_temp;
  50. netdev_dbg(dev, "%s: Initializing DCB state for port[%d]\n",
  51. __func__, pi->port_id);
  52. }
  53. void cxgb4_dcb_version_init(struct net_device *dev)
  54. {
  55. struct port_info *pi = netdev2pinfo(dev);
  56. struct port_dcb_info *dcb = &pi->dcb;
  57. /* Any writes here are only done on kernels that exlicitly need
  58. * a specific version, say < 2.6.38 which only support CEE
  59. */
  60. dcb->dcb_version = FW_PORT_DCB_VER_AUTO;
  61. }
  62. static void cxgb4_dcb_cleanup_apps(struct net_device *dev)
  63. {
  64. struct port_info *pi = netdev2pinfo(dev);
  65. struct adapter *adap = pi->adapter;
  66. struct port_dcb_info *dcb = &pi->dcb;
  67. struct dcb_app app;
  68. int i, err;
  69. /* zero priority implies remove */
  70. app.priority = 0;
  71. for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
  72. /* Check if app list is exhausted */
  73. if (!dcb->app_priority[i].protocolid)
  74. break;
  75. app.protocol = dcb->app_priority[i].protocolid;
  76. if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) {
  77. app.priority = dcb->app_priority[i].user_prio_map;
  78. app.selector = dcb->app_priority[i].sel_field + 1;
  79. err = dcb_ieee_delapp(dev, &app);
  80. } else {
  81. app.selector = !!(dcb->app_priority[i].sel_field);
  82. err = dcb_setapp(dev, &app);
  83. }
  84. if (err) {
  85. dev_err(adap->pdev_dev,
  86. "Failed DCB Clear %s Application Priority: sel=%d, prot=%d, , err=%d\n",
  87. dcb_ver_array[dcb->dcb_version], app.selector,
  88. app.protocol, -err);
  89. break;
  90. }
  91. }
  92. }
  93. /* Reset a port's Data Center Bridging state. Typically used after a
  94. * Link Down event.
  95. */
  96. void cxgb4_dcb_reset(struct net_device *dev)
  97. {
  98. cxgb4_dcb_cleanup_apps(dev);
  99. cxgb4_dcb_state_init(dev);
  100. }
  101. /* Finite State machine for Data Center Bridging.
  102. */
  103. void cxgb4_dcb_state_fsm(struct net_device *dev,
  104. enum cxgb4_dcb_state_input transition_to)
  105. {
  106. struct port_info *pi = netdev2pinfo(dev);
  107. struct port_dcb_info *dcb = &pi->dcb;
  108. struct adapter *adap = pi->adapter;
  109. enum cxgb4_dcb_state current_state = dcb->state;
  110. netdev_dbg(dev, "%s: State change from %d to %d for %s\n",
  111. __func__, dcb->state, transition_to, dev->name);
  112. switch (current_state) {
  113. case CXGB4_DCB_STATE_START: {
  114. switch (transition_to) {
  115. case CXGB4_DCB_INPUT_FW_DISABLED: {
  116. /* we're going to use Host DCB */
  117. dcb->state = CXGB4_DCB_STATE_HOST;
  118. dcb->supported = CXGB4_DCBX_HOST_SUPPORT;
  119. break;
  120. }
  121. case CXGB4_DCB_INPUT_FW_ENABLED: {
  122. /* we're going to use Firmware DCB */
  123. dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE;
  124. dcb->supported = DCB_CAP_DCBX_LLD_MANAGED;
  125. if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE)
  126. dcb->supported |= DCB_CAP_DCBX_VER_IEEE;
  127. else
  128. dcb->supported |= DCB_CAP_DCBX_VER_CEE;
  129. break;
  130. }
  131. case CXGB4_DCB_INPUT_FW_INCOMPLETE: {
  132. /* expected transition */
  133. break;
  134. }
  135. case CXGB4_DCB_INPUT_FW_ALLSYNCED: {
  136. dcb->state = CXGB4_DCB_STATE_FW_ALLSYNCED;
  137. break;
  138. }
  139. default:
  140. goto bad_state_input;
  141. }
  142. break;
  143. }
  144. case CXGB4_DCB_STATE_FW_INCOMPLETE: {
  145. switch (transition_to) {
  146. case CXGB4_DCB_INPUT_FW_ENABLED: {
  147. /* we're alreaady in firmware DCB mode */
  148. break;
  149. }
  150. case CXGB4_DCB_INPUT_FW_INCOMPLETE: {
  151. /* we're already incomplete */
  152. break;
  153. }
  154. case CXGB4_DCB_INPUT_FW_ALLSYNCED: {
  155. dcb->state = CXGB4_DCB_STATE_FW_ALLSYNCED;
  156. dcb->enabled = 1;
  157. linkwatch_fire_event(dev);
  158. break;
  159. }
  160. default:
  161. goto bad_state_input;
  162. }
  163. break;
  164. }
  165. case CXGB4_DCB_STATE_FW_ALLSYNCED: {
  166. switch (transition_to) {
  167. case CXGB4_DCB_INPUT_FW_ENABLED: {
  168. /* we're alreaady in firmware DCB mode */
  169. break;
  170. }
  171. case CXGB4_DCB_INPUT_FW_INCOMPLETE: {
  172. /* We were successfully running with firmware DCB but
  173. * now it's telling us that it's in an "incomplete
  174. * state. We need to reset back to a ground state
  175. * of incomplete.
  176. */
  177. cxgb4_dcb_reset(dev);
  178. dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE;
  179. dcb->supported = CXGB4_DCBX_FW_SUPPORT;
  180. linkwatch_fire_event(dev);
  181. break;
  182. }
  183. case CXGB4_DCB_INPUT_FW_ALLSYNCED: {
  184. /* we're already all sync'ed
  185. * this is only applicable for IEEE or
  186. * when another VI already completed negotiaton
  187. */
  188. dcb->enabled = 1;
  189. linkwatch_fire_event(dev);
  190. break;
  191. }
  192. default:
  193. goto bad_state_input;
  194. }
  195. break;
  196. }
  197. case CXGB4_DCB_STATE_HOST: {
  198. switch (transition_to) {
  199. case CXGB4_DCB_INPUT_FW_DISABLED: {
  200. /* we're alreaady in Host DCB mode */
  201. break;
  202. }
  203. default:
  204. goto bad_state_input;
  205. }
  206. break;
  207. }
  208. default:
  209. goto bad_state_transition;
  210. }
  211. return;
  212. bad_state_input:
  213. dev_err(adap->pdev_dev, "cxgb4_dcb_state_fsm: illegal input symbol %d\n",
  214. transition_to);
  215. return;
  216. bad_state_transition:
  217. dev_err(adap->pdev_dev, "cxgb4_dcb_state_fsm: bad state transition, state = %d, input = %d\n",
  218. current_state, transition_to);
  219. }
  220. /* Handle a DCB/DCBX update message from the firmware.
  221. */
  222. void cxgb4_dcb_handle_fw_update(struct adapter *adap,
  223. const struct fw_port_cmd *pcmd)
  224. {
  225. const union fw_port_dcb *fwdcb = &pcmd->u.dcb;
  226. int port = FW_PORT_CMD_PORTID_G(be32_to_cpu(pcmd->op_to_portid));
  227. struct net_device *dev = adap->port[adap->chan_map[port]];
  228. struct port_info *pi = netdev_priv(dev);
  229. struct port_dcb_info *dcb = &pi->dcb;
  230. int dcb_type = pcmd->u.dcb.pgid.type;
  231. int dcb_running_version;
  232. /* Handle Firmware DCB Control messages separately since they drive
  233. * our state machine.
  234. */
  235. if (dcb_type == FW_PORT_DCB_TYPE_CONTROL) {
  236. enum cxgb4_dcb_state_input input =
  237. ((pcmd->u.dcb.control.all_syncd_pkd &
  238. FW_PORT_CMD_ALL_SYNCD_F)
  239. ? CXGB4_DCB_INPUT_FW_ALLSYNCED
  240. : CXGB4_DCB_INPUT_FW_INCOMPLETE);
  241. if (dcb->dcb_version != FW_PORT_DCB_VER_UNKNOWN) {
  242. dcb_running_version = FW_PORT_CMD_DCB_VERSION_G(
  243. be16_to_cpu(
  244. pcmd->u.dcb.control.dcb_version_to_app_state));
  245. if (dcb_running_version == FW_PORT_DCB_VER_CEE1D01 ||
  246. dcb_running_version == FW_PORT_DCB_VER_IEEE) {
  247. dcb->dcb_version = dcb_running_version;
  248. dev_warn(adap->pdev_dev, "Interface %s is running %s\n",
  249. dev->name,
  250. dcb_ver_array[dcb->dcb_version]);
  251. } else {
  252. dev_warn(adap->pdev_dev,
  253. "Something screwed up, requested firmware for %s, but firmware returned %s instead\n",
  254. dcb_ver_array[dcb->dcb_version],
  255. dcb_ver_array[dcb_running_version]);
  256. dcb->dcb_version = FW_PORT_DCB_VER_UNKNOWN;
  257. }
  258. }
  259. cxgb4_dcb_state_fsm(dev, input);
  260. return;
  261. }
  262. /* It's weird, and almost certainly an error, to get Firmware DCB
  263. * messages when we either haven't been told whether we're going to be
  264. * doing Host or Firmware DCB; and even worse when we've been told
  265. * that we're doing Host DCB!
  266. */
  267. if (dcb->state == CXGB4_DCB_STATE_START ||
  268. dcb->state == CXGB4_DCB_STATE_HOST) {
  269. dev_err(adap->pdev_dev, "Receiving Firmware DCB messages in State %d\n",
  270. dcb->state);
  271. return;
  272. }
  273. /* Now handle the general Firmware DCB update messages ...
  274. */
  275. switch (dcb_type) {
  276. case FW_PORT_DCB_TYPE_PGID:
  277. dcb->pgid = be32_to_cpu(fwdcb->pgid.pgid);
  278. dcb->msgs |= CXGB4_DCB_FW_PGID;
  279. break;
  280. case FW_PORT_DCB_TYPE_PGRATE:
  281. dcb->pg_num_tcs_supported = fwdcb->pgrate.num_tcs_supported;
  282. memcpy(dcb->pgrate, &fwdcb->pgrate.pgrate,
  283. sizeof(dcb->pgrate));
  284. memcpy(dcb->tsa, &fwdcb->pgrate.tsa,
  285. sizeof(dcb->tsa));
  286. dcb->msgs |= CXGB4_DCB_FW_PGRATE;
  287. if (dcb->msgs & CXGB4_DCB_FW_PGID)
  288. IEEE_FAUX_SYNC(dev, dcb);
  289. break;
  290. case FW_PORT_DCB_TYPE_PRIORATE:
  291. memcpy(dcb->priorate, &fwdcb->priorate.strict_priorate,
  292. sizeof(dcb->priorate));
  293. dcb->msgs |= CXGB4_DCB_FW_PRIORATE;
  294. break;
  295. case FW_PORT_DCB_TYPE_PFC:
  296. dcb->pfcen = fwdcb->pfc.pfcen;
  297. dcb->pfc_num_tcs_supported = fwdcb->pfc.max_pfc_tcs;
  298. dcb->msgs |= CXGB4_DCB_FW_PFC;
  299. IEEE_FAUX_SYNC(dev, dcb);
  300. break;
  301. case FW_PORT_DCB_TYPE_APP_ID: {
  302. const struct fw_port_app_priority *fwap = &fwdcb->app_priority;
  303. int idx = fwap->idx;
  304. struct app_priority *ap = &dcb->app_priority[idx];
  305. struct dcb_app app = {
  306. .protocol = be16_to_cpu(fwap->protocolid),
  307. };
  308. int err;
  309. /* Convert from firmware format to relevant format
  310. * when using app selector
  311. */
  312. if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) {
  313. app.selector = (fwap->sel_field + 1);
  314. app.priority = ffs(fwap->user_prio_map) - 1;
  315. err = dcb_ieee_setapp(dev, &app);
  316. IEEE_FAUX_SYNC(dev, dcb);
  317. } else {
  318. /* Default is CEE */
  319. app.selector = !!(fwap->sel_field);
  320. app.priority = fwap->user_prio_map;
  321. err = dcb_setapp(dev, &app);
  322. }
  323. if (err)
  324. dev_err(adap->pdev_dev,
  325. "Failed DCB Set Application Priority: sel=%d, prot=%d, prio=%d, err=%d\n",
  326. app.selector, app.protocol, app.priority, -err);
  327. ap->user_prio_map = fwap->user_prio_map;
  328. ap->sel_field = fwap->sel_field;
  329. ap->protocolid = be16_to_cpu(fwap->protocolid);
  330. dcb->msgs |= CXGB4_DCB_FW_APP_ID;
  331. break;
  332. }
  333. default:
  334. dev_err(adap->pdev_dev, "Unknown DCB update type received %x\n",
  335. dcb_type);
  336. break;
  337. }
  338. }
  339. /* Data Center Bridging netlink operations.
  340. */
  341. /* Get current DCB enabled/disabled state.
  342. */
  343. static u8 cxgb4_getstate(struct net_device *dev)
  344. {
  345. struct port_info *pi = netdev2pinfo(dev);
  346. return pi->dcb.enabled;
  347. }
  348. /* Set DCB enabled/disabled.
  349. */
  350. static u8 cxgb4_setstate(struct net_device *dev, u8 enabled)
  351. {
  352. struct port_info *pi = netdev2pinfo(dev);
  353. /* If DCBx is host-managed, dcb is enabled by outside lldp agents */
  354. if (pi->dcb.state == CXGB4_DCB_STATE_HOST) {
  355. pi->dcb.enabled = enabled;
  356. return 0;
  357. }
  358. /* Firmware doesn't provide any mechanism to control the DCB state.
  359. */
  360. if (enabled != (pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED))
  361. return 1;
  362. return 0;
  363. }
  364. static void cxgb4_getpgtccfg(struct net_device *dev, int tc,
  365. u8 *prio_type, u8 *pgid, u8 *bw_per,
  366. u8 *up_tc_map, int local)
  367. {
  368. struct fw_port_cmd pcmd;
  369. struct port_info *pi = netdev2pinfo(dev);
  370. struct adapter *adap = pi->adapter;
  371. int err;
  372. *prio_type = *pgid = *bw_per = *up_tc_map = 0;
  373. if (local)
  374. INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
  375. else
  376. INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
  377. pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
  378. err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
  379. if (err != FW_PORT_DCB_CFG_SUCCESS) {
  380. dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
  381. return;
  382. }
  383. *pgid = (be32_to_cpu(pcmd.u.dcb.pgid.pgid) >> (tc * 4)) & 0xf;
  384. if (local)
  385. INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
  386. else
  387. INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
  388. pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
  389. err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
  390. if (err != FW_PORT_DCB_CFG_SUCCESS) {
  391. dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
  392. -err);
  393. return;
  394. }
  395. *bw_per = pcmd.u.dcb.pgrate.pgrate[*pgid];
  396. *up_tc_map = (1 << tc);
  397. /* prio_type is link strict */
  398. if (*pgid != 0xF)
  399. *prio_type = 0x2;
  400. }
  401. static void cxgb4_getpgtccfg_tx(struct net_device *dev, int tc,
  402. u8 *prio_type, u8 *pgid, u8 *bw_per,
  403. u8 *up_tc_map)
  404. {
  405. /* tc 0 is written at MSB position */
  406. return cxgb4_getpgtccfg(dev, (7 - tc), prio_type, pgid, bw_per,
  407. up_tc_map, 1);
  408. }
  409. static void cxgb4_getpgtccfg_rx(struct net_device *dev, int tc,
  410. u8 *prio_type, u8 *pgid, u8 *bw_per,
  411. u8 *up_tc_map)
  412. {
  413. /* tc 0 is written at MSB position */
  414. return cxgb4_getpgtccfg(dev, (7 - tc), prio_type, pgid, bw_per,
  415. up_tc_map, 0);
  416. }
  417. static void cxgb4_setpgtccfg_tx(struct net_device *dev, int tc,
  418. u8 prio_type, u8 pgid, u8 bw_per,
  419. u8 up_tc_map)
  420. {
  421. struct fw_port_cmd pcmd;
  422. struct port_info *pi = netdev2pinfo(dev);
  423. struct adapter *adap = pi->adapter;
  424. int fw_tc = 7 - tc;
  425. u32 _pgid;
  426. int err;
  427. if (pgid == DCB_ATTR_VALUE_UNDEFINED)
  428. return;
  429. if (bw_per == DCB_ATTR_VALUE_UNDEFINED)
  430. return;
  431. INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
  432. pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
  433. err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
  434. if (err != FW_PORT_DCB_CFG_SUCCESS) {
  435. dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
  436. return;
  437. }
  438. _pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
  439. _pgid &= ~(0xF << (fw_tc * 4));
  440. _pgid |= pgid << (fw_tc * 4);
  441. pcmd.u.dcb.pgid.pgid = cpu_to_be32(_pgid);
  442. INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
  443. err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
  444. if (err != FW_PORT_DCB_CFG_SUCCESS) {
  445. dev_err(adap->pdev_dev, "DCB write PGID failed with %d\n",
  446. -err);
  447. return;
  448. }
  449. memset(&pcmd, 0, sizeof(struct fw_port_cmd));
  450. INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
  451. pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
  452. err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
  453. if (err != FW_PORT_DCB_CFG_SUCCESS) {
  454. dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
  455. -err);
  456. return;
  457. }
  458. pcmd.u.dcb.pgrate.pgrate[pgid] = bw_per;
  459. INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
  460. if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
  461. pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F);
  462. err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
  463. if (err != FW_PORT_DCB_CFG_SUCCESS)
  464. dev_err(adap->pdev_dev, "DCB write PGRATE failed with %d\n",
  465. -err);
  466. }
  467. static void cxgb4_getpgbwgcfg(struct net_device *dev, int pgid, u8 *bw_per,
  468. int local)
  469. {
  470. struct fw_port_cmd pcmd;
  471. struct port_info *pi = netdev2pinfo(dev);
  472. struct adapter *adap = pi->adapter;
  473. int err;
  474. if (local)
  475. INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
  476. else
  477. INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
  478. pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
  479. err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
  480. if (err != FW_PORT_DCB_CFG_SUCCESS) {
  481. dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
  482. -err);
  483. return;
  484. }
  485. *bw_per = pcmd.u.dcb.pgrate.pgrate[pgid];
  486. }
  487. static void cxgb4_getpgbwgcfg_tx(struct net_device *dev, int pgid, u8 *bw_per)
  488. {
  489. return cxgb4_getpgbwgcfg(dev, pgid, bw_per, 1);
  490. }
  491. static void cxgb4_getpgbwgcfg_rx(struct net_device *dev, int pgid, u8 *bw_per)
  492. {
  493. return cxgb4_getpgbwgcfg(dev, pgid, bw_per, 0);
  494. }
  495. static void cxgb4_setpgbwgcfg_tx(struct net_device *dev, int pgid,
  496. u8 bw_per)
  497. {
  498. struct fw_port_cmd pcmd;
  499. struct port_info *pi = netdev2pinfo(dev);
  500. struct adapter *adap = pi->adapter;
  501. int err;
  502. INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
  503. pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
  504. err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
  505. if (err != FW_PORT_DCB_CFG_SUCCESS) {
  506. dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
  507. -err);
  508. return;
  509. }
  510. pcmd.u.dcb.pgrate.pgrate[pgid] = bw_per;
  511. INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
  512. if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
  513. pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F);
  514. err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
  515. if (err != FW_PORT_DCB_CFG_SUCCESS)
  516. dev_err(adap->pdev_dev, "DCB write PGRATE failed with %d\n",
  517. -err);
  518. }
  519. /* Return whether the specified Traffic Class Priority has Priority Pause
  520. * Frames enabled.
  521. */
  522. static void cxgb4_getpfccfg(struct net_device *dev, int priority, u8 *pfccfg)
  523. {
  524. struct port_info *pi = netdev2pinfo(dev);
  525. struct port_dcb_info *dcb = &pi->dcb;
  526. if (!cxgb4_dcb_state_synced(dcb->state) ||
  527. priority >= CXGB4_MAX_PRIORITY)
  528. *pfccfg = 0;
  529. else
  530. *pfccfg = (pi->dcb.pfcen >> (7 - priority)) & 1;
  531. }
  532. /* Enable/disable Priority Pause Frames for the specified Traffic Class
  533. * Priority.
  534. */
  535. static void cxgb4_setpfccfg(struct net_device *dev, int priority, u8 pfccfg)
  536. {
  537. struct fw_port_cmd pcmd;
  538. struct port_info *pi = netdev2pinfo(dev);
  539. struct adapter *adap = pi->adapter;
  540. int err;
  541. if (!cxgb4_dcb_state_synced(pi->dcb.state) ||
  542. priority >= CXGB4_MAX_PRIORITY)
  543. return;
  544. INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
  545. if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
  546. pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F);
  547. pcmd.u.dcb.pfc.type = FW_PORT_DCB_TYPE_PFC;
  548. pcmd.u.dcb.pfc.pfcen = pi->dcb.pfcen;
  549. if (pfccfg)
  550. pcmd.u.dcb.pfc.pfcen |= (1 << (7 - priority));
  551. else
  552. pcmd.u.dcb.pfc.pfcen &= (~(1 << (7 - priority)));
  553. err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
  554. if (err != FW_PORT_DCB_CFG_SUCCESS) {
  555. dev_err(adap->pdev_dev, "DCB PFC write failed with %d\n", -err);
  556. return;
  557. }
  558. pi->dcb.pfcen = pcmd.u.dcb.pfc.pfcen;
  559. }
  560. static u8 cxgb4_setall(struct net_device *dev)
  561. {
  562. return 0;
  563. }
  564. /* Return DCB capabilities.
  565. */
  566. static u8 cxgb4_getcap(struct net_device *dev, int cap_id, u8 *caps)
  567. {
  568. struct port_info *pi = netdev2pinfo(dev);
  569. switch (cap_id) {
  570. case DCB_CAP_ATTR_PG:
  571. case DCB_CAP_ATTR_PFC:
  572. *caps = true;
  573. break;
  574. case DCB_CAP_ATTR_PG_TCS:
  575. /* 8 priorities for PG represented by bitmap */
  576. *caps = 0x80;
  577. break;
  578. case DCB_CAP_ATTR_PFC_TCS:
  579. /* 8 priorities for PFC represented by bitmap */
  580. *caps = 0x80;
  581. break;
  582. case DCB_CAP_ATTR_GSP:
  583. *caps = true;
  584. break;
  585. case DCB_CAP_ATTR_UP2TC:
  586. case DCB_CAP_ATTR_BCN:
  587. *caps = false;
  588. break;
  589. case DCB_CAP_ATTR_DCBX:
  590. *caps = pi->dcb.supported;
  591. break;
  592. default:
  593. *caps = false;
  594. }
  595. return 0;
  596. }
  597. /* Return the number of Traffic Classes for the indicated Traffic Class ID.
  598. */
  599. static int cxgb4_getnumtcs(struct net_device *dev, int tcs_id, u8 *num)
  600. {
  601. struct port_info *pi = netdev2pinfo(dev);
  602. switch (tcs_id) {
  603. case DCB_NUMTCS_ATTR_PG:
  604. if (pi->dcb.msgs & CXGB4_DCB_FW_PGRATE)
  605. *num = pi->dcb.pg_num_tcs_supported;
  606. else
  607. *num = 0x8;
  608. break;
  609. case DCB_NUMTCS_ATTR_PFC:
  610. *num = 0x8;
  611. break;
  612. default:
  613. return -EINVAL;
  614. }
  615. return 0;
  616. }
  617. /* Set the number of Traffic Classes supported for the indicated Traffic Class
  618. * ID.
  619. */
  620. static int cxgb4_setnumtcs(struct net_device *dev, int tcs_id, u8 num)
  621. {
  622. /* Setting the number of Traffic Classes isn't supported.
  623. */
  624. return -ENOSYS;
  625. }
  626. /* Return whether Priority Flow Control is enabled. */
  627. static u8 cxgb4_getpfcstate(struct net_device *dev)
  628. {
  629. struct port_info *pi = netdev2pinfo(dev);
  630. if (!cxgb4_dcb_state_synced(pi->dcb.state))
  631. return false;
  632. return pi->dcb.pfcen != 0;
  633. }
  634. /* Enable/disable Priority Flow Control. */
  635. static void cxgb4_setpfcstate(struct net_device *dev, u8 state)
  636. {
  637. /* We can't enable/disable Priority Flow Control but we also can't
  638. * return an error ...
  639. */
  640. }
  641. /* Return the Application User Priority Map associated with the specified
  642. * Application ID.
  643. */
  644. static int __cxgb4_getapp(struct net_device *dev, u8 app_idtype, u16 app_id,
  645. int peer)
  646. {
  647. struct port_info *pi = netdev2pinfo(dev);
  648. struct adapter *adap = pi->adapter;
  649. int i;
  650. if (!cxgb4_dcb_state_synced(pi->dcb.state))
  651. return 0;
  652. for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
  653. struct fw_port_cmd pcmd;
  654. int err;
  655. if (peer)
  656. INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
  657. else
  658. INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
  659. pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
  660. pcmd.u.dcb.app_priority.idx = i;
  661. err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
  662. if (err != FW_PORT_DCB_CFG_SUCCESS) {
  663. dev_err(adap->pdev_dev, "DCB APP read failed with %d\n",
  664. -err);
  665. return err;
  666. }
  667. if (be16_to_cpu(pcmd.u.dcb.app_priority.protocolid) == app_id)
  668. if (pcmd.u.dcb.app_priority.sel_field == app_idtype)
  669. return pcmd.u.dcb.app_priority.user_prio_map;
  670. /* exhausted app list */
  671. if (!pcmd.u.dcb.app_priority.protocolid)
  672. break;
  673. }
  674. return -EEXIST;
  675. }
  676. /* Return the Application User Priority Map associated with the specified
  677. * Application ID.
  678. */
  679. static int cxgb4_getapp(struct net_device *dev, u8 app_idtype, u16 app_id)
  680. {
  681. /* Convert app_idtype to firmware format before querying */
  682. return __cxgb4_getapp(dev, app_idtype == DCB_APP_IDTYPE_ETHTYPE ?
  683. app_idtype : 3, app_id, 0);
  684. }
  685. /* Write a new Application User Priority Map for the specified Application ID
  686. */
  687. static int __cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id,
  688. u8 app_prio)
  689. {
  690. struct fw_port_cmd pcmd;
  691. struct port_info *pi = netdev2pinfo(dev);
  692. struct adapter *adap = pi->adapter;
  693. int i, err;
  694. if (!cxgb4_dcb_state_synced(pi->dcb.state))
  695. return -EINVAL;
  696. /* DCB info gets thrown away on link up */
  697. if (!netif_carrier_ok(dev))
  698. return -ENOLINK;
  699. for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
  700. INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
  701. pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
  702. pcmd.u.dcb.app_priority.idx = i;
  703. err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
  704. if (err != FW_PORT_DCB_CFG_SUCCESS) {
  705. dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
  706. -err);
  707. return err;
  708. }
  709. if (be16_to_cpu(pcmd.u.dcb.app_priority.protocolid) == app_id) {
  710. /* overwrite existing app table */
  711. pcmd.u.dcb.app_priority.protocolid = 0;
  712. break;
  713. }
  714. /* find first empty slot */
  715. if (!pcmd.u.dcb.app_priority.protocolid)
  716. break;
  717. }
  718. if (i == CXGB4_MAX_DCBX_APP_SUPPORTED) {
  719. /* no empty slots available */
  720. dev_err(adap->pdev_dev, "DCB app table full\n");
  721. return -EBUSY;
  722. }
  723. /* write out new app table entry */
  724. INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
  725. if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
  726. pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F);
  727. pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
  728. pcmd.u.dcb.app_priority.protocolid = cpu_to_be16(app_id);
  729. pcmd.u.dcb.app_priority.sel_field = app_idtype;
  730. pcmd.u.dcb.app_priority.user_prio_map = app_prio;
  731. pcmd.u.dcb.app_priority.idx = i;
  732. err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
  733. if (err != FW_PORT_DCB_CFG_SUCCESS) {
  734. dev_err(adap->pdev_dev, "DCB app table write failed with %d\n",
  735. -err);
  736. return err;
  737. }
  738. return 0;
  739. }
  740. /* Priority for CEE inside dcb_app is bitmask, with 0 being an invalid value */
  741. static int cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id,
  742. u8 app_prio)
  743. {
  744. int ret;
  745. struct dcb_app app = {
  746. .selector = app_idtype,
  747. .protocol = app_id,
  748. .priority = app_prio,
  749. };
  750. if (app_idtype != DCB_APP_IDTYPE_ETHTYPE &&
  751. app_idtype != DCB_APP_IDTYPE_PORTNUM)
  752. return -EINVAL;
  753. /* Convert app_idtype to a format that firmware understands */
  754. ret = __cxgb4_setapp(dev, app_idtype == DCB_APP_IDTYPE_ETHTYPE ?
  755. app_idtype : 3, app_id, app_prio);
  756. if (ret)
  757. return ret;
  758. return dcb_setapp(dev, &app);
  759. }
  760. /* Return whether IEEE Data Center Bridging has been negotiated.
  761. */
  762. static inline int
  763. cxgb4_ieee_negotiation_complete(struct net_device *dev,
  764. enum cxgb4_dcb_fw_msgs dcb_subtype)
  765. {
  766. struct port_info *pi = netdev2pinfo(dev);
  767. struct port_dcb_info *dcb = &pi->dcb;
  768. if (dcb->state == CXGB4_DCB_STATE_FW_ALLSYNCED)
  769. if (dcb_subtype && !(dcb->msgs & dcb_subtype))
  770. return 0;
  771. return (cxgb4_dcb_state_synced(dcb->state) &&
  772. (dcb->supported & DCB_CAP_DCBX_VER_IEEE));
  773. }
  774. static int cxgb4_ieee_read_ets(struct net_device *dev, struct ieee_ets *ets,
  775. int local)
  776. {
  777. struct port_info *pi = netdev2pinfo(dev);
  778. struct port_dcb_info *dcb = &pi->dcb;
  779. struct adapter *adap = pi->adapter;
  780. uint32_t tc_info;
  781. struct fw_port_cmd pcmd;
  782. int i, bwg, err;
  783. if (!(dcb->msgs & (CXGB4_DCB_FW_PGID | CXGB4_DCB_FW_PGRATE)))
  784. return 0;
  785. ets->ets_cap = dcb->pg_num_tcs_supported;
  786. if (local) {
  787. ets->willing = 1;
  788. INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
  789. } else {
  790. INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
  791. }
  792. pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
  793. err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
  794. if (err != FW_PORT_DCB_CFG_SUCCESS) {
  795. dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
  796. return err;
  797. }
  798. tc_info = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
  799. if (local)
  800. INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
  801. else
  802. INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
  803. pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
  804. err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
  805. if (err != FW_PORT_DCB_CFG_SUCCESS) {
  806. dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
  807. -err);
  808. return err;
  809. }
  810. for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
  811. bwg = (tc_info >> ((7 - i) * 4)) & 0xF;
  812. ets->prio_tc[i] = bwg;
  813. ets->tc_tx_bw[i] = pcmd.u.dcb.pgrate.pgrate[i];
  814. ets->tc_rx_bw[i] = ets->tc_tx_bw[i];
  815. ets->tc_tsa[i] = pcmd.u.dcb.pgrate.tsa[i];
  816. }
  817. return 0;
  818. }
  819. static int cxgb4_ieee_get_ets(struct net_device *dev, struct ieee_ets *ets)
  820. {
  821. return cxgb4_ieee_read_ets(dev, ets, 1);
  822. }
  823. /* We reuse this for peer PFC as well, as we can't have it enabled one way */
  824. static int cxgb4_ieee_get_pfc(struct net_device *dev, struct ieee_pfc *pfc)
  825. {
  826. struct port_info *pi = netdev2pinfo(dev);
  827. struct port_dcb_info *dcb = &pi->dcb;
  828. memset(pfc, 0, sizeof(struct ieee_pfc));
  829. if (!(dcb->msgs & CXGB4_DCB_FW_PFC))
  830. return 0;
  831. pfc->pfc_cap = dcb->pfc_num_tcs_supported;
  832. pfc->pfc_en = bitswap_1(dcb->pfcen);
  833. return 0;
  834. }
  835. static int cxgb4_ieee_peer_ets(struct net_device *dev, struct ieee_ets *ets)
  836. {
  837. return cxgb4_ieee_read_ets(dev, ets, 0);
  838. }
  839. /* Fill in the Application User Priority Map associated with the
  840. * specified Application.
  841. * Priority for IEEE dcb_app is an integer, with 0 being a valid value
  842. */
  843. static int cxgb4_ieee_getapp(struct net_device *dev, struct dcb_app *app)
  844. {
  845. int prio;
  846. if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
  847. return -EINVAL;
  848. if (!(app->selector && app->protocol))
  849. return -EINVAL;
  850. /* Try querying firmware first, use firmware format */
  851. prio = __cxgb4_getapp(dev, app->selector - 1, app->protocol, 0);
  852. if (prio < 0)
  853. prio = dcb_ieee_getapp_mask(dev, app);
  854. app->priority = ffs(prio) - 1;
  855. return 0;
  856. }
  857. /* Write a new Application User Priority Map for the specified Application ID.
  858. * Priority for IEEE dcb_app is an integer, with 0 being a valid value
  859. */
  860. static int cxgb4_ieee_setapp(struct net_device *dev, struct dcb_app *app)
  861. {
  862. int ret;
  863. if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
  864. return -EINVAL;
  865. if (!(app->selector && app->protocol))
  866. return -EINVAL;
  867. if (!(app->selector > IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
  868. app->selector < IEEE_8021QAZ_APP_SEL_ANY))
  869. return -EINVAL;
  870. /* change selector to a format that firmware understands */
  871. ret = __cxgb4_setapp(dev, app->selector - 1, app->protocol,
  872. (1 << app->priority));
  873. if (ret)
  874. return ret;
  875. return dcb_ieee_setapp(dev, app);
  876. }
  877. /* Return our DCBX parameters.
  878. */
  879. static u8 cxgb4_getdcbx(struct net_device *dev)
  880. {
  881. struct port_info *pi = netdev2pinfo(dev);
  882. /* This is already set by cxgb4_set_dcb_caps, so just return it */
  883. return pi->dcb.supported;
  884. }
  885. /* Set our DCBX parameters.
  886. */
  887. static u8 cxgb4_setdcbx(struct net_device *dev, u8 dcb_request)
  888. {
  889. struct port_info *pi = netdev2pinfo(dev);
  890. /* Filter out requests which exceed our capabilities.
  891. */
  892. if ((dcb_request & (CXGB4_DCBX_FW_SUPPORT | CXGB4_DCBX_HOST_SUPPORT))
  893. != dcb_request)
  894. return 1;
  895. /* Can't enable DCB if we haven't successfully negotiated it.
  896. */
  897. if (!cxgb4_dcb_state_synced(pi->dcb.state))
  898. return 1;
  899. /* There's currently no mechanism to allow for the firmware DCBX
  900. * negotiation to be changed from the Host Driver. If the caller
  901. * requests exactly the same parameters that we already have then
  902. * we'll allow them to be successfully "set" ...
  903. */
  904. if (dcb_request != pi->dcb.supported)
  905. return 1;
  906. pi->dcb.supported = dcb_request;
  907. return 0;
  908. }
  909. static int cxgb4_getpeer_app(struct net_device *dev,
  910. struct dcb_peer_app_info *info, u16 *app_count)
  911. {
  912. struct fw_port_cmd pcmd;
  913. struct port_info *pi = netdev2pinfo(dev);
  914. struct adapter *adap = pi->adapter;
  915. int i, err = 0;
  916. if (!cxgb4_dcb_state_synced(pi->dcb.state))
  917. return 1;
  918. info->willing = 0;
  919. info->error = 0;
  920. *app_count = 0;
  921. for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
  922. INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
  923. pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
  924. pcmd.u.dcb.app_priority.idx = *app_count;
  925. err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
  926. if (err != FW_PORT_DCB_CFG_SUCCESS) {
  927. dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
  928. -err);
  929. return err;
  930. }
  931. /* find first empty slot */
  932. if (!pcmd.u.dcb.app_priority.protocolid)
  933. break;
  934. }
  935. *app_count = i;
  936. return err;
  937. }
  938. static int cxgb4_getpeerapp_tbl(struct net_device *dev, struct dcb_app *table)
  939. {
  940. struct fw_port_cmd pcmd;
  941. struct port_info *pi = netdev2pinfo(dev);
  942. struct adapter *adap = pi->adapter;
  943. int i, err = 0;
  944. if (!cxgb4_dcb_state_synced(pi->dcb.state))
  945. return 1;
  946. for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
  947. INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
  948. pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
  949. pcmd.u.dcb.app_priority.idx = i;
  950. err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
  951. if (err != FW_PORT_DCB_CFG_SUCCESS) {
  952. dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
  953. -err);
  954. return err;
  955. }
  956. /* find first empty slot */
  957. if (!pcmd.u.dcb.app_priority.protocolid)
  958. break;
  959. table[i].selector = (pcmd.u.dcb.app_priority.sel_field + 1);
  960. table[i].protocol =
  961. be16_to_cpu(pcmd.u.dcb.app_priority.protocolid);
  962. table[i].priority =
  963. ffs(pcmd.u.dcb.app_priority.user_prio_map) - 1;
  964. }
  965. return err;
  966. }
  967. /* Return Priority Group information.
  968. */
  969. static int cxgb4_cee_peer_getpg(struct net_device *dev, struct cee_pg *pg)
  970. {
  971. struct fw_port_cmd pcmd;
  972. struct port_info *pi = netdev2pinfo(dev);
  973. struct adapter *adap = pi->adapter;
  974. u32 pgid;
  975. int i, err;
  976. /* We're always "willing" -- the Switch Fabric always dictates the
  977. * DCBX parameters to us.
  978. */
  979. pg->willing = true;
  980. INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
  981. pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
  982. err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
  983. if (err != FW_PORT_DCB_CFG_SUCCESS) {
  984. dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
  985. return err;
  986. }
  987. pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
  988. for (i = 0; i < CXGB4_MAX_PRIORITY; i++)
  989. pg->prio_pg[7 - i] = (pgid >> (i * 4)) & 0xF;
  990. INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
  991. pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
  992. err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
  993. if (err != FW_PORT_DCB_CFG_SUCCESS) {
  994. dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
  995. -err);
  996. return err;
  997. }
  998. for (i = 0; i < CXGB4_MAX_PRIORITY; i++)
  999. pg->pg_bw[i] = pcmd.u.dcb.pgrate.pgrate[i];
  1000. pg->tcs_supported = pcmd.u.dcb.pgrate.num_tcs_supported;
  1001. return 0;
  1002. }
  1003. /* Return Priority Flow Control information.
  1004. */
  1005. static int cxgb4_cee_peer_getpfc(struct net_device *dev, struct cee_pfc *pfc)
  1006. {
  1007. struct port_info *pi = netdev2pinfo(dev);
  1008. cxgb4_getnumtcs(dev, DCB_NUMTCS_ATTR_PFC, &(pfc->tcs_supported));
  1009. /* Firmware sends this to us in a formwat that is a bit flipped version
  1010. * of spec, correct it before we send it to host. This is taken care of
  1011. * by bit shifting in other uses of pfcen
  1012. */
  1013. pfc->pfc_en = bitswap_1(pi->dcb.pfcen);
  1014. pfc->tcs_supported = pi->dcb.pfc_num_tcs_supported;
  1015. return 0;
  1016. }
  1017. const struct dcbnl_rtnl_ops cxgb4_dcb_ops = {
  1018. .ieee_getets = cxgb4_ieee_get_ets,
  1019. .ieee_getpfc = cxgb4_ieee_get_pfc,
  1020. .ieee_getapp = cxgb4_ieee_getapp,
  1021. .ieee_setapp = cxgb4_ieee_setapp,
  1022. .ieee_peer_getets = cxgb4_ieee_peer_ets,
  1023. .ieee_peer_getpfc = cxgb4_ieee_get_pfc,
  1024. /* CEE std */
  1025. .getstate = cxgb4_getstate,
  1026. .setstate = cxgb4_setstate,
  1027. .getpgtccfgtx = cxgb4_getpgtccfg_tx,
  1028. .getpgbwgcfgtx = cxgb4_getpgbwgcfg_tx,
  1029. .getpgtccfgrx = cxgb4_getpgtccfg_rx,
  1030. .getpgbwgcfgrx = cxgb4_getpgbwgcfg_rx,
  1031. .setpgtccfgtx = cxgb4_setpgtccfg_tx,
  1032. .setpgbwgcfgtx = cxgb4_setpgbwgcfg_tx,
  1033. .setpfccfg = cxgb4_setpfccfg,
  1034. .getpfccfg = cxgb4_getpfccfg,
  1035. .setall = cxgb4_setall,
  1036. .getcap = cxgb4_getcap,
  1037. .getnumtcs = cxgb4_getnumtcs,
  1038. .setnumtcs = cxgb4_setnumtcs,
  1039. .getpfcstate = cxgb4_getpfcstate,
  1040. .setpfcstate = cxgb4_setpfcstate,
  1041. .getapp = cxgb4_getapp,
  1042. .setapp = cxgb4_setapp,
  1043. /* DCBX configuration */
  1044. .getdcbx = cxgb4_getdcbx,
  1045. .setdcbx = cxgb4_setdcbx,
  1046. /* peer apps */
  1047. .peer_getappinfo = cxgb4_getpeer_app,
  1048. .peer_getapptable = cxgb4_getpeerapp_tbl,
  1049. /* CEE peer */
  1050. .cee_peer_getpg = cxgb4_cee_peer_getpg,
  1051. .cee_peer_getpfc = cxgb4_cee_peer_getpfc,
  1052. };