⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wavelan.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *	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) *//*------------------------------------------------------------------*//* * Wrapper for disabling interrupts. */static inline unsigned longwv_splhi(void){  unsigned long flags;  save_flags(flags);  cli();  return(flags);}/*------------------------------------------------------------------*//* * Wrapper for re-enabling interrupts. */static inline voidwv_splx(unsigned long	flags){  restore_flags(flags);}/*------------------------------------------------------------------*//* * Translate irq number to PSA irq parameter */static u_charwv_irq_to_psa(int	irq){  if(irq < 0 || irq >= NELS(irqvals))    return 0;  return irqvals[irq];}/*------------------------------------------------------------------*//* * Translate PSA irq parameter to irq number  */static intwv_psa_to_irq(u_char	irqval){  int	irq;  for(irq = 0; irq < NELS(irqvals); irq++)    if(irqvals[irq] == irqval)      return irq;  return -1;}#ifdef STRUCT_CHECK/*------------------------------------------------------------------*//* * Sanity routine to verify the sizes of the various WaveLAN interface * structures. */static char *wv_struct_check(void){#define	SC(t,s,n)	if (sizeof(t) != s) return(n);  SC(psa_t, PSA_SIZE, "psa_t");  SC(mmw_t, MMW_SIZE, "mmw_t");  SC(mmr_t, MMR_SIZE, "mmr_t");  SC(ha_t, HA_SIZE, "ha_t");#undef	SC  return((char *) NULL);} /* wv_struct_check */#endif	/* STRUCT_CHECK *//********************* 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 u_shorthasr_read(u_long	ioaddr){  return(inw(HASR(ioaddr)));} /* hasr_read *//*------------------------------------------------------------------*//* * Write to card's Host Adapter Command Register. */static inline voidhacr_write(u_long	ioaddr,	   u_short	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 inline voidhacr_write_slow(u_long	ioaddr,		u_short	hacr){  hacr_write(ioaddr, hacr);  /* delay might only be needed sometimes */  udelay(1000L);} /* hacr_write_slow *//*------------------------------------------------------------------*//* * Set the channel attention bit. */static inline voidset_chan_attn(u_long	ioaddr,	      u_short	hacr){  hacr_write(ioaddr, hacr | HACR_CA);} /* set_chan_attn *//*------------------------------------------------------------------*//* * Reset, and then set host adaptor into default mode. */static inline voidwv_hacr_reset(u_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 bits mode */static inline voidwv_16_off(u_long	ioaddr,	  u_short	hacr){  hacr &= ~HACR_16BITS;  hacr_write(ioaddr, hacr);} /* wv_16_off *//*------------------------------------------------------------------*//* * Set the i/o transfer over the ISA bus to 8 bits mode */static inline voidwv_16_on(u_long		ioaddr,	 u_short	hacr){  hacr |= HACR_16BITS;  hacr_write(ioaddr, hacr);} /* wv_16_on *//*------------------------------------------------------------------*//* * Disable interrupts on the WaveLAN hardware */static inline voidwv_ints_off(device *	dev){  net_local *	lp = (net_local *)dev->priv;  u_long	ioaddr = dev->base_addr;  u_long	x;  x = wv_splhi();  lp->hacr &= ~HACR_INTRON;  hacr_write(ioaddr, lp->hacr);  wv_splx(x);} /* wv_ints_off *//*------------------------------------------------------------------*//* * Enable interrupts on the WaveLAN hardware */static inline voidwv_ints_on(device *	dev){  net_local *	lp = (net_local *)dev->priv;  u_long	ioaddr = dev->base_addr;  u_long	x;  x = wv_splhi();  lp->hacr |= HACR_INTRON;  hacr_write(ioaddr, lp->hacr);  wv_splx(x);} /* 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 voidpsa_read(u_long		ioaddr,	 u_short	hacr,	 int		o,	/* offset in PSA */	 u_char *	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 Paramter Storage Area to the WaveLAN card's memory */static voidpsa_write(u_long	ioaddr,	  u_short	hacr,	  int		o,	/* Offset in psa */	  u_char *	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))	udelay(1000);    }  wv_16_on(ioaddr, hacr);} /* psa_write */#ifdef PSA_CRC/*------------------------------------------------------------------*//* * Calculate the PSA CRC (not tested yet) * As the WaveLAN drivers don't use the CRC, I won't use it either. * 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) */static u_shortpsa_crc(u_short *	psa,	/* The PSA */	int		size)	/* Number of short for CRC */{  int		byte_cnt;	/* Loop on the PSA */  u_short	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	/* PSA_CRC *//*------------------------------------------------------------------*//* * Write 1 byte to the MMC. */static inline voidmmc_out(u_long		ioaddr,	u_short		o,	u_char		d){  /* Wait for MMC to go idle */  while(inw(HASR(ioaddr)) & HASR_MMC_BUSY)    ;  outw((u_short) (((u_short) d << 8) | (o << 1) | 1),       MMCR(ioaddr));}/*------------------------------------------------------------------*//* * Routine to write bytes to the Modem Management Controller. * We start by the end because it is the way it should be ! */static inline voidmmc_write(u_long	ioaddr,	  u_char	o,	  u_char *	b,	  int		n){  o += n;  b += n;  while(n-- > 0 )    mmc_out(ioaddr, --o, *(--b));} /* mmc_write *//*------------------------------------------------------------------*//* * Read 1 byte from the MMC. * Optimised version for 1 byte, avoid using memory... */static inline u_charmmc_in(u_long	ioaddr,       u_short	o){  while(inw(HASR(ioaddr)) & HASR_MMC_BUSY)    ;  outw(o << 1, MMCR(ioaddr));  while(inw(HASR(ioaddr)) & HASR_MMC_BUSY)    ;  return (u_char) (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 by the end because it is the way it should be ! */static inline voidmmc_read(u_long		ioaddr,	 u_char		o,	 u_char *	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 intmmc_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 voidfee_wait(u_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 voidfee_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 */{  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)));    }}#ifdef WIRELESS_EXT	/* If wireless extension exist in the kernel *//*------------------------------------------------------------------*//* * 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 voidfee_write(u_long	ioaddr,	/* i/o port of the card */	  u_short	o,	/* destination offset */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -