Deleted Added
full compact
if_npe.c (186352) if_npe.c (186420)
1/*-
2 * Copyright (c) 2006-2008 Sam Leffler. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 9 unchanged lines hidden (view full) ---

18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2006-2008 Sam Leffler. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 9 unchanged lines hidden (view full) ---

18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25#include <sys/cdefs.h>
26__FBSDID("$FreeBSD: head/sys/arm/xscale/ixp425/if_npe.c 186352 2008-12-20 03:26:09Z sam $");
26__FBSDID("$FreeBSD: head/sys/arm/xscale/ixp425/if_npe.c 186420 2008-12-23 04:51:46Z sam $");
27
28/*
29 * Intel XScale NPE Ethernet driver.
30 *
31 * This driver handles the two ports present on the IXP425.
32 * Packet processing is done by the Network Processing Engines
33 * (NPE's) that work together with a MAC and PHY. The MAC
34 * is also mapped to the XScale cpu; the PHY is accessed via

--- 117 unchanged lines hidden (view full) ---

152 * multi-port processing. It may be better to handle
153 * all traffic through one Q (as done by the Intel drivers).
154 *
155 * Note that the PHY's are accessible only from MAC A
156 * on the IXP425. This and other platform-specific
157 * assumptions probably need to be handled through hints.
158 */
159static const struct {
27
28/*
29 * Intel XScale NPE Ethernet driver.
30 *
31 * This driver handles the two ports present on the IXP425.
32 * Packet processing is done by the Network Processing Engines
33 * (NPE's) that work together with a MAC and PHY. The MAC
34 * is also mapped to the XScale cpu; the PHY is accessed via

--- 117 unchanged lines hidden (view full) ---

152 * multi-port processing. It may be better to handle
153 * all traffic through one Q (as done by the Intel drivers).
154 *
155 * Note that the PHY's are accessible only from MAC A
156 * on the IXP425. This and other platform-specific
157 * assumptions probably need to be handled through hints.
158 */
159static const struct {
160 uint32_t imageid; /* default fw image */
161 uint32_t macbase;
162 uint32_t miibase;
163 int phy; /* phy id */
164 uint8_t rx_qid;
165 uint8_t rx_freeqid;
166 uint8_t tx_qid;
167 uint8_t tx_doneqid;
168} npeconfig[NPE_MAX] = {
169 [NPE_A] = {
160 uint32_t macbase;
161 uint32_t miibase;
162 int phy; /* phy id */
163 uint8_t rx_qid;
164 uint8_t rx_freeqid;
165 uint8_t tx_qid;
166 uint8_t tx_doneqid;
167} npeconfig[NPE_MAX] = {
168 [NPE_A] = {
170 .imageid = IXP425_NPE_A_IMAGEID,
171 .macbase = IXP435_MAC_A_HWBASE,
172 .miibase = IXP425_MAC_C_HWBASE,
173 .phy = 2,
174 .rx_qid = 4,
175 .rx_freeqid = 26,
176 .tx_qid = 23,
177 .tx_doneqid = 31
178 },
179 [NPE_B] = {
169 .macbase = IXP435_MAC_A_HWBASE,
170 .miibase = IXP425_MAC_C_HWBASE,
171 .phy = 2,
172 .rx_qid = 4,
173 .rx_freeqid = 26,
174 .tx_qid = 23,
175 .tx_doneqid = 31
176 },
177 [NPE_B] = {
180 .imageid = IXP425_NPE_B_IMAGEID,
181 .macbase = IXP425_MAC_B_HWBASE,
182 .miibase = IXP425_MAC_C_HWBASE,
183 .phy = 0,
184 .rx_qid = 4,
185 .rx_freeqid = 27,
186 .tx_qid = 24,
187 .tx_doneqid = 31
188 },
189 [NPE_C] = {
178 .macbase = IXP425_MAC_B_HWBASE,
179 .miibase = IXP425_MAC_C_HWBASE,
180 .phy = 0,
181 .rx_qid = 4,
182 .rx_freeqid = 27,
183 .tx_qid = 24,
184 .tx_doneqid = 31
185 },
186 [NPE_C] = {
190 .imageid = IXP425_NPE_C_IMAGEID,
191 .macbase = IXP425_MAC_C_HWBASE,
192 .miibase = IXP425_MAC_C_HWBASE,
193 .phy = 1,
194 .rx_qid = 12,
195 .rx_freeqid = 28,
196 .tx_qid = 25,
197 .tx_doneqid = 31
198 },

--- 54 unchanged lines hidden (view full) ---

253/* NB: all tx done processing goes through one queue */
254static int tx_doneqid = -1;
255
256SYSCTL_NODE(_hw, OID_AUTO, npe, CTLFLAG_RD, 0, "IXP4XX NPE driver parameters");
257
258static int npe_debug = 0;
259SYSCTL_INT(_hw_npe, OID_AUTO, debug, CTLFLAG_RW, &npe_debug,
260 0, "IXP4XX NPE network interface debug msgs");
187 .macbase = IXP425_MAC_C_HWBASE,
188 .miibase = IXP425_MAC_C_HWBASE,
189 .phy = 1,
190 .rx_qid = 12,
191 .rx_freeqid = 28,
192 .tx_qid = 25,
193 .tx_doneqid = 31
194 },

--- 54 unchanged lines hidden (view full) ---

249/* NB: all tx done processing goes through one queue */
250static int tx_doneqid = -1;
251
252SYSCTL_NODE(_hw, OID_AUTO, npe, CTLFLAG_RD, 0, "IXP4XX NPE driver parameters");
253
254static int npe_debug = 0;
255SYSCTL_INT(_hw_npe, OID_AUTO, debug, CTLFLAG_RW, &npe_debug,
256 0, "IXP4XX NPE network interface debug msgs");
261TUNABLE_INT("hw.npe.npe", &npe_debug);
257TUNABLE_INT("hw.npe.debug", &npe_debug);
262#define DPRINTF(sc, fmt, ...) do { \
263 if (sc->sc_debug) device_printf(sc->sc_dev, fmt, __VA_ARGS__); \
264} while (0)
265#define DPRINTFn(n, sc, fmt, ...) do { \
266 if (sc->sc_debug >= n) device_printf(sc->sc_dev, fmt, __VA_ARGS__);\
267} while (0)
268static int npe_tickinterval = 3; /* npe_tick frequency (secs) */
269SYSCTL_INT(_hw_npe, OID_AUTO, tickinterval, CTLFLAG_RD, &npe_tickinterval,

--- 26 unchanged lines hidden (view full) ---

296static int
297npe_probe(device_t dev)
298{
299 static const char *desc[NPE_MAX] = {
300 [NPE_A] = "IXP NPE-A",
301 [NPE_B] = "IXP NPE-B",
302 [NPE_C] = "IXP NPE-C"
303 };
258#define DPRINTF(sc, fmt, ...) do { \
259 if (sc->sc_debug) device_printf(sc->sc_dev, fmt, __VA_ARGS__); \
260} while (0)
261#define DPRINTFn(n, sc, fmt, ...) do { \
262 if (sc->sc_debug >= n) device_printf(sc->sc_dev, fmt, __VA_ARGS__);\
263} while (0)
264static int npe_tickinterval = 3; /* npe_tick frequency (secs) */
265SYSCTL_INT(_hw_npe, OID_AUTO, tickinterval, CTLFLAG_RD, &npe_tickinterval,

--- 26 unchanged lines hidden (view full) ---

292static int
293npe_probe(device_t dev)
294{
295 static const char *desc[NPE_MAX] = {
296 [NPE_A] = "IXP NPE-A",
297 [NPE_B] = "IXP NPE-B",
298 [NPE_C] = "IXP NPE-C"
299 };
300 int unit = device_get_unit(dev);
304 int npeid;
305
301 int npeid;
302
303 if (unit > 2 ||
304 (ixp4xx_read_feature_bits() &
305 (unit == 0 ? EXP_FCTRL_ETH0 : EXP_FCTRL_ETH1)) == 0)
306 return EINVAL;
307
306 npeid = -1;
307 if (!override_npeid(dev, "npeid", &npeid))
308 npeid = -1;
309 if (!override_npeid(dev, "npeid", &npeid))
308 npeid = unit2npeid(device_get_unit(dev));
310 npeid = unit2npeid(unit);
309 if (npeid == -1) {
311 if (npeid == -1) {
310 device_printf(dev, "unit not supported\n");
312 device_printf(dev, "unit %d not supported\n", unit);
311 return EINVAL;
312 }
313 return EINVAL;
314 }
313 /* XXX check feature register to see if enabled */
314 device_set_desc(dev, desc[npeid]);
315 return 0;
316}
317
318static int
319npe_attach(device_t dev)
320{
321 struct npe_softc *sc = device_get_softc(dev);

--- 317 unchanged lines hidden (view full) ---

639 }
640 if (bootverbose)
641 device_printf(dev, "using npe.%d.%s=%d override\n",
642 unit, resname, resval);
643 *val = resval;
644 return 1;
645}
646
315 device_set_desc(dev, desc[npeid]);
316 return 0;
317}
318
319static int
320npe_attach(device_t dev)
321{
322 struct npe_softc *sc = device_get_softc(dev);

--- 317 unchanged lines hidden (view full) ---

640 }
641 if (bootverbose)
642 device_printf(dev, "using npe.%d.%s=%d override\n",
643 unit, resname, resval);
644 *val = resval;
645 return 1;
646}
647
647static int
648override_imageid(device_t dev, const char *resname, uint32_t *val)
649{
650 int unit = device_get_unit(dev);
651 int resval;
652
653 if (resource_int_value("npe", unit, resname, &resval) != 0)
654 return 0;
655 /* XXX validate */
656 if (bootverbose)
657 device_printf(dev, "using npe.%d.%s=0x%x override\n",
658 unit, resname, resval);
659 *val = resval;
660 return 1;
661}
662
663static void
664npe_mac_reset(struct npe_softc *sc)
665{
666 /*
667 * Reset MAC core.
668 */
669 WR4(sc, NPE_MAC_CORE_CNTRL, NPE_CORE_RESET);
670 DELAY(NPE_MAC_RESET_DELAY);
671 /* configure MAC to generate MDC clock */
672 WR4(sc, NPE_MAC_CORE_CNTRL, NPE_CORE_MDC_EN);
673}
674
675static int
676npe_activate(device_t dev)
677{
678 struct npe_softc * sc = device_get_softc(dev);
679 int error, i, macbase, miibase;
648static void
649npe_mac_reset(struct npe_softc *sc)
650{
651 /*
652 * Reset MAC core.
653 */
654 WR4(sc, NPE_MAC_CORE_CNTRL, NPE_CORE_RESET);
655 DELAY(NPE_MAC_RESET_DELAY);
656 /* configure MAC to generate MDC clock */
657 WR4(sc, NPE_MAC_CORE_CNTRL, NPE_CORE_MDC_EN);
658}
659
660static int
661npe_activate(device_t dev)
662{
663 struct npe_softc * sc = device_get_softc(dev);
664 int error, i, macbase, miibase;
680 uint32_t imageid, msg[2];
681
682 /*
683 * Setup NEP ID, MAC, and MII bindings. We allow override
684 * via hints to handle unexpected board configs.
685 */
686 if (!override_npeid(dev, "npeid", &sc->sc_npeid))
687 sc->sc_npeid = unit2npeid(device_get_unit(dev));
688 sc->sc_npe = ixpnpe_attach(dev, sc->sc_npeid);

--- 28 unchanged lines hidden (view full) ---

717 "cannot map MII registers 0x%x:0x%x\n",
718 miibase, IXP425_REG_SIZE);
719 return ENOMEM;
720 }
721 } else
722 sc->sc_miih = sc->sc_ioh;
723
724 /*
665
666 /*
667 * Setup NEP ID, MAC, and MII bindings. We allow override
668 * via hints to handle unexpected board configs.
669 */
670 if (!override_npeid(dev, "npeid", &sc->sc_npeid))
671 sc->sc_npeid = unit2npeid(device_get_unit(dev));
672 sc->sc_npe = ixpnpe_attach(dev, sc->sc_npeid);

