/* Broadcom NetXtreme-C/E network driver.
 *
 * Copyright (c) 2014-2016 Broadcom Corporation
 * Copyright (c) 2016-2017 Broadcom Limited
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 */

#include <linux/netdevice.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/rtnetlink.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/etherdevice.h>
#include <rdma/ib_verbs.h>
#include "bnxt_hsi.h"
#include "bnxt.h"
#include "bnxt_hwrm.h"
#include "bnxt_dcb.h"

#ifdef CONFIG_BNXT_DCB
static int bnxt_queue_to_tc(struct bnxt *bp, u8 queue_id)
{
	int i, j;

	for (i = 0; i < bp->max_tc; i++) {
		if (bp->q_info[i].queue_id == queue_id) {
			for (j = 0; j < bp->max_tc; j++) {
				if (bp->tc_to_qidx[j] == i)
					return j;
			}
		}
	}
	return -EINVAL;
}

static int bnxt_hwrm_queue_pri2cos_cfg(struct bnxt *bp, struct ieee_ets *ets)
{
	struct hwrm_queue_pri2cos_cfg_input *req;
	u8 *pri2cos;
	int rc, i;

	rc = hwrm_req_init(bp, req, HWRM_QUEUE_PRI2COS_CFG);
	if (rc)
		return rc;

	req->flags = cpu_to_le32(QUEUE_PRI2COS_CFG_REQ_FLAGS_PATH_BIDIR |
				 QUEUE_PRI2COS_CFG_REQ_FLAGS_IVLAN);

	pri2cos = &req->pri0_cos_queue_id;
	for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
		u8 qidx;

		req->enables |= cpu_to_le32(
			QUEUE_PRI2COS_CFG_REQ_ENABLES_PRI0_COS_QUEUE_ID << i);

		qidx = bp->tc_to_qidx[ets->prio_tc[i]];
		pri2cos[i] = bp->q_info[qidx].queue_id;
	}
	return hwrm_req_send(bp, req);
}

static int bnxt_hwrm_queue_pri2cos_qcfg(struct bnxt *bp, struct ieee_ets *ets)
{
	struct hwrm_queue_pri2cos_qcfg_output *resp;
	struct hwrm_queue_pri2cos_qcfg_input *req;
	int rc;

	rc = hwrm_req_init(bp, req, HWRM_QUEUE_PRI2COS_QCFG);
	if (rc)
		return rc;

	req->flags = cpu_to_le32(QUEUE_PRI2COS_QCFG_REQ_FLAGS_IVLAN);
	resp = hwrm_req_hold(bp, req);
	rc = hwrm_req_send(bp, req);
	if (!rc) {
		u8 *pri2cos = &resp->pri0_cos_queue_id;
		int i;

		for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
			u8 queue_id = pri2cos[i];
			int tc;

			tc = bnxt_queue_to_tc(bp, queue_id);
			if (tc >= 0)
				ets->prio_tc[i] = tc;
		}
	}
	hwrm_req_drop(bp, req);
	return rc;
}

