#ifndef _MWL_HAL_H_
#define _MWL_HAL_H_
#define MWL_MBSS_SUPPORT
#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_ACK_QUEUES 0
#define MWL_NUM_TX_QUEUES \
(MWL_NUM_EDCA_QUEUES + MWL_NUM_HCCA_QUEUES + MWL_NUM_BA_QUEUES + \
MWL_NUM_MGMT_QUEUES + MWL_NUM_ACK_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;
enum {
MWL_WME_AC_BK = 0,
MWL_WME_AC_BE = 1,
MWL_WME_AC_VI = 2,
MWL_WME_AC_VO = 3,
};
struct mwl_hal {
bus_space_handle_t mh_ioh;
bus_space_tag_t mh_iot;
uint32_t mh_imask;
};
struct mwl_hal *mwl_hal_attach(device_t 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 *);
int mwl_hal_ismbsscapable(struct mwl_hal *);
typedef enum {
MWL_HAL_AP,
MWL_HAL_STA,
MWL_HAL_IBSS
} 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;
uint8_t ieee;
int8_t maxTxPow;
uint8_t targetPowers[4];
#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 **);
static __inline void
mwl_hal_getisr(struct mwl_hal *mh, uint32_t *status)
{
#define MACREG_REG_A2H_INTERRUPT_CAUSE 0x00000C30
#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) {
cause = 0;
} else if (cause != 0) {
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);
static __inline void
mwl_hal_txstart(struct mwl_hal *mh, int qnum)
{
#define MACREG_REG_H2A_INTERRUPT_EVENTS 0x00000C18
#define MACREG_H2ARIC_BIT_PPA_READY 0x00000001
#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;
} MWL_HAL_CHANNEL_FLAGS;
typedef struct {
uint32_t channel;
MWL_HAL_CHANNEL_FLAGS channelFlags;
} MWL_HAL_CHANNEL;
struct mwl_hal_hwspec {
uint8_t hwVersion;
uint8_t hostInterface;
uint16_t maxNumWCB;
uint16_t maxNumMCAddr;
uint16_t maxNumTxWcb;
uint8_t macAddr[6];
uint16_t regionCode;
uint16_t numAntennas;
uint32_t fwReleaseNumber;
uint32_t wcbBase0;
uint32_t rxDescRead;
uint32_t rxDescWrite;
uint32_t ulFwAwakeCookie;
uint32_t wcbBase[MWL_NUM_TX_QUEUES - MWL_NUM_ACK_QUEUES];
};
int mwl_hal_gethwspecs(struct mwl_hal *mh, struct mwl_hal_hwspec *);
struct mwl_hal_txrxdma {
uint32_t maxNumWCB;
uint32_t maxNumTxWcb;
uint32_t rxDescRead;
uint32_t rxDescWrite;
uint32_t wcbBase[MWL_NUM_TX_QUEUES - MWL_NUM_ACK_QUEUES];
};
int mwl_hal_sethwdma(struct mwl_hal *mh, const struct mwl_hal_txrxdma *);
struct mwl_hal_hwstats {
uint32_t TxRetrySuccesses;
uint32_t TxMultipleRetrySuccesses;
uint32_t TxFailures;
uint32_t RTSSuccesses;
uint32_t RTSFailures;
uint32_t AckFailures;
uint32_t RxDuplicateFrames;
uint32_t FCSErrorCount;
uint32_t TxWatchDogTimeouts;
uint32_t RxOverflows;
uint32_t RxFragErrors;
uint32_t RxMemErrors;
uint32_t RxPointerErrors;
uint32_t TxUnderflows;
uint32_t TxDone;
uint32_t TxDoneBufTryPut;
uint32_t TxDoneBufPut;
uint32_t Wait4TxBuf;
uint32_t TxAttempts;
uint32_t TxSuccesses;
uint32_t TxFragments;
uint32_t TxMulticasts;
uint32_t RxNonCtlPkts;
uint32_t RxMulticasts;
uint32_t RxUndecryptableFrames;
uint32_t RxICVErrors;
uint32_t RxExcludedFrames;
};
int mwl_hal_gethwstats(struct mwl_hal *mh, struct mwl_hal_hwstats *);
int mwl_hal_sethtgi(struct mwl_hal_vap *, int GIType);
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);
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);
int mwl_hal_setrtsthreshold(struct mwl_hal_vap *, int threshold);
int mwl_hal_setinframode(struct mwl_hal_vap *);
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);
int mwl_hal_setregioncode(struct mwl_hal *mh, int regionCode);
int mwl_hal_setchannelswitchie(struct mwl_hal *,
const MWL_HAL_CHANNEL *nextchan, uint32_t mode, uint32_t count);
enum {
DOMAIN_CODE_FCC = 0x10,
DOMAIN_CODE_IC = 0x20,
DOMAIN_CODE_ETSI = 0x30,
DOMAIN_CODE_SPAIN = 0x31,
DOMAIN_CODE_FRANCE = 0x32,
DOMAIN_CODE_ETSI_131 = 0x130,
DOMAIN_CODE_MKK = 0x40,
DOMAIN_CODE_MKK2 = 0x41,
DOMAIN_CODE_DGT = 0x80,
DOMAIN_CODE_AUS = 0x81,
};
typedef enum {
RATE_AUTO = 0,
RATE_FIXED = 2,
RATE_FIXED_DROP = 1,
} MWL_HAL_TXRATE_HANDLING;
typedef struct {
uint8_t McastRate;
#define RATE_MCS 0x80
uint8_t MgtRate;
struct {
uint8_t TryCount;
uint8_t Rate;
} RateSeries[4];
} MWL_HAL_TXRATE;
int mwl_hal_settxrate(struct mwl_hal_vap *,
MWL_HAL_TXRATE_HANDLING handling, const MWL_HAL_TXRATE *rate);
int mwl_hal_settxrate_auto(struct mwl_hal *, const MWL_HAL_TXRATE *rate);
int mwl_hal_setslottime(struct mwl_hal *mh, int usecs);
int mwl_hal_adjusttxpower(struct mwl_hal *, uint32_t powerLevel);
int mwl_hal_settxpower(struct mwl_hal *, const MWL_HAL_CHANNEL *,
uint8_t maxtxpow);
#define MWL_HAL_MCAST_MAX 32
int mwl_hal_setmcast(struct mwl_hal *mh, int nmc, const uint8_t macs[]);
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
uint32_t keyFlags;
#define KEY_FLAG_INUSE 0x00000001
#define KEY_FLAG_RXGROUPKEY 0x00000002
#define KEY_FLAG_TXGROUPKEY 0x00000004
#define KEY_FLAG_PAIRWISE 0x00000008
#define KEY_FLAG_RXONLY 0x00000010
#define KEY_FLAG_AUTHENTICATOR 0x00000020
#define KEY_FLAG_TSC_VALID 0x00000040
#define KEY_FLAG_WEP_TXKEY 0x01000000
#define KEY_FLAG_MICKEY_VALID 0x02000000
uint32_t keyIndex;
uint16_t keyLen;
union {
uint8_t wep[16];
uint8_t aes[16];
struct {
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;
int mwl_hal_keyset(struct mwl_hal_vap *, const MWL_HAL_KEYVAL *kv,
const uint8_t mac[6]);
int mwl_hal_keyreset(struct mwl_hal_vap *, const MWL_HAL_KEYVAL *kv,
const uint8_t mac[6]);
int mwl_hal_setmac(struct mwl_hal_vap *, const uint8_t addr[6]);
int mwl_hal_setbeacon(struct mwl_hal_vap *, const void *, size_t);
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);
int mwl_hal_setassocid(struct mwl_hal_vap *, const uint8_t bssId[6],
uint16_t assocId);
int mwl_hal_setchannel(struct mwl_hal *mh, const MWL_HAL_CHANNEL *c);
typedef struct {
void *data[2];
int txq;
} MWL_HAL_BASTREAM;
const MWL_HAL_BASTREAM *mwl_hal_bastream_alloc(struct mwl_hal_vap *,
int ba_type, const uint8_t Macaddr[6], 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_vap *, 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_getwatchdogbitmap(struct mwl_hal *mh, uint8_t bitmap[1]);
int mwl_hal_bastream_get_seqno(struct mwl_hal *mh, const MWL_HAL_BASTREAM *,
const uint8_t Macaddr[6], uint16_t *pseqno);
void mwl_hal_setbastreams(struct mwl_hal *mh, int mask);
int mwl_hal_getbastreams(struct mwl_hal *mh);
int mwl_hal_setaggampduratemode(struct mwl_hal *, int mode, int thresh);
int mwl_hal_getaggampduratemode(struct mwl_hal *, int *mode, int *thresh);
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]);
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);
int mwl_hal_stop(struct mwl_hal_vap *);
int mwl_hal_start(struct mwl_hal_vap *);
int mwl_hal_updatetim(struct mwl_hal_vap *, uint16_t aid, int set);
int mwl_hal_setgprot(struct mwl_hal *, int);
int mwl_hal_setwmm(struct mwl_hal *mh, int onoff);
int mwl_hal_setedcaparams(struct mwl_hal *mh, uint8_t qnum,
uint32_t CWmin, uint32_t CWmax, uint8_t AIFSN, uint16_t TXOPLimit);
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);
typedef enum {
HTPROTECT_NONE = 0,
HTPROTECT_OPT = 1,
HTPROTECT_HT20 = 2,
HTPROTECT_HT2040 = 3,
HTPROTECT_AUTO = 4,
} MWL_HAL_HTPROTECT;
int mwl_hal_setnprot(struct mwl_hal_vap *, MWL_HAL_HTPROTECT mode);
int mwl_hal_setnprotmode(struct mwl_hal_vap *, uint8_t mode);
int mwl_hal_setoptimizationlevel(struct mwl_hal *mh, int onoff);
int mwl_hal_setmimops(struct mwl_hal *mh, const uint8_t addr[6],
uint8_t enable, uint8_t mode);
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);
int mwl_hal_setpromisc(struct mwl_hal *, int ena);
int mwl_hal_getpromisc(struct mwl_hal *);
int mwl_hal_setcfend(struct mwl_hal *, int ena);
int mwl_hal_setdwds(struct mwl_hal *, int ena);
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