Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 13 Aug 2013 09:08:10 +0200
From:      "Cedric GROSS" <cg@cgross.info>
To:        "'Adrian Chadd'" <adrian@freebsd.org>
Cc:        freebsd-wireless@freebsd.org
Subject:   RE: [iwn]Review Split 6
Message-ID:  <000c01ce97f3$e0178d10$a046a730$@info>
In-Reply-To: <00cc01ce978e$dada4190$908ec4b0$@info>
References:  <001d01ce9694$142db8b0$3c892a10$@info> <CAJ-VmomM3FcdiuVWdiZ68i--ikGgNFvySiPURyOe_4CR_eYYXA@mail.gmail.com> <00cc01ce978e$dada4190$908ec4b0$@info>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.

------=_NextPart_000_000D_01CE9804.A3A05D10
Content-Type: text/plain;
	charset="us-ascii"
Content-Transfer-Encoding: 7bit

> >
> > I guess '_u1' here is 'PAN VAP'. We'll eventually rename this stuff
> > and maybe shift it into a separate source file so all the PAN stuff
> > clearly lives elsewhere.
> 
> Ok I'll do that.
> 

Here is new version of split 6 with new files and new function renamed.

Cedric

------=_NextPart_000_000D_01CE9804.A3A05D10
Content-Type: application/octet-stream;
	name="pan2.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="pan2.patch"

Index: sys/dev/iwn/if_iwn.c=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
--- sys/dev/iwn/if_iwn.c	(revision 254271)=0A=
+++ sys/dev/iwn/if_iwn.c	(working copy)=0A=
@@ -77,6 +77,7 @@=0A=
 #include <dev/iwn/if_iwnreg.h>=0A=
 #include <dev/iwn/if_iwnvar.h>=0A=
 #include <dev/iwn/if_iwn_devid.h>=0A=
+#include <dev/iwn/if_iwn_pan.h>=0A=
 =0A=
 struct iwn_ident {=0A=
 	uint16_t	vendor;=0A=
@@ -180,7 +181,6 @@=0A=
 static void	iwn_read_eeprom_enhinfo(struct iwn_softc *);=0A=
 static struct ieee80211_node *iwn_node_alloc(struct ieee80211vap *,=0A=
 		    const uint8_t mac[IEEE80211_ADDR_LEN]);=0A=
-static void	iwn_newassoc(struct ieee80211_node *, int);=0A=
 static int	iwn_media_change(struct ifnet *);=0A=
 static int	iwn_newstate(struct ieee80211vap *, enum ieee80211_state, =
int);=0A=
 static void	iwn_calib_timeout(void *);=0A=
@@ -225,7 +225,6 @@=0A=
 static void	iwn_start_locked(struct ifnet *);=0A=
 static void	iwn_watchdog(void *);=0A=
 static int	iwn_ioctl(struct ifnet *, u_long, caddr_t);=0A=
-static int	iwn_cmd(struct iwn_softc *, int, const void *, int, int);=0A=
 static int	iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *,=0A=
 		    int);=0A=
 static int	iwn5000_add_node(struct iwn_softc *, struct iwn_node_info *,=0A=
@@ -329,37 +328,7 @@=0A=
 #ifdef	IWN_DEBUG=0A=
 static char	*iwn_get_csr_string(int);=0A=
 static void	iwn_debug_register(struct iwn_softc *);=0A=
-#endif=0A=
-=0A=
-#ifdef	IWN_DEBUG=0A=
-enum {=0A=
-	IWN_DEBUG_XMIT		=3D 0x00000001,	/* basic xmit operation */=0A=
-	IWN_DEBUG_RECV		=3D 0x00000002,	/* basic recv operation */=0A=
-	IWN_DEBUG_STATE		=3D 0x00000004,	/* 802.11 state transitions */=0A=
-	IWN_DEBUG_TXPOW		=3D 0x00000008,	/* tx power processing */=0A=
-	IWN_DEBUG_RESET		=3D 0x00000010,	/* reset processing */=0A=
-	IWN_DEBUG_OPS		=3D 0x00000020,	/* iwn_ops processing */=0A=
-	IWN_DEBUG_BEACON 	=3D 0x00000040,	/* beacon handling */=0A=
-	IWN_DEBUG_WATCHDOG 	=3D 0x00000080,	/* watchdog timeout */=0A=
-	IWN_DEBUG_INTR		=3D 0x00000100,	/* ISR */=0A=
-	IWN_DEBUG_CALIBRATE	=3D 0x00000200,	/* periodic calibration */=0A=
-	IWN_DEBUG_NODE		=3D 0x00000400,	/* node management */=0A=
-	IWN_DEBUG_LED		=3D 0x00000800,	/* led management */=0A=
-	IWN_DEBUG_CMD		=3D 0x00001000,	/* cmd submission */=0A=
-	IWN_DEBUG_TXRATE	=3D 0x00002000,	/* TX rate debugging */=0A=
-	IWN_DEBUG_PWRSAVE	=3D 0x00004000,	/* Power save operations */=0A=
-	IWN_DEBUG_REGISTER	=3D 0x20000000,	/* print chipset register */=0A=
-	IWN_DEBUG_TRACE		=3D 0x40000000,	/* Print begin and start driver =
function */=0A=
-	IWN_DEBUG_FATAL		=3D 0x80000000,	/* fatal errors */=0A=
-	IWN_DEBUG_ANY		=3D 0xffffffff=0A=
-};=0A=
-=0A=
-#define DPRINTF(sc, m, fmt, ...) do {			\=0A=
-	if (sc->sc_debug & (m))				\=0A=
-		printf(fmt, __VA_ARGS__);		\=0A=
-} while (0)=0A=
-=0A=
-static const char *=0A=
+const char *=0A=
 iwn_intr_str(uint8_t cmd)=0A=
 {=0A=
 	switch (cmd) {=0A=
@@ -401,8 +370,6 @@=0A=
 	}=0A=
 	return "UNKNOWN INTR NOTIF/CMD";=0A=
 }=0A=
-#else=0A=
-#define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)=0A=
 #endif=0A=
 =0A=
 static device_method_t iwn_methods[] =3D {=0A=
@@ -919,6 +886,13 @@=0A=
 =0A=
 	IEEE80211_ADDR_COPY(mac1, mac);=0A=
 =0A=
+	if(unit =3D=3D 1) {=0A=
+		if(!(sc->sc_flags & IWN_FLAG_PAN_SUPPORT))=0A=
+			return NULL;=0A=
+		mac1[5] +=3D 1;=0A=
+		sc->ctx	=3D IWN_RXON_PAN_CTX;=0A=
+	}=0A=
+=0A=
 	ivp =3D (struct iwn_vap *) malloc(sizeof(struct iwn_vap),=0A=
 	    M_80211_VAP, M_NOWAIT | M_ZERO);=0A=
 	if (ivp =3D=3D NULL)=0A=
@@ -925,13 +899,27 @@=0A=
 		return NULL;=0A=
 	vap =3D &ivp->iv_vap;=0A=
 	ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac1);=0A=
-	ivp->ctx =3D IWN_RXON_BSS_CTX;=0A=
-	IEEE80211_ADDR_COPY(ivp->macaddr, mac1);=0A=
+=0A=
+	if(unit =3D=3D 1) {=0A=
+		ivp->ctx =3D IWN_RXON_PAN_CTX;=0A=
+		ivp->iv_newstate =3D vap->iv_newstate;=0A=
+		vap->iv_newstate =3D iwn_newstate_pan;=0A=
+		IEEE80211_ADDR_COPY(ivp->macaddr, mac1);=0A=
+		memset(&sc->rx_on[IWN_RXON_PAN_CTX], 0, sizeof (struct iwn_rxon));=0A=
+		memcpy(&sc->rx_on[IWN_RXON_PAN_CTX], &sc->rx_on[IWN_RXON_BSS_CTX], =
sc->rxonsz);=0A=
+		IEEE80211_ADDR_COPY(sc->rx_on[IWN_RXON_PAN_CTX].myaddr, mac1);=0A=
+		sc->rx_on[IWN_RXON_PAN_CTX].mode =3D IWN_MODE_2STA;=0A=
+		sc->ivap[IWN_RXON_PAN_CTX] =3D vap;=0A=
+	}=0A=
+	else {=0A=
+		ivp->ctx =3D IWN_RXON_BSS_CTX;=0A=
+		IEEE80211_ADDR_COPY(ivp->macaddr, mac1);=0A=
+		ivp->iv_newstate =3D vap->iv_newstate;=0A=
+		vap->iv_newstate =3D iwn_newstate;=0A=
+		sc->ivap[IWN_RXON_BSS_CTX] =3D vap;=0A=
+	}=0A=
+=0A=
 	vap->iv_bmissthreshold =3D 10;		/* override default */=0A=
