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