📄 r8180_core.c
字号:
e = create_proc_read_entry("stats-ieee", S_IFREG | S_IRUGO, priv->dir_dev, proc_get_stats_ieee, dev); if (!e) { DMESG("Unable to initialize " "/proc/net/rtl8180/%s/stats-ieee\n", dev->name); } e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO, priv->dir_dev, proc_get_stats_ap, dev); if (!e) { DMESG("Unable to initialize " "/proc/net/rtl8180/%s/stats-ap\n", dev->name); } e = create_proc_read_entry("registers", S_IFREG | S_IRUGO, priv->dir_dev, proc_get_registers, dev); if (!e) { DMESG("Unable to initialize " "/proc/net/rtl8180/%s/registers\n", dev->name); }}/**************************************************************************** -----------------------------MISC STUFF-------------------------*****************************************************************************//* FIXME: check if we can use some standard already-existent data type+functions in kernel*/void buffer_add(struct buffer **buffer, u32 *buf, dma_addr_t dma, struct buffer **bufferhead){#ifdef DEBUG_RING DMESG("adding buffer to TX/RX struct");#endif struct buffer *tmp; if(! *buffer){ *buffer = kmalloc(sizeof(struct buffer),GFP_KERNEL); if (*buffer == NULL) { DMESG ("EE: Failed to kmalloc TX/RX struct"); return; } (*buffer)->next=*buffer; (*buffer)->buf=buf; (*buffer)->dma=dma; if(bufferhead !=NULL) (*bufferhead) = (*buffer); return; } tmp=*buffer; while(tmp->next!=(*buffer)) tmp=tmp->next; if ((tmp->next= kmalloc(sizeof(struct buffer),GFP_KERNEL)) == NULL){ DMESG ("EE: Failed to kmalloc TX/RX struct"); return; } tmp->next->buf=buf; tmp->next->dma=dma; tmp->next->next=*buffer;}void buffer_free(struct net_device *dev,struct buffer **buffer,int len,short consistent){ struct buffer *tmp,*next; struct r8180_priv *priv = (struct r8180_priv *)dev->priv; struct pci_dev *pdev=priv->pdev; //int i; if(! *buffer) return; /*for(tmp=*buffer; tmp->next != *buffer; tmp=tmp->next) */ tmp=*buffer; do{ next=tmp->next; if(consistent){ pci_free_consistent(pdev,len, tmp->buf,tmp->dma); }else{ pci_unmap_single(pdev, tmp->dma, len,PCI_DMA_FROMDEVICE); kfree(tmp->buf); } kfree(tmp); tmp = next; } while(next != *buffer); *buffer=NULL;}void print_buffer(u32 *buffer, int len){ int i; u8 *buf =(u8*)buffer; printk("ASCII BUFFER DUMP (len: %x):\n",len); for(i=0;i<len;i++) printk("%c",buf[i]); printk("\nBINARY BUFFER DUMP (len: %x):\n",len); for(i=0;i<len;i++) printk("%x",buf[i]); printk("\n");}int get_curr_tx_free_desc(struct net_device *dev, int priority){ struct r8180_priv *priv = dev->priv; u32* tail; u32* head; switch (priority){ case LOW_PRIORITY: head = priv->txlpringhead; tail = priv->txlpringtail; break; case HI_PRIORITY: head = priv->txhpringhead; tail = priv->txhpringtail; break; case NORM_PRIORITY: head = priv->txnpringhead; tail = priv->txnpringtail; break; default: return -1; } //DMESG("%x %x", head, tail); if( head <= tail ) return priv->txringcount-1 - (tail - head)/8; return (head - tail)/8/4;}short check_nic_enought_desc(struct net_device *dev, int priority){ struct r8180_priv *priv = dev->priv; int requiredbyte, required; requiredbyte = priv->ieee80211->fts + sizeof(struct ieee80211_header_data); required = requiredbyte / (priv->txbuffsize-4); if (requiredbyte % priv->txbuffsize) required++; /* for now we keep two free descriptor as a safety boundary * between the tail and the head */ return (required+2 < get_curr_tx_free_desc(dev,priority));}/* This function is only for debuging purpose */ void check_tx_ring(struct net_device *dev, int pri){ static int maxlog =3; struct r8180_priv *priv = (struct r8180_priv *)dev->priv; u32* tmp; struct buffer *buf; int i; int nic; u32* tail; u32* head; u32* begin; u32 nicbegin; struct buffer* buffer; maxlog --; if (maxlog <0 ) return; switch(pri) { case LOW_PRIORITY: tail = priv->txlpringtail; begin = priv->txlpring; head = priv->txlpringhead; buffer = priv->txlpbufs; nic = read_nic_dword(dev,TX_LOWPRIORITY_RING_ADDR); nicbegin = priv->txlpringdma; break; case HI_PRIORITY: tail = priv->txhpringtail; begin = priv->txhpring; head = priv->txhpringhead; nic = read_nic_dword(dev,TX_HIGHPRIORITY_RING_ADDR); buffer = priv->txhpbufs; nicbegin = priv->txhpringdma; break; case NORM_PRIORITY: tail = priv->txnpringtail; begin = priv->txnpring; head = priv->txnpringhead; nic = read_nic_dword(dev,TX_NORMPRIORITY_RING_ADDR); buffer = priv->txnpbufs; nicbegin = priv->txnpringdma; break; default: return ; break; } if(!priv->txnpbufs) DMESG ("EE: NIC TX ack, but TX queue corrupted!"); else{ for(i=0,buf=buffer, tmp=begin; tmp<begin+(priv->txringcount)*8; tmp+=8,buf=buf->next,i++) DMESG("BUF%d %s %x %s. Next : %x",i, *tmp & (1<<31) ? "filled" : "empty", *(buf->buf), *tmp & (1<<15)? "ok": "err", *(tmp+4)); } DMESG("nic at %d", (nic-nicbegin) / 8 /4); DMESG("tail at %d", ((int)tail - (int)begin) /8 /4); DMESG("head at %d", ((int)head - (int)begin) /8 /4); DMESG("check free desc returns %d", check_nic_enought_desc(dev,pri)); DMESG("free desc is %d\n", get_curr_tx_free_desc(dev,pri)); //rtl8180_reset(dev); return;}void tx_timeout(struct net_device *dev){// struct r8180_priv *priv = (struct r8180_priv *)dev->priv; #ifdef DEBUG_TX_DESC check_tx_ring(dev,LOW_PRIORITY); check_tx_ring(dev,HI_PRIORITY); check_tx_ring(dev,NORM_PRIORITY);#endif rtl8180_commit(dev);}/* this function is only for debugging purpose */void check_rxbuf(struct net_device *dev){ struct r8180_priv *priv = (struct r8180_priv *)dev->priv; u32* tmp; struct buffer *buf; if(!priv->rxbuffer) DMESG ("EE: NIC RX ack, but RX queue corrupted!"); else{ for(buf=priv->rxbuffer, tmp=priv->rxring; tmp < priv->rxring+(priv->rxringcount)*4; tmp+=4, buf=buf->next) DMESG("BUF %s %x", *tmp & (1<<31) ? "empty" : "filled", *(buf->buf)); } return;}void dump_eprom(struct net_device *dev){ int i; for(i=0; i<63; i++) DMESG("EEPROM addr %x : %x", i, eprom_read(dev,i));}void rtl8180_dump_reg(struct net_device *dev){ int i; int n; int max=0xff; DMESG("Dumping NIC register map"); for(n=0;n<=max;) { printk( "\nD: %2x> ", n); for(i=0;i<16 && n<=max;i++,n++) printk("%2x ",read_nic_byte(dev,n)); } printk("\n");}void fix_tx_fifo(struct net_device *dev){ struct r8180_priv *priv = (struct r8180_priv *)dev->priv; u32 *tmp; int i;#ifdef DEBUG_TX_ALLOC DMESG("FIXING TX FIFOs");#endif for (tmp=priv->txnpring, i=0; i < priv->txringcount; tmp+=8, i++) { *tmp = *tmp &~ (1<<31); } for (tmp=priv->txhpring, i=0; i < priv->txringcount; tmp+=8,i++){ *tmp = *tmp &~ (1<<31); } for (tmp=priv->txlpring, i=0; i < priv->txringcount; tmp+=8, i++){ *tmp = *tmp &~ (1<<31); } for (tmp=priv->txbeaconring, i=0; i < priv->txbeaconcount; tmp+=8, i++){ *tmp = *tmp &~ (1<<31); }#ifdef DEBUG_TX_ALLOC DMESG("TX FIFOs FIXED");#endif priv->txlpringtail = priv->txlpring; priv->txlpringhead = priv->txlpring; priv->txlpbufstail = priv->txlpbufs; priv->txnpringtail = priv->txnpring; priv->txnpringhead = priv->txnpring; priv->txnpbufstail = priv->txnpbufs; priv->txhpringtail = priv->txhpring; priv->txhpringhead = priv->txhpring; priv->txhpbufstail = priv->txhpbufs; priv->txbeacontail = priv->txbeaconring; set_nic_txring(dev); ieee80211_r8180_reset_queue(priv->ieee80211); }void fix_rx_fifo(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)dev->priv; u32 *tmp; struct buffer *rxbuf; #ifdef DEBUG_RXALLOC DMESG("FIXING RX FIFO"); check_rxbuf(dev);#endif for (tmp=priv->rxring, rxbuf=priv->rxbufferhead; (tmp < (priv->rxring)+(priv->rxringcount)*4); tmp+=4,rxbuf=rxbuf->next){ *(tmp+2) = rxbuf->dma; *tmp=*tmp &~ 0xfff; *tmp=*tmp | priv->rxbuffersize; *tmp |= (1<<31); } #ifdef DEBUG_RXALLOC DMESG("RX FIFO FIXED"); check_rxbuf(dev);#endif priv->rxringtail=priv->rxring; priv->rxbuffer=priv->rxbufferhead; priv->rx_skb_complete=1; set_nic_rxring(dev);}void IBSS_randomize_cell(struct net_device *dev){ struct r8180_priv *priv = (struct r8180_priv *)dev->priv; /* must an IBSS cell addrest start with 0x00 or 0x02 ? * seems that my ipw2100 card doens't link on with * the Rtl8180 if the address is not in certain range */ priv->ieee80211->beacon_cell_ssid[0] = 2; get_random_bytes(priv->ieee80211->beacon_cell_ssid+1,ETH_ALEN-1);}/**************************************************************************** ------------------------------HW STUFF---------------------------*****************************************************************************/unsigned char QUALITY_MAP[] = { 0x64, 0x64, 0x64, 0x63, 0x63, 0x62, 0x62, 0x61, 0x61, 0x60, 0x60, 0x5f, 0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x57, 0x56, 0x54, 0x52, 0x4f, 0x4c, 0x49, 0x45, 0x41, 0x3c, 0x37, 0x31, 0x29, 0x24, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20, 0x1f, 0x1f, 0x1e, 0x1e, 0x1e, 0x1d, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a, 0x19, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x12, 0x11, 0x0f, 0x0e, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x01, 0x00};unsigned char STRENGTH_MAP[] = { 0x64, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 0x57, 0x54, 0x52, 0x50, 0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x41, 0x3f, 0x3c, 0x3a, 0x37, 0x36, 0x36, 0x1c, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b, 0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07, 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02, 0x00 };void rtl8180_RSSI_calc(struct net_device *dev, u8 *rssi, u8 *qual){ //void Mlme_UpdateRssiSQ(struct net_device *dev, u8 *rssi, u8 *qual){ struct r8180_priv *priv = (struct r8180_priv *)dev->priv; u32 temp; u32 temp2; u32 temp3; u32 lsb; u32 q; u32 orig_qual; u8 _rssi; q = *qual; orig_qual = *qual; _rssi = 0; // avoid gcc complains.. if (q <= 0x4e) { temp = QUALITY_MAP[q]; } else { if( q & 0x80 ) { temp = 0x32; } else { temp = 1; } } *qual = temp; temp2 = *rssi; switch(priv->rf_chip){ case RFCHIPID_RFMD: lsb = temp2 & 1; temp2 &= 0x7e; if ( !lsb || !(temp2 <= 0x3c) ) { temp2 = 0x64; } else { temp2 = 100 * temp2 / 0x3c; } *rssi = temp2 & 0xff; _rssi = temp2 & 0xff; break; case RFCHIPID_INTERSIL: lsb = temp2; temp2 &= 0xfffffffe; temp2 *= 251; temp3 = temp2; temp2 <<= 6; temp3 += temp2; temp3 <<= 1; temp2 = 0x4950df; temp2 -= temp3; lsb &= 1; if ( temp2 <= 0x3e0000 ) { if ( temp2 < 0xffef0000 ) temp2 = 0xffef0000; } else { temp2 = 0x3e0000; } if ( !lsb ) { temp2 -= 0xf0000; } else { temp2 += 0xf0000; } temp3 = 0x4d0000; temp3 -= temp2; temp3 *= 100; temp3 = temp3 / 0x6d; temp3 >>= 0x10; _rssi = temp3 & 0xff; *rssi = temp3 & 0xff; break; case RFCHIPID_GCT: lsb = temp2 & 1; temp2 &= 0x7e; if ( ! lsb || !(temp2 <= 0x3c) ){ temp2 = 0x64; } else { temp2 = (100 * temp2) / 0x3c; } *rssi = temp2 & 0xff; _rssi = temp2 & 0xff; break; case RFCHIPID_PHILIPS: if( orig_qual <= 0x4e ){ _rssi = STRENGTH_MAP[orig_qual]; *rssi = _rssi; } else { orig_qual -= 0x80; if ( !orig_qual ){ _rssi = 1; *rssi = 1; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -