Commit 359f2d17 authored by Jeff Garzik's avatar Jeff Garzik

Merge branch 'upstream' of...

Merge branch 'upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6 into upstream

Conflicts:

	drivers/net/wireless/zd1211rw/zd_mac.h
	net/ieee80211/softmac/ieee80211softmac_assoc.c
parents 0efdf262 720eeb43
...@@ -1100,15 +1100,13 @@ static struct sta_info * ap_add_sta(struct ap_data *ap, u8 *addr) ...@@ -1100,15 +1100,13 @@ static struct sta_info * ap_add_sta(struct ap_data *ap, u8 *addr)
{ {
struct sta_info *sta; struct sta_info *sta;
sta = (struct sta_info *) sta = kzalloc(sizeof(struct sta_info), GFP_ATOMIC);
kmalloc(sizeof(struct sta_info), GFP_ATOMIC);
if (sta == NULL) { if (sta == NULL) {
PDEBUG(DEBUG_AP, "AP: kmalloc failed\n"); PDEBUG(DEBUG_AP, "AP: kmalloc failed\n");
return NULL; return NULL;
} }
/* initialize STA info data */ /* initialize STA info data */
memset(sta, 0, sizeof(struct sta_info));
sta->local = ap->local; sta->local = ap->local;
skb_queue_head_init(&sta->tx_buf); skb_queue_head_init(&sta->tx_buf);
memcpy(sta->addr, addr, ETH_ALEN); memcpy(sta->addr, addr, ETH_ALEN);
......
...@@ -563,12 +563,11 @@ static int prism2_config(struct pcmcia_device *link) ...@@ -563,12 +563,11 @@ static int prism2_config(struct pcmcia_device *link)
PDEBUG(DEBUG_FLOW, "prism2_config()\n"); PDEBUG(DEBUG_FLOW, "prism2_config()\n");
parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL); parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
hw_priv = kmalloc(sizeof(*hw_priv), GFP_KERNEL); hw_priv = kzalloc(sizeof(*hw_priv), GFP_KERNEL);
if (parse == NULL || hw_priv == NULL) { if (parse == NULL || hw_priv == NULL) {
ret = -ENOMEM; ret = -ENOMEM;
goto failed; goto failed;
} }
memset(hw_priv, 0, sizeof(*hw_priv));
tuple.Attributes = 0; tuple.Attributes = 0;
tuple.TupleData = buf; tuple.TupleData = buf;
......
...@@ -685,14 +685,12 @@ static int prism2_download(local_info_t *local, ...@@ -685,14 +685,12 @@ static int prism2_download(local_info_t *local,
goto out; goto out;
} }
dl = kmalloc(sizeof(*dl) + param->num_areas * dl = kzalloc(sizeof(*dl) + param->num_areas *
sizeof(struct prism2_download_data_area), GFP_KERNEL); sizeof(struct prism2_download_data_area), GFP_KERNEL);
if (dl == NULL) { if (dl == NULL) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
memset(dl, 0, sizeof(*dl) + param->num_areas *
sizeof(struct prism2_download_data_area));
dl->dl_cmd = param->dl_cmd; dl->dl_cmd = param->dl_cmd;
dl->start_addr = param->start_addr; dl->start_addr = param->start_addr;
dl->num_areas = param->num_areas; dl->num_areas = param->num_areas;
......
...@@ -347,14 +347,12 @@ static int hfa384x_cmd(struct net_device *dev, u16 cmd, u16 param0, ...@@ -347,14 +347,12 @@ static int hfa384x_cmd(struct net_device *dev, u16 cmd, u16 param0,
if (signal_pending(current)) if (signal_pending(current))
return -EINTR; return -EINTR;
entry = (struct hostap_cmd_queue *) entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
kmalloc(sizeof(*entry), GFP_ATOMIC);
if (entry == NULL) { if (entry == NULL) {
printk(KERN_DEBUG "%s: hfa384x_cmd - kmalloc failed\n", printk(KERN_DEBUG "%s: hfa384x_cmd - kmalloc failed\n",
dev->name); dev->name);
return -ENOMEM; return -ENOMEM;
} }
memset(entry, 0, sizeof(*entry));
atomic_set(&entry->usecnt, 1); atomic_set(&entry->usecnt, 1);
entry->type = CMD_SLEEP; entry->type = CMD_SLEEP;
entry->cmd = cmd; entry->cmd = cmd;
...@@ -517,14 +515,12 @@ static int hfa384x_cmd_callback(struct net_device *dev, u16 cmd, u16 param0, ...@@ -517,14 +515,12 @@ static int hfa384x_cmd_callback(struct net_device *dev, u16 cmd, u16 param0,
return -1; return -1;
} }
entry = (struct hostap_cmd_queue *) entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
kmalloc(sizeof(*entry), GFP_ATOMIC);
if (entry == NULL) { if (entry == NULL) {
printk(KERN_DEBUG "%s: hfa384x_cmd_callback - kmalloc " printk(KERN_DEBUG "%s: hfa384x_cmd_callback - kmalloc "
"failed\n", dev->name); "failed\n", dev->name);
return -ENOMEM; return -ENOMEM;
} }
memset(entry, 0, sizeof(*entry));
atomic_set(&entry->usecnt, 1); atomic_set(&entry->usecnt, 1);
entry->type = CMD_CALLBACK; entry->type = CMD_CALLBACK;
entry->cmd = cmd; entry->cmd = cmd;
...@@ -3016,14 +3012,12 @@ static int prism2_set_tim(struct net_device *dev, int aid, int set) ...@@ -3016,14 +3012,12 @@ static int prism2_set_tim(struct net_device *dev, int aid, int set)
iface = netdev_priv(dev); iface = netdev_priv(dev);
local = iface->local; local = iface->local;
new_entry = (struct set_tim_data *) new_entry = kzalloc(sizeof(*new_entry), GFP_ATOMIC);
kmalloc(sizeof(*new_entry), GFP_ATOMIC);
if (new_entry == NULL) { if (new_entry == NULL) {
printk(KERN_DEBUG "%s: prism2_set_tim: kmalloc failed\n", printk(KERN_DEBUG "%s: prism2_set_tim: kmalloc failed\n",
local->dev->name); local->dev->name);
return -ENOMEM; return -ENOMEM;
} }
memset(new_entry, 0, sizeof(*new_entry));
new_entry->aid = aid; new_entry->aid = aid;
new_entry->set = set; new_entry->set = set;
......
...@@ -327,11 +327,10 @@ static void prism2_info_hostscanresults(local_info_t *local, ...@@ -327,11 +327,10 @@ static void prism2_info_hostscanresults(local_info_t *local,
ptr = (u8 *) pos; ptr = (u8 *) pos;
new_count = left / result_size; new_count = left / result_size;
results = kmalloc(new_count * sizeof(struct hfa384x_hostscan_result), results = kcalloc(new_count, sizeof(struct hfa384x_hostscan_result),
GFP_ATOMIC); GFP_ATOMIC);
if (results == NULL) if (results == NULL)
return; return;
memset(results, 0, new_count * sizeof(struct hfa384x_hostscan_result));
for (i = 0; i < new_count; i++) { for (i = 0; i < new_count; i++) {
memcpy(&results[i], ptr, copy_len); memcpy(&results[i], ptr, copy_len);
......
...@@ -181,12 +181,10 @@ static int prism2_ioctl_siwencode(struct net_device *dev, ...@@ -181,12 +181,10 @@ static int prism2_ioctl_siwencode(struct net_device *dev,
struct ieee80211_crypt_data *new_crypt; struct ieee80211_crypt_data *new_crypt;
/* take WEP into use */ /* take WEP into use */
new_crypt = (struct ieee80211_crypt_data *) new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
kmalloc(sizeof(struct ieee80211_crypt_data),
GFP_KERNEL); GFP_KERNEL);
if (new_crypt == NULL) if (new_crypt == NULL)
return -ENOMEM; return -ENOMEM;
memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
new_crypt->ops = ieee80211_get_crypto_ops("WEP"); new_crypt->ops = ieee80211_get_crypto_ops("WEP");
if (!new_crypt->ops) { if (!new_crypt->ops) {
request_module("ieee80211_crypt_wep"); request_module("ieee80211_crypt_wep");
...@@ -3320,14 +3318,12 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev, ...@@ -3320,14 +3318,12 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
prism2_crypt_delayed_deinit(local, crypt); prism2_crypt_delayed_deinit(local, crypt);
new_crypt = (struct ieee80211_crypt_data *) new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
kmalloc(sizeof(struct ieee80211_crypt_data),
GFP_KERNEL); GFP_KERNEL);
if (new_crypt == NULL) { if (new_crypt == NULL) {
ret = -ENOMEM; ret = -ENOMEM;
goto done; goto done;
} }
memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
new_crypt->ops = ops; new_crypt->ops = ops;
new_crypt->priv = new_crypt->ops->init(i); new_crypt->priv = new_crypt->ops->init(i);
if (new_crypt->priv == NULL) { if (new_crypt->priv == NULL) {
...@@ -3538,14 +3534,12 @@ static int prism2_ioctl_set_encryption(local_info_t *local, ...@@ -3538,14 +3534,12 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
prism2_crypt_delayed_deinit(local, crypt); prism2_crypt_delayed_deinit(local, crypt);
new_crypt = (struct ieee80211_crypt_data *) new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
kmalloc(sizeof(struct ieee80211_crypt_data),
GFP_KERNEL); GFP_KERNEL);
if (new_crypt == NULL) { if (new_crypt == NULL) {
ret = -ENOMEM; ret = -ENOMEM;
goto done; goto done;
} }
memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
new_crypt->ops = ops; new_crypt->ops = ops;
new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx); new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx);
if (new_crypt->priv == NULL) { if (new_crypt->priv == NULL) {
......
...@@ -300,10 +300,9 @@ static int prism2_pci_probe(struct pci_dev *pdev, ...@@ -300,10 +300,9 @@ static int prism2_pci_probe(struct pci_dev *pdev,
struct hostap_interface *iface; struct hostap_interface *iface;
struct hostap_pci_priv *hw_priv; struct hostap_pci_priv *hw_priv;
hw_priv = kmalloc(sizeof(*hw_priv), GFP_KERNEL); hw_priv = kzalloc(sizeof(*hw_priv), GFP_KERNEL);
if (hw_priv == NULL) if (hw_priv == NULL)
return -ENOMEM; return -ENOMEM;
memset(hw_priv, 0, sizeof(*hw_priv));
if (pci_enable_device(pdev)) if (pci_enable_device(pdev))
goto err_out_free; goto err_out_free;
......
...@@ -447,10 +447,9 @@ static int prism2_plx_probe(struct pci_dev *pdev, ...@@ -447,10 +447,9 @@ static int prism2_plx_probe(struct pci_dev *pdev,
int tmd7160; int tmd7160;
struct hostap_plx_priv *hw_priv; struct hostap_plx_priv *hw_priv;
hw_priv = kmalloc(sizeof(*hw_priv), GFP_KERNEL); hw_priv = kzalloc(sizeof(*hw_priv), GFP_KERNEL);
if (hw_priv == NULL) if (hw_priv == NULL)
return -ENOMEM; return -ENOMEM;
memset(hw_priv, 0, sizeof(*hw_priv));
if (pci_enable_device(pdev)) if (pci_enable_device(pdev))
goto err_out_free; goto err_out_free;
......
...@@ -6220,7 +6220,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, ...@@ -6220,7 +6220,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
/* Allocate and initialize the Tx/Rx queues and lists */ /* Allocate and initialize the Tx/Rx queues and lists */
if (ipw2100_queues_allocate(priv)) { if (ipw2100_queues_allocate(priv)) {
printk(KERN_WARNING DRV_NAME printk(KERN_WARNING DRV_NAME
"Error calilng ipw2100_queues_allocate.\n"); "Error calling ipw2100_queues_allocate.\n");
err = -ENOMEM; err = -ENOMEM;
goto fail; goto fail;
} }
......
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
#define VQ #define VQ
#endif #endif
#define IPW2200_VERSION "1.1.4" VK VD VM VP VR VQ #define IPW2200_VERSION "1.2.0" VK VD VM VP VR VQ
#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver" #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"
#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation" #define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation"
#define DRV_VERSION IPW2200_VERSION #define DRV_VERSION IPW2200_VERSION
...@@ -7677,7 +7677,8 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv, ...@@ -7677,7 +7677,8 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
/* Big bitfield of all the fields we provide in radiotap */ /* Big bitfield of all the fields we provide in radiotap */
ipw_rt->rt_hdr.it_present = ipw_rt->rt_hdr.it_present =
((1 << IEEE80211_RADIOTAP_FLAGS) | ((1 << IEEE80211_RADIOTAP_TSFT) |
(1 << IEEE80211_RADIOTAP_FLAGS) |
(1 << IEEE80211_RADIOTAP_RATE) | (1 << IEEE80211_RADIOTAP_RATE) |
(1 << IEEE80211_RADIOTAP_CHANNEL) | (1 << IEEE80211_RADIOTAP_CHANNEL) |
(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
...@@ -7686,10 +7687,14 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv, ...@@ -7686,10 +7687,14 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
/* Zero the flags, we'll add to them as we go */ /* Zero the flags, we'll add to them as we go */
ipw_rt->rt_flags = 0; ipw_rt->rt_flags = 0;
ipw_rt->rt_tsf = 0ULL; ipw_rt->rt_tsf = (u64)(frame->parent_tsf[3] << 24 |
frame->parent_tsf[2] << 16 |
frame->parent_tsf[1] << 8 |
frame->parent_tsf[0]);
/* Convert signal to DBM */ /* Convert signal to DBM */
ipw_rt->rt_dbmsignal = antsignal; ipw_rt->rt_dbmsignal = antsignal;
ipw_rt->rt_dbmnoise = frame->noise;
/* Convert the channel data and set the flags */ /* Convert the channel data and set the flags */
ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(received_channel)); ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(received_channel));
...@@ -7889,7 +7894,8 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv, ...@@ -7889,7 +7894,8 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
/* Big bitfield of all the fields we provide in radiotap */ /* Big bitfield of all the fields we provide in radiotap */
ipw_rt->rt_hdr.it_present = ipw_rt->rt_hdr.it_present =
((1 << IEEE80211_RADIOTAP_FLAGS) | ((1 << IEEE80211_RADIOTAP_TSFT) |
(1 << IEEE80211_RADIOTAP_FLAGS) |
(1 << IEEE80211_RADIOTAP_RATE) | (1 << IEEE80211_RADIOTAP_RATE) |
(1 << IEEE80211_RADIOTAP_CHANNEL) | (1 << IEEE80211_RADIOTAP_CHANNEL) |
(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
...@@ -7898,7 +7904,10 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv, ...@@ -7898,7 +7904,10 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
/* Zero the flags, we'll add to them as we go */ /* Zero the flags, we'll add to them as we go */
ipw_rt->rt_flags = 0; ipw_rt->rt_flags = 0;
ipw_rt->rt_tsf = 0ULL; ipw_rt->rt_tsf = (u64)(frame->parent_tsf[3] << 24 |
frame->parent_tsf[2] << 16 |
frame->parent_tsf[1] << 8 |
frame->parent_tsf[0]);
/* Convert to DBM */ /* Convert to DBM */
ipw_rt->rt_dbmsignal = signal; ipw_rt->rt_dbmsignal = signal;
...@@ -8297,7 +8306,7 @@ static void ipw_rx(struct ipw_priv *priv) ...@@ -8297,7 +8306,7 @@ static void ipw_rx(struct ipw_priv *priv)
("Notification: subtype=%02X flags=%02X size=%d\n", ("Notification: subtype=%02X flags=%02X size=%d\n",
pkt->u.notification.subtype, pkt->u.notification.subtype,
pkt->u.notification.flags, pkt->u.notification.flags,
pkt->u.notification.size); le16_to_cpu(pkt->u.notification.size));
ipw_rx_notification(priv, &pkt->u.notification); ipw_rx_notification(priv, &pkt->u.notification);
break; break;
} }
...@@ -11145,14 +11154,13 @@ static int ipw_up(struct ipw_priv *priv) ...@@ -11145,14 +11154,13 @@ static int ipw_up(struct ipw_priv *priv)
return -EIO; return -EIO;
if (cmdlog && !priv->cmdlog) { if (cmdlog && !priv->cmdlog) {
priv->cmdlog = kmalloc(sizeof(*priv->cmdlog) * cmdlog, priv->cmdlog = kcalloc(cmdlog, sizeof(*priv->cmdlog),
GFP_KERNEL); GFP_KERNEL);
if (priv->cmdlog == NULL) { if (priv->cmdlog == NULL) {
IPW_ERROR("Error allocating %d command log entries.\n", IPW_ERROR("Error allocating %d command log entries.\n",
cmdlog); cmdlog);
return -ENOMEM; return -ENOMEM;
} else { } else {
memset(priv->cmdlog, 0, sizeof(*priv->cmdlog) * cmdlog);
priv->cmdlog_len = cmdlog; priv->cmdlog_len = cmdlog;
} }
} }
......
...@@ -2141,11 +2141,9 @@ prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid, ...@@ -2141,11 +2141,9 @@ prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
struct islpci_bss_wpa_ie, list); struct islpci_bss_wpa_ie, list);
list_del(&bss->list); list_del(&bss->list);
} else { } else {
bss = kmalloc(sizeof (*bss), GFP_ATOMIC); bss = kzalloc(sizeof (*bss), GFP_ATOMIC);
if (bss != NULL) { if (bss != NULL)
priv->num_bss_wpa++; priv->num_bss_wpa++;
memset(bss, 0, sizeof (*bss));
}
} }
if (bss != NULL) { if (bss != NULL) {
memcpy(bss->bssid, bssid, ETH_ALEN); memcpy(bss->bssid, bssid, ETH_ALEN);
...@@ -2686,11 +2684,10 @@ prism2_ioctl_set_generic_element(struct net_device *ndev, ...@@ -2686,11 +2684,10 @@ prism2_ioctl_set_generic_element(struct net_device *ndev,
return -EINVAL; return -EINVAL;
alen = sizeof(*attach) + len; alen = sizeof(*attach) + len;
attach = kmalloc(alen, GFP_KERNEL); attach = kzalloc(alen, GFP_KERNEL);
if (attach == NULL) if (attach == NULL)
return -ENOMEM; return -ENOMEM;
memset(attach, 0, alen);
#define WLAN_FC_TYPE_MGMT 0 #define WLAN_FC_TYPE_MGMT 0
#define WLAN_FC_STYPE_ASSOC_REQ 0 #define WLAN_FC_STYPE_ASSOC_REQ 0
#define WLAN_FC_STYPE_REASSOC_REQ 2 #define WLAN_FC_STYPE_REASSOC_REQ 2
......
...@@ -235,12 +235,10 @@ mgt_init(islpci_private *priv) ...@@ -235,12 +235,10 @@ mgt_init(islpci_private *priv)
{ {
int i; int i;
priv->mib = kmalloc(OID_NUM_LAST * sizeof (void *), GFP_KERNEL); priv->mib = kcalloc(OID_NUM_LAST, sizeof (void *), GFP_KERNEL);
if (!priv->mib) if (!priv->mib)
return -ENOMEM; return -ENOMEM;
memset(priv->mib, 0, OID_NUM_LAST * sizeof (void *));
/* Alloc the cache */ /* Alloc the cache */
for (i = 0; i < OID_NUM_LAST; i++) { for (i = 0; i < OID_NUM_LAST; i++) {
if (isl_oid[i].flags & OID_FLAG_CACHED) { if (isl_oid[i].flags & OID_FLAG_CACHED) {
......
...@@ -1673,3 +1673,16 @@ int zd_rfwritev_cr_locked(struct zd_chip *chip, ...@@ -1673,3 +1673,16 @@ int zd_rfwritev_cr_locked(struct zd_chip *chip,
return 0; return 0;
} }
int zd_chip_set_multicast_hash(struct zd_chip *chip,
struct zd_mc_hash *hash)
{
struct zd_ioreq32 ioreqs[] = {
{ CR_GROUP_HASH_P1, hash->low },
{ CR_GROUP_HASH_P2, hash->high },
};
dev_dbg_f(zd_chip_dev(chip), "hash l 0x%08x h 0x%08x\n",
ioreqs[0].value, ioreqs[1].value);
return zd_iowrite32a(chip, ioreqs, ARRAY_SIZE(ioreqs));
}
...@@ -390,10 +390,19 @@ ...@@ -390,10 +390,19 @@
#define CR_BSSID_P1 CTL_REG(0x0618) #define CR_BSSID_P1 CTL_REG(0x0618)
#define CR_BSSID_P2 CTL_REG(0x061C) #define CR_BSSID_P2 CTL_REG(0x061C)
#define CR_BCN_PLCP_CFG CTL_REG(0x0620) #define CR_BCN_PLCP_CFG CTL_REG(0x0620)
/* Group hash table for filtering incoming packets.
*
* The group hash table is 64 bit large and split over two parts. The first
* part is the lower part. The upper 6 bits of the last byte of the target
* address are used as index. Packets are received if the hash table bit is
* set. This is used for multicast handling, but for broadcasts (address
* ff:ff:ff:ff:ff:ff) the highest bit in the second table must also be set.
*/
#define CR_GROUP_HASH_P1 CTL_REG(0x0624) #define CR_GROUP_HASH_P1 CTL_REG(0x0624)
#define CR_GROUP_HASH_P2 CTL_REG(0x0628) #define CR_GROUP_HASH_P2 CTL_REG(0x0628)
#define CR_RX_TIMEOUT CTL_REG(0x062C)
#define CR_RX_TIMEOUT CTL_REG(0x062C)
/* Basic rates supported by the BSS. When producing ACK or CTS messages, the /* Basic rates supported by the BSS. When producing ACK or CTS messages, the
* device will use a rate in this table that is less than or equal to the rate * device will use a rate in this table that is less than or equal to the rate
* of the incoming frame which prompted the response */ * of the incoming frame which prompted the response */
...@@ -864,4 +873,36 @@ u8 zd_rx_strength_percent(u8 rssi); ...@@ -864,4 +873,36 @@ u8 zd_rx_strength_percent(u8 rssi);
u16 zd_rx_rate(const void *rx_frame, const struct rx_status *status); u16 zd_rx_rate(const void *rx_frame, const struct rx_status *status);
struct zd_mc_hash {
u32 low;
u32 high;
};
static inline void zd_mc_clear(struct zd_mc_hash *hash)
{
hash->low = 0;
/* The interfaces must always received broadcasts.
* The hash of the broadcast address ff:ff:ff:ff:ff:ff is 63.
*/
hash->high = 0x80000000;
}
static inline void zd_mc_add_all(struct zd_mc_hash *hash)
{
hash->low = hash->high = 0xffffffff;
}
static inline void zd_mc_add_addr(struct zd_mc_hash *hash, u8 *addr)
{
unsigned int i = addr[5] >> 2;
if (i < 32) {
hash->low |= 1 << i;
} else {
hash->high |= 1 << (i-32);
}
}
int zd_chip_set_multicast_hash(struct zd_chip *chip,
struct zd_mc_hash *hash);
#endif /* _ZD_CHIP_H */ #endif /* _ZD_CHIP_H */
...@@ -39,6 +39,8 @@ static void housekeeping_init(struct zd_mac *mac); ...@@ -39,6 +39,8 @@ static void housekeeping_init(struct zd_mac *mac);
static void housekeeping_enable(struct zd_mac *mac); static void housekeeping_enable(struct zd_mac *mac);
static void housekeeping_disable(struct zd_mac *mac); static void housekeeping_disable(struct zd_mac *mac);
static void set_multicast_hash_handler(void *mac_ptr);
int zd_mac_init(struct zd_mac *mac, int zd_mac_init(struct zd_mac *mac,
struct net_device *netdev, struct net_device *netdev,
struct usb_interface *intf) struct usb_interface *intf)
...@@ -55,6 +57,8 @@ int zd_mac_init(struct zd_mac *mac, ...@@ -55,6 +57,8 @@ int zd_mac_init(struct zd_mac *mac,
softmac_init(ieee80211_priv(netdev)); softmac_init(ieee80211_priv(netdev));
zd_chip_init(&mac->chip, netdev, intf); zd_chip_init(&mac->chip, netdev, intf);
housekeeping_init(mac); housekeeping_init(mac);
INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler,
mac);
return 0; return 0;
} }
...@@ -136,6 +140,7 @@ int zd_mac_init_hw(struct zd_mac *mac, u8 device_type) ...@@ -136,6 +140,7 @@ int zd_mac_init_hw(struct zd_mac *mac, u8 device_type)
void zd_mac_clear(struct zd_mac *mac) void zd_mac_clear(struct zd_mac *mac)
{ {
flush_workqueue(zd_workqueue);
zd_chip_clear(&mac->chip); zd_chip_clear(&mac->chip);
ZD_ASSERT(!spin_is_locked(&mac->lock)); ZD_ASSERT(!spin_is_locked(&mac->lock));
ZD_MEMCLEAR(mac, sizeof(struct zd_mac)); ZD_MEMCLEAR(mac, sizeof(struct zd_mac));
...@@ -256,6 +261,42 @@ int zd_mac_set_mac_address(struct net_device *netdev, void *p) ...@@ -256,6 +261,42 @@ int zd_mac_set_mac_address(struct net_device *netdev, void *p)
return 0; return 0;
} }
static void set_multicast_hash_handler(void *mac_ptr)
{
struct zd_mac *mac = mac_ptr;
struct zd_mc_hash hash;
spin_lock_irq(&mac->lock);
hash = mac->multicast_hash;
spin_unlock_irq(&mac->lock);
zd_chip_set_multicast_hash(&mac->chip, &hash);
}
void zd_mac_set_multicast_list(struct net_device *dev)
{
struct zd_mc_hash hash;
struct zd_mac *mac = zd_netdev_mac(dev);
struct dev_mc_list *mc;
unsigned long flags;
if (dev->flags & (IFF_PROMISC|IFF_ALLMULTI)) {
zd_mc_add_all(&hash);
} else {
zd_mc_clear(&hash);
for (mc = dev->mc_list; mc; mc = mc->next) {
dev_dbg_f(zd_mac_dev(mac), "mc addr " MAC_FMT "\n",
MAC_ARG(mc->dmi_addr));
zd_mc_add_addr(&hash, mc->dmi_addr);
}
}
spin_lock_irqsave(&mac->lock, flags);
mac->multicast_hash = hash;
spin_unlock_irqrestore(&mac->lock, flags);
queue_work(zd_workqueue, &mac->set_multicast_hash_work);
}
int zd_mac_set_regdomain(struct zd_mac *mac, u8 regdomain) int zd_mac_set_regdomain(struct zd_mac *mac, u8 regdomain)
{ {
int r; int r;
...@@ -618,6 +659,9 @@ int zd_mac_get_range(struct zd_mac *mac, struct iw_range *range) ...@@ -618,6 +659,9 @@ int zd_mac_get_range(struct zd_mac *mac, struct iw_range *range)
range->we_version_compiled = WIRELESS_EXT; range->we_version_compiled = WIRELESS_EXT;
range->we_version_source = 20; range->we_version_source = 20;
range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
ZD_ASSERT(!irqs_disabled()); ZD_ASSERT(!irqs_disabled());
spin_lock_irq(&mac->lock); spin_lock_irq(&mac->lock);
regdomain = mac->regdomain; regdomain = mac->regdomain;
...@@ -930,7 +974,8 @@ static int is_data_packet_for_us(struct ieee80211_device *ieee, ...@@ -930,7 +974,8 @@ static int is_data_packet_for_us(struct ieee80211_device *ieee,
} }
return memcmp(hdr->addr1, netdev->dev_addr, ETH_ALEN) == 0 || return memcmp(hdr->addr1, netdev->dev_addr, ETH_ALEN) == 0 ||
is_multicast_ether_addr(hdr->addr1) || (is_multicast_ether_addr(hdr->addr1) &&
memcmp(hdr->addr3, netdev->dev_addr, ETH_ALEN) != 0) ||
(netdev->flags & IFF_PROMISC); (netdev->flags & IFF_PROMISC);
} }
...@@ -1062,10 +1107,8 @@ int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length) ...@@ -1062,10 +1107,8 @@ int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length)
memcpy(skb_put(skb, length), buffer, length); memcpy(skb_put(skb, length), buffer, length);
r = ieee80211_rx(ieee, skb, &stats); r = ieee80211_rx(ieee, skb, &stats);
if (!r) { if (!r)
ZD_ASSERT(in_irq()); dev_kfree_skb_any(skb);
dev_kfree_skb_irq(skb);
}
return 0; return 0;
} }
......
...@@ -133,6 +133,8 @@ struct zd_mac { ...@@ -133,6 +133,8 @@ struct zd_mac {
struct iw_statistics iw_stats; struct iw_statistics iw_stats;
struct housekeeping housekeeping; struct housekeeping housekeeping;
struct work_struct set_multicast_hash_work;
struct zd_mc_hash multicast_hash;
struct delayed_work set_rts_cts_work; struct delayed_work set_rts_cts_work;
struct delayed_work set_basic_rates_work; struct delayed_work set_basic_rates_work;
...@@ -189,6 +191,7 @@ int zd_mac_init_hw(struct zd_mac *mac, u8 device_type); ...@@ -189,6 +191,7 @@ int zd_mac_init_hw(struct zd_mac *mac, u8 device_type);
int zd_mac_open(struct net_device *netdev); int zd_mac_open(struct net_device *netdev);
int zd_mac_stop(struct net_device *netdev); int zd_mac_stop(struct net_device *netdev);
int zd_mac_set_mac_address(struct net_device *dev, void *p); int zd_mac_set_mac_address(struct net_device *dev, void *p);
void zd_mac_set_multicast_list(struct net_device *netdev);
int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length); int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length);
......
...@@ -242,7 +242,7 @@ struct net_device *zd_netdev_alloc(struct usb_interface *intf) ...@@ -242,7 +242,7 @@ struct net_device *zd_netdev_alloc(struct usb_interface *intf)
netdev->open = zd_mac_open; netdev->open = zd_mac_open;
netdev->stop = zd_mac_stop; netdev->stop = zd_mac_stop;
/* netdev->get_stats = */ /* netdev->get_stats = */
/* netdev->set_multicast_list = */ netdev->set_multicast_list = zd_mac_set_multicast_list;
netdev->set_mac_address = zd_mac_set_mac_address; netdev->set_mac_address = zd_mac_set_mac_address;
netdev->wireless_handlers = &iw_handler_def; netdev->wireless_handlers = &iw_handler_def;
/* netdev->ethtool_ops = */ /* netdev->ethtool_ops = */
......
...@@ -431,6 +431,17 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev, ...@@ -431,6 +431,17 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev,
return 0; return 0;
} }
void
ieee80211softmac_try_reassoc(struct ieee80211softmac_device *mac)
{
unsigned long flags;
spin_lock_irqsave(&mac->lock, flags);
mac->associnfo.associating = 1;
schedule_work(&mac->associnfo.work);
spin_unlock_irqrestore(&mac->lock, flags);
}
int int
ieee80211softmac_handle_disassoc(struct net_device * dev, ieee80211softmac_handle_disassoc(struct net_device * dev,
struct ieee80211_disassoc *disassoc) struct ieee80211_disassoc *disassoc)
...@@ -449,8 +460,7 @@ ieee80211softmac_handle_disassoc(struct net_device * dev, ...@@ -449,8 +460,7 @@ ieee80211softmac_handle_disassoc(struct net_device * dev,
dprintk(KERN_INFO PFX "got disassoc frame\n"); dprintk(KERN_INFO PFX "got disassoc frame\n");
ieee80211softmac_disassoc(mac); ieee80211softmac_disassoc(mac);
/* try to reassociate */ ieee80211softmac_try_reassoc(mac);
schedule_delayed_work(&mac->associnfo.work, 0);
return 0; return 0;
} }
......
...@@ -337,6 +337,8 @@ ieee80211softmac_deauth_from_net(struct ieee80211softmac_device *mac, ...@@ -337,6 +337,8 @@ ieee80211softmac_deauth_from_net(struct ieee80211softmac_device *mac,
/* can't transmit data right now... */ /* can't transmit data right now... */
netif_carrier_off(mac->dev); netif_carrier_off(mac->dev);
spin_unlock_irqrestore(&mac->lock, flags); spin_unlock_irqrestore(&mac->lock, flags);
ieee80211softmac_try_reassoc(mac);
} }
/* /*
......
...@@ -239,4 +239,6 @@ void ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, in ...@@ -239,4 +239,6 @@ void ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, in
int ieee80211softmac_notify_internal(struct ieee80211softmac_device *mac, int ieee80211softmac_notify_internal(struct ieee80211softmac_device *mac,
int event, void *event_context, notify_function_ptr fun, void *context, gfp_t gfp_mask); int event, void *event_context, notify_function_ptr fun, void *context, gfp_t gfp_mask);
void ieee80211softmac_try_reassoc(struct ieee80211softmac_device *mac);
#endif /* IEEE80211SOFTMAC_PRIV_H_ */ #endif /* IEEE80211SOFTMAC_PRIV_H_ */
...@@ -495,7 +495,8 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev, ...@@ -495,7 +495,8 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev,
printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n"); printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n");
goto out; goto out;
} }
return ieee80211softmac_deauth_req(mac, net, reason); err = ieee80211softmac_deauth_req(mac, net, reason);
goto out;
case IW_MLME_DISASSOC: case IW_MLME_DISASSOC:
ieee80211softmac_send_disassoc_req(mac, reason); ieee80211softmac_send_disassoc_req(mac, reason);
mac->associnfo.associated = 0; mac->associnfo.associated = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment