]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/net/wireless/ath/ath9k/wmi.c
ath9k_htc: Use SKB's private area for TX parameters
[mv-sheeva.git] / drivers / net / wireless / ath / ath9k / wmi.c
index d3d24904f62f89d46ff270914f7946b9f43bdf5e..83d1e0e5dd8c3d25e53f80acc808468906c4b7d6 100644 (file)
@@ -23,20 +23,18 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
                return "WMI_ECHO_CMDID";
        case WMI_ACCESS_MEMORY_CMDID:
                return "WMI_ACCESS_MEMORY_CMDID";
+       case WMI_GET_FW_VERSION:
+               return "WMI_GET_FW_VERSION";
        case WMI_DISABLE_INTR_CMDID:
                return "WMI_DISABLE_INTR_CMDID";
        case WMI_ENABLE_INTR_CMDID:
                return "WMI_ENABLE_INTR_CMDID";
-       case WMI_RX_LINK_CMDID:
-               return "WMI_RX_LINK_CMDID";
        case WMI_ATH_INIT_CMDID:
                return "WMI_ATH_INIT_CMDID";
        case WMI_ABORT_TXQ_CMDID:
                return "WMI_ABORT_TXQ_CMDID";
        case WMI_STOP_TX_DMA_CMDID:
                return "WMI_STOP_TX_DMA_CMDID";
-       case WMI_STOP_DMA_RECV_CMDID:
-               return "WMI_STOP_DMA_RECV_CMDID";
        case WMI_ABORT_TX_DMA_CMDID:
                return "WMI_ABORT_TX_DMA_CMDID";
        case WMI_DRAIN_TXQ_CMDID:
@@ -51,8 +49,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
                return "WMI_FLUSH_RECV_CMDID";
        case WMI_SET_MODE_CMDID:
                return "WMI_SET_MODE_CMDID";
-       case WMI_RESET_CMDID:
-               return "WMI_RESET_CMDID";
        case WMI_NODE_CREATE_CMDID:
                return "WMI_NODE_CREATE_CMDID";
        case WMI_NODE_REMOVE_CMDID:
@@ -61,8 +57,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
                return "WMI_VAP_REMOVE_CMDID";
        case WMI_VAP_CREATE_CMDID:
                return "WMI_VAP_CREATE_CMDID";
-       case WMI_BEACON_UPDATE_CMDID:
-               return "WMI_BEACON_UPDATE_CMDID";
        case WMI_REG_READ_CMDID:
                return "WMI_REG_READ_CMDID";
        case WMI_REG_WRITE_CMDID:
@@ -71,10 +65,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
                return "WMI_RC_STATE_CHANGE_CMDID";
        case WMI_RC_RATE_UPDATE_CMDID:
                return "WMI_RC_RATE_UPDATE_CMDID";
-       case WMI_DEBUG_INFO_CMDID:
-               return "WMI_DEBUG_INFO_CMDID";
-       case WMI_HOST_ATTACH:
-               return "WMI_HOST_ATTACH";
        case WMI_TARGET_IC_UPDATE_CMDID:
                return "WMI_TARGET_IC_UPDATE_CMDID";
        case WMI_TGT_STATS_CMDID:
@@ -83,8 +73,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
                return "WMI_TX_AGGR_ENABLE_CMDID";
        case WMI_TGT_DETACH_CMDID:
                return "WMI_TGT_DETACH_CMDID";
-       case WMI_TGT_TXQ_ENABLE_CMDID:
-               return "WMI_TGT_TXQ_ENABLE_CMDID";
        case WMI_AGGR_LIMIT_CMD:
                return "WMI_AGGR_LIMIT_CMD";
        }
@@ -102,9 +90,12 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv)
 
        wmi->drv_priv = priv;
        wmi->stopped = false;
+       skb_queue_head_init(&wmi->wmi_event_queue);
        mutex_init(&wmi->op_mutex);
        mutex_init(&wmi->multi_write_mutex);
        init_completion(&wmi->cmd_wait);
+       tasklet_init(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet,
+                    (unsigned long)wmi);
 
        return wmi;
 }
@@ -120,11 +111,64 @@ void ath9k_deinit_wmi(struct ath9k_htc_priv *priv)
        kfree(priv->wmi);
 }
 
