[PATCH 3/14 linux-2.6.7-rc1] prism54: add iwspy support

From: Luis R. Rodriguez
Date: Mon May 24 2004 - 03:41:58 EST



2004-03-18 Aurelien Alleaume <slts@xxxxxxx>

* islpci_eth.c, islpci_dev.h, isl_ioctl.c : iwspy support. Ran
* lindent.

--
GnuPG Key fingerprint = 113F B290 C6D2 0251 4D84 A34A 6ADD 4937 E20A 525E
2004-03-18 Aurelien Alleaume <slts@xxxxxxx>

* islpci_eth.c, islpci_dev.h, isl_ioctl.c : iwspy support. Ran lindent.

Index: linux-2.6.7-rc1/drivers/net/wireless/prism54/isl_ioctl.c
===================================================================
RCS file: /var/lib/cvs/prism54-ng/ksrc/isl_ioctl.c,v
retrieving revision 1.144
retrieving revision 1.145
diff -u -r1.144 -r1.145
--- linux-2.6.7-rc1/drivers/net/wireless/prism54/isl_ioctl.c 18 Mar 2004 11:16:23 -0000 1.144
+++ linux-2.6.7-rc1/drivers/net/wireless/prism54/isl_ioctl.c 18 Mar 2004 15:27:44 -0000 1.145
@@ -1,4 +1,4 @@
-/* $Header: /var/lib/cvs/prism54-ng/ksrc/isl_ioctl.c,v 1.144 2004/03/18 11:16:23 ajfa Exp $
+/* $Header: /var/lib/cvs/prism54-ng/ksrc/isl_ioctl.c,v 1.145 2004/03/18 15:27:44 ajfa Exp $
*
* Copyright (C) 2002 Intersil Americas Inc.
* (C) 2003,2004 Aurelien Alleaume <slts@xxxxxxx>
@@ -2098,6 +2098,31 @@
return ret;
}

+static int
+prism54_set_spy(struct net_device *ndev,
+ struct iw_request_info *info,
+ union iwreq_data *uwrq, char *extra)
+{
+ islpci_private *priv = netdev_priv(ndev);
+ u32 u, oid = OID_INL_CONFIG;
+
+ down_write(&priv->mib_sem);
+ mgt_get(priv, OID_INL_CONFIG, &u);
+
+ if ((uwrq->data.length == 0) && (priv->spy_data.spy_number > 0))
+ /* disable spy */
+ u &= ~INL_CONFIG_RXANNEX;
+ else if ((uwrq->data.length > 0) && (priv->spy_data.spy_number == 0))
+ /* enable spy */
+ u |= INL_CONFIG_RXANNEX;
+
+ mgt_set(priv, OID_INL_CONFIG, &u);
+ mgt_commit_list(priv, &oid, 1);
+ up_write(&priv->mib_sem);
+
+ return iw_handler_set_spy(ndev, info, uwrq, extra);
+}
+
static const iw_handler prism54_handler[] = {
(iw_handler) prism54_commit, /* SIOCSIWCOMMIT */
(iw_handler) prism54_get_name, /* SIOCGIWNAME */
@@ -2115,7 +2140,7 @@
(iw_handler) NULL, /* SIOCGIWPRIV */
(iw_handler) NULL, /* SIOCSIWSTATS */
(iw_handler) NULL, /* SIOCGIWSTATS */
- iw_handler_set_spy, /* SIOCSIWSPY */
+ prism54_set_spy, /* SIOCSIWSPY */
iw_handler_get_spy, /* SIOCGIWSPY */
iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
@@ -2182,7 +2207,6 @@
#define IWPRIV_SSID(n,x) IWPRIV_SET_SSID(n,x), IWPRIV_GET(n,x)
#define IWPRIV_ADDR(n,x) IWPRIV_SET_ADDR(n,x), IWPRIV_GET(n,x)

-
/* Note : limited to 128 private ioctls */

static const struct iw_priv_args prism54_private_args[] = {
@@ -2234,7 +2258,7 @@
IWPRIV_U32(DOT11_OID_AUTHENABLE, "authenable"),
IWPRIV_U32(DOT11_OID_PRIVACYINVOKED, "privinvok"),
IWPRIV_U32(DOT11_OID_EXUNENCRYPTED, "exunencrypt"),
-
+
IWPRIV_U32(DOT11_OID_REKEYTHRESHOLD, "rekeythresh"),

IWPRIV_U32(DOT11_OID_MAXTXLIFETIME, "maxtxlife"),
@@ -2261,7 +2285,7 @@
IWPRIV_GET(DOT11_OID_FREQUENCYACTIVITY, "freqactivity"),
IWPRIV_U32(DOT11_OID_NONERPPROTECTION, "nonerpprotec"),
IWPRIV_U32(DOT11_OID_PROFILES, "profile"),
- IWPRIV_GET(DOT11_OID_EXTENDEDRATES,"extrates"),
+ IWPRIV_GET(DOT11_OID_EXTENDEDRATES, "extrates"),
IWPRIV_U32(DOT11_OID_MLMEAUTOLEVEL, "mlmelevel"),

IWPRIV_GET(DOT11_OID_BSSS, "bsss"),
@@ -2308,20 +2332,13 @@
.standard = (iw_handler *) prism54_handler,
.private = (iw_handler *) prism54_private_handler,
.private_args = (struct iw_priv_args *) prism54_private_args,
+ .spy_offset = offsetof(islpci_private, spy_data),
};

-/* These ioctls won't work with the new API */
+/* For ioctls that don't work with the new API */

int
prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
{
- /*struct iwreq *wrq = (struct iwreq *) rq;
- islpci_private *priv = netdev_priv(ndev);
- int ret = 0;
-
- switch (cmd) {
-
- }
- */
return -EOPNOTSUPP;
}
Index: linux-2.6.7-rc1/drivers/net/wireless/prism54/isl_oid.h
===================================================================
RCS file: /var/lib/cvs/prism54-ng/ksrc/isl_oid.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- linux-2.6.7-rc1/drivers/net/wireless/prism54/isl_oid.h 18 Mar 2004 11:16:23 -0000 1.4
+++ linux-2.6.7-rc1/drivers/net/wireless/prism54/isl_oid.h 18 Mar 2004 15:27:44 -0000 1.5
@@ -1,9 +1,9 @@
/*
- * $Id: isl_oid.h,v 1.4 2004/03/18 11:16:23 ajfa Exp $
+ * $Id: isl_oid.h,v 1.5 2004/03/18 15:27:44 ajfa Exp $
*
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@xxxxxxx>
* Copyright (C) 2004 Luis R. Rodriguez <mcgrof@xxxxxxxxxxxxxxxxxx>
- * Copyright (C) 2004 Aurélien Alleaume <slts@xxxxxxx>
+ * Copyright (C) 2004 Aurelien Alleaume <slts@xxxxxxx>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -91,6 +91,19 @@
u16 mhz[0];
} __attribute__ ((packed));

+struct obj_rx_annex {
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u32 something0;
+ u32 time;
+ u16 something1;
+ u16 rate;
+ u16 freq;
+ u16 something2;
+ u8 rssi;
+ u8 pad[3];
+} __attribute__ ((packed));
+
/*
* in case everything's ok, the inlined function below will be
* optimized away by the compiler...
Index: linux-2.6.7-rc1/drivers/net/wireless/prism54/islpci_dev.h
===================================================================
RCS file: /var/lib/cvs/prism54-ng/ksrc/islpci_dev.h,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -r1.56 -r1.57
--- linux-2.6.7-rc1/drivers/net/wireless/prism54/islpci_dev.h 18 Mar 2004 11:44:17 -0000 1.56
+++ linux-2.6.7-rc1/drivers/net/wireless/prism54/islpci_dev.h 18 Mar 2004 15:27:44 -0000 1.57
@@ -1,4 +1,4 @@
-/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_dev.h,v 1.56 2004/03/18 11:44:17 ajfa Exp $
+/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_dev.h,v 1.57 2004/03/18 15:27:44 ajfa Exp $
*
* Copyright (C) 2002 Intersil Americas Inc.
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@xxxxxxx>
@@ -26,6 +26,7 @@
#include <linux/version.h>
#include <linux/netdevice.h>
#include <linux/wireless.h>
+#include <net/iw_handler.h>
#include <linux/list.h>

#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
@@ -111,6 +112,8 @@
struct iw_statistics local_iwstatistics;
struct iw_statistics iwstatistics;

+ struct iw_spy_data spy_data; /* iwspy support */
+
struct islpci_acl acl;

/* PCI bus allocation & configuration members */
@@ -182,7 +185,7 @@
islpci_state_t state;
int state_off; /* enumeration of off-state, if 0 then
* we're not in any off-state */
-
+
/* WPA stuff */
int wpa; /* WPA mode enabled */
struct list_head bss_wpa_list;
Index: linux-2.6.7-rc1/drivers/net/wireless/prism54/islpci_eth.c
===================================================================
RCS file: /var/lib/cvs/prism54-ng/ksrc/islpci_eth.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- linux-2.6.7-rc1/drivers/net/wireless/prism54/islpci_eth.c 18 Mar 2004 11:44:17 -0000 1.30
+++ linux-2.6.7-rc1/drivers/net/wireless/prism54/islpci_eth.c 18 Mar 2004 15:27:44 -0000 1.31
@@ -1,7 +1,7 @@
-/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_eth.c,v 1.30 2004/03/18 11:44:17 ajfa Exp $
+/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_eth.c,v 1.31 2004/03/18 15:27:44 ajfa Exp $
*
* Copyright (C) 2002 Intersil Americas Inc.
- *
+ * Copyright (C) 2004 Aurelien Alleaume <slts@xxxxxxx>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License
@@ -205,7 +205,7 @@
priv->data_low_tx[index] = skb;
/* set the proper fragment start address and size information */
fragment->size = cpu_to_le16(frame_size);
- fragment->flags = cpu_to_le16(0); /* set to 1 if more fragments */
+ fragment->flags = cpu_to_le16(0); /* set to 1 if more fragments */
fragment->address = cpu_to_le32(pci_map_address);
curr_frag++;

@@ -215,7 +215,7 @@
cb->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ] = cpu_to_le32(curr_frag);

