mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
wil6210: drop Rx packets with L2 error indication from HW
Due to recent change in FW, driver will be notified of corrupted Rx packets (e.g. MIC error). Drop such packets before they are delivered to network stack. Signed-off-by: Dedy Lansky <dlansky@codeaurora.org> Signed-off-by: Maya Erez <merez@codeaurora.org> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
parent
1bd82ee09a
commit
e15af41c05
@ -1734,13 +1734,11 @@ __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
|
|||||||
p->stats.rx_short_frame,
|
p->stats.rx_short_frame,
|
||||||
p->stats.rx_large_frame,
|
p->stats.rx_large_frame,
|
||||||
p->stats.rx_replay);
|
p->stats.rx_replay);
|
||||||
|
seq_printf(s,
|
||||||
if (wil->use_enhanced_dma_hw)
|
"mic error %lu, key error %lu, amsdu error %lu\n",
|
||||||
seq_printf(s,
|
p->stats.rx_mic_error,
|
||||||
"mic error %lu, key error %lu, amsdu error %lu\n",
|
p->stats.rx_key_error,
|
||||||
p->stats.rx_mic_error,
|
p->stats.rx_amsdu_error);
|
||||||
p->stats.rx_key_error,
|
|
||||||
p->stats.rx_amsdu_error);
|
|
||||||
|
|
||||||
seq_puts(s, "Rx/MCS:");
|
seq_puts(s, "Rx/MCS:");
|
||||||
for (mcs = 0; mcs < ARRAY_SIZE(p->stats.rx_per_mcs);
|
for (mcs = 0; mcs < ARRAY_SIZE(p->stats.rx_per_mcs);
|
||||||
|
@ -678,6 +678,21 @@ static int wil_rx_crypto_check(struct wil6210_priv *wil, struct sk_buff *skb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int wil_rx_error_check(struct wil6210_priv *wil, struct sk_buff *skb,
|
||||||
|
struct wil_net_stats *stats)
|
||||||
|
{
|
||||||
|
struct vring_rx_desc *d = wil_skb_rxdesc(skb);
|
||||||
|
|
||||||
|
if ((d->dma.status & RX_DMA_STATUS_ERROR) &&
|
||||||
|
(d->dma.error & RX_DMA_ERROR_MIC)) {
|
||||||
|
stats->rx_mic_error++;
|
||||||
|
wil_dbg_txrx(wil, "MIC error, dropping packet\n");
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void wil_get_netif_rx_params(struct sk_buff *skb, int *cid,
|
static void wil_get_netif_rx_params(struct sk_buff *skb, int *cid,
|
||||||
int *security)
|
int *security)
|
||||||
{
|
{
|
||||||
@ -736,6 +751,12 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
|
|||||||
goto stats;
|
goto stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check errors reported by HW and update statistics */
|
||||||
|
if (unlikely(wil->txrx_ops.rx_error_check(wil, skb, stats))) {
|
||||||
|
dev_kfree_skb(skb);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (wdev->iftype == NL80211_IFTYPE_AP && !vif->ap_isolate) {
|
if (wdev->iftype == NL80211_IFTYPE_AP && !vif->ap_isolate) {
|
||||||
if (mcast) {
|
if (mcast) {
|
||||||
/* send multicast frames both to higher layers in
|
/* send multicast frames both to higher layers in
|
||||||
@ -2212,6 +2233,7 @@ void wil_init_txrx_ops_legacy_dma(struct wil6210_priv *wil)
|
|||||||
wil->txrx_ops.get_netif_rx_params =
|
wil->txrx_ops.get_netif_rx_params =
|
||||||
wil_get_netif_rx_params;
|
wil_get_netif_rx_params;
|
||||||
wil->txrx_ops.rx_crypto_check = wil_rx_crypto_check;
|
wil->txrx_ops.rx_crypto_check = wil_rx_crypto_check;
|
||||||
|
wil->txrx_ops.rx_error_check = wil_rx_error_check;
|
||||||
wil->txrx_ops.is_rx_idle = wil_is_rx_idle;
|
wil->txrx_ops.is_rx_idle = wil_is_rx_idle;
|
||||||
wil->txrx_ops.rx_fini = wil_rx_fini;
|
wil->txrx_ops.rx_fini = wil_rx_fini;
|
||||||
}
|
}
|
||||||
|
@ -795,14 +795,15 @@ static int wil_check_bar(struct wil6210_priv *wil, void *msg, int cid,
|
|||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wil_rx_edma_check_errors(struct wil6210_priv *wil, void *msg,
|
static int wil_rx_error_check_edma(struct wil6210_priv *wil,
|
||||||
struct wil_net_stats *stats,
|
struct sk_buff *skb,
|
||||||
struct sk_buff *skb)
|
struct wil_net_stats *stats)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
int l2_rx_status;
|
int l2_rx_status;
|
||||||
int l3_rx_status;
|
int l3_rx_status;
|
||||||
int l4_rx_status;
|
int l4_rx_status;
|
||||||
|
void *msg = wil_skb_rxstatus(skb);
|
||||||
|
|
||||||
error = wil_rx_status_get_error(msg);
|
error = wil_rx_status_get_error(msg);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
@ -865,7 +866,6 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil,
|
|||||||
struct wil_net_stats *stats = NULL;
|
struct wil_net_stats *stats = NULL;
|
||||||
u16 dmalen;
|
u16 dmalen;
|
||||||
int cid;
|
int cid;
|
||||||
int rc;
|
|
||||||
bool eop, headstolen;
|
bool eop, headstolen;
|
||||||
int delta;
|
int delta;
|
||||||
u8 dr_bit;
|
u8 dr_bit;
|
||||||
@ -937,13 +937,6 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil,
|
|||||||
goto skipping;
|
goto skipping;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check and treat errors reported by HW */
|
|
||||||
rc = wil_rx_edma_check_errors(wil, msg, stats, skb);
|
|
||||||
if (rc) {
|
|
||||||
rxdata->skipping = true;
|
|
||||||
goto skipping;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely(dmalen > sz)) {
|
if (unlikely(dmalen > sz)) {
|
||||||
wil_err(wil, "Rx size too large: %d bytes!\n", dmalen);
|
wil_err(wil, "Rx size too large: %d bytes!\n", dmalen);
|
||||||
stats->rx_large_frame++;
|
stats->rx_large_frame++;
|
||||||
@ -1593,6 +1586,7 @@ void wil_init_txrx_ops_edma(struct wil6210_priv *wil)
|
|||||||
wil->txrx_ops.get_reorder_params = wil_get_reorder_params_edma;
|
wil->txrx_ops.get_reorder_params = wil_get_reorder_params_edma;
|
||||||
wil->txrx_ops.get_netif_rx_params = wil_get_netif_rx_params_edma;
|
wil->txrx_ops.get_netif_rx_params = wil_get_netif_rx_params_edma;
|
||||||
wil->txrx_ops.rx_crypto_check = wil_rx_crypto_check_edma;
|
wil->txrx_ops.rx_crypto_check = wil_rx_crypto_check_edma;
|
||||||
|
wil->txrx_ops.rx_error_check = wil_rx_error_check_edma;
|
||||||
wil->txrx_ops.is_rx_idle = wil_is_rx_idle_edma;
|
wil->txrx_ops.is_rx_idle = wil_is_rx_idle_edma;
|
||||||
wil->txrx_ops.rx_fini = wil_rx_fini_edma;
|
wil->txrx_ops.rx_fini = wil_rx_fini_edma;
|
||||||
}
|
}
|
||||||
|
@ -543,6 +543,27 @@ struct wil_status_ring {
|
|||||||
struct wil_ring_rx_data rx_data;
|
struct wil_ring_rx_data rx_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define WIL_STA_TID_NUM (16)
|
||||||
|
#define WIL_MCS_MAX (12) /* Maximum MCS supported */
|
||||||
|
|
||||||
|
struct wil_net_stats {
|
||||||
|
unsigned long rx_packets;
|
||||||
|
unsigned long tx_packets;
|
||||||
|
unsigned long rx_bytes;
|
||||||
|
unsigned long tx_bytes;
|
||||||
|
unsigned long tx_errors;
|
||||||
|
unsigned long rx_dropped;
|
||||||
|
unsigned long rx_non_data_frame;
|
||||||
|
unsigned long rx_short_frame;
|
||||||
|
unsigned long rx_large_frame;
|
||||||
|
unsigned long rx_replay;
|
||||||
|
unsigned long rx_mic_error;
|
||||||
|
unsigned long rx_key_error; /* eDMA specific */
|
||||||
|
unsigned long rx_amsdu_error; /* eDMA specific */
|
||||||
|
u16 last_mcs_rx;
|
||||||
|
u64 rx_per_mcs[WIL_MCS_MAX + 1];
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct tx_rx_ops - different TX/RX ops for legacy and enhanced
|
* struct tx_rx_ops - different TX/RX ops for legacy and enhanced
|
||||||
* DMA flow
|
* DMA flow
|
||||||
@ -576,6 +597,8 @@ struct wil_txrx_ops {
|
|||||||
void (*get_netif_rx_params)(struct sk_buff *skb,
|
void (*get_netif_rx_params)(struct sk_buff *skb,
|
||||||
int *cid, int *security);
|
int *cid, int *security);
|
||||||
int (*rx_crypto_check)(struct wil6210_priv *wil, struct sk_buff *skb);
|
int (*rx_crypto_check)(struct wil6210_priv *wil, struct sk_buff *skb);
|
||||||
|
int (*rx_error_check)(struct wil6210_priv *wil, struct sk_buff *skb,
|
||||||
|
struct wil_net_stats *stats);
|
||||||
bool (*is_rx_idle)(struct wil6210_priv *wil);
|
bool (*is_rx_idle)(struct wil6210_priv *wil);
|
||||||
irqreturn_t (*irq_rx)(int irq, void *cookie);
|
irqreturn_t (*irq_rx)(int irq, void *cookie);
|
||||||
};
|
};
|
||||||
@ -676,27 +699,6 @@ enum wil_sta_status {
|
|||||||
wil_sta_connected = 2,
|
wil_sta_connected = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define WIL_STA_TID_NUM (16)
|
|
||||||
#define WIL_MCS_MAX (12) /* Maximum MCS supported */
|
|
||||||
|
|
||||||
struct wil_net_stats {
|
|
||||||
unsigned long rx_packets;
|
|
||||||
unsigned long tx_packets;
|
|
||||||
unsigned long rx_bytes;
|
|
||||||
unsigned long tx_bytes;
|
|
||||||
unsigned long tx_errors;
|
|
||||||
unsigned long rx_dropped;
|
|
||||||
unsigned long rx_non_data_frame;
|
|
||||||
unsigned long rx_short_frame;
|
|
||||||
unsigned long rx_large_frame;
|
|
||||||
unsigned long rx_replay;
|
|
||||||
unsigned long rx_mic_error; /* eDMA specific */
|
|
||||||
unsigned long rx_key_error; /* eDMA specific */
|
|
||||||
unsigned long rx_amsdu_error; /* eDMA specific */
|
|
||||||
u16 last_mcs_rx;
|
|
||||||
u64 rx_per_mcs[WIL_MCS_MAX + 1];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct wil_sta_info - data for peer
|
* struct wil_sta_info - data for peer
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user