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 #include <linux/crc-ccitt.h>
41 #include <linux/firmware.h>
45 #define FIRMWAREIMAGE_LENGTH 0x1000
47 #define FIRMWARE_2870_MIN_VERSION 12
48 #define FIRMWARE_2870_FILENAME "rt2870.bin"
49 MODULE_FIRMWARE(FIRMWARE_2870_FILENAME);
51 #define FIRMWARE_3070_MIN_VERSION 17
52 #define FIRMWARE_3070_FILENAME "rt3070.bin"
53 MODULE_FIRMWARE(FIRMWARE_3070_FILENAME);
55 #define FIRMWARE_3071_MIN_VERSION 17
56 #define FIRMWARE_3071_FILENAME "rt3071.bin" /* for RT3071/RT3072 */
57 MODULE_FIRMWARE(FIRMWARE_3071_FILENAME);
59 #else /* RTMP_MAC_PCI */
61 #define FIRMWAREIMAGE_LENGTH 0x2000
63 #define FIRMWARE_2860_MIN_VERSION 11
64 #define FIRMWARE_2860_FILENAME "rt2860.bin"
65 MODULE_FIRMWARE(FIRMWARE_2860_FILENAME);
67 #define FIRMWARE_3090_MIN_VERSION 19
68 #define FIRMWARE_3090_FILENAME "rt3090.bin" /* for RT3090/RT3390 */
69 MODULE_FIRMWARE(FIRMWARE_3090_FILENAME);
74 ========================================================================
77 erase 8051 firmware image in MAC ASIC
80 Adapter Pointer to our adapter
84 ========================================================================
86 int RtmpAsicEraseFirmware(struct rt_rtmp_adapter *pAd)
90 for (i = 0; i < MAX_FIRMWARE_IMAGE_SIZE; i += 4)
91 RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, 0);
96 static const struct firmware *rtmp_get_firmware(struct rt_rtmp_adapter *adapter)
99 const struct firmware *fw = NULL;
104 if (adapter->firmware)
105 return adapter->firmware;
108 if (IS_RT3071(adapter)) {
109 name = FIRMWARE_3071_FILENAME;
110 min_version = FIRMWARE_3071_MIN_VERSION;
111 } else if (IS_RT3070(adapter)) {
112 name = FIRMWARE_3070_FILENAME;
113 min_version = FIRMWARE_3070_MIN_VERSION;
115 name = FIRMWARE_2870_FILENAME;
116 min_version = FIRMWARE_2870_MIN_VERSION;
118 dev = &((struct os_cookie *)adapter->OS_Cookie)->pUsb_Dev->dev;
119 #else /* RTMP_MAC_PCI */
120 if (IS_RT3090(adapter) || IS_RT3390(adapter)) {
121 name = FIRMWARE_3090_FILENAME;
122 min_version = FIRMWARE_3090_MIN_VERSION;
124 name = FIRMWARE_2860_FILENAME;
125 min_version = FIRMWARE_2860_MIN_VERSION;
127 dev = &((struct os_cookie *)adapter->OS_Cookie)->pci_dev->dev;
130 err = request_firmware(&fw, name, dev);
132 dev_err(dev, "firmware file %s request failed (%d)\n",
137 if (fw->size < FIRMWAREIMAGE_LENGTH) {
138 dev_err(dev, "firmware file %s size is invalid\n", name);
142 /* is it new enough? */
143 adapter->FirmwareVersion = fw->data[FIRMWAREIMAGE_LENGTH - 3];
144 if (adapter->FirmwareVersion < min_version) {
146 "firmware file %s is too old;"
147 " driver requires v%d or later\n",
152 /* is the internal CRC correct? */
153 if (crc_ccitt(0xffff, fw->data, FIRMWAREIMAGE_LENGTH - 2) !=
154 (fw->data[FIRMWAREIMAGE_LENGTH - 2] |
155 (fw->data[FIRMWAREIMAGE_LENGTH - 1] << 8))) {
156 dev_err(dev, "firmware file %s failed internal CRC\n", name);
160 adapter->firmware = fw;
164 release_firmware(fw);
169 ========================================================================
172 Load 8051 firmware file into MAC ASIC
175 Adapter Pointer to our adapter
178 NDIS_STATUS_SUCCESS firmware image load ok
179 NDIS_STATUS_FAILURE image not found
183 ========================================================================
185 int RtmpAsicLoadFirmware(struct rt_rtmp_adapter *pAd)
187 const struct firmware *fw;
188 int Status = NDIS_STATUS_SUCCESS;
192 fw = rtmp_get_firmware(pAd);
194 return NDIS_STATUS_FAILURE;
196 RTMP_WRITE_FIRMWARE(pAd, fw->data, FIRMWAREIMAGE_LENGTH);
198 /* check if MCU is ready */
201 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg);
207 } while (Index++ < 1000);
210 DBGPRINT(RT_DEBUG_ERROR,
211 ("NICLoadFirmware: MCU is not ready\n"));
212 Status = NDIS_STATUS_FAILURE;
215 DBGPRINT(RT_DEBUG_TRACE, ("<=== %s (status=%d)\n", __func__, Status));
220 int RtmpAsicSendCommandToMcu(struct rt_rtmp_adapter *pAd,
222 u8 Token, u8 Arg0, u8 Arg1)
224 HOST_CMD_CSR_STRUC H2MCmd;
225 H2M_MAILBOX_STRUC H2MMailbox;
228 #ifdef PCIE_PS_SUPPORT
229 /* 3090F power solution 3 has hw limitation that needs to ban all mcu command */
230 /* when firmware is in radio state. For other chip doesn't have this limitation. */
231 if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
232 && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
233 && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
234 && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
235 RTMP_SEM_LOCK(&pAd->McuCmdLock);
236 if ((pAd->brt30xxBanMcuCmd == TRUE)
237 && (Command != WAKE_MCU_CMD) && (Command != RFOFF_MCU_CMD)) {
238 RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
239 DBGPRINT(RT_DEBUG_TRACE,
240 (" Ban Mcu Cmd %x in sleep mode\n", Command));
242 } else if ((Command == SLEEP_MCU_CMD)
243 || (Command == RFOFF_MCU_CMD)) {
244 pAd->brt30xxBanMcuCmd = TRUE;
245 } else if (Command != WAKE_MCU_CMD) {
246 pAd->brt30xxBanMcuCmd = FALSE;
249 RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
252 if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
253 && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
254 && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
255 && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
256 && (Command == WAKE_MCU_CMD)) {
259 RTMP_IO_FORCE_READ32(pAd, H2M_MAILBOX_CSR,
261 if (H2MMailbox.field.Owner == 0)
265 DBGPRINT(RT_DEBUG_INFO,
266 ("AsicSendCommanToMcu::Mail box is busy\n"));
270 DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
274 H2MMailbox.field.Owner = 1; /* pass ownership to MCU */
275 H2MMailbox.field.CmdToken = Token;
276 H2MMailbox.field.HighByte = Arg1;
277 H2MMailbox.field.LowByte = Arg0;
278 RTMP_IO_FORCE_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
281 H2MCmd.field.HostCommand = Command;
282 RTMP_IO_FORCE_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
285 #endif /* PCIE_PS_SUPPORT // */
288 RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
289 if (H2MMailbox.field.Owner == 0)
297 #endif /* RTMP_MAC_PCI // */
299 DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
304 #endif /* RTMP_MAC_PCI // */
306 H2MMailbox.field.Owner = 1; /* pass ownership to MCU */
307 H2MMailbox.field.CmdToken = Token;
308 H2MMailbox.field.HighByte = Arg1;
309 H2MMailbox.field.LowByte = Arg0;
310 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
313 H2MCmd.field.HostCommand = Command;
314 RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
316 if (Command != 0x80) {
319 #ifdef PCIE_PS_SUPPORT
320 /* 3090 MCU Wakeup command needs more time to be stable. */
321 /* Before stable, don't issue other MCU command to prevent from firmware error. */
322 if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
323 && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
324 && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
325 && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
326 && (Command == WAKE_MCU_CMD)) {
328 /*Put this is after RF programming. */
329 /*NdisAcquireSpinLock(&pAd->McuCmdLock); */
330 /*pAd->brt30xxBanMcuCmd = FALSE; */
331 /*NdisReleaseSpinLock(&pAd->McuCmdLock); */
333 #endif /* PCIE_PS_SUPPORT // */