Deleted Added
full compact
1/*-
2 * Copyright (c) 1999 The NetBSD Foundation, Inc.
3 * Copyright (c) 2001-2003 Thomas Moestl <tmm@FreeBSD.org>.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Paul Kranenburg.
8 *

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

33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 * from: NetBSD: hme.c,v 1.29 2002/05/05 03:02:38 thorpej Exp
38 */
39
40#include <sys/cdefs.h>
41__FBSDID("$FreeBSD: head/sys/dev/hme/if_hme.c 133688 2004-08-13 23:14:50Z rwatson $");
41__FBSDID("$FreeBSD: head/sys/dev/hme/if_hme.c 137982 2004-11-22 06:46:30Z yongari $");
42
43/*
44 * HME Ethernet module driver.
45 *
46 * The HME is e.g. part of the PCIO PCI multi function device.
47 * It supports TX gathering and TX and RX checksum offloading.
48 * RX buffers must be aligned at a programmable offset modulo 16. We choose 2
49 * for this offset: mbuf clusters are usually on about 2^11 boundaries, 2 bytes

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

94#include <dev/mii/miivar.h>
95
96#include <machine/bus.h>
97
98#include <dev/hme/if_hmereg.h>
99#include <dev/hme/if_hmevar.h>
100
101static void hme_start(struct ifnet *);
102static void hme_start_locked(struct ifnet *);
103static void hme_stop(struct hme_softc *);
104static int hme_ioctl(struct ifnet *, u_long, caddr_t);
105static void hme_tick(void *);
106static void hme_watchdog(struct ifnet *);
107static void hme_init(void *);
108static void hme_init_locked(void *);
109static int hme_add_rxbuf(struct hme_softc *, unsigned int, int);
110static int hme_meminit(struct hme_softc *);
111static int hme_mac_bitflip(struct hme_softc *, u_int32_t, u_int32_t,
112 u_int32_t, u_int32_t);
113static void hme_mifinit(struct hme_softc *);
114static void hme_reset(struct hme_softc *);
115static void hme_setladrf(struct hme_softc *, int);
116

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

192 * sc_mac{t,h,o} (MAC registers)
193 * sc_mif{t,h,o} (Management Interface registers)
194 *
195 * the maximum bus burst size:
196 * sc_burst
197 *
198 */
199
200 HME_LOCK_ASSERT(sc, MA_NOTOWNED);
201 /* Make sure the chip is stopped. */
202 HME_LOCK(sc);
203 hme_stop(sc);
204 HME_UNLOCK(sc);
205
206 /*
207 * Allocate DMA capable memory
208 * Buffer descriptors must be aligned on a 2048 byte boundary;
209 * take this into account when calculating the size. Note that
210 * the maximum number of descriptors (256) occupies 2048 bytes,
211 * so we allocate that much regardless of HME_N*DESC.
212 */

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

284 }
285
286 sc->sc_csum_features = HME_CSUM_FEATURES;
287 /* Initialize ifnet structure. */
288 ifp->if_softc = sc;
289 if_initname(ifp, device_get_name(sc->sc_dev),
290 device_get_unit(sc->sc_dev));
291 ifp->if_mtu = ETHERMTU;
287 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
288 IFF_NEEDSGIANT;
292 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
293 ifp->if_start = hme_start;
294 ifp->if_ioctl = hme_ioctl;
295 ifp->if_init = hme_init;
296 ifp->if_watchdog = hme_watchdog;
297 IFQ_SET_MAXLEN(&ifp->if_snd, HME_NTXQ);
298 ifp->if_snd.ifq_drv_maxlen = HME_NTXQ;
299 IFQ_SET_READY(&ifp->if_snd);
300
301 HME_LOCK(sc);
302 hme_mifinit(sc);
303 HME_UNLOCK(sc);
304
305 if ((error = mii_phy_probe(sc->sc_dev, &sc->sc_miibus, hme_mediachange,
306 hme_mediastatus)) != 0) {
307 device_printf(sc->sc_dev, "phy probe failed: %d\n", error);
308 goto fail_rxdesc;
309 }
310 sc->sc_mii = device_get_softc(sc->sc_miibus);
311

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

