tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

athn(4) usb patch



Hi Martin,

Here's a debugged version of the first patch I made for athn at usb
(the original ones don't work).  The AR9271 dongle I ordered arrived
sooner than I expected, so I've had it for a while.

I don't have it working yet with usbwifi (also, it needs an interrupt
pipe before usbwifi ever opens it), although my attempt at that was
quite crude to begin with.

Also my PGP key and account details are sorted; just don't think the
agreement arrived in the US yet.

Jeandre
diff -r e7067aff72a8 sys/dev/ic/athn.c
--- a/sys/dev/ic/athn.c	Fri Aug 11 16:08:59 2023 -0700
+++ b/sys/dev/ic/athn.c	Sat Sep 30 20:27:59 2023 +1300
@@ -119,11 +119,6 @@
 Static int	athn_transmit(struct ieee80211com *, struct mbuf *);
 Static void	athn_get_radiocaps(struct ieee80211com *,
 		    int, int *, struct ieee80211_channel []);
-Static struct ieee80211vap *
-		athn_vap_create(struct ieee80211com *,  const char [IFNAMSIZ],
-		    int, enum ieee80211_opmode, int,
-		    const uint8_t [IEEE80211_ADDR_LEN],
-		    const uint8_t [IEEE80211_ADDR_LEN]);
 Static void athn_vap_delete(struct ieee80211vap *);
 
 #ifdef ATHN_BT_COEXISTENCE
@@ -145,12 +140,6 @@
 #endif /* notyet */
 Static void	athn_set_multi(struct ieee80211com *);
 
-struct athn_vap {
-	struct ieee80211vap vap;
-	int (*newstate)(struct ieee80211vap *, enum ieee80211_state, int);
-	callout_t av_scan_to;
-};
-
 PUBLIC int
 athn_attach(struct athn_softc *sc)
 {
@@ -2403,6 +2392,7 @@
 {
 	struct athn_node *an = (void *)ni;
 	struct ieee80211_rateset *rs = &ni->ni_rates;
+	struct athn_softc *sc = ni->ni_ic->ic_softc;
 	uint8_t rate;
 	int ridx, i, j;
 
@@ -2694,7 +2684,7 @@
 		}
 
 		sc->sc_tx_timer = 5;
-		callout_reset(&sc->sc_watchdog_to, hz, athn_watchdog, sc);
+		callout_schedule(&sc->sc_watchdog_to, hz);
 	}
 }
 
@@ -2712,7 +2702,7 @@
 			ieee80211_stat_add(&sc->sc_ic.ic_oerrors, 1);
 			return;
 		}
-		callout_reset(&sc->sc_watchdog_to, hz, athn_watchdog, sc);
+		callout_schedule(&sc->sc_watchdog_to, hz);
 	}
 }
 
@@ -3053,7 +3043,7 @@
 	struct athn_softc *sc = ic->ic_softc;
 	int s;
 
-	DPRINTFN(5, ("%s: %s\n",ic->ic_name, __func__));
+	/* DPRINTFN(5, ("%s: %s\n",ic->ic_name, __func__)); */
 
 	s = splnet();
 	IF_ENQUEUE(&sc->sc_sendq, m);
@@ -3106,7 +3096,7 @@
 		ieee80211_start_all(ic);
 }
 
