diff options
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r-- | drivers/net/wireless/b43/b43.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/b43/debugfs.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/b43/debugfs.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/b43/dma.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/b43/main.c | 280 | ||||
-rw-r--r-- | drivers/net/wireless/b43/phy_a.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/b43/phy_common.c | 18 | ||||
-rw-r--r-- | drivers/net/wireless/b43/phy_g.c | 28 | ||||
-rw-r--r-- | drivers/net/wireless/b43/pio.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/b43/xmit.c | 64 | ||||
-rw-r--r-- | drivers/net/wireless/b43/xmit.h | 5 |
11 files changed, 258 insertions, 151 deletions
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 427b8203e3f9..a53c378e7484 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -718,7 +718,6 @@ struct b43_wldev { | |||
718 | 718 | ||
719 | bool bad_frames_preempt; /* Use "Bad Frames Preemption" (default off) */ | 719 | bool bad_frames_preempt; /* Use "Bad Frames Preemption" (default off) */ |
720 | bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */ | 720 | bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */ |
721 | bool short_slot; /* TRUE, if short slot timing is enabled. */ | ||
722 | bool radio_hw_enable; /* saved state of radio hardware enabled state */ | 721 | bool radio_hw_enable; /* saved state of radio hardware enabled state */ |
723 | bool suspend_in_progress; /* TRUE, if we are in a suspend/resume cycle */ | 722 | bool suspend_in_progress; /* TRUE, if we are in a suspend/resume cycle */ |
724 | 723 | ||
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c index 06a01da80160..e04fc91f569e 100644 --- a/drivers/net/wireless/b43/debugfs.c +++ b/drivers/net/wireless/b43/debugfs.c | |||
@@ -731,6 +731,7 @@ static void b43_add_dynamic_debug(struct b43_wldev *dev) | |||
731 | add_dyn_dbg("debug_pwork_stop", B43_DBG_PWORK_STOP, 0); | 731 | add_dyn_dbg("debug_pwork_stop", B43_DBG_PWORK_STOP, 0); |
732 | add_dyn_dbg("debug_lo", B43_DBG_LO, 0); | 732 | add_dyn_dbg("debug_lo", B43_DBG_LO, 0); |
733 | add_dyn_dbg("debug_firmware", B43_DBG_FIRMWARE, 0); | 733 | add_dyn_dbg("debug_firmware", B43_DBG_FIRMWARE, 0); |
734 | add_dyn_dbg("debug_keys", B43_DBG_KEYS, 0); | ||
734 | 735 | ||
735 | #undef add_dyn_dbg | 736 | #undef add_dyn_dbg |
736 | } | 737 | } |
diff --git a/drivers/net/wireless/b43/debugfs.h b/drivers/net/wireless/b43/debugfs.h index 22ffd02ba554..7886cbe2d1d1 100644 --- a/drivers/net/wireless/b43/debugfs.h +++ b/drivers/net/wireless/b43/debugfs.h | |||
@@ -12,6 +12,7 @@ enum b43_dyndbg { /* Dynamic debugging features */ | |||
12 | B43_DBG_PWORK_STOP, | 12 | B43_DBG_PWORK_STOP, |
13 | B43_DBG_LO, | 13 | B43_DBG_LO, |
14 | B43_DBG_FIRMWARE, | 14 | B43_DBG_FIRMWARE, |
15 | B43_DBG_KEYS, | ||
15 | __B43_NR_DYNDBG, | 16 | __B43_NR_DYNDBG, |
16 | }; | 17 | }; |
17 | 18 | ||
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 098f886976f6..6d65a02b7052 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
@@ -1387,13 +1387,11 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, | |||
1387 | 1387 | ||
1388 | info = IEEE80211_SKB_CB(meta->skb); | 1388 | info = IEEE80211_SKB_CB(meta->skb); |
1389 | 1389 | ||
1390 | memset(&info->status, 0, sizeof(info->status)); | ||
1391 | |||
1392 | /* | 1390 | /* |
1393 | * Call back to inform the ieee80211 subsystem about | 1391 | * Call back to inform the ieee80211 subsystem about |
1394 | * the status of the transmission. | 1392 | * the status of the transmission. |
1395 | */ | 1393 | */ |
1396 | frame_succeed = b43_fill_txstatus_report(info, status); | 1394 | frame_succeed = b43_fill_txstatus_report(dev, info, status); |
1397 | #ifdef CONFIG_B43_DEBUG | 1395 | #ifdef CONFIG_B43_DEBUG |
1398 | if (frame_succeed) | 1396 | if (frame_succeed) |
1399 | ring->nr_succeed_tx_packets++; | 1397 | ring->nr_succeed_tx_packets++; |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 14c44df584d0..7b31a327b24a 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -703,13 +703,11 @@ static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time) | |||
703 | static void b43_short_slot_timing_enable(struct b43_wldev *dev) | 703 | static void b43_short_slot_timing_enable(struct b43_wldev *dev) |
704 | { | 704 | { |
705 | b43_set_slot_time(dev, 9); | 705 | b43_set_slot_time(dev, 9); |
706 | dev->short_slot = 1; | ||
707 | } | 706 | } |
708 | 707 | ||
709 | static void b43_short_slot_timing_disable(struct b43_wldev *dev) | 708 | static void b43_short_slot_timing_disable(struct b43_wldev *dev) |
710 | { | 709 | { |
711 | b43_set_slot_time(dev, 20); | 710 | b43_set_slot_time(dev, 20); |
712 | dev->short_slot = 0; | ||
713 | } | 711 | } |
714 | 712 | ||
715 | /* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable. | 713 | /* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable. |
@@ -994,6 +992,52 @@ static void b43_clear_keys(struct b43_wldev *dev) | |||
994 | b43_key_clear(dev, i); | 992 | b43_key_clear(dev, i); |
995 | } | 993 | } |
996 | 994 | ||
995 | static void b43_dump_keymemory(struct b43_wldev *dev) | ||
996 | { | ||
997 | unsigned int i, index, offset; | ||
998 | DECLARE_MAC_BUF(macbuf); | ||
999 | u8 mac[ETH_ALEN]; | ||
1000 | u16 algo; | ||
1001 | u32 rcmta0; | ||
1002 | u16 rcmta1; | ||
1003 | u64 hf; | ||
1004 | struct b43_key *key; | ||
1005 | |||
1006 | if (!b43_debug(dev, B43_DBG_KEYS)) | ||
1007 | return; | ||
1008 | |||
1009 | hf = b43_hf_read(dev); | ||
1010 | b43dbg(dev->wl, "Hardware key memory dump: USEDEFKEYS=%u\n", | ||
1011 | !!(hf & B43_HF_USEDEFKEYS)); | ||
1012 | for (index = 0; index < dev->max_nr_keys; index++) { | ||
1013 | key = &(dev->key[index]); | ||
1014 | printk(KERN_DEBUG "Key slot %02u: %s", | ||
1015 | index, (key->keyconf == NULL) ? " " : "*"); | ||
1016 | offset = dev->ktp + (index * B43_SEC_KEYSIZE); | ||
1017 | for (i = 0; i < B43_SEC_KEYSIZE; i += 2) { | ||
1018 | u16 tmp = b43_shm_read16(dev, B43_SHM_SHARED, offset + i); | ||
1019 | printk("%02X%02X", (tmp & 0xFF), ((tmp >> 8) & 0xFF)); | ||
1020 | } | ||
1021 | |||
1022 | algo = b43_shm_read16(dev, B43_SHM_SHARED, | ||
1023 | B43_SHM_SH_KEYIDXBLOCK + (index * 2)); | ||
1024 | printk(" Algo: %04X/%02X", algo, key->algorithm); | ||
1025 | |||
1026 | if (index >= 4) { | ||
1027 | rcmta0 = b43_shm_read32(dev, B43_SHM_RCMTA, | ||
1028 | ((index - 4) * 2) + 0); | ||
1029 | rcmta1 = b43_shm_read16(dev, B43_SHM_RCMTA, | ||
1030 | ((index - 4) * 2) + 1); | ||
1031 | *((__le32 *)(&mac[0])) = cpu_to_le32(rcmta0); | ||
1032 | *((__le16 *)(&mac[4])) = cpu_to_le16(rcmta1); | ||
1033 | printk(" MAC: %s", | ||
1034 | print_mac(macbuf, mac)); | ||
1035 | } else | ||
1036 | printk(" DEFAULT KEY"); | ||
1037 | printk("\n"); | ||
1038 | } | ||
1039 | } | ||
1040 | |||
997 | void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags) | 1041 | void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags) |
998 | { | 1042 | { |
999 | u32 macctl; | 1043 | u32 macctl; |
@@ -1339,25 +1383,6 @@ u8 b43_ieee80211_antenna_sanitize(struct b43_wldev *dev, | |||
1339 | return antenna_nr; | 1383 | return antenna_nr; |
1340 | } | 1384 | } |
1341 | 1385 | ||
1342 | static int b43_antenna_from_ieee80211(struct b43_wldev *dev, u8 antenna) | ||
1343 | { | ||
1344 | antenna = b43_ieee80211_antenna_sanitize(dev, antenna); | ||
1345 | switch (antenna) { | ||
1346 | case 0: /* default/diversity */ | ||
1347 | return B43_ANTENNA_DEFAULT; | ||
1348 | case 1: /* Antenna 0 */ | ||
1349 | return B43_ANTENNA0; | ||
1350 | case 2: /* Antenna 1 */ | ||
1351 | return B43_ANTENNA1; | ||
1352 | case 3: /* Antenna 2 */ | ||
1353 | return B43_ANTENNA2; | ||
1354 | case 4: /* Antenna 3 */ | ||
1355 | return B43_ANTENNA3; | ||
1356 | default: | ||
1357 | return B43_ANTENNA_DEFAULT; | ||
1358 | } | ||
1359 | } | ||
1360 | |||
1361 | /* Convert a b43 antenna number value to the PHY TX control value. */ | 1386 | /* Convert a b43 antenna number value to the PHY TX control value. */ |
1362 | static u16 b43_antenna_to_phyctl(int antenna) | 1387 | static u16 b43_antenna_to_phyctl(int antenna) |
1363 | { | 1388 | { |
@@ -1399,7 +1424,7 @@ static void b43_write_beacon_template(struct b43_wldev *dev, | |||
1399 | len, ram_offset, shm_size_offset, rate); | 1424 | len, ram_offset, shm_size_offset, rate); |
1400 | 1425 | ||
1401 | /* Write the PHY TX control parameters. */ | 1426 | /* Write the PHY TX control parameters. */ |
1402 | antenna = b43_antenna_from_ieee80211(dev, info->antenna_sel_tx); | 1427 | antenna = B43_ANTENNA_DEFAULT; |
1403 | antenna = b43_antenna_to_phyctl(antenna); | 1428 | antenna = b43_antenna_to_phyctl(antenna); |
1404 | ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL); | 1429 | ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL); |
1405 | /* We can't send beacons with short preamble. Would get PHY errors. */ | 1430 | /* We can't send beacons with short preamble. Would get PHY errors. */ |
@@ -1693,25 +1718,6 @@ static void b43_update_templates(struct b43_wl *wl) | |||
1693 | queue_work(wl->hw->workqueue, &wl->beacon_update_trigger); | 1718 | queue_work(wl->hw->workqueue, &wl->beacon_update_trigger); |
1694 | } | 1719 | } |
1695 | 1720 | ||
1696 | static void b43_set_ssid(struct b43_wldev *dev, const u8 * ssid, u8 ssid_len) | ||
1697 | { | ||
1698 | u32 tmp; | ||
1699 | u16 i, len; | ||
1700 | |||
1701 | len = min((u16) ssid_len, (u16) 0x100); | ||
1702 | for (i = 0; i < len; i += sizeof(u32)) { | ||
1703 | tmp = (u32) (ssid[i + 0]); | ||
1704 | if (i + 1 < len) | ||
1705 | tmp |= (u32) (ssid[i + 1]) << 8; | ||
1706 | if (i + 2 < len) | ||
1707 | tmp |= (u32) (ssid[i + 2]) << 16; | ||
1708 | if (i + 3 < len) | ||
1709 | tmp |= (u32) (ssid[i + 3]) << 24; | ||
1710 | b43_shm_write32(dev, B43_SHM_SHARED, 0x380 + i, tmp); | ||
1711 | } | ||
1712 | b43_shm_write16(dev, B43_SHM_SHARED, 0x48, len); | ||
1713 | } | ||
1714 | |||
1715 | static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int) | 1721 | static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int) |
1716 | { | 1722 | { |
1717 | b43_time_lock(dev); | 1723 | b43_time_lock(dev); |
@@ -3339,15 +3345,31 @@ init_failure: | |||
3339 | return err; | 3345 | return err; |
3340 | } | 3346 | } |
3341 | 3347 | ||
3342 | static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) | 3348 | /* Write the short and long frame retry limit values. */ |
3349 | static void b43_set_retry_limits(struct b43_wldev *dev, | ||
3350 | unsigned int short_retry, | ||
3351 | unsigned int long_retry) | ||
3352 | { | ||
3353 | /* The retry limit is a 4-bit counter. Enforce this to avoid overflowing | ||
3354 | * the chip-internal counter. */ | ||
3355 | short_retry = min(short_retry, (unsigned int)0xF); | ||
3356 | long_retry = min(long_retry, (unsigned int)0xF); | ||
3357 | |||
3358 | b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_SRLIMIT, | ||
3359 | short_retry); | ||
3360 | b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_LRLIMIT, | ||
3361 | long_retry); | ||
3362 | } | ||
3363 | |||
3364 | static int b43_op_config(struct ieee80211_hw *hw, u32 changed) | ||
3343 | { | 3365 | { |
3344 | struct b43_wl *wl = hw_to_b43_wl(hw); | 3366 | struct b43_wl *wl = hw_to_b43_wl(hw); |
3345 | struct b43_wldev *dev; | 3367 | struct b43_wldev *dev; |
3346 | struct b43_phy *phy; | 3368 | struct b43_phy *phy; |
3369 | struct ieee80211_conf *conf = &hw->conf; | ||
3347 | unsigned long flags; | 3370 | unsigned long flags; |
3348 | int antenna; | 3371 | int antenna; |
3349 | int err = 0; | 3372 | int err = 0; |
3350 | u32 savedirqs; | ||
3351 | 3373 | ||
3352 | mutex_lock(&wl->mutex); | 3374 | mutex_lock(&wl->mutex); |
3353 | 3375 | ||
@@ -3358,33 +3380,20 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) | |||
3358 | dev = wl->current_dev; | 3380 | dev = wl->current_dev; |
3359 | phy = &dev->phy; | 3381 | phy = &dev->phy; |
3360 | 3382 | ||
3361 | /* Disable IRQs while reconfiguring the device. | 3383 | b43_mac_suspend(dev); |
3362 | * This makes it possible to drop the spinlock throughout | 3384 | |
3363 | * the reconfiguration process. */ | 3385 | if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) |
3364 | spin_lock_irqsave(&wl->irq_lock, flags); | 3386 | b43_set_retry_limits(dev, conf->short_frame_max_tx_count, |
3365 | if (b43_status(dev) < B43_STAT_STARTED) { | 3387 | conf->long_frame_max_tx_count); |
3366 | spin_unlock_irqrestore(&wl->irq_lock, flags); | 3388 | changed &= ~IEEE80211_CONF_CHANGE_RETRY_LIMITS; |
3367 | goto out_unlock_mutex; | 3389 | if (!changed) |
3368 | } | 3390 | goto out_mac_enable; |
3369 | savedirqs = b43_interrupt_disable(dev, B43_IRQ_ALL); | ||
3370 | spin_unlock_irqrestore(&wl->irq_lock, flags); | ||
3371 | b43_synchronize_irq(dev); | ||
3372 | 3391 | ||
3373 | /* Switch to the requested channel. | 3392 | /* Switch to the requested channel. |
3374 | * The firmware takes care of races with the TX handler. */ | 3393 | * The firmware takes care of races with the TX handler. */ |
3375 | if (conf->channel->hw_value != phy->channel) | 3394 | if (conf->channel->hw_value != phy->channel) |
3376 | b43_switch_channel(dev, conf->channel->hw_value); | 3395 | b43_switch_channel(dev, conf->channel->hw_value); |
3377 | 3396 | ||
3378 | /* Enable/Disable ShortSlot timing. */ | ||
3379 | if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) != | ||
3380 | dev->short_slot) { | ||
3381 | B43_WARN_ON(phy->type != B43_PHYTYPE_G); | ||
3382 | if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) | ||
3383 | b43_short_slot_timing_enable(dev); | ||
3384 | else | ||
3385 | b43_short_slot_timing_disable(dev); | ||
3386 | } | ||
3387 | |||
3388 | dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP); | 3397 | dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP); |
3389 | 3398 | ||
3390 | /* Adjust the desired TX power level. */ | 3399 | /* Adjust the desired TX power level. */ |
@@ -3399,9 +3408,9 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) | |||
3399 | } | 3408 | } |
3400 | 3409 | ||
3401 | /* Antennas for RX and management frame TX. */ | 3410 | /* Antennas for RX and management frame TX. */ |
3402 | antenna = b43_antenna_from_ieee80211(dev, conf->antenna_sel_tx); | 3411 | antenna = B43_ANTENNA_DEFAULT; |
3403 | b43_mgmtframe_txantenna(dev, antenna); | 3412 | b43_mgmtframe_txantenna(dev, antenna); |
3404 | antenna = b43_antenna_from_ieee80211(dev, conf->antenna_sel_rx); | 3413 | antenna = B43_ANTENNA_DEFAULT; |
3405 | if (phy->ops->set_rx_antenna) | 3414 | if (phy->ops->set_rx_antenna) |
3406 | phy->ops->set_rx_antenna(dev, antenna); | 3415 | phy->ops->set_rx_antenna(dev, antenna); |
3407 | 3416 | ||
@@ -3425,16 +3434,91 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) | |||
3425 | } | 3434 | } |
3426 | } | 3435 | } |
3427 | 3436 | ||
3428 | spin_lock_irqsave(&wl->irq_lock, flags); | 3437 | out_mac_enable: |
3429 | b43_interrupt_enable(dev, savedirqs); | 3438 | b43_mac_enable(dev); |
3430 | mmiowb(); | 3439 | out_unlock_mutex: |
3431 | spin_unlock_irqrestore(&wl->irq_lock, flags); | ||
3432 | out_unlock_mutex: | ||
3433 | mutex_unlock(&wl->mutex); | 3440 | mutex_unlock(&wl->mutex); |
3434 | 3441 | ||
3435 | return err; | 3442 | return err; |
3436 | } | 3443 | } |
3437 | 3444 | ||
3445 | static void b43_update_basic_rates(struct b43_wldev *dev, u64 brates) | ||
3446 | { | ||
3447 | struct ieee80211_supported_band *sband = | ||
3448 | dev->wl->hw->wiphy->bands[b43_current_band(dev->wl)]; | ||
3449 | struct ieee80211_rate *rate; | ||
3450 | int i; | ||
3451 | u16 basic, direct, offset, basic_offset, rateptr; | ||
3452 | |||
3453 | for (i = 0; i < sband->n_bitrates; i++) { | ||
3454 | rate = &sband->bitrates[i]; | ||
3455 | |||
3456 | if (b43_is_cck_rate(rate->hw_value)) { | ||
3457 | direct = B43_SHM_SH_CCKDIRECT; | ||
3458 | basic = B43_SHM_SH_CCKBASIC; | ||
3459 | offset = b43_plcp_get_ratecode_cck(rate->hw_value); | ||
3460 | offset &= 0xF; | ||
3461 | } else { | ||
3462 | direct = B43_SHM_SH_OFDMDIRECT; | ||
3463 | basic = B43_SHM_SH_OFDMBASIC; | ||
3464 | offset = b43_plcp_get_ratecode_ofdm(rate->hw_value); | ||
3465 | offset &= 0xF; | ||
3466 | } | ||
3467 | |||
3468 | rate = ieee80211_get_response_rate(sband, brates, rate->bitrate); | ||
3469 | |||
3470 | if (b43_is_cck_rate(rate->hw_value)) { | ||
3471 | basic_offset = b43_plcp_get_ratecode_cck(rate->hw_value); | ||
3472 | basic_offset &= 0xF; | ||
3473 | } else { | ||
3474 | basic_offset = b43_plcp_get_ratecode_ofdm(rate->hw_value); | ||
3475 | basic_offset &= 0xF; | ||
3476 | } | ||
3477 | |||
3478 | /* | ||
3479 | * Get the pointer that we need to point to | ||
3480 | * from the direct map | ||
3481 | */ | ||
3482 | rateptr = b43_shm_read16(dev, B43_SHM_SHARED, | ||
3483 | direct + 2 * basic_offset); | ||
3484 | /* and write it to the basic map */ | ||
3485 | b43_shm_write16(dev, B43_SHM_SHARED, basic + 2 * offset, | ||
3486 | rateptr); | ||
3487 | } | ||
3488 | } | ||
3489 | |||
3490 | static void b43_op_bss_info_changed(struct ieee80211_hw *hw, | ||
3491 | struct ieee80211_vif *vif, | ||
3492 | struct ieee80211_bss_conf *conf, | ||
3493 | u32 changed) | ||
3494 | { | ||
3495 | struct b43_wl *wl = hw_to_b43_wl(hw); | ||
3496 | struct b43_wldev *dev; | ||
3497 | |||
3498 | mutex_lock(&wl->mutex); | ||
3499 | |||
3500 | dev = wl->current_dev; | ||
3501 | if (!dev || b43_status(dev) < B43_STAT_STARTED) | ||
3502 | goto out_unlock_mutex; | ||
3503 | b43_mac_suspend(dev); | ||
3504 | |||
3505 | if (changed & BSS_CHANGED_BASIC_RATES) | ||
3506 | b43_update_basic_rates(dev, conf->basic_rates); | ||
3507 | |||
3508 | if (changed & BSS_CHANGED_ERP_SLOT) { | ||
3509 | if (conf->use_short_slot) | ||
3510 | b43_short_slot_timing_enable(dev); | ||
3511 | else | ||
3512 | b43_short_slot_timing_disable(dev); | ||
3513 | } | ||
3514 | |||
3515 | b43_mac_enable(dev); | ||
3516 | out_unlock_mutex: | ||
3517 | mutex_unlock(&wl->mutex); | ||
3518 | |||
3519 | return; | ||
3520 | } | ||
3521 | |||
3438 | static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 3522 | static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
3439 | const u8 *local_addr, const u8 *addr, | 3523 | const u8 *local_addr, const u8 *addr, |
3440 | struct ieee80211_key_conf *key) | 3524 | struct ieee80211_key_conf *key) |
@@ -3445,7 +3529,6 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3445 | u8 algorithm; | 3529 | u8 algorithm; |
3446 | u8 index; | 3530 | u8 index; |
3447 | int err; | 3531 | int err; |
3448 | DECLARE_MAC_BUF(mac); | ||
3449 | 3532 | ||
3450 | if (modparam_nohwcrypt) | 3533 | if (modparam_nohwcrypt) |
3451 | return -ENOSPC; /* User disabled HW-crypto */ | 3534 | return -ENOSPC; /* User disabled HW-crypto */ |
@@ -3528,15 +3611,18 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3528 | default: | 3611 | default: |
3529 | B43_WARN_ON(1); | 3612 | B43_WARN_ON(1); |
3530 | } | 3613 | } |
3614 | |||
3531 | out_unlock: | 3615 | out_unlock: |
3532 | spin_unlock_irqrestore(&wl->irq_lock, flags); | ||
3533 | mutex_unlock(&wl->mutex); | ||
3534 | if (!err) { | 3616 | if (!err) { |
3535 | b43dbg(wl, "%s hardware based encryption for keyidx: %d, " | 3617 | b43dbg(wl, "%s hardware based encryption for keyidx: %d, " |
3536 | "mac: %s\n", | 3618 | "mac: %pM\n", |
3537 | cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, | 3619 | cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, |
3538 | print_mac(mac, addr)); | 3620 | addr); |
3621 | b43_dump_keymemory(dev); | ||
3539 | } | 3622 | } |
3623 | spin_unlock_irqrestore(&wl->irq_lock, flags); | ||
3624 | mutex_unlock(&wl->mutex); | ||
3625 | |||
3540 | return err; | 3626 | return err; |
3541 | } | 3627 | } |
3542 | 3628 | ||
@@ -3598,8 +3684,6 @@ static int b43_op_config_interface(struct ieee80211_hw *hw, | |||
3598 | if (b43_is_mode(wl, NL80211_IFTYPE_AP) || | 3684 | if (b43_is_mode(wl, NL80211_IFTYPE_AP) || |
3599 | b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT)) { | 3685 | b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT)) { |
3600 | B43_WARN_ON(vif->type != wl->if_type); | 3686 | B43_WARN_ON(vif->type != wl->if_type); |
3601 | if (conf->changed & IEEE80211_IFCC_SSID) | ||
3602 | b43_set_ssid(dev, conf->ssid, conf->ssid_len); | ||
3603 | if (conf->changed & IEEE80211_IFCC_BEACON) | 3687 | if (conf->changed & IEEE80211_IFCC_BEACON) |
3604 | b43_update_templates(wl); | 3688 | b43_update_templates(wl); |
3605 | } else if (b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) { | 3689 | } else if (b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) { |
@@ -3878,22 +3962,6 @@ static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev) | |||
3878 | #endif /* CONFIG_SSB_DRIVER_PCICORE */ | 3962 | #endif /* CONFIG_SSB_DRIVER_PCICORE */ |
3879 | } | 3963 | } |
3880 | 3964 | ||
3881 | /* Write the short and long frame retry limit values. */ | ||
3882 | static void b43_set_retry_limits(struct b43_wldev *dev, | ||
3883 | unsigned int short_retry, | ||
3884 | unsigned int long_retry) | ||
3885 | { | ||
3886 | /* The retry limit is a 4-bit counter. Enforce this to avoid overflowing | ||
3887 | * the chip-internal counter. */ | ||
3888 | short_retry = min(short_retry, (unsigned int)0xF); | ||
3889 | long_retry = min(long_retry, (unsigned int)0xF); | ||
3890 | |||
3891 | b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_SRLIMIT, | ||
3892 | short_retry); | ||
3893 | b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_LRLIMIT, | ||
3894 | long_retry); | ||
3895 | } | ||
3896 | |||
3897 | static void b43_set_synth_pu_delay(struct b43_wldev *dev, bool idle) | 3965 | static void b43_set_synth_pu_delay(struct b43_wldev *dev, bool idle) |
3898 | { | 3966 | { |
3899 | u16 pu_delay; | 3967 | u16 pu_delay; |
@@ -4214,26 +4282,6 @@ static void b43_op_stop(struct ieee80211_hw *hw) | |||
4214 | cancel_work_sync(&(wl->txpower_adjust_work)); | 4282 | cancel_work_sync(&(wl->txpower_adjust_work)); |
4215 | } | 4283 | } |
4216 | 4284 | ||
4217 | static int b43_op_set_retry_limit(struct ieee80211_hw *hw, | ||
4218 | u32 short_retry_limit, u32 long_retry_limit) | ||
4219 | { | ||
4220 | struct b43_wl *wl = hw_to_b43_wl(hw); | ||
4221 | struct b43_wldev *dev; | ||
4222 | int err = 0; | ||
4223 | |||
4224 | mutex_lock(&wl->mutex); | ||
4225 | dev = wl->current_dev; | ||
4226 | if (unlikely(!dev || (b43_status(dev) < B43_STAT_INITIALIZED))) { | ||
4227 | err = -ENODEV; | ||
4228 | goto out_unlock; | ||
4229 | } | ||
4230 | b43_set_retry_limits(dev, short_retry_limit, long_retry_limit); | ||
4231 | out_unlock: | ||
4232 | mutex_unlock(&wl->mutex); | ||
4233 | |||
4234 | return err; | ||
4235 | } | ||
4236 | |||
4237 | static int b43_op_beacon_set_tim(struct ieee80211_hw *hw, | 4285 | static int b43_op_beacon_set_tim(struct ieee80211_hw *hw, |
4238 | struct ieee80211_sta *sta, bool set) | 4286 | struct ieee80211_sta *sta, bool set) |
4239 | { | 4287 | { |
@@ -4263,6 +4311,7 @@ static const struct ieee80211_ops b43_hw_ops = { | |||
4263 | .add_interface = b43_op_add_interface, | 4311 | .add_interface = b43_op_add_interface, |
4264 | .remove_interface = b43_op_remove_interface, | 4312 | .remove_interface = b43_op_remove_interface, |
4265 | .config = b43_op_config, | 4313 | .config = b43_op_config, |
4314 | .bss_info_changed = b43_op_bss_info_changed, | ||
4266 | .config_interface = b43_op_config_interface, | 4315 | .config_interface = b43_op_config_interface, |
4267 | .configure_filter = b43_op_configure_filter, | 4316 | .configure_filter = b43_op_configure_filter, |
4268 | .set_key = b43_op_set_key, | 4317 | .set_key = b43_op_set_key, |
@@ -4270,7 +4319,6 @@ static const struct ieee80211_ops b43_hw_ops = { | |||
4270 | .get_tx_stats = b43_op_get_tx_stats, | 4319 | .get_tx_stats = b43_op_get_tx_stats, |
4271 | .start = b43_op_start, | 4320 | .start = b43_op_start, |
4272 | .stop = b43_op_stop, | 4321 | .stop = b43_op_stop, |
4273 | .set_retry_limit = b43_op_set_retry_limit, | ||
4274 | .set_tim = b43_op_beacon_set_tim, | 4322 | .set_tim = b43_op_beacon_set_tim, |
4275 | .sta_notify = b43_op_sta_notify, | 4323 | .sta_notify = b43_op_sta_notify, |
4276 | }; | 4324 | }; |
@@ -4588,7 +4636,7 @@ static int b43_wireless_init(struct ssb_device *dev) | |||
4588 | BIT(NL80211_IFTYPE_ADHOC); | 4636 | BIT(NL80211_IFTYPE_ADHOC); |
4589 | 4637 | ||
4590 | hw->queues = b43_modparam_qos ? 4 : 1; | 4638 | hw->queues = b43_modparam_qos ? 4 : 1; |
4591 | hw->max_altrates = 1; | 4639 | hw->max_rates = 2; |
4592 | SET_IEEE80211_DEV(hw, dev->dev); | 4640 | SET_IEEE80211_DEV(hw, dev->dev); |
4593 | if (is_valid_ether_addr(sprom->et1mac)) | 4641 | if (is_valid_ether_addr(sprom->et1mac)) |
4594 | SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac); | 4642 | SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac); |
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c index 0f1a84c9de61..7fe9d1701624 100644 --- a/drivers/net/wireless/b43/phy_a.c +++ b/drivers/net/wireless/b43/phy_a.c | |||
@@ -77,7 +77,7 @@ static s8 b43_aphy_estimate_power_out(struct b43_wldev *dev, s8 tssi) | |||
77 | } | 77 | } |
78 | #endif | 78 | #endif |
79 | 79 | ||
80 | void b43_radio_set_tx_iq(struct b43_wldev *dev) | 80 | static void b43_radio_set_tx_iq(struct b43_wldev *dev) |
81 | { | 81 | { |
82 | static const u8 data_high[5] = { 0x00, 0x40, 0x80, 0x90, 0xD0 }; | 82 | static const u8 data_high[5] = { 0x00, 0x40, 0x80, 0x90, 0xD0 }; |
83 | static const u8 data_low[5] = { 0x00, 0x01, 0x05, 0x06, 0x0A }; | 83 | static const u8 data_low[5] = { 0x00, 0x01, 0x05, 0x06, 0x0A }; |
@@ -147,7 +147,7 @@ static void aphy_channel_switch(struct b43_wldev *dev, unsigned int channel) | |||
147 | //FIXME b43_phy_xmitpower(dev); | 147 | //FIXME b43_phy_xmitpower(dev); |
148 | } | 148 | } |
149 | 149 | ||
150 | void b43_radio_init2060(struct b43_wldev *dev) | 150 | static void b43_radio_init2060(struct b43_wldev *dev) |
151 | { | 151 | { |
152 | b43_radio_write16(dev, 0x0004, 0x00C0); | 152 | b43_radio_write16(dev, 0x0004, 0x00C0); |
153 | b43_radio_write16(dev, 0x0005, 0x0008); | 153 | b43_radio_write16(dev, 0x0005, 0x0008); |
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index af37abccccb3..026b61c03fb9 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c | |||
@@ -178,13 +178,27 @@ void b43_phy_unlock(struct b43_wldev *dev) | |||
178 | b43_power_saving_ctl_bits(dev, 0); | 178 | b43_power_saving_ctl_bits(dev, 0); |
179 | } | 179 | } |
180 | 180 | ||
181 | static inline void assert_mac_suspended(struct b43_wldev *dev) | ||
182 | { | ||
183 | if (!B43_DEBUG) | ||
184 | return; | ||
185 | if ((b43_status(dev) >= B43_STAT_INITIALIZED) && | ||
186 | (dev->mac_suspended <= 0)) { | ||
187 | b43dbg(dev->wl, "PHY/RADIO register access with " | ||
188 | "enabled MAC.\n"); | ||
189 | dump_stack(); | ||
190 | } | ||
191 | } | ||
192 | |||
181 | u16 b43_radio_read(struct b43_wldev *dev, u16 reg) | 193 | u16 b43_radio_read(struct b43_wldev *dev, u16 reg) |
182 | { | 194 | { |
195 | assert_mac_suspended(dev); | ||
183 | return dev->phy.ops->radio_read(dev, reg); | 196 | return dev->phy.ops->radio_read(dev, reg); |
184 | } | 197 | } |
185 | 198 | ||
186 | void b43_radio_write(struct b43_wldev *dev, u16 reg, u16 value) | 199 | void b43_radio_write(struct b43_wldev *dev, u16 reg, u16 value) |
187 | { | 200 | { |
201 | assert_mac_suspended(dev); | ||
188 | dev->phy.ops->radio_write(dev, reg, value); | 202 | dev->phy.ops->radio_write(dev, reg, value); |
189 | } | 203 | } |
190 | 204 | ||
@@ -208,11 +222,13 @@ void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set) | |||
208 | 222 | ||
209 | u16 b43_phy_read(struct b43_wldev *dev, u16 reg) | 223 | u16 b43_phy_read(struct b43_wldev *dev, u16 reg) |
210 | { | 224 | { |
225 | assert_mac_suspended(dev); | ||
211 | return dev->phy.ops->phy_read(dev, reg); | 226 | return dev->phy.ops->phy_read(dev, reg); |
212 | } | 227 | } |
213 | 228 | ||
214 | void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value) | 229 | void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value) |
215 | { | 230 | { |
231 | assert_mac_suspended(dev); | ||
216 | dev->phy.ops->phy_write(dev, reg, value); | 232 | dev->phy.ops->phy_write(dev, reg, value); |
217 | } | 233 | } |
218 | 234 | ||
@@ -280,8 +296,10 @@ void b43_software_rfkill(struct b43_wldev *dev, enum rfkill_state state) | |||
280 | state = RFKILL_STATE_SOFT_BLOCKED; | 296 | state = RFKILL_STATE_SOFT_BLOCKED; |
281 | } | 297 | } |
282 | 298 | ||
299 | b43_mac_suspend(dev); | ||
283 | phy->ops->software_rfkill(dev, state); | 300 | phy->ops->software_rfkill(dev, state); |
284 | phy->radio_on = (state == RFKILL_STATE_UNBLOCKED); | 301 | phy->radio_on = (state == RFKILL_STATE_UNBLOCKED); |
302 | b43_mac_enable(dev); | ||
285 | } | 303 | } |
286 | 304 | ||
287 | /** | 305 | /** |
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c index 232181f6333c..caac4a45f0bf 100644 --- a/drivers/net/wireless/b43/phy_g.c +++ b/drivers/net/wireless/b43/phy_g.c | |||
@@ -54,7 +54,7 @@ static const s8 b43_tssi2dbm_g_table[] = { | |||
54 | -20, -20, -20, -20, | 54 | -20, -20, -20, -20, |
55 | }; | 55 | }; |
56 | 56 | ||
57 | const u8 b43_radio_channel_codes_bg[] = { | 57 | static const u8 b43_radio_channel_codes_bg[] = { |
58 | 12, 17, 22, 27, | 58 | 12, 17, 22, 27, |
59 | 32, 37, 42, 47, | 59 | 32, 37, 42, 47, |
60 | 52, 57, 62, 67, | 60 | 52, 57, 62, 67, |
@@ -215,9 +215,9 @@ void b43_gphy_set_baseband_attenuation(struct b43_wldev *dev, | |||
215 | } | 215 | } |
216 | 216 | ||
217 | /* Adjust the transmission power output (G-PHY) */ | 217 | /* Adjust the transmission power output (G-PHY) */ |
218 | void b43_set_txpower_g(struct b43_wldev *dev, | 218 | static void b43_set_txpower_g(struct b43_wldev *dev, |
219 | const struct b43_bbatt *bbatt, | 219 | const struct b43_bbatt *bbatt, |
220 | const struct b43_rfatt *rfatt, u8 tx_control) | 220 | const struct b43_rfatt *rfatt, u8 tx_control) |
221 | { | 221 | { |
222 | struct b43_phy *phy = &dev->phy; | 222 | struct b43_phy *phy = &dev->phy; |
223 | struct b43_phy_g *gphy = phy->g; | 223 | struct b43_phy_g *gphy = phy->g; |
@@ -383,14 +383,14 @@ static void b43_set_original_gains(struct b43_wldev *dev) | |||
383 | } | 383 | } |
384 | 384 | ||
385 | /* http://bcm-specs.sipsolutions.net/NRSSILookupTable */ | 385 | /* http://bcm-specs.sipsolutions.net/NRSSILookupTable */ |
386 | void b43_nrssi_hw_write(struct b43_wldev *dev, u16 offset, s16 val) | 386 | static void b43_nrssi_hw_write(struct b43_wldev *dev, u16 offset, s16 val) |
387 | { | 387 | { |
388 | b43_phy_write(dev, B43_PHY_NRSSILT_CTRL, offset); | 388 | b43_phy_write(dev, B43_PHY_NRSSILT_CTRL, offset); |
389 | b43_phy_write(dev, B43_PHY_NRSSILT_DATA, (u16) val); | 389 | b43_phy_write(dev, B43_PHY_NRSSILT_DATA, (u16) val); |
390 | } | 390 | } |
391 | 391 | ||
392 | /* http://bcm-specs.sipsolutions.net/NRSSILookupTable */ | 392 | /* http://bcm-specs.sipsolutions.net/NRSSILookupTable */ |
393 | s16 b43_nrssi_hw_read(struct b43_wldev *dev, u16 offset) | 393 | static s16 b43_nrssi_hw_read(struct b43_wldev *dev, u16 offset) |
394 | { | 394 | { |
395 | u16 val; | 395 | u16 val; |
396 | 396 | ||
@@ -401,7 +401,7 @@ s16 b43_nrssi_hw_read(struct b43_wldev *dev, u16 offset) | |||
401 | } | 401 | } |
402 | 402 | ||
403 | /* http://bcm-specs.sipsolutions.net/NRSSILookupTable */ | 403 | /* http://bcm-specs.sipsolutions.net/NRSSILookupTable */ |
404 | void b43_nrssi_hw_update(struct b43_wldev *dev, u16 val) | 404 | static void b43_nrssi_hw_update(struct b43_wldev *dev, u16 val) |
405 | { | 405 | { |
406 | u16 i; | 406 | u16 i; |
407 | s16 tmp; | 407 | s16 tmp; |
@@ -415,7 +415,7 @@ void b43_nrssi_hw_update(struct b43_wldev *dev, u16 val) | |||
415 | } | 415 | } |
416 | 416 | ||
417 | /* http://bcm-specs.sipsolutions.net/NRSSILookupTable */ | 417 | /* http://bcm-specs.sipsolutions.net/NRSSILookupTable */ |
418 | void b43_nrssi_mem_update(struct b43_wldev *dev) | 418 | static void b43_nrssi_mem_update(struct b43_wldev *dev) |
419 | { | 419 | { |
420 | struct b43_phy_g *gphy = dev->phy.g; | 420 | struct b43_phy_g *gphy = dev->phy.g; |
421 | s16 i, delta; | 421 | s16 i, delta; |
@@ -589,7 +589,7 @@ static void b43_calc_nrssi_offset(struct b43_wldev *dev) | |||
589 | b43_phy_write(dev, 0x0811, backup[1]); | 589 | b43_phy_write(dev, 0x0811, backup[1]); |
590 | } | 590 | } |
591 | 591 | ||
592 | void b43_calc_nrssi_slope(struct b43_wldev *dev) | 592 | static void b43_calc_nrssi_slope(struct b43_wldev *dev) |
593 | { | 593 | { |
594 | struct b43_phy *phy = &dev->phy; | 594 | struct b43_phy *phy = &dev->phy; |
595 | struct b43_phy_g *gphy = phy->g; | 595 | struct b43_phy_g *gphy = phy->g; |
@@ -1354,7 +1354,7 @@ struct init2050_saved_values { | |||
1354 | u16 phy_syncctl; | 1354 | u16 phy_syncctl; |
1355 | }; | 1355 | }; |
1356 | 1356 | ||
1357 | u16 b43_radio_init2050(struct b43_wldev *dev) | 1357 | static u16 b43_radio_init2050(struct b43_wldev *dev) |
1358 | { | 1358 | { |
1359 | struct b43_phy *phy = &dev->phy; | 1359 | struct b43_phy *phy = &dev->phy; |
1360 | struct init2050_saved_values sav; | 1360 | struct init2050_saved_values sav; |
@@ -3047,6 +3047,8 @@ static void b43_gphy_op_adjust_txpower(struct b43_wldev *dev) | |||
3047 | int rfatt, bbatt; | 3047 | int rfatt, bbatt; |
3048 | u8 tx_control; | 3048 | u8 tx_control; |
3049 | 3049 | ||
3050 | b43_mac_suspend(dev); | ||
3051 | |||
3050 | spin_lock_irq(&dev->wl->irq_lock); | 3052 | spin_lock_irq(&dev->wl->irq_lock); |
3051 | 3053 | ||
3052 | /* Calculate the new attenuation values. */ | 3054 | /* Calculate the new attenuation values. */ |
@@ -3103,6 +3105,8 @@ static void b43_gphy_op_adjust_txpower(struct b43_wldev *dev) | |||
3103 | gphy->tx_control); | 3105 | gphy->tx_control); |
3104 | b43_radio_unlock(dev); | 3106 | b43_radio_unlock(dev); |
3105 | b43_phy_unlock(dev); | 3107 | b43_phy_unlock(dev); |
3108 | |||
3109 | b43_mac_enable(dev); | ||
3106 | } | 3110 | } |
3107 | 3111 | ||
3108 | static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev, | 3112 | static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev, |
@@ -3215,9 +3219,9 @@ static void b43_gphy_op_pwork_15sec(struct b43_wldev *dev) | |||
3215 | struct b43_phy *phy = &dev->phy; | 3219 | struct b43_phy *phy = &dev->phy; |
3216 | struct b43_phy_g *gphy = phy->g; | 3220 | struct b43_phy_g *gphy = phy->g; |
3217 | 3221 | ||
3222 | b43_mac_suspend(dev); | ||
3218 | //TODO: update_aci_moving_average | 3223 | //TODO: update_aci_moving_average |
3219 | if (gphy->aci_enable && gphy->aci_wlan_automatic) { | 3224 | if (gphy->aci_enable && gphy->aci_wlan_automatic) { |
3220 | b43_mac_suspend(dev); | ||
3221 | if (!gphy->aci_enable && 1 /*TODO: not scanning? */ ) { | 3225 | if (!gphy->aci_enable && 1 /*TODO: not scanning? */ ) { |
3222 | if (0 /*TODO: bunch of conditions */ ) { | 3226 | if (0 /*TODO: bunch of conditions */ ) { |
3223 | phy->ops->interf_mitigation(dev, | 3227 | phy->ops->interf_mitigation(dev, |
@@ -3227,12 +3231,12 @@ static void b43_gphy_op_pwork_15sec(struct b43_wldev *dev) | |||
3227 | if (/*(aci_average > 1000) &&*/ !b43_gphy_aci_scan(dev)) | 3231 | if (/*(aci_average > 1000) &&*/ !b43_gphy_aci_scan(dev)) |
3228 | phy->ops->interf_mitigation(dev, B43_INTERFMODE_NONE); | 3232 | phy->ops->interf_mitigation(dev, B43_INTERFMODE_NONE); |
3229 | } | 3233 | } |
3230 | b43_mac_enable(dev); | ||
3231 | } else if (gphy->interfmode == B43_INTERFMODE_NONWLAN && | 3234 | } else if (gphy->interfmode == B43_INTERFMODE_NONWLAN && |
3232 | phy->rev == 1) { | 3235 | phy->rev == 1) { |
3233 | //TODO: implement rev1 workaround | 3236 | //TODO: implement rev1 workaround |
3234 | } | 3237 | } |
3235 | b43_lo_g_maintanance_work(dev); | 3238 | b43_lo_g_maintanance_work(dev); |
3239 | b43_mac_enable(dev); | ||
3236 | } | 3240 | } |
3237 | 3241 | ||
3238 | static void b43_gphy_op_pwork_60sec(struct b43_wldev *dev) | 3242 | static void b43_gphy_op_pwork_60sec(struct b43_wldev *dev) |
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c index 401591267592..1036bef8c4cc 100644 --- a/drivers/net/wireless/b43/pio.c +++ b/drivers/net/wireless/b43/pio.c | |||
@@ -587,9 +587,8 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev, | |||
587 | spin_lock(&q->lock); /* IRQs are already disabled. */ | 587 | spin_lock(&q->lock); /* IRQs are already disabled. */ |
588 | 588 | ||
589 | info = IEEE80211_SKB_CB(pack->skb); | 589 | info = IEEE80211_SKB_CB(pack->skb); |
590 | memset(&info->status, 0, sizeof(info->status)); | ||
591 | 590 | ||
592 | b43_fill_txstatus_report(info, status); | 591 | b43_fill_txstatus_report(dev, info, status); |
593 | 592 | ||
594 | total_len = pack->skb->len + b43_txhdr_size(dev); | 593 | total_len = pack->skb->len + b43_txhdr_size(dev); |
595 | total_len = roundup(total_len, 4); | 594 | total_len = roundup(total_len, 4); |
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index 2fabcf8f0474..eae9b8052658 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
@@ -46,7 +46,6 @@ static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp) | |||
46 | case 0x6E: | 46 | case 0x6E: |
47 | return 3; | 47 | return 3; |
48 | } | 48 | } |
49 | B43_WARN_ON(1); | ||
50 | return -1; | 49 | return -1; |
51 | } | 50 | } |
52 | 51 | ||
@@ -73,7 +72,6 @@ static u8 b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy) | |||
73 | case 0xC: | 72 | case 0xC: |
74 | return base + 7; | 73 | return base + 7; |
75 | } | 74 | } |
76 | B43_WARN_ON(1); | ||
77 | return -1; | 75 | return -1; |
78 | } | 76 | } |
79 | 77 | ||
@@ -185,7 +183,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
185 | u8 *_txhdr, | 183 | u8 *_txhdr, |
186 | const unsigned char *fragment_data, | 184 | const unsigned char *fragment_data, |
187 | unsigned int fragment_len, | 185 | unsigned int fragment_len, |
188 | const struct ieee80211_tx_info *info, | 186 | struct ieee80211_tx_info *info, |
189 | u16 cookie) | 187 | u16 cookie) |
190 | { | 188 | { |
191 | struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr; | 189 | struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr; |
@@ -202,6 +200,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
202 | u16 phy_ctl = 0; | 200 | u16 phy_ctl = 0; |
203 | u8 extra_ft = 0; | 201 | u8 extra_ft = 0; |
204 | struct ieee80211_rate *txrate; | 202 | struct ieee80211_rate *txrate; |
203 | struct ieee80211_tx_rate *rates; | ||
205 | 204 | ||
206 | memset(txhdr, 0, sizeof(*txhdr)); | 205 | memset(txhdr, 0, sizeof(*txhdr)); |
207 | 206 | ||
@@ -291,7 +290,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
291 | phy_ctl |= B43_TXH_PHY_ENC_OFDM; | 290 | phy_ctl |= B43_TXH_PHY_ENC_OFDM; |
292 | else | 291 | else |
293 | phy_ctl |= B43_TXH_PHY_ENC_CCK; | 292 | phy_ctl |= B43_TXH_PHY_ENC_CCK; |
294 | if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE) | 293 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) |
295 | phy_ctl |= B43_TXH_PHY_SHORTPRMBL; | 294 | phy_ctl |= B43_TXH_PHY_SHORTPRMBL; |
296 | 295 | ||
297 | switch (b43_ieee80211_antenna_sanitize(dev, info->antenna_sel_tx)) { | 296 | switch (b43_ieee80211_antenna_sanitize(dev, info->antenna_sel_tx)) { |
@@ -314,6 +313,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
314 | B43_WARN_ON(1); | 313 | B43_WARN_ON(1); |
315 | } | 314 | } |
316 | 315 | ||
316 | rates = info->control.rates; | ||
317 | /* MAC control */ | 317 | /* MAC control */ |
318 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) | 318 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) |
319 | mac_ctl |= B43_TXH_MAC_ACK; | 319 | mac_ctl |= B43_TXH_MAC_ACK; |
@@ -324,12 +324,22 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
324 | mac_ctl |= B43_TXH_MAC_STMSDU; | 324 | mac_ctl |= B43_TXH_MAC_STMSDU; |
325 | if (phy->type == B43_PHYTYPE_A) | 325 | if (phy->type == B43_PHYTYPE_A) |
326 | mac_ctl |= B43_TXH_MAC_5GHZ; | 326 | mac_ctl |= B43_TXH_MAC_5GHZ; |
327 | if (info->flags & IEEE80211_TX_CTL_LONG_RETRY_LIMIT) | 327 | |
328 | /* Overwrite rates[0].count to make the retry calculation | ||
329 | * in the tx status easier. need the actual retry limit to | ||
330 | * detect whether the fallback rate was used. | ||
331 | */ | ||
332 | if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || | ||
333 | (rates[0].count <= dev->wl->hw->conf.long_frame_max_tx_count)) { | ||
334 | rates[0].count = dev->wl->hw->conf.long_frame_max_tx_count; | ||
328 | mac_ctl |= B43_TXH_MAC_LONGFRAME; | 335 | mac_ctl |= B43_TXH_MAC_LONGFRAME; |
336 | } else { | ||
337 | rates[0].count = dev->wl->hw->conf.short_frame_max_tx_count; | ||
338 | } | ||
329 | 339 | ||
330 | /* Generate the RTS or CTS-to-self frame */ | 340 | /* Generate the RTS or CTS-to-self frame */ |
331 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) || | 341 | if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || |
332 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) { | 342 | (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) { |
333 | unsigned int len; | 343 | unsigned int len; |
334 | struct ieee80211_hdr *hdr; | 344 | struct ieee80211_hdr *hdr; |
335 | int rts_rate, rts_rate_fb; | 345 | int rts_rate, rts_rate_fb; |
@@ -344,7 +354,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
344 | rts_rate_fb = b43_calc_fallback_rate(rts_rate); | 354 | rts_rate_fb = b43_calc_fallback_rate(rts_rate); |
345 | rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb); | 355 | rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb); |
346 | 356 | ||
347 | if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) { | 357 | if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { |
348 | struct ieee80211_cts *cts; | 358 | struct ieee80211_cts *cts; |
349 | 359 | ||
350 | if (b43_is_old_txhdr_format(dev)) { | 360 | if (b43_is_old_txhdr_format(dev)) { |
@@ -596,6 +606,8 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
596 | phytype == B43_PHYTYPE_A); | 606 | phytype == B43_PHYTYPE_A); |
597 | else | 607 | else |
598 | status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp); | 608 | status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp); |
609 | if (unlikely(status.rate_idx == -1)) | ||
610 | goto drop; | ||
599 | status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT); | 611 | status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT); |
600 | 612 | ||
601 | /* | 613 | /* |
@@ -687,10 +699,18 @@ void b43_handle_txstatus(struct b43_wldev *dev, | |||
687 | /* Fill out the mac80211 TXstatus report based on the b43-specific | 699 | /* Fill out the mac80211 TXstatus report based on the b43-specific |
688 | * txstatus report data. This returns a boolean whether the frame was | 700 | * txstatus report data. This returns a boolean whether the frame was |
689 | * successfully transmitted. */ | 701 | * successfully transmitted. */ |
690 | bool b43_fill_txstatus_report(struct ieee80211_tx_info *report, | 702 | bool b43_fill_txstatus_report(struct b43_wldev *dev, |
703 | struct ieee80211_tx_info *report, | ||
691 | const struct b43_txstatus *status) | 704 | const struct b43_txstatus *status) |
692 | { | 705 | { |
693 | bool frame_success = 1; | 706 | bool frame_success = 1; |
707 | int retry_limit; | ||
708 | |||
709 | /* preserve the confiured retry limit before clearing the status | ||
710 | * The xmit function has overwritten the rc's value with the actual | ||
711 | * retry limit done by the hardware */ | ||
712 | retry_limit = report->status.rates[0].count; | ||
713 | ieee80211_tx_info_clear_status(report); | ||
694 | 714 | ||
695 | if (status->acked) { | 715 | if (status->acked) { |
696 | /* The frame was ACKed. */ | 716 | /* The frame was ACKed. */ |
@@ -700,14 +720,32 @@ bool b43_fill_txstatus_report(struct ieee80211_tx_info *report, | |||
700 | if (!(report->flags & IEEE80211_TX_CTL_NO_ACK)) { | 720 | if (!(report->flags & IEEE80211_TX_CTL_NO_ACK)) { |
701 | /* ...but we expected an ACK. */ | 721 | /* ...but we expected an ACK. */ |
702 | frame_success = 0; | 722 | frame_success = 0; |
703 | report->status.excessive_retries = 1; | ||
704 | } | 723 | } |
705 | } | 724 | } |
706 | if (status->frame_count == 0) { | 725 | if (status->frame_count == 0) { |
707 | /* The frame was not transmitted at all. */ | 726 | /* The frame was not transmitted at all. */ |
708 | report->status.retry_count = 0; | 727 | report->status.rates[0].count = 0; |
709 | } else | 728 | } else if (status->rts_count > dev->wl->hw->conf.short_frame_max_tx_count) { |
710 | report->status.retry_count = status->frame_count - 1; | 729 | /* |
730 | * If the short retries (RTS, not data frame) have exceeded | ||
731 | * the limit, the hw will not have tried the selected rate, | ||
732 | * but will have used the fallback rate instead. | ||
733 | * Don't let the rate control count attempts for the selected | ||
734 | * rate in this case, otherwise the statistics will be off. | ||
735 | */ | ||
736 | report->status.rates[0].count = 0; | ||
737 | report->status.rates[1].count = status->frame_count; | ||
738 | } else { | ||
739 | if (status->frame_count > retry_limit) { | ||
740 | report->status.rates[0].count = retry_limit; | ||
741 | report->status.rates[1].count = status->frame_count - | ||
742 | retry_limit; | ||
743 | |||
744 | } else { | ||
745 | report->status.rates[0].count = status->frame_count; | ||
746 | report->status.rates[1].idx = -1; | ||
747 | } | ||
748 | } | ||
711 | 749 | ||
712 | return frame_success; | 750 | return frame_success; |
713 | } | 751 | } |
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h index 0215faf47541..4fb2a190f7a7 100644 --- a/drivers/net/wireless/b43/xmit.h +++ b/drivers/net/wireless/b43/xmit.h | |||
@@ -178,7 +178,7 @@ 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_info *txctl, u16 cookie); | 181 | struct ieee80211_tx_info *txctl, u16 cookie); |
182 | 182 | ||
183 | /* Transmit Status */ | 183 | /* Transmit Status */ |
184 | struct b43_txstatus { | 184 | struct b43_txstatus { |
@@ -294,7 +294,8 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr); | |||
294 | 294 | ||
295 | void b43_handle_txstatus(struct b43_wldev *dev, | 295 | void b43_handle_txstatus(struct b43_wldev *dev, |
296 | const struct b43_txstatus *status); | 296 | const struct b43_txstatus *status); |
297 | bool b43_fill_txstatus_report(struct ieee80211_tx_info *report, | 297 | bool b43_fill_txstatus_report(struct b43_wldev *dev, |
298 | struct ieee80211_tx_info *report, | ||
298 | const struct b43_txstatus *status); | 299 | const struct b43_txstatus *status); |
299 | 300 | ||
300 | void b43_tx_suspend(struct b43_wldev *dev); | 301 | void b43_tx_suspend(struct b43_wldev *dev); |