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

📄 zd1211.c

📁 该代码为linux下通过usb驱动实现的无线网络驱动程序,在2.6.18的内核下调试通过
💻 C
📖 第 1 页 / 共 5 页
字号:
		up(&macp->reg_sem);
		return 0;
	}

   	pRegBuffer = kmalloc(size, GFP_KERNEL);

	if (!pRegBuffer) {
		up(&macp->reg_sem);
		return -ENOMEM;
	}else
		memset(pRegBuffer, 0x0, size);

	((PUSB_READ_REG_REQ)pRegBuffer)->RequestID  = zd_cpu_to_le16(REGID_READ);

	for (ii = 0; ii < RegCount; ii ++){
		if ((Address[ii] & BASE_ADDR_MASK_HOST) == USB_BASE_ADDR_HOST)
			Address[ii] = Address[ii] - USB_BASE_ADDR_HOST + macp->AddrEntryTable;
		else if ((Address[ii] & BASE_ADDR_MASK_HOST) == USB_BASE_ADDR_EEPROM)
			Address[ii] = ((Address[ii] - USB_BASE_ADDR_EEPROM) / 2) + cFIRMWARE_EEPROM_OFFSET;
                                         //0x9900                     //0xF817
		((PUSB_READ_REG_REQ) pRegBuffer)->Address[ii] = zd_cpu_to_le16(Address[ii]);
	}

	bufSize = sizeof(u16) * (1+RegCount);

	if (macp->ep4isIntOut)
		usb_fill_int_urb(macp->reg_urb, macp->usb,
			usb_sndintpipe(macp->usb, EP_REG_OUT),
			pRegBuffer, bufSize, 
			zd1211_reg_cb, macp, 1);
	else
		usb_fill_bulk_urb(macp->reg_urb, macp->usb,
			usb_sndbulkpipe(macp->usb, EP_REG_OUT),
			pRegBuffer, bufSize,
			zd1211_reg_cb, macp);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14))                         
	macp->reg_urb->transfer_flags |= URB_ASYNC_UNLINK;     
#endif

	if ((ret = SUBMIT_URB(macp->reg_urb, GFP_ATOMIC))){
		printk(KERN_ERR "zd1211: failed reg_urb\n");
		zd1211_DumpErrorCode(macp, ret);
		up(&macp->reg_sem);
		kfree(pRegBuffer);	
		return ret;
	}
    	
	//wait command complete
	macp->regWaitRCompCnt++;
	//printk(KERN_ERR "before wait 4\n");
	wait_event(macp->regSet_wait, test_bit(ZD1211_CMD_FINISH, &macp->flags));
	//printk(KERN_ERR "after wait 4\n");
	macp->regRWCompCnt++;

	clear_bit(ZD1211_CMD_FINISH, &macp->flags);
	kfree(pRegBuffer);		

	if (ret != 0)
		goto out;

	//wait response complete
	macp->regWaitRspCnt++;

#if 0//(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))      
	if (wait_event_interruptible_timeout(macp->iorwRsp_wait, test_bit(ZD1211_REQ_COMP, &macp->flags), HZ/2)){ //use it, we may can't wake up

		//interrupt by a signal
		memset(macp->IntEPBuffer, 0, MAX_EPINT_BUFFER);
		macp->regUnCompCnt++;
		ret = -ERESTARTSYS;
		goto out;
	}
	else
		macp->regRspCompCnt++; 
#else
//#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))      
    //interruptible_sleep_on_timeout(&macp->iorwRsp_wait, 1); //magic delay 
    //20060809 MZCai. the interruptible... has race condition issue. 
    //We don't use it anymore in 2.6.x. 
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))      
    wait_event_interruptible_timeout(macp->iorwRsp_wait, 0, 1); 
#else
    interruptible_sleep_on_timeout(&macp->iorwRsp_wait, 1); //magic delay
#endif


	//interruptible_sleep_on_timeout(&macp->iorwRsp_wait, HZ/40); //magic delay
	if (!test_bit(ZD1211_REQ_COMP, &macp->flags)){
		//check if Rsp has completed, race condition may happen,
		macp->regRdSleepCnt++;
		//we waste time_out time
	//printk(KERN_ERR "before wait 2\n");
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))      
    wait_event_interruptible_timeout(macp->iorwRsp_wait, 0, HZ/10);
#else
    interruptible_sleep_on_timeout(&macp->iorwRsp_wait, HZ/10); //magic delay
#endif
	//wake up, check if timeout or ompleted

	}
	if (test_bit(ZD1211_REQ_COMP, &macp->flags))
		macp->regRspCompCnt++;
	else{
		memset(macp->IntEPBuffer, 0x0, MAX_EPINT_BUFFER);
		macp->regUnCompCnt++;
		ret = -1;
		goto out;
	}
#endif

	// Get data
	if ((macp->ReadRegCount == 0) || (macp->ReadRegCount > MAX_EPINT_BUFFER)){
		ret = 1;
	}    
	else {
		for (ii = 0; ii < (macp->ReadRegCount-2) / 4; ii++){
            pValue[ii] = zd_get_LE_U16(macp->IntEPBuffer2+(1+ii*2+1)*2);
		}    
		ret = 0;    
	}

out:
	clear_bit(ZD1211_REQ_COMP, &macp->flags);  
	up(&macp->reg_sem);
	return ret;	
}	                          
                          
u32 zd1211_readl(u32 Address, u8 bAddUSBCSRAddress)
{
	struct zd1205_private *macp = g_dev->priv;

	u16  ReadAddr[2];
	u16  ReadData[2];
	int bRet = 1;
	u32 value;
	int count = 0;

	if (bAddUSBCSRAddress && Address < 0x8000){
		Address += macp->USBCSRAddress;

		if ((Address & BASE_ADDR_MASK_HOST) == USB_BASE_ADDR_HOST)
			ReadAddr[1] = (u16) Address + 1;
		else
			ReadAddr[1] = (u16) Address + 2;
	}
	else
		ReadAddr[1] = (u16) Address + 1;

	ReadAddr[0] = (u16) Address;    // Read Low Word first

	while (bRet != 0){
		bRet = zd1211_USB_PACKAGE_READ_REGISTER(ReadAddr, ReadData, 2, false);
		count++;
		
		if (count > 5){
			printk(KERN_ERR "1211_readl failed for 5 attempts...Very Serious");
			break;
		}
	}
    
	value = (((u32) ReadData[1]) << 16) + ReadData[0];
	return value;
}

//return 0: success
int zd1211_USB_PACKAGE_WRITE_REGISTER(u16 *Address, u16 *Value, u16 RegCount, u8 bAddUSBCSRAddress)
{
	struct zd1205_private *macp = g_dev->priv;
	u8 *pRegBuffer = NULL;
	int ret;
	u16 size = sizeof(USB_WRITE_REG);
	u16 bufSize;
	int i;

#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
	if (in_interrupt()){
#else
	if (in_atomic()){
#endif
		FPRINT("********zd1211_USB_PACKAGE_WRITE_REGISTER in_interrupt*********");
		return 0;
	}

 	down(&macp->reg_sem);	    
		
	if ((RegCount == 0) || (!macp->bUSBDeveiceAttached) || !test_bit(ZD1211_RUNNING, &macp->flags)) {	
		up(&macp->reg_sem);	 
		return 0;
	}	
 
	pRegBuffer = kmalloc(size, GFP_KERNEL);
	if (!pRegBuffer) {
		up(&macp->reg_sem);
		return -ENOMEM;
	}
	else
		memset(pRegBuffer, 0x0, size);

	((PUSB_WRITE_REG)pRegBuffer)->RequestID	= zd_cpu_to_le16(REGID_WRITE);

	if (RegCount > cMIN_MULTI_WRITE_REG_NUM){
		for (i=cMIN_MULTI_WRITE_REG_NUM; i<RegCount; i++){
			if (bAddUSBCSRAddress)
				Address[i] += macp->USBCSRAddress;
                
			if ((Address[i] & BASE_ADDR_MASK_HOST) == USB_BASE_ADDR_HOST)
				Address[i] = Address[i] - USB_BASE_ADDR_HOST + macp->AddrEntryTable;
			else if ((Address[i] & BASE_ADDR_MASK_HOST) == USB_BASE_ADDR_EEPROM)
				Address[i] = ((Address[i] - USB_BASE_ADDR_EEPROM) / 2) + cFIRMWARE_EEPROM_OFFSET;

			((PUSB_WRITE_REG)pRegBuffer)->WritePackage[i].Address = zd_cpu_to_le16(Address[i]);
			((PUSB_WRITE_REG)pRegBuffer)->WritePackage[i].WriteData_low = zd_cpu_to_le16(Value[i]);
		}
	}

	bufSize = sizeof(u16) * (1+RegCount*2);

	if (macp->ep4isIntOut)                      
		usb_fill_int_urb(macp->reg_urb, macp->usb,
			usb_sndintpipe(macp->usb, EP_REG_OUT),
			pRegBuffer, bufSize, 
			zd1211_reg_cb, macp, 1);
	else
		usb_fill_bulk_urb(macp->reg_urb, macp->usb,
			usb_sndbulkpipe(macp->usb, EP_REG_OUT),
			pRegBuffer, bufSize,
			zd1211_reg_cb, macp);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14))
	macp->reg_urb->transfer_flags |= URB_ASYNC_UNLINK;	     