-static struct ieee80211vap *
+struct ieee80211vap *
 athn_vap_create(struct ieee80211com *ic,  const char name[IFNAMSIZ],
     int unit, enum ieee80211_opmode opmode, int flags,
     const uint8_t bssid[IEEE80211_ADDR_LEN],
@@ -3137,7 +3127,8 @@
 	ifp = vap->vap.iv_ifp;
 
 	/* Use common softint-based if_input */
-	ifp->if_percpuq = if_percpuq_create(ifp);
+	if (!(sc->sc_flags & ATHN_FLAG_USB))
+		ifp->if_percpuq = if_percpuq_create(ifp);
 
 	/* Override state transition machine. */
 	vap->newstate = vap->vap.iv_newstate;
@@ -3169,7 +3160,7 @@
 	struct ifnet *ifp = arg->iv_ifp;
 	struct athn_vap *vap = (struct athn_vap *)arg;
 
-	DPRINTFN(5, ("%s: %s\n", ifp->if_xname, __func__));
+	/* DPRINTFN(5, ("%s: %s\n", ifp->if_xname, __func__)); */
 
 	callout_halt(&vap->av_scan_to, NULL);
 	callout_destroy(&vap->av_scan_to);
diff -r e7067aff72a8 sys/dev/ic/athnvar.h
--- a/sys/dev/ic/athnvar.h	Fri Aug 11 16:08:59 2023 -0700
+++ b/sys/dev/ic/athnvar.h	Sat Sep 30 20:27:59 2023 +1300
@@ -318,6 +318,12 @@
 #define ATHN_POWER_OFDM_EXT	67
 #define ATHN_POWER_COUNT	68
 
+struct athn_vap {
+	struct ieee80211vap vap;
+	int (*newstate)(struct ieee80211vap *, enum ieee80211_state, int);
+	callout_t av_scan_to;
+};
+
 struct athn_node {
 	struct ieee80211_node	ni;
 	uint8_t		ridx[IEEE80211_RATE_MAXSIZE];
@@ -646,6 +652,11 @@
 void	athn_set_rxfilter(struct athn_softc *, uint32_t);
 void	athn_set_sta_timers(struct ieee80211vap *);
 void	athn_updateslot(struct ieee80211com *);
+struct ieee80211vap *
+	athn_vap_create(struct ieee80211com *,  const char [IFNAMSIZ],
+	    int, enum ieee80211_opmode, int,
+	    const uint8_t [IEEE80211_ADDR_LEN],
+	    const uint8_t [IEEE80211_ADDR_LEN]);
 
 #ifdef notyet_edca
 void	athn_updateedca(struct ieee80211com *);
diff -r e7067aff72a8 sys/dev/usb/if_athn_usb.c
--- a/sys/dev/usb/if_athn_usb.c	Fri Aug 11 16:08:59 2023 -0700
+++ b/sys/dev/usb/if_athn_usb.c	Sat Sep 30 20:27:59 2023 +1300
@@ -78,9 +78,6 @@
 #define ATHN_USB_SOFTC(sc)	((struct athn_usb_softc *)(sc))
 #define ATHN_USB_NODE(ni)	((struct athn_usb_node *)(ni))
 
-#define IS_UP_AND_RUNNING(ifp) \
-	(((ifp)->if_flags & IFF_UP) && ((ifp)->if_flags & IFF_RUNNING))
-
 #define athn_usb_wmi_cmd(sc, cmd_id) \
 	athn_usb_wmi_xcmd(sc, cmd_id, NULL, 0, NULL)
 
@@ -97,6 +94,11 @@
 Static int	athn_usb_alloc_tx_msg(struct athn_usb_softc *);
 Static int	athn_usb_alloc_tx_list(struct athn_usb_softc *);
 Static void	athn_usb_attachhook(device_t);
+Static struct ieee80211vap *
+		athn_usb_vap_create(struct ieee80211com *, const char [IFNAMSIZ],
+		    int, enum ieee80211_opmode, int,
+		    const uint8_t [IEEE80211_ADDR_LEN],
+		    const uint8_t [IEEE80211_ADDR_LEN]);
 Static void	athn_usb_bcneof(struct usbd_xfer *, void *,
 		    usbd_status);
 Static void	athn_usb_abort_pipes(struct athn_usb_softc *);
@@ -116,18 +118,18 @@
 Static int	athn_usb_htc_msg(struct athn_usb_softc *, uint16_t, void *,
 		    int);
 Static int	athn_usb_htc_setup(struct athn_usb_softc *);
-Static int	athn_usb_init(struct ifnet *);
-Static int	athn_usb_init_locked(struct ifnet *);
+Static int	athn_usb_init(struct athn_usb_softc *);
+Static int	athn_usb_init_locked(struct athn_usb_softc *);
 Static void	athn_usb_intr(struct usbd_xfer *, void *,
 		    usbd_status);
-Static int	athn_usb_ioctl(struct ifnet *, u_long, void *);
+//Static int	athn_usb_ioctl(struct ifnet *, u_long, void *);
 Static int	athn_usb_load_firmware(struct athn_usb_softc *);
 Static const struct athn_usb_type *
 		athn_usb_lookup(int, int);
-Static int	athn_usb_media_change(struct ifnet *);
+//Static int	athn_usb_media_change(struct ifnet *);
 Static void	athn_usb_newassoc(struct ieee80211_node *, int);
 Static void	athn_usb_newassoc_cb(struct athn_usb_softc *, void *);
-Static int	athn_usb_newstate(struct ieee80211com *, enum ieee80211_state,
+Static int	athn_usb_newstate(struct ieee80211vap *, enum ieee80211_state,
 		    int);
 Static void	athn_usb_newstate_cb(struct athn_usb_softc *, void *);
 Static void	athn_usb_node_cleanup(struct ieee80211_node *);
@@ -142,10 +144,15 @@
 Static void	athn_usb_rx_wmi_ctrl(struct athn_usb_softc *, uint8_t *, size_t);
 Static void	athn_usb_rxeof(struct usbd_xfer *, void *,
 		    usbd_status);
-Static void	athn_usb_start(struct ifnet *);
+Static void	athn_usb_parent(struct ieee80211com *);
+Static int	athn_usb_transmit(struct ieee80211com *, struct mbuf *);
+Static int	athn_usb_raw_xmit(struct ieee80211_node *, struct mbuf *,
+		    const struct ieee80211_bpf_params *);
+Static void	athn_usb_set_channel(struct ieee80211com *);
+Static void	athn_usb_start(struct athn_usb_softc *);
 //Static void	athn_usb_start_locked(struct ifnet *);
-Static void	athn_usb_stop(struct ifnet *, int disable);
-Static void	athn_usb_stop_locked(struct ifnet *);
+Static void	athn_usb_stop(struct athn_usb_softc *, int disable);
+Static void	athn_usb_stop_locked(struct athn_usb_softc *);
 Static void	athn_usb_swba(struct athn_usb_softc *);
 Static int	athn_usb_switch_chan(struct athn_softc *,
 		    struct ieee80211_channel *, struct ieee80211_channel *);
@@ -158,7 +165,7 @@
 Static void	athn_usb_updateslot_cb(struct athn_usb_softc *, void *);
 Static void	athn_usb_wait_async(struct athn_usb_softc *);
 Static int	athn_usb_wait_msg(struct athn_usb_softc *);
-Static void	athn_usb_watchdog(struct ifnet *);
+Static void	athn_usb_watchdog(void *);
 Static int	athn_usb_wmi_xcmd(struct athn_usb_softc *, uint16_t, void *,
 		    int, void *);
 Static void	athn_usb_wmieof(struct usbd_xfer *, void *,
@@ -371,13 +378,10 @@
 Static void
 athn_usb_node_cleanup(struct ieee80211_node *ni)
 {
-	struct athn_usb_softc *usc;
-	struct ieee80211com *ic;
+	struct ieee80211com *ic = ni->ni_ic;
+	struct athn_usb_softc *usc = ATHN_USB_SOFTC(ic->ic_softc);
 	uint8_t sta_index;
 
-	usc = ATHN_USB_SOFTC(TAILQ_FIRST(&(ni->ni_ic->ic_vaps))->iv_ifp->if_softc);
-	ic = &ATHN_SOFTC(usc)->sc_ic;
-
 	DPRINTFN(DBG_FN, usc, "\n");
 
 	if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
@@ -396,7 +400,6 @@
 	struct athn_softc *sc = &usc->usc_sc;
 	struct athn_ops *ops = &sc->sc_ops;
 	struct ieee80211com *ic = &sc->sc_ic;
-	struct ifnet *ifp = &sc->sc_if;
 	size_t i;
 	int error;
 
@@ -419,17 +422,9 @@
 		return;
 
 	/* We're now ready to attach the bus agnostic driver. */
-	TAILQ_FIRST(&(ic->ic_vaps))->iv_ifp = ifp;
 	ic->ic_updateslot = athn_usb_updateslot;
 	sc->sc_max_aid = AR_USB_MAX_STA;  /* Firmware is limited to 8 STA */
-	sc->sc_media_change = athn_usb_media_change;
-
-	/* Override some operations for USB. */
-	ifp->if_init = athn_usb_init;
-	ifp->if_stop = athn_usb_stop;
-	ifp->if_ioctl = athn_usb_ioctl;
-	ifp->if_start = athn_usb_start;
-	ifp->if_watchdog = athn_usb_watchdog;
+	//sc->sc_media_change = athn_usb_media_change;
 
 	error = athn_attach(sc);
 	if (error != 0) {
@@ -437,6 +432,15 @@
 	}
 	usc->usc_athn_attached = 1;
 
+	/* Override some operations for USB. */
+	ic->ic_vap_create = athn_usb_vap_create;
+	ic->ic_parent = athn_usb_parent;
+	ic->ic_transmit = athn_usb_transmit;
+	ic->ic_raw_xmit = athn_usb_raw_xmit;
+	ic->ic_set_channel = athn_usb_set_channel;
+
+	callout_setfunc(&sc->sc_watchdog_to, athn_usb_watchdog, sc);
+
 	/* hooks for HostAP association and disassociation */
 	ic->ic_newassoc = athn_usb_newassoc;
 	usc->usc_node_cleanup = ic->ic_node_cleanup;
@@ -450,7 +454,6 @@
 	ic->ic_delete_key = athn_usb_delete_key;
 	ic->ic_ampdu_tx_start = athn_usb_ampdu_tx_start;
 	ic->ic_ampdu_tx_stop = athn_usb_ampdu_tx_stop;
-	ic->ic_newstate = athn_usb_newstate;   /* XXX should we have this one? */ 
 #endif
 
 	ops->rx_enable = athn_usb_rx_enable;
@@ -514,7 +517,7 @@
 
 	athn_usb_wait_async(usc);
 
-	athn_usb_stop(&sc->sc_if, 0);
+	athn_usb_stop(usc, 0);
 	usb_rem_task_wait(usc->usc_udev, &usc->usc_task, USB_TASKQ_DRIVER,
 	    NULL);
 
@@ -559,14 +562,20 @@
 
 	DPRINTFN(DBG_FN, usc, "\n");
 
-	switch (act) {
-	case DVACT_DEACTIVATE:
-		if_deactivate(TAILQ_FIRST(&(sc->sc_ic.ic_vaps))->iv_ifp);
-		usc->usc_dying = 1;
-		return 0;
-	default:
-		return EOPNOTSUPP;
-	}
+	return ieee80211_activate(&sc->sc_ic, act);
+}
+
+Static struct ieee80211vap *
+athn_usb_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ],
+    int unit, enum ieee80211_opmode opmode, int flags,
+    const uint8_t bssid[IEEE80211_ADDR_LEN],
+    const uint8_t macaddr[IEEE80211_ADDR_LEN])
+{
+	struct ieee80211vap *vap;
+
+	vap = athn_vap_create(ic, name, unit, opmode, flags, bssid, macaddr);
+	vap->iv_newstate = athn_usb_newstate;
+	return vap;
 }
 
 Static int
@@ -1387,6 +1396,7 @@
 	usc->usc_wcount = 0;	/* Always flush buffer. */
 }
 
+#if 0
 Static int
 athn_usb_media_change(struct ifnet *ifp)
 {
@@ -1406,18 +1416,20 @@
 	}
 	return error;
 }
