]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/net/wireless/ath/carl9170/rx.c
carl9170: remove stale rx error path
[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         switch (mac->status & AR9170_RX_STATUS_MPDU) {
608         case AR9170_RX_STATUS_MPDU_FIRST:
609                 /* Aggregated MPDUs start with an PLCP header */
610                 if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) {
611                         head = (void *) buf;
612
613                         /*
614                          * The PLCP header needs to be cached for the
615                          * following MIDDLE + LAST A-MPDU packets.
616                          *
617                          * So, if you are wondering why all frames seem
618                          * to share a common RX status information,
619                          * then you have the answer right here...
620                          */
621                         memcpy(&ar->rx_plcp, (void *) buf,
622                                sizeof(struct ar9170_rx_head));
623
624                         mpdu_len -= sizeof(struct ar9170_rx_head);
625                         buf += sizeof(struct ar9170_rx_head);
626
627                         ar->rx_has_plcp = true;
628                 } else {
629                         if (net_ratelimit()) {
630                                 wiphy_err(ar->hw->wiphy, "plcp info "
631                                         "is clipped.\n");
632                         }
633
634                         goto drop;
635                 }
636                 break;
637
638         case AR9170_RX_STATUS_MPDU_LAST:
639                 /*
640                  * The last frame of an A-MPDU has an extra tail
641                  * which does contain the phy status of the whole
642                  * aggregate.
643                  */
644
645                 if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) {
646                         mpdu_len -= sizeof(struct ar9170_rx_phystatus);
647                         phy = (void *)(buf + mpdu_len);
648                 } else {
649                         if (net_ratelimit()) {
650                                 wiphy_err(ar->hw->wiphy, "frame tail "
651                                         "is clipped.\n");
652                         }
653
654                         goto drop;
655                 }
656
657         case AR9170_RX_STATUS_MPDU_MIDDLE:
658                 /*  These are just data + mac status */
659                 if (unlikely(!ar->rx_has_plcp)) {
660                         if (!net_ratelimit())
661                                 return;
662
663                         wiphy_err(ar->hw->wiphy, "rx stream does not start "
664                                         "with a first_mpdu frame tag.\n");
665
666                         goto drop;
667                 }
668
669                 head = &ar->rx_plcp;
670                 break;
671
672         case AR9170_RX_STATUS_MPDU_SINGLE:
673                 /* single mpdu has both: plcp (head) and phy status (tail) */
674                 head = (void *) buf;
675
676                 mpdu_len -= sizeof(struct ar9170_rx_head);
677                 mpdu_len -= sizeof(struct ar9170_rx_phystatus);
678
679                 buf += sizeof(struct ar9170_rx_head);
680                 phy = (void *)(buf + mpdu_len);
681                 break;
682
683         default:
684                 BUG_ON(1);
685                 break;
686         }
687
688         /* FC + DU + RA + FCS */
689         if (unlikely(mpdu_len < (2 + 2 + ETH_ALEN + FCS_LEN)))
690                 goto drop;
691
692         memset(&status, 0, sizeof(status));
693         if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status)))
694                 goto drop;
695
696         if (phy)
697                 carl9170_rx_phy_status(ar, phy, &status);
698
699         carl9170_ps_beacon(ar, buf, mpdu_len);
700
701         skb = carl9170_rx_copy_data(buf, mpdu_len);
702         if (!skb)
703                 goto drop;
704
705         memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
706         ieee80211_rx(ar->hw, skb);
707         return;
708
709 drop:
710         ar->rx_dropped++;
711 }
712
713 static void carl9170_rx_untie_cmds(struct ar9170 *ar, const u8 *respbuf,
714                                    const unsigned int resplen)
715 {
716         struct carl9170_rsp *cmd;
717         int i = 0;
718
719         while (i < resplen) {
720                 cmd = (void *) &respbuf[i];
721
722                 i += cmd->hdr.len + 4;
723                 if (unlikely(i > resplen))
724                         break;
725
726                 carl9170_handle_command_response(ar, cmd, cmd->hdr.len + 4);
727         }
728
729         if (unlikely(i != resplen)) {
730                 if (!net_ratelimit())
731                         return;
732
733                 wiphy_err(ar->hw->wiphy, "malformed firmware trap:\n");
734                 print_hex_dump_bytes("rxcmd:", DUMP_PREFIX_OFFSET,
735                                      respbuf, resplen);
736         }
737 }
738
739 static void __carl9170_rx(struct ar9170 *ar, u8 *buf, unsigned int len)
740 {
741         unsigned int i = 0;
742
743         /* weird thing, but this is the same in the original driver */
744         while (len > 2 && i < 12 && buf[0] == 0xff && buf[1] == 0xff) {
745                 i += 2;
746                 len -= 2;
747                 buf += 2;
748         }
749
750         if (unlikely(len < 4))
751                 return;
752
753         /* found the 6 * 0xffff marker? */
754         if (i == 12)
755                 carl9170_rx_untie_cmds(ar, buf, len);
756         else
757                 carl9170_handle_mpdu(ar, buf, len);
758 }
759
760 static void carl9170_rx_stream(struct ar9170 *ar, void *buf, unsigned int len)
761 {
762         unsigned int tlen, wlen = 0, clen = 0;
763         struct ar9170_stream *rx_stream;
764         u8 *tbuf;
765
766         tbuf = buf;
767         tlen = len;
768
769         while (tlen >= 4) {
770                 rx_stream = (void *) tbuf;
771                 clen = le16_to_cpu(rx_stream->length);
772                 wlen = ALIGN(clen, 4);
773
774                 /* check if this is stream has a valid tag.*/
775                 if (rx_stream->tag != cpu_to_le16(AR9170_RX_STREAM_TAG)) {
776                         /*
777                          * TODO: handle the highly unlikely event that the
778                          * corrupted stream has the TAG at the right position.
779                          */
780
781                         /* check if the frame can be repaired. */
782                         if (!ar->rx_failover_missing) {
783
784                                 /* this is not "short read". */
785                                 if (net_ratelimit()) {
786                                         wiphy_err(ar->hw->wiphy,
787                                                 "missing tag!\n");
788                                 }
789
790                                 __carl9170_rx(ar, tbuf, tlen);
791                                 return;
792                         }
793
794                         if (ar->rx_failover_missing > tlen) {
795                                 if (net_ratelimit()) {
796                                         wiphy_err(ar->hw->wiphy,
797                                                 "possible multi "
798                                                 "stream corruption!\n");
799                                         goto err_telluser;
800                                 } else {
801                                         goto err_silent;
802                                 }
803                         }
804
805                         memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
806                         ar->rx_failover_missing -= tlen;
807
808                         if (ar->rx_failover_missing <= 0) {
809                                 /*
810                                  * nested carl9170_rx_stream call!
811                                  *
812                                  * termination is guranteed, even when the
813                                  * combined frame also have an element with
814                                  * a bad tag.
815                                  */
816
817                                 ar->rx_failover_missing = 0;
818                                 carl9170_rx_stream(ar, ar->rx_failover->data,
819                                                    ar->rx_failover->len);
820
821                                 skb_reset_tail_pointer(ar->rx_failover);
822                                 skb_trim(ar->rx_failover, 0);
823                         }
824
825                         return;
826                 }
827
828                 /* check if stream is clipped */
829                 if (wlen > tlen - 4) {
830                         if (ar->rx_failover_missing) {
831                                 /* TODO: handle double stream corruption. */
832                                 if (net_ratelimit()) {
833                                         wiphy_err(ar->hw->wiphy, "double rx "
834                                                 "stream corruption!\n");
835                                         goto err_telluser;
836                                 } else {
837                                         goto err_silent;
838                                 }
839                         }
840
841                         /*
842                          * save incomplete data set.
843                          * the firmware will resend the missing bits when
844                          * the rx - descriptor comes round again.
845                          */
846
847                         memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
848                         ar->rx_failover_missing = clen - tlen;
849                         return;
850                 }
851                 __carl9170_rx(ar, rx_stream->payload, clen);
852
853                 tbuf += wlen + 4;
854                 tlen -= wlen + 4;
855         }
856
857         if (tlen) {
858                 if (net_ratelimit()) {
859                         wiphy_err(ar->hw->wiphy, "%d bytes of unprocessed "
860                                 "data left in rx stream!\n", tlen);
861                 }
862
863                 goto err_telluser;
864         }
865
866         return;
867
868 err_telluser:
869         wiphy_err(ar->hw->wiphy, "damaged RX stream data [want:%d, "
870                 "data:%d, rx:%d, pending:%d ]\n", clen, wlen, tlen,
871                 ar->rx_failover_missing);
872
873         if (ar->rx_failover_missing)
874                 print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET,
875                                      ar->rx_failover->data,
876                                      ar->rx_failover->len);
877
878         print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET,
879                              buf, len);
880
881         wiphy_err(ar->hw->wiphy, "please check your hardware and cables, if "
882                 "you see this message frequently.\n");
883
884 err_silent:
885         if (ar->rx_failover_missing) {
886                 skb_reset_tail_pointer(ar->rx_failover);
887                 skb_trim(ar->rx_failover, 0);
888                 ar->rx_failover_missing = 0;
889         }
890 }
891
892 void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len)
893 {
894         if (ar->fw.rx_stream)
895                 carl9170_rx_stream(ar, buf, len);
896         else
897                 __carl9170_rx(ar, buf, len);
898 }