Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6d7e18b1 authored by Geoff Levand's avatar Geoff Levand Committed by Greg Kroah-Hartman
Browse files

net/ps3_gelic_net: Fix RX sk_buff length



[ Upstream commit 19b3bb51c3bc288b3f2c6f8c4450b0f548320625 ]

The Gelic Ethernet device needs to have the RX sk_buffs aligned to
GELIC_NET_RXBUF_ALIGN, and also the length of the RX sk_buffs must
be a multiple of GELIC_NET_RXBUF_ALIGN.

The current Gelic Ethernet driver was not allocating sk_buffs large
enough to allow for this alignment.

Also, correct the maximum and minimum MTU sizes, and add a new
preprocessor macro for the maximum frame size, GELIC_NET_MAX_FRAME.

Fixes various randomly occurring runtime network errors.

Fixes: 02c18891 ("ps3: gigabit ethernet driver for PS3, take3")
Signed-off-by: default avatarGeoff Levand <geoff@infradead.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 0e5c7d00
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -365,28 +365,29 @@ static int gelic_card_init_chain(struct gelic_card *card,
 *
 * allocates a new rx skb, iommu-maps it and attaches it to the descriptor.
 * Activate the descriptor state-wise
 *
 * Gelic RX sk_buffs must be aligned to GELIC_NET_RXBUF_ALIGN and the length
 * must be a multiple of GELIC_NET_RXBUF_ALIGN.
 */
static int gelic_descr_prepare_rx(struct gelic_card *card,
				  struct gelic_descr *descr)
{
	static const unsigned int rx_skb_size =
		ALIGN(GELIC_NET_MAX_FRAME, GELIC_NET_RXBUF_ALIGN) +
		GELIC_NET_RXBUF_ALIGN - 1;
	int offset;
	unsigned int bufsize;

	if (gelic_descr_get_status(descr) !=  GELIC_DESCR_DMA_NOT_IN_USE)
		dev_info(ctodev(card), "%s: ERROR status\n", __func__);
	/* we need to round up the buffer size to a multiple of 128 */
	bufsize = ALIGN(GELIC_NET_MAX_MTU, GELIC_NET_RXBUF_ALIGN);

	/* and we need to have it 128 byte aligned, therefore we allocate a
	 * bit more */
	descr->skb = dev_alloc_skb(bufsize + GELIC_NET_RXBUF_ALIGN - 1);
	descr->skb = netdev_alloc_skb(*card->netdev, rx_skb_size);
	if (!descr->skb) {
		descr->buf_addr = 0; /* tell DMAC don't touch memory */
		dev_info(ctodev(card),
			 "%s:allocate skb failed !!\n", __func__);
		return -ENOMEM;
	}
	descr->buf_size = cpu_to_be32(bufsize);
	descr->buf_size = cpu_to_be32(rx_skb_size);
	descr->dmac_cmd_status = 0;
	descr->result_size = 0;
	descr->valid_size = 0;
@@ -399,7 +400,7 @@ static int gelic_descr_prepare_rx(struct gelic_card *card,
	/* io-mmu-map the skb */
	descr->buf_addr = cpu_to_be32(dma_map_single(ctodev(card),
						     descr->skb->data,
						     GELIC_NET_MAX_MTU,
						     GELIC_NET_MAX_FRAME,
						     DMA_FROM_DEVICE));
	if (!descr->buf_addr) {
		dev_kfree_skb_any(descr->skb);
@@ -917,7 +918,7 @@ static void gelic_net_pass_skb_up(struct gelic_descr *descr,
	data_error = be32_to_cpu(descr->data_error);
	/* unmap skb buffer */
	dma_unmap_single(ctodev(card), be32_to_cpu(descr->buf_addr),
			 GELIC_NET_MAX_MTU,
			 GELIC_NET_MAX_FRAME,
			 DMA_FROM_DEVICE);

	skb_put(skb, be32_to_cpu(descr->valid_size)?
+3 −2
Original line number Diff line number Diff line
@@ -19,8 +19,9 @@
#define GELIC_NET_RX_DESCRIPTORS        128 /* num of descriptors */
#define GELIC_NET_TX_DESCRIPTORS        128 /* num of descriptors */

#define GELIC_NET_MAX_MTU               VLAN_ETH_FRAME_LEN
#define GELIC_NET_MIN_MTU               VLAN_ETH_ZLEN
#define GELIC_NET_MAX_FRAME             2312
#define GELIC_NET_MAX_MTU               2294
#define GELIC_NET_MIN_MTU               64
#define GELIC_NET_RXBUF_ALIGN           128
#define GELIC_CARD_RX_CSUM_DEFAULT      1 /* hw chksum */
#define GELIC_NET_WATCHDOG_TIMEOUT      5*HZ