EN7581 or AN7583 SoCs support connecting multiple external SerDes (e.g.
Ethernet or USB SerDes) to GDM3 or GDM4 ports via a hw arbiter that
manages the traffic in a TDM manner. As a result multiple net_devices can
connect to the same GDM{3,4} port and there is a theoretical "1:n"
relation between GDM ports and net_devices.
┌─────────────────────────────────┐
│ │ ┌──────┐
│ P1 GDM1 ├────►MT7530│
│ │ └──────┘
│ │ ETH0 (DSA conduit)
│ │
│ PSE/FE │
│ │
│ │
│ │ ┌─────┐
│ P0 CDM1 ├────►QDMA0│
│ P4 P9 GDM4 │ └─────┘
└──┬─────────────────────────┬────┘
│ │
┌──▼──┐ ┌────▼────┐
│ PPE │ │ ARB │
└─────┘ └─┬─────┬─┘
│ │
┌──▼──┐┌─▼───┐
│ ETH ││ USB │
└─────┘└─────┘
ETH1 ETH2
This series introduces support for multiple net_devices connected to the
same Frame Engine (FE) GDM port (GDM3 or GDM4) via an external hw
arbiter. Please note GDM1 or GDM2 does not support the connection with
the external arbiter.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://github.com/openwrt/openwrt/pull/23481
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
1013 lines
32 KiB
Diff
1013 lines
32 KiB
Diff
From e15783f7c987e199ecf80b3d858ed5a86d33c508 Mon Sep 17 00:00:00 2001
|
|
Message-ID: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
|
Date: Sat, 1 Nov 2025 11:25:52 +0100
|
|
Subject: [PATCH 01/13] net: airoha: Introduce airoha_gdm_dev struct
|
|
|
|
EN7581 and AN7583 SoCs support connecting multiple external SerDes to GDM3
|
|
or GDM4 ports via a hw arbiter that manages the traffic in a TDM manner.
|
|
As a result multiple net_devices can connect to the same GDM{3,4} port
|
|
and there is a theoretical "1:n" relation between GDM port and
|
|
net_devices.
|
|
Introduce airoha_gdm_dev struct to collect net_device related info (e.g.
|
|
net_device and external phy pointer). Please note this is just a
|
|
preliminary patch and we are still supporting a single net_device for
|
|
each GDM port. Subsequent patches will add support for multiple net_devices
|
|
connected to the same GDM port.
|
|
|
|
Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
|
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
|
---
|
|
drivers/net/ethernet/airoha/airoha_eth.c | 312 ++++++++++++++---------
|
|
drivers/net/ethernet/airoha/airoha_eth.h | 13 +-
|
|
drivers/net/ethernet/airoha/airoha_ppe.c | 17 +-
|
|
3 files changed, 206 insertions(+), 136 deletions(-)
|
|
|
|
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
|
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
|
@@ -727,6 +727,7 @@ static int airoha_qdma_rx_process(struct
|
|
struct airoha_qdma_desc *desc = &q->desc[q->tail];
|
|
u32 hash, reason, msg1, desc_ctrl;
|
|
struct airoha_gdm_port *port;
|
|
+ struct net_device *netdev;
|
|
int data_len, len, p;
|
|
struct page *page;
|
|
|
|
@@ -753,6 +754,10 @@ static int airoha_qdma_rx_process(struct
|
|
goto free_frag;
|
|
|
|
port = eth->ports[p];
|
|
+ if (!port->dev)
|
|
+ goto free_frag;
|
|
+
|
|
+ netdev = port->dev->dev;
|
|
if (!q->skb) { /* first buffer */
|
|
q->skb = napi_build_skb(e->buf - AIROHA_RX_HEADROOM,
|
|
q->buf_size);
|
|
@@ -762,15 +767,15 @@ static int airoha_qdma_rx_process(struct
|
|
skb_reserve(q->skb, AIROHA_RX_HEADROOM);
|
|
__skb_put(q->skb, len);
|
|
skb_mark_for_recycle(q->skb);
|
|
- q->skb->dev = port->dev;
|
|
+ q->skb->dev = netdev;
|
|
q->skb->ip_summed = CHECKSUM_UNNECESSARY;
|
|
skb_record_rx_queue(q->skb, qid);
|
|
|
|
- if (lro_q && (port->dev->features & NETIF_F_LRO) &&
|
|
+ if (lro_q && (netdev->features & NETIF_F_LRO) &&
|
|
airoha_qdma_lro_rx_process(q, desc) < 0)
|
|
goto free_frag;
|
|
|
|
- q->skb->protocol = eth_type_trans(q->skb, port->dev);
|
|
+ q->skb->protocol = eth_type_trans(q->skb, netdev);
|
|
} else { /* scattered frame */
|
|
struct skb_shared_info *shinfo = skb_shinfo(q->skb);
|
|
int nr_frags = shinfo->nr_frags;
|
|
@@ -786,7 +791,7 @@ static int airoha_qdma_rx_process(struct
|
|
if (FIELD_GET(QDMA_DESC_MORE_MASK, desc_ctrl))
|
|
continue;
|
|
|
|
- if (netdev_uses_dsa(port->dev)) {
|
|
+ if (netdev_uses_dsa(netdev)) {
|
|
/* PPE module requires untagged packets to work
|
|
* properly and it provides DSA port index via the
|
|
* DMA descriptor. Report DSA tag to the DSA stack
|
|
@@ -983,6 +988,7 @@ static void airoha_qdma_wake_netdev_txqs
|
|
|
|
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
|
struct airoha_gdm_port *port = eth->ports[i];
|
|
+ struct airoha_gdm_dev *dev;
|
|
int j;
|
|
|
|
if (!port)
|
|
@@ -991,11 +997,12 @@ static void airoha_qdma_wake_netdev_txqs
|
|
if (port->qdma != qdma)
|
|
continue;
|
|
|
|
- for (j = 0; j < port->dev->num_tx_queues; j++) {
|
|
+ dev = port->dev;
|
|
+ for (j = 0; j < dev->dev->num_tx_queues; j++) {
|
|
if (airoha_qdma_get_txq(qdma, j) != qid)
|
|
continue;
|
|
|
|
- netif_wake_subqueue(port->dev, j);
|
|
+ netif_wake_subqueue(dev->dev, j);
|
|
}
|
|
}
|
|
q->txq_stopped = false;
|
|
@@ -1839,33 +1846,34 @@ static void airoha_update_hw_stats(struc
|
|
spin_unlock(&port->stats.lock);
|
|
}
|
|
|
|
-static int airoha_dev_open(struct net_device *dev)
|
|
+static int airoha_dev_open(struct net_device *netdev)
|
|
{
|
|
- int err, len = ETH_HLEN + dev->mtu + ETH_FCS_LEN;
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ int err, len = ETH_HLEN + netdev->mtu + ETH_FCS_LEN;
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
struct airoha_qdma *qdma = port->qdma;
|
|
u32 pse_port = FE_PSE_PORT_PPE1;
|
|
|
|
#if defined(CONFIG_PCS_AIROHA)
|
|
if (airhoa_is_phy_external(port)) {
|
|
- err = phylink_of_phy_connect(port->phylink, dev->dev.of_node, 0);
|
|
+ err = phylink_of_phy_connect(dev->phylink, netdev->dev.of_node, 0);
|
|
if (err) {
|
|
- netdev_err(dev, "%s: could not attach PHY: %d\n", __func__,
|
|
+ netdev_err(netdev, "%s: could not attach PHY: %d\n", __func__,
|
|
err);
|
|
return err;
|
|
}
|
|
|
|
- phylink_start(port->phylink);
|
|
+ phylink_start(dev->phylink);
|
|
}
|
|
#endif
|
|
|
|
- netif_tx_start_all_queues(dev);
|
|
+ netif_tx_start_all_queues(netdev);
|
|
err = airoha_set_vip_for_gdm_port(port, true);
|
|
if (err)
|
|
return err;
|
|
|
|
/* It seems GDM3 and GDM4 needs SPORT enabled to correctly work */
|
|
- if (netdev_uses_dsa(dev) || port->id > 2)
|
|
+ if (netdev_uses_dsa(netdev) || port->id > 2)
|
|
airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
|
|
GDM_STAG_EN_MASK);
|
|
else
|
|
@@ -1893,16 +1901,17 @@ static int airoha_dev_open(struct net_de
|
|
return 0;
|
|
}
|
|
|
|
-static int airoha_dev_stop(struct net_device *dev)
|
|
+static int airoha_dev_stop(struct net_device *netdev)
|
|
{
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
struct airoha_qdma *qdma = port->qdma;
|
|
int i;
|
|
|
|
- netif_tx_disable(dev);
|
|
+ netif_tx_disable(netdev);
|
|
airoha_set_vip_for_gdm_port(port, false);
|
|
- for (i = 0; i < dev->num_tx_queues; i++)
|
|
- netdev_tx_reset_subqueue(dev, i);
|
|
+ for (i = 0; i < netdev->num_tx_queues; i++)
|
|
+ netdev_tx_reset_subqueue(netdev, i);
|
|
|
|
airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
|
|
FE_PSE_PORT_DROP);
|
|
@@ -1922,24 +1931,25 @@ static int airoha_dev_stop(struct net_de
|
|
|
|
#if defined(CONFIG_PCS_AIROHA)
|
|
if (airhoa_is_phy_external(port)) {
|
|
- phylink_stop(port->phylink);
|
|
- phylink_disconnect_phy(port->phylink);
|
|
+ phylink_stop(dev->phylink);
|
|
+ phylink_disconnect_phy(dev->phylink);
|
|
}
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
-static int airoha_dev_set_macaddr(struct net_device *dev, void *p)
|
|
+static int airoha_dev_set_macaddr(struct net_device *netdev, void *p)
|
|
{
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
int err;
|
|
|
|
- err = eth_mac_addr(dev, p);
|
|
+ err = eth_mac_addr(netdev, p);
|
|
if (err)
|
|
return err;
|
|
|
|
- airoha_set_macaddr(port, dev->dev_addr);
|
|
+ airoha_set_macaddr(port, netdev->dev_addr);
|
|
|
|
return 0;
|
|
}
|
|
@@ -2005,16 +2015,17 @@ static int airoha_set_gdm2_loopback(stru
|
|
return 0;
|
|
}
|
|
|
|
-static int airoha_dev_init(struct net_device *dev)
|
|
+static int airoha_dev_init(struct net_device *netdev)
|
|
{
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
- struct airoha_eth *eth = port->eth;
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
+ struct airoha_eth *eth = dev->eth;
|
|
int i;
|
|
|
|
/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
|
|
port->qdma = ð->qdma[!airoha_is_lan_gdm_port(port)];
|
|
- port->dev->irq = port->qdma->irq_banks[0].irq;
|
|
- airoha_set_macaddr(port, dev->dev_addr);
|
|
+ dev->dev->irq = port->qdma->irq_banks[0].irq;
|
|
+ airoha_set_macaddr(port, netdev->dev_addr);
|
|
|
|
switch (port->id) {
|
|
case AIROHA_GDM3_IDX:
|
|
@@ -2039,10 +2050,11 @@ static int airoha_dev_init(struct net_de
|
|
return 0;
|
|
}
|
|
|
|
-static void airoha_dev_get_stats64(struct net_device *dev,
|
|
+static void airoha_dev_get_stats64(struct net_device *netdev,
|
|
struct rtnl_link_stats64 *storage)
|
|
{
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
unsigned int start;
|
|
|
|
airoha_update_hw_stats(port);
|
|
@@ -2061,36 +2073,39 @@ static void airoha_dev_get_stats64(struc
|
|
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
|
|
}
|
|
|
|
-static int airoha_dev_change_mtu(struct net_device *dev, int mtu)
|
|
+static int airoha_dev_change_mtu(struct net_device *netdev, int mtu)
|
|
{
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
struct airoha_eth *eth = port->qdma->eth;
|
|
u32 len = ETH_HLEN + mtu + ETH_FCS_LEN;
|
|
|
|
airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id),
|
|
GDM_LONG_LEN_MASK,
|
|
FIELD_PREP(GDM_LONG_LEN_MASK, len));
|
|
- WRITE_ONCE(dev->mtu, mtu);
|
|
+ WRITE_ONCE(netdev->mtu, mtu);
|
|
|
|
return 0;
|
|
}
|
|
|
|
-static u16 airoha_dev_select_queue(struct net_device *dev, struct sk_buff *skb,
|
|
+static u16 airoha_dev_select_queue(struct net_device *netdev,
|
|
+ struct sk_buff *skb,
|
|
struct net_device *sb_dev)
|
|
{
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
int queue, channel;
|
|
|
|
/* For dsa device select QoS channel according to the dsa user port
|
|
* index, rely on port id otherwise. Select QoS queue based on the
|
|
* skb priority.
|
|
*/
|
|
- channel = netdev_uses_dsa(dev) ? skb_get_queue_mapping(skb) : port->id;
|
|
+ channel = netdev_uses_dsa(netdev) ? skb_get_queue_mapping(skb) : port->id;
|
|
channel = channel % AIROHA_NUM_QOS_CHANNELS;
|
|
queue = (skb->priority - 1) % AIROHA_NUM_QOS_QUEUES; /* QoS queue */
|
|
queue = channel * AIROHA_NUM_QOS_QUEUES + queue;
|
|
|
|
- return queue < dev->num_tx_queues ? queue : 0;
|
|
+ return queue < netdev->num_tx_queues ? queue : 0;
|
|
}
|
|
|
|
static u32 airoha_get_dsa_tag(struct sk_buff *skb, struct net_device *dev)
|
|
@@ -2153,12 +2168,13 @@ int airoha_get_fe_port(struct airoha_gdm
|
|
}
|
|
}
|
|
|
|
-static int airoha_dev_set_features(struct net_device *dev,
|
|
+static int airoha_dev_set_features(struct net_device *netdev,
|
|
netdev_features_t features)
|
|
{
|
|
|
|
- netdev_features_t diff = dev->features ^ features;
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ netdev_features_t diff = netdev->features ^ features;
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
struct airoha_qdma *qdma = port->qdma;
|
|
struct airoha_eth *eth = qdma->eth;
|
|
int qdma_id = qdma - ð->qdma[0];
|
|
@@ -2192,6 +2208,7 @@ static int airoha_dev_set_features(struc
|
|
} else {
|
|
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
|
struct airoha_gdm_port *p = eth->ports[i];
|
|
+ struct airoha_gdm_dev *d;
|
|
|
|
if (!p)
|
|
continue;
|
|
@@ -2199,10 +2216,11 @@ static int airoha_dev_set_features(struc
|
|
if (p->qdma != qdma)
|
|
continue;
|
|
|
|
- if (p->dev == dev)
|
|
+ d = p->dev;
|
|
+ if (d->dev == netdev)
|
|
continue;
|
|
|
|
- if (p->dev->features & NETIF_F_LRO)
|
|
+ if (d->dev->features & NETIF_F_LRO)
|
|
return 0;
|
|
}
|
|
airoha_fe_lro_disable(eth, qdma_id);
|
|
@@ -2212,9 +2230,10 @@ static int airoha_dev_set_features(struc
|
|
}
|
|
|
|
static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
|
|
- struct net_device *dev)
|
|
+ struct net_device *netdev)
|
|
{
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
struct airoha_qdma *qdma = port->qdma;
|
|
u32 nr_frags, tag, msg0, msg1, len;
|
|
struct airoha_queue_entry *e;
|
|
@@ -2227,7 +2246,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
|
u8 fport;
|
|
|
|
qid = airoha_qdma_get_txq(qdma, skb_get_queue_mapping(skb));
|
|
- tag = airoha_get_dsa_tag(skb, dev);
|
|
+ tag = airoha_get_dsa_tag(skb, netdev);
|
|
|
|
msg0 = FIELD_PREP(QDMA_ETH_TXMSG_CHAN_MASK,
|
|
qid / AIROHA_NUM_QOS_QUEUES) |
|
|
@@ -2263,7 +2282,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
|
|
|
spin_lock_bh(&q->lock);
|
|
|
|
- txq = skb_get_tx_queue(dev, skb);
|
|
+ txq = skb_get_tx_queue(netdev, skb);
|
|
nr_frags = 1 + skb_shinfo(skb)->nr_frags;
|
|
|
|
if (q->queued + nr_frags >= q->ndesc) {
|
|
@@ -2287,9 +2306,9 @@ static netdev_tx_t airoha_dev_xmit(struc
|
|
dma_addr_t addr;
|
|
u32 val;
|
|
|
|
- addr = dma_map_single(dev->dev.parent, data, len,
|
|
+ addr = dma_map_single(netdev->dev.parent, data, len,
|
|
DMA_TO_DEVICE);
|
|
- if (unlikely(dma_mapping_error(dev->dev.parent, addr)))
|
|
+ if (unlikely(dma_mapping_error(netdev->dev.parent, addr)))
|
|
goto error_unmap;
|
|
|
|
list_move_tail(&e->list, &tx_list);
|
|
@@ -2338,7 +2357,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
|
|
|
error_unmap:
|
|
list_for_each_entry(e, &tx_list, list) {
|
|
- dma_unmap_single(dev->dev.parent, e->dma_addr, e->dma_len,
|
|
+ dma_unmap_single(netdev->dev.parent, e->dma_addr, e->dma_len,
|
|
DMA_TO_DEVICE);
|
|
e->dma_addr = 0;
|
|
}
|
|
@@ -2347,25 +2366,27 @@ error_unmap:
|
|
spin_unlock_bh(&q->lock);
|
|
error:
|
|
dev_kfree_skb_any(skb);
|
|
- dev->stats.tx_dropped++;
|
|
+ netdev->stats.tx_dropped++;
|
|
|
|
return NETDEV_TX_OK;
|
|
}
|
|
|
|
-static void airoha_ethtool_get_drvinfo(struct net_device *dev,
|
|
+static void airoha_ethtool_get_drvinfo(struct net_device *netdev,
|
|
struct ethtool_drvinfo *info)
|
|
{
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
struct airoha_eth *eth = port->qdma->eth;
|
|
|
|
strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver));
|
|
strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info));
|
|
}
|
|
|
|
-static void airoha_ethtool_get_mac_stats(struct net_device *dev,
|
|
+static void airoha_ethtool_get_mac_stats(struct net_device *netdev,
|
|
struct ethtool_eth_mac_stats *stats)
|
|
{
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
unsigned int start;
|
|
|
|
airoha_update_hw_stats(port);
|
|
@@ -2393,11 +2414,12 @@ static const struct ethtool_rmon_hist_ra
|
|
};
|
|
|
|
static void
|
|
-airoha_ethtool_get_rmon_stats(struct net_device *dev,
|
|
+airoha_ethtool_get_rmon_stats(struct net_device *netdev,
|
|
struct ethtool_rmon_stats *stats,
|
|
const struct ethtool_rmon_hist_range **ranges)
|
|
{
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
struct airoha_hw_stats *hw_stats = &port->stats;
|
|
unsigned int start;
|
|
|
|
@@ -2422,11 +2444,12 @@ airoha_ethtool_get_rmon_stats(struct net
|
|
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
|
|
}
|
|
|
|
-static int airoha_qdma_set_chan_tx_sched(struct net_device *dev,
|
|
+static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
|
|
int channel, enum tx_sched_mode mode,
|
|
const u16 *weights, u8 n_weights)
|
|
{
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
int i;
|
|
|
|
for (i = 0; i < AIROHA_NUM_TX_RING; i++)
|
|
@@ -2511,10 +2534,12 @@ static int airoha_qdma_set_tx_ets_sched(
|
|
ARRAY_SIZE(w));
|
|
}
|
|
|
|
-static int airoha_qdma_get_tx_ets_stats(struct net_device *dev, int channel,
|
|
+static int airoha_qdma_get_tx_ets_stats(struct net_device *netdev, int channel,
|
|
struct tc_ets_qopt_offload *opt)
|
|
{
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
+
|
|
u64 cpu_tx_packets = airoha_qdma_rr(port->qdma,
|
|
REG_CNTR_VAL(channel << 1));
|
|
u64 fwd_tx_packets = airoha_qdma_rr(port->qdma,
|
|
@@ -2776,11 +2801,12 @@ static int airoha_qdma_set_trtcm_token_b
|
|
mode, val);
|
|
}
|
|
|
|
-static int airoha_qdma_set_tx_rate_limit(struct net_device *dev,
|
|
+static int airoha_qdma_set_tx_rate_limit(struct net_device *netdev,
|
|
int channel, u32 rate,
|
|
u32 bucket_size)
|
|
{
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
int i, err;
|
|
|
|
for (i = 0; i <= TRTCM_PEAK_MODE; i++) {
|
|
@@ -2800,20 +2826,22 @@ static int airoha_qdma_set_tx_rate_limit
|
|
return 0;
|
|
}
|
|
|
|
-static int airoha_tc_htb_alloc_leaf_queue(struct net_device *dev,
|
|
+static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
|
|
struct tc_htb_qopt_offload *opt)
|
|
{
|
|
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
|
|
u32 rate = div_u64(opt->rate, 1000) << 3; /* kbps */
|
|
- int err, num_tx_queues = dev->real_num_tx_queues;
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ int err, num_tx_queues = netdev->real_num_tx_queues;
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
|
|
if (opt->parent_classid != TC_HTB_CLASSID_ROOT) {
|
|
NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid");
|
|
return -EINVAL;
|
|
}
|
|
|
|
- err = airoha_qdma_set_tx_rate_limit(dev, channel, rate, opt->quantum);
|
|
+ err = airoha_qdma_set_tx_rate_limit(netdev, channel, rate,
|
|
+ opt->quantum);
|
|
if (err) {
|
|
NL_SET_ERR_MSG_MOD(opt->extack,
|
|
"failed configuring htb offload");
|
|
@@ -2823,9 +2851,10 @@ static int airoha_tc_htb_alloc_leaf_queu
|
|
if (opt->command == TC_HTB_NODE_MODIFY)
|
|
return 0;
|
|
|
|
- err = netif_set_real_num_tx_queues(dev, num_tx_queues + 1);
|
|
+ err = netif_set_real_num_tx_queues(netdev, num_tx_queues + 1);
|
|
if (err) {
|
|
- airoha_qdma_set_tx_rate_limit(dev, channel, 0, opt->quantum);
|
|
+ airoha_qdma_set_tx_rate_limit(netdev, channel, 0,
|
|
+ opt->quantum);
|
|
NL_SET_ERR_MSG_MOD(opt->extack,
|
|
"failed setting real_num_tx_queues");
|
|
return err;
|
|
@@ -2915,11 +2944,12 @@ static int airoha_tc_matchall_act_valida
|
|
return 0;
|
|
}
|
|
|
|
-static int airoha_dev_tc_matchall(struct net_device *dev,
|
|
+static int airoha_dev_tc_matchall(struct net_device *netdev,
|
|
struct tc_cls_matchall_offload *f)
|
|
{
|
|
enum trtcm_unit_type unit_type = TRTCM_BYTE_UNIT;
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
u32 rate = 0, bucket_size = 0;
|
|
|
|
switch (f->command) {
|
|
@@ -2954,18 +2984,19 @@ static int airoha_dev_tc_matchall(struct
|
|
static int airoha_dev_setup_tc_block_cb(enum tc_setup_type type,
|
|
void *type_data, void *cb_priv)
|
|
{
|
|
- struct net_device *dev = cb_priv;
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ struct net_device *netdev = cb_priv;
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
struct airoha_eth *eth = port->qdma->eth;
|
|
|
|
- if (!tc_can_offload(dev))
|
|
+ if (!tc_can_offload(netdev))
|
|
return -EOPNOTSUPP;
|
|
|
|
switch (type) {
|
|
case TC_SETUP_CLSFLOWER:
|
|
return airoha_ppe_setup_tc_block_cb(ð->ppe->dev, type_data);
|
|
case TC_SETUP_CLSMATCHALL:
|
|
- return airoha_dev_tc_matchall(dev, type_data);
|
|
+ return airoha_dev_tc_matchall(netdev, type_data);
|
|
default:
|
|
return -EOPNOTSUPP;
|
|
}
|
|
@@ -3012,47 +3043,51 @@ static int airoha_dev_setup_tc_block(str
|
|
}
|
|
}
|
|
|
|
-static void airoha_tc_remove_htb_queue(struct net_device *dev, int queue)
|
|
+static void airoha_tc_remove_htb_queue(struct net_device *netdev, int queue)
|
|
{
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
|
|
- netif_set_real_num_tx_queues(dev, dev->real_num_tx_queues - 1);
|
|
- airoha_qdma_set_tx_rate_limit(dev, queue + 1, 0, 0);
|
|
+ netif_set_real_num_tx_queues(netdev, netdev->real_num_tx_queues - 1);
|
|
+ airoha_qdma_set_tx_rate_limit(netdev, queue + 1, 0, 0);
|
|
clear_bit(queue, port->qos_sq_bmap);
|
|
}
|
|
|
|
-static int airoha_tc_htb_delete_leaf_queue(struct net_device *dev,
|
|
+static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev,
|
|
struct tc_htb_qopt_offload *opt)
|
|
{
|
|
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
|
|
if (!test_bit(channel, port->qos_sq_bmap)) {
|
|
NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
|
|
return -EINVAL;
|
|
}
|
|
|
|
- airoha_tc_remove_htb_queue(dev, channel);
|
|
+ airoha_tc_remove_htb_queue(netdev, channel);
|
|
|
|
return 0;
|
|
}
|
|
|
|
-static int airoha_tc_htb_destroy(struct net_device *dev)
|
|
+static int airoha_tc_htb_destroy(struct net_device *netdev)
|
|
{
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
int q;
|
|
|
|
for_each_set_bit(q, port->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS)
|
|
- airoha_tc_remove_htb_queue(dev, q);
|
|
+ airoha_tc_remove_htb_queue(netdev, q);
|
|
|
|
return 0;
|
|
}
|
|
|
|
-static int airoha_tc_get_htb_get_leaf_queue(struct net_device *dev,
|
|
+static int airoha_tc_get_htb_get_leaf_queue(struct net_device *netdev,
|
|
struct tc_htb_qopt_offload *opt)
|
|
{
|
|
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
|
|
if (!test_bit(channel, port->qos_sq_bmap)) {
|
|
NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
|
|
@@ -3088,8 +3123,8 @@ static int airoha_tc_setup_qdisc_htb(str
|
|
return 0;
|
|
}
|
|
|
|
-static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type,
|
|
- void *type_data)
|
|
+static int airoha_dev_tc_setup(struct net_device *dev,
|
|
+ enum tc_setup_type type, void *type_data)
|
|
{
|
|
switch (type) {
|
|
case TC_SETUP_QDISC_ETS:
|
|
@@ -3161,13 +3196,18 @@ static void airoha_metadata_dst_free(str
|
|
}
|
|
}
|
|
|
|
-bool airoha_is_valid_gdm_port(struct airoha_eth *eth,
|
|
- struct airoha_gdm_port *port)
|
|
+bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
|
|
+ struct airoha_gdm_dev *dev)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
|
- if (eth->ports[i] == port)
|
|
+ struct airoha_gdm_port *port = eth->ports[i];
|
|
+
|
|
+ if (!port)
|
|
+ continue;
|
|
+
|
|
+ if (port->dev == dev)
|
|
return true;
|
|
}
|
|
|
|
@@ -3179,8 +3219,9 @@ static void airoha_mac_link_up(struct ph
|
|
unsigned int mode, phy_interface_t interface,
|
|
int speed, int duplex, bool tx_pause, bool rx_pause)
|
|
{
|
|
- struct airoha_gdm_port *port = container_of(config, struct airoha_gdm_port,
|
|
- phylink_config);
|
|
+ struct airoha_gdm_dev *dev = container_of(config, struct airoha_gdm_dev,
|
|
+ phylink_config);
|
|
+ struct airoha_gdm_port *port = dev->port;
|
|
struct airoha_qdma *qdma = port->qdma;
|
|
struct airoha_eth *eth = qdma->eth;
|
|
u32 frag_size_tx, frag_size_rx;
|
|
@@ -3236,65 +3277,122 @@ static int airoha_fill_available_pcs(str
|
|
&num_available_pcs);
|
|
}
|
|
|
|
-static int airoha_setup_phylink(struct net_device *dev)
|
|
+static int airoha_setup_phylink(struct net_device *netdev)
|
|
{
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
- struct device_node *np = dev->dev.of_node;
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
+ struct device_node *np = netdev->dev.of_node;
|
|
phy_interface_t phy_mode;
|
|
struct phylink *phylink;
|
|
int err;
|
|
|
|
err = of_get_phy_mode(np, &phy_mode);
|
|
if (err) {
|
|
- dev_err(&dev->dev, "incorrect phy-mode\n");
|
|
+ dev_err(&netdev->dev, "incorrect phy-mode\n");
|
|
return err;
|
|
}
|
|
|
|
- port->phylink_config.dev = &dev->dev;
|
|
- port->phylink_config.type = PHYLINK_NETDEV;
|
|
- port->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
|
|
- MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD |
|
|
- MAC_5000FD | MAC_10000FD;
|
|
+ dev->phylink_config.dev = &netdev->dev;
|
|
+ dev->phylink_config.type = PHYLINK_NETDEV;
|
|
+ dev->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
|
|
+ MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD |
|
|
+ MAC_5000FD | MAC_10000FD;
|
|
|
|
- err = fwnode_phylink_pcs_parse(dev_fwnode(&dev->dev), NULL,
|
|
- &port->phylink_config.num_available_pcs);
|
|
+ err = fwnode_phylink_pcs_parse(dev_fwnode(&netdev->dev), NULL,
|
|
+ &dev->phylink_config.num_available_pcs);
|
|
if (err)
|
|
return err;
|
|
|
|
- port->phylink_config.fill_available_pcs = airoha_fill_available_pcs;
|
|
+ dev->phylink_config.fill_available_pcs = airoha_fill_available_pcs;
|
|
|
|
__set_bit(PHY_INTERFACE_MODE_SGMII,
|
|
- port->phylink_config.supported_interfaces);
|
|
+ dev->phylink_config.supported_interfaces);
|
|
__set_bit(PHY_INTERFACE_MODE_1000BASEX,
|
|
- port->phylink_config.supported_interfaces);
|
|
+ dev->phylink_config.supported_interfaces);
|
|
__set_bit(PHY_INTERFACE_MODE_2500BASEX,
|
|
- port->phylink_config.supported_interfaces);
|
|
+ dev->phylink_config.supported_interfaces);
|
|
__set_bit(PHY_INTERFACE_MODE_10GBASER,
|
|
- port->phylink_config.supported_interfaces);
|
|
+ dev->phylink_config.supported_interfaces);
|
|
__set_bit(PHY_INTERFACE_MODE_USXGMII,
|
|
- port->phylink_config.supported_interfaces);
|
|
+ dev->phylink_config.supported_interfaces);
|
|
|
|
- phy_interface_copy(port->phylink_config.pcs_interfaces,
|
|
- port->phylink_config.supported_interfaces);
|
|
+ phy_interface_copy(dev->phylink_config.pcs_interfaces,
|
|
+ dev->phylink_config.supported_interfaces);
|
|
|
|
- phylink = phylink_create(&port->phylink_config,
|
|
+ phylink = phylink_create(&dev->phylink_config,
|
|
of_fwnode_handle(np),
|
|
phy_mode, &airoha_phylink_ops);
|
|
if (IS_ERR(phylink))
|
|
return PTR_ERR(phylink);
|
|
|
|
- port->phylink = phylink;
|
|
+ dev->phylink = phylink;
|
|
|
|
return err;
|
|
}
|
|
#endif
|
|
|
|
+static int airoha_alloc_gdm_device(struct airoha_eth *eth,
|
|
+ struct airoha_gdm_port *port,
|
|
+ struct device_node *np)
|
|
+{
|
|
+ struct airoha_gdm_dev *dev;
|
|
+ struct net_device *netdev;
|
|
+ int err;
|
|
+
|
|
+ netdev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*dev),
|
|
+ AIROHA_NUM_NETDEV_TX_RINGS,
|
|
+ AIROHA_NUM_RX_RING);
|
|
+ if (!netdev) {
|
|
+ dev_err(eth->dev, "alloc_etherdev failed\n");
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+
|
|
+ netdev->netdev_ops = &airoha_netdev_ops;
|
|
+ netdev->ethtool_ops = &airoha_ethtool_ops;
|
|
+ netdev->max_mtu = AIROHA_MAX_MTU;
|
|
+ netdev->watchdog_timeo = 5 * HZ;
|
|
+ netdev->hw_features = AIROHA_HW_FEATURES | NETIF_F_LRO;
|
|
+ netdev->features |= AIROHA_HW_FEATURES;
|
|
+ netdev->vlan_features = AIROHA_HW_FEATURES;
|
|
+ netdev->dev.of_node = np;
|
|
+ SET_NETDEV_DEV(netdev, eth->dev);
|
|
+
|
|
+ /* reserve hw queues for HTB offloading */
|
|
+ err = netif_set_real_num_tx_queues(netdev, AIROHA_NUM_TX_RING);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
+ err = of_get_ethdev_address(np, netdev);
|
|
+ if (err) {
|
|
+ if (err == -EPROBE_DEFER)
|
|
+ return err;
|
|
+
|
|
+ eth_hw_addr_random(netdev);
|
|
+ dev_info(eth->dev, "generated random MAC address %pM\n",
|
|
+ netdev->dev_addr);
|
|
+ }
|
|
+
|
|
+ dev = netdev_priv(netdev);
|
|
+ dev->dev = netdev;
|
|
+ dev->port = port;
|
|
+ port->dev = dev;
|
|
+ dev->eth = eth;
|
|
+
|
|
+#if defined(CONFIG_PCS_AIROHA)
|
|
+ if (airhoa_is_phy_external(port)) {
|
|
+ err = airoha_setup_phylink(netdev);
|
|
+ if (err)
|
|
+ return err;
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int airoha_alloc_gdm_port(struct airoha_eth *eth,
|
|
struct device_node *np)
|
|
{
|
|
const __be32 *id_ptr = of_get_property(np, "reg", NULL);
|
|
struct airoha_gdm_port *port;
|
|
- struct net_device *dev;
|
|
int err, p;
|
|
u32 id;
|
|
|
|
@@ -3316,58 +3414,22 @@ static int airoha_alloc_gdm_port(struct
|
|
return -EINVAL;
|
|
}
|
|
|
|
- dev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*port),
|
|
- AIROHA_NUM_NETDEV_TX_RINGS,
|
|
- AIROHA_NUM_RX_RING);
|
|
- if (!dev) {
|
|
- dev_err(eth->dev, "alloc_etherdev failed\n");
|
|
+ port = devm_kzalloc(eth->dev, sizeof(*port), GFP_KERNEL);
|
|
+ if (!port)
|
|
return -ENOMEM;
|
|
- }
|
|
-
|
|
- dev->netdev_ops = &airoha_netdev_ops;
|
|
- dev->ethtool_ops = &airoha_ethtool_ops;
|
|
- dev->max_mtu = AIROHA_MAX_MTU;
|
|
- dev->watchdog_timeo = 5 * HZ;
|
|
- dev->hw_features = AIROHA_HW_FEATURES | NETIF_F_LRO;
|
|
- dev->features |= AIROHA_HW_FEATURES;
|
|
- dev->vlan_features = AIROHA_HW_FEATURES;
|
|
- dev->dev.of_node = np;
|
|
- SET_NETDEV_DEV(dev, eth->dev);
|
|
-
|
|
- /* reserve hw queues for HTB offloading */
|
|
- err = netif_set_real_num_tx_queues(dev, AIROHA_NUM_TX_RING);
|
|
- if (err)
|
|
- return err;
|
|
|
|
- err = of_get_ethdev_address(np, dev);
|
|
- if (err) {
|
|
- if (err == -EPROBE_DEFER)
|
|
- return err;
|
|
-
|
|
- eth_hw_addr_random(dev);
|
|
- dev_info(eth->dev, "generated random MAC address %pM\n",
|
|
- dev->dev_addr);
|
|
- }
|
|
-
|
|
- port = netdev_priv(dev);
|
|
u64_stats_init(&port->stats.syncp);
|
|
spin_lock_init(&port->stats.lock);
|
|
- port->eth = eth;
|
|
- port->dev = dev;
|
|
port->id = id;
|
|
/* XXX: Read nbq from DTS */
|
|
port->nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0;
|
|
eth->ports[p] = port;
|
|
|
|
-#if defined(CONFIG_PCS_AIROHA)
|
|
- if (airhoa_is_phy_external(port)) {
|
|
- err = airoha_setup_phylink(dev);
|
|
- if (err)
|
|
- return err;
|
|
- }
|
|
-#endif
|
|
+ err = airoha_metadata_dst_alloc(port);
|
|
+ if (err)
|
|
+ return err;
|
|
|
|
- return airoha_metadata_dst_alloc(port);
|
|
+ return airoha_alloc_gdm_device(eth, port, np);
|
|
}
|
|
|
|
static int airoha_register_gdm_devices(struct airoha_eth *eth)
|
|
@@ -3381,7 +3443,7 @@ static int airoha_register_gdm_devices(s
|
|
if (!port)
|
|
continue;
|
|
|
|
- err = register_netdev(port->dev);
|
|
+ err = register_netdev(port->dev->dev);
|
|
if (err)
|
|
return err;
|
|
}
|
|
@@ -3490,16 +3552,18 @@ error_napi_stop:
|
|
|
|
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
|
struct airoha_gdm_port *port = eth->ports[i];
|
|
+ struct airoha_gdm_dev *dev;
|
|
|
|
if (!port)
|
|
continue;
|
|
|
|
- if (port->dev->reg_state == NETREG_REGISTERED) {
|
|
+ dev = port->dev;
|
|
+ if (dev && dev->dev->reg_state == NETREG_REGISTERED) {
|
|
#if defined(CONFIG_PCS_AIROHA)
|
|
if (airhoa_is_phy_external(port))
|
|
- phylink_destroy(port->phylink);
|
|
+ phylink_destroy(dev->phylink);
|
|
#endif
|
|
- unregister_netdev(port->dev);
|
|
+ unregister_netdev(dev->dev);
|
|
}
|
|
airoha_metadata_dst_free(port);
|
|
}
|
|
@@ -3521,15 +3585,19 @@ static void airoha_remove(struct platfor
|
|
|
|
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
|
struct airoha_gdm_port *port = eth->ports[i];
|
|
+ struct airoha_gdm_dev *dev;
|
|
|
|
if (!port)
|
|
continue;
|
|
|
|
#if defined(CONFIG_PCS_AIROHA)
|
|
if (airhoa_is_phy_external(port))
|
|
- phylink_destroy(port->phylink);
|
|
+ phylink_destroy(dev->phylink);
|
|
#endif
|
|
- unregister_netdev(port->dev);
|
|
+
|
|
+ dev = port->dev;
|
|
+ if (dev)
|
|
+ unregister_netdev(dev->dev);
|
|
airoha_metadata_dst_free(port);
|
|
}
|
|
airoha_hw_cleanup(eth);
|
|
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
|
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
|
@@ -546,17 +546,22 @@ struct airoha_qdma {
|
|
struct airoha_queue q_rx[AIROHA_NUM_RX_RING];
|
|
};
|
|
|
|
-struct airoha_gdm_port {
|
|
- struct airoha_qdma *qdma;
|
|
- struct airoha_eth *eth;
|
|
+struct airoha_gdm_dev {
|
|
+ struct airoha_gdm_port *port;
|
|
struct net_device *dev;
|
|
- int id;
|
|
- int nbq;
|
|
+ struct airoha_eth *eth;
|
|
|
|
#if defined(CONFIG_PCS_AIROHA)
|
|
struct phylink *phylink;
|
|
struct phylink_config phylink_config;
|
|
#endif
|
|
+};
|
|
+
|
|
+struct airoha_gdm_port {
|
|
+ struct airoha_qdma *qdma;
|
|
+ struct airoha_gdm_dev *dev;
|
|
+ int id;
|
|
+ int nbq;
|
|
|
|
struct airoha_hw_stats stats;
|
|
|
|
@@ -690,8 +695,8 @@ static inline bool airoha_qdma_is_lro_qu
|
|
}
|
|
|
|
int airoha_get_fe_port(struct airoha_gdm_port *port);
|
|
-bool airoha_is_valid_gdm_port(struct airoha_eth *eth,
|
|
- struct airoha_gdm_port *port);
|
|
+bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
|
|
+ struct airoha_gdm_dev *dev);
|
|
|
|
void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id,
|
|
u8 fport);
|
|
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
|
|
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
|
|
@@ -297,12 +297,12 @@ static void airoha_ppe_foe_set_bridge_ad
|
|
|
|
static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
|
|
struct airoha_foe_entry *hwe,
|
|
- struct net_device *dev, int type,
|
|
+ struct net_device *netdev, int type,
|
|
struct airoha_flow_data *data,
|
|
int l4proto, u8 dsfield)
|
|
{
|
|
u32 qdata = FIELD_PREP(AIROHA_FOE_SHAPER_ID, 0x7f), ports_pad, val;
|
|
- int wlan_etype = -EINVAL, dsa_port = airoha_get_dsa_port(&dev);
|
|
+ int wlan_etype = -EINVAL, dsa_port = airoha_get_dsa_port(&netdev);
|
|
struct airoha_foe_mac_info_common *l2;
|
|
u8 smac_id = 0xf;
|
|
|
|
@@ -318,10 +318,11 @@ static int airoha_ppe_foe_entry_prepare(
|
|
hwe->ib1 = val;
|
|
|
|
val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f);
|
|
- if (dev) {
|
|
+ if (netdev) {
|
|
struct airoha_wdma_info info = {};
|
|
|
|
- if (!airoha_ppe_get_wdma_info(dev, data->eth.h_dest, &info)) {
|
|
+ if (!airoha_ppe_get_wdma_info(netdev, data->eth.h_dest,
|
|
+ &info)) {
|
|
val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, info.idx) |
|
|
FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT,
|
|
FE_PSE_PORT_CDM4);
|
|
@@ -331,12 +332,14 @@ static int airoha_ppe_foe_entry_prepare(
|
|
FIELD_PREP(AIROHA_FOE_MAC_WDMA_WCID,
|
|
info.wcid);
|
|
} else {
|
|
- struct airoha_gdm_port *port = netdev_priv(dev);
|
|
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
|
u8 pse_port, channel, priority;
|
|
+ struct airoha_gdm_port *port;
|
|
|
|
- if (!airoha_is_valid_gdm_port(eth, port))
|
|
+ if (!airoha_is_valid_gdm_dev(eth, dev))
|
|
return -EINVAL;
|
|
|
|
+ port = dev->port;
|
|
if (dsa_port >= 0 || eth->ports[1])
|
|
pse_port = port->id == 4 ? FE_PSE_PORT_GDM4
|
|
: port->id;
|
|
@@ -1483,7 +1486,7 @@ void airoha_ppe_check_skb(struct airoha_
|
|
void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port)
|
|
{
|
|
struct airoha_eth *eth = port->qdma->eth;
|
|
- struct net_device *dev = port->dev;
|
|
+ struct net_device *dev = port->dev->dev;
|
|
const u8 *addr = dev->dev_addr;
|
|
u32 val;
|
|
|