aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/b43/main.c')
-rw-r--r--drivers/net/wireless/b43/main.c317
1 files changed, 195 insertions, 122 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 017a041d07d0..071f61437c67 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -128,58 +128,143 @@ static struct ieee80211_rate __b43_ratetable[] = {
128#define b43_g_ratetable (__b43_ratetable + 0) 128#define b43_g_ratetable (__b43_ratetable + 0)
129#define b43_g_ratetable_size 12 129#define b43_g_ratetable_size 12
130 130
131#define CHANTAB_ENT(_chanid, _freq) \ 131#define CHAN4G(_channel, _freq, _flags) { \
132 { \ 132 .band = IEEE80211_BAND_2GHZ, \
133 .center_freq = (_freq), \ 133 .center_freq = (_freq), \
134 .hw_value = (_chanid), \ 134 .hw_value = (_channel), \
135 } 135 .flags = (_flags), \
136 .max_antenna_gain = 0, \
137 .max_power = 30, \
138}
136static struct ieee80211_channel b43_2ghz_chantable[] = { 139static struct ieee80211_channel b43_2ghz_chantable[] = {
137 CHANTAB_ENT(1, 2412), 140 CHAN4G(1, 2412, 0),
138 CHANTAB_ENT(2, 2417), 141 CHAN4G(2, 2417, 0),
139 CHANTAB_ENT(3, 2422), 142 CHAN4G(3, 2422, 0),
140 CHANTAB_ENT(4, 2427), 143 CHAN4G(4, 2427, 0),
141 CHANTAB_ENT(5, 2432), 144 CHAN4G(5, 2432, 0),
142 CHANTAB_ENT(6, 2437), 145 CHAN4G(6, 2437, 0),
143 CHANTAB_ENT(7, 2442), 146 CHAN4G(7, 2442, 0),
144 CHANTAB_ENT(8, 2447), 147 CHAN4G(8, 2447, 0),
145 CHANTAB_ENT(9, 2452), 148 CHAN4G(9, 2452, 0),
146 CHANTAB_ENT(10, 2457), 149 CHAN4G(10, 2457, 0),
147 CHANTAB_ENT(11, 2462), 150 CHAN4G(11, 2462, 0),
148 CHANTAB_ENT(12, 2467), 151 CHAN4G(12, 2467, 0),
149 CHANTAB_ENT(13, 2472), 152 CHAN4G(13, 2472, 0),
150 CHANTAB_ENT(14, 2484), 153 CHAN4G(14, 2484, 0),
154};
155#undef CHAN4G
156
157#define CHAN5G(_channel, _flags) { \
158 .band = IEEE80211_BAND_5GHZ, \
159 .center_freq = 5000 + (5 * (_channel)), \
160 .hw_value = (_channel), \
161 .flags = (_flags), \
162 .max_antenna_gain = 0, \
163 .max_power = 30, \
164}
165static struct ieee80211_channel b43_5ghz_nphy_chantable[] = {
166 CHAN5G(32, 0), CHAN5G(34, 0),
167 CHAN5G(36, 0), CHAN5G(38, 0),
168 CHAN5G(40, 0), CHAN5G(42, 0),
169 CHAN5G(44, 0), CHAN5G(46, 0),
170 CHAN5G(48, 0), CHAN5G(50, 0),
171 CHAN5G(52, 0), CHAN5G(54, 0),
172 CHAN5G(56, 0), CHAN5G(58, 0),
173 CHAN5G(60, 0), CHAN5G(62, 0),
174 CHAN5G(64, 0), CHAN5G(66, 0),
175 CHAN5G(68, 0), CHAN5G(70, 0),
176 CHAN5G(72, 0), CHAN5G(74, 0),
177 CHAN5G(76, 0), CHAN5G(78, 0),
178 CHAN5G(80, 0), CHAN5G(82, 0),
179 CHAN5G(84, 0), CHAN5G(86, 0),
180 CHAN5G(88, 0), CHAN5G(90, 0),
181 CHAN5G(92, 0), CHAN5G(94, 0),
182 CHAN5G(96, 0), CHAN5G(98, 0),
183 CHAN5G(100, 0), CHAN5G(102, 0),
184 CHAN5G(104, 0), CHAN5G(106, 0),
185 CHAN5G(108, 0), CHAN5G(110, 0),
186 CHAN5G(112, 0), CHAN5G(114, 0),
187 CHAN5G(116, 0), CHAN5G(118, 0),
188 CHAN5G(120, 0), CHAN5G(122, 0),
189 CHAN5G(124, 0), CHAN5G(126, 0),
190 CHAN5G(128, 0), CHAN5G(130, 0),
191 CHAN5G(132, 0), CHAN5G(134, 0),
192 CHAN5G(136, 0), CHAN5G(138, 0),
193 CHAN5G(140, 0), CHAN5G(142, 0),
194 CHAN5G(144, 0), CHAN5G(145, 0),
195 CHAN5G(146, 0), CHAN5G(147, 0),
196 CHAN5G(148, 0), CHAN5G(149, 0),
197 CHAN5G(150, 0), CHAN5G(151, 0),
198 CHAN5G(152, 0), CHAN5G(153, 0),
199 CHAN5G(154, 0), CHAN5G(155, 0),
200 CHAN5G(156, 0), CHAN5G(157, 0),
201 CHAN5G(158, 0), CHAN5G(159, 0),
202 CHAN5G(160, 0), CHAN5G(161, 0),
203 CHAN5G(162, 0), CHAN5G(163, 0),
204 CHAN5G(164, 0), CHAN5G(165, 0),
205 CHAN5G(166, 0), CHAN5G(168, 0),
206 CHAN5G(170, 0), CHAN5G(172, 0),
207 CHAN5G(174, 0), CHAN5G(176, 0),
208 CHAN5G(178, 0), CHAN5G(180, 0),
209 CHAN5G(182, 0), CHAN5G(184, 0),
210 CHAN5G(186, 0), CHAN5G(188, 0),
211 CHAN5G(190, 0), CHAN5G(192, 0),
212 CHAN5G(194, 0), CHAN5G(196, 0),
213 CHAN5G(198, 0), CHAN5G(200, 0),
214 CHAN5G(202, 0), CHAN5G(204, 0),
215 CHAN5G(206, 0), CHAN5G(208, 0),
216 CHAN5G(210, 0), CHAN5G(212, 0),
217 CHAN5G(214, 0), CHAN5G(216, 0),
218 CHAN5G(218, 0), CHAN5G(220, 0),
219 CHAN5G(222, 0), CHAN5G(224, 0),
220 CHAN5G(226, 0), CHAN5G(228, 0),
151}; 221};
152 222
153#ifdef NOTYET 223static struct ieee80211_channel b43_5ghz_aphy_chantable[] = {
154static struct ieee80211_channel b43_5ghz_chantable[] = { 224 CHAN5G(34, 0), CHAN5G(36, 0),
155 CHANTAB_ENT(36, 5180), 225 CHAN5G(38, 0), CHAN5G(40, 0),
156 CHANTAB_ENT(40, 5200), 226 CHAN5G(42, 0), CHAN5G(44, 0),
157 CHANTAB_ENT(44, 5220), 227 CHAN5G(46, 0), CHAN5G(48, 0),
158 CHANTAB_ENT(48, 5240), 228 CHAN5G(52, 0), CHAN5G(56, 0),
159 CHANTAB_ENT(52, 5260), 229 CHAN5G(60, 0), CHAN5G(64, 0),
160 CHANTAB_ENT(56, 5280), 230 CHAN5G(100, 0), CHAN5G(104, 0),
161 CHANTAB_ENT(60, 5300), 231 CHAN5G(108, 0), CHAN5G(112, 0),
162 CHANTAB_ENT(64, 5320), 232 CHAN5G(116, 0), CHAN5G(120, 0),
163 CHANTAB_ENT(149, 5745), 233 CHAN5G(124, 0), CHAN5G(128, 0),
164 CHANTAB_ENT(153, 5765), 234 CHAN5G(132, 0), CHAN5G(136, 0),
165 CHANTAB_ENT(157, 5785), 235 CHAN5G(140, 0), CHAN5G(149, 0),
166 CHANTAB_ENT(161, 5805), 236 CHAN5G(153, 0), CHAN5G(157, 0),
167 CHANTAB_ENT(165, 5825), 237 CHAN5G(161, 0), CHAN5G(165, 0),
238 CHAN5G(184, 0), CHAN5G(188, 0),
239 CHAN5G(192, 0), CHAN5G(196, 0),
240 CHAN5G(200, 0), CHAN5G(204, 0),
241 CHAN5G(208, 0), CHAN5G(212, 0),
242 CHAN5G(216, 0),
243};
244#undef CHAN5G
245
246static struct ieee80211_supported_band b43_band_5GHz_nphy = {
247 .band = IEEE80211_BAND_5GHZ,
248 .channels = b43_5ghz_nphy_chantable,
249 .n_channels = ARRAY_SIZE(b43_5ghz_nphy_chantable),
250 .bitrates = b43_a_ratetable,
251 .n_bitrates = b43_a_ratetable_size,
168}; 252};
169 253
170static struct ieee80211_supported_band b43_band_5GHz = { 254static struct ieee80211_supported_band b43_band_5GHz_aphy = {
171 .channels = b43_5ghz_chantable, 255 .band = IEEE80211_BAND_5GHZ,
172 .n_channels = ARRAY_SIZE(b43_5ghz_chantable), 256 .channels = b43_5ghz_aphy_chantable,
173 .bitrates = b43_a_ratetable, 257 .n_channels = ARRAY_SIZE(b43_5ghz_aphy_chantable),
174 .n_bitrates = b43_a_ratetable_size, 258 .bitrates = b43_a_ratetable,
259 .n_bitrates = b43_a_ratetable_size,
175}; 260};
176#endif
177 261
178static struct ieee80211_supported_band b43_band_2GHz = { 262static struct ieee80211_supported_band b43_band_2GHz = {
179 .channels = b43_2ghz_chantable, 263 .band = IEEE80211_BAND_2GHZ,
180 .n_channels = ARRAY_SIZE(b43_2ghz_chantable), 264 .channels = b43_2ghz_chantable,
181 .bitrates = b43_g_ratetable, 265 .n_channels = ARRAY_SIZE(b43_2ghz_chantable),
182 .n_bitrates = b43_g_ratetable_size, 266 .bitrates = b43_g_ratetable,
267 .n_bitrates = b43_g_ratetable_size,
183}; 268};
184 269
185static void b43_wireless_core_exit(struct b43_wldev *dev); 270static void b43_wireless_core_exit(struct b43_wldev *dev);
@@ -2657,45 +2742,6 @@ static int b43_op_get_stats(struct ieee80211_hw *hw,
2657 return 0; 2742 return 0;
2658} 2743}
2659 2744
2660static const char *phymode_to_string(unsigned int phymode)
2661{
2662 switch (phymode) {
2663 case B43_PHYMODE_A:
2664 return "A";
2665 case B43_PHYMODE_B:
2666 return "B";
2667 case B43_PHYMODE_G:
2668 return "G";
2669 default:
2670 B43_WARN_ON(1);
2671 }
2672 return "";
2673}
2674
2675static int find_wldev_for_phymode(struct b43_wl *wl,
2676 unsigned int phymode,
2677 struct b43_wldev **dev, bool * gmode)
2678{
2679 struct b43_wldev *d;
2680
2681 list_for_each_entry(d, &wl->devlist, list) {
2682 if (d->phy.possible_phymodes & phymode) {
2683 /* Ok, this device supports the PHY-mode.
2684 * Now figure out how the gmode bit has to be
2685 * set to support it. */
2686 if (phymode == B43_PHYMODE_A)
2687 *gmode = 0;
2688 else
2689 *gmode = 1;
2690 *dev = d;
2691
2692 return 0;
2693 }
2694 }
2695
2696 return -ESRCH;
2697}
2698
2699static void b43_put_phy_into_reset(struct b43_wldev *dev) 2745static void b43_put_phy_into_reset(struct b43_wldev *dev)
2700{ 2746{
2701 struct ssb_device *sdev = dev->dev; 2747 struct ssb_device *sdev = dev->dev;
@@ -2715,28 +2761,64 @@ static void b43_put_phy_into_reset(struct b43_wldev *dev)
2715 msleep(1); 2761 msleep(1);
2716} 2762}
2717 2763
2764static const char * band_to_string(enum ieee80211_band band)
2765{
2766 switch (band) {
2767 case IEEE80211_BAND_5GHZ:
2768 return "5";
2769 case IEEE80211_BAND_2GHZ:
2770 return "2.4";
2771 default:
2772 break;
2773 }
2774 B43_WARN_ON(1);
2775 return "";
2776}
2777
2718/* Expects wl->mutex locked */ 2778/* Expects wl->mutex locked */
2719static int b43_switch_phymode(struct b43_wl *wl, unsigned int new_mode) 2779static int b43_switch_band(struct b43_wl *wl, struct ieee80211_channel *chan)
2720{ 2780{
2721 struct b43_wldev *up_dev; 2781 struct b43_wldev *up_dev = NULL;
2722 struct b43_wldev *down_dev; 2782 struct b43_wldev *down_dev;
2783 struct b43_wldev *d;
2723 int err; 2784 int err;
2724 bool gmode = 0; 2785 bool gmode;
2725 int prev_status; 2786 int prev_status;
2726 2787
2727 err = find_wldev_for_phymode(wl, new_mode, &up_dev, &gmode); 2788 /* Find a device and PHY which supports the band. */
2728 if (err) { 2789 list_for_each_entry(d, &wl->devlist, list) {
2729 b43err(wl, "Could not find a device for %s-PHY mode\n", 2790 switch (chan->band) {
2730 phymode_to_string(new_mode)); 2791 case IEEE80211_BAND_5GHZ:
2731 return err; 2792 if (d->phy.supports_5ghz) {
2793 up_dev = d;
2794 gmode = 0;
2795 }
2796 break;
2797 case IEEE80211_BAND_2GHZ:
2798 if (d->phy.supports_2ghz) {
2799 up_dev = d;
2800 gmode = 1;
2801 }
2802 break;
2803 default:
2804 B43_WARN_ON(1);
2805 return -EINVAL;
2806 }
2807 if (up_dev)
2808 break;
2809 }
2810 if (!up_dev) {
2811 b43err(wl, "Could not find a device for %s-GHz band operation\n",
2812 band_to_string(chan->band));
2813 return -ENODEV;
2732 } 2814 }
2733 if ((up_dev == wl->current_dev) && 2815 if ((up_dev == wl->current_dev) &&
2734 (!!wl->current_dev->phy.gmode == !!gmode)) { 2816 (!!wl->current_dev->phy.gmode == !!gmode)) {
2735 /* This device is already running. */ 2817 /* This device is already running. */
2736 return 0; 2818 return 0;
2737 } 2819 }
2738 b43dbg(wl, "Reconfiguring PHYmode to %s-PHY\n", 2820 b43dbg(wl, "Switching to %s-GHz band\n",
2739 phymode_to_string(new_mode)); 2821 band_to_string(chan->band));
2740 down_dev = wl->current_dev; 2822 down_dev = wl->current_dev;
2741 2823
2742 prev_status = b43_status(down_dev); 2824 prev_status = b43_status(down_dev);
@@ -2758,8 +2840,8 @@ static int b43_switch_phymode(struct b43_wl *wl, unsigned int new_mode)
2758 err = b43_wireless_core_init(up_dev); 2840 err = b43_wireless_core_init(up_dev);
2759 if (err) { 2841 if (err) {
2760 b43err(wl, "Fatal: Could not initialize device for " 2842 b43err(wl, "Fatal: Could not initialize device for "
2761 "newly selected %s-PHY mode\n", 2843 "selected %s-GHz band\n",
2762 phymode_to_string(new_mode)); 2844 band_to_string(chan->band));
2763 goto init_failure; 2845 goto init_failure;
2764 } 2846 }
2765 } 2847 }
@@ -2767,8 +2849,8 @@ static int b43_switch_phymode(struct b43_wl *wl, unsigned int new_mode)
2767 err = b43_wireless_core_start(up_dev); 2849 err = b43_wireless_core_start(up_dev);
2768 if (err) { 2850 if (err) {
2769 b43err(wl, "Fatal: Coult not start device for " 2851 b43err(wl, "Fatal: Coult not start device for "
2770 "newly selected %s-PHY mode\n", 2852 "selected %s-GHz band\n",
2771 phymode_to_string(new_mode)); 2853 band_to_string(chan->band));
2772 b43_wireless_core_exit(up_dev); 2854 b43_wireless_core_exit(up_dev);
2773 goto init_failure; 2855 goto init_failure;
2774 } 2856 }
@@ -2778,7 +2860,7 @@ static int b43_switch_phymode(struct b43_wl *wl, unsigned int new_mode)
2778 wl->current_dev = up_dev; 2860 wl->current_dev = up_dev;
2779 2861
2780 return 0; 2862 return 0;
2781 init_failure: 2863init_failure:
2782 /* Whoops, failed to init the new core. No core is operating now. */ 2864 /* Whoops, failed to init the new core. No core is operating now. */
2783 wl->current_dev = NULL; 2865 wl->current_dev = NULL;
2784 return err; 2866 return err;
@@ -2836,25 +2918,14 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
2836 struct b43_wldev *dev; 2918 struct b43_wldev *dev;
2837 struct b43_phy *phy; 2919 struct b43_phy *phy;
2838 unsigned long flags; 2920 unsigned long flags;
2839 unsigned int new_phymode = 0xFFFF;
2840 int antenna; 2921 int antenna;
2841 int err = 0; 2922 int err = 0;
2842 u32 savedirqs; 2923 u32 savedirqs;
2843 2924
2844 mutex_lock(&wl->mutex); 2925 mutex_lock(&wl->mutex);
2845 2926
2846 /* Switch the PHY mode (if necessary). */ 2927 /* Switch the band (if necessary). This might change the active core. */
2847 switch (conf->channel->band) { 2928 err = b43_switch_band(wl, conf->channel);
2848 case IEEE80211_BAND_5GHZ:
2849 new_phymode = B43_PHYMODE_A;
2850 break;
2851 case IEEE80211_BAND_2GHZ:
2852 new_phymode = B43_PHYMODE_G;
2853 break;
2854 default:
2855 B43_WARN_ON(1);
2856 }
2857 err = b43_switch_phymode(wl, new_phymode);
2858 if (err) 2929 if (err)
2859 goto out_unlock_mutex; 2930 goto out_unlock_mutex;
2860 dev = wl->current_dev; 2931 dev = wl->current_dev;
@@ -3817,21 +3888,23 @@ static void b43_chip_reset(struct work_struct *work)
3817 b43info(wl, "Controller restarted\n"); 3888 b43info(wl, "Controller restarted\n");
3818} 3889}
3819 3890
3820static int b43_setup_modes(struct b43_wldev *dev, 3891static int b43_setup_bands(struct b43_wldev *dev,
3821 bool have_2ghz_phy, bool have_5ghz_phy) 3892 bool have_2ghz_phy, bool have_5ghz_phy)
3822{ 3893{
3823 struct ieee80211_hw *hw = dev->wl->hw; 3894 struct ieee80211_hw *hw = dev->wl->hw;
3824 struct b43_phy *phy = &dev->phy;
3825 3895
3826 /* XXX: This function will go away soon, when mac80211 3896 if (have_2ghz_phy)
3827 * band stuff is rewritten. So this is just a hack. 3897 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &b43_band_2GHz;
3828 * For now we always claim GPHY mode, as there is no 3898 if (dev->phy.type == B43_PHYTYPE_N) {
3829 * support for NPHY and APHY in the device, yet. 3899 if (have_5ghz_phy)
3830 * This assumption is OK, as any B, N or A PHY will already 3900 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_nphy;
3831 * have died a horrible sanity check death earlier. */ 3901 } else {
3902 if (have_5ghz_phy)
3903 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_aphy;
3904 }
3832 3905
3833 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &b43_band_2GHz; 3906 dev->phy.supports_2ghz = have_2ghz_phy;
3834 phy->possible_phymodes |= B43_PHYMODE_G; 3907 dev->phy.supports_5ghz = have_5ghz_phy;
3835 3908
3836 return 0; 3909 return 0;
3837} 3910}
@@ -3913,7 +3986,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
3913 err = b43_validate_chipaccess(dev); 3986 err = b43_validate_chipaccess(dev);
3914 if (err) 3987 if (err)
3915 goto err_powerdown; 3988 goto err_powerdown;
3916 err = b43_setup_modes(dev, have_2ghz_phy, have_5ghz_phy); 3989 err = b43_setup_bands(dev, have_2ghz_phy, have_5ghz_phy);
3917 if (err) 3990 if (err)
3918 goto err_powerdown; 3991 goto err_powerdown;
3919 3992