4242 * Falcon only performs RSS on TCP/UDP packets.
4343 */
4444struct efx_loopback_payload {
45+ char pad [2 ]; /* Ensures ip is 4-byte aligned */
4546 struct ethhdr header ;
4647 struct iphdr ip ;
4748 struct udphdr udp ;
4849 __be16 iteration ;
4950 char msg [64 ];
50- } __packed ;
51+ } __packed __aligned (4 );
52+ #define EFX_LOOPBACK_PAYLOAD_LEN (sizeof(struct efx_loopback_payload) - \
53+ offsetof(struct efx_loopback_payload, \
54+ header))
5155
5256/* Loopback test source MAC address */
5357static const u8 payload_source [ETH_ALEN ] __aligned (2 ) = {
@@ -282,7 +286,7 @@ void efx_siena_loopback_rx_packet(struct efx_nic *efx,
282286 const char * buf_ptr , int pkt_len )
283287{
284288 struct efx_loopback_state * state = efx -> loopback_selftest ;
285- struct efx_loopback_payload * received ;
289+ struct efx_loopback_payload received ;
286290 struct efx_loopback_payload * payload ;
287291
288292 BUG_ON (!buf_ptr );
@@ -293,57 +297,58 @@ void efx_siena_loopback_rx_packet(struct efx_nic *efx,
293297
294298 payload = & state -> payload ;
295299
296- received = (struct efx_loopback_payload * ) buf_ptr ;
297- received -> ip .saddr = payload -> ip .saddr ;
300+ memcpy (& received .header , buf_ptr ,
301+ min_t (int , pkt_len , EFX_LOOPBACK_PAYLOAD_LEN ));
302+ received .ip .saddr = payload -> ip .saddr ;
298303 if (state -> offload_csum )
299- received -> ip .check = payload -> ip .check ;
304+ received . ip .check = payload -> ip .check ;
300305
301306 /* Check that header exists */
302- if (pkt_len < sizeof (received -> header )) {
307+ if (pkt_len < sizeof (received . header )) {
303308 netif_err (efx , drv , efx -> net_dev ,
304309 "saw runt RX packet (length %d) in %s loopback "
305310 "test\n" , pkt_len , LOOPBACK_MODE (efx ));
306311 goto err ;
307312 }
308313
309314 /* Check that the ethernet header exists */
310- if (memcmp (& received -> header , & payload -> header , ETH_HLEN ) != 0 ) {
315+ if (memcmp (& received . header , & payload -> header , ETH_HLEN ) != 0 ) {
311316 netif_err (efx , drv , efx -> net_dev ,
312317 "saw non-loopback RX packet in %s loopback test\n" ,
313318 LOOPBACK_MODE (efx ));
314319 goto err ;
315320 }
316321
317322 /* Check packet length */
318- if (pkt_len != sizeof ( * payload ) ) {
323+ if (pkt_len != EFX_LOOPBACK_PAYLOAD_LEN ) {
319324 netif_err (efx , drv , efx -> net_dev ,
320325 "saw incorrect RX packet length %d (wanted %d) in "
321- "%s loopback test\n" , pkt_len , ( int ) sizeof ( * payload ),
322- LOOPBACK_MODE (efx ));
326+ "%s loopback test\n" , pkt_len ,
327+ ( int ) EFX_LOOPBACK_PAYLOAD_LEN , LOOPBACK_MODE (efx ));
323328 goto err ;
324329 }
325330
326331 /* Check that IP header matches */
327- if (memcmp (& received -> ip , & payload -> ip , sizeof (payload -> ip )) != 0 ) {
332+ if (memcmp (& received . ip , & payload -> ip , sizeof (payload -> ip )) != 0 ) {
328333 netif_err (efx , drv , efx -> net_dev ,
329334 "saw corrupted IP header in %s loopback test\n" ,
330335 LOOPBACK_MODE (efx ));
331336 goto err ;
332337 }
333338
334339 /* Check that msg and padding matches */
335- if (memcmp (& received -> msg , & payload -> msg , sizeof (received -> msg )) != 0 ) {
340+ if (memcmp (& received . msg , & payload -> msg , sizeof (received . msg )) != 0 ) {
336341 netif_err (efx , drv , efx -> net_dev ,
337342 "saw corrupted RX packet in %s loopback test\n" ,
338343 LOOPBACK_MODE (efx ));
339344 goto err ;
340345 }
341346
342347 /* Check that iteration matches */
343- if (received -> iteration != payload -> iteration ) {
348+ if (received . iteration != payload -> iteration ) {
344349 netif_err (efx , drv , efx -> net_dev ,
345350 "saw RX packet from iteration %d (wanted %d) in "
346- "%s loopback test\n" , ntohs (received -> iteration ),
351+ "%s loopback test\n" , ntohs (received . iteration ),
347352 ntohs (payload -> iteration ), LOOPBACK_MODE (efx ));
348353 goto err ;
349354 }
@@ -363,7 +368,8 @@ void efx_siena_loopback_rx_packet(struct efx_nic *efx,
363368 buf_ptr , pkt_len , 0 );
364369 netif_err (efx , drv , efx -> net_dev , "expected packet:\n" );
365370 print_hex_dump (KERN_ERR , "" , DUMP_PREFIX_OFFSET , 0x10 , 1 ,
366- & state -> payload , sizeof (state -> payload ), 0 );
371+ & state -> payload .header , EFX_LOOPBACK_PAYLOAD_LEN ,
372+ 0 );
367373 }
368374#endif
369375 atomic_inc (& state -> rx_bad );
@@ -385,14 +391,15 @@ static void efx_iterate_state(struct efx_nic *efx)
385391 payload -> ip .daddr = htonl (INADDR_LOOPBACK );
386392 payload -> ip .ihl = 5 ;
387393 payload -> ip .check = (__force __sum16 ) htons (0xdead );
388- payload -> ip .tot_len = htons (sizeof (* payload ) - sizeof (struct ethhdr ));
394+ payload -> ip .tot_len = htons (sizeof (* payload ) -
395+ offsetof(struct efx_loopback_payload , ip ));
389396 payload -> ip .version = IPVERSION ;
390397 payload -> ip .protocol = IPPROTO_UDP ;
391398
392399 /* Initialise udp header */
393400 payload -> udp .source = 0 ;
394- payload -> udp .len = htons (sizeof (* payload ) - sizeof ( struct ethhdr ) -
395- sizeof (struct iphdr ));
401+ payload -> udp .len = htons (sizeof (* payload ) -
402+ offsetof (struct efx_loopback_payload , udp ));
396403 payload -> udp .check = 0 ; /* checksum ignored */
397404
398405 /* Fill out payload */
@@ -418,7 +425,7 @@ static int efx_begin_loopback(struct efx_tx_queue *tx_queue)
418425 for (i = 0 ; i < state -> packet_count ; i ++ ) {
419426 /* Allocate an skb, holding an extra reference for
420427 * transmit completion counting */
421- skb = alloc_skb (sizeof ( state -> payload ) , GFP_KERNEL );
428+ skb = alloc_skb (EFX_LOOPBACK_PAYLOAD_LEN , GFP_KERNEL );
422429 if (!skb )
423430 return - ENOMEM ;
424431 state -> skbs [i ] = skb ;
@@ -429,6 +436,8 @@ static int efx_begin_loopback(struct efx_tx_queue *tx_queue)
429436 payload = skb_put (skb , sizeof (state -> payload ));
430437 memcpy (payload , & state -> payload , sizeof (state -> payload ));
431438 payload -> ip .saddr = htonl (INADDR_LOOPBACK | (i << 2 ));
439+ /* Strip off the leading padding */
440+ skb_pull (skb , offsetof(struct efx_loopback_payload , header ));
432441
433442 /* Ensure everything we've written is visible to the
434443 * interrupt handler. */
0 commit comments