📄 rtusb_io.c
字号:
========================================================================
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 + -