+#endif
 
 Static int
-athn_usb_newstate(struct ieee80211com *ic, enum ieee80211_state nstate,
+athn_usb_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate,
     int arg)
 {
-	struct athn_softc *sc = TAILQ_FIRST(&(ic->ic_vaps))->iv_ifp->if_softc;
+	struct athn_softc *sc = vap->iv_ic->ic_softc;
 	struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc);
 	struct athn_usb_cmd_newstate cmd;
 
 	DPRINTFN(DBG_FN, sc, "\n");
 
 	/* Do it in a process context. */
+	cmd.vap = vap;
 	cmd.state = nstate;
 	cmd.arg = arg;
 	athn_usb_do_async(usc, athn_usb_newstate_cb, &cmd, sizeof(cmd));
@@ -1430,6 +1442,8 @@
 	struct athn_usb_cmd_newstate *cmd = arg;
 	struct athn_softc *sc = &usc->usc_sc;
 	struct ieee80211com *ic = &sc->sc_ic;
+	struct ieee80211vap *vap = cmd->vap;
+	struct athn_vap *avap = (struct athn_vap *)vap;
 	enum ieee80211_state ostate, nstate;
 	uint32_t reg, intr_mask;
 	int s;
@@ -1438,9 +1452,10 @@
 
 	callout_stop(&sc->sc_calib_to);
 
