Files
Linux_Drivers/osdrv/extdrv/wireless/mediatek/mt7603/mcu/andes_mt.c
forum_service 213c880673 add driver of tp、wiegand-gpio and wireless
Change-Id: Ie3c11d9d85cf1a05042f5690ac711856fe8b1ad7
2023-12-22 09:56:05 +08:00

4574 lines
125 KiB
C

/*
***************************************************************************
* MediaTek Inc.
*
* All rights reserved. source code is an unpublished work and the
* use of a copyright notice does not imply otherwise. This source code
* contains confidential trade secret material of MediaTek. Any attemp
* or participation in deciphering, decoding, reverse engineering or in any
* way altering the source code is stricitly prohibited, unless the prior
* written consent of MediaTek, Inc. is obtained.
***************************************************************************
Module Name:
andes_mt.c
*/
#include "rt_config.h"
#ifdef RTMP_SDIO_SUPPORT
INT32 AndesMTSendCmdMsgToSdio(PRTMP_ADAPTER pAd)
{
INT32 Ret = 0;
struct MCU_CTRL *ctl = &pAd->MCUCtrl;
PNDIS_PACKET NetPkt = NULL;
struct cmd_msg *msg = NULL;
while ((msg = AndesDequeueCmdMsg(ctl, &ctl->txq_sdio)) != NULL) {
if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MCU_SEND_IN_BAND_CMD)
|| RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)
|| RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_SUSPEND)) {
if (!msg->need_wait)
AndesFreeCmdMsg(msg);
continue;
}
if (AndesQueueLen(ctl, &ctl->ackq) > 0) {
AndesQueueHeadCmdMsg(&ctl->txq_sdio, msg, msg->state);
Ret = NDIS_STATUS_FAILURE;
continue;
}
NetPkt = msg->net_pkt;
/* send to SDIO host */
Ret = MTSDIOCmdTx(pAd, GET_OS_PKT_DATAPTR(NetPkt),
GET_OS_PKT_LEN(NetPkt));
if (Ret)
{
msg->state = tx_sdio_fail;
DBGPRINT(RT_DEBUG_ERROR, ("kick out cmd to sdio host fail\n"));
RTMP_OS_COMPLETE(&msg->tx_sdio_done);
break;
}
else
{
msg->state = tx_sdio_ok;
DBGPRINT(RT_DEBUG_TRACE, ("kick out cmd to sdio host ok\n"));
}
RTMP_OS_COMPLETE(&msg->tx_sdio_done);
}
return Ret;
}
static INT32 AndesMTSdioSubmitCmdMsgToSDIOWorker(PRTMP_ADAPTER pAd, struct cmd_msg *msg)
{
INT32 Ret = 0;
struct MCU_CTRL *ctl = &pAd->MCUCtrl;
POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
AndesQueueTailCmdMsg(&ctl->txq_sdio, msg, msg->state);
MTSDIOAddWorkerTaskList(pAd);
queue_work(pObj->SdioWq, &pObj->SdioWork);
/* Wait for SDIO tx timeout */
if (!AndesWaitForSdioCompleteTimeout(msg, msg->tx_sdio_timeout)) {
DBGPRINT(RT_DEBUG_ERROR, ("%s: Wait for SDIO tx timeout(%d)\n", __FUNCTION__,
msg->tx_sdio_timeout));
AndesUnlinkCmdMsg(msg, &ctl->txq_sdio);
Ret = -1;
}
else
{
if (msg->state == tx_sdio_ok)
{
Ret = 0;
}
else
{
Ret = -1;
}
}
return Ret;
}
INT32 AndesMTSdioKickOutCmdMsg(PRTMP_ADAPTER pAd, struct cmd_msg *msg)
{
struct MCU_CTRL *ctl = &pAd->MCUCtrl;
INT32 Ret = 0;
PNDIS_PACKET net_pkt = msg->net_pkt;
if (!OS_TEST_BIT(MCU_INIT, &ctl->flags))
return -1;
if (msg->state != tx_retransmit) {
/*
* append to meet block unit and zero four bytes padding
* when using sdio block mode
*/
memset(OS_PKT_TAIL_BUF_EXTEND(net_pkt, ctl->SDIOPadSize), 0x00, SDIO_END_PADDING);
}
Ret = AndesMTSdioSubmitCmdMsgToSDIOWorker(pAd, msg);
if (msg->need_wait)
AndesQueueTailCmdMsg(&ctl->ackq, msg, wait_cmd_out_and_ack);
else
AndesQueueTailCmdMsg(&ctl->kickq, msg, wait_cmd_out);
if (Ret) {
if (!msg->need_wait) {
AndesUnlinkCmdMsg(msg, &ctl->kickq);
AndesQueueTailCmdMsg(&ctl->tx_doneq, msg, tx_kickout_fail);
AndesIncErrorCount(ctl, error_tx_kickout_fail);
} else {
AndesUnlinkCmdMsg(msg, &ctl->ackq);
msg->state = tx_kickout_fail;
AndesIncErrorCount(ctl, error_tx_kickout_fail);
RTMP_OS_COMPLETE(&msg->ack_done);
}
DBGPRINT(RT_DEBUG_ERROR, ("%s:submit cmd msg to SDIO host fail(%d)\n", __FUNCTION__, Ret));
}
return Ret;
}
INT32 AndesMTSdioChkCrc(RTMP_ADAPTER *pAd, UINT32 checksum_len)
{
}
UINT16 AndesMTSdioGetCrc(RTMP_ADAPTER *pAd)
{
}
#endif
#ifdef RTMP_USB_SUPPORT
INT32 AndesMTUsbChkCrc(RTMP_ADAPTER *ad, UINT32 checksum_len)
{
int ret = 0;
UINT8 cmd[8];
RTMP_CHIP_CAP *cap = &ad->chipCap;
DBGPRINT(RT_DEBUG_OFF, ("%s\n", __FUNCTION__));
NdisMoveMemory(cmd, &cap->rom_patch_offset, 4);
NdisMoveMemory(&cmd[4], &checksum_len, 4);
ret = RTUSB_VendorRequest(ad,
USBD_TRANSFER_DIRECTION_OUT,
DEVICE_VENDOR_REQUEST_OUT,
0x01,
0x20,
0x00,
cmd,
8);
return ret;
}
UINT16 AndesMTUsbGetCrc(RTMP_ADAPTER *ad)
{
//int ret = 0;
UINT16 crc, count = 0;
while (1) {
/*ret = */RTUSB_VendorRequest(ad,
(USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
DEVICE_VENDOR_REQUEST_IN,
0x01,
0x21,
0x00,
&crc,
2);
if (crc != 0xFFFF)
break;
RtmpOsMsDelay(100);
if (count++ > 100) {
DBGPRINT(RT_DEBUG_ERROR, ("Query CRC over %d times\n", count));
break;
}
}
return crc;
}
INT32 AndesMTUSBKickOutCmdMsg(PRTMP_ADAPTER ad, struct cmd_msg *msg)
{
struct MCU_CTRL *ctl = &ad->MCUCtrl;
POS_COOKIE pObj = (POS_COOKIE)ad->OS_Cookie;
int ret = 0;
PNDIS_PACKET net_pkt = msg->net_pkt;
RTMP_CHIP_CAP *pChipCap = &ad->chipCap;
if (msg->state != tx_retransmit) {
/* append four zero bytes padding when usb aggregate enable */
memset(OS_PKT_TAIL_BUF_EXTEND(net_pkt, USB_END_PADDING), 0x00, USB_END_PADDING);
}
RTUSB_FILL_BULK_URB(msg->urb, pObj->pUsb_Dev,
usb_sndbulkpipe(pObj->pUsb_Dev, pChipCap->CommandBulkOutAddr),
GET_OS_PKT_DATAPTR(net_pkt), GET_OS_PKT_LEN(net_pkt), UsbKickOutCmdMsgComplete, net_pkt);
if (msg->need_wait)
AndesQueueTailCmdMsg(&ctl->ackq, msg, wait_cmd_out_and_ack);
else
AndesQueueTailCmdMsg(&ctl->kickq, msg, wait_cmd_out);
if (!OS_TEST_BIT(MCU_INIT, &ctl->flags))
return -1;
OS_SET_BIT(MCU_TX_IN_PROGRESS, &ctl->flags);
#ifdef USB_IOT_WORKAROUND2
if (ad->bUSBIOTReady)
usb_iot_add_padding(msg->urb, msg->usb_iot_w2_buf, NULL);
#endif
ret = RTUSB_SUBMIT_URB(msg->urb);
if (ret) {
OS_CLEAR_BIT(MCU_TX_IN_PROGRESS, &ctl->flags);
if (!msg->need_wait) {
AndesUnlinkCmdMsg(msg, &ctl->kickq);
AndesQueueTailCmdMsg(&ctl->tx_doneq, msg, tx_kickout_fail);
AndesIncErrorCount(ctl, error_tx_kickout_fail);
} else {
AndesUnlinkCmdMsg(msg, &ctl->ackq);
msg->state = tx_kickout_fail;
AndesIncErrorCount(ctl, error_tx_kickout_fail);
RTMP_OS_COMPLETE(&msg->ack_done);
}
DBGPRINT(RT_DEBUG_ERROR, ("%s:submit urb fail(%d)\n", __FUNCTION__, ret));
}
return ret;
}
#endif /* RTMP_USB_SUPPORT */
#ifdef RTMP_PCI_SUPPORT
INT32 AndesMTPciKickOutCmdMsg(PRTMP_ADAPTER pAd, struct cmd_msg *msg)
{
int ret = NDIS_STATUS_SUCCESS;
unsigned long flags = 0;
ULONG FreeNum;
PNDIS_PACKET net_pkt = msg->net_pkt;
UINT32 SwIdx = 0;
UCHAR *pSrcBufVA;
UINT SrcBufLen = 0;
PACKET_INFO PacketInfo;
TXD_STRUC *pTxD;
struct MCU_CTRL *ctl = &pAd->MCUCtrl;
#ifdef RT_BIG_ENDIAN
TXD_STRUC *pDestTxD;
UCHAR tx_hw_info[TXD_SIZE];
#endif
if (!OS_TEST_BIT(MCU_INIT, &ctl->flags))
return -1;
FreeNum = GET_CTRLRING_FREENO(pAd);
if (FreeNum == 0) {
DBGPRINT(RT_DEBUG_WARN, ("%s FreeNum == 0 (TxCpuIdx = %d, TxDmaIdx = %d, TxSwFreeIdx = %d)\n",
__FUNCTION__, pAd->CtrlRing.TxCpuIdx, pAd->CtrlRing.TxDmaIdx, pAd->CtrlRing.TxSwFreeIdx));
return NDIS_STATUS_FAILURE;
}
RTMP_SPIN_LOCK_IRQSAVE(&pAd->CtrlRingLock, &flags);
RTMP_QueryPacketInfo(net_pkt, &PacketInfo, &pSrcBufVA, &SrcBufLen);
if (pSrcBufVA == NULL) {
RTMP_SPIN_UNLOCK_IRQRESTORE(&pAd->CtrlRingLock, &flags);
return NDIS_STATUS_FAILURE;
}
SwIdx = pAd->CtrlRing.TxCpuIdx;
#ifdef RT_BIG_ENDIAN
pDestTxD = (TXD_STRUC *)pAd->CtrlRing.Cell[SwIdx].AllocVa;
NdisMoveMemory(&tx_hw_info[0], (UCHAR *)pDestTxD, TXD_SIZE);
pTxD = (TXD_STRUC *)&tx_hw_info[0];
#else
pTxD = (TXD_STRUC *)pAd->CtrlRing.Cell[SwIdx].AllocVa;
#endif
#ifdef RT_BIG_ENDIAN
RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
#endif /* RT_BIG_ENDIAN */
pAd->CtrlRing.Cell[SwIdx].pNdisPacket = net_pkt;
pAd->CtrlRing.Cell[SwIdx].pNextNdisPacket = NULL;
pAd->CtrlRing.Cell[SwIdx].PacketPa = PCI_MAP_SINGLE(pAd, (pSrcBufVA) , (SrcBufLen), 0, RTMP_PCI_DMA_TODEVICE);
pTxD->LastSec0 = 1;
pTxD->LastSec1 = 0;
pTxD->SDLen0 = SrcBufLen;
pTxD->SDLen1 = 0;
pTxD->SDPtr0 = pAd->CtrlRing.Cell[SwIdx].PacketPa;
pTxD->Burst = 0;
pTxD->DMADONE = 0;
#ifdef RT_BIG_ENDIAN
RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
#endif
/* flush dcache if no consistent memory is supported */
RTMP_DCACHE_FLUSH(SrcBufPA, SrcBufLen);
RTMP_DCACHE_FLUSH(pAd->CtrlRing.Cell[SwIdx].AllocPa, TXD_SIZE);
/* Increase TX_CTX_IDX, but write to register later.*/
INC_RING_INDEX(pAd->CtrlRing.TxCpuIdx, MGMT_RING_SIZE);
if (msg->need_wait)
AndesQueueTailCmdMsg(&ctl->ackq, msg, wait_ack);
else
AndesQueueTailCmdMsg(&ctl->tx_doneq, msg, tx_done);
if (!OS_TEST_BIT(MCU_INIT, &ctl->flags)) {
RTMP_SPIN_UNLOCK_IRQRESTORE(&pAd->CtrlRingLock, &flags);
return -1;
}
RTMP_IO_WRITE32(pAd, pAd->CtrlRing.hw_cidx_addr, pAd->CtrlRing.TxCpuIdx);
RTMP_SPIN_UNLOCK_IRQRESTORE(&pAd->CtrlRingLock, &flags);
return ret;
}
#endif /* RTMP_PCI_SUPPORT */
VOID AndesMTFillCmdHeader(struct cmd_msg *msg, PNDIS_PACKET net_pkt)
{
FW_TXD *fw_txd;
RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)msg->priv;
struct MCU_CTRL *Ctl = &pAd->MCUCtrl;
if ((Ctl->Stage == FW_NO_INIT) || (Ctl->Stage == FW_DOWNLOAD) || (Ctl->Stage == ROM_PATCH_DOWNLOAD))
fw_txd = (FW_TXD *)OS_PKT_HEAD_BUF_EXTEND(net_pkt, 12);
else if (Ctl->Stage == FW_RUN_TIME)
fw_txd = (FW_TXD *)OS_PKT_HEAD_BUF_EXTEND(net_pkt, sizeof(*fw_txd));
else
{
DBGPRINT(RT_DEBUG_OFF, ("%s: Unknown Control Stage(%d)\n", __FUNCTION__,
Ctl->Stage));
return;
}
fw_txd->fw_txd_0.field.length = GET_OS_PKT_LEN(net_pkt);
fw_txd->fw_txd_0.field.pq_id = msg->pq_id;
fw_txd->fw_txd_1.field.cid = msg->cmd_type;
fw_txd->fw_txd_1.field.pkt_type_id = PKT_ID_CMD;
fw_txd->fw_txd_1.field.set_query = msg->set_query;
fw_txd->fw_txd_1.field.seq_num = msg->seq;
fw_txd->fw_txd_2.field.ext_cid = msg->ext_cmd_type;
if ((msg->cmd_type == EXT_CID) && ((msg->set_query == CMD_SET) || (msg->set_query == CMD_QUERY))
&& (msg->need_rsp == TRUE))
{
fw_txd->fw_txd_2.field.ext_cid_option = EXT_CID_OPTION_NEED_ACK;
}
else
{
fw_txd->fw_txd_2.field.ext_cid_option = EXT_CID_OPTION_NO_NEED_ACK;
}
fw_txd->fw_txd_0.word = cpu2le32(fw_txd->fw_txd_0.word);
fw_txd->fw_txd_1.word = cpu2le32(fw_txd->fw_txd_1.word);
fw_txd->fw_txd_2.word = cpu2le32(fw_txd->fw_txd_2.word);
#ifdef CONFIG_TRACE_SUPPORT
TRACE_MCU_CMD_INFO(fw_txd->fw_txd_0.field.length, fw_txd->fw_txd_0.field.pq_id,
fw_txd->fw_txd_1.field.cid, fw_txd->fw_txd_1.field.pkt_type_id,
fw_txd->fw_txd_1.field.set_query, fw_txd->fw_txd_1.field.seq_num,
fw_txd->fw_txd_2.field.ext_cid, fw_txd->fw_txd_2.field.ext_cid_option,
(char *)(GET_OS_PKT_DATAPTR(net_pkt)), GET_OS_PKT_LEN(net_pkt));
#endif /* CONFIG_TRACE_SUPPORT */
}
INT32 CmdInitAccessRegWrite(RTMP_ADAPTER *ad, UINT32 address, UINT32 data)
{
struct cmd_msg *msg;
struct _INIT_CMD_ACCESS_REG access_reg;
INT32 ret = 0;
DBGPRINT(RT_DEBUG_INFO, ("%s: address = %x, data = %x\n", __FUNCTION__, address, data));
msg = AndesAllocCmdMsg(ad, sizeof(struct _INIT_CMD_ACCESS_REG));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, INIT_CMD_ACCESS_REG, CMD_SET, EXT_CMD_NA, FALSE, 0, FALSE, FALSE, 0, NULL, NULL);
memset(&access_reg, 0x00, sizeof(access_reg));
access_reg.ucSetQuery = 1;
access_reg.u4Address = cpu2le32(address);
access_reg.u4Data = cpu2le32(data);
AndesAppendCmdMsg(msg, (char *)&access_reg, sizeof(access_reg));
ret = AndesSendCmdMsg(ad, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
static VOID CmdInitAccessRegReadCb(struct cmd_msg *msg, char *data, UINT16 len)
{
struct _INIT_EVENT_ACCESS_REG *access_reg = (struct _INIT_EVENT_ACCESS_REG *)data;
NdisMoveMemory(msg->rsp_payload, &access_reg->u4Data, len - 4);
*((UINT32 *)(msg->rsp_payload)) = le2cpu32(*((UINT32 *)msg->rsp_payload));
}
INT32 CmdInitAccessRegRead(RTMP_ADAPTER *pAd, UINT32 address, UINT32 *data)
{
struct cmd_msg *msg;
struct _INIT_CMD_ACCESS_REG access_reg;
INT32 ret = 0;
DBGPRINT(RT_DEBUG_INFO, ("%s: address = %x\n", __FUNCTION__, address));
msg = AndesAllocCmdMsg(pAd, sizeof(struct _INIT_CMD_ACCESS_REG));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, INIT_CMD_ACCESS_REG, CMD_QUERY, EXT_CMD_NA, TRUE, 0,
TRUE, TRUE, 8, (CHAR *)data, CmdInitAccessRegReadCb);
memset(&access_reg, 0x00, sizeof(access_reg));
access_reg.ucSetQuery = 0;
access_reg.u4Address = cpu2le32(address);
AndesAppendCmdMsg(msg, (char *)&access_reg, sizeof(access_reg));
ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
static VOID CmdReStartDLRsp(struct cmd_msg *msg, char *Data, UINT16 Len)
{
FW_RXD_2 Status;
Status = *(FW_RXD_2 *)Data;
switch (Status.field.ext_eid)
{
case WIFI_FW_DOWNLOAD_SUCCESS:
DBGPRINT(RT_DEBUG_OFF, ("%s: WiFI FW Download Success\n", __FUNCTION__));
break;
case WIFI_FW_DOWNLOAD_INVALID_PARAM:
DBGPRINT(RT_DEBUG_OFF, ("%s: WiFi FW Download Invalid Parameter\n", __FUNCTION__));
break;
case WIFI_FW_DOWNLOAD_INVALID_CRC:
DBGPRINT(RT_DEBUG_OFF, ("%s: WiFi FW Download Invalid CRC\n", __FUNCTION__));
break;
case WIFI_FW_DOWNLOAD_DECRYPTION_FAIL:
DBGPRINT(RT_DEBUG_OFF, ("%s: WiFi FW Download Decryption Fail\n", __FUNCTION__));
break;
case WIFI_FW_DOWNLOAD_UNKNOWN_CMD:
DBGPRINT(RT_DEBUG_OFF, ("%s: WiFi FW Download Unknown CMD\n", __FUNCTION__));
break;
case WIFI_FW_DOWNLOAD_TIMEOUT:
DBGPRINT(RT_DEBUG_OFF, ("%s: WiFi FW Download Timeout\n", __FUNCTION__));
break;
default:
DBGPRINT(RT_DEBUG_OFF, ("%s: Unknow Status(%u)\n", __FUNCTION__, Status.field.ext_eid));
break;
}
}
static VOID CmdSecKeyRsp(struct cmd_msg *msg, char *Data, UINT16 Len)
{
P_EVENT_SEC_ADDREMOVE_STRUC_T EvtSecKey;
UINT32 Status;
UINT32 WlanIndex;
EvtSecKey = (struct _EVENT_SEC_ADDREMOVE_STRUC_T *)Data;
Status = le2cpu32(EvtSecKey->u4Status);
WlanIndex = le2cpu32(EvtSecKey->u4WlanIdx);
if (Status != 0) {
DBGPRINT(RT_DEBUG_ERROR, ("%s, error set key, wlan idx(%d), status: 0x%x\n", __FUNCTION__, WlanIndex, Status));
} else {
DBGPRINT(RT_DEBUG_TRACE, ("%s, wlan idx(%d), status: 0x%x\n", __FUNCTION__, WlanIndex, Status));
}
}
#if 1 /* Leonardo: TODO: Should be removed */
static VOID CmdPsRetrieveRsp(struct cmd_msg *msg, char *Data, UINT16 Len)
{
P_EXT_EVENT_AP_PS_RETRIEVE_T EvtPsCapatibility;
UINT32 Status;
EvtPsCapatibility = (P_EXT_EVENT_AP_PS_RETRIEVE_T)Data;
Status = le2cpu32(EvtPsCapatibility->u4Param1);
DBGPRINT(RT_DEBUG_ERROR, ("%s Disable FW PS Supportstatus:%x !!!!!\n",__FUNCTION__,Status));
}
#endif
#ifdef MT_PS
#if defined(MT7603) && defined(RTMP_PCI_SUPPORT)
static VOID CmdPsRetrieveStartRspFromCR(RTMP_ADAPTER *pAd, char *Data, UINT16 Len)
{
MAC_TABLE_ENTRY *pEntry;
P_EXT_EVENT_AP_PS_RETRIEVE_T EvtPsRetrieveStart;
UINT32 WlanIdx;
STA_TR_ENTRY *tr_entry;
NDIS_STATUS token_status;
unsigned char q_idx;
struct tx_swq_fifo *ps_fifo_swq;
UINT deq_qid;
//unsigned long IrqFlags;
EvtPsRetrieveStart = (P_EXT_EVENT_AP_PS_RETRIEVE_T)Data;
WlanIdx = le2cpu32(EvtPsRetrieveStart->u4Param1);
if (!(VALID_TR_WCID(WlanIdx))) {
DBGPRINT(RT_DEBUG_ERROR | DBG_FUNC_PS, ("---->%s INVALID_TR_WCID(WlanIndex)\n", __FUNCTION__));
goto NEXT;
}
pEntry = &pAd->MacTab.Content[WlanIdx];
tr_entry = &pAd->MacTab.tr_entry[WlanIdx];
if (IS_ENTRY_NONE(pEntry))
{
DBGPRINT(RT_DEBUG_ERROR | DBG_FUNC_PS, ("---->%s Entry(wcid=%d) left.\n", __FUNCTION__, WlanIdx));
goto NEXT;
}
DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_PS, ("---->%s: Start to send TOKEN frames, WlanIdx=%d\n", __FUNCTION__, WlanIdx));
if (tr_entry->ps_state != APPS_RETRIEVE_START_PS)
{
DBGPRINT(RT_DEBUG_ERROR | DBG_FUNC_PS, ("---->%s Entry(wcid=%d) ps state(%d) is not APPS_RETRIEVE_START_PS\n", __FUNCTION__, WlanIdx, tr_entry->ps_state));
goto NEXT;
}
tr_entry->ps_state = APPS_RETRIEVE_GOING;
CheckSkipTX(pAd, pEntry);
tr_entry->ps_qbitmap = 0;
for (q_idx = 0; q_idx < NUM_OF_TX_RING; q_idx++)
{
UINT16 IsEmpty = IS_TXRING_EMPTY(pAd, q_idx);
if (!IsEmpty)
{
token_status = RtmpEnqueueTokenFrame(pAd, &(pEntry->Addr[0]), 0, WlanIdx, 0, q_idx);
if (!token_status)
tr_entry->ps_qbitmap |= (1 << q_idx);
else
DBGPRINT(RT_DEBUG_ERROR, ("%s(%d) Fail: Send TOKEN Frame, AC=%d\n", __FUNCTION__, __LINE__, q_idx));
}
}
if (tr_entry->ps_qbitmap == 0)
{
q_idx = QID_AC_VO;
token_status = RtmpEnqueueTokenFrame(pAd, &(pEntry->Addr[0]), 0, WlanIdx, 0, q_idx);
if (!token_status)
tr_entry->ps_qbitmap |= (1 << q_idx);
}
if (tr_entry->ps_qbitmap == 0)
{
tr_entry->ps_state = APPS_RETRIEVE_WAIT_EVENT;
tr_entry->token_enq_all_fail = TRUE;
RTEnqueueInternalCmd(pAd, CMDTHREAD_PS_CLEAR, (VOID *)&WlanIdx, sizeof(UINT32));
DBGPRINT(RT_DEBUG_WARN | DBG_FUNC_PS, ("%s(%d): (ps_state = %d) token_enq_all_fail!! ==> send CMDTHREAD_PS_CLEAR cmd.\n",
__FUNCTION__, __LINE__, tr_entry->ps_state));
}
else
{
tr_entry->token_enq_all_fail = FALSE;
}
NEXT:
ps_fifo_swq = &pAd->apps_cr_q;
deq_qid = ps_fifo_swq->deqIdx;
while (ps_fifo_swq->swq[deq_qid] != 0) {
WlanIdx = ps_fifo_swq->swq[deq_qid];
pEntry = &pAd->MacTab.Content[WlanIdx];
tr_entry = &pAd->MacTab.tr_entry[WlanIdx];
if (pEntry->PsMode == PWR_ACTIVE) {
ps_fifo_swq->swq[deq_qid] = 0;
INC_RING_INDEX(ps_fifo_swq->deqIdx, TX_SWQ_FIFO_LEN);
tr_entry->ps_state = APPS_RETRIEVE_IDLE;
MtHandleRxPsPoll(pAd, &pEntry->Addr[0], WlanIdx, TRUE);
deq_qid = ps_fifo_swq->deqIdx;
} else {
if (MtStartPSRetrieve(pAd, ps_fifo_swq->swq[deq_qid]) == TRUE) {
ps_fifo_swq->swq[deq_qid] = 0;
INC_RING_INDEX(ps_fifo_swq->deqIdx, TX_SWQ_FIFO_LEN);
tr_entry->ps_state = APPS_RETRIEVE_START_PS;
}
break;
}
}
}
#endif /* MT7603 && RTMP_PCI_SUPPORT */
VOID AndesPsRetrieveStartRsp(RTMP_ADAPTER *pAd, char *Data, UINT16 Len)
{
MAC_TABLE_ENTRY *pEntry;
P_EXT_EVENT_AP_PS_RETRIEVE_T EvtPsRetrieveStart;
UINT32 WlanIdx;
STA_TR_ENTRY *tr_entry;
NDIS_STATUS token_status;
unsigned char q_idx;
EvtPsRetrieveStart = (P_EXT_EVENT_AP_PS_RETRIEVE_T)Data;
WlanIdx = le2cpu32(EvtPsRetrieveStart->u4Param1);
if (!(VALID_TR_WCID(WlanIdx))) {
DBGPRINT(RT_DEBUG_ERROR | DBG_FUNC_PS, ("---->%s INVALID_TR_WCID(WlanIndex)\n", __FUNCTION__));
return;
}
pEntry = &pAd->MacTab.Content[WlanIdx];
tr_entry = &pAd->MacTab.tr_entry[WlanIdx];
if (IS_ENTRY_NONE(pEntry))
{
DBGPRINT(RT_DEBUG_ERROR | DBG_FUNC_PS, ("---->%s Entry(wcid=%d) left.\n", __FUNCTION__, WlanIdx));
return;
}
DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_PS, ("---->%s: Start to send TOKEN frames, WlanIdx=%d\n", __FUNCTION__, WlanIdx));
tr_entry->ps_state = APPS_RETRIEVE_GOING;
tr_entry->ps_qbitmap = 0;
for (q_idx = 0; q_idx < NUM_OF_TX_RING; q_idx++)
{
//UINT16 IsEmpty = IS_TXRING_EMPTY(pAd, q_idx);
UINT16 IsEmpty = (pAd->TxRing[q_idx].TxDmaIdx == pAd->TxRing[q_idx].TxCpuIdx) ? 1: 0;
if (!IsEmpty)
{
token_status = RtmpEnqueueTokenFrame(pAd, &(pEntry->Addr[0]), 0, WlanIdx, 0, q_idx);
if (!token_status)
{
tr_entry->ps_qbitmap |= (1 << q_idx);
}
else
{
DBGPRINT(RT_DEBUG_ERROR, ("%s(%d) Fail: Send TOKEN Frame, AC=%d\n", __FUNCTION__, __LINE__, q_idx));
}
}
}
if (tr_entry->ps_qbitmap == 0)
{
q_idx = QID_AC_VO;
token_status = RtmpEnqueueTokenFrame(pAd, &(pEntry->Addr[0]), 0, WlanIdx, 0, q_idx);
if (!token_status)
tr_entry->ps_qbitmap |= (1 << q_idx);
}
if (tr_entry->ps_qbitmap == 0)
{
tr_entry->ps_state = APPS_RETRIEVE_WAIT_EVENT;
tr_entry->token_enq_all_fail = TRUE;
RTEnqueueInternalCmd(pAd, CMDTHREAD_PS_CLEAR, (VOID *)&WlanIdx, sizeof(UINT32));
DBGPRINT(RT_DEBUG_WARN | DBG_FUNC_PS, ("%s(%d): (ps_state = %d) token_enq_all_fail!! ==> send CMDTHREAD_PS_CLEAR cmd.\n",
__FUNCTION__, __LINE__, tr_entry->ps_state));
}
else
{
tr_entry->token_enq_all_fail = FALSE;
}
}
static VOID CmdPsRetrieveStartRsp(struct cmd_msg *msg, char *Data, UINT16 Len)
{
RTMP_ADAPTER *ad = NULL;
ad = (RTMP_ADAPTER *)msg->priv;
DBGPRINT(RT_DEBUG_ERROR, ("------> %s(%d)\n", __FUNCTION__, __LINE__));
#ifdef RTMP_PCI_SUPPORT
AndesPsRetrieveStartRsp(ad, Data, Len);
#endif /* RTMP_PCI_SUPPORT */
#if defined(RTMP_USB_SUPPORT) || defined(RTMP_SDIO_SUPPORT)
/*
We need to move AndesPsRetrieveStartRsp to cmd thread for CR read/write.
*/
RTEnqueueInternalCmd(ad, CMDTHREAD_PS_RETRIEVE_RSP, Data, Len);
#endif /* defined(RTMP_USB_SUPPORT) || defined(RTMP_SDIO_SUPPORT) */
DBGPRINT(RT_DEBUG_ERROR, ("<------ %s(%d)\n", __FUNCTION__, __LINE__));
}
static VOID CmdPsClearRsp(struct cmd_msg *msg, char *Data, UINT16 Len)
{
//UINT8 Status;
MAC_TABLE_ENTRY *pEntry;
//QUEUE_ENTRY *pQEntry;
P_CMD_AP_PS_CLEAR_STRUC_T EvtPsClear;
RTMP_ADAPTER *ad = (RTMP_ADAPTER *)msg->priv;
STA_TR_ENTRY *tr_entry;
//unsigned long IrqFlags;
//struct wtbl_entry tb_entry;
UINT32 WlanIndex;
//union WTBL_1_DW3 *dw3 = (union WTBL_1_DW3 *)&tb_entry.wtbl_1.wtbl_1_d3.word;
unsigned char q_idx = 0;
EvtPsClear = (struct _CMD_AP_PS_CLEAR_STRUC_T *)Data;
WlanIndex = le2cpu32(EvtPsClear->u4WlanIdx);
pEntry = &ad->MacTab.Content[WlanIndex];
tr_entry = &ad->MacTab.tr_entry[WlanIndex];
if (ad->MacTab.tr_entry[WlanIndex].PsMode == PWR_ACTIVE)
tr_entry->ps_state = APPS_RETRIEVE_IDLE;
else
tr_entry->ps_state = APPS_RETRIEVE_DONE;
DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_PS, ("wcid=%d, Receive Event of CmdPsClear tr_entry->ps_state=%d\n", WlanIndex,tr_entry->ps_state));
if(tr_entry->token_enq_all_fail)
{
tr_entry->token_enq_all_fail = FALSE;
if (tr_entry->ps_queue.Number)
MtEnqTxSwqFromPsQueue(ad, q_idx, tr_entry);
for (q_idx = 0; q_idx < NUM_OF_TX_RING; q_idx++)
{
if (q_idx < WMM_QUE_NUM)
tr_entry->TokenCount[q_idx] = tr_entry->tx_queue[q_idx].Number;
else
break;
}
}
#ifdef RTMP_MAC_PCI
#ifdef DOT11_N_SUPPORT
SendRefreshBAR(ad, pEntry);
#endif /* DOT11_N_SUPPORT */
#endif /* RTMP_MAC_PCI */
if (tr_entry->ps_state == APPS_RETRIEVE_IDLE)
MtHandleRxPsPoll(ad, &pEntry->Addr[0], WlanIndex, TRUE);
#ifdef UAPSD_SUPPORT
else
{
if (tr_entry->bEospNullSnd)
{
//UINT32 AcQueId;
tr_entry->bEospNullSnd = FALSE;
/* sanity Check for UAPSD condition */
if (tr_entry->EospNullUp >= 8)
tr_entry->EospNullUp = 1; /* shout not be here */
/* get the AC ID of incoming packet */
//AcQueId = WMM_UP2AC_MAP[tr_entry->EospNullUp];
/* bQosNull = bEOSP = TRUE = 1 */
/*
Use management queue to tx QoS Null frame to avoid delay so
us_of_frame is not used.
*/
RtmpEnqueueNullFrame(ad, pEntry->Addr, pEntry->CurrTxRate,
pEntry->Aid, pEntry->func_tb_idx, TRUE, TRUE, tr_entry->EospNullUp);
#ifdef UAPSD_DEBUG
DBGPRINT(RT_DEBUG_ERROR, ("%s: send a EOSP QoS Null frame!\n", __FUNCTION__));
#endif /* UAPSD_DEBUG */
}
else if (pEntry->UAPSDTxNum != 0)
{
RTMPDeQueuePacket(ad, TRUE, NUM_OF_TX_RING, pEntry->wcid, pEntry->UAPSDTxNum);
}
}
#endif /* UAPSD_SUPPORT */
}
#endif /* MT_PS */
static VOID CmdStartDLRsp(struct cmd_msg *msg, char *Data, UINT16 Len)
{
UINT8 Status;
Status = *Data;
switch (Status)
{
case WIFI_FW_DOWNLOAD_SUCCESS:
DBGPRINT(RT_DEBUG_OFF, ("%s: WiFI FW Download Success\n", __FUNCTION__));
break;
case WIFI_FW_DOWNLOAD_INVALID_PARAM:
DBGPRINT(RT_DEBUG_OFF, ("%s: WiFi FW Download Invalid Parameter\n", __FUNCTION__));
break;
case WIFI_FW_DOWNLOAD_INVALID_CRC:
DBGPRINT(RT_DEBUG_OFF, ("%s: WiFi FW Download Invalid CRC\n", __FUNCTION__));
break;
case WIFI_FW_DOWNLOAD_DECRYPTION_FAIL:
DBGPRINT(RT_DEBUG_OFF, ("%s: WiFi FW Download Decryption Fail\n", __FUNCTION__));
break;
case WIFI_FW_DOWNLOAD_UNKNOWN_CMD:
DBGPRINT(RT_DEBUG_OFF, ("%s: WiFi FW Download Unknown CMD\n", __FUNCTION__));
break;
case WIFI_FW_DOWNLOAD_TIMEOUT:
DBGPRINT(RT_DEBUG_OFF, ("%s: WiFi FW Download Timeout\n", __FUNCTION__));
break;
default:
DBGPRINT(RT_DEBUG_OFF, ("%s: Unknow Status(%d)\n", __FUNCTION__, Status));
break;
}
}
INT32 CmdSecKeyReq(RTMP_ADAPTER *ad, UINT8 AddRemove, UINT8 Keytype, UINT8 *pAddr, UINT8 Alg, UINT8 KeyID, UINT8 KeyLen, UINT8 WlanIdx, UINT8 *KeyMaterial)
{
struct cmd_msg *msg;
struct _CMD_SEC_ADDREMOVE_KEY_STRUC_T CmdSecKey;
int ret = 0;
msg = AndesAllocCmdMsg(ad, sizeof(struct _CMD_SEC_ADDREMOVE_KEY_STRUC_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_SEC_ADDREMOVE_KEY, FALSE, 0, FALSE, TRUE, sizeof(struct _EVENT_SEC_ADDREMOVE_STRUC_T), NULL, CmdSecKeyRsp);
memset(&CmdSecKey, 0x00, sizeof(CmdSecKey));
CmdSecKey.ucAddRemove = AddRemove;
CmdSecKey.ucKeyType = Keytype;
memcpy(CmdSecKey.aucPeerAddr, pAddr, 6);
CmdSecKey.ucAlgorithmId = Alg;
CmdSecKey.ucKeyId = KeyID;
CmdSecKey.ucKeyLen = KeyLen;
memcpy(CmdSecKey.aucKeyMaterial, KeyMaterial, KeyLen);
CmdSecKey.ucWlanIndex = WlanIdx;
AndesAppendCmdMsg(msg, (char *)&CmdSecKey, sizeof(CmdSecKey));
ret = AndesSendCmdMsg(ad, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
INT32 CmdPsRetrieveReq(RTMP_ADAPTER *ad, UINT32 enable)
{
struct cmd_msg *msg;
struct _CMD_AP_PS_RETRIEVE_T CmdPsCapatibility;
int ret = 0;
msg = AndesAllocCmdMsg(ad, sizeof(struct _CMD_AP_PS_RETRIEVE_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_AP_PWR_SAVING_CAPABILITY, TRUE, 0, TRUE, TRUE, sizeof(struct _CMD_AP_PS_RETRIEVE_T), NULL, CmdPsRetrieveRsp);
NdisZeroMemory(&CmdPsCapatibility, sizeof(CmdPsCapatibility));
CmdPsCapatibility.u4Option= cpu2le32(0);
CmdPsCapatibility.u4Param1= cpu2le32(enable);
AndesAppendCmdMsg(msg, (char *)&CmdPsCapatibility, sizeof(CmdPsCapatibility));
ret = AndesSendCmdMsg(ad, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
#ifdef MT_PS
INT32 CmdPsRetrieveStartReq(RTMP_ADAPTER *ad, UINT32 WlanIdx)
{
struct cmd_msg *msg;
struct _EXT_CMD_AP_PWS_START_T CmdApPwsStart;
int ret = 0;
/*how to handle memory allocate failure? */
msg = AndesAllocCmdMsg(ad, sizeof(struct _EXT_CMD_AP_PWS_START_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
DBGPRINT(RT_DEBUG_ERROR | DBG_FUNC_PS, ("%s:(ret = %d)\n", __FUNCTION__, ret));
goto error;
}
DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_PS, ("%s(%d): RTEnqueueInternalCmd comming!! WlanIdx: %x\n",__FUNCTION__, __LINE__,WlanIdx));
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_PS_RETRIEVE_START, TRUE, 0, TRUE, TRUE, sizeof(struct _EXT_CMD_AP_PWS_START_T), NULL, CmdPsRetrieveStartRsp);
NdisZeroMemory(&CmdApPwsStart, sizeof(CmdApPwsStart));
CmdApPwsStart.u4WlanIdx= cpu2le32(WlanIdx);
AndesAppendCmdMsg(msg, (char *)&CmdApPwsStart, sizeof(CmdApPwsStart));
msg->wcid = WlanIdx;
ret = AndesSendCmdMsg(ad, msg);
error:
return ret;
}
INT32 CmdPsClearReq(RTMP_ADAPTER *ad, UINT32 wlanidx, BOOLEAN p_wait)
{
struct cmd_msg *msg;
struct _CMD_AP_PS_CLEAR_STRUC_T CmdPsClear;
int ret = 0;
msg = AndesAllocCmdMsg(ad, sizeof(struct _CMD_AP_PS_CLEAR_STRUC_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
DBGPRINT(RT_DEBUG_ERROR | DBG_FUNC_PS, ("%s:(ret = %d)\n", __FUNCTION__, ret));
goto error;
}
DBGPRINT(RT_DEBUG_INFO | DBG_FUNC_PS, ("%s(%d): RTEnqueueInternalCmd comming!! WlanIdx: %x\n",__FUNCTION__, __LINE__,wlanidx));
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_QUERY, EXT_CMD_PWR_SAVING, TRUE, 0, TRUE, TRUE, sizeof(struct _CMD_AP_PS_CLEAR_STRUC_T), NULL, CmdPsClearRsp);
NdisZeroMemory(&CmdPsClear, sizeof(CmdPsClear));
CmdPsClear.u4WlanIdx = cpu2le32(wlanidx);
CmdPsClear.u4Status = cpu2le32(0);
AndesAppendCmdMsg(msg, (char *)&CmdPsClear, sizeof(CmdPsClear));
msg->wcid = wlanidx;
ret = AndesSendCmdMsg(ad, msg);
error:
return ret;
}
#endif /* MT_PS */
static INT32 CmdRestartDLReq(RTMP_ADAPTER *ad)
{
struct cmd_msg *msg;
int ret = 0;
msg = AndesAllocCmdMsg(ad, 0);
if (!msg) {
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, MT_RESTART_DL_REQ, CMD_NA, EXT_CMD_NA, TRUE, 0, TRUE, TRUE, 0, NULL, CmdReStartDLRsp);
ret = AndesSendCmdMsg(ad, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
/*Nobody uses it currently*/
#if 0
static VOID CmdPatchSemRsp(struct cmd_msg *msg, char *Data, UINT16 Len)
{
RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)msg->priv;
struct MCU_CTRL *Ctl = &pAd->MCUCtrl;
Ctl->SemStatus = *Data;
DBGPRINT(RT_DEBUG_OFF,("Patch SEM Status=%d\n", Ctl->SemStatus));
}
static INT32 CmdPatchSemGet(RTMP_ADAPTER *ad, UINT32 Semaphore)
{
struct cmd_msg *msg;
int ret = 0;
UINT32 value;
msg = AndesAllocCmdMsg(ad, 4);
if (!msg) {
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, MT_PATCH_SEM_CONTROL, CMD_NA, EXT_CMD_NA, TRUE, 0, TRUE, TRUE, 0, NULL, CmdPatchSemRsp);
/* Semaphore */
value = cpu2le32(Semaphore);
AndesAppendCmdMsg(msg, (char *)&value, 4);
ret = AndesSendCmdMsg(ad, msg);
error:
DBGPRINT(RT_DEBUG_OFF, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
static VOID CmdHIFLoopbackRsp(struct cmd_msg *msg, char *Data, UINT16 Len)
{
UINT8 Status;
Status = *Data;
printk("HIF Loopback status=%d\n", Status);
switch (Status)
{
case TARGET_ADDRESS_LEN_SUCCESS:
DBGPRINT(RT_DEBUG_INFO, ("%s: Request target address and length success\n", __FUNCTION__));
break;
default:
DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow Status(%d)\n", __FUNCTION__, Status));
break;
}
}
static INT32 CmdHIFLoopbackReq(RTMP_ADAPTER *ad, UINT32 enable, UINT32 qidx)
{
struct cmd_msg *msg;
int ret = 0;
UINT32 value;
msg = AndesAllocCmdMsg(ad, 4);
if (!msg) {
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, MT_HIF_LOOPBACK, CMD_NA, EXT_CMD_NA, TRUE, 0, TRUE, TRUE, 0, NULL, CmdHIFLoopbackRsp);
/* start enable */
enable = (qidx << 16) | (enable & 0xffff);
value = cpu2le32(enable);
printk("loopback value=0x%x\n", value);
AndesAppendCmdMsg(msg, (char *)&value, 4);
ret = AndesSendCmdMsg(ad, msg);
error:
DBGPRINT(RT_DEBUG_OFF, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
#endif
static VOID CmdAddrellLenRsp(struct cmd_msg *msg, char *Data, UINT16 Len)
{
UINT8 Status;
Status = *Data;
switch (Status)
{
case TARGET_ADDRESS_LEN_SUCCESS:
DBGPRINT(RT_DEBUG_INFO, ("%s: Request target address and length success\n", __FUNCTION__));
break;
default:
DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow Status(%d)\n", __FUNCTION__, Status));
break;
}
}
static INT32 CmdAddressLenReq(RTMP_ADAPTER *ad, UINT32 address, UINT32 len, UINT32 data_mode)
{
struct cmd_msg *msg;
int ret = 0;
UINT32 value;
DBGPRINT(RT_DEBUG_TRACE, ("Start address = %x, DL length = %d, Data mode = %x\n",
address, len, data_mode));
msg = AndesAllocCmdMsg(ad, 12);
if (!msg) {
ret = NDIS_STATUS_RESOURCES;
goto error;
}
if (address == ROM_PATCH_START_ADDRESS)
AndesInitCmdMsg(msg, P1_Q0, MT_PATCH_START_REQ, CMD_NA, EXT_CMD_NA, TRUE, 0, TRUE, TRUE, 0, NULL, CmdAddrellLenRsp);
else
AndesInitCmdMsg(msg, P1_Q0, MT_TARGET_ADDRESS_LEN_REQ, CMD_NA, EXT_CMD_NA, TRUE, 0, TRUE, TRUE, 0, NULL, CmdAddrellLenRsp);
/* start address */
value = cpu2le32(address);
AndesAppendCmdMsg(msg, (char *)&value, 4);
/* dl length */
value = cpu2le32(len);
AndesAppendCmdMsg(msg, (char *)&value, 4);
/* data mode */
value = cpu2le32(data_mode);
AndesAppendCmdMsg(msg, (char *)&value, 4);
ret = AndesSendCmdMsg(ad, msg);
error:
DBGPRINT(RT_DEBUG_OFF, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
static INT32 CmdFwScatter(RTMP_ADAPTER *ad, UINT8 *dl_payload, UINT32 dl_len, UINT32 count)
{
struct cmd_msg *msg;
int ret = 0;
msg = AndesAllocCmdMsg(ad, dl_len);
if (!msg) {
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, 0xC000, MT_FW_SCATTER, CMD_NA, EXT_CMD_NA, FALSE, 0, FALSE, FALSE, 0, NULL, NULL);
AndesAppendCmdMsg(msg, (char *)dl_payload, dl_len);
ret = AndesSendCmdMsg(ad, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(scatter = %d, ret = %d)\n", __FUNCTION__, count, ret));
return ret;
}
static INT32 CmdFwScatters(RTMP_ADAPTER *ad, UINT8 *image, UINT32 image_len)
{
INT32 sent_len;
UINT32 cur_len = 0, count = 0;
RTMP_CHIP_CAP *cap = &ad->chipCap;
int ret = 0;
while (1)
{
INT32 sent_len_max = MT_UPLOAD_FW_UNIT - cap->cmd_header_len;
sent_len = (image_len - cur_len) >= sent_len_max ? sent_len_max : (image_len - cur_len);
if (sent_len > 0) {
ret = CmdFwScatter(ad, image + cur_len, sent_len, count);
count++;
if (ret)
goto error;
cur_len += sent_len;
} else {
break;
}
}
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
static VOID CmdPatchFinishRsp(struct cmd_msg *msg, char *Data, UINT16 Len)
{
UINT8 Status;
Status = *Data;
switch (Status)
{
case WIFI_FW_DOWNLOAD_SUCCESS:
DBGPRINT(RT_DEBUG_OFF, ("%s: WiFI ROM Patch Download Success\n", __FUNCTION__));
break;
default:
DBGPRINT(RT_DEBUG_OFF, ("%s: WiFi ROM Patch Fail (%d)\n", __FUNCTION__, Status));
break;
}
}
static INT32 CmdPatchFinishReq(RTMP_ADAPTER *ad)
{
struct cmd_msg *msg;
int ret = 0;
DBGPRINT(RT_DEBUG_OFF, ("%s\n", __FUNCTION__));
msg = AndesAllocCmdMsg(ad, 0);
if (!msg) {
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, MT_PATCH_FINISH_REQ, CMD_NA, EXT_CMD_NA, TRUE, 0, TRUE, TRUE, 0, NULL, CmdPatchFinishRsp);
ret = AndesSendCmdMsg(ad, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
static INT32 CmdFwStartReq(RTMP_ADAPTER *ad, UINT32 override, UINT32 address)
{
struct cmd_msg *msg;
int ret = 0;
UINT32 value;
DBGPRINT(RT_DEBUG_OFF, ("%s: override = %d, address = %d\n", __FUNCTION__, override, address));
msg = AndesAllocCmdMsg(ad, 8);
if (!msg) {
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, MT_FW_START_REQ, CMD_NA, EXT_CMD_NA, TRUE, 0, TRUE, TRUE, 0, NULL, CmdStartDLRsp);
/* override */
value = cpu2le32(override);
AndesAppendCmdMsg(msg, (char *)&value, 4);
/* entry point address */
value = cpu2le32(address);
AndesAppendCmdMsg(msg, (char *)&value, 4);
ret = AndesSendCmdMsg(ad, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
INT32 CmdChPrivilege(RTMP_ADAPTER *ad, UINT8 Action, UINT8 control_chl, UINT8 central_chl,
UINT8 BW, UINT8 TXStream, UINT8 RXStream)
{
struct cmd_msg *msg;
struct _CMD_CH_PRIVILEGE_T ch_privilege;
INT32 ret = 0;
struct MCU_CTRL *Ctl = &ad->MCUCtrl;
if (central_chl == 0)
{
DBGPRINT(RT_DEBUG_ERROR, ("%s: central channel = 0 is invalid\n", __FUNCTION__));
return -1;
}
DBGPRINT(RT_DEBUG_INFO, ("%s: control_chl = %d, central_chl = %d, BW = %d, \
TXStream = %d, RXStream = %d\n", __FUNCTION__, \
control_chl, central_chl, BW, TXStream, RXStream));
msg = AndesAllocCmdMsg(ad, sizeof(struct _CMD_CH_PRIVILEGE_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, CMD_CH_PRIVILEGE, CMD_SET, EXT_CMD_NA, FALSE, 0, FALSE, FALSE, 0, NULL, NULL);
memset(&ch_privilege, 0x00, sizeof(ch_privilege));
ch_privilege.ucAction = Action;
ch_privilege.ucPrimaryChannel = control_chl;
if (BW == BAND_WIDTH_20)
{
ch_privilege.ucRfSco = CMD_CH_PRIV_SCO_SCN;
}
else if (BW == BAND_WIDTH_40)
{
if (control_chl < central_chl)
ch_privilege.ucRfSco = CMD_CH_PRIV_SCO_SCA;
else
ch_privilege.ucRfSco = CMD_CH_PRIV_SCO_SCB;
}
else
{
DBGPRINT(RT_DEBUG_ERROR, ("unknown bandwidth = %d\n", BW));
}
if (central_chl > 14)
ch_privilege.ucRfBand = CMD_CH_PRIV_BAND_A;
else
ch_privilege.ucRfBand = CMD_CH_PRIV_BAND_G;
ch_privilege.ucRfChannelWidth = CMD_CH_PRIV_CH_WIDTH_20_40;
ch_privilege.ucReqType = CMD_CH_PRIV_REQ_JOIN;
AndesAppendCmdMsg(msg, (char *)&ch_privilege, sizeof(ch_privilege));
if (IS_MT7603(ad) || IS_MT7628(ad))
{
UINT32 Value;
RTMP_IO_READ32(ad, RMAC_RMCR, &Value);
if (Value & RMAC_RMCR_RX_STREAM_0)
Ctl->RxStream0 = 1;
if (Value & RMAC_RMCR_RX_STREAM_1)
Ctl->RxStream1 = 1;
Value |= RMAC_RMCR_RX_STREAM_0;
Value |= RMAC_RMCR_RX_STREAM_1;
RTMP_IO_WRITE32(ad, RMAC_RMCR, Value);
}
ret = AndesSendCmdMsg(ad, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
static VOID CmdMultipleMacRegAccessWriteCb(struct cmd_msg *msg,
char *data, UINT16 len)
{
EXT_EVENT_MULTI_CR_ACCESS_WR_T *EventMultiCRAccessWR
= (EXT_EVENT_MULTI_CR_ACCESS_WR_T *)(data + 20);
EventMultiCRAccessWR->u4Status = le2cpu32(EventMultiCRAccessWR->u4Status);
if (EventMultiCRAccessWR->u4Status)
DBGPRINT(RT_DEBUG_ERROR, ("%s: fail\n", __FUNCTION__));
}
INT32 CmdMultipleMacRegAccessWrite(RTMP_ADAPTER *pAd, RTMP_REG_PAIR *RegPair,
UINT32 Num)
{
struct cmd_msg *msg;
CMD_MULTI_CR_ACCESS_T MultiCR;
INT32 Ret;
UINT32 Index;
msg = AndesAllocCmdMsg(pAd, sizeof(CMD_MULTI_CR_ACCESS_T) * Num);
if (!msg)
{
Ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_MULTIPLE_REG_ACCESS,
TRUE, 0, TRUE, TRUE, 32, NULL, CmdMultipleMacRegAccessWriteCb);
for (Index = 0; Index < Num; Index++)
{
memset(&MultiCR, 0x00, sizeof(MultiCR));
MultiCR.u4Type = cpu2le32(MAC_CR);
MultiCR.u4Addr = cpu2le32(RegPair[Index].Register);
MultiCR.u4Data = cpu2le32(RegPair[Index].Value);
// DBGPRINT(RT_DEBUG_TRACE, ("%s: offset: = %x\n", __FUNCTION__,MultiCR.u4Addr));
AndesAppendCmdMsg(msg, (char *)&MultiCR, sizeof(MultiCR));
}
Ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, Ret));
return Ret;
}
static VOID CmdMultipleRfRegAccessWriteCb(struct cmd_msg *msg,
char *data, UINT16 len)
{
EXT_EVENT_MULTI_CR_ACCESS_WR_T *EventMultiCRAccessWR
= (EXT_EVENT_MULTI_CR_ACCESS_WR_T *)(data + 20);
EventMultiCRAccessWR->u4Status = le2cpu32(EventMultiCRAccessWR->u4Status);
if (EventMultiCRAccessWR->u4Status)
DBGPRINT(RT_DEBUG_ERROR, ("%s: fail\n", __FUNCTION__));
}
INT32 CmdMultipleRfRegAccessWrite(RTMP_ADAPTER *pAd, MT_RF_REG_PAIR *RegPair,
UINT32 Num)
{
struct cmd_msg *msg;
CMD_MULTI_CR_ACCESS_T MultiCR;
INT32 Ret;
UINT32 Index;
msg = AndesAllocCmdMsg(pAd, sizeof(CMD_MULTI_CR_ACCESS_T) * Num);
if (!msg)
{
Ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_MULTIPLE_REG_ACCESS,
TRUE, 0, TRUE, TRUE, 32, NULL, CmdMultipleRfRegAccessWriteCb);
for (Index = 0; Index < Num; Index++)
{
memset(&MultiCR, 0x00, sizeof(MultiCR));
MultiCR.u4Type = cpu2le32((RF_CR & 0xff) |
((RegPair->WiFiStream & 0xffffff) << 8));
MultiCR.u4Addr = cpu2le32(RegPair[Index].Register);
MultiCR.u4Data = cpu2le32(RegPair[Index].Value);
AndesAppendCmdMsg(msg, (char *)&MultiCR, sizeof(MultiCR));
}
Ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, Ret));
return Ret;
}
static VOID CmdMultipleRfRegAccessReadCb(struct cmd_msg *msg,
char *data, UINT16 len)
{
UINT32 Index;
UINT32 Num = (len -20) / sizeof(EXT_EVENT_MULTI_CR_ACCESS_RD_T);
EXT_EVENT_MULTI_CR_ACCESS_RD_T *EventMultiCRAccessRD
= (EXT_EVENT_MULTI_CR_ACCESS_RD_T *)(data + 20);
MT_RF_REG_PAIR *RegPair = (MT_RF_REG_PAIR *)msg->rsp_payload;
for (Index = 0; Index < Num; Index++)
{
RegPair->WiFiStream = (le2cpu32(EventMultiCRAccessRD->u4Type)
& (0xffffff << 8)) >> 8;
RegPair->Register = le2cpu32(EventMultiCRAccessRD->u4Addr);
RegPair->Value = le2cpu32(EventMultiCRAccessRD->u4Data);
EventMultiCRAccessRD++;
RegPair++;
}
}
INT32 CmdMultiPleRfRegAccessRead(RTMP_ADAPTER *pAd, MT_RF_REG_PAIR *RegPair,
UINT32 Num)
{
struct cmd_msg *msg;
CMD_MULTI_CR_ACCESS_T MultiCR;
INT32 Ret;
UINT32 Index;
msg = AndesAllocCmdMsg(pAd, sizeof(CMD_MULTI_CR_ACCESS_T) * Num);
if (!msg)
{
Ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_QUERY, EXT_CMD_MULTIPLE_REG_ACCESS,
TRUE, 0, TRUE, TRUE, (UINT16)(12 * Num) + 20, (char *)RegPair,
CmdMultipleRfRegAccessReadCb);
for (Index = 0; Index < Num; Index++)
{
memset(&MultiCR, 0x00, sizeof(MultiCR));
MultiCR.u4Type = cpu2le32((RF_CR & 0xff) |
((RegPair->WiFiStream & 0xffffff) << 8));
MultiCR.u4Addr = cpu2le32(RegPair[Index].Register);
AndesAppendCmdMsg(msg, (char *)&MultiCR, sizeof(MultiCR));
}
Ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, Ret));
return Ret;
}
static VOID CmdMultipleMacRegAccessReadCb(struct cmd_msg *msg,
char *data, UINT16 len)
{
UINT32 Index;
UINT32 Num = (len - 20) / sizeof(EXT_EVENT_MULTI_CR_ACCESS_RD_T);
EXT_EVENT_MULTI_CR_ACCESS_RD_T *EventMultiCRAccessRD
= (EXT_EVENT_MULTI_CR_ACCESS_RD_T *)(data + 20);
RTMP_REG_PAIR *RegPair = (RTMP_REG_PAIR *)msg->rsp_payload;
for (Index = 0; Index < Num; Index++)
{
RegPair->Register = le2cpu32(EventMultiCRAccessRD->u4Addr);
RegPair->Value = le2cpu32(EventMultiCRAccessRD->u4Data);
EventMultiCRAccessRD++;
RegPair++;
}
}
INT32 CmdMultiPleMacRegAccessRead(RTMP_ADAPTER *pAd, RTMP_REG_PAIR *RegPair,
UINT32 Num)
{
struct cmd_msg *msg;
CMD_MULTI_CR_ACCESS_T MultiCR;
INT32 Ret;
UINT32 Index;
msg = AndesAllocCmdMsg(pAd, sizeof(CMD_MULTI_CR_ACCESS_T) * Num);
if (!msg)
{
Ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_QUERY, EXT_CMD_MULTIPLE_REG_ACCESS,
TRUE, 0, TRUE, TRUE, (UINT16)(12 * Num) + 20, (char *)RegPair,
CmdMultipleMacRegAccessReadCb);
for (Index = 0; Index < Num; Index++)
{
memset(&MultiCR, 0x00, sizeof(MultiCR));
MultiCR.u4Type = cpu2le32(MAC_CR);
MultiCR.u4Addr = cpu2le32(RegPair[Index].Register);
AndesAppendCmdMsg(msg, (char *)&MultiCR, sizeof(MultiCR));
}
Ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, Ret));
return Ret;
}
INT32 CmdAccessRegWrite(RTMP_ADAPTER *ad, UINT32 address, UINT32 data)
{
struct cmd_msg *msg;
struct _CMD_ACCESS_REG_T access_reg;
INT32 ret = 0;
DBGPRINT(RT_DEBUG_INFO, ("%s: address = %x, data = %x\n", __FUNCTION__, address, data));
msg = AndesAllocCmdMsg(ad, sizeof(struct _CMD_ACCESS_REG_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, CMD_ACCESS_REG, CMD_SET, EXT_CMD_NA, FALSE, 0, FALSE, FALSE, 0, NULL, NULL);
memset(&access_reg, 0x00, sizeof(access_reg));
access_reg.u4Address = cpu2le32(address);
access_reg.u4Data = cpu2le32(data);
AndesAppendCmdMsg(msg, (char *)&access_reg, sizeof(access_reg));
ret = AndesSendCmdMsg(ad, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
static VOID CmdAccessRegReadCb(struct cmd_msg *msg, char *data, UINT16 len)
{
struct _CMD_ACCESS_REG_T *access_reg = (struct _CMD_ACCESS_REG_T *)data;
DBGPRINT(RT_DEBUG_INFO, ("%s\n", __FUNCTION__));
NdisMoveMemory(msg->rsp_payload, &access_reg->u4Data, len - 4);
*((UINT32 *)(msg->rsp_payload)) = le2cpu32(*((UINT32 *)msg->rsp_payload));
}
INT32 CmdAccessRegRead(RTMP_ADAPTER *pAd, UINT32 address, UINT32 *data)
{
struct cmd_msg *msg;
struct _CMD_ACCESS_REG_T access_reg;
INT32 ret = 0;
msg = AndesAllocCmdMsg(pAd, sizeof(struct _CMD_ACCESS_REG_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, CMD_ACCESS_REG, CMD_QUERY, EXT_CMD_NA, TRUE, 0,
TRUE, TRUE, 8, (CHAR *)data, CmdAccessRegReadCb);
memset(&access_reg, 0x00, sizeof(access_reg));
access_reg.u4Address = cpu2le32(address);
AndesAppendCmdMsg(msg, (char *)&access_reg, sizeof(access_reg));
ret = AndesSendCmdMsg(pAd, msg);
DBGPRINT(RT_DEBUG_INFO, ("%s: address = %x, value = %x\n", __FUNCTION__, address, *data));
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
INT32 CmdRFRegAccessWrite(RTMP_ADAPTER *pAd, UINT32 RFIdx, UINT32 Offset, UINT32 Value)
{
struct cmd_msg *msg;
struct _CMD_RF_REG_ACCESS_T RFRegAccess;
INT32 ret = 0;
DBGPRINT(RT_DEBUG_INFO, ("%s: RFIdx = %d, Offset = %x, Value = %x\n", __FUNCTION__,\
RFIdx, Offset, Value));
msg = AndesAllocCmdMsg(pAd, sizeof(struct _CMD_RF_REG_ACCESS_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_RF_REG_ACCESS, FALSE, 0, FALSE, FALSE, 0, NULL, NULL);
memset(&RFRegAccess, 0x00, sizeof(RFRegAccess));
RFRegAccess.WiFiStream = cpu2le32(RFIdx);
RFRegAccess.Address = cpu2le32(Offset);
RFRegAccess.Data = cpu2le32(Value);
AndesAppendCmdMsg(msg, (char *)&RFRegAccess, sizeof(RFRegAccess));
ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
static VOID CmdRFRegAccessReadCb(struct cmd_msg *msg, char *Data, UINT16 Len)
{
struct _CMD_RF_REG_ACCESS_T *RFRegAccess = (struct _CMD_RF_REG_ACCESS_T *)Data;
NdisMoveMemory(msg->rsp_payload, &RFRegAccess->Data, Len - 8);
*((UINT32 *)msg->rsp_payload) = le2cpu32(*((UINT32 *)msg->rsp_payload));
}
INT32 CmdRFRegAccessRead(RTMP_ADAPTER *pAd, UINT32 RFIdx, UINT32 Offset, UINT32 *Value)
{
struct cmd_msg *msg;
struct _CMD_RF_REG_ACCESS_T RFRegAccess;
INT32 ret = 0;
DBGPRINT(RT_DEBUG_INFO, ("%s: RFIdx = %d, Offset = %x\n", __FUNCTION__, RFIdx, Offset));
msg = AndesAllocCmdMsg(pAd, sizeof(struct _CMD_RF_REG_ACCESS_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_QUERY, EXT_CMD_RF_REG_ACCESS, TRUE, 0,
TRUE, TRUE, 12, (CHAR *)Value, CmdRFRegAccessReadCb);
memset(&RFRegAccess, 0x00, sizeof(RFRegAccess));
RFRegAccess.WiFiStream = cpu2le32(RFIdx);
RFRegAccess.Address = cpu2le32(Offset);
AndesAppendCmdMsg(msg, (char *)&RFRegAccess, sizeof(RFRegAccess));
ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
VOID CmdIOWrite32(RTMP_ADAPTER *pAd, UINT32 Offset, UINT32 Value)
{
struct MCU_CTRL *Ctl = &pAd->MCUCtrl;
RTMP_REG_PAIR RegPair;
if (Ctl->Stage == FW_RUN_TIME)
{
RegPair.Register = Offset;
RegPair.Value = Value;
CmdMultipleMacRegAccessWrite(pAd, &RegPair, 1);
}
#ifdef E2P_WITHOUT_FW_SUPPORT
else if (Ctl->Stage == FW_NO_INIT)
{
RTMP_IO_WRITE32(pAd, Offset, Value);
}
#endif /* E2P_WITHOUT_FW_SUPPORT */
else
{
CmdInitAccessRegWrite(pAd, Offset, Value);
}
}
VOID CmdIORead32(struct _RTMP_ADAPTER *pAd, UINT32 Offset, UINT32 *Value)
{
struct MCU_CTRL *Ctl = &pAd->MCUCtrl;
RTMP_REG_PAIR RegPair;
RegPair.Value = 0;
if (Ctl->Stage == FW_RUN_TIME)
{
RegPair.Register = Offset;
CmdMultiPleMacRegAccessRead(pAd, &RegPair, 1);
*Value = RegPair.Value;
}
#ifdef E2P_WITHOUT_FW_SUPPORT
else if (Ctl->Stage == FW_NO_INIT)
{
RTMP_IO_READ32(pAd, Offset, Value);
}
#endif /* E2P_WITHOUT_FW_SUPPORT */
else
{
CmdInitAccessRegRead(pAd, Offset, Value);
}
}
static VOID EventExtCmdResult(struct cmd_msg *msg, char *Data, UINT16 Len)
{
struct _EVENT_EXT_CMD_RESULT_T *EventExtCmdResult = (struct _EVENT_EXT_CMD_RESULT_T *)Data;
RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)msg->priv;
DBGPRINT(RT_DEBUG_INFO, ("%s: EventExtCmdResult.ucExTenCID = 0x%x\n",
__FUNCTION__, EventExtCmdResult->ucExTenCID));
EventExtCmdResult->u4Status = le2cpu32(EventExtCmdResult->u4Status);
DBGPRINT(RT_DEBUG_INFO, ("%s: EventExtCmdResult.u4Status = 0x%x\n",
__FUNCTION__, EventExtCmdResult->u4Status));
RTMP_OS_TXRXHOOK_CALL(WLAN_CALIB_TEST_RSP, NULL, (UCHAR)EventExtCmdResult->u4Status, pAd);
}
VOID EventExtCmdResultHandler(RTMP_ADAPTER *pAd, char *Data, UINT16 Len)
{
struct _EVENT_EXT_CMD_RESULT_T *EventExtCmdResult = (struct _EVENT_EXT_CMD_RESULT_T *)Data;
//RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)msg->priv;
DBGPRINT(RT_DEBUG_INFO, ("%s: EventExtCmdResult.ucExTenCID = 0x%x\n",
__FUNCTION__, EventExtCmdResult->ucExTenCID));
EventExtCmdResult->u4Status = le2cpu32(EventExtCmdResult->u4Status);
DBGPRINT(RT_DEBUG_INFO, ("%s: EventExtCmdResult.u4Status = 0x%x\n",
__FUNCTION__, EventExtCmdResult->u4Status));
RTMP_OS_TXRXHOOK_CALL(WLAN_CALIB_TEST_RSP, NULL, (UCHAR)EventExtCmdResult->u4Status, pAd);
}
INT32 CmdIcapOverLap(RTMP_ADAPTER *pAd, UINT32 IcapLen)
{
struct cmd_msg *msg;
struct _CMD_TEST_CTRL_T TestCtrl;
INT32 ret = 0;
DBGPRINT(RT_DEBUG_INFO, ("%s: IcapLen = %d\n", __FUNCTION__, IcapLen));
msg = AndesAllocCmdMsg(pAd, sizeof(TestCtrl));
if (!msg) {
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_RF_TEST, TRUE, 0,
TRUE, TRUE, 8, NULL, EventExtCmdResult);
memset(&TestCtrl, 0x00, sizeof(TestCtrl));
TestCtrl.ucAction = 0;
TestCtrl.ucIcapLen = (UINT8)IcapLen;
TestCtrl.u.u4OpMode = OPERATION_ICAP_OVERLAP;
AndesAppendCmdMsg(msg, (char *)&TestCtrl, sizeof(TestCtrl));
ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
INT32 CmdRfTest(RTMP_ADAPTER *pAd, UINT8 Action, UINT8 Mode, UINT8 CalItem)
{
struct cmd_msg *msg;
struct _CMD_TEST_CTRL_T TestCtrl;
INT32 ret = 0;
DBGPRINT(RT_DEBUG_INFO, ("%s: Action = %d Mode = %d CalItem = %d\n", __FUNCTION__, Action, Mode, CalItem));
msg = AndesAllocCmdMsg(pAd, sizeof(TestCtrl));
if (!msg) {
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_RF_TEST, TRUE, 0,
TRUE, TRUE, 8, NULL, EventExtCmdResult);
memset(&TestCtrl, 0x00, sizeof(TestCtrl));
TestCtrl.ucAction = Action;
TestCtrl.u.u4OpMode = (UINT32)Mode;
if (Action == ACTION_IN_RFTEST) {
/* set Cal Items */
TestCtrl.u.rRfATInfo.u4FuncIndex = 1;
TestCtrl.u.rRfATInfo.u4FuncData = (UINT32)CalItem;
}
AndesAppendCmdMsg(msg, (char *)&TestCtrl, sizeof(TestCtrl));
ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
INT32 CmdRadioOnOffCtrl(RTMP_ADAPTER *pAd, UINT8 On)
{
struct cmd_msg *msg;
struct _EXT_CMD_RADIO_ON_OFF_CTRL_T RadioOnOffCtrl;
INT32 ret = 0;
DBGPRINT(RT_DEBUG_INFO, ("%s: On = %d\n", __FUNCTION__, On));
msg = AndesAllocCmdMsg(pAd, sizeof(RadioOnOffCtrl));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_RADIO_ON_OFF_CTRL, TRUE, 0,
TRUE, TRUE, 8, NULL, EventExtCmdResult);
memset(&RadioOnOffCtrl, 0x00, sizeof(RadioOnOffCtrl));
if (On == WIFI_RADIO_ON)
RadioOnOffCtrl.ucWiFiRadioCtrl = WIFI_RADIO_ON;
else if (On == WIFI_RADIO_OFF)
RadioOnOffCtrl.ucWiFiRadioCtrl = WIFI_RADIO_OFF;
else
DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknown state On = %d\n", __FUNCTION__, On));
AndesAppendCmdMsg(msg, (char *)&RadioOnOffCtrl, sizeof(RadioOnOffCtrl));
ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
INT32 CmdWiFiRxDisable(RTMP_ADAPTER *pAd, UINT RxDisable)
{
struct cmd_msg *msg;
struct _EXT_CMD_WIFI_RX_DISABLE_T WiFiRxDisable;
INT32 ret = 0;
DBGPRINT(RT_DEBUG_INFO, ("%s: WiFiRxDisable = %d\n", __FUNCTION__, RxDisable));
if (RxDisable != WIFI_RX_DISABLE)
{
DBGPRINT(RT_DEBUG_ERROR, ("Error: %s: RxDisable = %d\n", __FUNCTION__, RxDisable));
return ret;
}
msg = AndesAllocCmdMsg(pAd, sizeof(WiFiRxDisable));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_WIFI_RX_DISABLE, TRUE, 0,
TRUE, TRUE, 8, NULL, EventExtCmdResult);
memset(&WiFiRxDisable, 0x00, sizeof(WiFiRxDisable));
WiFiRxDisable.ucWiFiRxDisableCtrl = (UINT8)RxDisable;
AndesAppendCmdMsg(msg, (char *)&WiFiRxDisable, sizeof(WiFiRxDisable));
ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
//NoA
INT32 CmdP2pNoaOffloadCtrl(RTMP_ADAPTER *ad, UINT8 enable)
{
struct cmd_msg *msg;
struct _EXT_CMD_NOA_CTRL_T extCmdNoaCtrl;
int ret = 0;
msg = AndesAllocCmdMsg(ad, sizeof(struct _EXT_CMD_NOA_CTRL_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_ID_NOA_OFFLOAD_CTRL,
TRUE, 0, TRUE, TRUE,
sizeof(struct _EXT_CMD_NOA_CTRL_T), NULL, EventExtCmdResult);
NdisZeroMemory(&extCmdNoaCtrl, sizeof(extCmdNoaCtrl));
extCmdNoaCtrl.ucMode1 = (UINT8)cpu2le32(enable);
//extCmdNoaCtrl.ucMode0 = cpu2le32(enable);
AndesAppendCmdMsg(msg, (char *)&extCmdNoaCtrl, sizeof(extCmdNoaCtrl));
ret = AndesSendCmdMsg(ad, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
#ifdef SINGLE_SKU_V2
enum {
SKU_CCK_1_2=0,
SKU_CCK_55_11,
SKU_OFDM_6_9,
SKU_OFDM_12_18,
SKU_OFDM_24_36,
SKU_OFDM_48,
SKU_OFDM_54,
SKU_HT20_0_8,
SKU_HT20_32,
SKU_HT20_1_2_9_10,
SKU_HT20_3_4_11_12,
SKU_HT20_5_13,
SKU_HT20_6_14,
SKU_HT20_7_15,
SKU_HT40_0_8,
SKU_HT40_32,
SKU_HT40_1_2_9_10,
SKU_HT40_3_4_11_12,
SKU_HT40_5_13,
SKU_HT40_6_14,
SKU_HT40_7_15,
};
static VOID mt_FillSkuParameter(RTMP_ADAPTER *pAd,UINT8 channel,UINT8 *txPowerSku)
{
CH_POWER *ch, *ch_temp;
UCHAR start_ch;
//UCHAR base_pwr = pAd->DefaultTargetPwr;
UINT8 j;
DlListForEachSafe(ch, ch_temp, &pAd->SingleSkuPwrList, CH_POWER, List)
{
start_ch = ch->StartChannel;
if ( channel >= start_ch )
{
for ( j = 0; j < ch->num; j++ )
{
if ( channel == ch->Channel[j] )
{
txPowerSku[SKU_CCK_1_2] = ch->PwrCCK[0] ? ch->PwrCCK[0] : 0xff;
txPowerSku[SKU_CCK_55_11] = ch->PwrCCK[2] ? ch->PwrCCK[2] : 0xff;
txPowerSku[SKU_OFDM_6_9] = ch->PwrOFDM[0] ? ch->PwrOFDM[0] : 0xff;
txPowerSku[SKU_OFDM_12_18]= ch->PwrOFDM[2] ? ch->PwrOFDM[2] : 0xff;
txPowerSku[SKU_OFDM_24_36]= ch->PwrOFDM[4] ? ch->PwrOFDM[4] : 0xff;
txPowerSku[SKU_OFDM_48] = ch->PwrOFDM[6] ? ch->PwrOFDM[6] : 0xff;
txPowerSku[SKU_OFDM_54] = ch->PwrOFDM[7] ? ch->PwrOFDM[7] : 0xff;
txPowerSku[SKU_HT20_0_8] = ch->PwrHT20[0] ? ch->PwrHT20[2] : 0xff;
txPowerSku[SKU_HT20_32] = 0xff;
txPowerSku[SKU_HT20_1_2_9_10] = ch->PwrHT20[1] ? ch->PwrHT20[1] : 0xff;
txPowerSku[SKU_HT20_3_4_11_12] = ch->PwrHT20[3] ? ch->PwrHT20[3] : 0xff;
txPowerSku[SKU_HT20_5_13] = ch->PwrHT20[5] ? ch->PwrHT20[5] : 0xff;
txPowerSku[SKU_HT20_6_14] = ch->PwrHT20[6] ? ch->PwrHT20[6] : 0xff;
txPowerSku[SKU_HT20_7_15] = ch->PwrHT20[7] ? ch->PwrHT20[7] : 0xff;
txPowerSku[SKU_HT40_0_8] = ch->PwrHT40[0] ? ch->PwrHT40[0] : 0xff;
txPowerSku[SKU_HT40_32] = 0xff;
txPowerSku[SKU_HT40_1_2_9_10] = ch->PwrHT40[1] ? ch->PwrHT40[1] : 0xff;
txPowerSku[SKU_HT40_3_4_11_12] = ch->PwrHT40[3] ? ch->PwrHT40[3] : 0xff;
txPowerSku[SKU_HT40_5_13] = ch->PwrHT40[5] ? ch->PwrHT40[5] : 0xff;
txPowerSku[SKU_HT40_6_14] = ch->PwrHT40[6] ? ch->PwrHT40[6] : 0xff;
txPowerSku[SKU_HT40_7_15] = ch->PwrHT40[7] ? ch->PwrHT40[7] : 0xff;
break;
}
}
}
}
}
#endif
INT32 CmdChannelSwitch(RTMP_ADAPTER *pAd, UINT8 control_chl, UINT8 central_chl,
UINT8 BW, UINT8 TXStream, UINT8 RXStream)
{
struct cmd_msg *msg;
struct _EXT_CMD_CHAN_SWITCH_T CmdChanSwitch;
INT32 ret = 0,i=0;
#ifdef RTMP_SDIO_SUPPORT
return 0;
#endif /*leonardo for SDIO FPGA pass*/
if (central_chl == 0)
{
DBGPRINT(RT_DEBUG_ERROR, ("%s: central channel = 0 is invalid\n", __FUNCTION__));
return -1;
}
DBGPRINT(RT_DEBUG_INFO, ("%s: control_chl = %d, central_chl = %d, BW = %d, \
TXStream = %d, RXStream = %d\n", __FUNCTION__, \
control_chl, central_chl, BW, TXStream, RXStream));
msg = AndesAllocCmdMsg(pAd, sizeof(CmdChanSwitch));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_CHANNEL_SWITCH, TRUE, 0,
TRUE, TRUE, 8, NULL, EventExtCmdResult);
memset(&CmdChanSwitch, 0x00, sizeof(CmdChanSwitch));
CmdChanSwitch.ucCtrlCh = control_chl;
CmdChanSwitch.ucCentralCh = central_chl;
CmdChanSwitch.ucBW = BW;
CmdChanSwitch.ucTxStreamNum = TXStream;
CmdChanSwitch.ucRxStreamNum = RXStream;
for(i=0;i<SKU_SIZE;i++)
{
CmdChanSwitch.aucTxPowerSKU[i]=0xff;
}
#ifdef SINGLE_SKU_V2
if (pAd->SKUEn)
mt_FillSkuParameter(pAd,central_chl,CmdChanSwitch.aucTxPowerSKU);
#endif
AndesAppendCmdMsg(msg, (char *)&CmdChanSwitch, sizeof(CmdChanSwitch));
ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
static VOID EventExtNicCapability(struct cmd_msg *msg, char *Data, UINT16 Len)
{
struct _EXT_EVENT_NIC_CAPABILITY_T *ExtEventNicCapability = (EXT_EVENT_NIC_CAPABILITY *)Data;
UINT32 Loop;
DBGPRINT(RT_DEBUG_OFF, ("The data code of firmware:"));
for (Loop = 0; Loop < 16; Loop++)
{
DBGPRINT(RT_DEBUG_OFF, ("%c", ExtEventNicCapability->aucDateCode[Loop]));
}
DBGPRINT(RT_DEBUG_OFF, ("\nThe version code of firmware:"));
for (Loop = 0; Loop < 12; Loop++)
{
DBGPRINT(RT_DEBUG_OFF, ("%c", ExtEventNicCapability->aucVersionCode[Loop]));
}
}
INT32 CmdNicCapability(RTMP_ADAPTER *pAd)
{
struct cmd_msg *msg;
INT32 ret = 0;
msg = AndesAllocCmdMsg(pAd, 0);
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_QUERY, EXT_CMD_NIC_CAPABILITY, TRUE, 0,
TRUE, TRUE, 28, NULL, EventExtNicCapability);
ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
INT32 CmdFwLog2Host(RTMP_ADAPTER *pAd, UINT8 FWLog2HostCtrl)
{
struct cmd_msg *msg;
INT32 Ret = 0;
EXT_CMD_FW_LOG_2_HOST_CTRL_T CmdFwLog2HostCtrl;
msg = AndesAllocCmdMsg(pAd, sizeof(CmdFwLog2HostCtrl));
if (!msg)
{
Ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_QUERY, EXT_CMD_FW_LOG_2_HOST,
FALSE, 0, FALSE, FALSE, 0, NULL, NULL);
memset(&CmdFwLog2HostCtrl, 0x00, sizeof(CmdFwLog2HostCtrl));
CmdFwLog2HostCtrl.ucFwLog2HostCtrl = FWLog2HostCtrl;
AndesAppendCmdMsg(msg, (char *)&CmdFwLog2HostCtrl,
sizeof(CmdFwLog2HostCtrl));
Ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, Ret));
return Ret;
}
#ifdef BCN_OFFLOAD_SUPPORT
static VOID ExtEventBcnUpdateHandler(RTMP_ADAPTER *pAd, UINT8 *Data, UINT32 Length)
{
if ((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) ||
(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) ||
(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) ||
(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
{
return;
}
RTMP_UPDATE_BCN(pAd);
}
#endif
#ifdef THERMAL_PROTECT_SUPPORT
static VOID EventThermalProtect(RTMP_ADAPTER *pAd, UINT8 *Data, UINT32 Length)
{
EXT_EVENT_THERMAL_PROTECT_T *EvtThermalProtect;
UINT8 HLType;
UINT32 ret;
EvtThermalProtect = (EXT_EVENT_THERMAL_PROTECT_T *)Data;
HLType = EvtThermalProtect->ucHLType;
pAd->last_thermal_pro_temp = EvtThermalProtect->cCurrentTemp;
DBGPRINT(RT_DEBUG_OFF, ("%s: HLType = %d, CurrentTemp = %d\n", __FUNCTION__, HLType, pAd->last_thermal_pro_temp));
RTMP_SEM_EVENT_WAIT(&pAd->AutoRateLock, ret);
if (HLType == HIGH_TEMP_THD)
{
pAd->force_one_tx_stream = TRUE;
DBGPRINT(RT_DEBUG_OFF, ("Switch TX to 1 stram\n"));
}
else
{
pAd->force_one_tx_stream = FALSE;
DBGPRINT(RT_DEBUG_OFF, ("Switch TX to 2 stram\n"));
}
pAd->switch_tx_stream = TRUE;
pAd->fgThermalProtectToggle = TRUE;
RTMP_SEM_EVENT_UP(&pAd->AutoRateLock);
}
INT32 CmdThermalProtect(RTMP_ADAPTER *ad, UINT8 HighEn, CHAR HighTempTh, UINT8 LowEn, CHAR LowTempTh)
{
struct cmd_msg *msg;
INT32 ret = 0;
EXT_CMD_THERMAL_PROTECT_T ThermalProtect;
msg = AndesAllocCmdMsg(ad, sizeof(EXT_CMD_THERMAL_PROTECT_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_THERMAL_PROTECT, TRUE, 0, TRUE, TRUE, 8, NULL, EventExtCmdResult);
NdisZeroMemory(&ThermalProtect, sizeof(ThermalProtect));
ThermalProtect.ucHighEnable = HighEn;
ThermalProtect.cHighTempThreshold = HighTempTh;
ThermalProtect.ucLowEnable = LowEn;
ThermalProtect.cLowTempThreshold = LowTempTh;
ad->thermal_pro_high_criteria = HighTempTh;
ad->thermal_pro_high_en = HighEn;
ad->thermal_pro_low_criteria = LowTempTh;
ad->thermal_pro_low_en = LowEn;
AndesAppendCmdMsg(msg, (char *)&ThermalProtect, sizeof(ThermalProtect));
ret = AndesSendCmdMsg(ad, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
#endif
#ifdef BCN_OFFLOAD_SUPPORT
/*****************************************
ExT_CID = 0x33
*****************************************/
INT32 CmdBcnUpdateSet(RTMP_ADAPTER *pAd, CMD_BCN_UPDATE_T bcn_update)
{
struct cmd_msg *msg;
INT32 ret=0,size=0;
size = sizeof(CMD_BCN_UPDATE_T);
msg = AndesAllocCmdMsg(pAd, size);
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_ID_BCN_UPDATE, FALSE, 0, FALSE, FALSE, 0, NULL, NULL);
AndesAppendCmdMsg(msg, (char *)&bcn_update, size);
ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_OFF, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
#endif
#define TOP_MISC2 0x1134
#define SW_SYN0 0x81021250
static NDIS_STATUS AndesMTLoadFwMethod1(RTMP_ADAPTER *ad)
{
UINT32 value, loop, dl_len;
UINT32 ret = 0;
RTMP_CHIP_CAP *cap = &ad->chipCap;
#ifdef RTMP_PCI_SUPPORT
POS_COOKIE obj = (POS_COOKIE)ad->OS_Cookie;
#endif /* RTMP_PCI_SUPPORT */
struct MCU_CTRL *Ctl = &ad->MCUCtrl;
#ifdef RTMP_PCI_SUPPORT
UINT32 RemapBase, RemapOffset;
UINT32 RestoreValue;
#endif
if (cap->load_code_method == BIN_FILE_METHOD) {
DBGPRINT(RT_DEBUG_OFF, ("load fw image from /lib/firmware/%s\n", cap->fw_bin_file_name));
#ifdef RTMP_PCI_SUPPORT
OS_LOAD_CODE_FROM_BIN(&cap->FWImageName, cap->fw_bin_file_name, obj->pci_dev, &cap->fw_len);
#endif
} else {
cap->FWImageName = cap->fw_header_image;
}
if (!cap->FWImageName) {
if (cap->load_code_method == BIN_FILE_METHOD) {
DBGPRINT(RT_DEBUG_ERROR, ("%s:Please assign a fw image(/lib/firmware/%s), load_method(%d)\n", __FUNCTION__, cap->fw_bin_file_name, cap->load_code_method));
} else {
DBGPRINT(RT_DEBUG_ERROR, ("%s:Please assign a fw image, load_method(%d)\n",
__FUNCTION__, cap->load_code_method));
}
ret = NDIS_STATUS_FAILURE;
goto done;
}
Ctl->Stage = FW_DOWNLOAD;
DBGPRINT(RT_DEBUG_OFF, ("FW Version:"));
for (loop = 0; loop < 10; loop++)
DBGPRINT(RT_DEBUG_OFF, ("%c", *(cap->FWImageName + cap->fw_len - 29 + loop)));
DBGPRINT(RT_DEBUG_OFF, ("\n"));
DBGPRINT(RT_DEBUG_OFF, ("FW Build Date:"));
for (loop = 0; loop < 15; loop++)
DBGPRINT(RT_DEBUG_OFF, ("%c", *(cap->FWImageName + cap->fw_len - 19 + loop)));
DBGPRINT(RT_DEBUG_OFF, ("\n"));
dl_len = (*(cap->FWImageName + cap->fw_len - 1) << 24) |
(*(cap->FWImageName + cap->fw_len - 2) << 16) |
(*(cap->FWImageName + cap->fw_len -3) << 8) |
*(cap->FWImageName + cap->fw_len - 4);
dl_len += 4; /* including crc value */
DBGPRINT(RT_DEBUG_INFO, ("\ndownload len = %d\n", dl_len));
#ifdef RTMP_PCI_SUPPORT
if (IS_MT7603(ad))
{
RTMP_IO_READ32(ad, MCU_PCIE_REMAP_1, &RestoreValue);
RemapBase = GET_REMAP_1_BASE(0x50012498) << 18;
RemapOffset = GET_REMAP_1_OFFSET(0x50012498);
RTMP_IO_WRITE32(ad, MCU_PCIE_REMAP_1, RemapBase);
RTMP_IO_WRITE32(ad, 0x40000 + RemapOffset, 0x5);
RTMP_IO_WRITE32(ad, 0x40000 + RemapOffset, 0x5);
RtmpusecDelay(1);
RTMP_IO_WRITE32(ad, MCU_PCIE_REMAP_1, RestoreValue);
}
#endif
#if defined(RTMP_PCI_SUPPORT) || defined(RTMP_USB_SUPPORT)
/* switch to bypass mode */
RTMP_IO_READ32(ad, SCH_REG4, &value);
value &= ~SCH_REG4_BYPASS_MODE_MASK;
value |= SCH_REG4_BYPASS_MODE(1);
#ifdef RTMP_PCI_SUPPORT
value &= ~SCH_REG4_FORCE_QID_MASK;
value |= SCH_REG4_FORCE_QID(5);
#endif
#ifdef RTMP_USB_SUPPORT
value &= ~SCH_REG4_FORCE_QID_MASK;
value |= SCH_REG4_FORCE_QID(8);
#endif
RTMP_IO_WRITE32(ad, SCH_REG4, value);
#endif
/* optional CMD procedure */
/* CMD restart download flow request */
RTMP_IO_READ32(ad, TOP_MISC2, &value);
DBGPRINT(RT_DEBUG_INFO, ("TOP_MSIC = %x\n", value));
/* check ram code if running, if it is, need to do optional cmd procedure */
if ((value & 0x02) == 0x02) {
#ifdef LOAD_FW_ONE_TIME
ret = NDIS_STATUS_SUCCESS;
Ctl->Stage = FW_RUN_TIME;
ad->FWLoad = 1;
goto done;
#else /* LOAD_FW_ONE_TIME */
ret = CmdRestartDLReq(ad);
if (ret)
goto done;
#endif /* !LOAD_FW_ONE_TIME */
}
/* check rom code if ready */
loop = 0;
do
{
RTMP_IO_READ32(ad, TOP_MISC2, &value);
if((value & 0x01) == 0x01 && !(value & 0x02))
break;
RtmpOsMsDelay(1);
loop++;
} while (loop <= 500);
if (loop > 500) {
DBGPRINT(RT_DEBUG_ERROR, ("%s: rom code is not ready(TOP_MISC2 = %d)\n", __FUNCTION__, value));
goto done;
}
/* standard CMD procedure */
/* 1. Config PDA phase */
ret = CmdAddressLenReq(ad, FW_CODE_START_ADDRESS1, dl_len, TARGET_ADDR_LEN_NEED_RSP);
if (ret)
goto done;
/* 2. Loading firmware image phase */
ret = CmdFwScatters(ad, cap->FWImageName, dl_len);
if (ret)
goto done;
/* 3. Firmware start negotiation phase */
ret = CmdFwStartReq(ad, 1, FW_CODE_START_ADDRESS1);
/* 4. check Firmware running */
for (loop = 0; loop < 500; loop++)
{
RTMP_IO_READ32(ad, TOP_MISC2, &value);
DBGPRINT(RT_DEBUG_INFO, ("TOP_MSIC = %x\n", value));
if ((value & 0x02) == 0x02)
break;
RtmpOsMsDelay(1);
}
if (loop == 500)
{
ret = NDIS_STATUS_FAILURE;
DBGPRINT(RT_DEBUG_OFF, ("firmware loading failure\n"));
Ctl->Stage = FW_NO_INIT;
}
else
{
Ctl->Stage = FW_RUN_TIME;
}
done:
#if defined(RTMP_PCI_SUPPORT) || defined(RTMP_USB_SUPPORT)
/* Switch to normal mode */
RTMP_IO_READ32(ad, SCH_REG4, &value);
value &= ~SCH_REG4_BYPASS_MODE_MASK;
value |= SCH_REG4_BYPASS_MODE(0);
value &= ~SCH_REG4_FORCE_QID_MASK;
value |= SCH_REG4_FORCE_QID(0);
RTMP_IO_WRITE32(ad, SCH_REG4, value);
RTMP_IO_READ32(ad, SCH_REG4, &value);
value |= (1 << 8);
RTMP_IO_WRITE32(ad, SCH_REG4, value);
RTMP_IO_READ32(ad, SCH_REG4, &value);
value &= ~(1 << 8);
RTMP_IO_WRITE32(ad, SCH_REG4, value);
#endif
return ret;
}
static NDIS_STATUS AndesMTLoadFwMethod2(RTMP_ADAPTER *ad)
{
UINT32 value, loop, ilm_dl_len, dlm_dl_len;
UINT8 ilm_feature_set, dlm_feature_set;
UINT8 ilm_chip_info, dlm_chip_info;
UINT32 ilm_target_addr, dlm_target_addr;
UINT32 ret = 0;
RTMP_CHIP_CAP *cap = &ad->chipCap;
#ifdef RTMP_PCI_SUPPORT
POS_COOKIE obj = (POS_COOKIE)ad->OS_Cookie;
#endif /* RTMP_PCI_SUPPORT */
struct MCU_CTRL *Ctl = &ad->MCUCtrl;
if (cap->load_code_method == BIN_FILE_METHOD) {
DBGPRINT(RT_DEBUG_OFF, ("load fw image from /lib/firmware/%s\n", cap->fw_bin_file_name));
#ifdef RTMP_PCI_SUPPORT
OS_LOAD_CODE_FROM_BIN(&cap->FWImageName, cap->fw_bin_file_name, obj->pci_dev, &cap->fw_len);
#endif
} else {
cap->FWImageName = cap->fw_header_image;
}
if (!cap->FWImageName) {
if (cap->load_code_method == BIN_FILE_METHOD) {
DBGPRINT(RT_DEBUG_ERROR, ("%s:Please assign a fw image(/lib/firmware/%s), load_method(%d)\n", __FUNCTION__, cap->fw_bin_file_name, cap->load_code_method));
} else {
DBGPRINT(RT_DEBUG_ERROR, ("%s:Please assign a fw image, load_method(%d)\n",
__FUNCTION__, cap->load_code_method));
}
ret = NDIS_STATUS_FAILURE;
goto done;
}
Ctl->Stage = FW_DOWNLOAD;
ilm_target_addr = (*(cap->FWImageName + cap->fw_len - (33 + 36)) << 24) |
(*(cap->FWImageName + cap->fw_len - (34 + 36)) << 16) |
(*(cap->FWImageName + cap->fw_len -(35 + 36)) << 8) |
*(cap->FWImageName + cap->fw_len - (36 + 36));
DBGPRINT(RT_DEBUG_TRACE, ("ILM target address = %x\n", ilm_target_addr));
ilm_chip_info = *(cap->FWImageName + cap->fw_len - (32 + 36));
DBGPRINT(RT_DEBUG_TRACE, ("\nILM chip information = %x\n", ilm_chip_info));
ilm_feature_set = *(cap->FWImageName + cap->fw_len - (31 + 36));
DBGPRINT(RT_DEBUG_TRACE, ("\nILM feature set = %x\n", ilm_feature_set));
DBGPRINT(RT_DEBUG_TRACE, ("\nILM Build Date:"));
for (loop = 0; loop < 8; loop++)
DBGPRINT(RT_DEBUG_OFF, ("%c", *(cap->FWImageName + cap->fw_len - (20 + 36) + loop)));
ilm_dl_len = (*(cap->FWImageName + cap->fw_len - (1 + 36)) << 24) |
(*(cap->FWImageName + cap->fw_len - (2 + 36)) << 16) |
(*(cap->FWImageName + cap->fw_len -(3 + 36)) << 8) |
*(cap->FWImageName + cap->fw_len - (4 + 36));
ilm_dl_len += 4; /* including crc value */
DBGPRINT(RT_DEBUG_TRACE, ("\nILM download len = %d\n", ilm_dl_len));
dlm_target_addr = (*(cap->FWImageName + cap->fw_len - 33) << 24) |
(*(cap->FWImageName + cap->fw_len - 34) << 16) |
(*(cap->FWImageName + cap->fw_len - 35) << 8) |
*(cap->FWImageName + cap->fw_len - 36);
DBGPRINT(RT_DEBUG_TRACE, ("DLM target address = %x\n", dlm_target_addr));
dlm_chip_info = *(cap->FWImageName + cap->fw_len - 32);
DBGPRINT(RT_DEBUG_TRACE, ("\nDLM chip information = %x\n", dlm_chip_info));
dlm_feature_set = *(cap->FWImageName + cap->fw_len - 31);
DBGPRINT(RT_DEBUG_TRACE, ("\nDLM feature set = %x\n", dlm_feature_set));
DBGPRINT(RT_DEBUG_TRACE, ("DLM Build Date:"));
for (loop = 0; loop < 8; loop++)
DBGPRINT(RT_DEBUG_OFF, ("%c", *(cap->FWImageName + cap->fw_len - 20 + loop)));
dlm_dl_len = (*(cap->FWImageName + cap->fw_len - 1) << 24) |
(*(cap->FWImageName + cap->fw_len - 2) << 16) |
(*(cap->FWImageName + cap->fw_len - 3) << 8) |
*(cap->FWImageName + cap->fw_len - 4);
dlm_dl_len += 4; /* including crc value */
DBGPRINT(RT_DEBUG_TRACE, ("\nDLM download len = %d\n", dlm_dl_len));
#if defined(RTMP_PCI_SUPPORT) || defined(RTMP_USB_SUPPORT)
/* switch to bypass mode */
RTMP_IO_READ32(ad, SCH_REG4, &value);
value &= ~SCH_REG4_BYPASS_MODE_MASK;
value |= SCH_REG4_BYPASS_MODE(1);
#ifdef RTMP_PCI_SUPPORT
value &= ~SCH_REG4_FORCE_QID_MASK;
value |= SCH_REG4_FORCE_QID(5);
#endif
#ifdef RTMP_USB_SUPPORT
value &= ~SCH_REG4_FORCE_QID_MASK;
value |= SCH_REG4_FORCE_QID(8);
#endif
RTMP_IO_WRITE32(ad, SCH_REG4, value);
#endif
/* optional CMD procedure */
/* CMD restart download flow request */
#if defined(RTMP_PCI_SUPPORT) || defined(RTMP_USB_SUPPORT)
RTMP_IO_READ32(ad, SW_SYN0, &value);
DBGPRINT(RT_DEBUG_TRACE, ("SW_SYN0 = %x\n", value));
/* check ram code if running, if it is, need to do optional cmd procedure */
if ((value & 0x03) == 0x03) {
ret = CmdRestartDLReq(ad);
if (ret)
goto done;
}
/* check rom code if ready */
loop = 0;
do
{
RTMP_IO_READ32(ad, SW_SYN0, &value);
if ((value & 0x01) == 0x01)
break;
RtmpOsMsDelay(1);
loop++;
} while (loop <= 500);
if (loop > 500) {
DBGPRINT(RT_DEBUG_ERROR, ("%s: rom code is not ready(SW_SYN0 = %d)\n", __FUNCTION__, value));
goto done;
}
#endif
/* ILM */
/* standard CMD procedure */
/* 1. Config PDA phase */
ret = CmdAddressLenReq(ad, ilm_target_addr, ilm_dl_len,
(ilm_feature_set & FW_FEATURE_SET_ENCRY) |
(FW_FEATURE_SET_KEY(GET_FEATURE_SET_KEY(ilm_feature_set))) |
((ilm_feature_set & FW_FEATURE_SET_ENCRY) ? FW_FEATURE_RESET_IV: 0) |
TARGET_ADDR_LEN_NEED_RSP);
if (ret)
goto done;
/* 2. Loading ilm firmware image phase */
ret = CmdFwScatters(ad, cap->FWImageName, ilm_dl_len);
if (ret)
goto done;
/* DLM */
/* standard CMD procedure */
/* 1. Config PDA phase */
ret = CmdAddressLenReq(ad, dlm_target_addr, dlm_dl_len,
(dlm_feature_set & FW_FEATURE_SET_ENCRY) |
(FW_FEATURE_SET_KEY(GET_FEATURE_SET_KEY(dlm_feature_set))) |
((dlm_feature_set & FW_FEATURE_SET_ENCRY) ? FW_FEATURE_RESET_IV: 0) |
TARGET_ADDR_LEN_NEED_RSP);
if (ret)
goto done;
/* 2. Loading dlm firmware image phase */
ret = CmdFwScatters(ad, cap->FWImageName + ilm_dl_len, dlm_dl_len);
if (ret)
goto done;
/* 3. Firmware start negotiation phase */
ret = CmdFwStartReq(ad, 0, 0);
#if defined(RTMP_PCI_SUPPORT) || defined(RTMP_USB_SUPPORT)
/* 4. check Firmware running */
for (loop = 0; loop < 500; loop++)
{
RTMP_IO_READ32(ad, SW_SYN0, &value);
DBGPRINT(RT_DEBUG_TRACE, ("SW_SYN0 = %x\n", value));
if ((value & 0x03) == 0x03)
break;
RtmpOsMsDelay(1);
}
if (loop == 500)
{
ret = NDIS_STATUS_FAILURE;
DBGPRINT(RT_DEBUG_OFF, ("firmware loading failure\n"));
Ctl->Stage = FW_NO_INIT;
}
else
{
Ctl->Stage = FW_RUN_TIME;
}
#endif
#ifdef RTMP_SDIO_SUPPORT
RtmpOsMsDelay(1000);
Ctl->Stage = FW_RUN_TIME;
printk("%s: &pAd->MCUCtrl=%p\n",__FUNCTION__,Ctl);
printk("%s(): findish download fw ya! \n", __FUNCTION__);
#endif
done:
#if defined(RTMP_PCI_SUPPORT) || defined(RTMP_USB_SUPPORT)
/* Switch to normal mode */
RTMP_IO_READ32(ad, SCH_REG4, &value);
value &= ~SCH_REG4_BYPASS_MODE_MASK;
value |= SCH_REG4_BYPASS_MODE(0);
value &= ~SCH_REG4_FORCE_QID_MASK;
value |= SCH_REG4_FORCE_QID(0);
RTMP_IO_WRITE32(ad, SCH_REG4, value);
RTMP_IO_READ32(ad, SCH_REG4, &value);
value |= (1 << 8);
RTMP_IO_WRITE32(ad, SCH_REG4, value);
RTMP_IO_READ32(ad, SCH_REG4, &value);
value &= ~(1 << 8);
RTMP_IO_WRITE32(ad, SCH_REG4, value);
#endif
return ret;
}
NDIS_STATUS AndesMTLoadFw(RTMP_ADAPTER *pAd)
{
UINT32 Ret;
RTMP_CHIP_CAP *Cap = &pAd->chipCap;
if (Cap->DownLoadType == DownLoadTypeA)
{
Ret = AndesMTLoadFwMethod1(pAd);
}
else if (Cap->DownLoadType == DownLoadTypeB)
{
Ret = AndesMTLoadFwMethod2(pAd);
}
else
{
DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow Download type(%d)\n", __FUNCTION__, Cap->DownLoadType));
Ret = -1;
}
return Ret;
}
NDIS_STATUS AndesMTLoadRomPatch(RTMP_ADAPTER *ad)
{
UINT32 value, loop;
UINT32 ret;
RTMP_CHIP_CAP *cap = &ad->chipCap;
RTMP_CHIP_OP *pChipOps = &ad->chipOps;
//POS_COOKIE obj = (POS_COOKIE)ad->OS_Cookie;
struct MCU_CTRL *Ctl = &ad->MCUCtrl;
UINT32 patch_len = 0, total_checksum = 0;
if (cap->load_code_method == BIN_FILE_METHOD) {
DBGPRINT(RT_DEBUG_OFF, ("load fw image from /lib/firmware/%s\n", cap->fw_bin_file_name));
DBGPRINT(RT_DEBUG_ERROR, ("%s:Not support now(/lib/firmware/%s), load_method(%d)\n", __FUNCTION__, cap->rom_patch_bin_file_name, cap->load_code_method));
} else {
cap->rom_patch = cap->rom_patch_header_image;
}
if (!cap->rom_patch) {
if (cap->load_code_method == BIN_FILE_METHOD) {
DBGPRINT(RT_DEBUG_ERROR, ("%s:Please assign a fw image(/lib/firmware/%s), load_method(%d)\n", __FUNCTION__, cap->fw_bin_file_name, cap->load_code_method));
} else {
DBGPRINT(RT_DEBUG_ERROR, ("%s:Please assign a fw image, load_method(%d)\n",
__FUNCTION__, cap->load_code_method));
}
ret = NDIS_STATUS_FAILURE;
goto done;
}
Ctl->Stage = ROM_PATCH_DOWNLOAD;
DBGPRINT(RT_DEBUG_TRACE, ("Build Date:"));
for (loop = 0; loop < 16; loop++)
DBGPRINT(RT_DEBUG_OFF, ("%c", *(cap->rom_patch + loop)));
DBGPRINT(RT_DEBUG_OFF, ("\n"));
DBGPRINT(RT_DEBUG_OFF, ("platform = \n"));
for (loop = 0; loop < 4; loop++)
DBGPRINT(RT_DEBUG_OFF, ("%c", *(cap->rom_patch + 16 + loop)));
DBGPRINT(RT_DEBUG_OFF, ("\n"));
DBGPRINT(RT_DEBUG_OFF, ("hw/sw version = \n"));
for (loop = 0; loop < 4; loop++)
DBGPRINT(RT_DEBUG_OFF, ("%02x", *(cap->rom_patch + 20 + loop)));
DBGPRINT(RT_DEBUG_OFF, ("\n"));
DBGPRINT(RT_DEBUG_OFF, ("patch version = \n"));
for (loop = 0; loop < 4; loop++)
DBGPRINT(RT_DEBUG_OFF, ("%02x", *(cap->rom_patch + 24 + loop)));
DBGPRINT(RT_DEBUG_OFF, ("\n"));
total_checksum = *(cap->rom_patch + 28) | (*(cap->rom_patch + 29) << 8);
patch_len = cap->rom_patch_len - PATCH_INFO_SIZE;
DBGPRINT(RT_DEBUG_INFO, ("\ndownload len = %d\n", patch_len));
#if defined(RTMP_PCI_SUPPORT) || defined(RTMP_USB_SUPPORT)
/* switch to bypass mode */
RTMP_IO_READ32(ad, SCH_REG4, &value);
value &= ~SCH_REG4_BYPASS_MODE_MASK;
value |= SCH_REG4_BYPASS_MODE(1);
#ifdef RTMP_USB_SUPPORT
value &= ~SCH_REG4_FORCE_QID_MASK;
value |= SCH_REG4_FORCE_QID(8);
#endif
RTMP_IO_WRITE32(ad, SCH_REG4, value);
#endif
#if 0
ret = CmdPatchSemGet(ad, GET_PATCH_SEM);
if (ret)
goto done;
if (Ctl->SemStatus != 2) {
Ctl->Stage = FW_NO_INIT;
DBGPRINT(RT_DEBUG_OFF, ("\nPatch download before or Get Sem Fail, Status (%d)\n", Ctl->SemStatus));
goto done;
}
#endif
/* standard CMD procedure */
/* 1. Config PDA phase */
ret = CmdAddressLenReq(ad, ROM_PATCH_START_ADDRESS, patch_len, TARGET_ADDR_LEN_NEED_RSP);
if (ret)
goto done;
/* 2. Loading rom patch image phase */
ret = CmdFwScatters(ad, cap->rom_patch + PATCH_INFO_SIZE, patch_len);
if (ret)
goto done;
/* 3. ROM patch start negotiation phase */
ret = CmdPatchFinishReq(ad);
DBGPRINT(RT_DEBUG_OFF, ("Send checksum req..\n"));
pChipOps->AndesMTChkCrc(ad, patch_len);
RtmpOsMsDelay(20);
if (total_checksum != pChipOps->AndesMTGetCrc(ad)) {
DBGPRINT(RT_DEBUG_OFF, ("checksum fail!, local(0x%x) <> fw(0x%x)\n", total_checksum,
pChipOps->AndesMTGetCrc(ad)));
ret = NDIS_STATUS_FAILURE;
}
DBGPRINT(RT_DEBUG_OFF, ("checksum=0x%x\n", pChipOps->AndesMTGetCrc(ad)));
#if 0
ret = CmdPatchSemGet(ad, REL_PATCH_SEM);
if (ret)
goto done;
#endif
done:
#if defined(RTMP_PCI_SUPPORT) || defined(RTMP_USB_SUPPORT)
/* Switch to normal mode */
RTMP_IO_READ32(ad, SCH_REG4, &value);
value &= ~SCH_REG4_BYPASS_MODE_MASK;
value |= SCH_REG4_BYPASS_MODE(0);
value &= ~SCH_REG4_FORCE_QID_MASK;
value |= SCH_REG4_FORCE_QID(0);
RTMP_IO_WRITE32(ad, SCH_REG4, value);
RTMP_IO_READ32(ad, SCH_REG4, &value);
value |= (1 << 8);
RTMP_IO_WRITE32(ad, SCH_REG4, value);
RTMP_IO_READ32(ad, SCH_REG4, &value);
value &= ~(1 << 8);
RTMP_IO_WRITE32(ad, SCH_REG4, value);
#endif
return ret;
}
INT32 AndesMTEraseFw(RTMP_ADAPTER *pAd)
{
RTMP_CHIP_CAP *cap = &pAd->chipCap;
if (cap->load_code_method == BIN_FILE_METHOD) {
if (cap->FWImageName) {
os_free_mem(NULL, cap->FWImageName);
cap->FWImageName = NULL;
}
}
return 0;
}
static VOID EventChPrivilegeHandler(RTMP_ADAPTER *pAd, UINT8 *Data, UINT32 Length)
{
//struct cmd_msg *msg, *msg_tmp;
struct MCU_CTRL *ctl = &pAd->MCUCtrl;
UINT32 Value;
if (IS_MT7603(pAd) || IS_MT7628(pAd))
{
RTMP_IO_READ32(pAd, RMAC_RMCR, &Value);
if (ctl->RxStream0 == 1)
Value |= RMAC_RMCR_RX_STREAM_0;
else
Value &= ~RMAC_RMCR_RX_STREAM_0;
if (ctl->RxStream1 == 1)
Value |= RMAC_RMCR_RX_STREAM_1;
else
Value &= ~RMAC_RMCR_RX_STREAM_1;
RTMP_IO_WRITE32(pAd, RMAC_RMCR, Value);
}
DBGPRINT(RT_DEBUG_INFO, ("%s\n", __FUNCTION__));
}
#ifdef CONFIG_STA_SUPPORT
static VOID ExtEventBeaconLostHandler(RTMP_ADAPTER *pAd, UINT8 *Data, UINT32 Length)
{
struct _EXT_EVENT_BEACON_LOSS_T *pExtEventBeaconLoss = (struct _EXT_EVENT_BEACON_LOSS_T *)Data;
pAd->StaCfg.PwrMgmt.bBeaconLost = TRUE;
DBGPRINT(RT_DEBUG_TRACE, ("%s::FW LOG, Beacon lost (%x:%x:%x:%x:%x:%x)\n",
__FUNCTION__,
pExtEventBeaconLoss->aucBssid[0],
pExtEventBeaconLoss->aucBssid[1],
pExtEventBeaconLoss->aucBssid[2],
pExtEventBeaconLoss->aucBssid[3],
pExtEventBeaconLoss->aucBssid[4],
pExtEventBeaconLoss->aucBssid[5]));
}
#endif /*CONFIG_STA_SUPPORT*/
static VOID ExtEventFwLog2HostHandler(RTMP_ADAPTER *pAd, UINT8 *Data, UINT32 Length)
{
DBGPRINT(RT_DEBUG_TRACE, ("FW LOG: %s\n", Data));
}
static VOID EventExtEventHandler(RTMP_ADAPTER *pAd, UINT8 ExtEID, UINT8 *Data, UINT32 Length)
{
switch (ExtEID)
{
case EXT_EVENT_CMD_RESULT:
EventExtCmdResultHandler(pAd, Data, (UINT16)Length);
break;
case EXT_EVENT_FW_LOG_2_HOST:
ExtEventFwLog2HostHandler(pAd, Data, Length);
break;
#ifdef MT_PS
#if defined(MT7603) && defined(RTMP_PCI_SUPPORT)
case EXT_CMD_PS_RETRIEVE_START:
CmdPsRetrieveStartRspFromCR(pAd, Data, Length);
break;
#endif /* MT7603 */
#endif /* MT_PS */
#ifdef THERMAL_PROTECT_SUPPORT
case EXT_EVENT_THERMAL_PROTECT:
EventThermalProtect(pAd, Data, Length);
break;
#endif
#ifdef BCN_OFFLOAD_SUPPORT
case EXT_EVENT_BCN_UPDATE:
ExtEventBcnUpdateHandler(pAd, Data, Length);
break;
#endif
#ifdef CONFIG_STA_SUPPORT
case EXT_EVENT_BEACON_LOSS:
ExtEventBeaconLostHandler(pAd, Data, Length);
break;
#endif /*CONFIG_STA_SUPPORT*/
default:
DBGPRINT(RT_DEBUG_OFF, ("%s: Unknown Ext Event(%x)\n", __FUNCTION__,
ExtEID));
break;
}
}
static VOID UnsolicitedEventHandler(RTMP_ADAPTER *pAd, UINT8 EID, UINT8 ExtEID, UINT8 *Data, UINT32 Length)
{
switch (EID)
{
case EVENT_CH_PRIVILEGE:
EventChPrivilegeHandler(pAd, Data, Length);
break;
case EXT_EVENT:
EventExtEventHandler(pAd, ExtEID, Data, Length);
break;
default:
DBGPRINT(RT_DEBUG_OFF, ("%s: Unknown Event(%x)\n", __FUNCTION__, EID));
break;
}
}
static VOID AndesMTRxProcessEvent(RTMP_ADAPTER *pAd, struct cmd_msg *rx_msg)
{
PNDIS_PACKET net_pkt = rx_msg->net_pkt;
struct cmd_msg *msg, *msg_tmp;
EVENT_RXD *event_rxd = (EVENT_RXD *)GET_OS_PKT_DATAPTR(net_pkt);
struct MCU_CTRL *ctl = &pAd->MCUCtrl;
#ifdef RTMP_PCI_SUPPORT
unsigned long flags;
#endif /* RTMP_PCI_SUPPORT */
//event_rxd->fw_rxd_0.word = le2cpu32(event_rxd->fw_rxd_0.word);
event_rxd->fw_rxd_1.word = le2cpu32(event_rxd->fw_rxd_1.word);
event_rxd->fw_rxd_2.word = le2cpu32(event_rxd->fw_rxd_2.word);
#ifdef CONFIG_TRACE_SUPPORT
TRACE_MCU_EVENT_INFO(event_rxd->fw_rxd_0.field.length, event_rxd->fw_rxd_0.field.pkt_type_id,
event_rxd->fw_rxd_1.field.eid, event_rxd->fw_rxd_1.field.seq_num,
event_rxd->fw_rxd_2.field.ext_eid, GET_OS_PKT_DATAPTR(net_pkt) + sizeof(*event_rxd), event_rxd->fw_rxd_0.field.length - sizeof(*event_rxd));
#endif
#if 0
printk("event_rxd->fw_rxd_1.field.eid = %x, event_rxd->fw_rxd_1.field.seq_num = %x,\
event_rxd->fw_rxd_2.field.ext_eid = %x\n", event_rxd->fw_rxd_1.field.eid,\
event_rxd->fw_rxd_1.field.seq_num, event_rxd->fw_rxd_2.field.ext_eid);
#endif
if ((event_rxd->fw_rxd_1.field.seq_num == 0) ||
(event_rxd->fw_rxd_2.field.ext_eid == EXT_EVENT_FW_LOG_2_HOST) ||
(event_rxd->fw_rxd_2.field.ext_eid == EXT_EVENT_THERMAL_PROTECT)) {
/* if have callback function */
UnsolicitedEventHandler(pAd, (UINT8)event_rxd->fw_rxd_1.field.eid
, (UINT8)event_rxd->fw_rxd_2.field.ext_eid
, GET_OS_PKT_DATAPTR(net_pkt) + sizeof(*event_rxd)
, event_rxd->fw_rxd_0.field.length - sizeof(*event_rxd));
}
else
{
#if defined(RTMP_USB_SUPPORT) || defined(RTMP_SDIO_SUPPORT)
RTMP_SPIN_LOCK_IRQ(&ctl->ackq_lock);
#endif
#ifdef RTMP_PCI_SUPPORT
RTMP_SPIN_LOCK_IRQSAVE(&ctl->ackq_lock, &flags);
#endif
DlListForEachSafe(msg, msg_tmp, &ctl->ackq, struct cmd_msg, list) {
if (msg->seq == event_rxd->fw_rxd_1.field.seq_num)
{
_AndesUnlinkCmdMsg(msg, &ctl->ackq);
#if defined(RTMP_USB_SUPPORT) || defined(RTMP_SDIO_SUPPORT)
RTMP_SPIN_UNLOCK_IRQ(&ctl->ackq_lock);
#endif
#ifdef RTMP_PCI_SUPPORT
RTMP_SPIN_UNLOCK_IRQRESTORE(&ctl->ackq_lock, &flags);
#endif
if ((event_rxd->fw_rxd_1.field.eid == MT_FW_START_RSP)
|| (event_rxd->fw_rxd_1.field.eid == MT_RESTART_DL_RSP)
|| (event_rxd->fw_rxd_1.field.eid == MT_TARGET_ADDRESS_LEN_RSP)
|| (event_rxd->fw_rxd_1.field.eid == MT_PATCH_SEM_RSP)) {
msg->rsp_handler(msg, (char*)(GET_OS_PKT_DATAPTR(net_pkt) + sizeof(*event_rxd) - 4),
event_rxd->fw_rxd_0.field.length - sizeof(*event_rxd) + 4);
}
else if ((msg->rsp_payload_len == event_rxd->fw_rxd_0.field.length - sizeof(*event_rxd))
&& (msg->rsp_payload_len != 0))
{
if (msg->rsp_handler == NULL)
{
DBGPRINT(RT_DEBUG_ERROR, ("%s(): rsp_handler is NULL!!!! (cmd_type = 0x%x, ext_cmd_type = 0x%x)\n",
__FUNCTION__, msg->cmd_type, msg->ext_cmd_type));
}
else
{
msg->rsp_handler(msg, GET_OS_PKT_DATAPTR(net_pkt) + sizeof(*event_rxd),
event_rxd->fw_rxd_0.field.length - sizeof(*event_rxd));
}
}
else
{
DBGPRINT(RT_DEBUG_ERROR, ("expect response len(%d), command response len(%zu) invalid\n", msg->rsp_payload_len, event_rxd->fw_rxd_0.field.length - sizeof(*event_rxd)));
msg->rsp_payload_len =
(UINT16)(event_rxd->fw_rxd_0.field.length -
sizeof(*event_rxd));
}
if (msg->need_wait) {
RTMP_OS_COMPLETE(&msg->ack_done);
} else {
AndesFreeCmdMsg(msg);
}
#if defined(RTMP_USB_SUPPORT) || defined(RTMP_SDIO_SUPPORT)
RTMP_SPIN_LOCK_IRQ(&ctl->ackq_lock);
#endif
#ifdef RTMP_PCI_SUPPORT
RTMP_SPIN_LOCK_IRQSAVE(&ctl->ackq_lock, &flags);
#endif
break;
}
}
#if defined(RTMP_USB_SUPPORT) || defined(RTMP_SDIO_SUPPORT)
RTMP_SPIN_UNLOCK_IRQ(&ctl->ackq_lock);
#endif
#ifdef RTMP_PCI_SUPPORT
RTMP_SPIN_UNLOCK_IRQRESTORE(&ctl->ackq_lock, &flags);
#endif
}
}
VOID AndesMTRxEventHandler(RTMP_ADAPTER *pAd, UCHAR *data)
{
struct cmd_msg *msg;
struct MCU_CTRL *ctl = &pAd->MCUCtrl;
EVENT_RXD *event_rxd = (EVENT_RXD *)data;
if (!OS_TEST_BIT(MCU_INIT, &ctl->flags)) {
return;
}
DBGPRINT(RT_DEBUG_INFO, ("%s\n", __FUNCTION__));
msg = AndesAllocCmdMsg(pAd, event_rxd->fw_rxd_0.field.length);
if (!msg)
return;
AndesAppendCmdMsg(msg, (char *)data, event_rxd->fw_rxd_0.field.length);
AndesMTRxProcessEvent(pAd, msg);
#ifdef RTMP_PCI_SUPPORT
if (msg->net_pkt)
RTMPFreeNdisPacket(pAd, msg->net_pkt);
#endif
AndesFreeCmdMsg(msg);
}
#ifdef RTMP_PCI_SUPPORT
VOID AndesMTPciFwInit(RTMP_ADAPTER *pAd)
{
struct MCU_CTRL *Ctl = &pAd->MCUCtrl;
DBGPRINT(RT_DEBUG_TRACE, ("%s\n", __FUNCTION__));
Ctl->Stage = FW_NO_INIT;
/* Enable Interrupt*/
RTMP_IRQ_ENABLE(pAd);
RT28XXDMAEnable(pAd);
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP);
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MCU_SEND_IN_BAND_CMD);
}
VOID AndesMTPciFwExit(RTMP_ADAPTER *pAd)
{
DBGPRINT(RT_DEBUG_TRACE, ("%s\n", __FUNCTION__));
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MCU_SEND_IN_BAND_CMD);
RT28XXDMADisable(pAd);
RTMP_ASIC_INTERRUPT_DISABLE(pAd);
}
#endif /* RTMP_PCI_SUPPORT */
#ifdef RTMP_USB_SUPPORT
VOID AndesMTUsbFwInit(RTMP_ADAPTER *pAd)
{
struct MCU_CTRL *Ctl = &pAd->MCUCtrl;
DBGPRINT(RT_DEBUG_TRACE, ("%s\n", __FUNCTION__));
Ctl->Stage = FW_NO_INIT;
RT28XXDMAEnable(pAd);
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP);
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MCU_SEND_IN_BAND_CMD);
UsbRxCmdMsgsReceive(pAd);
RTUSBBulkReceive(pAd);
}
#endif /* RTMP_USB_SUPPORT */
#ifdef RTMP_SDIO_SUPPORT
VOID AndesMTSdioFwInit(RTMP_ADAPTER *pAd)
{
struct MCU_CTRL *Ctl = &pAd->MCUCtrl;
UINT32 value;
DBGPRINT(RT_DEBUG_TRACE, ("%s\n", __FUNCTION__));
Ctl->Stage = FW_NO_INIT;
/* Enable Interrupt*/
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP);
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MCU_SEND_IN_BAND_CMD);
RTMP_SDIO_WRITE32(pAd, WHIER, (RX0_DONE_INT_EN |RX1_DONE_INT_EN));
RTMP_SDIO_READ32(pAd, WHIER,&value);
printk("%s(): MCR_WHIER: value:%x\n", __FUNCTION__,value);
RTMP_SDIO_READ32(pAd, WHISR,&value);
printk("%s(): MCR_WHISR1: value:%x\n", __FUNCTION__,value);
RTMP_SDIO_WRITE32(pAd, WHLPCR, W_INT_EN_SET);
}
VOID AndesMTSdioFwExit(RTMP_ADAPTER *pAd)
{
DBGPRINT(RT_DEBUG_TRACE, ("%s\n", __FUNCTION__));
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MCU_SEND_IN_BAND_CMD);
}
#endif
static VOID CmdEfuseBufferModeRsp(struct cmd_msg *msg, char *Data, UINT16 Len)
{
struct _EVENT_EXT_CMD_RESULT_T *EventExtCmdResult = (struct _EVENT_EXT_CMD_RESULT_T *)Data;
//RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)msg->priv;
DBGPRINT(RT_DEBUG_INFO, ("%s: EventExtCmdResult.ucExTenCID = 0x%x\n",__FUNCTION__, EventExtCmdResult->ucExTenCID));
EventExtCmdResult->u4Status = le2cpu32(EventExtCmdResult->u4Status);
DBGPRINT(RT_DEBUG_INFO, ("%s: EventExtCmdResult.u4Status = 0x%x\n",__FUNCTION__, EventExtCmdResult->u4Status));
}
static VOID CmdThemalSensorRsp(struct cmd_msg *msg, char *Data, UINT16 Len)
{
struct _EXT_EVENT_GET_SENSOR_RESULT_T *EventExtCmdResult = (struct _EXT_EVENT_GET_SENSOR_RESULT_T *)Data;
//RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)msg->priv;
EventExtCmdResult->u4SensorResult = le2cpu32(EventExtCmdResult->u4SensorResult);
DBGPRINT(RT_DEBUG_OFF, ("ThemalSensor = 0x%x\n", EventExtCmdResult->u4SensorResult));
}
static inline VOID bufferModeFieldSet(RTMP_ADAPTER *pAd,EXT_CMD_EFUSE_BUFFER_MODE_T *pCmd,UINT16 addr)
{
UINT32 i = pCmd->ucCount;
if (i >= EFUSE_CONTENT_BUFFER_SIZE) {
DBGPRINT(RT_DEBUG_ERROR,
("%s: EFUSE_CONTENT_BUFFER_SIZE Overflow\n",
__FUNCTION__));
return;
}
pCmd->aBinContent[i].u2Addr = cpu2le16(addr);
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[addr] ;
pCmd->ucCount++;
}
static VOID CmdExtPmMgtBitRsp(struct cmd_msg *msg, char *Data, UINT16 Len)
{
struct _EVENT_EXT_CMD_RESULT_T *EventExtCmdResult = (struct _EVENT_EXT_CMD_RESULT_T *)Data;
//RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)msg->priv;
DBGPRINT(RT_DEBUG_OFF, ("%s: EventExtCmdResult.ucExTenCID = 0x%x\n",__FUNCTION__, EventExtCmdResult->ucExTenCID));
EventExtCmdResult->u4Status = le2cpu32(EventExtCmdResult->u4Status);
DBGPRINT(RT_DEBUG_OFF, ("%s: EventExtCmdResult.u4Status = 0x%x\n",__FUNCTION__, EventExtCmdResult->u4Status));
}
static VOID CmdExtPmStateCtrlRsp(struct cmd_msg *msg, char *Data, UINT16 Len)
{
struct _EVENT_EXT_CMD_RESULT_T *EventExtCmdResult = (struct _EVENT_EXT_CMD_RESULT_T *)Data;
//RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)msg->priv;
DBGPRINT(RT_DEBUG_OFF, ("%s: EventExtCmdResult.ucExTenCID = 0x%x\n",__FUNCTION__, EventExtCmdResult->ucExTenCID));
EventExtCmdResult->u4Status = le2cpu32(EventExtCmdResult->u4Status);
DBGPRINT(RT_DEBUG_OFF, ("%s: EventExtCmdResult.u4Status = 0x%x\n",__FUNCTION__, EventExtCmdResult->u4Status));
}
static VOID CmdFillEeprom(RTMP_ADAPTER *pAd,EXT_CMD_EFUSE_BUFFER_MODE_T *pCmd)
{
UINT8 i = 0;
pCmd->aBinContent[i].u2Addr = NIC_CONFIGURE_0_TOP;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[NIC_CONFIGURE_0_TOP] ;
i++;
pCmd->aBinContent[i].u2Addr = NIC_CONFIGURE_1;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[NIC_CONFIGURE_1];
i++;
pCmd->aBinContent[i].u2Addr = NIC_CONFIGURE_1_TOP;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[NIC_CONFIGURE_1_TOP];
i++;
pCmd->aBinContent[i].u2Addr = WIFI_RF_SETTING;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[WIFI_RF_SETTING];
i++;
pCmd->aBinContent[i].u2Addr = G_BAND_20_40_BW_PWR_DELTA;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[G_BAND_20_40_BW_PWR_DELTA];
i++;
pCmd->aBinContent[i].u2Addr = A_BAND_20_80_BW_PWR_DELTA_ANALOG;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[A_BAND_20_80_BW_PWR_DELTA_ANALOG];
i++;
pCmd->aBinContent[i].u2Addr = A_BAND_EXT_PA_SETTING;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[A_BAND_EXT_PA_SETTING];
i++;
pCmd->aBinContent[i].u2Addr = TEMP_SENSOR_CAL;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TEMP_SENSOR_CAL];
i++;
pCmd->aBinContent[i].u2Addr = TX0_G_BAND_TSSI_SLOPE;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX0_G_BAND_TSSI_SLOPE];
i++;
pCmd->aBinContent[i].u2Addr = TX0_G_BAND_TSSI_SLOPE_TOP;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX0_G_BAND_TSSI_SLOPE_TOP];
i++;
pCmd->aBinContent[i].u2Addr = TX0_G_BAND_TARGET_PWR;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX0_G_BAND_TARGET_PWR];
i++;
pCmd->aBinContent[i].u2Addr = TX0_G_BAND_OFFSET_LOW;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX0_G_BAND_OFFSET_LOW];
i++;
pCmd->aBinContent[i].u2Addr = TX0_G_BAND_CHL_PWR_DELTA_MID;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX0_G_BAND_CHL_PWR_DELTA_MID];
i++;
pCmd->aBinContent[i].u2Addr = TX0_G_BAND_OFFSET_HIGH;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX0_G_BAND_OFFSET_HIGH];
i++;
pCmd->aBinContent[i].u2Addr = TX1_G_BAND_TSSI_SLOPE;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX1_G_BAND_TSSI_SLOPE];
i++;
pCmd->aBinContent[i].u2Addr = TX1_G_BAND_TSSI_SLOPE_TOP;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX1_G_BAND_TSSI_SLOPE_TOP];
i++;
pCmd->aBinContent[i].u2Addr = TX1_G_BAND_TARGET_PWR;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX1_G_BAND_TARGET_PWR];
i++;
pCmd->aBinContent[i].u2Addr = TX1_G_BAND_CHL_PWR_DELATE_LOW;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX1_G_BAND_CHL_PWR_DELATE_LOW];
i++;
pCmd->aBinContent[i].u2Addr = TX1_G_BAND_CHL_PWR_DELTA_MID;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX1_G_BAND_CHL_PWR_DELTA_MID];
i++;
pCmd->aBinContent[i].u2Addr = TX1_G_BAND_CHL_PWR_DELTA_HIGH;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX1_G_BAND_CHL_PWR_DELTA_HIGH];
i++;
pCmd->aBinContent[i].u2Addr = TX_PWR_CCK_1_2M;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX_PWR_CCK_1_2M];
i++;
pCmd->aBinContent[i].u2Addr = TX_PWR_CCK_5_11M;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX_PWR_CCK_5_11M];
i++;
pCmd->aBinContent[i].u2Addr = TX_PWR_G_BAND_OFDM_6_9M;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX_PWR_G_BAND_OFDM_6_9M];
i++;
pCmd->aBinContent[i].u2Addr = TX_PWR_OFDM_12_18M;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX_PWR_OFDM_12_18M];
i++;
pCmd->aBinContent[i].u2Addr = TX_PWR_G_BAND_OFDM_24_36M;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX_PWR_G_BAND_OFDM_24_36M];
i++;
pCmd->aBinContent[i].u2Addr = TX_PWR_G_BNAD_OFDM_48;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX_PWR_G_BNAD_OFDM_48];
i++;
pCmd->aBinContent[i].u2Addr = TX_PWR_G_BAND_OFDM_54M;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX_PWR_G_BAND_OFDM_54M];
i++;
pCmd->aBinContent[i].u2Addr = TX_PWR_HT_BPSK_MCS_0_8;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX_PWR_HT_BPSK_MCS_0_8];
i++;
pCmd->aBinContent[i].u2Addr = TX_PWR_HT_BPSK_MCS_32;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX_PWR_HT_BPSK_MCS_32];
i++;
pCmd->aBinContent[i].u2Addr = TX_PWR_HT_QPSK_MCS_1_2_9_10;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX_PWR_HT_QPSK_MCS_1_2_9_10];
i++;
pCmd->aBinContent[i].u2Addr = TX_PWR_HT_16QAM_MCS_3_4_11_12;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX_PWR_HT_16QAM_MCS_3_4_11_12];
i++;
pCmd->aBinContent[i].u2Addr = TX_PWR_HT_64QAM_MCS_5_13;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX_PWR_HT_64QAM_MCS_5_13];
i++;
pCmd->aBinContent[i].u2Addr = TX_PWR_HT_64QAM_MCS_6_14;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX_PWR_HT_64QAM_MCS_6_14];
i++;
pCmd->aBinContent[i].u2Addr = TX_PWR_HT_64QAM_MCS_7_15;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[TX_PWR_HT_64QAM_MCS_7_15];
i++;
pCmd->aBinContent[i].u2Addr = ELAN_RX_MODE_GAIN;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[ELAN_RX_MODE_GAIN];
i++;
pCmd->aBinContent[i].u2Addr = ELAN_RX_MODE_NF;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[ELAN_RX_MODE_NF];
i++;
pCmd->aBinContent[i].u2Addr = ELAN_RX_MODE_P1DB;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[ELAN_RX_MODE_P1DB];
i++;
pCmd->aBinContent[i].u2Addr = ELAN_BYPASS_MODE_GAIN;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[ELAN_BYPASS_MODE_GAIN];
i++;
pCmd->aBinContent[i].u2Addr = ELAN_BYPASS_MODE_NF;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[ELAN_BYPASS_MODE_NF];
i++;
pCmd->aBinContent[i].u2Addr = ELAN_BYPASS_MODE_P1DB;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[ELAN_BYPASS_MODE_P1DB];
i++;
pCmd->aBinContent[i].u2Addr = STEP_NUM_NEG_7;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[STEP_NUM_NEG_7];
i++;
pCmd->aBinContent[i].u2Addr = STEP_NUM_NEG_6;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[STEP_NUM_NEG_6];
i++;
pCmd->aBinContent[i].u2Addr = STEP_NUM_NEG_5;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[STEP_NUM_NEG_5];
i++;
pCmd->aBinContent[i].u2Addr = STEP_NUM_NEG_4;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[STEP_NUM_NEG_4];
i++;
pCmd->aBinContent[i].u2Addr = STEP_NUM_NEG_3;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[STEP_NUM_NEG_3];
i++;
pCmd->aBinContent[i].u2Addr = STEP_NUM_NEG_2;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[STEP_NUM_NEG_2];
i++;
pCmd->aBinContent[i].u2Addr = STEP_NUM_NEG_1;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[STEP_NUM_NEG_1];
i++;
pCmd->aBinContent[i].u2Addr = STEP_NUM_NEG_0;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[STEP_NUM_NEG_0];
i++;
pCmd->aBinContent[i].u2Addr = REF_STEP_24G;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[REF_STEP_24G];
i++;
pCmd->aBinContent[i].u2Addr = REF_TEMP_24G;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[REF_TEMP_24G];
i++;
pCmd->aBinContent[i].u2Addr = STEP_NUM_PLUS_1;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[STEP_NUM_PLUS_1];
i++;
pCmd->aBinContent[i].u2Addr = STEP_NUM_PLUS_2;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[STEP_NUM_PLUS_2];
i++;
pCmd->aBinContent[i].u2Addr = STEP_NUM_PLUS_3;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[STEP_NUM_PLUS_3];
i++;
pCmd->aBinContent[i].u2Addr = STEP_NUM_PLUS_4;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[STEP_NUM_PLUS_4];
i++;
pCmd->aBinContent[i].u2Addr = STEP_NUM_PLUS_5;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[STEP_NUM_PLUS_5];
i++;
pCmd->aBinContent[i].u2Addr = STEP_NUM_PLUS_6;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[STEP_NUM_PLUS_6];
i++;
pCmd->aBinContent[i].u2Addr = STEP_NUM_PLUS_7;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[STEP_NUM_PLUS_7];
i++;
pCmd->aBinContent[i].u2Addr = XTAL_CALIB_FREQ_OFFSET;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[XTAL_CALIB_FREQ_OFFSET];
i++;
pCmd->aBinContent[i].u2Addr = XTAL_TRIM_2_COMP;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[XTAL_TRIM_2_COMP];
i++;
pCmd->aBinContent[i].u2Addr = XTAL_TRIM_3_COMP;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[XTAL_TRIM_3_COMP];
i++;
pCmd->aBinContent[i].u2Addr = WF_RCAL;
pCmd->aBinContent[i].ucValue = pAd->EEPROMImage[WF_RCAL];
i++;
pCmd->ucCount = i;
/*check endian and transfer it is needed*/
for(i=0;i<pCmd->ucCount ;i++)
{
pCmd->aBinContent[i].u2Addr = cpu2le16(pCmd->aBinContent[i].u2Addr);
}
/*extend for function requset, need backward compatible*/
bufferModeFieldSet(pAd,pCmd,0x24);
bufferModeFieldSet(pAd,pCmd,0x25);
bufferModeFieldSet(pAd,pCmd,0x34);
bufferModeFieldSet(pAd,pCmd,0x39);
bufferModeFieldSet(pAd,pCmd,0x3b);
bufferModeFieldSet(pAd,pCmd,0x42);
bufferModeFieldSet(pAd,pCmd,0x43);
bufferModeFieldSet(pAd,pCmd,0x9e);
bufferModeFieldSet(pAd,pCmd,0x9f);
bufferModeFieldSet(pAd,pCmd,0xf2);
bufferModeFieldSet(pAd,pCmd,0xf8);
bufferModeFieldSet(pAd,pCmd,0xf9);
bufferModeFieldSet(pAd,pCmd,0xfa);
bufferModeFieldSet(pAd,pCmd,0x12e);
for(i=0;i<=0xf;i++)
{
bufferModeFieldSet(pAd,pCmd,0x130+i);
}
/*need minus 1 for add one more time*/
pCmd->ucCount--;
}
VOID CmdEfusBufferModeSet(RTMP_ADAPTER *pAd)
{
struct cmd_msg *msg;
EXT_CMD_EFUSE_BUFFER_MODE_T CmdEfuseBufferMode;
int ret = 0;
msg = AndesAllocCmdMsg(pAd, sizeof(EXT_CMD_EFUSE_BUFFER_MODE_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_EFUSE_BUFFER_MODE, TRUE, 0,TRUE, TRUE, 8, NULL, CmdEfuseBufferModeRsp);
memset(&CmdEfuseBufferMode, 0x00, sizeof(CmdEfuseBufferMode));
switch(pAd->eeprom_type){
case EEPROM_EFUSE:
{
CmdEfuseBufferMode.ucSourceMode = EEPROM_MODE_EFUSE;
CmdEfuseBufferMode.ucCount = 0;
}
break;
case EEPROM_FLASH:
{
CmdEfuseBufferMode.ucSourceMode = EEPROM_MODE_BUFFER;
CmdFillEeprom(pAd,&CmdEfuseBufferMode);
}
break;
default:
goto error;
break;
}
AndesAppendCmdMsg(msg, (char *)&CmdEfuseBufferMode, sizeof(CmdEfuseBufferMode));
ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ;
}
VOID CmdSetTxPowerCtrl(RTMP_ADAPTER *pAd, UINT8 central_chl)
{
struct cmd_msg *msg;
EXT_CMD_TX_POWER_CTRL_T CmdTxPwrCtrl;
int ret = 0;
USHORT i;
int j;
UINT8 PwrPercentageDelta = 0;
USHORT Value;
struct MT_TX_PWR_CAP *cap = &pAd->chipCap.MTTxPwrCap;
msg = AndesAllocCmdMsg(pAd, sizeof(EXT_CMD_TX_POWER_CTRL_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_SET_TX_POWER_CTRL, TRUE, 0,
TRUE, TRUE, 8, NULL, EventExtCmdResult);
memset(&CmdTxPwrCtrl, 0x00, sizeof(CmdTxPwrCtrl));
CmdTxPwrCtrl.ucCenterChannel = central_chl;
if (pAd->eeprom_type == EEPROM_EFUSE)
{
RT28xx_EEPROM_READ16(pAd, NIC_CONFIGURE_1, Value);
CmdTxPwrCtrl.ucTSSIEnable = (UINT8)((Value & 0xff00) >> 8);
RT28xx_EEPROM_READ16(pAd, NIC_CONFIGURE_1, Value);
CmdTxPwrCtrl.ucTempCompEnable = (Value & 0xff);
RT28xx_EEPROM_READ16(pAd, TX0_G_BAND_TARGET_PWR, Value);
CmdTxPwrCtrl.aucTargetPower[0] = Value & 0xff;
RT28xx_EEPROM_READ16(pAd, TX1_G_BAND_TARGET_PWR, Value);
CmdTxPwrCtrl.aucTargetPower[1] = Value & 0xff;
j = 0;
for (i = 0; i < 7; i++)
{
RT28xx_EEPROM_READ16(pAd, TX_PWR_CCK_1_2M + (i * 2), Value);
CmdTxPwrCtrl.aucRatePowerDelta[j] = Value & 0xff;
j++;
CmdTxPwrCtrl.aucRatePowerDelta[j] = (UINT8)((Value & 0xff00) >> 8);
j++;
}
RT28xx_EEPROM_READ16(pAd, G_BAND_20_40_BW_PWR_DELTA, Value);
CmdTxPwrCtrl.ucBWPowerDelta = Value & 0xff;
RT28xx_EEPROM_READ16(pAd, TX0_G_BAND_TARGET_PWR, Value);
CmdTxPwrCtrl.aucCHPowerDelta[0] = (UINT8)((Value & 0xff00) >> 8);
RT28xx_EEPROM_READ16(pAd, TX0_G_BAND_CHL_PWR_DELTA_MID, Value);
CmdTxPwrCtrl.aucCHPowerDelta[1] = Value & 0xff;
CmdTxPwrCtrl.aucCHPowerDelta[2] = (UINT8)((Value & 0xff00) >> 8);
RT28xx_EEPROM_READ16(pAd, TX1_G_BAND_TARGET_PWR, Value);
CmdTxPwrCtrl.aucCHPowerDelta[3] = (UINT8)((Value & 0xff00) >> 8);
RT28xx_EEPROM_READ16(pAd, TX1_G_BAND_CHL_PWR_DELTA_MID, Value);
CmdTxPwrCtrl.aucCHPowerDelta[4] = Value & 0xff;
CmdTxPwrCtrl.aucCHPowerDelta[5] = (UINT8)((Value & 0xff00) >> 8);
j = 0;
for (i = 0; i < 9; i++)
{
RT28xx_EEPROM_READ16(pAd, STEP_NUM_NEG_7 + (i * 2), Value);
CmdTxPwrCtrl.aucTempCompPower[j] = Value & 0xff;
j++;
if (i != 8)
{
CmdTxPwrCtrl.aucTempCompPower[j] = (UINT8)((Value & 0xff00) >> 8);
j++;
}
}
}
else
{
CmdTxPwrCtrl.ucTSSIEnable = pAd->EEPROMImage[NIC_CONFIGURE_1_TOP];
CmdTxPwrCtrl.ucTempCompEnable = pAd->EEPROMImage[NIC_CONFIGURE_1];
CmdTxPwrCtrl.aucTargetPower[0] = pAd->EEPROMImage[TX0_G_BAND_TARGET_PWR];
CmdTxPwrCtrl.aucTargetPower[1] = pAd->EEPROMImage[TX1_G_BAND_TARGET_PWR];
#ifdef CONFIG_ATE
/* Replace Target Power from QA Tool manual setting*/
if (ATE_ON(pAd)) {
DBGPRINT(RT_DEBUG_TRACE, ("%s,ATE set tx power\n", __FUNCTION__));
CmdTxPwrCtrl.aucTargetPower[0] = pAd->ATECtrl.TxPower0;
CmdTxPwrCtrl.aucTargetPower[1] = pAd->ATECtrl.TxPower1;
}
#endif
NdisCopyMemory(&CmdTxPwrCtrl.aucRatePowerDelta[0], &(pAd->EEPROMImage[TX_PWR_CCK_1_2M]), sizeof(CmdTxPwrCtrl.aucRatePowerDelta));
CmdTxPwrCtrl.ucBWPowerDelta = pAd->EEPROMImage[G_BAND_20_40_BW_PWR_DELTA];
NdisCopyMemory(&CmdTxPwrCtrl.aucCHPowerDelta[0], &(pAd->EEPROMImage[TX0_G_BAND_OFFSET_LOW]), sizeof(CmdTxPwrCtrl.aucCHPowerDelta[0]));
NdisCopyMemory(&CmdTxPwrCtrl.aucCHPowerDelta[1], &(pAd->EEPROMImage[TX0_G_BAND_CHL_PWR_DELTA_MID]), sizeof(CmdTxPwrCtrl.aucCHPowerDelta[1]));
NdisCopyMemory(&CmdTxPwrCtrl.aucCHPowerDelta[2], &(pAd->EEPROMImage[TX0_G_BAND_OFFSET_HIGH]), sizeof(CmdTxPwrCtrl.aucCHPowerDelta[2]));
NdisCopyMemory(&CmdTxPwrCtrl.aucCHPowerDelta[3], &(pAd->EEPROMImage[TX1_G_BAND_CHL_PWR_DELATE_LOW]), sizeof(CmdTxPwrCtrl.aucCHPowerDelta[3]));
NdisCopyMemory(&CmdTxPwrCtrl.aucCHPowerDelta[4], &(pAd->EEPROMImage[TX1_G_BAND_CHL_PWR_DELTA_MID]), sizeof(CmdTxPwrCtrl.aucCHPowerDelta[4]));
NdisCopyMemory(&CmdTxPwrCtrl.aucCHPowerDelta[5], &(pAd->EEPROMImage[TX1_G_BAND_CHL_PWR_DELTA_HIGH]), sizeof(CmdTxPwrCtrl.aucCHPowerDelta[5]));
NdisCopyMemory(&CmdTxPwrCtrl.aucTempCompPower[0], &(pAd->EEPROMImage[STEP_NUM_NEG_7]), sizeof(CmdTxPwrCtrl.aucTempCompPower));
}
DBGPRINT(RT_DEBUG_INFO, ("PA type = %d\n", cap->pa_type));
// if (!(cap->pa_type & (1 << 1)))
if (1)
{
if (pAd->CommonCfg.TxPowerPercentage > 90)
{
PwrPercentageDelta = 0;
}
else if (pAd->CommonCfg.TxPowerPercentage > 60) /* reduce Pwr for 1 dB. */
{
PwrPercentageDelta = 1;
}
else if (pAd->CommonCfg.TxPowerPercentage > 30) /* reduce Pwr for 3 dB. */
{
PwrPercentageDelta = 3;
}
else if (pAd->CommonCfg.TxPowerPercentage > 15) /* reduce Pwr for 6 dB. */
{
PwrPercentageDelta = 6;
}
else if (pAd->CommonCfg.TxPowerPercentage > 9) /* reduce Pwr for 9 dB. */
{
PwrPercentageDelta = 9;
}
else /* reduce Pwr for 12 dB. */
{
PwrPercentageDelta = 12;
}
DBGPRINT(RT_DEBUG_INFO, ("Before apply tx pwr percentage, CmdTxPwrCtrl.aucTargetPower[0] = 0x%x\n", CmdTxPwrCtrl.aucTargetPower[0]));
DBGPRINT(RT_DEBUG_INFO, ("Before apply tx pwr percentage, CmdTxPwrCtrl.aucTargetPower[1] = 0x%x\n", CmdTxPwrCtrl.aucTargetPower[1]));
DBGPRINT(RT_DEBUG_INFO, ("Percentage = 0x%x\n", PwrPercentageDelta));
CmdTxPwrCtrl.ucReserved = PwrPercentageDelta;
}
else
{
#ifdef CONFIG_ATE
if (!ATE_ON(pAd))
#endif
{
DBGPRINT(RT_DEBUG_TRACE, ("EPA, do not need to apply tx power percentage\n"));
goto error;
}
}
DBGPRINT(RT_DEBUG_INFO, ("CmdTxPwrCtrl.ucCenterChannel=%x\n", CmdTxPwrCtrl.ucCenterChannel));
DBGPRINT(RT_DEBUG_INFO, ("CmdTxPwrCtrl.ucTSSIEnable=%x \n", CmdTxPwrCtrl.ucTSSIEnable));
DBGPRINT(RT_DEBUG_INFO, ("CmdTxPwrCtrl.ucTempCompEnable=%x\n", CmdTxPwrCtrl.ucTempCompEnable));
DBGPRINT(RT_DEBUG_INFO, ("CmdTxPwrCtrl.aucTargetPower[0]=%x\n", CmdTxPwrCtrl.aucTargetPower[0]));
DBGPRINT(RT_DEBUG_INFO, ("CmdTxPwrCtrl.aucTargetPower[1]=%x\n", CmdTxPwrCtrl.aucTargetPower[1]));
for(i=0; i<14;i++)
DBGPRINT(RT_DEBUG_INFO, ("CmdTxPwrCtrl.aucRatePowerDelta[%d]=%x\n", i, CmdTxPwrCtrl.aucRatePowerDelta[i]));
DBGPRINT(RT_DEBUG_INFO, ("CmdTxPwrCtrl.ucBWPowerDelta=%x \n",CmdTxPwrCtrl.ucBWPowerDelta));
for(i=0;i<6;i++)
DBGPRINT(RT_DEBUG_INFO, ("CmdTxPwrCtrl.aucCHPowerDelta[%d]=%x\n", i, CmdTxPwrCtrl.aucCHPowerDelta[i]));
for(i=0;i<17;i++)
DBGPRINT(RT_DEBUG_INFO, ("CmdTxPwrCtrl.aucTempCompPower[%d]=%x\n", i, CmdTxPwrCtrl.aucTempCompPower[i]));
AndesAppendCmdMsg(msg, (char *)&CmdTxPwrCtrl, sizeof(CmdTxPwrCtrl));
ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return;
}
VOID CmdGetThemalSensorResult(struct _RTMP_ADAPTER *pAd, UINT8 option)
{
struct cmd_msg *msg;
EXT_CMD_GET_SENSOR_RESULT_T CmdSensorResult;
INT32 ret;
#ifdef CONFIG_QA
ATE_CTRL *ATECtrl = &(pAd->ATECtrl);
#endif /* CONFIG_QA */
ret = 0;
msg = AndesAllocCmdMsg(pAd, sizeof(EXT_CMD_GET_SENSOR_RESULT_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
#ifdef CONFIG_QA
//ATE_CTRL *ATECtrl = &(pAd->ATECtrl);
if(ATECtrl->bQAEnabled){
DBGPRINT(RT_DEBUG_OFF, ("%s: Call to qa_agent\n", __FUNCTION__));
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_GET_THEMAL_SENSOR, TRUE, 0, TRUE, TRUE, 8, NULL, HQA_GetThermalValue_CB);
} else
#endif
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_GET_THEMAL_SENSOR, TRUE, 0, TRUE, TRUE, 8, NULL, CmdThemalSensorRsp);
CmdSensorResult.ucActionIdx = option;
AndesAppendCmdMsg(msg, (char *)&CmdSensorResult, sizeof(CmdSensorResult));
ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ;
}
#ifdef LED_CONTROL_SUPPORT
INT AndesLedOP(
IN PRTMP_ADAPTER pAd,
IN UCHAR LedIdx,
IN UCHAR LinkStatus)
{
struct cmd_msg *msg;
CHAR *Pos, *pBuf;
UINT32 VarLen;
UINT32 arg0, arg1;
INT32 ret;
UINT32 blinkSel = 2; // 2 : data only, 0 : all Tx frames, 1 : Exclude Tx Beacon and TIM broadcast frames
ret = 0;
msg = AndesAllocCmdMsg(pAd, sizeof(LED_NMAC_CMD));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_LED_CTRL, FALSE, 0, FALSE, FALSE, 0, NULL, NULL);
//memset(&CmdEfuseBufferMode, 0x00, sizeof(CmdEfuseBufferMode));
/* Calibration ID and Parameter */
VarLen = 8;
arg0 = cpu2le32(LedIdx);
arg1 = cpu2le32(LinkStatus | (blinkSel << 24));
os_alloc_mem(pAd, (UCHAR **)&pBuf, VarLen);
if (pBuf == NULL)
{
return NDIS_STATUS_RESOURCES;
}
NdisZeroMemory(pBuf, VarLen);
Pos = pBuf;
/* Parameter */
NdisMoveMemory(Pos, &arg0, 4);
NdisMoveMemory(Pos+4, &arg1, 4);
Pos += 4;
hex_dump("AndesLedOP: ", pBuf, VarLen);
AndesAppendCmdMsg(msg, (char *)pBuf, VarLen);
ret = AndesSendCmdMsg(pAd, msg);
os_free_mem(NULL, pBuf);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
INT AndesLedEnhanceOP(
IN PRTMP_ADAPTER pAd,
IN UCHAR LedIdx,
IN UCHAR on_time,
IN UCHAR off_time,
IN UCHAR Led_Parameter
)
{
struct cmd_msg *msg;
CHAR *Pos, *pBuf;
UINT32 VarLen;
UINT32 arg0/*, arg1*/;
INT32 ret = 0;
//UCHAR parameter[4]={0};
LED_ENHANCE led_enhance;
msg = AndesAllocCmdMsg(pAd, sizeof(LED_NMAC_CMD));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_LED_CTRL, FALSE, 0, FALSE, FALSE, 0, NULL, NULL);
//memset(&CmdEfuseBufferMode, 0x00, sizeof(CmdEfuseBufferMode));
/* Calibration ID and Parameter */
VarLen = 8;
arg0 = LedIdx;
//arg1 = LinkStatus;
//parameter[1]=on_time;
//parameter[2]=off_time;
//parameter[3]=31;
led_enhance.word = 0;
led_enhance.field.on_time=on_time;
led_enhance.field.off_time=off_time;
led_enhance.field.idx = Led_Parameter;
os_alloc_mem(pAd, (UCHAR **)&pBuf, VarLen);
if (pBuf == NULL)
{
return NDIS_STATUS_RESOURCES;
}
NdisZeroMemory(pBuf, VarLen);
Pos = pBuf;
/* Parameter */
NdisMoveMemory(Pos, &arg0, 4);
//NdisMoveMemory(Pos+4, &arg1, 4);
NdisMoveMemory(Pos+4, &led_enhance, sizeof(led_enhance));
Pos += 4;
hex_dump("AndesLedOPEnhance: ", pBuf, VarLen);
AndesAppendCmdMsg(msg, (char *)pBuf, VarLen);
ret = AndesSendCmdMsg(pAd, msg);
os_free_mem(NULL, pBuf);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
#endif /*LED_CONTROL_SUPPORT*/
INT32 CmdExtPwrMgtBitWifi(RTMP_ADAPTER *pAd, UINT8 ucWlanIdx, UINT8 ucPwrMgtBit)
{
struct cmd_msg *msg;
EXT_CMD_PWR_MGT_BIT_T PwrMgtBitWifi = {0};
INT32 Ret = 0;
msg = AndesAllocCmdMsg(pAd, sizeof(EXT_CMD_PWR_MGT_BIT_T));
if (!msg)
{
Ret = NDIS_STATUS_RESOURCES;
goto error;
}
PwrMgtBitWifi.ucWlanIdx = (UINT8)cpu2le32(ucWlanIdx);
PwrMgtBitWifi.ucPwrMgtBit = (UINT8)cpu2le32(ucPwrMgtBit);
DBGPRINT(RT_DEBUG_OFF, ("%s:ucWlanIdx(%d), ucPwrMgtBit(%d)\n", __FUNCTION__, ucWlanIdx, ucPwrMgtBit));
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_ID_PWR_MGT_BIT_WIFI, TRUE, 0,TRUE, TRUE, 8, NULL, CmdExtPmMgtBitRsp);
AndesAppendCmdMsg(msg, (char *)&PwrMgtBitWifi, sizeof(PwrMgtBitWifi));
Ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_OFF, ("%s:(Ret = %d)\n", __FUNCTION__, Ret));
return Ret;
}
/*1: enter, 2: exit specific PM state*/
INT32 CmdExtPmStateCtrl(RTMP_ADAPTER *pAd, UINT8 ucWlanIdx, UINT8 ucPmNumber, UINT8 ucPmState)
{
#ifdef CONFIG_STA_SUPPORT
static UINT32 u4RfCr = 0;
UINT32 u4TempRfCr = 0;
PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[ucWlanIdx];
#endif
struct cmd_msg *msg = NULL;
EXT_CMD_PM_STATE_CTRL_T CmdPmStateCtrl = {0};
INT32 Ret = 0;
msg = AndesAllocCmdMsg(pAd, sizeof(EXT_CMD_PM_STATE_CTRL_T));
if (!msg)
{
Ret = NDIS_STATUS_RESOURCES;
goto error;
}
/* Fill parameter here*/
CmdPmStateCtrl.ucWlanIdx = (UINT8)cpu2le32(ucWlanIdx);
CmdPmStateCtrl.ucPmNumber = (UINT8)cpu2le32(ucPmNumber);
CmdPmStateCtrl.ucPmState = (UINT8)cpu2le32(ucPmState);
#ifdef CONFIG_STA_SUPPORT
NdisMoveMemory(CmdPmStateCtrl.aucBssid, pEntry->Addr, MAC_ADDR_LEN);
DBGPRINT(RT_DEBUG_OFF, ("%s:(%x, %x, %x, %x, %x, %x), BeaconPeriod(%d), DtimPeriod(%d), AID(%d)\n",
__FUNCTION__,
PRINT_MAC(pEntry->Addr),
pAd->MlmeAux.BeaconPeriod,
pAd->MlmeAux.DtimPeriod,
pAd->StaActive.Aid));
#endif /* CONFIG_STA_SUPPORT */
#ifdef CONFIG_STA_SUPPORT
if (ucPmState == ENTER_PM_STATE)
{
CmdPmStateCtrl.ucDtimPeriod = (UINT8)cpu2le32(pAd->MlmeAux.DtimPeriod);
CmdPmStateCtrl.u2BcnInterval = (UINT16)cpu2le32(pAd->MlmeAux.BeaconPeriod);
CmdPmStateCtrl.u4Aid = cpu2le32(pAd->StaActive.Aid);
RTMP_IO_READ32(pAd, RMAC_RFCR, &u4RfCr);
DBGPRINT(RT_DEBUG_OFF, ("%s: RMAC_RFCR 0x%x\n", __FUNCTION__, u4RfCr));
u4TempRfCr = u4RfCr;
u4TempRfCr |= (DROP_PROBE_REQ | DROP_NOT_MY_BSSID | DROP_DIFF_BSSID_BCN);
CmdPmStateCtrl.u4RxFilter = cpu2le32(u4TempRfCr);
DBGPRINT(RT_DEBUG_OFF, ("%s: u4RxFilter 0x%x\n", __FUNCTION__, CmdPmStateCtrl.u4RxFilter));
CmdPmStateCtrl.u4Feature = cpu2le32(PM_CMD_FEATURE_PSPOLL_OFFLOAD);
CmdPmStateCtrl.ucOwnMacIdx = cpu2le32(0); //AsicSetDevMac
// TODO: Hanmim 7636 psm
CmdPmStateCtrl.ucWmmIdx = cpu2le32(0); // 0: WMM1, 1: WMM2
CmdPmStateCtrl.ucBcnLossCount = cpu2le32(5); // 2.5sec
CmdPmStateCtrl.ucBcnSpDuration = cpu2le32(0);
}
else
{
CmdPmStateCtrl.u4RxFilter = cpu2le32(u4RfCr);
}
#endif /* CONFIG_STA_SUPPORT */
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_PM_STATE_CTRL, TRUE, 0,TRUE, TRUE, 8, NULL, CmdExtPmStateCtrlRsp);
AndesAppendCmdMsg(msg, (char *)&CmdPmStateCtrl, sizeof(CmdPmStateCtrl));
Ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_OFF, ("%s:(Ret = %d)\n", __FUNCTION__, Ret));
return Ret;
}
INT32 CmdEdcaParameterSet(RTMP_ADAPTER *pAd, CMD_EDCA_SET_T EdcaParam)
{
struct cmd_msg *msg;
INT32 ret=0,size=0;
size = 4+sizeof(TX_AC_PARAM_T)*EdcaParam.ucTotalNum;
msg = AndesAllocCmdMsg(pAd, size);
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_ID_EDCA_SET, FALSE, 0, FALSE, FALSE, 0, NULL, NULL);
AndesAppendCmdMsg(msg, (char *)&EdcaParam,size);
ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
INT32 CmdSlotTimeSet(RTMP_ADAPTER *pAd, UINT8 SlotTime,UINT8 SifsTime,UINT8 RifsTime,UINT16 EifsTime)
{
struct cmd_msg *msg;
INT32 ret=0;
CMD_SLOT_TIME_SET_T cmdSlotTime;
NdisZeroMemory(&cmdSlotTime,sizeof(CMD_SLOT_TIME_SET_T));
msg = AndesAllocCmdMsg(pAd, sizeof(CMD_SLOT_TIME_SET_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_ID_SLOT_TIME_SET, FALSE, 0, FALSE, FALSE, 0, NULL, NULL);
cmdSlotTime.u2Eifs = EifsTime;
cmdSlotTime.ucRifs = RifsTime;
cmdSlotTime.ucSifs = SifsTime;
cmdSlotTime.ucSlotTime = SlotTime;
AndesAppendCmdMsg(msg, (char *)&cmdSlotTime,sizeof(CMD_SLOT_TIME_SET_T));
ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
INT32 CmdIdConfigInternalSetting(RTMP_ADAPTER *pAd, UINT8 SubOpCode, UINT8 Param)
{
struct cmd_msg *msg;
INT32 ret=0;
CMD_CONFIG_INTERNAL_SETTING_T CmdConfigInternalSetting;
NdisZeroMemory(&CmdConfigInternalSetting, sizeof(CMD_CONFIG_INTERNAL_SETTING_T));
msg = AndesAllocCmdMsg(pAd, sizeof(CMD_CONFIG_INTERNAL_SETTING_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_ID_CONFIG_INTERNAL_SETTING, FALSE, 0, FALSE, FALSE, 0, NULL, NULL);
CmdConfigInternalSetting.ucSubOpcode = SubOpCode;
CmdConfigInternalSetting.aucPara[0] = Param;
AndesAppendCmdMsg(msg, (char *)&CmdConfigInternalSetting, sizeof(CMD_CONFIG_INTERNAL_SETTING_T));
ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_INFO, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}
#ifdef BCN_OFFLOAD_SUPPORT
VOID RT28xx_UpdateBeaconToMcu(
IN RTMP_ADAPTER *pAd,
IN INT apidx,
IN UCHAR HWBssidIdx,
IN BOOLEAN Enable,
IN ULONG FrameLen,
IN ULONG UpdatePos)
{
CMD_BCN_UPDATE_T bcn_update;
NdisZeroMemory(&bcn_update, sizeof(CMD_BCN_UPDATE_T));
bcn_update.ucHwBssidIdx = HWBssidIdx;
if (HWBssidIdx > 0) //HWBssid > 0 case, no extendable bssid.
bcn_update.ucExtBssidIdx = 0;
else
bcn_update.ucExtBssidIdx = (UINT8)apidx;
bcn_update.ucEnable = Enable;
//bcn_update.ucWlanIdx = 0;//hardcode at present
bcn_update.u2BcnPeriod = pAd->CommonCfg.BeaconPeriod;
CmdBcnUpdateSet(pAd, bcn_update);
}
#endif /*BCN_OFFLOAD_SUPPORT*/
#ifdef MT_WOW_SUPPORT
static VOID EventExtCmdPacketFilterRsp(struct cmd_msg *msg, char *Data, UINT16 Len)
{
P_EXT_EVENT_PF_GENERAL_T pPFRsp = (P_EXT_EVENT_PF_GENERAL_T)Data;
DBGPRINT(RT_DEBUG_OFF, ("%s: u4PfCmdType = 0x%x u4Status = 0x%x\n",
__FUNCTION__, le2cpu32(pPFRsp->u4PfCmdType), le2cpu32(pPFRsp->u4Status)));
}
static VOID EventExtCmdWakeupOptionRsp(struct cmd_msg *msg, char *Data, UINT16 Len)
{
P_EXT_EVENT_WAKEUP_OPTION_T pWakeOptRsp = (P_EXT_EVENT_WAKEUP_OPTION_T)Data;
DBGPRINT(RT_DEBUG_OFF, ("%s: u4PfCmdType = 0x%x u4Status = 0x%x\n",
__FUNCTION__, le2cpu32(pWakeOptRsp->u4PfCmdType), le2cpu32(pWakeOptRsp->u4Status)));
}
VOID MT76xxAndesWOWEnable(
IN PRTMP_ADAPTER pAd)
{
//hw-enable cmd
//1. magic, parameter=enable
//2. eapol , param = enable
//3. bssid , param = bssid[3:0]
//4. mode, parm = white
//5. PF, param = enable
//wakeup command param = choose usb. others dont' care
struct wifi_dev *wdev = &pAd->StaCfg.wdev;
MAC_TABLE_ENTRY *pEntry = NULL;
struct cmd_msg *msg;
INT32 ret = NDIS_STATUS_SUCCESS;
//CMD_PACKET_FILTER_MAGIC_PACKET_T CmdMagicPacket;
CMD_PACKET_FILTER_GLOBAL_T CmdPFGlobal;
CMD_PACKET_FILTER_GTK_T CmdGTK;
CMD_PACKET_FILTER_WAKEUP_OPTION_T CmdWakeupOption;
DBGPRINT(RT_DEBUG_OFF, ("%s:\n", __FUNCTION__));
/* security configuration */
NdisZeroMemory(&CmdGTK, sizeof(CmdGTK));
msg = AndesAllocCmdMsg(pAd, sizeof(CMD_PACKET_FILTER_GTK_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_ID_PACKET_FILTER, TRUE, 0,
TRUE, TRUE, sizeof(EXT_EVENT_PF_GENERAL_T), NULL, EventExtCmdPacketFilterRsp);
CmdGTK.PFType = cpu2le32(_ENUM_TYPE_GTK_REKEY);
if (wdev->AuthMode == Ndis802_11AuthModeWPAPSK)
CmdGTK.WPAVersion = cpu2le32(0);
else
CmdGTK.WPAVersion = cpu2le32(1);
pEntry = &pAd->MacTab.Content[BSSID_WCID];
#ifdef RT_BIG_ENDIAN
{
int index = 0;
UINT32 *pKey = (UINT32 *)pEntry->PTK;
for (index=0; index < 64; index += 4)
{
*pKey = SWAP32(*pKey);
pKey++;
}
}
#else
#ifndef RT_CFG80211_SUPPORT
NdisCopyMemory(CmdGTK.PTK, pEntry->PTK, LEN_PTK);
#else
NdisCopyMemory(CmdGTK.PTK, pAd->WOW_Cfg.PTK, LEN_PTK);
hex_dump("WOW_Cfg.KCK", pAd->WOW_Cfg.PTK, LEN_PTK_KCK);
hex_dump("WOW_Cfg.KEK", &pAd->WOW_Cfg.PTK[LEN_PTK_KCK], LEN_PTK_KEK);
#endif
#endif
CmdGTK.BssidIndex = cpu2le32(0);
CmdGTK.OwnMacIndex = cpu2le32(0x0);
CmdGTK.WmmIndex = cpu2le32(0);
if (wdev->AuthMode >= Ndis802_11AuthModeWPAPSK){
#ifndef RT_CFG80211_SUPPORT
NdisCopyMemory(CmdGTK.ReplayCounter, pEntry->ReplayCounter, LEN_KEY_DESC_REPLAY);
#else
NdisCopyMemory(CmdGTK.ReplayCounter, pAd->WOW_Cfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
#endif
CmdGTK.GroupKeyIndex = cpu2le32(MCAST_WCID);
CmdGTK.PairKeyIndex = cpu2le32(pEntry->wcid);
}
DBGPRINT(RT_DEBUG_OFF, ("%s: BssidIndex %d, GroupKeyIndex %d, OwnMacIndex %d, PairKeyIndex %d, WmmIndex %d\n",
__FUNCTION__, CmdGTK.BssidIndex, CmdGTK.GroupKeyIndex, CmdGTK.OwnMacIndex, CmdGTK.PairKeyIndex, CmdGTK.WmmIndex));
AndesAppendCmdMsg(msg, (char *)&CmdGTK, sizeof(CMD_PACKET_FILTER_GTK_T));
ret = AndesSendCmdMsg(pAd, msg);
#if 0
/* ARP offload */
if (pAd->WOW_Cfg.IPAddress[0] ||
pAd->WOW_Cfg.IPAddress[1] ||
pAd->WOW_Cfg.IPAddress[2] ||
pAd->WOW_Cfg.IPAddress[3] )
{
os_zero_mem(&CmdARPNS, sizeof(CMD_PACKET_FILTER_ARPNS_T));
msg = AndesAllocCmdMsg(pAd, sizeof(CMD_PACKET_FILTER_ARPNS_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_ID_PACKET_FILTER, TRUE, 0,
TRUE, TRUE, sizeof(EXT_EVENT_PF_GENERAL_T), NULL, EventExtCmdPacketFilterRsp);
CmdARPNS.PFType = cpu2le32(_ENUM_TYPE_ARPNS);
CmdARPNS.IPIndex = cpu2le32(0); /* default use index 0 */
CmdARPNS.Enable = cpu2le32(TRUE);
CmdARPNS.BssidEnable = cpu2le32(BIT(0)|BIT(1)|BIT(2)|BIT(3)); /* enable all BSSID */
CmdARPNS.Offload = cpu2le32(0); /* IPv4 */
CmdARPNS.Type = cpu2le32(0x7); /* support all packet type */
NdisCopyMemory(CmdARPNS.IPAddress, pAd->WOW_Cfg.IPAddress, sizeof(CmdARPNS.IPAddress));
AndesAppendCmdMsg(msg, (char *)&CmdARPNS, sizeof(CMD_PACKET_FILTER_ARPNS_T));
ret = AndesSendCmdMsg(pAd, msg);
}
#endif
// Wakeup option
NdisZeroMemory(&CmdWakeupOption, sizeof(CMD_PACKET_FILTER_WAKEUP_OPTION_T));
msg = AndesAllocCmdMsg(pAd, sizeof(CMD_PACKET_FILTER_WAKEUP_OPTION_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_ID_WAKEUP_OPTION, TRUE, 0,
TRUE, TRUE, sizeof(EXT_EVENT_WAKEUP_OPTION_T), NULL, EventExtCmdWakeupOptionRsp);
CmdWakeupOption.WakeupInterface = cpu2le32(pAd->WOW_Cfg.nWakeupInterface);
CmdWakeupOption.GPIONumber = cpu2le32(pAd->WOW_Cfg.nSelectedGPIO);
CmdWakeupOption.GPIOTimer = cpu2le32(pAd->WOW_Cfg.nHoldTime); // unit is us
if (pAd->WOW_Cfg.nWakeupInterface == WOW_WAKEUP_BY_GPIO)
CmdWakeupOption.GpioParameter |= 0x1;
if (pAd->WOW_Cfg.bGPIOHighLow == WOW_GPIO_LOW_TO_HIGH)
CmdWakeupOption.GpioParameter |= 0x4;
else
CmdWakeupOption.GpioParameter |= 0x2;
DBGPRINT(RT_DEBUG_OFF, ("%s:(WakeupInterface=%d, GPIONumber=%d, GPIOTimer=%d, GpioParameter=0x%x)\n", __FUNCTION__, CmdWakeupOption.WakeupInterface,
CmdWakeupOption.GPIONumber, CmdWakeupOption.GPIOTimer, CmdWakeupOption.GpioParameter));
AndesAppendCmdMsg(msg, (char *)&CmdWakeupOption, sizeof(CMD_PACKET_FILTER_WAKEUP_OPTION_T));
ret = AndesSendCmdMsg(pAd, msg);
// WOW enable
NdisZeroMemory(&CmdPFGlobal, sizeof(CMD_PACKET_FILTER_GLOBAL_T));
msg = AndesAllocCmdMsg(pAd, sizeof(CMD_PACKET_FILTER_GLOBAL_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_ID_PACKET_FILTER, TRUE, 0,
TRUE, TRUE, sizeof(EXT_EVENT_PF_GENERAL_T), NULL, EventExtCmdPacketFilterRsp);
CmdPFGlobal.PFType = cpu2le32(_ENUM_TYPE_GLOBAL_EN);
CmdPFGlobal.FunctionSelect = cpu2le32(_ENUM_GLOBAL_WOW_EN);
CmdPFGlobal.Enable = cpu2le32(1); //bit0=1 mean BSS0 for staion mode
/* if 0: NOT to configure. non-0: set value 1~15 */
if (pAd->WOW_Cfg.nKeepAlivePeriod != 0) {
CmdPFGlobal.extParam = ((FW_KEEP_ALIVE_ENABLE_MASK)
| (pAd->WOW_Cfg.nKeepAlivePeriod & FW_KEEP_ALIVE_PERIOD_MASK));
}
AndesAppendCmdMsg(msg, (char *)&CmdPFGlobal, sizeof(CMD_PACKET_FILTER_GLOBAL_T));
ret = AndesSendCmdMsg(pAd, msg);
error:
DBGPRINT(RT_DEBUG_OFF, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return;
}
VOID MT76xxAndesWOWDisable(
IN PRTMP_ADAPTER pAd)
{
CMD_PACKET_FILTER_GLOBAL_T CmdPFGlobal;
MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[BSSID_WCID];
struct cmd_msg *msg;
INT32 ret = NDIS_STATUS_SUCCESS;
DBGPRINT(RT_DEBUG_OFF, ("%s:\n", __FUNCTION__));
// PF disable
NdisZeroMemory(&CmdPFGlobal, sizeof(CMD_PACKET_FILTER_GLOBAL_T));
msg = AndesAllocCmdMsg(pAd, sizeof(CMD_PACKET_FILTER_GLOBAL_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_ID_PACKET_FILTER, TRUE, 0,
TRUE, TRUE, sizeof(EXT_EVENT_PF_GENERAL_T), NULL, EventExtCmdPacketFilterRsp);
CmdPFGlobal.PFType = cpu2le32(_ENUM_TYPE_GLOBAL_EN);
CmdPFGlobal.FunctionSelect = cpu2le32(_ENUM_GLOBAL_WOW_EN);
CmdPFGlobal.Enable = cpu2le32(0);
AndesAppendCmdMsg(msg, (char *)&CmdPFGlobal, sizeof(CMD_PACKET_FILTER_GLOBAL_T));
ret = AndesSendCmdMsg(pAd, msg);
#if 0 //New architecture: just need one CMD to disable WOW.
/* traffic to Host */
NdisZeroMemory(&CmdPFGlobal, sizeof(CMD_PACKET_FILTER_GLOBAL_T));
msg = AndesAllocCmdMsg(pAd, sizeof(CMD_PACKET_FILTER_GLOBAL_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_ID_PACKET_FILTER, TRUE, 0,
TRUE, TRUE, sizeof(EXT_EVENT_PF_GENERAL_T), NULL, EventExtCmdPacketFilterRsp);
CmdPFGlobal.PFType = cpu2le32(_ENUM_TYPE_GLOBAL_EN);
CmdPFGlobal.FunctionSelect = cpu2le32(_ENUM_GLOBAL_ALL_TOMCU);
CmdPFGlobal.Enable = cpu2le32(0);
AndesAppendCmdMsg(msg, (char *)&CmdPFGlobal, sizeof(CMD_PACKET_FILTER_GLOBAL_T));
ret = AndesSendCmdMsg(pAd, msg);
/* Restore MAC TX/RX */
//AsicSetMacTxRx(pAd, ASIC_MAC_TXRX, TRUE);
#endif
/* Update GTK */
AsicStaUpdateGroupKey(pAd);
/* Reset CCMP RX BMC PN before start rx in case GTK is renewed. */
pEntry->rx_ccmp_pn_bmc[1] = 0;
pEntry->rx_ccmp_pn_bmc_zero[1] = TRUE;
pEntry->rx_ccmp_pn_bmc[2] = 0;
pEntry->rx_ccmp_pn_bmc_zero[2] = TRUE;
error:
DBGPRINT(RT_DEBUG_OFF, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return;
}
VOID MT76xxAndesWOWInit(
IN PRTMP_ADAPTER pAd)
{
struct cmd_msg *msg;
INT32 ret = NDIS_STATUS_SUCCESS;
CMD_PACKET_FILTER_WAKEUP_OPTION_T CmdWakeupOption;
if (!pAd->WOW_Cfg.bEnable)
return;
DBGPRINT(RT_DEBUG_OFF, ("%s:\n", __FUNCTION__));
if (pAd->WOW_Cfg.nWakeupInterface == WOW_WAKEUP_BY_GPIO){
// Wakeup option
NdisZeroMemory(&CmdWakeupOption, sizeof(CMD_PACKET_FILTER_WAKEUP_OPTION_T));
msg = AndesAllocCmdMsg(pAd, sizeof(CMD_PACKET_FILTER_WAKEUP_OPTION_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_ID_WAKEUP_OPTION, TRUE, 0,
TRUE, TRUE, sizeof(EXT_EVENT_WAKEUP_OPTION_T), NULL, EventExtCmdWakeupOptionRsp);
CmdWakeupOption.WakeupInterface = cpu2le32(pAd->WOW_Cfg.nWakeupInterface);
CmdWakeupOption.GPIONumber = cpu2le32(pAd->WOW_Cfg.nSelectedGPIO);
CmdWakeupOption.GPIOTimer = cpu2le32(pAd->WOW_Cfg.nHoldTime); // unit is us
if (pAd->WOW_Cfg.nWakeupInterface == WOW_WAKEUP_BY_GPIO)
CmdWakeupOption.GpioParameter |= 0x1;
if (pAd->WOW_Cfg.bGPIOHighLow == WOW_GPIO_LOW_TO_HIGH)
CmdWakeupOption.GpioParameter |= 0x4;
else
CmdWakeupOption.GpioParameter |= 0x2;
DBGPRINT(RT_DEBUG_OFF, ("%s:(WakeupInterface=%d, GPIONumber=%d, GPIOTimer=%d, GpioParameter=0x%x)\n", __FUNCTION__, CmdWakeupOption.WakeupInterface,
CmdWakeupOption.GPIONumber, CmdWakeupOption.GPIOTimer, CmdWakeupOption.GpioParameter));
AndesAppendCmdMsg(msg, (char *)&CmdWakeupOption, sizeof(CMD_PACKET_FILTER_WAKEUP_OPTION_T));
ret = AndesSendCmdMsg(pAd, msg);
}
error:
DBGPRINT(RT_DEBUG_OFF, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return;
}
#endif
INT32 CmdACQueue_Control
( IN struct _RTMP_ADAPTER *ad,
IN UINT8 ucation, // 0: stop; 1: flush; 2: start
IN UINT8 BssidIdx,
IN UINT32 u4AcQueueMap)
{
struct cmd_msg *msg;
EXT_CMD_AC_QUEUE_CONTROL_T ac_queue_control;
int ret;
DBGPRINT(RT_DEBUG_TRACE, ("CmdACQueue_Control ucation %d BssidIdx %d u4AcQueueMap %d\n",ucation,BssidIdx,u4AcQueueMap));
msg = AndesAllocCmdMsg(ad, sizeof(EXT_CMD_AC_QUEUE_CONTROL_T));
if (!msg)
{
ret = NDIS_STATUS_RESOURCES;
goto error;
}
AndesInitCmdMsg(msg, P1_Q0, EXT_CID, CMD_SET, EXT_CMD_ID_AC_QUEUE_CONTROL, FALSE, 0,
FALSE, FALSE, 0, NULL, NULL);
NdisZeroMemory(&ac_queue_control, sizeof(EXT_CMD_AC_QUEUE_CONTROL_T));
ac_queue_control.ucAction = ucation;
ac_queue_control.ucBssidIdx =BssidIdx;
ac_queue_control.u4AcQueueMap =u4AcQueueMap;
AndesAppendCmdMsg(msg, (char *)&ac_queue_control, sizeof(EXT_CMD_AC_QUEUE_CONTROL_T));
ret = AndesSendCmdMsg(ad, msg);
error:
DBGPRINT(RT_DEBUG_OFF, ("%s:(ret = %d)\n", __FUNCTION__, ret));
return ret;
}