⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 r8180_core.c

📁 rtl8180网卡在linux下的驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		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 + -