2013-07-23 02:18:46

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 00/21] mwifiex updates for 3.12

This series includes error case handling, bridged packet handling
in AP mode, p2p updates, random cleanups, etc.

Amitkumar Karwar (11):
mwifiex: add PCIe shutdown handler to avoid system hang on reboot
mwifiex: move del_timer_sync(scan_delay_timer) call to fix memleak
mwifiex: remove unnecessary del_timer(cmd_timer)
mwifiex: move if_ops.cleanup_if() call
mwifiex: add unregister_dev handler for usb interface
mwifiex: reduce firmware poll retries
mwifiex: replace mdelay with msleep
mwifiex: correction in mwifiex_check_fw_status() return status
mwifiex: handle driver initialization error paths
mwifiex: code rearrangement in sdio.c
mwifiex: remove duplicate structure host_cmd_tlv

Avinash Patil (5):
mwifiex: rename pkt_count to ba_pkt_count in mwifiex_ra_list_tbl
struct
mwifiex: maintain outstanding packet count for RA list instead of
packet size
mwifiex: delete AP TX queues when bridged packets reach threshold
mwifiex: correct max IE length check for WPS IE
mwifiex: modify mwifiex_ap_sta_limits to advertise support for P2P

Huawei Yang (2):
mwifiex: remove stop_net_dev_queue operation in AP forwarding
mwifiex: add tx info to skb when forming mgmt frame

Stone Piao (3):
mwifiex: discard deauth and disassoc event during WPS session
mwifiex: skip registering mgmt frame that has already registered
mwifiex: support to send deauth for P2P client

drivers/net/wireless/mwifiex/11n_aggr.c | 4 +-
drivers/net/wireless/mwifiex/cfg80211.c | 25 +++-
drivers/net/wireless/mwifiex/decl.h | 3 +-
drivers/net/wireless/mwifiex/fw.h | 44 +++----
drivers/net/wireless/mwifiex/ie.c | 2 +-
drivers/net/wireless/mwifiex/init.c | 14 +-
drivers/net/wireless/mwifiex/join.c | 1 +
drivers/net/wireless/mwifiex/main.c | 87 +++++++++----
drivers/net/wireless/mwifiex/main.h | 6 +-
drivers/net/wireless/mwifiex/pcie.c | 13 +-
drivers/net/wireless/mwifiex/sdio.c | 213 +++++++++++++++----------------
drivers/net/wireless/mwifiex/sta_cmd.c | 5 +-
drivers/net/wireless/mwifiex/sta_event.c | 10 ++
drivers/net/wireless/mwifiex/sta_ioctl.c | 11 +-
drivers/net/wireless/mwifiex/uap_cmd.c | 130 ++++++++++---------
drivers/net/wireless/mwifiex/uap_txrx.c | 70 +++++++++-
drivers/net/wireless/mwifiex/usb.c | 8 ++
drivers/net/wireless/mwifiex/wmm.c | 16 +--
18 files changed, 390 insertions(+), 272 deletions(-)

--
1.8.2.3



2013-07-23 02:19:17

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 17/21] mwifiex: correction in mwifiex_check_fw_status() return status

From: Amitkumar Karwar <[email protected]>

For PCIe cards, when wrong firmware is downloaded, firmware is
failed to be ready in 10 seconds. We should return an error at
this point. But currently we are sending first command to firmware.
As expected firmware doesn't respond to this command and command
timeout occurs.

This patch fixes the problem by removing unnecessary 'ret'
variable modifications in "if (ret) {" block.
The block is just supposed to update "adapter->winner" flag.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/pcie.c | 2 --
1 file changed, 2 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 098153f..52da8ee 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -1954,12 +1954,10 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
else if (!winner_status) {
dev_err(adapter->dev, "PCI-E is the winner\n");
adapter->winner = 1;
- ret = -1;
} else {
dev_err(adapter->dev,
"PCI-E is not the winner <%#x,%d>, exit dnld\n",
ret, adapter->winner);
- ret = 0;
}
}

--
1.8.2.3


2013-07-23 02:18:57

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 18/21] mwifiex: handle driver initialization error paths

From: Amitkumar Karwar <[email protected]>

mwifiex_fw_dpc() asynchronously takes care of firmware download
and initialization. Currently the error paths in mwifiex_fw_dpc()
are not handled. So if wrong firmware is downloaded, required
cleanup work is not performed. memory is leaked and workqueue
remains unterminated in this case.

mwifiex_terminate_workqueue() is moved to avoid forward
declaration.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/main.c | 83 ++++++++++++++++++++++++-------------
drivers/net/wireless/mwifiex/main.h | 1 +
2 files changed, 56 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index e64c369..5644c7f 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -390,6 +390,17 @@ static void mwifiex_free_adapter(struct mwifiex_adapter *adapter)
}

/*
+ * This function cancels all works in the queue and destroys
+ * the main workqueue.
+ */
+static void mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
+{
+ flush_workqueue(adapter->workqueue);
+ destroy_workqueue(adapter->workqueue);
+ adapter->workqueue = NULL;
+}
+
+/*
* This function gets firmware and initializes it.
*
* The main initialization steps followed are -
@@ -398,7 +409,7 @@ static void mwifiex_free_adapter(struct mwifiex_adapter *adapter)
*/
static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
{
- int ret;
+ int ret, i;
char fmt[64];
struct mwifiex_private *priv;
struct mwifiex_adapter *adapter = context;
@@ -407,7 +418,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
if (!firmware) {
dev_err(adapter->dev,
"Failed to get firmware %s\n", adapter->fw_name);
- goto done;
+ goto err_dnld_fw;
}

memset(&fw, 0, sizeof(struct mwifiex_fw_image));
@@ -420,7 +431,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
else
ret = mwifiex_dnld_fw(adapter, &fw);
if (ret == -1)
- goto done;
+ goto err_dnld_fw;

dev_notice(adapter->dev, "WLAN FW is active\n");

@@ -432,13 +443,15 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
}

/* enable host interrupt after fw dnld is successful */
- if (adapter->if_ops.enable_int)
- adapter->if_ops.enable_int(adapter);
+ if (adapter->if_ops.enable_int) {
+ if (adapter->if_ops.enable_int(adapter))
+ goto err_dnld_fw;
+ }

adapter->init_wait_q_woken = false;
ret = mwifiex_init_fw(adapter);
if (ret == -1) {
- goto done;
+ goto err_init_fw;
} else if (!ret) {
adapter->hw_status = MWIFIEX_HW_STATUS_READY;
goto done;
@@ -447,12 +460,12 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
wait_event_interruptible(adapter->init_wait_q,
adapter->init_wait_q_woken);
if (adapter->hw_status != MWIFIEX_HW_STATUS_READY)
- goto done;
+ goto err_init_fw;

priv = adapter->priv[MWIFIEX_BSS_ROLE_STA];
if (mwifiex_register_cfg80211(adapter)) {
dev_err(adapter->dev, "cannot register with cfg80211\n");
- goto err_init_fw;
+ goto err_register_cfg80211;
}

rtnl_lock();
@@ -483,13 +496,39 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
goto done;

err_add_intf:
- mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
+ for (i = 0; i < adapter->priv_num; i++) {
+ priv = adapter->priv[i];
+
+ if (!priv)
+ continue;
+
+ if (priv->wdev && priv->netdev)
+ mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
+ }
rtnl_unlock();
+err_register_cfg80211:
+ wiphy_unregister(adapter->wiphy);
+ wiphy_free(adapter->wiphy);
err_init_fw:
if (adapter->if_ops.disable_int)
adapter->if_ops.disable_int(adapter);
+err_dnld_fw:
pr_debug("info: %s: unregister device\n", __func__);
- adapter->if_ops.unregister_dev(adapter);
+ if (adapter->if_ops.unregister_dev)
+ adapter->if_ops.unregister_dev(adapter);
+
+ if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) ||
+ (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) {
+ pr_debug("info: %s: shutdown mwifiex\n", __func__);
+ adapter->init_wait_q_woken = false;
+
+ if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
+ wait_event_interruptible(adapter->init_wait_q,
+ adapter->init_wait_q_woken);
+ }
+ adapter->surprise_removed = true;
+ mwifiex_terminate_workqueue(adapter);
+ mwifiex_free_adapter(adapter);
done:
if (adapter->cal_data) {
release_firmware(adapter->cal_data);
@@ -497,6 +536,7 @@ done:
}
release_firmware(adapter->firmware);
complete(&adapter->fw_load);
+ up(adapter->card_sem);
return;
}

@@ -807,18 +847,6 @@ static void mwifiex_main_work_queue(struct work_struct *work)
}