-	/* Override with driver methods. */=0A=
-	ivp->iv_newstate =3D vap->iv_newstate;=0A=
-	vap->iv_newstate =3D iwn_newstate;=0A=
-	sc->ivap[IWN_RXON_BSS_CTX] =3D vap;=0A=
 =0A=
 	ieee80211_ratectl_init(vap);=0A=
 	/* Complete setup. */=0A=
@@ -944,7 +932,11 @@=0A=
 iwn_vap_delete(struct ieee80211vap *vap)=0A=
 {=0A=
 	struct iwn_vap *ivp =3D IWN_VAP(vap);=0A=
+	struct iwn_softc *sc =3D vap->iv_ic->ic_ifp->if_softc;=0A=
 =0A=
+	if(ivp->ctx =3D=3D IWN_RXON_PAN_CTX)=0A=
+		sc->ctx =3D 0;=0A=
+=0A=
 	ieee80211_ratectl_deinit(vap);=0A=
 	ieee80211_vap_detach(vap);=0A=
 	free(ivp, M_80211_VAP);=0A=
@@ -2317,7 +2309,7 @@=0A=
 #undef	RV=0A=
 }=0A=
 =0A=
-static void=0A=
+void=0A=
 iwn_newassoc(struct ieee80211_node *ni, int isnew)=0A=
 {=0A=
 	/* Doesn't do anything at the moment */=0A=
@@ -2794,6 +2786,7 @@=0A=
 	struct ieee80211vap *vap =3D TAILQ_FIRST(&ic->ic_vaps);=0A=
 	struct iwn_calib_state *calib =3D &sc->calib;=0A=
 	struct iwn_stats *stats =3D (struct iwn_stats *)(desc + 1);=0A=
+	struct ieee80211vap *vap1;=0A=
 	int temp;=0A=
 =0A=
 	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);=0A=
@@ -2805,6 +2798,13 @@=0A=
 	    __func__);=0A=
 		return;=0A=
 	}=0A=
+	if(sc->ctx =3D=3D IWN_RXON_PAN_CTX) {=0A=
+		vap1 =3D sc->ivap[IWN_RXON_PAN_CTX];=0A=
+		/* Ignore statistics received during a scan. */=0A=
+		if (vap1->iv_state !=3D IEEE80211_S_RUN ||=0A=
+		    (ic->ic_flags & IEEE80211_F_SCAN))=0A=
+			return;=0A=
+	}=0A=
 =0A=
 	bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD);=0A=
 =0A=
@@ -2993,12 +2993,19 @@=0A=
 static void=0A=
 iwn_cmd_done(struct iwn_softc *sc, struct iwn_rx_desc *desc)=0A=
 {=0A=
-	struct iwn_tx_ring *ring =3D &sc->txq[4];=0A=
+	struct iwn_tx_ring *ring;=0A=
 	struct iwn_tx_data *data;=0A=
+	int cmd_queue_num;=0A=
 =0A=
-	if ((desc->qid & 0xf) !=3D 4)=0A=
+	if(sc->sc_flags & IWN_FLAG_PAN_SUPPORT)=0A=
+		cmd_queue_num =3D IWN_PAN_CMD_QUEUE;=0A=
+	else=0A=
+		cmd_queue_num =3D IWN_CMD_QUEUE_NUM;=0A=
+=0A=
+	if ((desc->qid & IWN_RX_DESC_QID_MSK) !=3D cmd_queue_num)=0A=
 		return;	/* Not a command ack. */=0A=
 =0A=
+	ring =3D &sc->txq[cmd_queue_num];=0A=
 	data =3D &ring->data[desc->idx];=0A=
 =0A=
 	/* If the command was mapped in an mbuf, free it. */=0A=
@@ -3154,7 +3161,7 @@=0A=
 		    desc->type, iwn_intr_str(desc->type),=0A=
 		    le16toh(desc->len));=0A=
 =0A=
