Module Name:    src
Committed By:   mlelstv
Date:           Wed Jul 19 16:55:12 UTC 2017

Modified Files:
        src/sys/dev/pci: if_iwn.c if_iwnreg.h if_iwnvar.h

Log Message:
Pull in some hardware support from FreeBSD. Also fix 5GHz mode by
adapting the method described in: https://forums.freebsd.org/threads/53574/.


To generate a diff of this commit:
cvs rdiff -u -r1.84 -r1.85 src/sys/dev/pci/if_iwn.c
cvs rdiff -u -r1.16 -r1.17 src/sys/dev/pci/if_iwnreg.h
cvs rdiff -u -r1.19 -r1.20 src/sys/dev/pci/if_iwnvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/if_iwn.c
diff -u src/sys/dev/pci/if_iwn.c:1.84 src/sys/dev/pci/if_iwn.c:1.85
--- src/sys/dev/pci/if_iwn.c:1.84	Thu Feb  2 10:05:35 2017
+++ src/sys/dev/pci/if_iwn.c	Wed Jul 19 16:55:12 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_iwn.c,v 1.84 2017/02/02 10:05:35 nonaka Exp $	*/
+/*	$NetBSD: if_iwn.c,v 1.85 2017/07/19 16:55:12 mlelstv Exp $	*/
 /*	$OpenBSD: if_iwn.c,v 1.135 2014/09/10 07:22:09 dcoppa Exp $	*/
 
 /*-
@@ -22,7 +22,7 @@
  * adapters.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_iwn.c,v 1.84 2017/02/02 10:05:35 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_iwn.c,v 1.85 2017/07/19 16:55:12 mlelstv Exp $");
 
 #define IWN_USE_RBUF	/* Use local storage for RX */
 #undef IWN_HWCRYPTO	/* XXX does not even compile yet */
