Deleted Added
full compact
if_fxp.c (185329) if_fxp.c (185330)
1/*-
2 * Copyright (c) 1995, David Greenman
3 * Copyright (c) 2001 Jonathan Lemon <jlemon@freebsd.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

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

23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 */
29
30#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1995, David Greenman
3 * Copyright (c) 2001 Jonathan Lemon <jlemon@freebsd.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

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

23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/dev/fxp/if_fxp.c 185329 2008-11-26 06:36:53Z yongari $");
31__FBSDID("$FreeBSD: head/sys/dev/fxp/if_fxp.c 185330 2008-11-26 07:36:17Z yongari $");
32
33/*
34 * Intel EtherExpress Pro/100B PCI Fast Ethernet driver
35 */
36
37#ifdef HAVE_KERNEL_OPTION_HEADERS
38#include "opt_device_polling.h"
39#endif

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

614 sc->rfa_size = sizeof (struct fxp_rfa) - FXP_RFAX_LEN;
615 sc->tx_cmd = FXP_CB_COMMAND_XMIT;
616 }
617
618 /*
619 * Allocate DMA tags and DMA safe memory.
620 */
621 sc->maxtxseg = FXP_NTXSEG;
32
33/*
34 * Intel EtherExpress Pro/100B PCI Fast Ethernet driver
35 */
36
37#ifdef HAVE_KERNEL_OPTION_HEADERS
38#include "opt_device_polling.h"
39#endif

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

614 sc->rfa_size = sizeof (struct fxp_rfa) - FXP_RFAX_LEN;
615 sc->tx_cmd = FXP_CB_COMMAND_XMIT;
616 }
617
618 /*
619 * Allocate DMA tags and DMA safe memory.
620 */
621 sc->maxtxseg = FXP_NTXSEG;
622 if (sc->flags & FXP_FLAG_EXT_RFA)
622 sc->maxsegsize = MCLBYTES;
623 if (sc->flags & FXP_FLAG_EXT_RFA) {
623 sc->maxtxseg--;
624 sc->maxtxseg--;
625 sc->maxsegsize = FXP_TSO_SEGSIZE;
626 }
624 error = bus_dma_tag_create(bus_get_dma_tag(dev), 2, 0,
625 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
627 error = bus_dma_tag_create(bus_get_dma_tag(dev), 2, 0,
628 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
626 MCLBYTES * sc->maxtxseg, sc->maxtxseg, MCLBYTES, 0,
629 sc->maxsegsize * sc->maxtxseg + sizeof(struct ether_vlan_header),
630 sc->maxtxseg, sc->maxsegsize, 0,
627 busdma_lock_mutex, &Giant, &sc->fxp_mtag);
628 if (error) {
629 device_printf(dev, "could not allocate dma tag\n");
630 goto fail;
631 }
632
633 error = bus_dma_tag_create(bus_get_dma_tag(dev), 4, 0,
634 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,

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

775 ifp->if_init = fxp_init;
776 ifp->if_softc = sc;
777 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
778 ifp->if_ioctl = fxp_ioctl;
779 ifp->if_start = fxp_start;
780
781 ifp->if_capabilities = ifp->if_capenable = 0;
782
631 busdma_lock_mutex, &Giant, &sc->fxp_mtag);
632 if (error) {
633 device_printf(dev, "could not allocate dma tag\n");
634 goto fail;
635 }
636
637 error = bus_dma_tag_create(bus_get_dma_tag(dev), 4, 0,
638 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,

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

779 ifp->if_init = fxp_init;
780 ifp->if_softc = sc;
781 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
782 ifp->if_ioctl = fxp_ioctl;
783 ifp->if_start = fxp_start;
784
785 ifp->if_capabilities = ifp->if_capenable = 0;
786
783 /* Enable checksum offload for 82550 or better chips */
787 /* Enable checksum offload/TSO for 82550 or better chips */
784 if (sc->flags & FXP_FLAG_EXT_RFA) {
788 if (sc->flags & FXP_FLAG_EXT_RFA) {
785 ifp->if_hwassist = FXP_CSUM_FEATURES;
786 ifp->if_capabilities |= IFCAP_HWCSUM;
787 ifp->if_capenable |= IFCAP_HWCSUM;
789 ifp->if_hwassist = FXP_CSUM_FEATURES | CSUM_TSO;
790 ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_TSO4;
791 ifp->if_capenable |= IFCAP_HWCSUM | IFCAP_TSO4;
788 }
789
790 if (sc->flags & FXP_FLAG_82559_RXCSUM) {
791 ifp->if_capabilities |= IFCAP_RXCSUM;
792 ifp->if_capenable |= IFCAP_RXCSUM;
793 }
794
795#ifdef DEVICE_POLLING

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

1270
1271static int
1272fxp_encap(struct fxp_softc *sc, struct mbuf **m_head)
1273{
1274 struct ifnet *ifp;
1275 struct mbuf *m;
1276 struct fxp_tx *txp;
1277 struct fxp_cb_tx *cbp;
792 }
793
794 if (sc->flags & FXP_FLAG_82559_RXCSUM) {
795 ifp->if_capabilities |= IFCAP_RXCSUM;
796 ifp->if_capenable |= IFCAP_RXCSUM;
797 }
798
799#ifdef DEVICE_POLLING

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

1274
1275static int
1276fxp_encap(struct fxp_softc *sc, struct mbuf **m_head)
1277{
1278 struct ifnet *ifp;
1279 struct mbuf *m;
1280 struct fxp_tx *txp;
1281 struct fxp_cb_tx *cbp;
1282 struct tcphdr *tcp;
1278 bus_dma_segment_t segs[FXP_NTXSEG];
1283 bus_dma_segment_t segs[FXP_NTXSEG];
1279 int error, i, nseg;
1284 int error, i, nseg, tcp_payload;
1280
1281 FXP_LOCK_ASSERT(sc, MA_OWNED);
1282 ifp = sc->ifp;
1283
1285
1286 FXP_LOCK_ASSERT(sc, MA_OWNED);
1287 ifp = sc->ifp;
1288
1289 tcp_payload = 0;
1290 tcp = NULL;
1284 /*
1285 * Get pointer to next available tx desc.
1286 */
1287 txp = sc->fxp_desc.tx_last->tx_next;
1288
1289 /*
1290 * A note in Appendix B of the Intel 8255x 10/100 Mbps
1291 * Ethernet Controller Family Open Source Software

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

1353 FXP_IPCB_HARDWAREPARSING_ENABLE;
1354 txp->tx_cb->ipcb_ip_schedule |=
1355 FXP_IPCB_IP_CHECKSUM_ENABLE;
1356 }
1357 }
1358#endif
1359 }
1360
1291 /*
1292 * Get pointer to next available tx desc.
1293 */
1294 txp = sc->fxp_desc.tx_last->tx_next;
1295
1296 /*
1297 * A note in Appendix B of the Intel 8255x 10/100 Mbps
1298 * Ethernet Controller Family Open Source Software

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

1360 FXP_IPCB_HARDWAREPARSING_ENABLE;
1361 txp->tx_cb->ipcb_ip_schedule |=
1362 FXP_IPCB_IP_CHECKSUM_ENABLE;
1363 }
1364 }
1365#endif
1366 }
1367
1368 if (m->m_pkthdr.csum_flags & CSUM_TSO) {
1369 /*
1370 * 82550/82551 requires ethernet/IP/TCP headers must be
1371 * contained in the first active transmit buffer.
1372 */
1373 struct ether_header *eh;
1374 struct ip *ip;
1375 uint32_t ip_off, poff;
1376
1377 if (M_WRITABLE(*m_head) == 0) {
1378 /* Get a writable copy. */
1379 m = m_dup(*m_head, M_DONTWAIT);
1380 m_freem(*m_head);
1381 if (m == NULL) {
1382 *m_head = NULL;
1383 return (ENOBUFS);
1384 }
1385 *m_head = m;
1386 }
1387 ip_off = sizeof(struct ether_header);
1388 m = m_pullup(*m_head, ip_off);
1389 if (m == NULL) {
1390 *m_head = NULL;
1391 return (ENOBUFS);
1392 }
1393 eh = mtod(m, struct ether_header *);
1394 /* Check the existence of VLAN tag. */
1395 if (eh->ether_type == htons(ETHERTYPE_VLAN)) {
1396 ip_off = sizeof(struct ether_vlan_header);
1397 m = m_pullup(m, ip_off);
1398 if (m == NULL) {
1399 *m_head = NULL;
1400 return (ENOBUFS);
1401 }
1402 }
1403 m = m_pullup(m, ip_off + sizeof(struct ip));
1404 if (m == NULL) {
1405 *m_head = NULL;
1406 return (ENOBUFS);
1407 }
1408 ip = (struct ip *)(mtod(m, char *) + ip_off);
1409 poff = ip_off + (ip->ip_hl << 2);
1410 m = m_pullup(m, poff + sizeof(struct tcphdr));
1411 if (m == NULL) {
1412 *m_head = NULL;
1413 return (ENOBUFS);
1414 }
1415 tcp = (struct tcphdr *)(mtod(m, char *) + poff);
1416 m = m_pullup(m, poff + sizeof(struct tcphdr) + tcp->th_off);
1417 if (m == NULL) {
1418 *m_head = NULL;
1419 return (ENOBUFS);
1420 }
1421
1422 /*
1423 * Since 82550/82551 doesn't modify IP length and pseudo
1424 * checksum in the first frame driver should compute it.
1425 */
1426 ip->ip_sum = 0;
1427 ip->ip_len = htons(ifp->if_mtu);
1428 tcp->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
1429 htons(IPPROTO_TCP + (tcp->th_off << 2) +
1430 m->m_pkthdr.tso_segsz));
1431 /* Compute total TCP payload. */
1432 tcp_payload = m->m_pkthdr.len - ip_off - (ip->ip_hl << 2);
1433 tcp_payload -= tcp->th_off << 2;
1434 *m_head = m;
1435 }
1436
1361 error = bus_dmamap_load_mbuf_sg(sc->fxp_mtag, txp->tx_map, *m_head,
1362 segs, &nseg, 0);
1363 if (error == EFBIG) {
1364 m = m_collapse(*m_head, M_DONTWAIT, sc->maxtxseg);
1365 if (m == NULL) {
1366 m_freem(*m_head);
1367 *m_head = NULL;
1368 return (ENOMEM);

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

1383 return (EIO);
1384 }
1385
1386 KASSERT(nseg <= sc->maxtxseg, ("too many DMA segments"));
1387 bus_dmamap_sync(sc->fxp_mtag, txp->tx_map, BUS_DMASYNC_PREWRITE);
1388
1389 cbp = txp->tx_cb;
1390 for (i = 0; i < nseg; i++) {
1437 error = bus_dmamap_load_mbuf_sg(sc->fxp_mtag, txp->tx_map, *m_head,
1438 segs, &nseg, 0);
1439 if (error == EFBIG) {
1440 m = m_collapse(*m_head, M_DONTWAIT, sc->maxtxseg);
1441 if (m == NULL) {
1442 m_freem(*m_head);
1443 *m_head = NULL;
1444 return (ENOMEM);

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

1459 return (EIO);
1460 }
1461
1462 KASSERT(nseg <= sc->maxtxseg, ("too many DMA segments"));
1463 bus_dmamap_sync(sc->fxp_mtag, txp->tx_map, BUS_DMASYNC_PREWRITE);
1464
1465 cbp = txp->tx_cb;
1466 for (i = 0; i < nseg; i++) {
1391 KASSERT(segs[i].ds_len <= MCLBYTES, ("segment size too large"));
1392 /*
1393 * If this is an 82550/82551, then we're using extended
1394 * TxCBs _and_ we're using checksum offload. This means
1395 * that the TxCB is really an IPCB. One major difference
1396 * between the two is that with plain extended TxCBs,
1397 * the bottom half of the TxCB contains two entries from
1398 * the TBD array, whereas IPCBs contain just one entry:
1399 * one entry (8 bytes) has been sacrificed for the TCP/IP
1400 * checksum offload control bits. So to make things work
1401 * right, we have to start filling in the TBD array
1402 * starting from a different place depending on whether
1403 * the chip is an 82550/82551 or not.
1404 */
1405 if (sc->flags & FXP_FLAG_EXT_RFA) {
1467 /*
1468 * If this is an 82550/82551, then we're using extended
1469 * TxCBs _and_ we're using checksum offload. This means
1470 * that the TxCB is really an IPCB. One major difference
1471 * between the two is that with plain extended TxCBs,
1472 * the bottom half of the TxCB contains two entries from
1473 * the TBD array, whereas IPCBs contain just one entry:
1474 * one entry (8 bytes) has been sacrificed for the TCP/IP
1475 * checksum offload control bits. So to make things work
1476 * right, we have to start filling in the TBD array
1477 * starting from a different place depending on whether
1478 * the chip is an 82550/82551 or not.
1479 */
1480 if (sc->flags & FXP_FLAG_EXT_RFA) {
1406 cbp->tbd[i + 1].tb_addr = htole32(segs[i].ds_addr);
1407 cbp->tbd[i + 1].tb_size = htole32(segs[i].ds_len);
1481 cbp->tbd[i + 2].tb_addr = htole32(segs[i].ds_addr);
1482 cbp->tbd[i + 2].tb_size = htole32(segs[i].ds_len);
1408 } else {
1409 cbp->tbd[i].tb_addr = htole32(segs[i].ds_addr);
1410 cbp->tbd[i].tb_size = htole32(segs[i].ds_len);
1411 }
1412 }
1483 } else {
1484 cbp->tbd[i].tb_addr = htole32(segs[i].ds_addr);
1485 cbp->tbd[i].tb_size = htole32(segs[i].ds_len);
1486 }
1487 }
1413 cbp->tbd_number = nseg;
1488 if (sc->flags & FXP_FLAG_EXT_RFA) {
1489 /* Configure dynamic TBD for 82550/82551. */
1490 cbp->tbd_number = 0xFF;
1491 cbp->tbd[nseg + 1].tb_size |= htole32(0x8000);
1492 } else
1493 cbp->tbd_number = nseg;
1494 /* Configure TSO. */
1495 if (m->m_pkthdr.csum_flags & CSUM_TSO) {
1496 cbp->tbd[-1].tb_size = htole32(m->m_pkthdr.tso_segsz << 16);
1497 cbp->tbd[1].tb_size = htole32(tcp_payload << 16);
1498 cbp->ipcb_ip_schedule |= FXP_IPCB_LARGESEND_ENABLE |
1499 FXP_IPCB_IP_CHECKSUM_ENABLE |
1500 FXP_IPCB_TCP_PACKET |
1501 FXP_IPCB_TCPUDP_CHECKSUM_ENABLE;
1502 }
1414
1415 txp->tx_mbuf = m;
1416 txp->tx_cb->cb_status = 0;
1417 txp->tx_cb->byte_count = 0;
1418 if (sc->tx_queued != FXP_CXINT_THRESH - 1)
1419 txp->tx_cb->cb_command =
1420 htole16(sc->tx_cmd | FXP_CB_COMMAND_SF |
1421 FXP_CB_COMMAND_S);
1422 else
1423 txp->tx_cb->cb_command =
1424 htole16(sc->tx_cmd | FXP_CB_COMMAND_SF |
1425 FXP_CB_COMMAND_S | FXP_CB_COMMAND_I);
1503
1504 txp->tx_mbuf = m;
1505 txp->tx_cb->cb_status = 0;
1506 txp->tx_cb->byte_count = 0;
1507 if (sc->tx_queued != FXP_CXINT_THRESH - 1)
1508 txp->tx_cb->cb_command =
1509 htole16(sc->tx_cmd | FXP_CB_COMMAND_SF |
1510 FXP_CB_COMMAND_S);
1511 else
1512 txp->tx_cb->cb_command =
1513 htole16(sc->tx_cmd | FXP_CB_COMMAND_SF |
1514 FXP_CB_COMMAND_S | FXP_CB_COMMAND_I);
1426 txp->tx_cb->tx_threshold = tx_threshold;
1515 if ((m->m_pkthdr.csum_flags & CSUM_TSO) == 0)
1516 txp->tx_cb->tx_threshold = tx_threshold;
1427
1428 /*
1429 * Advance the end of list forward.
1430 */
1431
1432#ifdef __alpha__
1433 /*
1434 * On platforms which can't access memory in 16-bit

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

2092 cbp->ci_int = 1; /* interrupt on CU idle */
2093 cbp->ext_txcb_dis = sc->flags & FXP_FLAG_EXT_TXCB ? 0 : 1;
2094 cbp->ext_stats_dis = 1; /* disable extended counters */
2095 cbp->keep_overrun_rx = 0; /* don't pass overrun frames to host */
2096 cbp->save_bf = sc->flags & FXP_FLAG_SAVE_BAD ? 1 : prm;
2097 cbp->disc_short_rx = !prm; /* discard short packets */
2098 cbp->underrun_retry = 1; /* retry mode (once) on DMA underrun */
2099 cbp->two_frames = 0; /* do not limit FIFO to 2 frames */
1517
1518 /*
1519 * Advance the end of list forward.
1520 */
1521
1522#ifdef __alpha__
1523 /*
1524 * On platforms which can't access memory in 16-bit

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

2182 cbp->ci_int = 1; /* interrupt on CU idle */
2183 cbp->ext_txcb_dis = sc->flags & FXP_FLAG_EXT_TXCB ? 0 : 1;
2184 cbp->ext_stats_dis = 1; /* disable extended counters */
2185 cbp->keep_overrun_rx = 0; /* don't pass overrun frames to host */
2186 cbp->save_bf = sc->flags & FXP_FLAG_SAVE_BAD ? 1 : prm;
2187 cbp->disc_short_rx = !prm; /* discard short packets */
2188 cbp->underrun_retry = 1; /* retry mode (once) on DMA underrun */
2189 cbp->two_frames = 0; /* do not limit FIFO to 2 frames */
2100 cbp->dyn_tbd = 0; /* (no) dynamic TBD mode */
2190 cbp->dyn_tbd = sc->flags & FXP_FLAG_EXT_RFA ? 1 : 0;
2101 cbp->ext_rfa = sc->flags & FXP_FLAG_EXT_RFA ? 1 : 0;
2102 cbp->mediatype = sc->flags & FXP_FLAG_SERIAL_MEDIA ? 0 : 1;
2103 cbp->csma_dis = 0; /* (don't) disable link */
2104 cbp->tcp_udp_cksum = ((sc->flags & FXP_FLAG_82559_RXCSUM) != 0 &&
2105 (ifp->if_capenable & IFCAP_RXCSUM) != 0) ? 1 : 0;
2106 cbp->vlan_tco = 0; /* (don't) enable vlan wakeup */
2107 cbp->link_wake_en = 0; /* (don't) assert PME# on link change */
2108 cbp->arp_wake_en = 0; /* (don't) assert PME# on arp */

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

2584 ifp->if_hwassist &= ~FXP_CSUM_FEATURES;
2585 }
2586 if ((mask & IFCAP_RXCSUM) != 0 &&
2587 (ifp->if_capabilities & IFCAP_RXCSUM) != 0) {
2588 ifp->if_capenable ^= IFCAP_RXCSUM;
2589 if ((sc->flags & FXP_FLAG_82559_RXCSUM) != 0)
2590 reinit++;
2591 }
2191 cbp->ext_rfa = sc->flags & FXP_FLAG_EXT_RFA ? 1 : 0;
2192 cbp->mediatype = sc->flags & FXP_FLAG_SERIAL_MEDIA ? 0 : 1;
2193 cbp->csma_dis = 0; /* (don't) disable link */
2194 cbp->tcp_udp_cksum = ((sc->flags & FXP_FLAG_82559_RXCSUM) != 0 &&
2195 (ifp->if_capenable & IFCAP_RXCSUM) != 0) ? 1 : 0;
2196 cbp->vlan_tco = 0; /* (don't) enable vlan wakeup */
2197 cbp->link_wake_en = 0; /* (don't) assert PME# on link change */
2198 cbp->arp_wake_en = 0; /* (don't) assert PME# on arp */

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

2674 ifp->if_hwassist &= ~FXP_CSUM_FEATURES;
2675 }
2676 if ((mask & IFCAP_RXCSUM) != 0 &&
2677 (ifp->if_capabilities & IFCAP_RXCSUM) != 0) {
2678 ifp->if_capenable ^= IFCAP_RXCSUM;
2679 if ((sc->flags & FXP_FLAG_82559_RXCSUM) != 0)
2680 reinit++;
2681 }
2682 if ((mask & IFCAP_TSO4) != 0 &&
2683 (ifp->if_capabilities & IFCAP_TSO4) != 0) {
2684 ifp->if_capenable ^= IFCAP_TSO4;
2685 if ((ifp->if_capenable & IFCAP_TSO4) != 0)
2686 ifp->if_hwassist |= CSUM_TSO;
2687 else
2688 ifp->if_hwassist &= ~CSUM_TSO;
2689 }
2592 if ((mask & IFCAP_VLAN_MTU) != 0 &&
2593 (ifp->if_capabilities & IFCAP_VLAN_MTU) != 0) {
2594 ifp->if_capenable ^= IFCAP_VLAN_MTU;
2595 if (sc->revision != FXP_REV_82557)
2596 flag = FXP_FLAG_LONG_PKT_EN;
2597 else /* a hack to get long frames on the old chip */
2598 flag = FXP_FLAG_SAVE_BAD;
2599 sc->flags ^= flag;

--- 259 unchanged lines hidden ---
2690 if ((mask & IFCAP_VLAN_MTU) != 0 &&
2691 (ifp->if_capabilities & IFCAP_VLAN_MTU) != 0) {
2692 ifp->if_capenable ^= IFCAP_VLAN_MTU;
2693 if (sc->revision != FXP_REV_82557)
2694 flag = FXP_FLAG_LONG_PKT_EN;
2695 else /* a hack to get long frames on the old chip */
2696 flag = FXP_FLAG_SAVE_BAD;
2697 sc->flags ^= flag;

--- 259 unchanged lines hidden ---