static int bnxt_hwrm_queue_cos2bw_cfg(struct bnxt *bp, struct ieee_ets *ets,
				      u8 max_tc)
{
	struct hwrm_queue_cos2bw_cfg_input *req;
	struct bnxt_cos2bw_cfg cos2bw;
	int rc, i;

	rc = hwrm_req_init(bp, req, HWRM_QUEUE_COS2BW_CFG);
	if (rc)
		return rc;

	for (i = 0; i < max_tc; i++) {
		u8 qidx = bp->tc_to_qidx[i];

		req->enables |= cpu_to_le32(
			QUEUE_COS2BW_CFG_REQ_ENABLES_COS_QUEUE_ID0_VALID <<
			qidx);

		memset(&cos2bw, 0, sizeof(cos2bw));
		cos2bw.queue_id = bp->q_info[qidx].queue_id;
		if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_STRICT) {
			cos2bw.tsa =
				QUEUE_COS2BW_QCFG_RESP_QUEUE_ID0_TSA_ASSIGN_SP;
			cos2bw.pri_lvl = i;
		} else {
			cos2bw.tsa =
				QUEUE_COS2BW_QCFG_RESP_QUEUE_ID0_TSA_ASSIGN_ETS;
			cos2bw.bw_weight = ets->tc_tx_bw[i];
			/* older firmware requires min_bw to be set to the
			 * same weight value in percent.
			 */
			cos2bw.min_bw =
				cpu_to_le32((ets->tc_tx_bw[i] * 100) |
					    BW_VALUE_UNIT_PERCENT1_100);
		}
		if (qidx == 0) {
			req->queue_id0 = cos2bw.queue_id;
			req->queue_id0_min_bw = cos2bw.min_bw;
			req->queue_id0_max_bw = cos2bw.max_bw;
			req->queue_id0_tsa_assign = cos2bw.tsa;
			req->queue_id0_pri_lvl = cos2bw.pri_lvl;
			req->queue_id0_bw_weight = cos2bw.bw_weight;
		} else {
			memcpy(&req->cfg[i - 1], &cos2bw.cfg, sizeof(cos2bw.cfg));
		}
	}
	return hwrm_req_send(bp, req);
}

static int bnxt_hwrm_queue_cos2bw_qcfg(struct bnxt *bp, struct ieee_ets *ets)
{
	struct hwrm_queue_cos2bw_qcfg_output *resp;
	struct hwrm_queue_cos2bw_qcfg_input *req;
	struct bnxt_cos2bw_cfg cos2bw;
	int rc, i;

	rc = hwrm_req_init(bp, req, HWRM_QUEUE_COS2BW_QCFG);
	if (rc)
		return rc;

	resp = hwrm_req_hold(bp, req);
	rc = hwrm_req_send(bp, req);
	if (rc) {
		hwrm_req_drop(bp, req);
		return rc;
	}

	for (i = 0; i < bp->max_tc; i++) {
		int tc;

		if (i == 0) {
			cos2bw.queue_id = resp->queue_id0;
			cos2bw.min_bw = resp->queue_id0_min_bw;
			cos2bw.max_bw = resp->queue_id0_max_bw;
			cos2bw.tsa = resp->queue_id0_tsa_assign;
			cos2bw.pri_lvl = resp->queue_id0_pri_lvl;
			cos2bw.bw_weight = resp->queue_id0_bw_weight;
		} else {
			memcpy(&cos2bw.cfg, &resp->cfg[i - 1], sizeof(cos2bw.cfg));
		}

		tc = bnxt_queue_to_tc(bp, cos2bw.queue_id);
		if (tc < 0)
			continue;

		if (cos2bw.tsa ==
		    QUEUE_COS2BW_QCFG_RESP_QUEUE_ID0_TSA_ASSIGN_SP) {
			ets->tc_tsa[tc] = IEEE_8021QAZ_TSA_STRICT;
		} else {
			ets->tc_tsa[tc] = IEEE_8021QAZ_TSA_ETS;
			ets->tc_tx_bw[tc] = cos2bw.bw_weight;
		}
	}
	hwrm_req_drop(bp, req);
	return 0;
}

static int bnxt_queue_remap(struct bnxt *bp, unsigned int lltc_mask)
{
	unsigned long qmap = 0;
	int max = bp->max_tc;
	int i, j, rc;

	/* Assign lossless TCs first */
	for (i = 0, j = 0; i < max; ) {
		if (lltc_mask & (1 << i)) {
			if (BNXT_LLQ(bp->q_info[j].queue_profile)) {
				bp->tc_to_qidx[i] = j;
				__set_bit(j, &qmap);
				i++;
			}
			j++;
			continue;
		}
		i++;
	}

	for (i = 0, j = 0; i < max; i++) {
		if (lltc_mask & (1 << i))
			continue;
		j = find_next_zero_bit(&qmap, max, j);
		bp->tc_to_qidx[i] = j;
		__set_bit(j, &qmap);
		j++;
	}

	if (netif_running(bp->dev)) {
		bnxt_close_nic(bp, false, false);
		rc = bnxt_open_nic(bp, false, false);
		if (rc) {
			netdev_warn(bp->dev, "failed to open NIC, rc = %d\n", rc);
			return rc;
		}
	}
	if (bp->ieee_ets) {
		int tc = bp->num_tc;

		if (!tc)
			tc = 1;
		rc = bnxt_hwrm_queue_cos2bw_cfg(bp, bp->ieee_ets, tc);
		if (rc) {
			netdev_warn(bp->dev, "failed to config BW, rc = %d\n", rc);
			return rc;
		}
		rc = bnxt_hwrm_queue_pri2cos_cfg(bp, bp->ieee_ets);
		if (rc) {
			netdev_warn(bp->dev, "failed to config prio, rc = %d\n", rc);
			return rc;
		}
	}
	return 0;
}

static int bnxt_hwrm_queue_pfc_cfg(struct bnxt *bp, struct ieee_pfc *pfc)
{
	struct hwrm_queue_pfcenable_cfg_input *req;
	struct ieee_ets *my_ets = bp->ieee_ets;
	unsigned int tc_mask = 0, pri_mask = 0;
	u8 i, pri, lltc_count = 0;
	bool need_q_remap = false;
	int rc;

	if (!my_ets)
		return -EINVAL;

	for (i = 0; i < bp->max_tc; i++) {
		for (pri = 0; pri < IEEE_8021QAZ_MAX_TCS; pri++) {
			if ((pfc->pfc_en & (1 << pri)) &&
			    (my_ets->prio_tc[pri] == i)) {
				pri_mask |= 1 << pri;
				tc_mask |= 1 << i;
			}
		}
		if (tc_mask & (1 << i))
			lltc_count++;
	}
	if (lltc_count > bp->max_lltc)
		return -EINVAL;

	for (i = 0; i < bp->max_tc; i++) {
		if (tc_mask & (1 << i)) {
			u8 qidx = bp->tc_to_qidx[i];

			if (!BNXT_LLQ(bp->q_info[qidx].queue_profile)) {
				need_q_remap = true;
				break;
			}
		}
	}

	if (need_q_remap)
		bnxt_queue_remap(bp, tc_mask);

	rc = hwrm_req_init(bp, req, HWRM_QUEUE_PFCENABLE_CFG);
	if (rc)
		return rc;

	req->flags = cpu_to_le32(pri_mask);
	return hwrm_req_send(bp, req);
}

static int bnxt_hwrm_queue_pfc_qcfg(struct bnxt *bp, struct ieee_pfc *pfc)
{
	struct hwrm_queue_pfcenable_qcfg_output *resp;
	struct hwrm_queue_pfcenable_qcfg_input *req;
	u8 pri_mask;
	int rc;

	rc = hwrm_req_init(bp, req, HWRM_QUEUE_PFCENABLE_QCFG);
	if (rc)
		return rc;

	resp = hwrm_req_hold(bp, req);
	rc = hwrm_req_send(bp, req);
	if (rc) {
		hwrm_req_drop(bp, req);
		return rc;
	}

	pri_mask = le32_to_cpu(resp->flags);
	pfc->pfc_en = pri_mask;
	hwrm_req_drop(bp, req);
	return 0;
}

