PERFORCE change 129271 for review

Kevin Lo kevlo at FreeBSD.org
Mon Nov 19 22:42:44 PST 2007


http://perforce.freebsd.org/chv.cgi?CH=129271

Change 129271 by kevlo at kevlo_rtsl on 2007/11/20 06:42:32

	Rework LED support
	Obtained from: DragonFlyBSD

Affected files ...

.. //depot/projects/wifi/sys/dev/bwi/if_bwi.c#9 edit
.. //depot/projects/wifi/sys/dev/bwi/if_bwireg.h#4 edit
.. //depot/projects/wifi/sys/dev/bwi/if_bwivar.h#5 edit

Differences ...

==== //depot/projects/wifi/sys/dev/bwi/if_bwi.c#9 (text+ko) ====

@@ -111,8 +111,8 @@
 static int	bwi_calc_rssi(struct bwi_softc *, const struct bwi_rxbuf_hdr *);
 static __inline uint8_t bwi_ofdm_plcp2rate(const uint32_t *);
 static __inline uint8_t bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *);
-static void bwi_rx_radiotap(struct bwi_softc *, struct mbuf *,
-			struct bwi_rxbuf_hdr *, const void *, int);
+static void	bwi_rx_radiotap(struct bwi_softc *, struct mbuf *,
+			struct bwi_rxbuf_hdr *, const void *, int, int);
 
 static void	bwi_stop(struct bwi_softc *);
 static int	bwi_newbuf(struct bwi_softc *, int, int);
@@ -132,7 +132,7 @@
 static void	bwi_setup_rx_desc32(struct bwi_softc *, int, bus_addr_t, int);
 static void	bwi_setup_tx_desc32(struct bwi_softc *, struct bwi_ring_data *,
 				    int, bus_addr_t, int);
-static void	bwi_rxeof32(struct bwi_softc *);
+static int	bwi_rxeof32(struct bwi_softc *);
 static void	bwi_start_tx32(struct bwi_softc *, uint32_t, int);
 static void	bwi_txeof_status32(struct bwi_softc *);
 
@@ -145,11 +145,11 @@
 static void	bwi_setup_rx_desc64(struct bwi_softc *, int, bus_addr_t, int);
 static void	bwi_setup_tx_desc64(struct bwi_softc *, struct bwi_ring_data *,
 				    int, bus_addr_t, int);
-static void	bwi_rxeof64(struct bwi_softc *);
+static int	bwi_rxeof64(struct bwi_softc *);
 static void	bwi_start_tx64(struct bwi_softc *, uint32_t, int);
 static void	bwi_txeof_status64(struct bwi_softc *);
 
-static void	bwi_rxeof(struct bwi_softc *, int);
+static int	bwi_rxeof(struct bwi_softc *, int);
 static void	_bwi_txeof(struct bwi_softc *, uint16_t, int, int);
 static void	bwi_txeof(struct bwi_softc *);
 static void	bwi_txeof_status(struct bwi_softc *, int);
@@ -195,6 +195,10 @@
 
 static void	bwi_led_attach(struct bwi_softc *);
 static void	bwi_led_newstate(struct bwi_softc *, enum ieee80211_state);
