diff options
author | Samuel Ortiz <samuel.ortiz@intel.com> | 2009-06-15 15:59:51 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-07-10 14:57:51 -0400 |
commit | a70742f167424bab794ca74b9e99b598b358bb7d (patch) | |
tree | 28db2ea700e844beb7ce18ace345fcf3797c22bc /drivers/net/wireless/iwmc3200wifi | |
parent | 0c5553b1392dea5ba5ad678790367c1275ed1172 (diff) |
iwmc3200wifi: handling wifi_if_ntfy responses
When we're calling iwm_send_wifi_if_cmd() with the resp flag set, we're
currently waiting on the mlme queue, waiting for some flags here and there to
show up.
This patch adds a wifi_ntfy bitmap, and when we're sending a wifi_if command
expecting an answers, we wait synchronously for it to show up, on a dedicated
queue. The wifi_ntfy bit is set when we receive the corresponding answer.
Signed-off-by: Samuel Ortiz <samuel.ortiz@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwmc3200wifi')
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/commands.c | 31 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/iwm.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/main.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/rx.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/umac.h | 2 |
5 files changed, 31 insertions, 15 deletions
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c index 834a7f544e5d..337a884f52df 100644 --- a/drivers/net/wireless/iwmc3200wifi/commands.c +++ b/drivers/net/wireless/iwmc3200wifi/commands.c | |||
@@ -70,14 +70,28 @@ static int iwm_send_lmac_ptrough_cmd(struct iwm_priv *iwm, | |||
70 | int iwm_send_wifi_if_cmd(struct iwm_priv *iwm, void *payload, u16 payload_size, | 70 | int iwm_send_wifi_if_cmd(struct iwm_priv *iwm, void *payload, u16 payload_size, |
71 | bool resp) | 71 | bool resp) |
72 | { | 72 | { |
73 | struct iwm_umac_wifi_if *hdr = (struct iwm_umac_wifi_if *)payload; | ||
73 | struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT; | 74 | struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT; |
74 | struct iwm_umac_cmd umac_cmd; | 75 | struct iwm_umac_cmd umac_cmd; |
76 | int ret; | ||
77 | u8 oid = hdr->oid; | ||
75 | 78 | ||
76 | umac_cmd.id = UMAC_CMD_OPCODE_WIFI_IF_WRAPPER; | 79 | umac_cmd.id = UMAC_CMD_OPCODE_WIFI_IF_WRAPPER; |
77 | umac_cmd.resp = resp; | 80 | umac_cmd.resp = resp; |
78 | 81 | ||
79 | return iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, | 82 | ret = iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, |
80 | payload, payload_size); | 83 | payload, payload_size); |
84 | |||
85 | if (resp) { | ||
86 | ret = wait_event_interruptible_timeout(iwm->wifi_ntfy_queue, | ||
87 | test_and_clear_bit(oid, &iwm->wifi_ntfy[0]), | ||
88 | 3 * HZ); | ||
89 | |||
90 | if (!ret) | ||
91 | ret = -EBUSY; | ||
92 | } | ||
93 | |||
94 | return ret; | ||
81 | } | 95 | } |
82 | 96 | ||
83 | static struct coex_event iwm_sta_xor_prio_tbl[COEX_EVENTS_NUM] = | 97 | static struct coex_event iwm_sta_xor_prio_tbl[COEX_EVENTS_NUM] = |
@@ -746,14 +760,6 @@ int iwm_send_mlme_profile(struct iwm_priv *iwm) | |||
746 | return ret; | 760 | return ret; |
747 | } | 761 | } |
748 | 762 | ||
749 | /* Wait for the profile to be active */ | ||
750 | ret = wait_event_interruptible_timeout(iwm->mlme_queue, | ||
751 | iwm->umac_profile_active == 1, | ||
752 | 3 * HZ); | ||
753 | if (!ret) | ||
754 | return -EBUSY; | ||
755 | |||
756 | |||
757 | for (i = 0; i < IWM_NUM_KEYS; i++) | 763 | for (i = 0; i < IWM_NUM_KEYS; i++) |
758 | if (iwm->keys[i].in_use) { | 764 | if (iwm->keys[i].in_use) { |
759 | int default_key = 0; | 765 | int default_key = 0; |
@@ -778,8 +784,8 @@ int iwm_send_mlme_profile(struct iwm_priv *iwm) | |||
778 | 784 | ||
779 | int iwm_invalidate_mlme_profile(struct iwm_priv *iwm) | 785 | int iwm_invalidate_mlme_profile(struct iwm_priv *iwm) |
780 | { | 786 | { |
781 | int ret; | ||
782 | struct iwm_umac_invalidate_profile invalid; | 787 | struct iwm_umac_invalidate_profile invalid; |
788 | int ret; | ||
783 | 789 | ||
784 | invalid.hdr.oid = UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE; | 790 | invalid.hdr.oid = UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE; |
785 | invalid.hdr.buf_size = | 791 | invalid.hdr.buf_size = |
@@ -793,8 +799,7 @@ int iwm_invalidate_mlme_profile(struct iwm_priv *iwm) | |||
793 | return ret; | 799 | return ret; |
794 | 800 | ||
795 | ret = wait_event_interruptible_timeout(iwm->mlme_queue, | 801 | ret = wait_event_interruptible_timeout(iwm->mlme_queue, |
796 | (iwm->umac_profile_active == 0), | 802 | (iwm->umac_profile_active == 0), 2 * HZ); |
797 | 2 * HZ); | ||
798 | if (!ret) | 803 | if (!ret) |
799 | return -EBUSY; | 804 | return -EBUSY; |
800 | 805 | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h index 77c339f8516c..d8d4ae2d91b0 100644 --- a/drivers/net/wireless/iwmc3200wifi/iwm.h +++ b/drivers/net/wireless/iwmc3200wifi/iwm.h | |||
@@ -278,6 +278,9 @@ struct iwm_priv { | |||
278 | struct iwm_key keys[IWM_NUM_KEYS]; | 278 | struct iwm_key keys[IWM_NUM_KEYS]; |
279 | struct iwm_key *default_key; | 279 | struct iwm_key *default_key; |
280 | 280 | ||
281 | DECLARE_BITMAP(wifi_ntfy, WIFI_IF_NTFY_MAX); | ||
282 | wait_queue_head_t wifi_ntfy_queue; | ||
283 | |||
281 | wait_queue_head_t mlme_queue; | 284 | wait_queue_head_t mlme_queue; |
282 | 285 | ||
283 | struct iw_statistics wstats; | 286 | struct iw_statistics wstats; |
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c index 8be206d58222..844872213a12 100644 --- a/drivers/net/wireless/iwmc3200wifi/main.c +++ b/drivers/net/wireless/iwmc3200wifi/main.c | |||
@@ -191,6 +191,7 @@ int iwm_priv_init(struct iwm_priv *iwm) | |||
191 | INIT_LIST_HEAD(&iwm->pending_notif); | 191 | INIT_LIST_HEAD(&iwm->pending_notif); |
192 | init_waitqueue_head(&iwm->notif_queue); | 192 | init_waitqueue_head(&iwm->notif_queue); |
193 | init_waitqueue_head(&iwm->nonwifi_queue); | 193 | init_waitqueue_head(&iwm->nonwifi_queue); |
194 | init_waitqueue_head(&iwm->wifi_ntfy_queue); | ||
194 | init_waitqueue_head(&iwm->mlme_queue); | 195 | init_waitqueue_head(&iwm->mlme_queue); |
195 | memcpy(&iwm->conf, &def_iwm_conf, sizeof(struct iwm_conf)); | 196 | memcpy(&iwm->conf, &def_iwm_conf, sizeof(struct iwm_conf)); |
196 | spin_lock_init(&iwm->tx_credit.lock); | 197 | spin_lock_init(&iwm->tx_credit.lock); |
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c index d73cf96c6dc6..49a8be7c5396 100644 --- a/drivers/net/wireless/iwmc3200wifi/rx.c +++ b/drivers/net/wireless/iwmc3200wifi/rx.c | |||
@@ -993,12 +993,17 @@ static int iwm_ntf_wifi_if_wrapper(struct iwm_priv *iwm, u8 *buf, | |||
993 | (struct iwm_umac_wifi_if *)cmd->buf.payload; | 993 | (struct iwm_umac_wifi_if *)cmd->buf.payload; |
994 | 994 | ||
995 | IWM_DBG_NTF(iwm, DBG, "WIFI_IF_WRAPPER cmd is delivered to UMAC: " | 995 | IWM_DBG_NTF(iwm, DBG, "WIFI_IF_WRAPPER cmd is delivered to UMAC: " |
996 | "oid is %d\n", hdr->oid); | 996 | "oid is 0x%x\n", hdr->oid); |
997 | |||
998 | if (hdr->oid <= WIFI_IF_NTFY_MAX) { | ||
999 | set_bit(hdr->oid, &iwm->wifi_ntfy[0]); | ||
1000 | wake_up_interruptible(&iwm->wifi_ntfy_queue); | ||
1001 | } else | ||
1002 | return -EINVAL; | ||
997 | 1003 | ||
998 | switch (hdr->oid) { | 1004 | switch (hdr->oid) { |
999 | case UMAC_WIFI_IF_CMD_SET_PROFILE: | 1005 | case UMAC_WIFI_IF_CMD_SET_PROFILE: |
1000 | iwm->umac_profile_active = 1; | 1006 | iwm->umac_profile_active = 1; |
1001 | wake_up_interruptible(&iwm->mlme_queue); | ||
1002 | break; | 1007 | break; |
1003 | default: | 1008 | default: |
1004 | break; | 1009 | break; |
diff --git a/drivers/net/wireless/iwmc3200wifi/umac.h b/drivers/net/wireless/iwmc3200wifi/umac.h index 4a95cce1f0a6..0af2a3c76281 100644 --- a/drivers/net/wireless/iwmc3200wifi/umac.h +++ b/drivers/net/wireless/iwmc3200wifi/umac.h | |||
@@ -495,6 +495,8 @@ struct iwm_fw_alive_hdr { | |||
495 | #define WIFI_DBG_IF_NTFY_COEX_HANDLE_ENVELOP 0xE8 | 495 | #define WIFI_DBG_IF_NTFY_COEX_HANDLE_ENVELOP 0xE8 |
496 | #define WIFI_DBG_IF_NTFY_COEX_HANDLE_RELEASE_ENVELOP 0xE9 | 496 | #define WIFI_DBG_IF_NTFY_COEX_HANDLE_RELEASE_ENVELOP 0xE9 |
497 | 497 | ||
498 | #define WIFI_IF_NTFY_MAX 0xff | ||
499 | |||
498 | /* Notification structures */ | 500 | /* Notification structures */ |
499 | struct iwm_umac_notif_wifi_if { | 501 | struct iwm_umac_notif_wifi_if { |
500 | struct iwm_umac_wifi_in_hdr hdr; | 502 | struct iwm_umac_wifi_in_hdr hdr; |