static int bnxt_hwrm_set_dcbx_app(struct bnxt *bp, struct dcb_app *app,
				  bool add)
{
	struct hwrm_fw_set_structured_data_input *set;
	struct hwrm_fw_get_structured_data_input *get;
	struct hwrm_struct_data_dcbx_app *fw_app;
	struct hwrm_struct_hdr *data;
	dma_addr_t mapping;
	size_t data_len;
	int rc, n, i;

	if (bp->hwrm_spec_code < 0x10601)
		return 0;

	rc = hwrm_req_init(bp, get, HWRM_FW_GET_STRUCTURED_DATA);
	if (rc)
		return rc;

	hwrm_req_hold(bp, get);
	hwrm_req_alloc_flags(bp, get, GFP_KERNEL | __GFP_ZERO);

	n = IEEE_8021QAZ_MAX_TCS;
	data_len = sizeof(*data) + sizeof(*fw_app) * n;
	data = hwrm_req_dma_slice(bp, get, data_len, &mapping);
	if (!data) {
		rc = -ENOMEM;
		goto set_app_exit;
	}

	get->dest_data_addr = cpu_to_le64(mapping);
	get->structure_id = cpu_to_le16(STRUCT_HDR_STRUCT_ID_DCBX_APP);
	get->subtype = cpu_to_le16(HWRM_STRUCT_DATA_SUBTYPE_HOST_OPERATIONAL);
	get->count = 0;
	rc = hwrm_req_send(bp, get);
	if (rc)
		goto set_app_exit;

	fw_app = (struct hwrm_struct_data_dcbx_app *)(data + 1);

	if (data->struct_id != cpu_to_le16(STRUCT_HDR_STRUCT_ID_DCBX_APP)) {
		rc = -ENODEV;
		goto set_app_exit;
	}

	n = data->count;
	for (i = 0; i < n; i++, fw_app++) {
		if (fw_app->protocol_id == cpu_to_be16(app->protocol) &&
		    fw_app->protocol_selector == app->selector &&
		    fw_app->priority == app->priority) {
			if (add)
				goto set_app_exit;
			else
				break;
		}
	}
	if (add) {
		/* append */
		n++;
		fw_app->protocol_id = cpu_to_be16(app->protocol);
		fw_app->protocol_selector = app->selector;
		fw_app->priority = app->priority;
		fw_app->valid = 1;
	} else {
		size_t len = 0;

		/* not found, nothing to delete */
		if (n == i)
			goto set_app_exit;

		len = (n - 1 - i) * sizeof(*fw_app);
		if (len)
			memmove(fw_app, fw_app + 1, len);
		n--;
		memset(fw_app + n, 0, sizeof(*fw_app));
	}
	data->count = n;
	data->len = cpu_to_le16(sizeof(*fw_app) * n);
	data->subtype = cpu_to_le16(HWRM_STRUCT_DATA_SUBTYPE_HOST_OPERATIONAL);

	rc = hwrm_req_init(bp, set, HWRM_FW_SET_STRUCTURED_DATA);
	if (rc)
		goto set_app_exit;

	set->src_data_addr = cpu_to_le64(mapping);
	set->data_len = cpu_to_le16(sizeof(*data) + sizeof(*fw_app) * n);
	set->hdr_cnt = 1;
	rc = hwrm_req_send(bp, set);

set_app_exit:
	hwrm_req_drop(bp, get); /* dropping get request and associated slice */
	return rc;
}

static int bnxt_hwrm_queue_dscp_qcaps(struct bnxt *bp)
{
	struct hwrm_queue_dscp_qcaps_output *resp;
	struct hwrm_queue_dscp_qcaps_input *req;
	int rc;

	bp->max_dscp_value = 0;
	if (bp->hwrm_spec_code < 0x10800 || BNXT_VF(bp))
		return 0;

	rc = hwrm_req_init(bp, req, HWRM_QUEUE_DSCP_QCAPS);
	if (rc)
		return rc;

	resp = hwrm_req_hold(bp, req);
	rc = hwrm_req_send_silent(bp, req);
	if (!rc) {
		bp->max_dscp_value = (1 << resp->num_dscp_bits) - 1;
		if (bp->max_dscp_value < 0x3f)
			bp->max_dscp_value = 0;
	}
	hwrm_req_drop(bp, req);
	return rc;
}

static int bnxt_hwrm_queue_dscp2pri_cfg(struct bnxt *bp, struct dcb_app *app,
					bool add)
{
	struct hwrm_queue_dscp2pri_cfg_input *req;
	struct bnxt_dscp2pri_entry *dscp2pri;
	dma_addr_t mapping;
	int rc;

	if (bp->hwrm_spec_code < 0x10800)
		return 0;

	rc = hwrm_req_init(bp, req, HWRM_QUEUE_DSCP2PRI_CFG);
	if (rc)
		return rc;

	dscp2pri = hwrm_req_dma_slice(bp, req, sizeof(*dscp2pri), &mapping);
	if (!dscp2pri) {
		hwrm_req_drop(bp, req);
		return -ENOMEM;
	}

	req->src_data_addr = cpu_to_le64(mapping);
	dscp2pri->dscp = app->protocol;
	if (add)
		dscp2pri->mask = 0x3f;
	else
		dscp2pri->mask = 0;
	dscp2pri->pri = app->priority;
	req->entry_cnt = cpu_to_le16(1);
	rc = hwrm_req_send(bp, req);
	return rc;
}

