Bug
        
                          [В начало]
Ошибка # 112
Показать/спрятать трассу ошибок|            Error trace     
         /*Is true unsafe:*/   /*Number of usage points:2*/ /*Number of usages :2*/ /*Two examples:*/ /*_____________________*/ /*rtnl_lock[1]*/         {           return ;         }        {         /*_____________________*/  396     struct sk_buff *ldvarg1;   397     struct ifreq *ldvarg4;   398     int ldvarg3;   399     void *ldvarg0;   400     int ldvarg2;   401     unsigned long ldvarg11;   402     loff_t *ldvarg7;   403     const char *ldvarg12;   404     int ldvarg5;   405     long long ldvarg6;   406     unsigned long ldvarg8;   407     loff_t *ldvarg10;   408     char *ldvarg9;   409     struct ifreq *ldvarg17;   410     struct sk_buff *ldvarg14;   411     void *ldvarg13;   412     int ldvarg16;   413     int ldvarg15;   414     unsigned long ldvarg24;   415     int ldvarg18;   416     loff_t *ldvarg20;   417     loff_t *ldvarg23;   418     unsigned long ldvarg21;   419     const char *ldvarg25;   420     char *ldvarg22;   421     long long ldvarg19;   422     long long ldvarg27;   423     int ldvarg26;   424     unsigned long ldvarg32;   425     loff_t *ldvarg31;   426     const char *ldvarg33;   427     char *ldvarg30;   428     unsigned long ldvarg29;   429     loff_t *ldvarg28;   430     unsigned long ldvarg37;   431     long long ldvarg35;   432     loff_t *ldvarg36;   433     char *ldvarg38;   434     int ldvarg34;   435     void *ldvarg39;   436     int ldvarg41;   437     struct ifreq *ldvarg43;   438     int ldvarg42;   439     struct sk_buff *ldvarg40;   440     unsigned char *ldvarg45;   441     const struct sk_buff *ldvarg44;   442     const struct pci_device_id *ldvarg47;   443     struct pm_message ldvarg46;   444     int ldvarg48;   445     unsigned long ldvarg51;   446     char *ldvarg52;   447     long long ldvarg49;   448     loff_t *ldvarg50;   449     const char *ldvarg60;   450     unsigned long ldvarg59;   451     unsigned long ldvarg56;   452     char *ldvarg57;   453     long long ldvarg54;   454     loff_t *ldvarg58;   455     int ldvarg53;   456     loff_t *ldvarg55;   457     char *ldvarg65;   458     loff_t *ldvarg63;   459     int ldvarg61;   460     unsigned long ldvarg64;   461     long long ldvarg62;   462     const char *ldvarg73;   463     char *ldvarg70;   464     long long ldvarg67;   465     loff_t *ldvarg71;   466     loff_t *ldvarg68;   467     unsigned long ldvarg72;   468     unsigned long ldvarg69;   469     int ldvarg66;   470     int tmp;   471     int tmp___0;   472     int tmp___1;   473     int tmp___2;   474     int tmp___3;   475     int tmp___4;   476     int tmp___5;   477     int tmp___6;   478     int tmp___7;   479     int tmp___8;   480     int tmp___9;   481     int tmp___10;   482     int tmp___11;   483     int tmp___12;   484     int tmp___13;   485     int tmp___14;   486     int tmp___15;   487     int tmp___16;   488     int tmp___17;   489     int tmp___18;   490     int tmp___19;   491     int tmp___20;   492     int tmp___21;   493     int tmp___22;   494     int tmp___23;   495     int tmp___24;   496     int tmp___25;   497     int tmp___26;   498     int tmp___27;   499     int tmp___28;   500     int tmp___29;   501     int tmp___30;   502     int tmp___31;   503     int tmp___32;   504     int tmp___33;   395     ldv_initialize() { /* Function call is skipped due to function is undefined */}   472     ldv_state_variable_11 = 0;   473     ldv_state_variable_7 = 0;   474     ldv_state_variable_2 = 0;   476     ldv_state_variable_1 = 1;   477     ref_cnt = 0;   478     ldv_state_variable_0 = 1;   479     ldv_state_variable_13 = 0;   480     ldv_state_variable_6 = 0;   481     ldv_state_variable_3 = 0;   482     ldv_state_variable_9 = 0;   483     ldv_state_variable_12 = 0;   484     ldv_state_variable_14 = 0;   485     ldv_state_variable_15 = 0;   486     ldv_state_variable_8 = 0;   487     ldv_state_variable_4 = 0;   488     ldv_state_variable_10 = 0;   489     ldv_state_variable_5 = 0;   490     ldv_57264:;   491     tmp = __VERIFIER_nondet_int() { /* Function call is skipped due to function is undefined */}   491     switch (tmp);   766     tmp___8 = __VERIFIER_nondet_int() { /* Function call is skipped due to function is undefined */}   766     switch (tmp___8);           { /*Change states for locks rtnl_lock*/   342       rtnl_lock() { /* Function call is skipped due to function is undefined */}           }          {  7755       struct airo_info *local;  7756       int tmp;  7757       int tmp___0;  7755       local = (struct airo_info *)(dev->__annonCompField102.ml_priv);             {   310         return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;             } 7759       tmp = down_trylock(&(local->sem)) { /* Function call is skipped due to function is undefined */}             {  7700         struct StatusRid status_rid;  7701         struct StatsRid stats_rid;  7702         struct CapabilityRid cap_rid;  7703         __le32 *vals;  7704         int tmp;  7703         vals = (__le32 *)(&(stats_rid.vals));               { 117 Ignored inline assembler code   119           return ;;               }              {  1858           int tmp;                 {               } 4134             unsigned short status;  4135             int rc;  4136             int tmp;  4137             struct __anonstruct_Cmd_476 cmd;  4138             struct __anonstruct_Resp_477 rsp;  4139             unsigned short tmp___0;  4140             int tmp___1;  4141             int tmp___2;  4142             int _min1;  4143             int _min2;  4144             int tmp___3;  4134             rc = 0;                   {   310               return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                   }                  {  4114               struct __anonstruct_Cmd_476 cmd;  4115               struct __anonstruct_Resp_477 rsp;  4116               unsigned short status;  4118               __memset((void *)(&cmd), 0, 8UL) { /* Function call is skipped due to function is undefined */}  4119               cmd.cmd = accmd;  4120               cmd.parm0 = rid;                     {                   } 3949                 int max_tries;  3950                 unsigned short tmp;  3951                 unsigned short tmp___0;  3952                 int tmp___1;  3953                 int tmp___2;  3954                 unsigned short tmp___3;  3955                 unsigned short tmp___4;  3956                 unsigned short tmp___5;  3949                 max_tries = 600000;                       {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       } 3954                 int __CPAchecker_TMP_0 = (int)(pCmd->parm0);                       {  3550                   int tmp;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3554                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         { 316 Ignored inline assembler code   317                     return ;;                         } 3555                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                   -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                         {                       }316 Ignored inline assembler code   317                     return ;;                         } 3955                 int __CPAchecker_TMP_1 = (int)(pCmd->parm1);                       {  3550                   int tmp;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3554                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         { 316 Ignored inline assembler code   317                     return ;;                         } 3555                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                   -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                         {                       }316 Ignored inline assembler code   317                     return ;;                         } 3956                 int __CPAchecker_TMP_2 = (int)(pCmd->parm2);                       {  3550                   int tmp;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3554                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         { 316 Ignored inline assembler code   317                     return ;;                         } 3555                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                   -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                         {                       }316 Ignored inline assembler code   317                     return ;;                         } 3957                 int __CPAchecker_TMP_3 = (int)(pCmd->cmd);                       {  3550                   int tmp;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3554                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         { 316 Ignored inline assembler code   317                     return ;;                         } 3555                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                   -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                         {                       }316 Ignored inline assembler code   317                     return ;;                         } 3959                 goto ldv_55699;  3959                 tmp___2 = max_tries;  3959                 max_tries = max_tries - 1;                       {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       } 3964                 goto ldv_55700;                       {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       }                      {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       }                      {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       }                      {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       } 3980                 int __CPAchecker_TMP_6 = (int)(pRsp->status);                       {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       }                      {                     } 3550                   int tmp;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3554                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         { 316 Ignored inline assembler code   317                     return ;;                         } 3555                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                   -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                         {                       }316 Ignored inline assembler code   317                     return ;;                         } 4165             status = (u16 )tmp___1;                   {  4001               int timeout;  4002               int max_tries;  4003               int status;  4004               unsigned short tmp;  4005               int tmp___0;  4006               int tmp___1;  4001               timeout = 50;  4002               max_tries = 3;                     {  3550                 int tmp;                       {   310                   return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                       } 3554                 unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                       { 316 Ignored inline assembler code   317                   return ;;                       } 3555                 unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                 -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                       {                     }316 Ignored inline assembler code   317                   return ;;                       }                    {  3550                 int tmp;                       {   310                   return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                       } 3554                 unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                       { 316 Ignored inline assembler code   317                   return ;;                       } 3555                 unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                 -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                       {                     }316 Ignored inline assembler code   317                   return ;;                       } 4006               ldv_55711:;                     {  3561                 unsigned short rc;  3562                 int tmp;  3563                 unsigned char tmp___0;  3564                 unsigned char tmp___1;                       {   310                   return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                       } 3567                 unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                       {   318                   unsigned char value;   316                   Ignored inline assembler code  316                   return value;;                       } 3567                 rc = (unsigned short)tmp___0;  3568                 unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                       {   318                   unsigned char value;   316                   Ignored inline assembler code  316                   return value;;                       } 3568                 rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                     } 4007               status = (int)tmp;                   } 4176             _min1 = len;  4176             _min2 = (int)(*((__le16 *)pBuf));  4176             int __CPAchecker_TMP_1;  4176             __CPAchecker_TMP_1 = _min2;  4176             len = __CPAchecker_TMP_1 + -2;  4188             done:;                 }              {  1848           int tmp;                 {               } 4134             unsigned short status;  4135             int rc;  4136             int tmp;  4137             struct __anonstruct_Cmd_476 cmd;  4138             struct __anonstruct_Resp_477 rsp;  4139             unsigned short tmp___0;  4140             int tmp___1;  4141             int tmp___2;  4142             int _min1;  4143             int _min2;  4144             int tmp___3;  4134             rc = 0;                   {   310               return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                   }                  {  4114               struct __anonstruct_Cmd_476 cmd;  4115               struct __anonstruct_Resp_477 rsp;  4116               unsigned short status;  4118               __memset((void *)(&cmd), 0, 8UL) { /* Function call is skipped due to function is undefined */}  4119               cmd.cmd = accmd;  4120               cmd.parm0 = rid;                     {                   } 3949                 int max_tries;  3950                 unsigned short tmp;  3951                 unsigned short tmp___0;  3952                 int tmp___1;  3953                 int tmp___2;  3954                 unsigned short tmp___3;  3955                 unsigned short tmp___4;  3956                 unsigned short tmp___5;  3949                 max_tries = 600000;                       {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       } 3954                 int __CPAchecker_TMP_0 = (int)(pCmd->parm0);                       {  3550                   int tmp;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3554                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         { 316 Ignored inline assembler code   317                     return ;;                         } 3555                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                   -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                         {                       }316 Ignored inline assembler code   317                     return ;;                         } 3955                 int __CPAchecker_TMP_1 = (int)(pCmd->parm1);                       {  3550                   int tmp;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3554                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         { 316 Ignored inline assembler code   317                     return ;;                         } 3555                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                   -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                         {                       }316 Ignored inline assembler code   317                     return ;;                         } 3956                 int __CPAchecker_TMP_2 = (int)(pCmd->parm2);                       {  3550                   int tmp;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3554                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         { 316 Ignored inline assembler code   317                     return ;;                         } 3555                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                   -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                         {                       }316 Ignored inline assembler code   317                     return ;;                         } 3957                 int __CPAchecker_TMP_3 = (int)(pCmd->cmd);                       {  3550                   int tmp;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3554                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         { 316 Ignored inline assembler code   317                     return ;;                         } 3555                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                   -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                         {                       }316 Ignored inline assembler code   317                     return ;;                         } 3959                 goto ldv_55699;  3959                 tmp___2 = max_tries;  3959                 max_tries = max_tries - 1;                       {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       } 3964                 goto ldv_55700;                       {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       }                      {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       }                      {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       }                      {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       } 3980                 int __CPAchecker_TMP_6 = (int)(pRsp->status);                       {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       }                      {                     } 3550                   int tmp;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3554                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         { 316 Ignored inline assembler code   317                     return ;;                         } 3555                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                   -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                         {                       }316 Ignored inline assembler code   317                     return ;;                         } 4165             status = (u16 )tmp___1;                   {  4001               int timeout;  4002               int max_tries;  4003               int status;  4004               unsigned short tmp;  4005               int tmp___0;  4006               int tmp___1;  4001               timeout = 50;  4002               max_tries = 3;                     {  3550                 int tmp;                       {   310                   return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                       } 3554                 unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                       { 316 Ignored inline assembler code   317                   return ;;                       } 3555                 unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                 -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                       {                     }316 Ignored inline assembler code   317                   return ;;                       }                    {  3550                 int tmp;                       {   310                   return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                       } 3554                 unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                       { 316 Ignored inline assembler code   317                   return ;;                       } 3555                 unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                 -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                       {                     }316 Ignored inline assembler code   317                   return ;;                       } 4006               ldv_55711:;                     {  3561                 unsigned short rc;  3562                 int tmp;  3563                 unsigned char tmp___0;  3564                 unsigned char tmp___1;                       {   310                   return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                       } 3567                 unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                       {   318                   unsigned char value;   316                   Ignored inline assembler code  316                   return value;;                       } 3567                 rc = (unsigned short)tmp___0;  3568                 unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                       {   318                   unsigned char value;   316                   Ignored inline assembler code  316                   return value;;                       } 3568                 rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                     } 4007               status = (int)tmp;                   } 4176             _min1 = len;  4176             _min2 = (int)(*((__le16 *)pBuf));  4176             int __CPAchecker_TMP_1;  4176             __CPAchecker_TMP_1 = _min2;  4176             len = __CPAchecker_TMP_1 + -2;  4188             done:;                 }              {  1863           int tmp;                 {               } 4134             unsigned short status;  4135             int rc;  4136             int tmp;  4137             struct __anonstruct_Cmd_476 cmd;  4138             struct __anonstruct_Resp_477 rsp;  4139             unsigned short tmp___0;  4140             int tmp___1;  4141             int tmp___2;  4142             int _min1;  4143             int _min2;  4144             int tmp___3;  4134             rc = 0;                   {   310               return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                   }                  {  4114               struct __anonstruct_Cmd_476 cmd;  4115               struct __anonstruct_Resp_477 rsp;  4116               unsigned short status;  4118               __memset((void *)(&cmd), 0, 8UL) { /* Function call is skipped due to function is undefined */}  4119               cmd.cmd = accmd;  4120               cmd.parm0 = rid;                     {                   } 3949                 int max_tries;  3950                 unsigned short tmp;  3951                 unsigned short tmp___0;  3952                 int tmp___1;  3953                 int tmp___2;  3954                 unsigned short tmp___3;  3955                 unsigned short tmp___4;  3956                 unsigned short tmp___5;  3949                 max_tries = 600000;                       {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       } 3954                 int __CPAchecker_TMP_0 = (int)(pCmd->parm0);                       {  3550                   int tmp;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3554                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         { 316 Ignored inline assembler code   317                     return ;;                         } 3555                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                   -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                         {                       }316 Ignored inline assembler code   317                     return ;;                         } 3955                 int __CPAchecker_TMP_1 = (int)(pCmd->parm1);                       {  3550                   int tmp;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3554                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         { 316 Ignored inline assembler code   317                     return ;;                         } 3555                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                   -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                         {                       }316 Ignored inline assembler code   317                     return ;;                         } 3956                 int __CPAchecker_TMP_2 = (int)(pCmd->parm2);                       {  3550                   int tmp;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3554                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         { 316 Ignored inline assembler code   317                     return ;;                         } 3555                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                   -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                         {                       }316 Ignored inline assembler code   317                     return ;;                         } 3957                 int __CPAchecker_TMP_3 = (int)(pCmd->cmd);                       {  3550                   int tmp;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3554                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         { 316 Ignored inline assembler code   317                     return ;;                         } 3555                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                   -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                         {                       }316 Ignored inline assembler code   317                     return ;;                         } 3959                 goto ldv_55699;  3959                 tmp___2 = max_tries;  3959                 max_tries = max_tries - 1;                       {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       } 3964                 goto ldv_55700;                       {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       }                      {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       }                      {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       }                      {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       } 3980                 int __CPAchecker_TMP_6 = (int)(pRsp->status);                       {  3561                   unsigned short rc;  3562                   int tmp;  3563                   unsigned char tmp___0;  3564                   unsigned char tmp___1;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3567                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3567                   rc = (unsigned short)tmp___0;  3568                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                         {   318                     unsigned char value;   316                     Ignored inline assembler code  316                     return value;;                         } 3568                   rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                       }                      {                     } 3550                   int tmp;                         {   310                     return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                         } 3554                   unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                         { 316 Ignored inline assembler code   317                     return ;;                         } 3555                   unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                   -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                         {                       }316 Ignored inline assembler code   317                     return ;;                         } 4165             status = (u16 )tmp___1;                   {  4001               int timeout;  4002               int max_tries;  4003               int status;  4004               unsigned short tmp;  4005               int tmp___0;  4006               int tmp___1;  4001               timeout = 50;  4002               max_tries = 3;                     {  3550                 int tmp;                       {   310                   return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                       } 3554                 unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                       { 316 Ignored inline assembler code   317                   return ;;                       } 3555                 unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                 -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                       {                     }316 Ignored inline assembler code   317                   return ;;                       }                    {  3550                 int tmp;                       {   310                   return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                       } 3554                 unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                       { 316 Ignored inline assembler code   317                   return ;;                       } 3555                 unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555                 -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                       {                     }316 Ignored inline assembler code   317                   return ;;                       } 4006               ldv_55711:;                     {  3561                 unsigned short rc;  3562                 int tmp;  3563                 unsigned char tmp___0;  3564                 unsigned char tmp___1;                       {   310                   return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                       } 3567                 unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                       {   318                   unsigned char value;   316                   Ignored inline assembler code  316                   return value;;                       } 3567                 rc = (unsigned short)tmp___0;  3568                 unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                       {   318                   unsigned char value;   316                   Ignored inline assembler code  316                   return value;;                       } 3568                 rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                     } 4007               status = (int)tmp;                   } 4176             _min1 = len;  4176             _min2 = (int)(*((__le16 *)pBuf));  4176             int __CPAchecker_TMP_1;  4176             __CPAchecker_TMP_1 = _min2;  4176             len = __CPAchecker_TMP_1 + -2;  4188             done:;                 } 7714         up(&(local->sem)) { /* Function call is skipped due to function is undefined */}  7717         local->wstats.status = status_rid.mode;  7720         unsigned long __CPAchecker_TMP_0 = (unsigned long)(local->rssi);  7725         local->wstats.qual.qual = (__u8 )(status_rid.normalizedSignalStrength);               return ;;             }            return ;;           }          return ;;         }/*Without locks*/ /*Failure in refinement*/         {           return ;         }        {       396     struct sk_buff *ldvarg1;   397     struct ifreq *ldvarg4;   398     int ldvarg3;   399     void *ldvarg0;   400     int ldvarg2;   401     unsigned long ldvarg11;   402     loff_t *ldvarg7;   403     const char *ldvarg12;   404     int ldvarg5;   405     long long ldvarg6;   406     unsigned long ldvarg8;   407     loff_t *ldvarg10;   408     char *ldvarg9;   409     struct ifreq *ldvarg17;   410     struct sk_buff *ldvarg14;   411     void *ldvarg13;   412     int ldvarg16;   413     int ldvarg15;   414     unsigned long ldvarg24;   415     int ldvarg18;   416     loff_t *ldvarg20;   417     loff_t *ldvarg23;   418     unsigned long ldvarg21;   419     const char *ldvarg25;   420     char *ldvarg22;   421     long long ldvarg19;   422     long long ldvarg27;   423     int ldvarg26;   424     unsigned long ldvarg32;   425     loff_t *ldvarg31;   426     const char *ldvarg33;   427     char *ldvarg30;   428     unsigned long ldvarg29;   429     loff_t *ldvarg28;   430     unsigned long ldvarg37;   431     long long ldvarg35;   432     loff_t *ldvarg36;   433     char *ldvarg38;   434     int ldvarg34;   435     void *ldvarg39;   436     int ldvarg41;   437     struct ifreq *ldvarg43;   438     int ldvarg42;   439     struct sk_buff *ldvarg40;   440     unsigned char *ldvarg45;   441     const struct sk_buff *ldvarg44;   442     const struct pci_device_id *ldvarg47;   443     struct pm_message ldvarg46;   444     int ldvarg48;   445     unsigned long ldvarg51;   446     char *ldvarg52;   447     long long ldvarg49;   448     loff_t *ldvarg50;   449     const char *ldvarg60;   450     unsigned long ldvarg59;   451     unsigned long ldvarg56;   452     char *ldvarg57;   453     long long ldvarg54;   454     loff_t *ldvarg58;   455     int ldvarg53;   456     loff_t *ldvarg55;   457     char *ldvarg65;   458     loff_t *ldvarg63;   459     int ldvarg61;   460     unsigned long ldvarg64;   461     long long ldvarg62;   462     const char *ldvarg73;   463     char *ldvarg70;   464     long long ldvarg67;   465     loff_t *ldvarg71;   466     loff_t *ldvarg68;   467     unsigned long ldvarg72;   468     unsigned long ldvarg69;   469     int ldvarg66;   470     int tmp;   471     int tmp___0;   472     int tmp___1;   473     int tmp___2;   474     int tmp___3;   475     int tmp___4;   476     int tmp___5;   477     int tmp___6;   478     int tmp___7;   479     int tmp___8;   480     int tmp___9;   481     int tmp___10;   482     int tmp___11;   483     int tmp___12;   484     int tmp___13;   485     int tmp___14;   486     int tmp___15;   487     int tmp___16;   488     int tmp___17;   489     int tmp___18;   490     int tmp___19;   491     int tmp___20;   492     int tmp___21;   493     int tmp___22;   494     int tmp___23;   495     int tmp___24;   496     int tmp___25;   497     int tmp___26;   498     int tmp___27;   499     int tmp___28;   500     int tmp___29;   501     int tmp___30;   502     int tmp___31;   503     int tmp___32;   504     int tmp___33;   395     ldv_initialize() { /* Function call is skipped due to function is undefined */}   472     ldv_state_variable_11 = 0;   473     ldv_state_variable_7 = 0;   474     ldv_state_variable_2 = 0;   476     ldv_state_variable_1 = 1;   477     ref_cnt = 0;   478     ldv_state_variable_0 = 1;   479     ldv_state_variable_13 = 0;   480     ldv_state_variable_6 = 0;   481     ldv_state_variable_3 = 0;   482     ldv_state_variable_9 = 0;   483     ldv_state_variable_12 = 0;   484     ldv_state_variable_14 = 0;   485     ldv_state_variable_15 = 0;   486     ldv_state_variable_8 = 0;   487     ldv_state_variable_4 = 0;   488     ldv_state_variable_10 = 0;   489     ldv_state_variable_5 = 0;   490     ldv_57264:;   491     tmp = __VERIFIER_nondet_int() { /* Function call is skipped due to function is undefined */}   491     switch (tmp);           {   216       int tmp;   215       tmp = __VERIFIER_nondet_int() { /* Function call is skipped due to function is undefined */}   215       switch (tmp);             {   285         enum irqreturn irq_retval;   286         int tmp;   287         int tmp___0;   285         tmp = __VERIFIER_nondet_int() { /* Function call is skipped due to function is undefined */}   285         irq_retval = (irqreturn_t )tmp;   288         tmp___0 = __VERIFIER_nondet_int() { /* Function call is skipped due to function is undefined */}   288         switch (tmp___0);   291         LDV_IN_INTERRUPT = 2;               {  3484           struct net_device *dev;  3485           unsigned short status;  3486           unsigned short savedInterrupts;  3487           struct airo_info *ai;  3488           int handled;  3489           _Bool tmp;  3490           int tmp___0;  3484           dev = (struct net_device *)dev_id;  3485           savedInterrupts = 0U;  3486           ai = (struct airo_info *)(dev->__annonCompField102.ml_priv);  3487           handled = 0;                 {  3310             int tmp;                   {   310               return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                   } 3310             return tmp != 0;;                 } 3489           tmp___0 = 0;  3494           ldv_55602:;                 {  3561             unsigned short rc;  3562             int tmp;  3563             unsigned char tmp___0;  3564             unsigned char tmp___1;                   {   310               return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                   } 3567             unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                   {   318               unsigned char value;   316               Ignored inline assembler code  316               return value;;                   } 3567             rc = (unsigned short)tmp___0;  3568             unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                   {   318               unsigned char value;   316               Ignored inline assembler code  316               return value;;                   } 3568             rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                 } 3497           handled = 1;                 {  3561             unsigned short rc;  3562             int tmp;  3563             unsigned char tmp___0;  3564             unsigned char tmp___1;                   {   310               return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                   } 3567             unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                   {   318               unsigned char value;   316               Ignored inline assembler code  316               return value;;                   } 3567             rc = (unsigned short)tmp___0;  3568             unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);                   {   318               unsigned char value;   316               Ignored inline assembler code  316               return value;;                   } 3568             rc = (((int)((unsigned short)tmp___1)) << 8U) + ((int)rc);                 }                {  3550             int tmp;                   {   310               return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                   } 3554             unsigned int __CPAchecker_TMP_1 = (unsigned int)(ai->dev->base_addr);                   { 316 Ignored inline assembler code   317               return ;;                   } 3555             unsigned int __CPAchecker_TMP_2 = (unsigned int)(ai->dev->base_addr);  3555             -outb((int)((unsigned char)(((int)val) >> 8)), (int)((__CPAchecker_TMP_2 + ((unsigned int)reg)) + 1U))                   {                 }316 Ignored inline assembler code   317               return ;;                   }                {  3289             struct sk_buff *skb;  3290             unsigned short fc;  3291             unsigned short v;  3292             __le16 *buffer;  3293             __le16 tmpbuf[4U];  3294             unsigned short len;  3295             unsigned short hdrlen;  3296             unsigned short gap;  3297             unsigned short fid;  3298             struct rx_hdr hdr;  3299             int success;  3300             int tmp;  3301             int tmp___0;  3302             int tmp___1;  3303             int tmp___2;  3304             int tmp___3;  3305             unsigned char *tmp___4;  3306             struct MICBuffer micbuf;  3307             unsigned short tmp___5;  3308             int tmp___6;  3309             int tmp___7;  3310             char *sa;  3311             struct iw_quality wstats;  3312             int tmp___8;  3313             int tmp___9;  3289             skb = (struct sk_buff *)0;  3291             hdrlen = 0U;  3293             success = 0;                   {   310               return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                   }                  {   310               return ((int)(((unsigned long)(*(addr + ((unsigned long)(nr >> 6))))) >> (((int)nr) & 63))) & 1;;                   }                  {  3712               struct __anonstruct_RxFid_490 rxd;  3713               struct sk_buff *skb;  3714               unsigned short len;  3715               unsigned short hdrlen;  3716               unsigned short fc;  3717               struct rx_hdr hdr;  3718               unsigned short gap;  3719               u16 *buffer;  3720               char *ptr;  3721               int tmp;  3722               unsigned char *tmp___0;  3723               char *sa;  3724               struct iw_quality wstats;  3713               skb = (struct sk_buff *)0;  3714               hdrlen = 0U;  3719               ptr = (((ai->rxfids)[0]).virtual_host_addr) + 4UL;                     {   219                 __memcpy(dst, (const void *)src, count) { /* Function call is skipped due to function is undefined */}   220                 return ;;                     } 3722               __memcpy((void *)(&hdr), (const void *)ptr, 16UL) { /* Function call is skipped due to function is undefined */}  3723               ptr = ptr + 16UL;  3727               unsigned long __CPAchecker_TMP_0 = (unsigned long)(ai->wifidev);  3729               len = hdr.len;                     {     9                 unsigned short tmp;                       {    65                   return (__u16 )(*p);;                       }    9                 return tmp;;                     } 3738               hdrlen = (u16 )tmp;                     {  2370                 struct sk_buff *tmp;                       {  2356                   struct sk_buff *tmp;  2357                   tmp = __netdev_alloc_skb(dev, length, 34078752U) { /* Function call is skipped due to function is undefined */}  2357                   return tmp;;                       } 2370                 return tmp;;                     } 3745               tmp___0 = skb_put(skb, (unsigned int)(((int)len) + ((int)hdrlen))) { /* Function call is skipped due to function is undefined */}  3745               buffer = (u16 *)tmp___0;  3746               __memcpy((void *)buffer, (const void *)ptr, (size_t )hdrlen) { /* Function call is skipped due to function is undefined */}  3747               ptr = ptr + ((unsigned long)hdrlen);                     {     9                 unsigned short tmp;                       {    65                   return (__u16 )(*p);;                       }    9                 return tmp;;                     } 3751               ptr = ptr + 2UL;  3759               __memcpy(((void *)buffer) + ((unsigned long)hdrlen), (const void *)ptr, (size_t )len) { /* Function call is skipped due to function is undefined */}  3760               ptr = ptr + ((unsigned long)len);  3766               sa = ((char *)buffer) + 10UL;  3767               wstats.qual = (hdr.rssi)[0];  3768               unsigned long __CPAchecker_TMP_1 = (unsigned long)(ai->rssi);  3771               wstats.level = (__u8 )((((int)((hdr.rssi)[1])) + 321) / 2);  3772               wstats.noise = ai->wstats.qual.noise;  3773               wstats.updated = 11U;  3777               wireless_spy_update(ai->dev, (unsigned char *)sa, &wstats) { /* Function call is skipped due to function is undefined */}                     return ;;                   }                  return ;;                 }                return ;;               }              return ;;             }            return ;;           }          return ;;         } |              Source code             1 /*======================================================================
    2 
    3     Aironet driver for 4500 and 4800 series cards
    4 
    5     This code is released under both the GPL version 2 and BSD licenses.
    6     Either license may be used.  The respective licenses are found at
    7     the end of this file.
    8 
    9     This code was developed by Benjamin Reed <breed@users.sourceforge.net>
   10     including portions of which come from the Aironet PC4500
   11     Developer's Reference Manual and used with permission.  Copyright
   12     (C) 1999 Benjamin Reed.  All Rights Reserved.  Permission to use
   13     code in the Developer's manual was granted for this driver by
   14     Aironet.  Major code contributions were received from Javier Achirica
   15     <achirica@users.sourceforge.net> and Jean Tourrilhes <jt@hpl.hp.com>.
   16     Code was also integrated from the Cisco Aironet driver for Linux.
   17     Support for MPI350 cards was added by Fabrice Bellet
   18     <fabrice@bellet.info>.
   19 
   20 ======================================================================*/
   21 
   22 #include <linux/err.h>
   23 #include <linux/init.h>
   24 
   25 #include <linux/kernel.h>
   26 #include <linux/module.h>
   27 #include <linux/proc_fs.h>
   28 
   29 #include <linux/sched.h>
   30 #include <linux/ptrace.h>
   31 #include <linux/slab.h>
   32 #include <linux/string.h>
   33 #include <linux/timer.h>
   34 #include <linux/interrupt.h>
   35 #include <linux/in.h>
   36 #include <linux/bitops.h>
   37 #include <linux/scatterlist.h>
   38 #include <linux/crypto.h>
   39 #include <linux/io.h>
   40 #include <asm/unaligned.h>
   41 
   42 #include <linux/netdevice.h>
   43 #include <linux/etherdevice.h>
   44 #include <linux/skbuff.h>
   45 #include <linux/if_arp.h>
   46 #include <linux/ioport.h>
   47 #include <linux/pci.h>
   48 #include <linux/uaccess.h>
   49 #include <linux/kthread.h>
   50 #include <linux/freezer.h>
   51 
   52 #include <net/cfg80211.h>
   53 #include <net/iw_handler.h>
   54 
   55 #include "airo.h"
   56 
   57 #define DRV_NAME "airo"
   58 
   59 #ifdef CONFIG_PCI
   60 static const struct pci_device_id card_ids[] = {
   61 	{ 0x14b9, 1, PCI_ANY_ID, PCI_ANY_ID, },
   62 	{ 0x14b9, 0x4500, PCI_ANY_ID, PCI_ANY_ID },
   63 	{ 0x14b9, 0x4800, PCI_ANY_ID, PCI_ANY_ID, },
   64 	{ 0x14b9, 0x0340, PCI_ANY_ID, PCI_ANY_ID, },
   65 	{ 0x14b9, 0x0350, PCI_ANY_ID, PCI_ANY_ID, },
   66 	{ 0x14b9, 0x5000, PCI_ANY_ID, PCI_ANY_ID, },
   67 	{ 0x14b9, 0xa504, PCI_ANY_ID, PCI_ANY_ID, },
   68 	{ 0, }
   69 };
   70 MODULE_DEVICE_TABLE(pci, card_ids);
   71 
   72 static int airo_pci_probe(struct pci_dev *, const struct pci_device_id *);
   73 static void airo_pci_remove(struct pci_dev *);
   74 static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state);
   75 static int airo_pci_resume(struct pci_dev *pdev);
   76 
   77 static struct pci_driver airo_driver = {
   78 	.name     = DRV_NAME,
   79 	.id_table = card_ids,
   80 	.probe    = airo_pci_probe,
   81 	.remove   = airo_pci_remove,
   82 	.suspend  = airo_pci_suspend,
   83 	.resume   = airo_pci_resume,
   84 };
   85 #endif /* CONFIG_PCI */
   86 
   87 /* Include Wireless Extension definition and check version - Jean II */
   88 #include <linux/wireless.h>
   89 #define WIRELESS_SPY		/* enable iwspy support */
   90 
   91 #define CISCO_EXT		/* enable Cisco extensions */
   92 #ifdef CISCO_EXT
   93 #include <linux/delay.h>
   94 #endif
   95 
   96 /* Hack to do some power saving */
   97 #define POWER_ON_DOWN
   98 
   99 /* As you can see this list is HUGH!
  100    I really don't know what a lot of these counts are about, but they
  101    are all here for completeness.  If the IGNLABEL macro is put in
  102    infront of the label, that statistic will not be included in the list
  103    of statistics in the /proc filesystem */
  104 
  105 #define IGNLABEL(comment) NULL
  106 static const char *statsLabels[] = {
  107 	"RxOverrun",
  108 	IGNLABEL("RxPlcpCrcErr"),
  109 	IGNLABEL("RxPlcpFormatErr"),
  110 	IGNLABEL("RxPlcpLengthErr"),
  111 	"RxMacCrcErr",
  112 	"RxMacCrcOk",
  113 	"RxWepErr",
  114 	"RxWepOk",
  115 	"RetryLong",
  116 	"RetryShort",
  117 	"MaxRetries",
  118 	"NoAck",
  119 	"NoCts",
  120 	"RxAck",
  121 	"RxCts",
  122 	"TxAck",
  123 	"TxRts",
  124 	"TxCts",
  125 	"TxMc",
  126 	"TxBc",
  127 	"TxUcFrags",
  128 	"TxUcPackets",
  129 	"TxBeacon",
  130 	"RxBeacon",
  131 	"TxSinColl",
  132 	"TxMulColl",
  133 	"DefersNo",
  134 	"DefersProt",
  135 	"DefersEngy",
  136 	"DupFram",
  137 	"RxFragDisc",
  138 	"TxAged",
  139 	"RxAged",
  140 	"LostSync-MaxRetry",
  141 	"LostSync-MissedBeacons",
  142 	"LostSync-ArlExceeded",
  143 	"LostSync-Deauth",
  144 	"LostSync-Disassoced",
  145 	"LostSync-TsfTiming",
  146 	"HostTxMc",
  147 	"HostTxBc",
  148 	"HostTxUc",
  149 	"HostTxFail",
  150 	"HostRxMc",
  151 	"HostRxBc",
  152 	"HostRxUc",
  153 	"HostRxDiscard",
  154 	IGNLABEL("HmacTxMc"),
  155 	IGNLABEL("HmacTxBc"),
  156 	IGNLABEL("HmacTxUc"),
  157 	IGNLABEL("HmacTxFail"),
  158 	IGNLABEL("HmacRxMc"),
  159 	IGNLABEL("HmacRxBc"),
  160 	IGNLABEL("HmacRxUc"),
  161 	IGNLABEL("HmacRxDiscard"),
  162 	IGNLABEL("HmacRxAccepted"),
  163 	"SsidMismatch",
  164 	"ApMismatch",
  165 	"RatesMismatch",
  166 	"AuthReject",
  167 	"AuthTimeout",
  168 	"AssocReject",
  169 	"AssocTimeout",
  170 	IGNLABEL("ReasonOutsideTable"),
  171 	IGNLABEL("ReasonStatus1"),
  172 	IGNLABEL("ReasonStatus2"),
  173 	IGNLABEL("ReasonStatus3"),
  174 	IGNLABEL("ReasonStatus4"),
  175 	IGNLABEL("ReasonStatus5"),
  176 	IGNLABEL("ReasonStatus6"),
  177 	IGNLABEL("ReasonStatus7"),
  178 	IGNLABEL("ReasonStatus8"),
  179 	IGNLABEL("ReasonStatus9"),
  180 	IGNLABEL("ReasonStatus10"),
  181 	IGNLABEL("ReasonStatus11"),
  182 	IGNLABEL("ReasonStatus12"),
  183 	IGNLABEL("ReasonStatus13"),
  184 	IGNLABEL("ReasonStatus14"),
  185 	IGNLABEL("ReasonStatus15"),
  186 	IGNLABEL("ReasonStatus16"),
  187 	IGNLABEL("ReasonStatus17"),
  188 	IGNLABEL("ReasonStatus18"),
  189 	IGNLABEL("ReasonStatus19"),
  190 	"RxMan",
  191 	"TxMan",
  192 	"RxRefresh",
  193 	"TxRefresh",
  194 	"RxPoll",
  195 	"TxPoll",
  196 	"HostRetries",
  197 	"LostSync-HostReq",
  198 	"HostTxBytes",
  199 	"HostRxBytes",
  200 	"ElapsedUsec",
  201 	"ElapsedSec",
  202 	"LostSyncBetterAP",
  203 	"PrivacyMismatch",
  204 	"Jammed",
  205 	"DiscRxNotWepped",
  206 	"PhyEleMismatch",
  207 	(char*)-1 };
  208 #ifndef RUN_AT
  209 #define RUN_AT(x) (jiffies+(x))
  210 #endif
  211 
  212 
  213 /* These variables are for insmod, since it seems that the rates
  214    can only be set in setup_card.  Rates should be a comma separated
  215    (no spaces) list of rates (up to 8). */
  216 
  217 static int rates[8];
  218 static char *ssids[3];
  219 
  220 static int io[4];
  221 static int irq[4];
  222 
  223 static
  224 int maxencrypt /* = 0 */; /* The highest rate that the card can encrypt at.
  225 		       0 means no limit.  For old cards this was 4 */
  226 
  227 static int auto_wep /* = 0 */; /* If set, it tries to figure out the wep mode */
  228 static int aux_bap /* = 0 */; /* Checks to see if the aux ports are needed to read
  229 		    the bap, needed on some older cards and buses. */
  230 static int adhoc;
  231 
  232 static int probe = 1;
  233 
  234 static kuid_t proc_kuid;
  235 static int proc_uid /* = 0 */;
  236 
  237 static kgid_t proc_kgid;
  238 static int proc_gid /* = 0 */;
  239 
  240 static int airo_perm = 0555;
  241 
  242 static int proc_perm = 0644;
  243 
  244 MODULE_AUTHOR("Benjamin Reed");
  245 MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet cards.  "
  246 		   "Direct support for ISA/PCI/MPI cards and support for PCMCIA when used with airo_cs.");
  247 MODULE_LICENSE("Dual BSD/GPL");
  248 MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340/350");
  249 module_param_array(io, int, NULL, 0);
  250 module_param_array(irq, int, NULL, 0);
  251 module_param_array(rates, int, NULL, 0);
  252 module_param_array(ssids, charp, NULL, 0);
  253 module_param(auto_wep, int, 0);
  254 MODULE_PARM_DESC(auto_wep,
  255 		 "If non-zero, the driver will keep looping through the authentication options until an association is made.  "
  256 		 "The value of auto_wep is number of the wep keys to check.  "
  257 		 "A value of 2 will try using the key at index 0 and index 1.");
  258 module_param(aux_bap, int, 0);
  259 MODULE_PARM_DESC(aux_bap,
  260 		 "If non-zero, the driver will switch into a mode that seems to work better for older cards with some older buses.  "
  261 		 "Before switching it checks that the switch is needed.");
  262 module_param(maxencrypt, int, 0);
  263 MODULE_PARM_DESC(maxencrypt,
  264 		 "The maximum speed that the card can do encryption.  "
  265 		 "Units are in 512kbs.  "
  266 		 "Zero (default) means there is no limit.  "
  267 		 "Older cards used to be limited to 2mbs (4).");
  268 module_param(adhoc, int, 0);
  269 MODULE_PARM_DESC(adhoc, "If non-zero, the card will start in adhoc mode.");
  270 module_param(probe, int, 0);
  271 MODULE_PARM_DESC(probe, "If zero, the driver won't start the card.");
  272 
  273 module_param(proc_uid, int, 0);
  274 MODULE_PARM_DESC(proc_uid, "The uid that the /proc files will belong to.");
  275 module_param(proc_gid, int, 0);
  276 MODULE_PARM_DESC(proc_gid, "The gid that the /proc files will belong to.");
  277 module_param(airo_perm, int, 0);
  278 MODULE_PARM_DESC(airo_perm, "The permission bits of /proc/[driver/]aironet.");
  279 module_param(proc_perm, int, 0);
  280 MODULE_PARM_DESC(proc_perm, "The permission bits of the files in /proc");
  281 
  282 /* This is a kind of sloppy hack to get this information to OUT4500 and
  283    IN4500.  I would be extremely interested in the situation where this
  284    doesn't work though!!! */
  285 static int do8bitIO /* = 0 */;
  286 
  287 /* Return codes */
  288 #define SUCCESS 0
  289 #define ERROR -1
  290 #define NO_PACKET -2
  291 
  292 /* Commands */
  293 #define NOP2		0x0000
  294 #define MAC_ENABLE	0x0001
  295 #define MAC_DISABLE	0x0002
  296 #define CMD_LOSE_SYNC	0x0003 /* Not sure what this does... */
  297 #define CMD_SOFTRESET	0x0004
  298 #define HOSTSLEEP	0x0005
  299 #define CMD_MAGIC_PKT	0x0006
  300 #define CMD_SETWAKEMASK	0x0007
  301 #define CMD_READCFG	0x0008
  302 #define CMD_SETMODE	0x0009
  303 #define CMD_ALLOCATETX	0x000a
  304 #define CMD_TRANSMIT	0x000b
  305 #define CMD_DEALLOCATETX 0x000c
  306 #define NOP		0x0010
  307 #define CMD_WORKAROUND	0x0011
  308 #define CMD_ALLOCATEAUX 0x0020
  309 #define CMD_ACCESS	0x0021
  310 #define CMD_PCIBAP	0x0022
  311 #define CMD_PCIAUX	0x0023
  312 #define CMD_ALLOCBUF	0x0028
  313 #define CMD_GETTLV	0x0029
  314 #define CMD_PUTTLV	0x002a
  315 #define CMD_DELTLV	0x002b
  316 #define CMD_FINDNEXTTLV	0x002c
  317 #define CMD_PSPNODES	0x0030
  318 #define CMD_SETCW	0x0031    
  319 #define CMD_SETPCF	0x0032    
  320 #define CMD_SETPHYREG	0x003e
  321 #define CMD_TXTEST	0x003f
  322 #define MAC_ENABLETX	0x0101
  323 #define CMD_LISTBSS	0x0103
  324 #define CMD_SAVECFG	0x0108
  325 #define CMD_ENABLEAUX	0x0111
  326 #define CMD_WRITERID	0x0121
  327 #define CMD_USEPSPNODES	0x0130
  328 #define MAC_ENABLERX	0x0201
  329 
  330 /* Command errors */
  331 #define ERROR_QUALIF 0x00
  332 #define ERROR_ILLCMD 0x01
  333 #define ERROR_ILLFMT 0x02
  334 #define ERROR_INVFID 0x03
  335 #define ERROR_INVRID 0x04
  336 #define ERROR_LARGE 0x05
  337 #define ERROR_NDISABL 0x06
  338 #define ERROR_ALLOCBSY 0x07
  339 #define ERROR_NORD 0x0B
  340 #define ERROR_NOWR 0x0C
  341 #define ERROR_INVFIDTX 0x0D
  342 #define ERROR_TESTACT 0x0E
  343 #define ERROR_TAGNFND 0x12
  344 #define ERROR_DECODE 0x20
  345 #define ERROR_DESCUNAV 0x21
  346 #define ERROR_BADLEN 0x22
  347 #define ERROR_MODE 0x80
  348 #define ERROR_HOP 0x81
  349 #define ERROR_BINTER 0x82
  350 #define ERROR_RXMODE 0x83
  351 #define ERROR_MACADDR 0x84
  352 #define ERROR_RATES 0x85
  353 #define ERROR_ORDER 0x86
  354 #define ERROR_SCAN 0x87
  355 #define ERROR_AUTH 0x88
  356 #define ERROR_PSMODE 0x89
  357 #define ERROR_RTYPE 0x8A
  358 #define ERROR_DIVER 0x8B
  359 #define ERROR_SSID 0x8C
  360 #define ERROR_APLIST 0x8D
  361 #define ERROR_AUTOWAKE 0x8E
  362 #define ERROR_LEAP 0x8F
  363 
  364 /* Registers */
  365 #define COMMAND 0x00
  366 #define PARAM0 0x02
  367 #define PARAM1 0x04
  368 #define PARAM2 0x06
  369 #define STATUS 0x08
  370 #define RESP0 0x0a
  371 #define RESP1 0x0c
  372 #define RESP2 0x0e
  373 #define LINKSTAT 0x10
  374 #define SELECT0 0x18
  375 #define OFFSET0 0x1c
  376 #define RXFID 0x20
  377 #define TXALLOCFID 0x22
  378 #define TXCOMPLFID 0x24
  379 #define DATA0 0x36
  380 #define EVSTAT 0x30
  381 #define EVINTEN 0x32
  382 #define EVACK 0x34
  383 #define SWS0 0x28
  384 #define SWS1 0x2a
  385 #define SWS2 0x2c
  386 #define SWS3 0x2e
  387 #define AUXPAGE 0x3A
  388 #define AUXOFF 0x3C
  389 #define AUXDATA 0x3E
  390 
  391 #define FID_TX 1
  392 #define FID_RX 2
  393 /* Offset into aux memory for descriptors */
  394 #define AUX_OFFSET 0x800
  395 /* Size of allocated packets */
  396 #define PKTSIZE 1840
  397 #define RIDSIZE 2048
  398 /* Size of the transmit queue */
  399 #define MAXTXQ 64
  400 
  401 /* BAP selectors */
  402 #define BAP0 0 /* Used for receiving packets */
  403 #define BAP1 2 /* Used for xmiting packets and working with RIDS */
  404 
  405 /* Flags */
  406 #define COMMAND_BUSY 0x8000
  407 
  408 #define BAP_BUSY 0x8000
  409 #define BAP_ERR 0x4000
  410 #define BAP_DONE 0x2000
  411 
  412 #define PROMISC 0xffff
  413 #define NOPROMISC 0x0000
  414 
  415 #define EV_CMD 0x10
  416 #define EV_CLEARCOMMANDBUSY 0x4000
  417 #define EV_RX 0x01
  418 #define EV_TX 0x02
  419 #define EV_TXEXC 0x04
  420 #define EV_ALLOC 0x08
  421 #define EV_LINK 0x80
  422 #define EV_AWAKE 0x100
  423 #define EV_TXCPY 0x400
  424 #define EV_UNKNOWN 0x800
  425 #define EV_MIC 0x1000 /* Message Integrity Check Interrupt */
  426 #define EV_AWAKEN 0x2000
  427 #define STATUS_INTS (EV_AWAKE|EV_LINK|EV_TXEXC|EV_TX|EV_TXCPY|EV_RX|EV_MIC)
  428 
  429 #ifdef CHECK_UNKNOWN_INTS
  430 #define IGNORE_INTS ( EV_CMD | EV_UNKNOWN)
  431 #else
  432 #define IGNORE_INTS (~STATUS_INTS)
  433 #endif
  434 
  435 /* RID TYPES */
  436 #define RID_RW 0x20
  437 
  438 /* The RIDs */
  439 #define RID_CAPABILITIES 0xFF00
  440 #define RID_APINFO     0xFF01
  441 #define RID_RADIOINFO  0xFF02
  442 #define RID_UNKNOWN3   0xFF03
  443 #define RID_RSSI       0xFF04
  444 #define RID_CONFIG     0xFF10
  445 #define RID_SSID       0xFF11
  446 #define RID_APLIST     0xFF12
  447 #define RID_DRVNAME    0xFF13
  448 #define RID_ETHERENCAP 0xFF14
  449 #define RID_WEP_TEMP   0xFF15
  450 #define RID_WEP_PERM   0xFF16
  451 #define RID_MODULATION 0xFF17
  452 #define RID_OPTIONS    0xFF18
  453 #define RID_ACTUALCONFIG 0xFF20 /*readonly*/
  454 #define RID_FACTORYCONFIG 0xFF21
  455 #define RID_UNKNOWN22  0xFF22
  456 #define RID_LEAPUSERNAME 0xFF23
  457 #define RID_LEAPPASSWORD 0xFF24
  458 #define RID_STATUS     0xFF50
  459 #define RID_BEACON_HST 0xFF51
  460 #define RID_BUSY_HST   0xFF52
  461 #define RID_RETRIES_HST 0xFF53
  462 #define RID_UNKNOWN54  0xFF54
  463 #define RID_UNKNOWN55  0xFF55
  464 #define RID_UNKNOWN56  0xFF56
  465 #define RID_MIC        0xFF57
  466 #define RID_STATS16    0xFF60
  467 #define RID_STATS16DELTA 0xFF61
  468 #define RID_STATS16DELTACLEAR 0xFF62
  469 #define RID_STATS      0xFF68
  470 #define RID_STATSDELTA 0xFF69
  471 #define RID_STATSDELTACLEAR 0xFF6A
  472 #define RID_ECHOTEST_RID 0xFF70
  473 #define RID_ECHOTEST_RESULTS 0xFF71
  474 #define RID_BSSLISTFIRST 0xFF72
  475 #define RID_BSSLISTNEXT  0xFF73
  476 #define RID_WPA_BSSLISTFIRST 0xFF74
  477 #define RID_WPA_BSSLISTNEXT  0xFF75
  478 
  479 typedef struct {
  480 	u16 cmd;
  481 	u16 parm0;
  482 	u16 parm1;
  483 	u16 parm2;
  484 } Cmd;
  485 
  486 typedef struct {
  487 	u16 status;
  488 	u16 rsp0;
  489 	u16 rsp1;
  490 	u16 rsp2;
  491 } Resp;
  492 
  493 /*
  494  * Rids and endian-ness:  The Rids will always be in cpu endian, since
  495  * this all the patches from the big-endian guys end up doing that.
  496  * so all rid access should use the read/writeXXXRid routines.
  497  */
  498 
  499 /* This structure came from an email sent to me from an engineer at
  500    aironet for inclusion into this driver */
  501 typedef struct WepKeyRid WepKeyRid;
  502 struct WepKeyRid {
  503 	__le16 len;
  504 	__le16 kindex;
  505 	u8 mac[ETH_ALEN];
  506 	__le16 klen;
  507 	u8 key[16];
  508 } __packed;
  509 
  510 /* These structures are from the Aironet's PC4500 Developers Manual */
  511 typedef struct Ssid Ssid;
  512 struct Ssid {
  513 	__le16 len;
  514 	u8 ssid[32];
  515 } __packed;
  516 
  517 typedef struct SsidRid SsidRid;
  518 struct SsidRid {
  519 	__le16 len;
  520 	Ssid ssids[3];
  521 } __packed;
  522 
  523 typedef struct ModulationRid ModulationRid;
  524 struct ModulationRid {
  525         __le16 len;
  526         __le16 modulation;
  527 #define MOD_DEFAULT cpu_to_le16(0)
  528 #define MOD_CCK cpu_to_le16(1)
  529 #define MOD_MOK cpu_to_le16(2)
  530 } __packed;
  531 
  532 typedef struct ConfigRid ConfigRid;
  533 struct ConfigRid {
  534 	__le16 len; /* sizeof(ConfigRid) */
  535 	__le16 opmode; /* operating mode */
  536 #define MODE_STA_IBSS cpu_to_le16(0)
  537 #define MODE_STA_ESS cpu_to_le16(1)
  538 #define MODE_AP cpu_to_le16(2)
  539 #define MODE_AP_RPTR cpu_to_le16(3)
  540 #define MODE_CFG_MASK cpu_to_le16(0xff)
  541 #define MODE_ETHERNET_HOST cpu_to_le16(0<<8) /* rx payloads converted */
  542 #define MODE_LLC_HOST cpu_to_le16(1<<8) /* rx payloads left as is */
  543 #define MODE_AIRONET_EXTEND cpu_to_le16(1<<9) /* enable Aironet extenstions */
  544 #define MODE_AP_INTERFACE cpu_to_le16(1<<10) /* enable ap interface extensions */
  545 #define MODE_ANTENNA_ALIGN cpu_to_le16(1<<11) /* enable antenna alignment */
  546 #define MODE_ETHER_LLC cpu_to_le16(1<<12) /* enable ethernet LLC */
  547 #define MODE_LEAF_NODE cpu_to_le16(1<<13) /* enable leaf node bridge */
  548 #define MODE_CF_POLLABLE cpu_to_le16(1<<14) /* enable CF pollable */
  549 #define MODE_MIC cpu_to_le16(1<<15) /* enable MIC */
  550 	__le16 rmode; /* receive mode */
  551 #define RXMODE_BC_MC_ADDR cpu_to_le16(0)
  552 #define RXMODE_BC_ADDR cpu_to_le16(1) /* ignore multicasts */
  553 #define RXMODE_ADDR cpu_to_le16(2) /* ignore multicast and broadcast */
  554 #define RXMODE_RFMON cpu_to_le16(3) /* wireless monitor mode */
  555 #define RXMODE_RFMON_ANYBSS cpu_to_le16(4)
  556 #define RXMODE_LANMON cpu_to_le16(5) /* lan style monitor -- data packets only */
  557 #define RXMODE_MASK cpu_to_le16(255)
  558 #define RXMODE_DISABLE_802_3_HEADER cpu_to_le16(1<<8) /* disables 802.3 header on rx */
  559 #define RXMODE_FULL_MASK (RXMODE_MASK | RXMODE_DISABLE_802_3_HEADER)
  560 #define RXMODE_NORMALIZED_RSSI cpu_to_le16(1<<9) /* return normalized RSSI */
  561 	__le16 fragThresh;
  562 	__le16 rtsThres;
  563 	u8 macAddr[ETH_ALEN];
  564 	u8 rates[8];
  565 	__le16 shortRetryLimit;
  566 	__le16 longRetryLimit;
  567 	__le16 txLifetime; /* in kusec */
  568 	__le16 rxLifetime; /* in kusec */
  569 	__le16 stationary;
  570 	__le16 ordering;
  571 	__le16 u16deviceType; /* for overriding device type */
  572 	__le16 cfpRate;
  573 	__le16 cfpDuration;
  574 	__le16 _reserved1[3];
  575 	/*---------- Scanning/Associating ----------*/
  576 	__le16 scanMode;
  577 #define SCANMODE_ACTIVE cpu_to_le16(0)
  578 #define SCANMODE_PASSIVE cpu_to_le16(1)
  579 #define SCANMODE_AIROSCAN cpu_to_le16(2)
  580 	__le16 probeDelay; /* in kusec */
  581 	__le16 probeEnergyTimeout; /* in kusec */
  582         __le16 probeResponseTimeout;
  583 	__le16 beaconListenTimeout;
  584 	__le16 joinNetTimeout;
  585 	__le16 authTimeout;
  586 	__le16 authType;
  587 #define AUTH_OPEN cpu_to_le16(0x1)
  588 #define AUTH_ENCRYPT cpu_to_le16(0x101)
  589 #define AUTH_SHAREDKEY cpu_to_le16(0x102)
  590 #define AUTH_ALLOW_UNENCRYPTED cpu_to_le16(0x200)
  591 	__le16 associationTimeout;
  592 	__le16 specifiedApTimeout;
  593 	__le16 offlineScanInterval;
  594 	__le16 offlineScanDuration;
  595 	__le16 linkLossDelay;
  596 	__le16 maxBeaconLostTime;
  597 	__le16 refreshInterval;
  598 #define DISABLE_REFRESH cpu_to_le16(0xFFFF)
  599 	__le16 _reserved1a[1];
  600 	/*---------- Power save operation ----------*/
  601 	__le16 powerSaveMode;
  602 #define POWERSAVE_CAM cpu_to_le16(0)
  603 #define POWERSAVE_PSP cpu_to_le16(1)
  604 #define POWERSAVE_PSPCAM cpu_to_le16(2)
  605 	__le16 sleepForDtims;
  606 	__le16 listenInterval;
  607 	__le16 fastListenInterval;
  608 	__le16 listenDecay;
  609 	__le16 fastListenDelay;
  610 	__le16 _reserved2[2];
  611 	/*---------- Ap/Ibss config items ----------*/
  612 	__le16 beaconPeriod;
  613 	__le16 atimDuration;
  614 	__le16 hopPeriod;
  615 	__le16 channelSet;
  616 	__le16 channel;
  617 	__le16 dtimPeriod;
  618 	__le16 bridgeDistance;
  619 	__le16 radioID;
  620 	/*---------- Radio configuration ----------*/
  621 	__le16 radioType;
  622 #define RADIOTYPE_DEFAULT cpu_to_le16(0)
  623 #define RADIOTYPE_802_11 cpu_to_le16(1)
  624 #define RADIOTYPE_LEGACY cpu_to_le16(2)
  625 	u8 rxDiversity;
  626 	u8 txDiversity;
  627 	__le16 txPower;
  628 #define TXPOWER_DEFAULT 0
  629 	__le16 rssiThreshold;
  630 #define RSSI_DEFAULT 0
  631         __le16 modulation;
  632 #define PREAMBLE_AUTO cpu_to_le16(0)
  633 #define PREAMBLE_LONG cpu_to_le16(1)
  634 #define PREAMBLE_SHORT cpu_to_le16(2)
  635 	__le16 preamble;
  636 	__le16 homeProduct;
  637 	__le16 radioSpecific;
  638 	/*---------- Aironet Extensions ----------*/
  639 	u8 nodeName[16];
  640 	__le16 arlThreshold;
  641 	__le16 arlDecay;
  642 	__le16 arlDelay;
  643 	__le16 _reserved4[1];
  644 	/*---------- Aironet Extensions ----------*/
  645 	u8 magicAction;
  646 #define MAGIC_ACTION_STSCHG 1
  647 #define MAGIC_ACTION_RESUME 2
  648 #define MAGIC_IGNORE_MCAST (1<<8)
  649 #define MAGIC_IGNORE_BCAST (1<<9)
  650 #define MAGIC_SWITCH_TO_PSP (0<<10)
  651 #define MAGIC_STAY_IN_CAM (1<<10)
  652 	u8 magicControl;
  653 	__le16 autoWake;
  654 } __packed;
  655 
  656 typedef struct StatusRid StatusRid;
  657 struct StatusRid {
  658 	__le16 len;
  659 	u8 mac[ETH_ALEN];
  660 	__le16 mode;
  661 	__le16 errorCode;
  662 	__le16 sigQuality;
  663 	__le16 SSIDlen;
  664 	char SSID[32];
  665 	char apName[16];
  666 	u8 bssid[4][ETH_ALEN];
  667 	__le16 beaconPeriod;
  668 	__le16 dimPeriod;
  669 	__le16 atimDuration;
  670 	__le16 hopPeriod;
  671 	__le16 channelSet;
  672 	__le16 channel;
  673 	__le16 hopsToBackbone;
  674 	__le16 apTotalLoad;
  675 	__le16 generatedLoad;
  676 	__le16 accumulatedArl;
  677 	__le16 signalQuality;
  678 	__le16 currentXmitRate;
  679 	__le16 apDevExtensions;
  680 	__le16 normalizedSignalStrength;
  681 	__le16 shortPreamble;
  682 	u8 apIP[4];
  683 	u8 noisePercent; /* Noise percent in last second */
  684 	u8 noisedBm; /* Noise dBm in last second */
  685 	u8 noiseAvePercent; /* Noise percent in last minute */
  686 	u8 noiseAvedBm; /* Noise dBm in last minute */
  687 	u8 noiseMaxPercent; /* Highest noise percent in last minute */
  688 	u8 noiseMaxdBm; /* Highest noise dbm in last minute */
  689 	__le16 load;
  690 	u8 carrier[4];
  691 	__le16 assocStatus;
  692 #define STAT_NOPACKETS 0
  693 #define STAT_NOCARRIERSET 10
  694 #define STAT_GOTCARRIERSET 11
  695 #define STAT_WRONGSSID 20
  696 #define STAT_BADCHANNEL 25
  697 #define STAT_BADBITRATES 30
  698 #define STAT_BADPRIVACY 35
  699 #define STAT_APFOUND 40
  700 #define STAT_APREJECTED 50
  701 #define STAT_AUTHENTICATING 60
  702 #define STAT_DEAUTHENTICATED 61
  703 #define STAT_AUTHTIMEOUT 62
  704 #define STAT_ASSOCIATING 70
  705 #define STAT_DEASSOCIATED 71
  706 #define STAT_ASSOCTIMEOUT 72
  707 #define STAT_NOTAIROAP 73
  708 #define STAT_ASSOCIATED 80
  709 #define STAT_LEAPING 90
  710 #define STAT_LEAPFAILED 91
  711 #define STAT_LEAPTIMEDOUT 92
  712 #define STAT_LEAPCOMPLETE 93
  713 } __packed;
  714 
  715 typedef struct StatsRid StatsRid;
  716 struct StatsRid {
  717 	__le16 len;
  718 	__le16 spacer;
  719 	__le32 vals[100];
  720 } __packed;
  721 
  722 typedef struct APListRid APListRid;
  723 struct APListRid {
  724 	__le16 len;
  725 	u8 ap[4][ETH_ALEN];
  726 } __packed;
  727 
  728 typedef struct CapabilityRid CapabilityRid;
  729 struct CapabilityRid {
  730 	__le16 len;
  731 	char oui[3];
  732 	char zero;
  733 	__le16 prodNum;
  734 	char manName[32];
  735 	char prodName[16];
  736 	char prodVer[8];
  737 	char factoryAddr[ETH_ALEN];
  738 	char aironetAddr[ETH_ALEN];
  739 	__le16 radioType;
  740 	__le16 country;
  741 	char callid[ETH_ALEN];
  742 	char supportedRates[8];
  743 	char rxDiversity;
  744 	char txDiversity;
  745 	__le16 txPowerLevels[8];
  746 	__le16 hardVer;
  747 	__le16 hardCap;
  748 	__le16 tempRange;
  749 	__le16 softVer;
  750 	__le16 softSubVer;
  751 	__le16 interfaceVer;
  752 	__le16 softCap;
  753 	__le16 bootBlockVer;
  754 	__le16 requiredHard;
  755 	__le16 extSoftCap;
  756 } __packed;
  757 
  758 /* Only present on firmware >= 5.30.17 */
  759 typedef struct BSSListRidExtra BSSListRidExtra;
  760 struct BSSListRidExtra {
  761   __le16 unknown[4];
  762   u8 fixed[12]; /* WLAN management frame */
  763   u8 iep[624];
  764 } __packed;
  765 
  766 typedef struct BSSListRid BSSListRid;
  767 struct BSSListRid {
  768   __le16 len;
  769   __le16 index; /* First is 0 and 0xffff means end of list */
  770 #define RADIO_FH 1 /* Frequency hopping radio type */
  771 #define RADIO_DS 2 /* Direct sequence radio type */
  772 #define RADIO_TMA 4 /* Proprietary radio used in old cards (2500) */
  773   __le16 radioType;
  774   u8 bssid[ETH_ALEN]; /* Mac address of the BSS */
  775   u8 zero;
  776   u8 ssidLen;
  777   u8 ssid[32];
  778   __le16 dBm;
  779 #define CAP_ESS cpu_to_le16(1<<0)
  780 #define CAP_IBSS cpu_to_le16(1<<1)
  781 #define CAP_PRIVACY cpu_to_le16(1<<4)
  782 #define CAP_SHORTHDR cpu_to_le16(1<<5)
  783   __le16 cap;
  784   __le16 beaconInterval;
  785   u8 rates[8]; /* Same as rates for config rid */
  786   struct { /* For frequency hopping only */
  787     __le16 dwell;
  788     u8 hopSet;
  789     u8 hopPattern;
  790     u8 hopIndex;
  791     u8 fill;
  792   } fh;
  793   __le16 dsChannel;
  794   __le16 atimWindow;
  795 
  796   /* Only present on firmware >= 5.30.17 */
  797   BSSListRidExtra extra;
  798 } __packed;
  799 
  800 typedef struct {
  801   BSSListRid bss;
  802   struct list_head list;
  803 } BSSListElement;
  804 
  805 typedef struct tdsRssiEntry tdsRssiEntry;
  806 struct tdsRssiEntry {
  807   u8 rssipct;
  808   u8 rssidBm;
  809 } __packed;
  810 
  811 typedef struct tdsRssiRid tdsRssiRid;
  812 struct tdsRssiRid {
  813   u16 len;
  814   tdsRssiEntry x[256];
  815 } __packed;
  816 
  817 typedef struct MICRid MICRid;
  818 struct MICRid {
  819 	__le16 len;
  820 	__le16 state;
  821 	__le16 multicastValid;
  822 	u8  multicast[16];
  823 	__le16 unicastValid;
  824 	u8  unicast[16];
  825 } __packed;
  826 
  827 typedef struct MICBuffer MICBuffer;
  828 struct MICBuffer {
  829 	__be16 typelen;
  830 
  831 	union {
  832 	    u8 snap[8];
  833 	    struct {
  834 		u8 dsap;
  835 		u8 ssap;
  836 		u8 control;
  837 		u8 orgcode[3];
  838 		u8 fieldtype[2];
  839 	    } llc;
  840 	} u;
  841 	__be32 mic;
  842 	__be32 seq;
  843 } __packed;
  844 
  845 typedef struct {
  846 	u8 da[ETH_ALEN];
  847 	u8 sa[ETH_ALEN];
  848 } etherHead;
  849 
  850 #define TXCTL_TXOK (1<<1) /* report if tx is ok */
  851 #define TXCTL_TXEX (1<<2) /* report if tx fails */
  852 #define TXCTL_802_3 (0<<3) /* 802.3 packet */
  853 #define TXCTL_802_11 (1<<3) /* 802.11 mac packet */
  854 #define TXCTL_ETHERNET (0<<4) /* payload has ethertype */
  855 #define TXCTL_LLC (1<<4) /* payload is llc */
  856 #define TXCTL_RELEASE (0<<5) /* release after completion */
  857 #define TXCTL_NORELEASE (1<<5) /* on completion returns to host */
  858 
  859 #define BUSY_FID 0x10000
  860 
  861 #ifdef CISCO_EXT
  862 #define AIROMAGIC	0xa55a
  863 /* Warning : SIOCDEVPRIVATE may disapear during 2.5.X - Jean II */
  864 #ifdef SIOCIWFIRSTPRIV
  865 #ifdef SIOCDEVPRIVATE
  866 #define AIROOLDIOCTL	SIOCDEVPRIVATE
  867 #define AIROOLDIDIFC 	AIROOLDIOCTL + 1
  868 #endif /* SIOCDEVPRIVATE */
  869 #else /* SIOCIWFIRSTPRIV */
  870 #define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
  871 #endif /* SIOCIWFIRSTPRIV */
  872 /* This may be wrong. When using the new SIOCIWFIRSTPRIV range, we probably
  873  * should use only "GET" ioctls (last bit set to 1). "SET" ioctls are root
  874  * only and don't return the modified struct ifreq to the application which
  875  * is usually a problem. - Jean II */
  876 #define AIROIOCTL	SIOCIWFIRSTPRIV
  877 #define AIROIDIFC 	AIROIOCTL + 1
  878 
  879 /* Ioctl constants to be used in airo_ioctl.command */
  880 
  881 #define	AIROGCAP  		0	// Capability rid
  882 #define AIROGCFG		1       // USED A LOT
  883 #define AIROGSLIST		2	// System ID list
  884 #define AIROGVLIST		3       // List of specified AP's
  885 #define AIROGDRVNAM		4	//  NOTUSED
  886 #define AIROGEHTENC		5	// NOTUSED
  887 #define AIROGWEPKTMP		6
  888 #define AIROGWEPKNV		7
  889 #define AIROGSTAT		8
  890 #define AIROGSTATSC32		9
  891 #define AIROGSTATSD32		10
  892 #define AIROGMICRID		11
  893 #define AIROGMICSTATS		12
  894 #define AIROGFLAGS		13
  895 #define AIROGID			14
  896 #define AIRORRID		15
  897 #define AIRORSWVERSION		17
  898 
  899 /* Leave gap of 40 commands after AIROGSTATSD32 for future */
  900 
  901 #define AIROPCAP               	AIROGSTATSD32 + 40
  902 #define AIROPVLIST              AIROPCAP      + 1
  903 #define AIROPSLIST		AIROPVLIST    + 1
  904 #define AIROPCFG		AIROPSLIST    + 1
  905 #define AIROPSIDS		AIROPCFG      + 1
  906 #define AIROPAPLIST		AIROPSIDS     + 1
  907 #define AIROPMACON		AIROPAPLIST   + 1	/* Enable mac  */
  908 #define AIROPMACOFF		AIROPMACON    + 1 	/* Disable mac */
  909 #define AIROPSTCLR		AIROPMACOFF   + 1
  910 #define AIROPWEPKEY		AIROPSTCLR    + 1
  911 #define AIROPWEPKEYNV		AIROPWEPKEY   + 1
  912 #define AIROPLEAPPWD            AIROPWEPKEYNV + 1
  913 #define AIROPLEAPUSR            AIROPLEAPPWD  + 1
  914 
  915 /* Flash codes */
  916 
  917 #define AIROFLSHRST	       AIROPWEPKEYNV  + 40
  918 #define AIROFLSHGCHR           AIROFLSHRST    + 1
  919 #define AIROFLSHSTFL           AIROFLSHGCHR   + 1
  920 #define AIROFLSHPCHR           AIROFLSHSTFL   + 1
  921 #define AIROFLPUTBUF           AIROFLSHPCHR   + 1
  922 #define AIRORESTART            AIROFLPUTBUF   + 1
  923 
  924 #define FLASHSIZE	32768
  925 #define AUXMEMSIZE	(256 * 1024)
  926 
  927 typedef struct aironet_ioctl {
  928 	unsigned short command;		// What to do
  929 	unsigned short len;		// Len of data
  930 	unsigned short ridnum;		// rid number
  931 	unsigned char __user *data;	// d-data
  932 } aironet_ioctl;
  933 
  934 static const char swversion[] = "2.1";
  935 #endif /* CISCO_EXT */
  936 
  937 #define NUM_MODULES       2
  938 #define MIC_MSGLEN_MAX    2400
  939 #define EMMH32_MSGLEN_MAX MIC_MSGLEN_MAX
  940 #define AIRO_DEF_MTU      2312
  941 
  942 typedef struct {
  943 	u32   size;            // size
  944 	u8    enabled;         // MIC enabled or not
  945 	u32   rxSuccess;       // successful packets received
  946 	u32   rxIncorrectMIC;  // pkts dropped due to incorrect MIC comparison
  947 	u32   rxNotMICed;      // pkts dropped due to not being MIC'd
  948 	u32   rxMICPlummed;    // pkts dropped due to not having a MIC plummed
  949 	u32   rxWrongSequence; // pkts dropped due to sequence number violation
  950 	u32   reserve[32];
  951 } mic_statistics;
  952 
  953 typedef struct {
  954 	u32 coeff[((EMMH32_MSGLEN_MAX)+3)>>2];
  955 	u64 accum;	// accumulated mic, reduced to u32 in final()
  956 	int position;	// current position (byte offset) in message
  957 	union {
  958 		u8  d8[4];
  959 		__be32 d32;
  960 	} part;	// saves partial message word across update() calls
  961 } emmh32_context;
  962 
  963 typedef struct {
  964 	emmh32_context seed;	    // Context - the seed
  965 	u32		 rx;	    // Received sequence number
  966 	u32		 tx;	    // Tx sequence number
  967 	u32		 window;    // Start of window
  968 	u8		 valid;	    // Flag to say if context is valid or not
  969 	u8		 key[16];
  970 } miccntx;
  971 
  972 typedef struct {
  973 	miccntx mCtx;		// Multicast context
  974 	miccntx uCtx;		// Unicast context
  975 } mic_module;
  976 
  977 typedef struct {
  978 	unsigned int  rid: 16;
  979 	unsigned int  len: 15;
  980 	unsigned int  valid: 1;
  981 	dma_addr_t host_addr;
  982 } Rid;
  983 
  984 typedef struct {
  985 	unsigned int  offset: 15;
  986 	unsigned int  eoc: 1;
  987 	unsigned int  len: 15;
  988 	unsigned int  valid: 1;
  989 	dma_addr_t host_addr;
  990 } TxFid;
  991 
  992 struct rx_hdr {
  993 	__le16 status, len;
  994 	u8 rssi[2];
  995 	u8 rate;
  996 	u8 freq;
  997 	__le16 tmp[4];
  998 } __packed;
  999 
 1000 typedef struct {
 1001 	unsigned int  ctl: 15;
 1002 	unsigned int  rdy: 1;
 1003 	unsigned int  len: 15;
 1004 	unsigned int  valid: 1;
 1005 	dma_addr_t host_addr;
 1006 } RxFid;
 1007 
 1008 /*
 1009  * Host receive descriptor
 1010  */
 1011 typedef struct {
 1012 	unsigned char __iomem *card_ram_off; /* offset into card memory of the
 1013 						desc */
 1014 	RxFid         rx_desc;		     /* card receive descriptor */
 1015 	char          *virtual_host_addr;    /* virtual address of host receive
 1016 					        buffer */
 1017 	int           pending;
 1018 } HostRxDesc;
 1019 
 1020 /*
 1021  * Host transmit descriptor
 1022  */
 1023 typedef struct {
 1024 	unsigned char __iomem *card_ram_off;	     /* offset into card memory of the
 1025 						desc */
 1026 	TxFid         tx_desc;		     /* card transmit descriptor */
 1027 	char          *virtual_host_addr;    /* virtual address of host receive
 1028 					        buffer */
 1029 	int           pending;
 1030 } HostTxDesc;
 1031 
 1032 /*
 1033  * Host RID descriptor
 1034  */
 1035 typedef struct {
 1036 	unsigned char __iomem *card_ram_off;      /* offset into card memory of the
 1037 					     descriptor */
 1038 	Rid           rid_desc;		  /* card RID descriptor */
 1039 	char          *virtual_host_addr; /* virtual address of host receive
 1040 					     buffer */
 1041 } HostRidDesc;
 1042 
 1043 typedef struct {
 1044 	u16 sw0;
 1045 	u16 sw1;
 1046 	u16 status;
 1047 	u16 len;
 1048 #define HOST_SET (1 << 0)
 1049 #define HOST_INT_TX (1 << 1) /* Interrupt on successful TX */
 1050 #define HOST_INT_TXERR (1 << 2) /* Interrupt on unseccessful TX */
 1051 #define HOST_LCC_PAYLOAD (1 << 4) /* LLC payload, 0 = Ethertype */
 1052 #define HOST_DONT_RLSE (1 << 5) /* Don't release buffer when done */
 1053 #define HOST_DONT_RETRY (1 << 6) /* Don't retry trasmit */
 1054 #define HOST_CLR_AID (1 << 7) /* clear AID failure */
 1055 #define HOST_RTS (1 << 9) /* Force RTS use */
 1056 #define HOST_SHORT (1 << 10) /* Do short preamble */
 1057 	u16 ctl;
 1058 	u16 aid;
 1059 	u16 retries;
 1060 	u16 fill;
 1061 } TxCtlHdr;
 1062 
 1063 typedef struct {
 1064         u16 ctl;
 1065         u16 duration;
 1066         char addr1[6];
 1067         char addr2[6];
 1068         char addr3[6];
 1069         u16 seq;
 1070         char addr4[6];
 1071 } WifiHdr;
 1072 
 1073 
 1074 typedef struct {
 1075 	TxCtlHdr ctlhdr;
 1076 	u16 fill1;
 1077 	u16 fill2;
 1078 	WifiHdr wifihdr;
 1079 	u16 gaplen;
 1080 	u16 status;
 1081 } WifiCtlHdr;
 1082 
 1083 static WifiCtlHdr wifictlhdr8023 = {
 1084 	.ctlhdr = {
 1085 		.ctl	= HOST_DONT_RLSE,
 1086 	}
 1087 };
 1088 
 1089 // A few details needed for WEP (Wireless Equivalent Privacy)
 1090 #define MAX_KEY_SIZE 13			// 128 (?) bits
 1091 #define MIN_KEY_SIZE  5			// 40 bits RC4 - WEP
 1092 typedef struct wep_key_t {
 1093 	u16	len;
 1094 	u8	key[16];	/* 40-bit and 104-bit keys */
 1095 } wep_key_t;
 1096 
 1097 /* List of Wireless Handlers (new API) */
 1098 static const struct iw_handler_def	airo_handler_def;
 1099 
 1100 static const char version[] = "airo.c 0.6 (Ben Reed & Javier Achirica)";
 1101 
 1102 struct airo_info;
 1103 
 1104 static int get_dec_u16( char *buffer, int *start, int limit );
 1105 static void OUT4500( struct airo_info *, u16 register, u16 value );
 1106 static unsigned short IN4500( struct airo_info *, u16 register );
 1107 static u16 setup_card(struct airo_info*, u8 *mac, int lock);
 1108 static int enable_MAC(struct airo_info *ai, int lock);
 1109 static void disable_MAC(struct airo_info *ai, int lock);
 1110 static void enable_interrupts(struct airo_info*);
 1111 static void disable_interrupts(struct airo_info*);
 1112 static u16 issuecommand(struct airo_info*, Cmd *pCmd, Resp *pRsp);
 1113 static int bap_setup(struct airo_info*, u16 rid, u16 offset, int whichbap);
 1114 static int aux_bap_read(struct airo_info*, __le16 *pu16Dst, int bytelen,
 1115 			int whichbap);
 1116 static int fast_bap_read(struct airo_info*, __le16 *pu16Dst, int bytelen,
 1117 			 int whichbap);
 1118 static int bap_write(struct airo_info*, const __le16 *pu16Src, int bytelen,
 1119 		     int whichbap);
 1120 static int PC4500_accessrid(struct airo_info*, u16 rid, u16 accmd);
 1121 static int PC4500_readrid(struct airo_info*, u16 rid, void *pBuf, int len, int lock);
 1122 static int PC4500_writerid(struct airo_info*, u16 rid, const void
 1123 			   *pBuf, int len, int lock);
 1124 static int do_writerid( struct airo_info*, u16 rid, const void *rid_data,
 1125 			int len, int dummy );
 1126 static u16 transmit_allocate(struct airo_info*, int lenPayload, int raw);
 1127 static int transmit_802_3_packet(struct airo_info*, int len, char *pPacket);
 1128 static int transmit_802_11_packet(struct airo_info*, int len, char *pPacket);
 1129 
 1130 static int mpi_send_packet (struct net_device *dev);
 1131 static void mpi_unmap_card(struct pci_dev *pci);
 1132 static void mpi_receive_802_3(struct airo_info *ai);
 1133 static void mpi_receive_802_11(struct airo_info *ai);
 1134 static int waitbusy (struct airo_info *ai);
 1135 
 1136 static irqreturn_t airo_interrupt( int irq, void* dev_id);
 1137 static int airo_thread(void *data);
 1138 static void timer_func( struct net_device *dev );
 1139 static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 1140 static struct iw_statistics *airo_get_wireless_stats (struct net_device *dev);
 1141 static void airo_read_wireless_stats (struct airo_info *local);
 1142 #ifdef CISCO_EXT
 1143 static int readrids(struct net_device *dev, aironet_ioctl *comp);
 1144 static int writerids(struct net_device *dev, aironet_ioctl *comp);
 1145 static int flashcard(struct net_device *dev, aironet_ioctl *comp);
 1146 #endif /* CISCO_EXT */
 1147 static void micinit(struct airo_info *ai);
 1148 static int micsetup(struct airo_info *ai);
 1149 static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len);
 1150 static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen);
 1151 
 1152 static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi);
 1153 static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm);
 1154 
 1155 static void airo_networks_free(struct airo_info *ai);
 1156 
 1157 struct airo_info {
 1158 	struct net_device             *dev;
 1159 	struct list_head              dev_list;
 1160 	/* Note, we can have MAX_FIDS outstanding.  FIDs are 16-bits, so we
 1161 	   use the high bit to mark whether it is in use. */
 1162 #define MAX_FIDS 6
 1163 #define MPI_MAX_FIDS 1
 1164 	u32                           fids[MAX_FIDS];
 1165 	ConfigRid config;
 1166 	char keyindex; // Used with auto wep
 1167 	char defindex; // Used with auto wep
 1168 	struct proc_dir_entry *proc_entry;
 1169         spinlock_t aux_lock;
 1170 #define FLAG_RADIO_OFF	0	/* User disabling of MAC */
 1171 #define FLAG_RADIO_DOWN	1	/* ifup/ifdown disabling of MAC */
 1172 #define FLAG_RADIO_MASK 0x03
 1173 #define FLAG_ENABLED	2
 1174 #define FLAG_ADHOC	3	/* Needed by MIC */
 1175 #define FLAG_MIC_CAPABLE 4
 1176 #define FLAG_UPDATE_MULTI 5
 1177 #define FLAG_UPDATE_UNI 6
 1178 #define FLAG_802_11	7
 1179 #define FLAG_PROMISC	8	/* IFF_PROMISC 0x100 - include/linux/if.h */
 1180 #define FLAG_PENDING_XMIT 9
 1181 #define FLAG_PENDING_XMIT11 10
 1182 #define FLAG_MPI	11
 1183 #define FLAG_REGISTERED	12
 1184 #define FLAG_COMMIT	13
 1185 #define FLAG_RESET	14
 1186 #define FLAG_FLASHING	15
 1187 #define FLAG_WPA_CAPABLE	16
 1188 	unsigned long flags;
 1189 #define JOB_DIE	0
 1190 #define JOB_XMIT	1
 1191 #define JOB_XMIT11	2
 1192 #define JOB_STATS	3
 1193 #define JOB_PROMISC	4
 1194 #define JOB_MIC	5
 1195 #define JOB_EVENT	6
 1196 #define JOB_AUTOWEP	7
 1197 #define JOB_WSTATS	8
 1198 #define JOB_SCAN_RESULTS  9
 1199 	unsigned long jobs;
 1200 	int (*bap_read)(struct airo_info*, __le16 *pu16Dst, int bytelen,
 1201 			int whichbap);
 1202 	unsigned short *flash;
 1203 	tdsRssiEntry *rssi;
 1204 	struct task_struct *list_bss_task;
 1205 	struct task_struct *airo_thread_task;
 1206 	struct semaphore sem;
 1207 	wait_queue_head_t thr_wait;
 1208 	unsigned long expires;
 1209 	struct {
 1210 		struct sk_buff *skb;
 1211 		int fid;
 1212 	} xmit, xmit11;
 1213 	struct net_device *wifidev;
 1214 	struct iw_statistics	wstats;		// wireless stats
 1215 	unsigned long		scan_timeout;	/* Time scan should be read */
 1216 	struct iw_spy_data	spy_data;
 1217 	struct iw_public_data	wireless_data;
 1218 	/* MIC stuff */
 1219 	struct crypto_cipher	*tfm;
 1220 	mic_module		mod[2];
 1221 	mic_statistics		micstats;
 1222 	HostRxDesc rxfids[MPI_MAX_FIDS]; // rx/tx/config MPI350 descriptors
 1223 	HostTxDesc txfids[MPI_MAX_FIDS];
 1224 	HostRidDesc config_desc;
 1225 	unsigned long ridbus; // phys addr of config_desc
 1226 	struct sk_buff_head txq;// tx queue used by mpi350 code
 1227 	struct pci_dev          *pci;
 1228 	unsigned char		__iomem *pcimem;
 1229 	unsigned char		__iomem *pciaux;
 1230 	unsigned char		*shared;
 1231 	dma_addr_t		shared_dma;
 1232 	pm_message_t		power;
 1233 	SsidRid			*SSID;
 1234 	APListRid		APList;
 1235 #define	PCI_SHARED_LEN		2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE
 1236 	char			proc_name[IFNAMSIZ];
 1237 
 1238 	int			wep_capable;
 1239 	int			max_wep_idx;
 1240 	int			last_auth;
 1241 
 1242 	/* WPA-related stuff */
 1243 	unsigned int bssListFirst;
 1244 	unsigned int bssListNext;
 1245 	unsigned int bssListRidLen;
 1246 
 1247 	struct list_head network_list;
 1248 	struct list_head network_free_list;
 1249 	BSSListElement *networks;
 1250 };
 1251 
 1252 static inline int bap_read(struct airo_info *ai, __le16 *pu16Dst, int bytelen,
 1253 			   int whichbap)
 1254 {
 1255 	return ai->bap_read(ai, pu16Dst, bytelen, whichbap);
 1256 }
 1257 
 1258 static int setup_proc_entry( struct net_device *dev,
 1259 			     struct airo_info *apriv );
 1260 static int takedown_proc_entry( struct net_device *dev,
 1261 				struct airo_info *apriv );
 1262 
 1263 static int cmdreset(struct airo_info *ai);
 1264 static int setflashmode (struct airo_info *ai);
 1265 static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime);
 1266 static int flashputbuf(struct airo_info *ai);
 1267 static int flashrestart(struct airo_info *ai,struct net_device *dev);
 1268 
 1269 #define airo_print(type, name, fmt, args...) \
 1270 	printk(type DRV_NAME "(%s): " fmt "\n", name, ##args)
 1271 
 1272 #define airo_print_info(name, fmt, args...) \
 1273 	airo_print(KERN_INFO, name, fmt, ##args)
 1274 
 1275 #define airo_print_dbg(name, fmt, args...) \
 1276 	airo_print(KERN_DEBUG, name, fmt, ##args)
 1277 
 1278 #define airo_print_warn(name, fmt, args...) \
 1279 	airo_print(KERN_WARNING, name, fmt, ##args)
 1280 
 1281 #define airo_print_err(name, fmt, args...) \
 1282 	airo_print(KERN_ERR, name, fmt, ##args)
 1283 
 1284 #define AIRO_FLASH(dev) (((struct airo_info *)dev->ml_priv)->flash)
 1285 
 1286 /***********************************************************************
 1287  *                              MIC ROUTINES                           *
 1288  ***********************************************************************
 1289  */
 1290 
 1291 static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq);
 1292 static void MoveWindow(miccntx *context, u32 micSeq);
 1293 static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen,
 1294 			   struct crypto_cipher *tfm);
 1295 static void emmh32_init(emmh32_context *context);
 1296 static void emmh32_update(emmh32_context *context, u8 *pOctets, int len);
 1297 static void emmh32_final(emmh32_context *context, u8 digest[4]);
 1298 static int flashpchar(struct airo_info *ai,int byte,int dwelltime);
 1299 
 1300 static void age_mic_context(miccntx *cur, miccntx *old, u8 *key, int key_len,
 1301 			    struct crypto_cipher *tfm)
 1302 {
 1303 	/* If the current MIC context is valid and its key is the same as
 1304 	 * the MIC register, there's nothing to do.
 1305 	 */
 1306 	if (cur->valid && (memcmp(cur->key, key, key_len) == 0))
 1307 		return;
 1308 
 1309 	/* Age current mic Context */
 1310 	memcpy(old, cur, sizeof(*cur));
 1311 
 1312 	/* Initialize new context */
 1313 	memcpy(cur->key, key, key_len);
 1314 	cur->window  = 33; /* Window always points to the middle */
 1315 	cur->rx      = 0;  /* Rx Sequence numbers */
 1316 	cur->tx      = 0;  /* Tx sequence numbers */
 1317 	cur->valid   = 1;  /* Key is now valid */
 1318 
 1319 	/* Give key to mic seed */
 1320 	emmh32_setseed(&cur->seed, key, key_len, tfm);
 1321 }
 1322 
 1323 /* micinit - Initialize mic seed */
 1324 
 1325 static void micinit(struct airo_info *ai)
 1326 {
 1327 	MICRid mic_rid;
 1328 
 1329 	clear_bit(JOB_MIC, &ai->jobs);
 1330 	PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0);
 1331 	up(&ai->sem);
 1332 
 1333 	ai->micstats.enabled = (le16_to_cpu(mic_rid.state) & 0x00FF) ? 1 : 0;
 1334 	if (!ai->micstats.enabled) {
 1335 		/* So next time we have a valid key and mic is enabled, we will
 1336 		 * update the sequence number if the key is the same as before.
 1337 		 */
 1338 		ai->mod[0].uCtx.valid = 0;
 1339 		ai->mod[0].mCtx.valid = 0;
 1340 		return;
 1341 	}
 1342 
 1343 	if (mic_rid.multicastValid) {
 1344 		age_mic_context(&ai->mod[0].mCtx, &ai->mod[1].mCtx,
 1345 		                mic_rid.multicast, sizeof(mic_rid.multicast),
 1346 		                ai->tfm);
 1347 	}
 1348 
 1349 	if (mic_rid.unicastValid) {
 1350 		age_mic_context(&ai->mod[0].uCtx, &ai->mod[1].uCtx,
 1351 				mic_rid.unicast, sizeof(mic_rid.unicast),
 1352 				ai->tfm);
 1353 	}
 1354 }
 1355 
 1356 /* micsetup - Get ready for business */
 1357 
 1358 static int micsetup(struct airo_info *ai) {
 1359 	int i;
 1360 
 1361 	if (ai->tfm == NULL)
 1362 	        ai->tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
 1363 
 1364         if (IS_ERR(ai->tfm)) {
 1365                 airo_print_err(ai->dev->name, "failed to load transform for AES");
 1366                 ai->tfm = NULL;
 1367                 return ERROR;
 1368         }
 1369 
 1370 	for (i=0; i < NUM_MODULES; i++) {
 1371 		memset(&ai->mod[i].mCtx,0,sizeof(miccntx));
 1372 		memset(&ai->mod[i].uCtx,0,sizeof(miccntx));
 1373 	}
 1374 	return SUCCESS;
 1375 }
 1376 
 1377 static const u8 micsnap[] = {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02};
 1378 
 1379 /*===========================================================================
 1380  * Description: Mic a packet
 1381  *    
 1382  *      Inputs: etherHead * pointer to an 802.3 frame
 1383  *    
 1384  *     Returns: BOOLEAN if successful, otherwise false.
 1385  *             PacketTxLen will be updated with the mic'd packets size.
 1386  *
 1387  *    Caveats: It is assumed that the frame buffer will already
 1388  *             be big enough to hold the largets mic message possible.
 1389  *            (No memory allocation is done here).
 1390  *  
 1391  *    Author: sbraneky (10/15/01)
 1392  *    Merciless hacks by rwilcher (1/14/02)
 1393  */
 1394 
 1395 static int encapsulate(struct airo_info *ai ,etherHead *frame, MICBuffer *mic, int payLen)
 1396 {
 1397 	miccntx   *context;
 1398 
 1399 	// Determine correct context
 1400 	// If not adhoc, always use unicast key
 1401 
 1402 	if (test_bit(FLAG_ADHOC, &ai->flags) && (frame->da[0] & 0x1))
 1403 		context = &ai->mod[0].mCtx;
 1404 	else
 1405 		context = &ai->mod[0].uCtx;
 1406   
 1407 	if (!context->valid)
 1408 		return ERROR;
 1409 
 1410 	mic->typelen = htons(payLen + 16); //Length of Mic'd packet
 1411 
 1412 	memcpy(&mic->u.snap, micsnap, sizeof(micsnap)); // Add Snap
 1413 
 1414 	// Add Tx sequence
 1415 	mic->seq = htonl(context->tx);
 1416 	context->tx += 2;
 1417 
 1418 	emmh32_init(&context->seed); // Mic the packet
 1419 	emmh32_update(&context->seed,frame->da,ETH_ALEN * 2); // DA,SA
 1420 	emmh32_update(&context->seed,(u8*)&mic->typelen,10); // Type/Length and Snap
 1421 	emmh32_update(&context->seed,(u8*)&mic->seq,sizeof(mic->seq)); //SEQ
 1422 	emmh32_update(&context->seed,(u8*)(frame + 1),payLen); //payload
 1423 	emmh32_final(&context->seed, (u8*)&mic->mic);
 1424 
 1425 	/*    New Type/length ?????????? */
 1426 	mic->typelen = 0; //Let NIC know it could be an oversized packet
 1427 	return SUCCESS;
 1428 }
 1429 
 1430 typedef enum {
 1431     NONE,
 1432     NOMIC,
 1433     NOMICPLUMMED,
 1434     SEQUENCE,
 1435     INCORRECTMIC,
 1436 } mic_error;
 1437 
 1438 /*===========================================================================
 1439  *  Description: Decapsulates a MIC'd packet and returns the 802.3 packet
 1440  *               (removes the MIC stuff) if packet is a valid packet.
 1441  *      
 1442  *       Inputs: etherHead  pointer to the 802.3 packet             
 1443  *     
 1444  *      Returns: BOOLEAN - TRUE if packet should be dropped otherwise FALSE
 1445  *     
 1446  *      Author: sbraneky (10/15/01)
 1447  *    Merciless hacks by rwilcher (1/14/02)
 1448  *---------------------------------------------------------------------------
 1449  */
 1450 
 1451 static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *eth, u16 payLen)
 1452 {
 1453 	int      i;
 1454 	u32      micSEQ;
 1455 	miccntx  *context;
 1456 	u8       digest[4];
 1457 	mic_error micError = NONE;
 1458 
 1459 	// Check if the packet is a Mic'd packet
 1460 
 1461 	if (!ai->micstats.enabled) {
 1462 		//No Mic set or Mic OFF but we received a MIC'd packet.
 1463 		if (memcmp ((u8*)eth + 14, micsnap, sizeof(micsnap)) == 0) {
 1464 			ai->micstats.rxMICPlummed++;
 1465 			return ERROR;
 1466 		}
 1467 		return SUCCESS;
 1468 	}
 1469 
 1470 	if (ntohs(mic->typelen) == 0x888E)
 1471 		return SUCCESS;
 1472 
 1473 	if (memcmp (mic->u.snap, micsnap, sizeof(micsnap)) != 0) {
 1474 	    // Mic enabled but packet isn't Mic'd
 1475 		ai->micstats.rxMICPlummed++;
 1476 	    	return ERROR;
 1477 	}
 1478 
 1479 	micSEQ = ntohl(mic->seq);            //store SEQ as CPU order
 1480 
 1481 	//At this point we a have a mic'd packet and mic is enabled
 1482 	//Now do the mic error checking.
 1483 
 1484 	//Receive seq must be odd
 1485 	if ( (micSEQ & 1) == 0 ) {
 1486 		ai->micstats.rxWrongSequence++;
 1487 		return ERROR;
 1488 	}
 1489 
 1490 	for (i = 0; i < NUM_MODULES; i++) {
 1491 		int mcast = eth->da[0] & 1;
 1492 		//Determine proper context 
 1493 		context = mcast ? &ai->mod[i].mCtx : &ai->mod[i].uCtx;
 1494 	
 1495 		//Make sure context is valid
 1496 		if (!context->valid) {
 1497 			if (i == 0)
 1498 				micError = NOMICPLUMMED;
 1499 			continue;                
 1500 		}
 1501 	       	//DeMic it 
 1502 
 1503 		if (!mic->typelen)
 1504 			mic->typelen = htons(payLen + sizeof(MICBuffer) - 2);
 1505 	
 1506 		emmh32_init(&context->seed);
 1507 		emmh32_update(&context->seed, eth->da, ETH_ALEN*2); 
 1508 		emmh32_update(&context->seed, (u8 *)&mic->typelen, sizeof(mic->typelen)+sizeof(mic->u.snap)); 
 1509 		emmh32_update(&context->seed, (u8 *)&mic->seq,sizeof(mic->seq));	
 1510 		emmh32_update(&context->seed, (u8 *)(eth + 1),payLen);	
 1511 		//Calculate MIC
 1512 		emmh32_final(&context->seed, digest);
 1513 	
 1514 		if (memcmp(digest, &mic->mic, 4)) { //Make sure the mics match
 1515 		  //Invalid Mic
 1516 			if (i == 0)
 1517 				micError = INCORRECTMIC;
 1518 			continue;
 1519 		}
 1520 
 1521 		//Check Sequence number if mics pass
 1522 		if (RxSeqValid(ai, context, mcast, micSEQ) == SUCCESS) {
 1523 			ai->micstats.rxSuccess++;
 1524 			return SUCCESS;
 1525 		}
 1526 		if (i == 0)
 1527 			micError = SEQUENCE;
 1528 	}
 1529 
 1530 	// Update statistics
 1531 	switch (micError) {
 1532 		case NOMICPLUMMED: ai->micstats.rxMICPlummed++;   break;
 1533 		case SEQUENCE:    ai->micstats.rxWrongSequence++; break;
 1534 		case INCORRECTMIC: ai->micstats.rxIncorrectMIC++; break;
 1535 		case NONE:  break;
 1536 		case NOMIC: break;
 1537 	}
 1538 	return ERROR;
 1539 }
 1540 
 1541 /*===========================================================================
 1542  * Description:  Checks the Rx Seq number to make sure it is valid
 1543  *               and hasn't already been received
 1544  *   
 1545  *     Inputs: miccntx - mic context to check seq against
 1546  *             micSeq  - the Mic seq number
 1547  *   
 1548  *    Returns: TRUE if valid otherwise FALSE. 
 1549  *
 1550  *    Author: sbraneky (10/15/01)
 1551  *    Merciless hacks by rwilcher (1/14/02)
 1552  *---------------------------------------------------------------------------
 1553  */
 1554 
 1555 static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq)
 1556 {
 1557 	u32 seq,index;
 1558 
 1559 	//Allow for the ap being rebooted - if it is then use the next 
 1560 	//sequence number of the current sequence number - might go backwards
 1561 
 1562 	if (mcast) {
 1563 		if (test_bit(FLAG_UPDATE_MULTI, &ai->flags)) {
 1564 			clear_bit (FLAG_UPDATE_MULTI, &ai->flags);
 1565 			context->window = (micSeq > 33) ? micSeq : 33;
 1566 			context->rx     = 0;        // Reset rx
 1567 		}
 1568 	} else if (test_bit(FLAG_UPDATE_UNI, &ai->flags)) {
 1569 		clear_bit (FLAG_UPDATE_UNI, &ai->flags);
 1570 		context->window = (micSeq > 33) ? micSeq : 33; // Move window
 1571 		context->rx     = 0;        // Reset rx
 1572 	}
 1573 
 1574 	//Make sequence number relative to START of window
 1575 	seq = micSeq - (context->window - 33);
 1576 
 1577 	//Too old of a SEQ number to check.
 1578 	if ((s32)seq < 0)
 1579 		return ERROR;
 1580     
 1581 	if ( seq > 64 ) {
 1582 		//Window is infinite forward
 1583 		MoveWindow(context,micSeq);
 1584 		return SUCCESS;
 1585 	}
 1586 
 1587 	// We are in the window. Now check the context rx bit to see if it was already sent
 1588 	seq >>= 1;         //divide by 2 because we only have odd numbers
 1589 	index = 1 << seq;  //Get an index number
 1590 
 1591 	if (!(context->rx & index)) {
 1592 		//micSEQ falls inside the window.
 1593 		//Add seqence number to the list of received numbers.
 1594 		context->rx |= index;
 1595 
 1596 		MoveWindow(context,micSeq);
 1597 
 1598 		return SUCCESS;
 1599 	}
 1600 	return ERROR;
 1601 }
 1602 
 1603 static void MoveWindow(miccntx *context, u32 micSeq)
 1604 {
 1605 	u32 shift;
 1606 
 1607 	//Move window if seq greater than the middle of the window
 1608 	if (micSeq > context->window) {
 1609 		shift = (micSeq - context->window) >> 1;
 1610     
 1611 		    //Shift out old
 1612 		if (shift < 32)
 1613 			context->rx >>= shift;
 1614 		else
 1615 			context->rx = 0;
 1616 
 1617 		context->window = micSeq;      //Move window
 1618 	}
 1619 }
 1620 
 1621 /*==============================================*/
 1622 /*========== EMMH ROUTINES  ====================*/
 1623 /*==============================================*/
 1624 
 1625 /* mic accumulate */
 1626 #define MIC_ACCUM(val)	\
 1627 	context->accum += (u64)(val) * context->coeff[coeff_position++];
 1628 
 1629 static unsigned char aes_counter[16];
 1630 
 1631 /* expand the key to fill the MMH coefficient array */
 1632 static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen,
 1633 			   struct crypto_cipher *tfm)
 1634 {
 1635   /* take the keying material, expand if necessary, truncate at 16-bytes */
 1636   /* run through AES counter mode to generate context->coeff[] */
 1637   
 1638 	int i,j;
 1639 	u32 counter;
 1640 	u8 *cipher, plain[16];
 1641 
 1642 	crypto_cipher_setkey(tfm, pkey, 16);
 1643 	counter = 0;
 1644 	for (i = 0; i < ARRAY_SIZE(context->coeff); ) {
 1645 		aes_counter[15] = (u8)(counter >> 0);
 1646 		aes_counter[14] = (u8)(counter >> 8);
 1647 		aes_counter[13] = (u8)(counter >> 16);
 1648 		aes_counter[12] = (u8)(counter >> 24);
 1649 		counter++;
 1650 		memcpy (plain, aes_counter, 16);
 1651 		crypto_cipher_encrypt_one(tfm, plain, plain);
 1652 		cipher = plain;
 1653 		for (j = 0; (j < 16) && (i < ARRAY_SIZE(context->coeff)); ) {
 1654 			context->coeff[i++] = ntohl(*(__be32 *)&cipher[j]);
 1655 			j += 4;
 1656 		}
 1657 	}
 1658 }
 1659 
 1660 /* prepare for calculation of a new mic */
 1661 static void emmh32_init(emmh32_context *context)
 1662 {
 1663 	/* prepare for new mic calculation */
 1664 	context->accum = 0;
 1665 	context->position = 0;
 1666 }
 1667 
 1668 /* add some bytes to the mic calculation */
 1669 static void emmh32_update(emmh32_context *context, u8 *pOctets, int len)
 1670 {
 1671 	int	coeff_position, byte_position;
 1672   
 1673 	if (len == 0) return;
 1674   
 1675 	coeff_position = context->position >> 2;
 1676   
 1677 	/* deal with partial 32-bit word left over from last update */
 1678 	byte_position = context->position & 3;
 1679 	if (byte_position) {
 1680 		/* have a partial word in part to deal with */
 1681 		do {
 1682 			if (len == 0) return;
 1683 			context->part.d8[byte_position++] = *pOctets++;
 1684 			context->position++;
 1685 			len--;
 1686 		} while (byte_position < 4);
 1687 		MIC_ACCUM(ntohl(context->part.d32));
 1688 	}
 1689 
 1690 	/* deal with full 32-bit words */
 1691 	while (len >= 4) {
 1692 		MIC_ACCUM(ntohl(*(__be32 *)pOctets));
 1693 		context->position += 4;
 1694 		pOctets += 4;
 1695 		len -= 4;
 1696 	}
 1697 
 1698 	/* deal with partial 32-bit word that will be left over from this update */
 1699 	byte_position = 0;
 1700 	while (len > 0) {
 1701 		context->part.d8[byte_position++] = *pOctets++;
 1702 		context->position++;
 1703 		len--;
 1704 	}
 1705 }
 1706 
 1707 /* mask used to zero empty bytes for final partial word */
 1708 static u32 mask32[4] = { 0x00000000L, 0xFF000000L, 0xFFFF0000L, 0xFFFFFF00L };
 1709 
 1710 /* calculate the mic */
 1711 static void emmh32_final(emmh32_context *context, u8 digest[4])
 1712 {
 1713 	int	coeff_position, byte_position;
 1714 	u32	val;
 1715   
 1716 	u64 sum, utmp;
 1717 	s64 stmp;
 1718 
 1719 	coeff_position = context->position >> 2;
 1720   
 1721 	/* deal with partial 32-bit word left over from last update */
 1722 	byte_position = context->position & 3;
 1723 	if (byte_position) {
 1724 		/* have a partial word in part to deal with */
 1725 		val = ntohl(context->part.d32);
 1726 		MIC_ACCUM(val & mask32[byte_position]);	/* zero empty bytes */
 1727 	}
 1728 
 1729 	/* reduce the accumulated u64 to a 32-bit MIC */
 1730 	sum = context->accum;
 1731 	stmp = (sum  & 0xffffffffLL) - ((sum >> 32)  * 15);
 1732 	utmp = (stmp & 0xffffffffLL) - ((stmp >> 32) * 15);
 1733 	sum = utmp & 0xffffffffLL;
 1734 	if (utmp > 0x10000000fLL)
 1735 		sum -= 15;
 1736 
 1737 	val = (u32)sum;
 1738 	digest[0] = (val>>24) & 0xFF;
 1739 	digest[1] = (val>>16) & 0xFF;
 1740 	digest[2] = (val>>8) & 0xFF;
 1741 	digest[3] = val & 0xFF;
 1742 }
 1743 
 1744 static int readBSSListRid(struct airo_info *ai, int first,
 1745 		      BSSListRid *list)
 1746 {
 1747 	Cmd cmd;
 1748 	Resp rsp;
 1749 
 1750 	if (first == 1) {
 1751 		if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
 1752 		memset(&cmd, 0, sizeof(cmd));
 1753 		cmd.cmd=CMD_LISTBSS;
 1754 		if (down_interruptible(&ai->sem))
 1755 			return -ERESTARTSYS;
 1756 		ai->list_bss_task = current;
 1757 		issuecommand(ai, &cmd, &rsp);
 1758 		up(&ai->sem);
 1759 		/* Let the command take effect */
 1760 		schedule_timeout_uninterruptible(3 * HZ);
 1761 		ai->list_bss_task = NULL;
 1762 	}
 1763 	return PC4500_readrid(ai, first ? ai->bssListFirst : ai->bssListNext,
 1764 			    list, ai->bssListRidLen, 1);
 1765 }
 1766 
 1767 static int readWepKeyRid(struct airo_info *ai, WepKeyRid *wkr, int temp, int lock)
 1768 {
 1769 	return PC4500_readrid(ai, temp ? RID_WEP_TEMP : RID_WEP_PERM,
 1770 				wkr, sizeof(*wkr), lock);
 1771 }
 1772 
 1773 static int writeWepKeyRid(struct airo_info *ai, WepKeyRid *wkr, int perm, int lock)
 1774 {
 1775 	int rc;
 1776 	rc = PC4500_writerid(ai, RID_WEP_TEMP, wkr, sizeof(*wkr), lock);
 1777 	if (rc!=SUCCESS)
 1778 		airo_print_err(ai->dev->name, "WEP_TEMP set %x", rc);
 1779 	if (perm) {
 1780 		rc = PC4500_writerid(ai, RID_WEP_PERM, wkr, sizeof(*wkr), lock);
 1781 		if (rc!=SUCCESS)
 1782 			airo_print_err(ai->dev->name, "WEP_PERM set %x", rc);
 1783 	}
 1784 	return rc;
 1785 }
 1786 
 1787 static int readSsidRid(struct airo_info*ai, SsidRid *ssidr)
 1788 {
 1789 	return PC4500_readrid(ai, RID_SSID, ssidr, sizeof(*ssidr), 1);
 1790 }
 1791 
 1792 static int writeSsidRid(struct airo_info*ai, SsidRid *pssidr, int lock)
 1793 {
 1794 	return PC4500_writerid(ai, RID_SSID, pssidr, sizeof(*pssidr), lock);
 1795 }
 1796 
 1797 static int readConfigRid(struct airo_info *ai, int lock)
 1798 {
 1799 	int rc;
 1800 	ConfigRid cfg;
 1801 
 1802 	if (ai->config.len)
 1803 		return SUCCESS;
 1804 
 1805 	rc = PC4500_readrid(ai, RID_ACTUALCONFIG, &cfg, sizeof(cfg), lock);
 1806 	if (rc != SUCCESS)
 1807 		return rc;
 1808 
 1809 	ai->config = cfg;
 1810 	return SUCCESS;
 1811 }
 1812 
 1813 static inline void checkThrottle(struct airo_info *ai)
 1814 {
 1815 	int i;
 1816 /* Old hardware had a limit on encryption speed */
 1817 	if (ai->config.authType != AUTH_OPEN && maxencrypt) {
 1818 		for(i=0; i<8; i++) {
 1819 			if (ai->config.rates[i] > maxencrypt) {
 1820 				ai->config.rates[i] = 0;
 1821 			}
 1822 		}
 1823 	}
 1824 }
 1825 
 1826 static int writeConfigRid(struct airo_info *ai, int lock)
 1827 {
 1828 	ConfigRid cfgr;
 1829 
 1830 	if (!test_bit (FLAG_COMMIT, &ai->flags))
 1831 		return SUCCESS;
 1832 
 1833 	clear_bit (FLAG_COMMIT, &ai->flags);
 1834 	clear_bit (FLAG_RESET, &ai->flags);
 1835 	checkThrottle(ai);
 1836 	cfgr = ai->config;
 1837 
 1838 	if ((cfgr.opmode & MODE_CFG_MASK) == MODE_STA_IBSS)
 1839 		set_bit(FLAG_ADHOC, &ai->flags);
 1840 	else
 1841 		clear_bit(FLAG_ADHOC, &ai->flags);
 1842 
 1843 	return PC4500_writerid( ai, RID_CONFIG, &cfgr, sizeof(cfgr), lock);
 1844 }
 1845 
 1846 static int readStatusRid(struct airo_info *ai, StatusRid *statr, int lock)
 1847 {
 1848 	return PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr), lock);
 1849 }
 1850 
 1851 static int writeAPListRid(struct airo_info *ai, APListRid *aplr, int lock)
 1852 {
 1853 	return PC4500_writerid(ai, RID_APLIST, aplr, sizeof(*aplr), lock);
 1854 }
 1855 
 1856 static int readCapabilityRid(struct airo_info *ai, CapabilityRid *capr, int lock)
 1857 {
 1858 	return PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr), lock);
 1859 }
 1860 
 1861 static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock)
 1862 {
 1863 	return PC4500_readrid(ai, rid, sr, sizeof(*sr), lock);
 1864 }
 1865 
 1866 static void try_auto_wep(struct airo_info *ai)
 1867 {
 1868 	if (auto_wep && !test_bit(FLAG_RADIO_DOWN, &ai->flags)) {
 1869 		ai->expires = RUN_AT(3*HZ);
 1870 		wake_up_interruptible(&ai->thr_wait);
 1871 	}
 1872 }
 1873 
 1874 static int airo_open(struct net_device *dev) {
 1875 	struct airo_info *ai = dev->ml_priv;
 1876 	int rc = 0;
 1877 
 1878 	if (test_bit(FLAG_FLASHING, &ai->flags))
 1879 		return -EIO;
 1880 
 1881 	/* Make sure the card is configured.
 1882 	 * Wireless Extensions may postpone config changes until the card
 1883 	 * is open (to pipeline changes and speed-up card setup). If
 1884 	 * those changes are not yet committed, do it now - Jean II */
 1885 	if (test_bit(FLAG_COMMIT, &ai->flags)) {
 1886 		disable_MAC(ai, 1);
 1887 		writeConfigRid(ai, 1);
 1888 	}
 1889 
 1890 	if (ai->wifidev != dev) {
 1891 		clear_bit(JOB_DIE, &ai->jobs);
 1892 		ai->airo_thread_task = kthread_run(airo_thread, dev, "%s",
 1893 						   dev->name);
 1894 		if (IS_ERR(ai->airo_thread_task))
 1895 			return (int)PTR_ERR(ai->airo_thread_task);
 1896 
 1897 		rc = request_irq(dev->irq, airo_interrupt, IRQF_SHARED,
 1898 			dev->name, dev);
 1899 		if (rc) {
 1900 			airo_print_err(dev->name,
 1901 				"register interrupt %d failed, rc %d",
 1902 				dev->irq, rc);
 1903 			set_bit(JOB_DIE, &ai->jobs);
 1904 			kthread_stop(ai->airo_thread_task);
 1905 			return rc;
 1906 		}
 1907 
 1908 		/* Power on the MAC controller (which may have been disabled) */
 1909 		clear_bit(FLAG_RADIO_DOWN, &ai->flags);
 1910 		enable_interrupts(ai);
 1911 
 1912 		try_auto_wep(ai);
 1913 	}
 1914 	enable_MAC(ai, 1);
 1915 
 1916 	netif_start_queue(dev);
 1917 	return 0;
 1918 }
 1919 
 1920 static netdev_tx_t mpi_start_xmit(struct sk_buff *skb,
 1921 					struct net_device *dev)
 1922 {
 1923 	int npacks, pending;
 1924 	unsigned long flags;
 1925 	struct airo_info *ai = dev->ml_priv;
 1926 
 1927 	if (!skb) {
 1928 		airo_print_err(dev->name, "%s: skb == NULL!",__func__);
 1929 		return NETDEV_TX_OK;
 1930 	}
 1931 	npacks = skb_queue_len (&ai->txq);
 1932 
 1933 	if (npacks >= MAXTXQ - 1) {
 1934 		netif_stop_queue (dev);
 1935 		if (npacks > MAXTXQ) {
 1936 			dev->stats.tx_fifo_errors++;
 1937 			return NETDEV_TX_BUSY;
 1938 		}
 1939 		skb_queue_tail (&ai->txq, skb);
 1940 		return NETDEV_TX_OK;
 1941 	}
 1942 
 1943 	spin_lock_irqsave(&ai->aux_lock, flags);
 1944 	skb_queue_tail (&ai->txq, skb);
 1945 	pending = test_bit(FLAG_PENDING_XMIT, &ai->flags);
 1946 	spin_unlock_irqrestore(&ai->aux_lock,flags);
 1947 	netif_wake_queue (dev);
 1948 
 1949 	if (pending == 0) {
 1950 		set_bit(FLAG_PENDING_XMIT, &ai->flags);
 1951 		mpi_send_packet (dev);
 1952 	}
 1953 	return NETDEV_TX_OK;
 1954 }
 1955 
 1956 /*
 1957  * @mpi_send_packet
 1958  *
 1959  * Attempt to transmit a packet. Can be called from interrupt
 1960  * or transmit . return number of packets we tried to send
 1961  */
 1962 
 1963 static int mpi_send_packet (struct net_device *dev)
 1964 {
 1965 	struct sk_buff *skb;
 1966 	unsigned char *buffer;
 1967 	s16 len;
 1968 	__le16 *payloadLen;
 1969 	struct airo_info *ai = dev->ml_priv;
 1970 	u8 *sendbuf;
 1971 
 1972 	/* get a packet to send */
 1973 
 1974 	if ((skb = skb_dequeue(&ai->txq)) == NULL) {
 1975 		airo_print_err(dev->name,
 1976 			"%s: Dequeue'd zero in send_packet()",
 1977 			__func__);
 1978 		return 0;
 1979 	}
 1980 
 1981 	/* check min length*/
 1982 	len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
 1983 	buffer = skb->data;
 1984 
 1985 	ai->txfids[0].tx_desc.offset = 0;
 1986 	ai->txfids[0].tx_desc.valid = 1;
 1987 	ai->txfids[0].tx_desc.eoc = 1;
 1988 	ai->txfids[0].tx_desc.len =len+sizeof(WifiHdr);
 1989 
 1990 /*
 1991  * Magic, the cards firmware needs a length count (2 bytes) in the host buffer
 1992  * right after  TXFID_HDR.The TXFID_HDR contains the status short so payloadlen
 1993  * is immediately after it. ------------------------------------------------
 1994  *                         |TXFIDHDR+STATUS|PAYLOADLEN|802.3HDR|PACKETDATA|
 1995  *                         ------------------------------------------------
 1996  */
 1997 
 1998 	memcpy(ai->txfids[0].virtual_host_addr,
 1999 		(char *)&wifictlhdr8023, sizeof(wifictlhdr8023));
 2000 
 2001 	payloadLen = (__le16 *)(ai->txfids[0].virtual_host_addr +
 2002 		sizeof(wifictlhdr8023));
 2003 	sendbuf = ai->txfids[0].virtual_host_addr +
 2004 		sizeof(wifictlhdr8023) + 2 ;
 2005 
 2006 	/*
 2007 	 * Firmware automatically puts 802 header on so
 2008 	 * we don't need to account for it in the length
 2009 	 */
 2010 	if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled &&
 2011 		(ntohs(((__be16 *)buffer)[6]) != 0x888E)) {
 2012 		MICBuffer pMic;
 2013 
 2014 		if (encapsulate(ai, (etherHead *)buffer, &pMic, len - sizeof(etherHead)) != SUCCESS)
 2015 			return ERROR;
 2016 
 2017 		*payloadLen = cpu_to_le16(len-sizeof(etherHead)+sizeof(pMic));
 2018 		ai->txfids[0].tx_desc.len += sizeof(pMic);
 2019 		/* copy data into airo dma buffer */
 2020 		memcpy (sendbuf, buffer, sizeof(etherHead));
 2021 		buffer += sizeof(etherHead);
 2022 		sendbuf += sizeof(etherHead);
 2023 		memcpy (sendbuf, &pMic, sizeof(pMic));
 2024 		sendbuf += sizeof(pMic);
 2025 		memcpy (sendbuf, buffer, len - sizeof(etherHead));
 2026 	} else {
 2027 		*payloadLen = cpu_to_le16(len - sizeof(etherHead));
 2028 
 2029 		dev->trans_start = jiffies;
 2030 
 2031 		/* copy data into airo dma buffer */
 2032 		memcpy(sendbuf, buffer, len);
 2033 	}
 2034 
 2035 	memcpy_toio(ai->txfids[0].card_ram_off,
 2036 		&ai->txfids[0].tx_desc, sizeof(TxFid));
 2037 
 2038 	OUT4500(ai, EVACK, 8);
 2039 
 2040 	dev_kfree_skb_any(skb);
 2041 	return 1;
 2042 }
 2043 
 2044 static void get_tx_error(struct airo_info *ai, s32 fid)
 2045 {
 2046 	__le16 status;
 2047 
 2048 	if (fid < 0)
 2049 		status = ((WifiCtlHdr *)ai->txfids[0].virtual_host_addr)->ctlhdr.status;
 2050 	else {
 2051 		if (bap_setup(ai, ai->fids[fid] & 0xffff, 4, BAP0) != SUCCESS)
 2052 			return;
 2053 		bap_read(ai, &status, 2, BAP0);
 2054 	}
 2055 	if (le16_to_cpu(status) & 2) /* Too many retries */
 2056 		ai->dev->stats.tx_aborted_errors++;
 2057 	if (le16_to_cpu(status) & 4) /* Transmit lifetime exceeded */
 2058 		ai->dev->stats.tx_heartbeat_errors++;
 2059 	if (le16_to_cpu(status) & 8) /* Aid fail */
 2060 		{ }
 2061 	if (le16_to_cpu(status) & 0x10) /* MAC disabled */
 2062 		ai->dev->stats.tx_carrier_errors++;
 2063 	if (le16_to_cpu(status) & 0x20) /* Association lost */
 2064 		{ }
 2065 	/* We produce a TXDROP event only for retry or lifetime
 2066 	 * exceeded, because that's the only status that really mean
 2067 	 * that this particular node went away.
 2068 	 * Other errors means that *we* screwed up. - Jean II */
 2069 	if ((le16_to_cpu(status) & 2) ||
 2070 	     (le16_to_cpu(status) & 4)) {
 2071 		union iwreq_data	wrqu;
 2072 		char junk[0x18];
 2073 
 2074 		/* Faster to skip over useless data than to do
 2075 		 * another bap_setup(). We are at offset 0x6 and
 2076 		 * need to go to 0x18 and read 6 bytes - Jean II */
 2077 		bap_read(ai, (__le16 *) junk, 0x18, BAP0);
 2078 
 2079 		/* Copy 802.11 dest address.
 2080 		 * We use the 802.11 header because the frame may
 2081 		 * not be 802.3 or may be mangled...
 2082 		 * In Ad-Hoc mode, it will be the node address.
 2083 		 * In managed mode, it will be most likely the AP addr
 2084 		 * User space will figure out how to convert it to
 2085 		 * whatever it needs (IP address or else).
 2086 		 * - Jean II */
 2087 		memcpy(wrqu.addr.sa_data, junk + 0x12, ETH_ALEN);
 2088 		wrqu.addr.sa_family = ARPHRD_ETHER;
 2089 
 2090 		/* Send event to user space */
 2091 		wireless_send_event(ai->dev, IWEVTXDROP, &wrqu, NULL);
 2092 	}
 2093 }
 2094 
 2095 static void airo_end_xmit(struct net_device *dev) {
 2096 	u16 status;
 2097 	int i;
 2098 	struct airo_info *priv = dev->ml_priv;
 2099 	struct sk_buff *skb = priv->xmit.skb;
 2100 	int fid = priv->xmit.fid;
 2101 	u32 *fids = priv->fids;
 2102 
 2103 	clear_bit(JOB_XMIT, &priv->jobs);
 2104 	clear_bit(FLAG_PENDING_XMIT, &priv->flags);
 2105 	status = transmit_802_3_packet (priv, fids[fid], skb->data);
 2106 	up(&priv->sem);
 2107 
 2108 	i = 0;
 2109 	if ( status == SUCCESS ) {
 2110 		dev->trans_start = jiffies;
 2111 		for (; i < MAX_FIDS / 2 && (priv->fids[i] & 0xffff0000); i++);
 2112 	} else {
 2113 		priv->fids[fid] &= 0xffff;
 2114 		dev->stats.tx_window_errors++;
 2115 	}
 2116 	if (i < MAX_FIDS / 2)
 2117 		netif_wake_queue(dev);
 2118 	dev_kfree_skb(skb);
 2119 }
 2120 
 2121 static netdev_tx_t airo_start_xmit(struct sk_buff *skb,
 2122 					 struct net_device *dev)
 2123 {
 2124 	s16 len;
 2125 	int i, j;
 2126 	struct airo_info *priv = dev->ml_priv;
 2127 	u32 *fids = priv->fids;
 2128 
 2129 	if ( skb == NULL ) {
 2130 		airo_print_err(dev->name, "%s: skb == NULL!", __func__);
 2131 		return NETDEV_TX_OK;
 2132 	}
 2133 
 2134 	/* Find a vacant FID */
 2135 	for( i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++ );
 2136 	for( j = i + 1; j < MAX_FIDS / 2 && (fids[j] & 0xffff0000); j++ );
 2137 
 2138 	if ( j >= MAX_FIDS / 2 ) {
 2139 		netif_stop_queue(dev);
 2140 
 2141 		if (i == MAX_FIDS / 2) {
 2142 			dev->stats.tx_fifo_errors++;
 2143 			return NETDEV_TX_BUSY;
 2144 		}
 2145 	}
 2146 	/* check min length*/
 2147 	len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
 2148         /* Mark fid as used & save length for later */
 2149 	fids[i] |= (len << 16);
 2150 	priv->xmit.skb = skb;
 2151 	priv->xmit.fid = i;
 2152 	if (down_trylock(&priv->sem) != 0) {
 2153 		set_bit(FLAG_PENDING_XMIT, &priv->flags);
 2154 		netif_stop_queue(dev);
 2155 		set_bit(JOB_XMIT, &priv->jobs);
 2156 		wake_up_interruptible(&priv->thr_wait);
 2157 	} else
 2158 		airo_end_xmit(dev);
 2159 	return NETDEV_TX_OK;
 2160 }
 2161 
 2162 static void airo_end_xmit11(struct net_device *dev) {
 2163 	u16 status;
 2164 	int i;
 2165 	struct airo_info *priv = dev->ml_priv;
 2166 	struct sk_buff *skb = priv->xmit11.skb;
 2167 	int fid = priv->xmit11.fid;
 2168 	u32 *fids = priv->fids;
 2169 
 2170 	clear_bit(JOB_XMIT11, &priv->jobs);
 2171 	clear_bit(FLAG_PENDING_XMIT11, &priv->flags);
 2172 	status = transmit_802_11_packet (priv, fids[fid], skb->data);
 2173 	up(&priv->sem);
 2174 
 2175 	i = MAX_FIDS / 2;
 2176 	if ( status == SUCCESS ) {
 2177 		dev->trans_start = jiffies;
 2178 		for (; i < MAX_FIDS && (priv->fids[i] & 0xffff0000); i++);
 2179 	} else {
 2180 		priv->fids[fid] &= 0xffff;
 2181 		dev->stats.tx_window_errors++;
 2182 	}
 2183 	if (i < MAX_FIDS)
 2184 		netif_wake_queue(dev);
 2185 	dev_kfree_skb(skb);
 2186 }
 2187 
 2188 static netdev_tx_t airo_start_xmit11(struct sk_buff *skb,
 2189 					   struct net_device *dev)
 2190 {
 2191 	s16 len;
 2192 	int i, j;
 2193 	struct airo_info *priv = dev->ml_priv;
 2194 	u32 *fids = priv->fids;
 2195 
 2196 	if (test_bit(FLAG_MPI, &priv->flags)) {
 2197 		/* Not implemented yet for MPI350 */
 2198 		netif_stop_queue(dev);
 2199 		dev_kfree_skb_any(skb);
 2200 		return NETDEV_TX_OK;
 2201 	}
 2202 
 2203 	if ( skb == NULL ) {
 2204 		airo_print_err(dev->name, "%s: skb == NULL!", __func__);
 2205 		return NETDEV_TX_OK;
 2206 	}
 2207 
 2208 	/* Find a vacant FID */
 2209 	for( i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++ );
 2210 	for( j = i + 1; j < MAX_FIDS && (fids[j] & 0xffff0000); j++ );
 2211 
 2212 	if ( j >= MAX_FIDS ) {
 2213 		netif_stop_queue(dev);
 2214 
 2215 		if (i == MAX_FIDS) {
 2216 			dev->stats.tx_fifo_errors++;
 2217 			return NETDEV_TX_BUSY;
 2218 		}
 2219 	}
 2220 	/* check min length*/
 2221 	len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
 2222         /* Mark fid as used & save length for later */
 2223 	fids[i] |= (len << 16);
 2224 	priv->xmit11.skb = skb;
 2225 	priv->xmit11.fid = i;
 2226 	if (down_trylock(&priv->sem) != 0) {
 2227 		set_bit(FLAG_PENDING_XMIT11, &priv->flags);
 2228 		netif_stop_queue(dev);
 2229 		set_bit(JOB_XMIT11, &priv->jobs);
 2230 		wake_up_interruptible(&priv->thr_wait);
 2231 	} else
 2232 		airo_end_xmit11(dev);
 2233 	return NETDEV_TX_OK;
 2234 }
 2235 
 2236 static void airo_read_stats(struct net_device *dev)
 2237 {
 2238 	struct airo_info *ai = dev->ml_priv;
 2239 	StatsRid stats_rid;
 2240 	__le32 *vals = stats_rid.vals;
 2241 
 2242 	clear_bit(JOB_STATS, &ai->jobs);
 2243 	if (ai->power.event) {
 2244 		up(&ai->sem);
 2245 		return;
 2246 	}
 2247 	readStatsRid(ai, &stats_rid, RID_STATS, 0);
 2248 	up(&ai->sem);
 2249 
 2250 	dev->stats.rx_packets = le32_to_cpu(vals[43]) + le32_to_cpu(vals[44]) +
 2251 			       le32_to_cpu(vals[45]);
 2252 	dev->stats.tx_packets = le32_to_cpu(vals[39]) + le32_to_cpu(vals[40]) +
 2253 			       le32_to_cpu(vals[41]);
 2254 	dev->stats.rx_bytes = le32_to_cpu(vals[92]);
 2255 	dev->stats.tx_bytes = le32_to_cpu(vals[91]);
 2256 	dev->stats.rx_errors = le32_to_cpu(vals[0]) + le32_to_cpu(vals[2]) +
 2257 			      le32_to_cpu(vals[3]) + le32_to_cpu(vals[4]);
 2258 	dev->stats.tx_errors = le32_to_cpu(vals[42]) +
 2259 			      dev->stats.tx_fifo_errors;
 2260 	dev->stats.multicast = le32_to_cpu(vals[43]);
 2261 	dev->stats.collisions = le32_to_cpu(vals[89]);
 2262 
 2263 	/* detailed rx_errors: */
 2264 	dev->stats.rx_length_errors = le32_to_cpu(vals[3]);
 2265 	dev->stats.rx_crc_errors = le32_to_cpu(vals[4]);
 2266 	dev->stats.rx_frame_errors = le32_to_cpu(vals[2]);
 2267 	dev->stats.rx_fifo_errors = le32_to_cpu(vals[0]);
 2268 }
 2269 
 2270 static struct net_device_stats *airo_get_stats(struct net_device *dev)
 2271 {
 2272 	struct airo_info *local =  dev->ml_priv;
 2273 
 2274 	if (!test_bit(JOB_STATS, &local->jobs)) {
 2275 		/* Get stats out of the card if available */
 2276 		if (down_trylock(&local->sem) != 0) {
 2277 			set_bit(JOB_STATS, &local->jobs);
 2278 			wake_up_interruptible(&local->thr_wait);
 2279 		} else
 2280 			airo_read_stats(dev);
 2281 	}
 2282 
 2283 	return &dev->stats;
 2284 }
 2285 
 2286 static void airo_set_promisc(struct airo_info *ai) {
 2287 	Cmd cmd;
 2288 	Resp rsp;
 2289 
 2290 	memset(&cmd, 0, sizeof(cmd));
 2291 	cmd.cmd=CMD_SETMODE;
 2292 	clear_bit(JOB_PROMISC, &ai->jobs);
 2293 	cmd.parm0=(ai->flags&IFF_PROMISC) ? PROMISC : NOPROMISC;
 2294 	issuecommand(ai, &cmd, &rsp);
 2295 	up(&ai->sem);
 2296 }
 2297 
 2298 static void airo_set_multicast_list(struct net_device *dev) {
 2299 	struct airo_info *ai = dev->ml_priv;
 2300 
 2301 	if ((dev->flags ^ ai->flags) & IFF_PROMISC) {
 2302 		change_bit(FLAG_PROMISC, &ai->flags);
 2303 		if (down_trylock(&ai->sem) != 0) {
 2304 			set_bit(JOB_PROMISC, &ai->jobs);
 2305 			wake_up_interruptible(&ai->thr_wait);
 2306 		} else
 2307 			airo_set_promisc(ai);
 2308 	}
 2309 
 2310 	if ((dev->flags&IFF_ALLMULTI) || !netdev_mc_empty(dev)) {
 2311 		/* Turn on multicast.  (Should be already setup...) */
 2312 	}
 2313 }
 2314 
 2315 static int airo_set_mac_address(struct net_device *dev, void *p)
 2316 {
 2317 	struct airo_info *ai = dev->ml_priv;
 2318 	struct sockaddr *addr = p;
 2319 
 2320 	readConfigRid(ai, 1);
 2321 	memcpy (ai->config.macAddr, addr->sa_data, dev->addr_len);
 2322 	set_bit (FLAG_COMMIT, &ai->flags);
 2323 	disable_MAC(ai, 1);
 2324 	writeConfigRid (ai, 1);
 2325 	enable_MAC(ai, 1);
 2326 	memcpy (ai->dev->dev_addr, addr->sa_data, dev->addr_len);
 2327 	if (ai->wifidev)
 2328 		memcpy (ai->wifidev->dev_addr, addr->sa_data, dev->addr_len);
 2329 	return 0;
 2330 }
 2331 
 2332 static int airo_change_mtu(struct net_device *dev, int new_mtu)
 2333 {
 2334 	if ((new_mtu < 68) || (new_mtu > 2400))
 2335 		return -EINVAL;
 2336 	dev->mtu = new_mtu;
 2337 	return 0;
 2338 }
 2339 
 2340 static LIST_HEAD(airo_devices);
 2341 
 2342 static void add_airo_dev(struct airo_info *ai)
 2343 {
 2344 	/* Upper layers already keep track of PCI devices,
 2345 	 * so we only need to remember our non-PCI cards. */
 2346 	if (!ai->pci)
 2347 		list_add_tail(&ai->dev_list, &airo_devices);
 2348 }
 2349 
 2350 static void del_airo_dev(struct airo_info *ai)
 2351 {
 2352 	if (!ai->pci)
 2353 		list_del(&ai->dev_list);
 2354 }
 2355 
 2356 static int airo_close(struct net_device *dev) {
 2357 	struct airo_info *ai = dev->ml_priv;
 2358 
 2359 	netif_stop_queue(dev);
 2360 
 2361 	if (ai->wifidev != dev) {
 2362 #ifdef POWER_ON_DOWN
 2363 		/* Shut power to the card. The idea is that the user can save
 2364 		 * power when he doesn't need the card with "ifconfig down".
 2365 		 * That's the method that is most friendly towards the network
 2366 		 * stack (i.e. the network stack won't try to broadcast
 2367 		 * anything on the interface and routes are gone. Jean II */
 2368 		set_bit(FLAG_RADIO_DOWN, &ai->flags);
 2369 		disable_MAC(ai, 1);
 2370 #endif
 2371 		disable_interrupts( ai );
 2372 
 2373 		free_irq(dev->irq, dev);
 2374 
 2375 		set_bit(JOB_DIE, &ai->jobs);
 2376 		kthread_stop(ai->airo_thread_task);
 2377 	}
 2378 	return 0;
 2379 }
 2380 
 2381 void stop_airo_card( struct net_device *dev, int freeres )
 2382 {
 2383 	struct airo_info *ai = dev->ml_priv;
 2384 
 2385 	set_bit(FLAG_RADIO_DOWN, &ai->flags);
 2386 	disable_MAC(ai, 1);
 2387 	disable_interrupts(ai);
 2388 	takedown_proc_entry( dev, ai );
 2389 	if (test_bit(FLAG_REGISTERED, &ai->flags)) {
 2390 		unregister_netdev( dev );
 2391 		if (ai->wifidev) {
 2392 			unregister_netdev(ai->wifidev);
 2393 			free_netdev(ai->wifidev);
 2394 			ai->wifidev = NULL;
 2395 		}
 2396 		clear_bit(FLAG_REGISTERED, &ai->flags);
 2397 	}
 2398 	/*
 2399 	 * Clean out tx queue
 2400 	 */
 2401 	if (test_bit(FLAG_MPI, &ai->flags) && !skb_queue_empty(&ai->txq)) {
 2402 		struct sk_buff *skb = NULL;
 2403 		for (;(skb = skb_dequeue(&ai->txq));)
 2404 			dev_kfree_skb(skb);
 2405 	}
 2406 
 2407 	airo_networks_free (ai);
 2408 
 2409 	kfree(ai->flash);
 2410 	kfree(ai->rssi);
 2411 	kfree(ai->SSID);
 2412 	if (freeres) {
 2413 		/* PCMCIA frees this stuff, so only for PCI and ISA */
 2414 	        release_region( dev->base_addr, 64 );
 2415 		if (test_bit(FLAG_MPI, &ai->flags)) {
 2416 			if (ai->pci)
 2417 				mpi_unmap_card(ai->pci);
 2418 			if (ai->pcimem)
 2419 				iounmap(ai->pcimem);
 2420 			if (ai->pciaux)
 2421 				iounmap(ai->pciaux);
 2422 			pci_free_consistent(ai->pci, PCI_SHARED_LEN,
 2423 				ai->shared, ai->shared_dma);
 2424 		}
 2425         }
 2426 	crypto_free_cipher(ai->tfm);
 2427 	del_airo_dev(ai);
 2428 	free_netdev( dev );
 2429 }
 2430 
 2431 EXPORT_SYMBOL(stop_airo_card);
 2432 
 2433 static int wll_header_parse(const struct sk_buff *skb, unsigned char *haddr)
 2434 {
 2435 	memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN);
 2436 	return ETH_ALEN;
 2437 }
 2438 
 2439 static void mpi_unmap_card(struct pci_dev *pci)
 2440 {
 2441 	unsigned long mem_start = pci_resource_start(pci, 1);
 2442 	unsigned long mem_len = pci_resource_len(pci, 1);
 2443 	unsigned long aux_start = pci_resource_start(pci, 2);
 2444 	unsigned long aux_len = AUXMEMSIZE;
 2445 
 2446 	release_mem_region(aux_start, aux_len);
 2447 	release_mem_region(mem_start, mem_len);
 2448 }
 2449 
 2450 /*************************************************************
 2451  *  This routine assumes that descriptors have been setup .
 2452  *  Run at insmod time or after reset  when the decriptors
 2453  *  have been initialized . Returns 0 if all is well nz
 2454  *  otherwise . Does not allocate memory but sets up card
 2455  *  using previously allocated descriptors.
 2456  */
 2457 static int mpi_init_descriptors (struct airo_info *ai)
 2458 {
 2459 	Cmd cmd;
 2460 	Resp rsp;
 2461 	int i;
 2462 	int rc = SUCCESS;
 2463 
 2464 	/* Alloc  card RX descriptors */
 2465 	netif_stop_queue(ai->dev);
 2466 
 2467 	memset(&rsp,0,sizeof(rsp));
 2468 	memset(&cmd,0,sizeof(cmd));
 2469 
 2470 	cmd.cmd = CMD_ALLOCATEAUX;
 2471 	cmd.parm0 = FID_RX;
 2472 	cmd.parm1 = (ai->rxfids[0].card_ram_off - ai->pciaux);
 2473 	cmd.parm2 = MPI_MAX_FIDS;
 2474 	rc=issuecommand(ai, &cmd, &rsp);
 2475 	if (rc != SUCCESS) {
 2476 		airo_print_err(ai->dev->name, "Couldn't allocate RX FID");
 2477 		return rc;
 2478 	}
 2479 
 2480 	for (i=0; i<MPI_MAX_FIDS; i++) {
 2481 		memcpy_toio(ai->rxfids[i].card_ram_off,
 2482 			&ai->rxfids[i].rx_desc, sizeof(RxFid));
 2483 	}
 2484 
 2485 	/* Alloc card TX descriptors */
 2486 
 2487 	memset(&rsp,0,sizeof(rsp));
 2488 	memset(&cmd,0,sizeof(cmd));
 2489 
 2490 	cmd.cmd = CMD_ALLOCATEAUX;
 2491 	cmd.parm0 = FID_TX;
 2492 	cmd.parm1 = (ai->txfids[0].card_ram_off - ai->pciaux);
 2493 	cmd.parm2 = MPI_MAX_FIDS;
 2494 
 2495 	for (i=0; i<MPI_MAX_FIDS; i++) {
 2496 		ai->txfids[i].tx_desc.valid = 1;
 2497 		memcpy_toio(ai->txfids[i].card_ram_off,
 2498 			&ai->txfids[i].tx_desc, sizeof(TxFid));
 2499 	}
 2500 	ai->txfids[i-1].tx_desc.eoc = 1; /* Last descriptor has EOC set */
 2501 
 2502 	rc=issuecommand(ai, &cmd, &rsp);
 2503 	if (rc != SUCCESS) {
 2504 		airo_print_err(ai->dev->name, "Couldn't allocate TX FID");
 2505 		return rc;
 2506 	}
 2507 
 2508 	/* Alloc card Rid descriptor */
 2509 	memset(&rsp,0,sizeof(rsp));
 2510 	memset(&cmd,0,sizeof(cmd));
 2511 
 2512 	cmd.cmd = CMD_ALLOCATEAUX;
 2513 	cmd.parm0 = RID_RW;
 2514 	cmd.parm1 = (ai->config_desc.card_ram_off - ai->pciaux);
 2515 	cmd.parm2 = 1; /* Magic number... */
 2516 	rc=issuecommand(ai, &cmd, &rsp);
 2517 	if (rc != SUCCESS) {
 2518 		airo_print_err(ai->dev->name, "Couldn't allocate RID");
 2519 		return rc;
 2520 	}
 2521 
 2522 	memcpy_toio(ai->config_desc.card_ram_off,
 2523 		&ai->config_desc.rid_desc, sizeof(Rid));
 2524 
 2525 	return rc;
 2526 }
 2527 
 2528 /*
 2529  * We are setting up three things here:
 2530  * 1) Map AUX memory for descriptors: Rid, TxFid, or RxFid.
 2531  * 2) Map PCI memory for issuing commands.
 2532  * 3) Allocate memory (shared) to send and receive ethernet frames.
 2533  */
 2534 static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci)
 2535 {
 2536 	unsigned long mem_start, mem_len, aux_start, aux_len;
 2537 	int rc = -1;
 2538 	int i;
 2539 	dma_addr_t busaddroff;
 2540 	unsigned char *vpackoff;
 2541 	unsigned char __iomem *pciaddroff;
 2542 
 2543 	mem_start = pci_resource_start(pci, 1);
 2544 	mem_len = pci_resource_len(pci, 1);
 2545 	aux_start = pci_resource_start(pci, 2);
 2546 	aux_len = AUXMEMSIZE;
 2547 
 2548 	if (!request_mem_region(mem_start, mem_len, DRV_NAME)) {
 2549 		airo_print_err("", "Couldn't get region %x[%x]",
 2550 			(int)mem_start, (int)mem_len);
 2551 		goto out;
 2552 	}
 2553 	if (!request_mem_region(aux_start, aux_len, DRV_NAME)) {
 2554 		airo_print_err("", "Couldn't get region %x[%x]",
 2555 			(int)aux_start, (int)aux_len);
 2556 		goto free_region1;
 2557 	}
 2558 
 2559 	ai->pcimem = ioremap(mem_start, mem_len);
 2560 	if (!ai->pcimem) {
 2561 		airo_print_err("", "Couldn't map region %x[%x]",
 2562 			(int)mem_start, (int)mem_len);
 2563 		goto free_region2;
 2564 	}
 2565 	ai->pciaux = ioremap(aux_start, aux_len);
 2566 	if (!ai->pciaux) {
 2567 		airo_print_err("", "Couldn't map region %x[%x]",
 2568 			(int)aux_start, (int)aux_len);
 2569 		goto free_memmap;
 2570 	}
 2571 
 2572 	/* Reserve PKTSIZE for each fid and 2K for the Rids */
 2573 	ai->shared = pci_alloc_consistent(pci, PCI_SHARED_LEN, &ai->shared_dma);
 2574 	if (!ai->shared) {
 2575 		airo_print_err("", "Couldn't alloc_consistent %d",
 2576 			PCI_SHARED_LEN);
 2577 		goto free_auxmap;
 2578 	}
 2579 
 2580 	/*
 2581 	 * Setup descriptor RX, TX, CONFIG
 2582 	 */
 2583 	busaddroff = ai->shared_dma;
 2584 	pciaddroff = ai->pciaux + AUX_OFFSET;
 2585 	vpackoff   = ai->shared;
 2586 
 2587 	/* RX descriptor setup */
 2588 	for(i = 0; i < MPI_MAX_FIDS; i++) {
 2589 		ai->rxfids[i].pending = 0;
 2590 		ai->rxfids[i].card_ram_off = pciaddroff;
 2591 		ai->rxfids[i].virtual_host_addr = vpackoff;
 2592 		ai->rxfids[i].rx_desc.host_addr = busaddroff;
 2593 		ai->rxfids[i].rx_desc.valid = 1;
 2594 		ai->rxfids[i].rx_desc.len = PKTSIZE;
 2595 		ai->rxfids[i].rx_desc.rdy = 0;
 2596 
 2597 		pciaddroff += sizeof(RxFid);
 2598 		busaddroff += PKTSIZE;
 2599 		vpackoff   += PKTSIZE;
 2600 	}
 2601 
 2602 	/* TX descriptor setup */
 2603 	for(i = 0; i < MPI_MAX_FIDS; i++) {
 2604 		ai->txfids[i].card_ram_off = pciaddroff;
 2605 		ai->txfids[i].virtual_host_addr = vpackoff;
 2606 		ai->txfids[i].tx_desc.valid = 1;
 2607 		ai->txfids[i].tx_desc.host_addr = busaddroff;
 2608 		memcpy(ai->txfids[i].virtual_host_addr,
 2609 			&wifictlhdr8023, sizeof(wifictlhdr8023));
 2610 
 2611 		pciaddroff += sizeof(TxFid);
 2612 		busaddroff += PKTSIZE;
 2613 		vpackoff   += PKTSIZE;
 2614 	}
 2615 	ai->txfids[i-1].tx_desc.eoc = 1; /* Last descriptor has EOC set */
 2616 
 2617 	/* Rid descriptor setup */
 2618 	ai->config_desc.card_ram_off = pciaddroff;
 2619 	ai->config_desc.virtual_host_addr = vpackoff;
 2620 	ai->config_desc.rid_desc.host_addr = busaddroff;
 2621 	ai->ridbus = busaddroff;
 2622 	ai->config_desc.rid_desc.rid = 0;
 2623 	ai->config_desc.rid_desc.len = RIDSIZE;
 2624 	ai->config_desc.rid_desc.valid = 1;
 2625 	pciaddroff += sizeof(Rid);
 2626 	busaddroff += RIDSIZE;
 2627 	vpackoff   += RIDSIZE;
 2628 
 2629 	/* Tell card about descriptors */
 2630 	if (mpi_init_descriptors (ai) != SUCCESS)
 2631 		goto free_shared;
 2632 
 2633 	return 0;
 2634  free_shared:
 2635 	pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma);
 2636  free_auxmap:
 2637 	iounmap(ai->pciaux);
 2638  free_memmap:
 2639 	iounmap(ai->pcimem);
 2640  free_region2:
 2641 	release_mem_region(aux_start, aux_len);
 2642  free_region1:
 2643 	release_mem_region(mem_start, mem_len);
 2644  out:
 2645 	return rc;
 2646 }
 2647 
 2648 static const struct header_ops airo_header_ops = {
 2649 	.parse = wll_header_parse,
 2650 };
 2651 
 2652 static const struct net_device_ops airo11_netdev_ops = {
 2653 	.ndo_open 		= airo_open,
 2654 	.ndo_stop 		= airo_close,
 2655 	.ndo_start_xmit 	= airo_start_xmit11,
 2656 	.ndo_get_stats 		= airo_get_stats,
 2657 	.ndo_set_mac_address	= airo_set_mac_address,
 2658 	.ndo_do_ioctl		= airo_ioctl,
 2659 	.ndo_change_mtu		= airo_change_mtu,
 2660 };
 2661 
 2662 static void wifi_setup(struct net_device *dev)
 2663 {
 2664 	dev->netdev_ops = &airo11_netdev_ops;
 2665 	dev->header_ops = &airo_header_ops;
 2666 	dev->wireless_handlers = &airo_handler_def;
 2667 
 2668 	dev->type               = ARPHRD_IEEE80211;
 2669 	dev->hard_header_len    = ETH_HLEN;
 2670 	dev->mtu                = AIRO_DEF_MTU;
 2671 	dev->addr_len           = ETH_ALEN;
 2672 	dev->tx_queue_len       = 100; 
 2673 
 2674 	eth_broadcast_addr(dev->broadcast);
 2675 
 2676 	dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
 2677 }
 2678 
 2679 static struct net_device *init_wifidev(struct airo_info *ai,
 2680 					struct net_device *ethdev)
 2681 {
 2682 	int err;
 2683 	struct net_device *dev = alloc_netdev(0, "wifi%d", NET_NAME_UNKNOWN,
 2684 					      wifi_setup);
 2685 	if (!dev)
 2686 		return NULL;
 2687 	dev->ml_priv = ethdev->ml_priv;
 2688 	dev->irq = ethdev->irq;
 2689 	dev->base_addr = ethdev->base_addr;
 2690 	dev->wireless_data = ethdev->wireless_data;
 2691 	SET_NETDEV_DEV(dev, ethdev->dev.parent);
 2692 	eth_hw_addr_inherit(dev, ethdev);
 2693 	err = register_netdev(dev);
 2694 	if (err<0) {
 2695 		free_netdev(dev);
 2696 		return NULL;
 2697 	}
 2698 	return dev;
 2699 }
 2700 
 2701 static int reset_card( struct net_device *dev , int lock) {
 2702 	struct airo_info *ai = dev->ml_priv;
 2703 
 2704 	if (lock && down_interruptible(&ai->sem))
 2705 		return -1;
 2706 	waitbusy (ai);
 2707 	OUT4500(ai,COMMAND,CMD_SOFTRESET);
 2708 	msleep(200);
 2709 	waitbusy (ai);
 2710 	msleep(200);
 2711 	if (lock)
 2712 		up(&ai->sem);
 2713 	return 0;
 2714 }
 2715 
 2716 #define AIRO_MAX_NETWORK_COUNT	64
 2717 static int airo_networks_allocate(struct airo_info *ai)
 2718 {
 2719 	if (ai->networks)
 2720 		return 0;
 2721 
 2722 	ai->networks = kcalloc(AIRO_MAX_NETWORK_COUNT, sizeof(BSSListElement),
 2723 			       GFP_KERNEL);
 2724 	if (!ai->networks) {
 2725 		airo_print_warn("", "Out of memory allocating beacons");
 2726 		return -ENOMEM;
 2727 	}
 2728 
 2729 	return 0;
 2730 }
 2731 
 2732 static void airo_networks_free(struct airo_info *ai)
 2733 {
 2734 	kfree(ai->networks);
 2735 	ai->networks = NULL;
 2736 }
 2737 
 2738 static void airo_networks_initialize(struct airo_info *ai)
 2739 {
 2740 	int i;
 2741 
 2742 	INIT_LIST_HEAD(&ai->network_free_list);
 2743 	INIT_LIST_HEAD(&ai->network_list);
 2744 	for (i = 0; i < AIRO_MAX_NETWORK_COUNT; i++)
 2745 		list_add_tail(&ai->networks[i].list,
 2746 			      &ai->network_free_list);
 2747 }
 2748 
 2749 static const struct net_device_ops airo_netdev_ops = {
 2750 	.ndo_open		= airo_open,
 2751 	.ndo_stop		= airo_close,
 2752 	.ndo_start_xmit		= airo_start_xmit,
 2753 	.ndo_get_stats		= airo_get_stats,
 2754 	.ndo_set_rx_mode	= airo_set_multicast_list,
 2755 	.ndo_set_mac_address	= airo_set_mac_address,
 2756 	.ndo_do_ioctl		= airo_ioctl,
 2757 	.ndo_change_mtu		= airo_change_mtu,
 2758 	.ndo_validate_addr	= eth_validate_addr,
 2759 };
 2760 
 2761 static const struct net_device_ops mpi_netdev_ops = {
 2762 	.ndo_open		= airo_open,
 2763 	.ndo_stop		= airo_close,
 2764 	.ndo_start_xmit		= mpi_start_xmit,
 2765 	.ndo_get_stats		= airo_get_stats,
 2766 	.ndo_set_rx_mode	= airo_set_multicast_list,
 2767 	.ndo_set_mac_address	= airo_set_mac_address,
 2768 	.ndo_do_ioctl		= airo_ioctl,
 2769 	.ndo_change_mtu		= airo_change_mtu,
 2770 	.ndo_validate_addr	= eth_validate_addr,
 2771 };
 2772 
 2773 
 2774 static struct net_device *_init_airo_card( unsigned short irq, int port,
 2775 					   int is_pcmcia, struct pci_dev *pci,
 2776 					   struct device *dmdev )
 2777 {
 2778 	struct net_device *dev;
 2779 	struct airo_info *ai;
 2780 	int i, rc;
 2781 	CapabilityRid cap_rid;
 2782 
 2783 	/* Create the network device object. */
 2784 	dev = alloc_netdev(sizeof(*ai), "", NET_NAME_UNKNOWN, ether_setup);
 2785 	if (!dev) {
 2786 		airo_print_err("", "Couldn't alloc_etherdev");
 2787 		return NULL;
 2788 	}
 2789 
 2790 	ai = dev->ml_priv = netdev_priv(dev);
 2791 	ai->wifidev = NULL;
 2792 	ai->flags = 1 << FLAG_RADIO_DOWN;
 2793 	ai->jobs = 0;
 2794 	ai->dev = dev;
 2795 	if (pci && (pci->device == 0x5000 || pci->device == 0xa504)) {
 2796 		airo_print_dbg("", "Found an MPI350 card");
 2797 		set_bit(FLAG_MPI, &ai->flags);
 2798 	}
 2799 	spin_lock_init(&ai->aux_lock);
 2800 	sema_init(&ai->sem, 1);
 2801 	ai->config.len = 0;
 2802 	ai->pci = pci;
 2803 	init_waitqueue_head (&ai->thr_wait);
 2804 	ai->tfm = NULL;
 2805 	add_airo_dev(ai);
 2806 	ai->APList.len = cpu_to_le16(sizeof(struct APListRid));
 2807 
 2808 	if (airo_networks_allocate (ai))
 2809 		goto err_out_free;
 2810 	airo_networks_initialize (ai);
 2811 
 2812 	skb_queue_head_init (&ai->txq);
 2813 
 2814 	/* The Airo-specific entries in the device structure. */
 2815 	if (test_bit(FLAG_MPI,&ai->flags))
 2816 		dev->netdev_ops = &mpi_netdev_ops;
 2817 	else
 2818 		dev->netdev_ops = &airo_netdev_ops;
 2819 	dev->wireless_handlers = &airo_handler_def;
 2820 	ai->wireless_data.spy_data = &ai->spy_data;
 2821 	dev->wireless_data = &ai->wireless_data;
 2822 	dev->irq = irq;
 2823 	dev->base_addr = port;
 2824 	dev->priv_flags &= ~IFF_TX_SKB_SHARING;
 2825 
 2826 	SET_NETDEV_DEV(dev, dmdev);
 2827 
 2828 	reset_card (dev, 1);
 2829 	msleep(400);
 2830 
 2831 	if (!is_pcmcia) {
 2832 		if (!request_region(dev->base_addr, 64, DRV_NAME)) {
 2833 			rc = -EBUSY;
 2834 			airo_print_err(dev->name, "Couldn't request region");
 2835 			goto err_out_nets;
 2836 		}
 2837 	}
 2838 
 2839 	if (test_bit(FLAG_MPI,&ai->flags)) {
 2840 		if (mpi_map_card(ai, pci)) {
 2841 			airo_print_err("", "Could not map memory");
 2842 			goto err_out_res;
 2843 		}
 2844 	}
 2845 
 2846 	if (probe) {
 2847 		if (setup_card(ai, dev->dev_addr, 1) != SUCCESS) {
 2848 			airo_print_err(dev->name, "MAC could not be enabled" );
 2849 			rc = -EIO;
 2850 			goto err_out_map;
 2851 		}
 2852 	} else if (!test_bit(FLAG_MPI,&ai->flags)) {
 2853 		ai->bap_read = fast_bap_read;
 2854 		set_bit(FLAG_FLASHING, &ai->flags);
 2855 	}
 2856 
 2857 	strcpy(dev->name, "eth%d");
 2858 	rc = register_netdev(dev);
 2859 	if (rc) {
 2860 		airo_print_err(dev->name, "Couldn't register_netdev");
 2861 		goto err_out_map;
 2862 	}
 2863 	ai->wifidev = init_wifidev(ai, dev);
 2864 	if (!ai->wifidev)
 2865 		goto err_out_reg;
 2866 
 2867 	rc = readCapabilityRid(ai, &cap_rid, 1);
 2868 	if (rc != SUCCESS) {
 2869 		rc = -EIO;
 2870 		goto err_out_wifi;
 2871 	}
 2872 	/* WEP capability discovery */
 2873 	ai->wep_capable = (cap_rid.softCap & cpu_to_le16(0x02)) ? 1 : 0;
 2874 	ai->max_wep_idx = (cap_rid.softCap & cpu_to_le16(0x80)) ? 3 : 0;
 2875 
 2876 	airo_print_info(dev->name, "Firmware version %x.%x.%02d",
 2877 	                ((le16_to_cpu(cap_rid.softVer) >> 8) & 0xF),
 2878 	                (le16_to_cpu(cap_rid.softVer) & 0xFF),
 2879 	                le16_to_cpu(cap_rid.softSubVer));
 2880 
 2881 	/* Test for WPA support */
 2882 	/* Only firmware versions 5.30.17 or better can do WPA */
 2883 	if (le16_to_cpu(cap_rid.softVer) > 0x530
 2884 	 || (le16_to_cpu(cap_rid.softVer) == 0x530
 2885 	      && le16_to_cpu(cap_rid.softSubVer) >= 17)) {
 2886 		airo_print_info(ai->dev->name, "WPA supported.");
 2887 
 2888 		set_bit(FLAG_WPA_CAPABLE, &ai->flags);
 2889 		ai->bssListFirst = RID_WPA_BSSLISTFIRST;
 2890 		ai->bssListNext = RID_WPA_BSSLISTNEXT;
 2891 		ai->bssListRidLen = sizeof(BSSListRid);
 2892 	} else {
 2893 		airo_print_info(ai->dev->name, "WPA unsupported with firmware "
 2894 			"versions older than 5.30.17.");
 2895 
 2896 		ai->bssListFirst = RID_BSSLISTFIRST;
 2897 		ai->bssListNext = RID_BSSLISTNEXT;
 2898 		ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra);
 2899 	}
 2900 
 2901 	set_bit(FLAG_REGISTERED,&ai->flags);
 2902 	airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr);
 2903 
 2904 	/* Allocate the transmit buffers */
 2905 	if (probe && !test_bit(FLAG_MPI,&ai->flags))
 2906 		for( i = 0; i < MAX_FIDS; i++ )
 2907 			ai->fids[i] = transmit_allocate(ai,AIRO_DEF_MTU,i>=MAX_FIDS/2);
 2908 
 2909 	if (setup_proc_entry(dev, dev->ml_priv) < 0)
 2910 		goto err_out_wifi;
 2911 
 2912 	return dev;
 2913 
 2914 err_out_wifi:
 2915 	unregister_netdev(ai->wifidev);
 2916 	free_netdev(ai->wifidev);
 2917 err_out_reg:
 2918 	unregister_netdev(dev);
 2919 err_out_map:
 2920 	if (test_bit(FLAG_MPI,&ai->flags) && pci) {
 2921 		pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma);
 2922 		iounmap(ai->pciaux);
 2923 		iounmap(ai->pcimem);
 2924 		mpi_unmap_card(ai->pci);
 2925 	}
 2926 err_out_res:
 2927 	if (!is_pcmcia)
 2928 	        release_region( dev->base_addr, 64 );
 2929 err_out_nets:
 2930 	airo_networks_free(ai);
 2931 err_out_free:
 2932 	del_airo_dev(ai);
 2933 	free_netdev(dev);
 2934 	return NULL;
 2935 }
 2936 
 2937 struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia,
 2938 				  struct device *dmdev)
 2939 {
 2940 	return _init_airo_card ( irq, port, is_pcmcia, NULL, dmdev);
 2941 }
 2942 
 2943 EXPORT_SYMBOL(init_airo_card);
 2944 
 2945 static int waitbusy (struct airo_info *ai) {
 2946 	int delay = 0;
 2947 	while ((IN4500(ai, COMMAND) & COMMAND_BUSY) && (delay < 10000)) {
 2948 		udelay (10);
 2949 		if ((++delay % 20) == 0)
 2950 			OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
 2951 	}
 2952 	return delay < 10000;
 2953 }
 2954 
 2955 int reset_airo_card( struct net_device *dev )
 2956 {
 2957 	int i;
 2958 	struct airo_info *ai = dev->ml_priv;
 2959 
 2960 	if (reset_card (dev, 1))
 2961 		return -1;
 2962 
 2963 	if ( setup_card(ai, dev->dev_addr, 1 ) != SUCCESS ) {
 2964 		airo_print_err(dev->name, "MAC could not be enabled");
 2965 		return -1;
 2966 	}
 2967 	airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr);
 2968 	/* Allocate the transmit buffers if needed */
 2969 	if (!test_bit(FLAG_MPI,&ai->flags))
 2970 		for( i = 0; i < MAX_FIDS; i++ )
 2971 			ai->fids[i] = transmit_allocate (ai,AIRO_DEF_MTU,i>=MAX_FIDS/2);
 2972 
 2973 	enable_interrupts( ai );
 2974 	netif_wake_queue(dev);
 2975 	return 0;
 2976 }
 2977 
 2978 EXPORT_SYMBOL(reset_airo_card);
 2979 
 2980 static void airo_send_event(struct net_device *dev) {
 2981 	struct airo_info *ai = dev->ml_priv;
 2982 	union iwreq_data wrqu;
 2983 	StatusRid status_rid;
 2984 
 2985 	clear_bit(JOB_EVENT, &ai->jobs);
 2986 	PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid), 0);
 2987 	up(&ai->sem);
 2988 	wrqu.data.length = 0;
 2989 	wrqu.data.flags = 0;
 2990 	memcpy(wrqu.ap_addr.sa_data, status_rid.bssid[0], ETH_ALEN);
 2991 	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
 2992 
 2993 	/* Send event to user space */
 2994 	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
 2995 }
 2996 
 2997 static void airo_process_scan_results (struct airo_info *ai) {
 2998 	union iwreq_data	wrqu;
 2999 	BSSListRid bss;
 3000 	int rc;
 3001 	BSSListElement * loop_net;
 3002 	BSSListElement * tmp_net;
 3003 
 3004 	/* Blow away current list of scan results */
 3005 	list_for_each_entry_safe (loop_net, tmp_net, &ai->network_list, list) {
 3006 		list_move_tail (&loop_net->list, &ai->network_free_list);
 3007 		/* Don't blow away ->list, just BSS data */
 3008 		memset (loop_net, 0, sizeof (loop_net->bss));
 3009 	}
 3010 
 3011 	/* Try to read the first entry of the scan result */
 3012 	rc = PC4500_readrid(ai, ai->bssListFirst, &bss, ai->bssListRidLen, 0);
 3013 	if((rc) || (bss.index == cpu_to_le16(0xffff))) {
 3014 		/* No scan results */
 3015 		goto out;
 3016 	}
 3017 
 3018 	/* Read and parse all entries */
 3019 	tmp_net = NULL;
 3020 	while((!rc) && (bss.index != cpu_to_le16(0xffff))) {
 3021 		/* Grab a network off the free list */
 3022 		if (!list_empty(&ai->network_free_list)) {
 3023 			tmp_net = list_entry(ai->network_free_list.next,
 3024 					    BSSListElement, list);
 3025 			list_del(ai->network_free_list.next);
 3026 		}
 3027 
 3028 		if (tmp_net != NULL) {
 3029 			memcpy(tmp_net, &bss, sizeof(tmp_net->bss));
 3030 			list_add_tail(&tmp_net->list, &ai->network_list);
 3031 			tmp_net = NULL;
 3032 		}
 3033 
 3034 		/* Read next entry */
 3035 		rc = PC4500_readrid(ai, ai->bssListNext,
 3036 				    &bss, ai->bssListRidLen, 0);
 3037 	}
 3038 
 3039 out:
 3040 	/* write APList back (we cleared it in airo_set_scan) */
 3041 	disable_MAC(ai, 2);
 3042 	writeAPListRid(ai, &ai->APList, 0);
 3043 	enable_MAC(ai, 0);
 3044 
 3045 	ai->scan_timeout = 0;
 3046 	clear_bit(JOB_SCAN_RESULTS, &ai->jobs);
 3047 	up(&ai->sem);
 3048 
 3049 	/* Send an empty event to user space.
 3050 	 * We don't send the received data on
 3051 	 * the event because it would require
 3052 	 * us to do complex transcoding, and
 3053 	 * we want to minimise the work done in
 3054 	 * the irq handler. Use a request to
 3055 	 * extract the data - Jean II */
 3056 	wrqu.data.length = 0;
 3057 	wrqu.data.flags = 0;
 3058 	wireless_send_event(ai->dev, SIOCGIWSCAN, &wrqu, NULL);
 3059 }
 3060 
 3061 static int airo_thread(void *data) {
 3062 	struct net_device *dev = data;
 3063 	struct airo_info *ai = dev->ml_priv;
 3064 	int locked;
 3065 
 3066 	set_freezable();
 3067 	while(1) {
 3068 		/* make swsusp happy with our thread */
 3069 		try_to_freeze();
 3070 
 3071 		if (test_bit(JOB_DIE, &ai->jobs))
 3072 			break;
 3073 
 3074 		if (ai->jobs) {
 3075 			locked = down_interruptible(&ai->sem);
 3076 		} else {
 3077 			wait_queue_t wait;
 3078 
 3079 			init_waitqueue_entry(&wait, current);
 3080 			add_wait_queue(&ai->thr_wait, &wait);
 3081 			for (;;) {
 3082 				set_current_state(TASK_INTERRUPTIBLE);
 3083 				if (ai->jobs)
 3084 					break;
 3085 				if (ai->expires || ai->scan_timeout) {
 3086 					if (ai->scan_timeout &&
 3087 							time_after_eq(jiffies,ai->scan_timeout)){
 3088 						set_bit(JOB_SCAN_RESULTS, &ai->jobs);
 3089 						break;
 3090 					} else if (ai->expires &&
 3091 							time_after_eq(jiffies,ai->expires)){
 3092 						set_bit(JOB_AUTOWEP, &ai->jobs);
 3093 						break;
 3094 					}
 3095 					if (!kthread_should_stop() &&
 3096 					    !freezing(current)) {
 3097 						unsigned long wake_at;
 3098 						if (!ai->expires || !ai->scan_timeout) {
 3099 							wake_at = max(ai->expires,
 3100 								ai->scan_timeout);
 3101 						} else {
 3102 							wake_at = min(ai->expires,
 3103 								ai->scan_timeout);
 3104 						}
 3105 						schedule_timeout(wake_at - jiffies);
 3106 						continue;
 3107 					}
 3108 				} else if (!kthread_should_stop() &&
 3109 					   !freezing(current)) {
 3110 					schedule();
 3111 					continue;
 3112 				}
 3113 				break;
 3114 			}
 3115 			current->state = TASK_RUNNING;
 3116 			remove_wait_queue(&ai->thr_wait, &wait);
 3117 			locked = 1;
 3118 		}
 3119 
 3120 		if (locked)
 3121 			continue;
 3122 
 3123 		if (test_bit(JOB_DIE, &ai->jobs)) {
 3124 			up(&ai->sem);
 3125 			break;
 3126 		}
 3127 
 3128 		if (ai->power.event || test_bit(FLAG_FLASHING, &ai->flags)) {
 3129 			up(&ai->sem);
 3130 			continue;
 3131 		}
 3132 
 3133 		if (test_bit(JOB_XMIT, &ai->jobs))
 3134 			airo_end_xmit(dev);
 3135 		else if (test_bit(JOB_XMIT11, &ai->jobs))
 3136 			airo_end_xmit11(dev);
 3137 		else if (test_bit(JOB_STATS, &ai->jobs))
 3138 			airo_read_stats(dev);
 3139 		else if (test_bit(JOB_WSTATS, &ai->jobs))
 3140 			airo_read_wireless_stats(ai);
 3141 		else if (test_bit(JOB_PROMISC, &ai->jobs))
 3142 			airo_set_promisc(ai);
 3143 		else if (test_bit(JOB_MIC, &ai->jobs))
 3144 			micinit(ai);
 3145 		else if (test_bit(JOB_EVENT, &ai->jobs))
 3146 			airo_send_event(dev);
 3147 		else if (test_bit(JOB_AUTOWEP, &ai->jobs))
 3148 			timer_func(dev);
 3149 		else if (test_bit(JOB_SCAN_RESULTS, &ai->jobs))
 3150 			airo_process_scan_results(ai);
 3151 		else  /* Shouldn't get here, but we make sure to unlock */
 3152 			up(&ai->sem);
 3153 	}
 3154 
 3155 	return 0;
 3156 }
 3157 
 3158 static int header_len(__le16 ctl)
 3159 {
 3160 	u16 fc = le16_to_cpu(ctl);
 3161 	switch (fc & 0xc) {
 3162 	case 4:
 3163 		if ((fc & 0xe0) == 0xc0)
 3164 			return 10;	/* one-address control packet */
 3165 		return 16;	/* two-address control packet */
 3166 	case 8:
 3167 		if ((fc & 0x300) == 0x300)
 3168 			return 30;	/* WDS packet */
 3169 	}
 3170 	return 24;
 3171 }
 3172 
 3173 static void airo_handle_cisco_mic(struct airo_info *ai)
 3174 {
 3175 	if (test_bit(FLAG_MIC_CAPABLE, &ai->flags)) {
 3176 		set_bit(JOB_MIC, &ai->jobs);
 3177 		wake_up_interruptible(&ai->thr_wait);
 3178 	}
 3179 }
 3180 
 3181 /* Airo Status codes */
 3182 #define STAT_NOBEACON	0x8000 /* Loss of sync - missed beacons */
 3183 #define STAT_MAXRETRIES	0x8001 /* Loss of sync - max retries */
 3184 #define STAT_MAXARL	0x8002 /* Loss of sync - average retry level exceeded*/
 3185 #define STAT_FORCELOSS	0x8003 /* Loss of sync - host request */
 3186 #define STAT_TSFSYNC	0x8004 /* Loss of sync - TSF synchronization */
 3187 #define STAT_DEAUTH	0x8100 /* low byte is 802.11 reason code */
 3188 #define STAT_DISASSOC	0x8200 /* low byte is 802.11 reason code */
 3189 #define STAT_ASSOC_FAIL	0x8400 /* low byte is 802.11 reason code */
 3190 #define STAT_AUTH_FAIL	0x0300 /* low byte is 802.11 reason code */
 3191 #define STAT_ASSOC	0x0400 /* Associated */
 3192 #define STAT_REASSOC    0x0600 /* Reassociated?  Only on firmware >= 5.30.17 */
 3193 
 3194 static void airo_print_status(const char *devname, u16 status)
 3195 {
 3196 	u8 reason = status & 0xFF;
 3197 
 3198 	switch (status & 0xFF00) {
 3199 	case STAT_NOBEACON:
 3200 		switch (status) {
 3201 		case STAT_NOBEACON:
 3202 			airo_print_dbg(devname, "link lost (missed beacons)");
 3203 			break;
 3204 		case STAT_MAXRETRIES:
 3205 		case STAT_MAXARL:
 3206 			airo_print_dbg(devname, "link lost (max retries)");
 3207 			break;
 3208 		case STAT_FORCELOSS:
 3209 			airo_print_dbg(devname, "link lost (local choice)");
 3210 			break;
 3211 		case STAT_TSFSYNC:
 3212 			airo_print_dbg(devname, "link lost (TSF sync lost)");
 3213 			break;
 3214 		default:
 3215 			airo_print_dbg(devname, "unknown status %x\n", status);
 3216 			break;
 3217 		}
 3218 		break;
 3219 	case STAT_DEAUTH:
 3220 		airo_print_dbg(devname, "deauthenticated (reason: %d)", reason);
 3221 		break;
 3222 	case STAT_DISASSOC:
 3223 		airo_print_dbg(devname, "disassociated (reason: %d)", reason);
 3224 		break;
 3225 	case STAT_ASSOC_FAIL:
 3226 		airo_print_dbg(devname, "association failed (reason: %d)",
 3227 			       reason);
 3228 		break;
 3229 	case STAT_AUTH_FAIL:
 3230 		airo_print_dbg(devname, "authentication failed (reason: %d)",
 3231 			       reason);
 3232 		break;
 3233 	case STAT_ASSOC:
 3234 	case STAT_REASSOC:
 3235 		break;
 3236 	default:
 3237 		airo_print_dbg(devname, "unknown status %x\n", status);
 3238 		break;
 3239 	}
 3240 }
 3241 
 3242 static void airo_handle_link(struct airo_info *ai)
 3243 {
 3244 	union iwreq_data wrqu;
 3245 	int scan_forceloss = 0;
 3246 	u16 status;
 3247 
 3248 	/* Get new status and acknowledge the link change */
 3249 	status = le16_to_cpu(IN4500(ai, LINKSTAT));
 3250 	OUT4500(ai, EVACK, EV_LINK);
 3251 
 3252 	if ((status == STAT_FORCELOSS) && (ai->scan_timeout > 0))
 3253 		scan_forceloss = 1;
 3254 
 3255 	airo_print_status(ai->dev->name, status);
 3256 
 3257 	if ((status == STAT_ASSOC) || (status == STAT_REASSOC)) {
 3258 		if (auto_wep)
 3259 			ai->expires = 0;
 3260 		if (ai->list_bss_task)
 3261 			wake_up_process(ai->list_bss_task);
 3262 		set_bit(FLAG_UPDATE_UNI, &ai->flags);
 3263 		set_bit(FLAG_UPDATE_MULTI, &ai->flags);
 3264 
 3265 		if (down_trylock(&ai->sem) != 0) {
 3266 			set_bit(JOB_EVENT, &ai->jobs);
 3267 			wake_up_interruptible(&ai->thr_wait);
 3268 		} else
 3269 			airo_send_event(ai->dev);
 3270 		netif_carrier_on(ai->dev);
 3271 	} else if (!scan_forceloss) {
 3272 		if (auto_wep && !ai->expires) {
 3273 			ai->expires = RUN_AT(3*HZ);
 3274 			wake_up_interruptible(&ai->thr_wait);
 3275 		}
 3276 
 3277 		/* Send event to user space */
 3278 		eth_zero_addr(wrqu.ap_addr.sa_data);
 3279 		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
 3280 		wireless_send_event(ai->dev, SIOCGIWAP, &wrqu, NULL);
 3281 		netif_carrier_off(ai->dev);
 3282 	} else {
 3283 		netif_carrier_off(ai->dev);
 3284 	}
 3285 }
 3286 
 3287 static void airo_handle_rx(struct airo_info *ai)
 3288 {
 3289 	struct sk_buff *skb = NULL;
 3290 	__le16 fc, v, *buffer, tmpbuf[4];
 3291 	u16 len, hdrlen = 0, gap, fid;
 3292 	struct rx_hdr hdr;
 3293 	int success = 0;
 3294 
 3295 	if (test_bit(FLAG_MPI, &ai->flags)) {
 3296 		if (test_bit(FLAG_802_11, &ai->flags))
 3297 			mpi_receive_802_11(ai);
 3298 		else
 3299 			mpi_receive_802_3(ai);
 3300 		OUT4500(ai, EVACK, EV_RX);
 3301 		return;
 3302 	}
 3303 
 3304 	fid = IN4500(ai, RXFID);
 3305 
 3306 	/* Get the packet length */
 3307 	if (test_bit(FLAG_802_11, &ai->flags)) {
 3308 		bap_setup (ai, fid, 4, BAP0);
 3309 		bap_read (ai, (__le16*)&hdr, sizeof(hdr), BAP0);
 3310 		/* Bad CRC. Ignore packet */
 3311 		if (le16_to_cpu(hdr.status) & 2)
 3312 			hdr.len = 0;
 3313 		if (ai->wifidev == NULL)
 3314 			hdr.len = 0;
 3315 	} else {
 3316 		bap_setup(ai, fid, 0x36, BAP0);
 3317 		bap_read(ai, &hdr.len, 2, BAP0);
 3318 	}
 3319 	len = le16_to_cpu(hdr.len);
 3320 
 3321 	if (len > AIRO_DEF_MTU) {
 3322 		airo_print_err(ai->dev->name, "Bad size %d", len);
 3323 		goto done;
 3324 	}
 3325 	if (len == 0)
 3326 		goto done;
 3327 
 3328 	if (test_bit(FLAG_802_11, &ai->flags)) {
 3329 		bap_read(ai, &fc, sizeof (fc), BAP0);
 3330 		hdrlen = header_len(fc);
 3331 	} else
 3332 		hdrlen = ETH_ALEN * 2;
 3333 
 3334 	skb = dev_alloc_skb(len + hdrlen + 2 + 2);
 3335 	if (!skb) {
 3336 		ai->dev->stats.rx_dropped++;
 3337 		goto done;
 3338 	}
 3339 
 3340 	skb_reserve(skb, 2); /* This way the IP header is aligned */
 3341 	buffer = (__le16 *) skb_put(skb, len + hdrlen);
 3342 	if (test_bit(FLAG_802_11, &ai->flags)) {
 3343 		buffer[0] = fc;
 3344 		bap_read(ai, buffer + 1, hdrlen - 2, BAP0);
 3345 		if (hdrlen == 24)
 3346 			bap_read(ai, tmpbuf, 6, BAP0);
 3347 
 3348 		bap_read(ai, &v, sizeof(v), BAP0);
 3349 		gap = le16_to_cpu(v);
 3350 		if (gap) {
 3351 			if (gap <= 8) {
 3352 				bap_read(ai, tmpbuf, gap, BAP0);
 3353 			} else {
 3354 				airo_print_err(ai->dev->name, "gaplen too "
 3355 					"big. Problems will follow...");
 3356 			}
 3357 		}
 3358 		bap_read(ai, buffer + hdrlen/2, len, BAP0);
 3359 	} else {
 3360 		MICBuffer micbuf;
 3361 
 3362 		bap_read(ai, buffer, ETH_ALEN * 2, BAP0);
 3363 		if (ai->micstats.enabled) {
 3364 			bap_read(ai, (__le16 *) &micbuf, sizeof (micbuf), BAP0);
 3365 			if (ntohs(micbuf.typelen) > 0x05DC)
 3366 				bap_setup(ai, fid, 0x44, BAP0);
 3367 			else {
 3368 				if (len <= sizeof (micbuf)) {
 3369 					dev_kfree_skb_irq(skb);
 3370 					goto done;
 3371 				}
 3372 
 3373 				len -= sizeof(micbuf);
 3374 				skb_trim(skb, len + hdrlen);
 3375 			}
 3376 		}
 3377 
 3378 		bap_read(ai, buffer + ETH_ALEN, len, BAP0);
 3379 		if (decapsulate(ai, &micbuf, (etherHead*) buffer, len))
 3380 			dev_kfree_skb_irq (skb);
 3381 		else
 3382 			success = 1;
 3383 	}
 3384 
 3385 #ifdef WIRELESS_SPY
 3386 	if (success && (ai->spy_data.spy_number > 0)) {
 3387 		char *sa;
 3388 		struct iw_quality wstats;
 3389 
 3390 		/* Prepare spy data : addr + qual */
 3391 		if (!test_bit(FLAG_802_11, &ai->flags)) {
 3392 			sa = (char *) buffer + 6;
 3393 			bap_setup(ai, fid, 8, BAP0);
 3394 			bap_read(ai, (__le16 *) hdr.rssi, 2, BAP0);
 3395 		} else
 3396 			sa = (char *) buffer + 10;
 3397 		wstats.qual = hdr.rssi[0];
 3398 		if (ai->rssi)
 3399 			wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
 3400 		else
 3401 			wstats.level = (hdr.rssi[1] + 321) / 2;
 3402 		wstats.noise = ai->wstats.qual.noise;
 3403 		wstats.updated =  IW_QUAL_LEVEL_UPDATED
 3404 				| IW_QUAL_QUAL_UPDATED
 3405 				| IW_QUAL_DBM;
 3406 		/* Update spy records */
 3407 		wireless_spy_update(ai->dev, sa, &wstats);
 3408 	}
 3409 #endif /* WIRELESS_SPY */
 3410 
 3411 done:
 3412 	OUT4500(ai, EVACK, EV_RX);
 3413 
 3414 	if (success) {
 3415 		if (test_bit(FLAG_802_11, &ai->flags)) {
 3416 			skb_reset_mac_header(skb);
 3417 			skb->pkt_type = PACKET_OTHERHOST;
 3418 			skb->dev = ai->wifidev;
 3419 			skb->protocol = htons(ETH_P_802_2);
 3420 		} else
 3421 			skb->protocol = eth_type_trans(skb, ai->dev);
 3422 		skb->ip_summed = CHECKSUM_NONE;
 3423 
 3424 		netif_rx(skb);
 3425 	}
 3426 }
 3427 
 3428 static void airo_handle_tx(struct airo_info *ai, u16 status)
 3429 {
 3430 	int i, len = 0, index = -1;
 3431 	u16 fid;
 3432 
 3433 	if (test_bit(FLAG_MPI, &ai->flags)) {
 3434 		unsigned long flags;
 3435 
 3436 		if (status & EV_TXEXC)
 3437 			get_tx_error(ai, -1);
 3438 
 3439 		spin_lock_irqsave(&ai->aux_lock, flags);
 3440 		if (!skb_queue_empty(&ai->txq)) {
 3441 			spin_unlock_irqrestore(&ai->aux_lock,flags);
 3442 			mpi_send_packet(ai->dev);
 3443 		} else {
 3444 			clear_bit(FLAG_PENDING_XMIT, &ai->flags);
 3445 			spin_unlock_irqrestore(&ai->aux_lock,flags);
 3446 			netif_wake_queue(ai->dev);
 3447 		}
 3448 		OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
 3449 		return;
 3450 	}
 3451 
 3452 	fid = IN4500(ai, TXCOMPLFID);
 3453 
 3454 	for(i = 0; i < MAX_FIDS; i++) {
 3455 		if ((ai->fids[i] & 0xffff) == fid) {
 3456 			len = ai->fids[i] >> 16;
 3457 			index = i;
 3458 		}
 3459 	}
 3460 
 3461 	if (index != -1) {
 3462 		if (status & EV_TXEXC)
 3463 			get_tx_error(ai, index);
 3464 
 3465 		OUT4500(ai, EVACK, status & (EV_TX | EV_TXEXC));
 3466 
 3467 		/* Set up to be used again */
 3468 		ai->fids[index] &= 0xffff;
 3469 		if (index < MAX_FIDS / 2) {
 3470 			if (!test_bit(FLAG_PENDING_XMIT, &ai->flags))
 3471 				netif_wake_queue(ai->dev);
 3472 		} else {
 3473 			if (!test_bit(FLAG_PENDING_XMIT11, &ai->flags))
 3474 				netif_wake_queue(ai->wifidev);
 3475 		}
 3476 	} else {
 3477 		OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
 3478 		airo_print_err(ai->dev->name, "Unallocated FID was used to xmit");
 3479 	}
 3480 }
 3481 
 3482 static irqreturn_t airo_interrupt(int irq, void *dev_id)
 3483 {
 3484 	struct net_device *dev = dev_id;
 3485 	u16 status, savedInterrupts = 0;
 3486 	struct airo_info *ai = dev->ml_priv;
 3487 	int handled = 0;
 3488 
 3489 	if (!netif_device_present(dev))
 3490 		return IRQ_NONE;
 3491 
 3492 	for (;;) {
 3493 		status = IN4500(ai, EVSTAT);
 3494 		if (!(status & STATUS_INTS) || (status == 0xffff))
 3495 			break;
 3496 
 3497 		handled = 1;
 3498 
 3499 		if (status & EV_AWAKE) {
 3500 			OUT4500(ai, EVACK, EV_AWAKE);
 3501 			OUT4500(ai, EVACK, EV_AWAKE);
 3502 		}
 3503 
 3504 		if (!savedInterrupts) {
 3505 			savedInterrupts = IN4500(ai, EVINTEN);
 3506 			OUT4500(ai, EVINTEN, 0);
 3507 		}
 3508 
 3509 		if (status & EV_MIC) {
 3510 			OUT4500(ai, EVACK, EV_MIC);
 3511 			airo_handle_cisco_mic(ai);
 3512 		}
 3513 
 3514 		if (status & EV_LINK) {
 3515 			/* Link status changed */
 3516 			airo_handle_link(ai);
 3517 		}
 3518 
 3519 		/* Check to see if there is something to receive */
 3520 		if (status & EV_RX)
 3521 			airo_handle_rx(ai);
 3522 
 3523 		/* Check to see if a packet has been transmitted */
 3524 		if (status & (EV_TX | EV_TXCPY | EV_TXEXC))
 3525 			airo_handle_tx(ai, status);
 3526 
 3527 		if ( status & ~STATUS_INTS & ~IGNORE_INTS ) {
 3528 			airo_print_warn(ai->dev->name, "Got weird status %x",
 3529 				status & ~STATUS_INTS & ~IGNORE_INTS );
 3530 		}
 3531 	}
 3532 
 3533 	if (savedInterrupts)
 3534 		OUT4500(ai, EVINTEN, savedInterrupts);
 3535 
 3536 	return IRQ_RETVAL(handled);
 3537 }
 3538 
 3539 /*
 3540  *  Routines to talk to the card
 3541  */
 3542 
 3543 /*
 3544  *  This was originally written for the 4500, hence the name
 3545  *  NOTE:  If use with 8bit mode and SMP bad things will happen!
 3546  *         Why would some one do 8 bit IO in an SMP machine?!?
 3547  */
 3548 static void OUT4500( struct airo_info *ai, u16 reg, u16 val ) {
 3549 	if (test_bit(FLAG_MPI,&ai->flags))
 3550 		reg <<= 1;
 3551 	if ( !do8bitIO )
 3552 		outw( val, ai->dev->base_addr + reg );
 3553 	else {
 3554 		outb( val & 0xff, ai->dev->base_addr + reg );
 3555 		outb( val >> 8, ai->dev->base_addr + reg + 1 );
 3556 	}
 3557 }
 3558 
 3559 static u16 IN4500( struct airo_info *ai, u16 reg ) {
 3560 	unsigned short rc;
 3561 
 3562 	if (test_bit(FLAG_MPI,&ai->flags))
 3563 		reg <<= 1;
 3564 	if ( !do8bitIO )
 3565 		rc = inw( ai->dev->base_addr + reg );
 3566 	else {
 3567 		rc = inb( ai->dev->base_addr + reg );
 3568 		rc += ((int)inb( ai->dev->base_addr + reg + 1 )) << 8;
 3569 	}
 3570 	return rc;
 3571 }
 3572 
 3573 static int enable_MAC(struct airo_info *ai, int lock)
 3574 {
 3575 	int rc;
 3576 	Cmd cmd;
 3577 	Resp rsp;
 3578 
 3579 	/* FLAG_RADIO_OFF : Radio disabled via /proc or Wireless Extensions
 3580 	 * FLAG_RADIO_DOWN : Radio disabled via "ifconfig ethX down"
 3581 	 * Note : we could try to use !netif_running(dev) in enable_MAC()
 3582 	 * instead of this flag, but I don't trust it *within* the
 3583 	 * open/close functions, and testing both flags together is
 3584 	 * "cheaper" - Jean II */
 3585 	if (ai->flags & FLAG_RADIO_MASK) return SUCCESS;
 3586 
 3587 	if (lock && down_interruptible(&ai->sem))
 3588 		return -ERESTARTSYS;
 3589 
 3590 	if (!test_bit(FLAG_ENABLED, &ai->flags)) {
 3591 		memset(&cmd, 0, sizeof(cmd));
 3592 		cmd.cmd = MAC_ENABLE;
 3593 		rc = issuecommand(ai, &cmd, &rsp);
 3594 		if (rc == SUCCESS)
 3595 			set_bit(FLAG_ENABLED, &ai->flags);
 3596 	} else
 3597 		rc = SUCCESS;
 3598 
 3599 	if (lock)
 3600 	    up(&ai->sem);
 3601 
 3602 	if (rc)
 3603 		airo_print_err(ai->dev->name, "Cannot enable MAC");
 3604 	else if ((rsp.status & 0xFF00) != 0) {
 3605 		airo_print_err(ai->dev->name, "Bad MAC enable reason=%x, "
 3606 			"rid=%x, offset=%d", rsp.rsp0, rsp.rsp1, rsp.rsp2);
 3607 		rc = ERROR;
 3608 	}
 3609 	return rc;
 3610 }
 3611 
 3612 static void disable_MAC( struct airo_info *ai, int lock ) {
 3613         Cmd cmd;
 3614 	Resp rsp;
 3615 
 3616 	if (lock == 1 && down_interruptible(&ai->sem))
 3617 		return;
 3618 
 3619 	if (test_bit(FLAG_ENABLED, &ai->flags)) {
 3620 		if (lock != 2) /* lock == 2 means don't disable carrier */
 3621 			netif_carrier_off(ai->dev);
 3622 		memset(&cmd, 0, sizeof(cmd));
 3623 		cmd.cmd = MAC_DISABLE; // disable in case already enabled
 3624 		issuecommand(ai, &cmd, &rsp);
 3625 		clear_bit(FLAG_ENABLED, &ai->flags);
 3626 	}
 3627 	if (lock == 1)
 3628 		up(&ai->sem);
 3629 }
 3630 
 3631 static void enable_interrupts( struct airo_info *ai ) {
 3632 	/* Enable the interrupts */
 3633 	OUT4500( ai, EVINTEN, STATUS_INTS );
 3634 }
 3635 
 3636 static void disable_interrupts( struct airo_info *ai ) {
 3637 	OUT4500( ai, EVINTEN, 0 );
 3638 }
 3639 
 3640 static void mpi_receive_802_3(struct airo_info *ai)
 3641 {
 3642 	RxFid rxd;
 3643 	int len = 0;
 3644 	struct sk_buff *skb;
 3645 	char *buffer;
 3646 	int off = 0;
 3647 	MICBuffer micbuf;
 3648 
 3649 	memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
 3650 	/* Make sure we got something */
 3651 	if (rxd.rdy && rxd.valid == 0) {
 3652 		len = rxd.len + 12;
 3653 		if (len < 12 || len > 2048)
 3654 			goto badrx;
 3655 
 3656 		skb = dev_alloc_skb(len);
 3657 		if (!skb) {
 3658 			ai->dev->stats.rx_dropped++;
 3659 			goto badrx;
 3660 		}
 3661 		buffer = skb_put(skb,len);
 3662 		memcpy(buffer, ai->rxfids[0].virtual_host_addr, ETH_ALEN * 2);
 3663 		if (ai->micstats.enabled) {
 3664 			memcpy(&micbuf,
 3665 				ai->rxfids[0].virtual_host_addr + ETH_ALEN * 2,
 3666 				sizeof(micbuf));
 3667 			if (ntohs(micbuf.typelen) <= 0x05DC) {
 3668 				if (len <= sizeof(micbuf) + ETH_ALEN * 2)
 3669 					goto badmic;
 3670 
 3671 				off = sizeof(micbuf);
 3672 				skb_trim (skb, len - off);
 3673 			}
 3674 		}
 3675 		memcpy(buffer + ETH_ALEN * 2,
 3676 			ai->rxfids[0].virtual_host_addr + ETH_ALEN * 2 + off,
 3677 			len - ETH_ALEN * 2 - off);
 3678 		if (decapsulate (ai, &micbuf, (etherHead*)buffer, len - off - ETH_ALEN * 2)) {
 3679 badmic:
 3680 			dev_kfree_skb_irq (skb);
 3681 			goto badrx;
 3682 		}
 3683 #ifdef WIRELESS_SPY
 3684 		if (ai->spy_data.spy_number > 0) {
 3685 			char *sa;
 3686 			struct iw_quality wstats;
 3687 			/* Prepare spy data : addr + qual */
 3688 			sa = buffer + ETH_ALEN;
 3689 			wstats.qual = 0; /* XXX Where do I get that info from ??? */
 3690 			wstats.level = 0;
 3691 			wstats.updated = 0;
 3692 			/* Update spy records */
 3693 			wireless_spy_update(ai->dev, sa, &wstats);
 3694 		}
 3695 #endif /* WIRELESS_SPY */
 3696 
 3697 		skb->ip_summed = CHECKSUM_NONE;
 3698 		skb->protocol = eth_type_trans(skb, ai->dev);
 3699 		netif_rx(skb);
 3700 	}
 3701 badrx:
 3702 	if (rxd.valid == 0) {
 3703 		rxd.valid = 1;
 3704 		rxd.rdy = 0;
 3705 		rxd.len = PKTSIZE;
 3706 		memcpy_toio(ai->rxfids[0].card_ram_off, &rxd, sizeof(rxd));
 3707 	}
 3708 }
 3709 
 3710 static void mpi_receive_802_11(struct airo_info *ai)
 3711 {
 3712 	RxFid rxd;
 3713 	struct sk_buff *skb = NULL;
 3714 	u16 len, hdrlen = 0;
 3715 	__le16 fc;
 3716 	struct rx_hdr hdr;
 3717 	u16 gap;
 3718 	u16 *buffer;
 3719 	char *ptr = ai->rxfids[0].virtual_host_addr + 4;
 3720 
 3721 	memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
 3722 	memcpy ((char *)&hdr, ptr, sizeof(hdr));
 3723 	ptr += sizeof(hdr);
 3724 	/* Bad CRC. Ignore packet */
 3725 	if (le16_to_cpu(hdr.status) & 2)
 3726 		hdr.len = 0;
 3727 	if (ai->wifidev == NULL)
 3728 		hdr.len = 0;
 3729 	len = le16_to_cpu(hdr.len);
 3730 	if (len > AIRO_DEF_MTU) {
 3731 		airo_print_err(ai->dev->name, "Bad size %d", len);
 3732 		goto badrx;
 3733 	}
 3734 	if (len == 0)
 3735 		goto badrx;
 3736 
 3737 	fc = get_unaligned((__le16 *)ptr);
 3738 	hdrlen = header_len(fc);
 3739 
 3740 	skb = dev_alloc_skb( len + hdrlen + 2 );
 3741 	if ( !skb ) {
 3742 		ai->dev->stats.rx_dropped++;
 3743 		goto badrx;
 3744 	}
 3745 	buffer = (u16*)skb_put (skb, len + hdrlen);
 3746 	memcpy ((char *)buffer, ptr, hdrlen);
 3747 	ptr += hdrlen;
 3748 	if (hdrlen == 24)
 3749 		ptr += 6;
 3750 	gap = get_unaligned_le16(ptr);
 3751 	ptr += sizeof(__le16);
 3752 	if (gap) {
 3753 		if (gap <= 8)
 3754 			ptr += gap;
 3755 		else
 3756 			airo_print_err(ai->dev->name,
 3757 			    "gaplen too big. Problems will follow...");
 3758 	}
 3759 	memcpy ((char *)buffer + hdrlen, ptr, len);
 3760 	ptr += len;
 3761 #ifdef IW_WIRELESS_SPY	  /* defined in iw_handler.h */
 3762 	if (ai->spy_data.spy_number > 0) {
 3763 		char *sa;
 3764 		struct iw_quality wstats;
 3765 		/* Prepare spy data : addr + qual */
 3766 		sa = (char*)buffer + 10;
 3767 		wstats.qual = hdr.rssi[0];
 3768 		if (ai->rssi)
 3769 			wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
 3770 		else
 3771 			wstats.level = (hdr.rssi[1] + 321) / 2;
 3772 		wstats.noise = ai->wstats.qual.noise;
 3773 		wstats.updated = IW_QUAL_QUAL_UPDATED
 3774 			| IW_QUAL_LEVEL_UPDATED
 3775 			| IW_QUAL_DBM;
 3776 		/* Update spy records */
 3777 		wireless_spy_update(ai->dev, sa, &wstats);
 3778 	}
 3779 #endif /* IW_WIRELESS_SPY */
 3780 	skb_reset_mac_header(skb);
 3781 	skb->pkt_type = PACKET_OTHERHOST;
 3782 	skb->dev = ai->wifidev;
 3783 	skb->protocol = htons(ETH_P_802_2);
 3784 	skb->ip_summed = CHECKSUM_NONE;
 3785 	netif_rx( skb );
 3786 
 3787 badrx:
 3788 	if (rxd.valid == 0) {
 3789 		rxd.valid = 1;
 3790 		rxd.rdy = 0;
 3791 		rxd.len = PKTSIZE;
 3792 		memcpy_toio(ai->rxfids[0].card_ram_off, &rxd, sizeof(rxd));
 3793 	}
 3794 }
 3795 
 3796 static inline void set_auth_type(struct airo_info *local, int auth_type)
 3797 {
 3798 	local->config.authType = auth_type;
 3799 	/* Cache the last auth type used (of AUTH_OPEN and AUTH_ENCRYPT).
 3800 	 * Used by airo_set_auth()
 3801 	 */
 3802 	if (auth_type == AUTH_OPEN || auth_type == AUTH_ENCRYPT)
 3803 		local->last_auth = auth_type;
 3804 }
 3805 
 3806 static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
 3807 {
 3808 	Cmd cmd;
 3809 	Resp rsp;
 3810 	int status;
 3811 	SsidRid mySsid;
 3812 	__le16 lastindex;
 3813 	WepKeyRid wkr;
 3814 	int rc;
 3815 
 3816 	memset( &mySsid, 0, sizeof( mySsid ) );
 3817 	kfree (ai->flash);
 3818 	ai->flash = NULL;
 3819 
 3820 	/* The NOP is the first step in getting the card going */
 3821 	cmd.cmd = NOP;
 3822 	cmd.parm0 = cmd.parm1 = cmd.parm2 = 0;
 3823 	if (lock && down_interruptible(&ai->sem))
 3824 		return ERROR;
 3825 	if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
 3826 		if (lock)
 3827 			up(&ai->sem);
 3828 		return ERROR;
 3829 	}
 3830 	disable_MAC( ai, 0);
 3831 
 3832 	// Let's figure out if we need to use the AUX port
 3833 	if (!test_bit(FLAG_MPI,&ai->flags)) {
 3834 		cmd.cmd = CMD_ENABLEAUX;
 3835 		if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
 3836 			if (lock)
 3837 				up(&ai->sem);
 3838 			airo_print_err(ai->dev->name, "Error checking for AUX port");
 3839 			return ERROR;
 3840 		}
 3841 		if (!aux_bap || rsp.status & 0xff00) {
 3842 			ai->bap_read = fast_bap_read;
 3843 			airo_print_dbg(ai->dev->name, "Doing fast bap_reads");
 3844 		} else {
 3845 			ai->bap_read = aux_bap_read;
 3846 			airo_print_dbg(ai->dev->name, "Doing AUX bap_reads");
 3847 		}
 3848 	}
 3849 	if (lock)
 3850 		up(&ai->sem);
 3851 	if (ai->config.len == 0) {
 3852 		int i;
 3853 		tdsRssiRid rssi_rid;
 3854 		CapabilityRid cap_rid;
 3855 
 3856 		kfree(ai->SSID);
 3857 		ai->SSID = NULL;
 3858 		// general configuration (read/modify/write)
 3859 		status = readConfigRid(ai, lock);
 3860 		if ( status != SUCCESS ) return ERROR;
 3861 
 3862 		status = readCapabilityRid(ai, &cap_rid, lock);
 3863 		if ( status != SUCCESS ) return ERROR;
 3864 
 3865 		status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),lock);
 3866 		if ( status == SUCCESS ) {
 3867 			if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL)
 3868 				memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); /* Skip RID length member */
 3869 		}
 3870 		else {
 3871 			kfree(ai->rssi);
 3872 			ai->rssi = NULL;
 3873 			if (cap_rid.softCap & cpu_to_le16(8))
 3874 				ai->config.rmode |= RXMODE_NORMALIZED_RSSI;
 3875 			else
 3876 				airo_print_warn(ai->dev->name, "unknown received signal "
 3877 						"level scale");
 3878 		}
 3879 		ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
 3880 		set_auth_type(ai, AUTH_OPEN);
 3881 		ai->config.modulation = MOD_CCK;
 3882 
 3883 		if (le16_to_cpu(cap_rid.len) >= sizeof(cap_rid) &&
 3884 		    (cap_rid.extSoftCap & cpu_to_le16(1)) &&
 3885 		    micsetup(ai) == SUCCESS) {
 3886 			ai->config.opmode |= MODE_MIC;
 3887 			set_bit(FLAG_MIC_CAPABLE, &ai->flags);
 3888 		}
 3889 
 3890 		/* Save off the MAC */
 3891 		for( i = 0; i < ETH_ALEN; i++ ) {
 3892 			mac[i] = ai->config.macAddr[i];
 3893 		}
 3894 
 3895 		/* Check to see if there are any insmod configured
 3896 		   rates to add */
 3897 		if ( rates[0] ) {
 3898 			memset(ai->config.rates,0,sizeof(ai->config.rates));
 3899 			for( i = 0; i < 8 && rates[i]; i++ ) {
 3900 				ai->config.rates[i] = rates[i];
 3901 			}
 3902 		}
 3903 		set_bit (FLAG_COMMIT, &ai->flags);
 3904 	}
 3905 
 3906 	/* Setup the SSIDs if present */
 3907 	if ( ssids[0] ) {
 3908 		int i;
 3909 		for( i = 0; i < 3 && ssids[i]; i++ ) {
 3910 			size_t len = strlen(ssids[i]);
 3911 			if (len > 32)
 3912 				len = 32;
 3913 			mySsid.ssids[i].len = cpu_to_le16(len);
 3914 			memcpy(mySsid.ssids[i].ssid, ssids[i], len);
 3915 		}
 3916 		mySsid.len = cpu_to_le16(sizeof(mySsid));
 3917 	}
 3918 
 3919 	status = writeConfigRid(ai, lock);
 3920 	if ( status != SUCCESS ) return ERROR;
 3921 
 3922 	/* Set up the SSID list */
 3923 	if ( ssids[0] ) {
 3924 		status = writeSsidRid(ai, &mySsid, lock);
 3925 		if ( status != SUCCESS ) return ERROR;
 3926 	}
 3927 
 3928 	status = enable_MAC(ai, lock);
 3929 	if (status != SUCCESS)
 3930 		return ERROR;
 3931 
 3932 	/* Grab the initial wep key, we gotta save it for auto_wep */
 3933 	rc = readWepKeyRid(ai, &wkr, 1, lock);
 3934 	if (rc == SUCCESS) do {
 3935 		lastindex = wkr.kindex;
 3936 		if (wkr.kindex == cpu_to_le16(0xffff)) {
 3937 			ai->defindex = wkr.mac[0];
 3938 		}
 3939 		rc = readWepKeyRid(ai, &wkr, 0, lock);
 3940 	} while(lastindex != wkr.kindex);
 3941 
 3942 	try_auto_wep(ai);
 3943 
 3944 	return SUCCESS;
 3945 }
 3946 
 3947 static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
 3948         // Im really paranoid about letting it run forever!
 3949 	int max_tries = 600000;
 3950 
 3951 	if (IN4500(ai, EVSTAT) & EV_CMD)
 3952 		OUT4500(ai, EVACK, EV_CMD);
 3953 
 3954 	OUT4500(ai, PARAM0, pCmd->parm0);
 3955 	OUT4500(ai, PARAM1, pCmd->parm1);
 3956 	OUT4500(ai, PARAM2, pCmd->parm2);
 3957 	OUT4500(ai, COMMAND, pCmd->cmd);
 3958 
 3959 	while (max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0) {
 3960 		if ((IN4500(ai, COMMAND)) == pCmd->cmd)
 3961 			// PC4500 didn't notice command, try again
 3962 			OUT4500(ai, COMMAND, pCmd->cmd);
 3963 		if (!in_atomic() && (max_tries & 255) == 0)
 3964 			schedule();
 3965 	}
 3966 
 3967 	if ( max_tries == -1 ) {
 3968 		airo_print_err(ai->dev->name,
 3969 			"Max tries exceeded when issuing command");
 3970 		if (IN4500(ai, COMMAND) & COMMAND_BUSY)
 3971 			OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
 3972 		return ERROR;
 3973 	}
 3974 
 3975 	// command completed
 3976 	pRsp->status = IN4500(ai, STATUS);
 3977 	pRsp->rsp0 = IN4500(ai, RESP0);
 3978 	pRsp->rsp1 = IN4500(ai, RESP1);
 3979 	pRsp->rsp2 = IN4500(ai, RESP2);
 3980 	if ((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_SOFTRESET)
 3981 		airo_print_err(ai->dev->name,
 3982 			"cmd:%x status:%x rsp0:%x rsp1:%x rsp2:%x",
 3983 			pCmd->cmd, pRsp->status, pRsp->rsp0, pRsp->rsp1,
 3984 			pRsp->rsp2);
 3985 
 3986 	// clear stuck command busy if necessary
 3987 	if (IN4500(ai, COMMAND) & COMMAND_BUSY) {
 3988 		OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
 3989 	}
 3990 	// acknowledge processing the status/response
 3991 	OUT4500(ai, EVACK, EV_CMD);
 3992 
 3993 	return SUCCESS;
 3994 }
 3995 
 3996 /* Sets up the bap to start exchange data.  whichbap should
 3997  * be one of the BAP0 or BAP1 defines.  Locks should be held before
 3998  * calling! */
 3999 static int bap_setup(struct airo_info *ai, u16 rid, u16 offset, int whichbap )
 4000 {
 4001 	int timeout = 50;
 4002 	int max_tries = 3;
 4003 
 4004 	OUT4500(ai, SELECT0+whichbap, rid);
 4005 	OUT4500(ai, OFFSET0+whichbap, offset);
 4006 	while (1) {
 4007 		int status = IN4500(ai, OFFSET0+whichbap);
 4008 		if (status & BAP_BUSY) {
 4009                         /* This isn't really a timeout, but its kinda
 4010 			   close */
 4011 			if (timeout--) {
 4012 				continue;
 4013 			}
 4014 		} else if ( status & BAP_ERR ) {
 4015 			/* invalid rid or offset */
 4016 			airo_print_err(ai->dev->name, "BAP error %x %d",
 4017 				status, whichbap );
 4018 			return ERROR;
 4019 		} else if (status & BAP_DONE) { // success
 4020 			return SUCCESS;
 4021 		}
 4022 		if ( !(max_tries--) ) {
 4023 			airo_print_err(ai->dev->name,
 4024 				"BAP setup error too many retries\n");
 4025 			return ERROR;
 4026 		}
 4027 		// -- PC4500 missed it, try again
 4028 		OUT4500(ai, SELECT0+whichbap, rid);
 4029 		OUT4500(ai, OFFSET0+whichbap, offset);
 4030 		timeout = 50;
 4031 	}
 4032 }
 4033 
 4034 /* should only be called by aux_bap_read.  This aux function and the
 4035    following use concepts not documented in the developers guide.  I
 4036    got them from a patch given to my by Aironet */
 4037 static u16 aux_setup(struct airo_info *ai, u16 page,
 4038 		     u16 offset, u16 *len)
 4039 {
 4040 	u16 next;
 4041 
 4042 	OUT4500(ai, AUXPAGE, page);
 4043 	OUT4500(ai, AUXOFF, 0);
 4044 	next = IN4500(ai, AUXDATA);
 4045 	*len = IN4500(ai, AUXDATA)&0xff;
 4046 	if (offset != 4) OUT4500(ai, AUXOFF, offset);
 4047 	return next;
 4048 }
 4049 
 4050 /* requires call to bap_setup() first */
 4051 static int aux_bap_read(struct airo_info *ai, __le16 *pu16Dst,
 4052 			int bytelen, int whichbap)
 4053 {
 4054 	u16 len;
 4055 	u16 page;
 4056 	u16 offset;
 4057 	u16 next;
 4058 	int words;
 4059 	int i;
 4060 	unsigned long flags;
 4061 
 4062 	spin_lock_irqsave(&ai->aux_lock, flags);
 4063 	page = IN4500(ai, SWS0+whichbap);
 4064 	offset = IN4500(ai, SWS2+whichbap);
 4065 	next = aux_setup(ai, page, offset, &len);
 4066 	words = (bytelen+1)>>1;
 4067 
 4068 	for (i=0; i<words;) {
 4069 		int count;
 4070 		count = (len>>1) < (words-i) ? (len>>1) : (words-i);
 4071 		if ( !do8bitIO )
 4072 			insw( ai->dev->base_addr+DATA0+whichbap,
 4073 			      pu16Dst+i,count );
 4074 		else
 4075 			insb( ai->dev->base_addr+DATA0+whichbap,
 4076 			      pu16Dst+i, count << 1 );
 4077 		i += count;
 4078 		if (i<words) {
 4079 			next = aux_setup(ai, next, 4, &len);
 4080 		}
 4081 	}
 4082 	spin_unlock_irqrestore(&ai->aux_lock, flags);
 4083 	return SUCCESS;
 4084 }
 4085 
 4086 
 4087 /* requires call to bap_setup() first */
 4088 static int fast_bap_read(struct airo_info *ai, __le16 *pu16Dst,
 4089 			 int bytelen, int whichbap)
 4090 {
 4091 	bytelen = (bytelen + 1) & (~1); // round up to even value
 4092 	if ( !do8bitIO )
 4093 		insw( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen>>1 );
 4094 	else
 4095 		insb( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen );
 4096 	return SUCCESS;
 4097 }
 4098 
 4099 /* requires call to bap_setup() first */
 4100 static int bap_write(struct airo_info *ai, const __le16 *pu16Src,
 4101 		     int bytelen, int whichbap)
 4102 {
 4103 	bytelen = (bytelen + 1) & (~1); // round up to even value
 4104 	if ( !do8bitIO )
 4105 		outsw( ai->dev->base_addr+DATA0+whichbap,
 4106 		       pu16Src, bytelen>>1 );
 4107 	else
 4108 		outsb( ai->dev->base_addr+DATA0+whichbap, pu16Src, bytelen );
 4109 	return SUCCESS;
 4110 }
 4111 
 4112 static int PC4500_accessrid(struct airo_info *ai, u16 rid, u16 accmd)
 4113 {
 4114 	Cmd cmd; /* for issuing commands */
 4115 	Resp rsp; /* response from commands */
 4116 	u16 status;
 4117 
 4118 	memset(&cmd, 0, sizeof(cmd));
 4119 	cmd.cmd = accmd;
 4120 	cmd.parm0 = rid;
 4121 	status = issuecommand(ai, &cmd, &rsp);
 4122 	if (status != 0) return status;
 4123 	if ( (rsp.status & 0x7F00) != 0) {
 4124 		return (accmd << 8) + (rsp.rsp0 & 0xFF);
 4125 	}
 4126 	return 0;
 4127 }
 4128 
 4129 /*  Note, that we are using BAP1 which is also used by transmit, so
 4130  *  we must get a lock. */
 4131 static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len, int lock)
 4132 {
 4133 	u16 status;
 4134         int rc = SUCCESS;
 4135 
 4136 	if (lock) {
 4137 		if (down_interruptible(&ai->sem))
 4138 			return ERROR;
 4139 	}
 4140 	if (test_bit(FLAG_MPI,&ai->flags)) {
 4141 		Cmd cmd;
 4142 		Resp rsp;
 4143 
 4144 		memset(&cmd, 0, sizeof(cmd));
 4145 		memset(&rsp, 0, sizeof(rsp));
 4146 		ai->config_desc.rid_desc.valid = 1;
 4147 		ai->config_desc.rid_desc.len = RIDSIZE;
 4148 		ai->config_desc.rid_desc.rid = 0;
 4149 		ai->config_desc.rid_desc.host_addr = ai->ridbus;
 4150 
 4151 		cmd.cmd = CMD_ACCESS;
 4152 		cmd.parm0 = rid;
 4153 
 4154 		memcpy_toio(ai->config_desc.card_ram_off,
 4155 			&ai->config_desc.rid_desc, sizeof(Rid));
 4156 
 4157 		rc = issuecommand(ai, &cmd, &rsp);
 4158 
 4159 		if (rsp.status & 0x7f00)
 4160 			rc = rsp.rsp0;
 4161 		if (!rc)
 4162 			memcpy(pBuf, ai->config_desc.virtual_host_addr, len);
 4163 		goto done;
 4164 	} else {
 4165 		if ((status = PC4500_accessrid(ai, rid, CMD_ACCESS))!=SUCCESS) {
 4166 	                rc = status;
 4167 	                goto done;
 4168 	        }
 4169 		if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
 4170 			rc = ERROR;
 4171 	                goto done;
 4172 	        }
 4173 		// read the rid length field
 4174 		bap_read(ai, pBuf, 2, BAP1);
 4175 		// length for remaining part of rid
 4176 		len = min(len, (int)le16_to_cpu(*(__le16*)pBuf)) - 2;
 4177 
 4178 		if ( len <= 2 ) {
 4179 			airo_print_err(ai->dev->name,
 4180 				"Rid %x has a length of %d which is too short",
 4181 				(int)rid, (int)len );
 4182 			rc = ERROR;
 4183 	                goto done;
 4184 		}
 4185 		// read remainder of the rid
 4186 		rc = bap_read(ai, ((__le16*)pBuf)+1, len, BAP1);
 4187 	}
 4188 done:
 4189 	if (lock)
 4190 		up(&ai->sem);
 4191 	return rc;
 4192 }
 4193 
 4194 /*  Note, that we are using BAP1 which is also used by transmit, so
 4195  *  make sure this isn't called when a transmit is happening */
 4196 static int PC4500_writerid(struct airo_info *ai, u16 rid,
 4197 			   const void *pBuf, int len, int lock)
 4198 {
 4199 	u16 status;
 4200 	int rc = SUCCESS;
 4201 
 4202 	*(__le16*)pBuf = cpu_to_le16((u16)len);
 4203 
 4204 	if (lock) {
 4205 		if (down_interruptible(&ai->sem))
 4206 			return ERROR;
 4207 	}
 4208 	if (test_bit(FLAG_MPI,&ai->flags)) {
 4209 		Cmd cmd;
 4210 		Resp rsp;
 4211 
 4212 		if (test_bit(FLAG_ENABLED, &ai->flags) && (RID_WEP_TEMP != rid))
 4213 			airo_print_err(ai->dev->name,
 4214 				"%s: MAC should be disabled (rid=%04x)",
 4215 				__func__, rid);
 4216 		memset(&cmd, 0, sizeof(cmd));
 4217 		memset(&rsp, 0, sizeof(rsp));
 4218 
 4219 		ai->config_desc.rid_desc.valid = 1;
 4220 		ai->config_desc.rid_desc.len = *((u16 *)pBuf);
 4221 		ai->config_desc.rid_desc.rid = 0;
 4222 
 4223 		cmd.cmd = CMD_WRITERID;
 4224 		cmd.parm0 = rid;
 4225 
 4226 		memcpy_toio(ai->config_desc.card_ram_off,
 4227 			&ai->config_desc.rid_desc, sizeof(Rid));
 4228 
 4229 		if (len < 4 || len > 2047) {
 4230 			airo_print_err(ai->dev->name, "%s: len=%d", __func__, len);
 4231 			rc = -1;
 4232 		} else {
 4233 			memcpy(ai->config_desc.virtual_host_addr,
 4234 				pBuf, len);
 4235 
 4236 			rc = issuecommand(ai, &cmd, &rsp);
 4237 			if ((rc & 0xff00) != 0) {
 4238 				airo_print_err(ai->dev->name, "%s: Write rid Error %d",
 4239 						__func__, rc);
 4240 				airo_print_err(ai->dev->name, "%s: Cmd=%04x",
 4241 						__func__, cmd.cmd);
 4242 			}
 4243 
 4244 			if ((rsp.status & 0x7f00))
 4245 				rc = rsp.rsp0;
 4246 		}
 4247 	} else {
 4248 		// --- first access so that we can write the rid data
 4249 		if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != 0) {
 4250 	                rc = status;
 4251 	                goto done;
 4252 	        }
 4253 		// --- now write the rid data
 4254 		if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
 4255 	                rc = ERROR;
 4256 	                goto done;
 4257 	        }
 4258 		bap_write(ai, pBuf, len, BAP1);
 4259 		// ---now commit the rid data
 4260 		rc = PC4500_accessrid(ai, rid, 0x100|CMD_ACCESS);
 4261 	}
 4262 done:
 4263 	if (lock)
 4264 		up(&ai->sem);
 4265         return rc;
 4266 }
 4267 
 4268 /* Allocates a FID to be used for transmitting packets.  We only use
 4269    one for now. */
 4270 static u16 transmit_allocate(struct airo_info *ai, int lenPayload, int raw)
 4271 {
 4272 	unsigned int loop = 3000;
 4273 	Cmd cmd;
 4274 	Resp rsp;
 4275 	u16 txFid;
 4276 	__le16 txControl;
 4277 
 4278 	cmd.cmd = CMD_ALLOCATETX;
 4279 	cmd.parm0 = lenPayload;
 4280 	if (down_interruptible(&ai->sem))
 4281 		return ERROR;
 4282 	if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
 4283 		txFid = ERROR;
 4284 		goto done;
 4285 	}
 4286 	if ( (rsp.status & 0xFF00) != 0) {
 4287 		txFid = ERROR;
 4288 		goto done;
 4289 	}
 4290 	/* wait for the allocate event/indication
 4291 	 * It makes me kind of nervous that this can just sit here and spin,
 4292 	 * but in practice it only loops like four times. */
 4293 	while (((IN4500(ai, EVSTAT) & EV_ALLOC) == 0) && --loop);
 4294 	if (!loop) {
 4295 		txFid = ERROR;
 4296 		goto done;
 4297 	}
 4298 
 4299 	// get the allocated fid and acknowledge
 4300 	txFid = IN4500(ai, TXALLOCFID);
 4301 	OUT4500(ai, EVACK, EV_ALLOC);
 4302 
 4303 	/*  The CARD is pretty cool since it converts the ethernet packet
 4304 	 *  into 802.11.  Also note that we don't release the FID since we
 4305 	 *  will be using the same one over and over again. */
 4306 	/*  We only have to setup the control once since we are not
 4307 	 *  releasing the fid. */
 4308 	if (raw)
 4309 		txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_11
 4310 			| TXCTL_ETHERNET | TXCTL_NORELEASE);
 4311 	else
 4312 		txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_3
 4313 			| TXCTL_ETHERNET | TXCTL_NORELEASE);
 4314 	if (bap_setup(ai, txFid, 0x0008, BAP1) != SUCCESS)
 4315 		txFid = ERROR;
 4316 	else
 4317 		bap_write(ai, &txControl, sizeof(txControl), BAP1);
 4318 
 4319 done:
 4320 	up(&ai->sem);
 4321 
 4322 	return txFid;
 4323 }
 4324 
 4325 /* In general BAP1 is dedicated to transmiting packets.  However,
 4326    since we need a BAP when accessing RIDs, we also use BAP1 for that.
 4327    Make sure the BAP1 spinlock is held when this is called. */
 4328 static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket)
 4329 {
 4330 	__le16 payloadLen;
 4331 	Cmd cmd;
 4332 	Resp rsp;
 4333 	int miclen = 0;
 4334 	u16 txFid = len;
 4335 	MICBuffer pMic;
 4336 
 4337 	len >>= 16;
 4338 
 4339 	if (len <= ETH_ALEN * 2) {
 4340 		airo_print_warn(ai->dev->name, "Short packet %d", len);
 4341 		return ERROR;
 4342 	}
 4343 	len -= ETH_ALEN * 2;
 4344 
 4345 	if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled && 
 4346 	    (ntohs(((__be16 *)pPacket)[6]) != 0x888E)) {
 4347 		if (encapsulate(ai,(etherHead *)pPacket,&pMic,len) != SUCCESS)
 4348 			return ERROR;
 4349 		miclen = sizeof(pMic);
 4350 	}
 4351 	// packet is destination[6], source[6], payload[len-12]
 4352 	// write the payload length and dst/src/payload
 4353 	if (bap_setup(ai, txFid, 0x0036, BAP1) != SUCCESS) return ERROR;
 4354 	/* The hardware addresses aren't counted as part of the payload, so
 4355 	 * we have to subtract the 12 bytes for the addresses off */
 4356 	payloadLen = cpu_to_le16(len + miclen);
 4357 	bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
 4358 	bap_write(ai, (__le16*)pPacket, sizeof(etherHead), BAP1);
 4359 	if (miclen)
 4360 		bap_write(ai, (__le16*)&pMic, miclen, BAP1);
 4361 	bap_write(ai, (__le16*)(pPacket + sizeof(etherHead)), len, BAP1);
 4362 	// issue the transmit command
 4363 	memset( &cmd, 0, sizeof( cmd ) );
 4364 	cmd.cmd = CMD_TRANSMIT;
 4365 	cmd.parm0 = txFid;
 4366 	if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
 4367 	if ( (rsp.status & 0xFF00) != 0) return ERROR;
 4368 	return SUCCESS;
 4369 }
 4370 
 4371 static int transmit_802_11_packet(struct airo_info *ai, int len, char *pPacket)
 4372 {
 4373 	__le16 fc, payloadLen;
 4374 	Cmd cmd;
 4375 	Resp rsp;
 4376 	int hdrlen;
 4377 	static u8 tail[(30-10) + 2 + 6] = {[30-10] = 6};
 4378 	/* padding of header to full size + le16 gaplen (6) + gaplen bytes */
 4379 	u16 txFid = len;
 4380 	len >>= 16;
 4381 
 4382 	fc = *(__le16*)pPacket;
 4383 	hdrlen = header_len(fc);
 4384 
 4385 	if (len < hdrlen) {
 4386 		airo_print_warn(ai->dev->name, "Short packet %d", len);
 4387 		return ERROR;
 4388 	}
 4389 
 4390 	/* packet is 802.11 header +  payload
 4391 	 * write the payload length and dst/src/payload */
 4392 	if (bap_setup(ai, txFid, 6, BAP1) != SUCCESS) return ERROR;
 4393 	/* The 802.11 header aren't counted as part of the payload, so
 4394 	 * we have to subtract the header bytes off */
 4395 	payloadLen = cpu_to_le16(len-hdrlen);
 4396 	bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
 4397 	if (bap_setup(ai, txFid, 0x0014, BAP1) != SUCCESS) return ERROR;
 4398 	bap_write(ai, (__le16 *)pPacket, hdrlen, BAP1);
 4399 	bap_write(ai, (__le16 *)(tail + (hdrlen - 10)), 38 - hdrlen, BAP1);
 4400 
 4401 	bap_write(ai, (__le16 *)(pPacket + hdrlen), len - hdrlen, BAP1);
 4402 	// issue the transmit command
 4403 	memset( &cmd, 0, sizeof( cmd ) );
 4404 	cmd.cmd = CMD_TRANSMIT;
 4405 	cmd.parm0 = txFid;
 4406 	if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
 4407 	if ( (rsp.status & 0xFF00) != 0) return ERROR;
 4408 	return SUCCESS;
 4409 }
 4410 
 4411 /*
 4412  *  This is the proc_fs routines.  It is a bit messier than I would
 4413  *  like!  Feel free to clean it up!
 4414  */
 4415 
 4416 static ssize_t proc_read( struct file *file,
 4417 			  char __user *buffer,
 4418 			  size_t len,
 4419 			  loff_t *offset);
 4420 
 4421 static ssize_t proc_write( struct file *file,
 4422 			   const char __user *buffer,
 4423 			   size_t len,
 4424 			   loff_t *offset );
 4425 static int proc_close( struct inode *inode, struct file *file );
 4426 
 4427 static int proc_stats_open( struct inode *inode, struct file *file );
 4428 static int proc_statsdelta_open( struct inode *inode, struct file *file );
 4429 static int proc_status_open( struct inode *inode, struct file *file );
 4430 static int proc_SSID_open( struct inode *inode, struct file *file );
 4431 static int proc_APList_open( struct inode *inode, struct file *file );
 4432 static int proc_BSSList_open( struct inode *inode, struct file *file );
 4433 static int proc_config_open( struct inode *inode, struct file *file );
 4434 static int proc_wepkey_open( struct inode *inode, struct file *file );
 4435 
 4436 static const struct file_operations proc_statsdelta_ops = {
 4437 	.owner		= THIS_MODULE,
 4438 	.read		= proc_read,
 4439 	.open		= proc_statsdelta_open,
 4440 	.release	= proc_close,
 4441 	.llseek		= default_llseek,
 4442 };
 4443 
 4444 static const struct file_operations proc_stats_ops = {
 4445 	.owner		= THIS_MODULE,
 4446 	.read		= proc_read,
 4447 	.open		= proc_stats_open,
 4448 	.release	= proc_close,
 4449 	.llseek		= default_llseek,
 4450 };
 4451 
 4452 static const struct file_operations proc_status_ops = {
 4453 	.owner		= THIS_MODULE,
 4454 	.read		= proc_read,
 4455 	.open		= proc_status_open,
 4456 	.release	= proc_close,
 4457 	.llseek		= default_llseek,
 4458 };
 4459 
 4460 static const struct file_operations proc_SSID_ops = {
 4461 	.owner		= THIS_MODULE,
 4462 	.read		= proc_read,
 4463 	.write		= proc_write,
 4464 	.open		= proc_SSID_open,
 4465 	.release	= proc_close,
 4466 	.llseek		= default_llseek,
 4467 };
 4468 
 4469 static const struct file_operations proc_BSSList_ops = {
 4470 	.owner		= THIS_MODULE,
 4471 	.read		= proc_read,
 4472 	.write		= proc_write,
 4473 	.open		= proc_BSSList_open,
 4474 	.release	= proc_close,
 4475 	.llseek		= default_llseek,
 4476 };
 4477 
 4478 static const struct file_operations proc_APList_ops = {
 4479 	.owner		= THIS_MODULE,
 4480 	.read		= proc_read,
 4481 	.write		= proc_write,
 4482 	.open		= proc_APList_open,
 4483 	.release	= proc_close,
 4484 	.llseek		= default_llseek,
 4485 };
 4486 
 4487 static const struct file_operations proc_config_ops = {
 4488 	.owner		= THIS_MODULE,
 4489 	.read		= proc_read,
 4490 	.write		= proc_write,
 4491 	.open		= proc_config_open,
 4492 	.release	= proc_close,
 4493 	.llseek		= default_llseek,
 4494 };
 4495 
 4496 static const struct file_operations proc_wepkey_ops = {
 4497 	.owner		= THIS_MODULE,
 4498 	.read		= proc_read,
 4499 	.write		= proc_write,
 4500 	.open		= proc_wepkey_open,
 4501 	.release	= proc_close,
 4502 	.llseek		= default_llseek,
 4503 };
 4504 
 4505 static struct proc_dir_entry *airo_entry;
 4506 
 4507 struct proc_data {
 4508 	int release_buffer;
 4509 	int readlen;
 4510 	char *rbuffer;
 4511 	int writelen;
 4512 	int maxwritelen;
 4513 	char *wbuffer;
 4514 	void (*on_close) (struct inode *, struct file *);
 4515 };
 4516 
 4517 static int setup_proc_entry( struct net_device *dev,
 4518 			     struct airo_info *apriv ) {
 4519 	struct proc_dir_entry *entry;
 4520 
 4521 	/* First setup the device directory */
 4522 	strcpy(apriv->proc_name,dev->name);
 4523 	apriv->proc_entry = proc_mkdir_mode(apriv->proc_name, airo_perm,
 4524 					    airo_entry);
 4525 	if (!apriv->proc_entry)
 4526 		return -ENOMEM;
 4527 	proc_set_user(apriv->proc_entry, proc_kuid, proc_kgid);
 4528 
 4529 	/* Setup the StatsDelta */
 4530 	entry = proc_create_data("StatsDelta", S_IRUGO & proc_perm,
 4531 				 apriv->proc_entry, &proc_statsdelta_ops, dev);
 4532 	if (!entry)
 4533 		goto fail;
 4534 	proc_set_user(entry, proc_kuid, proc_kgid);
 4535 
 4536 	/* Setup the Stats */
 4537 	entry = proc_create_data("Stats", S_IRUGO & proc_perm,
 4538 				 apriv->proc_entry, &proc_stats_ops, dev);
 4539 	if (!entry)
 4540 		goto fail;
 4541 	proc_set_user(entry, proc_kuid, proc_kgid);
 4542 
 4543 	/* Setup the Status */
 4544 	entry = proc_create_data("Status", S_IRUGO & proc_perm,
 4545 				 apriv->proc_entry, &proc_status_ops, dev);
 4546 	if (!entry)
 4547 		goto fail;
 4548 	proc_set_user(entry, proc_kuid, proc_kgid);
 4549 
 4550 	/* Setup the Config */
 4551 	entry = proc_create_data("Config", proc_perm,
 4552 				 apriv->proc_entry, &proc_config_ops, dev);
 4553 	if (!entry)
 4554 		goto fail;
 4555 	proc_set_user(entry, proc_kuid, proc_kgid);
 4556 
 4557 	/* Setup the SSID */
 4558 	entry = proc_create_data("SSID", proc_perm,
 4559 				 apriv->proc_entry, &proc_SSID_ops, dev);
 4560 	if (!entry)
 4561 		goto fail;
 4562 	proc_set_user(entry, proc_kuid, proc_kgid);
 4563 
 4564 	/* Setup the APList */
 4565 	entry = proc_create_data("APList", proc_perm,
 4566 				 apriv->proc_entry, &proc_APList_ops, dev);
 4567 	if (!entry)
 4568 		goto fail;
 4569 	proc_set_user(entry, proc_kuid, proc_kgid);
 4570 
 4571 	/* Setup the BSSList */
 4572 	entry = proc_create_data("BSSList", proc_perm,
 4573 				 apriv->proc_entry, &proc_BSSList_ops, dev);
 4574 	if (!entry)
 4575 		goto fail;
 4576 	proc_set_user(entry, proc_kuid, proc_kgid);
 4577 
 4578 	/* Setup the WepKey */
 4579 	entry = proc_create_data("WepKey", proc_perm,
 4580 				 apriv->proc_entry, &proc_wepkey_ops, dev);
 4581 	if (!entry)
 4582 		goto fail;
 4583 	proc_set_user(entry, proc_kuid, proc_kgid);
 4584 	return 0;
 4585 
 4586 fail:
 4587 	remove_proc_subtree(apriv->proc_name, airo_entry);
 4588 	return -ENOMEM;
 4589 }
 4590 
 4591 static int takedown_proc_entry( struct net_device *dev,
 4592 				struct airo_info *apriv )
 4593 {
 4594 	remove_proc_subtree(apriv->proc_name, airo_entry);
 4595 	return 0;
 4596 }
 4597 
 4598 /*
 4599  *  What we want from the proc_fs is to be able to efficiently read
 4600  *  and write the configuration.  To do this, we want to read the
 4601  *  configuration when the file is opened and write it when the file is
 4602  *  closed.  So basically we allocate a read buffer at open and fill it
 4603  *  with data, and allocate a write buffer and read it at close.
 4604  */
 4605 
 4606 /*
 4607  *  The read routine is generic, it relies on the preallocated rbuffer
 4608  *  to supply the data.
 4609  */
 4610 static ssize_t proc_read( struct file *file,
 4611 			  char __user *buffer,
 4612 			  size_t len,
 4613 			  loff_t *offset )
 4614 {
 4615 	struct proc_data *priv = file->private_data;
 4616 
 4617 	if (!priv->rbuffer)
 4618 		return -EINVAL;
 4619 
 4620 	return simple_read_from_buffer(buffer, len, offset, priv->rbuffer,
 4621 					priv->readlen);
 4622 }
 4623 
 4624 /*
 4625  *  The write routine is generic, it fills in a preallocated rbuffer
 4626  *  to supply the data.
 4627  */
 4628 static ssize_t proc_write( struct file *file,
 4629 			   const char __user *buffer,
 4630 			   size_t len,
 4631 			   loff_t *offset )
 4632 {
 4633 	ssize_t ret;
 4634 	struct proc_data *priv = file->private_data;
 4635 
 4636 	if (!priv->wbuffer)
 4637 		return -EINVAL;
 4638 
 4639 	ret = simple_write_to_buffer(priv->wbuffer, priv->maxwritelen, offset,
 4640 					buffer, len);
 4641 	if (ret > 0)
 4642 		priv->writelen = max_t(int, priv->writelen, *offset);
 4643 
 4644 	return ret;
 4645 }
 4646 
 4647 static int proc_status_open(struct inode *inode, struct file *file)
 4648 {
 4649 	struct proc_data *data;
 4650 	struct net_device *dev = PDE_DATA(inode);
 4651 	struct airo_info *apriv = dev->ml_priv;
 4652 	CapabilityRid cap_rid;
 4653 	StatusRid status_rid;
 4654 	u16 mode;
 4655 	int i;
 4656 
 4657 	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 4658 		return -ENOMEM;
 4659 	data = file->private_data;
 4660 	if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
 4661 		kfree (file->private_data);
 4662 		return -ENOMEM;
 4663 	}
 4664 
 4665 	readStatusRid(apriv, &status_rid, 1);
 4666 	readCapabilityRid(apriv, &cap_rid, 1);
 4667 
 4668 	mode = le16_to_cpu(status_rid.mode);
 4669 
 4670         i = sprintf(data->rbuffer, "Status: %s%s%s%s%s%s%s%s%s\n",
 4671                     mode & 1 ? "CFG ": "",
 4672                     mode & 2 ? "ACT ": "",
 4673                     mode & 0x10 ? "SYN ": "",
 4674                     mode & 0x20 ? "LNK ": "",
 4675                     mode & 0x40 ? "LEAP ": "",
 4676                     mode & 0x80 ? "PRIV ": "",
 4677                     mode & 0x100 ? "KEY ": "",
 4678                     mode & 0x200 ? "WEP ": "",
 4679                     mode & 0x8000 ? "ERR ": "");
 4680 	sprintf( data->rbuffer+i, "Mode: %x\n"
 4681 		 "Signal Strength: %d\n"
 4682 		 "Signal Quality: %d\n"
 4683 		 "SSID: %-.*s\n"
 4684 		 "AP: %-.16s\n"
 4685 		 "Freq: %d\n"
 4686 		 "BitRate: %dmbs\n"
 4687 		 "Driver Version: %s\n"
 4688 		 "Device: %s\nManufacturer: %s\nFirmware Version: %s\n"
 4689 		 "Radio type: %x\nCountry: %x\nHardware Version: %x\n"
 4690 		 "Software Version: %x\nSoftware Subversion: %x\n"
 4691 		 "Boot block version: %x\n",
 4692 		 le16_to_cpu(status_rid.mode),
 4693 		 le16_to_cpu(status_rid.normalizedSignalStrength),
 4694 		 le16_to_cpu(status_rid.signalQuality),
 4695 		 le16_to_cpu(status_rid.SSIDlen),
 4696 		 status_rid.SSID,
 4697 		 status_rid.apName,
 4698 		 le16_to_cpu(status_rid.channel),
 4699 		 le16_to_cpu(status_rid.currentXmitRate) / 2,
 4700 		 version,
 4701 		 cap_rid.prodName,
 4702 		 cap_rid.manName,
 4703 		 cap_rid.prodVer,
 4704 		 le16_to_cpu(cap_rid.radioType),
 4705 		 le16_to_cpu(cap_rid.country),
 4706 		 le16_to_cpu(cap_rid.hardVer),
 4707 		 le16_to_cpu(cap_rid.softVer),
 4708 		 le16_to_cpu(cap_rid.softSubVer),
 4709 		 le16_to_cpu(cap_rid.bootBlockVer));
 4710 	data->readlen = strlen( data->rbuffer );
 4711 	return 0;
 4712 }
 4713 
 4714 static int proc_stats_rid_open(struct inode*, struct file*, u16);
 4715 static int proc_statsdelta_open( struct inode *inode,
 4716 				 struct file *file ) {
 4717 	if (file->f_mode&FMODE_WRITE) {
 4718 		return proc_stats_rid_open(inode, file, RID_STATSDELTACLEAR);
 4719 	}
 4720 	return proc_stats_rid_open(inode, file, RID_STATSDELTA);
 4721 }
 4722 
 4723 static int proc_stats_open( struct inode *inode, struct file *file ) {
 4724 	return proc_stats_rid_open(inode, file, RID_STATS);
 4725 }
 4726 
 4727 static int proc_stats_rid_open( struct inode *inode,
 4728 				struct file *file,
 4729 				u16 rid )
 4730 {
 4731 	struct proc_data *data;
 4732 	struct net_device *dev = PDE_DATA(inode);
 4733 	struct airo_info *apriv = dev->ml_priv;
 4734 	StatsRid stats;
 4735 	int i, j;
 4736 	__le32 *vals = stats.vals;
 4737 	int len;
 4738 
 4739 	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 4740 		return -ENOMEM;
 4741 	data = file->private_data;
 4742 	if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) {
 4743 		kfree (file->private_data);
 4744 		return -ENOMEM;
 4745 	}
 4746 
 4747 	readStatsRid(apriv, &stats, rid, 1);
 4748 	len = le16_to_cpu(stats.len);
 4749 
 4750         j = 0;
 4751 	for(i=0; statsLabels[i]!=(char *)-1 && i*4<len; i++) {
 4752 		if (!statsLabels[i]) continue;
 4753 		if (j+strlen(statsLabels[i])+16>4096) {
 4754 			airo_print_warn(apriv->dev->name,
 4755 			       "Potentially disastrous buffer overflow averted!");
 4756 			break;
 4757 		}
 4758 		j+=sprintf(data->rbuffer+j, "%s: %u\n", statsLabels[i],
 4759 				le32_to_cpu(vals[i]));
 4760 	}
 4761 	if (i*4 >= len) {
 4762 		airo_print_warn(apriv->dev->name, "Got a short rid");
 4763 	}
 4764 	data->readlen = j;
 4765 	return 0;
 4766 }
 4767 
 4768 static int get_dec_u16( char *buffer, int *start, int limit ) {
 4769 	u16 value;
 4770 	int valid = 0;
 4771 	for (value = 0; *start < limit && buffer[*start] >= '0' &&
 4772 			buffer[*start] <= '9'; (*start)++) {
 4773 		valid = 1;
 4774 		value *= 10;
 4775 		value += buffer[*start] - '0';
 4776 	}
 4777 	if ( !valid ) return -1;
 4778 	return value;
 4779 }
 4780 
 4781 static int airo_config_commit(struct net_device *dev,
 4782 			      struct iw_request_info *info, void *zwrq,
 4783 			      char *extra);
 4784 
 4785 static inline int sniffing_mode(struct airo_info *ai)
 4786 {
 4787 	return (le16_to_cpu(ai->config.rmode) & le16_to_cpu(RXMODE_MASK)) >=
 4788 		le16_to_cpu(RXMODE_RFMON);
 4789 }
 4790 
 4791 static void proc_config_on_close(struct inode *inode, struct file *file)
 4792 {
 4793 	struct proc_data *data = file->private_data;
 4794 	struct net_device *dev = PDE_DATA(inode);
 4795 	struct airo_info *ai = dev->ml_priv;
 4796 	char *line;
 4797 
 4798 	if ( !data->writelen ) return;
 4799 
 4800 	readConfigRid(ai, 1);
 4801 	set_bit (FLAG_COMMIT, &ai->flags);
 4802 
 4803 	line = data->wbuffer;
 4804 	while( line[0] ) {
 4805 /*** Mode processing */
 4806 		if ( !strncmp( line, "Mode: ", 6 ) ) {
 4807 			line += 6;
 4808 			if (sniffing_mode(ai))
 4809 				set_bit (FLAG_RESET, &ai->flags);
 4810 			ai->config.rmode &= ~RXMODE_FULL_MASK;
 4811 			clear_bit (FLAG_802_11, &ai->flags);
 4812 			ai->config.opmode &= ~MODE_CFG_MASK;
 4813 			ai->config.scanMode = SCANMODE_ACTIVE;
 4814 			if ( line[0] == 'a' ) {
 4815 				ai->config.opmode |= MODE_STA_IBSS;
 4816 			} else {
 4817 				ai->config.opmode |= MODE_STA_ESS;
 4818 				if ( line[0] == 'r' ) {
 4819 					ai->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
 4820 					ai->config.scanMode = SCANMODE_PASSIVE;
 4821 					set_bit (FLAG_802_11, &ai->flags);
 4822 				} else if ( line[0] == 'y' ) {
 4823 					ai->config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER;
 4824 					ai->config.scanMode = SCANMODE_PASSIVE;
 4825 					set_bit (FLAG_802_11, &ai->flags);
 4826 				} else if ( line[0] == 'l' )
 4827 					ai->config.rmode |= RXMODE_LANMON;
 4828 			}
 4829 			set_bit (FLAG_COMMIT, &ai->flags);
 4830 		}
 4831 
 4832 /*** Radio status */
 4833 		else if (!strncmp(line,"Radio: ", 7)) {
 4834 			line += 7;
 4835 			if (!strncmp(line,"off",3)) {
 4836 				set_bit (FLAG_RADIO_OFF, &ai->flags);
 4837 			} else {
 4838 				clear_bit (FLAG_RADIO_OFF, &ai->flags);
 4839 			}
 4840 		}
 4841 /*** NodeName processing */
 4842 		else if ( !strncmp( line, "NodeName: ", 10 ) ) {
 4843 			int j;
 4844 
 4845 			line += 10;
 4846 			memset( ai->config.nodeName, 0, 16 );
 4847 /* Do the name, assume a space between the mode and node name */
 4848 			for( j = 0; j < 16 && line[j] != '\n'; j++ ) {
 4849 				ai->config.nodeName[j] = line[j];
 4850 			}
 4851 			set_bit (FLAG_COMMIT, &ai->flags);
 4852 		}
 4853 
 4854 /*** PowerMode processing */
 4855 		else if ( !strncmp( line, "PowerMode: ", 11 ) ) {
 4856 			line += 11;
 4857 			if ( !strncmp( line, "PSPCAM", 6 ) ) {
 4858 				ai->config.powerSaveMode = POWERSAVE_PSPCAM;
 4859 				set_bit (FLAG_COMMIT, &ai->flags);
 4860 			} else if ( !strncmp( line, "PSP", 3 ) ) {
 4861 				ai->config.powerSaveMode = POWERSAVE_PSP;
 4862 				set_bit (FLAG_COMMIT, &ai->flags);
 4863 			} else {
 4864 				ai->config.powerSaveMode = POWERSAVE_CAM;
 4865 				set_bit (FLAG_COMMIT, &ai->flags);
 4866 			}
 4867 		} else if ( !strncmp( line, "DataRates: ", 11 ) ) {
 4868 			int v, i = 0, k = 0; /* i is index into line,
 4869 						k is index to rates */
 4870 
 4871 			line += 11;
 4872 			while((v = get_dec_u16(line, &i, 3))!=-1) {
 4873 				ai->config.rates[k++] = (u8)v;
 4874 				line += i + 1;
 4875 				i = 0;
 4876 			}
 4877 			set_bit (FLAG_COMMIT, &ai->flags);
 4878 		} else if ( !strncmp( line, "Channel: ", 9 ) ) {
 4879 			int v, i = 0;
 4880 			line += 9;
 4881 			v = get_dec_u16(line, &i, i+3);
 4882 			if ( v != -1 ) {
 4883 				ai->config.channelSet = cpu_to_le16(v);
 4884 				set_bit (FLAG_COMMIT, &ai->flags);
 4885 			}
 4886 		} else if ( !strncmp( line, "XmitPower: ", 11 ) ) {
 4887 			int v, i = 0;
 4888 			line += 11;
 4889 			v = get_dec_u16(line, &i, i+3);
 4890 			if ( v != -1 ) {
 4891 				ai->config.txPower = cpu_to_le16(v);
 4892 				set_bit (FLAG_COMMIT, &ai->flags);
 4893 			}
 4894 		} else if ( !strncmp( line, "WEP: ", 5 ) ) {
 4895 			line += 5;
 4896 			switch( line[0] ) {
 4897 			case 's':
 4898 				set_auth_type(ai, AUTH_SHAREDKEY);
 4899 				break;
 4900 			case 'e':
 4901 				set_auth_type(ai, AUTH_ENCRYPT);
 4902 				break;
 4903 			default:
 4904 				set_auth_type(ai, AUTH_OPEN);
 4905 				break;
 4906 			}
 4907 			set_bit (FLAG_COMMIT, &ai->flags);
 4908 		} else if ( !strncmp( line, "LongRetryLimit: ", 16 ) ) {
 4909 			int v, i = 0;
 4910 
 4911 			line += 16;
 4912 			v = get_dec_u16(line, &i, 3);
 4913 			v = (v<0) ? 0 : ((v>255) ? 255 : v);
 4914 			ai->config.longRetryLimit = cpu_to_le16(v);
 4915 			set_bit (FLAG_COMMIT, &ai->flags);
 4916 		} else if ( !strncmp( line, "ShortRetryLimit: ", 17 ) ) {
 4917 			int v, i = 0;
 4918 
 4919 			line += 17;
 4920 			v = get_dec_u16(line, &i, 3);
 4921 			v = (v<0) ? 0 : ((v>255) ? 255 : v);
 4922 			ai->config.shortRetryLimit = cpu_to_le16(v);
 4923 			set_bit (FLAG_COMMIT, &ai->flags);
 4924 		} else if ( !strncmp( line, "RTSThreshold: ", 14 ) ) {
 4925 			int v, i = 0;
 4926 
 4927 			line += 14;
 4928 			v = get_dec_u16(line, &i, 4);
 4929 			v = (v<0) ? 0 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
 4930 			ai->config.rtsThres = cpu_to_le16(v);
 4931 			set_bit (FLAG_COMMIT, &ai->flags);
 4932 		} else if ( !strncmp( line, "TXMSDULifetime: ", 16 ) ) {
 4933 			int v, i = 0;
 4934 
 4935 			line += 16;
 4936 			v = get_dec_u16(line, &i, 5);
 4937 			v = (v<0) ? 0 : v;
 4938 			ai->config.txLifetime = cpu_to_le16(v);
 4939 			set_bit (FLAG_COMMIT, &ai->flags);
 4940 		} else if ( !strncmp( line, "RXMSDULifetime: ", 16 ) ) {
 4941 			int v, i = 0;
 4942 
 4943 			line += 16;
 4944 			v = get_dec_u16(line, &i, 5);
 4945 			v = (v<0) ? 0 : v;
 4946 			ai->config.rxLifetime = cpu_to_le16(v);
 4947 			set_bit (FLAG_COMMIT, &ai->flags);
 4948 		} else if ( !strncmp( line, "TXDiversity: ", 13 ) ) {
 4949 			ai->config.txDiversity =
 4950 				(line[13]=='l') ? 1 :
 4951 				((line[13]=='r')? 2: 3);
 4952 			set_bit (FLAG_COMMIT, &ai->flags);
 4953 		} else if ( !strncmp( line, "RXDiversity: ", 13 ) ) {
 4954 			ai->config.rxDiversity =
 4955 				(line[13]=='l') ? 1 :
 4956 				((line[13]=='r')? 2: 3);
 4957 			set_bit (FLAG_COMMIT, &ai->flags);
 4958 		} else if ( !strncmp( line, "FragThreshold: ", 15 ) ) {
 4959 			int v, i = 0;
 4960 
 4961 			line += 15;
 4962 			v = get_dec_u16(line, &i, 4);
 4963 			v = (v<256) ? 256 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
 4964 			v = v & 0xfffe; /* Make sure its even */
 4965 			ai->config.fragThresh = cpu_to_le16(v);
 4966 			set_bit (FLAG_COMMIT, &ai->flags);
 4967 		} else if (!strncmp(line, "Modulation: ", 12)) {
 4968 			line += 12;
 4969 			switch(*line) {
 4970 			case 'd':  ai->config.modulation=MOD_DEFAULT; set_bit(FLAG_COMMIT, &ai->flags); break;
 4971 			case 'c':  ai->config.modulation=MOD_CCK; set_bit(FLAG_COMMIT, &ai->flags); break;
 4972 			case 'm':  ai->config.modulation=MOD_MOK; set_bit(FLAG_COMMIT, &ai->flags); break;
 4973 			default: airo_print_warn(ai->dev->name, "Unknown modulation");
 4974 			}
 4975 		} else if (!strncmp(line, "Preamble: ", 10)) {
 4976 			line += 10;
 4977 			switch(*line) {
 4978 			case 'a': ai->config.preamble=PREAMBLE_AUTO; set_bit(FLAG_COMMIT, &ai->flags); break;
 4979 			case 'l': ai->config.preamble=PREAMBLE_LONG; set_bit(FLAG_COMMIT, &ai->flags); break;
 4980 			case 's': ai->config.preamble=PREAMBLE_SHORT; set_bit(FLAG_COMMIT, &ai->flags); break;
 4981 			default: airo_print_warn(ai->dev->name, "Unknown preamble");
 4982 			}
 4983 		} else {
 4984 			airo_print_warn(ai->dev->name, "Couldn't figure out %s", line);
 4985 		}
 4986 		while( line[0] && line[0] != '\n' ) line++;
 4987 		if ( line[0] ) line++;
 4988 	}
 4989 	airo_config_commit(dev, NULL, NULL, NULL);
 4990 }
 4991 
 4992 static const char *get_rmode(__le16 mode)
 4993 {
 4994         switch(mode & RXMODE_MASK) {
 4995         case RXMODE_RFMON:  return "rfmon";
 4996         case RXMODE_RFMON_ANYBSS:  return "yna (any) bss rfmon";
 4997         case RXMODE_LANMON:  return "lanmon";
 4998         }
 4999         return "ESS";
 5000 }
 5001 
 5002 static int proc_config_open(struct inode *inode, struct file *file)
 5003 {
 5004 	struct proc_data *data;
 5005 	struct net_device *dev = PDE_DATA(inode);
 5006 	struct airo_info *ai = dev->ml_priv;
 5007 	int i;
 5008 	__le16 mode;
 5009 
 5010 	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 5011 		return -ENOMEM;
 5012 	data = file->private_data;
 5013 	if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
 5014 		kfree (file->private_data);
 5015 		return -ENOMEM;
 5016 	}
 5017 	if ((data->wbuffer = kzalloc( 2048, GFP_KERNEL )) == NULL) {
 5018 		kfree (data->rbuffer);
 5019 		kfree (file->private_data);
 5020 		return -ENOMEM;
 5021 	}
 5022 	data->maxwritelen = 2048;
 5023 	data->on_close = proc_config_on_close;
 5024 
 5025 	readConfigRid(ai, 1);
 5026 
 5027 	mode = ai->config.opmode & MODE_CFG_MASK;
 5028 	i = sprintf( data->rbuffer,
 5029 		     "Mode: %s\n"
 5030 		     "Radio: %s\n"
 5031 		     "NodeName: %-16s\n"
 5032 		     "PowerMode: %s\n"
 5033 		     "DataRates: %d %d %d %d %d %d %d %d\n"
 5034 		     "Channel: %d\n"
 5035 		     "XmitPower: %d\n",
 5036 		     mode == MODE_STA_IBSS ? "adhoc" :
 5037 		     mode == MODE_STA_ESS ? get_rmode(ai->config.rmode):
 5038 		     mode == MODE_AP ? "AP" :
 5039 		     mode == MODE_AP_RPTR ? "AP RPTR" : "Error",
 5040 		     test_bit(FLAG_RADIO_OFF, &ai->flags) ? "off" : "on",
 5041 		     ai->config.nodeName,
 5042 		     ai->config.powerSaveMode == POWERSAVE_CAM ? "CAM" :
 5043 		     ai->config.powerSaveMode == POWERSAVE_PSP ? "PSP" :
 5044 		     ai->config.powerSaveMode == POWERSAVE_PSPCAM ? "PSPCAM" :
 5045 		     "Error",
 5046 		     (int)ai->config.rates[0],
 5047 		     (int)ai->config.rates[1],
 5048 		     (int)ai->config.rates[2],
 5049 		     (int)ai->config.rates[3],
 5050 		     (int)ai->config.rates[4],
 5051 		     (int)ai->config.rates[5],
 5052 		     (int)ai->config.rates[6],
 5053 		     (int)ai->config.rates[7],
 5054 		     le16_to_cpu(ai->config.channelSet),
 5055 		     le16_to_cpu(ai->config.txPower)
 5056 		);
 5057 	sprintf( data->rbuffer + i,
 5058 		 "LongRetryLimit: %d\n"
 5059 		 "ShortRetryLimit: %d\n"
 5060 		 "RTSThreshold: %d\n"
 5061 		 "TXMSDULifetime: %d\n"
 5062 		 "RXMSDULifetime: %d\n"
 5063 		 "TXDiversity: %s\n"
 5064 		 "RXDiversity: %s\n"
 5065 		 "FragThreshold: %d\n"
 5066 		 "WEP: %s\n"
 5067 		 "Modulation: %s\n"
 5068 		 "Preamble: %s\n",
 5069 		 le16_to_cpu(ai->config.longRetryLimit),
 5070 		 le16_to_cpu(ai->config.shortRetryLimit),
 5071 		 le16_to_cpu(ai->config.rtsThres),
 5072 		 le16_to_cpu(ai->config.txLifetime),
 5073 		 le16_to_cpu(ai->config.rxLifetime),
 5074 		 ai->config.txDiversity == 1 ? "left" :
 5075 		 ai->config.txDiversity == 2 ? "right" : "both",
 5076 		 ai->config.rxDiversity == 1 ? "left" :
 5077 		 ai->config.rxDiversity == 2 ? "right" : "both",
 5078 		 le16_to_cpu(ai->config.fragThresh),
 5079 		 ai->config.authType == AUTH_ENCRYPT ? "encrypt" :
 5080 		 ai->config.authType == AUTH_SHAREDKEY ? "shared" : "open",
 5081 		 ai->config.modulation == MOD_DEFAULT ? "default" :
 5082 		 ai->config.modulation == MOD_CCK ? "cck" :
 5083 		 ai->config.modulation == MOD_MOK ? "mok" : "error",
 5084 		 ai->config.preamble == PREAMBLE_AUTO ? "auto" :
 5085 		 ai->config.preamble == PREAMBLE_LONG ? "long" :
 5086 		 ai->config.preamble == PREAMBLE_SHORT ? "short" : "error"
 5087 		);
 5088 	data->readlen = strlen( data->rbuffer );
 5089 	return 0;
 5090 }
 5091 
 5092 static void proc_SSID_on_close(struct inode *inode, struct file *file)
 5093 {
 5094 	struct proc_data *data = file->private_data;
 5095 	struct net_device *dev = PDE_DATA(inode);
 5096 	struct airo_info *ai = dev->ml_priv;
 5097 	SsidRid SSID_rid;
 5098 	int i;
 5099 	char *p = data->wbuffer;
 5100 	char *end = p + data->writelen;
 5101 
 5102 	if (!data->writelen)
 5103 		return;
 5104 
 5105 	*end = '\n'; /* sentinel; we have space for it */
 5106 
 5107 	memset(&SSID_rid, 0, sizeof(SSID_rid));
 5108 
 5109 	for (i = 0; i < 3 && p < end; i++) {
 5110 		int j = 0;
 5111 		/* copy up to 32 characters from this line */
 5112 		while (*p != '\n' && j < 32)
 5113 			SSID_rid.ssids[i].ssid[j++] = *p++;
 5114 		if (j == 0)
 5115 			break;
 5116 		SSID_rid.ssids[i].len = cpu_to_le16(j);
 5117 		/* skip to the beginning of the next line */
 5118 		while (*p++ != '\n')
 5119 			;
 5120 	}
 5121 	if (i)
 5122 		SSID_rid.len = cpu_to_le16(sizeof(SSID_rid));
 5123 	disable_MAC(ai, 1);
 5124 	writeSsidRid(ai, &SSID_rid, 1);
 5125 	enable_MAC(ai, 1);
 5126 }
 5127 
 5128 static void proc_APList_on_close( struct inode *inode, struct file *file ) {
 5129 	struct proc_data *data = file->private_data;
 5130 	struct net_device *dev = PDE_DATA(inode);
 5131 	struct airo_info *ai = dev->ml_priv;
 5132 	APListRid *APList_rid = &ai->APList;
 5133 	int i;
 5134 
 5135 	if ( !data->writelen ) return;
 5136 
 5137 	memset(APList_rid, 0, sizeof(*APList_rid));
 5138 	APList_rid->len = cpu_to_le16(sizeof(*APList_rid));
 5139 
 5140 	for (i = 0; i < 4 && data->writelen >= (i + 1) * 6 * 3; i++)
 5141 		mac_pton(data->wbuffer + i * 6 * 3, APList_rid->ap[i]);
 5142 
 5143 	disable_MAC(ai, 1);
 5144 	writeAPListRid(ai, APList_rid, 1);
 5145 	enable_MAC(ai, 1);
 5146 }
 5147 
 5148 /* This function wraps PC4500_writerid with a MAC disable */
 5149 static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data,
 5150 			int len, int dummy ) {
 5151 	int rc;
 5152 
 5153 	disable_MAC(ai, 1);
 5154 	rc = PC4500_writerid(ai, rid, rid_data, len, 1);
 5155 	enable_MAC(ai, 1);
 5156 	return rc;
 5157 }
 5158 
 5159 /* Returns the WEP key at the specified index, or -1 if that key does
 5160  * not exist.  The buffer is assumed to be at least 16 bytes in length.
 5161  */
 5162 static int get_wep_key(struct airo_info *ai, u16 index, char *buf, u16 buflen)
 5163 {
 5164 	WepKeyRid wkr;
 5165 	int rc;
 5166 	__le16 lastindex;
 5167 
 5168 	rc = readWepKeyRid(ai, &wkr, 1, 1);
 5169 	if (rc != SUCCESS)
 5170 		return -1;
 5171 	do {
 5172 		lastindex = wkr.kindex;
 5173 		if (le16_to_cpu(wkr.kindex) == index) {
 5174 			int klen = min_t(int, buflen, le16_to_cpu(wkr.klen));
 5175 			memcpy(buf, wkr.key, klen);
 5176 			return klen;
 5177 		}
 5178 		rc = readWepKeyRid(ai, &wkr, 0, 1);
 5179 		if (rc != SUCCESS)
 5180 			return -1;
 5181 	} while (lastindex != wkr.kindex);
 5182 	return -1;
 5183 }
 5184 
 5185 static int get_wep_tx_idx(struct airo_info *ai)
 5186 {
 5187 	WepKeyRid wkr;
 5188 	int rc;
 5189 	__le16 lastindex;
 5190 
 5191 	rc = readWepKeyRid(ai, &wkr, 1, 1);
 5192 	if (rc != SUCCESS)
 5193 		return -1;
 5194 	do {
 5195 		lastindex = wkr.kindex;
 5196 		if (wkr.kindex == cpu_to_le16(0xffff))
 5197 			return wkr.mac[0];
 5198 		rc = readWepKeyRid(ai, &wkr, 0, 1);
 5199 		if (rc != SUCCESS)
 5200 			return -1;
 5201 	} while (lastindex != wkr.kindex);
 5202 	return -1;
 5203 }
 5204 
 5205 static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
 5206 		       u16 keylen, int perm, int lock)
 5207 {
 5208 	static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
 5209 	WepKeyRid wkr;
 5210 	int rc;
 5211 
 5212 	if (WARN_ON(keylen == 0))
 5213 		return -1;
 5214 
 5215 	memset(&wkr, 0, sizeof(wkr));
 5216 	wkr.len = cpu_to_le16(sizeof(wkr));
 5217 	wkr.kindex = cpu_to_le16(index);
 5218 	wkr.klen = cpu_to_le16(keylen);
 5219 	memcpy(wkr.key, key, keylen);
 5220 	memcpy(wkr.mac, macaddr, ETH_ALEN);
 5221 
 5222 	if (perm) disable_MAC(ai, lock);
 5223 	rc = writeWepKeyRid(ai, &wkr, perm, lock);
 5224 	if (perm) enable_MAC(ai, lock);
 5225 	return rc;
 5226 }
 5227 
 5228 static int set_wep_tx_idx(struct airo_info *ai, u16 index, int perm, int lock)
 5229 {
 5230 	WepKeyRid wkr;
 5231 	int rc;
 5232 
 5233 	memset(&wkr, 0, sizeof(wkr));
 5234 	wkr.len = cpu_to_le16(sizeof(wkr));
 5235 	wkr.kindex = cpu_to_le16(0xffff);
 5236 	wkr.mac[0] = (char)index;
 5237 
 5238 	if (perm) {
 5239 		ai->defindex = (char)index;
 5240 		disable_MAC(ai, lock);
 5241 	}
 5242 
 5243 	rc = writeWepKeyRid(ai, &wkr, perm, lock);
 5244 
 5245 	if (perm)
 5246 		enable_MAC(ai, lock);
 5247 	return rc;
 5248 }
 5249 
 5250 static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
 5251 	struct proc_data *data;
 5252 	struct net_device *dev = PDE_DATA(inode);
 5253 	struct airo_info *ai = dev->ml_priv;
 5254 	int i, rc;
 5255 	char key[16];
 5256 	u16 index = 0;
 5257 	int j = 0;
 5258 
 5259 	memset(key, 0, sizeof(key));
 5260 
 5261 	data = file->private_data;
 5262 	if ( !data->writelen ) return;
 5263 
 5264 	if (data->wbuffer[0] >= '0' && data->wbuffer[0] <= '3' &&
 5265 	    (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
 5266 		index = data->wbuffer[0] - '0';
 5267 		if (data->wbuffer[1] == '\n') {
 5268 			rc = set_wep_tx_idx(ai, index, 1, 1);
 5269 			if (rc < 0) {
 5270 				airo_print_err(ai->dev->name, "failed to set "
 5271 				               "WEP transmit index to %d: %d.",
 5272 				               index, rc);
 5273 			}
 5274 			return;
 5275 		}
 5276 		j = 2;
 5277 	} else {
 5278 		airo_print_err(ai->dev->name, "WepKey passed invalid key index");
 5279 		return;
 5280 	}
 5281 
 5282 	for( i = 0; i < 16*3 && data->wbuffer[i+j]; i++ ) {
 5283 		switch(i%3) {
 5284 		case 0:
 5285 			key[i/3] = hex_to_bin(data->wbuffer[i+j])<<4;
 5286 			break;
 5287 		case 1:
 5288 			key[i/3] |= hex_to_bin(data->wbuffer[i+j]);
 5289 			break;
 5290 		}
 5291 	}
 5292 
 5293 	rc = set_wep_key(ai, index, key, i/3, 1, 1);
 5294 	if (rc < 0) {
 5295 		airo_print_err(ai->dev->name, "failed to set WEP key at index "
 5296 		               "%d: %d.", index, rc);
 5297 	}
 5298 }
 5299 
 5300 static int proc_wepkey_open( struct inode *inode, struct file *file )
 5301 {
 5302 	struct proc_data *data;
 5303 	struct net_device *dev = PDE_DATA(inode);
 5304 	struct airo_info *ai = dev->ml_priv;
 5305 	char *ptr;
 5306 	WepKeyRid wkr;
 5307 	__le16 lastindex;
 5308 	int j=0;
 5309 	int rc;
 5310 
 5311 	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 5312 		return -ENOMEM;
 5313 	memset(&wkr, 0, sizeof(wkr));
 5314 	data = file->private_data;
 5315 	if ((data->rbuffer = kzalloc( 180, GFP_KERNEL )) == NULL) {
 5316 		kfree (file->private_data);
 5317 		return -ENOMEM;
 5318 	}
 5319 	data->writelen = 0;
 5320 	data->maxwritelen = 80;
 5321 	if ((data->wbuffer = kzalloc( 80, GFP_KERNEL )) == NULL) {
 5322 		kfree (data->rbuffer);
 5323 		kfree (file->private_data);
 5324 		return -ENOMEM;
 5325 	}
 5326 	data->on_close = proc_wepkey_on_close;
 5327 
 5328 	ptr = data->rbuffer;
 5329 	strcpy(ptr, "No wep keys\n");
 5330 	rc = readWepKeyRid(ai, &wkr, 1, 1);
 5331 	if (rc == SUCCESS) do {
 5332 		lastindex = wkr.kindex;
 5333 		if (wkr.kindex == cpu_to_le16(0xffff)) {
 5334 			j += sprintf(ptr+j, "Tx key = %d\n",
 5335 				     (int)wkr.mac[0]);
 5336 		} else {
 5337 			j += sprintf(ptr+j, "Key %d set with length = %d\n",
 5338 				     le16_to_cpu(wkr.kindex),
 5339 				     le16_to_cpu(wkr.klen));
 5340 		}
 5341 		readWepKeyRid(ai, &wkr, 0, 1);
 5342 	} while((lastindex != wkr.kindex) && (j < 180-30));
 5343 
 5344 	data->readlen = strlen( data->rbuffer );
 5345 	return 0;
 5346 }
 5347 
 5348 static int proc_SSID_open(struct inode *inode, struct file *file)
 5349 {
 5350 	struct proc_data *data;
 5351 	struct net_device *dev = PDE_DATA(inode);
 5352 	struct airo_info *ai = dev->ml_priv;
 5353 	int i;
 5354 	char *ptr;
 5355 	SsidRid SSID_rid;
 5356 
 5357 	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 5358 		return -ENOMEM;
 5359 	data = file->private_data;
 5360 	if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
 5361 		kfree (file->private_data);
 5362 		return -ENOMEM;
 5363 	}
 5364 	data->writelen = 0;
 5365 	data->maxwritelen = 33*3;
 5366 	/* allocate maxwritelen + 1; we'll want a sentinel */
 5367 	if ((data->wbuffer = kzalloc(33*3 + 1, GFP_KERNEL)) == NULL) {
 5368 		kfree (data->rbuffer);
 5369 		kfree (file->private_data);
 5370 		return -ENOMEM;
 5371 	}
 5372 	data->on_close = proc_SSID_on_close;
 5373 
 5374 	readSsidRid(ai, &SSID_rid);
 5375 	ptr = data->rbuffer;
 5376 	for (i = 0; i < 3; i++) {
 5377 		int j;
 5378 		size_t len = le16_to_cpu(SSID_rid.ssids[i].len);
 5379 		if (!len)
 5380 			break;
 5381 		if (len > 32)
 5382 			len = 32;
 5383 		for (j = 0; j < len && SSID_rid.ssids[i].ssid[j]; j++)
 5384 			*ptr++ = SSID_rid.ssids[i].ssid[j];
 5385 		*ptr++ = '\n';
 5386 	}
 5387 	*ptr = '\0';
 5388 	data->readlen = strlen( data->rbuffer );
 5389 	return 0;
 5390 }
 5391 
 5392 static int proc_APList_open( struct inode *inode, struct file *file ) {
 5393 	struct proc_data *data;
 5394 	struct net_device *dev = PDE_DATA(inode);
 5395 	struct airo_info *ai = dev->ml_priv;
 5396 	int i;
 5397 	char *ptr;
 5398 	APListRid *APList_rid = &ai->APList;
 5399 
 5400 	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 5401 		return -ENOMEM;
 5402 	data = file->private_data;
 5403 	if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
 5404 		kfree (file->private_data);
 5405 		return -ENOMEM;
 5406 	}
 5407 	data->writelen = 0;
 5408 	data->maxwritelen = 4*6*3;
 5409 	if ((data->wbuffer = kzalloc( data->maxwritelen, GFP_KERNEL )) == NULL) {
 5410 		kfree (data->rbuffer);
 5411 		kfree (file->private_data);
 5412 		return -ENOMEM;
 5413 	}
 5414 	data->on_close = proc_APList_on_close;
 5415 
 5416 	ptr = data->rbuffer;
 5417 	for( i = 0; i < 4; i++ ) {
 5418 // We end when we find a zero MAC
 5419 		if ( !*(int*)APList_rid->ap[i] &&
 5420 		     !*(int*)&APList_rid->ap[i][2]) break;
 5421 		ptr += sprintf(ptr, "%pM\n", APList_rid->ap[i]);
 5422 	}
 5423 	if (i==0) ptr += sprintf(ptr, "Not using specific APs\n");
 5424 
 5425 	*ptr = '\0';
 5426 	data->readlen = strlen( data->rbuffer );
 5427 	return 0;
 5428 }
 5429 
 5430 static int proc_BSSList_open( struct inode *inode, struct file *file ) {
 5431 	struct proc_data *data;
 5432 	struct net_device *dev = PDE_DATA(inode);
 5433 	struct airo_info *ai = dev->ml_priv;
 5434 	char *ptr;
 5435 	BSSListRid BSSList_rid;
 5436 	int rc;
 5437 	/* If doLoseSync is not 1, we won't do a Lose Sync */
 5438 	int doLoseSync = -1;
 5439 
 5440 	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 5441 		return -ENOMEM;
 5442 	data = file->private_data;
 5443 	if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) {
 5444 		kfree (file->private_data);
 5445 		return -ENOMEM;
 5446 	}
 5447 	data->writelen = 0;
 5448 	data->maxwritelen = 0;
 5449 	data->wbuffer = NULL;
 5450 	data->on_close = NULL;
 5451 
 5452 	if (file->f_mode & FMODE_WRITE) {
 5453 		if (!(file->f_mode & FMODE_READ)) {
 5454 			Cmd cmd;
 5455 			Resp rsp;
 5456 
 5457 			if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
 5458 			memset(&cmd, 0, sizeof(cmd));
 5459 			cmd.cmd=CMD_LISTBSS;
 5460 			if (down_interruptible(&ai->sem))
 5461 				return -ERESTARTSYS;
 5462 			issuecommand(ai, &cmd, &rsp);
 5463 			up(&ai->sem);
 5464 			data->readlen = 0;
 5465 			return 0;
 5466 		}
 5467 		doLoseSync = 1;
 5468 	}
 5469 	ptr = data->rbuffer;
 5470 	/* There is a race condition here if there are concurrent opens.
 5471            Since it is a rare condition, we'll just live with it, otherwise
 5472            we have to add a spin lock... */
 5473 	rc = readBSSListRid(ai, doLoseSync, &BSSList_rid);
 5474 	while(rc == 0 && BSSList_rid.index != cpu_to_le16(0xffff)) {
 5475 		ptr += sprintf(ptr, "%pM %*s rssi = %d",
 5476 			       BSSList_rid.bssid,
 5477 				(int)BSSList_rid.ssidLen,
 5478 				BSSList_rid.ssid,
 5479 				le16_to_cpu(BSSList_rid.dBm));
 5480 		ptr += sprintf(ptr, " channel = %d %s %s %s %s\n",
 5481 				le16_to_cpu(BSSList_rid.dsChannel),
 5482 				BSSList_rid.cap & CAP_ESS ? "ESS" : "",
 5483 				BSSList_rid.cap & CAP_IBSS ? "adhoc" : "",
 5484 				BSSList_rid.cap & CAP_PRIVACY ? "wep" : "",
 5485 				BSSList_rid.cap & CAP_SHORTHDR ? "shorthdr" : "");
 5486 		rc = readBSSListRid(ai, 0, &BSSList_rid);
 5487 	}
 5488 	*ptr = '\0';
 5489 	data->readlen = strlen( data->rbuffer );
 5490 	return 0;
 5491 }
 5492 
 5493 static int proc_close( struct inode *inode, struct file *file )
 5494 {
 5495 	struct proc_data *data = file->private_data;
 5496 
 5497 	if (data->on_close != NULL)
 5498 		data->on_close(inode, file);
 5499 	kfree(data->rbuffer);
 5500 	kfree(data->wbuffer);
 5501 	kfree(data);
 5502 	return 0;
 5503 }
 5504 
 5505 /* Since the card doesn't automatically switch to the right WEP mode,
 5506    we will make it do it.  If the card isn't associated, every secs we
 5507    will switch WEP modes to see if that will help.  If the card is
 5508    associated we will check every minute to see if anything has
 5509    changed. */
 5510 static void timer_func( struct net_device *dev ) {
 5511 	struct airo_info *apriv = dev->ml_priv;
 5512 
 5513 /* We don't have a link so try changing the authtype */
 5514 	readConfigRid(apriv, 0);
 5515 	disable_MAC(apriv, 0);
 5516 	switch(apriv->config.authType) {
 5517 		case AUTH_ENCRYPT:
 5518 /* So drop to OPEN */
 5519 			apriv->config.authType = AUTH_OPEN;
 5520 			break;
 5521 		case AUTH_SHAREDKEY:
 5522 			if (apriv->keyindex < auto_wep) {
 5523 				set_wep_tx_idx(apriv, apriv->keyindex, 0, 0);
 5524 				apriv->config.authType = AUTH_SHAREDKEY;
 5525 				apriv->keyindex++;
 5526 			} else {
 5527 			        /* Drop to ENCRYPT */
 5528 				apriv->keyindex = 0;
 5529 				set_wep_tx_idx(apriv, apriv->defindex, 0, 0);
 5530 				apriv->config.authType = AUTH_ENCRYPT;
 5531 			}
 5532 			break;
 5533 		default:  /* We'll escalate to SHAREDKEY */
 5534 			apriv->config.authType = AUTH_SHAREDKEY;
 5535 	}
 5536 	set_bit (FLAG_COMMIT, &apriv->flags);
 5537 	writeConfigRid(apriv, 0);
 5538 	enable_MAC(apriv, 0);
 5539 	up(&apriv->sem);
 5540 
 5541 /* Schedule check to see if the change worked */
 5542 	clear_bit(JOB_AUTOWEP, &apriv->jobs);
 5543 	apriv->expires = RUN_AT(HZ*3);
 5544 }
 5545 
 5546 #ifdef CONFIG_PCI
 5547 static int airo_pci_probe(struct pci_dev *pdev,
 5548 				    const struct pci_device_id *pent)
 5549 {
 5550 	struct net_device *dev;
 5551 
 5552 	if (pci_enable_device(pdev))
 5553 		return -ENODEV;
 5554 	pci_set_master(pdev);
 5555 
 5556 	if (pdev->device == 0x5000 || pdev->device == 0xa504)
 5557 			dev = _init_airo_card(pdev->irq, pdev->resource[0].start, 0, pdev, &pdev->dev);
 5558 	else
 5559 			dev = _init_airo_card(pdev->irq, pdev->resource[2].start, 0, pdev, &pdev->dev);
 5560 	if (!dev) {
 5561 		pci_disable_device(pdev);
 5562 		return -ENODEV;
 5563 	}
 5564 
 5565 	pci_set_drvdata(pdev, dev);
 5566 	return 0;
 5567 }
 5568 
 5569 static void airo_pci_remove(struct pci_dev *pdev)
 5570 {
 5571 	struct net_device *dev = pci_get_drvdata(pdev);
 5572 
 5573 	airo_print_info(dev->name, "Unregistering...");
 5574 	stop_airo_card(dev, 1);
 5575 	pci_disable_device(pdev);
 5576 }
 5577 
 5578 static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 5579 {
 5580 	struct net_device *dev = pci_get_drvdata(pdev);
 5581 	struct airo_info *ai = dev->ml_priv;
 5582 	Cmd cmd;
 5583 	Resp rsp;
 5584 
 5585 	if (!ai->SSID)
 5586 		ai->SSID = kmalloc(sizeof(SsidRid), GFP_KERNEL);
 5587 	if (!ai->SSID)
 5588 		return -ENOMEM;
 5589 	readSsidRid(ai, ai->SSID);
 5590 	memset(&cmd, 0, sizeof(cmd));
 5591 	/* the lock will be released at the end of the resume callback */
 5592 	if (down_interruptible(&ai->sem))
 5593 		return -EAGAIN;
 5594 	disable_MAC(ai, 0);
 5595 	netif_device_detach(dev);
 5596 	ai->power = state;
 5597 	cmd.cmd = HOSTSLEEP;
 5598 	issuecommand(ai, &cmd, &rsp);
 5599 
 5600 	pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
 5601 	pci_save_state(pdev);
 5602 	pci_set_power_state(pdev, pci_choose_state(pdev, state));
 5603 	return 0;
 5604 }
 5605 
 5606 static int airo_pci_resume(struct pci_dev *pdev)
 5607 {
 5608 	struct net_device *dev = pci_get_drvdata(pdev);
 5609 	struct airo_info *ai = dev->ml_priv;
 5610 	pci_power_t prev_state = pdev->current_state;
 5611 
 5612 	pci_set_power_state(pdev, PCI_D0);
 5613 	pci_restore_state(pdev);
 5614 	pci_enable_wake(pdev, PCI_D0, 0);
 5615 
 5616 	if (prev_state != PCI_D1) {
 5617 		reset_card(dev, 0);
 5618 		mpi_init_descriptors(ai);
 5619 		setup_card(ai, dev->dev_addr, 0);
 5620 		clear_bit(FLAG_RADIO_OFF, &ai->flags);
 5621 		clear_bit(FLAG_PENDING_XMIT, &ai->flags);
 5622 	} else {
 5623 		OUT4500(ai, EVACK, EV_AWAKEN);
 5624 		OUT4500(ai, EVACK, EV_AWAKEN);
 5625 		msleep(100);
 5626 	}
 5627 
 5628 	set_bit(FLAG_COMMIT, &ai->flags);
 5629 	disable_MAC(ai, 0);
 5630         msleep(200);
 5631 	if (ai->SSID) {
 5632 		writeSsidRid(ai, ai->SSID, 0);
 5633 		kfree(ai->SSID);
 5634 		ai->SSID = NULL;
 5635 	}
 5636 	writeAPListRid(ai, &ai->APList, 0);
 5637 	writeConfigRid(ai, 0);
 5638 	enable_MAC(ai, 0);
 5639 	ai->power = PMSG_ON;
 5640 	netif_device_attach(dev);
 5641 	netif_wake_queue(dev);
 5642 	enable_interrupts(ai);
 5643 	up(&ai->sem);
 5644 	return 0;
 5645 }
 5646 #endif
 5647 
 5648 static int __init airo_init_module( void )
 5649 {
 5650 	int i;
 5651 
 5652 	proc_kuid = make_kuid(&init_user_ns, proc_uid);
 5653 	proc_kgid = make_kgid(&init_user_ns, proc_gid);
 5654 	if (!uid_valid(proc_kuid) || !gid_valid(proc_kgid))
 5655 		return -EINVAL;
 5656 
 5657 	airo_entry = proc_mkdir_mode("driver/aironet", airo_perm, NULL);
 5658 
 5659 	if (airo_entry)
 5660 		proc_set_user(airo_entry, proc_kuid, proc_kgid);
 5661 
 5662 	for (i = 0; i < 4 && io[i] && irq[i]; i++) {
 5663 		airo_print_info("", "Trying to configure ISA adapter at irq=%d "
 5664 			"io=0x%x", irq[i], io[i] );
 5665 		if (init_airo_card( irq[i], io[i], 0, NULL ))
 5666 			/* do nothing */ ;
 5667 	}
 5668 
 5669 #ifdef CONFIG_PCI
 5670 	airo_print_info("", "Probing for PCI adapters");
 5671 	i = pci_register_driver(&airo_driver);
 5672 	airo_print_info("", "Finished probing for PCI adapters");
 5673 
 5674 	if (i) {
 5675 		remove_proc_entry("driver/aironet", NULL);
 5676 		return i;
 5677 	}
 5678 #endif
 5679 
 5680 	/* Always exit with success, as we are a library module
 5681 	 * as well as a driver module
 5682 	 */
 5683 	return 0;
 5684 }
 5685 
 5686 static void __exit airo_cleanup_module( void )
 5687 {
 5688 	struct airo_info *ai;
 5689 	while(!list_empty(&airo_devices)) {
 5690 		ai = list_entry(airo_devices.next, struct airo_info, dev_list);
 5691 		airo_print_info(ai->dev->name, "Unregistering...");
 5692 		stop_airo_card(ai->dev, 1);
 5693 	}
 5694 #ifdef CONFIG_PCI
 5695 	pci_unregister_driver(&airo_driver);
 5696 #endif
 5697 	remove_proc_entry("driver/aironet", NULL);
 5698 }
 5699 
 5700 /*
 5701  * Initial Wireless Extension code for Aironet driver by :
 5702  *	Jean Tourrilhes <jt@hpl.hp.com> - HPL - 17 November 00
 5703  * Conversion to new driver API by :
 5704  *	Jean Tourrilhes <jt@hpl.hp.com> - HPL - 26 March 02
 5705  * Javier also did a good amount of work here, adding some new extensions
 5706  * and fixing my code. Let's just say that without him this code just
 5707  * would not work at all... - Jean II
 5708  */
 5709 
 5710 static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi)
 5711 {
 5712 	if (!rssi_rid)
 5713 		return 0;
 5714 
 5715 	return (0x100 - rssi_rid[rssi].rssidBm);
 5716 }
 5717 
 5718 static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm)
 5719 {
 5720 	int i;
 5721 
 5722 	if (!rssi_rid)
 5723 		return 0;
 5724 
 5725 	for (i = 0; i < 256; i++)
 5726 		if (rssi_rid[i].rssidBm == dbm)
 5727 			return rssi_rid[i].rssipct;
 5728 
 5729 	return 0;
 5730 }
 5731 
 5732 
 5733 static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid)
 5734 {
 5735 	int quality = 0;
 5736 	u16 sq;
 5737 
 5738 	if ((status_rid->mode & cpu_to_le16(0x3f)) != cpu_to_le16(0x3f))
 5739 		return 0;
 5740 
 5741 	if (!(cap_rid->hardCap & cpu_to_le16(8)))
 5742 		return 0;
 5743 
 5744 	sq = le16_to_cpu(status_rid->signalQuality);
 5745 	if (memcmp(cap_rid->prodName, "350", 3))
 5746 		if (sq > 0x20)
 5747 			quality = 0;
 5748 		else
 5749 			quality = 0x20 - sq;
 5750 	else
 5751 		if (sq > 0xb0)
 5752 			quality = 0;
 5753 		else if (sq < 0x10)
 5754 			quality = 0xa0;
 5755 		else
 5756 			quality = 0xb0 - sq;
 5757 	return quality;
 5758 }
 5759 
 5760 #define airo_get_max_quality(cap_rid) (memcmp((cap_rid)->prodName, "350", 3) ? 0x20 : 0xa0)
 5761 #define airo_get_avg_quality(cap_rid) (memcmp((cap_rid)->prodName, "350", 3) ? 0x10 : 0x50);
 5762 
 5763 /*------------------------------------------------------------------*/
 5764 /*
 5765  * Wireless Handler : get protocol name
 5766  */
 5767 static int airo_get_name(struct net_device *dev,
 5768 			 struct iw_request_info *info,
 5769 			 char *cwrq,
 5770 			 char *extra)
 5771 {
 5772 	strcpy(cwrq, "IEEE 802.11-DS");
 5773 	return 0;
 5774 }
 5775 
 5776 /*------------------------------------------------------------------*/
 5777 /*
 5778  * Wireless Handler : set frequency
 5779  */
 5780 static int airo_set_freq(struct net_device *dev,
 5781 			 struct iw_request_info *info,
 5782 			 struct iw_freq *fwrq,
 5783 			 char *extra)
 5784 {
 5785 	struct airo_info *local = dev->ml_priv;
 5786 	int rc = -EINPROGRESS;		/* Call commit handler */
 5787 
 5788 	/* If setting by frequency, convert to a channel */
 5789 	if(fwrq->e == 1) {
 5790 		int f = fwrq->m / 100000;
 5791 
 5792 		/* Hack to fall through... */
 5793 		fwrq->e = 0;
 5794 		fwrq->m = ieee80211_frequency_to_channel(f);
 5795 	}
 5796 	/* Setting by channel number */
 5797 	if((fwrq->m > 1000) || (fwrq->e > 0))
 5798 		rc = -EOPNOTSUPP;
 5799 	else {
 5800 		int channel = fwrq->m;
 5801 		/* We should do a better check than that,
 5802 		 * based on the card capability !!! */
 5803 		if((channel < 1) || (channel > 14)) {
 5804 			airo_print_dbg(dev->name, "New channel value of %d is invalid!",
 5805 				fwrq->m);
 5806 			rc = -EINVAL;
 5807 		} else {
 5808 			readConfigRid(local, 1);
 5809 			/* Yes ! We can set it !!! */
 5810 			local->config.channelSet = cpu_to_le16(channel);
 5811 			set_bit (FLAG_COMMIT, &local->flags);
 5812 		}
 5813 	}
 5814 	return rc;
 5815 }
 5816 
 5817 /*------------------------------------------------------------------*/
 5818 /*
 5819  * Wireless Handler : get frequency
 5820  */
 5821 static int airo_get_freq(struct net_device *dev,
 5822 			 struct iw_request_info *info,
 5823 			 struct iw_freq *fwrq,
 5824 			 char *extra)
 5825 {
 5826 	struct airo_info *local = dev->ml_priv;
 5827 	StatusRid status_rid;		/* Card status info */
 5828 	int ch;
 5829 
 5830 	readConfigRid(local, 1);
 5831 	if ((local->config.opmode & MODE_CFG_MASK) == MODE_STA_ESS)
 5832 		status_rid.channel = local->config.channelSet;
 5833 	else
 5834 		readStatusRid(local, &status_rid, 1);
 5835 
 5836 	ch = le16_to_cpu(status_rid.channel);
 5837 	if((ch > 0) && (ch < 15)) {
 5838 		fwrq->m = 100000 *
 5839 			ieee80211_channel_to_frequency(ch, IEEE80211_BAND_2GHZ);
 5840 		fwrq->e = 1;
 5841 	} else {
 5842 		fwrq->m = ch;
 5843 		fwrq->e = 0;
 5844 	}
 5845 
 5846 	return 0;
 5847 }
 5848 
 5849 /*------------------------------------------------------------------*/
 5850 /*
 5851  * Wireless Handler : set ESSID
 5852  */
 5853 static int airo_set_essid(struct net_device *dev,
 5854 			  struct iw_request_info *info,
 5855 			  struct iw_point *dwrq,
 5856 			  char *extra)
 5857 {
 5858 	struct airo_info *local = dev->ml_priv;
 5859 	SsidRid SSID_rid;		/* SSIDs */
 5860 
 5861 	/* Reload the list of current SSID */
 5862 	readSsidRid(local, &SSID_rid);
 5863 
 5864 	/* Check if we asked for `any' */
 5865 	if (dwrq->flags == 0) {
 5866 		/* Just send an empty SSID list */
 5867 		memset(&SSID_rid, 0, sizeof(SSID_rid));
 5868 	} else {
 5869 		unsigned index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
 5870 
 5871 		/* Check the size of the string */
 5872 		if (dwrq->length > IW_ESSID_MAX_SIZE)
 5873 			return -E2BIG ;
 5874 
 5875 		/* Check if index is valid */
 5876 		if (index >= ARRAY_SIZE(SSID_rid.ssids))
 5877 			return -EINVAL;
 5878 
 5879 		/* Set the SSID */
 5880 		memset(SSID_rid.ssids[index].ssid, 0,
 5881 		       sizeof(SSID_rid.ssids[index].ssid));
 5882 		memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length);
 5883 		SSID_rid.ssids[index].len = cpu_to_le16(dwrq->length);
 5884 	}
 5885 	SSID_rid.len = cpu_to_le16(sizeof(SSID_rid));
 5886 	/* Write it to the card */
 5887 	disable_MAC(local, 1);
 5888 	writeSsidRid(local, &SSID_rid, 1);
 5889 	enable_MAC(local, 1);
 5890 
 5891 	return 0;
 5892 }
 5893 
 5894 /*------------------------------------------------------------------*/
 5895 /*
 5896  * Wireless Handler : get ESSID
 5897  */
 5898 static int airo_get_essid(struct net_device *dev,
 5899 			  struct iw_request_info *info,
 5900 			  struct iw_point *dwrq,
 5901 			  char *extra)
 5902 {
 5903 	struct airo_info *local = dev->ml_priv;
 5904 	StatusRid status_rid;		/* Card status info */
 5905 
 5906 	readStatusRid(local, &status_rid, 1);
 5907 
 5908 	/* Note : if dwrq->flags != 0, we should
 5909 	 * get the relevant SSID from the SSID list... */
 5910 
 5911 	/* Get the current SSID */
 5912 	memcpy(extra, status_rid.SSID, le16_to_cpu(status_rid.SSIDlen));
 5913 	/* If none, we may want to get the one that was set */
 5914 
 5915 	/* Push it out ! */
 5916 	dwrq->length = le16_to_cpu(status_rid.SSIDlen);
 5917 	dwrq->flags = 1; /* active */
 5918 
 5919 	return 0;
 5920 }
 5921 
 5922 /*------------------------------------------------------------------*/
 5923 /*
 5924  * Wireless Handler : set AP address
 5925  */
 5926 static int airo_set_wap(struct net_device *dev,
 5927 			struct iw_request_info *info,
 5928 			struct sockaddr *awrq,
 5929 			char *extra)
 5930 {
 5931 	struct airo_info *local = dev->ml_priv;
 5932 	Cmd cmd;
 5933 	Resp rsp;
 5934 	APListRid *APList_rid = &local->APList;
 5935 
 5936 	if (awrq->sa_family != ARPHRD_ETHER)
 5937 		return -EINVAL;
 5938 	else if (is_broadcast_ether_addr(awrq->sa_data) ||
 5939 		 is_zero_ether_addr(awrq->sa_data)) {
 5940 		memset(&cmd, 0, sizeof(cmd));
 5941 		cmd.cmd=CMD_LOSE_SYNC;
 5942 		if (down_interruptible(&local->sem))
 5943 			return -ERESTARTSYS;
 5944 		issuecommand(local, &cmd, &rsp);
 5945 		up(&local->sem);
 5946 	} else {
 5947 		memset(APList_rid, 0, sizeof(*APList_rid));
 5948 		APList_rid->len = cpu_to_le16(sizeof(*APList_rid));
 5949 		memcpy(APList_rid->ap[0], awrq->sa_data, ETH_ALEN);
 5950 		disable_MAC(local, 1);
 5951 		writeAPListRid(local, APList_rid, 1);
 5952 		enable_MAC(local, 1);
 5953 	}
 5954 	return 0;
 5955 }
 5956 
 5957 /*------------------------------------------------------------------*/
 5958 /*
 5959  * Wireless Handler : get AP address
 5960  */
 5961 static int airo_get_wap(struct net_device *dev,
 5962 			struct iw_request_info *info,
 5963 			struct sockaddr *awrq,
 5964 			char *extra)
 5965 {
 5966 	struct airo_info *local = dev->ml_priv;
 5967 	StatusRid status_rid;		/* Card status info */
 5968 
 5969 	readStatusRid(local, &status_rid, 1);
 5970 
 5971 	/* Tentative. This seems to work, wow, I'm lucky !!! */
 5972 	memcpy(awrq->sa_data, status_rid.bssid[0], ETH_ALEN);
 5973 	awrq->sa_family = ARPHRD_ETHER;
 5974 
 5975 	return 0;
 5976 }
 5977 
 5978 /*------------------------------------------------------------------*/
 5979 /*
 5980  * Wireless Handler : set Nickname
 5981  */
 5982 static int airo_set_nick(struct net_device *dev,
 5983 			 struct iw_request_info *info,
 5984 			 struct iw_point *dwrq,
 5985 			 char *extra)
 5986 {
 5987 	struct airo_info *local = dev->ml_priv;
 5988 
 5989 	/* Check the size of the string */
 5990 	if(dwrq->length > 16) {
 5991 		return -E2BIG;
 5992 	}
 5993 	readConfigRid(local, 1);
 5994 	memset(local->config.nodeName, 0, sizeof(local->config.nodeName));
 5995 	memcpy(local->config.nodeName, extra, dwrq->length);
 5996 	set_bit (FLAG_COMMIT, &local->flags);
 5997 
 5998 	return -EINPROGRESS;		/* Call commit handler */
 5999 }
 6000 
 6001 /*------------------------------------------------------------------*/
 6002 /*
 6003  * Wireless Handler : get Nickname
 6004  */
 6005 static int airo_get_nick(struct net_device *dev,
 6006 			 struct iw_request_info *info,
 6007 			 struct iw_point *dwrq,
 6008 			 char *extra)
 6009 {
 6010 	struct airo_info *local = dev->ml_priv;
 6011 
 6012 	readConfigRid(local, 1);
 6013 	strncpy(extra, local->config.nodeName, 16);
 6014 	extra[16] = '\0';
 6015 	dwrq->length = strlen(extra);
 6016 
 6017 	return 0;
 6018 }
 6019 
 6020 /*------------------------------------------------------------------*/
 6021 /*
 6022  * Wireless Handler : set Bit-Rate
 6023  */
 6024 static int airo_set_rate(struct net_device *dev,
 6025 			 struct iw_request_info *info,
 6026 			 struct iw_param *vwrq,
 6027 			 char *extra)
 6028 {
 6029 	struct airo_info *local = dev->ml_priv;
 6030 	CapabilityRid cap_rid;		/* Card capability info */
 6031 	u8	brate = 0;
 6032 	int	i;
 6033 
 6034 	/* First : get a valid bit rate value */
 6035 	readCapabilityRid(local, &cap_rid, 1);
 6036 
 6037 	/* Which type of value ? */
 6038 	if((vwrq->value < 8) && (vwrq->value >= 0)) {
 6039 		/* Setting by rate index */
 6040 		/* Find value in the magic rate table */
 6041 		brate = cap_rid.supportedRates[vwrq->value];
 6042 	} else {
 6043 		/* Setting by frequency value */
 6044 		u8	normvalue = (u8) (vwrq->value/500000);
 6045 
 6046 		/* Check if rate is valid */
 6047 		for(i = 0 ; i < 8 ; i++) {
 6048 			if(normvalue == cap_rid.supportedRates[i]) {
 6049 				brate = normvalue;
 6050 				break;
 6051 			}
 6052 		}
 6053 	}
 6054 	/* -1 designed the max rate (mostly auto mode) */
 6055 	if(vwrq->value == -1) {
 6056 		/* Get the highest available rate */
 6057 		for(i = 0 ; i < 8 ; i++) {
 6058 			if(cap_rid.supportedRates[i] == 0)
 6059 				break;
 6060 		}
 6061 		if(i != 0)
 6062 			brate = cap_rid.supportedRates[i - 1];
 6063 	}
 6064 	/* Check that it is valid */
 6065 	if(brate == 0) {
 6066 		return -EINVAL;
 6067 	}
 6068 
 6069 	readConfigRid(local, 1);
 6070 	/* Now, check if we want a fixed or auto value */
 6071 	if(vwrq->fixed == 0) {
 6072 		/* Fill all the rates up to this max rate */
 6073 		memset(local->config.rates, 0, 8);
 6074 		for(i = 0 ; i < 8 ; i++) {
 6075 			local->config.rates[i] = cap_rid.supportedRates[i];
 6076 			if(local->config.rates[i] == brate)
 6077 				break;
 6078 		}
 6079 	} else {
 6080 		/* Fixed mode */
 6081 		/* One rate, fixed */
 6082 		memset(local->config.rates, 0, 8);
 6083 		local->config.rates[0] = brate;
 6084 	}
 6085 	set_bit (FLAG_COMMIT, &local->flags);
 6086 
 6087 	return -EINPROGRESS;		/* Call commit handler */
 6088 }
 6089 
 6090 /*------------------------------------------------------------------*/
 6091 /*
 6092  * Wireless Handler : get Bit-Rate
 6093  */
 6094 static int airo_get_rate(struct net_device *dev,
 6095 			 struct iw_request_info *info,
 6096 			 struct iw_param *vwrq,
 6097 			 char *extra)
 6098 {
 6099 	struct airo_info *local = dev->ml_priv;
 6100 	StatusRid status_rid;		/* Card status info */
 6101 
 6102 	readStatusRid(local, &status_rid, 1);
 6103 
 6104 	vwrq->value = le16_to_cpu(status_rid.currentXmitRate) * 500000;
 6105 	/* If more than one rate, set auto */
 6106 	readConfigRid(local, 1);
 6107 	vwrq->fixed = (local->config.rates[1] == 0);
 6108 
 6109 	return 0;
 6110 }
 6111 
 6112 /*------------------------------------------------------------------*/
 6113 /*
 6114  * Wireless Handler : set RTS threshold
 6115  */
 6116 static int airo_set_rts(struct net_device *dev,
 6117 			struct iw_request_info *info,
 6118 			struct iw_param *vwrq,
 6119 			char *extra)
 6120 {
 6121 	struct airo_info *local = dev->ml_priv;
 6122 	int rthr = vwrq->value;
 6123 
 6124 	if(vwrq->disabled)
 6125 		rthr = AIRO_DEF_MTU;
 6126 	if((rthr < 0) || (rthr > AIRO_DEF_MTU)) {
 6127 		return -EINVAL;
 6128 	}
 6129 	readConfigRid(local, 1);
 6130 	local->config.rtsThres = cpu_to_le16(rthr);
 6131 	set_bit (FLAG_COMMIT, &local->flags);
 6132 
 6133 	return -EINPROGRESS;		/* Call commit handler */
 6134 }
 6135 
 6136 /*------------------------------------------------------------------*/
 6137 /*
 6138  * Wireless Handler : get RTS threshold
 6139  */
 6140 static int airo_get_rts(struct net_device *dev,
 6141 			struct iw_request_info *info,
 6142 			struct iw_param *vwrq,
 6143 			char *extra)
 6144 {
 6145 	struct airo_info *local = dev->ml_priv;
 6146 
 6147 	readConfigRid(local, 1);
 6148 	vwrq->value = le16_to_cpu(local->config.rtsThres);
 6149 	vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
 6150 	vwrq->fixed = 1;
 6151 
 6152 	return 0;
 6153 }
 6154 
 6155 /*------------------------------------------------------------------*/
 6156 /*
 6157  * Wireless Handler : set Fragmentation threshold
 6158  */
 6159 static int airo_set_frag(struct net_device *dev,
 6160 			 struct iw_request_info *info,
 6161 			 struct iw_param *vwrq,
 6162 			 char *extra)
 6163 {
 6164 	struct airo_info *local = dev->ml_priv;
 6165 	int fthr = vwrq->value;
 6166 
 6167 	if(vwrq->disabled)
 6168 		fthr = AIRO_DEF_MTU;
 6169 	if((fthr < 256) || (fthr > AIRO_DEF_MTU)) {
 6170 		return -EINVAL;
 6171 	}
 6172 	fthr &= ~0x1;	/* Get an even value - is it really needed ??? */
 6173 	readConfigRid(local, 1);
 6174 	local->config.fragThresh = cpu_to_le16(fthr);
 6175 	set_bit (FLAG_COMMIT, &local->flags);
 6176 
 6177 	return -EINPROGRESS;		/* Call commit handler */
 6178 }
 6179 
 6180 /*------------------------------------------------------------------*/
 6181 /*
 6182  * Wireless Handler : get Fragmentation threshold
 6183  */
 6184 static int airo_get_frag(struct net_device *dev,
 6185 			 struct iw_request_info *info,
 6186 			 struct iw_param *vwrq,
 6187 			 char *extra)
 6188 {
 6189 	struct airo_info *local = dev->ml_priv;
 6190 
 6191 	readConfigRid(local, 1);
 6192 	vwrq->value = le16_to_cpu(local->config.fragThresh);
 6193 	vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
 6194 	vwrq->fixed = 1;
 6195 
 6196 	return 0;
 6197 }
 6198 
 6199 /*------------------------------------------------------------------*/
 6200 /*
 6201  * Wireless Handler : set Mode of Operation
 6202  */
 6203 static int airo_set_mode(struct net_device *dev,
 6204 			 struct iw_request_info *info,
 6205 			 __u32 *uwrq,
 6206 			 char *extra)
 6207 {
 6208 	struct airo_info *local = dev->ml_priv;
 6209 	int reset = 0;
 6210 
 6211 	readConfigRid(local, 1);
 6212 	if (sniffing_mode(local))
 6213 		reset = 1;
 6214 
 6215 	switch(*uwrq) {
 6216 		case IW_MODE_ADHOC:
 6217 			local->config.opmode &= ~MODE_CFG_MASK;
 6218 			local->config.opmode |= MODE_STA_IBSS;
 6219 			local->config.rmode &= ~RXMODE_FULL_MASK;
 6220 			local->config.scanMode = SCANMODE_ACTIVE;
 6221 			clear_bit (FLAG_802_11, &local->flags);
 6222 			break;
 6223 		case IW_MODE_INFRA:
 6224 			local->config.opmode &= ~MODE_CFG_MASK;
 6225 			local->config.opmode |= MODE_STA_ESS;
 6226 			local->config.rmode &= ~RXMODE_FULL_MASK;
 6227 			local->config.scanMode = SCANMODE_ACTIVE;
 6228 			clear_bit (FLAG_802_11, &local->flags);
 6229 			break;
 6230 		case IW_MODE_MASTER:
 6231 			local->config.opmode &= ~MODE_CFG_MASK;
 6232 			local->config.opmode |= MODE_AP;
 6233 			local->config.rmode &= ~RXMODE_FULL_MASK;
 6234 			local->config.scanMode = SCANMODE_ACTIVE;
 6235 			clear_bit (FLAG_802_11, &local->flags);
 6236 			break;
 6237 		case IW_MODE_REPEAT:
 6238 			local->config.opmode &= ~MODE_CFG_MASK;
 6239 			local->config.opmode |= MODE_AP_RPTR;
 6240 			local->config.rmode &= ~RXMODE_FULL_MASK;
 6241 			local->config.scanMode = SCANMODE_ACTIVE;
 6242 			clear_bit (FLAG_802_11, &local->flags);
 6243 			break;
 6244 		case IW_MODE_MONITOR:
 6245 			local->config.opmode &= ~MODE_CFG_MASK;
 6246 			local->config.opmode |= MODE_STA_ESS;
 6247 			local->config.rmode &= ~RXMODE_FULL_MASK;
 6248 			local->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
 6249 			local->config.scanMode = SCANMODE_PASSIVE;
 6250 			set_bit (FLAG_802_11, &local->flags);
 6251 			break;
 6252 		default:
 6253 			return -EINVAL;
 6254 	}
 6255 	if (reset)
 6256 		set_bit (FLAG_RESET, &local->flags);
 6257 	set_bit (FLAG_COMMIT, &local->flags);
 6258 
 6259 	return -EINPROGRESS;		/* Call commit handler */
 6260 }
 6261 
 6262 /*------------------------------------------------------------------*/
 6263 /*
 6264  * Wireless Handler : get Mode of Operation
 6265  */
 6266 static int airo_get_mode(struct net_device *dev,
 6267 			 struct iw_request_info *info,
 6268 			 __u32 *uwrq,
 6269 			 char *extra)
 6270 {
 6271 	struct airo_info *local = dev->ml_priv;
 6272 
 6273 	readConfigRid(local, 1);
 6274 	/* If not managed, assume it's ad-hoc */
 6275 	switch (local->config.opmode & MODE_CFG_MASK) {
 6276 		case MODE_STA_ESS:
 6277 			*uwrq = IW_MODE_INFRA;
 6278 			break;
 6279 		case MODE_AP:
 6280 			*uwrq = IW_MODE_MASTER;
 6281 			break;
 6282 		case MODE_AP_RPTR:
 6283 			*uwrq = IW_MODE_REPEAT;
 6284 			break;
 6285 		default:
 6286 			*uwrq = IW_MODE_ADHOC;
 6287 	}
 6288 
 6289 	return 0;
 6290 }
 6291 
 6292 static inline int valid_index(struct airo_info *ai, int index)
 6293 {
 6294 	return (index >= 0) && (index <= ai->max_wep_idx);
 6295 }
 6296 
 6297 /*------------------------------------------------------------------*/
 6298 /*
 6299  * Wireless Handler : set Encryption Key
 6300  */
 6301 static int airo_set_encode(struct net_device *dev,
 6302 			   struct iw_request_info *info,
 6303 			   struct iw_point *dwrq,
 6304 			   char *extra)
 6305 {
 6306 	struct airo_info *local = dev->ml_priv;
 6307 	int perm = (dwrq->flags & IW_ENCODE_TEMP ? 0 : 1);
 6308 	__le16 currentAuthType = local->config.authType;
 6309 	int rc = 0;
 6310 
 6311 	if (!local->wep_capable)
 6312 		return -EOPNOTSUPP;
 6313 
 6314 	readConfigRid(local, 1);
 6315 
 6316 	/* Basic checking: do we have a key to set ?
 6317 	 * Note : with the new API, it's impossible to get a NULL pointer.
 6318 	 * Therefore, we need to check a key size == 0 instead.
 6319 	 * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
 6320 	 * when no key is present (only change flags), but older versions
 6321 	 * don't do it. - Jean II */
 6322 	if (dwrq->length > 0) {
 6323 		wep_key_t key;
 6324 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
 6325 		int current_index;
 6326 
 6327 		/* Check the size of the key */
 6328 		if (dwrq->length > MAX_KEY_SIZE) {
 6329 			return -EINVAL;
 6330 		}
 6331 
 6332 		current_index = get_wep_tx_idx(local);
 6333 		if (current_index < 0)
 6334 			current_index = 0;
 6335 
 6336 		/* Check the index (none -> use current) */
 6337 		if (!valid_index(local, index))
 6338 			index = current_index;
 6339 
 6340 		/* Set the length */
 6341 		if (dwrq->length > MIN_KEY_SIZE)
 6342 			key.len = MAX_KEY_SIZE;
 6343 		else
 6344 			key.len = MIN_KEY_SIZE;
 6345 		/* Check if the key is not marked as invalid */
 6346 		if(!(dwrq->flags & IW_ENCODE_NOKEY)) {
 6347 			/* Cleanup */
 6348 			memset(key.key, 0, MAX_KEY_SIZE);
 6349 			/* Copy the key in the driver */
 6350 			memcpy(key.key, extra, dwrq->length);
 6351 			/* Send the key to the card */
 6352 			rc = set_wep_key(local, index, key.key, key.len, perm, 1);
 6353 			if (rc < 0) {
 6354 				airo_print_err(local->dev->name, "failed to set"
 6355 				               " WEP key at index %d: %d.",
 6356 				               index, rc);
 6357 				return rc;
 6358 			}
 6359 		}
 6360 		/* WE specify that if a valid key is set, encryption
 6361 		 * should be enabled (user may turn it off later)
 6362 		 * This is also how "iwconfig ethX key on" works */
 6363 		if((index == current_index) && (key.len > 0) &&
 6364 		   (local->config.authType == AUTH_OPEN))
 6365 			set_auth_type(local, AUTH_ENCRYPT);
 6366 	} else {
 6367 		/* Do we want to just set the transmit key index ? */
 6368 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
 6369 		if (valid_index(local, index)) {
 6370 			rc = set_wep_tx_idx(local, index, perm, 1);
 6371 			if (rc < 0) {
 6372 				airo_print_err(local->dev->name, "failed to set"
 6373 				               " WEP transmit index to %d: %d.",
 6374 				               index, rc);
 6375 				return rc;
 6376 			}
 6377 		} else {
 6378 			/* Don't complain if only change the mode */
 6379 			if (!(dwrq->flags & IW_ENCODE_MODE))
 6380 				return -EINVAL;
 6381 		}
 6382 	}
 6383 	/* Read the flags */
 6384 	if (dwrq->flags & IW_ENCODE_DISABLED)
 6385 		set_auth_type(local, AUTH_OPEN);	/* disable encryption */
 6386 	if(dwrq->flags & IW_ENCODE_RESTRICTED)
 6387 		set_auth_type(local, AUTH_SHAREDKEY);	/* Only Both */
 6388 	if (dwrq->flags & IW_ENCODE_OPEN)
 6389 		set_auth_type(local, AUTH_ENCRYPT);	/* Only Wep */
 6390 	/* Commit the changes to flags if needed */
 6391 	if (local->config.authType != currentAuthType)
 6392 		set_bit (FLAG_COMMIT, &local->flags);
 6393 	return -EINPROGRESS;		/* Call commit handler */
 6394 }
 6395 
 6396 /*------------------------------------------------------------------*/
 6397 /*
 6398  * Wireless Handler : get Encryption Key
 6399  */
 6400 static int airo_get_encode(struct net_device *dev,
 6401 			   struct iw_request_info *info,
 6402 			   struct iw_point *dwrq,
 6403 			   char *extra)
 6404 {
 6405 	struct airo_info *local = dev->ml_priv;
 6406 	int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
 6407 	int wep_key_len;
 6408 	u8 buf[16];
 6409 
 6410 	if (!local->wep_capable)
 6411 		return -EOPNOTSUPP;
 6412 
 6413 	readConfigRid(local, 1);
 6414 
 6415 	/* Check encryption mode */
 6416 	switch(local->config.authType)	{
 6417 		case AUTH_ENCRYPT:
 6418 			dwrq->flags = IW_ENCODE_OPEN;
 6419 			break;
 6420 		case AUTH_SHAREDKEY:
 6421 			dwrq->flags = IW_ENCODE_RESTRICTED;
 6422 			break;
 6423 		default:
 6424 		case AUTH_OPEN:
 6425 			dwrq->flags = IW_ENCODE_DISABLED;
 6426 			break;
 6427 	}
 6428 	/* We can't return the key, so set the proper flag and return zero */
 6429 	dwrq->flags |= IW_ENCODE_NOKEY;
 6430 	memset(extra, 0, 16);
 6431 
 6432 	/* Which key do we want ? -1 -> tx index */
 6433 	if (!valid_index(local, index)) {
 6434 		index = get_wep_tx_idx(local);
 6435 		if (index < 0)
 6436 			index = 0;
 6437 	}
 6438 	dwrq->flags |= index + 1;
 6439 
 6440 	/* Copy the key to the user buffer */
 6441 	wep_key_len = get_wep_key(local, index, &buf[0], sizeof(buf));
 6442 	if (wep_key_len < 0) {
 6443 		dwrq->length = 0;
 6444 	} else {
 6445 		dwrq->length = wep_key_len;
 6446 		memcpy(extra, buf, dwrq->length);
 6447 	}
 6448 
 6449 	return 0;
 6450 }
 6451 
 6452 /*------------------------------------------------------------------*/
 6453 /*
 6454  * Wireless Handler : set extended Encryption parameters
 6455  */
 6456 static int airo_set_encodeext(struct net_device *dev,
 6457 			   struct iw_request_info *info,
 6458 			    union iwreq_data *wrqu,
 6459 			    char *extra)
 6460 {
 6461 	struct airo_info *local = dev->ml_priv;
 6462 	struct iw_point *encoding = &wrqu->encoding;
 6463 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
 6464 	int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 );
 6465 	__le16 currentAuthType = local->config.authType;
 6466 	int idx, key_len, alg = ext->alg, set_key = 1, rc;
 6467 	wep_key_t key;
 6468 
 6469 	if (!local->wep_capable)
 6470 		return -EOPNOTSUPP;
 6471 
 6472 	readConfigRid(local, 1);
 6473 
 6474 	/* Determine and validate the key index */
 6475 	idx = encoding->flags & IW_ENCODE_INDEX;
 6476 	if (idx) {
 6477 		if (!valid_index(local, idx - 1))
 6478 			return -EINVAL;
 6479 		idx--;
 6480 	} else {
 6481 		idx = get_wep_tx_idx(local);
 6482 		if (idx < 0)
 6483 			idx = 0;
 6484 	}
 6485 
 6486 	if (encoding->flags & IW_ENCODE_DISABLED)
 6487 		alg = IW_ENCODE_ALG_NONE;
 6488 
 6489 	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
 6490 		/* Only set transmit key index here, actual
 6491 		 * key is set below if needed.
 6492 		 */
 6493 		rc = set_wep_tx_idx(local, idx, perm, 1);
 6494 		if (rc < 0) {
 6495 			airo_print_err(local->dev->name, "failed to set "
 6496 			               "WEP transmit index to %d: %d.",
 6497 			               idx, rc);
 6498 			return rc;
 6499 		}
 6500 		set_key = ext->key_len > 0 ? 1 : 0;
 6501 	}
 6502 
 6503 	if (set_key) {
 6504 		/* Set the requested key first */
 6505 		memset(key.key, 0, MAX_KEY_SIZE);
 6506 		switch (alg) {
 6507 		case IW_ENCODE_ALG_NONE:
 6508 			key.len = 0;
 6509 			break;
 6510 		case IW_ENCODE_ALG_WEP:
 6511 			if (ext->key_len > MIN_KEY_SIZE) {
 6512 				key.len = MAX_KEY_SIZE;
 6513 			} else if (ext->key_len > 0) {
 6514 				key.len = MIN_KEY_SIZE;
 6515 			} else {
 6516 				return -EINVAL;
 6517 			}
 6518 			key_len = min (ext->key_len, key.len);
 6519 			memcpy(key.key, ext->key, key_len);
 6520 			break;
 6521 		default:
 6522 			return -EINVAL;
 6523 		}
 6524 		if (key.len == 0) {
 6525 			rc = set_wep_tx_idx(local, idx, perm, 1);
 6526 			if (rc < 0) {
 6527 				airo_print_err(local->dev->name,
 6528 					       "failed to set WEP transmit index to %d: %d.",
 6529 					       idx, rc);
 6530 				return rc;
 6531 			}
 6532 		} else {
 6533 			rc = set_wep_key(local, idx, key.key, key.len, perm, 1);
 6534 			if (rc < 0) {
 6535 				airo_print_err(local->dev->name,
 6536 					       "failed to set WEP key at index %d: %d.",
 6537 					       idx, rc);
 6538 				return rc;
 6539 			}
 6540 		}
 6541 	}
 6542 
 6543 	/* Read the flags */
 6544 	if (encoding->flags & IW_ENCODE_DISABLED)
 6545 		set_auth_type(local, AUTH_OPEN);	/* disable encryption */
 6546 	if(encoding->flags & IW_ENCODE_RESTRICTED)
 6547 		set_auth_type(local, AUTH_SHAREDKEY);	/* Only Both */
 6548 	if (encoding->flags & IW_ENCODE_OPEN)
 6549 		set_auth_type(local, AUTH_ENCRYPT);
 6550 	/* Commit the changes to flags if needed */
 6551 	if (local->config.authType != currentAuthType)
 6552 		set_bit (FLAG_COMMIT, &local->flags);
 6553 
 6554 	return -EINPROGRESS;
 6555 }
 6556 
 6557 
 6558 /*------------------------------------------------------------------*/
 6559 /*
 6560  * Wireless Handler : get extended Encryption parameters
 6561  */
 6562 static int airo_get_encodeext(struct net_device *dev,
 6563 			    struct iw_request_info *info,
 6564 			    union iwreq_data *wrqu,
 6565 			    char *extra)
 6566 {
 6567 	struct airo_info *local = dev->ml_priv;
 6568 	struct iw_point *encoding = &wrqu->encoding;
 6569 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
 6570 	int idx, max_key_len, wep_key_len;
 6571 	u8 buf[16];
 6572 
 6573 	if (!local->wep_capable)
 6574 		return -EOPNOTSUPP;
 6575 
 6576 	readConfigRid(local, 1);
 6577 
 6578 	max_key_len = encoding->length - sizeof(*ext);
 6579 	if (max_key_len < 0)
 6580 		return -EINVAL;
 6581 
 6582 	idx = encoding->flags & IW_ENCODE_INDEX;
 6583 	if (idx) {
 6584 		if (!valid_index(local, idx - 1))
 6585 			return -EINVAL;
 6586 		idx--;
 6587 	} else {
 6588 		idx = get_wep_tx_idx(local);
 6589 		if (idx < 0)
 6590 			idx = 0;
 6591 	}
 6592 
 6593 	encoding->flags = idx + 1;
 6594 	memset(ext, 0, sizeof(*ext));
 6595 
 6596 	/* Check encryption mode */
 6597 	switch(local->config.authType) {
 6598 		case AUTH_ENCRYPT:
 6599 			encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED;
 6600 			break;
 6601 		case AUTH_SHAREDKEY:
 6602 			encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED;
 6603 			break;
 6604 		default:
 6605 		case AUTH_OPEN:
 6606 			encoding->flags = IW_ENCODE_ALG_NONE | IW_ENCODE_DISABLED;
 6607 			break;
 6608 	}
 6609 	/* We can't return the key, so set the proper flag and return zero */
 6610 	encoding->flags |= IW_ENCODE_NOKEY;
 6611 	memset(extra, 0, 16);
 6612 	
 6613 	/* Copy the key to the user buffer */
 6614 	wep_key_len = get_wep_key(local, idx, &buf[0], sizeof(buf));
 6615 	if (wep_key_len < 0) {
 6616 		ext->key_len = 0;
 6617 	} else {
 6618 		ext->key_len = wep_key_len;
 6619 		memcpy(extra, buf, ext->key_len);
 6620 	}
 6621 
 6622 	return 0;
 6623 }
 6624 
 6625 
 6626 /*------------------------------------------------------------------*/
 6627 /*
 6628  * Wireless Handler : set extended authentication parameters
 6629  */
 6630 static int airo_set_auth(struct net_device *dev,
 6631 			       struct iw_request_info *info,
 6632 			       union iwreq_data *wrqu, char *extra)
 6633 {
 6634 	struct airo_info *local = dev->ml_priv;
 6635 	struct iw_param *param = &wrqu->param;
 6636 	__le16 currentAuthType = local->config.authType;
 6637 
 6638 	switch (param->flags & IW_AUTH_INDEX) {
 6639 	case IW_AUTH_WPA_VERSION:
 6640 	case IW_AUTH_CIPHER_PAIRWISE:
 6641 	case IW_AUTH_CIPHER_GROUP:
 6642 	case IW_AUTH_KEY_MGMT:
 6643 	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
 6644 	case IW_AUTH_PRIVACY_INVOKED:
 6645 		/*
 6646 		 * airo does not use these parameters
 6647 		 */
 6648 		break;
 6649 
 6650 	case IW_AUTH_DROP_UNENCRYPTED:
 6651 		if (param->value) {
 6652 			/* Only change auth type if unencrypted */
 6653 			if (currentAuthType == AUTH_OPEN)
 6654 				set_auth_type(local, AUTH_ENCRYPT);
 6655 		} else {
 6656 			set_auth_type(local, AUTH_OPEN);
 6657 		}
 6658 
 6659 		/* Commit the changes to flags if needed */
 6660 		if (local->config.authType != currentAuthType)
 6661 			set_bit (FLAG_COMMIT, &local->flags);
 6662 		break;
 6663 
 6664 	case IW_AUTH_80211_AUTH_ALG: {
 6665 			if (param->value & IW_AUTH_ALG_SHARED_KEY) {
 6666 				set_auth_type(local, AUTH_SHAREDKEY);
 6667 			} else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
 6668 				/* We don't know here if WEP open system or
 6669 				 * unencrypted mode was requested - so use the
 6670 				 * last mode (of these two) used last time
 6671 				 */
 6672 				set_auth_type(local, local->last_auth);
 6673 			} else
 6674 				return -EINVAL;
 6675 
 6676 			/* Commit the changes to flags if needed */
 6677 			if (local->config.authType != currentAuthType)
 6678 				set_bit (FLAG_COMMIT, &local->flags);
 6679 			break;
 6680 		}
 6681 
 6682 	case IW_AUTH_WPA_ENABLED:
 6683 		/* Silently accept disable of WPA */
 6684 		if (param->value > 0)
 6685 			return -EOPNOTSUPP;
 6686 		break;
 6687 
 6688 	default:
 6689 		return -EOPNOTSUPP;
 6690 	}
 6691 	return -EINPROGRESS;
 6692 }
 6693 
 6694 
 6695 /*------------------------------------------------------------------*/
 6696 /*
 6697  * Wireless Handler : get extended authentication parameters
 6698  */
 6699 static int airo_get_auth(struct net_device *dev,
 6700 			       struct iw_request_info *info,
 6701 			       union iwreq_data *wrqu, char *extra)
 6702 {
 6703 	struct airo_info *local = dev->ml_priv;
 6704 	struct iw_param *param = &wrqu->param;
 6705 	__le16 currentAuthType = local->config.authType;
 6706 
 6707 	switch (param->flags & IW_AUTH_INDEX) {
 6708 	case IW_AUTH_DROP_UNENCRYPTED:
 6709 		switch (currentAuthType) {
 6710 		case AUTH_SHAREDKEY:
 6711 		case AUTH_ENCRYPT:
 6712 			param->value = 1;
 6713 			break;
 6714 		default:
 6715 			param->value = 0;
 6716 			break;
 6717 		}
 6718 		break;
 6719 
 6720 	case IW_AUTH_80211_AUTH_ALG:
 6721 		switch (currentAuthType) {
 6722 		case AUTH_SHAREDKEY:
 6723 			param->value = IW_AUTH_ALG_SHARED_KEY;
 6724 			break;
 6725 		case AUTH_ENCRYPT:
 6726 		default:
 6727 			param->value = IW_AUTH_ALG_OPEN_SYSTEM;
 6728 			break;
 6729 		}
 6730 		break;
 6731 
 6732 	case IW_AUTH_WPA_ENABLED:
 6733 		param->value = 0;
 6734 		break;
 6735 
 6736 	default:
 6737 		return -EOPNOTSUPP;
 6738 	}
 6739 	return 0;
 6740 }
 6741 
 6742 
 6743 /*------------------------------------------------------------------*/
 6744 /*
 6745  * Wireless Handler : set Tx-Power
 6746  */
 6747 static int airo_set_txpow(struct net_device *dev,
 6748 			  struct iw_request_info *info,
 6749 			  struct iw_param *vwrq,
 6750 			  char *extra)
 6751 {
 6752 	struct airo_info *local = dev->ml_priv;
 6753 	CapabilityRid cap_rid;		/* Card capability info */
 6754 	int i;
 6755 	int rc = -EINVAL;
 6756 	__le16 v = cpu_to_le16(vwrq->value);
 6757 
 6758 	readCapabilityRid(local, &cap_rid, 1);
 6759 
 6760 	if (vwrq->disabled) {
 6761 		set_bit (FLAG_RADIO_OFF, &local->flags);
 6762 		set_bit (FLAG_COMMIT, &local->flags);
 6763 		return -EINPROGRESS;		/* Call commit handler */
 6764 	}
 6765 	if (vwrq->flags != IW_TXPOW_MWATT) {
 6766 		return -EINVAL;
 6767 	}
 6768 	clear_bit (FLAG_RADIO_OFF, &local->flags);
 6769 	for (i = 0; i < 8 && cap_rid.txPowerLevels[i]; i++)
 6770 		if (v == cap_rid.txPowerLevels[i]) {
 6771 			readConfigRid(local, 1);
 6772 			local->config.txPower = v;
 6773 			set_bit (FLAG_COMMIT, &local->flags);
 6774 			rc = -EINPROGRESS;	/* Call commit handler */
 6775 			break;
 6776 		}
 6777 	return rc;
 6778 }
 6779 
 6780 /*------------------------------------------------------------------*/
 6781 /*
 6782  * Wireless Handler : get Tx-Power
 6783  */
 6784 static int airo_get_txpow(struct net_device *dev,
 6785 			  struct iw_request_info *info,
 6786 			  struct iw_param *vwrq,
 6787 			  char *extra)
 6788 {
 6789 	struct airo_info *local = dev->ml_priv;
 6790 
 6791 	readConfigRid(local, 1);
 6792 	vwrq->value = le16_to_cpu(local->config.txPower);
 6793 	vwrq->fixed = 1;	/* No power control */
 6794 	vwrq->disabled = test_bit(FLAG_RADIO_OFF, &local->flags);
 6795 	vwrq->flags = IW_TXPOW_MWATT;
 6796 
 6797 	return 0;
 6798 }
 6799 
 6800 /*------------------------------------------------------------------*/
 6801 /*
 6802  * Wireless Handler : set Retry limits
 6803  */
 6804 static int airo_set_retry(struct net_device *dev,
 6805 			  struct iw_request_info *info,
 6806 			  struct iw_param *vwrq,
 6807 			  char *extra)
 6808 {
 6809 	struct airo_info *local = dev->ml_priv;
 6810 	int rc = -EINVAL;
 6811 
 6812 	if(vwrq->disabled) {
 6813 		return -EINVAL;
 6814 	}
 6815 	readConfigRid(local, 1);
 6816 	if(vwrq->flags & IW_RETRY_LIMIT) {
 6817 		__le16 v = cpu_to_le16(vwrq->value);
 6818 		if(vwrq->flags & IW_RETRY_LONG)
 6819 			local->config.longRetryLimit = v;
 6820 		else if (vwrq->flags & IW_RETRY_SHORT)
 6821 			local->config.shortRetryLimit = v;
 6822 		else {
 6823 			/* No modifier : set both */
 6824 			local->config.longRetryLimit = v;
 6825 			local->config.shortRetryLimit = v;
 6826 		}
 6827 		set_bit (FLAG_COMMIT, &local->flags);
 6828 		rc = -EINPROGRESS;		/* Call commit handler */
 6829 	}
 6830 	if(vwrq->flags & IW_RETRY_LIFETIME) {
 6831 		local->config.txLifetime = cpu_to_le16(vwrq->value / 1024);
 6832 		set_bit (FLAG_COMMIT, &local->flags);
 6833 		rc = -EINPROGRESS;		/* Call commit handler */
 6834 	}
 6835 	return rc;
 6836 }
 6837 
 6838 /*------------------------------------------------------------------*/
 6839 /*
 6840  * Wireless Handler : get Retry limits
 6841  */
 6842 static int airo_get_retry(struct net_device *dev,
 6843 			  struct iw_request_info *info,
 6844 			  struct iw_param *vwrq,
 6845 			  char *extra)
 6846 {
 6847 	struct airo_info *local = dev->ml_priv;
 6848 
 6849 	vwrq->disabled = 0;      /* Can't be disabled */
 6850 
 6851 	readConfigRid(local, 1);
 6852 	/* Note : by default, display the min retry number */
 6853 	if((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
 6854 		vwrq->flags = IW_RETRY_LIFETIME;
 6855 		vwrq->value = le16_to_cpu(local->config.txLifetime) * 1024;
 6856 	} else if((vwrq->flags & IW_RETRY_LONG)) {
 6857 		vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
 6858 		vwrq->value = le16_to_cpu(local->config.longRetryLimit);
 6859 	} else {
 6860 		vwrq->flags = IW_RETRY_LIMIT;
 6861 		vwrq->value = le16_to_cpu(local->config.shortRetryLimit);
 6862 		if(local->config.shortRetryLimit != local->config.longRetryLimit)
 6863 			vwrq->flags |= IW_RETRY_SHORT;
 6864 	}
 6865 
 6866 	return 0;
 6867 }
 6868 
 6869 /*------------------------------------------------------------------*/
 6870 /*
 6871  * Wireless Handler : get range info
 6872  */
 6873 static int airo_get_range(struct net_device *dev,
 6874 			  struct iw_request_info *info,
 6875 			  struct iw_point *dwrq,
 6876 			  char *extra)
 6877 {
 6878 	struct airo_info *local = dev->ml_priv;
 6879 	struct iw_range *range = (struct iw_range *) extra;
 6880 	CapabilityRid cap_rid;		/* Card capability info */
 6881 	int		i;
 6882 	int		k;
 6883 
 6884 	readCapabilityRid(local, &cap_rid, 1);
 6885 
 6886 	dwrq->length = sizeof(struct iw_range);
 6887 	memset(range, 0, sizeof(*range));
 6888 	range->min_nwid = 0x0000;
 6889 	range->max_nwid = 0x0000;
 6890 	range->num_channels = 14;
 6891 	/* Should be based on cap_rid.country to give only
 6892 	 * what the current card support */
 6893 	k = 0;
 6894 	for(i = 0; i < 14; i++) {
 6895 		range->freq[k].i = i + 1; /* List index */
 6896 		range->freq[k].m = 100000 *
 6897 		     ieee80211_channel_to_frequency(i + 1, IEEE80211_BAND_2GHZ);
 6898 		range->freq[k++].e = 1;	/* Values in MHz -> * 10^5 * 10 */
 6899 	}
 6900 	range->num_frequency = k;
 6901 
 6902 	range->sensitivity = 65535;
 6903 
 6904 	/* Hum... Should put the right values there */
 6905 	if (local->rssi)
 6906 		range->max_qual.qual = 100;	/* % */
 6907 	else
 6908 		range->max_qual.qual = airo_get_max_quality(&cap_rid);
 6909 	range->max_qual.level = 0x100 - 120;	/* -120 dBm */
 6910 	range->max_qual.noise = 0x100 - 120;	/* -120 dBm */
 6911 
 6912 	/* Experimental measurements - boundary 11/5.5 Mb/s */
 6913 	/* Note : with or without the (local->rssi), results
 6914 	 * are somewhat different. - Jean II */
 6915 	if (local->rssi) {
 6916 		range->avg_qual.qual = 50;		/* % */
 6917 		range->avg_qual.level = 0x100 - 70;	/* -70 dBm */
 6918 	} else {
 6919 		range->avg_qual.qual = airo_get_avg_quality(&cap_rid);
 6920 		range->avg_qual.level = 0x100 - 80;	/* -80 dBm */
 6921 	}
 6922 	range->avg_qual.noise = 0x100 - 85;		/* -85 dBm */
 6923 
 6924 	for(i = 0 ; i < 8 ; i++) {
 6925 		range->bitrate[i] = cap_rid.supportedRates[i] * 500000;
 6926 		if(range->bitrate[i] == 0)
 6927 			break;
 6928 	}
 6929 	range->num_bitrates = i;
 6930 
 6931 	/* Set an indication of the max TCP throughput
 6932 	 * in bit/s that we can expect using this interface.
 6933 	 * May be use for QoS stuff... Jean II */
 6934 	if(i > 2)
 6935 		range->throughput = 5000 * 1000;
 6936 	else
 6937 		range->throughput = 1500 * 1000;
 6938 
 6939 	range->min_rts = 0;
 6940 	range->max_rts = AIRO_DEF_MTU;
 6941 	range->min_frag = 256;
 6942 	range->max_frag = AIRO_DEF_MTU;
 6943 
 6944 	if(cap_rid.softCap & cpu_to_le16(2)) {
 6945 		// WEP: RC4 40 bits
 6946 		range->encoding_size[0] = 5;
 6947 		// RC4 ~128 bits
 6948 		if (cap_rid.softCap & cpu_to_le16(0x100)) {
 6949 			range->encoding_size[1] = 13;
 6950 			range->num_encoding_sizes = 2;
 6951 		} else
 6952 			range->num_encoding_sizes = 1;
 6953 		range->max_encoding_tokens =
 6954 			cap_rid.softCap & cpu_to_le16(0x80) ? 4 : 1;
 6955 	} else {
 6956 		range->num_encoding_sizes = 0;
 6957 		range->max_encoding_tokens = 0;
 6958 	}
 6959 	range->min_pmp = 0;
 6960 	range->max_pmp = 5000000;	/* 5 secs */
 6961 	range->min_pmt = 0;
 6962 	range->max_pmt = 65535 * 1024;	/* ??? */
 6963 	range->pmp_flags = IW_POWER_PERIOD;
 6964 	range->pmt_flags = IW_POWER_TIMEOUT;
 6965 	range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
 6966 
 6967 	/* Transmit Power - values are in mW */
 6968 	for(i = 0 ; i < 8 ; i++) {
 6969 		range->txpower[i] = le16_to_cpu(cap_rid.txPowerLevels[i]);
 6970 		if(range->txpower[i] == 0)
 6971 			break;
 6972 	}
 6973 	range->num_txpower = i;
 6974 	range->txpower_capa = IW_TXPOW_MWATT;
 6975 	range->we_version_source = 19;
 6976 	range->we_version_compiled = WIRELESS_EXT;
 6977 	range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
 6978 	range->retry_flags = IW_RETRY_LIMIT;
 6979 	range->r_time_flags = IW_RETRY_LIFETIME;
 6980 	range->min_retry = 1;
 6981 	range->max_retry = 65535;
 6982 	range->min_r_time = 1024;
 6983 	range->max_r_time = 65535 * 1024;
 6984 
 6985 	/* Event capability (kernel + driver) */
 6986 	range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
 6987 				IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
 6988 				IW_EVENT_CAPA_MASK(SIOCGIWAP) |
 6989 				IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
 6990 	range->event_capa[1] = IW_EVENT_CAPA_K_1;
 6991 	range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVTXDROP);
 6992 	return 0;
 6993 }
 6994 
 6995 /*------------------------------------------------------------------*/
 6996 /*
 6997  * Wireless Handler : set Power Management
 6998  */
 6999 static int airo_set_power(struct net_device *dev,
 7000 			  struct iw_request_info *info,
 7001 			  struct iw_param *vwrq,
 7002 			  char *extra)
 7003 {
 7004 	struct airo_info *local = dev->ml_priv;
 7005 
 7006 	readConfigRid(local, 1);
 7007 	if (vwrq->disabled) {
 7008 		if (sniffing_mode(local))
 7009 			return -EINVAL;
 7010 		local->config.powerSaveMode = POWERSAVE_CAM;
 7011 		local->config.rmode &= ~RXMODE_MASK;
 7012 		local->config.rmode |= RXMODE_BC_MC_ADDR;
 7013 		set_bit (FLAG_COMMIT, &local->flags);
 7014 		return -EINPROGRESS;		/* Call commit handler */
 7015 	}
 7016 	if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
 7017 		local->config.fastListenDelay = cpu_to_le16((vwrq->value + 500) / 1024);
 7018 		local->config.powerSaveMode = POWERSAVE_PSPCAM;
 7019 		set_bit (FLAG_COMMIT, &local->flags);
 7020 	} else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
 7021 		local->config.fastListenInterval =
 7022 		local->config.listenInterval =
 7023 			cpu_to_le16((vwrq->value + 500) / 1024);
 7024 		local->config.powerSaveMode = POWERSAVE_PSPCAM;
 7025 		set_bit (FLAG_COMMIT, &local->flags);
 7026 	}
 7027 	switch (vwrq->flags & IW_POWER_MODE) {
 7028 		case IW_POWER_UNICAST_R:
 7029 			if (sniffing_mode(local))
 7030 				return -EINVAL;
 7031 			local->config.rmode &= ~RXMODE_MASK;
 7032 			local->config.rmode |= RXMODE_ADDR;
 7033 			set_bit (FLAG_COMMIT, &local->flags);
 7034 			break;
 7035 		case IW_POWER_ALL_R:
 7036 			if (sniffing_mode(local))
 7037 				return -EINVAL;
 7038 			local->config.rmode &= ~RXMODE_MASK;
 7039 			local->config.rmode |= RXMODE_BC_MC_ADDR;
 7040 			set_bit (FLAG_COMMIT, &local->flags);
 7041 		case IW_POWER_ON:
 7042 			/* This is broken, fixme ;-) */
 7043 			break;
 7044 		default:
 7045 			return -EINVAL;
 7046 	}
 7047 	// Note : we may want to factor local->need_commit here
 7048 	// Note2 : may also want to factor RXMODE_RFMON test
 7049 	return -EINPROGRESS;		/* Call commit handler */
 7050 }
 7051 
 7052 /*------------------------------------------------------------------*/
 7053 /*
 7054  * Wireless Handler : get Power Management
 7055  */
 7056 static int airo_get_power(struct net_device *dev,
 7057 			  struct iw_request_info *info,
 7058 			  struct iw_param *vwrq,
 7059 			  char *extra)
 7060 {
 7061 	struct airo_info *local = dev->ml_priv;
 7062 	__le16 mode;
 7063 
 7064 	readConfigRid(local, 1);
 7065 	mode = local->config.powerSaveMode;
 7066 	if ((vwrq->disabled = (mode == POWERSAVE_CAM)))
 7067 		return 0;
 7068 	if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
 7069 		vwrq->value = le16_to_cpu(local->config.fastListenDelay) * 1024;
 7070 		vwrq->flags = IW_POWER_TIMEOUT;
 7071 	} else {
 7072 		vwrq->value = le16_to_cpu(local->config.fastListenInterval) * 1024;
 7073 		vwrq->flags = IW_POWER_PERIOD;
 7074 	}
 7075 	if ((local->config.rmode & RXMODE_MASK) == RXMODE_ADDR)
 7076 		vwrq->flags |= IW_POWER_UNICAST_R;
 7077 	else
 7078 		vwrq->flags |= IW_POWER_ALL_R;
 7079 
 7080 	return 0;
 7081 }
 7082 
 7083 /*------------------------------------------------------------------*/
 7084 /*
 7085  * Wireless Handler : set Sensitivity
 7086  */
 7087 static int airo_set_sens(struct net_device *dev,
 7088 			 struct iw_request_info *info,
 7089 			 struct iw_param *vwrq,
 7090 			 char *extra)
 7091 {
 7092 	struct airo_info *local = dev->ml_priv;
 7093 
 7094 	readConfigRid(local, 1);
 7095 	local->config.rssiThreshold =
 7096 		cpu_to_le16(vwrq->disabled ? RSSI_DEFAULT : vwrq->value);
 7097 	set_bit (FLAG_COMMIT, &local->flags);
 7098 
 7099 	return -EINPROGRESS;		/* Call commit handler */
 7100 }
 7101 
 7102 /*------------------------------------------------------------------*/
 7103 /*
 7104  * Wireless Handler : get Sensitivity
 7105  */
 7106 static int airo_get_sens(struct net_device *dev,
 7107 			 struct iw_request_info *info,
 7108 			 struct iw_param *vwrq,
 7109 			 char *extra)
 7110 {
 7111 	struct airo_info *local = dev->ml_priv;
 7112 
 7113 	readConfigRid(local, 1);
 7114 	vwrq->value = le16_to_cpu(local->config.rssiThreshold);
 7115 	vwrq->disabled = (vwrq->value == 0);
 7116 	vwrq->fixed = 1;
 7117 
 7118 	return 0;
 7119 }
 7120 
 7121 /*------------------------------------------------------------------*/
 7122 /*
 7123  * Wireless Handler : get AP List
 7124  * Note : this is deprecated in favor of IWSCAN
 7125  */
 7126 static int airo_get_aplist(struct net_device *dev,
 7127 			   struct iw_request_info *info,
 7128 			   struct iw_point *dwrq,
 7129 			   char *extra)
 7130 {
 7131 	struct airo_info *local = dev->ml_priv;
 7132 	struct sockaddr *address = (struct sockaddr *) extra;
 7133 	struct iw_quality *qual;
 7134 	BSSListRid BSSList;
 7135 	int i;
 7136 	int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
 7137 
 7138 	qual = kmalloc(IW_MAX_AP * sizeof(*qual), GFP_KERNEL);
 7139 	if (!qual)
 7140 		return -ENOMEM;
 7141 
 7142 	for (i = 0; i < IW_MAX_AP; i++) {
 7143 		u16 dBm;
 7144 		if (readBSSListRid(local, loseSync, &BSSList))
 7145 			break;
 7146 		loseSync = 0;
 7147 		memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN);
 7148 		address[i].sa_family = ARPHRD_ETHER;
 7149 		dBm = le16_to_cpu(BSSList.dBm);
 7150 		if (local->rssi) {
 7151 			qual[i].level = 0x100 - dBm;
 7152 			qual[i].qual = airo_dbm_to_pct(local->rssi, dBm);
 7153 			qual[i].updated = IW_QUAL_QUAL_UPDATED
 7154 					| IW_QUAL_LEVEL_UPDATED
 7155 					| IW_QUAL_DBM;
 7156 		} else {
 7157 			qual[i].level = (dBm + 321) / 2;
 7158 			qual[i].qual = 0;
 7159 			qual[i].updated = IW_QUAL_QUAL_INVALID
 7160 					| IW_QUAL_LEVEL_UPDATED
 7161 					| IW_QUAL_DBM;
 7162 		}
 7163 		qual[i].noise = local->wstats.qual.noise;
 7164 		if (BSSList.index == cpu_to_le16(0xffff))
 7165 			break;
 7166 	}
 7167 	if (!i) {
 7168 		StatusRid status_rid;		/* Card status info */
 7169 		readStatusRid(local, &status_rid, 1);
 7170 		for (i = 0;
 7171 		     i < min(IW_MAX_AP, 4) &&
 7172 			     (status_rid.bssid[i][0]
 7173 			      & status_rid.bssid[i][1]
 7174 			      & status_rid.bssid[i][2]
 7175 			      & status_rid.bssid[i][3]
 7176 			      & status_rid.bssid[i][4]
 7177 			      & status_rid.bssid[i][5])!=0xff &&
 7178 			     (status_rid.bssid[i][0]
 7179 			      | status_rid.bssid[i][1]
 7180 			      | status_rid.bssid[i][2]
 7181 			      | status_rid.bssid[i][3]
 7182 			      | status_rid.bssid[i][4]
 7183 			      | status_rid.bssid[i][5]);
 7184 		     i++) {
 7185 			memcpy(address[i].sa_data,
 7186 			       status_rid.bssid[i], ETH_ALEN);
 7187 			address[i].sa_family = ARPHRD_ETHER;
 7188 		}
 7189 	} else {
 7190 		dwrq->flags = 1; /* Should be define'd */
 7191 		memcpy(extra + sizeof(struct sockaddr) * i, qual,
 7192 		       sizeof(struct iw_quality) * i);
 7193 	}
 7194 	dwrq->length = i;
 7195 
 7196 	kfree(qual);
 7197 	return 0;
 7198 }
 7199 
 7200 /*------------------------------------------------------------------*/
 7201 /*
 7202  * Wireless Handler : Initiate Scan
 7203  */
 7204 static int airo_set_scan(struct net_device *dev,
 7205 			 struct iw_request_info *info,
 7206 			 struct iw_point *dwrq,
 7207 			 char *extra)
 7208 {
 7209 	struct airo_info *ai = dev->ml_priv;
 7210 	Cmd cmd;
 7211 	Resp rsp;
 7212 	int wake = 0;
 7213 	APListRid APList_rid_empty;
 7214 
 7215 	/* Note : you may have realised that, as this is a SET operation,
 7216 	 * this is privileged and therefore a normal user can't
 7217 	 * perform scanning.
 7218 	 * This is not an error, while the device perform scanning,
 7219 	 * traffic doesn't flow, so it's a perfect DoS...
 7220 	 * Jean II */
 7221 	if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
 7222 
 7223 	if (down_interruptible(&ai->sem))
 7224 		return -ERESTARTSYS;
 7225 
 7226 	/* If there's already a scan in progress, don't
 7227 	 * trigger another one. */
 7228 	if (ai->scan_timeout > 0)
 7229 		goto out;
 7230 
 7231 	/* Clear APList as it affects scan results */
 7232 	memset(&APList_rid_empty, 0, sizeof(APList_rid_empty));
 7233 	APList_rid_empty.len = cpu_to_le16(sizeof(APList_rid_empty));
 7234 	disable_MAC(ai, 2);
 7235 	writeAPListRid(ai, &APList_rid_empty, 0);
 7236 	enable_MAC(ai, 0);
 7237 
 7238 	/* Initiate a scan command */
 7239 	ai->scan_timeout = RUN_AT(3*HZ);
 7240 	memset(&cmd, 0, sizeof(cmd));
 7241 	cmd.cmd=CMD_LISTBSS;
 7242 	issuecommand(ai, &cmd, &rsp);
 7243 	wake = 1;
 7244 
 7245 out:
 7246 	up(&ai->sem);
 7247 	if (wake)
 7248 		wake_up_interruptible(&ai->thr_wait);
 7249 	return 0;
 7250 }
 7251 
 7252 /*------------------------------------------------------------------*/
 7253 /*
 7254  * Translate scan data returned from the card to a card independent
 7255  * format that the Wireless Tools will understand - Jean II
 7256  */
 7257 static inline char *airo_translate_scan(struct net_device *dev,
 7258 					struct iw_request_info *info,
 7259 					char *current_ev,
 7260 					char *end_buf,
 7261 					BSSListRid *bss)
 7262 {
 7263 	struct airo_info *ai = dev->ml_priv;
 7264 	struct iw_event		iwe;		/* Temporary buffer */
 7265 	__le16			capabilities;
 7266 	char *			current_val;	/* For rates */
 7267 	int			i;
 7268 	char *		buf;
 7269 	u16 dBm;
 7270 
 7271 	/* First entry *MUST* be the AP MAC address */
 7272 	iwe.cmd = SIOCGIWAP;
 7273 	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
 7274 	memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
 7275 	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
 7276 					  &iwe, IW_EV_ADDR_LEN);
 7277 
 7278 	/* Other entries will be displayed in the order we give them */
 7279 
 7280 	/* Add the ESSID */
 7281 	iwe.u.data.length = bss->ssidLen;
 7282 	if(iwe.u.data.length > 32)
 7283 		iwe.u.data.length = 32;
 7284 	iwe.cmd = SIOCGIWESSID;
 7285 	iwe.u.data.flags = 1;
 7286 	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
 7287 					  &iwe, bss->ssid);
 7288 
 7289 	/* Add mode */
 7290 	iwe.cmd = SIOCGIWMODE;
 7291 	capabilities = bss->cap;
 7292 	if(capabilities & (CAP_ESS | CAP_IBSS)) {
 7293 		if(capabilities & CAP_ESS)
 7294 			iwe.u.mode = IW_MODE_MASTER;
 7295 		else
 7296 			iwe.u.mode = IW_MODE_ADHOC;
 7297 		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
 7298 						  &iwe, IW_EV_UINT_LEN);
 7299 	}
 7300 
 7301 	/* Add frequency */
 7302 	iwe.cmd = SIOCGIWFREQ;
 7303 	iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
 7304 	iwe.u.freq.m = 100000 *
 7305 	      ieee80211_channel_to_frequency(iwe.u.freq.m, IEEE80211_BAND_2GHZ);
 7306 	iwe.u.freq.e = 1;
 7307 	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
 7308 					  &iwe, IW_EV_FREQ_LEN);
 7309 
 7310 	dBm = le16_to_cpu(bss->dBm);
 7311 
 7312 	/* Add quality statistics */
 7313 	iwe.cmd = IWEVQUAL;
 7314 	if (ai->rssi) {
 7315 		iwe.u.qual.level = 0x100 - dBm;
 7316 		iwe.u.qual.qual = airo_dbm_to_pct(ai->rssi, dBm);
 7317 		iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
 7318 				| IW_QUAL_LEVEL_UPDATED
 7319 				| IW_QUAL_DBM;
 7320 	} else {
 7321 		iwe.u.qual.level = (dBm + 321) / 2;
 7322 		iwe.u.qual.qual = 0;
 7323 		iwe.u.qual.updated = IW_QUAL_QUAL_INVALID
 7324 				| IW_QUAL_LEVEL_UPDATED
 7325 				| IW_QUAL_DBM;
 7326 	}
 7327 	iwe.u.qual.noise = ai->wstats.qual.noise;
 7328 	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
 7329 					  &iwe, IW_EV_QUAL_LEN);
 7330 
 7331 	/* Add encryption capability */
 7332 	iwe.cmd = SIOCGIWENCODE;
 7333 	if(capabilities & CAP_PRIVACY)
 7334 		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
 7335 	else
 7336 		iwe.u.data.flags = IW_ENCODE_DISABLED;
 7337 	iwe.u.data.length = 0;
 7338 	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
 7339 					  &iwe, bss->ssid);
 7340 
 7341 	/* Rate : stuffing multiple values in a single event require a bit
 7342 	 * more of magic - Jean II */
 7343 	current_val = current_ev + iwe_stream_lcp_len(info);
 7344 
 7345 	iwe.cmd = SIOCGIWRATE;
 7346 	/* Those two flags are ignored... */
 7347 	iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
 7348 	/* Max 8 values */
 7349 	for(i = 0 ; i < 8 ; i++) {
 7350 		/* NULL terminated */
 7351 		if(bss->rates[i] == 0)
 7352 			break;
 7353 		/* Bit rate given in 500 kb/s units (+ 0x80) */
 7354 		iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
 7355 		/* Add new value to event */
 7356 		current_val = iwe_stream_add_value(info, current_ev,
 7357 						   current_val, end_buf,
 7358 						   &iwe, IW_EV_PARAM_LEN);
 7359 	}
 7360 	/* Check if we added any event */
 7361 	if ((current_val - current_ev) > iwe_stream_lcp_len(info))
 7362 		current_ev = current_val;
 7363 
 7364 	/* Beacon interval */
 7365 	buf = kmalloc(30, GFP_KERNEL);
 7366 	if (buf) {
 7367 		iwe.cmd = IWEVCUSTOM;
 7368 		sprintf(buf, "bcn_int=%d", bss->beaconInterval);
 7369 		iwe.u.data.length = strlen(buf);
 7370 		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
 7371 						  &iwe, buf);
 7372 		kfree(buf);
 7373 	}
 7374 
 7375 	/* Put WPA/RSN Information Elements into the event stream */
 7376 	if (test_bit(FLAG_WPA_CAPABLE, &ai->flags)) {
 7377 		unsigned int num_null_ies = 0;
 7378 		u16 length = sizeof (bss->extra.iep);
 7379 		u8 *ie = (void *)&bss->extra.iep;
 7380 
 7381 		while ((length >= 2) && (num_null_ies < 2)) {
 7382 			if (2 + ie[1] > length) {
 7383 				/* Invalid element, don't continue parsing IE */
 7384 				break;
 7385 			}
 7386 
 7387 			switch (ie[0]) {
 7388 			case WLAN_EID_SSID:
 7389 				/* Two zero-length SSID elements
 7390 				 * mean we're done parsing elements */
 7391 				if (!ie[1])
 7392 					num_null_ies++;
 7393 				break;
 7394 
 7395 			case WLAN_EID_VENDOR_SPECIFIC:
 7396 				if (ie[1] >= 4 &&
 7397 				    ie[2] == 0x00 &&
 7398 				    ie[3] == 0x50 &&
 7399 				    ie[4] == 0xf2 &&
 7400 				    ie[5] == 0x01) {
 7401 					iwe.cmd = IWEVGENIE;
 7402 					/* 64 is an arbitrary cut-off */
 7403 					iwe.u.data.length = min(ie[1] + 2,
 7404 								64);
 7405 					current_ev = iwe_stream_add_point(
 7406 							info, current_ev,
 7407 							end_buf, &iwe, ie);
 7408 				}
 7409 				break;
 7410 
 7411 			case WLAN_EID_RSN:
 7412 				iwe.cmd = IWEVGENIE;
 7413 				/* 64 is an arbitrary cut-off */
 7414 				iwe.u.data.length = min(ie[1] + 2, 64);
 7415 				current_ev = iwe_stream_add_point(
 7416 					info, current_ev, end_buf,
 7417 					&iwe, ie);
 7418 				break;
 7419 
 7420 			default:
 7421 				break;
 7422 			}
 7423 
 7424 			length -= 2 + ie[1];
 7425 			ie += 2 + ie[1];
 7426 		}
 7427 	}
 7428 	return current_ev;
 7429 }
 7430 
 7431 /*------------------------------------------------------------------*/
 7432 /*
 7433  * Wireless Handler : Read Scan Results
 7434  */
 7435 static int airo_get_scan(struct net_device *dev,
 7436 			 struct iw_request_info *info,
 7437 			 struct iw_point *dwrq,
 7438 			 char *extra)
 7439 {
 7440 	struct airo_info *ai = dev->ml_priv;
 7441 	BSSListElement *net;
 7442 	int err = 0;
 7443 	char *current_ev = extra;
 7444 
 7445 	/* If a scan is in-progress, return -EAGAIN */
 7446 	if (ai->scan_timeout > 0)
 7447 		return -EAGAIN;
 7448 
 7449 	if (down_interruptible(&ai->sem))
 7450 		return -EAGAIN;
 7451 
 7452 	list_for_each_entry (net, &ai->network_list, list) {
 7453 		/* Translate to WE format this entry */
 7454 		current_ev = airo_translate_scan(dev, info, current_ev,
 7455 						 extra + dwrq->length,
 7456 						 &net->bss);
 7457 
 7458 		/* Check if there is space for one more entry */
 7459 		if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) {
 7460 			/* Ask user space to try again with a bigger buffer */
 7461 			err = -E2BIG;
 7462 			goto out;
 7463 		}
 7464 	}
 7465 
 7466 	/* Length of data */
 7467 	dwrq->length = (current_ev - extra);
 7468 	dwrq->flags = 0;	/* todo */
 7469 
 7470 out:
 7471 	up(&ai->sem);
 7472 	return err;
 7473 }
 7474 
 7475 /*------------------------------------------------------------------*/
 7476 /*
 7477  * Commit handler : called after a bunch of SET operations
 7478  */
 7479 static int airo_config_commit(struct net_device *dev,
 7480 			      struct iw_request_info *info,	/* NULL */
 7481 			      void *zwrq,			/* NULL */
 7482 			      char *extra)			/* NULL */
 7483 {
 7484 	struct airo_info *local = dev->ml_priv;
 7485 
 7486 	if (!test_bit (FLAG_COMMIT, &local->flags))
 7487 		return 0;
 7488 
 7489 	/* Some of the "SET" function may have modified some of the
 7490 	 * parameters. It's now time to commit them in the card */
 7491 	disable_MAC(local, 1);
 7492 	if (test_bit (FLAG_RESET, &local->flags)) {
 7493 		SsidRid SSID_rid;
 7494 
 7495 		readSsidRid(local, &SSID_rid);
 7496 		if (test_bit(FLAG_MPI,&local->flags))
 7497 			setup_card(local, dev->dev_addr, 1 );
 7498 		else
 7499 			reset_airo_card(dev);
 7500 		disable_MAC(local, 1);
 7501 		writeSsidRid(local, &SSID_rid, 1);
 7502 		writeAPListRid(local, &local->APList, 1);
 7503 	}
 7504 	if (down_interruptible(&local->sem))
 7505 		return -ERESTARTSYS;
 7506 	writeConfigRid(local, 0);
 7507 	enable_MAC(local, 0);
 7508 	if (test_bit (FLAG_RESET, &local->flags))
 7509 		airo_set_promisc(local);
 7510 	else
 7511 		up(&local->sem);
 7512 
 7513 	return 0;
 7514 }
 7515 
 7516 /*------------------------------------------------------------------*/
 7517 /*
 7518  * Structures to export the Wireless Handlers
 7519  */
 7520 
 7521 static const struct iw_priv_args airo_private_args[] = {
 7522 /*{ cmd,         set_args,                            get_args, name } */
 7523   { AIROIOCTL, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
 7524     IW_PRIV_TYPE_BYTE | 2047, "airoioctl" },
 7525   { AIROIDIFC, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
 7526     IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "airoidifc" },
 7527 };
 7528 
 7529 static const iw_handler		airo_handler[] =
 7530 {
 7531 	(iw_handler) airo_config_commit,	/* SIOCSIWCOMMIT */
 7532 	(iw_handler) airo_get_name,		/* SIOCGIWNAME */
 7533 	(iw_handler) NULL,			/* SIOCSIWNWID */
 7534 	(iw_handler) NULL,			/* SIOCGIWNWID */
 7535 	(iw_handler) airo_set_freq,		/* SIOCSIWFREQ */
 7536 	(iw_handler) airo_get_freq,		/* SIOCGIWFREQ */
 7537 	(iw_handler) airo_set_mode,		/* SIOCSIWMODE */
 7538 	(iw_handler) airo_get_mode,		/* SIOCGIWMODE */
 7539 	(iw_handler) airo_set_sens,		/* SIOCSIWSENS */
 7540 	(iw_handler) airo_get_sens,		/* SIOCGIWSENS */
 7541 	(iw_handler) NULL,			/* SIOCSIWRANGE */
 7542 	(iw_handler) airo_get_range,		/* SIOCGIWRANGE */
 7543 	(iw_handler) NULL,			/* SIOCSIWPRIV */
 7544 	(iw_handler) NULL,			/* SIOCGIWPRIV */
 7545 	(iw_handler) NULL,			/* SIOCSIWSTATS */
 7546 	(iw_handler) NULL,			/* SIOCGIWSTATS */
 7547 	iw_handler_set_spy,			/* SIOCSIWSPY */
 7548 	iw_handler_get_spy,			/* SIOCGIWSPY */
 7549 	iw_handler_set_thrspy,			/* SIOCSIWTHRSPY */
 7550 	iw_handler_get_thrspy,			/* SIOCGIWTHRSPY */
 7551 	(iw_handler) airo_set_wap,		/* SIOCSIWAP */
 7552 	(iw_handler) airo_get_wap,		/* SIOCGIWAP */
 7553 	(iw_handler) NULL,			/* -- hole -- */
 7554 	(iw_handler) airo_get_aplist,		/* SIOCGIWAPLIST */
 7555 	(iw_handler) airo_set_scan,		/* SIOCSIWSCAN */
 7556 	(iw_handler) airo_get_scan,		/* SIOCGIWSCAN */
 7557 	(iw_handler) airo_set_essid,		/* SIOCSIWESSID */
 7558 	(iw_handler) airo_get_essid,		/* SIOCGIWESSID */
 7559 	(iw_handler) airo_set_nick,		/* SIOCSIWNICKN */
 7560 	(iw_handler) airo_get_nick,		/* SIOCGIWNICKN */
 7561 	(iw_handler) NULL,			/* -- hole -- */
 7562 	(iw_handler) NULL,			/* -- hole -- */
 7563 	(iw_handler) airo_set_rate,		/* SIOCSIWRATE */
 7564 	(iw_handler) airo_get_rate,		/* SIOCGIWRATE */
 7565 	(iw_handler) airo_set_rts,		/* SIOCSIWRTS */
 7566 	(iw_handler) airo_get_rts,		/* SIOCGIWRTS */
 7567 	(iw_handler) airo_set_frag,		/* SIOCSIWFRAG */
 7568 	(iw_handler) airo_get_frag,		/* SIOCGIWFRAG */
 7569 	(iw_handler) airo_set_txpow,		/* SIOCSIWTXPOW */
 7570 	(iw_handler) airo_get_txpow,		/* SIOCGIWTXPOW */
 7571 	(iw_handler) airo_set_retry,		/* SIOCSIWRETRY */
 7572 	(iw_handler) airo_get_retry,		/* SIOCGIWRETRY */
 7573 	(iw_handler) airo_set_encode,		/* SIOCSIWENCODE */
 7574 	(iw_handler) airo_get_encode,		/* SIOCGIWENCODE */
 7575 	(iw_handler) airo_set_power,		/* SIOCSIWPOWER */
 7576 	(iw_handler) airo_get_power,		/* SIOCGIWPOWER */
 7577 	(iw_handler) NULL,			/* -- hole -- */
 7578 	(iw_handler) NULL,			/* -- hole -- */
 7579 	(iw_handler) NULL,			/* SIOCSIWGENIE */
 7580 	(iw_handler) NULL,			/* SIOCGIWGENIE */
 7581 	(iw_handler) airo_set_auth,		/* SIOCSIWAUTH */
 7582 	(iw_handler) airo_get_auth,		/* SIOCGIWAUTH */
 7583 	(iw_handler) airo_set_encodeext,	/* SIOCSIWENCODEEXT */
 7584 	(iw_handler) airo_get_encodeext,	/* SIOCGIWENCODEEXT */
 7585 	(iw_handler) NULL,			/* SIOCSIWPMKSA */
 7586 };
 7587 
 7588 /* Note : don't describe AIROIDIFC and AIROOLDIDIFC in here.
 7589  * We want to force the use of the ioctl code, because those can't be
 7590  * won't work the iw_handler code (because they simultaneously read
 7591  * and write data and iw_handler can't do that).
 7592  * Note that it's perfectly legal to read/write on a single ioctl command,
 7593  * you just can't use iwpriv and need to force it via the ioctl handler.
 7594  * Jean II */
 7595 static const iw_handler		airo_private_handler[] =
 7596 {
 7597 	NULL,				/* SIOCIWFIRSTPRIV */
 7598 };
 7599 
 7600 static const struct iw_handler_def	airo_handler_def =
 7601 {
 7602 	.num_standard	= ARRAY_SIZE(airo_handler),
 7603 	.num_private	= ARRAY_SIZE(airo_private_handler),
 7604 	.num_private_args = ARRAY_SIZE(airo_private_args),
 7605 	.standard	= airo_handler,
 7606 	.private	= airo_private_handler,
 7607 	.private_args	= airo_private_args,
 7608 	.get_wireless_stats = airo_get_wireless_stats,
 7609 };
 7610 
 7611 /*
 7612  * This defines the configuration part of the Wireless Extensions
 7613  * Note : irq and spinlock protection will occur in the subroutines
 7614  *
 7615  * TODO :
 7616  *	o Check input value more carefully and fill correct values in range
 7617  *	o Test and shakeout the bugs (if any)
 7618  *
 7619  * Jean II
 7620  *
 7621  * Javier Achirica did a great job of merging code from the unnamed CISCO
 7622  * developer that added support for flashing the card.
 7623  */
 7624 static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 7625 {
 7626 	int rc = 0;
 7627 	struct airo_info *ai = dev->ml_priv;
 7628 
 7629 	if (ai->power.event)
 7630 		return 0;
 7631 
 7632 	switch (cmd) {
 7633 #ifdef CISCO_EXT
 7634 	case AIROIDIFC:
 7635 #ifdef AIROOLDIDIFC
 7636 	case AIROOLDIDIFC:
 7637 #endif
 7638 	{
 7639 		int val = AIROMAGIC;
 7640 		aironet_ioctl com;
 7641 		if (copy_from_user(&com,rq->ifr_data,sizeof(com)))
 7642 			rc = -EFAULT;
 7643 		else if (copy_to_user(com.data,(char *)&val,sizeof(val)))
 7644 			rc = -EFAULT;
 7645 	}
 7646 	break;
 7647 
 7648 	case AIROIOCTL:
 7649 #ifdef AIROOLDIOCTL
 7650 	case AIROOLDIOCTL:
 7651 #endif
 7652 		/* Get the command struct and hand it off for evaluation by
 7653 		 * the proper subfunction
 7654 		 */
 7655 	{
 7656 		aironet_ioctl com;
 7657 		if (copy_from_user(&com,rq->ifr_data,sizeof(com))) {
 7658 			rc = -EFAULT;
 7659 			break;
 7660 		}
 7661 
 7662 		/* Separate R/W functions bracket legality here
 7663 		 */
 7664 		if ( com.command == AIRORSWVERSION ) {
 7665 			if (copy_to_user(com.data, swversion, sizeof(swversion)))
 7666 				rc = -EFAULT;
 7667 			else
 7668 				rc = 0;
 7669 		}
 7670 		else if ( com.command <= AIRORRID)
 7671 			rc = readrids(dev,&com);
 7672 		else if ( com.command >= AIROPCAP && com.command <= (AIROPLEAPUSR+2) )
 7673 			rc = writerids(dev,&com);
 7674 		else if ( com.command >= AIROFLSHRST && com.command <= AIRORESTART )
 7675 			rc = flashcard(dev,&com);
 7676 		else
 7677 			rc = -EINVAL;      /* Bad command in ioctl */
 7678 	}
 7679 	break;
 7680 #endif /* CISCO_EXT */
 7681 
 7682 	// All other calls are currently unsupported
 7683 	default:
 7684 		rc = -EOPNOTSUPP;
 7685 	}
 7686 	return rc;
 7687 }
 7688 
 7689 /*
 7690  * Get the Wireless stats out of the driver
 7691  * Note : irq and spinlock protection will occur in the subroutines
 7692  *
 7693  * TODO :
 7694  *	o Check if work in Ad-Hoc mode (otherwise, use SPY, as in wvlan_cs)
 7695  *
 7696  * Jean
 7697  */
 7698 static void airo_read_wireless_stats(struct airo_info *local)
 7699 {
 7700 	StatusRid status_rid;
 7701 	StatsRid stats_rid;
 7702 	CapabilityRid cap_rid;
 7703 	__le32 *vals = stats_rid.vals;
 7704 
 7705 	/* Get stats out of the card */
 7706 	clear_bit(JOB_WSTATS, &local->jobs);
 7707 	if (local->power.event) {
 7708 		up(&local->sem);
 7709 		return;
 7710 	}
 7711 	readCapabilityRid(local, &cap_rid, 0);
 7712 	readStatusRid(local, &status_rid, 0);
 7713 	readStatsRid(local, &stats_rid, RID_STATS, 0);
 7714 	up(&local->sem);
 7715 
 7716 	/* The status */
 7717 	local->wstats.status = le16_to_cpu(status_rid.mode);
 7718 
 7719 	/* Signal quality and co */
 7720 	if (local->rssi) {
 7721 		local->wstats.qual.level =
 7722 			airo_rssi_to_dbm(local->rssi,
 7723 					 le16_to_cpu(status_rid.sigQuality));
 7724 		/* normalizedSignalStrength appears to be a percentage */
 7725 		local->wstats.qual.qual =
 7726 			le16_to_cpu(status_rid.normalizedSignalStrength);
 7727 	} else {
 7728 		local->wstats.qual.level =
 7729 			(le16_to_cpu(status_rid.normalizedSignalStrength) + 321) / 2;
 7730 		local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid);
 7731 	}
 7732 	if (le16_to_cpu(status_rid.len) >= 124) {
 7733 		local->wstats.qual.noise = 0x100 - status_rid.noisedBm;
 7734 		local->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
 7735 	} else {
 7736 		local->wstats.qual.noise = 0;
 7737 		local->wstats.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID | IW_QUAL_DBM;
 7738 	}
 7739 
 7740 	/* Packets discarded in the wireless adapter due to wireless
 7741 	 * specific problems */
 7742 	local->wstats.discard.nwid = le32_to_cpu(vals[56]) +
 7743 				     le32_to_cpu(vals[57]) +
 7744 				     le32_to_cpu(vals[58]); /* SSID Mismatch */
 7745 	local->wstats.discard.code = le32_to_cpu(vals[6]);/* RxWepErr */
 7746 	local->wstats.discard.fragment = le32_to_cpu(vals[30]);
 7747 	local->wstats.discard.retries = le32_to_cpu(vals[10]);
 7748 	local->wstats.discard.misc = le32_to_cpu(vals[1]) +
 7749 				     le32_to_cpu(vals[32]);
 7750 	local->wstats.miss.beacon = le32_to_cpu(vals[34]);
 7751 }
 7752 
 7753 static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
 7754 {
 7755 	struct airo_info *local =  dev->ml_priv;
 7756 
 7757 	if (!test_bit(JOB_WSTATS, &local->jobs)) {
 7758 		/* Get stats out of the card if available */
 7759 		if (down_trylock(&local->sem) != 0) {
 7760 			set_bit(JOB_WSTATS, &local->jobs);
 7761 			wake_up_interruptible(&local->thr_wait);
 7762 		} else
 7763 			airo_read_wireless_stats(local);
 7764 	}
 7765 
 7766 	return &local->wstats;
 7767 }
 7768 
 7769 #ifdef CISCO_EXT
 7770 /*
 7771  * This just translates from driver IOCTL codes to the command codes to
 7772  * feed to the radio's host interface. Things can be added/deleted
 7773  * as needed.  This represents the READ side of control I/O to
 7774  * the card
 7775  */
 7776 static int readrids(struct net_device *dev, aironet_ioctl *comp) {
 7777 	unsigned short ridcode;
 7778 	unsigned char *iobuf;
 7779 	int len;
 7780 	struct airo_info *ai = dev->ml_priv;
 7781 
 7782 	if (test_bit(FLAG_FLASHING, &ai->flags))
 7783 		return -EIO;
 7784 
 7785 	switch(comp->command)
 7786 	{
 7787 	case AIROGCAP:      ridcode = RID_CAPABILITIES; break;
 7788 	case AIROGCFG:      ridcode = RID_CONFIG;
 7789 		if (test_bit(FLAG_COMMIT, &ai->flags)) {
 7790 			disable_MAC (ai, 1);
 7791 			writeConfigRid (ai, 1);
 7792 			enable_MAC(ai, 1);
 7793 		}
 7794 		break;
 7795 	case AIROGSLIST:    ridcode = RID_SSID;         break;
 7796 	case AIROGVLIST:    ridcode = RID_APLIST;       break;
 7797 	case AIROGDRVNAM:   ridcode = RID_DRVNAME;      break;
 7798 	case AIROGEHTENC:   ridcode = RID_ETHERENCAP;   break;
 7799 	case AIROGWEPKTMP:  ridcode = RID_WEP_TEMP;
 7800 		/* Only super-user can read WEP keys */
 7801 		if (!capable(CAP_NET_ADMIN))
 7802 			return -EPERM;
 7803 		break;
 7804 	case AIROGWEPKNV:   ridcode = RID_WEP_PERM;
 7805 		/* Only super-user can read WEP keys */
 7806 		if (!capable(CAP_NET_ADMIN))
 7807 			return -EPERM;
 7808 		break;
 7809 	case AIROGSTAT:     ridcode = RID_STATUS;       break;
 7810 	case AIROGSTATSD32: ridcode = RID_STATSDELTA;   break;
 7811 	case AIROGSTATSC32: ridcode = RID_STATS;        break;
 7812 	case AIROGMICSTATS:
 7813 		if (copy_to_user(comp->data, &ai->micstats,
 7814 				 min((int)comp->len,(int)sizeof(ai->micstats))))
 7815 			return -EFAULT;
 7816 		return 0;
 7817 	case AIRORRID:      ridcode = comp->ridnum;     break;
 7818 	default:
 7819 		return -EINVAL;
 7820 	}
 7821 
 7822 	if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
 7823 		return -ENOMEM;
 7824 
 7825 	PC4500_readrid(ai,ridcode,iobuf,RIDSIZE, 1);
 7826 	/* get the count of bytes in the rid  docs say 1st 2 bytes is it.
 7827 	 * then return it to the user
 7828 	 * 9/22/2000 Honor user given length
 7829 	 */
 7830 	len = comp->len;
 7831 
 7832 	if (copy_to_user(comp->data, iobuf, min(len, (int)RIDSIZE))) {
 7833 		kfree (iobuf);
 7834 		return -EFAULT;
 7835 	}
 7836 	kfree (iobuf);
 7837 	return 0;
 7838 }
 7839 
 7840 /*
 7841  * Danger Will Robinson write the rids here
 7842  */
 7843 
 7844 static int writerids(struct net_device *dev, aironet_ioctl *comp) {
 7845 	struct airo_info *ai = dev->ml_priv;
 7846 	int  ridcode;
 7847         int  enabled;
 7848 	static int (* writer)(struct airo_info *, u16 rid, const void *, int, int);
 7849 	unsigned char *iobuf;
 7850 
 7851 	/* Only super-user can write RIDs */
 7852 	if (!capable(CAP_NET_ADMIN))
 7853 		return -EPERM;
 7854 
 7855 	if (test_bit(FLAG_FLASHING, &ai->flags))
 7856 		return -EIO;
 7857 
 7858 	ridcode = 0;
 7859 	writer = do_writerid;
 7860 
 7861 	switch(comp->command)
 7862 	{
 7863 	case AIROPSIDS:     ridcode = RID_SSID;         break;
 7864 	case AIROPCAP:      ridcode = RID_CAPABILITIES; break;
 7865 	case AIROPAPLIST:   ridcode = RID_APLIST;       break;
 7866 	case AIROPCFG: ai->config.len = 0;
 7867 			    clear_bit(FLAG_COMMIT, &ai->flags);
 7868 			    ridcode = RID_CONFIG;       break;
 7869 	case AIROPWEPKEYNV: ridcode = RID_WEP_PERM;     break;
 7870 	case AIROPLEAPUSR:  ridcode = RID_LEAPUSERNAME; break;
 7871 	case AIROPLEAPPWD:  ridcode = RID_LEAPPASSWORD; break;
 7872 	case AIROPWEPKEY:   ridcode = RID_WEP_TEMP; writer = PC4500_writerid;
 7873 		break;
 7874 	case AIROPLEAPUSR+1: ridcode = 0xFF2A;          break;
 7875 	case AIROPLEAPUSR+2: ridcode = 0xFF2B;          break;
 7876 
 7877 		/* this is not really a rid but a command given to the card
 7878 		 * same with MAC off
 7879 		 */
 7880 	case AIROPMACON:
 7881 		if (enable_MAC(ai, 1) != 0)
 7882 			return -EIO;
 7883 		return 0;
 7884 
 7885 		/*
 7886 		 * Evidently this code in the airo driver does not get a symbol
 7887 		 * as disable_MAC. it's probably so short the compiler does not gen one.
 7888 		 */
 7889 	case AIROPMACOFF:
 7890 		disable_MAC(ai, 1);
 7891 		return 0;
 7892 
 7893 		/* This command merely clears the counts does not actually store any data
 7894 		 * only reads rid. But as it changes the cards state, I put it in the
 7895 		 * writerid routines.
 7896 		 */
 7897 	case AIROPSTCLR:
 7898 		if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
 7899 			return -ENOMEM;
 7900 
 7901 		PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDSIZE, 1);
 7902 
 7903 		enabled = ai->micstats.enabled;
 7904 		memset(&ai->micstats,0,sizeof(ai->micstats));
 7905 		ai->micstats.enabled = enabled;
 7906 
 7907 		if (copy_to_user(comp->data, iobuf,
 7908 				 min((int)comp->len, (int)RIDSIZE))) {
 7909 			kfree (iobuf);
 7910 			return -EFAULT;
 7911 		}
 7912 		kfree (iobuf);
 7913 		return 0;
 7914 
 7915 	default:
 7916 		return -EOPNOTSUPP;	/* Blarg! */
 7917 	}
 7918 	if(comp->len > RIDSIZE)
 7919 		return -EINVAL;
 7920 
 7921 	if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
 7922 		return -ENOMEM;
 7923 
 7924 	if (copy_from_user(iobuf,comp->data,comp->len)) {
 7925 		kfree (iobuf);
 7926 		return -EFAULT;
 7927 	}
 7928 
 7929 	if (comp->command == AIROPCFG) {
 7930 		ConfigRid *cfg = (ConfigRid *)iobuf;
 7931 
 7932 		if (test_bit(FLAG_MIC_CAPABLE, &ai->flags))
 7933 			cfg->opmode |= MODE_MIC;
 7934 
 7935 		if ((cfg->opmode & MODE_CFG_MASK) == MODE_STA_IBSS)
 7936 			set_bit (FLAG_ADHOC, &ai->flags);
 7937 		else
 7938 			clear_bit (FLAG_ADHOC, &ai->flags);
 7939 	}
 7940 
 7941 	if((*writer)(ai, ridcode, iobuf,comp->len,1)) {
 7942 		kfree (iobuf);
 7943 		return -EIO;
 7944 	}
 7945 	kfree (iobuf);
 7946 	return 0;
 7947 }
 7948 
 7949 /*****************************************************************************
 7950  * Ancillary flash / mod functions much black magic lurkes here              *
 7951  *****************************************************************************
 7952  */
 7953 
 7954 /*
 7955  * Flash command switch table
 7956  */
 7957 
 7958 static int flashcard(struct net_device *dev, aironet_ioctl *comp) {
 7959 	int z;
 7960 
 7961 	/* Only super-user can modify flash */
 7962 	if (!capable(CAP_NET_ADMIN))
 7963 		return -EPERM;
 7964 
 7965 	switch(comp->command)
 7966 	{
 7967 	case AIROFLSHRST:
 7968 		return cmdreset((struct airo_info *)dev->ml_priv);
 7969 
 7970 	case AIROFLSHSTFL:
 7971 		if (!AIRO_FLASH(dev) &&
 7972 		    (AIRO_FLASH(dev) = kmalloc(FLASHSIZE, GFP_KERNEL)) == NULL)
 7973 			return -ENOMEM;
 7974 		return setflashmode((struct airo_info *)dev->ml_priv);
 7975 
 7976 	case AIROFLSHGCHR: /* Get char from aux */
 7977 		if(comp->len != sizeof(int))
 7978 			return -EINVAL;
 7979 		if (copy_from_user(&z,comp->data,comp->len))
 7980 			return -EFAULT;
 7981 		return flashgchar((struct airo_info *)dev->ml_priv, z, 8000);
 7982 
 7983 	case AIROFLSHPCHR: /* Send char to card. */
 7984 		if(comp->len != sizeof(int))
 7985 			return -EINVAL;
 7986 		if (copy_from_user(&z,comp->data,comp->len))
 7987 			return -EFAULT;
 7988 		return flashpchar((struct airo_info *)dev->ml_priv, z, 8000);
 7989 
 7990 	case AIROFLPUTBUF: /* Send 32k to card */
 7991 		if (!AIRO_FLASH(dev))
 7992 			return -ENOMEM;
 7993 		if(comp->len > FLASHSIZE)
 7994 			return -EINVAL;
 7995 		if (copy_from_user(AIRO_FLASH(dev), comp->data, comp->len))
 7996 			return -EFAULT;
 7997 
 7998 		flashputbuf((struct airo_info *)dev->ml_priv);
 7999 		return 0;
 8000 
 8001 	case AIRORESTART:
 8002 		if (flashrestart((struct airo_info *)dev->ml_priv, dev))
 8003 			return -EIO;
 8004 		return 0;
 8005 	}
 8006 	return -EINVAL;
 8007 }
 8008 
 8009 #define FLASH_COMMAND  0x7e7e
 8010 
 8011 /*
 8012  * STEP 1)
 8013  * Disable MAC and do soft reset on
 8014  * card.
 8015  */
 8016 
 8017 static int cmdreset(struct airo_info *ai) {
 8018 	disable_MAC(ai, 1);
 8019 
 8020 	if(!waitbusy (ai)){
 8021 		airo_print_info(ai->dev->name, "Waitbusy hang before RESET");
 8022 		return -EBUSY;
 8023 	}
 8024 
 8025 	OUT4500(ai,COMMAND,CMD_SOFTRESET);
 8026 
 8027 	ssleep(1);			/* WAS 600 12/7/00 */
 8028 
 8029 	if(!waitbusy (ai)){
 8030 		airo_print_info(ai->dev->name, "Waitbusy hang AFTER RESET");
 8031 		return -EBUSY;
 8032 	}
 8033 	return 0;
 8034 }
 8035 
 8036 /* STEP 2)
 8037  * Put the card in legendary flash
 8038  * mode
 8039  */
 8040 
 8041 static int setflashmode (struct airo_info *ai) {
 8042 	set_bit (FLAG_FLASHING, &ai->flags);
 8043 
 8044 	OUT4500(ai, SWS0, FLASH_COMMAND);
 8045 	OUT4500(ai, SWS1, FLASH_COMMAND);
 8046 	if (probe) {
 8047 		OUT4500(ai, SWS0, FLASH_COMMAND);
 8048 		OUT4500(ai, COMMAND,0x10);
 8049 	} else {
 8050 		OUT4500(ai, SWS2, FLASH_COMMAND);
 8051 		OUT4500(ai, SWS3, FLASH_COMMAND);
 8052 		OUT4500(ai, COMMAND,0);
 8053 	}
 8054 	msleep(500);		/* 500ms delay */
 8055 
 8056 	if(!waitbusy(ai)) {
 8057 		clear_bit (FLAG_FLASHING, &ai->flags);
 8058 		airo_print_info(ai->dev->name, "Waitbusy hang after setflash mode");
 8059 		return -EIO;
 8060 	}
 8061 	return 0;
 8062 }
 8063 
 8064 /* Put character to SWS0 wait for dwelltime
 8065  * x 50us for  echo .
 8066  */
 8067 
 8068 static int flashpchar(struct airo_info *ai,int byte,int dwelltime) {
 8069 	int echo;
 8070 	int waittime;
 8071 
 8072 	byte |= 0x8000;
 8073 
 8074 	if(dwelltime == 0 )
 8075 		dwelltime = 200;
 8076 
 8077 	waittime=dwelltime;
 8078 
 8079 	/* Wait for busy bit d15 to go false indicating buffer empty */
 8080 	while ((IN4500 (ai, SWS0) & 0x8000) && waittime > 0) {
 8081 		udelay (50);
 8082 		waittime -= 50;
 8083 	}
 8084 
 8085 	/* timeout for busy clear wait */
 8086 	if(waittime <= 0 ){
 8087 		airo_print_info(ai->dev->name, "flash putchar busywait timeout!");
 8088 		return -EBUSY;
 8089 	}
 8090 
 8091 	/* Port is clear now write byte and wait for it to echo back */
 8092 	do {
 8093 		OUT4500(ai,SWS0,byte);
 8094 		udelay(50);
 8095 		dwelltime -= 50;
 8096 		echo = IN4500(ai,SWS1);
 8097 	} while (dwelltime >= 0 && echo != byte);
 8098 
 8099 	OUT4500(ai,SWS1,0);
 8100 
 8101 	return (echo == byte) ? 0 : -EIO;
 8102 }
 8103 
 8104 /*
 8105  * Get a character from the card matching matchbyte
 8106  * Step 3)
 8107  */
 8108 static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){
 8109 	int           rchar;
 8110 	unsigned char rbyte=0;
 8111 
 8112 	do {
 8113 		rchar = IN4500(ai,SWS1);
 8114 
 8115 		if(dwelltime && !(0x8000 & rchar)){
 8116 			dwelltime -= 10;
 8117 			mdelay(10);
 8118 			continue;
 8119 		}
 8120 		rbyte = 0xff & rchar;
 8121 
 8122 		if( (rbyte == matchbyte) && (0x8000 & rchar) ){
 8123 			OUT4500(ai,SWS1,0);
 8124 			return 0;
 8125 		}
 8126 		if( rbyte == 0x81 || rbyte == 0x82 || rbyte == 0x83 || rbyte == 0x1a || 0xffff == rchar)
 8127 			break;
 8128 		OUT4500(ai,SWS1,0);
 8129 
 8130 	}while(dwelltime > 0);
 8131 	return -EIO;
 8132 }
 8133 
 8134 /*
 8135  * Transfer 32k of firmware data from user buffer to our buffer and
 8136  * send to the card
 8137  */
 8138 
 8139 static int flashputbuf(struct airo_info *ai){
 8140 	int            nwords;
 8141 
 8142 	/* Write stuff */
 8143 	if (test_bit(FLAG_MPI,&ai->flags))
 8144 		memcpy_toio(ai->pciaux + 0x8000, ai->flash, FLASHSIZE);
 8145 	else {
 8146 		OUT4500(ai,AUXPAGE,0x100);
 8147 		OUT4500(ai,AUXOFF,0);
 8148 
 8149 		for(nwords=0;nwords != FLASHSIZE / 2;nwords++){
 8150 			OUT4500(ai,AUXDATA,ai->flash[nwords] & 0xffff);
 8151 		}
 8152 	}
 8153 	OUT4500(ai,SWS0,0x8000);
 8154 
 8155 	return 0;
 8156 }
 8157 
 8158 /*
 8159  *
 8160  */
 8161 static int flashrestart(struct airo_info *ai,struct net_device *dev){
 8162 	int    i,status;
 8163 
 8164 	ssleep(1);			/* Added 12/7/00 */
 8165 	clear_bit (FLAG_FLASHING, &ai->flags);
 8166 	if (test_bit(FLAG_MPI, &ai->flags)) {
 8167 		status = mpi_init_descriptors(ai);
 8168 		if (status != SUCCESS)
 8169 			return status;
 8170 	}
 8171 	status = setup_card(ai, dev->dev_addr, 1);
 8172 
 8173 	if (!test_bit(FLAG_MPI,&ai->flags))
 8174 		for( i = 0; i < MAX_FIDS; i++ ) {
 8175 			ai->fids[i] = transmit_allocate
 8176 				( ai, AIRO_DEF_MTU, i >= MAX_FIDS / 2 );
 8177 		}
 8178 
 8179 	ssleep(1);			/* Added 12/7/00 */
 8180 	return status;
 8181 }
 8182 #endif /* CISCO_EXT */
 8183 
 8184 /*
 8185     This program is free software; you can redistribute it and/or
 8186     modify it under the terms of the GNU General Public License
 8187     as published by the Free Software Foundation; either version 2
 8188     of the License, or (at your option) any later version.
 8189 
 8190     This program is distributed in the hope that it will be useful,
 8191     but WITHOUT ANY WARRANTY; without even the implied warranty of
 8192     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 8193     GNU General Public License for more details.
 8194 
 8195     In addition:
 8196 
 8197     Redistribution and use in source and binary forms, with or without
 8198     modification, are permitted provided that the following conditions
 8199     are met:
 8200 
 8201     1. Redistributions of source code must retain the above copyright
 8202        notice, this list of conditions and the following disclaimer.
 8203     2. Redistributions in binary form must reproduce the above copyright
 8204        notice, this list of conditions and the following disclaimer in the
 8205        documentation and/or other materials provided with the distribution.
 8206     3. The name of the author may not be used to endorse or promote
 8207        products derived from this software without specific prior written
 8208        permission.
 8209 
 8210     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 8211     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 8212     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 8213     ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 8214     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 8215     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 8216     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 8217     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 8218     STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 8219     IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 8220     POSSIBILITY OF SUCH DAMAGE.
 8221 */
 8222 
 8223 module_init(airo_init_module);
 8224 module_exit(airo_cleanup_module);                 1 
    2 #include <linux/kernel.h>
    3 #include <linux/mutex.h>
    4 #include <linux/spinlock.h>
    5 #include <linux/errno.h>
    6 #include <verifier/rcv.h>
    7 #include <linux/list.h>
    8 
    9 /* mutexes */
   10 extern int mutex_lock_interruptible(struct mutex *lock);
   11 extern int mutex_lock_killable(struct mutex *lock);
   12 extern void mutex_lock(struct mutex *lock);
   13 
   14 /* mutex model functions */
   15 extern void ldv_mutex_lock(struct mutex *lock, char *sign);
   16 extern int ldv_mutex_is_locked(struct mutex *lock, char *sign);
   17 extern void ldv_mutex_unlock(struct mutex *lock, char *sign);
   18 
   19 
   20 /* Spin locks */
   21 extern void __ldv_spin_lock(spinlock_t *lock);
   22 extern void __ldv_spin_unlock(spinlock_t *lock);
   23 extern int __ldv_spin_trylock(spinlock_t *lock);
   24 extern void __ldv_spin_unlock_wait(spinlock_t *lock);
   25 extern void __ldv_spin_can_lock(spinlock_t *lock);
   26 extern int __ldv_atomic_dec_and_lock(spinlock_t *lock);
   27 
   28 /* spin model functions */
   29 extern void ldv_spin_lock(spinlock_t *lock, char *sign);
   30 extern void ldv_spin_unlock(spinlock_t *lock, char *sign);
   31 extern int ldv_spin_is_locked(spinlock_t *lock, char *sign);
   32 
   33 /* Support for list binder functions */
   34 static inline struct list_head *ldv_list_get_first(struct list_head *head) {
   35   return head->next;
   36 }
   37 
   38 static inline int ldv_list_is_stop(struct list_head *pos, struct list_head *head) {
   39   return pos==head;
   40 }
   41 
   42 static inline struct list_head *ldv_list_get_next(struct list_head *pos) {
   43   return pos->next;
   44 }
   45 
   46 #include <linux/mutex.h>
   47 #include <linux/slab.h>
   48 #include <linux/irqreturn.h>
   49 #include <verifier/rcv.h>
   50 #include <linux/rtnetlink.h>
   51 #include <linux/gfp.h>
   52 int ldv_state_variable_8;
   53 struct pci_dev *airo_driver_group1;
   54 int ldv_state_variable_15;
   55 int pci_counter;
   56 struct inode *proc_stats_ops_group1;
   57 int ldv_state_variable_0;
   58 int ldv_state_variable_5;
   59 int ldv_state_variable_13;
   60 int ldv_state_variable_12;
   61 int ldv_state_variable_14;
   62 struct net_device *airo11_netdev_ops_group1;
   63 int ldv_state_variable_9;
   64 int ref_cnt;
   65 int ldv_irq_line_1_1;
   66 int ldv_state_variable_1;
   67 int ldv_state_variable_7;
   68 int ldv_irq_line_1_2;
   69 struct file *proc_BSSList_ops_group2;
   70 struct inode *proc_SSID_ops_group1;
   71 struct file *proc_statsdelta_ops_group2;
   72 int ldv_irq_1_3=0;
   73 void* ldv_irq_data_1_1;
   74 int ldv_state_variable_10;
   75 int ldv_irq_1_0=0;
   76 void* ldv_irq_data_1_0;
   77 int ldv_state_variable_6;
   78 struct inode *proc_status_ops_group1;
   79 void* ldv_irq_data_1_3;
   80 int ldv_state_variable_2;
   81 void* ldv_irq_data_1_2;
   82 struct net_device *airo_handler_def_group1;
   83 struct net_device *mpi_netdev_ops_group1;
   84 struct inode *proc_BSSList_ops_group1;
   85 struct inode *proc_APList_ops_group1;
   86 struct inode *proc_statsdelta_ops_group1;
   87 struct file *proc_stats_ops_group2;
   88 int ldv_state_variable_11;
   89 int ldv_irq_1_2=0;
   90 int LDV_IN_INTERRUPT = 1;
   91 struct file *proc_APList_ops_group2;
   92 struct file *proc_config_ops_group2;
   93 int ldv_irq_1_1=0;
   94 int __VERIFIER_nondet_int(void);
   95 struct file *proc_SSID_ops_group2;
   96 struct file *proc_status_ops_group2;
   97 struct inode *proc_wepkey_ops_group1;
   98 int ldv_irq_line_1_3;
   99 struct mutex fs_mutex;
  100 struct inode *proc_config_ops_group1;
  101 int ldv_state_variable_3;
  102 int ldv_irq_line_1_0;
  103 struct mutex ar_mutex;
  104 struct file *proc_wepkey_ops_group2;
  105 int ldv_state_variable_4;
  106 struct net_device *airo_netdev_ops_group1;
  107 void ldv_file_operations_7(void);
  108 void ldv_file_operations_6(void);
  109 int evil_hack_13(void);
  110 int reg_check_1(irqreturn_t (*handler)(int, void *));
  111 void ldv_pci_driver_15(void);
  112 void ldv_file_operations_10(void);
  113 int evil_hack_12(void);
  114 void ldv_net_device_ops_11(void);
  115 void choose_interrupt_1(void);
  116 int evil_hack_11(void);
  117 void ldv_file_operations_9(void);
  118 void ldv_file_operations_3(void);
  119 void ldv_file_operations_8(void);
  120 void disable_suitable_irq_1(int line, void * data);
  121 int ldv_irq_1(int state, int line, void *data);
  122 void activate_suitable_irq_1(int line, void * data);
  123 int evil_hack_fs_lock(void);
  124 int __VERIFIER_nondet_int(void);
  125 int evil_hack_2(void);
  126 void ldv_file_operations_5(void);
  127 void ldv_net_device_ops_13(void);
  128 void ldv_net_device_ops_12(void);
  129 int evil_hack_ar_lock(void);
  130 void ldv_file_operations_4(void);
  131 #line 1 "/work/ldvuser/andrianov/work/current--X--drivers/net/wireless/--X--defaultlinux-4.5-rc7--X--races--X--cpachecker/linux-4.5-rc7/csd_deg_dscv/833/dscv_tempdir/dscv/ri/races/drivers/net/wireless/cisco/airo.c"
  132 /*======================================================================
  133 
  134     Aironet driver for 4500 and 4800 series cards
  135 
  136     This code is released under both the GPL version 2 and BSD licenses.
  137     Either license may be used.  The respective licenses are found at
  138     the end of this file.
  139 
  140     This code was developed by Benjamin Reed <breed@users.sourceforge.net>
  141     including portions of which come from the Aironet PC4500
  142     Developer's Reference Manual and used with permission.  Copyright
  143     (C) 1999 Benjamin Reed.  All Rights Reserved.  Permission to use
  144     code in the Developer's manual was granted for this driver by
  145     Aironet.  Major code contributions were received from Javier Achirica
  146     <achirica@users.sourceforge.net> and Jean Tourrilhes <jt@hpl.hp.com>.
  147     Code was also integrated from the Cisco Aironet driver for Linux.
  148     Support for MPI350 cards was added by Fabrice Bellet
  149     <fabrice@bellet.info>.
  150 
  151 ======================================================================*/
  152 
  153 #include <linux/err.h>
  154 #include <linux/init.h>
  155 
  156 #include <linux/kernel.h>
  157 #include <linux/module.h>
  158 #include <linux/proc_fs.h>
  159 
  160 #include <linux/sched.h>
  161 #include <linux/ptrace.h>
  162 #include <linux/slab.h>
  163 #include <linux/string.h>
  164 #include <linux/timer.h>
  165 #include <linux/interrupt.h>
  166 #include <linux/in.h>
  167 #include <linux/bitops.h>
  168 #include <linux/scatterlist.h>
  169 #include <linux/crypto.h>
  170 #include <linux/io.h>
  171 #include <asm/unaligned.h>
  172 
  173 #include <linux/netdevice.h>
  174 #include <linux/etherdevice.h>
  175 #include <linux/skbuff.h>
  176 #include <linux/if_arp.h>
  177 #include <linux/ioport.h>
  178 #include <linux/pci.h>
  179 #include <linux/uaccess.h>
  180 #include <linux/kthread.h>
  181 #include <linux/freezer.h>
  182 
  183 #include <net/cfg80211.h>
  184 #include <net/iw_handler.h>
  185 
  186 #include "airo.h"
  187 
  188 #define DRV_NAME "airo"
  189 
  190 #ifdef CONFIG_PCI
  191 static const struct pci_device_id card_ids[] = {
  192 	{ 0x14b9, 1, PCI_ANY_ID, PCI_ANY_ID, },
  193 	{ 0x14b9, 0x4500, PCI_ANY_ID, PCI_ANY_ID },
  194 	{ 0x14b9, 0x4800, PCI_ANY_ID, PCI_ANY_ID, },
  195 	{ 0x14b9, 0x0340, PCI_ANY_ID, PCI_ANY_ID, },
  196 	{ 0x14b9, 0x0350, PCI_ANY_ID, PCI_ANY_ID, },
  197 	{ 0x14b9, 0x5000, PCI_ANY_ID, PCI_ANY_ID, },
  198 	{ 0x14b9, 0xa504, PCI_ANY_ID, PCI_ANY_ID, },
  199 	{ 0, }
  200 };
  201 MODULE_DEVICE_TABLE(pci, card_ids);
  202 
  203 static int airo_pci_probe(struct pci_dev *, const struct pci_device_id *);
  204 static void airo_pci_remove(struct pci_dev *);
  205 static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state);
  206 static int airo_pci_resume(struct pci_dev *pdev);
  207 
  208 static struct pci_driver airo_driver = {
  209 	.name     = DRV_NAME,
  210 	.id_table = card_ids,
  211 	.probe    = airo_pci_probe,
  212 	.remove   = airo_pci_remove,
  213 	.suspend  = airo_pci_suspend,
  214 	.resume   = airo_pci_resume,
  215 };
  216 #endif /* CONFIG_PCI */
  217 
  218 /* Include Wireless Extension definition and check version - Jean II */
  219 #include <linux/wireless.h>
  220 #define WIRELESS_SPY		/* enable iwspy support */
  221 
  222 #define CISCO_EXT		/* enable Cisco extensions */
  223 #ifdef CISCO_EXT
  224 #include <linux/delay.h>
  225 #endif
  226 
  227 /* Hack to do some power saving */
  228 #define POWER_ON_DOWN
  229 
  230 /* As you can see this list is HUGH!
  231    I really don't know what a lot of these counts are about, but they
  232    are all here for completeness.  If the IGNLABEL macro is put in
  233    infront of the label, that statistic will not be included in the list
  234    of statistics in the /proc filesystem */
  235 
  236 #define IGNLABEL(comment) NULL
  237 static const char *statsLabels[] = {
  238 	"RxOverrun",
  239 	IGNLABEL("RxPlcpCrcErr"),
  240 	IGNLABEL("RxPlcpFormatErr"),
  241 	IGNLABEL("RxPlcpLengthErr"),
  242 	"RxMacCrcErr",
  243 	"RxMacCrcOk",
  244 	"RxWepErr",
  245 	"RxWepOk",
  246 	"RetryLong",
  247 	"RetryShort",
  248 	"MaxRetries",
  249 	"NoAck",
  250 	"NoCts",
  251 	"RxAck",
  252 	"RxCts",
  253 	"TxAck",
  254 	"TxRts",
  255 	"TxCts",
  256 	"TxMc",
  257 	"TxBc",
  258 	"TxUcFrags",
  259 	"TxUcPackets",
  260 	"TxBeacon",
  261 	"RxBeacon",
  262 	"TxSinColl",
  263 	"TxMulColl",
  264 	"DefersNo",
  265 	"DefersProt",
  266 	"DefersEngy",
  267 	"DupFram",
  268 	"RxFragDisc",
  269 	"TxAged",
  270 	"RxAged",
  271 	"LostSync-MaxRetry",
  272 	"LostSync-MissedBeacons",
  273 	"LostSync-ArlExceeded",
  274 	"LostSync-Deauth",
  275 	"LostSync-Disassoced",
  276 	"LostSync-TsfTiming",
  277 	"HostTxMc",
  278 	"HostTxBc",
  279 	"HostTxUc",
  280 	"HostTxFail",
  281 	"HostRxMc",
  282 	"HostRxBc",
  283 	"HostRxUc",
  284 	"HostRxDiscard",
  285 	IGNLABEL("HmacTxMc"),
  286 	IGNLABEL("HmacTxBc"),
  287 	IGNLABEL("HmacTxUc"),
  288 	IGNLABEL("HmacTxFail"),
  289 	IGNLABEL("HmacRxMc"),
  290 	IGNLABEL("HmacRxBc"),
  291 	IGNLABEL("HmacRxUc"),
  292 	IGNLABEL("HmacRxDiscard"),
  293 	IGNLABEL("HmacRxAccepted"),
  294 	"SsidMismatch",
  295 	"ApMismatch",
  296 	"RatesMismatch",
  297 	"AuthReject",
  298 	"AuthTimeout",
  299 	"AssocReject",
  300 	"AssocTimeout",
  301 	IGNLABEL("ReasonOutsideTable"),
  302 	IGNLABEL("ReasonStatus1"),
  303 	IGNLABEL("ReasonStatus2"),
  304 	IGNLABEL("ReasonStatus3"),
  305 	IGNLABEL("ReasonStatus4"),
  306 	IGNLABEL("ReasonStatus5"),
  307 	IGNLABEL("ReasonStatus6"),
  308 	IGNLABEL("ReasonStatus7"),
  309 	IGNLABEL("ReasonStatus8"),
  310 	IGNLABEL("ReasonStatus9"),
  311 	IGNLABEL("ReasonStatus10"),
  312 	IGNLABEL("ReasonStatus11"),
  313 	IGNLABEL("ReasonStatus12"),
  314 	IGNLABEL("ReasonStatus13"),
  315 	IGNLABEL("ReasonStatus14"),
  316 	IGNLABEL("ReasonStatus15"),
  317 	IGNLABEL("ReasonStatus16"),
  318 	IGNLABEL("ReasonStatus17"),
  319 	IGNLABEL("ReasonStatus18"),
  320 	IGNLABEL("ReasonStatus19"),
  321 	"RxMan",
  322 	"TxMan",
  323 	"RxRefresh",
  324 	"TxRefresh",
  325 	"RxPoll",
  326 	"TxPoll",
  327 	"HostRetries",
  328 	"LostSync-HostReq",
  329 	"HostTxBytes",
  330 	"HostRxBytes",
  331 	"ElapsedUsec",
  332 	"ElapsedSec",
  333 	"LostSyncBetterAP",
  334 	"PrivacyMismatch",
  335 	"Jammed",
  336 	"DiscRxNotWepped",
  337 	"PhyEleMismatch",
  338 	(char*)-1 };
  339 #ifndef RUN_AT
  340 #define RUN_AT(x) (jiffies+(x))
  341 #endif
  342 
  343 
  344 /* These variables are for insmod, since it seems that the rates
  345    can only be set in setup_card.  Rates should be a comma separated
  346    (no spaces) list of rates (up to 8). */
  347 
  348 static int rates[8];
  349 static char *ssids[3];
  350 
  351 static int io[4];
  352 static int irq[4];
  353 
  354 static
  355 int maxencrypt /* = 0 */; /* The highest rate that the card can encrypt at.
  356 		       0 means no limit.  For old cards this was 4 */
  357 
  358 static int auto_wep /* = 0 */; /* If set, it tries to figure out the wep mode */
  359 static int aux_bap /* = 0 */; /* Checks to see if the aux ports are needed to read
  360 		    the bap, needed on some older cards and buses. */
  361 static int adhoc;
  362 
  363 static int probe = 1;
  364 
  365 static kuid_t proc_kuid;
  366 static int proc_uid /* = 0 */;
  367 
  368 static kgid_t proc_kgid;
  369 static int proc_gid /* = 0 */;
  370 
  371 static int airo_perm = 0555;
  372 
  373 static int proc_perm = 0644;
  374 
  375 MODULE_AUTHOR("Benjamin Reed");
  376 MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet cards.  "
  377 		   "Direct support for ISA/PCI/MPI cards and support for PCMCIA when used with airo_cs.");
  378 MODULE_LICENSE("Dual BSD/GPL");
  379 MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340/350");
  380 module_param_array(io, int, NULL, 0);
  381 module_param_array(irq, int, NULL, 0);
  382 module_param_array(rates, int, NULL, 0);
  383 module_param_array(ssids, charp, NULL, 0);
  384 module_param(auto_wep, int, 0);
  385 MODULE_PARM_DESC(auto_wep,
  386 		 "If non-zero, the driver will keep looping through the authentication options until an association is made.  "
  387 		 "The value of auto_wep is number of the wep keys to check.  "
  388 		 "A value of 2 will try using the key at index 0 and index 1.");
  389 module_param(aux_bap, int, 0);
  390 MODULE_PARM_DESC(aux_bap,
  391 		 "If non-zero, the driver will switch into a mode that seems to work better for older cards with some older buses.  "
  392 		 "Before switching it checks that the switch is needed.");
  393 module_param(maxencrypt, int, 0);
  394 MODULE_PARM_DESC(maxencrypt,
  395 		 "The maximum speed that the card can do encryption.  "
  396 		 "Units are in 512kbs.  "
  397 		 "Zero (default) means there is no limit.  "
  398 		 "Older cards used to be limited to 2mbs (4).");
  399 module_param(adhoc, int, 0);
  400 MODULE_PARM_DESC(adhoc, "If non-zero, the card will start in adhoc mode.");
  401 module_param(probe, int, 0);
  402 MODULE_PARM_DESC(probe, "If zero, the driver won't start the card.");
  403 
  404 module_param(proc_uid, int, 0);
  405 MODULE_PARM_DESC(proc_uid, "The uid that the /proc files will belong to.");
  406 module_param(proc_gid, int, 0);
  407 MODULE_PARM_DESC(proc_gid, "The gid that the /proc files will belong to.");
  408 module_param(airo_perm, int, 0);
  409 MODULE_PARM_DESC(airo_perm, "The permission bits of /proc/[driver/]aironet.");
  410 module_param(proc_perm, int, 0);
  411 MODULE_PARM_DESC(proc_perm, "The permission bits of the files in /proc");
  412 
  413 /* This is a kind of sloppy hack to get this information to OUT4500 and
  414    IN4500.  I would be extremely interested in the situation where this
  415    doesn't work though!!! */
  416 static int do8bitIO /* = 0 */;
  417 
  418 /* Return codes */
  419 #define SUCCESS 0
  420 #define ERROR -1
  421 #define NO_PACKET -2
  422 
  423 /* Commands */
  424 #define NOP2		0x0000
  425 #define MAC_ENABLE	0x0001
  426 #define MAC_DISABLE	0x0002
  427 #define CMD_LOSE_SYNC	0x0003 /* Not sure what this does... */
  428 #define CMD_SOFTRESET	0x0004
  429 #define HOSTSLEEP	0x0005
  430 #define CMD_MAGIC_PKT	0x0006
  431 #define CMD_SETWAKEMASK	0x0007
  432 #define CMD_READCFG	0x0008
  433 #define CMD_SETMODE	0x0009
  434 #define CMD_ALLOCATETX	0x000a
  435 #define CMD_TRANSMIT	0x000b
  436 #define CMD_DEALLOCATETX 0x000c
  437 #define NOP		0x0010
  438 #define CMD_WORKAROUND	0x0011
  439 #define CMD_ALLOCATEAUX 0x0020
  440 #define CMD_ACCESS	0x0021
  441 #define CMD_PCIBAP	0x0022
  442 #define CMD_PCIAUX	0x0023
  443 #define CMD_ALLOCBUF	0x0028
  444 #define CMD_GETTLV	0x0029
  445 #define CMD_PUTTLV	0x002a
  446 #define CMD_DELTLV	0x002b
  447 #define CMD_FINDNEXTTLV	0x002c
  448 #define CMD_PSPNODES	0x0030
  449 #define CMD_SETCW	0x0031    
  450 #define CMD_SETPCF	0x0032    
  451 #define CMD_SETPHYREG	0x003e
  452 #define CMD_TXTEST	0x003f
  453 #define MAC_ENABLETX	0x0101
  454 #define CMD_LISTBSS	0x0103
  455 #define CMD_SAVECFG	0x0108
  456 #define CMD_ENABLEAUX	0x0111
  457 #define CMD_WRITERID	0x0121
  458 #define CMD_USEPSPNODES	0x0130
  459 #define MAC_ENABLERX	0x0201
  460 
  461 /* Command errors */
  462 #define ERROR_QUALIF 0x00
  463 #define ERROR_ILLCMD 0x01
  464 #define ERROR_ILLFMT 0x02
  465 #define ERROR_INVFID 0x03
  466 #define ERROR_INVRID 0x04
  467 #define ERROR_LARGE 0x05
  468 #define ERROR_NDISABL 0x06
  469 #define ERROR_ALLOCBSY 0x07
  470 #define ERROR_NORD 0x0B
  471 #define ERROR_NOWR 0x0C
  472 #define ERROR_INVFIDTX 0x0D
  473 #define ERROR_TESTACT 0x0E
  474 #define ERROR_TAGNFND 0x12
  475 #define ERROR_DECODE 0x20
  476 #define ERROR_DESCUNAV 0x21
  477 #define ERROR_BADLEN 0x22
  478 #define ERROR_MODE 0x80
  479 #define ERROR_HOP 0x81
  480 #define ERROR_BINTER 0x82
  481 #define ERROR_RXMODE 0x83
  482 #define ERROR_MACADDR 0x84
  483 #define ERROR_RATES 0x85
  484 #define ERROR_ORDER 0x86
  485 #define ERROR_SCAN 0x87
  486 #define ERROR_AUTH 0x88
  487 #define ERROR_PSMODE 0x89
  488 #define ERROR_RTYPE 0x8A
  489 #define ERROR_DIVER 0x8B
  490 #define ERROR_SSID 0x8C
  491 #define ERROR_APLIST 0x8D
  492 #define ERROR_AUTOWAKE 0x8E
  493 #define ERROR_LEAP 0x8F
  494 
  495 /* Registers */
  496 #define COMMAND 0x00
  497 #define PARAM0 0x02
  498 #define PARAM1 0x04
  499 #define PARAM2 0x06
  500 #define STATUS 0x08
  501 #define RESP0 0x0a
  502 #define RESP1 0x0c
  503 #define RESP2 0x0e
  504 #define LINKSTAT 0x10
  505 #define SELECT0 0x18
  506 #define OFFSET0 0x1c
  507 #define RXFID 0x20
  508 #define TXALLOCFID 0x22
  509 #define TXCOMPLFID 0x24
  510 #define DATA0 0x36
  511 #define EVSTAT 0x30
  512 #define EVINTEN 0x32
  513 #define EVACK 0x34
  514 #define SWS0 0x28
  515 #define SWS1 0x2a
  516 #define SWS2 0x2c
  517 #define SWS3 0x2e
  518 #define AUXPAGE 0x3A
  519 #define AUXOFF 0x3C
  520 #define AUXDATA 0x3E
  521 
  522 #define FID_TX 1
  523 #define FID_RX 2
  524 /* Offset into aux memory for descriptors */
  525 #define AUX_OFFSET 0x800
  526 /* Size of allocated packets */
  527 #define PKTSIZE 1840
  528 #define RIDSIZE 2048
  529 /* Size of the transmit queue */
  530 #define MAXTXQ 64
  531 
  532 /* BAP selectors */
  533 #define BAP0 0 /* Used for receiving packets */
  534 #define BAP1 2 /* Used for xmiting packets and working with RIDS */
  535 
  536 /* Flags */
  537 #define COMMAND_BUSY 0x8000
  538 
  539 #define BAP_BUSY 0x8000
  540 #define BAP_ERR 0x4000
  541 #define BAP_DONE 0x2000
  542 
  543 #define PROMISC 0xffff
  544 #define NOPROMISC 0x0000
  545 
  546 #define EV_CMD 0x10
  547 #define EV_CLEARCOMMANDBUSY 0x4000
  548 #define EV_RX 0x01
  549 #define EV_TX 0x02
  550 #define EV_TXEXC 0x04
  551 #define EV_ALLOC 0x08
  552 #define EV_LINK 0x80
  553 #define EV_AWAKE 0x100
  554 #define EV_TXCPY 0x400
  555 #define EV_UNKNOWN 0x800
  556 #define EV_MIC 0x1000 /* Message Integrity Check Interrupt */
  557 #define EV_AWAKEN 0x2000
  558 #define STATUS_INTS (EV_AWAKE|EV_LINK|EV_TXEXC|EV_TX|EV_TXCPY|EV_RX|EV_MIC)
  559 
  560 #ifdef CHECK_UNKNOWN_INTS
  561 #define IGNORE_INTS ( EV_CMD | EV_UNKNOWN)
  562 #else
  563 #define IGNORE_INTS (~STATUS_INTS)
  564 #endif
  565 
  566 /* RID TYPES */
  567 #define RID_RW 0x20
  568 
  569 /* The RIDs */
  570 #define RID_CAPABILITIES 0xFF00
  571 #define RID_APINFO     0xFF01
  572 #define RID_RADIOINFO  0xFF02
  573 #define RID_UNKNOWN3   0xFF03
  574 #define RID_RSSI       0xFF04
  575 #define RID_CONFIG     0xFF10
  576 #define RID_SSID       0xFF11
  577 #define RID_APLIST     0xFF12
  578 #define RID_DRVNAME    0xFF13
  579 #define RID_ETHERENCAP 0xFF14
  580 #define RID_WEP_TEMP   0xFF15
  581 #define RID_WEP_PERM   0xFF16
  582 #define RID_MODULATION 0xFF17
  583 #define RID_OPTIONS    0xFF18
  584 #define RID_ACTUALCONFIG 0xFF20 /*readonly*/
  585 #define RID_FACTORYCONFIG 0xFF21
  586 #define RID_UNKNOWN22  0xFF22
  587 #define RID_LEAPUSERNAME 0xFF23
  588 #define RID_LEAPPASSWORD 0xFF24
  589 #define RID_STATUS     0xFF50
  590 #define RID_BEACON_HST 0xFF51
  591 #define RID_BUSY_HST   0xFF52
  592 #define RID_RETRIES_HST 0xFF53
  593 #define RID_UNKNOWN54  0xFF54
  594 #define RID_UNKNOWN55  0xFF55
  595 #define RID_UNKNOWN56  0xFF56
  596 #define RID_MIC        0xFF57
  597 #define RID_STATS16    0xFF60
  598 #define RID_STATS16DELTA 0xFF61
  599 #define RID_STATS16DELTACLEAR 0xFF62
  600 #define RID_STATS      0xFF68
  601 #define RID_STATSDELTA 0xFF69
  602 #define RID_STATSDELTACLEAR 0xFF6A
  603 #define RID_ECHOTEST_RID 0xFF70
  604 #define RID_ECHOTEST_RESULTS 0xFF71
  605 #define RID_BSSLISTFIRST 0xFF72
  606 #define RID_BSSLISTNEXT  0xFF73
  607 #define RID_WPA_BSSLISTFIRST 0xFF74
  608 #define RID_WPA_BSSLISTNEXT  0xFF75
  609 
  610 typedef struct {
  611 	u16 cmd;
  612 	u16 parm0;
  613 	u16 parm1;
  614 	u16 parm2;
  615 } Cmd;
  616 
  617 typedef struct {
  618 	u16 status;
  619 	u16 rsp0;
  620 	u16 rsp1;
  621 	u16 rsp2;
  622 } Resp;
  623 
  624 /*
  625  * Rids and endian-ness:  The Rids will always be in cpu endian, since
  626  * this all the patches from the big-endian guys end up doing that.
  627  * so all rid access should use the read/writeXXXRid routines.
  628  */
  629 
  630 /* This structure came from an email sent to me from an engineer at
  631    aironet for inclusion into this driver */
  632 typedef struct WepKeyRid WepKeyRid;
  633 struct WepKeyRid {
  634 	__le16 len;
  635 	__le16 kindex;
  636 	u8 mac[ETH_ALEN];
  637 	__le16 klen;
  638 	u8 key[16];
  639 } __packed;
  640 
  641 /* These structures are from the Aironet's PC4500 Developers Manual */
  642 typedef struct Ssid Ssid;
  643 struct Ssid {
  644 	__le16 len;
  645 	u8 ssid[32];
  646 } __packed;
  647 
  648 typedef struct SsidRid SsidRid;
  649 struct SsidRid {
  650 	__le16 len;
  651 	Ssid ssids[3];
  652 } __packed;
  653 
  654 typedef struct ModulationRid ModulationRid;
  655 struct ModulationRid {
  656         __le16 len;
  657         __le16 modulation;
  658 #define MOD_DEFAULT cpu_to_le16(0)
  659 #define MOD_CCK cpu_to_le16(1)
  660 #define MOD_MOK cpu_to_le16(2)
  661 } __packed;
  662 
  663 typedef struct ConfigRid ConfigRid;
  664 struct ConfigRid {
  665 	__le16 len; /* sizeof(ConfigRid) */
  666 	__le16 opmode; /* operating mode */
  667 #define MODE_STA_IBSS cpu_to_le16(0)
  668 #define MODE_STA_ESS cpu_to_le16(1)
  669 #define MODE_AP cpu_to_le16(2)
  670 #define MODE_AP_RPTR cpu_to_le16(3)
  671 #define MODE_CFG_MASK cpu_to_le16(0xff)
  672 #define MODE_ETHERNET_HOST cpu_to_le16(0<<8) /* rx payloads converted */
  673 #define MODE_LLC_HOST cpu_to_le16(1<<8) /* rx payloads left as is */
  674 #define MODE_AIRONET_EXTEND cpu_to_le16(1<<9) /* enable Aironet extenstions */
  675 #define MODE_AP_INTERFACE cpu_to_le16(1<<10) /* enable ap interface extensions */
  676 #define MODE_ANTENNA_ALIGN cpu_to_le16(1<<11) /* enable antenna alignment */
  677 #define MODE_ETHER_LLC cpu_to_le16(1<<12) /* enable ethernet LLC */
  678 #define MODE_LEAF_NODE cpu_to_le16(1<<13) /* enable leaf node bridge */
  679 #define MODE_CF_POLLABLE cpu_to_le16(1<<14) /* enable CF pollable */
  680 #define MODE_MIC cpu_to_le16(1<<15) /* enable MIC */
  681 	__le16 rmode; /* receive mode */
  682 #define RXMODE_BC_MC_ADDR cpu_to_le16(0)
  683 #define RXMODE_BC_ADDR cpu_to_le16(1) /* ignore multicasts */
  684 #define RXMODE_ADDR cpu_to_le16(2) /* ignore multicast and broadcast */
  685 #define RXMODE_RFMON cpu_to_le16(3) /* wireless monitor mode */
  686 #define RXMODE_RFMON_ANYBSS cpu_to_le16(4)
  687 #define RXMODE_LANMON cpu_to_le16(5) /* lan style monitor -- data packets only */
  688 #define RXMODE_MASK cpu_to_le16(255)
  689 #define RXMODE_DISABLE_802_3_HEADER cpu_to_le16(1<<8) /* disables 802.3 header on rx */
  690 #define RXMODE_FULL_MASK (RXMODE_MASK | RXMODE_DISABLE_802_3_HEADER)
  691 #define RXMODE_NORMALIZED_RSSI cpu_to_le16(1<<9) /* return normalized RSSI */
  692 	__le16 fragThresh;
  693 	__le16 rtsThres;
  694 	u8 macAddr[ETH_ALEN];
  695 	u8 rates[8];
  696 	__le16 shortRetryLimit;
  697 	__le16 longRetryLimit;
  698 	__le16 txLifetime; /* in kusec */
  699 	__le16 rxLifetime; /* in kusec */
  700 	__le16 stationary;
  701 	__le16 ordering;
  702 	__le16 u16deviceType; /* for overriding device type */
  703 	__le16 cfpRate;
  704 	__le16 cfpDuration;
  705 	__le16 _reserved1[3];
  706 	/*---------- Scanning/Associating ----------*/
  707 	__le16 scanMode;
  708 #define SCANMODE_ACTIVE cpu_to_le16(0)
  709 #define SCANMODE_PASSIVE cpu_to_le16(1)
  710 #define SCANMODE_AIROSCAN cpu_to_le16(2)
  711 	__le16 probeDelay; /* in kusec */
  712 	__le16 probeEnergyTimeout; /* in kusec */
  713         __le16 probeResponseTimeout;
  714 	__le16 beaconListenTimeout;
  715 	__le16 joinNetTimeout;
  716 	__le16 authTimeout;
  717 	__le16 authType;
  718 #define AUTH_OPEN cpu_to_le16(0x1)
  719 #define AUTH_ENCRYPT cpu_to_le16(0x101)
  720 #define AUTH_SHAREDKEY cpu_to_le16(0x102)
  721 #define AUTH_ALLOW_UNENCRYPTED cpu_to_le16(0x200)
  722 	__le16 associationTimeout;
  723 	__le16 specifiedApTimeout;
  724 	__le16 offlineScanInterval;
  725 	__le16 offlineScanDuration;
  726 	__le16 linkLossDelay;
  727 	__le16 maxBeaconLostTime;
  728 	__le16 refreshInterval;
  729 #define DISABLE_REFRESH cpu_to_le16(0xFFFF)
  730 	__le16 _reserved1a[1];
  731 	/*---------- Power save operation ----------*/
  732 	__le16 powerSaveMode;
  733 #define POWERSAVE_CAM cpu_to_le16(0)
  734 #define POWERSAVE_PSP cpu_to_le16(1)
  735 #define POWERSAVE_PSPCAM cpu_to_le16(2)
  736 	__le16 sleepForDtims;
  737 	__le16 listenInterval;
  738 	__le16 fastListenInterval;
  739 	__le16 listenDecay;
  740 	__le16 fastListenDelay;
  741 	__le16 _reserved2[2];
  742 	/*---------- Ap/Ibss config items ----------*/
  743 	__le16 beaconPeriod;
  744 	__le16 atimDuration;
  745 	__le16 hopPeriod;
  746 	__le16 channelSet;
  747 	__le16 channel;
  748 	__le16 dtimPeriod;
  749 	__le16 bridgeDistance;
  750 	__le16 radioID;
  751 	/*---------- Radio configuration ----------*/
  752 	__le16 radioType;
  753 #define RADIOTYPE_DEFAULT cpu_to_le16(0)
  754 #define RADIOTYPE_802_11 cpu_to_le16(1)
  755 #define RADIOTYPE_LEGACY cpu_to_le16(2)
  756 	u8 rxDiversity;
  757 	u8 txDiversity;
  758 	__le16 txPower;
  759 #define TXPOWER_DEFAULT 0
  760 	__le16 rssiThreshold;
  761 #define RSSI_DEFAULT 0
  762         __le16 modulation;
  763 #define PREAMBLE_AUTO cpu_to_le16(0)
  764 #define PREAMBLE_LONG cpu_to_le16(1)
  765 #define PREAMBLE_SHORT cpu_to_le16(2)
  766 	__le16 preamble;
  767 	__le16 homeProduct;
  768 	__le16 radioSpecific;
  769 	/*---------- Aironet Extensions ----------*/
  770 	u8 nodeName[16];
  771 	__le16 arlThreshold;
  772 	__le16 arlDecay;
  773 	__le16 arlDelay;
  774 	__le16 _reserved4[1];
  775 	/*---------- Aironet Extensions ----------*/
  776 	u8 magicAction;
  777 #define MAGIC_ACTION_STSCHG 1
  778 #define MAGIC_ACTION_RESUME 2
  779 #define MAGIC_IGNORE_MCAST (1<<8)
  780 #define MAGIC_IGNORE_BCAST (1<<9)
  781 #define MAGIC_SWITCH_TO_PSP (0<<10)
  782 #define MAGIC_STAY_IN_CAM (1<<10)
  783 	u8 magicControl;
  784 	__le16 autoWake;
  785 } __packed;
  786 
  787 typedef struct StatusRid StatusRid;
  788 struct StatusRid {
  789 	__le16 len;
  790 	u8 mac[ETH_ALEN];
  791 	__le16 mode;
  792 	__le16 errorCode;
  793 	__le16 sigQuality;
  794 	__le16 SSIDlen;
  795 	char SSID[32];
  796 	char apName[16];
  797 	u8 bssid[4][ETH_ALEN];
  798 	__le16 beaconPeriod;
  799 	__le16 dimPeriod;
  800 	__le16 atimDuration;
  801 	__le16 hopPeriod;
  802 	__le16 channelSet;
  803 	__le16 channel;
  804 	__le16 hopsToBackbone;
  805 	__le16 apTotalLoad;
  806 	__le16 generatedLoad;
  807 	__le16 accumulatedArl;
  808 	__le16 signalQuality;
  809 	__le16 currentXmitRate;
  810 	__le16 apDevExtensions;
  811 	__le16 normalizedSignalStrength;
  812 	__le16 shortPreamble;
  813 	u8 apIP[4];
  814 	u8 noisePercent; /* Noise percent in last second */
  815 	u8 noisedBm; /* Noise dBm in last second */
  816 	u8 noiseAvePercent; /* Noise percent in last minute */
  817 	u8 noiseAvedBm; /* Noise dBm in last minute */
  818 	u8 noiseMaxPercent; /* Highest noise percent in last minute */
  819 	u8 noiseMaxdBm; /* Highest noise dbm in last minute */
  820 	__le16 load;
  821 	u8 carrier[4];
  822 	__le16 assocStatus;
  823 #define STAT_NOPACKETS 0
  824 #define STAT_NOCARRIERSET 10
  825 #define STAT_GOTCARRIERSET 11
  826 #define STAT_WRONGSSID 20
  827 #define STAT_BADCHANNEL 25
  828 #define STAT_BADBITRATES 30
  829 #define STAT_BADPRIVACY 35
  830 #define STAT_APFOUND 40
  831 #define STAT_APREJECTED 50
  832 #define STAT_AUTHENTICATING 60
  833 #define STAT_DEAUTHENTICATED 61
  834 #define STAT_AUTHTIMEOUT 62
  835 #define STAT_ASSOCIATING 70
  836 #define STAT_DEASSOCIATED 71
  837 #define STAT_ASSOCTIMEOUT 72
  838 #define STAT_NOTAIROAP 73
  839 #define STAT_ASSOCIATED 80
  840 #define STAT_LEAPING 90
  841 #define STAT_LEAPFAILED 91
  842 #define STAT_LEAPTIMEDOUT 92
  843 #define STAT_LEAPCOMPLETE 93
  844 } __packed;
  845 
  846 typedef struct StatsRid StatsRid;
  847 struct StatsRid {
  848 	__le16 len;
  849 	__le16 spacer;
  850 	__le32 vals[100];
  851 } __packed;
  852 
  853 typedef struct APListRid APListRid;
  854 struct APListRid {
  855 	__le16 len;
  856 	u8 ap[4][ETH_ALEN];
  857 } __packed;
  858 
  859 typedef struct CapabilityRid CapabilityRid;
  860 struct CapabilityRid {
  861 	__le16 len;
  862 	char oui[3];
  863 	char zero;
  864 	__le16 prodNum;
  865 	char manName[32];
  866 	char prodName[16];
  867 	char prodVer[8];
  868 	char factoryAddr[ETH_ALEN];
  869 	char aironetAddr[ETH_ALEN];
  870 	__le16 radioType;
  871 	__le16 country;
  872 	char callid[ETH_ALEN];
  873 	char supportedRates[8];
  874 	char rxDiversity;
  875 	char txDiversity;
  876 	__le16 txPowerLevels[8];
  877 	__le16 hardVer;
  878 	__le16 hardCap;
  879 	__le16 tempRange;
  880 	__le16 softVer;
  881 	__le16 softSubVer;
  882 	__le16 interfaceVer;
  883 	__le16 softCap;
  884 	__le16 bootBlockVer;
  885 	__le16 requiredHard;
  886 	__le16 extSoftCap;
  887 } __packed;
  888 
  889 /* Only present on firmware >= 5.30.17 */
  890 typedef struct BSSListRidExtra BSSListRidExtra;
  891 struct BSSListRidExtra {
  892   __le16 unknown[4];
  893   u8 fixed[12]; /* WLAN management frame */
  894   u8 iep[624];
  895 } __packed;
  896 
  897 typedef struct BSSListRid BSSListRid;
  898 struct BSSListRid {
  899   __le16 len;
  900   __le16 index; /* First is 0 and 0xffff means end of list */
  901 #define RADIO_FH 1 /* Frequency hopping radio type */
  902 #define RADIO_DS 2 /* Direct sequence radio type */
  903 #define RADIO_TMA 4 /* Proprietary radio used in old cards (2500) */
  904   __le16 radioType;
  905   u8 bssid[ETH_ALEN]; /* Mac address of the BSS */
  906   u8 zero;
  907   u8 ssidLen;
  908   u8 ssid[32];
  909   __le16 dBm;
  910 #define CAP_ESS cpu_to_le16(1<<0)
  911 #define CAP_IBSS cpu_to_le16(1<<1)
  912 #define CAP_PRIVACY cpu_to_le16(1<<4)
  913 #define CAP_SHORTHDR cpu_to_le16(1<<5)
  914   __le16 cap;
  915   __le16 beaconInterval;
  916   u8 rates[8]; /* Same as rates for config rid */
  917   struct { /* For frequency hopping only */
  918     __le16 dwell;
  919     u8 hopSet;
  920     u8 hopPattern;
  921     u8 hopIndex;
  922     u8 fill;
  923   } fh;
  924   __le16 dsChannel;
  925   __le16 atimWindow;
  926 
  927   /* Only present on firmware >= 5.30.17 */
  928   BSSListRidExtra extra;
  929 } __packed;
  930 
  931 typedef struct {
  932   BSSListRid bss;
  933   struct list_head list;
  934 } BSSListElement;
  935 
  936 typedef struct tdsRssiEntry tdsRssiEntry;
  937 struct tdsRssiEntry {
  938   u8 rssipct;
  939   u8 rssidBm;
  940 } __packed;
  941 
  942 typedef struct tdsRssiRid tdsRssiRid;
  943 struct tdsRssiRid {
  944   u16 len;
  945   tdsRssiEntry x[256];
  946 } __packed;
  947 
  948 typedef struct MICRid MICRid;
  949 struct MICRid {
  950 	__le16 len;
  951 	__le16 state;
  952 	__le16 multicastValid;
  953 	u8  multicast[16];
  954 	__le16 unicastValid;
  955 	u8  unicast[16];
  956 } __packed;
  957 
  958 typedef struct MICBuffer MICBuffer;
  959 struct MICBuffer {
  960 	__be16 typelen;
  961 
  962 	union {
  963 	    u8 snap[8];
  964 	    struct {
  965 		u8 dsap;
  966 		u8 ssap;
  967 		u8 control;
  968 		u8 orgcode[3];
  969 		u8 fieldtype[2];
  970 	    } llc;
  971 	} u;
  972 	__be32 mic;
  973 	__be32 seq;
  974 } __packed;
  975 
  976 typedef struct {
  977 	u8 da[ETH_ALEN];
  978 	u8 sa[ETH_ALEN];
  979 } etherHead;
  980 
  981 #define TXCTL_TXOK (1<<1) /* report if tx is ok */
  982 #define TXCTL_TXEX (1<<2) /* report if tx fails */
  983 #define TXCTL_802_3 (0<<3) /* 802.3 packet */
  984 #define TXCTL_802_11 (1<<3) /* 802.11 mac packet */
  985 #define TXCTL_ETHERNET (0<<4) /* payload has ethertype */
  986 #define TXCTL_LLC (1<<4) /* payload is llc */
  987 #define TXCTL_RELEASE (0<<5) /* release after completion */
  988 #define TXCTL_NORELEASE (1<<5) /* on completion returns to host */
  989 
  990 #define BUSY_FID 0x10000
  991 
  992 #ifdef CISCO_EXT
  993 #define AIROMAGIC	0xa55a
  994 /* Warning : SIOCDEVPRIVATE may disapear during 2.5.X - Jean II */
  995 #ifdef SIOCIWFIRSTPRIV
  996 #ifdef SIOCDEVPRIVATE
  997 #define AIROOLDIOCTL	SIOCDEVPRIVATE
  998 #define AIROOLDIDIFC 	AIROOLDIOCTL + 1
  999 #endif /* SIOCDEVPRIVATE */
 1000 #else /* SIOCIWFIRSTPRIV */
 1001 #define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
 1002 #endif /* SIOCIWFIRSTPRIV */
 1003 /* This may be wrong. When using the new SIOCIWFIRSTPRIV range, we probably
 1004  * should use only "GET" ioctls (last bit set to 1). "SET" ioctls are root
 1005  * only and don't return the modified struct ifreq to the application which
 1006  * is usually a problem. - Jean II */
 1007 #define AIROIOCTL	SIOCIWFIRSTPRIV
 1008 #define AIROIDIFC 	AIROIOCTL + 1
 1009 
 1010 /* Ioctl constants to be used in airo_ioctl.command */
 1011 
 1012 #define	AIROGCAP  		0	// Capability rid
 1013 #define AIROGCFG		1       // USED A LOT
 1014 #define AIROGSLIST		2	// System ID list
 1015 #define AIROGVLIST		3       // List of specified AP's
 1016 #define AIROGDRVNAM		4	//  NOTUSED
 1017 #define AIROGEHTENC		5	// NOTUSED
 1018 #define AIROGWEPKTMP		6
 1019 #define AIROGWEPKNV		7
 1020 #define AIROGSTAT		8
 1021 #define AIROGSTATSC32		9
 1022 #define AIROGSTATSD32		10
 1023 #define AIROGMICRID		11
 1024 #define AIROGMICSTATS		12
 1025 #define AIROGFLAGS		13
 1026 #define AIROGID			14
 1027 #define AIRORRID		15
 1028 #define AIRORSWVERSION		17
 1029 
 1030 /* Leave gap of 40 commands after AIROGSTATSD32 for future */
 1031 
 1032 #define AIROPCAP               	AIROGSTATSD32 + 40
 1033 #define AIROPVLIST              AIROPCAP      + 1
 1034 #define AIROPSLIST		AIROPVLIST    + 1
 1035 #define AIROPCFG		AIROPSLIST    + 1
 1036 #define AIROPSIDS		AIROPCFG      + 1
 1037 #define AIROPAPLIST		AIROPSIDS     + 1
 1038 #define AIROPMACON		AIROPAPLIST   + 1	/* Enable mac  */
 1039 #define AIROPMACOFF		AIROPMACON    + 1 	/* Disable mac */
 1040 #define AIROPSTCLR		AIROPMACOFF   + 1
 1041 #define AIROPWEPKEY		AIROPSTCLR    + 1
 1042 #define AIROPWEPKEYNV		AIROPWEPKEY   + 1
 1043 #define AIROPLEAPPWD            AIROPWEPKEYNV + 1
 1044 #define AIROPLEAPUSR            AIROPLEAPPWD  + 1
 1045 
 1046 /* Flash codes */
 1047 
 1048 #define AIROFLSHRST	       AIROPWEPKEYNV  + 40
 1049 #define AIROFLSHGCHR           AIROFLSHRST    + 1
 1050 #define AIROFLSHSTFL           AIROFLSHGCHR   + 1
 1051 #define AIROFLSHPCHR           AIROFLSHSTFL   + 1
 1052 #define AIROFLPUTBUF           AIROFLSHPCHR   + 1
 1053 #define AIRORESTART            AIROFLPUTBUF   + 1
 1054 
 1055 #define FLASHSIZE	32768
 1056 #define AUXMEMSIZE	(256 * 1024)
 1057 
 1058 typedef struct aironet_ioctl {
 1059 	unsigned short command;		// What to do
 1060 	unsigned short len;		// Len of data
 1061 	unsigned short ridnum;		// rid number
 1062 	unsigned char __user *data;	// d-data
 1063 } aironet_ioctl;
 1064 
 1065 static const char swversion[] = "2.1";
 1066 #endif /* CISCO_EXT */
 1067 
 1068 #define NUM_MODULES       2
 1069 #define MIC_MSGLEN_MAX    2400
 1070 #define EMMH32_MSGLEN_MAX MIC_MSGLEN_MAX
 1071 #define AIRO_DEF_MTU      2312
 1072 
 1073 typedef struct {
 1074 	u32   size;            // size
 1075 	u8    enabled;         // MIC enabled or not
 1076 	u32   rxSuccess;       // successful packets received
 1077 	u32   rxIncorrectMIC;  // pkts dropped due to incorrect MIC comparison
 1078 	u32   rxNotMICed;      // pkts dropped due to not being MIC'd
 1079 	u32   rxMICPlummed;    // pkts dropped due to not having a MIC plummed
 1080 	u32   rxWrongSequence; // pkts dropped due to sequence number violation
 1081 	u32   reserve[32];
 1082 } mic_statistics;
 1083 
 1084 typedef struct {
 1085 	u32 coeff[((EMMH32_MSGLEN_MAX)+3)>>2];
 1086 	u64 accum;	// accumulated mic, reduced to u32 in final()
 1087 	int position;	// current position (byte offset) in message
 1088 	union {
 1089 		u8  d8[4];
 1090 		__be32 d32;
 1091 	} part;	// saves partial message word across update() calls
 1092 } emmh32_context;
 1093 
 1094 typedef struct {
 1095 	emmh32_context seed;	    // Context - the seed
 1096 	u32		 rx;	    // Received sequence number
 1097 	u32		 tx;	    // Tx sequence number
 1098 	u32		 window;    // Start of window
 1099 	u8		 valid;	    // Flag to say if context is valid or not
 1100 	u8		 key[16];
 1101 } miccntx;
 1102 
 1103 typedef struct {
 1104 	miccntx mCtx;		// Multicast context
 1105 	miccntx uCtx;		// Unicast context
 1106 } mic_module;
 1107 
 1108 typedef struct {
 1109 	unsigned int  rid: 16;
 1110 	unsigned int  len: 15;
 1111 	unsigned int  valid: 1;
 1112 	dma_addr_t host_addr;
 1113 } Rid;
 1114 
 1115 typedef struct {
 1116 	unsigned int  offset: 15;
 1117 	unsigned int  eoc: 1;
 1118 	unsigned int  len: 15;
 1119 	unsigned int  valid: 1;
 1120 	dma_addr_t host_addr;
 1121 } TxFid;
 1122 
 1123 struct rx_hdr {
 1124 	__le16 status, len;
 1125 	u8 rssi[2];
 1126 	u8 rate;
 1127 	u8 freq;
 1128 	__le16 tmp[4];
 1129 } __packed;
 1130 
 1131 typedef struct {
 1132 	unsigned int  ctl: 15;
 1133 	unsigned int  rdy: 1;
 1134 	unsigned int  len: 15;
 1135 	unsigned int  valid: 1;
 1136 	dma_addr_t host_addr;
 1137 } RxFid;
 1138 
 1139 /*
 1140  * Host receive descriptor
 1141  */
 1142 typedef struct {
 1143 	unsigned char __iomem *card_ram_off; /* offset into card memory of the
 1144 						desc */
 1145 	RxFid         rx_desc;		     /* card receive descriptor */
 1146 	char          *virtual_host_addr;    /* virtual address of host receive
 1147 					        buffer */
 1148 	int           pending;
 1149 } HostRxDesc;
 1150 
 1151 /*
 1152  * Host transmit descriptor
 1153  */
 1154 typedef struct {
 1155 	unsigned char __iomem *card_ram_off;	     /* offset into card memory of the
 1156 						desc */
 1157 	TxFid         tx_desc;		     /* card transmit descriptor */
 1158 	char          *virtual_host_addr;    /* virtual address of host receive
 1159 					        buffer */
 1160 	int           pending;
 1161 } HostTxDesc;
 1162 
 1163 /*
 1164  * Host RID descriptor
 1165  */
 1166 typedef struct {
 1167 	unsigned char __iomem *card_ram_off;      /* offset into card memory of the
 1168 					     descriptor */
 1169 	Rid           rid_desc;		  /* card RID descriptor */
 1170 	char          *virtual_host_addr; /* virtual address of host receive
 1171 					     buffer */
 1172 } HostRidDesc;
 1173 
 1174 typedef struct {
 1175 	u16 sw0;
 1176 	u16 sw1;
 1177 	u16 status;
 1178 	u16 len;
 1179 #define HOST_SET (1 << 0)
 1180 #define HOST_INT_TX (1 << 1) /* Interrupt on successful TX */
 1181 #define HOST_INT_TXERR (1 << 2) /* Interrupt on unseccessful TX */
 1182 #define HOST_LCC_PAYLOAD (1 << 4) /* LLC payload, 0 = Ethertype */
 1183 #define HOST_DONT_RLSE (1 << 5) /* Don't release buffer when done */
 1184 #define HOST_DONT_RETRY (1 << 6) /* Don't retry trasmit */
 1185 #define HOST_CLR_AID (1 << 7) /* clear AID failure */
 1186 #define HOST_RTS (1 << 9) /* Force RTS use */
 1187 #define HOST_SHORT (1 << 10) /* Do short preamble */
 1188 	u16 ctl;
 1189 	u16 aid;
 1190 	u16 retries;
 1191 	u16 fill;
 1192 } TxCtlHdr;
 1193 
 1194 typedef struct {
 1195         u16 ctl;
 1196         u16 duration;
 1197         char addr1[6];
 1198         char addr2[6];
 1199         char addr3[6];
 1200         u16 seq;
 1201         char addr4[6];
 1202 } WifiHdr;
 1203 
 1204 
 1205 typedef struct {
 1206 	TxCtlHdr ctlhdr;
 1207 	u16 fill1;
 1208 	u16 fill2;
 1209 	WifiHdr wifihdr;
 1210 	u16 gaplen;
 1211 	u16 status;
 1212 } WifiCtlHdr;
 1213 
 1214 static WifiCtlHdr wifictlhdr8023 = {
 1215 	.ctlhdr = {
 1216 		.ctl	= HOST_DONT_RLSE,
 1217 	}
 1218 };
 1219 
 1220 // A few details needed for WEP (Wireless Equivalent Privacy)
 1221 #define MAX_KEY_SIZE 13			// 128 (?) bits
 1222 #define MIN_KEY_SIZE  5			// 40 bits RC4 - WEP
 1223 typedef struct wep_key_t {
 1224 	u16	len;
 1225 	u8	key[16];	/* 40-bit and 104-bit keys */
 1226 } wep_key_t;
 1227 
 1228 /* List of Wireless Handlers (new API) */
 1229 static const struct iw_handler_def	airo_handler_def;
 1230 
 1231 static const char version[] = "airo.c 0.6 (Ben Reed & Javier Achirica)";
 1232 
 1233 struct airo_info;
 1234 
 1235 static int get_dec_u16( char *buffer, int *start, int limit );
 1236 static void OUT4500( struct airo_info *, u16 register, u16 value );
 1237 static unsigned short IN4500( struct airo_info *, u16 register );
 1238 static u16 setup_card(struct airo_info*, u8 *mac, int lock);
 1239 static int enable_MAC(struct airo_info *ai, int lock);
 1240 static void disable_MAC(struct airo_info *ai, int lock);
 1241 static void enable_interrupts(struct airo_info*);
 1242 static void disable_interrupts(struct airo_info*);
 1243 static u16 issuecommand(struct airo_info*, Cmd *pCmd, Resp *pRsp);
 1244 static int bap_setup(struct airo_info*, u16 rid, u16 offset, int whichbap);
 1245 static int aux_bap_read(struct airo_info*, __le16 *pu16Dst, int bytelen,
 1246 			int whichbap);
 1247 static int fast_bap_read(struct airo_info*, __le16 *pu16Dst, int bytelen,
 1248 			 int whichbap);
 1249 static int bap_write(struct airo_info*, const __le16 *pu16Src, int bytelen,
 1250 		     int whichbap);
 1251 static int PC4500_accessrid(struct airo_info*, u16 rid, u16 accmd);
 1252 static int PC4500_readrid(struct airo_info*, u16 rid, void *pBuf, int len, int lock);
 1253 static int PC4500_writerid(struct airo_info*, u16 rid, const void
 1254 			   *pBuf, int len, int lock);
 1255 static int do_writerid( struct airo_info*, u16 rid, const void *rid_data,
 1256 			int len, int dummy );
 1257 static u16 transmit_allocate(struct airo_info*, int lenPayload, int raw);
 1258 static int transmit_802_3_packet(struct airo_info*, int len, char *pPacket);
 1259 static int transmit_802_11_packet(struct airo_info*, int len, char *pPacket);
 1260 
 1261 static int mpi_send_packet (struct net_device *dev);
 1262 static void mpi_unmap_card(struct pci_dev *pci);
 1263 static void mpi_receive_802_3(struct airo_info *ai);
 1264 static void mpi_receive_802_11(struct airo_info *ai);
 1265 static int waitbusy (struct airo_info *ai);
 1266 
 1267 static irqreturn_t airo_interrupt( int irq, void* dev_id);
 1268 static int airo_thread(void *data);
 1269 static void timer_func( struct net_device *dev );
 1270 static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 1271 static struct iw_statistics *airo_get_wireless_stats (struct net_device *dev);
 1272 static void airo_read_wireless_stats (struct airo_info *local);
 1273 #ifdef CISCO_EXT
 1274 static int readrids(struct net_device *dev, aironet_ioctl *comp);
 1275 static int writerids(struct net_device *dev, aironet_ioctl *comp);
 1276 static int flashcard(struct net_device *dev, aironet_ioctl *comp);
 1277 #endif /* CISCO_EXT */
 1278 static void micinit(struct airo_info *ai);
 1279 static int micsetup(struct airo_info *ai);
 1280 static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len);
 1281 static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen);
 1282 
 1283 static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi);
 1284 static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm);
 1285 
 1286 static void airo_networks_free(struct airo_info *ai);
 1287 
 1288 struct airo_info {
 1289 	struct net_device             *dev;
 1290 	struct list_head              dev_list;
 1291 	/* Note, we can have MAX_FIDS outstanding.  FIDs are 16-bits, so we
 1292 	   use the high bit to mark whether it is in use. */
 1293 #define MAX_FIDS 6
 1294 #define MPI_MAX_FIDS 1
 1295 	u32                           fids[MAX_FIDS];
 1296 	ConfigRid config;
 1297 	char keyindex; // Used with auto wep
 1298 	char defindex; // Used with auto wep
 1299 	struct proc_dir_entry *proc_entry;
 1300         spinlock_t aux_lock;
 1301 #define FLAG_RADIO_OFF	0	/* User disabling of MAC */
 1302 #define FLAG_RADIO_DOWN	1	/* ifup/ifdown disabling of MAC */
 1303 #define FLAG_RADIO_MASK 0x03
 1304 #define FLAG_ENABLED	2
 1305 #define FLAG_ADHOC	3	/* Needed by MIC */
 1306 #define FLAG_MIC_CAPABLE 4
 1307 #define FLAG_UPDATE_MULTI 5
 1308 #define FLAG_UPDATE_UNI 6
 1309 #define FLAG_802_11	7
 1310 #define FLAG_PROMISC	8	/* IFF_PROMISC 0x100 - include/linux/if.h */
 1311 #define FLAG_PENDING_XMIT 9
 1312 #define FLAG_PENDING_XMIT11 10
 1313 #define FLAG_MPI	11
 1314 #define FLAG_REGISTERED	12
 1315 #define FLAG_COMMIT	13
 1316 #define FLAG_RESET	14
 1317 #define FLAG_FLASHING	15
 1318 #define FLAG_WPA_CAPABLE	16
 1319 	unsigned long flags;
 1320 #define JOB_DIE	0
 1321 #define JOB_XMIT	1
 1322 #define JOB_XMIT11	2
 1323 #define JOB_STATS	3
 1324 #define JOB_PROMISC	4
 1325 #define JOB_MIC	5
 1326 #define JOB_EVENT	6
 1327 #define JOB_AUTOWEP	7
 1328 #define JOB_WSTATS	8
 1329 #define JOB_SCAN_RESULTS  9
 1330 	unsigned long jobs;
 1331 	int (*bap_read)(struct airo_info*, __le16 *pu16Dst, int bytelen,
 1332 			int whichbap);
 1333 	unsigned short *flash;
 1334 	tdsRssiEntry *rssi;
 1335 	struct task_struct *list_bss_task;
 1336 	struct task_struct *airo_thread_task;
 1337 	struct semaphore sem;
 1338 	wait_queue_head_t thr_wait;
 1339 	unsigned long expires;
 1340 	struct {
 1341 		struct sk_buff *skb;
 1342 		int fid;
 1343 	} xmit, xmit11;
 1344 	struct net_device *wifidev;
 1345 	struct iw_statistics	wstats;		// wireless stats
 1346 	unsigned long		scan_timeout;	/* Time scan should be read */
 1347 	struct iw_spy_data	spy_data;
 1348 	struct iw_public_data	wireless_data;
 1349 	/* MIC stuff */
 1350 	struct crypto_cipher	*tfm;
 1351 	mic_module		mod[2];
 1352 	mic_statistics		micstats;
 1353 	HostRxDesc rxfids[MPI_MAX_FIDS]; // rx/tx/config MPI350 descriptors
 1354 	HostTxDesc txfids[MPI_MAX_FIDS];
 1355 	HostRidDesc config_desc;
 1356 	unsigned long ridbus; // phys addr of config_desc
 1357 	struct sk_buff_head txq;// tx queue used by mpi350 code
 1358 	struct pci_dev          *pci;
 1359 	unsigned char		__iomem *pcimem;
 1360 	unsigned char		__iomem *pciaux;
 1361 	unsigned char		*shared;
 1362 	dma_addr_t		shared_dma;
 1363 	pm_message_t		power;
 1364 	SsidRid			*SSID;
 1365 	APListRid		APList;
 1366 #define	PCI_SHARED_LEN		2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE
 1367 	char			proc_name[IFNAMSIZ];
 1368 
 1369 	int			wep_capable;
 1370 	int			max_wep_idx;
 1371 	int			last_auth;
 1372 
 1373 	/* WPA-related stuff */
 1374 	unsigned int bssListFirst;
 1375 	unsigned int bssListNext;
 1376 	unsigned int bssListRidLen;
 1377 
 1378 	struct list_head network_list;
 1379 	struct list_head network_free_list;
 1380 	BSSListElement *networks;
 1381 };
 1382 
 1383 static inline int bap_read(struct airo_info *ai, __le16 *pu16Dst, int bytelen,
 1384 			   int whichbap)
 1385 {
 1386 	return ai->bap_read(ai, pu16Dst, bytelen, whichbap);
 1387 }
 1388 
 1389 static int setup_proc_entry( struct net_device *dev,
 1390 			     struct airo_info *apriv );
 1391 static int takedown_proc_entry( struct net_device *dev,
 1392 				struct airo_info *apriv );
 1393 
 1394 static int cmdreset(struct airo_info *ai);
 1395 static int setflashmode (struct airo_info *ai);
 1396 static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime);
 1397 static int flashputbuf(struct airo_info *ai);
 1398 static int flashrestart(struct airo_info *ai,struct net_device *dev);
 1399 
 1400 #define airo_print(type, name, fmt, args...) \
 1401 	printk(type DRV_NAME "(%s): " fmt "\n", name, ##args)
 1402 
 1403 #define airo_print_info(name, fmt, args...) \
 1404 	airo_print(KERN_INFO, name, fmt, ##args)
 1405 
 1406 #define airo_print_dbg(name, fmt, args...) \
 1407 	airo_print(KERN_DEBUG, name, fmt, ##args)
 1408 
 1409 #define airo_print_warn(name, fmt, args...) \
 1410 	airo_print(KERN_WARNING, name, fmt, ##args)
 1411 
 1412 #define airo_print_err(name, fmt, args...) \
 1413 	airo_print(KERN_ERR, name, fmt, ##args)
 1414 
 1415 #define AIRO_FLASH(dev) (((struct airo_info *)dev->ml_priv)->flash)
 1416 
 1417 /***********************************************************************
 1418  *                              MIC ROUTINES                           *
 1419  ***********************************************************************
 1420  */
 1421 
 1422 static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq);
 1423 static void MoveWindow(miccntx *context, u32 micSeq);
 1424 static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen,
 1425 			   struct crypto_cipher *tfm);
 1426 static void emmh32_init(emmh32_context *context);
 1427 static void emmh32_update(emmh32_context *context, u8 *pOctets, int len);
 1428 static void emmh32_final(emmh32_context *context, u8 digest[4]);
 1429 static int flashpchar(struct airo_info *ai,int byte,int dwelltime);
 1430 
 1431 static void age_mic_context(miccntx *cur, miccntx *old, u8 *key, int key_len,
 1432 			    struct crypto_cipher *tfm)
 1433 {
 1434 	/* If the current MIC context is valid and its key is the same as
 1435 	 * the MIC register, there's nothing to do.
 1436 	 */
 1437 	if (cur->valid && (memcmp(cur->key, key, key_len) == 0))
 1438 		return;
 1439 
 1440 	/* Age current mic Context */
 1441 	memcpy(old, cur, sizeof(*cur));
 1442 
 1443 	/* Initialize new context */
 1444 	memcpy(cur->key, key, key_len);
 1445 	cur->window  = 33; /* Window always points to the middle */
 1446 	cur->rx      = 0;  /* Rx Sequence numbers */
 1447 	cur->tx      = 0;  /* Tx sequence numbers */
 1448 	cur->valid   = 1;  /* Key is now valid */
 1449 
 1450 	/* Give key to mic seed */
 1451 	emmh32_setseed(&cur->seed, key, key_len, tfm);
 1452 }
 1453 
 1454 /* micinit - Initialize mic seed */
 1455 
 1456 static void micinit(struct airo_info *ai)
 1457 {
 1458 	MICRid mic_rid;
 1459 
 1460 	clear_bit(JOB_MIC, &ai->jobs);
 1461 	PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0);
 1462 	up(&ai->sem);
 1463 
 1464 	ai->micstats.enabled = (le16_to_cpu(mic_rid.state) & 0x00FF) ? 1 : 0;
 1465 	if (!ai->micstats.enabled) {
 1466 		/* So next time we have a valid key and mic is enabled, we will
 1467 		 * update the sequence number if the key is the same as before.
 1468 		 */
 1469 		ai->mod[0].uCtx.valid = 0;
 1470 		ai->mod[0].mCtx.valid = 0;
 1471 		return;
 1472 	}
 1473 
 1474 	if (mic_rid.multicastValid) {
 1475 		age_mic_context(&ai->mod[0].mCtx, &ai->mod[1].mCtx,
 1476 		                mic_rid.multicast, sizeof(mic_rid.multicast),
 1477 		                ai->tfm);
 1478 	}
 1479 
 1480 	if (mic_rid.unicastValid) {
 1481 		age_mic_context(&ai->mod[0].uCtx, &ai->mod[1].uCtx,
 1482 				mic_rid.unicast, sizeof(mic_rid.unicast),
 1483 				ai->tfm);
 1484 	}
 1485 }
 1486 
 1487 /* micsetup - Get ready for business */
 1488 
 1489 static int micsetup(struct airo_info *ai) {
 1490 	int i;
 1491 
 1492 	if (ai->tfm == NULL)
 1493 	        ai->tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
 1494 
 1495         if (IS_ERR(ai->tfm)) {
 1496                 airo_print_err(ai->dev->name, "failed to load transform for AES");
 1497                 ai->tfm = NULL;
 1498                 return ERROR;
 1499         }
 1500 
 1501 	for (i=0; i < NUM_MODULES; i++) {
 1502 		memset(&ai->mod[i].mCtx,0,sizeof(miccntx));
 1503 		memset(&ai->mod[i].uCtx,0,sizeof(miccntx));
 1504 	}
 1505 	return SUCCESS;
 1506 }
 1507 
 1508 static const u8 micsnap[] = {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02};
 1509 
 1510 /*===========================================================================
 1511  * Description: Mic a packet
 1512  *    
 1513  *      Inputs: etherHead * pointer to an 802.3 frame
 1514  *    
 1515  *     Returns: BOOLEAN if successful, otherwise false.
 1516  *             PacketTxLen will be updated with the mic'd packets size.
 1517  *
 1518  *    Caveats: It is assumed that the frame buffer will already
 1519  *             be big enough to hold the largets mic message possible.
 1520  *            (No memory allocation is done here).
 1521  *  
 1522  *    Author: sbraneky (10/15/01)
 1523  *    Merciless hacks by rwilcher (1/14/02)
 1524  */
 1525 
 1526 static int encapsulate(struct airo_info *ai ,etherHead *frame, MICBuffer *mic, int payLen)
 1527 {
 1528 	miccntx   *context;
 1529 
 1530 	// Determine correct context
 1531 	// If not adhoc, always use unicast key
 1532 
 1533 	if (test_bit(FLAG_ADHOC, &ai->flags) && (frame->da[0] & 0x1))
 1534 		context = &ai->mod[0].mCtx;
 1535 	else
 1536 		context = &ai->mod[0].uCtx;
 1537   
 1538 	if (!context->valid)
 1539 		return ERROR;
 1540 
 1541 	mic->typelen = htons(payLen + 16); //Length of Mic'd packet
 1542 
 1543 	memcpy(&mic->u.snap, micsnap, sizeof(micsnap)); // Add Snap
 1544 
 1545 	// Add Tx sequence
 1546 	mic->seq = htonl(context->tx);
 1547 	context->tx += 2;
 1548 
 1549 	emmh32_init(&context->seed); // Mic the packet
 1550 	emmh32_update(&context->seed,frame->da,ETH_ALEN * 2); // DA,SA
 1551 	emmh32_update(&context->seed,(u8*)&mic->typelen,10); // Type/Length and Snap
 1552 	emmh32_update(&context->seed,(u8*)&mic->seq,sizeof(mic->seq)); //SEQ
 1553 	emmh32_update(&context->seed,(u8*)(frame + 1),payLen); //payload
 1554 	emmh32_final(&context->seed, (u8*)&mic->mic);
 1555 
 1556 	/*    New Type/length ?????????? */
 1557 	mic->typelen = 0; //Let NIC know it could be an oversized packet
 1558 	return SUCCESS;
 1559 }
 1560 
 1561 typedef enum {
 1562     NONE,
 1563     NOMIC,
 1564     NOMICPLUMMED,
 1565     SEQUENCE,
 1566     INCORRECTMIC,
 1567 } mic_error;
 1568 
 1569 /*===========================================================================
 1570  *  Description: Decapsulates a MIC'd packet and returns the 802.3 packet
 1571  *               (removes the MIC stuff) if packet is a valid packet.
 1572  *      
 1573  *       Inputs: etherHead  pointer to the 802.3 packet             
 1574  *     
 1575  *      Returns: BOOLEAN - TRUE if packet should be dropped otherwise FALSE
 1576  *     
 1577  *      Author: sbraneky (10/15/01)
 1578  *    Merciless hacks by rwilcher (1/14/02)
 1579  *---------------------------------------------------------------------------
 1580  */
 1581 
 1582 static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *eth, u16 payLen)
 1583 {
 1584 	int      i;
 1585 	u32      micSEQ;
 1586 	miccntx  *context;
 1587 	u8       digest[4];
 1588 	mic_error micError = NONE;
 1589 
 1590 	// Check if the packet is a Mic'd packet
 1591 
 1592 	if (!ai->micstats.enabled) {
 1593 		//No Mic set or Mic OFF but we received a MIC'd packet.
 1594 		if (memcmp ((u8*)eth + 14, micsnap, sizeof(micsnap)) == 0) {
 1595 			ai->micstats.rxMICPlummed++;
 1596 			return ERROR;
 1597 		}
 1598 		return SUCCESS;
 1599 	}
 1600 
 1601 	if (ntohs(mic->typelen) == 0x888E)
 1602 		return SUCCESS;
 1603 
 1604 	if (memcmp (mic->u.snap, micsnap, sizeof(micsnap)) != 0) {
 1605 	    // Mic enabled but packet isn't Mic'd
 1606 		ai->micstats.rxMICPlummed++;
 1607 	    	return ERROR;
 1608 	}
 1609 
 1610 	micSEQ = ntohl(mic->seq);            //store SEQ as CPU order
 1611 
 1612 	//At this point we a have a mic'd packet and mic is enabled
 1613 	//Now do the mic error checking.
 1614 
 1615 	//Receive seq must be odd
 1616 	if ( (micSEQ & 1) == 0 ) {
 1617 		ai->micstats.rxWrongSequence++;
 1618 		return ERROR;
 1619 	}
 1620 
 1621 	for (i = 0; i < NUM_MODULES; i++) {
 1622 		int mcast = eth->da[0] & 1;
 1623 		//Determine proper context 
 1624 		context = mcast ? &ai->mod[i].mCtx : &ai->mod[i].uCtx;
 1625 	
 1626 		//Make sure context is valid
 1627 		if (!context->valid) {
 1628 			if (i == 0)
 1629 				micError = NOMICPLUMMED;
 1630 			continue;                
 1631 		}
 1632 	       	//DeMic it 
 1633 
 1634 		if (!mic->typelen)
 1635 			mic->typelen = htons(payLen + sizeof(MICBuffer) - 2);
 1636 	
 1637 		emmh32_init(&context->seed);
 1638 		emmh32_update(&context->seed, eth->da, ETH_ALEN*2); 
 1639 		emmh32_update(&context->seed, (u8 *)&mic->typelen, sizeof(mic->typelen)+sizeof(mic->u.snap)); 
 1640 		emmh32_update(&context->seed, (u8 *)&mic->seq,sizeof(mic->seq));	
 1641 		emmh32_update(&context->seed, (u8 *)(eth + 1),payLen);	
 1642 		//Calculate MIC
 1643 		emmh32_final(&context->seed, digest);
 1644 	
 1645 		if (memcmp(digest, &mic->mic, 4)) { //Make sure the mics match
 1646 		  //Invalid Mic
 1647 			if (i == 0)
 1648 				micError = INCORRECTMIC;
 1649 			continue;
 1650 		}
 1651 
 1652 		//Check Sequence number if mics pass
 1653 		if (RxSeqValid(ai, context, mcast, micSEQ) == SUCCESS) {
 1654 			ai->micstats.rxSuccess++;
 1655 			return SUCCESS;
 1656 		}
 1657 		if (i == 0)
 1658 			micError = SEQUENCE;
 1659 	}
 1660 
 1661 	// Update statistics
 1662 	switch (micError) {
 1663 		case NOMICPLUMMED: ai->micstats.rxMICPlummed++;   break;
 1664 		case SEQUENCE:    ai->micstats.rxWrongSequence++; break;
 1665 		case INCORRECTMIC: ai->micstats.rxIncorrectMIC++; break;
 1666 		case NONE:  break;
 1667 		case NOMIC: break;
 1668 	}
 1669 	return ERROR;
 1670 }
 1671 
 1672 /*===========================================================================
 1673  * Description:  Checks the Rx Seq number to make sure it is valid
 1674  *               and hasn't already been received
 1675  *   
 1676  *     Inputs: miccntx - mic context to check seq against
 1677  *             micSeq  - the Mic seq number
 1678  *   
 1679  *    Returns: TRUE if valid otherwise FALSE. 
 1680  *
 1681  *    Author: sbraneky (10/15/01)
 1682  *    Merciless hacks by rwilcher (1/14/02)
 1683  *---------------------------------------------------------------------------
 1684  */
 1685 
 1686 static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq)
 1687 {
 1688 	u32 seq,index;
 1689 
 1690 	//Allow for the ap being rebooted - if it is then use the next 
 1691 	//sequence number of the current sequence number - might go backwards
 1692 
 1693 	if (mcast) {
 1694 		if (test_bit(FLAG_UPDATE_MULTI, &ai->flags)) {
 1695 			clear_bit (FLAG_UPDATE_MULTI, &ai->flags);
 1696 			context->window = (micSeq > 33) ? micSeq : 33;
 1697 			context->rx     = 0;        // Reset rx
 1698 		}
 1699 	} else if (test_bit(FLAG_UPDATE_UNI, &ai->flags)) {
 1700 		clear_bit (FLAG_UPDATE_UNI, &ai->flags);
 1701 		context->window = (micSeq > 33) ? micSeq : 33; // Move window
 1702 		context->rx     = 0;        // Reset rx
 1703 	}
 1704 
 1705 	//Make sequence number relative to START of window
 1706 	seq = micSeq - (context->window - 33);
 1707 
 1708 	//Too old of a SEQ number to check.
 1709 	if ((s32)seq < 0)
 1710 		return ERROR;
 1711     
 1712 	if ( seq > 64 ) {
 1713 		//Window is infinite forward
 1714 		MoveWindow(context,micSeq);
 1715 		return SUCCESS;
 1716 	}
 1717 
 1718 	// We are in the window. Now check the context rx bit to see if it was already sent
 1719 	seq >>= 1;         //divide by 2 because we only have odd numbers
 1720 	index = 1 << seq;  //Get an index number
 1721 
 1722 	if (!(context->rx & index)) {
 1723 		//micSEQ falls inside the window.
 1724 		//Add seqence number to the list of received numbers.
 1725 		context->rx |= index;
 1726 
 1727 		MoveWindow(context,micSeq);
 1728 
 1729 		return SUCCESS;
 1730 	}
 1731 	return ERROR;
 1732 }
 1733 
 1734 static void MoveWindow(miccntx *context, u32 micSeq)
 1735 {
 1736 	u32 shift;
 1737 
 1738 	//Move window if seq greater than the middle of the window
 1739 	if (micSeq > context->window) {
 1740 		shift = (micSeq - context->window) >> 1;
 1741     
 1742 		    //Shift out old
 1743 		if (shift < 32)
 1744 			context->rx >>= shift;
 1745 		else
 1746 			context->rx = 0;
 1747 
 1748 		context->window = micSeq;      //Move window
 1749 	}
 1750 }
 1751 
 1752 /*==============================================*/
 1753 /*========== EMMH ROUTINES  ====================*/
 1754 /*==============================================*/
 1755 
 1756 /* mic accumulate */
 1757 #define MIC_ACCUM(val)	\
 1758 	context->accum += (u64)(val) * context->coeff[coeff_position++];
 1759 
 1760 static unsigned char aes_counter[16];
 1761 
 1762 /* expand the key to fill the MMH coefficient array */
 1763 static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen,
 1764 			   struct crypto_cipher *tfm)
 1765 {
 1766   /* take the keying material, expand if necessary, truncate at 16-bytes */
 1767   /* run through AES counter mode to generate context->coeff[] */
 1768   
 1769 	int i,j;
 1770 	u32 counter;
 1771 	u8 *cipher, plain[16];
 1772 
 1773 	crypto_cipher_setkey(tfm, pkey, 16);
 1774 	counter = 0;
 1775 	for (i = 0; i < ARRAY_SIZE(context->coeff); ) {
 1776 		aes_counter[15] = (u8)(counter >> 0);
 1777 		aes_counter[14] = (u8)(counter >> 8);
 1778 		aes_counter[13] = (u8)(counter >> 16);
 1779 		aes_counter[12] = (u8)(counter >> 24);
 1780 		counter++;
 1781 		memcpy (plain, aes_counter, 16);
 1782 		crypto_cipher_encrypt_one(tfm, plain, plain);
 1783 		cipher = plain;
 1784 		for (j = 0; (j < 16) && (i < ARRAY_SIZE(context->coeff)); ) {
 1785 			context->coeff[i++] = ntohl(*(__be32 *)&cipher[j]);
 1786 			j += 4;
 1787 		}
 1788 	}
 1789 }
 1790 
 1791 /* prepare for calculation of a new mic */
 1792 static void emmh32_init(emmh32_context *context)
 1793 {
 1794 	/* prepare for new mic calculation */
 1795 	context->accum = 0;
 1796 	context->position = 0;
 1797 }
 1798 
 1799 /* add some bytes to the mic calculation */
 1800 static void emmh32_update(emmh32_context *context, u8 *pOctets, int len)
 1801 {
 1802 	int	coeff_position, byte_position;
 1803   
 1804 	if (len == 0) return;
 1805   
 1806 	coeff_position = context->position >> 2;
 1807   
 1808 	/* deal with partial 32-bit word left over from last update */
 1809 	byte_position = context->position & 3;
 1810 	if (byte_position) {
 1811 		/* have a partial word in part to deal with */
 1812 		do {
 1813 			if (len == 0) return;
 1814 			context->part.d8[byte_position++] = *pOctets++;
 1815 			context->position++;
 1816 			len--;
 1817 		} while (byte_position < 4);
 1818 		MIC_ACCUM(ntohl(context->part.d32));
 1819 	}
 1820 
 1821 	/* deal with full 32-bit words */
 1822 	while (len >= 4) {
 1823 		MIC_ACCUM(ntohl(*(__be32 *)pOctets));
 1824 		context->position += 4;
 1825 		pOctets += 4;
 1826 		len -= 4;
 1827 	}
 1828 
 1829 	/* deal with partial 32-bit word that will be left over from this update */
 1830 	byte_position = 0;
 1831 	while (len > 0) {
 1832 		context->part.d8[byte_position++] = *pOctets++;
 1833 		context->position++;
 1834 		len--;
 1835 	}
 1836 }
 1837 
 1838 /* mask used to zero empty bytes for final partial word */
 1839 static u32 mask32[4] = { 0x00000000L, 0xFF000000L, 0xFFFF0000L, 0xFFFFFF00L };
 1840 
 1841 /* calculate the mic */
 1842 static void emmh32_final(emmh32_context *context, u8 digest[4])
 1843 {
 1844 	int	coeff_position, byte_position;
 1845 	u32	val;
 1846   
 1847 	u64 sum, utmp;
 1848 	s64 stmp;
 1849 
 1850 	coeff_position = context->position >> 2;
 1851   
 1852 	/* deal with partial 32-bit word left over from last update */
 1853 	byte_position = context->position & 3;
 1854 	if (byte_position) {
 1855 		/* have a partial word in part to deal with */
 1856 		val = ntohl(context->part.d32);
 1857 		MIC_ACCUM(val & mask32[byte_position]);	/* zero empty bytes */
 1858 	}
 1859 
 1860 	/* reduce the accumulated u64 to a 32-bit MIC */
 1861 	sum = context->accum;
 1862 	stmp = (sum  & 0xffffffffLL) - ((sum >> 32)  * 15);
 1863 	utmp = (stmp & 0xffffffffLL) - ((stmp >> 32) * 15);
 1864 	sum = utmp & 0xffffffffLL;
 1865 	if (utmp > 0x10000000fLL)
 1866 		sum -= 15;
 1867 
 1868 	val = (u32)sum;
 1869 	digest[0] = (val>>24) & 0xFF;
 1870 	digest[1] = (val>>16) & 0xFF;
 1871 	digest[2] = (val>>8) & 0xFF;
 1872 	digest[3] = val & 0xFF;
 1873 }
 1874 
 1875 static int readBSSListRid(struct airo_info *ai, int first,
 1876 		      BSSListRid *list)
 1877 {
 1878 	Cmd cmd;
 1879 	Resp rsp;
 1880 
 1881 	if (first == 1) {
 1882 		if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
 1883 		memset(&cmd, 0, sizeof(cmd));
 1884 		cmd.cmd=CMD_LISTBSS;
 1885 		if (down_interruptible(&ai->sem))
 1886 			return -ERESTARTSYS;
 1887 		ai->list_bss_task = current;
 1888 		issuecommand(ai, &cmd, &rsp);
 1889 		up(&ai->sem);
 1890 		/* Let the command take effect */
 1891 		schedule_timeout_uninterruptible(3 * HZ);
 1892 		ai->list_bss_task = NULL;
 1893 	}
 1894 	return PC4500_readrid(ai, first ? ai->bssListFirst : ai->bssListNext,
 1895 			    list, ai->bssListRidLen, 1);
 1896 }
 1897 
 1898 static int readWepKeyRid(struct airo_info *ai, WepKeyRid *wkr, int temp, int lock)
 1899 {
 1900 	return PC4500_readrid(ai, temp ? RID_WEP_TEMP : RID_WEP_PERM,
 1901 				wkr, sizeof(*wkr), lock);
 1902 }
 1903 
 1904 static int writeWepKeyRid(struct airo_info *ai, WepKeyRid *wkr, int perm, int lock)
 1905 {
 1906 	int rc;
 1907 	rc = PC4500_writerid(ai, RID_WEP_TEMP, wkr, sizeof(*wkr), lock);
 1908 	if (rc!=SUCCESS)
 1909 		airo_print_err(ai->dev->name, "WEP_TEMP set %x", rc);
 1910 	if (perm) {
 1911 		rc = PC4500_writerid(ai, RID_WEP_PERM, wkr, sizeof(*wkr), lock);
 1912 		if (rc!=SUCCESS)
 1913 			airo_print_err(ai->dev->name, "WEP_PERM set %x", rc);
 1914 	}
 1915 	return rc;
 1916 }
 1917 
 1918 static int readSsidRid(struct airo_info*ai, SsidRid *ssidr)
 1919 {
 1920 	return PC4500_readrid(ai, RID_SSID, ssidr, sizeof(*ssidr), 1);
 1921 }
 1922 
 1923 static int writeSsidRid(struct airo_info*ai, SsidRid *pssidr, int lock)
 1924 {
 1925 	return PC4500_writerid(ai, RID_SSID, pssidr, sizeof(*pssidr), lock);
 1926 }
 1927 
 1928 static int readConfigRid(struct airo_info *ai, int lock)
 1929 {
 1930 	int rc;
 1931 	ConfigRid cfg;
 1932 
 1933 	if (ai->config.len)
 1934 		return SUCCESS;
 1935 
 1936 	rc = PC4500_readrid(ai, RID_ACTUALCONFIG, &cfg, sizeof(cfg), lock);
 1937 	if (rc != SUCCESS)
 1938 		return rc;
 1939 
 1940 	ai->config = cfg;
 1941 	return SUCCESS;
 1942 }
 1943 
 1944 static inline void checkThrottle(struct airo_info *ai)
 1945 {
 1946 	int i;
 1947 /* Old hardware had a limit on encryption speed */
 1948 	if (ai->config.authType != AUTH_OPEN && maxencrypt) {
 1949 		for(i=0; i<8; i++) {
 1950 			if (ai->config.rates[i] > maxencrypt) {
 1951 				ai->config.rates[i] = 0;
 1952 			}
 1953 		}
 1954 	}
 1955 }
 1956 
 1957 static int writeConfigRid(struct airo_info *ai, int lock)
 1958 {
 1959 	ConfigRid cfgr;
 1960 
 1961 	if (!test_bit (FLAG_COMMIT, &ai->flags))
 1962 		return SUCCESS;
 1963 
 1964 	clear_bit (FLAG_COMMIT, &ai->flags);
 1965 	clear_bit (FLAG_RESET, &ai->flags);
 1966 	checkThrottle(ai);
 1967 	cfgr = ai->config;
 1968 
 1969 	if ((cfgr.opmode & MODE_CFG_MASK) == MODE_STA_IBSS)
 1970 		set_bit(FLAG_ADHOC, &ai->flags);
 1971 	else
 1972 		clear_bit(FLAG_ADHOC, &ai->flags);
 1973 
 1974 	return PC4500_writerid( ai, RID_CONFIG, &cfgr, sizeof(cfgr), lock);
 1975 }
 1976 
 1977 static int readStatusRid(struct airo_info *ai, StatusRid *statr, int lock)
 1978 {
 1979 	return PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr), lock);
 1980 }
 1981 
 1982 static int writeAPListRid(struct airo_info *ai, APListRid *aplr, int lock)
 1983 {
 1984 	return PC4500_writerid(ai, RID_APLIST, aplr, sizeof(*aplr), lock);
 1985 }
 1986 
 1987 static int readCapabilityRid(struct airo_info *ai, CapabilityRid *capr, int lock)
 1988 {
 1989 	return PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr), lock);
 1990 }
 1991 
 1992 static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock)
 1993 {
 1994 	return PC4500_readrid(ai, rid, sr, sizeof(*sr), lock);
 1995 }
 1996 
 1997 static void try_auto_wep(struct airo_info *ai)
 1998 {
 1999 	if (auto_wep && !test_bit(FLAG_RADIO_DOWN, &ai->flags)) {
 2000 		ai->expires = RUN_AT(3*HZ);
 2001 		wake_up_interruptible(&ai->thr_wait);
 2002 	}
 2003 }
 2004 
 2005 static int airo_open(struct net_device *dev) {
 2006 	struct airo_info *ai = dev->ml_priv;
 2007 	int rc = 0;
 2008 
 2009 	if (test_bit(FLAG_FLASHING, &ai->flags))
 2010 		return -EIO;
 2011 
 2012 	/* Make sure the card is configured.
 2013 	 * Wireless Extensions may postpone config changes until the card
 2014 	 * is open (to pipeline changes and speed-up card setup). If
 2015 	 * those changes are not yet committed, do it now - Jean II */
 2016 	if (test_bit(FLAG_COMMIT, &ai->flags)) {
 2017 		disable_MAC(ai, 1);
 2018 		writeConfigRid(ai, 1);
 2019 	}
 2020 
 2021 	if (ai->wifidev != dev) {
 2022 		clear_bit(JOB_DIE, &ai->jobs);
 2023 		ai->airo_thread_task = kthread_run(airo_thread, dev, "%s",
 2024 						   dev->name);
 2025 		if (IS_ERR(ai->airo_thread_task))
 2026 			return (int)PTR_ERR(ai->airo_thread_task);
 2027 
 2028 		rc = request_irq(dev->irq, airo_interrupt, IRQF_SHARED,
 2029 			dev->name, dev);
 2030 		if (rc) {
 2031 			airo_print_err(dev->name,
 2032 				"register interrupt %d failed, rc %d",
 2033 				dev->irq, rc);
 2034 			set_bit(JOB_DIE, &ai->jobs);
 2035 			kthread_stop(ai->airo_thread_task);
 2036 			return rc;
 2037 		}
 2038 
 2039 		/* Power on the MAC controller (which may have been disabled) */
 2040 		clear_bit(FLAG_RADIO_DOWN, &ai->flags);
 2041 		enable_interrupts(ai);
 2042 
 2043 		try_auto_wep(ai);
 2044 	}
 2045 	enable_MAC(ai, 1);
 2046 
 2047 	netif_start_queue(dev);
 2048 	return 0;
 2049 }
 2050 
 2051 static netdev_tx_t mpi_start_xmit(struct sk_buff *skb,
 2052 					struct net_device *dev)
 2053 {
 2054 	int npacks, pending;
 2055 	unsigned long flags;
 2056 	struct airo_info *ai = dev->ml_priv;
 2057 
 2058 	if (!skb) {
 2059 		airo_print_err(dev->name, "%s: skb == NULL!",__func__);
 2060 		return NETDEV_TX_OK;
 2061 	}
 2062 	npacks = skb_queue_len (&ai->txq);
 2063 
 2064 	if (npacks >= MAXTXQ - 1) {
 2065 		netif_stop_queue (dev);
 2066 		if (npacks > MAXTXQ) {
 2067 			dev->stats.tx_fifo_errors++;
 2068 			return NETDEV_TX_BUSY;
 2069 		}
 2070 		skb_queue_tail (&ai->txq, skb);
 2071 		return NETDEV_TX_OK;
 2072 	}
 2073 
 2074 	spin_lock_irqsave(&ai->aux_lock, flags);
 2075 	skb_queue_tail (&ai->txq, skb);
 2076 	pending = test_bit(FLAG_PENDING_XMIT, &ai->flags);
 2077 	spin_unlock_irqrestore(&ai->aux_lock,flags);
 2078 	netif_wake_queue (dev);
 2079 
 2080 	if (pending == 0) {
 2081 		set_bit(FLAG_PENDING_XMIT, &ai->flags);
 2082 		mpi_send_packet (dev);
 2083 	}
 2084 	return NETDEV_TX_OK;
 2085 }
 2086 
 2087 /*
 2088  * @mpi_send_packet
 2089  *
 2090  * Attempt to transmit a packet. Can be called from interrupt
 2091  * or transmit . return number of packets we tried to send
 2092  */
 2093 
 2094 static int mpi_send_packet (struct net_device *dev)
 2095 {
 2096 	struct sk_buff *skb;
 2097 	unsigned char *buffer;
 2098 	s16 len;
 2099 	__le16 *payloadLen;
 2100 	struct airo_info *ai = dev->ml_priv;
 2101 	u8 *sendbuf;
 2102 
 2103 	/* get a packet to send */
 2104 
 2105 	if ((skb = skb_dequeue(&ai->txq)) == NULL) {
 2106 		airo_print_err(dev->name,
 2107 			"%s: Dequeue'd zero in send_packet()",
 2108 			__func__);
 2109 		return 0;
 2110 	}
 2111 
 2112 	/* check min length*/
 2113 	len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
 2114 	buffer = skb->data;
 2115 
 2116 	ai->txfids[0].tx_desc.offset = 0;
 2117 	ai->txfids[0].tx_desc.valid = 1;
 2118 	ai->txfids[0].tx_desc.eoc = 1;
 2119 	ai->txfids[0].tx_desc.len =len+sizeof(WifiHdr);
 2120 
 2121 /*
 2122  * Magic, the cards firmware needs a length count (2 bytes) in the host buffer
 2123  * right after  TXFID_HDR.The TXFID_HDR contains the status short so payloadlen
 2124  * is immediately after it. ------------------------------------------------
 2125  *                         |TXFIDHDR+STATUS|PAYLOADLEN|802.3HDR|PACKETDATA|
 2126  *                         ------------------------------------------------
 2127  */
 2128 
 2129 	memcpy(ai->txfids[0].virtual_host_addr,
 2130 		(char *)&wifictlhdr8023, sizeof(wifictlhdr8023));
 2131 
 2132 	payloadLen = (__le16 *)(ai->txfids[0].virtual_host_addr +
 2133 		sizeof(wifictlhdr8023));
 2134 	sendbuf = ai->txfids[0].virtual_host_addr +
 2135 		sizeof(wifictlhdr8023) + 2 ;
 2136 
 2137 	/*
 2138 	 * Firmware automatically puts 802 header on so
 2139 	 * we don't need to account for it in the length
 2140 	 */
 2141 	if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled &&
 2142 		(ntohs(((__be16 *)buffer)[6]) != 0x888E)) {
 2143 		MICBuffer pMic;
 2144 
 2145 		if (encapsulate(ai, (etherHead *)buffer, &pMic, len - sizeof(etherHead)) != SUCCESS)
 2146 			return ERROR;
 2147 
 2148 		*payloadLen = cpu_to_le16(len-sizeof(etherHead)+sizeof(pMic));
 2149 		ai->txfids[0].tx_desc.len += sizeof(pMic);
 2150 		/* copy data into airo dma buffer */
 2151 		memcpy (sendbuf, buffer, sizeof(etherHead));
 2152 		buffer += sizeof(etherHead);
 2153 		sendbuf += sizeof(etherHead);
 2154 		memcpy (sendbuf, &pMic, sizeof(pMic));
 2155 		sendbuf += sizeof(pMic);
 2156 		memcpy (sendbuf, buffer, len - sizeof(etherHead));
 2157 	} else {
 2158 		*payloadLen = cpu_to_le16(len - sizeof(etherHead));
 2159 
 2160 		dev->trans_start = jiffies;
 2161 
 2162 		/* copy data into airo dma buffer */
 2163 		memcpy(sendbuf, buffer, len);
 2164 	}
 2165 
 2166 	memcpy_toio(ai->txfids[0].card_ram_off,
 2167 		&ai->txfids[0].tx_desc, sizeof(TxFid));
 2168 
 2169 	OUT4500(ai, EVACK, 8);
 2170 
 2171 	dev_kfree_skb_any(skb);
 2172 	return 1;
 2173 }
 2174 
 2175 static void get_tx_error(struct airo_info *ai, s32 fid)
 2176 {
 2177 	__le16 status;
 2178 
 2179 	if (fid < 0)
 2180 		status = ((WifiCtlHdr *)ai->txfids[0].virtual_host_addr)->ctlhdr.status;
 2181 	else {
 2182 		if (bap_setup(ai, ai->fids[fid] & 0xffff, 4, BAP0) != SUCCESS)
 2183 			return;
 2184 		bap_read(ai, &status, 2, BAP0);
 2185 	}
 2186 	if (le16_to_cpu(status) & 2) /* Too many retries */
 2187 		ai->dev->stats.tx_aborted_errors++;
 2188 	if (le16_to_cpu(status) & 4) /* Transmit lifetime exceeded */
 2189 		ai->dev->stats.tx_heartbeat_errors++;
 2190 	if (le16_to_cpu(status) & 8) /* Aid fail */
 2191 		{ }
 2192 	if (le16_to_cpu(status) & 0x10) /* MAC disabled */
 2193 		ai->dev->stats.tx_carrier_errors++;
 2194 	if (le16_to_cpu(status) & 0x20) /* Association lost */
 2195 		{ }
 2196 	/* We produce a TXDROP event only for retry or lifetime
 2197 	 * exceeded, because that's the only status that really mean
 2198 	 * that this particular node went away.
 2199 	 * Other errors means that *we* screwed up. - Jean II */
 2200 	if ((le16_to_cpu(status) & 2) ||
 2201 	     (le16_to_cpu(status) & 4)) {
 2202 		union iwreq_data	wrqu;
 2203 		char junk[0x18];
 2204 
 2205 		/* Faster to skip over useless data than to do
 2206 		 * another bap_setup(). We are at offset 0x6 and
 2207 		 * need to go to 0x18 and read 6 bytes - Jean II */
 2208 		bap_read(ai, (__le16 *) junk, 0x18, BAP0);
 2209 
 2210 		/* Copy 802.11 dest address.
 2211 		 * We use the 802.11 header because the frame may
 2212 		 * not be 802.3 or may be mangled...
 2213 		 * In Ad-Hoc mode, it will be the node address.
 2214 		 * In managed mode, it will be most likely the AP addr
 2215 		 * User space will figure out how to convert it to
 2216 		 * whatever it needs (IP address or else).
 2217 		 * - Jean II */
 2218 		memcpy(wrqu.addr.sa_data, junk + 0x12, ETH_ALEN);
 2219 		wrqu.addr.sa_family = ARPHRD_ETHER;
 2220 
 2221 		/* Send event to user space */
 2222 		wireless_send_event(ai->dev, IWEVTXDROP, &wrqu, NULL);
 2223 	}
 2224 }
 2225 
 2226 static void airo_end_xmit(struct net_device *dev) {
 2227 	u16 status;
 2228 	int i;
 2229 	struct airo_info *priv = dev->ml_priv;
 2230 	struct sk_buff *skb = priv->xmit.skb;
 2231 	int fid = priv->xmit.fid;
 2232 	u32 *fids = priv->fids;
 2233 
 2234 	clear_bit(JOB_XMIT, &priv->jobs);
 2235 	clear_bit(FLAG_PENDING_XMIT, &priv->flags);
 2236 	status = transmit_802_3_packet (priv, fids[fid], skb->data);
 2237 	up(&priv->sem);
 2238 
 2239 	i = 0;
 2240 	if ( status == SUCCESS ) {
 2241 		dev->trans_start = jiffies;
 2242 		for (; i < MAX_FIDS / 2 && (priv->fids[i] & 0xffff0000); i++);
 2243 	} else {
 2244 		priv->fids[fid] &= 0xffff;
 2245 		dev->stats.tx_window_errors++;
 2246 	}
 2247 	if (i < MAX_FIDS / 2)
 2248 		netif_wake_queue(dev);
 2249 	dev_kfree_skb(skb);
 2250 }
 2251 
 2252 static netdev_tx_t airo_start_xmit(struct sk_buff *skb,
 2253 					 struct net_device *dev)
 2254 {
 2255 	s16 len;
 2256 	int i, j;
 2257 	struct airo_info *priv = dev->ml_priv;
 2258 	u32 *fids = priv->fids;
 2259 
 2260 	if ( skb == NULL ) {
 2261 		airo_print_err(dev->name, "%s: skb == NULL!", __func__);
 2262 		return NETDEV_TX_OK;
 2263 	}
 2264 
 2265 	/* Find a vacant FID */
 2266 	for( i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++ );
 2267 	for( j = i + 1; j < MAX_FIDS / 2 && (fids[j] & 0xffff0000); j++ );
 2268 
 2269 	if ( j >= MAX_FIDS / 2 ) {
 2270 		netif_stop_queue(dev);
 2271 
 2272 		if (i == MAX_FIDS / 2) {
 2273 			dev->stats.tx_fifo_errors++;
 2274 			return NETDEV_TX_BUSY;
 2275 		}
 2276 	}
 2277 	/* check min length*/
 2278 	len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
 2279         /* Mark fid as used & save length for later */
 2280 	fids[i] |= (len << 16);
 2281 	priv->xmit.skb = skb;
 2282 	priv->xmit.fid = i;
 2283 	if (down_trylock(&priv->sem) != 0) {
 2284 		set_bit(FLAG_PENDING_XMIT, &priv->flags);
 2285 		netif_stop_queue(dev);
 2286 		set_bit(JOB_XMIT, &priv->jobs);
 2287 		wake_up_interruptible(&priv->thr_wait);
 2288 	} else
 2289 		airo_end_xmit(dev);
 2290 	return NETDEV_TX_OK;
 2291 }
 2292 
 2293 static void airo_end_xmit11(struct net_device *dev) {
 2294 	u16 status;
 2295 	int i;
 2296 	struct airo_info *priv = dev->ml_priv;
 2297 	struct sk_buff *skb = priv->xmit11.skb;
 2298 	int fid = priv->xmit11.fid;
 2299 	u32 *fids = priv->fids;
 2300 
 2301 	clear_bit(JOB_XMIT11, &priv->jobs);
 2302 	clear_bit(FLAG_PENDING_XMIT11, &priv->flags);
 2303 	status = transmit_802_11_packet (priv, fids[fid], skb->data);
 2304 	up(&priv->sem);
 2305 
 2306 	i = MAX_FIDS / 2;
 2307 	if ( status == SUCCESS ) {
 2308 		dev->trans_start = jiffies;
 2309 		for (; i < MAX_FIDS && (priv->fids[i] & 0xffff0000); i++);
 2310 	} else {
 2311 		priv->fids[fid] &= 0xffff;
 2312 		dev->stats.tx_window_errors++;
 2313 	}
 2314 	if (i < MAX_FIDS)
 2315 		netif_wake_queue(dev);
 2316 	dev_kfree_skb(skb);
 2317 }
 2318 
 2319 static netdev_tx_t airo_start_xmit11(struct sk_buff *skb,
 2320 					   struct net_device *dev)
 2321 {
 2322 	s16 len;
 2323 	int i, j;
 2324 	struct airo_info *priv = dev->ml_priv;
 2325 	u32 *fids = priv->fids;
 2326 
 2327 	if (test_bit(FLAG_MPI, &priv->flags)) {
 2328 		/* Not implemented yet for MPI350 */
 2329 		netif_stop_queue(dev);
 2330 		dev_kfree_skb_any(skb);
 2331 		return NETDEV_TX_OK;
 2332 	}
 2333 
 2334 	if ( skb == NULL ) {
 2335 		airo_print_err(dev->name, "%s: skb == NULL!", __func__);
 2336 		return NETDEV_TX_OK;
 2337 	}
 2338 
 2339 	/* Find a vacant FID */
 2340 	for( i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++ );
 2341 	for( j = i + 1; j < MAX_FIDS && (fids[j] & 0xffff0000); j++ );
 2342 
 2343 	if ( j >= MAX_FIDS ) {
 2344 		netif_stop_queue(dev);
 2345 
 2346 		if (i == MAX_FIDS) {
 2347 			dev->stats.tx_fifo_errors++;
 2348 			return NETDEV_TX_BUSY;
 2349 		}
 2350 	}
 2351 	/* check min length*/
 2352 	len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
 2353         /* Mark fid as used & save length for later */
 2354 	fids[i] |= (len << 16);
 2355 	priv->xmit11.skb = skb;
 2356 	priv->xmit11.fid = i;
 2357 	if (down_trylock(&priv->sem) != 0) {
 2358 		set_bit(FLAG_PENDING_XMIT11, &priv->flags);
 2359 		netif_stop_queue(dev);
 2360 		set_bit(JOB_XMIT11, &priv->jobs);
 2361 		wake_up_interruptible(&priv->thr_wait);
 2362 	} else
 2363 		airo_end_xmit11(dev);
 2364 	return NETDEV_TX_OK;
 2365 }
 2366 
 2367 static void airo_read_stats(struct net_device *dev)
 2368 {
 2369 	struct airo_info *ai = dev->ml_priv;
 2370 	StatsRid stats_rid;
 2371 	__le32 *vals = stats_rid.vals;
 2372 
 2373 	clear_bit(JOB_STATS, &ai->jobs);
 2374 	if (ai->power.event) {
 2375 		up(&ai->sem);
 2376 		return;
 2377 	}
 2378 	readStatsRid(ai, &stats_rid, RID_STATS, 0);
 2379 	up(&ai->sem);
 2380 
 2381 	dev->stats.rx_packets = le32_to_cpu(vals[43]) + le32_to_cpu(vals[44]) +
 2382 			       le32_to_cpu(vals[45]);
 2383 	dev->stats.tx_packets = le32_to_cpu(vals[39]) + le32_to_cpu(vals[40]) +
 2384 			       le32_to_cpu(vals[41]);
 2385 	dev->stats.rx_bytes = le32_to_cpu(vals[92]);
 2386 	dev->stats.tx_bytes = le32_to_cpu(vals[91]);
 2387 	dev->stats.rx_errors = le32_to_cpu(vals[0]) + le32_to_cpu(vals[2]) +
 2388 			      le32_to_cpu(vals[3]) + le32_to_cpu(vals[4]);
 2389 	dev->stats.tx_errors = le32_to_cpu(vals[42]) +
 2390 			      dev->stats.tx_fifo_errors;
 2391 	dev->stats.multicast = le32_to_cpu(vals[43]);
 2392 	dev->stats.collisions = le32_to_cpu(vals[89]);
 2393 
 2394 	/* detailed rx_errors: */
 2395 	dev->stats.rx_length_errors = le32_to_cpu(vals[3]);
 2396 	dev->stats.rx_crc_errors = le32_to_cpu(vals[4]);
 2397 	dev->stats.rx_frame_errors = le32_to_cpu(vals[2]);
 2398 	dev->stats.rx_fifo_errors = le32_to_cpu(vals[0]);
 2399 }
 2400 
 2401 static struct net_device_stats *airo_get_stats(struct net_device *dev)
 2402 {
 2403 	struct airo_info *local =  dev->ml_priv;
 2404 
 2405 	if (!test_bit(JOB_STATS, &local->jobs)) {
 2406 		/* Get stats out of the card if available */
 2407 		if (down_trylock(&local->sem) != 0) {
 2408 			set_bit(JOB_STATS, &local->jobs);
 2409 			wake_up_interruptible(&local->thr_wait);
 2410 		} else
 2411 			airo_read_stats(dev);
 2412 	}
 2413 
 2414 	return &dev->stats;
 2415 }
 2416 
 2417 static void airo_set_promisc(struct airo_info *ai) {
 2418 	Cmd cmd;
 2419 	Resp rsp;
 2420 
 2421 	memset(&cmd, 0, sizeof(cmd));
 2422 	cmd.cmd=CMD_SETMODE;
 2423 	clear_bit(JOB_PROMISC, &ai->jobs);
 2424 	cmd.parm0=(ai->flags&IFF_PROMISC) ? PROMISC : NOPROMISC;
 2425 	issuecommand(ai, &cmd, &rsp);
 2426 	up(&ai->sem);
 2427 }
 2428 
 2429 static void airo_set_multicast_list(struct net_device *dev) {
 2430 	struct airo_info *ai = dev->ml_priv;
 2431 
 2432 	if ((dev->flags ^ ai->flags) & IFF_PROMISC) {
 2433 		change_bit(FLAG_PROMISC, &ai->flags);
 2434 		if (down_trylock(&ai->sem) != 0) {
 2435 			set_bit(JOB_PROMISC, &ai->jobs);
 2436 			wake_up_interruptible(&ai->thr_wait);
 2437 		} else
 2438 			airo_set_promisc(ai);
 2439 	}
 2440 
 2441 	if ((dev->flags&IFF_ALLMULTI) || !netdev_mc_empty(dev)) {
 2442 		/* Turn on multicast.  (Should be already setup...) */
 2443 	}
 2444 }
 2445 
 2446 static int airo_set_mac_address(struct net_device *dev, void *p)
 2447 {
 2448 	struct airo_info *ai = dev->ml_priv;
 2449 	struct sockaddr *addr = p;
 2450 
 2451 	readConfigRid(ai, 1);
 2452 	memcpy (ai->config.macAddr, addr->sa_data, dev->addr_len);
 2453 	set_bit (FLAG_COMMIT, &ai->flags);
 2454 	disable_MAC(ai, 1);
 2455 	writeConfigRid (ai, 1);
 2456 	enable_MAC(ai, 1);
 2457 	memcpy (ai->dev->dev_addr, addr->sa_data, dev->addr_len);
 2458 	if (ai->wifidev)
 2459 		memcpy (ai->wifidev->dev_addr, addr->sa_data, dev->addr_len);
 2460 	return 0;
 2461 }
 2462 
 2463 static int airo_change_mtu(struct net_device *dev, int new_mtu)
 2464 {
 2465 	if ((new_mtu < 68) || (new_mtu > 2400))
 2466 		return -EINVAL;
 2467 	dev->mtu = new_mtu;
 2468 	return 0;
 2469 }
 2470 
 2471 static LIST_HEAD(airo_devices);
 2472 
 2473 static void add_airo_dev(struct airo_info *ai)
 2474 {
 2475 	/* Upper layers already keep track of PCI devices,
 2476 	 * so we only need to remember our non-PCI cards. */
 2477 	if (!ai->pci)
 2478 		list_add_tail(&ai->dev_list, &airo_devices);
 2479 }
 2480 
 2481 static void del_airo_dev(struct airo_info *ai)
 2482 {
 2483 	if (!ai->pci)
 2484 		list_del(&ai->dev_list);
 2485 }
 2486 
 2487 static int airo_close(struct net_device *dev) {
 2488 	struct airo_info *ai = dev->ml_priv;
 2489 
 2490 	netif_stop_queue(dev);
 2491 
 2492 	if (ai->wifidev != dev) {
 2493 #ifdef POWER_ON_DOWN
 2494 		/* Shut power to the card. The idea is that the user can save
 2495 		 * power when he doesn't need the card with "ifconfig down".
 2496 		 * That's the method that is most friendly towards the network
 2497 		 * stack (i.e. the network stack won't try to broadcast
 2498 		 * anything on the interface and routes are gone. Jean II */
 2499 		set_bit(FLAG_RADIO_DOWN, &ai->flags);
 2500 		disable_MAC(ai, 1);
 2501 #endif
 2502 		disable_interrupts( ai );
 2503 
 2504 		free_irq(dev->irq, dev);
 2505 
 2506 		set_bit(JOB_DIE, &ai->jobs);
 2507 		kthread_stop(ai->airo_thread_task);
 2508 	}
 2509 	return 0;
 2510 }
 2511 
 2512 void stop_airo_card( struct net_device *dev, int freeres )
 2513 {
 2514 	struct airo_info *ai = dev->ml_priv;
 2515 
 2516 	set_bit(FLAG_RADIO_DOWN, &ai->flags);
 2517 	disable_MAC(ai, 1);
 2518 	disable_interrupts(ai);
 2519 	takedown_proc_entry( dev, ai );
 2520 	if (test_bit(FLAG_REGISTERED, &ai->flags)) {
 2521 		unregister_netdev( dev );
 2522 		if (ai->wifidev) {
 2523 			unregister_netdev(ai->wifidev);
 2524 			free_netdev(ai->wifidev);
 2525 			ai->wifidev = NULL;
 2526 		}
 2527 		clear_bit(FLAG_REGISTERED, &ai->flags);
 2528 	}
 2529 	/*
 2530 	 * Clean out tx queue
 2531 	 */
 2532 	if (test_bit(FLAG_MPI, &ai->flags) && !skb_queue_empty(&ai->txq)) {
 2533 		struct sk_buff *skb = NULL;
 2534 		for (;(skb = skb_dequeue(&ai->txq));)
 2535 			dev_kfree_skb(skb);
 2536 	}
 2537 
 2538 	airo_networks_free (ai);
 2539 
 2540 	kfree(ai->flash);
 2541 	kfree(ai->rssi);
 2542 	kfree(ai->SSID);
 2543 	if (freeres) {
 2544 		/* PCMCIA frees this stuff, so only for PCI and ISA */
 2545 	        release_region( dev->base_addr, 64 );
 2546 		if (test_bit(FLAG_MPI, &ai->flags)) {
 2547 			if (ai->pci)
 2548 				mpi_unmap_card(ai->pci);
 2549 			if (ai->pcimem)
 2550 				iounmap(ai->pcimem);
 2551 			if (ai->pciaux)
 2552 				iounmap(ai->pciaux);
 2553 			pci_free_consistent(ai->pci, PCI_SHARED_LEN,
 2554 				ai->shared, ai->shared_dma);
 2555 		}
 2556         }
 2557 	crypto_free_cipher(ai->tfm);
 2558 	del_airo_dev(ai);
 2559 	free_netdev( dev );
 2560 }
 2561 
 2562 EXPORT_SYMBOL(stop_airo_card);
 2563 
 2564 static int wll_header_parse(const struct sk_buff *skb, unsigned char *haddr)
 2565 {
 2566 	memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN);
 2567 	return ETH_ALEN;
 2568 }
 2569 
 2570 static void mpi_unmap_card(struct pci_dev *pci)
 2571 {
 2572 	unsigned long mem_start = pci_resource_start(pci, 1);
 2573 	unsigned long mem_len = pci_resource_len(pci, 1);
 2574 	unsigned long aux_start = pci_resource_start(pci, 2);
 2575 	unsigned long aux_len = AUXMEMSIZE;
 2576 
 2577 	release_mem_region(aux_start, aux_len);
 2578 	release_mem_region(mem_start, mem_len);
 2579 }
 2580 
 2581 /*************************************************************
 2582  *  This routine assumes that descriptors have been setup .
 2583  *  Run at insmod time or after reset  when the decriptors
 2584  *  have been initialized . Returns 0 if all is well nz
 2585  *  otherwise . Does not allocate memory but sets up card
 2586  *  using previously allocated descriptors.
 2587  */
 2588 static int mpi_init_descriptors (struct airo_info *ai)
 2589 {
 2590 	Cmd cmd;
 2591 	Resp rsp;
 2592 	int i;
 2593 	int rc = SUCCESS;
 2594 
 2595 	/* Alloc  card RX descriptors */
 2596 	netif_stop_queue(ai->dev);
 2597 
 2598 	memset(&rsp,0,sizeof(rsp));
 2599 	memset(&cmd,0,sizeof(cmd));
 2600 
 2601 	cmd.cmd = CMD_ALLOCATEAUX;
 2602 	cmd.parm0 = FID_RX;
 2603 	cmd.parm1 = (ai->rxfids[0].card_ram_off - ai->pciaux);
 2604 	cmd.parm2 = MPI_MAX_FIDS;
 2605 	rc=issuecommand(ai, &cmd, &rsp);
 2606 	if (rc != SUCCESS) {
 2607 		airo_print_err(ai->dev->name, "Couldn't allocate RX FID");
 2608 		return rc;
 2609 	}
 2610 
 2611 	for (i=0; i<MPI_MAX_FIDS; i++) {
 2612 		memcpy_toio(ai->rxfids[i].card_ram_off,
 2613 			&ai->rxfids[i].rx_desc, sizeof(RxFid));
 2614 	}
 2615 
 2616 	/* Alloc card TX descriptors */
 2617 
 2618 	memset(&rsp,0,sizeof(rsp));
 2619 	memset(&cmd,0,sizeof(cmd));
 2620 
 2621 	cmd.cmd = CMD_ALLOCATEAUX;
 2622 	cmd.parm0 = FID_TX;
 2623 	cmd.parm1 = (ai->txfids[0].card_ram_off - ai->pciaux);
 2624 	cmd.parm2 = MPI_MAX_FIDS;
 2625 
 2626 	for (i=0; i<MPI_MAX_FIDS; i++) {
 2627 		ai->txfids[i].tx_desc.valid = 1;
 2628 		memcpy_toio(ai->txfids[i].card_ram_off,
 2629 			&ai->txfids[i].tx_desc, sizeof(TxFid));
 2630 	}
 2631 	ai->txfids[i-1].tx_desc.eoc = 1; /* Last descriptor has EOC set */
 2632 
 2633 	rc=issuecommand(ai, &cmd, &rsp);
 2634 	if (rc != SUCCESS) {
 2635 		airo_print_err(ai->dev->name, "Couldn't allocate TX FID");
 2636 		return rc;
 2637 	}
 2638 
 2639 	/* Alloc card Rid descriptor */
 2640 	memset(&rsp,0,sizeof(rsp));
 2641 	memset(&cmd,0,sizeof(cmd));
 2642 
 2643 	cmd.cmd = CMD_ALLOCATEAUX;
 2644 	cmd.parm0 = RID_RW;
 2645 	cmd.parm1 = (ai->config_desc.card_ram_off - ai->pciaux);
 2646 	cmd.parm2 = 1; /* Magic number... */
 2647 	rc=issuecommand(ai, &cmd, &rsp);
 2648 	if (rc != SUCCESS) {
 2649 		airo_print_err(ai->dev->name, "Couldn't allocate RID");
 2650 		return rc;
 2651 	}
 2652 
 2653 	memcpy_toio(ai->config_desc.card_ram_off,
 2654 		&ai->config_desc.rid_desc, sizeof(Rid));
 2655 
 2656 	return rc;
 2657 }
 2658 
 2659 /*
 2660  * We are setting up three things here:
 2661  * 1) Map AUX memory for descriptors: Rid, TxFid, or RxFid.
 2662  * 2) Map PCI memory for issuing commands.
 2663  * 3) Allocate memory (shared) to send and receive ethernet frames.
 2664  */
 2665 static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci)
 2666 {
 2667 	unsigned long mem_start, mem_len, aux_start, aux_len;
 2668 	int rc = -1;
 2669 	int i;
 2670 	dma_addr_t busaddroff;
 2671 	unsigned char *vpackoff;
 2672 	unsigned char __iomem *pciaddroff;
 2673 
 2674 	mem_start = pci_resource_start(pci, 1);
 2675 	mem_len = pci_resource_len(pci, 1);
 2676 	aux_start = pci_resource_start(pci, 2);
 2677 	aux_len = AUXMEMSIZE;
 2678 
 2679 	if (!request_mem_region(mem_start, mem_len, DRV_NAME)) {
 2680 		airo_print_err("", "Couldn't get region %x[%x]",
 2681 			(int)mem_start, (int)mem_len);
 2682 		goto out;
 2683 	}
 2684 	if (!request_mem_region(aux_start, aux_len, DRV_NAME)) {
 2685 		airo_print_err("", "Couldn't get region %x[%x]",
 2686 			(int)aux_start, (int)aux_len);
 2687 		goto free_region1;
 2688 	}
 2689 
 2690 	ai->pcimem = ioremap(mem_start, mem_len);
 2691 	if (!ai->pcimem) {
 2692 		airo_print_err("", "Couldn't map region %x[%x]",
 2693 			(int)mem_start, (int)mem_len);
 2694 		goto free_region2;
 2695 	}
 2696 	ai->pciaux = ioremap(aux_start, aux_len);
 2697 	if (!ai->pciaux) {
 2698 		airo_print_err("", "Couldn't map region %x[%x]",
 2699 			(int)aux_start, (int)aux_len);
 2700 		goto free_memmap;
 2701 	}
 2702 
 2703 	/* Reserve PKTSIZE for each fid and 2K for the Rids */
 2704 	ai->shared = pci_alloc_consistent(pci, PCI_SHARED_LEN, &ai->shared_dma);
 2705 	if (!ai->shared) {
 2706 		airo_print_err("", "Couldn't alloc_consistent %d",
 2707 			PCI_SHARED_LEN);
 2708 		goto free_auxmap;
 2709 	}
 2710 
 2711 	/*
 2712 	 * Setup descriptor RX, TX, CONFIG
 2713 	 */
 2714 	busaddroff = ai->shared_dma;
 2715 	pciaddroff = ai->pciaux + AUX_OFFSET;
 2716 	vpackoff   = ai->shared;
 2717 
 2718 	/* RX descriptor setup */
 2719 	for(i = 0; i < MPI_MAX_FIDS; i++) {
 2720 		ai->rxfids[i].pending = 0;
 2721 		ai->rxfids[i].card_ram_off = pciaddroff;
 2722 		ai->rxfids[i].virtual_host_addr = vpackoff;
 2723 		ai->rxfids[i].rx_desc.host_addr = busaddroff;
 2724 		ai->rxfids[i].rx_desc.valid = 1;
 2725 		ai->rxfids[i].rx_desc.len = PKTSIZE;
 2726 		ai->rxfids[i].rx_desc.rdy = 0;
 2727 
 2728 		pciaddroff += sizeof(RxFid);
 2729 		busaddroff += PKTSIZE;
 2730 		vpackoff   += PKTSIZE;
 2731 	}
 2732 
 2733 	/* TX descriptor setup */
 2734 	for(i = 0; i < MPI_MAX_FIDS; i++) {
 2735 		ai->txfids[i].card_ram_off = pciaddroff;
 2736 		ai->txfids[i].virtual_host_addr = vpackoff;
 2737 		ai->txfids[i].tx_desc.valid = 1;
 2738 		ai->txfids[i].tx_desc.host_addr = busaddroff;
 2739 		memcpy(ai->txfids[i].virtual_host_addr,
 2740 			&wifictlhdr8023, sizeof(wifictlhdr8023));
 2741 
 2742 		pciaddroff += sizeof(TxFid);
 2743 		busaddroff += PKTSIZE;
 2744 		vpackoff   += PKTSIZE;
 2745 	}
 2746 	ai->txfids[i-1].tx_desc.eoc = 1; /* Last descriptor has EOC set */
 2747 
 2748 	/* Rid descriptor setup */
 2749 	ai->config_desc.card_ram_off = pciaddroff;
 2750 	ai->config_desc.virtual_host_addr = vpackoff;
 2751 	ai->config_desc.rid_desc.host_addr = busaddroff;
 2752 	ai->ridbus = busaddroff;
 2753 	ai->config_desc.rid_desc.rid = 0;
 2754 	ai->config_desc.rid_desc.len = RIDSIZE;
 2755 	ai->config_desc.rid_desc.valid = 1;
 2756 	pciaddroff += sizeof(Rid);
 2757 	busaddroff += RIDSIZE;
 2758 	vpackoff   += RIDSIZE;
 2759 
 2760 	/* Tell card about descriptors */
 2761 	if (mpi_init_descriptors (ai) != SUCCESS)
 2762 		goto free_shared;
 2763 
 2764 	return 0;
 2765  free_shared:
 2766 	pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma);
 2767  free_auxmap:
 2768 	iounmap(ai->pciaux);
 2769  free_memmap:
 2770 	iounmap(ai->pcimem);
 2771  free_region2:
 2772 	release_mem_region(aux_start, aux_len);
 2773  free_region1:
 2774 	release_mem_region(mem_start, mem_len);
 2775  out:
 2776 	return rc;
 2777 }
 2778 
 2779 static const struct header_ops airo_header_ops = {
 2780 	.parse = wll_header_parse,
 2781 };
 2782 
 2783 static const struct net_device_ops airo11_netdev_ops = {
 2784 	.ndo_open 		= airo_open,
 2785 	.ndo_stop 		= airo_close,
 2786 	.ndo_start_xmit 	= airo_start_xmit11,
 2787 	.ndo_get_stats 		= airo_get_stats,
 2788 	.ndo_set_mac_address	= airo_set_mac_address,
 2789 	.ndo_do_ioctl		= airo_ioctl,
 2790 	.ndo_change_mtu		= airo_change_mtu,
 2791 };
 2792 
 2793 static void wifi_setup(struct net_device *dev)
 2794 {
 2795 	dev->netdev_ops = &airo11_netdev_ops;
 2796 	dev->header_ops = &airo_header_ops;
 2797 	dev->wireless_handlers = &airo_handler_def;
 2798 
 2799 	dev->type               = ARPHRD_IEEE80211;
 2800 	dev->hard_header_len    = ETH_HLEN;
 2801 	dev->mtu                = AIRO_DEF_MTU;
 2802 	dev->addr_len           = ETH_ALEN;
 2803 	dev->tx_queue_len       = 100; 
 2804 
 2805 	eth_broadcast_addr(dev->broadcast);
 2806 
 2807 	dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
 2808 }
 2809 
 2810 static struct net_device *init_wifidev(struct airo_info *ai,
 2811 					struct net_device *ethdev)
 2812 {
 2813 	int err;
 2814 	struct net_device *dev = alloc_netdev(0, "wifi%d", NET_NAME_UNKNOWN,
 2815 					      wifi_setup);
 2816 	if (!dev)
 2817 		return NULL;
 2818 	dev->ml_priv = ethdev->ml_priv;
 2819 	dev->irq = ethdev->irq;
 2820 	dev->base_addr = ethdev->base_addr;
 2821 	dev->wireless_data = ethdev->wireless_data;
 2822 	SET_NETDEV_DEV(dev, ethdev->dev.parent);
 2823 	eth_hw_addr_inherit(dev, ethdev);
 2824 	err = register_netdev(dev);
 2825 	if (err<0) {
 2826 		free_netdev(dev);
 2827 		return NULL;
 2828 	}
 2829 	return dev;
 2830 }
 2831 
 2832 static int reset_card( struct net_device *dev , int lock) {
 2833 	struct airo_info *ai = dev->ml_priv;
 2834 
 2835 	if (lock && down_interruptible(&ai->sem))
 2836 		return -1;
 2837 	waitbusy (ai);
 2838 	OUT4500(ai,COMMAND,CMD_SOFTRESET);
 2839 	msleep(200);
 2840 	waitbusy (ai);
 2841 	msleep(200);
 2842 	if (lock)
 2843 		up(&ai->sem);
 2844 	return 0;
 2845 }
 2846 
 2847 #define AIRO_MAX_NETWORK_COUNT	64
 2848 static int airo_networks_allocate(struct airo_info *ai)
 2849 {
 2850 	if (ai->networks)
 2851 		return 0;
 2852 
 2853 	ai->networks = kcalloc(AIRO_MAX_NETWORK_COUNT, sizeof(BSSListElement),
 2854 			       GFP_KERNEL);
 2855 	if (!ai->networks) {
 2856 		airo_print_warn("", "Out of memory allocating beacons");
 2857 		return -ENOMEM;
 2858 	}
 2859 
 2860 	return 0;
 2861 }
 2862 
 2863 static void airo_networks_free(struct airo_info *ai)
 2864 {
 2865 	kfree(ai->networks);
 2866 	ai->networks = NULL;
 2867 }
 2868 
 2869 static void airo_networks_initialize(struct airo_info *ai)
 2870 {
 2871 	int i;
 2872 
 2873 	INIT_LIST_HEAD(&ai->network_free_list);
 2874 	INIT_LIST_HEAD(&ai->network_list);
 2875 	for (i = 0; i < AIRO_MAX_NETWORK_COUNT; i++)
 2876 		list_add_tail(&ai->networks[i].list,
 2877 			      &ai->network_free_list);
 2878 }
 2879 
 2880 static const struct net_device_ops airo_netdev_ops = {
 2881 	.ndo_open		= airo_open,
 2882 	.ndo_stop		= airo_close,
 2883 	.ndo_start_xmit		= airo_start_xmit,
 2884 	.ndo_get_stats		= airo_get_stats,
 2885 	.ndo_set_rx_mode	= airo_set_multicast_list,
 2886 	.ndo_set_mac_address	= airo_set_mac_address,
 2887 	.ndo_do_ioctl		= airo_ioctl,
 2888 	.ndo_change_mtu		= airo_change_mtu,
 2889 	.ndo_validate_addr	= eth_validate_addr,
 2890 };
 2891 
 2892 static const struct net_device_ops mpi_netdev_ops = {
 2893 	.ndo_open		= airo_open,
 2894 	.ndo_stop		= airo_close,
 2895 	.ndo_start_xmit		= mpi_start_xmit,
 2896 	.ndo_get_stats		= airo_get_stats,
 2897 	.ndo_set_rx_mode	= airo_set_multicast_list,
 2898 	.ndo_set_mac_address	= airo_set_mac_address,
 2899 	.ndo_do_ioctl		= airo_ioctl,
 2900 	.ndo_change_mtu		= airo_change_mtu,
 2901 	.ndo_validate_addr	= eth_validate_addr,
 2902 };
 2903 
 2904 
 2905 static struct net_device *_init_airo_card( unsigned short irq, int port,
 2906 					   int is_pcmcia, struct pci_dev *pci,
 2907 					   struct device *dmdev )
 2908 {
 2909 	struct net_device *dev;
 2910 	struct airo_info *ai;
 2911 	int i, rc;
 2912 	CapabilityRid cap_rid;
 2913 
 2914 	/* Create the network device object. */
 2915 	dev = alloc_netdev(sizeof(*ai), "", NET_NAME_UNKNOWN, ether_setup);
 2916 	if (!dev) {
 2917 		airo_print_err("", "Couldn't alloc_etherdev");
 2918 		return NULL;
 2919 	}
 2920 
 2921 	ai = dev->ml_priv = netdev_priv(dev);
 2922 	ai->wifidev = NULL;
 2923 	ai->flags = 1 << FLAG_RADIO_DOWN;
 2924 	ai->jobs = 0;
 2925 	ai->dev = dev;
 2926 	if (pci && (pci->device == 0x5000 || pci->device == 0xa504)) {
 2927 		airo_print_dbg("", "Found an MPI350 card");
 2928 		set_bit(FLAG_MPI, &ai->flags);
 2929 	}
 2930 	spin_lock_init(&ai->aux_lock);
 2931 	sema_init(&ai->sem, 1);
 2932 	ai->config.len = 0;
 2933 	ai->pci = pci;
 2934 	init_waitqueue_head (&ai->thr_wait);
 2935 	ai->tfm = NULL;
 2936 	add_airo_dev(ai);
 2937 	ai->APList.len = cpu_to_le16(sizeof(struct APListRid));
 2938 
 2939 	if (airo_networks_allocate (ai))
 2940 		goto err_out_free;
 2941 	airo_networks_initialize (ai);
 2942 
 2943 	skb_queue_head_init (&ai->txq);
 2944 
 2945 	/* The Airo-specific entries in the device structure. */
 2946 	if (test_bit(FLAG_MPI,&ai->flags))
 2947 		dev->netdev_ops = &mpi_netdev_ops;
 2948 	else
 2949 		dev->netdev_ops = &airo_netdev_ops;
 2950 	dev->wireless_handlers = &airo_handler_def;
 2951 	ai->wireless_data.spy_data = &ai->spy_data;
 2952 	dev->wireless_data = &ai->wireless_data;
 2953 	dev->irq = irq;
 2954 	dev->base_addr = port;
 2955 	dev->priv_flags &= ~IFF_TX_SKB_SHARING;
 2956 
 2957 	SET_NETDEV_DEV(dev, dmdev);
 2958 
 2959 	reset_card (dev, 1);
 2960 	msleep(400);
 2961 
 2962 	if (!is_pcmcia) {
 2963 		if (!request_region(dev->base_addr, 64, DRV_NAME)) {
 2964 			rc = -EBUSY;
 2965 			airo_print_err(dev->name, "Couldn't request region");
 2966 			goto err_out_nets;
 2967 		}
 2968 	}
 2969 
 2970 	if (test_bit(FLAG_MPI,&ai->flags)) {
 2971 		if (mpi_map_card(ai, pci)) {
 2972 			airo_print_err("", "Could not map memory");
 2973 			goto err_out_res;
 2974 		}
 2975 	}
 2976 
 2977 	if (probe) {
 2978 		if (setup_card(ai, dev->dev_addr, 1) != SUCCESS) {
 2979 			airo_print_err(dev->name, "MAC could not be enabled" );
 2980 			rc = -EIO;
 2981 			goto err_out_map;
 2982 		}
 2983 	} else if (!test_bit(FLAG_MPI,&ai->flags)) {
 2984 		ai->bap_read = fast_bap_read;
 2985 		set_bit(FLAG_FLASHING, &ai->flags);
 2986 	}
 2987 
 2988 	strcpy(dev->name, "eth%d");
 2989 	rc = register_netdev(dev);
 2990 	if (rc) {
 2991 		airo_print_err(dev->name, "Couldn't register_netdev");
 2992 		goto err_out_map;
 2993 	}
 2994 	ai->wifidev = init_wifidev(ai, dev);
 2995 	if (!ai->wifidev)
 2996 		goto err_out_reg;
 2997 
 2998 	rc = readCapabilityRid(ai, &cap_rid, 1);
 2999 	if (rc != SUCCESS) {
 3000 		rc = -EIO;
 3001 		goto err_out_wifi;
 3002 	}
 3003 	/* WEP capability discovery */
 3004 	ai->wep_capable = (cap_rid.softCap & cpu_to_le16(0x02)) ? 1 : 0;
 3005 	ai->max_wep_idx = (cap_rid.softCap & cpu_to_le16(0x80)) ? 3 : 0;
 3006 
 3007 	airo_print_info(dev->name, "Firmware version %x.%x.%02d",
 3008 	                ((le16_to_cpu(cap_rid.softVer) >> 8) & 0xF),
 3009 	                (le16_to_cpu(cap_rid.softVer) & 0xFF),
 3010 	                le16_to_cpu(cap_rid.softSubVer));
 3011 
 3012 	/* Test for WPA support */
 3013 	/* Only firmware versions 5.30.17 or better can do WPA */
 3014 	if (le16_to_cpu(cap_rid.softVer) > 0x530
 3015 	 || (le16_to_cpu(cap_rid.softVer) == 0x530
 3016 	      && le16_to_cpu(cap_rid.softSubVer) >= 17)) {
 3017 		airo_print_info(ai->dev->name, "WPA supported.");
 3018 
 3019 		set_bit(FLAG_WPA_CAPABLE, &ai->flags);
 3020 		ai->bssListFirst = RID_WPA_BSSLISTFIRST;
 3021 		ai->bssListNext = RID_WPA_BSSLISTNEXT;
 3022 		ai->bssListRidLen = sizeof(BSSListRid);
 3023 	} else {
 3024 		airo_print_info(ai->dev->name, "WPA unsupported with firmware "
 3025 			"versions older than 5.30.17.");
 3026 
 3027 		ai->bssListFirst = RID_BSSLISTFIRST;
 3028 		ai->bssListNext = RID_BSSLISTNEXT;
 3029 		ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra);
 3030 	}
 3031 
 3032 	set_bit(FLAG_REGISTERED,&ai->flags);
 3033 	airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr);
 3034 
 3035 	/* Allocate the transmit buffers */
 3036 	if (probe && !test_bit(FLAG_MPI,&ai->flags))
 3037 		for( i = 0; i < MAX_FIDS; i++ )
 3038 			ai->fids[i] = transmit_allocate(ai,AIRO_DEF_MTU,i>=MAX_FIDS/2);
 3039 
 3040 	if (setup_proc_entry(dev, dev->ml_priv) < 0)
 3041 		goto err_out_wifi;
 3042 
 3043 	return dev;
 3044 
 3045 err_out_wifi:
 3046 	unregister_netdev(ai->wifidev);
 3047 	free_netdev(ai->wifidev);
 3048 err_out_reg:
 3049 	unregister_netdev(dev);
 3050 err_out_map:
 3051 	if (test_bit(FLAG_MPI,&ai->flags) && pci) {
 3052 		pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma);
 3053 		iounmap(ai->pciaux);
 3054 		iounmap(ai->pcimem);
 3055 		mpi_unmap_card(ai->pci);
 3056 	}
 3057 err_out_res:
 3058 	if (!is_pcmcia)
 3059 	        release_region( dev->base_addr, 64 );
 3060 err_out_nets:
 3061 	airo_networks_free(ai);
 3062 err_out_free:
 3063 	del_airo_dev(ai);
 3064 	free_netdev(dev);
 3065 	return NULL;
 3066 }
 3067 
 3068 struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia,
 3069 				  struct device *dmdev)
 3070 {
 3071 	return _init_airo_card ( irq, port, is_pcmcia, NULL, dmdev);
 3072 }
 3073 
 3074 EXPORT_SYMBOL(init_airo_card);
 3075 
 3076 static int waitbusy (struct airo_info *ai) {
 3077 	int delay = 0;
 3078 	while ((IN4500(ai, COMMAND) & COMMAND_BUSY) && (delay < 10000)) {
 3079 		udelay (10);
 3080 		if ((++delay % 20) == 0)
 3081 			OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
 3082 	}
 3083 	return delay < 10000;
 3084 }
 3085 
 3086 int reset_airo_card( struct net_device *dev )
 3087 {
 3088 	int i;
 3089 	struct airo_info *ai = dev->ml_priv;
 3090 
 3091 	if (reset_card (dev, 1))
 3092 		return -1;
 3093 
 3094 	if ( setup_card(ai, dev->dev_addr, 1 ) != SUCCESS ) {
 3095 		airo_print_err(dev->name, "MAC could not be enabled");
 3096 		return -1;
 3097 	}
 3098 	airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr);
 3099 	/* Allocate the transmit buffers if needed */
 3100 	if (!test_bit(FLAG_MPI,&ai->flags))
 3101 		for( i = 0; i < MAX_FIDS; i++ )
 3102 			ai->fids[i] = transmit_allocate (ai,AIRO_DEF_MTU,i>=MAX_FIDS/2);
 3103 
 3104 	enable_interrupts( ai );
 3105 	netif_wake_queue(dev);
 3106 	return 0;
 3107 }
 3108 
 3109 EXPORT_SYMBOL(reset_airo_card);
 3110 
 3111 static void airo_send_event(struct net_device *dev) {
 3112 	struct airo_info *ai = dev->ml_priv;
 3113 	union iwreq_data wrqu;
 3114 	StatusRid status_rid;
 3115 
 3116 	clear_bit(JOB_EVENT, &ai->jobs);
 3117 	PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid), 0);
 3118 	up(&ai->sem);
 3119 	wrqu.data.length = 0;
 3120 	wrqu.data.flags = 0;
 3121 	memcpy(wrqu.ap_addr.sa_data, status_rid.bssid[0], ETH_ALEN);
 3122 	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
 3123 
 3124 	/* Send event to user space */
 3125 	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
 3126 }
 3127 
 3128 static void airo_process_scan_results (struct airo_info *ai) {
 3129 	union iwreq_data	wrqu;
 3130 	BSSListRid bss;
 3131 	int rc;
 3132 	BSSListElement * loop_net;
 3133 	BSSListElement * tmp_net;
 3134 
 3135 	/* Blow away current list of scan results */
 3136 	list_for_each_entry_safe (loop_net, tmp_net, &ai->network_list, list) {
 3137 		list_move_tail (&loop_net->list, &ai->network_free_list);
 3138 		/* Don't blow away ->list, just BSS data */
 3139 		memset (loop_net, 0, sizeof (loop_net->bss));
 3140 	}
 3141 
 3142 	/* Try to read the first entry of the scan result */
 3143 	rc = PC4500_readrid(ai, ai->bssListFirst, &bss, ai->bssListRidLen, 0);
 3144 	if((rc) || (bss.index == cpu_to_le16(0xffff))) {
 3145 		/* No scan results */
 3146 		goto out;
 3147 	}
 3148 
 3149 	/* Read and parse all entries */
 3150 	tmp_net = NULL;
 3151 	while((!rc) && (bss.index != cpu_to_le16(0xffff))) {
 3152 		/* Grab a network off the free list */
 3153 		if (!list_empty(&ai->network_free_list)) {
 3154 			tmp_net = list_entry(ai->network_free_list.next,
 3155 					    BSSListElement, list);
 3156 			list_del(ai->network_free_list.next);
 3157 		}
 3158 
 3159 		if (tmp_net != NULL) {
 3160 			memcpy(tmp_net, &bss, sizeof(tmp_net->bss));
 3161 			list_add_tail(&tmp_net->list, &ai->network_list);
 3162 			tmp_net = NULL;
 3163 		}
 3164 
 3165 		/* Read next entry */
 3166 		rc = PC4500_readrid(ai, ai->bssListNext,
 3167 				    &bss, ai->bssListRidLen, 0);
 3168 	}
 3169 
 3170 out:
 3171 	/* write APList back (we cleared it in airo_set_scan) */
 3172 	disable_MAC(ai, 2);
 3173 	writeAPListRid(ai, &ai->APList, 0);
 3174 	enable_MAC(ai, 0);
 3175 
 3176 	ai->scan_timeout = 0;
 3177 	clear_bit(JOB_SCAN_RESULTS, &ai->jobs);
 3178 	up(&ai->sem);
 3179 
 3180 	/* Send an empty event to user space.
 3181 	 * We don't send the received data on
 3182 	 * the event because it would require
 3183 	 * us to do complex transcoding, and
 3184 	 * we want to minimise the work done in
 3185 	 * the irq handler. Use a request to
 3186 	 * extract the data - Jean II */
 3187 	wrqu.data.length = 0;
 3188 	wrqu.data.flags = 0;
 3189 	wireless_send_event(ai->dev, SIOCGIWSCAN, &wrqu, NULL);
 3190 }
 3191 
 3192 static int airo_thread(void *data) {
 3193 	struct net_device *dev = data;
 3194 	struct airo_info *ai = dev->ml_priv;
 3195 	int locked;
 3196 
 3197 	set_freezable();
 3198 	while(1) {
 3199 		/* make swsusp happy with our thread */
 3200 		try_to_freeze();
 3201 
 3202 		if (test_bit(JOB_DIE, &ai->jobs))
 3203 			break;
 3204 
 3205 		if (ai->jobs) {
 3206 			locked = down_interruptible(&ai->sem);
 3207 		} else {
 3208 			wait_queue_t wait;
 3209 
 3210 			init_waitqueue_entry(&wait, current);
 3211 			add_wait_queue(&ai->thr_wait, &wait);
 3212 			for (;;) {
 3213 				set_current_state(TASK_INTERRUPTIBLE);
 3214 				if (ai->jobs)
 3215 					break;
 3216 				if (ai->expires || ai->scan_timeout) {
 3217 					if (ai->scan_timeout &&
 3218 							time_after_eq(jiffies,ai->scan_timeout)){
 3219 						set_bit(JOB_SCAN_RESULTS, &ai->jobs);
 3220 						break;
 3221 					} else if (ai->expires &&
 3222 							time_after_eq(jiffies,ai->expires)){
 3223 						set_bit(JOB_AUTOWEP, &ai->jobs);
 3224 						break;
 3225 					}
 3226 					if (!kthread_should_stop() &&
 3227 					    !freezing(current)) {
 3228 						unsigned long wake_at;
 3229 						if (!ai->expires || !ai->scan_timeout) {
 3230 							wake_at = max(ai->expires,
 3231 								ai->scan_timeout);
 3232 						} else {
 3233 							wake_at = min(ai->expires,
 3234 								ai->scan_timeout);
 3235 						}
 3236 						schedule_timeout(wake_at - jiffies);
 3237 						continue;
 3238 					}
 3239 				} else if (!kthread_should_stop() &&
 3240 					   !freezing(current)) {
 3241 					schedule();
 3242 					continue;
 3243 				}
 3244 				break;
 3245 			}
 3246 			current->state = TASK_RUNNING;
 3247 			remove_wait_queue(&ai->thr_wait, &wait);
 3248 			locked = 1;
 3249 		}
 3250 
 3251 		if (locked)
 3252 			continue;
 3253 
 3254 		if (test_bit(JOB_DIE, &ai->jobs)) {
 3255 			up(&ai->sem);
 3256 			break;
 3257 		}
 3258 
 3259 		if (ai->power.event || test_bit(FLAG_FLASHING, &ai->flags)) {
 3260 			up(&ai->sem);
 3261 			continue;
 3262 		}
 3263 
 3264 		if (test_bit(JOB_XMIT, &ai->jobs))
 3265 			airo_end_xmit(dev);
 3266 		else if (test_bit(JOB_XMIT11, &ai->jobs))
 3267 			airo_end_xmit11(dev);
 3268 		else if (test_bit(JOB_STATS, &ai->jobs))
 3269 			airo_read_stats(dev);
 3270 		else if (test_bit(JOB_WSTATS, &ai->jobs))
 3271 			airo_read_wireless_stats(ai);
 3272 		else if (test_bit(JOB_PROMISC, &ai->jobs))
 3273 			airo_set_promisc(ai);
 3274 		else if (test_bit(JOB_MIC, &ai->jobs))
 3275 			micinit(ai);
 3276 		else if (test_bit(JOB_EVENT, &ai->jobs))
 3277 			airo_send_event(dev);
 3278 		else if (test_bit(JOB_AUTOWEP, &ai->jobs))
 3279 			timer_func(dev);
 3280 		else if (test_bit(JOB_SCAN_RESULTS, &ai->jobs))
 3281 			airo_process_scan_results(ai);
 3282 		else  /* Shouldn't get here, but we make sure to unlock */
 3283 			up(&ai->sem);
 3284 	}
 3285 
 3286 	return 0;
 3287 }
 3288 
 3289 static int header_len(__le16 ctl)
 3290 {
 3291 	u16 fc = le16_to_cpu(ctl);
 3292 	switch (fc & 0xc) {
 3293 	case 4:
 3294 		if ((fc & 0xe0) == 0xc0)
 3295 			return 10;	/* one-address control packet */
 3296 		return 16;	/* two-address control packet */
 3297 	case 8:
 3298 		if ((fc & 0x300) == 0x300)
 3299 			return 30;	/* WDS packet */
 3300 	}
 3301 	return 24;
 3302 }
 3303 
 3304 static void airo_handle_cisco_mic(struct airo_info *ai)
 3305 {
 3306 	if (test_bit(FLAG_MIC_CAPABLE, &ai->flags)) {
 3307 		set_bit(JOB_MIC, &ai->jobs);
 3308 		wake_up_interruptible(&ai->thr_wait);
 3309 	}
 3310 }
 3311 
 3312 /* Airo Status codes */
 3313 #define STAT_NOBEACON	0x8000 /* Loss of sync - missed beacons */
 3314 #define STAT_MAXRETRIES	0x8001 /* Loss of sync - max retries */
 3315 #define STAT_MAXARL	0x8002 /* Loss of sync - average retry level exceeded*/
 3316 #define STAT_FORCELOSS	0x8003 /* Loss of sync - host request */
 3317 #define STAT_TSFSYNC	0x8004 /* Loss of sync - TSF synchronization */
 3318 #define STAT_DEAUTH	0x8100 /* low byte is 802.11 reason code */
 3319 #define STAT_DISASSOC	0x8200 /* low byte is 802.11 reason code */
 3320 #define STAT_ASSOC_FAIL	0x8400 /* low byte is 802.11 reason code */
 3321 #define STAT_AUTH_FAIL	0x0300 /* low byte is 802.11 reason code */
 3322 #define STAT_ASSOC	0x0400 /* Associated */
 3323 #define STAT_REASSOC    0x0600 /* Reassociated?  Only on firmware >= 5.30.17 */
 3324 
 3325 static void airo_print_status(const char *devname, u16 status)
 3326 {
 3327 	u8 reason = status & 0xFF;
 3328 
 3329 	switch (status & 0xFF00) {
 3330 	case STAT_NOBEACON:
 3331 		switch (status) {
 3332 		case STAT_NOBEACON:
 3333 			airo_print_dbg(devname, "link lost (missed beacons)");
 3334 			break;
 3335 		case STAT_MAXRETRIES:
 3336 		case STAT_MAXARL:
 3337 			airo_print_dbg(devname, "link lost (max retries)");
 3338 			break;
 3339 		case STAT_FORCELOSS:
 3340 			airo_print_dbg(devname, "link lost (local choice)");
 3341 			break;
 3342 		case STAT_TSFSYNC:
 3343 			airo_print_dbg(devname, "link lost (TSF sync lost)");
 3344 			break;
 3345 		default:
 3346 			airo_print_dbg(devname, "unknown status %x\n", status);
 3347 			break;
 3348 		}
 3349 		break;
 3350 	case STAT_DEAUTH:
 3351 		airo_print_dbg(devname, "deauthenticated (reason: %d)", reason);
 3352 		break;
 3353 	case STAT_DISASSOC:
 3354 		airo_print_dbg(devname, "disassociated (reason: %d)", reason);
 3355 		break;
 3356 	case STAT_ASSOC_FAIL:
 3357 		airo_print_dbg(devname, "association failed (reason: %d)",
 3358 			       reason);
 3359 		break;
 3360 	case STAT_AUTH_FAIL:
 3361 		airo_print_dbg(devname, "authentication failed (reason: %d)",
 3362 			       reason);
 3363 		break;
 3364 	case STAT_ASSOC:
 3365 	case STAT_REASSOC:
 3366 		break;
 3367 	default:
 3368 		airo_print_dbg(devname, "unknown status %x\n", status);
 3369 		break;
 3370 	}
 3371 }
 3372 
 3373 static void airo_handle_link(struct airo_info *ai)
 3374 {
 3375 	union iwreq_data wrqu;
 3376 	int scan_forceloss = 0;
 3377 	u16 status;
 3378 
 3379 	/* Get new status and acknowledge the link change */
 3380 	status = le16_to_cpu(IN4500(ai, LINKSTAT));
 3381 	OUT4500(ai, EVACK, EV_LINK);
 3382 
 3383 	if ((status == STAT_FORCELOSS) && (ai->scan_timeout > 0))
 3384 		scan_forceloss = 1;
 3385 
 3386 	airo_print_status(ai->dev->name, status);
 3387 
 3388 	if ((status == STAT_ASSOC) || (status == STAT_REASSOC)) {
 3389 		if (auto_wep)
 3390 			ai->expires = 0;
 3391 		if (ai->list_bss_task)
 3392 			wake_up_process(ai->list_bss_task);
 3393 		set_bit(FLAG_UPDATE_UNI, &ai->flags);
 3394 		set_bit(FLAG_UPDATE_MULTI, &ai->flags);
 3395 
 3396 		if (down_trylock(&ai->sem) != 0) {
 3397 			set_bit(JOB_EVENT, &ai->jobs);
 3398 			wake_up_interruptible(&ai->thr_wait);
 3399 		} else
 3400 			airo_send_event(ai->dev);
 3401 		netif_carrier_on(ai->dev);
 3402 	} else if (!scan_forceloss) {
 3403 		if (auto_wep && !ai->expires) {
 3404 			ai->expires = RUN_AT(3*HZ);
 3405 			wake_up_interruptible(&ai->thr_wait);
 3406 		}
 3407 
 3408 		/* Send event to user space */
 3409 		eth_zero_addr(wrqu.ap_addr.sa_data);
 3410 		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
 3411 		wireless_send_event(ai->dev, SIOCGIWAP, &wrqu, NULL);
 3412 		netif_carrier_off(ai->dev);
 3413 	} else {
 3414 		netif_carrier_off(ai->dev);
 3415 	}
 3416 }
 3417 
 3418 static void airo_handle_rx(struct airo_info *ai)
 3419 {
 3420 	struct sk_buff *skb = NULL;
 3421 	__le16 fc, v, *buffer, tmpbuf[4];
 3422 	u16 len, hdrlen = 0, gap, fid;
 3423 	struct rx_hdr hdr;
 3424 	int success = 0;
 3425 
 3426 	if (test_bit(FLAG_MPI, &ai->flags)) {
 3427 		if (test_bit(FLAG_802_11, &ai->flags))
 3428 			mpi_receive_802_11(ai);
 3429 		else
 3430 			mpi_receive_802_3(ai);
 3431 		OUT4500(ai, EVACK, EV_RX);
 3432 		return;
 3433 	}
 3434 
 3435 	fid = IN4500(ai, RXFID);
 3436 
 3437 	/* Get the packet length */
 3438 	if (test_bit(FLAG_802_11, &ai->flags)) {
 3439 		bap_setup (ai, fid, 4, BAP0);
 3440 		bap_read (ai, (__le16*)&hdr, sizeof(hdr), BAP0);
 3441 		/* Bad CRC. Ignore packet */
 3442 		if (le16_to_cpu(hdr.status) & 2)
 3443 			hdr.len = 0;
 3444 		if (ai->wifidev == NULL)
 3445 			hdr.len = 0;
 3446 	} else {
 3447 		bap_setup(ai, fid, 0x36, BAP0);
 3448 		bap_read(ai, &hdr.len, 2, BAP0);
 3449 	}
 3450 	len = le16_to_cpu(hdr.len);
 3451 
 3452 	if (len > AIRO_DEF_MTU) {
 3453 		airo_print_err(ai->dev->name, "Bad size %d", len);
 3454 		goto done;
 3455 	}
 3456 	if (len == 0)
 3457 		goto done;
 3458 
 3459 	if (test_bit(FLAG_802_11, &ai->flags)) {
 3460 		bap_read(ai, &fc, sizeof (fc), BAP0);
 3461 		hdrlen = header_len(fc);
 3462 	} else
 3463 		hdrlen = ETH_ALEN * 2;
 3464 
 3465 	skb = dev_alloc_skb(len + hdrlen + 2 + 2);
 3466 	if (!skb) {
 3467 		ai->dev->stats.rx_dropped++;
 3468 		goto done;
 3469 	}
 3470 
 3471 	skb_reserve(skb, 2); /* This way the IP header is aligned */
 3472 	buffer = (__le16 *) skb_put(skb, len + hdrlen);
 3473 	if (test_bit(FLAG_802_11, &ai->flags)) {
 3474 		buffer[0] = fc;
 3475 		bap_read(ai, buffer + 1, hdrlen - 2, BAP0);
 3476 		if (hdrlen == 24)
 3477 			bap_read(ai, tmpbuf, 6, BAP0);
 3478 
 3479 		bap_read(ai, &v, sizeof(v), BAP0);
 3480 		gap = le16_to_cpu(v);
 3481 		if (gap) {
 3482 			if (gap <= 8) {
 3483 				bap_read(ai, tmpbuf, gap, BAP0);
 3484 			} else {
 3485 				airo_print_err(ai->dev->name, "gaplen too "
 3486 					"big. Problems will follow...");
 3487 			}
 3488 		}
 3489 		bap_read(ai, buffer + hdrlen/2, len, BAP0);
 3490 	} else {
 3491 		MICBuffer micbuf;
 3492 
 3493 		bap_read(ai, buffer, ETH_ALEN * 2, BAP0);
 3494 		if (ai->micstats.enabled) {
 3495 			bap_read(ai, (__le16 *) &micbuf, sizeof (micbuf), BAP0);
 3496 			if (ntohs(micbuf.typelen) > 0x05DC)
 3497 				bap_setup(ai, fid, 0x44, BAP0);
 3498 			else {
 3499 				if (len <= sizeof (micbuf)) {
 3500 					dev_kfree_skb_irq(skb);
 3501 					goto done;
 3502 				}
 3503 
 3504 				len -= sizeof(micbuf);
 3505 				skb_trim(skb, len + hdrlen);
 3506 			}
 3507 		}
 3508 
 3509 		bap_read(ai, buffer + ETH_ALEN, len, BAP0);
 3510 		if (decapsulate(ai, &micbuf, (etherHead*) buffer, len))
 3511 			dev_kfree_skb_irq (skb);
 3512 		else
 3513 			success = 1;
 3514 	}
 3515 
 3516 #ifdef WIRELESS_SPY
 3517 	if (success && (ai->spy_data.spy_number > 0)) {
 3518 		char *sa;
 3519 		struct iw_quality wstats;
 3520 
 3521 		/* Prepare spy data : addr + qual */
 3522 		if (!test_bit(FLAG_802_11, &ai->flags)) {
 3523 			sa = (char *) buffer + 6;
 3524 			bap_setup(ai, fid, 8, BAP0);
 3525 			bap_read(ai, (__le16 *) hdr.rssi, 2, BAP0);
 3526 		} else
 3527 			sa = (char *) buffer + 10;
 3528 		wstats.qual = hdr.rssi[0];
 3529 		if (ai->rssi)
 3530 			wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
 3531 		else
 3532 			wstats.level = (hdr.rssi[1] + 321) / 2;
 3533 		wstats.noise = ai->wstats.qual.noise;
 3534 		wstats.updated =  IW_QUAL_LEVEL_UPDATED
 3535 				| IW_QUAL_QUAL_UPDATED
 3536 				| IW_QUAL_DBM;
 3537 		/* Update spy records */
 3538 		wireless_spy_update(ai->dev, sa, &wstats);
 3539 	}
 3540 #endif /* WIRELESS_SPY */
 3541 
 3542 done:
 3543 	OUT4500(ai, EVACK, EV_RX);
 3544 
 3545 	if (success) {
 3546 		if (test_bit(FLAG_802_11, &ai->flags)) {
 3547 			skb_reset_mac_header(skb);
 3548 			skb->pkt_type = PACKET_OTHERHOST;
 3549 			skb->dev = ai->wifidev;
 3550 			skb->protocol = htons(ETH_P_802_2);
 3551 		} else
 3552 			skb->protocol = eth_type_trans(skb, ai->dev);
 3553 		skb->ip_summed = CHECKSUM_NONE;
 3554 
 3555 		netif_rx(skb);
 3556 	}
 3557 }
 3558 
 3559 static void airo_handle_tx(struct airo_info *ai, u16 status)
 3560 {
 3561 	int i, len = 0, index = -1;
 3562 	u16 fid;
 3563 
 3564 	if (test_bit(FLAG_MPI, &ai->flags)) {
 3565 		unsigned long flags;
 3566 
 3567 		if (status & EV_TXEXC)
 3568 			get_tx_error(ai, -1);
 3569 
 3570 		spin_lock_irqsave(&ai->aux_lock, flags);
 3571 		if (!skb_queue_empty(&ai->txq)) {
 3572 			spin_unlock_irqrestore(&ai->aux_lock,flags);
 3573 			mpi_send_packet(ai->dev);
 3574 		} else {
 3575 			clear_bit(FLAG_PENDING_XMIT, &ai->flags);
 3576 			spin_unlock_irqrestore(&ai->aux_lock,flags);
 3577 			netif_wake_queue(ai->dev);
 3578 		}
 3579 		OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
 3580 		return;
 3581 	}
 3582 
 3583 	fid = IN4500(ai, TXCOMPLFID);
 3584 
 3585 	for(i = 0; i < MAX_FIDS; i++) {
 3586 		if ((ai->fids[i] & 0xffff) == fid) {
 3587 			len = ai->fids[i] >> 16;
 3588 			index = i;
 3589 		}
 3590 	}
 3591 
 3592 	if (index != -1) {
 3593 		if (status & EV_TXEXC)
 3594 			get_tx_error(ai, index);
 3595 
 3596 		OUT4500(ai, EVACK, status & (EV_TX | EV_TXEXC));
 3597 
 3598 		/* Set up to be used again */
 3599 		ai->fids[index] &= 0xffff;
 3600 		if (index < MAX_FIDS / 2) {
 3601 			if (!test_bit(FLAG_PENDING_XMIT, &ai->flags))
 3602 				netif_wake_queue(ai->dev);
 3603 		} else {
 3604 			if (!test_bit(FLAG_PENDING_XMIT11, &ai->flags))
 3605 				netif_wake_queue(ai->wifidev);
 3606 		}
 3607 	} else {
 3608 		OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
 3609 		airo_print_err(ai->dev->name, "Unallocated FID was used to xmit");
 3610 	}
 3611 }
 3612 
 3613 static irqreturn_t airo_interrupt(int irq, void *dev_id)
 3614 {
 3615 	struct net_device *dev = dev_id;
 3616 	u16 status, savedInterrupts = 0;
 3617 	struct airo_info *ai = dev->ml_priv;
 3618 	int handled = 0;
 3619 
 3620 	if (!netif_device_present(dev))
 3621 		return IRQ_NONE;
 3622 
 3623 	for (;;) {
 3624 		status = IN4500(ai, EVSTAT);
 3625 		if (!(status & STATUS_INTS) || (status == 0xffff))
 3626 			break;
 3627 
 3628 		handled = 1;
 3629 
 3630 		if (status & EV_AWAKE) {
 3631 			OUT4500(ai, EVACK, EV_AWAKE);
 3632 			OUT4500(ai, EVACK, EV_AWAKE);
 3633 		}
 3634 
 3635 		if (!savedInterrupts) {
 3636 			savedInterrupts = IN4500(ai, EVINTEN);
 3637 			OUT4500(ai, EVINTEN, 0);
 3638 		}
 3639 
 3640 		if (status & EV_MIC) {
 3641 			OUT4500(ai, EVACK, EV_MIC);
 3642 			airo_handle_cisco_mic(ai);
 3643 		}
 3644 
 3645 		if (status & EV_LINK) {
 3646 			/* Link status changed */
 3647 			airo_handle_link(ai);
 3648 		}
 3649 
 3650 		/* Check to see if there is something to receive */
 3651 		if (status & EV_RX)
 3652 			airo_handle_rx(ai);
 3653 
 3654 		/* Check to see if a packet has been transmitted */
 3655 		if (status & (EV_TX | EV_TXCPY | EV_TXEXC))
 3656 			airo_handle_tx(ai, status);
 3657 
 3658 		if ( status & ~STATUS_INTS & ~IGNORE_INTS ) {
 3659 			airo_print_warn(ai->dev->name, "Got weird status %x",
 3660 				status & ~STATUS_INTS & ~IGNORE_INTS );
 3661 		}
 3662 	}
 3663 
 3664 	if (savedInterrupts)
 3665 		OUT4500(ai, EVINTEN, savedInterrupts);
 3666 
 3667 	return IRQ_RETVAL(handled);
 3668 }
 3669 
 3670 /*
 3671  *  Routines to talk to the card
 3672  */
 3673 
 3674 /*
 3675  *  This was originally written for the 4500, hence the name
 3676  *  NOTE:  If use with 8bit mode and SMP bad things will happen!
 3677  *         Why would some one do 8 bit IO in an SMP machine?!?
 3678  */
 3679 static void OUT4500( struct airo_info *ai, u16 reg, u16 val ) {
 3680 	if (test_bit(FLAG_MPI,&ai->flags))
 3681 		reg <<= 1;
 3682 	if ( !do8bitIO )
 3683 		outw( val, ai->dev->base_addr + reg );
 3684 	else {
 3685 		outb( val & 0xff, ai->dev->base_addr + reg );
 3686 		outb( val >> 8, ai->dev->base_addr + reg + 1 );
 3687 	}
 3688 }
 3689 
 3690 static u16 IN4500( struct airo_info *ai, u16 reg ) {
 3691 	unsigned short rc;
 3692 
 3693 	if (test_bit(FLAG_MPI,&ai->flags))
 3694 		reg <<= 1;
 3695 	if ( !do8bitIO )
 3696 		rc = inw( ai->dev->base_addr + reg );
 3697 	else {
 3698 		rc = inb( ai->dev->base_addr + reg );
 3699 		rc += ((int)inb( ai->dev->base_addr + reg + 1 )) << 8;
 3700 	}
 3701 	return rc;
 3702 }
 3703 
 3704 static int enable_MAC(struct airo_info *ai, int lock)
 3705 {
 3706 	int rc;
 3707 	Cmd cmd;
 3708 	Resp rsp;
 3709 
 3710 	/* FLAG_RADIO_OFF : Radio disabled via /proc or Wireless Extensions
 3711 	 * FLAG_RADIO_DOWN : Radio disabled via "ifconfig ethX down"
 3712 	 * Note : we could try to use !netif_running(dev) in enable_MAC()
 3713 	 * instead of this flag, but I don't trust it *within* the
 3714 	 * open/close functions, and testing both flags together is
 3715 	 * "cheaper" - Jean II */
 3716 	if (ai->flags & FLAG_RADIO_MASK) return SUCCESS;
 3717 
 3718 	if (lock && down_interruptible(&ai->sem))
 3719 		return -ERESTARTSYS;
 3720 
 3721 	if (!test_bit(FLAG_ENABLED, &ai->flags)) {
 3722 		memset(&cmd, 0, sizeof(cmd));
 3723 		cmd.cmd = MAC_ENABLE;
 3724 		rc = issuecommand(ai, &cmd, &rsp);
 3725 		if (rc == SUCCESS)
 3726 			set_bit(FLAG_ENABLED, &ai->flags);
 3727 	} else
 3728 		rc = SUCCESS;
 3729 
 3730 	if (lock)
 3731 	    up(&ai->sem);
 3732 
 3733 	if (rc)
 3734 		airo_print_err(ai->dev->name, "Cannot enable MAC");
 3735 	else if ((rsp.status & 0xFF00) != 0) {
 3736 		airo_print_err(ai->dev->name, "Bad MAC enable reason=%x, "
 3737 			"rid=%x, offset=%d", rsp.rsp0, rsp.rsp1, rsp.rsp2);
 3738 		rc = ERROR;
 3739 	}
 3740 	return rc;
 3741 }
 3742 
 3743 static void disable_MAC( struct airo_info *ai, int lock ) {
 3744         Cmd cmd;
 3745 	Resp rsp;
 3746 
 3747 	if (lock == 1 && down_interruptible(&ai->sem))
 3748 		return;
 3749 
 3750 	if (test_bit(FLAG_ENABLED, &ai->flags)) {
 3751 		if (lock != 2) /* lock == 2 means don't disable carrier */
 3752 			netif_carrier_off(ai->dev);
 3753 		memset(&cmd, 0, sizeof(cmd));
 3754 		cmd.cmd = MAC_DISABLE; // disable in case already enabled
 3755 		issuecommand(ai, &cmd, &rsp);
 3756 		clear_bit(FLAG_ENABLED, &ai->flags);
 3757 	}
 3758 	if (lock == 1)
 3759 		up(&ai->sem);
 3760 }
 3761 
 3762 static void enable_interrupts( struct airo_info *ai ) {
 3763 	/* Enable the interrupts */
 3764 	OUT4500( ai, EVINTEN, STATUS_INTS );
 3765 }
 3766 
 3767 static void disable_interrupts( struct airo_info *ai ) {
 3768 	OUT4500( ai, EVINTEN, 0 );
 3769 }
 3770 
 3771 static void mpi_receive_802_3(struct airo_info *ai)
 3772 {
 3773 	RxFid rxd;
 3774 	int len = 0;
 3775 	struct sk_buff *skb;
 3776 	char *buffer;
 3777 	int off = 0;
 3778 	MICBuffer micbuf;
 3779 
 3780 	memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
 3781 	/* Make sure we got something */
 3782 	if (rxd.rdy && rxd.valid == 0) {
 3783 		len = rxd.len + 12;
 3784 		if (len < 12 || len > 2048)
 3785 			goto badrx;
 3786 
 3787 		skb = dev_alloc_skb(len);
 3788 		if (!skb) {
 3789 			ai->dev->stats.rx_dropped++;
 3790 			goto badrx;
 3791 		}
 3792 		buffer = skb_put(skb,len);
 3793 		memcpy(buffer, ai->rxfids[0].virtual_host_addr, ETH_ALEN * 2);
 3794 		if (ai->micstats.enabled) {
 3795 			memcpy(&micbuf,
 3796 				ai->rxfids[0].virtual_host_addr + ETH_ALEN * 2,
 3797 				sizeof(micbuf));
 3798 			if (ntohs(micbuf.typelen) <= 0x05DC) {
 3799 				if (len <= sizeof(micbuf) + ETH_ALEN * 2)
 3800 					goto badmic;
 3801 
 3802 				off = sizeof(micbuf);
 3803 				skb_trim (skb, len - off);
 3804 			}
 3805 		}
 3806 		memcpy(buffer + ETH_ALEN * 2,
 3807 			ai->rxfids[0].virtual_host_addr + ETH_ALEN * 2 + off,
 3808 			len - ETH_ALEN * 2 - off);
 3809 		if (decapsulate (ai, &micbuf, (etherHead*)buffer, len - off - ETH_ALEN * 2)) {
 3810 badmic:
 3811 			dev_kfree_skb_irq (skb);
 3812 			goto badrx;
 3813 		}
 3814 #ifdef WIRELESS_SPY
 3815 		if (ai->spy_data.spy_number > 0) {
 3816 			char *sa;
 3817 			struct iw_quality wstats;
 3818 			/* Prepare spy data : addr + qual */
 3819 			sa = buffer + ETH_ALEN;
 3820 			wstats.qual = 0; /* XXX Where do I get that info from ??? */
 3821 			wstats.level = 0;
 3822 			wstats.updated = 0;
 3823 			/* Update spy records */
 3824 			wireless_spy_update(ai->dev, sa, &wstats);
 3825 		}
 3826 #endif /* WIRELESS_SPY */
 3827 
 3828 		skb->ip_summed = CHECKSUM_NONE;
 3829 		skb->protocol = eth_type_trans(skb, ai->dev);
 3830 		netif_rx(skb);
 3831 	}
 3832 badrx:
 3833 	if (rxd.valid == 0) {
 3834 		rxd.valid = 1;
 3835 		rxd.rdy = 0;
 3836 		rxd.len = PKTSIZE;
 3837 		memcpy_toio(ai->rxfids[0].card_ram_off, &rxd, sizeof(rxd));
 3838 	}
 3839 }
 3840 
 3841 static void mpi_receive_802_11(struct airo_info *ai)
 3842 {
 3843 	RxFid rxd;
 3844 	struct sk_buff *skb = NULL;
 3845 	u16 len, hdrlen = 0;
 3846 	__le16 fc;
 3847 	struct rx_hdr hdr;
 3848 	u16 gap;
 3849 	u16 *buffer;
 3850 	char *ptr = ai->rxfids[0].virtual_host_addr + 4;
 3851 
 3852 	memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
 3853 	memcpy ((char *)&hdr, ptr, sizeof(hdr));
 3854 	ptr += sizeof(hdr);
 3855 	/* Bad CRC. Ignore packet */
 3856 	if (le16_to_cpu(hdr.status) & 2)
 3857 		hdr.len = 0;
 3858 	if (ai->wifidev == NULL)
 3859 		hdr.len = 0;
 3860 	len = le16_to_cpu(hdr.len);
 3861 	if (len > AIRO_DEF_MTU) {
 3862 		airo_print_err(ai->dev->name, "Bad size %d", len);
 3863 		goto badrx;
 3864 	}
 3865 	if (len == 0)
 3866 		goto badrx;
 3867 
 3868 	fc = get_unaligned((__le16 *)ptr);
 3869 	hdrlen = header_len(fc);
 3870 
 3871 	skb = dev_alloc_skb( len + hdrlen + 2 );
 3872 	if ( !skb ) {
 3873 		ai->dev->stats.rx_dropped++;
 3874 		goto badrx;
 3875 	}
 3876 	buffer = (u16*)skb_put (skb, len + hdrlen);
 3877 	memcpy ((char *)buffer, ptr, hdrlen);
 3878 	ptr += hdrlen;
 3879 	if (hdrlen == 24)
 3880 		ptr += 6;
 3881 	gap = get_unaligned_le16(ptr);
 3882 	ptr += sizeof(__le16);
 3883 	if (gap) {
 3884 		if (gap <= 8)
 3885 			ptr += gap;
 3886 		else
 3887 			airo_print_err(ai->dev->name,
 3888 			    "gaplen too big. Problems will follow...");
 3889 	}
 3890 	memcpy ((char *)buffer + hdrlen, ptr, len);
 3891 	ptr += len;
 3892 #ifdef IW_WIRELESS_SPY	  /* defined in iw_handler.h */
 3893 	if (ai->spy_data.spy_number > 0) {
 3894 		char *sa;
 3895 		struct iw_quality wstats;
 3896 		/* Prepare spy data : addr + qual */
 3897 		sa = (char*)buffer + 10;
 3898 		wstats.qual = hdr.rssi[0];
 3899 		if (ai->rssi)
 3900 			wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
 3901 		else
 3902 			wstats.level = (hdr.rssi[1] + 321) / 2;
 3903 		wstats.noise = ai->wstats.qual.noise;
 3904 		wstats.updated = IW_QUAL_QUAL_UPDATED
 3905 			| IW_QUAL_LEVEL_UPDATED
 3906 			| IW_QUAL_DBM;
 3907 		/* Update spy records */
 3908 		wireless_spy_update(ai->dev, sa, &wstats);
 3909 	}
 3910 #endif /* IW_WIRELESS_SPY */
 3911 	skb_reset_mac_header(skb);
 3912 	skb->pkt_type = PACKET_OTHERHOST;
 3913 	skb->dev = ai->wifidev;
 3914 	skb->protocol = htons(ETH_P_802_2);
 3915 	skb->ip_summed = CHECKSUM_NONE;
 3916 	netif_rx( skb );
 3917 
 3918 badrx:
 3919 	if (rxd.valid == 0) {
 3920 		rxd.valid = 1;
 3921 		rxd.rdy = 0;
 3922 		rxd.len = PKTSIZE;
 3923 		memcpy_toio(ai->rxfids[0].card_ram_off, &rxd, sizeof(rxd));
 3924 	}
 3925 }
 3926 
 3927 static inline void set_auth_type(struct airo_info *local, int auth_type)
 3928 {
 3929 	local->config.authType = auth_type;
 3930 	/* Cache the last auth type used (of AUTH_OPEN and AUTH_ENCRYPT).
 3931 	 * Used by airo_set_auth()
 3932 	 */
 3933 	if (auth_type == AUTH_OPEN || auth_type == AUTH_ENCRYPT)
 3934 		local->last_auth = auth_type;
 3935 }
 3936 
 3937 static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
 3938 {
 3939 	Cmd cmd;
 3940 	Resp rsp;
 3941 	int status;
 3942 	SsidRid mySsid;
 3943 	__le16 lastindex;
 3944 	WepKeyRid wkr;
 3945 	int rc;
 3946 
 3947 	memset( &mySsid, 0, sizeof( mySsid ) );
 3948 	kfree (ai->flash);
 3949 	ai->flash = NULL;
 3950 
 3951 	/* The NOP is the first step in getting the card going */
 3952 	cmd.cmd = NOP;
 3953 	cmd.parm0 = cmd.parm1 = cmd.parm2 = 0;
 3954 	if (lock && down_interruptible(&ai->sem))
 3955 		return ERROR;
 3956 	if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
 3957 		if (lock)
 3958 			up(&ai->sem);
 3959 		return ERROR;
 3960 	}
 3961 	disable_MAC( ai, 0);
 3962 
 3963 	// Let's figure out if we need to use the AUX port
 3964 	if (!test_bit(FLAG_MPI,&ai->flags)) {
 3965 		cmd.cmd = CMD_ENABLEAUX;
 3966 		if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
 3967 			if (lock)
 3968 				up(&ai->sem);
 3969 			airo_print_err(ai->dev->name, "Error checking for AUX port");
 3970 			return ERROR;
 3971 		}
 3972 		if (!aux_bap || rsp.status & 0xff00) {
 3973 			ai->bap_read = fast_bap_read;
 3974 			airo_print_dbg(ai->dev->name, "Doing fast bap_reads");
 3975 		} else {
 3976 			ai->bap_read = aux_bap_read;
 3977 			airo_print_dbg(ai->dev->name, "Doing AUX bap_reads");
 3978 		}
 3979 	}
 3980 	if (lock)
 3981 		up(&ai->sem);
 3982 	if (ai->config.len == 0) {
 3983 		int i;
 3984 		tdsRssiRid rssi_rid;
 3985 		CapabilityRid cap_rid;
 3986 
 3987 		kfree(ai->SSID);
 3988 		ai->SSID = NULL;
 3989 		// general configuration (read/modify/write)
 3990 		status = readConfigRid(ai, lock);
 3991 		if ( status != SUCCESS ) return ERROR;
 3992 
 3993 		status = readCapabilityRid(ai, &cap_rid, lock);
 3994 		if ( status != SUCCESS ) return ERROR;
 3995 
 3996 		status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),lock);
 3997 		if ( status == SUCCESS ) {
 3998 			if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL)
 3999 				memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); /* Skip RID length member */
 4000 		}
 4001 		else {
 4002 			kfree(ai->rssi);
 4003 			ai->rssi = NULL;
 4004 			if (cap_rid.softCap & cpu_to_le16(8))
 4005 				ai->config.rmode |= RXMODE_NORMALIZED_RSSI;
 4006 			else
 4007 				airo_print_warn(ai->dev->name, "unknown received signal "
 4008 						"level scale");
 4009 		}
 4010 		ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
 4011 		set_auth_type(ai, AUTH_OPEN);
 4012 		ai->config.modulation = MOD_CCK;
 4013 
 4014 		if (le16_to_cpu(cap_rid.len) >= sizeof(cap_rid) &&
 4015 		    (cap_rid.extSoftCap & cpu_to_le16(1)) &&
 4016 		    micsetup(ai) == SUCCESS) {
 4017 			ai->config.opmode |= MODE_MIC;
 4018 			set_bit(FLAG_MIC_CAPABLE, &ai->flags);
 4019 		}
 4020 
 4021 		/* Save off the MAC */
 4022 		for( i = 0; i < ETH_ALEN; i++ ) {
 4023 			mac[i] = ai->config.macAddr[i];
 4024 		}
 4025 
 4026 		/* Check to see if there are any insmod configured
 4027 		   rates to add */
 4028 		if ( rates[0] ) {
 4029 			memset(ai->config.rates,0,sizeof(ai->config.rates));
 4030 			for( i = 0; i < 8 && rates[i]; i++ ) {
 4031 				ai->config.rates[i] = rates[i];
 4032 			}
 4033 		}
 4034 		set_bit (FLAG_COMMIT, &ai->flags);
 4035 	}
 4036 
 4037 	/* Setup the SSIDs if present */
 4038 	if ( ssids[0] ) {
 4039 		int i;
 4040 		for( i = 0; i < 3 && ssids[i]; i++ ) {
 4041 			size_t len = strlen(ssids[i]);
 4042 			if (len > 32)
 4043 				len = 32;
 4044 			mySsid.ssids[i].len = cpu_to_le16(len);
 4045 			memcpy(mySsid.ssids[i].ssid, ssids[i], len);
 4046 		}
 4047 		mySsid.len = cpu_to_le16(sizeof(mySsid));
 4048 	}
 4049 
 4050 	status = writeConfigRid(ai, lock);
 4051 	if ( status != SUCCESS ) return ERROR;
 4052 
 4053 	/* Set up the SSID list */
 4054 	if ( ssids[0] ) {
 4055 		status = writeSsidRid(ai, &mySsid, lock);
 4056 		if ( status != SUCCESS ) return ERROR;
 4057 	}
 4058 
 4059 	status = enable_MAC(ai, lock);
 4060 	if (status != SUCCESS)
 4061 		return ERROR;
 4062 
 4063 	/* Grab the initial wep key, we gotta save it for auto_wep */
 4064 	rc = readWepKeyRid(ai, &wkr, 1, lock);
 4065 	if (rc == SUCCESS) do {
 4066 		lastindex = wkr.kindex;
 4067 		if (wkr.kindex == cpu_to_le16(0xffff)) {
 4068 			ai->defindex = wkr.mac[0];
 4069 		}
 4070 		rc = readWepKeyRid(ai, &wkr, 0, lock);
 4071 	} while(lastindex != wkr.kindex);
 4072 
 4073 	try_auto_wep(ai);
 4074 
 4075 	return SUCCESS;
 4076 }
 4077 
 4078 static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
 4079         // Im really paranoid about letting it run forever!
 4080 	int max_tries = 600000;
 4081 
 4082 	if (IN4500(ai, EVSTAT) & EV_CMD)
 4083 		OUT4500(ai, EVACK, EV_CMD);
 4084 
 4085 	OUT4500(ai, PARAM0, pCmd->parm0);
 4086 	OUT4500(ai, PARAM1, pCmd->parm1);
 4087 	OUT4500(ai, PARAM2, pCmd->parm2);
 4088 	OUT4500(ai, COMMAND, pCmd->cmd);
 4089 
 4090 	while (max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0) {
 4091 		if ((IN4500(ai, COMMAND)) == pCmd->cmd)
 4092 			// PC4500 didn't notice command, try again
 4093 			OUT4500(ai, COMMAND, pCmd->cmd);
 4094 		if (!in_atomic() && (max_tries & 255) == 0)
 4095 			schedule();
 4096 	}
 4097 
 4098 	if ( max_tries == -1 ) {
 4099 		airo_print_err(ai->dev->name,
 4100 			"Max tries exceeded when issuing command");
 4101 		if (IN4500(ai, COMMAND) & COMMAND_BUSY)
 4102 			OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
 4103 		return ERROR;
 4104 	}
 4105 
 4106 	// command completed
 4107 	pRsp->status = IN4500(ai, STATUS);
 4108 	pRsp->rsp0 = IN4500(ai, RESP0);
 4109 	pRsp->rsp1 = IN4500(ai, RESP1);
 4110 	pRsp->rsp2 = IN4500(ai, RESP2);
 4111 	if ((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_SOFTRESET)
 4112 		airo_print_err(ai->dev->name,
 4113 			"cmd:%x status:%x rsp0:%x rsp1:%x rsp2:%x",
 4114 			pCmd->cmd, pRsp->status, pRsp->rsp0, pRsp->rsp1,
 4115 			pRsp->rsp2);
 4116 
 4117 	// clear stuck command busy if necessary
 4118 	if (IN4500(ai, COMMAND) & COMMAND_BUSY) {
 4119 		OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
 4120 	}
 4121 	// acknowledge processing the status/response
 4122 	OUT4500(ai, EVACK, EV_CMD);
 4123 
 4124 	return SUCCESS;
 4125 }
 4126 
 4127 /* Sets up the bap to start exchange data.  whichbap should
 4128  * be one of the BAP0 or BAP1 defines.  Locks should be held before
 4129  * calling! */
 4130 static int bap_setup(struct airo_info *ai, u16 rid, u16 offset, int whichbap )
 4131 {
 4132 	int timeout = 50;
 4133 	int max_tries = 3;
 4134 
 4135 	OUT4500(ai, SELECT0+whichbap, rid);
 4136 	OUT4500(ai, OFFSET0+whichbap, offset);
 4137 	while (1) {
 4138 		int status = IN4500(ai, OFFSET0+whichbap);
 4139 		if (status & BAP_BUSY) {
 4140                         /* This isn't really a timeout, but its kinda
 4141 			   close */
 4142 			if (timeout--) {
 4143 				continue;
 4144 			}
 4145 		} else if ( status & BAP_ERR ) {
 4146 			/* invalid rid or offset */
 4147 			airo_print_err(ai->dev->name, "BAP error %x %d",
 4148 				status, whichbap );
 4149 			return ERROR;
 4150 		} else if (status & BAP_DONE) { // success
 4151 			return SUCCESS;
 4152 		}
 4153 		if ( !(max_tries--) ) {
 4154 			airo_print_err(ai->dev->name,
 4155 				"BAP setup error too many retries\n");
 4156 			return ERROR;
 4157 		}
 4158 		// -- PC4500 missed it, try again
 4159 		OUT4500(ai, SELECT0+whichbap, rid);
 4160 		OUT4500(ai, OFFSET0+whichbap, offset);
 4161 		timeout = 50;
 4162 	}
 4163 }
 4164 
 4165 /* should only be called by aux_bap_read.  This aux function and the
 4166    following use concepts not documented in the developers guide.  I
 4167    got them from a patch given to my by Aironet */
 4168 static u16 aux_setup(struct airo_info *ai, u16 page,
 4169 		     u16 offset, u16 *len)
 4170 {
 4171 	u16 next;
 4172 
 4173 	OUT4500(ai, AUXPAGE, page);
 4174 	OUT4500(ai, AUXOFF, 0);
 4175 	next = IN4500(ai, AUXDATA);
 4176 	*len = IN4500(ai, AUXDATA)&0xff;
 4177 	if (offset != 4) OUT4500(ai, AUXOFF, offset);
 4178 	return next;
 4179 }
 4180 
 4181 /* requires call to bap_setup() first */
 4182 static int aux_bap_read(struct airo_info *ai, __le16 *pu16Dst,
 4183 			int bytelen, int whichbap)
 4184 {
 4185 	u16 len;
 4186 	u16 page;
 4187 	u16 offset;
 4188 	u16 next;
 4189 	int words;
 4190 	int i;
 4191 	unsigned long flags;
 4192 
 4193 	spin_lock_irqsave(&ai->aux_lock, flags);
 4194 	page = IN4500(ai, SWS0+whichbap);
 4195 	offset = IN4500(ai, SWS2+whichbap);
 4196 	next = aux_setup(ai, page, offset, &len);
 4197 	words = (bytelen+1)>>1;
 4198 
 4199 	for (i=0; i<words;) {
 4200 		int count;
 4201 		count = (len>>1) < (words-i) ? (len>>1) : (words-i);
 4202 		if ( !do8bitIO )
 4203 			insw( ai->dev->base_addr+DATA0+whichbap,
 4204 			      pu16Dst+i,count );
 4205 		else
 4206 			insb( ai->dev->base_addr+DATA0+whichbap,
 4207 			      pu16Dst+i, count << 1 );
 4208 		i += count;
 4209 		if (i<words) {
 4210 			next = aux_setup(ai, next, 4, &len);
 4211 		}
 4212 	}
 4213 	spin_unlock_irqrestore(&ai->aux_lock, flags);
 4214 	return SUCCESS;
 4215 }
 4216 
 4217 
 4218 /* requires call to bap_setup() first */
 4219 static int fast_bap_read(struct airo_info *ai, __le16 *pu16Dst,
 4220 			 int bytelen, int whichbap)
 4221 {
 4222 	bytelen = (bytelen + 1) & (~1); // round up to even value
 4223 	if ( !do8bitIO )
 4224 		insw( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen>>1 );
 4225 	else
 4226 		insb( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen );
 4227 	return SUCCESS;
 4228 }
 4229 
 4230 /* requires call to bap_setup() first */
 4231 static int bap_write(struct airo_info *ai, const __le16 *pu16Src,
 4232 		     int bytelen, int whichbap)
 4233 {
 4234 	bytelen = (bytelen + 1) & (~1); // round up to even value
 4235 	if ( !do8bitIO )
 4236 		outsw( ai->dev->base_addr+DATA0+whichbap,
 4237 		       pu16Src, bytelen>>1 );
 4238 	else
 4239 		outsb( ai->dev->base_addr+DATA0+whichbap, pu16Src, bytelen );
 4240 	return SUCCESS;
 4241 }
 4242 
 4243 static int PC4500_accessrid(struct airo_info *ai, u16 rid, u16 accmd)
 4244 {
 4245 	Cmd cmd; /* for issuing commands */
 4246 	Resp rsp; /* response from commands */
 4247 	u16 status;
 4248 
 4249 	memset(&cmd, 0, sizeof(cmd));
 4250 	cmd.cmd = accmd;
 4251 	cmd.parm0 = rid;
 4252 	status = issuecommand(ai, &cmd, &rsp);
 4253 	if (status != 0) return status;
 4254 	if ( (rsp.status & 0x7F00) != 0) {
 4255 		return (accmd << 8) + (rsp.rsp0 & 0xFF);
 4256 	}
 4257 	return 0;
 4258 }
 4259 
 4260 /*  Note, that we are using BAP1 which is also used by transmit, so
 4261  *  we must get a lock. */
 4262 static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len, int lock)
 4263 {
 4264 	u16 status;
 4265         int rc = SUCCESS;
 4266 
 4267 	if (lock) {
 4268 		if (down_interruptible(&ai->sem))
 4269 			return ERROR;
 4270 	}
 4271 	if (test_bit(FLAG_MPI,&ai->flags)) {
 4272 		Cmd cmd;
 4273 		Resp rsp;
 4274 
 4275 		memset(&cmd, 0, sizeof(cmd));
 4276 		memset(&rsp, 0, sizeof(rsp));
 4277 		ai->config_desc.rid_desc.valid = 1;
 4278 		ai->config_desc.rid_desc.len = RIDSIZE;
 4279 		ai->config_desc.rid_desc.rid = 0;
 4280 		ai->config_desc.rid_desc.host_addr = ai->ridbus;
 4281 
 4282 		cmd.cmd = CMD_ACCESS;
 4283 		cmd.parm0 = rid;
 4284 
 4285 		memcpy_toio(ai->config_desc.card_ram_off,
 4286 			&ai->config_desc.rid_desc, sizeof(Rid));
 4287 
 4288 		rc = issuecommand(ai, &cmd, &rsp);
 4289 
 4290 		if (rsp.status & 0x7f00)
 4291 			rc = rsp.rsp0;
 4292 		if (!rc)
 4293 			memcpy(pBuf, ai->config_desc.virtual_host_addr, len);
 4294 		goto done;
 4295 	} else {
 4296 		if ((status = PC4500_accessrid(ai, rid, CMD_ACCESS))!=SUCCESS) {
 4297 	                rc = status;
 4298 	                goto done;
 4299 	        }
 4300 		if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
 4301 			rc = ERROR;
 4302 	                goto done;
 4303 	        }
 4304 		// read the rid length field
 4305 		bap_read(ai, pBuf, 2, BAP1);
 4306 		// length for remaining part of rid
 4307 		len = min(len, (int)le16_to_cpu(*(__le16*)pBuf)) - 2;
 4308 
 4309 		if ( len <= 2 ) {
 4310 			airo_print_err(ai->dev->name,
 4311 				"Rid %x has a length of %d which is too short",
 4312 				(int)rid, (int)len );
 4313 			rc = ERROR;
 4314 	                goto done;
 4315 		}
 4316 		// read remainder of the rid
 4317 		rc = bap_read(ai, ((__le16*)pBuf)+1, len, BAP1);
 4318 	}
 4319 done:
 4320 	if (lock)
 4321 		up(&ai->sem);
 4322 	return rc;
 4323 }
 4324 
 4325 /*  Note, that we are using BAP1 which is also used by transmit, so
 4326  *  make sure this isn't called when a transmit is happening */
 4327 static int PC4500_writerid(struct airo_info *ai, u16 rid,
 4328 			   const void *pBuf, int len, int lock)
 4329 {
 4330 	u16 status;
 4331 	int rc = SUCCESS;
 4332 
 4333 	*(__le16*)pBuf = cpu_to_le16((u16)len);
 4334 
 4335 	if (lock) {
 4336 		if (down_interruptible(&ai->sem))
 4337 			return ERROR;
 4338 	}
 4339 	if (test_bit(FLAG_MPI,&ai->flags)) {
 4340 		Cmd cmd;
 4341 		Resp rsp;
 4342 
 4343 		if (test_bit(FLAG_ENABLED, &ai->flags) && (RID_WEP_TEMP != rid))
 4344 			airo_print_err(ai->dev->name,
 4345 				"%s: MAC should be disabled (rid=%04x)",
 4346 				__func__, rid);
 4347 		memset(&cmd, 0, sizeof(cmd));
 4348 		memset(&rsp, 0, sizeof(rsp));
 4349 
 4350 		ai->config_desc.rid_desc.valid = 1;
 4351 		ai->config_desc.rid_desc.len = *((u16 *)pBuf);
 4352 		ai->config_desc.rid_desc.rid = 0;
 4353 
 4354 		cmd.cmd = CMD_WRITERID;
 4355 		cmd.parm0 = rid;
 4356 
 4357 		memcpy_toio(ai->config_desc.card_ram_off,
 4358 			&ai->config_desc.rid_desc, sizeof(Rid));
 4359 
 4360 		if (len < 4 || len > 2047) {
 4361 			airo_print_err(ai->dev->name, "%s: len=%d", __func__, len);
 4362 			rc = -1;
 4363 		} else {
 4364 			memcpy(ai->config_desc.virtual_host_addr,
 4365 				pBuf, len);
 4366 
 4367 			rc = issuecommand(ai, &cmd, &rsp);
 4368 			if ((rc & 0xff00) != 0) {
 4369 				airo_print_err(ai->dev->name, "%s: Write rid Error %d",
 4370 						__func__, rc);
 4371 				airo_print_err(ai->dev->name, "%s: Cmd=%04x",
 4372 						__func__, cmd.cmd);
 4373 			}
 4374 
 4375 			if ((rsp.status & 0x7f00))
 4376 				rc = rsp.rsp0;
 4377 		}
 4378 	} else {
 4379 		// --- first access so that we can write the rid data
 4380 		if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != 0) {
 4381 	                rc = status;
 4382 	                goto done;
 4383 	        }
 4384 		// --- now write the rid data
 4385 		if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
 4386 	                rc = ERROR;
 4387 	                goto done;
 4388 	        }
 4389 		bap_write(ai, pBuf, len, BAP1);
 4390 		// ---now commit the rid data
 4391 		rc = PC4500_accessrid(ai, rid, 0x100|CMD_ACCESS);
 4392 	}
 4393 done:
 4394 	if (lock)
 4395 		up(&ai->sem);
 4396         return rc;
 4397 }
 4398 
 4399 /* Allocates a FID to be used for transmitting packets.  We only use
 4400    one for now. */
 4401 static u16 transmit_allocate(struct airo_info *ai, int lenPayload, int raw)
 4402 {
 4403 	unsigned int loop = 3000;
 4404 	Cmd cmd;
 4405 	Resp rsp;
 4406 	u16 txFid;
 4407 	__le16 txControl;
 4408 
 4409 	cmd.cmd = CMD_ALLOCATETX;
 4410 	cmd.parm0 = lenPayload;
 4411 	if (down_interruptible(&ai->sem))
 4412 		return ERROR;
 4413 	if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
 4414 		txFid = ERROR;
 4415 		goto done;
 4416 	}
 4417 	if ( (rsp.status & 0xFF00) != 0) {
 4418 		txFid = ERROR;
 4419 		goto done;
 4420 	}
 4421 	/* wait for the allocate event/indication
 4422 	 * It makes me kind of nervous that this can just sit here and spin,
 4423 	 * but in practice it only loops like four times. */
 4424 	while (((IN4500(ai, EVSTAT) & EV_ALLOC) == 0) && --loop);
 4425 	if (!loop) {
 4426 		txFid = ERROR;
 4427 		goto done;
 4428 	}
 4429 
 4430 	// get the allocated fid and acknowledge
 4431 	txFid = IN4500(ai, TXALLOCFID);
 4432 	OUT4500(ai, EVACK, EV_ALLOC);
 4433 
 4434 	/*  The CARD is pretty cool since it converts the ethernet packet
 4435 	 *  into 802.11.  Also note that we don't release the FID since we
 4436 	 *  will be using the same one over and over again. */
 4437 	/*  We only have to setup the control once since we are not
 4438 	 *  releasing the fid. */
 4439 	if (raw)
 4440 		txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_11
 4441 			| TXCTL_ETHERNET | TXCTL_NORELEASE);
 4442 	else
 4443 		txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_3
 4444 			| TXCTL_ETHERNET | TXCTL_NORELEASE);
 4445 	if (bap_setup(ai, txFid, 0x0008, BAP1) != SUCCESS)
 4446 		txFid = ERROR;
 4447 	else
 4448 		bap_write(ai, &txControl, sizeof(txControl), BAP1);
 4449 
 4450 done:
 4451 	up(&ai->sem);
 4452 
 4453 	return txFid;
 4454 }
 4455 
 4456 /* In general BAP1 is dedicated to transmiting packets.  However,
 4457    since we need a BAP when accessing RIDs, we also use BAP1 for that.
 4458    Make sure the BAP1 spinlock is held when this is called. */
 4459 static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket)
 4460 {
 4461 	__le16 payloadLen;
 4462 	Cmd cmd;
 4463 	Resp rsp;
 4464 	int miclen = 0;
 4465 	u16 txFid = len;
 4466 	MICBuffer pMic;
 4467 
 4468 	len >>= 16;
 4469 
 4470 	if (len <= ETH_ALEN * 2) {
 4471 		airo_print_warn(ai->dev->name, "Short packet %d", len);
 4472 		return ERROR;
 4473 	}
 4474 	len -= ETH_ALEN * 2;
 4475 
 4476 	if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled && 
 4477 	    (ntohs(((__be16 *)pPacket)[6]) != 0x888E)) {
 4478 		if (encapsulate(ai,(etherHead *)pPacket,&pMic,len) != SUCCESS)
 4479 			return ERROR;
 4480 		miclen = sizeof(pMic);
 4481 	}
 4482 	// packet is destination[6], source[6], payload[len-12]
 4483 	// write the payload length and dst/src/payload
 4484 	if (bap_setup(ai, txFid, 0x0036, BAP1) != SUCCESS) return ERROR;
 4485 	/* The hardware addresses aren't counted as part of the payload, so
 4486 	 * we have to subtract the 12 bytes for the addresses off */
 4487 	payloadLen = cpu_to_le16(len + miclen);
 4488 	bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
 4489 	bap_write(ai, (__le16*)pPacket, sizeof(etherHead), BAP1);
 4490 	if (miclen)
 4491 		bap_write(ai, (__le16*)&pMic, miclen, BAP1);
 4492 	bap_write(ai, (__le16*)(pPacket + sizeof(etherHead)), len, BAP1);
 4493 	// issue the transmit command
 4494 	memset( &cmd, 0, sizeof( cmd ) );
 4495 	cmd.cmd = CMD_TRANSMIT;
 4496 	cmd.parm0 = txFid;
 4497 	if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
 4498 	if ( (rsp.status & 0xFF00) != 0) return ERROR;
 4499 	return SUCCESS;
 4500 }
 4501 
 4502 static int transmit_802_11_packet(struct airo_info *ai, int len, char *pPacket)
 4503 {
 4504 	__le16 fc, payloadLen;
 4505 	Cmd cmd;
 4506 	Resp rsp;
 4507 	int hdrlen;
 4508 	static u8 tail[(30-10) + 2 + 6] = {[30-10] = 6};
 4509 	/* padding of header to full size + le16 gaplen (6) + gaplen bytes */
 4510 	u16 txFid = len;
 4511 	len >>= 16;
 4512 
 4513 	fc = *(__le16*)pPacket;
 4514 	hdrlen = header_len(fc);
 4515 
 4516 	if (len < hdrlen) {
 4517 		airo_print_warn(ai->dev->name, "Short packet %d", len);
 4518 		return ERROR;
 4519 	}
 4520 
 4521 	/* packet is 802.11 header +  payload
 4522 	 * write the payload length and dst/src/payload */
 4523 	if (bap_setup(ai, txFid, 6, BAP1) != SUCCESS) return ERROR;
 4524 	/* The 802.11 header aren't counted as part of the payload, so
 4525 	 * we have to subtract the header bytes off */
 4526 	payloadLen = cpu_to_le16(len-hdrlen);
 4527 	bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
 4528 	if (bap_setup(ai, txFid, 0x0014, BAP1) != SUCCESS) return ERROR;
 4529 	bap_write(ai, (__le16 *)pPacket, hdrlen, BAP1);
 4530 	bap_write(ai, (__le16 *)(tail + (hdrlen - 10)), 38 - hdrlen, BAP1);
 4531 
 4532 	bap_write(ai, (__le16 *)(pPacket + hdrlen), len - hdrlen, BAP1);
 4533 	// issue the transmit command
 4534 	memset( &cmd, 0, sizeof( cmd ) );
 4535 	cmd.cmd = CMD_TRANSMIT;
 4536 	cmd.parm0 = txFid;
 4537 	if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
 4538 	if ( (rsp.status & 0xFF00) != 0) return ERROR;
 4539 	return SUCCESS;
 4540 }
 4541 
 4542 /*
 4543  *  This is the proc_fs routines.  It is a bit messier than I would
 4544  *  like!  Feel free to clean it up!
 4545  */
 4546 
 4547 static ssize_t proc_read( struct file *file,
 4548 			  char __user *buffer,
 4549 			  size_t len,
 4550 			  loff_t *offset);
 4551 
 4552 static ssize_t proc_write( struct file *file,
 4553 			   const char __user *buffer,
 4554 			   size_t len,
 4555 			   loff_t *offset );
 4556 static int proc_close( struct inode *inode, struct file *file );
 4557 
 4558 static int proc_stats_open( struct inode *inode, struct file *file );
 4559 static int proc_statsdelta_open( struct inode *inode, struct file *file );
 4560 static int proc_status_open( struct inode *inode, struct file *file );
 4561 static int proc_SSID_open( struct inode *inode, struct file *file );
 4562 static int proc_APList_open( struct inode *inode, struct file *file );
 4563 static int proc_BSSList_open( struct inode *inode, struct file *file );
 4564 static int proc_config_open( struct inode *inode, struct file *file );
 4565 static int proc_wepkey_open( struct inode *inode, struct file *file );
 4566 
 4567 static const struct file_operations proc_statsdelta_ops = {
 4568 	.owner		= THIS_MODULE,
 4569 	.read		= proc_read,
 4570 	.open		= proc_statsdelta_open,
 4571 	.release	= proc_close,
 4572 	.llseek		= default_llseek,
 4573 };
 4574 
 4575 static const struct file_operations proc_stats_ops = {
 4576 	.owner		= THIS_MODULE,
 4577 	.read		= proc_read,
 4578 	.open		= proc_stats_open,
 4579 	.release	= proc_close,
 4580 	.llseek		= default_llseek,
 4581 };
 4582 
 4583 static const struct file_operations proc_status_ops = {
 4584 	.owner		= THIS_MODULE,
 4585 	.read		= proc_read,
 4586 	.open		= proc_status_open,
 4587 	.release	= proc_close,
 4588 	.llseek		= default_llseek,
 4589 };
 4590 
 4591 static const struct file_operations proc_SSID_ops = {
 4592 	.owner		= THIS_MODULE,
 4593 	.read		= proc_read,
 4594 	.write		= proc_write,
 4595 	.open		= proc_SSID_open,
 4596 	.release	= proc_close,
 4597 	.llseek		= default_llseek,
 4598 };
 4599 
 4600 static const struct file_operations proc_BSSList_ops = {
 4601 	.owner		= THIS_MODULE,
 4602 	.read		= proc_read,
 4603 	.write		= proc_write,
 4604 	.open		= proc_BSSList_open,
 4605 	.release	= proc_close,
 4606 	.llseek		= default_llseek,
 4607 };
 4608 
 4609 static const struct file_operations proc_APList_ops = {
 4610 	.owner		= THIS_MODULE,
 4611 	.read		= proc_read,
 4612 	.write		= proc_write,
 4613 	.open		= proc_APList_open,
 4614 	.release	= proc_close,
 4615 	.llseek		= default_llseek,
 4616 };
 4617 
 4618 static const struct file_operations proc_config_ops = {
 4619 	.owner		= THIS_MODULE,
 4620 	.read		= proc_read,
 4621 	.write		= proc_write,
 4622 	.open		= proc_config_open,
 4623 	.release	= proc_close,
 4624 	.llseek		= default_llseek,
 4625 };
 4626 
 4627 static const struct file_operations proc_wepkey_ops = {
 4628 	.owner		= THIS_MODULE,
 4629 	.read		= proc_read,
 4630 	.write		= proc_write,
 4631 	.open		= proc_wepkey_open,
 4632 	.release	= proc_close,
 4633 	.llseek		= default_llseek,
 4634 };
 4635 
 4636 static struct proc_dir_entry *airo_entry;
 4637 
 4638 struct proc_data {
 4639 	int release_buffer;
 4640 	int readlen;
 4641 	char *rbuffer;
 4642 	int writelen;
 4643 	int maxwritelen;
 4644 	char *wbuffer;
 4645 	void (*on_close) (struct inode *, struct file *);
 4646 };
 4647 
 4648 static int setup_proc_entry( struct net_device *dev,
 4649 			     struct airo_info *apriv ) {
 4650 	struct proc_dir_entry *entry;
 4651 
 4652 	/* First setup the device directory */
 4653 	strcpy(apriv->proc_name,dev->name);
 4654 	apriv->proc_entry = proc_mkdir_mode(apriv->proc_name, airo_perm,
 4655 					    airo_entry);
 4656 	if (!apriv->proc_entry)
 4657 		return -ENOMEM;
 4658 	proc_set_user(apriv->proc_entry, proc_kuid, proc_kgid);
 4659 
 4660 	/* Setup the StatsDelta */
 4661 	entry = proc_create_data("StatsDelta", S_IRUGO & proc_perm,
 4662 				 apriv->proc_entry, &proc_statsdelta_ops, dev);
 4663 	if (!entry)
 4664 		goto fail;
 4665 	proc_set_user(entry, proc_kuid, proc_kgid);
 4666 
 4667 	/* Setup the Stats */
 4668 	entry = proc_create_data("Stats", S_IRUGO & proc_perm,
 4669 				 apriv->proc_entry, &proc_stats_ops, dev);
 4670 	if (!entry)
 4671 		goto fail;
 4672 	proc_set_user(entry, proc_kuid, proc_kgid);
 4673 
 4674 	/* Setup the Status */
 4675 	entry = proc_create_data("Status", S_IRUGO & proc_perm,
 4676 				 apriv->proc_entry, &proc_status_ops, dev);
 4677 	if (!entry)
 4678 		goto fail;
 4679 	proc_set_user(entry, proc_kuid, proc_kgid);
 4680 
 4681 	/* Setup the Config */
 4682 	entry = proc_create_data("Config", proc_perm,
 4683 				 apriv->proc_entry, &proc_config_ops, dev);
 4684 	if (!entry)
 4685 		goto fail;
 4686 	proc_set_user(entry, proc_kuid, proc_kgid);
 4687 
 4688 	/* Setup the SSID */
 4689 	entry = proc_create_data("SSID", proc_perm,
 4690 				 apriv->proc_entry, &proc_SSID_ops, dev);
 4691 	if (!entry)
 4692 		goto fail;
 4693 	proc_set_user(entry, proc_kuid, proc_kgid);
 4694 
 4695 	/* Setup the APList */
 4696 	entry = proc_create_data("APList", proc_perm,
 4697 				 apriv->proc_entry, &proc_APList_ops, dev);
 4698 	if (!entry)
 4699 		goto fail;
 4700 	proc_set_user(entry, proc_kuid, proc_kgid);
 4701 
 4702 	/* Setup the BSSList */
 4703 	entry = proc_create_data("BSSList", proc_perm,
 4704 				 apriv->proc_entry, &proc_BSSList_ops, dev);
 4705 	if (!entry)
 4706 		goto fail;
 4707 	proc_set_user(entry, proc_kuid, proc_kgid);
 4708 
 4709 	/* Setup the WepKey */
 4710 	entry = proc_create_data("WepKey", proc_perm,
 4711 				 apriv->proc_entry, &proc_wepkey_ops, dev);
 4712 	if (!entry)
 4713 		goto fail;
 4714 	proc_set_user(entry, proc_kuid, proc_kgid);
 4715 	return 0;
 4716 
 4717 fail:
 4718 	remove_proc_subtree(apriv->proc_name, airo_entry);
 4719 	return -ENOMEM;
 4720 }
 4721 
 4722 static int takedown_proc_entry( struct net_device *dev,
 4723 				struct airo_info *apriv )
 4724 {
 4725 	remove_proc_subtree(apriv->proc_name, airo_entry);
 4726 	return 0;
 4727 }
 4728 
 4729 /*
 4730  *  What we want from the proc_fs is to be able to efficiently read
 4731  *  and write the configuration.  To do this, we want to read the
 4732  *  configuration when the file is opened and write it when the file is
 4733  *  closed.  So basically we allocate a read buffer at open and fill it
 4734  *  with data, and allocate a write buffer and read it at close.
 4735  */
 4736 
 4737 /*
 4738  *  The read routine is generic, it relies on the preallocated rbuffer
 4739  *  to supply the data.
 4740  */
 4741 static ssize_t proc_read( struct file *file,
 4742 			  char __user *buffer,
 4743 			  size_t len,
 4744 			  loff_t *offset )
 4745 {
 4746 	struct proc_data *priv = file->private_data;
 4747 
 4748 	if (!priv->rbuffer)
 4749 		return -EINVAL;
 4750 
 4751 	return simple_read_from_buffer(buffer, len, offset, priv->rbuffer,
 4752 					priv->readlen);
 4753 }
 4754 
 4755 /*
 4756  *  The write routine is generic, it fills in a preallocated rbuffer
 4757  *  to supply the data.
 4758  */
 4759 static ssize_t proc_write( struct file *file,
 4760 			   const char __user *buffer,
 4761 			   size_t len,
 4762 			   loff_t *offset )
 4763 {
 4764 	ssize_t ret;
 4765 	struct proc_data *priv = file->private_data;
 4766 
 4767 	if (!priv->wbuffer)
 4768 		return -EINVAL;
 4769 
 4770 	ret = simple_write_to_buffer(priv->wbuffer, priv->maxwritelen, offset,
 4771 					buffer, len);
 4772 	if (ret > 0)
 4773 		priv->writelen = max_t(int, priv->writelen, *offset);
 4774 
 4775 	return ret;
 4776 }
 4777 
 4778 static int proc_status_open(struct inode *inode, struct file *file)
 4779 {
 4780 	struct proc_data *data;
 4781 	struct net_device *dev = PDE_DATA(inode);
 4782 	struct airo_info *apriv = dev->ml_priv;
 4783 	CapabilityRid cap_rid;
 4784 	StatusRid status_rid;
 4785 	u16 mode;
 4786 	int i;
 4787 
 4788 	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 4789 		return -ENOMEM;
 4790 	data = file->private_data;
 4791 	if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
 4792 		kfree (file->private_data);
 4793 		return -ENOMEM;
 4794 	}
 4795 
 4796 	readStatusRid(apriv, &status_rid, 1);
 4797 	readCapabilityRid(apriv, &cap_rid, 1);
 4798 
 4799 	mode = le16_to_cpu(status_rid.mode);
 4800 
 4801         i = sprintf(data->rbuffer, "Status: %s%s%s%s%s%s%s%s%s\n",
 4802                     mode & 1 ? "CFG ": "",
 4803                     mode & 2 ? "ACT ": "",
 4804                     mode & 0x10 ? "SYN ": "",
 4805                     mode & 0x20 ? "LNK ": "",
 4806                     mode & 0x40 ? "LEAP ": "",
 4807                     mode & 0x80 ? "PRIV ": "",
 4808                     mode & 0x100 ? "KEY ": "",
 4809                     mode & 0x200 ? "WEP ": "",
 4810                     mode & 0x8000 ? "ERR ": "");
 4811 	sprintf( data->rbuffer+i, "Mode: %x\n"
 4812 		 "Signal Strength: %d\n"
 4813 		 "Signal Quality: %d\n"
 4814 		 "SSID: %-.*s\n"
 4815 		 "AP: %-.16s\n"
 4816 		 "Freq: %d\n"
 4817 		 "BitRate: %dmbs\n"
 4818 		 "Driver Version: %s\n"
 4819 		 "Device: %s\nManufacturer: %s\nFirmware Version: %s\n"
 4820 		 "Radio type: %x\nCountry: %x\nHardware Version: %x\n"
 4821 		 "Software Version: %x\nSoftware Subversion: %x\n"
 4822 		 "Boot block version: %x\n",
 4823 		 le16_to_cpu(status_rid.mode),
 4824 		 le16_to_cpu(status_rid.normalizedSignalStrength),
 4825 		 le16_to_cpu(status_rid.signalQuality),
 4826 		 le16_to_cpu(status_rid.SSIDlen),
 4827 		 status_rid.SSID,
 4828 		 status_rid.apName,
 4829 		 le16_to_cpu(status_rid.channel),
 4830 		 le16_to_cpu(status_rid.currentXmitRate) / 2,
 4831 		 version,
 4832 		 cap_rid.prodName,
 4833 		 cap_rid.manName,
 4834 		 cap_rid.prodVer,
 4835 		 le16_to_cpu(cap_rid.radioType),
 4836 		 le16_to_cpu(cap_rid.country),
 4837 		 le16_to_cpu(cap_rid.hardVer),
 4838 		 le16_to_cpu(cap_rid.softVer),
 4839 		 le16_to_cpu(cap_rid.softSubVer),
 4840 		 le16_to_cpu(cap_rid.bootBlockVer));
 4841 	data->readlen = strlen( data->rbuffer );
 4842 	return 0;
 4843 }
 4844 
 4845 static int proc_stats_rid_open(struct inode*, struct file*, u16);
 4846 static int proc_statsdelta_open( struct inode *inode,
 4847 				 struct file *file ) {
 4848 	if (file->f_mode&FMODE_WRITE) {
 4849 		return proc_stats_rid_open(inode, file, RID_STATSDELTACLEAR);
 4850 	}
 4851 	return proc_stats_rid_open(inode, file, RID_STATSDELTA);
 4852 }
 4853 
 4854 static int proc_stats_open( struct inode *inode, struct file *file ) {
 4855 	return proc_stats_rid_open(inode, file, RID_STATS);
 4856 }
 4857 
 4858 static int proc_stats_rid_open( struct inode *inode,
 4859 				struct file *file,
 4860 				u16 rid )
 4861 {
 4862 	struct proc_data *data;
 4863 	struct net_device *dev = PDE_DATA(inode);
 4864 	struct airo_info *apriv = dev->ml_priv;
 4865 	StatsRid stats;
 4866 	int i, j;
 4867 	__le32 *vals = stats.vals;
 4868 	int len;
 4869 
 4870 	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 4871 		return -ENOMEM;
 4872 	data = file->private_data;
 4873 	if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) {
 4874 		kfree (file->private_data);
 4875 		return -ENOMEM;
 4876 	}
 4877 
 4878 	readStatsRid(apriv, &stats, rid, 1);
 4879 	len = le16_to_cpu(stats.len);
 4880 
 4881         j = 0;
 4882 	for(i=0; statsLabels[i]!=(char *)-1 && i*4<len; i++) {
 4883 		if (!statsLabels[i]) continue;
 4884 		if (j+strlen(statsLabels[i])+16>4096) {
 4885 			airo_print_warn(apriv->dev->name,
 4886 			       "Potentially disastrous buffer overflow averted!");
 4887 			break;
 4888 		}
 4889 		j+=sprintf(data->rbuffer+j, "%s: %u\n", statsLabels[i],
 4890 				le32_to_cpu(vals[i]));
 4891 	}
 4892 	if (i*4 >= len) {
 4893 		airo_print_warn(apriv->dev->name, "Got a short rid");
 4894 	}
 4895 	data->readlen = j;
 4896 	return 0;
 4897 }
 4898 
 4899 static int get_dec_u16( char *buffer, int *start, int limit ) {
 4900 	u16 value;
 4901 	int valid = 0;
 4902 	for (value = 0; *start < limit && buffer[*start] >= '0' &&
 4903 			buffer[*start] <= '9'; (*start)++) {
 4904 		valid = 1;
 4905 		value *= 10;
 4906 		value += buffer[*start] - '0';
 4907 	}
 4908 	if ( !valid ) return -1;
 4909 	return value;
 4910 }
 4911 
 4912 static int airo_config_commit(struct net_device *dev,
 4913 			      struct iw_request_info *info, void *zwrq,
 4914 			      char *extra);
 4915 
 4916 static inline int sniffing_mode(struct airo_info *ai)
 4917 {
 4918 	return (le16_to_cpu(ai->config.rmode) & le16_to_cpu(RXMODE_MASK)) >=
 4919 		le16_to_cpu(RXMODE_RFMON);
 4920 }
 4921 
 4922 static void proc_config_on_close(struct inode *inode, struct file *file)
 4923 {
 4924 	struct proc_data *data = file->private_data;
 4925 	struct net_device *dev = PDE_DATA(inode);
 4926 	struct airo_info *ai = dev->ml_priv;
 4927 	char *line;
 4928 
 4929 	if ( !data->writelen ) return;
 4930 
 4931 	readConfigRid(ai, 1);
 4932 	set_bit (FLAG_COMMIT, &ai->flags);
 4933 
 4934 	line = data->wbuffer;
 4935 	while( line[0] ) {
 4936 /*** Mode processing */
 4937 		if ( !strncmp( line, "Mode: ", 6 ) ) {
 4938 			line += 6;
 4939 			if (sniffing_mode(ai))
 4940 				set_bit (FLAG_RESET, &ai->flags);
 4941 			ai->config.rmode &= ~RXMODE_FULL_MASK;
 4942 			clear_bit (FLAG_802_11, &ai->flags);
 4943 			ai->config.opmode &= ~MODE_CFG_MASK;
 4944 			ai->config.scanMode = SCANMODE_ACTIVE;
 4945 			if ( line[0] == 'a' ) {
 4946 				ai->config.opmode |= MODE_STA_IBSS;
 4947 			} else {
 4948 				ai->config.opmode |= MODE_STA_ESS;
 4949 				if ( line[0] == 'r' ) {
 4950 					ai->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
 4951 					ai->config.scanMode = SCANMODE_PASSIVE;
 4952 					set_bit (FLAG_802_11, &ai->flags);
 4953 				} else if ( line[0] == 'y' ) {
 4954 					ai->config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER;
 4955 					ai->config.scanMode = SCANMODE_PASSIVE;
 4956 					set_bit (FLAG_802_11, &ai->flags);
 4957 				} else if ( line[0] == 'l' )
 4958 					ai->config.rmode |= RXMODE_LANMON;
 4959 			}
 4960 			set_bit (FLAG_COMMIT, &ai->flags);
 4961 		}
 4962 
 4963 /*** Radio status */
 4964 		else if (!strncmp(line,"Radio: ", 7)) {
 4965 			line += 7;
 4966 			if (!strncmp(line,"off",3)) {
 4967 				set_bit (FLAG_RADIO_OFF, &ai->flags);
 4968 			} else {
 4969 				clear_bit (FLAG_RADIO_OFF, &ai->flags);
 4970 			}
 4971 		}
 4972 /*** NodeName processing */
 4973 		else if ( !strncmp( line, "NodeName: ", 10 ) ) {
 4974 			int j;
 4975 
 4976 			line += 10;
 4977 			memset( ai->config.nodeName, 0, 16 );
 4978 /* Do the name, assume a space between the mode and node name */
 4979 			for( j = 0; j < 16 && line[j] != '\n'; j++ ) {
 4980 				ai->config.nodeName[j] = line[j];
 4981 			}
 4982 			set_bit (FLAG_COMMIT, &ai->flags);
 4983 		}
 4984 
 4985 /*** PowerMode processing */
 4986 		else if ( !strncmp( line, "PowerMode: ", 11 ) ) {
 4987 			line += 11;
 4988 			if ( !strncmp( line, "PSPCAM", 6 ) ) {
 4989 				ai->config.powerSaveMode = POWERSAVE_PSPCAM;
 4990 				set_bit (FLAG_COMMIT, &ai->flags);
 4991 			} else if ( !strncmp( line, "PSP", 3 ) ) {
 4992 				ai->config.powerSaveMode = POWERSAVE_PSP;
 4993 				set_bit (FLAG_COMMIT, &ai->flags);
 4994 			} else {
 4995 				ai->config.powerSaveMode = POWERSAVE_CAM;
 4996 				set_bit (FLAG_COMMIT, &ai->flags);
 4997 			}
 4998 		} else if ( !strncmp( line, "DataRates: ", 11 ) ) {
 4999 			int v, i = 0, k = 0; /* i is index into line,
 5000 						k is index to rates */
 5001 
 5002 			line += 11;
 5003 			while((v = get_dec_u16(line, &i, 3))!=-1) {
 5004 				ai->config.rates[k++] = (u8)v;
 5005 				line += i + 1;
 5006 				i = 0;
 5007 			}
 5008 			set_bit (FLAG_COMMIT, &ai->flags);
 5009 		} else if ( !strncmp( line, "Channel: ", 9 ) ) {
 5010 			int v, i = 0;
 5011 			line += 9;
 5012 			v = get_dec_u16(line, &i, i+3);
 5013 			if ( v != -1 ) {
 5014 				ai->config.channelSet = cpu_to_le16(v);
 5015 				set_bit (FLAG_COMMIT, &ai->flags);
 5016 			}
 5017 		} else if ( !strncmp( line, "XmitPower: ", 11 ) ) {
 5018 			int v, i = 0;
 5019 			line += 11;
 5020 			v = get_dec_u16(line, &i, i+3);
 5021 			if ( v != -1 ) {
 5022 				ai->config.txPower = cpu_to_le16(v);
 5023 				set_bit (FLAG_COMMIT, &ai->flags);
 5024 			}
 5025 		} else if ( !strncmp( line, "WEP: ", 5 ) ) {
 5026 			line += 5;
 5027 			switch( line[0] ) {
 5028 			case 's':
 5029 				set_auth_type(ai, AUTH_SHAREDKEY);
 5030 				break;
 5031 			case 'e':
 5032 				set_auth_type(ai, AUTH_ENCRYPT);
 5033 				break;
 5034 			default:
 5035 				set_auth_type(ai, AUTH_OPEN);
 5036 				break;
 5037 			}
 5038 			set_bit (FLAG_COMMIT, &ai->flags);
 5039 		} else if ( !strncmp( line, "LongRetryLimit: ", 16 ) ) {
 5040 			int v, i = 0;
 5041 
 5042 			line += 16;
 5043 			v = get_dec_u16(line, &i, 3);
 5044 			v = (v<0) ? 0 : ((v>255) ? 255 : v);
 5045 			ai->config.longRetryLimit = cpu_to_le16(v);
 5046 			set_bit (FLAG_COMMIT, &ai->flags);
 5047 		} else if ( !strncmp( line, "ShortRetryLimit: ", 17 ) ) {
 5048 			int v, i = 0;
 5049 
 5050 			line += 17;
 5051 			v = get_dec_u16(line, &i, 3);
 5052 			v = (v<0) ? 0 : ((v>255) ? 255 : v);
 5053 			ai->config.shortRetryLimit = cpu_to_le16(v);
 5054 			set_bit (FLAG_COMMIT, &ai->flags);
 5055 		} else if ( !strncmp( line, "RTSThreshold: ", 14 ) ) {
 5056 			int v, i = 0;
 5057 
 5058 			line += 14;
 5059 			v = get_dec_u16(line, &i, 4);
 5060 			v = (v<0) ? 0 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
 5061 			ai->config.rtsThres = cpu_to_le16(v);
 5062 			set_bit (FLAG_COMMIT, &ai->flags);
 5063 		} else if ( !strncmp( line, "TXMSDULifetime: ", 16 ) ) {
 5064 			int v, i = 0;
 5065 
 5066 			line += 16;
 5067 			v = get_dec_u16(line, &i, 5);
 5068 			v = (v<0) ? 0 : v;
 5069 			ai->config.txLifetime = cpu_to_le16(v);
 5070 			set_bit (FLAG_COMMIT, &ai->flags);
 5071 		} else if ( !strncmp( line, "RXMSDULifetime: ", 16 ) ) {
 5072 			int v, i = 0;
 5073 
 5074 			line += 16;
 5075 			v = get_dec_u16(line, &i, 5);
 5076 			v = (v<0) ? 0 : v;
 5077 			ai->config.rxLifetime = cpu_to_le16(v);
 5078 			set_bit (FLAG_COMMIT, &ai->flags);
 5079 		} else if ( !strncmp( line, "TXDiversity: ", 13 ) ) {
 5080 			ai->config.txDiversity =
 5081 				(line[13]=='l') ? 1 :
 5082 				((line[13]=='r')? 2: 3);
 5083 			set_bit (FLAG_COMMIT, &ai->flags);
 5084 		} else if ( !strncmp( line, "RXDiversity: ", 13 ) ) {
 5085 			ai->config.rxDiversity =
 5086 				(line[13]=='l') ? 1 :
 5087 				((line[13]=='r')? 2: 3);
 5088 			set_bit (FLAG_COMMIT, &ai->flags);
 5089 		} else if ( !strncmp( line, "FragThreshold: ", 15 ) ) {
 5090 			int v, i = 0;
 5091 
 5092 			line += 15;
 5093 			v = get_dec_u16(line, &i, 4);
 5094 			v = (v<256) ? 256 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
 5095 			v = v & 0xfffe; /* Make sure its even */
 5096 			ai->config.fragThresh = cpu_to_le16(v);
 5097 			set_bit (FLAG_COMMIT, &ai->flags);
 5098 		} else if (!strncmp(line, "Modulation: ", 12)) {
 5099 			line += 12;
 5100 			switch(*line) {
 5101 			case 'd':  ai->config.modulation=MOD_DEFAULT; set_bit(FLAG_COMMIT, &ai->flags); break;
 5102 			case 'c':  ai->config.modulation=MOD_CCK; set_bit(FLAG_COMMIT, &ai->flags); break;
 5103 			case 'm':  ai->config.modulation=MOD_MOK; set_bit(FLAG_COMMIT, &ai->flags); break;
 5104 			default: airo_print_warn(ai->dev->name, "Unknown modulation");
 5105 			}
 5106 		} else if (!strncmp(line, "Preamble: ", 10)) {
 5107 			line += 10;
 5108 			switch(*line) {
 5109 			case 'a': ai->config.preamble=PREAMBLE_AUTO; set_bit(FLAG_COMMIT, &ai->flags); break;
 5110 			case 'l': ai->config.preamble=PREAMBLE_LONG; set_bit(FLAG_COMMIT, &ai->flags); break;
 5111 			case 's': ai->config.preamble=PREAMBLE_SHORT; set_bit(FLAG_COMMIT, &ai->flags); break;
 5112 			default: airo_print_warn(ai->dev->name, "Unknown preamble");
 5113 			}
 5114 		} else {
 5115 			airo_print_warn(ai->dev->name, "Couldn't figure out %s", line);
 5116 		}
 5117 		while( line[0] && line[0] != '\n' ) line++;
 5118 		if ( line[0] ) line++;
 5119 	}
 5120 	airo_config_commit(dev, NULL, NULL, NULL);
 5121 }
 5122 
 5123 static const char *get_rmode(__le16 mode)
 5124 {
 5125         switch(mode & RXMODE_MASK) {
 5126         case RXMODE_RFMON:  return "rfmon";
 5127         case RXMODE_RFMON_ANYBSS:  return "yna (any) bss rfmon";
 5128         case RXMODE_LANMON:  return "lanmon";
 5129         }
 5130         return "ESS";
 5131 }
 5132 
 5133 static int proc_config_open(struct inode *inode, struct file *file)
 5134 {
 5135 	struct proc_data *data;
 5136 	struct net_device *dev = PDE_DATA(inode);
 5137 	struct airo_info *ai = dev->ml_priv;
 5138 	int i;
 5139 	__le16 mode;
 5140 
 5141 	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 5142 		return -ENOMEM;
 5143 	data = file->private_data;
 5144 	if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
 5145 		kfree (file->private_data);
 5146 		return -ENOMEM;
 5147 	}
 5148 	if ((data->wbuffer = kzalloc( 2048, GFP_KERNEL )) == NULL) {
 5149 		kfree (data->rbuffer);
 5150 		kfree (file->private_data);
 5151 		return -ENOMEM;
 5152 	}
 5153 	data->maxwritelen = 2048;
 5154 	data->on_close = proc_config_on_close;
 5155 
 5156 	readConfigRid(ai, 1);
 5157 
 5158 	mode = ai->config.opmode & MODE_CFG_MASK;
 5159 	i = sprintf( data->rbuffer,
 5160 		     "Mode: %s\n"
 5161 		     "Radio: %s\n"
 5162 		     "NodeName: %-16s\n"
 5163 		     "PowerMode: %s\n"
 5164 		     "DataRates: %d %d %d %d %d %d %d %d\n"
 5165 		     "Channel: %d\n"
 5166 		     "XmitPower: %d\n",
 5167 		     mode == MODE_STA_IBSS ? "adhoc" :
 5168 		     mode == MODE_STA_ESS ? get_rmode(ai->config.rmode):
 5169 		     mode == MODE_AP ? "AP" :
 5170 		     mode == MODE_AP_RPTR ? "AP RPTR" : "Error",
 5171 		     test_bit(FLAG_RADIO_OFF, &ai->flags) ? "off" : "on",
 5172 		     ai->config.nodeName,
 5173 		     ai->config.powerSaveMode == POWERSAVE_CAM ? "CAM" :
 5174 		     ai->config.powerSaveMode == POWERSAVE_PSP ? "PSP" :
 5175 		     ai->config.powerSaveMode == POWERSAVE_PSPCAM ? "PSPCAM" :
 5176 		     "Error",
 5177 		     (int)ai->config.rates[0],
 5178 		     (int)ai->config.rates[1],
 5179 		     (int)ai->config.rates[2],
 5180 		     (int)ai->config.rates[3],
 5181 		     (int)ai->config.rates[4],
 5182 		     (int)ai->config.rates[5],
 5183 		     (int)ai->config.rates[6],
 5184 		     (int)ai->config.rates[7],
 5185 		     le16_to_cpu(ai->config.channelSet),
 5186 		     le16_to_cpu(ai->config.txPower)
 5187 		);
 5188 	sprintf( data->rbuffer + i,
 5189 		 "LongRetryLimit: %d\n"
 5190 		 "ShortRetryLimit: %d\n"
 5191 		 "RTSThreshold: %d\n"
 5192 		 "TXMSDULifetime: %d\n"
 5193 		 "RXMSDULifetime: %d\n"
 5194 		 "TXDiversity: %s\n"
 5195 		 "RXDiversity: %s\n"
 5196 		 "FragThreshold: %d\n"
 5197 		 "WEP: %s\n"
 5198 		 "Modulation: %s\n"
 5199 		 "Preamble: %s\n",
 5200 		 le16_to_cpu(ai->config.longRetryLimit),
 5201 		 le16_to_cpu(ai->config.shortRetryLimit),
 5202 		 le16_to_cpu(ai->config.rtsThres),
 5203 		 le16_to_cpu(ai->config.txLifetime),
 5204 		 le16_to_cpu(ai->config.rxLifetime),
 5205 		 ai->config.txDiversity == 1 ? "left" :
 5206 		 ai->config.txDiversity == 2 ? "right" : "both",
 5207 		 ai->config.rxDiversity == 1 ? "left" :
 5208 		 ai->config.rxDiversity == 2 ? "right" : "both",
 5209 		 le16_to_cpu(ai->config.fragThresh),
 5210 		 ai->config.authType == AUTH_ENCRYPT ? "encrypt" :
 5211 		 ai->config.authType == AUTH_SHAREDKEY ? "shared" : "open",
 5212 		 ai->config.modulation == MOD_DEFAULT ? "default" :
 5213 		 ai->config.modulation == MOD_CCK ? "cck" :
 5214 		 ai->config.modulation == MOD_MOK ? "mok" : "error",
 5215 		 ai->config.preamble == PREAMBLE_AUTO ? "auto" :
 5216 		 ai->config.preamble == PREAMBLE_LONG ? "long" :
 5217 		 ai->config.preamble == PREAMBLE_SHORT ? "short" : "error"
 5218 		);
 5219 	data->readlen = strlen( data->rbuffer );
 5220 	return 0;
 5221 }
 5222 
 5223 static void proc_SSID_on_close(struct inode *inode, struct file *file)
 5224 {
 5225 	struct proc_data *data = file->private_data;
 5226 	struct net_device *dev = PDE_DATA(inode);
 5227 	struct airo_info *ai = dev->ml_priv;
 5228 	SsidRid SSID_rid;
 5229 	int i;
 5230 	char *p = data->wbuffer;
 5231 	char *end = p + data->writelen;
 5232 
 5233 	if (!data->writelen)
 5234 		return;
 5235 
 5236 	*end = '\n'; /* sentinel; we have space for it */
 5237 
 5238 	memset(&SSID_rid, 0, sizeof(SSID_rid));
 5239 
 5240 	for (i = 0; i < 3 && p < end; i++) {
 5241 		int j = 0;
 5242 		/* copy up to 32 characters from this line */
 5243 		while (*p != '\n' && j < 32)
 5244 			SSID_rid.ssids[i].ssid[j++] = *p++;
 5245 		if (j == 0)
 5246 			break;
 5247 		SSID_rid.ssids[i].len = cpu_to_le16(j);
 5248 		/* skip to the beginning of the next line */
 5249 		while (*p++ != '\n')
 5250 			;
 5251 	}
 5252 	if (i)
 5253 		SSID_rid.len = cpu_to_le16(sizeof(SSID_rid));
 5254 	disable_MAC(ai, 1);
 5255 	writeSsidRid(ai, &SSID_rid, 1);
 5256 	enable_MAC(ai, 1);
 5257 }
 5258 
 5259 static void proc_APList_on_close( struct inode *inode, struct file *file ) {
 5260 	struct proc_data *data = file->private_data;
 5261 	struct net_device *dev = PDE_DATA(inode);
 5262 	struct airo_info *ai = dev->ml_priv;
 5263 	APListRid *APList_rid = &ai->APList;
 5264 	int i;
 5265 
 5266 	if ( !data->writelen ) return;
 5267 
 5268 	memset(APList_rid, 0, sizeof(*APList_rid));
 5269 	APList_rid->len = cpu_to_le16(sizeof(*APList_rid));
 5270 
 5271 	for (i = 0; i < 4 && data->writelen >= (i + 1) * 6 * 3; i++)
 5272 		mac_pton(data->wbuffer + i * 6 * 3, APList_rid->ap[i]);
 5273 
 5274 	disable_MAC(ai, 1);
 5275 	writeAPListRid(ai, APList_rid, 1);
 5276 	enable_MAC(ai, 1);
 5277 }
 5278 
 5279 /* This function wraps PC4500_writerid with a MAC disable */
 5280 static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data,
 5281 			int len, int dummy ) {
 5282 	int rc;
 5283 
 5284 	disable_MAC(ai, 1);
 5285 	rc = PC4500_writerid(ai, rid, rid_data, len, 1);
 5286 	enable_MAC(ai, 1);
 5287 	return rc;
 5288 }
 5289 
 5290 /* Returns the WEP key at the specified index, or -1 if that key does
 5291  * not exist.  The buffer is assumed to be at least 16 bytes in length.
 5292  */
 5293 static int get_wep_key(struct airo_info *ai, u16 index, char *buf, u16 buflen)
 5294 {
 5295 	WepKeyRid wkr;
 5296 	int rc;
 5297 	__le16 lastindex;
 5298 
 5299 	rc = readWepKeyRid(ai, &wkr, 1, 1);
 5300 	if (rc != SUCCESS)
 5301 		return -1;
 5302 	do {
 5303 		lastindex = wkr.kindex;
 5304 		if (le16_to_cpu(wkr.kindex) == index) {
 5305 			int klen = min_t(int, buflen, le16_to_cpu(wkr.klen));
 5306 			memcpy(buf, wkr.key, klen);
 5307 			return klen;
 5308 		}
 5309 		rc = readWepKeyRid(ai, &wkr, 0, 1);
 5310 		if (rc != SUCCESS)
 5311 			return -1;
 5312 	} while (lastindex != wkr.kindex);
 5313 	return -1;
 5314 }
 5315 
 5316 static int get_wep_tx_idx(struct airo_info *ai)
 5317 {
 5318 	WepKeyRid wkr;
 5319 	int rc;
 5320 	__le16 lastindex;
 5321 
 5322 	rc = readWepKeyRid(ai, &wkr, 1, 1);
 5323 	if (rc != SUCCESS)
 5324 		return -1;
 5325 	do {
 5326 		lastindex = wkr.kindex;
 5327 		if (wkr.kindex == cpu_to_le16(0xffff))
 5328 			return wkr.mac[0];
 5329 		rc = readWepKeyRid(ai, &wkr, 0, 1);
 5330 		if (rc != SUCCESS)
 5331 			return -1;
 5332 	} while (lastindex != wkr.kindex);
 5333 	return -1;
 5334 }
 5335 
 5336 static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
 5337 		       u16 keylen, int perm, int lock)
 5338 {
 5339 	static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
 5340 	WepKeyRid wkr;
 5341 	int rc;
 5342 
 5343 	if (WARN_ON(keylen == 0))
 5344 		return -1;
 5345 
 5346 	memset(&wkr, 0, sizeof(wkr));
 5347 	wkr.len = cpu_to_le16(sizeof(wkr));
 5348 	wkr.kindex = cpu_to_le16(index);
 5349 	wkr.klen = cpu_to_le16(keylen);
 5350 	memcpy(wkr.key, key, keylen);
 5351 	memcpy(wkr.mac, macaddr, ETH_ALEN);
 5352 
 5353 	if (perm) disable_MAC(ai, lock);
 5354 	rc = writeWepKeyRid(ai, &wkr, perm, lock);
 5355 	if (perm) enable_MAC(ai, lock);
 5356 	return rc;
 5357 }
 5358 
 5359 static int set_wep_tx_idx(struct airo_info *ai, u16 index, int perm, int lock)
 5360 {
 5361 	WepKeyRid wkr;
 5362 	int rc;
 5363 
 5364 	memset(&wkr, 0, sizeof(wkr));
 5365 	wkr.len = cpu_to_le16(sizeof(wkr));
 5366 	wkr.kindex = cpu_to_le16(0xffff);
 5367 	wkr.mac[0] = (char)index;
 5368 
 5369 	if (perm) {
 5370 		ai->defindex = (char)index;
 5371 		disable_MAC(ai, lock);
 5372 	}
 5373 
 5374 	rc = writeWepKeyRid(ai, &wkr, perm, lock);
 5375 
 5376 	if (perm)
 5377 		enable_MAC(ai, lock);
 5378 	return rc;
 5379 }
 5380 
 5381 static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
 5382 	struct proc_data *data;
 5383 	struct net_device *dev = PDE_DATA(inode);
 5384 	struct airo_info *ai = dev->ml_priv;
 5385 	int i, rc;
 5386 	char key[16];
 5387 	u16 index = 0;
 5388 	int j = 0;
 5389 
 5390 	memset(key, 0, sizeof(key));
 5391 
 5392 	data = file->private_data;
 5393 	if ( !data->writelen ) return;
 5394 
 5395 	if (data->wbuffer[0] >= '0' && data->wbuffer[0] <= '3' &&
 5396 	    (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
 5397 		index = data->wbuffer[0] - '0';
 5398 		if (data->wbuffer[1] == '\n') {
 5399 			rc = set_wep_tx_idx(ai, index, 1, 1);
 5400 			if (rc < 0) {
 5401 				airo_print_err(ai->dev->name, "failed to set "
 5402 				               "WEP transmit index to %d: %d.",
 5403 				               index, rc);
 5404 			}
 5405 			return;
 5406 		}
 5407 		j = 2;
 5408 	} else {
 5409 		airo_print_err(ai->dev->name, "WepKey passed invalid key index");
 5410 		return;
 5411 	}
 5412 
 5413 	for( i = 0; i < 16*3 && data->wbuffer[i+j]; i++ ) {
 5414 		switch(i%3) {
 5415 		case 0:
 5416 			key[i/3] = hex_to_bin(data->wbuffer[i+j])<<4;
 5417 			break;
 5418 		case 1:
 5419 			key[i/3] |= hex_to_bin(data->wbuffer[i+j]);
 5420 			break;
 5421 		}
 5422 	}
 5423 
 5424 	rc = set_wep_key(ai, index, key, i/3, 1, 1);
 5425 	if (rc < 0) {
 5426 		airo_print_err(ai->dev->name, "failed to set WEP key at index "
 5427 		               "%d: %d.", index, rc);
 5428 	}
 5429 }
 5430 
 5431 static int proc_wepkey_open( struct inode *inode, struct file *file )
 5432 {
 5433 	struct proc_data *data;
 5434 	struct net_device *dev = PDE_DATA(inode);
 5435 	struct airo_info *ai = dev->ml_priv;
 5436 	char *ptr;
 5437 	WepKeyRid wkr;
 5438 	__le16 lastindex;
 5439 	int j=0;
 5440 	int rc;
 5441 
 5442 	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 5443 		return -ENOMEM;
 5444 	memset(&wkr, 0, sizeof(wkr));
 5445 	data = file->private_data;
 5446 	if ((data->rbuffer = kzalloc( 180, GFP_KERNEL )) == NULL) {
 5447 		kfree (file->private_data);
 5448 		return -ENOMEM;
 5449 	}
 5450 	data->writelen = 0;
 5451 	data->maxwritelen = 80;
 5452 	if ((data->wbuffer = kzalloc( 80, GFP_KERNEL )) == NULL) {
 5453 		kfree (data->rbuffer);
 5454 		kfree (file->private_data);
 5455 		return -ENOMEM;
 5456 	}
 5457 	data->on_close = proc_wepkey_on_close;
 5458 
 5459 	ptr = data->rbuffer;
 5460 	strcpy(ptr, "No wep keys\n");
 5461 	rc = readWepKeyRid(ai, &wkr, 1, 1);
 5462 	if (rc == SUCCESS) do {
 5463 		lastindex = wkr.kindex;
 5464 		if (wkr.kindex == cpu_to_le16(0xffff)) {
 5465 			j += sprintf(ptr+j, "Tx key = %d\n",
 5466 				     (int)wkr.mac[0]);
 5467 		} else {
 5468 			j += sprintf(ptr+j, "Key %d set with length = %d\n",
 5469 				     le16_to_cpu(wkr.kindex),
 5470 				     le16_to_cpu(wkr.klen));
 5471 		}
 5472 		readWepKeyRid(ai, &wkr, 0, 1);
 5473 	} while((lastindex != wkr.kindex) && (j < 180-30));
 5474 
 5475 	data->readlen = strlen( data->rbuffer );
 5476 	return 0;
 5477 }
 5478 
 5479 static int proc_SSID_open(struct inode *inode, struct file *file)
 5480 {
 5481 	struct proc_data *data;
 5482 	struct net_device *dev = PDE_DATA(inode);
 5483 	struct airo_info *ai = dev->ml_priv;
 5484 	int i;
 5485 	char *ptr;
 5486 	SsidRid SSID_rid;
 5487 
 5488 	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 5489 		return -ENOMEM;
 5490 	data = file->private_data;
 5491 	if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
 5492 		kfree (file->private_data);
 5493 		return -ENOMEM;
 5494 	}
 5495 	data->writelen = 0;
 5496 	data->maxwritelen = 33*3;
 5497 	/* allocate maxwritelen + 1; we'll want a sentinel */
 5498 	if ((data->wbuffer = kzalloc(33*3 + 1, GFP_KERNEL)) == NULL) {
 5499 		kfree (data->rbuffer);
 5500 		kfree (file->private_data);
 5501 		return -ENOMEM;
 5502 	}
 5503 	data->on_close = proc_SSID_on_close;
 5504 
 5505 	readSsidRid(ai, &SSID_rid);
 5506 	ptr = data->rbuffer;
 5507 	for (i = 0; i < 3; i++) {
 5508 		int j;
 5509 		size_t len = le16_to_cpu(SSID_rid.ssids[i].len);
 5510 		if (!len)
 5511 			break;
 5512 		if (len > 32)
 5513 			len = 32;
 5514 		for (j = 0; j < len && SSID_rid.ssids[i].ssid[j]; j++)
 5515 			*ptr++ = SSID_rid.ssids[i].ssid[j];
 5516 		*ptr++ = '\n';
 5517 	}
 5518 	*ptr = '\0';
 5519 	data->readlen = strlen( data->rbuffer );
 5520 	return 0;
 5521 }
 5522 
 5523 static int proc_APList_open( struct inode *inode, struct file *file ) {
 5524 	struct proc_data *data;
 5525 	struct net_device *dev = PDE_DATA(inode);
 5526 	struct airo_info *ai = dev->ml_priv;
 5527 	int i;
 5528 	char *ptr;
 5529 	APListRid *APList_rid = &ai->APList;
 5530 
 5531 	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 5532 		return -ENOMEM;
 5533 	data = file->private_data;
 5534 	if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
 5535 		kfree (file->private_data);
 5536 		return -ENOMEM;
 5537 	}
 5538 	data->writelen = 0;
 5539 	data->maxwritelen = 4*6*3;
 5540 	if ((data->wbuffer = kzalloc( data->maxwritelen, GFP_KERNEL )) == NULL) {
 5541 		kfree (data->rbuffer);
 5542 		kfree (file->private_data);
 5543 		return -ENOMEM;
 5544 	}
 5545 	data->on_close = proc_APList_on_close;
 5546 
 5547 	ptr = data->rbuffer;
 5548 	for( i = 0; i < 4; i++ ) {
 5549 // We end when we find a zero MAC
 5550 		if ( !*(int*)APList_rid->ap[i] &&
 5551 		     !*(int*)&APList_rid->ap[i][2]) break;
 5552 		ptr += sprintf(ptr, "%pM\n", APList_rid->ap[i]);
 5553 	}
 5554 	if (i==0) ptr += sprintf(ptr, "Not using specific APs\n");
 5555 
 5556 	*ptr = '\0';
 5557 	data->readlen = strlen( data->rbuffer );
 5558 	return 0;
 5559 }
 5560 
 5561 static int proc_BSSList_open( struct inode *inode, struct file *file ) {
 5562 	struct proc_data *data;
 5563 	struct net_device *dev = PDE_DATA(inode);
 5564 	struct airo_info *ai = dev->ml_priv;
 5565 	char *ptr;
 5566 	BSSListRid BSSList_rid;
 5567 	int rc;
 5568 	/* If doLoseSync is not 1, we won't do a Lose Sync */
 5569 	int doLoseSync = -1;
 5570 
 5571 	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 5572 		return -ENOMEM;
 5573 	data = file->private_data;
 5574 	if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) {
 5575 		kfree (file->private_data);
 5576 		return -ENOMEM;
 5577 	}
 5578 	data->writelen = 0;
 5579 	data->maxwritelen = 0;
 5580 	data->wbuffer = NULL;
 5581 	data->on_close = NULL;
 5582 
 5583 	if (file->f_mode & FMODE_WRITE) {
 5584 		if (!(file->f_mode & FMODE_READ)) {
 5585 			Cmd cmd;
 5586 			Resp rsp;
 5587 
 5588 			if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
 5589 			memset(&cmd, 0, sizeof(cmd));
 5590 			cmd.cmd=CMD_LISTBSS;
 5591 			if (down_interruptible(&ai->sem))
 5592 				return -ERESTARTSYS;
 5593 			issuecommand(ai, &cmd, &rsp);
 5594 			up(&ai->sem);
 5595 			data->readlen = 0;
 5596 			return 0;
 5597 		}
 5598 		doLoseSync = 1;
 5599 	}
 5600 	ptr = data->rbuffer;
 5601 	/* There is a race condition here if there are concurrent opens.
 5602            Since it is a rare condition, we'll just live with it, otherwise
 5603            we have to add a spin lock... */
 5604 	rc = readBSSListRid(ai, doLoseSync, &BSSList_rid);
 5605 	while(rc == 0 && BSSList_rid.index != cpu_to_le16(0xffff)) {
 5606 		ptr += sprintf(ptr, "%pM %*s rssi = %d",
 5607 			       BSSList_rid.bssid,
 5608 				(int)BSSList_rid.ssidLen,
 5609 				BSSList_rid.ssid,
 5610 				le16_to_cpu(BSSList_rid.dBm));
 5611 		ptr += sprintf(ptr, " channel = %d %s %s %s %s\n",
 5612 				le16_to_cpu(BSSList_rid.dsChannel),
 5613 				BSSList_rid.cap & CAP_ESS ? "ESS" : "",
 5614 				BSSList_rid.cap & CAP_IBSS ? "adhoc" : "",
 5615 				BSSList_rid.cap & CAP_PRIVACY ? "wep" : "",
 5616 				BSSList_rid.cap & CAP_SHORTHDR ? "shorthdr" : "");
 5617 		rc = readBSSListRid(ai, 0, &BSSList_rid);
 5618 	}
 5619 	*ptr = '\0';
 5620 	data->readlen = strlen( data->rbuffer );
 5621 	return 0;
 5622 }
 5623 
 5624 static int proc_close( struct inode *inode, struct file *file )
 5625 {
 5626 	struct proc_data *data = file->private_data;
 5627 
 5628 	if (data->on_close != NULL)
 5629 		data->on_close(inode, file);
 5630 	kfree(data->rbuffer);
 5631 	kfree(data->wbuffer);
 5632 	kfree(data);
 5633 	return 0;
 5634 }
 5635 
 5636 /* Since the card doesn't automatically switch to the right WEP mode,
 5637    we will make it do it.  If the card isn't associated, every secs we
 5638    will switch WEP modes to see if that will help.  If the card is
 5639    associated we will check every minute to see if anything has
 5640    changed. */
 5641 static void timer_func( struct net_device *dev ) {
 5642 	struct airo_info *apriv = dev->ml_priv;
 5643 
 5644 /* We don't have a link so try changing the authtype */
 5645 	readConfigRid(apriv, 0);
 5646 	disable_MAC(apriv, 0);
 5647 	switch(apriv->config.authType) {
 5648 		case AUTH_ENCRYPT:
 5649 /* So drop to OPEN */
 5650 			apriv->config.authType = AUTH_OPEN;
 5651 			break;
 5652 		case AUTH_SHAREDKEY:
 5653 			if (apriv->keyindex < auto_wep) {
 5654 				set_wep_tx_idx(apriv, apriv->keyindex, 0, 0);
 5655 				apriv->config.authType = AUTH_SHAREDKEY;
 5656 				apriv->keyindex++;
 5657 			} else {
 5658 			        /* Drop to ENCRYPT */
 5659 				apriv->keyindex = 0;
 5660 				set_wep_tx_idx(apriv, apriv->defindex, 0, 0);
 5661 				apriv->config.authType = AUTH_ENCRYPT;
 5662 			}
 5663 			break;
 5664 		default:  /* We'll escalate to SHAREDKEY */
 5665 			apriv->config.authType = AUTH_SHAREDKEY;
 5666 	}
 5667 	set_bit (FLAG_COMMIT, &apriv->flags);
 5668 	writeConfigRid(apriv, 0);
 5669 	enable_MAC(apriv, 0);
 5670 	up(&apriv->sem);
 5671 
 5672 /* Schedule check to see if the change worked */
 5673 	clear_bit(JOB_AUTOWEP, &apriv->jobs);
 5674 	apriv->expires = RUN_AT(HZ*3);
 5675 }
 5676 
 5677 #ifdef CONFIG_PCI
 5678 static int airo_pci_probe(struct pci_dev *pdev,
 5679 				    const struct pci_device_id *pent)
 5680 {
 5681 	struct net_device *dev;
 5682 
 5683 	if (pci_enable_device(pdev))
 5684 		return -ENODEV;
 5685 	pci_set_master(pdev);
 5686 
 5687 	if (pdev->device == 0x5000 || pdev->device == 0xa504)
 5688 			dev = _init_airo_card(pdev->irq, pdev->resource[0].start, 0, pdev, &pdev->dev);
 5689 	else
 5690 			dev = _init_airo_card(pdev->irq, pdev->resource[2].start, 0, pdev, &pdev->dev);
 5691 	if (!dev) {
 5692 		pci_disable_device(pdev);
 5693 		return -ENODEV;
 5694 	}
 5695 
 5696 	pci_set_drvdata(pdev, dev);
 5697 	return 0;
 5698 }
 5699 
 5700 static void airo_pci_remove(struct pci_dev *pdev)
 5701 {
 5702 	struct net_device *dev = pci_get_drvdata(pdev);
 5703 
 5704 	airo_print_info(dev->name, "Unregistering...");
 5705 	stop_airo_card(dev, 1);
 5706 	pci_disable_device(pdev);
 5707 }
 5708 
 5709 static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 5710 {
 5711 	struct net_device *dev = pci_get_drvdata(pdev);
 5712 	struct airo_info *ai = dev->ml_priv;
 5713 	Cmd cmd;
 5714 	Resp rsp;
 5715 
 5716 	if (!ai->SSID)
 5717 		ai->SSID = kmalloc(sizeof(SsidRid), GFP_KERNEL);
 5718 	if (!ai->SSID)
 5719 		return -ENOMEM;
 5720 	readSsidRid(ai, ai->SSID);
 5721 	memset(&cmd, 0, sizeof(cmd));
 5722 	/* the lock will be released at the end of the resume callback */
 5723 	if (down_interruptible(&ai->sem))
 5724 		return -EAGAIN;
 5725 	disable_MAC(ai, 0);
 5726 	netif_device_detach(dev);
 5727 	ai->power = state;
 5728 	cmd.cmd = HOSTSLEEP;
 5729 	issuecommand(ai, &cmd, &rsp);
 5730 
 5731 	pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
 5732 	pci_save_state(pdev);
 5733 	pci_set_power_state(pdev, pci_choose_state(pdev, state));
 5734 	return 0;
 5735 }
 5736 
 5737 static int airo_pci_resume(struct pci_dev *pdev)
 5738 {
 5739 	struct net_device *dev = pci_get_drvdata(pdev);
 5740 	struct airo_info *ai = dev->ml_priv;
 5741 	pci_power_t prev_state = pdev->current_state;
 5742 
 5743 	pci_set_power_state(pdev, PCI_D0);
 5744 	pci_restore_state(pdev);
 5745 	pci_enable_wake(pdev, PCI_D0, 0);
 5746 
 5747 	if (prev_state != PCI_D1) {
 5748 		reset_card(dev, 0);
 5749 		mpi_init_descriptors(ai);
 5750 		setup_card(ai, dev->dev_addr, 0);
 5751 		clear_bit(FLAG_RADIO_OFF, &ai->flags);
 5752 		clear_bit(FLAG_PENDING_XMIT, &ai->flags);
 5753 	} else {
 5754 		OUT4500(ai, EVACK, EV_AWAKEN);
 5755 		OUT4500(ai, EVACK, EV_AWAKEN);
 5756 		msleep(100);
 5757 	}
 5758 
 5759 	set_bit(FLAG_COMMIT, &ai->flags);
 5760 	disable_MAC(ai, 0);
 5761         msleep(200);
 5762 	if (ai->SSID) {
 5763 		writeSsidRid(ai, ai->SSID, 0);
 5764 		kfree(ai->SSID);
 5765 		ai->SSID = NULL;
 5766 	}
 5767 	writeAPListRid(ai, &ai->APList, 0);
 5768 	writeConfigRid(ai, 0);
 5769 	enable_MAC(ai, 0);
 5770 	ai->power = PMSG_ON;
 5771 	netif_device_attach(dev);
 5772 	netif_wake_queue(dev);
 5773 	enable_interrupts(ai);
 5774 	up(&ai->sem);
 5775 	return 0;
 5776 }
 5777 #endif
 5778 
 5779 static int __init airo_init_module( void )
 5780 {
 5781 	int i;
 5782 
 5783 	proc_kuid = make_kuid(&init_user_ns, proc_uid);
 5784 	proc_kgid = make_kgid(&init_user_ns, proc_gid);
 5785 	if (!uid_valid(proc_kuid) || !gid_valid(proc_kgid))
 5786 		return -EINVAL;
 5787 
 5788 	airo_entry = proc_mkdir_mode("driver/aironet", airo_perm, NULL);
 5789 
 5790 	if (airo_entry)
 5791 		proc_set_user(airo_entry, proc_kuid, proc_kgid);
 5792 
 5793 	for (i = 0; i < 4 && io[i] && irq[i]; i++) {
 5794 		airo_print_info("", "Trying to configure ISA adapter at irq=%d "
 5795 			"io=0x%x", irq[i], io[i] );
 5796 		if (init_airo_card( irq[i], io[i], 0, NULL ))
 5797 			/* do nothing */ ;
 5798 	}
 5799 
 5800 #ifdef CONFIG_PCI
 5801 	airo_print_info("", "Probing for PCI adapters");
 5802 	i = pci_register_driver(&airo_driver);
 5803 	airo_print_info("", "Finished probing for PCI adapters");
 5804 
 5805 	if (i) {
 5806 		remove_proc_entry("driver/aironet", NULL);
 5807 		return i;
 5808 	}
 5809 #endif
 5810 
 5811 	/* Always exit with success, as we are a library module
 5812 	 * as well as a driver module
 5813 	 */
 5814 	return 0;
 5815 }
 5816 
 5817 static void __exit airo_cleanup_module( void )
 5818 {
 5819 	struct airo_info *ai;
 5820 	while(!list_empty(&airo_devices)) {
 5821 		ai = list_entry(airo_devices.next, struct airo_info, dev_list);
 5822 		airo_print_info(ai->dev->name, "Unregistering...");
 5823 		stop_airo_card(ai->dev, 1);
 5824 	}
 5825 #ifdef CONFIG_PCI
 5826 	pci_unregister_driver(&airo_driver);
 5827 #endif
 5828 	remove_proc_entry("driver/aironet", NULL);
 5829 }
 5830 
 5831 /*
 5832  * Initial Wireless Extension code for Aironet driver by :
 5833  *	Jean Tourrilhes <jt@hpl.hp.com> - HPL - 17 November 00
 5834  * Conversion to new driver API by :
 5835  *	Jean Tourrilhes <jt@hpl.hp.com> - HPL - 26 March 02
 5836  * Javier also did a good amount of work here, adding some new extensions
 5837  * and fixing my code. Let's just say that without him this code just
 5838  * would not work at all... - Jean II
 5839  */
 5840 
 5841 static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi)
 5842 {
 5843 	if (!rssi_rid)
 5844 		return 0;
 5845 
 5846 	return (0x100 - rssi_rid[rssi].rssidBm);
 5847 }
 5848 
 5849 static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm)
 5850 {
 5851 	int i;
 5852 
 5853 	if (!rssi_rid)
 5854 		return 0;
 5855 
 5856 	for (i = 0; i < 256; i++)
 5857 		if (rssi_rid[i].rssidBm == dbm)
 5858 			return rssi_rid[i].rssipct;
 5859 
 5860 	return 0;
 5861 }
 5862 
 5863 
 5864 static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid)
 5865 {
 5866 	int quality = 0;
 5867 	u16 sq;
 5868 
 5869 	if ((status_rid->mode & cpu_to_le16(0x3f)) != cpu_to_le16(0x3f))
 5870 		return 0;
 5871 
 5872 	if (!(cap_rid->hardCap & cpu_to_le16(8)))
 5873 		return 0;
 5874 
 5875 	sq = le16_to_cpu(status_rid->signalQuality);
 5876 	if (memcmp(cap_rid->prodName, "350", 3))
 5877 		if (sq > 0x20)
 5878 			quality = 0;
 5879 		else
 5880 			quality = 0x20 - sq;
 5881 	else
 5882 		if (sq > 0xb0)
 5883 			quality = 0;
 5884 		else if (sq < 0x10)
 5885 			quality = 0xa0;
 5886 		else
 5887 			quality = 0xb0 - sq;
 5888 	return quality;
 5889 }
 5890 
 5891 #define airo_get_max_quality(cap_rid) (memcmp((cap_rid)->prodName, "350", 3) ? 0x20 : 0xa0)
 5892 #define airo_get_avg_quality(cap_rid) (memcmp((cap_rid)->prodName, "350", 3) ? 0x10 : 0x50);
 5893 
 5894 /*------------------------------------------------------------------*/
 5895 /*
 5896  * Wireless Handler : get protocol name
 5897  */
 5898 static int airo_get_name(struct net_device *dev,
 5899 			 struct iw_request_info *info,
 5900 			 char *cwrq,
 5901 			 char *extra)
 5902 {
 5903 	strcpy(cwrq, "IEEE 802.11-DS");
 5904 	return 0;
 5905 }
 5906 
 5907 /*------------------------------------------------------------------*/
 5908 /*
 5909  * Wireless Handler : set frequency
 5910  */
 5911 static int airo_set_freq(struct net_device *dev,
 5912 			 struct iw_request_info *info,
 5913 			 struct iw_freq *fwrq,
 5914 			 char *extra)
 5915 {
 5916 	struct airo_info *local = dev->ml_priv;
 5917 	int rc = -EINPROGRESS;		/* Call commit handler */
 5918 
 5919 	/* If setting by frequency, convert to a channel */
 5920 	if(fwrq->e == 1) {
 5921 		int f = fwrq->m / 100000;
 5922 
 5923 		/* Hack to fall through... */
 5924 		fwrq->e = 0;
 5925 		fwrq->m = ieee80211_frequency_to_channel(f);
 5926 	}
 5927 	/* Setting by channel number */
 5928 	if((fwrq->m > 1000) || (fwrq->e > 0))
 5929 		rc = -EOPNOTSUPP;
 5930 	else {
 5931 		int channel = fwrq->m;
 5932 		/* We should do a better check than that,
 5933 		 * based on the card capability !!! */
 5934 		if((channel < 1) || (channel > 14)) {
 5935 			airo_print_dbg(dev->name, "New channel value of %d is invalid!",
 5936 				fwrq->m);
 5937 			rc = -EINVAL;
 5938 		} else {
 5939 			readConfigRid(local, 1);
 5940 			/* Yes ! We can set it !!! */
 5941 			local->config.channelSet = cpu_to_le16(channel);
 5942 			set_bit (FLAG_COMMIT, &local->flags);
 5943 		}
 5944 	}
 5945 	return rc;
 5946 }
 5947 
 5948 /*------------------------------------------------------------------*/
 5949 /*
 5950  * Wireless Handler : get frequency
 5951  */
 5952 static int airo_get_freq(struct net_device *dev,
 5953 			 struct iw_request_info *info,
 5954 			 struct iw_freq *fwrq,
 5955 			 char *extra)
 5956 {
 5957 	struct airo_info *local = dev->ml_priv;
 5958 	StatusRid status_rid;		/* Card status info */
 5959 	int ch;
 5960 
 5961 	readConfigRid(local, 1);
 5962 	if ((local->config.opmode & MODE_CFG_MASK) == MODE_STA_ESS)
 5963 		status_rid.channel = local->config.channelSet;
 5964 	else
 5965 		readStatusRid(local, &status_rid, 1);
 5966 
 5967 	ch = le16_to_cpu(status_rid.channel);
 5968 	if((ch > 0) && (ch < 15)) {
 5969 		fwrq->m = 100000 *
 5970 			ieee80211_channel_to_frequency(ch, IEEE80211_BAND_2GHZ);
 5971 		fwrq->e = 1;
 5972 	} else {
 5973 		fwrq->m = ch;
 5974 		fwrq->e = 0;
 5975 	}
 5976 
 5977 	return 0;
 5978 }
 5979 
 5980 /*------------------------------------------------------------------*/
 5981 /*
 5982  * Wireless Handler : set ESSID
 5983  */
 5984 static int airo_set_essid(struct net_device *dev,
 5985 			  struct iw_request_info *info,
 5986 			  struct iw_point *dwrq,
 5987 			  char *extra)
 5988 {
 5989 	struct airo_info *local = dev->ml_priv;
 5990 	SsidRid SSID_rid;		/* SSIDs */
 5991 
 5992 	/* Reload the list of current SSID */
 5993 	readSsidRid(local, &SSID_rid);
 5994 
 5995 	/* Check if we asked for `any' */
 5996 	if (dwrq->flags == 0) {
 5997 		/* Just send an empty SSID list */
 5998 		memset(&SSID_rid, 0, sizeof(SSID_rid));
 5999 	} else {
 6000 		unsigned index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
 6001 
 6002 		/* Check the size of the string */
 6003 		if (dwrq->length > IW_ESSID_MAX_SIZE)
 6004 			return -E2BIG ;
 6005 
 6006 		/* Check if index is valid */
 6007 		if (index >= ARRAY_SIZE(SSID_rid.ssids))
 6008 			return -EINVAL;
 6009 
 6010 		/* Set the SSID */
 6011 		memset(SSID_rid.ssids[index].ssid, 0,
 6012 		       sizeof(SSID_rid.ssids[index].ssid));
 6013 		memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length);
 6014 		SSID_rid.ssids[index].len = cpu_to_le16(dwrq->length);
 6015 	}
 6016 	SSID_rid.len = cpu_to_le16(sizeof(SSID_rid));
 6017 	/* Write it to the card */
 6018 	disable_MAC(local, 1);
 6019 	writeSsidRid(local, &SSID_rid, 1);
 6020 	enable_MAC(local, 1);
 6021 
 6022 	return 0;
 6023 }
 6024 
 6025 /*------------------------------------------------------------------*/
 6026 /*
 6027  * Wireless Handler : get ESSID
 6028  */
 6029 static int airo_get_essid(struct net_device *dev,
 6030 			  struct iw_request_info *info,
 6031 			  struct iw_point *dwrq,
 6032 			  char *extra)
 6033 {
 6034 	struct airo_info *local = dev->ml_priv;
 6035 	StatusRid status_rid;		/* Card status info */
 6036 
 6037 	readStatusRid(local, &status_rid, 1);
 6038 
 6039 	/* Note : if dwrq->flags != 0, we should
 6040 	 * get the relevant SSID from the SSID list... */
 6041 
 6042 	/* Get the current SSID */
 6043 	memcpy(extra, status_rid.SSID, le16_to_cpu(status_rid.SSIDlen));
 6044 	/* If none, we may want to get the one that was set */
 6045 
 6046 	/* Push it out ! */
 6047 	dwrq->length = le16_to_cpu(status_rid.SSIDlen);
 6048 	dwrq->flags = 1; /* active */
 6049 
 6050 	return 0;
 6051 }
 6052 
 6053 /*------------------------------------------------------------------*/
 6054 /*
 6055  * Wireless Handler : set AP address
 6056  */
 6057 static int airo_set_wap(struct net_device *dev,
 6058 			struct iw_request_info *info,
 6059 			struct sockaddr *awrq,
 6060 			char *extra)
 6061 {
 6062 	struct airo_info *local = dev->ml_priv;
 6063 	Cmd cmd;
 6064 	Resp rsp;
 6065 	APListRid *APList_rid = &local->APList;
 6066 
 6067 	if (awrq->sa_family != ARPHRD_ETHER)
 6068 		return -EINVAL;
 6069 	else if (is_broadcast_ether_addr(awrq->sa_data) ||
 6070 		 is_zero_ether_addr(awrq->sa_data)) {
 6071 		memset(&cmd, 0, sizeof(cmd));
 6072 		cmd.cmd=CMD_LOSE_SYNC;
 6073 		if (down_interruptible(&local->sem))
 6074 			return -ERESTARTSYS;
 6075 		issuecommand(local, &cmd, &rsp);
 6076 		up(&local->sem);
 6077 	} else {
 6078 		memset(APList_rid, 0, sizeof(*APList_rid));
 6079 		APList_rid->len = cpu_to_le16(sizeof(*APList_rid));
 6080 		memcpy(APList_rid->ap[0], awrq->sa_data, ETH_ALEN);
 6081 		disable_MAC(local, 1);
 6082 		writeAPListRid(local, APList_rid, 1);
 6083 		enable_MAC(local, 1);
 6084 	}
 6085 	return 0;
 6086 }
 6087 
 6088 /*------------------------------------------------------------------*/
 6089 /*
 6090  * Wireless Handler : get AP address
 6091  */
 6092 static int airo_get_wap(struct net_device *dev,
 6093 			struct iw_request_info *info,
 6094 			struct sockaddr *awrq,
 6095 			char *extra)
 6096 {
 6097 	struct airo_info *local = dev->ml_priv;
 6098 	StatusRid status_rid;		/* Card status info */
 6099 
 6100 	readStatusRid(local, &status_rid, 1);
 6101 
 6102 	/* Tentative. This seems to work, wow, I'm lucky !!! */
 6103 	memcpy(awrq->sa_data, status_rid.bssid[0], ETH_ALEN);
 6104 	awrq->sa_family = ARPHRD_ETHER;
 6105 
 6106 	return 0;
 6107 }
 6108 
 6109 /*------------------------------------------------------------------*/
 6110 /*
 6111  * Wireless Handler : set Nickname
 6112  */
 6113 static int airo_set_nick(struct net_device *dev,
 6114 			 struct iw_request_info *info,
 6115 			 struct iw_point *dwrq,
 6116 			 char *extra)
 6117 {
 6118 	struct airo_info *local = dev->ml_priv;
 6119 
 6120 	/* Check the size of the string */
 6121 	if(dwrq->length > 16) {
 6122 		return -E2BIG;
 6123 	}
 6124 	readConfigRid(local, 1);
 6125 	memset(local->config.nodeName, 0, sizeof(local->config.nodeName));
 6126 	memcpy(local->config.nodeName, extra, dwrq->length);
 6127 	set_bit (FLAG_COMMIT, &local->flags);
 6128 
 6129 	return -EINPROGRESS;		/* Call commit handler */
 6130 }
 6131 
 6132 /*------------------------------------------------------------------*/
 6133 /*
 6134  * Wireless Handler : get Nickname
 6135  */
 6136 static int airo_get_nick(struct net_device *dev,
 6137 			 struct iw_request_info *info,
 6138 			 struct iw_point *dwrq,
 6139 			 char *extra)
 6140 {
 6141 	struct airo_info *local = dev->ml_priv;
 6142 
 6143 	readConfigRid(local, 1);
 6144 	strncpy(extra, local->config.nodeName, 16);
 6145 	extra[16] = '\0';
 6146 	dwrq->length = strlen(extra);
 6147 
 6148 	return 0;
 6149 }
 6150 
 6151 /*------------------------------------------------------------------*/
 6152 /*
 6153  * Wireless Handler : set Bit-Rate
 6154  */
 6155 static int airo_set_rate(struct net_device *dev,
 6156 			 struct iw_request_info *info,
 6157 			 struct iw_param *vwrq,
 6158 			 char *extra)
 6159 {
 6160 	struct airo_info *local = dev->ml_priv;
 6161 	CapabilityRid cap_rid;		/* Card capability info */
 6162 	u8	brate = 0;
 6163 	int	i;
 6164 
 6165 	/* First : get a valid bit rate value */
 6166 	readCapabilityRid(local, &cap_rid, 1);
 6167 
 6168 	/* Which type of value ? */
 6169 	if((vwrq->value < 8) && (vwrq->value >= 0)) {
 6170 		/* Setting by rate index */
 6171 		/* Find value in the magic rate table */
 6172 		brate = cap_rid.supportedRates[vwrq->value];
 6173 	} else {
 6174 		/* Setting by frequency value */
 6175 		u8	normvalue = (u8) (vwrq->value/500000);
 6176 
 6177 		/* Check if rate is valid */
 6178 		for(i = 0 ; i < 8 ; i++) {
 6179 			if(normvalue == cap_rid.supportedRates[i]) {
 6180 				brate = normvalue;
 6181 				break;
 6182 			}
 6183 		}
 6184 	}
 6185 	/* -1 designed the max rate (mostly auto mode) */
 6186 	if(vwrq->value == -1) {
 6187 		/* Get the highest available rate */
 6188 		for(i = 0 ; i < 8 ; i++) {
 6189 			if(cap_rid.supportedRates[i] == 0)
 6190 				break;
 6191 		}
 6192 		if(i != 0)
 6193 			brate = cap_rid.supportedRates[i - 1];
 6194 	}
 6195 	/* Check that it is valid */
 6196 	if(brate == 0) {
 6197 		return -EINVAL;
 6198 	}
 6199 
 6200 	readConfigRid(local, 1);
 6201 	/* Now, check if we want a fixed or auto value */
 6202 	if(vwrq->fixed == 0) {
 6203 		/* Fill all the rates up to this max rate */
 6204 		memset(local->config.rates, 0, 8);
 6205 		for(i = 0 ; i < 8 ; i++) {
 6206 			local->config.rates[i] = cap_rid.supportedRates[i];
 6207 			if(local->config.rates[i] == brate)
 6208 				break;
 6209 		}
 6210 	} else {
 6211 		/* Fixed mode */
 6212 		/* One rate, fixed */
 6213 		memset(local->config.rates, 0, 8);
 6214 		local->config.rates[0] = brate;
 6215 	}
 6216 	set_bit (FLAG_COMMIT, &local->flags);
 6217 
 6218 	return -EINPROGRESS;		/* Call commit handler */
 6219 }
 6220 
 6221 /*------------------------------------------------------------------*/
 6222 /*
 6223  * Wireless Handler : get Bit-Rate
 6224  */
 6225 static int airo_get_rate(struct net_device *dev,
 6226 			 struct iw_request_info *info,
 6227 			 struct iw_param *vwrq,
 6228 			 char *extra)
 6229 {
 6230 	struct airo_info *local = dev->ml_priv;
 6231 	StatusRid status_rid;		/* Card status info */
 6232 
 6233 	readStatusRid(local, &status_rid, 1);
 6234 
 6235 	vwrq->value = le16_to_cpu(status_rid.currentXmitRate) * 500000;
 6236 	/* If more than one rate, set auto */
 6237 	readConfigRid(local, 1);
 6238 	vwrq->fixed = (local->config.rates[1] == 0);
 6239 
 6240 	return 0;
 6241 }
 6242 
 6243 /*------------------------------------------------------------------*/
 6244 /*
 6245  * Wireless Handler : set RTS threshold
 6246  */
 6247 static int airo_set_rts(struct net_device *dev,
 6248 			struct iw_request_info *info,
 6249 			struct iw_param *vwrq,
 6250 			char *extra)
 6251 {
 6252 	struct airo_info *local = dev->ml_priv;
 6253 	int rthr = vwrq->value;
 6254 
 6255 	if(vwrq->disabled)
 6256 		rthr = AIRO_DEF_MTU;
 6257 	if((rthr < 0) || (rthr > AIRO_DEF_MTU)) {
 6258 		return -EINVAL;
 6259 	}
 6260 	readConfigRid(local, 1);
 6261 	local->config.rtsThres = cpu_to_le16(rthr);
 6262 	set_bit (FLAG_COMMIT, &local->flags);
 6263 
 6264 	return -EINPROGRESS;		/* Call commit handler */
 6265 }
 6266 
 6267 /*------------------------------------------------------------------*/
 6268 /*
 6269  * Wireless Handler : get RTS threshold
 6270  */
 6271 static int airo_get_rts(struct net_device *dev,
 6272 			struct iw_request_info *info,
 6273 			struct iw_param *vwrq,
 6274 			char *extra)
 6275 {
 6276 	struct airo_info *local = dev->ml_priv;
 6277 
 6278 	readConfigRid(local, 1);
 6279 	vwrq->value = le16_to_cpu(local->config.rtsThres);
 6280 	vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
 6281 	vwrq->fixed = 1;
 6282 
 6283 	return 0;
 6284 }
 6285 
 6286 /*------------------------------------------------------------------*/
 6287 /*
 6288  * Wireless Handler : set Fragmentation threshold
 6289  */
 6290 static int airo_set_frag(struct net_device *dev,
 6291 			 struct iw_request_info *info,
 6292 			 struct iw_param *vwrq,
 6293 			 char *extra)
 6294 {
 6295 	struct airo_info *local = dev->ml_priv;
 6296 	int fthr = vwrq->value;
 6297 
 6298 	if(vwrq->disabled)
 6299 		fthr = AIRO_DEF_MTU;
 6300 	if((fthr < 256) || (fthr > AIRO_DEF_MTU)) {
 6301 		return -EINVAL;
 6302 	}
 6303 	fthr &= ~0x1;	/* Get an even value - is it really needed ??? */
 6304 	readConfigRid(local, 1);
 6305 	local->config.fragThresh = cpu_to_le16(fthr);
 6306 	set_bit (FLAG_COMMIT, &local->flags);
 6307 
 6308 	return -EINPROGRESS;		/* Call commit handler */
 6309 }
 6310 
 6311 /*------------------------------------------------------------------*/
 6312 /*
 6313  * Wireless Handler : get Fragmentation threshold
 6314  */
 6315 static int airo_get_frag(struct net_device *dev,
 6316 			 struct iw_request_info *info,
 6317 			 struct iw_param *vwrq,
 6318 			 char *extra)
 6319 {
 6320 	struct airo_info *local = dev->ml_priv;
 6321 
 6322 	readConfigRid(local, 1);
 6323 	vwrq->value = le16_to_cpu(local->config.fragThresh);
 6324 	vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
 6325 	vwrq->fixed = 1;
 6326 
 6327 	return 0;
 6328 }
 6329 
 6330 /*------------------------------------------------------------------*/
 6331 /*
 6332  * Wireless Handler : set Mode of Operation
 6333  */
 6334 static int airo_set_mode(struct net_device *dev,
 6335 			 struct iw_request_info *info,
 6336 			 __u32 *uwrq,
 6337 			 char *extra)
 6338 {
 6339 	struct airo_info *local = dev->ml_priv;
 6340 	int reset = 0;
 6341 
 6342 	readConfigRid(local, 1);
 6343 	if (sniffing_mode(local))
 6344 		reset = 1;
 6345 
 6346 	switch(*uwrq) {
 6347 		case IW_MODE_ADHOC:
 6348 			local->config.opmode &= ~MODE_CFG_MASK;
 6349 			local->config.opmode |= MODE_STA_IBSS;
 6350 			local->config.rmode &= ~RXMODE_FULL_MASK;
 6351 			local->config.scanMode = SCANMODE_ACTIVE;
 6352 			clear_bit (FLAG_802_11, &local->flags);
 6353 			break;
 6354 		case IW_MODE_INFRA:
 6355 			local->config.opmode &= ~MODE_CFG_MASK;
 6356 			local->config.opmode |= MODE_STA_ESS;
 6357 			local->config.rmode &= ~RXMODE_FULL_MASK;
 6358 			local->config.scanMode = SCANMODE_ACTIVE;
 6359 			clear_bit (FLAG_802_11, &local->flags);
 6360 			break;
 6361 		case IW_MODE_MASTER:
 6362 			local->config.opmode &= ~MODE_CFG_MASK;
 6363 			local->config.opmode |= MODE_AP;
 6364 			local->config.rmode &= ~RXMODE_FULL_MASK;
 6365 			local->config.scanMode = SCANMODE_ACTIVE;
 6366 			clear_bit (FLAG_802_11, &local->flags);
 6367 			break;
 6368 		case IW_MODE_REPEAT:
 6369 			local->config.opmode &= ~MODE_CFG_MASK;
 6370 			local->config.opmode |= MODE_AP_RPTR;
 6371 			local->config.rmode &= ~RXMODE_FULL_MASK;
 6372 			local->config.scanMode = SCANMODE_ACTIVE;
 6373 			clear_bit (FLAG_802_11, &local->flags);
 6374 			break;
 6375 		case IW_MODE_MONITOR:
 6376 			local->config.opmode &= ~MODE_CFG_MASK;
 6377 			local->config.opmode |= MODE_STA_ESS;
 6378 			local->config.rmode &= ~RXMODE_FULL_MASK;
 6379 			local->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
 6380 			local->config.scanMode = SCANMODE_PASSIVE;
 6381 			set_bit (FLAG_802_11, &local->flags);
 6382 			break;
 6383 		default:
 6384 			return -EINVAL;
 6385 	}
 6386 	if (reset)
 6387 		set_bit (FLAG_RESET, &local->flags);
 6388 	set_bit (FLAG_COMMIT, &local->flags);
 6389 
 6390 	return -EINPROGRESS;		/* Call commit handler */
 6391 }
 6392 
 6393 /*------------------------------------------------------------------*/
 6394 /*
 6395  * Wireless Handler : get Mode of Operation
 6396  */
 6397 static int airo_get_mode(struct net_device *dev,
 6398 			 struct iw_request_info *info,
 6399 			 __u32 *uwrq,
 6400 			 char *extra)
 6401 {
 6402 	struct airo_info *local = dev->ml_priv;
 6403 
 6404 	readConfigRid(local, 1);
 6405 	/* If not managed, assume it's ad-hoc */
 6406 	switch (local->config.opmode & MODE_CFG_MASK) {
 6407 		case MODE_STA_ESS:
 6408 			*uwrq = IW_MODE_INFRA;
 6409 			break;
 6410 		case MODE_AP:
 6411 			*uwrq = IW_MODE_MASTER;
 6412 			break;
 6413 		case MODE_AP_RPTR:
 6414 			*uwrq = IW_MODE_REPEAT;
 6415 			break;
 6416 		default:
 6417 			*uwrq = IW_MODE_ADHOC;
 6418 	}
 6419 
 6420 	return 0;
 6421 }
 6422 
 6423 static inline int valid_index(struct airo_info *ai, int index)
 6424 {
 6425 	return (index >= 0) && (index <= ai->max_wep_idx);
 6426 }
 6427 
 6428 /*------------------------------------------------------------------*/
 6429 /*
 6430  * Wireless Handler : set Encryption Key
 6431  */
 6432 static int airo_set_encode(struct net_device *dev,
 6433 			   struct iw_request_info *info,
 6434 			   struct iw_point *dwrq,
 6435 			   char *extra)
 6436 {
 6437 	struct airo_info *local = dev->ml_priv;
 6438 	int perm = (dwrq->flags & IW_ENCODE_TEMP ? 0 : 1);
 6439 	__le16 currentAuthType = local->config.authType;
 6440 	int rc = 0;
 6441 
 6442 	if (!local->wep_capable)
 6443 		return -EOPNOTSUPP;
 6444 
 6445 	readConfigRid(local, 1);
 6446 
 6447 	/* Basic checking: do we have a key to set ?
 6448 	 * Note : with the new API, it's impossible to get a NULL pointer.
 6449 	 * Therefore, we need to check a key size == 0 instead.
 6450 	 * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
 6451 	 * when no key is present (only change flags), but older versions
 6452 	 * don't do it. - Jean II */
 6453 	if (dwrq->length > 0) {
 6454 		wep_key_t key;
 6455 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
 6456 		int current_index;
 6457 
 6458 		/* Check the size of the key */
 6459 		if (dwrq->length > MAX_KEY_SIZE) {
 6460 			return -EINVAL;
 6461 		}
 6462 
 6463 		current_index = get_wep_tx_idx(local);
 6464 		if (current_index < 0)
 6465 			current_index = 0;
 6466 
 6467 		/* Check the index (none -> use current) */
 6468 		if (!valid_index(local, index))
 6469 			index = current_index;
 6470 
 6471 		/* Set the length */
 6472 		if (dwrq->length > MIN_KEY_SIZE)
 6473 			key.len = MAX_KEY_SIZE;
 6474 		else
 6475 			key.len = MIN_KEY_SIZE;
 6476 		/* Check if the key is not marked as invalid */
 6477 		if(!(dwrq->flags & IW_ENCODE_NOKEY)) {
 6478 			/* Cleanup */
 6479 			memset(key.key, 0, MAX_KEY_SIZE);
 6480 			/* Copy the key in the driver */
 6481 			memcpy(key.key, extra, dwrq->length);
 6482 			/* Send the key to the card */
 6483 			rc = set_wep_key(local, index, key.key, key.len, perm, 1);
 6484 			if (rc < 0) {
 6485 				airo_print_err(local->dev->name, "failed to set"
 6486 				               " WEP key at index %d: %d.",
 6487 				               index, rc);
 6488 				return rc;
 6489 			}
 6490 		}
 6491 		/* WE specify that if a valid key is set, encryption
 6492 		 * should be enabled (user may turn it off later)
 6493 		 * This is also how "iwconfig ethX key on" works */
 6494 		if((index == current_index) && (key.len > 0) &&
 6495 		   (local->config.authType == AUTH_OPEN))
 6496 			set_auth_type(local, AUTH_ENCRYPT);
 6497 	} else {
 6498 		/* Do we want to just set the transmit key index ? */
 6499 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
 6500 		if (valid_index(local, index)) {
 6501 			rc = set_wep_tx_idx(local, index, perm, 1);
 6502 			if (rc < 0) {
 6503 				airo_print_err(local->dev->name, "failed to set"
 6504 				               " WEP transmit index to %d: %d.",
 6505 				               index, rc);
 6506 				return rc;
 6507 			}
 6508 		} else {
 6509 			/* Don't complain if only change the mode */
 6510 			if (!(dwrq->flags & IW_ENCODE_MODE))
 6511 				return -EINVAL;
 6512 		}
 6513 	}
 6514 	/* Read the flags */
 6515 	if (dwrq->flags & IW_ENCODE_DISABLED)
 6516 		set_auth_type(local, AUTH_OPEN);	/* disable encryption */
 6517 	if(dwrq->flags & IW_ENCODE_RESTRICTED)
 6518 		set_auth_type(local, AUTH_SHAREDKEY);	/* Only Both */
 6519 	if (dwrq->flags & IW_ENCODE_OPEN)
 6520 		set_auth_type(local, AUTH_ENCRYPT);	/* Only Wep */
 6521 	/* Commit the changes to flags if needed */
 6522 	if (local->config.authType != currentAuthType)
 6523 		set_bit (FLAG_COMMIT, &local->flags);
 6524 	return -EINPROGRESS;		/* Call commit handler */
 6525 }
 6526 
 6527 /*------------------------------------------------------------------*/
 6528 /*
 6529  * Wireless Handler : get Encryption Key
 6530  */
 6531 static int airo_get_encode(struct net_device *dev,
 6532 			   struct iw_request_info *info,
 6533 			   struct iw_point *dwrq,
 6534 			   char *extra)
 6535 {
 6536 	struct airo_info *local = dev->ml_priv;
 6537 	int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
 6538 	int wep_key_len;
 6539 	u8 buf[16];
 6540 
 6541 	if (!local->wep_capable)
 6542 		return -EOPNOTSUPP;
 6543 
 6544 	readConfigRid(local, 1);
 6545 
 6546 	/* Check encryption mode */
 6547 	switch(local->config.authType)	{
 6548 		case AUTH_ENCRYPT:
 6549 			dwrq->flags = IW_ENCODE_OPEN;
 6550 			break;
 6551 		case AUTH_SHAREDKEY:
 6552 			dwrq->flags = IW_ENCODE_RESTRICTED;
 6553 			break;
 6554 		default:
 6555 		case AUTH_OPEN:
 6556 			dwrq->flags = IW_ENCODE_DISABLED;
 6557 			break;
 6558 	}
 6559 	/* We can't return the key, so set the proper flag and return zero */
 6560 	dwrq->flags |= IW_ENCODE_NOKEY;
 6561 	memset(extra, 0, 16);
 6562 
 6563 	/* Which key do we want ? -1 -> tx index */
 6564 	if (!valid_index(local, index)) {
 6565 		index = get_wep_tx_idx(local);
 6566 		if (index < 0)
 6567 			index = 0;
 6568 	}
 6569 	dwrq->flags |= index + 1;
 6570 
 6571 	/* Copy the key to the user buffer */
 6572 	wep_key_len = get_wep_key(local, index, &buf[0], sizeof(buf));
 6573 	if (wep_key_len < 0) {
 6574 		dwrq->length = 0;
 6575 	} else {
 6576 		dwrq->length = wep_key_len;
 6577 		memcpy(extra, buf, dwrq->length);
 6578 	}
 6579 
 6580 	return 0;
 6581 }
 6582 
 6583 /*------------------------------------------------------------------*/
 6584 /*
 6585  * Wireless Handler : set extended Encryption parameters
 6586  */
 6587 static int airo_set_encodeext(struct net_device *dev,
 6588 			   struct iw_request_info *info,
 6589 			    union iwreq_data *wrqu,
 6590 			    char *extra)
 6591 {
 6592 	struct airo_info *local = dev->ml_priv;
 6593 	struct iw_point *encoding = &wrqu->encoding;
 6594 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
 6595 	int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 );
 6596 	__le16 currentAuthType = local->config.authType;
 6597 	int idx, key_len, alg = ext->alg, set_key = 1, rc;
 6598 	wep_key_t key;
 6599 
 6600 	if (!local->wep_capable)
 6601 		return -EOPNOTSUPP;
 6602 
 6603 	readConfigRid(local, 1);
 6604 
 6605 	/* Determine and validate the key index */
 6606 	idx = encoding->flags & IW_ENCODE_INDEX;
 6607 	if (idx) {
 6608 		if (!valid_index(local, idx - 1))
 6609 			return -EINVAL;
 6610 		idx--;
 6611 	} else {
 6612 		idx = get_wep_tx_idx(local);
 6613 		if (idx < 0)
 6614 			idx = 0;
 6615 	}
 6616 
 6617 	if (encoding->flags & IW_ENCODE_DISABLED)
 6618 		alg = IW_ENCODE_ALG_NONE;
 6619 
 6620 	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
 6621 		/* Only set transmit key index here, actual
 6622 		 * key is set below if needed.
 6623 		 */
 6624 		rc = set_wep_tx_idx(local, idx, perm, 1);
 6625 		if (rc < 0) {
 6626 			airo_print_err(local->dev->name, "failed to set "
 6627 			               "WEP transmit index to %d: %d.",
 6628 			               idx, rc);
 6629 			return rc;
 6630 		}
 6631 		set_key = ext->key_len > 0 ? 1 : 0;
 6632 	}
 6633 
 6634 	if (set_key) {
 6635 		/* Set the requested key first */
 6636 		memset(key.key, 0, MAX_KEY_SIZE);
 6637 		switch (alg) {
 6638 		case IW_ENCODE_ALG_NONE:
 6639 			key.len = 0;
 6640 			break;
 6641 		case IW_ENCODE_ALG_WEP:
 6642 			if (ext->key_len > MIN_KEY_SIZE) {
 6643 				key.len = MAX_KEY_SIZE;
 6644 			} else if (ext->key_len > 0) {
 6645 				key.len = MIN_KEY_SIZE;
 6646 			} else {
 6647 				return -EINVAL;
 6648 			}
 6649 			key_len = min (ext->key_len, key.len);
 6650 			memcpy(key.key, ext->key, key_len);
 6651 			break;
 6652 		default:
 6653 			return -EINVAL;
 6654 		}
 6655 		if (key.len == 0) {
 6656 			rc = set_wep_tx_idx(local, idx, perm, 1);
 6657 			if (rc < 0) {
 6658 				airo_print_err(local->dev->name,
 6659 					       "failed to set WEP transmit index to %d: %d.",
 6660 					       idx, rc);
 6661 				return rc;
 6662 			}
 6663 		} else {
 6664 			rc = set_wep_key(local, idx, key.key, key.len, perm, 1);
 6665 			if (rc < 0) {
 6666 				airo_print_err(local->dev->name,
 6667 					       "failed to set WEP key at index %d: %d.",
 6668 					       idx, rc);
 6669 				return rc;
 6670 			}
 6671 		}
 6672 	}
 6673 
 6674 	/* Read the flags */
 6675 	if (encoding->flags & IW_ENCODE_DISABLED)
 6676 		set_auth_type(local, AUTH_OPEN);	/* disable encryption */
 6677 	if(encoding->flags & IW_ENCODE_RESTRICTED)
 6678 		set_auth_type(local, AUTH_SHAREDKEY);	/* Only Both */
 6679 	if (encoding->flags & IW_ENCODE_OPEN)
 6680 		set_auth_type(local, AUTH_ENCRYPT);
 6681 	/* Commit the changes to flags if needed */
 6682 	if (local->config.authType != currentAuthType)
 6683 		set_bit (FLAG_COMMIT, &local->flags);
 6684 
 6685 	return -EINPROGRESS;
 6686 }
 6687 
 6688 
 6689 /*------------------------------------------------------------------*/
 6690 /*
 6691  * Wireless Handler : get extended Encryption parameters
 6692  */
 6693 static int airo_get_encodeext(struct net_device *dev,
 6694 			    struct iw_request_info *info,
 6695 			    union iwreq_data *wrqu,
 6696 			    char *extra)
 6697 {
 6698 	struct airo_info *local = dev->ml_priv;
 6699 	struct iw_point *encoding = &wrqu->encoding;
 6700 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
 6701 	int idx, max_key_len, wep_key_len;
 6702 	u8 buf[16];
 6703 
 6704 	if (!local->wep_capable)
 6705 		return -EOPNOTSUPP;
 6706 
 6707 	readConfigRid(local, 1);
 6708 
 6709 	max_key_len = encoding->length - sizeof(*ext);
 6710 	if (max_key_len < 0)
 6711 		return -EINVAL;
 6712 
 6713 	idx = encoding->flags & IW_ENCODE_INDEX;
 6714 	if (idx) {
 6715 		if (!valid_index(local, idx - 1))
 6716 			return -EINVAL;
 6717 		idx--;
 6718 	} else {
 6719 		idx = get_wep_tx_idx(local);
 6720 		if (idx < 0)
 6721 			idx = 0;
 6722 	}
 6723 
 6724 	encoding->flags = idx + 1;
 6725 	memset(ext, 0, sizeof(*ext));
 6726 
 6727 	/* Check encryption mode */
 6728 	switch(local->config.authType) {
 6729 		case AUTH_ENCRYPT:
 6730 			encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED;
 6731 			break;
 6732 		case AUTH_SHAREDKEY:
 6733 			encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED;
 6734 			break;
 6735 		default:
 6736 		case AUTH_OPEN:
 6737 			encoding->flags = IW_ENCODE_ALG_NONE | IW_ENCODE_DISABLED;
 6738 			break;
 6739 	}
 6740 	/* We can't return the key, so set the proper flag and return zero */
 6741 	encoding->flags |= IW_ENCODE_NOKEY;
 6742 	memset(extra, 0, 16);
 6743 	
 6744 	/* Copy the key to the user buffer */
 6745 	wep_key_len = get_wep_key(local, idx, &buf[0], sizeof(buf));
 6746 	if (wep_key_len < 0) {
 6747 		ext->key_len = 0;
 6748 	} else {
 6749 		ext->key_len = wep_key_len;
 6750 		memcpy(extra, buf, ext->key_len);
 6751 	}
 6752 
 6753 	return 0;
 6754 }
 6755 
 6756 
 6757 /*------------------------------------------------------------------*/
 6758 /*
 6759  * Wireless Handler : set extended authentication parameters
 6760  */
 6761 static int airo_set_auth(struct net_device *dev,
 6762 			       struct iw_request_info *info,
 6763 			       union iwreq_data *wrqu, char *extra)
 6764 {
 6765 	struct airo_info *local = dev->ml_priv;
 6766 	struct iw_param *param = &wrqu->param;
 6767 	__le16 currentAuthType = local->config.authType;
 6768 
 6769 	switch (param->flags & IW_AUTH_INDEX) {
 6770 	case IW_AUTH_WPA_VERSION:
 6771 	case IW_AUTH_CIPHER_PAIRWISE:
 6772 	case IW_AUTH_CIPHER_GROUP:
 6773 	case IW_AUTH_KEY_MGMT:
 6774 	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
 6775 	case IW_AUTH_PRIVACY_INVOKED:
 6776 		/*
 6777 		 * airo does not use these parameters
 6778 		 */
 6779 		break;
 6780 
 6781 	case IW_AUTH_DROP_UNENCRYPTED:
 6782 		if (param->value) {
 6783 			/* Only change auth type if unencrypted */
 6784 			if (currentAuthType == AUTH_OPEN)
 6785 				set_auth_type(local, AUTH_ENCRYPT);
 6786 		} else {
 6787 			set_auth_type(local, AUTH_OPEN);
 6788 		}
 6789 
 6790 		/* Commit the changes to flags if needed */
 6791 		if (local->config.authType != currentAuthType)
 6792 			set_bit (FLAG_COMMIT, &local->flags);
 6793 		break;
 6794 
 6795 	case IW_AUTH_80211_AUTH_ALG: {
 6796 			if (param->value & IW_AUTH_ALG_SHARED_KEY) {
 6797 				set_auth_type(local, AUTH_SHAREDKEY);
 6798 			} else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
 6799 				/* We don't know here if WEP open system or
 6800 				 * unencrypted mode was requested - so use the
 6801 				 * last mode (of these two) used last time
 6802 				 */
 6803 				set_auth_type(local, local->last_auth);
 6804 			} else
 6805 				return -EINVAL;
 6806 
 6807 			/* Commit the changes to flags if needed */
 6808 			if (local->config.authType != currentAuthType)
 6809 				set_bit (FLAG_COMMIT, &local->flags);
 6810 			break;
 6811 		}
 6812 
 6813 	case IW_AUTH_WPA_ENABLED:
 6814 		/* Silently accept disable of WPA */
 6815 		if (param->value > 0)
 6816 			return -EOPNOTSUPP;
 6817 		break;
 6818 
 6819 	default:
 6820 		return -EOPNOTSUPP;
 6821 	}
 6822 	return -EINPROGRESS;
 6823 }
 6824 
 6825 
 6826 /*------------------------------------------------------------------*/
 6827 /*
 6828  * Wireless Handler : get extended authentication parameters
 6829  */
 6830 static int airo_get_auth(struct net_device *dev,
 6831 			       struct iw_request_info *info,
 6832 			       union iwreq_data *wrqu, char *extra)
 6833 {
 6834 	struct airo_info *local = dev->ml_priv;
 6835 	struct iw_param *param = &wrqu->param;
 6836 	__le16 currentAuthType = local->config.authType;
 6837 
 6838 	switch (param->flags & IW_AUTH_INDEX) {
 6839 	case IW_AUTH_DROP_UNENCRYPTED:
 6840 		switch (currentAuthType) {
 6841 		case AUTH_SHAREDKEY:
 6842 		case AUTH_ENCRYPT:
 6843 			param->value = 1;
 6844 			break;
 6845 		default:
 6846 			param->value = 0;
 6847 			break;
 6848 		}
 6849 		break;
 6850 
 6851 	case IW_AUTH_80211_AUTH_ALG:
 6852 		switch (currentAuthType) {
 6853 		case AUTH_SHAREDKEY:
 6854 			param->value = IW_AUTH_ALG_SHARED_KEY;
 6855 			break;
 6856 		case AUTH_ENCRYPT:
 6857 		default:
 6858 			param->value = IW_AUTH_ALG_OPEN_SYSTEM;
 6859 			break;
 6860 		}
 6861 		break;
 6862 
 6863 	case IW_AUTH_WPA_ENABLED:
 6864 		param->value = 0;
 6865 		break;
 6866 
 6867 	default:
 6868 		return -EOPNOTSUPP;
 6869 	}
 6870 	return 0;
 6871 }
 6872 
 6873 
 6874 /*------------------------------------------------------------------*/
 6875 /*
 6876  * Wireless Handler : set Tx-Power
 6877  */
 6878 static int airo_set_txpow(struct net_device *dev,
 6879 			  struct iw_request_info *info,
 6880 			  struct iw_param *vwrq,
 6881 			  char *extra)
 6882 {
 6883 	struct airo_info *local = dev->ml_priv;
 6884 	CapabilityRid cap_rid;		/* Card capability info */
 6885 	int i;
 6886 	int rc = -EINVAL;
 6887 	__le16 v = cpu_to_le16(vwrq->value);
 6888 
 6889 	readCapabilityRid(local, &cap_rid, 1);
 6890 
 6891 	if (vwrq->disabled) {
 6892 		set_bit (FLAG_RADIO_OFF, &local->flags);
 6893 		set_bit (FLAG_COMMIT, &local->flags);
 6894 		return -EINPROGRESS;		/* Call commit handler */
 6895 	}
 6896 	if (vwrq->flags != IW_TXPOW_MWATT) {
 6897 		return -EINVAL;
 6898 	}
 6899 	clear_bit (FLAG_RADIO_OFF, &local->flags);
 6900 	for (i = 0; i < 8 && cap_rid.txPowerLevels[i]; i++)
 6901 		if (v == cap_rid.txPowerLevels[i]) {
 6902 			readConfigRid(local, 1);
 6903 			local->config.txPower = v;
 6904 			set_bit (FLAG_COMMIT, &local->flags);
 6905 			rc = -EINPROGRESS;	/* Call commit handler */
 6906 			break;
 6907 		}
 6908 	return rc;
 6909 }
 6910 
 6911 /*------------------------------------------------------------------*/
 6912 /*
 6913  * Wireless Handler : get Tx-Power
 6914  */
 6915 static int airo_get_txpow(struct net_device *dev,
 6916 			  struct iw_request_info *info,
 6917 			  struct iw_param *vwrq,
 6918 			  char *extra)
 6919 {
 6920 	struct airo_info *local = dev->ml_priv;
 6921 
 6922 	readConfigRid(local, 1);
 6923 	vwrq->value = le16_to_cpu(local->config.txPower);
 6924 	vwrq->fixed = 1;	/* No power control */
 6925 	vwrq->disabled = test_bit(FLAG_RADIO_OFF, &local->flags);
 6926 	vwrq->flags = IW_TXPOW_MWATT;
 6927 
 6928 	return 0;
 6929 }
 6930 
 6931 /*------------------------------------------------------------------*/
 6932 /*
 6933  * Wireless Handler : set Retry limits
 6934  */
 6935 static int airo_set_retry(struct net_device *dev,
 6936 			  struct iw_request_info *info,
 6937 			  struct iw_param *vwrq,
 6938 			  char *extra)
 6939 {
 6940 	struct airo_info *local = dev->ml_priv;
 6941 	int rc = -EINVAL;
 6942 
 6943 	if(vwrq->disabled) {
 6944 		return -EINVAL;
 6945 	}
 6946 	readConfigRid(local, 1);
 6947 	if(vwrq->flags & IW_RETRY_LIMIT) {
 6948 		__le16 v = cpu_to_le16(vwrq->value);
 6949 		if(vwrq->flags & IW_RETRY_LONG)
 6950 			local->config.longRetryLimit = v;
 6951 		else if (vwrq->flags & IW_RETRY_SHORT)
 6952 			local->config.shortRetryLimit = v;
 6953 		else {
 6954 			/* No modifier : set both */
 6955 			local->config.longRetryLimit = v;
 6956 			local->config.shortRetryLimit = v;
 6957 		}
 6958 		set_bit (FLAG_COMMIT, &local->flags);
 6959 		rc = -EINPROGRESS;		/* Call commit handler */
 6960 	}
 6961 	if(vwrq->flags & IW_RETRY_LIFETIME) {
 6962 		local->config.txLifetime = cpu_to_le16(vwrq->value / 1024);
 6963 		set_bit (FLAG_COMMIT, &local->flags);
 6964 		rc = -EINPROGRESS;		/* Call commit handler */
 6965 	}
 6966 	return rc;
 6967 }
 6968 
 6969 /*------------------------------------------------------------------*/
 6970 /*
 6971  * Wireless Handler : get Retry limits
 6972  */
 6973 static int airo_get_retry(struct net_device *dev,
 6974 			  struct iw_request_info *info,
 6975 			  struct iw_param *vwrq,
 6976 			  char *extra)
 6977 {
 6978 	struct airo_info *local = dev->ml_priv;
 6979 
 6980 	vwrq->disabled = 0;      /* Can't be disabled */
 6981 
 6982 	readConfigRid(local, 1);
 6983 	/* Note : by default, display the min retry number */
 6984 	if((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
 6985 		vwrq->flags = IW_RETRY_LIFETIME;
 6986 		vwrq->value = le16_to_cpu(local->config.txLifetime) * 1024;
 6987 	} else if((vwrq->flags & IW_RETRY_LONG)) {
 6988 		vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
 6989 		vwrq->value = le16_to_cpu(local->config.longRetryLimit);
 6990 	} else {
 6991 		vwrq->flags = IW_RETRY_LIMIT;
 6992 		vwrq->value = le16_to_cpu(local->config.shortRetryLimit);
 6993 		if(local->config.shortRetryLimit != local->config.longRetryLimit)
 6994 			vwrq->flags |= IW_RETRY_SHORT;
 6995 	}
 6996 
 6997 	return 0;
 6998 }
 6999 
 7000 /*------------------------------------------------------------------*/
 7001 /*
 7002  * Wireless Handler : get range info
 7003  */
 7004 static int airo_get_range(struct net_device *dev,
 7005 			  struct iw_request_info *info,
 7006 			  struct iw_point *dwrq,
 7007 			  char *extra)
 7008 {
 7009 	struct airo_info *local = dev->ml_priv;
 7010 	struct iw_range *range = (struct iw_range *) extra;
 7011 	CapabilityRid cap_rid;		/* Card capability info */
 7012 	int		i;
 7013 	int		k;
 7014 
 7015 	readCapabilityRid(local, &cap_rid, 1);
 7016 
 7017 	dwrq->length = sizeof(struct iw_range);
 7018 	memset(range, 0, sizeof(*range));
 7019 	range->min_nwid = 0x0000;
 7020 	range->max_nwid = 0x0000;
 7021 	range->num_channels = 14;
 7022 	/* Should be based on cap_rid.country to give only
 7023 	 * what the current card support */
 7024 	k = 0;
 7025 	for(i = 0; i < 14; i++) {
 7026 		range->freq[k].i = i + 1; /* List index */
 7027 		range->freq[k].m = 100000 *
 7028 		     ieee80211_channel_to_frequency(i + 1, IEEE80211_BAND_2GHZ);
 7029 		range->freq[k++].e = 1;	/* Values in MHz -> * 10^5 * 10 */
 7030 	}
 7031 	range->num_frequency = k;
 7032 
 7033 	range->sensitivity = 65535;
 7034 
 7035 	/* Hum... Should put the right values there */
 7036 	if (local->rssi)
 7037 		range->max_qual.qual = 100;	/* % */
 7038 	else
 7039 		range->max_qual.qual = airo_get_max_quality(&cap_rid);
 7040 	range->max_qual.level = 0x100 - 120;	/* -120 dBm */
 7041 	range->max_qual.noise = 0x100 - 120;	/* -120 dBm */
 7042 
 7043 	/* Experimental measurements - boundary 11/5.5 Mb/s */
 7044 	/* Note : with or without the (local->rssi), results
 7045 	 * are somewhat different. - Jean II */
 7046 	if (local->rssi) {
 7047 		range->avg_qual.qual = 50;		/* % */
 7048 		range->avg_qual.level = 0x100 - 70;	/* -70 dBm */
 7049 	} else {
 7050 		range->avg_qual.qual = airo_get_avg_quality(&cap_rid);
 7051 		range->avg_qual.level = 0x100 - 80;	/* -80 dBm */
 7052 	}
 7053 	range->avg_qual.noise = 0x100 - 85;		/* -85 dBm */
 7054 
 7055 	for(i = 0 ; i < 8 ; i++) {
 7056 		range->bitrate[i] = cap_rid.supportedRates[i] * 500000;
 7057 		if(range->bitrate[i] == 0)
 7058 			break;
 7059 	}
 7060 	range->num_bitrates = i;
 7061 
 7062 	/* Set an indication of the max TCP throughput
 7063 	 * in bit/s that we can expect using this interface.
 7064 	 * May be use for QoS stuff... Jean II */
 7065 	if(i > 2)
 7066 		range->throughput = 5000 * 1000;
 7067 	else
 7068 		range->throughput = 1500 * 1000;
 7069 
 7070 	range->min_rts = 0;
 7071 	range->max_rts = AIRO_DEF_MTU;
 7072 	range->min_frag = 256;
 7073 	range->max_frag = AIRO_DEF_MTU;
 7074 
 7075 	if(cap_rid.softCap & cpu_to_le16(2)) {
 7076 		// WEP: RC4 40 bits
 7077 		range->encoding_size[0] = 5;
 7078 		// RC4 ~128 bits
 7079 		if (cap_rid.softCap & cpu_to_le16(0x100)) {
 7080 			range->encoding_size[1] = 13;
 7081 			range->num_encoding_sizes = 2;
 7082 		} else
 7083 			range->num_encoding_sizes = 1;
 7084 		range->max_encoding_tokens =
 7085 			cap_rid.softCap & cpu_to_le16(0x80) ? 4 : 1;
 7086 	} else {
 7087 		range->num_encoding_sizes = 0;
 7088 		range->max_encoding_tokens = 0;
 7089 	}
 7090 	range->min_pmp = 0;
 7091 	range->max_pmp = 5000000;	/* 5 secs */
 7092 	range->min_pmt = 0;
 7093 	range->max_pmt = 65535 * 1024;	/* ??? */
 7094 	range->pmp_flags = IW_POWER_PERIOD;
 7095 	range->pmt_flags = IW_POWER_TIMEOUT;
 7096 	range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
 7097 
 7098 	/* Transmit Power - values are in mW */
 7099 	for(i = 0 ; i < 8 ; i++) {
 7100 		range->txpower[i] = le16_to_cpu(cap_rid.txPowerLevels[i]);
 7101 		if(range->txpower[i] == 0)
 7102 			break;
 7103 	}
 7104 	range->num_txpower = i;
 7105 	range->txpower_capa = IW_TXPOW_MWATT;
 7106 	range->we_version_source = 19;
 7107 	range->we_version_compiled = WIRELESS_EXT;
 7108 	range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
 7109 	range->retry_flags = IW_RETRY_LIMIT;
 7110 	range->r_time_flags = IW_RETRY_LIFETIME;
 7111 	range->min_retry = 1;
 7112 	range->max_retry = 65535;
 7113 	range->min_r_time = 1024;
 7114 	range->max_r_time = 65535 * 1024;
 7115 
 7116 	/* Event capability (kernel + driver) */
 7117 	range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
 7118 				IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
 7119 				IW_EVENT_CAPA_MASK(SIOCGIWAP) |
 7120 				IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
 7121 	range->event_capa[1] = IW_EVENT_CAPA_K_1;
 7122 	range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVTXDROP);
 7123 	return 0;
 7124 }
 7125 
 7126 /*------------------------------------------------------------------*/
 7127 /*
 7128  * Wireless Handler : set Power Management
 7129  */
 7130 static int airo_set_power(struct net_device *dev,
 7131 			  struct iw_request_info *info,
 7132 			  struct iw_param *vwrq,
 7133 			  char *extra)
 7134 {
 7135 	struct airo_info *local = dev->ml_priv;
 7136 
 7137 	readConfigRid(local, 1);
 7138 	if (vwrq->disabled) {
 7139 		if (sniffing_mode(local))
 7140 			return -EINVAL;
 7141 		local->config.powerSaveMode = POWERSAVE_CAM;
 7142 		local->config.rmode &= ~RXMODE_MASK;
 7143 		local->config.rmode |= RXMODE_BC_MC_ADDR;
 7144 		set_bit (FLAG_COMMIT, &local->flags);
 7145 		return -EINPROGRESS;		/* Call commit handler */
 7146 	}
 7147 	if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
 7148 		local->config.fastListenDelay = cpu_to_le16((vwrq->value + 500) / 1024);
 7149 		local->config.powerSaveMode = POWERSAVE_PSPCAM;
 7150 		set_bit (FLAG_COMMIT, &local->flags);
 7151 	} else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
 7152 		local->config.fastListenInterval =
 7153 		local->config.listenInterval =
 7154 			cpu_to_le16((vwrq->value + 500) / 1024);
 7155 		local->config.powerSaveMode = POWERSAVE_PSPCAM;
 7156 		set_bit (FLAG_COMMIT, &local->flags);
 7157 	}
 7158 	switch (vwrq->flags & IW_POWER_MODE) {
 7159 		case IW_POWER_UNICAST_R:
 7160 			if (sniffing_mode(local))
 7161 				return -EINVAL;
 7162 			local->config.rmode &= ~RXMODE_MASK;
 7163 			local->config.rmode |= RXMODE_ADDR;
 7164 			set_bit (FLAG_COMMIT, &local->flags);
 7165 			break;
 7166 		case IW_POWER_ALL_R:
 7167 			if (sniffing_mode(local))
 7168 				return -EINVAL;
 7169 			local->config.rmode &= ~RXMODE_MASK;
 7170 			local->config.rmode |= RXMODE_BC_MC_ADDR;
 7171 			set_bit (FLAG_COMMIT, &local->flags);
 7172 		case IW_POWER_ON:
 7173 			/* This is broken, fixme ;-) */
 7174 			break;
 7175 		default:
 7176 			return -EINVAL;
 7177 	}
 7178 	// Note : we may want to factor local->need_commit here
 7179 	// Note2 : may also want to factor RXMODE_RFMON test
 7180 	return -EINPROGRESS;		/* Call commit handler */
 7181 }
 7182 
 7183 /*------------------------------------------------------------------*/
 7184 /*
 7185  * Wireless Handler : get Power Management
 7186  */
 7187 static int airo_get_power(struct net_device *dev,
 7188 			  struct iw_request_info *info,
 7189 			  struct iw_param *vwrq,
 7190 			  char *extra)
 7191 {
 7192 	struct airo_info *local = dev->ml_priv;
 7193 	__le16 mode;
 7194 
 7195 	readConfigRid(local, 1);
 7196 	mode = local->config.powerSaveMode;
 7197 	if ((vwrq->disabled = (mode == POWERSAVE_CAM)))
 7198 		return 0;
 7199 	if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
 7200 		vwrq->value = le16_to_cpu(local->config.fastListenDelay) * 1024;
 7201 		vwrq->flags = IW_POWER_TIMEOUT;
 7202 	} else {
 7203 		vwrq->value = le16_to_cpu(local->config.fastListenInterval) * 1024;
 7204 		vwrq->flags = IW_POWER_PERIOD;
 7205 	}
 7206 	if ((local->config.rmode & RXMODE_MASK) == RXMODE_ADDR)
 7207 		vwrq->flags |= IW_POWER_UNICAST_R;
 7208 	else
 7209 		vwrq->flags |= IW_POWER_ALL_R;
 7210 
 7211 	return 0;
 7212 }
 7213 
 7214 /*------------------------------------------------------------------*/
 7215 /*
 7216  * Wireless Handler : set Sensitivity
 7217  */
 7218 static int airo_set_sens(struct net_device *dev,
 7219 			 struct iw_request_info *info,
 7220 			 struct iw_param *vwrq,
 7221 			 char *extra)
 7222 {
 7223 	struct airo_info *local = dev->ml_priv;
 7224 
 7225 	readConfigRid(local, 1);
 7226 	local->config.rssiThreshold =
 7227 		cpu_to_le16(vwrq->disabled ? RSSI_DEFAULT : vwrq->value);
 7228 	set_bit (FLAG_COMMIT, &local->flags);
 7229 
 7230 	return -EINPROGRESS;		/* Call commit handler */
 7231 }
 7232 
 7233 /*------------------------------------------------------------------*/
 7234 /*
 7235  * Wireless Handler : get Sensitivity
 7236  */
 7237 static int airo_get_sens(struct net_device *dev,
 7238 			 struct iw_request_info *info,
 7239 			 struct iw_param *vwrq,
 7240 			 char *extra)
 7241 {
 7242 	struct airo_info *local = dev->ml_priv;
 7243 
 7244 	readConfigRid(local, 1);
 7245 	vwrq->value = le16_to_cpu(local->config.rssiThreshold);
 7246 	vwrq->disabled = (vwrq->value == 0);
 7247 	vwrq->fixed = 1;
 7248 
 7249 	return 0;
 7250 }
 7251 
 7252 /*------------------------------------------------------------------*/
 7253 /*
 7254  * Wireless Handler : get AP List
 7255  * Note : this is deprecated in favor of IWSCAN
 7256  */
 7257 static int airo_get_aplist(struct net_device *dev,
 7258 			   struct iw_request_info *info,
 7259 			   struct iw_point *dwrq,
 7260 			   char *extra)
 7261 {
 7262 	struct airo_info *local = dev->ml_priv;
 7263 	struct sockaddr *address = (struct sockaddr *) extra;
 7264 	struct iw_quality *qual;
 7265 	BSSListRid BSSList;
 7266 	int i;
 7267 	int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
 7268 
 7269 	qual = kmalloc(IW_MAX_AP * sizeof(*qual), GFP_KERNEL);
 7270 	if (!qual)
 7271 		return -ENOMEM;
 7272 
 7273 	for (i = 0; i < IW_MAX_AP; i++) {
 7274 		u16 dBm;
 7275 		if (readBSSListRid(local, loseSync, &BSSList))
 7276 			break;
 7277 		loseSync = 0;
 7278 		memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN);
 7279 		address[i].sa_family = ARPHRD_ETHER;
 7280 		dBm = le16_to_cpu(BSSList.dBm);
 7281 		if (local->rssi) {
 7282 			qual[i].level = 0x100 - dBm;
 7283 			qual[i].qual = airo_dbm_to_pct(local->rssi, dBm);
 7284 			qual[i].updated = IW_QUAL_QUAL_UPDATED
 7285 					| IW_QUAL_LEVEL_UPDATED
 7286 					| IW_QUAL_DBM;
 7287 		} else {
 7288 			qual[i].level = (dBm + 321) / 2;
 7289 			qual[i].qual = 0;
 7290 			qual[i].updated = IW_QUAL_QUAL_INVALID
 7291 					| IW_QUAL_LEVEL_UPDATED
 7292 					| IW_QUAL_DBM;
 7293 		}
 7294 		qual[i].noise = local->wstats.qual.noise;
 7295 		if (BSSList.index == cpu_to_le16(0xffff))
 7296 			break;
 7297 	}
 7298 	if (!i) {
 7299 		StatusRid status_rid;		/* Card status info */
 7300 		readStatusRid(local, &status_rid, 1);
 7301 		for (i = 0;
 7302 		     i < min(IW_MAX_AP, 4) &&
 7303 			     (status_rid.bssid[i][0]
 7304 			      & status_rid.bssid[i][1]
 7305 			      & status_rid.bssid[i][2]
 7306 			      & status_rid.bssid[i][3]
 7307 			      & status_rid.bssid[i][4]
 7308 			      & status_rid.bssid[i][5])!=0xff &&
 7309 			     (status_rid.bssid[i][0]
 7310 			      | status_rid.bssid[i][1]
 7311 			      | status_rid.bssid[i][2]
 7312 			      | status_rid.bssid[i][3]
 7313 			      | status_rid.bssid[i][4]
 7314 			      | status_rid.bssid[i][5]);
 7315 		     i++) {
 7316 			memcpy(address[i].sa_data,
 7317 			       status_rid.bssid[i], ETH_ALEN);
 7318 			address[i].sa_family = ARPHRD_ETHER;
 7319 		}
 7320 	} else {
 7321 		dwrq->flags = 1; /* Should be define'd */
 7322 		memcpy(extra + sizeof(struct sockaddr) * i, qual,
 7323 		       sizeof(struct iw_quality) * i);
 7324 	}
 7325 	dwrq->length = i;
 7326 
 7327 	kfree(qual);
 7328 	return 0;
 7329 }
 7330 
 7331 /*------------------------------------------------------------------*/
 7332 /*
 7333  * Wireless Handler : Initiate Scan
 7334  */
 7335 static int airo_set_scan(struct net_device *dev,
 7336 			 struct iw_request_info *info,
 7337 			 struct iw_point *dwrq,
 7338 			 char *extra)
 7339 {
 7340 	struct airo_info *ai = dev->ml_priv;
 7341 	Cmd cmd;
 7342 	Resp rsp;
 7343 	int wake = 0;
 7344 	APListRid APList_rid_empty;
 7345 
 7346 	/* Note : you may have realised that, as this is a SET operation,
 7347 	 * this is privileged and therefore a normal user can't
 7348 	 * perform scanning.
 7349 	 * This is not an error, while the device perform scanning,
 7350 	 * traffic doesn't flow, so it's a perfect DoS...
 7351 	 * Jean II */
 7352 	if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
 7353 
 7354 	if (down_interruptible(&ai->sem))
 7355 		return -ERESTARTSYS;
 7356 
 7357 	/* If there's already a scan in progress, don't
 7358 	 * trigger another one. */
 7359 	if (ai->scan_timeout > 0)
 7360 		goto out;
 7361 
 7362 	/* Clear APList as it affects scan results */
 7363 	memset(&APList_rid_empty, 0, sizeof(APList_rid_empty));
 7364 	APList_rid_empty.len = cpu_to_le16(sizeof(APList_rid_empty));
 7365 	disable_MAC(ai, 2);
 7366 	writeAPListRid(ai, &APList_rid_empty, 0);
 7367 	enable_MAC(ai, 0);
 7368 
 7369 	/* Initiate a scan command */
 7370 	ai->scan_timeout = RUN_AT(3*HZ);
 7371 	memset(&cmd, 0, sizeof(cmd));
 7372 	cmd.cmd=CMD_LISTBSS;
 7373 	issuecommand(ai, &cmd, &rsp);
 7374 	wake = 1;
 7375 
 7376 out:
 7377 	up(&ai->sem);
 7378 	if (wake)
 7379 		wake_up_interruptible(&ai->thr_wait);
 7380 	return 0;
 7381 }
 7382 
 7383 /*------------------------------------------------------------------*/
 7384 /*
 7385  * Translate scan data returned from the card to a card independent
 7386  * format that the Wireless Tools will understand - Jean II
 7387  */
 7388 static inline char *airo_translate_scan(struct net_device *dev,
 7389 					struct iw_request_info *info,
 7390 					char *current_ev,
 7391 					char *end_buf,
 7392 					BSSListRid *bss)
 7393 {
 7394 	struct airo_info *ai = dev->ml_priv;
 7395 	struct iw_event		iwe;		/* Temporary buffer */
 7396 	__le16			capabilities;
 7397 	char *			current_val;	/* For rates */
 7398 	int			i;
 7399 	char *		buf;
 7400 	u16 dBm;
 7401 
 7402 	/* First entry *MUST* be the AP MAC address */
 7403 	iwe.cmd = SIOCGIWAP;
 7404 	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
 7405 	memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
 7406 	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
 7407 					  &iwe, IW_EV_ADDR_LEN);
 7408 
 7409 	/* Other entries will be displayed in the order we give them */
 7410 
 7411 	/* Add the ESSID */
 7412 	iwe.u.data.length = bss->ssidLen;
 7413 	if(iwe.u.data.length > 32)
 7414 		iwe.u.data.length = 32;
 7415 	iwe.cmd = SIOCGIWESSID;
 7416 	iwe.u.data.flags = 1;
 7417 	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
 7418 					  &iwe, bss->ssid);
 7419 
 7420 	/* Add mode */
 7421 	iwe.cmd = SIOCGIWMODE;
 7422 	capabilities = bss->cap;
 7423 	if(capabilities & (CAP_ESS | CAP_IBSS)) {
 7424 		if(capabilities & CAP_ESS)
 7425 			iwe.u.mode = IW_MODE_MASTER;
 7426 		else
 7427 			iwe.u.mode = IW_MODE_ADHOC;
 7428 		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
 7429 						  &iwe, IW_EV_UINT_LEN);
 7430 	}
 7431 
 7432 	/* Add frequency */
 7433 	iwe.cmd = SIOCGIWFREQ;
 7434 	iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
 7435 	iwe.u.freq.m = 100000 *
 7436 	      ieee80211_channel_to_frequency(iwe.u.freq.m, IEEE80211_BAND_2GHZ);
 7437 	iwe.u.freq.e = 1;
 7438 	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
 7439 					  &iwe, IW_EV_FREQ_LEN);
 7440 
 7441 	dBm = le16_to_cpu(bss->dBm);
 7442 
 7443 	/* Add quality statistics */
 7444 	iwe.cmd = IWEVQUAL;
 7445 	if (ai->rssi) {
 7446 		iwe.u.qual.level = 0x100 - dBm;
 7447 		iwe.u.qual.qual = airo_dbm_to_pct(ai->rssi, dBm);
 7448 		iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
 7449 				| IW_QUAL_LEVEL_UPDATED
 7450 				| IW_QUAL_DBM;
 7451 	} else {
 7452 		iwe.u.qual.level = (dBm + 321) / 2;
 7453 		iwe.u.qual.qual = 0;
 7454 		iwe.u.qual.updated = IW_QUAL_QUAL_INVALID
 7455 				| IW_QUAL_LEVEL_UPDATED
 7456 				| IW_QUAL_DBM;
 7457 	}
 7458 	iwe.u.qual.noise = ai->wstats.qual.noise;
 7459 	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
 7460 					  &iwe, IW_EV_QUAL_LEN);
 7461 
 7462 	/* Add encryption capability */
 7463 	iwe.cmd = SIOCGIWENCODE;
 7464 	if(capabilities & CAP_PRIVACY)
 7465 		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
 7466 	else
 7467 		iwe.u.data.flags = IW_ENCODE_DISABLED;
 7468 	iwe.u.data.length = 0;
 7469 	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
 7470 					  &iwe, bss->ssid);
 7471 
 7472 	/* Rate : stuffing multiple values in a single event require a bit
 7473 	 * more of magic - Jean II */
 7474 	current_val = current_ev + iwe_stream_lcp_len(info);
 7475 
 7476 	iwe.cmd = SIOCGIWRATE;
 7477 	/* Those two flags are ignored... */
 7478 	iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
 7479 	/* Max 8 values */
 7480 	for(i = 0 ; i < 8 ; i++) {
 7481 		/* NULL terminated */
 7482 		if(bss->rates[i] == 0)
 7483 			break;
 7484 		/* Bit rate given in 500 kb/s units (+ 0x80) */
 7485 		iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
 7486 		/* Add new value to event */
 7487 		current_val = iwe_stream_add_value(info, current_ev,
 7488 						   current_val, end_buf,
 7489 						   &iwe, IW_EV_PARAM_LEN);
 7490 	}
 7491 	/* Check if we added any event */
 7492 	if ((current_val - current_ev) > iwe_stream_lcp_len(info))
 7493 		current_ev = current_val;
 7494 
 7495 	/* Beacon interval */
 7496 	buf = kmalloc(30, GFP_KERNEL);
 7497 	if (buf) {
 7498 		iwe.cmd = IWEVCUSTOM;
 7499 		sprintf(buf, "bcn_int=%d", bss->beaconInterval);
 7500 		iwe.u.data.length = strlen(buf);
 7501 		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
 7502 						  &iwe, buf);
 7503 		kfree(buf);
 7504 	}
 7505 
 7506 	/* Put WPA/RSN Information Elements into the event stream */
 7507 	if (test_bit(FLAG_WPA_CAPABLE, &ai->flags)) {
 7508 		unsigned int num_null_ies = 0;
 7509 		u16 length = sizeof (bss->extra.iep);
 7510 		u8 *ie = (void *)&bss->extra.iep;
 7511 
 7512 		while ((length >= 2) && (num_null_ies < 2)) {
 7513 			if (2 + ie[1] > length) {
 7514 				/* Invalid element, don't continue parsing IE */
 7515 				break;
 7516 			}
 7517 
 7518 			switch (ie[0]) {
 7519 			case WLAN_EID_SSID:
 7520 				/* Two zero-length SSID elements
 7521 				 * mean we're done parsing elements */
 7522 				if (!ie[1])
 7523 					num_null_ies++;
 7524 				break;
 7525 
 7526 			case WLAN_EID_VENDOR_SPECIFIC:
 7527 				if (ie[1] >= 4 &&
 7528 				    ie[2] == 0x00 &&
 7529 				    ie[3] == 0x50 &&
 7530 				    ie[4] == 0xf2 &&
 7531 				    ie[5] == 0x01) {
 7532 					iwe.cmd = IWEVGENIE;
 7533 					/* 64 is an arbitrary cut-off */
 7534 					iwe.u.data.length = min(ie[1] + 2,
 7535 								64);
 7536 					current_ev = iwe_stream_add_point(
 7537 							info, current_ev,
 7538 							end_buf, &iwe, ie);
 7539 				}
 7540 				break;
 7541 
 7542 			case WLAN_EID_RSN:
 7543 				iwe.cmd = IWEVGENIE;
 7544 				/* 64 is an arbitrary cut-off */
 7545 				iwe.u.data.length = min(ie[1] + 2, 64);
 7546 				current_ev = iwe_stream_add_point(
 7547 					info, current_ev, end_buf,
 7548 					&iwe, ie);
 7549 				break;
 7550 
 7551 			default:
 7552 				break;
 7553 			}
 7554 
 7555 			length -= 2 + ie[1];
 7556 			ie += 2 + ie[1];
 7557 		}
 7558 	}
 7559 	return current_ev;
 7560 }
 7561 
 7562 /*------------------------------------------------------------------*/
 7563 /*
 7564  * Wireless Handler : Read Scan Results
 7565  */
 7566 static int airo_get_scan(struct net_device *dev,
 7567 			 struct iw_request_info *info,
 7568 			 struct iw_point *dwrq,
 7569 			 char *extra)
 7570 {
 7571 	struct airo_info *ai = dev->ml_priv;
 7572 	BSSListElement *net;
 7573 	int err = 0;
 7574 	char *current_ev = extra;
 7575 
 7576 	/* If a scan is in-progress, return -EAGAIN */
 7577 	if (ai->scan_timeout > 0)
 7578 		return -EAGAIN;
 7579 
 7580 	if (down_interruptible(&ai->sem))
 7581 		return -EAGAIN;
 7582 
 7583 	list_for_each_entry (net, &ai->network_list, list) {
 7584 		/* Translate to WE format this entry */
 7585 		current_ev = airo_translate_scan(dev, info, current_ev,
 7586 						 extra + dwrq->length,
 7587 						 &net->bss);
 7588 
 7589 		/* Check if there is space for one more entry */
 7590 		if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) {
 7591 			/* Ask user space to try again with a bigger buffer */
 7592 			err = -E2BIG;
 7593 			goto out;
 7594 		}
 7595 	}
 7596 
 7597 	/* Length of data */
 7598 	dwrq->length = (current_ev - extra);
 7599 	dwrq->flags = 0;	/* todo */
 7600 
 7601 out:
 7602 	up(&ai->sem);
 7603 	return err;
 7604 }
 7605 
 7606 /*------------------------------------------------------------------*/
 7607 /*
 7608  * Commit handler : called after a bunch of SET operations
 7609  */
 7610 static int airo_config_commit(struct net_device *dev,
 7611 			      struct iw_request_info *info,	/* NULL */
 7612 			      void *zwrq,			/* NULL */
 7613 			      char *extra)			/* NULL */
 7614 {
 7615 	struct airo_info *local = dev->ml_priv;
 7616 
 7617 	if (!test_bit (FLAG_COMMIT, &local->flags))
 7618 		return 0;
 7619 
 7620 	/* Some of the "SET" function may have modified some of the
 7621 	 * parameters. It's now time to commit them in the card */
 7622 	disable_MAC(local, 1);
 7623 	if (test_bit (FLAG_RESET, &local->flags)) {
 7624 		SsidRid SSID_rid;
 7625 
 7626 		readSsidRid(local, &SSID_rid);
 7627 		if (test_bit(FLAG_MPI,&local->flags))
 7628 			setup_card(local, dev->dev_addr, 1 );
 7629 		else
 7630 			reset_airo_card(dev);
 7631 		disable_MAC(local, 1);
 7632 		writeSsidRid(local, &SSID_rid, 1);
 7633 		writeAPListRid(local, &local->APList, 1);
 7634 	}
 7635 	if (down_interruptible(&local->sem))
 7636 		return -ERESTARTSYS;
 7637 	writeConfigRid(local, 0);
 7638 	enable_MAC(local, 0);
 7639 	if (test_bit (FLAG_RESET, &local->flags))
 7640 		airo_set_promisc(local);
 7641 	else
 7642 		up(&local->sem);
 7643 
 7644 	return 0;
 7645 }
 7646 
 7647 /*------------------------------------------------------------------*/
 7648 /*
 7649  * Structures to export the Wireless Handlers
 7650  */
 7651 
 7652 static const struct iw_priv_args airo_private_args[] = {
 7653 /*{ cmd,         set_args,                            get_args, name } */
 7654   { AIROIOCTL, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
 7655     IW_PRIV_TYPE_BYTE | 2047, "airoioctl" },
 7656   { AIROIDIFC, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
 7657     IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "airoidifc" },
 7658 };
 7659 
 7660 static const iw_handler		airo_handler[] =
 7661 {
 7662 	(iw_handler) airo_config_commit,	/* SIOCSIWCOMMIT */
 7663 	(iw_handler) airo_get_name,		/* SIOCGIWNAME */
 7664 	(iw_handler) NULL,			/* SIOCSIWNWID */
 7665 	(iw_handler) NULL,			/* SIOCGIWNWID */
 7666 	(iw_handler) airo_set_freq,		/* SIOCSIWFREQ */
 7667 	(iw_handler) airo_get_freq,		/* SIOCGIWFREQ */
 7668 	(iw_handler) airo_set_mode,		/* SIOCSIWMODE */
 7669 	(iw_handler) airo_get_mode,		/* SIOCGIWMODE */
 7670 	(iw_handler) airo_set_sens,		/* SIOCSIWSENS */
 7671 	(iw_handler) airo_get_sens,		/* SIOCGIWSENS */
 7672 	(iw_handler) NULL,			/* SIOCSIWRANGE */
 7673 	(iw_handler) airo_get_range,		/* SIOCGIWRANGE */
 7674 	(iw_handler) NULL,			/* SIOCSIWPRIV */
 7675 	(iw_handler) NULL,			/* SIOCGIWPRIV */
 7676 	(iw_handler) NULL,			/* SIOCSIWSTATS */
 7677 	(iw_handler) NULL,			/* SIOCGIWSTATS */
 7678 	iw_handler_set_spy,			/* SIOCSIWSPY */
 7679 	iw_handler_get_spy,			/* SIOCGIWSPY */
 7680 	iw_handler_set_thrspy,			/* SIOCSIWTHRSPY */
 7681 	iw_handler_get_thrspy,			/* SIOCGIWTHRSPY */
 7682 	(iw_handler) airo_set_wap,		/* SIOCSIWAP */
 7683 	(iw_handler) airo_get_wap,		/* SIOCGIWAP */
 7684 	(iw_handler) NULL,			/* -- hole -- */
 7685 	(iw_handler) airo_get_aplist,		/* SIOCGIWAPLIST */
 7686 	(iw_handler) airo_set_scan,		/* SIOCSIWSCAN */
 7687 	(iw_handler) airo_get_scan,		/* SIOCGIWSCAN */
 7688 	(iw_handler) airo_set_essid,		/* SIOCSIWESSID */
 7689 	(iw_handler) airo_get_essid,		/* SIOCGIWESSID */
 7690 	(iw_handler) airo_set_nick,		/* SIOCSIWNICKN */
 7691 	(iw_handler) airo_get_nick,		/* SIOCGIWNICKN */
 7692 	(iw_handler) NULL,			/* -- hole -- */
 7693 	(iw_handler) NULL,			/* -- hole -- */
 7694 	(iw_handler) airo_set_rate,		/* SIOCSIWRATE */
 7695 	(iw_handler) airo_get_rate,		/* SIOCGIWRATE */
 7696 	(iw_handler) airo_set_rts,		/* SIOCSIWRTS */
 7697 	(iw_handler) airo_get_rts,		/* SIOCGIWRTS */
 7698 	(iw_handler) airo_set_frag,		/* SIOCSIWFRAG */
 7699 	(iw_handler) airo_get_frag,		/* SIOCGIWFRAG */
 7700 	(iw_handler) airo_set_txpow,		/* SIOCSIWTXPOW */
 7701 	(iw_handler) airo_get_txpow,		/* SIOCGIWTXPOW */
 7702 	(iw_handler) airo_set_retry,		/* SIOCSIWRETRY */
 7703 	(iw_handler) airo_get_retry,		/* SIOCGIWRETRY */
 7704 	(iw_handler) airo_set_encode,		/* SIOCSIWENCODE */
 7705 	(iw_handler) airo_get_encode,		/* SIOCGIWENCODE */
 7706 	(iw_handler) airo_set_power,		/* SIOCSIWPOWER */
 7707 	(iw_handler) airo_get_power,		/* SIOCGIWPOWER */
 7708 	(iw_handler) NULL,			/* -- hole -- */
 7709 	(iw_handler) NULL,			/* -- hole -- */
 7710 	(iw_handler) NULL,			/* SIOCSIWGENIE */
 7711 	(iw_handler) NULL,			/* SIOCGIWGENIE */
 7712 	(iw_handler) airo_set_auth,		/* SIOCSIWAUTH */
 7713 	(iw_handler) airo_get_auth,		/* SIOCGIWAUTH */
 7714 	(iw_handler) airo_set_encodeext,	/* SIOCSIWENCODEEXT */
 7715 	(iw_handler) airo_get_encodeext,	/* SIOCGIWENCODEEXT */
 7716 	(iw_handler) NULL,			/* SIOCSIWPMKSA */
 7717 };
 7718 
 7719 /* Note : don't describe AIROIDIFC and AIROOLDIDIFC in here.
 7720  * We want to force the use of the ioctl code, because those can't be
 7721  * won't work the iw_handler code (because they simultaneously read
 7722  * and write data and iw_handler can't do that).
 7723  * Note that it's perfectly legal to read/write on a single ioctl command,
 7724  * you just can't use iwpriv and need to force it via the ioctl handler.
 7725  * Jean II */
 7726 static const iw_handler		airo_private_handler[] =
 7727 {
 7728 	NULL,				/* SIOCIWFIRSTPRIV */
 7729 };
 7730 
 7731 static const struct iw_handler_def	airo_handler_def =
 7732 {
 7733 	.num_standard	= ARRAY_SIZE(airo_handler),
 7734 	.num_private	= ARRAY_SIZE(airo_private_handler),
 7735 	.num_private_args = ARRAY_SIZE(airo_private_args),
 7736 	.standard	= airo_handler,
 7737 	.private	= airo_private_handler,
 7738 	.private_args	= airo_private_args,
 7739 	.get_wireless_stats = airo_get_wireless_stats,
 7740 };
 7741 
 7742 /*
 7743  * This defines the configuration part of the Wireless Extensions
 7744  * Note : irq and spinlock protection will occur in the subroutines
 7745  *
 7746  * TODO :
 7747  *	o Check input value more carefully and fill correct values in range
 7748  *	o Test and shakeout the bugs (if any)
 7749  *
 7750  * Jean II
 7751  *
 7752  * Javier Achirica did a great job of merging code from the unnamed CISCO
 7753  * developer that added support for flashing the card.
 7754  */
 7755 static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 7756 {
 7757 	int rc = 0;
 7758 	struct airo_info *ai = dev->ml_priv;
 7759 
 7760 	if (ai->power.event)
 7761 		return 0;
 7762 
 7763 	switch (cmd) {
 7764 #ifdef CISCO_EXT
 7765 	case AIROIDIFC:
 7766 #ifdef AIROOLDIDIFC
 7767 	case AIROOLDIDIFC:
 7768 #endif
 7769 	{
 7770 		int val = AIROMAGIC;
 7771 		aironet_ioctl com;
 7772 		if (copy_from_user(&com,rq->ifr_data,sizeof(com)))
 7773 			rc = -EFAULT;
 7774 		else if (copy_to_user(com.data,(char *)&val,sizeof(val)))
 7775 			rc = -EFAULT;
 7776 	}
 7777 	break;
 7778 
 7779 	case AIROIOCTL:
 7780 #ifdef AIROOLDIOCTL
 7781 	case AIROOLDIOCTL:
 7782 #endif
 7783 		/* Get the command struct and hand it off for evaluation by
 7784 		 * the proper subfunction
 7785 		 */
 7786 	{
 7787 		aironet_ioctl com;
 7788 		if (copy_from_user(&com,rq->ifr_data,sizeof(com))) {
 7789 			rc = -EFAULT;
 7790 			break;
 7791 		}
 7792 
 7793 		/* Separate R/W functions bracket legality here
 7794 		 */
 7795 		if ( com.command == AIRORSWVERSION ) {
 7796 			if (copy_to_user(com.data, swversion, sizeof(swversion)))
 7797 				rc = -EFAULT;
 7798 			else
 7799 				rc = 0;
 7800 		}
 7801 		else if ( com.command <= AIRORRID)
 7802 			rc = readrids(dev,&com);
 7803 		else if ( com.command >= AIROPCAP && com.command <= (AIROPLEAPUSR+2) )
 7804 			rc = writerids(dev,&com);
 7805 		else if ( com.command >= AIROFLSHRST && com.command <= AIRORESTART )
 7806 			rc = flashcard(dev,&com);
 7807 		else
 7808 			rc = -EINVAL;      /* Bad command in ioctl */
 7809 	}
 7810 	break;
 7811 #endif /* CISCO_EXT */
 7812 
 7813 	// All other calls are currently unsupported
 7814 	default:
 7815 		rc = -EOPNOTSUPP;
 7816 	}
 7817 	return rc;
 7818 }
 7819 
 7820 /*
 7821  * Get the Wireless stats out of the driver
 7822  * Note : irq and spinlock protection will occur in the subroutines
 7823  *
 7824  * TODO :
 7825  *	o Check if work in Ad-Hoc mode (otherwise, use SPY, as in wvlan_cs)
 7826  *
 7827  * Jean
 7828  */
 7829 static void airo_read_wireless_stats(struct airo_info *local)
 7830 {
 7831 	StatusRid status_rid;
 7832 	StatsRid stats_rid;
 7833 	CapabilityRid cap_rid;
 7834 	__le32 *vals = stats_rid.vals;
 7835 
 7836 	/* Get stats out of the card */
 7837 	clear_bit(JOB_WSTATS, &local->jobs);
 7838 	if (local->power.event) {
 7839 		up(&local->sem);
 7840 		return;
 7841 	}
 7842 	readCapabilityRid(local, &cap_rid, 0);
 7843 	readStatusRid(local, &status_rid, 0);
 7844 	readStatsRid(local, &stats_rid, RID_STATS, 0);
 7845 	up(&local->sem);
 7846 
 7847 	/* The status */
 7848 	local->wstats.status = le16_to_cpu(status_rid.mode);
 7849 
 7850 	/* Signal quality and co */
 7851 	if (local->rssi) {
 7852 		local->wstats.qual.level =
 7853 			airo_rssi_to_dbm(local->rssi,
 7854 					 le16_to_cpu(status_rid.sigQuality));
 7855 		/* normalizedSignalStrength appears to be a percentage */
 7856 		local->wstats.qual.qual =
 7857 			le16_to_cpu(status_rid.normalizedSignalStrength);
 7858 	} else {
 7859 		local->wstats.qual.level =
 7860 			(le16_to_cpu(status_rid.normalizedSignalStrength) + 321) / 2;
 7861 		local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid);
 7862 	}
 7863 	if (le16_to_cpu(status_rid.len) >= 124) {
 7864 		local->wstats.qual.noise = 0x100 - status_rid.noisedBm;
 7865 		local->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
 7866 	} else {
 7867 		local->wstats.qual.noise = 0;
 7868 		local->wstats.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID | IW_QUAL_DBM;
 7869 	}
 7870 
 7871 	/* Packets discarded in the wireless adapter due to wireless
 7872 	 * specific problems */
 7873 	local->wstats.discard.nwid = le32_to_cpu(vals[56]) +
 7874 				     le32_to_cpu(vals[57]) +
 7875 				     le32_to_cpu(vals[58]); /* SSID Mismatch */
 7876 	local->wstats.discard.code = le32_to_cpu(vals[6]);/* RxWepErr */
 7877 	local->wstats.discard.fragment = le32_to_cpu(vals[30]);
 7878 	local->wstats.discard.retries = le32_to_cpu(vals[10]);
 7879 	local->wstats.discard.misc = le32_to_cpu(vals[1]) +
 7880 				     le32_to_cpu(vals[32]);
 7881 	local->wstats.miss.beacon = le32_to_cpu(vals[34]);
 7882 }
 7883 
 7884 static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
 7885 {
 7886 	struct airo_info *local =  dev->ml_priv;
 7887 
 7888 	if (!test_bit(JOB_WSTATS, &local->jobs)) {
 7889 		/* Get stats out of the card if available */
 7890 		if (down_trylock(&local->sem) != 0) {
 7891 			set_bit(JOB_WSTATS, &local->jobs);
 7892 			wake_up_interruptible(&local->thr_wait);
 7893 		} else
 7894 			airo_read_wireless_stats(local);
 7895 	}
 7896 
 7897 	return &local->wstats;
 7898 }
 7899 
 7900 #ifdef CISCO_EXT
 7901 /*
 7902  * This just translates from driver IOCTL codes to the command codes to
 7903  * feed to the radio's host interface. Things can be added/deleted
 7904  * as needed.  This represents the READ side of control I/O to
 7905  * the card
 7906  */
 7907 static int readrids(struct net_device *dev, aironet_ioctl *comp) {
 7908 	unsigned short ridcode;
 7909 	unsigned char *iobuf;
 7910 	int len;
 7911 	struct airo_info *ai = dev->ml_priv;
 7912 
 7913 	if (test_bit(FLAG_FLASHING, &ai->flags))
 7914 		return -EIO;
 7915 
 7916 	switch(comp->command)
 7917 	{
 7918 	case AIROGCAP:      ridcode = RID_CAPABILITIES; break;
 7919 	case AIROGCFG:      ridcode = RID_CONFIG;
 7920 		if (test_bit(FLAG_COMMIT, &ai->flags)) {
 7921 			disable_MAC (ai, 1);
 7922 			writeConfigRid (ai, 1);
 7923 			enable_MAC(ai, 1);
 7924 		}
 7925 		break;
 7926 	case AIROGSLIST:    ridcode = RID_SSID;         break;
 7927 	case AIROGVLIST:    ridcode = RID_APLIST;       break;
 7928 	case AIROGDRVNAM:   ridcode = RID_DRVNAME;      break;
 7929 	case AIROGEHTENC:   ridcode = RID_ETHERENCAP;   break;
 7930 	case AIROGWEPKTMP:  ridcode = RID_WEP_TEMP;
 7931 		/* Only super-user can read WEP keys */
 7932 		if (!capable(CAP_NET_ADMIN))
 7933 			return -EPERM;
 7934 		break;
 7935 	case AIROGWEPKNV:   ridcode = RID_WEP_PERM;
 7936 		/* Only super-user can read WEP keys */
 7937 		if (!capable(CAP_NET_ADMIN))
 7938 			return -EPERM;
 7939 		break;
 7940 	case AIROGSTAT:     ridcode = RID_STATUS;       break;
 7941 	case AIROGSTATSD32: ridcode = RID_STATSDELTA;   break;
 7942 	case AIROGSTATSC32: ridcode = RID_STATS;        break;
 7943 	case AIROGMICSTATS:
 7944 		if (copy_to_user(comp->data, &ai->micstats,
 7945 				 min((int)comp->len,(int)sizeof(ai->micstats))))
 7946 			return -EFAULT;
 7947 		return 0;
 7948 	case AIRORRID:      ridcode = comp->ridnum;     break;
 7949 	default:
 7950 		return -EINVAL;
 7951 	}
 7952 
 7953 	if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
 7954 		return -ENOMEM;
 7955 
 7956 	PC4500_readrid(ai,ridcode,iobuf,RIDSIZE, 1);
 7957 	/* get the count of bytes in the rid  docs say 1st 2 bytes is it.
 7958 	 * then return it to the user
 7959 	 * 9/22/2000 Honor user given length
 7960 	 */
 7961 	len = comp->len;
 7962 
 7963 	if (copy_to_user(comp->data, iobuf, min(len, (int)RIDSIZE))) {
 7964 		kfree (iobuf);
 7965 		return -EFAULT;
 7966 	}
 7967 	kfree (iobuf);
 7968 	return 0;
 7969 }
 7970 
 7971 /*
 7972  * Danger Will Robinson write the rids here
 7973  */
 7974 
 7975 static int writerids(struct net_device *dev, aironet_ioctl *comp) {
 7976 	struct airo_info *ai = dev->ml_priv;
 7977 	int  ridcode;
 7978         int  enabled;
 7979 	static int (* writer)(struct airo_info *, u16 rid, const void *, int, int);
 7980 	unsigned char *iobuf;
 7981 
 7982 	/* Only super-user can write RIDs */
 7983 	if (!capable(CAP_NET_ADMIN))
 7984 		return -EPERM;
 7985 
 7986 	if (test_bit(FLAG_FLASHING, &ai->flags))
 7987 		return -EIO;
 7988 
 7989 	ridcode = 0;
 7990 	writer = do_writerid;
 7991 
 7992 	switch(comp->command)
 7993 	{
 7994 	case AIROPSIDS:     ridcode = RID_SSID;         break;
 7995 	case AIROPCAP:      ridcode = RID_CAPABILITIES; break;
 7996 	case AIROPAPLIST:   ridcode = RID_APLIST;       break;
 7997 	case AIROPCFG: ai->config.len = 0;
 7998 			    clear_bit(FLAG_COMMIT, &ai->flags);
 7999 			    ridcode = RID_CONFIG;       break;
 8000 	case AIROPWEPKEYNV: ridcode = RID_WEP_PERM;     break;
 8001 	case AIROPLEAPUSR:  ridcode = RID_LEAPUSERNAME; break;
 8002 	case AIROPLEAPPWD:  ridcode = RID_LEAPPASSWORD; break;
 8003 	case AIROPWEPKEY:   ridcode = RID_WEP_TEMP; writer = PC4500_writerid;
 8004 		break;
 8005 	case AIROPLEAPUSR+1: ridcode = 0xFF2A;          break;
 8006 	case AIROPLEAPUSR+2: ridcode = 0xFF2B;          break;
 8007 
 8008 		/* this is not really a rid but a command given to the card
 8009 		 * same with MAC off
 8010 		 */
 8011 	case AIROPMACON:
 8012 		if (enable_MAC(ai, 1) != 0)
 8013 			return -EIO;
 8014 		return 0;
 8015 
 8016 		/*
 8017 		 * Evidently this code in the airo driver does not get a symbol
 8018 		 * as disable_MAC. it's probably so short the compiler does not gen one.
 8019 		 */
 8020 	case AIROPMACOFF:
 8021 		disable_MAC(ai, 1);
 8022 		return 0;
 8023 
 8024 		/* This command merely clears the counts does not actually store any data
 8025 		 * only reads rid. But as it changes the cards state, I put it in the
 8026 		 * writerid routines.
 8027 		 */
 8028 	case AIROPSTCLR:
 8029 		if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
 8030 			return -ENOMEM;
 8031 
 8032 		PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDSIZE, 1);
 8033 
 8034 		enabled = ai->micstats.enabled;
 8035 		memset(&ai->micstats,0,sizeof(ai->micstats));
 8036 		ai->micstats.enabled = enabled;
 8037 
 8038 		if (copy_to_user(comp->data, iobuf,
 8039 				 min((int)comp->len, (int)RIDSIZE))) {
 8040 			kfree (iobuf);
 8041 			return -EFAULT;
 8042 		}
 8043 		kfree (iobuf);
 8044 		return 0;
 8045 
 8046 	default:
 8047 		return -EOPNOTSUPP;	/* Blarg! */
 8048 	}
 8049 	if(comp->len > RIDSIZE)
 8050 		return -EINVAL;
 8051 
 8052 	if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
 8053 		return -ENOMEM;
 8054 
 8055 	if (copy_from_user(iobuf,comp->data,comp->len)) {
 8056 		kfree (iobuf);
 8057 		return -EFAULT;
 8058 	}
 8059 
 8060 	if (comp->command == AIROPCFG) {
 8061 		ConfigRid *cfg = (ConfigRid *)iobuf;
 8062 
 8063 		if (test_bit(FLAG_MIC_CAPABLE, &ai->flags))
 8064 			cfg->opmode |= MODE_MIC;
 8065 
 8066 		if ((cfg->opmode & MODE_CFG_MASK) == MODE_STA_IBSS)
 8067 			set_bit (FLAG_ADHOC, &ai->flags);
 8068 		else
 8069 			clear_bit (FLAG_ADHOC, &ai->flags);
 8070 	}
 8071 
 8072 	if((*writer)(ai, ridcode, iobuf,comp->len,1)) {
 8073 		kfree (iobuf);
 8074 		return -EIO;
 8075 	}
 8076 	kfree (iobuf);
 8077 	return 0;
 8078 }
 8079 
 8080 /*****************************************************************************
 8081  * Ancillary flash / mod functions much black magic lurkes here              *
 8082  *****************************************************************************
 8083  */
 8084 
 8085 /*
 8086  * Flash command switch table
 8087  */
 8088 
 8089 static int flashcard(struct net_device *dev, aironet_ioctl *comp) {
 8090 	int z;
 8091 
 8092 	/* Only super-user can modify flash */
 8093 	if (!capable(CAP_NET_ADMIN))
 8094 		return -EPERM;
 8095 
 8096 	switch(comp->command)
 8097 	{
 8098 	case AIROFLSHRST:
 8099 		return cmdreset((struct airo_info *)dev->ml_priv);
 8100 
 8101 	case AIROFLSHSTFL:
 8102 		if (!AIRO_FLASH(dev) &&
 8103 		    (AIRO_FLASH(dev) = kmalloc(FLASHSIZE, GFP_KERNEL)) == NULL)
 8104 			return -ENOMEM;
 8105 		return setflashmode((struct airo_info *)dev->ml_priv);
 8106 
 8107 	case AIROFLSHGCHR: /* Get char from aux */
 8108 		if(comp->len != sizeof(int))
 8109 			return -EINVAL;
 8110 		if (copy_from_user(&z,comp->data,comp->len))
 8111 			return -EFAULT;
 8112 		return flashgchar((struct airo_info *)dev->ml_priv, z, 8000);
 8113 
 8114 	case AIROFLSHPCHR: /* Send char to card. */
 8115 		if(comp->len != sizeof(int))
 8116 			return -EINVAL;
 8117 		if (copy_from_user(&z,comp->data,comp->len))
 8118 			return -EFAULT;
 8119 		return flashpchar((struct airo_info *)dev->ml_priv, z, 8000);
 8120 
 8121 	case AIROFLPUTBUF: /* Send 32k to card */
 8122 		if (!AIRO_FLASH(dev))
 8123 			return -ENOMEM;
 8124 		if(comp->len > FLASHSIZE)
 8125 			return -EINVAL;
 8126 		if (copy_from_user(AIRO_FLASH(dev), comp->data, comp->len))
 8127 			return -EFAULT;
 8128 
 8129 		flashputbuf((struct airo_info *)dev->ml_priv);
 8130 		return 0;
 8131 
 8132 	case AIRORESTART:
 8133 		if (flashrestart((struct airo_info *)dev->ml_priv, dev))
 8134 			return -EIO;
 8135 		return 0;
 8136 	}
 8137 	return -EINVAL;
 8138 }
 8139 
 8140 #define FLASH_COMMAND  0x7e7e
 8141 
 8142 /*
 8143  * STEP 1)
 8144  * Disable MAC and do soft reset on
 8145  * card.
 8146  */
 8147 
 8148 static int cmdreset(struct airo_info *ai) {
 8149 	disable_MAC(ai, 1);
 8150 
 8151 	if(!waitbusy (ai)){
 8152 		airo_print_info(ai->dev->name, "Waitbusy hang before RESET");
 8153 		return -EBUSY;
 8154 	}
 8155 
 8156 	OUT4500(ai,COMMAND,CMD_SOFTRESET);
 8157 
 8158 	ssleep(1);			/* WAS 600 12/7/00 */
 8159 
 8160 	if(!waitbusy (ai)){
 8161 		airo_print_info(ai->dev->name, "Waitbusy hang AFTER RESET");
 8162 		return -EBUSY;
 8163 	}
 8164 	return 0;
 8165 }
 8166 
 8167 /* STEP 2)
 8168  * Put the card in legendary flash
 8169  * mode
 8170  */
 8171 
 8172 static int setflashmode (struct airo_info *ai) {
 8173 	set_bit (FLAG_FLASHING, &ai->flags);
 8174 
 8175 	OUT4500(ai, SWS0, FLASH_COMMAND);
 8176 	OUT4500(ai, SWS1, FLASH_COMMAND);
 8177 	if (probe) {
 8178 		OUT4500(ai, SWS0, FLASH_COMMAND);
 8179 		OUT4500(ai, COMMAND,0x10);
 8180 	} else {
 8181 		OUT4500(ai, SWS2, FLASH_COMMAND);
 8182 		OUT4500(ai, SWS3, FLASH_COMMAND);
 8183 		OUT4500(ai, COMMAND,0);
 8184 	}
 8185 	msleep(500);		/* 500ms delay */
 8186 
 8187 	if(!waitbusy(ai)) {
 8188 		clear_bit (FLAG_FLASHING, &ai->flags);
 8189 		airo_print_info(ai->dev->name, "Waitbusy hang after setflash mode");
 8190 		return -EIO;
 8191 	}
 8192 	return 0;
 8193 }
 8194 
 8195 /* Put character to SWS0 wait for dwelltime
 8196  * x 50us for  echo .
 8197  */
 8198 
 8199 static int flashpchar(struct airo_info *ai,int byte,int dwelltime) {
 8200 	int echo;
 8201 	int waittime;
 8202 
 8203 	byte |= 0x8000;
 8204 
 8205 	if(dwelltime == 0 )
 8206 		dwelltime = 200;
 8207 
 8208 	waittime=dwelltime;
 8209 
 8210 	/* Wait for busy bit d15 to go false indicating buffer empty */
 8211 	while ((IN4500 (ai, SWS0) & 0x8000) && waittime > 0) {
 8212 		udelay (50);
 8213 		waittime -= 50;
 8214 	}
 8215 
 8216 	/* timeout for busy clear wait */
 8217 	if(waittime <= 0 ){
 8218 		airo_print_info(ai->dev->name, "flash putchar busywait timeout!");
 8219 		return -EBUSY;
 8220 	}
 8221 
 8222 	/* Port is clear now write byte and wait for it to echo back */
 8223 	do {
 8224 		OUT4500(ai,SWS0,byte);
 8225 		udelay(50);
 8226 		dwelltime -= 50;
 8227 		echo = IN4500(ai,SWS1);
 8228 	} while (dwelltime >= 0 && echo != byte);
 8229 
 8230 	OUT4500(ai,SWS1,0);
 8231 
 8232 	return (echo == byte) ? 0 : -EIO;
 8233 }
 8234 
 8235 /*
 8236  * Get a character from the card matching matchbyte
 8237  * Step 3)
 8238  */
 8239 static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){
 8240 	int           rchar;
 8241 	unsigned char rbyte=0;
 8242 
 8243 	do {
 8244 		rchar = IN4500(ai,SWS1);
 8245 
 8246 		if(dwelltime && !(0x8000 & rchar)){
 8247 			dwelltime -= 10;
 8248 			mdelay(10);
 8249 			continue;
 8250 		}
 8251 		rbyte = 0xff & rchar;
 8252 
 8253 		if( (rbyte == matchbyte) && (0x8000 & rchar) ){
 8254 			OUT4500(ai,SWS1,0);
 8255 			return 0;
 8256 		}
 8257 		if( rbyte == 0x81 || rbyte == 0x82 || rbyte == 0x83 || rbyte == 0x1a || 0xffff == rchar)
 8258 			break;
 8259 		OUT4500(ai,SWS1,0);
 8260 
 8261 	}while(dwelltime > 0);
 8262 	return -EIO;
 8263 }
 8264 
 8265 /*
 8266  * Transfer 32k of firmware data from user buffer to our buffer and
 8267  * send to the card
 8268  */
 8269 
 8270 static int flashputbuf(struct airo_info *ai){
 8271 	int            nwords;
 8272 
 8273 	/* Write stuff */
 8274 	if (test_bit(FLAG_MPI,&ai->flags))
 8275 		memcpy_toio(ai->pciaux + 0x8000, ai->flash, FLASHSIZE);
 8276 	else {
 8277 		OUT4500(ai,AUXPAGE,0x100);
 8278 		OUT4500(ai,AUXOFF,0);
 8279 
 8280 		for(nwords=0;nwords != FLASHSIZE / 2;nwords++){
 8281 			OUT4500(ai,AUXDATA,ai->flash[nwords] & 0xffff);
 8282 		}
 8283 	}
 8284 	OUT4500(ai,SWS0,0x8000);
 8285 
 8286 	return 0;
 8287 }
 8288 
 8289 /*
 8290  *
 8291  */
 8292 static int flashrestart(struct airo_info *ai,struct net_device *dev){
 8293 	int    i,status;
 8294 
 8295 	ssleep(1);			/* Added 12/7/00 */
 8296 	clear_bit (FLAG_FLASHING, &ai->flags);
 8297 	if (test_bit(FLAG_MPI, &ai->flags)) {
 8298 		status = mpi_init_descriptors(ai);
 8299 		if (status != SUCCESS)
 8300 			return status;
 8301 	}
 8302 	status = setup_card(ai, dev->dev_addr, 1);
 8303 
 8304 	if (!test_bit(FLAG_MPI,&ai->flags))
 8305 		for( i = 0; i < MAX_FIDS; i++ ) {
 8306 			ai->fids[i] = transmit_allocate
 8307 				( ai, AIRO_DEF_MTU, i >= MAX_FIDS / 2 );
 8308 		}
 8309 
 8310 	ssleep(1);			/* Added 12/7/00 */
 8311 	return status;
 8312 }
 8313 #endif /* CISCO_EXT */
 8314 
 8315 /*
 8316     This program is free software; you can redistribute it and/or
 8317     modify it under the terms of the GNU General Public License
 8318     as published by the Free Software Foundation; either version 2
 8319     of the License, or (at your option) any later version.
 8320 
 8321     This program is distributed in the hope that it will be useful,
 8322     but WITHOUT ANY WARRANTY; without even the implied warranty of
 8323     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 8324     GNU General Public License for more details.
 8325 
 8326     In addition:
 8327 
 8328     Redistribution and use in source and binary forms, with or without
 8329     modification, are permitted provided that the following conditions
 8330     are met:
 8331 
 8332     1. Redistributions of source code must retain the above copyright
 8333        notice, this list of conditions and the following disclaimer.
 8334     2. Redistributions in binary form must reproduce the above copyright
 8335        notice, this list of conditions and the following disclaimer in the
 8336        documentation and/or other materials provided with the distribution.
 8337     3. The name of the author may not be used to endorse or promote
 8338        products derived from this software without specific prior written
 8339        permission.
 8340 
 8341     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 8342     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 8343     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 8344     ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 8345     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 8346     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 8347     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 8348     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 8349     STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 8350     IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 8351     POSSIBILITY OF SUCH DAMAGE.
 8352 */
 8353 
 8354 module_init(airo_init_module);
 8355 module_exit(airo_cleanup_module);
 8356 
 8357 #line 131 "/work/ldvuser/andrianov/work/current--X--drivers/net/wireless/--X--defaultlinux-4.5-rc7--X--races--X--cpachecker/linux-4.5-rc7/csd_deg_dscv/833/dscv_tempdir/dscv/ri/races/drivers/net/wireless/cisco/airo.o.c.prepared"
 8358 
 8359 int ldv_retval_20;
 8360 int ldv_retval_18;
 8361 int ldv_retval_2;
 8362 int ldv_retval_5;
 8363 int ldv_retval_0;
 8364 int ldv_ndo_init_13(void);
 8365 int ldv_retval_11;
 8366 int ldv_retval_1;
 8367 int ldv_shutdown_15(void);
 8368 int ldv_resume_early_15(void);
 8369 int ldv_retval_15;
 8370 int ldv_ndo_init_11(void);
 8371 int ldv_retval_16;
 8372 int ldv_suspend_late_15(void);
 8373 void ldv_check_final_state(void);
 8374 int ldv_retval_8;
 8375 int ldv_retval_7;
 8376 int ldv_retval_19;
 8377 int ldv_retval_14;
 8378 int ldv_ndo_init_12(void);
 8379 int ldv_retval_17;
 8380 int ldv_retval_12;
 8381 void ldv_initialize(void);
 8382 int ldv_retval_6;
 8383 int ldv_ndo_uninit_13(void);
 8384 int ldv_retval_13;
 8385 int ldv_ndo_uninit_11(void);
 8386 int ldv_retval_9;
 8387 int ldv_retval_10;
 8388 int ldv_retval_4;
 8389 int ldv_ndo_uninit_12(void);
 8390 struct iw_statistics *ldv_retval_3;
 8391 
 8392 
 8393 void ldv_file_operations_7(void){
 8394     proc_SSID_ops_group1 = ldv_undef_ptr();
 8395     proc_SSID_ops_group2 = ldv_undef_ptr();
 8396 }
 8397 
 8398 
 8399 void ldv_file_operations_6(void){
 8400     proc_BSSList_ops_group1 = ldv_undef_ptr();
 8401     proc_BSSList_ops_group2 = ldv_undef_ptr();
 8402 }
 8403 
 8404 
 8405 int evil_hack_13(void){
 8406     rtnl_lock();
 8407     return 1;
 8408 }
 8409 
 8410 
 8411 int reg_check_1(irqreturn_t (*handler)(int, void *)){
 8412     if(handler == airo_interrupt){
 8413         return 1;
 8414     }
 8415     return 0;
 8416 }
 8417 
 8418 
 8419 void ldv_pci_driver_15(void){
 8420     airo_driver_group1 = ldv_undef_ptr();
 8421 }
 8422 
 8423 
 8424 void ldv_file_operations_10(void){
 8425     proc_statsdelta_ops_group1 = ldv_undef_ptr();
 8426     proc_statsdelta_ops_group2 = ldv_undef_ptr();
 8427 }
 8428 
 8429 
 8430 int evil_hack_12(void){
 8431     rtnl_lock();
 8432     return 1;
 8433 }
 8434 
 8435 
 8436 void ldv_net_device_ops_11(void){
 8437     mpi_netdev_ops_group1 = ldv_undef_ptr();
 8438 }
 8439 
 8440 
 8441 void choose_interrupt_1(void){
 8442     switch(__VERIFIER_nondet_int()){
 8443         case 0: {
 8444             ldv_irq_1_0 = ldv_irq_1(ldv_irq_1_0, ldv_irq_line_1_0, ldv_irq_data_1_0);
 8445         }
 8446         break;
 8447         case 1: {
 8448             ldv_irq_1_0 = ldv_irq_1(ldv_irq_1_1, ldv_irq_line_1_1, ldv_irq_data_1_1);
 8449         }
 8450         break;
 8451         case 2: {
 8452             ldv_irq_1_0 = ldv_irq_1(ldv_irq_1_2, ldv_irq_line_1_2, ldv_irq_data_1_2);
 8453         }
 8454         break;
 8455         case 3: {
 8456             ldv_irq_1_0 = ldv_irq_1(ldv_irq_1_3, ldv_irq_line_1_3, ldv_irq_data_1_3);
 8457         }
 8458         break;
 8459         default: ldv_assume(0);
 8460     }
 8461     return;
 8462 }
 8463 
 8464 
 8465 int evil_hack_11(void){
 8466     rtnl_lock();
 8467     return 1;
 8468 }
 8469 
 8470 
 8471 void ldv_file_operations_9(void){
 8472     proc_stats_ops_group1 = ldv_undef_ptr();
 8473     proc_stats_ops_group2 = ldv_undef_ptr();
 8474 }
 8475 
 8476 
 8477 void ldv_file_operations_3(void){
 8478     proc_wepkey_ops_group1 = ldv_undef_ptr();
 8479     proc_wepkey_ops_group2 = ldv_undef_ptr();
 8480 }
 8481 
 8482 
 8483 void ldv_file_operations_8(void){
 8484     proc_status_ops_group1 = ldv_undef_ptr();
 8485     proc_status_ops_group2 = ldv_undef_ptr();
 8486 }
 8487 
 8488 
 8489 void disable_suitable_irq_1(int line, void * data){
 8490     if(ldv_irq_1_0 != 0 && line == ldv_irq_line_1_0){
 8491         ldv_irq_1_0 = 0;
 8492         return;
 8493     }
 8494     if(ldv_irq_1_1 != 0 && line == ldv_irq_line_1_1){
 8495         ldv_irq_1_1 = 0;
 8496         return;
 8497     }
 8498     if(ldv_irq_1_2 != 0 && line == ldv_irq_line_1_2){
 8499         ldv_irq_1_2 = 0;
 8500         return;
 8501     }
 8502     if(ldv_irq_1_3 != 0 && line == ldv_irq_line_1_3){
 8503         ldv_irq_1_3 = 0;
 8504         return;
 8505     }
 8506     return;
 8507 }
 8508 
 8509 
 8510 int ldv_irq_1(int state, int line, void *data){
 8511     irqreturn_t irq_retval;
 8512     irq_retval = __VERIFIER_nondet_int();
 8513 
 8514     if(state != 0){
 8515         switch(__VERIFIER_nondet_int()){
 8516         case 0:{
 8517             if(state == 1){
 8518                 LDV_IN_INTERRUPT=2;
 8519                 irq_retval = airo_interrupt(line, data);
 8520                 LDV_IN_INTERRUPT=1;
 8521                 return state;
 8522             }
 8523         }
 8524         break;
 8525         default: ldv_assume(0);
 8526         }
 8527     }
 8528     return state;
 8529 }
 8530 
 8531 
 8532 void activate_suitable_irq_1(int line, void * data){
 8533     if(ldv_irq_1_0 == 0){
 8534         ldv_irq_line_1_0 = line;
 8535         ldv_irq_data_1_0 = data;
 8536         ldv_irq_1_0 = 1;
 8537         return;
 8538     }
 8539     if(ldv_irq_1_1 == 0){
 8540         ldv_irq_line_1_1 = line;
 8541         ldv_irq_data_1_1 = data;
 8542         ldv_irq_1_1 = 1;
 8543         return;
 8544     }
 8545     if(ldv_irq_1_2 == 0){
 8546         ldv_irq_line_1_2 = line;
 8547         ldv_irq_data_1_2 = data;
 8548         ldv_irq_1_2 = 1;
 8549         return;
 8550     }
 8551     if(ldv_irq_1_3 == 0){
 8552         ldv_irq_line_1_3 = line;
 8553         ldv_irq_data_1_3 = data;
 8554         ldv_irq_1_3 = 1;
 8555         return;
 8556     }
 8557     return;
 8558 }
 8559 
 8560 
 8561 int evil_hack_fs_lock(void){
 8562     mutex_lock(&fs_mutex);
 8563     return 1;
 8564 }
 8565 
 8566 int __VERIFIER_nondet_int(void);
 8567 
 8568 int evil_hack_2(void){
 8569     rtnl_lock();
 8570     return 1;
 8571 }
 8572 
 8573 
 8574 void ldv_file_operations_5(void){
 8575     proc_APList_ops_group1 = ldv_undef_ptr();
 8576     proc_APList_ops_group2 = ldv_undef_ptr();
 8577 }
 8578 
 8579 
 8580 void ldv_net_device_ops_13(void){
 8581     airo11_netdev_ops_group1 = ldv_undef_ptr();
 8582 }
 8583 
 8584 
 8585 void ldv_net_device_ops_12(void){
 8586     airo_netdev_ops_group1 = ldv_undef_ptr();
 8587 }
 8588 
 8589 
 8590 int evil_hack_ar_lock(void){
 8591     mutex_lock(&ar_mutex);
 8592     return 1;
 8593 }
 8594 
 8595 
 8596 void ldv_file_operations_4(void){
 8597     proc_config_ops_group1 = ldv_undef_ptr();
 8598     proc_config_ops_group2 = ldv_undef_ptr();
 8599 }
 8600 
 8601 
 8602 /* DEG-ENVIRONMENT-BEGIN */
 8603 extern void ldv_main_exported_6(void);
 8604 extern void ldv_main_exported_11(void);
 8605 extern void ldv_main_exported_3(void);
 8606 extern void ldv_main_exported_7(void);
 8607 extern void ldv_main_exported_9(void);
 8608 extern void ldv_main_exported_12(void);
 8609 extern void ldv_main_exported_2(void);
 8610 extern void ldv_main_exported_15(void);
 8611 extern void ldv_main_exported_14(void);
 8612 extern void ldv_main_exported_8(void);
 8613 extern void ldv_main_exported_4(void);
 8614 extern void ldv_main_exported_0(void);
 8615 extern void ldv_main_exported_13(void);
 8616 extern void ldv_main_exported_10(void);
 8617 extern void ldv_main_exported_5(void);
 8618 
 8619 //********************* LDV MAIN *********************
 8620 //main
 8621 void entry_point(void){
 8622  ldv_initialize();
 8623  //args for callbacks
 8624  struct sk_buff *ldvarg1;
 8625  struct ifreq *ldvarg4;
 8626  int ldvarg3;
 8627  void *ldvarg0;
 8628  int ldvarg2;
 8629  size_t ldvarg11;
 8630  loff_t *ldvarg7;
 8631  char const *ldvarg12;
 8632  int ldvarg5;
 8633  loff_t ldvarg6;
 8634  size_t ldvarg8;
 8635  loff_t *ldvarg10;
 8636  char *ldvarg9;
 8637  struct ifreq *ldvarg17;
 8638  struct sk_buff *ldvarg14;
 8639  void *ldvarg13;
 8640  int ldvarg16;
 8641  int ldvarg15;
 8642  size_t ldvarg24;
 8643  int ldvarg18;
 8644  loff_t *ldvarg20;
 8645  loff_t *ldvarg23;
 8646  size_t ldvarg21;
 8647  char const *ldvarg25;
 8648  char *ldvarg22;
 8649  loff_t ldvarg19;
 8650  loff_t ldvarg27;
 8651  int ldvarg26;
 8652  size_t ldvarg32;
 8653  loff_t *ldvarg31;
 8654  char const *ldvarg33;
 8655  char *ldvarg30;
 8656  size_t ldvarg29;
 8657  loff_t *ldvarg28;
 8658  size_t ldvarg37;
 8659  loff_t ldvarg35;
 8660  loff_t *ldvarg36;
 8661  char *ldvarg38;
 8662  int ldvarg34;
 8663  void *ldvarg39;
 8664  int ldvarg41;
 8665  struct ifreq *ldvarg43;
 8666  int ldvarg42;
 8667  struct sk_buff *ldvarg40;
 8668  unsigned char *ldvarg45;
 8669  struct sk_buff const *ldvarg44;
 8670  struct pci_device_id const *ldvarg47;
 8671  pm_message_t ldvarg46;
 8672  int ldvarg48;
 8673  size_t ldvarg51;
 8674  char *ldvarg52;
 8675  loff_t ldvarg49;
 8676  loff_t *ldvarg50;
 8677  char const *ldvarg60;
 8678  size_t ldvarg59;
 8679  size_t ldvarg56;
 8680  char *ldvarg57;
 8681  loff_t ldvarg54;
 8682  loff_t *ldvarg58;
 8683  int ldvarg53;
 8684  loff_t *ldvarg55;
 8685  char *ldvarg65;
 8686  loff_t *ldvarg63;
 8687  int ldvarg61;
 8688  size_t ldvarg64;
 8689  loff_t ldvarg62;
 8690  char const *ldvarg73;
 8691  char *ldvarg70;
 8692  loff_t ldvarg67;
 8693  loff_t *ldvarg71;
 8694  loff_t *ldvarg68;
 8695  size_t ldvarg72;
 8696  size_t ldvarg69;
 8697  int ldvarg66;
 8698  //initialization of machine states
 8699  ldv_state_variable_11=0;
 8700  ldv_state_variable_7=0;
 8701  ldv_state_variable_2=0;
 8702 
 8703  ldv_state_variable_1=1;
 8704  ref_cnt=0;
 8705  ldv_state_variable_0=1;
 8706  ldv_state_variable_13=0;
 8707  ldv_state_variable_6=0;
 8708  ldv_state_variable_3=0;
 8709  ldv_state_variable_9=0;
 8710  ldv_state_variable_12=0;
 8711  ldv_state_variable_14=0;
 8712  ldv_state_variable_15=0;
 8713  ldv_state_variable_8=0;
 8714  ldv_state_variable_4=0;
 8715  ldv_state_variable_10=0;
 8716  ldv_state_variable_5=0;
 8717  while(1){
 8718   switch(__VERIFIER_nondet_int()){
 8719   case 0:{
 8720    /*DEG-struct: handlers from structure mpi_netdev_ops*/
 8721    /*DEG-CHECK: checking registration of mpi_netdev_ops structure*/
 8722    if(ldv_state_variable_11 != 0){
 8723     switch(__VERIFIER_nondet_int()){
 8724     case 0:{
 8725      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 8726      if(ldv_state_variable_11 == 3 && evil_hack_11()){
 8727       /*DEG-CALL: handler ndo_stop from mpi_netdev_ops*/
 8728       (& airo_close)(mpi_netdev_ops_group1);
 8729       ldv_state_variable_11 = 2;
 8730       rtnl_unlock();
 8731      }
 8732     }
 8733     break;
 8734     case 1:{
 8735      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 8736      if(ldv_state_variable_11 == 1){
 8737       /*DEG-CALL: handler ndo_set_rx_mode from mpi_netdev_ops*/
 8738       (& airo_set_multicast_list)(mpi_netdev_ops_group1);
 8739       /*DEG-postcall: default*/
 8740       ldv_state_variable_11 = 1;
 8741      }
 8742      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 8743      if(ldv_state_variable_11 == 3){
 8744       /*DEG-CALL: handler ndo_set_rx_mode from mpi_netdev_ops*/
 8745       (& airo_set_multicast_list)(mpi_netdev_ops_group1);
 8746       /*DEG-postcall: default*/
 8747       ldv_state_variable_11 = 3;
 8748      }
 8749      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 8750      if(ldv_state_variable_11 == 2){
 8751       /*DEG-CALL: handler ndo_set_rx_mode from mpi_netdev_ops*/
 8752       (& airo_set_multicast_list)(mpi_netdev_ops_group1);
 8753       /*DEG-postcall: default*/
 8754       ldv_state_variable_11 = 2;
 8755      }
 8756     }
 8757     break;
 8758     case 2:{
 8759      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 8760      if(ldv_state_variable_11 == 1){
 8761       /*DEG-CALL: handler ndo_validate_addr from mpi_netdev_ops*/
 8762       (& eth_validate_addr)(mpi_netdev_ops_group1);
 8763       /*DEG-postcall: default*/
 8764       ldv_state_variable_11 = 1;
 8765      }
 8766      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 8767      if(ldv_state_variable_11 == 3){
 8768       /*DEG-CALL: handler ndo_validate_addr from mpi_netdev_ops*/
 8769       (& eth_validate_addr)(mpi_netdev_ops_group1);
 8770       /*DEG-postcall: default*/
 8771       ldv_state_variable_11 = 3;
 8772      }
 8773      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 8774      if(ldv_state_variable_11 == 2){
 8775       /*DEG-CALL: handler ndo_validate_addr from mpi_netdev_ops*/
 8776       (& eth_validate_addr)(mpi_netdev_ops_group1);
 8777       /*DEG-postcall: default*/
 8778       ldv_state_variable_11 = 2;
 8779      }
 8780     }
 8781     break;
 8782     case 3:{
 8783      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 8784      if(ldv_state_variable_11 == 1 && evil_hack_11()){
 8785       /*DEG-CALL: handler ndo_do_ioctl from mpi_netdev_ops*/
 8786       (& airo_ioctl)(mpi_netdev_ops_group1,ldvarg4,ldvarg3);
 8787       ldv_state_variable_11 = 1;
 8788       rtnl_unlock();
 8789      }
 8790      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 8791      if(ldv_state_variable_11 == 3 && evil_hack_11()){
 8792       /*DEG-CALL: handler ndo_do_ioctl from mpi_netdev_ops*/
 8793       (& airo_ioctl)(mpi_netdev_ops_group1,ldvarg4,ldvarg3);
 8794       ldv_state_variable_11 = 3;
 8795       rtnl_unlock();
 8796      }
 8797      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 8798      if(ldv_state_variable_11 == 2 && evil_hack_11()){
 8799       /*DEG-CALL: handler ndo_do_ioctl from mpi_netdev_ops*/
 8800       (& airo_ioctl)(mpi_netdev_ops_group1,ldvarg4,ldvarg3);
 8801       ldv_state_variable_11 = 2;
 8802       rtnl_unlock();
 8803      }
 8804     }
 8805     break;
 8806     case 4:{
 8807      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 8808      if(ldv_state_variable_11 == 1){
 8809       /*DEG-CALL: handler ndo_get_stats from mpi_netdev_ops*/
 8810       (& airo_get_stats)(mpi_netdev_ops_group1);
 8811       /*DEG-postcall: default*/
 8812       ldv_state_variable_11 = 1;
 8813      }
 8814      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 8815      if(ldv_state_variable_11 == 3){
 8816       /*DEG-CALL: handler ndo_get_stats from mpi_netdev_ops*/
 8817       (& airo_get_stats)(mpi_netdev_ops_group1);
 8818       /*DEG-postcall: default*/
 8819       ldv_state_variable_11 = 3;
 8820      }
 8821      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 8822      if(ldv_state_variable_11 == 2){
 8823       /*DEG-CALL: handler ndo_get_stats from mpi_netdev_ops*/
 8824       (& airo_get_stats)(mpi_netdev_ops_group1);
 8825       /*DEG-postcall: default*/
 8826       ldv_state_variable_11 = 2;
 8827      }
 8828     }
 8829     break;
 8830     case 5:{
 8831      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 8832      if(ldv_state_variable_11 == 3){
 8833       /*DEG-CALL: handler ndo_change_mtu from mpi_netdev_ops*/
 8834       (& airo_change_mtu)(mpi_netdev_ops_group1,ldvarg2);
 8835       /*DEG-postcall: default*/
 8836       ldv_state_variable_11 = 3;
 8837      }
 8838      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 8839      if(ldv_state_variable_11 == 2){
 8840       /*DEG-CALL: handler ndo_change_mtu from mpi_netdev_ops*/
 8841       (& airo_change_mtu)(mpi_netdev_ops_group1,ldvarg2);
 8842       /*DEG-postcall: default*/
 8843       ldv_state_variable_11 = 2;
 8844      }
 8845     }
 8846     break;
 8847     case 6:{
 8848      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 8849      if(ldv_state_variable_11 == 2 && evil_hack_11()){
 8850       /*DEG-CALL: handler ndo_open from mpi_netdev_ops*/
 8851       ldv_retval_1=(& airo_open)(mpi_netdev_ops_group1);
 8852       if(ldv_retval_1==0){
 8853       ldv_state_variable_11 = 3;
 8854       }
 8855      }
 8856     }
 8857     break;
 8858     case 7:{
 8859      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 8860      if(ldv_state_variable_11 == 3){
 8861       /*DEG-CALL: handler ndo_start_xmit from mpi_netdev_ops*/
 8862       (& mpi_start_xmit)(ldvarg1,mpi_netdev_ops_group1);
 8863       /*DEG-postcall: default*/
 8864       ldv_state_variable_11 = 3;
 8865      }
 8866     }
 8867     break;
 8868     case 8:{
 8869      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 8870      if(ldv_state_variable_11 == 1){
 8871       /*DEG-CALL: handler ndo_set_mac_address from mpi_netdev_ops*/
 8872       (& airo_set_mac_address)(mpi_netdev_ops_group1,ldvarg0);
 8873       /*DEG-postcall: default*/
 8874       ldv_state_variable_11 = 1;
 8875      }
 8876      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 8877      if(ldv_state_variable_11 == 3){
 8878       /*DEG-CALL: handler ndo_set_mac_address from mpi_netdev_ops*/
 8879       (& airo_set_mac_address)(mpi_netdev_ops_group1,ldvarg0);
 8880       /*DEG-postcall: default*/
 8881       ldv_state_variable_11 = 3;
 8882      }
 8883      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 8884      if(ldv_state_variable_11 == 2){
 8885       /*DEG-CALL: handler ndo_set_mac_address from mpi_netdev_ops*/
 8886       (& airo_set_mac_address)(mpi_netdev_ops_group1,ldvarg0);
 8887       /*DEG-postcall: default*/
 8888       ldv_state_variable_11 = 2;
 8889      }
 8890     }
 8891     break;
 8892     case 9:{
 8893      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 8894      if(ldv_state_variable_11 == 1){
 8895       /*DEG-CALL: handler ndo_init from mpi_netdev_ops*/
 8896       ldv_retval_0=ldv_ndo_init_11();
 8897       if(ldv_retval_0==0){
 8898       ldv_state_variable_11 = 2;
 8899       ref_cnt++;
 8900       }
 8901      }
 8902     }
 8903     break;
 8904     case 10:{
 8905      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 8906      if(ldv_state_variable_11 == 2 && evil_hack_11()){
 8907       /*DEG-CALL: handler ndo_uninit from mpi_netdev_ops*/
 8908       ldv_ndo_uninit_11();
 8909       ldv_state_variable_11 = 1;
 8910       ref_cnt--;
 8911       rtnl_unlock();
 8912      }
 8913     }
 8914     break;
 8915     default: ldv_assume(0);
 8916     }
 8917    }
 8918   }
 8919   break;
 8920   case 1:{
 8921    /*DEG-struct: handlers from structure proc_SSID_ops*/
 8922    /*DEG-CHECK: checking registration of proc_SSID_ops structure*/
 8923    if(ldv_state_variable_7 != 0){
 8924     switch(__VERIFIER_nondet_int()){
 8925     case 0:{
 8926      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 8927      if(ldv_state_variable_7 == 1){
 8928       /*DEG-CALL: handler write from proc_SSID_ops*/
 8929       (& proc_write)(proc_SSID_ops_group2,ldvarg12,ldvarg11,ldvarg10);
 8930       /*DEG-postcall: default*/
 8931       ldv_state_variable_7 = 1;
 8932      }
 8933      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 8934      if(ldv_state_variable_7 == 2){
 8935       /*DEG-CALL: handler write from proc_SSID_ops*/
 8936       (& proc_write)(proc_SSID_ops_group2,ldvarg12,ldvarg11,ldvarg10);
 8937       /*DEG-postcall: default*/
 8938       ldv_state_variable_7 = 2;
 8939      }
 8940     }
 8941     break;
 8942     case 1:{
 8943      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 8944      if(ldv_state_variable_7 == 2){
 8945       /*DEG-CALL: handler read from proc_SSID_ops*/
 8946       (& proc_read)(proc_SSID_ops_group2,ldvarg9,ldvarg8,ldvarg7);
 8947       /*DEG-postcall: default*/
 8948       ldv_state_variable_7 = 2;
 8949      }
 8950     }
 8951     break;
 8952     case 2:{
 8953      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 8954      if(ldv_state_variable_7 == 1){
 8955       /*DEG-CALL: handler open from proc_SSID_ops*/
 8956       ldv_retval_2=(& proc_SSID_open)(proc_SSID_ops_group1,proc_SSID_ops_group2);
 8957       if(ldv_retval_2==0){
 8958       ldv_state_variable_7 = 2;
 8959       ref_cnt++;
 8960       }
 8961      }
 8962     }
 8963     break;
 8964     case 3:{
 8965      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 8966      if(ldv_state_variable_7 == 2){
 8967       /*DEG-CALL: handler release from proc_SSID_ops*/
 8968       (& proc_close)(proc_SSID_ops_group1,proc_SSID_ops_group2);
 8969       ldv_state_variable_7 = 1;
 8970       ref_cnt--;
 8971      }
 8972     }
 8973     break;
 8974     case 4:{
 8975      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 8976      if(ldv_state_variable_7 == 2){
 8977       /*DEG-CALL: handler llseek from proc_SSID_ops*/
 8978       (& default_llseek)(proc_SSID_ops_group2,ldvarg6,ldvarg5);
 8979       /*DEG-postcall: default*/
 8980       ldv_state_variable_7 = 2;
 8981      }
 8982     }
 8983     break;
 8984     default: ldv_assume(0);
 8985     }
 8986    }
 8987   }
 8988   break;
 8989   case 2:{
 8990    /*DEG-struct: handlers from structure airo_handler_def*/
 8991    /*DEG-CHECK: checking registration of airo_handler_def structure*/
 8992    if(ldv_state_variable_2 != 0){
 8993     switch(__VERIFIER_nondet_int()){
 8994     case 0:{
 8995      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 8996      if(ldv_state_variable_2 == 1 && evil_hack_2()){
 8997       /*DEG-CALL: handler get_wireless_stats from airo_handler_def*/
 8998       ldv_retval_3=(& airo_get_wireless_stats)(airo_handler_def_group1);
 8999       if(ldv_retval_3==0){
 9000       ldv_state_variable_2 = 1;
 9001       rtnl_unlock();
 9002       }
 9003      }
 9004     }
 9005     break;
 9006     default: ldv_assume(0);
 9007     }
 9008    }
 9009   }
 9010   break;
 9011   case 3:{
 9012    /*DEG-struct: handlers from structure ldv_request_irq_0*/
 9013    /*DEG-CHECK: checking registration of ldv_request_irq_0 structure*/
 9014    if(ldv_state_variable_1 != 0){
 9015     choose_interrupt_1();
 9016    }
 9017   }
 9018   break;
 9019   case 4:{
 9020    /*DEG-struct: handlers from structure module*/
 9021    /*DEG-CHECK: checking registration of module structure*/
 9022    if(ldv_state_variable_0 != 0){
 9023     switch(__VERIFIER_nondet_int()){
 9024     case 0:{
 9025      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 9026      if(ldv_state_variable_0 == 3 && ref_cnt==0){
 9027       /*DEG-CALL: handler module_exit from module*/
 9028       airo_cleanup_module();
 9029       ldv_state_variable_0 = 2;
 9030       goto ldv_final;
 9031      }
 9032     }
 9033     break;
 9034     case 1:{
 9035      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9036      if(ldv_state_variable_0 == 1){
 9037       /*DEG-CALL: handler module_init from module*/
 9038       ldv_retval_4=airo_init_module();
 9039       /*DEG-postcall: if success*/
 9040       if(ldv_retval_4==0){
 9041       ldv_state_variable_0 = 3;
 9042       ldv_state_variable_5 = 1;
 9043               ldv_file_operations_5();
 9044           ldv_state_variable_10 = 1;
 9045               ldv_file_operations_10();
 9046           ldv_state_variable_4 = 1;
 9047               ldv_file_operations_4();
 9048           ldv_state_variable_8 = 1;
 9049               ldv_file_operations_8();
 9050           ldv_state_variable_14 = 1;
 9051       ldv_state_variable_9 = 1;
 9052               ldv_file_operations_9();
 9053           ldv_state_variable_7 = 1;
 9054               ldv_file_operations_7();
 9055           ldv_state_variable_3 = 1;
 9056               ldv_file_operations_3();
 9057           ldv_state_variable_6 = 1;
 9058               ldv_file_operations_6();
 9059       }
 9060       if(ldv_retval_4!=0){
 9061       ldv_state_variable_0 = 2;
 9062       goto ldv_final;
 9063       }
 9064      }
 9065     }
 9066     break;
 9067     default: ldv_assume(0);
 9068     }
 9069    }
 9070   }
 9071   break;
 9072   case 5:{
 9073    /*DEG-struct: handlers from structure airo11_netdev_ops*/
 9074    /*DEG-CHECK: checking registration of airo11_netdev_ops structure*/
 9075    if(ldv_state_variable_13 != 0){
 9076     switch(__VERIFIER_nondet_int()){
 9077     case 0:{
 9078      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 9079      if(ldv_state_variable_13 == 3 && evil_hack_13()){
 9080       /*DEG-CALL: handler ndo_stop from airo11_netdev_ops*/
 9081       (& airo_close)(airo11_netdev_ops_group1);
 9082       ldv_state_variable_13 = 2;
 9083       rtnl_unlock();
 9084      }
 9085     }
 9086     break;
 9087     case 1:{
 9088      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9089      if(ldv_state_variable_13 == 1 && evil_hack_13()){
 9090       /*DEG-CALL: handler ndo_do_ioctl from airo11_netdev_ops*/
 9091       (& airo_ioctl)(airo11_netdev_ops_group1,ldvarg17,ldvarg16);
 9092       ldv_state_variable_13 = 1;
 9093       rtnl_unlock();
 9094      }
 9095      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 9096      if(ldv_state_variable_13 == 3 && evil_hack_13()){
 9097       /*DEG-CALL: handler ndo_do_ioctl from airo11_netdev_ops*/
 9098       (& airo_ioctl)(airo11_netdev_ops_group1,ldvarg17,ldvarg16);
 9099       ldv_state_variable_13 = 3;
 9100       rtnl_unlock();
 9101      }
 9102      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9103      if(ldv_state_variable_13 == 2 && evil_hack_13()){
 9104       /*DEG-CALL: handler ndo_do_ioctl from airo11_netdev_ops*/
 9105       (& airo_ioctl)(airo11_netdev_ops_group1,ldvarg17,ldvarg16);
 9106       ldv_state_variable_13 = 2;
 9107       rtnl_unlock();
 9108      }
 9109     }
 9110     break;
 9111     case 2:{
 9112      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 9113      if(ldv_state_variable_13 == 3){
 9114       /*DEG-CALL: handler ndo_change_mtu from airo11_netdev_ops*/
 9115       (& airo_change_mtu)(airo11_netdev_ops_group1,ldvarg15);
 9116       /*DEG-postcall: default*/
 9117       ldv_state_variable_13 = 3;
 9118      }
 9119      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9120      if(ldv_state_variable_13 == 2){
 9121       /*DEG-CALL: handler ndo_change_mtu from airo11_netdev_ops*/
 9122       (& airo_change_mtu)(airo11_netdev_ops_group1,ldvarg15);
 9123       /*DEG-postcall: default*/
 9124       ldv_state_variable_13 = 2;
 9125      }
 9126     }
 9127     break;
 9128     case 3:{
 9129      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9130      if(ldv_state_variable_13 == 2 && evil_hack_13()){
 9131       /*DEG-CALL: handler ndo_open from airo11_netdev_ops*/
 9132       ldv_retval_6=(& airo_open)(airo11_netdev_ops_group1);
 9133       if(ldv_retval_6==0){
 9134       ldv_state_variable_13 = 3;
 9135       }
 9136      }
 9137     }
 9138     break;
 9139     case 4:{
 9140      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 9141      if(ldv_state_variable_13 == 3){
 9142       /*DEG-CALL: handler ndo_start_xmit from airo11_netdev_ops*/
 9143       (& airo_start_xmit11)(ldvarg14,airo11_netdev_ops_group1);
 9144       /*DEG-postcall: default*/
 9145       ldv_state_variable_13 = 3;
 9146      }
 9147     }
 9148     break;
 9149     case 5:{
 9150      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9151      if(ldv_state_variable_13 == 1){
 9152       /*DEG-CALL: handler ndo_set_mac_address from airo11_netdev_ops*/
 9153       (& airo_set_mac_address)(airo11_netdev_ops_group1,ldvarg13);
 9154       /*DEG-postcall: default*/
 9155       ldv_state_variable_13 = 1;
 9156      }
 9157      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 9158      if(ldv_state_variable_13 == 3){
 9159       /*DEG-CALL: handler ndo_set_mac_address from airo11_netdev_ops*/
 9160       (& airo_set_mac_address)(airo11_netdev_ops_group1,ldvarg13);
 9161       /*DEG-postcall: default*/
 9162       ldv_state_variable_13 = 3;
 9163      }
 9164      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9165      if(ldv_state_variable_13 == 2){
 9166       /*DEG-CALL: handler ndo_set_mac_address from airo11_netdev_ops*/
 9167       (& airo_set_mac_address)(airo11_netdev_ops_group1,ldvarg13);
 9168       /*DEG-postcall: default*/
 9169       ldv_state_variable_13 = 2;
 9170      }
 9171     }
 9172     break;
 9173     case 6:{
 9174      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9175      if(ldv_state_variable_13 == 1){
 9176       /*DEG-CALL: handler ndo_get_stats from airo11_netdev_ops*/
 9177       (& airo_get_stats)(airo11_netdev_ops_group1);
 9178       /*DEG-postcall: default*/
 9179       ldv_state_variable_13 = 1;
 9180      }
 9181      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 9182      if(ldv_state_variable_13 == 3){
 9183       /*DEG-CALL: handler ndo_get_stats from airo11_netdev_ops*/
 9184       (& airo_get_stats)(airo11_netdev_ops_group1);
 9185       /*DEG-postcall: default*/
 9186       ldv_state_variable_13 = 3;
 9187      }
 9188      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9189      if(ldv_state_variable_13 == 2){
 9190       /*DEG-CALL: handler ndo_get_stats from airo11_netdev_ops*/
 9191       (& airo_get_stats)(airo11_netdev_ops_group1);
 9192       /*DEG-postcall: default*/
 9193       ldv_state_variable_13 = 2;
 9194      }
 9195     }
 9196     break;
 9197     case 7:{
 9198      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9199      if(ldv_state_variable_13 == 1){
 9200       /*DEG-CALL: handler ndo_init from airo11_netdev_ops*/
 9201       ldv_retval_5=ldv_ndo_init_13();
 9202       if(ldv_retval_5==0){
 9203       ldv_state_variable_13 = 2;
 9204       ref_cnt++;
 9205       }
 9206      }
 9207     }
 9208     break;
 9209     case 8:{
 9210      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9211      if(ldv_state_variable_13 == 2 && evil_hack_13()){
 9212       /*DEG-CALL: handler ndo_uninit from airo11_netdev_ops*/
 9213       ldv_ndo_uninit_13();
 9214       ldv_state_variable_13 = 1;
 9215       ref_cnt--;
 9216       rtnl_unlock();
 9217      }
 9218     }
 9219     break;
 9220     default: ldv_assume(0);
 9221     }
 9222    }
 9223   }
 9224   break;
 9225   case 6:{
 9226    /*DEG-struct: handlers from structure proc_BSSList_ops*/
 9227    /*DEG-CHECK: checking registration of proc_BSSList_ops structure*/
 9228    if(ldv_state_variable_6 != 0){
 9229     switch(__VERIFIER_nondet_int()){
 9230     case 0:{
 9231      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9232      if(ldv_state_variable_6 == 1){
 9233       /*DEG-CALL: handler write from proc_BSSList_ops*/
 9234       (& proc_write)(proc_BSSList_ops_group2,ldvarg25,ldvarg24,ldvarg23);
 9235       /*DEG-postcall: default*/
 9236       ldv_state_variable_6 = 1;
 9237      }
 9238      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9239      if(ldv_state_variable_6 == 2){
 9240       /*DEG-CALL: handler write from proc_BSSList_ops*/
 9241       (& proc_write)(proc_BSSList_ops_group2,ldvarg25,ldvarg24,ldvarg23);
 9242       /*DEG-postcall: default*/
 9243       ldv_state_variable_6 = 2;
 9244      }
 9245     }
 9246     break;
 9247     case 1:{
 9248      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9249      if(ldv_state_variable_6 == 2){
 9250       /*DEG-CALL: handler read from proc_BSSList_ops*/
 9251       (& proc_read)(proc_BSSList_ops_group2,ldvarg22,ldvarg21,ldvarg20);
 9252       /*DEG-postcall: default*/
 9253       ldv_state_variable_6 = 2;
 9254      }
 9255     }
 9256     break;
 9257     case 2:{
 9258      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9259      if(ldv_state_variable_6 == 1){
 9260       /*DEG-CALL: handler open from proc_BSSList_ops*/
 9261       ldv_retval_7=(& proc_BSSList_open)(proc_BSSList_ops_group1,proc_BSSList_ops_group2);
 9262       if(ldv_retval_7==0){
 9263       ldv_state_variable_6 = 2;
 9264       ref_cnt++;
 9265       }
 9266      }
 9267     }
 9268     break;
 9269     case 3:{
 9270      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9271      if(ldv_state_variable_6 == 2){
 9272       /*DEG-CALL: handler release from proc_BSSList_ops*/
 9273       (& proc_close)(proc_BSSList_ops_group1,proc_BSSList_ops_group2);
 9274       ldv_state_variable_6 = 1;
 9275       ref_cnt--;
 9276      }
 9277     }
 9278     break;
 9279     case 4:{
 9280      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9281      if(ldv_state_variable_6 == 2){
 9282       /*DEG-CALL: handler llseek from proc_BSSList_ops*/
 9283       (& default_llseek)(proc_BSSList_ops_group2,ldvarg19,ldvarg18);
 9284       /*DEG-postcall: default*/
 9285       ldv_state_variable_6 = 2;
 9286      }
 9287     }
 9288     break;
 9289     default: ldv_assume(0);
 9290     }
 9291    }
 9292   }
 9293   break;
 9294   case 7:{
 9295    /*DEG-struct: handlers from structure proc_wepkey_ops*/
 9296    /*DEG-CHECK: checking registration of proc_wepkey_ops structure*/
 9297    if(ldv_state_variable_3 != 0){
 9298     switch(__VERIFIER_nondet_int()){
 9299     case 0:{
 9300      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9301      if(ldv_state_variable_3 == 1){
 9302       /*DEG-CALL: handler write from proc_wepkey_ops*/
 9303       (& proc_write)(proc_wepkey_ops_group2,ldvarg33,ldvarg32,ldvarg31);
 9304       /*DEG-postcall: default*/
 9305       ldv_state_variable_3 = 1;
 9306      }
 9307      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9308      if(ldv_state_variable_3 == 2){
 9309       /*DEG-CALL: handler write from proc_wepkey_ops*/
 9310       (& proc_write)(proc_wepkey_ops_group2,ldvarg33,ldvarg32,ldvarg31);
 9311       /*DEG-postcall: default*/
 9312       ldv_state_variable_3 = 2;
 9313      }
 9314     }
 9315     break;
 9316     case 1:{
 9317      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9318      if(ldv_state_variable_3 == 2){
 9319       /*DEG-CALL: handler read from proc_wepkey_ops*/
 9320       (& proc_read)(proc_wepkey_ops_group2,ldvarg30,ldvarg29,ldvarg28);
 9321       /*DEG-postcall: default*/
 9322       ldv_state_variable_3 = 2;
 9323      }
 9324     }
 9325     break;
 9326     case 2:{
 9327      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9328      if(ldv_state_variable_3 == 1){
 9329       /*DEG-CALL: handler open from proc_wepkey_ops*/
 9330       ldv_retval_8=(& proc_wepkey_open)(proc_wepkey_ops_group1,proc_wepkey_ops_group2);
 9331       if(ldv_retval_8==0){
 9332       ldv_state_variable_3 = 2;
 9333       ref_cnt++;
 9334       }
 9335      }
 9336     }
 9337     break;
 9338     case 3:{
 9339      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9340      if(ldv_state_variable_3 == 2){
 9341       /*DEG-CALL: handler release from proc_wepkey_ops*/
 9342       (& proc_close)(proc_wepkey_ops_group1,proc_wepkey_ops_group2);
 9343       ldv_state_variable_3 = 1;
 9344       ref_cnt--;
 9345      }
 9346     }
 9347     break;
 9348     case 4:{
 9349      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9350      if(ldv_state_variable_3 == 2){
 9351       /*DEG-CALL: handler llseek from proc_wepkey_ops*/
 9352       (& default_llseek)(proc_wepkey_ops_group2,ldvarg27,ldvarg26);
 9353       /*DEG-postcall: default*/
 9354       ldv_state_variable_3 = 2;
 9355      }
 9356     }
 9357     break;
 9358     default: ldv_assume(0);
 9359     }
 9360    }
 9361   }
 9362   break;
 9363   case 8:{
 9364    /*DEG-struct: handlers from structure proc_stats_ops*/
 9365    /*DEG-CHECK: checking registration of proc_stats_ops structure*/
 9366    if(ldv_state_variable_9 != 0){
 9367     switch(__VERIFIER_nondet_int()){
 9368     case 0:{
 9369      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9370      if(ldv_state_variable_9 == 2){
 9371       /*DEG-CALL: handler read from proc_stats_ops*/
 9372       (& proc_read)(proc_stats_ops_group2,ldvarg38,ldvarg37,ldvarg36);
 9373       /*DEG-postcall: default*/
 9374       ldv_state_variable_9 = 2;
 9375      }
 9376     }
 9377     break;
 9378     case 1:{
 9379      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9380      if(ldv_state_variable_9 == 1){
 9381       /*DEG-CALL: handler open from proc_stats_ops*/
 9382       ldv_retval_9=(& proc_stats_open)(proc_stats_ops_group1,proc_stats_ops_group2);
 9383       if(ldv_retval_9==0){
 9384       ldv_state_variable_9 = 2;
 9385       ref_cnt++;
 9386       }
 9387      }
 9388     }
 9389     break;
 9390     case 2:{
 9391      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9392      if(ldv_state_variable_9 == 2){
 9393       /*DEG-CALL: handler release from proc_stats_ops*/
 9394       (& proc_close)(proc_stats_ops_group1,proc_stats_ops_group2);
 9395       ldv_state_variable_9 = 1;
 9396       ref_cnt--;
 9397      }
 9398     }
 9399     break;
 9400     case 3:{
 9401      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9402      if(ldv_state_variable_9 == 2){
 9403       /*DEG-CALL: handler llseek from proc_stats_ops*/
 9404       (& default_llseek)(proc_stats_ops_group2,ldvarg35,ldvarg34);
 9405       /*DEG-postcall: default*/
 9406       ldv_state_variable_9 = 2;
 9407      }
 9408     }
 9409     break;
 9410     default: ldv_assume(0);
 9411     }
 9412    }
 9413   }
 9414   break;
 9415   case 9:{
 9416    /*DEG-struct: handlers from structure airo_netdev_ops*/
 9417    /*DEG-CHECK: checking registration of airo_netdev_ops structure*/
 9418    if(ldv_state_variable_12 != 0){
 9419     switch(__VERIFIER_nondet_int()){
 9420     case 0:{
 9421      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9422      if(ldv_state_variable_12 == 1){
 9423       /*DEG-CALL: handler ndo_set_rx_mode from airo_netdev_ops*/
 9424       (& airo_set_multicast_list)(airo_netdev_ops_group1);
 9425       /*DEG-postcall: default*/
 9426       ldv_state_variable_12 = 1;
 9427      }
 9428      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 9429      if(ldv_state_variable_12 == 3){
 9430       /*DEG-CALL: handler ndo_set_rx_mode from airo_netdev_ops*/
 9431       (& airo_set_multicast_list)(airo_netdev_ops_group1);
 9432       /*DEG-postcall: default*/
 9433       ldv_state_variable_12 = 3;
 9434      }
 9435      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9436      if(ldv_state_variable_12 == 2){
 9437       /*DEG-CALL: handler ndo_set_rx_mode from airo_netdev_ops*/
 9438       (& airo_set_multicast_list)(airo_netdev_ops_group1);
 9439       /*DEG-postcall: default*/
 9440       ldv_state_variable_12 = 2;
 9441      }
 9442     }
 9443     break;
 9444     case 1:{
 9445      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 9446      if(ldv_state_variable_12 == 3 && evil_hack_12()){
 9447       /*DEG-CALL: handler ndo_stop from airo_netdev_ops*/
 9448       (& airo_close)(airo_netdev_ops_group1);
 9449       ldv_state_variable_12 = 2;
 9450       rtnl_unlock();
 9451      }
 9452     }
 9453     break;
 9454     case 2:{
 9455      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9456      if(ldv_state_variable_12 == 1){
 9457       /*DEG-CALL: handler ndo_validate_addr from airo_netdev_ops*/
 9458       (& eth_validate_addr)(airo_netdev_ops_group1);
 9459       /*DEG-postcall: default*/
 9460       ldv_state_variable_12 = 1;
 9461      }
 9462      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 9463      if(ldv_state_variable_12 == 3){
 9464       /*DEG-CALL: handler ndo_validate_addr from airo_netdev_ops*/
 9465       (& eth_validate_addr)(airo_netdev_ops_group1);
 9466       /*DEG-postcall: default*/
 9467       ldv_state_variable_12 = 3;
 9468      }
 9469      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9470      if(ldv_state_variable_12 == 2){
 9471       /*DEG-CALL: handler ndo_validate_addr from airo_netdev_ops*/
 9472       (& eth_validate_addr)(airo_netdev_ops_group1);
 9473       /*DEG-postcall: default*/
 9474       ldv_state_variable_12 = 2;
 9475      }
 9476     }
 9477     break;
 9478     case 3:{
 9479      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9480      if(ldv_state_variable_12 == 1 && evil_hack_12()){
 9481       /*DEG-CALL: handler ndo_do_ioctl from airo_netdev_ops*/
 9482       (& airo_ioctl)(airo_netdev_ops_group1,ldvarg43,ldvarg42);
 9483       ldv_state_variable_12 = 1;
 9484       rtnl_unlock();
 9485      }
 9486      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 9487      if(ldv_state_variable_12 == 3 && evil_hack_12()){
 9488       /*DEG-CALL: handler ndo_do_ioctl from airo_netdev_ops*/
 9489       (& airo_ioctl)(airo_netdev_ops_group1,ldvarg43,ldvarg42);
 9490       ldv_state_variable_12 = 3;
 9491       rtnl_unlock();
 9492      }
 9493      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9494      if(ldv_state_variable_12 == 2 && evil_hack_12()){
 9495       /*DEG-CALL: handler ndo_do_ioctl from airo_netdev_ops*/
 9496       (& airo_ioctl)(airo_netdev_ops_group1,ldvarg43,ldvarg42);
 9497       ldv_state_variable_12 = 2;
 9498       rtnl_unlock();
 9499      }
 9500     }
 9501     break;
 9502     case 4:{
 9503      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9504      if(ldv_state_variable_12 == 1){
 9505       /*DEG-CALL: handler ndo_get_stats from airo_netdev_ops*/
 9506       (& airo_get_stats)(airo_netdev_ops_group1);
 9507       /*DEG-postcall: default*/
 9508       ldv_state_variable_12 = 1;
 9509      }
 9510      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 9511      if(ldv_state_variable_12 == 3){
 9512       /*DEG-CALL: handler ndo_get_stats from airo_netdev_ops*/
 9513       (& airo_get_stats)(airo_netdev_ops_group1);
 9514       /*DEG-postcall: default*/
 9515       ldv_state_variable_12 = 3;
 9516      }
 9517      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9518      if(ldv_state_variable_12 == 2){
 9519       /*DEG-CALL: handler ndo_get_stats from airo_netdev_ops*/
 9520       (& airo_get_stats)(airo_netdev_ops_group1);
 9521       /*DEG-postcall: default*/
 9522       ldv_state_variable_12 = 2;
 9523      }
 9524     }
 9525     break;
 9526     case 5:{
 9527      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 9528      if(ldv_state_variable_12 == 3){
 9529       /*DEG-CALL: handler ndo_change_mtu from airo_netdev_ops*/
 9530       (& airo_change_mtu)(airo_netdev_ops_group1,ldvarg41);
 9531       /*DEG-postcall: default*/
 9532       ldv_state_variable_12 = 3;
 9533      }
 9534      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9535      if(ldv_state_variable_12 == 2){
 9536       /*DEG-CALL: handler ndo_change_mtu from airo_netdev_ops*/
 9537       (& airo_change_mtu)(airo_netdev_ops_group1,ldvarg41);
 9538       /*DEG-postcall: default*/
 9539       ldv_state_variable_12 = 2;
 9540      }
 9541     }
 9542     break;
 9543     case 6:{
 9544      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9545      if(ldv_state_variable_12 == 2 && evil_hack_12()){
 9546       /*DEG-CALL: handler ndo_open from airo_netdev_ops*/
 9547       ldv_retval_11=(& airo_open)(airo_netdev_ops_group1);
 9548       if(ldv_retval_11==0){
 9549       ldv_state_variable_12 = 3;
 9550       }
 9551      }
 9552     }
 9553     break;
 9554     case 7:{
 9555      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 9556      if(ldv_state_variable_12 == 3){
 9557       /*DEG-CALL: handler ndo_start_xmit from airo_netdev_ops*/
 9558       (& airo_start_xmit)(ldvarg40,airo_netdev_ops_group1);
 9559       /*DEG-postcall: default*/
 9560       ldv_state_variable_12 = 3;
 9561      }
 9562     }
 9563     break;
 9564     case 8:{
 9565      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9566      if(ldv_state_variable_12 == 1){
 9567       /*DEG-CALL: handler ndo_set_mac_address from airo_netdev_ops*/
 9568       (& airo_set_mac_address)(airo_netdev_ops_group1,ldvarg39);
 9569       /*DEG-postcall: default*/
 9570       ldv_state_variable_12 = 1;
 9571      }
 9572      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 9573      if(ldv_state_variable_12 == 3){
 9574       /*DEG-CALL: handler ndo_set_mac_address from airo_netdev_ops*/
 9575       (& airo_set_mac_address)(airo_netdev_ops_group1,ldvarg39);
 9576       /*DEG-postcall: default*/
 9577       ldv_state_variable_12 = 3;
 9578      }
 9579      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9580      if(ldv_state_variable_12 == 2){
 9581       /*DEG-CALL: handler ndo_set_mac_address from airo_netdev_ops*/
 9582       (& airo_set_mac_address)(airo_netdev_ops_group1,ldvarg39);
 9583       /*DEG-postcall: default*/
 9584       ldv_state_variable_12 = 2;
 9585      }
 9586     }
 9587     break;
 9588     case 9:{
 9589      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9590      if(ldv_state_variable_12 == 1){
 9591       /*DEG-CALL: handler ndo_init from airo_netdev_ops*/
 9592       ldv_retval_10=ldv_ndo_init_12();
 9593       if(ldv_retval_10==0){
 9594       ldv_state_variable_12 = 2;
 9595       ref_cnt++;
 9596       }
 9597      }
 9598     }
 9599     break;
 9600     case 10:{
 9601      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9602      if(ldv_state_variable_12 == 2 && evil_hack_12()){
 9603       /*DEG-CALL: handler ndo_uninit from airo_netdev_ops*/
 9604       ldv_ndo_uninit_12();
 9605       ldv_state_variable_12 = 1;
 9606       ref_cnt--;
 9607       rtnl_unlock();
 9608      }
 9609     }
 9610     break;
 9611     default: ldv_assume(0);
 9612     }
 9613    }
 9614   }
 9615   break;
 9616   case 10:{
 9617    /*DEG-struct: handlers from structure airo_header_ops*/
 9618    /*DEG-CHECK: checking registration of airo_header_ops structure*/
 9619    if(ldv_state_variable_14 != 0){
 9620     switch(__VERIFIER_nondet_int()){
 9621     case 0:{
 9622      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9623      if(ldv_state_variable_14 == 1){
 9624       /*DEG-CALL: handler parse from airo_header_ops*/
 9625       (& wll_header_parse)(ldvarg44,ldvarg45);
 9626       /*DEG-postcall: default*/
 9627       ldv_state_variable_14 = 1;
 9628      }
 9629     }
 9630     break;
 9631     default: ldv_assume(0);
 9632     }
 9633    }
 9634   }
 9635   break;
 9636   case 11:{
 9637    /*DEG-struct: handlers from structure airo_driver*/
 9638    /*DEG-CHECK: checking registration of airo_driver structure*/
 9639    if(ldv_state_variable_15 != 0){
 9640     switch(__VERIFIER_nondet_int()){
 9641     case 0:{
 9642      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9643      if(ldv_state_variable_15 == 1){
 9644       /*DEG-CALL: handler probe from airo_driver*/
 9645       ldv_retval_16=(& airo_pci_probe)(airo_driver_group1,ldvarg47);
 9646       if(ldv_retval_16==0){
 9647       ldv_state_variable_15 = 2;
 9648       ref_cnt++;
 9649       }
 9650      }
 9651     }
 9652     break;
 9653     case 1:{
 9654      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9655      if(ldv_state_variable_15 == 2 && pci_counter==0){
 9656       /*DEG-CALL: handler suspend from airo_driver*/
 9657       ldv_retval_15=(& airo_pci_suspend)(airo_driver_group1,ldvarg46);
 9658       if(ldv_retval_15==0){
 9659       ldv_state_variable_15 = 3;
 9660       }
 9661      }
 9662     }
 9663     break;
 9664     case 2:{
 9665      /*DEG-state: state 4 (look at corresponding state-chart diagram for details)*/
 9666      if(ldv_state_variable_15 == 4){
 9667       /*DEG-CALL: handler remove from airo_driver*/
 9668       (& airo_pci_remove)(airo_driver_group1);
 9669       ldv_state_variable_15 = 1;
 9670      }
 9671      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 9672      if(ldv_state_variable_15 == 3){
 9673       /*DEG-CALL: handler remove from airo_driver*/
 9674       (& airo_pci_remove)(airo_driver_group1);
 9675       ldv_state_variable_15 = 1;
 9676      }
 9677      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9678      if(ldv_state_variable_15 == 2){
 9679       /*DEG-CALL: handler remove from airo_driver*/
 9680       (& airo_pci_remove)(airo_driver_group1);
 9681       ldv_state_variable_15 = 1;
 9682      }
 9683      /*DEG-state: state 5 (look at corresponding state-chart diagram for details)*/
 9684      if(ldv_state_variable_15 == 5){
 9685       /*DEG-CALL: handler remove from airo_driver*/
 9686       (& airo_pci_remove)(airo_driver_group1);
 9687       ldv_state_variable_15 = 1;
 9688      }
 9689     }
 9690     break;
 9691     case 3:{
 9692      /*DEG-state: state 4 (look at corresponding state-chart diagram for details)*/
 9693      if(ldv_state_variable_15 == 4){
 9694       /*DEG-CALL: handler resume from airo_driver*/
 9695       ldv_retval_14=(& airo_pci_resume)(airo_driver_group1);
 9696       if(ldv_retval_14==0){
 9697       ldv_state_variable_15 = 2;
 9698       }
 9699      }
 9700      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 9701      if(ldv_state_variable_15 == 3){
 9702       /*DEG-CALL: handler resume from airo_driver*/
 9703       ldv_retval_14=(& airo_pci_resume)(airo_driver_group1);
 9704       if(ldv_retval_14==0){
 9705       ldv_state_variable_15 = 2;
 9706       }
 9707      }
 9708      /*DEG-state: state 5 (look at corresponding state-chart diagram for details)*/
 9709      if(ldv_state_variable_15 == 5){
 9710       /*DEG-CALL: handler resume from airo_driver*/
 9711       ldv_retval_14=(& airo_pci_resume)(airo_driver_group1);
 9712       if(ldv_retval_14==0){
 9713       ldv_state_variable_15 = 2;
 9714       }
 9715      }
 9716     }
 9717     break;
 9718     case 4:{
 9719      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 9720      if(ldv_state_variable_15 == 3){
 9721       /*DEG-CALL: handler suspend_late from airo_driver*/
 9722       ldv_retval_13=ldv_suspend_late_15();
 9723       if(ldv_retval_13==0){
 9724       ldv_state_variable_15 = 4;
 9725       }
 9726      }
 9727     }
 9728     break;
 9729     case 5:{
 9730      /*DEG-state: state 4 (look at corresponding state-chart diagram for details)*/
 9731      if(ldv_state_variable_15 == 4){
 9732       /*DEG-CALL: handler resume_early from airo_driver*/
 9733       ldv_retval_12=ldv_resume_early_15();
 9734       if(ldv_retval_12==0){
 9735       ldv_state_variable_15 = 5;
 9736       }
 9737      }
 9738      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 9739      if(ldv_state_variable_15 == 3){
 9740       /*DEG-CALL: handler resume_early from airo_driver*/
 9741       ldv_retval_12=ldv_resume_early_15();
 9742       if(ldv_retval_12==0){
 9743       ldv_state_variable_15 = 5;
 9744       }
 9745      }
 9746     }
 9747     break;
 9748     case 6:{
 9749      /*DEG-state: state 4 (look at corresponding state-chart diagram for details)*/
 9750      if(ldv_state_variable_15 == 4){
 9751       /*DEG-CALL: handler shutdown from airo_driver*/
 9752       ldv_shutdown_15();
 9753       ldv_state_variable_15 = 4;
 9754      }
 9755      /*DEG-state: state 3 (look at corresponding state-chart diagram for details)*/
 9756      if(ldv_state_variable_15 == 3){
 9757       /*DEG-CALL: handler shutdown from airo_driver*/
 9758       ldv_shutdown_15();
 9759       ldv_state_variable_15 = 3;
 9760      }
 9761      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9762      if(ldv_state_variable_15 == 2){
 9763       /*DEG-CALL: handler shutdown from airo_driver*/
 9764       ldv_shutdown_15();
 9765       ldv_state_variable_15 = 2;
 9766      }
 9767      /*DEG-state: state 5 (look at corresponding state-chart diagram for details)*/
 9768      if(ldv_state_variable_15 == 5){
 9769       /*DEG-CALL: handler shutdown from airo_driver*/
 9770       ldv_shutdown_15();
 9771       ldv_state_variable_15 = 5;
 9772      }
 9773     }
 9774     break;
 9775     default: ldv_assume(0);
 9776     }
 9777    }
 9778   }
 9779   break;
 9780   case 12:{
 9781    /*DEG-struct: handlers from structure proc_status_ops*/
 9782    /*DEG-CHECK: checking registration of proc_status_ops structure*/
 9783    if(ldv_state_variable_8 != 0){
 9784     switch(__VERIFIER_nondet_int()){
 9785     case 0:{
 9786      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9787      if(ldv_state_variable_8 == 2){
 9788       /*DEG-CALL: handler read from proc_status_ops*/
 9789       (& proc_read)(proc_status_ops_group2,ldvarg52,ldvarg51,ldvarg50);
 9790       /*DEG-postcall: default*/
 9791       ldv_state_variable_8 = 2;
 9792      }
 9793     }
 9794     break;
 9795     case 1:{
 9796      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9797      if(ldv_state_variable_8 == 1){
 9798       /*DEG-CALL: handler open from proc_status_ops*/
 9799       ldv_retval_17=(& proc_status_open)(proc_status_ops_group1,proc_status_ops_group2);
 9800       if(ldv_retval_17==0){
 9801       ldv_state_variable_8 = 2;
 9802       ref_cnt++;
 9803       }
 9804      }
 9805     }
 9806     break;
 9807     case 2:{
 9808      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9809      if(ldv_state_variable_8 == 2){
 9810       /*DEG-CALL: handler release from proc_status_ops*/
 9811       (& proc_close)(proc_status_ops_group1,proc_status_ops_group2);
 9812       ldv_state_variable_8 = 1;
 9813       ref_cnt--;
 9814      }
 9815     }
 9816     break;
 9817     case 3:{
 9818      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9819      if(ldv_state_variable_8 == 2){
 9820       /*DEG-CALL: handler llseek from proc_status_ops*/
 9821       (& default_llseek)(proc_status_ops_group2,ldvarg49,ldvarg48);
 9822       /*DEG-postcall: default*/
 9823       ldv_state_variable_8 = 2;
 9824      }
 9825     }
 9826     break;
 9827     default: ldv_assume(0);
 9828     }
 9829    }
 9830   }
 9831   break;
 9832   case 13:{
 9833    /*DEG-struct: handlers from structure proc_config_ops*/
 9834    /*DEG-CHECK: checking registration of proc_config_ops structure*/
 9835    if(ldv_state_variable_4 != 0){
 9836     switch(__VERIFIER_nondet_int()){
 9837     case 0:{
 9838      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9839      if(ldv_state_variable_4 == 1){
 9840       /*DEG-CALL: handler write from proc_config_ops*/
 9841       (& proc_write)(proc_config_ops_group2,ldvarg60,ldvarg59,ldvarg58);
 9842       /*DEG-postcall: default*/
 9843       ldv_state_variable_4 = 1;
 9844      }
 9845      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9846      if(ldv_state_variable_4 == 2){
 9847       /*DEG-CALL: handler write from proc_config_ops*/
 9848       (& proc_write)(proc_config_ops_group2,ldvarg60,ldvarg59,ldvarg58);
 9849       /*DEG-postcall: default*/
 9850       ldv_state_variable_4 = 2;
 9851      }
 9852     }
 9853     break;
 9854     case 1:{
 9855      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9856      if(ldv_state_variable_4 == 2){
 9857       /*DEG-CALL: handler read from proc_config_ops*/
 9858       (& proc_read)(proc_config_ops_group2,ldvarg57,ldvarg56,ldvarg55);
 9859       /*DEG-postcall: default*/
 9860       ldv_state_variable_4 = 2;
 9861      }
 9862     }
 9863     break;
 9864     case 2:{
 9865      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9866      if(ldv_state_variable_4 == 1){
 9867       /*DEG-CALL: handler open from proc_config_ops*/
 9868       ldv_retval_18=(& proc_config_open)(proc_config_ops_group1,proc_config_ops_group2);
 9869       if(ldv_retval_18==0){
 9870       ldv_state_variable_4 = 2;
 9871       ref_cnt++;
 9872       }
 9873      }
 9874     }
 9875     break;
 9876     case 3:{
 9877      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9878      if(ldv_state_variable_4 == 2){
 9879       /*DEG-CALL: handler release from proc_config_ops*/
 9880       (& proc_close)(proc_config_ops_group1,proc_config_ops_group2);
 9881       ldv_state_variable_4 = 1;
 9882       ref_cnt--;
 9883      }
 9884     }
 9885     break;
 9886     case 4:{
 9887      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9888      if(ldv_state_variable_4 == 2){
 9889       /*DEG-CALL: handler llseek from proc_config_ops*/
 9890       (& default_llseek)(proc_config_ops_group2,ldvarg54,ldvarg53);
 9891       /*DEG-postcall: default*/
 9892       ldv_state_variable_4 = 2;
 9893      }
 9894     }
 9895     break;
 9896     default: ldv_assume(0);
 9897     }
 9898    }
 9899   }
 9900   break;
 9901   case 14:{
 9902    /*DEG-struct: handlers from structure proc_statsdelta_ops*/
 9903    /*DEG-CHECK: checking registration of proc_statsdelta_ops structure*/
 9904    if(ldv_state_variable_10 != 0){
 9905     switch(__VERIFIER_nondet_int()){
 9906     case 0:{
 9907      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9908      if(ldv_state_variable_10 == 2){
 9909       /*DEG-CALL: handler read from proc_statsdelta_ops*/
 9910       (& proc_read)(proc_statsdelta_ops_group2,ldvarg65,ldvarg64,ldvarg63);
 9911       /*DEG-postcall: default*/
 9912       ldv_state_variable_10 = 2;
 9913      }
 9914     }
 9915     break;
 9916     case 1:{
 9917      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9918      if(ldv_state_variable_10 == 1){
 9919       /*DEG-CALL: handler open from proc_statsdelta_ops*/
 9920       ldv_retval_19=(& proc_statsdelta_open)(proc_statsdelta_ops_group1,proc_statsdelta_ops_group2);
 9921       if(ldv_retval_19==0){
 9922       ldv_state_variable_10 = 2;
 9923       ref_cnt++;
 9924       }
 9925      }
 9926     }
 9927     break;
 9928     case 2:{
 9929      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9930      if(ldv_state_variable_10 == 2){
 9931       /*DEG-CALL: handler release from proc_statsdelta_ops*/
 9932       (& proc_close)(proc_statsdelta_ops_group1,proc_statsdelta_ops_group2);
 9933       ldv_state_variable_10 = 1;
 9934       ref_cnt--;
 9935      }
 9936     }
 9937     break;
 9938     case 3:{
 9939      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9940      if(ldv_state_variable_10 == 2){
 9941       /*DEG-CALL: handler llseek from proc_statsdelta_ops*/
 9942       (& default_llseek)(proc_statsdelta_ops_group2,ldvarg62,ldvarg61);
 9943       /*DEG-postcall: default*/
 9944       ldv_state_variable_10 = 2;
 9945      }
 9946     }
 9947     break;
 9948     default: ldv_assume(0);
 9949     }
 9950    }
 9951   }
 9952   break;
 9953   case 15:{
 9954    /*DEG-struct: handlers from structure proc_APList_ops*/
 9955    /*DEG-CHECK: checking registration of proc_APList_ops structure*/
 9956    if(ldv_state_variable_5 != 0){
 9957     switch(__VERIFIER_nondet_int()){
 9958     case 0:{
 9959      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9960      if(ldv_state_variable_5 == 1){
 9961       /*DEG-CALL: handler write from proc_APList_ops*/
 9962       (& proc_write)(proc_APList_ops_group2,ldvarg73,ldvarg72,ldvarg71);
 9963       /*DEG-postcall: default*/
 9964       ldv_state_variable_5 = 1;
 9965      }
 9966      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9967      if(ldv_state_variable_5 == 2){
 9968       /*DEG-CALL: handler write from proc_APList_ops*/
 9969       (& proc_write)(proc_APList_ops_group2,ldvarg73,ldvarg72,ldvarg71);
 9970       /*DEG-postcall: default*/
 9971       ldv_state_variable_5 = 2;
 9972      }
 9973     }
 9974     break;
 9975     case 1:{
 9976      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9977      if(ldv_state_variable_5 == 2){
 9978       /*DEG-CALL: handler read from proc_APList_ops*/
 9979       (& proc_read)(proc_APList_ops_group2,ldvarg70,ldvarg69,ldvarg68);
 9980       /*DEG-postcall: default*/
 9981       ldv_state_variable_5 = 2;
 9982      }
 9983     }
 9984     break;
 9985     case 2:{
 9986      /*DEG-state: state 1 (look at corresponding state-chart diagram for details)*/
 9987      if(ldv_state_variable_5 == 1){
 9988       /*DEG-CALL: handler open from proc_APList_ops*/
 9989       ldv_retval_20=(& proc_APList_open)(proc_APList_ops_group1,proc_APList_ops_group2);
 9990       if(ldv_retval_20==0){
 9991       ldv_state_variable_5 = 2;
 9992       ref_cnt++;
 9993       }
 9994      }
 9995     }
 9996     break;
 9997     case 3:{
 9998      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
 9999      if(ldv_state_variable_5 == 2){
10000       /*DEG-CALL: handler release from proc_APList_ops*/
10001       (& proc_close)(proc_APList_ops_group1,proc_APList_ops_group2);
10002       ldv_state_variable_5 = 1;
10003       ref_cnt--;
10004      }
10005     }
10006     break;
10007     case 4:{
10008      /*DEG-state: state 2 (look at corresponding state-chart diagram for details)*/
10009      if(ldv_state_variable_5 == 2){
10010       /*DEG-CALL: handler llseek from proc_APList_ops*/
10011       (& default_llseek)(proc_APList_ops_group2,ldvarg67,ldvarg66);
10012       /*DEG-postcall: default*/
10013       ldv_state_variable_5 = 2;
10014      }
10015     }
10016     break;
10017     default: ldv_assume(0);
10018     }
10019    }
10020   }
10021   break;
10022   default: ldv_assume(0);
10023   }
10024  }
10025  ldv_final:
10026  ldv_check_final_state();
10027  return;
10028 }
10029 /* DEG-ENVIRONMENT-END */                 1 #ifndef _LDV_RCV_H_
    2 #define _LDV_RCV_H_
    3 
    4 /* If expr evaluates to zero, ldv_assert() causes a program to reach the error
    5    label like the standard assert(). */
    6 #define ldv_assert(expr) ((expr) ? 0 : ldv_error())
    7 
    8 /* The error label wrapper. It is used because of some static verifiers (like
    9    BLAST) don't accept multiple error labels through a program. */
   10 static inline void ldv_error(void)
   11 {
   12   LDV_ERROR: goto LDV_ERROR;
   13 }
   14 
   15 /* If expr evaluates to zero, ldv_assume() causes an infinite loop that is
   16    avoided by verifiers. */
   17 #define ldv_assume(expr) ((expr) ? 0 : ldv_stop())
   18 
   19 /* Infinite loop, that causes verifiers to skip such paths. */
   20 static inline void ldv_stop(void) {
   21   LDV_STOP: goto LDV_STOP;
   22 }
   23 
   24 /* Special nondeterministic functions. */
   25 int ldv_undef_int(void);
   26 void *ldv_undef_ptr(void);
   27 unsigned long ldv_undef_ulong(void);
   28 long ldv_undef_long(void);
   29 /* Return nondeterministic negative integer number. */
   30 static inline int ldv_undef_int_negative(void)
   31 {
   32   int ret = ldv_undef_int();
   33 
   34   ldv_assume(ret < 0);
   35 
   36   return ret;
   37 }
   38 /* Return nondeterministic nonpositive integer number. */
   39 static inline int ldv_undef_int_nonpositive(void)
   40 {
   41   int ret = ldv_undef_int();
   42 
   43   ldv_assume(ret <= 0);
   44 
   45   return ret;
   46 }
   47 
   48 /* Add explicit model for __builin_expect GCC function. Without the model a
   49    return value will be treated as nondetermined by verifiers. */
   50 static inline long __builtin_expect(long exp, long c)
   51 {
   52   return exp;
   53 }
   54 
   55 /* This function causes the program to exit abnormally. GCC implements this
   56 function by using a target-dependent mechanism (such as intentionally executing
   57 an illegal instruction) or by calling abort. The mechanism used may vary from
   58 release to release so you should not rely on any particular implementation.
   59 http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html */
   60 static inline void __builtin_trap(void)
   61 {
   62   ldv_assert(0);
   63 }
   64 
   65 /* The constant is for simulating an error of ldv_undef_ptr() function. */
   66 #define LDV_PTR_MAX 2012
   67 
   68 #endif /* _LDV_RCV_H_ */            | 
Here is an explanation of a rule violation arisen while checking your driver against a corresponding kernel.
Note that it may be false positive, i.e. there isn't a real error indeed. Please analyze a given error trace and related source code to understand whether there is an error in your driver.
Error trace column contains a path on which the given rule is violated. You can expand/collapse some entity classes by clicking on corresponding checkboxes in a main menu or in an advanced Others menu. Also you can expand/collapse each particular entity by clicking on +/-. In hovering on some entities you can see some tips. Also the error trace is bound with related source code. Line numbers may be shown as links on the left. You can click on them to open corresponding lines in source code.
Source code column contains a content of files related with the error trace. There is source code of your driver (note that there are some LDV modifications at the end), kernel headers and rule model. Tabs show a currently opened file and other available files. In hovering on them you can see full file names. On clicking a corresponding file content will be shown.
| Ядро | Модуль | Правило | Верификатор | Вердикт | Статус | Время создания | 
| linux-4.5-rc7 | drivers/net/wireless/cisco/airo.ko | races | CPAchecker | Bug | Unreported | 2016-03-14 15:12:44 | 
Комментарий
Write access to local->wstats.qual.qual is not protected from parallel interrupt handling
[В начало]