qcacmn: Add WLAN IPA RX exception packet to pm queue

Below signature is seen in driver logs.
Target is suspended (via send_process_dhcp_ind_cmd_tlv:244)
cds_trigger_recovery_handler: critical host timeout trigger
fw recovery for reason code 34

Suspend/Resume test is run with SAP started and a ref-client
is associated with the SAP. One DHCP-Req packet is received
from ref-client before driver completes the resume process.
With SAP_DHCP_FW_IND feature enabled, driver will send one
WMI cmd to target for such DHCP packets received.

With IPA_OFFLOAD enabled, such DHCP packets are received from
the RX exception callback from IPA driver. Hence add support
to queue these DHCP packets onto pm_queue_head skb queue when
WLAN IPA component is still in suspended state. When IPA component
is resumed from suspend state, pm_queue_head skb queue will be
drained to pass up queued RX exception packets to stack.

For QCA_IPA_LL_TX_FLOW_CONTROL enabled platforms, such as WIN
chipsets, suspend/resume is not supported. Hence wrap fixes
only for !QCA_IPA_LL_TX_FLOW_CONTROL.

Change-Id: I823005d9b58d1d62eec2c044621e1c1423aa3537
CRs-Fixed: 3457254
This commit is contained in:
Jia Ding
2023-04-05 22:42:00 +08:00
committed by Madan Koyyalamudi
父節點 54d4446b4b
當前提交 e5050154f1
共有 2 個文件被更改,包括 123 次插入4 次删除

查看文件

