patch-2.1.36 linux/drivers/net/wavelan.c
Next file: linux/drivers/net/wavelan.p.h
Previous file: linux/drivers/net/tunnel.c
Back to the patch index
Back to the overall index
- Lines: 634
- Date:
Thu Apr 17 14:40:36 1997
- Orig file:
v2.1.35/linux/drivers/net/wavelan.c
- Orig date:
Fri Apr 4 08:52:22 1997
diff -u --recursive --new-file v2.1.35/linux/drivers/net/wavelan.c linux/drivers/net/wavelan.c
@@ -112,7 +112,7 @@
* Read from card's Host Adaptor Status Register.
*/
static inline u_short
-hasr_read(u_short ioaddr)
+hasr_read(u_long ioaddr)
{
return(inw(HASR(ioaddr)));
} /* hasr_read */
@@ -122,7 +122,7 @@
* Write to card's Host Adapter Command Register.
*/
static inline void
-hacr_write(u_short ioaddr,
+hacr_write(u_long ioaddr,
u_short hacr)
{
outw(hacr, HACR(ioaddr));
@@ -134,7 +134,7 @@
* those times when it is needed.
*/
static inline void
-hacr_write_slow(u_short ioaddr,
+hacr_write_slow(u_long ioaddr,
u_short hacr)
{
hacr_write(ioaddr, hacr);
@@ -147,7 +147,7 @@
* Set the channel attention bit.
*/
static inline void
-set_chan_attn(u_short ioaddr,
+set_chan_attn(u_long ioaddr,
u_short hacr)
{
hacr_write(ioaddr, hacr | HACR_CA);
@@ -158,7 +158,7 @@
* Reset, and then set host adaptor into default mode.
*/
static inline void
-wv_hacr_reset(u_short ioaddr)
+wv_hacr_reset(u_long ioaddr)
{
hacr_write_slow(ioaddr, HACR_RESET);
hacr_write(ioaddr, HACR_DEFAULT);
@@ -169,7 +169,7 @@
* Set the i/o transfer over the ISA bus to 8 bits mode
*/
static inline void
-wv_16_off(u_short ioaddr,
+wv_16_off(u_long ioaddr,
u_short hacr)
{
hacr &= ~HACR_16BITS;
@@ -181,7 +181,7 @@
* Set the i/o transfer over the ISA bus to 8 bits mode
*/
static inline void
-wv_16_on(u_short ioaddr,
+wv_16_on(u_long ioaddr,
u_short hacr)
{
hacr |= HACR_16BITS;
@@ -196,7 +196,7 @@
wv_ints_off(device * dev)
{
net_local * lp = (net_local *)dev->priv;
- u_short ioaddr = dev->base_addr;
+ u_long ioaddr = dev->base_addr;
u_long x;
x = wv_splhi();
@@ -215,7 +215,7 @@
wv_ints_on(device * dev)
{
net_local * lp = (net_local *)dev->priv;
- u_short ioaddr = dev->base_addr;
+ u_long ioaddr = dev->base_addr;
u_long x;
x = wv_splhi();
@@ -239,7 +239,7 @@
* Read bytes from the PSA.
*/
static void
-psa_read(u_short ioaddr,
+psa_read(u_long ioaddr,
u_short hacr,
int o, /* offset in PSA */
u_char * b, /* buffer to fill */
@@ -262,7 +262,7 @@
* Write the Paramter Storage Area to the WaveLAN card's memory
*/
static void
-psa_write(u_short ioaddr,
+psa_write(u_long ioaddr,
u_short hacr,
int o, /* Offset in psa */
u_char * b, /* Buffer in memory */
@@ -329,7 +329,7 @@
* Write 1 byte to the MMC.
*/
static inline void
-mmc_out(u_short ioaddr,
+mmc_out(u_long ioaddr,
u_short o,
u_char d)
{
@@ -347,7 +347,7 @@
* We start by the end because it is the way it should be !
*/
static inline void
-mmc_write(u_short ioaddr,
+mmc_write(u_long ioaddr,
u_char o,
u_char * b,
int n)
@@ -365,7 +365,7 @@
* Optimised version for 1 byte, avoid using memory...
*/
static inline u_char
-mmc_in(u_short ioaddr,
+mmc_in(u_long ioaddr,
u_short o)
{
while(inw(HASR(ioaddr)) & HASR_MMC_BUSY)
@@ -386,7 +386,7 @@
* We start by the end because it is the way it should be !
*/
static inline void
-mmc_read(u_short ioaddr,
+mmc_read(u_long ioaddr,
u_char o,
u_char * b,
int n)
@@ -400,11 +400,27 @@
/*------------------------------------------------------------------*/
/*
+ * Get the type of encryption available...
+ */
+static inline int
+mmc_encr(u_long ioaddr) /* i/o port of the card */
+{
+ int temp;
+
+ temp = mmc_in(ioaddr, mmroff(0, mmr_des_avail));
+ if((temp != MMR_DES_AVAIL_DES) && (temp != MMR_DES_AVAIL_AES))
+ return 0;
+ else
+ return temp;
+}
+
+/*------------------------------------------------------------------*/
+/*
* Wait for the frequency EEprom to complete a command...
* I hope this one will be optimally inlined...
*/
static inline void
-fee_wait(u_short ioaddr, /* i/o port of the card */
+fee_wait(u_long ioaddr, /* i/o port of the card */
int delay, /* Base delay to wait for */
int number) /* Number of time to wait */
{
@@ -420,7 +436,7 @@
* Read bytes from the Frequency EEprom (frequency select cards).
*/
static void
-fee_read(u_short ioaddr, /* i/o port of the card */
+fee_read(u_long ioaddr, /* i/o port of the card */
u_short o, /* destination offset */
u_short * b, /* data buffer */
int n) /* number of registers */
@@ -445,6 +461,8 @@
}
}
+#ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */
+
/*------------------------------------------------------------------*/
/*
* Write bytes from the Frequency EEprom (frequency select cards).
@@ -453,7 +471,7 @@
* Jean II
*/
static void
-fee_write(u_short ioaddr, /* i/o port of the card */
+fee_write(u_long ioaddr, /* i/o port of the card */
u_short o, /* destination offset */
u_short * b, /* data buffer */
int n) /* number of registers */
@@ -528,6 +546,7 @@
fee_wait(ioaddr, 10, 100);
#endif /* EEPROM_IS_PROTECTED */
}
+#endif /* WIRELESS_EXT */
/************************ I82586 SUBROUTINES *************************/
/*
@@ -540,7 +559,7 @@
* Why inlining this function make it fail ???
*/
static /*inline*/ void
-obram_read(u_short ioaddr,
+obram_read(u_long ioaddr,
u_short o,
u_char * b,
int n)
@@ -554,7 +573,7 @@
* Write bytes to the on-board RAM.
*/
static inline void
-obram_write(u_short ioaddr,
+obram_write(u_long ioaddr,
u_short o,
u_char * b,
int n)
@@ -571,7 +590,7 @@
wv_ack(device * dev)
{
net_local * lp = (net_local *)dev->priv;
- u_short ioaddr = dev->base_addr;
+ u_long ioaddr = dev->base_addr;
u_short scb_cs;
int i;
@@ -614,7 +633,7 @@
const char * str)
{
net_local * lp = (net_local *)dev->priv;
- u_short ioaddr = dev->base_addr;
+ u_long ioaddr = dev->base_addr;
u_short scb_cmd;
ach_t cb;
int i;
@@ -660,7 +679,7 @@
*/
static inline int
wv_config_complete(device * dev,
- u_short ioaddr,
+ u_long ioaddr,
net_local * lp)
{
unsigned short mcs_addr;
@@ -722,7 +741,7 @@
*/
static int
wv_complete(device * dev,
- u_short ioaddr,
+ u_long ioaddr,
net_local * lp)
{
int nreaped = 0;
@@ -992,7 +1011,7 @@
static void
wv_mmc_show(device * dev)
{
- u_short ioaddr = dev->base_addr;
+ u_long ioaddr = dev->base_addr;
net_local * lp = (net_local *)dev->priv;
mmr_t m;
@@ -1077,7 +1096,7 @@
* Print the last block of the i82586 memory
*/
static void
-wv_scb_show(unsigned short ioaddr)
+wv_scb_show(u_long ioaddr)
{
scb_t scb;
@@ -1162,7 +1181,7 @@
int i,
u_short p)
{
- unsigned short ioaddr;
+ u_long ioaddr;
ac_tx_t actx;
ioaddr = dev->base_addr;
@@ -1529,7 +1548,7 @@
* (called in wavelan_ioctl)
*/
static inline int
-wv_set_frequency(u_short ioaddr, /* i/o port of the card */
+wv_set_frequency(u_long ioaddr, /* i/o port of the card */
iw_freq * frequency)
{
const int BAND_NUM = 10; /* Number of bands */
@@ -1550,7 +1569,7 @@
}
/* Setting by channel (same as wfreqsel) */
- /* Warning : each channel is 11MHz wide, so some of the channels
+ /* Warning : each channel is 22MHz wide, so some of the channels
* will interfere... */
if((frequency->e == 0) &&
(frequency->m >= 0) && (frequency->m < BAND_NUM))
@@ -1729,7 +1748,7 @@
* Give the list of available frequencies
*/
static inline int
-wv_frequency_list(u_short ioaddr, /* i/o port of the card */
+wv_frequency_list(u_long ioaddr, /* i/o port of the card */
iw_freq * list, /* List of frequency to fill */
int max) /* Maximum number of frequencies */
{
@@ -1826,7 +1845,7 @@
struct ifreq * rq, /* Data passed */
int cmd) /* Ioctl number */
{
- unsigned short ioaddr = dev->base_addr;
+ u_long ioaddr = dev->base_addr;
net_local * lp = (net_local *)dev->priv; /* lp is not unused */
struct iwreq * wrq = (struct iwreq *) rq;
psa_t psa;
@@ -1866,9 +1885,7 @@
m.w.mmw_netw_id_h = (wrq->u.nwid.nwid & 0xFF00) >> 8;
mmc_write(ioaddr, (char *)&m.w.mmw_netw_id_l - (char *)&m,
(unsigned char *)&m.w.mmw_netw_id_l, 2);
- m.w.mmw_loopt_sel = 0x00;
- mmc_write(ioaddr, (char *)&m.w.mmw_loopt_sel - (char *)&m,
- (unsigned char *)&m.w.mmw_loopt_sel, 1);
+ mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel), 0x00);
}
else
{
@@ -1878,10 +1895,8 @@
(char *)&psa.psa_nwid_select - (char *)&psa,
(unsigned char *)&psa.psa_nwid_select, 1);
- /* Disable nwid in the mmc (no check) */
- m.w.mmw_loopt_sel = MMW_LOOPT_SEL_DIS_NWID;
- mmc_write(ioaddr, (char *)&m.w.mmw_loopt_sel - (char *)&m,
- (unsigned char *)&m.w.mmw_loopt_sel, 1);
+ /* Disable nwid in the mmc (no filtering) */
+ mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel), MMW_LOOPT_SEL_DIS_NWID);
}
break;
@@ -1950,6 +1965,82 @@
wrq->u.sensitivity = psa.psa_thr_pre_set & 0x3F;
break;
+ case SIOCSIWENCODE:
+ /* Set encryption key */
+ if(!mmc_encr(ioaddr))
+ {
+ ret = -EOPNOTSUPP;
+ break;
+ }
+
+ if(wrq->u.encoding.method)
+ { /* enable encryption */
+ int i;
+ long long key = wrq->u.encoding.code;
+
+ for(i = 7; i >= 0; i--)
+ {
+ psa.psa_encryption_key[i] = key & 0xFF;
+ key >>= 8;
+ }
+ psa.psa_encryption_select = 1;
+ psa_write(ioaddr, lp->hacr,
+ (char *) &psa.psa_encryption_select - (char *) &psa,
+ (unsigned char *) &psa.psa_encryption_select, 8+1);
+
+ mmc_out(ioaddr, mmwoff(0, mmw_encr_enable),
+ MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE);
+ mmc_write(ioaddr, mmwoff(0, mmw_encr_key),
+ (unsigned char *) &psa.psa_encryption_key, 8);
+ }
+ else
+ { /* disable encryption */
+ psa.psa_encryption_select = 0;
+ psa_write(ioaddr, lp->hacr,
+ (char *) &psa.psa_encryption_select - (char *) &psa,
+ (unsigned char *) &psa.psa_encryption_select, 1);
+
+ mmc_out(ioaddr, mmwoff(0, mmw_encr_enable), 0);
+ }
+ break;
+
+ case SIOCGIWENCODE:
+ /* Read the encryption key */
+ if(!mmc_encr(ioaddr))
+ {
+ ret = -EOPNOTSUPP;
+ break;
+ }
+
+ /* only super-user can see encryption key */
+ if(!suser())
+ {
+ ret = -EPERM;
+ break;
+ }
+ else
+ {
+ int i;
+ long long key = 0;
+
+ psa_read(ioaddr, lp->hacr,
+ (char *) &psa.psa_encryption_select - (char *) &psa,
+ (unsigned char *) &psa.psa_encryption_select, 1+8);
+ for(i = 0; i < 8; i++)
+ {
+ key <<= 8;
+ key += psa.psa_encryption_key[i];
+ }
+ wrq->u.encoding.code = key;
+
+ /* encryption is enabled */
+ if(psa.psa_encryption_select)
+ wrq->u.encoding.method = mmc_encr(ioaddr);
+ else
+ wrq->u.encoding.method = 0;
+ }
+ break;
+
case SIOCGIWRANGE:
/* Basic checking... */
if(wrq->u.data.pointer != (caddr_t) 0)
@@ -2207,7 +2298,7 @@
static iw_stats *
wavelan_get_wireless_stats(device * dev)
{
- unsigned short ioaddr = dev->base_addr;
+ u_long ioaddr = dev->base_addr;
net_local * lp = (net_local *) dev->priv;
mmr_t m;
iw_stats * wstats;
@@ -2281,7 +2372,7 @@
int sksize)
{
net_local * lp = (net_local *) dev->priv;
- u_short ioaddr = dev->base_addr;
+ u_long ioaddr = dev->base_addr;
struct sk_buff * skb;
#ifdef DEBUG_RX_TRACE
@@ -2353,8 +2444,9 @@
*/
netif_rx(skb);
+ /* Keep stats up to date */
lp->stats.rx_packets++;
- lp->stats.rx_bytes+=sksize;
+ lp->stats.rx_bytes += skb->len;
#ifdef DEBUG_RX_TRACE
printk(KERN_DEBUG "%s: <-wv_packet_read()\n", dev->name);
@@ -2370,7 +2462,7 @@
static inline void
wv_receive(device * dev)
{
- u_short ioaddr = dev->base_addr;
+ u_long ioaddr = dev->base_addr;
net_local * lp = (net_local *)dev->priv;
int nreaped = 0;
@@ -2556,7 +2648,7 @@
short length)
{
net_local * lp = (net_local *) dev->priv;
- u_short ioaddr = dev->base_addr;
+ u_long ioaddr = dev->base_addr;
unsigned short txblock;
unsigned short txpred;
unsigned short tx_addr;
@@ -2649,6 +2741,9 @@
(unsigned char *) &nop.nop_h.ac_link,
sizeof(nop.nop_h.ac_link));
+ /* Keep stats up to date */
+ lp->stats.tx_bytes += length;
+
/* If watchdog not already active, activate it... */
if(lp->watchdog.prev == (timer_list *) NULL)
{
@@ -2701,20 +2796,6 @@
return 1;
/*
- * If some higher layer thinks we've missed
- * a tx-done interrupt we are passed NULL.
- * Caution: dev_tint() handles the cli()/sti() itself.
- */
- if(skb == (struct sk_buff *)0)
- {
-#ifdef DEBUG_TX_ERROR
- printk(KERN_INFO "%s: wavelan_packet_xmit(): skb == NULL\n", dev->name);
-#endif
- dev_tint(dev);
- return 0;
- }
-
- /*
* Block a timer-based transmit from overlapping.
* In other words, prevent reentering this routine.
*/
@@ -2761,7 +2842,7 @@
static inline int
wv_mmc_init(device * dev)
{
- u_short ioaddr = dev->base_addr;
+ u_long ioaddr = dev->base_addr;
net_local * lp = (net_local *)dev->priv;
psa_t psa;
mmw_t m;
@@ -2790,6 +2871,9 @@
/* As NWID is not set : no NWID checking */
psa.psa_nwid_select = 0;
+ /* Disable encryption */
+ psa.psa_encryption_select = 0;
+
/* Set to standard values
* 0x04 for AT,
* 0x01 for MCA,
@@ -2807,7 +2891,7 @@
#ifdef USE_PSA_CONFIG
/* Write the psa */
psa_write(ioaddr, lp->hacr, (char *)psa.psa_nwid - (char *)&psa,
- (unsigned char *)psa.psa_nwid, 3);
+ (unsigned char *)psa.psa_nwid, 4);
psa_write(ioaddr, lp->hacr, (char *)&psa.psa_thr_pre_set - (char *)&psa,
(unsigned char *)&psa.psa_thr_pre_set, 1);
psa_write(ioaddr, lp->hacr, (char *)&psa.psa_quality_thr - (char *)&psa,
@@ -2829,6 +2913,14 @@
else
m.mmw_loopt_sel = MMW_LOOPT_SEL_DIS_NWID;
+ memcpy(&m.mmw_encr_key, &psa.psa_encryption_key,
+ sizeof(m.mmw_encr_key));
+
+ if(psa.psa_encryption_select)
+ m.mmw_encr_enable = MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE;
+ else
+ m.mmw_encr_enable = 0;
+
m.mmw_thr_pre_set = psa.psa_thr_pre_set & 0x3F;
m.mmw_quality_thr = psa.psa_quality_thr & 0x0F;
@@ -2920,7 +3012,7 @@
wv_ru_start(device * dev)
{
net_local * lp = (net_local *) dev->priv;
- u_short ioaddr = dev->base_addr;
+ u_long ioaddr = dev->base_addr;
u_short scb_cs;
fd_t fd;
rbd_t rbd;
@@ -3014,7 +3106,7 @@
wv_cu_start(device * dev)
{
net_local * lp = (net_local *) dev->priv;
- u_short ioaddr = dev->base_addr;
+ u_long ioaddr = dev->base_addr;
int i;
u_short txblock;
u_short first_nop;
@@ -3115,7 +3207,7 @@
wv_82586_start(device * dev)
{
net_local * lp = (net_local *) dev->priv;
- u_short ioaddr = dev->base_addr;
+ u_long ioaddr = dev->base_addr;
scp_t scp; /* system configuration pointer */
iscp_t iscp; /* intermediate scp */
scb_t scb; /* system control block */
@@ -3245,7 +3337,7 @@
wv_82586_config(device * dev)
{
net_local * lp = (net_local *) dev->priv;
- u_short ioaddr = dev->base_addr;
+ u_long ioaddr = dev->base_addr;
unsigned short txblock;
unsigned short txpred;
unsigned short tx_addr;
@@ -3441,7 +3533,7 @@
wv_82586_stop(device * dev)
{
net_local * lp = (net_local *) dev->priv;
- u_short ioaddr = dev->base_addr;
+ u_long ioaddr = dev->base_addr;
u_short scb_cmd;
#ifdef DEBUG_CONFIG_TRACE
@@ -3476,7 +3568,7 @@
wv_hw_reset(device * dev)
{
net_local * lp = (net_local *)dev->priv;
- u_short ioaddr = dev->base_addr;
+ u_long ioaddr = dev->base_addr;
#ifdef DEBUG_CONFIG_TRACE
printk(KERN_DEBUG "%s: ->wv_hw_reset(dev=0x%x)\n", dev->name,
@@ -3521,7 +3613,7 @@
* (called in wavelan_probe() and init_module())
*/
static int
-wv_check_ioaddr(u_short ioaddr,
+wv_check_ioaddr(u_long ioaddr,
u_char * mac)
{
int i; /* Loop counter */
@@ -3568,7 +3660,7 @@
struct pt_regs * regs)
{
device * dev;
- u_short ioaddr;
+ u_long ioaddr;
net_local * lp;
u_short hasr;
u_short status;
@@ -3715,7 +3807,7 @@
{
device * dev;
net_local * lp;
- unsigned short ioaddr;
+ u_long ioaddr;
unsigned long x;
unsigned int nreaped;
@@ -3910,7 +4002,7 @@
static int
wavelan_config(device * dev)
{
- u_short ioaddr = dev->base_addr;
+ u_long ioaddr = dev->base_addr;
u_char irq_mask;
int irq;
net_local * lp;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov