Merge branch 'fixes-davem' of master.kernel.org:/pub/scm/linux/kernel/git/linville/wireless-2.6

This commit is contained in:
David S. Miller 2007-10-17 21:14:35 -07:00
Родитель c95477090a 107acb23ba
Коммит fe537c0ee8
5 изменённых файлов: 77 добавлений и 48 удалений

Просмотреть файл

@ -22,7 +22,7 @@ config SSB
config SSB_PCIHOST_POSSIBLE config SSB_PCIHOST_POSSIBLE
bool bool
depends on SSB && PCI depends on SSB && (PCI = y || PCI = SSB)
default y default y
config SSB_PCIHOST config SSB_PCIHOST
@ -37,7 +37,7 @@ config SSB_PCIHOST
config SSB_PCMCIAHOST_POSSIBLE config SSB_PCMCIAHOST_POSSIBLE
bool bool
depends on SSB && PCMCIA && EXPERIMENTAL depends on SSB && (PCMCIA = y || PCMCIA = SSB) && EXPERIMENTAL
default y default y
config SSB_PCMCIAHOST config SSB_PCMCIAHOST

Просмотреть файл

@ -173,7 +173,7 @@ u32 ssb_cpu_clock(struct ssb_mipscore *mcore)
void ssb_mipscore_init(struct ssb_mipscore *mcore) void ssb_mipscore_init(struct ssb_mipscore *mcore)
{ {
struct ssb_bus *bus = mcore->dev->bus; struct ssb_bus *bus;
struct ssb_device *dev; struct ssb_device *dev;
unsigned long hz, ns; unsigned long hz, ns;
unsigned int irq, i; unsigned int irq, i;
@ -183,6 +183,7 @@ void ssb_mipscore_init(struct ssb_mipscore *mcore)
ssb_dprintk(KERN_INFO PFX "Initializing MIPS core...\n"); ssb_dprintk(KERN_INFO PFX "Initializing MIPS core...\n");
bus = mcore->dev->bus;
hz = ssb_clockspeed(bus); hz = ssb_clockspeed(bus);
if (!hz) if (!hz)
hz = 100000000; hz = 100000000;

Просмотреть файл

@ -586,7 +586,7 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
if (stype & IEEE80211_STYPE_QOS_DATA) { if (stype & IEEE80211_STYPE_QOS_DATA) {
const struct ieee80211_hdr_3addrqos *qoshdr = const struct ieee80211_hdr_3addrqos *qoshdr =
(struct ieee80211_hdr_3addrqos *)skb->data; (struct ieee80211_hdr_3addrqos *)skb->data;
hdr[12] = qoshdr->qos_ctl & cpu_to_le16(IEEE80211_QCTL_TID); hdr[12] = le16_to_cpu(qoshdr->qos_ctl) & IEEE80211_QCTL_TID;
} else } else
hdr[12] = 0; /* priority */ hdr[12] = 0; /* priority */

Просмотреть файл

@ -306,9 +306,12 @@ int ieee80211_set_channel(struct ieee80211_local *local, int channel, int freq)
((chan->chan == channel) || (chan->freq == freq))) { ((chan->chan == channel) || (chan->freq == freq))) {
local->oper_channel = chan; local->oper_channel = chan;
local->oper_hw_mode = mode; local->oper_hw_mode = mode;
set++; set = 1;
break;
} }
} }
if (set)
break;
} }
if (set) { if (set) {
@ -508,32 +511,40 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
static int ieee80211_ioctl_siwscan(struct net_device *dev, static int ieee80211_ioctl_siwscan(struct net_device *dev,
struct iw_request_info *info, struct iw_request_info *info,
struct iw_point *data, char *extra) union iwreq_data *wrqu, char *extra)
{ {
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct iw_scan_req *req = NULL;
u8 *ssid = NULL; u8 *ssid = NULL;
size_t ssid_len = 0; size_t ssid_len = 0;
if (!netif_running(dev)) if (!netif_running(dev))
return -ENETDOWN; return -ENETDOWN;
switch (sdata->type) { if (wrqu->data.length == sizeof(struct iw_scan_req) &&
case IEEE80211_IF_TYPE_STA: wrqu->data.flags & IW_SCAN_THIS_ESSID) {
case IEEE80211_IF_TYPE_IBSS: req = (struct iw_scan_req *)extra;
if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) { ssid = req->essid;
ssid = sdata->u.sta.ssid; ssid_len = req->essid_len;
ssid_len = sdata->u.sta.ssid_len; } else {
switch (sdata->type) {
case IEEE80211_IF_TYPE_STA:
case IEEE80211_IF_TYPE_IBSS:
if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
ssid = sdata->u.sta.ssid;
ssid_len = sdata->u.sta.ssid_len;
}
break;
case IEEE80211_IF_TYPE_AP:
if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
ssid = sdata->u.ap.ssid;
ssid_len = sdata->u.ap.ssid_len;
}
break;
default:
return -EOPNOTSUPP;
} }
break;
case IEEE80211_IF_TYPE_AP:
if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
ssid = sdata->u.ap.ssid;
ssid_len = sdata->u.ap.ssid_len;
}
break;
default:
return -EOPNOTSUPP;
} }
return ieee80211_sta_req_scan(dev, ssid, ssid_len); return ieee80211_sta_req_scan(dev, ssid, ssid_len);

