driver for Marvell 88W8363 Wireless LAN controller

This commit is contained in:
Sam Leffler 2009-06-01 18:07:01 +00:00
parent a43cee7009
commit cf4c5a5331
17 changed files with 13057 additions and 0 deletions

View File

@ -1162,6 +1162,33 @@ dev/mpt/mpt_pci.c optional mpt pci
dev/mpt/mpt_raid.c optional mpt
dev/mpt/mpt_user.c optional mpt
dev/msk/if_msk.c optional msk
dev/mwl/if_mwl.c optional mwl
dev/mwl/if_mwl_pci.c optional mwl pci
dev/mwl/mwlhal.c optional mwl
mwlfw.c optional mwlfw \
compile-with "${AWK} -f $S/tools/fw_stub.awk mw88W8363.fw:mw88W8363fw mwlboot.fw:mwlboot -mmwl -c${.TARGET}" \
no-implicit-rule before-depend local \
clean "mwlfw.c"
mw88W8363.fwo optional mwlfw \
dependency "mw88W8363.fw" \
compile-with "${LD} -b binary -d -warn-common -r -d -o ${.TARGET} mw88W8363.fw" \
no-implicit-rule \
clean "mw88W8363.fwo"
mw88W8363.fw optional mwlfw \
dependency ".PHONY" \
compile-with "uudecode -o ${.TARGET} $S/contrib/dev/mwl/mw88W8363.fw.uu" \
no-obj no-implicit-rule \
clean "mw88W8363.fw"
mwlboot.fwo optional mwlfw \
dependency "mwlboot.fw" \
compile-with "${LD} -b binary -d -warn-common -r -d -o ${.TARGET} mwlboot.fw" \
no-implicit-rule \
clean "mwlboot.fwo"
mwlboot.fw optional mwlfw \
dependency ".PHONY" \
compile-with "uudecode -o ${.TARGET} $S/contrib/dev/mwl/mwlboot.fw.uu" \
no-obj no-implicit-rule \
clean "mwlboot.fw"
dev/mxge/if_mxge.c optional mxge pci
dev/mxge/mxge_lro.c optional mxge pci
dev/mxge/mxge_eth_z8e.c optional mxge pci

View File

@ -777,6 +777,14 @@ MALO_DEBUG opt_malo.h
MALO_TXBUF opt_malo.h
MALO_RXBUF opt_malo.h
# options for the Marvell wireless driver
MWL_DEBUG opt_mwl.h
MWL_TXBUF opt_mwl.h
MWL_RXBUF opt_mwl.h
MWL_DIAGAPI opt_mwl.h
MWL_AGGR_SIZE opt_mwl.h
MWL_TX_NODROP opt_mwl.h
# dcons options
DCONS_BUF_SIZE opt_dcons.h
DCONS_POLL_HZ opt_dcons.h

View File

@ -0,0 +1,43 @@
FIRMWARE LICENSE TERMS
Copyright (c) Marvell International Ltd.
All rights reserved.
Redistribution. Redistribution and use in binary form, without
modification, are permitted provided that the following conditions are
met:
* Redistributions must reproduce the above copyright notice and the
following disclaimer in the documentation and/or other materials
provided with the distribution.
* Neither the name of Marvell International Ltd. nor the names of its
suppliers may be used to endorse or promote products derived from this
software without specific prior written permission.
* No reverse engineering, decompilation, or disassembly of this software
is permitted.
Limited patent license. Marvell International Ltd. grants a world-wide,
royalty-free, non-exclusive license under patents it now or hereafter
owns or controls to make, have made, use, import, offer to sell and sell
("Utilize") this software, but solely to the extent that any such patent
is necessary to Utilize the software alone, or in combination with an
operating system licensed under an approved Open Source license as
listed by the Open Source Initiative at http://opensource.org/licenses.
The patent license shall not apply to any other combinations which
include this software. No hardware per se is licensed hereunder.
DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIPOSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,22 @@
# $FreeBSD$
FILES= mw88W8363.fw.uu mwlboot.fw.uu
mw88W8363.fw.uu: mv88W8363fw.h LICENSE
(cat mv88W8363fw.h; \
echo 'int main(void) { \
write(1, fmimage, sizeof(fmimage)); return 0; \
}') | ${CC} -o build -x c -
(sed 's/^/# /' LICENSE; ./build | uuencode mw88W8363.fw) > ${.TARGET}
mwlboot.fw.uu: mvbootfw.h LICENSE
(cat mvbootfw.h; \
echo 'int main(void) { \
write(1, hlpimage, sizeof(hlpimage)); return 0; \
}') | ${CC} -o build -x c -
(sed 's/^/# /' LICENSE; ./build | uuencode mwlboot.fw) > ${.TARGET}
clean:
rm -f build build.c ${FILES}
.include <bsd.prog.mk>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,97 @@
# FIRMWARE LICENSE TERMS
#
#
# Copyright (c) Marvell International Ltd.
#
# All rights reserved.
#
# Redistribution. Redistribution and use in binary form, without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions must reproduce the above copyright notice and the
# following disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# * Neither the name of Marvell International Ltd. nor the names of its
# suppliers may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# * No reverse engineering, decompilation, or disassembly of this software
# is permitted.
#
# Limited patent license. Marvell International Ltd. grants a world-wide,
# royalty-free, non-exclusive license under patents it now or hereafter
# owns or controls to make, have made, use, import, offer to sell and sell
# ("Utilize") this software, but solely to the extent that any such patent
# is necessary to Utilize the software alone, or in combination with an
# operating system licensed under an approved Open Source license as
# listed by the Open Source Initiative at http://opensource.org/licenses.
# The patent license shall not apply to any other combinations which
# include this software. No hardware per se is licensed hereunder.
#
# DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIPOSSIBILITY OF SUCH DAMAGE.
#
#
begin 644 mwlboot.fw
M`P``Z@4```````````````````!0`)_E$`\![@``X.-($)_E#`"!Y1@`D>4@
M"*#A"P!0XP0```H;`%#C`@``"BP`G^4P`('E`0``ZB0`G^4P`('E(-"?Y2``
MG^4`$)#E'""?Y0`0@N4&``#J=!\````@`(`2"0``YSH'%``@``0$````_/\`
M`,2`C^(#`)CH"`"`X`@0@>`!L$#B`0!0X1,```IP`+#H!0!4X?K__PH!`!3C
M"T"$$`$`%>,+4(40`@`5XPE0A1`#4,7C$&!6XHP0M"B,$*4H^___BH9NL.$,
M`+0H#`"E*`1PE$0$<(5$Z?__Z@@@F.4,,)CE""""X`@P@^`!P$+B`'"@XP``
MH.,`8*#C`+"@XP,`4N$0```+,`"RZ`$`%.,,0(00`@`4XPE`A!`#0,3C$%!5
MXL$(I"C\__^*A5ZPX4$`I"@$<(1$\/__ZA@````\````/````%0````$\!_E
M@`$`P````````````````*@!``````#`L`8``%@(````"`#`D````*@!````
M````L`8`P`````"0"`#`<````'!'<$<`1PA'$$<81R!'*$<P1SA'>$<```,`
M4N.#``":`\`0X@@```H!,-'D`@!<XPP@@N`!P-&4`3#`Y`$PT30$($+B`<#`
ME`$PP#0#,!'B8P``"@0@4N)T```Z`\`QYP(`4^,(```*#P``BBPTH.$$P+'E
M!"!2X@P\@^$$,(#D^?__*@$0@>)H``#J+#B@X03`L>4$(%+B##B#X00P@.3Y
M__\J`A"!XF```.HL/*#A!,"QY00@4N(,-(/A!#"`Y/G__RH#$('B6```ZGA'
M```>_R_A>$<```Y0H.$\``#K!>"@X0!`H.$-$*#A"C"@X0<`P.-@T(#B$$`M
MZ?H``.L00+WH!]#!XP!@H.,`<*#C`("@XP"PH.,$P*#AP`FLZ,`)K.C`":SH
MP`FLZ!]`+>D``*#C`!"@X____^M`$('B`6"`X$1OAN(<8(3E&!"$Y0$`H.,4
M`(3E'T"]Z`(0H.$>_R_A>$<``!!`+>D`(*#A``"@X____^L00+WH'O\OX=3_
M_^LV``#Z',"?Y0_`C.`!`!SC#>"/$@_@H`$<_R_A`<"/XAS_+^$`\%+X[0,`
M`'A'```!0"WI4```^P%`O>@!``#J>$<`````X.-3``#J>$<`````G^4>_R_A
MH`@`P'A'```00"WI("!2X@4``#H84+$H&%"@*!A0L2@84*`H("!2(OG__RH"
MSK#A&%"Q*!A0H"@8`+%(&`"@2!!`O>@"S[#A!#"1)`0P@"0>_R\!@B^PX0$@
MT40!,-$D`<#1)`$@P$0!,,`D`<#`)![_+^$0M00<`/``^"`<__>L[Q"\"+P8
M1_"U!!P-'(.P`/`4Z@"4`94`(`#P`/@"D"9(:49X1`#P`/@%'`X<`*D#R0#P
M`/@`\`#X`/``^``A`"``\`#X!QS_]Y;O!!P`(0=B`"``\`#X01QA8@`A`"``
M\`#X`"&@8@`@`/``^``AX&(`(`#P`/@@8P#P`/@`\`#X`/``^`#P`/@`\`#X
M`/``^`#P`/@`\`#X*!PQ'`.P\+P(O!A'"+4`\`#X`/``^`#P`/@!L`B\&$<`
M`)0```!X1P``&`"@XP@0G^56-!+O'O\OX0D````F``(`>$<``![_+^%X1P``
M$$`MZ:'__^L$`(#B$$"]Z![_+^$`1P``_K4`(`*0`9!-2`$FP&L&*!G2`J,;
M7%L`GT0```,$!`0$!``F1TH`(1%@A`!&2%%@D6!&30%9*!S_]S?^1$@`6?_W
M,OX`X/[G`9@`*`G004B`:0`,``(0(0A#!1P`(`&0`.`0)3Q/*!PY6?_W'OX`
M+@30.D@`6?_W%_X`)@`@`)`W2`!9__<0_C!(+D\/R`_'$#\X:`$H#]`$*`W0
M`2`N3P5#*!PY6?_W`/XL2`!9__?[_0"8`"CCT")(`&@!*!C0!"@,T21/`"`Y
M6?_W[OTC2`!9__?I_1M(0&C_]X__&4D`(`A@2&"(8,A@`I@`**O0_KT93Q-(
M.5F%:"@<__?5_19(`%G_]]#]`"``D!1(`%G_]\K]$T@`6?_WQOT`*`'1`2;<
MYP$@!4,H'#E9__>]_0I(`%G_][C]`)@`*,_1Y>?`_P``D`@`P!@(`,``"@#`
M``@`P``@`(!X"`#`2`@`P#`(`,!@"`#`"$L:8!AA&6(#(,`"!"H!T&<@@`$#
M24`Q"&`8:``H_-$(8'!'`.@`@`0`G^5`'8#B#O"@X0`0``0!204@2&%P1P`,
M`(!P1P```"!P1W!'``!P1P``<$<```-(!$D(@$`'08A!@'!'```$@```(```
M@`$AR0=(B$`'_-5P1P))`T@!@(\AP8-P1P2````@``"``2')!XAB<$<!(<D'
MB&-P1P5*@+42'07*`DD$.O_W4NT`(("]``H`P)`(`,"`M?_WZ_X`(("]```$
M(4@'06,`(4%B<$<!(<D'2&I`!_S5<$<!(<@'`6($(4%C<$<!(<D'B(%P1P$A
MR0?(8W!'<$<```=(`+4`:$((!4E2`$`YR&F`!_S5"&D#2?_W<O\`O0``0`P`
M@``*`,!P1P``!$D(8`-(!2%`.$%A`"'!87!'``!`#`"`<$<```)(`"$!@0TA
M`8!P1R`!`(`"20B)P`?\U7!'```@`0"``T@-(0&``"&!@0$A@8!P1R`!`(`!
M20AA<$<````!`(`!24AA<$<````!`(`!200@"(-P1T```(`#20B)0`?\U0`@
M"(%P1P``0```@`%)!"`(@W!'0```@`$AR0>(8G!'`2')!TAA<$=X1P``$$`M
MZ2C__^L`$*#C`!"`Y1!`O>@>_R_A004`P!$%`,`M!@#`>08`P*4%`,#M!0#`
M704`P!D%`,!-!@#`C08`P+D%`,`)!@#`-04`P`D%`,`=!@#`908`P)D%`,#%
M!0#`'04`P/T$`,`-!@#`608`P(T%`,#!!0#`904`P`T%`,!E!0#`904`P&4%
>`,!E!0#`504`P!4%`,!!!@#`A08`P+$%`,#Q!0#`
`
end

4990
sys/dev/mwl/if_mwl.c Normal file

File diff suppressed because it is too large Load Diff

316
sys/dev/mwl/if_mwl_pci.c Normal file
View File

@ -0,0 +1,316 @@
/*-
* Copyright (c) 2007-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2007-2009 Marvell Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*/
#include <sys/cdefs.h>
#ifdef __FreeBSD__
__FBSDID("$FreeBSD$");
#endif
/*
* PCI front-end for the Marvell Wireless LAN controller driver.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/errno.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/bus.h>
#include <sys/rman.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_media.h>
#include <net/if_arp.h>
#include <net80211/ieee80211_var.h>
#include <dev/mwl/if_mwlvar.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
/*
* PCI glue.
*/
struct mwl_pci_softc {
struct mwl_softc sc_sc;
struct resource *sc_sr0; /* BAR0 memory resource */
struct resource *sc_sr1; /* BAR1 memory resource */
struct resource *sc_irq; /* irq resource */
void *sc_ih; /* interrupt handler */
};
#define BS_BAR0 0x10
#define BS_BAR1 0x14
struct mwl_pci_ident {
uint16_t vendor;
uint16_t device;
const char *name;
};
static const struct mwl_pci_ident mwl_pci_ids[] = {
{ 0x11ab, 0x2a02, "Marvell 88W8363" },
{ 0x11ab, 0x2a03, "Marvell 88W8363" },
{ 0x11ab, 0x2a0a, "Marvell 88W8363" },
{ 0x11ab, 0x2a0b, "Marvell 88W8363" },
{ 0x11ab, 0x2a0c, "Marvell 88W8363" },
{ 0x11ab, 0x2a21, "Marvell 88W8363" },
{ 0x11ab, 0x2a24, "Marvell 88W8363" },
{ 0, 0, NULL }
};
const static struct mwl_pci_ident *
mwl_pci_lookup(int vendor, int device)
{
const struct mwl_pci_ident *ident;
for (ident = mwl_pci_ids; ident->name != NULL; ident++)
if (vendor == ident->vendor && device == ident->device)
return ident;
return NULL;
}
static int
mwl_pci_probe(device_t dev)
{
const struct mwl_pci_ident *ident;
ident = mwl_pci_lookup(pci_get_vendor(dev), pci_get_device(dev));
if (ident != NULL) {
device_set_desc(dev, ident->name);
return BUS_PROBE_DEFAULT;
}
return ENXIO;
}
static u_int32_t
mwl_pci_setup(device_t dev)
{
u_int32_t cmd;
/*
* Enable memory mapping and bus mastering.
*/
cmd = pci_read_config(dev, PCIR_COMMAND, 4);
cmd |= PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN;
pci_write_config(dev, PCIR_COMMAND, cmd, 4);
cmd = pci_read_config(dev, PCIR_COMMAND, 4);
if ((cmd & PCIM_CMD_MEMEN) == 0) {
device_printf(dev, "failed to enable memory mapping\n");
return 0;
}
if ((cmd & PCIM_CMD_BUSMASTEREN) == 0) {
device_printf(dev, "failed to enable bus mastering\n");
return 0;
}
return 1;
}
static int
mwl_pci_attach(device_t dev)
{
struct mwl_pci_softc *psc = device_get_softc(dev);
struct mwl_softc *sc = &psc->sc_sc;
int rid, error = ENXIO;
sc->sc_dev = dev;
/*
* Enable memory mapping and bus mastering.
*/
if (!mwl_pci_setup(dev))
return 0;
/*
* Setup memory-mapping of PCI registers.
*/
rid = BS_BAR0;
psc->sc_sr0 = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (psc->sc_sr0 == NULL) {
device_printf(dev, "cannot map BAR0 register space\n");
goto bad;
}
rid = BS_BAR1;
psc->sc_sr1 = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (psc->sc_sr1 == NULL) {
device_printf(dev, "cannot map BAR1 register space\n");
goto bad1;
}
sc->sc_invalid = 1;
/*
* Arrange interrupt line.
*/
rid = 0;
psc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_SHAREABLE|RF_ACTIVE);
if (psc->sc_irq == NULL) {
device_printf(dev, "could not map interrupt\n");
goto bad2;
}
if (bus_setup_intr(dev, psc->sc_irq,
INTR_TYPE_NET | INTR_MPSAFE,
NULL, mwl_intr, sc, &psc->sc_ih)) {
device_printf(dev, "could not establish interrupt\n");
goto bad3;
}
/*
* Setup DMA descriptor area.
*/
if (bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
1, 0, /* alignment, bounds */
BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
BUS_SPACE_MAXADDR, /* maxsize */
MWL_TXDESC, /* nsegments */
BUS_SPACE_MAXADDR, /* maxsegsize */
BUS_DMA_ALLOCNOW, /* flags */
NULL, /* lockfunc */
NULL, /* lockarg */
&sc->sc_dmat)) {
device_printf(dev, "cannot allocate DMA tag\n");
goto bad4;
}
/*
* Finish off the attach.
*/
MWL_LOCK_INIT(sc);
sc->sc_io0t = rman_get_bustag(psc->sc_sr0);
sc->sc_io0h = rman_get_bushandle(psc->sc_sr0);
sc->sc_io1t = rman_get_bustag(psc->sc_sr1);
sc->sc_io1h = rman_get_bushandle(psc->sc_sr1);
if (mwl_attach(pci_get_device(dev), sc) == 0)
return (0);
MWL_LOCK_DESTROY(sc);
bus_dma_tag_destroy(sc->sc_dmat);
bad4:
bus_teardown_intr(dev, psc->sc_irq, psc->sc_ih);
bad3:
bus_release_resource(dev, SYS_RES_IRQ, 0, psc->sc_irq);
bad2:
bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR1, psc->sc_sr1);
bad1:
bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR0, psc->sc_sr0);
bad:
return (error);
}
static int
mwl_pci_detach(device_t dev)
{
struct mwl_pci_softc *psc = device_get_softc(dev);
struct mwl_softc *sc = &psc->sc_sc;
/* check if device was removed */
sc->sc_invalid = !bus_child_present(dev);
mwl_detach(sc);
bus_generic_detach(dev);
bus_teardown_intr(dev, psc->sc_irq, psc->sc_ih);
bus_release_resource(dev, SYS_RES_IRQ, 0, psc->sc_irq);
bus_dma_tag_destroy(sc->sc_dmat);
bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR1, psc->sc_sr1);
bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR0, psc->sc_sr0);
MWL_LOCK_DESTROY(sc);
return (0);
}
static int
mwl_pci_shutdown(device_t dev)
{
struct mwl_pci_softc *psc = device_get_softc(dev);
mwl_shutdown(&psc->sc_sc);
return (0);
}
static int
mwl_pci_suspend(device_t dev)
{
struct mwl_pci_softc *psc = device_get_softc(dev);
mwl_suspend(&psc->sc_sc);
return (0);
}
static int
mwl_pci_resume(device_t dev)
{
struct mwl_pci_softc *psc = device_get_softc(dev);
if (!mwl_pci_setup(dev))
return ENXIO;
mwl_resume(&psc->sc_sc);
return (0);
}
static device_method_t mwl_pci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, mwl_pci_probe),
DEVMETHOD(device_attach, mwl_pci_attach),
DEVMETHOD(device_detach, mwl_pci_detach),
DEVMETHOD(device_shutdown, mwl_pci_shutdown),
DEVMETHOD(device_suspend, mwl_pci_suspend),
DEVMETHOD(device_resume, mwl_pci_resume),
{ 0,0 }
};
static driver_t mwl_pci_driver = {
"mwl",
mwl_pci_methods,
sizeof (struct mwl_pci_softc)
};
static devclass_t mwl_devclass;
DRIVER_MODULE(mwl, pci, mwl_pci_driver, mwl_devclass, 0, 0);
MODULE_VERSION(mwl, 1);
MODULE_DEPEND(mwl, wlan, 1, 1, 1); /* 802.11 media layer */
MODULE_DEPEND(mwl, mwlfw_fw, 1, 1, 1); /* firmware */

