2 * Copyright (C) 2013-2014 Chelsio Communications. All rights reserved.
4 * Written by Anish Bhatt (anish@chelsio.com)
5 * Casey Leedom (leedom@chelsio.com)
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.
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
16 * The full GNU General Public License is included in this distribution in
17 * the file called "COPYING".
23 /* DCBx version control
25 const char * const dcb_ver_array[] = {
34 static inline bool cxgb4_dcb_state_synced(enum cxgb4_dcb_state state)
36 if (state == CXGB4_DCB_STATE_FW_ALLSYNCED ||
37 state == CXGB4_DCB_STATE_HOST)
43 /* Initialize a port's Data Center Bridging state.
45 void cxgb4_dcb_state_init(struct net_device *dev)
47 struct port_info *pi = netdev2pinfo(dev);
48 struct port_dcb_info *dcb = &pi->dcb;
49 int version_temp = dcb->dcb_version;
51 memset(dcb, 0, sizeof(struct port_dcb_info));
52 dcb->state = CXGB4_DCB_STATE_START;
54 dcb->dcb_version = version_temp;
56 netdev_dbg(dev, "%s: Initializing DCB state for port[%d]\n",
57 __func__, pi->port_id);
60 void cxgb4_dcb_version_init(struct net_device *dev)
62 struct port_info *pi = netdev2pinfo(dev);
63 struct port_dcb_info *dcb = &pi->dcb;
65 /* Any writes here are only done on kernels that exlicitly need
66 * a specific version, say < 2.6.38 which only support CEE
68 dcb->dcb_version = FW_PORT_DCB_VER_AUTO;
71 static void cxgb4_dcb_cleanup_apps(struct net_device *dev)
73 struct port_info *pi = netdev2pinfo(dev);
74 struct adapter *adap = pi->adapter;
75 struct port_dcb_info *dcb = &pi->dcb;
79 /* zero priority implies remove */
82 for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
83 /* Check if app list is exhausted */
84 if (!dcb->app_priority[i].protocolid)
87 app.protocol = dcb->app_priority[i].protocolid;
89 if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) {
90 app.priority = dcb->app_priority[i].user_prio_map;
91 app.selector = dcb->app_priority[i].sel_field + 1;
92 err = dcb_ieee_delapp(dev, &app);
94 app.selector = !!(dcb->app_priority[i].sel_field);
95 err = dcb_setapp(dev, &app);
99 dev_err(adap->pdev_dev,
100 "Failed DCB Clear %s Application Priority: sel=%d, prot=%d, , err=%d\n",
101 dcb_ver_array[dcb->dcb_version], app.selector,
108 /* Reset a port's Data Center Bridging state. Typically used after a
111 void cxgb4_dcb_reset(struct net_device *dev)
113 cxgb4_dcb_cleanup_apps(dev);
114 cxgb4_dcb_state_init(dev);
117 /* update the dcb port support, if version is IEEE then set it to
118 * FW_PORT_DCB_VER_IEEE and if DCB_CAP_DCBX_VER_CEE is already set then
119 * clear that. and if it is set to CEE then set dcb supported to
120 * DCB_CAP_DCBX_VER_CEE & if DCB_CAP_DCBX_VER_IEEE is set, clear it
122 static inline void cxgb4_dcb_update_support(struct port_dcb_info *dcb)
124 if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) {
125 if (dcb->supported & DCB_CAP_DCBX_VER_CEE)
126 dcb->supported &= ~DCB_CAP_DCBX_VER_CEE;
127 dcb->supported |= DCB_CAP_DCBX_VER_IEEE;
128 } else if (dcb->dcb_version == FW_PORT_DCB_VER_CEE1D01) {
129 if (dcb->supported & DCB_CAP_DCBX_VER_IEEE)
130 dcb->supported &= ~DCB_CAP_DCBX_VER_IEEE;
131 dcb->supported |= DCB_CAP_DCBX_VER_CEE;
135 /* Finite State machine for Data Center Bridging.
137 void cxgb4_dcb_state_fsm(struct net_device *dev,
138 enum cxgb4_dcb_state_input transition_to)
140 struct port_info *pi = netdev2pinfo(dev);
141 struct port_dcb_info *dcb = &pi->dcb;
142 struct adapter *adap = pi->adapter;
143 enum cxgb4_dcb_state current_state = dcb->state;
145 netdev_dbg(dev, "%s: State change from %d to %d for %s\n",
146 __func__, dcb->state, transition_to, dev->name);
148 switch (current_state) {
149 case CXGB4_DCB_STATE_START: {
150 switch (transition_to) {
151 case CXGB4_DCB_INPUT_FW_DISABLED: {
152 /* we're going to use Host DCB */
153 dcb->state = CXGB4_DCB_STATE_HOST;
154 dcb->supported = CXGB4_DCBX_HOST_SUPPORT;
158 case CXGB4_DCB_INPUT_FW_ENABLED: {
159 /* we're going to use Firmware DCB */
160 dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE;
161 dcb->supported = DCB_CAP_DCBX_LLD_MANAGED;
162 if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE)
163 dcb->supported |= DCB_CAP_DCBX_VER_IEEE;
165 dcb->supported |= DCB_CAP_DCBX_VER_CEE;
169 case CXGB4_DCB_INPUT_FW_INCOMPLETE: {
170 /* expected transition */
174 case CXGB4_DCB_INPUT_FW_ALLSYNCED: {
175 dcb->state = CXGB4_DCB_STATE_FW_ALLSYNCED;
180 goto bad_state_input;
185 case CXGB4_DCB_STATE_FW_INCOMPLETE: {
186 if (transition_to != CXGB4_DCB_INPUT_FW_DISABLED) {
187 /* during this CXGB4_DCB_STATE_FW_INCOMPLETE state,
188 * check if the dcb version is changed (there can be
189 * mismatch in default config & the negotiated switch
190 * configuration at FW, so update the dcb support
193 cxgb4_dcb_update_support(dcb);
195 switch (transition_to) {
196 case CXGB4_DCB_INPUT_FW_ENABLED: {
197 /* we're alreaady in firmware DCB mode */
201 case CXGB4_DCB_INPUT_FW_INCOMPLETE: {
202 /* we're already incomplete */
206 case CXGB4_DCB_INPUT_FW_ALLSYNCED: {
207 dcb->state = CXGB4_DCB_STATE_FW_ALLSYNCED;
209 linkwatch_fire_event(dev);
214 goto bad_state_input;
219 case CXGB4_DCB_STATE_FW_ALLSYNCED: {
220 switch (transition_to) {
221 case CXGB4_DCB_INPUT_FW_ENABLED: {
222 /* we're alreaady in firmware DCB mode */
226 case CXGB4_DCB_INPUT_FW_INCOMPLETE: {
227 /* We were successfully running with firmware DCB but
228 * now it's telling us that it's in an "incomplete
229 * state. We need to reset back to a ground state
232 cxgb4_dcb_reset(dev);
233 dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE;
234 dcb->supported = CXGB4_DCBX_FW_SUPPORT;
235 linkwatch_fire_event(dev);
239 case CXGB4_DCB_INPUT_FW_ALLSYNCED: {
240 /* we're already all sync'ed
241 * this is only applicable for IEEE or
242 * when another VI already completed negotiaton
245 linkwatch_fire_event(dev);
250 goto bad_state_input;
255 case CXGB4_DCB_STATE_HOST: {
256 switch (transition_to) {
257 case CXGB4_DCB_INPUT_FW_DISABLED: {
258 /* we're alreaady in Host DCB mode */
263 goto bad_state_input;
269 goto bad_state_transition;
274 dev_err(adap->pdev_dev, "cxgb4_dcb_state_fsm: illegal input symbol %d\n",
278 bad_state_transition:
279 dev_err(adap->pdev_dev, "cxgb4_dcb_state_fsm: bad state transition, state = %d, input = %d\n",
280 current_state, transition_to);
283 /* Handle a DCB/DCBX update message from the firmware.
285 void cxgb4_dcb_handle_fw_update(struct adapter *adap,
286 const struct fw_port_cmd *pcmd)
288 const union fw_port_dcb *fwdcb = &pcmd->u.dcb;
289 int port = FW_PORT_CMD_PORTID_G(be32_to_cpu(pcmd->op_to_portid));
290 struct net_device *dev = adap->port[adap->chan_map[port]];
291 struct port_info *pi = netdev_priv(dev);
292 struct port_dcb_info *dcb = &pi->dcb;
293 int dcb_type = pcmd->u.dcb.pgid.type;
294 int dcb_running_version;
296 /* Handle Firmware DCB Control messages separately since they drive
299 if (dcb_type == FW_PORT_DCB_TYPE_CONTROL) {
300 enum cxgb4_dcb_state_input input =
301 ((pcmd->u.dcb.control.all_syncd_pkd &
302 FW_PORT_CMD_ALL_SYNCD_F)
303 ? CXGB4_DCB_INPUT_FW_ALLSYNCED
304 : CXGB4_DCB_INPUT_FW_INCOMPLETE);
306 if (dcb->dcb_version != FW_PORT_DCB_VER_UNKNOWN) {
307 dcb_running_version = FW_PORT_CMD_DCB_VERSION_G(
309 pcmd->u.dcb.control.dcb_version_to_app_state));
310 if (dcb_running_version == FW_PORT_DCB_VER_CEE1D01 ||
311 dcb_running_version == FW_PORT_DCB_VER_IEEE) {
312 dcb->dcb_version = dcb_running_version;
313 dev_warn(adap->pdev_dev, "Interface %s is running %s\n",
315 dcb_ver_array[dcb->dcb_version]);
317 dev_warn(adap->pdev_dev,
318 "Something screwed up, requested firmware for %s, but firmware returned %s instead\n",
319 dcb_ver_array[dcb->dcb_version],
320 dcb_ver_array[dcb_running_version]);
321 dcb->dcb_version = FW_PORT_DCB_VER_UNKNOWN;
325 cxgb4_dcb_state_fsm(dev, input);
329 /* It's weird, and almost certainly an error, to get Firmware DCB
330 * messages when we either haven't been told whether we're going to be
331 * doing Host or Firmware DCB; and even worse when we've been told
332 * that we're doing Host DCB!
334 if (dcb->state == CXGB4_DCB_STATE_START ||
335 dcb->state == CXGB4_DCB_STATE_HOST) {
336 dev_err(adap->pdev_dev, "Receiving Firmware DCB messages in State %d\n",
341 /* Now handle the general Firmware DCB update messages ...
344 case FW_PORT_DCB_TYPE_PGID:
345 dcb->pgid = be32_to_cpu(fwdcb->pgid.pgid);
346 dcb->msgs |= CXGB4_DCB_FW_PGID;
349 case FW_PORT_DCB_TYPE_PGRATE:
350 dcb->pg_num_tcs_supported = fwdcb->pgrate.num_tcs_supported;
351 memcpy(dcb->pgrate, &fwdcb->pgrate.pgrate,
352 sizeof(dcb->pgrate));
353 memcpy(dcb->tsa, &fwdcb->pgrate.tsa,
355 dcb->msgs |= CXGB4_DCB_FW_PGRATE;
356 if (dcb->msgs & CXGB4_DCB_FW_PGID)
357 IEEE_FAUX_SYNC(dev, dcb);
360 case FW_PORT_DCB_TYPE_PRIORATE:
361 memcpy(dcb->priorate, &fwdcb->priorate.strict_priorate,
362 sizeof(dcb->priorate));
363 dcb->msgs |= CXGB4_DCB_FW_PRIORATE;
366 case FW_PORT_DCB_TYPE_PFC:
367 dcb->pfcen = fwdcb->pfc.pfcen;
368 dcb->pfc_num_tcs_supported = fwdcb->pfc.max_pfc_tcs;
369 dcb->msgs |= CXGB4_DCB_FW_PFC;
370 IEEE_FAUX_SYNC(dev, dcb);
373 case FW_PORT_DCB_TYPE_APP_ID: {
374 const struct fw_port_app_priority *fwap = &fwdcb->app_priority;
376 struct app_priority *ap = &dcb->app_priority[idx];
378 struct dcb_app app = {
379 .protocol = be16_to_cpu(fwap->protocolid),
383 /* Convert from firmware format to relevant format
384 * when using app selector
386 if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) {
387 app.selector = (fwap->sel_field + 1);
388 app.priority = ffs(fwap->user_prio_map) - 1;
389 err = dcb_ieee_setapp(dev, &app);
390 IEEE_FAUX_SYNC(dev, dcb);
393 app.selector = !!(fwap->sel_field);
394 app.priority = fwap->user_prio_map;
395 err = dcb_setapp(dev, &app);
399 dev_err(adap->pdev_dev,
400 "Failed DCB Set Application Priority: sel=%d, prot=%d, prio=%d, err=%d\n",
401 app.selector, app.protocol, app.priority, -err);
403 ap->user_prio_map = fwap->user_prio_map;
404 ap->sel_field = fwap->sel_field;
405 ap->protocolid = be16_to_cpu(fwap->protocolid);
406 dcb->msgs |= CXGB4_DCB_FW_APP_ID;
411 dev_err(adap->pdev_dev, "Unknown DCB update type received %x\n",
417 /* Data Center Bridging netlink operations.
421 /* Get current DCB enabled/disabled state.
423 static u8 cxgb4_getstate(struct net_device *dev)
425 struct port_info *pi = netdev2pinfo(dev);
427 return pi->dcb.enabled;
430 /* Set DCB enabled/disabled.
432 static u8 cxgb4_setstate(struct net_device *dev, u8 enabled)
434 struct port_info *pi = netdev2pinfo(dev);
436 /* If DCBx is host-managed, dcb is enabled by outside lldp agents */
437 if (pi->dcb.state == CXGB4_DCB_STATE_HOST) {
438 pi->dcb.enabled = enabled;
442 /* Firmware doesn't provide any mechanism to control the DCB state.
444 if (enabled != (pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED))
450 static void cxgb4_getpgtccfg(struct net_device *dev, int tc,
451 u8 *prio_type, u8 *pgid, u8 *bw_per,
452 u8 *up_tc_map, int local)
454 struct fw_port_cmd pcmd;
455 struct port_info *pi = netdev2pinfo(dev);
456 struct adapter *adap = pi->adapter;
459 *prio_type = *pgid = *bw_per = *up_tc_map = 0;
462 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
464 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
466 pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
467 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
468 if (err != FW_PORT_DCB_CFG_SUCCESS) {
469 dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
472 *pgid = (be32_to_cpu(pcmd.u.dcb.pgid.pgid) >> (tc * 4)) & 0xf;
475 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
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",
486 *bw_per = pcmd.u.dcb.pgrate.pgrate[*pgid];
487 *up_tc_map = (1 << tc);
489 /* prio_type is link strict */
494 static void cxgb4_getpgtccfg_tx(struct net_device *dev, int tc,
495 u8 *prio_type, u8 *pgid, u8 *bw_per,
498 /* tc 0 is written at MSB position */
499 return cxgb4_getpgtccfg(dev, (7 - tc), prio_type, pgid, bw_per,
504 static void cxgb4_getpgtccfg_rx(struct net_device *dev, int tc,
505 u8 *prio_type, u8 *pgid, u8 *bw_per,
508 /* tc 0 is written at MSB position */
509 return cxgb4_getpgtccfg(dev, (7 - tc), prio_type, pgid, bw_per,
513 static void cxgb4_setpgtccfg_tx(struct net_device *dev, int tc,
514 u8 prio_type, u8 pgid, u8 bw_per,
517 struct fw_port_cmd pcmd;
518 struct port_info *pi = netdev2pinfo(dev);
519 struct adapter *adap = pi->adapter;
524 if (pgid == DCB_ATTR_VALUE_UNDEFINED)
526 if (bw_per == DCB_ATTR_VALUE_UNDEFINED)
529 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
530 pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
532 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
533 if (err != FW_PORT_DCB_CFG_SUCCESS) {
534 dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
538 _pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
539 _pgid &= ~(0xF << (fw_tc * 4));
540 _pgid |= pgid << (fw_tc * 4);
541 pcmd.u.dcb.pgid.pgid = cpu_to_be32(_pgid);
543 INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
545 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
546 if (err != FW_PORT_DCB_CFG_SUCCESS) {
547 dev_err(adap->pdev_dev, "DCB write PGID failed with %d\n",
552 memset(&pcmd, 0, sizeof(struct fw_port_cmd));
554 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
555 pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
557 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
558 if (err != FW_PORT_DCB_CFG_SUCCESS) {
559 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
564 pcmd.u.dcb.pgrate.pgrate[pgid] = bw_per;
566 INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
567 if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
568 pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F);
570 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
571 if (err != FW_PORT_DCB_CFG_SUCCESS)
572 dev_err(adap->pdev_dev, "DCB write PGRATE failed with %d\n",
576 static void cxgb4_getpgbwgcfg(struct net_device *dev, int pgid, u8 *bw_per,
579 struct fw_port_cmd pcmd;
580 struct port_info *pi = netdev2pinfo(dev);
581 struct adapter *adap = pi->adapter;
585 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
587 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
589 pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
590 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
591 if (err != FW_PORT_DCB_CFG_SUCCESS) {
592 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
597 *bw_per = pcmd.u.dcb.pgrate.pgrate[pgid];
600 static void cxgb4_getpgbwgcfg_tx(struct net_device *dev, int pgid, u8 *bw_per)
602 return cxgb4_getpgbwgcfg(dev, pgid, bw_per, 1);
605 static void cxgb4_getpgbwgcfg_rx(struct net_device *dev, int pgid, u8 *bw_per)
607 return cxgb4_getpgbwgcfg(dev, pgid, bw_per, 0);
610 static void cxgb4_setpgbwgcfg_tx(struct net_device *dev, int pgid,
613 struct fw_port_cmd pcmd;
614 struct port_info *pi = netdev2pinfo(dev);
615 struct adapter *adap = pi->adapter;
618 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
619 pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
621 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
622 if (err != FW_PORT_DCB_CFG_SUCCESS) {
623 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
628 pcmd.u.dcb.pgrate.pgrate[pgid] = bw_per;
630 INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
631 if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
632 pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F);
634 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
636 if (err != FW_PORT_DCB_CFG_SUCCESS)
637 dev_err(adap->pdev_dev, "DCB write PGRATE failed with %d\n",
641 /* Return whether the specified Traffic Class Priority has Priority Pause
644 static void cxgb4_getpfccfg(struct net_device *dev, int priority, u8 *pfccfg)
646 struct port_info *pi = netdev2pinfo(dev);
647 struct port_dcb_info *dcb = &pi->dcb;
649 if (!cxgb4_dcb_state_synced(dcb->state) ||
650 priority >= CXGB4_MAX_PRIORITY)
653 *pfccfg = (pi->dcb.pfcen >> (7 - priority)) & 1;
656 /* Enable/disable Priority Pause Frames for the specified Traffic Class
659 static void cxgb4_setpfccfg(struct net_device *dev, int priority, u8 pfccfg)
661 struct fw_port_cmd pcmd;
662 struct port_info *pi = netdev2pinfo(dev);
663 struct adapter *adap = pi->adapter;
666 if (!cxgb4_dcb_state_synced(pi->dcb.state) ||
667 priority >= CXGB4_MAX_PRIORITY)
670 INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
671 if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
672 pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F);
674 pcmd.u.dcb.pfc.type = FW_PORT_DCB_TYPE_PFC;
675 pcmd.u.dcb.pfc.pfcen = pi->dcb.pfcen;
678 pcmd.u.dcb.pfc.pfcen |= (1 << (7 - priority));
680 pcmd.u.dcb.pfc.pfcen &= (~(1 << (7 - priority)));
682 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
683 if (err != FW_PORT_DCB_CFG_SUCCESS) {
684 dev_err(adap->pdev_dev, "DCB PFC write failed with %d\n", -err);
688 pi->dcb.pfcen = pcmd.u.dcb.pfc.pfcen;
691 static u8 cxgb4_setall(struct net_device *dev)
696 /* Return DCB capabilities.
698 static u8 cxgb4_getcap(struct net_device *dev, int cap_id, u8 *caps)
700 struct port_info *pi = netdev2pinfo(dev);
703 case DCB_CAP_ATTR_PG:
704 case DCB_CAP_ATTR_PFC:
708 case DCB_CAP_ATTR_PG_TCS:
709 /* 8 priorities for PG represented by bitmap */
713 case DCB_CAP_ATTR_PFC_TCS:
714 /* 8 priorities for PFC represented by bitmap */
718 case DCB_CAP_ATTR_GSP:
722 case DCB_CAP_ATTR_UP2TC:
723 case DCB_CAP_ATTR_BCN:
727 case DCB_CAP_ATTR_DCBX:
728 *caps = pi->dcb.supported;
738 /* Return the number of Traffic Classes for the indicated Traffic Class ID.
740 static int cxgb4_getnumtcs(struct net_device *dev, int tcs_id, u8 *num)
742 struct port_info *pi = netdev2pinfo(dev);
745 case DCB_NUMTCS_ATTR_PG:
746 if (pi->dcb.msgs & CXGB4_DCB_FW_PGRATE)
747 *num = pi->dcb.pg_num_tcs_supported;
752 case DCB_NUMTCS_ATTR_PFC:
763 /* Set the number of Traffic Classes supported for the indicated Traffic Class
766 static int cxgb4_setnumtcs(struct net_device *dev, int tcs_id, u8 num)
768 /* Setting the number of Traffic Classes isn't supported.
773 /* Return whether Priority Flow Control is enabled. */
774 static u8 cxgb4_getpfcstate(struct net_device *dev)
776 struct port_info *pi = netdev2pinfo(dev);
778 if (!cxgb4_dcb_state_synced(pi->dcb.state))
781 return pi->dcb.pfcen != 0;
784 /* Enable/disable Priority Flow Control. */
785 static void cxgb4_setpfcstate(struct net_device *dev, u8 state)
787 /* We can't enable/disable Priority Flow Control but we also can't
788 * return an error ...
792 /* Return the Application User Priority Map associated with the specified
795 static int __cxgb4_getapp(struct net_device *dev, u8 app_idtype, u16 app_id,
798 struct port_info *pi = netdev2pinfo(dev);
799 struct adapter *adap = pi->adapter;
802 if (!cxgb4_dcb_state_synced(pi->dcb.state))
805 for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
806 struct fw_port_cmd pcmd;
810 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
812 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
814 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
815 pcmd.u.dcb.app_priority.idx = i;
817 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
818 if (err != FW_PORT_DCB_CFG_SUCCESS) {
819 dev_err(adap->pdev_dev, "DCB APP read failed with %d\n",
823 if (be16_to_cpu(pcmd.u.dcb.app_priority.protocolid) == app_id)
824 if (pcmd.u.dcb.app_priority.sel_field == app_idtype)
825 return pcmd.u.dcb.app_priority.user_prio_map;
827 /* exhausted app list */
828 if (!pcmd.u.dcb.app_priority.protocolid)
835 /* Return the Application User Priority Map associated with the specified
838 static int cxgb4_getapp(struct net_device *dev, u8 app_idtype, u16 app_id)
840 /* Convert app_idtype to firmware format before querying */
841 return __cxgb4_getapp(dev, app_idtype == DCB_APP_IDTYPE_ETHTYPE ?
842 app_idtype : 3, app_id, 0);
845 /* Write a new Application User Priority Map for the specified Application ID
847 static int __cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id,
850 struct fw_port_cmd pcmd;
851 struct port_info *pi = netdev2pinfo(dev);
852 struct adapter *adap = pi->adapter;
856 if (!cxgb4_dcb_state_synced(pi->dcb.state))
859 /* DCB info gets thrown away on link up */
860 if (!netif_carrier_ok(dev))
863 for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
864 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
865 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
866 pcmd.u.dcb.app_priority.idx = i;
867 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
869 if (err != FW_PORT_DCB_CFG_SUCCESS) {
870 dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
874 if (be16_to_cpu(pcmd.u.dcb.app_priority.protocolid) == app_id) {
875 /* overwrite existing app table */
876 pcmd.u.dcb.app_priority.protocolid = 0;
879 /* find first empty slot */
880 if (!pcmd.u.dcb.app_priority.protocolid)
884 if (i == CXGB4_MAX_DCBX_APP_SUPPORTED) {
885 /* no empty slots available */
886 dev_err(adap->pdev_dev, "DCB app table full\n");
890 /* write out new app table entry */
891 INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
892 if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
893 pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F);
895 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
896 pcmd.u.dcb.app_priority.protocolid = cpu_to_be16(app_id);
897 pcmd.u.dcb.app_priority.sel_field = app_idtype;
898 pcmd.u.dcb.app_priority.user_prio_map = app_prio;
899 pcmd.u.dcb.app_priority.idx = i;
901 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
902 if (err != FW_PORT_DCB_CFG_SUCCESS) {
903 dev_err(adap->pdev_dev, "DCB app table write failed with %d\n",
911 /* Priority for CEE inside dcb_app is bitmask, with 0 being an invalid value */
912 static int cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id,
916 struct dcb_app app = {
917 .selector = app_idtype,
919 .priority = app_prio,
922 if (app_idtype != DCB_APP_IDTYPE_ETHTYPE &&
923 app_idtype != DCB_APP_IDTYPE_PORTNUM)
926 /* Convert app_idtype to a format that firmware understands */
927 ret = __cxgb4_setapp(dev, app_idtype == DCB_APP_IDTYPE_ETHTYPE ?
928 app_idtype : 3, app_id, app_prio);
932 return dcb_setapp(dev, &app);
935 /* Return whether IEEE Data Center Bridging has been negotiated.
938 cxgb4_ieee_negotiation_complete(struct net_device *dev,
939 enum cxgb4_dcb_fw_msgs dcb_subtype)
941 struct port_info *pi = netdev2pinfo(dev);
942 struct port_dcb_info *dcb = &pi->dcb;
944 if (dcb->state == CXGB4_DCB_STATE_FW_ALLSYNCED)
945 if (dcb_subtype && !(dcb->msgs & dcb_subtype))
948 return (cxgb4_dcb_state_synced(dcb->state) &&
949 (dcb->supported & DCB_CAP_DCBX_VER_IEEE));
952 static int cxgb4_ieee_read_ets(struct net_device *dev, struct ieee_ets *ets,
955 struct port_info *pi = netdev2pinfo(dev);
956 struct port_dcb_info *dcb = &pi->dcb;
957 struct adapter *adap = pi->adapter;
959 struct fw_port_cmd pcmd;
962 if (!(dcb->msgs & (CXGB4_DCB_FW_PGID | CXGB4_DCB_FW_PGRATE)))
965 ets->ets_cap = dcb->pg_num_tcs_supported;
969 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
971 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
974 pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
975 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
976 if (err != FW_PORT_DCB_CFG_SUCCESS) {
977 dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
981 tc_info = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
984 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
986 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
988 pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
989 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
990 if (err != FW_PORT_DCB_CFG_SUCCESS) {
991 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
996 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
997 bwg = (tc_info >> ((7 - i) * 4)) & 0xF;
998 ets->prio_tc[i] = bwg;
999 ets->tc_tx_bw[i] = pcmd.u.dcb.pgrate.pgrate[i];
1000 ets->tc_rx_bw[i] = ets->tc_tx_bw[i];
1001 ets->tc_tsa[i] = pcmd.u.dcb.pgrate.tsa[i];
1007 static int cxgb4_ieee_get_ets(struct net_device *dev, struct ieee_ets *ets)
1009 return cxgb4_ieee_read_ets(dev, ets, 1);
1012 /* We reuse this for peer PFC as well, as we can't have it enabled one way */
1013 static int cxgb4_ieee_get_pfc(struct net_device *dev, struct ieee_pfc *pfc)
1015 struct port_info *pi = netdev2pinfo(dev);
1016 struct port_dcb_info *dcb = &pi->dcb;
1018 memset(pfc, 0, sizeof(struct ieee_pfc));
1020 if (!(dcb->msgs & CXGB4_DCB_FW_PFC))
1023 pfc->pfc_cap = dcb->pfc_num_tcs_supported;
1024 pfc->pfc_en = bitswap_1(dcb->pfcen);
1029 static int cxgb4_ieee_peer_ets(struct net_device *dev, struct ieee_ets *ets)
1031 return cxgb4_ieee_read_ets(dev, ets, 0);
1034 /* Fill in the Application User Priority Map associated with the
1035 * specified Application.
1036 * Priority for IEEE dcb_app is an integer, with 0 being a valid value
1038 static int cxgb4_ieee_getapp(struct net_device *dev, struct dcb_app *app)
1042 if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
1044 if (!(app->selector && app->protocol))
1047 /* Try querying firmware first, use firmware format */
1048 prio = __cxgb4_getapp(dev, app->selector - 1, app->protocol, 0);
1051 prio = dcb_ieee_getapp_mask(dev, app);
1053 app->priority = ffs(prio) - 1;
1057 /* Write a new Application User Priority Map for the specified Application ID.
1058 * Priority for IEEE dcb_app is an integer, with 0 being a valid value
1060 static int cxgb4_ieee_setapp(struct net_device *dev, struct dcb_app *app)
1064 if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
1066 if (!(app->selector && app->protocol))
1069 if (!(app->selector > IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
1070 app->selector < IEEE_8021QAZ_APP_SEL_ANY))
1073 /* change selector to a format that firmware understands */
1074 ret = __cxgb4_setapp(dev, app->selector - 1, app->protocol,
1075 (1 << app->priority));
1079 return dcb_ieee_setapp(dev, app);
1082 /* Return our DCBX parameters.
1084 static u8 cxgb4_getdcbx(struct net_device *dev)
1086 struct port_info *pi = netdev2pinfo(dev);
1088 /* This is already set by cxgb4_set_dcb_caps, so just return it */
1089 return pi->dcb.supported;
1092 /* Set our DCBX parameters.
1094 static u8 cxgb4_setdcbx(struct net_device *dev, u8 dcb_request)
1096 struct port_info *pi = netdev2pinfo(dev);
1098 /* Filter out requests which exceed our capabilities.
1100 if ((dcb_request & (CXGB4_DCBX_FW_SUPPORT | CXGB4_DCBX_HOST_SUPPORT))
1104 /* Can't enable DCB if we haven't successfully negotiated it.
1106 if (!cxgb4_dcb_state_synced(pi->dcb.state))
1109 /* There's currently no mechanism to allow for the firmware DCBX
1110 * negotiation to be changed from the Host Driver. If the caller
1111 * requests exactly the same parameters that we already have then
1112 * we'll allow them to be successfully "set" ...
1114 if (dcb_request != pi->dcb.supported)
1117 pi->dcb.supported = dcb_request;
1121 static int cxgb4_getpeer_app(struct net_device *dev,
1122 struct dcb_peer_app_info *info, u16 *app_count)
1124 struct fw_port_cmd pcmd;
1125 struct port_info *pi = netdev2pinfo(dev);
1126 struct adapter *adap = pi->adapter;
1129 if (!cxgb4_dcb_state_synced(pi->dcb.state))
1136 for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
1137 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
1138 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
1139 pcmd.u.dcb.app_priority.idx = *app_count;
1140 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
1142 if (err != FW_PORT_DCB_CFG_SUCCESS) {
1143 dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
1148 /* find first empty slot */
1149 if (!pcmd.u.dcb.app_priority.protocolid)
1156 static int cxgb4_getpeerapp_tbl(struct net_device *dev, struct dcb_app *table)
1158 struct fw_port_cmd pcmd;
1159 struct port_info *pi = netdev2pinfo(dev);
1160 struct adapter *adap = pi->adapter;
1163 if (!cxgb4_dcb_state_synced(pi->dcb.state))
1166 for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
1167 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
1168 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
1169 pcmd.u.dcb.app_priority.idx = i;
1170 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
1172 if (err != FW_PORT_DCB_CFG_SUCCESS) {
1173 dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
1178 /* find first empty slot */
1179 if (!pcmd.u.dcb.app_priority.protocolid)
1182 table[i].selector = (pcmd.u.dcb.app_priority.sel_field + 1);
1184 be16_to_cpu(pcmd.u.dcb.app_priority.protocolid);
1186 ffs(pcmd.u.dcb.app_priority.user_prio_map) - 1;
1191 /* Return Priority Group information.
1193 static int cxgb4_cee_peer_getpg(struct net_device *dev, struct cee_pg *pg)
1195 struct fw_port_cmd pcmd;
1196 struct port_info *pi = netdev2pinfo(dev);
1197 struct adapter *adap = pi->adapter;
1201 /* We're always "willing" -- the Switch Fabric always dictates the
1202 * DCBX parameters to us.
1206 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
1207 pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
1208 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
1209 if (err != FW_PORT_DCB_CFG_SUCCESS) {
1210 dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
1213 pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
1215 for (i = 0; i < CXGB4_MAX_PRIORITY; i++)
1216 pg->prio_pg[7 - i] = (pgid >> (i * 4)) & 0xF;
1218 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
1219 pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
1220 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
1221 if (err != FW_PORT_DCB_CFG_SUCCESS) {
1222 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
1227 for (i = 0; i < CXGB4_MAX_PRIORITY; i++)
1228 pg->pg_bw[i] = pcmd.u.dcb.pgrate.pgrate[i];
1230 pg->tcs_supported = pcmd.u.dcb.pgrate.num_tcs_supported;
1235 /* Return Priority Flow Control information.
1237 static int cxgb4_cee_peer_getpfc(struct net_device *dev, struct cee_pfc *pfc)
1239 struct port_info *pi = netdev2pinfo(dev);
1241 cxgb4_getnumtcs(dev, DCB_NUMTCS_ATTR_PFC, &(pfc->tcs_supported));
1243 /* Firmware sends this to us in a formwat that is a bit flipped version
1244 * of spec, correct it before we send it to host. This is taken care of
1245 * by bit shifting in other uses of pfcen
1247 pfc->pfc_en = bitswap_1(pi->dcb.pfcen);
1249 pfc->tcs_supported = pi->dcb.pfc_num_tcs_supported;
1254 const struct dcbnl_rtnl_ops cxgb4_dcb_ops = {
1255 .ieee_getets = cxgb4_ieee_get_ets,
1256 .ieee_getpfc = cxgb4_ieee_get_pfc,
1257 .ieee_getapp = cxgb4_ieee_getapp,
1258 .ieee_setapp = cxgb4_ieee_setapp,
1259 .ieee_peer_getets = cxgb4_ieee_peer_ets,
1260 .ieee_peer_getpfc = cxgb4_ieee_get_pfc,
1263 .getstate = cxgb4_getstate,
1264 .setstate = cxgb4_setstate,
1265 .getpgtccfgtx = cxgb4_getpgtccfg_tx,
1266 .getpgbwgcfgtx = cxgb4_getpgbwgcfg_tx,
1267 .getpgtccfgrx = cxgb4_getpgtccfg_rx,
1268 .getpgbwgcfgrx = cxgb4_getpgbwgcfg_rx,
1269 .setpgtccfgtx = cxgb4_setpgtccfg_tx,
1270 .setpgbwgcfgtx = cxgb4_setpgbwgcfg_tx,
1271 .setpfccfg = cxgb4_setpfccfg,
1272 .getpfccfg = cxgb4_getpfccfg,
1273 .setall = cxgb4_setall,
1274 .getcap = cxgb4_getcap,
1275 .getnumtcs = cxgb4_getnumtcs,
1276 .setnumtcs = cxgb4_setnumtcs,
1277 .getpfcstate = cxgb4_getpfcstate,
1278 .setpfcstate = cxgb4_setpfcstate,
1279 .getapp = cxgb4_getapp,
1280 .setapp = cxgb4_setapp,
1282 /* DCBX configuration */
1283 .getdcbx = cxgb4_getdcbx,
1284 .setdcbx = cxgb4_setdcbx,
1287 .peer_getappinfo = cxgb4_getpeer_app,
1288 .peer_getapptable = cxgb4_getpeerapp_tbl,
1291 .cee_peer_getpg = cxgb4_cee_peer_getpg,
1292 .cee_peer_getpfc = cxgb4_cee_peer_getpfc,