Deleted Added
sdiff udiff text old ( 133688 ) new ( 137982 )
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 $");
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_stop(struct hme_softc *);
103static int hme_ioctl(struct ifnet *, u_long, caddr_t);
104static void hme_tick(void *);
105static void hme_watchdog(struct ifnet *);
106static void hme_init(void *);
107static int hme_add_rxbuf(struct hme_softc *, unsigned int, int);
108static int hme_meminit(struct hme_softc *);
109static int hme_mac_bitflip(struct hme_softc *, u_int32_t, u_int32_t,
110 u_int32_t, u_int32_t);
111static void hme_mifinit(struct hme_softc *);
112static void hme_reset(struct hme_softc *);
113static void hme_setladrf(struct hme_softc *, int);
114

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

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

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

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

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

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

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

368}
369
370void
371hme_detach(struct hme_softc *sc)
372{
373 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
374 int i;
375
376 ether_ifdetach(ifp);
377 hme_stop(sc);
378 device_delete_child(sc->sc_dev, sc->sc_miibus);
379
380 for (i = 0; i < HME_NTXQ; i++) {
381 bus_dmamap_destroy(sc->sc_tdmatag,
382 sc->sc_rb.rb_txdesc[i].htx_dmamap);
383 }
384 bus_dmamap_destroy(sc->sc_rdmatag, sc->sc_rb.rb_spare_dmamap);
385 for (i = 0; i < HME_NRXDESC; i++) {

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

395 bus_dma_tag_destroy(sc->sc_cdmatag);
396 bus_dma_tag_destroy(sc->sc_pdmatag);
397}
398
399void
400hme_suspend(struct hme_softc *sc)
401{
402
403 hme_stop(sc);
404}
405
406void
407hme_resume(struct hme_softc *sc)
408{
409 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
410
411 if ((ifp->if_flags & IFF_UP) != 0)
412 hme_init(ifp);
413}
414
415static void
416hme_cdma_callback(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
417{
418 struct hme_softc *sc = (struct hme_softc *)xsc;
419
420 if (error != 0)

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

436 callout_reset(&sc->sc_tick_ch, hz, hme_tick, sc);
437}
438
439static void
440hme_reset(struct hme_softc *sc)
441{
442 int s;
443
444 s = splnet();
445 hme_init(sc);
446 splx(s);
447}
448
449static void
450hme_stop(struct hme_softc *sc)
451{
452 u_int32_t v;
453 int n;
454

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

666/*
667 * Initialization of interface; set up initialization block
668 * and transmit/receive descriptor rings.
669 */
670static void
671hme_init(void *xsc)
672{
673 struct hme_softc *sc = (struct hme_softc *)xsc;
674 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
675 u_int8_t *ea;
676 u_int32_t n, v;
677
678 /*
679 * Initialization sequence. The numbered steps below correspond
680 * to the sequence outlined in section 6.3.5.1 in the Ethernet
681 * Channel Engine manual (part of the PCIO manual).
682 * See also the STP2002-STQ document from Sun Microsystems.
683 */
684
685 /* step 1 & 2. Reset the Ethernet Channel */

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

844 HME_ERX_READ_4(sc, HME_ERXI_CFG),
845 HME_ETX_READ_4(sc, HME_ETXI_CFG));
846 CTR2(KTR_HME, "hme_init: mac rxcfg %#x, maci txcfg %#x",
847 HME_MAC_READ_4(sc, HME_MACI_RXCFG),
848 HME_MAC_READ_4(sc, HME_MACI_TXCFG));
849#endif
850
851 /* Set the current media. */
852 /* mii_mediachg(sc->sc_mii); */
853
854 /* Start the one second timer. */
855 callout_reset(&sc->sc_tick_ch, hz, hme_tick, sc);
856
857 ifp->if_flags |= IFF_RUNNING;
858 ifp->if_flags &= ~IFF_OACTIVE;
859 ifp->if_timer = 0;
860 hme_start(ifp);
861}
862
863struct hme_txdma_arg {
864 struct hme_softc *hta_sc;
865 struct hme_txdesc *hta_htx;
866 int hta_ndescs;
867};
868

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

1054
1055 m->m_pkthdr.rcvif = ifp;
1056 m->m_pkthdr.len = m->m_len = len + HME_RXOFFS;
1057 m_adj(m, HME_RXOFFS);
1058 /* RX TCP/UDP checksum */
1059 if (ifp->if_capenable & IFCAP_RXCSUM)
1060 hme_rxcksum(m, flags);
1061 /* Pass the packet up. */
1062 (*ifp->if_input)(ifp, m);
1063}
1064
1065static void
1066hme_start(struct ifnet *ifp)
1067{
1068 struct hme_softc *sc = (struct hme_softc *)ifp->if_softc;
1069 struct mbuf *m;
1070 int error, enq = 0;
1071
1072 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
1073 return;
1074
1075 error = 0;

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

1168 }
1169 /* Turn off watchdog */
1170 if (sc->sc_rb.rb_td_nbusy == 0)
1171 ifp->if_timer = 0;
1172
1173 /* Update ring */
1174 sc->sc_rb.rb_tdtail = ri;
1175
1176 hme_start(ifp);
1177
1178 if (sc->sc_rb.rb_td_nbusy == 0)
1179 ifp->if_timer = 0;
1180}
1181
1182/*
1183 * RX TCP/UDP checksum
1184 */

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

1297}
1298
1299void
1300hme_intr(void *v)
1301{
1302 struct hme_softc *sc = (struct hme_softc *)v;
1303 u_int32_t status;
1304
1305 status = HME_SEB_READ_4(sc, HME_SEBI_STAT);
1306 CTR1(KTR_HME, "hme_intr: status %#x", (u_int)status);
1307
1308 if ((status & HME_SEB_STAT_ALL_ERRORS) != 0)
1309 hme_eint(sc, status);
1310
1311 if ((status & (HME_SEB_STAT_TXALL | HME_SEB_STAT_HOSTTOTX)) != 0)
1312 hme_tint(sc);
1313
1314 if ((status & HME_SEB_STAT_RXTOHOST) != 0)
1315 hme_rint(sc);
1316}
1317
1318
1319static void
1320hme_watchdog(struct ifnet *ifp)
1321{
1322 struct hme_softc *sc = ifp->if_softc;
1323#ifdef HMEDEBUG
1324 u_int32_t status;
1325
1326 status = HME_SEB_READ_4(sc, HME_SEBI_STAT);
1327 CTR1(KTR_HME, "hme_watchdog: status %x", (u_int)status);
1328#endif
1329 device_printf(sc->sc_dev, "device timeout\n");
1330 ++ifp->if_oerrors;
1331
1332 hme_reset(sc);
1333}
1334
1335/*
1336 * Initialize the MII Management Interface
1337 */
1338static void
1339hme_mifinit(struct hme_softc *sc)
1340{
1341 u_int32_t v;
1342
1343 /* Configure the MIF in frame mode */
1344 v = HME_MIF_READ_4(sc, HME_MIFI_CFG);
1345 v &= ~HME_MIF_CFG_BBMODE;
1346 HME_MIF_WRITE_4(sc, HME_MIFI_CFG, v);
1347}
1348
1349/*
1350 * MII interface
1351 */
1352int
1353hme_mii_readreg(device_t dev, int phy, int reg)
1354{
1355 struct hme_softc *sc = device_get_softc(dev);
1356 int n;
1357 u_int32_t v;
1358
1359 /* Select the desired PHY in the MIF configuration register */
1360 v = HME_MIF_READ_4(sc, HME_MIFI_CFG);
1361 /* Clear PHY select bit */
1362 v &= ~HME_MIF_CFG_PHY;
1363 if (phy == HME_PHYAD_EXTERNAL)
1364 /* Set PHY select bit to get at external device */
1365 v |= HME_MIF_CFG_PHY;
1366 HME_MIF_WRITE_4(sc, HME_MIFI_CFG, v);

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

1371 (MII_COMMAND_READ << HME_MIF_FO_OPC_SHIFT) |
1372 (phy << HME_MIF_FO_PHYAD_SHIFT) |
1373 (reg << HME_MIF_FO_REGAD_SHIFT);
1374
1375 HME_MIF_WRITE_4(sc, HME_MIFI_FO, v);
1376 for (n = 0; n < 100; n++) {
1377 DELAY(1);
1378 v = HME_MIF_READ_4(sc, HME_MIFI_FO);
1379 if (v & HME_MIF_FO_TALSB)
1380 return (v & HME_MIF_FO_DATA);
1381 }
1382
1383 device_printf(sc->sc_dev, "mii_read timeout\n");
1384 return (0);
1385}
1386
1387int
1388hme_mii_writereg(device_t dev, int phy, int reg, int val)
1389{
1390 struct hme_softc *sc = device_get_softc(dev);
1391 int n;
1392 u_int32_t v;
1393
1394 /* Select the desired PHY in the MIF configuration register */
1395 v = HME_MIF_READ_4(sc, HME_MIFI_CFG);
1396 /* Clear PHY select bit */
1397 v &= ~HME_MIF_CFG_PHY;
1398 if (phy == HME_PHYAD_EXTERNAL)
1399 /* Set PHY select bit to get at external device */
1400 v |= HME_MIF_CFG_PHY;
1401 HME_MIF_WRITE_4(sc, HME_MIFI_CFG, v);

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

1407 (phy << HME_MIF_FO_PHYAD_SHIFT) |
1408 (reg << HME_MIF_FO_REGAD_SHIFT) |
1409 (val & HME_MIF_FO_DATA);
1410
1411 HME_MIF_WRITE_4(sc, HME_MIFI_FO, v);
1412 for (n = 0; n < 100; n++) {
1413 DELAY(1);
1414 v = HME_MIF_READ_4(sc, HME_MIFI_FO);
1415 if (v & HME_MIF_FO_TALSB)
1416 return (1);
1417 }
1418
1419 device_printf(sc->sc_dev, "mii_write timeout\n");
1420 return (0);
1421}
1422
1423void
1424hme_mii_statchg(device_t dev)
1425{
1426 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];
1429 u_int32_t v;
1430
1431#ifdef HMEDEBUG
1432 if (sc->sc_debug)
1433 printf("hme_mii_statchg: status change: phy = %d\n", phy);
1434#endif
1435
1436 /* Select the current PHY in the MIF configuration register */
1437 v = HME_MIF_READ_4(sc, HME_MIFI_CFG);
1438 v &= ~HME_MIF_CFG_PHY;
1439 if (phy == HME_PHYAD_EXTERNAL)
1440 v |= HME_MIF_CFG_PHY;
1441 HME_MIF_WRITE_4(sc, HME_MIFI_CFG, v);
1442
1443 /* Set the MAC Full Duplex bit appropriately */
1444 v = HME_MAC_READ_4(sc, HME_MACI_TXCFG);
1445 if (!hme_mac_bitflip(sc, HME_MACI_TXCFG, v, HME_MAC_TXCFG_ENABLE, 0))
1446 return;
1447 if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_FDX) != 0)
1448 v |= HME_MAC_TXCFG_FULLDPLX;
1449 else
1450 v &= ~HME_MAC_TXCFG_FULLDPLX;
1451 HME_MAC_WRITE_4(sc, HME_MACI_TXCFG, v);
1452 if (!hme_mac_bitflip(sc, HME_MACI_TXCFG, v, 0, HME_MAC_TXCFG_ENABLE))
1453 return;
1454}
1455
1456static int
1457hme_mediachange(struct ifnet *ifp)
1458{
1459 struct hme_softc *sc = ifp->if_softc;
1460
1461 return (mii_mediachg(sc->sc_mii));
1462}
1463
1464static void
1465hme_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
1466{
1467 struct hme_softc *sc = ifp->if_softc;
1468
1469 if ((ifp->if_flags & IFF_UP) == 0)
1470 return;
1471
1472 mii_pollstat(sc->sc_mii);
1473 ifmr->ifm_active = sc->sc_mii->mii_media_active;
1474 ifmr->ifm_status = sc->sc_mii->mii_media_status;
1475}
1476
1477/*
1478 * Process an ioctl request.
1479 */
1480static int
1481hme_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1482{
1483 struct hme_softc *sc = ifp->if_softc;
1484 struct ifreq *ifr = (struct ifreq *)data;
1485 int s, error = 0;
1486
1487 s = splnet();
1488
1489 switch (cmd) {
1490 case SIOCSIFFLAGS:
1491 if ((ifp->if_flags & IFF_UP) == 0 &&
1492 (ifp->if_flags & IFF_RUNNING) != 0) {
1493 /*
1494 * If interface is marked down and it is running, then
1495 * stop it.
1496 */
1497 hme_stop(sc);
1498 ifp->if_flags &= ~IFF_RUNNING;
1499 } else if ((ifp->if_flags & IFF_UP) != 0 &&
1500 (ifp->if_flags & IFF_RUNNING) == 0) {
1501 /*
1502 * If interface is marked up and it is stopped, then
1503 * start it.
1504 */
1505 hme_init(sc);
1506 } else if ((ifp->if_flags & IFF_UP) != 0) {
1507 /*
1508 * Reset the interface to pick up changes in any other
1509 * flags that affect hardware registers.
1510 */
1511 hme_init(sc);
1512 }
1513 if ((ifp->if_flags & IFF_LINK0) != 0)
1514 sc->sc_csum_features |= CSUM_UDP;
1515 else
1516 sc->sc_csum_features &= ~CSUM_UDP;
1517 if ((ifp->if_capenable & IFCAP_TXCSUM) != 0)
1518 ifp->if_hwassist = sc->sc_csum_features;
1519#ifdef HMEDEBUG
1520 sc->sc_debug = (ifp->if_flags & IFF_DEBUG) != 0 ? 1 : 0;
1521#endif
1522 break;
1523
1524 case SIOCADDMULTI:
1525 case SIOCDELMULTI:
1526 hme_setladrf(sc, 1);
1527 error = 0;
1528 break;
1529 case SIOCGIFMEDIA:
1530 case SIOCSIFMEDIA:
1531 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii->mii_media, cmd);
1532 break;
1533 case SIOCSIFCAP:
1534 ifp->if_capenable = ifr->ifr_reqcap;
1535 if ((ifp->if_capenable & IFCAP_TXCSUM) != 0)
1536 ifp->if_hwassist = sc->sc_csum_features;
1537 else
1538 ifp->if_hwassist = 0;
1539 break;
1540 default:
1541 error = ether_ioctl(ifp, cmd, data);
1542 break;
1543 }
1544
1545 splx(s);
1546 return (error);
1547}
1548
1549/*
1550 * Set up the logical address filter.
1551 */
1552static void
1553hme_setladrf(struct hme_softc *sc, int reenable)
1554{
1555 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1556 struct ifmultiaddr *inm;
1557 u_int32_t crc;
1558 u_int32_t hash[4];
1559 u_int32_t macc;
1560
1561 /* Clear hash table */
1562 hash[3] = hash[2] = hash[1] = hash[0] = 0;
1563
1564 /* Get current RX configuration */
1565 macc = HME_MAC_READ_4(sc, HME_MACI_RXCFG);
1566
1567 /*
1568 * Disable the receiver while changing it's state as the documentation

--- 60 unchanged lines hidden ---