aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwmc3200wifi
diff options
context:
space:
mode:
authorSamuel Ortiz <samuel.ortiz@intel.com>2009-06-15 15:59:51 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-10 14:57:51 -0400
commita70742f167424bab794ca74b9e99b598b358bb7d (patch)
tree28db2ea700e844beb7ce18ace345fcf3797c22bc /drivers/net/wireless/iwmc3200wifi
parent0c5553b1392dea5ba5ad678790367c1275ed1172 (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.c31
-rw-r--r--drivers/net/wireless/iwmc3200wifi/iwm.h3
-rw-r--r--drivers/net/wireless/iwmc3200wifi/main.c1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c9
-rw-r--r--drivers/net/wireless/iwmc3200wifi/umac.h2
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,
70int iwm_send_wifi_if_cmd(struct iwm_priv *iwm, void *payload, u16 payload_size, 70int 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
83static struct coex_event iwm_sta_xor_prio_tbl[COEX_EVENTS_NUM] = 97static 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
779int iwm_invalidate_mlme_profile(struct iwm_priv *iwm) 785int 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 */
499struct iwm_umac_notif_wifi_if { 501struct iwm_umac_notif_wifi_if {
500 struct iwm_umac_wifi_in_hdr hdr; 502 struct iwm_umac_wifi_in_hdr hdr;