-	s = splnet();
-
-	ostate = TAILQ_FIRST(&(ic->ic_vaps))->iv_state;
+	s = splnet(); /* XXX needed? */
+	IEEE80211_LOCK(ic);
+
+	ostate = vap->iv_state;
 	nstate = cmd->state;
 	DPRINTFN(DBG_STM, usc, "newstate %s(%d) -> %s(%d)\n",
 		    ieee80211_state_name[ostate], ostate,
@@ -1449,7 +1464,7 @@
 	if (ostate == IEEE80211_S_RUN) {
 		uint8_t sta_index;
 
-		sta_index = ATHN_NODE(TAILQ_FIRST(&(ic->ic_vaps))->iv_bss)->sta_index;
+		sta_index = ATHN_NODE(vap->iv_bss)->sta_index;
 		DPRINTFN(DBG_NODES, usc, "removing node %u\n", sta_index);
 		athn_usb_remove_hw_node(usc, &sta_index);
 	}
@@ -1463,7 +1478,7 @@
 		athn_set_led(sc, !sc->sc_led_state);
 		(void)athn_usb_switch_chan(sc, ic->ic_curchan, NULL);
 		if (!usc->usc_dying)
-			callout_schedule(&sc->sc_scan_to, hz / 5);
+			callout_schedule(&avap->av_scan_to, hz / 5);
 		break;
 	case IEEE80211_S_AUTH:
 		athn_set_led(sc, 0);
@@ -1479,20 +1494,20 @@
 
 		/* Create node entry for our BSS. */
 		DPRINTFN(DBG_NODES, sc, "create node for AID=%#x\n",
-		    ic->ic_bss->ni_associd);
-		athn_usb_create_node(usc, TAILQ_FIRST(&(ic->ic_vaps))->iv_bss);	/* XXX: handle error? */
-
-		athn_set_bss(sc, TAILQ_FIRST(&(ic->ic_vaps))->iv_bss);
+		    vap->iv_bss->ni_associd);
+		athn_usb_create_node(usc, vap->iv_bss);	/* XXX: handle error? */
+
+		athn_set_bss(sc, vap->iv_bss);
 		athn_usb_wmi_cmd(usc, AR_WMI_CMD_DISABLE_INTR);
 #ifndef IEEE80211_STA_ONLY
 		if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
-			athn_set_hostap_timers(sc);
+			athn_set_hostap_timers(vap);
 			/* Enable software beacon alert interrupts. */
 			intr_mask = htobe32(AR_IMR_SWBA);
 		} else
 #endif
 		{
-			athn_set_sta_timers(sc);
+			athn_set_sta_timers(vap);
 			/* Enable beacon miss interrupts. */
 			intr_mask = htobe32(AR_IMR_BMISS);
 
@@ -1513,7 +1528,8 @@
 		break;
 	}
 	if (!usc->usc_dying)
-		(void)sc->sc_newstate(ic, nstate, cmd->arg);
+		(void)avap->newstate(vap, nstate, cmd->arg);
+	IEEE80211_UNLOCK(ic);
 	splx(s);
 }
 
@@ -1521,7 +1537,7 @@
 athn_usb_newassoc(struct ieee80211_node *ni, int isnew)
 {
 	struct ieee80211com *ic = ni->ni_ic;
-	struct athn_softc *sc = TAILQ_FIRST(&(ic->ic_vaps))->iv_ifp->if_softc;
+	struct athn_softc *sc = ic->ic_softc;
 	struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc);
 
 	DPRINTFN(DBG_FN, sc, "\n");
