Changeset b99c023 in rtems-libbsd


Ignore:
Timestamp:
Mar 30, 2015, 12:30:04 PM (5 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
afaeccc05a556f6aa25ba044a7e49d6aa634a59e, master
Children:
051b634
Parents:
5deeb69
git-author:
Sebastian Huber <sebastian.huber@…> (03/30/15 12:30:04)
git-committer:
Sebastian Huber <sebastian.huber@…> (01/10/17 08:53:33)
Message:

if_dwc: Checksum offload

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

Legend:

Unmodified
Added
Removed
  • freebsd/sys/dev/dwc/if_dwc.c

    r5deeb69 rb99c023  
    103103#define DDESC_TDES0_TXFIRST             (1U << 28)
    104104#define DDESC_TDES0_TXCRCDIS            (1U << 27)
     105#define DDESC_TDES0_CIC_IP_HDR          (0x1U << 22)
     106#define DDESC_TDES0_CIC_IP_HDR_PYL      (0x2U << 22)
     107#define DDESC_TDES0_CIC_IP_HDR_PYL_PHDR (0x3U << 22)
    105108#define DDESC_TDES0_TXRINGEND           (1U << 21)
    106109#define DDESC_TDES0_TXCHAIN             (1U << 20)
     
    109112#define DDESC_RDES0_FL_MASK             0x3fff
    110113#define DDESC_RDES0_FL_SHIFT            16      /* Frame Length */
     114#define DDESC_RDES0_ESA                 (1U << 0)
    111115#define DDESC_RDES1_CHAINED             (1U << 14)
     116#define DDESC_RDES4_IP_PYL_ERR          (1U << 4)
     117#define DDESC_RDES4_IP_HDR_ERR          (1U << 3)
     118#define DDESC_RDES4_IP_PYL_TYPE_MSK     0x7U
     119#define DDESC_RDES4_IP_PYL_UDP          1U
     120#define DDESC_RDES4_IP_PYL_TCP          2U
    112121
    113122/* Alt descriptor bits. */
     
    131140        uint32_t addr;          /* pointer to buffer data */
    132141        uint32_t addr_next;     /* link to next descriptor */
     142        uint32_t tdes4;
     143        uint32_t tdes5;
     144        uint32_t timestamp_low;
     145        uint32_t timestamp_high;
    133146};
    134147
     
    139152#define DWC_DESC_RING_ALIGN             2048
    140153
     154#define DWC_CKSUM_ASSIST        (CSUM_IP | CSUM_TCP | CSUM_UDP | \
     155                                 CSUM_TCP_IPV6 | CSUM_UDP_IPV6)
     156
    141157static struct resource_spec dwc_spec[] = {
    142158        { SYS_RES_MEMORY,       0,      RF_ACTIVE },
     
    174190
    175191static void
    176 dwc_setup_txdesc(struct dwc_softc *sc, int idx, bus_dma_segment_t segs[TX_MAX_DMA_SEGS],
    177     int nsegs)
     192dwc_setup_txdesc(struct dwc_softc *sc, int csum_flags, int idx,
     193    bus_dma_segment_t segs[TX_MAX_DMA_SEGS], int nsegs)
    178194{
    179195        int i;
     
    212228                            DDESC_TDES0_OWN;
    213229
    214                         if (i == 0)
     230                        if (i == 0) {
    215231                                flags |= DDESC_TDES0_TXFIRST;
     232
     233                                if ((csum_flags & (CSUM_TCP | CSUM_UDP |
     234                                    CSUM_TCP_IPV6 | CSUM_UDP_IPV6)) != 0)
     235                                        flags |=
     236                                            DDESC_TDES0_CIC_IP_HDR_PYL_PHDR;
     237                                else if ((csum_flags & CSUM_IP) != 0)
     238                                        flags |= DDESC_TDES0_CIC_IP_HDR;
     239                        }
    216240
    217241                        if (i == nsegs - 1)
     
    263287            BUS_DMASYNC_PREWRITE);
    264288
    265         dwc_setup_txdesc(sc, idx, segs, nsegs);
     289        dwc_setup_txdesc(sc, m->m_pkthdr.csum_flags, idx, segs, nsegs);
    266290
    267291        ETHER_BPF_MTAP(sc->ifp, m);
     
    463487        /* Enable transmitters */
    464488        reg = READ4(sc, MAC_CONFIGURATION);
     489        reg |= (CONF_IPC);
    465490        reg |= (CONF_JD | CONF_ACS | CONF_BE);
    466491        reg |= (CONF_TE | CONF_RE);
     
    771796        int error, idx, len;
    772797        uint32_t rdes0;
     798        uint32_t rdes4;
    773799
    774800        ifp = sc->ifp;
     
    791817                        m->m_pkthdr.len = len;
    792818                        m->m_len = len;
     819
     820                        /* Check checksum offload flags. */
     821                        if ((rdes0 & DDESC_RDES0_ESA) != 0) {
     822                                rdes4 = sc->rxdesc_ring[idx].tdes4;
     823
     824                                /* TCP or UDP checks out, IP checks out too. */
     825                                if ((rdes4 & DDESC_RDES4_IP_PYL_TYPE_MSK) ==
     826                                    DDESC_RDES4_IP_PYL_UDP ||
     827                                    (rdes4 & DDESC_RDES4_IP_PYL_TYPE_MSK) ==
     828                                    DDESC_RDES4_IP_PYL_TCP) {
     829                                        m->m_pkthdr.csum_flags |=
     830                                                CSUM_IP_CHECKED |
     831                                                CSUM_IP_VALID |
     832                                                CSUM_DATA_VALID |
     833                                                CSUM_PSEUDO_HDR;
     834                                        m->m_pkthdr.csum_data = 0xffff;
     835                                } else if ((rdes4 & (DDESC_RDES4_IP_PYL_ERR |
     836                                    DDESC_RDES4_IP_HDR_ERR)) == 0) {
     837                                        /* Only IP checks out. */
     838                                        m->m_pkthdr.csum_flags |=
     839                                                CSUM_IP_CHECKED |
     840                                                CSUM_IP_VALID;
     841                                        m->m_pkthdr.csum_data = 0xffff;
     842                                }
     843                        }
    793844
    794845                        /* Remove trailing FCS */
     
    10151066                        goto out;
    10161067                }
     1068                sc->rxdesc_ring[idx].tdes4 = 0;
    10171069        }
    10181070
     
    12301282                reg = (BUS_MODE_EIGHTXPBL);
    12311283        reg |= (BUS_MODE_PBL_BEATS_8 << BUS_MODE_PBL_SHIFT);
     1284        reg |= (BUS_MODE_ATDS);
    12321285        WRITE4(sc, BUS_MODE, reg);
    12331286
     
    12571310        if_initname(ifp, device_get_name(dev), device_get_unit(dev));
    12581311        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    1259         ifp->if_capabilities = IFCAP_VLAN_MTU;
     1312        ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6 |
     1313            IFCAP_VLAN_MTU | IFCAP_VLAN_HWCSUM;
    12601314        ifp->if_capenable = ifp->if_capabilities;
     1315        ifp->if_hwassist = DWC_CKSUM_ASSIST;
    12611316        ifp->if_start = dwc_txstart;
    12621317        ifp->if_ioctl = dwc_ioctl;
  • freebsd/sys/dev/dwc/if_dwc.h

    r5deeb69 rb99c023  
    4444#define  CONF_FES               (1 << 14)       /* MII speed select */
    4545#define  CONF_DM                (1 << 11)       /* Full Duplex Enable */
     46#define  CONF_IPC               (1 << 10)       /* Checksum Enable */
    4647#define  CONF_ACS               (1 << 7)
    4748#define  CONF_TE                (1 << 3)
     
    221222#define  BUS_MODE_PBL_SHIFT     8 /* Single block transfer size */
    222223#define  BUS_MODE_PBL_BEATS_8   8
     224#define  BUS_MODE_ATDS          (1 << 7) /* Alternate Descriptor Size */
    223225#define  BUS_MODE_SWR           (1 << 0) /* Reset */
    224226#define TRANSMIT_POLL_DEMAND    0x1004
Note: See TracChangeset for help on using the changeset viewer.