-		if (!(desc->qid & 0x80))	/* Reply to a command. */=0A=
+		if (!(desc->qid & IWN_UNSOLICITED_RX_NOTIF))	/* Reply to a command. */=0A=
 			iwn_cmd_done(sc, desc);=0A=
 =0A=
 		switch (desc->type) {=0A=
@@ -3187,7 +3194,10 @@=0A=
 		{=0A=
 			struct iwn_beacon_missed *miss =3D=0A=
 			    (struct iwn_beacon_missed *)(desc + 1);=0A=
-			int misses;=0A=
+			struct ieee80211vap *vap0 =3D sc->ivap[IWN_RXON_BSS_CTX];=0A=
+			struct ieee80211vap *vap1 =3D sc->ivap[IWN_RXON_PAN_CTX];=0A=
+			int misses,iv_bmissthreshold;=0A=
+			int DoReinit =3D0 ;=0A=
 =0A=
 			bus_dmamap_sync(sc->rxq.data_dmat, data->map,=0A=
 			    BUS_DMASYNC_POSTREAD);=0A=
@@ -3194,17 +3204,31 @@=0A=
 			misses =3D le32toh(miss->consecutive);=0A=
 =0A=
 			DPRINTF(sc, IWN_DEBUG_STATE,=0A=
-			    "%s: beacons missed %d/%d\n", __func__,=0A=
-			    misses, le32toh(miss->total));=0A=
+			    "%s: beacons missed %d/%d rcv %d expect %d\n", __func__,=0A=
+			    misses, le32toh(miss->total), le32toh(miss->received),=0A=
+			    le32toh(miss->expected));=0A=
+=0A=
+			iv_bmissthreshold =3D vap0->iv_bmissthreshold;=0A=
+=0A=
+			if(sc->ctx =3D=3D IWN_RXON_PAN_CTX) {=0A=
+				iv_bmissthreshold =3D vap1->iv_bmissthreshold;=0A=
+				if (vap0->iv_state =3D=3D IEEE80211_S_RUN &&=0A=
+				    vap1->iv_state =3D=3D IEEE80211_S_RUN &&=0A=
+				    (ic->ic_flags & IEEE80211_F_SCAN) =3D=3D 0)=0A=
+					DoReinit =3D 1;=0A=
+			}=0A=
+			else if (vap0->iv_state =3D=3D IEEE80211_S_RUN &&=0A=
+				 (ic->ic_flags & IEEE80211_F_SCAN) =3D=3D 0)=0A=
+					DoReinit =3D 1;=0A=
+=0A=
 			/*=0A=
 			 * If more than 5 consecutive beacons are missed,=0A=
 			 * reinitialize the sensitivity state machine.=0A=
 			 */=0A=
-			if (vap->iv_state =3D=3D IEEE80211_S_RUN &&=0A=
-			    (ic->ic_flags & IEEE80211_F_SCAN) =3D=3D 0) {=0A=
+			if (DoReinit=3D=3D1) {=0A=
 				if (misses > 5)=0A=
 					(void)iwn_init_sensitivity(sc);=0A=
-				if (misses >=3D vap->iv_bmissthreshold) {=0A=
+				if (misses >=3D iv_bmissthreshold) {=0A=
 					IWN_UNLOCK(sc);=0A=
 					ieee80211_beacon_miss(ic);=0A=
 					IWN_LOCK(sc);=0A=
@@ -3568,6 +3592,7 @@=0A=
 	const struct ieee80211_txparam *tp;=0A=
 	struct ieee80211vap *vap =3D ni->ni_vap;=0A=
 	struct ieee80211com *ic =3D ni->ni_ic;=0A=
+	struct iwn_vap *ivp =3D IWN_VAP(vap);=0A=
 	struct iwn_node *wn =3D (void *)ni;=0A=
 	struct iwn_tx_ring *ring;=0A=
 	struct iwn_tx_desc *desc;=0A=
@@ -3600,21 +3625,23 @@=0A=
 		qos =3D 0;=0A=
 		tid =3D 0;=0A=
 	}=0A=
-	ac =3D M_WME_GETAC(m);=0A=
-	if (m->m_flags & M_AMPDU_MPDU) {=0A=
+=0A=
+	if(ivp->ctx =3D=3D IWN_RXON_PAN_CTX)=0A=
+		ac =3D iwn_pan_ac_to_queue[M_WME_GETAC(m)];=0A=
+	else=0A=
+		ac =3D iwn_bss_ac_to_queue[M_WME_GETAC(m)];=0A=
+=0A=
+	if (IEEE80211_QOS_HAS_SEQ(wh) &&=0A=
+	    IEEE80211_AMPDU_RUNNING(&ni->ni_tx_ampdu[ac])) {=0A=
 		struct ieee80211_tx_ampdu *tap =3D &ni->ni_tx_ampdu[ac];=0A=
 =0A=
-		if (!IEEE80211_AMPDU_RUNNING(tap)) {=0A=
-			m_freem(m);=0A=
-			return EINVAL;=0A=
-		}=0A=
-=0A=
-		ac =3D *(int *)tap->txa_private;=0A=
+		ring =3D &sc->txq[*(int *)tap->txa_private];=0A=
 		*(uint16_t *)wh->i_seq =3D=0A=
 		    htole16(ni->ni_txseqs[tid] << IEEE80211_SEQ_SEQ_SHIFT);=0A=
 		ni->ni_txseqs[tid]++;=0A=
-	}=0A=
-	ring =3D &sc->txq[ac];=0A=
+	} else=0A=
+		ring =3D &sc->txq[ac];=0A=
+=0A=
 	desc =3D &ring->desc[ring->cur];=0A=
 	data =3D &ring->data[ring->cur];=0A=
 =0A=
@@ -3707,9 +3734,12 @@=0A=
 	}=0A=
 =0A=
 	if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||=0A=
-	    type !=3D IEEE80211_FC0_TYPE_DATA)=0A=
-		tx->id =3D sc->broadcast_id;=0A=
-	else=0A=
+	    type !=3D IEEE80211_FC0_TYPE_DATA) {=0A=
+		if(ivp->ctx =3D=3D IWN_RXON_PAN_CTX)=0A=
+			tx->id =3D IWN_PAN_ID_BCAST;=0A=
+		else=0A=
+			tx->id =3D sc->broadcast_id;=0A=
+	} else=0A=
 		tx->id =3D wn->id;=0A=
 =0A=
 	if (type =3D=3D IEEE80211_FC0_TYPE_MGT) {=0A=
@@ -3739,7 +3769,7 @@=0A=
 	tx->data_ntries =3D 15;=0A=
 	tx->lifetime =3D htole32(IWN_LIFETIME_INFINITE);=0A=
 	tx->rate =3D iwn_rate_to_plcp(sc, ni, rate);=0A=
-	if (tx->id =3D=3D sc->broadcast_id) {=0A=
+	if ((tx->id =3D=3D IWN_PAN_ID_BCAST) || (tx->id =3D=3D =
sc->broadcast_id)) {=0A=
 		/* Group or management frame. */=0A=
 		tx->linkq =3D 0;=0A=
 		/* XXX Alternate between antenna A and B? */=0A=
@@ -3856,7 +3886,7 @@=0A=
 	u_int hdrlen;=0A=
 	int ac, totlen, error, pad, nsegs =3D 0, i, rate;=0A=
 	uint8_t ridx, type, txant;=0A=
-=0A=
+	struct iwn_vap *ivp =3D IWN_VAP(vap);=0A=
 	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);=0A=
 =0A=
 	IWN_LOCK_ASSERT(sc);=0A=
@@ -3946,7 +3976,10 @@=0A=
 =0A=
 	tx->len =3D htole16(totlen);=0A=
 	tx->tid =3D 0;=0A=
-	tx->id =3D sc->broadcast_id;=0A=
+	if(ivp->ctx =3D=3D IWN_RXON_PAN_CTX)=0A=
+		tx->id =3D IWN_PAN_ID_BCAST;=0A=
+	else=0A=
+		tx->id =3D sc->broadcast_id;=0A=
 	tx->rts_ntries =3D params->ibp_try1;=0A=
 	tx->data_ntries =3D params->ibp_try0;=0A=
 	tx->lifetime =3D htole32(IWN_LIFETIME_INFINITE);=0A=
@@ -4204,16 +4237,16 @@=0A=
 /*=0A=
  * Send a command to the firmware.=0A=
  */=0A=
-static int=0A=
+int=0A=
 iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int =
async)=0A=
 {=0A=
-	struct iwn_tx_ring *ring =3D &sc->txq[4];=0A=
+	struct iwn_tx_ring *ring ;=0A=
 	struct iwn_tx_desc *desc;=0A=
 	struct iwn_tx_data *data;=0A=
 	struct iwn_tx_cmd *cmd;=0A=
 	struct mbuf *m;=0A=
 	bus_addr_t paddr;=0A=
-	int totlen, error;=0A=
+	int totlen, error,cmd_queue_num;=0A=
 =0A=
 	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);=0A=
 =0A=
@@ -4220,6 +4253,12 @@=0A=
 	if (async =3D=3D 0)=0A=
 		IWN_LOCK_ASSERT(sc);=0A=
 =0A=
+	if(sc->sc_flags & IWN_FLAG_PAN_SUPPORT)=0A=
+		cmd_queue_num =3D IWN_PAN_CMD_QUEUE;=0A=
+	else=0A=
+		cmd_queue_num =3D IWN_CMD_QUEUE_NUM;=0A=
+=0A=
+	ring =3D &sc->txq[cmd_queue_num];=0A=
 	desc =3D &ring->desc[ring->cur];=0A=
 	data =3D &ring->data[ring->cur];=0A=
 	totlen =3D 4 + size;=0A=
@@ -5546,6 +5585,8 @@=0A=
 	struct ieee80211com *ic =3D ifp->if_l2com;=0A=
 	struct ieee80211_scan_state *ss =3D ic->ic_scan;	/*XXX*/=0A=
 	struct ieee80211_node *ni =3D ss->ss_vap->iv_bss;=0A=
+	struct ieee80211vap *vap =3D ni->ni_vap;=0A=
+	struct iwn_vap *ivp =3D IWN_VAP(vap);=0A=
 	struct iwn_scan_hdr *hdr;=0A=
 	struct iwn_cmd_data *tx;=0A=
 	struct iwn_scan_essid *essid;=0A=
@@ -5560,7 +5601,11 @@=0A=
 =0A=
 	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);=0A=
 =0A=
-	sc->rxon =3D &sc->rx_on[IWN_RXON_BSS_CTX];=0A=
+	if(ivp->ctx =3D=3D IWN_RXON_BSS_CTX)=0A=
+		sc->rxon =3D &sc->rx_on[IWN_RXON_BSS_CTX];=0A=
+	else if(ivp->ctx =3D=3D IWN_RXON_PAN_CTX)=0A=
+		sc->rxon =3D &sc->rx_on[IWN_RXON_PAN_CTX];=0A=
+=0A=
 	buf =3D malloc(IWN_SCAN_MAXSZ, M_DEVBUF, M_NOWAIT | M_ZERO);=0A=
 	if (buf =3D=3D NULL) {=0A=
 		device_printf(sc->sc_dev,=0A=
@@ -5592,7 +5637,11 @@=0A=
 =0A=
 	tx =3D (struct iwn_cmd_data *)(hdr + 1);=0A=
 	tx->flags =3D htole32(IWN_TX_AUTO_SEQ);=0A=
-	tx->id =3D sc->broadcast_id;=0A=
+	if(ivp->ctx =3D=3D IWN_RXON_PAN_CTX)=0A=
+		tx->id =3D IWN_PAN_ID_BCAST;=0A=
+	else=0A=
+		tx->id =3D sc->broadcast_id;=0A=
+=0A=
 	tx->lifetime =3D htole32(IWN_LIFETIME_INFINITE);=0A=
 =0A=
 	if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) {=0A=
@@ -5629,7 +5678,7 @@=0A=
 	    IEEE80211_FC0_SUBTYPE_PROBE_REQ;=0A=
 	wh->i_fc[1] =3D IEEE80211_FC1_DIR_NODS;=0A=
 	IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr);=0A=
-	IEEE80211_ADDR_COPY(wh->i_addr2, IF_LLADDR(ifp));=0A=
+	IEEE80211_ADDR_COPY(wh->i_addr2, ivp->macaddr);=0A=
 	IEEE80211_ADDR_COPY(wh->i_addr3, ifp->if_broadcastaddr);=0A=
 	*(uint16_t *)&wh->i_dur[0] =3D 0;	/* filled by HW */=0A=
 	*(uint16_t *)&wh->i_seq[0] =3D 0;	/* filled by HW */=0A=
@@ -5781,6 +5830,15 @@=0A=
 	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);=0A=
 =0A=
 	sc->rxon =3D &sc->rx_on[IWN_RXON_BSS_CTX];=0A=
+=0A=
+	if(sc->ctx =3D=3D IWN_RXON_PAN_CTX) {=0A=
+		if ((error =3D iwn_set_pan_params(sc)) !=3D 0) {=0A=
+			device_printf(sc->sc_dev,=0A=
+			   "%s: iwn_set_pan_params error %d\n", __func__, error);=0A=
+			return error;=0A=
+		}=0A=
+	}=0A=
+=0A=
 	if (ic->ic_opmode =3D=3D IEEE80211_M_MONITOR) {=0A=
 		/* Link LED blinks while monitoring. */=0A=
 		iwn_set_led(sc, IWN_LED_LINK, 5, 5);=0A=
@@ -6420,7 +6478,11 @@=0A=
 	IWN_SETBITS(sc, IWN_FH_TX_CHICKEN, IWN_FH_TX_CHICKEN_SCHED_RETRY);=0A=
 =0A=
 	/* Enable chain mode for all queues, except command queue. */=0A=
-	iwn_prph_write(sc, IWN5000_SCHED_QCHAIN_SEL, 0xfffef);=0A=
+	if(sc->sc_flags & IWN_FLAG_PAN_SUPPORT)=0A=
+		iwn_prph_write(sc, IWN5000_SCHED_QCHAIN_SEL, 0xffdff);=0A=
+	else=0A=
+		iwn_prph_write(sc, IWN5000_SCHED_QCHAIN_SEL, 0xfffef);=0A=
+=0A=
 	iwn_prph_write(sc, IWN5000_SCHED_AGGR_SEL, 0);=0A=
 =0A=
 	for (qid =3D 0; qid < IWN5000_NTXQUEUES; qid++) {=0A=
@@ -6440,11 +6502,20 @@=0A=
 	/* Identify TX FIFO rings (0-7). */=0A=
 	iwn_prph_write(sc, IWN5000_SCHED_TXFACT, 0xff);=0A=
 =0A=
-	/* Mark TX rings (4 EDCA + cmd + 2 HCCA) as active. */=0A=
-	for (qid =3D 0; qid < 7; qid++) {=0A=
-		static uint8_t qid2fifo[] =3D { 3, 2, 1, 0, 7, 5, 6 };=0A=
-		iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),=0A=
-		    IWN5000_TXQ_STATUS_ACTIVE | qid2fifo[qid]);=0A=
+	if(sc->sc_flags & IWN_FLAG_PAN_SUPPORT) {=0A=
+		/* Mark TX rings as active. */=0A=
+		for (qid =3D 0; qid < 11; qid++) {=0A=
+			static uint8_t qid2fifo[] =3D { 3, 2, 1, 0, 0, 4, 2, 5, 4, 7, 5 };=0A=
+			iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),=0A=
+			    IWN5000_TXQ_STATUS_ACTIVE | qid2fifo[qid]);=0A=
+		}=0A=
+	} else {=0A=
+		/* Mark TX rings (4 EDCA + cmd + 2 HCCA) as active. */=0A=
+		for (qid =3D 0; qid < 7; qid++) {=0A=
+			static uint8_t qid2fifo[] =3D { 3, 2, 1, 0, 7, 5, 6 };=0A=
+			iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),=0A=
+				IWN5000_TXQ_STATUS_ACTIVE | qid2fifo[qid]);=0A=
+		}=0A=
 	}=0A=
 	iwn_nic_unlock(sc);=0A=
 =0A=
