// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2019, Intel Corporation. */

#include "ice.h"
#include "ice_dcb.h"
#include "ice_dcb_lib.h"
#include "ice_dcb_nl.h"
#include <net/dcbnl.h>

/**
 * ice_dcbnl_devreset - perform enough of a ifdown/ifup to sync DCBNL info
 * @netdev: device associated with interface that needs reset
 */
static void ice_dcbnl_devreset(struct net_device *netdev)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);

	while (ice_is_reset_in_progress(pf->state))
		usleep_range(1000, 2000);

	dev_close(netdev);
	netdev_state_change(netdev);
	dev_open(netdev, NULL);
	netdev_state_change(netdev);
}

/**
 * ice_dcbnl_getets - retrieve local ETS configuration
 * @netdev: the relevant netdev
 * @ets: struct to hold ETS configuration
 */
static int ice_dcbnl_getets(struct net_device *netdev, struct ieee_ets *ets)
{
	struct ice_dcbx_cfg *dcbxcfg;
	struct ice_pf *pf;

	pf = ice_netdev_to_pf(netdev);
	dcbxcfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg;

	ets->willing = dcbxcfg->etscfg.willing;
	ets->ets_cap = dcbxcfg->etscfg.maxtcs;
	ets->cbs = dcbxcfg->etscfg.cbs;
	memcpy(ets->tc_tx_bw, dcbxcfg->etscfg.tcbwtable, sizeof(ets->tc_tx_bw));
	memcpy(ets->tc_rx_bw, dcbxcfg->etscfg.tcbwtable, sizeof(ets->tc_rx_bw));
	memcpy(ets->tc_tsa, dcbxcfg->etscfg.tsatable, sizeof(ets->tc_tsa));
	memcpy(ets->prio_tc, dcbxcfg->etscfg.prio_table, sizeof(ets->prio_tc));
	memcpy(ets->tc_reco_bw, dcbxcfg->etsrec.tcbwtable,
	       sizeof(ets->tc_reco_bw));
	memcpy(ets->tc_reco_tsa, dcbxcfg->etsrec.tsatable,
	       sizeof(ets->tc_reco_tsa));
	memcpy(ets->reco_prio_tc, dcbxcfg->etscfg.prio_table,
	       sizeof(ets->reco_prio_tc));

	return 0;
}

/**
 * ice_dcbnl_setets - set IEEE ETS configuration
 * @netdev: pointer to relevant netdev
 * @ets: struct to hold ETS configuration
 */
static int ice_dcbnl_setets(struct net_device *netdev, struct ieee_ets *ets)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);
	struct ice_dcbx_cfg *new_cfg;
	int bwcfg = 0, bwrec = 0;
	int err, i;

	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
		return -EINVAL;

	if (pf->lag && pf->lag->bonded) {
		netdev_err(netdev, "DCB changes not allowed when in a bond\n");
		return -EINVAL;
	}

	new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;

	mutex_lock(&pf->tc_mutex);

	new_cfg->etscfg.willing = ets->willing;
	new_cfg->etscfg.cbs = ets->cbs;
	ice_for_each_traffic_class(i) {
		new_cfg->etscfg.tcbwtable[i] = ets->tc_tx_bw[i];
		bwcfg += ets->tc_tx_bw[i];
		new_cfg->etscfg.tsatable[i] = ets->tc_tsa[i];
		if (new_cfg->pfc_mode == ICE_QOS_MODE_VLAN) {
			/* in DSCP mode up->tc mapping cannot change */
			new_cfg->etscfg.prio_table[i] = ets->prio_tc[i];
			new_cfg->etsrec.prio_table[i] = ets->reco_prio_tc[i];
		}
		new_cfg->etsrec.tcbwtable[i] = ets->tc_reco_bw[i];
		bwrec += ets->tc_reco_bw[i];
		new_cfg->etsrec.tsatable[i] = ets->tc_reco_tsa[i];
	}

	if (ice_dcb_bwchk(pf, new_cfg)) {
		err = -EINVAL;
		goto ets_out;
	}

	new_cfg->etscfg.maxtcs = pf->hw.func_caps.common_cap.maxtc;

	if (!bwcfg)
		new_cfg->etscfg.tcbwtable[0] = 100;

	if (!bwrec)
		new_cfg->etsrec.tcbwtable[0] = 100;

	err = ice_pf_dcb_cfg(pf, new_cfg, true);
	/* return of zero indicates new cfg applied */
	if (err == ICE_DCB_HW_CHG_RST)
		ice_dcbnl_devreset(netdev);
	if (err == ICE_DCB_NO_HW_CHG)
		err = ICE_DCB_HW_CHG_RST;

ets_out:
	mutex_unlock(&pf->tc_mutex);
	return err;
}