@@ -1558,7 +1574,7 @@
 athn_usb_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
     uint8_t tid)
 {
-	struct athn_softc *sc = ic->ic_ifp->if_softc;
+	struct athn_softc *sc = ic->ic_softc;
 	struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc);
 	struct athn_node *an = ATHN_NODE(ni);
 	struct athn_usb_aggr_cmd cmd;
@@ -1592,7 +1608,7 @@
 athn_usb_ampdu_tx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
     uint8_t tid)
 {
-	struct athn_softc *sc = ic->ic_ifp->if_softc;
+	struct athn_softc *sc = ic->ic_softc;
 	struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc);
 	struct athn_node *an = ATHN_NODE(ni);
 	struct athn_usb_aggr_cmd cmd;
@@ -1796,7 +1812,7 @@
 Static void
 athn_usb_updateedca(struct ieee80211com *ic)
 {
-	struct athn_softc *sc = ic->ic_ifp->if_softc;
+	struct athn_softc *sc = ic->ic_softc;
 	struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc);
 
 	DPRINTFN(DBG_FN, sc, "\n");
@@ -1821,8 +1837,7 @@
 Static void
 athn_usb_updateslot(struct ieee80211com *ic)
 {
-	struct ifnet *ifp = TAILQ_FIRST(&(ic->ic_vaps))->iv_ifp;
-	struct athn_softc *sc = ifp->if_softc;
+	struct athn_softc *sc = ic->ic_softc;
 	struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc);
 
 	DPRINTFN(DBG_FN, sc, "\n");
@@ -1848,7 +1863,7 @@
 	DPRINTFN(DBG_FN, usc, "\n");
 
 	s = splnet();
-	athn_updateslot(&usc->usc_sc.sc_if);
+	athn_updateslot(&usc->usc_sc.sc_ic);
 	splx(s);
 }
 
@@ -1857,7 +1872,7 @@
 athn_usb_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
     struct ieee80211_key *k)
 {
-	struct athn_softc *sc = ic->ic_ifp->if_softc;
+	struct athn_softc *sc = ic->ic_softc;
 	struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc);
 	struct ifnet *ifp = &usc->usc_sc.sc_if;
 	struct athn_usb_cmd_key cmd;
@@ -1895,7 +1910,7 @@
 athn_usb_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
     struct ieee80211_key *k)
 {
-	struct athn_softc *sc = ic->ic_ifp->if_softc;
+	struct athn_softc *sc = ic->ic_softc;
 	struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc);
 	struct ifnet *ifp = &usc->usc_sc.sc_if;
 	struct athn_usb_cmd_key cmd;
@@ -2223,7 +2238,6 @@
 {
 	struct athn_softc *sc = &usc->usc_sc;
 	struct ieee80211com *ic = &sc->sc_ic;
-	struct ifnet *ifp = &sc->sc_if;
 	struct ieee80211_frame *wh;
 	struct ieee80211_node *ni;
 	struct ar_htc_frame_hdr *htc;
@@ -2262,7 +2276,6 @@
 		goto skip;
 
 	m_adj(m, sizeof(*rs));	/* Strip Rx status. */
-	m_set_rcvif(m, ifp);
 
 	s = splnet();
 
@@ -2285,10 +2298,11 @@
 	m_adj(m, -IEEE80211_CRC_LEN);
 
 	/* Send the frame to the 802.11 layer. */
-	ieee80211_input(ni, m, rs->rs_rssi + AR_USB_DEFAULT_NF, 0);
+	ieee80211_rx_enqueue(ic, m, rs->rs_rssi + AR_USB_DEFAULT_NF);
 
 	/* Node is no longer needed. */
-	ieee80211_free_node(ni);
+	if (ni)
+		ieee80211_free_node(ni);
 	splx(s);
 	return;
  skip:
@@ -2414,7 +2428,6 @@
 	struct athn_usb_tx_data *data = priv;
 	struct athn_usb_softc *usc = data->sc;
 	struct athn_softc *sc = &usc->usc_sc;
-	struct ifnet *ifp = &sc->sc_if;
 	int s;
 
 	if (usc->usc_dying)
@@ -2432,18 +2445,19 @@
 		DPRINTFN(DBG_TX, sc, "TX status=%d\n", status);
 		if (status == USBD_STALLED)
 			usbd_clear_endpoint_stall_async(usc->usc_tx_data_pipe);
-		if_statinc(ifp, if_oerrors);
+		//if_statinc(ifp, if_oerrors);
+		/* XXX */
+		ieee80211_stat_add(&sc->sc_ic.ic_oerrors, 1);
 		splx(s);
 		/* XXX Why return? */
 		return;
 	}
 	sc->sc_tx_timer = 0;
-	if_statinc(ifp, if_opackets);
 
 	/* We just released a Tx buffer, notify Tx. */
