Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 18 Jun 2011 12:03:30 +0000 (UTC)
From:      Bernhard Schmidt <bschmidt@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r223249 - stable/8/sys/dev/iwn
Message-ID:  <201106181203.p5IC3UqF040047@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bschmidt
Date: Sat Jun 18 12:03:30 2011
New Revision: 223249
URL: http://svn.freebsd.org/changeset/base/223249

Log:
  MFC r220727-220728:
  - Read RX/TX chainmasks directly of the EEPROM. Some chips are known to
    have the wrong/broken information stored, keep the hardcoded values for
    those.
  - Bring over the HAL/OPS changes, instead of two const structs it is now
    slightly more dynamic.
  
  Obtained from:	OpenBSD

Modified:
  stable/8/sys/dev/iwn/if_iwn.c
  stable/8/sys/dev/iwn/if_iwnvar.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/dev/iwn/if_iwn.c
==============================================================================
--- stable/8/sys/dev/iwn/if_iwn.c	Sat Jun 18 12:00:49 2011	(r223248)
+++ stable/8/sys/dev/iwn/if_iwn.c	Sat Jun 18 12:03:30 2011	(r223249)
@@ -115,7 +115,8 @@ static const struct iwn_ident iwn_ident_
 
 static int	iwn_probe(device_t);
 static int	iwn_attach(device_t);