#endif

	if ((ret = SUBMIT_URB(macp->reg_urb, GFP_ATOMIC))){
		printk(KERN_ERR "zd1211: failed reg_urb\n");
		zd1211_DumpErrorCode(macp, ret);
		goto out;
	}	
	
	macp->regWaitWCompCnt++;
	wait_event(macp->regSet_wait, test_bit(ZD1211_CMD_FINISH, &macp->flags));

	macp->regRWCompCnt++;
	clear_bit(ZD1211_CMD_FINISH, &macp->flags);
     
out:
	kfree(pRegBuffer);
	up(&macp->reg_sem);
	return ret;	
}

int zd1211_WriteMultiRegister(u16 *Address, u16 *Value, u16 RegCount, u8 bAddUSBCSRAddress)
{
	int ret = 1;
	int count = 0;

	while (ret != 0){
   		ret = zd1211_USB_PACKAGE_WRITE_REGISTER(Address, Value, RegCount, bAddUSBCSRAddress);

   		count++;
		if (count > 5){
			FPRINT("zd1211_WriteMultiRegister failed");
			break;
		}
	}

   	return ret;	
}                                    	                            
                          

//return 0: success
int zd1211_writel(u32 Address, u32 Value, u8 bAddUSBCSRAddress)
{
	struct zd1205_private *macp = g_dev->priv;
#ifdef fQuickPhySet

	u8	bIsPhyReg = 0;
#endif

	
	u16  WriteAddr[6];
	u16  WriteData[6];
	int ret = 1;
	int count = 0;

#ifdef fQuickPhySet

	if (bAddUSBCSRAddress && (Address <= ZD1205_PHY_END))

		bIsPhyReg = 1;
#endif
  

#ifdef fQuickPhySet
	if (bIsPhyReg){
		u32	tmpvalue;

		tmpvalue = zd_readl(CtlReg1);
		tmpvalue &= ~0x80;
		{
			if (((macp->USBCSRAddress+CtlReg1) & BASE_ADDR_MASK_HOST) == USB_BASE_ADDR_HOST)
				WriteAddr[0] = (u16) (macp->USBCSRAddress+CtlReg1) + 1;
			else

				// must write High word first
				WriteAddr[0] = (u16) (macp->USBCSRAddress+CtlReg1) + 2;
		}
		WriteData[0] = (u16) (tmpvalue >> 16);

		WriteAddr[1] = (u16) (macp->USBCSRAddress+CtlReg1);

		WriteData[1] = (u16) (tmpvalue & 0xFFFF);

 		if (bAddUSBCSRAddress ){
			Address += (u16) (macp->USBCSRAddress);
			if ((Address & BASE_ADDR_MASK_HOST) == USB_BASE_ADDR_HOST)
				WriteAddr[2] = (u16) Address + 1;
			else
				// must write High word first
				WriteAddr[2] = (u16) Address + 2;
		}
		else
			WriteAddr[2] = (u16) Address + 1;

		WriteData[2] = (u16) (Value >> 16);
		WriteAddr[3] = (u16) Address;

		WriteData[3] = (u16) (Value & 0xFFFF);


		tmpvalue |= 0x80;
		{

			if (((macp->USBCSRAddress+CtlReg1) & BASE_ADDR_MASK_HOST) == USB_BASE_ADDR_HOST)

				WriteAddr[4] = (u16) (macp->USBCSRAddress+CtlReg1) + 1;
			else
				// must write High word first
				WriteAddr[4] = (u16) (macp->USBCSRAddress+CtlReg1) + 2;
		}
		WriteData[4] = (u16) (tmpvalue >> 16);
		WriteAddr[5] = (u16) (macp->USBCSRAddress+CtlReg1);
		WriteData[5] = (u16) (tmpvalue & 0xFFFF);

		return zd1211_USB_PACKAGE_WRITE_REGISTER(WriteAddr, WriteData, 6, false);
	}
	else
	{
#endif
     if (bAddUSBCSRAddress && Address < 0x8000){
        Address += macp->USBCSRAddress;
        if ((Address & BASE_ADDR_MASK_HOST) == USB_BASE_ADDR_HOST)
            WriteAddr[0] = (u16) Address + 1;
        else
   	 	// must write High word first
            WriteAddr[0] = (u16) Address + 2;
    }
    else
        WriteAddr[0] = (u16) Address + 1;

	WriteAddr[1] = (u16) Address;
    WriteData[0] = (u16) (Value >> 16);
    WriteData[1] = (u16) (Value & 0xFFFF);


    while (ret != 0){
   		ret = zd1211_USB_PACKAGE_WRITE_REGISTER(WriteAddr, WriteData, 2, false);
   		count++;
    	if (count > 5){

    		printk(KERN_ERR "zd1211_writel failed for 5 attempts\n");
    		break;
    	}
   	}

#ifdef fQuickPhySet
	}
#endif

   	return ret;	
}



