Skip to content

Commit 37c8489

Browse files
saprojkuba-moo
authored andcommitted
net: ftmac100: allow increasing MTU to make most use of single-segment buffers
If the FTMAC100 is used as a DSA master, then it is expected that frames which are MTU sized on the wire facing the external switch port (1500 octets in L2 payload, plus L2 header) also get a DSA tag when seen by the host port. This extra tag increases the length of the packet as the host port sees it, and the FTMAC100 is not prepared to handle frames whose length exceeds 1518 octets (including FCS) at all. Only a minimal rework is needed to support this configuration. Since MTU-sized DSA-tagged frames still fit within a single buffer (RX_BUF_SIZE), we just need to optimize the resource management rather than implement multi buffer RX. In ndo_change_mtu(), we toggle the FTMAC100_MACCR_RX_FTL bit to tell the hardware to drop (or not) frames with an L2 payload length larger than 1500. We need to replicate the MACCR configuration in ftmac100_start_hw() as well, since there is a hardware reset there which clears previous settings. The advantage of dynamically changing FTMAC100_MACCR_RX_FTL is that when dev->mtu is at the default value of 1500, large frames are automatically dropped in hardware and we do not spend CPU cycles dropping them. Suggested-by: Vladimir Oltean <[email protected]> Signed-off-by: Sergei Antonov <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 30f837b commit 37c8489

File tree

1 file changed

+31
-2
lines changed

1 file changed

+31
-2
lines changed

drivers/net/ethernet/faraday/ftmac100.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/dma-mapping.h>
1212
#include <linux/etherdevice.h>
1313
#include <linux/ethtool.h>
14+
#include <linux/if_ether.h>
1415
#include <linux/if_vlan.h>
1516
#include <linux/init.h>
1617
#include <linux/interrupt.h>
@@ -28,8 +29,8 @@
2829
#define RX_QUEUE_ENTRIES 128 /* must be power of 2 */
2930
#define TX_QUEUE_ENTRIES 16 /* must be power of 2 */
3031

31-
#define MAX_PKT_SIZE 1518
3232
#define RX_BUF_SIZE 2044 /* must be smaller than 0x7ff */
33+
#define MAX_PKT_SIZE RX_BUF_SIZE /* multi-segment not supported */
3334

3435
#if MAX_PKT_SIZE > 0x7ff
3536
#error invalid MAX_PKT_SIZE
@@ -160,6 +161,7 @@ static void ftmac100_set_mac(struct ftmac100 *priv, const unsigned char *mac)
160161
static int ftmac100_start_hw(struct ftmac100 *priv)
161162
{
162163
struct net_device *netdev = priv->netdev;
164+
unsigned int maccr = MACCR_ENABLE_ALL;
163165

164166
if (ftmac100_reset(priv))
165167
return -EIO;
@@ -176,7 +178,11 @@ static int ftmac100_start_hw(struct ftmac100 *priv)
176178

177179
ftmac100_set_mac(priv, netdev->dev_addr);
178180

179-
iowrite32(MACCR_ENABLE_ALL, priv->base + FTMAC100_OFFSET_MACCR);
181+
/* See ftmac100_change_mtu() */
182+
if (netdev->mtu > ETH_DATA_LEN)
183+
maccr |= FTMAC100_MACCR_RX_FTL;
184+
185+
iowrite32(maccr, priv->base + FTMAC100_OFFSET_MACCR);
180186
return 0;
181187
}
182188

@@ -1033,13 +1039,36 @@ static int ftmac100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int c
10331039
return generic_mii_ioctl(&priv->mii, data, cmd, NULL);
10341040
}
10351041

1042+
static int ftmac100_change_mtu(struct net_device *netdev, int mtu)
1043+
{
1044+
struct ftmac100 *priv = netdev_priv(netdev);
1045+
unsigned int maccr;
1046+
1047+
maccr = ioread32(priv->base + FTMAC100_OFFSET_MACCR);
1048+
if (mtu > ETH_DATA_LEN) {
1049+
/* process long packets in the driver */
1050+
maccr |= FTMAC100_MACCR_RX_FTL;
1051+
} else {
1052+
/* Let the controller drop incoming packets greater
1053+
* than 1518 (that is 1500 + 14 Ethernet + 4 FCS).
1054+
*/
1055+
maccr &= ~FTMAC100_MACCR_RX_FTL;
1056+
}
1057+
iowrite32(maccr, priv->base + FTMAC100_OFFSET_MACCR);
1058+
1059+
netdev->mtu = mtu;
1060+
1061+
return 0;
1062+
}
1063+
10361064
static const struct net_device_ops ftmac100_netdev_ops = {
10371065
.ndo_open = ftmac100_open,
10381066
.ndo_stop = ftmac100_stop,
10391067
.ndo_start_xmit = ftmac100_hard_start_xmit,
10401068
.ndo_set_mac_address = eth_mac_addr,
10411069
.ndo_validate_addr = eth_validate_addr,
10421070
.ndo_eth_ioctl = ftmac100_do_ioctl,
1071+
.ndo_change_mtu = ftmac100_change_mtu,
10431072
};
10441073

10451074
/******************************************************************************

0 commit comments

Comments
 (0)