4574 lines
125 KiB
C
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;
|
|
|
|
|
|
}
|
|
|
|
|