Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f93f160b authored by Vasundhara Volam's avatar Vasundhara Volam Committed by David S. Miller
Browse files

be2net: refactor multi-channel config code for Skyhawk-R chip



Currently multi-channel configuration is read via the QUERY_FW_CONFIG cmd.
This method has been deprecated by the Skyhawk-R FW. Instead,
GET_PROFILE_CONFIG::port-desc must be used to query this configuration.

This patch also:
a) introduces a few macros to identify certain categories of multi-channel
configs
2) re-factors the be_cmd_set_profile_config() code to be able to read any kind
of desc (and not just the nic-desc.)

Signed-off-by: default avatarVasundhara Volam <vasundhara.volam@emulex.com>
Signed-off-by: default avatarSathya Perla <sathya.perla@emulex.com>
Signed-off-by: default avatarSomnath Kotur <somnath.kotur@emulex.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 40263820
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -88,7 +88,6 @@ static inline char *nic_name(struct pci_dev *pdev)
#define BE_MIN_MTU		256

#define BE_NUM_VLANS_SUPPORTED	64
#define BE_UMC_NUM_VLANS_SUPPORTED	15
#define BE_MAX_EQD		128u
#define	BE_MAX_TX_FRAG_COUNT	30

@@ -293,7 +292,7 @@ struct be_rx_compl_info {
	u8 ip_csum;
	u8 l4_csum;
	u8 ipv6;
	u8 vtm;
	u8 qnq;
	u8 pkt_type;
	u8 ip_frag;
};
@@ -465,6 +464,7 @@ struct be_adapter {

	u32 port_num;
	bool promiscuous;
	u8 mc_type;
	u32 function_mode;
	u32 function_caps;
	u32 rx_fc;		/* Rx flow control */
@@ -534,6 +534,14 @@ static inline u16 be_max_qs(struct be_adapter *adapter)
	return min_t(u16, num, num_online_cpus());
}

/* Is BE in pvid_tagging mode */
#define be_pvid_tagging_enabled(adapter)	(adapter->pvid)

/* Is BE in QNQ multi-channel mode */
#define be_is_qnq_mode(adapter)		(adapter->mc_type == FLEX10 ||  \
					 adapter->mc_type == vNIC1 ||	\
					 adapter->mc_type == UFP)

#define lancer_chip(adapter)	(adapter->pdev->device == OC_DEVICE_ID3 || \
				 adapter->pdev->device == OC_DEVICE_ID4)

+20 −0
Original line number Diff line number Diff line
@@ -3296,6 +3296,21 @@ static struct be_pcie_res_desc *be_get_pcie_desc(u8 devfn, u8 *buf,
	return NULL;
}

static struct be_port_res_desc *be_get_port_desc(u8 *buf, u32 desc_count)
{
	struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf;
	int i;

	for (i = 0; i < desc_count; i++) {
		if (hdr->desc_type == PORT_RESOURCE_DESC_TYPE_V1)
			return (struct be_port_res_desc *)hdr;

		hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0;
		hdr = (void *)hdr + hdr->desc_len;
	}
	return NULL;
}