/*
- * This function cancels all works in the queue and destroys
- * the main workqueue.
- */
-static void
-mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
-{
- flush_workqueue(adapter->workqueue);
- destroy_workqueue(adapter->workqueue);
- adapter->workqueue = NULL;
-}
-
-/*
* This function adds the card.
*
* This function follows the following major steps to set up the device -
@@ -846,6 +874,7 @@ mwifiex_add_card(void *card, struct semaphore *sem,
}

adapter->iface_type = iface_type;
+ adapter->card_sem = sem;

adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
adapter->surprise_removed = false;
@@ -876,17 +905,12 @@ mwifiex_add_card(void *card, struct semaphore *sem,
goto err_init_fw;
}

- up(sem);
return 0;

err_init_fw:
pr_debug("info: %s: unregister device\n", __func__);
if (adapter->if_ops.unregister_dev)
adapter->if_ops.unregister_dev(adapter);
-err_registerdev:
- adapter->surprise_removed = true;
- mwifiex_terminate_workqueue(adapter);
-err_kmalloc:
if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) ||
(adapter->hw_status == MWIFIEX_HW_STATUS_READY)) {
pr_debug("info: %s: shutdown mwifiex\n", __func__);
@@ -896,7 +920,10 @@ err_kmalloc:
wait_event_interruptible(adapter->init_wait_q,
adapter->init_wait_q_woken);
}
-
+err_registerdev:
+ adapter->surprise_removed = true;
+ mwifiex_terminate_workqueue(adapter);
+err_kmalloc:
mwifiex_free_adapter(adapter);

err_init_sw:
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index bb28d3d..9ee3b1b 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -749,6 +749,7 @@ struct mwifiex_adapter {

atomic_t is_tx_received;
atomic_t pending_bridged_pkts;
+ struct semaphore *card_sem;
};

int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
--
1.8.2.3


2013-07-23 02:19:22

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 16/21] mwifiex: replace mdelay with msleep

From: Amitkumar Karwar <[email protected]>

It is observed that when wrong firmware is downloaded for
PCIe card, system hangs for 10 seconds. The reason is mdelay()
is used when firmware status is polled.

Replace mdelay with msleep(non-blocking API) to fix the issue.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/pcie.c | 2 +-
drivers/net/wireless/mwifiex/sdio.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index dce6486..098153f 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -1942,7 +1942,7 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
ret = 0;
break;
} else {
- mdelay(100);
+ msleep(100);
ret = -1;
}
}
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 5ef49f2..c32a735 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -944,7 +944,7 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
ret = 0;
break;
} else {
- mdelay(100);
+ msleep(100);
ret = -1;
}
}
--
1.8.2.3


2013-07-23 02:18:30

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 02/21] mwifiex: rename pkt_count to ba_pkt_count in mwifiex_ra_list_tbl struct

From: Avinash Patil <[email protected]>

pkt_count is used to determine if BA can be formed on this RA list
by comparing it with randomly generated BA threshold. The pkt_count
variable name here is ambiguous and does not reflect its usage
correctly. Rename it to ba_pkt_count.

Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/main.h | 2 +-
drivers/net/wireless/mwifiex/wmm.c | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 253e0bd..884b42b 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -207,7 +207,7 @@ struct mwifiex_ra_list_tbl {
u32 total_pkts_size;
u32 is_11n_enabled;
u16 max_amsdu;
- u16 pkt_count;
+ u16 ba_pkt_count;
u8 ba_packet_thr;
};

diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 944e884..9c1eeee 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -188,7 +188,7 @@ mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra)
ra_list, ra_list->is_11n_enabled);

if (ra_list->is_11n_enabled) {
- ra_list->pkt_count = 0;
+ ra_list->ba_pkt_count = 0;
ra_list->ba_packet_thr =
mwifiex_get_random_ba_threshold();
}
@@ -680,7 +680,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
skb_queue_tail(&ra_list->skb_head, skb);

ra_list->total_pkts_size += skb->len;
- ra_list->pkt_count++;
+ ra_list->ba_pkt_count++;

if (atomic_read(&priv->wmm.highest_queued_prio) <
tos_to_tid_inv[tid_down])
@@ -1063,7 +1063,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
skb_queue_tail(&ptr->skb_head, skb);

ptr->total_pkts_size += skb->len;
- ptr->pkt_count++;
+ ptr->ba_pkt_count++;
tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
ra_list_flags);
@@ -1224,7 +1224,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
mwifiex_send_single_packet() */
} else {
if (mwifiex_is_ampdu_allowed(priv, tid) &&
- ptr->pkt_count > ptr->ba_packet_thr) {
+ ptr->ba_pkt_count > ptr->ba_packet_thr) {
if (mwifiex_space_avail_for_new_ba_stream(adapter)) {
mwifiex_create_ba_tbl(priv, ptr->ra, tid,
BA_SETUP_INPROGRESS);
--
1.8.2.3


2013-07-24 15:30:12

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 19/21] mwifiex: code rearrangement in sdio.c

This one also did not apply on the current wireless-next...

On Mon, Jul 22, 2013 at 07:17:56PM -0700, Bing Zhao wrote:
> From: Amitkumar Karwar <[email protected]>
>
> Some function definitions are moved to appropriate place
> to avoid forward declarations.
>
> Signed-off-by: Amitkumar Karwar <[email protected]>
> Signed-off-by: Bing Zhao <[email protected]>
> ---
> drivers/net/wireless/mwifiex/sdio.c | 211 ++++++++++++++++++------------------
> 1 file changed, 104 insertions(+), 107 deletions(-)
>
> diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
> index c32a735..1eb5efa1 100644
> --- a/drivers/net/wireless/mwifiex/sdio.c
> +++ b/drivers/net/wireless/mwifiex/sdio.c
> @@ -50,9 +50,6 @@ static struct mwifiex_if_ops sdio_ops;
>
> static struct semaphore add_remove_card_sem;
>
> -static int mwifiex_sdio_resume(struct device *dev);
> -static void mwifiex_sdio_interrupt(struct sdio_func *func);
> -
> /*
> * SDIO probe.
> *
> @@ -113,6 +110,51 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
> }
>
> /*
> + * SDIO resume.
> + *
> + * Kernel needs to suspend all functions separately. Therefore all
> + * registered functions must have drivers with suspend and resume
> + * methods. Failing that the kernel simply removes the whole card.
> + *
> + * If already not resumed, this function turns on the traffic and
> + * sends a host sleep cancel request to the firmware.
> + */
> +static int mwifiex_sdio_resume(struct device *dev)
> +{
> + struct sdio_func *func = dev_to_sdio_func(dev);
> + struct sdio_mmc_card *card;
> + struct mwifiex_adapter *adapter;
> + mmc_pm_flag_t pm_flag = 0;
> +
> + if (func) {
> + pm_flag = sdio_get_host_pm_caps(func);
> + card = sdio_get_drvdata(func);
> + if (!card || !card->adapter) {
> + pr_err("resume: invalid card or adapter\n");
> + return 0;
> + }
> + } else {
> + pr_err("resume: sdio_func is not specified\n");
> + return 0;
> + }
> +
> + adapter = card->adapter;
> +
> + if (!adapter->is_suspended) {
> + dev_warn(adapter->dev, "device already resumed\n");
> + return 0;
> + }
> +
> + adapter->is_suspended = false;
> +
> + /* Disable Host Sleep */
> + mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
> + MWIFIEX_ASYNC_CMD);
> +
> + return 0;
> +}
> +
> +/*
> * SDIO remove.
> *
> * This function removes the interface and frees up the card structure.
> @@ -212,51 +254,6 @@ static int mwifiex_sdio_suspend(struct device *dev)
> return ret;
> }
>
> -/*
> - * SDIO resume.
> - *
> - * Kernel needs to suspend all functions separately. Therefore all
> - * registered functions must have drivers with suspend and resume
> - * methods. Failing that the kernel simply removes the whole card.
> - *
> - * If already not resumed, this function turns on the traffic and
> - * sends a host sleep cancel request to the firmware.
> - */
> -static int mwifiex_sdio_resume(struct device *dev)
> -{
> - struct sdio_func *func = dev_to_sdio_func(dev);
> - struct sdio_mmc_card *card;
> - struct mwifiex_adapter *adapter;
> - mmc_pm_flag_t pm_flag = 0;
> -
> - if (func) {
> - pm_flag = sdio_get_host_pm_caps(func);
> - card = sdio_get_drvdata(func);
> - if (!card || !card->adapter) {
> - pr_err("resume: invalid card or adapter\n");
> - return 0;
> - }
> - } else {
> - pr_err("resume: sdio_func is not specified\n");
> - return 0;
> - }
> -
> - adapter = card->adapter;
> -
> - if (!adapter->is_suspended) {
> - dev_warn(adapter->dev, "device already resumed\n");
> - return 0;
> - }
> -
> - adapter->is_suspended = false;
> -
> - /* Disable Host Sleep */
> - mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
> - MWIFIEX_ASYNC_CMD);
> -
> - return 0;
> -}
> -
> /* Device ID for SD8786 */
> #define SDIO_DEVICE_ID_MARVELL_8786 (0x9116)
> /* Device ID for SD8787 */
> @@ -707,6 +704,65 @@ static void mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
> }
>
> /*
> + * This function reads the interrupt status from card.
> + */
> +static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
> +{
> + struct sdio_mmc_card *card = adapter->card;
> + u8 sdio_ireg;
> + unsigned long flags;
> +
> + if (mwifiex_read_data_sync(adapter, card->mp_regs,
> + card->reg->max_mp_regs,
> + REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0)) {
> + dev_err(adapter->dev, "read mp_regs failed\n");
> + return;
> + }
> +
> + sdio_ireg = card->mp_regs[HOST_INTSTATUS_REG];
> + if (sdio_ireg) {
> + /*
> + * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
> + * For SDIO new mode CMD port interrupts
> + * DN_LD_CMD_PORT_HOST_INT_STATUS and/or
> + * UP_LD_CMD_PORT_HOST_INT_STATUS
> + * Clear the interrupt status register
> + */
> + dev_dbg(adapter->dev, "int: sdio_ireg = %#x\n", sdio_ireg);
> + spin_lock_irqsave(&adapter->int_lock, flags);
> + adapter->int_status |= sdio_ireg;
> + spin_unlock_irqrestore(&adapter->int_lock, flags);
> + }
> +}
> +
> +/*
> + * SDIO interrupt handler.
> + *
> + * This function reads the interrupt status from firmware and handles
> + * the interrupt in current thread (ksdioirqd) right away.
> + */
> +static void
> +mwifiex_sdio_interrupt(struct sdio_func *func)
> +{
> + struct mwifiex_adapter *adapter;
> + struct sdio_mmc_card *card;
> +
> + card = sdio_get_drvdata(func);
> + if (!card || !card->adapter) {
> + pr_debug("int: func=%p card=%p adapter=%p\n",
> + func, card, card ? card->adapter : NULL);
> + return;
> + }
> + adapter = card->adapter;
> +
> + if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP)
> + adapter->ps_state = PS_STATE_AWAKE;
> +
> + mwifiex_interrupt_status(adapter);
> + mwifiex_main_process(adapter);
> +}
> +
> +/*
> * This function enables the host interrupt.
> *
> * The host interrupt enable mask is written to the card
> @@ -963,65 +1019,6 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
> }
>
> /*
> - * This function reads the interrupt status from card.
> - */
> -static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
> -{
> - struct sdio_mmc_card *card = adapter->card;
> - u8 sdio_ireg;
> - unsigned long flags;
> -
> - if (mwifiex_read_data_sync(adapter, card->mp_regs,
> - card->reg->max_mp_regs,
> - REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0)) {
> - dev_err(adapter->dev, "read mp_regs failed\n");
> - return;
> - }
> -
> - sdio_ireg = card->mp_regs[HOST_INTSTATUS_REG];
> - if (sdio_ireg) {
> - /*
> - * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
> - * For SDIO new mode CMD port interrupts
> - * DN_LD_CMD_PORT_HOST_INT_STATUS and/or
> - * UP_LD_CMD_PORT_HOST_INT_STATUS
> - * Clear the interrupt status register
> - */
> - dev_dbg(adapter->dev, "int: sdio_ireg = %#x\n", sdio_ireg);
> - spin_lock_irqsave(&adapter->int_lock, flags);
> - adapter->int_status |= sdio_ireg;
> - spin_unlock_irqrestore(&adapter->int_lock, flags);
> - }
> -}
> -
> -/*
> - * SDIO interrupt handler.
> - *
> - * This function reads the interrupt status from firmware and handles
> - * the interrupt in current thread (ksdioirqd) right away.
> - */
> -static void
> -mwifiex_sdio_interrupt(struct sdio_func *func)
> -{
> - struct mwifiex_adapter *adapter;
> - struct sdio_mmc_card *card;
> -
> - card = sdio_get_drvdata(func);
> - if (!card || !card->adapter) {
> - pr_debug("int: func=%p card=%p adapter=%p\n",
> - func, card, card ? card->adapter : NULL);
> - return;
> - }
> - adapter = card->adapter;
> -
> - if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP)
> - adapter->ps_state = PS_STATE_AWAKE;
> -
> - mwifiex_interrupt_status(adapter);
> - mwifiex_main_process(adapter);
> -}
> -
> -/*
> * This function decodes a received packet.
> *
> * Based on the type, the packet is treated as either a data, or
> --
> 1.8.2.3
>
>

--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.

2013-07-23 02:19:13

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 10/21] mwifiex: add PCIe shutdown handler to avoid system hang on reboot

From: Amitkumar Karwar <[email protected]>

If reboot command is issued when device is in connected state,
system hangs while booting. This issue is fixed by doing cleanup
in shutdown handler.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/pcie.c | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 4a57eb4..dce6486 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -235,6 +235,14 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
kfree(card);
}

+static void mwifiex_pcie_shutdown(struct pci_dev *pdev)
+{
+ user_rmmod = 1;
+ mwifiex_pcie_remove(pdev);
+
+ return;
+}
+
static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = {
{
PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
@@ -268,6 +276,7 @@ static struct pci_driver __refdata mwifiex_pcie = {
.pm = &mwifiex_pcie_pm_ops,
},
#endif
+ .shutdown = mwifiex_pcie_shutdown,
};

/*
--
1.8.2.3


2013-07-23 02:18:42

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 01/21] mwifiex: remove stop_net_dev_queue operation in AP forwarding

From: Huawei Yang <[email protected]>

Under uAP mode mwifiex may stop all net tx queues on forwarding
packets. This may stop some tx queues and they never have chance
to be waked up. There is also no need to check tx_pending and
stop queues here. Because local host has such kind of check when
transmitting packets and it's not proper to have forwarding affect
local transmitting.

Signed-off-by: Huawei Yang <[email protected]>
Reviewed-by: Avinash Patil <[email protected]>
Acked-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/uap_txrx.c | 4 ----
1 file changed, 4 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c
index a018e42..11df2b2 100644
--- a/drivers/net/wireless/mwifiex/uap_txrx.c
+++ b/drivers/net/wireless/mwifiex/uap_txrx.c
@@ -95,10 +95,6 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
atomic_inc(&adapter->tx_pending);
atomic_inc(&adapter->pending_bridged_pkts);

- if ((atomic_read(&adapter->tx_pending) >= MAX_TX_PENDING)) {
- mwifiex_set_trans_start(priv->netdev);
- mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
- }
return;
}

--
1.8.2.3


2013-07-23 02:18:51

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 08/21] mwifiex: support to send deauth for P2P client

From: Stone Piao <[email protected]>

During P2P handshake, P2P client needs to send deauth after EAPOL
FAILURE to GO. We need add bss mode for P2P client when handle deauth
request.

Without this change, deauth can not be sent out from P2P client side.

Signed-off-by: Stone Piao <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/join.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 1c8a771..ba043ca 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -1425,6 +1425,7 @@ int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)

switch (priv->bss_mode) {
case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_P2P_CLIENT:
return mwifiex_deauthenticate_infra(priv, mac);
case NL80211_IFTYPE_ADHOC:
return mwifiex_send_cmd_sync(priv,
--
1.8.2.3


2013-07-23 02:19:17

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 13/21] mwifiex: move if_ops.cleanup_if() call

From: Amitkumar Karwar <[email protected]>

As if_ops.init_if() is called in mwifiex_register(),
corresponding cleanup routine should be called in
mwifiex_unregister().

Currently it's there in mwifiex_adapter_cleanup(), hence
interface specific cleanup is not performed if driver
initialization is failed.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/init.c | 3 ---
drivers/net/wireless/mwifiex/main.c | 3 +++
2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 8ff5d7b..2cda7ee 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -394,9 +394,6 @@ mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)

dev_dbg(adapter->dev, "info: free scan table\n");

- if (adapter->if_ops.cleanup_if)
- adapter->if_ops.cleanup_if(adapter);
-
if (adapter->sleep_cfm)
dev_kfree_skb_any(adapter->sleep_cfm);
}
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 8217368..e64c369 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -191,6 +191,9 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
{
s32 i;

+ if (adapter->if_ops.cleanup_if)
+ adapter->if_ops.cleanup_if(adapter);
+
del_timer(&adapter->cmd_timer);

/* Free private structures */
--
1.8.2.3


