]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/net/wireless/ath/carl9170/rx.c
carl9170: common error path for bad frames
[net-next-2.6.git] / drivers / net / wireless / ath / carl9170 / rx.c
1 /*
2  * Atheros CARL9170 driver
3  *
4  * 802.11 & command trap routines
5  *
6  * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7  * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; see the file COPYING.  If not, see
21  * http://www.gnu.org/licenses/.
22  *
23  * This file incorporates work covered by the following copyright and
24  * permission notice:
25  *    Copyright (c) 2007-2008 Atheros Communications, Inc.
26  *
27  *    Permission to use, copy, modify, and/or distribute this software for any
28  *    purpose with or without fee is hereby granted, provided that the above
29  *    copyright notice and this permission notice appear in all copies.
30  *
31  *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
32  *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
33  *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
34  *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
35  *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
36  *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
37  *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
38  */
39
40 #include <linux/init.h>
41 #include <linux/slab.h>
42 #include <linux/module.h>
43 #include <linux/etherdevice.h>
44 #include <linux/crc32.h>
45 #include <net/mac80211.h>
46 #include "carl9170.h"
47 #include "hw.h"
48 #include "cmd.h"
49
50 static void carl9170_dbg_message(struct ar9170 *ar, const char *buf, u32 len)
51 {
52         bool restart = false;
53         enum carl9170_restart_reasons reason = CARL9170_RR_NO_REASON;
54
55         if (len > 3) {
56                 if (memcmp(buf, CARL9170_ERR_MAGIC, 3) == 0) {
57                         ar->fw.err_counter++;
58                         if (ar->fw.err_counter > 3) {
59                                 restart = true;
60                                 reason = CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS;
61                         }
62                 }
63
64                 if (memcmp(buf, CARL9170_BUG_MAGIC, 3) == 0) {
65                         ar->fw.bug_counter++;
66                         restart = true;
67                         reason = CARL9170_RR_FATAL_FIRMWARE_ERROR;
68                 }
69         }
70
71         wiphy_info(ar->hw->wiphy, "FW: %.*s\n", len, buf);
72
73         if (restart)
74                 carl9170_restart(ar, reason);
75 }
76
77 static void carl9170_handle_ps(struct ar9170 *ar, struct carl9170_rsp *rsp)
78 {
79         u32 ps;
80         bool new_ps;
81
82         ps = le32_to_cpu(rsp->psm.state);
83
84         new_ps = (ps & CARL9170_PSM_COUNTER) != CARL9170_PSM_WAKE;
85         if (ar->ps.state != new_ps) {
86                 if (!new_ps) {
87                         ar->ps.sleep_ms = jiffies_to_msecs(jiffies -
88                                 ar->ps.last_action);
89                 }
90
91                 ar->ps.last_action = jiffies;
92
93                 ar->ps.state = new_ps;
94         }
95 }
96
97 static int carl9170_check_sequence(struct ar9170 *ar, unsigned int seq)
98 {
99         if (ar->cmd_seq < -1)
100                 return 0;
101
102         /*
103          * Initialize Counter
104          */
105         if (ar->cmd_seq < 0)
106                 ar->cmd_seq = seq;
107
108         /*
109          * The sequence is strictly monotonic increasing and it never skips!
110          *
111          * Therefore we can safely assume that whenever we received an
112          * unexpected sequence we have lost some valuable data.
113          */
114         if (seq != ar->cmd_seq) {
115                 int count;
116
117                 count = (seq - ar->cmd_seq) % ar->fw.cmd_bufs;
118
119                 wiphy_err(ar->hw->wiphy, "lost %d command responses/traps! "
120                           "w:%d g:%d\n", count, ar->cmd_seq, seq);
121
122                 carl9170_restart(ar, CARL9170_RR_LOST_RSP);
123                 return -EIO;
124         }
125
126         ar->cmd_seq = (ar->cmd_seq + 1) % ar->fw.cmd_bufs;
127         return 0;
128 }
129
130 static void carl9170_cmd_callback(struct ar9170 *ar, u32 len, void *buffer)
131 {
132         /*
133          * Some commands may have a variable response length
134          * and we cannot predict the correct length in advance.
135          * So we only check if we provided enough space for the data.
136          */
137         if (unlikely(ar->readlen != (len - 4))) {
138                 dev_warn(&ar->udev->dev, "received invalid command response:"
139                          "got %d, instead of %d\n", len - 4, ar->readlen);
140                 print_hex_dump_bytes("carl9170 cmd:", DUMP_PREFIX_OFFSET,
141                         ar->cmd_buf, (ar->cmd.hdr.len + 4) & 0x3f);
142                 print_hex_dump_bytes("carl9170 rsp:", DUMP_PREFIX_OFFSET,
143                         buffer, len);
144                 /*
145                  * Do not complete. The command times out,
146                  * and we get a stack trace from there.
147                  */
148                 carl9170_restart(ar, CARL9170_RR_INVALID_RSP);
149         }
150
151         spin_lock(&ar->cmd_lock);
152         if (ar->readbuf) {
153                 if (len >= 4)
154                         memcpy(ar->readbuf, buffer + 4, len - 4);
155
156                 ar->readbuf = NULL;
157         }
158         complete(&ar->cmd_wait);
159         spin_unlock(&ar->cmd_lock);
160 }
161
162 void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
163 {
164         struct carl9170_rsp *cmd = (void *) buf;
165         struct ieee80211_vif *vif;
166
167         if (carl9170_check_sequence(ar, cmd->hdr.seq))
168                 return;
169
170         if ((cmd->hdr.cmd & CARL9170_RSP_FLAG) != CARL9170_RSP_FLAG) {
171                 if (!(cmd->hdr.cmd & CARL9170_CMD_ASYNC_FLAG))
172                         carl9170_cmd_callback(ar, len, buf);
173
174                 return;
175         }
176
177         if (unlikely(cmd->hdr.len != (len - 4))) {
178                 if (net_ratelimit()) {
179                         wiphy_err(ar->hw->wiphy, "FW: received over-/under"
180                                 "sized event %x (%d, but should be %d).\n",
181                                cmd->hdr.cmd, cmd->hdr.len, len - 4);
182
183                         print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE,
184                                              buf, len);
185                 }
186
187                 return;
188         }
189
190         /* hardware event handlers */
191         switch (cmd->hdr.cmd) {
192         case CARL9170_RSP_PRETBTT:
193                 /* pre-TBTT event */
194                 rcu_read_lock();
195                 vif = carl9170_get_main_vif(ar);
196
197                 if (!vif) {
198                         rcu_read_unlock();
199                         break;
200                 }
201
202                 switch (vif->type) {
203                 case NL80211_IFTYPE_STATION:
204                         carl9170_handle_ps(ar, cmd);
205                         break;
206
207                 case NL80211_IFTYPE_AP:
208                 case NL80211_IFTYPE_ADHOC:
209                         carl9170_update_beacon(ar, true);
210                         break;
211
212                 default:
213                         break;
214                 }
215                 rcu_read_unlock();
216
217                 break;
218
219
220         case CARL9170_RSP_TXCOMP:
221                 /* TX status notification */
222                 carl9170_tx_process_status(ar, cmd);
223                 break;
224
225         case CARL9170_RSP_BEACON_CONFIG:
226                 /*
227                  * (IBSS) beacon send notification
228                  * bytes: 04 c2 XX YY B4 B3 B2 B1
229                  *
230                  * XX always 80
231                  * YY always 00
232                  * B1-B4 "should" be the number of send out beacons.
233                  */
234                 break;
235
236         case CARL9170_RSP_ATIM:
237                 /* End of Atim Window */
238                 break;
239
240         case CARL9170_RSP_WATCHDOG:
241                 /* Watchdog Interrupt */
242                 carl9170_restart(ar, CARL9170_RR_WATCHDOG);
243                 break;
244
245         case CARL9170_RSP_TEXT:
246                 /* firmware debug */
247                 carl9170_dbg_message(ar, (char *)buf + 4, len - 4);
248                 break;
249
250         case CARL9170_RSP_HEXDUMP:
251                 wiphy_dbg(ar->hw->wiphy, "FW: HD %d\n", len - 4);
252                 print_hex_dump_bytes("FW:", DUMP_PREFIX_NONE,
253                                      (char *)buf + 4, len - 4);
254                 break;
255
256         case CARL9170_RSP_RADAR:
257                 if (!net_ratelimit())
258                         break;
259
260                 wiphy_info(ar->hw->wiphy, "FW: RADAR! Please report this "
261                        "incident to linux-wireless@vger.kernel.org !\n");
262                 break;
263
264         case CARL9170_RSP_GPIO:
265 #ifdef CONFIG_CARL9170_WPC
266                 if (ar->wps.pbc) {
267                         bool state = !!(cmd->gpio.gpio & cpu_to_le32(
268                                 AR9170_GPIO_PORT_WPS_BUTTON_PRESSED));
269
270                         if (state != ar->wps.pbc_state) {
271                                 ar->wps.pbc_state = state;
272                                 input_report_key(ar->wps.pbc, KEY_WPS_BUTTON,
273                                                  state);
274                                 input_sync(ar->wps.pbc);
275                         }
276                 }
277 #endif /* CONFIG_CARL9170_WPC */
278                 break;
279
280         case CARL9170_RSP_BOOT:
281                 complete(&ar->fw_boot_wait);
282                 break;
283
284         default:
285                 wiphy_err(ar->hw->wiphy, "FW: received unhandled event %x\n",
286                         cmd->hdr.cmd);
287                 print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
288                 break;
289         }
290 }
291
292 static int carl9170_rx_mac_status(struct ar9170 *ar,
293         struct ar9170_rx_head *head, struct ar9170_rx_macstatus *mac,
294         struct ieee80211_rx_status *status)
295 {
296         struct ieee80211_channel *chan;
297         u8 error, decrypt;
298
299         BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
300         BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4);
301
302         error = mac->error;
303
304         if (error & AR9170_RX_ERROR_WRONG_RA) {
305                 if (!ar->sniffer_enabled)
306                         return -EINVAL;
307         }
308
309         if (error & AR9170_RX_ERROR_PLCP) {
310                 if (!(ar->filter_state & FIF_PLCPFAIL))
311                         return -EINVAL;
312
313                 status->flag |= RX_FLAG_FAILED_PLCP_CRC;
314         }
315
316         if (error & AR9170_RX_ERROR_FCS) {
317                 ar->tx_fcs_errors++;
318
319                 if (!(ar->filter_state & FIF_FCSFAIL))
320                         return -EINVAL;
321
322                 status->flag |= RX_FLAG_FAILED_FCS_CRC;
323         }
324
325         decrypt = ar9170_get_decrypt_type(mac);
326         if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
327             decrypt != AR9170_ENC_ALG_NONE) {
328                 if ((decrypt == AR9170_ENC_ALG_TKIP) &&
329                     (error & AR9170_RX_ERROR_MMIC))
330                         status->flag |= RX_FLAG_MMIC_ERROR;
331
332                 status->flag |= RX_FLAG_DECRYPTED;
333         }
334
335         if (error & AR9170_RX_ERROR_DECRYPT && !ar->sniffer_enabled)
336                 return -ENODATA;
337
338         error &= ~(AR9170_RX_ERROR_MMIC |
339                    AR9170_RX_ERROR_FCS |
340                    AR9170_RX_ERROR_WRONG_RA |
341                    AR9170_RX_ERROR_DECRYPT |
342                    AR9170_RX_ERROR_PLCP);
343
344         /* drop any other error frames */
345         if (unlikely(error)) {
346                 /* TODO: update netdevice's RX dropped/errors statistics */
347
348                 if (net_ratelimit())
349                         wiphy_dbg(ar->hw->wiphy, "received frame with "
350                                "suspicious error code (%#x).\n", error);
351
352                 return -EINVAL;
353         }
354
355         chan = ar->channel;
356         if (chan) {
357                 status->band = chan->band;
358                 status->freq = chan->center_freq;
359         }
360
361         switch (mac->status & AR9170_RX_STATUS_MODULATION) {
362         case AR9170_RX_STATUS_MODULATION_CCK:
363                 if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
364                         status->flag |= RX_FLAG_SHORTPRE;
365                 switch (head->plcp[0]) {
366                 case AR9170_RX_PHY_RATE_CCK_1M:
367                         status->rate_idx = 0;
368                         break;
369                 case AR9170_RX_PHY_RATE_CCK_2M:
370                         status->rate_idx = 1;
371                         break;
372                 case AR9170_RX_PHY_RATE_CCK_5M:
373                         status->rate_idx = 2;
374                         break;
375                 case AR9170_RX_PHY_RATE_CCK_11M:
376                         status->rate_idx = 3;
377                         break;
378                 default:
379                         if (net_ratelimit()) {
380                                 wiphy_err(ar->hw->wiphy, "invalid plcp cck "
381                                        "rate (%x).\n", head->plcp[0]);
382                         }
383
384                         return -EINVAL;
385                 }
386                 break;
387
388         case AR9170_RX_STATUS_MODULATION_DUPOFDM:
389         case AR9170_RX_STATUS_MODULATION_OFDM:
390                 switch (head->plcp[0] & 0xf) {
391                 case AR9170_TXRX_PHY_RATE_OFDM_6M:
392                         status->rate_idx = 0;
393                         break;
394                 case AR9170_TXRX_PHY_RATE_OFDM_9M:
395                         status->rate_idx = 1;
396                         break;
397                 case AR9170_TXRX_PHY_RATE_OFDM_12M:
398                         status->rate_idx = 2;
399                         break;
400                 case AR9170_TXRX_PHY_RATE_OFDM_18M:
401                         status->rate_idx = 3;
402                         break;
403                 case AR9170_TXRX_PHY_RATE_OFDM_24M:
404                         status->rate_idx = 4;
405                         break;
406                 case AR9170_TXRX_PHY_RATE_OFDM_36M:
407                         status->rate_idx = 5;
408                         break;
409                 case AR9170_TXRX_PHY_RATE_OFDM_48M:
410                         status->rate_idx = 6;
411                         break;
412                 case AR9170_TXRX_PHY_RATE_OFDM_54M:
413                         status->rate_idx = 7;
414                         break;
415                 default:
416                         if (net_ratelimit()) {
417                                 wiphy_err(ar->hw->wiphy, "invalid plcp ofdm "
418                                         "rate (%x).\n", head->plcp[0]);
419                         }
420
421                         return -EINVAL;
422                 }
423                 if (status->band == IEEE80211_BAND_2GHZ)
424                         status->rate_idx += 4;
425                 break;
426
427         case AR9170_RX_STATUS_MODULATION_HT:
428                 if (head->plcp[3] & 0x80)
429                         status->flag |= RX_FLAG_40MHZ;
430                 if (head->plcp[6] & 0x80)
431                         status->flag |= RX_FLAG_SHORT_GI;
432
433                 status->rate_idx = clamp(0, 75, head->plcp[3] & 0x7f);
434                 status->flag |= RX_FLAG_HT;
435                 break;
436
437         default:
438                 BUG();
439                 return -ENOSYS;
440         }
441
442         return 0;
443 }
444
445 static void carl9170_rx_phy_status(struct ar9170 *ar,
446         struct ar9170_rx_phystatus *phy, struct ieee80211_rx_status *status)
447 {
448         int i;
449
450         BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20);
451
452         for (i = 0; i < 3; i++)
453                 if (phy->rssi[i] != 0x80)
454                         status->antenna |= BIT(i);
455
456         /* post-process RSSI */
457         for (i = 0; i < 7; i++)
458                 if (phy->rssi[i] & 0x80)
459                         phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f;
460
461         /* TODO: we could do something with phy_errors */
462         status->signal = ar->noise[0] + phy->rssi_combined;
463 }
464
465 static struct sk_buff *carl9170_rx_copy_data(u8 *buf, int len)
466 {
467         struct sk_buff *skb;
468         int reserved = 0;
469         struct ieee80211_hdr *hdr = (void *) buf;
470
471         if (ieee80211_is_data_qos(hdr->frame_control)) {
472                 u8 *qc = ieee80211_get_qos_ctl(hdr);
473                 reserved += NET_IP_ALIGN;
474
475                 if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
476                         reserved += NET_IP_ALIGN;
477         }
478
479         if (ieee80211_has_a4(hdr->frame_control))
480                 reserved += NET_IP_ALIGN;
481
482         reserved = 32 + (reserved & NET_IP_ALIGN);
483
484         skb = dev_alloc_skb(len + reserved);
485         if (likely(skb)) {
486                 skb_reserve(skb, reserved);
487                 memcpy(skb_put(skb, len), buf, len);
488         }
489
490         return skb;
491 }
492
493 static u8 *carl9170_find_ie(u8 *data, unsigned int len, u8 ie)
494 {
495         struct ieee80211_mgmt *mgmt = (void *)data;
496         u8 *pos, *end;
497
498         pos = (u8 *)mgmt->u.beacon.variable;
499         end = data + len;
500         while (pos < end) {
501                 if (pos + 2 + pos[1] > end)
502                         return NULL;
503
504                 if (pos[0] == ie)
505                         return pos;
506
507                 pos += 2 + pos[1];
508         }
509         return NULL;
510 }
511
512 /*
513  * NOTE:
514  *
515  * The firmware is in charge of waking up the device just before
516  * the AP is expected to transmit the next beacon.
517  *
518  * This leaves the driver with the important task of deciding when
519  * to set the PHY back to bed again.
520  */
521 static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len)
522 {
523         struct ieee80211_hdr *hdr = (void *) data;
524         struct ieee80211_tim_ie *tim_ie;
525         u8 *tim;
526         u8 tim_len;
527         bool cam;
528
529         if (likely(!(ar->hw->conf.flags & IEEE80211_CONF_PS)))
530                 return;
531
532         /* check if this really is a beacon */
533         if (!ieee80211_is_beacon(hdr->frame_control))
534                 return;
535
536         /* min. beacon length + FCS_LEN */
537         if (len <= 40 + FCS_LEN)
538                 return;
539
540         /* and only beacons from the associated BSSID, please */
541         if (compare_ether_addr(hdr->addr3, ar->common.curbssid) ||
542             !ar->common.curaid)
543                 return;
544
545         ar->ps.last_beacon = jiffies;
546
547         tim = carl9170_find_ie(data, len - FCS_LEN, WLAN_EID_TIM);
548         if (!tim)
549                 return;
550
551         if (tim[1] < sizeof(*tim_ie))
552                 return;
553
554         tim_len = tim[1];
555         tim_ie = (struct ieee80211_tim_ie *) &tim[2];
556
557         if (!WARN_ON_ONCE(!ar->hw->conf.ps_dtim_period))
558                 ar->ps.dtim_counter = (tim_ie->dtim_count - 1) %
559                         ar->hw->conf.ps_dtim_period;
560
561         /* Check whenever the PHY can be turned off again. */
562
563         /* 1. What about buffered unicast traffic for our AID? */
564         cam = ieee80211_check_tim(tim_ie, tim_len, ar->common.curaid);
565
566         /* 2. Maybe the AP wants to send multicast/broadcast data? */
567         cam = !!(tim_ie->bitmap_ctrl & 0x01);
568
569         if (!cam) {
570                 /* back to low-power land. */
571                 ar->ps.off_override &= ~PS_OFF_BCN;
572                 carl9170_ps_check(ar);
573         } else {
574                 /* force CAM */
575                 ar->ps.off_override |= PS_OFF_BCN;
576         }
577 }
578
579 /*
580  * If the frame alignment is right (or the kernel has
581  * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
582  * is only a single MPDU in the USB frame, then we could
583  * submit to mac80211 the SKB directly. However, since
584  * there may be multiple packets in one SKB in stream
585  * mode, and we need to observe the proper ordering,
586  * this is non-trivial.
587  */
588
589 static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
590 {
591         struct ar9170_rx_head *head;
592         struct ar9170_rx_macstatus *mac;
593         struct ar9170_rx_phystatus *phy = NULL;
594         struct ieee80211_rx_status status;
595         struct sk_buff *skb;
596         int mpdu_len;
597
598         if (!IS_STARTED(ar))
599                 return;
600
601         if (unlikely(len < sizeof(*mac)))
602                 goto drop;
603
604         mpdu_len = len - sizeof(*mac);
605
606         mac = (void *)(buf + mpdu_len);
607         if (unlikely(mac->error & AR9170_RX_ERROR_FATAL))
608                 goto drop;
609
610         switch (mac->status & AR9170_RX_STATUS_MPDU) {
611         case AR9170_RX_STATUS_MPDU_FIRST:
612                 /* Aggregated MPDUs start with an PLCP header */
613                 if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) {
614                         head = (void *) buf;
615
616                         /*
617                          * The PLCP header needs to be cached for the
618                          * following MIDDLE + LAST A-MPDU packets.
619                          *
620                          * So, if you are wondering why all frames seem
621                          * to share a common RX status information,
622                          * then you have the answer right here...
623                          */
624                         memcpy(&ar->rx_plcp, (void *) buf,
625                                sizeof(struct ar9170_rx_head));
626
627                         mpdu_len -= sizeof(struct ar9170_rx_head);
628                         buf += sizeof(struct ar9170_rx_head);
629
630                         ar->rx_has_plcp = true;
631                 } else {
632                         if (net_ratelimit()) {
633                                 wiphy_err(ar->hw->wiphy, "plcp info "
634                                         "is clipped.\n");
635                         }
636
637                         goto drop;
638                 }
639                 break;
640
641         case AR9170_RX_STATUS_MPDU_LAST:
642                 /*
643                  * The last frame of an A-MPDU has an extra tail
644                  * which does contain the phy status of the whole
645                  * aggregate.
646                  */
647
648                 if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) {
649                         mpdu_len -= sizeof(struct ar9170_rx_phystatus);
650                         phy = (void *)(buf + mpdu_len);
651                 } else {
652                         if (net_ratelimit()) {
653                                 wiphy_err(ar->hw->wiphy, "frame tail "
654                                         "is clipped.\n");
655                         }
656
657                         goto drop;
658                 }
659
660         case AR9170_RX_STATUS_MPDU_MIDDLE:
661                 /*  These are just data + mac status */
662                 if (unlikely(!ar->rx_has_plcp)) {
663                         if (!net_ratelimit())
664                                 return;
665
666                         wiphy_err(ar->hw->wiphy, "rx stream does not start "
667                                         "with a first_mpdu frame tag.\n");
668
669                         goto drop;
670                 }
671
672                 head = &ar->rx_plcp;
673                 break;
674
675         case AR9170_RX_STATUS_MPDU_SINGLE:
676                 /* single mpdu has both: plcp (head) and phy status (tail) */
677                 head = (void *) buf;
678
679                 mpdu_len -= sizeof(struct ar9170_rx_head);
680                 mpdu_len -= sizeof(struct ar9170_rx_phystatus);
681
682                 buf += sizeof(struct ar9170_rx_head);
683                 phy = (void *)(buf + mpdu_len);
684                 break;
685
686         default:
687                 BUG_ON(1);
688                 break;
689         }
690
691         /* FC + DU + RA + FCS */
692         if (unlikely(mpdu_len < (2 + 2 + ETH_ALEN + FCS_LEN)))
693                 goto drop;
694
695         memset(&status, 0, sizeof(status));
696         if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status)))
697                 goto drop;
698
699         if (phy)
700                 carl9170_rx_phy_status(ar, phy, &status);
701
702         carl9170_ps_beacon(ar, buf, mpdu_len);
703
704         skb = carl9170_rx_copy_data(buf, mpdu_len);
705         if (!skb)
706                 goto drop;
707
708         memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
709         ieee80211_rx(ar->hw, skb);
710         return;
711
712 drop:
713         ar->rx_dropped++;
714 }
715
716 static void carl9170_rx_untie_cmds(struct ar9170 *ar, const u8 *respbuf,
717                                    const unsigned int resplen)
718 {
719         struct carl9170_rsp *cmd;
720         int i = 0;
721
722         while (i < resplen) {
723                 cmd = (void *) &respbuf[i];
724
725                 i += cmd->hdr.len + 4;
726                 if (unlikely(i > resplen))
727                         break;
728
729                 carl9170_handle_command_response(ar, cmd, cmd->hdr.len + 4);
730         }
731
732         if (unlikely(i != resplen)) {
733                 if (!net_ratelimit())
734                         return;
735
736                 wiphy_err(ar->hw->wiphy, "malformed firmware trap:\n");
737                 print_hex_dump_bytes("rxcmd:", DUMP_PREFIX_OFFSET,
738                                      respbuf, resplen);
739         }
740 }
741
742 static void __carl9170_rx(struct ar9170 *ar, u8 *buf, unsigned int len)
743 {
744         unsigned int i = 0;
745
746         /* weird thing, but this is the same in the original driver */
747         while (len > 2 && i < 12 && buf[0] == 0xff && buf[1] == 0xff) {
748                 i += 2;
749                 len -= 2;
750                 buf += 2;
751         }
752
753         if (unlikely(len < 4))
754                 return;
755
756         /* found the 6 * 0xffff marker? */
757         if (i == 12)
758                 carl9170_rx_untie_cmds(ar, buf, len);
759         else
760                 carl9170_handle_mpdu(ar, buf, len);
761 }
762
763 static void carl9170_rx_stream(struct ar9170 *ar, void *buf, unsigned int len)
764 {
765         unsigned int tlen, wlen = 0, clen = 0;
766         struct ar9170_stream *rx_stream;
767         u8 *tbuf;
768
769         tbuf = buf;
770         tlen = len;
771
772         while (tlen >= 4) {
773                 rx_stream = (void *) tbuf;
774                 clen = le16_to_cpu(rx_stream->length);
775                 wlen = ALIGN(clen, 4);
776
777                 /* check if this is stream has a valid tag.*/
778                 if (rx_stream->tag != cpu_to_le16(AR9170_RX_STREAM_TAG)) {
779                         /*
780                          * TODO: handle the highly unlikely event that the
781                          * corrupted stream has the TAG at the right position.
782                          */
783
784                         /* check if the frame can be repaired. */
785                         if (!ar->rx_failover_missing) {
786
787                                 /* this is not "short read". */
788                                 if (net_ratelimit()) {
789                                         wiphy_err(ar->hw->wiphy,
790                                                 "missing tag!\n");
791                                 }
792
793                                 __carl9170_rx(ar, tbuf, tlen);
794                                 return;
795                         }
796
797                         if (ar->rx_failover_missing > tlen) {
798                                 if (net_ratelimit()) {
799                                         wiphy_err(ar->hw->wiphy,
800                                                 "possible multi "
801                                                 "stream corruption!\n");
802                                         goto err_telluser;
803                                 } else {
804                                         goto err_silent;
805                                 }
806                         }
807
808                         memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
809                         ar->rx_failover_missing -= tlen;
810
811                         if (ar->rx_failover_missing <= 0) {
812                                 /*
813                                  * nested carl9170_rx_stream call!
814                                  *
815                                  * termination is guranteed, even when the
816                                  * combined frame also have an element with
817                                  * a bad tag.
818                                  */
819
820                                 ar->rx_failover_missing = 0;
821                                 carl9170_rx_stream(ar, ar->rx_failover->data,
822                                                    ar->rx_failover->len);
823
824                                 skb_reset_tail_pointer(ar->rx_failover);
825                                 skb_trim(ar->rx_failover, 0);
826                         }
827
828                         return;
829                 }
830
831                 /* check if stream is clipped */
832                 if (wlen > tlen - 4) {
833                         if (ar->rx_failover_missing) {
834                                 /* TODO: handle double stream corruption. */
835                                 if (net_ratelimit()) {
836                                         wiphy_err(ar->hw->wiphy, "double rx "
837                                                 "stream corruption!\n");
838                                         goto err_telluser;
839                                 } else {
840                                         goto err_silent;
841                                 }
842                         }
843
844                         /*
845                          * save incomplete data set.
846                          * the firmware will resend the missing bits when
847                          * the rx - descriptor comes round again.
848                          */
849
850                         memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
851                         ar->rx_failover_missing = clen - tlen;
852                         return;
853                 }
854                 __carl9170_rx(ar, rx_stream->payload, clen);
855
856                 tbuf += wlen + 4;
857                 tlen -= wlen + 4;
858         }
859
860         if (tlen) {
861                 if (net_ratelimit()) {
862                         wiphy_err(ar->hw->wiphy, "%d bytes of unprocessed "
863                                 "data left in rx stream!\n", tlen);
864                 }
865
866                 goto err_telluser;
867         }
868
869         return;
870
871 err_telluser:
872         wiphy_err(ar->hw->wiphy, "damaged RX stream data [want:%d, "
873                 "data:%d, rx:%d, pending:%d ]\n", clen, wlen, tlen,
874                 ar->rx_failover_missing);
875
876         if (ar->rx_failover_missing)
877                 print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET,
878                                      ar->rx_failover->data,
879                                      ar->rx_failover->len);
880
881         print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET,
882                              buf, len);
883
884         wiphy_err(ar->hw->wiphy, "please check your hardware and cables, if "
885                 "you see this message frequently.\n");
886
887 err_silent:
888         if (ar->rx_failover_missing) {
889                 skb_reset_tail_pointer(ar->rx_failover);
890                 skb_trim(ar->rx_failover, 0);
891                 ar->rx_failover_missing = 0;
892         }
893 }
894
895 void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len)
896 {
897         if (ar->fw.rx_stream)
898                 carl9170_rx_stream(ar, buf, len);
899         else
900                 __carl9170_rx(ar, buf, len);
901 }