--- 28 unchanged lines hidden (view full) ---

701 "cannot map MII registers 0x%x:0x%x\n",
702 miibase, IXP425_REG_SIZE);
703 return ENOMEM;
704 }
705 } else
706 sc->sc_miih = sc->sc_ioh;
707
708 /*
725 * Load NPE firmware and start it running. We assume
726 * that minor version bumps remain compatible so probe
727 * the firmware image starting with the expected version
728 * and then bump the minor version up to the max.
709 * Load NPE firmware and start it running.
729 */
710 */
730 if (!override_imageid(dev, "imageid", &imageid))
731 imageid = npeconfig[sc->sc_npeid].imageid;
732 for (;;) {
733 error = ixpnpe_init(sc->sc_npe, "npe_fw", imageid);
734 if (error == 0)
735 break;
736 /* ESRCH is returned when the requested image is not present */
737 if (error != ESRCH) {
738 device_printf(dev, "cannot init NPE (error %d)\n",
739 error);
740 return error;
741 }
742 /* bump the minor version up to the max possible */
743 if (NPEIMAGE_MINOR(imageid) == 0xff) {
744 device_printf(dev, "cannot locate firmware "
745 "(imageid 0x%08x)\n", imageid);
746 return error;
747 }
748 imageid++;
711 error = ixpnpe_init(sc->sc_npe);
712 if (error != 0) {
713 device_printf(dev, "cannot init NPE (error %d)\n", error);
714 return error;
749 }
715 }
750 /* NB: firmware should respond with a status msg */
751 if (ixpnpe_recvmsg_sync(sc->sc_npe, msg) != 0) {
752 device_printf(dev, "firmware did not respond as expected\n");
753 return EIO;
754 }
755
756 /* probe for PHY */
757 if (mii_phy_probe(dev, &sc->sc_mii, npe_ifmedia_update, npe_ifmedia_status)) {
758 device_printf(dev, "cannot find PHY %d.\n", sc->sc_phy);
759 return ENXIO;
760 }
761
762 error = npe_dma_setup(sc, &sc->txdma, "tx", npe_txbuf, NPE_MAXSEG);

