aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r--drivers/net/wireless/b43/dma.c30
-rw-r--r--drivers/net/wireless/b43/main.c19
-rw-r--r--drivers/net/wireless/b43/xmit.c23
-rw-r--r--drivers/net/wireless/b43/xmit.h10
4 files changed, 63 insertions, 19 deletions
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 3e73d2a523aa..8a708b77925d 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -1114,7 +1114,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
1114{ 1114{
1115 const struct b43_dma_ops *ops = ring->ops; 1115 const struct b43_dma_ops *ops = ring->ops;
1116 u8 *header; 1116 u8 *header;
1117 int slot; 1117 int slot, old_top_slot, old_used_slots;
1118 int err; 1118 int err;
1119 struct b43_dmadesc_generic *desc; 1119 struct b43_dmadesc_generic *desc;
1120 struct b43_dmadesc_meta *meta; 1120 struct b43_dmadesc_meta *meta;
@@ -1126,6 +1126,9 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
1126#define SLOTS_PER_PACKET 2 1126#define SLOTS_PER_PACKET 2
1127 B43_WARN_ON(skb_shinfo(skb)->nr_frags); 1127 B43_WARN_ON(skb_shinfo(skb)->nr_frags);
1128 1128
1129 old_top_slot = ring->current_slot;
1130 old_used_slots = ring->used_slots;
1131
1129 /* Get a slot for the header. */ 1132 /* Get a slot for the header. */
1130 slot = request_slot(ring); 1133 slot = request_slot(ring);
1131 desc = ops->idx2desc(ring, slot, &meta_hdr); 1134 desc = ops->idx2desc(ring, slot, &meta_hdr);
@@ -1133,13 +1136,21 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
1133 1136
1134 header = &(ring->txhdr_cache[slot * hdrsize]); 1137 header = &(ring->txhdr_cache[slot * hdrsize]);
1135 cookie = generate_cookie(ring, slot); 1138 cookie = generate_cookie(ring, slot);
1136 b43_generate_txhdr(ring->dev, header, 1139 err = b43_generate_txhdr(ring->dev, header,
1137 skb->data, skb->len, ctl, cookie); 1140 skb->data, skb->len, ctl, cookie);
1141 if (unlikely(err)) {
1142 ring->current_slot = old_top_slot;
1143 ring->used_slots = old_used_slots;
1144 return err;
1145 }
1138 1146
1139 meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header, 1147 meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header,
1140 hdrsize, 1); 1148 hdrsize, 1);
1141 if (dma_mapping_error(meta_hdr->dmaaddr)) 1149 if (dma_mapping_error(meta_hdr->dmaaddr)) {
1150 ring->current_slot = old_top_slot;
1151 ring->used_slots = old_used_slots;
1142 return -EIO; 1152 return -EIO;
1153 }
1143 ops->fill_descriptor(ring, desc, meta_hdr->dmaaddr, 1154 ops->fill_descriptor(ring, desc, meta_hdr->dmaaddr,
1144 hdrsize, 1, 0, 0); 1155 hdrsize, 1, 0, 0);
1145 1156
@@ -1157,6 +1168,8 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
1157 if (dma_mapping_error(meta->dmaaddr)) { 1168 if (dma_mapping_error(meta->dmaaddr)) {
1158 bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); 1169 bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
1159 if (!bounce_skb) { 1170 if (!bounce_skb) {
1171 ring->current_slot = old_top_slot;
1172 ring->used_slots = old_used_slots;
1160 err = -ENOMEM; 1173 err = -ENOMEM;
1161 goto out_unmap_hdr; 1174 goto out_unmap_hdr;
1162 } 1175 }
@@ -1167,6 +1180,8 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
1167 meta->skb = skb; 1180 meta->skb = skb;
1168 meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); 1181 meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
1169 if (dma_mapping_error(meta->dmaaddr)) { 1182 if (dma_mapping_error(meta->dmaaddr)) {
1183 ring->current_slot = old_top_slot;
1184 ring->used_slots = old_used_slots;
1170 err = -EIO; 1185 err = -EIO;
1171 goto out_free_bounce; 1186 goto out_free_bounce;
1172 } 1187 }
@@ -1252,6 +1267,13 @@ int b43_dma_tx(struct b43_wldev *dev,
1252 B43_WARN_ON(ring->stopped); 1267 B43_WARN_ON(ring->stopped);
1253 1268
1254 err = dma_tx_fragment(ring, skb, ctl); 1269 err = dma_tx_fragment(ring, skb, ctl);
1270 if (unlikely(err == -ENOKEY)) {
1271 /* Drop this packet, as we don't have the encryption key
1272 * anymore and must not transmit it unencrypted. */
1273 dev_kfree_skb_any(skb);
1274 err = 0;
1275 goto out_unlock;
1276 }
1255 if (unlikely(err)) { 1277 if (unlikely(err)) {
1256 b43err(dev->wl, "DMA tx mapping failure\n"); 1278 b43err(dev->wl, "DMA tx mapping failure\n");
1257 goto out_unlock; 1279 goto out_unlock;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 88d2c15d3fbe..64c154d080d8 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3532,8 +3532,6 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
3532 b43_bluetooth_coext_enable(dev); 3532 b43_bluetooth_coext_enable(dev);
3533 3533
3534 ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */ 3534 ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */
3535 memset(wl->bssid, 0, ETH_ALEN);
3536 memset(wl->mac_addr, 0, ETH_ALEN);
3537 b43_upload_card_macaddress(dev); 3535 b43_upload_card_macaddress(dev);
3538 b43_security_init(dev); 3536 b43_security_init(dev);
3539 b43_rng_init(wl); 3537 b43_rng_init(wl);
@@ -3630,6 +3628,15 @@ static int b43_op_start(struct ieee80211_hw *hw)
3630 struct b43_wldev *dev = wl->current_dev; 3628 struct b43_wldev *dev = wl->current_dev;
3631 int did_init = 0; 3629 int did_init = 0;
3632 int err = 0; 3630 int err = 0;
3631 bool do_rfkill_exit = 0;
3632
3633 /* Kill all old instance specific information to make sure
3634 * the card won't use it in the short timeframe between start
3635 * and mac80211 reconfiguring it. */
3636 memset(wl->bssid, 0, ETH_ALEN);
3637 memset(wl->mac_addr, 0, ETH_ALEN);
3638 wl->filter_flags = 0;
3639 wl->radiotap_enabled = 0;
3633 3640
3634 /* First register RFkill. 3641 /* First register RFkill.
3635 * LEDs that are registered later depend on it. */ 3642 * LEDs that are registered later depend on it. */
@@ -3639,8 +3646,10 @@ static int b43_op_start(struct ieee80211_hw *hw)
3639 3646
3640 if (b43_status(dev) < B43_STAT_INITIALIZED) { 3647 if (b43_status(dev) < B43_STAT_INITIALIZED) {
3641 err = b43_wireless_core_init(dev); 3648 err = b43_wireless_core_init(dev);
3642 if (err) 3649 if (err) {
3650 do_rfkill_exit = 1;
3643 goto out_mutex_unlock; 3651 goto out_mutex_unlock;
3652 }
3644 did_init = 1; 3653 did_init = 1;
3645 } 3654 }
3646 3655
@@ -3649,6 +3658,7 @@ static int b43_op_start(struct ieee80211_hw *hw)
3649 if (err) { 3658 if (err) {
3650 if (did_init) 3659 if (did_init)
3651 b43_wireless_core_exit(dev); 3660 b43_wireless_core_exit(dev);
3661 do_rfkill_exit = 1;
3652 goto out_mutex_unlock; 3662 goto out_mutex_unlock;
3653 } 3663 }
3654 } 3664 }
@@ -3656,6 +3666,9 @@ static int b43_op_start(struct ieee80211_hw *hw)
3656 out_mutex_unlock: 3666 out_mutex_unlock:
3657 mutex_unlock(&wl->mutex); 3667 mutex_unlock(&wl->mutex);
3658 3668
3669 if (do_rfkill_exit)
3670 b43_rfkill_exit(dev);
3671
3659 return err; 3672 return err;
3660} 3673}
3661 3674
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 3fc53e8b4416..7caa26eb4105 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -178,12 +178,12 @@ static u8 b43_calc_fallback_rate(u8 bitrate)
178} 178}
179 179
180/* Generate a TX data header. */ 180/* Generate a TX data header. */
181void b43_generate_txhdr(struct b43_wldev *dev, 181int b43_generate_txhdr(struct b43_wldev *dev,
182 u8 *_txhdr, 182 u8 *_txhdr,
183 const unsigned char *fragment_data, 183 const unsigned char *fragment_data,
184 unsigned int fragment_len, 184 unsigned int fragment_len,
185 const struct ieee80211_tx_control *txctl, 185 const struct ieee80211_tx_control *txctl,
186 u16 cookie) 186 u16 cookie)
187{ 187{
188 struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr; 188 struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr;
189 const struct b43_phy *phy = &dev->phy; 189 const struct b43_phy *phy = &dev->phy;
@@ -237,7 +237,15 @@ void b43_generate_txhdr(struct b43_wldev *dev,
237 237
238 B43_WARN_ON(key_idx >= dev->max_nr_keys); 238 B43_WARN_ON(key_idx >= dev->max_nr_keys);
239 key = &(dev->key[key_idx]); 239 key = &(dev->key[key_idx]);
240 B43_WARN_ON(!key->keyconf); 240
241 if (unlikely(!key->keyconf)) {
242 /* This key is invalid. This might only happen
243 * in a short timeframe after machine resume before
244 * we were able to reconfigure keys.
245 * Drop this packet completely. Do not transmit it
246 * unencrypted to avoid leaking information. */
247 return -ENOKEY;
248 }
241 249
242 /* Hardware appends ICV. */ 250 /* Hardware appends ICV. */
243 plcp_fragment_len += txctl->icv_len; 251 plcp_fragment_len += txctl->icv_len;
@@ -408,6 +416,7 @@ void b43_generate_txhdr(struct b43_wldev *dev,
408 txhdr->phy_ctl = cpu_to_le16(phy_ctl); 416 txhdr->phy_ctl = cpu_to_le16(phy_ctl);
409 txhdr->extra_ft = extra_ft; 417 txhdr->extra_ft = extra_ft;
410 418
419 return 0;
411} 420}
412 421
413static s8 b43_rssi_postprocess(struct b43_wldev *dev, 422static s8 b43_rssi_postprocess(struct b43_wldev *dev,
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h
index ca2a2ab8654c..41765039552b 100644
--- a/drivers/net/wireless/b43/xmit.h
+++ b/drivers/net/wireless/b43/xmit.h
@@ -174,11 +174,11 @@ size_t b43_txhdr_size(struct b43_wldev *dev)
174} 174}
175 175
176 176
177void b43_generate_txhdr(struct b43_wldev *dev, 177int b43_generate_txhdr(struct b43_wldev *dev,
178 u8 * txhdr, 178 u8 * txhdr,
179 const unsigned char *fragment_data, 179 const unsigned char *fragment_data,
180 unsigned int fragment_len, 180 unsigned int fragment_len,
181 const struct ieee80211_tx_control *txctl, u16 cookie); 181 const struct ieee80211_tx_control *txctl, u16 cookie);
182 182
183/* Transmit Status */ 183/* Transmit Status */
184struct b43_txstatus { 184struct b43_txstatus {