Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 14 May 2016 23:38:22 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r299790 - head/sys/dev/bwn
Message-ID:  <201605142338.u4ENcMFJ087849@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Sat May 14 23:38:21 2016
New Revision: 299790
URL: https://svnweb.freebsd.org/changeset/base/299790

Log:
  [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!

Modified:
  head/sys/dev/bwn/if_bwn_phy_g.h
  head/sys/dev/bwn/if_bwnvar.h

Modified: head/sys/dev/bwn/if_bwn_phy_g.h
==============================================================================
--- head/sys/dev/bwn/if_bwn_phy_g.h	Sat May 14 23:36:00 2016	(r299789)
+++ head/sys/dev/bwn/if_bwn_phy_g.h	Sat May 14 23:38:21 2016	(r299790)
@@ -49,7 +49,7 @@ extern int bwn_phy_g_switch_channel(stru
 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);

Modified: head/sys/dev/bwn/if_bwnvar.h
==============================================================================
--- head/sys/dev/bwn/if_bwnvar.h	Sat May 14 23:36:00 2016	(r299789)
+++ head/sys/dev/bwn/if_bwnvar.h	Sat May 14 23:38:21 2016	(r299790)
@@ -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 */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605142338.u4ENcMFJ087849>