2013-07-24 15:30:12

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 18/21] mwifiex: handle driver initialization error paths

This one didn't apply on the current wireless-next tree. Can you
fix it up?

On Mon, Jul 22, 2013 at 07:17:55PM -0700, Bing Zhao wrote:
> From: Amitkumar Karwar <[email protected]>
>
> mwifiex_fw_dpc() asynchronously takes care of firmware download
> and initialization. Currently the error paths in mwifiex_fw_dpc()
> are not handled. So if wrong firmware is downloaded, required
> cleanup work is not performed. memory is leaked and workqueue
> remains unterminated in this case.
>
> mwifiex_terminate_workqueue() is moved to avoid forward
> declaration.
>
> Signed-off-by: Amitkumar Karwar <[email protected]>
> Signed-off-by: Bing Zhao <[email protected]>
> ---
> drivers/net/wireless/mwifiex/main.c | 83 ++++++++++++++++++++++++-------------
> drivers/net/wireless/mwifiex/main.h | 1 +
> 2 files changed, 56 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
> index e64c369..5644c7f 100644
> --- a/drivers/net/wireless/mwifiex/main.c
> +++ b/drivers/net/wireless/mwifiex/main.c
> @@ -390,6 +390,17 @@ static void mwifiex_free_adapter(struct mwifiex_adapter *adapter)
> }
>
> /*
> + * This function cancels all works in the queue and destroys
> + * the main workqueue.
> + */
> +static void mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
> +{
> + flush_workqueue(adapter->workqueue);
> + destroy_workqueue(adapter->workqueue);
> + adapter->workqueue = NULL;
> +}
> +
> +/*
> * This function gets firmware and initializes it.
> *
> * The main initialization steps followed are -
> @@ -398,7 +409,7 @@ static void mwifiex_free_adapter(struct mwifiex_adapter *adapter)
> */
> static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
> {
> - int ret;
> + int ret, i;
> char fmt[64];
> struct mwifiex_private *priv;
> struct mwifiex_adapter *adapter = context;
> @@ -407,7 +418,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
> if (!firmware) {
> dev_err(adapter->dev,
> "Failed to get firmware %s\n", adapter->fw_name);
> - goto done;
> + goto err_dnld_fw;
> }
>
> memset(&fw, 0, sizeof(struct mwifiex_fw_image));
> @@ -420,7 +431,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
> else
> ret = mwifiex_dnld_fw(adapter, &fw);
> if (ret == -1)
> - goto done;
> + goto err_dnld_fw;
>
> dev_notice(adapter->dev, "WLAN FW is active\n");
>
> @@ -432,13 +443,15 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
> }
>
> /* enable host interrupt after fw dnld is successful */
> - if (adapter->if_ops.enable_int)
> - adapter->if_ops.enable_int(adapter);
> + if (adapter->if_ops.enable_int) {
> + if (adapter->if_ops.enable_int(adapter))
> + goto err_dnld_fw;
> + }
>
> adapter->init_wait_q_woken = false;
> ret = mwifiex_init_fw(adapter);
> if (ret == -1) {
> - goto done;
> + goto err_init_fw;
> } else if (!ret) {
> adapter->hw_status = MWIFIEX_HW_STATUS_READY;
> goto done;
> @@ -447,12 +460,12 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
> wait_event_interruptible(adapter->init_wait_q,
> adapter->init_wait_q_woken);
> if (adapter->hw_status != MWIFIEX_HW_STATUS_READY)
> - goto done;
> + goto err_init_fw;
>
> priv = adapter->priv[MWIFIEX_BSS_ROLE_STA];
> if (mwifiex_register_cfg80211(adapter)) {
> dev_err(adapter->dev, "cannot register with cfg80211\n");
> - goto err_init_fw;
> + goto err_register_cfg80211;
> }
>
> rtnl_lock();
> @@ -483,13 +496,39 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
> goto done;
>
> err_add_intf:
> - mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
> + for (i = 0; i < adapter->priv_num; i++) {
> + priv = adapter->priv[i];
> +
> + if (!priv)
> + continue;
> +
> + if (priv->wdev && priv->netdev)
> + mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
> + }
> rtnl_unlock();
> +err_register_cfg80211:
> + wiphy_unregister(adapter->wiphy);
> + wiphy_free(adapter->wiphy);
> err_init_fw:
> if (adapter->if_ops.disable_int)
> adapter->if_ops.disable_int(adapter);
> +err_dnld_fw:
> pr_debug("info: %s: unregister device\n", __func__);
> - adapter->if_ops.unregister_dev(adapter);
> + if (adapter->if_ops.unregister_dev)
> + adapter->if_ops.unregister_dev(adapter);
> +
> + if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) ||
> + (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) {
> + pr_debug("info: %s: shutdown mwifiex\n", __func__);
> + adapter->init_wait_q_woken = false;
> +
> + if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
> + wait_event_interruptible(adapter->init_wait_q,
> + adapter->init_wait_q_woken);
> + }
> + adapter->surprise_removed = true;
> + mwifiex_terminate_workqueue(adapter);
> + mwifiex_free_adapter(adapter);
> done:
> if (adapter->cal_data) {
> release_firmware(adapter->cal_data);
> @@ -497,6 +536,7 @@ done:
> }
> release_firmware(adapter->firmware);
> complete(&adapter->fw_load);
> + up(adapter->card_sem);
> return;
> }
>
> @@ -807,18 +847,6 @@ static void mwifiex_main_work_queue(struct work_struct *work)
> }
>
> /*
> - * This function cancels all works in the queue and destroys
> - * the main workqueue.
> - */
> -static void
> -mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
> -{
> - flush_workqueue(adapter->workqueue);
> - destroy_workqueue(adapter->workqueue);
> - adapter->workqueue = NULL;
> -}
> -
> -/*
> * This function adds the card.
> *
> * This function follows the following major steps to set up the device -
> @@ -846,6 +874,7 @@ mwifiex_add_card(void *card, struct semaphore *sem,
> }
>
> adapter->iface_type = iface_type;
> + adapter->card_sem = sem;
>
> adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
> adapter->surprise_removed = false;
> @@ -876,17 +905,12 @@ mwifiex_add_card(void *card, struct semaphore *sem,
> goto err_init_fw;
> }
>
> - up(sem);
> return 0;
>
> err_init_fw:
> pr_debug("info: %s: unregister device\n", __func__);
> if (adapter->if_ops.unregister_dev)
> adapter->if_ops.unregister_dev(adapter);
> -err_registerdev:
> - adapter->surprise_removed = true;
> - mwifiex_terminate_workqueue(adapter);
> -err_kmalloc:
> if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) ||
> (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) {
> pr_debug("info: %s: shutdown mwifiex\n", __func__);
> @@ -896,7 +920,10 @@ err_kmalloc:
> wait_event_interruptible(adapter->init_wait_q,
> adapter->init_wait_q_woken);
> }
> -
> +err_registerdev:
> + adapter->surprise_removed = true;
> + mwifiex_terminate_workqueue(adapter);
> +err_kmalloc:
> mwifiex_free_adapter(adapter);
>
> err_init_sw:
> diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
> index bb28d3d..9ee3b1b 100644
> --- a/drivers/net/wireless/mwifiex/main.h
> +++ b/drivers/net/wireless/mwifiex/main.h
> @@ -749,6 +749,7 @@ struct mwifiex_adapter {
>
> atomic_t is_tx_received;
> atomic_t pending_bridged_pkts;
> + struct semaphore *card_sem;
> };
>
> int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
> --
> 1.8.2.3
>
>

--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.

2013-07-23 02:18:59

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 14/21] mwifiex: add unregister_dev handler for usb interface

From: Amitkumar Karwar <[email protected]>

Clear the data pointer stored in USB interface structure in
this handler. This helps to return from mwifiex_usb_disconnect()
if driver deinitialization is already performed while handling
an error path for mwifiex_usb_probe().

USB8797 card gets enumerated twice. First enumeration is for
firmware download and second enumeration expects firmware
initialization. mwifiex_usb_probe() always takes care of
deinitialization for first enumeration after firmware download.

Also, this change matches our handling for SDIO and PCIe
interfaces.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/usb.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index f90fe21..fca98b5 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -786,6 +786,13 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
return 0;
}

+static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
+{
+ struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;
+
+ usb_set_intfdata(card->intf, NULL);
+}
+
static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
struct mwifiex_fw_image *fw)
{
@@ -978,6 +985,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)

static struct mwifiex_if_ops usb_ops = {
.register_dev = mwifiex_register_dev,
+ .unregister_dev = mwifiex_unregister_dev,
.wakeup = mwifiex_pm_wakeup_card,
.wakeup_complete = mwifiex_pm_wakeup_card_complete,

--
1.8.2.3


2013-07-23 02:18:47

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 03/21] mwifiex: maintain outstanding packet count for RA list instead of packet size

From: Avinash Patil <[email protected]>

Maintain total outstanding packet count for RA list instead of total
outstanding size as packet count metric seems more reasonable for
checking threshold etc.

Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/11n_aggr.c | 4 ++--
drivers/net/wireless/mwifiex/main.h | 2 +-
drivers/net/wireless/mwifiex/wmm.c | 8 ++++----
3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index a78e065..8f9f542 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -189,7 +189,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,

skb_src = skb_dequeue(&pra_list->skb_head);

- pra_list->total_pkts_size -= skb_src->len;
+ pra_list->total_pkt_count--;

atomic_dec(&priv->wmm.tx_pkts_queued);

@@ -268,7 +268,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,

skb_queue_tail(&pra_list->skb_head, skb_aggr);

- pra_list->total_pkts_size += skb_aggr->len;
+ pra_list->total_pkt_count++;

atomic_inc(&priv->wmm.tx_pkts_queued);

diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 884b42b..a3036d1 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -204,11 +204,11 @@ struct mwifiex_ra_list_tbl {
struct list_head list;
struct sk_buff_head skb_head;
u8 ra[ETH_ALEN];
- u32 total_pkts_size;
u32 is_11n_enabled;
u16 max_amsdu;
u16 ba_pkt_count;
u8 ba_packet_thr;
+ u16 total_pkt_count;
};

struct mwifiex_tid_tbl {
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 9c1eeee..2e8f9cd 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -120,7 +120,7 @@ mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra)

memcpy(ra_list->ra, ra, ETH_ALEN);

- ra_list->total_pkts_size = 0;
+ ra_list->total_pkt_count = 0;

dev_dbg(adapter->dev, "info: allocated ra_list %p\n", ra_list);

@@ -679,8 +679,8 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,

skb_queue_tail(&ra_list->skb_head, skb);

- ra_list->total_pkts_size += skb->len;
ra_list->ba_pkt_count++;
+ ra_list->total_pkt_count++;

if (atomic_read(&priv->wmm.highest_queued_prio) <
tos_to_tid_inv[tid_down])
@@ -1037,7 +1037,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
tx_info = MWIFIEX_SKB_TXCB(skb);
dev_dbg(adapter->dev, "data: dequeuing the packet %p %p\n", ptr, skb);

- ptr->total_pkts_size -= skb->len;
+ ptr->total_pkt_count--;

if (!skb_queue_empty(&ptr->skb_head))
skb_next = skb_peek(&ptr->skb_head);
@@ -1062,7 +1062,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,

skb_queue_tail(&ptr->skb_head, skb);

- ptr->total_pkts_size += skb->len;
+ ptr->total_pkt_count++;
ptr->ba_pkt_count++;
tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
--
1.8.2.3


2013-07-23 02:19:27

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 19/21] mwifiex: code rearrangement in sdio.c

From: Amitkumar Karwar <[email protected]>

Some function definitions are moved to appropriate place
to avoid forward declarations.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/sdio.c | 211 ++++++++++++++++++------------------
1 file changed, 104 insertions(+), 107 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index c32a735..1eb5efa1 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -50,9 +50,6 @@ static struct mwifiex_if_ops sdio_ops;

static struct semaphore add_remove_card_sem;

-static int mwifiex_sdio_resume(struct device *dev);
-static void mwifiex_sdio_interrupt(struct sdio_func *func);
-
/*
* SDIO probe.
*
@@ -113,6 +110,51 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
}

/*
+ * SDIO resume.
+ *
+ * Kernel needs to suspend all functions separately. Therefore all
+ * registered functions must have drivers with suspend and resume
+ * methods. Failing that the kernel simply removes the whole card.
+ *
+ * If already not resumed, this function turns on the traffic and
+ * sends a host sleep cancel request to the firmware.
+ */
+static int mwifiex_sdio_resume(struct device *dev)
+{
+ struct sdio_func *func = dev_to_sdio_func(dev);
+ struct sdio_mmc_card *card;
+ struct mwifiex_adapter *adapter;
+ mmc_pm_flag_t pm_flag = 0;
+
+ if (func) {
+ pm_flag = sdio_get_host_pm_caps(func);
+ card = sdio_get_drvdata(func);
+ if (!card || !card->adapter) {
+ pr_err("resume: invalid card or adapter\n");
+ return 0;
+ }
+ } else {
+ pr_err("resume: sdio_func is not specified\n");
+ return 0;
+ }
+
+ adapter = card->adapter;
+
+ if (!adapter->is_suspended) {
+ dev_warn(adapter->dev, "device already resumed\n");
+ return 0;
+ }
+
+ adapter->is_suspended = false;
+
+ /* Disable Host Sleep */
+ mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
+ MWIFIEX_ASYNC_CMD);
+
+ return 0;
+}
+
+/*
* SDIO remove.
*
* This function removes the interface and frees up the card structure.
@@ -212,51 +254,6 @@ static int mwifiex_sdio_suspend(struct device *dev)
return ret;
}

-/*
- * SDIO resume.
- *
- * Kernel needs to suspend all functions separately. Therefore all
- * registered functions must have drivers with suspend and resume
- * methods. Failing that the kernel simply removes the whole card.
- *
- * If already not resumed, this function turns on the traffic and
- * sends a host sleep cancel request to the firmware.
- */
-static int mwifiex_sdio_resume(struct device *dev)
-{
- struct sdio_func *func = dev_to_sdio_func(dev);
- struct sdio_mmc_card *card;
- struct mwifiex_adapter *adapter;
- mmc_pm_flag_t pm_flag = 0;
-
- if (func) {
- pm_flag = sdio_get_host_pm_caps(func);
- card = sdio_get_drvdata(func);
- if (!card || !card->adapter) {
- pr_err("resume: invalid card or adapter\n");
- return 0;
- }
- } else {
- pr_err("resume: sdio_func is not specified\n");
- return 0;
- }
-
- adapter = card->adapter;
-
- if (!adapter->is_suspended) {
- dev_warn(adapter->dev, "device already resumed\n");
- return 0;
- }
-
- adapter->is_suspended = false;
-
- /* Disable Host Sleep */
- mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
- MWIFIEX_ASYNC_CMD);
-
- return 0;
-}
-
/* Device ID for SD8786 */
#define SDIO_DEVICE_ID_MARVELL_8786 (0x9116)
/* Device ID for SD8787 */
@@ -707,6 +704,65 @@ static void mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
}

