Lines Matching +full:mwlboot +full:. +full:fw
5 * Copyright (c) 2007-2009 Marvell Semiconductor, Inc.
6 * All rights reserved.
11 * 1. Redistributions of source code must retain the above copyright
13 * without modification.
14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
17 * similar Disclaimer requirement for further binary redistribution.
23 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
30 * THE POSSIBILITY OF SUCH DAMAGES.
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/sysctl.h>
36 #include <sys/malloc.h>
37 #include <sys/lock.h>
38 #include <sys/mutex.h>
39 #include <sys/kernel.h>
40 #include <sys/errno.h>
41 #include <sys/bus.h>
42 #include <sys/endian.h>
44 #include <sys/linker.h>
45 #include <sys/firmware.h>
47 #include <machine/bus.h>
49 #include <dev/mwl/mwlhal.h>
50 #include <dev/mwl/mwlreg.h>
52 #include <sys/socket.h>
53 #include <sys/sockio.h>
54 #include <net/if.h>
55 #include <dev/mwl/mwldiag.h>
71 #define MWL_BASTREAMS_MAX 7 /* max BA streams (NB: fw >3.3.5.9) */
72 #define MWL_BAQID_MAX 8 /* max BA Q id's (NB: fw >3.3.5.9) */
81 * implemented in firmware.
100 pCmd->CmdHdr.Cmd = htole16(cmd); \
101 pCmd->CmdHdr.Length = htole16(sizeof(type)); \
106 pCmd->CmdHdr.MacId = vap->macid; \
139 * Per-device state. We allocate a single cmd buffer for
140 * submitting operations to the firmware. Access to this
141 * buffer (and the f/w) are single-threaded. At present
142 * we spin waiting for cmds to complete which is bad. Not
144 * control when we get cmd done interrupts. There's no
147 * linux driver logic. This falls apart when the f/w fails;
149 * to finish.
163 #define MHF_FWHANG 0x0002 /* fw appears hung */
167 int mh_regioncode; /* XXX last region code sent to fw */
217 return bus_space_read_4(mh->public.mh_iot, mh->public.mh_ioh, off); in RD4()
223 bus_space_write_4(mh->public.mh_iot, mh->public.mh_ioh, off, val); in WR4()
235 * Setup for communication with the device. We allocate
236 * a command buffer and map it for bus dma use. The pci
239 * memory controller reset). All bus i/o operations happen
240 * in BAR 1; the driver passes in the tag and handle we need.
254 mh->public.mh_ioh = ioh; in mwl_hal_attach()
255 mh->public.mh_iot = iot; in mwl_hal_attach()
257 mh->mh_streams[i].public.txq = ba2qid[i]; in mwl_hal_attach()
258 mh->mh_streams[i].stream = i; in mwl_hal_attach()
260 if (mh->mh_streams[i].public.txq < MWL_BAQID_MAX) in mwl_hal_attach()
261 qid2ba[mh->mh_streams[i].public.txq] = i; in mwl_hal_attach()
264 "stream %d\n", mh->mh_streams[i].public.txq, i); in mwl_hal_attach()
289 mh->mh_revs.mh_devid = devid; in mwl_hal_attach()
296 * space of the h/w. We request "coherent" memory which in mwl_hal_attach()
297 * will be uncached on some architectures. in mwl_hal_attach()
338 * Some cards have SDRAM. When loading firmware we need in mwl_hal_attach()
339 * to reset the SDRAM controller prior to doing this. in mwl_hal_attach()
341 * mwl_hal_fwload. in mwl_hal_attach()
380 * Reset internal state after a firmware download.
390 mh->mh_vaps[i].mh = NULL; in mwlResetHalState()
392 * Clear cumulative stats. in mwlResetHalState()
399 * Fetch cal data for later use. in mwlResetHalState()
400 * XXX may want to fetch other stuff too. in mwlResetHalState()
438 * Manipulate the debug mask. Note debug
440 * compiled with MWLHAL_DEBUG defined.
476 * Return the current ISR setting and clear the cause.
492 cause &~ mh->public.mh_imask);
500 * Set the interrupt mask.
510 mh->public.mh_imask = mask; in mwl_hal_intrset()
519 * for processing. The driver says what h/w q has work in
520 * case the f/w ever gets smarter.
534 * Callback from the driver on a cmd done interrupt.
536 * cmd completion.
552 * Return "hw specs". Note this must be the first
554 * f/w will lockup.
586 mh->mh_revs.mh_macRev = hw->hwVersion; /* XXX */ in mwl_hal_gethwspecs()
587 mh->mh_revs.mh_phyRev = hw->hostInterface; /* XXX */ in mwl_hal_gethwspecs()
591 /* starting with 3.4.x.x s/w BA streams supported */ in mwl_hal_gethwspecs()
602 * and related state. This cmd must be done immediately after a
603 * mwl_hal_gethwspecs call or the f/w will lockup.
628 if (mh->mh_revs.mh_macRev < 5) in mwl_hal_sethwdma()
643 * Retrieve statistics from the f/w.
667 * through public registers. Note these registers in mwl_hal_gethwstats()
668 * are "clear on read" so we maintain cumulative data. in mwl_hal_gethwstats()
686 * Set HT guard interval handling.
687 * Takes effect immediately.
715 * Configure radio.
716 * Takes effect immediately.
742 * Configure antenna use.
743 * Takes effect immediately.
771 * Set packet size threshold for implicit use of RTS.
772 * Takes effect immediately.
794 * Enable sta-mode operation (disables beacon frame xmit).
813 * Configure radar detection in support of 802.11h.
825 pCmd->CmdHdr.Length = htole16(sizeof(HostCmd_802_11h_Detect_Radar)); in mwl_hal_setradardetection()
837 * value suitable for feeding to the firmware.
838 * Note this includes byte swapping.
847 * precise band info causes it to lockup (sometimes). in cvtChannelFlags()
849 w = (chan->channelFlags.FreqBand == MWL_FREQ_BAND_2DOT4GHZ) ? in cvtChannelFlags()
851 switch (chan->channelFlags.ChnlWidth) { in cvtChannelFlags()
863 switch (chan->channelFlags.ExtChnlOffset) { in cvtChannelFlags()
878 * Start a channel switch announcement countdown. The IE
881 * channels.
905 * Set the region code that selects the radar bin'ing agorithm.
917 /* XXX map pseudo-codes to fw codes */ in mwl_hal_setregioncode()
960 htole32(RATEVAL(rate->RateSeries[0].Rate)); in mwl_hal_settxrate()
961 fp->FixRateTypeFlags.FixRateType = in mwl_hal_settxrate()
962 htole32(RATETYPE(rate->RateSeries[0].Rate)); in mwl_hal_settxrate()
970 if (rate->RateSeries[0].TryCount == 0) in mwl_hal_settxrate()
972 fp->FixRateTypeFlags.FixRateType = in mwl_hal_settxrate()
973 htole32(RATETYPE(rate->RateSeries[i].Rate)); in mwl_hal_settxrate()
975 htole32(RATEVAL(rate->RateSeries[i].Rate)); in mwl_hal_settxrate()
976 fp->FixRateTypeFlags.RetryCountValid = in mwl_hal_settxrate()
979 htole32(rate->RateSeries[i].TryCount-1); in mwl_hal_settxrate()
1070 if (c->channelFlags.FreqBand == MWL_FREQ_BAND_2DOT4GHZ) { in findchannel()
1072 if (c->channelFlags.ChnlWidth == MWL_CH_40_MHz_WIDTH) { in findchannel()
1074 if (c->channelFlags.ExtChnlOffset == MWL_EXT_CH_BELOW_CTRL_CH) in findchannel()
1080 } else if (c->channelFlags.FreqBand == MWL_FREQ_BAND_5GHZ) { in findchannel()
1081 if (c->channelFlags.ChnlWidth == MWL_CH_40_MHz_WIDTH) { in findchannel()
1083 if (c->channelFlags.ExtChnlOffset == MWL_EXT_CH_BELOW_CTRL_CH) in findchannel()
1089 if (ci->channels[i].ieee == chan) in findchannel()
1110 __func__, c->channel, c->channelFlags.FreqBand, in mwl_hal_settxpower()
1111 c->channelFlags.ChnlWidth, c->channelFlags.ExtChnlOffset); in mwl_hal_settxpower()
1121 if (c->channelFlags.FreqBand == MWL_FREQ_BAND_5GHZ) in mwl_hal_settxpower()
1191 pCmd->KeyParam.Length = htole16(sizeof(pCmd->KeyParam)); in mwl_hal_keyset()
1192 pCmd->KeyParam.KeyTypeId = htole16(kv->keyTypeId); in mwl_hal_keyset()
1193 pCmd->KeyParam.KeyInfo = htole32(kv->keyFlags); in mwl_hal_keyset()
1194 pCmd->KeyParam.KeyIndex = htole32(kv->keyIndex); in mwl_hal_keyset()
1196 memcpy(&pCmd->KeyParam.Key, &kv->key, kv->keyLen); in mwl_hal_keyset()
1199 pCmd->KeyParam.KeyLen = htole16(kv->keyLen); in mwl_hal_keyset()
1202 pCmd->KeyParam.KeyLen = htole16(sizeof(TKIP_TYPE_KEY)); in mwl_hal_keyset()
1203 pCmd->KeyParam.Key.TkipKey.TkipRsc.low = in mwl_hal_keyset()
1204 htole16(kv->key.tkip.rsc.low); in mwl_hal_keyset()
1205 pCmd->KeyParam.Key.TkipKey.TkipRsc.high = in mwl_hal_keyset()
1206 htole32(kv->key.tkip.rsc.high); in mwl_hal_keyset()
1207 pCmd->KeyParam.Key.TkipKey.TkipTsc.low = in mwl_hal_keyset()
1208 htole16(kv->key.tkip.tsc.low); in mwl_hal_keyset()
1209 pCmd->KeyParam.Key.TkipKey.TkipTsc.high = in mwl_hal_keyset()
1210 htole32(kv->key.tkip.tsc.high); in mwl_hal_keyset()
1213 pCmd->KeyParam.KeyLen = htole16(sizeof(AES_TYPE_KEY)); in mwl_hal_keyset()
1217 IEEE80211_ADDR_COPY(pCmd->KeyParam.Macaddr, mac); in mwl_hal_keyset()
1237 pCmd->KeyParam.Length = htole16(sizeof(pCmd->KeyParam)); in mwl_hal_keyreset()
1238 pCmd->KeyParam.KeyTypeId = htole16(kv->keyTypeId); in mwl_hal_keyreset()
1239 pCmd->KeyParam.KeyInfo = htole32(kv->keyFlags); in mwl_hal_keyreset()
1240 pCmd->KeyParam.KeyIndex = htole32(kv->keyIndex); in mwl_hal_keyreset()
1242 IEEE80211_ADDR_COPY(pCmd->KeyParam.Macaddr, mac); in mwl_hal_keyreset()
1290 pCmd->CmdHdr.Length = htole16(sizeof(HostCmd_DS_SET_BEACON)-1+frameLen); in mwl_hal_setbeacon()
1382 pCmd->BaInfo.CreateParams.BarThrs = htole32(63); in bastream_check_available()
1383 pCmd->BaInfo.CreateParams.WindowSize = htole32(64); in bastream_check_available()
1384 pCmd->BaInfo.CreateParams.IdleThrs = htole32(0x22000); in bastream_check_available()
1385 IEEE80211_ADDR_COPY(&pCmd->BaInfo.CreateParams.PeerMacAddr[0], Macaddr); in bastream_check_available()
1386 pCmd->BaInfo.CreateParams.DialogToken = 10; in bastream_check_available()
1387 pCmd->BaInfo.CreateParams.Tid = Tid; in bastream_check_available()
1388 pCmd->BaInfo.CreateParams.QueueId = qid; in bastream_check_available()
1389 pCmd->BaInfo.CreateParams.ParamInfo = (uint8_t) ParamInfo; in bastream_check_available()
1391 cvtBAFlags(&pCmd->BaInfo.CreateParams.Flags, sp->ba_policy, 0); in bastream_check_available()
1393 pCmd->BaInfo.CreateParams.Flags = in bastream_check_available()
1403 * h/w backed under some (as yet not understood) conditions. in bastream_check_available()
1404 * Check the result code to catch this. in bastream_check_available()
1406 if (le16toh(pCmd->CmdHdr.Result) != HostCmd_RESULT_OK) in bastream_check_available()
1435 sp->public.data[0] = a1; in mwl_hal_bastream_alloc()
1436 sp->public.data[1] = a2; in mwl_hal_bastream_alloc()
1455 return &mh->mh_streams[s].public; in mwl_hal_bastream_lookup()
1474 pCmd->BaInfo.CreateParams.BarThrs = htole32(BarThrs); in mwl_hal_bastream_create()
1475 pCmd->BaInfo.CreateParams.WindowSize = htole32(WindowSize); in mwl_hal_bastream_create()
1476 pCmd->BaInfo.CreateParams.IdleThrs = htole32(0x22000); in mwl_hal_bastream_create()
1477 IEEE80211_ADDR_COPY(&pCmd->BaInfo.CreateParams.PeerMacAddr[0], in mwl_hal_bastream_create()
1480 memset(&pCmd->BaInfo.CreateParams.StaSrcMacAddr, 0, IEEE80211_ADDR_LEN); in mwl_hal_bastream_create()
1482 pCmd->BaInfo.CreateParams.DialogToken = DialogToken; in mwl_hal_bastream_create()
1484 pCmd->BaInfo.CreateParams.DialogToken = 10; in mwl_hal_bastream_create()
1486 pCmd->BaInfo.CreateParams.Tid = sp->tid; in mwl_hal_bastream_create()
1487 pCmd->BaInfo.CreateParams.QueueId = sp->stream; in mwl_hal_bastream_create()
1488 pCmd->BaInfo.CreateParams.ParamInfo = sp->paraminfo; in mwl_hal_bastream_create()
1490 pCmd->BaInfo.CreateParams.StartSeqNo = htole16(seqno); in mwl_hal_bastream_create()
1492 cvtBAFlags(&pCmd->BaInfo.CreateParams.Flags, sp->ba_policy, 0); in mwl_hal_bastream_create()
1494 pCmd->BaInfo.CreateParams.Flags = in mwl_hal_bastream_create()
1504 * h/w backed under some (as yet not understood) conditions. in mwl_hal_bastream_create()
1505 * Check the result code to catch this. in mwl_hal_bastream_create()
1507 if (le16toh(pCmd->CmdHdr.Result) != HostCmd_RESULT_OK) in mwl_hal_bastream_create()
1532 pCmd->BaInfo.DestroyParams.FwBaContext.Context = in mwl_hal_bastream_destroy()
1540 sp->public.data[0] = NULL; in mwl_hal_bastream_destroy()
1541 sp->public.data[1] = NULL; in mwl_hal_bastream_destroy()
1583 /* fw returns qid, map it to BA stream */ in mwl_hal_getwatchdogbitmap()
1592 * Configure aggressive Ampdu rate mode.
1675 to->AddHtInfo.ControlChan = from->AddHtInfo.ControlChan; in cvtPeerInfo()
1676 to->AddHtInfo.AddChan = from->AddHtInfo.AddChan; in cvtPeerInfo()
1677 to->AddHtInfo.OpMode = htole16(from->AddHtInfo.OpMode); in cvtPeerInfo()
1678 to->AddHtInfo.stbc = htole16(from->AddHtInfo.stbc); in cvtPeerInfo()
1681 /* XXX station id must be in [0..63] */
1737 * save queues and reap frames on the tx aggregation q's.
1751 * a non-zero value is a noop. in mwl_hal_setkeepalive()
1863 * NB: CWmin and CWmax are always set. in mwl_hal_setedcaparams()
2008 * Calculate the max tx power from the channel's cal data.
2020 * Construct channel info for 5GHz channels from cal data.
2063 * Construct channel info for 2.4GHz channels from cal data.
2229 * Diagnostic api's for set/get registers.
2278 u_int r = regs[i].start; in mwl_hal_getregdump()
2279 u_int e = regs[i].end; in mwl_hal_getregdump()
2331 device_printf(mh->mh_dev, "problem loading fw image\n"); in mwl_hal_getdiagstate()
2340 * Low level firmware cmd block handshake support.
2419 * Firmware download support.
2427 #include <dev/mwl/mwlbootfw.h>
2428 #include <dev/mwl/mwl88W8363fw.h>
2473 * Firmware block xmit when talking to the boot-rom.
2494 * Firmware block xmit when talking to the 1st-stage loader.
2525 const char *fwbootname = "mwlboot"; in mwl_hal_fwload()
2527 const struct firmware *fw; in mwl_hal_fwload() local
2536 fw = firmware_get(fwname); in mwl_hal_fwload()
2537 if (fw == NULL) { in mwl_hal_fwload()
2542 fmdata = fw->data; in mwl_hal_fwload()
2543 fmsize = fw->datasize; in mwl_hal_fwload()
2553 * 2-stage load, get the boot firmware. in mwl_hal_fwload()
2579 * Do 2-stage load. The 1st stage loader is setup in mwl_hal_fwload()
2581 * image using a different handshake. With this in mwl_hal_fwload()
2583 * that have a CRC. If a chunk is incorrect we'll in mwl_hal_fwload()
2584 * be told to retransmit. in mwl_hal_fwload()
2616 * retry infinitely. in mwl_hal_fwload()
2646 /* done with firmware... */ in mwl_hal_fwload()
2649 firmware_put(fw, FIRMWARE_UNLOAD); in mwl_hal_fwload()
2653 * written back indicating it's ready to go. in mwl_hal_fwload()
2657 * XXX WAR for mfg fw download in mwl_hal_fwload()
2673 /* done with firmware... */ in mwl_hal_fwload()
2676 firmware_put(fw, FIRMWARE_UNLOAD); in mwl_hal_fwload()