qcacmn: Register separate function pointer to receive EAPOL frames

Add changes to register separate function pointer to receive EAPOL
frames instead of using regular RX path and adding export symbol
for __qdf_nbuf_data_get_eapol_subtype() to access in it multiple
modules

Change-Id: Id05b982d31a7e008536d10dd5281e88cceba96db
Esse commit está contido em:
Shiva Sankar Gajula
2021-08-21 09:09:56 +05:30
commit de Madan Koyyalamudi
commit dcbdb29d04
8 arquivos alterados com 177 adições e 15 exclusões

Ver arquivo

@@ -971,6 +971,7 @@ typedef void (*ol_txrx_pktdump_cb)(ol_txrx_soc_handle soc,
* format specified by the OS to use for tx and rx
* frames (either 802.3 or native WiFi). In case RX Threads are enabled, pkts
* are given to the thread, instead of the stack via this pointer.
* @rx.rx_eapol - This rx function pointer used to receive only eapol frames
* @rx.stack - function to give packets to the stack. Differs from @rx.rx.
* In case RX Threads are enabled, this pointer holds the callback to give
* packets to the stack.
@@ -1006,6 +1007,9 @@ struct ol_txrx_ops {
/* rx function pointers - specified by OS shim, stored by txrx */
struct {
ol_txrx_rx_fp rx;
#ifdef QCA_SUPPORT_EAPOL_OVER_CONTROL_PORT
ol_txrx_rx_fp rx_eapol;
#endif
ol_txrx_rx_fp rx_stack;
ol_txrx_rx_flush_fp rx_flush;
ol_txrx_rx_gro_flush_ind_fp rx_gro_flush;

Ver arquivo

@@ -2134,10 +2134,15 @@ struct cdp_peer_hmwds_ast_add_status {
uint8_t ast_mac[QDF_MAC_ADDR_SIZE];
};
/*
* Enumeration of cdp soc parameters
* @DP_SOC_PARAM_EAPOL_OVER_CONTROL_PORT: For sending EAPOL's over control port
*/
enum cdp_soc_param_t {
DP_SOC_PARAM_MSDU_EXCEPTION_DESC,
DP_SOC_PARAM_CMEM_FSE_SUPPORT,
DP_SOC_PARAM_MAX_AST_AGEOUT,
DP_SOC_PARAM_EAPOL_OVER_CONTROL_PORT,
DP_SOC_PARAM_MAX,
};

Ver arquivo

@@ -5763,6 +5763,41 @@ static void dp_vdev_pdev_list_remove(struct dp_soc *soc,
qdf_spin_unlock_bh(&pdev->vdev_list_lock);
}
#ifdef QCA_SUPPORT_EAPOL_OVER_CONTROL_PORT
/*
* dp_vdev_init_rx_eapol() - initializing osif_rx_eapol
* @vdev: Datapath VDEV handle
*
* Return: None
*/
static inline void dp_vdev_init_rx_eapol(struct dp_vdev *vdev)
{
vdev->osif_rx_eapol = NULL;
}
/*
* dp_vdev_register_rx_eapol() - Register VDEV operations for rx_eapol
* @vdev: DP vdev handle
* @txrx_ops: Tx and Rx operations
*
* Return: None
*/
static inline void dp_vdev_register_rx_eapol(struct dp_vdev *vdev,
struct ol_txrx_ops *txrx_ops)
{
vdev->osif_rx_eapol = txrx_ops->rx.rx_eapol;
}
#else
static inline void dp_vdev_init_rx_eapol(struct dp_vdev *vdev)
{
}
static inline void dp_vdev_register_rx_eapol(struct dp_vdev *vdev,
struct ol_txrx_ops *txrx_ops)
{
}
#endif
/*
* dp_vdev_attach_wifi3() - attach txrx vdev
* @txrx_pdev: Datapath PDEV handle
@@ -5825,6 +5860,7 @@ static QDF_STATUS dp_vdev_attach_wifi3(struct cdp_soc_t *cdp_soc,
vdev->drop_unenc = 1;
vdev->sec_type = cdp_sec_type_none;
vdev->multipass_en = false;
dp_vdev_init_rx_eapol(vdev);
qdf_atomic_init(&vdev->ref_cnt);
for (i = 0; i < DP_MOD_ID_MAX; i++)
qdf_atomic_init(&vdev->mod_refs[i]);
@@ -5998,6 +6034,8 @@ static QDF_STATUS dp_vdev_register_wifi3(struct cdp_soc_t *soc_hdl,
#endif
vdev->me_convert = txrx_ops->me_convert;
dp_vdev_register_rx_eapol(vdev, txrx_ops);
dp_vdev_register_tx_handler(vdev, soc, txrx_ops);
dp_init_info("%pK: DP Vdev Register success", soc);
@@ -10258,6 +10296,11 @@ static QDF_STATUS dp_soc_set_param(struct cdp_soc_t *soc_hdl,
soc->max_ast_ageout_count = value;
dp_info("Max ast ageout count %u", soc->max_ast_ageout_count);
break;
case DP_SOC_PARAM_EAPOL_OVER_CONTROL_PORT:
soc->eapol_over_control_port = value;
dp_info("Eapol over control_port:%d",
soc->eapol_over_control_port);
break;
default:
dp_info("not handled param %d ", param);
break;

Ver arquivo

@@ -1582,13 +1582,23 @@ static void dp_rx_check_delivery_to_stack(struct dp_soc *soc,
}
#endif /* ifdef DELIVERY_TO_STACK_STATUS_CHECK */
void dp_rx_deliver_to_stack(struct dp_soc *soc,
/*
* dp_rx_validate_rx_callbacks() - validate rx callbacks
* @soc DP soc
* @vdev: DP vdev handle
* @peer: pointer to the peer object
* nbuf_head: skb list head
*
* Return: QDF_STATUS - QDF_STATUS_SUCCESS
* QDF_STATUS_E_FAILURE
*/
static inline QDF_STATUS
dp_rx_validate_rx_callbacks(struct dp_soc *soc,
struct dp_vdev *vdev,
struct dp_peer *peer,
qdf_nbuf_t nbuf_head,
qdf_nbuf_t nbuf_tail)
qdf_nbuf_t nbuf_head)
{
int num_nbuf = 0;
int num_nbuf;
if (qdf_unlikely(!vdev || vdev->delete.pending)) {
num_nbuf = dp_rx_drop_nbuf_list(NULL, nbuf_head);
@@ -1598,7 +1608,7 @@ void dp_rx_deliver_to_stack(struct dp_soc *soc,
* belonged. Hence we update the soc rx error stats.
*/
DP_STATS_INC(soc, rx.err.invalid_vdev, num_nbuf);
return;
return QDF_STATUS_E_FAILURE;
}
/*
@@ -1613,9 +1623,22 @@ void dp_rx_deliver_to_stack(struct dp_soc *soc,
nbuf_head);
DP_STATS_DEC(peer, rx.to_stack.num, num_nbuf);
}
return;
return QDF_STATUS_E_FAILURE;
}
return QDF_STATUS_SUCCESS;
}
QDF_STATUS dp_rx_deliver_to_stack(struct dp_soc *soc,
struct dp_vdev *vdev,
struct dp_peer *peer,
qdf_nbuf_t nbuf_head,
qdf_nbuf_t nbuf_tail)
{
if (dp_rx_validate_rx_callbacks(soc, vdev, peer, nbuf_head) !=
QDF_STATUS_SUCCESS)
return QDF_STATUS_E_FAILURE;
if (qdf_unlikely(vdev->rx_decap_type == htt_cmn_pkt_type_raw) ||
(vdev->rx_decap_type == htt_cmn_pkt_type_native_wifi)) {
vdev->osif_rsim_rx_decap(vdev->osif_vdev, &nbuf_head,
@@ -1623,8 +1646,27 @@ void dp_rx_deliver_to_stack(struct dp_soc *soc,
}
dp_rx_check_delivery_to_stack(soc, vdev, peer, nbuf_head);
return QDF_STATUS_SUCCESS;
}
#ifdef QCA_SUPPORT_EAPOL_OVER_CONTROL_PORT
QDF_STATUS dp_rx_eapol_deliver_to_stack(struct dp_soc *soc,
struct dp_vdev *vdev,
struct dp_peer *peer,
qdf_nbuf_t nbuf_head,
qdf_nbuf_t nbuf_tail)
{
if (dp_rx_validate_rx_callbacks(soc, vdev, peer, nbuf_head) !=
QDF_STATUS_SUCCESS)
return QDF_STATUS_E_FAILURE;
vdev->osif_rx_eapol(vdev->osif_vdev, nbuf_head);
return QDF_STATUS_SUCCESS;
}
#endif
#ifndef QCA_HOST_MODE_WIFI_DISABLED
#ifdef VDEV_PEER_PROTOCOL_COUNT
#define dp_rx_msdu_stats_update_prot_cnts(vdev_hdl, nbuf, peer) \

Ver arquivo

@@ -1587,13 +1587,32 @@ QDF_STATUS dp_peer_set_rx_capture_enabled(struct dp_pdev *pdev,
* @nbuf_head: skb list head
* @nbuf_tail: skb list tail
*
* Return: None
* Return: QDF_STATUS
*/
void dp_rx_deliver_to_stack(struct dp_soc *soc,
struct dp_vdev *vdev,
struct dp_peer *peer,
qdf_nbuf_t nbuf_head,
qdf_nbuf_t nbuf_tail);
QDF_STATUS dp_rx_deliver_to_stack(struct dp_soc *soc,
struct dp_vdev *vdev,
struct dp_peer *peer,
qdf_nbuf_t nbuf_head,
qdf_nbuf_t nbuf_tail);
#ifdef QCA_SUPPORT_EAPOL_OVER_CONTROL_PORT
/**
* dp_rx_eapol_deliver_to_stack() - deliver pkts to network stack
* caller to hold peer refcount and check for valid peer
* @soc: soc
* @vdev: vdev
* @peer: peer
* @nbuf_head: skb list head
* @nbuf_tail: skb list tail
*
* return: QDF_STATUS
*/
QDF_STATUS dp_rx_eapol_deliver_to_stack(struct dp_soc *soc,
struct dp_vdev *vdev,
struct dp_peer *peer,
qdf_nbuf_t nbuf_head,
qdf_nbuf_t nbuf_tail);
#endif
#ifndef QCA_HOST_MODE_WIFI_DISABLED

Ver arquivo

@@ -1742,6 +1742,44 @@ fail:
return;
}
/*
* dp_rx_deliver_to_osif_stack() - function to deliver rx pkts to stack
* @soc: DP soc
* @vdv: DP vdev handle
* @peer: pointer to the peer object
* @nbuf: skb list head
* @tail: skb list tail
* @is_eapol: eapol pkt check
*
* Return: None
*/
#ifdef QCA_SUPPORT_EAPOL_OVER_CONTROL_PORT
static inline void
dp_rx_deliver_to_osif_stack(struct dp_soc *soc,
struct dp_vdev *vdev,
struct dp_peer *peer,
qdf_nbuf_t nbuf,
qdf_nbuf_t tail,
bool is_eapol)
{
if (is_eapol && soc->eapol_over_control_port)
dp_rx_eapol_deliver_to_stack(soc, vdev, peer, nbuf, NULL);
else
dp_rx_deliver_to_stack(soc, vdev, peer, nbuf, NULL);
}
#else
static inline void
dp_rx_deliver_to_osif_stack(struct dp_soc *soc,
struct dp_vdev *vdev,
struct dp_peer *peer,
qdf_nbuf_t nbuf,
qdf_nbuf_t tail,
bool is_eapol)
{
dp_rx_deliver_to_stack(soc, vdev, peer, nbuf, NULL);
}
#endif
#ifdef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG
/**
* dp_rx_err_route_hdl() - Function to send EAPOL frames to stack
@@ -1768,6 +1806,7 @@ dp_rx_err_route_hdl(struct dp_soc *soc, qdf_nbuf_t nbuf,
uint16_t msdu_len;
struct dp_vdev *vdev;
struct hal_rx_msdu_metadata msdu_metadata;
bool is_eapol;
hal_rx_msdu_metadata_get(soc->hal_soc, rx_tlv_hdr, &msdu_metadata);
msdu_len = hal_rx_msdu_start_msdu_len_get(soc->hal_soc, rx_tlv_hdr);
@@ -1820,8 +1859,8 @@ dp_rx_err_route_hdl(struct dp_soc *soc, qdf_nbuf_t nbuf,
* Indicate EAPOL frame to stack only when vap mac address
* matches the destination address.
*/
if (qdf_nbuf_is_ipv4_eapol_pkt(nbuf) ||
qdf_nbuf_is_ipv4_wapi_pkt(nbuf)) {
is_eapol = qdf_nbuf_is_ipv4_eapol_pkt(nbuf);
if (is_eapol || qdf_nbuf_is_ipv4_wapi_pkt(nbuf)) {
qdf_ether_header_t *eh =
(qdf_ether_header_t *)qdf_nbuf_data(nbuf);
if (qdf_mem_cmp(eh->ether_dhost, &vdev->mac_addr.raw[0],
@@ -1839,7 +1878,10 @@ dp_rx_err_route_hdl(struct dp_soc *soc, qdf_nbuf_t nbuf,
DP_STATS_INC(peer, rx.to_stack.num, 1);
qdf_nbuf_set_exc_frame(nbuf, 1);
qdf_nbuf_set_next(nbuf, NULL);
dp_rx_deliver_to_stack(soc, vdev, peer, nbuf, NULL);
dp_rx_deliver_to_osif_stack(soc, vdev, peer, nbuf,
NULL, is_eapol);
return;
}
}

Ver arquivo

@@ -1913,6 +1913,7 @@ struct dp_soc {
uint8_t wds_ast_aging_timer_cnt;
bool pending_ageout;
uint32_t max_ast_ageout_count;
uint8_t eapol_over_control_port;
qdf_timer_t lmac_reap_timer;
uint8_t lmac_timer_init;
@@ -2706,6 +2707,10 @@ struct dp_vdev {
ol_txrx_rx_gro_flush_ind_fp osif_gro_flush;
/* default RX call back function called by dp */
ol_txrx_rx_fp osif_rx;
#ifdef QCA_SUPPORT_EAPOL_OVER_CONTROL_PORT
/* callback to receive eapol frames */
ol_txrx_rx_fp osif_rx_eapol;
#endif
/* callback to deliver rx frames to the OS */
ol_txrx_rx_fp osif_rx_stack;
/* Callback to handle rx fisa frames */

Ver arquivo

@@ -1358,6 +1358,8 @@ __qdf_nbuf_data_get_eapol_subtype(uint8_t *data)
return subtype;
}
qdf_export_symbol(__qdf_nbuf_data_get_eapol_subtype);
/**
* __qdf_nbuf_data_get_arp_subtype() - get the subtype
* of ARP packet.