wavelan_cs.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:136k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Wavelan Pcmcia driver
  3.  *
  4.  * Jean II - HPLB '96
  5.  *
  6.  * Reorganisation and extension of the driver.
  7.  * Original copyright follow. See wavelan_cs.h for details.
  8.  *
  9.  * This code is derived from Anthony D. Joseph's code and all the changes here
  10.  * are also under the original copyright below.
  11.  *
  12.  * This code supports version 2.00 of WaveLAN/PCMCIA cards (2.4GHz), and
  13.  * can work on Linux 2.0.36 with support of David Hinds' PCMCIA Card Services
  14.  *
  15.  * Joe Finney (joe@comp.lancs.ac.uk) at Lancaster University in UK added
  16.  * critical code in the routine to initialize the Modem Management Controller.
  17.  *
  18.  * Thanks to Alan Cox and Bruce Janson for their advice.
  19.  *
  20.  * -- Yunzhou Li (scip4166@nus.sg)
  21.  *
  22. #ifdef WAVELAN_ROAMING
  23.  * Roaming support added 07/22/98 by Justin Seger (jseger@media.mit.edu)
  24.  * based on patch by Joe Finney from Lancaster University.
  25. #endif :-)
  26.  *
  27.  * Lucent (formerly AT&T GIS, formerly NCR) WaveLAN PCMCIA card: An
  28.  * Ethernet-like radio transceiver controlled by an Intel 82593 coprocessor.
  29.  *
  30.  *   A non-shared memory PCMCIA ethernet driver for linux
  31.  *
  32.  * ISA version modified to support PCMCIA by Anthony Joseph (adj@lcs.mit.edu)
  33.  *
  34.  *
  35.  * Joseph O'Sullivan & John Langford (josullvn@cs.cmu.edu & jcl@cs.cmu.edu)
  36.  *
  37.  * Apr 2 '98  made changes to bring the i82593 control/int handling in line
  38.  *             with offical specs...
  39.  *
  40.  * Changes:
  41.  * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/08/2000
  42.  * - reorganize kmallocs in wavelan_attach, checking all for failure
  43.  *   and releasing the previous allocations if one fails
  44.  *
  45.  *
  46.  ****************************************************************************
  47.  *   Copyright 1995
  48.  *   Anthony D. Joseph
  49.  *   Massachusetts Institute of Technology
  50.  *
  51.  *   Permission to use, copy, modify, and distribute this program
  52.  *   for any purpose and without fee is hereby granted, provided
  53.  *   that this copyright and permission notice appear on all copies
  54.  *   and supporting documentation, the name of M.I.T. not be used
  55.  *   in advertising or publicity pertaining to distribution of the
  56.  *   program without specific prior permission, and notice be given
  57.  *   in supporting documentation that copying and distribution is
  58.  *   by permission of M.I.T.  M.I.T. makes no representations about
  59.  *   the suitability of this software for any purpose.  It is pro-
  60.  *   vided "as is" without express or implied warranty.         
  61.  ****************************************************************************
  62.  *
  63.  */
  64. #include "wavelan_cs.h" /* Private header */
  65. /************************* MISC SUBROUTINES **************************/
  66. /*
  67.  * Subroutines which won't fit in one of the following category
  68.  * (wavelan modem or i82593)
  69.  */
  70. /*------------------------------------------------------------------*/
  71. /*
  72.  * Wrapper for reporting error to cardservices
  73.  */
  74. static void cs_error(client_handle_t handle, int func, int ret)
  75. {
  76.     error_info_t err = { func, ret };
  77.     CardServices(ReportError, handle, &err);
  78. }
  79. #ifdef STRUCT_CHECK
  80. /*------------------------------------------------------------------*/
  81. /*
  82.  * Sanity routine to verify the sizes of the various WaveLAN interface
  83.  * structures.
  84.  */
  85. static char *
  86. wv_structuct_check(void)
  87. {
  88. #define SC(t,s,n) if (sizeof(t) != s) return(n);
  89.   SC(psa_t, PSA_SIZE, "psa_t");
  90.   SC(mmw_t, MMW_SIZE, "mmw_t");
  91.   SC(mmr_t, MMR_SIZE, "mmr_t");
  92. #undef SC
  93.   return((char *) NULL);
  94. } /* wv_structuct_check */
  95. #endif /* STRUCT_CHECK */
  96. /******************* MODEM MANAGEMENT SUBROUTINES *******************/
  97. /*
  98.  * Usefull subroutines to manage the modem of the wavelan
  99.  */
  100. /*------------------------------------------------------------------*/
  101. /*
  102.  * Read from card's Host Adaptor Status Register.
  103.  */
  104. static inline u_char
  105. hasr_read(u_long base)
  106. {
  107.   return(inb(HASR(base)));
  108. } /* hasr_read */
  109. /*------------------------------------------------------------------*/
  110. /*
  111.  * Write to card's Host Adapter Command Register.
  112.  */
  113. static inline void
  114. hacr_write(u_long base,
  115.    u_char hacr)
  116. {
  117.   outb(hacr, HACR(base));
  118. } /* hacr_write */
  119. /*------------------------------------------------------------------*/
  120. /*
  121.  * Write to card's Host Adapter Command Register. Include a delay for
  122.  * those times when it is needed.
  123.  */
  124. static inline void
  125. hacr_write_slow(u_long base,
  126. u_char hacr)
  127. {
  128.   hacr_write(base, hacr);
  129.   /* delay might only be needed sometimes */
  130.   mdelay(1L);
  131. } /* hacr_write_slow */
  132. /*------------------------------------------------------------------*/
  133. /*
  134.  * Read the Parameter Storage Area from the WaveLAN card's memory
  135.  */
  136. static void
  137. psa_read(device * dev,
  138.  int o, /* offset in PSA */
  139.  u_char * b, /* buffer to fill */
  140.  int n) /* size to read */
  141. {
  142.   u_char * ptr = ((u_char *)dev->mem_start) + PSA_ADDR + (o << 1);
  143.   while(n-- > 0)
  144.     {
  145.       *b++ = readb(ptr);
  146.       /* Due to a lack of address decode pins, the WaveLAN PCMCIA card
  147.        * only supports reading even memory addresses. That means the
  148.        * increment here MUST be two.
  149.        * Because of that, we can't use memcpy_fromio()...
  150.        */
  151.       ptr += 2;
  152.     }
  153. } /* psa_read */
  154. /*------------------------------------------------------------------*/
  155. /*
  156.  * Write the Paramter Storage Area to the WaveLAN card's memory
  157.  */
  158. static void
  159. psa_write(device * dev,
  160.   int o, /* Offset in psa */
  161.   u_char * b, /* Buffer in memory */
  162.   int n) /* Length of buffer */
  163. {
  164.   u_char * ptr = ((u_char *) dev->mem_start) + PSA_ADDR + (o << 1);
  165.   int count = 0;
  166.   ioaddr_t base = dev->base_addr;
  167.   /* As there seem to have no flag PSA_BUSY as in the ISA model, we are
  168.    * oblige to verify this address to know when the PSA is ready... */
  169.   volatile u_char * verify = ((u_char *) dev->mem_start) + PSA_ADDR +
  170.     (psaoff(0, psa_comp_number) << 1);
  171.   /* Authorize writting to PSA */
  172.   hacr_write(base, HACR_PWR_STAT | HACR_ROM_WEN);
  173.   while(n-- > 0)
  174.     {
  175.       /* write to PSA */
  176.       writeb(*b++, ptr);
  177.       ptr += 2;
  178.       /* I don't have the spec, so I don't know what the correct
  179.        * sequence to write is. This hack seem to work for me... */
  180.       count = 0;
  181.       while((readb(verify) != PSA_COMP_PCMCIA_915) && (count++ < 100))
  182. mdelay(1);
  183.     }
  184.   /* Put the host interface back in standard state */
  185.   hacr_write(base, HACR_DEFAULT);
  186. } /* psa_write */
  187. #ifdef SET_PSA_CRC
  188. /*------------------------------------------------------------------*/
  189. /*
  190.  * Calculate the PSA CRC
  191.  * Thanks to Valster, Nico <NVALSTER@wcnd.nl.lucent.com> for the code
  192.  * NOTE: By specifying a length including the CRC position the
  193.  * returned value should be zero. (i.e. a correct checksum in the PSA)
  194.  *
  195.  * The Windows drivers don't use the CRC, but the AP and the PtP tool
  196.  * depend on it.
  197.  */
  198. static u_short
  199. psa_crc(unsigned char * psa, /* The PSA */
  200. int size) /* Number of short for CRC */
  201. {
  202.   int byte_cnt; /* Loop on the PSA */
  203.   u_short crc_bytes = 0; /* Data in the PSA */
  204.   int bit_cnt; /* Loop on the bits of the short */
  205.   for(byte_cnt = 0; byte_cnt < size; byte_cnt++ )
  206.     {
  207.       crc_bytes ^= psa[byte_cnt]; /* Its an xor */
  208.       for(bit_cnt = 1; bit_cnt < 9; bit_cnt++ )
  209. {
  210.   if(crc_bytes & 0x0001)
  211.     crc_bytes = (crc_bytes >> 1) ^ 0xA001;
  212.   else
  213.     crc_bytes >>= 1 ;
  214.         }
  215.     }
  216.   return crc_bytes;
  217. } /* psa_crc */
  218. #endif /* SET_PSA_CRC */
  219. /*------------------------------------------------------------------*/
  220. /*
  221.  * update the checksum field in the Wavelan's PSA
  222.  */
  223. static void
  224. update_psa_checksum(device * dev)
  225. {
  226. #ifdef SET_PSA_CRC
  227.   psa_t psa;
  228.   u_short crc;
  229.   /* read the parameter storage area */
  230.   psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
  231.   /* update the checksum */
  232.   crc = psa_crc((unsigned char *) &psa,
  233. sizeof(psa) - sizeof(psa.psa_crc[0]) - sizeof(psa.psa_crc[1])
  234. - sizeof(psa.psa_crc_status));
  235.   psa.psa_crc[0] = crc & 0xFF;
  236.   psa.psa_crc[1] = (crc & 0xFF00) >> 8;
  237.   /* Write it ! */
  238.   psa_write(dev, (char *)&psa.psa_crc - (char *)&psa,
  239.     (unsigned char *)&psa.psa_crc, 2);
  240. #ifdef DEBUG_IOCTL_INFO
  241.   printk (KERN_DEBUG "%s: update_psa_checksum(): crc = 0x%02x%02xn",
  242.           dev->name, psa.psa_crc[0], psa.psa_crc[1]);
  243.   /* Check again (luxury !) */
  244.   crc = psa_crc((unsigned char *) &psa,
  245.  sizeof(psa) - sizeof(psa.psa_crc_status));
  246.   if(crc != 0)
  247.     printk(KERN_WARNING "%s: update_psa_checksum(): CRC does not agree with PSA data (even after recalculating)n", dev->name);
  248. #endif /* DEBUG_IOCTL_INFO */
  249. #endif /* SET_PSA_CRC */
  250. } /* update_psa_checksum */
  251. /*------------------------------------------------------------------*/
  252. /*
  253.  * Write 1 byte to the MMC.
  254.  */
  255. static inline void
  256. mmc_out(u_long base,
  257. u_short o,
  258. u_char d)
  259. {
  260.   /* Wait for MMC to go idle */
  261.   while(inb(HASR(base)) & HASR_MMI_BUSY)
  262.     ;
  263.   outb((u_char)((o << 1) | MMR_MMI_WR), MMR(base));
  264.   outb(d, MMD(base));
  265. }
  266. /*------------------------------------------------------------------*/
  267. /*
  268.  * Routine to write bytes to the Modem Management Controller.
  269.  * We start by the end because it is the way it should be !
  270.  */
  271. static inline void
  272. mmc_write(u_long base,
  273.   u_char o,
  274.   u_char * b,
  275.   int n)
  276. {
  277.   o += n;
  278.   b += n;
  279.   while(n-- > 0 )
  280.     mmc_out(base, --o, *(--b));
  281. } /* mmc_write */
  282. /*------------------------------------------------------------------*/
  283. /*
  284.  * Read 1 byte from the MMC.
  285.  * Optimised version for 1 byte, avoid using memory...
  286.  */
  287. static inline u_char
  288. mmc_in(u_long base,
  289.        u_short o)
  290. {
  291.   while(inb(HASR(base)) & HASR_MMI_BUSY)
  292.     ;
  293.   outb(o << 1, MMR(base)); /* Set the read address */
  294.   outb(0, MMD(base)); /* Required dummy write */
  295.   while(inb(HASR(base)) & HASR_MMI_BUSY)
  296.     ;
  297.   return (u_char) (inb(MMD(base))); /* Now do the actual read */
  298. }
  299. /*------------------------------------------------------------------*/
  300. /*
  301.  * Routine to read bytes from the Modem Management Controller.
  302.  * The implementation is complicated by a lack of address lines,
  303.  * which prevents decoding of the low-order bit.
  304.  * (code has just been moved in the above function)
  305.  * We start by the end because it is the way it should be !
  306.  */
  307. static inline void
  308. mmc_read(u_long base,
  309.  u_char o,
  310.  u_char * b,
  311.  int n)
  312. {
  313.   o += n;
  314.   b += n;
  315.   while(n-- > 0)
  316.     *(--b) = mmc_in(base, --o);
  317. } /* mmc_read */
  318. /*------------------------------------------------------------------*/
  319. /*
  320.  * Get the type of encryption available...
  321.  */
  322. static inline int
  323. mmc_encr(u_long base) /* i/o port of the card */
  324. {
  325.   int temp;
  326.   temp = mmc_in(base, mmroff(0, mmr_des_avail));
  327.   if((temp != MMR_DES_AVAIL_DES) && (temp != MMR_DES_AVAIL_AES))
  328.     return 0;
  329.   else
  330.     return temp;
  331. }
  332. /*------------------------------------------------------------------*/
  333. /*
  334.  * Wait for the frequency EEprom to complete a command...
  335.  * I hope this one will be optimally inlined...
  336.  */
  337. static inline void
  338. fee_wait(u_long base, /* i/o port of the card */
  339.  int delay, /* Base delay to wait for */
  340.  int number) /* Number of time to wait */
  341. {
  342.   int count = 0; /* Wait only a limited time */
  343.   while((count++ < number) &&
  344. (mmc_in(base, mmroff(0, mmr_fee_status)) & MMR_FEE_STATUS_BUSY))
  345.     udelay(delay);
  346. }
  347. /*------------------------------------------------------------------*/
  348. /*
  349.  * Read bytes from the Frequency EEprom (frequency select cards).
  350.  */
  351. static void
  352. fee_read(u_long base, /* i/o port of the card */
  353.  u_short o, /* destination offset */
  354.  u_short * b, /* data buffer */
  355.  int n) /* number of registers */
  356. {
  357.   b += n; /* Position at the end of the area */
  358.   /* Write the address */
  359.   mmc_out(base, mmwoff(0, mmw_fee_addr), o + n - 1);
  360.   /* Loop on all buffer */
  361.   while(n-- > 0)
  362.     {
  363.       /* Write the read command */
  364.       mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_READ);
  365.       /* Wait until EEprom is ready (should be quick !) */
  366.       fee_wait(base, 10, 100);
  367.       /* Read the value */
  368.       *--b = ((mmc_in(base, mmroff(0, mmr_fee_data_h)) << 8) |
  369.       mmc_in(base, mmroff(0, mmr_fee_data_l)));
  370.     }
  371. }
  372. #ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */
  373. /*------------------------------------------------------------------*/
  374. /*
  375.  * Write bytes from the Frequency EEprom (frequency select cards).
  376.  * This is a bit complicated, because the frequency eeprom has to
  377.  * be unprotected and the write enabled.
  378.  * Jean II
  379.  */
  380. static void
  381. fee_write(u_long base, /* i/o port of the card */
  382.   u_short o, /* destination offset */
  383.   u_short * b, /* data buffer */
  384.   int n) /* number of registers */
  385. {
  386.   b += n; /* Position at the end of the area */
  387. #ifdef EEPROM_IS_PROTECTED /* disabled */
  388. #ifdef DOESNT_SEEM_TO_WORK /* disabled */
  389.   /* Ask to read the protected register */
  390.   mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRREAD);
  391.   fee_wait(base, 10, 100);
  392.   /* Read the protected register */
  393.   printk("Protected 2 : %02X-%02Xn",
  394.  mmc_in(base, mmroff(0, mmr_fee_data_h)),
  395.  mmc_in(base, mmroff(0, mmr_fee_data_l)));
  396. #endif /* DOESNT_SEEM_TO_WORK */
  397.   /* Enable protected register */
  398.   mmc_out(base, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN);
  399.   mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PREN);
  400.   fee_wait(base, 10, 100);
  401.   /* Unprotect area */
  402.   mmc_out(base, mmwoff(0, mmw_fee_addr), o + n);
  403.   mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);
  404. #ifdef DOESNT_SEEM_TO_WORK /* disabled */
  405.   /* Or use : */
  406.   mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRCLEAR);
  407. #endif /* DOESNT_SEEM_TO_WORK */
  408.   fee_wait(base, 10, 100);
  409. #endif /* EEPROM_IS_PROTECTED */
  410.   /* Write enable */
  411.   mmc_out(base, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN);
  412.   mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WREN);
  413.   fee_wait(base, 10, 100);
  414.   /* Write the EEprom address */
  415.   mmc_out(base, mmwoff(0, mmw_fee_addr), o + n - 1);
  416.   /* Loop on all buffer */
  417.   while(n-- > 0)
  418.     {
  419.       /* Write the value */
  420.       mmc_out(base, mmwoff(0, mmw_fee_data_h), (*--b) >> 8);
  421.       mmc_out(base, mmwoff(0, mmw_fee_data_l), *b & 0xFF);
  422.       /* Write the write command */
  423.       mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WRITE);
  424.       /* Wavelan doc says : wait at least 10 ms for EEBUSY = 0 */
  425.       mdelay(10);
  426.       fee_wait(base, 10, 100);
  427.     }
  428.   /* Write disable */
  429.   mmc_out(base, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_DS);
  430.   mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WDS);
  431.   fee_wait(base, 10, 100);
  432. #ifdef EEPROM_IS_PROTECTED /* disabled */
  433.   /* Reprotect EEprom */
  434.   mmc_out(base, mmwoff(0, mmw_fee_addr), 0x00);
  435.   mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);
  436.   fee_wait(base, 10, 100);
  437. #endif /* EEPROM_IS_PROTECTED */
  438. }
  439. #endif /* WIRELESS_EXT */
  440. /******************* WaveLAN Roaming routines... ********************/
  441. #ifdef WAVELAN_ROAMING /* Conditional compile, see wavelan_cs.h */
  442. unsigned char WAVELAN_BEACON_ADDRESS[]= {0x09,0x00,0x0e,0x20,0x03,0x00};
  443.   
  444. void wv_roam_init(struct net_device *dev)
  445. {
  446.   net_local  *lp= (net_local *)dev->priv;
  447.   /* Do not remove this unless you have a good reason */
  448.   printk(KERN_NOTICE "%s: Warning, you have enabled roaming on"
  449.  " device %s !n", dev->name, dev->name);
  450.   printk(KERN_NOTICE "Roaming is currently an experimental unsupported feature"
  451.  " of the Wavelan driver.n");
  452.   printk(KERN_NOTICE "It may work, but may also make the driver behave in"
  453.  " erratic ways or crash.n");
  454.   lp->wavepoint_table.head=NULL;           /* Initialise WavePoint table */
  455.   lp->wavepoint_table.num_wavepoints=0;
  456.   lp->wavepoint_table.locked=0;
  457.   lp->curr_point=NULL;                        /* No default WavePoint */
  458.   lp->cell_search=0;
  459.   
  460.   lp->cell_timer.data=(int)lp;                /* Start cell expiry timer */
  461.   lp->cell_timer.function=wl_cell_expiry;
  462.   lp->cell_timer.expires=jiffies+CELL_TIMEOUT;
  463.   add_timer(&lp->cell_timer);
  464.   
  465.   wv_nwid_filter(NWID_PROMISC,lp) ;    /* Enter NWID promiscuous mode */
  466.   /* to build up a good WavePoint */
  467.                                            /* table... */
  468.   printk(KERN_DEBUG "WaveLAN: Roaming enabled on device %sn",dev->name);
  469. }
  470.  
  471. void wv_roam_cleanup(struct net_device *dev)
  472. {
  473.   wavepoint_history *ptr,*old_ptr;
  474.   net_local *lp= (net_local *)dev->priv;
  475.   
  476.   printk(KERN_DEBUG "WaveLAN: Roaming Disabled on device %sn",dev->name);
  477.   
  478.   /* Fixme : maybe we should check that the timer exist before deleting it */
  479.   del_timer(&lp->cell_timer);          /* Remove cell expiry timer       */
  480.   ptr=lp->wavepoint_table.head;        /* Clear device's WavePoint table */
  481.   while(ptr!=NULL)
  482.     {
  483.       old_ptr=ptr;
  484.       ptr=ptr->next;
  485.       wl_del_wavepoint(old_ptr,lp);
  486.     }
  487. }
  488. /* Enable/Disable NWID promiscuous mode on a given device */
  489. void wv_nwid_filter(unsigned char mode, net_local *lp)
  490. {
  491.   mm_t                  m;
  492.   unsigned long         flags;
  493.   
  494. #ifdef WAVELAN_ROAMING_DEBUG
  495.   printk(KERN_DEBUG "WaveLAN: NWID promisc %s, device %sn",(mode==NWID_PROMISC) ? "on" : "off", lp->dev->name);
  496. #endif
  497.   
  498.   /* Disable interrupts & save flags */
  499.   spin_lock_irqsave (&lp->lock, flags);
  500.   
  501.   m.w.mmw_loopt_sel = (mode==NWID_PROMISC) ? MMW_LOOPT_SEL_DIS_NWID : 0x00;
  502.   mmc_write(lp->dev->base_addr, (char *)&m.w.mmw_loopt_sel - (char *)&m, (unsigned char *)&m.w.mmw_loopt_sel, 1);
  503.   
  504.   /* ReEnable interrupts & restore flags */
  505.   spin_unlock_irqrestore (&lp->lock, flags);
  506.   
  507.   if(mode==NWID_PROMISC)
  508.     lp->cell_search=1;
  509.   else
  510. lp->cell_search=0;
  511. }
  512. /* Find a record in the WavePoint table matching a given NWID */
  513. wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp)
  514. {
  515.   wavepoint_history *ptr=lp->wavepoint_table.head;
  516.   
  517.   while(ptr!=NULL){
  518.     if(ptr->nwid==nwid)
  519.       return ptr;
  520.     ptr=ptr->next;
  521.   }
  522.   return NULL;
  523. }
  524. /* Create a new wavepoint table entry */
  525. wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_local* lp)
  526. {
  527.   wavepoint_history *new_wavepoint;
  528. #ifdef WAVELAN_ROAMING_DEBUG
  529.   printk(KERN_DEBUG "WaveLAN: New Wavepoint, NWID:%.4Xn",nwid);
  530. #endif
  531.   
  532.   if(lp->wavepoint_table.num_wavepoints==MAX_WAVEPOINTS)
  533.     return NULL;
  534.   
  535.   new_wavepoint=(wavepoint_history *) kmalloc(sizeof(wavepoint_history),GFP_ATOMIC);
  536.   if(new_wavepoint==NULL)
  537.     return NULL;
  538.   
  539.   new_wavepoint->nwid=nwid;                       /* New WavePoints NWID */
  540.   new_wavepoint->average_fast=0;                    /* Running Averages..*/
  541.   new_wavepoint->average_slow=0;
  542.   new_wavepoint->qualptr=0;                       /* Start of ringbuffer */
  543.   new_wavepoint->last_seq=seq-1;                /* Last sequence no.seen */
  544.   memset(new_wavepoint->sigqual,0,WAVEPOINT_HISTORY);/* Empty ringbuffer */
  545.   
  546.   new_wavepoint->next=lp->wavepoint_table.head;/* Add to wavepoint table */
  547.   new_wavepoint->prev=NULL;
  548.   
  549.   if(lp->wavepoint_table.head!=NULL)
  550.     lp->wavepoint_table.head->prev=new_wavepoint;
  551.   
  552.   lp->wavepoint_table.head=new_wavepoint;
  553.   
  554.   lp->wavepoint_table.num_wavepoints++;     /* no. of visible wavepoints */
  555.   
  556.   return new_wavepoint;
  557. }
  558. /* Remove a wavepoint entry from WavePoint table */
  559. void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp)
  560. {
  561.   if(wavepoint==NULL)
  562.     return;
  563.   
  564.   if(lp->curr_point==wavepoint)
  565.     lp->curr_point=NULL;
  566.   
  567.   if(wavepoint->prev!=NULL)
  568.     wavepoint->prev->next=wavepoint->next;
  569.   
  570.   if(wavepoint->next!=NULL)
  571.     wavepoint->next->prev=wavepoint->prev;
  572.   
  573.   if(lp->wavepoint_table.head==wavepoint)
  574.     lp->wavepoint_table.head=wavepoint->next;
  575.   
  576.   lp->wavepoint_table.num_wavepoints--;
  577.   kfree(wavepoint);
  578. }
  579. /* Timer callback function - checks WavePoint table for stale entries */ 
  580. void wl_cell_expiry(unsigned long data)
  581. {
  582.   net_local *lp=(net_local *)data;
  583.   wavepoint_history *wavepoint=lp->wavepoint_table.head,*old_point;
  584.   
  585. #if WAVELAN_ROAMING_DEBUG > 1
  586.   printk(KERN_DEBUG "WaveLAN: Wavepoint timeout, dev %sn",lp->dev->name);
  587. #endif
  588.   
  589.   if(lp->wavepoint_table.locked)
  590.     {
  591. #if WAVELAN_ROAMING_DEBUG > 1
  592.       printk(KERN_DEBUG "WaveLAN: Wavepoint table locked...n");
  593. #endif
  594.       
  595.       lp->cell_timer.expires=jiffies+1; /* If table in use, come back later */
  596.       add_timer(&lp->cell_timer);
  597.       return;
  598.     }
  599.   
  600.   while(wavepoint!=NULL)
  601.     {
  602.       if(wavepoint->last_seen < jiffies-CELL_TIMEOUT)
  603. {
  604. #ifdef WAVELAN_ROAMING_DEBUG
  605.   printk(KERN_DEBUG "WaveLAN: Bye bye %.4Xn",wavepoint->nwid);
  606. #endif
  607.   
  608.   old_point=wavepoint;
  609.   wavepoint=wavepoint->next;
  610.   wl_del_wavepoint(old_point,lp);
  611. }
  612.       else
  613. wavepoint=wavepoint->next;
  614.     }
  615.   lp->cell_timer.expires=jiffies+CELL_TIMEOUT;
  616.   add_timer(&lp->cell_timer);
  617. }
  618. /* Update SNR history of a wavepoint */
  619. void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsigned char seq)
  620. {
  621.   int i=0,num_missed=0,ptr=0;
  622.   int average_fast=0,average_slow=0;
  623.   
  624.   num_missed=(seq-wavepoint->last_seq)%WAVEPOINT_HISTORY;/* Have we missed
  625.     any beacons? */
  626.   if(num_missed)
  627.     for(i=0;i<num_missed;i++)
  628.       {
  629. wavepoint->sigqual[wavepoint->qualptr++]=0; /* If so, enter them as 0's */
  630. wavepoint->qualptr %=WAVEPOINT_HISTORY;    /* in the ringbuffer. */
  631.       }
  632.   wavepoint->last_seen=jiffies;                 /* Add beacon to history */
  633.   wavepoint->last_seq=seq;
  634.   wavepoint->sigqual[wavepoint->qualptr++]=sigqual;          
  635.   wavepoint->qualptr %=WAVEPOINT_HISTORY;
  636.   ptr=(wavepoint->qualptr-WAVEPOINT_FAST_HISTORY+WAVEPOINT_HISTORY)%WAVEPOINT_HISTORY;
  637.   
  638.   for(i=0;i<WAVEPOINT_FAST_HISTORY;i++)       /* Update running averages */
  639.     {
  640.       average_fast+=wavepoint->sigqual[ptr++];
  641.       ptr %=WAVEPOINT_HISTORY;
  642.     }
  643.   
  644.   average_slow=average_fast;
  645.   for(i=WAVEPOINT_FAST_HISTORY;i<WAVEPOINT_HISTORY;i++)
  646.     {
  647.       average_slow+=wavepoint->sigqual[ptr++];
  648.       ptr %=WAVEPOINT_HISTORY;
  649.     }
  650.   
  651.   wavepoint->average_fast=average_fast/WAVEPOINT_FAST_HISTORY;
  652.   wavepoint->average_slow=average_slow/WAVEPOINT_HISTORY;
  653. }
  654. /* Perform a handover to a new WavePoint */
  655. void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp)
  656. {
  657.   ioaddr_t              base = lp->dev->base_addr;  
  658.   mm_t                  m;
  659.   unsigned long         flags;
  660.   
  661.   if(wavepoint==lp->curr_point)          /* Sanity check... */
  662.     {
  663.       wv_nwid_filter(!NWID_PROMISC,lp);
  664.       return;
  665.     }
  666.   
  667. #ifdef WAVELAN_ROAMING_DEBUG
  668.   printk(KERN_DEBUG "WaveLAN: Doing handover to %.4X, dev %sn",wavepoint->nwid,lp->dev->name);
  669. #endif
  670.  
  671.   /* Disable interrupts & save flags */
  672.   spin_lock_irqsave(&lp->lock, flags);
  673.   
  674.   m.w.mmw_netw_id_l = wavepoint->nwid & 0xFF;
  675.   m.w.mmw_netw_id_h = (wavepoint->nwid & 0xFF00) >> 8;
  676.   
  677.   mmc_write(base, (char *)&m.w.mmw_netw_id_l - (char *)&m, (unsigned char *)&m.w.mmw_netw_id_l, 2);
  678.   
  679.   /* ReEnable interrupts & restore flags */
  680.   spin_unlock_irqrestore (&lp->lock, flags);
  681.   
  682.   wv_nwid_filter(!NWID_PROMISC,lp);
  683.   lp->curr_point=wavepoint;
  684. }
  685. /* Called when a WavePoint beacon is received */
  686. static inline void wl_roam_gather(device *  dev,
  687.   u_char *  hdr,   /* Beacon header */
  688.   u_char *  stats) /* SNR, Signal quality 
  689.       of packet */
  690. {
  691.   wavepoint_beacon *beacon= (wavepoint_beacon *)hdr; /* Rcvd. Beacon */
  692.   unsigned short nwid=ntohs(beacon->nwid);  
  693.   unsigned short sigqual=stats[2] & MMR_SGNL_QUAL;   /* SNR of beacon */
  694.   wavepoint_history *wavepoint=NULL;                /* WavePoint table entry */
  695.   net_local *lp=(net_local *)dev->priv;              /* Device info */
  696. #if WAVELAN_ROAMING_DEBUG > 1
  697.   printk(KERN_DEBUG "WaveLAN: beacon, dev %s:n",dev->name);
  698.   printk(KERN_DEBUG "Domain: %.4X NWID: %.4X SigQual=%dn",ntohs(beacon->domain_id),nwid,sigqual);
  699. #endif
  700.   
  701.   lp->wavepoint_table.locked=1;                            /* <Mutex> */
  702.   
  703.   wavepoint=wl_roam_check(nwid,lp);            /* Find WavePoint table entry */
  704.   if(wavepoint==NULL)                    /* If no entry, Create a new one... */
  705.     {
  706.       wavepoint=wl_new_wavepoint(nwid,beacon->seq,lp);
  707.       if(wavepoint==NULL)
  708. goto out;
  709.     }
  710.   if(lp->curr_point==NULL)             /* If this is the only WavePoint, */
  711.     wv_roam_handover(wavepoint, lp);          /* Jump on it! */
  712.   
  713.   wl_update_history(wavepoint, sigqual, beacon->seq); /* Update SNR history
  714.  stats. */
  715.   
  716.   if(lp->curr_point->average_slow < SEARCH_THRESH_LOW) /* If our current */
  717.     if(!lp->cell_search)                  /* WavePoint is getting faint, */
  718.       wv_nwid_filter(NWID_PROMISC,lp);    /* start looking for a new one */
  719.   
  720.   if(wavepoint->average_slow > 
  721.      lp->curr_point->average_slow + WAVELAN_ROAMING_DELTA)
  722.     wv_roam_handover(wavepoint, lp);   /* Handover to a better WavePoint */
  723.   
  724.   if(lp->curr_point->average_slow > SEARCH_THRESH_HIGH) /* If our SNR is */
  725.     if(lp->cell_search)  /* getting better, drop out of cell search mode */
  726.       wv_nwid_filter(!NWID_PROMISC,lp);
  727.   
  728. out:
  729.   lp->wavepoint_table.locked=0;                        /* </MUTEX>   :-) */
  730. }
  731. /* Test this MAC frame a WavePoint beacon */
  732. static inline int WAVELAN_BEACON(unsigned char *data)
  733. {
  734.   wavepoint_beacon *beacon= (wavepoint_beacon *)data;
  735.   static wavepoint_beacon beacon_template={0xaa,0xaa,0x03,0x08,0x00,0x0e,0x20,0x03,0x00};
  736.   
  737.   if(memcmp(beacon,&beacon_template,9)==0)
  738.     return 1;
  739.   else
  740.     return 0;
  741. }
  742. #endif /* WAVELAN_ROAMING */
  743. /************************ I82593 SUBROUTINES *************************/
  744. /*
  745.  * Useful subroutines to manage the Ethernet controller
  746.  */
  747. /*------------------------------------------------------------------*/
  748. /*
  749.  * Routine to synchronously send a command to the i82593 chip. 
  750.  * Should be called with interrupts enabled.
  751.  */
  752. static int
  753. wv_82593_cmd(device * dev,
  754.      char * str,
  755.      int cmd,
  756.      int result)
  757. {
  758.   ioaddr_t base = dev->base_addr;
  759.   net_local * lp = (net_local *)dev->priv;
  760.   int status;
  761.   long spin;
  762.   u_long flags;
  763.   /* Spin until the chip finishes executing its current command (if any) */
  764.   do
  765.     {
  766.       spin_lock_irqsave (&lp->lock, flags);
  767.       outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
  768.       status = inb(LCSR(base));
  769.       spin_unlock_irqrestore (&lp->lock, flags);
  770.     }
  771.   while((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE);
  772.   /* We are waiting for command completion */
  773.   wv_wait_completed = TRUE;
  774.   /* Issue the command to the controller */
  775.   outb(cmd, LCCR(base));
  776.   /* If we don't have to check the result of the command */
  777.   if(result == SR0_NO_RESULT)
  778.     {
  779.       wv_wait_completed = FALSE;
  780.       return(TRUE);
  781.     }
  782.   /* Busy wait while the LAN controller executes the command.
  783.    * Note : wv_wait_completed should be volatile */
  784.   spin = 0;
  785.   while(wv_wait_completed && (spin++ < 1000))
  786.     udelay(10);
  787.   /* If the interrupt handler hasn't be called */
  788.   if(wv_wait_completed)
  789.     {
  790.       outb(OP0_NOP, LCCR(base));
  791.       status = inb(LCSR(base));
  792.       if(status & SR0_INTERRUPT)
  793. {
  794.   /* There was an interrupt : call the interrupt handler */
  795. #ifdef DEBUG_INTERRUPT_ERROR
  796.   printk(KERN_WARNING "wv_82593_cmd: interrupt handler not installed or interrupt disabledn");
  797. #endif
  798.   wavelan_interrupt(dev->irq, (void *) dev,
  799.     (struct pt_regs *) NULL);
  800. }
  801.       else
  802. {
  803.   wv_wait_completed = 0; /* XXX */
  804. #ifdef DEBUG_INTERRUPT_ERROR
  805.   printk(KERN_INFO "wv_82593_cmd: %s timeout, status0 0x%02xn",
  806.  str, status);
  807. #endif
  808.   /* We probably should reset the controller here */
  809.   return(FALSE);
  810. }
  811.     }
  812.   /* Check the return code provided by the interrupt handler against
  813.    * the expected return code provided by the caller */
  814.   if((lp->status & SR0_EVENT_MASK) != result)
  815.     {
  816. #ifdef DEBUG_INTERRUPT_ERROR
  817.       printk(KERN_INFO "wv_82593_cmd: %s failed, status0 = 0x%xn",
  818.      str, lp->status);
  819. #endif
  820.       return(FALSE);
  821.     }
  822.   return(TRUE);
  823. } /* wv_82593_cmd */
  824. /*------------------------------------------------------------------*/
  825. /*
  826.  * This routine does a 593 op-code number 7, and obtains the diagnose
  827.  * status for the WaveLAN.
  828.  */
  829. static inline int
  830. wv_diag(device * dev)
  831. {
  832.   if(wv_82593_cmd(dev, "wv_diag(): diagnose",
  833.   OP0_DIAGNOSE, SR0_DIAGNOSE_PASSED))
  834.     return(TRUE);
  835. #ifdef DEBUG_CONFIG_ERROR
  836.   printk(KERN_INFO "wavelan_cs: i82593 Self Test failed!n");
  837. #endif
  838.   return(FALSE);
  839. } /* wv_diag */
  840. /*------------------------------------------------------------------*/
  841. /*
  842.  * Routine to read len bytes from the i82593's ring buffer, starting at
  843.  * chip address addr. The results read from the chip are stored in buf.
  844.  * The return value is the address to use for next the call.
  845.  */
  846. static int
  847. read_ringbuf(device * dev,
  848.      int addr,
  849.      char * buf,
  850.      int len)
  851. {
  852.   ioaddr_t base = dev->base_addr;
  853.   int ring_ptr = addr;
  854.   int chunk_len;
  855.   char * buf_ptr = buf;
  856. #ifdef OLDIES
  857.   /* After having check skb_put (net/core/skbuff.c) in the kernel, it seem
  858.    * quite safe to remove this... */
  859.   /* If buf is NULL, just increment the ring buffer pointer */
  860.   if(buf == NULL)
  861.     return((ring_ptr - RX_BASE + len) % RX_SIZE + RX_BASE);
  862. #endif
  863.   /* Get all the buffer */
  864.   while(len > 0)
  865.     {
  866.       /* Position the Program I/O Register at the ring buffer pointer */
  867.       outb(ring_ptr & 0xff, PIORL(base));
  868.       outb(((ring_ptr >> 8) & PIORH_MASK), PIORH(base));
  869.       /* First, determine how much we can read without wrapping around the
  870.  ring buffer */
  871.       if((addr + len) < (RX_BASE + RX_SIZE))
  872. chunk_len = len;
  873.       else
  874. chunk_len = RX_BASE + RX_SIZE - addr;
  875.       insb(PIOP(base), buf_ptr, chunk_len);
  876.       buf_ptr += chunk_len;
  877.       len -= chunk_len;
  878.       ring_ptr = (ring_ptr - RX_BASE + chunk_len) % RX_SIZE + RX_BASE;
  879.     }
  880.   return(ring_ptr);
  881. } /* read_ringbuf */
  882. /*------------------------------------------------------------------*/
  883. /*
  884.  * Reconfigure the i82593, or at least ask for it...
  885.  * Because wv_82593_config use the transmission buffer, we must do it
  886.  * when we are sure that there is no transmission, so we do it now
  887.  * or in wavelan_packet_xmit() (I can't find any better place,
  888.  * wavelan_interrupt is not an option...), so you may experience
  889.  * some delay sometime...
  890.  */
  891. static inline void wv_82593_reconfig (device * dev)
  892. {
  893. net_local *lp = (net_local *) dev->priv;
  894. dev_link_t *link = ((net_local *) dev->priv)->link;
  895. /* Check if we can do it now ! */
  896. if (!(link->open)) {
  897. lp->reconfig_82593 = TRUE;
  898. #ifdef DEBUG_IOCTL_INFO
  899. printk (KERN_DEBUG "%s: wv_82593_reconfig(): delayed (link = %d)n",
  900. dev->name, link->open);
  901. #endif
  902. } else {
  903. netif_stop_queue (dev);
  904. lp->reconfig_82593 = FALSE;
  905. wv_82593_config (dev);
  906. netif_wake_queue (dev);
  907. }
  908. }
  909. #ifdef OLDIES
  910. /*------------------------------------------------------------------*/
  911. /*
  912.  * Dumps the current i82593 receive buffer to the console.
  913.  */
  914. static void wavelan_dump(device *dev)
  915. {
  916.   ioaddr_t base = dev->base_addr;
  917.   int i, c;
  918.   /* disable receiver so we can use channel 1 */
  919.   outb(OP0_RCV_DISABLE, LCCR(base));
  920.   /* reset receive DMA pointer */
  921.   hacr_write_slow(base, HACR_PWR_STAT | HACR_RX_DMA_RESET);
  922.   hacr_write(base, HACR_DEFAULT);
  923.   /* dump into receive buffer */
  924.   wv_82593_cmd(dev, "wavelan_dump(): dump", CR0_CHNL|OP0_DUMP, SR0_DUMP_DONE);
  925.   /* set read pointer to start of receive buffer */
  926.   outb(0, PIORL(base));
  927.   outb(0, PIORH(base));
  928.   printk(KERN_DEBUG "wavelan_cs: dump:n");
  929.   printk(KERN_DEBUG "     00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
  930.   for(i = 0; i < 73; i++){
  931.     if((i % 16) == 0) {
  932.       printk("n0x%02x:", i);
  933.       if (!i) {
  934. printk("   ");
  935. continue;
  936.       }
  937.     }
  938.     c = inb(PIOP(base));
  939.     printk("%02x ", c);
  940.   }
  941.   printk("n");
  942.   /* enable the receiver again */
  943.   wv_ru_start(dev);
  944. }
  945. #endif
  946. /********************* DEBUG & INFO SUBROUTINES *********************/
  947. /*
  948.  * This routines are used in the code to show debug informations.
  949.  * Most of the time, it dump the content of hardware structures...
  950.  */
  951. #ifdef DEBUG_PSA_SHOW
  952. /*------------------------------------------------------------------*/
  953. /*
  954.  * Print the formatted contents of the Parameter Storage Area.
  955.  */
  956. static void
  957. wv_psa_show(psa_t * p)
  958. {
  959.   printk(KERN_DEBUG "##### wavelan psa contents: #####n");
  960.   printk(KERN_DEBUG "psa_io_base_addr_1: 0x%02X %02X %02X %02Xn",
  961.  p->psa_io_base_addr_1,
  962.  p->psa_io_base_addr_2,
  963.  p->psa_io_base_addr_3,
  964.  p->psa_io_base_addr_4);
  965.   printk(KERN_DEBUG "psa_rem_boot_addr_1: 0x%02X %02X %02Xn",
  966.  p->psa_rem_boot_addr_1,
  967.  p->psa_rem_boot_addr_2,
  968.  p->psa_rem_boot_addr_3);
  969.   printk(KERN_DEBUG "psa_holi_params: 0x%02x, ", p->psa_holi_params);
  970.   printk("psa_int_req_no: %dn", p->psa_int_req_no);
  971. #ifdef DEBUG_SHOW_UNUSED
  972.   printk(KERN_DEBUG "psa_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02Xn",
  973.  p->psa_unused0[0],
  974.  p->psa_unused0[1],
  975.  p->psa_unused0[2],
  976.  p->psa_unused0[3],
  977.  p->psa_unused0[4],
  978.  p->psa_unused0[5],
  979.  p->psa_unused0[6]);
  980. #endif /* DEBUG_SHOW_UNUSED */
  981.   printk(KERN_DEBUG "psa_univ_mac_addr[]: %02x:%02x:%02x:%02x:%02x:%02xn",
  982.  p->psa_univ_mac_addr[0],
  983.  p->psa_univ_mac_addr[1],
  984.  p->psa_univ_mac_addr[2],
  985.  p->psa_univ_mac_addr[3],
  986.  p->psa_univ_mac_addr[4],
  987.  p->psa_univ_mac_addr[5]);
  988.   printk(KERN_DEBUG "psa_local_mac_addr[]: %02x:%02x:%02x:%02x:%02x:%02xn",
  989.  p->psa_local_mac_addr[0],
  990.  p->psa_local_mac_addr[1],
  991.  p->psa_local_mac_addr[2],
  992.  p->psa_local_mac_addr[3],
  993.  p->psa_local_mac_addr[4],
  994.  p->psa_local_mac_addr[5]);
  995.   printk(KERN_DEBUG "psa_univ_local_sel: %d, ", p->psa_univ_local_sel);
  996.   printk("psa_comp_number: %d, ", p->psa_comp_number);
  997.   printk("psa_thr_pre_set: 0x%02xn", p->psa_thr_pre_set);
  998.   printk(KERN_DEBUG "psa_feature_select/decay_prm: 0x%02x, ",
  999.  p->psa_feature_select);
  1000.   printk("psa_subband/decay_update_prm: %dn", p->psa_subband);
  1001.   printk(KERN_DEBUG "psa_quality_thr: 0x%02x, ", p->psa_quality_thr);
  1002.   printk("psa_mod_delay: 0x%02xn", p->psa_mod_delay);
  1003.   printk(KERN_DEBUG "psa_nwid: 0x%02x%02x, ", p->psa_nwid[0], p->psa_nwid[1]);
  1004.   printk("psa_nwid_select: %dn", p->psa_nwid_select);
  1005.   printk(KERN_DEBUG "psa_encryption_select: %d, ", p->psa_encryption_select);
  1006.   printk("psa_encryption_key[]: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02xn",
  1007.  p->psa_encryption_key[0],
  1008.  p->psa_encryption_key[1],
  1009.  p->psa_encryption_key[2],
  1010.  p->psa_encryption_key[3],
  1011.  p->psa_encryption_key[4],
  1012.  p->psa_encryption_key[5],
  1013.  p->psa_encryption_key[6],
  1014.  p->psa_encryption_key[7]);
  1015.   printk(KERN_DEBUG "psa_databus_width: %dn", p->psa_databus_width);
  1016.   printk(KERN_DEBUG "psa_call_code/auto_squelch: 0x%02x, ",
  1017.  p->psa_call_code[0]);
  1018.   printk("psa_call_code[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02Xn",
  1019.  p->psa_call_code[0],
  1020.  p->psa_call_code[1],
  1021.  p->psa_call_code[2],
  1022.  p->psa_call_code[3],
  1023.  p->psa_call_code[4],
  1024.  p->psa_call_code[5],
  1025.  p->psa_call_code[6],
  1026.  p->psa_call_code[7]);
  1027. #ifdef DEBUG_SHOW_UNUSED
  1028.   printk(KERN_DEBUG "psa_reserved[]: %02X:%02X:%02X:%02Xn",
  1029.  p->psa_reserved[0],
  1030.  p->psa_reserved[1],
  1031.  p->psa_reserved[2],
  1032.  p->psa_reserved[3]);
  1033. #endif /* DEBUG_SHOW_UNUSED */
  1034.   printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status);
  1035.   printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]);
  1036.   printk("psa_crc_status: 0x%02xn", p->psa_crc_status);
  1037. } /* wv_psa_show */
  1038. #endif /* DEBUG_PSA_SHOW */
  1039. #ifdef DEBUG_MMC_SHOW
  1040. /*------------------------------------------------------------------*/
  1041. /*
  1042.  * Print the formatted status of the Modem Management Controller.
  1043.  * This function need to be completed...
  1044.  */
  1045. static void
  1046. wv_mmc_show(device * dev)
  1047. {
  1048.   ioaddr_t base = dev->base_addr;
  1049.   net_local * lp = (net_local *)dev->priv;
  1050.   mmr_t m;
  1051.   /* Basic check */
  1052.   if(hasr_read(base) & HASR_NO_CLK)
  1053.     {
  1054.       printk(KERN_WARNING "%s: wv_mmc_show: modem not connectedn",
  1055.      dev->name);
  1056.       return;
  1057.     }
  1058.   /* Read the mmc */
  1059.   mmc_out(base, mmwoff(0, mmw_freeze), 1);
  1060.   mmc_read(base, 0, (u_char *)&m, sizeof(m));
  1061.   mmc_out(base, mmwoff(0, mmw_freeze), 0);
  1062. #ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */
  1063.   /* Don't forget to update statistics */
  1064.   lp->wstats.discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
  1065. #endif /* WIRELESS_EXT */
  1066.   printk(KERN_DEBUG "##### wavelan modem status registers: #####n");
  1067. #ifdef DEBUG_SHOW_UNUSED
  1068.   printk(KERN_DEBUG "mmc_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02Xn",
  1069.  m.mmr_unused0[0],
  1070.  m.mmr_unused0[1],
  1071.  m.mmr_unused0[2],
  1072.  m.mmr_unused0[3],
  1073.  m.mmr_unused0[4],
  1074.  m.mmr_unused0[5],
  1075.  m.mmr_unused0[6],
  1076.  m.mmr_unused0[7]);
  1077. #endif /* DEBUG_SHOW_UNUSED */
  1078.   printk(KERN_DEBUG "Encryption algorythm: %02X - Status: %02Xn",
  1079.  m.mmr_des_avail, m.mmr_des_status);
  1080. #ifdef DEBUG_SHOW_UNUSED
  1081.   printk(KERN_DEBUG "mmc_unused1[]: %02X:%02X:%02X:%02X:%02Xn",
  1082.  m.mmr_unused1[0],
  1083.  m.mmr_unused1[1],
  1084.  m.mmr_unused1[2],
  1085.  m.mmr_unused1[3],
  1086.  m.mmr_unused1[4]);
  1087. #endif /* DEBUG_SHOW_UNUSED */
  1088.   printk(KERN_DEBUG "dce_status: 0x%x [%s%s%s%s]n",
  1089.  m.mmr_dce_status,
  1090.  (m.mmr_dce_status & MMR_DCE_STATUS_RX_BUSY) ? "energy detected,":"",
  1091.  (m.mmr_dce_status & MMR_DCE_STATUS_LOOPT_IND) ?
  1092.  "loop test indicated," : "",
  1093.  (m.mmr_dce_status & MMR_DCE_STATUS_TX_BUSY) ? "transmitter on," : "",
  1094.  (m.mmr_dce_status & MMR_DCE_STATUS_JBR_EXPIRED) ?
  1095.  "jabber timer expired," : "");
  1096.   printk(KERN_DEBUG "Dsp ID: %02Xn",
  1097.  m.mmr_dsp_id);
  1098. #ifdef DEBUG_SHOW_UNUSED
  1099.   printk(KERN_DEBUG "mmc_unused2[]: %02X:%02Xn",
  1100.  m.mmr_unused2[0],
  1101.  m.mmr_unused2[1]);
  1102. #endif /* DEBUG_SHOW_UNUSED */
  1103.   printk(KERN_DEBUG "# correct_nwid: %d, # wrong_nwid: %dn",
  1104.  (m.mmr_correct_nwid_h << 8) | m.mmr_correct_nwid_l,
  1105.  (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l);
  1106.   printk(KERN_DEBUG "thr_pre_set: 0x%x [current signal %s]n",
  1107.  m.mmr_thr_pre_set & MMR_THR_PRE_SET,
  1108.  (m.mmr_thr_pre_set & MMR_THR_PRE_SET_CUR) ? "above" : "below");
  1109.   printk(KERN_DEBUG "signal_lvl: %d [%s], ",
  1110.  m.mmr_signal_lvl & MMR_SIGNAL_LVL,
  1111.  (m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) ? "new msg" : "no new msg");
  1112.   printk("silence_lvl: %d [%s], ", m.mmr_silence_lvl & MMR_SILENCE_LVL,
  1113.  (m.mmr_silence_lvl & MMR_SILENCE_LVL_VALID) ? "update done" : "no new update");
  1114.   printk("sgnl_qual: 0x%x [%s]n", m.mmr_sgnl_qual & MMR_SGNL_QUAL,
  1115.  (m.mmr_sgnl_qual & MMR_SGNL_QUAL_ANT) ? "Antenna 1" : "Antenna 0");
  1116. #ifdef DEBUG_SHOW_UNUSED
  1117.   printk(KERN_DEBUG "netw_id_l: %xn", m.mmr_netw_id_l);
  1118. #endif /* DEBUG_SHOW_UNUSED */
  1119. } /* wv_mmc_show */
  1120. #endif /* DEBUG_MMC_SHOW */
  1121. #ifdef DEBUG_I82593_SHOW
  1122. /*------------------------------------------------------------------*/
  1123. /*
  1124.  * Print the formatted status of the i82593's receive unit.
  1125.  */
  1126. static void
  1127. wv_ru_show(device * dev)
  1128. {
  1129.   net_local *lp = (net_local *) dev->priv;
  1130.   printk(KERN_DEBUG "##### wavelan i82593 receiver status: #####n");
  1131.   printk(KERN_DEBUG "ru: rfp %d stop %d", lp->rfp, lp->stop);
  1132.   /*
  1133.    * Not implemented yet...
  1134.    */
  1135.   printk("n");
  1136. } /* wv_ru_show */
  1137. #endif /* DEBUG_I82593_SHOW */
  1138. #ifdef DEBUG_DEVICE_SHOW
  1139. /*------------------------------------------------------------------*/
  1140. /*
  1141.  * Print the formatted status of the WaveLAN PCMCIA device driver.
  1142.  */
  1143. static void
  1144. wv_dev_show(device * dev)
  1145. {
  1146.   printk(KERN_DEBUG "dev:");
  1147.   printk(" trans_start=%ld,", dev->trans_start);
  1148.   printk(" flags=0x%x,", dev->flags);
  1149.   printk("n");
  1150. } /* wv_dev_show */
  1151. /*------------------------------------------------------------------*/
  1152. /*
  1153.  * Print the formatted status of the WaveLAN PCMCIA device driver's
  1154.  * private information.
  1155.  */
  1156. static void
  1157. wv_local_show(device * dev)
  1158. {
  1159.   net_local *lp;
  1160.   lp = (net_local *)dev->priv;
  1161.   printk(KERN_DEBUG "local:");
  1162.   /*
  1163.    * Not implemented yet...
  1164.    */
  1165.   printk("n");
  1166. } /* wv_local_show */
  1167. #endif /* DEBUG_DEVICE_SHOW */
  1168. #if defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO)
  1169. /*------------------------------------------------------------------*/
  1170. /*
  1171.  * Dump packet header (and content if necessary) on the screen
  1172.  */
  1173. static inline void
  1174. wv_packet_info(u_char * p, /* Packet to dump */
  1175.        int length, /* Length of the packet */
  1176.        char * msg1, /* Name of the device */
  1177.        char * msg2) /* Name of the function */
  1178. {
  1179.   int i;
  1180.   int maxi;
  1181.   printk(KERN_DEBUG "%s: %s(): dest %02X:%02X:%02X:%02X:%02X:%02X, length %dn",
  1182.  msg1, msg2, p[0], p[1], p[2], p[3], p[4], p[5], length);
  1183.   printk(KERN_DEBUG "%s: %s(): src %02X:%02X:%02X:%02X:%02X:%02X, type 0x%02X%02Xn",
  1184.  msg1, msg2, p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13]);
  1185. #ifdef DEBUG_PACKET_DUMP
  1186.   printk(KERN_DEBUG "data="");
  1187.   if((maxi = length) > DEBUG_PACKET_DUMP)
  1188.     maxi = DEBUG_PACKET_DUMP;
  1189.   for(i = 14; i < maxi; i++)
  1190.     if(p[i] >= ' ' && p[i] <= '~')
  1191.       printk(" %c", p[i]);
  1192.     else
  1193.       printk("%02X", p[i]);
  1194.   if(maxi < length)
  1195.     printk("..");
  1196.   printk(""n");
  1197.   printk(KERN_DEBUG "n");
  1198. #endif /* DEBUG_PACKET_DUMP */
  1199. }
  1200. #endif /* defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO) */
  1201. /*------------------------------------------------------------------*/
  1202. /*
  1203.  * This is the information which is displayed by the driver at startup
  1204.  * There  is a lot of flag to configure it at your will...
  1205.  */
  1206. static inline void
  1207. wv_init_info(device * dev)
  1208. {
  1209.   ioaddr_t base = dev->base_addr;
  1210.   psa_t psa;
  1211.   int i;
  1212.   /* Read the parameter storage area */
  1213.   psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
  1214. #ifdef DEBUG_PSA_SHOW
  1215.   wv_psa_show(&psa);
  1216. #endif
  1217. #ifdef DEBUG_MMC_SHOW
  1218.   wv_mmc_show(dev);
  1219. #endif
  1220. #ifdef DEBUG_I82593_SHOW
  1221.   wv_ru_show(dev);
  1222. #endif
  1223. #ifdef DEBUG_BASIC_SHOW
  1224.   /* Now, let's go for the basic stuff */
  1225.   printk(KERN_NOTICE "%s: WaveLAN: port %#x, irq %d, hw_addr",
  1226.  dev->name, base, dev->irq);
  1227.   for(i = 0; i < WAVELAN_ADDR_SIZE; i++)
  1228.     printk("%s%02X", (i == 0) ? " " : ":", dev->dev_addr[i]);
  1229.   /* Print current network id */
  1230.   if(psa.psa_nwid_select)
  1231.     printk(", nwid 0x%02X-%02X", psa.psa_nwid[0], psa.psa_nwid[1]);
  1232.   else
  1233.     printk(", nwid off");
  1234.   /* If 2.00 card */
  1235.   if(!(mmc_in(base, mmroff(0, mmr_fee_status)) &
  1236.        (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
  1237.     {
  1238.       unsigned short freq;
  1239.       /* Ask the EEprom to read the frequency from the first area */
  1240.       fee_read(base, 0x00 /* 1st area - frequency... */,
  1241.        &freq, 1);
  1242.       /* Print frequency */
  1243.       printk(", 2.00, %ld", (freq >> 6) + 2400L);
  1244.       /* Hack !!! */
  1245.       if(freq & 0x20)
  1246. printk(".5");
  1247.     }
  1248.   else
  1249.     {
  1250.       printk(", PCMCIA, ");
  1251.       switch (psa.psa_subband)
  1252. {
  1253. case PSA_SUBBAND_915:
  1254.   printk("915");
  1255.   break;
  1256. case PSA_SUBBAND_2425:
  1257.   printk("2425");
  1258.   break;
  1259. case PSA_SUBBAND_2460:
  1260.   printk("2460");
  1261.   break;
  1262. case PSA_SUBBAND_2484:
  1263.   printk("2484");
  1264.   break;
  1265. case PSA_SUBBAND_2430_5:
  1266.   printk("2430.5");
  1267.   break;
  1268. default:
  1269.   printk("unknown");
  1270. }
  1271.     }
  1272.   printk(" MHzn");
  1273. #endif /* DEBUG_BASIC_SHOW */
  1274. #ifdef DEBUG_VERSION_SHOW
  1275.   /* Print version information */
  1276.   printk(KERN_NOTICE "%s", version);
  1277. #endif
  1278. } /* wv_init_info */
  1279. /********************* IOCTL, STATS & RECONFIG *********************/
  1280. /*
  1281.  * We found here routines that are called by Linux on differents
  1282.  * occasions after the configuration and not for transmitting data
  1283.  * These may be called when the user use ifconfig, /proc/net/dev
  1284.  * or wireless extensions
  1285.  */
  1286. /*------------------------------------------------------------------*/
  1287. /*
  1288.  * Get the current ethernet statistics. This may be called with the
  1289.  * card open or closed.
  1290.  * Used when the user read /proc/net/dev
  1291.  */
  1292. static en_stats *
  1293. wavelan_get_stats(device * dev)
  1294. {
  1295. #ifdef DEBUG_IOCTL_TRACE
  1296.   printk(KERN_DEBUG "%s: <>wavelan_get_stats()n", dev->name);
  1297. #endif
  1298.   return(&((net_local *) dev->priv)->stats);
  1299. }
  1300. /*------------------------------------------------------------------*/
  1301. /*
  1302.  * Set or clear the multicast filter for this adaptor.
  1303.  * num_addrs == -1 Promiscuous mode, receive all packets
  1304.  * num_addrs == 0 Normal mode, clear multicast list
  1305.  * num_addrs > 0 Multicast mode, receive normal and MC packets,
  1306.  * and do best-effort filtering.
  1307.  */
  1308. static void
  1309. wavelan_set_multicast_list(device * dev)
  1310. {
  1311.   net_local * lp = (net_local *) dev->priv;
  1312. #ifdef DEBUG_IOCTL_TRACE
  1313.   printk(KERN_DEBUG "%s: ->wavelan_set_multicast_list()n", dev->name);
  1314. #endif
  1315. #ifdef DEBUG_IOCTL_INFO
  1316.   printk(KERN_DEBUG "%s: wavelan_set_multicast_list(): setting Rx mode %02X to %d addresses.n",
  1317.  dev->name, dev->flags, dev->mc_count);
  1318. #endif
  1319.   if(dev->flags & IFF_PROMISC)
  1320.     {
  1321.       /*
  1322.        * Enable promiscuous mode: receive all packets.
  1323.        */
  1324.       if(!lp->promiscuous)
  1325. {
  1326.   lp->promiscuous = 1;
  1327.   lp->allmulticast = 0;
  1328.   lp->mc_count = 0;
  1329.   wv_82593_reconfig(dev);
  1330.   /* Tell the kernel that we are doing a really bad job... */
  1331.   dev->flags |= IFF_PROMISC;
  1332. }
  1333.     }
  1334.   else
  1335.     /* If all multicast addresses
  1336.      * or too much multicast addresses for the hardware filter */
  1337.     if((dev->flags & IFF_ALLMULTI) ||
  1338.        (dev->mc_count > I82593_MAX_MULTICAST_ADDRESSES))
  1339.       {
  1340. /*
  1341.  * Disable promiscuous mode, but active the all multicast mode
  1342.  */
  1343. if(!lp->allmulticast)
  1344.   {
  1345.     lp->promiscuous = 0;
  1346.     lp->allmulticast = 1;
  1347.     lp->mc_count = 0;
  1348.     wv_82593_reconfig(dev);
  1349.     /* Tell the kernel that we are doing a really bad job... */
  1350.     dev->flags |= IFF_ALLMULTI;
  1351.   }
  1352.       }
  1353.     else
  1354.       /* If there is some multicast addresses to send */
  1355.       if(dev->mc_list != (struct dev_mc_list *) NULL)
  1356. {
  1357.   /*
  1358.    * Disable promiscuous mode, but receive all packets
  1359.    * in multicast list
  1360.    */
  1361. #ifdef MULTICAST_AVOID
  1362.   if(lp->promiscuous || lp->allmulticast ||
  1363.      (dev->mc_count != lp->mc_count))
  1364. #endif
  1365.     {
  1366.       lp->promiscuous = 0;
  1367.       lp->allmulticast = 0;
  1368.       lp->mc_count = dev->mc_count;
  1369.       wv_82593_reconfig(dev);
  1370.     }
  1371. }
  1372.       else
  1373. {
  1374.   /*
  1375.    * Switch to normal mode: disable promiscuous mode and 
  1376.    * clear the multicast list.
  1377.    */
  1378.   if(lp->promiscuous || lp->mc_count == 0)
  1379.     {
  1380.       lp->promiscuous = 0;
  1381.       lp->allmulticast = 0;
  1382.       lp->mc_count = 0;
  1383.       wv_82593_reconfig(dev);
  1384.     }
  1385. }
  1386. #ifdef DEBUG_IOCTL_TRACE
  1387.   printk(KERN_DEBUG "%s: <-wavelan_set_multicast_list()n", dev->name);
  1388. #endif
  1389. }
  1390. /*------------------------------------------------------------------*/
  1391. /*
  1392.  * This function doesn't exist...
  1393.  * (Note : it was a nice way to test the reconfigure stuff...)
  1394.  */
  1395. #ifdef SET_MAC_ADDRESS
  1396. static int
  1397. wavelan_set_mac_address(device * dev,
  1398. void * addr)
  1399. {
  1400.   struct sockaddr * mac = addr;
  1401.   /* Copy the address */
  1402.   memcpy(dev->dev_addr, mac->sa_data, WAVELAN_ADDR_SIZE);
  1403.   /* Reconfig the beast */
  1404.   wv_82593_reconfig(dev);
  1405.   return 0;
  1406. }
  1407. #endif /* SET_MAC_ADDRESS */
  1408. #ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */
  1409. /*------------------------------------------------------------------*/
  1410. /*
  1411.  * Frequency setting (for hardware able of it)
  1412.  * It's a bit complicated and you don't really want to look into it...
  1413.  * (called in wavelan_ioctl)
  1414.  */
  1415. static inline int
  1416. wv_set_frequency(u_long base, /* i/o port of the card */
  1417.  iw_freq * frequency)
  1418. {
  1419.   const int BAND_NUM = 10; /* Number of bands */
  1420.   long freq = 0L; /* offset to 2.4 GHz in .5 MHz */
  1421. #ifdef DEBUG_IOCTL_INFO
  1422.   int i;
  1423. #endif
  1424.   /* Setting by frequency */
  1425.   /* Theoritically, you may set any frequency between
  1426.    * the two limits with a 0.5 MHz precision. In practice,
  1427.    * I don't want you to have trouble with local
  1428.    * regulations... */
  1429.   if((frequency->e == 1) &&
  1430.      (frequency->m >= (int) 2.412e8) && (frequency->m <= (int) 2.487e8))
  1431.     {
  1432.       freq = ((frequency->m / 10000) - 24000L) / 5;
  1433.     }
  1434.   /* Setting by channel (same as wfreqsel) */
  1435.   /* Warning : each channel is 22MHz wide, so some of the channels
  1436.    * will interfere... */
  1437.   if((frequency->e == 0) &&
  1438.      (frequency->m >= 0) && (frequency->m < BAND_NUM))
  1439.     {
  1440.       /* Get frequency offset. */
  1441.       freq = channel_bands[frequency->m] >> 1;
  1442.     }
  1443.   /* Verify if the frequency is allowed */
  1444.   if(freq != 0L)
  1445.     {
  1446.       u_short table[10]; /* Authorized frequency table */
  1447.       /* Read the frequency table */
  1448.       fee_read(base, 0x71 /* frequency table */,
  1449.        table, 10);
  1450. #ifdef DEBUG_IOCTL_INFO
  1451.       printk(KERN_DEBUG "Frequency table :");
  1452.       for(i = 0; i < 10; i++)
  1453. {
  1454.   printk(" %04X",
  1455.  table[i]);
  1456. }
  1457.       printk("n");
  1458. #endif
  1459.       /* Look in the table if the frequency is allowed */
  1460.       if(!(table[9 - ((freq - 24) / 16)] &
  1461.    (1 << ((freq - 24) % 16))))
  1462. return -EINVAL; /* not allowed */
  1463.     }
  1464.   else
  1465.     return -EINVAL;
  1466.   /* If we get a usable frequency */
  1467.   if(freq != 0L)
  1468.     {
  1469.       unsigned short area[16];
  1470.       unsigned short dac[2];
  1471.       unsigned short area_verify[16];
  1472.       unsigned short dac_verify[2];
  1473.       /* Corresponding gain (in the power adjust value table)
  1474.        * see AT&T Wavelan Data Manual, REF 407-024689/E, page 3-8
  1475.        * & WCIN062D.DOC, page 6.2.9 */
  1476.       unsigned short power_limit[] = { 40, 80, 120, 160, 0 };
  1477.       int power_band = 0; /* Selected band */
  1478.       unsigned short power_adjust; /* Correct value */
  1479.       /* Search for the gain */
  1480.       power_band = 0;
  1481.       while((freq > power_limit[power_band]) &&
  1482.     (power_limit[++power_band] != 0))
  1483. ;
  1484.       /* Read the first area */
  1485.       fee_read(base, 0x00,
  1486.        area, 16);
  1487.       /* Read the DAC */
  1488.       fee_read(base, 0x60,
  1489.        dac, 2);
  1490.       /* Read the new power adjust value */
  1491.       fee_read(base, 0x6B - (power_band >> 1),
  1492.        &power_adjust, 1);
  1493.       if(power_band & 0x1)
  1494. power_adjust >>= 8;
  1495.       else
  1496. power_adjust &= 0xFF;
  1497. #ifdef DEBUG_IOCTL_INFO
  1498.       printk(KERN_DEBUG "Wavelan EEprom Area 1 :");
  1499.       for(i = 0; i < 16; i++)
  1500. {
  1501.   printk(" %04X",
  1502.  area[i]);
  1503. }
  1504.       printk("n");
  1505.       printk(KERN_DEBUG "Wavelan EEprom DAC : %04X %04Xn",
  1506.      dac[0], dac[1]);
  1507. #endif
  1508.       /* Frequency offset (for info only...) */
  1509.       area[0] = ((freq << 5) & 0xFFE0) | (area[0] & 0x1F);
  1510.       /* Receiver Principle main divider coefficient */
  1511.       area[3] = (freq >> 1) + 2400L - 352L;
  1512.       area[2] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF);
  1513.       /* Transmitter Main divider coefficient */
  1514.       area[13] = (freq >> 1) + 2400L;
  1515.       area[12] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF);
  1516.       /* Others part of the area are flags, bit streams or unused... */
  1517.       /* Set the value in the DAC */
  1518.       dac[1] = ((power_adjust >> 1) & 0x7F) | (dac[1] & 0xFF80);
  1519.       dac[0] = ((power_adjust & 0x1) << 4) | (dac[0] & 0xFFEF);
  1520.       /* Write the first area */
  1521.       fee_write(base, 0x00,
  1522. area, 16);
  1523.       /* Write the DAC */
  1524.       fee_write(base, 0x60,
  1525. dac, 2);
  1526.       /* We now should verify here that the EEprom writting was ok */
  1527.       /* ReRead the first area */
  1528.       fee_read(base, 0x00,
  1529.        area_verify, 16);
  1530.       /* ReRead the DAC */
  1531.       fee_read(base, 0x60,
  1532.        dac_verify, 2);
  1533.       /* Compare */
  1534.       if(memcmp(area, area_verify, 16 * 2) ||
  1535.  memcmp(dac, dac_verify, 2 * 2))
  1536. {
  1537. #ifdef DEBUG_IOCTL_ERROR
  1538.   printk(KERN_INFO "Wavelan: wv_set_frequency : unable to write new frequency to EEprom (?)n");
  1539. #endif
  1540.   return -EOPNOTSUPP;
  1541. }
  1542.       /* We must download the frequency parameters to the
  1543.        * synthetisers (from the EEprom - area 1)
  1544.        * Note : as the EEprom is auto decremented, we set the end
  1545.        * if the area... */
  1546.       mmc_out(base, mmwoff(0, mmw_fee_addr), 0x0F);
  1547.       mmc_out(base, mmwoff(0, mmw_fee_ctrl),
  1548.       MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);
  1549.       /* Wait until the download is finished */
  1550.       fee_wait(base, 100, 100);
  1551.       /* We must now download the power adjust value (gain) to
  1552.        * the synthetisers (from the EEprom - area 7 - DAC) */
  1553.       mmc_out(base, mmwoff(0, mmw_fee_addr), 0x61);
  1554.       mmc_out(base, mmwoff(0, mmw_fee_ctrl),
  1555.       MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);
  1556.       /* Wait until the download is finished */
  1557.       fee_wait(base, 100, 100);
  1558. #ifdef DEBUG_IOCTL_INFO
  1559.       /* Verification of what we have done... */
  1560.       printk(KERN_DEBUG "Wavelan EEprom Area 1 :");
  1561.       for(i = 0; i < 16; i++)
  1562. {
  1563.   printk(" %04X",
  1564.  area_verify[i]);
  1565. }
  1566.       printk("n");
  1567.       printk(KERN_DEBUG "Wavelan EEprom DAC : %04X %04Xn",
  1568.      dac_verify[0], dac_verify[1]);
  1569. #endif
  1570.       return 0;
  1571.     }
  1572.   else
  1573.     return -EINVAL; /* Bah, never get there... */
  1574. }
  1575. /*------------------------------------------------------------------*/
  1576. /*
  1577.  * Give the list of available frequencies
  1578.  */
  1579. static inline int
  1580. wv_frequency_list(u_long base, /* i/o port of the card */
  1581.   iw_freq * list, /* List of frequency to fill */
  1582.   int max) /* Maximum number of frequencies */
  1583. {
  1584.   u_short table[10]; /* Authorized frequency table */
  1585.   long freq = 0L; /* offset to 2.4 GHz in .5 MHz + 12 MHz */
  1586.   int i; /* index in the table */
  1587. #if WIRELESS_EXT > 7
  1588.   const int BAND_NUM = 10; /* Number of bands */
  1589.   int c = 0; /* Channel number */
  1590. #endif /* WIRELESS_EXT */
  1591.   /* Read the frequency table */
  1592.   fee_read(base, 0x71 /* frequency table */,
  1593.    table, 10);
  1594.   /* Look all frequencies */
  1595.   i = 0;
  1596.   for(freq = 0; freq < 150; freq++)
  1597.     /* Look in the table if the frequency is allowed */
  1598.     if(table[9 - (freq / 16)] & (1 << (freq % 16)))
  1599.       {
  1600. #if WIRELESS_EXT > 7
  1601. /* Compute approximate channel number */
  1602. while((((channel_bands[c] >> 1) - 24) < freq) &&
  1603.       (c < BAND_NUM))
  1604.   c++;
  1605. list[i].i = c; /* Set the list index */
  1606. #endif /* WIRELESS_EXT */
  1607. /* put in the list */
  1608. list[i].m = (((freq + 24) * 5) + 24000L) * 10000;
  1609. list[i++].e = 1;
  1610. /* Check number */
  1611. if(i >= max)
  1612.   return(i);
  1613.       }
  1614.   return(i);
  1615. }
  1616. #ifdef WIRELESS_SPY
  1617. /*------------------------------------------------------------------*/
  1618. /*
  1619.  * Gather wireless spy statistics : for each packet, compare the source
  1620.  * address with out list, and if match, get the stats...
  1621.  * Sorry, but this function really need wireless extensions...
  1622.  */
  1623. static inline void
  1624. wl_spy_gather(device * dev,
  1625.       u_char * mac, /* MAC address */
  1626.       u_char * stats) /* Statistics to gather */
  1627. {
  1628.   net_local * lp = (net_local *) dev->priv;
  1629.   int i;
  1630.   /* Look all addresses */
  1631.   for(i = 0; i < lp->spy_number; i++)
  1632.     /* If match */
  1633.     if(!memcmp(mac, lp->spy_address[i], WAVELAN_ADDR_SIZE))
  1634.       {
  1635. /* Update statistics */
  1636. lp->spy_stat[i].qual = stats[2] & MMR_SGNL_QUAL;
  1637. lp->spy_stat[i].level = stats[0] & MMR_SIGNAL_LVL;
  1638. lp->spy_stat[i].noise = stats[1] & MMR_SILENCE_LVL;
  1639. lp->spy_stat[i].updated = 0x7;
  1640.       }
  1641. }
  1642. #endif /* WIRELESS_SPY */
  1643. #ifdef HISTOGRAM
  1644. /*------------------------------------------------------------------*/
  1645. /*
  1646.  * This function calculate an histogram on the signal level.
  1647.  * As the noise is quite constant, it's like doing it on the SNR.
  1648.  * We have defined a set of interval (lp->his_range), and each time
  1649.  * the level goes in that interval, we increment the count (lp->his_sum).
  1650.  * With this histogram you may detect if one wavelan is really weak,
  1651.  * or you may also calculate the mean and standard deviation of the level...
  1652.  */
  1653. static inline void
  1654. wl_his_gather(device * dev,
  1655.       u_char * stats) /* Statistics to gather */
  1656. {
  1657.   net_local * lp = (net_local *) dev->priv;
  1658.   u_char level = stats[0] & MMR_SIGNAL_LVL;
  1659.   int i;
  1660.   /* Find the correct interval */
  1661.   i = 0;
  1662.   while((i < (lp->his_number - 1)) && (level >= lp->his_range[i++]))
  1663.     ;
  1664.   /* Increment interval counter */
  1665.   (lp->his_sum[i])++;
  1666. }
  1667. #endif /* HISTOGRAM */
  1668. /*------------------------------------------------------------------*/
  1669. /*
  1670.  * Perform ioctl : config & info stuff
  1671.  * This is here that are treated the wireless extensions (iwconfig)
  1672.  */
  1673. static int
  1674. wavelan_ioctl(struct net_device * dev, /* Device on wich the ioctl apply */
  1675.       struct ifreq * rq, /* Data passed */
  1676.       int cmd) /* Ioctl number */
  1677. {
  1678.   ioaddr_t base = dev->base_addr;
  1679.   net_local * lp = (net_local *)dev->priv; /* lp is not unused */
  1680.   struct iwreq * wrq = (struct iwreq *) rq;
  1681.   psa_t psa;
  1682.   mm_t m;
  1683.   unsigned long flags;
  1684.   int ret = 0;
  1685. #ifdef DEBUG_IOCTL_TRACE
  1686.   printk(KERN_DEBUG "%s: ->wavelan_ioctl(cmd=0x%X)n", dev->name, cmd);
  1687. #endif
  1688.   /* Disable interrupts & save flags */
  1689.   spin_lock_irqsave (&lp->lock, flags);
  1690.   /* Look what is the request */
  1691.   switch(cmd)
  1692.     {
  1693.       /* --------------- WIRELESS EXTENSIONS --------------- */
  1694.     case SIOCGIWNAME:
  1695.       strcpy(wrq->u.name, "Wavelan");
  1696.       break;
  1697.     case SIOCSIWNWID:
  1698.       /* Set NWID in wavelan */
  1699. #if WIRELESS_EXT > 8
  1700.       if(!wrq->u.nwid.disabled)
  1701. {
  1702.   /* Set NWID in psa */
  1703.   psa.psa_nwid[0] = (wrq->u.nwid.value & 0xFF00) >> 8;
  1704.   psa.psa_nwid[1] = wrq->u.nwid.value & 0xFF;
  1705. #else /* WIRELESS_EXT > 8 */
  1706.       if(wrq->u.nwid.on)
  1707. {
  1708.   /* Set NWID in psa */
  1709.   psa.psa_nwid[0] = (wrq->u.nwid.nwid & 0xFF00) >> 8;
  1710.   psa.psa_nwid[1] = wrq->u.nwid.nwid & 0xFF;
  1711. #endif /* WIRELESS_EXT > 8 */
  1712.   psa.psa_nwid_select = 0x01;
  1713.   psa_write(dev, (char *)psa.psa_nwid - (char *)&psa,
  1714.     (unsigned char *)psa.psa_nwid, 3);
  1715.   /* Set NWID in mmc */
  1716.   m.w.mmw_netw_id_l = psa.psa_nwid[1];
  1717.   m.w.mmw_netw_id_h = psa.psa_nwid[0];
  1718.   mmc_write(base, (char *)&m.w.mmw_netw_id_l - (char *)&m,
  1719.     (unsigned char *)&m.w.mmw_netw_id_l, 2);
  1720.   mmc_out(base, mmwoff(0, mmw_loopt_sel), 0x00);
  1721. }
  1722.       else
  1723. {
  1724.   /* Disable nwid in the psa */
  1725.   psa.psa_nwid_select = 0x00;
  1726.   psa_write(dev, (char *)&psa.psa_nwid_select - (char *)&psa,
  1727.     (unsigned char *)&psa.psa_nwid_select, 1);
  1728.   /* Disable nwid in the mmc (no filtering) */
  1729.   mmc_out(base, mmwoff(0, mmw_loopt_sel), MMW_LOOPT_SEL_DIS_NWID);
  1730. }
  1731.       /* update the Wavelan checksum */
  1732.       update_psa_checksum(dev);
  1733.       break;
  1734.     case SIOCGIWNWID:
  1735.       /* Read the NWID */
  1736.       psa_read(dev, (char *)psa.psa_nwid - (char *)&psa,
  1737.        (unsigned char *)psa.psa_nwid, 3);
  1738. #if WIRELESS_EXT > 8
  1739.       wrq->u.nwid.value = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1];
  1740.       wrq->u.nwid.disabled = !(psa.psa_nwid_select);
  1741.       wrq->u.nwid.fixed = 1; /* Superfluous */
  1742. #else /* WIRELESS_EXT > 8 */
  1743.       wrq->u.nwid.nwid = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1];
  1744.       wrq->u.nwid.on = psa.psa_nwid_select;
  1745. #endif /* WIRELESS_EXT > 8 */
  1746.       break;
  1747.     case SIOCSIWFREQ:
  1748.       /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable) */
  1749.       if(!(mmc_in(base, mmroff(0, mmr_fee_status)) &
  1750.    (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
  1751. ret = wv_set_frequency(base, &(wrq->u.freq));
  1752.       else
  1753. ret = -EOPNOTSUPP;
  1754.       break;
  1755.     case SIOCGIWFREQ:
  1756.       /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable)
  1757.        * (does it work for everybody XXX - especially old cards...) */
  1758.       if(!(mmc_in(base, mmroff(0, mmr_fee_status)) &
  1759.    (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
  1760. {
  1761.   unsigned short freq;
  1762.   /* Ask the EEprom to read the frequency from the first area */
  1763.   fee_read(base, 0x00 /* 1st area - frequency... */,
  1764.    &freq, 1);
  1765.   wrq->u.freq.m = ((freq >> 5) * 5 + 24000L) * 10000;
  1766.   wrq->u.freq.e = 1;
  1767. }
  1768.       else
  1769. {
  1770.   psa_read(dev, (char *)&psa.psa_subband - (char *)&psa,
  1771.    (unsigned char *)&psa.psa_subband, 1);
  1772.   if(psa.psa_subband <= 4)
  1773.     {
  1774.       wrq->u.freq.m = fixed_bands[psa.psa_subband];
  1775.       wrq->u.freq.e = (psa.psa_subband != 0);
  1776.     }
  1777.   else
  1778.     ret = -EOPNOTSUPP;
  1779. }
  1780.       break;
  1781.     case SIOCSIWSENS:
  1782.       /* Set the level threshold */
  1783. #if WIRELESS_EXT > 7
  1784.       /* We should complain loudly if wrq->u.sens.fixed = 0, because we
  1785.        * can't set auto mode... */
  1786.       psa.psa_thr_pre_set = wrq->u.sens.value & 0x3F;
  1787. #else /* WIRELESS_EXT > 7 */
  1788.       psa.psa_thr_pre_set = wrq->u.sensitivity & 0x3F;
  1789. #endif /* WIRELESS_EXT > 7 */
  1790.       psa_write(dev, (char *)&psa.psa_thr_pre_set - (char *)&psa,
  1791.        (unsigned char *)&psa.psa_thr_pre_set, 1);
  1792.       /* update the Wavelan checksum */
  1793.       update_psa_checksum(dev);
  1794.       mmc_out(base, mmwoff(0, mmw_thr_pre_set), psa.psa_thr_pre_set);
  1795.       break;
  1796.     case SIOCGIWSENS:
  1797.       /* Read the level threshold */
  1798.       psa_read(dev, (char *)&psa.psa_thr_pre_set - (char *)&psa,
  1799.        (unsigned char *)&psa.psa_thr_pre_set, 1);
  1800. #if WIRELESS_EXT > 7
  1801.       wrq->u.sens.value = psa.psa_thr_pre_set & 0x3F;
  1802.       wrq->u.sens.fixed = 1;
  1803. #else /* WIRELESS_EXT > 7 */
  1804.       wrq->u.sensitivity = psa.psa_thr_pre_set & 0x3F;
  1805. #endif /* WIRELESS_EXT > 7 */
  1806.       break;
  1807. #if WIRELESS_EXT > 8
  1808.     case SIOCSIWENCODE:
  1809.       /* Set encryption key */
  1810.       if(!mmc_encr(base))
  1811. {
  1812.   ret = -EOPNOTSUPP;
  1813.   break;
  1814. }
  1815.       /* Basic checking... */
  1816.       if(wrq->u.encoding.pointer != (caddr_t) 0)
  1817. {
  1818.   /* Check the size of the key */
  1819.   if(wrq->u.encoding.length != 8)
  1820.     {
  1821.       ret = -EINVAL;
  1822.       break;
  1823.     }
  1824.   /* Copy the key in the driver */
  1825.   if(copy_from_user(psa.psa_encryption_key, wrq->u.encoding.pointer,
  1826.     wrq->u.encoding.length))
  1827.     {
  1828.       ret = -EFAULT;
  1829.       break;
  1830.     }
  1831.   psa.psa_encryption_select = 1;
  1832.   psa_write(dev, (char *) &psa.psa_encryption_select - (char *) &psa,
  1833.     (unsigned char *) &psa.psa_encryption_select, 8+1);
  1834.   mmc_out(base, mmwoff(0, mmw_encr_enable),
  1835.   MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE);
  1836.   mmc_write(base, mmwoff(0, mmw_encr_key),
  1837.     (unsigned char *) &psa.psa_encryption_key, 8);
  1838. }
  1839.       if(wrq->u.encoding.flags & IW_ENCODE_DISABLED)
  1840. { /* disable encryption */
  1841.   psa.psa_encryption_select = 0;
  1842.   psa_write(dev, (char *) &psa.psa_encryption_select - (char *) &psa,
  1843.     (unsigned char *) &psa.psa_encryption_select, 1);
  1844.   mmc_out(base, mmwoff(0, mmw_encr_enable), 0);
  1845. }
  1846.       /* update the Wavelan checksum */
  1847.       update_psa_checksum(dev);
  1848.       break;
  1849.     case SIOCGIWENCODE:
  1850.       /* Read the encryption key */
  1851.       if(!mmc_encr(base))
  1852. {
  1853.   ret = -EOPNOTSUPP;
  1854.   break;
  1855. }
  1856.       /* only super-user can see encryption key */
  1857.       if(!capable(CAP_NET_ADMIN))
  1858. {
  1859.   ret = -EPERM;
  1860.   break;
  1861. }
  1862.       /* Basic checking... */
  1863.       if(wrq->u.encoding.pointer != (caddr_t) 0)
  1864. {
  1865.   psa_read(dev, (char *) &psa.psa_encryption_select - (char *) &psa,
  1866.    (unsigned char *) &psa.psa_encryption_select, 1+8);
  1867.   /* encryption is enabled ? */
  1868.   if(psa.psa_encryption_select)
  1869.     wrq->u.encoding.flags = IW_ENCODE_ENABLED;
  1870.   else
  1871.     wrq->u.encoding.flags = IW_ENCODE_DISABLED;
  1872.   wrq->u.encoding.flags |= mmc_encr(base);
  1873.   /* Copy the key to the user buffer */
  1874.   wrq->u.encoding.length = 8;
  1875.   if(copy_to_user(wrq->u.encoding.pointer, psa.psa_encryption_key, 8))
  1876.     ret = -EFAULT;
  1877. }
  1878.       break;
  1879. #endif /* WIRELESS_EXT > 8 */
  1880. #ifdef WAVELAN_ROAMING_EXT
  1881. #if WIRELESS_EXT > 5
  1882.     case SIOCSIWESSID:
  1883.       /* Check if disable */
  1884.       if(wrq->u.data.flags == 0)
  1885. lp->filter_domains = 0;
  1886.       else
  1887. /* Basic checking... */
  1888. if(wrq->u.data.pointer != (caddr_t) 0)
  1889.   {
  1890.     char essid[IW_ESSID_MAX_SIZE + 1];
  1891.     char * endp;
  1892.     /* Check the size of the string */
  1893.     if(wrq->u.data.length > IW_ESSID_MAX_SIZE + 1)
  1894.       {
  1895. ret = -E2BIG;
  1896. break;
  1897.       }
  1898.     /* Copy the string in the driver */
  1899.     if(copy_from_user(essid, wrq->u.data.pointer, wrq->u.data.length))
  1900.       {
  1901. ret = -EFAULT;
  1902. break;
  1903.       }
  1904.     essid[IW_ESSID_MAX_SIZE] = '';
  1905. #ifdef DEBUG_IOCTL_INFO
  1906.     printk(KERN_DEBUG "SetEssid : ``%s''n", essid);
  1907. #endif /* DEBUG_IOCTL_INFO */
  1908.     /* Convert to a number (note : Wavelan specific) */
  1909.     lp->domain_id = simple_strtoul(essid, &endp, 16);
  1910.     /* Has it worked  ? */
  1911.     if(endp > essid)
  1912.       lp->filter_domains = 1;
  1913.     else
  1914.       {
  1915. lp->filter_domains = 0;
  1916. ret = -EINVAL;
  1917.       }
  1918.   }
  1919.       break;
  1920.     case SIOCGIWESSID:
  1921.       /* Basic checking... */
  1922.       if(wrq->u.data.pointer != (caddr_t) 0)
  1923. {
  1924.   char essid[IW_ESSID_MAX_SIZE + 1];
  1925.   /* Is the domain ID active ? */
  1926.   wrq->u.data.flags = lp->filter_domains;
  1927.   /* Copy Domain ID into a string (Wavelan specific) */
  1928.   /* Sound crazy, be we can't have a snprintf in the kernel !!! */
  1929.   sprintf(essid, "%lX", lp->domain_id);
  1930.   essid[IW_ESSID_MAX_SIZE] = '';
  1931.   /* Set the length */
  1932.   wrq->u.data.length = strlen(essid) + 1;
  1933.   /* Copy structure to the user buffer */
  1934.   if(copy_to_user(wrq->u.data.pointer, essid, wrq->u.data.length))
  1935.     ret = -EFAULT;
  1936. }
  1937.       break;
  1938.     case SIOCSIWAP:
  1939. #ifdef DEBUG_IOCTL_INFO
  1940.       printk(KERN_DEBUG "Set AP to : %02X:%02X:%02X:%02X:%02X:%02Xn",
  1941.      wrq->u.ap_addr.sa_data[0],
  1942.      wrq->u.ap_addr.sa_data[1],
  1943.      wrq->u.ap_addr.sa_data[2],
  1944.      wrq->u.ap_addr.sa_data[3],
  1945.      wrq->u.ap_addr.sa_data[4],
  1946.      wrq->u.ap_addr.sa_data[5]);
  1947. #endif /* DEBUG_IOCTL_INFO */
  1948.       ret = -EOPNOTSUPP; /* Not supported yet */
  1949.       break;
  1950.     case SIOCGIWAP:
  1951.       /* Should get the real McCoy instead of own Ethernet address */
  1952.       memcpy(wrq->u.ap_addr.sa_data, dev->dev_addr, WAVELAN_ADDR_SIZE);
  1953.       wrq->u.ap_addr.sa_family = ARPHRD_ETHER;
  1954.       ret = -EOPNOTSUPP; /* Not supported yet */
  1955.       break;
  1956. #endif /* WIRELESS_EXT > 5 */
  1957. #endif /* WAVELAN_ROAMING_EXT */
  1958. #if WIRELESS_EXT > 8
  1959. #ifdef WAVELAN_ROAMING
  1960.     case SIOCSIWMODE:
  1961.       switch(wrq->u.mode)
  1962. {
  1963. case IW_MODE_ADHOC:
  1964.   if(do_roaming)
  1965.     {
  1966.       wv_roam_cleanup(dev);
  1967.       do_roaming = 0;
  1968.     }
  1969.   break;
  1970. case IW_MODE_INFRA:
  1971.   if(!do_roaming)
  1972.     {
  1973.       wv_roam_init(dev);
  1974.       do_roaming = 1;
  1975.     }
  1976.   break;
  1977. default:
  1978.   ret = -EINVAL;
  1979. }
  1980.       break;
  1981.     case SIOCGIWMODE:
  1982.       if(do_roaming)
  1983. wrq->u.mode = IW_MODE_INFRA;
  1984.       else
  1985. wrq->u.mode = IW_MODE_ADHOC;
  1986.       break;
  1987. #endif /* WAVELAN_ROAMING */
  1988. #endif /* WIRELESS_EXT > 8 */
  1989.     case SIOCGIWRANGE:
  1990.       /* Basic checking... */
  1991.       if(wrq->u.data.pointer != (caddr_t) 0)
  1992. {
  1993.   struct iw_range range;
  1994.   /* Set the length (very important for backward compatibility) */
  1995.   wrq->u.data.length = sizeof(struct iw_range);
  1996.   /* Set all the info we don't care or don't know about to zero */
  1997.   memset(&range, 0, sizeof(range));
  1998.   /* Set the Wireless Extension versions */
  1999.   range.we_version_compiled = WIRELESS_EXT;
  2000.   range.we_version_source = 9; /* Nothing for us in v10 and v11 */
  2001.   /* Set information in the range struct */
  2002.   range.throughput = 1.4 * 1000 * 1000; /* don't argue on this ! */
  2003.   range.min_nwid = 0x0000;
  2004.   range.max_nwid = 0xFFFF;
  2005.   /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable) */
  2006.   if(!(mmc_in(base, mmroff(0, mmr_fee_status)) &
  2007.        (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
  2008.     {
  2009.       range.num_channels = 10;
  2010.       range.num_frequency = wv_frequency_list(base, range.freq,
  2011.       IW_MAX_FREQUENCIES);
  2012.     }
  2013.   else
  2014.     range.num_channels = range.num_frequency = 0;
  2015.   range.sensitivity = 0x3F;
  2016.   range.max_qual.qual = MMR_SGNL_QUAL;
  2017.   range.max_qual.level = MMR_SIGNAL_LVL;
  2018.   range.max_qual.noise = MMR_SILENCE_LVL;
  2019. #if WIRELESS_EXT > 11
  2020.   range.avg_qual.qual = MMR_SGNL_QUAL; /* Always max */
  2021.   /* Need to get better values for those two */
  2022.   range.avg_qual.level = 30;
  2023.   range.avg_qual.noise = 8;
  2024. #endif /* WIRELESS_EXT > 11 */
  2025. #if WIRELESS_EXT > 7
  2026.   range.num_bitrates = 1;
  2027.   range.bitrate[0] = 2000000; /* 2 Mb/s */
  2028. #endif /* WIRELESS_EXT > 7 */
  2029. #if WIRELESS_EXT > 8
  2030.   /* Encryption supported ? */
  2031.   if(mmc_encr(base))
  2032.     {
  2033.       range.encoding_size[0] = 8; /* DES = 64 bits key */
  2034.       range.num_encoding_sizes = 1;
  2035.       range.max_encoding_tokens = 1; /* Only one key possible */
  2036.     }
  2037.   else
  2038.     {
  2039.       range.num_encoding_sizes = 0;
  2040.       range.max_encoding_tokens = 0;
  2041.     }
  2042. #endif /* WIRELESS_EXT > 8 */
  2043.   /* Copy structure to the user buffer */
  2044.   if(copy_to_user(wrq->u.data.pointer, &range,
  2045.   sizeof(struct iw_range)))
  2046.     ret = -EFAULT;
  2047. }
  2048.       break;
  2049.     case SIOCGIWPRIV:
  2050.       /* Basic checking... */
  2051.       if(wrq->u.data.pointer != (caddr_t) 0)
  2052. {
  2053.   struct iw_priv_args priv[] =
  2054.   { /* cmd, set_args, get_args, name */
  2055.     { SIOCSIPQTHR, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setqualthr" },
  2056.     { SIOCGIPQTHR, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getqualthr" },
  2057.     { SIOCSIPHISTO, IW_PRIV_TYPE_BYTE | 16, 0, "sethisto" },
  2058.     { SIOCGIPHISTO, 0,     IW_PRIV_TYPE_INT | 16, "gethisto" },
  2059.     { SIOCSIPROAM, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1 , 0, "setroam" },
  2060.     { SIOCGIPROAM, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getroam" },
  2061.   };
  2062.   /* Set the number of ioctl available */
  2063.   wrq->u.data.length = 6;
  2064.   /* Copy structure to the user buffer */
  2065.   if(copy_to_user(wrq->u.data.pointer, (u_char *) priv,
  2066.        sizeof(priv)))
  2067.     ret = -EFAULT;
  2068. }
  2069.       break;
  2070. #ifdef WIRELESS_SPY
  2071.     case SIOCSIWSPY:
  2072.       /* Set the spy list */
  2073.       /* Check the number of addresses */
  2074.       if(wrq->u.data.length > IW_MAX_SPY)
  2075. {
  2076.   ret = -E2BIG;
  2077.   break;
  2078. }
  2079.       lp->spy_number = wrq->u.data.length;
  2080.       /* If there is some addresses to copy */
  2081.       if(lp->spy_number > 0)
  2082. {
  2083.   struct sockaddr address[IW_MAX_SPY];
  2084.   int i;
  2085.   /* Copy addresses to the driver */
  2086.   if(copy_from_user(address, wrq->u.data.pointer,
  2087.     sizeof(struct sockaddr) * lp->spy_number))
  2088.     {
  2089.       ret = -EFAULT;
  2090.       break;
  2091.     }
  2092.   /* Copy addresses to the lp structure */
  2093.   for(i = 0; i < lp->spy_number; i++)
  2094.     {
  2095.       memcpy(lp->spy_address[i], address[i].sa_data,
  2096.      WAVELAN_ADDR_SIZE);
  2097.     }
  2098.   /* Reset structure... */
  2099.   memset(lp->spy_stat, 0x00, sizeof(iw_qual) * IW_MAX_SPY);
  2100. #ifdef DEBUG_IOCTL_INFO
  2101.   printk(KERN_DEBUG "SetSpy - Set of new addresses is :n");
  2102.   for(i = 0; i < wrq->u.data.length; i++)
  2103.     printk(KERN_DEBUG "%02X:%02X:%02X:%02X:%02X:%02Xn",
  2104.    lp->spy_address[i][0],
  2105.    lp->spy_address[i][1],
  2106.    lp->spy_address[i][2],
  2107.    lp->spy_address[i][3],
  2108.    lp->spy_address[i][4],
  2109.    lp->spy_address[i][5]);
  2110. #endif /* DEBUG_IOCTL_INFO */
  2111. }
  2112.       break;
  2113.     case SIOCGIWSPY:
  2114.       /* Get the spy list and spy stats */
  2115.       /* Set the number of addresses */
  2116.       wrq->u.data.length = lp->spy_number;
  2117.       /* If the user want to have the addresses back... */
  2118.       if((lp->spy_number > 0) && (wrq->u.data.pointer != (caddr_t) 0))
  2119. {
  2120.   struct sockaddr address[IW_MAX_SPY];
  2121.   int i;
  2122.   /* Copy addresses from the lp structure */
  2123.   for(i = 0; i < lp->spy_number; i++)
  2124.     {
  2125.       memcpy(address[i].sa_data, lp->spy_address[i],
  2126.      WAVELAN_ADDR_SIZE);
  2127.       address[i].sa_family = ARPHRD_ETHER;
  2128.     }
  2129.   /* Copy addresses to the user buffer */
  2130.   if(copy_to_user(wrq->u.data.pointer, address,
  2131.        sizeof(struct sockaddr) * lp->spy_number))
  2132.     {
  2133.       ret = -EFAULT;
  2134.       break;
  2135.     }
  2136.   /* Copy stats to the user buffer (just after) */
  2137.   if(copy_to_user(wrq->u.data.pointer +
  2138.        (sizeof(struct sockaddr) * lp->spy_number),
  2139.        lp->spy_stat, sizeof(iw_qual) * lp->spy_number))
  2140.     {
  2141.       ret = -EFAULT;
  2142.       break;
  2143.     }
  2144.   /* Reset updated flags */
  2145.   for(i = 0; i < lp->spy_number; i++)
  2146.     lp->spy_stat[i].updated = 0x0;
  2147. } /* if(pointer != NULL) */