if (curr_frag - priv->free_data_tx + ISL38XX_MIN_QTHRESHOLD
- > ISL38XX_CB_TX_QSIZE) {
+ > ISL38XX_CB_TX_QSIZE) {
/* stop sends from upper layers */
netif_stop_queue(ndev);

@@ -236,7 +236,7 @@

return 0;

- drop_free:
+ drop_free:
/* free the skbuf structure before aborting */
dev_kfree_skb(skb);
skb = NULL;
@@ -266,7 +266,8 @@
index = priv->free_data_rx % ISL38XX_CB_RX_QSIZE;
size = le16_to_cpu(control_block->rx_data_low[index].size);
skb = priv->data_low_rx[index];
- offset = ((unsigned long) le32_to_cpu(control_block->rx_data_low[index].address) -
+ offset = ((unsigned long)
+ le32_to_cpu(control_block->rx_data_low[index].address) -
(unsigned long) skb->data) & 3;

#if VERBOSE > SHOW_ERROR_MESSAGES
@@ -320,15 +321,34 @@
* header and without the FCS. But there a is a bit that
* indicates if the packet is corrupted :-) */
if (skb->data[8] & 0x01)
- /* This one is bad. Drop it !*/
+ /* This one is bad. Drop it ! */
discard = 1;
skb_pull(skb, 20);
skb->protocol = htons(ETH_P_802_2);
skb->mac.raw = skb->data;
skb->pkt_type = PACKET_OTHERHOST;
- } else
+ } else {
+ if (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.
+ */
+ struct iw_quality wstats;
+ struct obj_rx_annex *annex =
+ (struct obj_rx_annex *) skb->data;
+ wstats.level = annex->rssi;
+ /* The noise value can be a bit outdated if nobody's
+ * reading wireless stats... */
+ wstats.noise = priv->iwstatistics.qual.noise;
+ wstats.qual = wstats.level - wstats.noise;
+ wstats.updated = 0x07;
+ /* Update spy records */
+ wireless_spy_update(ndev, annex->addr2, &wstats);
+ /* 20 = sizeof(struct obj_rx_annex) - 2*ETH_ALEN */
+ memcpy(skb->data + 20, skb->data, 2 * ETH_ALEN);
+ skb_pull(skb, 20);
+ }
skb->protocol = eth_type_trans(skb, ndev);
-
+ }
skb->ip_summed = CHECKSUM_NONE;
priv->statistics.rx_packets++;
priv->statistics.rx_bytes += size;
@@ -343,8 +363,7 @@
if (discard) {
dev_kfree_skb(skb);
skb = NULL;
- }
- else
+ } else
netif_rx(skb);