136
sys/dev/mwl/if_mwlioctl.h Normal file
View File

@ -0,0 +1,136 @@
/*-
* Copyright (c) 2007-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2007-2009 Marvell Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
* $FreeBSD$
*/
/*
* Ioctl-related defintions for the Marvel Wireless LAN controller driver.
*/
#ifndef _DEV_MWL_MVIOCTL_H
#define _DEV_MWL_MVIOCTL_H
struct mwl_stats {
struct mwl_hal_hwstats hw_stats; /* XXX tied to h/w defs */
uint32_t mst_failure; /* generic hardware failure */
uint32_t mst_rx_badtkipicv;
uint32_t mst_tx_discard;
uint32_t mst_tx_qstop;
uint32_t mst_tx_encap;
uint32_t mst_tx_mgmt;
uint32_t mst_rx_nombuf;
uint32_t mst_rx_busdma;
uint32_t mst_rx_tooshort;
uint32_t mst_tx_busdma;
uint32_t mst_tx_linear;
uint32_t mst_tx_nombuf;
uint32_t mst_tx_nodata;
uint32_t mst_tx_shortpre;
uint32_t mst_tx_retries;
uint32_t mst_tx_mretries;
uint32_t mst_tx_linkerror;
uint32_t mst_tx_xretries;
uint32_t mst_tx_aging;
uint32_t mst_tx_qdrop;
uint32_t mst_ff_txerr;
uint32_t mst_watchdog;
uint32_t mst_tx_packets;
uint32_t mst_rx_packets;
int8_t mst_rx_rssi;
int8_t mst_rx_noise;
uint8_t mst_tx_rate;
uint32_t mst_ant_tx[4];
uint32_t mst_ant_rx[4];
uint32_t mst_tx_tso;
uint32_t mst_tso_badeth;
uint32_t mst_tso_nohdr;
uint32_t mst_tso_badsplit;
uint32_t mst_rx_crypto;
uint32_t mst_rx_tkipmic;
uint32_t mst_rx_nodmabuf;
uint32_t mst_tx_noheadroom;
uint32_t mst_tx_badframetype;
uint32_t mst_ampdu_nostream;
uint32_t mst_ampdu_reject;
uint32_t mst_addba_nostream;
uint32_t mst_bacreate_failed;
uint32_t mst_bawatchdog;
uint32_t mst_radardetect;
uint32_t mst_rx_dmabufmissing;
uint32_t mst_bawatchdog_notfound;
uint32_t mst_bawatchdog_empty;
uint32_t mst_bawatchdog_failed;
uint32_t mst_rxbuf_failed;
uint32_t mst_pad[31];
};
#define SIOCGMVSTATS _IOWR('i', 137, struct ifreq)
/*
* Radio capture format.
*/
#define MWL_RX_RADIOTAP_PRESENT ( \
(1 << IEEE80211_RADIOTAP_FLAGS) | \
(1 << IEEE80211_RADIOTAP_RATE) | \
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \
0)
struct mwl_rx_radiotap_header {
struct ieee80211_radiotap_header wr_ihdr;
u_int8_t wr_flags;
u_int8_t wr_rate;
u_int16_t wr_chan_freq;
u_int16_t wr_chan_flags;
int8_t wr_antsignal;
int8_t wr_antnoise;
u_int8_t wr_antenna;
};
#define MWL_TX_RADIOTAP_PRESENT ( \
(1 << IEEE80211_RADIOTAP_FLAGS) | \
(1 << IEEE80211_RADIOTAP_RATE) | \
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
(1 << IEEE80211_RADIOTAP_DBM_TX_POWER) | \
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
0)
struct mwl_tx_radiotap_header {
struct ieee80211_radiotap_header wt_ihdr;
u_int8_t wt_flags;
u_int8_t wt_rate;
u_int16_t wt_chan_freq;
u_int16_t wt_chan_flags;
u_int8_t wt_txpower;
u_int8_t wt_antenna;
};
#endif /* _DEV_MWL_MVIOCTL_H */

354
sys/dev/mwl/if_mwlvar.h Normal file
View File

@ -0,0 +1,354 @@
/*-
* Copyright (c) 2007-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2007-2009 Marvell Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
* $FreeBSD$
*/
/*
* Definitions for the Marvell 88W8363 Wireless LAN controller.
*/
#ifndef _DEV_MWL_MVVAR_H
#define _DEV_MWL_MVVAR_H
#include <sys/endian.h>
#include <net80211/ieee80211_radiotap.h>
#include <dev/mwl/mwlhal.h>
#include <dev/mwl/mwlreg.h>
#include <dev/mwl/if_mwlioctl.h>
#ifndef MWL_TXBUF
#define MWL_TXBUF 256 /* number of TX descriptors/buffers */
#endif
#ifndef MWL_RXDESC
#define MWL_RXDESC 256 /* number of RX descriptors */
#endif
#ifndef MWL_RXBUF
#define MWL_RXBUF ((5*MWL_RXDESC)/2)/* number of RX dma buffers */
#endif
#ifndef MWL_MAXBA
#define MWL_MAXBA 2 /* max BA streams/sta */
#endif
#ifdef MWL_SGDMA_SUPPORT
#define MWL_TXDESC 6 /* max tx descriptors/segments */
#else
#define MWL_TXDESC 1 /* max tx descriptors/segments */
#endif
#ifndef MWL_AGGR_SIZE
#define MWL_AGGR_SIZE 3839 /* max tx agregation size */
#endif
#define MWL_AGEINTERVAL 1 /* poke f/w every sec to age q's */
#define MWL_MAXSTAID 64 /* max of 64 stations */
/*
* DMA state for tx/rx descriptors.
*/
/*
* Software backed version of tx/rx descriptors. We keep
* the software state out of the h/w descriptor structure
* so that may be allocated in uncached memory w/o paying
* performance hit.
*/
struct mwl_txbuf {
STAILQ_ENTRY(mwl_txbuf) bf_list;
void *bf_desc; /* h/w descriptor */
bus_addr_t bf_daddr; /* physical addr of desc */
bus_dmamap_t bf_dmamap; /* DMA map for descriptors */
int bf_nseg;
bus_dma_segment_t bf_segs[MWL_TXDESC];
struct mbuf *bf_m;
struct ieee80211_node *bf_node;
struct mwl_txq *bf_txq; /* backpointer to tx q/ring */
};
typedef STAILQ_HEAD(, mwl_txbuf) mwl_txbufhead;
/*
* Common "base class" for tx/rx descriptor resources
* allocated using the bus dma api.
*/
struct mwl_descdma {
const char* dd_name;
void *dd_desc; /* descriptors */
bus_addr_t dd_desc_paddr; /* physical addr of dd_desc */
bus_size_t dd_desc_len; /* size of dd_desc */
bus_dma_segment_t dd_dseg;
int dd_dnseg; /* number of segments */
bus_dma_tag_t dd_dmat; /* bus DMA tag */
bus_dmamap_t dd_dmamap; /* DMA map for descriptors */
void *dd_bufptr; /* associated buffers */
};
/*
* TX/RX ring definitions. There are 4 tx rings, one
* per AC, and 1 rx ring. Note carefully that transmit
* descriptors are treated as a contiguous chunk and the
* firmware pre-fetches descriptors. This means that we
* must preserve order when moving descriptors between
* the active+free lists; otherwise we may stall transmit.
*/
struct mwl_txq {
struct mwl_descdma dma; /* bus dma resources */
struct mtx lock; /* tx q lock */
char name[12]; /* e.g. "mwl0_txq4" */
int qnum; /* f/w q number */
int txpri; /* f/w tx priority */
int nfree; /* # buffers on free list */
mwl_txbufhead free; /* queue of free buffers */
mwl_txbufhead active; /* queue of active buffers */
};
#define MWL_TXQ_LOCK_INIT(_sc, _tq) do { \
snprintf((_tq)->name, sizeof((_tq)->name), "%s_txq%u", \
device_get_nameunit((_sc)->sc_dev), (_tq)->qnum); \
mtx_init(&(_tq)->lock, (_tq)->name, NULL, MTX_DEF); \
} while (0)
#define MWL_TXQ_LOCK_DESTROY(_tq) mtx_destroy(&(_tq)->lock)
#define MWL_TXQ_LOCK(_tq) mtx_lock(&(_tq)->lock)
#define MWL_TXQ_UNLOCK(_tq) mtx_unlock(&(_tq)->lock)
#define MWL_TXQ_LOCK_ASSERT(_tq) mtx_assert(&(_tq)->lock, MA_OWNED)
#define MWL_TXDESC_SYNC(txq, ds, how) do { \
bus_dmamap_sync((txq)->dma.dd_dmat, (txq)->dma.dd_dmamap, how); \
} while(0)
/*
* RX dma buffers that are not in use are kept on a list.
*/
struct mwl_jumbo {
SLIST_ENTRY(mwl_jumbo) next;
};
typedef SLIST_HEAD(, mwl_jumbo) mwl_jumbohead;
#define MWL_JUMBO_DATA2BUF(_data) ((struct mwl_jumbo *)(_data))
#define MWL_JUMBO_BUF2DATA(_buf) ((uint8_t *)(_buf))
#define MWL_JUMBO_OFFSET(_sc, _data) \
(((const uint8_t *)(_data)) - (const uint8_t *)((_sc)->sc_rxmem))
#define MWL_JUMBO_DMA_ADDR(_sc, _data) \
((_sc)->sc_rxmem_paddr + MWL_JUMBO_OFFSET(_sc, _data))
struct mwl_rxbuf {
STAILQ_ENTRY(mwl_rxbuf) bf_list;
void *bf_desc; /* h/w descriptor */
bus_addr_t bf_daddr; /* physical addr of desc */
uint8_t *bf_data; /* rx data area */
};
typedef STAILQ_HEAD(, mwl_rxbuf) mwl_rxbufhead;
#define MWL_RXDESC_SYNC(sc, ds, how) do { \
bus_dmamap_sync((sc)->sc_rxdma.dd_dmat, (sc)->sc_rxdma.dd_dmamap, how);\
} while (0)
/*
* BA stream state. One of these is setup for each stream
* allocated/created for use. We pre-allocate the h/w stream
* before sending ADDBA request then complete the setup when
* get ADDBA response (success). The completed state is setup
* to optimize the fast path in mwl_txstart--we precalculate
* the QoS control bits in the outbound frame and use those
* to identify which BA stream to use (assigning the h/w q to
* the TxPriority field of the descriptor).
*
* NB: Each station may have at most MWL_MAXBA streams at one time.
*/
struct mwl_bastate {
uint16_t qos; /* QoS ctl for BA stream */
uint8_t txq; /* h/w q for BA stream */
const MWL_HAL_BASTREAM *bastream; /* A-MPDU BA stream */
};
static __inline__ void
mwl_bastream_setup(struct mwl_bastate *bas, int ac, int txq)
{
bas->txq = txq;
bas->qos = htole16(WME_AC_TO_TID(ac) | IEEE80211_QOS_ACKPOLICY_BA);
}
static __inline__ void
mwl_bastream_free(struct mwl_bastate *bas)
{
bas->qos = 0;
bas->bastream = NULL;
/* NB: don't need to clear txq */
}
/*
* Check the QoS control bits from an outbound frame against the
* value calculated when a BA stream is setup (above). We need
* to match the TID and also the ACK policy so we only match AMPDU
* frames. The bits from the frame are assumed in network byte
* order, hence the potential byte swap.
*/
static __inline__ int
mwl_bastream_match(const struct mwl_bastate *bas, uint16_t qos)
{
return (qos & htole16(IEEE80211_QOS_TID|IEEE80211_QOS_ACKPOLICY)) ==
bas->qos;
}
/* driver-specific node state */
struct mwl_node {
struct ieee80211_node mn_node; /* base class */
struct mwl_ant_info mn_ai; /* antenna info */
uint32_t mn_avgrssi; /* average rssi over all rx frames */
uint16_t mn_staid; /* firmware station id */
struct mwl_bastate mn_ba[MWL_MAXBA];
struct mwl_hal_vap *mn_hvap; /* hal vap handle */
};
#define MWL_NODE(ni) ((struct mwl_node *)(ni))
#define MWL_NODE_CONST(ni) ((const struct mwl_node *)(ni))
/*
* Driver-specific vap state.
*/
struct mwl_vap {
struct ieee80211vap mv_vap; /* base class */
struct mwl_hal_vap *mv_hvap; /* hal vap handle */
struct mwl_hal_vap *mv_ap_hvap; /* ap hal vap handle for wds */
uint16_t mv_last_ps_sta; /* last count of ps sta's */
uint16_t mv_eapolformat; /* fixed tx rate for EAPOL */
int (*mv_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
int (*mv_set_tim)(struct ieee80211_node *, int);
};
#define MWL_VAP(vap) ((struct mwl_vap *)(vap))
#define MWL_VAP_CONST(vap) ((const struct mwl_vap *)(vap))
struct mwl_softc {
struct ifnet *sc_ifp; /* interface common */
struct mwl_stats sc_stats; /* interface statistics */
int sc_debug;
device_t sc_dev;
bus_dma_tag_t sc_dmat; /* bus DMA tag */
bus_space_handle_t sc_io0h; /* BAR 0 */
bus_space_tag_t sc_io0t;
bus_space_handle_t sc_io1h; /* BAR 1 */
bus_space_tag_t sc_io1t;
struct mtx sc_mtx; /* master lock (recursive) */
struct taskqueue *sc_tq; /* private task queue */
unsigned int sc_invalid : 1, /* disable hardware accesses */
sc_recvsetup:1, /* recv setup */
sc_csapending:1,/* 11h channel switch pending */
sc_radarena : 1,/* radar detection enabled */
sc_rxblocked: 1;/* rx waiting for dma buffers */
struct mwl_hal *sc_mh; /* h/w access layer */
struct mwl_hal_vap *sc_hvap; /* hal vap handle */
struct mwl_hal_hwspec sc_hwspecs; /* h/w capabilities */
uint32_t sc_fwrelease; /* release # of loaded f/w */
struct mwl_hal_txrxdma sc_hwdma; /* h/w dma setup */
uint32_t sc_imask; /* interrupt mask copy */
enum ieee80211_phymode sc_curmode;
u_int16_t sc_curaid; /* current association id */
u_int8_t sc_curbssid[IEEE80211_ADDR_LEN];
MWL_HAL_CHANNEL sc_curchan;
MWL_HAL_TXRATE_HANDLING sc_txratehandling;
u_int16_t sc_rxantenna; /* rx antenna */
u_int16_t sc_txantenna; /* tx antenna */
uint8_t sc_napvaps; /* # ap mode vaps */
uint8_t sc_nwdsvaps; /* # wds mode vaps */
uint8_t sc_nstavaps; /* # sta mode vaps */
uint8_t sc_nbssid0; /* # vap's using base mac */
uint32_t sc_bssidmask; /* bssid mask */
void (*sc_recv_mgmt)(struct ieee80211com *,
struct mbuf *,
struct ieee80211_node *,
int, int, int, u_int32_t);
int (*sc_newstate)(struct ieee80211com *,
enum ieee80211_state, int);
void (*sc_node_cleanup)(struct ieee80211_node *);
void (*sc_node_drain)(struct ieee80211_node *);
void (*sc_recv_action)(struct ieee80211_node *,
const uint8_t *, const uint8_t *);
int (*sc_addba_request)(struct ieee80211_node *,
struct ieee80211_tx_ampdu *,
int dialogtoken, int baparamset,
int batimeout);
int (*sc_addba_response)(struct ieee80211_node *,
struct ieee80211_tx_ampdu *,
int status, int baparamset,
int batimeout);
void (*sc_addba_stop)(struct ieee80211_node *,
struct ieee80211_tx_ampdu *);
struct mwl_descdma sc_rxdma; /* rx bus dma resources */
mwl_rxbufhead sc_rxbuf; /* rx buffers */
struct mwl_rxbuf *sc_rxnext; /* next rx buffer to process */
struct task sc_rxtask; /* rx int processing */
void *sc_rxmem; /* rx dma buffer pool */
bus_dma_tag_t sc_rxdmat; /* rx bus DMA tag */
bus_size_t sc_rxmemsize; /* rx dma buffer pool size */
bus_dmamap_t sc_rxmap; /* map for rx dma buffers */
bus_addr_t sc_rxmem_paddr; /* physical addr of sc_rxmem */
mwl_jumbohead sc_rxfree; /* list of free dma buffers */
int sc_nrxfree; /* # buffers on rx free list */
struct mtx sc_rxlock; /* lock on sc_rxfree */
struct mwl_txq sc_txq[MWL_NUM_TX_QUEUES];
struct mwl_txq *sc_ac2q[5]; /* WME AC -> h/w q map */
struct mbuf *sc_aggrq; /* aggregation q */
struct task sc_txtask; /* tx int processing */
struct task sc_bawatchdogtask;/* BA watchdog processing */
struct task sc_radartask; /* radar detect processing */
struct task sc_chanswitchtask;/* chan switch processing */
uint8_t sc_staid[MWL_MAXSTAID/NBBY];
int sc_ageinterval;
struct callout sc_timer; /* periodic work */
struct mwl_tx_radiotap_header sc_tx_th;
struct mwl_rx_radiotap_header sc_rx_th;
};
#define MWL_LOCK_INIT(_sc) \
mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
NULL, MTX_DEF | MTX_RECURSE)
#define MWL_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx)
#define MWL_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
#define MWL_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
#define MWL_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
#define MWL_RXFREE_INIT(_sc) \
mtx_init(&(_sc)->sc_rxlock, device_get_nameunit((_sc)->sc_dev), \
NULL, MTX_DEF)
#define MWL_RXFREE_DESTROY(_sc) mtx_destroy(&(_sc)->sc_rxlock)
#define MWL_RXFREE_LOCK(_sc) mtx_lock(&(_sc)->sc_rxlock)
#define MWL_RXFREE_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_rxlock)
#define MWL_RXFREE_ASSERT(_sc) mtx_assert(&(_sc)->sc_rxlock, MA_OWNED)
int mwl_attach(u_int16_t, struct mwl_softc *);
int mwl_detach(struct mwl_softc *);
void mwl_resume(struct mwl_softc *);
void mwl_suspend(struct mwl_softc *);
void mwl_shutdown(void *);
void mwl_intr(void *);
#endif /* _DEV_MWL_MVVAR_H */