/**
 * ice_dcbnl_getnumtcs - Get max number of traffic classes supported
 * @dev: pointer to netdev struct
 * @tcid: TC ID
 * @num: total number of TCs supported by the adapter
 *
 * Return the total number of TCs supported
 */
static int
ice_dcbnl_getnumtcs(struct net_device *dev, int __always_unused tcid, u8 *num)
{
	struct ice_pf *pf = ice_netdev_to_pf(dev);

	if (!test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags))
		return -EINVAL;

	*num = pf->hw.func_caps.common_cap.maxtc;
	return 0;
}

/**
 * ice_dcbnl_getdcbx - retrieve current DCBX capability
 * @netdev: pointer to the netdev struct
 */
static u8 ice_dcbnl_getdcbx(struct net_device *netdev)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);

	return pf->dcbx_cap;
}

/**
 * ice_dcbnl_setdcbx - set required DCBX capability
 * @netdev: the corresponding netdev
 * @mode: required mode
 */
static u8 ice_dcbnl_setdcbx(struct net_device *netdev, u8 mode)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);
	struct ice_qos_cfg *qos_cfg;

	/* if FW LLDP agent is running, DCBNL not allowed to change mode */
	if (test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags))
		return ICE_DCB_NO_HW_CHG;

	/* No support for LLD_MANAGED modes or CEE+IEEE */
	if ((mode & DCB_CAP_DCBX_LLD_MANAGED) ||
	    ((mode & DCB_CAP_DCBX_VER_IEEE) && (mode & DCB_CAP_DCBX_VER_CEE)) ||
	    !(mode & DCB_CAP_DCBX_HOST))
		return ICE_DCB_NO_HW_CHG;

	/* Already set to the given mode no change */
	if (mode == pf->dcbx_cap)
		return ICE_DCB_NO_HW_CHG;

	if (pf->lag && pf->lag->bonded) {
		netdev_err(netdev, "DCB changes not allowed when in a bond\n");
		return ICE_DCB_NO_HW_CHG;
	}

	qos_cfg = &pf->hw.port_info->qos_cfg;

	/* DSCP configuration is not DCBx negotiated */
	if (qos_cfg->local_dcbx_cfg.pfc_mode == ICE_QOS_MODE_DSCP)
		return ICE_DCB_NO_HW_CHG;

	pf->dcbx_cap = mode;

	if (mode & DCB_CAP_DCBX_VER_CEE)
		qos_cfg->local_dcbx_cfg.dcbx_mode = ICE_DCBX_MODE_CEE;
	else
		qos_cfg->local_dcbx_cfg.dcbx_mode = ICE_DCBX_MODE_IEEE;

	dev_info(ice_pf_to_dev(pf), "DCBx mode = 0x%x\n", mode);
	return ICE_DCB_HW_CHG_RST;
}

/**
 * ice_dcbnl_get_perm_hw_addr - MAC address used by DCBX
 * @netdev: pointer to netdev struct
 * @perm_addr: buffer to return permanent MAC address
 */
static void ice_dcbnl_get_perm_hw_addr(struct net_device *netdev, u8 *perm_addr)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);
	struct ice_port_info *pi = pf->hw.port_info;
	int i, j;

	memset(perm_addr, 0xff, MAX_ADDR_LEN);

	for (i = 0; i < netdev->addr_len; i++)
		perm_addr[i] = pi->mac.perm_addr[i];

	for (j = 0; j < netdev->addr_len; j++, i++)
		perm_addr[i] = pi->mac.perm_addr[j];
}

/**
 * ice_get_pfc_delay - Retrieve PFC Link Delay
 * @hw: pointer to HW struct
 * @delay: holds the PFC Link Delay value
 */
static void ice_get_pfc_delay(struct ice_hw *hw, u16 *delay)
{
	u32 val;

	val = rd32(hw, PRTDCB_GENC);
	*delay = FIELD_GET(PRTDCB_GENC_PFCLDA_M, val);
}

/**
 * ice_dcbnl_getpfc - retrieve local IEEE PFC config
 * @netdev: pointer to netdev struct
 * @pfc: struct to hold PFC info
 */
static int ice_dcbnl_getpfc(struct net_device *netdev, struct ieee_pfc *pfc)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);
	struct ice_port_info *pi = pf->hw.port_info;
	struct ice_dcbx_cfg *dcbxcfg;
	int i;

	dcbxcfg = &pi->qos_cfg.local_dcbx_cfg;
	pfc->pfc_cap = dcbxcfg->pfc.pfccap;
	pfc->pfc_en = dcbxcfg->pfc.pfcena;
	pfc->mbc = dcbxcfg->pfc.mbc;
	ice_get_pfc_delay(&pf->hw, &pfc->delay);

	ice_for_each_traffic_class(i) {
		pfc->requests[i] = pf->stats.priority_xoff_tx[i];
		pfc->indications[i] = pf->stats.priority_xoff_rx[i];
	}

	return 0;
}

