qcacmn: Host CCE Classification Changes
Host CCE Classification changes for RAW Mode workaround H/w CCE hangs while classfiying raw packets so the classification is moved to host Change-Id: I75cfc6b140a7983fcdfb797c93b9fd57f01c5ee3
This commit is contained in:

committad av
snandini

förälder
75ba86ec7c
incheckning
34721398d5
@@ -108,6 +108,7 @@
|
||||
*/
|
||||
enum cdp_cfg_param_type {
|
||||
CDP_CFG_MAX_PEER_ID,
|
||||
CDP_CFG_CCE_DISABLE,
|
||||
CDP_CFG_NUM_PARAMS
|
||||
};
|
||||
|
||||
@@ -938,6 +939,9 @@ struct cdp_tx_ingress_stats {
|
||||
/* Resource Full: Congestion Control */
|
||||
uint32_t res_full;
|
||||
} dropped;
|
||||
|
||||
/*Number of packets classified by CCE*/
|
||||
uint32_t cce_classified;
|
||||
};
|
||||
|
||||
struct cdp_vdev_stats {
|
||||
|
@@ -3830,6 +3830,7 @@ static inline void dp_aggregate_pdev_stats(struct dp_pdev *pdev)
|
||||
DP_STATS_AGGR(pdev, vdev, tx_i.dropped.enqueue_fail);
|
||||
DP_STATS_AGGR(pdev, vdev, tx_i.dropped.desc_na);
|
||||
DP_STATS_AGGR(pdev, vdev, tx_i.dropped.res_full);
|
||||
DP_STATS_AGGR(pdev, vdev, tx_i.cce_classified);
|
||||
|
||||
pdev->stats.tx_i.dropped.dropped_pkt.num =
|
||||
pdev->stats.tx_i.dropped.dma_error +
|
||||
@@ -3944,6 +3945,9 @@ dp_print_pdev_tx_stats(struct dp_pdev *pdev)
|
||||
pdev->stats.tx_i.nawds_mcast.num);
|
||||
DP_PRINT_STATS(" Bytes = %d",
|
||||
pdev->stats.tx_i.nawds_mcast.bytes);
|
||||
DP_PRINT_STATS("CCE Classified:");
|
||||
DP_TRACE(FATAL, " CCE Classified Packets: %u",
|
||||
pdev->stats.tx_i.cce_classified);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5686,6 +5690,7 @@ void *dp_soc_attach_wifi3(void *osif_soc, void *hif_handle,
|
||||
}
|
||||
|
||||
wlan_cfg_set_rx_hash(soc->wlan_cfg_ctx, rx_hash);
|
||||
soc->cce_disable = false;
|
||||
|
||||
if (soc->cdp_soc.ol_ops->get_dp_cfg_param) {
|
||||
int ret = soc->cdp_soc.ol_ops->get_dp_cfg_param(soc->osif_soc,
|
||||
@@ -5694,6 +5699,11 @@ void *dp_soc_attach_wifi3(void *osif_soc, void *hif_handle,
|
||||
if (ret != -EINVAL) {
|
||||
wlan_cfg_set_max_peer_id(soc->wlan_cfg_ctx, ret);
|
||||
}
|
||||
|
||||
ret = soc->cdp_soc.ol_ops->get_dp_cfg_param(soc->osif_soc,
|
||||
CDP_CFG_CCE_DISABLE);
|
||||
if (ret)
|
||||
soc->cce_disable = true;
|
||||
}
|
||||
|
||||
qdf_spinlock_create(&soc->peer_ref_mutex);
|
||||
|
@@ -868,6 +868,68 @@ static QDF_STATUS dp_tx_hw_enqueue(struct dp_soc *soc, struct dp_vdev *vdev,
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* dp_cce_classify() - Classify the frame based on CCE rules
|
||||
* @vdev: DP vdev handle
|
||||
* @nbuf: skb
|
||||
*
|
||||
* Classify frames based on CCE rules
|
||||
* Return: bool( true if classified,
|
||||
* else false)
|
||||
*/
|
||||
static bool dp_cce_classify(qdf_nbuf_t nbuf)
|
||||
{
|
||||
struct ether_header *eh = NULL;
|
||||
uint16_t ether_type;
|
||||
qdf_llc_t *llcHdr;
|
||||
qdf_nbuf_t nbuf_clone = NULL;
|
||||
|
||||
eh = (struct ether_header *) qdf_nbuf_data(nbuf);
|
||||
ether_type = eh->ether_type;
|
||||
|
||||
llcHdr = (qdf_llc_t *)(nbuf->data + sizeof(struct ether_header));
|
||||
|
||||
if (qdf_unlikely(DP_FRAME_IS_SNAP(llcHdr))) {
|
||||
ether_type = (uint16_t)*(nbuf->data + 2*ETHER_ADDR_LEN +
|
||||
sizeof(*llcHdr));
|
||||
nbuf_clone = qdf_nbuf_clone(nbuf);
|
||||
qdf_nbuf_pull_head(nbuf_clone, sizeof(*llcHdr));
|
||||
|
||||
if (ether_type == htons(ETHERTYPE_8021Q)) {
|
||||
qdf_nbuf_pull_head(nbuf_clone, sizeof(*llcHdr)
|
||||
+sizeof(qdf_net_vlanhdr_t));
|
||||
}
|
||||
} else {
|
||||
if (ether_type == htons(ETHERTYPE_8021Q)) {
|
||||
nbuf_clone = qdf_nbuf_clone(nbuf);
|
||||
qdf_nbuf_pull_head(nbuf_clone,
|
||||
sizeof(qdf_net_vlanhdr_t));
|
||||
}
|
||||
}
|
||||
|
||||
if (qdf_unlikely(nbuf_clone))
|
||||
nbuf = nbuf_clone;
|
||||
|
||||
if (qdf_unlikely(qdf_nbuf_is_ipv4_eapol_pkt(nbuf)
|
||||
|| qdf_nbuf_is_ipv4_arp_pkt(nbuf)
|
||||
|| qdf_nbuf_is_ipv4_wapi_pkt(nbuf)
|
||||
|| qdf_nbuf_is_ipv4_tdls_pkt(nbuf)
|
||||
|| (qdf_nbuf_is_ipv4_pkt(nbuf)
|
||||
&& qdf_nbuf_is_ipv4_dhcp_pkt(nbuf))
|
||||
|| (qdf_nbuf_is_ipv6_pkt(nbuf) &&
|
||||
qdf_nbuf_is_ipv6_dhcp_pkt(nbuf)))) {
|
||||
if (qdf_unlikely(nbuf_clone != NULL))
|
||||
qdf_nbuf_free(nbuf_clone);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (qdf_unlikely(nbuf_clone != NULL))
|
||||
qdf_nbuf_free(nbuf_clone);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_classify_tid() - Obtain TID to be used for this frame
|
||||
* @vdev: DP vdev handle
|
||||
@@ -928,7 +990,6 @@ static void dp_tx_classify_tid(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
||||
L3datap = hdr_ptr + sizeof(struct ether_header) +
|
||||
sizeof(*llcHdr);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (ether_type == htons(ETHERTYPE_8021Q)) {
|
||||
evh = (qdf_ethervlan_header_t *) eh;
|
||||
@@ -1068,6 +1129,14 @@ static qdf_nbuf_t dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
||||
return nbuf;
|
||||
}
|
||||
|
||||
if (qdf_unlikely(soc->cce_disable)) {
|
||||
if (dp_cce_classify(nbuf) == true) {
|
||||
DP_STATS_INC(vdev, tx_i.cce_classified, 1);
|
||||
tid = DP_VO_TID;
|
||||
tx_desc->flags |= DP_TX_DESC_FLAG_TO_FW;
|
||||
}
|
||||
}
|
||||
|
||||
dp_tx_update_tdls_flags(tx_desc);
|
||||
|
||||
if (qdf_unlikely(hal_srng_access_start(soc->hal_soc, hal_srng))) {
|
||||
@@ -1138,6 +1207,7 @@ qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
||||
struct dp_pdev *pdev = vdev->pdev;
|
||||
struct dp_soc *soc = pdev->soc;
|
||||
struct dp_tx_desc_s *tx_desc;
|
||||
bool is_cce_classified = false;
|
||||
QDF_STATUS status;
|
||||
|
||||
struct dp_tx_queue *tx_q = &msdu_info->tx_queue;
|
||||
@@ -1151,6 +1221,14 @@ qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
||||
return nbuf;
|
||||
}
|
||||
|
||||
if (qdf_unlikely(soc->cce_disable)) {
|
||||
is_cce_classified = dp_cce_classify(nbuf);
|
||||
if (is_cce_classified) {
|
||||
DP_STATS_INC(vdev, tx_i.cce_classified, 1);
|
||||
msdu_info->tid = DP_VO_TID;
|
||||
}
|
||||
}
|
||||
|
||||
if (msdu_info->frm_type == dp_tx_frm_me)
|
||||
nbuf = msdu_info->u.sg_info.curr_seg->nbuf;
|
||||
|
||||
@@ -1183,6 +1261,9 @@ qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
||||
tx_desc->flags |= DP_TX_DESC_FLAG_ME;
|
||||
}
|
||||
|
||||
if (is_cce_classified)
|
||||
tx_desc->flags |= DP_TX_DESC_FLAG_TO_FW;
|
||||
|
||||
/*
|
||||
* Enqueue the Tx MSDU descriptor to HW for transmit
|
||||
*/
|
||||
|
@@ -125,6 +125,9 @@ union dp_rx_desc_list_elem_t;
|
||||
(_a)[4] == 0xff && \
|
||||
(_a)[5] == 0xff)
|
||||
#define IS_LLC_PRESENT(typeorlen) ((typeorlen) >= 0x600)
|
||||
#define DP_FRAME_IS_SNAP(_llc) ((_llc)->llc_dsap == 0xaa && \
|
||||
(_llc)->llc_ssap == 0xaa && \
|
||||
(_llc)->llc_un.type_snap.control == 0x3)
|
||||
#define DP_FRAME_FC0_TYPE_MASK 0x0c
|
||||
#define DP_FRAME_FC0_TYPE_DATA 0x08
|
||||
#define DP_FRAME_IS_DATA(_frame) \
|
||||
@@ -585,6 +588,9 @@ struct dp_soc {
|
||||
/* Number of PDEVs */
|
||||
uint8_t pdev_count;
|
||||
|
||||
/*cce disable*/
|
||||
bool cce_disable;
|
||||
|
||||
/* Link descriptor memory banks */
|
||||
struct {
|
||||
void *base_vaddr_unaligned;
|
||||
|
@@ -60,6 +60,7 @@
|
||||
#define QDF_NBUF_TRAC_EAPOL_ETH_TYPE 0x888E
|
||||
#define QDF_NBUF_TRAC_WAPI_ETH_TYPE 0x88b4
|
||||
#define QDF_NBUF_TRAC_ARP_ETH_TYPE 0x0806
|
||||
#define QDF_NBUF_TRAC_TDLS_ETH_TYPE 0x890D
|
||||
#define QDF_NBUF_TRAC_IPV4_ETH_TYPE 0x0800
|
||||
#define QDF_NBUF_TRAC_IPV6_ETH_TYPE 0x86dd
|
||||
#define QDF_NBUF_DEST_MAC_OFFSET 0
|
||||
@@ -71,10 +72,14 @@
|
||||
#define QDF_NBUF_TRAC_IPV4_ADDR_BCAST_MASK 0xF0000000
|
||||
#define QDF_NBUF_TRAC_IPV6_DEST_ADDR_OFFSET 38
|
||||
#define QDF_NBUF_TRAC_IPV6_DEST_ADDR 0xFF00
|
||||
#define QDF_NBUF_TRAC_IPV6_OFFSET 14
|
||||
#define QDF_NBUF_TRAC_IPV6_HEADER_SIZE 40
|
||||
#define QDF_NBUF_TRAC_ICMP_TYPE 1
|
||||
#define QDF_NBUF_TRAC_TCP_TYPE 6
|
||||
#define QDF_NBUF_TRAC_UDP_TYPE 17
|
||||
#define QDF_NBUF_TRAC_ICMPV6_TYPE 0x3a
|
||||
#define QDF_NBUF_TRAC_DHCP6_SRV_PORT 547
|
||||
#define QDF_NBUF_TRAC_DHCP6_CLI_PORT 546
|
||||
|
||||
/* EAPOL Related MASK */
|
||||
#define EAPOL_PACKET_TYPE_OFFSET 15
|
||||
@@ -1769,6 +1774,21 @@ bool qdf_nbuf_data_is_ipv4_dhcp_pkt(uint8_t *data)
|
||||
return __qdf_nbuf_data_is_ipv4_dhcp_pkt(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* qdf_nbuf_data_is_ipv6_dhcp_pkt() - check if it is DHCP packet.
|
||||
* @data: Pointer to DHCP packet data buffer
|
||||
*
|
||||
* This func. checks whether it is a DHCP packet or not.
|
||||
*
|
||||
* Return: true if it is a DHCP packet
|
||||
* false if not
|
||||
*/
|
||||
static inline
|
||||
bool qdf_nbuf_is_ipv6_dhcp_pkt(qdf_nbuf_t buf)
|
||||
{
|
||||
return __qdf_nbuf_data_is_ipv6_dhcp_pkt(qdf_nbuf_data(buf));
|
||||
}
|
||||
|
||||
/**
|
||||
* qdf_nbuf_is_ipv4_eapol_pkt() - check if packet is a eapol packet or not
|
||||
* @buf: buffer
|
||||
@@ -1812,6 +1832,20 @@ bool qdf_nbuf_is_ipv4_wapi_pkt(qdf_nbuf_t buf)
|
||||
return __qdf_nbuf_is_ipv4_wapi_pkt(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* qdf_nbuf_is_ipv4_tdls_pkt() - check if packet is a tdls packet or not
|
||||
* @buf: buffer
|
||||
*
|
||||
* This api is for ipv4 packet.
|
||||
*
|
||||
* Return: true if packet is TDLS packet
|
||||
*/
|
||||
static inline
|
||||
bool qdf_nbuf_is_ipv4_tdls_pkt(qdf_nbuf_t buf)
|
||||
{
|
||||
return __qdf_nbuf_is_ipv4_tdls_pkt(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* qdf_nbuf_is_ipv4_arp_pkt() - check if packet is a arp packet or not
|
||||
* @buf: buffer
|
||||
|
@@ -626,6 +626,7 @@ QDF_STATUS __qdf_nbuf_frag_map(
|
||||
void qdf_nbuf_classify_pkt(struct sk_buff *skb);
|
||||
|
||||
bool __qdf_nbuf_is_ipv4_wapi_pkt(struct sk_buff *skb);
|
||||
bool __qdf_nbuf_is_ipv4_tdls_pkt(struct sk_buff *skb);
|
||||
bool __qdf_nbuf_data_is_ipv4_pkt(uint8_t *data);
|
||||
bool __qdf_nbuf_data_is_ipv6_pkt(uint8_t *data);
|
||||
bool __qdf_nbuf_data_is_ipv4_mcast_pkt(uint8_t *data);
|
||||
@@ -637,6 +638,7 @@ bool __qdf_nbuf_data_is_ipv4_tcp_pkt(uint8_t *data);
|
||||
bool __qdf_nbuf_data_is_ipv6_udp_pkt(uint8_t *data);
|
||||
bool __qdf_nbuf_data_is_ipv6_tcp_pkt(uint8_t *data);
|
||||
bool __qdf_nbuf_data_is_ipv4_dhcp_pkt(uint8_t *data);
|
||||
bool __qdf_nbuf_data_is_ipv6_dhcp_pkt(uint8_t *data);
|
||||
bool __qdf_nbuf_data_is_ipv4_eapol_pkt(uint8_t *data);
|
||||
bool __qdf_nbuf_data_is_ipv4_arp_pkt(uint8_t *data);
|
||||
enum qdf_proto_subtype __qdf_nbuf_data_get_dhcp_subtype(uint8_t *data);
|
||||
|
@@ -1033,6 +1033,30 @@ bool __qdf_nbuf_is_ipv4_wapi_pkt(struct sk_buff *skb)
|
||||
else
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL(__qdf_nbuf_is_ipv4_wapi_pkt);
|
||||
|
||||
/**
|
||||
* __qdf_nbuf_is_ipv4_tdls_pkt() - check if skb data is a tdls packet
|
||||
* @skb: Pointer to network buffer
|
||||
*
|
||||
* This api is for ipv4 packet.
|
||||
*
|
||||
* Return: true if packet is tdls packet
|
||||
* false otherwise.
|
||||
*/
|
||||
bool __qdf_nbuf_is_ipv4_tdls_pkt(struct sk_buff *skb)
|
||||
{
|
||||
uint16_t ether_type;
|
||||
|
||||
ether_type = *(uint16_t *)(skb->data +
|
||||
QDF_NBUF_TRAC_ETH_TYPE_OFFSET);
|
||||
|
||||
if (ether_type == QDF_SWAP_U16(QDF_NBUF_TRAC_TDLS_ETH_TYPE))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL(__qdf_nbuf_is_ipv4_tdls_pkt);
|
||||
|
||||
/**
|
||||
* __qdf_nbuf_data_is_ipv4_arp_pkt() - check if skb data is a arp packet
|
||||
@@ -1080,6 +1104,36 @@ bool __qdf_nbuf_data_is_ipv6_pkt(uint8_t *data)
|
||||
}
|
||||
EXPORT_SYMBOL(__qdf_nbuf_data_is_ipv6_pkt);
|
||||
|
||||
/**
|
||||
* __qdf_nbuf_data_is_ipv6_dhcp_pkt() - check if skb data is a dhcp packet
|
||||
* @data: Pointer to network data buffer
|
||||
*
|
||||
* This api is for ipv6 packet.
|
||||
*
|
||||
* Return: true if packet is DHCP packet
|
||||
* false otherwise
|
||||
*/
|
||||
bool __qdf_nbuf_data_is_ipv6_dhcp_pkt(uint8_t *data)
|
||||
{
|
||||
uint16_t sport;
|
||||
uint16_t dport;
|
||||
|
||||
sport = *(uint16_t *)(data + QDF_NBUF_TRAC_IPV6_OFFSET +
|
||||
QDF_NBUF_TRAC_IPV6_HEADER_SIZE);
|
||||
dport = *(uint16_t *)(data + QDF_NBUF_TRAC_IPV6_OFFSET +
|
||||
QDF_NBUF_TRAC_IPV6_HEADER_SIZE +
|
||||
sizeof(uint16_t));
|
||||
|
||||
if (((sport == QDF_SWAP_U16(QDF_NBUF_TRAC_DHCP6_SRV_PORT)) &&
|
||||
(dport == QDF_SWAP_U16(QDF_NBUF_TRAC_DHCP6_CLI_PORT))) ||
|
||||
((sport == QDF_SWAP_U16(QDF_NBUF_TRAC_DHCP6_CLI_PORT)) &&
|
||||
(dport == QDF_SWAP_U16(QDF_NBUF_TRAC_DHCP6_SRV_PORT))))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL(__qdf_nbuf_data_is_ipv6_dhcp_pkt);
|
||||
|
||||
/**
|
||||
* __qdf_nbuf_data_is_ipv4_mcast_pkt() - check if it is IPV4 multicast packet.
|
||||
* @data: Pointer to IPV4 packet data buffer
|
||||
|
Referens i nytt ärende
Block a user