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

📄 rtusb_io.c

📁 经过修改的在uClinux2.6上正常运行的ralink rt2571芯片组的设备驱动程序.
💻 C
📖 第 1 页 / 共 2 页
字号:
	========================================================================
	
	Routine Description:

	Arguments:

	Return Value:
	
	Note:
	
	========================================================================
*/
VOID	RTUSBInitializeCmdQ(
	IN	PCmdQ	cmdq)
{
	cmdq->head = NULL;
	cmdq->tail = NULL;
	cmdq->size = 0;
}

/*
	========================================================================
	
	Routine Description:

	Arguments:

	Return Value:
	
	Note:
	
	========================================================================
*/
NDIS_STATUS	RTUSBEnqueueCmdFromNdis(
	IN	PRTMP_ADAPTER	pAd,
	IN	NDIS_OID		Oid,
	IN	BOOLEAN			SetInformation,
	IN	PVOID			pInformationBuffer,
	IN	ULONG			InformationBufferLength)
{
	PCmdQElmt	cmdqelmt = NULL;
	ULONG       IrqFlags;
	
	if (pAd->RTUSBCmdThr_pid < 0) 
		return (NDIS_STATUS_RESOURCES);
        
    cmdqelmt = (PCmdQElmt) kmalloc(sizeof(CmdQElmt), MEM_ALLOC_FLAG);
	if (!cmdqelmt) 
	{
		DBGPRINT(RT_DEBUG_ERROR,"Not enough memory\n");
		kfree((PCmdQElmt)cmdqelmt);
		return NDIS_STATUS_RESOURCES;
	}

	if ((Oid == RT_OID_MULTI_READ_MAC) ||
		(Oid == RT_OID_VENDOR_READ_BBP) ||
#ifdef DBG		
		(Oid == RT_OID_802_11_QUERY_HARDWARE_REGISTER) ||
#endif		
		(Oid == RT_OID_USB_VENDOR_EEPROM_READ))
	{
		cmdqelmt->buffer = pInformationBuffer;
	}
	else
	{
		cmdqelmt->buffer = NULL;
		if (pInformationBuffer != NULL)
		{
			cmdqelmt->buffer =	kmalloc(InformationBufferLength, MEM_ALLOC_FLAG);
			if ((!cmdqelmt->buffer) )
			{       
                kfree((PVOID)cmdqelmt->buffer);
				kfree((PCmdQElmt)cmdqelmt);
				return (NDIS_STATUS_RESOURCES);
			}
			else
			{
				NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
				cmdqelmt->bufferlength = InformationBufferLength;
			}
		}
		else
			cmdqelmt->bufferlength = 0;
	}
	
	cmdqelmt->command = Oid;
	cmdqelmt->CmdFromNdis = TRUE;
	if (SetInformation == TRUE)
		cmdqelmt->SetOperation = TRUE;
	else
		cmdqelmt->SetOperation = FALSE;

	NdisAcquireSpinLock(&pAd->CmdQLock,  IrqFlags);
	EnqueueCmd((&pAd->CmdQ), cmdqelmt);
	NdisReleaseSpinLock(&pAd->CmdQLock,  IrqFlags);
	
    RTUSBCMDUp(pAd);
	
	if ((Oid == OID_802_11_BSSID_LIST_SCAN) ||
		(Oid == RT_OID_802_11_BSSID) ||
		(Oid == OID_802_11_SSID) ||
		(Oid == OID_802_11_DISASSOCIATE))
	{
		return(NDIS_STATUS_SUCCESS);
	}
	
    return(NDIS_STATUS_SUCCESS);
}

