Wed Jan 29 06:46:59 2020 UTC ()
Adopt <net/if_stats.h>.


(thorpej)
diff -r1.72 -r1.73 src/sys/dev/pci/if_pcn.c

cvs diff -r1.72 -r1.73 src/sys/dev/pci/if_pcn.c (expand / switch to unified diff)

--- src/sys/dev/pci/if_pcn.c 2019/10/11 14:22:46 1.72
+++ src/sys/dev/pci/if_pcn.c 2020/01/29 06:46:58 1.73
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if_pcn.c,v 1.72 2019/10/11 14:22:46 msaitoh Exp $ */ 1/* $NetBSD: if_pcn.c,v 1.73 2020/01/29 06:46:58 thorpej Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001 Wasabi Systems, Inc. 4 * Copyright (c) 2001 Wasabi Systems, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 7 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -55,27 +55,27 @@ @@ -55,27 +55,27 @@
55 * Ethernet Controller with Integrated PHY 55 * Ethernet Controller with Integrated PHY
56 * 56 *
57 * This also supports the virtual PCnet-PCI Ethernet interface found 57 * This also supports the virtual PCnet-PCI Ethernet interface found
58 * in VMware. 58 * in VMware.
59 * 59 *
60 * TODO: 60 * TODO:
61 * 61 *
62 * * Split this into bus-specific and bus-independent portions. 62 * * Split this into bus-specific and bus-independent portions.
63 * The core could also be used for the ILACC (Am79900) 32-bit 63 * The core could also be used for the ILACC (Am79900) 32-bit
64 * Ethernet chip (XXX only if we use an ILACC-compatible SWSTYLE). 64 * Ethernet chip (XXX only if we use an ILACC-compatible SWSTYLE).
65 */ 65 */
66 66
67#include <sys/cdefs.h> 67#include <sys/cdefs.h>
68__KERNEL_RCSID(0, "$NetBSD: if_pcn.c,v 1.72 2019/10/11 14:22:46 msaitoh Exp $"); 68__KERNEL_RCSID(0, "$NetBSD: if_pcn.c,v 1.73 2020/01/29 06:46:58 thorpej Exp $");
69 69
70#include <sys/param.h> 70#include <sys/param.h>
71#include <sys/systm.h> 71#include <sys/systm.h>
72#include <sys/callout.h> 72#include <sys/callout.h>
73#include <sys/mbuf.h> 73#include <sys/mbuf.h>
74#include <sys/malloc.h> 74#include <sys/malloc.h>
75#include <sys/kernel.h> 75#include <sys/kernel.h>
76#include <sys/socket.h> 76#include <sys/socket.h>
77#include <sys/ioctl.h> 77#include <sys/ioctl.h>
78#include <sys/errno.h> 78#include <sys/errno.h>
79#include <sys/device.h> 79#include <sys/device.h>
80#include <sys/queue.h> 80#include <sys/queue.h>
81 81
@@ -1153,27 +1153,27 @@ static void @@ -1153,27 +1153,27 @@ static void
1153pcn_watchdog(struct ifnet *ifp) 1153pcn_watchdog(struct ifnet *ifp)
1154{ 1154{
1155 struct pcn_softc *sc = ifp->if_softc; 1155 struct pcn_softc *sc = ifp->if_softc;
1156 1156
1157 /* 1157 /*
1158 * Since we're not interrupting every packet, sweep 1158 * Since we're not interrupting every packet, sweep
1159 * up before we report an error. 1159 * up before we report an error.
1160 */ 1160 */
1161 pcn_txintr(sc); 1161 pcn_txintr(sc);
1162 1162
1163 if (sc->sc_txfree != PCN_NTXDESC) { 1163 if (sc->sc_txfree != PCN_NTXDESC) {
1164 printf("%s: device timeout (txfree %d txsfree %d)\n", 1164 printf("%s: device timeout (txfree %d txsfree %d)\n",
1165 device_xname(sc->sc_dev), sc->sc_txfree, sc->sc_txsfree); 1165 device_xname(sc->sc_dev), sc->sc_txfree, sc->sc_txsfree);
1166 ifp->if_oerrors++; 1166 if_statinc(ifp, if_oerrors);
1167 1167
1168 /* Reset the interface. */ 1168 /* Reset the interface. */
1169 (void) pcn_init(ifp); 1169 (void) pcn_init(ifp);
1170 } 1170 }
1171 1171
1172 /* Try to get more packets going. */ 1172 /* Try to get more packets going. */
1173 pcn_start(ifp); 1173 pcn_start(ifp);
1174} 1174}
1175 1175
1176/* 1176/*
1177 * pcn_ioctl: [ifnet interface function] 1177 * pcn_ioctl: [ifnet interface function]
1178 * 1178 *
1179 * Handle control requests from the operator. 1179 * Handle control requests from the operator.
@@ -1238,52 +1238,52 @@ pcn_intr(void *arg) @@ -1238,52 +1238,52 @@ pcn_intr(void *arg)
1238 if (csr0 & LE_C0_RINT) { 1238 if (csr0 & LE_C0_RINT) {
1239 PCN_EVCNT_INCR(&sc->sc_ev_rxintr); 1239 PCN_EVCNT_INCR(&sc->sc_ev_rxintr);
1240 wantinit = pcn_rxintr(sc); 1240 wantinit = pcn_rxintr(sc);
1241 } 1241 }
1242 1242
1243 if (csr0 & LE_C0_TINT) { 1243 if (csr0 & LE_C0_TINT) {
1244 PCN_EVCNT_INCR(&sc->sc_ev_txintr); 1244 PCN_EVCNT_INCR(&sc->sc_ev_txintr);
1245 pcn_txintr(sc); 1245 pcn_txintr(sc);
1246 } 1246 }
1247 1247
1248 if (csr0 & LE_C0_ERR) { 1248 if (csr0 & LE_C0_ERR) {
1249 if (csr0 & LE_C0_BABL) { 1249 if (csr0 & LE_C0_BABL) {
1250 PCN_EVCNT_INCR(&sc->sc_ev_babl); 1250 PCN_EVCNT_INCR(&sc->sc_ev_babl);
1251 ifp->if_oerrors++; 1251 if_statinc(ifp, if_oerrors);
1252 } 1252 }
1253 if (csr0 & LE_C0_MISS) { 1253 if (csr0 & LE_C0_MISS) {
1254 PCN_EVCNT_INCR(&sc->sc_ev_miss); 1254 PCN_EVCNT_INCR(&sc->sc_ev_miss);
1255 ifp->if_ierrors++; 1255 if_statinc(ifp, if_ierrors);
1256 } 1256 }
1257 if (csr0 & LE_C0_MERR) { 1257 if (csr0 & LE_C0_MERR) {
1258 PCN_EVCNT_INCR(&sc->sc_ev_merr); 1258 PCN_EVCNT_INCR(&sc->sc_ev_merr);
1259 printf("%s: memory error\n", 1259 printf("%s: memory error\n",
1260 device_xname(sc->sc_dev)); 1260 device_xname(sc->sc_dev));
1261 wantinit = 1; 1261 wantinit = 1;
1262 break; 1262 break;
1263 } 1263 }
1264 } 1264 }
1265 1265
1266 if ((csr0 & LE_C0_RXON) == 0) { 1266 if ((csr0 & LE_C0_RXON) == 0) {
1267 printf("%s: receiver disabled\n", 1267 printf("%s: receiver disabled\n",
1268 device_xname(sc->sc_dev)); 1268 device_xname(sc->sc_dev));
1269 ifp->if_ierrors++; 1269 if_statinc(ifp, if_ierrors);
1270 wantinit = 1; 1270 wantinit = 1;
1271 } 1271 }
1272 1272
1273 if ((csr0 & LE_C0_TXON) == 0) { 1273 if ((csr0 & LE_C0_TXON) == 0) {
1274 printf("%s: transmitter disabled\n", 1274 printf("%s: transmitter disabled\n",
1275 device_xname(sc->sc_dev)); 1275 device_xname(sc->sc_dev));
1276 ifp->if_oerrors++; 1276 if_statinc(ifp, if_oerrors);
1277 wantinit = 1; 1277 wantinit = 1;
1278 } 1278 }
1279 } 1279 }
1280 1280
1281 if (handled) { 1281 if (handled) {
1282 if (wantinit) 1282 if (wantinit)
1283 pcn_init(ifp); 1283 pcn_init(ifp);
1284 1284
1285 /* Try to get more packets going. */ 1285 /* Try to get more packets going. */
1286 if_schedule_deferred_start(ifp); 1286 if_schedule_deferred_start(ifp);
1287 } 1287 }
1288 1288
1289 return handled; 1289 return handled;
@@ -1339,27 +1339,27 @@ pcn_txintr(struct pcn_softc *sc) @@ -1339,27 +1339,27 @@ pcn_txintr(struct pcn_softc *sc)
1339 1339
1340 tmd1 = le32toh(sc->sc_txdescs[txs->txs_lastdesc].tmd1); 1340 tmd1 = le32toh(sc->sc_txdescs[txs->txs_lastdesc].tmd1);
1341 if (tmd1 & LE_T1_OWN) 1341 if (tmd1 & LE_T1_OWN)
1342 break; 1342 break;
1343 1343
1344 /* 1344 /*
1345 * Slightly annoying -- we have to loop through the 1345 * Slightly annoying -- we have to loop through the
1346 * descriptors we've used looking for ERR, since it 1346 * descriptors we've used looking for ERR, since it
1347 * can appear on any descriptor in the chain. 1347 * can appear on any descriptor in the chain.
1348 */ 1348 */
1349 for (j = txs->txs_firstdesc;; j = PCN_NEXTTX(j)) { 1349 for (j = txs->txs_firstdesc;; j = PCN_NEXTTX(j)) {
1350 tmd = le32toh(sc->sc_txdescs[j].tmd1); 1350 tmd = le32toh(sc->sc_txdescs[j].tmd1);
1351 if (tmd & LE_T1_ERR) { 1351 if (tmd & LE_T1_ERR) {
1352 ifp->if_oerrors++; 1352 if_statinc(ifp, if_oerrors);
1353 if (sc->sc_swstyle == LE_B20_SSTYLE_PCNETPCI3) 1353 if (sc->sc_swstyle == LE_B20_SSTYLE_PCNETPCI3)
1354 tmd2 = le32toh(sc->sc_txdescs[j].tmd0); 1354 tmd2 = le32toh(sc->sc_txdescs[j].tmd0);
1355 else 1355 else
1356 tmd2 = le32toh(sc->sc_txdescs[j].tmd2); 1356 tmd2 = le32toh(sc->sc_txdescs[j].tmd2);
1357 if (tmd2 & LE_T2_UFLO) { 1357 if (tmd2 & LE_T2_UFLO) {
1358 if (sc->sc_xmtsp < LE_C80_XMTSP_MAX) { 1358 if (sc->sc_xmtsp < LE_C80_XMTSP_MAX) {
1359 sc->sc_xmtsp++; 1359 sc->sc_xmtsp++;
1360 printf("%s: transmit " 1360 printf("%s: transmit "
1361 "underrun; new threshold: " 1361 "underrun; new threshold: "
1362 "%s\n", 1362 "%s\n",
1363 device_xname(sc->sc_dev), 1363 device_xname(sc->sc_dev),
1364 sc->sc_xmtsp_desc[ 1364 sc->sc_xmtsp_desc[
1365 sc->sc_xmtsp]); 1365 sc->sc_xmtsp]);
@@ -1370,41 +1370,41 @@ pcn_txintr(struct pcn_softc *sc) @@ -1370,41 +1370,41 @@ pcn_txintr(struct pcn_softc *sc)
1370 LE_C80_XMTFW(sc->sc_xmtfw)); 1370 LE_C80_XMTFW(sc->sc_xmtfw));
1371 pcn_csr_write(sc, LE_CSR5, 1371 pcn_csr_write(sc, LE_CSR5,
1372 sc->sc_csr5); 1372 sc->sc_csr5);
1373 } else { 1373 } else {
1374 printf("%s: transmit " 1374 printf("%s: transmit "
1375 "underrun\n", 1375 "underrun\n",
1376 device_xname(sc->sc_dev)); 1376 device_xname(sc->sc_dev));
1377 } 1377 }
1378 } else if (tmd2 & LE_T2_BUFF) { 1378 } else if (tmd2 & LE_T2_BUFF) {
1379 printf("%s: transmit buffer error\n", 1379 printf("%s: transmit buffer error\n",
1380 device_xname(sc->sc_dev)); 1380 device_xname(sc->sc_dev));
1381 } 1381 }
1382 if (tmd2 & LE_T2_LCOL) 1382 if (tmd2 & LE_T2_LCOL)
1383 ifp->if_collisions++; 1383 if_statinc(ifp, if_collisions);
1384 if (tmd2 & LE_T2_RTRY) 1384 if (tmd2 & LE_T2_RTRY)
1385 ifp->if_collisions += 16; 1385 if_statadd(ifp, if_collisions, 16);
1386 goto next_packet; 1386 goto next_packet;
1387 } 1387 }
1388 if (j == txs->txs_lastdesc) 1388 if (j == txs->txs_lastdesc)
1389 break; 1389 break;
1390 } 1390 }
1391 if (tmd1 & LE_T1_ONE) 1391 if (tmd1 & LE_T1_ONE)
1392 ifp->if_collisions++; 1392 if_statinc(ifp, if_collisions);
1393 else if (tmd & LE_T1_MORE) { 1393 else if (tmd & LE_T1_MORE) {
1394 /* Real number is unknown. */ 1394 /* Real number is unknown. */
1395 ifp->if_collisions += 2; 1395 if_statadd(ifp, if_collisions, 2);
1396 } 1396 }
1397 ifp->if_opackets++; 1397 if_statinc(ifp, if_opackets);
1398 next_packet: 1398 next_packet:
1399 sc->sc_txfree += txs->txs_dmamap->dm_nsegs; 1399 sc->sc_txfree += txs->txs_dmamap->dm_nsegs;
1400 bus_dmamap_sync(sc->sc_dmat, txs->txs_dmamap, 1400 bus_dmamap_sync(sc->sc_dmat, txs->txs_dmamap,
1401 0, txs->txs_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1401 0, txs->txs_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
1402 bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap); 1402 bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap);
1403 m_freem(txs->txs_mbuf); 1403 m_freem(txs->txs_mbuf);
1404 txs->txs_mbuf = NULL; 1404 txs->txs_mbuf = NULL;
1405 } 1405 }
1406 1406
1407 /* Update the dirty transmit buffer pointer. */ 1407 /* Update the dirty transmit buffer pointer. */
1408 sc->sc_txsdirty = i; 1408 sc->sc_txsdirty = i;
1409 1409
1410 /* 1410 /*
@@ -1451,27 +1451,27 @@ pcn_rxintr(struct pcn_softc *sc) @@ -1451,27 +1451,27 @@ pcn_rxintr(struct pcn_softc *sc)
1451 /* Make sure the packet is in a single buffer. */ 1451 /* Make sure the packet is in a single buffer. */
1452 if ((rmd1 & (LE_R1_STP | LE_R1_ENP)) != 1452 if ((rmd1 & (LE_R1_STP | LE_R1_ENP)) !=
1453 (LE_R1_STP | LE_R1_ENP)) { 1453 (LE_R1_STP | LE_R1_ENP)) {
1454 printf("%s: packet spilled into next buffer\n", 1454 printf("%s: packet spilled into next buffer\n",
1455 device_xname(sc->sc_dev)); 1455 device_xname(sc->sc_dev));
1456 return 1; /* pcn_intr() will re-init */ 1456 return 1; /* pcn_intr() will re-init */
1457 } 1457 }
1458 1458
1459 /* 1459 /*
1460 * If the packet had an error, simple recycle the 1460 * If the packet had an error, simple recycle the
1461 * buffer. 1461 * buffer.
1462 */ 1462 */
1463 if (rmd1 & LE_R1_ERR) { 1463 if (rmd1 & LE_R1_ERR) {
1464 ifp->if_ierrors++; 1464 if_statinc(ifp, if_ierrors);
1465 /* 1465 /*
1466 * If we got an overflow error, chances 1466 * If we got an overflow error, chances
1467 * are there will be a CRC error. In 1467 * are there will be a CRC error. In
1468 * this case, just print the overflow 1468 * this case, just print the overflow
1469 * error, and skip the others. 1469 * error, and skip the others.
1470 */ 1470 */
1471 if (rmd1 & LE_R1_OFLO) 1471 if (rmd1 & LE_R1_OFLO)
1472 printf("%s: overflow error\n", 1472 printf("%s: overflow error\n",
1473 device_xname(sc->sc_dev)); 1473 device_xname(sc->sc_dev));
1474 else { 1474 else {
1475#define PRINTIT(x, str) \ 1475#define PRINTIT(x, str) \
1476 if (rmd1 & (x)) \ 1476 if (rmd1 & (x)) \
1477 printf("%s: %s\n", \ 1477 printf("%s: %s\n", \
@@ -1520,27 +1520,27 @@ pcn_rxintr(struct pcn_softc *sc) @@ -1520,27 +1520,27 @@ pcn_rxintr(struct pcn_softc *sc)
1520 if (m == NULL) 1520 if (m == NULL)
1521 goto dropit; 1521 goto dropit;
1522 m->m_data += 2; 1522 m->m_data += 2;
1523 memcpy(mtod(m, void *), 1523 memcpy(mtod(m, void *),
1524 mtod(rxs->rxs_mbuf, void *), len); 1524 mtod(rxs->rxs_mbuf, void *), len);
1525 PCN_INIT_RXDESC(sc, i); 1525 PCN_INIT_RXDESC(sc, i);
1526 bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0, 1526 bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
1527 rxs->rxs_dmamap->dm_mapsize, 1527 rxs->rxs_dmamap->dm_mapsize,
1528 BUS_DMASYNC_PREREAD); 1528 BUS_DMASYNC_PREREAD);
1529 } else { 1529 } else {
1530 m = rxs->rxs_mbuf; 1530 m = rxs->rxs_mbuf;
1531 if (pcn_add_rxbuf(sc, i) != 0) { 1531 if (pcn_add_rxbuf(sc, i) != 0) {
1532 dropit: 1532 dropit:
1533 ifp->if_ierrors++; 1533 if_statinc(ifp, if_ierrors);
1534 PCN_INIT_RXDESC(sc, i); 1534 PCN_INIT_RXDESC(sc, i);
1535 bus_dmamap_sync(sc->sc_dmat, 1535 bus_dmamap_sync(sc->sc_dmat,
1536 rxs->rxs_dmamap, 0, 1536 rxs->rxs_dmamap, 0,
1537 rxs->rxs_dmamap->dm_mapsize, 1537 rxs->rxs_dmamap->dm_mapsize,
1538 BUS_DMASYNC_PREREAD); 1538 BUS_DMASYNC_PREREAD);
1539 continue; 1539 continue;
1540 } 1540 }
1541 } 1541 }
1542 1542
1543 m_set_rcvif(m, ifp); 1543 m_set_rcvif(m, ifp);
1544 m->m_pkthdr.len = m->m_len = len; 1544 m->m_pkthdr.len = m->m_len = len;
1545 1545
1546 /* Pass it on. */ 1546 /* Pass it on. */