hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/drivers/net/wireless/ath/ath9k/wmi.c
....@@ -106,8 +106,7 @@
106106 mutex_init(&wmi->multi_rmw_mutex);
107107 init_completion(&wmi->cmd_wait);
108108 INIT_LIST_HEAD(&wmi->pending_tx_events);
109
- tasklet_init(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet,
110
- (unsigned long)wmi);
109
+ tasklet_setup(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet);
111110
112111 return wmi;
113112 }
....@@ -121,7 +120,7 @@
121120 mutex_unlock(&wmi->op_mutex);
122121 }
123122
124
-void ath9k_destoy_wmi(struct ath9k_htc_priv *priv)
123
+void ath9k_destroy_wmi(struct ath9k_htc_priv *priv)
125124 {
126125 kfree(priv->wmi);
127126 }
....@@ -136,9 +135,9 @@
136135 spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags);
137136 }
138137
139
-void ath9k_wmi_event_tasklet(unsigned long data)
138
+void ath9k_wmi_event_tasklet(struct tasklet_struct *t)
140139 {
141
- struct wmi *wmi = (struct wmi *)data;
140
+ struct wmi *wmi = from_tasklet(wmi, t, wmi_event_tasklet);
142141 struct ath9k_htc_priv *priv = wmi->drv_priv;
143142 struct wmi_cmd_hdr *hdr;
144143 void *wmi_event;
....@@ -170,6 +169,10 @@
170169 &wmi->drv_priv->fatal_work);
171170 break;
172171 case WMI_TXSTATUS_EVENTID:
172
+ /* Check if ath9k_tx_init() completed. */
173
+ if (!data_race(priv->tx.initialized))
174
+ break;
175
+
173176 spin_lock_bh(&priv->tx.tx_lock);
174177 if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) {
175178 spin_unlock_bh(&priv->tx.tx_lock);
....@@ -218,6 +221,10 @@
218221 if (unlikely(wmi->stopped))
219222 goto free_skb;
220223
224
+ /* Validate the obtained SKB. */
225
+ if (unlikely(skb->len < sizeof(struct wmi_cmd_hdr)))
226
+ goto free_skb;
227
+
221228 hdr = (struct wmi_cmd_hdr *) skb->data;
222229 cmd_id = be16_to_cpu(hdr->command_id);
223230
....@@ -235,10 +242,10 @@
235242 spin_unlock_irqrestore(&wmi->wmi_lock, flags);
236243 goto free_skb;
237244 }
238
- spin_unlock_irqrestore(&wmi->wmi_lock, flags);
239245
240246 /* WMI command response */
241247 ath9k_wmi_rsp_callback(wmi, skb);
248
+ spin_unlock_irqrestore(&wmi->wmi_lock, flags);
242249
243250 free_skb:
244251 kfree_skb(skb);
....@@ -276,7 +283,8 @@
276283
277284 static int ath9k_wmi_cmd_issue(struct wmi *wmi,
278285 struct sk_buff *skb,
279
- enum wmi_cmd_id cmd, u16 len)
286
+ enum wmi_cmd_id cmd, u16 len,
287
+ u8 *rsp_buf, u32 rsp_len)
280288 {
281289 struct wmi_cmd_hdr *hdr;
282290 unsigned long flags;
....@@ -286,6 +294,11 @@
286294 hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id);
287295
288296 spin_lock_irqsave(&wmi->wmi_lock, flags);
297
+
298
+ /* record the rsp buffer and length */
299
+ wmi->cmd_rsp_buf = rsp_buf;
300
+ wmi->cmd_rsp_len = rsp_len;
301
+
289302 wmi->last_seq_id = wmi->tx_seq_id;
290303 spin_unlock_irqrestore(&wmi->wmi_lock, flags);
291304
....@@ -301,8 +314,8 @@
301314 struct ath_common *common = ath9k_hw_common(ah);
302315 u16 headroom = sizeof(struct htc_frame_hdr) +
303316 sizeof(struct wmi_cmd_hdr);
317
+ unsigned long time_left, flags;
304318 struct sk_buff *skb;
305
- unsigned long time_left;
306319 int ret = 0;
307320
308321 if (ah->ah_flags & AH_UNPLUGGED)
....@@ -326,11 +339,7 @@
326339 goto out;
327340 }
328341
329
- /* record the rsp buffer and length */
330
- wmi->cmd_rsp_buf = rsp_buf;
331
- wmi->cmd_rsp_len = rsp_len;
332
-
333
- ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len);
342
+ ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len, rsp_buf, rsp_len);
334343 if (ret)
335344 goto out;
336345
....@@ -338,8 +347,10 @@
338347 if (!time_left) {
339348 ath_dbg(common, WMI, "Timeout waiting for WMI command: %s\n",
340349 wmi_cmd_to_name(cmd_id));
350
+ spin_lock_irqsave(&wmi->wmi_lock, flags);
351
+ wmi->last_seq_id = 0;
352
+ spin_unlock_irqrestore(&wmi->wmi_lock, flags);
341353 mutex_unlock(&wmi->op_mutex);
342
- kfree_skb(skb);
343354 return -ETIMEDOUT;
344355 }
345356