Commit 19b3bb51 authored by Geoff Levand's avatar Geoff Levand Committed by David S. Miller
Browse files

net/ps3_gelic_net: Fix RX sk_buff length



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>
parent 7d722c98
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -365,26 +365,27 @@ 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 */
		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;
@@ -397,7 +398,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);
@@ -915,7 +916,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