~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/net/wireless/ath/ath9k/wmi.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (c) 2010 Atheros Communications Inc.
 
2
 * Copyright (c) 2010-2011 Atheros Communications Inc.
3
3
 *
4
4
 * Permission to use, copy, modify, and/or distribute this software for any
5
5
 * purpose with or without fee is hereby granted, provided that the above
23
23
                return "WMI_ECHO_CMDID";
24
24
        case WMI_ACCESS_MEMORY_CMDID:
25
25
                return "WMI_ACCESS_MEMORY_CMDID";
 
26
        case WMI_GET_FW_VERSION:
 
27
                return "WMI_GET_FW_VERSION";
26
28
        case WMI_DISABLE_INTR_CMDID:
27
29
                return "WMI_DISABLE_INTR_CMDID";
28
30
        case WMI_ENABLE_INTR_CMDID:
29
31
                return "WMI_ENABLE_INTR_CMDID";
30
 
        case WMI_RX_LINK_CMDID:
31
 
                return "WMI_RX_LINK_CMDID";
32
32
        case WMI_ATH_INIT_CMDID:
33
33
                return "WMI_ATH_INIT_CMDID";
34
34
        case WMI_ABORT_TXQ_CMDID:
35
35
                return "WMI_ABORT_TXQ_CMDID";
36
36
        case WMI_STOP_TX_DMA_CMDID:
37
37
                return "WMI_STOP_TX_DMA_CMDID";
38
 
        case WMI_STOP_DMA_RECV_CMDID:
39
 
                return "WMI_STOP_DMA_RECV_CMDID";
40
38
        case WMI_ABORT_TX_DMA_CMDID:
41
39
                return "WMI_ABORT_TX_DMA_CMDID";
42
40
        case WMI_DRAIN_TXQ_CMDID:
51
49
                return "WMI_FLUSH_RECV_CMDID";
52
50
        case WMI_SET_MODE_CMDID:
53
51
                return "WMI_SET_MODE_CMDID";
54
 
        case WMI_RESET_CMDID:
55
 
                return "WMI_RESET_CMDID";
56
52
        case WMI_NODE_CREATE_CMDID:
57
53
                return "WMI_NODE_CREATE_CMDID";
58
54
        case WMI_NODE_REMOVE_CMDID:
61
57
                return "WMI_VAP_REMOVE_CMDID";
62
58
        case WMI_VAP_CREATE_CMDID:
63
59
                return "WMI_VAP_CREATE_CMDID";
64
 
        case WMI_BEACON_UPDATE_CMDID:
65
 
                return "WMI_BEACON_UPDATE_CMDID";
66
60
        case WMI_REG_READ_CMDID:
67
61
                return "WMI_REG_READ_CMDID";
68
62
        case WMI_REG_WRITE_CMDID:
71
65
                return "WMI_RC_STATE_CHANGE_CMDID";
72
66
        case WMI_RC_RATE_UPDATE_CMDID:
73
67
                return "WMI_RC_RATE_UPDATE_CMDID";
74
 
        case WMI_DEBUG_INFO_CMDID:
75
 
                return "WMI_DEBUG_INFO_CMDID";
76
 
        case WMI_HOST_ATTACH:
77
 
                return "WMI_HOST_ATTACH";
78
68
        case WMI_TARGET_IC_UPDATE_CMDID:
79
69
                return "WMI_TARGET_IC_UPDATE_CMDID";
80
 
        case WMI_TGT_STATS_CMDID:
81
 
                return "WMI_TGT_STATS_CMDID";
82
70
        case WMI_TX_AGGR_ENABLE_CMDID:
83
71
                return "WMI_TX_AGGR_ENABLE_CMDID";
84
72
        case WMI_TGT_DETACH_CMDID:
85
73
                return "WMI_TGT_DETACH_CMDID";
86
 
        case WMI_TGT_TXQ_ENABLE_CMDID:
87
 
                return "WMI_TGT_TXQ_ENABLE_CMDID";
88
 
        case WMI_AGGR_LIMIT_CMD:
89
 
                return "WMI_AGGR_LIMIT_CMD";
 
74
        case WMI_NODE_UPDATE_CMDID:
 
75
                return "WMI_NODE_UPDATE_CMDID";
 
76
        case WMI_INT_STATS_CMDID:
 
77
                return "WMI_INT_STATS_CMDID";
 
78
        case WMI_TX_STATS_CMDID:
 
79
                return "WMI_TX_STATS_CMDID";
 
80
        case WMI_RX_STATS_CMDID:
 
81
                return "WMI_RX_STATS_CMDID";
 
82
        case WMI_BITRATE_MASK_CMDID:
 
83
                return "WMI_BITRATE_MASK_CMDID";
90
84
        }
91
85
 
92
86
        return "Bogus";
102
96
 
103
97
        wmi->drv_priv = priv;
104
98
        wmi->stopped = false;
 
99
        skb_queue_head_init(&wmi->wmi_event_queue);
 
100
        spin_lock_init(&wmi->wmi_lock);
 
101
        spin_lock_init(&wmi->event_lock);
105
102
        mutex_init(&wmi->op_mutex);
106
103
        mutex_init(&wmi->multi_write_mutex);
107
104
        init_completion(&wmi->cmd_wait);
 
105
        INIT_LIST_HEAD(&wmi->pending_tx_events);
 
106
        tasklet_init(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet,
 
107
                     (unsigned long)wmi);
108
108
 
109
109
        return wmi;
