This patch series includes few fixes and USB multichannel
feature support patch series
Amitkumar Karwar (2):
mwifiex: avoid memsetting PCIe event buffer
mwifiex: Suppress -ENOSR error for data traffic on USB
Aniket Nagarnaik (2):
mwifiex: don't always include ht/vht info in tdls confirm frame
mwifiex: fix NULL pointer dereference during hidden SSID scan
Xinming Hu (4):
mwifiex: fix typo in del_virtual_intf() function
mwifiex: minor corrections in multiport aggregation code
mwifiex: fix driver init failure under memory pressure
mwifiex: NULL check for cfg80211_inform_bss()
Zhaoyang Liu (8):
mwifiex: update amsdu tx packet time stamp
mwifiex: correct paused tx data packet counter
mwifiex: fix tx data_sent issue for usb interface
mwifiex: move usb specific data_sent update to usb.c
mwifiex: add usb multi channel event process support
mwifiex: add usb tx data multi endpoints support
mwifiex: add usb multi endpoints resync support
mwifiex: complete usb tx data with multi endpoints
drivers/net/wireless/mwifiex/11n_aggr.c | 8 +-
drivers/net/wireless/mwifiex/cfg80211.c | 12 +-
drivers/net/wireless/mwifiex/fw.h | 18 +++
drivers/net/wireless/mwifiex/init.c | 1 +
drivers/net/wireless/mwifiex/main.c | 60 +++++++-
drivers/net/wireless/mwifiex/main.h | 8 ++
drivers/net/wireless/mwifiex/pcie.c | 1 -
drivers/net/wireless/mwifiex/scan.c | 22 +--
drivers/net/wireless/mwifiex/sdio.c | 29 ++--
drivers/net/wireless/mwifiex/sta_cmd.c | 3 +-
drivers/net/wireless/mwifiex/sta_cmdresp.c | 11 ++
drivers/net/wireless/mwifiex/sta_event.c | 78 ++++++++--
drivers/net/wireless/mwifiex/sta_tx.c | 7 +-
drivers/net/wireless/mwifiex/tdls.c | 12 ++
drivers/net/wireless/mwifiex/txrx.c | 19 +--
drivers/net/wireless/mwifiex/uap_event.c | 4 +-
drivers/net/wireless/mwifiex/uap_txrx.c | 10 +-
drivers/net/wireless/mwifiex/usb.c | 224 +++++++++++++++++++++++------
drivers/net/wireless/mwifiex/usb.h | 15 +-
drivers/net/wireless/mwifiex/wmm.c | 52 +++++--
20 files changed, 469 insertions(+), 125 deletions(-)
--
1.8.1.4
From: Xinming Hu <[email protected]>
Interface counters should be incremented in add_virtual_intf()
and decremented in del_virtual_intf() function. This patch
corrects it.
Signed-off-by: Xinming Hu <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/mwifiex/cfg80211.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 7e71dd7..4e06e98 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -2862,14 +2862,14 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
case NL80211_IFTYPE_UNSPECIFIED:
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_ADHOC:
- adapter->curr_iface_comb.sta_intf++;
+ adapter->curr_iface_comb.sta_intf--;
break;
case NL80211_IFTYPE_AP:
- adapter->curr_iface_comb.uap_intf++;
+ adapter->curr_iface_comb.uap_intf--;
break;
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_P2P_GO:
- adapter->curr_iface_comb.p2p_intf++;
+ adapter->curr_iface_comb.p2p_intf--;
break;
default:
mwifiex_dbg(adapter, ERROR,
--
1.8.1.4
From: Zhaoyang Liu <[email protected]>
This patch add support for usb multi endpoints resync.
Once multi channel event is received from firmware,
update usb_mc_setp flag to block TX data until setup is over.
And available data endpoint will be attached to BSS interface.
Signed-off-by: Zhaoyang Liu <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/mwifiex/main.c | 54 +++++++++++++++++++++++++---
drivers/net/wireless/mwifiex/main.h | 3 ++
drivers/net/wireless/mwifiex/sta_cmdresp.c | 11 ++++++
drivers/net/wireless/mwifiex/sta_event.c | 5 +++
drivers/net/wireless/mwifiex/usb.c | 56 ++++++++++++++++++++++++++++++
drivers/net/wireless/mwifiex/usb.h | 2 ++
6 files changed, 127 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 6c8f35f..da88b4d 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -294,9 +294,15 @@ process_start:
/* We have tried to wakeup the card already */
if (adapter->pm_wakeup_fw_try)
break;
- if (adapter->ps_state != PS_STATE_AWAKE ||
- adapter->tx_lock_flag)
+ if (adapter->ps_state != PS_STATE_AWAKE)
break;
+ if (adapter->tx_lock_flag) {
+ if (adapter->iface_type == MWIFIEX_USB) {
+ if (!adapter->usb_mc_setup)
+ break;
+ } else
+ break;
+ }
if ((!adapter->scan_chan_gap_enabled &&
adapter->scan_processing) || adapter->data_sent ||
@@ -345,11 +351,18 @@ process_start:
*/
if ((adapter->ps_state == PS_STATE_SLEEP) ||
(adapter->ps_state == PS_STATE_PRE_SLEEP) ||
- (adapter->ps_state == PS_STATE_SLEEP_CFM) ||
- adapter->tx_lock_flag){
+ (adapter->ps_state == PS_STATE_SLEEP_CFM)) {
continue;
}
+ if (adapter->tx_lock_flag) {
+ if (adapter->iface_type == MWIFIEX_USB) {
+ if (!adapter->usb_mc_setup)
+ continue;
+ } else
+ continue;
+ }
+
if (!adapter->cmd_sent && !adapter->curr_cmd &&
mwifiex_is_send_cmd_allowed
(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA))) {
@@ -359,6 +372,13 @@ process_start:
}
}
+ /** If USB Multi channel setup ongoing,
+ * wait for ready to tx data.
+ */
+ if (adapter->iface_type == MWIFIEX_USB &&
+ adapter->usb_mc_setup)
+ continue;
+
if ((adapter->scan_chan_gap_enabled ||
!adapter->scan_processing) &&
!adapter->data_sent &&
@@ -928,6 +948,32 @@ mwifiex_tx_timeout(struct net_device *dev)
}
}
+void mwifiex_multi_chan_resync(struct mwifiex_adapter *adapter)
+{
+ struct usb_card_rec *card = adapter->card;
+ struct mwifiex_private *priv;
+ u16 tx_buf_size;
+ int i, ret;
+
+ card->mc_resync_flag = true;
+ for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++) {
+ if (atomic_read(&card->port[i].tx_data_urb_pending)) {
+ mwifiex_dbg(adapter, WARN, "pending data urb in sys\n");
+ return;
+ }
+ }
+
+ card->mc_resync_flag = false;
+ tx_buf_size = 0xffff;
+ priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+ ret = mwifiex_send_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF,
+ HostCmd_ACT_GEN_SET, 0, &tx_buf_size, false);
+ if (ret)
+ mwifiex_dbg(adapter, ERROR,
+ "send reconfig tx buf size cmd err\n");
+}
+EXPORT_SYMBOL_GPL(mwifiex_multi_chan_resync);
+
void mwifiex_drv_info_dump(struct mwifiex_adapter *adapter)
{
void *p;
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 3e044b4..47ab094 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -817,6 +817,7 @@ struct mwifiex_if_ops {
void (*iface_work)(struct work_struct *work);
void (*submit_rem_rx_urbs)(struct mwifiex_adapter *adapter);
void (*deaggr_pkt)(struct mwifiex_adapter *, struct sk_buff *);
+ void (*multi_port_resync)(struct mwifiex_adapter *);
};
struct mwifiex_adapter {
@@ -992,6 +993,7 @@ struct mwifiex_adapter {
bool drcs_enabled;
u8 active_scan_triggered;
bool usb_mc_status;
+ bool usb_mc_setup;
};
void mwifiex_process_tx_queue(struct mwifiex_adapter *adapter);
@@ -1567,6 +1569,7 @@ void mwifiex_process_tx_pause_event(struct mwifiex_private *priv,
struct sk_buff *event);
void mwifiex_process_multi_chan_event(struct mwifiex_private *priv,
struct sk_buff *event_skb);
+void mwifiex_multi_chan_resync(struct mwifiex_adapter *adapter);
#ifdef CONFIG_DEBUG_FS
void mwifiex_debugfs_init(void);
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index a218c75..9ac7aa2 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -1150,6 +1150,17 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
ret = mwifiex_ret_11n_addba_resp(priv, resp);
break;
case HostCmd_CMD_RECONFIGURE_TX_BUFF:
+ if (0xffff == (u16)le16_to_cpu(resp->params.tx_buf.buff_size)) {
+ if (adapter->iface_type == MWIFIEX_USB &&
+ adapter->usb_mc_setup) {
+ if (adapter->if_ops.multi_port_resync)
+ adapter->if_ops.
+ multi_port_resync(adapter);
+ adapter->usb_mc_setup = false;
+ adapter->tx_lock_flag = false;
+ }
+ break;
+ }
adapter->tx_buf_size = (u16) le16_to_cpu(resp->params.
tx_buf.buff_size);
adapter->tx_buf_size = (adapter->tx_buf_size
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 6792089..c333b24 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -381,6 +381,11 @@ void mwifiex_process_multi_chan_event(struct mwifiex_private *priv,
sizeof(struct mwifiex_ie_types_header));
}
+ if (adapter->iface_type == MWIFIEX_USB) {
+ adapter->tx_lock_flag = true;
+ adapter->usb_mc_setup = true;
+ mwifiex_multi_chan_resync(adapter);
+ }
}
void mwifiex_process_tx_pause_event(struct mwifiex_private *priv,
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index cc120d6..0772da6 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -285,6 +285,9 @@ static void mwifiex_usb_tx_complete(struct urb *urb)
urb->status ? -1 : 0);
}
+ if (card->mc_resync_flag)
+ mwifiex_multi_chan_resync(adapter);
+
mwifiex_queue_main_work(adapter);
return;
@@ -664,6 +667,10 @@ static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter)
if (!port->tx_data_ep)
continue;
port->tx_data_ix = 0;
+ if (port->tx_data_ep == MWIFIEX_USB_EP_DATA)
+ port->block_status = false;
+ else
+ port->block_status = true;
for (j = 0; j < MWIFIEX_TX_DATA_URB; j++) {
port->tx_data_list[j].adapter = adapter;
port->tx_data_list[j].ep = port->tx_data_ep;
@@ -762,6 +769,53 @@ static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *pbuf,
return ret;
}
+static void mwifiex_usb_port_resync(struct mwifiex_adapter *adapter)
+{
+ struct usb_card_rec *card = adapter->card;
+ u8 active_port = MWIFIEX_USB_EP_DATA;
+ struct mwifiex_private *priv = NULL;
+ int i;
+
+ if (adapter->usb_mc_status) {
+ for (i = 0; i < adapter->priv_num; i++) {
+ priv = adapter->priv[i];
+ if (!priv)
+ continue;
+ if ((priv->bss_role == MWIFIEX_BSS_ROLE_UAP &&
+ !priv->bss_started) ||
+ (priv->bss_role == MWIFIEX_BSS_ROLE_STA &&
+ !priv->media_connected))
+ priv->usb_port = MWIFIEX_USB_EP_DATA;
+ }
+ for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++)
+ card->port[i].block_status = false;
+ } else {
+ for (i = 0; i < adapter->priv_num; i++) {
+ priv = adapter->priv[i];
+ if (!priv)
+ continue;
+ if ((priv->bss_role == MWIFIEX_BSS_ROLE_UAP &&
+ priv->bss_started) ||
+ (priv->bss_role == MWIFIEX_BSS_ROLE_STA &&
+ priv->media_connected)) {
+ active_port = priv->usb_port;
+ break;
+ }
+ }
+ for (i = 0; i < adapter->priv_num; i++) {
+ priv = adapter->priv[i];
+ if (priv)
+ priv->usb_port = active_port;
+ }
+ for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++) {
+ if (active_port == card->port[i].tx_data_ep)
+ card->port[i].block_status = false;
+ else
+ card->port[i].block_status = true;
+ }
+ }
+}
+
/* This function write a command/data packet to card. */
static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
struct sk_buff *skb,
@@ -890,6 +944,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
}
adapter->usb_mc_status = false;
+ adapter->usb_mc_setup = false;
return 0;
}
@@ -1120,6 +1175,7 @@ static struct mwifiex_if_ops usb_ops = {
.event_complete = mwifiex_usb_cmd_event_complete,
.host_to_card = mwifiex_usb_host_to_card,
.submit_rem_rx_urbs = mwifiex_usb_submit_rem_rx_urbs,
+ .multi_port_resync = mwifiex_usb_port_resync,
};
/* This function initializes the USB driver module.
diff --git a/drivers/net/wireless/mwifiex/usb.h b/drivers/net/wireless/mwifiex/usb.h
index 6339d87..b4e9246 100644
--- a/drivers/net/wireless/mwifiex/usb.h
+++ b/drivers/net/wireless/mwifiex/usb.h
@@ -64,6 +64,7 @@ struct urb_context {
struct usb_tx_data_port {
u8 tx_data_ep;
+ u8 block_status;
atomic_t tx_data_urb_pending;
int tx_data_ix;
struct urb_context tx_data_list[MWIFIEX_TX_DATA_URB];
@@ -84,6 +85,7 @@ struct usb_card_rec {
atomic_t tx_cmd_urb_pending;
int bulk_out_maxpktsize;
struct urb_context tx_cmd;
+ u8 mc_resync_flag;
struct usb_tx_data_port port[MWIFIEX_TX_DATA_PORT];
};
--
1.8.1.4
From: Zhaoyang Liu <[email protected]>
This patch fixes observed issues while updating counter for
number of paused data packets in wmm queue when trying to
delete packet or delete station entry.
Signed-off-by: Zhaoyang Liu <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/mwifiex/uap_txrx.c | 10 +++++++---
drivers/net/wireless/mwifiex/wmm.c | 9 +++++++--
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c
index 8766741..74d5d72 100644
--- a/drivers/net/wireless/mwifiex/uap_txrx.c
+++ b/drivers/net/wireless/mwifiex/uap_txrx.c
@@ -31,7 +31,8 @@
*/
static bool
mwifiex_uap_del_tx_pkts_in_ralist(struct mwifiex_private *priv,
- struct list_head *ra_list_head)
+ struct list_head *ra_list_head,
+ int tid)
{
struct mwifiex_ra_list_tbl *ra_list;
struct sk_buff *skb, *tmp;
@@ -49,7 +50,10 @@ mwifiex_uap_del_tx_pkts_in_ralist(struct mwifiex_private *priv,
__skb_unlink(skb, &ra_list->skb_head);
mwifiex_write_data_complete(adapter, skb, 0,
-1);
- atomic_dec(&priv->wmm.tx_pkts_queued);
+ if (ra_list->tx_paused)
+ priv->wmm.pkts_paused[tid]--;
+ else
+ atomic_dec(&priv->wmm.tx_pkts_queued);
pkt_deleted = true;
}
if ((atomic_read(&adapter->pending_bridged_pkts) <=
@@ -77,7 +81,7 @@ static void mwifiex_uap_cleanup_tx_queues(struct mwifiex_private *priv)
if (priv->del_list_idx == MAX_NUM_TID)
priv->del_list_idx = 0;
ra_list = &priv->wmm.tid_tbl_ptr[priv->del_list_idx].ra_list;
- if (mwifiex_uap_del_tx_pkts_in_ralist(priv, ra_list)) {
+ if (mwifiex_uap_del_tx_pkts_in_ralist(priv, ra_list, i)) {
priv->del_list_idx++;
break;
}
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 173d366..8e30fb3 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -160,7 +160,6 @@ void mwifiex_ralist_add(struct mwifiex_private *priv, const u8 *ra)
ra_list->tdls_link = false;
ra_list->ba_status = BA_SETUP_NONE;
ra_list->amsdu_in_ampdu = false;
- ra_list->tx_paused = false;
if (!mwifiex_queuing_ra_based(priv)) {
if (mwifiex_is_tdls_link_setup
(mwifiex_get_tdls_link_status(priv, ra))) {
@@ -173,6 +172,8 @@ void mwifiex_ralist_add(struct mwifiex_private *priv, const u8 *ra)
} else {
spin_lock_irqsave(&priv->sta_list_spinlock, flags);
node = mwifiex_get_sta_entry(priv, ra);
+ if (node)
+ ra_list->tx_paused = node->tx_pause;
ra_list->is_11n_enabled =
mwifiex_is_sta_11n_enabled(priv, node);
if (ra_list->is_11n_enabled)
@@ -737,7 +738,11 @@ mwifiex_wmm_del_peer_ra_list(struct mwifiex_private *priv, const u8 *ra_addr)
if (!ra_list)
continue;
mwifiex_wmm_del_pkts_in_ralist_node(priv, ra_list);
- atomic_sub(ra_list->total_pkt_count, &priv->wmm.tx_pkts_queued);
+ if (ra_list->tx_paused)
+ priv->wmm.pkts_paused[i] -= ra_list->total_pkt_count;
+ else
+ atomic_sub(ra_list->total_pkt_count,
+ &priv->wmm.tx_pkts_queued);
list_del(&ra_list->list);
kfree(ra_list);
}
--
1.8.1.4
From: Zhaoyang Liu <[email protected]>
This patch move data_sent flag update to usb.c file.
>From now all data_sent update cases only happened in specific file:
sdio.c, usb.c, pcie.c. Outside ot these files, it is only allowed
to check the value of data_ent.
Signed-off-by: Zhaoyang Liu <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/mwifiex/11n_aggr.c | 5 -----
drivers/net/wireless/mwifiex/sta_tx.c | 5 -----
drivers/net/wireless/mwifiex/txrx.c | 13 -------------
drivers/net/wireless/mwifiex/usb.c | 7 ++++++-
drivers/net/wireless/mwifiex/wmm.c | 5 -----
5 files changed, 6 insertions(+), 29 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index ce22cc8..46221c2 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -259,7 +259,6 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
}
if (adapter->iface_type == MWIFIEX_USB) {
- adapter->data_sent = true;
ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_USB_EP_DATA,
skb_aggr, NULL);
} else {
@@ -300,16 +299,12 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
mwifiex_dbg(adapter, ERROR, "data: -EBUSY is returned\n");
break;
case -1:
- if (adapter->iface_type == MWIFIEX_USB)
- adapter->data_sent = false;
mwifiex_dbg(adapter, ERROR, "%s: host_to_card failed: %#x\n",
__func__, ret);
adapter->dbg.num_tx_host_to_card_failure++;
mwifiex_write_data_complete(adapter, skb_aggr, 1, ret);
return 0;
case -EINPROGRESS:
- if (adapter->iface_type == MWIFIEX_USB)
- adapter->data_sent = false;
break;
case 0:
mwifiex_write_data_complete(adapter, skb_aggr, 1, ret);
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index 7a4d5f4..877ad06 100644
--- a/drivers/net/wireless/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -174,7 +174,6 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
local_tx_pd->bss_type = priv->bss_type;
if (adapter->iface_type == MWIFIEX_USB) {
- adapter->data_sent = true;
ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_USB_EP_DATA,
skb, NULL);
} else {
@@ -192,8 +191,6 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
adapter->dbg.num_tx_host_to_card_failure++;
break;
case -1:
- if (adapter->iface_type == MWIFIEX_USB)
- adapter->data_sent = false;
dev_kfree_skb_any(skb);
mwifiex_dbg(adapter, ERROR,
"%s: host_to_card failed: ret=%d\n",
@@ -208,8 +205,6 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
adapter->tx_lock_flag = true;
break;
case -EINPROGRESS:
- if (adapter->iface_type == MWIFIEX_USB)
- adapter->data_sent = false;
adapter->tx_lock_flag = true;
break;
default:
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index 6ef030a..90f4915 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -115,7 +115,6 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
local_tx_pd = (struct txpd *)(head_ptr + hroom);
if (adapter->iface_type == MWIFIEX_USB) {
- adapter->data_sent = true;
ret = adapter->if_ops.host_to_card(adapter,
MWIFIEX_USB_EP_DATA,
skb, NULL);
@@ -142,8 +141,6 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
mwifiex_dbg(adapter, ERROR, "data: -EBUSY is returned\n");
break;
case -1:
- if (adapter->iface_type == MWIFIEX_USB)
- adapter->data_sent = false;
mwifiex_dbg(adapter, ERROR,
"mwifiex_write_data_async failed: 0x%X\n",
ret);
@@ -151,8 +148,6 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
mwifiex_write_data_complete(adapter, skb, 0, ret);
break;
case -EINPROGRESS:
- if (adapter->iface_type == MWIFIEX_USB)
- adapter->data_sent = false;
break;
case 0:
mwifiex_write_data_complete(adapter, skb, 0, ret);
@@ -193,7 +188,6 @@ static int mwifiex_host_to_card(struct mwifiex_adapter *adapter,
}
if (adapter->iface_type == MWIFIEX_USB) {
- adapter->data_sent = true;
ret = adapter->if_ops.host_to_card(adapter,
MWIFIEX_USB_EP_DATA,
skb, NULL);
@@ -222,16 +216,12 @@ static int mwifiex_host_to_card(struct mwifiex_adapter *adapter,
mwifiex_dbg(adapter, ERROR, "data: -EBUSY is returned\n");
break;
case -1:
- if (adapter->iface_type == MWIFIEX_USB)
- adapter->data_sent = false;
mwifiex_dbg(adapter, ERROR,
"mwifiex_write_data_async failed: 0x%X\n", ret);
adapter->dbg.num_tx_host_to_card_failure++;
mwifiex_write_data_complete(adapter, skb, 0, ret);
break;
case -EINPROGRESS:
- if (adapter->iface_type == MWIFIEX_USB)
- adapter->data_sent = false;
break;
case 0:
mwifiex_write_data_complete(adapter, skb, 0, ret);
@@ -306,9 +296,6 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
if (!priv)
goto done;
- if (adapter->iface_type == MWIFIEX_USB)
- adapter->data_sent = false;
-
mwifiex_set_trans_start(priv->netdev);
if (!status) {
priv->stats.tx_packets++;
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index bc8619d..3f1713e 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -272,6 +272,7 @@ static void mwifiex_usb_tx_complete(struct urb *urb)
mwifiex_dbg(adapter, DATA,
"%s: DATA\n", __func__);
atomic_dec(&card->tx_data_urb_pending);
+ adapter->data_sent = false;
mwifiex_write_data_complete(adapter, context->skb, 0,
urb->status ? -1 : 0);
}
@@ -752,6 +753,7 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
if (ep == card->tx_data_ep &&
atomic_read(&card->tx_data_urb_pending) >= MWIFIEX_TX_DATA_URB) {
+ adapter->data_sent = true;
return -EBUSY;
}
@@ -788,6 +790,7 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
atomic_dec(&card->tx_cmd_urb_pending);
} else {
atomic_dec(&card->tx_data_urb_pending);
+ adapter->data_sent = false;
if (card->tx_data_ix)
card->tx_data_ix--;
else
@@ -798,8 +801,10 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
} else {
if (ep == card->tx_data_ep &&
atomic_read(&card->tx_data_urb_pending) ==
- MWIFIEX_TX_DATA_URB)
+ MWIFIEX_TX_DATA_URB) {
+ adapter->data_sent = true;
return -ENOSR;
+ }
}
return -EINPROGRESS;
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 8a3f59e..4f303f3 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -1326,7 +1326,6 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
if (adapter->iface_type == MWIFIEX_USB) {
- adapter->data_sent = true;
ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_USB_EP_DATA,
skb, NULL);
} else {
@@ -1356,15 +1355,11 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
ra_list_flags);
break;
case -1:
- if (adapter->iface_type == MWIFIEX_USB)
- adapter->data_sent = false;
mwifiex_dbg(adapter, ERROR, "host_to_card failed: %#x\n", ret);
adapter->dbg.num_tx_host_to_card_failure++;
mwifiex_write_data_complete(adapter, skb, 0, ret);
break;
case -EINPROGRESS:
- if (adapter->iface_type == MWIFIEX_USB)
- adapter->data_sent = false;
break;
case 0:
mwifiex_write_data_complete(adapter, skb, 0, ret);
--
1.8.1.4
From: Xinming Hu <[email protected]>
This patch includes below changes
1) Check if multiport aggregation feature flag while doing rx
length validation check.
2) Reset buffer size variables when buffers are freed.
Signed-off-by: Xinming Hu <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/mwifiex/sdio.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 5d05c6f..d35210c 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -1606,8 +1606,9 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
(rx_len + MWIFIEX_SDIO_BLOCK_SIZE -
1) / MWIFIEX_SDIO_BLOCK_SIZE;
if (rx_len <= INTF_HEADER_LEN ||
- (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) >
- card->mpa_rx.buf_size) {
+ (card->mpa_rx.enabled &&
+ ((rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) >
+ card->mpa_rx.buf_size))) {
mwifiex_dbg(adapter, ERROR,
"invalid rx_len=%d\n",
rx_len);
@@ -1925,6 +1926,8 @@ error:
if (ret) {
kfree(card->mpa_tx.buf);
kfree(card->mpa_rx.buf);
+ card->mpa_tx.buf_size = 0;
+ card->mpa_rx.buf_size = 0;
}
return ret;
--
1.8.1.4
Preallocated PCIe buffer is being reused for all PCIe interface
events. Physical address of the buffer is shared with firmware
so that it can perform DMA on it. As event length is specified
in the header, there should not be a problem if the buffer gets
overwritten.
We will save some cycles by avoiding memset everytime while
submitting the buffer to firmware.
Fixes: 2728cecdc7d6bf3d21(mwifiex: corrections in PCIe event skb)
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/mwifiex/pcie.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 408b684..21192b6 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -1815,7 +1815,6 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
if (!card->evt_buf_list[rdptr]) {
skb_push(skb, INTF_HEADER_LEN);
skb_put(skb, MAX_EVENT_SIZE - skb->len);
- memset(skb->data, 0, MAX_EVENT_SIZE);
if (mwifiex_map_pci_memory(adapter, skb,
MAX_EVENT_SIZE,
PCI_DMA_FROMDEVICE))
--
1.8.1.4
From: Xinming Hu <[email protected]>
cfg80211_inform_bss would return null in some cases, such as
memory allocation failure.
This patch adds sanity check for this case, to avoid possible
issues when above corner case is hit.
Signed-off-by: Xinming Hu <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/mwifiex/cfg80211.c | 6 ++++--
drivers/net/wireless/mwifiex/scan.c | 20 ++++++++++++--------
2 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 4e06e98..262c4b9 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1994,8 +1994,10 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
CFG80211_BSS_FTYPE_UNKNOWN,
bss_info.bssid, 0, WLAN_CAPABILITY_IBSS,
0, ie_buf, ie_len, 0, GFP_KERNEL);
- cfg80211_put_bss(priv->wdev.wiphy, bss);
- memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN);
+ if (bss) {
+ cfg80211_put_bss(priv->wdev.wiphy, bss);
+ ether_addr_copy(priv->cfg_bssid, bss_info.bssid);
+ }
return 0;
}
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 5847863..3675730 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1839,14 +1839,18 @@ mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info,
bssid, timestamp,
cap_info_bitmap, beacon_period,
ie_buf, ie_len, rssi, GFP_KERNEL);
- bss_priv = (struct mwifiex_bss_priv *)bss->priv;
- bss_priv->band = band;
- bss_priv->fw_tsf = fw_tsf;
- if (priv->media_connected &&
- !memcmp(bssid, priv->curr_bss_params.bss_descriptor
- .mac_address, ETH_ALEN))
- mwifiex_update_curr_bss_params(priv, bss);
- cfg80211_put_bss(priv->wdev.wiphy, bss);
+ if (bss) {
+ bss_priv = (struct mwifiex_bss_priv *)bss->priv;
+ bss_priv->band = band;
+ bss_priv->fw_tsf = fw_tsf;
+ if (priv->media_connected &&
+ !memcmp(bssid, priv->curr_bss_params.
+ bss_descriptor.mac_address,
+ ETH_ALEN))
+ mwifiex_update_curr_bss_params(priv,
+ bss);
+ cfg80211_put_bss(priv->wdev.wiphy, bss);
+ }
if ((chan->flags & IEEE80211_CHAN_RADAR) ||
(chan->flags & IEEE80211_CHAN_NO_IR)) {
--
1.8.1.4
From: Zhaoyang Liu <[email protected]>
This patch do the work to TX data with specific USB
endpoint. At the same time, update data_sent flag
according to multi port status. And is_port_ready
API is added for BSS interface to check if current
used usb data endpoint is available or not.
Signed-off-by: Zhaoyang Liu <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/mwifiex/11n_aggr.c | 2 +-
drivers/net/wireless/mwifiex/main.h | 1 +
drivers/net/wireless/mwifiex/sta_event.c | 4 ++-
drivers/net/wireless/mwifiex/sta_tx.c | 6 +++-
drivers/net/wireless/mwifiex/txrx.c | 4 +--
drivers/net/wireless/mwifiex/uap_event.c | 4 ++-
drivers/net/wireless/mwifiex/usb.c | 47 ++++++++++++++++++++++++++++----
drivers/net/wireless/mwifiex/wmm.c | 38 +++++++++++++++++++++++---
8 files changed, 90 insertions(+), 16 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index 46221c2..2c5ffa1 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -259,7 +259,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
}
if (adapter->iface_type == MWIFIEX_USB) {
- ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_USB_EP_DATA,
+ ret = adapter->if_ops.host_to_card(adapter, priv->usb_port,
skb_aggr, NULL);
} else {
if (skb_src)
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 47ab094..05e1e63 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -818,6 +818,7 @@ struct mwifiex_if_ops {
void (*submit_rem_rx_urbs)(struct mwifiex_adapter *adapter);
void (*deaggr_pkt)(struct mwifiex_adapter *, struct sk_buff *);
void (*multi_port_resync)(struct mwifiex_adapter *);
+ bool (*is_port_ready)(struct mwifiex_private *);
};
struct mwifiex_adapter {
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index c333b24..ff3ee9d 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -616,7 +616,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
adapter->tx_lock_flag = false;
if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) {
if (mwifiex_check_last_packet_indication(priv)) {
- if (adapter->data_sent) {
+ if (adapter->data_sent ||
+ (adapter->if_ops.is_port_ready &&
+ !adapter->if_ops.is_port_ready(priv))) {
adapter->ps_state = PS_STATE_AWAKE;
adapter->pm_wakeup_card_req = false;
adapter->pm_wakeup_fw_try = false;
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index 877ad06..f6683ea 100644
--- a/drivers/net/wireless/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -153,6 +153,10 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
if (adapter->data_sent)
return -1;
+ if (adapter->if_ops.is_port_ready &&
+ !adapter->if_ops.is_port_ready(priv))
+ return -1;
+
skb = dev_alloc_skb(data_len);
if (!skb)
return -1;
@@ -174,7 +178,7 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
local_tx_pd->bss_type = priv->bss_type;
if (adapter->iface_type == MWIFIEX_USB) {
- ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_USB_EP_DATA,
+ ret = adapter->if_ops.host_to_card(adapter, priv->usb_port,
skb, NULL);
} else {
skb_push(skb, INTF_HEADER_LEN);
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index 90f4915..bf6182b 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -116,7 +116,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
local_tx_pd = (struct txpd *)(head_ptr + hroom);
if (adapter->iface_type == MWIFIEX_USB) {
ret = adapter->if_ops.host_to_card(adapter,
- MWIFIEX_USB_EP_DATA,
+ priv->usb_port,
skb, NULL);
} else {
ret = adapter->if_ops.host_to_card(adapter,
@@ -189,7 +189,7 @@ static int mwifiex_host_to_card(struct mwifiex_adapter *adapter,
if (adapter->iface_type == MWIFIEX_USB) {
ret = adapter->if_ops.host_to_card(adapter,
- MWIFIEX_USB_EP_DATA,
+ priv->usb_port,
skb, NULL);
} else {
ret = adapter->if_ops.host_to_card(adapter,
diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c
index 46c972a..078834c 100644
--- a/drivers/net/wireless/mwifiex/uap_event.c
+++ b/drivers/net/wireless/mwifiex/uap_event.c
@@ -269,7 +269,9 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
adapter->tx_lock_flag = false;
if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) {
if (mwifiex_check_last_packet_indication(priv)) {
- if (adapter->data_sent) {
+ if (adapter->data_sent ||
+ (adapter->if_ops.is_port_ready &&
+ !adapter->if_ops.is_port_ready(priv))) {
adapter->ps_state = PS_STATE_AWAKE;
adapter->pm_wakeup_card_req = false;
adapter->pm_wakeup_fw_try = false;
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index 0772da6..e43aff9 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -277,6 +277,7 @@ static void mwifiex_usb_tx_complete(struct urb *urb)
port = &card->port[i];
if (context->ep == port->tx_data_ep) {
atomic_dec(&port->tx_data_urb_pending);
+ port->block_status = false;
break;
}
}
@@ -816,6 +817,31 @@ static void mwifiex_usb_port_resync(struct mwifiex_adapter *adapter)
}
}
+static bool mwifiex_usb_is_port_ready(struct mwifiex_private *priv)
+{
+ struct usb_card_rec *card = priv->adapter->card;
+ int idx;
+
+ for (idx = 0; idx < MWIFIEX_TX_DATA_PORT; idx++) {
+ if (priv->usb_port == card->port[idx].tx_data_ep)
+ return !card->port[idx].block_status;
+ }
+
+ return false;
+}
+
+static inline u8 mwifiex_usb_data_sent(struct mwifiex_adapter *adapter)
+{
+ struct usb_card_rec *card = adapter->card;
+ int i;
+
+ for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++)
+ if (!card->port[i].block_status)
+ return false;
+
+ return true;
+}
+
/* This function write a command/data packet to card. */
static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
struct sk_buff *skb,
@@ -826,7 +852,7 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
struct usb_tx_data_port *port = NULL;
u8 *data = (u8 *)skb->data;
struct urb *tx_urb;
- int idx;
+ int idx, ret;
if (adapter->is_suspended) {
mwifiex_dbg(adapter, ERROR,
@@ -849,8 +875,9 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
port = &card->port[idx];
if (atomic_read(&port->tx_data_urb_pending)
>= MWIFIEX_TX_DATA_URB) {
- adapter->data_sent = true;
- return -EBUSY;
+ port->block_status = true;
+ ret = -EBUSY;
+ goto done;
}
if (port->tx_data_ix >= MWIFIEX_TX_DATA_URB)
port->tx_data_ix = 0;
@@ -888,7 +915,7 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
atomic_dec(&card->tx_cmd_urb_pending);
} else {
atomic_dec(&port->tx_data_urb_pending);
- adapter->data_sent = false;
+ port->block_status = false;
if (port->tx_data_ix)
port->tx_data_ix--;
else
@@ -900,12 +927,19 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
if (ep != card->tx_cmd_ep &&
atomic_read(&port->tx_data_urb_pending) ==
MWIFIEX_TX_DATA_URB) {
- adapter->data_sent = true;
- return -ENOSR;
+ port->block_status = true;
+ ret = -ENOSR;
+ goto done;
}
}
return -EINPROGRESS;
+
+done:
+ if (ep != card->tx_cmd_ep)
+ adapter->data_sent = mwifiex_usb_data_sent(adapter);
+
+ return ret;
}
/* This function register usb device and initialize parameter. */
@@ -1176,6 +1210,7 @@ static struct mwifiex_if_ops usb_ops = {
.host_to_card = mwifiex_usb_host_to_card,
.submit_rem_rx_urbs = mwifiex_usb_submit_rem_rx_urbs,
.multi_port_resync = mwifiex_usb_port_resync,
+ .is_port_ready = mwifiex_usb_is_port_ready,
};
/* This function initializes the USB driver module.
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 4f303f3..7bbdfe4 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -452,7 +452,21 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter)
int mwifiex_bypass_txlist_empty(struct mwifiex_adapter *adapter)
{
- return atomic_read(&adapter->bypass_tx_pending) ? false : true;
+ struct mwifiex_private *priv;
+ int i;
+
+ for (i = 0; i < adapter->priv_num; i++) {
+ priv = adapter->priv[i];
+ if (!priv)
+ continue;
+ if (adapter->if_ops.is_port_ready &&
+ !adapter->if_ops.is_port_ready(priv))
+ continue;
+ if (!skb_queue_empty(&priv->bypass_txq))
+ return false;
+ }
+
+ return true;
}
/*
@@ -466,9 +480,14 @@ mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter)
for (i = 0; i < adapter->priv_num; ++i) {
priv = adapter->priv[i];
- if (priv && !priv->port_open)
+ if (!priv)
+ continue;
+ if (!priv->port_open)
+ continue;
+ if (adapter->if_ops.is_port_ready &&
+ !adapter->if_ops.is_port_ready(priv))
continue;
- if (priv && atomic_read(&priv->wmm.tx_pkts_queued))
+ if (atomic_read(&priv->wmm.tx_pkts_queued))
return false;
}
@@ -1091,6 +1110,10 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
(atomic_read(&priv_tmp->wmm.tx_pkts_queued) == 0))
continue;
+ if (adapter->if_ops.is_port_ready &&
+ !adapter->if_ops.is_port_ready(priv_tmp))
+ continue;
+
/* iterate over the WMM queues of the BSS */
hqp = &priv_tmp->wmm.highest_queued_prio;
for (i = atomic_read(hqp); i >= LOW_PRIO_TID; --i) {
@@ -1326,7 +1349,7 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
if (adapter->iface_type == MWIFIEX_USB) {
- ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_USB_EP_DATA,
+ ret = adapter->if_ops.host_to_card(adapter, priv->usb_port,
skb, NULL);
} else {
tx_param.next_pkt_len =
@@ -1467,6 +1490,13 @@ void mwifiex_process_bypass_tx(struct mwifiex_adapter *adapter)
for (i = 0; i < adapter->priv_num; ++i) {
priv = adapter->priv[i];
+ if (!priv)
+ continue;
+
+ if (adapter->if_ops.is_port_ready &&
+ !adapter->if_ops.is_port_ready(priv))
+ continue;
+
if (skb_queue_empty(&priv->bypass_txq))
continue;
--
1.8.1.4
From: Xinming Hu <[email protected]>
64k Tx and Rx buffers are allocated during driver initialization
for SDIO level data aggregations. When host is under memory
pressure situation, kzalloc() request for 64k may fail.
We will try allocating 32k buffers and disable our rx single port
aggreagation feature in this situation.
If the allocation still fails, we will disable our sdio multport
aggregation feature as well. In this way, we will transmit and
receive packets one by one, thus reduce the demand for big
memory.
Signed-off-by: Xinming Hu <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/mwifiex/main.h | 2 ++
drivers/net/wireless/mwifiex/sdio.c | 22 ++++++++++++++++------
drivers/net/wireless/mwifiex/sta_cmd.c | 3 ++-
3 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index f4159ed..8f5c3da 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -861,6 +861,8 @@ struct mwifiex_adapter {
u8 more_task_flag;
u16 tx_buf_size;
u16 curr_tx_buf_size;
+ /* sdio single port rx aggregation capability */
+ bool host_disable_sdio_rx_aggr;
bool sdio_rx_aggr_enable;
u16 sdio_rx_block_size;
u32 ioport;
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index d35210c..78a8474 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -2058,16 +2058,26 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
ret = mwifiex_alloc_sdio_mpa_buffers(adapter,
card->mp_tx_agg_buf_size,
card->mp_rx_agg_buf_size);
- if (ret) {
- mwifiex_dbg(adapter, ERROR,
- "failed to alloc sdio mp-a buffers\n");
- kfree(card->mp_regs);
- return -1;
+
+ /* Allocate 32k MPA Tx/Rx buffers if 64k memory allocation fails */
+ if (ret && (card->mp_tx_agg_buf_size == MWIFIEX_MP_AGGR_BUF_SIZE_MAX ||
+ card->mp_rx_agg_buf_size == MWIFIEX_MP_AGGR_BUF_SIZE_MAX)) {
+ /* Disable rx single port aggregation */
+ adapter->host_disable_sdio_rx_aggr = true;
+
+ ret = mwifiex_alloc_sdio_mpa_buffers
+ (adapter, MWIFIEX_MP_AGGR_BUF_SIZE_32K,
+ MWIFIEX_MP_AGGR_BUF_SIZE_32K);
+ if (ret) {
+ /* Disable multi port aggregation */
+ card->mpa_tx.enabled = 0;
+ card->mpa_rx.enabled = 0;
+ }
}
adapter->auto_tdls = card->can_auto_tdls;
adapter->ext_scan = card->can_ext_scan;
- return ret;
+ return 0;
}
/*
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index fd7bf94..e486867 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -2156,7 +2156,8 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
/** Set SDIO Single Port RX Aggr Info */
if (priv->adapter->iface_type == MWIFIEX_SDIO &&
- ISSUPP_SDIO_SPA_ENABLED(priv->adapter->fw_cap_info)) {
+ ISSUPP_SDIO_SPA_ENABLED(priv->adapter->fw_cap_info) &&
+ !priv->adapter->host_disable_sdio_rx_aggr) {
sdio_sp_rx_aggr_enable = true;
ret = mwifiex_send_cmd(priv,
HostCmd_CMD_SDIO_SP_RX_AGGR_CFG,
--
1.8.1.4
From: Zhaoyang Liu <[email protected]>
This patch add multi channel event process for USB multi tx data endpoints.
Driver receives firmware multi channel event only in case that new
connection is setup or interface is disconnect. Different BSS interface
need update used usb endpoint.
Signed-off-by: Zhaoyang Liu <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/mwifiex/fw.h | 18 +++++++++
drivers/net/wireless/mwifiex/init.c | 1 +
drivers/net/wireless/mwifiex/main.h | 2 +
drivers/net/wireless/mwifiex/sta_event.c | 69 +++++++++++++++++++++++++++-----
drivers/net/wireless/mwifiex/usb.c | 2 +
5 files changed, 82 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index eaed2e0..1e1e81a 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -107,6 +107,7 @@ enum KEY_TYPE_ID {
enum mwifiex_usb_ep {
MWIFIEX_USB_EP_CMD_EVENT = 1,
MWIFIEX_USB_EP_DATA = 2,
+ MWIFIEX_USB_EP_DATA_CH2 = 3,
};
enum MWIFIEX_802_11_PRIVACY_FILTER {
@@ -177,6 +178,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define TLV_TYPE_COALESCE_RULE (PROPRIETARY_TLV_BASE_ID + 154)
#define TLV_TYPE_KEY_PARAM_V2 (PROPRIETARY_TLV_BASE_ID + 156)
#define TLV_TYPE_MULTI_CHAN_INFO (PROPRIETARY_TLV_BASE_ID + 183)
+#define TLV_TYPE_MC_GROUP_INFO (PROPRIETARY_TLV_BASE_ID + 184)
#define TLV_TYPE_TDLS_IDLE_TIMEOUT (PROPRIETARY_TLV_BASE_ID + 194)
#define TLV_TYPE_SCAN_CHANNEL_GAP (PROPRIETARY_TLV_BASE_ID + 197)
#define TLV_TYPE_API_REV (PROPRIETARY_TLV_BASE_ID + 199)
@@ -1994,6 +1996,22 @@ struct mwifiex_ie_types_multi_chan_info {
u8 tlv_buffer[0];
} __packed;
+struct mwifiex_ie_types_mc_group_info {
+ struct mwifiex_ie_types_header header;
+ u8 chan_group_id;
+ u8 chan_buf_weight;
+ u8 band_config;
+ u8 chan_num;
+ u32 chan_time;
+ u32 reserved;
+ union {
+ u8 sdio_func_num;
+ u8 usb_ep_num;
+ } hid_num;
+ u8 intf_num;
+ u8 bss_type_numlist[0];
+} __packed;
+
struct meas_rpt_map {
u8 rssi:3;
u8 unmeasured:1;
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 5d3ae63..de74a77 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -78,6 +78,7 @@ int mwifiex_init_priv(struct mwifiex_private *priv)
priv->media_connected = false;
eth_broadcast_addr(priv->curr_addr);
priv->port_open = false;
+ priv->usb_port = MWIFIEX_USB_EP_DATA;
priv->pkt_tx_ctrl = 0;
priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
priv->data_rate = 0; /* Initially indicate the rate as auto */
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 8f5c3da..3e044b4 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -520,6 +520,7 @@ struct mwifiex_private {
u8 curr_addr[ETH_ALEN];
u8 media_connected;
u8 port_open;
+ u8 usb_port;
u32 num_tx_timeout;
/* track consecutive timeout */
u8 tx_timeout_cnt;
@@ -990,6 +991,7 @@ struct mwifiex_adapter {
u8 coex_rx_win_size;
bool drcs_enabled;
u8 active_scan_triggered;
+ bool usb_mc_status;
};
void mwifiex_process_tx_queue(struct mwifiex_adapter *adapter);
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 3d18c58..6792089 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -313,25 +313,74 @@ void mwifiex_process_multi_chan_event(struct mwifiex_private *priv,
struct sk_buff *event_skb)
{
struct mwifiex_ie_types_multi_chan_info *chan_info;
- u16 status;
+ struct mwifiex_ie_types_mc_group_info *grp_info;
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct mwifiex_ie_types_header *tlv;
+ u16 tlv_buf_left, tlv_type, tlv_len;
+ int intf_num, bss_type, bss_num, i;
+ struct mwifiex_private *intf_priv;
+ tlv_buf_left = event_skb->len - sizeof(u32);
chan_info = (void *)event_skb->data + sizeof(u32);
- if (le16_to_cpu(chan_info->header.type) != TLV_TYPE_MULTI_CHAN_INFO) {
- mwifiex_dbg(priv->adapter, ERROR,
+ if (le16_to_cpu(chan_info->header.type) != TLV_TYPE_MULTI_CHAN_INFO ||
+ tlv_buf_left < sizeof(struct mwifiex_ie_types_multi_chan_info)) {
+ mwifiex_dbg(adapter, ERROR,
"unknown TLV in chan_info event\n");
return;
}
- status = le16_to_cpu(chan_info->status);
+ adapter->usb_mc_status = le16_to_cpu(chan_info->status);
+ mwifiex_dbg(adapter, EVENT, "multi chan operation %s\n",
+ adapter->usb_mc_status ? "started" : "over");
- if (status) {
- mwifiex_dbg(priv->adapter, EVENT,
- "multi-channel operation started\n");
- } else {
- mwifiex_dbg(priv->adapter, EVENT,
- "multi-channel operation over\n");
+ tlv_buf_left -= sizeof(struct mwifiex_ie_types_multi_chan_info);
+ tlv = (struct mwifiex_ie_types_header *)chan_info->tlv_buffer;
+
+ while (tlv_buf_left >= (int)sizeof(struct mwifiex_ie_types_header)) {
+ tlv_type = le16_to_cpu(tlv->type);
+ tlv_len = le16_to_cpu(tlv->len);
+ if ((sizeof(struct mwifiex_ie_types_header) + tlv_len) >
+ tlv_buf_left) {
+ mwifiex_dbg(adapter, ERROR, "wrong tlv: tlvLen=%d,\t"
+ "tlvBufLeft=%d\n", tlv_len, tlv_buf_left);
+ break;
+ }
+ if (tlv_type != TLV_TYPE_MC_GROUP_INFO) {
+ mwifiex_dbg(adapter, ERROR, "wrong tlv type: 0x%x\n",
+ tlv_type);
+ break;
+ }
+
+ grp_info = (struct mwifiex_ie_types_mc_group_info *)tlv;
+ intf_num = grp_info->intf_num;
+ for (i = 0; i < intf_num; i++) {
+ bss_type = grp_info->bss_type_numlist[i] >> 4;
+ bss_num = grp_info->bss_type_numlist[i] & BSS_NUM_MASK;
+ intf_priv = mwifiex_get_priv_by_id(adapter, bss_num,
+ bss_type);
+ if (!intf_priv) {
+ mwifiex_dbg(adapter, ERROR,
+ "Invalid bss_type bss_num\t"
+ "in multi channel event\n");
+ continue;
+ }
+ if (adapter->iface_type == MWIFIEX_USB) {
+ u8 ep;
+
+ ep = grp_info->hid_num.usb_ep_num;
+ if (ep == MWIFIEX_USB_EP_DATA ||
+ ep == MWIFIEX_USB_EP_DATA_CH2)
+ intf_priv->usb_port = ep;
+ }
+ }
+
+ tlv_buf_left -= sizeof(struct mwifiex_ie_types_header) +
+ tlv_len;
+ tlv = (void *)((u8 *)tlv + tlv_len +
+ sizeof(struct mwifiex_ie_types_header));
}
+
}
void mwifiex_process_tx_pause_event(struct mwifiex_private *priv,
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index 3f1713e..5a70fe9 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -845,6 +845,8 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
break;
}
+ adapter->usb_mc_status = false;
+
return 0;
}
--
1.8.1.4
From: Aniket Nagarnaik <[email protected]>
This NULL pointer dereference is observed during suspend resume
stress test. All pending commands are cancelled when system goes
into suspend state. There a corner case in which host may receive
response for last scan command after this and try to trigger extra
active scan for hidden SSIDs.
The issue is fixed by adding a NULL check to skip that extra scan.
Fixes: 2375fa2b36feaf34 (mwifiex: fix unable to connect hidden SSID..)
Cc: <[email protected]> [v4.2+]
Signed-off-by: Aniket Nagarnaik <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/mwifiex/scan.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 3675730..c20017c 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1893,7 +1893,7 @@ mwifiex_active_scan_req_for_passive_chan(struct mwifiex_private *priv)
u8 id = 0;
struct mwifiex_user_scan_cfg *user_scan_cfg;
- if (adapter->active_scan_triggered) {
+ if (adapter->active_scan_triggered || !priv->scan_request) {
adapter->active_scan_triggered = false;
return 0;
}
--
1.8.1.4
From: Zhaoyang Liu <[email protected]>
This patch fix missing tx data_sent flag update for usb interface.
Except USB interface, data_sent flag has been updated in specific
file such as sdio.c and pcie.c. So only USB interface type need check
when TX data completed.
Signed-off-by: Zhaoyang Liu <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/mwifiex/11n_aggr.c | 4 ++--
drivers/net/wireless/mwifiex/sta_tx.c | 6 +++++-
drivers/net/wireless/mwifiex/txrx.c | 8 ++++----
drivers/net/wireless/mwifiex/wmm.c | 4 ++--
4 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index 6cb0d33..ce22cc8 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -300,7 +300,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
mwifiex_dbg(adapter, ERROR, "data: -EBUSY is returned\n");
break;
case -1:
- if (adapter->iface_type != MWIFIEX_PCIE)
+ if (adapter->iface_type == MWIFIEX_USB)
adapter->data_sent = false;
mwifiex_dbg(adapter, ERROR, "%s: host_to_card failed: %#x\n",
__func__, ret);
@@ -308,7 +308,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
mwifiex_write_data_complete(adapter, skb_aggr, 1, ret);
return 0;
case -EINPROGRESS:
- if (adapter->iface_type != MWIFIEX_PCIE)
+ if (adapter->iface_type == MWIFIEX_USB)
adapter->data_sent = false;
break;
case 0:
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index 355ac59..7a4d5f4 100644
--- a/drivers/net/wireless/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -174,6 +174,7 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
local_tx_pd->bss_type = priv->bss_type;
if (adapter->iface_type == MWIFIEX_USB) {
+ adapter->data_sent = true;
ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_USB_EP_DATA,
skb, NULL);
} else {
@@ -191,7 +192,8 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
adapter->dbg.num_tx_host_to_card_failure++;
break;
case -1:
- adapter->data_sent = false;
+ if (adapter->iface_type == MWIFIEX_USB)
+ adapter->data_sent = false;
dev_kfree_skb_any(skb);
mwifiex_dbg(adapter, ERROR,
"%s: host_to_card failed: ret=%d\n",
@@ -206,6 +208,8 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
adapter->tx_lock_flag = true;
break;
case -EINPROGRESS:
+ if (adapter->iface_type == MWIFIEX_USB)
+ adapter->data_sent = false;
adapter->tx_lock_flag = true;
break;
default:
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index 98f097d..6ef030a 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -142,7 +142,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
mwifiex_dbg(adapter, ERROR, "data: -EBUSY is returned\n");
break;
case -1:
- if (adapter->iface_type != MWIFIEX_PCIE)
+ if (adapter->iface_type == MWIFIEX_USB)
adapter->data_sent = false;
mwifiex_dbg(adapter, ERROR,
"mwifiex_write_data_async failed: 0x%X\n",
@@ -151,7 +151,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
mwifiex_write_data_complete(adapter, skb, 0, ret);
break;
case -EINPROGRESS:
- if (adapter->iface_type != MWIFIEX_PCIE)
+ if (adapter->iface_type == MWIFIEX_USB)
adapter->data_sent = false;
break;
case 0:
@@ -222,7 +222,7 @@ static int mwifiex_host_to_card(struct mwifiex_adapter *adapter,
mwifiex_dbg(adapter, ERROR, "data: -EBUSY is returned\n");
break;
case -1:
- if (adapter->iface_type != MWIFIEX_PCIE)
+ if (adapter->iface_type == MWIFIEX_USB)
adapter->data_sent = false;
mwifiex_dbg(adapter, ERROR,
"mwifiex_write_data_async failed: 0x%X\n", ret);
@@ -230,7 +230,7 @@ static int mwifiex_host_to_card(struct mwifiex_adapter *adapter,
mwifiex_write_data_complete(adapter, skb, 0, ret);
break;
case -EINPROGRESS:
- if (adapter->iface_type != MWIFIEX_PCIE)
+ if (adapter->iface_type == MWIFIEX_USB)
adapter->data_sent = false;
break;
case 0:
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 8e30fb3..8a3f59e 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -1356,14 +1356,14 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
ra_list_flags);
break;
case -1:
- if (adapter->iface_type != MWIFIEX_PCIE)
+ if (adapter->iface_type == MWIFIEX_USB)
adapter->data_sent = false;
mwifiex_dbg(adapter, ERROR, "host_to_card failed: %#x\n", ret);
adapter->dbg.num_tx_host_to_card_failure++;
mwifiex_write_data_complete(adapter, skb, 0, ret);
break;
case -EINPROGRESS:
- if (adapter->iface_type != MWIFIEX_PCIE)
+ if (adapter->iface_type == MWIFIEX_USB)
adapter->data_sent = false;
break;
case 0:
--
1.8.1.4
We have preallocated buffer pool for Tx data. During high
data traffic, all buffers are submitted to USB and driver needs
to wait until one of the buffers get available for next Tx
packet.
"data: -ENOSR is returned" errors is expected in this case. Let's
lower the priority of this message.
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/mwifiex/txrx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index 8b1e5b5..98f097d 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -130,7 +130,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
switch (ret) {
case -ENOSR:
- mwifiex_dbg(adapter, ERROR, "data: -ENOSR is returned\n");
+ mwifiex_dbg(adapter, DATA, "data: -ENOSR is returned\n");
break;
case -EBUSY:
if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
--
1.8.1.4
> From: Xinming Hu <[email protected]>
>
> Interface counters should be incremented in add_virtual_intf()
> and decremented in del_virtual_intf() function. This patch
> corrects it.
>
> Signed-off-by: Xinming Hu <[email protected]>
> Signed-off-by: Amitkumar Karwar <[email protected]>
Thanks, 16 patches applied to wireless-drivers-next.git:
65405c51bb2e mwifiex: fix typo in del_virtual_intf() function
0a252abb6ad7 mwifiex: update amsdu tx packet time stamp
e3ad3d5b6ab2 mwifiex: minor corrections in multiport aggregation code
9a9053c3420f mwifiex: fix driver init failure under memory pressure
02421dd3f6af mwifiex: NULL check for cfg80211_inform_bss()
2c3da961268f mwifiex: don't always include ht/vht info in tdls confirm frame
17e524b1b60f mwifiex: fix NULL pointer dereference during hidden SSID scan
14d9c11c91a6 mwifiex: avoid memsetting PCIe event buffer
70c5ad7e20c1 mwifiex: correct paused tx data packet counter
17090beec26e mwifiex: Suppress -ENOSR error for data traffic on USB
d22871db0172 mwifiex: fix tx data_sent issue for usb interface
d941444321f6 mwifiex: move usb specific data_sent update to usb.c
2b0f997db43f mwifiex: add usb multi channel event process support
308fe29ef243 mwifiex: add usb tx data multi endpoints support
7e4e5d2cd081 mwifiex: add usb multi endpoints resync support
735ab6bfc038 mwifiex: complete usb tx data with multi endpoints
Kalle Valo
From: Zhaoyang Liu <[email protected]>
This patch fixes the issue of delay time in A-MSDU tx packet.
In generated new A-MSDU packet, the time stamp is initialized to zero.
Choose the time of first MSDU packet as aggregated packet's time.
Signed-off-by: Zhaoyang Liu <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/mwifiex/11n_aggr.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index f7c7172..6cb0d33 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -202,6 +202,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;
tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_AGGR_PKT;
skb_aggr->priority = skb_src->priority;
+ skb_aggr->tstamp = skb_src->tstamp;
do_gettimeofday(&tv);
skb_aggr->tstamp = timeval_to_ktime(tv);
--
1.8.1.4
From: Aniket Nagarnaik <[email protected]>
Current TDLS implementation always includes ht/vht information
in tdls setup confirm frame which causes teardown by legacy
peer station after TDLS handshake. We will inclue ht/vht
capabilities in tdls setup confirm frame only if peer station
supports it to fix this problem.
Signed-off-by: Aniket Nagarnaik <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/mwifiex/tdls.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/net/wireless/mwifiex/tdls.c b/drivers/net/wireless/mwifiex/tdls.c
index b3e163d..9275f9c 100644
--- a/drivers/net/wireless/mwifiex/tdls.c
+++ b/drivers/net/wireless/mwifiex/tdls.c
@@ -204,6 +204,12 @@ mwifiex_tdls_add_ht_oper(struct mwifiex_private *priv, const u8 *mac,
return -1;
}
+ if (!(le16_to_cpu(sta_ptr->tdls_cap.ht_capb.cap_info))) {
+ mwifiex_dbg(priv->adapter, WARN,
+ "TDLS peer doesn't support ht capabilities\n");
+ return 0;
+ }
+
pos = (void *)skb_put(skb, sizeof(struct ieee80211_ht_operation) + 2);
*pos++ = WLAN_EID_HT_OPERATION;
*pos++ = sizeof(struct ieee80211_ht_operation);
@@ -252,6 +258,12 @@ static int mwifiex_tdls_add_vht_oper(struct mwifiex_private *priv,
return -1;
}
+ if (!(le32_to_cpu(sta_ptr->tdls_cap.vhtcap.vht_cap_info))) {
+ mwifiex_dbg(adapter, WARN,
+ "TDLS peer doesn't support vht capabilities\n");
+ return 0;
+ }
+
if (!mwifiex_is_bss_in_11ac_mode(priv)) {
if (sta_ptr->tdls_cap.extcap.ext_capab[7] &
WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED) {
--
1.8.1.4
From: Zhaoyang Liu <[email protected]>
This patch add support for USB interface to TX data
with different endpoint. And previous TX information
are saved in new designed structure.
Signed-off-by: Zhaoyang Liu <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/mwifiex/main.c | 6 +-
drivers/net/wireless/mwifiex/usb.c | 124 ++++++++++++++++++++++++------------
drivers/net/wireless/mwifiex/usb.h | 13 ++--
3 files changed, 97 insertions(+), 46 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 278dc94..6c8f35f 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -963,8 +963,10 @@ void mwifiex_drv_info_dump(struct mwifiex_adapter *adapter)
cardp = (struct usb_card_rec *)adapter->card;
p += sprintf(p, "tx_cmd_urb_pending = %d\n",
atomic_read(&cardp->tx_cmd_urb_pending));
- p += sprintf(p, "tx_data_urb_pending = %d\n",
- atomic_read(&cardp->tx_data_urb_pending));
+ p += sprintf(p, "tx_data_urb_pending_port_0 = %d\n",
+ atomic_read(&cardp->port[0].tx_data_urb_pending));
+ p += sprintf(p, "tx_data_urb_pending_port_1 = %d\n",
+ atomic_read(&cardp->port[1].tx_data_urb_pending));
p += sprintf(p, "rx_cmd_urb_pending = %d\n",
atomic_read(&cardp->rx_cmd_urb_pending));
p += sprintf(p, "rx_data_urb_pending = %d\n",
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index 5a70fe9..cc120d6 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -259,6 +259,8 @@ static void mwifiex_usb_tx_complete(struct urb *urb)
struct urb_context *context = (struct urb_context *)(urb->context);
struct mwifiex_adapter *adapter = context->adapter;
struct usb_card_rec *card = adapter->card;
+ struct usb_tx_data_port *port;
+ int i;
mwifiex_dbg(adapter, INFO,
"%s: status: %d\n", __func__, urb->status);
@@ -271,7 +273,13 @@ static void mwifiex_usb_tx_complete(struct urb *urb)
} else {
mwifiex_dbg(adapter, DATA,
"%s: DATA\n", __func__);
- atomic_dec(&card->tx_data_urb_pending);
+ for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++) {
+ port = &card->port[i];
+ if (context->ep == port->tx_data_ep) {
+ atomic_dec(&port->tx_data_urb_pending);
+ break;
+ }
+ }
adapter->data_sent = false;
mwifiex_write_data_complete(adapter, context->skb, 0,
urb->status ? -1 : 0);
@@ -323,7 +331,8 @@ static int mwifiex_usb_submit_rx_urb(struct urb_context *ctx, int size)
static void mwifiex_usb_free(struct usb_card_rec *card)
{
- int i;
+ struct usb_tx_data_port *port;
+ int i, j;
if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb)
usb_kill_urb(card->rx_cmd.urb);
@@ -341,9 +350,12 @@ static void mwifiex_usb_free(struct usb_card_rec *card)
card->rx_data_list[i].urb = NULL;
}
- for (i = 0; i < MWIFIEX_TX_DATA_URB; i++) {
- usb_free_urb(card->tx_data_list[i].urb);
- card->tx_data_list[i].urb = NULL;
+ for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++) {
+ port = &card->port[i];
+ for (j = 0; j < MWIFIEX_TX_DATA_URB; j++) {
+ usb_free_urb(port->tx_data_list[j].urb);
+ port->tx_data_list[j].urb = NULL;
+ }
}
usb_free_urb(card->tx_cmd.urb);
@@ -431,8 +443,18 @@ static int mwifiex_usb_probe(struct usb_interface *intf,
pr_debug("info: bulk OUT: max pkt size: %d, addr: %d\n",
le16_to_cpu(epd->wMaxPacketSize),
epd->bEndpointAddress);
- card->tx_data_ep = usb_endpoint_num(epd);
- atomic_set(&card->tx_data_urb_pending, 0);
+ card->port[0].tx_data_ep = usb_endpoint_num(epd);
+ atomic_set(&card->port[0].tx_data_urb_pending, 0);
+ }
+ if (usb_endpoint_dir_out(epd) &&
+ usb_endpoint_num(epd) == MWIFIEX_USB_EP_DATA_CH2 &&
+ usb_endpoint_xfer_bulk(epd)) {
+ pr_debug("info: bulk OUT chan2:\t"
+ "max pkt size: %d, addr: %d\n",
+ le16_to_cpu(epd->wMaxPacketSize),
+ epd->bEndpointAddress);
+ card->port[1].tx_data_ep = usb_endpoint_num(epd);
+ atomic_set(&card->port[1].tx_data_urb_pending, 0);
}
if (usb_endpoint_dir_out(epd) &&
usb_endpoint_num(epd) == MWIFIEX_USB_EP_CMD_EVENT &&
@@ -474,7 +496,8 @@ static int mwifiex_usb_suspend(struct usb_interface *intf, pm_message_t message)
{
struct usb_card_rec *card = usb_get_intfdata(intf);
struct mwifiex_adapter *adapter;
- int i;
+ struct usb_tx_data_port *port;
+ int i, j;
if (!card || !card->adapter) {
pr_err("%s: card or card->adapter is NULL\n", __func__);
@@ -505,9 +528,13 @@ static int mwifiex_usb_suspend(struct usb_interface *intf, pm_message_t message)
if (card->rx_data_list[i].urb)
usb_kill_urb(card->rx_data_list[i].urb);
- for (i = 0; i < MWIFIEX_TX_DATA_URB; i++)
- if (card->tx_data_list[i].urb)
- usb_kill_urb(card->tx_data_list[i].urb);
+ for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++) {
+ port = &card->port[i];
+ for (j = 0; j < MWIFIEX_TX_DATA_URB; j++) {
+ if (port->tx_data_list[j].urb)
+ usb_kill_urb(port->tx_data_list[j].urb);
+ }
+ }
if (card->tx_cmd.urb)
usb_kill_urb(card->tx_cmd.urb);
@@ -619,7 +646,8 @@ static struct usb_driver mwifiex_usb_driver = {
static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter)
{
struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;
- int i;
+ struct usb_tx_data_port *port;
+ int i, j;
card->tx_cmd.adapter = adapter;
card->tx_cmd.ep = card->tx_cmd_ep;
@@ -631,17 +659,21 @@ static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter)
return -ENOMEM;
}
- card->tx_data_ix = 0;
-
- for (i = 0; i < MWIFIEX_TX_DATA_URB; i++) {
- card->tx_data_list[i].adapter = adapter;
- card->tx_data_list[i].ep = card->tx_data_ep;
-
- card->tx_data_list[i].urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!card->tx_data_list[i].urb) {
- mwifiex_dbg(adapter, ERROR,
- "tx_data_list[] urb allocation failed\n");
- return -ENOMEM;
+ for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++) {
+ port = &card->port[i];
+ if (!port->tx_data_ep)
+ continue;
+ port->tx_data_ix = 0;
+ for (j = 0; j < MWIFIEX_TX_DATA_URB; j++) {
+ port->tx_data_list[j].adapter = adapter;
+ port->tx_data_list[j].ep = port->tx_data_ep;
+ port->tx_data_list[j].urb =
+ usb_alloc_urb(0, GFP_KERNEL);
+ if (!port->tx_data_list[j].urb) {
+ mwifiex_dbg(adapter, ERROR,
+ "urb allocation failed\n");
+ return -ENOMEM;
+ }
}
}
@@ -736,9 +768,11 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
struct mwifiex_tx_param *tx_param)
{
struct usb_card_rec *card = adapter->card;
- struct urb_context *context;
+ struct urb_context *context = NULL;
+ struct usb_tx_data_port *port = NULL;
u8 *data = (u8 *)skb->data;
struct urb *tx_urb;
+ int idx;
if (adapter->is_suspended) {
mwifiex_dbg(adapter, ERROR,
@@ -751,20 +785,30 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
return -1;
}
- if (ep == card->tx_data_ep &&
- atomic_read(&card->tx_data_urb_pending) >= MWIFIEX_TX_DATA_URB) {
- adapter->data_sent = true;
- return -EBUSY;
- }
-
mwifiex_dbg(adapter, INFO, "%s: ep=%d\n", __func__, ep);
if (ep == card->tx_cmd_ep) {
context = &card->tx_cmd;
} else {
- if (card->tx_data_ix >= MWIFIEX_TX_DATA_URB)
- card->tx_data_ix = 0;
- context = &card->tx_data_list[card->tx_data_ix++];
+ for (idx = 0; idx < MWIFIEX_TX_DATA_PORT; idx++) {
+ if (ep == card->port[idx].tx_data_ep) {
+ port = &card->port[idx];
+ if (atomic_read(&port->tx_data_urb_pending)
+ >= MWIFIEX_TX_DATA_URB) {
+ adapter->data_sent = true;
+ return -EBUSY;
+ }
+ if (port->tx_data_ix >= MWIFIEX_TX_DATA_URB)
+ port->tx_data_ix = 0;
+ context =
+ &port->tx_data_list[port->tx_data_ix++];
+ break;
+ }
+ }
+ if (!port) {
+ mwifiex_dbg(adapter, ERROR, "Wrong usb tx data port\n");
+ return -1;
+ }
}
context->adapter = adapter;
@@ -781,7 +825,7 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
if (ep == card->tx_cmd_ep)
atomic_inc(&card->tx_cmd_urb_pending);
else
- atomic_inc(&card->tx_data_urb_pending);
+ atomic_inc(&port->tx_data_urb_pending);
if (usb_submit_urb(tx_urb, GFP_ATOMIC)) {
mwifiex_dbg(adapter, ERROR,
@@ -789,18 +833,18 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
if (ep == card->tx_cmd_ep) {
atomic_dec(&card->tx_cmd_urb_pending);
} else {
- atomic_dec(&card->tx_data_urb_pending);
+ atomic_dec(&port->tx_data_urb_pending);
adapter->data_sent = false;
- if (card->tx_data_ix)
- card->tx_data_ix--;
+ if (port->tx_data_ix)
+ port->tx_data_ix--;
else
- card->tx_data_ix = MWIFIEX_TX_DATA_URB;
+ port->tx_data_ix = MWIFIEX_TX_DATA_URB;
}
return -1;
} else {
- if (ep == card->tx_data_ep &&
- atomic_read(&card->tx_data_urb_pending) ==
+ if (ep != card->tx_cmd_ep &&
+ atomic_read(&port->tx_data_urb_pending) ==
MWIFIEX_TX_DATA_URB) {
adapter->data_sent = true;
return -ENOSR;
diff --git a/drivers/net/wireless/mwifiex/usb.h b/drivers/net/wireless/mwifiex/usb.h
index 6029a68..6339d87 100644
--- a/drivers/net/wireless/mwifiex/usb.h
+++ b/drivers/net/wireless/mwifiex/usb.h
@@ -38,6 +38,7 @@
#define USB8XXX_FW_READY 2
#define USB8XXX_FW_MAX_RETRY 3
+#define MWIFIEX_TX_DATA_PORT 2
#define MWIFIEX_TX_DATA_URB 6
#define MWIFIEX_RX_DATA_URB 6
#define MWIFIEX_USB_TIMEOUT 100
@@ -61,6 +62,13 @@ struct urb_context {
u8 ep;
};
+struct usb_tx_data_port {
+ u8 tx_data_ep;
+ atomic_t tx_data_urb_pending;
+ int tx_data_ix;
+ struct urb_context tx_data_list[MWIFIEX_TX_DATA_URB];
+};
+
struct usb_card_rec {
struct mwifiex_adapter *adapter;
struct usb_device *udev;
@@ -72,14 +80,11 @@ struct usb_card_rec {
u8 usb_boot_state;
u8 rx_data_ep;
atomic_t rx_data_urb_pending;
- u8 tx_data_ep;
u8 tx_cmd_ep;
- atomic_t tx_data_urb_pending;
atomic_t tx_cmd_urb_pending;
int bulk_out_maxpktsize;
struct urb_context tx_cmd;
- int tx_data_ix;
- struct urb_context tx_data_list[MWIFIEX_TX_DATA_URB];
+ struct usb_tx_data_port port[MWIFIEX_TX_DATA_PORT];
};
struct fw_header {
--
1.8.1.4