diff options
-rw-r--r-- | package/d80211/Makefile | 11 | ||||
-rw-r--r-- | package/d80211/src/Kconfig | 2 | ||||
-rw-r--r-- | package/d80211/src/ieee80211.c | 114 | ||||
-rw-r--r-- | package/d80211/src/ieee80211_common.h (renamed from package/d80211/src/include/net/d80211_common.h) | 6 | ||||
-rw-r--r-- | package/d80211/src/ieee80211_i.h | 51 | ||||
-rw-r--r-- | package/d80211/src/ieee80211_iface.c | 22 | ||||
-rw-r--r-- | package/d80211/src/ieee80211_ioctl.c | 124 | ||||
-rw-r--r-- | package/d80211/src/ieee80211_scan.c | 83 | ||||
-rw-r--r-- | package/d80211/src/ieee80211_sta.c | 99 | ||||
-rw-r--r-- | package/d80211/src/ieee80211_sysfs.c | 10 | ||||
-rw-r--r-- | package/d80211/src/include/compat_hacks.h | 28 | ||||
-rw-r--r-- | package/d80211/src/include/linux/ieee80211.h (renamed from package/d80211/src/include/net/d80211_mgmt.h) | 170 | ||||
-rw-r--r-- | package/d80211/src/include/net/d80211.h | 154 | ||||
-rw-r--r-- | package/d80211/src/include/net/d80211_shared.h | 46 | ||||
-rw-r--r-- | package/d80211/src/sta_info.c | 9 | ||||
-rw-r--r-- | package/d80211/src/wep.c | 1 | ||||
-rw-r--r-- | package/d80211/src/wme.c | 24 | ||||
-rw-r--r-- | package/d80211/src/wpa.c | 2 |
18 files changed, 492 insertions, 464 deletions
diff --git a/package/d80211/Makefile b/package/d80211/Makefile index 2bc9d4102..25b9051bd 100644 --- a/package/d80211/Makefile +++ b/package/d80211/Makefile @@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=kmod-d80211 -PKG_VERSION:=20061230 +PKG_VERSION:=20070201 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME) @@ -29,6 +29,7 @@ endef define Build/Prepare mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR)/ + $(SED) 's,INIT_WORK(,INIT_WORK_NEW(,g' $(PKG_BUILD_DIR)/*.[ch] endef define Build/Compile @@ -36,17 +37,19 @@ define Build/Compile CROSS_COMPILE="$(TARGET_CROSS)" \ ARCH="$(LINUX_KARCH)" \ SUBDIRS="$(PKG_BUILD_DIR)" \ - EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include" \ + EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include -include compat_hacks.h" \ modules endef define Build/InstallDev - mkdir -p $(STAGING_DIR)/usr/include/net - $(CP) ./src/include/net/* $(STAGING_DIR)/usr/include/net/ + mkdir -p $(STAGING_DIR)/usr/include + $(CP) ./src/include/* $(STAGING_DIR)/usr/include/ endef define Build/UninstallDev rm -f $(STAGING_DIR)/usr/include/net/d80211* + rm -f $(STAGING_DIR)/usr/include/compat_hacks.h + rm -f $(STAGING_DIR)/usr/include/linux/ieee80211* endef $(eval $(call KernelPackage,d80211)) diff --git a/package/d80211/src/Kconfig b/package/d80211/src/Kconfig index 0f07d41f1..7d661632f 100644 --- a/package/d80211/src/Kconfig +++ b/package/d80211/src/Kconfig @@ -1,8 +1,10 @@ config D80211 tristate "Generic IEEE 802.11 Networking Stack (dscape)" select CRYPTO + select CRYPTO_ECB select CRYPTO_ARC4 select CRYPTO_AES + select WIRELESS_EXT ---help--- This option enables the hardware independent IEEE 802.11 networking stack. diff --git a/package/d80211/src/ieee80211.c b/package/d80211/src/ieee80211.c index 6e10db510..7353ed343 100644 --- a/package/d80211/src/ieee80211.c +++ b/package/d80211/src/ieee80211.c @@ -22,8 +22,7 @@ #include <linux/compiler.h> #include <linux/bitmap.h> -#include <net/d80211_common.h> -#include <net/d80211_mgmt.h> +#include "ieee80211_common.h" #include "ieee80211_i.h" #include "ieee80211_rate.h" #include "wep.h" @@ -1362,11 +1361,9 @@ static int ieee80211_master_start_xmit(struct sk_buff *skb, struct ieee80211_tx_control control; struct ieee80211_tx_packet_data *pkt_data; struct net_device *odev = NULL; - struct ieee80211_sub_if_data *sdata, *osdata; + struct ieee80211_sub_if_data *osdata; int ret; - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - /* * copy control out of the skb so other people can use skb->cb */ @@ -1395,8 +1392,6 @@ static int ieee80211_master_start_xmit(struct sk_buff *skb, control.flags |= IEEE80211_TXCTL_REQ_TX_STATUS; if (pkt_data->do_not_encrypt) control.flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; - control.pkt_type = - pkt_data->pkt_probe_resp ? PKT_PROBE_RESP : PKT_NORMAL; if (pkt_data->requeue) control.flags |= IEEE80211_TXCTL_REQUEUE; control.queue = pkt_data->queue; @@ -1628,10 +1623,6 @@ ieee80211_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev) pkt_data->ifindex = sdata->dev->ifindex; pkt_data->mgmt_iface = (sdata->type == IEEE80211_IF_TYPE_MGMT); - if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && - (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP) - pkt_data->pkt_probe_resp = 1; - skb->priority = 20; /* use hardcoded priority for mgmt TX queue */ skb->dev = sdata->local->mdev; @@ -1915,7 +1906,8 @@ int ieee80211_if_config_beacon(struct net_device *dev) int ieee80211_hw_config(struct ieee80211_local *local) { - int i, ret = 0; + struct ieee80211_hw_mode *mode; + int ret = 0; #ifdef CONFIG_D80211_VERBOSE_DEBUG printk(KERN_DEBUG "HW CONFIG: channel=%d freq=%d " @@ -1926,12 +1918,10 @@ int ieee80211_hw_config(struct ieee80211_local *local) if (local->ops->config) ret = local->ops->config(local_to_hw(local), &local->hw.conf); - for (i = 0; i < local->hw.num_modes; i++) { - struct ieee80211_hw_modes *mode = &local->hw.modes[i]; + list_for_each_entry(mode, &local->modes_list, list) { if (mode->mode == local->hw.conf.phymode) { - if (local->curr_rates != mode->rates) { + if (local->curr_rates != mode->rates) rate_control_clear(local); - } local->curr_rates = mode->rates; local->num_curr_rates = mode->num_rates; ieee80211_prepare_rates(local); @@ -1947,7 +1937,7 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) { /* FIX: what would be proper limits for MTU? * This interface uses 802.3 frames. */ - if (new_mtu < 256 || new_mtu > IEEE80211_DATA_LEN - 24 - 6) { + if (new_mtu < 256 || new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6) { printk(KERN_WARNING "%s: invalid MTU %d\n", dev->name, new_mtu); return -EINVAL; @@ -1965,7 +1955,7 @@ static int ieee80211_change_mtu_apdev(struct net_device *dev, int new_mtu) { /* FIX: what would be proper limits for MTU? * This interface uses 802.11 frames. */ - if (new_mtu < 256 || new_mtu > IEEE80211_DATA_LEN) { + if (new_mtu < 256 || new_mtu > IEEE80211_MAX_DATA_LEN) { printk(KERN_WARNING "%s: invalid MTU %d\n", dev->name, new_mtu); return -EINVAL; @@ -2092,13 +2082,14 @@ void ieee80211_if_shutdown(struct net_device *dev) case IEEE80211_IF_TYPE_IBSS: sdata->u.sta.state = IEEE80211_DISABLED; cancel_delayed_work(&sdata->u.sta.work); - if (local->scan_work.data == sdata->dev) { + if (!local->ops->hw_scan && + local->scan_dev == sdata->dev) { local->sta_scanning = 0; cancel_delayed_work(&local->scan_work); flush_scheduled_work(); /* see comment in ieee80211_unregister_hw to * understand why this works */ - local->scan_work.data = NULL; + local->scan_dev = NULL; } else flush_scheduled_work(); break; @@ -2511,10 +2502,10 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx) static struct ieee80211_rate * ieee80211_get_rate(struct ieee80211_local *local, int phymode, int hw_rate) { - int m, r; + struct ieee80211_hw_mode *mode; + int r; - for (m = 0; m < local->hw.num_modes; m++) { - struct ieee80211_hw_modes *mode = &local->hw.modes[m]; + list_for_each_entry(mode, &local->modes_list, list) { if (mode->mode != phymode) continue; for (r = 0; r < mode->num_rates; r++) { @@ -4050,7 +4041,6 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local, pkt_data->mgmt_iface = (control->type == IEEE80211_IF_TYPE_MGMT); pkt_data->req_tx_status = !!(control->flags & IEEE80211_TXCTL_REQ_TX_STATUS); pkt_data->do_not_encrypt = !!(control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT); - pkt_data->pkt_probe_resp = (control->pkt_type == PKT_PROBE_RESP); pkt_data->requeue = !!(control->flags & IEEE80211_TXCTL_REQUEUE); pkt_data->queue = control->queue; @@ -4334,6 +4324,7 @@ void ieee80211_if_setup(struct net_device *dev) dev->open = ieee80211_open; dev->stop = ieee80211_stop; dev->tx_queue_len = 0; + dev->uninit = ieee80211_if_reinit; dev->destructor = ieee80211_if_free; } @@ -4348,27 +4339,10 @@ void ieee80211_if_mgmt_setup(struct net_device *dev) dev->type = ARPHRD_IEEE80211_PRISM; dev->hard_header_parse = header_parse_80211; dev->tx_queue_len = 0; + dev->uninit = ieee80211_if_reinit; dev->destructor = ieee80211_if_free; } -static void ieee80211_precalc_modes(struct ieee80211_local *local) -{ - struct ieee80211_hw_modes *mode; - struct ieee80211_rate *rate; - struct ieee80211_hw *hw = &local->hw; - int m, r; - - local->hw_modes = 0; - for (m = 0; m < hw->num_modes; m++) { - mode = &hw->modes[m]; - local->hw_modes |= 1 << mode->mode; - for (r = 0; r < mode->num_rates; r++) { - rate = &mode->rates[r]; - rate->rate_inv = CHAN_UTIL_RATE_LCM / rate->rate; - } - } -} - int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, const char *name) { @@ -4421,7 +4395,7 @@ static void rate_control_deinitialize(struct ieee80211_local *local) } struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, - struct ieee80211_ops *ops) + const struct ieee80211_ops *ops) { struct net_device *mdev; struct ieee80211_local *local; @@ -4461,6 +4435,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, local->hw.priv = (char *)mdev->priv + ((sizeof(struct ieee80211_sub_if_data) + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST); + local->hw.queues = 1; /* default */ local->mdev = mdev; local->rx_pre_handlers = ieee80211_rx_pre_handlers; @@ -4482,10 +4457,13 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, init_timer(&local->scan.timer); /* clear it out */ + INIT_LIST_HEAD(&local->modes_list); + spin_lock_init(&local->sub_if_lock); INIT_LIST_HEAD(&local->sub_if_list); spin_lock_init(&local->generic_lock); + INIT_DELAYED_WORK(&local->scan_work, ieee80211_sta_scan_work); init_timer(&local->stat_timer); local->stat_timer.function = ieee80211_stat_refresh; local->stat_timer.data = (unsigned long) local; @@ -4546,9 +4524,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) local->hw.conf.beacon_int = 1000; - /* Don't care about the result */ - ieee80211_update_hw(local_to_hw(local)); - result = sta_info_start(local); if (result < 0) goto fail_sta_info; @@ -4633,35 +4608,38 @@ fail_sysfs: } EXPORT_SYMBOL(ieee80211_register_hw); -int ieee80211_update_hw(struct ieee80211_hw *hw) +int ieee80211_register_hwmode(struct ieee80211_hw *hw, + struct ieee80211_hw_mode *mode) { struct ieee80211_local *local = hw_to_local(hw); + struct ieee80211_rate *rate; + int i; - /* Backwards compatibility for low-level drivers that do not set number - * of TX queues. */ - if (hw->queues == 0) - hw->queues = 1; + INIT_LIST_HEAD(&mode->list); + list_add_tail(&mode->list, &local->modes_list); - if (!hw->modes || !hw->modes->channels || !hw->modes->rates || - !hw->modes->num_channels || !hw->modes->num_rates) - return -1; - - ieee80211_precalc_modes(local); - local->hw.conf.phymode = hw->modes[0].mode; - local->curr_rates = hw->modes[0].rates; - local->num_curr_rates = hw->modes[0].num_rates; - ieee80211_prepare_rates(local); + local->hw_modes |= (1 << mode->mode); + for (i = 0; i < mode->num_rates; i++) { + rate = &(mode->rates[i]); + rate->rate_inv = CHAN_UTIL_RATE_LCM / rate->rate; + } - local->hw.conf.freq = local->hw.modes[0].channels[0].freq; - local->hw.conf.channel = local->hw.modes[0].channels[0].chan; - local->hw.conf.channel_val = local->hw.modes[0].channels[0].val; + if (!local->curr_rates) { + /* Default to this mode */ + local->hw.conf.phymode = mode->mode; + local->curr_rates = mode->rates; + local->num_curr_rates = mode->num_rates; + ieee80211_prepare_rates(local); + local->hw.conf.freq = mode->channels[0].freq; + local->hw.conf.channel = mode->channels[0].chan; + local->hw.conf.channel_val = mode->channels[0].val; + } ieee80211_init_client(local->mdev); - /* FIXME: Invoke config to allow driver to set the channel. */ return 0; } -EXPORT_SYMBOL(ieee80211_update_hw); +EXPORT_SYMBOL(ieee80211_register_hwmode); void ieee80211_unregister_hw(struct ieee80211_hw *hw) { @@ -4686,7 +4664,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) if (local->stat_time) del_timer_sync(&local->stat_timer); - if (local->scan_work.data) { + if (!local->ops->hw_scan && local->scan_dev) { local->sta_scanning = 0; cancel_delayed_work(&local->scan_work); flush_scheduled_work(); @@ -4709,12 +4687,13 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) if (skb_queue_len(&local->skb_queue) || skb_queue_len(&local->skb_queue_unreliable)) - printk(KERN_WARNING "%s: skb_queue not empty", + printk(KERN_WARNING "%s: skb_queue not empty\n", local->mdev->name); skb_queue_purge(&local->skb_queue); skb_queue_purge(&local->skb_queue_unreliable); ieee80211_dev_free_index(local); + ieee80211_wep_free(local); ieee80211_led_exit(local); } EXPORT_SYMBOL(ieee80211_unregister_hw); @@ -4724,7 +4703,6 @@ void ieee80211_free_hw(struct ieee80211_hw *hw) struct ieee80211_local *local = hw_to_local(hw); ieee80211_if_free(local->mdev); - ieee80211_wep_free(local); ieee80211_dev_free(local); } EXPORT_SYMBOL(ieee80211_free_hw); diff --git a/package/d80211/src/include/net/d80211_common.h b/package/d80211/src/ieee80211_common.h index 31167f0e0..06c970d1b 100644 --- a/package/d80211/src/include/net/d80211_common.h +++ b/package/d80211/src/ieee80211_common.h @@ -7,8 +7,8 @@ * published by the Free Software Foundation. */ -#ifndef D80211_COMMON_H -#define D80211_COMMON_H +#ifndef IEEE80211_COMMON_H +#define IEEE80211_COMMON_H #include <linux/types.h> @@ -95,4 +95,4 @@ struct ieee80211_radar_info { int radar_type; }; -#endif /* D80211_COMMON_H */ +#endif /* IEEE80211_COMMON_H */ diff --git a/package/d80211/src/ieee80211_i.h b/package/d80211/src/ieee80211_i.h index ef303dae6..aa4aa8105 100644 --- a/package/d80211/src/ieee80211_i.h +++ b/package/d80211/src/ieee80211_i.h @@ -155,10 +155,9 @@ struct ieee80211_tx_packet_data { unsigned long jiffies; unsigned int req_tx_status:1; unsigned int do_not_encrypt:1; - unsigned int pkt_probe_resp:1; unsigned int requeue:1; - unsigned int queue:4; unsigned int mgmt_iface:1; + unsigned int queue:4; }; struct ieee80211_tx_stored_packet { @@ -181,7 +180,7 @@ struct ieee80211_passive_scan { int channel; /* channel to be scanned */ int tries; - int mode_idx; + struct ieee80211_hw_mode *mode; int chan_idx; int freq; @@ -240,7 +239,7 @@ struct ieee80211_if_sta { IEEE80211_ASSOCIATE, IEEE80211_ASSOCIATED, IEEE80211_IBSS_SEARCH, IEEE80211_IBSS_JOINED } state; - struct work_struct work; + struct delayed_work work; u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; u8 ssid[IEEE80211_MAX_SSID_LEN]; size_t ssid_len; @@ -334,7 +333,10 @@ struct ieee80211_local { * it first anyway so they become a no-op */ struct ieee80211_hw hw; - struct ieee80211_ops *ops; + const struct ieee80211_ops *ops; + + /* List of registered struct ieee80211_hw_mode */ + struct list_head modes_list; struct net_device *mdev; /* wmaster# - "master" 802.11 device */ struct net_device *apdev; /* wlan#ap - management frames (hostapd) */ @@ -425,11 +427,12 @@ struct ieee80211_local { spinlock_t sub_if_lock; /* mutex for STA data structures */ struct list_head sub_if_list; int sta_scanning; - int scan_hw_mode_idx; + struct ieee80211_hw_mode *scan_hw_mode; int scan_channel_idx; enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state; unsigned long last_scan_completed; - struct work_struct scan_work; + struct delayed_work scan_work; + struct net_device *scan_dev; int scan_oper_channel; int scan_oper_channel_val; int scan_oper_power_level; @@ -558,20 +561,38 @@ struct sta_attribute { ssize_t (*store)(struct sta_info *, const char *buf, size_t count); }; +static inline void __bss_tim_set(struct ieee80211_if_ap *bss, int aid) +{ + /* + * This format has ben mandated by the IEEE specifications, + * so this line may not be changed to use the __set_bit() format. + */ + bss->tim[(aid)/8] |= 1<<((aid) % 8); +} + static inline void bss_tim_set(struct ieee80211_local *local, struct ieee80211_if_ap *bss, int aid) { - spin_lock(&local->sta_lock); - bss->tim[(aid)/8] |= 1<<((aid) % 8); - spin_unlock(&local->sta_lock); + spin_lock_bh(&local->sta_lock); + __bss_tim_set(bss, aid); + spin_unlock_bh(&local->sta_lock); +} + +static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, int aid) +{ + /* + * This format has ben mandated by the IEEE specifications, + * so this line may not be changed to use the __clear_bit() format. + */ + bss->tim[(aid)/8] &= !(1<<((aid) % 8)); } static inline void bss_tim_clear(struct ieee80211_local *local, struct ieee80211_if_ap *bss, int aid) { - spin_lock(&local->sta_lock); - bss->tim[(aid)/8] &= !(1<<((aid) % 8)); - spin_unlock(&local->sta_lock); + spin_lock_bh(&local->sta_lock); + __bss_tim_clear(bss, aid); + spin_unlock_bh(&local->sta_lock); } /* ieee80211.c */ @@ -607,6 +628,7 @@ extern const struct iw_handler_def ieee80211_iw_master_handler_def; int ieee80211_set_hw_encryption(struct net_device *dev, struct sta_info *sta, u8 addr[ETH_ALEN], struct ieee80211_key *key); +void ieee80211_update_default_wep_only(struct ieee80211_local *local); /* ieee80211_scan.c */ void ieee80211_init_scan(struct ieee80211_local *local); @@ -638,7 +660,8 @@ int ieee80211_set_compression(struct ieee80211_local *local, struct net_device *dev, struct sta_info *sta); int ieee80211_init_client(struct net_device *dev); /* ieee80211_sta.c */ -void ieee80211_sta_work(void *ptr); +void ieee80211_sta_work(struct work_struct *work); +void ieee80211_sta_scan_work(struct work_struct *work); void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb, struct ieee80211_rx_status *rx_status); int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len); diff --git a/package/d80211/src/ieee80211_iface.c b/package/d80211/src/ieee80211_iface.c index 3e9d53180..3b2d259d1 100644 --- a/package/d80211/src/ieee80211_iface.c +++ b/package/d80211/src/ieee80211_iface.c @@ -12,7 +12,6 @@ #include <linux/netdevice.h> #include <linux/rtnetlink.h> #include <net/d80211.h> -#include <net/d80211_mgmt.h> #include "ieee80211_i.h" #include "sta_info.h" @@ -42,7 +41,7 @@ int ieee80211_if_add(struct net_device *dev, const char *name, { struct net_device *ndev, *tmp_dev; struct ieee80211_local *local = dev->ieee80211_ptr; - struct ieee80211_sub_if_data *sdata = NULL, *sdata_parent; + struct ieee80211_sub_if_data *sdata = NULL; int ret; int i; @@ -56,7 +55,8 @@ int ieee80211_if_add(struct net_device *dev, const char *name, if (strlen(name) == 0) { i = 0; do { - sprintf(ndev->name, "%s.%d", dev->name, i++); + snprintf(ndev->name, sizeof(ndev->name), "%s.%d", + dev->name, i++); tmp_dev = dev_get_by_name(ndev->name); if (!tmp_dev) break; @@ -82,7 +82,6 @@ int ieee80211_if_add(struct net_device *dev, const char *name, sdata->type = IEEE80211_IF_TYPE_AP; sdata->dev = ndev; sdata->local = local; - sdata_parent = IEEE80211_DEV_TO_SUB_IF(dev); ieee80211_if_sdata_init(sdata); ret = register_netdevice(ndev); @@ -97,6 +96,7 @@ int ieee80211_if_add(struct net_device *dev, const char *name, } list_add(&sdata->list, &local->sub_if_list); + ieee80211_update_default_wep_only(local); return 0; @@ -164,6 +164,7 @@ void ieee80211_if_del_mgmt(struct ieee80211_local *local) void ieee80211_if_set_type(struct net_device *dev, int type) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_local *local = dev->ieee80211_ptr; sdata->type = type; switch (type) { @@ -185,7 +186,7 @@ void ieee80211_if_set_type(struct net_device *dev, int type) struct ieee80211_if_sta *ifsta; ifsta = &sdata->u.sta; - INIT_WORK(&ifsta->work, ieee80211_sta_work, dev); + INIT_DELAYED_WORK(&ifsta->work, ieee80211_sta_work); ifsta->capab = WLAN_CAPABILITY_ESS; ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN | @@ -205,6 +206,7 @@ void ieee80211_if_set_type(struct net_device *dev, int type) dev->name, __FUNCTION__, type); } ieee80211_sysfs_change_if_type(dev); + ieee80211_update_default_wep_only(local); } /* Must be called with rtnl lock held. */ @@ -225,15 +227,13 @@ void ieee80211_if_reinit(struct net_device *dev) * really much point in disabling the keys at this point. */ memset(addr, 0xff, ETH_ALEN); if (local->ops->set_key) - local->ops->set_key(dev, DISABLE_KEY, addr, - local->keys[i], 0); + local->ops->set_key(local_to_hw(local), DISABLE_KEY, addr, + local->keys[i], 0); #endif ieee80211_key_free(sdata->keys[i]); + sdata->keys[i] = NULL; } - /* Shouldn't be necessary but won't hurt */ - ieee80211_if_shutdown(dev); - switch (sdata->type) { case IEEE80211_IF_TYPE_AP: { /* Remove all virtual interfaces that use this BSS @@ -308,7 +308,6 @@ void __ieee80211_if_del(struct ieee80211_local *local, { struct net_device *dev = sdata->dev; - ieee80211_if_reinit(dev); list_del(&sdata->list); ieee80211_sysfs_remove_netdevice(dev); unregister_netdevice(dev); @@ -329,6 +328,7 @@ int ieee80211_if_remove(struct net_device *dev, const char *name, int id) strcmp(name, sdata->dev->name) == 0 && sdata->dev != local->mdev) { __ieee80211_if_del(local, sdata); + ieee80211_update_default_wep_only(local); return 0; } } diff --git a/package/d80211/src/ieee80211_ioctl.c b/package/d80211/src/ieee80211_ioctl.c index c74b4318d..5a21b2d4d 100644 --- a/package/d80211/src/ieee80211_ioctl.c +++ b/package/d80211/src/ieee80211_ioctl.c @@ -20,7 +20,6 @@ #include <asm/uaccess.h> #include <net/d80211.h> -#include <net/d80211_mgmt.h> #include "ieee80211_i.h" #include "hostapd_ioctl.h" #include "ieee80211_rate.h" @@ -120,43 +119,45 @@ static int ieee80211_ioctl_get_hw_features(struct net_device *dev, struct ieee80211_local *local = dev->ieee80211_ptr; u8 *pos = param->u.hw_features.data; int left = param_len - (pos - (u8 *) param); - int mode, i; + int i; struct hostapd_ioctl_hw_modes_hdr *hdr; struct ieee80211_rate_data *rate; struct ieee80211_channel_data *chan; + struct ieee80211_hw_mode *mode; param->u.hw_features.flags = 0; if (local->hw.flags & IEEE80211_HW_DATA_NULLFUNC_ACK) param->u.hw_features.flags |= HOSTAP_HW_FLAG_NULLFUNC_OK; - param->u.hw_features.num_modes = local->hw.num_modes; - for (mode = 0; mode < local->hw.num_modes; mode++) { + param->u.hw_features.num_modes = 0; + list_for_each_entry(mode, &local->modes_list, list) { int clen, rlen; - struct ieee80211_hw_modes *m = &local->hw.modes[mode]; - clen = m->num_channels * sizeof(struct ieee80211_channel_data); - rlen = m->num_rates * sizeof(struct ieee80211_rate_data); + + param->u.hw_features.num_modes++; + clen = mode->num_channels * sizeof(struct ieee80211_channel_data); + rlen = mode->num_rates * sizeof(struct ieee80211_rate_data); if (left < sizeof(*hdr) + clen + rlen) return -E2BIG; left -= sizeof(*hdr) + clen + rlen; hdr = (struct hostapd_ioctl_hw_modes_hdr *) pos; - hdr->mode = m->mode; - hdr->num_channels = m->num_channels; - hdr->num_rates = m->num_rates; + hdr->mode = mode->mode; + hdr->num_channels = mode->num_channels; + hdr->num_rates = mode->num_rates; pos = (u8 *) (hdr + 1); chan = (struct ieee80211_channel_data *) pos; - for (i = 0; i < m->num_channels; i++) { - chan[i].chan = m->channels[i].chan; - chan[i].freq = m->channels[i].freq; - chan[i].flag = m->channels[i].flag; + for (i = 0; i < mode->num_channels; i++) { + chan[i].chan = mode->channels[i].chan; + chan[i].freq = mode->channels[i].freq; + chan[i].flag = mode->channels[i].flag; } pos += clen; rate = (struct ieee80211_rate_data *) pos; - for (i = 0; i < m->num_rates; i++) { - rate[i].rate = m->rates[i].rate; - rate[i].flags = m->rates[i].flags; + for (i = 0; i < mode->num_rates; i++) { + rate[i].rate = mode->rates[i].rate; + rate[i].flags = mode->rates[i].flags; } pos += rlen; } @@ -198,8 +199,8 @@ static int ieee80211_ioctl_scan(struct net_device *dev, param->u.scan.last_rx = local->scan.rx_packets; local->scan.rx_packets = -1; } - param->u.scan.channel = local->hw.modes[local->scan.mode_idx]. - channels[local->scan.chan_idx].chan; + param->u.scan.channel = + local->scan.mode->channels[local->scan.chan_idx].chan; return 0; } @@ -285,7 +286,9 @@ static int ieee80211_ioctl_add_sta(struct net_device *dev, if (sta->dev != dev) { /* Binding STA to a new interface, so remove all references to * the old BSS. */ + spin_lock_bh(&local->sta_lock); sta_info_remove_aid_ptr(sta); + spin_unlock_bh(&local->sta_lock); } /* TODO @@ -359,7 +362,7 @@ static int ieee80211_ioctl_remove_sta(struct net_device *dev, sta = sta_info_get(local, param->sta_addr); if (sta) { sta_info_put(sta); - sta_info_free(sta, 1); + sta_info_free(sta, 0); } return sta ? 0 : -ENOENT; @@ -407,10 +410,8 @@ static int ieee80211_ioctl_get_info_sta(struct net_device *dev, if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { - struct ieee80211_sub_if_data *sdata; struct net_device_stats *stats; - sdata = IEEE80211_DEV_TO_SUB_IF(dev); stats = ieee80211_dev_stats(local->mdev); param->u.get_info_sta.rx_bytes = stats->rx_bytes; param->u.get_info_sta.tx_bytes = stats->tx_bytes; @@ -537,9 +538,7 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr, } key = sdata->keys[idx]; - /* Disable hwaccel for default keys when the interface is not - * the default one. - * TODO: consider adding hwaccel support for these; at least + /* TODO: consider adding hwaccel support for these; at least * Atheros key cache should be able to handle this since AP is * only transmitting frames with default keys. */ /* FIX: hw key cache can be used when only one virtual @@ -548,11 +547,6 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr, * must be used. This should be done automatically * based on configured station devices. For the time * being, this can be only set at compile time. */ - /* FIXME: There is no more anything like "default - * interface". We should try hwaccel if there is just one - * interface - for now, hwaccel is unconditionaly - * disabled. */ - try_hwaccel = 0; } else { set_tx_key = 0; if (idx != 0) { @@ -621,7 +615,9 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr, if (alg == ALG_NONE) { keyconf = NULL; - if (try_hwaccel && key && local->ops->set_key && + if (try_hwaccel && key && + key->hw_key_idx != HW_KEY_IDX_INVALID && + local->ops->set_key && (keyconf = ieee80211_key_data2conf(local, key)) != NULL && local->ops->set_key(local_to_hw(local), DISABLE_KEY, sta_addr, keyconf, sta ? sta->aid : 0)) { @@ -810,7 +806,7 @@ static int ieee80211_ioctl_get_encryption(struct net_device *dev, param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { sta = NULL; - if (param->u.crypt.idx > NUM_DEFAULT_KEYS) { + if (param->u.crypt.idx >= NUM_DEFAULT_KEYS) { param->u.crypt.idx = sdata->default_key ? sdata->default_key->keyidx : 0; return 0; @@ -1357,19 +1353,16 @@ static int ieee80211_ioctl_set_channel_flag(struct net_device *dev, struct prism2_hostapd_param *param) { struct ieee80211_local *local = dev->ieee80211_ptr; - struct ieee80211_hw_modes *mode = NULL; + struct ieee80211_hw_mode *mode; struct ieee80211_channel *chan = NULL; int i; - for (i = 0; i < local->hw.num_modes; i++) { - mode = &local->hw.modes[i]; + list_for_each_entry(mode, &local->modes_list, list) { if (mode->mode == param->u.set_channel_flag.mode) - break; - mode = NULL; + goto found; } - - if (!mode) - return -ENOENT; + return -ENOENT; +found: for (i = 0; i < mode->num_channels; i++) { chan = &mode->channels[i]; @@ -1706,10 +1699,10 @@ static void ieee80211_unmask_channel(struct net_device *dev, int mode, static int ieee80211_unmask_channels(struct net_device *dev) { struct ieee80211_local *local = dev->ieee80211_ptr; - int m, c; + struct ieee80211_hw_mode *mode; + int c; - for (m = 0; m < local->hw.num_modes; m++) { - struct ieee80211_hw_modes *mode = &local->hw.modes[m]; + list_for_each_entry(mode, &local->modes_list, list) { for (c = 0; c < mode->num_channels; c++) { ieee80211_unmask_channel(dev, mode->mode, &mode->channels[c]); @@ -1807,7 +1800,8 @@ int ieee80211_ioctl_siwfreq(struct net_device *dev, struct iw_freq *freq, char *extra) { struct ieee80211_local *local = dev->ieee80211_ptr; - int m, c, nfreq, set = 0; + struct ieee80211_hw_mode *mode; + int c, nfreq, set = 0; /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */ if (freq->e == 0) @@ -1822,8 +1816,7 @@ int ieee80211_ioctl_siwfreq(struct net_device *dev, return -EINVAL; } - for (m = 0; m < local->hw.num_modes; m++) { - struct ieee80211_hw_modes *mode = &local->hw.modes[m]; + list_for_each_entry(mode, &local->modes_list, list) { for (c = 0; c < mode->num_channels; c++) { struct ieee80211_channel *chan = &mode->channels[c]; if (chan->flag & IEEE80211_CHAN_W_SCAN && @@ -2005,7 +1998,7 @@ static int ieee80211_ioctl_siwscan(struct net_device *dev, sdata->type == IEEE80211_IF_TYPE_IBSS) { ssid = sdata->u.sta.ssid; ssid_len = sdata->u.sta.ssid_len; - } else if (sdata == IEEE80211_IF_TYPE_AP) { + } else if (sdata->type == IEEE80211_IF_TYPE_AP) { ssid = sdata->u.ap.ssid; ssid_len = sdata->u.ap.ssid_len; } else @@ -2166,10 +2159,10 @@ static int ieee80211_ioctl_giwretry(struct net_device *dev, static void ieee80211_ioctl_unmask_channels(struct ieee80211_local *local) { - int m, c; + struct ieee80211_hw_mode *mode; + int c; - for (m = 0; m < local->hw.num_modes; m++) { - struct ieee80211_hw_modes *mode = &local->hw.modes[m]; + list_for_each_entry(mode, &local->modes_list, list) { for (c = 0; c < mode->num_channels; c++) { struct ieee80211_channel *chan = &mode->channels[c]; chan->flag |= IEEE80211_CHAN_W_SCAN; @@ -2364,6 +2357,36 @@ static int ieee80211_ioctl_default_wep_only(struct ieee80211_local *local, } +void ieee80211_update_default_wep_only(struct ieee80211_local *local) +{ + int i = 0; + struct ieee80211_sub_if_data *sdata; + + spin_lock_bh(&local->sub_if_lock); + list_for_each_entry(sdata, &local->sub_if_list, list) { + + if (sdata->dev == local->mdev) + continue; + + /* If there is an AP interface then depend on userspace to + set default_wep_only correctly. */ + if (sdata->type == IEEE80211_IF_TYPE_AP) { + spin_unlock_bh(&local->sub_if_lock); + return; + } + + i++; + } + + if (i <= 1) + ieee80211_ioctl_default_wep_only(local, 1); + else + ieee80211_ioctl_default_wep_only(local, 0); + + spin_unlock_bh(&local->sub_if_lock); +} + + static int ieee80211_ioctl_prism2_param(struct net_device *dev, struct iw_request_info *info, void *wrqu, char *extra) @@ -3025,6 +3048,7 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *net wstats->qual.qual = 100*tmp_qual/local->hw.maxssi; wstats->qual.noise = sta->last_noise; wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; + sta_info_put(sta); } return wstats; } diff --git a/package/d80211/src/ieee80211_scan.c b/package/d80211/src/ieee80211_scan.c index 6db66f083..fe28f578b 100644 --- a/package/d80211/src/ieee80211_scan.c +++ b/package/d80211/src/ieee80211_scan.c @@ -24,49 +24,49 @@ #define SCAN_TXRX_THRESHOLD 75 static void get_channel_params(struct ieee80211_local *local, int channel, - struct ieee80211_hw_modes **mode, + struct ieee80211_hw_mode **mode, struct ieee80211_channel **chan) { - int m; + struct ieee80211_hw_mode *m; - for (m = 0; m < local->hw.num_modes; m++) { - *mode = &local->hw.modes[m]; - if ((*mode)->mode == local->hw.conf.phymode) + list_for_each_entry(m, &local->modes_list, list) { + *mode = m; + if (m->mode == local->hw.conf.phymode) break; } - local->scan.mode_idx = m; + local->scan.mode = m; local->scan.chan_idx = 0; do { - *chan = &(*mode)->channels[local->scan.chan_idx]; - if ((*chan)->chan == channel) { + *chan = &m->channels[local->scan.chan_idx]; + if ((*chan)->chan == channel) return; - } local->scan.chan_idx++; - } while (local->scan.chan_idx < (*mode)->num_channels); + } while (local->scan.chan_idx < m->num_channels); *chan = NULL; } static void next_chan_same_mode(struct ieee80211_local *local, - struct ieee80211_hw_modes **mode, + struct ieee80211_hw_mode **mode, struct ieee80211_channel **chan) { - int m, prev; + struct ieee80211_hw_mode *m; + int prev; - for (m = 0; m < local->hw.num_modes; m++) { - *mode = &local->hw.modes[m]; - if ((*mode)->mode == local->hw.conf.phymode) + list_for_each_entry(m, &local->modes_list, list) { + *mode = m; + if (m->mode == local->hw.conf.phymode) break; } - local->scan.mode_idx = m; + local->scan.mode = m; /* Select next channel - scan only channels marked with W_SCAN flag */ prev = local->scan.chan_idx; do { local->scan.chan_idx++; - if (local->scan.chan_idx >= (*mode)->num_channels) + if (local->scan.chan_idx >= m->num_channels) local->scan.chan_idx = 0; - *chan = &(*mode)->channels[local->scan.chan_idx]; + *chan = &m->channels[local->scan.chan_idx]; if ((*chan)->flag & IEEE80211_CHAN_W_SCAN) break; } while (local->scan.chan_idx != prev); @@ -74,43 +74,44 @@ static void next_chan_same_mode(struct ieee80211_local *local, static void next_chan_all_modes(struct ieee80211_local *local, - struct ieee80211_hw_modes **mode, + struct ieee80211_hw_mode **mode, struct ieee80211_channel **chan) { - int prev, prev_m; - - if (local->scan.mode_idx >= local->hw.num_modes) { - local->scan.mode_idx = 0; - local->scan.chan_idx = 0; - } + struct ieee80211_hw_mode *prev_m; + int prev; /* Select next channel - scan only channels marked with W_SCAN flag */ prev = local->scan.chan_idx; - prev_m = local->scan.mode_idx; + prev_m = local->scan.mode; do { - *mode = &local->hw.modes[local->scan.mode_idx]; + *mode = local->scan.mode; local->scan.chan_idx++; if (local->scan.chan_idx >= (*mode)->num_channels) { + struct list_head *next; + local->scan.chan_idx = 0; - local->scan.mode_idx++; - if (local->scan.mode_idx >= local->hw.num_modes) - local->scan.mode_idx = 0; - *mode = &local->hw.modes[local->scan.mode_idx]; + next = (*mode)->list.next; + if (next == &local->modes_list) + next = next->next; + *mode = list_entry(next, + struct ieee80211_hw_mode, + list); + local->scan.mode = *mode; } *chan = &(*mode)->channels[local->scan.chan_idx]; if ((*chan)->flag & IEEE80211_CHAN_W_SCAN) break; } while (local->scan.chan_idx != prev || - local->scan.mode_idx != prev_m); + local->scan.mode != prev_m); } static void ieee80211_scan_start(struct ieee80211_local *local, struct ieee80211_scan_conf *conf) { - int old_mode_idx = local->scan.mode_idx; + struct ieee80211_hw_mode *old_mode = local->scan.mode; int old_chan_idx = local->scan.chan_idx; - struct ieee80211_hw_modes *mode = NULL; + struct ieee80211_hw_mode *mode = NULL; struct ieee80211_channel *chan = NULL; int ret; @@ -189,7 +190,7 @@ static void ieee80211_scan_start(struct ieee80211_local *local, if (ret == -EAGAIN) { local->scan.timer.expires = jiffies + (local->scan.interval * HZ / 100); - local->scan.mode_idx = old_mode_idx; + local->scan.mode = old_mode; local->scan.chan_idx = old_chan_idx; } else { printk(KERN_DEBUG "%s: Got unknown error from " @@ -207,23 +208,17 @@ static void ieee80211_scan_start(struct ieee80211_local *local, static void ieee80211_scan_stop(struct ieee80211_local *local, struct ieee80211_scan_conf *conf) { - struct ieee80211_hw_modes *mode; + struct ieee80211_hw_mode *mode; struct ieee80211_channel *chan; int wait; if (!local->ops->passive_scan) return; - if (local->scan.mode_idx >= local->hw.num_modes) { - local->scan.mode_idx = 0; - local->scan.chan_idx = 0; - } + mode = local->scan.mode; - mode = &local->hw.modes[local->scan.mode_idx]; - - if (local->scan.chan_idx >= mode->num_channels) { + if (local->scan.chan_idx >= mode->num_channels) local->scan.chan_idx = 0; - } chan = &mode->channels[local->scan.chan_idx]; diff --git a/package/d80211/src/ieee80211_sta.c b/package/d80211/src/ieee80211_sta.c index 4985afe50..feba62b05 100644 --- a/package/d80211/src/ieee80211_sta.c +++ b/package/d80211/src/ieee80211_sta.c @@ -26,7 +26,6 @@ #include <asm/delay.h> #include <net/d80211.h> -#include <net/d80211_mgmt.h> #include "ieee80211_i.h" #include "ieee80211_rate.h" #include "hostapd_ioctl.h" @@ -392,7 +391,7 @@ static void ieee80211_set_disassoc(struct net_device *dev, } static void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb, - int encrypt, int probe_resp) + int encrypt) { struct ieee80211_sub_if_data *sdata; struct ieee80211_tx_packet_data *pkt_data; @@ -406,8 +405,6 @@ static void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb, pkt_data->ifindex = sdata->dev->ifindex; pkt_data->mgmt_iface = (sdata->type == IEEE80211_IF_TYPE_MGMT); pkt_data->do_not_encrypt = !encrypt; - if (probe_resp) - pkt_data->pkt_probe_resp = 1; dev_queue_xmit(skb); } @@ -444,7 +441,7 @@ static void ieee80211_send_auth(struct net_device *dev, if (extra) memcpy(skb_put(skb, extra_len), extra, extra_len); - ieee80211_sta_tx(dev, skb, encrypt, 0); + ieee80211_sta_tx(dev, skb, encrypt); } @@ -581,7 +578,7 @@ static void ieee80211_send_assoc(struct net_device *dev, if (ifsta->assocreq_ies) memcpy(ifsta->assocreq_ies, ies, ifsta->assocreq_ies_len); - ieee80211_sta_tx(dev, skb, 0, 0); + ieee80211_sta_tx(dev, skb, 0); } @@ -608,7 +605,7 @@ static void ieee80211_send_deauth(struct net_device *dev, skb_put(skb, 2); mgmt->u.deauth.reason_code = cpu_to_le16(reason); - ieee80211_sta_tx(dev, skb, 0, 0); + ieee80211_sta_tx(dev, skb, 0); } @@ -635,7 +632,7 @@ static void ieee80211_send_disassoc(struct net_device *dev, skb_put(skb, 2); mgmt->u.disassoc.reason_code = cpu_to_le16(reason); - ieee80211_sta_tx(dev, skb, 0, 0); + ieee80211_sta_tx(dev, skb, 0); } @@ -810,7 +807,7 @@ static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, *pos = rate->rate / 5; } - ieee80211_sta_tx(dev, skb, 0, 0); + ieee80211_sta_tx(dev, skb, 0); } @@ -1365,15 +1362,18 @@ static void ieee80211_rx_bss_info(struct net_device *dev, static unsigned long last_tsf_debug = 0; u64 tsf; if (local->ops->get_tsf) - tsf = local->ops->get_tsf(local->mdev); + tsf = local->ops->get_tsf(local_to_hw(local)); else tsf = -1LLU; if (time_after(jiffies, last_tsf_debug + 5 * HZ)) { printk(KERN_DEBUG "RX beacon SA=" MAC_FMT " BSSID=" MAC_FMT " TSF=0x%llx BCN=0x%llx diff=%lld " - "@%ld\n", + "@%lu\n", MAC_ARG(mgmt->sa), MAC_ARG(mgmt->bssid), - tsf, timestamp, tsf - timestamp, jiffies); + (unsigned long long)tsf, + (unsigned long long)timestamp, + (unsigned long long)(tsf - timestamp), + jiffies); last_tsf_debug = jiffies; } #endif /* CONFIG_D80211_IBSS_DEBUG */ @@ -1386,6 +1386,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev, if (sdata->type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && (sta = sta_info_get(local, mgmt->sa))) { + struct ieee80211_hw_mode *mode; struct ieee80211_rate *rates; size_t num_rates; u32 supp_rates, prev_rates; @@ -1395,8 +1396,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev, num_rates = local->num_curr_rates; oper_mode = local->sta_scanning ? local->scan_oper_phymode : local->hw.conf.phymode; - for (i = 0; i < local->hw.num_modes; i++) { - struct ieee80211_hw_modes *mode = &local->hw.modes[i]; + list_for_each_entry(mode, &local->modes_list, list) { if (oper_mode == mode->mode) { rates = mode->rates; num_rates = mode->num_rates; @@ -1699,7 +1699,7 @@ static void ieee80211_rx_mgmt_probe_req(struct net_device *dev, printk(KERN_DEBUG "%s: Sending ProbeResp to " MAC_FMT "\n", dev->name, MAC_ARG(resp->da)); #endif /* CONFIG_D80211_IBSS_DEBUG */ - ieee80211_sta_tx(dev, skb, 0, 1); + ieee80211_sta_tx(dev, skb, 0); } @@ -1843,10 +1843,11 @@ static void ieee80211_sta_merge_ibss(struct net_device *dev, } -void ieee80211_sta_work(void *ptr) +void ieee80211_sta_work(struct work_struct *work) { - struct net_device *dev = ptr; - struct ieee80211_sub_if_data *sdata; + struct ieee80211_sub_if_data *sdata = + container_of(work, struct ieee80211_sub_if_data, u.sta.work.work); + struct net_device *dev = sdata->dev; struct ieee80211_if_sta *ifsta; if (!netif_running(dev)) @@ -1923,17 +1924,17 @@ static void ieee80211_sta_new_auth(struct net_device *dev, printk(KERN_DEBUG "%s: Initial auth_alg=%d\n", dev->name, ifsta->auth_alg); ifsta->auth_transaction = -1; - ifsta->auth_tries = ifsta->assoc_tries = 0; + ifsta->associated = ifsta->auth_tries = ifsta->assoc_tries = 0; ieee80211_authenticate(dev, ifsta); } static int ieee80211_ibss_allowed(struct ieee80211_local *local) { - int m, c; + struct ieee80211_hw_mode *mode; + int c; - for (m = 0; m < local->hw.num_modes; m++) { - struct ieee80211_hw_modes *mode = &local->hw.modes[m]; + list_for_each_entry(mode, &local->modes_list, list) { if (mode->mode != local->hw.conf.phymode) continue; for (c = 0; c < mode->num_channels; c++) { @@ -2052,7 +2053,6 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, } memset(&control, 0, sizeof(control)); - control.pkt_type = PKT_PROBE_RESP; memset(&extra, 0, sizeof(extra)); extra.endidx = local->num_curr_rates; rate = rate_control_get_rate(local, dev, skb, &extra); @@ -2355,7 +2355,7 @@ int ieee80211_sta_set_bssid(struct net_device *dev, u8 *bssid) ifsta->bssid_set = 0; else ifsta->bssid_set = 1; - if (ifsta->ssid_set) + if (ifsta->ssid_set && ifsta->state != IEEE80211_AUTHENTICATE) ieee80211_sta_new_auth(dev, ifsta); return 0; @@ -2389,10 +2389,10 @@ static int ieee80211_sta_restore_oper_chan(struct net_device *dev) static int ieee80211_active_scan(struct ieee80211_local *local) { - int m, c; + struct ieee80211_hw_mode *mode; + int c; - for (m = 0; m < local->hw.num_modes; m++) { - struct ieee80211_hw_modes *mode = &local->hw.modes[m]; + list_for_each_entry(mode, &local->modes_list, list) { if (mode->mode != local->hw.conf.phymode) continue; for (c = 0; c < mode->num_channels; c++) { @@ -2413,7 +2413,7 @@ static int ieee80211_active_scan(struct ieee80211_local *local) void ieee80211_scan_completed(struct ieee80211_hw *hw) { struct ieee80211_local *local = hw_to_local(hw); - struct net_device *dev = local->scan_work.data; + struct net_device *dev = local->scan_dev; struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); union iwreq_data wrqu; @@ -2434,12 +2434,13 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw) } EXPORT_SYMBOL(ieee80211_scan_completed); -static void ieee80211_sta_scan_work(void *ptr) +void ieee80211_sta_scan_work(struct work_struct *work) { - struct net_device *dev = ptr; - struct ieee80211_local *local = dev->ieee80211_ptr; + struct ieee80211_local *local = + container_of(work, struct ieee80211_local, scan_work.work); + struct net_device *dev = local->scan_dev; struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_hw_modes *mode; + struct ieee80211_hw_mode *mode; struct ieee80211_channel *chan; int skip; unsigned long next_delay = 0; @@ -2449,10 +2450,9 @@ static void ieee80211_sta_scan_work(void *ptr) switch (local->scan_state) { case SCAN_SET_CHANNEL: - mode = &local->hw.modes[local->scan_hw_mode_idx]; - if (local->scan_hw_mode_idx >= local->hw.num_modes || - (local->scan_hw_mode_idx + 1 == local->hw.num_modes && - local->scan_channel_idx >= mode->num_channels)) { + mode = local->scan_hw_mode; + if (local->scan_hw_mode->list.next == &local->modes_list && + local->scan_channel_idx >= mode->num_channels) { if (ieee80211_sta_restore_oper_chan(dev)) { printk(KERN_DEBUG "%s: failed to restore " "operational channel after scan\n", @@ -2492,10 +2492,13 @@ static void ieee80211_sta_scan_work(void *ptr) } local->scan_channel_idx++; - if (local->scan_channel_idx >= - local->hw.modes[local->scan_hw_mode_idx].num_channels) { - local->scan_hw_mode_idx++; - local->scan_channel_idx = 0; + if (local->scan_channel_idx >= local->scan_hw_mode->num_channels) { + if (local->scan_hw_mode->list.next != &local->modes_list) { + local->scan_hw_mode = list_entry(local->scan_hw_mode->list.next, + struct ieee80211_hw_mode, + list); + local->scan_channel_idx = 0; + } } if (skip) @@ -2520,7 +2523,7 @@ static void ieee80211_sta_scan_work(void *ptr) if (next_delay) schedule_delayed_work(&local->scan_work, next_delay); else - schedule_work(&local->scan_work); + schedule_work(&local->scan_work.work); } } @@ -2553,7 +2556,7 @@ int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len) * scan */ if (local->sta_scanning) { - if (local->scan_work.data == dev) + if (local->scan_dev == dev) return 0; return -EBUSY; } @@ -2565,7 +2568,7 @@ int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len) ssid, ssid_len); if (!rc) { local->sta_scanning = 1; - local->scan_work.data = dev; + local->scan_dev = dev; } return rc; } @@ -2581,10 +2584,12 @@ int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len) } else local->scan_ssid_len = 0; local->scan_state = SCAN_SET_CHANNEL; - local->scan_hw_mode_idx = 0; + local->scan_hw_mode = list_entry(local->modes_list.next, + struct ieee80211_hw_mode, + list); local->scan_channel_idx = 0; - INIT_WORK(&local->scan_work, ieee80211_sta_scan_work, dev); - schedule_work(&local->scan_work); + local->scan_dev = dev; + schedule_work(&local->scan_work.work); return 0; } @@ -2697,7 +2702,7 @@ ieee80211_sta_scan_result(struct net_device *dev, if (buf) { memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVCUSTOM; - sprintf(buf, "tsf=%016llx", bss->timestamp); + sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp)); iwe.u.data.length = strlen(buf); current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf); diff --git a/package/d80211/src/ieee80211_sysfs.c b/package/d80211/src/ieee80211_sysfs.c index 6a60077d7..b9d0973d1 100644 --- a/package/d80211/src/ieee80211_sysfs.c +++ b/package/d80211/src/ieee80211_sysfs.c @@ -189,15 +189,13 @@ __IEEE80211_LOCAL_SHOW(tx_power_reduction); static ssize_t ieee80211_local_fmt_modes(struct ieee80211_local *local, char *buf) { - int i; - struct ieee80211_hw_modes *mode; + struct ieee80211_hw_mode *mode; char *p = buf; - /* FIXME: locking against ieee80211_update_hw? */ - for (i = 0; i < local->hw.num_modes; i++) { - mode = &local->hw.modes[i]; + /* FIXME: Locking? Could register a mode in the meantime. */ + list_for_each_entry(mode, &local->modes_list, list) p += sprintf(p, "%s\n", ieee80211_mode_str_short(mode->mode)); - } + return (p - buf); } __IEEE80211_LOCAL_SHOW(modes); diff --git a/package/d80211/src/include/compat_hacks.h b/package/d80211/src/include/compat_hacks.h new file mode 100644 index 000000000..07f46cbcb --- /dev/null +++ b/package/d80211/src/include/compat_hacks.h @@ -0,0 +1,28 @@ +#ifndef __COMPAT_HACKS +#define __COMPAT_HACKS + +#include <linux/types.h> +#include <linux/workqueue.h> +#include <net/sch_generic.h> + +struct delayed_work { + struct work_struct work; +}; + +#define INIT_DELAYED_WORK(_work, _func) \ + INIT_WORK(&(_work)->work, _func, NULL) + +#define INIT_WORK_NEW(_work, _func) INIT_WORK(_work, _func, NULL) + +#define schedule_delayed_work(_work, interval) schedule_delayed_work(&(_work)->work, interval) +#define cancel_delayed_work(_work) cancel_delayed_work(&(_work)->work) + +static inline struct Qdisc *_qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops) +{ + return qdisc_create_dflt(dev, ops); +} + +#define qdisc_create_dflt(_dev, _ops, _handle) \ + _qdisc_create_dflt(_dev, _ops) + +#endif diff --git a/package/d80211/src/include/net/d80211_mgmt.h b/package/d80211/src/include/linux/ieee80211.h index 87141d4ed..fe9ef2684 100644 --- a/package/d80211/src/include/net/d80211_mgmt.h +++ b/package/d80211/src/include/linux/ieee80211.h @@ -1,25 +1,116 @@ /* - * IEEE 802.11 -- shared defines for 80211.o and hostapd - * Copyright 2002, Jouni Malinen <jkmaline@cc.hut.fi> - * Copyright 2002-2004, Instant802 Networks, Inc. - * Copyright 2005, Devicescape Software, Inc. + * IEEE 802.11 defines + * + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen + * <jkmaline@cc.hut.fi> + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> + * Copyright (c) 2005, Devicescape Software, Inc. + * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#ifndef D802_11_MGMT_H -#define D802_11_MGMT_H +#ifndef IEEE80211_H +#define IEEE80211_H #include <linux/types.h> +#define FCS_LEN 4 + +#define IEEE80211_FCTL_VERS 0x0003 +#define IEEE80211_FCTL_FTYPE 0x000c +#define IEEE80211_FCTL_STYPE 0x00f0 +#define IEEE80211_FCTL_TODS 0x0100 +#define IEEE80211_FCTL_FROMDS 0x0200 +#define IEEE80211_FCTL_MOREFRAGS 0x0400 +#define IEEE80211_FCTL_RETRY 0x0800 +#define IEEE80211_FCTL_PM 0x1000 +#define IEEE80211_FCTL_MOREDATA 0x2000 +#define IEEE80211_FCTL_PROTECTED 0x4000 +#define IEEE80211_FCTL_ORDER 0x8000 + +#define IEEE80211_SCTL_FRAG 0x000F +#define IEEE80211_SCTL_SEQ 0xFFF0 + +#define IEEE80211_FTYPE_MGMT 0x0000 +#define IEEE80211_FTYPE_CTL 0x0004 +#define IEEE80211_FTYPE_DATA 0x0008 + +/* management */ +#define IEEE80211_STYPE_ASSOC_REQ 0x0000 +#define IEEE80211_STYPE_ASSOC_RESP 0x0010 +#define IEEE80211_STYPE_REASSOC_REQ 0x0020 +#define IEEE80211_STYPE_REASSOC_RESP 0x0030 +#define IEEE80211_STYPE_PROBE_REQ 0x0040 +#define IEEE80211_STYPE_PROBE_RESP 0x0050 +#define IEEE80211_STYPE_BEACON 0x0080 +#define IEEE80211_STYPE_ATIM 0x0090 +#define IEEE80211_STYPE_DISASSOC 0x00A0 +#define IEEE80211_STYPE_AUTH 0x00B0 +#define IEEE80211_STYPE_DEAUTH 0x00C0 +#define IEEE80211_STYPE_ACTION 0x00D0 + +/* control */ +#define IEEE80211_STYPE_PSPOLL 0x00A0 +#define IEEE80211_STYPE_RTS 0x00B0 +#define IEEE80211_STYPE_CTS 0x00C0 +#define IEEE80211_STYPE_ACK 0x00D0 +#define IEEE80211_STYPE_CFEND 0x00E0 +#define IEEE80211_STYPE_CFENDACK 0x00F0 + +/* data */ +#define IEEE80211_STYPE_DATA 0x0000 +#define IEEE80211_STYPE_DATA_CFACK 0x0010 +#define IEEE80211_STYPE_DATA_CFPOLL 0x0020 +#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030 +#define IEEE80211_STYPE_NULLFUNC 0x0040 +#define IEEE80211_STYPE_CFACK 0x0050 +#define IEEE80211_STYPE_CFPOLL 0x0060 +#define IEEE80211_STYPE_CFACKPOLL 0x0070 +#define IEEE80211_STYPE_QOS_DATA 0x0080 +#define IEEE80211_STYPE_QOS_DATA_CFACK 0x0090 +#define IEEE80211_STYPE_QOS_DATA_CFPOLL 0x00A0 +#define IEEE80211_STYPE_QOS_DATA_CFACKPOLL 0x00B0 +#define IEEE80211_STYPE_QOS_NULLFUNC 0x00C0 +#define IEEE80211_STYPE_QOS_CFACK 0x00D0 +#define IEEE80211_STYPE_QOS_CFPOLL 0x00E0 +#define IEEE80211_STYPE_QOS_CFACKPOLL 0x00F0 + + +/* miscellaneous IEEE 802.11 constants */ +#define IEEE80211_MAX_FRAG_THRESHOLD 2346 +#define IEEE80211_MAX_RTS_THRESHOLD 2347 +#define IEEE80211_MAX_AID 2007 +#define IEEE80211_MAX_TIM_LEN 251 +#define IEEE80211_MAX_DATA_LEN 2304 +/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section + 6.2.1.1.2. + + The figure in section 7.1.2 suggests a body size of up to 2312 + bytes is allowed, which is a bit confusing, I suspect this + represents the 2304 bytes of real data, plus a possible 8 bytes of + WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */ + + +struct ieee80211_hdr { + __le16 frame_control; + __le16 duration_id; + __u8 addr1[6]; + __u8 addr2[6]; + __u8 addr3[6]; + __le16 seq_ctrl; + __u8 addr4[6]; +} __attribute__ ((packed)); + + struct ieee80211_mgmt { __le16 frame_control; __le16 duration; - u8 da[6]; - u8 sa[6]; - u8 bssid[6]; + __u8 da[6]; + __u8 sa[6]; + __u8 bssid[6]; __le16 seq_ctrl; union { struct { @@ -27,7 +118,7 @@ struct ieee80211_mgmt { __le16 auth_transaction; __le16 status_code; /* possibly followed by Challenge text */ - u8 variable[0]; + __u8 variable[0]; } __attribute__ ((packed)) auth; struct { __le16 reason_code; @@ -43,14 +134,14 @@ struct ieee80211_mgmt { __le16 status_code; __le16 aid; /* followed by Supported rates */ - u8 variable[0]; + __u8 variable[0]; } __attribute__ ((packed)) assoc_resp, reassoc_resp; struct { __le16 capab_info; __le16 listen_interval; - u8 current_ap[6]; + __u8 current_ap[6]; /* followed by SSID and Supported rates */ - u8 variable[0]; + __u8 variable[0]; } __attribute__ ((packed)) reassoc_req; struct { __le16 reason_code; @@ -61,11 +152,11 @@ struct ieee80211_mgmt { __le16 capab_info; /* followed by some of SSID, Supported rates, * FH Params, DS Params, CF Params, IBSS Params, TIM */ - u8 variable[0]; + __u8 variable[0]; } __attribute__ ((packed)) beacon; struct { /* only variable items: SSID, Supported rates */ - u8 variable[0]; + __u8 variable[0]; } __attribute__ ((packed)) probe_req; struct { __le64 timestamp; @@ -73,24 +164,24 @@ struct ieee80211_mgmt { __le16 capab_info; /* followed by some of SSID, Supported rates, * FH Params, DS Params, CF Params, IBSS Params */ - u8 variable[0]; + __u8 variable[0]; } __attribute__ ((packed)) probe_resp; struct { - u8 category; + __u8 category; union { struct { - u8 action_code; - u8 dialog_token; - u8 status_code; - u8 variable[0]; + __u8 action_code; + __u8 dialog_token; + __u8 status_code; + __u8 variable[0]; } __attribute__ ((packed)) wme_action; struct{ - u8 action_code; - u8 element_id; - u8 length; - u8 switch_mode; - u8 new_chan; - u8 switch_count; + __u8 action_code; + __u8 element_id; + __u8 length; + __u8 switch_mode; + __u8 new_chan; + __u8 switch_count; } __attribute__((packed)) chan_switch; } u; } __attribute__ ((packed)) action; @@ -105,18 +196,19 @@ struct ieee80211_mgmt { #define WLAN_AUTH_CHALLENGE_LEN 128 -#define WLAN_CAPABILITY_ESS BIT(0) -#define WLAN_CAPABILITY_IBSS BIT(1) -#define WLAN_CAPABILITY_CF_POLLABLE BIT(2) -#define WLAN_CAPABILITY_CF_POLL_REQUEST BIT(3) -#define WLAN_CAPABILITY_PRIVACY BIT(4) -#define WLAN_CAPABILITY_SHORT_PREAMBLE BIT(5) -#define WLAN_CAPABILITY_PBCC BIT(6) -#define WLAN_CAPABILITY_CHANNEL_AGILITY BIT(7) +#define WLAN_CAPABILITY_ESS (1<<0) +#define WLAN_CAPABILITY_IBSS (1<<1) +#define WLAN_CAPABILITY_CF_POLLABLE (1<<2) +#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) +#define WLAN_CAPABILITY_PRIVACY (1<<4) +#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5) +#define WLAN_CAPABILITY_PBCC (1<<6) +#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) /* 802.11h */ -#define WLAN_CAPABILITY_SPECTRUM_MGMT BIT(8) -#define WLAN_CAPABILITY_SHORT_SLOT_TIME BIT(10) -#define WLAN_CAPABILITY_DSSS_OFDM BIT(13) +#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8) +#define WLAN_CAPABILITY_QOS (1<<9) +#define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10) +#define WLAN_CAPABILITY_DSSS_OFDM (1<<13) /* Status codes */ enum ieee80211_statuscode { @@ -220,4 +312,4 @@ enum ieee80211_eid { WLAN_EID_QOS_PARAMETER = 222 }; -#endif /* D802_11_MGMT_H */ +#endif /* IEEE80211_H */ diff --git a/package/d80211/src/include/net/d80211.h b/package/d80211/src/include/net/d80211.h index 30980e11e..65a5d3681 100644 --- a/package/d80211/src/include/net/d80211.h +++ b/package/d80211/src/include/net/d80211.h @@ -15,7 +15,7 @@ #include <linux/skbuff.h> #include <linux/wireless.h> #include <linux/device.h> -#include "d80211_shared.h" +#include <linux/ieee80211.h> /* Note! Only ieee80211_tx_status_irqsafe() and ieee80211_rx_irqsafe() can be * called in hardware interrupt context. The low-level driver must not call any @@ -46,6 +46,10 @@ #define IEEE80211_VERSION 2 +#define IEEE80211_CHAN_W_SCAN 0x00000001 +#define IEEE80211_CHAN_W_ACTIVE_SCAN 0x00000002 +#define IEEE80211_CHAN_W_IBSS 0x00000004 + /* Channel information structure. Low-level driver is expected to fill in chan, * freq, and val fields. Other fields will be filled in by 80211.o based on * hostapd information and low-level driver does not need to use them. The @@ -60,6 +64,22 @@ struct ieee80211_channel { unsigned char antenna_max; }; +#define IEEE80211_RATE_ERP 0x00000001 +#define IEEE80211_RATE_BASIC 0x00000002 +#define IEEE80211_RATE_PREAMBLE2 0x00000004 +#define IEEE80211_RATE_SUPPORTED 0x00000010 +#define IEEE80211_RATE_OFDM 0x00000020 +#define IEEE80211_RATE_CCK 0x00000040 +#define IEEE80211_RATE_TURBO 0x00000080 +#define IEEE80211_RATE_MANDATORY 0x00000100 + +#define IEEE80211_RATE_CCK_2 (IEEE80211_RATE_CCK | IEEE80211_RATE_PREAMBLE2) +#define IEEE80211_RATE_MODULATION(f) \ +(f & (IEEE80211_RATE_CCK | IEEE80211_RATE_OFDM)) + +/* Low-level driver should set PREAMBLE2, OFDM, CCK, and TURBO flags. + * BASIC, SUPPORTED, ERP, and MANDATORY flags are set in 80211.o based on the + * configuration. */ struct ieee80211_rate { int rate; /* rate in 100 kbps */ int val; /* hw specific value for the rate */ @@ -76,12 +96,25 @@ struct ieee80211_rate { * optimizing channel utilization estimates */ }; -struct ieee80211_hw_modes { - int mode; - int num_channels; - struct ieee80211_channel *channels; - int num_rates; - struct ieee80211_rate *rates; +/* 802.11g is backwards-compatible with 802.11b, so a wlan card can + * actually be both in 11b and 11g modes at the same time. */ +enum { + MODE_IEEE80211A = 0 /* IEEE 802.11a */, + MODE_IEEE80211B = 1 /* IEEE 802.11b only */, + MODE_ATHEROS_TURBO = 2 /* Atheros Turbo mode (2x.11a at 5 GHz) */, + MODE_IEEE80211G = 3 /* IEEE 802.11g (and 802.11b compatibility) */, + MODE_ATHEROS_TURBOG = 4 /* Atheros Turbo mode (2x.11g at 2.4 GHz) */, + NUM_IEEE80211_MODES = 5 +}; + +struct ieee80211_hw_mode { + int mode; /* MODE_IEEE80211... */ + int num_channels; /* Number of channels (below) */ + struct ieee80211_channel *channels; /* Array of supported channels */ + int num_rates; /* Number of rates (below) */ + struct ieee80211_rate *rates; /* Array of supported rates */ + + struct list_head list; /* Internal, don't touch */ }; struct ieee80211_tx_queue_params { @@ -135,7 +168,6 @@ struct ieee80211_low_level_stats { #define HW_KEY_IDX_INVALID -1 struct ieee80211_tx_control { - enum { PKT_NORMAL = 0, PKT_PROBE_RESP } pkt_type; int tx_rate; /* Transmit rate, given as the hw specific value for the * rate (from struct ieee80211_rate) */ int rts_cts_rate; /* Transmit rate for RTS/CTS frame, given as the hw @@ -420,9 +452,7 @@ typedef enum { SET_KEY, DISABLE_KEY, REMOVE_ALL_KEYS, } set_key_cmd; -/* This is driver-visible part of the per-hw state the stack keeps. - * If you change something in here, call ieee80211_update_hw() to - * notify the stack about the change. */ +/* This is driver-visible part of the per-hw state the stack keeps. */ struct ieee80211_hw { /* these are assigned by d80211, don't write */ int index; @@ -512,9 +542,6 @@ struct ieee80211_hw { /* This is maximum value for rssi reported by this device */ int maxssi; - int num_modes; - struct ieee80211_hw_modes *modes; - /* Number of available hardware TX queues for data packets. * WMM requires at least four queues. */ int queues; @@ -713,11 +740,11 @@ struct ieee80211_ops { * priv_data_len. */ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, - struct ieee80211_ops *ops); + const struct ieee80211_ops *ops); /* Register hardware device to the IEEE 802.11 code and kernel. Low-level * drivers must call this function before using any other IEEE 802.11 - * function. */ + * function except ieee80211_register_hwmode. */ int ieee80211_register_hw(struct ieee80211_hw *hw); /* driver can use this and ieee80211_get_rx_led_name to get the @@ -750,9 +777,9 @@ static inline char *ieee80211_get_rx_led_name(struct ieee80211_hw *hw) #endif } -/* Call this function if you changed the hardware description after - * ieee80211_register_hw */ -int ieee80211_update_hw(struct ieee80211_hw *hw); +/* Register a new hardware PHYMODE capability to the stack. */ +int ieee80211_register_hwmode(struct ieee80211_hw *hw, + struct ieee80211_hw_mode *mode); /* Unregister a hardware device. This function instructs 802.11 code to free * allocated resources and unregister netdevices from the kernel. */ @@ -936,95 +963,6 @@ enum { IEEE80211_TEST_PARAM_TX_ANT_SEL_RAW = 5, }; -/* IEEE 802.11 defines */ - -#define FCS_LEN 4 - -#define IEEE80211_DATA_LEN 2304 -/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section - 6.2.1.1.2. - - The figure in section 7.1.2 suggests a body size of up to 2312 - bytes is allowed, which is a bit confusing, I suspect this - represents the 2304 bytes of real data, plus a possible 8 bytes of - WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */ - -#define IEEE80211_FCTL_VERS 0x0003 -#define IEEE80211_FCTL_FTYPE 0x000c -#define IEEE80211_FCTL_STYPE 0x00f0 -#define IEEE80211_FCTL_TODS 0x0100 -#define IEEE80211_FCTL_FROMDS 0x0200 -#define IEEE80211_FCTL_MOREFRAGS 0x0400 -#define IEEE80211_FCTL_RETRY 0x0800 -#define IEEE80211_FCTL_PM 0x1000 -#define IEEE80211_FCTL_MOREDATA 0x2000 -#define IEEE80211_FCTL_PROTECTED 0x4000 -#define IEEE80211_FCTL_ORDER 0x8000 - -#define IEEE80211_SCTL_FRAG 0x000F -#define IEEE80211_SCTL_SEQ 0xFFF0 - -#define IEEE80211_FTYPE_MGMT 0x0000 -#define IEEE80211_FTYPE_CTL 0x0004 -#define IEEE80211_FTYPE_DATA 0x0008 - -/* management */ -#define IEEE80211_STYPE_ASSOC_REQ 0x0000 -#define IEEE80211_STYPE_ASSOC_RESP 0x0010 -#define IEEE80211_STYPE_REASSOC_REQ 0x0020 -#define IEEE80211_STYPE_REASSOC_RESP 0x0030 -#define IEEE80211_STYPE_PROBE_REQ 0x0040 -#define IEEE80211_STYPE_PROBE_RESP 0x0050 -#define IEEE80211_STYPE_BEACON 0x0080 -#define IEEE80211_STYPE_ATIM 0x0090 -#define IEEE80211_STYPE_DISASSOC 0x00A0 -#define IEEE80211_STYPE_AUTH 0x00B0 -#define IEEE80211_STYPE_DEAUTH 0x00C0 -#define IEEE80211_STYPE_ACTION 0x00D0 - -/* control */ -#define IEEE80211_STYPE_PSPOLL 0x00A0 -#define IEEE80211_STYPE_RTS 0x00B0 -#define IEEE80211_STYPE_CTS 0x00C0 -#define IEEE80211_STYPE_ACK 0x00D0 -#define IEEE80211_STYPE_CFEND 0x00E0 -#define IEEE80211_STYPE_CFENDACK 0x00F0 - -/* data */ -#define IEEE80211_STYPE_DATA 0x0000 -#define IEEE80211_STYPE_DATA_CFACK 0x0010 -#define IEEE80211_STYPE_DATA_CFPOLL 0x0020 -#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030 -#define IEEE80211_STYPE_NULLFUNC 0x0040 -#define IEEE80211_STYPE_CFACK 0x0050 -#define IEEE80211_STYPE_CFPOLL 0x0060 -#define IEEE80211_STYPE_CFACKPOLL 0x0070 -#define IEEE80211_STYPE_QOS_DATA 0x0080 -#define IEEE80211_STYPE_QOS_DATA_CFACK 0x0090 -#define IEEE80211_STYPE_QOS_DATA_CFPOLL 0x00A0 -#define IEEE80211_STYPE_QOS_DATA_CFACKPOLL 0x00B0 -#define IEEE80211_STYPE_QOS_NULLFUNC 0x00C0 -#define IEEE80211_STYPE_QOS_CFACK 0x00D0 -#define IEEE80211_STYPE_QOS_CFPOLL 0x00E0 -#define IEEE80211_STYPE_QOS_CFACKPOLL 0x00F0 - - -/* miscellaneous IEEE 802.11 constants */ -#define IEEE80211_MAX_FRAG_THRESHOLD 2346 -#define IEEE80211_MAX_RTS_THRESHOLD 2347 -#define IEEE80211_MAX_AID 2007 -#define IEEE80211_MAX_TIM_LEN 251 - -struct ieee80211_hdr { - __le16 frame_control; - __le16 duration_id; - u8 addr1[6]; - u8 addr2[6]; - u8 addr3[6]; - __le16 seq_ctrl; - u8 addr4[6]; -} __attribute__ ((packed)); - /* return a pointer to the source address (SA) */ static inline u8 *ieee80211_get_SA(struct ieee80211_hdr *hdr) { diff --git a/package/d80211/src/include/net/d80211_shared.h b/package/d80211/src/include/net/d80211_shared.h deleted file mode 100644 index 2f1bb4259..000000000 --- a/package/d80211/src/include/net/d80211_shared.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * IEEE 802.11 -- shared defines for low-level drivers, 80211.o, and hostapd - * Copyright 2002-2004, Instant802 Networks, Inc. - * Copyright 2005, Devicescape Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef D80211_SHARED_H -#define D80211_SHARED_H - -/* 802.11g is backwards-compatible with 802.11b, so a wlan card can - * actually be both in 11b and 11g modes at the same time. */ -enum { - MODE_IEEE80211A = 0 /* IEEE 802.11a */, - MODE_IEEE80211B = 1 /* IEEE 802.11b only */, - MODE_ATHEROS_TURBO = 2 /* Atheros Turbo mode (2x.11a at 5 GHz) */, - MODE_IEEE80211G = 3 /* IEEE 802.11g (and 802.11b compatibility) */, - MODE_ATHEROS_TURBOG = 4 /* Atheros Turbo mode (2x.11g at 2.4 GHz) */, - NUM_IEEE80211_MODES = 5 -}; - -#define IEEE80211_CHAN_W_SCAN 0x00000001 -#define IEEE80211_CHAN_W_ACTIVE_SCAN 0x00000002 -#define IEEE80211_CHAN_W_IBSS 0x00000004 - -/* Low-level driver should set PREAMBLE2, OFDM, CCK, and TURBO flags. - * BASIC, SUPPORTED, ERP, and MANDATORY flags are set in 80211.o based on the - * configuration. */ -#define IEEE80211_RATE_ERP 0x00000001 -#define IEEE80211_RATE_BASIC 0x00000002 -#define IEEE80211_RATE_PREAMBLE2 0x00000004 -#define IEEE80211_RATE_SUPPORTED 0x00000010 -#define IEEE80211_RATE_OFDM 0x00000020 -#define IEEE80211_RATE_CCK 0x00000040 -#define IEEE80211_RATE_TURBO 0x00000080 -#define IEEE80211_RATE_MANDATORY 0x00000100 - -#define IEEE80211_RATE_CCK_2 (IEEE80211_RATE_CCK | IEEE80211_RATE_PREAMBLE2) -#define IEEE80211_RATE_MODULATION(f) \ -(f & (IEEE80211_RATE_CCK | IEEE80211_RATE_OFDM)) - - -#endif /* D80211_SHARED_H */ diff --git a/package/d80211/src/sta_info.c b/package/d80211/src/sta_info.c index 0c42ae807..e8f2bab3f 100644 --- a/package/d80211/src/sta_info.c +++ b/package/d80211/src/sta_info.c @@ -342,9 +342,10 @@ static void sta_info_cleanup(unsigned long data) } -static void sta_info_proc_add_task(void *data) +static void sta_info_proc_add_task(struct work_struct *work) { - struct ieee80211_local *local = data; + struct ieee80211_local *local = + container_of(work, struct ieee80211_local, sta_proc_add); struct sta_info *sta, *tmp; while (1) { @@ -395,7 +396,7 @@ void sta_info_init(struct ieee80211_local *local) local->sta_cleanup.data = (unsigned long) local; local->sta_cleanup.function = sta_info_cleanup; - INIT_WORK(&local->sta_proc_add, sta_info_proc_add_task, local); + INIT_WORK(&local->sta_proc_add, sta_info_proc_add_task); } int sta_info_start(struct ieee80211_local *local) @@ -439,7 +440,7 @@ void sta_info_remove_aid_ptr(struct sta_info *sta) sdata->local->ops->set_tim(local_to_hw(sdata->local), sta->aid, 0); if (sdata->bss) - bss_tim_clear(sdata->local, sdata->bss, sta->aid); + __bss_tim_clear(sdata->bss, sta->aid); } diff --git a/package/d80211/src/wep.c b/package/d80211/src/wep.c index dee8eaec0..6a96ade59 100644 --- a/package/d80211/src/wep.c +++ b/package/d80211/src/wep.c @@ -15,6 +15,7 @@ #include <linux/crc32.h> #include <linux/crypto.h> #include <linux/err.h> +#include <linux/mm.h> #include <asm/scatterlist.h> #include <net/d80211.h> diff --git a/package/d80211/src/wme.c b/package/d80211/src/wme.c index b9505dcba..76e2c4b0c 100644 --- a/package/d80211/src/wme.c +++ b/package/d80211/src/wme.c @@ -129,24 +129,9 @@ static inline unsigned classify_1d(struct sk_buff *skb, struct Qdisc *qd) ip = (struct iphdr *) (skb->data + offset); dscp = ip->tos & 0xfc; - switch (dscp) { - case 0x20: - return 2; - case 0x40: - return 1; - case 0x60: - return 3; - case 0x80: - return 4; - case 0xa0: - return 5; - case 0xc0: - return 6; - case 0xe0: - return 7; - default: + if (dscp & 0x1c) return 0; - } + return dscp >> 5; } @@ -432,7 +417,8 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct rtattr *opt) /* create child queues */ for (i = 0; i < queues; i++) { skb_queue_head_init(&q->requeued[i]); - q->queues[i] = qdisc_create_dflt(qd->dev, &CHILD_QDISC_OPS); + q->queues[i] = qdisc_create_dflt(qd->dev, &CHILD_QDISC_OPS, + qd->handle); if (q->queues[i] == 0) { q->queues[i] = &noop_qdisc; printk(KERN_ERR "%s child qdisc %i creation failed", dev->name, i); @@ -658,7 +644,7 @@ void ieee80211_install_qdisc(struct net_device *dev) { struct Qdisc *qdisc; - qdisc = qdisc_create_dflt(dev, &wme_qdisc_ops); + qdisc = qdisc_create_dflt(dev, &wme_qdisc_ops, TC_H_ROOT); if (!qdisc) { printk(KERN_ERR "%s: qdisc installation failed\n", dev->name); return; diff --git a/package/d80211/src/wpa.c b/package/d80211/src/wpa.c index f64915694..7b64abf86 100644 --- a/package/d80211/src/wpa.c +++ b/package/d80211/src/wpa.c @@ -14,7 +14,7 @@ #include <net/iw_handler.h> #include <net/d80211.h> -#include <net/d80211_common.h> +#include "ieee80211_common.h" #include "ieee80211_i.h" #include "michael.h" #include "tkip.h" |