]> Pileus Git - ~andy/linux/commitdiff
iwlwifi: move ucode notification from iwl_priv to iwl_shared
authorDon Fry <donald.h.fry@intel.com>
Fri, 2 Dec 2011 16:48:40 +0000 (08:48 -0800)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 6 Dec 2011 21:07:07 +0000 (16:07 -0500)
Move the notification structures for ucode operations from the
iwl_priv structure to the iwl_shared structure, with associated
code changes.

Signed-off-by: Don Fry <donald.h.fry@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/iwlwifi/iwl-agn-rx.c
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
drivers/net/wireless/iwlwifi/iwl-agn.h
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-shared.h
drivers/net/wireless/iwlwifi/iwl-testmode.c
drivers/net/wireless/iwlwifi/iwl-ucode.c

index 0bc9622173510580b27892737b4ca03fad74ab52..575d1bb8e8cc4b1ab91f9797a452a0afdda7181e 100644 (file)
@@ -934,57 +934,6 @@ u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid)
        return ant;
 }
 
-/* notification wait support */
-void iwlagn_init_notification_wait(struct iwl_priv *priv,
-                                  struct iwl_notification_wait *wait_entry,
-                                  u8 cmd,
-                                  void (*fn)(struct iwl_priv *priv,
-                                             struct iwl_rx_packet *pkt,
-                                             void *data),
-                                  void *fn_data)
-{
-       wait_entry->fn = fn;
-       wait_entry->fn_data = fn_data;
-       wait_entry->cmd = cmd;
-       wait_entry->triggered = false;
-       wait_entry->aborted = false;
-
-       spin_lock_bh(&priv->notif_wait_lock);
-       list_add(&wait_entry->list, &priv->notif_waits);
-       spin_unlock_bh(&priv->notif_wait_lock);
-}
-
-int iwlagn_wait_notification(struct iwl_priv *priv,
-                            struct iwl_notification_wait *wait_entry,
-                            unsigned long timeout)
-{
-       int ret;
-
-       ret = wait_event_timeout(priv->notif_waitq,
-                                wait_entry->triggered || wait_entry->aborted,
-                                timeout);
-
-       spin_lock_bh(&priv->notif_wait_lock);
-       list_del(&wait_entry->list);
-       spin_unlock_bh(&priv->notif_wait_lock);
-
-       if (wait_entry->aborted)
-               return -EIO;
-
-       /* return value is always >= 0 */
-       if (ret <= 0)
-               return -ETIMEDOUT;
-       return 0;
-}
-
-void iwlagn_remove_notification(struct iwl_priv *priv,
-                               struct iwl_notification_wait *wait_entry)
-{
-       spin_lock_bh(&priv->notif_wait_lock);
-       list_del(&wait_entry->list);
-       spin_unlock_bh(&priv->notif_wait_lock);
-}
-
 #ifdef CONFIG_PM_SLEEP
 static void iwlagn_convert_p1k(u16 *p1k, __le16 *out)
 {
index 087fd52e572704a615fb35b4a10306b738cc1226..90c55ea4cc39a05309f909a1c3986acf5b04c7a0 100644 (file)
@@ -1131,9 +1131,9 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
        priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx;
 
        /* set up notification wait support */
-       spin_lock_init(&priv->notif_wait_lock);
-       INIT_LIST_HEAD(&priv->notif_waits);
-       init_waitqueue_head(&priv->notif_waitq);
+       spin_lock_init(&priv->shrd->notif_wait_lock);
+       INIT_LIST_HEAD(&priv->shrd->notif_waits);
+       init_waitqueue_head(&priv->shrd->notif_waitq);
 
        /* Set up BT Rx handlers */
        if (priv->cfg->lib->bt_rx_handler_setup)
@@ -1152,11 +1152,11 @@ int iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
         * even if the RX handler consumes the RXB we have
         * access to it in the notification wait entry.
         */
-       if (!list_empty(&priv->notif_waits)) {
+       if (!list_empty(&priv->shrd->notif_waits)) {
                struct iwl_notification_wait *w;
 
-               spin_lock(&priv->notif_wait_lock);
-               list_for_each_entry(w, &priv->notif_waits, list) {
+               spin_lock(&priv->shrd->notif_wait_lock);
+               list_for_each_entry(w, &priv->shrd->notif_waits, list) {
                        if (w->cmd != pkt->hdr.cmd)
                                continue;
                        IWL_DEBUG_RX(priv,
@@ -1167,9 +1167,9 @@ int iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
                        if (w->fn)
                                w->fn(priv, pkt, w->fn_data);
                }
-               spin_unlock(&priv->notif_wait_lock);
+               spin_unlock(&priv->shrd->notif_wait_lock);
 
-               wake_up_all(&priv->notif_waitq);
+               wake_up_all(&priv->shrd->notif_waitq);
        }
 
        if (priv->pre_rx_handler)
index 00b38711c15deed0be3715c792c0d6994893ca89..466e4ab544f7b7bb4379e598342b6c75d5833aef 100644 (file)
@@ -60,7 +60,7 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
        u8 old_dev_type = send->dev_type;
        int ret;
 
-       iwlagn_init_notification_wait(priv, &disable_wait,
+       iwl_init_notification_wait(priv->shrd, &disable_wait,
                                      REPLY_WIPAN_DEACTIVATION_COMPLETE,
                                      NULL, NULL);
 
@@ -74,9 +74,9 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
 
        if (ret) {
                IWL_ERR(priv, "Error disabling PAN (%d)\n", ret);
-               iwlagn_remove_notification(priv, &disable_wait);
+               iwl_remove_notification(priv->shrd, &disable_wait);
        } else {
-               ret = iwlagn_wait_notification(priv, &disable_wait, HZ);
+               ret = iwl_wait_notification(priv->shrd, &disable_wait, HZ);
                if (ret)
                        IWL_ERR(priv, "Timed out waiting for PAN disable\n");
        }
index 0db0a8fb56794efa577f98e0b2b78823a69bdcb2..f2f10702754d1f467da6f6a3514eaf305bda13b6 100644 (file)
@@ -356,22 +356,6 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
 void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv);
 void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac);
 
-/* notification wait support */
-void __acquires(wait_entry)
-iwlagn_init_notification_wait(struct iwl_priv *priv,
-                             struct iwl_notification_wait *wait_entry,
-                             u8 cmd,
-                             void (*fn)(struct iwl_priv *priv,
-                                        struct iwl_rx_packet *pkt,
-                                        void *data),
-                             void *fn_data);
-int __must_check __releases(wait_entry)
-iwlagn_wait_notification(struct iwl_priv *priv,
-                        struct iwl_notification_wait *wait_entry,
-                        unsigned long timeout);
-void __releases(wait_entry)
-iwlagn_remove_notification(struct iwl_priv *priv,
-                          struct iwl_notification_wait *wait_entry);
 extern int iwlagn_init_alive_start(struct iwl_priv *priv);
 extern int iwl_alive_start(struct iwl_priv *priv);
 /* svtool */
index b24623b3bdb3841b3c6ed7b9425d39ce7c10bc7d..3b6f48bfe0e396b21482bcb626d1598d69b721bc 100644 (file)
@@ -836,19 +836,6 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv,
 }
 #endif
 
-static void iwlagn_abort_notification_waits(struct iwl_priv *priv)
-{
-       unsigned long flags;
-       struct iwl_notification_wait *wait_entry;
-
-       spin_lock_irqsave(&priv->notif_wait_lock, flags);
-       list_for_each_entry(wait_entry, &priv->notif_waits, list)
-               wait_entry->aborted = true;
-       spin_unlock_irqrestore(&priv->notif_wait_lock, flags);
-
-       wake_up_all(&priv->notif_waitq);
-}
-
 void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
 {
        unsigned int reload_msec;
@@ -860,7 +847,7 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
        /* Cancel currently queued command. */
        clear_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status);
 
-       iwlagn_abort_notification_waits(priv);
+       iwl_abort_notification_waits(priv->shrd);
 
        /* Keep the restart process from trying to send host
         * commands by clearing the ready bit */
index 0019a23d6d49154a0e01e3447ad3d316796d706f..6f6a647d34f6003149fc7daddcbae4972a71b91c 100644 (file)
@@ -689,35 +689,6 @@ struct iwl_force_reset {
  */
 #define IWLAGN_EXT_BEACON_TIME_POS     22
 
-/**
- * struct iwl_notification_wait - notification wait entry
- * @list: list head for global list
- * @fn: function called with the notification
- * @cmd: command ID
- *
- * This structure is not used directly, to wait for a
- * notification declare it on the stack, and call
- * iwlagn_init_notification_wait() with appropriate
- * parameters. Then do whatever will cause the ucode
- * to notify the driver, and to wait for that then
- * call iwlagn_wait_notification().
- *
- * Each notification is one-shot. If at some point we
- * need to support multi-shot notifications (which
- * can't be allocated on the stack) we need to modify
- * the code for them.
- */
-struct iwl_notification_wait {
-       struct list_head list;
-
-       void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt,
-                  void *data);
-       void *fn_data;
-
-       u8 cmd;
-       bool triggered, aborted;
-};
-
 struct iwl_rxon_context {
        struct ieee80211_vif *vif;
 
@@ -992,10 +963,6 @@ struct iwl_priv {
        /* counts reply_tx error */
        struct reply_tx_error_statistics reply_tx_stats;
        struct reply_agg_tx_error_statistics reply_agg_tx_stats;
-       /* notification wait support */
-       struct list_head notif_waits;
-       spinlock_t notif_wait_lock;
-       wait_queue_head_t notif_waitq;
 
        /* remain-on-channel offload support */
        struct ieee80211_channel *hw_roc_channel;
index aa4905a2e7942238d62f43cc76e134cc1154a975..39aa9cf5b847353fa2542ad30f8c8a829c668eef 100644 (file)
@@ -273,6 +273,35 @@ enum iwl_ucode_type {
        IWL_UCODE_WOWLAN,
 };
 
+/**
+ * struct iwl_notification_wait - notification wait entry
+ * @list: list head for global list
+ * @fn: function called with the notification
+ * @cmd: command ID
+ *
+ * This structure is not used directly, to wait for a
+ * notification declare it on the stack, and call
+ * iwlagn_init_notification_wait() with appropriate
+ * parameters. Then do whatever will cause the ucode
+ * to notify the driver, and to wait for that then
+ * call iwlagn_wait_notification().
+ *
+ * Each notification is one-shot. If at some point we
+ * need to support multi-shot notifications (which
+ * can't be allocated on the stack) we need to modify
+ * the code for them.
+ */
+struct iwl_notification_wait {
+       struct list_head list;
+
+       void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt,
+                  void *data);
+       void *fn_data;
+
+       u8 cmd;
+       bool triggered, aborted;
+};
+
 /**
  * struct iwl_shared - shared fields for all the layers of the driver
  *
@@ -290,6 +319,10 @@ enum iwl_ucode_type {
  * @sta_lock: protects the station table.
  *     If lock and sta_lock are needed, lock must be acquired first.
  * @mutex:
+ * @ucode_type: indicator of loaded ucode image
+ * @notif_waits: things waiting for notification
+ * @notif_wait_lock: lock protecting notification
+ * @notif_waitq: head of notification wait queue
  */
 struct iwl_shared {
 #ifdef CONFIG_IWLWIFI_DEBUG
@@ -320,6 +353,11 @@ struct iwl_shared {
 
        /* ucode related variables */
        enum iwl_ucode_type ucode_type;
+
+       /* notification wait support */
+       struct list_head notif_waits;
+       spinlock_t notif_wait_lock;
+       wait_queue_head_t notif_waitq;
 };
 
 /*Whatever _m is (iwl_trans, iwl_priv, iwl_bus, these macros will work */
@@ -463,6 +501,24 @@ bool iwl_check_for_ct_kill(struct iwl_priv *priv);
 void iwl_stop_sw_queue(struct iwl_priv *priv, u8 ac);
 void iwl_wake_sw_queue(struct iwl_priv *priv, u8 ac);
 
+/* notification wait support */
+void iwl_abort_notification_waits(struct iwl_shared *shrd);
+void __acquires(wait_entry)
+iwl_init_notification_wait(struct iwl_shared *shrd,
+                             struct iwl_notification_wait *wait_entry,
+                             u8 cmd,
+                             void (*fn)(struct iwl_priv *priv,
+                                        struct iwl_rx_packet *pkt,
+                                        void *data),
+                             void *fn_data);
+int __must_check __releases(wait_entry)
+iwl_wait_notification(struct iwl_shared *shrd,
+                        struct iwl_notification_wait *wait_entry,
+                        unsigned long timeout);
+void __releases(wait_entry)
+iwl_remove_notification(struct iwl_shared *shrd,
+                          struct iwl_notification_wait *wait_entry);
+
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 void iwl_reset_traffic_log(struct iwl_priv *priv);
 #endif /* CONFIG_IWLWIFI_DEBUGFS */
index ed2a3d749b1b681587a3b91fb3e8e036db4a095a..ff72dbcfd52d66dbd73714e1b982c072eaea0741 100644 (file)
@@ -373,7 +373,7 @@ static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv)
        struct iwl_notification_wait calib_wait;
        int ret;
 
-       iwlagn_init_notification_wait(priv, &calib_wait,
+       iwl_init_notification_wait(priv->shrd, &calib_wait,
                                      CALIBRATION_COMPLETE_NOTIFICATION,
                                      NULL, NULL);
        ret = iwlagn_init_alive_start(priv);
@@ -383,14 +383,14 @@ static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv)
                goto cfg_init_calib_error;
        }
 
-       ret = iwlagn_wait_notification(priv, &calib_wait, 2 * HZ);
+       ret = iwl_wait_notification(priv->shrd, &calib_wait, 2 * HZ);
        if (ret)
                IWL_DEBUG_INFO(priv, "Error detecting"
                        " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret);
        return ret;
 
 cfg_init_calib_error:
-       iwlagn_remove_notification(priv, &calib_wait);
+       iwl_remove_notification(priv->shrd, &calib_wait);
        return ret;
 }
 
index 1b23b99c474c57bfa6b04ec94994e16c6bcddcca..b365de457b1bd33245ac23214182d231b6db2526 100644 (file)
@@ -571,6 +571,70 @@ static void iwl_alive_fn(struct iwl_priv *priv,
        alive_data->valid = palive->is_valid == UCODE_VALID_OK;
 }
 
+/* notification wait support */
+void iwl_init_notification_wait(struct iwl_shared *shrd,
+                                  struct iwl_notification_wait *wait_entry,
+                                  u8 cmd,
+                                  void (*fn)(struct iwl_priv *priv,
+                                             struct iwl_rx_packet *pkt,
+                                             void *data),
+                                  void *fn_data)
+{
+       wait_entry->fn = fn;
+       wait_entry->fn_data = fn_data;
+       wait_entry->cmd = cmd;
+       wait_entry->triggered = false;
+       wait_entry->aborted = false;
+
+       spin_lock_bh(&shrd->notif_wait_lock);
+       list_add(&wait_entry->list, &shrd->notif_waits);
+       spin_unlock_bh(&shrd->notif_wait_lock);
+}
+
+int iwl_wait_notification(struct iwl_shared *shrd,
+                            struct iwl_notification_wait *wait_entry,
+                            unsigned long timeout)
+{
+       int ret;
+
+       ret = wait_event_timeout(shrd->notif_waitq,
+                                wait_entry->triggered || wait_entry->aborted,
+                                timeout);
+
+       spin_lock_bh(&shrd->notif_wait_lock);
+       list_del(&wait_entry->list);
+       spin_unlock_bh(&shrd->notif_wait_lock);
+
+       if (wait_entry->aborted)
+               return -EIO;
+
+       /* return value is always >= 0 */
+       if (ret <= 0)
+               return -ETIMEDOUT;
+       return 0;
+}
+
+void iwl_remove_notification(struct iwl_shared *shrd,
+                               struct iwl_notification_wait *wait_entry)
+{
+       spin_lock_bh(&shrd->notif_wait_lock);
+       list_del(&wait_entry->list);
+       spin_unlock_bh(&shrd->notif_wait_lock);
+}
+
+void iwl_abort_notification_waits(struct iwl_shared *shrd)
+{
+       unsigned long flags;
+       struct iwl_notification_wait *wait_entry;
+
+       spin_lock_irqsave(&shrd->notif_wait_lock, flags);
+       list_for_each_entry(wait_entry, &shrd->notif_waits, list)
+               wait_entry->aborted = true;
+       spin_unlock_irqrestore(&shrd->notif_wait_lock, flags);
+
+       wake_up_all(&shrd->notif_waitq);
+}
+
 #define UCODE_ALIVE_TIMEOUT    HZ
 #define UCODE_CALIB_TIMEOUT    (2*HZ)
 
@@ -587,7 +651,7 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
        if (ret)
                return ret;
 
-       iwlagn_init_notification_wait(priv, &alive_wait, REPLY_ALIVE,
+       iwl_init_notification_wait(trans->shrd, &alive_wait, REPLY_ALIVE,
                                      iwl_alive_fn, &alive_data);
 
        old_type = trans->shrd->ucode_type;
@@ -596,7 +660,7 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
        ret = iwl_load_given_ucode(trans, ucode_type);
        if (ret) {
                trans->shrd->ucode_type = old_type;
-               iwlagn_remove_notification(priv, &alive_wait);
+               iwl_remove_notification(trans->shrd, &alive_wait);
                return ret;
        }
 
@@ -606,7 +670,8 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
         * Some things may run in the background now, but we
         * just wait for the ALIVE notification here.
         */
-       ret = iwlagn_wait_notification(priv, &alive_wait, UCODE_ALIVE_TIMEOUT);
+       ret = iwl_wait_notification(trans->shrd, &alive_wait,
+                                       UCODE_ALIVE_TIMEOUT);
        if (ret) {
                trans->shrd->ucode_type = old_type;
                return ret;
@@ -659,7 +724,7 @@ int iwlagn_run_init_ucode(struct iwl_priv *priv)
        if (priv->shrd->ucode_type != IWL_UCODE_NONE)
                return 0;
 
-       iwlagn_init_notification_wait(priv, &calib_wait,
+       iwl_init_notification_wait(priv->shrd, &calib_wait,
                                      CALIBRATION_COMPLETE_NOTIFICATION,
                                      NULL, NULL);
 
@@ -676,12 +741,13 @@ int iwlagn_run_init_ucode(struct iwl_priv *priv)
         * Some things may run in the background now, but we
         * just wait for the calibration complete notification.
         */
-       ret = iwlagn_wait_notification(priv, &calib_wait, UCODE_CALIB_TIMEOUT);
+       ret = iwl_wait_notification(priv->shrd, &calib_wait,
+                                       UCODE_CALIB_TIMEOUT);
 
        goto out;
 
  error:
-       iwlagn_remove_notification(priv, &calib_wait);
+       iwl_remove_notification(priv->shrd, &calib_wait);
  out:
        /* Whatever happened, stop the device */
        iwl_trans_stop_device(trans(priv));