/**
 * ice_dcbnl_setpfc - set local IEEE PFC config
 * @netdev: pointer to relevant netdev
 * @pfc: pointer to struct holding PFC config
 */
static int ice_dcbnl_setpfc(struct net_device *netdev, struct ieee_pfc *pfc)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);
	struct ice_dcbx_cfg *new_cfg;
	int err;

	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
		return -EINVAL;

	if (pf->lag && pf->lag->bonded) {
		netdev_err(netdev, "DCB changes not allowed when in a bond\n");
		return -EINVAL;
	}

	mutex_lock(&pf->tc_mutex);

	new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;

	if (pfc->pfc_cap)
		new_cfg->pfc.pfccap = pfc->pfc_cap;
	else
		new_cfg->pfc.pfccap = pf->hw.func_caps.common_cap.maxtc;

	new_cfg->pfc.pfcena = pfc->pfc_en;

	err = ice_pf_dcb_cfg(pf, new_cfg, true);
	if (err == ICE_DCB_HW_CHG_RST)
		ice_dcbnl_devreset(netdev);
	if (err == ICE_DCB_NO_HW_CHG)
		err = ICE_DCB_HW_CHG_RST;
	mutex_unlock(&pf->tc_mutex);
	return err;
}

/**
 * ice_dcbnl_get_pfc_cfg - Get CEE PFC config
 * @netdev: pointer to netdev struct
 * @prio: corresponding user priority
 * @setting: the PFC setting for given priority
 */
static void
ice_dcbnl_get_pfc_cfg(struct net_device *netdev, int prio, u8 *setting)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);
	struct ice_port_info *pi = pf->hw.port_info;

	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
		return;

	if (prio >= ICE_MAX_USER_PRIORITY)
		return;

	*setting = (pi->qos_cfg.local_dcbx_cfg.pfc.pfcena >> prio) & 0x1;
	dev_dbg(ice_pf_to_dev(pf), "Get PFC Config up=%d, setting=%d, pfcenable=0x%x\n",
		prio, *setting, pi->qos_cfg.local_dcbx_cfg.pfc.pfcena);
}

/**
 * ice_dcbnl_set_pfc_cfg - Set CEE PFC config
 * @netdev: the corresponding netdev
 * @prio: User Priority
 * @set: PFC setting to apply
 */
static void ice_dcbnl_set_pfc_cfg(struct net_device *netdev, int prio, u8 set)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);
	struct ice_dcbx_cfg *new_cfg;

	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
		return;

	if (prio >= ICE_MAX_USER_PRIORITY)
		return;

	if (pf->lag && pf->lag->bonded) {
		netdev_err(netdev, "DCB changes not allowed when in a bond\n");
		return;
	}

	new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;

	new_cfg->pfc.pfccap = pf->hw.func_caps.common_cap.maxtc;
	if (set)
		new_cfg->pfc.pfcena |= BIT(prio);
	else
		new_cfg->pfc.pfcena &= ~BIT(prio);

	dev_dbg(ice_pf_to_dev(pf), "Set PFC config UP:%d set:%d pfcena:0x%x\n",
		prio, set, new_cfg->pfc.pfcena);
}

/**
 * ice_dcbnl_getpfcstate - get CEE PFC mode
 * @netdev: pointer to netdev struct
 */
static u8 ice_dcbnl_getpfcstate(struct net_device *netdev)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);
	struct ice_port_info *pi = pf->hw.port_info;

	/* Return enabled if any UP enabled for PFC */
	if (pi->qos_cfg.local_dcbx_cfg.pfc.pfcena)
		return 1;

	return 0;
}

/**
 * ice_dcbnl_getstate - get DCB enabled state
 * @netdev: pointer to netdev struct
 */
static u8 ice_dcbnl_getstate(struct net_device *netdev)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);
	u8 state = 0;

	state = test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags);

	dev_dbg(ice_pf_to_dev(pf), "DCB enabled state = %d\n", state);
	return state;
}

/**
 * ice_dcbnl_setstate - Set CEE DCB state
 * @netdev: pointer to relevant netdev
 * @state: state value to set
 */
static u8 ice_dcbnl_setstate(struct net_device *netdev, u8 state)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);

	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
		return ICE_DCB_NO_HW_CHG;

	if (pf->lag && pf->lag->bonded) {
		netdev_err(netdev, "DCB changes not allowed when in a bond\n");
		return ICE_DCB_NO_HW_CHG;
	}

	/* Nothing to do */
	if (!!state == test_bit(ICE_FLAG_DCB_ENA, pf->flags))
		return ICE_DCB_NO_HW_CHG;

	if (state) {
		set_bit(ICE_FLAG_DCB_ENA, pf->flags);
		memcpy(&pf->hw.port_info->qos_cfg.desired_dcbx_cfg,
		       &pf->hw.port_info->qos_cfg.local_dcbx_cfg,
		       sizeof(struct ice_dcbx_cfg));
	} else {
		clear_bit(ICE_FLAG_DCB_ENA, pf->flags);
	}

	return ICE_DCB_HW_CHG;
}