Просмотреть файл

@ -12,7 +12,6 @@
*/ */
/* TODO: /* TODO:
* BSS table: use <BSSID,SSID> as the key to support multi-SSID APs
* order BSS list by RSSI(?) ("quality of AP") * order BSS list by RSSI(?) ("quality of AP")
* scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE, * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE,
* SSID) * SSID)
@ -61,7 +60,8 @@
static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst,
u8 *ssid, size_t ssid_len); u8 *ssid, size_t ssid_len);
static struct ieee80211_sta_bss * static struct ieee80211_sta_bss *
ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid); ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel,
u8 *ssid, u8 ssid_len);
static void ieee80211_rx_bss_put(struct net_device *dev, static void ieee80211_rx_bss_put(struct net_device *dev,
struct ieee80211_sta_bss *bss); struct ieee80211_sta_bss *bss);
static int ieee80211_sta_find_ibss(struct net_device *dev, static int ieee80211_sta_find_ibss(struct net_device *dev,
@ -427,7 +427,9 @@ static void ieee80211_set_associated(struct net_device *dev,
if (sdata->type != IEEE80211_IF_TYPE_STA) if (sdata->type != IEEE80211_IF_TYPE_STA)
return; return;
bss = ieee80211_rx_bss_get(dev, ifsta->bssid); bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
local->hw.conf.channel,
ifsta->ssid, ifsta->ssid_len);
if (bss) { if (bss) {
if (bss->has_erp_value) if (bss->has_erp_value)
ieee80211_handle_erp_ie(dev, bss->erp_value); ieee80211_handle_erp_ie(dev, bss->erp_value);
@ -574,7 +576,8 @@ static void ieee80211_send_assoc(struct net_device *dev,
capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME | capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME |
WLAN_CAPABILITY_SHORT_PREAMBLE; WLAN_CAPABILITY_SHORT_PREAMBLE;
} }
bss = ieee80211_rx_bss_get(dev, ifsta->bssid); bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel,
ifsta->ssid, ifsta->ssid_len);
if (bss) { if (bss) {
if (bss->capability & WLAN_CAPABILITY_PRIVACY) if (bss->capability & WLAN_CAPABILITY_PRIVACY)
capab |= WLAN_CAPABILITY_PRIVACY; capab |= WLAN_CAPABILITY_PRIVACY;
@ -722,6 +725,7 @@ static void ieee80211_send_disassoc(struct net_device *dev,
static int ieee80211_privacy_mismatch(struct net_device *dev, static int ieee80211_privacy_mismatch(struct net_device *dev,
struct ieee80211_if_sta *ifsta) struct ieee80211_if_sta *ifsta)
{ {
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sta_bss *bss; struct ieee80211_sta_bss *bss;
int res = 0; int res = 0;
@ -729,7 +733,8 @@ static int ieee80211_privacy_mismatch(struct net_device *dev,
ifsta->key_management_enabled) ifsta->key_management_enabled)
return 0; return 0;
bss = ieee80211_rx_bss_get(dev, ifsta->bssid); bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel,
ifsta->ssid, ifsta->ssid_len);
if (!bss) if (!bss)
return 0; return 0;
@ -1203,15 +1208,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
aid = le16_to_cpu(mgmt->u.assoc_resp.aid); aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
"set\n", dev->name, aid);
aid &= ~(BIT(15) | BIT(14));
printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x " printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x "
"status=%d aid=%d)\n", "status=%d aid=%d)\n",
dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa), dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa),
capab_info, status_code, aid); capab_info, status_code, aid & ~(BIT(15) | BIT(14)));
if (status_code != WLAN_STATUS_SUCCESS) { if (status_code != WLAN_STATUS_SUCCESS) {
printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
@ -1223,6 +1224,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
return; return;
} }
if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
"set\n", dev->name, aid);
aid &= ~(BIT(15) | BIT(14));
pos = mgmt->u.assoc_resp.variable; pos = mgmt->u.assoc_resp.variable;
if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems) if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems)
== ParseFailed) { == ParseFailed) {
@ -1241,7 +1247,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
* update our stored copy */ * update our stored copy */
if (elems.erp_info && elems.erp_info_len >= 1) { if (elems.erp_info && elems.erp_info_len >= 1) {
struct ieee80211_sta_bss *bss struct ieee80211_sta_bss *bss
= ieee80211_rx_bss_get(dev, ifsta->bssid); = ieee80211_rx_bss_get(dev, ifsta->bssid,
local->hw.conf.channel,
ifsta->ssid, ifsta->ssid_len);
if (bss) { if (bss) {
bss->erp_value = elems.erp_info[0]; bss->erp_value = elems.erp_info[0];
bss->has_erp_value = 1; bss->has_erp_value = 1;
@ -1271,7 +1279,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
" AP\n", dev->name); " AP\n", dev->name);
return; return;
} }
bss = ieee80211_rx_bss_get(dev, ifsta->bssid); bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
local->hw.conf.channel,
ifsta->ssid, ifsta->ssid_len);
if (bss) { if (bss) {
sta->last_rssi = bss->rssi; sta->last_rssi = bss->rssi;
sta->last_signal = bss->signal; sta->last_signal = bss->signal;
@ -1347,7 +1357,8 @@ static void __ieee80211_rx_bss_hash_del(struct net_device *dev,
static struct ieee80211_sta_bss * static struct ieee80211_sta_bss *
ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid) ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel,
u8 *ssid, u8 ssid_len)
{ {
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sta_bss *bss; struct ieee80211_sta_bss *bss;
@ -1358,6 +1369,11 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid)
atomic_inc(&bss->users); atomic_inc(&bss->users);
atomic_inc(&bss->users); atomic_inc(&bss->users);
memcpy(bss->bssid, bssid, ETH_ALEN); memcpy(bss->bssid, bssid, ETH_ALEN);
bss->channel = channel;
if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) {
memcpy(bss->ssid, ssid, ssid_len);
bss->ssid_len = ssid_len;
}
spin_lock_bh(&local->sta_bss_lock); spin_lock_bh(&local->sta_bss_lock);
/* TODO: order by RSSI? */ /* TODO: order by RSSI? */
@ -1369,7 +1385,8 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid)
static struct ieee80211_sta_bss * static struct ieee80211_sta_bss *
ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid) ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel,
u8 *ssid, u8 ssid_len)
{ {
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sta_bss *bss; struct ieee80211_sta_bss *bss;
@ -1377,7 +1394,10 @@ ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid)
spin_lock_bh(&local->sta_bss_lock); spin_lock_bh(&local->sta_bss_lock);
bss = local->sta_bss_hash[STA_HASH(bssid)]; bss = local->sta_bss_hash[STA_HASH(bssid)];
while (bss) { while (bss) {
if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) { if (!memcmp(bss->bssid, bssid, ETH_ALEN) &&
bss->channel == channel &&
bss->ssid_len == ssid_len &&
(ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) {
atomic_inc(&bss->users); atomic_inc(&bss->users);
break; break;
} }
@ -1545,9 +1565,11 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
else else
channel = rx_status->channel; channel = rx_status->channel;
bss = ieee80211_rx_bss_get(dev, mgmt->bssid); bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel,
elems.ssid, elems.ssid_len);
if (!bss) { if (!bss) {
bss = ieee80211_rx_bss_add(dev, mgmt->bssid); bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel,
elems.ssid, elems.ssid_len);
if (!bss) if (!bss)
return; return;
} else { } else {
@ -1573,10 +1595,6 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
if (elems.ssid && elems.ssid_len <= IEEE80211_MAX_SSID_LEN) {
memcpy(bss->ssid, elems.ssid, elems.ssid_len);
bss->ssid_len = elems.ssid_len;
}
bss->supp_rates_len = 0; bss->supp_rates_len = 0;
if (elems.supp_rates) { if (elems.supp_rates) {
@ -1647,7 +1665,6 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
bss->hw_mode = rx_status->phymode; bss->hw_mode = rx_status->phymode;
bss->channel = channel;
bss->freq = rx_status->freq; bss->freq = rx_status->freq;
if (channel != rx_status->channel && if (channel != rx_status->channel &&
(bss->hw_mode == MODE_IEEE80211G || (bss->hw_mode == MODE_IEEE80211G ||
@ -2375,7 +2392,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
{ {
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sta_bss *bss; struct ieee80211_sta_bss *bss;
struct ieee80211_sub_if_data *sdata; struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_hw_mode *mode; struct ieee80211_hw_mode *mode;
u8 bssid[ETH_ALEN], *pos; u8 bssid[ETH_ALEN], *pos;
int i; int i;
@ -2398,18 +2415,17 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n", printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n",
dev->name, print_mac(mac, bssid)); dev->name, print_mac(mac, bssid));
bss = ieee80211_rx_bss_add(dev, bssid); bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel,
sdata->u.sta.ssid, sdata->u.sta.ssid_len);
if (!bss) if (!bss)
return -ENOMEM; return -ENOMEM;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
mode = local->oper_hw_mode; mode = local->oper_hw_mode;
if (local->hw.conf.beacon_int == 0) if (local->hw.conf.beacon_int == 0)
local->hw.conf.beacon_int = 100; local->hw.conf.beacon_int = 100;
bss->beacon_int = local->hw.conf.beacon_int; bss->beacon_int = local->hw.conf.beacon_int;
bss->hw_mode = local->hw.conf.phymode; bss->hw_mode = local->hw.conf.phymode;
bss->channel = local->hw.conf.channel;
bss->freq = local->hw.conf.freq; bss->freq = local->hw.conf.freq;
bss->last_update = jiffies; bss->last_update = jiffies;
bss->capability = WLAN_CAPABILITY_IBSS; bss->capability = WLAN_CAPABILITY_IBSS;
@ -2469,7 +2485,8 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
"%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid)); "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid));
#endif /* CONFIG_MAC80211_IBSS_DEBUG */ #endif /* CONFIG_MAC80211_IBSS_DEBUG */
if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 &&
(bss = ieee80211_rx_bss_get(dev, bssid))) { (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel,
ifsta->ssid, ifsta->ssid_len))) {
printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" printk(KERN_DEBUG "%s: Selected IBSS BSSID %s"
" based on configured SSID\n", " based on configured SSID\n",
dev->name, print_mac(mac, bssid)); dev->name, print_mac(mac, bssid));