+static void	bwi_led_event(struct bwi_softc *, int);
+static void	bwi_led_blink_start(struct bwi_softc *, int, int);
+static void	bwi_led_blink_next(void *);
+static void	bwi_led_blink_end(void *);
 
 static const struct {
 	uint16_t	did_min;
@@ -242,6 +246,48 @@
 
 #undef CLKSRC
 
+#define VENDOR_LED_ACT(vendor)				\
+{							\
+	.vid = PCI_VENDOR_##vendor,			\
+	.led_act = { BWI_VENDOR_LED_ACT_##vendor }	\
+}
+
+static const struct {
+#define	PCI_VENDOR_COMPAQ	0x0e11
+#define	PCI_VENDOR_LINKSYS	0x1737
+	uint16_t	vid;
+	uint8_t		led_act[BWI_LED_MAX];
+} bwi_vendor_led_act[] = {
+	VENDOR_LED_ACT(COMPAQ),
+	VENDOR_LED_ACT(LINKSYS)
+#undef PCI_VENDOR_LINKSYS
+#undef PCI_VENDOR_COMPAQ
+};
+
+static const uint8_t bwi_default_led_act[BWI_LED_MAX] =
+	{ BWI_VENDOR_LED_ACT_DEFAULT };
+
+#undef VENDOR_LED_ACT
+
+static const struct {
+	int	on_dur;
+	int	off_dur;
+} bwi_led_duration[109] = {
+	[0]	= { 400, 100 },
+	[2]	= { 150, 75 },
+	[4]	= { 90, 45 },
+	[11]	= { 66, 34 },
+	[12]	= { 53, 26 },
+	[18]	= { 42, 21 },
+	[22]	= { 35, 17 },
+	[24]	= { 32, 16 },
+	[36]	= { 21, 10 },
+	[48]	= { 16, 8 },
+	[72]	= { 11, 5 },
+	[96]	= { 9, 4 },
+	[108]	= { 7, 3 }
+};
+
 static const uint8_t bwi_zero_addr[IEEE80211_ADDR_LEN];
 
 uint16_t
@@ -417,6 +463,10 @@
 
 	sc->sc_fw_version = BWI_FW_VERSION3;
 
+	/* Initialize LED vars */
+	sc->sc_led_idle = (2350 * hz) / 1000;
+	sc->sc_led_blink = 1;
+
 	ic->ic_ifp = ifp;
 	ic->ic_caps = IEEE80211_C_SHSLOT |
 		      IEEE80211_C_SHPREAMBLE |
@@ -1385,7 +1435,7 @@
 	struct ifnet *ifp = sc->sc_ic.ic_ifp;
 	uint32_t intr_status;
 	uint32_t txrx_intr_status[BWI_TXRX_NRING];
-	int i, txrx_error;
+	int i, txrx_error, tx = 0, rx_data = -1;
 
 	BWI_LOCK(sc);
 
@@ -1480,18 +1530,41 @@
 		if_printf(ifp, "intr noise\n");
 
 	if (txrx_intr_status[0] & BWI_TXRX_INTR_RX)
-		sc->sc_rxeof(sc);
+		rx_data = sc->sc_rxeof(sc);
 
-	if (txrx_intr_status[3] & BWI_TXRX_INTR_RX)
+	if (txrx_intr_status[3] & BWI_TXRX_INTR_RX) {
 		sc->sc_txeof_status(sc);
+		tx = 1;
+	}
 
-	if (intr_status & BWI_INTR_TX_DONE)
+	if (intr_status & BWI_INTR_TX_DONE) {
 		bwi_txeof(sc);
+		tx = 1;
+	}
 
-	/* TODO:LED */
-
 	/* Re-enable interrupts */
 	bwi_enable_intrs(sc, BWI_INIT_INTRS);
+
+	if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
+	int evt = BWI_LED_EVENT_NONE;
+
+	if (tx && rx_data > 0) {
+		if (sc->sc_rx_rate > sc->sc_tx_rate)
+			evt = BWI_LED_EVENT_RX;
+		else
+			evt = BWI_LED_EVENT_TX;
+		} else if (tx) {
+			evt = BWI_LED_EVENT_TX;
+		} else if (rx_data > 0) {
+			evt = BWI_LED_EVENT_RX;
+		} else if (rx_data == 0) {
+			evt = BWI_LED_EVENT_POLL;
+		}
+
+		if (evt != BWI_LED_EVENT_NONE)
+			bwi_led_event(sc, evt);
+	}
+
 	BWI_UNLOCK(sc);
 }
 
@@ -2454,14 +2527,14 @@
 	return 0;
 }
 
