Changeset 0323c28 in rtems-libbsd


Ignore:
Timestamp:
Oct 25, 2017, 6:01:27 AM (2 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
c1e05b9ea378b2971e3d7704779112b4bc4296da, 4a77611a223ea883fb548679b516d326a020d447
Children:
a8a9cf1
Parents:
fd5ee57
git-author:
Sebastian Huber <sebastian.huber@…> (10/25/17 06:01:27)
git-committer:
Sebastian Huber <sebastian.huber@…> (10/25/17 12:30:01)
Message:

ffec: Add interrupt coalescing support

Code is an adapted from the TSEC (if_tsec) network interface driver.

Update #3090.

Location:
freebsd/sys/dev/ffec
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • freebsd/sys/dev/ffec/if_ffec.c

    rfd5ee57 r0323c28  
    33/*-
    44 * Copyright (c) 2013 Ian Lepore <ian@freebsd.org>
     5 * Copyright (C) 2007-2008 Semihalf, Rafal Jaworowski
     6 * Copyright (C) 2006-2007 Semihalf, Piotr Kruszynski
    57 * All rights reserved.
    68 *
     
    139141#define MAX_IRQ_COUNT 3
    140142
     143/* Interrupt Coalescing types */
     144#define FEC_IC_RX               0
     145#define FEC_IC_TX               1
     146
    141147struct ffec_bufmap {
    142148        struct mbuf     *mbuf;
     
    189195        uint32_t                tx_idx_head;
    190196        uint32_t                tx_idx_tail;
     197
     198        /* interrupt coalescing */
     199        int             rx_ic_time;     /* RW, valid values 0..65535 */
     200        int             rx_ic_count;    /* RW, valid values 0..255 */
     201        int             tx_ic_time;
     202        int             tx_ic_count;
    191203};
    192204
     
    205217static void ffec_txstart_locked(struct ffec_softc *sc);
    206218static void ffec_txfinish_locked(struct ffec_softc *sc);
     219static void ffec_add_sysctls(struct ffec_softc *sc);
     220static int ffec_sysctl_ic_time(SYSCTL_HANDLER_ARGS);
     221static int ffec_sysctl_ic_count(SYSCTL_HANDLER_ARGS);
     222static void ffec_set_ic(struct ffec_softc *sc, bus_size_t off, int count,
     223    int time);
     224static void ffec_set_rxic(struct ffec_softc *sc);
     225static void ffec_set_txic(struct ffec_softc *sc);
    207226
    208227static inline uint16_t
     
    13031322         */
    13041323        WR4(sc, FEC_RDAR_REG, FEC_RDAR_RDAR);
     1324
     1325        ffec_set_rxic(sc);
     1326        ffec_set_txic(sc);
    13051327}
    13061328
     
    14941516        FFEC_LOCK_DESTROY(sc);
    14951517        return (0);
     1518}
     1519
     1520static void
     1521ffec_add_sysctls(struct ffec_softc *sc)
     1522{
     1523        struct sysctl_ctx_list *ctx;
     1524        struct sysctl_oid_list *children;
     1525        struct sysctl_oid *tree;
     1526
     1527        ctx = device_get_sysctl_ctx(sc->dev);
     1528        children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev));
     1529        tree = SYSCTL_ADD_NODE(ctx, children, OID_AUTO, "int_coal",
     1530            CTLFLAG_RD, 0, "FEC Interrupts coalescing");
     1531        children = SYSCTL_CHILDREN(tree);
     1532
     1533        SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "rx_time",
     1534            CTLTYPE_UINT | CTLFLAG_RW, sc, FEC_IC_RX, ffec_sysctl_ic_time,
     1535            "I", "IC RX time threshold (0-65535)");
     1536        SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "rx_count",
     1537            CTLTYPE_UINT | CTLFLAG_RW, sc, FEC_IC_RX, ffec_sysctl_ic_count,
     1538            "I", "IC RX frame count threshold (0-255)");
     1539
     1540        SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tx_time",
     1541            CTLTYPE_UINT | CTLFLAG_RW, sc, FEC_IC_TX, ffec_sysctl_ic_time,
     1542            "I", "IC TX time threshold (0-65535)");
     1543        SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tx_count",
     1544            CTLTYPE_UINT | CTLFLAG_RW, sc, FEC_IC_TX, ffec_sysctl_ic_count,
     1545            "I", "IC TX frame count threshold (0-255)");
     1546}
     1547
     1548/*
     1549 * With Interrupt Coalescing (IC) active, a transmit/receive frame
     1550 * interrupt is raised either upon:
     1551 *
     1552 * - threshold-defined period of time elapsed, or
     1553 * - threshold-defined number of frames is received/transmitted,
     1554 *   whichever occurs first.
     1555 *
     1556 * The following sysctls regulate IC behaviour (for TX/RX separately):
     1557 *
     1558 * dev.tsec.<unit>.int_coal.rx_time
     1559 * dev.tsec.<unit>.int_coal.rx_count
     1560 * dev.tsec.<unit>.int_coal.tx_time
     1561 * dev.tsec.<unit>.int_coal.tx_count
     1562 *
     1563 * Values:
     1564 *
     1565 * - 0 for either time or count disables IC on the given TX/RX path
     1566 *
     1567 * - count: 1-255 (expresses frame count number; note that value of 1 is
     1568 *   effectively IC off)
     1569 *
     1570 * - time: 1-65535 (value corresponds to a real time period and is
     1571 *   expressed in units equivalent to 64 FEC interface clocks, i.e. one timer
     1572 *   threshold unit is 26.5 us, 2.56 us, or 512 ns, corresponding to 10 Mbps,
     1573 *   100 Mbps, or 1Gbps, respectively. For detailed discussion consult the
     1574 *   FEC reference manual.
     1575 */
     1576static int
     1577ffec_sysctl_ic_time(SYSCTL_HANDLER_ARGS)
     1578{
     1579        int error;
     1580        uint32_t time;
     1581        struct ffec_softc *sc = (struct ffec_softc *)arg1;
     1582
     1583        time = (arg2 == FEC_IC_RX) ? sc->rx_ic_time : sc->tx_ic_time;
     1584
     1585        error = sysctl_handle_int(oidp, &time, 0, req);
     1586        if (error != 0)
     1587                return (error);
     1588
     1589        if (time > 65535)
     1590                return (EINVAL);
     1591
     1592        FFEC_LOCK(sc);
     1593        if (arg2 == FEC_IC_RX) {
     1594                sc->rx_ic_time = time;
     1595                ffec_set_rxic(sc);
     1596        } else {
     1597                sc->tx_ic_time = time;
     1598                ffec_set_txic(sc);
     1599        }
     1600        FFEC_UNLOCK(sc);
     1601
     1602        return (0);
     1603}
     1604
     1605static int
     1606ffec_sysctl_ic_count(SYSCTL_HANDLER_ARGS)
     1607{
     1608        int error;
     1609        uint32_t count;
     1610        struct ffec_softc *sc = (struct ffec_softc *)arg1;
     1611
     1612        count = (arg2 == FEC_IC_RX) ? sc->rx_ic_count : sc->tx_ic_count;
     1613
     1614        error = sysctl_handle_int(oidp, &count, 0, req);
     1615        if (error != 0)
     1616                return (error);
     1617
     1618        if (count > 255)
     1619                return (EINVAL);
     1620
     1621        FFEC_LOCK(sc);
     1622        if (arg2 == FEC_IC_RX) {
     1623                sc->rx_ic_count = count;
     1624                ffec_set_rxic(sc);
     1625        } else {
     1626                sc->tx_ic_count = count;
     1627                ffec_set_txic(sc);
     1628        }
     1629        FFEC_UNLOCK(sc);
     1630
     1631        return (0);
     1632}
     1633
     1634static void
     1635ffec_set_ic(struct ffec_softc *sc, bus_size_t off, int count, int time)
     1636{
     1637        uint32_t ic;
     1638
     1639        if (count == 0 || time == 0)
     1640                /* Disable RX IC */
     1641                ic = 0;
     1642        else {
     1643                ic = FEC_IC_ICEN;
     1644                ic |= FEC_IC_ICFT(count);
     1645                ic |= FEC_IC_ICTT(time);
     1646        }
     1647
     1648        WR4(sc, off, ic);
     1649}
     1650
     1651static void
     1652ffec_set_rxic(struct ffec_softc *sc)
     1653{
     1654
     1655        ffec_set_ic(sc, FEC_RXIC0_REG, sc->rx_ic_count, sc->rx_ic_time);
     1656}
     1657
     1658static void
     1659ffec_set_txic(struct ffec_softc *sc)
     1660{
     1661
     1662        ffec_set_ic(sc, FEC_TXIC0_REG, sc->tx_ic_count, sc->tx_ic_time);
    14961663}
    14971664
     
    17821949        WR4(sc, FEC_MSCR_REG, mscr);
    17831950
     1951        /* Configure defaults for interrupts coalescing */
     1952        sc->rx_ic_time = 768;
     1953        sc->rx_ic_count = RX_DESC_COUNT / 4;
     1954        sc->tx_ic_time = 768;
     1955        sc->tx_ic_count = TX_DESC_COUNT / 4;
     1956
     1957        ffec_add_sysctls(sc);
     1958
    17841959        /* Set up the ethernet interface. */
    17851960        sc->ifp = ifp = if_alloc(IFT_ETHER);
  • freebsd/sys/dev/ffec/if_ffecreg.h

    rfd5ee57 r0323c28  
    143143#define   FEC_OPD_PAUSE_DUR_SHIFT         0
    144144#define   FEC_OPD_PAUSE_DUR_MASK          (0xffff << FEC_OPD_PAUSE_DUR_SHIFT)
     145
     146#define FEC_TXIC0_REG                   0x00f0
     147#define FEC_TXIC1_REG                   0x00f4
     148#define FEC_TXIC2_REG                   0x00f8
     149#define FEC_RXIC0_REG                   0x0100
     150#define FEC_RXIC1_REG                   0x0104
     151#define FEC_RXIC2_REG                   0x0108
     152#define   FEC_IC_ICEN                     (1 <<  31)
     153#define   FEC_IC_ICCS                     (1 <<  30)
     154#define   FEC_IC_ICFT(x)                  (((x) & 0xff) << 20)
     155#define   FEC_IC_ICTT(x)                  ((x) & 0xffff)
    145156
    146157#define FEC_IAUR_REG                    0x0118
Note: See TracChangeset for help on using the changeset viewer.