/*
+ * This function reads the interrupt status from card.
+ */
+static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
+{
+ struct sdio_mmc_card *card = adapter->card;
+ u8 sdio_ireg;
+ unsigned long flags;
+
+ if (mwifiex_read_data_sync(adapter, card->mp_regs,
+ card->reg->max_mp_regs,
+ REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0)) {
+ dev_err(adapter->dev, "read mp_regs failed\n");
+ return;
+ }
+
+ sdio_ireg = card->mp_regs[HOST_INTSTATUS_REG];
+ if (sdio_ireg) {
+ /*
+ * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
+ * For SDIO new mode CMD port interrupts
+ * DN_LD_CMD_PORT_HOST_INT_STATUS and/or
+ * UP_LD_CMD_PORT_HOST_INT_STATUS
+ * Clear the interrupt status register
+ */
+ dev_dbg(adapter->dev, "int: sdio_ireg = %#x\n", sdio_ireg);
+ spin_lock_irqsave(&adapter->int_lock, flags);
+ adapter->int_status |= sdio_ireg;
+ spin_unlock_irqrestore(&adapter->int_lock, flags);
+ }
+}
+
+/*
+ * SDIO interrupt handler.
+ *
+ * This function reads the interrupt status from firmware and handles
+ * the interrupt in current thread (ksdioirqd) right away.
+ */
+static void
+mwifiex_sdio_interrupt(struct sdio_func *func)
+{
+ struct mwifiex_adapter *adapter;
+ struct sdio_mmc_card *card;
+
+ card = sdio_get_drvdata(func);
+ if (!card || !card->adapter) {
+ pr_debug("int: func=%p card=%p adapter=%p\n",
+ func, card, card ? card->adapter : NULL);
+ return;
+ }
+ adapter = card->adapter;
+
+ if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP)
+ adapter->ps_state = PS_STATE_AWAKE;
+
+ mwifiex_interrupt_status(adapter);
+ mwifiex_main_process(adapter);
+}
+
+/*
* This function enables the host interrupt.
*
* The host interrupt enable mask is written to the card
@@ -963,65 +1019,6 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
}

/*
- * This function reads the interrupt status from card.
- */
-static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
-{
- struct sdio_mmc_card *card = adapter->card;
- u8 sdio_ireg;
- unsigned long flags;
-
- if (mwifiex_read_data_sync(adapter, card->mp_regs,
- card->reg->max_mp_regs,
- REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0)) {
- dev_err(adapter->dev, "read mp_regs failed\n");
- return;
- }
-
- sdio_ireg = card->mp_regs[HOST_INTSTATUS_REG];
- if (sdio_ireg) {
- /*
- * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
- * For SDIO new mode CMD port interrupts
- * DN_LD_CMD_PORT_HOST_INT_STATUS and/or
- * UP_LD_CMD_PORT_HOST_INT_STATUS
- * Clear the interrupt status register
- */
- dev_dbg(adapter->dev, "int: sdio_ireg = %#x\n", sdio_ireg);
- spin_lock_irqsave(&adapter->int_lock, flags);
- adapter->int_status |= sdio_ireg;
- spin_unlock_irqrestore(&adapter->int_lock, flags);
- }
-}
-
-/*
- * SDIO interrupt handler.
- *
- * This function reads the interrupt status from firmware and handles
- * the interrupt in current thread (ksdioirqd) right away.
- */
-static void
-mwifiex_sdio_interrupt(struct sdio_func *func)
-{
- struct mwifiex_adapter *adapter;
- struct sdio_mmc_card *card;
-
- card = sdio_get_drvdata(func);
- if (!card || !card->adapter) {
- pr_debug("int: func=%p card=%p adapter=%p\n",
- func, card, card ? card->adapter : NULL);
- return;
- }
- adapter = card->adapter;
-
- if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP)
- adapter->ps_state = PS_STATE_AWAKE;
-
- mwifiex_interrupt_status(adapter);
- mwifiex_main_process(adapter);
-}
-
-/*
* This function decodes a received packet.
*
* Based on the type, the packet is treated as either a data, or
--
1.8.2.3


2013-07-23 02:18:54

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 12/21] mwifiex: remove unnecessary del_timer(cmd_timer)

From: Amitkumar Karwar <[email protected]>

It is already there in mwifiex_unregister(). So unnecessary
call in mwifiex_adapter_cleanup() is removed in this patch.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/init.c | 2 --
1 file changed, 2 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 787cff8..8ff5d7b 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -392,8 +392,6 @@ mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
dev_dbg(adapter->dev, "info: free cmd buffer\n");
mwifiex_free_cmd_buffer(adapter);

- del_timer(&adapter->cmd_timer);
-
dev_dbg(adapter->dev, "info: free scan table\n");

if (adapter->if_ops.cleanup_if)
--
1.8.2.3


2013-07-23 02:19:02

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 21/21] mwifiex: modify mwifiex_ap_sta_limits to advertise support for P2P

From: Avinash Patil <[email protected]>

We support maximum simultaneous 2 non-AP station interfaces and
they can assume role of Station/P2P client/P2P GO.
Advertise this support to cfg80211 so that concurrent P2P/STA
operation is possible.

Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/cfg80211.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index dbdd3b2..cc334d5 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -25,7 +25,9 @@ module_param(reg_alpha2, charp, 0);

static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = {
{
- .max = 2, .types = BIT(NL80211_IFTYPE_STATION),
+ .max = 2, .types = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_P2P_GO) |
+ BIT(NL80211_IFTYPE_P2P_CLIENT),
},
{
.max = 1, .types = BIT(NL80211_IFTYPE_AP),
--
1.8.2.3


2013-07-24 19:15:11

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 18/21] mwifiex: handle driver initialization error paths

On Wed, Jul 24, 2013 at 11:48:25AM -0700, Bing Zhao wrote:
> Hi John,
>
> > This one didn't apply on the current wireless-next tree. Can you
> > fix it up?
>
> 18/21 and 19/21 depend on this patch:
>
> commit 232fde062e0a2cc52e8e18a50cda361b4ba88f34
> Author: Daniel Drake <[email protected]>
> Date: Sat Jul 13 10:57:10 2013 -0400
>
> mwifiex: fix IRQ enable/disable
>
> which is in wireless.git and wireless-testing.git currently.
>
>
> We can apply 18 and 19 later after commit 232fde0 is merged back to wireless-next.git.
> (I will send you a reminder to merge these two patches once commit 232fde0 is in -next tree.)
>
> Thanks,
> Bing

OK, thanks for checking!

--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.

2013-07-23 02:18:48

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 04/21] mwifiex: delete AP TX queues when bridged packets reach threshold

From: Avinash Patil <[email protected]>

Delete packets from TX queues for this mwifiex_private structure
when bridged packet count reaches maximum threshold. Bridged packets
from each RA List are deleted till they fall to low threshold of 128.

Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/decl.h | 3 +-
drivers/net/wireless/mwifiex/init.c | 1 +
drivers/net/wireless/mwifiex/main.h | 1 +
drivers/net/wireless/mwifiex/uap_txrx.c | 66 ++++++++++++++++++++++++++++++++-
4 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 94cc09d..a599347 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -75,7 +75,8 @@
#define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0)
#define MWIFIEX_BUF_FLAG_BRIDGED_PKT BIT(1)

-#define MWIFIEX_BRIDGED_PKTS_THRESHOLD 1024
+#define MWIFIEX_BRIDGED_PKTS_THR_HIGH 1024
+#define MWIFIEX_BRIDGED_PKTS_THR_LOW 128

enum mwifiex_bss_type {
MWIFIEX_BSS_TYPE_STA = 0,
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 2cf8b96..09c4b76 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -135,6 +135,7 @@ int mwifiex_init_priv(struct mwifiex_private *priv)

priv->csa_chan = 0;
priv->csa_expire_time = 0;
+ priv->del_list_idx = 0;

return mwifiex_add_bss_prio_tbl(priv);
}
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index a3036d1..bb28d3d 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -515,6 +515,7 @@ struct mwifiex_private {
bool scan_aborting;
u8 csa_chan;
unsigned long csa_expire_time;
+ u8 del_list_idx;
};

enum mwifiex_ba_status {
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c
index 11df2b2..1cfe5a7 100644
--- a/drivers/net/wireless/mwifiex/uap_txrx.c
+++ b/drivers/net/wireless/mwifiex/uap_txrx.c
@@ -24,6 +24,69 @@
#include "11n_aggr.h"
#include "11n_rxreorder.h"

+/* This function checks if particular RA list has packets more than low bridge
+ * packet threshold and then deletes packet from this RA list.
+ * Function deletes packets from such RA list and returns true. If no such list
+ * is found, false is returned.
+ */
+static bool
+mwifiex_uap_del_tx_pkts_in_ralist(struct mwifiex_private *priv,
+ struct list_head *ra_list_head)
+{
+ struct mwifiex_ra_list_tbl *ra_list;
+ struct sk_buff *skb, *tmp;
+ bool pkt_deleted = false;
+ struct mwifiex_txinfo *tx_info;
+ struct mwifiex_adapter *adapter = priv->adapter;
+
+ list_for_each_entry(ra_list, ra_list_head, list) {
+ if (skb_queue_empty(&ra_list->skb_head))
+ continue;
+
+ skb_queue_walk_safe(&ra_list->skb_head, skb, tmp) {
+ tx_info = MWIFIEX_SKB_TXCB(skb);
+ if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) {
+ __skb_unlink(skb, &ra_list->skb_head);
+ mwifiex_write_data_complete(adapter, skb, 0,
+ -1);
+ atomic_dec(&priv->wmm.tx_pkts_queued);
+ pkt_deleted = true;
+ }
+ if ((atomic_read(&adapter->pending_bridged_pkts) <=
+ MWIFIEX_BRIDGED_PKTS_THR_LOW))
+ break;
+ }
+ }
+
+ return pkt_deleted;
+}
+
+/* This function deletes packets from particular RA List. RA list index
+ * from which packets are deleted is preserved so that packets from next RA
+ * list are deleted upon subsequent call thus maintaining fairness.
+ */
+static void mwifiex_uap_cleanup_tx_queues(struct mwifiex_private *priv)
+{
+ unsigned long flags;
+ struct list_head *ra_list;
+ int i;
+
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
+
+ for (i = 0; i < MAX_NUM_TID; i++, priv->del_list_idx++) {
+ 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)) {
+ priv->del_list_idx++;
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+}
+
+
static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
struct sk_buff *skb)
{
@@ -40,10 +103,11 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset);