-static void
+static int
 bwi_rxeof(struct bwi_softc *sc, int end_idx)
 {
 	struct bwi_ring_data *rd = &sc->sc_rx_rdata;
 	struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ifnet *ifp = ic->ic_ifp;
-	int idx;
+	int idx, rx_data = 0;
 
 	idx = rbd->rbd_idx;
 	while (idx != end_idx) {
@@ -2470,9 +2543,9 @@
 		struct ieee80211_frame_min *wh;
 		struct ieee80211_node *ni;
 		struct mbuf *m;
-		const uint8_t *plcp;
+		const void *plcp;
 		uint16_t flags2;
-		int buflen, wh_ofs, hdr_extra, rssi;
+		int buflen, wh_ofs, hdr_extra, rssi, type, rate;
 
 		m = rb->rb_mbuf;
 		bus_dmamap_sync(sc->sc_buf_dtag, rb->rb_dmap,
@@ -2507,18 +2580,27 @@
 		m->m_len = m->m_pkthdr.len = buflen + sizeof(*hdr);
 		m_adj(m, sizeof(*hdr) + wh_ofs);
 
+		if (htole16(hdr->rxh_flags1) & BWI_RXH_F1_OFDM)
+			rate = bwi_ofdm_plcp2rate(plcp);
+		else
+			rate = bwi_ds_plcp2rate(plcp);
+
 		/* RX radio tap */
 		if (sc->sc_drvbpf != NULL)
-			bwi_rx_radiotap(sc, m, hdr, plcp, rssi);
+			bwi_rx_radiotap(sc, m, hdr, plcp, rate, rssi);
 
 		m_adj(m, -IEEE80211_CRC_LEN);
 
 		wh = mtod(m, struct ieee80211_frame_min *);
 		ni = ieee80211_find_rxnode(ic, wh);
 
-		ieee80211_input(ic, m, ni, rssi - BWI_NOISE_FLOOR,
+		type = ieee80211_input(ic, m, ni, rssi - BWI_NOISE_FLOOR,
 		    BWI_NOISE_FLOOR, le16toh(hdr->rxh_tsf));
 		ieee80211_free_node(ni);
+		if (type == IEEE80211_FC0_TYPE_DATA) {
+			rx_data = 1;
+			sc->sc_rx_rate = rate;
+		}
 next:
 		idx = (idx + 1) % BWI_RX_NDESC;
 	}
@@ -2526,13 +2608,15 @@
 	rbd->rbd_idx = idx;
 	bus_dmamap_sync(sc->sc_rxring_dtag, rd->rdata_dmap,
 			BUS_DMASYNC_PREWRITE);
+
+	return rx_data;
 }
 
-static void
+static int
 bwi_rxeof32(struct bwi_softc *sc)
 {
 	uint32_t val, rx_ctrl;
-	int end_idx;
+	int end_idx, rx_data;
 
 	rx_ctrl = sc->sc_rx_rdata.rdata_txrx_ctrl;
 
@@ -2540,16 +2624,19 @@
 	end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) /
 		  sizeof(struct bwi_desc32);
 
-	bwi_rxeof(sc, end_idx);
+	rx_data = bwi_rxeof(sc, end_idx);
 
 	CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_INDEX,
 		    end_idx * sizeof(struct bwi_desc32));
+
+	return rx_data;
 }
 
-static void
+static int
 bwi_rxeof64(struct bwi_softc *sc)
 {
 	/* TODO:64 */
+	return 0;
 }
 
 static void
@@ -2816,12 +2903,16 @@
 	if (IEEE80211_IS_MULTICAST(wh->i_addr1))
 		rate = rate_fb = ic->ic_mcast_rate;
 	else if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) {
-		rate = ni->ni_rates.rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL;
+		rate = ni->ni_rates.rs_rates[ni->ni_txrate] & 
+		    IEEE80211_RATE_VAL;
 		rate_fb = (ni->ni_txrate > 0) ?
-		   ni->ni_rates.rs_rates[ni->ni_txrate-1] & IEEE80211_RATE_VAL : rate;
+		   ni->ni_rates.rs_rates[ni->ni_txrate-1] & 
+		       IEEE80211_RATE_VAL : rate;
 	} else
 		rate = rate_fb = ic->ic_fixed_rate;
 
+	sc->sc_tx_rate = rate;
+
 	/*
 	 * TX radio tap
 	 */