110
110
}
120
120
        kfree(priv->wmi);
121
121
}
122
122
 
123
 
void ath9k_swba_tasklet(unsigned long data)
124
 
{
125
 
        struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
126
 
        struct ath_common *common = ath9k_hw_common(priv->ah);
127
 
 
128
 
        ath_dbg(common, ATH_DBG_WMI, "SWBA Event received\n");
129
 
 
130
 
        ath9k_htc_swba(priv, priv->wmi->beacon_pending);
131
 
 
 
123
void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv)
 
124
{
 
125
        unsigned long flags;
 
126
 
 
127
        tasklet_kill(&priv->wmi->wmi_event_tasklet);
 
128
        spin_lock_irqsave(&priv->wmi->wmi_lock, flags);
 
129
        __skb_queue_purge(&priv->wmi->wmi_event_queue);
 
130
        spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags);
 
131
}
 
132
 
 
133
void ath9k_wmi_event_tasklet(unsigned long data)
 
134
{
 
135
        struct wmi *wmi = (struct wmi *)data;
 
136
        struct ath9k_htc_priv *priv = wmi->drv_priv;
 
137
        struct wmi_cmd_hdr *hdr;
 
138
        void *wmi_event;
 
139
        struct wmi_event_swba *swba;
 
140
        struct sk_buff *skb = NULL;
 
141
        unsigned long flags;
 
142
        u16 cmd_id;
 
143
 
 
144
        do {
 
145
                spin_lock_irqsave(&wmi->wmi_lock, flags);
 
146
                skb = __skb_dequeue(&wmi->wmi_event_queue);
 
147
                if (!skb) {
 
148
                        spin_unlock_irqrestore(&wmi->wmi_lock, flags);
 
149
                        return;
 
150
                }
 
151
                spin_unlock_irqrestore(&wmi->wmi_lock, flags);
 
152
 
 
153
                hdr = (struct wmi_cmd_hdr *) skb->data;
 
154
                cmd_id = be16_to_cpu(hdr->command_id);
 
155
                wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr));
 
156
 
 
157
                switch (cmd_id) {
 
158
                case WMI_SWBA_EVENTID:
 
159
                        swba = (struct wmi_event_swba *) wmi_event;
 
160
                        ath9k_htc_swba(priv, swba);
 
161
                        break;
 
162
                case WMI_FATAL_EVENTID:
 
163
                        ieee80211_queue_work(wmi->drv_priv->hw,
 
164
                                             &wmi->drv_priv->fatal_work);
 
165
                        break;
 
166
                case WMI_TXSTATUS_EVENTID:
 
167
                        spin_lock_bh(&priv->tx.tx_lock);
 
168
                        if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) {
 
169
                                spin_unlock_bh(&priv->tx.tx_lock);
 
170
                                break;
 
171
                        }
 
172
                        spin_unlock_bh(&priv->tx.tx_lock);
 
173
 
 
174
                        ath9k_htc_txstatus(priv, wmi_event);
 
175
                        break;
 
176
                default:
 
177
                        break;
 
178
                }
 
179
 
 
180
                kfree_skb(skb);
 
181
        } while (1);
132
182
}
133
183
 
134
184
void ath9k_fatal_work(struct work_struct *work)
157
207
        struct wmi *wmi = (struct wmi *) priv;
158
208
        struct wmi_cmd_hdr *hdr;
159
209
        u16 cmd_id;
160
 
        void *wmi_event;
161
 
#ifdef CONFIG_ATH9K_HTC_DEBUGFS
162
 
        __be32 txrate;
163
 
#endif
164
210
 
165
211
        if (unlikely(wmi->stopped))
166
212
                goto free_skb;
169
215
        cmd_id = be16_to_cpu(hdr->command_id);
170
216
 
171
217
        if (cmd_id & 0x1000) {
172
 
                wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr));
173
 
                switch (cmd_id) {
174
 
                case WMI_SWBA_EVENTID:
175
 
                        wmi->beacon_pending = *(u8 *)wmi_event;
176
 
                        tasklet_schedule(&wmi->drv_priv->swba_tasklet);
177
 
                        break;
178
 
                case WMI_FATAL_EVENTID:
179
 
                        ieee80211_queue_work(wmi->drv_priv->hw,
180
 
                                             &wmi->drv_priv->fatal_work);
181
 
                        break;
182
 
                case WMI_TXRATE_EVENTID:
183
 
#ifdef CONFIG_ATH9K_HTC_DEBUGFS
184
 
                        txrate = ((struct wmi_event_txrate *)wmi_event)->txrate;
185
 
                        wmi->drv_priv->debug.txrate = be32_to_cpu(txrate);
186
 
#endif
187
 
                        break;
188
 
                default:
189
 
                        break;
190
 
                }
191
 
                kfree_skb(skb);
 
218
                spin_lock(&wmi->wmi_lock);
 
219
                __skb_queue_tail(&wmi->wmi_event_queue, skb);
 
220
                spin_unlock(&wmi->wmi_lock);
 
221
                tasklet_schedule(&wmi->wmi_event_tasklet);
192
222
                return;
193
223
        }
194
224
 
247
277
        hdr->command_id = cpu_to_be16(cmd);
248
278
        hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id);
249
279
 
250
 
        return htc_send(wmi->htc, skb, wmi->ctrl_epid, NULL);
 
280
        return htc_send_epid(wmi->htc, skb, wmi->ctrl_epid);
251
281
}
252
282
 
253
283
int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,