2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 *************************************************************************
31 Miniport generic portion header file
35 -------- ---------- ----------------------------------------------
38 #include "../rt_config.h"
40 #if defined(RT2860) || defined(RT3090)
42 #include "../../rt3090/firmware.h"
45 #include "../../rt3070/firmware.h"
46 #include "firmware_3070.h"
49 #include <linux/bitrev.h>
53 /* RT2870 Firmware Spec only used 1 oct for version expression */
55 #define FIRMWARE_MINOR_VERSION 7
56 #endif /* RTMP_MAC_USB // */
58 /* New 8k byte firmware size for RT3071/RT3072 */
59 #define FIRMWAREIMAGE_MAX_LENGTH 0x2000
60 #define FIRMWAREIMAGE_LENGTH (sizeof (FirmwareImage) / sizeof(u8))
61 #define FIRMWARE_MAJOR_VERSION 0
63 #define FIRMWAREIMAGEV1_LENGTH 0x1000
64 #define FIRMWAREIMAGEV2_LENGTH 0x1000
67 #define FIRMWARE_MINOR_VERSION 2
68 #endif /* RTMP_MAC_PCI // */
71 ========================================================================
74 erase 8051 firmware image in MAC ASIC
77 Adapter Pointer to our adapter
81 ========================================================================
83 int RtmpAsicEraseFirmware(struct rt_rtmp_adapter *pAd)
87 for (i = 0; i < MAX_FIRMWARE_IMAGE_SIZE; i += 4)
88 RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, 0);
94 ========================================================================
97 Load 8051 firmware file into MAC ASIC
100 Adapter Pointer to our adapter
103 NDIS_STATUS_SUCCESS firmware image load ok
104 NDIS_STATUS_FAILURE image not found
108 ========================================================================
110 int RtmpAsicLoadFirmware(struct rt_rtmp_adapter *pAd)
113 int Status = NDIS_STATUS_SUCCESS;
114 u8 *pFirmwareImage = NULL;
115 unsigned long FileLength, Index;
118 u32 Version = (pAd->MACVersion >> 16);
121 /* New 8k byte firmware size for RT3071/RT3072 */
124 if (IS_RT3090(pAd) || IS_RT3390(pAd)) {
125 pFirmwareImage = FirmwareImage_3090;
126 FileLength = FIRMWAREIMAGE_MAX_LENGTH;
128 pFirmwareImage = FirmwareImage_2860;
129 FileLength = FIRMWAREIMAGE_MAX_LENGTH;
131 #endif /* RTMP_MAC_PCI // */
133 /* the firmware image consists of two parts */
134 if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070)) { /* use the second part */
135 /*printk("KH:Use New Version,part2\n"); */
138 FirmwareImage_3070[FIRMWAREIMAGEV1_LENGTH];
139 FileLength = FIRMWAREIMAGEV2_LENGTH;
141 /*printk("KH:Use New Version,part1\n"); */
142 if (Version == 0x3070)
143 pFirmwareImage = FirmwareImage_3070;
145 pFirmwareImage = FirmwareImage_2870;
146 FileLength = FIRMWAREIMAGEV1_LENGTH;
148 #endif /* RTMP_MAC_USB // */
151 RTMP_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength);
153 /* check if MCU is ready */
156 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg);
162 } while (Index++ < 1000);
165 DBGPRINT(RT_DEBUG_ERROR,
166 ("NICLoadFirmware: MCU is not ready\n"));
167 Status = NDIS_STATUS_FAILURE;
170 DBGPRINT(RT_DEBUG_TRACE, ("<=== %s (status=%d)\n", __func__, Status));
175 int RtmpAsicSendCommandToMcu(struct rt_rtmp_adapter *pAd,
177 u8 Token, u8 Arg0, u8 Arg1)
179 HOST_CMD_CSR_STRUC H2MCmd;
180 H2M_MAILBOX_STRUC H2MMailbox;
183 #ifdef PCIE_PS_SUPPORT
184 /* 3090F power solution 3 has hw limitation that needs to ban all mcu command */
185 /* when firmware is in radio state. For other chip doesn't have this limitation. */
186 if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
187 && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
188 && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
189 && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
190 RTMP_SEM_LOCK(&pAd->McuCmdLock);
191 if ((pAd->brt30xxBanMcuCmd == TRUE)
192 && (Command != WAKE_MCU_CMD) && (Command != RFOFF_MCU_CMD)) {
193 RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
194 DBGPRINT(RT_DEBUG_TRACE,
195 (" Ban Mcu Cmd %x in sleep mode\n", Command));
197 } else if ((Command == SLEEP_MCU_CMD)
198 || (Command == RFOFF_MCU_CMD)) {
199 pAd->brt30xxBanMcuCmd = TRUE;
200 } else if (Command != WAKE_MCU_CMD) {
201 pAd->brt30xxBanMcuCmd = FALSE;
204 RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
207 if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
208 && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
209 && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
210 && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
211 && (Command == WAKE_MCU_CMD)) {
214 RTMP_IO_FORCE_READ32(pAd, H2M_MAILBOX_CSR,
216 if (H2MMailbox.field.Owner == 0)
220 DBGPRINT(RT_DEBUG_INFO,
221 ("AsicSendCommanToMcu::Mail box is busy\n"));
225 DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
229 H2MMailbox.field.Owner = 1; /* pass ownership to MCU */
230 H2MMailbox.field.CmdToken = Token;
231 H2MMailbox.field.HighByte = Arg1;
232 H2MMailbox.field.LowByte = Arg0;
233 RTMP_IO_FORCE_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
236 H2MCmd.field.HostCommand = Command;
237 RTMP_IO_FORCE_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
240 #endif /* PCIE_PS_SUPPORT // */
243 RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
244 if (H2MMailbox.field.Owner == 0)
252 #endif /* RTMP_MAC_PCI // */
254 DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
259 #endif /* RTMP_MAC_PCI // */
261 H2MMailbox.field.Owner = 1; /* pass ownership to MCU */
262 H2MMailbox.field.CmdToken = Token;
263 H2MMailbox.field.HighByte = Arg1;
264 H2MMailbox.field.LowByte = Arg0;
265 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
268 H2MCmd.field.HostCommand = Command;
269 RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
271 if (Command != 0x80) {
274 #ifdef PCIE_PS_SUPPORT
275 /* 3090 MCU Wakeup command needs more time to be stable. */
276 /* Before stable, don't issue other MCU command to prevent from firmware error. */
277 if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
278 && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
279 && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
280 && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
281 && (Command == WAKE_MCU_CMD)) {
283 /*Put this is after RF programming. */
284 /*NdisAcquireSpinLock(&pAd->McuCmdLock); */
285 /*pAd->brt30xxBanMcuCmd = FALSE; */
286 /*NdisReleaseSpinLock(&pAd->McuCmdLock); */
288 #endif /* PCIE_PS_SUPPORT // */