340 /*
341 * Tell the upper layer(s) we support long frames/checksum offloads.
342 */
343 ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
344 ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_HWCSUM;
345 ifp->if_hwassist |= sc->sc_csum_features;
346 ifp->if_capenable |= IFCAP_VLAN_MTU | IFCAP_HWCSUM;
347
342 callout_init(&sc->sc_tick_ch, 0);
348 callout_init(&sc->sc_tick_ch, CALLOUT_MPSAFE);
349 return (0);
350
351fail_txdesc:
352 for (i = 0; i < tdesc; i++) {
353 bus_dmamap_destroy(sc->sc_tdmatag,
354 sc->sc_rb.rb_txdesc[i].htx_dmamap);
355 }
356 bus_dmamap_destroy(sc->sc_rdmatag, sc->sc_rb.rb_spare_dmamap);

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

374}
375
376void
377hme_detach(struct hme_softc *sc)
378{
379 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
380 int i;
381
382 HME_LOCK_ASSERT(sc, MA_NOTOWNED);
383
384 ether_ifdetach(ifp);
385 HME_LOCK(sc);
386 hme_stop(sc);
387 HME_UNLOCK(sc);
388 device_delete_child(sc->sc_dev, sc->sc_miibus);
389
390 for (i = 0; i < HME_NTXQ; i++) {
391 bus_dmamap_destroy(sc->sc_tdmatag,
392 sc->sc_rb.rb_txdesc[i].htx_dmamap);
393 }
394 bus_dmamap_destroy(sc->sc_rdmatag, sc->sc_rb.rb_spare_dmamap);
395 for (i = 0; i < HME_NRXDESC; i++) {

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

405 bus_dma_tag_destroy(sc->sc_cdmatag);
406 bus_dma_tag_destroy(sc->sc_pdmatag);
407}
408
409void
410hme_suspend(struct hme_softc *sc)
411{
412
413 HME_LOCK(sc);
414 hme_stop(sc);
415 HME_UNLOCK(sc);
416}
417
418void
419hme_resume(struct hme_softc *sc)
420{
421 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
422
423 HME_LOCK(sc);
424 if ((ifp->if_flags & IFF_UP) != 0)
412 hme_init(ifp);
425 hme_init_locked(ifp);
426 HME_UNLOCK(sc);
427}
428
429static void
430hme_cdma_callback(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
431{
432 struct hme_softc *sc = (struct hme_softc *)xsc;
433
434 if (error != 0)

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

450 callout_reset(&sc->sc_tick_ch, hz, hme_tick, sc);
451}
452
453static void
454hme_reset(struct hme_softc *sc)
455{
456 int s;
457
458 HME_LOCK(sc);
459 s = splnet();
445 hme_init(sc);
460 hme_init_locked(sc);
461 splx(s);
462 HME_UNLOCK(sc);
463}
464
465static void
466hme_stop(struct hme_softc *sc)
467{
468 u_int32_t v;
469 int n;
470

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

682/*
683 * Initialization of interface; set up initialization block
684 * and transmit/receive descriptor rings.
685 */
686static void
687hme_init(void *xsc)
688{
689 struct hme_softc *sc = (struct hme_softc *)xsc;
690
691 HME_LOCK(sc);
692 hme_init_locked(sc);
693 HME_UNLOCK(sc);
694}
695
696static void
697hme_init_locked(void *xsc)
698{
699 struct hme_softc *sc = (struct hme_softc *)xsc;
700 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
701 u_int8_t *ea;
702 u_int32_t n, v;
703
704 HME_LOCK_ASSERT(sc, MA_OWNED);
705 /*
706 * Initialization sequence. The numbered steps below correspond
707 * to the sequence outlined in section 6.3.5.1 in the Ethernet
708 * Channel Engine manual (part of the PCIO manual).
709 * See also the STP2002-STQ document from Sun Microsystems.
710 */
711
712 /* step 1 & 2. Reset the Ethernet Channel */

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

871 HME_ERX_READ_4(sc, HME_ERXI_CFG),
872 HME_ETX_READ_4(sc, HME_ETXI_CFG));
873 CTR2(KTR_HME, "hme_init: mac rxcfg %#x, maci txcfg %#x",
874 HME_MAC_READ_4(sc, HME_MACI_RXCFG),
875 HME_MAC_READ_4(sc, HME_MACI_TXCFG));
876#endif
877
878 /* Set the current media. */
852 /* mii_mediachg(sc->sc_mii); */
879 /*
880 * HME_UNLOCK(sc);
881 * mii_mediachg(sc->sc_mii);
882 * HME_LOCK(sc);
883 */
884
885 /* Start the one second timer. */
886 callout_reset(&sc->sc_tick_ch, hz, hme_tick, sc);
887
888 ifp->if_flags |= IFF_RUNNING;
889 ifp->if_flags &= ~IFF_OACTIVE;
890 ifp->if_timer = 0;
860 hme_start(ifp);
891 hme_start_locked(ifp);
892}
893
894struct hme_txdma_arg {
895 struct hme_softc *hta_sc;
896 struct hme_txdesc *hta_htx;
897 int hta_ndescs;
898};
899

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

1085
1086 m->m_pkthdr.rcvif = ifp;
1087 m->m_pkthdr.len = m->m_len = len + HME_RXOFFS;
1088 m_adj(m, HME_RXOFFS);
1089 /* RX TCP/UDP checksum */
1090 if (ifp->if_capenable & IFCAP_RXCSUM)
1091 hme_rxcksum(m, flags);
1092 /* Pass the packet up. */
1093 HME_UNLOCK(sc);
1094 (*ifp->if_input)(ifp, m);
1095 HME_LOCK(sc);
1096}
1097
1098static void
1099hme_start(struct ifnet *ifp)
1100{
1101 struct hme_softc *sc = ifp->if_softc;
1102
1103 HME_LOCK(sc);
1104 hme_start_locked(ifp);
1105 HME_UNLOCK(sc);
1106}
1107
1108static void
1109hme_start_locked(struct ifnet *ifp)
1110{
1111 struct hme_softc *sc = (struct hme_softc *)ifp->if_softc;
1112 struct mbuf *m;
1113 int error, enq = 0;
1114
1115 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
1116 return;
1117
1118 error = 0;

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

1211 }
1212 /* Turn off watchdog */
1213 if (sc->sc_rb.rb_td_nbusy == 0)
1214 ifp->if_timer = 0;
1215
1216 /* Update ring */
1217 sc->sc_rb.rb_tdtail = ri;
1218
1176 hme_start(ifp);
1219 hme_start_locked(ifp);
1220
1221 if (sc->sc_rb.rb_td_nbusy == 0)
1222 ifp->if_timer = 0;
1223}
1224
1225/*
1226 * RX TCP/UDP checksum
1227 */

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

