1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-10-19 02:29:40 +00:00

[bwn] add new types, prepare for PHY-N; prepare for rev 5xx firmware.

This is a big commit with a whole lot of little changes, all in
preparation for PHY-N and rev 5xx firmware.

* add in a write method that does an explicit flush
* change the txpwr recalc type to return an enum, versus just an int.
* add in PHY-N RX frame format bits, for decoding RX RSSI and such
* add in the header space calculation for rev 5xx firmware.
* add in a whole bunch of new types that the newer and 5g phy code
  needs.  Notably, broadcom has a split 5GHz band concept -
  5G-Low, 5G(-Mid) and 5G-High.  I kept encountering this at my
  day job and wondered whether it was just some marketing thing.
  Nope, turns out it isn't; it's an actual PHY thing.

* Add a "am I a siba bus device" method, that returns true.
  The aim is to convert all the siba/bhnd specific bits in if_bwn
  over to be wrapped in this check, so when landon does a BHND
  drive through he knows which bits need updating.

Now, this the /complete/ set of changes for rev 5xx firmware.
Notably, the TX descriptor handling isn't at all done yet and the
format has changed.  So don' try blindly flipping this on just yet!
This commit is contained in:
Adrian Chadd 2016-05-14 23:38:21 +00:00
parent 292e26ba55
commit 1ea968180f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=299790
2 changed files with 177 additions and 8 deletions

View File

@ -49,7 +49,7 @@ extern int bwn_phy_g_switch_channel(struct bwn_mac *mac, uint32_t newchan);
extern uint32_t bwn_phy_g_get_default_chan(struct bwn_mac *mac);
extern void bwn_phy_g_set_antenna(struct bwn_mac *mac, int antenna);
extern int bwn_phy_g_im(struct bwn_mac *mac, int mode);
extern int bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi);
extern bwn_txpwr_result_t bwn_phy_g_recalc_txpwr(struct bwn_mac *mac, int ignore_tssi);
extern void bwn_phy_g_set_txpwr(struct bwn_mac *mac);
extern void bwn_phy_g_task_15s(struct bwn_mac *mac);
extern void bwn_phy_g_task_60s(struct bwn_mac *mac);

View File

