Index: if_iwm.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_iwm.c,v
retrieving revision 1.76
diff -u -p -r1.76 if_iwm.c
--- if_iwm.c	23 Oct 2017 09:28:38 -0000	1.76
+++ if_iwm.c	9 Jan 2018 11:41:33 -0000
@@ -7726,22 +7726,38 @@ iwm_match(device_t parent, cfdata_t matc
 static int
 iwm_preinit(struct iwm_softc *sc)
 {
-	struct ieee80211com *ic = &sc->sc_ic;
-	int err;
+	int error;
+
+	if ((error = iwm_prepare_card_hw(sc)) != 0) {
+		aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
+		return error;
+	}
 
 	if (ISSET(sc->sc_flags, IWM_FLAG_ATTACHED))
 		return 0;
 
-	err = iwm_start_hw(sc);
-	if (err) {
+	error = iwm_start_hw(sc);
+	if (error) {
 		aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
-		return err;
+		return error;
 	}
 
-	err = iwm_run_init_mvm_ucode(sc, 1);
+	error = iwm_run_init_mvm_ucode(sc, 1);
 	iwm_stop_device(sc);
-	if (err)
-		return err;
+	return error;
+}
+
+static void
+iwm_attach_hook(device_t dev)
+{
+	struct iwm_softc *sc = device_private(dev);
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct ifnet *ifp = &sc->sc_ec.ec_if;
+
+	KASSERT(!cold);
+
+	if (iwm_preinit(sc) != 0)
+		return;
 
 	sc->sc_flags |= IWM_FLAG_ATTACHED;
 
@@ -7749,17 +7765,80 @@ iwm_preinit(struct iwm_softc *sc)
 	    sc->sc_hw_rev & IWM_CSR_HW_REV_TYPE_MSK, sc->sc_fwver,
 	    ether_sprintf(sc->sc_nvm.hw_addr));
 
+ 	/*
+	 * Attach interface
+	 */
+	ic->ic_ifp = ifp;
+	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
+	ic->ic_opmode = IEEE80211_M_STA;	/* default to BSS mode */
+	ic->ic_state = IEEE80211_S_INIT;
+
+	/* Set device capabilities. */
+	ic->ic_caps =
+	    IEEE80211_C_WEP |		/* WEP */
+	    IEEE80211_C_WPA |		/* 802.11i */
+#ifdef notyet
+	    IEEE80211_C_SCANALL |	/* device scans all channels at once */
+	    IEEE80211_C_SCANALLBAND |	/* device scans all bands at once */
+#endif
+	    IEEE80211_C_SHSLOT |	/* short slot time supported */
+	    IEEE80211_C_SHPREAMBLE;	/* short preamble supported */
+
 #ifndef IEEE80211_NO_HT
 	if (sc->sc_nvm.sku_cap_11n_enable)
 		iwm_setup_ht_rates(sc);
 #endif
+#ifndef IEEE80211_NO_HT
+	ic->ic_htcaps = IEEE80211_HTCAP_SGI20;
+	ic->ic_htxcaps = 0;
+	ic->ic_txbfcaps = 0;
+	ic->ic_aselcaps = 0;
+	ic->ic_ampdu_params = (IEEE80211_AMPDU_PARAM_SS_4 | 0x3 /* 64k */);
+#endif
 
 	/* not all hardware can do 5GHz band */
 	if (sc->sc_nvm.sku_cap_band_52GHz_enable)
 		ic->ic_sup_rates[IEEE80211_MODE_11A] = ieee80211_std_rateset_11a;
 
+	ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
+	ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
+
+	for (int i = 0; i < __arraycount(sc->sc_phyctxt); i++) {
+		sc->sc_phyctxt[i].id = i;
+	}
+
+	sc->sc_amrr.amrr_min_success_threshold =  1;
+	sc->sc_amrr.amrr_max_success_threshold = 15;
+
+	/* IBSS channel undefined for now. */
+	ic->ic_ibss_chan = &ic->ic_channels[1];
+
+#if 0
+	/* Max RSSI */
+	ic->ic_max_rssi = IWM_MAX_DBM - IWM_MIN_DBM;
+#endif
+ 
+	ifp->if_softc = sc;
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_init = iwm_init;
+	ifp->if_stop = iwm_stop;
+	ifp->if_ioctl = iwm_ioctl;
+	ifp->if_start = iwm_start;
+	ifp->if_watchdog = iwm_watchdog;
+	IFQ_SET_READY(&ifp->if_snd);
+	memcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ);
+
+	int error = if_initialize(ifp);
+	if (error != 0) {
+		aprint_error_dev(sc->sc_dev, "if_initialize failed(%d)\n",
+		    error);
+	}
 	ieee80211_ifattach(ic);
 
+	/* Use common softint-based if_input */
+	ifp->if_percpuq = if_percpuq_create(ifp);
+	if_register(ifp);
+
 	ic->ic_node_alloc = iwm_node_alloc;
 
 	/* Override 802.11 state transition machine. */
@@ -7769,16 +7848,29 @@ iwm_preinit(struct iwm_softc *sc)
 	ieee80211_announce(ic);
 
 	iwm_radiotap_attach(sc);
+	callout_init(&sc->sc_calib_to, 0);
+	callout_setfunc(&sc->sc_calib_to, iwm_calib_timeout, sc);
+	callout_init(&sc->sc_led_blink_to, 0);
+	callout_setfunc(&sc->sc_led_blink_to, iwm_led_blink_timeout, sc);
+#ifndef IEEE80211_NO_HT
+	if (workqueue_create(&sc->sc_setratewq, "iwmsr",
+	    iwm_setrates_task, sc, PRI_NONE, IPL_NET, 0))
+		panic("%s: could not create workqueue: setrates",
+		    device_xname(self));
+	if (workqueue_create(&sc->sc_bawq, "iwmba",
+	    iwm_ba_task, sc, PRI_NONE, IPL_NET, 0))
+		panic("%s: could not create workqueue: blockack",
+		    device_xname(self));
+	if (workqueue_create(&sc->sc_htprowq, "iwmhtpro",
+	    iwm_htprot_task, sc, PRI_NONE, IPL_NET, 0))
+		panic("%s: could not create workqueue: htprot",
+		    device_xname(self));
+#endif
 
-	return 0;
-}
-
-static void
-iwm_attach_hook(device_t dev)
-{
-	struct iwm_softc *sc = device_private(dev);
-
-	iwm_preinit(sc);
+	if (pmf_device_register(dev, NULL, NULL))
+		pmf_class_network_register(dev, ifp);
+	else
+		aprint_error_dev(dev, "couldn't establish power handler\n");
 }
 
 static void