@@ -790,7 +790,7 @@ iwn5000_attach(struct iwn_softc *sc, pci
 			sc->fwname = "iwlwifi-6000g2a-5.ucode";
 		break;
 	case IWN_HW_REV_TYPE_2030:
-		sc->limits = &iwn2000_sensitivity_limits;
+		sc->limits = &iwn2030_sensitivity_limits;
 		sc->fwname = "iwlwifi-2030-6.ucode";
 		ops->config_bt_coex = iwn_config_bt_coex_adv2;
 		break;
@@ -1781,6 +1781,7 @@ iwn_read_eeprom_enhinfo(struct iwn_softc
 	struct iwn_eeprom_enhinfo enhinfo[35];
 	uint16_t val, base;
 	int8_t maxpwr;
+	uint8_t flags;
 	int i;
 
 	iwn_read_prom_data(sc, IWN5000_EEPROM_REG, &val, 2);
@@ -1790,7 +1791,8 @@ iwn_read_eeprom_enhinfo(struct iwn_softc
 
 	memset(sc->enh_maxpwr, 0, sizeof sc->enh_maxpwr);
 	for (i = 0; i < __arraycount(enhinfo); i++) {
-		if (enhinfo[i].chan == 0 || enhinfo[i].reserved != 0)
+		flags = enhinfo[i].flags;
+		if (!(flags & IWN_ENHINFO_VALID))
 			continue;	/* Skip invalid entries. */
 
 		maxpwr = 0;
@@ -1915,6 +1917,10 @@ iwn_newstate(struct ieee80211com *ic, en
 		sc->rxon.filter &= ~htole32(IWN_FILTER_BSS);
 		sc->calib.state = IWN_CALIB_STATE_INIT;
 
+		/* Wait until we hear a beacon before we transmit */
+		if (IEEE80211_IS_CHAN_PASSIVE(ic->ic_curchan))
+			sc->sc_beacon_wait = 1;
+
 		if ((error = iwn_auth(sc)) != 0) {
 			aprint_error_dev(sc->sc_dev,
 			    "could not move to auth state\n");
@@ -1923,6 +1929,18 @@ iwn_newstate(struct ieee80211com *ic, en
 		break;
 
 	case IEEE80211_S_RUN:
+		/*
+		 * RUN -> RUN transition; Just restart timers.
+		 */
+		if (ic->ic_state == IEEE80211_S_RUN) {
+			sc->calib_cnt = 0;
+			break;
+		}
+
+		/* Wait until we hear a beacon before we transmit */
+		if (IEEE80211_IS_CHAN_PASSIVE(ic->ic_curchan))
+			sc->sc_beacon_wait = 1;
+
 		if ((error = iwn_run(sc)) != 0) {
 			aprint_error_dev(sc->sc_dev,
 			    "could not move to run state\n");
@@ -1933,6 +1951,13 @@ iwn_newstate(struct ieee80211com *ic, en
 	case IEEE80211_S_INIT:
 		sc->sc_flags &= ~IWN_FLAG_SCANNING;
 		sc->calib.state = IWN_CALIB_STATE_INIT;
+		/*
+		 * Purge the xmit queue so we don't have old frames
+		 * during a new association attempt.
+		 */
+		sc->sc_beacon_wait = 0;
+		ifp->if_flags &= ~IFF_OACTIVE;
+		iwn_start(ifp);
 		break;
 	}
 
@@ -2154,6 +2179,25 @@ iwn_rx_done(struct iwn_softc *sc, struct
 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
 	}
 
+	/*
+	 * If it's a beacon and we're waiting, then do the wakeup.
+	 */
+	if (sc->sc_beacon_wait) {
+		uint8_t type, subtype;
+		type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+		subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+		/*
+		 * This assumes at this point we've received our own
+		 * beacon.
+		 */
+		if (type == IEEE80211_FC0_TYPE_MGT &&
+		    subtype == IEEE80211_FC0_SUBTYPE_BEACON) {
+			sc->sc_beacon_wait = 0;
+			ifp->if_flags &= ~IFF_OACTIVE;
+			iwn_start(ifp);
+		}
+	}
+
 	/* Send the frame to the 802.11 layer. */
 	ieee80211_input(ic, m, ni, rssi, 0);
 
@@ -3142,6 +3186,11 @@ iwn_start(struct ifnet *ifp)
 		return;
 
 	for (;;) {
+		if (sc->sc_beacon_wait == 1) {
+			ifp->if_flags |= IFF_OACTIVE;
+			break;
+		}
+
 		if (sc->qfullmsk != 0) {
 			ifp->if_flags |= IFF_OACTIVE;
 			break;
@@ -3184,7 +3233,8 @@ iwn_start(struct ifnet *ifp)
 		ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ?
 		    M_WME_GETAC(m) : WME_AC_BE;
 
-		bpf_mtap(ifp, m);
+		if (sc->sc_beacon_wait == 0)
+			bpf_mtap(ifp, m);
 
 		if ((m = ieee80211_encap(ic, m, ni)) == NULL) {
 			ieee80211_free_node(ni);
@@ -3192,6 +3242,9 @@ iwn_start(struct ifnet *ifp)
 			continue;
 		}
 sendit:
+		if (sc->sc_beacon_wait)
+			continue;
+
 		bpf_mtap3(ic->ic_rawbpf, m);
 
 		if (iwn_tx(sc, m, ni, ac) != 0) {
@@ -3203,6 +3256,9 @@ sendit:
 		sc->sc_tx_timer = 5;
 		ifp->if_timer = 1;
 	}
+
+	if (sc->sc_beacon_wait > 1)
+		sc->sc_beacon_wait = 0;
 }
 
 static void
@@ -3695,6 +3751,7 @@ static int
 iwn5000_set_txpower(struct iwn_softc *sc, int async)
 {
 	struct iwn5000_cmd_txpower cmd;
+	int cmdid;
 
 	/*
 	 * TX power calibration is handled automatically by the firmware
@@ -3705,7 +3762,11 @@ iwn5000_set_txpower(struct iwn_softc *sc
 	cmd.flags = IWN5000_TXPOWER_NO_CLOSED;
 	cmd.srv_limit = IWN5000_TXPOWER_AUTO;
 	DPRINTF(("setting TX power\n"));
-	return iwn_cmd(sc, IWN_CMD_TXPOWER_DBM, &cmd, sizeof cmd, async);
+	if (IWN_UCODE_API(sc->ucode_rev) == 1)
+		cmdid = IWN_CMD_TXPOWER_DBM_V1;
+	else
+		cmdid = IWN_CMD_TXPOWER_DBM;
+	return iwn_cmd(sc, cmdid, &cmd, sizeof cmd, async);
 }
 
 /*
@@ -4166,7 +4227,7 @@ iwn_send_sensitivity(struct iwn_softc *s
 	cmd.energy_cck       = htole16(calib->energy_cck);
 	/* Barker modulation: use default values. */
 	cmd.corr_barker      = htole16(190);
-	cmd.corr_barker_mrc  = htole16(390);
+	cmd.corr_barker_mrc  = htole16(sc->limits->barker_mrc);
 	if (!(sc->sc_flags & IWN_FLAG_ENH_SENS))
 		goto send;
 	/* Enhanced sensitivity settings. */
@@ -5677,6 +5738,8 @@ iwn_read_firmware_leg(struct iwn_softc *
 	ptr = (const uint32_t *)fw->data;
 	rev = le32toh(*ptr++);
 
+	sc->ucode_rev = rev;
+
 	/* Check firmware API version. */
 	if (IWN_FW_API(rev) <= 1) {
 		aprint_error_dev(sc->sc_dev,
@@ -5742,6 +5805,7 @@ iwn_read_firmware_tlv(struct iwn_softc *
 	}
 	DPRINTF(("FW: \"%.64s\", build 0x%x\n", hdr->descr,
 	    le32toh(hdr->build)));
+	sc->ucode_rev = le32toh(hdr->rev);
 
 	/*
 	 * Select the closest supported alternative that is less than
@@ -6330,6 +6394,8 @@ iwn_init(struct ifnet *ifp)
 		goto fail;
 	}
 
+	sc->sc_beacon_wait = 0;
+
 	ifp->if_flags &= ~IFF_OACTIVE;
 	ifp->if_flags |= IFF_RUNNING;
 

Index: src/sys/dev/pci/if_iwnreg.h
diff -u src/sys/dev/pci/if_iwnreg.h:1.16 src/sys/dev/pci/if_iwnreg.h:1.17
--- src/sys/dev/pci/if_iwnreg.h:1.16	Sat Mar 11 21:23:36 2017
+++ src/sys/dev/pci/if_iwnreg.h	Wed Jul 19 16:55:12 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_iwnreg.h,v 1.16 2017/03/11 21:23:36 maya Exp $	*/
+/*	$NetBSD: if_iwnreg.h,v 1.17 2017/07/19 16:55:12 mlelstv Exp $	*/
 /*	$OpenBSD: if_iwnreg.h,v 1.49 2014/09/09 18:56:24 sthen Exp $	*/
 
 /*-
@@ -440,6 +440,7 @@ struct iwn_tx_cmd {
 #define IWN_CMD_TXPOWER_DBM		149
 #define IWN_CMD_TXPOWER			151
 #define IWN5000_CMD_TX_ANT_CONFIG	152
+#define IWN_CMD_TXPOWER_DBM_V1		152
 #define IWN_CMD_BT_COEX			155
 #define IWN_CMD_GET_STATISTICS		156
 #define IWN_CMD_SET_CRITICAL_TEMP	164
@@ -1594,7 +1595,17 @@ struct iwn_eeprom_chan {
 } __packed;
 
 struct iwn_eeprom_enhinfo {
-	uint16_t	chan;
+	uint8_t		flags;
+#define IWN_ENHINFO_VALID       (1 << 0)
+#define IWN_ENHINFO_5GHZ        (1 << 1)
+#define IWN_ENHINFO_OFDM        (1 << 2)
+#define IWN_ENHINFO_HT40        (1 << 3)
+#define IWN_ENHINFO_HTAP        (1 << 4)
+#define IWN_ENHINFO_RES1        (1 << 5)
+#define IWN_ENHINFO_RES2        (1 << 6)
+#define IWN_ENHINFO_COMMON      (1 << 7)
+
+	uint8_t		chan;
 	int8_t		chain[3];	/* max power in half-dBm */
 	uint8_t		reserved;
 	int8_t		mimo2;		/* max power in half-dBm */
@@ -1813,6 +1824,7 @@ struct iwn_sensitivity_limits {
 	uint32_t	min_energy_cck;
 	uint32_t	energy_cck;
 	uint32_t	energy_ofdm;
+	uint32_t	barker_mrc;
 };
 
 /*
@@ -1827,7 +1839,8 @@ static const struct iwn_sensitivity_limi
 	200, 400,
 	 97,
 	100,
-	100
+	100,
+	390
 };
 
 static const struct iwn_sensitivity_limits iwn5000_sensitivity_limits = {
@@ -1839,7 +1852,8 @@ static const struct iwn_sensitivity_limi
 	170, 400,
 	 95,
 	 95,
-	 95
+	 95,
+	390
 };
 
 static const struct iwn_sensitivity_limits iwn5150_sensitivity_limits = {
@@ -1851,7 +1865,8 @@ static const struct iwn_sensitivity_limi
 	170, 400,
 	 95,
 	 95,
-	 95
+	 95,
+	390
 };
 
 static const struct iwn_sensitivity_limits iwn1000_sensitivity_limits = {
@@ -1863,7 +1878,8 @@ static const struct iwn_sensitivity_limi
 	170, 400,
 	 95,
 	 95,
-	 95
+	 95,
+	390
 };
 
 static const struct iwn_sensitivity_limits iwn6000_sensitivity_limits = {
@@ -1875,7 +1891,21 @@ static const struct iwn_sensitivity_limi
 	160, 310,
 	 97,
 	 97,
-	100
+	100,
+	390
+};
+
+static const struct iwn_sensitivity_limits iwn6235_sensitivity_limits = {
+	105, 110,
+	192, 232,
+	 80, 145,
+	128, 232,
+	125, 175,
+	160, 310,
+	100,
+	110,
+	110,
+	336
 };
 
 static const struct iwn_sensitivity_limits iwn2000_sensitivity_limits = {
@@ -1887,7 +1917,21 @@ static const struct iwn_sensitivity_limi
 	160, 310,
 	 97,
 	 97,
-	100
+	100,
+	336
+};
+
+static const struct iwn_sensitivity_limits iwn2030_sensitivity_limits = {
+	105,110,
+	128,232,
+	80,145,
+	128,232,
+	125,175,
+	160,310,
+	97,
+	97,
+	110,
+	390
 };
 
 /* Map TID to TX scheduler's FIFO. */

Index: src/sys/dev/pci/if_iwnvar.h
diff -u src/sys/dev/pci/if_iwnvar.h:1.19 src/sys/dev/pci/if_iwnvar.h:1.20
--- src/sys/dev/pci/if_iwnvar.h:1.19	Thu Feb  2 10:05:35 2017
+++ src/sys/dev/pci/if_iwnvar.h	Wed Jul 19 16:55:12 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_iwnvar.h,v 1.19 2017/02/02 10:05:35 nonaka Exp $	*/
+/*	$NetBSD: if_iwnvar.h,v 1.20 2017/07/19 16:55:12 mlelstv Exp $	*/
 /*	$OpenBSD: if_iwnvar.h,v 1.28 2014/09/09 18:55:08 sthen Exp $	*/
 
 /*-
@@ -338,7 +338,11 @@ struct iwn_softc {
 #define sc_txtap	sc_txtapu.th
 	int			sc_txtap_len;
 
+#define IWN_UCODE_API(ver)	(((ver) & 0x0000ff00) >> 8)
+	uint32_t		ucode_rev;
+
 	kmutex_t		sc_mtx;         /* mutex for init/stop */
 
+	int			sc_beacon_wait;	/* defer/skip sending */
 };
 

Reply via email to