108
sys/dev/mwl/mwldiag.h Normal file
View File

@ -0,0 +1,108 @@
/*-
* Copyright (c) 2007-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2007-2009 Marvell Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
* $FreeBSD$
*/
#ifndef _MWL_DIAG_H_
#define _MWL_DIAG_H_
/*
* Diagnostic interface. This is an open-ended interface that
* is opaque to applications. Diagnostic programs use this to
* retrieve internal data structures, etc. There is no guarantee
* that calling conventions for calls other than MWL_DIAG_REVS
* are stable between HAL releases; a diagnostic application must
* use the HAL revision information to deal with ABI/API differences.
*
* NB: do not renumber these, certain codes are publicly used.
*/
enum {
MWL_DIAG_CMD_REVS = 0, /* MAC/PHY/Radio revs */
MWL_DIAG_CMD_REGS = 1, /* Registers */
MWL_DIAG_CMD_HOSTCMD = 2, /* issue arbitrary cmd */
MWL_DIAG_CMD_FWLOAD = 3, /* load firmware */
};
/*
* Device revision information.
*/
typedef struct {
uint16_t mh_devid; /* PCI device ID */
uint16_t mh_subvendorid; /* PCI subvendor ID */
uint16_t mh_macRev; /* MAC revision */
uint16_t mh_phyRev; /* PHY revision */
} MWL_DIAG_REVS;
typedef struct {
uint16_t start; /* first register */
uint16_t end; /* ending register or zero */
} MWL_DIAG_REGRANGE;
/*
* Registers are mapped into virtual banks; the hal converts
* r/w operations through the diag api to host cmds as required.
*
* NB: register offsets are 16-bits and we need to avoid real
* register mappings in BAR1.
*/
#define MWL_DIAG_BASE_MAC 0xa000
#define MWL_DIAG_ISMAC(r) \
(MWL_DIAG_BASE_MAC <= (r) && (r) < (MWL_DIAG_BASE_MAC+0x1000))
#define MWL_DIAG_BASE_BB 0xe000
#define MWL_DIAG_ISBB(r) \
(MWL_DIAG_BASE_BB <= (r) && (r) < (MWL_DIAG_BASE_BB+0x1000))
#define MWL_DIAG_BASE_RF 0xf000
#define MWL_DIAG_ISRF(r) \
(MWL_DIAG_BASE_RF <= (r) && (r) < (MWL_DIAG_BASE_RF+0x1000))
/*
* Firmware download
*/
typedef struct {
uint32_t opmode; /* operating mode */
uint32_t signature; /* f/w ready signature */
char name[1]; /* variable length pathname */
} MWL_DIAG_FWLOAD;
struct mwl_diag {
char md_name[IFNAMSIZ]; /* if name, e.g. "mv0" */
uint16_t md_id;
#define MWL_DIAG_DYN 0x8000 /* allocate buffer in caller */
#define MWL_DIAG_IN 0x4000 /* copy in parameters */
#define MWL_DIAG_OUT 0x0000 /* copy out results (always) */
#define MWL_DIAG_ID 0x0fff
uint16_t md_in_size; /* pack to fit, yech */
void * md_in_data;
void * md_out_data;
u_int md_out_size;
};
#define SIOCGMVDIAG _IOWR('i', 138, struct mwl_diag)
#define SIOCGMVRESET _IOW('i', 139, struct mwl_diag)
#endif /* _MWL_DIAG_H_ */

2703
sys/dev/mwl/mwlhal.c Normal file

File diff suppressed because it is too large Load Diff

666
sys/dev/mwl/mwlhal.h Normal file
View File

