]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: airoha: Move airoha_qdma pointer in airoha_gdm_dev struct
authorLorenzo Bianconi <lorenzo@kernel.org>
Wed, 27 May 2026 10:21:16 +0000 (12:21 +0200)
committerJakub Kicinski <kuba@kernel.org>
Tue, 2 Jun 2026 20:24:25 +0000 (13:24 -0700)
Move airoha_qdma pointer from airoha_gdm_port struct to airoha_gdm_dev
one since the QDMA block used depends on the particular net_device
WAN/LAN configuration and in the current codebase net_device pointer is
associated to airoha_gdm_dev struct.
This is a preliminary patch to support multiple net_devices connected
to the same GDM{3,4} port via an external hw arbiter.

Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260527-airoha-eth-multi-serdes-preliminary-v1-2-ec6ed73ef7fc@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/airoha/airoha_eth.c
drivers/net/ethernet/airoha/airoha_eth.h
drivers/net/ethernet/airoha/airoha_ppe.c

index b2684af2db764289af9ade30e026364cfa4c8c25..0f37d26e4d52e8fdb6a627cac9c74a1ace43362c 100644 (file)
@@ -71,9 +71,10 @@ static void airoha_qdma_irq_disable(struct airoha_irq_bank *irq_bank,
        airoha_qdma_set_irqmask(irq_bank, index, mask, 0);
 }
 
-static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
+static void airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr)
 {
-       struct airoha_eth *eth = port->qdma->eth;
+       struct airoha_gdm_port *port = dev->port;
+       struct airoha_eth *eth = dev->eth;
        u32 val, reg;
 
        reg = airoha_is_lan_gdm_port(port) ? REG_FE_LAN_MAC_H
@@ -85,7 +86,7 @@ static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
        airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), val);
        airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), val);
 
-       airoha_ppe_init_upd_mem(port);
+       airoha_ppe_init_upd_mem(dev);
 }
 
 static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr,
@@ -101,10 +102,10 @@ static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr,
                      FIELD_PREP(GDM_UCFQ_MASK, val));
 }
 
-static int airoha_set_vip_for_gdm_port(struct airoha_gdm_port *port,
-                                      bool enable)
+static int airoha_set_vip_for_gdm_port(struct airoha_gdm_dev *dev, bool enable)
 {
-       struct airoha_eth *eth = port->qdma->eth;
+       struct airoha_gdm_port *port = dev->port;
+       struct airoha_eth *eth = dev->eth;
        u32 vip_port;
 
        vip_port = eth->soc->ops.get_vip_port(port, port->nbq);
@@ -859,10 +860,13 @@ static void airoha_qdma_wake_netdev_txqs(struct airoha_queue *q)
                if (!port)
                        continue;
 
-               if (port->qdma != qdma)
+               dev = port->dev;
+               if (!dev)
+                       continue;
+
+               if (dev->qdma != qdma)
                        continue;
 
-               dev = port->dev;
                for (j = 0; j < dev->dev->num_tx_queues; j++) {
                        if (airoha_qdma_get_txq(qdma, j) != qid)
                                continue;
@@ -1563,9 +1567,10 @@ static void airoha_qdma_stop_napi(struct airoha_qdma *qdma)
        }
 }
 
