History

net: ethernet: mtk_eth_soc: initialize PPE per-tag-layer MTU registers

The PPE enforces output frame size limits via per-tag-layer VLAN_MTU registers that the driver never initializes. The hardware defaults do not account for PPPoE overhead, causing the PPE to punt encapsulated frames back to the CPU instead of forwarding them. Initialize the registers at PPE start and on MTU changes using the maximum GMAC MTU. This is a conservative approximation -- the actual per-PPE requirement depends on egress path, but using the global maximum ensures the limits are never too small.

Daniel Golle committed 7 months ago

Commit 2dddb341 parent 5e700c73 files · +52 −1Browse files

Unified · Split

3 files
  1. drivers/net/ethernet/mediatek/mtk_eth_soc.c +21 −1
  2. drivers/net/ethernet/mediatek/mtk_ppe.c +30 −0
  3. drivers/net/ethernet/mediatek/mtk_ppe.h +1 −0
drivers/net/ethernet/mediatek/mtk_eth_soc.c+21−1
@@ -3566,12 +3566,23 @@ found: · 3565 unmodified lines
3566 return NOTIFY_DONE;3566 return NOTIFY_DONE;
3567}3567}
3568 3568
3569static int mtk_max_gmac_mtu(struct mtk_eth *eth)
3570{
3571 int i, max_mtu = ETH_DATA_LEN;
3572
3573 for (i = 0; i < ARRAY_SIZE(eth->netdev); i++)
3574 if (eth->netdev[i] && eth->netdev[i]->mtu > max_mtu)
3575 max_mtu = eth->netdev[i]->mtu;
3576
3577 return max_mtu;
3578}
3579
3569static int mtk_open(struct net_device *dev)3580static int mtk_open(struct net_device *dev)
3570{3581{
3571 struct mtk_mac *mac = netdev_priv(dev);3582 struct mtk_mac *mac = netdev_priv(dev);
3572 struct mtk_eth *eth = mac->hw;3583 struct mtk_eth *eth = mac->hw;
3573 struct mtk_mac *target_mac;3584 struct mtk_mac *target_mac;
3574 int i, err, ppe_num;3585 int i, err, ppe_num, mtu;
3575 3586
3576 ppe_num = eth->soc->ppe_num;3587 ppe_num = eth->soc->ppe_num;
3577 3588
@@ -3618,6 +3629,10 @@ static int mtk_open(struct net_device *dev) · 40 unmodified lines
3618 mtk_gdm_config(eth, target_mac->id, gdm_config);3629 mtk_gdm_config(eth, target_mac->id, gdm_config);
3619 }3630 }
3620 3631
3632 mtu = mtk_max_gmac_mtu(eth);
3633 for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
3634 mtk_ppe_update_mtu(eth->ppe[i], mtu);
3635
3621 napi_enable(&eth->tx_napi);3636 napi_enable(&eth->tx_napi);
3622 napi_enable(&eth->rx_napi);3637 napi_enable(&eth->rx_napi);
3623 mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);3638 mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
@@ -4311,6 +4326,7 @@ static int mtk_change_mtu(struct net_device *dev, int new_mtu) · 687 unmodified lines
4311 int length = new_mtu + MTK_RX_ETH_HLEN;4326 int length = new_mtu + MTK_RX_ETH_HLEN;
4312 struct mtk_mac *mac = netdev_priv(dev);4327 struct mtk_mac *mac = netdev_priv(dev);
4313 struct mtk_eth *eth = mac->hw;4328 struct mtk_eth *eth = mac->hw;
4329 int max_mtu, i;
4314 4330
4315 if (rcu_access_pointer(eth->prog) &&4331 if (rcu_access_pointer(eth->prog) &&
4316 length > MTK_PP_MAX_BUF_SIZE) {4332 length > MTK_PP_MAX_BUF_SIZE) {
@@ -4321,6 +4337,10 @@ static int mtk_change_mtu(struct net_device *dev, int new_mtu) · 4 unmodified lines
4321 mtk_set_mcr_max_rx(mac, length);4337 mtk_set_mcr_max_rx(mac, length);
4322 WRITE_ONCE(dev->mtu, new_mtu);4338 WRITE_ONCE(dev->mtu, new_mtu);
4323 4339
4340 max_mtu = mtk_max_gmac_mtu(eth);
4341 for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
4342 mtk_ppe_update_mtu(eth->ppe[i], max_mtu);
4343
4324 return 0;4344 return 0;
4325}4345}
4326 4346
drivers/net/ethernet/mediatek/mtk_ppe.c+30−0
@@ -973,6 +973,36 @@ static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe) · 972 unmodified lines
973 }973 }
974}974}
975 975
976void mtk_ppe_update_mtu(struct mtk_ppe *ppe, int mtu)
977{
978 int base;
979 u32 val;
980
981 if (!ppe)
982 return;
983
984 /* The PPE checks output frame size against per-tag-layer MTU limits,
985 * treating PPPoE and DSA tags just like 802.1Q VLAN tags. The Linux
986 * device MTU already accounts for PPPoE (PPPOE_SES_HLEN) and DSA tag
987 * overhead, but 802.1Q VLAN tags are handled transparently without
988 * being reflected by the lower device MTU being increased by 4.
989 * Use the maximum MTU across all GMAC interfaces so that PPE output
990 * frame limits are sufficiently high regardless of which port a flow
991 * egresses through.
992 */
993 base = ETH_HLEN + mtu;
994
995 val = FIELD_PREP(MTK_PPE_VLAN_MTU0_NONE, base) |
996 FIELD_PREP(MTK_PPE_VLAN_MTU0_1TAG, base + VLAN_HLEN);
997 ppe_w32(ppe, MTK_PPE_VLAN_MTU0, val);
998
999 val = FIELD_PREP(MTK_PPE_VLAN_MTU1_2TAG,
1000 base + 2 * VLAN_HLEN) |
1001 FIELD_PREP(MTK_PPE_VLAN_MTU1_3TAG,
1002 base + 3 * VLAN_HLEN);
1003 ppe_w32(ppe, MTK_PPE_VLAN_MTU1, val);
1004}
1005
976void mtk_ppe_start(struct mtk_ppe *ppe)1006void mtk_ppe_start(struct mtk_ppe *ppe)
977{1007{
978 u32 val;1008 u32 val;
drivers/net/ethernet/mediatek/mtk_ppe.h+1−0
@@ -346,6 +346,7 @@ struct mtk_ppe { · 345 unmodified lines
346struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index);346struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index);
347 347
348void mtk_ppe_deinit(struct mtk_eth *eth);348void mtk_ppe_deinit(struct mtk_eth *eth);
349void mtk_ppe_update_mtu(struct mtk_ppe *ppe, int mtu);
349void mtk_ppe_start(struct mtk_ppe *ppe);350void mtk_ppe_start(struct mtk_ppe *ppe);
350int mtk_ppe_stop(struct mtk_ppe *ppe);351int mtk_ppe_stop(struct mtk_ppe *ppe);
351int mtk_ppe_prepare_reset(struct mtk_ppe *ppe);352int mtk_ppe_prepare_reset(struct mtk_ppe *ppe);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t