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

Commit cc4ce020 authored by Somnath Kotur's avatar Somnath Kotur Committed by David S. Miller
Browse files

be2net: Changes to use only priority codes allowed by f/w



Changes to use one of the priority codes allowed by CNA f/w for NIC traffic
from host. The driver gets the bit map of the priority codes allowed for
host traffic through a asynchronous message from the f/w that the driver
subscribes to.

Signed-off-by: default avatarSomnath Kotur <somnath.kotur@emulex.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e83726b0
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -264,6 +264,8 @@ struct be_adapter {
	u16 vlans_added;
	u16 max_vlans;	/* Number of vlans supported */
	u8 vlan_tag[VLAN_N_VID];
	u8 vlan_prio_bmap;	/* Available Priority BitMap */
	u16 recommended_prio;	/* Recommended Priority */
	struct be_dma_mem mc_cmd_mem;

	struct be_dma_mem stats_cmd;
+58 −3
Original line number Diff line number Diff line
@@ -96,6 +96,50 @@ static void be_async_link_state_process(struct be_adapter *adapter,
		evt->port_link_status == ASYNC_EVENT_LINK_UP);
}

/* Grp5 CoS Priority evt */
static void be_async_grp5_cos_priority_process(struct be_adapter *adapter,
		struct be_async_event_grp5_cos_priority *evt)
{
	if (evt->valid) {
		adapter->vlan_prio_bmap = evt->available_priority_bmap;
		adapter->recommended_prio =
			evt->reco_default_priority << VLAN_PRIO_SHIFT;
	}
}

/* Grp5 QOS Speed evt */
static void be_async_grp5_qos_speed_process(struct be_adapter *adapter,
		struct be_async_event_grp5_qos_link_speed *evt)
{
	if (evt->physical_port == adapter->port_num) {
		/* qos_link_speed is in units of 10 Mbps */
		adapter->link_speed = evt->qos_link_speed * 10;
	}
}

static void be_async_grp5_evt_process(struct be_adapter *adapter,
		u32 trailer, struct be_mcc_compl *evt)
{
	u8 event_type = 0;

	event_type = (trailer >> ASYNC_TRAILER_EVENT_TYPE_SHIFT) &
		ASYNC_TRAILER_EVENT_TYPE_MASK;

	switch (event_type) {
	case ASYNC_EVENT_COS_PRIORITY:
		be_async_grp5_cos_priority_process(adapter,
		(struct be_async_event_grp5_cos_priority *)evt);
	break;
	case ASYNC_EVENT_QOS_SPEED:
		be_async_grp5_qos_speed_process(adapter,
		(struct be_async_event_grp5_qos_link_speed *)evt);
	break;
	default:
		dev_warn(&adapter->pdev->dev, "Unknown grp5 event!\n");
		break;
	}
}

static inline bool is_link_state_evt(u32 trailer)
{
	return ((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
@@ -103,6 +147,13 @@ static inline bool is_link_state_evt(u32 trailer)
				ASYNC_EVENT_CODE_LINK_STATE;
}

static inline bool is_grp5_evt(u32 trailer)
{
	return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
		ASYNC_TRAILER_EVENT_CODE_MASK) ==
				ASYNC_EVENT_CODE_GRP_5);
}

static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter)
{
	struct be_queue_info *mcc_cq = &adapter->mcc_obj.cq;
@@ -143,6 +194,9 @@ int be_process_mcc(struct be_adapter *adapter, int *status)
			if (is_link_state_evt(compl->flags))
				be_async_link_state_process(adapter,
				(struct be_async_event_link_state *) compl);
			else if (is_grp5_evt(compl->flags))
				be_async_grp5_evt_process(adapter,
				compl->flags, compl);
		} else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
				*status = be_mcc_compl_process(adapter, compl);
				atomic_dec(&mcc_obj->q.used);
@@ -677,10 +731,10 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
	ctxt = &req->context;

	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
			OPCODE_COMMON_MCC_CREATE);
			OPCODE_COMMON_MCC_CREATE_EXT);

	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
			OPCODE_COMMON_MCC_CREATE, sizeof(*req));
			OPCODE_COMMON_MCC_CREATE_EXT, sizeof(*req));

	req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));

@@ -688,7 +742,8 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
	AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
		be_encoded_q_len(mccq->len));
	AMAP_SET_BITS(struct amap_mcc_context, cq_id, ctxt, cq->id);

	/* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */
	req->async_event_bitmap[0] |= 0x00000022;
	be_dws_cpu_to_le(ctxt, sizeof(req->context));

	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