static int bnxt_ets_validate(struct bnxt *bp, struct ieee_ets *ets, u8 *tc)
{
	int total_ets_bw = 0;
	bool zero = false;
	u8 max_tc = 0;
	int i;

	for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
		if (ets->prio_tc[i] > bp->max_tc) {
			netdev_err(bp->dev, "priority to TC mapping exceeds TC count %d\n",
				   ets->prio_tc[i]);
			return -EINVAL;
		}
		if (ets->prio_tc[i] > max_tc)
			max_tc = ets->prio_tc[i];

		if ((ets->tc_tx_bw[i] || ets->tc_tsa[i]) && i > bp->max_tc)
			return -EINVAL;

		switch (ets->tc_tsa[i]) {
		case IEEE_8021QAZ_TSA_STRICT:
			break;
		case IEEE_8021QAZ_TSA_ETS:
			total_ets_bw += ets->tc_tx_bw[i];
			zero = zero || !ets->tc_tx_bw[i];
			break;
		default:
			return -ENOTSUPP;
		}
	}
	if (total_ets_bw > 100) {
		netdev_warn(bp->dev, "rejecting ETS config exceeding available bandwidth\n");
		return -EINVAL;
	}
	if (zero && total_ets_bw == 100) {
		netdev_warn(bp->dev, "rejecting ETS config starving a TC\n");
		return -EINVAL;
	}

	if (max_tc >= bp->max_tc)
		*tc = bp->max_tc;
	else
		*tc = max_tc + 1;
	return 0;
}

static int bnxt_dcbnl_ieee_getets(struct net_device *dev, struct ieee_ets *ets)
{
	struct bnxt *bp = netdev_priv(dev);
	struct ieee_ets *my_ets = bp->ieee_ets;
	int rc;

	ets->ets_cap = bp->max_tc;

	if (!my_ets) {
		if (bp->dcbx_cap & DCB_CAP_DCBX_HOST)
			return 0;

		my_ets = kzalloc(sizeof(*my_ets), GFP_KERNEL);
		if (!my_ets)
			return -ENOMEM;
		rc = bnxt_hwrm_queue_cos2bw_qcfg(bp, my_ets);
		if (rc)
			goto error;
		rc = bnxt_hwrm_queue_pri2cos_qcfg(bp, my_ets);
		if (rc)
			goto error;

		/* cache result */
		bp->ieee_ets = my_ets;
	}

	ets->cbs = my_ets->cbs;
	memcpy(ets->tc_tx_bw, my_ets->tc_tx_bw, sizeof(ets->tc_tx_bw));
	memcpy(ets->tc_rx_bw, my_ets->tc_rx_bw, sizeof(ets->tc_rx_bw));
	memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa));
	memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc));
	return 0;
error:
	kfree(my_ets);
	return rc;
}

