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