 eb700029c7
			
		
	
	
		eb700029c7
		
	
	
	
	
		
			
			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 <dmitry.fleytman@ravellosystems.com> Signed-off-by: Leonid Bloch <leonid.bloch@ravellosystems.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Jason Wang <jasowang@redhat.com>
		
			
				
	
	
		
			101 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  *  IP checksumming functions.
 | |
|  *  (c) 2008 Gerd Hoffmann <kraxel@redhat.com>
 | |
|  *
 | |
|  *  This program is free software; you can redistribute it and/or modify
 | |
|  *  it under the terms of the GNU General Public License as published by
 | |
|  *  the Free Software Foundation; under version 2 of the License.
 | |
|  *
 | |
|  *  This program is distributed in the hope that it will be useful,
 | |
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|  *  GNU General Public License for more details.
 | |
|  *
 | |
|  *  You should have received a copy of the GNU General Public License
 | |
|  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 | |
|  */
 | |
| 
 | |
| #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);
 | |
| uint16_t net_checksum_finish(uint32_t sum);
 | |
| uint16_t net_checksum_tcpudp(uint16_t length, uint16_t proto,
 | |
|                              uint8_t *addrs, uint8_t *buf);
 | |
| void net_checksum_calculate(uint8_t *data, int length);
 | |
| 
 | |
| static inline uint32_t
 | |
| net_checksum_add(int len, uint8_t *buf)
 | |
| {
 | |
|     return net_checksum_add_cont(len, buf, 0);
 | |
| }
 | |
| 
 | |
| static inline uint16_t
 | |
| net_raw_checksum(uint8_t *data, int length)
 | |
| {
 | |
|     return net_checksum_finish(net_checksum_add(length, data));
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * net_checksum_add_iov: scatter-gather vector checksumming
 | |
|  *
 | |
|  * @iov: input scatter-gather array
 | |
|  * @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 csum_offset);
 | |
| 
 | |
| 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 */
 |