/**
 * ice_dcbnl_get_pg_tc_cfg_tx - get CEE PG Tx config
 * @netdev: pointer to netdev struct
 * @prio: the corresponding user priority
 * @prio_type: traffic priority type
 * @pgid: the BW group ID the traffic class belongs to
 * @bw_pct: BW percentage for the corresponding BWG
 * @up_map: prio mapped to corresponding TC
 */
static void
ice_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int prio,
			   u8 __always_unused *prio_type, u8 *pgid,
			   u8 __always_unused *bw_pct,
			   u8 __always_unused *up_map)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);
	struct ice_port_info *pi = pf->hw.port_info;

	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
		return;

	if (prio >= ICE_MAX_USER_PRIORITY)
		return;

	*pgid = pi->qos_cfg.local_dcbx_cfg.etscfg.prio_table[prio];
	dev_dbg(ice_pf_to_dev(pf), "Get PG config prio=%d tc=%d\n", prio,
		*pgid);
}

/**
 * ice_dcbnl_set_pg_tc_cfg_tx - set CEE PG Tx config
 * @netdev: pointer to relevant netdev
 * @tc: the corresponding traffic class
 * @prio_type: the traffic priority type
 * @bwg_id: the BW group ID the TC belongs to
 * @bw_pct: the BW perventage for the BWG
 * @up_map: prio mapped to corresponding TC
 */
static void
ice_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
			   u8 __always_unused prio_type,
			   u8 __always_unused bwg_id,
			   u8 __always_unused bw_pct, u8 up_map)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);
	struct ice_dcbx_cfg *new_cfg;
	int i;

	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
		return;

	if (tc >= ICE_MAX_TRAFFIC_CLASS)
		return;

	if (pf->lag && pf->lag->bonded) {
		netdev_err(netdev, "DCB changes not allowed when in a bond\n");
		return;
	}

	new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;

	/* prio_type, bwg_id and bw_pct per UP are not supported */

	ice_for_each_traffic_class(i) {
		if (up_map & BIT(i))
			new_cfg->etscfg.prio_table[i] = tc;
	}
	new_cfg->etscfg.tsatable[tc] = ICE_IEEE_TSA_ETS;
}

/**
 * ice_dcbnl_get_pg_bwg_cfg_tx - Get CEE PGBW config
 * @netdev: pointer to the netdev struct
 * @pgid: corresponding traffic class
 * @bw_pct: the BW percentage for the corresponding TC
 */
static void
ice_dcbnl_get_pg_bwg_cfg_tx(struct net_device *netdev, int pgid, u8 *bw_pct)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);
	struct ice_port_info *pi = pf->hw.port_info;

	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
		return;

	if (pgid >= ICE_MAX_TRAFFIC_CLASS)
		return;

	*bw_pct = pi->qos_cfg.local_dcbx_cfg.etscfg.tcbwtable[pgid];
	dev_dbg(ice_pf_to_dev(pf), "Get PG BW config tc=%d bw_pct=%d\n",
		pgid, *bw_pct);
}

/**
 * ice_dcbnl_set_pg_bwg_cfg_tx - set CEE PG Tx BW config
 * @netdev: the corresponding netdev
 * @pgid: Correspongind traffic class
 * @bw_pct: the BW percentage for the specified TC
 */
static void
ice_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int pgid, u8 bw_pct)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);
	struct ice_dcbx_cfg *new_cfg;

	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
		return;

	if (pgid >= ICE_MAX_TRAFFIC_CLASS)
		return;

	if (pf->lag && pf->lag->bonded) {
		netdev_err(netdev, "DCB changes not allowed when in a bond\n");
		return;
	}

	new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;

	new_cfg->etscfg.tcbwtable[pgid] = bw_pct;
}

/**
 * ice_dcbnl_get_pg_tc_cfg_rx - Get CEE PG Rx config
 * @netdev: pointer to netdev struct
 * @prio: the corresponding user priority
 * @prio_type: the traffic priority type
 * @pgid: the PG ID
 * @bw_pct: the BW percentage for the corresponding BWG
 * @up_map: prio mapped to corresponding TC
 */
static void
ice_dcbnl_get_pg_tc_cfg_rx(struct net_device *netdev, int prio,
			   u8 __always_unused *prio_type, u8 *pgid,
			   u8 __always_unused *bw_pct,
			   u8 __always_unused *up_map)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);
	struct ice_port_info *pi = pf->hw.port_info;

	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
		return;

	if (prio >= ICE_MAX_USER_PRIORITY)
		return;

	*pgid = pi->qos_cfg.local_dcbx_cfg.etscfg.prio_table[prio];
}

