summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wavelan.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2009-10-28 16:06:56 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-10-30 16:50:34 -0400
commit0234f84ebb00d36c48062befa5436eef36b71ccd (patch)
treea0bd2a87406bb15067414118d4eb12cee80036e9 /drivers/net/wireless/wavelan.c
parente38879efd336fb78b288dcebdc9ca030fd24f449 (diff)
wavelan: move driver to staging
Move the wavelan driver to drivers/staging. This is another pre-802.11 driver that has seen virtually no non-API-fixup activity in years, and for which no active hardware is likely to still exist. This driver represents unnecessary ongoing maintenance for no clear benefit. This patch brought to you by the "hacking" session at the 2009 Kernel Summit in Tokyo, Japan... Acked-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/wavelan.c')
-rw-r--r--drivers/net/wireless/wavelan.c4383
1 files changed, 0 insertions, 4383 deletions
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
deleted file mode 100644
index d634b2da3b84..000000000000
--- a/drivers/net/wireless/wavelan.c
+++ /dev/null
@@ -1,4383 +0,0 @@
-/*
- * WaveLAN ISA driver
- *
- * Jean II - HPLB '96
- *
- * Reorganisation and extension of the driver.
- * Original copyright follows (also see the end of this file).
- * See wavelan.p.h for details.
- *
- *
- *
- * AT&T GIS (nee NCR) WaveLAN card:
- * An Ethernet-like radio transceiver
- * controlled by an Intel 82586 coprocessor.
- */
-
-#include "wavelan.p.h" /* Private header */
-
-/************************* MISC SUBROUTINES **************************/
-/*
- * Subroutines which won't fit in one of the following category
- * (WaveLAN modem or i82586)
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Translate irq number to PSA irq parameter
- */
-static u8 wv_irq_to_psa(int irq)
-{
- if (irq < 0 || irq >= ARRAY_SIZE(irqvals))
- return 0;
-
- return irqvals[irq];
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Translate PSA irq parameter to irq number
- */
-static int __init wv_psa_to_irq(u8 irqval)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(irqvals); i++)
- if (irqvals[i] == irqval)
- return i;
-
- return -1;
-}
-
-/********************* HOST ADAPTER SUBROUTINES *********************/
-/*
- * Useful subroutines to manage the WaveLAN ISA interface
- *
- * One major difference with the PCMCIA hardware (except the port mapping)
- * is that we have to keep the state of the Host Control Register
- * because of the interrupt enable & bus size flags.
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Read from card's Host Adaptor Status Register.
- */
-static inline u16 hasr_read(unsigned long ioaddr)
-{
- return (inw(HASR(ioaddr)));
-} /* hasr_read */
-
-/*------------------------------------------------------------------*/
-/*
- * Write to card's Host Adapter Command Register.
- */
-static inline void hacr_write(unsigned long ioaddr, u16 hacr)
-{
- outw(hacr, HACR(ioaddr));
-} /* hacr_write */
-
-/*------------------------------------------------------------------*/
-/*
- * Write to card's Host Adapter Command Register. Include a delay for
- * those times when it is needed.
- */
-static void hacr_write_slow(unsigned long ioaddr, u16 hacr)
-{
- hacr_write(ioaddr, hacr);
- /* delay might only be needed sometimes */
- mdelay(1);
-} /* hacr_write_slow */
-
-/*------------------------------------------------------------------*/
-/*
- * Set the channel attention bit.
- */
-static inline void set_chan_attn(unsigned long ioaddr, u16 hacr)
-{
- hacr_write(ioaddr, hacr | HACR_CA);
-} /* set_chan_attn */
-
-/*------------------------------------------------------------------*/
-/*
- * Reset, and then set host adaptor into default mode.
- */
-static inline void wv_hacr_reset(unsigned long ioaddr)
-{
- hacr_write_slow(ioaddr, HACR_RESET);
- hacr_write(ioaddr, HACR_DEFAULT);
-} /* wv_hacr_reset */
-
-/*------------------------------------------------------------------*/
-/*
- * Set the I/O transfer over the ISA bus to 8-bit mode
- */
-static inline void wv_16_off(unsigned long ioaddr, u16 hacr)
-{
- hacr &= ~HACR_16BITS;
- hacr_write(ioaddr, hacr);
-} /* wv_16_off */
-
-/*------------------------------------------------------------------*/
-/*
- * Set the I/O transfer over the ISA bus to 8-bit mode
- */
-static inline void wv_16_on(unsigned long ioaddr, u16 hacr)
-{
- hacr |= HACR_16BITS;
- hacr_write(ioaddr, hacr);
-} /* wv_16_on */
-
-/*------------------------------------------------------------------*/
-/*
- * Disable interrupts on the WaveLAN hardware.
- * (called by wv_82586_stop())
- */
-static inline void wv_ints_off(struct net_device * dev)
-{
- net_local *lp = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
-
- lp->hacr &= ~HACR_INTRON;
- hacr_write(ioaddr, lp->hacr);
-} /* wv_ints_off */
-
-/*------------------------------------------------------------------*/
-/*
- * Enable interrupts on the WaveLAN hardware.
- * (called by wv_hw_reset())
- */
-static inline void wv_ints_on(struct net_device * dev)
-{
- net_local *lp = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
-
- lp->hacr |= HACR_INTRON;
- hacr_write(ioaddr, lp->hacr);
-} /* wv_ints_on */
-
-/******************* MODEM MANAGEMENT SUBROUTINES *******************/
-/*
- * Useful subroutines to manage the modem of the WaveLAN
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Read the Parameter Storage Area from the WaveLAN card's memory
- */
-/*
- * Read bytes from the PSA.
- */
-static void psa_read(unsigned long ioaddr, u16 hacr, int o, /* offset in PSA */
- u8 * b, /* buffer to fill */
- int n)
-{ /* size to read */
- wv_16_off(ioaddr, hacr);
-
- while (n-- > 0) {
- outw(o, PIOR2(ioaddr));
- o++;
- *b++ = inb(PIOP2(ioaddr));
- }
-
- wv_16_on(ioaddr, hacr);
-} /* psa_read */
-
-/*------------------------------------------------------------------*/
-/*
- * Write the Parameter Storage Area to the WaveLAN card's memory.
- */
-static void psa_write(unsigned long ioaddr, u16 hacr, int o, /* Offset in PSA */
- u8 * b, /* Buffer in memory */
- int n)
-{ /* Length of buffer */
- int count = 0;
-
- wv_16_off(ioaddr, hacr);
-
- while (n-- > 0) {
- outw(o, PIOR2(ioaddr));
- o++;
-
- outb(*b, PIOP2(ioaddr));
- b++;
-
- /* Wait for the memory to finish its write cycle */
- count = 0;
- while ((count++ < 100) &&
- (hasr_read(ioaddr) & HASR_PSA_BUSY)) mdelay(1);
- }
-
- wv_16_on(ioaddr, hacr);
-} /* psa_write */
-
-#ifdef SET_PSA_CRC
-/*------------------------------------------------------------------*/
-/*
- * Calculate the PSA CRC
- * Thanks to Valster, Nico <NVALSTER@wcnd.nl.lucent.com> for the code
- * NOTE: By specifying a length including the CRC position the
- * returned value should be zero. (i.e. a correct checksum in the PSA)
- *
- * The Windows drivers don't use the CRC, but the AP and the PtP tool
- * depend on it.
- */
-static u16 psa_crc(u8 * psa, /* The PSA */
- int size)
-{ /* Number of short for CRC */
- int byte_cnt; /* Loop on the PSA */
- u16 crc_bytes = 0; /* Data in the PSA */
- int bit_cnt; /* Loop on the bits of the short */
-
- for (byte_cnt = 0; byte_cnt < size; byte_cnt++) {
- crc_bytes ^= psa[byte_cnt]; /* Its an xor */
-
- for (bit_cnt = 1; bit_cnt < 9; bit_cnt++) {
- if (crc_bytes & 0x0001)
- crc_bytes = (crc_bytes >> 1) ^ 0xA001;
- else
- crc_bytes >>= 1;
- }
- }
-
- return crc_bytes;
-} /* psa_crc */
-#endif /* SET_PSA_CRC */
-
-/*------------------------------------------------------------------*/
-/*
- * update the checksum field in the Wavelan's PSA
- */
-static void update_psa_checksum(struct net_device * dev, unsigned long ioaddr, u16 hacr)
-{
-#ifdef SET_PSA_CRC
- psa_t psa;
- u16 crc;
-
- /* read the parameter storage area */
- psa_read(ioaddr, hacr, 0, (unsigned char *) &psa, sizeof(psa));
-
- /* update the checksum */
- crc = psa_crc((unsigned char *) &psa,
- sizeof(psa) - sizeof(psa.psa_crc[0]) -
- sizeof(psa.psa_crc[1])
- - sizeof(psa.psa_crc_status));
-
- psa.psa_crc[0] = crc & 0xFF;
- psa.psa_crc[1] = (crc & 0xFF00) >> 8;
-
- /* Write it ! */
- psa_write(ioaddr, hacr, (char *) &psa.psa_crc - (char *) &psa,
- (unsigned char *) &psa.psa_crc, 2);
-
-#ifdef DEBUG_IOCTL_INFO
- printk(KERN_DEBUG "%s: update_psa_checksum(): crc = 0x%02x%02x\n",
- dev->name, psa.psa_crc[0], psa.psa_crc[1]);
-
- /* Check again (luxury !) */
- crc = psa_crc((unsigned char *) &psa,
- sizeof(psa) - sizeof(psa.psa_crc_status));
-
- if (crc != 0)
- printk(KERN_WARNING
- "%s: update_psa_checksum(): CRC does not agree with PSA data (even after recalculating)\n",
- dev->name);
-#endif /* DEBUG_IOCTL_INFO */
-#endif /* SET_PSA_CRC */
-} /* update_psa_checksum */
-
-/*------------------------------------------------------------------*/
-/*
- * Write 1 byte to the MMC.
- */
-static void mmc_out(unsigned long ioaddr, u16 o, u8 d)
-{
- int count = 0;
-
- /* Wait for MMC to go idle */
- while ((count++ < 100) && (inw(HASR(ioaddr)) & HASR_MMC_BUSY))
- udelay(10);
-
- outw((u16) (((u16) d << 8) | (o << 1) | 1), MMCR(ioaddr));
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Routine to write bytes to the Modem Management Controller.
- * We start at the end because it is the way it should be!
- */
-static void mmc_write(unsigned long ioaddr, u8 o, u8 * b, int n)
-{
- o += n;
- b += n;
-
- while (n-- > 0)
- mmc_out(ioaddr, --o, *(--b));
-} /* mmc_write */
-
-/*------------------------------------------------------------------*/
-/*
- * Read a byte from the MMC.
- * Optimised version for 1 byte, avoid using memory.
- */
-static u8 mmc_in(unsigned long ioaddr, u16 o)
-{
- int count = 0;
-
- while ((count++ < 100) && (inw(HASR(ioaddr)) & HASR_MMC_BUSY))
- udelay(10);
- outw(o << 1, MMCR(ioaddr));
-
- while ((count++ < 100) && (inw(HASR(ioaddr)) & HASR_MMC_BUSY))
- udelay(10);
- return (u8) (inw(MMCR(ioaddr)) >> 8);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Routine to read bytes from the Modem Management Controller.
- * The implementation is complicated by a lack of address lines,
- * which prevents decoding of the low-order bit.
- * (code has just been moved in the above function)
- * We start at the end because it is the way it should be!
- */
-static inline void mmc_read(unsigned long ioaddr, u8 o, u8 * b, int n)
-{
- o += n;
- b += n;
-
- while (n-- > 0)
- *(--b) = mmc_in(ioaddr, --o);
-} /* mmc_read */
-
-/*------------------------------------------------------------------*/
-/*
- * Get the type of encryption available.
- */
-static inline int mmc_encr(unsigned 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(unsigned long ioaddr, /* I/O port of the card */
- int delay, /* Base delay to wait for */
- int number)
-{ /* Number of time to wait */
- int count = 0; /* Wait only a limited time */
-
- while ((count++ < number) &&
- (mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
- MMR_FEE_STATUS_BUSY)) udelay(delay);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Read bytes from the Frequency EEPROM (frequency select cards).
- */
-static void fee_read(unsigned long ioaddr, /* I/O port of the card */
- u16 o, /* destination offset */
- u16 * b, /* data buffer */
- int n)
-{ /* number of registers */
- b += n; /* Position at the end of the area */
-
- /* Write the address */
- mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), o + n - 1);
-
- /* Loop on all buffer */
- while (n-- > 0) {
- /* Write the read command */
- mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl),
- MMW_FEE_CTRL_READ);
-
- /* Wait until EEPROM is ready (should be quick). */
- fee_wait(ioaddr, 10, 100);
-
- /* Read the value. */
- *--b = ((mmc_in(ioaddr, mmroff(0, mmr_fee_data_h)) << 8) |
- mmc_in(ioaddr, mmroff(0, mmr_fee_data_l)));
- }
-}
-
-
-/*------------------------------------------------------------------*/
-/*
- * Write bytes from the Frequency EEPROM (frequency select cards).
- * This is a bit complicated, because the frequency EEPROM has to
- * be unprotected and the write enabled.
- * Jean II
- */
-static void fee_write(unsigned long ioaddr, /* I/O port of the card */
- u16 o, /* destination offset */
- u16 * b, /* data buffer */
- int n)
-{ /* number of registers */
- b += n; /* Position at the end of the area. */
-
-#ifdef EEPROM_IS_PROTECTED /* disabled */
-#ifdef DOESNT_SEEM_TO_WORK /* disabled */
- /* Ask to read the protected register */
- mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRREAD);
-
- fee_wait(ioaddr, 10, 100);
-
- /* Read the protected register. */
- printk("Protected 2: %02X-%02X\n",
- mmc_in(ioaddr, mmroff(0, mmr_fee_data_h)),
- mmc_in(ioaddr, mmroff(0, mmr_fee_data_l)));
-#endif /* DOESNT_SEEM_TO_WORK */
-
- /* Enable protected register. */
- mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN);
- mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PREN);
-
- fee_wait(ioaddr, 10, 100);
-
- /* Unprotect area. */
- mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), o + n);
- mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);
-#ifdef DOESNT_SEEM_TO_WORK /* disabled */
- /* or use: */
- mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRCLEAR);
-#endif /* DOESNT_SEEM_TO_WORK */
-
- fee_wait(ioaddr, 10, 100);
-#endif /* EEPROM_IS_PROTECTED */
-
- /* Write enable. */
- mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN);
- mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WREN);
-
- fee_wait(ioaddr, 10, 100);
-
- /* Write the EEPROM address. */
- mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), o + n - 1);
-
- /* Loop on all buffer */
- while (n-- > 0) {
- /* Write the value. */
- mmc_out(ioaddr, mmwoff(0, mmw_fee_data_h), (*--b) >> 8);
- mmc_out(ioaddr, mmwoff(0, mmw_fee_data_l), *b & 0xFF);
-
- /* Write the write command. */
- mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl),
- MMW_FEE_CTRL_WRITE);
-
- /* WaveLAN documentation says to wait at least 10 ms for EEBUSY = 0 */
- mdelay(10);
- fee_wait(ioaddr, 10, 100);
- }
-
- /* Write disable. */
- mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_DS);
- mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WDS);
-
- fee_wait(ioaddr, 10, 100);
-
-#ifdef EEPROM_IS_PROTECTED /* disabled */
- /* Reprotect EEPROM. */
- mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), 0x00);
- mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);
-
- fee_wait(ioaddr, 10, 100);
-#endif /* EEPROM_IS_PROTECTED */
-}
-
-/************************ I82586 SUBROUTINES *************************/
-/*
- * Useful subroutines to manage the Ethernet controller
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Read bytes from the on-board RAM.
- * Why does inlining this function make it fail?
- */
-static /*inline */ void obram_read(unsigned long ioaddr,
- u16 o, u8 * b, int n)
-{
- outw(o, PIOR1(ioaddr));
- insw(PIOP1(ioaddr), (unsigned short *) b, (n + 1) >> 1);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Write bytes to the on-board RAM.
- */
-static inline void obram_write(unsigned long ioaddr, u16 o, u8 * b, int n)
-{
- outw(o, PIOR1(ioaddr));
- outsw(PIOP1(ioaddr), (unsigned short *) b, (n + 1) >> 1);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Acknowledge the reading of the status issued by the i82586.
- */
-static void wv_ack(struct net_device * dev)
-{
- net_local *lp = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
- u16 scb_cs;
- int i;
-
- obram_read(ioaddr, scboff(OFFSET_SCB, scb_status),
- (unsigned char *) &scb_cs, sizeof(scb_cs));
- scb_cs &= SCB_ST_INT;
-
- if (scb_cs == 0)
- return;
-
- obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
- (unsigned char *) &scb_cs, sizeof(scb_cs));
-
- set_chan_attn(ioaddr, lp->hacr);
-
- for (i = 1000; i > 0; i--) {
- obram_read(ioaddr, scboff(OFFSET_SCB, scb_command),
- (unsigned char *) &scb_cs, sizeof(scb_cs));
- if (scb_cs == 0)
- break;
-
- udelay(10);
- }
- udelay(100);
-
-#ifdef DEBUG_CONFIG_ERROR
- if (i <= 0)
- printk(KERN_INFO
- "%s: wv_ack(): board not accepting command.\n",
- dev->name);
-#endif
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Set channel attention bit and busy wait until command has
- * completed, then acknowledge completion of the command.
- */
-static int wv_synchronous_cmd(struct net_device * dev, const char *str)
-{
- net_local *lp = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
- u16 scb_cmd;
- ach_t cb;
- int i;
-
- scb_cmd = SCB_CMD_CUC & SCB_CMD_CUC_GO;
- obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
- (unsigned char *) &scb_cmd, sizeof(scb_cmd));
-
- set_chan_attn(ioaddr, lp->hacr);
-
- for (i = 1000; i > 0; i--) {
- obram_read(ioaddr, OFFSET_CU, (unsigned char *) &cb,
- sizeof(cb));
- if (cb.ac_status & AC_SFLD_C)
- break;
-
- udelay(10);
- }
- udelay(100);
-
- if (i <= 0 || !(cb.ac_status & AC_SFLD_OK)) {
-#ifdef DEBUG_CONFIG_ERROR
- printk(KERN_INFO "%s: %s failed; status = 0x%x\n",
- dev->name, str, cb.ac_status);
-#endif
-#ifdef DEBUG_I82586_SHOW
- wv_scb_show(ioaddr);
-#endif
- return -1;
- }
-
- /* Ack the status */
- wv_ack(dev);
-
- return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Configuration commands completion interrupt.
- * Check if done, and if OK.
- */
-static int
-wv_config_complete(struct net_device * dev, unsigned long ioaddr, net_local * lp)
-{
- unsigned short mcs_addr;
- unsigned short status;
- int ret;
-
-#ifdef DEBUG_INTERRUPT_TRACE
- printk(KERN_DEBUG "%s: ->wv_config_complete()\n", dev->name);
-#endif
-
- mcs_addr = lp->tx_first_in_use + sizeof(ac_tx_t) + sizeof(ac_nop_t)
- + sizeof(tbd_t) + sizeof(ac_cfg_t) + sizeof(ac_ias_t);
-
- /* Read the status of the last command (set mc list). */
- obram_read(ioaddr, acoff(mcs_addr, ac_status),
- (unsigned char *) &status, sizeof(status));
-
- /* If not completed -> exit */
- if ((status & AC_SFLD_C) == 0)
- ret = 0; /* Not ready to be scrapped */
- else {
-#ifdef DEBUG_CONFIG_ERROR
- unsigned short cfg_addr;
- unsigned short ias_addr;
-
- /* Check mc_config command */
- if ((status & AC_SFLD_OK) != AC_SFLD_OK)
- printk(KERN_INFO
- "%s: wv_config_complete(): set_multicast_address failed; status = 0x%x\n",
- dev->name, status);
-
- /* check ia-config command */
- ias_addr = mcs_addr - sizeof(ac_ias_t);
- obram_read(ioaddr, acoff(ias_addr, ac_status),
- (unsigned char *) &status, sizeof(status));
- if ((status & AC_SFLD_OK) != AC_SFLD_OK)
- printk(KERN_INFO
- "%s: wv_config_complete(): set_MAC_address failed; status = 0x%x\n",
- dev->name, status);
-
- /* Check config command. */
- cfg_addr = ias_addr - sizeof(ac_cfg_t);
- obram_read(ioaddr, acoff(cfg_addr, ac_status),
- (unsigned char *) &status, sizeof(status));
- if ((status & AC_SFLD_OK) != AC_SFLD_OK)
- printk(KERN_INFO
- "%s: wv_config_complete(): configure failed; status = 0x%x\n",
- dev->name, status);
-#endif /* DEBUG_CONFIG_ERROR */
-
- ret = 1; /* Ready to be scrapped */
- }
-
-#ifdef DEBUG_INTERRUPT_TRACE
- printk(KERN_DEBUG "%s: <-wv_config_complete() - %d\n", dev->name,
- ret);
-#endif
- return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Command completion interrupt.
- * Reclaim as many freed tx buffers as we can.
- * (called in wavelan_interrupt()).
- * Note : the spinlock is already grabbed for us.
- */
-static int wv_complete(struct net_device * dev, unsigned long ioaddr, net_local * lp)
-{
- int nreaped = 0;
-
-#ifdef DEBUG_INTERRUPT_TRACE
- printk(KERN_DEBUG "%s: ->wv_complete()\n", dev->name);
-#endif
-
- /* Loop on all the transmit buffers */
- while (lp->tx_first_in_use != I82586NULL) {
- unsigned short tx_status;
-
- /* Read the first transmit buffer */
- obram_read(ioaddr, acoff(lp->tx_first_in_use, ac_status),
- (unsigned char *) &tx_status,
- sizeof(tx_status));
-
- /* If not completed -> exit */
- if ((tx_status & AC_SFLD_C) == 0)
- break;
-
- /* Hack for reconfiguration */
- if (tx_status == 0xFFFF)
- if (!wv_config_complete(dev, ioaddr, lp))
- break; /* Not completed */
-
- /* We now remove this buffer */
- nreaped++;
- --lp->tx_n_in_use;
-
-/*
-if (lp->tx_n_in_use > 0)
- printk("%c", "0123456789abcdefghijk"[lp->tx_n_in_use]);
-*/
-
- /* Was it the last one? */
- if (lp->tx_n_in_use <= 0)
- lp->tx_first_in_use = I82586NULL;
- else {
- /* Next one in the chain */
- lp->tx_first_in_use += TXBLOCKZ;
- if (lp->tx_first_in_use >=
- OFFSET_CU +
- NTXBLOCKS * TXBLOCKZ) lp->tx_first_in_use -=
- NTXBLOCKS * TXBLOCKZ;
- }
-
- /* Hack for reconfiguration */
- if (tx_status == 0xFFFF)
- continue;
-
- /* Now, check status of the finished command */
- if (tx_status & AC_SFLD_OK) {
- int ncollisions;
-
- dev->stats.tx_packets++;
- ncollisions = tx_status & AC_SFLD_MAXCOL;
- dev->stats.collisions += ncollisions;
-#ifdef DEBUG_TX_INFO
- if (ncollisions > 0)
- printk(KERN_DEBUG
- "%s: wv_complete(): tx completed after %d collisions.\n",
- dev->name, ncollisions);
-#endif
- } else {
- dev->stats.tx_errors++;
- if (tx_status & AC_SFLD_S10) {
- dev->stats.tx_carrier_errors++;
-#ifdef DEBUG_TX_FAIL
- printk(KERN_DEBUG
- "%s: wv_complete(): tx error: no CS.\n",
- dev->name);
-#endif
- }
- if (tx_status & AC_SFLD_S9) {
- dev->stats.tx_carrier_errors++;
-#ifdef DEBUG_TX_FAIL
- printk(KERN_DEBUG
- "%s: wv_complete(): tx error: lost CTS.\n",
- dev->name);
-#endif
- }
- if (tx_status & AC_SFLD_S8) {
- dev->stats.tx_fifo_errors++;
-#ifdef DEBUG_TX_FAIL
- printk(KERN_DEBUG
- "%s: wv_complete(): tx error: slow DMA.\n",
- dev->name);
-#endif
- }
- if (tx_status & AC_SFLD_S6) {
- dev->stats.tx_heartbeat_errors++;
-#ifdef DEBUG_TX_FAIL
- printk(KERN_DEBUG
- "%s: wv_complete(): tx error: heart beat.\n",
- dev->name);
-#endif
- }
- if (tx_status & AC_SFLD_S5) {
- dev->stats.tx_aborted_errors++;
-#ifdef DEBUG_TX_FAIL
- printk(KERN_DEBUG
- "%s: wv_complete(): tx error: too many collisions.\n",
- dev->name);
-#endif
- }
- }
-
-#ifdef DEBUG_TX_INFO
- printk(KERN_DEBUG
- "%s: wv_complete(): tx completed, tx_status 0x%04x\n",
- dev->name, tx_status);
-#endif
- }
-
-#ifdef DEBUG_INTERRUPT_INFO
- if (nreaped > 1)
- printk(KERN_DEBUG "%s: wv_complete(): reaped %d\n",
- dev->name, nreaped);
-#endif
-
- /*
- * Inform upper layers.
- */
- if (lp->tx_n_in_use < NTXBLOCKS - 1) {
- netif_wake_queue(dev);
- }
-#ifdef DEBUG_INTERRUPT_TRACE
- printk(KERN_DEBUG "%s: <-wv_complete()\n", dev->name);
-#endif
- return nreaped;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Reconfigure the i82586, or at least ask for it.
- * Because wv_82586_config uses a transmission buffer, we must do it
- * when we are sure that there is one left, so we do it now
- * or in wavelan_packet_xmit() (I can't find any better place,
- * wavelan_interrupt is not an option), so you may experience
- * delays sometimes.
- */
-static void wv_82586_reconfig(struct net_device * dev)
-{
- net_local *lp = netdev_priv(dev);
- unsigned long flags;
-
- /* Arm the flag, will be cleard in wv_82586_config() */
- lp->reconfig_82586 = 1;
-
- /* Check if we can do it now ! */
- if((netif_running(dev)) && !(netif_queue_stopped(dev))) {
- spin_lock_irqsave(&lp->spinlock, flags);
- /* May fail */
- wv_82586_config(dev);
- spin_unlock_irqrestore(&lp->spinlock, flags);
- }
- else {
-#ifdef DEBUG_CONFIG_INFO
- printk(KERN_DEBUG
- "%s: wv_82586_reconfig(): delayed (state = %lX)\n",
- dev->name, dev->state);
-#endif
- }
-}
-
-/********************* DEBUG & INFO SUBROUTINES *********************/
-/*
- * This routine is used in the code to show information for debugging.
- * Most of the time, it dumps the contents of hardware structures.
- */
-
-#ifdef DEBUG_PSA_SHOW
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted contents of the Parameter Storage Area.
- */
-static void wv_psa_show(psa_t * p)
-{
- printk(KERN_DEBUG "##### WaveLAN PSA contents: #####\n");
- printk(KERN_DEBUG "psa_io_base_addr_1: 0x%02X %02X %02X %02X\n",
- p->psa_io_base_addr_1,
- p->psa_io_base_addr_2,
- p->psa_io_base_addr_3, p->psa_io_base_addr_4);
- printk(KERN_DEBUG "psa_rem_boot_addr_1: 0x%02X %02X %02X\n",
- p->psa_rem_boot_addr_1,
- p->psa_rem_boot_addr_2, p->psa_rem_boot_addr_3);
- printk(KERN_DEBUG "psa_holi_params: 0x%02x, ", p->psa_holi_params);
- printk("psa_int_req_no: %d\n", p->psa_int_req_no);
-#ifdef DEBUG_SHOW_UNUSED
- printk(KERN_DEBUG "psa_unused0[]: %pM\n", p->psa_unused0);
-#endif /* DEBUG_SHOW_UNUSED */
- printk(KERN_DEBUG "psa_univ_mac_addr[]: %pM\n", p->psa_univ_mac_addr);
- printk(KERN_DEBUG "psa_local_mac_addr[]: %pM\n", p->psa_local_mac_addr);
- printk(KERN_DEBUG "psa_univ_local_sel: %d, ",
- p->psa_univ_local_sel);
- printk("psa_comp_number: %d, ", p->psa_comp_number);
- printk("psa_thr_pre_set: 0x%02x\n", p->psa_thr_pre_set);
- printk(KERN_DEBUG "psa_feature_select/decay_prm: 0x%02x, ",
- p->psa_feature_select);
- printk("psa_subband/decay_update_prm: %d\n", p->psa_subband);
- printk(KERN_DEBUG "psa_quality_thr: 0x%02x, ", p->psa_quality_thr);
- printk("psa_mod_delay: 0x%02x\n", p->psa_mod_delay);
- printk(KERN_DEBUG "psa_nwid: 0x%02x%02x, ", p->psa_nwid[0],
- p->psa_nwid[1]);
- printk("psa_nwid_select: %d\n", p->psa_nwid_select);
- printk(KERN_DEBUG "psa_encryption_select: %d, ",
- p->psa_encryption_select);
- printk
- ("psa_encryption_key[]: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
- p->psa_encryption_key[0], p->psa_encryption_key[1],
- p->psa_encryption_key[2], p->psa_encryption_key[3],
- p->psa_encryption_key[4], p->psa_encryption_key[5],
- p->psa_encryption_key[6], p->psa_encryption_key[7]);
- printk(KERN_DEBUG "psa_databus_width: %d\n", p->psa_databus_width);
- printk(KERN_DEBUG "psa_call_code/auto_squelch: 0x%02x, ",
- p->psa_call_code[0]);
- printk
- ("psa_call_code[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
- p->psa_call_code[0], p->psa_call_code[1], p->psa_call_code[2],
- p->psa_call_code[3], p->psa_call_code[4], p->psa_call_code[5],
- p->psa_call_code[6], p->psa_call_code[7]);
-#ifdef DEBUG_SHOW_UNUSED
- printk(KERN_DEBUG "psa_reserved[]: %02X:%02X\n",
- p->psa_reserved[0],
- p->psa_reserved[1]);
-#endif /* DEBUG_SHOW_UNUSED */
- printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status);
- printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]);
- printk("psa_crc_status: 0x%02x\n", p->psa_crc_status);
-} /* wv_psa_show */
-#endif /* DEBUG_PSA_SHOW */
-
-#ifdef DEBUG_MMC_SHOW
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted status of the Modem Management Controller.
- * This function needs to be completed.
- */
-static void wv_mmc_show(struct net_device * dev)
-{
- unsigned long ioaddr = dev->base_addr;
- net_local *lp = netdev_priv(dev);
- mmr_t m;
-
- /* Basic check */
- if (hasr_read(ioaddr) & HASR_NO_CLK) {
- printk(KERN_WARNING
- "%s: wv_mmc_show: modem not connected\n",
- dev->name);
- return;
- }
-
- /* Read the mmc */
- mmc_out(ioaddr, mmwoff(0, mmw_freeze), 1);
- mmc_read(ioaddr, 0, (u8 *) & m, sizeof(m));
- mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0);
-
- /* Don't forget to update statistics */
- lp->wstats.discard.nwid +=
- (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
-
- printk(KERN_DEBUG "##### WaveLAN modem status registers: #####\n");
-#ifdef DEBUG_SHOW_UNUSED
- printk(KERN_DEBUG
- "mmc_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
- m.mmr_unused0[0], m.mmr_unused0[1], m.mmr_unused0[2],
- m.mmr_unused0[3], m.mmr_unused0[4], m.mmr_unused0[5],
- m.mmr_unused0[6], m.mmr_unused0[7]);
-#endif /* DEBUG_SHOW_UNUSED */
- printk(KERN_DEBUG "Encryption algorithm: %02X - Status: %02X\n",
- m.mmr_des_avail, m.mmr_des_status);
-#ifdef DEBUG_SHOW_UNUSED
- printk(KERN_DEBUG "mmc_unused1[]: %02X:%02X:%02X:%02X:%02X\n",
- m.mmr_unused1[0],
- m.mmr_unused1[1],
- m.mmr_unused1[2], m.mmr_unused1[3], m.mmr_unused1[4]);
-#endif /* DEBUG_SHOW_UNUSED */
- printk(KERN_DEBUG "dce_status: 0x%x [%s%s%s%s]\n",
- m.mmr_dce_status,
- (m.
- mmr_dce_status & MMR_DCE_STATUS_RX_BUSY) ?
- "energy detected," : "",
- (m.
- mmr_dce_status & MMR_DCE_STATUS_LOOPT_IND) ?
- "loop test indicated," : "",
- (m.
- mmr_dce_status & MMR_DCE_STATUS_TX_BUSY) ?
- "transmitter on," : "",
- (m.
- mmr_dce_status & MMR_DCE_STATUS_JBR_EXPIRED) ?
- "jabber timer expired," : "");
- printk(KERN_DEBUG "Dsp ID: %02X\n", m.mmr_dsp_id);
-#ifdef DEBUG_SHOW_UNUSED
- printk(KERN_DEBUG "mmc_unused2[]: %02X:%02X\n",
- m.mmr_unused2[0], m.mmr_unused2[1]);
-#endif /* DEBUG_SHOW_UNUSED */
- printk(KERN_DEBUG "# correct_nwid: %d, # wrong_nwid: %d\n",
- (m.mmr_correct_nwid_h << 8) | m.mmr_correct_nwid_l,
- (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l);
- printk(KERN_DEBUG "thr_pre_set: 0x%x [current signal %s]\n",
- m.mmr_thr_pre_set & MMR_THR_PRE_SET,
- (m.
- mmr_thr_pre_set & MMR_THR_PRE_SET_CUR) ? "above" :
- "below");
- printk(KERN_DEBUG "signal_lvl: %d [%s], ",
- m.mmr_signal_lvl & MMR_SIGNAL_LVL,
- (m.
- mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) ? "new msg" :
- "no new msg");
- printk("silence_lvl: %d [%s], ",
- m.mmr_silence_lvl & MMR_SILENCE_LVL,
- (m.
- mmr_silence_lvl & MMR_SILENCE_LVL_VALID) ? "update done" :
- "no new update");
- printk("sgnl_qual: 0x%x [%s]\n", m.mmr_sgnl_qual & MMR_SGNL_QUAL,
- (m.
- mmr_sgnl_qual & MMR_SGNL_QUAL_ANT) ? "Antenna 1" :
- "Antenna 0");
-#ifdef DEBUG_SHOW_UNUSED
- printk(KERN_DEBUG "netw_id_l: %x\n", m.mmr_netw_id_l);
-#endif /* DEBUG_SHOW_UNUSED */
-} /* wv_mmc_show */
-#endif /* DEBUG_MMC_SHOW */
-
-#ifdef DEBUG_I82586_SHOW
-/*------------------------------------------------------------------*/
-/*
- * Print the last block of the i82586 memory.
- */
-static void wv_scb_show(unsigned long ioaddr)
-{
- scb_t scb;
-
- obram_read(ioaddr, OFFSET_SCB, (unsigned char *) &scb,
- sizeof(scb));
-
- printk(KERN_DEBUG "##### WaveLAN system control block: #####\n");
-
- printk(KERN_DEBUG "status: ");
- printk("stat 0x%x[%s%s%s%s] ",
- (scb.
- scb_status & (SCB_ST_CX | SCB_ST_FR | SCB_ST_CNA |
- SCB_ST_RNR)) >> 12,
- (scb.
- scb_status & SCB_ST_CX) ? "command completion interrupt," :
- "", (scb.scb_status & SCB_ST_FR) ? "frame received," : "",
- (scb.
- scb_status & SCB_ST_CNA) ? "command unit not active," : "",
- (scb.
- scb_status & SCB_ST_RNR) ? "receiving unit not ready," :
- "");
- printk("cus 0x%x[%s%s%s] ", (scb.scb_status & SCB_ST_CUS) >> 8,
- ((scb.scb_status & SCB_ST_CUS) ==
- SCB_ST_CUS_IDLE) ? "idle" : "",
- ((scb.scb_status & SCB_ST_CUS) ==
- SCB_ST_CUS_SUSP) ? "suspended" : "",
- ((scb.scb_status & SCB_ST_CUS) ==
- SCB_ST_CUS_ACTV) ? "active" : "");
- printk("rus 0x%x[%s%s%s%s]\n", (scb.scb_status & SCB_ST_RUS) >> 4,
- ((scb.scb_status & SCB_ST_RUS) ==
- SCB_ST_RUS_IDLE) ? "idle" : "",
- ((scb.scb_status & SCB_ST_RUS) ==
- SCB_ST_RUS_SUSP) ? "suspended" : "",
- ((scb.scb_status & SCB_ST_RUS) ==
- SCB_ST_RUS_NRES) ? "no resources" : "",
- ((scb.scb_status & SCB_ST_RUS) ==
- SCB_ST_RUS_RDY) ? "ready" : "");
-
- printk(KERN_DEBUG "command: ");
- printk("ack 0x%x[%s%s%s%s] ",
- (scb.
- scb_command & (SCB_CMD_ACK_CX | SCB_CMD_ACK_FR |
- SCB_CMD_ACK_CNA | SCB_CMD_ACK_RNR)) >> 12,
- (scb.
- scb_command & SCB_CMD_ACK_CX) ? "ack cmd completion," : "",
- (scb.
- scb_command & SCB_CMD_ACK_FR) ? "ack frame received," : "",
- (scb.
- scb_command & SCB_CMD_ACK_CNA) ? "ack CU not active," : "",
- (scb.
- scb_command & SCB_CMD_ACK_RNR) ? "ack RU not ready," : "");
- printk("cuc 0x%x[%s%s%s%s%s] ",
- (scb.scb_command & SCB_CMD_CUC) >> 8,
- ((scb.scb_command & SCB_CMD_CUC) ==
- SCB_CMD_CUC_NOP) ? "nop" : "",
- ((scb.scb_command & SCB_CMD_CUC) ==
- SCB_CMD_CUC_GO) ? "start cbl_offset" : "",
- ((scb.scb_command & SCB_CMD_CUC) ==
- SCB_CMD_CUC_RES) ? "resume execution" : "",
- ((scb.scb_command & SCB_CMD_CUC) ==
- SCB_CMD_CUC_SUS) ? "suspend execution" : "",
- ((scb.scb_command & SCB_CMD_CUC) ==
- SCB_CMD_CUC_ABT) ? "abort execution" : "");
- printk("ruc 0x%x[%s%s%s%s%s]\n",
- (scb.scb_command & SCB_CMD_RUC) >> 4,
- ((scb.scb_command & SCB_CMD_RUC) ==
- SCB_CMD_RUC_NOP) ? "nop" : "",
- ((scb.scb_command & SCB_CMD_RUC) ==
- SCB_CMD_RUC_GO) ? "start rfa_offset" : "",
- ((scb.scb_command & SCB_CMD_RUC) ==
- SCB_CMD_RUC_RES) ? "resume reception" : "",
- ((scb.scb_command & SCB_CMD_RUC) ==
- SCB_CMD_RUC_SUS) ? "suspend reception" : "",
- ((scb.scb_command & SCB_CMD_RUC) ==
- SCB_CMD_RUC_ABT) ? "abort re