@ -0,0 +1,666 @@
/*-
* Copyright (c) 2007-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2007-2009 Marvell Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
* $FreeBSD$
*/
#ifndef _MWL_HAL_H_
#define _MWL_HAL_H_
/*
* Hardware Access Layer for Marvell Wireless Devices.
*/
#define MWL_MBSS_SUPPORT /* enable multi-bss support */
/*
* Define total number of TX queues in the shared memory.
* This count includes the EDCA queues, Block Ack queues, and HCCA queues
* In addition to this, there could be a management packet queue some
* time in the future
*/
#define MWL_NUM_EDCA_QUEUES 4
#define MWL_NUM_HCCA_QUEUES 0
#define MWL_NUM_BA_QUEUES 0
#define MWL_NUM_MGMT_QUEUES 0
#define MWL_NUM_TX_QUEUES \
(MWL_NUM_EDCA_QUEUES + MWL_NUM_HCCA_QUEUES + MWL_NUM_BA_QUEUES + \
MWL_NUM_MGMT_QUEUES)
#define MWL_MAX_RXWCB_QUEUES 1
#define MWL_MAX_SUPPORTED_RATES 12
#define MWL_MAX_SUPPORTED_MCS 32
typedef enum {
MWL_HAL_OK
} MWL_HAL_STATUS;
/*
* Transmit queue assignment.
*/
enum {
MWL_WME_AC_BK = 0, /* background access category */
MWL_WME_AC_BE = 1, /* best effort access category*/
MWL_WME_AC_VI = 2, /* video access category */
MWL_WME_AC_VO = 3, /* voice access category */
};
struct device;
struct mwl_hal {
bus_space_handle_t mh_ioh; /* BAR 1 copied from softc */
bus_space_tag_t mh_iot;
uint32_t mh_imask; /* interrupt mask */
/* remainder is opaque to driver */
};
struct mwl_hal *mwl_hal_attach(struct device *dev, uint16_t devid,
bus_space_handle_t ioh, bus_space_tag_t iot, bus_dma_tag_t tag);
void mwl_hal_detach(struct mwl_hal *);
/*
* Query whether multi-bss support is available/enabled.
*/
int mwl_hal_ismbsscapable(struct mwl_hal *);
typedef enum {
MWL_HAL_AP,
MWL_HAL_STA, /* infrastructure mode */
MWL_HAL_IBSS /* ibss/adhoc mode */
} MWL_HAL_BSSTYPE;
struct mwl_hal_vap;
struct mwl_hal_vap *mwl_hal_newvap(struct mwl_hal *, MWL_HAL_BSSTYPE,
const uint8_t mac[6]);
void mwl_hal_delvap(struct mwl_hal_vap *);
enum {
MWL_HAL_DEBUG_SENDCMD = 0x00000001,
MWL_HAL_DEBUG_CMDDONE = 0x00000002,
MWL_HAL_DEBUG_IGNHANG = 0x00000004,
};
void mwl_hal_setdebug(struct mwl_hal *, int);
int mwl_hal_getdebug(struct mwl_hal *);
typedef struct {
uint16_t freqLow, freqHigh;
int nchannels;
struct mwl_hal_channel {
uint16_t freq; /* channel center */
uint8_t ieee; /* channel number */
int8_t maxTxPow; /* max tx power (dBm) */
uint8_t targetPowers[4];/* target powers (dBm) */
#define MWL_HAL_MAXCHAN 40
} channels[MWL_HAL_MAXCHAN];
} MWL_HAL_CHANNELINFO;
int mwl_hal_getchannelinfo(struct mwl_hal *, int band, int chw,
const MWL_HAL_CHANNELINFO **);
/*
* Return the current ISR setting and clear the cause.
*/
static __inline void
mwl_hal_getisr(struct mwl_hal *mh, uint32_t *status)
{
#define MACREG_REG_A2H_INTERRUPT_CAUSE 0x00000C30 // (From ARM to host)
#define MACREG_REG_INT_CODE 0x00000C14
uint32_t cause;
cause = bus_space_read_4(mh->mh_iot, mh->mh_ioh,
MACREG_REG_A2H_INTERRUPT_CAUSE);
if (cause == 0xffffffff) { /* card removed */
cause = 0;
} else if (cause != 0) {
/* clear cause bits */
bus_space_write_4(mh->mh_iot, mh->mh_ioh,
MACREG_REG_A2H_INTERRUPT_CAUSE, cause &~ mh->mh_imask);
(void) bus_space_read_4(mh->mh_iot, mh->mh_ioh,
MACREG_REG_INT_CODE);
cause &= mh->mh_imask;
}
*status = cause;
#undef MACREG_REG_INT_CODE
#undef MACREG_REG_A2H_INTERRUPT_CAUSE
}
void mwl_hal_intrset(struct mwl_hal *mh, uint32_t mask);
/*
* Kick the firmware to tell it there are new tx descriptors
* for processing. The driver says what h/w q has work in
* case the f/w ever gets smarter.
*/
static __inline void
mwl_hal_txstart(struct mwl_hal *mh, int qnum)
{
#define MACREG_REG_H2A_INTERRUPT_EVENTS 0x00000C18 // (From host to ARM)
#define MACREG_H2ARIC_BIT_PPA_READY 0x00000001 // bit 0
#define MACREG_REG_INT_CODE 0x00000C14
bus_space_write_4(mh->mh_iot, mh->mh_ioh,
MACREG_REG_H2A_INTERRUPT_EVENTS, MACREG_H2ARIC_BIT_PPA_READY);
(void) bus_space_read_4(mh->mh_iot, mh->mh_ioh, MACREG_REG_INT_CODE);
#undef MACREG_REG_INT_CODE
#undef MACREG_H2ARIC_BIT_PPA_READY
#undef MACREG_REG_H2A_INTERRUPT_EVENTS
}
void mwl_hal_cmddone(struct mwl_hal *mh);
typedef struct {
uint32_t FreqBand : 6,
#define MWL_FREQ_BAND_2DOT4GHZ 0x1
#define MWL_FREQ_BAND_5GHZ 0x4
ChnlWidth: 5,
#define MWL_CH_10_MHz_WIDTH 0x1
#define MWL_CH_20_MHz_WIDTH 0x2
#define MWL_CH_40_MHz_WIDTH 0x4
ExtChnlOffset: 2,
#define MWL_EXT_CH_NONE 0x0
#define MWL_EXT_CH_ABOVE_CTRL_CH 0x1
#define MWL_EXT_CH_BELOW_CTRL_CH 0x3
: 19; /* reserved */
} MWL_HAL_CHANNEL_FLAGS;
typedef struct {
uint32_t channel;
MWL_HAL_CHANNEL_FLAGS channelFlags;
} MWL_HAL_CHANNEL;
/*
* Get Hardware/Firmware capabilities.
*/
struct mwl_hal_hwspec {
uint8_t hwVersion; /* version of the HW */
uint8_t hostInterface; /* host interface */
uint16_t maxNumWCB; /* max # of WCB FW handles */
uint16_t maxNumMCAddr; /* max # of mcast addresses FW handles*/
uint16_t maxNumTxWcb; /* max # of tx descs per WCB */
uint8_t macAddr[6]; /* MAC address programmed in HW */
uint16_t regionCode; /* EEPROM region code */
uint16_t numAntennas; /* Number of antenna used */
uint32_t fwReleaseNumber; /* firmware release number */
uint32_t wcbBase0;
uint32_t rxDescRead;
uint32_t rxDescWrite;
uint32_t ulFwAwakeCookie;
uint32_t wcbBase[4];
};
int mwl_hal_gethwspecs(struct mwl_hal *mh, struct mwl_hal_hwspec *);
/*
* Supply tx/rx dma-related settings to the firmware.
*/
struct mwl_hal_txrxdma {
uint32_t maxNumWCB; /* max # of WCB FW handles */
uint32_t maxNumTxWcb; /* max # of tx descs per WCB */
uint32_t rxDescRead;
uint32_t rxDescWrite;
uint32_t wcbBase[4];
};
int mwl_hal_sethwdma(struct mwl_hal *mh, const struct mwl_hal_txrxdma *);
/*
* Get Hardware Statistics.
*
* Items marked with ! are deprecated and not ever updated. In
* some cases this is because work has been moved to the host (e.g.
* rx defragmentation).
*/
struct mwl_hal_hwstats {
uint32_t TxRetrySuccesses; /* tx success w/ 1 retry */
uint32_t TxMultipleRetrySuccesses;/* tx success w/ >1 retry */
uint32_t TxFailures; /* tx fail due to no ACK */
uint32_t RTSSuccesses; /* CTS rx'd for RTS */
uint32_t RTSFailures; /* CTS not rx'd for RTS */
uint32_t AckFailures; /* same as TxFailures */
uint32_t RxDuplicateFrames; /* rx discard for dup seqno */
uint32_t FCSErrorCount; /* rx discard for bad FCS */
uint32_t TxWatchDogTimeouts; /* MAC tx hang (f/w recovery) */
uint32_t RxOverflows; /* no f/w buffer for rx data */
uint32_t RxFragErrors; /* !rx fail due to defrag */
uint32_t RxMemErrors; /* out of mem or desc corrupted
in some way */
uint32_t RxPointerErrors; /* MAC internal ptr problem */
uint32_t TxUnderflows; /* !tx underflow on dma */
uint32_t TxDone; /* MAC tx ops completed
(possibly w/ error) */
uint32_t TxDoneBufTryPut; /* ! */
uint32_t TxDoneBufPut; /* same as TxDone */
uint32_t Wait4TxBuf; /* !no f/w buf avail when
supplied a tx descriptor */
uint32_t TxAttempts; /* tx descriptors processed */
uint32_t TxSuccesses; /* tx attempts successful */
uint32_t TxFragments; /* tx with fragmentation */
uint32_t TxMulticasts; /* tx multicast frames */
uint32_t RxNonCtlPkts; /* rx non-control frames */
uint32_t RxMulticasts; /* rx multicast frames */
uint32_t RxUndecryptableFrames; /* rx failed due to crypto */
uint32_t RxICVErrors; /* rx failed due to ICV check */
uint32_t RxExcludedFrames; /* rx discarded, e.g. bssid */
};
int mwl_hal_gethwstats(struct mwl_hal *mh, struct mwl_hal_hwstats *);
/*
* Set HT Guard Interval.
*
* GIType = 0: enable long and short GI
* GIType = 1: enable short GI
* GIType = 2: enable long GI
*/
int mwl_hal_sethtgi(struct mwl_hal_vap *, int GIType);
/*
* Set Radio Configuration.
*
* onoff != 0 turns radio on; otherwise off.
* if radio is enabled, the preamble is set too.
*/
typedef enum {
WL_LONG_PREAMBLE = 1,
WL_SHORT_PREAMBLE = 3,
WL_AUTO_PREAMBLE = 5,
} MWL_HAL_PREAMBLE;
int mwl_hal_setradio(struct mwl_hal *mh, int onoff, MWL_HAL_PREAMBLE preamble);
/*
* Set Antenna Configuration (legacy operation).
*
* The RX antenna can be selected using the the bitmask
* ant (bit 0 = antenna 1, bit 1 = antenna 2, etc.)
* (diversity?XXX)
*/
typedef enum {
WL_ANTENNATYPE_RX = 1,
WL_ANTENNATYPE_TX = 2,
} MWL_HAL_ANTENNA;
int mwl_hal_setantenna(struct mwl_hal *mh, MWL_HAL_ANTENNA dirSet, int ant);
/*
* Set the threshold for using RTS on TX.
*/
int mwl_hal_setrtsthreshold(struct mwl_hal_vap *, int threshold);
/*
* Set the adapter to operate in infrastructure mode.
*/
int mwl_hal_setinframode(struct mwl_hal_vap *);
/*
* Set Radar Detection Configuration.
*/
typedef enum {
DR_DFS_DISABLE = 0,
DR_CHK_CHANNEL_AVAILABLE_START = 1,
DR_CHK_CHANNEL_AVAILABLE_STOP = 2,
DR_IN_SERVICE_MONITOR_START = 3
} MWL_HAL_RADAR;
int mwl_hal_setradardetection(struct mwl_hal *mh, MWL_HAL_RADAR action);
/*
* Set the region code that selects the radar bin'ing agorithm.
*/
int mwl_hal_setregioncode(struct mwl_hal *mh, int regionCode);
/*
* Initiate an 802.11h-based channel switch. The CSA ie
* is included in the next beacon(s) using the specified
* information and the firmware counts down until switch
* time after which it notifies the driver by delivering
* an interrupt with MACREG_A2HRIC_BIT_CHAN_SWITCH set in
* the cause register.
*/
int mwl_hal_setchannelswitchie(struct mwl_hal *,
const MWL_HAL_CHANNEL *nextchan, uint32_t mode, uint32_t count);
/*
* Set regdomain code (IEEE SKU).
*/
enum {
DOMAIN_CODE_FCC = 0x10, /* USA */
DOMAIN_CODE_IC = 0x20, /* Canda */
DOMAIN_CODE_ETSI = 0x30, /* Europe */
DOMAIN_CODE_SPAIN = 0x31, /* Spain */
DOMAIN_CODE_FRANCE = 0x32, /* France */
DOMAIN_CODE_ETSI_131 = 0x130,/* ETSI w/ 1.3.1 radar type */
DOMAIN_CODE_MKK = 0x40, /* Japan */
DOMAIN_CODE_MKK2 = 0x41, /* Japan w/ 10MHz chan spacing */
DOMAIN_CODE_DGT = 0x80, /* Taiwan */
DOMAIN_CODE_AUS = 0x81, /* Australia */
};
/*
* Transmit rate control. Rate codes with bit 0x80 set are
* interpreted as MCS codes (this limits us to 0-127). The
* transmit rate can be set to a single fixed rate or can
* be configured to start at an initial rate and drop based
* on retry counts.
*/
typedef enum {
RATE_AUTO = 0, /* rate selected by firmware */
RATE_FIXED = 2, /* rate fixed */
RATE_FIXED_DROP = 1, /* rate starts fixed but may drop */
} MWL_HAL_TXRATE_HANDLING;
typedef struct {
uint8_t McastRate; /* rate for multicast frames */
#define RATE_MCS 0x80 /* rate is an MCS index */
uint8_t MgtRate; /* rate for management frames */
struct {
uint8_t TryCount; /* try this many times */
uint8_t Rate; /* use this tx rate */
} RateSeries[4]; /* rate series */
} MWL_HAL_TXRATE;
int mwl_hal_settxrate(struct mwl_hal_vap *,
MWL_HAL_TXRATE_HANDLING handling, const MWL_HAL_TXRATE *rate);
/* NB: hack for setting rates while scanning */
int mwl_hal_settxrate_auto(struct mwl_hal *, const MWL_HAL_TXRATE *rate);
/*
* Set the Slot Time Configuration.
* NB: usecs must either be 9 or 20 for now.
*/
int mwl_hal_setslottime(struct mwl_hal *mh, int usecs);
/*
* Adjust current transmit power settings according to powerLevel.
* This translates to low/medium/high use of the current tx power rate tables.
*/
int mwl_hal_adjusttxpower(struct mwl_hal *, uint32_t powerLevel);
/*
* Set the transmit power for the specified channel; the power
* is taken from the calibration data and capped according to
* the specified max tx power (in dBm).
*/
int mwl_hal_settxpower(struct mwl_hal *, const MWL_HAL_CHANNEL *,
uint8_t maxtxpow);
/*
* Set the Multicast Address Filter.
* A packed array addresses is specified.
*/
#define MWL_HAL_MCAST_MAX 32
int mwl_hal_setmcast(struct mwl_hal *mh, int nmc, const uint8_t macs[]);
/*
* Crypto Configuration.
*/
typedef struct {
uint16_t pad;
uint16_t keyTypeId;
#define KEY_TYPE_ID_WEP 0
#define KEY_TYPE_ID_TKIP 1
#define KEY_TYPE_ID_AES 2 /* AES-CCMP */
uint32_t keyFlags;
#define KEY_FLAG_INUSE 0x00000001 /* indicate key is in use */
#define KEY_FLAG_RXGROUPKEY 0x00000002 /* Group key for RX only */
#define KEY_FLAG_TXGROUPKEY 0x00000004 /* Group key for TX */
#define KEY_FLAG_PAIRWISE 0x00000008 /* pairwise */
#define KEY_FLAG_RXONLY 0x00000010 /* only used for RX */
#define KEY_FLAG_AUTHENTICATOR 0x00000020 /* Key is for Authenticator */
#define KEY_FLAG_TSC_VALID 0x00000040 /* Sequence counters valid */
#define KEY_FLAG_WEP_TXKEY 0x01000000 /* Tx key for WEP */
#define KEY_FLAG_MICKEY_VALID 0x02000000 /* Tx/Rx MIC keys are valid */
uint32_t keyIndex; /* for WEP only; actual key index */
uint16_t keyLen; /* key size in bytes */
union { /* key material, keyLen gives size */
uint8_t wep[16]; /* enough for 128 bits */
uint8_t aes[16];
struct {
/* NB: group or pairwise key is determined by keyFlags */
uint8_t keyMaterial[16];
uint8_t txMic[8];
uint8_t rxMic[8];
struct {
uint16_t low;
uint32_t high;
} rsc;
struct {
uint16_t low;
uint32_t high;
} tsc;
} __packed tkip;
}__packed key;
} __packed MWL_HAL_KEYVAL;
/*
* Plumb a unicast/group key. The mac address identifies
* the station, use the broadcast address for group keys.
*/
int mwl_hal_keyset(struct mwl_hal_vap *, const MWL_HAL_KEYVAL *kv,
const uint8_t mac[6]);
/*
* Plumb a unicast/group key. The mac address identifies
* the station, use the broadcast address for group keys.
*/
int mwl_hal_keyreset(struct mwl_hal_vap *, const MWL_HAL_KEYVAL *kv,
const uint8_t mac[6]);
/*
* Set the MAC address.
*/
int mwl_hal_setmac(struct mwl_hal_vap *, const uint8_t addr[6]);
/*
* Set the beacon frame contents. The firmware will modify the
* frame only to add CSA and WME ie's and to fill in dynamic fields
* such as the sequence #..
*/
int mwl_hal_setbeacon(struct mwl_hal_vap *, const void *, size_t);
/*
* Handle power save operation for AP operation when offloaded to
* the host (SET_HW_SPEC_HOST_POWERSAVE). mwl_hal_setbss_powersave
* informs the firmware whether 1+ associated stations are in power
* save mode (it will then buffer mcast traffic). mwl_hal_setsta_powersave
* specifies a change in power save state for an associated station.
*/
int mwl_hal_setpowersave_bss(struct mwl_hal_vap *, uint8_t nsta);
int mwl_hal_setpowersave_sta(struct mwl_hal_vap *, uint16_t aid, int ena);
/*
* Set Association Configuration for station operation.
*/
int mwl_hal_setassocid(struct mwl_hal_vap *, const uint8_t bssId[6],
uint16_t assocId);
/*
* Set the current channel.
*/
int mwl_hal_setchannel(struct mwl_hal *mh, const MWL_HAL_CHANNEL *c);
/*
* A-MPDU Block Ack (BA) stream support. There are several
* streams that the driver must multiplex. Once assigned
* to a station the driver queues frames to a corresponding
* transmit queue and the firmware handles all the work.
*
* XXX no way to find out how many streams are supported
*/
typedef struct {
void *data[2]; /* opaque data */
int txq;
} MWL_HAL_BASTREAM;
const MWL_HAL_BASTREAM *mwl_hal_bastream_alloc(struct mwl_hal *mh,
int ba_type, const uint8_t Macaddr[16], uint8_t Tid,
uint8_t ParamInfo, void *, void *);
const MWL_HAL_BASTREAM *mwl_hal_bastream_lookup(struct mwl_hal *mh, int s);
int mwl_hal_bastream_create(struct mwl_hal *mh, const MWL_HAL_BASTREAM *,
int BarThrs, int WindowSize, uint16_t seqno);
int mwl_hal_bastream_destroy(struct mwl_hal *mh, const MWL_HAL_BASTREAM *);
int mwl_hal_bastream_get_seqno(struct mwl_hal *mh, const MWL_HAL_BASTREAM *,
uint16_t *pseqno);
int mwl_hal_getwatchdogbitmap(struct mwl_hal *mh, uint8_t bitmap[1]);
/* for sysctl hookup for debugging */
void mwl_hal_setbastreams(struct mwl_hal *mh, int mask);
int mwl_hal_getbastreams(struct mwl_hal *mh);
/*
* Inform the firmware of a new association station.
* The address is the MAC address of the peer station.
* The AID is supplied sans the 0xc000 bits. The station
* ID is defined by the caller. The peer information must
* be supplied.
*
* NB: All values are in host byte order; any byte swapping
* is handled by the hal.
*/
typedef struct {
uint32_t LegacyRateBitMap;
uint32_t HTRateBitMap;
uint16_t CapInfo;
uint16_t HTCapabilitiesInfo;
uint8_t MacHTParamInfo;
uint8_t Rev;
struct {
uint8_t ControlChan;
uint8_t AddChan;
uint8_t OpMode;
uint8_t stbc;
} __packed AddHtInfo;
} __packed MWL_HAL_PEERINFO;
int mwl_hal_newstation(struct mwl_hal_vap *, const uint8_t addr[6],
uint16_t aid, uint16_t sid, const MWL_HAL_PEERINFO *,
int isQosSta, int wmeInfo);
int mwl_hal_delstation(struct mwl_hal_vap *, const uint8_t addr[6]);
/*
* Prod the firmware to age packets on station power
* save queues and reap frames on the tx aggregation q's.
*/
int mwl_hal_setkeepalive(struct mwl_hal *mh);
typedef enum {
AP_MODE_B_ONLY = 1,
AP_MODE_G_ONLY = 2,
AP_MODE_MIXED = 3,
AP_MODE_N_ONLY = 4,
AP_MODE_BandN = 5,
AP_MODE_GandN = 6,
AP_MODE_BandGandN = 7,
AP_MODE_A_ONLY = 8,
AP_MODE_AandG = 10,
AP_MODE_AandN = 12,
} MWL_HAL_APMODE;
int mwl_hal_setapmode(struct mwl_hal_vap *, MWL_HAL_APMODE);
/*
* Enable/disable firmware operation. mwl_hal_start is
* also used to sync state updates, e.g. beacon frame
* reconstruction after content changes.
*/
int mwl_hal_stop(struct mwl_hal_vap *);
int mwl_hal_start(struct mwl_hal_vap *);
/*
* Enable/disable 11g protection use. This call specifies
* the ERP information element flags to use.
*/
int mwl_hal_setgprot(struct mwl_hal *, int);
/*
* Enable/disable WMM support.
*/
int mwl_hal_setwmm(struct mwl_hal *mh, int onoff);
/*
* Configure WMM EDCA parameters for the specified h/w ring.
*/
int mwl_hal_setedcaparams(struct mwl_hal *mh, uint8_t qnum,
uint32_t CWmin, uint32_t CWmax, uint8_t AIFSN, uint16_t TXOPLimit);
/*
* Configure rate adaptation for indooor/outdoor operation.
* XXX wtf?
*/
int mwl_hal_setrateadaptmode(struct mwl_hal *mh, uint16_t mode);
typedef enum {
CSMODE_CONSERVATIVE = 0,
CSMODE_AGGRESSIVE = 1,
CSMODE_AUTO_ENA = 2,
CSMODE_AUTO_DIS = 3,
} MWL_HAL_CSMODE;
int mwl_hal_setcsmode(struct mwl_hal *mh, MWL_HAL_CSMODE csmode);
/*
* Configure 11n protection on/off.
*/
typedef enum {
HTPROTECT_NONE = 0, /* disable */
HTPROTECT_OPT = 1, /* optional */
HTPROTECT_HT20 = 2, /* protect only HT20 */
HTPROTECT_HT2040 = 3, /* protect HT20/40 */
HTPROTECT_AUTO = 4, /* automatic */
} MWL_HAL_HTPROTECT;
int mwl_hal_setnprot(struct mwl_hal_vap *, MWL_HAL_HTPROTECT mode);
/*
* Configure 11n protection mechanism for when protection is enabled.
*/
int mwl_hal_setnprotmode(struct mwl_hal_vap *, uint8_t mode);
/*
* Enable/disable Marvell "turbo mode"".
*/
int mwl_hal_setoptimizationlevel(struct mwl_hal *mh, int onoff);
/*
* Set MIMO Power Save handling for a station; the enable and mode
* values come directly from the Action frame.
*/
int mwl_hal_setmimops(struct mwl_hal *mh, const uint8_t addr[6],
uint8_t enable, uint8_t mode);
/*
* Retrieve the region/country code from the EEPROM.
*/
int mwl_hal_getregioncode(struct mwl_hal *mh, uint8_t *countryCode);
int mwl_hal_GetBeacon(struct mwl_hal *mh, uint8_t *pBcn, uint16_t *pLen);
int mwl_hal_SetRifs(struct mwl_hal *mh, uint8_t QNum);
/*
* Set/get promiscuous mode.
*/
int mwl_hal_setpromisc(struct mwl_hal *, int ena);
int mwl_hal_getpromisc(struct mwl_hal *);
/*
* Diagnostic interface. This is an open-ended interface that
* is opaque to applications. Diagnostic programs use this to
* retrieve internal data structures, etc. There is no guarantee
* that calling conventions for calls other than MWL_DIAG_REVS
* are stable between HAL releases; a diagnostic application must
* use the HAL revision information to deal with ABI/API differences.
*/
int mwl_hal_getdiagstate(struct mwl_hal *mh, int request,
const void *args, uint32_t argsize,
void **result, uint32_t *resultsize);
int mwl_hal_fwload(struct mwl_hal *mh, void *fwargs);
#endif /* _MWL_HAL_H_ */

