xref: /openbmc/qemu/hw/net/net_tx_pkt.h (revision 6eece7f5)
1 /*
2  * QEMU TX packets abstraction
3  *
4  * Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com)
5  *
6  * Developed by Daynix Computing LTD (http://www.daynix.com)
7  *
8  * Authors:
9  * Dmitry Fleytman <dmitry@daynix.com>
10  * Tamir Shomer <tamirs@daynix.com>
11  * Yan Vugenfirer <yan@daynix.com>
12  *
13  * This work is licensed under the terms of the GNU GPL, version 2 or later.
14  * See the COPYING file in the top-level directory.
15  *
16  */
17 
18 #ifndef NET_TX_PKT_H
19 #define NET_TX_PKT_H
20 
21 #include "net/eth.h"
22 #include "exec/hwaddr.h"
23 
24 /* define to enable packet dump functions */
25 /*#define NET_TX_PKT_DEBUG*/
26 
27 struct NetTxPkt;
28 
29 typedef void (* NetTxPktCallback)(void *, const struct iovec *, int, const struct iovec *, int);
30 
31 /**
32  * Init function for tx packet functionality
33  *
34  * @pkt:            packet pointer
35  * @pci_dev:        PCI device processing this packet
36  * @max_frags:      max tx ip fragments
37  */
38 void net_tx_pkt_init(struct NetTxPkt **pkt, PCIDevice *pci_dev,
39     uint32_t max_frags);
40 
41 /**
42  * Clean all tx packet resources.
43  *
44  * @pkt:            packet.
45  */
46 void net_tx_pkt_uninit(struct NetTxPkt *pkt);
47 
48 /**
49  * get virtio header
50  *
51  * @pkt:            packet
52  * @ret:            virtio header
53  */
54 struct virtio_net_hdr *net_tx_pkt_get_vhdr(struct NetTxPkt *pkt);
55 
56 /**
57  * build virtio header (will be stored in module context)
58  *
59  * @pkt:            packet
60  * @tso_enable:     TSO enabled
61  * @csum_enable:    CSO enabled
62  * @gso_size:       MSS size for TSO
63  * @ret:            operation result
64  *
65  */
66 bool net_tx_pkt_build_vheader(struct NetTxPkt *pkt, bool tso_enable,
67     bool csum_enable, uint32_t gso_size);
68 
69 /**
70 * updates vlan tag, and adds vlan header with custom ethernet type
71 * in case it is missing.
72 *
73 * @pkt:            packet
74 * @vlan:           VLAN tag
75 * @vlan_ethtype:   VLAN header Ethernet type
76 *
77 */
78 void net_tx_pkt_setup_vlan_header_ex(struct NetTxPkt *pkt,
79     uint16_t vlan, uint16_t vlan_ethtype);
80 
81 /**
82 * updates vlan tag, and adds vlan header in case it is missing
83 *
84 * @pkt:            packet
85 * @vlan:           VLAN tag
86 *
87 */
88 static inline void
89 net_tx_pkt_setup_vlan_header(struct NetTxPkt *pkt, uint16_t vlan)
90 {
91     net_tx_pkt_setup_vlan_header_ex(pkt, vlan, ETH_P_VLAN);
92 }
93 
94 /**
95  * populate data fragment into pkt context.
96  *
97  * @pkt:            packet
98  * @pa:             physical address of fragment
99  * @len:            length of fragment
100  *
101  */
102 bool net_tx_pkt_add_raw_fragment(struct NetTxPkt *pkt, hwaddr pa,
103     size_t len);
104 
105 /**
106  * Fix ip header fields and calculate IP header and pseudo header checksums.
107  *
108  * @pkt:            packet
109  *
110  */
111 void net_tx_pkt_update_ip_checksums(struct NetTxPkt *pkt);
112 
113 /**
114  * Calculate the IP header checksum.
115  *
116  * @pkt:            packet
117  *
118  */
119 void net_tx_pkt_update_ip_hdr_checksum(struct NetTxPkt *pkt);
120 
121 /**
122  * get length of all populated data.
123  *
124  * @pkt:            packet
125  * @ret:            total data length
126  *
127  */
128 size_t net_tx_pkt_get_total_len(struct NetTxPkt *pkt);
129 
130 /**
131  * get packet type
132  *
133  * @pkt:            packet
134  * @ret:            packet type
135  *
136  */
137 eth_pkt_types_e net_tx_pkt_get_packet_type(struct NetTxPkt *pkt);
138 
139 /**
140  * prints packet data if debug is enabled
141  *
142  * @pkt:            packet
143  *
144  */
145 void net_tx_pkt_dump(struct NetTxPkt *pkt);
146 
147 /**
148  * reset tx packet private context (needed to be called between packets)
149  *
150  * @pkt:            packet
151  * @dev:            PCI device processing the next packet
152  *
153  */
154 void net_tx_pkt_reset(struct NetTxPkt *pkt, PCIDevice *dev);
155 
156 /**
157  * Send packet to qemu. handles sw offloads if vhdr is not supported.
158  *
159  * @pkt:            packet
160  * @nc:             NetClientState
161  * @ret:            operation result
162  *
163  */
164 bool net_tx_pkt_send(struct NetTxPkt *pkt, NetClientState *nc);
165 
166 /**
167  * Send packet with a custom function.
168  *
169  * @pkt:            packet
170  * @offload:        whether the callback implements offloading
171  * @callback:       a function to be called back for each transformed packet
172  * @context:        a pointer to be passed to the callback.
173  * @ret:            operation result
174  */
175 bool net_tx_pkt_send_custom(struct NetTxPkt *pkt, bool offload,
176                             NetTxPktCallback callback, void *context);
177 
178 /**
179  * parse raw packet data and analyze offload requirements.
180  *
181  * @pkt:            packet
182  *
183  */
184 bool net_tx_pkt_parse(struct NetTxPkt *pkt);
185 
186 /**
187 * indicates if there are data fragments held by this packet object.
188 *
189 * @pkt:            packet
190 *
191 */
192 bool net_tx_pkt_has_fragments(struct NetTxPkt *pkt);
193 
194 /**
195  * Fix IPv6 'plen' field.
196  * If ipv6 payload length field is 0 - then there should be Hop-by-Hop
197  * option for packets greater than 65,535.
198  * For packets with a payload less than 65,535: fix 'plen' field.
199  * For backends with vheader, we need just one packet with proper
200  * payload size. For now, qemu drops every packet with size greater 64K
201  * (see net_tx_pkt_send()) so, there is no reason to add jumbo option to ip6
202  * hop-by-hop extension if it's missed
203  *
204  * @pkt            packet
205  */
206 void net_tx_pkt_fix_ip6_payload_len(struct NetTxPkt *pkt);
207 
208 #endif
209