aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex
diff options
context:
space:
mode:
authorMaithili Hinge <maithili@marvell.com>2015-03-23 02:01:25 -0400
committerKalle Valo <kvalo@codeaurora.org>2015-03-30 04:32:56 -0400
commit2f5872b60146eadf74b8d349a3596f5aaf687401 (patch)
treed9ad816df4eda516ab95e8080b94b5d9d7f0488f /drivers/net/wireless/mwifiex
parenteaa4059d56fdbeb1633c94e82d54849688d96777 (diff)
mwifiex: Fix issue in the SDIO reset path of mwifiex.
SDIO reset was not happening properly on mwifiex as cancel_work_sync in mwifiex_sdio_remove used to kill the calling work function itself. Due to this, the interface was not getting removed and card was not getting added again. Reset work function has been made independent of adapter variable and cancel_work_sync has been moved to cleanup function. Signed-off-by: Maithili Hinge <maithili@marvell.com> Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/mwifiex')
-rw-r--r--drivers/net/wireless/mwifiex/main.c3
-rw-r--r--drivers/net/wireless/mwifiex/main.h2
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c21
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c38
4 files changed, 28 insertions, 36 deletions
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index eaaacecbdef6..a3c2bb122c09 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -1149,9 +1149,6 @@ mwifiex_add_card(void *card, struct semaphore *sem,
1149 INIT_WORK(&adapter->rx_work, mwifiex_rx_work_queue); 1149 INIT_WORK(&adapter->rx_work, mwifiex_rx_work_queue);
1150 } 1150 }
1151 1151
1152 if (adapter->if_ops.iface_work)
1153 INIT_WORK(&adapter->iface_work, adapter->if_ops.iface_work);
1154
1155 /* Register the device. Fill up the private data structure with relevant 1152 /* Register the device. Fill up the private data structure with relevant
1156 information from the card. */ 1153 information from the card. */
1157 if (adapter->if_ops.register_dev(adapter)) { 1154 if (adapter->if_ops.register_dev(adapter)) {
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 842fa0beb188..b97b85b7f2a1 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -898,8 +898,6 @@ struct mwifiex_adapter {
898 bool ext_scan; 898 bool ext_scan;
899 u8 fw_api_ver; 899 u8 fw_api_ver;
900 u8 key_api_major_ver, key_api_minor_ver; 900 u8 key_api_major_ver, key_api_minor_ver;
901 struct work_struct iface_work;
902 unsigned long iface_work_flags;
903 struct memory_type_mapping *mem_type_mapping_tbl; 901 struct memory_type_mapping *mem_type_mapping_tbl;
904 u8 num_mem_types; 902 u8 num_mem_types;
905 u8 curr_mem_idx; 903 u8 curr_mem_idx;
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index b31c9a70ffaa..bcc7751d883c 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -234,8 +234,6 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
234 if (!adapter || !adapter->priv_num) 234 if (!adapter || !adapter->priv_num)
235 return; 235 return;
236 236
237 cancel_work_sync(&adapter->iface_work);
238
239 if (user_rmmod) { 237 if (user_rmmod) {
240#ifdef CONFIG_PM_SLEEP 238#ifdef CONFIG_PM_SLEEP
241 if (adapter->is_suspended) 239 if (adapter->is_suspended)
@@ -2373,25 +2371,26 @@ done:
2373 adapter->curr_mem_idx = 0; 2371 adapter->curr_mem_idx = 0;
2374} 2372}
2375 2373
2374static unsigned long iface_work_flags;
2375static struct mwifiex_adapter *save_adapter;
2376static void mwifiex_pcie_work(struct work_struct *work) 2376static void mwifiex_pcie_work(struct work_struct *work)
2377{ 2377{
2378 struct mwifiex_adapter *adapter =
2379 container_of(work, struct mwifiex_adapter, iface_work);
2380
2381 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP, 2378 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP,
2382 &adapter->iface_work_flags)) 2379 &iface_work_flags))
2383 mwifiex_pcie_fw_dump_work(adapter); 2380 mwifiex_pcie_fw_dump_work(save_adapter);
2384} 2381}
2385 2382
2383static DECLARE_WORK(pcie_work, mwifiex_pcie_work);
2386/* This function dumps FW information */ 2384/* This function dumps FW information */
2387static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter) 2385static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter)
2388{ 2386{
2389 if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags)) 2387 save_adapter = adapter;
2388 if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &iface_work_flags))
2390 return; 2389 return;
2391 2390
2392 set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags); 2391 set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &iface_work_flags);
2393 2392
2394 schedule_work(&adapter->iface_work); 2393 schedule_work(&pcie_work);
2395} 2394}
2396 2395
2397/* 2396/*
@@ -2619,7 +2618,6 @@ static struct mwifiex_if_ops pcie_ops = {
2619 .init_fw_port = mwifiex_pcie_init_fw_port, 2618 .init_fw_port = mwifiex_pcie_init_fw_port,
2620 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf, 2619 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
2621 .fw_dump = mwifiex_pcie_fw_dump, 2620 .fw_dump = mwifiex_pcie_fw_dump,
2622 .iface_work = mwifiex_pcie_work,
2623}; 2621};
2624 2622
2625/* 2623/*
@@ -2665,6 +2663,7 @@ static void mwifiex_pcie_cleanup_module(void)
2665 /* Set the flag as user is removing this module. */ 2663 /* Set the flag as user is removing this module. */
2666 user_rmmod = 1; 2664 user_rmmod = 1;
2667 2665
2666 cancel_work_sync(&pcie_work);
2668 pci_unregister_driver(&mwifiex_pcie); 2667 pci_unregister_driver(&mwifiex_pcie);
2669} 2668}
2670 2669
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 4f08c58989af..6af7a08253f2 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -47,6 +47,7 @@
47static u8 user_rmmod; 47static u8 user_rmmod;
48 48
49static struct mwifiex_if_ops sdio_ops; 49static struct mwifiex_if_ops sdio_ops;
50static unsigned long iface_work_flags;
50 51
51static struct semaphore add_remove_card_sem; 52static struct semaphore add_remove_card_sem;
52 53
@@ -200,8 +201,6 @@ mwifiex_sdio_remove(struct sdio_func *func)
200 if (!adapter || !adapter->priv_num) 201 if (!adapter || !adapter->priv_num)
201 return; 202 return;
202 203
203 cancel_work_sync(&adapter->iface_work);
204
205 if (user_rmmod) { 204 if (user_rmmod) {
206 if (adapter->is_suspended) 205 if (adapter->is_suspended)
207 mwifiex_sdio_resume(adapter->dev); 206 mwifiex_sdio_resume(adapter->dev);
@@ -2040,6 +2039,7 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port)
2040 port, card->mp_data_port_mask); 2039 port, card->mp_data_port_mask);
2041} 2040}
2042 2041
2042static struct mwifiex_adapter *save_adapter;
2043static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter) 2043static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter)
2044{ 2044{
2045 struct sdio_mmc_card *card = adapter->card; 2045 struct sdio_mmc_card *card = adapter->card;
@@ -2108,10 +2108,8 @@ rdwr_status mwifiex_sdio_rdwr_firmware(struct mwifiex_adapter *adapter,
2108} 2108}
2109 2109
2110/* This function dump firmware memory to file */ 2110/* This function dump firmware memory to file */
2111static void mwifiex_sdio_fw_dump_work(struct work_struct *work) 2111static void mwifiex_sdio_fw_dump_work(struct mwifiex_adapter *adapter)
2112{ 2112{
2113 struct mwifiex_adapter *adapter =
2114 container_of(work, struct mwifiex_adapter, iface_work);
2115 struct sdio_mmc_card *card = adapter->card; 2113 struct sdio_mmc_card *card = adapter->card;
2116 int ret = 0; 2114 int ret = 0;
2117 unsigned int reg, reg_start, reg_end; 2115 unsigned int reg, reg_start, reg_end;
@@ -2233,36 +2231,36 @@ done:
2233 2231
2234static void mwifiex_sdio_work(struct work_struct *work) 2232static void mwifiex_sdio_work(struct work_struct *work)
2235{ 2233{
2236 struct mwifiex_adapter *adapter =
2237 container_of(work, struct mwifiex_adapter, iface_work);
2238
2239 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET,
2240 &adapter->iface_work_flags))
2241 mwifiex_sdio_card_reset_work(adapter);
2242 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP, 2234 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP,
2243 &adapter->iface_work_flags)) 2235 &iface_work_flags))
2244 mwifiex_sdio_fw_dump_work(work); 2236 mwifiex_sdio_fw_dump_work(save_adapter);
2237 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET,
2238 &iface_work_flags))
2239 mwifiex_sdio_card_reset_work(save_adapter);
2245} 2240}
2246 2241
2242static DECLARE_WORK(sdio_work, mwifiex_sdio_work);
2247/* This function resets the card */ 2243/* This function resets the card */
2248static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter) 2244static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter)
2249{ 2245{
2250 if (test_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &adapter->iface_work_flags)) 2246 save_adapter = adapter;
2247 if (test_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &iface_work_flags))
2251 return; 2248 return;
2252 2249
2253 set_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &adapter->iface_work_flags); 2250 set_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &iface_work_flags);
2254 2251
2255 schedule_work(&adapter->iface_work); 2252 schedule_work(&sdio_work);
2256} 2253}
2257 2254
2258/* This function dumps FW information */ 2255/* This function dumps FW information */
2259static void mwifiex_sdio_fw_dump(struct mwifiex_adapter *adapter) 2256static void mwifiex_sdio_fw_dump(struct mwifiex_adapter *adapter)
2260{ 2257{
2261 if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags)) 2258 save_adapter = adapter;
2259 if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &iface_work_flags))
2262 return; 2260 return;
2263 2261
2264 set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags); 2262 set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &iface_work_flags);
2265 schedule_work(&adapter->iface_work); 2263 schedule_work(&sdio_work);
2266} 2264}
2267 2265
2268/* Function to dump SDIO function registers and SDIO scratch registers in case 2266/* Function to dump SDIO function registers and SDIO scratch registers in case
@@ -2378,7 +2376,6 @@ static struct mwifiex_if_ops sdio_ops = {
2378 .cmdrsp_complete = mwifiex_sdio_cmdrsp_complete, 2376 .cmdrsp_complete = mwifiex_sdio_cmdrsp_complete,
2379 .event_complete = mwifiex_sdio_event_complete, 2377 .event_complete = mwifiex_sdio_event_complete,
2380 .card_reset = mwifiex_sdio_card_reset, 2378 .card_reset = mwifiex_sdio_card_reset,
2381 .iface_work = mwifiex_sdio_work,
2382 .fw_dump = mwifiex_sdio_fw_dump, 2379 .fw_dump = mwifiex_sdio_fw_dump,
2383 .reg_dump = mwifiex_sdio_reg_dump, 2380 .reg_dump = mwifiex_sdio_reg_dump,
2384 .deaggr_pkt = mwifiex_deaggr_sdio_pkt, 2381 .deaggr_pkt = mwifiex_deaggr_sdio_pkt,
@@ -2418,6 +2415,7 @@ mwifiex_sdio_cleanup_module(void)
2418 2415
2419 /* Set the flag as user is removing this module. */ 2416 /* Set the flag as user is removing this module. */
2420 user_rmmod = 1; 2417 user_rmmod = 1;
2418 cancel_work_sync(&sdio_work);
2421 2419
2422 sdio_unregister_driver(&mwifiex_sdio); 2420 sdio_unregister_driver(&mwifiex_sdio);
2423} 2421}