3939 * Falcon only performs RSS on TCP/UDP packets.
4040 */
4141struct ef4_loopback_payload {
42+ char pad [2 ]; /* Ensures ip is 4-byte aligned */
4243 struct ethhdr header ;
4344 struct iphdr ip ;
4445 struct udphdr udp ;
4546 __be16 iteration ;
4647 char msg [64 ];
47- } __packed ;
48+ } __packed __aligned (4 );
49+ #define EF4_LOOPBACK_PAYLOAD_LEN (sizeof(struct ef4_loopback_payload) - \
50+ offsetof(struct ef4_loopback_payload, \
51+ header))
4852
4953/* Loopback test source MAC address */
5054static const u8 payload_source [ETH_ALEN ] __aligned (2 ) = {
@@ -284,7 +288,7 @@ void ef4_loopback_rx_packet(struct ef4_nic *efx,
284288 const char * buf_ptr , int pkt_len )
285289{
286290 struct ef4_loopback_state * state = efx -> loopback_selftest ;
287- struct ef4_loopback_payload * received ;
291+ struct ef4_loopback_payload received ;
288292 struct ef4_loopback_payload * payload ;
289293
290294 BUG_ON (!buf_ptr );
@@ -295,57 +299,58 @@ void ef4_loopback_rx_packet(struct ef4_nic *efx,
295299
296300 payload = & state -> payload ;
297301
298- received = (struct ef4_loopback_payload * ) buf_ptr ;
299- received -> ip .saddr = payload -> ip .saddr ;
302+ memcpy (& received .header , buf_ptr ,
303+ min_t (int , pkt_len , EF4_LOOPBACK_PAYLOAD_LEN ));
304+ received .ip .saddr = payload -> ip .saddr ;
300305 if (state -> offload_csum )
301- received -> ip .check = payload -> ip .check ;
306+ received . ip .check = payload -> ip .check ;
302307
303308 /* Check that header exists */
304- if (pkt_len < sizeof (received -> header )) {
309+ if (pkt_len < sizeof (received . header )) {
305310 netif_err (efx , drv , efx -> net_dev ,
306311 "saw runt RX packet (length %d) in %s loopback "
307312 "test\n" , pkt_len , LOOPBACK_MODE (efx ));
308313 goto err ;
309314 }
310315
311316 /* Check that the ethernet header exists */
312- if (memcmp (& received -> header , & payload -> header , ETH_HLEN ) != 0 ) {
317+ if (memcmp (& received . header , & payload -> header , ETH_HLEN ) != 0 ) {
313318 netif_err (efx , drv , efx -> net_dev ,
314319 "saw non-loopback RX packet in %s loopback test\n" ,
315320 LOOPBACK_MODE (efx ));
316321 goto err ;
317322 }
318323
319324 /* Check packet length */
320- if (pkt_len != sizeof ( * payload ) ) {
325+ if (pkt_len != EF4_LOOPBACK_PAYLOAD_LEN ) {
321326 netif_err (efx , drv , efx -> net_dev ,
322327 "saw incorrect RX packet length %d (wanted %d) in "
323- "%s loopback test\n" , pkt_len , ( int ) sizeof ( * payload ),
324- LOOPBACK_MODE (efx ));
328+ "%s loopback test\n" , pkt_len ,
329+ ( int ) EF4_LOOPBACK_PAYLOAD_LEN , LOOPBACK_MODE (efx ));
325330 goto err ;
326331 }
327332
328333 /* Check that IP header matches */
329- if (memcmp (& received -> ip , & payload -> ip , sizeof (payload -> ip )) != 0 ) {
334+ if (memcmp (& received . ip , & payload -> ip , sizeof (payload -> ip )) != 0 ) {
330335 netif_err (efx , drv , efx -> net_dev ,
331336 "saw corrupted IP header in %s loopback test\n" ,
332337 LOOPBACK_MODE (efx ));
333338 goto err ;
334339 }
335340
336341 /* Check that msg and padding matches */
337- if (memcmp (& received -> msg , & payload -> msg , sizeof (received -> msg )) != 0 ) {
342+ if (memcmp (& received . msg , & payload -> msg , sizeof (received . msg )) != 0 ) {
338343 netif_err (efx , drv , efx -> net_dev ,
339344 "saw corrupted RX packet in %s loopback test\n" ,
340345 LOOPBACK_MODE (efx ));
341346 goto err ;
342347 }
343348
344349 /* Check that iteration matches */
345- if (received -> iteration != payload -> iteration ) {
350+ if (received . iteration != payload -> iteration ) {
346351 netif_err (efx , drv , efx -> net_dev ,
347352 "saw RX packet from iteration %d (wanted %d) in "
348- "%s loopback test\n" , ntohs (received -> iteration ),
353+ "%s loopback test\n" , ntohs (received . iteration ),
349354 ntohs (payload -> iteration ), LOOPBACK_MODE (efx ));
350355 goto err ;
351356 }
@@ -365,7 +370,8 @@ void ef4_loopback_rx_packet(struct ef4_nic *efx,
365370 buf_ptr , pkt_len , 0 );
366371 netif_err (efx , drv , efx -> net_dev , "expected packet:\n" );
367372 print_hex_dump (KERN_ERR , "" , DUMP_PREFIX_OFFSET , 0x10 , 1 ,
368- & state -> payload , sizeof (state -> payload ), 0 );
373+ & state -> payload .header , EF4_LOOPBACK_PAYLOAD_LEN ,
374+ 0 );
369375 }
370376#endif
371377 atomic_inc (& state -> rx_bad );
@@ -387,14 +393,15 @@ static void ef4_iterate_state(struct ef4_nic *efx)
387393 payload -> ip .daddr = htonl (INADDR_LOOPBACK );
388394 payload -> ip .ihl = 5 ;
389395 payload -> ip .check = (__force __sum16 ) htons (0xdead );
390- payload -> ip .tot_len = htons (sizeof (* payload ) - sizeof (struct ethhdr ));
396+ payload -> ip .tot_len = htons (sizeof (* payload ) -
397+ offsetof(struct ef4_loopback_payload , ip ));
391398 payload -> ip .version = IPVERSION ;
392399 payload -> ip .protocol = IPPROTO_UDP ;
393400
394401 /* Initialise udp header */
395402 payload -> udp .source = 0 ;
396- payload -> udp .len = htons (sizeof (* payload ) - sizeof ( struct ethhdr ) -
397- sizeof (struct iphdr ));
403+ payload -> udp .len = htons (sizeof (* payload ) -
404+ offsetof (struct ef4_loopback_payload , udp ));
398405 payload -> udp .check = 0 ; /* checksum ignored */
399406
400407 /* Fill out payload */
@@ -420,7 +427,7 @@ static int ef4_begin_loopback(struct ef4_tx_queue *tx_queue)
420427 for (i = 0 ; i < state -> packet_count ; i ++ ) {
421428 /* Allocate an skb, holding an extra reference for
422429 * transmit completion counting */
423- skb = alloc_skb (sizeof ( state -> payload ) , GFP_KERNEL );
430+ skb = alloc_skb (EF4_LOOPBACK_PAYLOAD_LEN , GFP_KERNEL );
424431 if (!skb )
425432 return - ENOMEM ;
426433 state -> skbs [i ] = skb ;
@@ -431,6 +438,8 @@ static int ef4_begin_loopback(struct ef4_tx_queue *tx_queue)
431438 payload = skb_put (skb , sizeof (state -> payload ));
432439 memcpy (payload , & state -> payload , sizeof (state -> payload ));
433440 payload -> ip .saddr = htonl (INADDR_LOOPBACK | (i << 2 ));
441+ /* Strip off the leading padding */
442+ skb_pull (skb , offsetof(struct ef4_loopback_payload , header ));
434443
435444 /* Ensure everything we've written is visible to the
436445 * interrupt handler. */
0 commit comments