Index: sys/dev/iwn/if_iwn_pan.c=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
--- sys/dev/iwn/if_iwn_pan.c	(revision 0)=0A=
+++ sys/dev/iwn/if_iwn_pan.c	(working copy)=0A=
@@ -0,0 +1,566 @@=0A=
+/*-=0A=
+ * Copyright (c) 2013 Cedric GROSS <cg@cgross.info>=0A=
+ * Copyright (c) 2011 Intel Corporation=0A=
+ * Copyright (c) 2007-2009=0A=
+ *	Damien Bergamini <damien.bergamini@free.fr>=0A=
+ * Copyright (c) 2008=0A=
+ *	Benjamin Close <benjsc@FreeBSD.org>=0A=
+ * Copyright (c) 2008 Sam Leffler, Errno Consulting=0A=
+ *=0A=
+ * Permission to use, copy, modify, and distribute this software for any=0A=
+ * purpose with or without fee is hereby granted, provided that the =
above=0A=
+ * copyright notice and this permission notice appear in all copies.=0A=
+ *=0A=
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL =
WARRANTIES=0A=
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF=0A=
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE =
FOR=0A=
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY =
DAMAGES=0A=
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN=0A=
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT =
OF=0A=
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.=0A=
+ */=0A=
+=0A=
+#include <sys/cdefs.h>=0A=
+__FBSDID("$FreeBSD$");=0A=
+=0A=
+/*=0A=
+ * Driver for Intel WiFi Link 4965 and 1000/2000/5000/6000 Series 802.11=0A=
+ * network adapters.=0A=
+ */=0A=
+=0A=
+#include "opt_wlan.h"=0A=
+#include "opt_iwn.h"=0A=
+=0A=
+#include <sys/param.h>=0A=
+#include <sys/kernel.h>=0A=
+#include <sys/socket.h>=0A=
+#include <sys/bus.h>=0A=
+#include <sys/endian.h>=0A=
+=0A=
+#include <machine/bus.h>=0A=
+=0A=
+#include <net/if.h>=0A=
+#include <net/if_dl.h>=0A=
+#include <net/if_media.h>=0A=
+=0A=
+#include <net80211/ieee80211_var.h>=0A=
+=0A=
+#include <dev/iwn/if_iwnreg.h>=0A=
+#include <dev/iwn/if_iwnvar.h>=0A=
+=0A=
+#include <dev/iwn/if_iwn_pan.h>=0A=
+=0A=
+static int	iwn_auth_pan(struct iwn_softc *, struct ieee80211vap *);=0A=
+static int	iwn_set_timing_pan(struct iwn_softc *);=0A=
+static int	iwn_run_pan(struct iwn_softc *, struct ieee80211vap *);=0A=
+static int	iwn_config_pan(struct iwn_softc *);=0A=
+static int	iwn_updateedca_pan(struct ieee80211com *);=0A=
+static int	iwn_add_broadcast_node_pan(struct iwn_softc *, int);=0A=
+=0A=
+int=0A=
+iwn_newstate_pan(struct ieee80211vap *vap, enum ieee80211_state nstate,=0A=
+    int arg)=0A=
+{=0A=
+	struct iwn_vap *ivp =3D IWN_VAP(vap);=0A=
+	struct ieee80211com *ic =3D vap->iv_ic;=0A=
+	struct iwn_softc *sc =3D ic->ic_ifp->if_softc;=0A=
+=0A=
+	int error =3D 0;=0A=
+=0A=
+	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);=0A=
+=0A=
+	DPRINTF(sc, IWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,=0A=
+	    ieee80211_state_name[vap->iv_state], ieee80211_state_name[nstate]);=0A=
+=0A=
+	IEEE80211_UNLOCK(ic);=0A=
+	IWN_LOCK(sc);=0A=
+	callout_stop(&sc->calib_to);=0A=
+=0A=
+	sc->rxon =3D &sc->rx_on[IWN_RXON_PAN_CTX];=0A=
+=0A=
+	switch (nstate) {=0A=
+	case IEEE80211_S_ASSOC:=0A=
+		if (vap->iv_state !=3D IEEE80211_S_RUN)=0A=
+			break;=0A=
+		/* FALLTHROUGH */=0A=
+	case IEEE80211_S_AUTH:=0A=
+		if (vap->iv_state =3D=3D IEEE80211_S_AUTH)=0A=
+			break;=0A=
+=0A=
+		/*=0A=
+		 * !AUTH -> AUTH transition requires state reset to handle=0A=
+		 * reassociations correctly.=0A=
+		 */=0A=
+		sc->rxon->associd =3D 0;=0A=
+		sc->rxon->filter &=3D ~htole32(IWN_FILTER_BSS);=0A=
+		sc->calib.state =3D IWN_CALIB_STATE_INIT;=0A=
+=0A=
+		if ((error =3D iwn_auth_pan(sc, vap)) !=3D 0) {=0A=
+			device_printf(sc->sc_dev,=0A=
+			    "%s: could not move to auth state\n", __func__);=0A=
+		}=0A=
+		break;=0A=
+=0A=
+	case IEEE80211_S_SCAN:=0A=
+=0A=
+		if ((error =3D iwn_set_timing_pan(sc)) !=3D 0) {=0A=
+			device_printf(sc->sc_dev,=0A=
+			    "%s: iwn_set_timing_pan error %d\n", __func__, error);=0A=
+			return error;=0A=
+		}=0A=
+=0A=
+		break;=0A=
+=0A=
+	case IEEE80211_S_RUN:=0A=
+=0A=
+		/*=0A=
+		 * RUN -> RUN transition; Just restart the timers.=0A=
+		 */=0A=
+		if (vap->iv_state =3D=3D IEEE80211_S_RUN) {=0A=
+			sc->calib_cnt =3D 0;=0A=
+			break;=0A=
+		}=0A=
+=0A=
+		/*=0A=
+		 * !RUN -> RUN requires setting the association id=0A=
+		 * which is done with a firmware cmd.  We also defer=0A=
+		 * starting the timers until that work is done.=0A=
+		 */=0A=
+		if ((error =3D iwn_run_pan(sc, vap)) !=3D 0) {=0A=
+			device_printf(sc->sc_dev,=0A=
+			    "%s: could not move to run state\n", __func__);=0A=
+		}=0A=
+		break;=0A=
+=0A=
+	case IEEE80211_S_INIT:=0A=
+		sc->calib.state =3D IWN_CALIB_STATE_INIT;=0A=
+		break;=0A=
+=0A=
+	default:=0A=
+		break;=0A=
+	}=0A=
+	IWN_UNLOCK(sc);=0A=
+	IEEE80211_LOCK(ic);=0A=
+	if (error !=3D 0) {=0A=
+		DPRINTF(sc, IWN_DEBUG_TRACE, "->%s end in error\n", __func__);=0A=
+		return error;=0A=
+	}=0A=
+	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s end\n", __func__);=0A=
+	return ivp->iv_newstate(vap, nstate, arg);=0A=
+}=0A=
+=0A=
+static int=0A=
+iwn_auth_pan(struct iwn_softc *sc, struct ieee80211vap *vap)=0A=
+{=0A=
+	struct iwn_ops *ops =3D &sc->ops;=0A=
+	struct ifnet *ifp =3D sc->sc_ifp;=0A=
+	struct ieee80211com *ic =3D ifp->if_l2com;=0A=
+	struct ieee80211_node *ni =3D vap->iv_bss;=0A=
+	int error;=0A=
+	struct iwn_vap *ivp =3D IWN_VAP(vap);=0A=
+=0A=
+	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);=0A=
+=0A=
+	sc->rxon =3D &sc->rx_on[IWN_RXON_PAN_CTX];=0A=
+	IEEE80211_ADDR_COPY(sc->rxon->myaddr, ivp->macaddr);=0A=
+	IEEE80211_ADDR_COPY(sc->rxon->wlap, IF_LLADDR(ifp));=0A=
+	/* Update adapter configuration. */=0A=
+	IEEE80211_ADDR_COPY(sc->rxon->bssid, ni->ni_bssid);=0A=
+	sc->rxon->chan =3D ieee80211_chan2ieee(ic, ni->ni_chan);=0A=
+	sc->rxon->flags =3D htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);=0A=
+	if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))=0A=
+		sc->rxon->flags |=3D htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);=0A=
+	if (ic->ic_flags & IEEE80211_F_SHSLOT)=0A=
+		sc->rxon->flags |=3D htole32(IWN_RXON_SHSLOT);=0A=
+	if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)=0A=
+		sc->rxon->flags |=3D htole32(IWN_RXON_SHPREAMBLE);=0A=
+	if (IEEE80211_IS_CHAN_A(ni->ni_chan)) {=0A=
+		sc->rxon->cck_mask  =3D 0;=0A=
+		sc->rxon->ofdm_mask =3D 0x15;=0A=
+	} else if (IEEE80211_IS_CHAN_B(ni->ni_chan)) {=0A=
+		sc->rxon->cck_mask  =3D 0x03;=0A=
+		sc->rxon->ofdm_mask =3D 0;=0A=
+	} else {=0A=
+		/* Assume 802.11b/g. */=0A=
+		sc->rxon->cck_mask  =3D 0x0f;=0A=
+		sc->rxon->ofdm_mask =3D 0x15;=0A=
+	}=0A=
+	DPRINTF(sc, IWN_DEBUG_STATE, "rxon chan %d flags %x cck %x ofdm %x\n",=0A=
+	    sc->rxon->chan, sc->rxon->flags, sc->rxon->cck_mask,=0A=
+	    sc->rxon->ofdm_mask);=0A=
+	sc->rxon->mode =3D IWN_MODE_2STA;=0A=
+	error =3D iwn_cmd(sc, IWN_CMD_WIPAN_RXON, sc->rxon, sc->rxonsz, 0);=0A=
+	if (error !=3D 0) {=0A=
+		device_printf(sc->sc_dev, "%s: RXON command failed, error %d\n",=0A=
+		    __func__, error);=0A=
+		return error;=0A=
+	}=0A=
+=0A=
+	/* Configuration has changed, set TX power accordingly. */=0A=
+	if ((error =3D ops->set_txpower(sc, ni->ni_chan, 1)) !=3D 0) {=0A=
+		device_printf(sc->sc_dev,=0A=
+		    "%s: could not set TX power, error %d\n", __func__, error);=0A=
+		return error;=0A=
+	}=0A=
+	/*=0A=
+	 * Reconfiguring RXON clears the firmware nodes table so we must=0A=
+	 * add the broadcast node again.=0A=
+	 */=0A=
+	if ((error =3D iwn_add_broadcast_node_pan(sc, 0)) !=3D 0) {=0A=
+		device_printf(sc->sc_dev,=0A=
+		    "%s: could not add broadcast node, error %d\n", __func__,=0A=
+		    error);=0A=
+		return error;=0A=
+	}=0A=
+	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s end\n", __func__);=0A=
+=0A=
+	return 0;=0A=
+}=0A=
+=0A=
+static int=0A=
+iwn_set_timing_pan(struct iwn_softc *sc)=0A=
+{=0A=
+	struct iwn_cmd_timing cmd;=0A=
+	int error =3D 0;=0A=
+	struct ieee80211vap *vap;=0A=
+	struct iwn_vap *ivp;=0A=
+=0A=
+	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);=0A=
+=0A=
+	vap =3D sc->ivap[IWN_RXON_PAN_CTX];=0A=
+	ivp =3D IWN_VAP(vap);=0A=
+=0A=
+	if ((error =3D iwn_config_pan(sc)) !=3D 0) {=0A=
+		device_printf(sc->sc_dev,=0A=
+		    "%s: iwn_config1 error %d\n", __func__, error);=0A=
+		return error;=0A=
+	}=0A=
+=0A=
+	if ((error =3D iwn_set_pan_params(sc)) !=3D 0) {=0A=
+		device_printf(sc->sc_dev,=0A=
+		    "%s: iwn_set_pan_params error %d\n", __func__, error);=0A=
+		return error;=0A=
+	}=0A=
+=0A=
+	memset(&cmd, 0, sizeof cmd);=0A=
+	cmd.lintval =3D htole16(10);=0A=
+	cmd.bintval =3D htole16(IWN_BEACON_INTERVAL_DEFAULT);=0A=
+	ivp->beacon_int =3D cmd.bintval;=0A=
+	cmd.binitval =3D htole32(0x032000);=0A=
+	cmd.dtim_period =3D 1;=0A=
+=0A=
+	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s end\n", __func__);=0A=
+=0A=
+	return iwn_cmd(sc, IWN_CMD_WIPAN_RXON_TIMING, &cmd, sizeof cmd, 0);=0A=
+}=0A=
+static int=0A=
+iwn_run_pan(struct iwn_softc *sc, struct ieee80211vap *vap)=0A=
+{=0A=
+	struct iwn_ops *ops =3D &sc->ops;=0A=
+	struct ifnet *ifp =3D sc->sc_ifp;=0A=
+	struct ieee80211com *ic =3D ifp->if_l2com;=0A=
+	struct ieee80211_node *ni =3D vap->iv_bss;=0A=
+	struct iwn_vap *ivp =3D IWN_VAP(vap);=0A=
+	struct iwn_node_info node;=0A=
+	uint32_t htflags =3D 0;=0A=
+	int error;=0A=
+=0A=
+	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);=0A=
+=0A=
+	if (ic->ic_opmode =3D=3D IEEE80211_M_MONITOR) {=0A=
+		/* Link LED blinks while monitoring. */=0A=
+		return 0;=0A=
+	}=0A=
+=0A=
+	if ((error =3D iwn_set_timing_pan(sc)) !=3D 0) {=0A=
+		device_printf(sc->sc_dev,=0A=
+		    "%s: could not set timing, error %d\n", __func__, error);=0A=
+	}=0A=
+=0A=
+	if ((error =3D iwn_updateedca_pan(ic)) !=3D 0) {=0A=
+		device_printf(sc->sc_dev,=0A=
+		    "%s: iwn_updateedca_pan, error %d\n", __func__, error);=0A=
+		return error;=0A=
+	}=0A=
+=0A=
+	sc->rxon =3D &sc->rx_on[IWN_RXON_PAN_CTX];=0A=
+	IEEE80211_ADDR_COPY(sc->rxon->myaddr, ivp->macaddr);=0A=
+	IEEE80211_ADDR_COPY(sc->rxon->wlap, IF_LLADDR(ifp));=0A=
+	/* Update adapter configuration. */=0A=
+	IEEE80211_ADDR_COPY(sc->rxon->bssid, ni->ni_bssid);=0A=
+	sc->rxon->associd =3D htole16(IEEE80211_AID(ni->ni_associd));=0A=
+	sc->rxon->chan =3D ieee80211_chan2ieee(ic, ni->ni_chan);=0A=
+	sc->rxon->flags =3D htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);=0A=
+	if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))=0A=
+		sc->rxon->flags |=3D htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);=0A=
+	if (ic->ic_flags & IEEE80211_F_SHSLOT)=0A=
+		sc->rxon->flags |=3D htole32(IWN_RXON_SHSLOT);=0A=
+	if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)=0A=
+		sc->rxon->flags |=3D htole32(IWN_RXON_SHPREAMBLE);=0A=
+	if (IEEE80211_IS_CHAN_A(ni->ni_chan)) {=0A=
+		sc->rxon->cck_mask  =3D 0;=0A=
+		sc->rxon->ofdm_mask =3D 0x15;=0A=
+	} else if (IEEE80211_IS_CHAN_B(ni->ni_chan)) {=0A=
+		sc->rxon->cck_mask  =3D 0x03;=0A=
+		sc->rxon->ofdm_mask =3D 0;=0A=
+	} else {=0A=
+		/* Assume 802.11b/g. */=0A=
+		sc->rxon->cck_mask  =3D 0x0f;=0A=
+		sc->rxon->ofdm_mask =3D 0x15;=0A=
+	}=0A=
+	if (IEEE80211_IS_CHAN_HT(ni->ni_chan)) {=0A=
+		htflags |=3D IWN_RXON_HT_PROTMODE(ic->ic_curhtprotmode);=0A=
+		if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) {=0A=
+			switch (ic->ic_curhtprotmode) {=0A=
+			case IEEE80211_HTINFO_OPMODE_HT20PR:=0A=
+				htflags |=3D IWN_RXON_HT_MODEPURE40;=0A=
+				break;=0A=
+			default:=0A=
+				htflags |=3D IWN_RXON_HT_MODEMIXED;=0A=
+				break;=0A=
+			}=0A=
+		}=0A=
+		if (IEEE80211_IS_CHAN_HT40D(ni->ni_chan))=0A=
+			htflags |=3D IWN_RXON_HT_HT40MINUS;=0A=
+	}=0A=
+	sc->rxon->flags |=3D htole32(htflags);=0A=
+	sc->rxon->filter |=3D htole32(IWN_FILTER_BSS);=0A=
+	DPRINTF(sc, IWN_DEBUG_STATE, "rxon chan %d flags %x\n",=0A=
+	    sc->rxon->chan, sc->rxon->flags);=0A=
+	sc->rxon->mode =3D IWN_MODE_2STA;=0A=
+	error =3D iwn_cmd(sc, IWN_CMD_WIPAN_RXON, sc->rxon, sc->rxonsz, 0);=0A=
+	if (error !=3D 0) {=0A=
+		device_printf(sc->sc_dev,=0A=
+		    "%s: could not update configuration, error %d\n", __func__,=0A=
+		    error);=0A=
+		return error;=0A=
+	}=0A=
+=0A=
+	/* Configuration has changed, set TX power accordingly. */=0A=
+	if ((error =3D ops->set_txpower(sc, ni->ni_chan, 1)) !=3D 0) {=0A=
+		device_printf(sc->sc_dev,=0A=
+		    "%s: could not set TX power, error %d\n", __func__, error);=0A=
+		return error;=0A=
+	}=0A=
+=0A=
+	/* Fake a join to initialize the TX rate. */=0A=
+	((struct iwn_node *)ni)->id =3D IWN_STA_ID;=0A=
+	iwn_newassoc(ni, 1);=0A=
+=0A=
+	/* Add BSS node. */=0A=
+	memset(&node, 0, sizeof node);=0A=
+	node.htflags |=3D htole32(IWN_STA_FLAG_PAN_STATION);=0A=
+	IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);=0A=
+	node.id =3D IWN_STA_ID;=0A=
+	if (IEEE80211_IS_CHAN_HT(ni->ni_chan)) {=0A=
+		switch (ni->ni_htcap & IEEE80211_HTCAP_SMPS) {=0A=
+		case IEEE80211_HTCAP_SMPS_ENA:=0A=
+			node.htflags |=3D htole32(IWN_SMPS_MIMO_DIS);=0A=
+			break;=0A=
+		case IEEE80211_HTCAP_SMPS_DYNAMIC:=0A=
+			node.htflags |=3D htole32(IWN_SMPS_MIMO_PROT);=0A=
+			break;=0A=
+		}=0A=
+		node.htflags |=3D htole32(IWN_AMDPU_SIZE_FACTOR(3) |=0A=
+		    IWN_AMDPU_DENSITY(5));	/* 4us */=0A=
+		if (IEEE80211_IS_CHAN_HT40(ni->ni_chan))=0A=
+			node.htflags |=3D htole32(IWN_NODE_HT40);=0A=
+	}=0A=
+	DPRINTF(sc, IWN_DEBUG_STATE, "%s: adding BSS node1\n", __func__);=0A=
+	error =3D ops->add_node(sc, &node, 0);=0A=
+	if (error !=3D 0) {=0A=
+		device_printf(sc->sc_dev,=0A=
+		    "%s: could not add BSS node1, error %d\n", __func__, error);=0A=
+		return error;=0A=
+	}=0A=
+=0A=
+	/* Setting the initial rate for node */=0A=
+	ni->ni_txrate =3D ni->ni_rates.rs_rates[0];=0A=
+=0A=
+	/* XXX: init rate scaling */=0A=
+=0A=
+	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s end\n", __func__);=0A=
+=0A=
+#ifdef IWN_DTIM_INDICATES_UNICAST_PENDING_AT_AP=0A=
+	return iwn_set_pslevel(sc, IWN_POWERSAVE_DTIM_VOIP_COMPATIBLE,=0A=
+	    sc->desired_pwrsave_level, 0);=0A=
+#else=0A=
+	return 0;=0A=
+#endif=0A=
+=0A=
+}=0A=
+=0A=
+static int=0A=
+iwn_config_pan(struct iwn_softc *sc)=0A=
+{=0A=
+	struct ifnet *ifp =3D sc->sc_ifp;=0A=
+	struct ieee80211com *ic =3D ifp->if_l2com;=0A=
+	struct ieee80211vap *vap =3D sc->ivap[IWN_RXON_PAN_CTX];=0A=
+	struct iwn_vap *ivp =3D IWN_VAP(vap);=0A=
+	uint16_t rxchain;=0A=
+	int error;=0A=
+=0A=
+	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);=0A=
+=0A=
+	sc->rxon =3D &sc->rx_on[IWN_RXON_PAN_CTX];=0A=
+	IEEE80211_ADDR_COPY(sc->rxon->myaddr, ivp->macaddr);=0A=
+	IEEE80211_ADDR_COPY(sc->rxon->wlap, IF_LLADDR(ifp));=0A=
+	sc->rxon->chan =3D ieee80211_chan2ieee(ic, ic->ic_curchan);=0A=
+	sc->rxon->flags =3D htole32(IWN_RXON_TSF);=0A=
+	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))=0A=
+		sc->rxon->flags |=3D htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);=0A=
+	sc->rxon->mode =3D IWN_MODE_P2P;=0A=
+	sc->rxon->filter =3D htole32(IWN_FILTER_MULTICAST);=0A=
+	sc->rxon->cck_mask  =3D 0x0f;	/* not yet negotiated */=0A=
+	sc->rxon->ofdm_mask =3D 0xff;	/* not yet negotiated */=0A=
+	sc->rxon->ht_single_mask =3D 0xff;=0A=
+	sc->rxon->ht_dual_mask =3D 0xff;=0A=
+	sc->rxon->ht_triple_mask =3D 0xff;=0A=
+	rxchain =3D=0A=
+	    IWN_RXCHAIN_VALID(sc->rxchainmask) |=0A=
+	    IWN_RXCHAIN_MIMO_COUNT(2) |=0A=
+	    IWN_RXCHAIN_IDLE_COUNT(2);=0A=
+	sc->rxon->rxchain =3D htole16(rxchain);=0A=
+	sc->rxon->associd =3D 0;=0A=
+	sc->rxon->filter &=3D ~htole32(IWN_FILTER_BSS);=0A=
+=0A=
+	error =3D iwn_cmd(sc, IWN_CMD_WIPAN_RXON, sc->rxon, sc->rxonsz, 0);=0A=
+	if (error !=3D 0) {=0A=
+		device_printf(sc->sc_dev, "%s: IWN_CMD_WIPAN_RXON command failed\n",=0A=
+		    __func__);=0A=
+		return error;=0A=
+	}=0A=
+	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s end\n", __func__);=0A=
+=0A=
+	return 0;=0A=
+}=0A=
+=0A=
+int=0A=
+iwn_set_pan_params(struct iwn_softc *sc)=0A=
+{=0A=
+	struct iwn_pan_params_cmd cmd;=0A=
+	int slot0 =3D 300, slot1 =3D 0;=0A=
+	int bcnint;=0A=
+	int error =3D 0;=0A=
+=0A=
+	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);=0A=
+=0A=
+	/*=0A=
+	 * If the PAN context is inactive, then we don't need=0A=
+	 * to update the PAN parameters=0A=
+	 */=0A=
+	if (sc->ctx !=3D IWN_RXON_PAN_CTX) {=0A=
+		DPRINTF(sc, IWN_DEBUG_TRACE, "->%s end with no need to do that\n",=0A=
+		    __func__);=0A=
+		return 0;=0A=
+	}=0A=
+=0A=
+	memset(&cmd, 0, sizeof(cmd));=0A=
+=0A=
+	/* only 2 slots are currently allowed */=0A=
+	cmd.num_slots =3D 2;=0A=
+=0A=
+	cmd.slots[0].type =3D IWN_RXON_BSS_CTX;	/* BSS */=0A=
+	cmd.slots[1].type =3D IWN_RXON_PAN_CTX;	/* PAN */=0A=
+=0A=
+	cmd.flags |=3D htole16(IWN_PAN_PARAMS_FLG_SLOTTED_MODE);=0A=
+	bcnint =3D IWN_BEACON_INTERVAL_DEFAULT;=0A=
+	slot0 =3D (bcnint >> 1);=0A=
+	slot1 =3D (bcnint - slot0);=0A=
+=0A=
+	if(sc->uc_scan_progress =3D=3D 1) {=0A=
+		slot0 =3D bcnint * 3 - IWN_SLOT_TIME_MIN;=0A=
+		slot1 =3D IWN_SLOT_TIME_MIN;=0A=
+	}=0A=
+	cmd.slots[0].time =3D htole16(slot0);=0A=
+	cmd.slots[1].time =3D htole16(slot1);=0A=
+=0A=
+	error =3D iwn_cmd(sc, IWN_CMD_WIPAN_PARAMS, &cmd, sizeof(cmd), 0);=0A=
+	if (error !=3D 0) {=0A=
+		device_printf(sc->sc_dev,=0A=
+		    "%s: IWN_CMD_WIPAN_PARAMS command failed, error %d\n",=0A=
+		    __func__, error);=0A=
+		return error;=0A=
+	}=0A=
+=0A=
+	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s end\n", __func__);=0A=
+=0A=
+	return 0;=0A=
+}=0A=
+=0A=
+static int=0A=
+iwn_updateedca_pan(struct ieee80211com *ic)=0A=
+{=0A=
+#define IWN_EXP2(x)	((1 << (x)) - 1)	/* CWmin =3D 2^ECWmin - 1 */=0A=
+	struct iwn_softc *sc =3D ic->ic_ifp->if_softc;=0A=
+	struct iwn_edca_params cmd;=0A=
+	int aci;=0A=
+=0A=
+	memset(&cmd, 0, sizeof cmd);=0A=
+	cmd.flags =3D htole32(IWN_EDCA_UPDATE);=0A=
+	for (aci =3D 0; aci < WME_NUM_AC; aci++) {=0A=
+		const struct wmeParams *ac =3D=0A=
+		    &ic->ic_wme.wme_chanParams.cap_wmeParams[aci];=0A=
+		cmd.ac[aci].aifsn =3D ac->wmep_aifsn;=0A=
+		cmd.ac[aci].cwmin =3D htole16(IWN_EXP2(ac->wmep_logcwmin));=0A=
+		cmd.ac[aci].cwmax =3D htole16(IWN_EXP2(ac->wmep_logcwmax));=0A=
+		cmd.ac[aci].txoplimit =3D=0A=
+		    htole16(IEEE80211_TXOP_TO_US(ac->wmep_txopLimit));=0A=
+	}=0A=
+	return iwn_cmd(sc, IWN_CMD_WIPAN_QOS_PARAM, &cmd, sizeof cmd, 1);=0A=
+#undef IWN_EXP2=0A=
+}=0A=
+=0A=
+/*=0A=
+ * Broadcast node is used to send group-addressed and management frames.=0A=
+ */=0A=
+static int=0A=
+iwn_add_broadcast_node_pan(struct iwn_softc *sc, int async)=0A=
+{=0A=
+	struct iwn_ops *ops =3D &sc->ops;=0A=
+	struct ifnet *ifp =3D sc->sc_ifp;=0A=
+	struct ieee80211com *ic =3D ifp->if_l2com;=0A=
+	struct iwn_node_info node;=0A=
+	struct iwn_cmd_link_quality linkq;=0A=
+	uint8_t txant;=0A=
+	int i, error;=0A=
+=0A=
+	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);=0A=
+=0A=
+	sc->rxon =3D &sc->rx_on[IWN_RXON_PAN_CTX];=0A=
+=0A=
+	memset(&node, 0, sizeof node);=0A=
+	IEEE80211_ADDR_COPY(node.macaddr, ifp->if_broadcastaddr);=0A=
+=0A=
+	node.id =3D IWN_PAN_ID_BCAST;=0A=
+	node.htflags |=3D htole32(IWN_STA_FLAG_PAN_STATION);=0A=
+	DPRINTF(sc, IWN_DEBUG_RESET, "%s: adding broadcast node1\n", __func__);=0A=
+	if ((error =3D ops->add_node(sc, &node, async)) !=3D 0)=0A=
+		return error;=0A=
+=0A=
+	/* Use the first valid TX antenna. */=0A=
+	txant =3D IWN_LSB(sc->txchainmask);=0A=
+=0A=
+	memset(&linkq, 0, sizeof linkq);=0A=
+	linkq.id =3D IWN_PAN_ID_BCAST;=0A=
+	linkq.antmsk_1stream =3D txant;=0A=
+	linkq.antmsk_2stream =3D IWN_ANT_AB;=0A=
+	linkq.ampdu_max =3D 64;=0A=
+	linkq.ampdu_threshold =3D 3;=0A=
+	linkq.ampdu_limit =3D htole16(4000);	/* 4ms */=0A=
+=0A=
+	/* Use lowest mandatory bit-rate. */=0A=
+	if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))=0A=
+		linkq.retry[0] =3D htole32(0xd);=0A=
+	else=0A=
+		linkq.retry[0] =3D htole32(10 | IWN_RFLAG_CCK);=0A=
+	linkq.retry[0] |=3D htole32(IWN_RFLAG_ANT(txant));=0A=
+	/* Use same bit-rate for all TX retries. */=0A=
+	for (i =3D 1; i < IWN_MAX_TX_RETRIES; i++) {=0A=
+		linkq.retry[i] =3D linkq.retry[0];=0A=
+	}=0A=
+	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s end\n", __func__);=0A=
+=0A=
+	return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, async);=0A=
+}=0A=
+=0A=
Index: sys/dev/iwn/if_iwn_pan.h=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
--- sys/dev/iwn/if_iwn_pan.h	(revision 0)=0A=
+++ sys/dev/iwn/if_iwn_pan.h	(working copy)=0A=
@@ -0,0 +1,34 @@=0A=
+/*-=0A=
+ * Copyright (c) 2013 Cedric GROSS <cg@cgross.info>=0A=
+ *=0A=
+ * Permission to use, copy, modify, and distribute this software for any=0A=
+ * purpose with or without fee is hereby granted, provided that the =
above=0A=
+ * copyright notice and this permission notice appear in all copies.=0A=
+ *=0A=
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL =
WARRANTIES=0A=
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF=0A=
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE =
FOR=0A=
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY =
DAMAGES=0A=
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN=0A=
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT =
OF=0A=
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.=0A=
+ *=0A=
+ * $FreeBSD$=0A=
+ */=0A=
+=0A=
+#ifndef	__IF_IWN_PAN_H__=0A=
+#define	__IF_IWN_PAN_H__=0A=
+/*=0A=
+ * ADD / MODIFY STATION Command (Op Code 18) -  byte 76-18 -bit13=0A=
+ * STA_FLAG_PAN_STATION bit:=0A=
+ * This bit is set (1) for a station in PAN mode=0A=
+ */=0A=
+#define IWN_STA_FLAG_PAN_STATION		(1 << 13)=0A=
+=0A=
+#define IWN_BEACON_INTERVAL_DEFAULT		200=0A=
+#define IWN_SLOT_TIME_MIN		20=0A=
+=0A=
+extern	int iwn_newstate_pan(struct ieee80211vap *, enum =
ieee80211_state, int);=0A=
+extern	int iwn_set_pan_params(struct iwn_softc *);=0A=
+=0A=
+#endif=0A=
Index: sys/dev/iwn/if_iwnreg.h=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
--- sys/dev/iwn/if_iwnreg.h	(revision 254271)=0A=
+++ sys/dev/iwn/if_iwnreg.h	(working copy)=0A=
@@ -2052,3 +2052,36 @@=0A=
 #define IWN_BARRIER_READ_WRITE(sc)					\=0A=
 	bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, (sc)->sc_sz,	\=0A=
 	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE)=0A=
