aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/prism54
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/prism54')
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.c20
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.h20
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c1232
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.h16
-rw-r--r--drivers/net/wireless/prism54/isl_oid.h69
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c136
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.h35
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c120
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.h50
-rw-r--r--drivers/net/wireless/prism54/islpci_hotplug.c77
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.c44
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.h17
-rw-r--r--drivers/net/wireless/prism54/oid_mgt.c36
-rw-r--r--drivers/net/wireless/prism54/oid_mgt.h3
-rw-r--r--drivers/net/wireless/prism54/prismcompat.h8
15 files changed, 1014 insertions, 869 deletions
diff --git a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c
index 23deee69974..333c1a2f882 100644
--- a/drivers/net/wireless/prism54/isl_38xx.c
+++ b/drivers/net/wireless/prism54/isl_38xx.c
@@ -1,5 +1,4 @@
/*
- *
* Copyright (C) 2002 Intersil Americas Inc.
* Copyright (C) 2003-2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>_
*
@@ -13,8 +12,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
@@ -38,7 +36,7 @@
* isl38xx_disable_interrupts - disable all interrupts
* @device: pci memory base address
*
- * Instructs the device to disable all interrupt reporting by asserting
+ * Instructs the device to disable all interrupt reporting by asserting
* the IRQ line. New events may still show up in the interrupt identification
* register located at offset %ISL38XX_INT_IDENT_REG.
*/
@@ -204,17 +202,19 @@ isl38xx_interface_reset(void __iomem *device_base, dma_addr_t host_address)
/* enable the interrupt for detecting initialization */
/* Note: Do not enable other interrupts here. We want the
- * device to have come up first 100% before allowing any other
+ * device to have come up first 100% before allowing any other
* interrupts. */
isl38xx_w32_flush(device_base, ISL38XX_INT_IDENT_INIT, ISL38XX_INT_EN_REG);
udelay(ISL38XX_WRITEIO_DELAY); /* allow complete full reset */
}
void
-isl38xx_enable_common_interrupts(void __iomem *device_base) {
+isl38xx_enable_common_interrupts(void __iomem *device_base)
+{
u32 reg;
- reg = ( ISL38XX_INT_IDENT_UPDATE |
- ISL38XX_INT_IDENT_SLEEP | ISL38XX_INT_IDENT_WAKEUP);
+
+ reg = ISL38XX_INT_IDENT_UPDATE | ISL38XX_INT_IDENT_SLEEP |
+ ISL38XX_INT_IDENT_WAKEUP;
isl38xx_w32_flush(device_base, reg, ISL38XX_INT_EN_REG);
udelay(ISL38XX_WRITEIO_DELAY);
}
@@ -234,23 +234,21 @@ isl38xx_in_queue(isl38xx_control_block *cb, int queue)
/* send queues */
case ISL38XX_CB_TX_MGMTQ:
BUG_ON(delta > ISL38XX_CB_MGMT_QSIZE);
+
case ISL38XX_CB_TX_DATA_LQ:
case ISL38XX_CB_TX_DATA_HQ:
BUG_ON(delta > ISL38XX_CB_TX_QSIZE);
return delta;
- break;
/* receive queues */
case ISL38XX_CB_RX_MGMTQ:
BUG_ON(delta > ISL38XX_CB_MGMT_QSIZE);
return ISL38XX_CB_MGMT_QSIZE - delta;
- break;
case ISL38XX_CB_RX_DATA_LQ:
case ISL38XX_CB_RX_DATA_HQ:
BUG_ON(delta > ISL38XX_CB_RX_QSIZE);
return ISL38XX_CB_RX_QSIZE - delta;
- break;
}
BUG();
return 0;
diff --git a/drivers/net/wireless/prism54/isl_38xx.h b/drivers/net/wireless/prism54/isl_38xx.h
index 8af20980af8..547ab885610 100644
--- a/drivers/net/wireless/prism54/isl_38xx.h
+++ b/drivers/net/wireless/prism54/isl_38xx.h
@@ -1,5 +1,4 @@
/*
- *
* Copyright (C) 2002 Intersil Americas Inc.
*
* This program is free software; you can redistribute it and/or modify
@@ -12,8 +11,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
@@ -67,10 +65,10 @@
* @base: (host) memory base address of the device
* @val: 32bit value (host order) to write
* @offset: byte offset into @base to write value to
- *
+ *
* This helper takes care of writing a 32bit datum to the
- * specified offset into the device's pci memory space, and making sure
- * the pci memory buffers get flushed by performing one harmless read
+ * specified offset into the device's pci memory space, and making sure
+ * the pci memory buffers get flushed by performing one harmless read
* from the %ISL38XX_PCI_POSTING_FLUSH offset.
*/
static inline void
@@ -139,14 +137,14 @@ isl38xx_w32_flush(void __iomem *base, u32 val, unsigned long offset)
#define MAX_FRAGMENT_SIZE_RX 1600
typedef struct {
- u32 address; /* physical address on host */
- u16 size; /* packet size */
- u16 flags; /* set of bit-wise flags */
+ __le32 address; /* physical address on host */
+ __le16 size; /* packet size */
+ __le16 flags; /* set of bit-wise flags */
} isl38xx_fragment;
struct isl38xx_cb {
- u32 driver_curr_frag[ISL38XX_CB_QCOUNT];
- u32 device_curr_frag[ISL38XX_CB_QCOUNT];
+ __le32 driver_curr_frag[ISL38XX_CB_QCOUNT];
+ __le32 device_curr_frag[ISL38XX_CB_QCOUNT];
isl38xx_fragment rx_data_low[ISL38XX_CB_RX_QSIZE];
isl38xx_fragment tx_data_low[ISL38XX_CB_TX_QSIZE];
isl38xx_fragment rx_data_high[ISL38XX_CB_RX_QSIZE];
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 135a156db25..ecbb0546cf3 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -1,5 +1,4 @@
/*
- *
* Copyright (C) 2002 Intersil Americas Inc.
* (C) 2003,2004 Aurelien Alleaume <slts@free.fr>
* (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
@@ -15,15 +14,17 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
+#include <linux/capability.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/if_arp.h>
+#include <linux/slab.h>
#include <linux/pci.h>
+#include <linux/etherdevice.h>
#include <asm/uaccess.h>
@@ -35,24 +36,32 @@
#include <net/iw_handler.h> /* New driver API */
+#define KEY_SIZE_WEP104 13 /* 104/128-bit WEP keys */
+#define KEY_SIZE_WEP40 5 /* 40/64-bit WEP keys */
+/* KEY_SIZE_TKIP should match isl_oid.h, struct obj_key.key[] size */
+#define KEY_SIZE_TKIP 32 /* TKIP keys */
-static void prism54_wpa_ie_add(islpci_private *priv, u8 *bssid,
+static void prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
u8 *wpa_ie, size_t wpa_ie_len);
-static size_t prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie);
+static size_t prism54_wpa_bss_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie);
static int prism54_set_wpa(struct net_device *, struct iw_request_info *,
__u32 *, char *);
+/* In 500 kbps */
+static const unsigned char scan_rate_list[] = { 2, 4, 11, 22,
+ 12, 18, 24, 36,
+ 48, 72, 96, 108 };
/**
* prism54_mib_mode_helper - MIB change mode helper function
* @mib: the &struct islpci_mib object to modify
* @iw_mode: new mode (%IW_MODE_*)
- *
+ *
* This is a helper function, hence it does not lock. Make sure
- * caller deals with locking *if* necessary. This function sets the
- * mode-dependent mib values and does the mapping of the Linux
- * Wireless API modes to Device firmware modes. It also checks for
- * correct valid Linux wireless modes.
+ * caller deals with locking *if* necessary. This function sets the
+ * mode-dependent mib values and does the mapping of the Linux
+ * Wireless API modes to Device firmware modes. It also checks for
+ * correct valid Linux wireless modes.
*/
static int
prism54_mib_mode_helper(islpci_private *priv, u32 iw_mode)
@@ -64,7 +73,7 @@ prism54_mib_mode_helper(islpci_private *priv, u32 iw_mode)
if (iw_mode == IW_MODE_REPEAT || iw_mode == IW_MODE_SECOND) {
printk(KERN_DEBUG
"%s(): Sorry, Repeater mode and Secondary mode "
- "are not yet supported by this driver.\n", __FUNCTION__);
+ "are not yet supported by this driver.\n", __func__);
return -EINVAL;
}
@@ -110,7 +119,7 @@ prism54_mib_mode_helper(islpci_private *priv, u32 iw_mode)
*
* this function initializes the struct given as @mib with defaults,
* of which many are retrieved from the global module parameter
- * variables.
+ * variables.
*/
void
@@ -126,7 +135,7 @@ prism54_mib_init(islpci_private *priv)
authen = CARD_DEFAULT_AUTHEN;
wep = CARD_DEFAULT_WEP;
filter = CARD_DEFAULT_FILTER; /* (0) Do not filter un-encrypted data */
- dot1x = CARD_DEFAULT_DOT1X;
+ dot1x = CARD_DEFAULT_DOT1X;
mlme = CARD_DEFAULT_MLME_MODE;
conformance = CARD_DEFAULT_CONFORMANCE;
power = 127;
@@ -150,15 +159,15 @@ prism54_mib_init(islpci_private *priv)
* schedule_work(), thus we can as well use sleeping semaphore
* locking */
void
-prism54_update_stats(islpci_private *priv)
+prism54_update_stats(struct work_struct *work)
{
+ islpci_private *priv = container_of(work, islpci_private, stats_work);
char *data;
int j;
struct obj_bss bss, *bss2;
union oid_res_t r;
- if (down_interruptible(&priv->stats_sem))
- return;
+ mutex_lock(&priv->stats_lock);
/* Noise floor.
* I'm not sure if the unit is dBm.
@@ -174,7 +183,7 @@ prism54_update_stats(islpci_private *priv)
data = r.ptr;
/* copy this MAC to the bss */
- memcpy(bss.address, data, 6);
+ memcpy(bss.address, data, ETH_ALEN);
kfree(data);
/* now ask for the corresponding bss */
@@ -200,9 +209,7 @@ prism54_update_stats(islpci_private *priv)
mgt_get_request(priv, DOT11_OID_MPDUTXFAILED, 0, NULL, &r);
priv->local_iwstatistics.discard.retries = r.u;
- up(&priv->stats_sem);
-
- return;
+ mutex_unlock(&priv->stats_lock);
}
struct iw_statistics *
@@ -211,16 +218,16 @@ prism54_get_wireless_stats(struct net_device *ndev)
islpci_private *priv = netdev_priv(ndev);
/* If the stats are being updated return old data */
- if (down_trylock(&priv->stats_sem) == 0) {
+ if (mutex_trylock(&priv->stats_lock)) {
memcpy(&priv->iwstatistics, &priv->local_iwstatistics,
sizeof (struct iw_statistics));
/* They won't be marked updated for the next time */
priv->local_iwstatistics.qual.updated = 0;
- up(&priv->stats_sem);
+ mutex_unlock(&priv->stats_lock);
} else
priv->iwstatistics.qual.updated = 0;
- /* Update our wireless stats, but do not schedule to often
+ /* Update our wireless stats, but do not schedule to often
* (max 1 HZ) */
if ((priv->stats_timestamp == 0) ||
time_after(jiffies, priv->stats_timestamp + 1 * HZ)) {
@@ -326,7 +333,7 @@ prism54_set_mode(struct net_device *ndev, struct iw_request_info *info,
if (*uwrq > IW_MODE_MONITOR || *uwrq < IW_MODE_AUTO) {
printk(KERN_DEBUG
"%s: %s() You passed a non-valid init_mode.\n",
- priv->ndev->name, __FUNCTION__);
+ priv->ndev->name, __func__);
return -EINVAL;
}
@@ -468,6 +475,9 @@ prism54_get_range(struct net_device *ndev, struct iw_request_info *info,
range->event_capa[1] = IW_EVENT_CAPA_K_1;
range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVCUSTOM);
+ range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
+ IW_ENC_CAPA_CIPHER_TKIP;
+
if (islpci_get_state(priv) < PRV_STATE_INIT)
return 0;
@@ -521,7 +531,7 @@ prism54_set_wap(struct net_device *ndev, struct iw_request_info *info,
return -EINVAL;
/* prepare the structure for the set object */
- memcpy(&bssid[0], awrq->sa_data, 6);
+ memcpy(&bssid[0], awrq->sa_data, ETH_ALEN);
/* set the bssid -- does this make sense when in AP mode? */
rvalue = mgt_set_request(priv, DOT11_OID_BSSID, 0, &bssid);
@@ -540,7 +550,7 @@ prism54_get_wap(struct net_device *ndev, struct iw_request_info *info,
int rvalue;
rvalue = mgt_get_request(priv, DOT11_OID_BSSID, 0, NULL, &r);
- memcpy(awrq->sa_data, r.ptr, 6);
+ memcpy(awrq->sa_data, r.ptr, ETH_ALEN);
awrq->sa_family = ARPHRD_ETHER;
kfree(r.ptr);
@@ -561,19 +571,22 @@ prism54_set_scan(struct net_device *dev, struct iw_request_info *info,
*/
static char *
-prism54_translate_bss(struct net_device *ndev, char *current_ev,
- char *end_buf, struct obj_bss *bss, char noise)
+prism54_translate_bss(struct net_device *ndev, struct iw_request_info *info,
+ char *current_ev, char *end_buf, struct obj_bss *bss,
+ char noise)
{
struct iw_event iwe; /* Temporary buffer */
short cap;
islpci_private *priv = netdev_priv(ndev);
+ u8 wpa_ie[MAX_WPA_IE_LEN];
+ size_t wpa_ie_len;
/* The first entry must be the MAC address */
- memcpy(iwe.u.ap_addr.sa_data, bss->address, 6);
+ memcpy(iwe.u.ap_addr.sa_data, bss->address, ETH_ALEN);
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
iwe.cmd = SIOCGIWAP;
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
/* The following entries will be displayed in the same order we give them */
@@ -581,7 +594,7 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
iwe.u.data.length = bss->ssid.length;
iwe.u.data.flags = 1;
iwe.cmd = SIOCGIWESSID;
- current_ev = iwe_stream_add_point(current_ev, end_buf,
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
&iwe, bss->ssid.octets);
/* Capabilities */
@@ -598,9 +611,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
iwe.u.mode = IW_MODE_ADHOC;
iwe.cmd = SIOCGIWMODE;
if (iwe.u.mode)
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
/* Encryption capability */
if (cap & CAP_CRYPT)
@@ -609,14 +621,15 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
iwe.cmd = SIOCGIWENCODE;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, NULL);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, NULL);
/* Add frequency. (short) bss->channel is the frequency in MHz */
iwe.u.freq.m = bss->channel;
iwe.u.freq.e = 6;
iwe.cmd = SIOCGIWFREQ;
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */
iwe.u.qual.level = bss->rssi;
@@ -624,31 +637,43 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
/* do a simple SNR for quality */
iwe.u.qual.qual = bss->rssi - noise;
iwe.cmd = IWEVQUAL;
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
-
- if (priv->wpa) {
- u8 wpa_ie[MAX_WPA_IE_LEN];
- char *buf, *p;
- size_t wpa_ie_len;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
+
+ /* Add WPA/RSN Information Element, if any */
+ wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie);
+ if (wpa_ie_len > 0) {
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = min_t(size_t, wpa_ie_len, MAX_WPA_IE_LEN);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, wpa_ie);
+ }
+ /* Do the bitrates */
+ {
+ char *current_val = current_ev + iwe_stream_lcp_len(info);
int i;
-
- wpa_ie_len = prism54_wpa_ie_get(priv, bss->address, wpa_ie);
- if (wpa_ie_len > 0 &&
- (buf = kmalloc(wpa_ie_len * 2 + 10, GFP_ATOMIC))) {
- p = buf;
- p += sprintf(p, "wpa_ie=");
- for (i = 0; i < wpa_ie_len; i++) {
- p += sprintf(p, "%02x", wpa_ie[i]);
+ int mask;
+
+ iwe.cmd = SIOCGIWRATE;
+ /* Those two flags are ignored... */
+ iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+
+ /* Parse the bitmask */
+ mask = 0x1;
+ for(i = 0; i < sizeof(scan_rate_list); i++) {
+ if(bss->rates & mask) {
+ iwe.u.bitrate.value = (scan_rate_list[i] * 500000);
+ current_val = iwe_stream_add_value(
+ info, current_ev, current_val,
+ end_buf, &iwe, IW_EV_PARAM_LEN);
}
- memset(&iwe, 0, sizeof (iwe));
- iwe.cmd = IWEVCUSTOM;
- iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, buf);
- kfree(buf);
+ mask <<= 1;
}
+ /* Check if we added any event */
+ if ((current_val - current_ev) > iwe_stream_lcp_len(info))
+ current_ev = current_val;
}
+
return current_ev;
}
@@ -680,13 +705,13 @@ prism54_get_scan(struct net_device *ndev, struct iw_request_info *info,
* Starting with WE-17, the buffer can be as big as needed.
* But the device won't repport anything if you change the value
* of IWMAX_BSS=24. */
-
+
rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);
bsslist = r.ptr;
/* ok now, scan the list and translate its info */
for (i = 0; i < (int) bsslist->nr; i++) {
- current_ev = prism54_translate_bss(ndev, current_ev,
+ current_ev = prism54_translate_bss(ndev, info, current_ev,
extra + dwrq->length,
&(bsslist->bsslist[i]),
noise);
@@ -717,9 +742,9 @@ prism54_set_essid(struct net_device *ndev, struct iw_request_info *info,
/* Check if we were asked for `any' */
if (dwrq->flags && dwrq->length) {
- if (dwrq->length > min(33, IW_ESSID_MAX_SIZE + 1))
+ if (dwrq->length > 32)
return -E2BIG;
- essid.length = dwrq->length - 1;
+ essid.length = dwrq->length;
memcpy(essid.octets, extra, dwrq->length);
} else
essid.length = 0;
@@ -747,20 +772,20 @@ prism54_get_essid(struct net_device *ndev, struct iw_request_info *info,
if (essid->length) {
dwrq->flags = 1; /* set ESSID to ON for Wireless Extensions */
- /* if it is to big, trunk it */
- dwrq->length = min(IW_ESSID_MAX_SIZE, essid->length + 1);
+ /* if it is too big, trunk it */
+ dwrq->length = min((u8)IW_ESSID_MAX_SIZE, essid->length);
} else {
dwrq->flags = 0;
dwrq->length = 0;
}
- essid->octets[essid->length] = '\0';
+ essid->octets[dwrq->length] = '\0';
memcpy(extra, essid->octets, dwrq->length);
kfree(essid);
return rvalue;
}
-/* Provides no functionality, just completes the ioctl. In essence this is a
+/* Provides no functionality, just completes the ioctl. In essence this is a
* just a cosmetic ioctl.
*/
static int
@@ -789,7 +814,7 @@ prism54_get_nick(struct net_device *ndev, struct iw_request_info *info,
dwrq->length = 0;
down_read(&priv->mib_sem);
- dwrq->length = strlen(priv->nickname) + 1;
+ dwrq->length = strlen(priv->nickname);
memcpy(extra, priv->nickname, dwrq->length);
up_read(&priv->mib_sem);
@@ -967,9 +992,9 @@ prism54_set_retry(struct net_device *ndev, struct iw_request_info *info,
return -EINVAL;
if (vwrq->flags & IW_RETRY_LIMIT) {
- if (vwrq->flags & IW_RETRY_MIN)
+ if (vwrq->flags & IW_RETRY_SHORT)
slimit = vwrq->value;
- else if (vwrq->flags & IW_RETRY_MAX)
+ else if (vwrq->flags & IW_RETRY_LONG)
llimit = vwrq->value;
else {
/* we are asked to set both */
@@ -1010,18 +1035,18 @@ prism54_get_retry(struct net_device *ndev, struct iw_request_info *info,
mgt_get_request(priv, DOT11_OID_MAXTXLIFETIME, 0, NULL, &r);
vwrq->value = r.u * 1024;
vwrq->flags = IW_RETRY_LIFETIME;
- } else if ((vwrq->flags & IW_RETRY_MAX)) {
+ } else if ((vwrq->flags & IW_RETRY_LONG)) {
/* we are asked for the long retry limit */
rvalue |=
mgt_get_request(priv, DOT11_OID_LONGRETRIES, 0, NULL, &r);
vwrq->value = r.u;
- vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+ vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
} else {
/* default. get the short retry limit */
rvalue |=
mgt_get_request(priv, DOT11_OID_SHORTRETRIES, 0, NULL, &r);
vwrq->value = r.u;
- vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
+ vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
}
return rvalue;
@@ -1051,12 +1076,24 @@ prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
current_index = r.u;
/* Verify that the key is not marked as invalid */
if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
- key.length = dwrq->length > sizeof (key.key) ?
- sizeof (key.key) : dwrq->length;
- memcpy(key.key, extra, key.length);
- if (key.length == 32)
- /* we want WPA-PSK */
+ if (dwrq->length > KEY_SIZE_TKIP) {
+ /* User-provided key data too big */
+ return -EINVAL;
+ }
+ if (dwrq->length > KEY_SIZE_WEP104) {
+ /* WPA-PSK TKIP */
key.type = DOT11_PRIV_TKIP;
+ key.length = KEY_SIZE_TKIP;
+ } else if (dwrq->length > KEY_SIZE_WEP40) {
+ /* WEP 104/128 */
+ key.length = KEY_SIZE_WEP104;
+ } else {
+ /* WEP 40/64 */
+ key.length = KEY_SIZE_WEP40;
+ }
+ memset(key.key, 0, sizeof (key.key));
+ memcpy(key.key, extra, dwrq->length);
+
if ((index < 0) || (index > 3))
/* no index provided use the current one */
index = current_index;
@@ -1067,7 +1104,7 @@ prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
&key);
}
/*
- * If a valid key is set, encryption should be enabled
+ * If a valid key is set, encryption should be enabled
* (user may turn it off later).
* This is also how "iwconfig ethX key on" works
*/
@@ -1081,7 +1118,7 @@ prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
&index);
} else {
- if (!dwrq->flags & IW_ENCODE_MODE) {
+ if (!(dwrq->flags & IW_ENCODE_MODE)) {
/* we cannot do anything. Complain. */
return -EINVAL;
}
@@ -1089,7 +1126,7 @@ prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
}
/* now read the flags */
if (dwrq->flags & IW_ENCODE_DISABLED) {
- /* Encoding disabled,
+ /* Encoding disabled,
* authen = DOT11_AUTH_OS;
* invoke = 0;
* exunencrypt = 0; */
@@ -1150,7 +1187,7 @@ prism54_get_encode(struct net_device *ndev, struct iw_request_info *info,
rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
devindex = r.u;
/* Now get the key, return it */
- if ((index < 0) || (index > 3))
+ if (index == -1 || index > 3)
/* no index provided, use the current one */
index = devindex;
rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
@@ -1177,7 +1214,7 @@ prism54_get_txpower(struct net_device *ndev, struct iw_request_info *info,
vwrq->value = (s32) r.u / 4;
vwrq->fixed = 1;
/* radio is not turned of
- * btw: how is possible to turn off only the radio
+ * btw: how is possible to turn off only the radio
*/
vwrq->disabled = 0;
@@ -1197,7 +1234,7 @@ prism54_set_txpower(struct net_device *ndev, struct iw_request_info *info,
/* don't know how to disable radio */
printk(KERN_DEBUG
"%s: %s() disabling radio is not yet supported.\n",
- priv->ndev->name, __FUNCTION__);
+ priv->ndev->name, __func__);
return -ENOTSUPP;
} else if (vwrq->fixed)
/* currently only fixed value is supported */
@@ -1205,11 +1242,501 @@ prism54_set_txpower(struct net_device *ndev, struct iw_request_info *info,
else {
printk(KERN_DEBUG
"%s: %s() auto power will be implemented later.\n",
- priv->ndev->name, __FUNCTION__);
+ priv->ndev->name, __func__);
return -ENOTSUPP;
}
}
+static int prism54_set_genie(struct net_device *ndev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ islpci_private *priv = netdev_priv(ndev);
+ int alen, ret = 0;
+ struct obj_attachment *attach;
+
+ if (data->length > MAX_WPA_IE_LEN ||
+ (data->length && extra == NULL))
+ return -EINVAL;
+
+ memcpy(priv->wpa_ie, extra, data->length);
+ priv->wpa_ie_len = data->length;
+
+ alen = sizeof(*attach) + priv->wpa_ie_len;
+ attach = kzalloc(alen, GFP_KERNEL);
+ if (attach == NULL)
+ return -ENOMEM;
+
+#define WLAN_FC_TYPE_MGMT 0
+#define WLAN_FC_STYPE_ASSOC_REQ 0
+#define WLAN_FC_STYPE_REASSOC_REQ 2
+
+ /* Note: endianness is covered by mgt_set_varlen */
+ attach->type = (WLAN_FC_TYPE_MGMT << 2) |
+ (WLAN_FC_STYPE_ASSOC_REQ << 4);
+ attach->id = -1;
+ attach->size = priv->wpa_ie_len;
+ memcpy(attach->data, extra, priv->wpa_ie_len);
+
+ ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach,
+ priv->wpa_ie_len);
+ if (ret == 0) {
+ attach->type = (WLAN_FC_TYPE_MGMT << 2) |
+ (WLAN_FC_STYPE_REASSOC_REQ << 4);
+
+ ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach,
+ priv->wpa_ie_len);
+ if (ret == 0)
+ printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
+ ndev->name);
+ }
+
+ kfree(attach);
+ return ret;
+}
+
+
+static int prism54_get_genie(struct net_device *ndev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ islpci_private *priv = netdev_priv(ndev);
+ int len = priv->wpa_ie_len;
+
+ if (len <= 0) {
+ data->length = 0;
+ return 0;
+ }
+
+ if (data->length < len)
+ return -E2BIG;
+
+ data->length = len;
+ memcpy(extra, priv->wpa_ie, len);
+
+ return 0;
+}
+
+static int prism54_set_auth(struct net_device *ndev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ islpci_private *priv = netdev_priv(ndev);
+ struct iw_param *param = &wrqu->param;
+ u32 mlmelevel = 0, authen = 0, dot1x = 0;
+ u32 exunencrypt = 0, privinvoked = 0, wpa = 0;
+ u32 old_wpa;
+ int ret = 0;
+ union oid_res_t r;
+
+ if (islpci_get_state(priv) < PRV_STATE_INIT)
+ return 0;
+
+ /* first get the flags */
+ down_write(&priv->mib_sem);
+ wpa = old_wpa = priv->wpa;
+ up_write(&priv->mib_sem);
+ ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
+ authen = r.u;
+ ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
+ privinvoked = r.u;
+ ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
+ exunencrypt = r.u;
+ ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r);
+ dot1x = r.u;
+ ret = mgt_get_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, NULL, &r);
+ mlmelevel = r.u;
+
+ if (ret < 0)
+ goto out;
+
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_CIPHER_PAIRWISE:
+ case IW_AUTH_CIPHER_GROUP:
+ case IW_AUTH_KEY_MGMT:
+ break;
+
+ case IW_AUTH_WPA_ENABLED:
+ /* Do the same thing as IW_AUTH_WPA_VERSION */
+ if (param->value) {
+ wpa = 1;
+ privinvoked = 1; /* For privacy invoked */
+ exunencrypt = 1; /* Filter out all unencrypted frames */
+ dot1x = 0x01; /* To enable eap filter */
+ mlmelevel = DOT11_MLME_EXTENDED;
+ authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
+ } else {
+ wpa = 0;
+ privinvoked = 0;
+ exunencrypt = 0; /* Do not filter un-encrypted data */
+ dot1x = 0;
+ mlmelevel = DOT11_MLME_AUTO;
+ }
+ break;
+
+ case IW_AUTH_WPA_VERSION:
+ if (param->value & IW_AUTH_WPA_VERSION_DISABLED) {
+ wpa = 0;
+ privinvoked = 0;
+ exunencrypt = 0; /* Do not filter un-encrypted data */
+ dot1x = 0;
+ mlmelevel = DOT11_MLME_AUTO;
+ } else {
+ if (param->value & IW_AUTH_WPA_VERSION_WPA)
+ wpa = 1;
+ else if (param->value & IW_AUTH_WPA_VERSION_WPA2)
+ wpa = 2;
+ privinvoked = 1; /* For privacy invoked */
+ exunencrypt = 1; /* Filter out all unencrypted frames */
+ dot1x = 0x01; /* To enable eap filter */
+ mlmelevel = DOT11_MLME_EXTENDED;
+ authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
+ }
+ break;
+
+ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+ /* dot1x should be the opposite of RX_UNENCRYPTED_EAPOL;
+ * turn off dot1x when allowing receipt of unencrypted EAPOL
+ * frames, turn on dot1x when receipt should be disallowed
+ */
+ dot1x = param->value ? 0 : 0x01;
+ break;
+
+ case IW_AUTH_PRIVACY_INVOKED:
+ privinvoked = param->value ? 1 : 0;
+ break;
+
+ case IW_AUTH_DROP_UNENCRYPTED:
+ exunencrypt = param->value ? 1 : 0;
+ break;
+
+ case IW_AUTH_80211_AUTH_ALG:
+ if (param->value & IW_AUTH_ALG_SHARED_KEY) {
+ /* Only WEP uses _SK and _BOTH */
+ if (wpa > 0) {
+ ret = -EINVAL;
+ goto out;
+ }
+ authen = DOT11_AUTH_SK;
+ } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
+ authen = DOT11_AUTH_OS;
+ } else {
+ ret = -EINVAL;
+ goto out;
+ }
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ /* Set all the values */
+ down_write(&priv->mib_sem);
+ priv->wpa = wpa;
+ up_write(&priv->mib_sem);
+ mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
+ mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &privinvoked);
+ mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &exunencrypt);
+ mgt_set_request(priv, DOT11_OID_DOT1XENABLE, 0, &dot1x);
+ mgt_set_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, &mlmelevel);
+
+out:
+ return ret;
+}
+
+static int prism54_get_auth(struct net_device *ndev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ islpci_private *priv = netdev_priv(ndev);
+ struct iw_param *param = &wrqu->param;
+ u32 wpa = 0;
+ int ret = 0;
+ union oid_res_t r;
+
+ if (islpci_get_state(priv) < PRV_STATE_INIT)
+ return 0;
+
+ /* first get the flags */
+ down_write(&priv->mib_sem);
+ wpa = priv->wpa;
+ up_write(&priv->mib_sem);
+
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_CIPHER_PAIRWISE:
+ case IW_AUTH_CIPHER_GROUP:
+ case IW_AUTH_KEY_MGMT:
+ /*
+ * wpa_supplicant will control these internally
+ */
+ ret = -EOPNOTSUPP;
+ break;
+
+ case IW_AUTH_WPA_VERSION:
+ switch (wpa) {
+ case 1:
+ param->value = IW_AUTH_WPA_VERSION_WPA;
+ break;
+ case 2:
+ param->value = IW_AUTH_WPA_VERSION_WPA2;
+ break;
+ case 0:
+ default:
+ param->value = IW_AUTH_WPA_VERSION_DISABLED;
+ break;
+ }
+ break;
+
+ case IW_AUTH_DROP_UNENCRYPTED:
+ ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
+ if (ret >= 0)
+ param->value = r.u > 0 ? 1 : 0;
+ break;
+
+ case IW_AUTH_80211_AUTH_ALG:
+ ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
+ if (ret >= 0) {
+ switch (r.u) {
+ case DOT11_AUTH_OS:
+ param->value = IW_AUTH_ALG_OPEN_SYSTEM;
+ break;
+ case DOT11_AUTH_BOTH:
+ case DOT11_AUTH_SK:
+ param->value = IW_AUTH_ALG_SHARED_KEY;
+ break;
+ case DOT11_AUTH_NONE:
+ default:
+ param->value = 0;
+ break;
+ }
+ }
+ break;
+
+ case IW_AUTH_WPA_ENABLED:
+ param->value = wpa > 0 ? 1 : 0;
+ break;
+
+ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+ ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r);
+ if (ret >= 0)
+ param->value = r.u > 0 ? 1 : 0;
+ break;
+
+ case IW_AUTH_PRIVACY_INVOKED:
+ ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
+ if (ret >= 0)
+ param->value = r.u > 0 ? 1 : 0;
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+ return ret;
+}
+
+static int prism54_set_encodeext(struct net_device *ndev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ islpci_private *priv = netdev_priv(ndev);
+ struct iw_point *encoding = &wrqu->encoding;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ int idx, alg = ext->alg, set_key = 1;
+ union oid_res_t r;
+ int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
+ int ret = 0;
+
+ if (islpci_get_state(priv) < PRV_STATE_INIT)
+ return 0;
+
+ /* Determine and validate the key index */
+ idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
+ if (idx) {
+ if (idx < 0 || idx > 3)
+ return -EINVAL;
+ } else {
+ ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
+ if (ret < 0)
+ goto out;
+ idx = r.u;
+ }
+
+ if (encoding->flags & IW_ENCODE_DISABLED)
+ alg = IW_ENCODE_ALG_NONE;
+
+ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+ /* Only set transmit key index here, actual
+ * key is set below if needed.
+ */
+ ret = mgt_set_request(priv, DOT11_OID_DEFKEYID, 0, &idx);
+ set_key = ext->key_len > 0 ? 1 : 0;
+ }
+
+ if (set_key) {
+ struct obj_key key = { DOT11_PRIV_WEP, 0, "" };
+ switch (alg) {
+ case IW_ENCODE_ALG_NONE:
+ break;
+ case IW_ENCODE_ALG_WEP:
+ if (ext->key_len > KEY_SIZE_WEP104) {
+ ret = -EINVAL;
+ goto out;
+ }
+ if (ext->key_len > KEY_SIZE_WEP40)
+ key.length = KEY_SIZE_WEP104;
+ else
+ key.length = KEY_SIZE_WEP40;
+ break;
+ case IW_ENCODE_ALG_TKIP:
+ if (ext->key_len > KEY_SIZE_TKIP) {
+ ret = -EINVAL;
+ goto out;
+ }
+ key.type = DOT11_PRIV_TKIP;
+ key.length = KEY_SIZE_TKIP;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (key.length) {
+ memset(key.key, 0, sizeof(key.key));
+ memcpy(key.key, ext->key, ext->key_len);
+ ret = mgt_set_request(priv, DOT11_OID_DEFKEYX, idx,
+ &key);
+ if (ret < 0)
+ goto out;
+ }
+ }
+
+ /* Read the flags */
+ if (encoding->flags & IW_ENCODE_DISABLED) {
+ /* Encoding disabled,
+ * authen = DOT11_AUTH_OS;
+ * invoke = 0;
+ * exunencrypt = 0; */
+ }
+ if (encoding->flags & IW_ENCODE_OPEN) {
+ /* Encode but accept non-encoded packets. No auth */
+ invoke = 1;
+ }
+ if (encoding->flags & IW_ENCODE_RESTRICTED) {
+ /* Refuse non-encoded packets. Auth */
+ authen = DOT11_AUTH_BOTH;
+ invoke = 1;
+ exunencrypt = 1;
+ }
+
+ /* do the change if requested */
+ if (encoding->flags & IW_ENCODE_MODE) {
+ ret = mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0,
+ &authen);
+ ret = mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0,
+ &invoke);
+ ret = mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
+ &exunencrypt);
+ }
+
+out:
+ return ret;
+}
+
+
+static int prism54_get_encodeext(struct net_device *ndev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ islpci_private *priv = netdev_priv(ndev);
+ struct iw_point *encoding = &wrqu->encoding;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ int idx, max_key_len;
+ union oid_res_t r;
+ int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0, wpa = 0;
+ int ret = 0;
+
+ if (islpci_get_state(priv) < PRV_STATE_INIT)
+ return 0;
+
+ /* first get the flags */
+ ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
+ authen = r.u;
+ ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
+ invoke = r.u;
+ ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
+ exunencrypt = r.u;
+ if (ret < 0)
+ goto out;
+
+ max_key_len = encoding->length - sizeof(*ext);
+ if (max_key_len < 0)
+ return -EINVAL;
+
+ idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
+ if (idx) {
+ if (idx < 0 || idx > 3)
+ return -EINVAL;
+ } else {
+ ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
+ if (ret < 0)
+ goto out;
+ idx = r.u;
+ }
+
+ encoding->flags = idx + 1;
+ memset(ext, 0, sizeof(*ext));
+
+ switch (authen) {
+ case DOT11_AUTH_BOTH:
+ case DOT11_AUTH_SK:
+ wrqu->encoding.flags |= IW_ENCODE_RESTRICTED;
+ case DOT11_AUTH_OS:
+ default:
+ wrqu->encoding.flags |= IW_ENCODE_OPEN;
+ break;
+ }
+
+ down_write(&priv->mib_sem);
+ wpa = priv->wpa;
+ up_write(&priv->mib_sem);
+
+ if (authen == DOT11_AUTH_OS && !exunencrypt && !invoke && !wpa) {
+ /* No encryption */
+ ext->alg = IW_ENCODE_ALG_NONE;
+ ext->key_len = 0;
+ wrqu->encoding.flags |= IW_ENCODE_DISABLED;
+ } else {
+ struct obj_key *key;
+
+ ret = mgt_get_request(priv, DOT11_OID_DEFKEYX, idx, NULL, &r);
+ if (ret < 0)
+ goto out;
+ key = r.ptr;
+ if (max_key_len < key->length) {
+ ret = -E2BIG;
+ goto out;
+ }
+ memcpy(ext->key, key->key, key->length);
+ ext->key_len = key->length;
+
+ switch (key->type) {
+ case DOT11_PRIV_TKIP:
+ ext->alg = IW_ENCODE_ALG_TKIP;
+ break;
+ default:
+ case DOT11_PRIV_WEP:
+ ext->alg = IW_ENCODE_ALG_WEP;
+ break;
+ }
+ wrqu->encoding.flags |= IW_ENCODE_ENABLED;
+ }
+
+out:
+ return ret;
+}
+
+
static int
prism54_reset(struct net_device *ndev, struct iw_request_info *info,
__u32 * uwrq, char *extra)
@@ -1227,7 +1754,7 @@ prism54_get_oid(struct net_device *ndev, struct iw_request_info *info,
int rvalue;
enum oid_num_t n = dwrq->flags;
- rvalue = mgt_get_request((islpci_private *) ndev->priv, n, 0, NULL, &r);
+ rvalue = mgt_get_request(netdev_priv(ndev), n, 0, NULL, &r);
dwrq->length = mgt_response_to_str(n, &r, extra);
if ((isl_oid[n].flags & OID_FLAG_TYPE) != OID_TYPE_U32)
kfree(r.ptr);
@@ -1240,7 +1767,7 @@ prism54_set_u32(struct net_device *ndev, struct iw_request_info *info,
{
u32 oid = uwrq[0], u = uwrq[1];
- return mgt_set_request((islpci_private *) ndev->priv, oid, 0, &u);
+ return mgt_set_request(netdev_priv(ndev), oid, 0, &u);
}
static int
@@ -1249,13 +1776,13 @@ prism54_set_raw(struct net_device *ndev, struct iw_request_info *info,
{
u32 oid = dwrq->flags;
- return mgt_set_request((islpci_private *) ndev->priv, oid, 0, extra);
+ return mgt_set_request(netdev_priv(ndev), oid, 0, extra);
}
void
prism54_acl_init(struct islpci_acl *acl)
{
- sema_init(&acl->sem, 1);
+ mutex_init(&acl->lock);
INIT_LIST_HEAD(&acl->mac_list);
acl->size = 0;
acl->policy = MAC_POLICY_OPEN;
@@ -1267,11 +1794,10 @@ prism54_clear_mac(struct islpci_acl *acl)
struct list_head *ptr, *next;
struct mac_entry *entry;
- if (down_interruptible(&acl->sem))
- return;
+ mutex_lock(&acl->lock);
if (acl->size == 0) {
- up(&acl->sem);
+ mutex_unlock(&acl->lock);
return;
}
@@ -1282,7 +1808,7 @@ prism54_clear_mac(struct islpci_acl *acl)
kfree(entry);
}
acl->size = 0;
- up(&acl->sem);
+ mutex_unlock(&acl->lock);
}
void
@@ -1309,13 +1835,13 @@ prism54_add_mac(struct net_device *ndev, struct iw_request_info *info,
memcpy(entry->addr, addr->sa_data, ETH_ALEN);
- if (down_interruptible(&acl->sem)) {
+ if (mutex_lock_interruptible(&acl->lock)) {
kfree(entry);
return -ERESTARTSYS;
}
list_add_tail(&entry->_list, &acl->mac_list);
acl->size++;
- up(&acl->sem);
+ mutex_unlock(&acl->lock);
return 0;
}
@@ -1327,26 +1853,23 @@ prism54_del_mac(struct net_device *ndev, struct iw_request_info *info,
islpci_private *priv = netdev_priv(ndev);
struct islpci_acl *acl = &priv->acl;
struct mac_entry *entry;
- struct list_head *ptr;
struct sockaddr *addr = (struct sockaddr *) extra;
if (addr->sa_family != ARPHRD_ETHER)
return -EOPNOTSUPP;
- if (down_interruptible(&acl->sem))
+ if (mutex_lock_interruptible(&acl->lock))
return -ERESTARTSYS;
- for (ptr = acl->mac_list.next; ptr != &acl->mac_list; ptr = ptr->next) {
- entry = list_entry(ptr, struct mac_entry, _list);
-
- if (memcmp(entry->addr, addr->sa_data, ETH_ALEN) == 0) {
- list_del(ptr);
+ list_for_each_entry(entry, &acl->mac_list, _list) {
+ if (ether_addr_equal(entry->addr, addr->sa_data)) {
+ list_del(&entry->_list);
acl->size--;
kfree(entry);
- up(&acl->sem);
+ mutex_unlock(&acl->lock);
return 0;
}
}
- up(&acl->sem);
+ mutex_unlock(&acl->lock);
return -EINVAL;
}
@@ -1357,27 +1880,24 @@ prism54_get_mac(struct net_device *ndev, struct iw_request_info *info,
islpci_private *priv = netdev_priv(ndev);
struct islpci_acl *acl = &priv->acl;
struct mac_entry *entry;
- struct list_head *ptr;
struct sockaddr *dst = (struct sockaddr *) extra;
dwrq->length = 0;
- if (down_interruptible(&acl->sem))
+ if (mutex_lock_interruptible(&acl->lock))
return -ERESTARTSYS;
- for (ptr = acl->mac_list.next; ptr != &acl->mac_list; ptr = ptr->next) {
- entry = list_entry(ptr, struct mac_entry, _list);
-
+ list_for_each_entry(entry, &acl->mac_list, _list) {
memcpy(dst->sa_data, entry->addr, ETH_ALEN);
dst->sa_family = ARPHRD_ETHER;
dwrq->length++;
dst++;
}
- up(&acl->sem);
+ mutex_unlock(&acl->lock);
return 0;
}
-/* Setting policy also clears the MAC acl, even if we don't change the defaut
+/* Setting policy also clears the MAC acl, even if we don't change the default
* policy
*/
@@ -1434,27 +1954,25 @@ prism54_get_policy(struct net_device *ndev, struct iw_request_info *info,
static int
prism54_mac_accept(struct islpci_acl *acl, char *mac)
{
- struct list_head *ptr;
struct mac_entry *entry;
int res = 0;
- if (down_interruptible(&acl->sem))
+ if (mutex_lock_interruptible(&acl->lock))
return -ERESTARTSYS;
if (acl->policy == MAC_POLICY_OPEN) {
- up(&acl->sem);
+ mutex_unlock(&acl->lock);
return 1;
}
- for (ptr = acl->mac_list.next; ptr != &acl->mac_list; ptr = ptr->next) {
- entry = list_entry(ptr, struct mac_entry, _list);
+ list_for_each_entry(entry, &acl->mac_list, _list) {
if (memcmp(entry->addr, mac, ETH_ALEN) == 0) {
res = 1;
break;
}
}
res = (acl->policy == MAC_POLICY_ACCEPT) ? !res : res;
- up(&acl->sem);
+ mutex_unlock(&acl->lock);
return res;
}
@@ -1511,12 +2029,11 @@ static void
format_event(islpci_private *priv, char *dest, const char *str,
const struct obj_mlme *mlme, u16 *length, int error)
{
- const u8 *a = mlme->address;
int n = snprintf(dest, IW_CUSTOM_MAX,
- "%s %s %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X %s (%2.2X)",
+ "%s %s %pM %s (%2.2X)",
str,
((priv->iw_mode == IW_MODE_MASTER) ? "from" : "to"),
- a[0], a[1], a[2], a[3], a[4], a[5],
+ mlme->address,
(error ? (mlme->code ? " : REJECTED " : " : ACCEPTED ")
: ""), mlme->code);
BUG_ON(n > IW_CUSTOM_MAX);
@@ -1551,7 +2068,7 @@ send_simple_event(islpci_private *priv, const char *str)
memptr = kmalloc(IW_CUSTOM_MAX, GFP_KERNEL);
if (!memptr)
return;
- BUG_ON(n > IW_CUSTOM_MAX);
+ BUG_ON(n >= IW_CUSTOM_MAX);
wrqu.data.pointer = memptr;
wrqu.data.length = n;
strcpy(memptr, str);
@@ -1565,6 +2082,7 @@ link_changed(struct net_device *ndev, u32 bitrate)
islpci_private *priv = netdev_priv(ndev);
if (bitrate) {
+ netif_carrier_on(ndev);
if (priv->iw_mode == IW_MODE_INFRA) {
union iwreq_data uwrq;
prism54_get_wap(ndev, NULL, (struct sockaddr *) &uwrq,
@@ -1573,8 +2091,10 @@ link_changed(struct net_device *ndev, u32 bitrate)
} else
send_simple_event(netdev_priv(ndev),
"Link established");
- } else
+ } else {
+ netif_carrier_off(ndev);
send_simple_event(netdev_priv(ndev), "Link lost");
+ }
}
/* Beacon/ProbeResp payload header */
@@ -1582,17 +2102,14 @@ struct ieee80211_beacon_phdr {
u8 timestamp[8];
u16 beacon_int;
u16 capab_info;
-} __attribute__ ((packed));
+} __packed;
#define WLAN_EID_GENERIC 0xdd
static u8 wpa_oid[4] = { 0x00, 0x50, 0xf2, 1 };
-#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
-#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
-
static void
-prism54_wpa_ie_add(islpci_private *priv, u8 *bssid,
- u8 *wpa_ie, size_t wpa_ie_len)
+prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
+ u8 *wpa_ie, size_t wpa_ie_len)
{
struct list_head *ptr;
struct islpci_bss_wpa_ie *bss = NULL;
@@ -1600,8 +2117,7 @@ prism54_wpa_ie_add(islpci_private *priv, u8 *bssid,
if (wpa_ie_len > MAX_WPA_IE_LEN)
wpa_ie_len = MAX_WPA_IE_LEN;
- if (down_interruptible(&priv->wpa_sem))
- return;
+ mutex_lock(&priv->wpa_lock);
/* try to use existing entry */
list_for_each(ptr, &priv->bss_wpa_list) {
@@ -1621,11 +2137,9 @@ prism54_wpa_ie_add(islpci_private *priv, u8 *bssid,
struct islpci_bss_wpa_ie, list);
list_del(&bss->list);
} else {
- bss = kmalloc(sizeof (*bss), GFP_ATOMIC);
- if (bss != NULL) {
+ bss = kzalloc(sizeof (*bss), GFP_ATOMIC);
+ if (bss != NULL)
priv->num_bss_wpa++;
- memset(bss, 0, sizeof (*bss));
- }
}
if (bss != NULL) {
memcpy(bss->bssid, bssid, ETH_ALEN);
@@ -1638,8 +2152,8 @@ prism54_wpa_ie_add(islpci_private *priv, u8 *bssid,
bss->wpa_ie_len = wpa_ie_len;
bss->last_update = jiffies;
} else {
- printk(KERN_DEBUG "Failed to add BSS WPA entry for " MACSTR
- "\n", MAC2STR(bssid));
+ printk(KERN_DEBUG "Failed to add BSS WPA entry for "
+ "%pM\n", bssid);
}
/* expire old entries from WPA list */
@@ -1654,18 +2168,17 @@ prism54_wpa_ie_add(islpci_private *priv, u8 *bssid,
kfree(bss);
}
- up(&priv->wpa_sem);
+ mutex_unlock(&priv->wpa_lock);
}
static size_t
-prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie)
+prism54_wpa_bss_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie)
{
struct list_head *ptr;
struct islpci_bss_wpa_ie *bss = NULL;
size_t len = 0;
- if (down_interruptible(&priv->wpa_sem))
- return 0;
+ mutex_lock(&priv->wpa_lock);
list_for_each(ptr, &priv->bss_wpa_list) {
bss = list_entry(ptr, struct islpci_bss_wpa_ie, list);
@@ -1677,26 +2190,24 @@ prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie)
len = bss->wpa_ie_len;
memcpy(wpa_ie, bss->wpa_ie, len);
}
- up(&priv->wpa_sem);
+ mutex_unlock(&priv->wpa_lock);
return len;
}
void
-prism54_wpa_ie_init(islpci_private *priv)
+prism54_wpa_bss_ie_init(islpci_private *priv)
{
INIT_LIST_HEAD(&priv->bss_wpa_list);
- sema_init(&priv->wpa_sem, 1);
+ mutex_init(&priv->wpa_lock);
}
void
-prism54_wpa_ie_clean(islpci_private *priv)
+prism54_wpa_bss_ie_clean(islpci_private *priv)
{
- struct list_head *ptr, *n;
+ struct islpci_bss_wpa_ie *bss, *n;
- list_for_each_safe(ptr, n, &priv->bss_wpa_list) {
- struct islpci_bss_wpa_ie *bss;
- bss = list_entry(ptr, struct islpci_bss_wpa_ie, list);
+ list_for_each_entry_safe(bss, n, &priv->bss_wpa_list, list) {
kfree(bss);
}
}
@@ -1717,12 +2228,12 @@ prism54_process_bss_data(islpci_private *priv, u32 oid, u8 *addr,
while (pos < end) {
if (pos + 2 + pos[1] > end) {
printk(KERN_DEBUG "Parsing Beacon/ProbeResp failed "
- "for " MACSTR "\n", MAC2STR(addr));
+ "for %pM\n", addr);
return;
}
if (pos[0] == WLAN_EID_GENERIC && pos[1] >= 4 &&
memcmp(pos + 2, wpa_oid, 4) == 0) {
- prism54_wpa_ie_add(priv, addr, pos, pos[1] + 2);
+ prism54_wpa_bss_ie_add(priv, addr, pos, pos[1] + 2);
return;
}
pos += 2 + pos[1];
@@ -1812,7 +2323,7 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
case DOT11_OID_BEACON:
send_formatted_event(priv,
- "Received a beacon from an unkown AP",
+ "Received a beacon from an unknown AP",
mlme, 0);
break;
@@ -1834,24 +2345,18 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
handle_request(priv, mlme, oid);
send_formatted_event(priv, "Authenticate request (ex)", mlme, 1);
- if (priv->iw_mode != IW_MODE_MASTER
+ if (priv->iw_mode != IW_MODE_MASTER
&& mlmeex->state != DOT11_STATE_AUTHING)
break;
confirm = kmalloc(sizeof(struct obj_mlmeex) + 6, GFP_ATOMIC);
- if (!confirm)
+ if (!confirm)
break;
memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
- printk(KERN_DEBUG "Authenticate from: address:\t%02x:%02x:%02x:%02x:%02x:%02x\n",
- mlmeex->address[0],
- mlmeex->address[1],
- mlmeex->address[2],
- mlmeex->address[3],
- mlmeex->address[4],
- mlmeex->address[5]
- );
+ printk(KERN_DEBUG "Authenticate from: address:\t%pM\n",
+ mlmeex->address);
confirm->id = -1; /* or mlmeex->id ? */
confirm->state = 0; /* not used */
confirm->code = 0;
@@ -1878,10 +2383,10 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
handle_request(priv, mlme, oid);
send_formatted_event(priv, "Associate request (ex)", mlme, 1);
- if (priv->iw_mode != IW_MODE_MASTER
- && mlmeex->state != DOT11_STATE_AUTHING)
+ if (priv->iw_mode != IW_MODE_MASTER
+ && mlmeex->state != DOT11_STATE_ASSOCING)
break;
-
+
confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
if (!confirm)
@@ -1893,18 +2398,11 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
confirm->state = 0; /* not used */
confirm->code = 0;
- wpa_ie_len = prism54_wpa_ie_get(priv, mlmeex->address, wpa_ie);
+ wpa_ie_len = prism54_wpa_bss_ie_get(priv, mlmeex->address, wpa_ie);
if (!wpa_ie_len) {
- printk(KERN_DEBUG "No WPA IE found from "
- "address:\t%02x:%02x:%02x:%02x:%02x:%02x\n",
- mlmeex->address[0],
- mlmeex->address[1],
- mlmeex->address[2],
- mlmeex->address[3],
- mlmeex->address[4],
- mlmeex->address[5]
- );
+ printk(KERN_DEBUG "No WPA IE found from address:\t%pM\n",
+ mlmeex->address);
kfree(confirm);
break;
}
@@ -1915,14 +2413,14 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
mgt_set_varlen(priv, oid, confirm, wpa_ie_len);
kfree(confirm);
-
+
break;
case DOT11_OID_REASSOCIATEEX:
handle_request(priv, mlme, oid);
send_formatted_event(priv, "Reassociate request (ex)", mlme, 1);
- if (priv->iw_mode != IW_MODE_MASTER
+ if (priv->iw_mode != IW_MODE_MASTER
&& mlmeex->state != DOT11_STATE_ASSOCING)
break;
@@ -1937,29 +2435,22 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
confirm->state = 0; /* not used */
confirm->code = 0;
- wpa_ie_len = prism54_wpa_ie_get(priv, mlmeex->address, wpa_ie);
+ wpa_ie_len = prism54_wpa_bss_ie_get(priv, mlmeex->address, wpa_ie);
if (!wpa_ie_len) {
- printk(KERN_DEBUG "No WPA IE found from "
- "address:\t%02x:%02x:%02x:%02x:%02x:%02x\n",
- mlmeex->address[0],
- mlmeex->address[1],
- mlmeex->address[2],
- mlmeex->address[3],
- mlmeex->address[4],
- mlmeex->address[5]
- );
+ printk(KERN_DEBUG "No WPA IE found from address:\t%pM\n",
+ mlmeex->address);
kfree(confirm);
break;
}
- confirm->size = wpa_ie_len;
+ confirm->size = wpa_ie_len;
memcpy(&confirm->data, wpa_ie, wpa_ie_len);
mgt_set_varlen(priv, oid, confirm, wpa_ie_len);
kfree(confirm);
-
+
break;
default:
@@ -1974,9 +2465,10 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
* interrupt context, no locks held.
*/
void
-prism54_process_trap(void *data)
+prism54_process_trap(struct work_struct *work)
{
- struct islpci_mgmtframe *frame = data;
+ struct islpci_mgmtframe *frame =
+ container_of(work, struct islpci_mgmtframe, ws);
struct net_device *ndev = frame->ndev;
enum oid_num_t n = mgt_oidtonum(frame->header->oid);
@@ -1997,330 +2489,12 @@ prism54_set_mac_address(struct net_device *ndev, void *addr)
&((struct sockaddr *) addr)->sa_data);
if (!ret)
memcpy(priv->ndev->dev_addr,
- &((struct sockaddr *) addr)->sa_data, 6);
+ &((struct sockaddr *) addr)->sa_data, ETH_ALEN);
return ret;
}
-/* Note: currently, use hostapd ioctl from the Host AP driver for WPA
- * support. This is to be replaced with Linux wireless extensions once they
- * get WPA support. */
-
-/* Note II: please leave all this together as it will be easier to remove later,
- * once wireless extensions add WPA support -mcgrof */
-
-/* PRISM54_HOSTAPD ioctl() cmd: */
-enum {
- PRISM2_SET_ENCRYPTION = 6,
- PRISM2_HOSTAPD_SET_GENERIC_ELEMENT = 12,
- PRISM2_HOSTAPD_MLME = 13,
- PRISM2_HOSTAPD_SCAN_REQ = 14,
-};
-
#define PRISM54_SET_WPA SIOCIWFIRSTPRIV+12
-#define PRISM54_HOSTAPD SIOCIWFIRSTPRIV+25
-#define PRISM54_DROP_UNENCRYPTED SIOCIWFIRSTPRIV+26
-
-#define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024
-#define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \
-((int) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data))
-
-/* Maximum length for algorithm names (-1 for nul termination)
- * used in ioctl() */
-#define HOSTAP_CRYPT_ALG_NAME_LEN 16
-
-struct prism2_hostapd_param {
- u32 cmd;
- u8 sta_addr[ETH_ALEN];
- union {
- struct {
- u8 alg[HOSTAP_CRYPT_ALG_NAME_LEN];
- u32 flags;
- u32 err;
- u8 idx;
- u8 seq[8]; /* sequence counter (set: RX, get: TX) */
- u16 key_len;
- u8 key[0];
- } crypt;
- struct {
- u8 len;
- u8 data[0];
- } generic_elem;
- struct {
-#define MLME_STA_DEAUTH 0
-#define MLME_STA_DISASSOC 1
- u16 cmd;
- u16 reason_code;
- } mlme;
- struct {
- u8 ssid_len;
- u8 ssid[32];
- } scan_req;
- } u;
-};
-
-
-static int
-prism2_ioctl_set_encryption(struct net_device *dev,
- struct prism2_hostapd_param *param,
- int param_len)
-{
- islpci_private *priv = netdev_priv(dev);
- int rvalue = 0, force = 0;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
- union oid_res_t r;
-
- /* with the new API, it's impossible to get a NULL pointer.
- * New version of iwconfig set the IW_ENCODE_NOKEY flag
- * when no key is given, but older versions don't. */
-
- if (param->u.crypt.key_len > 0) {
- /* we have a key to set */
- int index = param->u.crypt.idx;
- int current_index;
- struct obj_key key = { DOT11_PRIV_TKIP, 0, "" };
-
- /* get the current key index */
- rvalue = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
- current_index = r.u;
- /* Verify that the key is not marked as invalid */
- if (!(param->u.crypt.flags & IW_ENCODE_NOKEY)) {
- key.length = param->u.crypt.key_len > sizeof (param->u.crypt.key) ?
- sizeof (param->u.crypt.key) : param->u.crypt.key_len;
- memcpy(key.key, param->u.crypt.key, key.length);
- if (key.length == 32)
- /* we want WPA-PSK */
- key.type = DOT11_PRIV_TKIP;
- if ((index < 0) || (index > 3))
- /* no index provided use the current one */
- index = current_index;
-
- /* now send the key to the card */
- rvalue |=
- mgt_set_request(priv, DOT11_OID_DEFKEYX, index,
- &key);
- }
- /*
- * If a valid key is set, encryption should be enabled
- * (user may turn it off later).
- * This is also how "iwconfig ethX key on" works
- */
- if ((index == current_index) && (key.length > 0))
- force = 1;
- } else {
- int index = (param->u.crypt.flags & IW_ENCODE_INDEX) - 1;
- if ((index >= 0) && (index <= 3)) {
- /* we want to set the key index */
- rvalue |=
- mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
- &index);
- } else {
- if (!param->u.crypt.flags & IW_ENCODE_MODE) {
- /* we cannot do anything. Complain. */
- return -EINVAL;
- }
- }
- }
- /* now read the flags */
- if (param->u.crypt.flags & IW_ENCODE_DISABLED) {
- /* Encoding disabled,
- * authen = DOT11_AUTH_OS;
- * invoke = 0;
- * exunencrypt = 0; */
- }
- if (param->u.crypt.flags & IW_ENCODE_OPEN)
- /* Encode but accept non-encoded packets. No auth */
- invoke = 1;
- if ((param->u.crypt.flags & IW_ENCODE_RESTRICTED) || force) {
- /* Refuse non-encoded packets. Auth */
- authen = DOT11_AUTH_BOTH;
- invoke = 1;
- exunencrypt = 1;
- }
- /* do the change if requested */
- if ((param->u.crypt.flags & IW_ENCODE_MODE) || force) {
- rvalue |=
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &invoke);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
- &exunencrypt);
- }
- return rvalue;
-}
-
-static int
-prism2_ioctl_set_generic_element(struct net_device *ndev,
- struct prism2_hostapd_param *param,
- int param_len)
-{
- islpci_private *priv = netdev_priv(ndev);
- int max_len, len, alen, ret=0;
- struct obj_attachment *attach;
-
- len = param->u.generic_elem.len;
- max_len = param_len - PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN;
- if (max_len < 0 || max_len < len)
- return -EINVAL;
-
- alen = sizeof(*attach) + len;
- attach = kmalloc(alen, GFP_KERNEL);
- if (attach == NULL)
- return -ENOMEM;
-
- memset(attach, 0, alen);
-#define WLAN_FC_TYPE_MGMT 0
-#define WLAN_FC_STYPE_ASSOC_REQ 0
-#define WLAN_FC_STYPE_REASSOC_REQ 2
-
- /* Note: endianness is covered by mgt_set_varlen */
-
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_ASSOC_REQ << 4);
- attach->id = -1;
- attach->size = len;
- memcpy(attach->data, param->u.generic_elem.data, len);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len);
-
- if (ret == 0) {
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_REASSOC_REQ << 4);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len);
-
- if (ret == 0)
- printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
- ndev->name);
- }
-
- kfree(attach);
- return ret;
-
-}
-
-static int
-prism2_ioctl_mlme(struct net_device *dev, struct prism2_hostapd_param *param)
-{
- return -EOPNOTSUPP;
-}
-
-static int
-prism2_ioctl_scan_req(struct net_device *ndev,
- struct prism2_hostapd_param *param)
-{
- islpci_private *priv = netdev_priv(ndev);
- int i, rvalue;
- struct obj_bsslist *bsslist;
- u32 noise = 0;
- char *extra = "";
- char *current_ev = "foo";
- union oid_res_t r;
-
- if (islpci_get_state(priv) < PRV_STATE_INIT) {
- /* device is not ready, fail gently */
- return 0;
- }
-
- /* first get the noise value. We will use it to report the link quality */
- rvalue = mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);
- noise = r.u;
-
- /* Ask the device for a list of known bss. We can report at most
- * IW_MAX_AP=64 to the range struct. But the device won't repport anything
- * if you change the value of IWMAX_BSS=24.
- */
- rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);
- bsslist = r.ptr;
-
- /* ok now, scan the list and translate its info */
- for (i = 0; i < min(IW_MAX_AP, (int) bsslist->nr); i++)
- current_ev = prism54_translate_bss(ndev, current_ev,
- extra + IW_SCAN_MAX_DATA,
- &(bsslist->bsslist[i]),
- noise);
- kfree(bsslist);
-
- return rvalue;
-}
-
-static int
-prism54_hostapd(struct net_device *ndev, struct iw_point *p)
-{
- struct prism2_hostapd_param *param;
- int ret = 0;
- u32 uwrq;
-
- printk(KERN_DEBUG "prism54_hostapd - len=%d\n", p->length);
- if (p->length < sizeof(struct prism2_hostapd_param) ||
- p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
- return -EINVAL;
-
- param = (struct prism2_hostapd_param *) kmalloc(p->length, GFP_KERNEL);
- if (param == NULL)
- return -ENOMEM;
-
- if (copy_from_user(param, p->pointer, p->length)) {
- kfree(param);
- return -EFAULT;
- }
-
- switch (param->cmd) {
- case PRISM2_SET_ENCRYPTION:
- printk(KERN_DEBUG "%s: Caught WPA supplicant set encryption request\n",
- ndev->name);
- ret = prism2_ioctl_set_encryption(ndev, param, p->length);
- break;
- case PRISM2_HOSTAPD_SET_GENERIC_ELEMENT:
- printk(KERN_DEBUG "%s: Caught WPA supplicant set WPA IE request\n",
- ndev->name);
- ret = prism2_ioctl_set_generic_element(ndev, param,
- p->length);
- break;
- case PRISM2_HOSTAPD_MLME:
- printk(KERN_DEBUG "%s: Caught WPA supplicant MLME request\n",
- ndev->name);
- ret = prism2_ioctl_mlme(ndev, param);
- break;
- case PRISM2_HOSTAPD_SCAN_REQ:
- printk(KERN_DEBUG "%s: Caught WPA supplicant scan request\n",
- ndev->name);
- ret = prism2_ioctl_scan_req(ndev, param);
- break;
- case PRISM54_SET_WPA:
- printk(KERN_DEBUG "%s: Caught WPA supplicant wpa init request\n",
- ndev->name);
- uwrq = 1;
- ret = prism54_set_wpa(ndev, NULL, &uwrq, NULL);
- break;
- case PRISM54_DROP_UNENCRYPTED:
- printk(KERN_DEBUG "%s: Caught WPA drop unencrypted request\n",
- ndev->name);
-#if 0
- uwrq = 0x01;
- mgt_set(priv, DOT11_OID_EXUNENCRYPTED, &uwrq);
- down_write(&priv->mib_sem);
- mgt_commit(priv);
- up_write(&priv->mib_sem);
-#endif
- /* Not necessary, as set_wpa does it, should we just do it here though? */
- ret = 0;
- break;
- default:
- printk(KERN_DEBUG "%s: Caught a WPA supplicant request that is not supported\n",
- ndev->name);
- ret = -EOPNOTSUPP;
- break;
- }
-
- if (ret == 0 && copy_to_user(p->pointer, param, p->length))
- ret = -EFAULT;
-
- kfree(param);
-
- return ret;
-}
static int
prism54_set_wpa(struct net_device *ndev, struct iw_request_info *info,
@@ -2350,7 +2524,7 @@ prism54_set_wpa(struct net_device *ndev, struct iw_request_info *info,
mlme = DOT11_MLME_AUTO;
printk("%s: Disabling WPA\n", ndev->name);
break;
- case 2:
+ case 2:
case 1: /* WPA */
printk("%s: Enabling WPA\n", ndev->name);
break;
@@ -2487,7 +2661,8 @@ prism54_set_spy(struct net_device *ndev,
union iwreq_data *uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- u32 u, oid = OID_INL_CONFIG;
+ u32 u;
+ enum oid_num_t oid = OID_INL_CONFIG;
down_write(&priv->mib_sem);
mgt_get(priv, OID_INL_CONFIG, &u);
@@ -2530,7 +2705,7 @@ static const iw_handler prism54_handler[] = {
(iw_handler) prism54_set_wap, /* SIOCSIWAP */
(iw_handler) prism54_get_wap, /* SIOCGIWAP */
(iw_handler) NULL, /* -- hole -- */
- (iw_handler) NULL, /* SIOCGIWAPLIST depreciated */
+ (iw_handler) NULL, /* SIOCGIWAPLIST deprecated */
(iw_handler) prism54_set_scan, /* SIOCSIWSCAN */
(iw_handler) prism54_get_scan, /* SIOCGIWSCAN */
(iw_handler) prism54_set_essid, /* SIOCSIWESSID */
@@ -2553,6 +2728,15 @@ static const iw_handler prism54_handler[] = {
(iw_handler) prism54_get_encode, /* SIOCGIWENCODE */
(iw_handler) NULL, /* SIOCSIWPOWER */
(iw_handler) NULL, /* SIOCGIWPOWER */
+ NULL, /* -- hole -- */
+ NULL, /* -- hole -- */
+ (iw_handler) prism54_set_genie, /* SIOCSIWGENIE */
+ (iw_handler) prism54_get_genie, /* SIOCGIWGENIE */
+ (iw_handler) prism54_set_auth, /* SIOCSIWAUTH */
+ (iw_handler) prism54_get_auth, /* SIOCGIWAUTH */
+ (iw_handler) prism54_set_encodeext, /* SIOCSIWENCODEEXT */
+ (iw_handler) prism54_get_encodeext, /* SIOCGIWENCODEEXT */
+ NULL, /* SIOCSIWPMKSA */
};
/* The low order bit identify a SET (0) or a GET (1) ioctl. */
@@ -2716,29 +2900,11 @@ static const iw_handler prism54_private_handler[] = {
};
const struct iw_handler_def prism54_handler_def = {
- .num_standard = sizeof (prism54_handler) / sizeof (iw_handler),
- .num_private = sizeof (prism54_private_handler) / sizeof (iw_handler),
- .num_private_args =
- sizeof (prism54_private_args) / sizeof (struct iw_priv_args),
+ .num_standard = ARRAY_SIZE(prism54_handler),
+ .num_private = ARRAY_SIZE(prism54_private_handler),
+ .num_private_args = ARRAY_SIZE(prism54_private_args),
.standard = (iw_handler *) prism54_handler,
.private = (iw_handler *) prism54_private_handler,
.private_args = (struct iw_priv_args *) prism54_private_args,
.get_wireless_stats = prism54_get_wireless_stats,
};
-
-/* For wpa_supplicant */
-
-int
-prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
-{
- struct iwreq *wrq = (struct iwreq *) rq;
- int ret = -1;
- switch (cmd) {
- case PRISM54_HOSTAPD:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- ret = prism54_hostapd(ndev, &wrq->u.data);
- return ret;
- }
- return -EOPNOTSUPP;
-}
diff --git a/drivers/net/wireless/prism54/isl_ioctl.h b/drivers/net/wireless/prism54/isl_ioctl.h
index 46d5cde80c8..842a2549fac 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.h
+++ b/drivers/net/wireless/prism54/isl_ioctl.h
@@ -1,5 +1,4 @@
/*
- *
* Copyright (C) 2002 Intersil Americas Inc.
* (C) 2003 Aurelien Alleaume <slts@free.fr>
* (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
@@ -14,8 +13,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
@@ -27,25 +25,23 @@
#include <net/iw_handler.h> /* New driver API */
-#define SUPPORTED_WIRELESS_EXT 16
+#define SUPPORTED_WIRELESS_EXT 19
void prism54_mib_init(islpci_private *);
struct iw_statistics *prism54_get_wireless_stats(struct net_device *);
-void prism54_update_stats(islpci_private *);
+void prism54_update_stats(struct work_struct *);
void prism54_acl_init(struct islpci_acl *);
void prism54_acl_clean(struct islpci_acl *);
-void prism54_process_trap(void *);
+void prism54_process_trap(struct work_struct *);
-void prism54_wpa_ie_init(islpci_private *priv);
-void prism54_wpa_ie_clean(islpci_private *priv);
+void prism54_wpa_bss_ie_init(islpci_private *priv);
+void prism54_wpa_bss_ie_clean(islpci_private *priv);
int prism54_set_mac_address(struct net_device *, void *);
-int prism54_ioctl(struct net_device *, struct ifreq *, int);
-
extern const struct iw_handler_def prism54_handler_def;
#endif /* _ISL_IOCTL_H */
diff --git a/drivers/net/wireless/prism54/isl_oid.h b/drivers/net/wireless/prism54/isl_oid.h
index 419edf7ccf1..83fec557997 100644
--- a/drivers/net/wireless/prism54/isl_oid.h
+++ b/drivers/net/wireless/prism54/isl_oid.h
@@ -1,6 +1,4 @@
/*
- *
- *
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
* Copyright (C) 2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
@@ -15,15 +13,14 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#if !defined(_ISL_OID_H)
#define _ISL_OID_H
-/*
+/*
* MIB related constant and structure definitions for communicating
* with the device firmware
*/
@@ -31,20 +28,20 @@
struct obj_ssid {
u8 length;
char octets[33];
-} __attribute__ ((packed));
+} __packed;
struct obj_key {
u8 type; /* dot11_priv_t */
u8 length;
char key[32];
-} __attribute__ ((packed));
+} __packed;
struct obj_mlme {
u8 address[6];
u16 id;
u16 state;
u16 code;
-} __attribute__ ((packed));
+} __packed;
struct obj_mlmeex {
u8 address[6];
@@ -53,12 +50,12 @@ struct obj_mlmeex {
u16 code;
u16 size;
u8 data[0];
-} __attribute__ ((packed));
+} __packed;
struct obj_buffer {
u32 size;
u32 addr; /* 32bit bus address */
-} __attribute__ ((packed));
+} __packed;
struct obj_bss {
u8 address[6];
@@ -79,17 +76,17 @@ struct obj_bss {
short rates;
short basic_rates;
int:16; /* padding */
-} __attribute__ ((packed));
+} __packed;
struct obj_bsslist {
u32 nr;
struct obj_bss bsslist[0];
-} __attribute__ ((packed));
+} __packed;
struct obj_frequencies {
u16 nr;
u16 mhz[0];
-} __attribute__ ((packed));
+} __packed;
struct obj_attachment {
char type;
@@ -97,23 +94,23 @@ struct obj_attachment {
short id;
short size;
char data[0];
-} __attribute__((packed));
+} __packed;
-/*
+/*
* in case everything's ok, the inlined function below will be
* optimized away by the compiler...
*/
static inline void
__bug_on_wrong_struct_sizes(void)
{
- BUG_ON(sizeof (struct obj_ssid) != 34);
- BUG_ON(sizeof (struct obj_key) != 34);
- BUG_ON(sizeof (struct obj_mlme) != 12);
- BUG_ON(sizeof (struct obj_mlmeex) != 14);
- BUG_ON(sizeof (struct obj_buffer) != 8);
- BUG_ON(sizeof (struct obj_bss) != 60);
- BUG_ON(sizeof (struct obj_bsslist) != 4);
- BUG_ON(sizeof (struct obj_frequencies) != 2);
+ BUILD_BUG_ON(sizeof (struct obj_ssid) != 34);
+ BUILD_BUG_ON(sizeof (struct obj_key) != 34);
+ BUILD_BUG_ON(sizeof (struct obj_mlme) != 12);
+ BUILD_BUG_ON(sizeof (struct obj_mlmeex) != 14);
+ BUILD_BUG_ON(sizeof (struct obj_buffer) != 8);
+ BUILD_BUG_ON(sizeof (struct obj_bss) != 60);
+ BUILD_BUG_ON(sizeof (struct obj_bsslist) != 4);
+ BUILD_BUG_ON(sizeof (struct obj_frequencies) != 2);
}
enum dot11_state_t {
@@ -154,13 +151,13 @@ enum dot11_priv_t {
/* Prism "Nitro" / Frameburst / "Packet Frame Grouping"
* Value is in microseconds. Represents the # microseconds
- * the firmware will take to group frames before sending out then out
+ * the firmware will take to group frames before sending out then out
* together with a CSMA contention. Without this all frames are
- * sent with a CSMA contention.
- * Bibliography:
+ * sent with a CSMA contention.
+ * Bibliography:
* http://www.hpl.hp.com/personal/Jean_Tourrilhes/Papers/Packet.Frame.Grouping.html
*/
-enum dot11_maxframeburst_t {
+enum dot11_maxframeburst_t {
/* Values for DOT11_OID_MAXFRAMEBURST */
DOT11_MAXFRAMEBURST_OFF = 0, /* Card firmware default */
DOT11_MAXFRAMEBURST_MIXED_SAFE = 650, /* 802.11 a,b,g safe */
@@ -176,9 +173,9 @@ enum dot11_maxframeburst_t {
/* Support for 802.11 long and short frame preambles.
* Long preamble uses 128-bit sync field, 8-bit CRC
* Short preamble uses 56-bit sync field, 16-bit CRC
- *
+ *
* 802.11a -- not sure, both optionally ?
- * 802.11b supports long and optionally short
+ * 802.11b supports long and optionally short
* 802.11g supports both */
enum dot11_preamblesettings_t {
DOT11_PREAMBLESETTING_LONG = 0,
@@ -194,7 +191,7 @@ enum dot11_preamblesettings_t {
* Long uses 802.11a slot timing (9 usec ?)
* Short uses 802.11b slot timing (20 use ?) */
enum dot11_slotsettings_t {
- DOT11_SLOTSETTINGS_LONG = 0,
+ DOT11_SLOTSETTINGS_LONG = 0,
/* Allows *only* long 802.11b slot timing */
DOT11_SLOTSETTINGS_SHORT = 1,
/* Allows *only* long 802.11a slot timing */
@@ -203,7 +200,7 @@ enum dot11_slotsettings_t {
};
/* All you need to know, ERP is "Extended Rate PHY".
- * An Extended Rate PHY (ERP) STA or AP shall support three different
+ * An Extended Rate PHY (ERP) STA or AP shall support three different
* preamble and header formats:
* Long preamble (refer to above)
* Short preamble (refer to above)
@@ -221,7 +218,7 @@ enum do11_nonerpstatus_t {
/* (ERP is "Extended Rate PHY") Way to read NONERP is NON-ERP-*
* The key here is DOT11 NON ERP NEVER protects against
* NON ERP STA's. You *don't* want this unless
- * you know what you are doing. It means you will only
+ * you know what you are doing. It means you will only
* get Extended Rate capabilities */
enum dot11_nonerpprotection_t {
DOT11_NONERP_NEVER = 0,
@@ -229,13 +226,13 @@ enum dot11_nonerpprotection_t {
DOT11_NONERP_DYNAMIC = 2
};
-/* Preset OID configuration for 802.11 modes
- * Note: DOT11_OID_CW[MIN|MAX] hold the values of the
+/* Preset OID configuration for 802.11 modes
+ * Note: DOT11_OID_CW[MIN|MAX] hold the values of the
* DCS MIN|MAX backoff used */
enum dot11_profile_t { /* And set/allowed values */
/* Allowed values for DOT11_OID_PROFILES */
DOT11_PROFILE_B_ONLY = 0,
- /* DOT11_OID_RATES: 1, 2, 5.5, 11Mbps
+ /* DOT11_OID_RATES: 1, 2, 5.5, 11Mbps
* DOT11_OID_PREAMBLESETTINGS: DOT11_PREAMBLESETTING_DYNAMIC
* DOT11_OID_CWMIN: 31
* DOT11_OID_NONEPROTECTION: DOT11_NOERP_DYNAMIC
@@ -275,7 +272,7 @@ enum oid_inl_conformance_t {
OID_INL_CONFORMANCE_NONE = 0, /* Perform active scanning */
OID_INL_CONFORMANCE_STRICT = 1, /* Strictly adhere to 802.11d */
OID_INL_CONFORMANCE_FLEXIBLE = 2, /* Use passed 802.11d info to
- * determine channel AND/OR just make assumption that active
+ * determine channel AND/OR just make assumption that active
* channels are valid channels */
};
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 5ddf2959903..931cf440ff1 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -1,5 +1,4 @@
/*
- *
* Copyright (C) 2002 Intersil Americas Inc.
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
* Copyright (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
@@ -14,15 +13,18 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
+#include <linux/hardirq.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/netdevice.h>
+#include <linux/ethtool.h>
#include <linux/pci.h>
+#include <linux/sched.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
#include <linux/if_arp.h>
@@ -40,10 +42,12 @@
#define ISL3877_IMAGE_FILE "isl3877"
#define ISL3886_IMAGE_FILE "isl3886"
#define ISL3890_IMAGE_FILE "isl3890"
+MODULE_FIRMWARE(ISL3877_IMAGE_FILE);
+MODULE_FIRMWARE(ISL3886_IMAGE_FILE);
+MODULE_FIRMWARE(ISL3890_IMAGE_FILE);
static int prism54_bring_down(islpci_private *);
static int islpci_alloc_memory(islpci_private *);
-static struct net_device_stats *islpci_statistics(struct net_device *);
/* Temporary dummy MAC address to use until firmware is loaded.
* The idea there is that some tools (such as nameif) may query
@@ -115,7 +119,7 @@ isl_upload_firmware(islpci_private *priv)
ISL38XX_MEMORY_WINDOW_SIZE : fw_len;
u32 __iomem *dev_fw_ptr = device_base + ISL38XX_DIRECT_MEM_WIN;
- /* set the cards base address for writting the data */
+ /* set the card's base address for writing the data */
isl38xx_w32_flush(device_base, reg,
ISL38XX_DIR_MEM_BASE_REG);
wmb(); /* be paranoid */
@@ -182,7 +186,7 @@ isl_upload_firmware(islpci_private *priv)
******************************************************************************/
irqreturn_t
-islpci_interrupt(int irq, void *config, struct pt_regs *regs)
+islpci_interrupt(int irq, void *config)
{
u32 reg;
islpci_private *priv = config;
@@ -224,14 +228,14 @@ islpci_interrupt(int irq, void *config, struct pt_regs *regs)
#if VERBOSE > SHOW_ERROR_MESSAGES
DEBUG(SHOW_FUNCTION_CALLS,
- "IRQ: Identification register 0x%p 0x%x \n", device, reg);
+ "IRQ: Identification register 0x%p 0x%x\n", device, reg);
#endif
/* check for each bit in the register separately */
if (reg & ISL38XX_INT_IDENT_UPDATE) {
#if VERBOSE > SHOW_ERROR_MESSAGES
/* Queue has been updated */
- DEBUG(SHOW_TRACING, "IRQ: Update flag \n");
+ DEBUG(SHOW_TRACING, "IRQ: Update flag\n");
DEBUG(SHOW_QUEUE_INDEXES,
"CB drv Qs: [%i][%i][%i][%i][%i][%i]\n",
@@ -297,7 +301,7 @@ islpci_interrupt(int irq, void *config, struct pt_regs *regs)
ISL38XX_CB_RX_DATA_LQ) != 0) {
#if VERBOSE > SHOW_ERROR_MESSAGES
DEBUG(SHOW_TRACING,
- "Received frame in Data Low Queue \n");
+ "Received frame in Data Low Queue\n");
#endif
islpci_eth_receive(priv);
}
@@ -322,7 +326,7 @@ islpci_interrupt(int irq, void *config, struct pt_regs *regs)
/* Device has been initialized */
#if VERBOSE > SHOW_ERROR_MESSAGES
DEBUG(SHOW_TRACING,
- "IRQ: Init flag, device initialized \n");
+ "IRQ: Init flag, device initialized\n");
#endif
wake_up(&priv->reset_done);
}
@@ -330,7 +334,7 @@ islpci_interrupt(int irq, void *config, struct pt_regs *regs)
if (reg & ISL38XX_INT_IDENT_SLEEP) {
/* Device intends to move to powersave state */
#if VERBOSE > SHOW_ERROR_MESSAGES
- DEBUG(SHOW_TRACING, "IRQ: Sleep flag \n");
+ DEBUG(SHOW_TRACING, "IRQ: Sleep flag\n");
#endif
isl38xx_handle_sleep_request(priv->control_block,
&powerstate,
@@ -340,7 +344,7 @@ islpci_interrupt(int irq, void *config, struct pt_regs *regs)
if (reg & ISL38XX_INT_IDENT_WAKEUP) {
/* Device has been woken up to active state */
#if VERBOSE > SHOW_ERROR_MESSAGES
- DEBUG(SHOW_TRACING, "IRQ: Wakeup flag \n");
+ DEBUG(SHOW_TRACING, "IRQ: Wakeup flag\n");
#endif
isl38xx_handle_wakeup(priv->control_block,
@@ -387,7 +391,16 @@ islpci_open(struct net_device *ndev)
}
netif_start_queue(ndev);
-/* netif_mark_up( ndev ); */
+
+ /* Turn off carrier if in STA or Ad-hoc mode. It will be turned on
+ * once the firmware receives a trap of being associated
+ * (GEN_OID_LINKSTATE). In other modes (AP or WDS or monitor) we
+ * should just leave the carrier on as its expected the firmware
+ * won't send us a trigger. */
+ if (priv->iw_mode == IW_MODE_INFRA || priv->iw_mode == IW_MODE_ADHOC)
+ netif_carrier_off(ndev);
+ else
+ netif_carrier_on(ndev);
return 0;
}
@@ -413,7 +426,7 @@ prism54_bring_down(islpci_private *priv)
islpci_set_state(priv, PRV_STATE_PREBOOT);
/* disable all device interrupts in case they weren't */
- isl38xx_disable_interrupts(priv->device_base);
+ isl38xx_disable_interrupts(priv->device_base);
/* For safety reasons, we may want to ensure that no DMA transfer is
* currently in progress by emptying the TX and RX queues. */
@@ -480,7 +493,7 @@ islpci_reset_if(islpci_private *priv)
DEFINE_WAIT(wait);
prepare_to_wait(&priv->reset_done, &wait, TASK_UNINTERRUPTIBLE);
-
+
/* now the last step is to reset the interface */
isl38xx_interface_reset(priv->device_base, priv->device_host_address);
islpci_set_state(priv, PRV_STATE_PREINIT);
@@ -488,7 +501,7 @@ islpci_reset_if(islpci_private *priv)
for(count = 0; count < 2 && result; count++) {
/* The software reset acknowledge needs about 220 msec here.
* Be conservative and wait for up to one second. */
-
+
remaining = schedule_timeout_uninterruptible(HZ);
if(remaining > 0) {
@@ -496,7 +509,7 @@ islpci_reset_if(islpci_private *priv)
break;
}
- /* If we're here it's because our IRQ hasn't yet gone through.
+ /* If we're here it's because our IRQ hasn't yet gone through.
* Retry a bit more...
*/
printk(KERN_ERR "%s: no 'reset complete' IRQ seen - retrying\n",
@@ -514,7 +527,7 @@ islpci_reset_if(islpci_private *priv)
/* Now that the device is 100% up, let's allow
* for the other interrupts --
- * NOTE: this is not *yet* true since we've only allowed the
+ * NOTE: this is not *yet* true since we've only allowed the
* INIT interrupt on the IRQ line. We can perhaps poll
* the IRQ line until we know for sure the reset went through */
isl38xx_enable_common_interrupts(priv->device_base);
@@ -605,18 +618,6 @@ islpci_reset(islpci_private *priv, int reload_firmware)
return rc;
}
-static struct net_device_stats *
-islpci_statistics(struct net_device *ndev)
-{
- islpci_private *priv = netdev_priv(ndev);
-
-#if VERBOSE > SHOW_ERROR_MESSAGES
- DEBUG(SHOW_FUNCTION_CALLS, "islpci_statistics\n");
-#endif
-
- return &priv->statistics;
-}
-
/******************************************************************************
Network device configuration functions
******************************************************************************/
@@ -629,12 +630,12 @@ islpci_alloc_memory(islpci_private *priv)
printk(KERN_DEBUG "islpci_alloc_memory\n");
#endif
- /* remap the PCI device base address to accessable */
+ /* remap the PCI device base address to accessible */
if (!(priv->device_base =
ioremap(pci_resource_start(priv->pdev, 0),
ISL38XX_PCI_MEM_SIZE))) {
/* error in remapping the PCI device memory address range */
- printk(KERN_ERR "PCI memory remapping failed \n");
+ printk(KERN_ERR "PCI memory remapping failed\n");
return -1;
}
@@ -708,15 +709,15 @@ islpci_alloc_memory(islpci_private *priv)
PCI_DMA_FROMDEVICE);
if (!priv->pci_map_rx_address[counter]) {
/* error mapping the buffer to device
- accessable memory address */
+ accessible memory address */
printk(KERN_ERR "failed to map skb DMA'able\n");
goto out_free;
}
}
prism54_acl_init(&priv->acl);
- prism54_wpa_ie_init(priv);
- if (mgt_init(priv))
+ prism54_wpa_bss_ie_init(priv);
+ if (mgt_init(priv))
goto out_free;
return 0;
@@ -772,9 +773,9 @@ islpci_free_memory(islpci_private *priv)
priv->data_low_rx[counter] = NULL;
}
- /* Free the acces control list and the WPA list */
+ /* Free the access control list and the WPA list */
prism54_acl_clean(&priv->acl);
- prism54_wpa_ie_clean(priv);
+ prism54_wpa_bss_ie_clean(priv);
mgt_clean(priv);
return 0;
@@ -788,6 +789,31 @@ islpci_set_multicast_list(struct net_device *dev)
}
#endif
+static void islpci_ethtool_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_VERSION, sizeof(info->version));
+}
+
+static const struct ethtool_ops islpci_ethtool_ops = {
+ .get_drvinfo = islpci_ethtool_get_drvinfo,
+};
+
+static const struct net_device_ops islpci_netdev_ops = {
+ .ndo_open = islpci_open,
+ .ndo_stop = islpci_close,
+ .ndo_start_xmit = islpci_eth_transmit,
+ .ndo_tx_timeout = islpci_eth_tx_timeout,
+ .ndo_set_mac_address = prism54_set_mac_address,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+static struct device_type wlan_type = {
+ .name = "wlan",
+};
+
struct net_device *
islpci_setup(struct pci_dev *pdev)
{
@@ -797,35 +823,25 @@ islpci_setup(struct pci_dev *pdev)
if (!ndev)
return ndev;
- SET_MODULE_OWNER(ndev);
pci_set_drvdata(pdev, ndev);
-#if defined(SET_NETDEV_DEV)
SET_NETDEV_DEV(ndev, &pdev->dev);
-#endif
+ SET_NETDEV_DEVTYPE(ndev, &wlan_type);
/* setup the structure members */
ndev->base_addr = pci_resource_start(pdev, 0);
ndev->irq = pdev->irq;
/* initialize the function pointers */
- ndev->open = &islpci_open;
- ndev->stop = &islpci_close;
- ndev->get_stats = &islpci_statistics;
- ndev->do_ioctl = &prism54_ioctl;
- ndev->wireless_handlers =
- (struct iw_handler_def *) &prism54_handler_def;
-
- ndev->hard_start_xmit = &islpci_eth_transmit;
+ ndev->netdev_ops = &islpci_netdev_ops;
+ ndev->wireless_handlers = &prism54_handler_def;
+ ndev->ethtool_ops = &islpci_ethtool_ops;
+
/* ndev->set_multicast_list = &islpci_set_multicast_list; */
ndev->addr_len = ETH_ALEN;
- ndev->set_mac_address = &prism54_set_mac_address;
/* Get a non-zero dummy MAC address for nameif. Jean II */
- memcpy(ndev->dev_addr, dummy_mac, 6);
+ memcpy(ndev->dev_addr, dummy_mac, ETH_ALEN);
-#ifdef HAVE_TX_TIMEOUT
ndev->watchdog_timeo = ISLPCI_TX_TIMEOUT;
- ndev->tx_timeout = &islpci_eth_tx_timeout;
-#endif
/* allocate a private device structure to the network device */
priv = netdev_priv(ndev);
@@ -850,10 +866,10 @@ islpci_setup(struct pci_dev *pdev)
init_waitqueue_head(&priv->reset_done);
/* init the queue read locks, process wait counter */
- sema_init(&priv->mgmt_sem, 1);
+ mutex_init(&priv->mgmt_lock);
priv->mgmt_received = NULL;
init_waitqueue_head(&priv->mgmt_wqueue);
- sema_init(&priv->stats_sem, 1);
+ mutex_init(&priv->stats_lock);
spin_lock_init(&priv->slock);
/* init state machine with off#1 state */
@@ -861,11 +877,10 @@ islpci_setup(struct pci_dev *pdev)
priv->state_off = 1;
/* initialize workqueue's */
- INIT_WORK(&priv->stats_work,
- (void (*)(void *)) prism54_update_stats, priv);
+ INIT_WORK(&priv->stats_work, prism54_update_stats);
priv->stats_timestamp = 0;
- INIT_WORK(&priv->reset_task, islpci_do_reset_and_wake, priv);
+ INIT_WORK(&priv->reset_task, islpci_do_reset_and_wake);
priv->reset_task_pending = 0;
/* allocate various memory areas */
@@ -889,7 +904,7 @@ islpci_setup(struct pci_dev *pdev)
if (register_netdev(ndev)) {
DEBUG(SHOW_ERROR_MESSAGES,
- "ERROR: register_netdev() failed \n");
+ "ERROR: register_netdev() failed\n");
goto do_islpci_free_memory;
}
@@ -898,7 +913,6 @@ islpci_setup(struct pci_dev *pdev)
do_islpci_free_memory:
islpci_free_memory(priv);
do_free_netdev:
- pci_set_drvdata(pdev, NULL);
free_netdev(ndev);
priv = NULL;
return NULL;
@@ -933,7 +947,7 @@ islpci_set_state(islpci_private *priv, islpci_state_t new_state)
if (!priv->state_off)
priv->state = new_state;
break;
- };
+ }
#if 0
printk(KERN_DEBUG "%s: state transition %d -> %d (off#%d)\n",
priv->ndev->name, old_state, new_state, priv->state_off);
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
index 07053165e4c..f6f088e05fe 100644
--- a/drivers/net/wireless/prism54/islpci_dev.h
+++ b/drivers/net/wireless/prism54/islpci_dev.h
@@ -1,6 +1,5 @@
/*
- *
- * Copyright (C) 2002 Intersil Americas Inc.
+ * Copyright (C) 2002 Intersil Americas Inc.
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
* Copyright (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
* Copyright (C) 2003 Aurelien Alleaume <slts@free.fr>
@@ -15,18 +14,19 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef _ISLPCI_DEV_H
#define _ISLPCI_DEV_H
+#include <linux/irqreturn.h>
#include <linux/netdevice.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>
#include <linux/list.h>
+#include <linux/mutex.h>
#include "isl_38xx.h"
#include "isl_oid.h"
@@ -55,7 +55,7 @@ struct islpci_acl {
enum { MAC_POLICY_OPEN=0, MAC_POLICY_ACCEPT=1, MAC_POLICY_REJECT=2 } policy;
struct list_head mac_list; /* a list of mac_entry */
int size; /* size of queue */
- struct semaphore sem; /* accessed in ioctls and trap_work */
+ struct mutex lock; /* accessed in ioctls and trap_work */
};
struct islpci_membuf {
@@ -72,12 +72,12 @@ struct islpci_bss_wpa_ie {
u8 bssid[ETH_ALEN];
u8 wpa_ie[MAX_WPA_IE_LEN];
size_t wpa_ie_len;
-
+
};
typedef struct {
spinlock_t slock; /* generic spinlock; */
-
+
u32 priv_oid;
/* our mib cache */
@@ -85,10 +85,10 @@ typedef struct {
struct rw_semaphore mib_sem;
void **mib;
char nickname[IW_ESSID_MAX_SIZE+1];
-
+
/* Take care of the wireless stats */
struct work_struct stats_work;
- struct semaphore stats_sem;
+ struct mutex stats_lock;
/* remember when we last updated the stats */
unsigned long stats_timestamp;
/* The first is accessed under semaphore locking.
@@ -120,7 +120,7 @@ typedef struct {
struct net_device *ndev;
/* device queue interface members */
- struct isl38xx_cb *control_block; /* device control block
+ struct isl38xx_cb *control_block; /* device control block
(== driver_mem_address!) */
/* Each queue has three indexes:
@@ -158,14 +158,11 @@ typedef struct {
dma_addr_t pci_map_tx_address[ISL38XX_CB_TX_QSIZE];
dma_addr_t pci_map_rx_address[ISL38XX_CB_RX_QSIZE];
- /* driver network interface members */
- struct net_device_stats statistics;
-
/* wait for a reset interrupt */
wait_queue_head_t reset_done;
/* used by islpci_mgt_transaction */
- struct semaphore mgmt_sem; /* serialize access to mailbox and wqueue */
+ struct mutex mgmt_lock; /* serialize access to mailbox and wqueue */
struct islpci_mgmtframe *mgmt_received; /* mbox for incoming frame */
wait_queue_head_t mgmt_wqueue; /* waitqueue for mbox */
@@ -178,7 +175,9 @@ typedef struct {
int wpa; /* WPA mode enabled */
struct list_head bss_wpa_list;
int num_bss_wpa;
- struct semaphore wpa_sem;
+ struct mutex wpa_lock;
+ u8 wpa_ie[MAX_WPA_IE_LEN];
+ size_t wpa_ie_len;
struct work_struct reset_task;
int reset_task_pending;
@@ -196,7 +195,7 @@ islpci_state_t islpci_set_state(islpci_private *priv, islpci_state_t new_state);
#define ISLPCI_TX_TIMEOUT (2*HZ)
-irqreturn_t islpci_interrupt(int, void *, struct pt_regs *);
+irqreturn_t islpci_interrupt(int, void *);
int prism54_post_setup(islpci_private *, int);
int islpci_reset(islpci_private *, int);
@@ -210,4 +209,8 @@ islpci_trigger(islpci_private *priv)
int islpci_free_memory(islpci_private *);
struct net_device *islpci_setup(struct pci_dev *);
+
+#define DRV_NAME "prism54"
+#define DRV_VERSION "1.2"
+
#endif /* _ISLPCI_DEV_H */
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 33d64d2ee53..674658f2e6e 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -1,5 +1,4 @@
/*
- *
* Copyright (C) 2002 Intersil Americas Inc.
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
* This program is free software; you can redistribute it and/or modify
@@ -12,18 +11,19 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
+#include <asm/byteorder.h>
#include "prismcompat.h"
#include "isl_38xx.h"
@@ -48,9 +48,9 @@ islpci_eth_cleanup_transmit(islpci_private *priv,
/* read the index of the first fragment to be freed */
index = priv->free_data_tx % ISL38XX_CB_TX_QSIZE;
- /* check for holes in the arrays caused by multi fragment frames
+ /* check for holes in the arrays caused by multi fragment frames
* searching for the last fragment of a frame */
- if (priv->pci_map_tx_address[index] != (dma_addr_t) NULL) {
+ if (priv->pci_map_tx_address[index]) {
/* entry is the last fragment of a frame
* free the skb structure and unmap pci memory */
skb = priv->data_low_tx[index];
@@ -72,7 +72,7 @@ islpci_eth_cleanup_transmit(islpci_private *priv,
}
}
-int
+netdev_tx_t
islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
{
islpci_private *priv = netdev_priv(ndev);
@@ -87,10 +87,9 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
unsigned long flags;
unsigned char wds_mac[6];
u32 curr_frag;
- int err = 0;
#if VERBOSE > SHOW_ERROR_MESSAGES
- DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_transmit \n");
+ DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_transmit\n");
#endif
/* lock the driver code */
@@ -107,15 +106,13 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
isl38xx_w32_flush(priv->device_base, ISL38XX_DEV_INT_UPDATE,
ISL38XX_DEV_INT_REG);
udelay(ISL38XX_WRITEIO_DELAY);
-
- err = -EBUSY;
goto drop_free;
}
/* Check alignment and WDS frame formatting. The start of the packet should
* be aligned on a 4-byte boundary. If WDS is enabled add another 6 bytes
* and add WDS address information */
if (likely(((long) skb->data & 0x03) | init_wds)) {
- /* get the number of bytes to add and re-allign */
+ /* get the number of bytes to add and re-align */
offset = (4 - (long) skb->data) & 0x03;
offset += init_wds ? 6 : 0;
@@ -137,13 +134,13 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
printk("islpci_eth_transmit:wds_mac\n");
#endif
memmove(skb->data + 6, src, skb->len);
- memcpy(skb->data, wds_mac, 6);
+ skb_copy_to_linear_data(skb, wds_mac, 6);
} else {
memmove(skb->data, src, skb->len);
}
#if VERBOSE > SHOW_ERROR_MESSAGES
- DEBUG(SHOW_TRACING, "memmove %p %p %i \n", skb->data,
+ DEBUG(SHOW_TRACING, "memmove %p %p %i\n", skb->data,
src, skb->len);
#endif
} else {
@@ -152,7 +149,6 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
if (unlikely(newskb == NULL)) {
printk(KERN_ERR "%s: Cannot allocate skb\n",
ndev->name);
- err = -ENOMEM;
goto drop_free;
}
newskb_offset = (4 - (long) newskb->data) & 0x03;
@@ -163,13 +159,16 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
skb_put(newskb, init_wds ? skb->len + 6 : skb->len);
if (init_wds) {
- memcpy(newskb->data + 6, skb->data, skb->len);
- memcpy(newskb->data, wds_mac, 6);
+ skb_copy_from_linear_data(skb,
+ newskb->data + 6,
+ skb->len);
+ skb_copy_to_linear_data(newskb, wds_mac, 6);
#ifdef ISLPCI_ETH_DEBUG
printk("islpci_eth_transmit:wds_mac\n");
#endif
} else
- memcpy(newskb->data, skb->data, skb->len);
+ skb_copy_from_linear_data(skb, newskb->data,
+ skb->len);
#if VERBOSE > SHOW_ERROR_MESSAGES
DEBUG(SHOW_TRACING, "memcpy %p %p %i wds %i\n",
@@ -177,7 +176,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
#endif
newskb->dev = skb->dev;
- dev_kfree_skb(skb);
+ dev_kfree_skb_irq(skb);
skb = newskb;
}
}
@@ -194,8 +193,6 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
if (unlikely(pci_map_address == 0)) {
printk(KERN_WARNING "%s: cannot map buffer to PCI\n",
ndev->name);
-
- err = -EIO;
goto drop_free;
}
/* Place the fragment in the control block structure. */
@@ -226,10 +223,8 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
priv->data_low_tx_full = 1;
}
- /* set the transmission time */
- ndev->trans_start = jiffies;
- priv->statistics.tx_packets++;
- priv->statistics.tx_bytes += skb->len;
+ ndev->stats.tx_packets++;
+ ndev->stats.tx_bytes += skb->len;
/* trigger the device */
islpci_trigger(priv);
@@ -237,13 +232,13 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
/* unlock the driver code */
spin_unlock_irqrestore(&priv->slock, flags);
- return 0;
+ return NETDEV_TX_OK;
drop_free:
- priv->statistics.tx_dropped++;
+ ndev->stats.tx_dropped++;
spin_unlock_irqrestore(&priv->slock, flags);
dev_kfree_skb(skb);
- return err;
+ return NETDEV_TX_OK;
}
static inline int
@@ -253,6 +248,7 @@ islpci_monitor_rx(islpci_private *priv, struct sk_buff **skb)
* header and without the FCS. But there a is a bit that
* indicates if the packet is corrupted :-) */
struct rfmon_header *hdr = (struct rfmon_header *) (*skb)->data;
+
if (hdr->flags & 0x01)
/* This one is bad. Drop it ! */
return -1;
@@ -284,10 +280,10 @@ islpci_monitor_rx(islpci_private *priv, struct sk_buff **skb)
(struct avs_80211_1_header *) skb_push(*skb,
sizeof (struct
avs_80211_1_header));
-
+
avs->version = cpu_to_be32(P80211CAPTURE_VERSION);
avs->length = cpu_to_be32(sizeof (struct avs_80211_1_header));
- avs->mactime = cpu_to_be64(le64_to_cpu(clock));
+ avs->mactime = cpu_to_be64(clock);
avs->hosttime = cpu_to_be64(jiffies);
avs->phytype = cpu_to_be32(6); /*OFDM: 6 for (g), 8 for (a) */
avs->channel = cpu_to_be32(channel_of_freq(freq));
@@ -303,7 +299,7 @@ islpci_monitor_rx(islpci_private *priv, struct sk_buff **skb)
skb_pull(*skb, sizeof (struct rfmon_header));
(*skb)->protocol = htons(ETH_P_802_2);
- (*skb)->mac.raw = (*skb)->data;
+ skb_reset_mac_header(*skb);
(*skb)->pkt_type = PACKET_OTHERHOST;
return 0;
@@ -321,7 +317,7 @@ islpci_eth_receive(islpci_private *priv)
int discard = 0;
#if VERBOSE > SHOW_ERROR_MESSAGES
- DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_receive \n");
+ DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_receive\n");
#endif
/* the device has written an Ethernet frame in the data area
@@ -345,7 +341,7 @@ islpci_eth_receive(islpci_private *priv)
priv->pci_map_rx_address[index],
MAX_FRAGMENT_SIZE_RX + 2, PCI_DMA_FROMDEVICE);
- /* update the skb structure and allign the buffer */
+ /* update the skb structure and align the buffer */
skb_put(skb, size);
if (offset) {
/* shift the buffer allocation offset bytes to get the right frame */
@@ -374,14 +370,11 @@ islpci_eth_receive(islpci_private *priv)
DEBUG(SHOW_BUFFER_CONTENTS, "\nrx %p ", skb->data);
display_buffer((char *) skb->data, skb->len);
#endif
-
- /* do some additional sk_buff and network layer parameters */
- skb->dev = ndev;
-
/* take care of monitor mode and spy monitoring. */
- if (unlikely(priv->iw_mode == IW_MODE_MONITOR))
+ if (unlikely(priv->iw_mode == IW_MODE_MONITOR)) {
+ skb->dev = ndev;
discard = islpci_monitor_rx(priv, &skb);
- else {
+ } else {
if (unlikely(skb->data[2 * ETH_ALEN] == 0)) {
/* The packet has a rx_annex. Read it for spy monitoring, Then
* remove it, while keeping the 2 leading MAC addr.
@@ -390,7 +383,7 @@ islpci_eth_receive(islpci_private *priv)
struct rx_annex_header *annex =
(struct rx_annex_header *) skb->data;
wstats.level = annex->rfmon.rssi;
- /* The noise value can be a bit outdated if nobody's
+ /* The noise value can be a bit outdated if nobody's
* reading wireless stats... */
wstats.noise = priv->local_iwstatistics.qual.noise;
wstats.qual = wstats.level - wstats.noise;
@@ -398,15 +391,17 @@ islpci_eth_receive(islpci_private *priv)
/* Update spy records */
wireless_spy_update(ndev, annex->addr2, &wstats);
- memcpy(skb->data + sizeof (struct rfmon_header),
- skb->data, 2 * ETH_ALEN);
+ skb_copy_from_linear_data(skb,
+ (skb->data +
+ sizeof(struct rfmon_header)),
+ 2 * ETH_ALEN);
skb_pull(skb, sizeof (struct rfmon_header));
}
skb->protocol = eth_type_trans(skb, ndev);
}
skb->ip_summed = CHECKSUM_NONE;
- priv->statistics.rx_packets++;
- priv->statistics.rx_bytes += size;
+ ndev->stats.rx_packets++;
+ ndev->stats.rx_bytes += size;
/* deliver the skb to the network layer */
#ifdef ISLPCI_ETH_DEBUG
@@ -434,7 +429,7 @@ islpci_eth_receive(islpci_private *priv)
skb = dev_alloc_skb(MAX_FRAGMENT_SIZE_RX + 2);
if (unlikely(skb == NULL)) {
/* error allocating an sk_buff structure elements */
- DEBUG(SHOW_ERROR_MESSAGES, "Error allocating skb \n");
+ DEBUG(SHOW_ERROR_MESSAGES, "Error allocating skb\n");
break;
}
skb_reserve(skb, (4 - (long) skb->data) & 0x03);
@@ -453,26 +448,24 @@ islpci_eth_receive(islpci_private *priv)
pci_map_single(priv->pdev, (void *) skb->data,
MAX_FRAGMENT_SIZE_RX + 2,
PCI_DMA_FROMDEVICE);
- if (unlikely(priv->pci_map_rx_address[index] == (dma_addr_t) NULL)) {
- /* error mapping the buffer to device accessable memory address */
+ if (unlikely(!priv->pci_map_rx_address[index])) {
+ /* error mapping the buffer to device accessible memory address */
DEBUG(SHOW_ERROR_MESSAGES,
"Error mapping DMA address\n");
/* free the skbuf structure before aborting */
- dev_kfree_skb_irq((struct sk_buff *) skb);
+ dev_kfree_skb_irq(skb);
skb = NULL;
break;
}
/* update the fragment address */
- control_block->rx_data_low[index].address = cpu_to_le32((u32)
- priv->
- pci_map_rx_address
- [index]);
+ control_block->rx_data_low[index].address =
+ cpu_to_le32((u32)priv->pci_map_rx_address[index]);
wmb();
/* increment the driver read pointer */
- add_le32p((u32 *) &control_block->
- driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1);
+ le32_add_cpu(&control_block->
+ driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1);
}
/* trigger the device */
@@ -482,29 +475,32 @@ islpci_eth_receive(islpci_private *priv)
}
void
-islpci_do_reset_and_wake(void *data)
+islpci_do_reset_and_wake(struct work_struct *work)
{
- islpci_private *priv = (islpci_private *) data;
+ islpci_private *priv = container_of(work, islpci_private, reset_task);
+
islpci_reset(priv, 1);
- netif_wake_queue(priv->ndev);
priv->reset_task_pending = 0;
+ smp_wmb();
+ netif_wake_queue(priv->ndev);
}
void
islpci_eth_tx_timeout(struct net_device *ndev)
{
islpci_private *priv = netdev_priv(ndev);
- struct net_device_stats *statistics = &priv->statistics;
/* increment the transmit error counter */
- statistics->tx_errors++;
+ ndev->stats.tx_errors++;
- printk(KERN_WARNING "%s: tx_timeout", ndev->name);
if (!priv->reset_task_pending) {
- priv->reset_task_pending = 1;
- printk(", scheduling a reset");
+ printk(KERN_WARNING
+ "%s: tx_timeout, scheduling reset", ndev->name);
netif_stop_queue(ndev);
+ priv->reset_task_pending = 1;
schedule_work(&priv->reset_task);
+ } else {
+ printk(KERN_WARNING
+ "%s: tx_timeout, waiting for reset", ndev->name);
}
- printk("\n");
}
diff --git a/drivers/net/wireless/prism54/islpci_eth.h b/drivers/net/wireless/prism54/islpci_eth.h
index bc9d7a60b8d..80f50f1bc6f 100644
--- a/drivers/net/wireless/prism54/islpci_eth.h
+++ b/drivers/net/wireless/prism54/islpci_eth.h
@@ -1,5 +1,4 @@
/*
- *
* Copyright (C) 2002 Intersil Americas Inc.
*
* This program is free software; you can redistribute it and/or modify
@@ -12,8 +11,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
@@ -24,50 +22,50 @@
#include "islpci_dev.h"
struct rfmon_header {
- u16 unk0; /* = 0x0000 */
- u16 length; /* = 0x1400 */
- u32 clock; /* 1MHz clock */
+ __le16 unk0; /* = 0x0000 */
+ __le16 length; /* = 0x1400 */
+ __le32 clock; /* 1MHz clock */
u8 flags;
u8 unk1;
u8 rate;
u8 unk2;
- u16 freq;
- u16 unk3;
+ __le16 freq;
+ __le16 unk3;
u8 rssi;
u8 padding[3];
-} __attribute__ ((packed));
+} __packed;
struct rx_annex_header {
u8 addr1[ETH_ALEN];
u8 addr2[ETH_ALEN];
struct rfmon_header rfmon;
-} __attribute__ ((packed));
+} __packed;
/* wlan-ng (and hopefully others) AVS header, version one. Fields in
* network byte order. */
#define P80211CAPTURE_VERSION 0x80211001
struct avs_80211_1_header {
- uint32_t version;
- uint32_t length;
- uint64_t mactime;
- uint64_t hosttime;
- uint32_t phytype;
- uint32_t channel;
- uint32_t datarate;
- uint32_t antenna;
- uint32_t priority;
- uint32_t ssi_type;
- int32_t ssi_signal;
- int32_t ssi_noise;
- uint32_t preamble;
- uint32_t encoding;
+ __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;
};
void islpci_eth_cleanup_transmit(islpci_private *, isl38xx_control_block *);
-int islpci_eth_transmit(struct sk_buff *, struct net_device *);
+netdev_tx_t islpci_eth_transmit(struct sk_buff *, struct net_device *);
int islpci_eth_receive(islpci_private *);
void islpci_eth_tx_timeout(struct net_device *);
-void islpci_do_reset_and_wake(void *data);
+void islpci_do_reset_and_wake(struct work_struct *);
#endif /* _ISL_GEN_H */
diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
index b41d666fea3..1105a12dbde 100644
--- a/drivers/net/wireless/prism54/islpci_hotplug.c
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c
@@ -1,5 +1,4 @@
/*
- *
* Copyright (C) 2002 Intersil Americas Inc.
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
*
@@ -13,24 +12,22 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
+#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/init.h> /* For __init, __exit */
+#include <linux/dma-mapping.h>
#include "prismcompat.h"
#include "islpci_dev.h"
#include "islpci_mgt.h" /* for pc_debug */
#include "isl_oid.h"
-#define DRV_NAME "prism54"
-#define DRV_VERSION "1.2"
-
MODULE_AUTHOR("[Intersil] R.Bastings and W.Termorshuizen, The prism54.org Development Team <prism54-devel@prism54.org>");
MODULE_DESCRIPTION("The Prism54 802.11 Wireless LAN adapter");
MODULE_LICENSE("GPL");
@@ -39,10 +36,10 @@ static int init_pcitm = 0;
module_param(init_pcitm, int, 0);
/* In this order: vendor, device, subvendor, subdevice, class, class_mask,
- * driver_data
- * If you have an update for this please contact prism54-devel@prism54.org
- * The latest list can be found at http://prism54.org/supported_cards.php */
-static const struct pci_device_id prism54_id_tbl[] = {
+ * driver_data
+ * If you have an update for this please contact prism54-devel@prism54.org
+ * The latest list can be found at http://wireless.kernel.org/en/users/Drivers/p54 */
+static DEFINE_PCI_DEVICE_TABLE(prism54_id_tbl) = {
/* Intersil PRISM Duette/Prism GT Wireless LAN adapter */
{
0x1260, 0x3890,
@@ -52,9 +49,7 @@ static const struct pci_device_id prism54_id_tbl[] = {
/* 3COM 3CRWE154G72 Wireless LAN adapter */
{
- 0x10b7, 0x6001,
- PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, 0
+ PCI_VDEVICE(3COM, 0x6001), 0
},
/* Intersil PRISM Indigo Wireless LAN adapter */
@@ -90,14 +85,13 @@ static struct pci_driver prism54_driver = {
.remove = prism54_remove,
.suspend = prism54_suspend,
.resume = prism54_resume,
- /* .enable_wake ; we don't support this yet */
};
/******************************************************************************
Module initialization functions
******************************************************************************/
-int
+static int
prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct net_device *ndev;
@@ -124,22 +118,22 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
/* enable PCI DMA */
- if (pci_set_dma_mask(pdev, 0xffffffff)) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
printk(KERN_ERR "%s: 32-bit PCI DMA not supported", DRV_NAME);
goto do_pci_disable_device;
}
/* 0x40 is the programmable timer to configure the response timeout (TRDY_TIMEOUT)
* 0x41 is the programmable timer to configure the retry timeout (RETRY_TIMEOUT)
- * The RETRY_TIMEOUT is used to set the number of retries that the core, as a
- * Master, will perform before abandoning a cycle. The default value for
- * RETRY_TIMEOUT is 0x80, which far exceeds the PCI 2.1 requirement for new
- * devices. A write of zero to the RETRY_TIMEOUT register disables this
- * function to allow use with any non-compliant legacy devices that may
- * execute more retries.
+ * The RETRY_TIMEOUT is used to set the number of retries that the core, as a
+ * Master, will perform before abandoning a cycle. The default value for
+ * RETRY_TIMEOUT is 0x80, which far exceeds the PCI 2.1 requirement for new
+ * devices. A write of zero to the RETRY_TIMEOUT register disables this
+ * function to allow use with any non-compliant legacy devices that may
+ * execute more retries.
*
- * Writing zero to both these two registers will disable both timeouts and
- * *can* solve problems caused by devices that are slow to respond.
+ * Writing zero to both these two registers will disable both timeouts and
+ * *can* solve problems caused by devices that are slow to respond.
* Make this configurable - MSW
*/
if ( init_pcitm >= 0 ) {
@@ -170,14 +164,14 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
pci_set_master(pdev);
/* enable MWI */
- pci_set_mwi(pdev);
+ pci_try_set_mwi(pdev);
/* setup the network device interface and its structure */
if (!(ndev = islpci_setup(pdev))) {
/* error configuring the driver as a network device */
printk(KERN_ERR "%s: could not configure network device\n",
DRV_NAME);
- goto do_pci_release_regions;
+ goto do_pci_clear_mwi;
}
priv = netdev_priv(ndev);
@@ -187,8 +181,8 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
isl38xx_disable_interrupts(priv->device_base);
/* request for the interrupt before uploading the firmware */
- rvalue = request_irq(pdev->irq, &islpci_interrupt,
- SA_SHIRQ, ndev->name, priv);
+ rvalue = request_irq(pdev->irq, islpci_interrupt,
+ IRQF_SHARED, ndev->name, priv);
if (rvalue) {
/* error, could not hook the handler to the irq */
@@ -204,9 +198,10 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
do_unregister_netdev:
unregister_netdev(ndev);
islpci_free_memory(priv);
- pci_set_drvdata(pdev, NULL);
free_netdev(ndev);
priv = NULL;
+ do_pci_clear_mwi:
+ pci_clear_mwi(pdev);
do_pci_release_regions:
pci_release_regions(pdev);
do_pci_disable_device:
@@ -218,7 +213,7 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
static volatile int __in_cleanup_module = 0;
/* this one removes one(!!) instance only */
-void
+static void
prism54_remove(struct pci_dev *pdev)
{
struct net_device *ndev = pci_get_drvdata(pdev);
@@ -240,7 +235,7 @@ prism54_remove(struct pci_dev *pdev)
isl38xx_disable_interrupts(priv->device_base);
islpci_set_state(priv, PRV_STATE_OFF);
/* This bellow causes a lockup at rmmod time. It might be
- * because some interrupts still linger after rmmod time,
+ * because some interrupts still linger after rmmod time,
* see bug #17 */
/* pci_set_power_state(pdev, 3);*/ /* try to power-off */
}
@@ -250,16 +245,17 @@ prism54_remove(struct pci_dev *pdev)
/* free the PCI memory and unmap the remapped page */
islpci_free_memory(priv);
- pci_set_drvdata(pdev, NULL);
free_netdev(ndev);
priv = NULL;
+ pci_clear_mwi(pdev);
+
pci_release_regions(pdev);
pci_disable_device(pdev);
}
-int
+static int
prism54_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct net_device *ndev = pci_get_drvdata(pdev);
@@ -282,17 +278,24 @@ prism54_suspend(struct pci_dev *pdev, pm_message_t state)
return 0;
}
-int
+static int
prism54_resume(struct pci_dev *pdev)
{
struct net_device *ndev = pci_get_drvdata(pdev);
islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
- BUG_ON(!priv);
+ int err;
- pci_enable_device(pdev);
+ BUG_ON(!priv);
printk(KERN_NOTICE "%s: got resume request\n", ndev->name);
+ err = pci_enable_device(pdev);
+ if (err) {
+ printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
+ ndev->name);
+ return err;
+ }
+
pci_restore_state(pdev);
/* alright let's go into the PREBOOT state */
@@ -312,7 +315,7 @@ prism54_module_init(void)
__bug_on_wrong_struct_sizes ();
- return pci_module_init(&prism54_driver);
+ return pci_register_driver(&prism54_driver);
}
/* by the time prism54_module_exit() terminates, as a postcondition
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
index 6a60c5970cb..0de14dfa68c 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.c
+++ b/drivers/net/wireless/prism54/islpci_mgt.c
@@ -1,5 +1,4 @@
/*
- *
* Copyright (C) 2002 Intersil Americas Inc.
* Copyright 2004 Jens Maurer <Jens.Maurer@gmx.net>
*
@@ -13,18 +12,17 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
-#include <linux/config.h>
#include <linux/netdevice.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
#include <asm/io.h>
-#include <asm/system.h>
#include <linux/if_arp.h>
#include "prismcompat.h"
@@ -114,7 +112,7 @@ islpci_mgmt_rx_fill(struct net_device *ndev)
u32 curr = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ]);
#if VERBOSE > SHOW_ERROR_MESSAGES
- DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgmt_rx_fill \n");
+ DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgmt_rx_fill\n");
#endif
while (curr - priv->index_mgmt_rx < ISL38XX_CB_MGMT_QSIZE) {
@@ -124,11 +122,8 @@ islpci_mgmt_rx_fill(struct net_device *ndev)
if (buf->mem == NULL) {
buf->mem = kmalloc(MGMT_FRAME_SIZE, GFP_ATOMIC);
- if (!buf->mem) {
- printk(KERN_WARNING
- "Error allocating management frame.\n");
+ if (!buf->mem)
return -ENOMEM;
- }
buf->size = MGMT_FRAME_SIZE;
}
if (buf->pci_addr == 0) {
@@ -192,11 +187,9 @@ islpci_mgt_transmit(struct net_device *ndev, int operation, unsigned long oid,
err = -ENOMEM;
p = buf.mem = kmalloc(frag_len, GFP_KERNEL);
- if (!buf.mem) {
- printk(KERN_DEBUG "%s: cannot allocate mgmt frame\n",
- ndev->name);
+ if (!buf.mem)
goto error;
- }
+
buf.size = frag_len;
/* create the header directly in the fragment data area */
@@ -212,7 +205,7 @@ islpci_mgt_transmit(struct net_device *ndev, int operation, unsigned long oid,
{
pimfor_header_t *h = buf.mem;
DEBUG(SHOW_PIMFOR_FRAMES,
- "PIMFOR: op %i, oid 0x%08lx, device %i, flags 0x%x length 0x%x \n",
+ "PIMFOR: op %i, oid 0x%08lx, device %i, flags 0x%x length 0x%x\n",
h->operation, oid, h->device_id, h->flags, length);
/* display the buffer contents for debugging */
@@ -280,7 +273,7 @@ islpci_mgt_receive(struct net_device *ndev)
u32 curr_frag;
#if VERBOSE > SHOW_ERROR_MESSAGES
- DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_receive \n");
+ DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_receive\n");
#endif
/* Only once per interrupt, determine fragment range to
@@ -339,7 +332,7 @@ islpci_mgt_receive(struct net_device *ndev)
#if VERBOSE > SHOW_ERROR_MESSAGES
DEBUG(SHOW_PIMFOR_FRAMES,
- "PIMFOR: op %i, oid 0x%08x, device %i, flags 0x%x length 0x%x \n",
+ "PIMFOR: op %i, oid 0x%08x, device %i, flags 0x%x length 0x%x\n",
header->operation, header->oid, header->device_id,
header->flags, header->length);
@@ -359,14 +352,11 @@ islpci_mgt_receive(struct net_device *ndev)
/* Determine frame size, skipping OID_INL_TUNNEL headers. */
size = PIMFOR_HEADER_SIZE + header->length;
- frame = kmalloc(sizeof (struct islpci_mgmtframe) + size,
+ frame = kmalloc(sizeof(struct islpci_mgmtframe) + size,
GFP_ATOMIC);
- if (!frame) {
- printk(KERN_WARNING
- "%s: Out of memory, cannot handle oid 0x%08x\n",
- ndev->name, header->oid);
+ if (!frame)
continue;
- }
+
frame->ndev = ndev;
memcpy(&frame->buf, header, size);
frame->header = (pimfor_header_t *) frame->buf;
@@ -388,7 +378,7 @@ islpci_mgt_receive(struct net_device *ndev)
/* Create work to handle trap out of interrupt
* context. */
- INIT_WORK(&frame->ws, prism54_process_trap, frame);
+ INIT_WORK(&frame->ws, prism54_process_trap);
schedule_work(&frame->ws);
} else {
@@ -462,7 +452,7 @@ islpci_mgt_transaction(struct net_device *ndev,
*recvframe = NULL;
- if (down_interruptible(&priv->mgmt_sem))
+ if (mutex_lock_interruptible(&priv->mgmt_lock))
return -ERESTARTSYS;
prepare_to_wait(&priv->mgmt_wqueue, &wait, TASK_UNINTERRUPTIBLE);
@@ -503,10 +493,10 @@ islpci_mgt_transaction(struct net_device *ndev,
printk(KERN_WARNING "%s: timeout waiting for mgmt response\n",
ndev->name);
- /* TODO: we should reset the device here */
+ /* TODO: we should reset the device here */
out:
finish_wait(&priv->mgmt_wqueue, &wait);
- up(&priv->mgmt_sem);
+ mutex_unlock(&priv->mgmt_lock);
return err;
}
diff --git a/drivers/net/wireless/prism54/islpci_mgt.h b/drivers/net/wireless/prism54/islpci_mgt.h
index 2982be3363e..700c434c880 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.h
+++ b/drivers/net/wireless/prism54/islpci_mgt.h
@@ -1,5 +1,4 @@
/*
- *
* Copyright (C) 2002 Intersil Americas Inc.
* Copyright (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
*
@@ -13,8 +12,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
@@ -23,6 +21,7 @@
#include <linux/wireless.h>
#include <linux/skbuff.h>
+#include <linux/slab.h>
/*
* Function definitions
@@ -36,8 +35,8 @@ extern int pc_debug;
/* General driver definitions */
-#define PCIDEVICE_LATENCY_TIMER_MIN 0x40
-#define PCIDEVICE_LATENCY_TIMER_VAL 0x50
+#define PCIDEVICE_LATENCY_TIMER_MIN 0x40
+#define PCIDEVICE_LATENCY_TIMER_VAL 0x50
/* Debugging verbose definitions */
#define SHOW_NOTHING 0x00 /* overrules everything */
@@ -86,12 +85,6 @@ extern int pc_debug;
#define PIMFOR_FLAG_APPLIC_ORIGIN 0x01
#define PIMFOR_FLAG_LITTLE_ENDIAN 0x02
-static inline void
-add_le32p(u32 * le_number, u32 add)
-{
- *le_number = cpu_to_le32(le32_to_cpup(le_number) + add);
-}
-
void display_buffer(char *, int);
/*
@@ -107,7 +100,7 @@ typedef struct {
u8 device_id;
u8 flags;
u32 length;
-} __attribute__ ((packed))
+} __packed
pimfor_header_t;
/* A received and interrupt-processed management frame, either for
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index eea2f04c8c6..47b34bfe890 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2003,2004 Aurelien Alleaume <slts@free.fr>
*
* This program is free software; you can redistribute it and/or modify
@@ -11,11 +11,13 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
#include "prismcompat.h"
#include "islpci_dev.h"
#include "islpci_mgt.h"
@@ -235,22 +237,18 @@ mgt_init(islpci_private *priv)
{
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)
return -ENOMEM;
- memset(priv->mib, 0, OID_NUM_LAST * sizeof (void *));
-
/* Alloc the cache */
for (i = 0; i < OID_NUM_LAST; i++) {
if (isl_oid[i].flags & OID_FLAG_CACHED) {
- priv->mib[i] = kmalloc(isl_oid[i].size *
+ priv->mib[i] = kzalloc(isl_oid[i].size *
(isl_oid[i].range + 1),
GFP_KERNEL);
if (!priv->mib[i])
return -ENOMEM;
- memset(priv->mib[i], 0,
- isl_oid[i].size * (isl_oid[i].range + 1));
} else
priv->mib[i] = NULL;
}
@@ -332,7 +330,7 @@ mgt_le_to_cpu(int type, void *data)
case OID_TYPE_ATTACH:{
struct obj_attachment *attach = data;
attach->id = le16_to_cpu(attach->id);
- attach->size = le16_to_cpu(attach->size);;
+ attach->size = le16_to_cpu(attach->size);
break;
}
case OID_TYPE_SSID:
@@ -401,7 +399,7 @@ mgt_cpu_to_le(int type, void *data)
case OID_TYPE_ATTACH:{
struct obj_attachment *attach = data;
attach->id = cpu_to_le16(attach->id);
- attach->size = cpu_to_le16(attach->size);;
+ attach->size = cpu_to_le16(attach->size);
break;
}
case OID_TYPE_SSID:
@@ -503,7 +501,7 @@ mgt_set_varlen(islpci_private *priv, enum oid_num_t n, void *data, int extra_len
}
if (ret || response_op == PIMFOR_OP_ERROR)
ret = -EIO;
- } else
+ } else
ret = -EIO;
/* re-set given data to what it was */
@@ -683,7 +681,7 @@ mgt_update_addr(islpci_private *priv)
isl_oid[GEN_OID_MACADDRESS].size, &res);
if ((ret == 0) && res && (res->header->operation != PIMFOR_OP_ERROR))
- memcpy(priv->ndev->dev_addr, res->data, 6);
+ memcpy(priv->ndev->dev_addr, res->data, ETH_ALEN);
else
ret = -EIO;
if (res)
@@ -694,21 +692,19 @@ mgt_update_addr(islpci_private *priv)
return ret;
}
-#define VEC_SIZE(a) (sizeof(a)/sizeof(a[0]))
-
int
mgt_commit(islpci_private *priv)
{
int rvalue;
- u32 u;
+ enum oid_num_t u;
if (islpci_get_state(priv) < PRV_STATE_INIT)
return 0;
- rvalue = mgt_commit_list(priv, commit_part1, VEC_SIZE(commit_part1));
+ rvalue = mgt_commit_list(priv, commit_part1, ARRAY_SIZE(commit_part1));
if (priv->iw_mode != IW_MODE_MONITOR)
- rvalue |= mgt_commit_list(priv, commit_part2, VEC_SIZE(commit_part2));
+ rvalue |= mgt_commit_list(priv, commit_part2, ARRAY_SIZE(commit_part2));
u = OID_INL_MODE;
rvalue |= mgt_commit_list(priv, &u, 1);
@@ -727,7 +723,7 @@ mgt_commit(islpci_private *priv)
* MEDIUMLIMIT,BEACONPERIOD,DTIMPERIOD,ATIMWINDOW,LISTENINTERVAL
* FREQUENCY,EXTENDEDRATES.
*
- * The way to do this is to set ESSID. Note though that they may get
+ * The way to do this is to set ESSID. Note though that they may get
* unlatch before though by setting another OID. */
#if 0
void
@@ -821,7 +817,7 @@ mgt_response_to_str(enum oid_num_t n, union oid_res_t *r, char *str)
k = snprintf(str, PRIV_STR_SIZE, "nr=%u\n", list->nr);
for (i = 0; i < list->nr; i++)
k += snprintf(str + k, PRIV_STR_SIZE - k,
- "bss[%u] : \nage=%u\nchannel=%u\n"
+ "bss[%u] :\nage=%u\nchannel=%u\n"
"capinfo=0x%X\nrates=0x%X\n"
"basic_rates=0x%X\n",
i, list->bsslist[i].age,
diff --git a/drivers/net/wireless/prism54/oid_mgt.h b/drivers/net/wireless/prism54/oid_mgt.h
index 92c8a2d4acd..cf5141df847 100644
--- a/drivers/net/wireless/prism54/oid_mgt.h
+++ b/drivers/net/wireless/prism54/oid_mgt.h
@@ -11,8 +11,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/drivers/net/wireless/prism54/prismcompat.h b/drivers/net/wireless/prism54/prismcompat.h
index 55541c01752..bc1401eb4b9 100644
--- a/drivers/net/wireless/prism54/prismcompat.h
+++ b/drivers/net/wireless/prism54/prismcompat.h
@@ -1,4 +1,4 @@
-/*
+/*
* (C) 2004 Margit Schubert-While <margitsw@t-online.de>
*
* This program is free software; you can redistribute it and/or modify
@@ -11,12 +11,11 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
-/*
+/*
* Compatibility header file to aid support of different kernel versions
*/
@@ -29,7 +28,6 @@
#include <linux/device.h>
#include <linux/firmware.h>
-#include <linux/config.h>
#include <linux/moduleparam.h>
#include <linux/workqueue.h>
#include <linux/compiler.h>