--- 216 unchanged lines hidden (view full) ---

979npe_setmac(struct npe_softc *sc, u_char *eaddr)
980{
981 WR4(sc, NPE_MAC_UNI_ADDR_1, eaddr[0]);
982 WR4(sc, NPE_MAC_UNI_ADDR_2, eaddr[1]);
983 WR4(sc, NPE_MAC_UNI_ADDR_3, eaddr[2]);
984 WR4(sc, NPE_MAC_UNI_ADDR_4, eaddr[3]);
985 WR4(sc, NPE_MAC_UNI_ADDR_5, eaddr[4]);
986 WR4(sc, NPE_MAC_UNI_ADDR_6, eaddr[5]);
716
717 /* probe for PHY */
718 if (mii_phy_probe(dev, &sc->sc_mii, npe_ifmedia_update, npe_ifmedia_status)) {
719 device_printf(dev, "cannot find PHY %d.\n", sc->sc_phy);
720 return ENXIO;
721 }
722
723 error = npe_dma_setup(sc, &sc->txdma, "tx", npe_txbuf, NPE_MAXSEG);

--- 216 unchanged lines hidden (view full) ---

940npe_setmac(struct npe_softc *sc, u_char *eaddr)
941{
942 WR4(sc, NPE_MAC_UNI_ADDR_1, eaddr[0]);
943 WR4(sc, NPE_MAC_UNI_ADDR_2, eaddr[1]);
944 WR4(sc, NPE_MAC_UNI_ADDR_3, eaddr[2]);
945 WR4(sc, NPE_MAC_UNI_ADDR_4, eaddr[3]);
946 WR4(sc, NPE_MAC_UNI_ADDR_5, eaddr[4]);
947 WR4(sc, NPE_MAC_UNI_ADDR_6, eaddr[5]);
987
988}
989
990static void
991npe_getmac(struct npe_softc *sc, u_char *eaddr)
992{
993 /* NB: the unicast address appears to be loaded from EEPROM on reset */
994 eaddr[0] = RD4(sc, NPE_MAC_UNI_ADDR_1) & 0xff;
995 eaddr[1] = RD4(sc, NPE_MAC_UNI_ADDR_2) & 0xff;

--- 779 unchanged lines hidden ---
948}
949
950static void
951npe_getmac(struct npe_softc *sc, u_char *eaddr)
952{
953 /* NB: the unicast address appears to be loaded from EEPROM on reset */
954 eaddr[0] = RD4(sc, NPE_MAC_UNI_ADDR_1) & 0xff;
955 eaddr[1] = RD4(sc, NPE_MAC_UNI_ADDR_2) & 0xff;

--- 779 unchanged lines hidden ---