-	if (ifp->if_flags & IFF_OACTIVE) {
-		ifp->if_flags &= ~IFF_OACTIVE;
-		ifp->if_start(ifp);
+	if (sc->sc_flags & ATHN_FLAG_TX_BUSY) {
+		sc->sc_flags &= ~ATHN_FLAG_TX_BUSY;
+		athn_usb_start(usc);
 	}
 	splx(s);
 }
@@ -2552,7 +2566,8 @@
 
 	s = splnet();
 	usbd_setup_xfer(data->xfer, data, data->buf, xferlen,
-	    USBD_FORCE_SHORT_XFER, ATHN_USB_TX_TIMEOUT, athn_usb_txeof);
+	    USBD_FORCE_SHORT_XFER, ATHN_USB_TX_TIMEOUT,
+	    athn_usb_txeof);
 	error = usbd_transfer(data->xfer);
 	if (__predict_false(error != USBD_IN_PROGRESS && error != 0)) {
 		splx(s);
@@ -2563,13 +2578,74 @@
 }
 
 Static void
-athn_usb_start(struct ifnet *ifp)
+athn_usb_parent(struct ieee80211com *ic)
 {
-	struct athn_softc *sc = ifp->if_softc;
+	struct athn_usb_softc *usc = ATHN_USB_SOFTC(ic->ic_softc);
+	bool startall = false;
+
+	/* XXX kassert that the device is fully running */
+	/* XXX do we need to accquire lock here? */
+	if (ic->ic_nrunning > 0) {
+		athn_usb_init(usc);
+		startall = true;
+	} else /* XXX pass 1 or 0? */
+		athn_usb_stop(usc, 1);
+
+	if (startall)
+		ieee80211_start_all(ic);
+}
+
+Static int
+athn_usb_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+	struct athn_softc *sc = ic->ic_softc;
 	struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc);
-	struct ieee80211com *ic = &sc->sc_ic;
+	int s;
+
+	s = splnet();
+	IF_ENQUEUE(&sc->sc_sendq, m);
+	if (!(sc->sc_flags & ATHN_FLAG_TX_BUSY))
+		athn_usb_start(usc);
+	splx(s);
+	return 0;
+}
+
+Static int
+athn_usb_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
+    const struct ieee80211_bpf_params *params)
+{
+	struct ieee80211com *ic = ni->ni_ic;
+	struct athn_softc *sc = ic->ic_softc;
+	struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc);
+	struct athn_usb_tx_data *data = NULL;
+
+	mutex_enter(&usc->usc_tx_mtx);
+	if (!TAILQ_EMPTY(&usc->usc_tx_free_list)) {
+		data = TAILQ_FIRST(&usc->usc_tx_free_list);
+		TAILQ_REMOVE(&usc->usc_tx_free_list, data, next);
+	}
+	mutex_exit(&usc->usc_tx_mtx);
+	if (data == NULL)
+		return -1;
+
+	return athn_usb_tx(sc, m, ni, data);
+}
+
+Static void
+athn_usb_set_channel(struct ieee80211com *ic)
+{
+	struct athn_softc *sc = ic->ic_softc;
+
+	athn_usb_switch_chan(sc, ic->ic_curchan, NULL); /* XXX extchan? */
+}
+
+Static void
+athn_usb_start(struct athn_usb_softc *usc)
+{
+	struct athn_softc *sc = ATHN_SOFTC(usc);
 	struct athn_usb_tx_data *data;
-	struct ether_header *eh;
+	struct ieee80211vap *vap = NULL;
+	struct ieee80211_frame *wh;
 	struct ieee80211_node *ni;
 	struct mbuf *m;
 
@@ -2578,7 +2654,7 @@
 
 	DPRINTFN(DBG_FN, sc, "\n");
 
-	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
+	if (sc->sc_flags & ATHN_FLAG_TX_BUSY)
 		return;
 
 	data = NULL;
@@ -2591,59 +2667,46 @@
 		mutex_exit(&usc->usc_tx_mtx);
 
 		if (data == NULL) {
-			ifp->if_flags |= IFF_OACTIVE;
+			sc->sc_flags |= ATHN_FLAG_TX_BUSY;
 			return;
 		}
 
-		/* Send pending management frames first. */
-		IF_DEQUEUE(&ic->ic_mgtq, m);
-		if (m != NULL) {
-			ni = M_GETCTX(m, struct ieee80211_node *);
-			M_CLEARCTX(m);
-			goto sendit;
-		}
-		if (ic->ic_state != IEEE80211_S_RUN)
-			break;
-
 		/* Encapsulate and send data frames. */
-		IFQ_DEQUEUE(&ifp->if_snd, m);
+		IFQ_DEQUEUE(&sc->sc_sendq, m);
 		if (m == NULL)
 			break;
 
-		if (m->m_len < (int)sizeof(*eh) &&
-		    (m = m_pullup(m, sizeof(*eh))) == NULL) {
-			if_statinc(ifp, if_oerrors);
+		ni = M_GETCTX(m, struct ieee80211_node *);
+		M_CLEARCTX(m);
+		vap = ni->ni_vap;
+
+		if (m->m_len < (int)sizeof(*wh) &&
+		    (m = m_pullup(m, sizeof(*wh))) == NULL) {
+			if_statinc(vap->iv_ifp, if_oerrors);
 			continue;
 		}
-		eh = mtod(m, struct ether_header *);
-		ni = ieee80211_find_txnode(ic, eh->ether_dhost);
+		wh = mtod(m, struct ieee80211_frame *);
 		if (ni == NULL) {
 			m_freem(m);
-			if_statinc(ifp, if_oerrors);
+			if_statinc(vap->iv_ifp, if_oerrors);
 			continue;
 		}
 
-		bpf_mtap(ifp, m, BPF_D_OUT);
-
-		if ((m = ieee80211_encap(ic, m, ni)) == NULL) {
-			ieee80211_free_node(ni);
-			if_statinc(ifp, if_oerrors);
-			continue;
-		}
- sendit:
-		bpf_mtap3(ic->ic_rawbpf, m, BPF_D_OUT);
+		/* bpf_mtap(ifp, m, BPF_D_OUT); */
+
+		/* bpf_mtap3(ic->ic_rawbpf, m, BPF_D_OUT); */
 
 		if (athn_usb_tx(sc, m, ni, data) != 0) {
 			m_freem(m);
 			ieee80211_free_node(ni);
-			if_statinc(ifp, if_oerrors);
+			if_statinc(vap->iv_ifp, if_oerrors);
 			continue;
 		}
 		data = NULL;
 		m_freem(m);
 		ieee80211_free_node(ni);
 		sc->sc_tx_timer = 5;
-		ifp->if_timer = 1;
+		callout_schedule(&sc->sc_watchdog_to, hz);
 	}
 
 	/* Return the Tx buffer to the free list */
@@ -2653,26 +2716,24 @@
 }
 
 Static void