-void ath9k_swba_tasklet(unsigned long data)
+void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv)
 {
-       struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
+       unsigned long flags;
 
-       ath9k_htc_swba(priv, priv->wmi->beacon_pending);
+       tasklet_kill(&priv->wmi->wmi_event_tasklet);
+       spin_lock_irqsave(&priv->wmi->wmi_lock, flags);
+       __skb_queue_purge(&priv->wmi->wmi_event_queue);
+       spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags);
+}
+
+void ath9k_wmi_event_tasklet(unsigned long data)
+{
+       struct wmi *wmi = (struct wmi *)data;
+       struct ath9k_htc_priv *priv = wmi->drv_priv;
+       struct wmi_cmd_hdr *hdr;
+       void *wmi_event;
+       struct wmi_event_swba *swba;
+       struct sk_buff *skb = NULL;
+       unsigned long flags;
+       u16 cmd_id;
+#ifdef CONFIG_ATH9K_HTC_DEBUGFS
+       __be32 txrate;
+#endif
+
+       do {
+               spin_lock_irqsave(&wmi->wmi_lock, flags);
+               skb = __skb_dequeue(&wmi->wmi_event_queue);
+               if (!skb) {
+                       spin_unlock_irqrestore(&wmi->wmi_lock, flags);
+                       return;
+               }
+               spin_unlock_irqrestore(&wmi->wmi_lock, flags);
+
+               hdr = (struct wmi_cmd_hdr *) skb->data;
+               cmd_id = be16_to_cpu(hdr->command_id);
+               wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr));
+
+               switch (cmd_id) {
+               case WMI_SWBA_EVENTID:
+                       swba = (struct wmi_event_swba *) wmi_event;
+                       ath9k_htc_swba(priv, swba);
+                       break;
+               case WMI_FATAL_EVENTID:
+                       ieee80211_queue_work(wmi->drv_priv->hw,
+                                            &wmi->drv_priv->fatal_work);
+                       break;
+               case WMI_TXRATE_EVENTID:
+#ifdef CONFIG_ATH9K_HTC_DEBUGFS
+                       txrate = ((struct wmi_event_txrate *)wmi_event)->txrate;
+                       wmi->drv_priv->debug.txrate = be32_to_cpu(txrate);
+#endif
+                       break;
+               default:
+                       break;
+               }
+
+               kfree_skb(skb);
+       } while (1);
 }
 
 void ath9k_fatal_work(struct work_struct *work)
@@ -153,10 +197,6 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
        struct wmi *wmi = (struct wmi *) priv;
        struct wmi_cmd_hdr *hdr;
        u16 cmd_id;
-       void *wmi_event;
-#ifdef CONFIG_ATH9K_HTC_DEBUGFS
-       __be32 txrate;
-#endif
 
        if (unlikely(wmi->stopped))
                goto free_skb;
@@ -165,26 +205,10 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
        cmd_id = be16_to_cpu(hdr->command_id);
 
        if (cmd_id & 0x1000) {
-               wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr));
-               switch (cmd_id) {
-               case WMI_SWBA_EVENTID:
-                       wmi->beacon_pending = *(u8 *)wmi_event;
-                       tasklet_schedule(&wmi->drv_priv->swba_tasklet);
-                       break;
-               case WMI_FATAL_EVENTID:
-                       ieee80211_queue_work(wmi->drv_priv->hw,
-                                            &wmi->drv_priv->fatal_work);
-                       break;
-               case WMI_TXRATE_EVENTID:
-#ifdef CONFIG_ATH9K_HTC_DEBUGFS
-                       txrate = ((struct wmi_event_txrate *)wmi_event)->txrate;
-                       wmi->drv_priv->debug.txrate = be32_to_cpu(txrate);
-#endif
-                       break;
-               default:
-                       break;
-               }
-               kfree_skb(skb);
+               spin_lock(&wmi->wmi_lock);
+               __skb_queue_tail(&wmi->wmi_event_queue, skb);
+               spin_unlock(&wmi->wmi_lock);
+               tasklet_schedule(&wmi->wmi_event_tasklet);
                return;
        }
 
@@ -243,7 +267,7 @@ static int ath9k_wmi_cmd_issue(struct wmi *wmi,
        hdr->command_id = cpu_to_be16(cmd);
        hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id);
 
-       return htc_send(wmi->htc, skb, wmi->ctrl_epid, NULL);
+       return htc_send(wmi->htc, skb, wmi->ctrl_epid);
 }
 
 int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,