static int bnxt_dcbnl_ieee_setets(struct net_device *dev, struct ieee_ets *ets)
{
	struct bnxt *bp = netdev_priv(dev);
	struct ieee_ets *my_ets = bp->ieee_ets;
	u8 max_tc = 0;
	int rc, i;

	if (!(bp->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
	    !(bp->dcbx_cap & DCB_CAP_DCBX_HOST))
		return -EINVAL;

	rc = bnxt_ets_validate(bp, ets, &max_tc);
	if (!rc) {
		if (!my_ets) {
			my_ets = kzalloc(sizeof(*my_ets), GFP_KERNEL);
			if (!my_ets)
				return -ENOMEM;
			/* initialize PRI2TC mappings to invalid value */
			for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
				my_ets->prio_tc[i] = IEEE_8021QAZ_MAX_TCS;
			bp->ieee_ets = my_ets;
		}
		rc = bnxt_setup_mq_tc(dev, max_tc);
		if (rc)
			return rc;
		rc = bnxt_hwrm_queue_cos2bw_cfg(bp, ets, max_tc);
		if (rc)
			return rc;
		rc = bnxt_hwrm_queue_pri2cos_cfg(bp, ets);
		if (rc)
			return rc;
		memcpy(my_ets, ets, sizeof(*my_ets));
	}
	return rc;
}

static int bnxt_dcbnl_ieee_getpfc(struct net_device *dev, struct ieee_pfc *pfc)
{
	struct bnxt *bp = netdev_priv(dev);
	__le64 *stats = bp->port_stats.hw_stats;
	struct ieee_pfc *my_pfc = bp->ieee_pfc;
	long rx_off, tx_off;
	int i, rc;

	pfc->pfc_cap = bp->max_lltc;

	if (!my_pfc) {
		if (bp->dcbx_cap & DCB_CAP_DCBX_HOST)
			return 0;

		my_pfc = kzalloc(sizeof(*my_pfc), GFP_KERNEL);
		if (!my_pfc)
			return 0;
		bp->ieee_pfc = my_pfc;
		rc = bnxt_hwrm_queue_pfc_qcfg(bp, my_pfc);
		if (rc)
			return 0;
	}

	pfc->pfc_en = my_pfc->pfc_en;
	pfc->mbc = my_pfc->mbc;
	pfc->delay = my_pfc->delay;

	if (!stats)
		return 0;

	rx_off = BNXT_RX_STATS_OFFSET(rx_pfc_ena_frames_pri0);
	tx_off = BNXT_TX_STATS_OFFSET(tx_pfc_ena_frames_pri0);
	for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++, rx_off++, tx_off++) {
		pfc->requests[i] = le64_to_cpu(*(stats + tx_off));
		pfc->indications[i] = le64_to_cpu(*(stats + rx_off));
	}

	return 0;
}