@@ -303,11 +303,13 @@ struct wlan_ipa_rx_hdr {
* @exception: Exception packet
* @iface_context: Interface context
* @ipa_tx_desc: IPA TX descriptor
* @send_to_nw: RX exception packet that needs to be passed up to stack
*/
struct wlan_ipa_pm_tx_cb {
bool exception;
struct wlan_ipa_iface_context *iface_context;
qdf_ipa_rx_data_t *ipa_tx_desc;
bool send_to_nw;
};
/**

查看文件

@@ -818,6 +818,7 @@ static void wlan_ipa_pm_flush(void *data)
struct wlan_ipa_pm_tx_cb *pm_tx_cb = NULL;
qdf_nbuf_t skb;
uint32_t dequeued = 0;
qdf_netdev_t ndev;
qdf_spin_lock_bh(&ipa_ctx->pm_lock);
while (((skb = qdf_nbuf_queue_remove(&ipa_ctx->pm_queue_head)) !=
@@ -836,6 +837,15 @@ static void wlan_ipa_pm_flush(void *data)
} else {
dev_kfree_skb_any(skb);
}
} else if (pm_tx_cb->send_to_nw) {
ndev = pm_tx_cb->iface_context->dev;
if (ipa_ctx->send_to_nw && ndev) {
ipa_ctx->send_to_nw(skb, ndev);
ipa_ctx->ipa_rx_net_send_count++;
} else {
dev_kfree_skb_any(skb);
}
} else {
wlan_ipa_send_pkt_to_tl(pm_tx_cb->iface_context,
pm_tx_cb->ipa_tx_desc);
@@ -1184,6 +1194,109 @@ static int wlan_ipa_send_sta_eapol_to_nw(qdf_nbuf_t skb,
return 0;
}
#ifndef QCA_IPA_LL_TX_FLOW_CONTROL
#ifdef SAP_DHCP_FW_IND
/**
* wlan_ipa_send_to_nw_sap_dhcp - Check if SAP mode and skb is a DHCP packet
* @iface_ctx: IPA per-interface ctx
* @skb: socket buffer
*
* Check if @iface_ctx is SAP and @skb is a DHCP packet.
*
* When SAP_DHCP_FW_IND feature is enabled, DHCP packets received will be
* notified to target via WMI cmd. However if system is suspended, WMI
* cmd is not allowed from Host to Target.
*
* Return: true if iface is SAP mode and skb is a DHCP packet. Otherwise false
*/
static bool
wlan_ipa_send_to_nw_sap_dhcp(struct wlan_ipa_iface_context *iface_ctx,
qdf_nbuf_t skb)
{
if (iface_ctx->device_mode == QDF_SAP_MODE &&
qdf_nbuf_is_ipv4_dhcp_pkt(skb) == true)
return true;
return false;
}
#else /* !SAP_DHCP_FW_IND */
static inline bool
wlan_ipa_send_to_nw_sap_dhcp(struct wlan_ipa_iface_context *iface_ctx,
qdf_nbuf_t skb)
{
return false;
}
#endif /* SAP_DHCP_FW_IND */
/**
* wlan_ipa_send_to_nw_defer - Check if skb needs to deferred to network stack
* @iface_ctx: IPA per-interface ctx
* @skb: socket buffer
*
* Check if @skb received on @iface_ctx needs to be deferred to be passed
* up to network stack.
*
* Return: true if needs to be deferred, otherwise false
*/
static bool wlan_ipa_send_to_nw_defer(struct wlan_ipa_iface_context *iface_ctx,
qdf_nbuf_t skb)
{
struct wlan_ipa_priv *ipa_ctx = iface_ctx->ipa_ctx;
qdf_spin_lock_bh(&ipa_ctx->pm_lock);
if (!ipa_ctx->suspended) {
qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
return false;
}
qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
return wlan_ipa_send_to_nw_sap_dhcp(iface_ctx, skb);
}
/**
* wlan_ipa_send_to_nw_queue - Add skb to pm_queue_head if deferred
* @iface_ctx: IPA per-interface ctx
* @skb: socket buffer
*
* Add @skb to pm_queue_head to defer passing up to network stack due to
* system suspended.
*
* Return: None
*/
static void wlan_ipa_send_to_nw_queue(struct wlan_ipa_iface_context *iface_ctx,
qdf_nbuf_t skb)
{
struct wlan_ipa_priv *ipa_ctx = iface_ctx->ipa_ctx;
struct wlan_ipa_pm_tx_cb *pm_cb;
qdf_mem_zero(skb->cb, sizeof(skb->cb));
pm_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb;
pm_cb->send_to_nw = true;
pm_cb->iface_context = iface_ctx;
qdf_spin_lock_bh(&ipa_ctx->pm_lock);
qdf_nbuf_queue_add(&ipa_ctx->pm_queue_head, skb);
qdf_spin_unlock_bh(&ipa_ctx->pm_lock);
ipa_ctx->stats.num_tx_queued++;
}
#else /* QCA_IPA_LL_TX_FLOW_CONTROL */
static inline bool
wlan_ipa_send_to_nw_defer(struct wlan_ipa_iface_context *iface_ctx,
qdf_nbuf_t skb)
{
return false;
}
static inline void
wlan_ipa_send_to_nw_queue(struct wlan_ipa_iface_context *iface_ctx,
qdf_nbuf_t skb)
{
}
#endif /* QCA_IPA_LL_TX_FLOW_CONTROL */
/**
* wlan_ipa_send_skb_to_network() - Send skb to kernel
* @skb: network buffer
@@ -1211,10 +1324,14 @@ wlan_ipa_send_skb_to_network(qdf_nbuf_t skb,
skb->destructor = wlan_ipa_uc_rt_debug_destructor;
if (ipa_ctx->send_to_nw)
ipa_ctx->send_to_nw(skb, iface_ctx->dev);
if (wlan_ipa_send_to_nw_defer(iface_ctx, skb)) {
wlan_ipa_send_to_nw_queue(iface_ctx, skb);
} else {
if (ipa_ctx->send_to_nw)
ipa_ctx->send_to_nw(skb, iface_ctx->dev);
ipa_ctx->ipa_rx_net_send_count++;
ipa_ctx->ipa_rx_net_send_count++;
}
}
/**
@@ -4199,7 +4316,7 @@ void wlan_ipa_flush(struct wlan_ipa_priv *ipa_ctx)
pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb;
if (pm_tx_cb->exception) {
if (pm_tx_cb->exception || pm_tx_cb->send_to_nw) {
dev_kfree_skb_any(skb);
} else {
if (pm_tx_cb->ipa_tx_desc)