+=0A=
+#ifdef	IWN_DEBUG=0A=
+enum {=0A=
+	IWN_DEBUG_XMIT		=3D 0x00000001,	/* basic xmit operation */=0A=
+	IWN_DEBUG_RECV		=3D 0x00000002,	/* basic recv operation */=0A=
+	IWN_DEBUG_STATE		=3D 0x00000004,	/* 802.11 state transitions */=0A=
+	IWN_DEBUG_TXPOW		=3D 0x00000008,	/* tx power processing */=0A=
+	IWN_DEBUG_RESET		=3D 0x00000010,	/* reset processing */=0A=
+	IWN_DEBUG_OPS		=3D 0x00000020,	/* iwn_ops processing */=0A=
+	IWN_DEBUG_BEACON	=3D 0x00000040,	/* beacon handling */=0A=
+	IWN_DEBUG_WATCHDOG 	=3D 0x00000080,	/* watchdog timeout */=0A=
+	IWN_DEBUG_INTR		=3D 0x00000100,	/* ISR */=0A=
+	IWN_DEBUG_CALIBRATE	=3D 0x00000200,	/* periodic calibration */=0A=
+	IWN_DEBUG_NODE		=3D 0x00000400,	/* node management */=0A=
+	IWN_DEBUG_LED		=3D 0x00000800,	/* led management */=0A=
+	IWN_DEBUG_CMD		=3D 0x00001000,	/* cmd submission */=0A=
+	IWN_DEBUG_TXRATE	=3D 0x00002000,	/* TX rate debugging */=0A=
+	IWN_DEBUG_PWRSAVE	=3D 0x00004000,	/* Power save operations */=0A=
+	IWN_DEBUG_REGISTER	=3D 0x20000000,	/* print chipset register */=0A=
+	IWN_DEBUG_TRACE		=3D 0x40000000,	/* Print begin and start driver =
function */=0A=
+	IWN_DEBUG_FATAL		=3D 0x80000000,	/* fatal errors */=0A=
+	IWN_DEBUG_ANY		=3D 0xffffffff=0A=
+};=0A=
+=0A=
+#define DPRINTF(sc, m, fmt, ...) do {			\=0A=
+	if (sc->sc_debug & (m))				\=0A=
+		printf(fmt, __VA_ARGS__);		\=0A=
+} while (0)=0A=
+=0A=
+#else=0A=
+#define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)=0A=
+#endif=0A=
+=0A=
Index: sys/dev/iwn/if_iwnvar.h=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
--- sys/dev/iwn/if_iwnvar.h	(revision 254271)=0A=
+++ sys/dev/iwn/if_iwnvar.h	(working copy)=0A=
@@ -391,6 +391,12 @@=0A=
 	struct iwn_base_params *base_params;=0A=
 };=0A=
 =0A=