@@ -3460,20 +3551,12 @@
 
 static void
 bwi_rx_radiotap(struct bwi_softc *sc, struct mbuf *m,
-		struct bwi_rxbuf_hdr *hdr, const void *plcp, int rssi)
+    struct bwi_rxbuf_hdr *hdr, const void *plcp, int rate, int rssi)
 {
 	const struct ieee80211_frame_min *wh;
-	uint16_t flags1;
-	uint8_t rate;
 
-	flags1 = htole16(hdr->rxh_flags1);
-	if (flags1 & BWI_RXH_F1_OFDM)
-		rate = bwi_ofdm_plcp2rate(plcp);
-	else
-		rate = bwi_ds_plcp2rate(plcp);
-
 	sc->sc_rx_th.wr_flags = IEEE80211_RADIOTAP_F_FCS;
-	if (flags1 & BWI_RXH_F1_SHPREAMBLE)
+	if (htole16(hdr->rxh_flags1) & BWI_RXH_F1_SHPREAMBLE)
 		sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
 
 	wh = mtod(m, const struct ieee80211_frame_min *);
@@ -3491,17 +3574,23 @@
 static void
 bwi_led_attach(struct bwi_softc *sc)
 {
-#define	PCI_VENDOR_COMPAQ 0x0e11
-	const static uint8_t led_default_act[BWI_LED_MAX] = {
-		BWI_LED_ACT_ACTIVE,
-		BWI_LED_ACT_2GHZ,
-		BWI_LED_ACT_5GHZ,
-		BWI_LED_ACT_OFF
-	};
-
+	const uint8_t *led_act = NULL;
 	uint16_t gpio, val[BWI_LED_MAX];
 	int i;
 
+#define N(arr)	(int)(sizeof(arr) / sizeof(arr[0]))
+
+	for (i = 0; i < N(bwi_vendor_led_act); ++i) {
+		if (sc->sc_pci_subvid == bwi_vendor_led_act[i].vid) {
+			led_act = bwi_vendor_led_act[i].led_act;
+			break;
+		}
+	}
+	if (led_act == NULL)
+		led_act = bwi_default_led_act;
+
+#undef N
+
 	gpio = bwi_read_sprom(sc, BWI_SPROM_GPIO01);
 	val[0] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_0);
 	val[1] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_1);
@@ -3514,19 +3603,46 @@
 		struct bwi_led *led = &sc->sc_leds[i];
 
 		if (val[i] == 0xff) {
-			led->l_act = led_default_act[i];
-			if (i == 0 && sc->sc_pci_subvid == PCI_VENDOR_COMPAQ)
-				led->l_act = BWI_LED_ACT_RFEN;
+			led->l_act = led_act[i];
 		} else {
 			if (val[i] & BWI_LED_ACT_LOW)
 				led->l_flags |= BWI_LED_F_ACTLOW;
 			led->l_act = __SHIFTOUT(val[i], BWI_LED_ACT_MASK);
 		}
+		led->l_mask = (1 << i);
+
+		if (led->l_act == BWI_LED_ACT_BLINK_SLOW ||
+		    led->l_act == BWI_LED_ACT_BLINK_POLL ||
+		    led->l_act == BWI_LED_ACT_BLINK) {
+			led->l_flags |= BWI_LED_F_BLINK;
+			if (led->l_act == BWI_LED_ACT_BLINK_POLL)
+				led->l_flags |= BWI_LED_F_POLLABLE;
+			else if (led->l_act == BWI_LED_ACT_BLINK_SLOW)
+				led->l_flags |= BWI_LED_F_SLOW;
+
+			if (sc->sc_blink_led == NULL) {
+				sc->sc_blink_led = led;
+				if (led->l_flags & BWI_LED_F_SLOW)
+					BWI_LED_SLOWDOWN(sc->sc_led_idle);
+			}
+		}
 
 		DPRINTF(sc, "%dth led, act %d, lowact %d\n",
 		    i, led->l_act, led->l_flags & BWI_LED_F_ACTLOW);
 	}
-#undef PCI_VENDOR_COMPAQ
+	callout_init(&sc->sc_led_blink_ch, CALLOUT_MPSAFE);
+}
+
+static __inline uint16_t
+bwi_led_onoff(const struct bwi_led *led, uint16_t val, int on)
+{
+	if (led->l_flags & BWI_LED_F_ACTLOW)
+		on = !on;
+	if (on)
+		val |= led->l_mask;
+	else
+		val &= ~led->l_mask;
+	return val;
 }
 
 static void
@@ -3536,6 +3652,11 @@
 	uint16_t val;
 	int i;
 
+	if (nstate == IEEE80211_S_INIT) {
+		callout_stop(&sc->sc_led_blink_ch);
+		sc->sc_led_blinking = 0;
+	}
+
 	if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
 		return;
 
