cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cxgb4_dcb.c (33783B)


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