+extern	int iwn_cmd(struct iwn_softc *, int, const void *, int, int);=0A=
+extern	void iwn_newassoc(struct ieee80211_node *, int);=0A=
+#ifdef	IWN_DEBUG=0A=
+extern	const char *iwn_intr_str(uint8_t);=0A=
+#endif=0A=
+=0A=
 #define IWN_LOCK_INIT(_sc) \=0A=
 	mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \=0A=
 	    MTX_NETWORK_LOCK, MTX_DEF)=0A=
Index: sys/modules/iwn/Makefile=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
--- sys/modules/iwn/Makefile	(revision 254271)=0A=
+++ sys/modules/iwn/Makefile	(working copy)=0A=
@@ -3,6 +3,7 @@=0A=
 .PATH:  ${.CURDIR}/../../dev/iwn=0A=
 =0A=
 KMOD    =3D if_iwn=0A=
-SRCS    =3D if_iwn.c device_if.h bus_if.h pci_if.h opt_iwn.h opt_wlan.h=0A=
+SRCS    =3D if_iwn.c if_iwn_pan.c device_if.h bus_if.h pci_if.h=0A=
+SRCS	+=3D opt_iwn.h opt_wlan.h=0A=
 =0A=
 .include <bsd.kmod.mk>=0A=

------=_NextPart_000_000D_01CE9804.A3A05D10--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?000c01ce97f3$e0178d10$a046a730$>