blob: 21f0e2a59059fe7f009a45e4c66339410da583a7 [file] [log] [blame]
/* Crossdriver (bcmdhd/brcmfmac) symbols extracted from bcmdhd bcmwifi_channels.h.
*
* Copyright 1999-2016, Broadcom Corporation
* 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.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* This software is provided by the copyright holder "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 copyright holder 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 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 damage
*/
#ifndef THIRD_PARTY_BCMDHD_CROSSDRIVER_BCMWIFI_CHANNELS_H_
#define THIRD_PARTY_BCMDHD_CROSSDRIVER_BCMWIFI_CHANNELS_H_
#include <stdint.h>
#include <zircon/status.h>
/* A chanspec holds the channel number, band, bandwidth and control sideband */
using chanspec_t = uint16_t;
/* channel defines */
#define CH_UPPER_SB 0x01
#define CH_LOWER_SB 0x02
#define CH_EWA_VALID 0x04
#define CH_80MHZ_APART 16
#define CH_40MHZ_APART 8
#define CH_20MHZ_APART 4
#define CH_10MHZ_APART 2
#define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */
#define CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */
/*
* max # supported channels. The max channel no is 216, this is that + 1
* rounded up to a multiple of NBBY (8). DO NOT MAKE it > 255: channels are
* uint8_t's all over
*/
#define MAXCHANNEL 224
#define MAXCHANNEL_NUM (MAXCHANNEL - 1) /* max channel number */
#define WL_CHANSPEC_CHAN_MASK 0x00ff
#define WL_CHANSPEC_CHAN_SHIFT 0
#define WL_CHANSPEC_CHAN1_MASK 0x000f
#define WL_CHANSPEC_CHAN1_SHIFT 0
#define WL_CHANSPEC_CHAN2_MASK 0x00f0
#define WL_CHANSPEC_CHAN2_SHIFT 4
#define WL_CHANSPEC_CTL_SB_MASK 0x0700
#define WL_CHANSPEC_CTL_SB_SHIFT 8
#define WL_CHANSPEC_CTL_SB_LLL 0x0000
#define WL_CHANSPEC_CTL_SB_LLU 0x0100
#define WL_CHANSPEC_CTL_SB_LUL 0x0200
#define WL_CHANSPEC_CTL_SB_LUU 0x0300
#define WL_CHANSPEC_CTL_SB_ULL 0x0400
#define WL_CHANSPEC_CTL_SB_ULU 0x0500
#define WL_CHANSPEC_CTL_SB_UUL 0x0600
#define WL_CHANSPEC_CTL_SB_UUU 0x0700
#define WL_CHANSPEC_CTL_SB_LL WL_CHANSPEC_CTL_SB_LLL
#define WL_CHANSPEC_CTL_SB_LU WL_CHANSPEC_CTL_SB_LLU
#define WL_CHANSPEC_CTL_SB_UL WL_CHANSPEC_CTL_SB_LUL
#define WL_CHANSPEC_CTL_SB_UU WL_CHANSPEC_CTL_SB_LUU
#define WL_CHANSPEC_CTL_SB_L WL_CHANSPEC_CTL_SB_LLL
#define WL_CHANSPEC_CTL_SB_U WL_CHANSPEC_CTL_SB_LLU
#define WL_CHANSPEC_CTL_SB_LOWER WL_CHANSPEC_CTL_SB_LLL
#define WL_CHANSPEC_CTL_SB_UPPER WL_CHANSPEC_CTL_SB_LLU
#define WL_CHANSPEC_CTL_SB_NONE WL_CHANSPEC_CTL_SB_LLL
#define WL_CHANSPEC_BW_MASK 0x3800
#define WL_CHANSPEC_BW_SHIFT 11
#define WL_CHANSPEC_BW_5 0x0000
#define WL_CHANSPEC_BW_10 0x0800
#define WL_CHANSPEC_BW_20 0x1000
#define WL_CHANSPEC_BW_40 0x1800
#define WL_CHANSPEC_BW_80 0x2000
#define WL_CHANSPEC_BW_160 0x2800
#define WL_CHANSPEC_BW_8080 0x3000
#define WL_CHANSPEC_BW_2P5 0x3800
#define WL_CHANSPEC_BAND_MASK 0xc000
#define WL_CHANSPEC_BAND_SHIFT 14
#define WL_CHANSPEC_BAND_2G 0x0000
#define WL_CHANSPEC_BAND_3G 0x4000
#define WL_CHANSPEC_BAND_4G 0x8000
#define WL_CHANSPEC_BAND_5G 0xc000
#define INVCHANSPEC 255
#define MAX_CHANSPEC 0xFFFF
/* channel defines */
#define LOWER_20_SB(channel) (((channel) > CH_10MHZ_APART) ? ((channel)-CH_10MHZ_APART) : 0)
#define UPPER_20_SB(channel) \
(((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? ((channel) + CH_10MHZ_APART) : 0)
#define LL_20_SB(channel) (((channel) > 3 * CH_10MHZ_APART) ? ((channel)-3 * CH_10MHZ_APART) : 0)
#define UU_20_SB(channel) \
(((channel) < (MAXCHANNEL - 3 * CH_10MHZ_APART)) ? ((channel) + 3 * CH_10MHZ_APART) : 0)
#define LU_20_SB(channel) LOWER_20_SB(channel)
#define UL_20_SB(channel) UPPER_20_SB(channel)
#define LOWER_40_SB(channel) ((channel)-CH_20MHZ_APART)
#define UPPER_40_SB(channel) ((channel) + CH_20MHZ_APART)
#define CHSPEC_WLCBANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX)
#define CH20MHZ_CHSPEC(channel) \
(chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \
(((channel) <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G))
#define CH2P5MHZ_CHSPEC(channel) \
(chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_2P5 | \
(((channel) <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G))
#define CH5MHZ_CHSPEC(channel) \
(chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_5 | \
(((channel) <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G))
#define CH10MHZ_CHSPEC(channel) \
(chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_10 | \
(((channel) <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G))
#define NEXT_20MHZ_CHAN(channel) \
(((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? ((channel) + CH_20MHZ_APART) : 0)
#define CH40MHZ_CHSPEC(channel, ctlsb) \
(chanspec_t)((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \
((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G))
#define CH80MHZ_CHSPEC(channel, ctlsb) \
(chanspec_t)((channel) | (ctlsb) | WL_CHANSPEC_BW_80 | WL_CHANSPEC_BAND_5G)
#define CH160MHZ_CHSPEC(channel, ctlsb) \
(chanspec_t)((channel) | (ctlsb) | WL_CHANSPEC_BW_160 | WL_CHANSPEC_BAND_5G)
#define CHBW_CHSPEC(bw, channel) \
(chanspec_t)((chanspec_t)(channel) | (bw) | \
(((channel) <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G))
/* simple MACROs to get different fields of chanspec */
// TODO(karlward) What about WL11AC_80P80 version of CHSPEC_CHANNEL?
#define CHSPEC_CHANNEL(chspec) ((uint8_t)((chspec)&WL_CHANSPEC_CHAN_MASK))
#define CHSPEC_CHAN1(chspec) ((chspec)&WL_CHANSPEC_CHAN1_MASK) >> WL_CHANSPEC_CHAN1_SHIFT
#define CHSPEC_CHAN2(chspec) ((chspec)&WL_CHANSPEC_CHAN2_MASK) >> WL_CHANSPEC_CHAN2_SHIFT
#define CHSPEC_BAND(chspec) ((chspec)&WL_CHANSPEC_BAND_MASK)
#define CHSPEC_CTL_SB(chspec) ((chspec)&WL_CHANSPEC_CTL_SB_MASK)
#define CHSPEC_BW(chspec) ((chspec)&WL_CHANSPEC_BW_MASK)
// TODO(karlward) What about WL11N_20MHZONLY version of these?
#define CHSPEC_IS2P5(chspec) (((chspec)&WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_2P5)
#define CHSPEC_IS5(chspec) (((chspec)&WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_5)
#define CHSPEC_IS10(chspec) (((chspec)&WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10)
#define CHSPEC_IS20(chspec) (((chspec)&WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20)
#define CHSPEC_IS40(chspec) (((chspec)&WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)
#define CHSPEC_IS80(chspec) (((chspec)&WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_80)
#define CHSPEC_IS160(chspec) (((chspec)&WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_160)
#define CHSPEC_IS8080(chspec) (((chspec)&WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_8080)
// TODO(karlward) What about WL11N_20MHZONLY and WL11ULB versions of this?
/* This MACRO is strictly to avoid abandons in existing code with ULB feature and is in no way
* optimial to use. Should be replaced with CHSPEC_BW_LE() instead
*/
#define BW_LE20(bw) \
(((bw) == WL_CHANSPEC_BW_2P5) || ((bw) == WL_CHANSPEC_BW_5) || ((bw) == WL_CHANSPEC_BW_10) || \
((bw) == WL_CHANSPEC_BW_20))
#define BW_LE40(bw) (BW_LE20(bw) || ((bw) == WL_CHANSPEC_BW_40))
#define BW_LE80(bw) (BW_LE40(bw) || ((bw) == WL_CHANSPEC_BW_80))
#define BW_LE160(bw) (BW_LE80(bw) || ((bw) == WL_CHANSPEC_BW_160))
#define CHSPEC_BW_LE20(chspec) (BW_LE20(CHSPEC_BW(chspec)))
#define CHSPEC_IS5G(chspec) (((chspec)&WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G)
#define CHSPEC_IS2G(chspec) (((chspec)&WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G)
#define CHSPEC_SB_UPPER(chspec) \
((((chspec)&WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER) && \
(((chspec)&WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40))
#define CHSPEC_SB_LOWER(chspec) \
((((chspec)&WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER) && \
(((chspec)&WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40))
/* Legacy Chanspec defines
* These are the defines for the previous format of the chanspec_t
*/
#define WL_LCHANSPEC_CHAN_MASK 0x00ff
#define WL_LCHANSPEC_CHAN_SHIFT 0
#define WL_LCHANSPEC_CTL_SB_MASK 0x0300
#define WL_LCHANSPEC_CTL_SB_SHIFT 8
#define WL_LCHANSPEC_CTL_SB_LOWER 0x0100
#define WL_LCHANSPEC_CTL_SB_UPPER 0x0200
#define WL_LCHANSPEC_CTL_SB_NONE 0x0300
#define WL_LCHANSPEC_BW_MASK 0x0C00
#define WL_LCHANSPEC_BW_SHIFT 10
#define WL_LCHANSPEC_BW_10 0x0400
#define WL_LCHANSPEC_BW_20 0x0800
#define WL_LCHANSPEC_BW_40 0x0C00
#define WL_LCHANSPEC_BAND_MASK 0xf000
#define WL_LCHANSPEC_BAND_SHIFT 12
#define WL_LCHANSPEC_BAND_5G 0x1000
#define WL_LCHANSPEC_BAND_2G 0x2000
#define LCHSPEC_CHANNEL(chspec) ((uint8_t)((chspec)&WL_LCHANSPEC_CHAN_MASK))
#define LCHSPEC_BAND(chspec) ((chspec)&WL_LCHANSPEC_BAND_MASK)
#define LCHSPEC_CTL_SB(chspec) ((chspec)&WL_LCHANSPEC_CTL_SB_MASK)
#define LCHSPEC_BW(chspec) ((chspec)&WL_LCHANSPEC_BW_MASK)
#define LCHSPEC_IS10(chspec) (((chspec)&WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_10)
#define LCHSPEC_IS20(chspec) (((chspec)&WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_20)
#define LCHSPEC_IS40(chspec) (((chspec)&WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40)
#define LCHSPEC_IS5G(chspec) (((chspec)&WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_5G)
#define LCHSPEC_IS2G(chspec) (((chspec)&WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_2G)
#define LCHSPEC_SB_UPPER(chspec) \
((((chspec)&WL_LCHANSPEC_CTL_SB_MASK) == WL_LCHANSPEC_CTL_SB_UPPER) && \
(((chspec)&WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40))
#define LCHSPEC_SB_LOWER(chspec) \
((((chspec)&WL_LCHANSPEC_CTL_SB_MASK) == WL_LCHANSPEC_CTL_SB_LOWER) && \
(((chspec)&WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40))
#define LCHSPEC_CREATE(chan, band, bw, sb) ((uint16_t)((chan) | (sb) | (bw) | (band)))
#define CH20MHZ_LCHSPEC(channel) \
(chanspec_t)((chanspec_t)(channel) | WL_LCHANSPEC_BW_20 | WL_LCHANSPEC_CTL_SB_NONE | \
(((channel) <= CH_MAX_2G_CHANNEL) ? WL_LCHANSPEC_BAND_2G : WL_LCHANSPEC_BAND_5G))
/* 80MHz channels in 5GHz band */
static const uint8_t wf_5g_80m_chans[] = {42, 58, 106, 122, 138, 155};
#define WF_NUM_5G_80M_CHANS (sizeof(wf_5g_80m_chans) / sizeof(uint8_t))
/*
* Verify the chanspec is using a legal set of parameters, i.e. that the
* chanspec specified a band, bw, ctl_sb and channel and that the
* combination could be legal given any set of circumstances.
* Returns true if chanspec is malformed, false if it looks good.
*
* Ported from wf_chspec_malformed.
*/
bool chspec_malformed(chanspec_t chanspec);
// This function returns the channel number that control traffic is being sent on, for 20MHz
// channels this is just the channel number, for 40MHZ, 80MHz, 160MHz channels it is the 20MHZ
// sideband depending on the chanspec selected. Ported from wf_chspec_ctlchan().
zx_status_t chspec_ctlchan(chanspec_t chspec, uint8_t* ctrl_chan);
#endif // THIRD_PARTY_BCMDHD_CROSSDRIVER_BCMWIFI_CHANNELS_H_