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

📄 wavelan.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    case SIOCSIWNWID:      /* Set NWID in WaveLAN. */      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;	  psa.psa_nwid_select = 0x01;	  psa_write(ioaddr, lp->hacr, (char *)psa.psa_nwid - (char *)&psa,		    (unsigned char *)psa.psa_nwid, 3);	  /* Set NWID in mmc. */	  m.w.mmw_netw_id_l = wrq->u.nwid.nwid & 0xFF;	  m.w.mmw_netw_id_h = (wrq->u.nwid.nwid & 0xFF00) >> 8;	  mmc_write(ioaddr, (char *)&m.w.mmw_netw_id_l - (char *)&m,		    (unsigned char *)&m.w.mmw_netw_id_l, 2);	  mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel), 0x00);	}      else	{	  /* Disable NWID in the psa. */	  psa.psa_nwid_select = 0x00;	  psa_write(ioaddr, lp->hacr,		    (char *)&psa.psa_nwid_select - (char *)&psa,		    (unsigned char *)&psa.psa_nwid_select, 1);	  /* Disable NWID in the mmc (no filtering). */	  mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel), MMW_LOOPT_SEL_DIS_NWID);	}#ifdef SET_PSA_CRC      /* update the Wavelan checksum */      update_psa_checksum(dev, ioaddr, lp->hacr);#endif      break;    case SIOCGIWNWID:      /* Read the NWID. */      psa_read(ioaddr, lp->hacr, (char *)psa.psa_nwid - (char *)&psa,	       (unsigned char *)psa.psa_nwid, 3);      wrq->u.nwid.nwid = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1];      wrq->u.nwid.on = psa.psa_nwid_select;      break;    case SIOCSIWFREQ:      /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */      if(!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &	   (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))	ret = wv_set_frequency(ioaddr, &(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(ioaddr, 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(ioaddr, 0x00, &freq, 1);	  wrq->u.freq.m = ((freq >> 5) * 5 + 24000L) * 10000;	  wrq->u.freq.e = 1;	}      else	{	  int	bands[] = { 915e6, 2.425e8, 2.46e8, 2.484e8, 2.4305e8 };	  psa_read(ioaddr, lp->hacr, (char *)&psa.psa_subband - (char *)&psa,		   (unsigned char *)&psa.psa_subband, 1);	  if(psa.psa_subband <= 4)	    {	      wrq->u.freq.m = bands[psa.psa_subband];	      wrq->u.freq.e = (psa.psa_subband != 0);	    }	  else	    ret = -EOPNOTSUPP;	}      break;    case SIOCSIWSENS:      /* Set the level threshold. */      if(!suser())	return -EPERM;      psa.psa_thr_pre_set = wrq->u.sensitivity & 0x3F;      psa_write(ioaddr, lp->hacr, (char *)&psa.psa_thr_pre_set - (char *)&psa,	       (unsigned char *) &psa.psa_thr_pre_set, 1);#ifdef SET_PSA_CRC      /* update the Wavelan checksum */      update_psa_checksum(dev, ioaddr, lp->hacr);#endif      mmc_out(ioaddr, mmwoff(0, mmw_thr_pre_set), psa.psa_thr_pre_set);      break;    case SIOCGIWSENS:      /* Read the level threshold. */      psa_read(ioaddr, lp->hacr, (char *)&psa.psa_thr_pre_set - (char *)&psa,	       (unsigned char *) &psa.psa_thr_pre_set, 1);      wrq->u.sensitivity = psa.psa_thr_pre_set & 0x3F;      break;     case SIOCSIWENCODE:       /* Set encryption key. */       if(!mmc_encr(ioaddr))	 {	   ret = -EOPNOTSUPP;	   break;	 }       if(wrq->u.encoding.method)	 {	/* Enable encryption. */	   int		i;	   long long	key = wrq->u.encoding.code;	   for(i = 7; i >= 0; i--)	     {	       psa.psa_encryption_key[i] = key & 0xFF;	       key >>= 8;	     }           psa.psa_encryption_select = 1;	   psa_write(ioaddr, lp->hacr,		     (char *) &psa.psa_encryption_select - (char *) &psa,		     (unsigned char *) &psa.psa_encryption_select, 8+1);           mmc_out(ioaddr, mmwoff(0, mmw_encr_enable),		   MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE);           mmc_write(ioaddr, mmwoff(0, mmw_encr_key),		     (unsigned char *) &psa.psa_encryption_key, 8);	 }       else	 {	/* Disable encryption. */	   psa.psa_encryption_select = 0;	   psa_write(ioaddr, lp->hacr,		     (char *) &psa.psa_encryption_select - (char *) &psa,		     (unsigned char *) &psa.psa_encryption_select, 1);	   mmc_out(ioaddr, mmwoff(0, mmw_encr_enable), 0);	 }#ifdef SET_PSA_CRC       /* update the Wavelan checksum */       update_psa_checksum(dev, ioaddr, lp->hacr);#endif       break;     case SIOCGIWENCODE:       /* Read the encryption key. */       if(!mmc_encr(ioaddr))	 {	   ret = -EOPNOTSUPP;	   break;	 }       /* Only super-user can see encryption key. */       if(!suser())	 {	   ret = -EPERM;	   break;	 }       else	 {	   int		i;	   long long	key = 0;	   psa_read(ioaddr, lp->hacr,		    (char *) &psa.psa_encryption_select - (char *) &psa,		    (unsigned char *) &psa.psa_encryption_select, 1+8);	   for(i = 0; i < 8; i++)	     {	       key <<= 8;	       key += psa.psa_encryption_key[i];	     }	   wrq->u.encoding.code = key;	   /* encryption is enabled */	   if(psa.psa_encryption_select)	     wrq->u.encoding.method = mmc_encr(ioaddr);	   else	     wrq->u.encoding.method = 0;	 }       break;    case SIOCGIWRANGE:      /* basic checking */      if(wrq->u.data.pointer != (caddr_t) 0)	{	  struct iw_range	range;	  /* Verify the user buffer. */	  ret = verify_area(VERIFY_WRITE, wrq->u.data.pointer,			    sizeof(struct iw_range));	  if(ret)	    break;	  /* Set the length (useless:  it's constant). */	  wrq->u.data.length = sizeof(struct iw_range);	  /* Set information in the range struct.  */	  range.throughput = 1.6 * 1024 * 1024;	/* 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(ioaddr, mmroff(0, mmr_fee_status)) &	       (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))	    {	      range.num_channels = 10;	      range.num_frequency = wv_frequency_list(ioaddr, range.freq,						      IW_MAX_FREQUENCIES);	    }	  else	    range.num_channels = range.num_frequency = 0;	  range.sensitivity = 0x3F;	  range.max_qual.qual = MMR_SGNL_QUAL;	  range.max_qual.level = MMR_SIGNAL_LVL;	  range.max_qual.noise = MMR_SILENCE_LVL;	  /* Copy structure to the user buffer. */	  copy_to_user(wrq->u.data.pointer, &range,		       sizeof(struct iw_range));	}      break;    case SIOCGIWPRIV:      /* Basic checking */      if(wrq->u.data.pointer != (caddr_t) 0)	{	  struct iw_priv_args	priv[] =	  {	/* cmd,		set_args,	get_args,	name */	    { SIOCSIPQTHR, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setqualthr" },	    { SIOCGIPQTHR, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getqualthr" },	    { SIOCSIPHISTO, IW_PRIV_TYPE_BYTE | 16,	0, "sethisto" },	    { SIOCGIPHISTO, 0,	    IW_PRIV_TYPE_INT | 16, "gethisto" },	  };	  /* Verify the user buffer. */	  ret = verify_area(VERIFY_WRITE, wrq->u.data.pointer,			    sizeof(priv));	  if(ret)	    break;	  /* Set the number of available ioctls. */	  wrq->u.data.length = 4;	  /* Copy structure to the user buffer. */	  copy_to_user(wrq->u.data.pointer, (u_char *) priv,		       sizeof(priv));	}      break;#ifdef WIRELESS_SPY    case SIOCSIWSPY:      /* Set the spy list */      /* Check the number of addresses. */      if(wrq->u.data.length > IW_MAX_SPY)	{	  ret = -E2BIG;	  break;	}      lp->spy_number = wrq->u.data.length;      /* Are there are addresses to copy? */      if(lp->spy_number > 0)	{	  struct sockaddr	address[IW_MAX_SPY];	  int			i;	  /* Verify where the user has set his addresses. */	  ret = verify_area(VERIFY_READ, wrq->u.data.pointer,			    sizeof(struct sockaddr) * lp->spy_number);	  if(ret)	    break;	  /* Copy addresses to the driver. */	  copy_from_user(address, wrq->u.data.pointer,			 sizeof(struct sockaddr) * lp->spy_number);	  /* Copy addresses to the lp structure. */	  for(i = 0; i < lp->spy_number; i++)	    {	      memcpy(lp->spy_address[i], address[i].sa_data,		     WAVELAN_ADDR_SIZE);	    }	  /* Reset structure. */	  memset(lp->spy_stat, 0x00, sizeof(iw_qual) * IW_MAX_SPY);#ifdef DEBUG_IOCTL_INFO	  printk(KERN_DEBUG "SetSpy:  set of new addresses is: \n");	  for(i = 0; i < wrq->u.data.length; i++)	    printk(KERN_DEBUG "%02X:%02X:%02X:%02X:%02X:%02X \n",		   lp->spy_address[i][0],		   lp->spy_address[i][1],		   lp->spy_address[i][2],		   lp->spy_address[i][3],		   lp->spy_address[i][4],		   lp->spy_address[i][5]);#endif	/* DEBUG_IOCTL_INFO */	}      break;    case SIOCGIWSPY:      /* Get the spy list and spy stats. */      /* Set the number of addresses */      wrq->u.data.length = lp->spy_number;      /* Does the user want to have the addresses back? */      if((lp->spy_number > 0) && (wrq->u.data.pointer != (caddr_t) 0))	{	  struct sockaddr	address[IW_MAX_SPY];	  int			i;	  /* Verify the user buffer. */	  ret = verify_area(VERIFY_WRITE, wrq->u.data.pointer,			    (sizeof(iw_qual) + sizeof(struct sockaddr))			    * IW_MAX_SPY);	  if(ret)	    break;	  /* Copy addresses from the lp structure. */	  for(i = 0; i < lp->spy_number; i++)	    {	      memcpy(address[i].sa_data, lp->spy_address[i],		     WAVELAN_ADDR_SIZE);	      address[i].sa_family = AF_UNIX;	    }	  /* Copy addresses to the user buffer. */	  copy_to_user(wrq->u.data.pointer, address,		       sizeof(struct sockaddr) * lp->spy_number);	  /* Copy stats to the user buffer (just after). */	  copy_to_user(wrq->u.data.pointer +		       (sizeof(struct sockaddr) * lp->spy_number),		       lp->spy_stat, sizeof(iw_qual) * lp->spy_number);	  /* Reset updated flags. */	  for(i = 0; i < lp->spy_number; i++)	    lp->spy_stat[i].updated = 0x0;	}	/* if(pointer != NULL) */      break;#endif	/* WIRELESS_SPY */      /* ------------------ PRIVATE IOCTL ------------------ */    case SIOCSIPQTHR:      if(!suser())	return -EPERM;      psa.psa_quality_thr = *(wrq->u.name) & 0x0F;      psa_write(ioaddr, lp->hacr, (char *)&psa.psa_quality_thr - (char *)&psa,	       (unsigned char *)&psa.psa_quality_thr, 1);#ifdef SET_PSA_CRC      /* update the Wavelan checksum */      update_psa_checksum(dev, ioaddr, lp->hacr);#endif      mmc_out(ioaddr, mmwoff(0, mmw_quality_thr), psa.psa_quality_thr);      break;    case SIOCGIPQTHR:      psa_read(ioaddr, lp->hacr, (char *)&psa.psa_quality_thr - (char *)&psa,	       (unsigned char *)&psa.psa_quality_thr, 1);      *(wrq->u.name) = psa.psa_quality_thr & 0x0F;      break;#ifdef HISTOGRAM    case SIOCSIPHISTO:      /* Verify that the user is root. */      if(!suser())	return -EPERM;      /* Check the number of intervals. */      if(wrq->u.data.length > 16)	{	  ret = -E2BIG;	  break;	}      lp->his_number = wrq->u.data.length;      /* Are there addresses to copy? */      if(lp->his_number > 0)	{	  /* Verify where the user has set his addresses. */	  ret = verify_area(VERIFY_READ, wrq->u.data.pointer,			    sizeof(char) * lp->his_number);	  if(ret)	    break;	  /* Copy interval ranges to the driver */	  copy_from_user(lp->his_range, wrq->u.data.pointer,			 sizeof(char) * lp->his_number);	  /* Reset structure. */	  memset(lp->his_sum, 0x00, sizeof(long) * 16);	}      break;    case SIOCGIPHISTO:      /* Set the number of intervals. */      wrq->u.data.length = lp->his_number;      /* Give back the distribution statistics */      if((lp->his_number > 0) && (wrq->u.data.pointer != (caddr_t) 0))	{	  /* Verify the user buffer. */	  ret = verify_area(VERIFY_WRITE, wrq->u.data.pointer,			    sizeof(long) * 16);	  if(ret)	    break;	  /* Copy data to the user buffer. */	  copy_to_user(wrq->u.data.pointer, lp->his_sum,		       sizeof(long) * lp->his_number);	}	/* if(pointer != NULL) */      break;#endif	/* HISTOGRAM */      /* ------------------- OTHER IOCTL ------------------- */    default:      ret = -EOPNOTSUPP;    }  /* Enable interrupts and restore flags. */  wv_splx(x);#ifdef DEBUG_IOCTL_TRACE  printk(KERN_DEBUG "%s: <-wavelan_ioctl()\n", dev->name);#endif  return ret;}/*------------------------------------------------------------------*//* * Get wireless statistics. * Called by /proc/net/wireless */static iw_stats *wavelan_get_wireless_stats(device *	dev){  u_long		ioaddr = dev->base_addr;  net_local *		lp = (net_local *) dev->priv;  mmr_t			m;  iw_stats *		wstats;  unsigned long		x;#ifdef DEBUG_IOCTL_TRACE  printk(KERN_DEBUG "%s: ->wavelan_get_wireless_stats()\n", dev->name);#endif  /* Disable interrupts and save flags. */  x = wv_splhi();  if(lp == (net_local *) NULL)    return (iw_stats *) NULL;  wstats = &lp->wstats;  /* Get data from the mmc. */  mmc_out(ioaddr, mmwoff(0, mmw_freeze), 1);  mmc_read(ioaddr, mmroff(0, mmr_dce_status), &m.mmr_dce_status, 1);  mmc_read(ioaddr, mmroff(0, mmr_wrong_nwid_l), &m.mmr_wrong_nwid_l, 2);  mmc_read(ioaddr, mmroff(0, mmr_thr_pre_set), &m.mmr_thr_pre_set, 4);  mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0);  /* Copy data to wireless stuff. */  wstats->status = m.mmr_dce_status & MMR_DCE_STATUS;  wstats->qual.qual = m.mmr_sgnl_qual & MMR_SGNL_QUAL;  wstats->qual.level = m.mmr_signal_lvl & MM

⌨️ 快捷键说明

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