Merge branches 'release', 'asus', 'sony-laptop' and 'thinkpad' into release
[pandora-kernel.git] / drivers / net / wireless / b43legacy / xmit.c
index c24399d..d84408a 100644 (file)
@@ -181,7 +181,7 @@ static u8 b43legacy_calc_fallback_rate(u8 bitrate)
        return 0;
 }
 
-static void generate_txhdr_fw3(struct b43legacy_wldev *dev,
+static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
                               struct b43legacy_txhdr_fw3 *txhdr,
                               const unsigned char *fragment_data,
                               unsigned int fragment_len,
@@ -223,7 +223,7 @@ static void generate_txhdr_fw3(struct b43legacy_wldev *dev,
        } else {
                int fbrate_base100kbps = B43legacy_RATE_TO_100KBPS(rate_fb);
                txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw,
-                                                        dev->wl->if_id,
+                                                        txctl->vif,
                                                         fragment_len,
                                                         fbrate_base100kbps);
        }
@@ -252,6 +252,13 @@ static void generate_txhdr_fw3(struct b43legacy_wldev *dev,
                        iv_len = min((size_t)txctl->iv_len,
                                     ARRAY_SIZE(txhdr->iv));
                        memcpy(txhdr->iv, ((u8 *)wlhdr) + wlhdr_len, iv_len);
+               } else {
+                       /* This key is invalid. This might only happen
+                        * in a short timeframe after machine resume before
+                        * we were able to reconfigure keys.
+                        * Drop this packet completely. Do not transmit it
+                        * unencrypted to avoid leaking information. */
+                       return -ENOKEY;
                }
        }
        b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *)
@@ -312,7 +319,7 @@ static void generate_txhdr_fw3(struct b43legacy_wldev *dev,
 
                if (txctl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
                        ieee80211_ctstoself_get(dev->wl->hw,
-                                               dev->wl->if_id,
+                                               txctl->vif,
                                                fragment_data,
                                                fragment_len, txctl,
                                                (struct ieee80211_cts *)
@@ -321,7 +328,7 @@ static void generate_txhdr_fw3(struct b43legacy_wldev *dev,
                        len = sizeof(struct ieee80211_cts);
                } else {
                        ieee80211_rts_get(dev->wl->hw,
-                                         dev->wl->if_id,
+                                         txctl->vif,
                                          fragment_data, fragment_len, txctl,
                                          (struct ieee80211_rts *)
                                          (txhdr->rts_frame));
@@ -345,16 +352,18 @@ static void generate_txhdr_fw3(struct b43legacy_wldev *dev,
        /* Apply the bitfields */
        txhdr->mac_ctl = cpu_to_le32(mac_ctl);
        txhdr->phy_ctl = cpu_to_le16(phy_ctl);
+
+       return 0;
 }
 
-void b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
+int b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
                              u8 *txhdr,
                              const unsigned char *fragment_data,
                              unsigned int fragment_len,
                              const struct ieee80211_tx_control *txctl,
                              u16 cookie)
 {
-       generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr,
+       return generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr,
                           fragment_data, fragment_len,
                           txctl, cookie);
 }
@@ -532,8 +541,24 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
        else
                status.rate = b43legacy_plcp_get_bitrate_cck(plcp);
        status.antenna = !!(phystat0 & B43legacy_RX_PHYST0_ANT);
-       status.mactime = mactime;
-       status.flag |= RX_FLAG_TSFT;
+
+       /*
+        * If monitors are present get full 64-bit timestamp. This
+        * code assumes we get to process the packet within 16 bits
+        * of timestamp, i.e. about 65 milliseconds after the PHY
+        * received the first symbol.
+        */
+       if (dev->wl->radiotap_enabled) {
+               u16 low_mactime_now;
+
+               b43legacy_tsf_read(dev, &status.mactime);
+               low_mactime_now = status.mactime;
+               status.mactime = status.mactime & ~0xFFFFULL;
+               status.mactime += mactime;
+               if (low_mactime_now <= mactime)
+                       status.mactime -= 0x10000;
+               status.flag |= RX_FLAG_TSFT;
+       }
 
        chanid = (chanstat & B43legacy_RX_CHAN_ID) >>
                  B43legacy_RX_CHAN_ID_SHIFT;