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 --- |