From owner-freebsd-wireless@FreeBSD.ORG Sun Aug 11 13:09:59 2013 Return-Path: Delivered-To: freebsd-wireless@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 77B7F7DE for ; Sun, 11 Aug 2013 13:09:59 +0000 (UTC) (envelope-from cg@cgross.info) Received: from alpha.kreiz-it.fr (alpha.kreiz-it.fr [IPv6:2001:41d0:8:dda6::1]) by mx1.freebsd.org (Postfix) with ESMTP id 8D31F24AB for ; Sun, 11 Aug 2013 13:09:58 +0000 (UTC) Received: from DirTech (lnr56-1-82-246-51-185.fbx.proxad.net [82.246.51.185]) by alpha.kreiz-it.fr (Postfix) with ESMTPSA id 9CF851B3 for ; Sun, 11 Aug 2013 15:09:56 +0200 (CEST) From: "Cedric GROSS" To: Subject: [iwn]Review Split 6 Date: Sun, 11 Aug 2013 15:09:54 +0200 Message-ID: <001d01ce9694$142db8b0$3c892a10$@info> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_001E_01CE96A4.D7B688B0" X-Mailer: Microsoft Office Outlook 12.0 Thread-Index: Ac6WlBJVX/p7JGXXQomXWq855xMLrA== Content-Language: fr X-Content-Filtered-By: Mailman/MimeDel 2.1.14 X-BeenThere: freebsd-wireless@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Discussions of 802.11 stack, tools device driver development." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 11 Aug 2013 13:09:59 -0000 This is a multi-part message in MIME format. ------=_NextPart_000_001E_01CE96A4.D7B688B0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Hello, Here is patch split 6. It's follow split 5 as it implement PAN context. This patch is purely based on work done by Sean Bruno. Cedric ------=_NextPart_000_001E_01CE96A4.D7B688B0 Content-Type: application/octet-stream; name="pan.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="pan.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 254210)=0A= +++ sys/dev/iwn/if_iwn.c (working copy)=0A= @@ -330,7 +330,16 @@=0A= static char *iwn_get_csr_string(int);=0A= static void iwn_debug_register(struct iwn_softc *);=0A= #endif=0A= +static int iwn_newstate_u1(struct ieee80211vap *, enum ieee80211_state, = int);=0A= +static int iwn_auth_u1(struct iwn_softc *, struct ieee80211vap *);=0A= +static int iwn_run_u1(struct iwn_softc *, struct ieee80211vap *);=0A= +static int iwn_set_timing_u1(struct iwn_softc *);=0A= +static int iwn_config_u1(struct iwn_softc *);=0A= +static int iwn_set_pan_params(struct iwn_softc *);=0A= +static int iwn_updateedca_u1(struct ieee80211com *);=0A= +static int iwn_add_broadcast_node_u1(struct iwn_softc *, int);=0A= =0A= +=0A= #ifdef IWN_DEBUG=0A= enum {=0A= IWN_DEBUG_XMIT =3D 0x00000001, /* basic xmit operation */=0A= @@ -919,6 +928,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 +941,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_u1;=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 +974,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= @@ -2794,6 +2828,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 +2840,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 +3035,20 @@=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= +=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 +3204,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 +3237,10 @@=0A= {=0A= struct iwn_beacon_missed *miss =3D=0A= (struct iwn_beacon_missed *)(desc + 1);=0A= - int misses;=0A= + int misses,iv_bmissthreshold;=0A= + int DoReinit =3D0 ;=0A= + struct ieee80211vap *vap0 =3D sc->ivap[IWN_RXON_BSS_CTX];=0A= + struct ieee80211vap *vap1 =3D sc->ivap[IWN_RXON_PAN_CTX];=0A= =0A= bus_dmamap_sync(sc->rxq.data_dmat, data->map,=0A= BUS_DMASYNC_POSTREAD);=0A= @@ -3194,17 +3247,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 +3635,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 +3668,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 +3777,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 +3812,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 +3929,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 +4019,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= @@ -4207,13 +4283,13 @@=0A= static 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 +4296,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 +5628,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 +5644,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 +5680,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 +5721,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 +5873,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 +6521,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 +6545,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= @@ -7621,3 +7735,510 @@=0A= DPRINTF(sc, IWN_DEBUG_REGISTER,"%s","\n");=0A= }=0A= #endif=0A= +static int=0A= +iwn_newstate_u1(struct ieee80211vap *vap, enum ieee80211_state nstate, = 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_u1(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= +=0A= + if ((error =3D iwn_set_timing_u1(sc)) !=3D 0) {=0A= + device_printf(sc->sc_dev,=0A= + "%s: iwn_set_timing_u1 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_u1(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_u1(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_u1(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_run_u1(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_node_info node;=0A= + uint32_t htflags =3D 0;=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= + 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_u1(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_u1(ic)) !=3D 0) {=0A= + device_printf(sc->sc_dev,=0A= + "%s: iwn_updateedca_u1, 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_set_timing_u1(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_u1(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= +=0A= +static int=0A= +iwn_config_u1(struct iwn_softc *sc)=0A= +{=0A= + struct ifnet *ifp =3D sc->sc_ifp;=0A= + struct ieee80211com *ic =3D ifp->if_l2com;=0A= + uint16_t rxchain;=0A= + int error;=0A= + struct ieee80211vap *vap =3D sc->ivap[IWN_RXON_PAN_CTX];=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= + 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= +static 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_u1(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_u1(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= 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 254210)=0A= +++ sys/dev/iwn/if_iwnreg.h (working copy)=0A= @@ -1689,6 +1689,16 @@=0A= } __packed;=0A= =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= +/*=0A= * Offsets of channels descriptions in EEPROM.=0A= */=0A= static const uint32_t iwn4965_regulatory_bands[IWN_NBANDS] =3D {=0A= ------=_NextPart_000_001E_01CE96A4.D7B688B0--