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

📄 wavelan_cs.c

📁 pcmcia source code
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef DEBUG_I82593_SHOW  wv_ru_show(dev);#endif#ifdef DEBUG_BASIC_SHOW  /* Now, let's go for the basic stuff */  printk(KERN_NOTICE "%s: WaveLAN: port %#x, irq %d, hw_addr",	 dev->name, base, dev->irq);  for(i = 0; i < WAVELAN_ADDR_SIZE; i++)    printk("%s%02X", (i == 0) ? " " : ":", dev->dev_addr[i]);  /* Print current network id */  if(psa.psa_nwid_select)    printk(", nwid 0x%02X-%02X", psa.psa_nwid[0], psa.psa_nwid[1]);  else    printk(", nwid off");  /* If 2.00 card */  if(!(mmc_in(base, mmroff(0, mmr_fee_status)) &       (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))    {      unsigned short	freq;      /* Ask the EEprom to read the frequency from the first area */      fee_read(base, 0x00 /* 1st area - frequency... */,	       &freq, 1);      /* Print frequency */      printk(", 2.00, %ld", (freq >> 6) + 2400L);      /* Hack !!! */      if(freq & 0x20)	printk(".5");    }  else    {      printk(", PCMCIA, ");      switch (psa.psa_subband)	{	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("unknown");	}    }  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 differents * 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  if(dev->flags & IFF_PROMISC)    {      /*       * Enable promiscuous mode: receive all packets.       */      if(!lp->promiscuous)	{	  lp->promiscuous = 1;	  lp->allmulticast = 0;	  lp->mc_count = 0;	  wv_82593_reconfig(dev);	  /* Tell the kernel that we are doing a really bad job... */	  dev->flags |= IFF_PROMISC;	}    }  else    /* If all multicast addresses     * or too much multicast addresses for the hardware filter */    if((dev->flags & IFF_ALLMULTI) ||       (dev->mc_count > I82593_MAX_MULTICAST_ADDRESSES))      {	/*	 * Disable promiscuous mode, but active the all multicast mode	 */	if(!lp->allmulticast)	  {	    lp->promiscuous = 0;	    lp->allmulticast = 1;	    lp->mc_count = 0;	    wv_82593_reconfig(dev);	    /* Tell the kernel that we are doing a really bad job... */	    dev->flags |= IFF_ALLMULTI;	  }      }    else      /* If there is some 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 || lp->allmulticast ||	     (dev->mc_count != lp->mc_count))#endif	    {	      lp->promiscuous = 0;	      lp->allmulticast = 0;	      lp->mc_count = dev->mc_count;	      wv_82593_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->allmulticast = 0;	      lp->mc_count = 0;	      wv_82593_reconfig(dev);	    }	}#ifdef DEBUG_IOCTL_TRACE  printk(KERN_DEBUG "%s: <-wavelan_set_multicast_list()\n", dev->name);#endif}/*------------------------------------------------------------------*//* * This function doesn't exist... * (Note : it was a nice way to test the reconfigure stuff...) */#ifdef SET_MAC_ADDRESSstatic 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);  /* Reconfig the beast */  wv_82593_reconfig(dev);  return 0;}#endif	/* SET_MAC_ADDRESS */#ifdef WIRELESS_EXT	/* If wireless extension exist in the kernel *//*------------------------------------------------------------------*//* * Frequency setting (for hardware able 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		base,	/* 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 */  /* Theoritically, 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 22MHz wide, so some of the channels   * will interfere... */  if((frequency->e == 0) &&     (frequency->m >= 0) && (frequency->m < BAND_NUM))    {      /* Get frequency offset. */      freq = channel_bands[frequency->m] >> 1;    }  /* Verify if the frequency is allowed */  if(freq != 0L)    {      u_short	table[10];	/* Authorized frequency table */      /* Read the frequency table */      fee_read(base, 0x71 /* frequency table */,	       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 if 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       * & 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(base, 0x00,	       area, 16);      /* Read the DAC */      fee_read(base, 0x60,	       dac, 2);      /* Read the new power adjust value */      fee_read(base, 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);      /* Others part 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(base, 0x00,		area, 16);      /* Write the DAC */      fee_write(base, 0x60,		dac, 2);      /* We now should verify here that the EEprom writting was ok */      /* ReRead the first area */      fee_read(base, 0x00,	       area_verify, 16);      /* ReRead the DAC */      fee_read(base, 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       * synthetisers (from the EEprom - area 1)       * Note : as the EEprom is auto decremented, we set the end       * if the area... */      mmc_out(base, mmwoff(0, mmw_fee_addr), 0x0F);      mmc_out(base, mmwoff(0, mmw_fee_ctrl),	      MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);      /* Wait until the download is finished */      fee_wait(base, 100, 100);      /* We must now download the power adjust value (gain) to       * the synthetisers (from the EEprom - area 7 - DAC) */      mmc_out(base, mmwoff(0, mmw_fee_addr), 0x61);      mmc_out(base, mmwoff(0, mmw_fee_ctrl),	      MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);      /* Wait until the download is finished */      fee_wait(base, 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	base,	/* i/o port of the card */		  iw_freq *	list,	/* List of frequency 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 */#if WIRELESS_EXT > 7  const int	BAND_NUM = 10;	/* Number of bands */  int		c = 0;		/* Channel number */#endif /* WIRELESS_EXT */  /* Read the frequency table */  fee_read(base, 0x71 /* frequency table */,	   table, 10);  /* Look 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)))      {#if WIRELESS_EXT > 7	/* Compute approximate channel number */	while((((channel_bands[c] >> 1) - 24) < freq) &&	      (c < BAND_NUM))	  c++;	list[i].i = c;	/* Set the list index */#endif /* WIRELESS_EXT */	/* put in the list */	list[i].m = (((freq + 24) * 5) + 24000L) * 10000;	list[i++].e = 1;	/* Check number */

⌨️ 快捷键说明

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