-static const struct iwn_hal *iwn_hal_attach(struct iwn_softc *);
+static int	iwn4965_attach(struct iwn_softc *, uint16_t);
+static int	iwn5000_attach(struct iwn_softc *, uint16_t);
 static void	iwn_radiotap_attach(struct iwn_softc *);
 static void	iwn_sysctlattach(struct iwn_softc *);
 static struct ieee80211vap *iwn_vap_create(struct ieee80211com *,
@@ -410,62 +411,6 @@ MODULE_DEPEND(iwn, firmware, 1, 1, 1);
 MODULE_DEPEND(iwn, pci, 1, 1, 1);
 MODULE_DEPEND(iwn, wlan, 1, 1, 1);
 
-static const struct iwn_hal iwn4965_hal = {
-	iwn4965_load_firmware,
-	iwn4965_read_eeprom,
-	iwn4965_post_alive,
-	iwn4965_nic_config,
-	iwn4965_update_sched,
-	iwn4965_get_temperature,
-	iwn4965_get_rssi,
-	iwn4965_set_txpower,
-	iwn4965_init_gains,
-	iwn4965_set_gains,
-	iwn4965_add_node,
-	iwn4965_tx_done,
-#if 0	/* HT */
-	iwn4965_ampdu_tx_start,
-	iwn4965_ampdu_tx_stop,
-#endif
-	IWN4965_NTXQUEUES,
-	IWN4965_NDMACHNLS,
-	IWN4965_ID_BROADCAST,
-	IWN4965_RXONSZ,
-	IWN4965_SCHEDSZ,
-	IWN4965_FW_TEXT_MAXSZ,
-	IWN4965_FW_DATA_MAXSZ,
-	IWN4965_FWSZ,
-	IWN4965_SCHED_TXFACT
-};
-
-static const struct iwn_hal iwn5000_hal = {
-	iwn5000_load_firmware,
-	iwn5000_read_eeprom,
-	iwn5000_post_alive,
-	iwn5000_nic_config,
-	iwn5000_update_sched,
-	iwn5000_get_temperature,
-	iwn5000_get_rssi,
-	iwn5000_set_txpower,
-	iwn5000_init_gains,
-	iwn5000_set_gains,
-	iwn5000_add_node,
-	iwn5000_tx_done,
-#if 0	/* HT */
-	iwn5000_ampdu_tx_start,
-	iwn5000_ampdu_tx_stop,
-#endif
-	IWN5000_NTXQUEUES,
-	IWN5000_NDMACHNLS,
-	IWN5000_ID_BROADCAST,
-	IWN5000_RXONSZ,
-	IWN5000_SCHEDSZ,
-	IWN5000_FW_TEXT_MAXSZ,
-	IWN5000_FW_DATA_MAXSZ,
-	IWN5000_FWSZ,
-	IWN5000_SCHED_TXFACT
-};
-
 static int
 iwn_probe(device_t dev)
 {
@@ -487,7 +432,6 @@ iwn_attach(device_t dev)
 	struct iwn_softc *sc = (struct iwn_softc *)device_get_softc(dev);
 	struct ieee80211com *ic;
 	struct ifnet *ifp;
-	const struct iwn_hal *hal;
 	uint32_t reg;
 	int i, error, result;
 	uint8_t macaddr[IEEE80211_ADDR_LEN];
@@ -545,10 +489,15 @@ iwn_attach(device_t dev)
 
 	IWN_LOCK_INIT(sc);
 
-	/* Attach Hardware Abstraction Layer. */
-	hal = iwn_hal_attach(sc);
-	if (hal == NULL) {
-		error = ENXIO;	/* XXX: Wrong error code? */
+	/* Read hardware revision and attach. */
+	sc->hw_type = (IWN_READ(sc, IWN_HW_REV) >> 4) & 0xf;
+	if (sc->hw_type == IWN_HW_REV_TYPE_4965)
+		error = iwn4965_attach(sc, pci_get_device(dev));
+	else
+		error = iwn5000_attach(sc, pci_get_device(dev));
+	if (error != 0) {
+		device_printf(dev, "could not attach device, error %d\n",
+		    error);
 		goto fail;
 	}
 
@@ -588,7 +537,7 @@ iwn_attach(device_t dev)
 	}
 
 	/* Allocate TX rings (16 on 4965AGN, 20 on >=5000). */
-	for (i = 0; i < hal->ntxqs; i++) {
+	for (i = 0; i < sc->ntxqs; i++) {
 		if ((error = iwn_alloc_tx_ring(sc, &sc->txq[i], i)) != 0) {
 			device_printf(dev,
 			    "could not allocate TX ring %d, error %d\n", i,
@@ -754,85 +703,121 @@ fail:
 	return error;
 }
 
-static const struct iwn_hal *
-iwn_hal_attach(struct iwn_softc *sc)
+static int
+iwn4965_attach(struct iwn_softc *sc, uint16_t pid)
 {
-	sc->hw_type = (IWN_READ(sc, IWN_HW_REV) >> 4) & 0xf;
+	struct iwn_ops *ops = &sc->ops;
+
+	ops->load_firmware = iwn4965_load_firmware;
+	ops->read_eeprom = iwn4965_read_eeprom;
+	ops->post_alive = iwn4965_post_alive;
+	ops->nic_config = iwn4965_nic_config;
+	ops->update_sched = iwn4965_update_sched;
+	ops->get_temperature = iwn4965_get_temperature;
+	ops->get_rssi = iwn4965_get_rssi;
+	ops->set_txpower = iwn4965_set_txpower;
+	ops->init_gains = iwn4965_init_gains;
+	ops->set_gains = iwn4965_set_gains;
+	ops->add_node = iwn4965_add_node;
+	ops->tx_done = iwn4965_tx_done;
+#if 0	/* HT */
+	ops->ampdu_tx_start = iwn4965_ampdu_tx_start;
+	ops->ampdu_tx_stop = iwn4965_ampdu_tx_stop;
+#endif
+	sc->ntxqs = IWN4965_NTXQUEUES;
+	sc->ndmachnls = IWN4965_NDMACHNLS;
+	sc->broadcast_id = IWN4965_ID_BROADCAST;
+	sc->rxonsz = IWN4965_RXONSZ;
+	sc->schedsz = IWN4965_SCHEDSZ;
+	sc->fw_text_maxsz = IWN4965_FW_TEXT_MAXSZ;
+	sc->fw_data_maxsz = IWN4965_FW_DATA_MAXSZ;
+	sc->fwsz = IWN4965_FWSZ;
+	sc->sched_txfact_addr = IWN4965_SCHED_TXFACT;
+	sc->limits = &iwn4965_sensitivity_limits;
+	sc->fwname = "iwn4965fw";
+	/* Override chains masks, ROM is known to be broken. */
+	sc->txchainmask = IWN_ANT_AB;
+	sc->rxchainmask = IWN_ANT_ABC;
+
+	return 0;
+}
+
+static int
+iwn5000_attach(struct iwn_softc *sc, uint16_t pid)
+{
+	struct iwn_ops *ops = &sc->ops;
+
+	ops->load_firmware = iwn5000_load_firmware;
+	ops->read_eeprom = iwn5000_read_eeprom;
+	ops->post_alive = iwn5000_post_alive;
+	ops->nic_config = iwn5000_nic_config;
+	ops->update_sched = iwn5000_update_sched;
+	ops->get_temperature = iwn5000_get_temperature;
+	ops->get_rssi = iwn5000_get_rssi;
+	ops->set_txpower = iwn5000_set_txpower;
+	ops->init_gains = iwn5000_init_gains;
+	ops->set_gains = iwn5000_set_gains;
+	ops->add_node = iwn5000_add_node;
+	ops->tx_done = iwn5000_tx_done;
+#if 0	/* HT */
+	ops->ampdu_tx_start = iwn5000_ampdu_tx_start;
+	ops->ampdu_tx_stop = iwn5000_ampdu_tx_stop;
+#endif
+	sc->ntxqs = IWN5000_NTXQUEUES;
+	sc->ndmachnls = IWN5000_NDMACHNLS;
+	sc->broadcast_id = IWN5000_ID_BROADCAST;
+	sc->rxonsz = IWN5000_RXONSZ;
+	sc->schedsz = IWN5000_SCHEDSZ;
+	sc->fw_text_maxsz = IWN5000_FW_TEXT_MAXSZ;
+	sc->fw_data_maxsz = IWN5000_FW_DATA_MAXSZ;
+	sc->fwsz = IWN5000_FWSZ;
+	sc->sched_txfact_addr = IWN5000_SCHED_TXFACT;
 
 	switch (sc->hw_type) {
-	case IWN_HW_REV_TYPE_4965:
-		sc->sc_hal = &iwn4965_hal;
-		sc->limits = &iwn4965_sensitivity_limits;
-		sc->fwname = "iwn4965fw";
-		sc->txchainmask = IWN_ANT_AB;
-		sc->rxchainmask = IWN_ANT_ABC;
-		break;
 	case IWN_HW_REV_TYPE_5100:
-		sc->sc_hal = &iwn5000_hal;
 		sc->limits = &iwn5000_sensitivity_limits;
 		sc->fwname = "iwn5000fw";
+		/* Override chains masks, ROM is known to be broken. */
 		sc->txchainmask = IWN_ANT_B;
 		sc->rxchainmask = IWN_ANT_AB;
 		break;
 	case IWN_HW_REV_TYPE_5150:
-		sc->sc_hal = &iwn5000_hal;
 		sc->limits = &iwn5150_sensitivity_limits;
 		sc->fwname = "iwn5150fw";
-		sc->txchainmask = IWN_ANT_A;
-		sc->rxchainmask = IWN_ANT_AB;
 		break;
 	case IWN_HW_REV_TYPE_5300:
 	case IWN_HW_REV_TYPE_5350:
-		sc->sc_hal = &iwn5000_hal;
 		sc->limits = &iwn5000_sensitivity_limits;
 		sc->fwname = "iwn5000fw";
-		sc->txchainmask = IWN_ANT_ABC;
-		sc->rxchainmask = IWN_ANT_ABC;
 		break;
 	case IWN_HW_REV_TYPE_1000:
-		sc->sc_hal = &iwn5000_hal;
 		sc->limits = &iwn1000_sensitivity_limits;
 		sc->fwname = "iwn1000fw";
-		sc->txchainmask = IWN_ANT_A;
-		sc->rxchainmask = IWN_ANT_AB;
 		break;
 	case IWN_HW_REV_TYPE_6000:
-		sc->sc_hal = &iwn5000_hal;
 		sc->limits = &iwn6000_sensitivity_limits;
 		sc->fwname = "iwn6000fw";
-		switch (pci_get_device(sc->sc_dev)) {
-		case 0x422C:
-		case 0x4239:
+		if (pid == 0x422c || pid == 0x4239) {
 			sc->sc_flags |= IWN_FLAG_INTERNAL_PA;
+			/* Override chains masks, ROM is known to be broken. */
 			sc->txchainmask = IWN_ANT_BC;
 			sc->rxchainmask = IWN_ANT_BC;
-			break;
-		default:
-			sc->txchainmask = IWN_ANT_ABC;
-			sc->rxchainmask = IWN_ANT_ABC;
-			break;
 		}
 		break;
 	case IWN_HW_REV_TYPE_6050:
-		sc->sc_hal = &iwn5000_hal;
 		sc->limits = &iwn6000_sensitivity_limits;
 		sc->fwname = "iwn6050fw";
-		sc->txchainmask = IWN_ANT_AB;
-		sc->rxchainmask = IWN_ANT_AB;
 		break;
 	case IWN_HW_REV_TYPE_6005:
-		sc->sc_hal = &iwn5000_hal;
 		sc->limits = &iwn6000_sensitivity_limits;
 		sc->fwname = "iwn6005fw";
-		sc->txchainmask = IWN_ANT_AB;
-		sc->rxchainmask = IWN_ANT_AB;
 		break;
 	default:
 		device_printf(sc->sc_dev, "adapter type %d not supported\n",
 		    sc->hw_type);
-		return NULL;
+		return ENOTSUP;
 	}
-	return sc->sc_hal;
+	return 0;
 }
 
 /*
@@ -934,9 +919,8 @@ iwn_detach(device_t dev)
 
 	/* Free DMA resources. */
 	iwn_free_rx_ring(sc, &sc->rxq);
-	if (sc->sc_hal != NULL)
-		for (qid = 0; qid < sc->sc_hal->ntxqs; qid++)
-			iwn_free_tx_ring(sc, &sc->txq[qid]);
+	for (qid = 0; qid < sc->ntxqs; qid++)
+		iwn_free_tx_ring(sc, &sc->txq[qid]);
 	iwn_free_sched(sc);
 	iwn_free_kw(sc);
 	if (sc->ict != NULL)
@@ -1298,7 +1282,7 @@ iwn_alloc_sched(struct iwn_softc *sc)
 {
 	/* TX scheduler rings must be aligned on a 1KB boundary. */
 	return iwn_dma_contig_alloc(sc, &sc->sched_dma, (void **)&sc->sched,
-	    sc->sc_hal->schedsz, 1024);
+	    sc->schedsz, 1024);
 }
 
 static void
@@ -1338,8 +1322,7 @@ static int
 iwn_alloc_fwmem(struct iwn_softc *sc)
 {
 	/* Must be aligned on a 16-byte boundary. */
-	return iwn_dma_contig_alloc(sc, &sc->fw_dma, NULL, sc->sc_hal->fwsz,
-	    16);
+	return iwn_dma_contig_alloc(sc, &sc->fw_dma, NULL, sc->fwsz, 16);
 }
 
 static void
@@ -1633,7 +1616,7 @@ iwn5000_ict_reset(struct iwn_softc *sc)
 static int
 iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])
 {
-	const struct iwn_hal *hal = sc->sc_hal;
+	struct iwn_ops *ops = &sc->ops;
 	uint16_t val;
 	int error;
 
@@ -1673,12 +1656,17 @@ iwn_read_eeprom(struct iwn_softc *sc, ui
 	iwn_read_prom_data(sc, IWN_EEPROM_RFCFG, &val, 2);
 	sc->rfcfg = le16toh(val);
 	DPRINTF(sc, IWN_DEBUG_RESET, "radio config=0x%04x\n", sc->rfcfg);
+	/* Read Tx/Rx chains from ROM unless it's known to be broken. */
+	if (sc->txchainmask == 0)
+		sc->txchainmask = IWN_RFCFG_TXANTMSK(sc->rfcfg);
+	if (sc->rxchainmask == 0)
+		sc->rxchainmask = IWN_RFCFG_RXANTMSK(sc->rfcfg);
 
 	/* Read MAC address. */
 	iwn_read_prom_data(sc, IWN_EEPROM_MAC, macaddr, 6);
 
 	/* Read adapter-specific information from EEPROM. */
-	hal->read_eeprom(sc);
+	ops->read_eeprom(sc);
 
 	iwn_apm_stop(sc);	/* Power OFF adapter. */
 
@@ -2203,7 +2191,7 @@ static void
 iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
     struct iwn_rx_data *data)
 {
-	const struct iwn_hal *hal = sc->sc_hal;
+	struct iwn_ops *ops = &sc->ops;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	struct iwn_rx_ring *ring = &sc->rxq;
@@ -2311,7 +2299,7 @@ iwn_rx_done(struct iwn_softc *sc, struct
 	nf = (ni != NULL && ni->ni_vap->iv_state == IEEE80211_S_RUN &&
 	    (ic->ic_flags & IEEE80211_F_SCAN) == 0) ? sc->noise : -95;
 
-	rssi = hal->get_rssi(sc, stat);
+	rssi = ops->get_rssi(sc, stat);
 
 	if (ieee80211_radiotap_active(ic)) {
 		struct iwn_rx_radiotap_header *tap = &sc->sc_rxtap;
@@ -2436,7 +2424,7 @@ static void
 iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc,
     struct iwn_rx_data *data)
 {
-	const struct iwn_hal *hal = sc->sc_hal;
+	struct iwn_ops *ops = &sc->ops;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
@@ -2459,7 +2447,7 @@ iwn_rx_statistics(struct iwn_softc *sc, 
 	if (stats->general.temp != sc->rawtemp) {
 		/* Convert "raw" temperature to degC. */
 		sc->rawtemp = stats->general.temp;
-		temp = hal->get_temperature(sc);
+		temp = ops->get_temperature(sc);
 		DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: temperature %d\n",
 		    __func__, temp);
 
@@ -2634,6 +2622,7 @@ iwn_cmd_done(struct iwn_softc *sc, struc
 static void
 iwn_notif_intr(struct iwn_softc *sc)
 {
+	struct iwn_ops *ops = &sc->ops;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
@@ -2680,7 +2669,7 @@ iwn_notif_intr(struct iwn_softc *sc)
 
 		case IWN_TX_DONE:
 			/* An 802.11 frame has been transmitted. */
-			sc->sc_hal->tx_done(sc, desc, data);
+			ops->tx_done(sc, desc, data);
 			break;
 
 		case IWN_RX_STATISTICS:
@@ -2818,7 +2807,7 @@ iwn_wakeup_intr(struct iwn_softc *sc)
 
 	/* Wakeup RX and TX rings. */
 	IWN_WRITE(sc, IWN_FH_RX_WPTR, sc->rxq.cur & ~7);
-	for (qid = 0; qid < sc->sc_hal->ntxqs; qid++) {
+	for (qid = 0; qid < sc->ntxqs; qid++) {
 		struct iwn_tx_ring *ring = &sc->txq[qid];
 		IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | ring->cur);
 	}
@@ -2849,7 +2838,6 @@ iwn_rftoggle_intr(struct iwn_softc *sc)
 static void
 iwn_fatal_intr(struct iwn_softc *sc)
 {
-	const struct iwn_hal *hal = sc->sc_hal;
 	struct iwn_fw_dump dump;
 	int i;
 
@@ -2861,7 +2849,7 @@ iwn_fatal_intr(struct iwn_softc *sc)
 	/* Check that the error log address is valid. */
 	if (sc->errptr < IWN_FW_DATA_BASE ||
 	    sc->errptr + sizeof (dump) >
-	    IWN_FW_DATA_BASE + hal->fw_data_maxsz) {
+	    IWN_FW_DATA_BASE + sc->fw_data_maxsz) {
 		printf("%s: bad firmware error log address 0x%08x\n", __func__,
 		    sc->errptr);
 		return;
@@ -2896,7 +2884,7 @@ iwn_fatal_intr(struct iwn_softc *sc)
 
 	/* Dump driver status (TX and RX rings) while we're here. */
 	printf("driver status:\n");
-	for (i = 0; i < hal->ntxqs; i++) {
+	for (i = 0; i < sc->ntxqs; i++) {
 		struct iwn_tx_ring *ring = &sc->txq[i];
 		printf("  tx ring %2d: qid=%-2d cur=%-3d queued=%-3d\n",
 		    i, ring->qid, ring->cur, ring->queued);
@@ -3069,7 +3057,6 @@ iwn_plcp_signal(int rate) {
 static int
 iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
 {
-	const struct iwn_hal *hal = sc->sc_hal;
 	const struct ieee80211_txparam *tp;
 	struct ieee80211vap *vap = ni->ni_vap;
 	struct ieee80211com *ic = ni->ni_ic;
@@ -3200,7 +3187,7 @@ iwn_tx_data(struct iwn_softc *sc, struct
 
 	if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
 	    type != IEEE80211_FC0_TYPE_DATA)
-		tx->id = hal->broadcast_id;
+		tx->id = sc->broadcast_id;
 	else
 		tx->id = wn->id;
 
@@ -3232,7 +3219,7 @@ iwn_tx_data(struct iwn_softc *sc, struct
 	tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
 	tx->plcp = rinfo->plcp;
 	tx->rflags = rinfo->flags;
-	if (tx->id == hal->broadcast_id) {
+	if (tx->id == sc->broadcast_id) {
 		/* Group or management frame. */
 		tx->linkq = 0;
 		/* XXX Alternate between antenna A and B? */
@@ -3314,7 +3301,7 @@ iwn_tx_data(struct iwn_softc *sc, struct
 
 #ifdef notyet
 	/* Update TX scheduler. */
-	hal->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
+	ops->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
 #endif
 
 	/* Kick TX ring. */
@@ -3332,7 +3319,6 @@ static int
 iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,
     struct ieee80211_node *ni, const struct ieee80211_bpf_params *params)
 {
-	const struct iwn_hal *hal = sc->sc_hal;
 	const struct iwn_rate *rinfo;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211vap *vap = ni->ni_vap;
@@ -3437,7 +3423,7 @@ iwn_tx_data_raw(struct iwn_softc *sc, st
 
 	tx->len = htole16(totlen);
 	tx->tid = 0;
-	tx->id = hal->broadcast_id;
+	tx->id = sc->broadcast_id;
 	tx->rts_ntries = params->ibp_try1;
 	tx->data_ntries = params->ibp_try0;
 	tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
@@ -3519,7 +3505,7 @@ iwn_tx_data_raw(struct iwn_softc *sc, st
 
 #ifdef notyet
 	/* Update TX scheduler. */
-	hal->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
+	ops->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
 #endif
 
 	/* Kick TX ring. */
@@ -3744,7 +3730,7 @@ iwn_cmd(struct iwn_softc *sc, int code, 
 
 #ifdef notyet
 	/* Update TX scheduler. */
-	sc->sc_hal->update_sched(sc, ring->qid, ring->cur, 0, 0);
+	ops->update_sched(sc, ring->qid, ring->cur, 0, 0);
 #endif
 
 	/* Kick command ring. */
@@ -3821,7 +3807,7 @@ iwn_set_link_quality(struct iwn_softc *s
 static int
 iwn_add_broadcast_node(struct iwn_softc *sc, int async)
 {
-	const struct iwn_hal *hal = sc->sc_hal;
+	struct iwn_ops *ops = &sc->ops;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	struct iwn_node_info node;
@@ -3832,16 +3818,16 @@ iwn_add_broadcast_node(struct iwn_softc 
 
 	memset(&node, 0, sizeof node);
 	IEEE80211_ADDR_COPY(node.macaddr, ifp->if_broadcastaddr);
-	node.id = hal->broadcast_id;
+	node.id = sc->broadcast_id;
 	DPRINTF(sc, IWN_DEBUG_RESET, "%s: adding broadcast node\n", __func__);
-	if ((error = hal->add_node(sc, &node, async)) != 0)
+	if ((error = ops->add_node(sc, &node, async)) != 0)
 		return error;
 
 	/* Use the first valid TX antenna. */
 	txant = IWN_LSB(sc->txchainmask);
 
 	memset(&linkq, 0, sizeof linkq);
-	linkq.id = sc->sc_hal->broadcast_id;
+	linkq.id = sc->broadcast_id;
 	linkq.antmsk_1stream = txant;
 	linkq.antmsk_2stream = IWN_ANT_AB;
 	linkq.ampdu_max = 64;
@@ -4266,7 +4252,7 @@ iwn5000_get_temperature(struct iwn_softc
 static int
 iwn_init_sensitivity(struct iwn_softc *sc)
 {
-	const struct iwn_hal *hal = sc->sc_hal;
+	struct iwn_ops *ops = &sc->ops;
 	struct iwn_calib_state *calib = &sc->calib;
 	uint32_t flags;
 	int error;
@@ -4289,7 +4275,7 @@ iwn_init_sensitivity(struct iwn_softc *s
 		return error;
 
 	/* Write initial gains. */
-	if ((error = hal->init_gains(sc)) != 0)
+	if ((error = ops->init_gains(sc)) != 0)
 		return error;
 
 	/* Request statistics at each beacon interval. */
@@ -4308,7 +4294,7 @@ static void
 iwn_collect_noise(struct iwn_softc *sc,
     const struct iwn_rx_general_stats *stats)
 {
-	const struct iwn_hal *hal = sc->sc_hal;
+	struct iwn_ops *ops = &sc->ops;
 	struct iwn_calib_state *calib = &sc->calib;
 	uint32_t val;
 	int i;
@@ -4339,13 +4325,13 @@ iwn_collect_noise(struct iwn_softc *sc,
 	if ((sc->chainmask & sc->txchainmask) == 0)
 		sc->chainmask |= IWN_LSB(sc->txchainmask);
 
-	(void)hal->set_gains(sc);
+	(void)ops->set_gains(sc);
 	calib->state = IWN_CALIB_STATE_RUN;
 
 #ifdef notyet
 	/* XXX Disable RX chains with no antennas connected. */
 	sc->rxon.rxchain = htole16(IWN_RXCHAIN_SEL(sc->chainmask));
-	(void)iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 1);
+	(void)iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, sc->rxonsz, 1);
 #endif
 
 #if 0
@@ -4708,7 +4694,7 @@ iwn_send_btcoex(struct iwn_softc *sc)
 static int
 iwn_config(struct iwn_softc *sc)
 {
-	const struct iwn_hal *hal = sc->sc_hal;
+	struct iwn_ops *ops = &sc->ops;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	uint32_t txmask;
@@ -4782,7 +4768,7 @@ iwn_config(struct iwn_softc *sc)
 	    IWN_RXCHAIN_IDLE_COUNT(2);
 	sc->rxon.rxchain = htole16(rxchain);
 	DPRINTF(sc, IWN_DEBUG_RESET, "%s: setting configuration\n", __func__);
-	error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 0);
+	error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, sc->rxonsz, 0);
 	if (error != 0) {
 		device_printf(sc->sc_dev, "%s: RXON command failed\n",
 		    __func__);
@@ -4796,7 +4782,7 @@ iwn_config(struct iwn_softc *sc)
 	}
 
 	/* Configuration has changed, set TX power accordingly. */
-	if ((error = hal->set_txpower(sc, ic->ic_curchan, 0)) != 0) {
+	if ((error = ops->set_txpower(sc, ic->ic_curchan, 0)) != 0) {
 		device_printf(sc->sc_dev, "%s: could not set TX power\n",
 		    __func__);
 		return error;
@@ -4878,7 +4864,7 @@ iwn_scan(struct iwn_softc *sc)
 
 	tx = (struct iwn_cmd_data *)(hdr + 1);
 	tx->flags = htole32(IWN_TX_AUTO_SEQ);
-	tx->id = sc->sc_hal->broadcast_id;
+	tx->id = sc->broadcast_id;
 	tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
 
 	if (IEEE80211_IS_CHAN_A(ic->ic_curchan)) {
@@ -4986,7 +4972,7 @@ iwn_scan(struct iwn_softc *sc)
 static int
 iwn_auth(struct iwn_softc *sc, struct ieee80211vap *vap)
 {
-	const struct iwn_hal *hal = sc->sc_hal;
+	struct iwn_ops *ops = &sc->ops;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	struct ieee80211_node *ni = vap->iv_bss;
@@ -5016,7 +5002,7 @@ iwn_auth(struct iwn_softc *sc, struct ie
 	DPRINTF(sc, IWN_DEBUG_STATE, "rxon chan %d flags %x cck %x ofdm %x\n",
 	    sc->rxon.chan, sc->rxon.flags, sc->rxon.cck_mask,
 	    sc->rxon.ofdm_mask);
-	error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 1);
+	error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, sc->rxonsz, 1);
 	if (error != 0) {
 		device_printf(sc->sc_dev, "%s: RXON command failed, error %d\n",
 		    __func__, error);
@@ -5024,7 +5010,7 @@ iwn_auth(struct iwn_softc *sc, struct ie
 	}
 
 	/* Configuration has changed, set TX power accordingly. */
-	if ((error = hal->set_txpower(sc, ni->ni_chan, 1)) != 0) {
+	if ((error = ops->set_txpower(sc, ni->ni_chan, 1)) != 0) {
 		device_printf(sc->sc_dev,
 		    "%s: could not set TX power, error %d\n", __func__, error);
 		return error;
@@ -5046,7 +5032,7 @@ static int
 iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
 {
 #define	MS(v,x)	(((v) & x) >> x##_S)
-	const struct iwn_hal *hal = sc->sc_hal;
+	struct iwn_ops *ops = &sc->ops;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	struct ieee80211_node *ni = vap->iv_bss;
@@ -5109,7 +5095,7 @@ iwn_run(struct iwn_softc *sc, struct iee
 	sc->rxon.filter |= htole32(IWN_FILTER_BSS);
 	DPRINTF(sc, IWN_DEBUG_STATE, "rxon chan %d flags %x\n",
 	    sc->rxon.chan, sc->rxon.flags);
-	error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 1);
+	error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, sc->rxonsz, 1);
 	if (error != 0) {
 		device_printf(sc->sc_dev,
 		    "%s: could not update configuration, error %d\n", __func__,
@@ -5118,7 +5104,7 @@ iwn_run(struct iwn_softc *sc, struct iee
 	}
 
 	/* Configuration has changed, set TX power accordingly. */
-	if ((error = hal->set_txpower(sc, ni->ni_chan, 1)) != 0) {
+	if ((error = ops->set_txpower(sc, ni->ni_chan, 1)) != 0) {
 		device_printf(sc->sc_dev,
 		    "%s: could not set TX power, error %d\n", __func__, error);
 		return error;
@@ -5137,7 +5123,7 @@ iwn_run(struct iwn_softc *sc, struct iee
 	    IWN_AMDPU_DENSITY(5));	/* 2us */
 #endif
 	DPRINTF(sc, IWN_DEBUG_STATE, "%s: adding BSS node\n", __func__);
-	error = hal->add_node(sc, &node, 1);
+	error = ops->add_node(sc, &node, 1);
 	if (error != 0) {
 		device_printf(sc->sc_dev,
 		    "%s: could not add BSS node, error %d\n", __func__, error);
@@ -5181,6 +5167,7 @@ iwn_ampdu_rx_start(struct ieee80211com *
 {
 	struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
 	struct iwn_softc *sc = ic->ic_softc;
+	struct iwn_ops *ops = &sc->ops;
 	struct iwn_node *wn = (void *)ni;
 	struct iwn_node_info node;
 
@@ -5192,7 +5179,7 @@ iwn_ampdu_rx_start(struct ieee80211com *
 	node.addba_ssn = htole16(ba->ba_winstart);
 	DPRINTF(sc, IWN_DEBUG_RECV, "ADDBA RA=%d TID=%d SSN=%d\n",
 	    wn->id, tid, ba->ba_winstart);
-	return sc->sc_hal->add_node(sc, &node, 1);
+	return ops->add_node(sc, &node, 1);
 }
 
 /*
@@ -5204,6 +5191,7 @@ iwn_ampdu_rx_stop(struct ieee80211com *i
     uint8_t tid)
 {
 	struct iwn_softc *sc = ic->ic_softc;
+	struct iwn_ops *ops = &sc->ops;
 	struct iwn_node *wn = (void *)ni;
 	struct iwn_node_info node;
 
@@ -5213,7 +5201,7 @@ iwn_ampdu_rx_stop(struct ieee80211com *i
 	node.flags = IWN_FLAG_SET_DELBA;
 	node.delba_tid = tid;
 	DPRINTF(sc, IWN_DEBUG_RECV, "DELBA RA=%d TID=%d\n", wn->id, tid);
-	(void)sc->sc_hal->add_node(sc, &node, 1);
+	(void)ops->add_node(sc, &node, 1);
 }
 
 /*
@@ -5226,7 +5214,7 @@ iwn_ampdu_tx_start(struct ieee80211com *
 {
 	struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
 	struct iwn_softc *sc = ic->ic_softc;
-	const struct iwn_hal *hal = sc->sc_hal;
+	struct iwn_ops *ops = &sc->ops;
 	struct iwn_node *wn = (void *)ni;
 	struct iwn_node_info node;
 	int error;
@@ -5238,13 +5226,13 @@ iwn_ampdu_tx_start(struct ieee80211com *
 	node.control = IWN_NODE_UPDATE;
 	node.flags = IWN_FLAG_SET_DISABLE_TID;
 	node.disable_tid = htole16(wn->disable_tid);
-	error = hal->add_node(sc, &node, 1);
+	error = ops->add_node(sc, &node, 1);
 	if (error != 0)
 		return error;
 
 	if ((error = iwn_nic_lock(sc)) != 0)
 		return error;
-	hal->ampdu_tx_start(sc, ni, tid, ba->ba_winstart);
+	ops->ampdu_tx_start(sc, ni, tid, ba->ba_winstart);
 	iwn_nic_unlock(sc);
 	return 0;
 }
@@ -5255,10 +5243,11 @@ iwn_ampdu_tx_stop(struct ieee80211com *i
 {
 	struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
 	struct iwn_softc *sc = ic->ic_softc;
+	struct iwn_ops *ops = &sc->ops;
 
 	if (iwn_nic_lock(sc) != 0)
 		return;
-	sc->sc_hal->ampdu_tx_stop(sc, tid, ba->ba_winstart);
+	ops->ampdu_tx_stop(sc, tid, ba->ba_winstart);
 	iwn_nic_unlock(sc);
 }
 
@@ -5968,7 +5957,6 @@ iwn_read_firmware_tlv(struct iwn_softc *
 static int
 iwn_read_firmware(struct iwn_softc *sc)
 {
-	const struct iwn_hal *hal = sc->sc_hal;
 	struct iwn_fw_info *fw = &sc->fw;
 	int error;
 
@@ -6011,10 +5999,10 @@ iwn_read_firmware(struct iwn_softc *sc)
 	}
 
 	/* Make sure text and data sections fit in hardware memory. */
-	if (fw->main.textsz > hal->fw_text_maxsz ||
-	    fw->main.datasz > hal->fw_data_maxsz ||
-	    fw->init.textsz > hal->fw_text_maxsz ||
-	    fw->init.datasz > hal->fw_data_maxsz ||
+	if (fw->main.textsz > sc->fw_text_maxsz ||
+	    fw->main.datasz > sc->fw_data_maxsz ||
+	    fw->init.textsz > sc->fw_text_maxsz ||
+	    fw->init.datasz > sc->fw_data_maxsz ||
 	    fw->boot.textsz > IWN_FW_BOOT_TEXT_MAXSZ ||
 	    (fw->boot.textsz & 3) != 0) {
 		device_printf(sc->sc_dev, "%s: firmware sections too large\n",
@@ -6232,7 +6220,7 @@ iwn_hw_prepare(struct iwn_softc *sc)
 static int
 iwn_hw_init(struct iwn_softc *sc)
 {
-	const struct iwn_hal *hal = sc->sc_hal;
+	struct iwn_ops *ops = &sc->ops;
 	int error, chnl, qid;
 
 	/* Clear pending interrupts. */
@@ -6252,7 +6240,7 @@ iwn_hw_init(struct iwn_softc *sc)
 	iwn_nic_unlock(sc);
 
 	/* Perform adapter-specific initialization. */
-	if ((error = hal->nic_config(sc)) != 0)
+	if ((error = ops->nic_config(sc)) != 0)
 		return error;
 
 	/* Initialize RX ring. */
@@ -6279,13 +6267,13 @@ iwn_hw_init(struct iwn_softc *sc)
 		return error;
 
 	/* Initialize TX scheduler. */
-	iwn_prph_write(sc, hal->sched_txfact_addr, 0);
+	iwn_prph_write(sc, sc->sched_txfact_addr, 0);
 
 	/* Set physical address of "keep warm" page (16-byte aligned). */
 	IWN_WRITE(sc, IWN_FH_KW_ADDR, sc->kw_dma.paddr >> 4);
 
 	/* Initialize TX rings. */
-	for (qid = 0; qid < hal->ntxqs; qid++) {
+	for (qid = 0; qid < sc->ntxqs; qid++) {
 		struct iwn_tx_ring *txq = &sc->txq[qid];
 
 		/* Set physical address of TX ring (256-byte aligned). */
@@ -6295,7 +6283,7 @@ iwn_hw_init(struct iwn_softc *sc)
 	iwn_nic_unlock(sc);
 
 	/* Enable DMA channels. */
-	for (chnl = 0; chnl < hal->ndmachnls; chnl++) {
+	for (chnl = 0; chnl < sc->ndmachnls; chnl++) {
 		IWN_WRITE(sc, IWN_FH_TX_CONFIG(chnl),
 		    IWN_FH_TX_CONFIG_DMA_ENA |
 		    IWN_FH_TX_CONFIG_DMA_CREDIT_ENA);
@@ -6316,7 +6304,7 @@ iwn_hw_init(struct iwn_softc *sc)
 	IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL);
 	IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL);
 
-	if ((error = hal->load_firmware(sc)) != 0) {
+	if ((error = ops->load_firmware(sc)) != 0) {
 		device_printf(sc->sc_dev,
 		    "%s: could not load firmware, error %d\n", __func__,
 		    error);
@@ -6330,13 +6318,12 @@ iwn_hw_init(struct iwn_softc *sc)
 		return error;
 	}
 	/* Do post-firmware initialization. */
-	return hal->post_alive(sc);
+	return ops->post_alive(sc);
 }
 
 static void
 iwn_hw_stop(struct iwn_softc *sc)
 {
-	const struct iwn_hal *hal = sc->sc_hal;
 	int chnl, qid, ntries;
 
 	IWN_WRITE(sc, IWN_RESET, IWN_RESET_NEVO);
@@ -6351,11 +6338,11 @@ iwn_hw_stop(struct iwn_softc *sc)
 	iwn_nic_unlock(sc);
 
 	/* Stop TX scheduler. */
-	iwn_prph_write(sc, hal->sched_txfact_addr, 0);
+	iwn_prph_write(sc, sc->sched_txfact_addr, 0);
 
 	/* Stop all DMA channels. */
 	if (iwn_nic_lock(sc) == 0) {
-		for (chnl = 0; chnl < hal->ndmachnls; chnl++) {
+		for (chnl = 0; chnl < sc->ndmachnls; chnl++) {
 			IWN_WRITE(sc, IWN_FH_TX_CONFIG(chnl), 0);
 			for (ntries = 0; ntries < 200; ntries++) {
 				if (IWN_READ(sc, IWN_FH_TX_STATUS) &
@@ -6371,7 +6358,7 @@ iwn_hw_stop(struct iwn_softc *sc)
 	iwn_reset_rx_ring(sc, &sc->rxq);
 
 	/* Reset all TX rings. */
-	for (qid = 0; qid < hal->ntxqs; qid++)
+	for (qid = 0; qid < sc->ntxqs; qid++)
 		iwn_reset_tx_ring(sc, &sc->txq[qid]);
 
 	if (iwn_nic_lock(sc) == 0) {

Modified: stable/8/sys/dev/iwn/if_iwnvar.h
==============================================================================
--- stable/8/sys/dev/iwn/if_iwnvar.h	Sat Jun 18 12:00:49 2011	(r223248)
+++ stable/8/sys/dev/iwn/if_iwnvar.h	Sat Jun 18 12:03:30 2011	(r223249)
@@ -157,7 +157,7 @@ struct iwn_fw_info {
 	struct iwn_fw_part	boot;
 };
 
-struct iwn_hal {
+struct iwn_ops {
 	int		(*load_firmware)(struct iwn_softc *);
 	void		(*read_eeprom)(struct iwn_softc *);
 	int		(*post_alive)(struct iwn_softc *);
@@ -180,15 +180,6 @@ struct iwn_hal {
 	void		(*ampdu_tx_stop)(struct iwn_softc *, uint8_t,
 			    uint16_t);
 #endif
-	int		ntxqs;
-	int		ndmachnls;
-	uint8_t		broadcast_id;
-	int		rxonsz;
-	int		schedsz;
-	uint32_t	fw_text_maxsz;
-	uint32_t	fw_data_maxsz;
-	uint32_t	fwsz;
-	bus_size_t	sched_txfact_addr;
 };
 
 struct iwn_vap {
@@ -215,10 +206,20 @@ struct iwn_softc {
 #define IWN_FLAG_INTERNAL_PA	(1 << 4)
 
 	uint8_t 		hw_type;
-	const struct iwn_hal	*sc_hal;
+
+	struct iwn_ops		ops;
 	const char		*fwname;
 	const struct iwn_sensitivity_limits
 				*limits;
+	int			ntxqs;
+	int			ndmachnls;
+	uint8_t			broadcast_id;
+	int			rxonsz;
+	int			schedsz;
+	uint32_t		fw_text_maxsz;
+	uint32_t		fw_data_maxsz;
+	uint32_t		fwsz;
+	bus_size_t		sched_txfact_addr;
 
 	/* TX scheduler rings. */
 	struct iwn_dma_info	sched_dma;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106181203.p5IC3UqF040047>