@ -58,9 +58,8 @@ struct bwn_mac;
#define BWN_ISOLDFMT(mac) ((mac)->mac_fw.rev <= 351)
#define BWN_TSSI2DBM(num, den) \
((int32_t)((num < 0) ? num / den : (num + den / 2) / den))
#define BWN_HDRSIZE(mac) \
((BWN_ISOLDFMT(mac)) ? (100 + sizeof(struct bwn_plcp6)) : \
(104 + sizeof(struct bwn_plcp6)))
#define BWN_HDRSIZE(mac) bwn_tx_hdrsize(mac)
#define BWN_PIO_COOKIE(tq, tp) \
((uint16_t)((((uint16_t)tq->tq_index + 1) << 12) | tp->tp_index))
#define BWN_DMA_COOKIE(dr, slot) \
@ -69,8 +68,16 @@ struct bwn_mac;
#define BWN_READ_4(mac, o) (siba_read_4(mac->mac_sc->sc_dev, o))
#define BWN_WRITE_2(mac, o, v) \
(siba_write_2(mac->mac_sc->sc_dev, o, v))
#define BWN_WRITE_2_F(mac, o, v) do { \
(BWN_WRITE_2(mac, o, v)); \
BWN_READ_2(mac, o); \
} while(0)
#define BWN_WRITE_SETMASK2(mac, offset, mask, set) \
BWN_WRITE_2(mac, offset, (BWN_READ_2(mac, offset) & mask) | set)
#define BWN_WRITE_4(mac, o, v) \
(siba_write_4(mac->mac_sc->sc_dev, o, v))
#define BWN_WRITE_SETMASK4(mac, offset, mask, set) \
BWN_WRITE_4(mac, offset, (BWN_READ_4(mac, offset) & mask) | set)
#define BWN_PIO_TXQOFFSET(mac) \
((siba_get_revid(mac->mac_sc->sc_dev) >= 11) ? 0x18 : 0)
#define BWN_PIO_RXQOFFSET(mac) \
@ -149,6 +156,26 @@ struct bwn_mac;
#define BWN_DMA_WRITE(dr, offset, value) \
(BWN_WRITE_4(dr->dr_mac, dr->dr_base + offset, value))
typedef enum {
BWN_PHY_BAND_2G = 0,
BWN_PHY_BAND_5G_LO = 1,
BWN_PHY_BAND_5G_MI = 2,
BWN_PHY_BAND_5G_HI = 3
} bwn_phy_band_t;
typedef enum {
BWN_BAND_2G,
BWN_BAND_5G,
} bwn_band_t;
typedef enum {
BWN_CHAN_TYPE_20,
BWN_CHAN_TYPE_20_HT,
BWN_CHAN_TYPE_40_HT_U,
BWN_CHAN_TYPE_40_HT_D,
} bwn_chan_type_t;
struct bwn_rate {
uint16_t rateid;
uint32_t flags;
@ -205,6 +232,11 @@ struct bwn_loctl {
int8_t q;
};
typedef enum {
BWN_TXPWR_RES_NEED_ADJUST,
BWN_TXPWR_RES_DONE,
} bwn_txpwr_result_t;
struct bwn_lo_calib {
struct bwn_bbatt bbatt;
struct bwn_rfatt rfatt;
@ -227,7 +259,17 @@ struct bwn_rxhdr4 {
int8_t power1;
} __packed n;
} __packed phy;
union {
struct {
int8_t power2;
uint8_t pad;
} __packed n;
struct {
uint8_t pad;
int8_t ht_power0;
} __packed ht;
uint16_t phy_status2;
} __packed ps2;
uint16_t phy_status3;
uint32_t mac_status;
uint16_t mac_time;
@ -314,8 +356,6 @@ struct bwn_phy_g {
#define BWN_IMMODE_NONWLAN 1
#define BWN_IMMODE_MANUAL 2
#define BWN_IMMODE_AUTO 3
#define BWN_TXPWR_RES_NEED_ADJUST 0
#define BWN_TXPWR_RES_DONE 1
#define BWN_PHYLP_TXPCTL_UNKNOWN 0
#define BWN_PHYLP_TXPCTL_OFF 1
@ -396,6 +436,8 @@ struct bwn_b206x_rfinit_entry {
uint8_t br_flags;
};
struct bwn_phy_n;
struct bwn_phy {
uint8_t type;
uint8_t rev;
@ -408,10 +450,17 @@ struct bwn_phy {
struct bwn_phy_g phy_g;
struct bwn_phy_lp phy_lp;
/*
* I'd like the newer PHY code to not hide in the top-level
* structs..
*/
struct bwn_phy_n *phy_n;
uint16_t rf_manuf;
uint16_t rf_ver;
uint8_t rf_rev;
int rf_on;
int phy_do_full_init;
int txpower;
int hwpctl;
@ -441,7 +490,7 @@ struct bwn_phy {
uint32_t (*get_default_chan)(struct bwn_mac *);
void (*set_antenna)(struct bwn_mac *, int);
int (*set_im)(struct bwn_mac *, int);
int (*recalc_txpwr)(struct bwn_mac *, int);
bwn_txpwr_result_t (*recalc_txpwr)(struct bwn_mac *, int);
void (*set_txpwr)(struct bwn_mac *);
void (*task_15s)(struct bwn_mac *);
void (*task_60s)(struct bwn_mac *);
@ -889,6 +938,23 @@ struct bwn_mac {
TAILQ_ENTRY(bwn_mac) mac_list;
};
static inline int
bwn_tx_hdrsize(struct bwn_mac *mac)
{
switch (mac->mac_fw.fw_hdr_format) {
case BWN_FW_HDR_598:
return (112 + (sizeof(struct bwn_plcp6)));
case BWN_FW_HDR_410:
return (104 + (sizeof(struct bwn_plcp6)));
case BWN_FW_HDR_351:
return (100 + (sizeof(struct bwn_plcp6)));
default:
printf("%s: unknown header format (%d)\n", __func__,
mac->mac_fw.fw_hdr_format);
return (112 + (sizeof(struct bwn_plcp6)));
}
}
/*
* Driver-specific vap state.
*/
@ -956,4 +1022,107 @@ struct bwn_softc {
#define BWN_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
#define BWN_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
static inline bwn_band_t
bwn_channel_band(struct bwn_mac *mac, struct ieee80211_channel *c)
{
if (IEEE80211_IS_CHAN_5GHZ(c))
return BWN_BAND_5G;
/* XXX check 2g, log error if not 2g or 5g? */
return BWN_BAND_2G;
}
static inline bwn_band_t
bwn_current_band(struct bwn_mac *mac)
{
struct ieee80211com *ic = &mac->mac_sc->sc_ic;
if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
return BWN_BAND_5G;
/* XXX check 2g, log error if not 2g or 5g? */
return BWN_BAND_2G;
}
static inline bool
bwn_is_40mhz(struct bwn_mac *mac)
{
struct ieee80211com *ic = &mac->mac_sc->sc_ic;
return !! (IEEE80211_IS_CHAN_HT40(ic->ic_curchan));
}
static inline int
bwn_get_centre_freq(struct bwn_mac *mac)
{
struct ieee80211com *ic = &mac->mac_sc->sc_ic;
/* XXX TODO: calculate correctly for HT40 mode */
return ic->ic_curchan->ic_freq;
}
static inline int
bwn_get_chan_centre_freq(struct bwn_mac *mac, struct ieee80211_channel *chan)
{
/* XXX TODO: calculate correctly for HT40 mode */
return chan->ic_freq;
}
static inline int
bwn_get_chan(struct bwn_mac *mac)
{
struct ieee80211com *ic = &mac->mac_sc->sc_ic;
/* XXX TODO: calculate correctly for HT40 mode */
return ic->ic_curchan->ic_ieee;
}
static inline struct ieee80211_channel *
bwn_get_channel(struct bwn_mac *mac)
{
struct ieee80211com *ic = &mac->mac_sc->sc_ic;
return ic->ic_curchan;
}
static inline bool
bwn_is_chan_passive(struct bwn_mac *mac)
{
struct ieee80211com *ic = &mac->mac_sc->sc_ic;
return !! IEEE80211_IS_CHAN_PASSIVE(ic->ic_curchan);
}
static inline bwn_chan_type_t
bwn_get_chan_type(struct bwn_mac *mac, struct ieee80211_channel *c)
{
struct ieee80211com *ic = &mac->mac_sc->sc_ic;
if (c == NULL)
c = ic->ic_curchan;
if (IEEE80211_IS_CHAN_HT40U(c))
return BWN_CHAN_TYPE_40_HT_U;
else if (IEEE80211_IS_CHAN_HT40D(c))
return BWN_CHAN_TYPE_40_HT_D;
else if (IEEE80211_IS_CHAN_HT20(c))
return BWN_CHAN_TYPE_20_HT;
else
return BWN_CHAN_TYPE_20;
}
static inline int
bwn_get_chan_power(struct bwn_mac *mac, struct ieee80211_channel *c)
{
/* return in dbm */
return c->ic_maxpower / 2;
}
/*
* For now there's no bhnd bus support. Places where it matters
* should call this routine so we can start logging things.
*/
static inline int
bwn_is_bus_siba(struct bwn_mac *mac)
{
return 1;
}
#endif /* !_IF_BWNVAR_H */