aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/main.c
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-08-27 12:53:02 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-08-29 16:24:12 -0400
commitef1a628d83fc0423c36e773281162be790503168 (patch)
tree436d3d7d91434febb1813dcea16060e6937288b9 /drivers/net/wireless/b43/main.c
parent35e032d82f3e2a9b0d92077b4fbc97166525ed53 (diff)
b43: Implement dynamic PHY API
This patch implements a dynamic "ops" based PHY API. This is needed in order to conveniently support future PHY types to avoid the "switch"-hell. This patch does not change any functionality. It just moves lots of code from one place to another and adjusts it for the changed data structures. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43/main.c')
-rw-r--r--drivers/net/wireless/b43/main.c172
1 files changed, 42 insertions, 130 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 7205a936ec74..af43f03b3189 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -44,7 +44,8 @@
44#include "b43.h" 44#include "b43.h"
45#include "main.h" 45#include "main.h"
46#include "debugfs.h" 46#include "debugfs.h"
47#include "phy.h" 47#include "phy_common.h"
48#include "phy_g.h"
48#include "nphy.h" 49#include "nphy.h"
49#include "dma.h" 50#include "dma.h"
50#include "pio.h" 51#include "pio.h"
@@ -1174,6 +1175,8 @@ static void b43_calculate_link_quality(struct b43_wldev *dev)
1174{ 1175{
1175 /* Top half of Link Quality calculation. */ 1176 /* Top half of Link Quality calculation. */
1176 1177
1178 if (dev->phy.type != B43_PHYTYPE_G)
1179 return;
1177 if (dev->noisecalc.calculation_running) 1180 if (dev->noisecalc.calculation_running)
1178 return; 1181 return;
1179 dev->noisecalc.calculation_running = 1; 1182 dev->noisecalc.calculation_running = 1;
@@ -1184,7 +1187,7 @@ static void b43_calculate_link_quality(struct b43_wldev *dev)
1184 1187
1185static void handle_irq_noise(struct b43_wldev *dev) 1188static void handle_irq_noise(struct b43_wldev *dev)
1186{ 1189{
1187 struct b43_phy *phy = &dev->phy; 1190 struct b43_phy_g *phy = dev->phy.g;
1188 u16 tmp; 1191 u16 tmp;
1189 u8 noise[4]; 1192 u8 noise[4];
1190 u8 i, j; 1193 u8 i, j;
@@ -1192,6 +1195,9 @@ static void handle_irq_noise(struct b43_wldev *dev)
1192 1195
1193 /* Bottom half of Link Quality calculation. */ 1196 /* Bottom half of Link Quality calculation. */
1194 1197
1198 if (dev->phy.type != B43_PHYTYPE_G)
1199 return;
1200
1195 /* Possible race condition: It might be possible that the user 1201 /* Possible race condition: It might be possible that the user
1196 * changed to a different channel in the meantime since we 1202 * changed to a different channel in the meantime since we
1197 * started the calculation. We ignore that fact, since it's 1203 * started the calculation. We ignore that fact, since it's
@@ -2688,9 +2694,7 @@ static void b43_mgmtframe_txantenna(struct b43_wldev *dev, int antenna)
2688/* This is the opposite of b43_chip_init() */ 2694/* This is the opposite of b43_chip_init() */
2689static void b43_chip_exit(struct b43_wldev *dev) 2695static void b43_chip_exit(struct b43_wldev *dev)
2690{ 2696{
2691 b43_radio_turn_off(dev, 1);
2692 b43_gpio_cleanup(dev); 2697 b43_gpio_cleanup(dev);
2693 b43_lo_g_cleanup(dev);
2694 /* firmware is released later */ 2698 /* firmware is released later */
2695} 2699}
2696 2700
@@ -2700,7 +2704,7 @@ static void b43_chip_exit(struct b43_wldev *dev)
2700static int b43_chip_init(struct b43_wldev *dev) 2704static int b43_chip_init(struct b43_wldev *dev)
2701{ 2705{
2702 struct b43_phy *phy = &dev->phy; 2706 struct b43_phy *phy = &dev->phy;
2703 int err, tmp; 2707 int err;
2704 u32 value32, macctl; 2708 u32 value32, macctl;
2705 u16 value16; 2709 u16 value16;
2706 2710
@@ -2725,19 +2729,19 @@ static int b43_chip_init(struct b43_wldev *dev)
2725 err = b43_upload_initvals(dev); 2729 err = b43_upload_initvals(dev);
2726 if (err) 2730 if (err)
2727 goto err_gpio_clean; 2731 goto err_gpio_clean;
2728 b43_radio_turn_on(dev);
2729 2732
2730 b43_write16(dev, 0x03E6, 0x0000); 2733 b43_write16(dev, 0x03E6, 0x0000);
2731 err = b43_phy_init(dev); 2734 err = b43_phy_init(dev);
2732 if (err) 2735 if (err)
2733 goto err_radio_off; 2736 goto err_gpio_clean;
2734 2737
2735 /* Select initial Interference Mitigation. */ 2738 /* Disable Interference Mitigation. */
2736 tmp = phy->interfmode; 2739 if (phy->ops->interf_mitigation)
2737 phy->interfmode = B43_INTERFMODE_NONE; 2740 phy->ops->interf_mitigation(dev, B43_INTERFMODE_NONE);
2738 b43_radio_set_interference_mitigation(dev, tmp);
2739 2741
2740 b43_set_rx_antenna(dev, B43_ANTENNA_DEFAULT); 2742 /* Select the antennae */
2743 if (phy->ops->set_rx_antenna)
2744 phy->ops->set_rx_antenna(dev, B43_ANTENNA_DEFAULT);
2741 b43_mgmtframe_txantenna(dev, B43_ANTENNA_DEFAULT); 2745 b43_mgmtframe_txantenna(dev, B43_ANTENNA_DEFAULT);
2742 2746
2743 if (phy->type == B43_PHYTYPE_B) { 2747 if (phy->type == B43_PHYTYPE_B) {
@@ -2790,8 +2794,6 @@ static int b43_chip_init(struct b43_wldev *dev)
2790out: 2794out:
2791 return err; 2795 return err;
2792 2796
2793err_radio_off:
2794 b43_radio_turn_off(dev, 1);
2795err_gpio_clean: 2797err_gpio_clean:
2796 b43_gpio_cleanup(dev); 2798 b43_gpio_cleanup(dev);
2797 return err; 2799 return err;
@@ -2799,25 +2801,10 @@ err_gpio_clean:
2799 2801
2800static void b43_periodic_every60sec(struct b43_wldev *dev) 2802static void b43_periodic_every60sec(struct b43_wldev *dev)
2801{ 2803{
2802 struct b43_phy *phy = &dev->phy; 2804 const struct b43_phy_operations *ops = dev->phy.ops;
2803 2805
2804 if (phy->type != B43_PHYTYPE_G) 2806 if (ops->pwork_60sec)
2805 return; 2807 ops->pwork_60sec(dev);
2806 if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI) {
2807 b43_mac_suspend(dev);
2808 b43_calc_nrssi_slope(dev);
2809 if ((phy->radio_ver == 0x2050) && (phy->radio_rev == 8)) {
2810 u8 old_chan = phy->channel;
2811
2812 /* VCO Calibration */
2813 if (old_chan >= 8)
2814 b43_radio_selectchannel(dev, 1, 0);
2815 else
2816 b43_radio_selectchannel(dev, 13, 0);
2817 b43_radio_selectchannel(dev, old_chan, 0);
2818 }
2819 b43_mac_enable(dev);
2820 }
2821} 2808}
2822 2809
2823static void b43_periodic_every30sec(struct b43_wldev *dev) 2810static void b43_periodic_every30sec(struct b43_wldev *dev)
@@ -2845,32 +2832,10 @@ static void b43_periodic_every15sec(struct b43_wldev *dev)
2845 } 2832 }
2846 } 2833 }
2847 2834
2848 if (phy->type == B43_PHYTYPE_G) { 2835 if (phy->ops->pwork_15sec)
2849 //TODO: update_aci_moving_average 2836 phy->ops->pwork_15sec(dev);
2850 if (phy->aci_enable && phy->aci_wlan_automatic) { 2837
2851 b43_mac_suspend(dev); 2838 phy->ops->xmitpower(dev);
2852 if (!phy->aci_enable && 1 /*TODO: not scanning? */ ) {
2853 if (0 /*TODO: bunch of conditions */ ) {
2854 b43_radio_set_interference_mitigation
2855 (dev, B43_INTERFMODE_MANUALWLAN);
2856 }
2857 } else if (1 /*TODO*/) {
2858 /*
2859 if ((aci_average > 1000) && !(b43_radio_aci_scan(dev))) {
2860 b43_radio_set_interference_mitigation(dev,
2861 B43_INTERFMODE_NONE);
2862 }
2863 */
2864 }
2865 b43_mac_enable(dev);
2866 } else if (phy->interfmode == B43_INTERFMODE_NONWLAN &&
2867 phy->rev == 1) {
2868 //TODO: implement rev1 workaround
2869 }
2870 }
2871 b43_phy_xmitpower(dev); //FIXME: unless scanning?
2872 b43_lo_g_maintanance_work(dev);
2873 //TODO for APHY (temperature?)
2874 2839
2875 atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT); 2840 atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT);
2876 wmb(); 2841 wmb();
@@ -3401,7 +3366,7 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
3401 /* Switch to the requested channel. 3366 /* Switch to the requested channel.
3402 * The firmware takes care of races with the TX handler. */ 3367 * The firmware takes care of races with the TX handler. */
3403 if (conf->channel->hw_value != phy->channel) 3368 if (conf->channel->hw_value != phy->channel)
3404 b43_radio_selectchannel(dev, conf->channel->hw_value, 0); 3369 b43_switch_channel(dev, conf->channel->hw_value);
3405 3370
3406 /* Enable/Disable ShortSlot timing. */ 3371 /* Enable/Disable ShortSlot timing. */
3407 if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) != 3372 if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) !=
@@ -3419,7 +3384,7 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
3419 if (conf->power_level != 0) { 3384 if (conf->power_level != 0) {
3420 if (conf->power_level != phy->power_level) { 3385 if (conf->power_level != phy->power_level) {
3421 phy->power_level = conf->power_level; 3386 phy->power_level = conf->power_level;
3422 b43_phy_xmitpower(dev); 3387 phy->ops->xmitpower(dev);
3423 } 3388 }
3424 } 3389 }
3425 3390
@@ -3427,7 +3392,8 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
3427 antenna = b43_antenna_from_ieee80211(dev, conf->antenna_sel_tx); 3392 antenna = b43_antenna_from_ieee80211(dev, conf->antenna_sel_tx);
3428 b43_mgmtframe_txantenna(dev, antenna); 3393 b43_mgmtframe_txantenna(dev, antenna);
3429 antenna = b43_antenna_from_ieee80211(dev, conf->antenna_sel_rx); 3394 antenna = b43_antenna_from_ieee80211(dev, conf->antenna_sel_rx);
3430 b43_set_rx_antenna(dev, antenna); 3395 if (phy->ops->set_rx_antenna)
3396 phy->ops->set_rx_antenna(dev, antenna);
3431 3397
3432 /* Update templates for AP/mesh mode. */ 3398 /* Update templates for AP/mesh mode. */
3433 if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP) || 3399 if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP) ||
@@ -3436,7 +3402,7 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
3436 3402
3437 if (!!conf->radio_enabled != phy->radio_on) { 3403 if (!!conf->radio_enabled != phy->radio_on) {
3438 if (conf->radio_enabled) { 3404 if (conf->radio_enabled) {
3439 b43_radio_turn_on(dev); 3405 b43_software_rfkill(dev, RFKILL_STATE_UNBLOCKED);
3440 b43info(dev->wl, "Radio turned on by software\n"); 3406 b43info(dev->wl, "Radio turned on by software\n");
3441 if (!dev->radio_hw_enable) { 3407 if (!dev->radio_hw_enable) {
3442 b43info(dev->wl, "The hardware RF-kill button " 3408 b43info(dev->wl, "The hardware RF-kill button "
@@ -3444,7 +3410,7 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
3444 "Press the button to turn it on.\n"); 3410 "Press the button to turn it on.\n");
3445 } 3411 }
3446 } else { 3412 } else {
3447 b43_radio_turn_off(dev, 0); 3413 b43_software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED);
3448 b43info(dev->wl, "Radio turned off by software\n"); 3414 b43info(dev->wl, "Radio turned off by software\n");
3449 } 3415 }
3450 } 3416 }
@@ -3818,48 +3784,9 @@ static int b43_phy_versioning(struct b43_wldev *dev)
3818static void setup_struct_phy_for_init(struct b43_wldev *dev, 3784static void setup_struct_phy_for_init(struct b43_wldev *dev,
3819 struct b43_phy *phy) 3785 struct b43_phy *phy)
3820{ 3786{
3821 struct b43_txpower_lo_control *lo;
3822 int i;
3823
3824 memset(phy->minlowsig, 0xFF, sizeof(phy->minlowsig));
3825 memset(phy->minlowsigpos, 0, sizeof(phy->minlowsigpos));
3826
3827 phy->aci_enable = 0;
3828 phy->aci_wlan_automatic = 0;
3829 phy->aci_hw_rssi = 0;
3830
3831 phy->radio_off_context.valid = 0;
3832
3833 lo = phy->lo_control;
3834 if (lo) {
3835 memset(lo, 0, sizeof(*(phy->lo_control)));
3836 lo->tx_bias = 0xFF;
3837 INIT_LIST_HEAD(&lo->calib_list);
3838 }
3839 phy->max_lb_gain = 0;
3840 phy->trsw_rx_gain = 0;
3841 phy->txpwr_offset = 0;
3842
3843 /* NRSSI */
3844 phy->nrssislope = 0;
3845 for (i = 0; i < ARRAY_SIZE(phy->nrssi); i++)
3846 phy->nrssi[i] = -1000;
3847 for (i = 0; i < ARRAY_SIZE(phy->nrssi_lt); i++)
3848 phy->nrssi_lt[i] = i;
3849
3850 phy->lofcal = 0xFFFF;
3851 phy->initval = 0xFFFF;
3852
3853 phy->interfmode = B43_INTERFMODE_NONE;
3854 phy->channel = 0xFF;
3855
3856 phy->hardware_power_control = !!modparam_hwpctl; 3787 phy->hardware_power_control = !!modparam_hwpctl;
3857
3858 /* PHY TX errors counter. */ 3788 /* PHY TX errors counter. */
3859 atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT); 3789 atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT);
3860
3861 /* OFDM-table address caching. */
3862 phy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_UNKNOWN;
3863} 3790}
3864 3791
3865static void setup_struct_wldev_for_init(struct b43_wldev *dev) 3792static void setup_struct_wldev_for_init(struct b43_wldev *dev)
@@ -3995,7 +3922,6 @@ static void b43_set_pretbtt(struct b43_wldev *dev)
3995/* Locking: wl->mutex */ 3922/* Locking: wl->mutex */
3996static void b43_wireless_core_exit(struct b43_wldev *dev) 3923static void b43_wireless_core_exit(struct b43_wldev *dev)
3997{ 3924{
3998 struct b43_phy *phy = &dev->phy;
3999 u32 macctl; 3925 u32 macctl;
4000 3926
4001 B43_WARN_ON(b43_status(dev) > B43_STAT_INITIALIZED); 3927 B43_WARN_ON(b43_status(dev) > B43_STAT_INITIALIZED);
@@ -4016,16 +3942,12 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
4016 b43_dma_free(dev); 3942 b43_dma_free(dev);
4017 b43_pio_free(dev); 3943 b43_pio_free(dev);
4018 b43_chip_exit(dev); 3944 b43_chip_exit(dev);
4019 b43_radio_turn_off(dev, 1);
4020 b43_switch_analog(dev, 0); 3945 b43_switch_analog(dev, 0);
4021 if (phy->dyn_tssi_tbl)
4022 kfree(phy->tssi2dbm);
4023 kfree(phy->lo_control);
4024 phy->lo_control = NULL;
4025 if (dev->wl->current_beacon) { 3946 if (dev->wl->current_beacon) {
4026 dev_kfree_skb_any(dev->wl->current_beacon); 3947 dev_kfree_skb_any(dev->wl->current_beacon);
4027 dev->wl->current_beacon = NULL; 3948 dev->wl->current_beacon = NULL;
4028 } 3949 }
3950 b43_phy_exit(dev);
4029 3951
4030 ssb_device_disable(dev->dev, 0); 3952 ssb_device_disable(dev->dev, 0);
4031 ssb_bus_may_powerdown(dev->dev->bus); 3953 ssb_bus_may_powerdown(dev->dev->bus);
@@ -4052,29 +3974,24 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4052 b43_wireless_core_reset(dev, tmp); 3974 b43_wireless_core_reset(dev, tmp);
4053 } 3975 }
4054 3976
4055 if ((phy->type == B43_PHYTYPE_B) || (phy->type == B43_PHYTYPE_G)) {
4056 phy->lo_control =
4057 kzalloc(sizeof(*(phy->lo_control)), GFP_KERNEL);
4058 if (!phy->lo_control) {
4059 err = -ENOMEM;
4060 goto err_busdown;
4061 }
4062 }
4063 setup_struct_wldev_for_init(dev); 3977 setup_struct_wldev_for_init(dev);
4064 3978 err = b43_phy_operations_setup(dev);
4065 err = b43_phy_init_tssi2dbm_table(dev);
4066 if (err) 3979 if (err)
4067 goto err_kfree_lo_control; 3980 goto err_busdown;
4068 3981
4069 /* Enable IRQ routing to this device. */ 3982 /* Enable IRQ routing to this device. */
4070 ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->dev); 3983 ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->dev);
4071 3984
4072 b43_imcfglo_timeouts_workaround(dev); 3985 b43_imcfglo_timeouts_workaround(dev);
4073 b43_bluetooth_coext_disable(dev); 3986 b43_bluetooth_coext_disable(dev);
4074 b43_phy_early_init(dev); 3987 if (phy->ops->prepare) {
3988 err = phy->ops->prepare(dev);
3989 if (err)
3990 goto err_phy_exit;
3991 }
4075 err = b43_chip_init(dev); 3992 err = b43_chip_init(dev);
4076 if (err) 3993 if (err)
4077 goto err_kfree_tssitbl; 3994 goto err_phy_exit;
4078 b43_shm_write16(dev, B43_SHM_SHARED, 3995 b43_shm_write16(dev, B43_SHM_SHARED,
4079 B43_SHM_SH_WLCOREREV, dev->dev->id.revision); 3996 B43_SHM_SH_WLCOREREV, dev->dev->id.revision);
4080 hf = b43_hf_read(dev); 3997 hf = b43_hf_read(dev);
@@ -4140,15 +4057,11 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4140out: 4057out:
4141 return err; 4058 return err;
4142 4059
4143 err_chip_exit: 4060err_chip_exit:
4144 b43_chip_exit(dev); 4061 b43_chip_exit(dev);
4145 err_kfree_tssitbl: 4062err_phy_exit:
4146 if (phy->dyn_tssi_tbl) 4063 b43_phy_exit(dev);
4147 kfree(phy->tssi2dbm); 4064err_busdown:
4148 err_kfree_lo_control:
4149 kfree(phy->lo_control);
4150 phy->lo_control = NULL;
4151 err_busdown:
4152 ssb_bus_may_powerdown(bus); 4065 ssb_bus_may_powerdown(bus);
4153 B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT); 4066 B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT);
4154 return err; 4067 return err;
@@ -4511,7 +4424,6 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
4511 wl->current_dev = dev; 4424 wl->current_dev = dev;
4512 INIT_WORK(&dev->restart_work, b43_chip_reset); 4425 INIT_WORK(&dev->restart_work, b43_chip_reset);
4513 4426
4514 b43_radio_turn_off(dev, 1);
4515 b43_switch_analog(dev, 0); 4427 b43_switch_analog(dev, 0);
4516 ssb_device_disable(dev->dev, 0); 4428 ssb_device_disable(dev->dev, 0);
4517 ssb_bus_may_powerdown(bus); 4429 ssb_bus_may_powerdown(bus);