@@ -3545,10 +3666,12 @@
 		int on;
 
 		if (led->l_act == BWI_LED_ACT_UNKN ||
-		    led->l_act == BWI_LED_ACT_NULL) {
-			/* Don't touch it */
+		    led->l_act == BWI_LED_ACT_NULL)
 			continue;
-		}
+
+		if ((led->l_flags & BWI_LED_F_BLINK) &&
+		    nstate != IEEE80211_S_INIT)
+		    	continue;
 
 		switch (led->l_act) {
 		case BWI_LED_ACT_ON:	/* Always on */
@@ -3556,8 +3679,6 @@
 			break;
 		case BWI_LED_ACT_OFF:	/* Always off */
 		case BWI_LED_ACT_5GHZ:	/* TODO: 11A */
-		case BWI_LED_ACT_MID:	/* Blinking ones */
-		case BWI_LED_ACT_FAST:
 			on = 0;
 			break;
 		default:
@@ -3572,23 +3693,92 @@
 					on = 0;
 				break;
 			default:
-				if (led->l_act == BWI_LED_ACT_RUN ||
-				    led->l_act == BWI_LED_ACT_ACTIVE)
+				if (led->l_act == BWI_LED_ACT_ASSOC)
 					on = 0;
 				break;
 			}
 			break;
 		}
 
-		if (led->l_flags & BWI_LED_F_ACTLOW)
-			on = !on;
+		val = bwi_led_onoff(led, val, on);
+	}
+	CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val);
+}
+static void
+bwi_led_event(struct bwi_softc *sc, int event)
+{
+	struct bwi_led *led = sc->sc_blink_led;
+	int rate;
+
+	if (event == BWI_LED_EVENT_POLL) {
+		if ((led->l_flags & BWI_LED_F_POLLABLE) == 0)
+			return;
+		if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
+			return;
+	}
+
+	sc->sc_led_ticks = ticks;
+	if (sc->sc_led_blinking)
+		return;
+
+	switch (event) {
+	case BWI_LED_EVENT_RX:
+		rate = sc->sc_rx_rate;
+		break;
+	case BWI_LED_EVENT_TX:
+		rate = sc->sc_tx_rate;
+		break;
+	case BWI_LED_EVENT_POLL:
+		rate = 0;
+		break;
+	default:
+		panic("unknown LED event %d\n", event);
+		break;
+	}
+	bwi_led_blink_start(sc, bwi_led_duration[rate].on_dur,
+	    bwi_led_duration[rate].off_dur);
+}
+
+static void
+bwi_led_blink_start(struct bwi_softc *sc, int on_dur, int off_dur)
+{
+	struct bwi_led *led = sc->sc_blink_led;
+	uint16_t val;
+
+	val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL);
+	val = bwi_led_onoff(led, val, 1);
+	CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val);
 
-		if (on)
-			val |= (1 << i);
-		else
-			val &= ~(1 << i);
+	if (led->l_flags & BWI_LED_F_SLOW) {
+		BWI_LED_SLOWDOWN(on_dur);
+		BWI_LED_SLOWDOWN(off_dur);
 	}
+
+	sc->sc_led_blinking = 1;
+	sc->sc_led_blink_offdur = off_dur;
+
+	callout_reset(&sc->sc_led_blink_ch, on_dur, bwi_led_blink_next, sc);
+}
+
+static void
+bwi_led_blink_next(void *xsc)
+{
+	struct bwi_softc *sc = xsc;
+	uint16_t val;
+
+	val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL);
+	val = bwi_led_onoff(sc->sc_blink_led, val, 0);
 	CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val);