+32 −1
Original line number Diff line number Diff line
@@ -82,7 +82,12 @@ struct be_mcc_compl {
 */
#define ASYNC_TRAILER_EVENT_CODE_SHIFT	8	/* bits 8 - 15 */
#define ASYNC_TRAILER_EVENT_CODE_MASK	0xFF
#define ASYNC_TRAILER_EVENT_TYPE_SHIFT	16
#define ASYNC_TRAILER_EVENT_TYPE_MASK	0xFF
#define ASYNC_EVENT_CODE_LINK_STATE	0x1
#define ASYNC_EVENT_CODE_GRP_5		0x5
#define ASYNC_EVENT_QOS_SPEED		0x1
#define ASYNC_EVENT_COS_PRIORITY	0x2
struct be_async_event_trailer {
	u32 code;
};
@@ -105,6 +110,30 @@ struct be_async_event_link_state {
	struct be_async_event_trailer trailer;
} __packed;

/* When the event code of an async trailer is GRP-5 and event_type is QOS_SPEED
 * the mcc_compl must be interpreted as follows
 */
struct be_async_event_grp5_qos_link_speed {
	u8 physical_port;
	u8 rsvd[5];
	u16 qos_link_speed;
	u32 event_tag;
	struct be_async_event_trailer trailer;
} __packed;

/* When the event code of an async trailer is GRP5 and event type is
 * CoS-Priority, the mcc_compl must be interpreted as follows
 */
struct be_async_event_grp5_cos_priority {
	u8 physical_port;
	u8 available_priority_bmap;
	u8 reco_default_priority;
	u8 valid;
	u8 rsvd0;
	u8 event_tag;
	struct be_async_event_trailer trailer;
} __packed;

struct be_mcc_mailbox {
	struct be_mcc_wrb wrb;
	struct be_mcc_compl compl;
@@ -125,6 +154,7 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_EQ_CREATE				13
#define OPCODE_COMMON_MCC_CREATE			21
#define OPCODE_COMMON_SET_QOS				28
#define OPCODE_COMMON_MCC_CREATE_EXT			90
#define OPCODE_COMMON_SEEPROM_READ			30
#define OPCODE_COMMON_NTWK_RX_FILTER    		34
#define OPCODE_COMMON_GET_FW_VERSION			35
@@ -338,6 +368,7 @@ struct be_cmd_req_mcc_create {
	struct be_cmd_req_hdr hdr;
	u16 num_pages;
	u16 rsvd0;
	u32 async_event_bitmap[1];
	u8 context[sizeof(struct amap_mcc_context) / 8];
	struct phys_addr pages[8];
} __packed;
+14 −6
Original line number Diff line number Diff line
@@ -429,9 +429,12 @@ static inline void wrb_fill(struct be_eth_wrb *wrb, u64 addr, int len)
	wrb->frag_len = len & ETH_WRB_FRAG_LEN_MASK;
}

static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb,
		u32 wrb_cnt, u32 len)
static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr,
		struct sk_buff *skb, u32 wrb_cnt, u32 len)
{
	u8 vlan_prio = 0;
	u16 vlan_tag = 0;

	memset(hdr, 0, sizeof(*hdr));

	AMAP_SET_BITS(struct amap_eth_hdr_wrb, crc, hdr, 1);
@@ -449,10 +452,15 @@ static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb,
			AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1);
	}

	if (vlan_tx_tag_present(skb)) {
	if (adapter->vlan_grp && vlan_tx_tag_present(skb)) {
		AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1);
		AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag,
			hdr, vlan_tx_tag_get(skb));
		vlan_tag = vlan_tx_tag_get(skb);
		vlan_prio = (vlan_tag & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
		/* If vlan priority provided by OS is NOT in available bmap */
		if (!(adapter->vlan_prio_bmap & (1 << vlan_prio)))
			vlan_tag = (vlan_tag & ~VLAN_PRIO_MASK) |
					adapter->recommended_prio;
		AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag, hdr, vlan_tag);
	}

	AMAP_SET_BITS(struct amap_eth_hdr_wrb, event, hdr, 1);
@@ -532,7 +540,7 @@ static int make_tx_wrbs(struct be_adapter *adapter,
		queue_head_inc(txq);
	}

	wrb_fill_hdr(hdr, first_skb, wrb_cnt, copied);
	wrb_fill_hdr(adapter, hdr, first_skb, wrb_cnt, copied);
	be_dws_cpu_to_le(hdr, sizeof(*hdr));

	return copied;