diff --git a/sys/dev/bwn/if_bwn_phy_g.h b/sys/dev/bwn/if_bwn_phy_g.h index 2de14e898d13..77c6fbba5d86 100644 --- a/sys/dev/bwn/if_bwn_phy_g.h +++ b/sys/dev/bwn/if_bwn_phy_g.h @@ -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); diff --git a/sys/dev/bwn/if_bwnvar.h b/sys/dev/bwn/if_bwnvar.h index e3e58158f5df..6743af1f8175 100644 --- a/sys/dev/bwn/if_bwnvar.h +++ b/sys/dev/bwn/if_bwnvar.h @@ -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; - uint16_t phy_status2; + 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 */