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 /* Initialize a port's Data Center Bridging state. Typically used after a
26 void cxgb4_dcb_state_init(struct net_device *dev)
28 struct port_info *pi = netdev2pinfo(dev);
29 struct port_dcb_info *dcb = &pi->dcb;
31 memset(dcb, 0, sizeof(struct port_dcb_info));
32 dcb->state = CXGB4_DCB_STATE_START;
35 /* Finite State machine for Data Center Bridging.
37 void cxgb4_dcb_state_fsm(struct net_device *dev,
38 enum cxgb4_dcb_state_input input)
40 struct port_info *pi = netdev2pinfo(dev);
41 struct port_dcb_info *dcb = &pi->dcb;
42 struct adapter *adap = pi->adapter;
45 case CXGB4_DCB_INPUT_FW_DISABLED: {
46 /* Firmware tells us it's not doing DCB */
48 case CXGB4_DCB_STATE_START: {
49 /* we're going to use Host DCB */
50 dcb->state = CXGB4_DCB_STATE_HOST;
51 dcb->supported = CXGB4_DCBX_HOST_SUPPORT;
56 case CXGB4_DCB_STATE_HOST: {
57 /* we're alreaady in Host DCB mode */
62 goto bad_state_transition;
67 case CXGB4_DCB_INPUT_FW_ENABLED: {
68 /* Firmware tells us that it is doing DCB */
70 case CXGB4_DCB_STATE_START: {
71 /* we're going to use Firmware DCB */
72 dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE;
73 dcb->supported = CXGB4_DCBX_FW_SUPPORT;
77 case CXGB4_DCB_STATE_FW_INCOMPLETE:
78 case CXGB4_DCB_STATE_FW_ALLSYNCED: {
79 /* we're alreaady in firmware DCB mode */
84 goto bad_state_transition;
89 case CXGB4_DCB_INPUT_FW_INCOMPLETE: {
90 /* Firmware tells us that its DCB state is incomplete */
92 case CXGB4_DCB_STATE_FW_INCOMPLETE: {
93 /* we're already incomplete */
97 case CXGB4_DCB_STATE_FW_ALLSYNCED: {
98 /* We were successfully running with firmware DCB but
99 * now it's telling us that it's in an "incomplete
100 * state. We need to reset back to a ground state
103 cxgb4_dcb_state_init(dev);
104 dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE;
105 dcb->supported = CXGB4_DCBX_FW_SUPPORT;
106 linkwatch_fire_event(dev);
111 goto bad_state_transition;
116 case CXGB4_DCB_INPUT_FW_ALLSYNCED: {
117 /* Firmware tells us that its DCB state is complete */
118 switch (dcb->state) {
119 case CXGB4_DCB_STATE_FW_INCOMPLETE: {
120 dcb->state = CXGB4_DCB_STATE_FW_ALLSYNCED;
122 linkwatch_fire_event(dev);
126 case CXGB4_DCB_STATE_FW_ALLSYNCED: {
127 /* we're already all sync'ed */
132 goto bad_state_transition;
138 goto bad_state_input;
143 dev_err(adap->pdev_dev, "cxgb4_dcb_state_fsm: illegal input symbol %d\n",
147 bad_state_transition:
148 dev_err(adap->pdev_dev, "cxgb4_dcb_state_fsm: bad state transition, state = %d, input = %d\n",
152 /* Handle a DCB/DCBX update message from the firmware.
154 void cxgb4_dcb_handle_fw_update(struct adapter *adap,
155 const struct fw_port_cmd *pcmd)
157 const union fw_port_dcb *fwdcb = &pcmd->u.dcb;
158 int port = FW_PORT_CMD_PORTID_GET(be32_to_cpu(pcmd->op_to_portid));
159 struct net_device *dev = adap->port[port];
160 struct port_info *pi = netdev_priv(dev);
161 struct port_dcb_info *dcb = &pi->dcb;
162 int dcb_type = pcmd->u.dcb.pgid.type;
164 /* Handle Firmware DCB Control messages separately since they drive
167 if (dcb_type == FW_PORT_DCB_TYPE_CONTROL) {
168 enum cxgb4_dcb_state_input input =
169 ((pcmd->u.dcb.control.all_syncd_pkd &
170 FW_PORT_CMD_ALL_SYNCD)
171 ? CXGB4_DCB_STATE_FW_ALLSYNCED
172 : CXGB4_DCB_STATE_FW_INCOMPLETE);
174 cxgb4_dcb_state_fsm(dev, input);
178 /* It's weird, and almost certainly an error, to get Firmware DCB
179 * messages when we either haven't been told whether we're going to be
180 * doing Host or Firmware DCB; and even worse when we've been told
181 * that we're doing Host DCB!
183 if (dcb->state == CXGB4_DCB_STATE_START ||
184 dcb->state == CXGB4_DCB_STATE_HOST) {
185 dev_err(adap->pdev_dev, "Receiving Firmware DCB messages in State %d\n",
190 /* Now handle the general Firmware DCB update messages ...
193 case FW_PORT_DCB_TYPE_PGID:
194 dcb->pgid = be32_to_cpu(fwdcb->pgid.pgid);
195 dcb->msgs |= CXGB4_DCB_FW_PGID;
198 case FW_PORT_DCB_TYPE_PGRATE:
199 dcb->pg_num_tcs_supported = fwdcb->pgrate.num_tcs_supported;
200 memcpy(dcb->pgrate, &fwdcb->pgrate.pgrate,
201 sizeof(dcb->pgrate));
202 dcb->msgs |= CXGB4_DCB_FW_PGRATE;
205 case FW_PORT_DCB_TYPE_PRIORATE:
206 memcpy(dcb->priorate, &fwdcb->priorate.strict_priorate,
207 sizeof(dcb->priorate));
208 dcb->msgs |= CXGB4_DCB_FW_PRIORATE;
211 case FW_PORT_DCB_TYPE_PFC:
212 dcb->pfcen = fwdcb->pfc.pfcen;
213 dcb->pfc_num_tcs_supported = fwdcb->pfc.max_pfc_tcs;
214 dcb->msgs |= CXGB4_DCB_FW_PFC;
217 case FW_PORT_DCB_TYPE_APP_ID: {
218 const struct fw_port_app_priority *fwap = &fwdcb->app_priority;
220 struct app_priority *ap = &dcb->app_priority[idx];
222 struct dcb_app app = {
223 .selector = fwap->sel_field,
224 .protocol = be16_to_cpu(fwap->protocolid),
225 .priority = fwap->user_prio_map,
229 err = dcb_setapp(dev, &app);
231 dev_err(adap->pdev_dev,
232 "Failed DCB Set Application Priority: sel=%d, prot=%d, prio=%d, err=%d\n",
233 app.selector, app.protocol, app.priority, -err);
235 ap->user_prio_map = fwap->user_prio_map;
236 ap->sel_field = fwap->sel_field;
237 ap->protocolid = be16_to_cpu(fwap->protocolid);
238 dcb->msgs |= CXGB4_DCB_FW_APP_ID;
243 dev_err(adap->pdev_dev, "Unknown DCB update type received %x\n",
249 /* Data Center Bridging netlink operations.
253 /* Get current DCB enabled/disabled state.
255 static u8 cxgb4_getstate(struct net_device *dev)
257 struct port_info *pi = netdev2pinfo(dev);
259 return pi->dcb.enabled;
262 /* Set DCB enabled/disabled.
264 static u8 cxgb4_setstate(struct net_device *dev, u8 enabled)
266 struct port_info *pi = netdev2pinfo(dev);
268 /* Firmware doesn't provide any mechanism to control the DCB state.
270 if (enabled != (pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED))
276 static void cxgb4_getpgtccfg(struct net_device *dev, int tc,
277 u8 *prio_type, u8 *pgid, u8 *bw_per,
278 u8 *up_tc_map, int local)
280 struct fw_port_cmd pcmd;
281 struct port_info *pi = netdev2pinfo(dev);
282 struct adapter *adap = pi->adapter;
285 *prio_type = *pgid = *bw_per = *up_tc_map = 0;
288 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
290 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
292 pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
293 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
294 if (err != FW_PORT_DCB_CFG_SUCCESS) {
295 dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
298 *pgid = (be32_to_cpu(pcmd.u.dcb.pgid.pgid) >> (tc * 4)) & 0xf;
300 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
301 pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
302 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
303 if (err != FW_PORT_DCB_CFG_SUCCESS) {
304 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
309 *bw_per = pcmd.u.dcb.pgrate.pgrate[*pgid];
310 *up_tc_map = (1 << tc);
312 /* prio_type is link strict */
316 static void cxgb4_getpgtccfg_tx(struct net_device *dev, int tc,
317 u8 *prio_type, u8 *pgid, u8 *bw_per,
320 return cxgb4_getpgtccfg(dev, tc, prio_type, pgid, bw_per, up_tc_map, 1);
324 static void cxgb4_getpgtccfg_rx(struct net_device *dev, int tc,
325 u8 *prio_type, u8 *pgid, u8 *bw_per,
328 return cxgb4_getpgtccfg(dev, tc, prio_type, pgid, bw_per, up_tc_map, 0);
331 static void cxgb4_setpgtccfg_tx(struct net_device *dev, int tc,
332 u8 prio_type, u8 pgid, u8 bw_per,
335 struct fw_port_cmd pcmd;
336 struct port_info *pi = netdev2pinfo(dev);
337 struct adapter *adap = pi->adapter;
341 if (pgid == DCB_ATTR_VALUE_UNDEFINED)
343 if (bw_per == DCB_ATTR_VALUE_UNDEFINED)
346 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
347 pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
349 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
350 if (err != FW_PORT_DCB_CFG_SUCCESS) {
351 dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
355 _pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
356 _pgid &= ~(0xF << (tc * 4));
357 _pgid |= pgid << (tc * 4);
358 pcmd.u.dcb.pgid.pgid = cpu_to_be32(_pgid);
360 INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
362 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
363 if (err != FW_PORT_DCB_CFG_SUCCESS) {
364 dev_err(adap->pdev_dev, "DCB write PGID failed with %d\n",
369 memset(&pcmd, 0, sizeof(struct fw_port_cmd));
371 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
372 pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
374 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
375 if (err != FW_PORT_DCB_CFG_SUCCESS) {
376 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
381 pcmd.u.dcb.pgrate.pgrate[pgid] = bw_per;
383 INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
384 if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
385 pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY);
387 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
388 if (err != FW_PORT_DCB_CFG_SUCCESS)
389 dev_err(adap->pdev_dev, "DCB write PGRATE failed with %d\n",
393 static void cxgb4_getpgbwgcfg(struct net_device *dev, int pgid, u8 *bw_per,
396 struct fw_port_cmd pcmd;
397 struct port_info *pi = netdev2pinfo(dev);
398 struct adapter *adap = pi->adapter;
402 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
404 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
406 pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
407 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
408 if (err != FW_PORT_DCB_CFG_SUCCESS) {
409 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
412 *bw_per = pcmd.u.dcb.pgrate.pgrate[pgid];
416 static void cxgb4_getpgbwgcfg_tx(struct net_device *dev, int pgid, u8 *bw_per)
418 return cxgb4_getpgbwgcfg(dev, pgid, bw_per, 1);
421 static void cxgb4_getpgbwgcfg_rx(struct net_device *dev, int pgid, u8 *bw_per)
423 return cxgb4_getpgbwgcfg(dev, pgid, bw_per, 0);
426 static void cxgb4_setpgbwgcfg_tx(struct net_device *dev, int pgid,
429 struct fw_port_cmd pcmd;
430 struct port_info *pi = netdev2pinfo(dev);
431 struct adapter *adap = pi->adapter;
434 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
435 pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
437 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
438 if (err != FW_PORT_DCB_CFG_SUCCESS) {
439 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
444 pcmd.u.dcb.pgrate.pgrate[pgid] = bw_per;
446 INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
447 if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
448 pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY);
450 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
452 if (err != FW_PORT_DCB_CFG_SUCCESS)
453 dev_err(adap->pdev_dev, "DCB write PGRATE failed with %d\n",
457 /* Return whether the specified Traffic Class Priority has Priority Pause
460 static void cxgb4_getpfccfg(struct net_device *dev, int priority, u8 *pfccfg)
462 struct port_info *pi = netdev2pinfo(dev);
463 struct port_dcb_info *dcb = &pi->dcb;
465 if (dcb->state != CXGB4_DCB_STATE_FW_ALLSYNCED ||
466 priority >= CXGB4_MAX_PRIORITY)
469 *pfccfg = (pi->dcb.pfcen >> priority) & 1;
472 /* Enable/disable Priority Pause Frames for the specified Traffic Class
475 static void cxgb4_setpfccfg(struct net_device *dev, int priority, u8 pfccfg)
477 struct fw_port_cmd pcmd;
478 struct port_info *pi = netdev2pinfo(dev);
479 struct adapter *adap = pi->adapter;
482 if (pi->dcb.state != CXGB4_DCB_STATE_FW_ALLSYNCED ||
483 priority >= CXGB4_MAX_PRIORITY)
486 INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
487 if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
488 pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY);
490 pcmd.u.dcb.pfc.type = FW_PORT_DCB_TYPE_PFC;
491 pcmd.u.dcb.pfc.pfcen = pi->dcb.pfcen;
494 pcmd.u.dcb.pfc.pfcen |= (1 << priority);
496 pcmd.u.dcb.pfc.pfcen &= (~(1 << priority));
498 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
499 if (err != FW_PORT_DCB_CFG_SUCCESS) {
500 dev_err(adap->pdev_dev, "DCB PFC write failed with %d\n", -err);
504 pi->dcb.pfcen = pcmd.u.dcb.pfc.pfcen;
507 static u8 cxgb4_setall(struct net_device *dev)
512 /* Return DCB capabilities.
514 static u8 cxgb4_getcap(struct net_device *dev, int cap_id, u8 *caps)
516 struct port_info *pi = netdev2pinfo(dev);
519 case DCB_CAP_ATTR_PG:
520 case DCB_CAP_ATTR_PFC:
524 case DCB_CAP_ATTR_PG_TCS:
525 /* 8 priorities for PG represented by bitmap */
529 case DCB_CAP_ATTR_PFC_TCS:
530 /* 8 priorities for PFC represented by bitmap */
534 case DCB_CAP_ATTR_GSP:
538 case DCB_CAP_ATTR_UP2TC:
539 case DCB_CAP_ATTR_BCN:
543 case DCB_CAP_ATTR_DCBX:
544 *caps = pi->dcb.supported;
554 /* Return the number of Traffic Classes for the indicated Traffic Class ID.
556 static int cxgb4_getnumtcs(struct net_device *dev, int tcs_id, u8 *num)
558 struct port_info *pi = netdev2pinfo(dev);
561 case DCB_NUMTCS_ATTR_PG:
562 if (pi->dcb.msgs & CXGB4_DCB_FW_PGRATE)
563 *num = pi->dcb.pg_num_tcs_supported;
568 case DCB_NUMTCS_ATTR_PFC:
579 /* Set the number of Traffic Classes supported for the indicated Traffic Class
582 static int cxgb4_setnumtcs(struct net_device *dev, int tcs_id, u8 num)
584 /* Setting the number of Traffic Classes isn't supported.
589 /* Return whether Priority Flow Control is enabled. */
590 static u8 cxgb4_getpfcstate(struct net_device *dev)
592 struct port_info *pi = netdev2pinfo(dev);
594 if (pi->dcb.state != CXGB4_DCB_STATE_FW_ALLSYNCED)
597 return pi->dcb.pfcen != 0;
600 /* Enable/disable Priority Flow Control. */
601 static void cxgb4_setpfcstate(struct net_device *dev, u8 state)
603 /* We can't enable/disable Priority Flow Control but we also can't
604 * return an error ...
608 /* Return the Application User Priority Map associated with the specified
611 static int __cxgb4_getapp(struct net_device *dev, u8 app_idtype, u16 app_id,
614 struct port_info *pi = netdev2pinfo(dev);
615 struct adapter *adap = pi->adapter;
618 if (pi->dcb.state != CXGB4_DCB_STATE_FW_ALLSYNCED)
621 for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
622 struct fw_port_cmd pcmd;
626 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
628 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
630 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
631 pcmd.u.dcb.app_priority.idx = i;
633 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
634 if (err != FW_PORT_DCB_CFG_SUCCESS) {
635 dev_err(adap->pdev_dev, "DCB APP read failed with %d\n",
639 if (be16_to_cpu(pcmd.u.dcb.app_priority.protocolid) == app_id)
640 return pcmd.u.dcb.app_priority.user_prio_map;
642 /* exhausted app list */
643 if (!pcmd.u.dcb.app_priority.protocolid)
650 /* Return the Application User Priority Map associated with the specified
653 static int cxgb4_getapp(struct net_device *dev, u8 app_idtype, u16 app_id)
655 return __cxgb4_getapp(dev, app_idtype, app_id, 0);
658 /* Write a new Application User Priority Map for the specified Application ID
660 static int cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id,
663 struct fw_port_cmd pcmd;
664 struct port_info *pi = netdev2pinfo(dev);
665 struct adapter *adap = pi->adapter;
669 if (pi->dcb.state != CXGB4_DCB_STATE_FW_ALLSYNCED)
672 /* DCB info gets thrown away on link up */
673 if (!netif_carrier_ok(dev))
676 if (app_idtype != DCB_APP_IDTYPE_ETHTYPE &&
677 app_idtype != DCB_APP_IDTYPE_PORTNUM)
680 for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
681 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
682 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
683 pcmd.u.dcb.app_priority.idx = i;
684 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
686 if (err != FW_PORT_DCB_CFG_SUCCESS) {
687 dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
691 if (be16_to_cpu(pcmd.u.dcb.app_priority.protocolid) == app_id) {
692 /* overwrite existing app table */
693 pcmd.u.dcb.app_priority.protocolid = 0;
696 /* find first empty slot */
697 if (!pcmd.u.dcb.app_priority.protocolid)
701 if (i == CXGB4_MAX_DCBX_APP_SUPPORTED) {
702 /* no empty slots available */
703 dev_err(adap->pdev_dev, "DCB app table full\n");
707 /* write out new app table entry */
708 INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
709 if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
710 pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY);
712 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
713 pcmd.u.dcb.app_priority.protocolid = cpu_to_be16(app_id);
714 pcmd.u.dcb.app_priority.sel_field = app_idtype;
715 pcmd.u.dcb.app_priority.user_prio_map = app_prio;
716 pcmd.u.dcb.app_priority.idx = i;
718 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
719 if (err != FW_PORT_DCB_CFG_SUCCESS) {
720 dev_err(adap->pdev_dev, "DCB app table write failed with %d\n",
728 /* Return whether IEEE Data Center Bridging has been negotiated.
730 static inline int cxgb4_ieee_negotiation_complete(struct net_device *dev)
732 struct port_info *pi = netdev2pinfo(dev);
733 struct port_dcb_info *dcb = &pi->dcb;
735 return (dcb->state == CXGB4_DCB_STATE_FW_ALLSYNCED &&
736 (dcb->supported & DCB_CAP_DCBX_VER_IEEE));
739 /* Fill in the Application User Priority Map associated with the
740 * specified Application.
742 static int cxgb4_ieee_getapp(struct net_device *dev, struct dcb_app *app)
746 if (!cxgb4_ieee_negotiation_complete(dev))
748 if (!(app->selector && app->protocol))
751 prio = dcb_getapp(dev, app);
753 /* If app doesn't exist in dcb_app table, try firmware
756 prio = __cxgb4_getapp(dev, app->selector, app->protocol, 0);
759 app->priority = prio;
763 /* Write a new Application User Priority Map for the specified App id. */
764 static int cxgb4_ieee_setapp(struct net_device *dev, struct dcb_app *app)
766 if (!cxgb4_ieee_negotiation_complete(dev))
768 if (!(app->selector && app->protocol && app->priority))
771 cxgb4_setapp(dev, app->selector, app->protocol, app->priority);
772 return dcb_setapp(dev, app);
775 /* Return our DCBX parameters.
777 static u8 cxgb4_getdcbx(struct net_device *dev)
779 struct port_info *pi = netdev2pinfo(dev);
781 /* This is already set by cxgb4_set_dcb_caps, so just return it */
782 return pi->dcb.supported;
785 /* Set our DCBX parameters.
787 static u8 cxgb4_setdcbx(struct net_device *dev, u8 dcb_request)
789 struct port_info *pi = netdev2pinfo(dev);
791 /* Filter out requests which exceed our capabilities.
793 if ((dcb_request & (CXGB4_DCBX_FW_SUPPORT | CXGB4_DCBX_HOST_SUPPORT))
797 /* Can't set DCBX capabilities if DCBX isn't enabled. */
801 /* There's currently no mechanism to allow for the firmware DCBX
802 * negotiation to be changed from the Host Driver. If the caller
803 * requests exactly the same parameters that we already have then
804 * we'll allow them to be successfully "set" ...
806 if (dcb_request != pi->dcb.supported)
809 pi->dcb.supported = dcb_request;
813 static int cxgb4_getpeer_app(struct net_device *dev,
814 struct dcb_peer_app_info *info, u16 *app_count)
816 struct fw_port_cmd pcmd;
817 struct port_info *pi = netdev2pinfo(dev);
818 struct adapter *adap = pi->adapter;
821 if (pi->dcb.state != CXGB4_DCB_STATE_FW_ALLSYNCED)
828 for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
829 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
830 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
831 pcmd.u.dcb.app_priority.idx = *app_count;
832 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
834 if (err != FW_PORT_DCB_CFG_SUCCESS) {
835 dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
840 /* find first empty slot */
841 if (!pcmd.u.dcb.app_priority.protocolid)
848 static int cxgb4_getpeerapp_tbl(struct net_device *dev, struct dcb_app *table)
850 struct fw_port_cmd pcmd;
851 struct port_info *pi = netdev2pinfo(dev);
852 struct adapter *adap = pi->adapter;
855 if (pi->dcb.state != CXGB4_DCB_STATE_FW_ALLSYNCED)
858 for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
859 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
860 pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
861 pcmd.u.dcb.app_priority.idx = i;
862 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
864 if (err != FW_PORT_DCB_CFG_SUCCESS) {
865 dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
870 /* find first empty slot */
871 if (!pcmd.u.dcb.app_priority.protocolid)
874 table[i].selector = pcmd.u.dcb.app_priority.sel_field;
876 be16_to_cpu(pcmd.u.dcb.app_priority.protocolid);
877 table[i].priority = pcmd.u.dcb.app_priority.user_prio_map;
882 /* Return Priority Group information.
884 static int cxgb4_cee_peer_getpg(struct net_device *dev, struct cee_pg *pg)
886 struct fw_port_cmd pcmd;
887 struct port_info *pi = netdev2pinfo(dev);
888 struct adapter *adap = pi->adapter;
892 /* We're always "willing" -- the Switch Fabric always dictates the
893 * DCBX parameters to us.
897 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
898 pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
899 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
900 if (err != FW_PORT_DCB_CFG_SUCCESS) {
901 dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
904 pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
906 for (i = 0; i < CXGB4_MAX_PRIORITY; i++)
907 pg->prio_pg[i] = (pgid >> (i * 4)) & 0xF;
909 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
910 pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
911 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
912 if (err != FW_PORT_DCB_CFG_SUCCESS) {
913 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
918 for (i = 0; i < CXGB4_MAX_PRIORITY; i++)
919 pg->pg_bw[i] = pcmd.u.dcb.pgrate.pgrate[i];
924 /* Return Priority Flow Control information.
926 static int cxgb4_cee_peer_getpfc(struct net_device *dev, struct cee_pfc *pfc)
928 struct port_info *pi = netdev2pinfo(dev);
930 cxgb4_getnumtcs(dev, DCB_NUMTCS_ATTR_PFC, &(pfc->tcs_supported));
931 pfc->pfc_en = pi->dcb.pfcen;
936 const struct dcbnl_rtnl_ops cxgb4_dcb_ops = {
937 .ieee_getapp = cxgb4_ieee_getapp,
938 .ieee_setapp = cxgb4_ieee_setapp,
941 .getstate = cxgb4_getstate,
942 .setstate = cxgb4_setstate,
943 .getpgtccfgtx = cxgb4_getpgtccfg_tx,
944 .getpgbwgcfgtx = cxgb4_getpgbwgcfg_tx,
945 .getpgtccfgrx = cxgb4_getpgtccfg_rx,
946 .getpgbwgcfgrx = cxgb4_getpgbwgcfg_rx,
947 .setpgtccfgtx = cxgb4_setpgtccfg_tx,
948 .setpgbwgcfgtx = cxgb4_setpgbwgcfg_tx,
949 .setpfccfg = cxgb4_setpfccfg,
950 .getpfccfg = cxgb4_getpfccfg,
951 .setall = cxgb4_setall,
952 .getcap = cxgb4_getcap,
953 .getnumtcs = cxgb4_getnumtcs,
954 .setnumtcs = cxgb4_setnumtcs,
955 .getpfcstate = cxgb4_getpfcstate,
956 .setpfcstate = cxgb4_setpfcstate,
957 .getapp = cxgb4_getapp,
958 .setapp = cxgb4_setapp,
960 /* DCBX configuration */
961 .getdcbx = cxgb4_getdcbx,
962 .setdcbx = cxgb4_setdcbx,
965 .peer_getappinfo = cxgb4_getpeer_app,
966 .peer_getapptable = cxgb4_getpeerapp_tbl,
969 .cee_peer_getpg = cxgb4_cee_peer_getpg,
970 .cee_peer_getpfc = cxgb4_cee_peer_getpfc,