1605d52e6SDmitry Fleytman /*
2605d52e6SDmitry Fleytman * QEMU TX packets abstraction
3605d52e6SDmitry Fleytman *
4605d52e6SDmitry Fleytman * Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com)
5605d52e6SDmitry Fleytman *
6605d52e6SDmitry Fleytman * Developed by Daynix Computing LTD (http://www.daynix.com)
7605d52e6SDmitry Fleytman *
8605d52e6SDmitry Fleytman * Authors:
9605d52e6SDmitry Fleytman * Dmitry Fleytman <dmitry@daynix.com>
10605d52e6SDmitry Fleytman * Tamir Shomer <tamirs@daynix.com>
11605d52e6SDmitry Fleytman * Yan Vugenfirer <yan@daynix.com>
12605d52e6SDmitry Fleytman *
13605d52e6SDmitry Fleytman * This work is licensed under the terms of the GNU GPL, version 2 or later.
14605d52e6SDmitry Fleytman * See the COPYING file in the top-level directory.
15605d52e6SDmitry Fleytman *
16605d52e6SDmitry Fleytman */
17605d52e6SDmitry Fleytman
18605d52e6SDmitry Fleytman #ifndef NET_TX_PKT_H
19605d52e6SDmitry Fleytman #define NET_TX_PKT_H
20605d52e6SDmitry Fleytman
21605d52e6SDmitry Fleytman #include "net/eth.h"
22605d52e6SDmitry Fleytman #include "exec/hwaddr.h"
23605d52e6SDmitry Fleytman
24605d52e6SDmitry Fleytman /* define to enable packet dump functions */
25605d52e6SDmitry Fleytman /*#define NET_TX_PKT_DEBUG*/
26605d52e6SDmitry Fleytman
27605d52e6SDmitry Fleytman struct NetTxPkt;
28605d52e6SDmitry Fleytman
29a51db580SAkihiko Odaki typedef void (*NetTxPktFreeFrag)(void *, void *, size_t);
30a51db580SAkihiko Odaki typedef void (*NetTxPktSend)(void *, const struct iovec *, int, const struct iovec *, int);
31ffbd2dbdSAkihiko Odaki
32605d52e6SDmitry Fleytman /**
33605d52e6SDmitry Fleytman * Init function for tx packet functionality
34605d52e6SDmitry Fleytman *
35605d52e6SDmitry Fleytman * @pkt: packet pointer
36605d52e6SDmitry Fleytman * @max_frags: max tx ip fragments
37605d52e6SDmitry Fleytman */
38a51db580SAkihiko Odaki void net_tx_pkt_init(struct NetTxPkt **pkt, uint32_t max_frags);
39605d52e6SDmitry Fleytman
40605d52e6SDmitry Fleytman /**
41605d52e6SDmitry Fleytman * Clean all tx packet resources.
42605d52e6SDmitry Fleytman *
43605d52e6SDmitry Fleytman * @pkt: packet.
44605d52e6SDmitry Fleytman */
45605d52e6SDmitry Fleytman void net_tx_pkt_uninit(struct NetTxPkt *pkt);
46605d52e6SDmitry Fleytman
47605d52e6SDmitry Fleytman /**
48605d52e6SDmitry Fleytman * get virtio header
49605d52e6SDmitry Fleytman *
50605d52e6SDmitry Fleytman * @pkt: packet
51605d52e6SDmitry Fleytman * @ret: virtio header
52605d52e6SDmitry Fleytman */
53605d52e6SDmitry Fleytman struct virtio_net_hdr *net_tx_pkt_get_vhdr(struct NetTxPkt *pkt);
54605d52e6SDmitry Fleytman
55605d52e6SDmitry Fleytman /**
56605d52e6SDmitry Fleytman * build virtio header (will be stored in module context)
57605d52e6SDmitry Fleytman *
58605d52e6SDmitry Fleytman * @pkt: packet
59605d52e6SDmitry Fleytman * @tso_enable: TSO enabled
60605d52e6SDmitry Fleytman * @csum_enable: CSO enabled
61605d52e6SDmitry Fleytman * @gso_size: MSS size for TSO
62f9a9eb16SAkihiko Odaki * @ret: operation result
63605d52e6SDmitry Fleytman *
64605d52e6SDmitry Fleytman */
65f9a9eb16SAkihiko Odaki bool net_tx_pkt_build_vheader(struct NetTxPkt *pkt, bool tso_enable,
66605d52e6SDmitry Fleytman bool csum_enable, uint32_t gso_size);
67605d52e6SDmitry Fleytman
68605d52e6SDmitry Fleytman /**
69eb700029SDmitry Fleytman * updates vlan tag, and adds vlan header with custom ethernet type
70eb700029SDmitry Fleytman * in case it is missing.
71eb700029SDmitry Fleytman *
72eb700029SDmitry Fleytman * @pkt: packet
73eb700029SDmitry Fleytman * @vlan: VLAN tag
74eb700029SDmitry Fleytman * @vlan_ethtype: VLAN header Ethernet type
75eb700029SDmitry Fleytman *
76eb700029SDmitry Fleytman */
77eb700029SDmitry Fleytman void net_tx_pkt_setup_vlan_header_ex(struct NetTxPkt *pkt,
78eb700029SDmitry Fleytman uint16_t vlan, uint16_t vlan_ethtype);
79eb700029SDmitry Fleytman
80eb700029SDmitry Fleytman /**
81605d52e6SDmitry Fleytman * updates vlan tag, and adds vlan header in case it is missing
82605d52e6SDmitry Fleytman *
83605d52e6SDmitry Fleytman * @pkt: packet
84605d52e6SDmitry Fleytman * @vlan: VLAN tag
85605d52e6SDmitry Fleytman *
86605d52e6SDmitry Fleytman */
87eb700029SDmitry Fleytman static inline void
net_tx_pkt_setup_vlan_header(struct NetTxPkt * pkt,uint16_t vlan)88eb700029SDmitry Fleytman net_tx_pkt_setup_vlan_header(struct NetTxPkt *pkt, uint16_t vlan)
89eb700029SDmitry Fleytman {
90eb700029SDmitry Fleytman net_tx_pkt_setup_vlan_header_ex(pkt, vlan, ETH_P_VLAN);
91eb700029SDmitry Fleytman }
92605d52e6SDmitry Fleytman
93605d52e6SDmitry Fleytman /**
94605d52e6SDmitry Fleytman * populate data fragment into pkt context.
95605d52e6SDmitry Fleytman *
96605d52e6SDmitry Fleytman * @pkt: packet
97a51db580SAkihiko Odaki * @base: pointer to fragment
98605d52e6SDmitry Fleytman * @len: length of fragment
99605d52e6SDmitry Fleytman *
100605d52e6SDmitry Fleytman */
101a51db580SAkihiko Odaki bool net_tx_pkt_add_raw_fragment(struct NetTxPkt *pkt, void *base, size_t len);
102605d52e6SDmitry Fleytman
103605d52e6SDmitry Fleytman /**
104eb700029SDmitry Fleytman * Fix ip header fields and calculate IP header and pseudo header checksums.
105605d52e6SDmitry Fleytman *
106605d52e6SDmitry Fleytman * @pkt: packet
107605d52e6SDmitry Fleytman *
108605d52e6SDmitry Fleytman */
109605d52e6SDmitry Fleytman void net_tx_pkt_update_ip_checksums(struct NetTxPkt *pkt);
110605d52e6SDmitry Fleytman
111605d52e6SDmitry Fleytman /**
112eb700029SDmitry Fleytman * Calculate the IP header checksum.
113eb700029SDmitry Fleytman *
114eb700029SDmitry Fleytman * @pkt: packet
115eb700029SDmitry Fleytman *
116eb700029SDmitry Fleytman */
117eb700029SDmitry Fleytman void net_tx_pkt_update_ip_hdr_checksum(struct NetTxPkt *pkt);
118eb700029SDmitry Fleytman
119eb700029SDmitry Fleytman /**
120*f199b13bSAkihiko Odaki * Calculate the SCTP checksum.
121*f199b13bSAkihiko Odaki *
122*f199b13bSAkihiko Odaki * @pkt: packet
123*f199b13bSAkihiko Odaki *
124*f199b13bSAkihiko Odaki */
125*f199b13bSAkihiko Odaki bool net_tx_pkt_update_sctp_checksum(struct NetTxPkt *pkt);
126*f199b13bSAkihiko Odaki
127*f199b13bSAkihiko Odaki /**
128605d52e6SDmitry Fleytman * get length of all populated data.
129605d52e6SDmitry Fleytman *
130605d52e6SDmitry Fleytman * @pkt: packet
131605d52e6SDmitry Fleytman * @ret: total data length
132605d52e6SDmitry Fleytman *
133605d52e6SDmitry Fleytman */
134605d52e6SDmitry Fleytman size_t net_tx_pkt_get_total_len(struct NetTxPkt *pkt);
135605d52e6SDmitry Fleytman
136605d52e6SDmitry Fleytman /**
137605d52e6SDmitry Fleytman * get packet type
138605d52e6SDmitry Fleytman *
139605d52e6SDmitry Fleytman * @pkt: packet
140605d52e6SDmitry Fleytman * @ret: packet type
141605d52e6SDmitry Fleytman *
142605d52e6SDmitry Fleytman */
143605d52e6SDmitry Fleytman eth_pkt_types_e net_tx_pkt_get_packet_type(struct NetTxPkt *pkt);
144605d52e6SDmitry Fleytman
145605d52e6SDmitry Fleytman /**
146605d52e6SDmitry Fleytman * prints packet data if debug is enabled
147605d52e6SDmitry Fleytman *
148605d52e6SDmitry Fleytman * @pkt: packet
149605d52e6SDmitry Fleytman *
150605d52e6SDmitry Fleytman */
151605d52e6SDmitry Fleytman void net_tx_pkt_dump(struct NetTxPkt *pkt);
152605d52e6SDmitry Fleytman
153605d52e6SDmitry Fleytman /**
154605d52e6SDmitry Fleytman * reset tx packet private context (needed to be called between packets)
155605d52e6SDmitry Fleytman *
156605d52e6SDmitry Fleytman * @pkt: packet
157a51db580SAkihiko Odaki * @callback: function to free the fragments
158a51db580SAkihiko Odaki * @context: pointer to be passed to the callback
159605d52e6SDmitry Fleytman */
160a51db580SAkihiko Odaki void net_tx_pkt_reset(struct NetTxPkt *pkt,
161a51db580SAkihiko Odaki NetTxPktFreeFrag callback, void *context);
162605d52e6SDmitry Fleytman
163605d52e6SDmitry Fleytman /**
164163246e1SAkihiko Odaki * Unmap a fragment mapped from a PCI device.
165163246e1SAkihiko Odaki *
166163246e1SAkihiko Odaki * @context: PCI device owning fragment
167163246e1SAkihiko Odaki * @base: pointer to fragment
168163246e1SAkihiko Odaki * @len: length of fragment
169163246e1SAkihiko Odaki */
170163246e1SAkihiko Odaki void net_tx_pkt_unmap_frag_pci(void *context, void *base, size_t len);
171163246e1SAkihiko Odaki
172163246e1SAkihiko Odaki /**
173a51db580SAkihiko Odaki * map data fragment from PCI device and populate it into pkt context.
174a51db580SAkihiko Odaki *
175a51db580SAkihiko Odaki * @pci_dev: PCI device owning fragment
176a51db580SAkihiko Odaki * @pa: physical address of fragment
177a51db580SAkihiko Odaki * @len: length of fragment
178a51db580SAkihiko Odaki */
179a51db580SAkihiko Odaki bool net_tx_pkt_add_raw_fragment_pci(struct NetTxPkt *pkt, PCIDevice *pci_dev,
180a51db580SAkihiko Odaki dma_addr_t pa, size_t len);
181a51db580SAkihiko Odaki
182a51db580SAkihiko Odaki /**
183605d52e6SDmitry Fleytman * Send packet to qemu. handles sw offloads if vhdr is not supported.
184605d52e6SDmitry Fleytman *
185605d52e6SDmitry Fleytman * @pkt: packet
186605d52e6SDmitry Fleytman * @nc: NetClientState
187605d52e6SDmitry Fleytman * @ret: operation result
188605d52e6SDmitry Fleytman *
189605d52e6SDmitry Fleytman */
190605d52e6SDmitry Fleytman bool net_tx_pkt_send(struct NetTxPkt *pkt, NetClientState *nc);
191605d52e6SDmitry Fleytman
192605d52e6SDmitry Fleytman /**
193ffbd2dbdSAkihiko Odaki * Send packet with a custom function.
194eb700029SDmitry Fleytman *
195eb700029SDmitry Fleytman * @pkt: packet
196ffbd2dbdSAkihiko Odaki * @offload: whether the callback implements offloading
197ffbd2dbdSAkihiko Odaki * @callback: a function to be called back for each transformed packet
198ffbd2dbdSAkihiko Odaki * @context: a pointer to be passed to the callback.
199eb700029SDmitry Fleytman * @ret: operation result
200eb700029SDmitry Fleytman */
201ffbd2dbdSAkihiko Odaki bool net_tx_pkt_send_custom(struct NetTxPkt *pkt, bool offload,
202a51db580SAkihiko Odaki NetTxPktSend callback, void *context);
203eb700029SDmitry Fleytman
204eb700029SDmitry Fleytman /**
205605d52e6SDmitry Fleytman * parse raw packet data and analyze offload requirements.
206605d52e6SDmitry Fleytman *
207605d52e6SDmitry Fleytman * @pkt: packet
208605d52e6SDmitry Fleytman *
209605d52e6SDmitry Fleytman */
210605d52e6SDmitry Fleytman bool net_tx_pkt_parse(struct NetTxPkt *pkt);
211605d52e6SDmitry Fleytman
212eb700029SDmitry Fleytman /**
213eb700029SDmitry Fleytman * indicates if there are data fragments held by this packet object.
214eb700029SDmitry Fleytman *
215eb700029SDmitry Fleytman * @pkt: packet
216eb700029SDmitry Fleytman *
217eb700029SDmitry Fleytman */
218eb700029SDmitry Fleytman bool net_tx_pkt_has_fragments(struct NetTxPkt *pkt);
219eb700029SDmitry Fleytman
220e219d309SAndrew /**
221e219d309SAndrew * Fix IPv6 'plen' field.
222e219d309SAndrew * If ipv6 payload length field is 0 - then there should be Hop-by-Hop
223e219d309SAndrew * option for packets greater than 65,535.
224e219d309SAndrew * For packets with a payload less than 65,535: fix 'plen' field.
225e219d309SAndrew * For backends with vheader, we need just one packet with proper
226e219d309SAndrew * payload size. For now, qemu drops every packet with size greater 64K
227e219d309SAndrew * (see net_tx_pkt_send()) so, there is no reason to add jumbo option to ip6
228e219d309SAndrew * hop-by-hop extension if it's missed
229e219d309SAndrew *
230e219d309SAndrew * @pkt packet
231e219d309SAndrew */
232e219d309SAndrew void net_tx_pkt_fix_ip6_payload_len(struct NetTxPkt *pkt);
233e219d309SAndrew
234605d52e6SDmitry Fleytman #endif
235