static int bnxt_dcbnl_ieee_setpfc(struct net_device *dev, struct ieee_pfc *pfc)
{
	struct bnxt *bp = netdev_priv(dev);
	struct ieee_pfc *my_pfc = bp->ieee_pfc;
	int rc;

	if (!(bp->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
	    !(bp->dcbx_cap & DCB_CAP_DCBX_HOST) ||
	    (bp->phy_flags & BNXT_PHY_FL_NO_PAUSE))
		return -EINVAL;

	if (!my_pfc) {
		my_pfc = kzalloc(sizeof(*my_pfc), GFP_KERNEL);
		if (!my_pfc)
			return -ENOMEM;
		bp->ieee_pfc = my_pfc;
	}
	rc = bnxt_hwrm_queue_pfc_cfg(bp, pfc);
	if (!rc)
		memcpy(my_pfc, pfc, sizeof(*my_pfc));

	return rc;
}

static int bnxt_dcbnl_ieee_dscp_app_prep(struct bnxt *bp, struct dcb_app *app)
{
	if (app->selector == IEEE_8021QAZ_APP_SEL_DSCP) {
		if (!bp->max_dscp_value)
			return -ENOTSUPP;
		if (app->protocol > bp->max_dscp_value)
			return -EINVAL;
	}
	return 0;
}

static int bnxt_dcbnl_ieee_setapp(struct net_device *dev, struct dcb_app *app)
{
	struct bnxt *bp = netdev_priv(dev);
	int rc;

	if (!(bp->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
	    !(bp->dcbx_cap & DCB_CAP_DCBX_HOST))
		return -EINVAL;

	rc = bnxt_dcbnl_ieee_dscp_app_prep(bp, app);
	if (rc)
		return rc;

	rc = dcb_ieee_setapp(dev, app);
	if (rc)
		return rc;

	if ((app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
	     app->protocol == ETH_P_IBOE) ||
	    (app->selector == IEEE_8021QAZ_APP_SEL_DGRAM &&
	     app->protocol == ROCE_V2_UDP_DPORT))
		rc = bnxt_hwrm_set_dcbx_app(bp, app, true);

	if (app->selector == IEEE_8021QAZ_APP_SEL_DSCP)
		rc = bnxt_hwrm_queue_dscp2pri_cfg(bp, app, true);

	return rc;
}

static int bnxt_dcbnl_ieee_delapp(struct net_device *dev, struct dcb_app *app)
{
	struct bnxt *bp = netdev_priv(dev);
	int rc;

	if (!(bp->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
	    !(bp->dcbx_cap & DCB_CAP_DCBX_HOST))
		return -EINVAL;

	rc = bnxt_dcbnl_ieee_dscp_app_prep(bp, app);
	if (rc)
		return rc;

	rc = dcb_ieee_delapp(dev, app);
	if (rc)
		return rc;
	if ((app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
	     app->protocol == ETH_P_IBOE) ||
	    (app->selector == IEEE_8021QAZ_APP_SEL_DGRAM &&
	     app->protocol == ROCE_V2_UDP_DPORT))
		rc = bnxt_hwrm_set_dcbx_app(bp, app, false);

	if (app->selector == IEEE_8021QAZ_APP_SEL_DSCP)
		rc = bnxt_hwrm_queue_dscp2pri_cfg(bp, app, false);

	return rc;
}

static u8 bnxt_dcbnl_getdcbx(struct net_device *dev)
{
	struct bnxt *bp = netdev_priv(dev);

	return bp->dcbx_cap;
}

static u8 bnxt_dcbnl_setdcbx(struct net_device *dev, u8 mode)
{
	struct bnxt *bp = netdev_priv(dev);

	/* All firmware DCBX settings are set in NVRAM */
	if (bp->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED)
		return 1;

	if (mode & DCB_CAP_DCBX_HOST) {
		if (BNXT_VF(bp) || (bp->fw_cap & BNXT_FW_CAP_LLDP_AGENT))
			return 1;

		/* only support IEEE */
		if ((mode & DCB_CAP_DCBX_VER_CEE) ||
		    !(mode & DCB_CAP_DCBX_VER_IEEE))
			return 1;
	}

	if (mode == bp->dcbx_cap)
		return 0;

	bp->dcbx_cap = mode;
	return 0;
}

static const struct dcbnl_rtnl_ops dcbnl_ops = {
	.ieee_getets	= bnxt_dcbnl_ieee_getets,
	.ieee_setets	= bnxt_dcbnl_ieee_setets,
	.ieee_getpfc	= bnxt_dcbnl_ieee_getpfc,
	.ieee_setpfc	= bnxt_dcbnl_ieee_setpfc,
	.ieee_setapp	= bnxt_dcbnl_ieee_setapp,
	.ieee_delapp	= bnxt_dcbnl_ieee_delapp,
	.getdcbx	= bnxt_dcbnl_getdcbx,
	.setdcbx	= bnxt_dcbnl_setdcbx,
};

void bnxt_dcb_init(struct bnxt *bp)
{
	bp->dcbx_cap = 0;
	if (bp->hwrm_spec_code < 0x10501)
		return;

	bnxt_hwrm_queue_dscp_qcaps(bp);
	bp->dcbx_cap = DCB_CAP_DCBX_VER_IEEE;
	if (BNXT_PF(bp) && !(bp->fw_cap & BNXT_FW_CAP_LLDP_AGENT))
		bp->dcbx_cap |= DCB_CAP_DCBX_HOST;
	else if (bp->fw_cap & BNXT_FW_CAP_DCBX_AGENT)
		bp->dcbx_cap |= DCB_CAP_DCBX_LLD_MANAGED;
	bp->dev->dcbnl_ops = &dcbnl_ops;
}

void bnxt_dcb_free(struct bnxt *bp)
{
	kfree(bp->ieee_pfc);
	kfree(bp->ieee_ets);
	bp->ieee_pfc = NULL;
	bp->ieee_ets = NULL;
}

#else

void bnxt_dcb_init(struct bnxt *bp)
{
}

void bnxt_dcb_free(struct bnxt *bp)
{
}

#endif
