1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2013-2014 Chelsio Communications. All rights reserved.
5 * Written by Anish Bhatt (anish@chelsio.com)
6 * Casey Leedom (leedom@chelsio.com)
11 /* DCBx version control
13 const char * const dcb_ver_array
[] = {
22 static inline bool cxgb4_dcb_state_synced(enum cxgb4_dcb_state state
)
24 if (state
== CXGB4_DCB_STATE_FW_ALLSYNCED
||
25 state
== CXGB4_DCB_STATE_HOST
)
31 /* Initialize a port's Data Center Bridging state.
33 void cxgb4_dcb_state_init(struct net_device
*dev
)
35 struct port_info
*pi
= netdev2pinfo(dev
);
36 struct port_dcb_info
*dcb
= &pi
->dcb
;
37 int version_temp
= dcb
->dcb_version
;
39 memset(dcb
, 0, sizeof(struct port_dcb_info
));
40 dcb
->state
= CXGB4_DCB_STATE_START
;
42 dcb
->dcb_version
= version_temp
;
44 netdev_dbg(dev
, "%s: Initializing DCB state for port[%d]\n",
45 __func__
, pi
->port_id
);
48 void cxgb4_dcb_version_init(struct net_device
*dev
)
50 struct port_info
*pi
= netdev2pinfo(dev
);
51 struct port_dcb_info
*dcb
= &pi
->dcb
;
53 /* Any writes here are only done on kernels that exlicitly need
54 * a specific version, say < 2.6.38 which only support CEE
56 dcb
->dcb_version
= FW_PORT_DCB_VER_AUTO
;
59 static void cxgb4_dcb_cleanup_apps(struct net_device
*dev
)
61 struct port_info
*pi
= netdev2pinfo(dev
);
62 struct adapter
*adap
= pi
->adapter
;
63 struct port_dcb_info
*dcb
= &pi
->dcb
;
67 /* zero priority implies remove */
70 for (i
= 0; i
< CXGB4_MAX_DCBX_APP_SUPPORTED
; i
++) {
71 /* Check if app list is exhausted */
72 if (!dcb
->app_priority
[i
].protocolid
)
75 app
.protocol
= dcb
->app_priority
[i
].protocolid
;
77 if (dcb
->dcb_version
== FW_PORT_DCB_VER_IEEE
) {
78 app
.priority
= dcb
->app_priority
[i
].user_prio_map
;
79 app
.selector
= dcb
->app_priority
[i
].sel_field
+ 1;
80 err
= dcb_ieee_delapp(dev
, &app
);
82 app
.selector
= !!(dcb
->app_priority
[i
].sel_field
);
83 err
= dcb_setapp(dev
, &app
);
87 dev_err(adap
->pdev_dev
,
88 "Failed DCB Clear %s Application Priority: sel=%d, prot=%d, , err=%d\n",
89 dcb_ver_array
[dcb
->dcb_version
], app
.selector
,
96 /* Reset a port's Data Center Bridging state. Typically used after a
99 void cxgb4_dcb_reset(struct net_device
*dev
)
101 cxgb4_dcb_cleanup_apps(dev
);
102 cxgb4_dcb_state_init(dev
);
105 /* update the dcb port support, if version is IEEE then set it to
106 * FW_PORT_DCB_VER_IEEE and if DCB_CAP_DCBX_VER_CEE is already set then
107 * clear that. and if it is set to CEE then set dcb supported to
108 * DCB_CAP_DCBX_VER_CEE & if DCB_CAP_DCBX_VER_IEEE is set, clear it
110 static inline void cxgb4_dcb_update_support(struct port_dcb_info
*dcb
)
112 if (dcb
->dcb_version
== FW_PORT_DCB_VER_IEEE
) {
113 if (dcb
->supported
& DCB_CAP_DCBX_VER_CEE
)
114 dcb
->supported
&= ~DCB_CAP_DCBX_VER_CEE
;
115 dcb
->supported
|= DCB_CAP_DCBX_VER_IEEE
;
116 } else if (dcb
->dcb_version
== FW_PORT_DCB_VER_CEE1D01
) {
117 if (dcb
->supported
& DCB_CAP_DCBX_VER_IEEE
)
118 dcb
->supported
&= ~DCB_CAP_DCBX_VER_IEEE
;
119 dcb
->supported
|= DCB_CAP_DCBX_VER_CEE
;
123 /* Finite State machine for Data Center Bridging.
125 void cxgb4_dcb_state_fsm(struct net_device
*dev
,
126 enum cxgb4_dcb_state_input transition_to
)
128 struct port_info
*pi
= netdev2pinfo(dev
);
129 struct port_dcb_info
*dcb
= &pi
->dcb
;
130 struct adapter
*adap
= pi
->adapter
;
131 enum cxgb4_dcb_state current_state
= dcb
->state
;
133 netdev_dbg(dev
, "%s: State change from %d to %d for %s\n",
134 __func__
, dcb
->state
, transition_to
, dev
->name
);
136 switch (current_state
) {
137 case CXGB4_DCB_STATE_START
: {
138 switch (transition_to
) {
139 case CXGB4_DCB_INPUT_FW_DISABLED
: {
140 /* we're going to use Host DCB */
141 dcb
->state
= CXGB4_DCB_STATE_HOST
;
142 dcb
->supported
= CXGB4_DCBX_HOST_SUPPORT
;
146 case CXGB4_DCB_INPUT_FW_ENABLED
: {
147 /* we're going to use Firmware DCB */
148 dcb
->state
= CXGB4_DCB_STATE_FW_INCOMPLETE
;
149 dcb
->supported
= DCB_CAP_DCBX_LLD_MANAGED
;
150 if (dcb
->dcb_version
== FW_PORT_DCB_VER_IEEE
)
151 dcb
->supported
|= DCB_CAP_DCBX_VER_IEEE
;
153 dcb
->supported
|= DCB_CAP_DCBX_VER_CEE
;
157 case CXGB4_DCB_INPUT_FW_INCOMPLETE
: {
158 /* expected transition */
162 case CXGB4_DCB_INPUT_FW_ALLSYNCED
: {
163 dcb
->state
= CXGB4_DCB_STATE_FW_ALLSYNCED
;
168 goto bad_state_input
;
173 case CXGB4_DCB_STATE_FW_INCOMPLETE
: {
174 if (transition_to
!= CXGB4_DCB_INPUT_FW_DISABLED
) {
175 /* during this CXGB4_DCB_STATE_FW_INCOMPLETE state,
176 * check if the dcb version is changed (there can be
177 * mismatch in default config & the negotiated switch
178 * configuration at FW, so update the dcb support
181 cxgb4_dcb_update_support(dcb
);
183 switch (transition_to
) {
184 case CXGB4_DCB_INPUT_FW_ENABLED
: {
185 /* we're alreaady in firmware DCB mode */
189 case CXGB4_DCB_INPUT_FW_INCOMPLETE
: {
190 /* we're already incomplete */
194 case CXGB4_DCB_INPUT_FW_ALLSYNCED
: {
195 dcb
->state
= CXGB4_DCB_STATE_FW_ALLSYNCED
;
197 linkwatch_fire_event(dev
);
202 goto bad_state_input
;
207 case CXGB4_DCB_STATE_FW_ALLSYNCED
: {
208 switch (transition_to
) {
209 case CXGB4_DCB_INPUT_FW_ENABLED
: {
210 /* we're alreaady in firmware DCB mode */
214 case CXGB4_DCB_INPUT_FW_INCOMPLETE
: {
215 /* We were successfully running with firmware DCB but
216 * now it's telling us that it's in an "incomplete
217 * state. We need to reset back to a ground state
220 cxgb4_dcb_reset(dev
);
221 dcb
->state
= CXGB4_DCB_STATE_FW_INCOMPLETE
;
222 dcb
->supported
= CXGB4_DCBX_FW_SUPPORT
;
223 linkwatch_fire_event(dev
);
227 case CXGB4_DCB_INPUT_FW_ALLSYNCED
: {
228 /* we're already all sync'ed
229 * this is only applicable for IEEE or
230 * when another VI already completed negotiaton
233 linkwatch_fire_event(dev
);
238 goto bad_state_input
;
243 case CXGB4_DCB_STATE_HOST
: {
244 switch (transition_to
) {
245 case CXGB4_DCB_INPUT_FW_DISABLED
: {
246 /* we're alreaady in Host DCB mode */
251 goto bad_state_input
;
257 goto bad_state_transition
;
262 dev_err(adap
->pdev_dev
, "cxgb4_dcb_state_fsm: illegal input symbol %d\n",
266 bad_state_transition
:
267 dev_err(adap
->pdev_dev
, "cxgb4_dcb_state_fsm: bad state transition, state = %d, input = %d\n",
268 current_state
, transition_to
);
271 /* Handle a DCB/DCBX update message from the firmware.
273 void cxgb4_dcb_handle_fw_update(struct adapter
*adap
,
274 const struct fw_port_cmd
*pcmd
)
276 const union fw_port_dcb
*fwdcb
= &pcmd
->u
.dcb
;
277 int port
= FW_PORT_CMD_PORTID_G(be32_to_cpu(pcmd
->op_to_portid
));
278 struct net_device
*dev
= adap
->port
[adap
->chan_map
[port
]];
279 struct port_info
*pi
= netdev_priv(dev
);
280 struct port_dcb_info
*dcb
= &pi
->dcb
;
281 int dcb_type
= pcmd
->u
.dcb
.pgid
.type
;
282 int dcb_running_version
;
284 /* Handle Firmware DCB Control messages separately since they drive
287 if (dcb_type
== FW_PORT_DCB_TYPE_CONTROL
) {
288 enum cxgb4_dcb_state_input input
=
289 ((pcmd
->u
.dcb
.control
.all_syncd_pkd
&
290 FW_PORT_CMD_ALL_SYNCD_F
)
291 ? CXGB4_DCB_INPUT_FW_ALLSYNCED
292 : CXGB4_DCB_INPUT_FW_INCOMPLETE
);
294 if (dcb
->dcb_version
!= FW_PORT_DCB_VER_UNKNOWN
) {
295 dcb_running_version
= FW_PORT_CMD_DCB_VERSION_G(
297 pcmd
->u
.dcb
.control
.dcb_version_to_app_state
));
298 if (dcb_running_version
== FW_PORT_DCB_VER_CEE1D01
||
299 dcb_running_version
== FW_PORT_DCB_VER_IEEE
) {
300 dcb
->dcb_version
= dcb_running_version
;
301 dev_warn(adap
->pdev_dev
, "Interface %s is running %s\n",
303 dcb_ver_array
[dcb
->dcb_version
]);
305 dev_warn(adap
->pdev_dev
,
306 "Something screwed up, requested firmware for %s, but firmware returned %s instead\n",
307 dcb_ver_array
[dcb
->dcb_version
],
308 dcb_ver_array
[dcb_running_version
]);
309 dcb
->dcb_version
= FW_PORT_DCB_VER_UNKNOWN
;
313 cxgb4_dcb_state_fsm(dev
, input
);
317 /* It's weird, and almost certainly an error, to get Firmware DCB
318 * messages when we either haven't been told whether we're going to be
319 * doing Host or Firmware DCB; and even worse when we've been told
320 * that we're doing Host DCB!
322 if (dcb
->state
== CXGB4_DCB_STATE_START
||
323 dcb
->state
== CXGB4_DCB_STATE_HOST
) {
324 dev_err(adap
->pdev_dev
, "Receiving Firmware DCB messages in State %d\n",
329 /* Now handle the general Firmware DCB update messages ...
332 case FW_PORT_DCB_TYPE_PGID
:
333 dcb
->pgid
= be32_to_cpu(fwdcb
->pgid
.pgid
);
334 dcb
->msgs
|= CXGB4_DCB_FW_PGID
;
337 case FW_PORT_DCB_TYPE_PGRATE
:
338 dcb
->pg_num_tcs_supported
= fwdcb
->pgrate
.num_tcs_supported
;
339 memcpy(dcb
->pgrate
, &fwdcb
->pgrate
.pgrate
,
340 sizeof(dcb
->pgrate
));
341 memcpy(dcb
->tsa
, &fwdcb
->pgrate
.tsa
,
343 dcb
->msgs
|= CXGB4_DCB_FW_PGRATE
;
344 if (dcb
->msgs
& CXGB4_DCB_FW_PGID
)
345 IEEE_FAUX_SYNC(dev
, dcb
);
348 case FW_PORT_DCB_TYPE_PRIORATE
:
349 memcpy(dcb
->priorate
, &fwdcb
->priorate
.strict_priorate
,
350 sizeof(dcb
->priorate
));
351 dcb
->msgs
|= CXGB4_DCB_FW_PRIORATE
;
354 case FW_PORT_DCB_TYPE_PFC
:
355 dcb
->pfcen
= fwdcb
->pfc
.pfcen
;
356 dcb
->pfc_num_tcs_supported
= fwdcb
->pfc
.max_pfc_tcs
;
357 dcb
->msgs
|= CXGB4_DCB_FW_PFC
;
358 IEEE_FAUX_SYNC(dev
, dcb
);
361 case FW_PORT_DCB_TYPE_APP_ID
: {
362 const struct fw_port_app_priority
*fwap
= &fwdcb
->app_priority
;
364 struct app_priority
*ap
= &dcb
->app_priority
[idx
];
366 struct dcb_app app
= {
367 .protocol
= be16_to_cpu(fwap
->protocolid
),
371 /* Convert from firmware format to relevant format
372 * when using app selector
374 if (dcb
->dcb_version
== FW_PORT_DCB_VER_IEEE
) {
375 app
.selector
= (fwap
->sel_field
+ 1);
376 app
.priority
= ffs(fwap
->user_prio_map
) - 1;
377 err
= dcb_ieee_setapp(dev
, &app
);
378 IEEE_FAUX_SYNC(dev
, dcb
);
381 app
.selector
= !!(fwap
->sel_field
);
382 app
.priority
= fwap
->user_prio_map
;
383 err
= dcb_setapp(dev
, &app
);
387 dev_err(adap
->pdev_dev
,
388 "Failed DCB Set Application Priority: sel=%d, prot=%d, prio=%d, err=%d\n",
389 app
.selector
, app
.protocol
, app
.priority
, -err
);
391 ap
->user_prio_map
= fwap
->user_prio_map
;
392 ap
->sel_field
= fwap
->sel_field
;
393 ap
->protocolid
= be16_to_cpu(fwap
->protocolid
);
394 dcb
->msgs
|= CXGB4_DCB_FW_APP_ID
;
399 dev_err(adap
->pdev_dev
, "Unknown DCB update type received %x\n",
405 /* Data Center Bridging netlink operations.
409 /* Get current DCB enabled/disabled state.
411 static u8
cxgb4_getstate(struct net_device
*dev
)
413 struct port_info
*pi
= netdev2pinfo(dev
);
415 return pi
->dcb
.enabled
;
418 /* Set DCB enabled/disabled.
420 static u8
cxgb4_setstate(struct net_device
*dev
, u8 enabled
)
422 struct port_info
*pi
= netdev2pinfo(dev
);
424 /* If DCBx is host-managed, dcb is enabled by outside lldp agents */
425 if (pi
->dcb
.state
== CXGB4_DCB_STATE_HOST
) {
426 pi
->dcb
.enabled
= enabled
;
430 /* Firmware doesn't provide any mechanism to control the DCB state.
432 if (enabled
!= (pi
->dcb
.state
== CXGB4_DCB_STATE_FW_ALLSYNCED
))
438 static void cxgb4_getpgtccfg(struct net_device
*dev
, int tc
,
439 u8
*prio_type
, u8
*pgid
, u8
*bw_per
,
440 u8
*up_tc_map
, int local
)
442 struct fw_port_cmd pcmd
;
443 struct port_info
*pi
= netdev2pinfo(dev
);
444 struct adapter
*adap
= pi
->adapter
;
447 *prio_type
= *pgid
= *bw_per
= *up_tc_map
= 0;
450 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd
, pi
->port_id
);
452 INIT_PORT_DCB_READ_PEER_CMD(pcmd
, pi
->port_id
);
454 pcmd
.u
.dcb
.pgid
.type
= FW_PORT_DCB_TYPE_PGID
;
455 err
= t4_wr_mbox(adap
, adap
->mbox
, &pcmd
, sizeof(pcmd
), &pcmd
);
456 if (err
!= FW_PORT_DCB_CFG_SUCCESS
) {
457 dev_err(adap
->pdev_dev
, "DCB read PGID failed with %d\n", -err
);
460 *pgid
= (be32_to_cpu(pcmd
.u
.dcb
.pgid
.pgid
) >> (tc
* 4)) & 0xf;
463 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd
, pi
->port_id
);
465 INIT_PORT_DCB_READ_PEER_CMD(pcmd
, pi
->port_id
);
466 pcmd
.u
.dcb
.pgrate
.type
= FW_PORT_DCB_TYPE_PGRATE
;
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 PGRATE failed with %d\n",
474 *bw_per
= pcmd
.u
.dcb
.pgrate
.pgrate
[*pgid
];
475 *up_tc_map
= (1 << tc
);
477 /* prio_type is link strict */
482 static void cxgb4_getpgtccfg_tx(struct net_device
*dev
, int tc
,
483 u8
*prio_type
, u8
*pgid
, u8
*bw_per
,
486 /* tc 0 is written at MSB position */
487 return cxgb4_getpgtccfg(dev
, (7 - tc
), prio_type
, pgid
, bw_per
,
492 static void cxgb4_getpgtccfg_rx(struct net_device
*dev
, int tc
,
493 u8
*prio_type
, u8
*pgid
, u8
*bw_per
,
496 /* tc 0 is written at MSB position */
497 return cxgb4_getpgtccfg(dev
, (7 - tc
), prio_type
, pgid
, bw_per
,
501 static void cxgb4_setpgtccfg_tx(struct net_device
*dev
, int tc
,
502 u8 prio_type
, u8 pgid
, u8 bw_per
,
505 struct fw_port_cmd pcmd
;
506 struct port_info
*pi
= netdev2pinfo(dev
);
507 struct adapter
*adap
= pi
->adapter
;
512 if (pgid
== DCB_ATTR_VALUE_UNDEFINED
)
514 if (bw_per
== DCB_ATTR_VALUE_UNDEFINED
)
517 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd
, pi
->port_id
);
518 pcmd
.u
.dcb
.pgid
.type
= FW_PORT_DCB_TYPE_PGID
;
520 err
= t4_wr_mbox(adap
, adap
->mbox
, &pcmd
, sizeof(pcmd
), &pcmd
);
521 if (err
!= FW_PORT_DCB_CFG_SUCCESS
) {
522 dev_err(adap
->pdev_dev
, "DCB read PGID failed with %d\n", -err
);
526 _pgid
= be32_to_cpu(pcmd
.u
.dcb
.pgid
.pgid
);
527 _pgid
&= ~(0xF << (fw_tc
* 4));
528 _pgid
|= pgid
<< (fw_tc
* 4);
529 pcmd
.u
.dcb
.pgid
.pgid
= cpu_to_be32(_pgid
);
531 INIT_PORT_DCB_WRITE_CMD(pcmd
, pi
->port_id
);
533 err
= t4_wr_mbox(adap
, adap
->mbox
, &pcmd
, sizeof(pcmd
), &pcmd
);
534 if (err
!= FW_PORT_DCB_CFG_SUCCESS
) {
535 dev_err(adap
->pdev_dev
, "DCB write PGID failed with %d\n",
540 memset(&pcmd
, 0, sizeof(struct fw_port_cmd
));
542 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd
, pi
->port_id
);
543 pcmd
.u
.dcb
.pgrate
.type
= FW_PORT_DCB_TYPE_PGRATE
;
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 read PGRATE failed with %d\n",
552 pcmd
.u
.dcb
.pgrate
.pgrate
[pgid
] = bw_per
;
554 INIT_PORT_DCB_WRITE_CMD(pcmd
, pi
->port_id
);
555 if (pi
->dcb
.state
== CXGB4_DCB_STATE_HOST
)
556 pcmd
.op_to_portid
|= cpu_to_be32(FW_PORT_CMD_APPLY_F
);
558 err
= t4_wr_mbox(adap
, adap
->mbox
, &pcmd
, sizeof(pcmd
), &pcmd
);
559 if (err
!= FW_PORT_DCB_CFG_SUCCESS
)
560 dev_err(adap
->pdev_dev
, "DCB write PGRATE failed with %d\n",
564 static void cxgb4_getpgbwgcfg(struct net_device
*dev
, int pgid
, u8
*bw_per
,
567 struct fw_port_cmd pcmd
;
568 struct port_info
*pi
= netdev2pinfo(dev
);
569 struct adapter
*adap
= pi
->adapter
;
573 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd
, pi
->port_id
);
575 INIT_PORT_DCB_READ_PEER_CMD(pcmd
, pi
->port_id
);
577 pcmd
.u
.dcb
.pgrate
.type
= FW_PORT_DCB_TYPE_PGRATE
;
578 err
= t4_wr_mbox(adap
, adap
->mbox
, &pcmd
, sizeof(pcmd
), &pcmd
);
579 if (err
!= FW_PORT_DCB_CFG_SUCCESS
) {
580 dev_err(adap
->pdev_dev
, "DCB read PGRATE failed with %d\n",
585 *bw_per
= pcmd
.u
.dcb
.pgrate
.pgrate
[pgid
];
588 static void cxgb4_getpgbwgcfg_tx(struct net_device
*dev
, int pgid
, u8
*bw_per
)
590 return cxgb4_getpgbwgcfg(dev
, pgid
, bw_per
, 1);
593 static void cxgb4_getpgbwgcfg_rx(struct net_device
*dev
, int pgid
, u8
*bw_per
)
595 return cxgb4_getpgbwgcfg(dev
, pgid
, bw_per
, 0);
598 static void cxgb4_setpgbwgcfg_tx(struct net_device
*dev
, int pgid
,
601 struct fw_port_cmd pcmd
;
602 struct port_info
*pi
= netdev2pinfo(dev
);
603 struct adapter
*adap
= pi
->adapter
;
606 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd
, pi
->port_id
);
607 pcmd
.u
.dcb
.pgrate
.type
= FW_PORT_DCB_TYPE_PGRATE
;
609 err
= t4_wr_mbox(adap
, adap
->mbox
, &pcmd
, sizeof(pcmd
), &pcmd
);
610 if (err
!= FW_PORT_DCB_CFG_SUCCESS
) {
611 dev_err(adap
->pdev_dev
, "DCB read PGRATE failed with %d\n",
616 pcmd
.u
.dcb
.pgrate
.pgrate
[pgid
] = bw_per
;
618 INIT_PORT_DCB_WRITE_CMD(pcmd
, pi
->port_id
);
619 if (pi
->dcb
.state
== CXGB4_DCB_STATE_HOST
)
620 pcmd
.op_to_portid
|= cpu_to_be32(FW_PORT_CMD_APPLY_F
);
622 err
= t4_wr_mbox(adap
, adap
->mbox
, &pcmd
, sizeof(pcmd
), &pcmd
);
624 if (err
!= FW_PORT_DCB_CFG_SUCCESS
)
625 dev_err(adap
->pdev_dev
, "DCB write PGRATE failed with %d\n",
629 /* Return whether the specified Traffic Class Priority has Priority Pause
632 static void cxgb4_getpfccfg(struct net_device
*dev
, int priority
, u8
*pfccfg
)
634 struct port_info
*pi
= netdev2pinfo(dev
);
635 struct port_dcb_info
*dcb
= &pi
->dcb
;
637 if (!cxgb4_dcb_state_synced(dcb
->state
) ||
638 priority
>= CXGB4_MAX_PRIORITY
)
641 *pfccfg
= (pi
->dcb
.pfcen
>> (7 - priority
)) & 1;
644 /* Enable/disable Priority Pause Frames for the specified Traffic Class
647 static void cxgb4_setpfccfg(struct net_device
*dev
, int priority
, u8 pfccfg
)
649 struct fw_port_cmd pcmd
;
650 struct port_info
*pi
= netdev2pinfo(dev
);
651 struct adapter
*adap
= pi
->adapter
;
654 if (!cxgb4_dcb_state_synced(pi
->dcb
.state
) ||
655 priority
>= CXGB4_MAX_PRIORITY
)
658 INIT_PORT_DCB_WRITE_CMD(pcmd
, pi
->port_id
);
659 if (pi
->dcb
.state
== CXGB4_DCB_STATE_HOST
)
660 pcmd
.op_to_portid
|= cpu_to_be32(FW_PORT_CMD_APPLY_F
);
662 pcmd
.u
.dcb
.pfc
.type
= FW_PORT_DCB_TYPE_PFC
;
663 pcmd
.u
.dcb
.pfc
.pfcen
= pi
->dcb
.pfcen
;
666 pcmd
.u
.dcb
.pfc
.pfcen
|= (1 << (7 - priority
));
668 pcmd
.u
.dcb
.pfc
.pfcen
&= (~(1 << (7 - priority
)));
670 err
= t4_wr_mbox(adap
, adap
->mbox
, &pcmd
, sizeof(pcmd
), &pcmd
);
671 if (err
!= FW_PORT_DCB_CFG_SUCCESS
) {
672 dev_err(adap
->pdev_dev
, "DCB PFC write failed with %d\n", -err
);
676 pi
->dcb
.pfcen
= pcmd
.u
.dcb
.pfc
.pfcen
;
679 static u8
cxgb4_setall(struct net_device
*dev
)
684 /* Return DCB capabilities.
686 static u8
cxgb4_getcap(struct net_device
*dev
, int cap_id
, u8
*caps
)
688 struct port_info
*pi
= netdev2pinfo(dev
);
691 case DCB_CAP_ATTR_PG
:
692 case DCB_CAP_ATTR_PFC
:
696 case DCB_CAP_ATTR_PG_TCS
:
697 /* 8 priorities for PG represented by bitmap */
701 case DCB_CAP_ATTR_PFC_TCS
:
702 /* 8 priorities for PFC represented by bitmap */
706 case DCB_CAP_ATTR_GSP
:
710 case DCB_CAP_ATTR_UP2TC
:
711 case DCB_CAP_ATTR_BCN
:
715 case DCB_CAP_ATTR_DCBX
:
716 *caps
= pi
->dcb
.supported
;
726 /* Return the number of Traffic Classes for the indicated Traffic Class ID.
728 static int cxgb4_getnumtcs(struct net_device
*dev
, int tcs_id
, u8
*num
)
730 struct port_info
*pi
= netdev2pinfo(dev
);
733 case DCB_NUMTCS_ATTR_PG
:
734 if (pi
->dcb
.msgs
& CXGB4_DCB_FW_PGRATE
)
735 *num
= pi
->dcb
.pg_num_tcs_supported
;
740 case DCB_NUMTCS_ATTR_PFC
:
751 /* Set the number of Traffic Classes supported for the indicated Traffic Class
754 static int cxgb4_setnumtcs(struct net_device
*dev
, int tcs_id
, u8 num
)
756 /* Setting the number of Traffic Classes isn't supported.
761 /* Return whether Priority Flow Control is enabled. */
762 static u8
cxgb4_getpfcstate(struct net_device
*dev
)
764 struct port_info
*pi
= netdev2pinfo(dev
);
766 if (!cxgb4_dcb_state_synced(pi
->dcb
.state
))
769 return pi
->dcb
.pfcen
!= 0;
772 /* Enable/disable Priority Flow Control. */
773 static void cxgb4_setpfcstate(struct net_device
*dev
, u8 state
)
775 /* We can't enable/disable Priority Flow Control but we also can't
776 * return an error ...
780 /* Return the Application User Priority Map associated with the specified
783 static int __cxgb4_getapp(struct net_device
*dev
, u8 app_idtype
, u16 app_id
,
786 struct port_info
*pi
= netdev2pinfo(dev
);
787 struct adapter
*adap
= pi
->adapter
;
790 if (!cxgb4_dcb_state_synced(pi
->dcb
.state
))
793 for (i
= 0; i
< CXGB4_MAX_DCBX_APP_SUPPORTED
; i
++) {
794 struct fw_port_cmd pcmd
;
798 INIT_PORT_DCB_READ_PEER_CMD(pcmd
, pi
->port_id
);
800 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd
, pi
->port_id
);
802 pcmd
.u
.dcb
.app_priority
.type
= FW_PORT_DCB_TYPE_APP_ID
;
803 pcmd
.u
.dcb
.app_priority
.idx
= i
;
805 err
= t4_wr_mbox(adap
, adap
->mbox
, &pcmd
, sizeof(pcmd
), &pcmd
);
806 if (err
!= FW_PORT_DCB_CFG_SUCCESS
) {
807 dev_err(adap
->pdev_dev
, "DCB APP read failed with %d\n",
811 if (be16_to_cpu(pcmd
.u
.dcb
.app_priority
.protocolid
) == app_id
)
812 if (pcmd
.u
.dcb
.app_priority
.sel_field
== app_idtype
)
813 return pcmd
.u
.dcb
.app_priority
.user_prio_map
;
815 /* exhausted app list */
816 if (!pcmd
.u
.dcb
.app_priority
.protocolid
)
823 /* Return the Application User Priority Map associated with the specified
826 static int cxgb4_getapp(struct net_device
*dev
, u8 app_idtype
, u16 app_id
)
828 /* Convert app_idtype to firmware format before querying */
829 return __cxgb4_getapp(dev
, app_idtype
== DCB_APP_IDTYPE_ETHTYPE
?
830 app_idtype
: 3, app_id
, 0);
833 /* Write a new Application User Priority Map for the specified Application ID
835 static int __cxgb4_setapp(struct net_device
*dev
, u8 app_idtype
, u16 app_id
,
838 struct fw_port_cmd pcmd
;
839 struct port_info
*pi
= netdev2pinfo(dev
);
840 struct adapter
*adap
= pi
->adapter
;
844 if (!cxgb4_dcb_state_synced(pi
->dcb
.state
))
847 /* DCB info gets thrown away on link up */
848 if (!netif_carrier_ok(dev
))
851 for (i
= 0; i
< CXGB4_MAX_DCBX_APP_SUPPORTED
; i
++) {
852 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd
, pi
->port_id
);
853 pcmd
.u
.dcb
.app_priority
.type
= FW_PORT_DCB_TYPE_APP_ID
;
854 pcmd
.u
.dcb
.app_priority
.idx
= i
;
855 err
= t4_wr_mbox(adap
, adap
->mbox
, &pcmd
, sizeof(pcmd
), &pcmd
);
857 if (err
!= FW_PORT_DCB_CFG_SUCCESS
) {
858 dev_err(adap
->pdev_dev
, "DCB app table read failed with %d\n",
862 if (be16_to_cpu(pcmd
.u
.dcb
.app_priority
.protocolid
) == app_id
) {
863 /* overwrite existing app table */
864 pcmd
.u
.dcb
.app_priority
.protocolid
= 0;
867 /* find first empty slot */
868 if (!pcmd
.u
.dcb
.app_priority
.protocolid
)
872 if (i
== CXGB4_MAX_DCBX_APP_SUPPORTED
) {
873 /* no empty slots available */
874 dev_err(adap
->pdev_dev
, "DCB app table full\n");
878 /* write out new app table entry */
879 INIT_PORT_DCB_WRITE_CMD(pcmd
, pi
->port_id
);
880 if (pi
->dcb
.state
== CXGB4_DCB_STATE_HOST
)
881 pcmd
.op_to_portid
|= cpu_to_be32(FW_PORT_CMD_APPLY_F
);
883 pcmd
.u
.dcb
.app_priority
.type
= FW_PORT_DCB_TYPE_APP_ID
;
884 pcmd
.u
.dcb
.app_priority
.protocolid
= cpu_to_be16(app_id
);
885 pcmd
.u
.dcb
.app_priority
.sel_field
= app_idtype
;
886 pcmd
.u
.dcb
.app_priority
.user_prio_map
= app_prio
;
887 pcmd
.u
.dcb
.app_priority
.idx
= i
;
889 err
= t4_wr_mbox(adap
, adap
->mbox
, &pcmd
, sizeof(pcmd
), &pcmd
);
890 if (err
!= FW_PORT_DCB_CFG_SUCCESS
) {
891 dev_err(adap
->pdev_dev
, "DCB app table write failed with %d\n",
899 /* Priority for CEE inside dcb_app is bitmask, with 0 being an invalid value */
900 static int cxgb4_setapp(struct net_device
*dev
, u8 app_idtype
, u16 app_id
,
904 struct dcb_app app
= {
905 .selector
= app_idtype
,
907 .priority
= app_prio
,
910 if (app_idtype
!= DCB_APP_IDTYPE_ETHTYPE
&&
911 app_idtype
!= DCB_APP_IDTYPE_PORTNUM
)
914 /* Convert app_idtype to a format that firmware understands */
915 ret
= __cxgb4_setapp(dev
, app_idtype
== DCB_APP_IDTYPE_ETHTYPE
?
916 app_idtype
: 3, app_id
, app_prio
);
920 return dcb_setapp(dev
, &app
);
923 /* Return whether IEEE Data Center Bridging has been negotiated.
926 cxgb4_ieee_negotiation_complete(struct net_device
*dev
,
927 enum cxgb4_dcb_fw_msgs dcb_subtype
)
929 struct port_info
*pi
= netdev2pinfo(dev
);
930 struct port_dcb_info
*dcb
= &pi
->dcb
;
932 if (dcb
->state
== CXGB4_DCB_STATE_FW_ALLSYNCED
)
933 if (dcb_subtype
&& !(dcb
->msgs
& dcb_subtype
))
936 return (cxgb4_dcb_state_synced(dcb
->state
) &&
937 (dcb
->supported
& DCB_CAP_DCBX_VER_IEEE
));
940 static int cxgb4_ieee_read_ets(struct net_device
*dev
, struct ieee_ets
*ets
,
943 struct port_info
*pi
= netdev2pinfo(dev
);
944 struct port_dcb_info
*dcb
= &pi
->dcb
;
945 struct adapter
*adap
= pi
->adapter
;
947 struct fw_port_cmd pcmd
;
950 if (!(dcb
->msgs
& (CXGB4_DCB_FW_PGID
| CXGB4_DCB_FW_PGRATE
)))
953 ets
->ets_cap
= dcb
->pg_num_tcs_supported
;
957 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd
, pi
->port_id
);
959 INIT_PORT_DCB_READ_PEER_CMD(pcmd
, pi
->port_id
);
962 pcmd
.u
.dcb
.pgid
.type
= FW_PORT_DCB_TYPE_PGID
;
963 err
= t4_wr_mbox(adap
, adap
->mbox
, &pcmd
, sizeof(pcmd
), &pcmd
);
964 if (err
!= FW_PORT_DCB_CFG_SUCCESS
) {
965 dev_err(adap
->pdev_dev
, "DCB read PGID failed with %d\n", -err
);
969 tc_info
= be32_to_cpu(pcmd
.u
.dcb
.pgid
.pgid
);
972 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd
, pi
->port_id
);
974 INIT_PORT_DCB_READ_PEER_CMD(pcmd
, pi
->port_id
);
976 pcmd
.u
.dcb
.pgrate
.type
= FW_PORT_DCB_TYPE_PGRATE
;
977 err
= t4_wr_mbox(adap
, adap
->mbox
, &pcmd
, sizeof(pcmd
), &pcmd
);
978 if (err
!= FW_PORT_DCB_CFG_SUCCESS
) {
979 dev_err(adap
->pdev_dev
, "DCB read PGRATE failed with %d\n",
984 for (i
= 0; i
< IEEE_8021QAZ_MAX_TCS
; i
++) {
985 bwg
= (tc_info
>> ((7 - i
) * 4)) & 0xF;
986 ets
->prio_tc
[i
] = bwg
;
987 ets
->tc_tx_bw
[i
] = pcmd
.u
.dcb
.pgrate
.pgrate
[i
];
988 ets
->tc_rx_bw
[i
] = ets
->tc_tx_bw
[i
];
989 ets
->tc_tsa
[i
] = pcmd
.u
.dcb
.pgrate
.tsa
[i
];
995 static int cxgb4_ieee_get_ets(struct net_device
*dev
, struct ieee_ets
*ets
)
997 return cxgb4_ieee_read_ets(dev
, ets
, 1);
1000 /* We reuse this for peer PFC as well, as we can't have it enabled one way */
1001 static int cxgb4_ieee_get_pfc(struct net_device
*dev
, struct ieee_pfc
*pfc
)
1003 struct port_info
*pi
= netdev2pinfo(dev
);
1004 struct port_dcb_info
*dcb
= &pi
->dcb
;
1006 memset(pfc
, 0, sizeof(struct ieee_pfc
));
1008 if (!(dcb
->msgs
& CXGB4_DCB_FW_PFC
))
1011 pfc
->pfc_cap
= dcb
->pfc_num_tcs_supported
;
1012 pfc
->pfc_en
= bitswap_1(dcb
->pfcen
);
1017 static int cxgb4_ieee_peer_ets(struct net_device
*dev
, struct ieee_ets
*ets
)
1019 return cxgb4_ieee_read_ets(dev
, ets
, 0);
1022 /* Fill in the Application User Priority Map associated with the
1023 * specified Application.
1024 * Priority for IEEE dcb_app is an integer, with 0 being a valid value
1026 static int cxgb4_ieee_getapp(struct net_device
*dev
, struct dcb_app
*app
)
1030 if (!cxgb4_ieee_negotiation_complete(dev
, CXGB4_DCB_FW_APP_ID
))
1032 if (!(app
->selector
&& app
->protocol
))
1035 /* Try querying firmware first, use firmware format */
1036 prio
= __cxgb4_getapp(dev
, app
->selector
- 1, app
->protocol
, 0);
1039 prio
= dcb_ieee_getapp_mask(dev
, app
);
1041 app
->priority
= ffs(prio
) - 1;
1045 /* Write a new Application User Priority Map for the specified Application ID.
1046 * Priority for IEEE dcb_app is an integer, with 0 being a valid value
1048 static int cxgb4_ieee_setapp(struct net_device
*dev
, struct dcb_app
*app
)
1052 if (!cxgb4_ieee_negotiation_complete(dev
, CXGB4_DCB_FW_APP_ID
))
1054 if (!(app
->selector
&& app
->protocol
))
1057 if (!(app
->selector
> IEEE_8021QAZ_APP_SEL_ETHERTYPE
&&
1058 app
->selector
< IEEE_8021QAZ_APP_SEL_ANY
))
1061 /* change selector to a format that firmware understands */
1062 ret
= __cxgb4_setapp(dev
, app
->selector
- 1, app
->protocol
,
1063 (1 << app
->priority
));
1067 return dcb_ieee_setapp(dev
, app
);
1070 /* Return our DCBX parameters.
1072 static u8
cxgb4_getdcbx(struct net_device
*dev
)
1074 struct port_info
*pi
= netdev2pinfo(dev
);
1076 /* This is already set by cxgb4_set_dcb_caps, so just return it */
1077 return pi
->dcb
.supported
;
1080 /* Set our DCBX parameters.
1082 static u8
cxgb4_setdcbx(struct net_device
*dev
, u8 dcb_request
)
1084 struct port_info
*pi
= netdev2pinfo(dev
);
1086 /* Filter out requests which exceed our capabilities.
1088 if ((dcb_request
& (CXGB4_DCBX_FW_SUPPORT
| CXGB4_DCBX_HOST_SUPPORT
))
1092 /* Can't enable DCB if we haven't successfully negotiated it.
1094 if (!cxgb4_dcb_state_synced(pi
->dcb
.state
))
1097 /* There's currently no mechanism to allow for the firmware DCBX
1098 * negotiation to be changed from the Host Driver. If the caller
1099 * requests exactly the same parameters that we already have then
1100 * we'll allow them to be successfully "set" ...
1102 if (dcb_request
!= pi
->dcb
.supported
)
1105 pi
->dcb
.supported
= dcb_request
;
1109 static int cxgb4_getpeer_app(struct net_device
*dev
,
1110 struct dcb_peer_app_info
*info
, u16
*app_count
)
1112 struct fw_port_cmd pcmd
;
1113 struct port_info
*pi
= netdev2pinfo(dev
);
1114 struct adapter
*adap
= pi
->adapter
;
1117 if (!cxgb4_dcb_state_synced(pi
->dcb
.state
))
1124 for (i
= 0; i
< CXGB4_MAX_DCBX_APP_SUPPORTED
; i
++) {
1125 INIT_PORT_DCB_READ_PEER_CMD(pcmd
, pi
->port_id
);
1126 pcmd
.u
.dcb
.app_priority
.type
= FW_PORT_DCB_TYPE_APP_ID
;
1127 pcmd
.u
.dcb
.app_priority
.idx
= *app_count
;
1128 err
= t4_wr_mbox(adap
, adap
->mbox
, &pcmd
, sizeof(pcmd
), &pcmd
);
1130 if (err
!= FW_PORT_DCB_CFG_SUCCESS
) {
1131 dev_err(adap
->pdev_dev
, "DCB app table read failed with %d\n",
1136 /* find first empty slot */
1137 if (!pcmd
.u
.dcb
.app_priority
.protocolid
)
1144 static int cxgb4_getpeerapp_tbl(struct net_device
*dev
, struct dcb_app
*table
)
1146 struct fw_port_cmd pcmd
;
1147 struct port_info
*pi
= netdev2pinfo(dev
);
1148 struct adapter
*adap
= pi
->adapter
;
1151 if (!cxgb4_dcb_state_synced(pi
->dcb
.state
))
1154 for (i
= 0; i
< CXGB4_MAX_DCBX_APP_SUPPORTED
; i
++) {
1155 INIT_PORT_DCB_READ_PEER_CMD(pcmd
, pi
->port_id
);
1156 pcmd
.u
.dcb
.app_priority
.type
= FW_PORT_DCB_TYPE_APP_ID
;
1157 pcmd
.u
.dcb
.app_priority
.idx
= i
;
1158 err
= t4_wr_mbox(adap
, adap
->mbox
, &pcmd
, sizeof(pcmd
), &pcmd
);
1160 if (err
!= FW_PORT_DCB_CFG_SUCCESS
) {
1161 dev_err(adap
->pdev_dev
, "DCB app table read failed with %d\n",
1166 /* find first empty slot */
1167 if (!pcmd
.u
.dcb
.app_priority
.protocolid
)
1170 table
[i
].selector
= (pcmd
.u
.dcb
.app_priority
.sel_field
+ 1);
1172 be16_to_cpu(pcmd
.u
.dcb
.app_priority
.protocolid
);
1174 ffs(pcmd
.u
.dcb
.app_priority
.user_prio_map
) - 1;
1179 /* Return Priority Group information.
1181 static int cxgb4_cee_peer_getpg(struct net_device
*dev
, struct cee_pg
*pg
)
1183 struct fw_port_cmd pcmd
;
1184 struct port_info
*pi
= netdev2pinfo(dev
);
1185 struct adapter
*adap
= pi
->adapter
;
1189 /* We're always "willing" -- the Switch Fabric always dictates the
1190 * DCBX parameters to us.
1194 INIT_PORT_DCB_READ_PEER_CMD(pcmd
, pi
->port_id
);
1195 pcmd
.u
.dcb
.pgid
.type
= FW_PORT_DCB_TYPE_PGID
;
1196 err
= t4_wr_mbox(adap
, adap
->mbox
, &pcmd
, sizeof(pcmd
), &pcmd
);
1197 if (err
!= FW_PORT_DCB_CFG_SUCCESS
) {
1198 dev_err(adap
->pdev_dev
, "DCB read PGID failed with %d\n", -err
);
1201 pgid
= be32_to_cpu(pcmd
.u
.dcb
.pgid
.pgid
);
1203 for (i
= 0; i
< CXGB4_MAX_PRIORITY
; i
++)
1204 pg
->prio_pg
[7 - i
] = (pgid
>> (i
* 4)) & 0xF;
1206 INIT_PORT_DCB_READ_PEER_CMD(pcmd
, pi
->port_id
);
1207 pcmd
.u
.dcb
.pgrate
.type
= FW_PORT_DCB_TYPE_PGRATE
;
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 PGRATE failed with %d\n",
1215 for (i
= 0; i
< CXGB4_MAX_PRIORITY
; i
++)
1216 pg
->pg_bw
[i
] = pcmd
.u
.dcb
.pgrate
.pgrate
[i
];
1218 pg
->tcs_supported
= pcmd
.u
.dcb
.pgrate
.num_tcs_supported
;
1223 /* Return Priority Flow Control information.
1225 static int cxgb4_cee_peer_getpfc(struct net_device
*dev
, struct cee_pfc
*pfc
)
1227 struct port_info
*pi
= netdev2pinfo(dev
);
1229 cxgb4_getnumtcs(dev
, DCB_NUMTCS_ATTR_PFC
, &(pfc
->tcs_supported
));
1231 /* Firmware sends this to us in a formwat that is a bit flipped version
1232 * of spec, correct it before we send it to host. This is taken care of
1233 * by bit shifting in other uses of pfcen
1235 pfc
->pfc_en
= bitswap_1(pi
->dcb
.pfcen
);
1237 pfc
->tcs_supported
= pi
->dcb
.pfc_num_tcs_supported
;
1242 const struct dcbnl_rtnl_ops cxgb4_dcb_ops
= {
1243 .ieee_getets
= cxgb4_ieee_get_ets
,
1244 .ieee_getpfc
= cxgb4_ieee_get_pfc
,
1245 .ieee_getapp
= cxgb4_ieee_getapp
,
1246 .ieee_setapp
= cxgb4_ieee_setapp
,
1247 .ieee_peer_getets
= cxgb4_ieee_peer_ets
,
1248 .ieee_peer_getpfc
= cxgb4_ieee_get_pfc
,
1251 .getstate
= cxgb4_getstate
,
1252 .setstate
= cxgb4_setstate
,
1253 .getpgtccfgtx
= cxgb4_getpgtccfg_tx
,
1254 .getpgbwgcfgtx
= cxgb4_getpgbwgcfg_tx
,
1255 .getpgtccfgrx
= cxgb4_getpgtccfg_rx
,
1256 .getpgbwgcfgrx
= cxgb4_getpgbwgcfg_rx
,
1257 .setpgtccfgtx
= cxgb4_setpgtccfg_tx
,
1258 .setpgbwgcfgtx
= cxgb4_setpgbwgcfg_tx
,
1259 .setpfccfg
= cxgb4_setpfccfg
,
1260 .getpfccfg
= cxgb4_getpfccfg
,
1261 .setall
= cxgb4_setall
,
1262 .getcap
= cxgb4_getcap
,
1263 .getnumtcs
= cxgb4_getnumtcs
,
1264 .setnumtcs
= cxgb4_setnumtcs
,
1265 .getpfcstate
= cxgb4_getpfcstate
,
1266 .setpfcstate
= cxgb4_setpfcstate
,
1267 .getapp
= cxgb4_getapp
,
1268 .setapp
= cxgb4_setapp
,
1270 /* DCBX configuration */
1271 .getdcbx
= cxgb4_getdcbx
,
1272 .setdcbx
= cxgb4_setdcbx
,
1275 .peer_getappinfo
= cxgb4_getpeer_app
,
1276 .peer_getapptable
= cxgb4_getpeerapp_tbl
,
1279 .cee_peer_getpg
= cxgb4_cee_peer_getpg
,
1280 .cee_peer_getpfc
= cxgb4_cee_peer_getpfc
,