-athn_usb_watchdog(struct ifnet *ifp)
+athn_usb_watchdog(void *arg)
 {
-	struct athn_softc *sc = ifp->if_softc;
+	struct athn_softc *sc = ATHN_SOFTC(arg);
 
 	DPRINTFN(DBG_FN, sc, "\n");
 
-	ifp->if_timer = 0;
-
 	if (sc->sc_tx_timer > 0) {
 		if (--sc->sc_tx_timer == 0) {
 			aprint_error_dev(sc->sc_dev, "device timeout\n");
 			/* athn_usb_init(ifp); XXX needs a process context! */
-			if_statinc(ifp, if_oerrors);
+			ieee80211_stat_add(&sc->sc_ic.ic_oerrors, 1);
 			return;
 		}
-		ifp->if_timer = 1;
+		callout_schedule(&sc->sc_watchdog_to, hz);
 	}
-	ieee80211_watchdog(&sc->sc_ic);
 }
 
+#if 0
 Static int
 athn_usb_ioctl(struct ifnet *ifp, u_long cmd, void *data)
 {
@@ -2743,25 +2804,22 @@
 	splx(s);
 	return error;
 }
+#endif
 
 Static int
-athn_usb_init(struct ifnet *ifp)
+athn_usb_init(struct athn_usb_softc *usc)
 {
-	struct athn_softc *sc = ifp->if_softc;
-	struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc);
-
 	mutex_enter(&usc->usc_lock);
-	int ret = athn_usb_init_locked(ifp);
+	int ret = athn_usb_init_locked(usc);
 	mutex_exit(&usc->usc_lock);
 
 	return ret;
 }
 
 Static int
-athn_usb_init_locked(struct ifnet *ifp)
+athn_usb_init_locked(struct athn_usb_softc *usc)
 {
-	struct athn_softc *sc = ifp->if_softc;
-	struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc);
+	struct athn_softc *sc = ATHN_SOFTC(usc);
 	struct athn_ops *ops = &sc->sc_ops;
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ieee80211_channel *curchan, *extchan;
@@ -2787,7 +2845,7 @@
 	extchan = NULL;
 
 	/* In case a new MAC address has been configured. */
-	IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
+	//IEEE80211_ADDR_COPY(ic->ic_macaddr, CLLADDR(ifp->if_sadl));
 
 	error = athn_set_power_awake(sc);
 	if (error != 0)
@@ -2820,10 +2878,10 @@
 
 	athn_rx_start(sc);
 
-	/* Create main interface on target. */
+	/* Create main interface on target.  XXX Probably wrong place. */
 	memset(&hvif, 0, sizeof(hvif));
 	hvif.index = 0;
-	IEEE80211_ADDR_COPY(hvif.myaddr, ic->ic_myaddr);
+	IEEE80211_ADDR_COPY(hvif.myaddr, ic->ic_macaddr);
 	switch (ic->ic_opmode) {
 	case IEEE80211_M_STA:
 		hvif.opmode = htobe32(AR_HTC_M_STA);
@@ -2842,8 +2900,10 @@
 		hvif.opmode = htobe32(AR_HTC_M_HOSTAP);
 		break;
 #endif
+	default:
+		break;
 	}
