aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43legacy/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/b43legacy/main.c')
-rw-r--r--drivers/net/wireless/b43legacy/main.c159
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 */
104static struct ieee80211_rate __b43legacy_ratetable[] = { 107static 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 }
136static struct ieee80211_channel b43legacy_bg_chantable[] = { 131static 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
148static 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
155static 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
154static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev); 162static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev);
155static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev); 163static 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
970static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, 978static 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 */
1000static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, 1008static 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
1055static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev, 1064static 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;