-static void airoha_update_hw_stats(struct airoha_gdm_port *port)
+static void airoha_update_hw_stats(struct airoha_gdm_dev *dev)
 {
-       struct airoha_eth *eth = port->qdma->eth;
+       struct airoha_gdm_port *port = dev->port;
+       struct airoha_eth *eth = dev->eth;
        u32 val, i = 0;
 
        spin_lock(&port->stats.lock);
@@ -1712,11 +1717,11 @@ static int airoha_dev_open(struct net_device *netdev)
        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;
+       struct airoha_qdma *qdma = dev->qdma;
        u32 pse_port = FE_PSE_PORT_PPE1;
 
        netif_tx_start_all_queues(netdev);
-       err = airoha_set_vip_for_gdm_port(port, true);
+       err = airoha_set_vip_for_gdm_port(dev, true);
        if (err)
                return err;
 
@@ -1752,11 +1757,11 @@ static int airoha_dev_stop(struct net_device *netdev)
 {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
        struct airoha_gdm_port *port = dev->port;
-       struct airoha_qdma *qdma = port->qdma;
+       struct airoha_qdma *qdma = dev->qdma;
        int i;
 
        netif_tx_disable(netdev);
-       airoha_set_vip_for_gdm_port(port, false);
+       airoha_set_vip_for_gdm_port(dev, false);
        for (i = 0; i < netdev->num_tx_queues; i++)
                netdev_tx_reset_subqueue(netdev, i);
 
@@ -1782,21 +1787,21 @@ static int airoha_dev_stop(struct net_device *netdev)
 static int airoha_dev_set_macaddr(struct net_device *netdev, void *p)
 {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
-       struct airoha_gdm_port *port = dev->port;
        int err;
 
        err = eth_mac_addr(netdev, p);
        if (err)
                return err;
 
-       airoha_set_macaddr(port, netdev->dev_addr);
+       airoha_set_macaddr(dev, netdev->dev_addr);
 
        return 0;
 }
 
-static int airoha_set_gdm2_loopback(struct airoha_gdm_port *port)
+static int airoha_set_gdm2_loopback(struct airoha_gdm_dev *dev)
 {
-       struct airoha_eth *eth = port->qdma->eth;
+       struct airoha_gdm_port *port = dev->port;
+       struct airoha_eth *eth = dev->eth;
        u32 val, pse_port, chan;
        int i, src_port;
 
@@ -1843,7 +1848,7 @@ static int airoha_set_gdm2_loopback(struct airoha_gdm_port *port)
                      __field_prep(SP_CPORT_MASK(val), FE_PSE_PORT_CDM2));
 
        for (i = 0; i < eth->soc->num_ppe; i++)
-               airoha_ppe_set_cpu_port(port, i, AIROHA_GDM2_IDX);
+               airoha_ppe_set_cpu_port(dev, i, AIROHA_GDM2_IDX);
 
        if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth)) {
                u32 mask = FC_ID_OF_SRC_PORT_MASK(port->nbq);
@@ -1863,9 +1868,9 @@ static int airoha_dev_init(struct net_device *netdev)
        int i;
 
        /* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
-       port->qdma = &eth->qdma[!airoha_is_lan_gdm_port(port)];
-       dev->dev->irq = port->qdma->irq_banks[0].irq;
-       airoha_set_macaddr(port, netdev->dev_addr);
+       dev->qdma = &eth->qdma[!airoha_is_lan_gdm_port(port)];
+       dev->dev->irq = dev->qdma->irq_banks[0].irq;
+       airoha_set_macaddr(dev, netdev->dev_addr);
 
        switch (port->id) {
        case AIROHA_GDM3_IDX:
@@ -1874,7 +1879,7 @@ static int airoha_dev_init(struct net_device *netdev)
                if (!eth->ports[1]) {
                        int err;
 
-                       err = airoha_set_gdm2_loopback(port);
+                       err = airoha_set_gdm2_loopback(dev);
                        if (err)
                                return err;
                }
@@ -1884,8 +1889,7 @@ static int airoha_dev_init(struct net_device *netdev)
        }
 
        for (i = 0; i < eth->soc->num_ppe; i++)
-               airoha_ppe_set_cpu_port(port, i,
-                                       airoha_get_fe_port(port));
+               airoha_ppe_set_cpu_port(dev, i, airoha_get_fe_port(dev));
 
        return 0;
 }
@@ -1897,7 +1901,7 @@ static void airoha_dev_get_stats64(struct net_device *netdev,
        struct airoha_gdm_port *port = dev->port;
        unsigned int start;
 
-       airoha_update_hw_stats(port);
+       airoha_update_hw_stats(dev);
        do {
                start = u64_stats_fetch_begin(&port->stats.syncp);
                storage->rx_packets = port->stats.rx_ok_pkts;
@@ -1917,8 +1921,8 @@ static int airoha_dev_change_mtu(struct net_device *netdev, int mtu)
 {
        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;
+       struct airoha_eth *eth = dev->eth;
 
        airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id),
                      GDM_LONG_LEN_MASK,
@@ -1992,10 +1996,10 @@ static u32 airoha_get_dsa_tag(struct sk_buff *skb, struct net_device *dev)
 #endif
 }
 
-int airoha_get_fe_port(struct airoha_gdm_port *port)
+int airoha_get_fe_port(struct airoha_gdm_dev *dev)
 {
-       struct airoha_qdma *qdma = port->qdma;
-       struct airoha_eth *eth = qdma->eth;
+       struct airoha_gdm_port *port = dev->port;
+       struct airoha_eth *eth = dev->eth;
 
        switch (eth->soc->version) {
        case 0x7583:
@@ -2012,8 +2016,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
                                   struct net_device *netdev)
 {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
-       struct airoha_gdm_port *port = dev->port;
-       struct airoha_qdma *qdma = port->qdma;
+       struct airoha_qdma *qdma = dev->qdma;
        u32 nr_frags, tag, msg0, msg1, len;
        struct airoha_queue_entry *e;
        struct netdev_queue *txq;
@@ -2051,7 +2054,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
                }
        }
 
-       fport = airoha_get_fe_port(port);
+       fport = airoha_get_fe_port(dev);
        msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
               FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f);
 
@@ -2154,8 +2157,7 @@ static void airoha_ethtool_get_drvinfo(struct net_device *netdev,
                                       struct ethtool_drvinfo *info)
 {
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
-       struct airoha_gdm_port *port = dev->port;
-       struct airoha_eth *eth = port->qdma->eth;
+       struct airoha_eth *eth = dev->eth;
 
        strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver));
        strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info));
@@ -2168,7 +2170,7 @@ static void airoha_ethtool_get_mac_stats(struct net_device *netdev,
        struct airoha_gdm_port *port = dev->port;
        unsigned int start;
 
-       airoha_update_hw_stats(port);
+       airoha_update_hw_stats(dev);
        do {
                start = u64_stats_fetch_begin(&port->stats.syncp);
                stats->FramesTransmittedOK = port->stats.tx_ok_pkts;
@@ -2208,7 +2210,7 @@ airoha_ethtool_get_rmon_stats(struct net_device *netdev,
                     ARRAY_SIZE(hw_stats->rx_len) + 1);
 
        *ranges = airoha_ethtool_rmon_ranges;
-       airoha_update_hw_stats(port);
+       airoha_update_hw_stats(dev);
        do {
                int i;
 
@@ -2228,18 +2230,17 @@ static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
                                         const u16 *weights, u8 n_weights)
 {
        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++)
-               airoha_qdma_clear(port->qdma, REG_QUEUE_CLOSE_CFG(channel),
+               airoha_qdma_clear(dev->qdma, REG_QUEUE_CLOSE_CFG(channel),
                                  TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i));
 
        for (i = 0; i < n_weights; i++) {
                u32 status;
                int err;
 
-               airoha_qdma_wr(port->qdma, REG_TXWRR_WEIGHT_CFG,
+               airoha_qdma_wr(dev->qdma, REG_TXWRR_WEIGHT_CFG,
                               TWRR_RW_CMD_MASK |
                               FIELD_PREP(TWRR_CHAN_IDX_MASK, channel) |
                               FIELD_PREP(TWRR_QUEUE_IDX_MASK, i) |
@@ -2247,13 +2248,12 @@ static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
                err = read_poll_timeout(airoha_qdma_rr, status,
                                        status & TWRR_RW_CMD_DONE,
                                        USEC_PER_MSEC, 10 * USEC_PER_MSEC,
-                                       true, port->qdma,
-                                       REG_TXWRR_WEIGHT_CFG);
+                                       true, dev->qdma, REG_TXWRR_WEIGHT_CFG);
                if (err)
                        return err;
        }
 
-       airoha_qdma_rmw(port->qdma, REG_CHAN_QOS_MODE(channel >> 3),
+       airoha_qdma_rmw(dev->qdma, REG_CHAN_QOS_MODE(channel >> 3),
                        CHAN_QOS_MODE_MASK(channel),
                        __field_prep(CHAN_QOS_MODE_MASK(channel), mode));
 
@@ -2319,9 +2319,9 @@ static int airoha_qdma_get_tx_ets_stats(struct net_device *netdev, int channel,
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
        struct airoha_gdm_port *port = dev->port;
 
-       u64 cpu_tx_packets = airoha_qdma_rr(port->qdma,
+       u64 cpu_tx_packets = airoha_qdma_rr(dev->qdma,
                                            REG_CNTR_VAL(channel << 1));
-       u64 fwd_tx_packets = airoha_qdma_rr(port->qdma,
+       u64 fwd_tx_packets = airoha_qdma_rr(dev->qdma,
                                            REG_CNTR_VAL((channel << 1) + 1));
        u64 tx_packets = (cpu_tx_packets - port->cpu_tx_packets) +
                         (fwd_tx_packets - port->fwd_tx_packets);
@@ -2585,17 +2585,16 @@ static int airoha_qdma_set_tx_rate_limit(struct net_device *netdev,
                                         u32 bucket_size)
 {
        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++) {
-               err = airoha_qdma_set_trtcm_config(port->qdma, channel,
+               err = airoha_qdma_set_trtcm_config(dev->qdma, channel,
                                                   REG_EGRESS_TRTCM_CFG, i,
                                                   !!rate, TRTCM_METER_MODE);
                if (err)
                        return err;
 
-               err = airoha_qdma_set_trtcm_token_bucket(port->qdma, channel,
+               err = airoha_qdma_set_trtcm_token_bucket(dev->qdma, channel,
                                                         REG_EGRESS_TRTCM_CFG,
                                                         i, rate, bucket_size);
                if (err)
@@ -2645,11 +2644,11 @@ static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
        return 0;
 }
 
-static int airoha_qdma_set_rx_meter(struct airoha_gdm_port *port,
+static int airoha_qdma_set_rx_meter(struct airoha_gdm_dev *dev,
                                    u32 rate, u32 bucket_size,
                                    enum trtcm_unit_type unit_type)
 {
-       struct airoha_qdma *qdma = port->qdma;
+       struct airoha_qdma *qdma = dev->qdma;
        int i;
 
        for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
@@ -2728,7 +2727,6 @@ static int airoha_dev_tc_matchall(struct net_device *netdev,
 {
        enum trtcm_unit_type unit_type = TRTCM_BYTE_UNIT;
        struct airoha_gdm_dev *dev = netdev_priv(netdev);
-       struct airoha_gdm_port *port = dev->port;
        u32 rate = 0, bucket_size = 0;
 
        switch (f->command) {
@@ -2753,7 +2751,7 @@ static int airoha_dev_tc_matchall(struct net_device *netdev,
                fallthrough;
        }
        case TC_CLSMATCHALL_DESTROY:
-               return airoha_qdma_set_rx_meter(port, rate, bucket_size,
+               return airoha_qdma_set_rx_meter(dev, rate, bucket_size,
                                                unit_type);
        default:
                return -EOPNOTSUPP;
@@ -2765,8 +2763,7 @@ static int airoha_dev_setup_tc_block_cb(enum tc_setup_type type,
 {
        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;
+       struct airoha_eth *eth = dev->eth;
 
        if (!tc_can_offload(netdev))
                return -EOPNOTSUPP;
index c78cabbec753872ad9d729ed5d38a9433afea1f6..f1eea492217c03345bab4d59b3441bde29ec80c9 100644 (file)
@@ -537,12 +537,12 @@ struct airoha_qdma {
 
 struct airoha_gdm_dev {
        struct airoha_gdm_port *port;
+       struct airoha_qdma *qdma;
        struct net_device *dev;
        struct airoha_eth *eth;
 };
 
 struct airoha_gdm_port {
-       struct airoha_qdma *qdma;
        struct airoha_gdm_dev *dev;
        int id;
        int nbq;
@@ -666,19 +666,18 @@ static inline bool airoha_is_7583(struct airoha_eth *eth)
        return eth->soc->version == 0x7583;
 }
 
-int airoha_get_fe_port(struct airoha_gdm_port *port);
+int airoha_get_fe_port(struct airoha_gdm_dev *dev);
 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);
+void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport);
 bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index);
 void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,
                          u16 hash, bool rx_wlan);
 int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data);
 int airoha_ppe_init(struct airoha_eth *eth);
 void airoha_ppe_deinit(struct airoha_eth *eth);
-void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port);
+void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev);
 u32 airoha_ppe_get_total_num_entries(struct airoha_ppe *ppe);
 struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe,
                                                  u32 hash);
index af7af4097b98c63a24ab17fb587bfc397a801333..22f5f1bae730976554771f186508f6176a88f52f 100644 (file)
@@ -84,9 +84,9 @@ static u32 airoha_ppe_get_timestamp(struct airoha_ppe *ppe)
                             AIROHA_FOE_IB1_BIND_TIMESTAMP);
 }
 
-void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id, u8 fport)
+void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport)
 {
-       struct airoha_qdma *qdma = port->qdma;
+       struct airoha_qdma *qdma = dev->qdma;
        struct airoha_eth *eth = qdma->eth;
        u8 qdma_id = qdma - &eth->qdma[0];
        u32 fe_cpu_port;
@@ -180,8 +180,8 @@ static void airoha_ppe_hw_init(struct airoha_ppe *ppe)
                        if (!port)
                                continue;
 
-                       airoha_ppe_set_cpu_port(port, i,
-                                               airoha_get_fe_port(port));
+                       airoha_ppe_set_cpu_port(port->dev, i,
+                                               airoha_get_fe_port(port->dev));
                }
        }
 }
@@ -1473,11 +1473,12 @@ void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,
        airoha_ppe_foe_insert_entry(ppe, skb, hash, rx_wlan);
 }
 
-void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port)
+void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev)
 {
-       struct airoha_eth *eth = port->qdma->eth;
-       struct net_device *dev = port->dev->dev;
-       const u8 *addr = dev->dev_addr;
+       struct airoha_gdm_port *port = dev->port;
+       struct net_device *netdev = dev->dev;
+       struct airoha_eth *eth = dev->eth;
+       const u8 *addr = netdev->dev_addr;
        u32 val;
 
        val = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5];