include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=kmod-d80211
-PKG_VERSION:=20061230
+PKG_VERSION:=20070201
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)
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
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))
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.
#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"
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
*/
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;
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;
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 "
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);
{
/* 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;
{
/* 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;
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;
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++) {
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;
dev->open = ieee80211_open;
dev->stop = ieee80211_stop;
dev->tx_queue_len = 0;
+ dev->uninit = ieee80211_if_reinit;
dev->destructor = ieee80211_if_free;
}
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)
{
}
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;
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;
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;
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;
}
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)
{
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();
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);
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);
--- /dev/null
+/*
+ * IEEE 802.11 driver (80211.o) -- hostapd interface
+ * Copyright 2002-2004, Instant802 Networks, 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 IEEE80211_COMMON_H
+#define IEEE80211_COMMON_H
+
+#include <linux/types.h>
+
+/*
+ * This is common header information with user space. It is used on all
+ * frames sent to wlan#ap interface.
+ */
+
+#define IEEE80211_FI_VERSION 0x80211001
+
+struct ieee80211_frame_info {
+ __be32 version;
+ __be32 length;
+ __be64 mactime;
+ __be64 hosttime;
+ __be32 phytype;
+ __be32 channel;
+ __be32 datarate;
+ __be32 antenna;
+ __be32 priority;
+ __be32 ssi_type;
+ __be32 ssi_signal;
+ __be32 ssi_noise;
+ __be32 preamble;
+ __be32 encoding;
+
+ /* Note: this structure is otherwise identical to capture format used
+ * in linux-wlan-ng, but this additional field is used to provide meta
+ * data about the frame to hostapd. This was the easiest method for
+ * providing this information, but this might change in the future. */
+ __be32 msg_type;
+} __attribute__ ((packed));
+
+
+enum ieee80211_msg_type {
+ ieee80211_msg_normal = 0,
+ ieee80211_msg_tx_callback_ack = 1,
+ ieee80211_msg_tx_callback_fail = 2,
+ ieee80211_msg_passive_scan = 3,
+ ieee80211_msg_wep_frame_unknown_key = 4,
+ ieee80211_msg_michael_mic_failure = 5,
+ /* hole at 6, was monitor but never sent to userspace */
+ ieee80211_msg_sta_not_assoc = 7,
+ ieee80211_msg_set_aid_for_sta = 8 /* used by Intersil MVC driver */,
+ ieee80211_msg_key_threshold_notification = 9,
+ ieee80211_msg_radar = 11,
+};
+
+struct ieee80211_msg_set_aid_for_sta {
+ char sta_address[ETH_ALEN];
+ u16 aid;
+};
+
+struct ieee80211_msg_key_notification {
+ int tx_rx_count;
+ char ifname[IFNAMSIZ];
+ u8 addr[ETH_ALEN]; /* ff:ff:ff:ff:ff:ff for broadcast keys */
+};
+
+
+enum ieee80211_phytype {
+ ieee80211_phytype_fhss_dot11_97 = 1,
+ ieee80211_phytype_dsss_dot11_97 = 2,
+ ieee80211_phytype_irbaseband = 3,
+ ieee80211_phytype_dsss_dot11_b = 4,
+ ieee80211_phytype_pbcc_dot11_b = 5,
+ ieee80211_phytype_ofdm_dot11_g = 6,
+ ieee80211_phytype_pbcc_dot11_g = 7,
+ ieee80211_phytype_ofdm_dot11_a = 8,
+ ieee80211_phytype_dsss_dot11_turbog = 255,
+ ieee80211_phytype_dsss_dot11_turbo = 256,
+};
+
+enum ieee80211_ssi_type {
+ ieee80211_ssi_none = 0,
+ ieee80211_ssi_norm = 1, /* normalized, 0-1000 */
+ ieee80211_ssi_dbm = 2,
+ ieee80211_ssi_raw = 3, /* raw SSI */
+};
+
+struct ieee80211_radar_info {
+ int channel;
+ int radar;
+ int radar_type;
+};
+
+#endif /* IEEE80211_COMMON_H */
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 {
int channel; /* channel to be scanned */
int tries;
- int mode_idx;
+ struct ieee80211_hw_mode *mode;
int chan_idx;
int freq;
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;
* 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) */
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;
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 */
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);
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);
#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"
{
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;
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;
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);
}
list_add(&sdata->list, &local->sub_if_list);
+ ieee80211_update_default_wep_only(local);
return 0;
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) {
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 |
dev->name, __FUNCTION__, type);
}
ieee80211_sysfs_change_if_type(dev);
+ ieee80211_update_default_wep_only(local);
}
/* Must be called with rtnl lock held. */
* 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
{
struct net_device *dev = sdata->dev;
- ieee80211_if_reinit(dev);
list_del(&sdata->list);
ieee80211_sysfs_remove_netdevice(dev);
unregister_netdevice(dev);
strcmp(name, sdata->dev->name) == 0 &&
sdata->dev != local->mdev) {
__ieee80211_if_del(local, sdata);
+ ieee80211_update_default_wep_only(local);
return 0;
}
}
#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"
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;
}
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;
}
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
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;
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;
}
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
* 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) {
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)) {
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;
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];
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]);
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)
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 &&
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
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;
}
+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)
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;
}
#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);
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;
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 "
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];
#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"
}
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;
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);
}
if (extra)
memcpy(skb_put(skb, extra_len), extra, extra_len);
- ieee80211_sta_tx(dev, skb, encrypt, 0);
+ ieee80211_sta_tx(dev, skb, encrypt);
}
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);
}
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);
}
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);
}
*pos = rate->rate / 5;
}
- ieee80211_sta_tx(dev, skb, 0, 0);
+ ieee80211_sta_tx(dev, skb, 0);
}
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 */
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;
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;
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);
}
}
-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))
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++) {
}
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);
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;
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++) {
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;
}
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;
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",
}
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)
if (next_delay)
schedule_delayed_work(&local->scan_work, next_delay);
else
- schedule_work(&local->scan_work);
+ schedule_work(&local->scan_work.work);
}
}
* scan */
if (local->sta_scanning) {
- if (local->scan_work.data == dev)
+ if (local->scan_dev == dev)
return 0;
return -EBUSY;
}
ssid, ssid_len);
if (!rc) {
local->sta_scanning = 1;
- local->scan_work.data = dev;
+ local->scan_dev = dev;
}
return rc;
}
} 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;
}
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);
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);
--- /dev/null
+#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
--- /dev/null
+/*
+ * 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 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];
+ __le16 seq_ctrl;
+ union {
+ struct {
+ __le16 auth_alg;
+ __le16 auth_transaction;
+ __le16 status_code;
+ /* possibly followed by Challenge text */
+ __u8 variable[0];
+ } __attribute__ ((packed)) auth;
+ struct {
+ __le16 reason_code;
+ } __attribute__ ((packed)) deauth;
+ struct {
+ __le16 capab_info;
+ __le16 listen_interval;
+ /* followed by SSID and Supported rates */
+ u8 variable[0];
+ } __attribute__ ((packed)) assoc_req;
+ struct {
+ __le16 capab_info;
+ __le16 status_code;
+ __le16 aid;
+ /* followed by Supported rates */
+ __u8 variable[0];
+ } __attribute__ ((packed)) assoc_resp, reassoc_resp;
+ struct {
+ __le16 capab_info;
+ __le16 listen_interval;
+ __u8 current_ap[6];
+ /* followed by SSID and Supported rates */
+ __u8 variable[0];
+ } __attribute__ ((packed)) reassoc_req;
+ struct {
+ __le16 reason_code;
+ } __attribute__ ((packed)) disassoc;
+ struct {
+ __le64 timestamp;
+ __le16 beacon_int;
+ __le16 capab_info;
+ /* followed by some of SSID, Supported rates,
+ * FH Params, DS Params, CF Params, IBSS Params, TIM */
+ __u8 variable[0];
+ } __attribute__ ((packed)) beacon;
+ struct {
+ /* only variable items: SSID, Supported rates */
+ __u8 variable[0];
+ } __attribute__ ((packed)) probe_req;
+ struct {
+ __le64 timestamp;
+ __le16 beacon_int;
+ __le16 capab_info;
+ /* followed by some of SSID, Supported rates,
+ * FH Params, DS Params, CF Params, IBSS Params */
+ __u8 variable[0];
+ } __attribute__ ((packed)) probe_resp;
+ struct {
+ __u8 category;
+ union {
+ struct {
+ __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;
+ } __attribute__((packed)) chan_switch;
+ } u;
+ } __attribute__ ((packed)) action;
+ } u;
+} __attribute__ ((packed));
+
+
+/* Authentication algorithms */
+#define WLAN_AUTH_OPEN 0
+#define WLAN_AUTH_SHARED_KEY 1
+#define WLAN_AUTH_LEAP 128
+
+#define WLAN_AUTH_CHALLENGE_LEN 128
+
+#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 (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 {
+ WLAN_STATUS_SUCCESS = 0,
+ WLAN_STATUS_UNSPECIFIED_FAILURE = 1,
+ WLAN_STATUS_CAPS_UNSUPPORTED = 10,
+ WLAN_STATUS_REASSOC_NO_ASSOC = 11,
+ WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12,
+ WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13,
+ WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14,
+ WLAN_STATUS_CHALLENGE_FAIL = 15,
+ WLAN_STATUS_AUTH_TIMEOUT = 16,
+ WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17,
+ WLAN_STATUS_ASSOC_DENIED_RATES = 18,
+ /* 802.11b */
+ WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19,
+ WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20,
+ WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21,
+ /* 802.11h */
+ WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22,
+ WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23,
+ WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24,
+ /* 802.11g */
+ WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25,
+ WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26,
+ /* 802.11i */
+ WLAN_STATUS_INVALID_IE = 40,
+ WLAN_STATUS_INVALID_GROUP_CIPHER = 41,
+ WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42,
+ WLAN_STATUS_INVALID_AKMP = 43,
+ WLAN_STATUS_UNSUPP_RSN_VERSION = 44,
+ WLAN_STATUS_INVALID_RSN_IE_CAP = 45,
+ WLAN_STATUS_CIPHER_SUITE_REJECTED = 46,
+};
+
+
+/* Reason codes */
+enum ieee80211_reasoncode {
+ WLAN_REASON_UNSPECIFIED = 1,
+ WLAN_REASON_PREV_AUTH_NOT_VALID = 2,
+ WLAN_REASON_DEAUTH_LEAVING = 3,
+ WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4,
+ WLAN_REASON_DISASSOC_AP_BUSY = 5,
+ WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6,
+ WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7,
+ WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8,
+ WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9,
+ /* 802.11h */
+ WLAN_REASON_DISASSOC_BAD_POWER = 10,
+ WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11,
+ /* 802.11i */
+ WLAN_REASON_INVALID_IE = 13,
+ WLAN_REASON_MIC_FAILURE = 14,
+ WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15,
+ WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16,
+ WLAN_REASON_IE_DIFFERENT = 17,
+ WLAN_REASON_INVALID_GROUP_CIPHER = 18,
+ WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19,
+ WLAN_REASON_INVALID_AKMP = 20,
+ WLAN_REASON_UNSUPP_RSN_VERSION = 21,
+ WLAN_REASON_INVALID_RSN_IE_CAP = 22,
+ WLAN_REASON_IEEE8021X_FAILED = 23,
+ WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
+};
+
+
+/* Information Element IDs */
+enum ieee80211_eid {
+ WLAN_EID_SSID = 0,
+ WLAN_EID_SUPP_RATES = 1,
+ WLAN_EID_FH_PARAMS = 2,
+ WLAN_EID_DS_PARAMS = 3,
+ WLAN_EID_CF_PARAMS = 4,
+ WLAN_EID_TIM = 5,
+ WLAN_EID_IBSS_PARAMS = 6,
+ WLAN_EID_CHALLENGE = 16,
+ /* 802.11d */
+ WLAN_EID_COUNTRY = 7,
+ WLAN_EID_HP_PARAMS = 8,
+ WLAN_EID_HP_TABLE = 9,
+ WLAN_EID_REQUEST = 10,
+ /* 802.11h */
+ WLAN_EID_PWR_CONSTRAINT = 32,
+ WLAN_EID_PWR_CAPABILITY = 33,
+ WLAN_EID_TPC_REQUEST = 34,
+ WLAN_EID_TPC_REPORT = 35,
+ WLAN_EID_SUPPORTED_CHANNELS = 36,
+ WLAN_EID_CHANNEL_SWITCH = 37,
+ WLAN_EID_MEASURE_REQUEST = 38,
+ WLAN_EID_MEASURE_REPORT = 39,
+ WLAN_EID_QUIET = 40,
+ WLAN_EID_IBSS_DFS = 41,
+ /* 802.11g */
+ WLAN_EID_ERP_INFO = 42,
+ WLAN_EID_EXT_SUPP_RATES = 50,
+ /* 802.11i */
+ WLAN_EID_RSN = 48,
+ WLAN_EID_WPA = 221,
+ WLAN_EID_GENERIC = 221,
+ WLAN_EID_VENDOR_SPECIFIC = 221,
+ WLAN_EID_QOS_PARAMETER = 222
+};
+
+#endif /* IEEE80211_H */
#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
#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
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 */
* 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 {
#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
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;
/* 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;
* 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
#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. */
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)
{
+++ /dev/null
-/*
- * IEEE 802.11 driver (80211.o) -- hostapd interface
- * Copyright 2002-2004, Instant802 Networks, 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_COMMON_H
-#define D80211_COMMON_H
-
-#include <linux/types.h>
-
-/*
- * This is common header information with user space. It is used on all
- * frames sent to wlan#ap interface.
- */
-
-#define IEEE80211_FI_VERSION 0x80211001
-
-struct ieee80211_frame_info {
- __be32 version;
- __be32 length;
- __be64 mactime;
- __be64 hosttime;
- __be32 phytype;
- __be32 channel;
- __be32 datarate;
- __be32 antenna;
- __be32 priority;
- __be32 ssi_type;
- __be32 ssi_signal;
- __be32 ssi_noise;
- __be32 preamble;
- __be32 encoding;
-
- /* Note: this structure is otherwise identical to capture format used
- * in linux-wlan-ng, but this additional field is used to provide meta
- * data about the frame to hostapd. This was the easiest method for
- * providing this information, but this might change in the future. */
- __be32 msg_type;
-} __attribute__ ((packed));
-
-
-enum ieee80211_msg_type {
- ieee80211_msg_normal = 0,
- ieee80211_msg_tx_callback_ack = 1,
- ieee80211_msg_tx_callback_fail = 2,
- ieee80211_msg_passive_scan = 3,
- ieee80211_msg_wep_frame_unknown_key = 4,
- ieee80211_msg_michael_mic_failure = 5,
- /* hole at 6, was monitor but never sent to userspace */
- ieee80211_msg_sta_not_assoc = 7,
- ieee80211_msg_set_aid_for_sta = 8 /* used by Intersil MVC driver */,
- ieee80211_msg_key_threshold_notification = 9,
- ieee80211_msg_radar = 11,
-};
-
-struct ieee80211_msg_set_aid_for_sta {
- char sta_address[ETH_ALEN];
- u16 aid;
-};
-
-struct ieee80211_msg_key_notification {
- int tx_rx_count;
- char ifname[IFNAMSIZ];
- u8 addr[ETH_ALEN]; /* ff:ff:ff:ff:ff:ff for broadcast keys */
-};
-
-
-enum ieee80211_phytype {
- ieee80211_phytype_fhss_dot11_97 = 1,
- ieee80211_phytype_dsss_dot11_97 = 2,
- ieee80211_phytype_irbaseband = 3,
- ieee80211_phytype_dsss_dot11_b = 4,
- ieee80211_phytype_pbcc_dot11_b = 5,
- ieee80211_phytype_ofdm_dot11_g = 6,
- ieee80211_phytype_pbcc_dot11_g = 7,
- ieee80211_phytype_ofdm_dot11_a = 8,
- ieee80211_phytype_dsss_dot11_turbog = 255,
- ieee80211_phytype_dsss_dot11_turbo = 256,
-};
-
-enum ieee80211_ssi_type {
- ieee80211_ssi_none = 0,
- ieee80211_ssi_norm = 1, /* normalized, 0-1000 */
- ieee80211_ssi_dbm = 2,
- ieee80211_ssi_raw = 3, /* raw SSI */
-};
-
-struct ieee80211_radar_info {
- int channel;
- int radar;
- int radar_type;
-};
-
-#endif /* D80211_COMMON_H */
+++ /dev/null
-/*
- * 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.
- *
- * 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
-
-#include <linux/types.h>
-
-struct ieee80211_mgmt {
- __le16 frame_control;
- __le16 duration;
- u8 da[6];
- u8 sa[6];
- u8 bssid[6];
- __le16 seq_ctrl;
- union {
- struct {
- __le16 auth_alg;
- __le16 auth_transaction;
- __le16 status_code;
- /* possibly followed by Challenge text */
- u8 variable[0];
- } __attribute__ ((packed)) auth;
- struct {
- __le16 reason_code;
- } __attribute__ ((packed)) deauth;
- struct {
- __le16 capab_info;
- __le16 listen_interval;
- /* followed by SSID and Supported rates */
- u8 variable[0];
- } __attribute__ ((packed)) assoc_req;
- struct {
- __le16 capab_info;
- __le16 status_code;
- __le16 aid;
- /* followed by Supported rates */
- u8 variable[0];
- } __attribute__ ((packed)) assoc_resp, reassoc_resp;
- struct {
- __le16 capab_info;
- __le16 listen_interval;
- u8 current_ap[6];
- /* followed by SSID and Supported rates */
- u8 variable[0];
- } __attribute__ ((packed)) reassoc_req;
- struct {
- __le16 reason_code;
- } __attribute__ ((packed)) disassoc;
- struct {
- __le64 timestamp;
- __le16 beacon_int;
- __le16 capab_info;
- /* followed by some of SSID, Supported rates,
- * FH Params, DS Params, CF Params, IBSS Params, TIM */
- u8 variable[0];
- } __attribute__ ((packed)) beacon;
- struct {
- /* only variable items: SSID, Supported rates */
- u8 variable[0];
- } __attribute__ ((packed)) probe_req;
- struct {
- __le64 timestamp;
- __le16 beacon_int;
- __le16 capab_info;
- /* followed by some of SSID, Supported rates,
- * FH Params, DS Params, CF Params, IBSS Params */
- u8 variable[0];
- } __attribute__ ((packed)) probe_resp;
- struct {
- u8 category;
- union {
- struct {
- 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;
- } __attribute__((packed)) chan_switch;
- } u;
- } __attribute__ ((packed)) action;
- } u;
-} __attribute__ ((packed));
-
-
-/* Authentication algorithms */
-#define WLAN_AUTH_OPEN 0
-#define WLAN_AUTH_SHARED_KEY 1
-#define WLAN_AUTH_LEAP 128
-
-#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)
-/* 802.11h */
-#define WLAN_CAPABILITY_SPECTRUM_MGMT BIT(8)
-#define WLAN_CAPABILITY_SHORT_SLOT_TIME BIT(10)
-#define WLAN_CAPABILITY_DSSS_OFDM BIT(13)
-
-/* Status codes */
-enum ieee80211_statuscode {
- WLAN_STATUS_SUCCESS = 0,
- WLAN_STATUS_UNSPECIFIED_FAILURE = 1,
- WLAN_STATUS_CAPS_UNSUPPORTED = 10,
- WLAN_STATUS_REASSOC_NO_ASSOC = 11,
- WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12,
- WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13,
- WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14,
- WLAN_STATUS_CHALLENGE_FAIL = 15,
- WLAN_STATUS_AUTH_TIMEOUT = 16,
- WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17,
- WLAN_STATUS_ASSOC_DENIED_RATES = 18,
- /* 802.11b */
- WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19,
- WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20,
- WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21,
- /* 802.11h */
- WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22,
- WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23,
- WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24,
- /* 802.11g */
- WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25,
- WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26,
- /* 802.11i */
- WLAN_STATUS_INVALID_IE = 40,
- WLAN_STATUS_INVALID_GROUP_CIPHER = 41,
- WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42,
- WLAN_STATUS_INVALID_AKMP = 43,
- WLAN_STATUS_UNSUPP_RSN_VERSION = 44,
- WLAN_STATUS_INVALID_RSN_IE_CAP = 45,
- WLAN_STATUS_CIPHER_SUITE_REJECTED = 46,
-};
-
-
-/* Reason codes */
-enum ieee80211_reasoncode {
- WLAN_REASON_UNSPECIFIED = 1,
- WLAN_REASON_PREV_AUTH_NOT_VALID = 2,
- WLAN_REASON_DEAUTH_LEAVING = 3,
- WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4,
- WLAN_REASON_DISASSOC_AP_BUSY = 5,
- WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6,
- WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7,
- WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8,
- WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9,
- /* 802.11h */
- WLAN_REASON_DISASSOC_BAD_POWER = 10,
- WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11,
- /* 802.11i */
- WLAN_REASON_INVALID_IE = 13,
- WLAN_REASON_MIC_FAILURE = 14,
- WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15,
- WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16,
- WLAN_REASON_IE_DIFFERENT = 17,
- WLAN_REASON_INVALID_GROUP_CIPHER = 18,
- WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19,
- WLAN_REASON_INVALID_AKMP = 20,
- WLAN_REASON_UNSUPP_RSN_VERSION = 21,
- WLAN_REASON_INVALID_RSN_IE_CAP = 22,
- WLAN_REASON_IEEE8021X_FAILED = 23,
- WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
-};
-
-
-/* Information Element IDs */
-enum ieee80211_eid {
- WLAN_EID_SSID = 0,
- WLAN_EID_SUPP_RATES = 1,
- WLAN_EID_FH_PARAMS = 2,
- WLAN_EID_DS_PARAMS = 3,
- WLAN_EID_CF_PARAMS = 4,
- WLAN_EID_TIM = 5,
- WLAN_EID_IBSS_PARAMS = 6,
- WLAN_EID_CHALLENGE = 16,
- /* 802.11d */
- WLAN_EID_COUNTRY = 7,
- WLAN_EID_HP_PARAMS = 8,
- WLAN_EID_HP_TABLE = 9,
- WLAN_EID_REQUEST = 10,
- /* 802.11h */
- WLAN_EID_PWR_CONSTRAINT = 32,
- WLAN_EID_PWR_CAPABILITY = 33,
- WLAN_EID_TPC_REQUEST = 34,
- WLAN_EID_TPC_REPORT = 35,
- WLAN_EID_SUPPORTED_CHANNELS = 36,
- WLAN_EID_CHANNEL_SWITCH = 37,
- WLAN_EID_MEASURE_REQUEST = 38,
- WLAN_EID_MEASURE_REPORT = 39,
- WLAN_EID_QUIET = 40,
- WLAN_EID_IBSS_DFS = 41,
- /* 802.11g */
- WLAN_EID_ERP_INFO = 42,
- WLAN_EID_EXT_SUPP_RATES = 50,
- /* 802.11i */
- WLAN_EID_RSN = 48,
- WLAN_EID_WPA = 221,
- WLAN_EID_GENERIC = 221,
- WLAN_EID_VENDOR_SPECIFIC = 221,
- WLAN_EID_QOS_PARAMETER = 222
-};
-
-#endif /* D802_11_MGMT_H */
+++ /dev/null
-/*
- * 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 */
}
-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) {
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)
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);
}
#include <linux/crc32.h>
#include <linux/crypto.h>
#include <linux/err.h>
+#include <linux/mm.h>
#include <asm/scatterlist.h>
#include <net/d80211.h>
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;
}
/* 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);
{
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;
#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"