--- ../ADM8211orig.notocar/Makefile 2003-06-25 05:31:11.000000000 +0200 +++ Makefile 2004-03-08 14:32:04.000000000 +0100 @@ -1,5 +1,5 @@ CC = gcc -FLAG = -D__KERNEL__ -DMODULE -Wall -Wstrict-prototypes -O2 -I/usr/src/linux-2.4/include -fomit-frame-pointer -fno-strict-aliasing -Wno-trigraphs -fno-common -pipe -mpreferred-stack-boundary=2 -march=i386 +FLAG = -D__KERNEL__ -DMODULE -Wall -Wstrict-prototypes -O2 -I/usr/src/linux-2.4/include -I/usr/src/linux/include -fomit-frame-pointer -fno-strict-aliasing -Wno-trigraphs -fno-common -pipe -mpreferred-stack-boundary=2 -march=i386 all: 8211.o --- ../ADM8211orig.notocar/adm8211.c 2003-06-25 05:33:47.000000000 +0200 +++ adm8211.c 2004-03-08 15:17:29.000000000 +0100 @@ -2,6 +2,15 @@ #define DRV_VERSION "1.05" #define DRV_RELDATE "June 24, 2003" +/* This driver was originally downloaded from ADMTek + * they hold copyright of the original code + * + * Modified by: Alejandro Grijalba (SuD) 2004 + * + * DISCLAIMER: No warranty of any kind + */ + + #include #include #include @@ -37,6 +46,8 @@ int csr0; +int modo_monitor=0; + // UM function extern void UM_Init_Module(STA_MDL *); extern void UM_MmIndicate(STA_MDL *, int, UINT8 *, int); @@ -64,6 +75,11 @@ extern void DefragmentPacketAssemble(LM_DEVICE_INFO * pLM_Device , BYTE *data, short pkt_len); +#ifndef IW_MODE_MONITOR + #define IW_MODE_MONITOR 6 + #warning YOU ARE USING AN OLD WIRELESS KERNEL DRIVER VERSION. Change includes, kernel, or whatever. +#endif + MODULE_AUTHOR("ADMtek"); MODULE_DESCRIPTION("ADM8211 Wireless netword card driver"); MODULE_LICENSE("Proprietary"); @@ -228,11 +244,19 @@ inl(ioaddr + CSR8); sum=0; + // Leer la direccion MAC de la tarjeta (se podra escribir?) + // modificar la variable leida no tiene efecto real + // enviar valores de salida al puerto modifica la memoria pero sigue sin cambiar la mac usada + //#warning JURL + //outl(0x01020304,ioaddr+0x94); + put_unaligned(le32_to_cpu(inl(ioaddr + 0x94)), (u32 *) dev->dev_addr); put_unaligned(le16_to_cpu(inl(ioaddr + 0x98)), (u16 *) (dev->dev_addr + 4)); for (i = 0; i < 6; i++) sum += dev->dev_addr[i]; + + sa_offset = 0; ee_addr_size = read_eeprom(ioaddr, 0xff, 8) & 0x40000 ? 8 : 6; eeprom_word_cnt = 1 << ee_addr_size; @@ -247,7 +271,11 @@ { ((u16 *) ee_data)[i] = le16_to_cpu(read_eeprom(ioaddr, i,ee_addr_size)); memcpy(&pDevice->LM_Device.Eeprom, ee_data, sizeof(pDevice->Eeprom)); +// printk("%04x ",(int)((u16 *)ee_data)[i]); +// printk("%c%c",(char)((u16 *)ee_data)[i]%256,(char)((u16 *)ee_data)[i]/256); } + printk("\n"); + // printk("La eeprom %d %d\n",eeprom_word_cnt,sizeof(pDevice->Eeprom)); //Read transceiver type switch (pDevice->Eeprom.SpecificRFType) { @@ -317,10 +345,16 @@ spin_lock_init(&lock); + modo_monitor=0; + pDevice->STA_Module.MDL_pDrvObj = (unsigned long*)dev; pDevice->LM_Device.MDL_pDrvObj = (unsigned long*)(&(pDevice->STA_Module)); Software_Init(&(pDevice->LM_Device)); - + +/*printk("tipo de arp %d\n",(int)dev->type); + dev->type = ARPHRD_IEEE80211; +printk("tipo de arp %d vs %d\n",(int)(dev->type),ARPHRD_IEEE80211); +*/ return 0; ERR_OUT: @@ -419,18 +453,23 @@ return 0; } +// Called each 2 seconds to compute statistics static void CheckForHangTimer(unsigned long data) { struct net_device *dev = (struct net_device *) data; struct adm8201_private *pDevice = (struct adm8201_private *) dev->priv; int next_tick = 2 * HZ; int i,j; -/*Jeffrey: for link quality*/ + + printk("check for hang timer\n"); + + + /*Jeffrey: for link quality*/ if ( (pDevice->STA_Module.MDL_Current_Action == ALL_COMPLETE ) && - (pDevice->STA_Module.MDL_Operation_Mode == 1 ) ) + (pDevice->STA_Module.MDL_Operation_Mode == 1 ) ) // Managed { - + printk("op 1\n"); pDevice->linkquality=(int)((pDevice->beaconcount*(pDevice->STA_Module.MDL_AP_Info[pDevice->STA_Module.MDL_AP_Inuse_Index].Beacon_Interval))/20); if(pDevice->linkquality > 96) { @@ -444,6 +483,7 @@ (pDevice->STA_Module.MDL_Operation_Mode == Ndis802_11IBSS ) ) { + printk("op adhoc\n"); if (pDevice->LM_Device.BeaconCount != 0) { pDevice->LM_Device.BeaconCount = 0; @@ -465,7 +505,7 @@ if( (pDevice->STA_Module.MDL_Assoc_Complete == 1) || (pDevice->STA_Module.MDL_Current_Action == ALL_COMPLETE) ) { - + printk("assoc complete\n"); if (pDevice->LM_Device.Start_Tx == 0) { #ifdef adm8201_debug @@ -507,6 +547,7 @@ (pDevice->LM_Device.RevisionStep == REVISION_BA) && (pDevice->RxPacketCountPer2S == 0) ) { + printk("check dxfer state\n"); LM_CheckDxferState(dev); } pDevice->RxPacketCountPer2S = 0; @@ -566,6 +607,18 @@ } + BYTE canalon=-1; +int i; +#define w(x) ((x>31)?(x<127?x:'.'):'.') + +#ifdef packet_debug + #define VOLCAR {if (packet_debug > 1) { printk("Channel %d\n", canalon); for (i=0;idata[i+0]),w(skb->data[i+1]),w(skb->data[i+2]),w(skb->data[i+3]),w(skb->data[i+4]),w(skb->data[i+5]),w(skb->data[i+6]),w(skb->data[i+7])); i=i+8; } printk("%02x ",skb->data[i]); } printk("\n"); }} +#else + #define VOLCAR ; +#endif + + +// HACK THIS TO AVOID XMIT IN MOnITOR static int adm8201_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct adm8201_private *pDevice = (struct adm8201_private *) dev->priv; @@ -573,6 +626,12 @@ u32 flag; int Length1,Length2; +//#warning this is not nice! if i try to hack this i get crash +//if (modo_monitor){ +// return -EINVAL; +//}else +{ + /* Calculate the next Tx descriptor entry. */ entry = pDevice->cur_tx % TX_RING_SIZE; @@ -584,13 +643,17 @@ //convert 802.3 header to 802.11 +printk("start_xmint antes y despues\n"); + int pkt_len=skb->len; VOLCAR; skb->data = (unsigned char *)UM_3to11(&(pDevice->STA_Module), (unsigned char *)&(pDevice->MSDU[entry].Content), &Length1, skb->data, &Length2); + VOLCAR; + pDevice->tx_ring[entry].buffer1 = virt_to_le32desc(&(pDevice->MSDU[entry].Content)); pDevice->tx_ring[entry].buffer2 = virt_to_le32desc(skb->data); - if (q_used_cnt < TX_QUEUE_LEN / 2) + if (q_used_cnt < TX_QUEUE_LEN / 2) { /* Typical path */ flag = 0x60000000; /* No interrupt */ } @@ -632,7 +695,7 @@ dev->trans_start = jiffies; /* Trigger an immediate transmit demand. */ outl(0, dev->base_addr + CSR1); - +} return 0; } @@ -671,6 +734,7 @@ if (csr5 & (RxIntr | RxNoBuf)) { + // Esta es la manera normal de recibir work_budget -= adm8201_rx_interrupt(dev); } @@ -689,7 +753,7 @@ /* Log errors. */ if (csr5 & AbnormalIntr) { /* Abnormal error summary bit. */ - + printk("Interrupcion anormal\n"); if (csr5 == 0xffffffff) break; @@ -827,6 +891,20 @@ pDevice->dirty_tx = dirty_tx; } + +//#define compact_logs 1 + +#ifdef compact_logs + // Si agrupamos los cambios de canales en multiplos de 14 salen todos iguales + #define MAXENTRADAS 14*5 + BYTE canales[MAXENTRADAS]; + int tCanales=0; + int itmp; +#endif + + + + static int adm8201_rx_interrupt(struct net_device *dev) { struct adm8201_private *pDevice = (struct adm8201_private *) dev->priv; @@ -839,7 +917,22 @@ BYTE FragmentNum = 0; BYTE TypeValue, num ; int len; +#ifdef defragment_debug + // Original code forgot this declaration + int i; +#endif + + +// NOTA Aqui podriamos situar el modo monitor? +#ifdef adm8201_debug +// printk(" %d ",adm8201_debug); + if (adm8201_debug > 6) { + printk("%s: First in adm8201_rx_interrupt(), entry %d.\n", + dev->name, entry); + } +#endif + /* If we own the next entry, it is a new packet. Send it up. */ while (!(pDevice->rx_ring[entry].status & cpu_to_le32(DescOwned))) { @@ -848,13 +941,14 @@ pDevice->rx_ring[entry].length = cpu_to_le32(pDevice->RDES1[entry]); -#ifdef adm8201_debug +#ifdef adm8201_debug_NO if (adm8201_debug > 5) { - printk(KERN_DEBUG "%s: In adm8201_rx_interrupt(), entry %d %8.8x.\n", + printk("%s: In adm8201_rx_interrupt(), entry %d %8.8x.\n", dev->name, entry, status); } #endif + if (--rx_work_limit < 0) { printk("rx_work_limit < 0 \n"); break; @@ -876,11 +970,15 @@ skb_put(skb = pDevice->rx_skbuff[entry], pkt_len); TypeValue = (skb->data[0] & 0x0f); + #ifdef packet_debug_VAAALE + #endif switch (TypeValue) { - case MANAGMENT_FRAME: + case MANAGMENT_FRAME: // Beacons #ifdef packet_debug - printk("cf = %02x %02x .....\n",skb->data[0],skb->data[1]); + printk("mf = %02x %02x .....\n",skb->data[0],skb->data[1]); #endif + // printk ("0x%X\n",(int)pDevice->STA_Module.MDL_TX_Power ); + // Si el AP que lo emite es el actual aumenta beaconcount /*Jeffrey: for link quality*/ if(skb->data[0]==0x80 &&skb->data[16]== @@ -903,16 +1001,48 @@ ) { pDevice->beaconcount++ ; - } + } + //VOLCAR; TypeValue = (skb->data[0] & 0xf0); - UM_MmIndicate(&(pDevice->STA_Module), TypeValue, skb->data, pkt_len); - dev_kfree_skb(skb); + // so if we ignore this entries will it be quiet? + if (modo_monitor) { + skb->len = pkt_len; + //VOLCAR; + // Indicate to Upper layer + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); + dev->last_rx = jiffies; + //#warning below line must be removed + //UM_MmIndicate(&(pDevice->STA_Module), TypeValue, skb->data, pkt_len); + } else { + UM_MmIndicate(&(pDevice->STA_Module), TypeValue, skb->data, pkt_len); + dev_kfree_skb(skb); + } + break; case CONTROL_FRAME: - dev_kfree_skb(skb); + #ifdef packet_debug + printk("cf = %02x %02x .....\n",skb->data[0],skb->data[1]); + #endif + VOLCAR; + + if (modo_monitor) { + skb->len = pkt_len; + //VOLCAR; + // Indicate to Upper layer + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); + dev->last_rx = jiffies; + } else + dev_kfree_skb(skb); break; case DATA_FRAME: + #ifdef packet_debug + printk("df = %02x %02x .....\n",skb->data[0],skb->data[1]); + //VOLCAR; + #endif + // Fragments FragmentNum = skb->data[22] & 0x0f; MoreFragment = skb->data[1] & 0x04; @@ -925,7 +1055,8 @@ skb->data[14] == pDevice->STA_Module.MDL_STA_MAC[4] && skb->data[15] == pDevice->STA_Module.MDL_STA_MAC[5]) { - printk(" receive myselt packet \n"); + printk(" receive myselt broadcast packet \n"); + // dont free in monitor mode dev_kfree_skb(skb); } @@ -988,10 +1119,12 @@ } } - skb->data = (unsigned char *)UM_11to3(&(pDevice->STA_Module), skb->data, &pkt_len); + if (!modo_monitor) { + skb->data = (unsigned char *)UM_11to3(&(pDevice->STA_Module), skb->data, &pkt_len); } skb->len = pkt_len; + //VOLCAR; // Indicate to Upper layer skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); @@ -1001,6 +1134,17 @@ break; default: + #ifdef packet_debug + printk("packet type unknown! (error?) = %02x %02x .....\n",skb->data[0],skb->data[1]); + #endif + // i wonder why original driver didnt skb-free here + + //warning, this is untested, hope it doesnt crash + skb->len = pkt_len; + // Indicate to Upper layer + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); + dev->last_rx = jiffies; break; } } //if ( status & BIT_30 ) @@ -1107,7 +1251,7 @@ return 0; } - +static int tenita=0; static struct net_device_stats *adm8201_get_stats(struct net_device *dev) { struct adm8201_private *pDevice = (struct adm8201_private *) dev->priv; @@ -1138,10 +1282,9 @@ BYTE AP_Num; int index; - +printk("ioctl\n"); if (! netif_device_present(dev)) return -ENODEV; - switch (cmd) { case SIOCGIWNAME: /* get name == wireless protocol */ @@ -1157,6 +1300,7 @@ if( (pDevice->STA_Module.MDL_Assoc_Complete == 1) || ( pDevice->STA_Module.MDL_Current_Action == ALL_COMPLETE ) ) { + // Esta funcion esta implementada en codigo cerrado UM_Query_Information(&(pDevice->STA_Module), OID_802_11_BSSID, wrq->u.ap_addr.sa_data, &query_len); } else @@ -1254,6 +1398,11 @@ return -EFAULT; break; + #warning i guess this case is wrong... i should have never added it + case SIOCSIFHWADDR: + printk("amos a intentarlo"); + break; + case SIOCSIWMODE: /* set operation mode */ #ifdef ioctl_debug printk("Set operation mode %x\n",wrq->u.mode); @@ -1264,18 +1413,64 @@ #ifdef ioctl_debug printk("this is ADHOC mode \n"); #endif + dev->type = ARPHRD_ETHER; pDevice->LM_Device.iw_mode = Ndis802_11IBSS; pDevice->STA_Module.MDL_Operation_Mode = Ndis802_11IBSS; //set adhoc mode + modo_monitor=0; break; case IW_MODE_INFRA: pDevice->LM_Device.iw_mode = Ndis802_11Infrastructure; pDevice->STA_Module.MDL_Operation_Mode = Ndis802_11Infrastructure; //set infrastructure mode + modo_monitor=0; + dev->type = ARPHRD_ETHER; #ifdef ioctl_debug printk("this is infrastructure mode \n"); #endif break; + case IW_MODE_MONITOR: + #ifdef ioctl_debug + printk("this is Monitor mode \n"); + #endif + dev->type = ARPHRD_IEEE80211; + modo_monitor=1; + + // What mode use here? + // IBSS and Auto give weird results, non-periodic packet bursts + // But managed gives as expected periodic small bursts + + //pDevice->LM_Device.iw_mode = Ndis802_11AutoUnknown; + //pDevice->STA_Module.MDL_Operation_Mode = Ndis802_11AutoUnknown; //set adhoc? mode +#warning none of these modes are really passive rfmon + pDevice->LM_Device.iw_mode = Ndis802_11Infrastructure; + pDevice->STA_Module.MDL_Operation_Mode = Ndis802_11Infrastructure; //set infrastructure mode + // pDevice->LM_Device.iw_mode = Ndis802_11IBSS; + // pDevice->STA_Module.MDL_Operation_Mode = Ndis802_11IBSS; //set adhoc? mode +// RF_SetAntenna(&(pDevice->LM_Device), tenita++ ); +// tenita=tenita%3; + // printk ("0x%X\n",(int)pDevice->STA_Module.MDL_TX_Power ); + // + // + // Deassociate and set ESSID to "any" + query_len = 3; + query_buf[0]='a'; + query_buf[1]='n'; + query_buf[2]='y'; + + UM_Set_Information(&(pDevice->STA_Module), OID_802_11_SSID, query_buf, &query_len); + + if( ( pDevice->LM_Device.UmInitModule_Flag == 0 ) && (pDevice->LM_Device.Start_ADM8211 == 1) ) + { // Dont know what this means, but this condition is true almost always + //only for iwcofnig use + #ifdef ioctl_debug + printk("ioctl set ssid call UM_Init_Module \n"); + #endif + UM_Init_Module(&pDevice->STA_Module); + } + break; + + default: #ifdef ioctl_debug printk(" not support mode \n"); @@ -1286,6 +1481,9 @@ break; case SIOCGIWMODE: /* get operation mode */ + if (modo_monitor == 1) + wrq->u.mode = IW_MODE_MONITOR; + else switch(pDevice->LM_Device.iw_mode) { case Ndis802_11Infrastructure: @@ -1446,6 +1644,7 @@ printk(" %x ",query_buf[i]); printk("\n"); #endif + // Curioso: "" -> "any" if(query_len == 0) { query_len = 3; @@ -1498,6 +1697,9 @@ break; case SIOCGIWNICKN: /* get node name/nickname */ +// printk("poniendo tenita %d",tenita%5); + +// RF_SetAntenna(&(pDevice->LM_Device), tenita++%5 ); if (pDevice->LM_Device.NicName[0] != 0 ) { memcpy(query_buf, pDevice->LM_Device.NicName, IW_ESSID_MAX_SIZE+1); @@ -1512,13 +1714,15 @@ #ifdef ioctl_debug printk("set channel/freq value =%d , type=%x\n",wrq->u.freq.m ,wrq->u.freq.e); #endif - if ( wrq->u.freq.e == 1 ) + #warning i dont like this code, but it works + if ( wrq->u.freq.e == 1 ) // case freq { for (i=0;i<14;i++) { if ( wrq->u.freq.m == channel_frequency[i] ) { wrq->u.freq.m=i+1; + #warning =1 o =i ? pDevice->LM_Device.freq_channel=1; break; } @@ -1538,15 +1742,17 @@ { UM_Set_Information(&(pDevice->STA_Module), OID_802_11_CHANNEL, query_buf, &query_len); } + if (modo_monitor) { + // Y esto es lo que habria que hacer + RF_SetChannel(&(pDevice->LM_Device),wrq->u.freq.m); + } break; case SIOCGIWFREQ:/* get channel/frequency (Hz) */ - if( (pDevice->STA_Module.MDL_Assoc_Complete == 1) || ( pDevice->STA_Module.MDL_Current_Action == ALL_COMPLETE ) ) { UM_Query_Information(&(pDevice->STA_Module), OID_802_11_CHANNEL, query_buf, &query_len); - if ( pDevice->LM_Device.freq_channel == 0 ) { wrq->u.freq.m = query_buf[0]; @@ -1565,6 +1771,16 @@ wrq->u.freq.m = 0 ; } wrq->u.freq.e = 1; // 0: chnnel 1:freq + if (modo_monitor) { + if (pDevice->STA_Module.MDL_Channel <= NUM_CHANNELS && pDevice->STA_Module.MDL_Channel >=1) { + wrq->u.freq.m = channel_frequency[pDevice->STA_Module.MDL_Channel-1]; + wrq->u.freq.e = 1; + } else { + wrq->u.freq.m = pDevice->STA_Module.MDL_Channel; + wrq->u.freq.e = 0; + } + } + break; case SIOCSIWSENS:/* set sensitivity (dBm) */ @@ -1664,7 +1880,8 @@ break; /* ************* end of Power saving *********** */ case SIOCSIWTXPOW:/* set transmit power (dBm) */ - + // NOTA Esto mandara cualquier valor de dBm < 64 a la capa inferior! + // La capa inferior (LM/UM) no se queja, pero no se si hace caso #ifdef ioctl_debug printk("Set TxPower value =%d fixed=%x disabled=%x flags=%x \n",wrq->u.txpower.value, wrq->u.txpower.fixed, wrq->u.txpower.disabled, wrq->u.txpower.flags); @@ -1678,6 +1895,7 @@ { if( wrq->u.txpower.value == -1 ) { + // Por eso sale el 47dBm wrq->u.txpower.value=0x2f; } pDevice->LM_Device.TxPowerFlag=Enable; @@ -1732,6 +1950,7 @@ err = -EOPNOTSUPP; break; + //NOTA Mmm... esto funciona? probar iwlist ap case SIOCGIWAPLIST: if (wrq->u.data.pointer) { @@ -1884,14 +2103,16 @@ /* it should be done init_timer before call this function */ /* del_timer(&LM_timer_list) in adm8201-close */ /************************************************************************/ - +// Called very frequently (~10 per second), when not associated int LOCAL_Timer_func(STA_MDL * pSTA_Module) { +// printk("Timer func\n"); + #warning we may want not to call this pSTA_Module->MDL_Time_Function((unsigned long *)pSTA_Module); LM_timer_list.function = (void *)LOCAL_Timer_func; LM_timer_list.expires = jiffies + pSTA_Module->MDL_Time; - if (pSTA_Module->MDL_Current_Action != 0x10) { + if (pSTA_Module->MDL_Current_Action != 0x10) { // 0x10 = ALL_COMPLETE add_timer(&LM_timer_list); } @@ -1926,6 +2147,7 @@ /************************************************************************/ /* Send packet Function */ /************************************************************************/ +// Used for sending probe requests void LM_Send_Packet(STA_MDL * pSTA_Module) { struct net_device *dev1 = (struct net_device *) pSTA_Module->MDL_pDrvObj; @@ -1934,17 +2156,26 @@ u32 flag; s32 Status; +if (modo_monitor) { + dev1->trans_start = jiffies; +}else { struct sk_buff *skb = dev_alloc_skb(512); +// printk("send packet\n"); + entry = pDevice->cur_tx % TX_RING_SIZE; q_used_cnt = pDevice->cur_tx - pDevice->dirty_tx; pDevice->tx_skbuff[entry] = skb; memcpy(skb_put(skb, pSTA_Module->MDL_TX_Len), pSTA_Module->MDL_TX_Buf, pSTA_Module->MDL_TX_Len); + int pkt_len=pSTA_Module->MDL_TX_Len; +//VOLCAR; UM_Free_Memory(pSTA_Module); - + pDevice->tx_ring[entry].buffer1 = virt_to_le32desc(skb->data); +//VOLCAR2( pDevice->tx_ring[entry].buffer1); + if (q_used_cnt < TX_QUEUE_LEN / 2) { /* Typical path */ flag = 0x60000000; /* No interrupt */ @@ -1982,7 +2213,7 @@ dev1->trans_start = jiffies; /* Trigger an immediate transmit demand. */ outl(0, dev1->base_addr + CSR1); - +} } /************************************************************************/ @@ -2036,16 +2267,34 @@ return Value8; } +int despacio=0; + void LM_Set_Channel(STA_MDL * pSTA_Module, BYTE channel) { struct net_device *dev1 =(struct net_device *) pSTA_Module->MDL_pDrvObj; struct adm8201_private *pDevice = (struct adm8201_private *) dev1->priv; #ifdef adm8201_debug - printk(" set channel %d \n",channel); + #ifdef compact_logs + if (tCanales==MAXENTRADAS) { + printk(" set channel"); + for (itmp=0; itmpLM_Device),channel); +// nice nice nice, we can help it hop channels at this callback + despacio++; +// RF_SetChannel(&(pDevice->LM_Device),(despacio%100)/10+1); } void LM_SetAntenna(STA_MDL * pSTA_Module , int Antenna )