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

📄 wavelan.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	{	case PSA_SUBBAND_915:	  printk("915");	  break;	case PSA_SUBBAND_2425:	  printk("2425");	  break;	case PSA_SUBBAND_2460:	  printk("2460");	  break;	case PSA_SUBBAND_2484:	  printk("2484");	  break;	case PSA_SUBBAND_2430_5:	  printk("2430.5");	  break;	default:	  printk("?");	}    }  printk(" MHz\n");#endif	/* DEBUG_BASIC_SHOW */#ifdef DEBUG_VERSION_SHOW  /* Print version information */  printk(KERN_NOTICE "%s", version);#endif} /* wv_init_info *//********************* IOCTL, STATS & RECONFIG *********************//* * We found here routines that are called by Linux on different * occasions after the configuration and not for transmitting data * These may be called when the user use ifconfig, /proc/net/dev * or wireless extensions *//*------------------------------------------------------------------*//* * Get the current Ethernet statistics. This may be called with the * card open or closed. * Used when the user read /proc/net/dev */static en_stats	*wavelan_get_stats(device *	dev){#ifdef DEBUG_IOCTL_TRACE  printk(KERN_DEBUG "%s: <>wavelan_get_stats()\n", dev->name);#endif  return(&((net_local *) dev->priv)->stats);}/*------------------------------------------------------------------*//* * Set or clear the multicast filter for this adaptor. * num_addrs == -1	Promiscuous mode, receive all packets * num_addrs == 0	Normal mode, clear multicast list * num_addrs > 0	Multicast mode, receive normal and MC packets, *			and do best-effort filtering. */static voidwavelan_set_multicast_list(device *	dev){  net_local *	lp = (net_local *) dev->priv;#ifdef DEBUG_IOCTL_TRACE  printk(KERN_DEBUG "%s: ->wavelan_set_multicast_list()\n", dev->name);#endif#ifdef DEBUG_IOCTL_INFO  printk(KERN_DEBUG "%s: wavelan_set_multicast_list(): setting Rx mode %02X to %d addresses.\n",	 dev->name, dev->flags, dev->mc_count);#endif  /* Are we asking for promiscuous mode,   * or all multicast addresses (we don't have that!)   * or too many multicast addresses for the hardware filter? */  if((dev->flags & IFF_PROMISC) ||     (dev->flags & IFF_ALLMULTI) ||     (dev->mc_count > I82586_MAX_MULTICAST_ADDRESSES))    {      /*       * Enable promiscuous mode: receive all packets.       */      if(!lp->promiscuous)	{	  lp->promiscuous = 1;	  lp->mc_count = 0;	  wv_82586_reconfig(dev);	  /* Tell the kernel that we are doing a really bad job. */	  dev->flags |= IFF_PROMISC;	}    }  else    /* Are there multicast addresses to send? */    if(dev->mc_list != (struct dev_mc_list *) NULL)      {	/*	 * Disable promiscuous mode, but receive all packets	 * in multicast list	 */#ifdef MULTICAST_AVOID	if(lp->promiscuous ||	   (dev->mc_count != lp->mc_count))#endif	  {	    lp->promiscuous = 0;	    lp->mc_count = dev->mc_count;	    wv_82586_reconfig(dev);	  }      }    else      {	/*	 * Switch to normal mode: disable promiscuous mode and 	 * clear the multicast list.	 */	if(lp->promiscuous || lp->mc_count == 0)	  {	    lp->promiscuous = 0;	    lp->mc_count = 0;	    wv_82586_reconfig(dev);	  }      }#ifdef DEBUG_IOCTL_TRACE  printk(KERN_DEBUG "%s: <-wavelan_set_multicast_list()\n", dev->name);#endif}/*------------------------------------------------------------------*//* * This function doesn't exist. */static intwavelan_set_mac_address(device *	dev,			void *		addr){  struct sockaddr *	mac = addr;  /* Copy the address. */  memcpy(dev->dev_addr, mac->sa_data, WAVELAN_ADDR_SIZE);  /* Reconfigure the beast. */  wv_82586_reconfig(dev);  return 0;}#ifdef WIRELESS_EXT	/* if wireless extensions exist in the kernel *//*------------------------------------------------------------------*//* * Frequency setting (for hardware capable of it) * It's a bit complicated and you don't really want to look into it. * (called in wavelan_ioctl) */static inline intwv_set_frequency(u_long		ioaddr,	/* I/O port of the card */		 iw_freq *	frequency){  const int	BAND_NUM = 10;	/* Number of bands */  long		freq = 0L;	/* offset to 2.4 GHz in .5 MHz */#ifdef DEBUG_IOCTL_INFO  int		i;#endif  /* Setting by frequency */  /* Theoretically, you may set any frequency between   * the two limits with a 0.5 MHz precision. In practice,   * I don't want you to have trouble with local regulations.   */  if((frequency->e == 1) &&     (frequency->m >= (int) 2.412e8) && (frequency->m <= (int) 2.487e8))    {      freq = ((frequency->m / 10000) - 24000L) / 5;    }  /* Setting by channel (same as wfreqsel) */  /* Warning: each channel is 22 MHz wide, so some of the channels   * will interfere. */  if((frequency->e == 0) &&     (frequency->m >= 0) && (frequency->m < BAND_NUM))    {      /* frequency in units of 250 kHz (as read in the offset register) */      short	bands[] = { 0x30, 0x58, 0x64, 0x7A, 0x80, 0xA8, 0xD0, 0xF0, 0xF8, 0x150 };      /* Get frequency offset. */      freq = bands[frequency->m] >> 1;    }  /* Verify that the frequency is allowed. */  if(freq != 0L)    {      u_short	table[10];	/* Authorized frequency table */      /* Read the frequency table. */      fee_read(ioaddr, 0x71, table, 10);#ifdef DEBUG_IOCTL_INFO      printk(KERN_DEBUG "Frequency table: ");      for(i = 0; i < 10; i++)	{	  printk(" %04X",		 table[i]);	}      printk("\n");#endif      /* Look in the table to see whether the frequency is allowed. */      if(!(table[9 - ((freq - 24) / 16)] &	   (1 << ((freq - 24) % 16))))	return -EINVAL;		/* not allowed */    }  else    return -EINVAL;  /* if we get a usable frequency */  if(freq != 0L)    {      unsigned short	area[16];      unsigned short	dac[2];      unsigned short	area_verify[16];      unsigned short	dac_verify[2];      /* Corresponding gain (in the power adjust value table)       * See AT&T WaveLAN Data Manual, REF 407-024689/E, page 3-8       * and WCIN062D.DOC, page 6.2.9. */      unsigned short	power_limit[] = { 40, 80, 120, 160, 0 };      int		power_band = 0;		/* Selected band */      unsigned short	power_adjust;		/* Correct value */      /* Search for the gain. */      power_band = 0;      while((freq > power_limit[power_band]) &&	    (power_limit[++power_band] != 0))	;      /* Read the first area. */      fee_read(ioaddr, 0x00, area, 16);      /* Read the DAC. */      fee_read(ioaddr, 0x60, dac, 2);      /* Read the new power adjust value. */      fee_read(ioaddr, 0x6B - (power_band >> 1), &power_adjust, 1);      if(power_band & 0x1)	power_adjust >>= 8;      else	power_adjust &= 0xFF;#ifdef DEBUG_IOCTL_INFO      printk(KERN_DEBUG "WaveLAN EEPROM Area 1: ");      for(i = 0; i < 16; i++)	{	  printk(" %04X",		 area[i]);	}      printk("\n");      printk(KERN_DEBUG "WaveLAN EEPROM DAC: %04X %04X\n",	     dac[0], dac[1]);#endif      /* Frequency offset (for info only) */      area[0] = ((freq << 5) & 0xFFE0) | (area[0] & 0x1F);      /* Receiver Principle main divider coefficient */      area[3] = (freq >> 1) + 2400L - 352L;      area[2] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF);      /* Transmitter Main divider coefficient */      area[13] = (freq >> 1) + 2400L;      area[12] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF);      /* Other parts of the area are flags, bit streams or unused. */      /* Set the value in the DAC. */      dac[1] = ((power_adjust >> 1) & 0x7F) | (dac[1] & 0xFF80);      dac[0] = ((power_adjust & 0x1) << 4) | (dac[0] & 0xFFEF);      /* Write the first area. */      fee_write(ioaddr, 0x00,		area, 16);      /* Write the DAC. */      fee_write(ioaddr, 0x60,		dac, 2);      /* We now should verify here that the writing of the EEPROM went OK. */      /* Reread the first area. */      fee_read(ioaddr, 0x00, area_verify, 16);      /* Reread the DAC. */      fee_read(ioaddr, 0x60, dac_verify, 2);      /* Compare. */      if(memcmp(area, area_verify, 16 * 2) ||	 memcmp(dac, dac_verify, 2 * 2))	{#ifdef DEBUG_IOCTL_ERROR	  printk(KERN_INFO "WaveLAN: wv_set_frequency: unable to write new frequency to EEPROM(?).\n");#endif	  return -EOPNOTSUPP;	}      /* We must download the frequency parameters to the       * synthesizers (from the EEPROM - area 1)       * Note: as the EEPROM is automatically decremented, we set the end       * if the area... */      mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), 0x0F);      mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl),	      MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);      /* Wait until the download is finished. */      fee_wait(ioaddr, 100, 100);      /* We must now download the power adjust value (gain) to       * the synthesizers (from the EEPROM - area 7 - DAC). */      mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), 0x61);      mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl),	      MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);      /* Wait for the download to finish. */      fee_wait(ioaddr, 100, 100);#ifdef DEBUG_IOCTL_INFO      /* Verification of what we have done */      printk(KERN_DEBUG "WaveLAN EEPROM Area 1: ");      for(i = 0; i < 16; i++)	{	  printk(" %04X",		 area_verify[i]);	}      printk("\n");      printk(KERN_DEBUG "WaveLAN EEPROM DAC:  %04X %04X\n",	     dac_verify[0], dac_verify[1]);#endif      return 0;    }  else    return -EINVAL;		/* Bah, never get there... */}/*------------------------------------------------------------------*//* * Give the list of available frequencies. */static inline intwv_frequency_list(u_long	ioaddr,	/* I/O port of the card */		  iw_freq *	list,	/* List of frequencies to fill */		  int		max)	/* Maximum number of frequencies */{  u_short	table[10];	/* Authorized frequency table */  long		freq = 0L;	/* offset to 2.4 GHz in .5 MHz + 12 MHz */  int		i;		/* index in the table */  /* Read the frequency table. */  fee_read(ioaddr, 0x71 /* frequency table */, table, 10);  /* Check all frequencies. */  i = 0;  for(freq = 0; freq < 150; freq++)    /* Look in the table if the frequency is allowed */    if(table[9 - (freq / 16)] & (1 << (freq % 16)))      {	/* put in the list */	list[i].m = (((freq + 24) * 5) + 24000L) * 10000;	list[i++].e = 1;	/* Check number. */	if(i >= max)	  return(i);      }  return(i);}#ifdef WIRELESS_SPY/*------------------------------------------------------------------*//* * Gather wireless spy statistics:  for each packet, compare the source * address with our list, and if they match, get the statistics. * Sorry, but this function really needs the wireless extensions. */static inline voidwl_spy_gather(device *	dev,	      u_char *	mac,		/* MAC address */	      u_char *	stats)		/* Statistics to gather */{  net_local *	lp = (net_local *) dev->priv;  int		i;  /* Check all addresses. */  for(i = 0; i < lp->spy_number; i++)    /* If match */    if(!memcmp(mac, lp->spy_address[i], WAVELAN_ADDR_SIZE))      {	/* Update statistics */	lp->spy_stat[i].qual = stats[2] & MMR_SGNL_QUAL;	lp->spy_stat[i].level = stats[0] & MMR_SIGNAL_LVL;	lp->spy_stat[i].noise = stats[1] & MMR_SILENCE_LVL;	lp->spy_stat[i].updated = 0x7;      }}#endif	/* WIRELESS_SPY */#ifdef HISTOGRAM/*------------------------------------------------------------------*//* * This function calculates a histogram of the signal level. * As the noise is quite constant, it's like doing it on the SNR. * We have defined a set of interval (lp->his_range), and each time * the level goes in that interval, we increment the count (lp->his_sum). * With this histogram you may detect if one WaveLAN is really weak, * or you may also calculate the mean and standard deviation of the level. */static inline voidwl_his_gather(device *	dev,	      u_char *	stats)		/* Statistics to gather */{  net_local *	lp = (net_local *) dev->priv;  u_char	level = stats[0] & MMR_SIGNAL_LVL;  int		i;  /* Find the correct interval. */  i = 0;  while((i < (lp->his_number - 1)) && (level >= lp->his_range[i++]))    ;  /* Increment interval counter. */  (lp->his_sum[i])++;}#endif	/* HISTOGRAM *//*------------------------------------------------------------------*//* * Perform ioctl for configuration and information. * It is here that the wireless extensions are treated (iwconfig). */static intwavelan_ioctl(struct device *	dev,	/* device on which the ioctl is applied */	      struct ifreq *	rq,	/* data passed */	      int		cmd)	/* ioctl number */{  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;  mm_t			m;  unsigned long		x;  int			ret = 0;#ifdef DEBUG_IOCTL_TRACE  printk(KERN_DEBUG "%s: ->wavelan_ioctl(cmd=0x%X)\n", dev->name, cmd);#endif  /* Disable interrupts and save flags. */  x = wv_splhi();  /* Look what is the request */  switch(cmd)    {      /* --------------- WIRELESS EXTENSIONS --------------- */    case SIOCGIWNAME:      strcpy(wrq->u.name, "WaveLAN");      break;

⌨️ 快捷键说明

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