OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
From: Javier Achirica (achiricattd.net)
Date: Mon May 21 2001 - 13:43:25 CDT

  • Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]

    On 21 May 2001 alexdigital-army.com wrote:

    > Do you have a beta version of a driver with RF Monitor mode included
    > that I could use? I tried applying the diff file posted earlier and got
    > a bunch of errors, so I probably don't have the latest version of the
    > the airo-linux driver, which I obtained from sourceforge.net.

    Attached is my latest version. The version in sourceforge you should patch
    is 1.7 from the CVS tree. This is the URL:

    <http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/~checkout~/airo-linux/airo-linux/kernel/airo.c?rev=1.7&content-type=text/plain>

    Javier Achirica

    --UugvWAfsgieZRqgk
    Content-Type: text/plain; charset=us-ascii
    Content-Disposition: attachment; filename="rfmon-airo.c.diff-20010521"

    --- airo.c.17 Wed May 16 21:59:19 2001
    +++ airo.c Sun May 20 23:34:11 2001
    -761,6 +761,7
     #define FLAG_RADIO_OFF 0x02
             int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen,
                             int whichbap);
    + int (*header_parse)(struct sk_buff*, unsigned char *);
     #ifdef WIRELESS_EXT
             int need_commit; // Need to set config
             struct iw_statistics wstats; // wireless stats
    -993,6 +994,19
             }
     }
     
    +static int airo_set_mac_address(struct net_device *dev, void *p)
    +{
    + struct airo_info *ai = (struct airo_info*)dev->priv;
    + struct sockaddr *addr = p;
    + ConfigRid cfg;
    +
    + readConfigRid (ai, &cfg);
    + memcpy (cfg.macAddr, addr->sa_data, dev->addr_len);
    + writeConfigRid (ai, &cfg);
    + memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
    + return 0;
    +}
    +
     static int airo_change_mtu(struct net_device *dev, int new_mtu)
     {
             if ((new_mtu < 68) || (new_mtu > 2400))
    -1056,12 +1070,14
             ai->bap1_lock = SPIN_LOCK_UNLOCKED;
             ai->aux_lock = SPIN_LOCK_UNLOCKED;
             ai->cmd_lock = SPIN_LOCK_UNLOCKED;
    + ai->header_parse = dev->hard_header_parse;
             add_airo_dev( dev );
             
             /* The Airo-specific entries in the device structure. */
             dev->hard_start_xmit = &airo_start_xmit;
             dev->get_stats = &airo_get_stats;
             dev->set_multicast_list = &airo_set_multicast_list;
    + dev->set_mac_address = &airo_set_mac_address;
             dev->do_ioctl = &airo_ioctl;
     #ifdef WIRELESS_EXT
             dev->get_wireless_stats = airo_get_wireless_stats;
    -1099,7 +1115,7
             }
             /* Allocate the transmit buffers */
             for( i = 0; i < MAX_FIDS; i++ ) {
    - ai->fids[i] = transmit_allocate( ai, 2000 );
    + ai->fids[i] = transmit_allocate( ai, 2312 );
             }
             
             setup_proc_entry( dev, (struct airo_info*)dev->priv );
    -1107,12 +1123,29
             return dev;
     }
     
    +int waitbusy (struct airo_info *ai) {
    + int delay = 0;
    + while ((IN4500 (ai, COMMAND) & COMMAND_BUSY) & (delay < 10000)) {
    + udelay (10);
    + if (++delay % 20)
    + OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
    + }
    + return delay < 10000;
    +}
    +
     int reset_airo_card( struct net_device *dev ) {
    - int i;
    + int i, flags;
             struct airo_info *ai = (struct airo_info*)dev->priv;
     
    - if ( setup_card(ai, dev->dev_addr,
    - &(ai)->config) != SUCCESS ) {
    + disable_MAC(ai);
    + spin_lock_irqsave(&ai->cmd_lock, flags);
    + waitbusy (ai);
    + OUT4500(ai,COMMAND,CMD_SOFTRESET);
    + mdelay (200);
    + waitbusy (ai);
    + mdelay (200);
    + spin_unlock_irqrestore(&ai->cmd_lock, flags);
    + if ( setup_card(ai, dev->dev_addr, &(ai)->config) != SUCCESS ) {
                     printk( KERN_ERR "airo: MAC could not be enabled\n" );
                     return -1;
             } else {
    -1126,19 +1159,22
                             dev->dev_addr[5]
                             );
                     /* Allocate the transmit buffers */
    - for( i = 0; i < MAX_FIDS; i++ ) {
    - ((struct airo_info*)dev->priv)->fids[i] =
    - transmit_allocate( ai, 2000 );
    - }
    + for( i = 0; i < MAX_FIDS; i++ )
    + ai->fids[i] = transmit_allocate( ai, 2312 );
             }
             enable_interrupts( ai );
             netif_start_queue(dev);
             return 0;
     }
     
    +int wll_header_parse(struct sk_buff *skb, unsigned char *haddr)
    +{
    + memcpy(haddr, skb->mac.raw + 10, ETH_ALEN);
    + return ETH_ALEN;
    +}
    +
     static void airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) {
             struct net_device *dev = (struct net_device *)dev_id;
    - u16 len;
             u16 status;
             u16 fid;
             struct airo_info *apriv = (struct airo_info *)dev->priv;
    -1149,7 +1185,7
                     return;
             
             status = IN4500( apriv, EVSTAT );
    - if ( !status ) return;
    + if ( !status || status == 0xffff ) return;
             
             if ( status & EV_AWAKE ) {
                     OUT4500( apriv, EVACK, EV_AWAKE );
    -1202,72 +1238,118
                     }
             }
             
    - /* Check to see if there is something to recieve */
    + /* Check to see if there is something to receive */
             if ( status & EV_RX ) {
                     struct sk_buff *skb;
                     int flags;
    + u16 fc, len, hdrlen;
    + struct {
    + u16 status, len;
    + u8 rssi[2];
    + } hdr;
     
                     fid = IN4500( apriv, RXFID );
     
                     /* Get the packet length */
                     spin_lock_irqsave(&apriv->bap0_lock, flags);
    - bap_setup( apriv, fid, 0x36, BAP0 );
    - bap_read( apriv, &len, sizeof(len), BAP0 );
    +#define ARPHRD_80211 11
    + if (dev->type == ARPHRD_80211) {
    + bap_setup (apriv, fid, 4, BAP0);
    + bap_read (apriv, (u16*)&hdr, sizeof(hdr), BAP0);
    + /* Bad CRC. Ignore packet */
    + if (le16_to_cpu(hdr.status) == 2) {
    +#if LINUX_VERSION_CODE > 0x20127
    + apriv->stats.rx_crc_errors++;
    +#endif
    + apriv->stats.rx_errors++;
    + hdr.len = 0;
    + }
    + } else {
    + bap_setup (apriv, fid, 6, BAP0);
    + bap_read (apriv, (u16*)&hdr.len, 4, BAP0);
    + }
    + len = le16_to_cpu(hdr.len);
     
    - len = le16_to_cpu(len);
    - /* The length only counts the payload
    - not the hw addresses */
    - len += 12;
    - if ( len < 12 || len > 2048 ) {
    + if (len > 2312) {
     #if LINUX_VERSION_CODE > 0x20127
                             apriv->stats.rx_length_errors++;
     #endif
                             apriv->stats.rx_errors++;
                             printk( KERN_ERR
                                     "airo: Bad size %d\n", len );
    - } else {
    - skb = dev_alloc_skb( len + 2 );
    + len = 0;
    + }
    + if (len) {
    + if (dev->type == ARPHRD_80211) {
    + bap_setup (apriv, fid, 0x14, BAP0);
    + bap_read (apriv, (u16*)&fc, sizeof(fc), BAP0);
    + if ((le16_to_cpu(fc) & 0x300) == 0x300)
    + hdrlen = 30;
    + else
    + hdrlen = 24;
    + } else
    + hdrlen = 12;
    +
    + skb = dev_alloc_skb( len + hdrlen + 2 );
                             if ( !skb ) {
                                     apriv->stats.rx_dropped++;
    + len = 0;
    + }
    + }
    + if (len) {
    + u16 *buffer;
    + buffer = (u16*)skb_put (skb, len + hdrlen);
    + if (dev->type == ARPHRD_80211) {
    + u16 gap, tmpbuf[4];
    + buffer[0] = fc;
    + bap_read (apriv, buffer + 1, hdrlen - 2, BAP0);
    + if (hdrlen == 24)
    + bap_read (apriv, tmpbuf, 6, BAP0);
    +
    + bap_read (apriv, &gap, sizeof(gap), BAP0);
    + gap = le16_to_cpu(gap);
    + if (gap && gap <= 8)
    + bap_read (apriv, tmpbuf, gap, BAP0);
    +
    + bap_read (apriv, buffer + hdrlen/2, len, BAP0);
                             } else {
    - char *buffer;
    - buffer = skb_put( skb, len );
    - bap_setup( apriv, fid, 0x36+sizeof(len), BAP0 );
    - bap_read( apriv, (u16*)buffer, len, BAP0 );
    + bap_setup (apriv, fid, 0x38, BAP0);
    + bap_read (apriv, buffer,len + hdrlen,BAP0);
    + }
     #ifdef WIRELESS_SPY
    - if (apriv->spy_number > 0) {
    -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(1,3,0))
    - char *srcaddr = skb->mac.raw + 6;
    -#else
    - char *srcaddr = skb->data + MAX_ADDR_SIZE;
    -#endif
    - u8 rssi[2];
    - int i;
    -
    - for (i=0; i<apriv->spy_number; i++)
    - if (!memcmp(srcaddr, apriv->spy_address[i], 6))
    - {
    - /* Get the rssi signal strength */
    - bap_setup( apriv, fid, 0x08, BAP0 );
    - bap_read( apriv, (u16 *)&rssi, sizeof(rssi), BAP0 );
    - apriv->spy_stat[i].qual = rssi[0];
    - apriv->spy_stat[i].level = rssi[1];
    - apriv->spy_stat[i].noise = 0;
    - apriv->spy_stat[i].updated = 3;
    - break;
    - }
    - }
    + if (apriv->spy_number > 0) {
    + int i;
    + char *sa;
    +
    + sa = (char*)buffer + ((dev->type == ARPHRD_80211) ? 10 : 6);
    +
    + for (i=0; i<apriv->spy_number; i++)
    + if (!memcmp(sa,apriv->spy_address[i],6))
    + {
    + apriv->spy_stat[i].qual = hdr.rssi[0];
    + apriv->spy_stat[i].level = hdr.rssi[1];
    + apriv->spy_stat[i].noise = 0;
    + apriv->spy_stat[i].updated = 3;
    + break;
    + }
    + }
     #endif /* WIRELESS_SPY */
    - apriv->stats.rx_packets++;
    + apriv->stats.rx_packets++;
     #if LINUX_VERSION_CODE > 0x20127
    - apriv->stats.rx_bytes += len;
    + apriv->stats.rx_bytes += len + hdrlen;
     #endif
    - skb->dev = dev;
    - skb->ip_summed = CHECKSUM_NONE;
    + dev->last_rx = jiffies;
    + skb->dev = dev;
    + skb->ip_summed = CHECKSUM_NONE;
    + if (dev->type == ARPHRD_80211) {
    + skb->mac.raw = skb->data;
    + skb_pull (skb, hdrlen);
    + skb->pkt_type = PACKET_OTHERHOST;
    + skb->protocol = htons(ETH_P_802_2);
    + } else
                                     skb->protocol = eth_type_trans( skb, dev );
     
    - netif_rx( skb );
    - }
    + netif_rx( skb );
                     }
                     spin_unlock_irqrestore(&apriv->bap0_lock, flags);
             }
    -2457,16 +2539,14
             struct net_device *dev = dp->data;
             struct airo_info *ai = (struct airo_info*)dev->priv;
             ConfigRid config;
    - Cmd cmd;
             Resp rsp;
             char *line;
    + int need_reset = 0;
             
             if ( !data->writelen ) return;
             dp = (struct proc_dir_entry *) inode->u.generic_ip;
             
    - memset(&cmd, 0, sizeof(Cmd));
    - cmd.cmd = MAC_DISABLE; // disable in case already enabled
    - issuecommand(ai, &cmd, &rsp);
    + disable_MAC(ai);
             readConfigRid(ai, &config);
     
             line = data->wbuffer;
    -2474,8 +2554,24
     /*** Mode processing */
                     if ( !strncmp( line, "Mode: ", 6 ) ) {
                             line += 6;
    - if ( line[0] == 'a' ) config.opmode = 0;
    - else config.opmode = 1;
    + config.rmode &= 0xfe00;
    + if ( line[0] == 'a' ) {
    + config.opmode = 0;
    + } else {
    + config.opmode = 1;
    + if ( line[0] == 'r' )
    + config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
    + else if ( line[0] == 'y' )
    + config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER;
    + }
    + if (config.rmode & RXMODE_DISABLE_802_3_HEADER) {
    + dev->type = ARPHRD_80211;
    + dev->hard_header_parse = wll_header_parse;
    + } else if (dev->type == ARPHRD_80211) {
    + dev->type = ARPHRD_ETHER;
    + dev->hard_header_parse = ai->header_parse;
    + need_reset = 1;
    + }
                     }
                     
     /*** Radio status */
    -2609,8 +2705,18
                     while( line[0] && line[0] != '\n' ) line++;
                     if ( line[0] ) line++;
             }
    - ai->config = config;
             checkThrottle(&config);
    + ai->config = config;
    + if (need_reset) {
    + APListRid APList_rid;
    + SsidRid SSID_rid;
    +
    + readAPListRid(ai, &APList_rid);
    + readSsidRid(ai, &SSID_rid);
    + reset_airo_card(dev);
    + writeSsidRid(ai, &SSID_rid);
    + writeAPListRid(ai, &APList_rid);
    + }
             writeConfigRid(ai, &config);
             enable_MAC(ai, &rsp);
     }
    -2768,14 +2874,10
     static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data,
                             int len ) {
             int rc;
    - Cmd cmd;
             Resp rsp;
             
    - memset(&cmd, 0, sizeof(cmd));
    - cmd.cmd = MAC_DISABLE; // disable in case already enabled
    - issuecommand(ai, &cmd, &rsp);
    - rc = PC4500_writerid(ai,
    - rid, rid_data, len);
    + disable_MAC(ai);
    + rc = PC4500_writerid(ai, rid, rid_data, len);
             enable_MAC(ai, &rsp);
             return rc;
     }
    -3865,6 +3967,10
     
             case SIOCSIWPOWER:
                     if (wrq->u.power.disabled) {
    + if ((config.rmode & 0xFF) >= RXMODE_RFMON) {
    + rc = -EINVAL;
    + break;
    + }
                             config.powerSaveMode = POWERSAVE_CAM;
                             config.rmode &= 0xFF00;
                             config.rmode |= RXMODE_BC_MC_ADDR;
    -3882,19 +3988,25
                     }
                     switch (wrq->u.power.flags & IW_POWER_MODE) {
                     case IW_POWER_UNICAST_R:
    + if ((config.rmode & 0xFF) >= RXMODE_RFMON) {
    + rc = -EINVAL;
    + break;
    + }
                             config.rmode &= 0xFF00;
                             config.rmode |= RXMODE_ADDR;
                             local->need_commit = 1;
                             break;
                     case IW_POWER_ALL_R:
    + if ((config.rmode & 0xFF) >= RXMODE_RFMON) {
    + rc = -EINVAL;
    + break;
    + }
                             config.rmode &= 0xFF00;
                             config.rmode |= RXMODE_BC_MC_ADDR;
                             local->need_commit = 1;
    - break;
                     case IW_POWER_ON:
                             break;
                     default:
    - local->need_commit = 0;
                             rc = -EINVAL;
                     }
                     break;
    -3918,6 +4030,7
                                     memcpy(s[i].sa_data, status_rid.bssid[i], 6);
                                     s[i].sa_family = ARPHRD_ETHER;
                             }
    + wrq->u.data.length = 4;
                             if (copy_to_user(wrq->u.data.pointer, &s, sizeof(s)))
                                     rc = -EFAULT;
                     }
    -4041,12 +4154,9
                      * local->need_commit != 0. Then, you need to patch "open"
                      * to do the final commit of all parameters...
                      * Jean II */
    - Cmd command;
                     Resp rsp;
     
    - command.cmd = MAC_DISABLE; // disable in case already enabled
    - issuecommand(local, &command, &rsp);
    -
    + disable_MAC(local);
                     local->config = config; /* ???? config is local !!! */
                     checkThrottle(&config);
                     writeConfigRid(local, &config);
    -4285,37 +4395,6
     
     #define FLASH_COMMAND 0x7e7e
     
    -int unstickbusy(struct airo_info *ai) {
    - unsigned short uword;
    -
    - /* clear stuck command busy if necessary */
    - if ((uword=IN4500(ai, COMMAND)) & COMMAND_BUSY) {
    - OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
    - return 1;
    - }
    - return 0;
    -}
    -
    -/* Wait for busy completion from card
    - * wait for delay uSec's Return true
    - * for success meaning command reg is
    - * clear
    - */
    -int WaitBusy(struct airo_info *ai,int uSec){
    - int statword =0xffff;
    - int delay =0;
    -
    - while((statword & COMMAND_BUSY) && delay <= (1000 * 100) ){
    - udelay(10);
    - delay += 10;
    - statword = IN4500(ai,COMMAND);
    -
    - if((COMMAND_BUSY & statword) && (delay%200)){
    - unstickbusy(ai);
    - }
    - }
    - return 0 == (COMMAND_BUSY & statword);
    -}
     /*
      * STEP 1)
      * Disable MAC and do soft reset on
    -4323,12 +4402,13
      */
     
     int cmdreset(struct airo_info *ai) {
    - int status;
    + int flags;
     
             disable_MAC(ai);
     
    - if(!(status = WaitBusy(ai,600))){
    - printk(KERN_INFO "Waitbusy hang b4 RESET =%d\n",status);
    + spin_lock_irqsave(&ai->cmd_lock, flags);
    + if(!waitbusy (ai)){
    + printk(KERN_INFO "Waitbusy hang before RESET\n");
                     return -EBUSY;
             }
         
    -4336,10 +4416,11
     
             mdelay(1024); /* WAS 600 12/7/00 */
     
    - if(!(status=WaitBusy(ai,100))){
    - printk(KERN_INFO "Waitbusy hang AFTER RESET =%d\n",status);
    + if(!waitbusy (ai)){
    + printk(KERN_INFO "Waitbusy hang AFTER RESET\n");
                     return -EBUSY;
             }
    + spin_unlock_irqrestore(&ai->cmd_lock, flags);
             return 0;
     }
     
    -4349,15 +4430,17
      */
     
     int setflashmode (struct airo_info *ai) {
    - int status;
    + int flags;
     
    + spin_lock_irqsave(&ai->cmd_lock, flags);
             OUT4500(ai, SWS0, FLASH_COMMAND);
             OUT4500(ai, SWS1, FLASH_COMMAND);
             OUT4500(ai, SWS0, FLASH_COMMAND);
             OUT4500(ai, COMMAND,0x10);
             mdelay(500); /* 500ms delay */
    + spin_unlock_irqrestore(&ai->cmd_lock, flags);
       
    - if(!(status=WaitBusy(ai,600))) {
    + if(!waitbusy(ai)) {
                     printk(KERN_INFO "Waitbusy hang after setflash mode\n");
                     return -EIO;
             }
    -4370,7 +4453,7
     
     int flashpchar(struct airo_info *ai,int byte,int dwelltime) {
             int echo;
    - int pollbusy,waittime;
    + int waittime;
     
             byte |= 0x8000;
     
    -4379,36 +4462,25
       
             waittime=dwelltime;
     
    - /* Wait for busy bit d15 to
    - * go false indicating buffer
    - * empty
    - */
    - do {
    - pollbusy = IN4500(ai,SWS0);
    -
    - if(pollbusy & 0x8000){
    - udelay(50);
    - waittime -= 50;
    - } else
    - break;
    - } while(waittime >=0);
    + /* Wait for busy bit d15 to go false indicating buffer empty */
    + while ((IN4500 (ai, SWS0) & 0x8000) && waittime > 0) {
    + udelay (50);
    + waittime -= 50;
    + }
     
             /* timeout for busy clear wait */
    -
             if(waittime <= 0 ){
                     printk(KERN_INFO "flash putchar busywait timeout! \n");
                     return -EBUSY;
             }
     
    - /* Port is clear now write byte and
    - * wait for it to echo back
    - */
    - do{
    + /* Port is clear now write byte and wait for it to echo back */
    + do {
                     OUT4500(ai,SWS0,byte);
                     udelay(50);
                     dwelltime -= 50;
                     echo = IN4500(ai,SWS1);
    - }while (dwelltime >= 0 && echo != byte);
    + } while (dwelltime >= 0 && echo != byte);
     
             OUT4500(ai,SWS1,0);
     
    -4476,7 +4548,7
             status = setup_card(ai, dev->dev_addr,&((struct airo_info*)dev->priv)->config);
     
             for( i = 0; i < MAX_FIDS; i++ ) {
    - ai->fids[i] = transmit_allocate( ai, 2000 );
    + ai->fids[i] = transmit_allocate( ai, 2312 );
             }
     
             mdelay(1024); /* Added 12/7/00 */

    --UugvWAfsgieZRqgk--