+
+	callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
+	    bwi_led_blink_end, sc);
+}
+
+static void
+bwi_led_blink_end(void *xsc)
+{
+	struct bwi_softc *sc = xsc;
+	sc->sc_led_blinking = 0;
 }
 
 /*

==== //depot/projects/wifi/sys/dev/bwi/if_bwireg.h#4 (text+ko) ====

@@ -412,17 +412,35 @@
 #define BWI_LED_ACT_MASK		__BITS(6, 0)
 #define BWI_LED_ACT_OFF			0
 #define BWI_LED_ACT_ON			1
-#define BWI_LED_ACT_ACTIVE		2
-#define BWI_LED_ACT_RFEN		3
+#define BWI_LED_ACT_BLINK		2
+#define BWI_LED_ACT_RF_ENABLED		3
 #define BWI_LED_ACT_5GHZ		4
 #define BWI_LED_ACT_2GHZ		5
 #define BWI_LED_ACT_11G			6
-#define BWI_LED_ACT_MID			7
-#define BWI_LED_ACT_FAST		8
+#define BWI_LED_ACT_BLINK_SLOW		7
+#define BWI_LED_ACT_BLINK_POLL		8
 #define BWI_LED_ACT_UNKN		9
-#define BWI_LED_ACT_RUN			10
+#define BWI_LED_ACT_ASSOC		10
 #define BWI_LED_ACT_NULL		11
 
+#define BWI_VENDOR_LED_ACT_COMPAQ	\
+	BWI_LED_ACT_RF_ENABLED,		\
+	BWI_LED_ACT_2GHZ,		\
+	BWI_LED_ACT_5GHZ,		\
+	BWI_LED_ACT_OFF
+
+#define BWI_VENDOR_LED_ACT_LINKSYS	\
+	BWI_LED_ACT_ASSOC,		\
+	BWI_LED_ACT_2GHZ,		\
+	BWI_LED_ACT_5GHZ,		\
+	BWI_LED_ACT_OFF
+
+#define BWI_VENDOR_LED_ACT_DEFAULT	\
+	BWI_LED_ACT_BLINK,		\
+	BWI_LED_ACT_2GHZ,		\
+	BWI_LED_ACT_5GHZ,		\
+	BWI_LED_ACT_OFF
+
 /*
  * BBP IDs
  */

==== //depot/projects/wifi/sys/dev/bwi/if_bwivar.h#5 (text+ko) ====

@@ -55,6 +55,12 @@
 #define BWI_SHRETRY_FB		3
 #define BWI_LGRETRY_FB		2
 
+#define BWI_LED_EVENT_NONE	-1
+#define BWI_LED_EVENT_POLL	0
+#define BWI_LED_EVENT_TX	1
+#define BWI_LED_EVENT_RX	2
+#define BWI_LED_SLOWDOWN(dur)	(dur) = (((dur) * 3) / 2)
+
 #define BWI_NOISE_FLOOR		-95	/* TODO: noise floor calc */
 #define BWI_FRAME_MIN_LEN(hdr)	\
 	((hdr) + sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN)
@@ -284,9 +290,13 @@
 struct bwi_led {
 	uint8_t			l_flags;	/* BWI_LED_F_ */
 	uint8_t			l_act;		/* BWI_LED_ACT_ */
+	uint8_t			l_mask;
 };
 
 #define BWI_LED_F_ACTLOW	0x1
+#define BWI_LED_F_BLINK		0x2
+#define BWI_LED_F_POLLABLE	0x4
+#define BWI_LED_F_SLOW		0x8
 
 enum bwi_clock_mode {
 	BWI_CLOCK_MODE_SLOW,
@@ -543,6 +553,14 @@
 	int			sc_nmac;
 	struct bwi_mac		sc_mac[BWI_MAC_MAX];
 
+	int			sc_rx_rate;
+	int			sc_tx_rate;
+
+	int			sc_led_blinking;
+	int			sc_led_ticks;
+	struct bwi_led		*sc_blink_led;
+	struct callout		sc_led_blink_ch;
+	int			sc_led_blink_offdur;
 	struct bwi_led		sc_leds[BWI_LED_MAX];
 
 	enum bwi_bus_space	sc_bus_space;
@@ -582,7 +600,7 @@
 
 	void			(*sc_setup_rxdesc)
 				(struct bwi_softc *, int, bus_addr_t, int);
-	void			(*sc_rxeof)(struct bwi_softc *);
+	int			(*sc_rxeof)(struct bwi_softc *);
 
 	void			(*sc_setup_txdesc)
 				(struct bwi_softc *, struct bwi_ring_data *,
@@ -595,6 +613,8 @@
 	/* Sysctl variables */
 	int			sc_fw_version;	/* BWI_FW_VERSION[34] */
 	int			sc_dwell_time;	/* milliseconds */
+	int			sc_led_idle;
+	int			sc_led_blink;
 };
 
 #define BWI_F_BUS_INITED	0x1


More information about the p4-projects mailing list