1352
sys/dev/mwl/mwlreg.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -178,6 +178,7 @@ SUBDIR= ${_3dfx} \
msdosfs_iconv \
${_mse} \
msk \
mwl \
mxge \
my \
${_ncp} \

41
sys/modules/mwl/Makefile Normal file
View File

@ -0,0 +1,41 @@
#
# Copyright (c) 2007-2009 Sam Leffler, Errno Consulting
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer,
# without modification.
# 2. Redistributions in binary form must reproduce at minimum a disclaimer
# similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
# redistribution must be conditioned upon including a substantially
# similar Disclaimer requirement for further binary redistribution.
#
# NO WARRANTY
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGES.
#
# $FreeBSD$
#
.PATH: ${.CURDIR}/../../dev/mwl
KMOD= if_mwl
SRCS= if_mwl.c if_mwl_pci.c mwlhal.c
SRCS+= device_if.h bus_if.h pci_if.h opt_inet.h opt_mwl.h
opt_mwl.h:
echo '#define MWL_DEBUG 1'> $@
.include <bsd.kmod.mk>

View File

@ -0,0 +1,14 @@
# $FreeBSD$
KMOD= mw88W8363fw
FIRMWS= mw88W8363.fw:mw88W8363fw mwlboot.fw:mwlboot
CLEANFILES+= mw88W8363.fw mwlboot.fw
mw88W8363.fw: ${.CURDIR}/../../contrib/dev/mwl/mw88W8363.fw.uu
uudecode -p $? > ${.TARGET}
mwlboot.fw: ${.CURDIR}/../../contrib/dev/mwl/mwlboot.fw.uu
uudecode -p $? > ${.TARGET}
.include <bsd.kmod.mk>