Commit af39cd4d authored by Jeff Garzik's avatar Jeff Garzik

Merge redhat.com:/spare/repo/netdev-2.6/prism54

into redhat.com:/spare/repo/net-drivers-2.6
parents 2424dc63 b15b9151
/* $Header: /var/lib/cvs/prism54-ng/ksrc/isl_38xx.c,v 1.22 2004/02/28 03:06:07 mcgrof Exp $ /*
* *
* Copyright (C) 2002 Intersil Americas Inc. * Copyright (C) 2002 Intersil Americas Inc.
* Copyright (C) 2003-2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>_ * Copyright (C) 2003-2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>_
......
/* $Header: /var/lib/cvs/prism54-ng/ksrc/isl_38xx.h,v 1.22 2004/02/28 03:06:07 mcgrof Exp $ /*
* *
* Copyright (C) 2002 Intersil Americas Inc. * Copyright (C) 2002 Intersil Americas Inc.
* *
......
This diff is collapsed.
/* $Header: /var/lib/cvs/prism54-ng/ksrc/isl_ioctl.h,v 1.30 2004/01/30 16:24:00 ajfa Exp $ /*
* *
* Copyright (C) 2002 Intersil Americas Inc. * Copyright (C) 2002 Intersil Americas Inc.
* (C) 2003 Aurelien Alleaume <slts@free.fr> * (C) 2003 Aurelien Alleaume <slts@free.fr>
......
/* /*
* $Id: isl_oid.h,v 1.3 2004/03/09 09:05:27 mcgrof Exp $ *
* *
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org> * Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
* Copyright (C) 2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu> * Copyright (C) 2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -457,16 +458,29 @@ enum oid_num_t { ...@@ -457,16 +458,29 @@ enum oid_num_t {
OID_NUM_LAST OID_NUM_LAST
}; };
/* We could add more flags. eg: in which mode are they allowed, ro, rw, ...*/ #define OID_FLAG_CACHED 0x80
#define OID_FLAG_CACHED 0x01 #define OID_FLAG_TYPE 0x7f
#define OID_FLAG_U32 0x02
#define OID_FLAG_MLMEEX 0x04 /* this type is special because of a variable #define OID_TYPE_U32 0x01
size field when sending. Not yet implemented (not used in driver). */ #define OID_TYPE_SSID 0x02
#define OID_TYPE_KEY 0x03
#define OID_TYPE_BUFFER 0x04
#define OID_TYPE_BSS 0x05
#define OID_TYPE_BSSLIST 0x06
#define OID_TYPE_FREQUENCIES 0x07
#define OID_TYPE_MLME 0x08
#define OID_TYPE_MLMEEX 0x09
#define OID_TYPE_ADDR 0x0A
#define OID_TYPE_RAW 0x0B
/* OID_TYPE_MLMEEX is special because of a variable size field when sending.
* Not yet implemented (not used in driver anyway).
*/
struct oid_t { struct oid_t {
enum oid_num_t oid; enum oid_num_t oid;
short range; /* to define a range of oid */ short range; /* to define a range of oid */
short size; /* size of the associated data */ short size; /* max size of the associated data */
char flags; char flags;
}; };
...@@ -478,6 +492,7 @@ union oid_res_t { ...@@ -478,6 +492,7 @@ union oid_res_t {
#define IWMAX_BITRATES 20 #define IWMAX_BITRATES 20
#define IWMAX_BSS 24 #define IWMAX_BSS 24
#define IWMAX_FREQ 30 #define IWMAX_FREQ 30
#define PRIV_STR_SIZE 1024
#endif /* !defined(_ISL_OID_H) */ #endif /* !defined(_ISL_OID_H) */
/* EOF */ /* EOF */
/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_dev.c,v 1.68 2004/02/28 03:06:07 mcgrof Exp $ /*
* *
* Copyright (C) 2002 Intersil Americas Inc. * Copyright (C) 2002 Intersil Americas Inc.
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org> * Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
...@@ -715,9 +715,9 @@ islpci_setup(struct pci_dev *pdev) ...@@ -715,9 +715,9 @@ islpci_setup(struct pci_dev *pdev)
priv = netdev_priv(ndev); priv = netdev_priv(ndev);
priv->ndev = ndev; priv->ndev = ndev;
priv->pdev = pdev; priv->pdev = pdev;
priv->monitor_type = ARPHRD_IEEE80211;
priv->ndev->type = (priv->iw_mode == IW_MODE_MONITOR) ? priv->ndev->type = (priv->iw_mode == IW_MODE_MONITOR) ?
ARPHRD_IEEE80211: ARPHRD_ETHER; priv->monitor_type : ARPHRD_ETHER;
/* save the start and end address of the PCI memory area */ /* save the start and end address of the PCI memory area */
ndev->mem_start = (unsigned long) priv->device_base; ndev->mem_start = (unsigned long) priv->device_base;
...@@ -743,9 +743,11 @@ islpci_setup(struct pci_dev *pdev) ...@@ -743,9 +743,11 @@ islpci_setup(struct pci_dev *pdev)
/* initialize workqueue's */ /* initialize workqueue's */
INIT_WORK(&priv->stats_work, INIT_WORK(&priv->stats_work,
(void (*)(void *)) prism54_update_stats, priv); (void (*)(void *)) prism54_update_stats, priv);
priv->stats_timestamp = 0; priv->stats_timestamp = 0;
INIT_WORK(&priv->reset_task, islpci_do_reset_and_wake, priv);
priv->reset_task_pending = 0;
/* allocate various memory areas */ /* allocate various memory areas */
if (islpci_alloc_memory(priv)) if (islpci_alloc_memory(priv))
goto do_free_netdev; goto do_free_netdev;
......
/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_dev.h,v 1.53 2004/02/28 03:06:07 mcgrof Exp $ /*
* *
* Copyright (C) 2002 Intersil Americas Inc. * Copyright (C) 2002 Intersil Americas Inc.
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org> * Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
* Copyright (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu> * Copyright (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
* Copyright (C) 2003 Aurelien Alleaume <slts@free.fr>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -25,6 +26,7 @@ ...@@ -25,6 +26,7 @@
#include <linux/version.h> #include <linux/version.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/wireless.h> #include <linux/wireless.h>
#include <net/iw_handler.h>
#include <linux/list.h> #include <linux/list.h>
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41) #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
...@@ -110,6 +112,10 @@ typedef struct { ...@@ -110,6 +112,10 @@ typedef struct {
struct iw_statistics local_iwstatistics; struct iw_statistics local_iwstatistics;
struct iw_statistics iwstatistics; struct iw_statistics iwstatistics;
struct iw_spy_data spy_data; /* iwspy support */
int monitor_type; /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_PRISM */
struct islpci_acl acl; struct islpci_acl acl;
/* PCI bus allocation & configuration members */ /* PCI bus allocation & configuration members */
...@@ -187,6 +193,9 @@ typedef struct { ...@@ -187,6 +193,9 @@ typedef struct {
struct list_head bss_wpa_list; struct list_head bss_wpa_list;
int num_bss_wpa; int num_bss_wpa;
struct semaphore wpa_sem; struct semaphore wpa_sem;
struct work_struct reset_task;
int reset_task_pending;
} islpci_private; } islpci_private;
static inline islpci_state_t static inline islpci_state_t
......
/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_eth.c,v 1.27 2004/01/30 16:24:00 ajfa Exp $ /*
* *
* Copyright (C) 2002 Intersil Americas Inc. * 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 * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License * the Free Software Foundation; either version 2 of the License
...@@ -24,10 +24,12 @@ ...@@ -24,10 +24,12 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/if_arp.h>
#include "isl_38xx.h" #include "isl_38xx.h"
#include "islpci_eth.h" #include "islpci_eth.h"
#include "islpci_mgt.h" #include "islpci_mgt.h"
#include "oid_mgt.h"
/****************************************************************************** /******************************************************************************
Network Interface functions Network Interface functions
...@@ -246,6 +248,69 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev) ...@@ -246,6 +248,69 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
return err; return err;
} }
static inline int
islpci_monitor_rx(islpci_private *priv, struct sk_buff **skb)
{
/* The card reports full 802.11 packets but with a 20 bytes
* 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;
if (priv->ndev->type == ARPHRD_IEEE80211_PRISM) {
struct avs_80211_1_header *avs;
/* extract the relevant data from the header */
u32 clock = hdr->clock;
u8 rate = hdr->rate;
u16 freq = be16_to_cpu(hdr->freq);
u8 rssi = hdr->rssi;
skb_pull(*skb, sizeof (struct rfmon_header));
if (skb_headroom(*skb) < sizeof (struct avs_80211_1_header)) {
struct sk_buff *newskb = skb_copy_expand(*skb,
sizeof (struct
avs_80211_1_header),
0, GFP_ATOMIC);
if (newskb) {
kfree_skb(*skb);
*skb = newskb;
} else
return -1;
/* This behavior is not very subtile... */
}
/* make room for the new header and fill it. */
avs =
(struct avs_80211_1_header *) skb_push(*skb,
sizeof (struct
avs_80211_1_header));
avs->version = htonl(P80211CAPTURE_VERSION);
avs->length = htonl(sizeof (struct avs_80211_1_header));
avs->mactime = __cpu_to_be64(clock);
avs->hosttime = __cpu_to_be64(jiffies);
avs->phytype = htonl(6); /*OFDM: 6 for (g), 8 for (a) */
avs->channel = htonl(channel_of_freq(freq));
avs->datarate = htonl(rate * 5);
avs->antenna = htonl(0); /*unknown */
avs->priority = htonl(0); /*unknown */
avs->ssi_type = htonl(2); /*2: dBm, 3: raw RSSI */
avs->ssi_signal = htonl(rssi);
avs->ssi_noise = htonl(priv->local_iwstatistics.qual.noise); /*better than 'undefined', I assume */
avs->preamble = htonl(0); /*unknown */
avs->encoding = htonl(0); /*unknown */
} else
skb_pull(*skb, sizeof (struct rfmon_header));
(*skb)->protocol = htons(ETH_P_802_2);
(*skb)->mac.raw = (*skb)->data;
(*skb)->pkt_type = PACKET_OTHERHOST;
return 0;
}
int int
islpci_eth_receive(islpci_private *priv) islpci_eth_receive(islpci_private *priv)
{ {
...@@ -266,7 +331,8 @@ islpci_eth_receive(islpci_private *priv) ...@@ -266,7 +331,8 @@ islpci_eth_receive(islpci_private *priv)
index = priv->free_data_rx % ISL38XX_CB_RX_QSIZE; index = priv->free_data_rx % ISL38XX_CB_RX_QSIZE;
size = le16_to_cpu(control_block->rx_data_low[index].size); size = le16_to_cpu(control_block->rx_data_low[index].size);
skb = priv->data_low_rx[index]; 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; (unsigned long) skb->data) & 3;
#if VERBOSE > SHOW_ERROR_MESSAGES #if VERBOSE > SHOW_ERROR_MESSAGES
...@@ -314,29 +380,32 @@ islpci_eth_receive(islpci_private *priv) ...@@ -314,29 +380,32 @@ islpci_eth_receive(islpci_private *priv)
/* do some additional sk_buff and network layer parameters */ /* do some additional sk_buff and network layer parameters */
skb->dev = ndev; skb->dev = ndev;
/* take care of monitor mode */ /* take care of monitor mode and spy monitoring. */
if (priv->iw_mode == IW_MODE_MONITOR) { if (priv->iw_mode == IW_MODE_MONITOR)
/* The card reports full 802.11 packets but with a 20 bytes discard = islpci_monitor_rx(priv, &skb);
* header and without the FCS. But there a is a bit that else {
* indicates if the packet is corrupted :-) */ if (skb->data[2 * ETH_ALEN] == 0) {
/* int i; */ /* The packet has a rx_annex. Read it for spy monitoring, Then
if (skb->data[8] & 0x01){ * remove it, while keeping the 2 leading MAC addr.
/* This one is bad. Drop it !*/ */
discard = 1; struct iw_quality wstats;
/* printk("BAD\n");*/ 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
* reading wireless stats... */
wstats.noise = priv->local_iwstatistics.qual.noise;
wstats.qual = wstats.level - wstats.noise;
wstats.updated = 0x07;
/* Update spy records */
wireless_spy_update(ndev, annex->addr2, &wstats);
memcpy(skb->data + sizeof (struct rfmon_header),
skb->data, 2 * ETH_ALEN);
skb_pull(skb, sizeof (struct rfmon_header));
} }
/*
for(i=0;i<50;i++)
printk("%2.2X:",skb->data[i]);
printk("\n");
*/
skb_pull(skb, 20);
skb->protocol = htons(ETH_P_802_2);
skb->mac.raw = skb->data;
skb->pkt_type = PACKET_OTHERHOST;
} else
skb->protocol = eth_type_trans(skb, ndev); skb->protocol = eth_type_trans(skb, ndev);
}
skb->ip_summed = CHECKSUM_NONE; skb->ip_summed = CHECKSUM_NONE;
priv->statistics.rx_packets++; priv->statistics.rx_packets++;
priv->statistics.rx_bytes += size; priv->statistics.rx_bytes += size;
...@@ -351,8 +420,7 @@ islpci_eth_receive(islpci_private *priv) ...@@ -351,8 +420,7 @@ islpci_eth_receive(islpci_private *priv)
if (discard) { if (discard) {
dev_kfree_skb(skb); dev_kfree_skb(skb);
skb = NULL; skb = NULL;
} } else
else
netif_rx(skb); netif_rx(skb);
/* increment the read index for the rx data low queue */ /* increment the read index for the rx data low queue */
...@@ -403,7 +471,7 @@ islpci_eth_receive(islpci_private *priv) ...@@ -403,7 +471,7 @@ islpci_eth_receive(islpci_private *priv)
wmb(); wmb();
/* increment the driver read pointer */ /* increment the driver read pointer */
add_le32p((u32 *) & control_block-> add_le32p((u32 *) &control_block->
driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1); driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1);
} }
...@@ -413,6 +481,15 @@ islpci_eth_receive(islpci_private *priv) ...@@ -413,6 +481,15 @@ islpci_eth_receive(islpci_private *priv)
return 0; return 0;
} }
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;
}
void void
islpci_eth_tx_timeout(struct net_device *ndev) islpci_eth_tx_timeout(struct net_device *ndev)
{ {
...@@ -422,13 +499,11 @@ islpci_eth_tx_timeout(struct net_device *ndev) ...@@ -422,13 +499,11 @@ islpci_eth_tx_timeout(struct net_device *ndev)
/* increment the transmit error counter */ /* increment the transmit error counter */
statistics->tx_errors++; statistics->tx_errors++;
#if 0 if (!priv->reset_task_pending) {
/* don't do this here! we are not allowed to sleep since we are in interrupt context */ priv->reset_task_pending = 1;
if (islpci_reset(priv)) netif_stop_queue(ndev);
printk(KERN_ERR "%s: error on TX timeout card reset!\n", schedule_work(&priv->reset_task);
ndev->name); }
#endif
/* netif_wake_queue(ndev); */
return; return;
} }
/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_eth.h,v 1.5 2004/01/12 22:16:32 jmaurer Exp $ /*
* *
* Copyright (C) 2002 Intersil Americas Inc. * Copyright (C) 2002 Intersil Americas Inc.
* *
...@@ -23,9 +23,51 @@ ...@@ -23,9 +23,51 @@
#include "isl_38xx.h" #include "isl_38xx.h"
#include "islpci_dev.h" #include "islpci_dev.h"
struct rfmon_header {
u16 unk0; /* = 0x0000 */
u16 length; /* = 0x1400 */
u32 clock; /* 1MHz clock */
u8 flags;
u8 unk1;
u8 rate;
u8 unk2;
u16 freq;
u16 unk3;
u8 rssi;
u8 padding[3];
} __attribute__ ((packed));
struct rx_annex_header {
u8 addr1[ETH_ALEN];
u8 addr2[ETH_ALEN];
struct rfmon_header rfmon;
} __attribute__ ((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;
};
void islpci_eth_cleanup_transmit(islpci_private *, isl38xx_control_block *); void islpci_eth_cleanup_transmit(islpci_private *, isl38xx_control_block *);
int islpci_eth_transmit(struct sk_buff *, struct net_device *); int islpci_eth_transmit(struct sk_buff *, struct net_device *);
int islpci_eth_receive(islpci_private *); int islpci_eth_receive(islpci_private *);
void islpci_eth_tx_timeout(struct net_device *); void islpci_eth_tx_timeout(struct net_device *);
void islpci_do_reset_and_wake(void *data);
#endif /* _ISL_GEN_H */ #endif /* _ISL_GEN_H */
/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_hotplug.c,v 1.56 2004/02/26 23:33:02 mcgrof Exp $ /*
* *
* Copyright (C) 2002 Intersil Americas Inc. * Copyright (C) 2002 Intersil Americas Inc.
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org> * Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
......
/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_mgt.c,v 1.40 2004/02/01 10:57:23 mcgrof Exp $ /*
* *
* Copyright (C) 2002 Intersil Americas Inc. * Copyright (C) 2002 Intersil Americas Inc.
* Copyright 2004 Jens Maurer <Jens.Maurer@gmx.net> * Copyright 2004 Jens Maurer <Jens.Maurer@gmx.net>
......
/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_mgt.h,v 1.22 2004/01/30 16:24:00 ajfa Exp $ /*
* *
* Copyright (C) 2002 Intersil Americas Inc. * Copyright (C) 2002 Intersil Americas Inc.
* Copyright (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu> * Copyright (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
......
This diff is collapsed.
/* /*
* Copyright (C) 2003 Aurelien Alleaume <slts@free.fr> * Copyright (C) 2003 Aurelien Alleaume <slts@free.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -28,9 +28,12 @@ int mgt_init(islpci_private *); ...@@ -28,9 +28,12 @@ int mgt_init(islpci_private *);
void mgt_clean(islpci_private *); void mgt_clean(islpci_private *);
/* I don't know where to put these 3 */
extern const int frequency_list_bg[]; extern const int frequency_list_bg[];
extern const int frequency_list_a[]; extern const int frequency_list_a[];
int channel_of_freq(int);
void mgt_le_to_cpu(int, void *);
int mgt_set_request(islpci_private *, enum oid_num_t, int, void *); int mgt_set_request(islpci_private *, enum oid_num_t, int, void *);
...@@ -41,11 +44,15 @@ int mgt_commit_list(islpci_private *, enum oid_num_t *, int); ...@@ -41,11 +44,15 @@ int mgt_commit_list(islpci_private *, enum oid_num_t *, int);
void mgt_set(islpci_private *, enum oid_num_t, void *); 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 *); void mgt_commit(islpci_private *);
int mgt_mlme_answer(islpci_private *); int mgt_mlme_answer(islpci_private *);
enum oid_num_t mgt_oidtonum(u32 oid); enum oid_num_t mgt_oidtonum(u32 oid);
int mgt_response_to_str(enum oid_num_t, union oid_res_t *, char *);
#endif /* !defined(_OID_MGT_H) */ #endif /* !defined(_OID_MGT_H) */
/* EOF */ /* EOF */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment