Skip to content

Commit d930655

Browse files
ozbenhdavem330
authored andcommitted
ftgmac100: Work around HW bug in runt frame detection
The HW incorrectly calculates the frame size without the vlan tag and compares that against 64. It will thus flag 64-bytes frames with a vlan tag as 60-bytes frames "runt" packets which we'll then drop. Thus we end up dropping ARP packets on vlan's ... It does that whether vlan tag stripping is enabled or not. This works around it by ignoring the "runt" error bit of the frame has been vlan tagged and is at least 60 bytes. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 4ca2415 commit d930655

File tree

1 file changed

+25
-10
lines changed

1 file changed

+25
-10
lines changed

drivers/net/ethernet/faraday/ftgmac100.c

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
350350
struct ftgmac100_rxdes *rxdes;
351351
struct sk_buff *skb;
352352
unsigned int pointer, size;
353-
u32 status;
353+
u32 status, csum_vlan;
354354
dma_addr_t map;
355355

356356
/* Grab next RX descriptor */
@@ -372,10 +372,27 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
372372
!(status & FTGMAC100_RXDES0_LRS)))
373373
goto drop;
374374

375+
/* Grab received size and csum vlan field in the descriptor */
376+
size = status & FTGMAC100_RXDES0_VDBC;
377+
csum_vlan = le32_to_cpu(rxdes->rxdes1);
378+
375379
/* Any error (other than csum offload) flagged ? */
376380
if (unlikely(status & RXDES0_ANY_ERROR)) {
377-
ftgmac100_rx_packet_error(priv, status);
378-
goto drop;
381+
/* Correct for incorrect flagging of runt packets
382+
* with vlan tags... Just accept a runt packet that
383+
* has been flagged as vlan and whose size is at
384+
* least 60 bytes.
385+
*/
386+
if ((status & FTGMAC100_RXDES0_RUNT) &&
387+
(csum_vlan & FTGMAC100_RXDES1_VLANTAG_AVAIL) &&
388+
(size >= 60))
389+
status &= ~FTGMAC100_RXDES0_RUNT;
390+
391+
/* Any error still in there ? */
392+
if (status & RXDES0_ANY_ERROR) {
393+
ftgmac100_rx_packet_error(priv, status);
394+
goto drop;
395+
}
379396
}
380397

381398
/* If the packet had no skb (failed to allocate earlier)
@@ -397,19 +414,17 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
397414
* we accept the HW test results.
398415
*/
399416
if (netdev->features & NETIF_F_RXCSUM) {
400-
__le32 csum_vlan = rxdes->rxdes1;
401-
__le32 err_bits = cpu_to_le32(FTGMAC100_RXDES1_TCP_CHKSUM_ERR |
402-
FTGMAC100_RXDES1_UDP_CHKSUM_ERR |
403-
FTGMAC100_RXDES1_IP_CHKSUM_ERR);
417+
u32 err_bits = FTGMAC100_RXDES1_TCP_CHKSUM_ERR |
418+
FTGMAC100_RXDES1_UDP_CHKSUM_ERR |
419+
FTGMAC100_RXDES1_IP_CHKSUM_ERR;
404420
if ((csum_vlan & err_bits) ||
405-
!(csum_vlan & cpu_to_le32(FTGMAC100_RXDES1_PROT_MASK)))
421+
!(csum_vlan & FTGMAC100_RXDES1_PROT_MASK))
406422
skb->ip_summed = CHECKSUM_NONE;
407423
else
408424
skb->ip_summed = CHECKSUM_UNNECESSARY;
409425
}
410426

411-
/* Grab received size annd transfer to skb */
412-
size = status & FTGMAC100_RXDES0_VDBC;
427+
/* Transfer received size to skb */
413428
skb_put(skb, size);
414429

415430
/* Tear down DMA mapping, do necessary cache management */

0 commit comments

Comments
 (0)