/**
 * ice_dcbnl_set_pg_tc_cfg_rx
 * @netdev: relevant netdev struct
 * @prio: corresponding user priority
 * @prio_type: the traffic priority type
 * @pgid: the PG ID
 * @bw_pct: BW percentage for corresponding BWG
 * @up_map: prio mapped to corresponding TC
 *
 * lldpad requires this function pointer to be non-NULL to complete CEE config.
 */
static void
ice_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev,
			   int __always_unused prio,
			   u8 __always_unused prio_type,
			   u8 __always_unused pgid,
			   u8 __always_unused bw_pct,
			   u8 __always_unused up_map)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);

	dev_dbg(ice_pf_to_dev(pf), "Rx TC PG Config Not Supported.\n");
}

/**
 * ice_dcbnl_get_pg_bwg_cfg_rx - Get CEE PG BW Rx config
 * @netdev: pointer to netdev struct
 * @pgid: the corresponding traffic class
 * @bw_pct: the BW percentage for the corresponding TC
 */
static void
ice_dcbnl_get_pg_bwg_cfg_rx(struct net_device *netdev, int __always_unused pgid,
			    u8 *bw_pct)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);

	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
		return;

	*bw_pct = 0;
}

/**
 * ice_dcbnl_set_pg_bwg_cfg_rx
 * @netdev: the corresponding netdev
 * @pgid: corresponding TC
 * @bw_pct: BW percentage for given TC
 *
 * lldpad requires this function pointer to be non-NULL to complete CEE config.
 */
static void
ice_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int __always_unused pgid,
			    u8 __always_unused bw_pct)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);

	dev_dbg(ice_pf_to_dev(pf), "Rx BWG PG Config Not Supported.\n");
}

/**
 * ice_dcbnl_get_cap - Get DCBX capabilities of adapter
 * @netdev: pointer to netdev struct
 * @capid: the capability type
 * @cap: the capability value
 */
static u8 ice_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);

	if (!(test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags)))
		return ICE_DCB_NO_HW_CHG;

	switch (capid) {
	case DCB_CAP_ATTR_PG:
		*cap = true;
		break;
	case DCB_CAP_ATTR_PFC:
		*cap = true;
		break;
	case DCB_CAP_ATTR_UP2TC:
		*cap = false;
		break;
	case DCB_CAP_ATTR_PG_TCS:
		*cap = 0x80;
		break;
	case DCB_CAP_ATTR_PFC_TCS:
		*cap = 0x80;
		break;
	case DCB_CAP_ATTR_GSP:
		*cap = false;
		break;
	case DCB_CAP_ATTR_BCN:
		*cap = false;
		break;
	case DCB_CAP_ATTR_DCBX:
		*cap = pf->dcbx_cap;
		break;
	default:
		*cap = false;
		break;
	}

	dev_dbg(ice_pf_to_dev(pf), "DCBX Get Capability cap=%d capval=0x%x\n",
		capid, *cap);
	return 0;
}

/**
 * ice_dcbnl_getapp - get CEE APP
 * @netdev: pointer to netdev struct
 * @idtype: the App selector
 * @id: the App ethtype or port number
 */
static int ice_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);
	struct dcb_app app = {
				.selector = idtype,
				.protocol = id,
			     };

	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
		return -EINVAL;

	return dcb_getapp(netdev, &app);
}

/**
 * ice_dcbnl_find_app - Search for APP in given DCB config
 * @cfg: struct to hold DCBX config
 * @app: struct to hold app data to look for
 */
static bool
ice_dcbnl_find_app(struct ice_dcbx_cfg *cfg,
		   struct ice_dcb_app_priority_table *app)
{
	unsigned int i;

	for (i = 0; i < cfg->numapps; i++) {
		if (app->selector == cfg->app[i].selector &&
		    app->prot_id == cfg->app[i].prot_id &&
		    app->priority == cfg->app[i].priority)
			return true;
	}

	return false;
}

#define ICE_BYTES_PER_DSCP_VAL		8

/**
 * ice_dcbnl_setapp - set local IEEE App config
 * @netdev: relevant netdev struct
 * @app: struct to hold app config info
 */