static void be_copy_nic_desc(struct be_resources *res,
			     struct be_nic_res_desc *desc)
{
@@ -3439,6 +3454,7 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
{
	struct be_cmd_resp_get_profile_config *resp;
	struct be_pcie_res_desc *pcie;
	struct be_port_res_desc *port;
	struct be_nic_res_desc *nic;
	struct be_queue_info *mccq = &adapter->mcc_obj.q;
	struct be_dma_mem cmd;
@@ -3466,6 +3482,10 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
	if (pcie)
		res->max_vfs = le16_to_cpu(pcie->num_vfs);

	port = be_get_port_desc(resp->func_param, desc_count);
	if (port)
		adapter->mc_type = port->mc_type;

	nic = be_get_nic_desc(resp->func_param, desc_count);
	if (nic)
		be_copy_nic_desc(res, nic);
+28 −8
Original line number Diff line number Diff line
@@ -1098,14 +1098,6 @@ struct be_cmd_resp_query_fw_cfg {
	u32 function_caps;
};

/* Is BE in a multi-channel mode */
static inline bool be_is_mc(struct be_adapter *adapter)
{
	return adapter->function_mode & FLEX10_MODE ||
		adapter->function_mode & VNIC_MODE ||
		adapter->function_mode & UMC_ENABLED;
}

/******************** RSS Config ****************************************/
/* RSS type		Input parameters used to compute RX hash
 * RSS_ENABLE_IPV4	SRC IPv4, DST IPv4
@@ -1828,6 +1820,7 @@ struct be_cmd_req_set_ext_fat_caps {
#define NIC_RESOURCE_DESC_TYPE_V0		0x41
#define PCIE_RESOURCE_DESC_TYPE_V1		0x50
#define NIC_RESOURCE_DESC_TYPE_V1		0x51
#define PORT_RESOURCE_DESC_TYPE_V1		0x55
#define MAX_RESOURCE_DESC			264

/* QOS unit number */
@@ -1891,6 +1884,33 @@ struct be_nic_res_desc {
	u32 rsvd8[7];
} __packed;

/************ Multi-Channel type ***********/
enum mc_type {
	MC_NONE = 0x01,
	UMC = 0x02,
	FLEX10 = 0x03,
	vNIC1 = 0x04,
	nPAR = 0x05,
	UFP = 0x06,
	vNIC2 = 0x07
};

struct be_port_res_desc {
	struct be_res_desc_hdr hdr;
	u8 rsvd0;
	u8 flags;
	u8 rsvd1;
	u8 mc_type;
	u16 rsvd2;
	u32 rsvd3[20];
} __packed;

/* Is BE in a multi-channel mode */
static inline bool be_is_mc(struct be_adapter *adapter)
{
	return adapter->mc_type > MC_NONE;
}

struct be_cmd_req_get_func_config {
	struct be_cmd_req_hdr hdr;
};
+2 −2
Original line number Diff line number Diff line
@@ -368,7 +368,7 @@ struct amap_eth_rx_compl_v0 {
	u8 numfrags[3];		/* dword 1 */
	u8 rss_flush;		/* dword 2 */
	u8 cast_enc[2];		/* dword 2 */
	u8 vtm;			/* dword 2 */
	u8 qnq;			/* dword 2 */
	u8 rss_bank;		/* dword 2 */
	u8 rsvd1[23];		/* dword 2 */
	u8 lro_pkt;		/* dword 2 */
@@ -401,7 +401,7 @@ struct amap_eth_rx_compl_v1 {
	u8 numfrags[3];		/* dword 1 */
	u8 rss_flush;		/* dword 2 */
	u8 cast_enc[2];		/* dword 2 */
	u8 vtm;			/* dword 2 */
	u8 qnq;			/* dword 2 */
	u8 rss_bank;		/* dword 2 */
	u8 port[2];		/* dword 2 */
	u8 vntagp;		/* dword 2 */
+67 −20
Original line number Diff line number Diff line
@@ -945,9 +945,9 @@ static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter,
	}

	/* If vlan tag is already inlined in the packet, skip HW VLAN
	 * tagging in UMC mode
	 * tagging in pvid-tagging mode
	 */
	if ((adapter->function_mode & UMC_ENABLED) &&
	if (be_pvid_tagging_enabled(adapter) &&
	    veh->h_vlan_proto == htons(ETH_P_8021Q))
			*skip_hw_vlan = true;

@@ -1660,7 +1660,7 @@ static void be_parse_rx_compl_v1(struct be_eth_rx_compl *compl,
	rxcp->rss_hash =
		AMAP_GET_BITS(struct amap_eth_rx_compl_v1, rsshash, compl);
	if (rxcp->vlanf) {
		rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtm,
		rxcp->qnq = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, qnq,
					  compl);
		rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vlan_tag,
					       compl);
@@ -1690,7 +1690,7 @@ static void be_parse_rx_compl_v0(struct be_eth_rx_compl *compl,
	rxcp->rss_hash =
		AMAP_GET_BITS(struct amap_eth_rx_compl_v0, rsshash, compl);
	if (rxcp->vlanf) {
		rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtm,
		rxcp->qnq = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, qnq,
					  compl);
		rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vlan_tag,
					       compl);
@@ -1723,9 +1723,11 @@ static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo)
		rxcp->l4_csum = 0;

	if (rxcp->vlanf) {
		/* vlanf could be wrongly set in some cards.
		 * ignore if vtm is not set */
		if ((adapter->function_mode & FLEX10_MODE) && !rxcp->vtm)
		/* In QNQ modes, if qnq bit is not set, then the packet was
		 * tagged only with the transparent outer vlan-tag and must
		 * not be treated as a vlan packet by host
		 */
		if (be_is_qnq_mode(adapter) && !rxcp->qnq)
			rxcp->vlanf = 0;

		if (!lancer_chip(adapter))
@@ -3109,6 +3111,22 @@ err:
	return status;
}

/* Converting function_mode bits on BE3 to SH mc_type enums */

static u8 be_convert_mc_type(u32 function_mode)
{
	if (function_mode & VNIC_MODE && function_mode & FLEX10_MODE)
		return vNIC1;
	else if (function_mode & FLEX10_MODE)
		return FLEX10;
	else if (function_mode & VNIC_MODE)
		return vNIC2;
	else if (function_mode & UMC_ENABLED)
		return UMC;
	else
		return MC_NONE;
}

/* On BE2/BE3 FW does not suggest the supported limits */
static void BEx_get_resources(struct be_adapter *adapter,
			      struct be_resources *res)
@@ -3129,12 +3147,23 @@ static void BEx_get_resources(struct be_adapter *adapter,
	else
		res->max_uc_mac = BE_VF_UC_PMAC_COUNT;

	if (adapter->function_mode & FLEX10_MODE)
	adapter->mc_type = be_convert_mc_type(adapter->function_mode);

	if (be_is_mc(adapter)) {
		/* Assuming that there are 4 channels per port,
		 * when multi-channel is enabled
		 */
		if (be_is_qnq_mode(adapter))
			res->max_vlans = BE_NUM_VLANS_SUPPORTED/8;
	else if (adapter->function_mode & UMC_ENABLED)
		res->max_vlans = BE_UMC_NUM_VLANS_SUPPORTED;
		else
			/* In a non-qnq multichannel mode, the pvid
			 * takes up one vlan entry
			 */
			res->max_vlans = (BE_NUM_VLANS_SUPPORTED / 4) - 1;
	} else {
		res->max_vlans = BE_NUM_VLANS_SUPPORTED;
	}

	res->max_mcast_mac = BE_MAX_MC;

	/* For BE3 1Gb ports, F/W does not properly support multiple TXQs */
@@ -4417,14 +4446,32 @@ static bool be_reset_required(struct be_adapter *adapter)

static char *mc_name(struct be_adapter *adapter)
{
	if (adapter->function_mode & FLEX10_MODE)
		return "FLEX10";
	else if (adapter->function_mode & VNIC_MODE)
		return "vNIC";
	else if (adapter->function_mode & UMC_ENABLED)
		return "UMC";
	else
		return "";
	char *str = "";	/* default */

	switch (adapter->mc_type) {
	case UMC:
		str = "UMC";
		break;
	case FLEX10:
		str = "FLEX10";
		break;
	case vNIC1:
		str = "vNIC-1";
		break;
	case nPAR:
		str = "nPAR";
		break;
	case UFP:
		str = "UFP";
		break;
	case vNIC2:
		str = "vNIC-2";
		break;
	default:
		str = "";
	}

	return str;
}

static inline char *func_name(struct be_adapter *adapter)