diff options
author | Maithili Hinge <maithili@marvell.com> | 2015-03-23 02:01:25 -0400 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2015-03-30 04:32:56 -0400 |
commit | 2f5872b60146eadf74b8d349a3596f5aaf687401 (patch) | |
tree | d9ad816df4eda516ab95e8080b94b5d9d7f0488f /drivers/net/wireless/mwifiex | |
parent | eaa4059d56fdbeb1633c94e82d54849688d96777 (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.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/main.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/pcie.c | 21 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/sdio.c | 38 |
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 | ||
2374 | static unsigned long iface_work_flags; | ||
2375 | static struct mwifiex_adapter *save_adapter; | ||
2376 | static void mwifiex_pcie_work(struct work_struct *work) | 2376 | static 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 | ||
2383 | static DECLARE_WORK(pcie_work, mwifiex_pcie_work); | ||
2386 | /* This function dumps FW information */ | 2384 | /* This function dumps FW information */ |
2387 | static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter) | 2385 | static 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 @@ | |||
47 | static u8 user_rmmod; | 47 | static u8 user_rmmod; |
48 | 48 | ||
49 | static struct mwifiex_if_ops sdio_ops; | 49 | static struct mwifiex_if_ops sdio_ops; |
50 | static unsigned long iface_work_flags; | ||
50 | 51 | ||
51 | static struct semaphore add_remove_card_sem; | 52 | static 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 | ||
2042 | static struct mwifiex_adapter *save_adapter; | ||
2043 | static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter) | 2043 | static 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 */ |
2111 | static void mwifiex_sdio_fw_dump_work(struct work_struct *work) | 2111 | static 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 | ||
2234 | static void mwifiex_sdio_work(struct work_struct *work) | 2232 | static 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 | ||
2242 | static DECLARE_WORK(sdio_work, mwifiex_sdio_work); | ||
2247 | /* This function resets the card */ | 2243 | /* This function resets the card */ |
2248 | static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter) | 2244 | static 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 */ |
2259 | static void mwifiex_sdio_fw_dump(struct mwifiex_adapter *adapter) | 2256 | static 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 | } |