static int ice_dcbnl_setapp(struct net_device *netdev, struct dcb_app *app)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);
	struct ice_dcb_app_priority_table new_app;
	struct ice_dcbx_cfg *old_cfg, *new_cfg;
	u8 max_tc;
	int ret;

	/* ONLY DSCP APP TLVs have operational significance */
	if (app->selector != IEEE_8021QAZ_APP_SEL_DSCP)
		return -EINVAL;

	/* only allow APP TLVs in SW Mode */
	if (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) {
		netdev_err(netdev, "can't do DSCP QoS when FW DCB agent active\n");
		return -EINVAL;
	}

	if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
		return -EINVAL;

	if (!ice_is_feature_supported(pf, ICE_F_DSCP))
		return -EOPNOTSUPP;

	if (app->protocol >= ICE_DSCP_NUM_VAL) {
		netdev_err(netdev, "DSCP value 0x%04X out of range\n",
			   app->protocol);
		return -EINVAL;
	}

	if (pf->lag && pf->lag->bonded) {
		netdev_err(netdev, "DCB changes not allowed when in a bond\n");
		return -EINVAL;
	}

	max_tc = pf->hw.func_caps.common_cap.maxtc;
	if (app->priority >= max_tc) {
		netdev_err(netdev, "TC %d out of range, max TC %d\n",
			   app->priority, max_tc);
		return -EINVAL;
	}

	/* grab TC mutex */
	mutex_lock(&pf->tc_mutex);

	new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;
	old_cfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg;

	ret = dcb_ieee_setapp(netdev, app);
	if (ret)
		goto setapp_out;

	if (test_and_set_bit(app->protocol, new_cfg->dscp_mapped)) {
		netdev_err(netdev, "DSCP value 0x%04X already user mapped\n",
			   app->protocol);
		ret = dcb_ieee_delapp(netdev, app);
		if (ret)
			netdev_err(netdev, "Failed to delete re-mapping TLV\n");
		ret = -EINVAL;
		goto setapp_out;
	}

	new_app.selector = app->selector;
	new_app.prot_id = app->protocol;
	new_app.priority = app->priority;

	/* If port is not in DSCP mode, need to set */
	if (old_cfg->pfc_mode == ICE_QOS_MODE_VLAN) {
		int i, j;

		/* set DSCP mode */
		ret = ice_aq_set_pfc_mode(&pf->hw, ICE_AQC_PFC_DSCP_BASED_PFC,
					  NULL);
		if (ret) {
			netdev_err(netdev, "Failed to set DSCP PFC mode %d\n",
				   ret);
			goto setapp_out;
		}
		netdev_info(netdev, "Switched QoS to L3 DSCP mode\n");

		new_cfg->pfc_mode = ICE_QOS_MODE_DSCP;

		/* set default DSCP QoS values */
		new_cfg->etscfg.willing = 0;
		new_cfg->pfc.pfccap = max_tc;
		new_cfg->pfc.willing = 0;

		for (i = 0; i < max_tc; i++)
			for (j = 0; j < ICE_BYTES_PER_DSCP_VAL; j++) {
				int dscp, offset;

				dscp = (i * max_tc) + j;
				offset = max_tc * ICE_BYTES_PER_DSCP_VAL;

				new_cfg->dscp_map[dscp] = i;
				/* if less that 8 TCs supported */
				if (max_tc < ICE_MAX_TRAFFIC_CLASS)
					new_cfg->dscp_map[dscp + offset] = i;
			}

		new_cfg->etscfg.tcbwtable[0] = 100;
		new_cfg->etscfg.tsatable[0] = ICE_IEEE_TSA_ETS;
		new_cfg->etscfg.prio_table[0] = 0;

		for (i = 1; i < max_tc; i++) {
			new_cfg->etscfg.tcbwtable[i] = 0;
			new_cfg->etscfg.tsatable[i] = ICE_IEEE_TSA_ETS;
			new_cfg->etscfg.prio_table[i] = i;
		}
	} /* end of switching to DSCP mode */

	/* apply new mapping for this DSCP value */
	new_cfg->dscp_map[app->protocol] = app->priority;
	new_cfg->app[new_cfg->numapps++] = new_app;

	ret = ice_pf_dcb_cfg(pf, new_cfg, true);
	/* return of zero indicates new cfg applied */
	if (ret == ICE_DCB_HW_CHG_RST)
		ice_dcbnl_devreset(netdev);
	else
		ret = ICE_DCB_NO_HW_CHG;

setapp_out:
	mutex_unlock(&pf->tc_mutex);
	return ret;
}

/**
 * ice_dcbnl_delapp - Delete local IEEE App config
 * @netdev: relevant netdev
 * @app: struct to hold app too delete
 *
 * Will not delete first application required by the FW
 */
