Skip to content

Commit

Permalink
Merge ebf0fb5 on remote branch
Browse files Browse the repository at this point in the history
Change-Id: I8dba31267b7473e402e28c5f709a4307c5a2a433
  • Loading branch information
Linux Build Service Account committed Jun 10, 2021
2 parents 9838220 + ebf0fb5 commit b5ac667
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 31 deletions.
11 changes: 10 additions & 1 deletion drivers/char/diag/diag_dci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1737,7 +1737,16 @@ static int diag_send_dci_pkt_remote(unsigned char *data, int len, int tag,
write_len += dci_header_size;
*(int *)(buf + write_len) = tag;
write_len += sizeof(int);
memcpy(buf + write_len, data, len);
if ((write_len + len) < DIAG_MDM_BUF_SIZE) {
memcpy(buf + write_len, data, len);
} else {
pr_err("diag: skip writing invalid length packet, token: %d, pkt_len: %d\n",
token, (write_len + len));
spin_lock_irqsave(&driver->dci_mempool_lock, flags);
diagmem_free(driver, buf, dci_ops_tbl[token].mempool);
spin_unlock_irqrestore(&driver->dci_mempool_lock, flags);
return -EAGAIN;
}
write_len += len;
*(buf + write_len) = CONTROL_CHAR; /* End Terminator */
write_len += sizeof(uint8_t);
Expand Down
10 changes: 9 additions & 1 deletion drivers/net/wireless/ath/wil6210/main.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
Expand Down Expand Up @@ -308,6 +308,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
/* statistics */
memset(&sta->stats, 0, sizeof(sta->stats));
sta->stats.tx_latency_min_us = U32_MAX;
wil_sta_info_amsdu_init(sta);
}

static void _wil6210_disconnect_complete(struct wil6210_vif *vif,
Expand Down Expand Up @@ -705,6 +706,13 @@ void wil_bcast_fini_all(struct wil6210_priv *wil)
}
}

void wil_sta_info_amsdu_init(struct wil_sta_info *sta)
{
sta->amsdu_drop_sn = -1;
sta->amsdu_drop_tid = -1;
sta->amsdu_drop = 0;
}

