iwmc3200wifi: handling wifi_if_ntfy responses
authorSamuel Ortiz <samuel.ortiz@intel.com>
Mon, 15 Jun 2009 19:59:51 +0000 (21:59 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 10 Jul 2009 18:57:51 +0000 (14:57 -0400)
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>
drivers/net/wireless/iwmc3200wifi/commands.c
drivers/net/wireless/iwmc3200wifi/iwm.h
drivers/net/wireless/iwmc3200wifi/main.c
drivers/net/wireless/iwmc3200wifi/rx.c
drivers/net/wireless/iwmc3200wifi/umac.h

index 834a7f544e5d761d57e60de5abc72d509e06ade2..337a884f52df873700e0cbd62215abc6bde8302a 100644 (file)
@@ -70,14 +70,28 @@ static int iwm_send_lmac_ptrough_cmd(struct iwm_priv *iwm,
 int iwm_send_wifi_if_cmd(struct iwm_priv *iwm, void *payload, u16 payload_size,
                         bool resp)
 {
+       struct iwm_umac_wifi_if *hdr = (struct iwm_umac_wifi_if *)payload;
        struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
        struct iwm_umac_cmd umac_cmd;
+       int ret;
+       u8 oid = hdr->oid;
 
        umac_cmd.id = UMAC_CMD_OPCODE_WIFI_IF_WRAPPER;
        umac_cmd.resp = resp;
 
-       return iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd,
-                                    payload, payload_size);
+       ret = iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd,
+                                   payload, payload_size);
+
+       if (resp) {
+               ret = wait_event_interruptible_timeout(iwm->wifi_ntfy_queue,
+                                  test_and_clear_bit(oid, &iwm->wifi_ntfy[0]),
+                                  3 * HZ);
+
+               if (!ret)
+                       ret = -EBUSY;
+       }
+
+       return ret;
 }
 
 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)
                return ret;
        }
 
-       /* Wait for the profile to be active */
-       ret = wait_event_interruptible_timeout(iwm->mlme_queue,
-                                              iwm->umac_profile_active == 1,
-                                              3 * HZ);
-       if (!ret)
-               return -EBUSY;
-
-
        for (i = 0; i < IWM_NUM_KEYS; i++)
                if (iwm->keys[i].in_use) {
                        int default_key = 0;
@@ -778,8 +784,8 @@ int iwm_send_mlme_profile(struct iwm_priv *iwm)
 
 int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
 {
-       int ret;
        struct iwm_umac_invalidate_profile invalid;
+       int ret;
 
        invalid.hdr.oid = UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE;
        invalid.hdr.buf_size =
@@ -793,8 +799,7 @@ int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
                return ret;
 
        ret = wait_event_interruptible_timeout(iwm->mlme_queue,
-                                (iwm->umac_profile_active == 0),
-                                              2 * HZ);
+                               (iwm->umac_profile_active == 0), 2 * HZ);
        if (!ret)
                return -EBUSY;
 
index 77c339f8516c80ef008fa5f0bb26e47cda235cd3..d8d4ae2d91b0abf31d306b1840f01e54e6b82500 100644 (file)
@@ -278,6 +278,9 @@ struct iwm_priv {
        struct iwm_key keys[IWM_NUM_KEYS];
        struct iwm_key *default_key;
 
+       DECLARE_BITMAP(wifi_ntfy, WIFI_IF_NTFY_MAX);
+       wait_queue_head_t wifi_ntfy_queue;
+
        wait_queue_head_t mlme_queue;
 
        struct iw_statistics wstats;
index 8be206d58222b8411123395b54be29bd7a229437..844872213a122a12837df5eaee9d358fb29dde41 100644 (file)
@@ -191,6 +191,7 @@ int iwm_priv_init(struct iwm_priv *iwm)
        INIT_LIST_HEAD(&iwm->pending_notif);
        init_waitqueue_head(&iwm->notif_queue);
        init_waitqueue_head(&iwm->nonwifi_queue);
+       init_waitqueue_head(&iwm->wifi_ntfy_queue);
        init_waitqueue_head(&iwm->mlme_queue);
        memcpy(&iwm->conf, &def_iwm_conf, sizeof(struct iwm_conf));
        spin_lock_init(&iwm->tx_credit.lock);
index d73cf96c6dc6588b4a223f3099d090dbd0f91021..49a8be7c539604d7203dea1630f5de3125de66fa 100644 (file)
@@ -993,12 +993,17 @@ static int iwm_ntf_wifi_if_wrapper(struct iwm_priv *iwm, u8 *buf,
                        (struct iwm_umac_wifi_if *)cmd->buf.payload;
 
        IWM_DBG_NTF(iwm, DBG, "WIFI_IF_WRAPPER cmd is delivered to UMAC: "
-                   "oid is %d\n", hdr->oid);
+                   "oid is 0x%x\n", hdr->oid);
+
+       if (hdr->oid <= WIFI_IF_NTFY_MAX) {
+               set_bit(hdr->oid, &iwm->wifi_ntfy[0]);
+               wake_up_interruptible(&iwm->wifi_ntfy_queue);
+       } else
+               return -EINVAL;
 
        switch (hdr->oid) {
        case UMAC_WIFI_IF_CMD_SET_PROFILE:
                iwm->umac_profile_active = 1;
-               wake_up_interruptible(&iwm->mlme_queue);
                break;
        default:
                break;
index 4a95cce1f0a6b05cd1cbe85850d6731ee9e517ea..0af2a3c762818821c7d89ccbe9da9944efd9ca9c 100644 (file)
@@ -495,6 +495,8 @@ struct iwm_fw_alive_hdr {
 #define WIFI_DBG_IF_NTFY_COEX_HANDLE_ENVELOP           0xE8
 #define WIFI_DBG_IF_NTFY_COEX_HANDLE_RELEASE_ENVELOP   0xE9
 
+#define WIFI_IF_NTFY_MAX 0xff
+
 /* Notification structures */
 struct iwm_umac_notif_wifi_if {
        struct iwm_umac_wifi_in_hdr hdr;