qcacmn: Support RX 2K jump/OOR frame handling from REO2TCL ring
Support RX 2K jump/OOR frame handling from REO2TCL ring. (a) configure REO error destination ring register to route 2K jump /OOR frame to REO2TCL ring. (b) for 2K jump RX frame, only accept ARP frame and drop others, meanwhile, send delba action frame to remote peer once receive first 2K jump data. (c) for OOR RX frame, accept ARP/EAPOL/DHCP/IPV6_DHCP frame, otherwise drop it. Change-Id: I7cb33279a8ba543686da4eba547e40f86813e057 CRs-Fixed: 2631949
This commit is contained in:
@@ -1676,25 +1676,6 @@ static inline bool dp_rx_enable_eol_data_check(struct dp_soc *soc)
|
||||
|
||||
#endif /* WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT */
|
||||
|
||||
/**
|
||||
* dp_is_special_data() - check is the pkt special like eapol, dhcp, etc
|
||||
*
|
||||
* @nbuf: pkt skb pointer
|
||||
*
|
||||
* Return: true if matched, false if not
|
||||
*/
|
||||
static inline
|
||||
bool dp_is_special_data(qdf_nbuf_t nbuf)
|
||||
{
|
||||
if (qdf_nbuf_is_ipv4_arp_pkt(nbuf) ||
|
||||
qdf_nbuf_is_ipv4_dhcp_pkt(nbuf) ||
|
||||
qdf_nbuf_is_ipv4_eapol_pkt(nbuf) ||
|
||||
qdf_nbuf_is_ipv6_dhcp_pkt(nbuf))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DP_RX_PKT_NO_PEER_DELIVER
|
||||
/**
|
||||
* dp_rx_deliver_to_stack_no_peer() - try deliver rx data even if
|
||||
@@ -1718,6 +1699,8 @@ void dp_rx_deliver_to_stack_no_peer(struct dp_soc *soc, qdf_nbuf_t nbuf)
|
||||
uint16_t msdu_len = 0;
|
||||
uint32_t pkt_len = 0;
|
||||
uint8_t *rx_tlv_hdr;
|
||||
uint32_t frame_mask = FRAME_MASK_IPV4_ARP | FRAME_MASK_IPV4_DHCP |
|
||||
FRAME_MASK_IPV4_EAPOL | FRAME_MASK_IPV6_DHCP;
|
||||
|
||||
peer_id = QDF_NBUF_CB_RX_PEER_ID(nbuf);
|
||||
if (peer_id > soc->max_peers)
|
||||
@@ -1728,30 +1711,28 @@ void dp_rx_deliver_to_stack_no_peer(struct dp_soc *soc, qdf_nbuf_t nbuf)
|
||||
if (!vdev || vdev->delete.pending || !vdev->osif_rx)
|
||||
goto deliver_fail;
|
||||
|
||||
if (qdf_unlikely(qdf_nbuf_is_frag(nbuf)))
|
||||
goto deliver_fail;
|
||||
|
||||
rx_tlv_hdr = qdf_nbuf_data(nbuf);
|
||||
l2_hdr_offset =
|
||||
hal_rx_msdu_end_l3_hdr_padding_get(soc->hal_soc, rx_tlv_hdr);
|
||||
|
||||
msdu_len = QDF_NBUF_CB_RX_PKT_LEN(nbuf);
|
||||
pkt_len = msdu_len + l2_hdr_offset + RX_PKT_TLVS_LEN;
|
||||
QDF_NBUF_CB_RX_NUM_ELEMENTS_IN_LIST(nbuf) = 1;
|
||||
|
||||
if (qdf_unlikely(qdf_nbuf_is_frag(nbuf))) {
|
||||
qdf_nbuf_pull_head(nbuf, RX_PKT_TLVS_LEN);
|
||||
} else {
|
||||
qdf_nbuf_set_pktlen(nbuf, pkt_len);
|
||||
qdf_nbuf_pull_head(nbuf,
|
||||
RX_PKT_TLVS_LEN +
|
||||
l2_hdr_offset);
|
||||
qdf_nbuf_set_pktlen(nbuf, pkt_len);
|
||||
qdf_nbuf_pull_head(nbuf,
|
||||
RX_PKT_TLVS_LEN +
|
||||
l2_hdr_offset);
|
||||
|
||||
if (dp_rx_is_special_frame(nbuf, frame_mask)) {
|
||||
vdev->osif_rx(vdev->osif_vdev, nbuf);
|
||||
DP_STATS_INC(soc, rx.err.pkt_delivered_no_peer, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* only allow special frames */
|
||||
if (!dp_is_special_data(nbuf))
|
||||
goto deliver_fail;
|
||||
|
||||
vdev->osif_rx(vdev->osif_vdev, nbuf);
|
||||
DP_STATS_INC(soc, rx.err.pkt_delivered_no_peer, 1);
|
||||
return;
|
||||
|
||||
deliver_fail:
|
||||
DP_STATS_INC_PKT(soc, rx.err.rx_invalid_peer, 1,
|
||||
QDF_NBUF_CB_RX_PKT_LEN(nbuf));
|
||||
@@ -2790,3 +2771,36 @@ dp_rx_nbuf_prepare(struct dp_soc *soc, struct dp_pdev *pdev)
|
||||
|
||||
return nbuf;
|
||||
}
|
||||
|
||||
#ifdef DP_RX_SPECIAL_FRAME_NEED
|
||||
bool dp_rx_deliver_special_frame(struct dp_soc *soc, struct dp_peer *peer,
|
||||
qdf_nbuf_t nbuf, uint32_t frame_mask)
|
||||
{
|
||||
uint32_t l2_hdr_offset = 0;
|
||||
uint16_t msdu_len = 0;
|
||||
uint32_t pkt_len = 0;
|
||||
uint8_t *rx_tlv_hdr;
|
||||
|
||||
if (qdf_unlikely(qdf_nbuf_is_frag(nbuf)))
|
||||
return false;
|
||||
|
||||
rx_tlv_hdr = qdf_nbuf_data(nbuf);
|
||||
l2_hdr_offset =
|
||||
hal_rx_msdu_end_l3_hdr_padding_get(soc->hal_soc, rx_tlv_hdr);
|
||||
|
||||
msdu_len = QDF_NBUF_CB_RX_PKT_LEN(nbuf);
|
||||
pkt_len = msdu_len + l2_hdr_offset + RX_PKT_TLVS_LEN;
|
||||
QDF_NBUF_CB_RX_NUM_ELEMENTS_IN_LIST(nbuf) = 1;
|
||||
|
||||
qdf_nbuf_set_pktlen(nbuf, pkt_len);
|
||||
dp_rx_skip_tlvs(nbuf, l2_hdr_offset);
|
||||
|
||||
if (dp_rx_is_special_frame(nbuf, frame_mask)) {
|
||||
dp_rx_deliver_to_stack(soc, peer->vdev, peer,
|
||||
nbuf, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user