void zd1211_StrongSignalDect(struct zd1205_private *macp)
{
    u32 tmpvalue;
    
	if ( (macp->PHYTestTimerCount >= macp->PHYTestTimer)&&
			(macp->PHYTestTimer) && (macp->PHYLowPower & BIT_0)	&&
			(!dot11Obj.bContinueTx) &&

			(macp->bAssoc)){
		macp->PHYTestTimerCount = 0;		
		if (macp->RF_Mode == RFMD_RF){
 			if ( (macp->PHYTestRssi >= macp->PHYTestRssiBound) &&

 				((!dot11Obj.CR122Flag) || (dot11Obj.CR122Flag == 2))){
	    		LockPhyReg(&dot11Obj);
				zd_writel(0xff, ZD1205_CR122);
				
				if ( (macp->PHYLowPower & BIT_1)&&
				 	((!dot11Obj.CR31Flag) || (dot11Obj.CR31Flag == 2)) ){


					macp->bTraceSetPoint = 0;

			    	tmpvalue = dot11Obj.IntValue[dot11Obj.Channel-1] - cPWR_STRONG_SIG_DROP;

                	zd_writel(tmpvalue, ZD1205_CR31);

					dot11Obj.CR31Flag = 1;
				}
      

				UnLockPhyReg(&dot11Obj);

				dot11Obj.CR122Flag = 1;

			}
			else if ( (macp->PHYTestRssi < macp->PHYTestRssiBound) &&
			    	((dot11Obj.CR122Flag) || (dot11Obj.CR122Flag == 2)) ){
            	LockPhyReg(&dot11Obj);
		    	zd_writel(0x00, ZD1205_CR122);
				UnLockPhyReg(&dot11Obj);
				
				if ( (macp->PHYLowPower & BIT_1) &&

				 	((dot11Obj.CR31Flag) || (dot11Obj.CR31Flag == 2)) ){
					macp->bTraceSetPoint = 1;

			    	HW_UpdateIntegrationValue(&dot11Obj, dot11Obj.Channel, macp->cardSetting.MacMode);

					dot11Obj.CR31Flag = 0;

				}
			
				
				dot11Obj.CR122Flag = 0;
			}

		} 
		else if((macp->RF_Mode == AL2230_RF) || (macp->RF_Mode == AL2230S_RF)){
			if ( (macp->PHYTestRssi >= macp->PHYTestRssiBound)&&
			 	((!dot11Obj.CR203Flag) || (dot11Obj.CR203Flag == 2)) ){

		    	LockPhyReg(&dot11Obj);

				zd_writel(0x0a, ZD1205_CR203);
				if ( (macp->PHYLowPower & BIT_1)&&
				 	((!dot11Obj.CR31Flag) || (dot11Obj.CR31Flag == 2)) ){



					macp->bTraceSetPoint = 0;

			   		tmpvalue = dot11Obj.IntValue[dot11Obj.Channel-1] - cPWR_STRONG_SIG_DROP;
                	zd_writel(tmpvalue, ZD1205_CR31);
					dot11Obj.CR31Flag = 1;
				}
       
				UnLockPhyReg(&dot11Obj);
				dot11Obj.CR203Flag = 1;
			}
			else if ( (macp->PHYTestRssi < macp->PHYTestRssiBound)&&
			      ((dot11Obj.CR203Flag) || (dot11Obj.CR203Flag == 2)) ){
	        	LockPhyReg(&dot11Obj);
		    	zd_writel(0x06, ZD1205_CR203);
		    	UnLockPhyReg(&dot11Obj);


		    	

				if ( (macp->PHYLowPower & BIT_1)&&
				 	((dot11Obj.CR31Flag) || (dot11Obj.CR31Flag == 2)) ){

					macp->bTraceSetPoint = 1;


			    	HW_UpdateIntegrationValue(&dot11Obj, dot11Obj.Channel, macp->cardSetting.MacMode);
					dot11Obj.CR31Flag = 0;
				}

				
				dot11Obj.CR203Flag = 0;
			}
		}	
	}
	else {
	    macp->PHYTestTimerCount++;

	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -