Module Name:    src
Committed By:   jdolecek
Date:           Wed Jun 13 19:37:23 UTC 2018

Modified Files:
        src/sys/dev/pci: if_msk.c if_mskvar.h

Log Message:
sync and adapt with OpenBSD if_msk.c rev. 1.43-1.65 (modulo some
cosmetics, stuff we already had, or stuff which does not apply due
to different frameworks):

- Add support for fiber on 88E8021/22
- Avoid unnecessary resets.  This should make fiber 88E8021/22 work completely
- Only probe phy's at address 0; gets rid of bogus phy's on the
  Marvell Yukon 88E8036
- Remove an unused function msk_setfilt() which was copied from sk(4)
- Make msk(4) detachable
- Simplify the combination use of pci_mapreg_type()/pci_mapreg_map()


To generate a diff of this commit:
cvs rdiff -u -r1.62 -r1.63 src/sys/dev/pci/if_msk.c
cvs rdiff -u -r1.13 -r1.14 src/sys/dev/pci/if_mskvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/if_msk.c
diff -u src/sys/dev/pci/if_msk.c:1.62 src/sys/dev/pci/if_msk.c:1.63
--- src/sys/dev/pci/if_msk.c:1.62	Wed Jun 13 19:28:18 2018
+++ src/sys/dev/pci/if_msk.c	Wed Jun 13 19:37:23 2018
@@ -1,5 +1,5 @@
-/* $NetBSD: if_msk.c,v 1.62 2018/06/13 19:28:18 jdolecek Exp $ */
-/*	$OpenBSD: if_msk.c,v 1.42 2007/01/17 02:43:02 krw Exp $	*/
+/* $NetBSD: if_msk.c,v 1.63 2018/06/13 19:37:23 jdolecek Exp $ */
+/*	$OpenBSD: if_msk.c,v 1.65 2008/09/10 14:01:22 blambert Exp $ */
 
 /*
  * Copyright (c) 1997, 1998, 1999, 2000
@@ -52,7 +52,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_msk.c,v 1.62 2018/06/13 19:28:18 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_msk.c,v 1.63 2018/06/13 19:37:23 jdolecek Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -94,10 +94,14 @@ __KERNEL_RCSID(0, "$NetBSD: if_msk.c,v 1
 
 int mskc_probe(device_t, cfdata_t, void *);
 void mskc_attach(device_t, device_t, void *);
+int mskc_detach(device_t, int);
+void mskc_reset(struct sk_softc *);
 static bool mskc_suspend(device_t, const pmf_qual_t *);
 static bool mskc_resume(device_t, const pmf_qual_t *);
 int msk_probe(device_t, cfdata_t, void *);
 void msk_attach(device_t, device_t, void *);
+int msk_detach(device_t, int);
+void msk_reset(struct sk_if_softc *);
 int mskcprint(void *, const char *);
 int msk_intr(void *);
 void msk_intr_yukon(struct sk_if_softc *);
@@ -110,7 +114,6 @@ int msk_init(struct ifnet *);
 void msk_init_yukon(struct sk_if_softc *);
 void msk_stop(struct ifnet *, int);
 void msk_watchdog(struct ifnet *);
-void msk_reset(struct sk_softc *);
 int msk_newbuf(struct sk_if_softc *, int, struct mbuf *, bus_dmamap_t);
 int msk_alloc_jumbo_mem(struct sk_if_softc *);
 void *msk_jalloc(struct sk_if_softc *);
@@ -124,7 +127,6 @@ int msk_miibus_readreg(device_t, int, in
 void msk_miibus_writereg(device_t, int, int, int);
 void msk_miibus_statchg(struct ifnet *);
 
-void msk_setfilt(struct sk_if_softc *, void *, int);
 void msk_setmulti(struct sk_if_softc *);
 void msk_setpromisc(struct sk_if_softc *);
 void msk_tick(void *);
@@ -330,17 +332,6 @@ msk_miibus_statchg(struct ifnet *ifp)
 }
 
 void
-msk_setfilt(struct sk_if_softc *sc_if, void *addrv, int slot)
-{
-	char *addr = addrv;
-	int base = XM_RXFILT_ENTRY(slot);
-
-	SK_XM_WRITE_2(sc_if, base, *(u_int16_t *)(&addr[0]));
-	SK_XM_WRITE_2(sc_if, base + 2, *(u_int16_t *)(&addr[2]));
-	SK_XM_WRITE_2(sc_if, base + 4, *(u_int16_t *)(&addr[4]));
-}
-
-void
 msk_setmulti(struct sk_if_softc *sc_if)
 {
 	struct ifnet *ifp= &sc_if->sk_ethercom.ec_if;
@@ -819,12 +810,13 @@ mskc_probe(device_t parent, cfdata_t mat
 /*
  * Force the GEnesis into reset, then bring it out of reset.
  */