/*
	========================================================================
	
	Routine Description:

	Arguments:

	Return Value:
	
	Note:
	
	========================================================================
*/
VOID	RTUSBEnqueueInternalCmd(
	IN	PRTMP_ADAPTER	pAd,
	IN	NDIS_OID		Oid)
{
	PCmdQElmt	cmdqelmt = NULL;
    ULONG       IrqFlags;
    
    if (pAd->RTUSBCmdThr_pid < 0) 
		return;
		
	switch (Oid)
	{
		case RT_OID_CHECK_GPIO:
			cmdqelmt = &(pAd->CmdQElements[CMD_CHECK_GPIO]);
			break;
			
		case RT_OID_PERIODIC_EXECUT:
			cmdqelmt = &(pAd->CmdQElements[CMD_PERIODIC_EXECUT]);
			break;
			
		//For Alpha only
		case RT_OID_ASICLED_EXECUT:
			cmdqelmt = &(pAd->CmdQElements[CMD_ASICLED_EXECUT]);
			break;

		case RT_OID_UPDATE_TX_RATE:
			cmdqelmt = &(pAd->CmdQElements[CMD_UPDATE_TX_RATE]);
			break;
			
		case RT_OID_SET_PSM_BIT_SAVE:
			cmdqelmt = &(pAd->CmdQElements[CMD_SET_PSM_SAVE]);
			break;
			
		case RT_OID_LINK_DOWN:
			cmdqelmt = &(pAd->CmdQElements[CMD_LINK_DOWN]);
			break;
			
		case RT_OID_USB_RESET_BULK_IN:
			cmdqelmt = &(pAd->CmdQElements[CMD_RESET_BULKIN]);
			break;
			
		case RT_OID_USB_RESET_BULK_OUT:
			cmdqelmt = &(pAd->CmdQElements[CMD_RESET_BULKOUT]);
			break;
			
		case RT_OID_RESET_FROM_ERROR:
			cmdqelmt = &(pAd->CmdQElements[CMD_RESET_FROM_ERROR]);
			break;
			
		case RT_OID_RESET_FROM_NDIS:
			cmdqelmt = &(pAd->CmdQElements[CMD_RESET_FROM_NDIS]);
			break;

		case RT_PERFORM_SOFT_DIVERSITY:
			cmdqelmt = &(pAd->CmdQElements[CMD_SOFT_DIVERSITY]);
			break;

        case RT_OID_FORCE_WAKE_UP:
            cmdqelmt = &(pAd->CmdQElements[CMD_FORCE_WAKEUP]);
            break;
 
        case RT_OID_SET_PSM_BIT_ACTIVE:
            cmdqelmt = &(pAd->CmdQElements[CMD_SET_PSM_ACTIVE]);
        break;
 
		default:
			break;
	}

	if ((cmdqelmt != NULL) && (cmdqelmt->InUse == FALSE) && (pAd->RTUSBCmdThr_pid > 0))
	{
		cmdqelmt->InUse = TRUE;
		cmdqelmt->command = Oid;

		NdisAcquireSpinLock(&pAd->CmdQLock, IrqFlags);
		EnqueueCmd((&pAd->CmdQ), cmdqelmt);
		NdisReleaseSpinLock(&pAd->CmdQLock, IrqFlags);
		
		RTUSBCMDUp(pAd);
	}
}

/*
	========================================================================
	
	Routine Description:

	Arguments:

	Return Value:
	
	Note:
	
	========================================================================
*/
VOID	RTUSBDequeueCmd(
	IN	PCmdQ		cmdq,
	OUT	PCmdQElmt	*pcmdqelmt)
{
	*pcmdqelmt = cmdq->head;
	
	if (*pcmdqelmt != NULL)
	{
		cmdq->head = cmdq->head->next;
		cmdq->size--;
		if (cmdq->size == 0)
			cmdq->tail = NULL;
	}
}

