Skip to content

Commit 3125fc1

Browse files
tmshlvckkuba-moo
authored andcommitted
net: spacemit: k1-emac: fix jumbo frame support
The driver never programs the MAC frame size and jabber registers, causing the hardware to reject frames larger than the default 1518 bytes even when larger DMA buffers are allocated. Program MAC_MAXIMUM_FRAME_SIZE, MAC_TRANSMIT_JABBER_SIZE, and MAC_RECEIVE_JABBER_SIZE based on the configured MTU. Also fix the maximum buffer size from 4096 to 4095, since the descriptor buffer size field is only 12 bits. Account for double VLAN tags in frame size calculations. Fixes: bfec6d7 ("net: spacemit: Add K1 Ethernet MAC") Cc: [email protected] Signed-off-by: Tomas Hlavacek <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 79987ce commit 3125fc1

1 file changed

Lines changed: 15 additions & 6 deletions

File tree

drivers/net/ethernet/spacemit/k1_emac.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/dma-mapping.h>
1313
#include <linux/etherdevice.h>
1414
#include <linux/ethtool.h>
15+
#include <linux/if_vlan.h>
1516
#include <linux/interrupt.h>
1617
#include <linux/io.h>
1718
#include <linux/iopoll.h>
@@ -38,7 +39,7 @@
3839

3940
#define EMAC_DEFAULT_BUFSIZE 1536
4041
#define EMAC_RX_BUF_2K 2048
41-
#define EMAC_RX_BUF_4K 4096
42+
#define EMAC_RX_BUF_MAX FIELD_MAX(RX_DESC_1_BUFFER_SIZE_1_MASK)
4243

4344
/* Tuning parameters from SpacemiT */
4445
#define EMAC_TX_FRAMES 64
@@ -202,8 +203,7 @@ static void emac_init_hw(struct emac_priv *priv)
202203
{
203204
/* Destination address for 802.3x Ethernet flow control */
204205
u8 fc_dest_addr[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x01 };
205-
206-
u32 rxirq = 0, dma = 0;
206+
u32 rxirq = 0, dma = 0, frame_sz;
207207

208208
regmap_set_bits(priv->regmap_apmu,
209209
priv->regmap_apmu_offset + APMU_EMAC_CTRL_REG,
@@ -228,6 +228,15 @@ static void emac_init_hw(struct emac_priv *priv)
228228
DEFAULT_TX_THRESHOLD);
229229
emac_wr(priv, MAC_RECEIVE_PACKET_START_THRESHOLD, DEFAULT_RX_THRESHOLD);
230230

231+
/* Set maximum frame size and jabber size based on configured MTU,
232+
* accounting for Ethernet header, double VLAN tags, and FCS.
233+
*/
234+
frame_sz = priv->ndev->mtu + ETH_HLEN + 2 * VLAN_HLEN + ETH_FCS_LEN;
235+
236+
emac_wr(priv, MAC_MAXIMUM_FRAME_SIZE, frame_sz);
237+
emac_wr(priv, MAC_TRANSMIT_JABBER_SIZE, frame_sz);
238+
emac_wr(priv, MAC_RECEIVE_JABBER_SIZE, frame_sz);
239+
231240
/* Configure flow control (enabled in emac_adjust_link() later) */
232241
emac_set_mac_addr_reg(priv, fc_dest_addr, MAC_FC_SOURCE_ADDRESS_HIGH);
233242
emac_wr(priv, MAC_FC_PAUSE_HIGH_THRESHOLD, DEFAULT_FC_FIFO_HIGH);
@@ -924,14 +933,14 @@ static int emac_change_mtu(struct net_device *ndev, int mtu)
924933
return -EBUSY;
925934
}
926935

927-
frame_len = mtu + ETH_HLEN + ETH_FCS_LEN;
936+
frame_len = mtu + ETH_HLEN + 2 * VLAN_HLEN + ETH_FCS_LEN;
928937

929938
if (frame_len <= EMAC_DEFAULT_BUFSIZE)
930939
priv->dma_buf_sz = EMAC_DEFAULT_BUFSIZE;
931940
else if (frame_len <= EMAC_RX_BUF_2K)
932941
priv->dma_buf_sz = EMAC_RX_BUF_2K;
933942
else
934-
priv->dma_buf_sz = EMAC_RX_BUF_4K;
943+
priv->dma_buf_sz = EMAC_RX_BUF_MAX;
935944

936945
ndev->mtu = mtu;
937946

@@ -2025,7 +2034,7 @@ static int emac_probe(struct platform_device *pdev)
20252034
ndev->hw_features = NETIF_F_SG;
20262035
ndev->features |= ndev->hw_features;
20272036

2028-
ndev->max_mtu = EMAC_RX_BUF_4K - (ETH_HLEN + ETH_FCS_LEN);
2037+
ndev->max_mtu = EMAC_RX_BUF_MAX - (ETH_HLEN + 2 * VLAN_HLEN + ETH_FCS_LEN);
20292038
ndev->pcpu_stat_type = NETDEV_PCPU_STAT_DSTATS;
20302039

20312040
priv = netdev_priv(ndev);

0 commit comments

Comments
 (0)