int wil_priv_init(struct wil6210_priv *wil)
{
uint i;
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/wireless/ath/wil6210/pcie_bus.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
Expand Down Expand Up @@ -112,7 +112,6 @@ int wil_set_capabilities(struct wil6210_priv *wil)
set_bit(hw_capa_no_flash, wil->hw_capa);
wil->use_enhanced_dma_hw = true;
wil->use_rx_hw_reordering = true;
wil->use_compressed_rx_status = true;
wil_fw_name = ftm_mode ? WIL_FW_NAME_FTM_TALYN :
WIL_FW_NAME_TALYN;
if (wil_fw_verify_file_exists(wil, wil_fw_name))
Expand Down
52 changes: 33 additions & 19 deletions drivers/net/wireless/ath/wil6210/txrx.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
Expand Down Expand Up @@ -750,11 +750,11 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
unsigned int len = skb->len;
int cid;
int security;
struct ethhdr *eth = (void *)skb->data;
u8 *sa, *da = wil_skb_get_da(skb);
/* here looking for DA, not A1, thus Rxdesc's 'mcast' indication
* is not suitable, need to look at data
*/
int mcast = is_multicast_ether_addr(eth->h_dest);
int mcast = is_multicast_ether_addr(da);
struct wil_net_stats *stats;
struct sk_buff *xmit_skb = NULL;
static const char * const gro_res_str[] = {
Expand All @@ -772,6 +772,18 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)

skb_orphan(skb);

/* pass only EAPOL packets as plaintext */
if (vif->privacy && !security &&
wil_skb_get_protocol(skb) != htons(ETH_P_PAE)) {
wil_dbg_txrx(wil,
"Rx drop plaintext frame with %d bytes in secure network\n",
skb->len);
dev_kfree_skb(skb);
ndev->stats.rx_dropped++;
stats->rx_dropped++;
return;
}

if (security && (wil->txrx_ops.rx_crypto_check(wil, skb) != 0)) {
rc = GRO_DROP;
dev_kfree_skb(skb);
Expand All @@ -786,21 +798,23 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
}

if (wdev->iftype == NL80211_IFTYPE_STATION) {
if (mcast && ether_addr_equal(eth->h_source, ndev->dev_addr)) {
sa = wil_skb_get_sa(skb);
if (mcast && ether_addr_equal(sa, ndev->dev_addr)) {
/* mcast packet looped back to us */
rc = GRO_DROP;
dev_kfree_skb(skb);
goto stats;
}
} else if (wdev->iftype == NL80211_IFTYPE_AP && !vif->ap_isolate) {
} else if (wdev->iftype == NL80211_IFTYPE_AP && !vif->ap_isolate &&
/* pass EAPOL packets to local net stack only */
(wil_skb_get_protocol(skb) != htons(ETH_P_PAE))) {
if (mcast) {
/* send multicast frames both to higher layers in
* local net stack and back to the wireless medium
*/
xmit_skb = skb_copy(skb, GFP_ATOMIC);
} else {
int xmit_cid = wil_find_cid(wil, vif->mid,
eth->h_dest);
int xmit_cid = wil_find_cid(wil, vif->mid, da);

if (xmit_cid >= 0) {
/* The destination station is associated to
Expand Down Expand Up @@ -1244,12 +1258,13 @@ static struct wil_ring *wil_find_tx_ucast(struct wil6210_priv *wil,
struct wil6210_vif *vif,
struct sk_buff *skb)
{
int i;
struct ethhdr *eth = (void *)skb->data;
int cid = wil_find_cid(wil, vif->mid, eth->h_dest);
int i, cid;
const u8 *da = wil_skb_get_da(skb);
int min_ring_id = wil_get_min_tx_ring_id(wil);

if (cid < 0)
cid = wil_find_cid(wil, vif->mid, da);

if (cid < 0 || cid >= WIL6210_MAX_CID)
return NULL;

/* TODO: fix for multiple TID */
Expand All @@ -1262,7 +1277,7 @@ static struct wil_ring *wil_find_tx_ucast(struct wil6210_priv *wil,
struct wil_ring_tx_data *txdata = &wil->ring_tx_data[i];

wil_dbg_txrx(wil, "find_tx_ucast: (%pM) -> [%d]\n",
eth->h_dest, i);
da, i);
if (v->va && txdata->enabled) {
return v;
} else {
Expand Down Expand Up @@ -1353,10 +1368,10 @@ static struct wil_ring *wil_find_tx_bcast_1(struct wil6210_priv *wil,
static void wil_set_da_for_vring(struct wil6210_priv *wil,
struct sk_buff *skb, int vring_index)
{
struct ethhdr *eth = (void *)skb->data;
u8 *da = wil_skb_get_da(skb);
int cid = wil->ring2cid_tid[vring_index][0];

ether_addr_copy(eth->h_dest, wil->sta[cid].addr);
ether_addr_copy(da, wil->sta[cid].addr);
}

static struct wil_ring *wil_find_tx_bcast_2(struct wil6210_priv *wil,
Expand All @@ -1367,8 +1382,7 @@ static struct wil_ring *wil_find_tx_bcast_2(struct wil6210_priv *wil,
struct sk_buff *skb2;
int i;
u8 cid;
struct ethhdr *eth = (void *)skb->data;
char *src = eth->h_source;
const u8 *src = wil_skb_get_sa(skb);
struct wil_ring_tx_data *txdata, *txdata2;
int min_ring_id = wil_get_min_tx_ring_id(wil);

Expand Down Expand Up @@ -2122,8 +2136,8 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
struct wil6210_vif *vif = ndev_to_vif(ndev);
struct wil6210_priv *wil = vif_to_wil(vif);
struct ethhdr *eth = (void *)skb->data;
bool bcast = is_multicast_ether_addr(eth->h_dest);
const u8 *da = wil_skb_get_da(skb);
bool bcast = is_multicast_ether_addr(da);
struct wil_ring *ring;
static bool pr_once_fw;
int rc;
Expand Down Expand Up @@ -2170,7 +2184,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
ring = wil_find_tx_ucast(wil, vif, skb);
}
if (unlikely(!ring)) {
wil_dbg_txrx(wil, "No Tx RING found for %pM\n", eth->h_dest);
wil_dbg_txrx(wil, "No Tx RING found for %pM\n", da);
goto drop;
}
/* set up vring entry */
Expand Down
27 changes: 24 additions & 3 deletions drivers/net/wireless/ath/wil6210/txrx.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
Expand Down Expand Up @@ -560,11 +560,32 @@ static inline int wil_ring_is_full(struct wil_ring *ring)
return wil_ring_next_tail(ring) == ring->swhead;
}

static inline bool wil_need_txstat(struct sk_buff *skb)
static inline __be16 wil_skb_get_protocol(struct sk_buff *skb)
{
struct ethhdr *eth = (void *)skb->data;

return eth->h_proto;
}

static inline u8 *wil_skb_get_da(struct sk_buff *skb)
{
struct ethhdr *eth = (void *)skb->data;

return eth->h_dest;
}

static inline u8 *wil_skb_get_sa(struct sk_buff *skb)
{
struct ethhdr *eth = (void *)skb->data;

return is_unicast_ether_addr(eth->h_dest) && skb->sk &&
return eth->h_source;
}

static inline bool wil_need_txstat(struct sk_buff *skb)
{
const u8 *da = wil_skb_get_da(skb);

return is_unicast_ether_addr(da) && skb->sk &&
(skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS);
}

Expand Down
94 changes: 93 additions & 1 deletion drivers/net/wireless/ath/wil6210/txrx_edma.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
Expand Down Expand Up @@ -755,6 +755,92 @@ static int wil_tx_ring_modify_edma(struct wil6210_vif *vif, int ring_id,
return -EOPNOTSUPP;
}

static int wil_check_amsdu(struct wil6210_priv *wil, void *msg, int cid,
struct wil_ring_rx_data *rxdata,
struct sk_buff *skb)
{
u8 *sa, *da;
int mid, tid;
u16 seq;
struct wil6210_vif *vif;
struct net_device *ndev;
struct wil_sta_info *sta;

/* drop all WDS packets - not supported */
if (wil_rx_status_get_ds_type(wil, msg) == WIL_RX_EDMA_DS_TYPE_WDS) {
wil_dbg_txrx(wil, "WDS is not supported");
return -EAGAIN;
}

/* check amsdu packets */
sta = &wil->sta[cid];
if (!wil_rx_status_is_basic_amsdu(msg)) {
if (sta->amsdu_drop_sn != -1)
wil_sta_info_amsdu_init(sta);
return 0;
}

mid = wil_rx_status_get_mid(msg);
tid = wil_rx_status_get_tid(msg);
seq = le16_to_cpu(wil_rx_status_get_seq(wil, msg));
vif = wil->vifs[mid];

if (unlikely(!vif)) {
wil_dbg_txrx(wil, "amsdu with invalid mid %d", mid);
return -EAGAIN;
}

if (unlikely(sta->amsdu_drop)) {
if (sta->amsdu_drop_sn == seq && sta->amsdu_drop_tid == tid) {
wil_dbg_txrx(wil, "Drop AMSDU sub frame, sn=%d\n",
seq);
return -EAGAIN;
}

/* previous AMSDU finished - clear drop amsdu flag */
sta->amsdu_drop = 0;
}

da = wil_skb_get_da(skb);
/* for all sub frame of the AMSDU, check that the SA or DA are valid
* compared with client/AP mac addresses
*/
switch (vif->wdev.iftype) {
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_P2P_CLIENT:
if (is_multicast_ether_addr(da))
return 0;

/* On client side, DA should be the client mac address */
ndev = vif_to_ndev(vif);
if (ether_addr_equal(ndev->dev_addr, da))
return 0;
break;

case NL80211_IFTYPE_P2P_GO:
case NL80211_IFTYPE_AP:
sa = wil_skb_get_sa(skb);
/* On AP side, the packet SA should be the client mac address.
* check also the DA is not rfc 1042 header
*/
if (ether_addr_equal(sta->addr, sa) &&
!ether_addr_equal(rfc1042_header, da))
return 0;
break;
default:
return 0;
}

sta->amsdu_drop_sn = seq;
sta->amsdu_drop_tid = tid;
sta->amsdu_drop = 1;
wil_dbg_txrx(wil,
"Drop AMSDU frame, sn=%d. Drop this and all next sub frames\n",
seq);

return -EAGAIN;
}

/* This function is used only for RX SW reorder */
static int wil_check_bar(struct wil6210_priv *wil, void *msg, int cid,
struct sk_buff *skb, struct wil_net_stats *stats)
Expand Down Expand Up @@ -1063,6 +1149,12 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil,
wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1,
skb->data, skb_headlen(skb), false);

if (!wil->use_compressed_rx_status &&
wil_check_amsdu(wil, msg, cid, rxdata, skb)) {
kfree_skb(skb);
goto again;
}

/* Has to be done after dma_unmap_single as skb->cb is also
* used for holding the pa
*/
Expand Down
20 changes: 19 additions & 1 deletion drivers/net/wireless/ath/wil6210/txrx_edma.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2016,2018-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2012-2016,2018-2021, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
Expand Down Expand Up @@ -59,6 +59,9 @@

#define WIL_RX_EDMA_MID_VALID_BIT BIT(22)

#define WIL_RX_EDMA_AMSDU_BASIC_MASK 0x1
#define WIL_RX_EDMA_DS_TYPE_WDS 0x3

#define WIL_EDMA_DESC_TX_MAC_CFG_0_QID_POS 16
#define WIL_EDMA_DESC_TX_MAC_CFG_0_QID_LEN 6

Expand Down Expand Up @@ -469,6 +472,21 @@ static inline int wil_rx_status_get_fc1(struct wil6210_priv *wil, void *msg)
0, 5) << 2;
}

static inline int wil_rx_status_get_ds_type(struct wil6210_priv *wil, void *msg)
{
if (wil->use_compressed_rx_status)
return 0;

return WIL_GET_BITS(((struct wil_rx_status_extended *)msg)->ext.d0,
19, 20);
}

static inline int wil_rx_status_is_basic_amsdu(void *msg)
{
return (WIL_GET_BITS(((struct wil_rx_status_compressed *)msg)->d1,
28, 29) == WIL_RX_EDMA_AMSDU_BASIC_MASK);
}

static inline __le16 wil_rx_status_get_seq(struct wil6210_priv *wil, void *msg)
{
if (wil->use_compressed_rx_status)
Expand Down
Loading

0 comments on commit b5ac667

Please sign in to comment.