diff options
Diffstat (limited to 'drivers/net/wireless/b43legacy/main.c')
-rw-r--r-- | drivers/net/wireless/b43legacy/main.c | 159 |
1 files changed, 70 insertions, 89 deletions
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index c39de422e220..d2a72a2cd178 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -95,28 +95,29 @@ MODULE_DEVICE_TABLE(ssb, b43legacy_ssb_tbl); | |||
95 | * data in there. This data is the same for all devices, so we don't | 95 | * data in there. This data is the same for all devices, so we don't |
96 | * get concurrency issues */ | 96 | * get concurrency issues */ |
97 | #define RATETAB_ENT(_rateid, _flags) \ | 97 | #define RATETAB_ENT(_rateid, _flags) \ |
98 | { \ | 98 | { \ |
99 | .rate = B43legacy_RATE_TO_100KBPS(_rateid), \ | 99 | .bitrate = B43legacy_RATE_TO_100KBPS(_rateid), \ |
100 | .val = (_rateid), \ | 100 | .hw_value = (_rateid), \ |
101 | .val2 = (_rateid), \ | 101 | .flags = (_flags), \ |
102 | .flags = (_flags), \ | ||
103 | } | 102 | } |
103 | /* | ||
104 | * NOTE: When changing this, sync with xmit.c's | ||
105 | * b43legacy_plcp_get_bitrate_idx_* functions! | ||
106 | */ | ||
104 | static struct ieee80211_rate __b43legacy_ratetable[] = { | 107 | static struct ieee80211_rate __b43legacy_ratetable[] = { |
105 | RATETAB_ENT(B43legacy_CCK_RATE_1MB, IEEE80211_RATE_CCK), | 108 | RATETAB_ENT(B43legacy_CCK_RATE_1MB, 0), |
106 | RATETAB_ENT(B43legacy_CCK_RATE_2MB, IEEE80211_RATE_CCK_2), | 109 | RATETAB_ENT(B43legacy_CCK_RATE_2MB, IEEE80211_RATE_SHORT_PREAMBLE), |
107 | RATETAB_ENT(B43legacy_CCK_RATE_5MB, IEEE80211_RATE_CCK_2), | 110 | RATETAB_ENT(B43legacy_CCK_RATE_5MB, IEEE80211_RATE_SHORT_PREAMBLE), |
108 | RATETAB_ENT(B43legacy_CCK_RATE_11MB, IEEE80211_RATE_CCK_2), | 111 | RATETAB_ENT(B43legacy_CCK_RATE_11MB, IEEE80211_RATE_SHORT_PREAMBLE), |
109 | RATETAB_ENT(B43legacy_OFDM_RATE_6MB, IEEE80211_RATE_OFDM), | 112 | RATETAB_ENT(B43legacy_OFDM_RATE_6MB, 0), |
110 | RATETAB_ENT(B43legacy_OFDM_RATE_9MB, IEEE80211_RATE_OFDM), | 113 | RATETAB_ENT(B43legacy_OFDM_RATE_9MB, 0), |
111 | RATETAB_ENT(B43legacy_OFDM_RATE_12MB, IEEE80211_RATE_OFDM), | 114 | RATETAB_ENT(B43legacy_OFDM_RATE_12MB, 0), |
112 | RATETAB_ENT(B43legacy_OFDM_RATE_18MB, IEEE80211_RATE_OFDM), | 115 | RATETAB_ENT(B43legacy_OFDM_RATE_18MB, 0), |
113 | RATETAB_ENT(B43legacy_OFDM_RATE_24MB, IEEE80211_RATE_OFDM), | 116 | RATETAB_ENT(B43legacy_OFDM_RATE_24MB, 0), |
114 | RATETAB_ENT(B43legacy_OFDM_RATE_36MB, IEEE80211_RATE_OFDM), | 117 | RATETAB_ENT(B43legacy_OFDM_RATE_36MB, 0), |
115 | RATETAB_ENT(B43legacy_OFDM_RATE_48MB, IEEE80211_RATE_OFDM), | 118 | RATETAB_ENT(B43legacy_OFDM_RATE_48MB, 0), |
116 | RATETAB_ENT(B43legacy_OFDM_RATE_54MB, IEEE80211_RATE_OFDM), | 119 | RATETAB_ENT(B43legacy_OFDM_RATE_54MB, 0), |
117 | }; | 120 | }; |
118 | #define b43legacy_a_ratetable (__b43legacy_ratetable + 4) | ||
119 | #define b43legacy_a_ratetable_size 8 | ||
120 | #define b43legacy_b_ratetable (__b43legacy_ratetable + 0) | 121 | #define b43legacy_b_ratetable (__b43legacy_ratetable + 0) |
121 | #define b43legacy_b_ratetable_size 4 | 122 | #define b43legacy_b_ratetable_size 4 |
122 | #define b43legacy_g_ratetable (__b43legacy_ratetable + 0) | 123 | #define b43legacy_g_ratetable (__b43legacy_ratetable + 0) |
@@ -124,14 +125,8 @@ static struct ieee80211_rate __b43legacy_ratetable[] = { | |||
124 | 125 | ||
125 | #define CHANTAB_ENT(_chanid, _freq) \ | 126 | #define CHANTAB_ENT(_chanid, _freq) \ |
126 | { \ | 127 | { \ |
127 | .chan = (_chanid), \ | 128 | .center_freq = (_freq), \ |
128 | .freq = (_freq), \ | 129 | .hw_value = (_chanid), \ |
129 | .val = (_chanid), \ | ||
130 | .flag = IEEE80211_CHAN_W_SCAN | \ | ||
131 | IEEE80211_CHAN_W_ACTIVE_SCAN | \ | ||
132 | IEEE80211_CHAN_W_IBSS, \ | ||
133 | .power_level = 0x0A, \ | ||
134 | .antenna_max = 0xFF, \ | ||
135 | } | 130 | } |
136 | static struct ieee80211_channel b43legacy_bg_chantable[] = { | 131 | static struct ieee80211_channel b43legacy_bg_chantable[] = { |
137 | CHANTAB_ENT(1, 2412), | 132 | CHANTAB_ENT(1, 2412), |
@@ -149,7 +144,20 @@ static struct ieee80211_channel b43legacy_bg_chantable[] = { | |||
149 | CHANTAB_ENT(13, 2472), | 144 | CHANTAB_ENT(13, 2472), |
150 | CHANTAB_ENT(14, 2484), | 145 | CHANTAB_ENT(14, 2484), |
151 | }; | 146 | }; |
152 | #define b43legacy_bg_chantable_size ARRAY_SIZE(b43legacy_bg_chantable) | 147 | |
148 | static struct ieee80211_supported_band b43legacy_band_2GHz_BPHY = { | ||
149 | .channels = b43legacy_bg_chantable, | ||
150 | .n_channels = ARRAY_SIZE(b43legacy_bg_chantable), | ||
151 | .bitrates = b43legacy_b_ratetable, | ||
152 | .n_bitrates = b43legacy_b_ratetable_size, | ||
153 | }; | ||
154 | |||
155 | static struct ieee80211_supported_band b43legacy_band_2GHz_GPHY = { | ||
156 | .channels = b43legacy_bg_chantable, | ||
157 | .n_channels = ARRAY_SIZE(b43legacy_bg_chantable), | ||
158 | .bitrates = b43legacy_g_ratetable, | ||
159 | .n_bitrates = b43legacy_g_ratetable_size, | ||
160 | }; | ||
153 | 161 | ||
154 | static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev); | 162 | static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev); |
155 | static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev); | 163 | static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev); |
@@ -969,18 +977,18 @@ static void b43legacy_write_beacon_template(struct b43legacy_wldev *dev, | |||
969 | 977 | ||
970 | static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, | 978 | static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, |
971 | u16 shm_offset, u16 size, | 979 | u16 shm_offset, u16 size, |
972 | u8 rate) | 980 | struct ieee80211_rate *rate) |
973 | { | 981 | { |
974 | struct b43legacy_plcp_hdr4 plcp; | 982 | struct b43legacy_plcp_hdr4 plcp; |
975 | u32 tmp; | 983 | u32 tmp; |
976 | __le16 dur; | 984 | __le16 dur; |
977 | 985 | ||
978 | plcp.data = 0; | 986 | plcp.data = 0; |
979 | b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate); | 987 | b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->bitrate); |
980 | dur = ieee80211_generic_frame_duration(dev->wl->hw, | 988 | dur = ieee80211_generic_frame_duration(dev->wl->hw, |
981 | dev->wl->vif, | 989 | dev->wl->vif, |
982 | size, | 990 | size, |
983 | B43legacy_RATE_TO_100KBPS(rate)); | 991 | rate); |
984 | /* Write PLCP in two parts and timing for packet transfer */ | 992 | /* Write PLCP in two parts and timing for packet transfer */ |
985 | tmp = le32_to_cpu(plcp.data); | 993 | tmp = le32_to_cpu(plcp.data); |
986 | b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, shm_offset, | 994 | b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, shm_offset, |
@@ -998,7 +1006,8 @@ static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, | |||
998 | * 3) Stripping TIM | 1006 | * 3) Stripping TIM |
999 | */ | 1007 | */ |
1000 | static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, | 1008 | static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, |
1001 | u16 *dest_size, u8 rate) | 1009 | u16 *dest_size, |
1010 | struct ieee80211_rate *rate) | ||
1002 | { | 1011 | { |
1003 | const u8 *src_data; | 1012 | const u8 *src_data; |
1004 | u8 *dest_data; | 1013 | u8 *dest_data; |
@@ -1046,7 +1055,7 @@ static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, | |||
1046 | dur = ieee80211_generic_frame_duration(dev->wl->hw, | 1055 | dur = ieee80211_generic_frame_duration(dev->wl->hw, |
1047 | dev->wl->vif, | 1056 | dev->wl->vif, |
1048 | *dest_size, | 1057 | *dest_size, |
1049 | B43legacy_RATE_TO_100KBPS(rate)); | 1058 | rate); |
1050 | hdr->duration_id = dur; | 1059 | hdr->duration_id = dur; |
1051 | 1060 | ||
1052 | return dest_data; | 1061 | return dest_data; |
@@ -1054,7 +1063,8 @@ static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, | |||
1054 | 1063 | ||
1055 | static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev, | 1064 | static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev, |
1056 | u16 ram_offset, | 1065 | u16 ram_offset, |
1057 | u16 shm_size_offset, u8 rate) | 1066 | u16 shm_size_offset, |
1067 | struct ieee80211_rate *rate) | ||
1058 | { | 1068 | { |
1059 | u8 *probe_resp_data; | 1069 | u8 *probe_resp_data; |
1060 | u16 size; | 1070 | u16 size; |
@@ -1069,19 +1079,19 @@ static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev, | |||
1069 | * all possible basic rates | 1079 | * all possible basic rates |
1070 | */ | 1080 | */ |
1071 | b43legacy_write_probe_resp_plcp(dev, 0x31A, size, | 1081 | b43legacy_write_probe_resp_plcp(dev, 0x31A, size, |
1072 | B43legacy_CCK_RATE_1MB); | 1082 | &b43legacy_b_ratetable[0]); |
1073 | b43legacy_write_probe_resp_plcp(dev, 0x32C, size, | 1083 | b43legacy_write_probe_resp_plcp(dev, 0x32C, size, |
1074 | B43legacy_CCK_RATE_2MB); | 1084 | &b43legacy_b_ratetable[1]); |
1075 | b43legacy_write_probe_resp_plcp(dev, 0x33E, size, | 1085 | b43legacy_write_probe_resp_plcp(dev, 0x33E, size, |
1076 | B43legacy_CCK_RATE_5MB); | 1086 | &b43legacy_b_ratetable[2]); |
1077 | b43legacy_write_probe_resp_plcp(dev, 0x350, size, | 1087 | b43legacy_write_probe_resp_plcp(dev, 0x350, size, |
1078 | B43legacy_CCK_RATE_11MB); | 1088 | &b43legacy_b_ratetable[3]); |
1079 | 1089 | ||
1080 | size = min((size_t)size, | 1090 | size = min((size_t)size, |
1081 | 0x200 - sizeof(struct b43legacy_plcp_hdr6)); | 1091 | 0x200 - sizeof(struct b43legacy_plcp_hdr6)); |
1082 | b43legacy_write_template_common(dev, probe_resp_data, | 1092 | b43legacy_write_template_common(dev, probe_resp_data, |
1083 | size, ram_offset, | 1093 | size, ram_offset, |
1084 | shm_size_offset, rate); | 1094 | shm_size_offset, rate->bitrate); |
1085 | kfree(probe_resp_data); | 1095 | kfree(probe_resp_data); |
1086 | } | 1096 | } |
1087 | 1097 | ||
@@ -1106,7 +1116,7 @@ static void b43legacy_update_templates(struct b43legacy_wldev *dev) | |||
1106 | b43legacy_write_beacon_template(dev, 0x468, 0x1A, | 1116 | b43legacy_write_beacon_template(dev, 0x468, 0x1A, |
1107 | B43legacy_CCK_RATE_1MB); | 1117 | B43legacy_CCK_RATE_1MB); |
1108 | b43legacy_write_probe_resp_template(dev, 0x268, 0x4A, | 1118 | b43legacy_write_probe_resp_template(dev, 0x268, 0x4A, |
1109 | B43legacy_CCK_RATE_11MB); | 1119 | &b43legacy_b_ratetable[0]); |
1110 | 1120 | ||
1111 | status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); | 1121 | status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); |
1112 | status |= 0x03; | 1122 | status |= 0x03; |
@@ -2550,14 +2560,16 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, | |||
2550 | antenna_rx = b43legacy_antenna_from_ieee80211(conf->antenna_sel_rx); | 2560 | antenna_rx = b43legacy_antenna_from_ieee80211(conf->antenna_sel_rx); |
2551 | 2561 | ||
2552 | mutex_lock(&wl->mutex); | 2562 | mutex_lock(&wl->mutex); |
2563 | dev = wl->current_dev; | ||
2564 | phy = &dev->phy; | ||
2553 | 2565 | ||
2554 | /* Switch the PHY mode (if necessary). */ | 2566 | /* Switch the PHY mode (if necessary). */ |
2555 | switch (conf->phymode) { | 2567 | switch (conf->channel->band) { |
2556 | case MODE_IEEE80211B: | 2568 | case IEEE80211_BAND_2GHZ: |
2557 | new_phymode = B43legacy_PHYMODE_B; | 2569 | if (phy->type == B43legacy_PHYTYPE_B) |
2558 | break; | 2570 | new_phymode = B43legacy_PHYMODE_B; |
2559 | case MODE_IEEE80211G: | 2571 | else |
2560 | new_phymode = B43legacy_PHYMODE_G; | 2572 | new_phymode = B43legacy_PHYMODE_G; |
2561 | break; | 2573 | break; |
2562 | default: | 2574 | default: |
2563 | B43legacy_WARN_ON(1); | 2575 | B43legacy_WARN_ON(1); |
@@ -2565,8 +2577,6 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, | |||
2565 | err = b43legacy_switch_phymode(wl, new_phymode); | 2577 | err = b43legacy_switch_phymode(wl, new_phymode); |
2566 | if (err) | 2578 | if (err) |
2567 | goto out_unlock_mutex; | 2579 | goto out_unlock_mutex; |
2568 | dev = wl->current_dev; | ||
2569 | phy = &dev->phy; | ||
2570 | 2580 | ||
2571 | /* Disable IRQs while reconfiguring the device. | 2581 | /* Disable IRQs while reconfiguring the device. |
2572 | * This makes it possible to drop the spinlock throughout | 2582 | * This makes it possible to drop the spinlock throughout |
@@ -2582,8 +2592,8 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, | |||
2582 | 2592 | ||
2583 | /* Switch to the requested channel. | 2593 | /* Switch to the requested channel. |
2584 | * The firmware takes care of races with the TX handler. */ | 2594 | * The firmware takes care of races with the TX handler. */ |
2585 | if (conf->channel_val != phy->channel) | 2595 | if (conf->channel->hw_value != phy->channel) |
2586 | b43legacy_radio_selectchannel(dev, conf->channel_val, 0); | 2596 | b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0); |
2587 | 2597 | ||
2588 | /* Enable/Disable ShortSlot timing. */ | 2598 | /* Enable/Disable ShortSlot timing. */ |
2589 | if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) | 2599 | if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) |
@@ -3398,48 +3408,19 @@ static int b43legacy_setup_modes(struct b43legacy_wldev *dev, | |||
3398 | int have_gphy) | 3408 | int have_gphy) |
3399 | { | 3409 | { |
3400 | struct ieee80211_hw *hw = dev->wl->hw; | 3410 | struct ieee80211_hw *hw = dev->wl->hw; |
3401 | struct ieee80211_hw_mode *mode; | ||
3402 | struct b43legacy_phy *phy = &dev->phy; | 3411 | struct b43legacy_phy *phy = &dev->phy; |
3403 | int cnt = 0; | ||
3404 | int err; | ||
3405 | 3412 | ||
3406 | phy->possible_phymodes = 0; | 3413 | phy->possible_phymodes = 0; |
3407 | for (; 1; cnt++) { | 3414 | if (have_bphy) { |
3408 | if (have_bphy) { | 3415 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
3409 | B43legacy_WARN_ON(cnt >= B43legacy_MAX_PHYHWMODES); | 3416 | &b43legacy_band_2GHz_BPHY; |
3410 | mode = &phy->hwmodes[cnt]; | 3417 | phy->possible_phymodes |= B43legacy_PHYMODE_B; |
3411 | 3418 | } | |
3412 | mode->mode = MODE_IEEE80211B; | 3419 | |
3413 | mode->num_channels = b43legacy_bg_chantable_size; | 3420 | if (have_gphy) { |
3414 | mode->channels = b43legacy_bg_chantable; | 3421 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
3415 | mode->num_rates = b43legacy_b_ratetable_size; | 3422 | &b43legacy_band_2GHz_GPHY; |
3416 | mode->rates = b43legacy_b_ratetable; | 3423 | phy->possible_phymodes |= B43legacy_PHYMODE_G; |
3417 | err = ieee80211_register_hwmode(hw, mode); | ||
3418 | if (err) | ||
3419 | return err; | ||
3420 | |||
3421 | phy->possible_phymodes |= B43legacy_PHYMODE_B; | ||
3422 | have_bphy = 0; | ||
3423 | continue; | ||
3424 | } | ||
3425 | if (have_gphy) { | ||
3426 | B43legacy_WARN_ON(cnt >= B43legacy_MAX_PHYHWMODES); | ||
3427 | mode = &phy->hwmodes[cnt]; | ||
3428 | |||
3429 | mode->mode = MODE_IEEE80211G; | ||
3430 | mode->num_channels = b43legacy_bg_chantable_size; | ||
3431 | mode->channels = b43legacy_bg_chantable; | ||
3432 | mode->num_rates = b43legacy_g_ratetable_size; | ||
3433 | mode->rates = b43legacy_g_ratetable; | ||
3434 | err = ieee80211_register_hwmode(hw, mode); | ||
3435 | if (err) | ||
3436 | return err; | ||
3437 | |||
3438 | phy->possible_phymodes |= B43legacy_PHYMODE_G; | ||
3439 | have_gphy = 0; | ||
3440 | continue; | ||
3441 | } | ||
3442 | break; | ||
3443 | } | 3424 | } |
3444 | 3425 | ||
3445 | return 0; | 3426 | return 0; |