-void msk_reset(struct sk_softc *sc)
+void
+mskc_reset(struct sk_softc *sc)
 {
 	u_int32_t imtimer_ticks, reg1;
 	int reg;
 
-	DPRINTFN(2, ("msk_reset\n"));
+	DPRINTFN(2, ("mskc_reset\n"));
 
 	CSR_WRITE_1(sc, SK_CSR, SK_CSR_SW_RESET);
 	CSR_WRITE_1(sc, SK_CSR, SK_CSR_MASTER_RESET);
@@ -891,8 +883,8 @@ void msk_reset(struct sk_softc *sc)
 
 	sk_win_write_1(sc, SK_TESTCTL1, 1);
 
-	DPRINTFN(2, ("msk_reset: sk_csr=%x\n", CSR_READ_1(sc, SK_CSR)));
-	DPRINTFN(2, ("msk_reset: sk_link_ctrl=%x\n",
+	DPRINTFN(2, ("mskc_reset: sk_csr=%x\n", CSR_READ_1(sc, SK_CSR)));
+	DPRINTFN(2, ("mskc_reset: sk_link_ctrl=%x\n",
 		     CSR_READ_2(sc, SK_LINK_CTRL)));
 
 	/* Disable ASF */
@@ -1023,6 +1015,18 @@ msk_probe(device_t parent, cfdata_t matc
 	return (0);
 }
 
+void
+msk_reset(struct sk_if_softc *sc_if)
+{
+	/* GMAC and GPHY Reset */
+	SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_RESET_SET);
+	SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, SK_GPHY_RESET_SET);
+	DELAY(1000);
+	SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, SK_GPHY_RESET_CLEAR);
+	SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_LOOP_OFF |
+		      SK_GMAC_PAUSE_ON | SK_GMAC_RESET_CLEAR);
+}
+
 static bool
 msk_resume(device_t dv, const pmf_qual_t *qual)
 {
@@ -1044,9 +1048,9 @@ msk_attach(device_t parent, device_t sel
 	struct skc_attach_args *sa = aux;
 	struct ifnet *ifp;
 	void *kva;
-	bus_dma_segment_t seg;
-	int i, rseg;
+	int i;
 	u_int32_t chunk;
+	int mii_flags;
 
 	sc_if->sk_dev = self;
 	sc_if->sk_port = sa->skc_port;
@@ -1092,11 +1096,13 @@ msk_attach(device_t parent, device_t sel
 
 	/* Allocate the descriptor queues. */
 	if (bus_dmamem_alloc(sc->sc_dmatag, sizeof(struct msk_ring_data),
-	    PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
+	    PAGE_SIZE, 0, &sc_if->sk_ring_seg, 1, &sc_if->sk_ring_nseg,
+	    BUS_DMA_NOWAIT)) {
 		aprint_error(": can't alloc rx buffers\n");
 		goto fail;
 	}
-	if (bus_dmamem_map(sc->sc_dmatag, &seg, rseg,
+	if (bus_dmamem_map(sc->sc_dmatag, &sc_if->sk_ring_seg,
+	    sc_if->sk_ring_nseg,
 	    sizeof(struct msk_ring_data), &kva, BUS_DMA_NOWAIT)) {
 		aprint_error(": can't map dma buffers (%zu bytes)\n",
 		       sizeof(struct msk_ring_data));
@@ -1138,6 +1144,8 @@ msk_attach(device_t parent, device_t sel
 	IFQ_SET_READY(&ifp->if_snd);
 	strlcpy(ifp->if_xname, device_xname(sc_if->sk_dev), IFNAMSIZ);
 
+	msk_reset(sc_if);
+
 	/*
 	 * Do miibus setup.
 	 */
@@ -1153,8 +1161,11 @@ msk_attach(device_t parent, device_t sel
 	sc_if->sk_ethercom.ec_mii = &sc_if->sk_mii;
 	ifmedia_init(&sc_if->sk_mii.mii_media, 0,
 	    ether_mediachange, ether_mediastatus);
-	mii_attach(self, &sc_if->sk_mii, 0xffffffff, MII_PHY_ANY,
-	    MII_OFFSET_ANY, MIIF_DOPAUSE|MIIF_FORCEANEG);
+	mii_flags = MIIF_DOPAUSE;
+	if (sc->sk_fibertype)
+		mii_flags |= MIIF_HAVEFIBER;
+	mii_attach(self, &sc_if->sk_mii, 0xffffffff, 0,
+	    MII_OFFSET_ANY, mii_flags);
 	if (LIST_FIRST(&sc_if->sk_mii.mii_phys) == NULL) {
 		aprint_error_dev(sc_if->sk_dev, "no PHY found!\n");
 		ifmedia_add(&sc_if->sk_mii.mii_media, IFM_ETHER|IFM_MANUAL,
@@ -1190,12 +1201,49 @@ fail_3:
 fail_2:
 	bus_dmamem_unmap(sc->sc_dmatag, kva, sizeof(struct msk_ring_data));
 fail_1:
-	bus_dmamem_free(sc->sc_dmatag, &seg, rseg);
+	bus_dmamem_free(sc->sc_dmatag, &sc_if->sk_ring_seg, sc_if->sk_ring_nseg);
 fail:
 	sc->sk_if[sa->skc_port] = NULL;
 }
 
 int
+msk_detach(device_t self, int flags)
+{
+	struct sk_if_softc *sc_if = (struct sk_if_softc *)self;
+	struct sk_softc *sc = sc_if->sk_softc;
+	struct ifnet *ifp = &sc_if->sk_ethercom.ec_if;
+
+	if (sc->sk_if[sc_if->sk_port] == NULL)
+		return (0);
+
+	rnd_detach_source(&sc->rnd_source);
+
+	callout_halt(&sc_if->sk_tick_ch, NULL);
+	callout_destroy(&sc_if->sk_tick_ch);
+
+	/* Detach any PHYs we might have. */
+	if (LIST_FIRST(&sc_if->sk_mii.mii_phys) != NULL)
+		mii_detach(&sc_if->sk_mii, MII_PHY_ANY, MII_OFFSET_ANY);
+
+	/* Delete any remaining media. */
+	ifmedia_delete_instance(&sc_if->sk_mii.mii_media, IFM_INST_ANY);
+
+	pmf_device_deregister(self);
+
+	ether_ifdetach(ifp);
+	if_detach(ifp);
+
+	bus_dmamap_destroy(sc->sc_dmatag, sc_if->sk_ring_map);
+	bus_dmamem_unmap(sc->sc_dmatag, sc_if->sk_rdata,
+	    sizeof(struct msk_ring_data));
+	bus_dmamem_free(sc->sc_dmatag,
+	    &sc_if->sk_ring_seg, sc_if->sk_ring_nseg);
+	sc->sk_if[sc_if->sk_port] = NULL;
+
+	return (0);
+}
+
+int
 mskcprint(void *aux, const char *pnp)
 {
 	struct skc_attach_args *sa = aux;
@@ -1224,12 +1272,10 @@ mskc_attach(device_t parent, device_t se
 	const char *intrstr = NULL;
 	bus_size_t size;
 	int rc, sk_nodenum;
-	u_int8_t hw;
+	u_int8_t hw, pmd;
 	const char *revstr = NULL;
 	const struct sysctlnode *node;
 	void *kva;
-	bus_dma_segment_t seg;
-	int rseg;
 	char intrbuf[PCI_INTRSTR_LEN];
 
 	DPRINTFN(2, ("begin mskc_attach\n"));
@@ -1268,17 +1314,9 @@ mskc_attach(device_t parent, device_t se
 	/*
 	 * Map control/status registers.
 	 */
-
 	memtype = pci_mapreg_type(pc, pa->pa_tag, SK_PCI_LOMEM);
-	switch (memtype) {
-	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
-	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
-		if (pci_mapreg_map(pa, SK_PCI_LOMEM,
-				   memtype, 0, &sc->sk_btag, &sc->sk_bhandle,
-				   NULL, &size) == 0) {
-			break;
-		}
-	default:
+	if (pci_mapreg_map(pa, SK_PCI_LOMEM, memtype, 0, &sc->sk_btag,
+	    &sc->sk_bhandle, NULL, &size)) {
 		aprint_error(": can't map mem space\n");
 		return;
 	}
@@ -1314,15 +1352,17 @@ mskc_attach(device_t parent, device_t se
 		aprint_error("\n");
 		goto fail_1;
 	}
+	sc->sk_pc = pc;
 
 	if (bus_dmamem_alloc(sc->sc_dmatag,
-	    MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc),
-	    PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
+	    MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc), PAGE_SIZE,
+	    0, &sc->sk_status_seg, 1, &sc->sk_status_nseg, BUS_DMA_NOWAIT)) {
 		aprint_error(": can't alloc status buffers\n");
 		goto fail_2;
 	}
 
-	if (bus_dmamem_map(sc->sc_dmatag, &seg, rseg,
+	if (bus_dmamem_map(sc->sc_dmatag,
+	    &sc->sk_status_seg, sc->sk_status_nseg,
 	    MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc),
 	    &kva, BUS_DMA_NOWAIT)) {
 		aprint_error(": can't map dma buffers (%zu bytes)\n",
@@ -1348,11 +1388,15 @@ mskc_attach(device_t parent, device_t se
 	sc->sk_int_mod_pending = 0;
 
 	/* Reset the adapter. */
-	msk_reset(sc);
+	mskc_reset(sc);
 
 	sc->sk_ramsize = sk_win_read_1(sc, SK_EPROM0) * 4096;
 	DPRINTFN(2, ("mskc_attach: ramsize=%dK\n", sc->sk_ramsize / 1024));
 
+	pmd = sk_win_read_1(sc, SK_PMDTYPE);
+	if (pmd == 'L' || pmd == 'S' || pmd == 'P')
+		sc->sk_fibertype = 1;
+
 	switch (sc->sk_type) {
 	case SK_YUKON_XL:
 		sc->sk_name = "Yukon-2 XL";
@@ -1597,11 +1641,42 @@ fail_4:
 	bus_dmamem_unmap(sc->sc_dmatag, kva,
 	    MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc));
 fail_3:
-	bus_dmamem_free(sc->sc_dmatag, &seg, rseg);
+	bus_dmamem_free(sc->sc_dmatag,
+	    &sc->sk_status_seg, sc->sk_status_nseg);
+	sc->sk_status_nseg = 0;
 fail_2:
 	pci_intr_disestablish(pc, sc->sk_intrhand);
+	sc->sk_intrhand = NULL;
 fail_1:
 	bus_space_unmap(sc->sk_btag, sc->sk_bhandle, size);
+	sc->sk_bsize = 0;
+}
+
+int
+mskc_detach(device_t self, int flags)
+{
+	struct sk_softc *sc = (struct sk_softc *)self;
+	int rv;
+
+	rv = config_detach_children(self, flags);
+	if (rv != 0)
+		return (rv);
+
+	if (sc->sk_status_nseg > 0) {
+		bus_dmamap_destroy(sc->sc_dmatag, sc->sk_status_map);
+		bus_dmamem_unmap(sc->sc_dmatag, sc->sk_status_ring,
+		    MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc));
+		bus_dmamem_free(sc->sc_dmatag,
+		    &sc->sk_status_seg, sc->sk_status_nseg);
+	}
+
+	if (sc->sk_intrhand)
+		pci_intr_disestablish(sc->sk_pc, sc->sk_intrhand);
+
+	if (sc->sk_bsize > 0)
+		bus_space_unmap(sc->sk_btag, sc->sk_bhandle, sc->sk_bsize);
+
+	return(0);
 }
 
 int
@@ -1775,7 +1850,8 @@ msk_watchdog(struct ifnet *ifp)
 			ifp->if_oerrors++;
 
 			/* XXX Resets both ports; we shouldn't do that. */
-			msk_reset(sc_if->sk_softc);
+			mskc_reset(sc_if->sk_softc);
+			msk_reset(sc_if);
 			msk_init(ifp);
 		}
 	}
@@ -1801,7 +1877,7 @@ mskc_resume(device_t dv, const pmf_qual_
 
 	DPRINTFN(2, ("mskc_resume\n"));
 
-	msk_reset(sc);
+	mskc_reset(sc);
 	CSR_WRITE_2(sc, SK_LED, SK_LED_GREEN_ON);
 
 	return true;
@@ -1948,7 +2024,6 @@ msk_tick(void *xsc_if)
 {
 	struct sk_if_softc *sc_if = xsc_if;
 	struct mii_data *mii = &sc_if->sk_mii;
-	uint16_t gpsr;
 	int s;
 
 	s = splnet();
@@ -2102,17 +2177,6 @@ msk_init_yukon(struct sk_if_softc *sc_if
 
 	DPRINTFN(6, ("msk_init_yukon: 1\n"));
 
-	/* GMAC and GPHY Reset */
-	SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_RESET_SET);
-	SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, SK_GPHY_RESET_SET);
-	DELAY(1000);
-
-	DPRINTFN(6, ("msk_init_yukon: 2\n"));
-
-	SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, SK_GPHY_RESET_CLEAR);
-	SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_LOOP_OFF |
-		      SK_GMAC_PAUSE_ON | SK_GMAC_RESET_CLEAR);
-
 	DPRINTFN(3, ("msk_init_yukon: gmac_ctrl=%#x\n",
 		     SK_IF_READ_4(sc_if, 0, SK_GMAC_CTRL)));
 
@@ -2451,10 +2515,10 @@ msk_stop(struct ifnet *ifp, int disable)
 }
 
 CFATTACH_DECL_NEW(mskc, sizeof(struct sk_softc), mskc_probe, mskc_attach,
-	NULL, NULL);
+	mskc_detach, NULL);
 
 CFATTACH_DECL_NEW(msk, sizeof(struct sk_if_softc), msk_probe, msk_attach,
-	NULL, NULL);
+	msk_detach, NULL);
 
 #ifdef MSK_DEBUG
 void

Index: src/sys/dev/pci/if_mskvar.h
diff -u src/sys/dev/pci/if_mskvar.h:1.13 src/sys/dev/pci/if_mskvar.h:1.14
--- src/sys/dev/pci/if_mskvar.h:1.13	Mon Jun 11 19:13:38 2018
+++ src/sys/dev/pci/if_mskvar.h	Wed Jun 13 19:37:23 2018
@@ -1,5 +1,5 @@
 /*	$OpenBSD: if_mskvar.h,v 1.3 2006/12/28 16:34:42 kettenis Exp $	*/
-/*	$NetBSD: if_mskvar.h,v 1.13 2018/06/11 19:13:38 jdolecek Exp $	*/
+/*	$NetBSD: if_mskvar.h,v 1.14 2018/06/13 19:37:23 jdolecek Exp $	*/
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -187,7 +187,10 @@ struct sk_softc {
 	device_t		sk_dev;
 	bus_space_handle_t	sk_bhandle;	/* bus space handle */
 	bus_space_tag_t		sk_btag;	/* bus space tag */
+	bus_size_t		sk_bsize;	/* bus space size */
 	void			*sk_intrhand;	/* irq handler handle */
+	pci_chipset_tag_t	sk_pc;
+	u_int8_t		sk_fibertype;
 	u_int8_t		sk_type;
 	u_int8_t		sk_rev;
 	u_int32_t		sk_workaround;
@@ -202,6 +205,8 @@ struct sk_softc {
 	struct sk_if_softc	*sk_if[2];
 	struct msk_status_desc	*sk_status_ring;
 	bus_dmamap_t		sk_status_map;
+	bus_dma_segment_t	sk_status_seg;
+	int			sk_status_nseg;
 	int			sk_status_idx;
 	int			sk_status_own_idx;
 	krndsource_t     rnd_source;
@@ -224,6 +229,8 @@ struct sk_if_softc {
 	struct msk_chain_data	sk_cdata;
 	struct msk_ring_data	*sk_rdata;
 	bus_dmamap_t		sk_ring_map;
+	bus_dma_segment_t	sk_ring_seg;
+	int			sk_ring_nseg;
 	int			sk_status_idx;
 	struct sk_softc		*sk_softc;	/* parent controller */
 	int			sk_if_flags;

Reply via email to