/*
    ========================================================================
	  usb_control_msg - Builds a control urb, sends it off and waits for completion
	  @dev: pointer to the usb device to send the message to
	  @pipe: endpoint "pipe" to send the message to
	  @request: USB message request value
	  @requesttype: USB message request type value
	  @value: USB message value
	  @index: USB message index value
	  @data: pointer to the data to send
	  @size: length in bytes of the data to send
	  @timeout: time in jiffies to wait for the message to complete before
			  timing out (if 0 the wait is forever)
	  Context: !in_interrupt ()

	  This function sends a simple control message to a specified endpoint
	  and waits for the message to complete, or timeout.
	  If successful, it returns the number of bytes transferred, otherwise a negative error number.

	 Don't use this function from within an interrupt context, like a
	  bottom half handler.	If you need an asynchronous message, or need to send
	  a message from within interrupt context, use usb_submit_urb()
	  If a thread in your driver uses this call, make sure your disconnect()
	  method can wait for it to complete.  Since you don't have a handle on
	  the URB used, you can't cancel the request.
  
	
	Routine Description:

	Arguments:

	Return Value:
	
	Note:
	
	========================================================================
*/
INT	    RTUSB_VendorRequest(
	IN	PRTMP_ADAPTER	pAd,
	IN	ULONG			TransferFlags,
	IN	UCHAR			RequestType,
	IN	UCHAR			Request,
	IN	USHORT			Value,
	IN	USHORT			Index,
	IN	PVOID			TransferBuffer,
	IN	ULONG			TransferBufferLength)
{
	int ret;
	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
	{
		DBGPRINT(RT_DEBUG_ERROR,"device disconnected\n");
		return -1;
	}
	else if (in_interrupt())	
	{
		DBGPRINT(RT_DEBUG_ERROR,"in_interrupt, return RTUSB_VendorRequest\n");

		return -1;
	}
	else
	{
	
		if( RequestType == DEVICE_VENDOR_REQUEST_OUT)
			ret=usb_control_msg(pAd->pUsb_Dev, usb_sndctrlpipe( pAd->pUsb_Dev, 0 ), Request, RequestType, Value,Index, TransferBuffer, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
		else if(RequestType == DEVICE_VENDOR_REQUEST_IN)
			ret=usb_control_msg(pAd->pUsb_Dev, usb_rcvctrlpipe( pAd->pUsb_Dev, 0 ), Request, RequestType, Value,Index, TransferBuffer, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
		else
		{
			DBGPRINT(RT_DEBUG_ERROR,"vendor request direction is failed\n");
			ret = -1;
		}

        if (ret < 0)
			DBGPRINT(RT_DEBUG_ERROR,"USBVendorRequest failed ret=%d \n",ret);
			
#if 0	    
        // retry
		if (ret < 0) {
			int temp_i=0;
			DBGPRINT(RT_DEBUG_ERROR,"USBVendorRequest failed ret=%d, \n",ret);
			ret = 0;
			do
			{
				if( RequestType == DEVICE_VENDOR_REQUEST_OUT)
					ret=usb_control_msg(pAd->pUsb_Dev, usb_sndctrlpipe( pAd->pUsb_Dev, 0 ), Request, RequestType, Value,Index, TransferBuffer, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
				else if(RequestType == DEVICE_VENDOR_REQUEST_IN)
					ret=usb_control_msg(pAd->pUsb_Dev, usb_rcvctrlpipe( pAd->pUsb_Dev, 0 ), Request, RequestType, Value,Index, TransferBuffer, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
				temp_i++;
			} while( (ret < 0) && (temp_i <= 1) );

			if( ret >= 0)
				return ret;
			
		}
#endif

	}
	return ret;
}

/*
	========================================================================
	
	Routine Description:
	  Creates an IRP to submite an IOCTL_INTERNAL_USB_RESET_PORT
	  synchronously. Callers of this function must be running at
	  PASSIVE LEVEL.

	Arguments:

	Return Value:

	Note:
	
	========================================================================
*/
NTSTATUS	RTUSB_ResetDevice(
	IN	PRTMP_ADAPTER	pAd)
{
	NTSTATUS		Status = TRUE;

	DBGPRINT_RAW(RT_DEBUG_TRACE, "--->USB_ResetDevice\n");
	//RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
	return Status;
}

#ifdef DBG
#define HARDWARE_MAC	0
#define HARDWARE_BBP	1
#define HARDWARE_RF		2
NDIS_STATUS     RTUSBQueryHardWareRegister(
	IN	PRTMP_ADAPTER	pAd,
	IN	PVOID			pBuf)
{
	PRT_802_11_HARDWARE_REGISTER	pHardwareRegister;
	ULONG							Value;
	USHORT							Offset;
	UCHAR							bbpValue;
	UCHAR							bbpID;
	NDIS_STATUS						Status = NDIS_STATUS_SUCCESS;	

	pHardwareRegister = (PRT_802_11_HARDWARE_REGISTER) pBuf;

	if (pHardwareRegister->HardwareType == HARDWARE_MAC)
	{
		//Check Offset is valid?
		if (pHardwareRegister->Offset > 0xF4)
			Status = NDIS_STATUS_FAILURE;
		
		Offset = (USHORT) pHardwareRegister->Offset;
		RTUSBReadMACRegister(pAd, Offset, &Value);
		pHardwareRegister->Data = Value;
		DBGPRINT(RT_DEBUG_TRACE, "MAC:Offset[0x%04x]=[0x%04x]\n", Offset, Value);
	}
	else if (pHardwareRegister->HardwareType == HARDWARE_BBP)
	{
		bbpID = (UCHAR) pHardwareRegister->Offset;
		
		RTUSBReadBBPRegister(pAd, bbpID, &bbpValue);		
		pHardwareRegister->Data = bbpValue;
		DBGPRINT(RT_DEBUG_TRACE, "BBP:ID[0x%02x]=[0x%02x]\n", bbpID, bbpValue);		
	}
	else
		Status = NDIS_STATUS_FAILURE;
	
	return Status;
}

NDIS_STATUS     RTUSBSetHardWareRegister(
	IN	PRTMP_ADAPTER	pAd,
	IN	PVOID			pBuf)
{
	PRT_802_11_HARDWARE_REGISTER	pHardwareRegister;
	ULONG							Value;
	USHORT							Offset;
	UCHAR							bbpValue;
	UCHAR							bbpID;
	NDIS_STATUS						Status = NDIS_STATUS_SUCCESS;	

	pHardwareRegister = (PRT_802_11_HARDWARE_REGISTER) pBuf;

	if (pHardwareRegister->HardwareType == HARDWARE_MAC)
	{
		//Check Offset is valid?
		if (pHardwareRegister->Offset > 0xF4)
			Status = NDIS_STATUS_FAILURE;

		Offset = (USHORT) pHardwareRegister->Offset;
		Value = (ULONG) pHardwareRegister->Data;
		RTUSBWriteMACRegister(pAd, Offset, Value);		
		DBGPRINT(RT_DEBUG_TRACE, "RT_OID_802_11_SET_HARDWARE_REGISTER (MAC offset=0x%08x, data=0x%08x)\n", pHardwareRegister->Offset, pHardwareRegister->Data);

		// 2004-11-08 a special 16-byte on-chip memory is used for RaConfig to pass debugging parameters to driver
		// for debug-tuning only
		if ((pHardwareRegister->Offset >= HW_DEBUG_SETTING_BASE) && 
			(pHardwareRegister->Offset <= HW_DEBUG_SETTING_END))
		{
			// 0x2bf0: test power-saving feature
			if (pHardwareRegister->Offset == HW_DEBUG_SETTING_BASE)
			{
#if 0			
				ULONG isr, imr, gimr;
				USHORT tbtt = 3;

				RTMP_IO_READ32(pAd, MCU_INT_SOURCE_CSR, &isr);
				RTMP_IO_READ32(pAd, MCU_INT_MASK_CSR, &imr);
				RTMP_IO_READ32(pAd, INT_MASK_CSR, &gimr);
				DBGPRINT(RT_DEBUG_TRACE, "Sleep %d TBTT, 8051 IMR=%08x, ISR=%08x, MAC IMR=%08x\n", tbtt, imr, isr, gimr);
				AsicSleepThenAutoWakeup(pAd, tbtt);	
#endif				
			}
			// 0x2bf4: test H2M_MAILBOX. byte3: Host command, byte2: token, byte1-0: arguments
			else if (pHardwareRegister->Offset == (HW_DEBUG_SETTING_BASE + 4))
			{
				// 0x2bf4: byte0 non-zero: enable R17 tuning, 0: disable R17 tuning
				if (pHardwareRegister->Data & 0x000000ff) 
				{
					pAd->BbpTuning.bEnable = TRUE;
					DBGPRINT(RT_DEBUG_TRACE,"turn on R17 tuning\n");
				}
				else
				{
					UCHAR R17;

					pAd->BbpTuning.bEnable = FALSE;
					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
					{
						if (pAd->PortCfg.Channel > 14)
							R17 = pAd->BbpTuning.R17LowerBoundA;
						else
							R17 = pAd->BbpTuning.R17LowerBoundG;
						RTUSBWriteBBPRegister(pAd, 17, R17);
						DBGPRINT(RT_DEBUG_TRACE,"turn off R17 tuning, restore to 0x%02x\n", R17);
					}
				}
			}
			// 0x2bf8: test ACK policy and QOS format in ADHOC mode
			else if (pHardwareRegister->Offset == (HW_DEBUG_SETTING_BASE + 8))
			{
				PUCHAR pAckStr[4] = {"NORMAL", "NO-ACK", "NO-EXPLICIT-ACK", "BLOCK-ACK"};
				EDCA_PARM DefaultEdcaParm;

				// byte0 b1-0 means ACK POLICY - 0: normal ACK, 1: no ACK, 2:no explicit ACK, 3:BA
				pAd->PortCfg.AckPolicy[0] = ((UCHAR)pHardwareRegister->Data & 0x02) << 5;
				pAd->PortCfg.AckPolicy[1] = ((UCHAR)pHardwareRegister->Data & 0x02) << 5;
				pAd->PortCfg.AckPolicy[2] = ((UCHAR)pHardwareRegister->Data & 0x02) << 5;
				pAd->PortCfg.AckPolicy[3] = ((UCHAR)pHardwareRegister->Data & 0x02) << 5;
				DBGPRINT(RT_DEBUG_TRACE, "ACK policy = %s\n", pAckStr[(UCHAR)pHardwareRegister->Data & 0x02]);

				// any non-ZERO value in byte1 turn on EDCA & QOS format
				if (pHardwareRegister->Data & 0x0000ff00) 
				{
					NdisZeroMemory(&DefaultEdcaParm, sizeof(EDCA_PARM));
					DefaultEdcaParm.bValid = TRUE;
					DefaultEdcaParm.Aifsn[0] = 3;
					DefaultEdcaParm.Aifsn[1] = 7;
					DefaultEdcaParm.Aifsn[2] = 2;
					DefaultEdcaParm.Aifsn[3] = 2;

					DefaultEdcaParm.Cwmin[0] = 4;
					DefaultEdcaParm.Cwmin[1] = 4;
					DefaultEdcaParm.Cwmin[2] = 3;
					DefaultEdcaParm.Cwmin[3] = 2;

					DefaultEdcaParm.Cwmax[0] = 10;
					DefaultEdcaParm.Cwmax[1] = 10;
					DefaultEdcaParm.Cwmax[2] = 4;
					DefaultEdcaParm.Cwmax[3] = 3;

					DefaultEdcaParm.Txop[0]  = 0;
					DefaultEdcaParm.Txop[1]  = 0;
					DefaultEdcaParm.Txop[2]  = 96;
					DefaultEdcaParm.Txop[3]  = 48;
					AsicSetEdcaParm(pAd, &DefaultEdcaParm);
				}
				else
					AsicSetEdcaParm(pAd, NULL);
			}
			// 0x2bfc: turn ON/OFF TX aggregation
			else if (pHardwareRegister->Offset == (HW_DEBUG_SETTING_BASE + 12))
			{
				if (pHardwareRegister->Data)
					OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
				else
					OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
				DBGPRINT(RT_DEBUG_TRACE, "AGGREGATION = %d\n", OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED));
			}
			else
				Status = NDIS_STATUS_FAILURE;				
		}
	}
	else if (pHardwareRegister->HardwareType == HARDWARE_BBP)
	{
		bbpID = (UCHAR) pHardwareRegister->Offset;
		bbpValue = (UCHAR) pHardwareRegister->Data;
		RTUSBWriteBBPRegister(pAd, bbpID, bbpValue);
		DBGPRINT(RT_DEBUG_TRACE, "BBP:ID[0x%02x]=[0x%02x]\n", bbpID, bbpValue);		
	}

	return Status;
}
#endif

⌨️ 快捷键说明

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