/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
*/
/* EMAC DMA HW engine uses three rings: * Tx: * TPD: Transmit Packet Descriptor ring. * Rx: * RFD: Receive Free Descriptor ring. * Ring of descriptors with empty buffers to be filled by Rx HW. * RRD: Receive Return Descriptor ring. * Ring of descriptors with buffers filled with received data.
*/
/* Number of bytes of the transmit packet. (include 4-byte CRC) */ #define TPD_BUF_LEN_SET(tpd, val) BITS_SET((tpd)->word[0], 0, 15, val) /* Custom Checksum Offload: When set, ask IP core to offload custom checksum */ #define TPD_CSX_SET(tpd, val) BITS_SET((tpd)->word[1], 8, 8, val) /* TCP Large Send Offload: When set, ask IP core to do offload TCP Large Send */ #define TPD_LSO(tpd) BITS_GET((tpd)->word[1], 12, 12) #define TPD_LSO_SET(tpd, val) BITS_SET((tpd)->word[1], 12, 12, val) /* Large Send Offload Version: When set, indicates this is an LSOv2 * (for both IPv4 and IPv6). When cleared, indicates this is an LSOv1 * (only for IPv4).
*/ #define TPD_LSOV_SET(tpd, val) BITS_SET((tpd)->word[1], 13, 13, val) /* IPv4 packet: When set, indicates this is an IPv4 packet, this bit is only * for LSOV2 format.
*/ #define TPD_IPV4_SET(tpd, val) BITS_SET((tpd)->word[1], 16, 16, val) /* 0: Ethernet frame (DA+SA+TYPE+DATA+CRC) * 1: IEEE 802.3 frame (DA+SA+LEN+DSAP+SSAP+CTL+ORG+TYPE+DATA+CRC)
*/ #define TPD_TYP_SET(tpd, val) BITS_SET((tpd)->word[1], 17, 17, val) /* Low-32bit Buffer Address */ #define TPD_BUFFER_ADDR_L_SET(tpd, val) ((tpd)->word[2] = cpu_to_le32(val)) /* CVLAN Tag to be inserted if INS_VLAN_TAG is set, CVLAN TPID based on global * register configuration.
*/ #define TPD_CVLAN_TAG_SET(tpd, val) BITS_SET((tpd)->word[3], 0, 15, val) /* Insert CVlan Tag: When set, ask MAC to insert CVLAN TAG to outgoing packet
*/ #define TPD_INSTC_SET(tpd, val) BITS_SET((tpd)->word[3], 17, 17, val) /* High-14bit Buffer Address, So, the 64b-bit address is * {DESC_CTRL_11_TX_DATA_HIADDR[17:0],(register) BUFFER_ADDR_H, BUFFER_ADDR_L} * Extend TPD_BUFFER_ADDR_H to [31, 18], because we never enable timestamping.
*/ #define TPD_BUFFER_ADDR_H_SET(tpd, val) BITS_SET((tpd)->word[3], 18, 31, val) /* Format D. Word offset from the 1st byte of this packet to start to calculate * the custom checksum.
*/ #define TPD_PAYLOAD_OFFSET_SET(tpd, val) BITS_SET((tpd)->word[1], 0, 7, val) /* Format D. Word offset from the 1st byte of this packet to fill the custom * checksum to
*/ #define TPD_CXSUM_OFFSET_SET(tpd, val) BITS_SET((tpd)->word[1], 18, 25, val)
/* Format C. TCP Header offset from the 1st byte of this packet. (byte unit) */ #define TPD_TCPHDR_OFFSET_SET(tpd, val) BITS_SET((tpd)->word[1], 0, 7, val) /* Format C. MSS (Maximum Segment Size) got from the protocol layer. (byte unit)
*/ #define TPD_MSS_SET(tpd, val) BITS_SET((tpd)->word[1], 18, 30, val) /* packet length in ext tpd */ #define TPD_PKT_LEN_SET(tpd, val) ((tpd)->word[2] = cpu_to_le32(val))
};
/* emac_ring_header represents a single, contiguous block of DMA space * mapped for the three descriptor rings (tpd, rfd, rrd)
*/ struct emac_ring_header { void *v_addr; /* virtual address */
dma_addr_t dma_addr; /* dma address */
size_t size; /* length in bytes */
size_t used;
};
/* emac_buffer is wrapper around a pointer to a socket buffer * so a DMA handle can be stored along with the skb
*/ struct emac_buffer { struct sk_buff *skb; /* socket buffer */
u16 length; /* rx buffer length */
dma_addr_t dma_addr; /* dma address */
};
/* receive free descriptor (rfd) ring */ struct emac_rfd_ring { struct emac_buffer *rfbuff;
u32 *v_addr; /* virtual address */
dma_addr_t dma_addr; /* dma address */
size_t size; /* length in bytes */ unsignedint count; /* number of desc in the ring */ unsignedint produce_idx; unsignedint process_idx; unsignedint consume_idx; /* unused */
};
/* Receive Return Desciptor (RRD) ring */ struct emac_rrd_ring {
u32 *v_addr; /* virtual address */
dma_addr_t dma_addr; /* physical address */
size_t size; /* length in bytes */ unsignedint count; /* number of desc in the ring */ unsignedint produce_idx; /* unused */ unsignedint consume_idx;
};
size_t size; /* length in bytes */ unsignedint count; /* number of desc in the ring */ unsignedint produce_idx; unsignedint consume_idx; unsignedint last_produce_idx;
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.