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