From d30300f771bffc3964e86472e0c21607521a2e24 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Thu, 12 May 2016 11:17:16 -0300 Subject: net: vl: Move default_net to vl.c All handling of defaults (default_* variables) is inside vl.c, move default_net there too, so we can more easily refactor that code later. Reviewed-by: Paolo Bonzini Signed-off-by: Eduardo Habkost Signed-off-by: Jason Wang --- include/net/net.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/net/net.h b/include/net/net.h index 73e4c466e2..059a464212 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -178,7 +178,6 @@ struct NICInfo { extern int nb_nics; extern NICInfo nd_table[MAX_NICS]; -extern int default_net; extern const char *host_net_devices[]; /* from net.c */ -- cgit v1.2.3 From 16a3df403b10c4ac347159e39005fd520b2648bb Mon Sep 17 00:00:00 2001 From: Zhang Chen Date: Fri, 13 May 2016 15:35:19 +0800 Subject: net/net: Add SocketReadState for reuse codes This function is from net/socket.c, move it to net.c and net.h. Add SocketReadState to make others reuse net_fill_rstate(). suggestion from jason. v4: - move 'rs->finalize = finalize' to rs_init() v3: - remove SocketReadState init callback - put finalize callback to net_fill_rstate() v2: - rename ReadState to SocketReadState - add SocketReadState init and finalize callback v1: - init patch Signed-off-by: Zhang Chen Signed-off-by: Li Zhijian Signed-off-by: Wen Congyang Signed-off-by: Jason Wang --- include/net/net.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include') diff --git a/include/net/net.h b/include/net/net.h index 059a464212..50b10504c5 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -57,6 +57,8 @@ typedef void (SetOffload)(NetClientState *, int, int, int, int, int); typedef void (SetVnetHdrLen)(NetClientState *, int); typedef int (SetVnetLE)(NetClientState *, bool); typedef int (SetVnetBE)(NetClientState *, bool); +typedef struct SocketReadState SocketReadState; +typedef void (SocketReadStateFinalize)(SocketReadState *rs); typedef struct NetClientInfo { NetClientOptionsKind type; @@ -102,6 +104,15 @@ typedef struct NICState { bool peer_deleted; } NICState; +struct SocketReadState { + int state; /* 0 = getting length, 1 = getting data */ + uint32_t index; + uint32_t packet_len; + uint8_t buf[NET_BUFSIZE]; + SocketReadStateFinalize *finalize; +}; + +int net_fill_rstate(SocketReadState *rs, const uint8_t *buf, int size); char *qemu_mac_strdup_printf(const uint8_t *macaddr); NetClientState *qemu_find_netdev(const char *id); int qemu_find_net_clients_except(const char *id, NetClientState **ncs, @@ -160,6 +171,8 @@ ssize_t qemu_deliver_packet_iov(NetClientState *sender, void print_net_client(Monitor *mon, NetClientState *nc); void hmp_info_network(Monitor *mon, const QDict *qdict); +void net_socket_rs_init(SocketReadState *rs, + SocketReadStateFinalize *finalize); /* NIC info */ -- cgit v1.2.3 From 059a65f3ad506105ac9b5b0c7c31f8a0be0abbbc Mon Sep 17 00:00:00 2001 From: Dmitry Fleytman Date: Wed, 1 Jun 2016 11:23:30 +0300 Subject: pci: fix unaligned access in pci_xxx_quad() Replace legacy cpu_to_le64w()/le64_to_cpup() calls with stq_le_p()/ldq_le_p(). Motivation for this modification is that follow up patches add utility function pcie_dev_ser_num_init() for PCIe DSN capability creation which uses pci_set_quad() with a misaligned offset. Signed-off-by: Dmitry Fleytman Signed-off-by: Leonid Bloch Reviewed-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- include/hw/pci/pci.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index ef6ba51f6c..4420f47598 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -465,16 +465,23 @@ pci_get_long(const uint8_t *config) return ldl_le_p(config); } +/* + * PCI capabilities and/or their fields + * are generally DWORD aligned only so + * mechanism used by pci_set/get_quad() + * must be tolerant to unaligned pointers + * + */ static inline void pci_set_quad(uint8_t *config, uint64_t val) { - cpu_to_le64w((uint64_t *)config, val); + stq_le_p(config, val); } static inline uint64_t pci_get_quad(const uint8_t *config) { - return le64_to_cpup((const uint64_t *)config); + return ldq_le_p(config); } static inline void -- cgit v1.2.3 From 3bdfaabbcf0e91d16e90691cf8bd4a836c67279a Mon Sep 17 00:00:00 2001 From: Dmitry Fleytman Date: Wed, 1 Jun 2016 11:23:31 +0300 Subject: msix: make msix_clr_pending() visible for clients This function will be used by e1000e device code. Signed-off-by: Dmitry Fleytman Signed-off-by: Leonid Bloch Reviewed-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- include/hw/pci/msix.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/hw/pci/msix.h b/include/hw/pci/msix.h index 72e5f931c5..048a29dd2f 100644 --- a/include/hw/pci/msix.h +++ b/include/hw/pci/msix.h @@ -29,6 +29,7 @@ int msix_present(PCIDevice *dev); bool msix_is_masked(PCIDevice *dev, unsigned vector); void msix_set_pending(PCIDevice *dev, unsigned vector); +void msix_clr_pending(PCIDevice *dev, int vector); int msix_vector_use(PCIDevice *dev, unsigned vector); void msix_vector_unuse(PCIDevice *dev, unsigned vector); -- cgit v1.2.3 From 83f17ed278dc5a8b3f7f2c8765f17ed4302b74e8 Mon Sep 17 00:00:00 2001 From: Dmitry Fleytman Date: Wed, 1 Jun 2016 11:23:32 +0300 Subject: pci: Introduce define for PM capability version 1.1 Signed-off-by: Dmitry Fleytman Signed-off-by: Leonid Bloch Reviewed-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- include/hw/pci/pci_regs.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/hw/pci/pci_regs.h b/include/hw/pci/pci_regs.h index ba8cbe9278..7a83142578 100644 --- a/include/hw/pci/pci_regs.h +++ b/include/hw/pci/pci_regs.h @@ -1 +1,3 @@ #include "standard-headers/linux/pci_regs.h" + +#define PCI_PM_CAP_VER_1_1 0x0002 /* PCI PM spec ver. 1.1 */ -- cgit v1.2.3 From 6383292ac884f01be609f69d888f54c099af622e Mon Sep 17 00:00:00 2001 From: Dmitry Fleytman Date: Wed, 1 Jun 2016 11:23:33 +0300 Subject: pcie: Add support for PCIe CAP v1 Added support for PCIe CAP v1, while reusing some of the existing v2 infrastructure. Signed-off-by: Dmitry Fleytman Signed-off-by: Leonid Bloch Reviewed-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- include/hw/pci/pcie.h | 4 ++++ include/hw/pci/pcie_regs.h | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h index b48a7a2c5a..cbbf0c5e08 100644 --- a/include/hw/pci/pcie.h +++ b/include/hw/pci/pcie.h @@ -80,8 +80,12 @@ struct PCIExpressDevice { /* PCI express capability helper functions */ int pcie_cap_init(PCIDevice *dev, uint8_t offset, uint8_t type, uint8_t port); +int pcie_cap_v1_init(PCIDevice *dev, uint8_t offset, + uint8_t type, uint8_t port); int pcie_endpoint_cap_init(PCIDevice *dev, uint8_t offset); void pcie_cap_exit(PCIDevice *dev); +int pcie_endpoint_cap_v1_init(PCIDevice *dev, uint8_t offset); +void pcie_cap_v1_exit(PCIDevice *dev); uint8_t pcie_cap_get_type(const PCIDevice *dev); void pcie_cap_flags_set_vector(PCIDevice *dev, uint8_t vector); uint8_t pcie_cap_flags_get_vector(PCIDevice *dev); diff --git a/include/hw/pci/pcie_regs.h b/include/hw/pci/pcie_regs.h index 6a28b33e69..a95522a13b 100644 --- a/include/hw/pci/pcie_regs.h +++ b/include/hw/pci/pcie_regs.h @@ -11,6 +11,7 @@ /* express capability */ +#define PCI_EXP_VER1_SIZEOF 0x14 /* express capability of ver. 1 */ #define PCI_EXP_VER2_SIZEOF 0x3c /* express capability of ver. 2 */ #define PCI_EXT_CAP_VER_SHIFT 16 #define PCI_EXT_CAP_NEXT_SHIFT 20 @@ -26,11 +27,11 @@ (((x) + PCI_EXT_CAP_ALIGN - 1) & ~(PCI_EXT_CAP_ALIGN - 1)) /* PCI_EXP_FLAGS */ -#define PCI_EXP_FLAGS_VER2 2 /* for now, supports only ver. 2 */ +#define PCI_EXP_FLAGS_VER1 1 +#define PCI_EXP_FLAGS_VER2 2 #define PCI_EXP_FLAGS_IRQ_SHIFT ctz32(PCI_EXP_FLAGS_IRQ) #define PCI_EXP_FLAGS_TYPE_SHIFT ctz32(PCI_EXP_FLAGS_TYPE) - /* PCI_EXP_LINK{CAP, STA} */ /* link speed */ #define PCI_EXP_LNK_LS_25 1 -- cgit v1.2.3 From b56b9285e4b58a0b8fe8b011d48dbf7e2afba785 Mon Sep 17 00:00:00 2001 From: Dmitry Fleytman Date: Wed, 1 Jun 2016 11:23:34 +0300 Subject: pcie: Introduce function for DSN capability creation Signed-off-by: Dmitry Fleytman Signed-off-by: Leonid Bloch Reviewed-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- include/hw/pci/pcie.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h index cbbf0c5e08..056d25e53c 100644 --- a/include/hw/pci/pcie.h +++ b/include/hw/pci/pcie.h @@ -119,6 +119,7 @@ void pcie_add_capability(PCIDevice *dev, uint16_t offset, uint16_t size); void pcie_ari_init(PCIDevice *dev, uint16_t offset, uint16_t nextfn); +void pcie_dev_ser_num_init(PCIDevice *dev, uint16_t offset, uint64_t ser_num); extern const VMStateDescription vmstate_pcie_device; -- cgit v1.2.3 From 0478d1ddaea3e6e1a19faa82f5bc2ef8f3300c42 Mon Sep 17 00:00:00 2001 From: Dmitry Fleytman Date: Wed, 1 Jun 2016 11:23:36 +0300 Subject: net: Introduce Toeplitz hash calculator Signed-off-by: Dmitry Fleytman Signed-off-by: Leonid Bloch Reviewed-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- include/net/checksum.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'include') diff --git a/include/net/checksum.h b/include/net/checksum.h index 7de1acb79a..dd8b4f6dc2 100644 --- a/include/net/checksum.h +++ b/include/net/checksum.h @@ -18,6 +18,7 @@ #ifndef QEMU_NET_CHECKSUM_H #define QEMU_NET_CHECKSUM_H +#include "qemu/bswap.h" struct iovec; uint32_t net_checksum_add_cont(int len, uint8_t *buf, int seq); @@ -50,4 +51,48 @@ uint32_t net_checksum_add_iov(const struct iovec *iov, const unsigned int iov_cnt, uint32_t iov_off, uint32_t size); +typedef struct toeplitz_key_st { + uint32_t leftmost_32_bits; + uint8_t *next_byte; +} net_toeplitz_key; + +static inline +void net_toeplitz_key_init(net_toeplitz_key *key, uint8_t *key_bytes) +{ + key->leftmost_32_bits = be32_to_cpu(*(uint32_t *)key_bytes); + key->next_byte = key_bytes + sizeof(uint32_t); +} + +static inline +void net_toeplitz_add(uint32_t *result, + uint8_t *input, + uint32_t len, + net_toeplitz_key *key) +{ + register uint32_t accumulator = *result; + register uint32_t leftmost_32_bits = key->leftmost_32_bits; + register uint32_t byte; + + for (byte = 0; byte < len; byte++) { + register uint8_t input_byte = input[byte]; + register uint8_t key_byte = *(key->next_byte++); + register uint8_t bit; + + for (bit = 0; bit < 8; bit++) { + if (input_byte & (1 << 7)) { + accumulator ^= leftmost_32_bits; + } + + leftmost_32_bits = + (leftmost_32_bits << 1) | ((key_byte & (1 << 7)) >> 7); + + input_byte <<= 1; + key_byte <<= 1; + } + } + + key->leftmost_32_bits = leftmost_32_bits; + *result = accumulator; +} + #endif /* QEMU_NET_CHECKSUM_H */ -- cgit v1.2.3 From 6d1d4939a6477f15f69234b426aaaae52369f22b Mon Sep 17 00:00:00 2001 From: Dmitry Fleytman Date: Wed, 1 Jun 2016 11:23:37 +0300 Subject: net: Add macros for MAC address tracing These macros will be used by future commits introducing e1000e device emulation and by vmxnet3 tracing code. Signed-off-by: Dmitry Fleytman Signed-off-by: Leonid Bloch Reviewed-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- include/net/net.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/net/net.h b/include/net/net.h index 50b10504c5..a69e382ba7 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -9,6 +9,11 @@ #include "migration/vmstate.h" #include "qapi-types.h" +#define MAC_FMT "%02X:%02X:%02X:%02X:%02X:%02X" +#define MAC_ARG(x) ((uint8_t *)(x))[0], ((uint8_t *)(x))[1], \ + ((uint8_t *)(x))[2], ((uint8_t *)(x))[3], \ + ((uint8_t *)(x))[4], ((uint8_t *)(x))[5] + #define MAX_QUEUE_NUM 1024 /* Maximum GSO packet size (64k) plus plenty of room for -- cgit v1.2.3 From 66409b7c8bd0ebb075a6af8cbc7846fc0a95107d Mon Sep 17 00:00:00 2001 From: Dmitry Fleytman Date: Wed, 1 Jun 2016 11:23:40 +0300 Subject: rtl8139: Move more TCP definitions to common header Signed-off-by: Dmitry Fleytman Signed-off-by: Leonid Bloch Reviewed-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- include/net/eth.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/net/eth.h b/include/net/eth.h index 18d0be3b16..5a32259938 100644 --- a/include/net/eth.h +++ b/include/net/eth.h @@ -67,6 +67,14 @@ typedef struct tcp_header { uint16_t th_urp; /* urgent pointer */ } tcp_header; +#define TCP_FLAGS_ONLY(flags) ((flags) & 0x3f) + +#define TCP_HEADER_FLAGS(tcp) \ + TCP_FLAGS_ONLY(be16_to_cpu((tcp)->th_offset_flags)) + +#define TCP_HEADER_DATA_OFFSET(tcp) \ + (((be16_to_cpu((tcp)->th_offset_flags) >> 12) & 0xf) << 2) + typedef struct udp_header { uint16_t uh_sport; /* source port */ uint16_t uh_dport; /* destination port */ -- cgit v1.2.3 From eb700029c7836798046191d62d595363d92c84d4 Mon Sep 17 00:00:00 2001 From: Dmitry Fleytman Date: Wed, 1 Jun 2016 11:23:41 +0300 Subject: net_pkt: Extend packet abstraction as required by e1000e functionality This patch extends the TX/RX packet abstractions with features that will be used by the e1000e device implementation. Changes are: 1. Support iovec lists for RX buffers 2. Deeper RX packets parsing 3. Loopback option for TX packets 4. Extended VLAN headers handling 5. RSS processing for RX packets Signed-off-by: Dmitry Fleytman Signed-off-by: Leonid Bloch Reviewed-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- include/net/checksum.h | 4 +- include/net/eth.h | 150 +++++++++++++++++++++++++++++++++++-------------- 2 files changed, 110 insertions(+), 44 deletions(-) (limited to 'include') diff --git a/include/net/checksum.h b/include/net/checksum.h index dd8b4f6dc2..7df472c2fe 100644 --- a/include/net/checksum.h +++ b/include/net/checksum.h @@ -46,10 +46,12 @@ net_raw_checksum(uint8_t *data, int length) * @iov_cnt: number of array elements * @iov_off: starting iov offset for checksumming * @size: length of data to be checksummed + * @csum_offset: offset of the checksum chunk */ uint32_t net_checksum_add_iov(const struct iovec *iov, const unsigned int iov_cnt, - uint32_t iov_off, uint32_t size); + uint32_t iov_off, uint32_t size, + uint32_t csum_offset); typedef struct toeplitz_key_st { uint32_t leftmost_32_bits; diff --git a/include/net/eth.h b/include/net/eth.h index 5a32259938..2013175857 100644 --- a/include/net/eth.h +++ b/include/net/eth.h @@ -72,6 +72,8 @@ typedef struct tcp_header { #define TCP_HEADER_FLAGS(tcp) \ TCP_FLAGS_ONLY(be16_to_cpu((tcp)->th_offset_flags)) +#define TCP_FLAG_ACK 0x10 + #define TCP_HEADER_DATA_OFFSET(tcp) \ (((be16_to_cpu((tcp)->th_offset_flags) >> 12) & 0xf) << 2) @@ -116,11 +118,34 @@ struct ip6_header { struct in6_address ip6_dst; /* destination address */ }; +typedef struct ip6_pseudo_header { + struct in6_address ip6_src; + struct in6_address ip6_dst; + uint32_t len; + uint8_t zero[3]; + uint8_t next_hdr; +} ip6_pseudo_header; + struct ip6_ext_hdr { uint8_t ip6r_nxt; /* next header */ uint8_t ip6r_len; /* length in units of 8 octets */ }; +struct ip6_ext_hdr_routing { + uint8_t nxt; + uint8_t len; + uint8_t rtype; + uint8_t segleft; + uint8_t rsvd[4]; +}; + +struct ip6_option_hdr { +#define IP6_OPT_PAD1 (0x00) +#define IP6_OPT_HOME (0xC9) + uint8_t type; + uint8_t len; +}; + struct udp_hdr { uint16_t uh_sport; /* source port */ uint16_t uh_dport; /* destination port */ @@ -169,19 +194,22 @@ struct tcp_hdr { #define PKT_GET_IP_HDR(p) \ ((struct ip_header *)(((uint8_t *)(p)) + eth_get_l2_hdr_length(p))) #define IP_HDR_GET_LEN(p) \ - ((((struct ip_header *)p)->ip_ver_len & 0x0F) << 2) + ((((struct ip_header *)(p))->ip_ver_len & 0x0F) << 2) #define PKT_GET_IP_HDR_LEN(p) \ (IP_HDR_GET_LEN(PKT_GET_IP_HDR(p))) #define PKT_GET_IP6_HDR(p) \ ((struct ip6_header *) (((uint8_t *)(p)) + eth_get_l2_hdr_length(p))) #define IP_HEADER_VERSION(ip) \ - ((ip->ip_ver_len >> 4)&0xf) + (((ip)->ip_ver_len >> 4) & 0xf) +#define IP4_IS_FRAGMENT(ip) \ + ((be16_to_cpu((ip)->ip_off) & (IP_OFFMASK | IP_MF)) != 0) #define ETH_P_IP (0x0800) /* Internet Protocol packet */ #define ETH_P_ARP (0x0806) /* Address Resolution packet */ #define ETH_P_IPV6 (0x86dd) #define ETH_P_VLAN (0x8100) #define ETH_P_DVLAN (0x88a8) +#define ETH_P_UNKNOWN (0xffff) #define VLAN_VID_MASK 0x0fff #define IP_HEADER_VERSION_4 (4) #define IP_HEADER_VERSION_6 (6) @@ -266,7 +294,7 @@ eth_get_l2_hdr_length(const void *p) case ETH_P_VLAN: return sizeof(struct eth_header) + sizeof(struct vlan_header); case ETH_P_DVLAN: - if (hvlan->h_proto == ETH_P_VLAN) { + if (be16_to_cpu(hvlan->h_proto) == ETH_P_VLAN) { return sizeof(struct eth_header) + 2 * sizeof(struct vlan_header); } else { return sizeof(struct eth_header) + sizeof(struct vlan_header); @@ -276,6 +304,19 @@ eth_get_l2_hdr_length(const void *p) } } +static inline uint32_t +eth_get_l2_hdr_length_iov(const struct iovec *iov, int iovcnt) +{ + uint8_t p[sizeof(struct eth_header) + sizeof(struct vlan_header)]; + size_t copied = iov_to_buf(iov, iovcnt, 0, p, ARRAY_SIZE(p)); + + if (copied < ARRAY_SIZE(p)) { + return copied; + } + + return eth_get_l2_hdr_length(p); +} + static inline uint16_t eth_get_pkt_tci(const void *p) { @@ -290,51 +331,67 @@ eth_get_pkt_tci(const void *p) } } -static inline bool -eth_strip_vlan(const void *p, uint8_t *new_ehdr_buf, - uint16_t *payload_offset, uint16_t *tci) -{ - uint16_t proto = be16_to_cpu(PKT_GET_ETH_HDR(p)->h_proto); - struct vlan_header *hvlan = PKT_GET_VLAN_HDR(p); - struct eth_header *new_ehdr = (struct eth_header *) new_ehdr_buf; +bool +eth_strip_vlan(const struct iovec *iov, int iovcnt, size_t iovoff, + uint8_t *new_ehdr_buf, + uint16_t *payload_offset, uint16_t *tci); - switch (proto) { - case ETH_P_VLAN: - case ETH_P_DVLAN: - memcpy(new_ehdr->h_source, PKT_GET_ETH_HDR(p)->h_source, ETH_ALEN); - memcpy(new_ehdr->h_dest, PKT_GET_ETH_HDR(p)->h_dest, ETH_ALEN); - new_ehdr->h_proto = hvlan->h_proto; - *tci = be16_to_cpu(hvlan->h_tci); - *payload_offset = - sizeof(struct eth_header) + sizeof(struct vlan_header); - if (be16_to_cpu(new_ehdr->h_proto) == ETH_P_VLAN) { - memcpy(PKT_GET_VLAN_HDR(new_ehdr), - PKT_GET_DVLAN_HDR(p), - sizeof(struct vlan_header)); - *payload_offset += sizeof(struct vlan_header); - } - return true; - default: - return false; - } -} +bool +eth_strip_vlan_ex(const struct iovec *iov, int iovcnt, size_t iovoff, + uint16_t vet, uint8_t *new_ehdr_buf, + uint16_t *payload_offset, uint16_t *tci); -static inline uint16_t -eth_get_l3_proto(const void *l2hdr, size_t l2hdr_len) +uint16_t +eth_get_l3_proto(const struct iovec *l2hdr_iov, int iovcnt, size_t l2hdr_len); + +void eth_setup_vlan_headers_ex(struct eth_header *ehdr, uint16_t vlan_tag, + uint16_t vlan_ethtype, bool *is_new); + +static inline void +eth_setup_vlan_headers(struct eth_header *ehdr, uint16_t vlan_tag, + bool *is_new) { - uint8_t *proto_ptr = (uint8_t *) l2hdr + l2hdr_len - sizeof(uint16_t); - return be16_to_cpup((uint16_t *)proto_ptr); + eth_setup_vlan_headers_ex(ehdr, vlan_tag, ETH_P_VLAN, is_new); } -void eth_setup_vlan_headers(struct eth_header *ehdr, uint16_t vlan_tag, - bool *is_new); uint8_t eth_get_gso_type(uint16_t l3_proto, uint8_t *l3_hdr, uint8_t l4proto); -void eth_get_protocols(const uint8_t *headers, - uint32_t hdr_length, +typedef struct eth_ip6_hdr_info_st { + uint8_t l4proto; + size_t full_hdr_len; + struct ip6_header ip6_hdr; + bool has_ext_hdrs; + bool rss_ex_src_valid; + struct in6_address rss_ex_src; + bool rss_ex_dst_valid; + struct in6_address rss_ex_dst; + bool fragment; +} eth_ip6_hdr_info; + +typedef struct eth_ip4_hdr_info_st { + struct ip_header ip4_hdr; + bool fragment; +} eth_ip4_hdr_info; + +typedef struct eth_l4_hdr_info_st { + union { + struct tcp_header tcp; + struct udp_header udp; + } hdr; + + bool has_tcp_data; +} eth_l4_hdr_info; + +void eth_get_protocols(const struct iovec *iov, int iovcnt, bool *isip4, bool *isip6, - bool *isudp, bool *istcp); + bool *isudp, bool *istcp, + size_t *l3hdr_off, + size_t *l4hdr_off, + size_t *l5hdr_off, + eth_ip6_hdr_info *ip6hdr_info, + eth_ip4_hdr_info *ip4hdr_info, + eth_l4_hdr_info *l4hdr_info); void eth_setup_ip4_fragmentation(const void *l2hdr, size_t l2hdr_len, void *l3hdr, size_t l3hdr_len, @@ -345,11 +402,18 @@ void eth_fix_ip4_checksum(void *l3hdr, size_t l3hdr_len); uint32_t -eth_calc_pseudo_hdr_csum(struct ip_header *iphdr, uint16_t csl); +eth_calc_ip4_pseudo_hdr_csum(struct ip_header *iphdr, + uint16_t csl, + uint32_t *cso); + +uint32_t +eth_calc_ip6_pseudo_hdr_csum(struct ip6_header *iphdr, + uint16_t csl, + uint8_t l4_proto, + uint32_t *cso); bool -eth_parse_ipv6_hdr(struct iovec *pkt, int pkt_frags, - size_t ip6hdr_off, uint8_t *l4proto, - size_t *full_hdr_len); +eth_parse_ipv6_hdr(const struct iovec *pkt, int pkt_frags, + size_t ip6hdr_off, eth_ip6_hdr_info *info); #endif -- cgit v1.2.3 From 1bb3c37182399c618485aefe158ea1f94182c67b Mon Sep 17 00:00:00 2001 From: Jean-Christophe Dubois Date: Mon, 30 May 2016 19:26:02 +0200 Subject: i.MX: Rename i.MX FEC defines to ENET_XXX Signed-off-by: Jean-Christophe Dubois Signed-off-by: Jason Wang --- include/hw/net/imx_fec.h | 64 ++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 32 deletions(-) (limited to 'include') diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h index cbf86509e8..e5e2f11837 100644 --- a/include/hw/net/imx_fec.h +++ b/include/hw/net/imx_fec.h @@ -30,24 +30,24 @@ #include "hw/sysbus.h" #include "net/net.h" -#define FEC_MAX_FRAME_SIZE 2032 +#define ENET_MAX_FRAME_SIZE 2032 -#define FEC_INT_HB (1 << 31) -#define FEC_INT_BABR (1 << 30) -#define FEC_INT_BABT (1 << 29) -#define FEC_INT_GRA (1 << 28) -#define FEC_INT_TXF (1 << 27) -#define FEC_INT_TXB (1 << 26) -#define FEC_INT_RXF (1 << 25) -#define FEC_INT_RXB (1 << 24) -#define FEC_INT_MII (1 << 23) -#define FEC_INT_EBERR (1 << 22) -#define FEC_INT_LC (1 << 21) -#define FEC_INT_RL (1 << 20) -#define FEC_INT_UN (1 << 19) +#define ENET_INT_HB (1 << 31) +#define ENET_INT_BABR (1 << 30) +#define ENET_INT_BABT (1 << 29) +#define ENET_INT_GRA (1 << 28) +#define ENET_INT_TXF (1 << 27) +#define ENET_INT_TXB (1 << 26) +#define ENET_INT_RXF (1 << 25) +#define ENET_INT_RXB (1 << 24) +#define ENET_INT_MII (1 << 23) +#define ENET_INT_EBERR (1 << 22) +#define ENET_INT_LC (1 << 21) +#define ENET_INT_RL (1 << 20) +#define ENET_INT_UN (1 << 19) -#define FEC_EN 2 -#define FEC_RESET 1 +#define ENET_ECR_RESET (1 << 0) +#define ENET_ECR_ETHEREN (1 << 1) /* Buffer Descriptor. */ typedef struct { @@ -56,22 +56,22 @@ typedef struct { uint32_t data; } IMXFECBufDesc; -#define FEC_BD_R (1 << 15) -#define FEC_BD_E (1 << 15) -#define FEC_BD_O1 (1 << 14) -#define FEC_BD_W (1 << 13) -#define FEC_BD_O2 (1 << 12) -#define FEC_BD_L (1 << 11) -#define FEC_BD_TC (1 << 10) -#define FEC_BD_ABC (1 << 9) -#define FEC_BD_M (1 << 8) -#define FEC_BD_BC (1 << 7) -#define FEC_BD_MC (1 << 6) -#define FEC_BD_LG (1 << 5) -#define FEC_BD_NO (1 << 4) -#define FEC_BD_CR (1 << 2) -#define FEC_BD_OV (1 << 1) -#define FEC_BD_TR (1 << 0) +#define ENET_BD_R (1 << 15) +#define ENET_BD_E (1 << 15) +#define ENET_BD_O1 (1 << 14) +#define ENET_BD_W (1 << 13) +#define ENET_BD_O2 (1 << 12) +#define ENET_BD_L (1 << 11) +#define ENET_BD_TC (1 << 10) +#define ENET_BD_ABC (1 << 9) +#define ENET_BD_M (1 << 8) +#define ENET_BD_BC (1 << 7) +#define ENET_BD_MC (1 << 6) +#define ENET_BD_LG (1 << 5) +#define ENET_BD_NO (1 << 4) +#define ENET_BD_CR (1 << 2) +#define ENET_BD_OV (1 << 1) +#define ENET_BD_TR (1 << 0) typedef struct IMXFECState { /*< private >*/ -- cgit v1.2.3 From db0de35268066108c693db52db24e89581878dd4 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Dubois Date: Mon, 30 May 2016 19:26:05 +0200 Subject: i.MX: move FEC device to a register array structure. This is to prepare for the ENET Gb device of the i.MX6. Signed-off-by: Jean-Christophe Dubois Signed-off-by: Jason Wang --- include/hw/net/imx_fec.h | 51 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 17 deletions(-) (limited to 'include') diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h index e5e2f11837..ed7a3b54ac 100644 --- a/include/hw/net/imx_fec.h +++ b/include/hw/net/imx_fec.h @@ -30,6 +30,33 @@ #include "hw/sysbus.h" #include "net/net.h" +#define ENET_EIR 1 +#define ENET_EIMR 2 +#define ENET_RDAR 4 +#define ENET_TDAR 5 +#define ENET_ECR 9 +#define ENET_MMFR 16 +#define ENET_MSCR 17 +#define ENET_MIBC 25 +#define ENET_RCR 33 +#define ENET_TCR 49 +#define ENET_PALR 57 +#define ENET_PAUR 58 +#define ENET_OPD 59 +#define ENET_IAUR 70 +#define ENET_IALR 71 +#define ENET_GAUR 72 +#define ENET_GALR 73 +#define ENET_TFWR 81 +#define ENET_FRBR 83 +#define ENET_FRSR 84 +#define ENET_RDSR 96 +#define ENET_TDSR 97 +#define ENET_MRBR 98 +#define ENET_MIIGSK_CFGR 192 +#define ENET_MIIGSK_ENR 194 +#define ENET_MAX 400 + #define ENET_MAX_FRAME_SIZE 2032 #define ENET_INT_HB (1 << 31) @@ -46,6 +73,12 @@ #define ENET_INT_RL (1 << 20) #define ENET_INT_UN (1 << 19) +/* RDAR */ +#define ENET_RDAR_RDAR (1 << 24) + +/* TDAR */ +#define ENET_TDAR_TDAR (1 << 24) + #define ENET_ECR_RESET (1 << 0) #define ENET_ECR_ETHEREN (1 << 1) @@ -83,25 +116,9 @@ typedef struct IMXFECState { qemu_irq irq; MemoryRegion iomem; - uint32_t irq_state; - uint32_t eir; - uint32_t eimr; - uint32_t rx_enabled; + uint32_t regs[ENET_MAX]; uint32_t rx_descriptor; uint32_t tx_descriptor; - uint32_t ecr; - uint32_t mmfr; - uint32_t mscr; - uint32_t mibc; - uint32_t rcr; - uint32_t tcr; - uint32_t tfwr; - uint32_t frsr; - uint32_t erdsr; - uint32_t etdsr; - uint32_t emrbr; - uint32_t miigsk_cfgr; - uint32_t miigsk_enr; uint32_t phy_status; uint32_t phy_control; -- cgit v1.2.3 From a699b410d7120dd67bc6c9beae44868780866f09 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Dubois Date: Mon, 30 May 2016 19:26:10 +0200 Subject: Add ENET/Gbps Ethernet support to FEC device The ENET device (present in i.MX6) is "derived" from FEC and backward compatible with it. This patch adds the necessary support of the added feature in the ENET device to allow Linux to use it (on supported processors). Signed-off-by: Jean-Christophe Dubois Signed-off-by: Jason Wang --- include/hw/net/imx_fec.h | 131 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h index ed7a3b54ac..62ad473b05 100644 --- a/include/hw/net/imx_fec.h +++ b/include/hw/net/imx_fec.h @@ -1,5 +1,5 @@ /* - * i.MX Fast Ethernet Controller emulation. + * i.MX FEC/ENET Ethernet Controller emulation. * * Copyright (c) 2013 Jean-Christophe Dubois. * @@ -27,6 +27,8 @@ #define TYPE_IMX_FEC "imx.fec" #define IMX_FEC(obj) OBJECT_CHECK(IMXFECState, (obj), TYPE_IMX_FEC) +#define TYPE_IMX_ENET "imx.enet" + #include "hw/sysbus.h" #include "net/net.h" @@ -53,12 +55,40 @@ #define ENET_RDSR 96 #define ENET_TDSR 97 #define ENET_MRBR 98 +#define ENET_RSFL 100 +#define ENET_RSEM 101 +#define ENET_RAEM 102 +#define ENET_RAFL 103 +#define ENET_TSEM 104 +#define ENET_TAEM 105 +#define ENET_TAFL 106 +#define ENET_TIPG 107 +#define ENET_FTRL 108 +#define ENET_TACC 112 +#define ENET_RACC 113 #define ENET_MIIGSK_CFGR 192 #define ENET_MIIGSK_ENR 194 +#define ENET_ATCR 256 +#define ENET_ATVR 257 +#define ENET_ATOFF 258 +#define ENET_ATPER 259 +#define ENET_ATCOR 260 +#define ENET_ATINC 261 +#define ENET_ATSTMP 262 +#define ENET_TGSR 385 +#define ENET_TCSR0 386 +#define ENET_TCCR0 387 +#define ENET_TCSR1 388 +#define ENET_TCCR1 389 +#define ENET_TCSR2 390 +#define ENET_TCCR2 391 +#define ENET_TCSR3 392 +#define ENET_TCCR3 393 #define ENET_MAX 400 #define ENET_MAX_FRAME_SIZE 2032 +/* EIR and EIMR */ #define ENET_INT_HB (1 << 31) #define ENET_INT_BABR (1 << 30) #define ENET_INT_BABT (1 << 29) @@ -72,6 +102,17 @@ #define ENET_INT_LC (1 << 21) #define ENET_INT_RL (1 << 20) #define ENET_INT_UN (1 << 19) +#define ENET_INT_PLR (1 << 18) +#define ENET_INT_WAKEUP (1 << 17) +#define ENET_INT_TS_AVAIL (1 << 16) +#define ENET_INT_TS_TIMER (1 << 15) + +#define ENET_INT_MAC (ENET_INT_HB | ENET_INT_BABR | ENET_INT_BABT | \ + ENET_INT_GRA | ENET_INT_TXF | ENET_INT_TXB | \ + ENET_INT_RXF | ENET_INT_RXB | ENET_INT_MII | \ + ENET_INT_EBERR | ENET_INT_LC | ENET_INT_RL | \ + ENET_INT_UN | ENET_INT_PLR | ENET_INT_WAKEUP | \ + ENET_INT_TS_AVAIL) /* RDAR */ #define ENET_RDAR_RDAR (1 << 24) @@ -79,8 +120,54 @@ /* TDAR */ #define ENET_TDAR_TDAR (1 << 24) +/* ECR */ #define ENET_ECR_RESET (1 << 0) #define ENET_ECR_ETHEREN (1 << 1) +#define ENET_ECR_MAGICEN (1 << 2) +#define ENET_ECR_SLEEP (1 << 3) +#define ENET_ECR_EN1588 (1 << 4) +#define ENET_ECR_SPEED (1 << 5) +#define ENET_ECR_DBGEN (1 << 6) +#define ENET_ECR_STOPEN (1 << 7) +#define ENET_ECR_DSBWP (1 << 8) + +/* MIBC */ +#define ENET_MIBC_MIB_DIS (1 << 31) +#define ENET_MIBC_MIB_IDLE (1 << 30) +#define ENET_MIBC_MIB_CLEAR (1 << 29) + +/* RCR */ +#define ENET_RCR_LOOP (1 << 0) +#define ENET_RCR_DRT (1 << 1) +#define ENET_RCR_MII_MODE (1 << 2) +#define ENET_RCR_PROM (1 << 3) +#define ENET_RCR_BC_REJ (1 << 4) +#define ENET_RCR_FCE (1 << 5) +#define ENET_RCR_RGMII_EN (1 << 6) +#define ENET_RCR_RMII_MODE (1 << 8) +#define ENET_RCR_RMII_10T (1 << 9) +#define ENET_RCR_PADEN (1 << 12) +#define ENET_RCR_PAUFWD (1 << 13) +#define ENET_RCR_CRCFWD (1 << 14) +#define ENET_RCR_CFEN (1 << 15) +#define ENET_RCR_MAX_FL_SHIFT (16) +#define ENET_RCR_MAX_FL_LENGTH (14) +#define ENET_RCR_NLC (1 << 30) +#define ENET_RCR_GRS (1 << 31) + +/* TCR */ +#define ENET_TCR_GTS (1 << 0) +#define ENET_TCR_FDEN (1 << 2) +#define ENET_TCR_TFC_PAUSE (1 << 3) +#define ENET_TCR_RFC_PAUSE (1 << 4) +#define ENET_TCR_ADDSEL_SHIFT (5) +#define ENET_TCR_ADDSEL_LENGTH (3) +#define ENET_TCR_CRCFWD (1 << 9) + +/* RDSR */ +#define ENET_TWFR_TFWR_SHIFT (0) +#define ENET_TWFR_TFWR_LENGTH (6) +#define ENET_TWFR_STRFWD (1 << 8) /* Buffer Descriptor. */ typedef struct { @@ -106,6 +193,44 @@ typedef struct { #define ENET_BD_OV (1 << 1) #define ENET_BD_TR (1 << 0) +typedef struct { + uint16_t length; + uint16_t flags; + uint32_t data; + uint16_t status; + uint16_t option; + uint16_t checksum; + uint16_t head_proto; + uint32_t last_buffer; + uint32_t timestamp; + uint32_t reserved[2]; +} IMXENETBufDesc; + +#define ENET_BD_ME (1 << 15) +#define ENET_BD_TX_INT (1 << 14) +#define ENET_BD_TS (1 << 13) +#define ENET_BD_PINS (1 << 12) +#define ENET_BD_IINS (1 << 11) +#define ENET_BD_PE (1 << 10) +#define ENET_BD_CE (1 << 9) +#define ENET_BD_UC (1 << 8) +#define ENET_BD_RX_INT (1 << 7) + +#define ENET_BD_TXE (1 << 15) +#define ENET_BD_UE (1 << 13) +#define ENET_BD_EE (1 << 12) +#define ENET_BD_FE (1 << 11) +#define ENET_BD_LCE (1 << 10) +#define ENET_BD_OE (1 << 9) +#define ENET_BD_TSE (1 << 8) +#define ENET_BD_ICE (1 << 5) +#define ENET_BD_PCR (1 << 4) +#define ENET_BD_VLAN (1 << 2) +#define ENET_BD_IPV6 (1 << 1) +#define ENET_BD_FRAG (1 << 0) + +#define ENET_BD_BDU (1 << 31) + typedef struct IMXFECState { /*< private >*/ SysBusDevice parent_obj; @@ -113,7 +238,7 @@ typedef struct IMXFECState { /*< public >*/ NICState *nic; NICConf conf; - qemu_irq irq; + qemu_irq irq[2]; MemoryRegion iomem; uint32_t regs[ENET_MAX]; @@ -125,6 +250,8 @@ typedef struct IMXFECState { uint32_t phy_advertise; uint32_t phy_int; uint32_t phy_int_mask; + + bool is_fec; } IMXFECState; #endif -- cgit v1.2.3 From 517b5e9a175fe7d47cc0fab6c2310241fd33c115 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Dubois Date: Mon, 30 May 2016 19:26:14 +0200 Subject: Add ENET device to i.MX6 SOC. This adds the ENET device to the i.MX6 SOC. This was tested by booting Linux on an Qemu i.MX6 instance and accessing the internet from the linux guest. Reviewed-by: Peter Maydell Signed-off-by: Jean-Christophe Dubois Signed-off-by: Jason Wang --- include/hw/arm/fsl-imx6.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h index e9157ea4b3..ec6c509d74 100644 --- a/include/hw/arm/fsl-imx6.h +++ b/include/hw/arm/fsl-imx6.h @@ -28,6 +28,7 @@ #include "hw/gpio/imx_gpio.h" #include "hw/sd/sdhci.h" #include "hw/ssi/imx_spi.h" +#include "hw/net/imx_fec.h" #include "exec/memory.h" #include "cpu.h" @@ -58,6 +59,7 @@ typedef struct FslIMX6State { IMXGPIOState gpio[FSL_IMX6_NUM_GPIOS]; SDHCIState esdhc[FSL_IMX6_NUM_ESDHCS]; IMXSPIState spi[FSL_IMX6_NUM_ECSPIS]; + IMXFECState eth; MemoryRegion rom; MemoryRegion caam; MemoryRegion ocram; @@ -436,8 +438,8 @@ typedef struct FslIMX6State { #define FSL_IMX6_HDMI_MASTER_IRQ 115 #define FSL_IMX6_HDMI_CEC_IRQ 116 #define FSL_IMX6_MLB150_LOW_IRQ 117 -#define FSL_IMX6_ENET_MAC_IRQ 118 -#define FSL_IMX6_ENET_MAC_1588_IRQ 119 +#define FSL_IMX6_ENET_MAC_1588_IRQ 118 +#define FSL_IMX6_ENET_MAC_IRQ 119 #define FSL_IMX6_PCIE1_IRQ 120 #define FSL_IMX6_PCIE2_IRQ 121 #define FSL_IMX6_PCIE3_IRQ 122 -- cgit v1.2.3