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

📄 wavelan_cs.c

📁 pcmcia source code
💻 C
📖 第 1 页 / 共 5 页
字号:
	if(i >= max)	  return(i);      }  return(i);}#ifdef WIRELESS_SPY/*------------------------------------------------------------------*//* * Gather wireless spy statistics : for each packet, compare the source * address with out list, and if match, get the stats... * Sorry, but this function really need 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;  /* Look 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 calculate an histogram on 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 : config & info stuff * This is here that are treated the wireless extensions (iwconfig) */static intwavelan_ioctl(struct net_device *	dev,	/* Device on wich the ioctl apply */	      struct ifreq *	rq,	/* Data passed */	      int		cmd)	/* Ioctl number */{  ioaddr_t		base = 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		flags;  int			ret = 0;#ifdef DEBUG_IOCTL_TRACE  printk(KERN_DEBUG "%s: ->wavelan_ioctl(cmd=0x%X)\n", dev->name, cmd);#endif  /* Disable interrupts & save flags */  wv_splhi(lp, &flags);  /* Look what is the request */  switch(cmd)    {      /* --------------- WIRELESS EXTENSIONS --------------- */    case SIOCGIWNAME:      strcpy(wrq->u.name, "Wavelan");      break;    case SIOCSIWNWID:      /* Set NWID in wavelan */#if WIRELESS_EXT > 8      if(!wrq->u.nwid.disabled)	{	  /* Set NWID in psa */	  psa.psa_nwid[0] = (wrq->u.nwid.value & 0xFF00) >> 8;	  psa.psa_nwid[1] = wrq->u.nwid.value & 0xFF;#else	/* WIRELESS_EXT > 8 */      if(wrq->u.nwid.on)	{	  /* Set NWID in psa */	  psa.psa_nwid[0] = (wrq->u.nwid.nwid & 0xFF00) >> 8;	  psa.psa_nwid[1] = wrq->u.nwid.nwid & 0xFF;#endif	/* WIRELESS_EXT > 8 */	  psa.psa_nwid_select = 0x01;	  psa_write(dev, (char *)psa.psa_nwid - (char *)&psa,		    (unsigned char *)psa.psa_nwid, 3);	  /* Set NWID in mmc */	  m.w.mmw_netw_id_l = psa.psa_nwid[1];	  m.w.mmw_netw_id_h = psa.psa_nwid[0];	  mmc_write(base, (char *)&m.w.mmw_netw_id_l - (char *)&m,		    (unsigned char *)&m.w.mmw_netw_id_l, 2);	  mmc_out(base, mmwoff(0, mmw_loopt_sel), 0x00);	}      else	{	  /* Disable nwid in the psa */	  psa.psa_nwid_select = 0x00;	  psa_write(dev, (char *)&psa.psa_nwid_select - (char *)&psa,		    (unsigned char *)&psa.psa_nwid_select, 1);	  /* Disable nwid in the mmc (no filtering) */	  mmc_out(base, mmwoff(0, mmw_loopt_sel), MMW_LOOPT_SEL_DIS_NWID);	}      /* update the Wavelan checksum */      update_psa_checksum(dev);      break;    case SIOCGIWNWID:      /* Read the NWID */      psa_read(dev, (char *)psa.psa_nwid - (char *)&psa,	       (unsigned char *)psa.psa_nwid, 3);#if WIRELESS_EXT > 8      wrq->u.nwid.value = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1];      wrq->u.nwid.disabled = !(psa.psa_nwid_select);      wrq->u.nwid.fixed = 1;	/* Superfluous */#else	/* WIRELESS_EXT > 8 */      wrq->u.nwid.nwid = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1];      wrq->u.nwid.on = psa.psa_nwid_select;#endif	/* WIRELESS_EXT > 8 */      break;    case SIOCSIWFREQ:      /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable) */      if(!(mmc_in(base, mmroff(0, mmr_fee_status)) &	   (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))	ret = wv_set_frequency(base, &(wrq->u.freq));      else	ret = -EOPNOTSUPP;      break;    case SIOCGIWFREQ:      /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable)       * (does it work for everybody ? - especially old cards...) */      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);	  wrq->u.freq.m = ((freq >> 5) * 5 + 24000L) * 10000;	  wrq->u.freq.e = 1;	}      else	{	  psa_read(dev, (char *)&psa.psa_subband - (char *)&psa,		   (unsigned char *)&psa.psa_subband, 1);	  if(psa.psa_subband <= 4)	    {	      wrq->u.freq.m = fixed_bands[psa.psa_subband];	      wrq->u.freq.e = (psa.psa_subband != 0);	    }	  else	    ret = -EOPNOTSUPP;	}      break;    case SIOCSIWSENS:      /* Set the level threshold */#if WIRELESS_EXT > 7      /* We should complain loudly if wrq->u.sens.fixed = 0, because we       * can't set auto mode... */      psa.psa_thr_pre_set = wrq->u.sens.value & 0x3F;#else	/* WIRELESS_EXT > 7 */      psa.psa_thr_pre_set = wrq->u.sensitivity & 0x3F;#endif	/* WIRELESS_EXT > 7 */      psa_write(dev, (char *)&psa.psa_thr_pre_set - (char *)&psa,	       (unsigned char *)&psa.psa_thr_pre_set, 1);      /* update the Wavelan checksum */      update_psa_checksum(dev);      mmc_out(base, mmwoff(0, mmw_thr_pre_set), psa.psa_thr_pre_set);      break;    case SIOCGIWSENS:      /* Read the level threshold */      psa_read(dev, (char *)&psa.psa_thr_pre_set - (char *)&psa,	       (unsigned char *)&psa.psa_thr_pre_set, 1);#if WIRELESS_EXT > 7      wrq->u.sens.value = psa.psa_thr_pre_set & 0x3F;      wrq->u.sens.fixed = 1;#else	/* WIRELESS_EXT > 7 */      wrq->u.sensitivity = psa.psa_thr_pre_set & 0x3F;#endif	/* WIRELESS_EXT > 7 */      break;#if WIRELESS_EXT > 8    case SIOCSIWENCODE:      /* Set encryption key */      if(!mmc_encr(base))	{	  ret = -EOPNOTSUPP;	  break;	}      /* Basic checking... */      if(wrq->u.encoding.pointer != (caddr_t) 0)	{	  /* Check the size of the key */	  if(wrq->u.encoding.length != 8)	    {	      ret = -EINVAL;	      break;	    }	  /* Copy the key in the driver */	  if(copy_from_user(psa.psa_encryption_key, wrq->u.encoding.pointer,			    wrq->u.encoding.length))	    {	      ret = -EFAULT;	      break;	    }	  psa.psa_encryption_select = 1;	  psa_write(dev, (char *) &psa.psa_encryption_select - (char *) &psa,		    (unsigned char *) &psa.psa_encryption_select, 8+1);	  mmc_out(base, mmwoff(0, mmw_encr_enable),		  MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE);	  mmc_write(base, mmwoff(0, mmw_encr_key),		    (unsigned char *) &psa.psa_encryption_key, 8);	}      if(wrq->u.encoding.flags & IW_ENCODE_DISABLED)	{	/* disable encryption */	  psa.psa_encryption_select = 0;	  psa_write(dev, (char *) &psa.psa_encryption_select - (char *) &psa,		    (unsigned char *) &psa.psa_encryption_select, 1);	  mmc_out(base, mmwoff(0, mmw_encr_enable), 0);	}      /* update the Wavelan checksum */      update_psa_checksum(dev);      break;    case SIOCGIWENCODE:      /* Read the encryption key */      if(!mmc_encr(base))	{	  ret = -EOPNOTSUPP;	  break;	}      /* only super-user can see encryption key */      if(!capable(CAP_NET_ADMIN))	{	  ret = -EPERM;	  break;	}      /* Basic checking... */      if(wrq->u.encoding.pointer != (caddr_t) 0)	{	  psa_read(dev, (char *) &psa.psa_encryption_select - (char *) &psa,		   (unsigned char *) &psa.psa_encryption_select, 1+8);	  /* encryption is enabled ? */	  if(psa.psa_encryption_select)	    wrq->u.encoding.flags = IW_ENCODE_ENABLED;	  else	    wrq->u.encoding.flags = IW_ENCODE_DISABLED;	  wrq->u.encoding.flags |= mmc_encr(base);	  /* Copy the key to the user buffer */	  wrq->u.encoding.length = 8;	  if(copy_to_user(wrq->u.encoding.pointer, psa.psa_encryption_key, 8))	    ret = -EFAULT;	}      break;#endif	/* WIRELESS_EXT > 8 */#ifdef WAVELAN_ROAMING_EXT#if WIRELESS_EXT > 5    case SIOCSIWESSID:      /* Check if disable */      if(wrq->u.data.flags == 0)	lp->filter_domains = 0;      else	/* Basic checking... */	if(wrq->u.data.pointer != (caddr_t) 0)	  {	    char	essid[IW_ESSID_MAX_SIZE + 1];	    char *	endp;	    /* Check the size of the string */	    if(wrq->u.data.length > IW_ESSID_MAX_SIZE + 1)	      {		ret = -E2BIG;		break;	      }	    /* Copy the string in the driver */	    if(copy_from_user(essid, wrq->u.data.pointer, wrq->u.data.length))	      {		ret = -EFAULT;		break;	      }	    essid[IW_ESSID_MAX_SIZE] = '\0';#ifdef DEBUG_IOCTL_INFO	    printk(KERN_DEBUG "SetEssid : ``%s''\n", essid);#endif	/* DEBUG_IOCTL_INFO */	    /* Convert to a number (note : Wavelan specific) */	    lp->domain_id = simple_strtoul(essid, &endp, 16);	    /* Has it worked  ? */	    if(endp > essid)	      lp->filter_domains = 1;	    else	      {		lp->filter_domains = 0;		ret = -EINVAL;	      }	  }      break;    case SIOCGIWESSID:      /* Basic checking... */      if(wrq->u.data.pointer != (caddr_t) 0)	{	  char		essid[IW_ESSID_MAX_SIZE + 1];	  /* Is the domain ID active ? */	  wrq->u.data.flags = lp->filter_domains;	  /* Copy Domain ID into a string (Wavelan specific) */	  /* Sound crazy, be we can't have a snprintf in the kernel !!! */	  sprintf(essid, "%lX", lp->domain_id);	  essid[IW_ESSID_MAX_SIZE] = '\0';	  /* Set the length */	  wrq->u.data.length = strlen(essid) + 1;	  /* Copy structure to the user buffer */	  if(copy_to_user(wrq->u.data.pointer, essid, wrq->u.data.length))	    ret = -EFAULT;	}      break;    case SIOCSIWAP:#ifdef DEBUG_IOCTL_INFO      printk(KERN_DEBUG "Set AP to : %02X:%02X:%02X:%02X:%02X:%02X\n",	     wrq->u.ap_addr.sa_data[0],	     wrq->u.ap_addr.sa_data[1],	     wrq->u.ap_addr.sa_data[2],	     wrq->u.ap_addr.sa_data[3],	     wrq->u.ap_addr.sa_data[4],	     wrq->u.ap_addr.sa_data[5]);#endif	/* DEBUG_IOCTL_INFO */      ret = -EOPNOTSUPP;	/* Not supported yet */      break;    case SIOCGIWAP:      /* Should get the real McCoy instead of own Ethernet address */      memcpy(wrq->u.ap_addr.sa_data, dev->dev_addr, WAVELAN_ADDR_SIZE);      wrq->u.ap_addr.sa_family = ARPHRD_ETHER;      ret = -EOPNOTSUPP;	/* Not supported yet */      break;#endif	/* WIRELESS_EXT > 5 */#endif	/* WAVELAN_ROAMING_EXT */#if WIRELESS_EXT > 8#ifdef WAVELAN_ROAMING    case SIOCSIWMODE:      switch(wrq->u.mode)	{	case IW_MODE_ADHOC:	  if(do_roaming)	    {	      wv_roam_cleanup(dev);	      do_roaming = 0;	    }	  break;	case IW_MODE_INFRA:	  if(!do_roaming)	    {	      wv_roam_init(dev);	      do_roaming = 1;	    }	  break;	default:	  ret = -EINVAL;	}      break;    case SIOCGIWMODE:      if(do_roaming)	wrq->u.mode = IW_MODE_INFRA;      else	wrq->u.mode = IW_MODE_ADHOC;      break;#endif	/* WAVELAN_ROAMING */#endif /* WIRELESS_EXT > 8 */    case SIOCGIWRANGE:      /* Basic checking... */      if(wrq->u.data.pointer != (caddr_t) 0)	{	  struct iw_range	range;	   /* Set the length (very important for backward compatibility) */	   wrq->u.data.length = sizeof(struct iw_range);	   /* Set all the info we don't care or don't know about to zero */	   memset(&range, 0, sizeof(range));#if WIRELESS_EXT > 10	   /* Set the Wireless Extension versions */	   range.we_version_compiled = WIRELESS_EXT;	   range.we_version_source = 9;	/* Nothing for us in v10 and v11 */#endif /* WIRELESS_EXT > 10 */	  /* Set information in the range struct */	  range.throughput = 1.4 * 1000 * 1000;	/* don't argue on this ! */	  range.min_nwid = 0x0000;	  range.max_nwid = 0xFFFF;	  /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable) */	  if(!(mmc_in(base, mmro

⌨️ 快捷键说明

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