static int ice_dcbnl_delapp(struct net_device *netdev, struct dcb_app *app)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);
	struct ice_dcbx_cfg *old_cfg, *new_cfg;
	unsigned int i, j;
	int ret = 0;

	if (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) {
		netdev_err(netdev, "can't delete DSCP netlink app when FW DCB agent is active\n");
		return -EINVAL;
	}

	if (pf->lag && pf->lag->bonded) {
		netdev_err(netdev, "DCB changes not allowed when in a bond\n");
		return -EINVAL;
	}

	mutex_lock(&pf->tc_mutex);
	old_cfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg;

	ret = dcb_ieee_delapp(netdev, app);
	if (ret)
		goto delapp_out;

	new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;

	for (i = 0; i < new_cfg->numapps; i++) {
		if (app->selector == new_cfg->app[i].selector &&
		    app->protocol == new_cfg->app[i].prot_id &&
		    app->priority == new_cfg->app[i].priority) {
			new_cfg->app[i].selector = 0;
			new_cfg->app[i].prot_id = 0;
			new_cfg->app[i].priority = 0;
			break;
		}
	}

	/* Did not find DCB App */
	if (i == new_cfg->numapps) {
		ret = -EINVAL;
		goto delapp_out;
	}

	new_cfg->numapps--;

	for (j = i; j < new_cfg->numapps; j++) {
		new_cfg->app[j].selector = old_cfg->app[j + 1].selector;
		new_cfg->app[j].prot_id = old_cfg->app[j + 1].prot_id;
		new_cfg->app[j].priority = old_cfg->app[j + 1].priority;
	}

	/* if not a DSCP APP TLV or DSCP is not supported, we are done */
	if (app->selector != IEEE_8021QAZ_APP_SEL_DSCP ||
	    !ice_is_feature_supported(pf, ICE_F_DSCP)) {
		ret = ICE_DCB_HW_CHG;
		goto delapp_out;
	}

	/* if DSCP TLV, then need to address change in mapping */
	clear_bit(app->protocol, new_cfg->dscp_mapped);
	/* remap this DSCP value to default value */
	new_cfg->dscp_map[app->protocol] = app->protocol %
					   ICE_BYTES_PER_DSCP_VAL;

	/* if the last DSCP mapping just got deleted, need to switch
	 * to L2 VLAN QoS mode
	 */
	if (bitmap_empty(new_cfg->dscp_mapped, ICE_DSCP_NUM_VAL) &&
	    new_cfg->pfc_mode == ICE_QOS_MODE_DSCP) {
		ret = ice_aq_set_pfc_mode(&pf->hw,
					  ICE_AQC_PFC_VLAN_BASED_PFC,
					  NULL);
		if (ret) {
			netdev_info(netdev, "Failed to set VLAN PFC mode %d\n",
				    ret);
			goto delapp_out;
		}
		netdev_info(netdev, "Switched QoS to L2 VLAN mode\n");

		new_cfg->pfc_mode = ICE_QOS_MODE_VLAN;

		ret = ice_dcb_sw_dflt_cfg(pf, true, true);
	} else {
		ret = ice_pf_dcb_cfg(pf, new_cfg, true);
	}

	/* return of ICE_DCB_HW_CHG_RST indicates new cfg applied
	 * and reset needs to be performed
	 */
	if (ret == ICE_DCB_HW_CHG_RST)
		ice_dcbnl_devreset(netdev);

	/* if the change was not siginificant enough to actually call
	 * the reconfiguration flow, we still need to tell caller that
	 * their request was successfully handled
	 */
	if (ret == ICE_DCB_NO_HW_CHG)
		ret = ICE_DCB_HW_CHG;

delapp_out:
	mutex_unlock(&pf->tc_mutex);
	return ret;
}

/**
 * ice_dcbnl_cee_set_all - Commit CEE DCB settings to HW
 * @netdev: the corresponding netdev
 */
static u8 ice_dcbnl_cee_set_all(struct net_device *netdev)
{
	struct ice_pf *pf = ice_netdev_to_pf(netdev);
	struct ice_dcbx_cfg *new_cfg;
	int err;

	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
		return ICE_DCB_NO_HW_CHG;

	if (pf->lag && pf->lag->bonded) {
		netdev_err(netdev, "DCB changes not allowed when in a bond\n");
		return ICE_DCB_NO_HW_CHG;
	}

	new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;

	mutex_lock(&pf->tc_mutex);

	err = ice_pf_dcb_cfg(pf, new_cfg, true);

	mutex_unlock(&pf->tc_mutex);
	return (err != ICE_DCB_HW_CHG_RST) ? ICE_DCB_NO_HW_CHG : err;
}

static const struct dcbnl_rtnl_ops dcbnl_ops = {
	/* IEEE 802.1Qaz std */
	.ieee_getets = ice_dcbnl_getets,
	.ieee_setets = ice_dcbnl_setets,
	.ieee_getpfc = ice_dcbnl_getpfc,
	.ieee_setpfc = ice_dcbnl_setpfc,
	.ieee_setapp = ice_dcbnl_setapp,
	.ieee_delapp = ice_dcbnl_delapp,

	/* CEE std */
	.getstate = ice_dcbnl_getstate,
	.setstate = ice_dcbnl_setstate,
	.getpermhwaddr = ice_dcbnl_get_perm_hw_addr,
	.setpgtccfgtx = ice_dcbnl_set_pg_tc_cfg_tx,
	.setpgbwgcfgtx = ice_dcbnl_set_pg_bwg_cfg_tx,
	.setpgtccfgrx = ice_dcbnl_set_pg_tc_cfg_rx,
	.setpgbwgcfgrx = ice_dcbnl_set_pg_bwg_cfg_rx,
	.getpgtccfgtx = ice_dcbnl_get_pg_tc_cfg_tx,
	.getpgbwgcfgtx = ice_dcbnl_get_pg_bwg_cfg_tx,
	.getpgtccfgrx = ice_dcbnl_get_pg_tc_cfg_rx,
	.getpgbwgcfgrx = ice_dcbnl_get_pg_bwg_cfg_rx,
	.setpfccfg = ice_dcbnl_set_pfc_cfg,
	.getpfccfg = ice_dcbnl_get_pfc_cfg,
	.setall = ice_dcbnl_cee_set_all,
	.getcap = ice_dcbnl_get_cap,
	.getnumtcs = ice_dcbnl_getnumtcs,
	.getpfcstate = ice_dcbnl_getpfcstate,
	.getapp = ice_dcbnl_getapp,

	/* DCBX configuration */
	.getdcbx = ice_dcbnl_getdcbx,
	.setdcbx = ice_dcbnl_setdcbx,
};