if ((atomic_read(&adapter->pending_bridged_pkts) >=
- MWIFIEX_BRIDGED_PKTS_THRESHOLD)) {
+ MWIFIEX_BRIDGED_PKTS_THR_HIGH)) {
dev_err(priv->adapter->dev,
"Tx: Bridge packet limit reached. Drop packet!\n");
kfree_skb(skb);
+ mwifiex_uap_cleanup_tx_queues(priv);
return;
}

--
1.8.2.3


2013-07-23 02:18:53

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 09/21] mwifiex: correct max IE length check for WPS IE

From: Avinash Patil <[email protected]>

This patch is bug fix for an invalid boundry check for WPS IE.
We should check max IE length against defined macro; instead we were
checking it against size of pointer. Fix it.
Also move IE length check before allocation of memory.

Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/sta_ioctl.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 206c3e0..c071ce9 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -797,15 +797,16 @@ static int mwifiex_set_wps_ie(struct mwifiex_private *priv,
u8 *ie_data_ptr, u16 ie_len)
{
if (ie_len) {
- priv->wps_ie = kzalloc(MWIFIEX_MAX_VSIE_LEN, GFP_KERNEL);
- if (!priv->wps_ie)
- return -ENOMEM;
- if (ie_len > sizeof(priv->wps_ie)) {
+ if (ie_len > MWIFIEX_MAX_VSIE_LEN) {
dev_dbg(priv->adapter->dev,
"info: failed to copy WPS IE, too big\n");
- kfree(priv->wps_ie);
return -1;
}
+
+ priv->wps_ie = kzalloc(MWIFIEX_MAX_VSIE_LEN, GFP_KERNEL);
+ if (!priv->wps_ie)
+ return -ENOMEM;
+
memcpy(priv->wps_ie, ie_data_ptr, ie_len);
priv->wps_ie_len = ie_len;
dev_dbg(priv->adapter->dev, "cmd: Set wps_ie_len=%d IE=%#x\n",
--
1.8.2.3


2013-07-23 02:18:55

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 11/21] mwifiex: move del_timer_sync(scan_delay_timer) call to fix memleak

From: Amitkumar Karwar <[email protected]>

Currently it is in mwifiex_adapter_cleanup() which doesn't get
called if driver initialization is failed causing memory leak.

scan_delay_timer is initialized in mwifiex_register(), so it
should be deleted in mwifiex_unregister(). Hence it has been
moved to appropriate place.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/init.c | 7 -------
drivers/net/wireless/mwifiex/main.c | 1 +
2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 09c4b76..787cff8 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -378,18 +378,11 @@ static void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
static void
mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
{
- int i;
-
if (!adapter) {
pr_err("%s: adapter is NULL\n", __func__);
return;
}

- for (i = 0; i < adapter->priv_num; i++) {
- if (adapter->priv[i])
- del_timer_sync(&adapter->priv[i]->scan_delay_timer);
- }
-
mwifiex_cancel_all_pending_cmd(adapter);

/* Free lock variables */
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 1753431..8217368 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -197,6 +197,7 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
for (i = 0; i < adapter->priv_num; i++) {
if (adapter->priv[i]) {
mwifiex_free_curr_bcn(adapter->priv[i]);
+ del_timer_sync(&adapter->priv[i]->scan_delay_timer);
kfree(adapter->priv[i]);
}
}
--
1.8.2.3


2013-07-23 02:18:50

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 06/21] mwifiex: discard deauth and disassoc event during WPS session

From: Stone Piao <[email protected]>

Some GO will send deauth or disassoc packet at the end of WPS
handshake, which causes P2P connecion failure due to the race
condition between event path and data path.

Signed-off-by: Stone Piao <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/sta_event.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index ea265ec..8b05752 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -201,6 +201,11 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)

case EVENT_DEAUTHENTICATED:
dev_dbg(adapter->dev, "event: Deauthenticated\n");
+ if (priv->wps.session_enable) {
+ dev_dbg(adapter->dev,
+ "info: receive deauth event in wps session\n");
+ break;
+ }
adapter->dbg.num_event_deauth++;
if (priv->media_connected) {
reason_code =
@@ -211,6 +216,11 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)

case EVENT_DISASSOCIATED:
dev_dbg(adapter->dev, "event: Disassociated\n");
+ if (priv->wps.session_enable) {
+ dev_dbg(adapter->dev,
+ "info: receive disassoc event in wps session\n");
+ break;
+ }
adapter->dbg.num_event_disassoc++;
if (priv->media_connected) {
reason_code =
--
1.8.2.3


2013-07-23 02:19:04

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 07/21] mwifiex: skip registering mgmt frame that has already registered

From: Stone Piao <[email protected]>

Before sending command to firmware, we need to check the frame type.
We skip registering the mgmt frame that has already been registered.

Signed-off-by: Stone Piao <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/cfg80211.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index d824fee..dbdd3b2 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -240,16 +240,20 @@ mwifiex_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
u16 frame_type, bool reg)
{
struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
+ u32 mask;

if (reg)
- priv->mgmt_frame_mask |= BIT(frame_type >> 4);
+ mask = priv->mgmt_frame_mask | BIT(frame_type >> 4);
else
- priv->mgmt_frame_mask &= ~BIT(frame_type >> 4);
+ mask = priv->mgmt_frame_mask & ~BIT(frame_type >> 4);

- mwifiex_send_cmd_async(priv, HostCmd_CMD_MGMT_FRAME_REG,
- HostCmd_ACT_GEN_SET, 0, &priv->mgmt_frame_mask);
-
- wiphy_dbg(wiphy, "info: mgmt frame registered\n");
+ if (mask != priv->mgmt_frame_mask) {
+ priv->mgmt_frame_mask = mask;
+ mwifiex_send_cmd_async(priv, HostCmd_CMD_MGMT_FRAME_REG,
+ HostCmd_ACT_GEN_SET, 0,
+ &priv->mgmt_frame_mask);
+ wiphy_dbg(wiphy, "info: mgmt frame registered\n");
+ }
}

/*
--
1.8.2.3


2013-07-23 02:18:35

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 05/21] mwifiex: add tx info to skb when forming mgmt frame

From: Huawei Yang <[email protected]>

In function 'mwifiex_write_data_complete' it need tx info to find
the mwifiex_private to updates statistics and wake up tx queues.
Or we may trigger tx queues timeout when transmitting lots of mgmt
frames.

Signed-off-by: Huawei Yang <[email protected]>
Signed-off-by: Stone Piao <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/cfg80211.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index ef5fa89..d824fee 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -189,6 +189,7 @@ mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
struct sk_buff *skb;
u16 pkt_len;
const struct ieee80211_mgmt *mgmt;
+ struct mwifiex_txinfo *tx_info;
struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);

if (!buf || !len) {
@@ -216,6 +217,10 @@ mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
return -ENOMEM;
}

+ tx_info = MWIFIEX_SKB_TXCB(skb);
+ tx_info->bss_num = priv->bss_num;
+ tx_info->bss_type = priv->bss_type;
+
mwifiex_form_mgmt_frame(skb, buf, len);
mwifiex_queue_tx_pkt(priv, skb);

--
1.8.2.3


2013-07-23 02:19:21

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 20/21] mwifiex: remove duplicate structure host_cmd_tlv

From: Amitkumar Karwar <[email protected]>

We already have 'struct mwifiex_ie_types_header' with same
definition. Hence host_cmd_tlv is removed in this patch.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/fw.h | 41 +++++------
drivers/net/wireless/mwifiex/ie.c | 2 +-
drivers/net/wireless/mwifiex/sta_cmd.c | 5 +-
drivers/net/wireless/mwifiex/uap_cmd.c | 130 +++++++++++++++++----------------
4 files changed, 91 insertions(+), 87 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 99c2729..c0dfc4d 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -1366,11 +1366,6 @@ struct host_cmd_ds_802_11_eeprom_access {
u8 value;
} __packed;

-struct host_cmd_tlv {
- __le16 type;
- __le16 len;
-} __packed;
-
struct mwifiex_assoc_event {
u8 sta_addr[ETH_ALEN];
__le16 type;
@@ -1396,99 +1391,99 @@ struct host_cmd_11ac_vht_cfg {
} __packed;

struct host_cmd_tlv_akmp {
- struct host_cmd_tlv tlv;
+ struct mwifiex_ie_types_header header;
__le16 key_mgmt;
__le16 key_mgmt_operation;
} __packed;

struct host_cmd_tlv_pwk_cipher {
- struct host_cmd_tlv tlv;
+ struct mwifiex_ie_types_header header;
__le16 proto;
u8 cipher;
u8 reserved;
} __packed;

struct host_cmd_tlv_gwk_cipher {
- struct host_cmd_tlv tlv;
+ struct mwifiex_ie_types_header header;
u8 cipher;
u8 reserved;
} __packed;

struct host_cmd_tlv_passphrase {
- struct host_cmd_tlv tlv;
+ struct mwifiex_ie_types_header header;
u8 passphrase[0];
} __packed;

struct host_cmd_tlv_wep_key {
- struct host_cmd_tlv tlv;
+ struct mwifiex_ie_types_header header;
u8 key_index;
u8 is_default;
u8 key[1];
};

struct host_cmd_tlv_auth_type {
- struct host_cmd_tlv tlv;
+ struct mwifiex_ie_types_header header;
u8 auth_type;
} __packed;

struct host_cmd_tlv_encrypt_protocol {
- struct host_cmd_tlv tlv;
+ struct mwifiex_ie_types_header header;
__le16 proto;
} __packed;

struct host_cmd_tlv_ssid {
- struct host_cmd_tlv tlv;
+ struct mwifiex_ie_types_header header;
u8 ssid[0];
} __packed;

struct host_cmd_tlv_rates {
- struct host_cmd_tlv tlv;
+ struct mwifiex_ie_types_header header;
u8 rates[0];
} __packed;

struct host_cmd_tlv_bcast_ssid {
- struct host_cmd_tlv tlv;
+ struct mwifiex_ie_types_header header;
u8 bcast_ctl;
} __packed;

struct host_cmd_tlv_beacon_period {
- struct host_cmd_tlv tlv;
+ struct mwifiex_ie_types_header header;
__le16 period;
} __packed;

struct host_cmd_tlv_dtim_period {
- struct host_cmd_tlv tlv;
+ struct mwifiex_ie_types_header header;
u8 period;
} __packed;

struct host_cmd_tlv_frag_threshold {
- struct host_cmd_tlv tlv;
+ struct mwifiex_ie_types_header header;
__le16 frag_thr;
} __packed;

struct host_cmd_tlv_rts_threshold {
- struct host_cmd_tlv tlv;
+ struct mwifiex_ie_types_header header;
__le16 rts_thr;
} __packed;

struct host_cmd_tlv_retry_limit {
- struct host_cmd_tlv tlv;
+ struct mwifiex_ie_types_header header;
u8 limit;
} __packed;

struct host_cmd_tlv_mac_addr {
- struct host_cmd_tlv tlv;
+ struct mwifiex_ie_types_header header;
u8 mac_addr[ETH_ALEN];
} __packed;

struct host_cmd_tlv_channel_band {
- struct host_cmd_tlv tlv;
+ struct mwifiex_ie_types_header header;
u8 band_config;
u8 channel;
} __packed;

struct host_cmd_tlv_ageout_timer {
- struct host_cmd_tlv tlv;
+ struct mwifiex_ie_types_header header;
__le32 sta_ao_timer;
} __packed;

diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c
index e38342f..220af4f 100644
--- a/drivers/net/wireless/mwifiex/ie.c
+++ b/drivers/net/wireless/mwifiex/ie.c
@@ -87,7 +87,7 @@ mwifiex_update_autoindex_ies(struct mwifiex_private *priv,
u8 *tmp;

input_len = le16_to_cpu(ie_list->len);
- travel_len = sizeof(struct host_cmd_tlv);
+ travel_len = sizeof(struct mwifiex_ie_types_header);

ie_list->len = 0;

diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 8ece485..9b75ed8 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -707,8 +707,9 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP) {
tlv_mac = (void *)((u8 *)&key_material->key_param_set +
key_param_len);
- tlv_mac->tlv.type = cpu_to_le16(TLV_TYPE_STA_MAC_ADDR);
- tlv_mac->tlv.len = cpu_to_le16(ETH_ALEN);
+ tlv_mac->header.type =
+ cpu_to_le16(TLV_TYPE_STA_MAC_ADDR);
+ tlv_mac->header.len = cpu_to_le16(ETH_ALEN);
memcpy(tlv_mac->mac_addr, enc_key->mac_addr, ETH_ALEN);
cmd_size = key_param_len + S_DS_GEN +
sizeof(key_material->action) +
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 2de882d..64424c8 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -293,9 +293,9 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size)
u8 *tlv = *tlv_buf;

tlv_akmp = (struct host_cmd_tlv_akmp *)tlv;
- tlv_akmp->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AKMP);
- tlv_akmp->tlv.len = cpu_to_le16(sizeof(struct host_cmd_tlv_akmp) -
- sizeof(struct host_cmd_tlv));
+ tlv_akmp->header.type = cpu_to_le16(TLV_TYPE_UAP_AKMP);
+ tlv_akmp->header.len = cpu_to_le16(sizeof(struct host_cmd_tlv_akmp) -
+ sizeof(struct mwifiex_ie_types_header));
tlv_akmp->key_mgmt_operation = cpu_to_le16(bss_cfg->key_mgmt_operation);
tlv_akmp->key_mgmt = cpu_to_le16(bss_cfg->key_mgmt);
cmd_size += sizeof(struct host_cmd_tlv_akmp);
@@ -303,10 +303,10 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size)

if (bss_cfg->wpa_cfg.pairwise_cipher_wpa & VALID_CIPHER_BITMAP) {
pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv;
- pwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER);
- pwk_cipher->tlv.len =
+ pwk_cipher->header.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER);
+ pwk_cipher->header.len =
cpu_to_le16(sizeof(struct host_cmd_tlv_pwk_cipher) -
- sizeof(struct host_cmd_tlv));
+ sizeof(struct mwifiex_ie_types_header));
pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA);
pwk_cipher->cipher = bss_cfg->wpa_cfg.pairwise_cipher_wpa;
cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher);
@@ -315,10 +315,10 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size)

if (bss_cfg->wpa_cfg.pairwise_cipher_wpa2 & VALID_CIPHER_BITMAP) {
pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv;
- pwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER);
- pwk_cipher->tlv.len =
+ pwk_cipher->header.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER);
+ pwk_cipher->header.len =
cpu_to_le16(sizeof(struct host_cmd_tlv_pwk_cipher) -
- sizeof(struct host_cmd_tlv));
+ sizeof(struct mwifiex_ie_types_header));
pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA2);
pwk_cipher->cipher = bss_cfg->wpa_cfg.pairwise_cipher_wpa2;
cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher);
@@ -327,10 +327,10 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size)

if (bss_cfg->wpa_cfg.group_cipher & VALID_CIPHER_BITMAP) {
gwk_cipher = (struct host_cmd_tlv_gwk_cipher *)tlv;
- gwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_GWK_CIPHER);
- gwk_cipher->tlv.len =
+ gwk_cipher->header.type = cpu_to_le16(TLV_TYPE_GWK_CIPHER);
+ gwk_cipher->header.len =
cpu_to_le16(sizeof(struct host_cmd_tlv_gwk_cipher) -
- sizeof(struct host_cmd_tlv));
+ sizeof(struct mwifiex_ie_types_header));
gwk_cipher->cipher = bss_cfg->wpa_cfg.group_cipher;
cmd_size += sizeof(struct host_cmd_tlv_gwk_cipher);
tlv += sizeof(struct host_cmd_tlv_gwk_cipher);
@@ -338,13 +338,15 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size)

if (bss_cfg->wpa_cfg.length) {
passphrase = (struct host_cmd_tlv_passphrase *)tlv;
- passphrase->tlv.type = cpu_to_le16(TLV_TYPE_UAP_WPA_PASSPHRASE);
- passphrase->tlv.len = cpu_to_le16(bss_cfg->wpa_cfg.length);
+ passphrase->header.type =
+ cpu_to_le16(TLV_TYPE_UAP_WPA_PASSPHRASE);
+ passphrase->header.len = cpu_to_le16(bss_cfg->wpa_cfg.length);
memcpy(passphrase->passphrase, bss_cfg->wpa_cfg.passphrase,
bss_cfg->wpa_cfg.length);
- cmd_size += sizeof(struct host_cmd_tlv) +
+ cmd_size += sizeof(struct mwifiex_ie_types_header) +
bss_cfg->wpa_cfg.length;
- tlv += sizeof(struct host_cmd_tlv) + bss_cfg->wpa_cfg.length;
+ tlv += sizeof(struct mwifiex_ie_types_header) +
+ bss_cfg->wpa_cfg.length;
}

*param_size = cmd_size;
@@ -403,16 +405,17 @@ mwifiex_uap_bss_wep(u8 **tlv_buf, void *cmd_buf, u16 *param_size)
(bss_cfg->wep_cfg[i].length == WLAN_KEY_LEN_WEP40 ||
bss_cfg->wep_cfg[i].length == WLAN_KEY_LEN_WEP104)) {
wep_key = (struct host_cmd_tlv_wep_key *)tlv;
- wep_key->tlv.type = cpu_to_le16(TLV_TYPE_UAP_WEP_KEY);
- wep_key->tlv.len =
+ wep_key->header.type =
+ cpu_to_le16(TLV_TYPE_UAP_WEP_KEY);
+ wep_key->header.len =
cpu_to_le16(bss_cfg->wep_cfg[i].length + 2);
wep_key->key_index = bss_cfg->wep_cfg[i].key_index;
wep_key->is_default = bss_cfg->wep_cfg[i].is_default;
memcpy(wep_key->key, bss_cfg->wep_cfg[i].key,
bss_cfg->wep_cfg[i].length);
- cmd_size += sizeof(struct host_cmd_tlv) + 2 +
+ cmd_size += sizeof(struct mwifiex_ie_types_header) + 2 +
bss_cfg->wep_cfg[i].length;
- tlv += sizeof(struct host_cmd_tlv) + 2 +
+ tlv += sizeof(struct mwifiex_ie_types_header) + 2 +
bss_cfg->wep_cfg[i].length;
}
}
@@ -449,16 +452,17 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)

if (bss_cfg->ssid.ssid_len) {
ssid = (struct host_cmd_tlv_ssid *)tlv;
- ssid->tlv.type = cpu_to_le16(TLV_TYPE_UAP_SSID);
- ssid->tlv.len = cpu_to_le16((u16)bss_cfg->ssid.ssid_len);
+ ssid->header.type = cpu_to_le16(TLV_TYPE_UAP_SSID);
+ ssid->header.len = cpu_to_le16((u16)bss_cfg->ssid.ssid_len);
memcpy(ssid->ssid, bss_cfg->ssid.ssid, bss_cfg->ssid.ssid_len);
- cmd_size += sizeof(struct host_cmd_tlv) +
+ cmd_size += sizeof(struct mwifiex_ie_types_header) +
bss_cfg->ssid.ssid_len;
- tlv += sizeof(struct host_cmd_tlv) + bss_cfg->ssid.ssid_len;
+ tlv += sizeof(struct mwifiex_ie_types_header) +
+ bss_cfg->ssid.ssid_len;

bcast_ssid = (struct host_cmd_tlv_bcast_ssid *)tlv;
- bcast_ssid->tlv.type = cpu_to_le16(TLV_TYPE_UAP_BCAST_SSID);
- bcast_ssid->tlv.len =
+ bcast_ssid->header.type = cpu_to_le16(TLV_TYPE_UAP_BCAST_SSID);
+ bcast_ssid->header.len =
cpu_to_le16(sizeof(bcast_ssid->bcast_ctl));
bcast_ssid->bcast_ctl = bss_cfg->bcast_ssid_ctl;
cmd_size += sizeof(struct host_cmd_tlv_bcast_ssid);
@@ -466,13 +470,13 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
}
if (bss_cfg->rates[0]) {
tlv_rates = (struct host_cmd_tlv_rates *)tlv;
- tlv_rates->tlv.type = cpu_to_le16(TLV_TYPE_UAP_RATES);
+ tlv_rates->header.type = cpu_to_le16(TLV_TYPE_UAP_RATES);

for (i = 0; i < MWIFIEX_SUPPORTED_RATES && bss_cfg->rates[i];
i++)
tlv_rates->rates[i] = bss_cfg->rates[i];

- tlv_rates->tlv.len = cpu_to_le16(i);
+ tlv_rates->header.len = cpu_to_le16(i);
cmd_size += sizeof(struct host_cmd_tlv_rates) + i;
tlv += sizeof(struct host_cmd_tlv_rates) + i;
}
@@ -482,10 +486,10 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
(bss_cfg->band_cfg == BAND_CONFIG_A &&
bss_cfg->channel <= MAX_CHANNEL_BAND_A))) {
chan_band = (struct host_cmd_tlv_channel_band *)tlv;
- chan_band->tlv.type = cpu_to_le16(TLV_TYPE_CHANNELBANDLIST);
- chan_band->tlv.len =
+ chan_band->header.type = cpu_to_le16(TLV_TYPE_CHANNELBANDLIST);
+ chan_band->header.len =
cpu_to_le16(sizeof(struct host_cmd_tlv_channel_band) -
- sizeof(struct host_cmd_tlv));
+ sizeof(struct mwifiex_ie_types_header));
chan_band->band_config = bss_cfg->band_cfg;
chan_band->channel = bss_cfg->channel;
cmd_size += sizeof(struct host_cmd_tlv_channel_band);
@@ -494,11 +498,11 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
if (bss_cfg->beacon_period >= MIN_BEACON_PERIOD &&
bss_cfg->beacon_period <= MAX_BEACON_PERIOD) {
beacon_period = (struct host_cmd_tlv_beacon_period *)tlv;
- beacon_period->tlv.type =
+ beacon_period->header.type =
cpu_to_le16(TLV_TYPE_UAP_BEACON_PERIOD);
- beacon_period->tlv.len =
+ beacon_period->header.len =
cpu_to_le16(sizeof(struct host_cmd_tlv_beacon_period) -
- sizeof(struct host_cmd_tlv));
+ sizeof(struct mwifiex_ie_types_header));
beacon_period->period = cpu_to_le16(bss_cfg->beacon_period);
cmd_size += sizeof(struct host_cmd_tlv_beacon_period);
tlv += sizeof(struct host_cmd_tlv_beacon_period);
@@ -506,21 +510,22 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
if (bss_cfg->dtim_period >= MIN_DTIM_PERIOD &&
bss_cfg->dtim_period <= MAX_DTIM_PERIOD) {
dtim_period = (struct host_cmd_tlv_dtim_period *)tlv;
- dtim_period->tlv.type = cpu_to_le16(TLV_TYPE_UAP_DTIM_PERIOD);
- dtim_period->tlv.len =
+ dtim_period->header.type =
+ cpu_to_le16(TLV_TYPE_UAP_DTIM_PERIOD);
+ dtim_period->header.len =
cpu_to_le16(sizeof(struct host_cmd_tlv_dtim_period) -
- sizeof(struct host_cmd_tlv));
+ sizeof(struct mwifiex_ie_types_header));
dtim_period->period = bss_cfg->dtim_period;
cmd_size += sizeof(struct host_cmd_tlv_dtim_period);
tlv += sizeof(struct host_cmd_tlv_dtim_period);
}
if (bss_cfg->rts_threshold <= MWIFIEX_RTS_MAX_VALUE) {
rts_threshold = (struct host_cmd_tlv_rts_threshold *)tlv;
- rts_threshold->tlv.type =
+ rts_threshold->header.type =
cpu_to_le16(TLV_TYPE_UAP_RTS_THRESHOLD);
- rts_threshold->tlv.len =
+ rts_threshold->header.len =
cpu_to_le16(sizeof(struct host_cmd_tlv_rts_threshold) -
- sizeof(struct host_cmd_tlv));
+ sizeof(struct mwifiex_ie_types_header));
rts_threshold->rts_thr = cpu_to_le16(bss_cfg->rts_threshold);
cmd_size += sizeof(struct host_cmd_tlv_frag_threshold);
tlv += sizeof(struct host_cmd_tlv_frag_threshold);
@@ -528,21 +533,22 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
if ((bss_cfg->frag_threshold >= MWIFIEX_FRAG_MIN_VALUE) &&
(bss_cfg->frag_threshold <= MWIFIEX_FRAG_MAX_VALUE)) {
frag_threshold = (struct host_cmd_tlv_frag_threshold *)tlv;
- frag_threshold->tlv.type =
+ frag_threshold->header.type =
cpu_to_le16(TLV_TYPE_UAP_FRAG_THRESHOLD);
- frag_threshold->tlv.len =
+ frag_threshold->header.len =
cpu_to_le16(sizeof(struct host_cmd_tlv_frag_threshold) -
- sizeof(struct host_cmd_tlv));
+ sizeof(struct mwifiex_ie_types_header));
frag_threshold->frag_thr = cpu_to_le16(bss_cfg->frag_threshold);
cmd_size += sizeof(struct host_cmd_tlv_frag_threshold);
tlv += sizeof(struct host_cmd_tlv_frag_threshold);
}
if (bss_cfg->retry_limit <= MWIFIEX_RETRY_LIMIT) {
retry_limit = (struct host_cmd_tlv_retry_limit *)tlv;
- retry_limit->tlv.type = cpu_to_le16(TLV_TYPE_UAP_RETRY_LIMIT);
- retry_limit->tlv.len =
+ retry_limit->header.type =
+ cpu_to_le16(TLV_TYPE_UAP_RETRY_LIMIT);
+ retry_limit->header.len =
cpu_to_le16(sizeof(struct host_cmd_tlv_retry_limit) -
- sizeof(struct host_cmd_tlv));
+ sizeof(struct mwifiex_ie_types_header));
retry_limit->limit = (u8)bss_cfg->retry_limit;
cmd_size += sizeof(struct host_cmd_tlv_retry_limit);
tlv += sizeof(struct host_cmd_tlv_retry_limit);
@@ -557,21 +563,21 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
if ((bss_cfg->auth_mode <= WLAN_AUTH_SHARED_KEY) ||
(bss_cfg->auth_mode == MWIFIEX_AUTH_MODE_AUTO)) {
auth_type = (struct host_cmd_tlv_auth_type *)tlv;
- auth_type->tlv.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
- auth_type->tlv.len =
+ auth_type->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
+ auth_type->header.len =
cpu_to_le16(sizeof(struct host_cmd_tlv_auth_type) -
- sizeof(struct host_cmd_tlv));
+ sizeof(struct mwifiex_ie_types_header));
auth_type->auth_type = (u8)bss_cfg->auth_mode;
cmd_size += sizeof(struct host_cmd_tlv_auth_type);
tlv += sizeof(struct host_cmd_tlv_auth_type);
}
if (bss_cfg->protocol) {
encrypt_protocol = (struct host_cmd_tlv_encrypt_protocol *)tlv;
- encrypt_protocol->tlv.type =
+ encrypt_protocol->header.type =
cpu_to_le16(TLV_TYPE_UAP_ENCRY_PROTOCOL);
- encrypt_protocol->tlv.len =
+ encrypt_protocol->header.len =
cpu_to_le16(sizeof(struct host_cmd_tlv_encrypt_protocol)
- - sizeof(struct host_cmd_tlv));
+ - sizeof(struct mwifiex_ie_types_header));
encrypt_protocol->proto = cpu_to_le16(bss_cfg->protocol);
cmd_size += sizeof(struct host_cmd_tlv_encrypt_protocol);
tlv += sizeof(struct host_cmd_tlv_encrypt_protocol);
@@ -608,9 +614,9 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)

if (bss_cfg->sta_ao_timer) {
ao_timer = (struct host_cmd_tlv_ageout_timer *)tlv;
- ao_timer->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AO_TIMER);
- ao_timer->tlv.len = cpu_to_le16(sizeof(*ao_timer) -
- sizeof(struct host_cmd_tlv));
+ ao_timer->header.type = cpu_to_le16(TLV_TYPE_UAP_AO_TIMER);
+ ao_timer->header.len = cpu_to_le16(sizeof(*ao_timer) -
+ sizeof(struct mwifiex_ie_types_header));
ao_timer->sta_ao_timer = cpu_to_le32(bss_cfg->sta_ao_timer);
cmd_size += sizeof(*ao_timer);
tlv += sizeof(*ao_timer);
@@ -618,9 +624,10 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)

if (bss_cfg->ps_sta_ao_timer) {
ps_ao_timer = (struct host_cmd_tlv_ageout_timer *)tlv;
- ps_ao_timer->tlv.type = cpu_to_le16(TLV_TYPE_UAP_PS_AO_TIMER);
- ps_ao_timer->tlv.len = cpu_to_le16(sizeof(*ps_ao_timer) -
- sizeof(struct host_cmd_tlv));
+ ps_ao_timer->header.type =
+ cpu_to_le16(TLV_TYPE_UAP_PS_AO_TIMER);
+ ps_ao_timer->header.len = cpu_to_le16(sizeof(*ps_ao_timer) -
+ sizeof(struct mwifiex_ie_types_header));
ps_ao_timer->sta_ao_timer =
cpu_to_le32(bss_cfg->ps_sta_ao_timer);
cmd_size += sizeof(*ps_ao_timer);
@@ -636,16 +643,17 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
static int mwifiex_uap_custom_ie_prepare(u8 *tlv, void *cmd_buf, u16 *ie_size)
{
struct mwifiex_ie_list *ap_ie = cmd_buf;
- struct host_cmd_tlv *tlv_ie = (struct host_cmd_tlv *)tlv;
+ struct mwifiex_ie_types_header *tlv_ie = (void *)tlv;

if (!ap_ie || !ap_ie->len || !ap_ie->ie_list)
return -1;

- *ie_size += le16_to_cpu(ap_ie->len) + sizeof(struct host_cmd_tlv);
+ *ie_size += le16_to_cpu(ap_ie->len) +
+ sizeof(struct mwifiex_ie_types_header);

tlv_ie->type = cpu_to_le16(TLV_TYPE_MGMT_IE);
tlv_ie->len = ap_ie->len;
- tlv += sizeof(struct host_cmd_tlv);
+ tlv += sizeof(struct mwifiex_ie_types_header);

memcpy(tlv, ap_ie->ie_list, le16_to_cpu(ap_ie->len));

--
1.8.2.3


2013-07-24 18:50:01

by Bing Zhao

[permalink] [raw]
Subject: RE: [PATCH 18/21] mwifiex: handle driver initialization error paths

Hi John,

> This one didn't apply on the current wireless-next tree. Can you
> fix it up?

18/21 and 19/21 depend on this patch:

commit 232fde062e0a2cc52e8e18a50cda361b4ba88f34
Author: Daniel Drake <[email protected]>
Date: Sat Jul 13 10:57:10 2013 -0400

mwifiex: fix IRQ enable/disable

which is in wireless.git and wireless-testing.git currently.


We can apply 18 and 19 later after commit 232fde0 is merged back to wireless-next.git.
(I will send you a reminder to merge these two patches once commit 232fde0 is in -next tree.)

Thanks,
Bing


2013-07-23 02:18:57

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 15/21] mwifiex: reduce firmware poll retries

From: Amitkumar Karwar <[email protected]>

After downloading the firmware, firmware status is checked by
reading a register. Polling interval is 100 msecs. Therefore 100
retries means the status is checked for 10 secs which is more than
sufficient for firmware to get ready.

This patch removes 1000 retries macro usage, because 100secs
time is not practical.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/fw.h | 3 ---
drivers/net/wireless/mwifiex/init.c | 1 -
2 files changed, 4 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 1b45aa5..99c2729 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -85,9 +85,6 @@ enum KEY_TYPE_ID {
#define WAPI_KEY_LEN 50

#define MAX_POLL_TRIES 100
-
-#define MAX_MULTI_INTERFACE_POLL_TRIES 1000
-
#define MAX_FIRMWARE_POLL_TRIES 100

#define FIRMWARE_READY_SDIO 0xfedc
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 2cda7ee..e021a58 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -691,7 +691,6 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
if (!adapter->winner) {
dev_notice(adapter->dev,
"FW already running! Skip FW dnld\n");
- poll_num = MAX_MULTI_INTERFACE_POLL_TRIES;
goto poll_fw;
}
}
--
1.8.2.3


2013-07-26 04:25:46

by Bing Zhao

[permalink] [raw]
Subject: RE: [PATCH 18/21] mwifiex: handle driver initialization error paths

Hi John,

> > 18/21 and 19/21 depend on this patch:
> >
> > commit 232fde062e0a2cc52e8e18a50cda361b4ba88f34
> > Author: Daniel Drake <[email protected]>
> > Date: Sat Jul 13 10:57:10 2013 -0400
> >
> > mwifiex: fix IRQ enable/disable
> >
> > which is in wireless.git and wireless-testing.git currently.
> >
> >
> > We can apply 18 and 19 later after commit 232fde0 is merged back to wireless-next.git.
> > (I will send you a reminder to merge these two patches once commit 232fde0 is in -next tree.)
> >
> > Thanks,
> > Bing
>
> OK, thanks for checking!

As the commit 232fde0 has been merged to wireless-next you may apply 18/21 and 19/21 now.

Thanks,
Bing