1340}
1341
1342void
1343hme_intr(void *v)
1344{
1345 struct hme_softc *sc = (struct hme_softc *)v;
1346 u_int32_t status;
1347
1348 HME_LOCK(sc);
1349 status = HME_SEB_READ_4(sc, HME_SEBI_STAT);
1350 CTR1(KTR_HME, "hme_intr: status %#x", (u_int)status);
1351
1352 if ((status & HME_SEB_STAT_ALL_ERRORS) != 0)
1353 hme_eint(sc, status);
1354
1355 if ((status & (HME_SEB_STAT_TXALL | HME_SEB_STAT_HOSTTOTX)) != 0)
1356 hme_tint(sc);
1357
1358 if ((status & HME_SEB_STAT_RXTOHOST) != 0)
1359 hme_rint(sc);
1360 HME_UNLOCK(sc);
1361}
1362
1363
1364static void
1365hme_watchdog(struct ifnet *ifp)
1366{
1367 struct hme_softc *sc = ifp->if_softc;
1368#ifdef HMEDEBUG
1369 u_int32_t status;
1370#endif
1371
1372 HME_LOCK(sc);
1373#ifdef HMEDEBUG
1374 status = HME_SEB_READ_4(sc, HME_SEBI_STAT);
1375 CTR1(KTR_HME, "hme_watchdog: status %x", (u_int)status);
1376#endif
1377 device_printf(sc->sc_dev, "device timeout\n");
1378 ++ifp->if_oerrors;
1379 HME_UNLOCK(sc);
1380
1381 hme_reset(sc);
1382}
1383
1384/*
1385 * Initialize the MII Management Interface
1386 */
1387static void
1388hme_mifinit(struct hme_softc *sc)
1389{
1390 u_int32_t v;
1391
1392 HME_LOCK_ASSERT(sc, MA_OWNED);
1393
1394 /* Configure the MIF in frame mode */
1395 v = HME_MIF_READ_4(sc, HME_MIFI_CFG);
1396 v &= ~HME_MIF_CFG_BBMODE;
1397 HME_MIF_WRITE_4(sc, HME_MIFI_CFG, v);
1398}
1399
1400/*
1401 * MII interface
1402 */
1403int
1404hme_mii_readreg(device_t dev, int phy, int reg)
1405{
1406 struct hme_softc *sc = device_get_softc(dev);
1407 int n;
1408 u_int32_t v;
1409
1410 HME_LOCK(sc);
1411 /* Select the desired PHY in the MIF configuration register */
1412 v = HME_MIF_READ_4(sc, HME_MIFI_CFG);
1413 /* Clear PHY select bit */
1414 v &= ~HME_MIF_CFG_PHY;
1415 if (phy == HME_PHYAD_EXTERNAL)
1416 /* Set PHY select bit to get at external device */
1417 v |= HME_MIF_CFG_PHY;
1418 HME_MIF_WRITE_4(sc, HME_MIFI_CFG, v);

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

1423 (MII_COMMAND_READ << HME_MIF_FO_OPC_SHIFT) |
1424 (phy << HME_MIF_FO_PHYAD_SHIFT) |
1425 (reg << HME_MIF_FO_REGAD_SHIFT);
1426
1427 HME_MIF_WRITE_4(sc, HME_MIFI_FO, v);
1428 for (n = 0; n < 100; n++) {
1429 DELAY(1);
1430 v = HME_MIF_READ_4(sc, HME_MIFI_FO);
1379 if (v & HME_MIF_FO_TALSB)
1431 if (v & HME_MIF_FO_TALSB) {
1432 HME_UNLOCK(sc);
1433 return (v & HME_MIF_FO_DATA);
1434 }
1435 }
1436
1437 device_printf(sc->sc_dev, "mii_read timeout\n");
1438 HME_UNLOCK(sc);
1439 return (0);
1440}
1441
1442int
1443hme_mii_writereg(device_t dev, int phy, int reg, int val)
1444{
1445 struct hme_softc *sc = device_get_softc(dev);
1446 int n;
1447 u_int32_t v;
1448
1449 HME_LOCK(sc);
1450 /* Select the desired PHY in the MIF configuration register */
1451 v = HME_MIF_READ_4(sc, HME_MIFI_CFG);
1452 /* Clear PHY select bit */
1453 v &= ~HME_MIF_CFG_PHY;
1454 if (phy == HME_PHYAD_EXTERNAL)
1455 /* Set PHY select bit to get at external device */
1456 v |= HME_MIF_CFG_PHY;
1457 HME_MIF_WRITE_4(sc, HME_MIFI_CFG, v);

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

1463 (phy << HME_MIF_FO_PHYAD_SHIFT) |
1464 (reg << HME_MIF_FO_REGAD_SHIFT) |
1465 (val & HME_MIF_FO_DATA);
1466
1467 HME_MIF_WRITE_4(sc, HME_MIFI_FO, v);
1468 for (n = 0; n < 100; n++) {
1469 DELAY(1);
1470 v = HME_MIF_READ_4(sc, HME_MIFI_FO);
1415 if (v & HME_MIF_FO_TALSB)
1471 if (v & HME_MIF_FO_TALSB) {
1472 HME_UNLOCK(sc);
1473 return (1);
1474 }
1475 }
1476
1477 device_printf(sc->sc_dev, "mii_write timeout\n");
1478 HME_UNLOCK(sc);
1479 return (0);
1480}
1481
1482void
1483hme_mii_statchg(device_t dev)
1484{
1485 struct hme_softc *sc = device_get_softc(dev);
1427 int instance = IFM_INST(sc->sc_mii->mii_media.ifm_cur->ifm_media);
1428 int phy = sc->sc_phys[instance];
1486 int instance;
1487 int phy;
1488 u_int32_t v;
1489
1490 HME_LOCK(sc);
1491 instance = IFM_INST(sc->sc_mii->mii_media.ifm_cur->ifm_media);
1492 phy = sc->sc_phys[instance];
1493#ifdef HMEDEBUG
1494 if (sc->sc_debug)
1495 printf("hme_mii_statchg: status change: phy = %d\n", phy);
1496#endif
1497
1498 /* Select the current PHY in the MIF configuration register */
1499 v = HME_MIF_READ_4(sc, HME_MIFI_CFG);
1500 v &= ~HME_MIF_CFG_PHY;
1501 if (phy == HME_PHYAD_EXTERNAL)
1502 v |= HME_MIF_CFG_PHY;
1503 HME_MIF_WRITE_4(sc, HME_MIFI_CFG, v);
1504
1505 /* Set the MAC Full Duplex bit appropriately */
1506 v = HME_MAC_READ_4(sc, HME_MACI_TXCFG);
1445 if (!hme_mac_bitflip(sc, HME_MACI_TXCFG, v, HME_MAC_TXCFG_ENABLE, 0))
1507 if (!hme_mac_bitflip(sc, HME_MACI_TXCFG, v, HME_MAC_TXCFG_ENABLE, 0)) {
1508 HME_UNLOCK(sc);
1509 return;
1510 }
1511 if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_FDX) != 0)
1512 v |= HME_MAC_TXCFG_FULLDPLX;
1513 else
1514 v &= ~HME_MAC_TXCFG_FULLDPLX;
1515 HME_MAC_WRITE_4(sc, HME_MACI_TXCFG, v);
1452 if (!hme_mac_bitflip(sc, HME_MACI_TXCFG, v, 0, HME_MAC_TXCFG_ENABLE))
1516 if (!hme_mac_bitflip(sc, HME_MACI_TXCFG, v, 0, HME_MAC_TXCFG_ENABLE)) {
1517 HME_UNLOCK(sc);
1518 return;
1519 }
1520 HME_UNLOCK(sc);
1521}
1522
1523static int
1524hme_mediachange(struct ifnet *ifp)
1525{
1526 struct hme_softc *sc = ifp->if_softc;
1527
1528 return (mii_mediachg(sc->sc_mii));
1529}
1530
1531static void
1532hme_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
1533{
1534 struct hme_softc *sc = ifp->if_softc;
1535
1469 if ((ifp->if_flags & IFF_UP) == 0)
1536 HME_LOCK(sc);
1537 if ((ifp->if_flags & IFF_UP) == 0) {
1538 HME_UNLOCK(sc);
1539 return;
1540 }
1541
1542 HME_UNLOCK(sc);
1543 mii_pollstat(sc->sc_mii);
1544 HME_LOCK(sc);
1545 ifmr->ifm_active = sc->sc_mii->mii_media_active;
1546 ifmr->ifm_status = sc->sc_mii->mii_media_status;
1547 HME_UNLOCK(sc);
1548}
1549
1550/*
1551 * Process an ioctl request.
1552 */
1553static int
1554hme_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1555{
1556 struct hme_softc *sc = ifp->if_softc;
1557 struct ifreq *ifr = (struct ifreq *)data;
1558 int s, error = 0;
1559
1560 HME_LOCK(sc);
1561 s = splnet();
1562
1563 switch (cmd) {
1564 case SIOCSIFFLAGS:
1565 if ((ifp->if_flags & IFF_UP) == 0 &&
1566 (ifp->if_flags & IFF_RUNNING) != 0) {
1567 /*
1568 * If interface is marked down and it is running, then
1569 * stop it.
1570 */
1571 hme_stop(sc);
1572 ifp->if_flags &= ~IFF_RUNNING;
1573 } else if ((ifp->if_flags & IFF_UP) != 0 &&
1574 (ifp->if_flags & IFF_RUNNING) == 0) {
1575 /*
1576 * If interface is marked up and it is stopped, then
1577 * start it.
1578 */
1505 hme_init(sc);
1579 hme_init_locked(sc);
1580 } else if ((ifp->if_flags & IFF_UP) != 0) {
1581 /*
1582 * Reset the interface to pick up changes in any other
1583 * flags that affect hardware registers.
1584 */
1511 hme_init(sc);
1585 hme_init_locked(sc);
1586 }
1587 if ((ifp->if_flags & IFF_LINK0) != 0)
1588 sc->sc_csum_features |= CSUM_UDP;
1589 else
1590 sc->sc_csum_features &= ~CSUM_UDP;
1591 if ((ifp->if_capenable & IFCAP_TXCSUM) != 0)
1592 ifp->if_hwassist = sc->sc_csum_features;
1593#ifdef HMEDEBUG
1594 sc->sc_debug = (ifp->if_flags & IFF_DEBUG) != 0 ? 1 : 0;
1595#endif
1596 break;
1597
1598 case SIOCADDMULTI:
1599 case SIOCDELMULTI:
1600 hme_setladrf(sc, 1);
1601 error = 0;
1602 break;
1603 case SIOCGIFMEDIA:
1604 case SIOCSIFMEDIA:
1605 HME_UNLOCK(sc);
1606 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii->mii_media, cmd);
1607 HME_LOCK(sc);
1608 break;
1609 case SIOCSIFCAP:
1610 ifp->if_capenable = ifr->ifr_reqcap;
1611 if ((ifp->if_capenable & IFCAP_TXCSUM) != 0)
1612 ifp->if_hwassist = sc->sc_csum_features;
1613 else
1614 ifp->if_hwassist = 0;
1615 break;
1616 default:
1617 HME_UNLOCK(sc);
1618 error = ether_ioctl(ifp, cmd, data);
1619 HME_LOCK(sc);
1620 break;
1621 }
1622
1623 splx(s);
1624 HME_UNLOCK(sc);
1625 return (error);
1626}
1627
1628/*
1629 * Set up the logical address filter.
1630 */
1631static void
1632hme_setladrf(struct hme_softc *sc, int reenable)
1633{
1634 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1635 struct ifmultiaddr *inm;
1636 u_int32_t crc;
1637 u_int32_t hash[4];
1638 u_int32_t macc;
1639
1640 HME_LOCK_ASSERT(sc, MA_OWNED);
1641 /* Clear hash table */
1642 hash[3] = hash[2] = hash[1] = hash[0] = 0;
1643
1644 /* Get current RX configuration */
1645 macc = HME_MAC_READ_4(sc, HME_MACI_RXCFG);
1646
1647 /*
1648 * Disable the receiver while changing it's state as the documentation

--- 60 unchanged lines hidden ---