-	hvif.rtsthreshold = htobe16(ic->ic_rtsthreshold);
+	hvif.rtsthreshold = htobe16(TAILQ_FIRST(&(ic->ic_vaps))->iv_rtsthreshold);
 	DPRINTFN(DBG_INIT, sc, "creating VAP\n");
 	error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_VAP_CREATE,
 	    &hvif, sizeof(hvif), NULL);
@@ -2852,7 +2912,7 @@
 
 	/* Create a fake node to send management frames before assoc. */
 	memset(&sta, 0, sizeof(sta));
-	IEEE80211_ADDR_COPY(sta.macaddr, ic->ic_myaddr);
+	IEEE80211_ADDR_COPY(sta.macaddr, ic->ic_macaddr);
 	sta.sta_index = 0;
 	sta.is_vif_sta = 1;
 	sta.vif_index = hvif.index;
@@ -2892,8 +2952,7 @@
 			goto fail;
 	}
 	/* We're ready to go. */
-	ifp->if_flags &= ~IFF_OACTIVE;
-	ifp->if_flags |= IFF_RUNNING;
+	sc->sc_flags |= ATHN_FLAG_TX_BUSY;
 
 #ifdef notyet
 	if (ic->ic_flags & IEEE80211_F_WEPON) {
@@ -2902,6 +2961,7 @@
 			athn_usb_set_key(ic, NULL, &ic->ic_nw_keys[i]);
 	}
 #endif
+#ifdef XXX
 	if (ic->ic_opmode == IEEE80211_M_HOSTAP)
 		ic->ic_max_aid = AR_USB_MAX_STA;  /* Firmware is limited to 8 STA */
 	else
@@ -2911,29 +2971,26 @@
 		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
 	else
 		ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
+#endif
 	athn_usb_wait_async(usc);
 	return 0;
  fail:
-	athn_usb_stop(ifp, 0);
+	athn_usb_stop(usc, 0);
 	return error;
 }
 
 Static void
-athn_usb_stop(struct ifnet *ifp, int disable)
+athn_usb_stop(struct athn_usb_softc *usc, int disable)
 {
-	struct athn_softc *sc = ifp->if_softc;
-	struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc);
-
 	mutex_enter(&usc->usc_lock);
-	athn_usb_stop_locked(ifp);
+	athn_usb_stop_locked(usc);
 	mutex_exit(&usc->usc_lock);
 }
 
 Static void
-athn_usb_stop_locked(struct ifnet *ifp)
+athn_usb_stop_locked(struct athn_usb_softc *usc)
 {
-	struct athn_softc *sc = ifp->if_softc;
-	struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc);
+	struct athn_softc *sc = ATHN_SOFTC(usc);
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ar_htc_target_vif hvif;
 	struct mbuf *m;
@@ -2943,16 +3000,15 @@
 	DPRINTFN(DBG_FN, sc, "\n");
 
 	s = splusb();
-	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
+	//ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
 	athn_usb_wait_async(usc);
 	splx(s);
 
 	sc->sc_tx_timer = 0;
-	ifp->if_timer = 0;
-	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
-
-	callout_stop(&sc->sc_scan_to);
+	sc->sc_flags &= ~ATHN_FLAG_TX_BUSY;
+
 	callout_stop(&sc->sc_calib_to);
+	callout_stop(&sc->sc_watchdog_to);
 
 	/* Abort Tx/Rx. */
 	usbd_abort_pipe(usc->usc_tx_data_pipe);
@@ -2967,7 +3023,7 @@
 	/* Remove main interface. */
 	memset(&hvif, 0, sizeof(hvif));
 	hvif.index = 0;
-	IEEE80211_ADDR_COPY(hvif.myaddr, ic->ic_myaddr);
+	IEEE80211_ADDR_COPY(hvif.myaddr, ic->ic_macaddr);
 	(void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_VAP_REMOVE,
 	    &hvif, sizeof(hvif), NULL);
 
diff -r e7067aff72a8 sys/dev/usb/if_athn_usb.h
--- a/sys/dev/usb/if_athn_usb.h	Fri Aug 11 16:08:59 2023 -0700
+++ b/sys/dev/usb/if_athn_usb.h	Sat Sep 30 20:27:59 2023 +1300
@@ -411,6 +411,7 @@
 };
 
 struct athn_usb_cmd_newstate {
+	struct ieee80211vap	*vap;
 	enum ieee80211_state	state;
 	int			arg;
 };
diff -r e7067aff72a8 sys/dev/usb/usbdevices.config
--- a/sys/dev/usb/usbdevices.config	Fri Aug 11 16:08:59 2023 -0700
+++ b/sys/dev/usb/usbdevices.config	Sat Sep 30 20:27:59 2023 +1300
@@ -136,7 +136,7 @@
 usmsc*	at uhub? port ?		# SMSC95xx based adapters
 
 # USB 802.11 adapters
-#athn*	at uhub? port ?		# Atheros AR9002U
+athn*	at uhub? port ?		# Atheros AR9002U
 atu*	at uhub? port ?		# Atmel AT76C50XX based adapters
 bwfm*	at uhub? port ?		# Broadcom FullMAC
 otus*	at uhub? port ?		# Atheros AR9001U


Home | Main Index | Thread Index | Old Index