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