be2net: fix a Tx stall bug caused by a specific ipv6 packet
Subsystems (3)
PATCH 2/3 be2net: fix a Tx stall bug caused by a specific ipv6 packet
The ASIC could lockup in the transmit path when it tries to insert VLAN in a specific ipv6 packet.
1) Identify the packet which can cause this.
2) Check if the firmware provides a workaround to prevent this.
3) If workaround is not present, drop the packet.
4) If the firmware provides a workaround, insert the VLAN tag in the packet and inform the firmware to skip further VLAN insertions.
Signed-off-by Ajit Khaparde <[email protected]>
--- drivers/net/ethernet/emulex/benet/be.h | 7 ++ drivers/net/ethernet/emulex/benet/be_cmds.c | 32 +++++++++ drivers/net/ethernet/emulex/benet/be_cmds.h | 13 ++++ drivers/net/ethernet/emulex/benet/be_main.c | 99 +++++++++++++++++++++++++-- 4 files changed, 144 insertions(+), 7 deletions(-)
drivers/net/ethernet/emulex/benet/be.h +7 -0
@@ -328,6 +328,7 @@ enum vf_state {#define BE_FLAGS_WORKER_SCHEDULED (1 << 3)#define BE_UC_PMAC_COUNT 30#define BE_VF_UC_PMAC_COUNT 2 +#define BE_FLAGS_QNQ_ASYNC_EVT_RCVD (1 << 11)struct phy_info {u8 transceiver;
@@ -434,6 +435,7 @@ struct be_adapter {u8 wol_cap;bool wol;u32 uc_macs;/* Count of secondary UC MAC programmed */ +u16 qnq_vid;u32 msg_enable;int be_get_temp_freq;u16 max_mcast_mac;
@@ -648,6 +650,11 @@ static inline bool be_is_wol_excluded(struct be_adapter *adapter) } } +static inline int qnq_async_evt_rcvd (struct be_adapter *adapter) +{ +return adapter->flags &BE_FLAGS_QNQ_ASYNC_EVT_RCVD ; +} +extern void be_cq_notify (struct be_adapter *adapter,u16 qid,bool arm,u16 num_popped);extern void be_link_status_update (struct be_adapter *adapter,u8 link_status);
drivers/net/ethernet/emulex/benet/be_cmds.c +32 -0
@@ -263,6 +263,27 @@ static void be_async_grp5_evt_process(struct be_adapter *adapter, } } +static void be_async_dbg_evt_process (struct be_adapter *adapter, +u32 trailer,struct be_mcc_compl *cmp) +{ +u8 event_type =0 ; +struct be_async_event_qnq *evt = (struct be_async_event_qnq *) cmp; + + event_type = (trailer >>ASYNC_TRAILER_EVENT_TYPE_SHIFT ) & +ASYNC_TRAILER_EVENT_TYPE_MASK ; + +switch (event_type) { +case ASYNC_DEBUG_EVENT_TYPE_QNQ : +if (evt->valid) + adapter->qnq_vid =le16_to_cpu (evt->vlan_tag); + adapter->flags |=BE_FLAGS_QNQ_ASYNC_EVT_RCVD ; +break ; +default : +dev_warn (&adapter->pdev->dev,"Unknown debug event\n" ); +break ; + } +} +static inline bool is_link_state_evt (u32 trailer) { return ((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
@@ -277,6 +298,13 @@ static inline bool is_grp5_evt(u32 trailer) ASYNC_EVENT_CODE_GRP_5); } +static inline bool is_dbg_evt (u32 trailer) +{ +return (((trailer >>ASYNC_TRAILER_EVENT_CODE_SHIFT ) & +ASYNC_TRAILER_EVENT_CODE_MASK ) == +ASYNC_EVENT_CODE_QNQ ); +} +static struct be_mcc_compl *be_mcc_compl_get (struct be_adapter *adapter) {struct be_queue_info *mcc_cq = &adapter->mcc_obj.cq;
@@ -325,6 +353,9 @@ int be_process_mcc(struct be_adapter *adapter)else if (is_grp5_evt (compl->flags))be_async_grp5_evt_process (adapter, compl->flags, compl); +else if (is_dbg_evt (compl->flags)) +be_async_dbg_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);
@@ -1022,6 +1053,7 @@ int be_cmd_mccq_ext_create(struct be_adapter *adapter,/* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */ req->async_event_bitmap[0 ] =cpu_to_le32 (0x00000022 ); + req->async_event_bitmap[0 ] |=cpu_to_le32 (1 <<ASYNC_EVENT_CODE_QNQ );be_dws_cpu_to_le (ctxt,sizeof (req->context));be_cmd_page_addrs_prepare (req->pages,ARRAY_SIZE (req->pages), q_mem);
drivers/net/ethernet/emulex/benet/be_cmds.h +13 -0
@@ -84,6 +84,9 @@ struct be_mcc_compl {#define ASYNC_EVENT_QOS_SPEED 0x1#define ASYNC_EVENT_COS_PRIORITY 0x2#define ASYNC_EVENT_PVID_STATE 0x3 +#define ASYNC_EVENT_CODE_QNQ 0x6 +#define ASYNC_DEBUG_EVENT_TYPE_QNQ 1 +struct be_async_event_trailer {u32 code; };
@@ -144,6 +147,16 @@ struct be_async_event_grp5_pvid_state {struct be_async_event_trailer trailer; } __packed; +/* async event indicating outer VLAN tag in QnQ */ +struct be_async_event_qnq { +u8 valid;/* Indicates if outer VLAN is valid */ +u8 rsvd0; +u16 vlan_tag; +u32 event_tag; +u8 rsvd1[4 ]; +struct be_async_event_trailer trailer; +} __packed; +struct be_mcc_mailbox {struct be_mcc_wrb wrb;struct be_mcc_compl compl;
drivers/net/ethernet/emulex/benet/be_main.c +92 -7
157 lines not on this page · raw message
Signature · 1 line
1.7.1