/**
 * ice_dcbnl_set_all - set all the apps and ieee data from DCBX config
 * @vsi: pointer to VSI struct
 */
void ice_dcbnl_set_all(struct ice_vsi *vsi)
{
	struct net_device *netdev = vsi->netdev;
	struct ice_dcbx_cfg *dcbxcfg;
	struct ice_port_info *pi;
	struct dcb_app sapp;
	struct ice_pf *pf;
	unsigned int i;

	if (!netdev)
		return;

	pf = ice_netdev_to_pf(netdev);
	pi = pf->hw.port_info;

	/* SW DCB taken care of by SW Default Config */
	if (pf->dcbx_cap & DCB_CAP_DCBX_HOST)
		return;

	/* DCB not enabled */
	if (!test_bit(ICE_FLAG_DCB_ENA, pf->flags))
		return;

	dcbxcfg = &pi->qos_cfg.local_dcbx_cfg;

	for (i = 0; i < dcbxcfg->numapps; i++) {
		u8 prio, tc_map;

		prio = dcbxcfg->app[i].priority;
		tc_map = BIT(dcbxcfg->etscfg.prio_table[prio]);

		/* Add APP only if the TC is enabled for this VSI */
		if (tc_map & vsi->tc_cfg.ena_tc) {
			sapp.selector = dcbxcfg->app[i].selector;
			sapp.protocol = dcbxcfg->app[i].prot_id;
			sapp.priority = prio;
			dcb_ieee_setapp(netdev, &sapp);
		}
	}
	/* Notify user-space of the changes */
	dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_SET, 0, 0);
}

/**
 * ice_dcbnl_vsi_del_app - Delete APP on all VSIs
 * @vsi: pointer to the main VSI
 * @app: APP to delete
 *
 * Delete given APP from all the VSIs for given PF
 */
static void
ice_dcbnl_vsi_del_app(struct ice_vsi *vsi,
		      struct ice_dcb_app_priority_table *app)
{
	struct dcb_app sapp;
	int err;

	sapp.selector = app->selector;
	sapp.protocol = app->prot_id;
	sapp.priority = app->priority;
	err = ice_dcbnl_delapp(vsi->netdev, &sapp);
	dev_dbg(ice_pf_to_dev(vsi->back), "Deleting app for VSI idx=%d err=%d sel=%d proto=0x%x, prio=%d\n",
		vsi->idx, err, app->selector, app->prot_id, app->priority);
}

/**
 * ice_dcbnl_flush_apps - Delete all removed APPs
 * @pf: the corresponding PF
 * @old_cfg: old DCBX configuration data
 * @new_cfg: new DCBX configuration data
 *
 * Find and delete all APPS that are not present in the passed
 * DCB configuration
 */
void
ice_dcbnl_flush_apps(struct ice_pf *pf, struct ice_dcbx_cfg *old_cfg,
		     struct ice_dcbx_cfg *new_cfg)
{
	struct ice_vsi *main_vsi = ice_get_main_vsi(pf);
	unsigned int i;

	if (!main_vsi)
		return;

	for (i = 0; i < old_cfg->numapps; i++) {
		struct ice_dcb_app_priority_table app = old_cfg->app[i];

		/* The APP is not available anymore delete it */
		if (!ice_dcbnl_find_app(new_cfg, &app))
			ice_dcbnl_vsi_del_app(main_vsi, &app);
	}
}

/**
 * ice_dcbnl_setup - setup DCBNL
 * @vsi: VSI to get associated netdev from
 */
void ice_dcbnl_setup(struct ice_vsi *vsi)
{
	struct net_device *netdev = vsi->netdev;
	struct ice_pf *pf;

	pf = ice_netdev_to_pf(netdev);
	if (!test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags))
		return;

	netdev->dcbnl_ops = &dcbnl_ops;
	ice_dcbnl_set_all(vsi);
}