/* increment the read index for the rx data low queue */
@@ -395,7 +414,7 @@
wmb();

/* increment the driver read pointer */
- add_le32p((u32 *) & control_block->
+ add_le32p((u32 *) &control_block->
driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1);
}

@@ -405,13 +424,13 @@
return 0;
}

-void
+void
islpci_do_reset_and_wake(void *data)
{
- islpci_private *priv = (islpci_private *) data;
- islpci_reset(priv, 1);
- netif_wake_queue(priv->ndev);
- priv->reset_task_pending = 0;
+ islpci_private *priv = (islpci_private *) data;
+ islpci_reset(priv, 1);
+ netif_wake_queue(priv->ndev);
+ priv->reset_task_pending = 0;
}

void
@@ -423,7 +442,7 @@
/* increment the transmit error counter */
statistics->tx_errors++;

- if(!priv->reset_task_pending) {
+ if (!priv->reset_task_pending) {
priv->reset_task_pending = 1;
netif_stop_queue(ndev);
schedule_work(&priv->reset_task);
Index: linux-2.6.7-rc1/drivers/net/wireless/prism54/oid_mgt.c
===================================================================
RCS file: /var/lib/cvs/prism54-ng/ksrc/oid_mgt.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- linux-2.6.7-rc1/drivers/net/wireless/prism54/oid_mgt.c 18 Mar 2004 11:16:23 -0000 1.8
+++ linux-2.6.7-rc1/drivers/net/wireless/prism54/oid_mgt.c 18 Mar 2004 15:27:44 -0000 1.9
@@ -570,6 +570,17 @@
mgt_cpu_to_le(isl_oid[n].flags & OID_FLAG_TYPE, priv->mib[n]);
}

+void
+mgt_get(islpci_private *priv, enum oid_num_t n, void *res)
+{
+ BUG_ON(OID_NUM_LAST <= n);
+ BUG_ON(priv->mib[n] == NULL);
+ BUG_ON(res == NULL);
+
+ memcpy(res, priv->mib[n], isl_oid[n].size);
+ mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, res);
+}
+
/* Commits the cache. Lock outside. */

static enum oid_num_t commit_part1[] = {
Index: linux-2.6.7-rc1/drivers/net/wireless/prism54/oid_mgt.h
===================================================================
RCS file: /var/lib/cvs/prism54-ng/ksrc/oid_mgt.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- linux-2.6.7-rc1/drivers/net/wireless/prism54/oid_mgt.h 18 Mar 2004 11:16:23 -0000 1.3
+++ linux-2.6.7-rc1/drivers/net/wireless/prism54/oid_mgt.h 18 Mar 2004 15:27:44 -0000 1.4
@@ -37,12 +37,14 @@
int mgt_set_request(islpci_private *, enum oid_num_t, int, void *);

int mgt_get_request(islpci_private *, enum oid_num_t, int, void *,
- union oid_res_t *);
+ union oid_res_t *);

int mgt_commit_list(islpci_private *, enum oid_num_t *, int);

void mgt_set(islpci_private *, enum oid_num_t, void *);

+void mgt_get(islpci_private *, enum oid_num_t, void *);
+
void mgt_commit(islpci_private *);

int mgt_mlme_answer(islpci_private *);

Attachment: pgp00000.pgp
Description: PGP signature