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