diff options
Diffstat (limited to 'package/rt2x00/src/rt2x00mac.c')
-rw-r--r-- | package/rt2x00/src/rt2x00mac.c | 138 |
1 files changed, 52 insertions, 86 deletions
diff --git a/package/rt2x00/src/rt2x00mac.c b/package/rt2x00/src/rt2x00mac.c index 349353bee5..8835df2e2e 100644 --- a/package/rt2x00/src/rt2x00mac.c +++ b/package/rt2x00/src/rt2x00mac.c @@ -33,6 +33,7 @@ #include <linux/netdevice.h> #include "rt2x00.h" +#include "rt2x00lib.h" #include "rt2x00dev.h" static int rt2x00_tx_rts_cts(struct rt2x00_dev *rt2x00dev, @@ -129,60 +130,18 @@ int rt2x00lib_reset(struct ieee80211_hw *hw) } EXPORT_SYMBOL_GPL(rt2x00lib_reset); -int rt2x00lib_open(struct ieee80211_hw *hw) -{ - struct rt2x00_dev *rt2x00dev = hw->priv; - int status; - - /* - * We must wait on the firmware before - * we can safely continue. - */ - status = rt2x00lib_load_firmware_wait(rt2x00dev); - if (status) - return status; - - /* - * Initialize the device. - */ - status = rt2x00lib_initialize(rt2x00dev); - if (status) - return status; - - /* - * Enable radio. - */ - status = rt2x00lib_enable_radio(rt2x00dev); - if (status) { - rt2x00lib_uninitialize(rt2x00dev); - return status; - } - - return 0; -} -EXPORT_SYMBOL_GPL(rt2x00lib_open); - -int rt2x00lib_stop(struct ieee80211_hw *hw) -{ - struct rt2x00_dev *rt2x00dev = hw->priv; - - rt2x00lib_disable_radio(rt2x00dev); - - return 0; -} -EXPORT_SYMBOL_GPL(rt2x00lib_stop); - int rt2x00lib_add_interface(struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf) { struct rt2x00_dev *rt2x00dev = hw->priv; struct interface *intf = &rt2x00dev->interface; + int status; /* * We only support 1 non-monitor interface. */ if (conf->type != IEEE80211_IF_TYPE_MNTR && - is_interface_present(&rt2x00dev->interface)) + is_interface_present(intf)) return -ENOBUFS; /* @@ -200,17 +159,39 @@ int rt2x00lib_add_interface(struct ieee80211_hw *hw, } /* - * If this is the first interface which is being added, - * we should write the MAC address to the device. - */ - if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) - rt2x00dev->ops->lib->config_mac_addr(rt2x00dev, conf->mac_addr); - - /* - * Enable periodic link tuning if this is a non-monitor interface. + * Initialize interface, and enable the radio when this + * is the first interface that is brought up. */ - if (conf->type != IEEE80211_IF_TYPE_MNTR) - rt2x00_start_link_tune(rt2x00dev); + if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) { + /* + * We must wait on the firmware before + * we can safely continue. + */ + status = rt2x00lib_load_firmware_wait(rt2x00dev); + if (status) + return status; + + /* + * Before initialization, the mac address should + * be configured. + */ + rt2x00dev->ops->lib->config_mac_addr(rt2x00dev, + conf->mac_addr); + + /* + * Initialize the device. + */ + status = rt2x00lib_initialize(rt2x00dev); + if (status) + return status; + + /* + * Enable radio. + */ + status = rt2x00lib_enable_radio(rt2x00dev); + if (status) + return status; + } return 0; } @@ -226,12 +207,12 @@ void rt2x00lib_remove_interface(struct ieee80211_hw *hw, * We only support 1 non-monitor interface. */ if (conf->type != IEEE80211_IF_TYPE_MNTR && - !is_interface_present(&rt2x00dev->interface)) + !is_interface_present(intf)) return; /* - * We support muliple monitor mode interfaces. - * All we need to do is decrease the monitor_count. + * When removing an monitor interface, decrease monitor_count. + * For non-monitor interfaces, all interface data needs to be reset. */ if (conf->type == IEEE80211_IF_TYPE_MNTR) { intf->monitor_count--; @@ -243,33 +224,18 @@ void rt2x00lib_remove_interface(struct ieee80211_hw *hw, } /* - * When this is a non-monitor mode, stop the periodic link tuning. - */ - if (conf->type != IEEE80211_IF_TYPE_MNTR) - rt2x00_stop_link_tune(rt2x00dev); - - /* - * Check if we still have 1 non-monitor or a monitor - * interface enabled. In that case we should update the - * registers. - */ - if (is_monitor_present(&rt2x00dev->interface) ^ - is_interface_present(&rt2x00dev->interface)) { - if (is_interface_present(&rt2x00dev->interface)) - rt2x00lib_config_type(rt2x00dev, - rt2x00dev->interface.type); - else - rt2x00lib_config_type(rt2x00dev, - IEEE80211_IF_TYPE_MNTR); - } - - /* - * Check which interfaces have been disabled. + * If this was the last interface, + * this is the time to disable the radio. + * If this is not the last interface, then we should + * check if we should switch completely to monitor + * mode or completely switch to the non-monitor mode. */ - if (!is_interface_present(&rt2x00dev->interface)) - __clear_bit(INTERFACE_ENABLED, &rt2x00dev->flags); - else if (!is_monitor_present(&rt2x00dev->interface)) - __clear_bit(INTERFACE_ENABLED_MONITOR, &rt2x00dev->flags); + if (!is_monitor_present(intf) && !is_interface_present(intf)) + rt2x00lib_disable_radio(rt2x00dev); + else if (is_monitor_present(intf) ^ is_interface_present(intf)) + rt2x00lib_config_type(rt2x00dev, + is_interface_present(intf) ? + intf->type : IEEE80211_IF_TYPE_MNTR); } EXPORT_SYMBOL_GPL(rt2x00lib_remove_interface); @@ -373,10 +339,10 @@ void rt2x00lib_set_multicast_list(struct ieee80211_hw *hw, * Check if the new state is different then the old state. */ if (test_bit(INTERFACE_ENABLED_PROMISC, &rt2x00dev->flags) == - (flags & IFF_PROMISC)) + !!(flags & IFF_PROMISC)) return; - rt2x00dev->interface.promisc = (flags & IFF_PROMISC); + rt2x00dev->interface.promisc = !!(flags & IFF_PROMISC); /* * Schedule the link tuner if this does not run @@ -384,7 +350,7 @@ void rt2x00lib_set_multicast_list(struct ieee80211_hw *hw, * switched off when it is not required. */ if (!work_pending(&rt2x00dev->link.work.work)) - queue_work(rt2x00dev->workqueue, &rt2x00dev->link.work.work); + queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->link.work.work); } EXPORT_SYMBOL_GPL(rt2x00lib_set_multicast_list); |