@@ -7786,8 +7878,6 @@ iwm_attach(device_t parent, device_t sel
 {
 	struct iwm_softc *sc = device_private(self);
 	struct pci_attach_args *pa = aux;
-	struct ieee80211com *ic = &sc->sc_ic;
-	struct ifnet *ifp = &sc->sc_ec.ec_if;
 	pcireg_t reg, memtype;
 	char intrbuf[PCI_INTRSTR_LEN];
 	const char *intrstr;
@@ -8068,100 +8158,6 @@ iwm_attach(device_t parent, device_t sel
 	}
 
 	/*
-	 * Attach interface
-	 */
-	ic->ic_ifp = ifp;
-	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
-	ic->ic_opmode = IEEE80211_M_STA;	/* default to BSS mode */
-	ic->ic_state = IEEE80211_S_INIT;
-
-	/* Set device capabilities. */
-	ic->ic_caps =
-	    IEEE80211_C_WEP |		/* WEP */
-	    IEEE80211_C_WPA |		/* 802.11i */
-#ifdef notyet
-	    IEEE80211_C_SCANALL |	/* device scans all channels at once */
-	    IEEE80211_C_SCANALLBAND |	/* device scans all bands at once */
-#endif
-	    IEEE80211_C_SHSLOT |	/* short slot time supported */
-	    IEEE80211_C_SHPREAMBLE;	/* short preamble supported */
-
-#ifndef IEEE80211_NO_HT
-	ic->ic_htcaps = IEEE80211_HTCAP_SGI20;
-	ic->ic_htxcaps = 0;
-	ic->ic_txbfcaps = 0;
-	ic->ic_aselcaps = 0;
-	ic->ic_ampdu_params = (IEEE80211_AMPDU_PARAM_SS_4 | 0x3 /* 64k */);
-#endif
-
-	/* all hardware can do 2.4GHz band */
-	ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
-	ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
-
-	for (int i = 0; i < __arraycount(sc->sc_phyctxt); i++) {
-		sc->sc_phyctxt[i].id = i;
-	}
-
-	sc->sc_amrr.amrr_min_success_threshold =  1;
-	sc->sc_amrr.amrr_max_success_threshold = 15;
-
-	/* IBSS channel undefined for now. */
-	ic->ic_ibss_chan = &ic->ic_channels[1];
-
-#if 0
-	ic->ic_max_rssi = IWM_MAX_DBM - IWM_MIN_DBM;
-#endif
-
-	ifp->if_softc = sc;
-	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
-	ifp->if_init = iwm_init;
-	ifp->if_stop = iwm_stop;
-	ifp->if_ioctl = iwm_ioctl;
-	ifp->if_start = iwm_start;
-	ifp->if_watchdog = iwm_watchdog;
-	IFQ_SET_READY(&ifp->if_snd);
-	memcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ);
-
-	err = if_initialize(ifp);
-	if (err != 0) {
-		aprint_error_dev(sc->sc_dev, "if_initialize failed(%d)\n",
-		    err);
-		goto fail6;
-	}
-#if 0
-	ieee80211_ifattach(ic);
-#else
-	ether_ifattach(ifp, ic->ic_myaddr);	/* XXX */
-#endif
-	/* Use common softint-based if_input */
-	ifp->if_percpuq = if_percpuq_create(ifp);
-	if_register(ifp);
-
-	callout_init(&sc->sc_calib_to, 0);
-	callout_setfunc(&sc->sc_calib_to, iwm_calib_timeout, sc);
-	callout_init(&sc->sc_led_blink_to, 0);
-	callout_setfunc(&sc->sc_led_blink_to, iwm_led_blink_timeout, sc);
-#ifndef IEEE80211_NO_HT
-	if (workqueue_create(&sc->sc_setratewq, "iwmsr",
-	    iwm_setrates_task, sc, PRI_NONE, IPL_NET, 0))
-		panic("%s: could not create workqueue: setrates",
-		    device_xname(self));
-	if (workqueue_create(&sc->sc_bawq, "iwmba",
-	    iwm_ba_task, sc, PRI_NONE, IPL_NET, 0))
-		panic("%s: could not create workqueue: blockack",
-		    device_xname(self));
-	if (workqueue_create(&sc->sc_htprowq, "iwmhtpro",
-	    iwm_htprot_task, sc, PRI_NONE, IPL_NET, 0))
-		panic("%s: could not create workqueue: htprot",
-		    device_xname(self));
-#endif
-
-	if (pmf_device_register(self, NULL, NULL))
-		pmf_class_network_register(self, ifp);
-	else
-		aprint_error_dev(self, "couldn't establish power handler\n");
-
-	/*
 	 * We can't do normal attach before the file system is mounted
 	 * because we cannot read the MAC address without loading the
 	 * firmware from disk.  So we postpone until mountroot is done.
@@ -8173,7 +8169,7 @@ iwm_attach(device_t parent, device_t sel
 
 	return;
 
-fail6:	iwm_free_rx_ring(sc, &sc->rxq);
+// fail6:	iwm_free_rx_ring(sc, &sc->rxq);
 fail5:	while (--txq_i >= 0)
 		iwm_free_tx_ring(sc, &sc->txq[txq_i]);
 fail4:	iwm_dma_contig_free(&sc->sched_dma);