diff options
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r-- | drivers/net/wireless/b43/dma.c | 30 | ||||
-rw-r--r-- | drivers/net/wireless/b43/main.c | 19 | ||||
-rw-r--r-- | drivers/net/wireless/b43/xmit.c | 23 | ||||
-rw-r--r-- | drivers/net/wireless/b43/xmit.h | 10 |
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. */ |
181 | void b43_generate_txhdr(struct b43_wldev *dev, | 181 | int 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 | ||
413 | static s8 b43_rssi_postprocess(struct b43_wldev *dev, | 422 | static 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 | ||
177 | void b43_generate_txhdr(struct b43_wldev *dev, | 177 | int 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 */ |
184 | struct b43_txstatus { | 184 | struct b43_txstatus { |