| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/01 23:40 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": [
"MACB",
"MACB_PCI"
],
"FocusSymbols": [
"macb_change_mtu",
"macb_set_ringparam",
"macb_context_swap_start",
"macb_context_swap_end",
"macb_context_alloc",
"macb_alloc",
"macb_free"
],
"Reasoning": "The patch refactors the Cadence MACB/GEM Ethernet driver to use a `macb_context` structure for ring and buffer management. This allows the driver to swap contexts dynamically when changing the MTU or ring parameters while the interface is running, avoiding a full close/open cycle. This is a significant functional change to the driver's core logic and resource management, making it worth fuzzing.",
"WorthFuzzing": true
} |
| 1/1 | 2026/07/01 23:40 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 4f3d0336c11ac81f72a1b540f31d4a19a3b61e18\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Wed Jul 1 23:40:38 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h\nindex 2de56017ee0d61..630fe92608bc14 100644\n--- a/drivers/net/ethernet/cadence/macb.h\n+++ b/drivers/net/ethernet/cadence/macb.h\n@@ -840,7 +840,7 @@\n */\n #define macb_or_gem_writel(__bp, __reg, __value) \\\n \t({ \\\n-\t\tif (macb_is_gem((__bp))) \\\n+\t\tif (macb_is_gem(\u0026(__bp)-\u003einfo)) \\\n \t\t\tgem_writel((__bp), __reg, __value); \\\n \t\telse \\\n \t\t\tmacb_writel((__bp), __reg, __value); \\\n@@ -849,7 +849,7 @@\n #define macb_or_gem_readl(__bp, __reg) \\\n \t({ \\\n \t\tu32 __v; \\\n-\t\tif (macb_is_gem((__bp))) \\\n+\t\tif (macb_is_gem(\u0026(__bp)-\u003einfo)) \\\n \t\t\t__v = gem_readl((__bp), __reg); \\\n \t\telse \\\n \t\t\t__v = macb_readl((__bp), __reg); \\\n@@ -1196,22 +1196,23 @@ static const struct gem_statistic queue_statistics[] = {\n \n struct macb;\n struct macb_queue;\n+struct macb_context;\n \n struct macb_or_gem_ops {\n-\tint\t(*mog_alloc_rx_buffers)(struct macb *bp);\n-\tvoid\t(*mog_free_rx_buffers)(struct macb *bp);\n-\tvoid\t(*mog_init_rings)(struct macb *bp);\n+\tint\t(*mog_alloc_rx_buffers)(struct macb_context *ctx);\n+\tvoid\t(*mog_free_rx_buffers)(struct macb_context *ctx);\n+\tvoid\t(*mog_init_rings)(struct macb_context *ctx);\n \tint\t(*mog_rx)(struct macb_queue *queue, struct napi_struct *napi,\n \t\t\t int budget);\n };\n \n /* MACB-PTP interface: adapt to platform needs. */\n struct macb_ptp_info {\n-\tvoid (*ptp_init)(struct net_device *ndev);\n-\tvoid (*ptp_remove)(struct net_device *ndev);\n+\tvoid (*ptp_init)(struct net_device *netdev);\n+\tvoid (*ptp_remove)(struct net_device *netdev);\n \ts32 (*get_ptp_max_adj)(void);\n \tunsigned int (*get_tsu_rate)(struct macb *bp);\n-\tint (*get_ts_info)(struct net_device *dev,\n+\tint (*get_ts_info)(struct net_device *netdev,\n \t\t\t struct kernel_ethtool_ts_info *info);\n \tint (*get_hwtst)(struct net_device *netdev,\n \t\t\t struct kernel_hwtstamp_config *tstamp_config);\n@@ -1272,21 +1273,10 @@ struct macb_queue {\n \n \t/* Lock to protect tx_head and tx_tail */\n \tspinlock_t\t\ttx_ptr_lock;\n-\tunsigned int\t\ttx_head, tx_tail;\n-\tstruct macb_dma_desc\t*tx_ring;\n-\tstruct macb_tx_skb\t*tx_skb;\n-\tdma_addr_t\t\ttx_ring_dma;\n \tstruct work_struct\ttx_error_task;\n \tbool\t\t\ttxubr_pending;\n \tstruct napi_struct\tnapi_tx;\n \n-\tdma_addr_t\t\trx_ring_dma;\n-\tdma_addr_t\t\trx_buffers_dma;\n-\tunsigned int\t\trx_tail;\n-\tunsigned int\t\trx_prepared_head;\n-\tstruct macb_dma_desc\t*rx_ring;\n-\tstruct sk_buff\t\t**rx_skbuff;\n-\tvoid\t\t\t*rx_buffers;\n \tstruct napi_struct\tnapi_rx;\n \tstruct queue_stats stats;\n };\n@@ -1301,6 +1291,44 @@ struct ethtool_rx_fs_list {\n \tunsigned int count;\n };\n \n+struct macb_info {\n+\tstruct platform_device\t*pdev;\n+\tstruct net_device\t*netdev;\n+\tstruct macb_or_gem_ops\tmacbgem_ops;\n+\tunsigned int\t\tnum_queues;\n+\tu32\t\t\tcaps;\n+\tint\t\t\trx_bd_rd_prefetch;\n+\tint\t\t\ttx_bd_rd_prefetch;\n+};\n+\n+struct macb_rxq {\n+\tstruct macb_dma_desc\t*ring;\t\t/* MACB \u0026 GEM */\n+\tdma_addr_t\t\tring_dma;\t/* MACB \u0026 GEM */\n+\tunsigned int\t\ttail;\t\t/* MACB \u0026 GEM */\n+\tunsigned int\t\tprepared_head;\t/* GEM */\n+\tstruct sk_buff\t\t**skbuff;\t/* GEM */\n+\tdma_addr_t\t\tbuffers_dma;\t/* MACB */\n+\tvoid\t\t\t*buffers;\t/* MACB */\n+};\n+\n+struct macb_txq {\n+\tunsigned int\t\thead;\n+\tunsigned int\t\ttail;\n+\tstruct macb_dma_desc\t*ring;\n+\tdma_addr_t\t\tring_dma;\n+\tstruct macb_tx_skb\t*skb;\n+};\n+\n+struct macb_context {\n+\tconst struct macb_info\t*info;\n+\n+\tunsigned int\t\trx_buffer_size;\n+\tunsigned int\t\trx_ring_size;\n+\tunsigned int\t\ttx_ring_size;\n+\tstruct macb_rxq\t\trxq[MACB_MAX_QUEUES];\n+\tstruct macb_txq\t\ttxq[MACB_MAX_QUEUES];\n+};\n+\n struct macb {\n \tvoid __iomem\t\t*regs;\n \tbool\t\t\tnative_io;\n@@ -1309,24 +1337,36 @@ struct macb {\n \tu32\t(*macb_reg_readl)(struct macb *bp, int offset);\n \tvoid\t(*macb_reg_writel)(struct macb *bp, int offset, u32 value);\n \n+\t/*\n+\t * Give direct access (bp-\u003ecaps) and\n+\t * allow taking a pointer to it (\u0026bp-\u003einfo) for contexts.\n+\t */\n+\tunion {\n+\t\tstruct macb_info;\n+\t\tstruct macb_info info;\n+\t};\n+\n+\t/*\n+\t * Context stores all its parameters.\n+\t * But we must remember them across closure.\n+\t */\n+\tunsigned int\t\tconfigured_rx_ring_size;\n+\tunsigned int\t\tconfigured_tx_ring_size;\n+\tstruct macb_context\t*ctx;\n+\n \tstruct macb_dma_desc\t*rx_ring_tieoff;\n \tdma_addr_t\t\trx_ring_tieoff_dma;\n-\tsize_t\t\t\trx_buffer_size;\n-\n-\tunsigned int\t\trx_ring_size;\n-\tunsigned int\t\ttx_ring_size;\n \n-\tunsigned int\t\tnum_queues;\n \tstruct macb_queue\tqueues[MACB_MAX_QUEUES];\n \n \tspinlock_t\t\tlock;\n-\tstruct platform_device\t*pdev;\n+\t/* Serializes context swap against phylink MAC callbacks. */\n+\tstruct mutex\t\tmac_cfg_lock;\n \tstruct clk\t\t*pclk;\n \tstruct clk\t\t*hclk;\n \tstruct clk\t\t*tx_clk;\n \tstruct clk\t\t*rx_clk;\n \tstruct clk\t\t*tsu_clk;\n-\tstruct net_device\t*dev;\n \t/* Protects hw_stats and ethtool_stats */\n \tspinlock_t\t\tstats_lock;\n \tunion {\n@@ -1334,15 +1374,12 @@ struct macb {\n \t\tstruct gem_stats\tgem;\n \t}\t\t\thw_stats;\n \n-\tstruct macb_or_gem_ops\tmacbgem_ops;\n-\n \tstruct mii_bus\t\t*mii_bus;\n \tstruct phylink\t\t*phylink;\n \tstruct phylink_config\tphylink_config;\n \tstruct phylink_pcs\tphylink_usx_pcs;\n \tstruct phylink_pcs\tphylink_sgmii_pcs;\n \n-\tu32\t\t\tcaps;\n \tunsigned int\t\tdma_burst_length;\n \n \tphy_interface_t\t\tphy_interface;\n@@ -1385,9 +1422,6 @@ struct macb {\n \tstruct delayed_work\ttx_lpi_work;\n \tu32\t\t\ttx_lpi_timer;\n \n-\tint\trx_bd_rd_prefetch;\n-\tint\ttx_bd_rd_prefetch;\n-\n \tu32\trx_intr_mask;\n \n \tstruct macb_pm_data pm_data;\n@@ -1406,8 +1440,8 @@ enum macb_bd_control {\n \tTSTAMP_ALL_FRAMES,\n };\n \n-void gem_ptp_init(struct net_device *ndev);\n-void gem_ptp_remove(struct net_device *ndev);\n+void gem_ptp_init(struct net_device *netdev);\n+void gem_ptp_remove(struct net_device *netdev);\n void gem_ptp_txstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc);\n void gem_ptp_rxstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc);\n static inline void gem_ptp_do_txstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc)\n@@ -1426,27 +1460,28 @@ static inline void gem_ptp_do_rxstamp(struct macb *bp, struct sk_buff *skb, stru\n \tgem_ptp_rxstamp(bp, skb, desc);\n }\n \n-int gem_get_hwtst(struct net_device *dev,\n+int gem_get_hwtst(struct net_device *netdev,\n \t\t struct kernel_hwtstamp_config *tstamp_config);\n-int gem_set_hwtst(struct net_device *dev,\n+int gem_set_hwtst(struct net_device *netdev,\n \t\t struct kernel_hwtstamp_config *tstamp_config,\n \t\t struct netlink_ext_ack *extack);\n #else\n-static inline void gem_ptp_init(struct net_device *ndev) { }\n-static inline void gem_ptp_remove(struct net_device *ndev) { }\n+static inline void gem_ptp_init(struct net_device *netdev) { }\n+static inline void gem_ptp_remove(struct net_device *netdev) { }\n \n static inline void gem_ptp_do_txstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc) { }\n static inline void gem_ptp_do_rxstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc) { }\n #endif\n \n-static inline bool macb_is_gem(struct macb *bp)\n+static inline bool macb_is_gem(const struct macb_info *info)\n {\n-\treturn !!(bp-\u003ecaps \u0026 MACB_CAPS_MACB_IS_GEM);\n+\treturn !!(info-\u003ecaps \u0026 MACB_CAPS_MACB_IS_GEM);\n }\n \n-static inline bool gem_has_ptp(struct macb *bp)\n+static inline bool gem_has_ptp(const struct macb_info *info)\n {\n-\treturn IS_ENABLED(CONFIG_MACB_USE_HWSTAMP) \u0026\u0026 (bp-\u003ecaps \u0026 MACB_CAPS_GEM_HAS_PTP);\n+\treturn IS_ENABLED(CONFIG_MACB_USE_HWSTAMP) \u0026\u0026\n+\t (info-\u003ecaps \u0026 MACB_CAPS_GEM_HAS_PTP);\n }\n \n /* ENST Helper functions */\n@@ -1462,16 +1497,16 @@ static inline u64 enst_max_hw_interval(u32 speed_mbps)\n \t\t\t ENST_TIME_GRANULARITY_NS * 1000, (speed_mbps));\n }\n \n-static inline bool macb_dma64(struct macb *bp)\n+static inline bool macb_dma64(const struct macb_info *info)\n {\n \treturn IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT) \u0026\u0026\n-\t bp-\u003ecaps \u0026 MACB_CAPS_DMA_64B;\n+\t info-\u003ecaps \u0026 MACB_CAPS_DMA_64B;\n }\n \n-static inline bool macb_dma_ptp(struct macb *bp)\n+static inline bool macb_dma_ptp(const struct macb_info *info)\n {\n \treturn IS_ENABLED(CONFIG_MACB_USE_HWSTAMP) \u0026\u0026\n-\t bp-\u003ecaps \u0026 MACB_CAPS_DMA_PTP;\n+\t info-\u003ecaps \u0026 MACB_CAPS_DMA_PTP;\n }\n \n static inline void macb_queue_isr_clear(struct macb *bp,\ndiff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c\nindex fd282a1700fb98..0ea7123ec8f8e2 100644\n--- a/drivers/net/ethernet/cadence/macb_main.c\n+++ b/drivers/net/ethernet/cadence/macb_main.c\n@@ -61,7 +61,7 @@ struct sifive_fu540_macb_mgmt {\n #define MAX_TX_RING_SIZE\t4096\n \n /* level of occupied TX descriptors under which we wake up TX process */\n-#define MACB_TX_WAKEUP_THRESH(bp)\t(3 * (bp)-\u003etx_ring_size / 4)\n+#define MACB_TX_WAKEUP_THRESH(bp)\t(3 * (bp)-\u003ectx-\u003etx_ring_size / 4)\n \n #define MACB_RX_INT_FLAGS\t(MACB_BIT(RCOMP) | MACB_BIT(ISR_ROVR))\n #define MACB_TX_ERR_FLAGS\t(MACB_BIT(ISR_TUND)\t\t\t\\\n@@ -126,75 +126,104 @@ struct sifive_fu540_macb_mgmt {\n * word 5: timestamp word 1\n * word 6: timestamp word 2\n */\n-static unsigned int macb_dma_desc_get_size(struct macb *bp)\n+static unsigned int macb_dma_desc_get_size(const struct macb_info *info)\n {\n \tunsigned int desc_size = sizeof(struct macb_dma_desc);\n \n-\tif (macb_dma64(bp))\n+\tif (macb_dma64(info))\n \t\tdesc_size += sizeof(struct macb_dma_desc_64);\n-\tif (macb_dma_ptp(bp))\n+\tif (macb_dma_ptp(info))\n \t\tdesc_size += sizeof(struct macb_dma_desc_ptp);\n \n \treturn desc_size;\n }\n \n-static unsigned int macb_adj_dma_desc_idx(struct macb *bp, unsigned int desc_idx)\n+static unsigned int macb_adj_dma_desc_idx(struct macb_context *ctx,\n+\t\t\t\t\t unsigned int desc_idx)\n {\n-\treturn desc_idx * (1 + macb_dma64(bp) + macb_dma_ptp(bp));\n+\treturn desc_idx * (1 + macb_dma64(ctx-\u003einfo) +\n+\t\t\t macb_dma_ptp(ctx-\u003einfo));\n }\n \n-static struct macb_dma_desc_64 *macb_64b_desc(struct macb *bp, struct macb_dma_desc *desc)\n+static struct macb_dma_desc_64 *macb_64b_desc(struct macb_dma_desc *desc)\n {\n \treturn (struct macb_dma_desc_64 *)((void *)desc\n \t\t+ sizeof(struct macb_dma_desc));\n }\n \n /* Ring buffer accessors */\n-static unsigned int macb_tx_ring_wrap(struct macb *bp, unsigned int index)\n+static unsigned int macb_tx_ring_wrap(struct macb_context *ctx,\n+\t\t\t\t unsigned int index)\n {\n-\treturn index \u0026 (bp-\u003etx_ring_size - 1);\n+\treturn index \u0026 (ctx-\u003etx_ring_size - 1);\n }\n \n-static struct macb_dma_desc *macb_tx_desc(struct macb_queue *queue,\n+static struct macb_txq *macb_txq(struct macb_queue *queue)\n+{\n+\tstruct macb *bp = queue-\u003ebp;\n+\tunsigned int q = queue - bp-\u003equeues;\n+\n+\treturn \u0026bp-\u003ectx-\u003etxq[q];\n+}\n+\n+static struct macb_rxq *macb_rxq(struct macb_queue *queue)\n+{\n+\tstruct macb *bp = queue-\u003ebp;\n+\tunsigned int q = queue - bp-\u003equeues;\n+\n+\treturn \u0026bp-\u003ectx-\u003erxq[q];\n+}\n+\n+static struct macb_dma_desc *macb_tx_desc(struct macb_context *ctx,\n+\t\t\t\t\t unsigned int q,\n \t\t\t\t\t unsigned int index)\n {\n-\tindex = macb_tx_ring_wrap(queue-\u003ebp, index);\n-\tindex = macb_adj_dma_desc_idx(queue-\u003ebp, index);\n-\treturn \u0026queue-\u003etx_ring[index];\n+\tindex = macb_tx_ring_wrap(ctx, index);\n+\tindex = macb_adj_dma_desc_idx(ctx, index);\n+\treturn \u0026ctx-\u003etxq[q].ring[index];\n }\n \n static struct macb_tx_skb *macb_tx_skb(struct macb_queue *queue,\n \t\t\t\t unsigned int index)\n {\n-\treturn \u0026queue-\u003etx_skb[macb_tx_ring_wrap(queue-\u003ebp, index)];\n+\tstruct macb_txq *txq = macb_txq(queue);\n+\n+\treturn \u0026txq-\u003eskb[macb_tx_ring_wrap(queue-\u003ebp-\u003ectx, index)];\n }\n \n static dma_addr_t macb_tx_dma(struct macb_queue *queue, unsigned int index)\n {\n+\tstruct macb_context *ctx = queue-\u003ebp-\u003ectx;\n+\tstruct macb_txq *txq = macb_txq(queue);\n \tdma_addr_t offset;\n \n-\toffset = macb_tx_ring_wrap(queue-\u003ebp, index) *\n-\t\t\tmacb_dma_desc_get_size(queue-\u003ebp);\n+\toffset = macb_tx_ring_wrap(ctx, index) *\n+\t\t\tmacb_dma_desc_get_size(\u0026queue-\u003ebp-\u003einfo);\n \n-\treturn queue-\u003etx_ring_dma + offset;\n+\treturn txq-\u003ering_dma + offset;\n }\n \n-static unsigned int macb_rx_ring_wrap(struct macb *bp, unsigned int index)\n+static unsigned int macb_rx_ring_wrap(struct macb_context *ctx,\n+\t\t\t\t unsigned int index)\n {\n-\treturn index \u0026 (bp-\u003erx_ring_size - 1);\n+\treturn index \u0026 (ctx-\u003erx_ring_size - 1);\n }\n \n-static struct macb_dma_desc *macb_rx_desc(struct macb_queue *queue, unsigned int index)\n+static struct macb_dma_desc *macb_rx_desc(struct macb_context *ctx,\n+\t\t\t\t\t unsigned int q, unsigned int index)\n {\n-\tindex = macb_rx_ring_wrap(queue-\u003ebp, index);\n-\tindex = macb_adj_dma_desc_idx(queue-\u003ebp, index);\n-\treturn \u0026queue-\u003erx_ring[index];\n+\tindex = macb_rx_ring_wrap(ctx, index);\n+\tindex = macb_adj_dma_desc_idx(ctx, index);\n+\treturn \u0026ctx-\u003erxq[q].ring[index];\n }\n \n static void *macb_rx_buffer(struct macb_queue *queue, unsigned int index)\n {\n-\treturn queue-\u003erx_buffers + queue-\u003ebp-\u003erx_buffer_size *\n-\t macb_rx_ring_wrap(queue-\u003ebp, index);\n+\tstruct macb_context *ctx = queue-\u003ebp-\u003ectx;\n+\tstruct macb_rxq *rxq = macb_rxq(queue);\n+\n+\treturn rxq-\u003ebuffers + ctx-\u003erx_buffer_size *\n+\t macb_rx_ring_wrap(ctx, index);\n }\n \n /* I/O accessors */\n@@ -252,12 +281,12 @@ static void macb_set_hwaddr(struct macb *bp)\n \tu32 bottom;\n \tu16 top;\n \n-\tbottom = get_unaligned_le32(bp-\u003edev-\u003edev_addr);\n+\tbottom = get_unaligned_le32(bp-\u003enetdev-\u003edev_addr);\n \tmacb_or_gem_writel(bp, SA1B, bottom);\n-\ttop = get_unaligned_le16(bp-\u003edev-\u003edev_addr + 4);\n+\ttop = get_unaligned_le16(bp-\u003enetdev-\u003edev_addr + 4);\n \tmacb_or_gem_writel(bp, SA1T, top);\n \n-\tif (gem_has_ptp(bp)) {\n+\tif (gem_has_ptp(\u0026bp-\u003einfo)) {\n \t\tgem_writel(bp, RXPTPUNI, bottom);\n \t\tgem_writel(bp, TXPTPUNI, bottom);\n \t}\n@@ -291,13 +320,13 @@ static void macb_get_hwaddr(struct macb *bp)\n \t\taddr[5] = (top \u003e\u003e 8) \u0026 0xff;\n \n \t\tif (is_valid_ether_addr(addr)) {\n-\t\t\teth_hw_addr_set(bp-\u003edev, addr);\n+\t\t\teth_hw_addr_set(bp-\u003enetdev, addr);\n \t\t\treturn;\n \t\t}\n \t}\n \n \tdev_info(\u0026bp-\u003epdev-\u003edev, \"invalid hw address, using random\\n\");\n-\teth_hw_addr_random(bp-\u003edev);\n+\teth_hw_addr_random(bp-\u003enetdev);\n }\n \n static int macb_mdio_wait_for_idle(struct macb *bp)\n@@ -463,19 +492,23 @@ static int macb_mdio_write_c45(struct mii_bus *bus, int mii_id,\n static void macb_init_buffers(struct macb *bp)\n {\n \tstruct macb_queue *queue;\n+\tstruct macb_rxq *rxq;\n+\tstruct macb_txq *txq;\n \tunsigned int q;\n \n \t/* Single register for all queues' high 32 bits. */\n-\tif (macb_dma64(bp)) {\n-\t\tmacb_writel(bp, RBQPH,\n-\t\t\t upper_32_bits(bp-\u003equeues[0].rx_ring_dma));\n-\t\tmacb_writel(bp, TBQPH,\n-\t\t\t upper_32_bits(bp-\u003equeues[0].tx_ring_dma));\n+\tif (macb_dma64(\u0026bp-\u003einfo)) {\n+\t\trxq = \u0026bp-\u003ectx-\u003erxq[0];\n+\t\ttxq = \u0026bp-\u003ectx-\u003etxq[0];\n+\t\tmacb_writel(bp, RBQPH, upper_32_bits(rxq-\u003ering_dma));\n+\t\tmacb_writel(bp, TBQPH, upper_32_bits(txq-\u003ering_dma));\n \t}\n \n \tfor (q = 0, queue = bp-\u003equeues; q \u003c bp-\u003enum_queues; ++q, ++queue) {\n-\t\tqueue_writel(queue, RBQP, lower_32_bits(queue-\u003erx_ring_dma));\n-\t\tqueue_writel(queue, TBQP, lower_32_bits(queue-\u003etx_ring_dma));\n+\t\trxq = \u0026bp-\u003ectx-\u003erxq[q];\n+\t\ttxq = \u0026bp-\u003ectx-\u003etxq[q];\n+\t\tqueue_writel(queue, RBQP, lower_32_bits(rxq-\u003ering_dma));\n+\t\tqueue_writel(queue, TBQP, lower_32_bits(txq-\u003ering_dma));\n \t}\n }\n \n@@ -509,12 +542,12 @@ static void macb_set_tx_clk(struct macb *bp, int speed)\n \tferr = abs(rate_rounded - rate);\n \tferr = DIV_ROUND_UP(ferr, rate / 100000);\n \tif (ferr \u003e 5)\n-\t\tnetdev_warn(bp-\u003edev,\n+\t\tnetdev_warn(bp-\u003enetdev,\n \t\t\t \"unable to generate target frequency: %ld Hz\\n\",\n \t\t\t rate);\n \n \tif (clk_set_rate(bp-\u003etx_clk, rate_rounded))\n-\t\tnetdev_err(bp-\u003edev, \"adjusting tx_clk failed.\\n\");\n+\t\tnetdev_err(bp-\u003enetdev, \"adjusting tx_clk failed.\\n\");\n }\n \n static void macb_usx_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,\n@@ -648,11 +681,12 @@ static bool macb_tx_lpi_set(struct macb *bp, bool enable)\n \n static bool macb_tx_all_queues_idle(struct macb *bp)\n {\n-\tstruct macb_queue *queue;\n+\tstruct macb_txq *txq;\n \tunsigned int q;\n \n-\tfor (q = 0, queue = bp-\u003equeues; q \u003c bp-\u003enum_queues; ++q, ++queue) {\n-\t\tif (READ_ONCE(queue-\u003etx_head) != READ_ONCE(queue-\u003etx_tail))\n+\tfor (q = 0; q \u003c bp-\u003enum_queues; ++q) {\n+\t\ttxq = \u0026bp-\u003ectx-\u003etxq[q];\n+\t\tif (READ_ONCE(txq-\u003ehead) != READ_ONCE(txq-\u003etail))\n \t\t\treturn false;\n \t}\n \treturn true;\n@@ -697,25 +731,31 @@ static void macb_tx_lpi_wake(struct macb *bp)\n \n static void macb_mac_disable_tx_lpi(struct phylink_config *config)\n {\n-\tstruct net_device *ndev = to_net_dev(config-\u003edev);\n-\tstruct macb *bp = netdev_priv(ndev);\n+\tstruct net_device *netdev = to_net_dev(config-\u003edev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tunsigned long flags;\n \n+\tmutex_lock(\u0026bp-\u003emac_cfg_lock);\n+\n \tcancel_delayed_work_sync(\u0026bp-\u003etx_lpi_work);\n \n \tspin_lock_irqsave(\u0026bp-\u003elock, flags);\n \tbp-\u003eeee_active = false;\n \tmacb_tx_lpi_set(bp, false);\n \tspin_unlock_irqrestore(\u0026bp-\u003elock, flags);\n+\n+\tmutex_unlock(\u0026bp-\u003emac_cfg_lock);\n }\n \n static int macb_mac_enable_tx_lpi(struct phylink_config *config, u32 timer,\n \t\t\t\t bool tx_clk_stop)\n {\n-\tstruct net_device *ndev = to_net_dev(config-\u003edev);\n-\tstruct macb *bp = netdev_priv(ndev);\n+\tstruct net_device *netdev = to_net_dev(config-\u003edev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tunsigned long flags;\n \n+\tmutex_lock(\u0026bp-\u003emac_cfg_lock);\n+\n \tspin_lock_irqsave(\u0026bp-\u003elock, flags);\n \tbp-\u003etx_lpi_timer = timer;\n \tbp-\u003eeee_active = true;\n@@ -726,18 +766,21 @@ static int macb_mac_enable_tx_lpi(struct phylink_config *config, u32 timer,\n \t */\n \tmod_delayed_work(system_wq, \u0026bp-\u003etx_lpi_work, msecs_to_jiffies(1000));\n \n+\tmutex_unlock(\u0026bp-\u003emac_cfg_lock);\n+\n \treturn 0;\n }\n \n static void macb_mac_config(struct phylink_config *config, unsigned int mode,\n \t\t\t const struct phylink_link_state *state)\n {\n-\tstruct net_device *ndev = to_net_dev(config-\u003edev);\n-\tstruct macb *bp = netdev_priv(ndev);\n+\tstruct net_device *netdev = to_net_dev(config-\u003edev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tunsigned long flags;\n \tu32 old_ctrl, ctrl;\n \tu32 old_ncr, ncr;\n \n+\tmutex_lock(\u0026bp-\u003emac_cfg_lock);\n \tspin_lock_irqsave(\u0026bp-\u003elock, flags);\n \n \told_ctrl = ctrl = macb_or_gem_readl(bp, NCFGR);\n@@ -746,7 +789,7 @@ static void macb_mac_config(struct phylink_config *config, unsigned int mode,\n \tif (bp-\u003ecaps \u0026 MACB_CAPS_MACB_IS_EMAC) {\n \t\tif (state-\u003einterface == PHY_INTERFACE_MODE_RMII)\n \t\t\tctrl |= MACB_BIT(RM9200_RMII);\n-\t} else if (macb_is_gem(bp)) {\n+\t} else if (macb_is_gem(\u0026bp-\u003einfo)) {\n \t\tctrl \u0026= ~(GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL));\n \t\tncr \u0026= ~GEM_BIT(ENABLE_HS_MAC);\n \n@@ -769,17 +812,20 @@ static void macb_mac_config(struct phylink_config *config, unsigned int mode,\n \t\tmacb_or_gem_writel(bp, NCR, ncr);\n \n \tspin_unlock_irqrestore(\u0026bp-\u003elock, flags);\n+\tmutex_unlock(\u0026bp-\u003emac_cfg_lock);\n }\n \n static void macb_mac_link_down(struct phylink_config *config, unsigned int mode,\n \t\t\t phy_interface_t interface)\n {\n-\tstruct net_device *ndev = to_net_dev(config-\u003edev);\n-\tstruct macb *bp = netdev_priv(ndev);\n+\tstruct net_device *netdev = to_net_dev(config-\u003edev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tstruct macb_queue *queue;\n \tunsigned int q;\n \tu32 ctrl;\n \n+\tmutex_lock(\u0026bp-\u003emac_cfg_lock);\n+\n \tif (!(bp-\u003ecaps \u0026 MACB_CAPS_MACB_IS_EMAC))\n \t\tfor (q = 0, queue = bp-\u003equeues; q \u003c bp-\u003enum_queues; ++q, ++queue)\n \t\t\tqueue_writel(queue, IDR,\n@@ -789,7 +835,9 @@ static void macb_mac_link_down(struct phylink_config *config, unsigned int mode,\n \tctrl = macb_readl(bp, NCR) \u0026 ~(MACB_BIT(RE) | MACB_BIT(TE));\n \tmacb_writel(bp, NCR, ctrl);\n \n-\tnetif_tx_stop_all_queues(ndev);\n+\tnetif_tx_stop_all_queues(netdev);\n+\n+\tmutex_unlock(\u0026bp-\u003emac_cfg_lock);\n }\n \n /* Use juggling algorithm to left rotate tx ring and tx skb array */\n@@ -798,28 +846,30 @@ static void gem_shuffle_tx_one_ring(struct macb_queue *queue)\n \tunsigned int head, tail, count, ring_size, desc_size;\n \tstruct macb_tx_skb tx_skb, *skb_curr, *skb_next;\n \tstruct macb_dma_desc *desc_curr, *desc_next;\n+\tunsigned int q = queue - queue-\u003ebp-\u003equeues;\n \tunsigned int i, cycles, shift, curr, next;\n-\tstruct macb *bp = queue-\u003ebp;\n+\tstruct macb_context *ctx = queue-\u003ebp-\u003ectx;\n+\tstruct macb_txq *txq = macb_txq(queue);\n \tunsigned char desc[24];\n \tunsigned long flags;\n \n-\tdesc_size = macb_dma_desc_get_size(bp);\n+\tdesc_size = macb_dma_desc_get_size(\u0026queue-\u003ebp-\u003einfo);\n \n \tif (WARN_ON_ONCE(desc_size \u003e ARRAY_SIZE(desc)))\n \t\treturn;\n \n \tspin_lock_irqsave(\u0026queue-\u003etx_ptr_lock, flags);\n-\thead = queue-\u003etx_head;\n-\ttail = queue-\u003etx_tail;\n-\tring_size = bp-\u003etx_ring_size;\n+\thead = txq-\u003ehead;\n+\ttail = txq-\u003etail;\n+\tring_size = ctx-\u003etx_ring_size;\n \tcount = CIRC_CNT(head, tail, ring_size);\n \n \tif (!(tail % ring_size))\n \t\tgoto unlock;\n \n \tif (!count) {\n-\t\tqueue-\u003etx_head = 0;\n-\t\tqueue-\u003etx_tail = 0;\n+\t\ttxq-\u003ehead = 0;\n+\t\ttxq-\u003etail = 0;\n \t\tgoto unlock;\n \t}\n \n@@ -827,7 +877,7 @@ static void gem_shuffle_tx_one_ring(struct macb_queue *queue)\n \tcycles = gcd(ring_size, shift);\n \n \tfor (i = 0; i \u003c cycles; i++) {\n-\t\tmemcpy(\u0026desc, macb_tx_desc(queue, i), desc_size);\n+\t\tmemcpy(\u0026desc, macb_tx_desc(ctx, q, i), desc_size);\n \t\tmemcpy(\u0026tx_skb, macb_tx_skb(queue, i),\n \t\t sizeof(struct macb_tx_skb));\n \n@@ -835,8 +885,8 @@ static void gem_shuffle_tx_one_ring(struct macb_queue *queue)\n \t\tnext = (curr + shift) % ring_size;\n \n \t\twhile (next != i) {\n-\t\t\tdesc_curr = macb_tx_desc(queue, curr);\n-\t\t\tdesc_next = macb_tx_desc(queue, next);\n+\t\t\tdesc_curr = macb_tx_desc(ctx, q, curr);\n+\t\t\tdesc_next = macb_tx_desc(ctx, q, next);\n \n \t\t\tmemcpy(desc_curr, desc_next, desc_size);\n \n@@ -853,7 +903,7 @@ static void gem_shuffle_tx_one_ring(struct macb_queue *queue)\n \t\t\tnext = (curr + shift) % ring_size;\n \t\t}\n \n-\t\tdesc_curr = macb_tx_desc(queue, curr);\n+\t\tdesc_curr = macb_tx_desc(ctx, q, curr);\n \t\tmemcpy(desc_curr, \u0026desc, desc_size);\n \t\tif (i == ring_size - 1)\n \t\t\tdesc_curr-\u003ectrl \u0026= ~MACB_BIT(TX_WRAP);\n@@ -863,8 +913,8 @@ static void gem_shuffle_tx_one_ring(struct macb_queue *queue)\n \t\t sizeof(struct macb_tx_skb));\n \t}\n \n-\tqueue-\u003etx_head = count;\n-\tqueue-\u003etx_tail = 0;\n+\ttxq-\u003ehead = count;\n+\ttxq-\u003etail = 0;\n \n \t/* Make descriptor updates visible to hardware */\n \twmb();\n@@ -877,25 +927,26 @@ static void gem_shuffle_tx_one_ring(struct macb_queue *queue)\n static void gem_shuffle_tx_rings(struct macb *bp)\n {\n \tstruct macb_queue *queue;\n-\tint q;\n+\tunsigned int q;\n \n \tfor (q = 0, queue = bp-\u003equeues; q \u003c bp-\u003enum_queues; q++, queue++)\n \t\tgem_shuffle_tx_one_ring(queue);\n }\n \n static void macb_mac_link_up(struct phylink_config *config,\n-\t\t\t struct phy_device *phy,\n+\t\t\t struct phy_device *phydev,\n \t\t\t unsigned int mode, phy_interface_t interface,\n \t\t\t int speed, int duplex,\n \t\t\t bool tx_pause, bool rx_pause)\n {\n-\tstruct net_device *ndev = to_net_dev(config-\u003edev);\n-\tstruct macb *bp = netdev_priv(ndev);\n+\tstruct net_device *netdev = to_net_dev(config-\u003edev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tstruct macb_queue *queue;\n \tunsigned long flags;\n \tunsigned int q;\n \tu32 ctrl;\n \n+\tmutex_lock(\u0026bp-\u003emac_cfg_lock);\n \tspin_lock_irqsave(\u0026bp-\u003elock, flags);\n \n \tctrl = macb_or_gem_readl(bp, NCFGR);\n@@ -910,7 +961,7 @@ static void macb_mac_link_up(struct phylink_config *config,\n \n \tif (!(bp-\u003ecaps \u0026 MACB_CAPS_MACB_IS_EMAC)) {\n \t\tctrl \u0026= ~MACB_BIT(PAE);\n-\t\tif (macb_is_gem(bp)) {\n+\t\tif (macb_is_gem(\u0026bp-\u003einfo)) {\n \t\t\tctrl \u0026= ~GEM_BIT(GBE);\n \n \t\t\tif (speed == SPEED_1000)\n@@ -941,19 +992,21 @@ static void macb_mac_link_up(struct phylink_config *config,\n \n \t/* Enable Rx and Tx; Enable PTP unicast */\n \tctrl = macb_readl(bp, NCR);\n-\tif (gem_has_ptp(bp))\n+\tif (gem_has_ptp(\u0026bp-\u003einfo))\n \t\tctrl |= MACB_BIT(PTPUNI);\n \n \tmacb_writel(bp, NCR, ctrl | MACB_BIT(RE) | MACB_BIT(TE));\n \n-\tnetif_tx_wake_all_queues(ndev);\n+\tnetif_tx_wake_all_queues(netdev);\n+\n+\tmutex_unlock(\u0026bp-\u003emac_cfg_lock);\n }\n \n static struct phylink_pcs *macb_mac_select_pcs(struct phylink_config *config,\n \t\t\t\t\t phy_interface_t interface)\n {\n-\tstruct net_device *ndev = to_net_dev(config-\u003edev);\n-\tstruct macb *bp = netdev_priv(ndev);\n+\tstruct net_device *netdev = to_net_dev(config-\u003edev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \n \tif (interface == PHY_INTERFACE_MODE_10GBASER)\n \t\treturn \u0026bp-\u003ephylink_usx_pcs;\n@@ -982,7 +1035,7 @@ static bool macb_phy_handle_exists(struct device_node *dn)\n static int macb_phylink_connect(struct macb *bp)\n {\n \tstruct device_node *dn = bp-\u003epdev-\u003edev.of_node;\n-\tstruct net_device *dev = bp-\u003edev;\n+\tstruct net_device *netdev = bp-\u003enetdev;\n \tstruct phy_device *phydev;\n \tint ret;\n \n@@ -992,7 +1045,7 @@ static int macb_phylink_connect(struct macb *bp)\n \tif (!dn || (ret \u0026\u0026 !macb_phy_handle_exists(dn))) {\n \t\tphydev = phy_find_first(bp-\u003emii_bus);\n \t\tif (!phydev) {\n-\t\t\tnetdev_err(dev, \"no PHY found\\n\");\n+\t\t\tnetdev_err(netdev, \"no PHY found\\n\");\n \t\t\treturn -ENXIO;\n \t\t}\n \n@@ -1001,7 +1054,7 @@ static int macb_phylink_connect(struct macb *bp)\n \t}\n \n \tif (ret) {\n-\t\tnetdev_err(dev, \"Could not attach PHY (%d)\\n\", ret);\n+\t\tnetdev_err(netdev, \"Could not attach PHY (%d)\\n\", ret);\n \t\treturn ret;\n \t}\n \n@@ -1013,21 +1066,21 @@ static int macb_phylink_connect(struct macb *bp)\n static void macb_get_pcs_fixed_state(struct phylink_config *config,\n \t\t\t\t struct phylink_link_state *state)\n {\n-\tstruct net_device *ndev = to_net_dev(config-\u003edev);\n-\tstruct macb *bp = netdev_priv(ndev);\n+\tstruct net_device *netdev = to_net_dev(config-\u003edev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \n \tstate-\u003elink = (macb_readl(bp, NSR) \u0026 MACB_BIT(NSR_LINK)) != 0;\n }\n \n /* based on au1000_eth. c*/\n-static int macb_mii_probe(struct net_device *dev)\n+static int macb_mii_probe(struct net_device *netdev)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \n \tbp-\u003ephylink_sgmii_pcs.ops = \u0026macb_phylink_pcs_ops;\n \tbp-\u003ephylink_usx_pcs.ops = \u0026macb_phylink_usx_pcs_ops;\n \n-\tbp-\u003ephylink_config.dev = \u0026dev-\u003edev;\n+\tbp-\u003ephylink_config.dev = \u0026netdev-\u003edev;\n \tbp-\u003ephylink_config.type = PHYLINK_NETDEV;\n \tbp-\u003ephylink_config.mac_managed_pm = true;\n \n@@ -1051,7 +1104,8 @@ static int macb_mii_probe(struct net_device *dev)\n \t\t bp-\u003ephylink_config.supported_interfaces);\n \n \t/* Determine what modes are supported */\n-\tif (macb_is_gem(bp) \u0026\u0026 (bp-\u003ecaps \u0026 MACB_CAPS_GIGABIT_MODE_AVAILABLE)) {\n+\tif (macb_is_gem(\u0026bp-\u003einfo) \u0026\u0026\n+\t (bp-\u003ecaps \u0026 MACB_CAPS_GIGABIT_MODE_AVAILABLE)) {\n \t\tbp-\u003ephylink_config.mac_capabilities |= MAC_1000FD;\n \t\tif (!(bp-\u003ecaps \u0026 MACB_CAPS_NO_GIGABIT_HALF))\n \t\t\tbp-\u003ephylink_config.mac_capabilities |= MAC_1000HD;\n@@ -1086,7 +1140,7 @@ static int macb_mii_probe(struct net_device *dev)\n \tbp-\u003ephylink = phylink_create(\u0026bp-\u003ephylink_config, bp-\u003epdev-\u003edev.fwnode,\n \t\t\t\t bp-\u003ephy_interface, \u0026macb_phylink_ops);\n \tif (IS_ERR(bp-\u003ephylink)) {\n-\t\tnetdev_err(dev, \"Could not create a phylink instance (%ld)\\n\",\n+\t\tnetdev_err(netdev, \"Could not create a phylink instance (%ld)\\n\",\n \t\t\t PTR_ERR(bp-\u003ephylink));\n \t\treturn PTR_ERR(bp-\u003ephylink);\n \t}\n@@ -1133,7 +1187,7 @@ static int macb_mii_init(struct macb *bp)\n \t */\n \tmdio_np = of_get_child_by_name(np, \"mdio\");\n \tif (!mdio_np \u0026\u0026 of_phy_is_fixed_link(np))\n-\t\treturn macb_mii_probe(bp-\u003edev);\n+\t\treturn macb_mii_probe(bp-\u003enetdev);\n \n \t/* Enable management port */\n \tmacb_writel(bp, NCR, MACB_BIT(MPE));\n@@ -1154,13 +1208,13 @@ static int macb_mii_init(struct macb *bp)\n \tbp-\u003emii_bus-\u003epriv = bp;\n \tbp-\u003emii_bus-\u003eparent = \u0026bp-\u003epdev-\u003edev;\n \n-\tdev_set_drvdata(\u0026bp-\u003edev-\u003edev, bp-\u003emii_bus);\n+\tdev_set_drvdata(\u0026bp-\u003enetdev-\u003edev, bp-\u003emii_bus);\n \n \terr = macb_mdiobus_register(bp, mdio_np);\n \tif (err)\n \t\tgoto err_out_free_mdiobus;\n \n-\terr = macb_mii_probe(bp-\u003edev);\n+\terr = macb_mii_probe(bp-\u003enetdev);\n \tif (err)\n \t\tgoto err_out_unregister_bus;\n \n@@ -1219,12 +1273,13 @@ static void macb_tx_unmap(struct macb *bp, struct macb_tx_skb *tx_skb, int budge\n \t}\n }\n \n-static void macb_set_addr(struct macb *bp, struct macb_dma_desc *desc, dma_addr_t addr)\n+static void macb_set_addr(const struct macb_info *info,\n+\t\t\t struct macb_dma_desc *desc, dma_addr_t addr)\n {\n-\tif (macb_dma64(bp)) {\n+\tif (macb_dma64(info)) {\n \t\tstruct macb_dma_desc_64 *desc_64;\n \n-\t\tdesc_64 = macb_64b_desc(bp, desc);\n+\t\tdesc_64 = macb_64b_desc(desc);\n \t\tdesc_64-\u003eaddrh = upper_32_bits(addr);\n \t\t/* The low bits of RX address contain the RX_USED bit, clearing\n \t\t * of which allows packet RX. Make sure the high bits are also\n@@ -1236,40 +1291,42 @@ static void macb_set_addr(struct macb *bp, struct macb_dma_desc *desc, dma_addr_\n \tdesc-\u003eaddr = lower_32_bits(addr);\n }\n \n-static dma_addr_t macb_get_addr(struct macb *bp, struct macb_dma_desc *desc)\n+static dma_addr_t macb_get_addr(struct macb_context *ctx,\n+\t\t\t\tstruct macb_dma_desc *desc)\n {\n \tdma_addr_t addr = 0;\n \n-\tif (macb_dma64(bp)) {\n+\tif (macb_dma64(ctx-\u003einfo)) {\n \t\tstruct macb_dma_desc_64 *desc_64;\n \n-\t\tdesc_64 = macb_64b_desc(bp, desc);\n+\t\tdesc_64 = macb_64b_desc(desc);\n \t\taddr = ((u64)(desc_64-\u003eaddrh) \u003c\u003c 32);\n \t}\n \taddr |= MACB_BF(RX_WADDR, MACB_BFEXT(RX_WADDR, desc-\u003eaddr));\n-\tif (macb_dma_ptp(bp))\n+\tif (macb_dma_ptp(ctx-\u003einfo))\n \t\taddr \u0026= ~GEM_BIT(DMA_RXVALID);\n \treturn addr;\n }\n \n static void macb_tx_error_task(struct work_struct *work)\n {\n-\tstruct macb_queue\t*queue = container_of(work, struct macb_queue,\n-\t\t\t\t\t\t tx_error_task);\n-\tbool\t\t\thalt_timeout = false;\n-\tstruct macb\t\t*bp = queue-\u003ebp;\n-\tu32\t\t\tqueue_index;\n-\tu32\t\t\tpackets = 0;\n-\tu32\t\t\tbytes = 0;\n-\tstruct macb_tx_skb\t*tx_skb;\n-\tstruct macb_dma_desc\t*desc;\n-\tstruct sk_buff\t\t*skb;\n-\tunsigned int\t\ttail;\n-\tunsigned long\t\tflags;\n-\n-\tqueue_index = queue - bp-\u003equeues;\n-\tnetdev_vdbg(bp-\u003edev, \"macb_tx_error_task: q = %u, t = %u, h = %u\\n\",\n-\t\t queue_index, queue-\u003etx_tail, queue-\u003etx_head);\n+\tstruct macb_queue *queue = container_of(work, struct macb_queue,\n+\t\t\t\t\t\ttx_error_task);\n+\tunsigned int q = queue - queue-\u003ebp-\u003equeues;\n+\tstruct macb_context *ctx = queue-\u003ebp-\u003ectx;\n+\tstruct macb_txq *txq = macb_txq(queue);\n+\tstruct macb *bp = queue-\u003ebp;\n+\tstruct macb_tx_skb *tx_skb;\n+\tstruct macb_dma_desc *desc;\n+\tbool halt_timeout = false;\n+\tstruct sk_buff *skb;\n+\tunsigned long flags;\n+\tunsigned int tail;\n+\tu32 packets = 0;\n+\tu32 bytes = 0;\n+\n+\tnetdev_vdbg(bp-\u003enetdev, \"macb_tx_error_task: q = %u, t = %u, h = %u\\n\",\n+\t\t q, txq-\u003etail, txq-\u003ehead);\n \n \t/* Prevent the queue NAPI TX poll from running, as it calls\n \t * macb_tx_complete(), which in turn may call netif_wake_subqueue().\n@@ -1281,14 +1338,14 @@ static void macb_tx_error_task(struct work_struct *work)\n \tspin_lock_irqsave(\u0026bp-\u003elock, flags);\n \n \t/* Make sure nobody is trying to queue up new packets */\n-\tnetif_tx_stop_all_queues(bp-\u003edev);\n+\tnetif_tx_stop_all_queues(bp-\u003enetdev);\n \n \t/* Stop transmission now\n \t * (in case we have just queued new packets)\n \t * macb/gem must be halted to write TBQP register\n \t */\n \tif (macb_halt_tx(bp)) {\n-\t\tnetdev_err(bp-\u003edev, \"BUG: halt tx timed out\\n\");\n+\t\tnetdev_err(bp-\u003enetdev, \"BUG: halt tx timed out\\n\");\n \t\tmacb_writel(bp, NCR, macb_readl(bp, NCR) \u0026 (~MACB_BIT(TE)));\n \t\thalt_timeout = true;\n \t}\n@@ -1296,10 +1353,10 @@ static void macb_tx_error_task(struct work_struct *work)\n \t/* Treat frames in TX queue including the ones that caused the error.\n \t * Free transmit buffers in upper layer.\n \t */\n-\tfor (tail = queue-\u003etx_tail; tail != queue-\u003etx_head; tail++) {\n+\tfor (tail = txq-\u003etail; tail != txq-\u003ehead; tail++) {\n \t\tu32\tctrl;\n \n-\t\tdesc = macb_tx_desc(queue, tail);\n+\t\tdesc = macb_tx_desc(ctx, q, tail);\n \t\tctrl = desc-\u003ectrl;\n \t\ttx_skb = macb_tx_skb(queue, tail);\n \t\tskb = tx_skb-\u003eskb;\n@@ -1317,13 +1374,13 @@ static void macb_tx_error_task(struct work_struct *work)\n \t\t\t * since it's the only one written back by the hardware\n \t\t\t */\n \t\t\tif (!(ctrl \u0026 MACB_BIT(TX_BUF_EXHAUSTED))) {\n-\t\t\t\tnetdev_vdbg(bp-\u003edev, \"txerr skb %u (data %p) TX complete\\n\",\n-\t\t\t\t\t macb_tx_ring_wrap(bp, tail),\n+\t\t\t\tnetdev_vdbg(bp-\u003enetdev, \"txerr skb %u (data %p) TX complete\\n\",\n+\t\t\t\t\t macb_tx_ring_wrap(ctx, tail),\n \t\t\t\t\t skb-\u003edata);\n-\t\t\t\tbp-\u003edev-\u003estats.tx_packets++;\n+\t\t\t\tbp-\u003enetdev-\u003estats.tx_packets++;\n \t\t\t\tqueue-\u003estats.tx_packets++;\n \t\t\t\tpackets++;\n-\t\t\t\tbp-\u003edev-\u003estats.tx_bytes += skb-\u003elen;\n+\t\t\t\tbp-\u003enetdev-\u003estats.tx_bytes += skb-\u003elen;\n \t\t\t\tqueue-\u003estats.tx_bytes += skb-\u003elen;\n \t\t\t\tbytes += skb-\u003elen;\n \t\t\t}\n@@ -1333,7 +1390,7 @@ static void macb_tx_error_task(struct work_struct *work)\n \t\t\t * those. Statistics are updated by hardware.\n \t\t\t */\n \t\t\tif (ctrl \u0026 MACB_BIT(TX_BUF_EXHAUSTED))\n-\t\t\t\tnetdev_err(bp-\u003edev,\n+\t\t\t\tnetdev_err(bp-\u003enetdev,\n \t\t\t\t\t \"BUG: TX buffers exhausted mid-frame\\n\");\n \n \t\t\tdesc-\u003ectrl = ctrl | MACB_BIT(TX_USED);\n@@ -1342,22 +1399,22 @@ static void macb_tx_error_task(struct work_struct *work)\n \t\tmacb_tx_unmap(bp, tx_skb, 0);\n \t}\n \n-\tnetdev_tx_completed_queue(netdev_get_tx_queue(bp-\u003edev, queue_index),\n+\tnetdev_tx_completed_queue(netdev_get_tx_queue(bp-\u003enetdev, q),\n \t\t\t\t packets, bytes);\n \n \t/* Set end of TX queue */\n-\tdesc = macb_tx_desc(queue, 0);\n-\tmacb_set_addr(bp, desc, 0);\n+\tdesc = macb_tx_desc(ctx, q, 0);\n+\tmacb_set_addr(\u0026bp-\u003einfo, desc, 0);\n \tdesc-\u003ectrl = MACB_BIT(TX_USED);\n \n \t/* Make descriptor updates visible to hardware */\n \twmb();\n \n \t/* Reinitialize the TX desc queue */\n-\tqueue_writel(queue, TBQP, lower_32_bits(queue-\u003etx_ring_dma));\n+\tqueue_writel(queue, TBQP, lower_32_bits(txq-\u003ering_dma));\n \t/* Make TX ring reflect state of hardware */\n-\tqueue-\u003etx_head = 0;\n-\tqueue-\u003etx_tail = 0;\n+\ttxq-\u003ehead = 0;\n+\ttxq-\u003etail = 0;\n \n \t/* Housework before enabling TX IRQ */\n \tmacb_writel(bp, TSR, macb_readl(bp, TSR));\n@@ -1367,7 +1424,7 @@ static void macb_tx_error_task(struct work_struct *work)\n \t\tmacb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TE));\n \n \t/* Now we are ready to start transmission again */\n-\tnetif_tx_start_all_queues(bp-\u003edev);\n+\tnetif_tx_start_all_queues(bp-\u003enetdev);\n \tmacb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));\n \n \tspin_unlock_irqrestore(\u0026bp-\u003elock, flags);\n@@ -1407,7 +1464,9 @@ static bool ptp_one_step_sync(struct sk_buff *skb)\n static int macb_tx_complete(struct macb_queue *queue, int budget)\n {\n \tstruct macb *bp = queue-\u003ebp;\n-\tu16 queue_index = queue - bp-\u003equeues;\n+\tstruct macb_txq *txq = macb_txq(queue);\n+\tunsigned int q = queue - bp-\u003equeues;\n+\tstruct macb_context *ctx = bp-\u003ectx;\n \tunsigned long flags;\n \tunsigned int tail;\n \tunsigned int head;\n@@ -1415,14 +1474,14 @@ static int macb_tx_complete(struct macb_queue *queue, int budget)\n \tu32 bytes = 0;\n \n \tspin_lock_irqsave(\u0026queue-\u003etx_ptr_lock, flags);\n-\thead = queue-\u003etx_head;\n-\tfor (tail = queue-\u003etx_tail; tail != head \u0026\u0026 packets \u003c budget; tail++) {\n+\thead = txq-\u003ehead;\n+\tfor (tail = txq-\u003etail; tail != head \u0026\u0026 packets \u003c budget; tail++) {\n \t\tstruct macb_tx_skb\t*tx_skb;\n \t\tstruct sk_buff\t\t*skb;\n \t\tstruct macb_dma_desc\t*desc;\n \t\tu32\t\t\tctrl;\n \n-\t\tdesc = macb_tx_desc(queue, tail);\n+\t\tdesc = macb_tx_desc(ctx, q, tail);\n \n \t\t/* Make hw descriptor updates visible to CPU */\n \t\trmb();\n@@ -1446,12 +1505,12 @@ static int macb_tx_complete(struct macb_queue *queue, int budget)\n \t\t\t\t !ptp_one_step_sync(skb))\n \t\t\t\t\tgem_ptp_do_txstamp(bp, skb, desc);\n \n-\t\t\t\tnetdev_vdbg(bp-\u003edev, \"skb %u (data %p) TX complete\\n\",\n-\t\t\t\t\t macb_tx_ring_wrap(bp, tail),\n+\t\t\t\tnetdev_vdbg(bp-\u003enetdev, \"skb %u (data %p) TX complete\\n\",\n+\t\t\t\t\t macb_tx_ring_wrap(ctx, tail),\n \t\t\t\t\t skb-\u003edata);\n-\t\t\t\tbp-\u003edev-\u003estats.tx_packets++;\n+\t\t\t\tbp-\u003enetdev-\u003estats.tx_packets++;\n \t\t\t\tqueue-\u003estats.tx_packets++;\n-\t\t\t\tbp-\u003edev-\u003estats.tx_bytes += skb-\u003elen;\n+\t\t\t\tbp-\u003enetdev-\u003estats.tx_bytes += skb-\u003elen;\n \t\t\t\tqueue-\u003estats.tx_bytes += skb-\u003elen;\n \t\t\t\tpackets++;\n \t\t\t\tbytes += skb-\u003elen;\n@@ -1469,14 +1528,14 @@ static int macb_tx_complete(struct macb_queue *queue, int budget)\n \t\t}\n \t}\n \n-\tnetdev_tx_completed_queue(netdev_get_tx_queue(bp-\u003edev, queue_index),\n+\tnetdev_tx_completed_queue(netdev_get_tx_queue(bp-\u003enetdev, q),\n \t\t\t\t packets, bytes);\n \n-\tqueue-\u003etx_tail = tail;\n-\tif (__netif_subqueue_stopped(bp-\u003edev, queue_index) \u0026\u0026\n-\t CIRC_CNT(queue-\u003etx_head, queue-\u003etx_tail,\n-\t\t bp-\u003etx_ring_size) \u003c= MACB_TX_WAKEUP_THRESH(bp))\n-\t\tnetif_wake_subqueue(bp-\u003edev, queue_index);\n+\ttxq-\u003etail = tail;\n+\tif (__netif_subqueue_stopped(bp-\u003enetdev, q) \u0026\u0026\n+\t CIRC_CNT(txq-\u003ehead, txq-\u003etail,\n+\t\t bp-\u003ectx-\u003etx_ring_size) \u003c= MACB_TX_WAKEUP_THRESH(bp))\n+\t\tnetif_wake_subqueue(bp-\u003enetdev, q);\n \tspin_unlock_irqrestore(\u0026queue-\u003etx_ptr_lock, flags);\n \n \tif (packets)\n@@ -1485,51 +1544,53 @@ static int macb_tx_complete(struct macb_queue *queue, int budget)\n \treturn packets;\n }\n \n-static void gem_rx_refill(struct macb_queue *queue)\n+static void gem_rx_refill(struct macb_context *ctx, unsigned int q)\n {\n-\tunsigned int\t\tentry;\n-\tstruct sk_buff\t\t*skb;\n-\tdma_addr_t\t\tpaddr;\n-\tstruct macb *bp = queue-\u003ebp;\n+\tstruct device *dev = \u0026ctx-\u003einfo-\u003epdev-\u003edev;\n+\tstruct macb_rxq *rxq = \u0026ctx-\u003erxq[q];\n \tstruct macb_dma_desc *desc;\n+\tstruct sk_buff *skb;\n+\tunsigned int entry;\n+\tdma_addr_t paddr;\n \n-\twhile (CIRC_SPACE(queue-\u003erx_prepared_head, queue-\u003erx_tail,\n-\t\t\tbp-\u003erx_ring_size) \u003e 0) {\n-\t\tentry = macb_rx_ring_wrap(bp, queue-\u003erx_prepared_head);\n+\twhile (CIRC_SPACE(rxq-\u003eprepared_head, rxq-\u003etail,\n+\t\t\t ctx-\u003erx_ring_size) \u003e 0) {\n+\t\tentry = macb_rx_ring_wrap(ctx, rxq-\u003eprepared_head);\n \n \t\t/* Make hw descriptor updates visible to CPU */\n \t\trmb();\n \n-\t\tdesc = macb_rx_desc(queue, entry);\n+\t\tdesc = macb_rx_desc(ctx, q, entry);\n \n-\t\tif (!queue-\u003erx_skbuff[entry]) {\n+\t\tif (!rxq-\u003eskbuff[entry]) {\n \t\t\t/* allocate sk_buff for this free entry in ring */\n-\t\t\tskb = netdev_alloc_skb(bp-\u003edev, bp-\u003erx_buffer_size);\n+\t\t\tskb = netdev_alloc_skb(ctx-\u003einfo-\u003enetdev,\n+\t\t\t\t\t ctx-\u003erx_buffer_size);\n \t\t\tif (unlikely(!skb)) {\n-\t\t\t\tnetdev_err(bp-\u003edev,\n+\t\t\t\tnetdev_err(ctx-\u003einfo-\u003enetdev,\n \t\t\t\t\t \"Unable to allocate sk_buff\\n\");\n \t\t\t\tbreak;\n \t\t\t}\n \n \t\t\t/* now fill corresponding descriptor entry */\n-\t\t\tpaddr = dma_map_single(\u0026bp-\u003epdev-\u003edev, skb-\u003edata,\n-\t\t\t\t\t bp-\u003erx_buffer_size,\n+\t\t\tpaddr = dma_map_single(dev, skb-\u003edata,\n+\t\t\t\t\t ctx-\u003erx_buffer_size,\n \t\t\t\t\t DMA_FROM_DEVICE);\n-\t\t\tif (dma_mapping_error(\u0026bp-\u003epdev-\u003edev, paddr)) {\n+\t\t\tif (dma_mapping_error(dev, paddr)) {\n \t\t\t\tdev_kfree_skb(skb);\n \t\t\t\tbreak;\n \t\t\t}\n \n-\t\t\tqueue-\u003erx_skbuff[entry] = skb;\n+\t\t\trxq-\u003eskbuff[entry] = skb;\n \n-\t\t\tif (entry == bp-\u003erx_ring_size - 1)\n+\t\t\tif (entry == ctx-\u003erx_ring_size - 1)\n \t\t\t\tpaddr |= MACB_BIT(RX_WRAP);\n \t\t\tdesc-\u003ectrl = 0;\n \t\t\t/* Setting addr clears RX_USED and allows reception,\n \t\t\t * make sure ctrl is cleared first to avoid a race.\n \t\t\t */\n \t\t\tdma_wmb();\n-\t\t\tmacb_set_addr(bp, desc, paddr);\n+\t\t\tmacb_set_addr(ctx-\u003einfo, desc, paddr);\n \n \t\t\t/* Properly align Ethernet header.\n \t\t\t *\n@@ -1542,31 +1603,34 @@ static void gem_rx_refill(struct macb_queue *queue)\n \t\t\t * setting the low 2/3 bits.\n \t\t\t * It is 3 bits if HW_DMA_CAP_PTP, else 2 bits.\n \t\t\t */\n-\t\t\tif (!(bp-\u003ecaps \u0026 MACB_CAPS_RSC))\n+\t\t\tif (!(ctx-\u003einfo-\u003ecaps \u0026 MACB_CAPS_RSC))\n \t\t\t\tskb_reserve(skb, NET_IP_ALIGN);\n \t\t} else {\n \t\t\tdesc-\u003ectrl = 0;\n \t\t\tdma_wmb();\n \t\t\tdesc-\u003eaddr \u0026= ~MACB_BIT(RX_USED);\n \t\t}\n-\t\tqueue-\u003erx_prepared_head++;\n+\t\trxq-\u003eprepared_head++;\n \t}\n \n \t/* Make descriptor updates visible to hardware */\n \twmb();\n \n-\tnetdev_vdbg(bp-\u003edev, \"rx ring: queue: %p, prepared head %d, tail %d\\n\",\n-\t\t\tqueue, queue-\u003erx_prepared_head, queue-\u003erx_tail);\n+\tnetdev_vdbg(ctx-\u003einfo-\u003enetdev,\n+\t\t \"rx ring: queue: %u, prepared head %d, tail %d\\n\",\n+\t\t q, rxq-\u003eprepared_head, rxq-\u003etail);\n }\n \n /* Mark DMA descriptors from begin up to and not including end as unused */\n static void discard_partial_frame(struct macb_queue *queue, unsigned int begin,\n \t\t\t\t unsigned int end)\n {\n+\tunsigned int q = queue - queue-\u003ebp-\u003equeues;\n+\tstruct macb_context *ctx = queue-\u003ebp-\u003ectx;\n \tunsigned int frag;\n \n \tfor (frag = begin; frag != end; frag++) {\n-\t\tstruct macb_dma_desc *desc = macb_rx_desc(queue, frag);\n+\t\tstruct macb_dma_desc *desc = macb_rx_desc(ctx, q, frag);\n \n \t\tdesc-\u003eaddr \u0026= ~MACB_BIT(RX_USED);\n \t}\n@@ -1583,26 +1647,29 @@ static void discard_partial_frame(struct macb_queue *queue, unsigned int begin,\n static int gem_rx(struct macb_queue *queue, struct napi_struct *napi,\n \t\t int budget)\n {\n+\tunsigned int q = queue - queue-\u003ebp-\u003equeues;\n+\tstruct macb_context *ctx = queue-\u003ebp-\u003ectx;\n+\tstruct macb_rxq *rxq = macb_rxq(queue);\n \tstruct macb *bp = queue-\u003ebp;\n-\tunsigned int\t\tlen;\n-\tunsigned int\t\tentry;\n-\tstruct sk_buff\t\t*skb;\n-\tstruct macb_dma_desc\t*desc;\n-\tint\t\t\tcount = 0;\n+\tstruct macb_dma_desc *desc;\n+\tstruct sk_buff *skb;\n+\tunsigned int entry;\n+\tunsigned int len;\n+\tint count = 0;\n \n \twhile (count \u003c budget) {\n \t\tu32 ctrl;\n \t\tdma_addr_t addr;\n \t\tbool rxused;\n \n-\t\tentry = macb_rx_ring_wrap(bp, queue-\u003erx_tail);\n-\t\tdesc = macb_rx_desc(queue, entry);\n+\t\tentry = macb_rx_ring_wrap(ctx, rxq-\u003etail);\n+\t\tdesc = macb_rx_desc(ctx, q, entry);\n \n \t\t/* Make hw descriptor updates visible to CPU */\n \t\trmb();\n \n \t\trxused = (desc-\u003eaddr \u0026 MACB_BIT(RX_USED)) ? true : false;\n-\t\taddr = macb_get_addr(bp, desc);\n+\t\taddr = macb_get_addr(ctx, desc);\n \n \t\tif (!rxused)\n \t\t\tbreak;\n@@ -1612,50 +1679,50 @@ static int gem_rx(struct macb_queue *queue, struct napi_struct *napi,\n \n \t\tctrl = desc-\u003ectrl;\n \n-\t\tqueue-\u003erx_tail++;\n+\t\trxq-\u003etail++;\n \t\tcount++;\n \n \t\tif (!(ctrl \u0026 MACB_BIT(RX_SOF) \u0026\u0026 ctrl \u0026 MACB_BIT(RX_EOF))) {\n-\t\t\tnetdev_err(bp-\u003edev,\n+\t\t\tnetdev_err(bp-\u003enetdev,\n \t\t\t\t \"not whole frame pointed by descriptor\\n\");\n-\t\t\tbp-\u003edev-\u003estats.rx_dropped++;\n+\t\t\tbp-\u003enetdev-\u003estats.rx_dropped++;\n \t\t\tqueue-\u003estats.rx_dropped++;\n \t\t\tbreak;\n \t\t}\n-\t\tskb = queue-\u003erx_skbuff[entry];\n+\t\tskb = rxq-\u003eskbuff[entry];\n \t\tif (unlikely(!skb)) {\n-\t\t\tnetdev_err(bp-\u003edev,\n+\t\t\tnetdev_err(bp-\u003enetdev,\n \t\t\t\t \"inconsistent Rx descriptor chain\\n\");\n-\t\t\tbp-\u003edev-\u003estats.rx_dropped++;\n+\t\t\tbp-\u003enetdev-\u003estats.rx_dropped++;\n \t\t\tqueue-\u003estats.rx_dropped++;\n \t\t\tbreak;\n \t\t}\n \t\t/* now everything is ready for receiving packet */\n-\t\tqueue-\u003erx_skbuff[entry] = NULL;\n+\t\trxq-\u003eskbuff[entry] = NULL;\n \t\tlen = ctrl \u0026 bp-\u003erx_frm_len_mask;\n \n-\t\tnetdev_vdbg(bp-\u003edev, \"gem_rx %u (len %u)\\n\", entry, len);\n+\t\tnetdev_vdbg(bp-\u003enetdev, \"gem_rx %u (len %u)\\n\", entry, len);\n \n \t\tskb_put(skb, len);\n \t\tdma_unmap_single(\u0026bp-\u003epdev-\u003edev, addr,\n-\t\t\t\t bp-\u003erx_buffer_size, DMA_FROM_DEVICE);\n+\t\t\t\t bp-\u003ectx-\u003erx_buffer_size, DMA_FROM_DEVICE);\n \n-\t\tskb-\u003eprotocol = eth_type_trans(skb, bp-\u003edev);\n+\t\tskb-\u003eprotocol = eth_type_trans(skb, bp-\u003enetdev);\n \t\tskb_checksum_none_assert(skb);\n-\t\tif (bp-\u003edev-\u003efeatures \u0026 NETIF_F_RXCSUM \u0026\u0026\n-\t\t !(bp-\u003edev-\u003eflags \u0026 IFF_PROMISC) \u0026\u0026\n+\t\tif (bp-\u003enetdev-\u003efeatures \u0026 NETIF_F_RXCSUM \u0026\u0026\n+\t\t !(bp-\u003enetdev-\u003eflags \u0026 IFF_PROMISC) \u0026\u0026\n \t\t GEM_BFEXT(RX_CSUM, ctrl) \u0026 GEM_RX_CSUM_CHECKED_MASK)\n \t\t\tskb-\u003eip_summed = CHECKSUM_UNNECESSARY;\n \n-\t\tbp-\u003edev-\u003estats.rx_packets++;\n+\t\tbp-\u003enetdev-\u003estats.rx_packets++;\n \t\tqueue-\u003estats.rx_packets++;\n-\t\tbp-\u003edev-\u003estats.rx_bytes += skb-\u003elen;\n+\t\tbp-\u003enetdev-\u003estats.rx_bytes += skb-\u003elen;\n \t\tqueue-\u003estats.rx_bytes += skb-\u003elen;\n \n \t\tgem_ptp_do_rxstamp(bp, skb, desc);\n \n #if defined(DEBUG) \u0026\u0026 defined(VERBOSE_DEBUG)\n-\t\tnetdev_vdbg(bp-\u003edev, \"received skb of length %u, csum: %08x\\n\",\n+\t\tnetdev_vdbg(bp-\u003enetdev, \"received skb of length %u, csum: %08x\\n\",\n \t\t\t skb-\u003elen, skb-\u003ecsum);\n \t\tprint_hex_dump(KERN_DEBUG, \" mac: \", DUMP_PREFIX_ADDRESS, 16, 1,\n \t\t\t skb_mac_header(skb), 16, true);\n@@ -1666,7 +1733,7 @@ static int gem_rx(struct macb_queue *queue, struct napi_struct *napi,\n \t\tnapi_gro_receive(napi, skb);\n \t}\n \n-\tgem_rx_refill(queue);\n+\tgem_rx_refill(ctx, q);\n \n \treturn count;\n }\n@@ -1674,19 +1741,21 @@ static int gem_rx(struct macb_queue *queue, struct napi_struct *napi,\n static int macb_rx_frame(struct macb_queue *queue, struct napi_struct *napi,\n \t\t\t unsigned int first_frag, unsigned int last_frag)\n {\n-\tunsigned int len;\n-\tunsigned int frag;\n+\tunsigned int q = queue - queue-\u003ebp-\u003equeues;\n+\tstruct macb_context *ctx = queue-\u003ebp-\u003ectx;\n+\tstruct macb *bp = queue-\u003ebp;\n+\tstruct macb_dma_desc *desc;\n \tunsigned int offset;\n \tstruct sk_buff *skb;\n-\tstruct macb_dma_desc *desc;\n-\tstruct macb *bp = queue-\u003ebp;\n+\tunsigned int frag;\n+\tunsigned int len;\n \n-\tdesc = macb_rx_desc(queue, last_frag);\n+\tdesc = macb_rx_desc(ctx, q, last_frag);\n \tlen = desc-\u003ectrl \u0026 bp-\u003erx_frm_len_mask;\n \n-\tnetdev_vdbg(bp-\u003edev, \"macb_rx_frame frags %u - %u (len %u)\\n\",\n-\t\tmacb_rx_ring_wrap(bp, first_frag),\n-\t\tmacb_rx_ring_wrap(bp, last_frag), len);\n+\tnetdev_vdbg(bp-\u003enetdev, \"macb_rx_frame frags %u - %u (len %u)\\n\",\n+\t\t macb_rx_ring_wrap(ctx, first_frag),\n+\t\t macb_rx_ring_wrap(ctx, last_frag), len);\n \n \t/* The ethernet header starts NET_IP_ALIGN bytes into the\n \t * first buffer. Since the header is 14 bytes, this makes the\n@@ -1696,11 +1765,11 @@ static int macb_rx_frame(struct macb_queue *queue, struct napi_struct *napi,\n \t * the two padding bytes into the skb so that we avoid hitting\n \t * the slowpath in memcpy(), and pull them off afterwards.\n \t */\n-\tskb = netdev_alloc_skb(bp-\u003edev, len + NET_IP_ALIGN);\n+\tskb = netdev_alloc_skb(bp-\u003enetdev, len + NET_IP_ALIGN);\n \tif (!skb) {\n-\t\tbp-\u003edev-\u003estats.rx_dropped++;\n+\t\tbp-\u003enetdev-\u003estats.rx_dropped++;\n \t\tfor (frag = first_frag; ; frag++) {\n-\t\t\tdesc = macb_rx_desc(queue, frag);\n+\t\t\tdesc = macb_rx_desc(ctx, q, frag);\n \t\t\tdesc-\u003eaddr \u0026= ~MACB_BIT(RX_USED);\n \t\t\tif (frag == last_frag)\n \t\t\t\tbreak;\n@@ -1718,7 +1787,7 @@ static int macb_rx_frame(struct macb_queue *queue, struct napi_struct *napi,\n \tskb_put(skb, len);\n \n \tfor (frag = first_frag; ; frag++) {\n-\t\tunsigned int frag_len = bp-\u003erx_buffer_size;\n+\t\tunsigned int frag_len = bp-\u003ectx-\u003erx_buffer_size;\n \n \t\tif (offset + frag_len \u003e len) {\n \t\t\tif (unlikely(frag != last_frag)) {\n@@ -1730,8 +1799,8 @@ static int macb_rx_frame(struct macb_queue *queue, struct napi_struct *napi,\n \t\tskb_copy_to_linear_data_offset(skb, offset,\n \t\t\t\t\t macb_rx_buffer(queue, frag),\n \t\t\t\t\t frag_len);\n-\t\toffset += bp-\u003erx_buffer_size;\n-\t\tdesc = macb_rx_desc(queue, frag);\n+\t\toffset += bp-\u003ectx-\u003erx_buffer_size;\n+\t\tdesc = macb_rx_desc(ctx, q, frag);\n \t\tdesc-\u003eaddr \u0026= ~MACB_BIT(RX_USED);\n \n \t\tif (frag == last_frag)\n@@ -1742,46 +1811,49 @@ static int macb_rx_frame(struct macb_queue *queue, struct napi_struct *napi,\n \twmb();\n \n \t__skb_pull(skb, NET_IP_ALIGN);\n-\tskb-\u003eprotocol = eth_type_trans(skb, bp-\u003edev);\n+\tskb-\u003eprotocol = eth_type_trans(skb, bp-\u003enetdev);\n \n-\tbp-\u003edev-\u003estats.rx_packets++;\n-\tbp-\u003edev-\u003estats.rx_bytes += skb-\u003elen;\n-\tnetdev_vdbg(bp-\u003edev, \"received skb of length %u, csum: %08x\\n\",\n+\tbp-\u003enetdev-\u003estats.rx_packets++;\n+\tbp-\u003enetdev-\u003estats.rx_bytes += skb-\u003elen;\n+\tnetdev_vdbg(bp-\u003enetdev, \"received skb of length %u, csum: %08x\\n\",\n \t\t skb-\u003elen, skb-\u003ecsum);\n \tnapi_gro_receive(napi, skb);\n \n \treturn 0;\n }\n \n-static inline void macb_init_rx_ring(struct macb_queue *queue)\n+static inline void macb_init_rx_ring(struct macb_context *ctx, unsigned int q)\n {\n-\tstruct macb *bp = queue-\u003ebp;\n-\tdma_addr_t addr;\n+\tstruct macb_rxq *rxq = \u0026ctx-\u003erxq[q];\n \tstruct macb_dma_desc *desc = NULL;\n+\tdma_addr_t addr;\n \tint i;\n \n-\taddr = queue-\u003erx_buffers_dma;\n-\tfor (i = 0; i \u003c bp-\u003erx_ring_size; i++) {\n-\t\tdesc = macb_rx_desc(queue, i);\n-\t\tmacb_set_addr(bp, desc, addr);\n+\taddr = rxq-\u003ebuffers_dma;\n+\tfor (i = 0; i \u003c ctx-\u003erx_ring_size; i++) {\n+\t\tdesc = macb_rx_desc(ctx, q, i);\n+\t\tmacb_set_addr(ctx-\u003einfo, desc, addr);\n \t\tdesc-\u003ectrl = 0;\n-\t\taddr += bp-\u003erx_buffer_size;\n+\t\taddr += ctx-\u003erx_buffer_size;\n \t}\n \tdesc-\u003eaddr |= MACB_BIT(RX_WRAP);\n-\tqueue-\u003erx_tail = 0;\n+\trxq-\u003etail = 0;\n }\n \n static int macb_rx(struct macb_queue *queue, struct napi_struct *napi,\n \t\t int budget)\n {\n+\tunsigned int q = queue - queue-\u003ebp-\u003equeues;\n+\tstruct macb_context *ctx = queue-\u003ebp-\u003ectx;\n+\tstruct macb_rxq *rxq = macb_rxq(queue);\n \tstruct macb *bp = queue-\u003ebp;\n \tbool reset_rx_queue = false;\n-\tint received = 0;\n-\tunsigned int tail;\n \tint first_frag = -1;\n+\tunsigned int tail;\n+\tint received = 0;\n \n-\tfor (tail = queue-\u003erx_tail; budget \u003e 0; tail++) {\n-\t\tstruct macb_dma_desc *desc = macb_rx_desc(queue, tail);\n+\tfor (tail = rxq-\u003etail; budget \u003e 0; tail++) {\n+\t\tstruct macb_dma_desc *desc = macb_rx_desc(ctx, q, tail);\n \t\tu32 ctrl;\n \n \t\t/* Make hw descriptor updates visible to CPU */\n@@ -1826,15 +1898,15 @@ static int macb_rx(struct macb_queue *queue, struct napi_struct *napi,\n \t\tunsigned long flags;\n \t\tu32 ctrl;\n \n-\t\tnetdev_err(bp-\u003edev, \"RX queue corruption: reset it\\n\");\n+\t\tnetdev_err(bp-\u003enetdev, \"RX queue corruption: reset it\\n\");\n \n \t\tspin_lock_irqsave(\u0026bp-\u003elock, flags);\n \n \t\tctrl = macb_readl(bp, NCR);\n \t\tmacb_writel(bp, NCR, ctrl \u0026 ~MACB_BIT(RE));\n \n-\t\tmacb_init_rx_ring(queue);\n-\t\tqueue_writel(queue, RBQP, queue-\u003erx_ring_dma);\n+\t\tmacb_init_rx_ring(ctx, q);\n+\t\tqueue_writel(queue, RBQP, rxq-\u003ering_dma);\n \n \t\tmacb_writel(bp, NCR, ctrl | MACB_BIT(RE));\n \n@@ -1843,21 +1915,23 @@ static int macb_rx(struct macb_queue *queue, struct napi_struct *napi,\n \t}\n \n \tif (first_frag != -1)\n-\t\tqueue-\u003erx_tail = first_frag;\n+\t\trxq-\u003etail = first_frag;\n \telse\n-\t\tqueue-\u003erx_tail = tail;\n+\t\trxq-\u003etail = tail;\n \n \treturn received;\n }\n \n static bool macb_rx_pending(struct macb_queue *queue)\n {\n-\tstruct macb *bp = queue-\u003ebp;\n-\tunsigned int\t\tentry;\n-\tstruct macb_dma_desc\t*desc;\n+\tunsigned int q = queue - queue-\u003ebp-\u003equeues;\n+\tstruct macb_context *ctx = queue-\u003ebp-\u003ectx;\n+\tstruct macb_rxq *rxq = macb_rxq(queue);\n+\tstruct macb_dma_desc *desc;\n+\tunsigned int entry;\n \n-\tentry = macb_rx_ring_wrap(bp, queue-\u003erx_tail);\n-\tdesc = macb_rx_desc(queue, entry);\n+\tentry = macb_rx_ring_wrap(ctx, rxq-\u003etail);\n+\tdesc = macb_rx_desc(ctx, q, entry);\n \n \t/* Make hw descriptor updates visible to CPU */\n \trmb();\n@@ -1873,7 +1947,7 @@ static int macb_rx_poll(struct napi_struct *napi, int budget)\n \n \twork_done = bp-\u003emacbgem_ops.mog_rx(queue, napi, budget);\n \n-\tnetdev_vdbg(bp-\u003edev, \"RX poll: queue = %u, work_done = %d, budget = %d\\n\",\n+\tnetdev_vdbg(bp-\u003enetdev, \"RX poll: queue = %u, work_done = %d, budget = %d\\n\",\n \t\t (unsigned int)(queue - bp-\u003equeues), work_done, budget);\n \n \tif (work_done \u003c budget \u0026\u0026 napi_complete_done(napi, work_done)) {\n@@ -1892,7 +1966,7 @@ static int macb_rx_poll(struct napi_struct *napi, int budget)\n \t\tif (macb_rx_pending(queue)) {\n \t\t\tqueue_writel(queue, IDR, bp-\u003erx_intr_mask);\n \t\t\tmacb_queue_isr_clear(bp, queue, MACB_BIT(RCOMP));\n-\t\t\tnetdev_vdbg(bp-\u003edev, \"poll: packets pending, reschedule\\n\");\n+\t\t\tnetdev_vdbg(bp-\u003enetdev, \"poll: packets pending, reschedule\\n\");\n \t\t\tnapi_schedule(napi);\n \t\t}\n \t}\n@@ -1904,18 +1978,20 @@ static int macb_rx_poll(struct napi_struct *napi, int budget)\n \n static void macb_tx_restart(struct macb_queue *queue)\n {\n+\tstruct macb_context *ctx = queue-\u003ebp-\u003ectx;\n+\tstruct macb_txq *txq = macb_txq(queue);\n \tstruct macb *bp = queue-\u003ebp;\n \tunsigned int head_idx, tbqp;\n \tunsigned long flags;\n \n \tspin_lock_irqsave(\u0026queue-\u003etx_ptr_lock, flags);\n \n-\tif (queue-\u003etx_head == queue-\u003etx_tail)\n+\tif (txq-\u003ehead == txq-\u003etail)\n \t\tgoto out_tx_ptr_unlock;\n \n-\ttbqp = queue_readl(queue, TBQP) / macb_dma_desc_get_size(bp);\n-\ttbqp = macb_adj_dma_desc_idx(bp, macb_tx_ring_wrap(bp, tbqp));\n-\thead_idx = macb_adj_dma_desc_idx(bp, macb_tx_ring_wrap(bp, queue-\u003etx_head));\n+\ttbqp = queue_readl(queue, TBQP) / macb_dma_desc_get_size(ctx-\u003einfo);\n+\ttbqp = macb_adj_dma_desc_idx(ctx, macb_tx_ring_wrap(ctx, tbqp));\n+\thead_idx = macb_adj_dma_desc_idx(ctx, macb_tx_ring_wrap(ctx, txq-\u003ehead));\n \n \tif (tbqp == head_idx)\n \t\tgoto out_tx_ptr_unlock;\n@@ -1930,15 +2006,18 @@ static void macb_tx_restart(struct macb_queue *queue)\n \n static bool macb_tx_complete_pending(struct macb_queue *queue)\n {\n+\tunsigned int q = queue - queue-\u003ebp-\u003equeues;\n+\tstruct macb_context *ctx = queue-\u003ebp-\u003ectx;\n+\tstruct macb_txq *txq = macb_txq(queue);\n \tbool retval = false;\n \tunsigned long flags;\n \n \tspin_lock_irqsave(\u0026queue-\u003etx_ptr_lock, flags);\n-\tif (queue-\u003etx_head != queue-\u003etx_tail) {\n+\tif (txq-\u003ehead != txq-\u003etail) {\n \t\t/* Make hw descriptor updates visible to CPU */\n \t\trmb();\n \n-\t\tif (macb_tx_desc(queue, queue-\u003etx_tail)-\u003ectrl \u0026 MACB_BIT(TX_USED))\n+\t\tif (macb_tx_desc(ctx, q, txq-\u003etail)-\u003ectrl \u0026 MACB_BIT(TX_USED))\n \t\t\tretval = true;\n \t}\n \tspin_unlock_irqrestore(\u0026queue-\u003etx_ptr_lock, flags);\n@@ -1956,11 +2035,11 @@ static int macb_tx_poll(struct napi_struct *napi, int budget)\n \trmb(); // ensure txubr_pending is up to date\n \tif (queue-\u003etxubr_pending) {\n \t\tqueue-\u003etxubr_pending = false;\n-\t\tnetdev_vdbg(bp-\u003edev, \"poll: tx restart\\n\");\n+\t\tnetdev_vdbg(bp-\u003enetdev, \"poll: tx restart\\n\");\n \t\tmacb_tx_restart(queue);\n \t}\n \n-\tnetdev_vdbg(bp-\u003edev, \"TX poll: queue = %u, work_done = %d, budget = %d\\n\",\n+\tnetdev_vdbg(bp-\u003enetdev, \"TX poll: queue = %u, work_done = %d, budget = %d\\n\",\n \t\t (unsigned int)(queue - bp-\u003equeues), work_done, budget);\n \n \tif (work_done \u003c budget \u0026\u0026 napi_complete_done(napi, work_done)) {\n@@ -1979,7 +2058,7 @@ static int macb_tx_poll(struct napi_struct *napi, int budget)\n \t\tif (macb_tx_complete_pending(queue)) {\n \t\t\tqueue_writel(queue, IDR, MACB_BIT(TCOMP));\n \t\t\tmacb_queue_isr_clear(bp, queue, MACB_BIT(TCOMP));\n-\t\t\tnetdev_vdbg(bp-\u003edev, \"TX poll: packets pending, reschedule\\n\");\n+\t\t\tnetdev_vdbg(bp-\u003enetdev, \"TX poll: packets pending, reschedule\\n\");\n \t\t\tnapi_schedule(napi);\n \t\t}\n \t}\n@@ -1990,7 +2069,8 @@ static int macb_tx_poll(struct napi_struct *napi, int budget)\n static void macb_hresp_error_task(struct work_struct *work)\n {\n \tstruct macb *bp = from_work(bp, work, hresp_err_bh_work);\n-\tstruct net_device *dev = bp-\u003edev;\n+\tstruct net_device *netdev = bp-\u003enetdev;\n+\tstruct macb_context *ctx = bp-\u003ectx;\n \tstruct macb_queue *queue;\n \tunsigned int q;\n \tu32 ctrl;\n@@ -2004,10 +2084,10 @@ static void macb_hresp_error_task(struct work_struct *work)\n \tctrl \u0026= ~(MACB_BIT(RE) | MACB_BIT(TE));\n \tmacb_writel(bp, NCR, ctrl);\n \n-\tnetif_tx_stop_all_queues(dev);\n-\tnetif_carrier_off(dev);\n+\tnetif_tx_stop_all_queues(netdev);\n+\tnetif_carrier_off(netdev);\n \n-\tbp-\u003emacbgem_ops.mog_init_rings(bp);\n+\tbp-\u003emacbgem_ops.mog_init_rings(ctx);\n \n \t/* Initialize TX and RX buffers */\n \tmacb_init_buffers(bp);\n@@ -2022,8 +2102,8 @@ static void macb_hresp_error_task(struct work_struct *work)\n \tctrl |= MACB_BIT(RE) | MACB_BIT(TE);\n \tmacb_writel(bp, NCR, ctrl);\n \n-\tnetif_carrier_on(dev);\n-\tnetif_tx_start_all_queues(dev);\n+\tnetif_carrier_on(netdev);\n+\tnetif_tx_start_all_queues(netdev);\n }\n \n static void macb_wol_interrupt(struct macb_queue *queue, u32 status)\n@@ -2032,7 +2112,7 @@ static void macb_wol_interrupt(struct macb_queue *queue, u32 status)\n \n \tqueue_writel(queue, IDR, MACB_BIT(WOL));\n \tmacb_writel(bp, WOL, 0);\n-\tnetdev_vdbg(bp-\u003edev, \"MACB WoL: queue = %u, isr = 0x%08lx\\n\",\n+\tnetdev_vdbg(bp-\u003enetdev, \"MACB WoL: queue = %u, isr = 0x%08lx\\n\",\n \t\t (unsigned int)(queue - bp-\u003equeues),\n \t\t (unsigned long)status);\n \tmacb_queue_isr_clear(bp, queue, MACB_BIT(WOL));\n@@ -2045,7 +2125,7 @@ static void gem_wol_interrupt(struct macb_queue *queue, u32 status)\n \n \tqueue_writel(queue, IDR, GEM_BIT(WOL));\n \tgem_writel(bp, WOL, 0);\n-\tnetdev_vdbg(bp-\u003edev, \"GEM WoL: queue = %u, isr = 0x%08lx\\n\",\n+\tnetdev_vdbg(bp-\u003enetdev, \"GEM WoL: queue = %u, isr = 0x%08lx\\n\",\n \t\t (unsigned int)(queue - bp-\u003equeues),\n \t\t (unsigned long)status);\n \tmacb_queue_isr_clear(bp, queue, GEM_BIT(WOL));\n@@ -2055,10 +2135,10 @@ static void gem_wol_interrupt(struct macb_queue *queue, u32 status)\n static int macb_interrupt_misc(struct macb_queue *queue, u32 status)\n {\n \tstruct macb *bp = queue-\u003ebp;\n-\tstruct net_device *dev;\n+\tstruct net_device *netdev;\n \tu32 ctrl;\n \n-\tdev = bp-\u003edev;\n+\tnetdev = bp-\u003enetdev;\n \n \tif (unlikely(status \u0026 (MACB_TX_ERR_FLAGS))) {\n \t\tqueue_writel(queue, IDR, MACB_TX_INT_FLAGS);\n@@ -2089,7 +2169,7 @@ static int macb_interrupt_misc(struct macb_queue *queue, u32 status)\n \tif (status \u0026 MACB_BIT(ISR_ROVR)) {\n \t\t/* We missed at least one packet */\n \t\tspin_lock(\u0026bp-\u003estats_lock);\n-\t\tif (macb_is_gem(bp))\n+\t\tif (macb_is_gem(\u0026bp-\u003einfo))\n \t\t\tbp-\u003ehw_stats.gem.rx_overruns++;\n \t\telse\n \t\t\tbp-\u003ehw_stats.macb.rx_overruns++;\n@@ -2099,11 +2179,11 @@ static int macb_interrupt_misc(struct macb_queue *queue, u32 status)\n \n \tif (status \u0026 MACB_BIT(HRESP)) {\n \t\tqueue_work(system_bh_wq, \u0026bp-\u003ehresp_err_bh_work);\n-\t\tnetdev_err(dev, \"DMA bus error: HRESP not OK\\n\");\n+\t\tnetdev_err(netdev, \"DMA bus error: HRESP not OK\\n\");\n \t\tmacb_queue_isr_clear(bp, queue, MACB_BIT(HRESP));\n \t}\n \n-\tif (macb_is_gem(bp)) {\n+\tif (macb_is_gem(\u0026bp-\u003einfo)) {\n \t\tif (status \u0026 GEM_BIT(WOL))\n \t\t\tgem_wol_interrupt(queue, status);\n \t} else {\n@@ -2118,25 +2198,33 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)\n {\n \tstruct macb_queue *queue = dev_id;\n \tstruct macb *bp = queue-\u003ebp;\n-\tstruct net_device *dev = bp-\u003edev;\n+\tstruct net_device *netdev = bp-\u003enetdev;\n \tu32 status;\n \n-\tstatus = queue_readl(queue, ISR);\n-\n-\tif (unlikely(!status))\n-\t\treturn IRQ_NONE;\n+\t/* detect spurious interrupts without grabbing bp-\u003elock */\n+\tif (bp-\u003ecaps \u0026 MACB_CAPS_ISR_CLEAR_ON_WRITE) {\n+\t\tstatus = queue_readl(queue, ISR);\n+\t\tif (unlikely(!status))\n+\t\t\treturn IRQ_NONE;\n+\t}\n \n \tspin_lock(\u0026bp-\u003elock);\n \n+\tstatus = queue_readl(queue, ISR);\n+\tif (unlikely(!status)) {\n+\t\tspin_unlock(\u0026bp-\u003elock);\n+\t\treturn IRQ_NONE;\n+\t}\n+\n \twhile (status) {\n \t\t/* close possible race with dev_close */\n-\t\tif (unlikely(!netif_running(dev))) {\n+\t\tif (unlikely(!netif_running(netdev))) {\n \t\t\tqueue_writel(queue, IDR, -1);\n \t\t\tmacb_queue_isr_clear(bp, queue, -1);\n \t\t\tbreak;\n \t\t}\n \n-\t\tnetdev_vdbg(bp-\u003edev, \"queue = %u, isr = 0x%08lx\\n\",\n+\t\tnetdev_vdbg(netdev, \"queue = %u, isr = 0x%08lx\\n\",\n \t\t\t (unsigned int)(queue - bp-\u003equeues),\n \t\t\t (unsigned long)status);\n \n@@ -2181,16 +2269,16 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)\n /* Polling receive - used by netconsole and other diagnostic tools\n * to allow network i/o with interrupts disabled.\n */\n-static void macb_poll_controller(struct net_device *dev)\n+static void macb_poll_controller(struct net_device *netdev)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tstruct macb_queue *queue;\n \tunsigned long flags;\n \tunsigned int q;\n \n \tlocal_irq_save(flags);\n \tfor (q = 0, queue = bp-\u003equeues; q \u003c bp-\u003enum_queues; ++q, ++queue)\n-\t\tmacb_interrupt(dev-\u003eirq, queue);\n+\t\tmacb_interrupt(netdev-\u003eirq, queue);\n \tlocal_irq_restore(flags);\n }\n #endif\n@@ -2200,9 +2288,12 @@ static unsigned int macb_tx_map(struct macb *bp,\n \t\t\t\tstruct sk_buff *skb,\n \t\t\t\tunsigned int hdrlen)\n {\n+\tstruct macb_txq *txq = macb_txq(queue);\n \tunsigned int f, nr_frags = skb_shinfo(skb)-\u003enr_frags;\n-\tunsigned int len, i, tx_head = queue-\u003etx_head;\n+\tunsigned int len, i, tx_head = txq-\u003ehead;\n \tu32 ctrl, lso_ctrl = 0, seq_ctrl = 0;\n+\tunsigned int q = queue - bp-\u003equeues;\n+\tstruct macb_context *ctx = bp-\u003ectx;\n \tunsigned int eof = 1, mss_mfs = 0;\n \tstruct macb_tx_skb *tx_skb = NULL;\n \tstruct macb_dma_desc *desc;\n@@ -2277,7 +2368,7 @@ static unsigned int macb_tx_map(struct macb *bp,\n \n \t/* Should never happen */\n \tif (unlikely(!tx_skb)) {\n-\t\tnetdev_err(bp-\u003edev, \"BUG! empty skb!\\n\");\n+\t\tnetdev_err(bp-\u003enetdev, \"BUG! empty skb!\\n\");\n \t\treturn 0;\n \t}\n \n@@ -2293,7 +2384,7 @@ static unsigned int macb_tx_map(struct macb *bp,\n \t */\n \ti = tx_head;\n \tctrl = MACB_BIT(TX_USED);\n-\tdesc = macb_tx_desc(queue, i);\n+\tdesc = macb_tx_desc(ctx, q, i);\n \tdesc-\u003ectrl = ctrl;\n \n \tif (lso_ctrl) {\n@@ -2314,21 +2405,22 @@ static unsigned int macb_tx_map(struct macb *bp,\n \tdo {\n \t\ti--;\n \t\ttx_skb = macb_tx_skb(queue, i);\n-\t\tdesc = macb_tx_desc(queue, i);\n+\t\tdesc = macb_tx_desc(ctx, q, i);\n \n \t\tctrl = (u32)tx_skb-\u003esize;\n \t\tif (eof) {\n \t\t\tctrl |= MACB_BIT(TX_LAST);\n \t\t\teof = 0;\n \t\t}\n-\t\tif (unlikely(macb_tx_ring_wrap(bp, i) == bp-\u003etx_ring_size - 1))\n+\t\tif (unlikely(macb_tx_ring_wrap(ctx, i) ==\n+\t\t\t\tbp-\u003ectx-\u003etx_ring_size - 1))\n \t\t\tctrl |= MACB_BIT(TX_WRAP);\n \n \t\t/* First descriptor is header descriptor */\n-\t\tif (i == queue-\u003etx_head) {\n+\t\tif (i == txq-\u003ehead) {\n \t\t\tctrl |= MACB_BF(TX_LSO, lso_ctrl);\n \t\t\tctrl |= MACB_BF(TX_TCP_SEQ_SRC, seq_ctrl);\n-\t\t\tif ((bp-\u003edev-\u003efeatures \u0026 NETIF_F_HW_CSUM) \u0026\u0026\n+\t\t\tif ((bp-\u003enetdev-\u003efeatures \u0026 NETIF_F_HW_CSUM) \u0026\u0026\n \t\t\t skb-\u003eip_summed != CHECKSUM_PARTIAL \u0026\u0026 !lso_ctrl \u0026\u0026\n \t\t\t !ptp_one_step_sync(skb))\n \t\t\t\tctrl |= MACB_BIT(TX_NOCRC);\n@@ -2339,22 +2431,22 @@ static unsigned int macb_tx_map(struct macb *bp,\n \t\t\tctrl |= MACB_BF(MSS_MFS, mss_mfs);\n \n \t\t/* Set TX buffer descriptor */\n-\t\tmacb_set_addr(bp, desc, tx_skb-\u003emapping);\n+\t\tmacb_set_addr(\u0026bp-\u003einfo, desc, tx_skb-\u003emapping);\n \t\t/* desc-\u003eaddr must be visible to hardware before clearing\n \t\t * 'TX_USED' bit in desc-\u003ectrl.\n \t\t */\n \t\twmb();\n \t\tdesc-\u003ectrl = ctrl;\n-\t} while (i != queue-\u003etx_head);\n+\t} while (i != txq-\u003ehead);\n \n-\tqueue-\u003etx_head = tx_head;\n+\ttxq-\u003ehead = tx_head;\n \n \treturn 0;\n \n dma_error:\n-\tnetdev_err(bp-\u003edev, \"TX DMA map failed\\n\");\n+\tnetdev_err(bp-\u003enetdev, \"TX DMA map failed\\n\");\n \n-\tfor (i = queue-\u003etx_head; i != tx_head; i++) {\n+\tfor (i = txq-\u003ehead; i != tx_head; i++) {\n \t\ttx_skb = macb_tx_skb(queue, i);\n \n \t\tmacb_tx_unmap(bp, tx_skb, 0);\n@@ -2364,7 +2456,7 @@ static unsigned int macb_tx_map(struct macb *bp,\n }\n \n static netdev_features_t macb_features_check(struct sk_buff *skb,\n-\t\t\t\t\t struct net_device *dev,\n+\t\t\t\t\t struct net_device *netdev,\n \t\t\t\t\t netdev_features_t features)\n {\n \tunsigned int nr_frags, f;\n@@ -2416,7 +2508,7 @@ static inline int macb_clear_csum(struct sk_buff *skb)\n \treturn 0;\n }\n \n-static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)\n+static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *netdev)\n {\n \tbool cloned = skb_cloned(*skb) || skb_header_cloned(*skb) ||\n \t\t skb_is_nonlinear(*skb);\n@@ -2425,7 +2517,7 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)\n \tstruct sk_buff *nskb;\n \tu32 fcs;\n \n-\tif (!(ndev-\u003efeatures \u0026 NETIF_F_HW_CSUM) ||\n+\tif (!(netdev-\u003efeatures \u0026 NETIF_F_HW_CSUM) ||\n \t !((*skb)-\u003eip_summed != CHECKSUM_PARTIAL) ||\n \t skb_shinfo(*skb)-\u003egso_size || ptp_one_step_sync(*skb))\n \t\treturn 0;\n@@ -2467,28 +2559,30 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)\n \treturn 0;\n }\n \n-static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)\n+static netdev_tx_t macb_start_xmit(struct sk_buff *skb,\n+\t\t\t\t struct net_device *netdev)\n {\n-\tu16 queue_index = skb_get_queue_mapping(skb);\n-\tstruct macb *bp = netdev_priv(dev);\n-\tstruct macb_queue *queue = \u0026bp-\u003equeues[queue_index];\n+\tstruct macb *bp = netdev_priv(netdev);\n+\tunsigned int q = skb_get_queue_mapping(skb);\n \tunsigned int desc_cnt, nr_frags, frag_size, f;\n+\tstruct macb_queue *queue = \u0026bp-\u003equeues[q];\n+\tstruct macb_txq *txq = macb_txq(queue);\n+\tnetdev_tx_t ret = NETDEV_TX_OK;\n \tunsigned int hdrlen;\n \tunsigned long flags;\n \tbool is_lso;\n-\tnetdev_tx_t ret = NETDEV_TX_OK;\n \n \tif (macb_clear_csum(skb)) {\n \t\tdev_kfree_skb_any(skb);\n \t\treturn ret;\n \t}\n \n-\tif (macb_pad_and_fcs(\u0026skb, dev)) {\n+\tif (macb_pad_and_fcs(\u0026skb, netdev)) {\n \t\tdev_kfree_skb_any(skb);\n \t\treturn ret;\n \t}\n \n-\tif (macb_dma_ptp(bp) \u0026\u0026\n+\tif (macb_dma_ptp(\u0026bp-\u003einfo) \u0026\u0026\n \t (skb_shinfo(skb)-\u003etx_flags \u0026 SKBTX_HW_TSTAMP))\n \t\tskb_shinfo(skb)-\u003etx_flags |= SKBTX_IN_PROGRESS;\n \n@@ -2502,7 +2596,7 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)\n \t\telse\n \t\t\thdrlen = skb_tcp_all_headers(skb);\n \t\tif (skb_headlen(skb) \u003c hdrlen) {\n-\t\t\tnetdev_err(bp-\u003edev, \"Error - LSO headers fragmented!!!\\n\");\n+\t\t\tnetdev_err(bp-\u003enetdev, \"Error - LSO headers fragmented!!!\\n\");\n \t\t\t/* if this is required, would need to copy to single buffer */\n \t\t\treturn NETDEV_TX_BUSY;\n \t\t}\n@@ -2510,9 +2604,9 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)\n \t\thdrlen = umin(skb_headlen(skb), bp-\u003emax_tx_length);\n \n #if defined(DEBUG) \u0026\u0026 defined(VERBOSE_DEBUG)\n-\tnetdev_vdbg(bp-\u003edev,\n-\t\t \"start_xmit: queue %hu len %u head %p data %p tail %p end %p\\n\",\n-\t\t queue_index, skb-\u003elen, skb-\u003ehead, skb-\u003edata,\n+\tnetdev_vdbg(bp-\u003enetdev,\n+\t\t \"start_xmit: queue %u len %u head %p data %p tail %p end %p\\n\",\n+\t\t q, skb-\u003elen, skb-\u003ehead, skb-\u003edata,\n \t\t skb_tail_pointer(skb), skb_end_pointer(skb));\n \tprint_hex_dump(KERN_DEBUG, \"data: \", DUMP_PREFIX_OFFSET, 16, 1,\n \t\t skb-\u003edata, 16, true);\n@@ -2536,11 +2630,11 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)\n \tspin_lock_irqsave(\u0026queue-\u003etx_ptr_lock, flags);\n \n \t/* This is a hard error, log it. */\n-\tif (CIRC_SPACE(queue-\u003etx_head, queue-\u003etx_tail,\n-\t\t bp-\u003etx_ring_size) \u003c desc_cnt) {\n-\t\tnetif_stop_subqueue(dev, queue_index);\n-\t\tnetdev_dbg(bp-\u003edev, \"tx_head = %u, tx_tail = %u\\n\",\n-\t\t\t queue-\u003etx_head, queue-\u003etx_tail);\n+\tif (CIRC_SPACE(txq-\u003ehead, txq-\u003etail,\n+\t\t bp-\u003ectx-\u003etx_ring_size) \u003c desc_cnt) {\n+\t\tnetif_stop_subqueue(netdev, q);\n+\t\tnetdev_dbg(netdev, \"tx_head = %u, tx_tail = %u\\n\",\n+\t\t\t txq-\u003ehead, txq-\u003etail);\n \t\tret = NETDEV_TX_BUSY;\n \t\tgoto unlock;\n \t}\n@@ -2554,7 +2648,7 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)\n \t/* Make newly initialized descriptor visible to hardware */\n \twmb();\n \tskb_tx_timestamp(skb);\n-\tnetdev_tx_sent_queue(netdev_get_tx_queue(bp-\u003edev, queue_index),\n+\tnetdev_tx_sent_queue(netdev_get_tx_queue(bp-\u003enetdev, q),\n \t\t\t skb-\u003elen);\n \n \tspin_lock(\u0026bp-\u003elock);\n@@ -2562,8 +2656,8 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)\n \tmacb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));\n \tspin_unlock(\u0026bp-\u003elock);\n \n-\tif (CIRC_SPACE(queue-\u003etx_head, queue-\u003etx_tail, bp-\u003etx_ring_size) \u003c 1)\n-\t\tnetif_stop_subqueue(dev, queue_index);\n+\tif (CIRC_SPACE(txq-\u003ehead, txq-\u003etail, bp-\u003ectx-\u003etx_ring_size) \u003c 1)\n+\t\tnetif_stop_subqueue(netdev, q);\n \n unlock:\n \tspin_unlock_irqrestore(\u0026queue-\u003etx_ptr_lock, flags);\n@@ -2571,151 +2665,163 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)\n \treturn ret;\n }\n \n-static void macb_init_rx_buffer_size(struct macb *bp, size_t size)\n+static unsigned int macb_rx_buffer_size(struct macb *bp, unsigned int mtu)\n {\n-\tif (!macb_is_gem(bp)) {\n-\t\tbp-\u003erx_buffer_size = MACB_RX_BUFFER_SIZE;\n+\tunsigned int size;\n+\n+\tif (!macb_is_gem(\u0026bp-\u003einfo)) {\n+\t\tsize = MACB_RX_BUFFER_SIZE;\n \t} else {\n-\t\tbp-\u003erx_buffer_size = MIN(size, RX_BUFFER_MAX);\n+\t\tsize = mtu + ETH_HLEN + ETH_FCS_LEN + NET_IP_ALIGN;\n+\t\tsize = MIN(size, RX_BUFFER_MAX);\n \n-\t\tif (bp-\u003erx_buffer_size % RX_BUFFER_MULTIPLE) {\n-\t\t\tnetdev_dbg(bp-\u003edev,\n+\t\tif (size % RX_BUFFER_MULTIPLE) {\n+\t\t\tnetdev_dbg(bp-\u003enetdev,\n \t\t\t\t \"RX buffer must be multiple of %d bytes, expanding\\n\",\n \t\t\t\t RX_BUFFER_MULTIPLE);\n-\t\t\tbp-\u003erx_buffer_size =\n-\t\t\t\troundup(bp-\u003erx_buffer_size, RX_BUFFER_MULTIPLE);\n+\t\t\tsize = roundup(size, RX_BUFFER_MULTIPLE);\n \t\t}\n \t}\n \n-\tnetdev_dbg(bp-\u003edev, \"mtu [%u] rx_buffer_size [%zu]\\n\",\n-\t\t bp-\u003edev-\u003emtu, bp-\u003erx_buffer_size);\n+\tnetdev_dbg(bp-\u003enetdev, \"mtu [%u] rx_buffer_size [%u]\\n\", mtu, size);\n+\treturn size;\n }\n \n-static void gem_free_rx_buffers(struct macb *bp)\n+static void gem_free_rx_buffers(struct macb_context *ctx)\n {\n-\tstruct sk_buff\t\t*skb;\n-\tstruct macb_dma_desc\t*desc;\n-\tstruct macb_queue *queue;\n-\tdma_addr_t\t\taddr;\n+\tstruct device *dev = \u0026ctx-\u003einfo-\u003epdev-\u003edev;\n+\tstruct macb_dma_desc *desc;\n+\tstruct macb_rxq *rxq;\n+\tstruct sk_buff *skb;\n+\tdma_addr_t addr;\n \tunsigned int q;\n \tint i;\n \n-\tfor (q = 0, queue = bp-\u003equeues; q \u003c bp-\u003enum_queues; ++q, ++queue) {\n-\t\tif (!queue-\u003erx_skbuff)\n+\tfor (q = 0; q \u003c ctx-\u003einfo-\u003enum_queues; ++q) {\n+\t\trxq = \u0026ctx-\u003erxq[q];\n+\n+\t\tif (!rxq-\u003eskbuff)\n \t\t\tcontinue;\n \n-\t\tfor (i = 0; i \u003c bp-\u003erx_ring_size; i++) {\n-\t\t\tskb = queue-\u003erx_skbuff[i];\n+\t\tfor (i = 0; i \u003c ctx-\u003erx_ring_size; i++) {\n+\t\t\tskb = rxq-\u003eskbuff[i];\n \n \t\t\tif (!skb)\n \t\t\t\tcontinue;\n \n-\t\t\tdesc = macb_rx_desc(queue, i);\n-\t\t\taddr = macb_get_addr(bp, desc);\n+\t\t\tdesc = macb_rx_desc(ctx, q, i);\n+\t\t\taddr = macb_get_addr(ctx, desc);\n \n-\t\t\tdma_unmap_single(\u0026bp-\u003epdev-\u003edev, addr, bp-\u003erx_buffer_size,\n-\t\t\t\t\tDMA_FROM_DEVICE);\n+\t\t\tdma_unmap_single(dev, addr, ctx-\u003erx_buffer_size,\n+\t\t\t\t\t DMA_FROM_DEVICE);\n \t\t\tdev_kfree_skb_any(skb);\n \t\t\tskb = NULL;\n \t\t}\n \n-\t\tkfree(queue-\u003erx_skbuff);\n-\t\tqueue-\u003erx_skbuff = NULL;\n+\t\tkfree(rxq-\u003eskbuff);\n+\t\trxq-\u003eskbuff = NULL;\n \t}\n }\n \n-static void macb_free_rx_buffers(struct macb *bp)\n+static void macb_free_rx_buffers(struct macb_context *ctx)\n {\n-\tstruct macb_queue *queue = \u0026bp-\u003equeues[0];\n+\tstruct device *dev = \u0026ctx-\u003einfo-\u003epdev-\u003edev;\n+\tstruct macb_rxq *rxq = \u0026ctx-\u003erxq[0];\n \n-\tif (queue-\u003erx_buffers) {\n-\t\tdma_free_coherent(\u0026bp-\u003epdev-\u003edev,\n-\t\t\t\t bp-\u003erx_ring_size * bp-\u003erx_buffer_size,\n-\t\t\t\t queue-\u003erx_buffers, queue-\u003erx_buffers_dma);\n-\t\tqueue-\u003erx_buffers = NULL;\n+\tif (rxq-\u003ebuffers) {\n+\t\tdma_free_coherent(dev,\n+\t\t\t\t ctx-\u003erx_ring_size * ctx-\u003erx_buffer_size,\n+\t\t\t\t rxq-\u003ebuffers, rxq-\u003ebuffers_dma);\n+\t\trxq-\u003ebuffers = NULL;\n \t}\n }\n \n-static unsigned int macb_tx_ring_size_per_queue(struct macb *bp)\n+static unsigned int macb_tx_ring_size_per_queue(struct macb_context *ctx)\n {\n-\treturn macb_dma_desc_get_size(bp) * bp-\u003etx_ring_size + bp-\u003etx_bd_rd_prefetch;\n+\treturn macb_dma_desc_get_size(ctx-\u003einfo) * ctx-\u003etx_ring_size +\n+\t\t\tctx-\u003einfo-\u003etx_bd_rd_prefetch;\n }\n \n-static unsigned int macb_rx_ring_size_per_queue(struct macb *bp)\n+static unsigned int macb_rx_ring_size_per_queue(struct macb_context *ctx)\n {\n-\treturn macb_dma_desc_get_size(bp) * bp-\u003erx_ring_size + bp-\u003erx_bd_rd_prefetch;\n+\treturn macb_dma_desc_get_size(ctx-\u003einfo) * ctx-\u003erx_ring_size +\n+\t\t\tctx-\u003einfo-\u003erx_bd_rd_prefetch;\n }\n \n-static void macb_free_consistent(struct macb *bp)\n+static void macb_free(struct macb_context *ctx)\n {\n-\tstruct device *dev = \u0026bp-\u003epdev-\u003edev;\n-\tstruct macb_queue *queue;\n+\tstruct device *dev = \u0026ctx-\u003einfo-\u003epdev-\u003edev;\n+\tstruct macb_txq *txq;\n+\tstruct macb_rxq *rxq;\n \tunsigned int q;\n \tsize_t size;\n \n-\tif (bp-\u003erx_ring_tieoff) {\n-\t\tdma_free_coherent(dev, macb_dma_desc_get_size(bp),\n-\t\t\t\t bp-\u003erx_ring_tieoff, bp-\u003erx_ring_tieoff_dma);\n-\t\tbp-\u003erx_ring_tieoff = NULL;\n-\t}\n+\tctx-\u003einfo-\u003emacbgem_ops.mog_free_rx_buffers(ctx);\n \n-\tbp-\u003emacbgem_ops.mog_free_rx_buffers(bp);\n+\ttxq = \u0026ctx-\u003etxq[0];\n+\tsize = ctx-\u003einfo-\u003enum_queues * macb_tx_ring_size_per_queue(ctx);\n+\tdma_free_coherent(dev, size, txq-\u003ering, txq-\u003ering_dma);\n \n-\tsize = bp-\u003enum_queues * macb_tx_ring_size_per_queue(bp);\n-\tdma_free_coherent(dev, size, bp-\u003equeues[0].tx_ring, bp-\u003equeues[0].tx_ring_dma);\n+\trxq = \u0026ctx-\u003erxq[0];\n+\tsize = ctx-\u003einfo-\u003enum_queues * macb_rx_ring_size_per_queue(ctx);\n+\tdma_free_coherent(dev, size, rxq-\u003ering, rxq-\u003ering_dma);\n \n-\tsize = bp-\u003enum_queues * macb_rx_ring_size_per_queue(bp);\n-\tdma_free_coherent(dev, size, bp-\u003equeues[0].rx_ring, bp-\u003equeues[0].rx_ring_dma);\n+\tfor (q = 0; q \u003c ctx-\u003einfo-\u003enum_queues; ++q) {\n+\t\ttxq = \u0026ctx-\u003etxq[q];\n+\t\trxq = \u0026ctx-\u003erxq[q];\n \n-\tfor (q = 0, queue = bp-\u003equeues; q \u003c bp-\u003enum_queues; ++q, ++queue) {\n-\t\tkfree(queue-\u003etx_skb);\n-\t\tqueue-\u003etx_skb = NULL;\n-\t\tqueue-\u003etx_ring = NULL;\n-\t\tqueue-\u003erx_ring = NULL;\n+\t\tkfree(txq-\u003eskb);\n+\t\ttxq-\u003eskb = NULL;\n+\t\ttxq-\u003ering = NULL;\n+\t\trxq-\u003ering = NULL;\n \t}\n }\n \n-static int gem_alloc_rx_buffers(struct macb *bp)\n+static int gem_alloc_rx_buffers(struct macb_context *ctx)\n {\n-\tstruct macb_queue *queue;\n+\tstruct macb_rxq *rxq;\n \tunsigned int q;\n \tint size;\n \n-\tfor (q = 0, queue = bp-\u003equeues; q \u003c bp-\u003enum_queues; ++q, ++queue) {\n-\t\tsize = bp-\u003erx_ring_size * sizeof(struct sk_buff *);\n-\t\tqueue-\u003erx_skbuff = kzalloc(size, GFP_KERNEL);\n-\t\tif (!queue-\u003erx_skbuff)\n+\tfor (q = 0; q \u003c ctx-\u003einfo-\u003enum_queues; ++q) {\n+\t\trxq = \u0026ctx-\u003erxq[q];\n+\t\tsize = ctx-\u003erx_ring_size * sizeof(struct sk_buff *);\n+\t\trxq-\u003eskbuff = kzalloc(size, GFP_KERNEL);\n+\t\tif (!rxq-\u003eskbuff)\n \t\t\treturn -ENOMEM;\n \t\telse\n-\t\t\tnetdev_dbg(bp-\u003edev,\n+\t\t\tnetdev_dbg(ctx-\u003einfo-\u003enetdev,\n \t\t\t\t \"Allocated %d RX struct sk_buff entries at %p\\n\",\n-\t\t\t\t bp-\u003erx_ring_size, queue-\u003erx_skbuff);\n+\t\t\t\t ctx-\u003erx_ring_size, rxq-\u003eskbuff);\n \t}\n \treturn 0;\n }\n \n-static int macb_alloc_rx_buffers(struct macb *bp)\n+static int macb_alloc_rx_buffers(struct macb_context *ctx)\n {\n-\tstruct macb_queue *queue = \u0026bp-\u003equeues[0];\n+\tstruct device *dev = \u0026ctx-\u003einfo-\u003epdev-\u003edev;\n+\tstruct macb_rxq *rxq = \u0026ctx-\u003erxq[0];\n \tint size;\n \n-\tsize = bp-\u003erx_ring_size * bp-\u003erx_buffer_size;\n-\tqueue-\u003erx_buffers = dma_alloc_coherent(\u0026bp-\u003epdev-\u003edev, size,\n-\t\t\t\t\t \u0026queue-\u003erx_buffers_dma, GFP_KERNEL);\n-\tif (!queue-\u003erx_buffers)\n+\tsize = ctx-\u003erx_ring_size * ctx-\u003erx_buffer_size;\n+\trxq-\u003ebuffers = dma_alloc_coherent(dev, size,\n+\t\t\t\t\t \u0026rxq-\u003ebuffers_dma, GFP_KERNEL);\n+\tif (!rxq-\u003ebuffers)\n \t\treturn -ENOMEM;\n \n-\tnetdev_dbg(bp-\u003edev,\n+\tnetdev_dbg(ctx-\u003einfo-\u003enetdev,\n \t\t \"Allocated RX buffers of %d bytes at %08lx (mapped %p)\\n\",\n-\t\t size, (unsigned long)queue-\u003erx_buffers_dma, queue-\u003erx_buffers);\n+\t\t size, (unsigned long)rxq-\u003ebuffers_dma, rxq-\u003ebuffers);\n \treturn 0;\n }\n \n-static int macb_alloc_consistent(struct macb *bp)\n+static int macb_alloc(struct macb_context *ctx)\n {\n-\tstruct device *dev = \u0026bp-\u003epdev-\u003edev;\n+\tunsigned int num_queues = ctx-\u003einfo-\u003enum_queues;\n+\tstruct device *dev = \u0026ctx-\u003einfo-\u003epdev-\u003edev;\n \tdma_addr_t tx_dma, rx_dma;\n-\tstruct macb_queue *queue;\n+\tstruct macb_txq *txq;\n+\tstruct macb_rxq *rxq;\n \tunsigned int q;\n \tvoid *tx, *rx;\n \tsize_t size;\n@@ -2727,113 +2833,125 @@ static int macb_alloc_consistent(struct macb *bp)\n \t * natural alignment of physical addresses.\n \t */\n \n-\tsize = bp-\u003enum_queues * macb_tx_ring_size_per_queue(bp);\n+\tsize = num_queues * macb_tx_ring_size_per_queue(ctx);\n \ttx = dma_alloc_coherent(dev, size, \u0026tx_dma, GFP_KERNEL);\n \tif (!tx || upper_32_bits(tx_dma) != upper_32_bits(tx_dma + size - 1))\n \t\tgoto out_err;\n-\tnetdev_dbg(bp-\u003edev, \"Allocated %zu bytes for %u TX rings at %08lx (mapped %p)\\n\",\n-\t\t size, bp-\u003enum_queues, (unsigned long)tx_dma, tx);\n+\tnetdev_dbg(ctx-\u003einfo-\u003enetdev,\n+\t\t \"Allocated %zu bytes for %u TX rings at %08lx (mapped %p)\\n\",\n+\t\t size, num_queues, (unsigned long)tx_dma, tx);\n \n-\tsize = bp-\u003enum_queues * macb_rx_ring_size_per_queue(bp);\n+\tsize = num_queues * macb_rx_ring_size_per_queue(ctx);\n \trx = dma_alloc_coherent(dev, size, \u0026rx_dma, GFP_KERNEL);\n \tif (!rx || upper_32_bits(rx_dma) != upper_32_bits(rx_dma + size - 1))\n \t\tgoto out_err;\n-\tnetdev_dbg(bp-\u003edev, \"Allocated %zu bytes for %u RX rings at %08lx (mapped %p)\\n\",\n-\t\t size, bp-\u003enum_queues, (unsigned long)rx_dma, rx);\n+\tnetdev_dbg(ctx-\u003einfo-\u003enetdev,\n+\t\t \"Allocated %zu bytes for %u RX rings at %08lx (mapped %p)\\n\",\n+\t\t size, num_queues, (unsigned long)rx_dma, rx);\n \n-\tfor (q = 0, queue = bp-\u003equeues; q \u003c bp-\u003enum_queues; ++q, ++queue) {\n-\t\tqueue-\u003etx_ring = tx + macb_tx_ring_size_per_queue(bp) * q;\n-\t\tqueue-\u003etx_ring_dma = tx_dma + macb_tx_ring_size_per_queue(bp) * q;\n+\tfor (q = 0; q \u003c num_queues; ++q) {\n+\t\ttxq = \u0026ctx-\u003etxq[q];\n+\t\trxq = \u0026ctx-\u003erxq[q];\n \n-\t\tqueue-\u003erx_ring = rx + macb_rx_ring_size_per_queue(bp) * q;\n-\t\tqueue-\u003erx_ring_dma = rx_dma + macb_rx_ring_size_per_queue(bp) * q;\n+\t\ttxq-\u003ering = tx + macb_tx_ring_size_per_queue(ctx) * q;\n+\t\ttxq-\u003ering_dma = tx_dma + macb_tx_ring_size_per_queue(ctx) * q;\n \n-\t\tsize = bp-\u003etx_ring_size * sizeof(struct macb_tx_skb);\n-\t\tqueue-\u003etx_skb = kmalloc(size, GFP_KERNEL);\n-\t\tif (!queue-\u003etx_skb)\n-\t\t\tgoto out_err;\n-\t}\n-\tif (bp-\u003emacbgem_ops.mog_alloc_rx_buffers(bp))\n-\t\tgoto out_err;\n+\t\trxq-\u003ering = rx + macb_rx_ring_size_per_queue(ctx) * q;\n+\t\trxq-\u003ering_dma = rx_dma + macb_rx_ring_size_per_queue(ctx) * q;\n \n-\t/* Required for tie off descriptor for PM cases */\n-\tif (!(bp-\u003ecaps \u0026 MACB_CAPS_QUEUE_DISABLE)) {\n-\t\tbp-\u003erx_ring_tieoff = dma_alloc_coherent(\u0026bp-\u003epdev-\u003edev,\n-\t\t\t\t\t\t\tmacb_dma_desc_get_size(bp),\n-\t\t\t\t\t\t\t\u0026bp-\u003erx_ring_tieoff_dma,\n-\t\t\t\t\t\t\tGFP_KERNEL);\n-\t\tif (!bp-\u003erx_ring_tieoff)\n+\t\tsize = ctx-\u003etx_ring_size * sizeof(struct macb_tx_skb);\n+\t\ttxq-\u003eskb = kmalloc(size, GFP_KERNEL);\n+\t\tif (!txq-\u003eskb)\n \t\t\tgoto out_err;\n \t}\n+\tif (ctx-\u003einfo-\u003emacbgem_ops.mog_alloc_rx_buffers(ctx))\n+\t\tgoto out_err;\n \n \treturn 0;\n \n out_err:\n-\tmacb_free_consistent(bp);\n+\tmacb_free(ctx);\n \treturn -ENOMEM;\n }\n \n-static void macb_init_tieoff(struct macb *bp)\n+static struct macb_context *macb_context_alloc(struct macb *bp,\n+\t\t\t\t\t unsigned int mtu,\n+\t\t\t\t\t unsigned int rx_ring_size,\n+\t\t\t\t\t unsigned int tx_ring_size)\n {\n-\tstruct macb_dma_desc *desc = bp-\u003erx_ring_tieoff;\n+\tstruct macb_context *ctx;\n+\tint err;\n \n-\tif (bp-\u003ecaps \u0026 MACB_CAPS_QUEUE_DISABLE)\n-\t\treturn;\n-\t/* Setup a wrapping descriptor with no free slots\n-\t * (WRAP and USED) to tie off/disable unused RX queues.\n-\t */\n-\tmacb_set_addr(bp, desc, MACB_BIT(RX_WRAP) | MACB_BIT(RX_USED));\n-\tdesc-\u003ectrl = 0;\n+\tctx = kzalloc_obj(*ctx);\n+\tif (!ctx)\n+\t\treturn ERR_PTR(-ENOMEM);\n+\n+\tctx-\u003einfo = \u0026bp-\u003einfo;\n+\tctx-\u003erx_buffer_size = macb_rx_buffer_size(bp, mtu);\n+\tctx-\u003erx_ring_size = rx_ring_size;\n+\tctx-\u003etx_ring_size = tx_ring_size;\n+\n+\terr = macb_alloc(ctx);\n+\tif (err) {\n+\t\tnetdev_err(bp-\u003enetdev,\n+\t\t\t \"Unable to allocate DMA memory (error %d)\\n\", err);\n+\t\tkfree(ctx);\n+\t\treturn ERR_PTR(err);\n+\t}\n+\n+\tbp-\u003emacbgem_ops.mog_init_rings(ctx);\n+\n+\treturn ctx;\n }\n \n-static void gem_init_rx_ring(struct macb_queue *queue)\n+static void gem_init_rx_ring(struct macb_context *ctx, unsigned int q)\n {\n-\tqueue-\u003erx_tail = 0;\n-\tqueue-\u003erx_prepared_head = 0;\n+\tstruct macb_rxq *rxq = \u0026ctx-\u003erxq[q];\n \n-\tgem_rx_refill(queue);\n+\trxq-\u003etail = 0;\n+\trxq-\u003eprepared_head = 0;\n+\n+\tgem_rx_refill(ctx, q);\n }\n \n-static void gem_init_rings(struct macb *bp)\n+static void gem_init_rings(struct macb_context *ctx)\n {\n-\tstruct macb_queue *queue;\n \tstruct macb_dma_desc *desc = NULL;\n+\tstruct macb_txq *txq;\n \tunsigned int q;\n \tint i;\n \n-\tfor (q = 0, queue = bp-\u003equeues; q \u003c bp-\u003enum_queues; ++q, ++queue) {\n-\t\tfor (i = 0; i \u003c bp-\u003etx_ring_size; i++) {\n-\t\t\tdesc = macb_tx_desc(queue, i);\n-\t\t\tmacb_set_addr(bp, desc, 0);\n+\tfor (q = 0; q \u003c ctx-\u003einfo-\u003enum_queues; ++q) {\n+\t\ttxq = \u0026ctx-\u003etxq[q];\n+\t\tfor (i = 0; i \u003c ctx-\u003etx_ring_size; i++) {\n+\t\t\tdesc = macb_tx_desc(ctx, q, i);\n+\t\t\tmacb_set_addr(ctx-\u003einfo, desc, 0);\n \t\t\tdesc-\u003ectrl = MACB_BIT(TX_USED);\n \t\t}\n \t\tdesc-\u003ectrl |= MACB_BIT(TX_WRAP);\n-\t\tqueue-\u003etx_head = 0;\n-\t\tqueue-\u003etx_tail = 0;\n+\t\ttxq-\u003ehead = 0;\n+\t\ttxq-\u003etail = 0;\n \n-\t\tgem_init_rx_ring(queue);\n+\t\tgem_init_rx_ring(ctx, q);\n \t}\n-\n-\tmacb_init_tieoff(bp);\n }\n \n-static void macb_init_rings(struct macb *bp)\n+static void macb_init_rings(struct macb_context *ctx)\n {\n-\tint i;\n+\tstruct macb_txq *txq = \u0026ctx-\u003etxq[0];\n \tstruct macb_dma_desc *desc = NULL;\n+\tint i;\n \n-\tmacb_init_rx_ring(\u0026bp-\u003equeues[0]);\n+\tmacb_init_rx_ring(ctx, 0);\n \n-\tfor (i = 0; i \u003c bp-\u003etx_ring_size; i++) {\n-\t\tdesc = macb_tx_desc(\u0026bp-\u003equeues[0], i);\n-\t\tmacb_set_addr(bp, desc, 0);\n+\tfor (i = 0; i \u003c ctx-\u003etx_ring_size; i++) {\n+\t\tdesc = macb_tx_desc(ctx, 0, i);\n+\t\tmacb_set_addr(ctx-\u003einfo, desc, 0);\n \t\tdesc-\u003ectrl = MACB_BIT(TX_USED);\n \t}\n-\tbp-\u003equeues[0].tx_head = 0;\n-\tbp-\u003equeues[0].tx_tail = 0;\n+\ttxq-\u003ehead = 0;\n+\ttxq-\u003etail = 0;\n \tdesc-\u003ectrl |= MACB_BIT(TX_WRAP);\n-\n-\tmacb_init_tieoff(bp);\n }\n \n static void macb_reset_hw(struct macb *bp)\n@@ -2897,7 +3015,7 @@ static u32 macb_mdc_clk_div(struct macb *bp)\n \tu32 config;\n \tunsigned long pclk_hz;\n \n-\tif (macb_is_gem(bp))\n+\tif (macb_is_gem(\u0026bp-\u003einfo))\n \t\treturn gem_mdc_clk_div(bp);\n \n \tpclk_hz = clk_get_rate(bp-\u003epclk);\n@@ -2919,7 +3037,7 @@ static u32 macb_mdc_clk_div(struct macb *bp)\n */\n static u32 macb_dbw(struct macb *bp)\n {\n-\tif (!macb_is_gem(bp))\n+\tif (!macb_is_gem(\u0026bp-\u003einfo))\n \t\treturn 0;\n \n \tswitch (GEM_BFEXT(DBWDEF, gem_readl(bp, DCFG1))) {\n@@ -2947,8 +3065,8 @@ static void macb_configure_dma(struct macb *bp)\n \tunsigned int q;\n \tu32 dmacfg;\n \n-\tbuffer_size = bp-\u003erx_buffer_size / RX_BUFFER_MULTIPLE;\n-\tif (macb_is_gem(bp)) {\n+\tbuffer_size = bp-\u003ectx-\u003erx_buffer_size / RX_BUFFER_MULTIPLE;\n+\tif (macb_is_gem(\u0026bp-\u003einfo)) {\n \t\tdmacfg = gem_readl(bp, DMACFG) \u0026 ~GEM_BF(RXBS, -1L);\n \t\tfor (q = 0, queue = bp-\u003equeues; q \u003c bp-\u003enum_queues; ++q, ++queue) {\n \t\t\tif (q)\n@@ -2966,22 +3084,123 @@ static void macb_configure_dma(struct macb *bp)\n \t\telse\n \t\t\tdmacfg |= GEM_BIT(ENDIA_DESC); /* CPU in big endian */\n \n-\t\tif (bp-\u003edev-\u003efeatures \u0026 NETIF_F_HW_CSUM)\n+\t\tif (bp-\u003enetdev-\u003efeatures \u0026 NETIF_F_HW_CSUM)\n \t\t\tdmacfg |= GEM_BIT(TXCOEN);\n \t\telse\n \t\t\tdmacfg \u0026= ~GEM_BIT(TXCOEN);\n \n \t\tdmacfg \u0026= ~GEM_BIT(ADDR64);\n-\t\tif (macb_dma64(bp))\n+\t\tif (macb_dma64(\u0026bp-\u003einfo))\n \t\t\tdmacfg |= GEM_BIT(ADDR64);\n-\t\tif (macb_dma_ptp(bp))\n+\t\tif (macb_dma_ptp(\u0026bp-\u003einfo))\n \t\t\tdmacfg |= GEM_BIT(RXEXT) | GEM_BIT(TXEXT);\n-\t\tnetdev_dbg(bp-\u003edev, \"Cadence configure DMA with 0x%08x\\n\",\n+\t\tnetdev_dbg(bp-\u003enetdev, \"Cadence configure DMA with 0x%08x\\n\",\n \t\t\t dmacfg);\n \t\tgem_writel(bp, DMACFG, dmacfg);\n \t}\n }\n \n+static void macb_context_swap_start(struct macb *bp)\n+{\n+\tstruct macb_queue *queue;\n+\tunsigned long flags;\n+\tunsigned int q;\n+\tu32 ctrl;\n+\n+\tmutex_lock(\u0026bp-\u003emac_cfg_lock);\n+\n+\t/* Mask interrupts before disabling BH features. */\n+\tspin_lock_irqsave(\u0026bp-\u003elock, flags);\n+\tfor (q = 0, queue = bp-\u003equeues; q \u003c bp-\u003enum_queues; ++q, ++queue) {\n+\t\tqueue_writel(queue, IDR, -1);\n+\t\tqueue_readl(queue, ISR);\n+\t\tmacb_queue_isr_clear(bp, queue, -1);\n+\t}\n+\tspin_unlock_irqrestore(\u0026bp-\u003elock, flags);\n+\n+\t/* Drain BH features. HW is still active and usable at this point. */\n+\n+\tcancel_work_sync(\u0026bp-\u003ehresp_err_bh_work);\n+\tcancel_delayed_work_sync(\u0026bp-\u003etx_lpi_work);\n+\n+\tfor (q = 0, queue = bp-\u003equeues; q \u003c bp-\u003enum_queues; ++q, ++queue) {\n+\t\tnapi_disable(\u0026queue-\u003enapi_rx);\n+\t\tnapi_disable(\u0026queue-\u003enapi_tx);\n+\t\tcancel_work_sync(\u0026queue-\u003etx_error_task);\n+\t\tnetdev_tx_reset_queue(netdev_get_tx_queue(bp-\u003enetdev, q));\n+\t}\n+\n+\t/* Can finally disable software Tx; need to wait until napi_tx and\n+\t * tx_error_task cannot be scheduled as either might wakeup Tx.\n+\t */\n+\tnetif_tx_disable(bp-\u003enetdev);\n+\n+\tspin_lock_irqsave(\u0026bp-\u003elock, flags);\n+\n+\t/* Whether it fails or not we'll disable TE/RE next.\n+\t * We were just trying to be nice.\n+\t */\n+\tmacb_halt_tx(bp);\n+\n+\tctrl = macb_readl(bp, NCR);\n+\tmacb_writel(bp, NCR, ctrl \u0026 ~(MACB_BIT(RE) | MACB_BIT(TE)));\n+\n+\tmacb_writel(bp, TSR, -1);\n+\tmacb_writel(bp, RSR, -1);\n+\n+\tspin_unlock_irqrestore(\u0026bp-\u003elock, flags);\n+}\n+\n+static void macb_context_swap_end(struct macb *bp,\n+\t\t\t\t struct macb_context *new_ctx)\n+{\n+\tstruct macb_context *old_ctx;\n+\tstruct macb_queue *queue;\n+\tunsigned long flags;\n+\tunsigned int q;\n+\tu32 ctrl;\n+\n+\tlockdep_assert_held(\u0026bp-\u003emac_cfg_lock);\n+\n+\t/* Swap contexts \u0026 give buffer pointers to HW. */\n+\n+\told_ctx = bp-\u003ectx;\n+\tbp-\u003ectx = new_ctx;\n+\tmacb_init_buffers(bp);\n+\n+\t/* Start NAPI, HW Tx/Rx and software Tx. */\n+\n+\tfor (q = 0, queue = bp-\u003equeues; q \u003c bp-\u003enum_queues; ++q, ++queue) {\n+\t\tnapi_enable(\u0026queue-\u003enapi_rx);\n+\t\tnapi_enable(\u0026queue-\u003enapi_tx);\n+\t}\n+\n+\tspin_lock_irqsave(\u0026bp-\u003elock, flags);\n+\n+\tmacb_configure_dma(bp);\n+\n+\tfor (q = 0, queue = bp-\u003equeues; q \u003c bp-\u003enum_queues; ++q, ++queue) {\n+\t\tqueue_writel(queue, IER,\n+\t\t\t bp-\u003erx_intr_mask |\n+\t\t\t MACB_TX_INT_FLAGS |\n+\t\t\t MACB_BIT(HRESP));\n+\t}\n+\n+\tctrl = macb_readl(bp, NCR);\n+\tmacb_writel(bp, NCR, ctrl | MACB_BIT(RE) | MACB_BIT(TE));\n+\n+\tspin_unlock_irqrestore(\u0026bp-\u003elock, flags);\n+\n+\tmutex_unlock(\u0026bp-\u003emac_cfg_lock);\n+\n+\tnetif_tx_start_all_queues(bp-\u003enetdev);\n+\n+\t/* Free old context. */\n+\n+\tmacb_free(old_ctx);\n+\tkfree(old_ctx);\n+}\n+\n static void macb_init_hw(struct macb *bp)\n {\n \tu32 config;\n@@ -3000,11 +3219,11 @@ static void macb_init_hw(struct macb *bp)\n \t\tconfig |= MACB_BIT(JFRAME);\t/* Enable jumbo frames */\n \telse\n \t\tconfig |= MACB_BIT(BIG);\t/* Receive oversized frames */\n-\tif (bp-\u003edev-\u003eflags \u0026 IFF_PROMISC)\n+\tif (bp-\u003enetdev-\u003eflags \u0026 IFF_PROMISC)\n \t\tconfig |= MACB_BIT(CAF);\t/* Copy All Frames */\n-\telse if (macb_is_gem(bp) \u0026\u0026 bp-\u003edev-\u003efeatures \u0026 NETIF_F_RXCSUM)\n+\telse if (macb_is_gem(\u0026bp-\u003einfo) \u0026\u0026 bp-\u003enetdev-\u003efeatures \u0026 NETIF_F_RXCSUM)\n \t\tconfig |= GEM_BIT(RXCOEN);\n-\tif (!(bp-\u003edev-\u003eflags \u0026 IFF_BROADCAST))\n+\tif (!(bp-\u003enetdev-\u003eflags \u0026 IFF_BROADCAST))\n \t\tconfig |= MACB_BIT(NBC);\t/* No BroadCast */\n \tconfig |= macb_dbw(bp);\n \tmacb_writel(bp, NCFGR, config);\n@@ -3078,17 +3297,17 @@ static int hash_get_index(__u8 *addr)\n }\n \n /* Add multicast addresses to the internal multicast-hash table. */\n-static void macb_sethashtable(struct net_device *dev)\n+static void macb_sethashtable(struct net_device *netdev)\n {\n \tstruct netdev_hw_addr *ha;\n \tunsigned long mc_filter[2];\n \tunsigned int bitnr;\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \n \tmc_filter[0] = 0;\n \tmc_filter[1] = 0;\n \n-\tnetdev_for_each_mc_addr(ha, dev) {\n+\tnetdev_for_each_mc_addr(ha, netdev) {\n \t\tbitnr = hash_get_index(ha-\u003eaddr);\n \t\tmc_filter[bitnr \u003e\u003e 5] |= 1 \u003c\u003c (bitnr \u0026 31);\n \t}\n@@ -3098,39 +3317,39 @@ static void macb_sethashtable(struct net_device *dev)\n }\n \n /* Enable/Disable promiscuous and multicast modes. */\n-static void macb_set_rx_mode(struct net_device *dev)\n+static void macb_set_rx_mode(struct net_device *netdev)\n {\n \tunsigned long cfg;\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \n \tcfg = macb_readl(bp, NCFGR);\n \n-\tif (dev-\u003eflags \u0026 IFF_PROMISC) {\n+\tif (netdev-\u003eflags \u0026 IFF_PROMISC) {\n \t\t/* Enable promiscuous mode */\n \t\tcfg |= MACB_BIT(CAF);\n \n \t\t/* Disable RX checksum offload */\n-\t\tif (macb_is_gem(bp))\n+\t\tif (macb_is_gem(\u0026bp-\u003einfo))\n \t\t\tcfg \u0026= ~GEM_BIT(RXCOEN);\n \t} else {\n \t\t/* Disable promiscuous mode */\n \t\tcfg \u0026= ~MACB_BIT(CAF);\n \n \t\t/* Enable RX checksum offload only if requested */\n-\t\tif (macb_is_gem(bp) \u0026\u0026 dev-\u003efeatures \u0026 NETIF_F_RXCSUM)\n+\t\tif (macb_is_gem(\u0026bp-\u003einfo) \u0026\u0026 netdev-\u003efeatures \u0026 NETIF_F_RXCSUM)\n \t\t\tcfg |= GEM_BIT(RXCOEN);\n \t}\n \n-\tif (dev-\u003eflags \u0026 IFF_ALLMULTI) {\n+\tif (netdev-\u003eflags \u0026 IFF_ALLMULTI) {\n \t\t/* Enable all multicast mode */\n \t\tmacb_or_gem_writel(bp, HRB, -1);\n \t\tmacb_or_gem_writel(bp, HRT, -1);\n \t\tcfg |= MACB_BIT(NCFGR_MTI);\n-\t} else if (!netdev_mc_empty(dev)) {\n+\t} else if (!netdev_mc_empty(netdev)) {\n \t\t/* Enable specific multicasts */\n-\t\tmacb_sethashtable(dev);\n+\t\tmacb_sethashtable(netdev);\n \t\tcfg |= MACB_BIT(NCFGR_MTI);\n-\t} else if (dev-\u003eflags \u0026 (~IFF_ALLMULTI)) {\n+\t} else if (netdev-\u003eflags \u0026 (~IFF_ALLMULTI)) {\n \t\t/* Disable all multicast mode */\n \t\tmacb_or_gem_writel(bp, HRB, 0);\n \t\tmacb_or_gem_writel(bp, HRT, 0);\n@@ -3140,31 +3359,28 @@ static void macb_set_rx_mode(struct net_device *dev)\n \tmacb_writel(bp, NCFGR, cfg);\n }\n \n-static int macb_open(struct net_device *dev)\n+static int macb_open(struct net_device *netdev)\n {\n-\tsize_t bufsz = dev-\u003emtu + ETH_HLEN + ETH_FCS_LEN + NET_IP_ALIGN;\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tstruct macb_queue *queue;\n \tunsigned int q;\n \tint err;\n \n-\tnetdev_dbg(bp-\u003edev, \"open\\n\");\n+\tnetdev_dbg(bp-\u003enetdev, \"open\\n\");\n \n \terr = pm_runtime_resume_and_get(\u0026bp-\u003epdev-\u003edev);\n \tif (err \u003c 0)\n \t\treturn err;\n \n-\t/* RX buffers initialization */\n-\tmacb_init_rx_buffer_size(bp, bufsz);\n-\n-\terr = macb_alloc_consistent(bp);\n-\tif (err) {\n-\t\tnetdev_err(dev, \"Unable to allocate DMA memory (error %d)\\n\",\n-\t\t\t err);\n+\tbp-\u003ectx = macb_context_alloc(bp, netdev-\u003emtu,\n+\t\t\t\t bp-\u003econfigured_rx_ring_size,\n+\t\t\t\t bp-\u003econfigured_tx_ring_size);\n+\tif (IS_ERR(bp-\u003ectx)) {\n+\t\terr = PTR_ERR(bp-\u003ectx);\n+\t\tbp-\u003ectx = NULL;\n \t\tgoto pm_exit;\n \t}\n \n-\tbp-\u003emacbgem_ops.mog_init_rings(bp);\n \tmacb_init_buffers(bp);\n \n \tfor (q = 0, queue = bp-\u003equeues; q \u003c bp-\u003enum_queues; ++q, ++queue) {\n@@ -3186,10 +3402,10 @@ static int macb_open(struct net_device *dev)\n \tif (err)\n \t\tgoto phy_off;\n \n-\tnetif_tx_start_all_queues(dev);\n+\tnetif_tx_start_all_queues(netdev);\n \n \tif (bp-\u003eptp_info)\n-\t\tbp-\u003eptp_info-\u003eptp_init(dev);\n+\t\tbp-\u003eptp_info-\u003eptp_init(netdev);\n \n \treturn 0;\n \n@@ -3202,25 +3418,27 @@ static int macb_open(struct net_device *dev)\n \t\tnapi_disable(\u0026queue-\u003enapi_rx);\n \t\tnapi_disable(\u0026queue-\u003enapi_tx);\n \t}\n-\tmacb_free_consistent(bp);\n+\tmacb_free(bp-\u003ectx);\n+\tkfree(bp-\u003ectx);\n+\tbp-\u003ectx = NULL;\n pm_exit:\n \tpm_runtime_put_sync(\u0026bp-\u003epdev-\u003edev);\n \treturn err;\n }\n \n-static int macb_close(struct net_device *dev)\n+static int macb_close(struct net_device *netdev)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tstruct macb_queue *queue;\n \tunsigned long flags;\n \tunsigned int q;\n \n-\tnetif_tx_stop_all_queues(dev);\n+\tnetif_tx_stop_all_queues(netdev);\n \n \tfor (q = 0, queue = bp-\u003equeues; q \u003c bp-\u003enum_queues; ++q, ++queue) {\n \t\tnapi_disable(\u0026queue-\u003enapi_rx);\n \t\tnapi_disable(\u0026queue-\u003enapi_tx);\n-\t\tnetdev_tx_reset_queue(netdev_get_tx_queue(dev, q));\n+\t\tnetdev_tx_reset_queue(netdev_get_tx_queue(netdev, q));\n \t}\n \n \tcancel_delayed_work_sync(\u0026bp-\u003etx_lpi_work);\n@@ -3232,38 +3450,58 @@ static int macb_close(struct net_device *dev)\n \n \tspin_lock_irqsave(\u0026bp-\u003elock, flags);\n \tmacb_reset_hw(bp);\n-\tnetif_carrier_off(dev);\n+\tnetif_carrier_off(netdev);\n \tspin_unlock_irqrestore(\u0026bp-\u003elock, flags);\n \n-\tmacb_free_consistent(bp);\n+\tmacb_free(bp-\u003ectx);\n+\tkfree(bp-\u003ectx);\n+\tbp-\u003ectx = NULL;\n \n \tif (bp-\u003eptp_info)\n-\t\tbp-\u003eptp_info-\u003eptp_remove(dev);\n+\t\tbp-\u003eptp_info-\u003eptp_remove(netdev);\n \n \tpm_runtime_put(\u0026bp-\u003epdev-\u003edev);\n \n \treturn 0;\n }\n \n-static int macb_change_mtu(struct net_device *dev, int new_mtu)\n+static int macb_change_mtu(struct net_device *netdev, int new_mtu)\n {\n-\tif (netif_running(dev))\n-\t\treturn -EBUSY;\n+\tstruct macb *bp = netdev_priv(netdev);\n+\tbool running = netif_running(netdev);\n+\tstruct macb_context *new_ctx;\n+\n+\tif (running) {\n+\t\t/* Context swapping is not supported for AT91. */\n+\t\tif (bp-\u003ecaps \u0026 MACB_CAPS_MACB_IS_EMAC)\n+\t\t\treturn -EBUSY;\n+\n+\t\tnew_ctx = macb_context_alloc(bp, new_mtu,\n+\t\t\t\t\t bp-\u003econfigured_rx_ring_size,\n+\t\t\t\t\t bp-\u003econfigured_tx_ring_size);\n+\t\tif (IS_ERR(new_ctx))\n+\t\t\treturn PTR_ERR(new_ctx);\n+\n+\t\tmacb_context_swap_start(bp);\n+\t}\n+\n+\tWRITE_ONCE(netdev-\u003emtu, new_mtu);\n \n-\tWRITE_ONCE(dev-\u003emtu, new_mtu);\n+\tif (running)\n+\t\tmacb_context_swap_end(bp, new_ctx);\n \n \treturn 0;\n }\n \n-static int macb_set_mac_addr(struct net_device *dev, void *addr)\n+static int macb_set_mac_addr(struct net_device *netdev, void *addr)\n {\n \tint err;\n \n-\terr = eth_mac_addr(dev, addr);\n+\terr = eth_mac_addr(netdev, addr);\n \tif (err \u003c 0)\n \t\treturn err;\n \n-\tmacb_set_hwaddr(netdev_priv(dev));\n+\tmacb_set_hwaddr(netdev_priv(netdev));\n \treturn 0;\n }\n \n@@ -3301,7 +3539,7 @@ static void gem_get_stats(struct macb *bp, struct rtnl_link_stats64 *nstat)\n \tstruct gem_stats *hwstat = \u0026bp-\u003ehw_stats.gem;\n \n \tspin_lock_irq(\u0026bp-\u003estats_lock);\n-\tif (netif_running(bp-\u003edev))\n+\tif (netif_running(bp-\u003enetdev))\n \t\tgem_update_stats(bp);\n \n \tnstat-\u003erx_errors = (hwstat-\u003erx_frame_check_sequence_errors +\n@@ -3334,10 +3572,10 @@ static void gem_get_stats(struct macb *bp, struct rtnl_link_stats64 *nstat)\n \tspin_unlock_irq(\u0026bp-\u003estats_lock);\n }\n \n-static void gem_get_ethtool_stats(struct net_device *dev,\n+static void gem_get_ethtool_stats(struct net_device *netdev,\n \t\t\t\t struct ethtool_stats *stats, u64 *data)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \n \tspin_lock_irq(\u0026bp-\u003estats_lock);\n \tgem_update_stats(bp);\n@@ -3346,9 +3584,9 @@ static void gem_get_ethtool_stats(struct net_device *dev,\n \tspin_unlock_irq(\u0026bp-\u003estats_lock);\n }\n \n-static int gem_get_sset_count(struct net_device *dev, int sset)\n+static int gem_get_sset_count(struct net_device *netdev, int sset)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \n \tswitch (sset) {\n \tcase ETH_SS_STATS:\n@@ -3358,9 +3596,9 @@ static int gem_get_sset_count(struct net_device *dev, int sset)\n \t}\n }\n \n-static void gem_get_ethtool_strings(struct net_device *dev, u32 sset, u8 *p)\n+static void gem_get_ethtool_strings(struct net_device *netdev, u32 sset, u8 *p)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tstruct macb_queue *queue;\n \tunsigned int i;\n \tunsigned int q;\n@@ -3379,14 +3617,14 @@ static void gem_get_ethtool_strings(struct net_device *dev, u32 sset, u8 *p)\n \t}\n }\n \n-static void macb_get_stats(struct net_device *dev,\n+static void macb_get_stats(struct net_device *netdev,\n \t\t\t struct rtnl_link_stats64 *nstat)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tstruct macb_stats *hwstat = \u0026bp-\u003ehw_stats.macb;\n \n-\tnetdev_stats_to_stats64(nstat, \u0026bp-\u003edev-\u003estats);\n-\tif (macb_is_gem(bp)) {\n+\tnetdev_stats_to_stats64(nstat, \u0026bp-\u003enetdev-\u003estats);\n+\tif (macb_is_gem(\u0026bp-\u003einfo)) {\n \t\tgem_get_stats(bp, nstat);\n \t\treturn;\n \t}\n@@ -3429,10 +3667,10 @@ static void macb_get_stats(struct net_device *dev,\n \tspin_unlock_irq(\u0026bp-\u003estats_lock);\n }\n \n-static void macb_get_pause_stats(struct net_device *dev,\n+static void macb_get_pause_stats(struct net_device *netdev,\n \t\t\t\t struct ethtool_pause_stats *pause_stats)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tstruct macb_stats *hwstat = \u0026bp-\u003ehw_stats.macb;\n \n \tspin_lock_irq(\u0026bp-\u003estats_lock);\n@@ -3442,10 +3680,10 @@ static void macb_get_pause_stats(struct net_device *dev,\n \tspin_unlock_irq(\u0026bp-\u003estats_lock);\n }\n \n-static void gem_get_pause_stats(struct net_device *dev,\n+static void gem_get_pause_stats(struct net_device *netdev,\n \t\t\t\tstruct ethtool_pause_stats *pause_stats)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tstruct gem_stats *hwstat = \u0026bp-\u003ehw_stats.gem;\n \n \tspin_lock_irq(\u0026bp-\u003estats_lock);\n@@ -3455,10 +3693,10 @@ static void gem_get_pause_stats(struct net_device *dev,\n \tspin_unlock_irq(\u0026bp-\u003estats_lock);\n }\n \n-static void macb_get_eth_mac_stats(struct net_device *dev,\n+static void macb_get_eth_mac_stats(struct net_device *netdev,\n \t\t\t\t struct ethtool_eth_mac_stats *mac_stats)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tstruct macb_stats *hwstat = \u0026bp-\u003ehw_stats.macb;\n \n \tspin_lock_irq(\u0026bp-\u003estats_lock);\n@@ -3480,10 +3718,10 @@ static void macb_get_eth_mac_stats(struct net_device *dev,\n \tspin_unlock_irq(\u0026bp-\u003estats_lock);\n }\n \n-static void gem_get_eth_mac_stats(struct net_device *dev,\n+static void gem_get_eth_mac_stats(struct net_device *netdev,\n \t\t\t\t struct ethtool_eth_mac_stats *mac_stats)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tstruct gem_stats *hwstat = \u0026bp-\u003ehw_stats.gem;\n \n \tspin_lock_irq(\u0026bp-\u003estats_lock);\n@@ -3513,10 +3751,10 @@ static void gem_get_eth_mac_stats(struct net_device *dev,\n }\n \n /* TODO: Report SQE test errors when added to phy_stats */\n-static void macb_get_eth_phy_stats(struct net_device *dev,\n+static void macb_get_eth_phy_stats(struct net_device *netdev,\n \t\t\t\t struct ethtool_eth_phy_stats *phy_stats)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tstruct macb_stats *hwstat = \u0026bp-\u003ehw_stats.macb;\n \n \tspin_lock_irq(\u0026bp-\u003estats_lock);\n@@ -3525,10 +3763,10 @@ static void macb_get_eth_phy_stats(struct net_device *dev,\n \tspin_unlock_irq(\u0026bp-\u003estats_lock);\n }\n \n-static void gem_get_eth_phy_stats(struct net_device *dev,\n+static void gem_get_eth_phy_stats(struct net_device *netdev,\n \t\t\t\t struct ethtool_eth_phy_stats *phy_stats)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tstruct gem_stats *hwstat = \u0026bp-\u003ehw_stats.gem;\n \n \tspin_lock_irq(\u0026bp-\u003estats_lock);\n@@ -3537,11 +3775,11 @@ static void gem_get_eth_phy_stats(struct net_device *dev,\n \tspin_unlock_irq(\u0026bp-\u003estats_lock);\n }\n \n-static void macb_get_rmon_stats(struct net_device *dev,\n+static void macb_get_rmon_stats(struct net_device *netdev,\n \t\t\t\tstruct ethtool_rmon_stats *rmon_stats,\n \t\t\t\tconst struct ethtool_rmon_hist_range **ranges)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tstruct macb_stats *hwstat = \u0026bp-\u003ehw_stats.macb;\n \n \tspin_lock_irq(\u0026bp-\u003estats_lock);\n@@ -3563,11 +3801,11 @@ static const struct ethtool_rmon_hist_range gem_rmon_ranges[] = {\n \t{ },\n };\n \n-static void gem_get_rmon_stats(struct net_device *dev,\n+static void gem_get_rmon_stats(struct net_device *netdev,\n \t\t\t struct ethtool_rmon_stats *rmon_stats,\n \t\t\t const struct ethtool_rmon_hist_range **ranges)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tstruct gem_stats *hwstat = \u0026bp-\u003ehw_stats.gem;\n \n \tspin_lock_irq(\u0026bp-\u003estats_lock);\n@@ -3598,18 +3836,25 @@ static int macb_get_regs_len(struct net_device *netdev)\n \treturn MACB_GREGS_NBR * sizeof(u32);\n }\n \n-static void macb_get_regs(struct net_device *dev, struct ethtool_regs *regs,\n+static void macb_get_regs(struct net_device *netdev, struct ethtool_regs *regs,\n \t\t\t void *p)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n-\tunsigned int tail, head;\n+\tdma_addr_t tx_dma_tail = 0, tx_dma_head = 0;\n+\tstruct macb *bp = netdev_priv(netdev);\n+\tunsigned int tail = 0, head = 0;\n+\tstruct macb_txq *txq;\n \tu32 *regs_buff = p;\n \n \tregs-\u003eversion = (macb_readl(bp, MID) \u0026 ((1 \u003c\u003c MACB_REV_SIZE) - 1))\n \t\t\t| MACB_GREGS_VERSION;\n \n-\ttail = macb_tx_ring_wrap(bp, bp-\u003equeues[0].tx_tail);\n-\thead = macb_tx_ring_wrap(bp, bp-\u003equeues[0].tx_head);\n+\tif (bp-\u003ectx) {\n+\t\ttxq = \u0026bp-\u003ectx-\u003etxq[0];\n+\t\ttail = macb_tx_ring_wrap(bp-\u003ectx, txq-\u003etail);\n+\t\thead = macb_tx_ring_wrap(bp-\u003ectx, txq-\u003ehead);\n+\t\ttx_dma_tail = macb_tx_dma(\u0026bp-\u003equeues[0], tail);\n+\t\ttx_dma_head = macb_tx_dma(\u0026bp-\u003equeues[0], head);\n+\t}\n \n \tregs_buff[0] = macb_readl(bp, NCR);\n \tregs_buff[1] = macb_or_gem_readl(bp, NCFGR);\n@@ -3622,12 +3867,12 @@ static void macb_get_regs(struct net_device *dev, struct ethtool_regs *regs,\n \n \tregs_buff[8] = tail;\n \tregs_buff[9] = head;\n-\tregs_buff[10] = macb_tx_dma(\u0026bp-\u003equeues[0], tail);\n-\tregs_buff[11] = macb_tx_dma(\u0026bp-\u003equeues[0], head);\n+\tregs_buff[10] = tx_dma_tail;\n+\tregs_buff[11] = tx_dma_head;\n \n \tif (!(bp-\u003ecaps \u0026 MACB_CAPS_USRIO_DISABLED))\n \t\tregs_buff[12] = macb_or_gem_readl(bp, USRIO);\n-\tif (macb_is_gem(bp))\n+\tif (macb_is_gem(\u0026bp-\u003einfo))\n \t\tregs_buff[13] = gem_readl(bp, DMACFG);\n }\n \n@@ -3688,8 +3933,8 @@ static void macb_get_ringparam(struct net_device *netdev,\n \tring-\u003erx_max_pending = MAX_RX_RING_SIZE;\n \tring-\u003etx_max_pending = MAX_TX_RING_SIZE;\n \n-\tring-\u003erx_pending = bp-\u003erx_ring_size;\n-\tring-\u003etx_pending = bp-\u003etx_ring_size;\n+\tring-\u003erx_pending = bp-\u003econfigured_rx_ring_size;\n+\tring-\u003etx_pending = bp-\u003econfigured_tx_ring_size;\n }\n \n static int macb_set_ringparam(struct net_device *netdev,\n@@ -3697,9 +3942,10 @@ static int macb_set_ringparam(struct net_device *netdev,\n \t\t\t struct kernel_ethtool_ringparam *kernel_ring,\n \t\t\t struct netlink_ext_ack *extack)\n {\n+\tunsigned int new_rx_size, new_tx_size;\n \tstruct macb *bp = netdev_priv(netdev);\n-\tu32 new_rx_size, new_tx_size;\n-\tunsigned int reset = 0;\n+\tbool running = netif_running(netdev);\n+\tstruct macb_context *new_ctx;\n \n \tif ((ring-\u003erx_mini_pending) || (ring-\u003erx_jumbo_pending))\n \t\treturn -EINVAL;\n@@ -3712,22 +3958,30 @@ static int macb_set_ringparam(struct net_device *netdev,\n \t\t\t MIN_TX_RING_SIZE, MAX_TX_RING_SIZE);\n \tnew_tx_size = roundup_pow_of_two(new_tx_size);\n \n-\tif ((new_tx_size == bp-\u003etx_ring_size) \u0026\u0026\n-\t (new_rx_size == bp-\u003erx_ring_size)) {\n+\tif (new_tx_size == bp-\u003econfigured_tx_ring_size \u0026\u0026\n+\t new_rx_size == bp-\u003econfigured_rx_ring_size) {\n \t\t/* nothing to do */\n \t\treturn 0;\n \t}\n \n-\tif (netif_running(bp-\u003edev)) {\n-\t\treset = 1;\n-\t\tmacb_close(bp-\u003edev);\n+\tif (running) {\n+\t\t/* Context swapping is not supported for AT91. */\n+\t\tif (bp-\u003ecaps \u0026 MACB_CAPS_MACB_IS_EMAC)\n+\t\t\treturn -EBUSY;\n+\n+\t\tnew_ctx = macb_context_alloc(bp, netdev-\u003emtu,\n+\t\t\t\t\t new_rx_size, new_tx_size);\n+\t\tif (IS_ERR(new_ctx))\n+\t\t\treturn PTR_ERR(new_ctx);\n+\n+\t\tmacb_context_swap_start(bp);\n \t}\n \n-\tbp-\u003erx_ring_size = new_rx_size;\n-\tbp-\u003etx_ring_size = new_tx_size;\n+\tbp-\u003econfigured_rx_ring_size = new_rx_size;\n+\tbp-\u003econfigured_tx_ring_size = new_tx_size;\n \n-\tif (reset)\n-\t\tmacb_open(bp-\u003edev);\n+\tif (running)\n+\t\tmacb_context_swap_end(bp, new_ctx);\n \n \treturn 0;\n }\n@@ -3754,13 +4008,13 @@ static s32 gem_get_ptp_max_adj(void)\n \treturn 64000000;\n }\n \n-static int gem_get_ts_info(struct net_device *dev,\n+static int gem_get_ts_info(struct net_device *netdev,\n \t\t\t struct kernel_ethtool_ts_info *info)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \n-\tif (!macb_dma_ptp(bp)) {\n-\t\tethtool_op_get_ts_info(dev, info);\n+\tif (!macb_dma_ptp(\u0026bp-\u003einfo)) {\n+\t\tethtool_op_get_ts_info(netdev, info);\n \t\treturn 0;\n \t}\n \n@@ -3807,7 +4061,7 @@ static int macb_get_ts_info(struct net_device *netdev,\n \n static void gem_enable_flow_filters(struct macb *bp, bool enable)\n {\n-\tstruct net_device *netdev = bp-\u003edev;\n+\tstruct net_device *netdev = bp-\u003enetdev;\n \tstruct ethtool_rx_fs_item *item;\n \tu32 t2_scr;\n \tint num_t2_scr;\n@@ -3860,7 +4114,7 @@ static void gem_prog_cmp_regs(struct macb *bp, struct ethtool_rx_flow_spec *fs)\n \tbool cmp_b = false;\n \tbool cmp_c = false;\n \n-\tif (!macb_is_gem(bp))\n+\tif (!macb_is_gem(\u0026bp-\u003einfo))\n \t\treturn;\n \n \ttp4sp_v = \u0026(fs-\u003eh_u.tcp_ip4_spec);\n@@ -4137,16 +4391,16 @@ static const struct ethtool_ops macb_ethtool_ops = {\n \t.set_ringparam\t\t= macb_set_ringparam,\n };\n \n-static int macb_get_eee(struct net_device *dev, struct ethtool_keee *eee)\n+static int macb_get_eee(struct net_device *netdev, struct ethtool_keee *eee)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \n \treturn phylink_ethtool_get_eee(bp-\u003ephylink, eee);\n }\n \n-static int macb_set_eee(struct net_device *dev, struct ethtool_keee *eee)\n+static int macb_set_eee(struct net_device *netdev, struct ethtool_keee *eee)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \n \treturn phylink_ethtool_set_eee(bp-\u003ephylink, eee);\n }\n@@ -4177,43 +4431,43 @@ static const struct ethtool_ops gem_ethtool_ops = {\n \t.set_eee\t\t= macb_set_eee,\n };\n \n-static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)\n+static int macb_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \n-\tif (!netif_running(dev))\n+\tif (!netif_running(netdev))\n \t\treturn -EINVAL;\n \n \treturn phylink_mii_ioctl(bp-\u003ephylink, rq, cmd);\n }\n \n-static int macb_hwtstamp_get(struct net_device *dev,\n+static int macb_hwtstamp_get(struct net_device *netdev,\n \t\t\t struct kernel_hwtstamp_config *cfg)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \n-\tif (!netif_running(dev))\n+\tif (!netif_running(netdev))\n \t\treturn -EINVAL;\n \n \tif (!bp-\u003eptp_info)\n \t\treturn -EOPNOTSUPP;\n \n-\treturn bp-\u003eptp_info-\u003eget_hwtst(dev, cfg);\n+\treturn bp-\u003eptp_info-\u003eget_hwtst(netdev, cfg);\n }\n \n-static int macb_hwtstamp_set(struct net_device *dev,\n+static int macb_hwtstamp_set(struct net_device *netdev,\n \t\t\t struct kernel_hwtstamp_config *cfg,\n \t\t\t struct netlink_ext_ack *extack)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \n-\tif (!netif_running(dev))\n+\tif (!netif_running(netdev))\n \t\treturn -EINVAL;\n \n \tif (!bp-\u003eptp_info)\n \t\treturn -EOPNOTSUPP;\n \n-\treturn bp-\u003eptp_info-\u003eset_hwtst(dev, cfg, extack);\n+\treturn bp-\u003eptp_info-\u003eset_hwtst(netdev, cfg, extack);\n }\n \n static inline void macb_set_txcsum_feature(struct macb *bp,\n@@ -4221,7 +4475,7 @@ static inline void macb_set_txcsum_feature(struct macb *bp,\n {\n \tu32 val;\n \n-\tif (!macb_is_gem(bp))\n+\tif (!macb_is_gem(\u0026bp-\u003einfo))\n \t\treturn;\n \n \tval = gem_readl(bp, DMACFG);\n@@ -4236,10 +4490,10 @@ static inline void macb_set_txcsum_feature(struct macb *bp,\n static inline void macb_set_rxcsum_feature(struct macb *bp,\n \t\t\t\t\t netdev_features_t features)\n {\n-\tstruct net_device *netdev = bp-\u003edev;\n+\tstruct net_device *netdev = bp-\u003enetdev;\n \tu32 val;\n \n-\tif (!macb_is_gem(bp))\n+\tif (!macb_is_gem(\u0026bp-\u003einfo))\n \t\treturn;\n \n \tval = gem_readl(bp, NCFGR);\n@@ -4254,7 +4508,7 @@ static inline void macb_set_rxcsum_feature(struct macb *bp,\n static inline void macb_set_rxflow_feature(struct macb *bp,\n \t\t\t\t\t netdev_features_t features)\n {\n-\tif (!macb_is_gem(bp))\n+\tif (!macb_is_gem(\u0026bp-\u003einfo))\n \t\treturn;\n \n \tgem_enable_flow_filters(bp, !!(features \u0026 NETIF_F_NTUPLE));\n@@ -4283,7 +4537,7 @@ static int macb_set_features(struct net_device *netdev,\n \n static void macb_restore_features(struct macb *bp)\n {\n-\tstruct net_device *netdev = bp-\u003edev;\n+\tstruct net_device *netdev = bp-\u003enetdev;\n \tnetdev_features_t features = netdev-\u003efeatures;\n \tstruct ethtool_rx_fs_item *item;\n \n@@ -4300,14 +4554,14 @@ static void macb_restore_features(struct macb *bp)\n \tmacb_set_rxflow_feature(bp, features);\n }\n \n-static int macb_taprio_setup_replace(struct net_device *ndev,\n+static int macb_taprio_setup_replace(struct net_device *netdev,\n \t\t\t\t struct tc_taprio_qopt_offload *conf)\n {\n \tu64 total_on_time = 0, start_time_sec = 0, start_time = conf-\u003ebase_time;\n \tu32 configured_queues = 0, speed = 0, start_time_nsec;\n \tstruct macb_queue_enst_config *enst_queue;\n \tstruct tc_taprio_sched_entry *entry;\n-\tstruct macb *bp = netdev_priv(ndev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tstruct ethtool_link_ksettings kset;\n \tstruct macb_queue *queue;\n \tu32 queue_mask;\n@@ -4316,13 +4570,13 @@ static int macb_taprio_setup_replace(struct net_device *ndev,\n \tint err;\n \n \tif (conf-\u003enum_entries \u003e bp-\u003enum_queues) {\n-\t\tnetdev_err(ndev, \"Too many TAPRIO entries: %zu \u003e %d queues\\n\",\n+\t\tnetdev_err(netdev, \"Too many TAPRIO entries: %zu \u003e %d queues\\n\",\n \t\t\t conf-\u003enum_entries, bp-\u003enum_queues);\n \t\treturn -EINVAL;\n \t}\n \n \tif (conf-\u003ebase_time \u003c 0) {\n-\t\tnetdev_err(ndev, \"Invalid base_time: must be 0 or positive, got %lld\\n\",\n+\t\tnetdev_err(netdev, \"Invalid base_time: must be 0 or positive, got %lld\\n\",\n \t\t\t conf-\u003ebase_time);\n \t\treturn -ERANGE;\n \t}\n@@ -4330,13 +4584,13 @@ static int macb_taprio_setup_replace(struct net_device *ndev,\n \t/* Get the current link speed */\n \terr = phylink_ethtool_ksettings_get(bp-\u003ephylink, \u0026kset);\n \tif (unlikely(err)) {\n-\t\tnetdev_err(ndev, \"Failed to get link settings: %d\\n\", err);\n+\t\tnetdev_err(netdev, \"Failed to get link settings: %d\\n\", err);\n \t\treturn err;\n \t}\n \n \tspeed = kset.base.speed;\n \tif (unlikely(speed \u003c= 0)) {\n-\t\tnetdev_err(ndev, \"Invalid speed: %d\\n\", speed);\n+\t\tnetdev_err(netdev, \"Invalid speed: %d\\n\", speed);\n \t\treturn -EINVAL;\n \t}\n \n@@ -4349,7 +4603,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,\n \t\tentry = \u0026conf-\u003eentries[i];\n \n \t\tif (entry-\u003ecommand != TC_TAPRIO_CMD_SET_GATES) {\n-\t\t\tnetdev_err(ndev, \"Entry %zu: unsupported command %d\\n\",\n+\t\t\tnetdev_err(netdev, \"Entry %zu: unsupported command %d\\n\",\n \t\t\t\t i, entry-\u003ecommand);\n \t\t\terr = -EOPNOTSUPP;\n \t\t\tgoto cleanup;\n@@ -4357,7 +4611,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,\n \n \t\t/* Validate gate_mask: must be nonzero, single queue, and within range */\n \t\tif (!is_power_of_2(entry-\u003egate_mask)) {\n-\t\t\tnetdev_err(ndev, \"Entry %zu: gate_mask 0x%x is not a power of 2 (only one queue per entry allowed)\\n\",\n+\t\t\tnetdev_err(netdev, \"Entry %zu: gate_mask 0x%x is not a power of 2 (only one queue per entry allowed)\\n\",\n \t\t\t\t i, entry-\u003egate_mask);\n \t\t\terr = -EINVAL;\n \t\t\tgoto cleanup;\n@@ -4366,7 +4620,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,\n \t\t/* gate_mask must not select queues outside the valid queues */\n \t\tqueue_id = order_base_2(entry-\u003egate_mask);\n \t\tif (queue_id \u003e= bp-\u003enum_queues) {\n-\t\t\tnetdev_err(ndev, \"Entry %zu: gate_mask 0x%x exceeds queue range (max_queues=%d)\\n\",\n+\t\t\tnetdev_err(netdev, \"Entry %zu: gate_mask 0x%x exceeds queue range (max_queues=%d)\\n\",\n \t\t\t\t i, entry-\u003egate_mask, bp-\u003enum_queues);\n \t\t\terr = -EINVAL;\n \t\t\tgoto cleanup;\n@@ -4376,7 +4630,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,\n \t\tstart_time_sec = start_time;\n \t\tstart_time_nsec = do_div(start_time_sec, NSEC_PER_SEC);\n \t\tif (start_time_sec \u003e GENMASK(GEM_START_TIME_SEC_SIZE - 1, 0)) {\n-\t\t\tnetdev_err(ndev, \"Entry %zu: Start time %llu s exceeds hardware limit\\n\",\n+\t\t\tnetdev_err(netdev, \"Entry %zu: Start time %llu s exceeds hardware limit\\n\",\n \t\t\t\t i, start_time_sec);\n \t\t\terr = -ERANGE;\n \t\t\tgoto cleanup;\n@@ -4384,7 +4638,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,\n \n \t\t/* Check for on time limit */\n \t\tif (entry-\u003einterval \u003e enst_max_hw_interval(speed)) {\n-\t\t\tnetdev_err(ndev, \"Entry %zu: interval %u ns exceeds hardware limit %llu ns\\n\",\n+\t\t\tnetdev_err(netdev, \"Entry %zu: interval %u ns exceeds hardware limit %llu ns\\n\",\n \t\t\t\t i, entry-\u003einterval, enst_max_hw_interval(speed));\n \t\t\terr = -ERANGE;\n \t\t\tgoto cleanup;\n@@ -4392,7 +4646,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,\n \n \t\t/* Check for off time limit*/\n \t\tif ((conf-\u003ecycle_time - entry-\u003einterval) \u003e enst_max_hw_interval(speed)) {\n-\t\t\tnetdev_err(ndev, \"Entry %zu: off_time %llu ns exceeds hardware limit %llu ns\\n\",\n+\t\t\tnetdev_err(netdev, \"Entry %zu: off_time %llu ns exceeds hardware limit %llu ns\\n\",\n \t\t\t\t i, conf-\u003ecycle_time - entry-\u003einterval,\n \t\t\t\t enst_max_hw_interval(speed));\n \t\t\terr = -ERANGE;\n@@ -4415,13 +4669,13 @@ static int macb_taprio_setup_replace(struct net_device *ndev,\n \n \t/* Check total interval doesn't exceed cycle time */\n \tif (total_on_time \u003e conf-\u003ecycle_time) {\n-\t\tnetdev_err(ndev, \"Total ON %llu ns exceeds cycle time %llu ns\\n\",\n+\t\tnetdev_err(netdev, \"Total ON %llu ns exceeds cycle time %llu ns\\n\",\n \t\t\t total_on_time, conf-\u003ecycle_time);\n \t\terr = -EINVAL;\n \t\tgoto cleanup;\n \t}\n \n-\tnetdev_dbg(ndev, \"TAPRIO setup: %zu entries, base_time=%lld ns, cycle_time=%llu ns\\n\",\n+\tnetdev_dbg(netdev, \"TAPRIO setup: %zu entries, base_time=%lld ns, cycle_time=%llu ns\\n\",\n \t\t conf-\u003enum_entries, conf-\u003ebase_time, conf-\u003ecycle_time);\n \n \t/* All validations passed - proceed with hardware configuration */\n@@ -4446,7 +4700,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,\n \t\tgem_writel(bp, ENST_CONTROL, configured_queues);\n \t}\n \n-\tnetdev_info(ndev, \"TAPRIO configuration completed successfully: %zu entries, %d queues configured\\n\",\n+\tnetdev_info(netdev, \"TAPRIO configuration completed successfully: %zu entries, %d queues configured\\n\",\n \t\t conf-\u003enum_entries, hweight32(configured_queues));\n \n cleanup:\n@@ -4454,14 +4708,14 @@ static int macb_taprio_setup_replace(struct net_device *ndev,\n \treturn err;\n }\n \n-static void macb_taprio_destroy(struct net_device *ndev)\n+static void macb_taprio_destroy(struct net_device *netdev)\n {\n-\tstruct macb *bp = netdev_priv(ndev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tstruct macb_queue *queue;\n \tu32 queue_mask;\n \tunsigned int q;\n \n-\tnetdev_reset_tc(ndev);\n+\tnetdev_reset_tc(netdev);\n \tqueue_mask = BIT_U32(bp-\u003enum_queues) - 1;\n \n \tscoped_guard(spinlock_irqsave, \u0026bp-\u003elock) {\n@@ -4476,30 +4730,30 @@ static void macb_taprio_destroy(struct net_device *ndev)\n \t\t\tqueue_writel(queue, ENST_OFF_TIME, 0);\n \t\t}\n \t}\n-\tnetdev_info(ndev, \"TAPRIO destroy: All gates disabled\\n\");\n+\tnetdev_info(netdev, \"TAPRIO destroy: All gates disabled\\n\");\n }\n \n-static int macb_setup_taprio(struct net_device *ndev,\n+static int macb_setup_taprio(struct net_device *netdev,\n \t\t\t struct tc_taprio_qopt_offload *taprio)\n {\n-\tstruct macb *bp = netdev_priv(ndev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tint err = 0;\n \n-\tif (unlikely(!(ndev-\u003ehw_features \u0026 NETIF_F_HW_TC)))\n+\tif (unlikely(!(netdev-\u003ehw_features \u0026 NETIF_F_HW_TC)))\n \t\treturn -EOPNOTSUPP;\n \n \t/* Check if Device is in runtime suspend */\n \tif (unlikely(pm_runtime_suspended(\u0026bp-\u003epdev-\u003edev))) {\n-\t\tnetdev_err(ndev, \"Device is in runtime suspend\\n\");\n+\t\tnetdev_err(netdev, \"Device is in runtime suspend\\n\");\n \t\treturn -EOPNOTSUPP;\n \t}\n \n \tswitch (taprio-\u003ecmd) {\n \tcase TAPRIO_CMD_REPLACE:\n-\t\terr = macb_taprio_setup_replace(ndev, taprio);\n+\t\terr = macb_taprio_setup_replace(netdev, taprio);\n \t\tbreak;\n \tcase TAPRIO_CMD_DESTROY:\n-\t\tmacb_taprio_destroy(ndev);\n+\t\tmacb_taprio_destroy(netdev);\n \t\tbreak;\n \tdefault:\n \t\terr = -EOPNOTSUPP;\n@@ -4508,23 +4762,23 @@ static int macb_setup_taprio(struct net_device *ndev,\n \treturn err;\n }\n \n-static int macb_setup_tc(struct net_device *dev, enum tc_setup_type type,\n+static int macb_setup_tc(struct net_device *netdev, enum tc_setup_type type,\n \t\t\t void *type_data)\n {\n-\tif (!dev || !type_data)\n+\tif (!netdev || !type_data)\n \t\treturn -EINVAL;\n \n \tswitch (type) {\n \tcase TC_SETUP_QDISC_TAPRIO:\n-\t\treturn macb_setup_taprio(dev, type_data);\n+\t\treturn macb_setup_taprio(netdev, type_data);\n \tdefault:\n \t\treturn -EOPNOTSUPP;\n \t}\n }\n \n-static void macb_tx_timeout(struct net_device *dev, unsigned int q)\n+static void macb_tx_timeout(struct net_device *netdev, unsigned int q)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \n \tmacb_tx_restart(\u0026bp-\u003equeues[q]);\n }\n@@ -4581,7 +4835,7 @@ static void macb_configure_caps(struct macb *bp,\n \t\t\tbp-\u003ecaps |= MACB_CAPS_FIFO_MODE;\n \t\tif (GEM_BFEXT(PBUF_RSC, gem_readl(bp, DCFG6)))\n \t\t\tbp-\u003ecaps |= MACB_CAPS_RSC;\n-\t\tif (gem_has_ptp(bp)) {\n+\t\tif (gem_has_ptp(\u0026bp-\u003einfo)) {\n \t\t\tif (!GEM_BFEXT(TSU, gem_readl(bp, DCFG5)))\n \t\t\t\tdev_err(\u0026bp-\u003epdev-\u003edev,\n \t\t\t\t\t\"GEM doesn't support hardware ptp.\\n\");\n@@ -4732,16 +4986,13 @@ static int macb_clk_init(struct platform_device *pdev, struct clk **pclk,\n \n static int macb_init_dflt(struct platform_device *pdev)\n {\n-\tstruct net_device *dev = platform_get_drvdata(pdev);\n+\tstruct net_device *netdev = platform_get_drvdata(pdev);\n \tunsigned int hw_q, q;\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tstruct macb_queue *queue;\n \tint err;\n \tu32 val, reg;\n \n-\tbp-\u003etx_ring_size = DEFAULT_TX_RING_SIZE;\n-\tbp-\u003erx_ring_size = DEFAULT_RX_RING_SIZE;\n-\n \t/* set the queue register mapping once for all: queue0 has a special\n \t * register mapping but we don't want to test the queue index then\n \t * compute the corresponding register offset at run time.\n@@ -4750,8 +5001,8 @@ static int macb_init_dflt(struct platform_device *pdev)\n \t\tqueue = \u0026bp-\u003equeues[q];\n \t\tqueue-\u003ebp = bp;\n \t\tspin_lock_init(\u0026queue-\u003etx_ptr_lock);\n-\t\tnetif_napi_add(dev, \u0026queue-\u003enapi_rx, macb_rx_poll);\n-\t\tnetif_napi_add_tx(dev, \u0026queue-\u003enapi_tx, macb_tx_poll);\n+\t\tnetif_napi_add(netdev, \u0026queue-\u003enapi_rx, macb_rx_poll);\n+\t\tnetif_napi_add_tx(netdev, \u0026queue-\u003enapi_tx, macb_tx_poll);\n \t\tif (hw_q) {\n \t\t\tqueue-\u003eISR = GEM_ISR(hw_q - 1);\n \t\t\tqueue-\u003eIER = GEM_IER(hw_q - 1);\n@@ -4781,7 +5032,7 @@ static int macb_init_dflt(struct platform_device *pdev)\n \t\t */\n \t\tqueue-\u003eirq = platform_get_irq(pdev, q);\n \t\terr = devm_request_irq(\u0026pdev-\u003edev, queue-\u003eirq, macb_interrupt,\n-\t\t\t\t IRQF_SHARED, dev-\u003ename, queue);\n+\t\t\t\t IRQF_SHARED, netdev-\u003ename, queue);\n \t\tif (err) {\n \t\t\tdev_err(\u0026pdev-\u003edev,\n \t\t\t\t\"Unable to request IRQ %d (error %d)\\n\",\n@@ -4793,47 +5044,47 @@ static int macb_init_dflt(struct platform_device *pdev)\n \t\tq++;\n \t}\n \n-\tdev-\u003enetdev_ops = \u0026macb_netdev_ops;\n+\tnetdev-\u003enetdev_ops = \u0026macb_netdev_ops;\n \n \t/* setup appropriated routines according to adapter type */\n-\tif (macb_is_gem(bp)) {\n+\tif (macb_is_gem(\u0026bp-\u003einfo)) {\n \t\tbp-\u003emacbgem_ops.mog_alloc_rx_buffers = gem_alloc_rx_buffers;\n \t\tbp-\u003emacbgem_ops.mog_free_rx_buffers = gem_free_rx_buffers;\n \t\tbp-\u003emacbgem_ops.mog_init_rings = gem_init_rings;\n \t\tbp-\u003emacbgem_ops.mog_rx = gem_rx;\n-\t\tdev-\u003eethtool_ops = \u0026gem_ethtool_ops;\n+\t\tnetdev-\u003eethtool_ops = \u0026gem_ethtool_ops;\n \t} else {\n \t\tbp-\u003emacbgem_ops.mog_alloc_rx_buffers = macb_alloc_rx_buffers;\n \t\tbp-\u003emacbgem_ops.mog_free_rx_buffers = macb_free_rx_buffers;\n \t\tbp-\u003emacbgem_ops.mog_init_rings = macb_init_rings;\n \t\tbp-\u003emacbgem_ops.mog_rx = macb_rx;\n-\t\tdev-\u003eethtool_ops = \u0026macb_ethtool_ops;\n+\t\tnetdev-\u003eethtool_ops = \u0026macb_ethtool_ops;\n \t}\n \n-\tnetdev_sw_irq_coalesce_default_on(dev);\n+\tnetdev_sw_irq_coalesce_default_on(netdev);\n \n-\tdev-\u003epriv_flags |= IFF_LIVE_ADDR_CHANGE;\n+\tnetdev-\u003epriv_flags |= IFF_LIVE_ADDR_CHANGE;\n \n \t/* Set features */\n-\tdev-\u003ehw_features = NETIF_F_SG;\n+\tnetdev-\u003ehw_features = NETIF_F_SG;\n \n \t/* Check LSO capability; runtime detection can be overridden by a cap\n \t * flag if the hardware is known to be buggy\n \t */\n \tif (!(bp-\u003ecaps \u0026 MACB_CAPS_NO_LSO) \u0026\u0026\n \t GEM_BFEXT(PBUF_LSO, gem_readl(bp, DCFG6)))\n-\t\tdev-\u003ehw_features |= MACB_NETIF_LSO;\n+\t\tnetdev-\u003ehw_features |= MACB_NETIF_LSO;\n \n \t/* Checksum offload is only available on gem with packet buffer */\n-\tif (macb_is_gem(bp) \u0026\u0026 !(bp-\u003ecaps \u0026 MACB_CAPS_FIFO_MODE))\n-\t\tdev-\u003ehw_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM;\n+\tif (macb_is_gem(\u0026bp-\u003einfo) \u0026\u0026 !(bp-\u003ecaps \u0026 MACB_CAPS_FIFO_MODE))\n+\t\tnetdev-\u003ehw_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM;\n \tif (bp-\u003ecaps \u0026 MACB_CAPS_SG_DISABLED)\n-\t\tdev-\u003ehw_features \u0026= ~NETIF_F_SG;\n+\t\tnetdev-\u003ehw_features \u0026= ~NETIF_F_SG;\n \t/* Enable HW_TC if hardware supports QBV */\n \tif (bp-\u003ecaps \u0026 MACB_CAPS_QBV)\n-\t\tdev-\u003ehw_features |= NETIF_F_HW_TC;\n+\t\tnetdev-\u003ehw_features |= NETIF_F_HW_TC;\n \n-\tdev-\u003efeatures = dev-\u003ehw_features;\n+\tnetdev-\u003efeatures = netdev-\u003ehw_features;\n \n \t/* Check RX Flow Filters support.\n \t * Max Rx flows set by availability of screeners \u0026 compare regs:\n@@ -4851,7 +5102,7 @@ static int macb_init_dflt(struct platform_device *pdev)\n \t\t\treg = GEM_BFINS(ETHTCMP, (uint16_t)ETH_P_IP, reg);\n \t\t\tgem_writel_n(bp, ETHT, SCRT2_ETHT, reg);\n \t\t\t/* Filtering is supported in hw but don't enable it in kernel now */\n-\t\t\tdev-\u003ehw_features |= NETIF_F_NTUPLE;\n+\t\t\tnetdev-\u003ehw_features |= NETIF_F_NTUPLE;\n \t\t\t/* init Rx flow definitions */\n \t\t\tbp-\u003erx_fs_list.count = 0;\n \t\t\tspin_lock_init(\u0026bp-\u003erx_fs_lock);\n@@ -4945,71 +5196,72 @@ static const struct macb_usrio_config at91_default_usrio = {\n \n static struct sifive_fu540_macb_mgmt *mgmt;\n \n-static int at91ether_alloc_coherent(struct macb *lp)\n+static int at91ether_alloc_coherent(struct macb *bp)\n {\n-\tstruct macb_queue *q = \u0026lp-\u003equeues[0];\n+\tstruct macb_rxq *rxq = \u0026bp-\u003ectx-\u003erxq[0];\n \n-\tq-\u003erx_ring = dma_alloc_coherent(\u0026lp-\u003epdev-\u003edev,\n-\t\t\t\t\t (AT91ETHER_MAX_RX_DESCR *\n-\t\t\t\t\t macb_dma_desc_get_size(lp)),\n-\t\t\t\t\t \u0026q-\u003erx_ring_dma, GFP_KERNEL);\n-\tif (!q-\u003erx_ring)\n+\trxq-\u003ering = dma_alloc_coherent(\u0026bp-\u003epdev-\u003edev,\n+\t\t\t\t (AT91ETHER_MAX_RX_DESCR *\n+\t\t\t\t macb_dma_desc_get_size(\u0026bp-\u003einfo)),\n+\t\t\t\t \u0026rxq-\u003ering_dma, GFP_KERNEL);\n+\tif (!rxq-\u003ering)\n \t\treturn -ENOMEM;\n \n-\tq-\u003erx_buffers = dma_alloc_coherent(\u0026lp-\u003epdev-\u003edev,\n-\t\t\t\t\t AT91ETHER_MAX_RX_DESCR *\n-\t\t\t\t\t AT91ETHER_MAX_RBUFF_SZ,\n-\t\t\t\t\t \u0026q-\u003erx_buffers_dma, GFP_KERNEL);\n-\tif (!q-\u003erx_buffers) {\n-\t\tdma_free_coherent(\u0026lp-\u003epdev-\u003edev,\n+\trxq-\u003ebuffers = dma_alloc_coherent(\u0026bp-\u003epdev-\u003edev,\n+\t\t\t\t\t AT91ETHER_MAX_RX_DESCR *\n+\t\t\t\t\t AT91ETHER_MAX_RBUFF_SZ,\n+\t\t\t\t\t \u0026rxq-\u003ebuffers_dma,\n+\t\t\t\t\t GFP_KERNEL);\n+\tif (!rxq-\u003ebuffers) {\n+\t\tdma_free_coherent(\u0026bp-\u003epdev-\u003edev,\n \t\t\t\t AT91ETHER_MAX_RX_DESCR *\n-\t\t\t\t macb_dma_desc_get_size(lp),\n-\t\t\t\t q-\u003erx_ring, q-\u003erx_ring_dma);\n-\t\tq-\u003erx_ring = NULL;\n+\t\t\t\t macb_dma_desc_get_size(\u0026bp-\u003einfo),\n+\t\t\t\t rxq-\u003ering, rxq-\u003ering_dma);\n+\t\trxq-\u003ering = NULL;\n \t\treturn -ENOMEM;\n \t}\n \n \treturn 0;\n }\n \n-static void at91ether_free_coherent(struct macb *lp)\n+static void at91ether_free_coherent(struct macb *bp)\n {\n-\tstruct macb_queue *q = \u0026lp-\u003equeues[0];\n+\tstruct macb_rxq *rxq = \u0026bp-\u003ectx-\u003erxq[0];\n \n-\tif (q-\u003erx_ring) {\n-\t\tdma_free_coherent(\u0026lp-\u003epdev-\u003edev,\n+\tif (rxq-\u003ering) {\n+\t\tdma_free_coherent(\u0026bp-\u003epdev-\u003edev,\n \t\t\t\t AT91ETHER_MAX_RX_DESCR *\n-\t\t\t\t macb_dma_desc_get_size(lp),\n-\t\t\t\t q-\u003erx_ring, q-\u003erx_ring_dma);\n-\t\tq-\u003erx_ring = NULL;\n+\t\t\t\t macb_dma_desc_get_size(\u0026bp-\u003einfo),\n+\t\t\t\t rxq-\u003ering, rxq-\u003ering_dma);\n+\t\trxq-\u003ering = NULL;\n \t}\n \n-\tif (q-\u003erx_buffers) {\n-\t\tdma_free_coherent(\u0026lp-\u003epdev-\u003edev,\n+\tif (rxq-\u003ebuffers) {\n+\t\tdma_free_coherent(\u0026bp-\u003epdev-\u003edev,\n \t\t\t\t AT91ETHER_MAX_RX_DESCR *\n \t\t\t\t AT91ETHER_MAX_RBUFF_SZ,\n-\t\t\t\t q-\u003erx_buffers, q-\u003erx_buffers_dma);\n-\t\tq-\u003erx_buffers = NULL;\n+\t\t\t\t rxq-\u003ebuffers, rxq-\u003ebuffers_dma);\n+\t\trxq-\u003ebuffers = NULL;\n \t}\n }\n \n /* Initialize and start the Receiver and Transmit subsystems */\n-static int at91ether_start(struct macb *lp)\n+static int at91ether_start(struct macb *bp)\n {\n-\tstruct macb_queue *q = \u0026lp-\u003equeues[0];\n+\tstruct macb_rxq *rxq = \u0026bp-\u003ectx-\u003erxq[0];\n \tstruct macb_dma_desc *desc;\n \tdma_addr_t addr;\n \tu32 ctl;\n \tint i, ret;\n \n-\tret = at91ether_alloc_coherent(lp);\n+\tret = at91ether_alloc_coherent(bp);\n \tif (ret)\n \t\treturn ret;\n \n-\taddr = q-\u003erx_buffers_dma;\n+\taddr = rxq-\u003ebuffers_dma;\n \tfor (i = 0; i \u003c AT91ETHER_MAX_RX_DESCR; i++) {\n-\t\tdesc = macb_rx_desc(q, i);\n-\t\tmacb_set_addr(lp, desc, addr);\n+\t\tdesc = macb_rx_desc(bp-\u003ectx, 0, i);\n+\t\tmacb_set_addr(\u0026bp-\u003einfo, desc, addr);\n \t\tdesc-\u003ectrl = 0;\n \t\taddr += AT91ETHER_MAX_RBUFF_SZ;\n \t}\n@@ -5018,17 +5270,17 @@ static int at91ether_start(struct macb *lp)\n \tdesc-\u003eaddr |= MACB_BIT(RX_WRAP);\n \n \t/* Reset buffer index */\n-\tq-\u003erx_tail = 0;\n+\trxq-\u003etail = 0;\n \n \t/* Program address of descriptor list in Rx Buffer Queue register */\n-\tmacb_writel(lp, RBQP, q-\u003erx_ring_dma);\n+\tmacb_writel(bp, RBQP, rxq-\u003ering_dma);\n \n \t/* Enable Receive and Transmit */\n-\tctl = macb_readl(lp, NCR);\n-\tmacb_writel(lp, NCR, ctl | MACB_BIT(RE) | MACB_BIT(TE));\n+\tctl = macb_readl(bp, NCR);\n+\tmacb_writel(bp, NCR, ctl | MACB_BIT(RE) | MACB_BIT(TE));\n \n \t/* Enable MAC interrupts */\n-\tmacb_writel(lp, IER, MACB_BIT(RCOMP)\t|\n+\tmacb_writel(bp, IER, MACB_BIT(RCOMP)\t|\n \t\t\t MACB_BIT(RXUBR)\t|\n \t\t\t MACB_BIT(ISR_TUND)\t|\n \t\t\t MACB_BIT(ISR_RLE)\t|\n@@ -5039,12 +5291,12 @@ static int at91ether_start(struct macb *lp)\n \treturn 0;\n }\n \n-static void at91ether_stop(struct macb *lp)\n+static void at91ether_stop(struct macb *bp)\n {\n \tu32 ctl;\n \n \t/* Disable MAC interrupts */\n-\tmacb_writel(lp, IDR, MACB_BIT(RCOMP)\t|\n+\tmacb_writel(bp, IDR, MACB_BIT(RCOMP)\t|\n \t\t\t MACB_BIT(RXUBR)\t|\n \t\t\t MACB_BIT(ISR_TUND)\t|\n \t\t\t MACB_BIT(ISR_RLE)\t|\n@@ -5053,96 +5305,112 @@ static void at91ether_stop(struct macb *lp)\n \t\t\t MACB_BIT(HRESP));\n \n \t/* Disable Receiver and Transmitter */\n-\tctl = macb_readl(lp, NCR);\n-\tmacb_writel(lp, NCR, ctl \u0026 ~(MACB_BIT(TE) | MACB_BIT(RE)));\n+\tctl = macb_readl(bp, NCR);\n+\tmacb_writel(bp, NCR, ctl \u0026 ~(MACB_BIT(TE) | MACB_BIT(RE)));\n \n \t/* Free resources. */\n-\tat91ether_free_coherent(lp);\n+\tat91ether_free_coherent(bp);\n }\n \n /* Open the ethernet interface */\n-static int at91ether_open(struct net_device *dev)\n+static int at91ether_open(struct net_device *netdev)\n {\n-\tstruct macb *lp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tu32 ctl;\n \tint ret;\n \n-\tret = pm_runtime_resume_and_get(\u0026lp-\u003epdev-\u003edev);\n+\tret = pm_runtime_resume_and_get(\u0026bp-\u003epdev-\u003edev);\n \tif (ret \u003c 0)\n \t\treturn ret;\n \n+\tbp-\u003ectx = kzalloc_obj(*bp-\u003ectx);\n+\tif (!bp-\u003ectx) {\n+\t\tret = -ENOMEM;\n+\t\tgoto pm_exit;\n+\t}\n+\tbp-\u003ectx-\u003einfo = \u0026bp-\u003einfo;\n+\n \t/* Clear internal statistics */\n-\tctl = macb_readl(lp, NCR);\n-\tmacb_writel(lp, NCR, ctl | MACB_BIT(CLRSTAT));\n+\tctl = macb_readl(bp, NCR);\n+\tmacb_writel(bp, NCR, ctl | MACB_BIT(CLRSTAT));\n \n-\tmacb_set_hwaddr(lp);\n+\tmacb_set_hwaddr(bp);\n \n-\tret = at91ether_start(lp);\n+\tret = at91ether_start(bp);\n \tif (ret)\n-\t\tgoto pm_exit;\n+\t\tgoto free_ctx;\n \n-\tret = macb_phylink_connect(lp);\n+\tret = macb_phylink_connect(bp);\n \tif (ret)\n \t\tgoto stop;\n \n-\tnetif_start_queue(dev);\n+\tnetif_start_queue(netdev);\n \n \treturn 0;\n \n stop:\n-\tat91ether_stop(lp);\n+\tat91ether_stop(bp);\n+free_ctx:\n+\tkfree(bp-\u003ectx);\n+\tbp-\u003ectx = NULL;\n pm_exit:\n-\tpm_runtime_put_sync(\u0026lp-\u003epdev-\u003edev);\n+\tpm_runtime_put_sync(\u0026bp-\u003epdev-\u003edev);\n \treturn ret;\n }\n \n /* Close the interface */\n-static int at91ether_close(struct net_device *dev)\n+static int at91ether_close(struct net_device *netdev)\n {\n-\tstruct macb *lp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \n-\tnetif_stop_queue(dev);\n+\tnetif_stop_queue(netdev);\n \n-\tphylink_stop(lp-\u003ephylink);\n-\tphylink_disconnect_phy(lp-\u003ephylink);\n+\tphylink_stop(bp-\u003ephylink);\n+\tphylink_disconnect_phy(bp-\u003ephylink);\n \n-\tat91ether_stop(lp);\n+\tat91ether_stop(bp);\n \n-\tpm_runtime_put(\u0026lp-\u003epdev-\u003edev);\n+\tkfree(bp-\u003ectx);\n+\tbp-\u003ectx = NULL;\n+\n+\tpm_runtime_put(\u0026bp-\u003epdev-\u003edev);\n \n \treturn 0;\n }\n \n /* Transmit packet */\n static netdev_tx_t at91ether_start_xmit(struct sk_buff *skb,\n-\t\t\t\t\tstruct net_device *dev)\n+\t\t\t\t\tstruct net_device *netdev)\n {\n-\tstruct macb *lp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n+\tstruct device *dev = \u0026bp-\u003epdev-\u003edev;\n \n-\tif (macb_readl(lp, TSR) \u0026 MACB_BIT(RM9200_BNQ)) {\n+\tif (macb_readl(bp, TSR) \u0026 MACB_BIT(RM9200_BNQ)) {\n \t\tint desc = 0;\n \n-\t\tnetif_stop_queue(dev);\n+\t\tnetif_stop_queue(netdev);\n \n \t\t/* Store packet information (to free when Tx completed) */\n-\t\tlp-\u003erm9200_txq[desc].skb = skb;\n-\t\tlp-\u003erm9200_txq[desc].size = skb-\u003elen;\n-\t\tlp-\u003erm9200_txq[desc].mapping = dma_map_single(\u0026lp-\u003epdev-\u003edev, skb-\u003edata,\n-\t\t\t\t\t\t\t skb-\u003elen, DMA_TO_DEVICE);\n-\t\tif (dma_mapping_error(\u0026lp-\u003epdev-\u003edev, lp-\u003erm9200_txq[desc].mapping)) {\n+\t\tbp-\u003erm9200_txq[desc].skb = skb;\n+\t\tbp-\u003erm9200_txq[desc].size = skb-\u003elen;\n+\t\tbp-\u003erm9200_txq[desc].mapping = dma_map_single(dev, skb-\u003edata,\n+\t\t\t\t\t\t\t skb-\u003elen,\n+\t\t\t\t\t\t\t DMA_TO_DEVICE);\n+\t\tif (dma_mapping_error(dev, bp-\u003erm9200_txq[desc].mapping)) {\n \t\t\tdev_kfree_skb_any(skb);\n-\t\t\tdev-\u003estats.tx_dropped++;\n-\t\t\tnetdev_err(dev, \"%s: DMA mapping error\\n\", __func__);\n+\t\t\tnetdev-\u003estats.tx_dropped++;\n+\t\t\tnetdev_err(netdev, \"%s: DMA mapping error\\n\", __func__);\n \t\t\treturn NETDEV_TX_OK;\n \t\t}\n \n \t\t/* Set address of the data in the Transmit Address register */\n-\t\tmacb_writel(lp, TAR, lp-\u003erm9200_txq[desc].mapping);\n+\t\tmacb_writel(bp, TAR, bp-\u003erm9200_txq[desc].mapping);\n \t\t/* Set length of the packet in the Transmit Control register */\n-\t\tmacb_writel(lp, TCR, skb-\u003elen);\n+\t\tmacb_writel(bp, TCR, skb-\u003elen);\n \n \t} else {\n-\t\tnetdev_err(dev, \"%s called, but device is busy!\\n\", __func__);\n+\t\tnetdev_err(netdev, \"%s called, but device is busy!\\n\",\n+\t\t\t __func__);\n \t\treturn NETDEV_TX_BUSY;\n \t}\n \n@@ -5152,104 +5420,106 @@ static netdev_tx_t at91ether_start_xmit(struct sk_buff *skb,\n /* Extract received frame from buffer descriptors and sent to upper layers.\n * (Called from interrupt context)\n */\n-static void at91ether_rx(struct net_device *dev)\n+static void at91ether_rx(struct net_device *netdev)\n {\n-\tstruct macb *lp = netdev_priv(dev);\n-\tstruct macb_queue *q = \u0026lp-\u003equeues[0];\n+\tstruct macb *bp = netdev_priv(netdev);\n+\tstruct macb_rxq *rxq = \u0026bp-\u003ectx-\u003erxq[0];\n \tstruct macb_dma_desc *desc;\n \tunsigned char *p_recv;\n \tstruct sk_buff *skb;\n \tunsigned int pktlen;\n \n-\tdesc = macb_rx_desc(q, q-\u003erx_tail);\n+\tdesc = macb_rx_desc(bp-\u003ectx, 0, rxq-\u003etail);\n \twhile (desc-\u003eaddr \u0026 MACB_BIT(RX_USED)) {\n-\t\tp_recv = q-\u003erx_buffers + q-\u003erx_tail * AT91ETHER_MAX_RBUFF_SZ;\n+\t\tp_recv = rxq-\u003ebuffers + rxq-\u003etail * AT91ETHER_MAX_RBUFF_SZ;\n \t\tpktlen = MACB_BF(RX_FRMLEN, desc-\u003ectrl);\n-\t\tskb = netdev_alloc_skb(dev, pktlen + 2);\n+\t\tskb = netdev_alloc_skb(netdev, pktlen + 2);\n \t\tif (skb) {\n \t\t\tskb_reserve(skb, 2);\n \t\t\tskb_put_data(skb, p_recv, pktlen);\n \n-\t\t\tskb-\u003eprotocol = eth_type_trans(skb, dev);\n-\t\t\tdev-\u003estats.rx_packets++;\n-\t\t\tdev-\u003estats.rx_bytes += pktlen;\n+\t\t\tskb-\u003eprotocol = eth_type_trans(skb, netdev);\n+\t\t\tnetdev-\u003estats.rx_packets++;\n+\t\t\tnetdev-\u003estats.rx_bytes += pktlen;\n \t\t\tnetif_rx(skb);\n \t\t} else {\n-\t\t\tdev-\u003estats.rx_dropped++;\n+\t\t\tnetdev-\u003estats.rx_dropped++;\n \t\t}\n \n \t\tif (desc-\u003ectrl \u0026 MACB_BIT(RX_MHASH_MATCH))\n-\t\t\tdev-\u003estats.multicast++;\n+\t\t\tnetdev-\u003estats.multicast++;\n \n \t\t/* reset ownership bit */\n \t\tdesc-\u003eaddr \u0026= ~MACB_BIT(RX_USED);\n \n \t\t/* wrap after last buffer */\n-\t\tif (q-\u003erx_tail == AT91ETHER_MAX_RX_DESCR - 1)\n-\t\t\tq-\u003erx_tail = 0;\n+\t\tif (rxq-\u003etail == AT91ETHER_MAX_RX_DESCR - 1)\n+\t\t\trxq-\u003etail = 0;\n \t\telse\n-\t\t\tq-\u003erx_tail++;\n+\t\t\trxq-\u003etail++;\n \n-\t\tdesc = macb_rx_desc(q, q-\u003erx_tail);\n+\t\tdesc = macb_rx_desc(bp-\u003ectx, 0, rxq-\u003etail);\n \t}\n }\n \n /* MAC interrupt handler */\n static irqreturn_t at91ether_interrupt(int irq, void *dev_id)\n {\n-\tstruct net_device *dev = dev_id;\n-\tstruct macb *lp = netdev_priv(dev);\n+\tstruct net_device *netdev = dev_id;\n+\tstruct macb *bp = netdev_priv(netdev);\n \tu32 intstatus, ctl;\n \tunsigned int desc;\n \n \t/* MAC Interrupt Status register indicates what interrupts are pending.\n \t * It is automatically cleared once read.\n \t */\n-\tintstatus = macb_readl(lp, ISR);\n+\tintstatus = macb_readl(bp, ISR);\n \n \t/* Receive complete */\n \tif (intstatus \u0026 MACB_BIT(RCOMP))\n-\t\tat91ether_rx(dev);\n+\t\tat91ether_rx(netdev);\n \n \t/* Transmit complete */\n \tif (intstatus \u0026 MACB_BIT(TCOMP)) {\n \t\t/* The TCOM bit is set even if the transmission failed */\n \t\tif (intstatus \u0026 (MACB_BIT(ISR_TUND) | MACB_BIT(ISR_RLE)))\n-\t\t\tdev-\u003estats.tx_errors++;\n+\t\t\tnetdev-\u003estats.tx_errors++;\n \n \t\tdesc = 0;\n-\t\tif (lp-\u003erm9200_txq[desc].skb) {\n-\t\t\tdev_consume_skb_irq(lp-\u003erm9200_txq[desc].skb);\n-\t\t\tlp-\u003erm9200_txq[desc].skb = NULL;\n-\t\t\tdma_unmap_single(\u0026lp-\u003epdev-\u003edev, lp-\u003erm9200_txq[desc].mapping,\n-\t\t\t\t\t lp-\u003erm9200_txq[desc].size, DMA_TO_DEVICE);\n-\t\t\tdev-\u003estats.tx_packets++;\n-\t\t\tdev-\u003estats.tx_bytes += lp-\u003erm9200_txq[desc].size;\n+\t\tif (bp-\u003erm9200_txq[desc].skb) {\n+\t\t\tdev_consume_skb_irq(bp-\u003erm9200_txq[desc].skb);\n+\t\t\tbp-\u003erm9200_txq[desc].skb = NULL;\n+\t\t\tdma_unmap_single(\u0026bp-\u003epdev-\u003edev,\n+\t\t\t\t\t bp-\u003erm9200_txq[desc].mapping,\n+\t\t\t\t\t bp-\u003erm9200_txq[desc].size,\n+\t\t\t\t\t DMA_TO_DEVICE);\n+\t\t\tnetdev-\u003estats.tx_packets++;\n+\t\t\tnetdev-\u003estats.tx_bytes += bp-\u003erm9200_txq[desc].size;\n \t\t}\n-\t\tnetif_wake_queue(dev);\n+\t\tnetif_wake_queue(netdev);\n \t}\n \n \t/* Work-around for EMAC Errata section 41.3.1 */\n \tif (intstatus \u0026 MACB_BIT(RXUBR)) {\n-\t\tctl = macb_readl(lp, NCR);\n-\t\tmacb_writel(lp, NCR, ctl \u0026 ~MACB_BIT(RE));\n+\t\tctl = macb_readl(bp, NCR);\n+\t\tmacb_writel(bp, NCR, ctl \u0026 ~MACB_BIT(RE));\n \t\twmb();\n-\t\tmacb_writel(lp, NCR, ctl | MACB_BIT(RE));\n+\t\tmacb_writel(bp, NCR, ctl | MACB_BIT(RE));\n \t}\n \n \tif (intstatus \u0026 MACB_BIT(ISR_ROVR))\n-\t\tnetdev_err(dev, \"ROVR error\\n\");\n+\t\tnetdev_err(netdev, \"ROVR error\\n\");\n \n \treturn IRQ_HANDLED;\n }\n \n #ifdef CONFIG_NET_POLL_CONTROLLER\n-static void at91ether_poll_controller(struct net_device *dev)\n+static void at91ether_poll_controller(struct net_device *netdev)\n {\n \tunsigned long flags;\n \n \tlocal_irq_save(flags);\n-\tat91ether_interrupt(dev-\u003eirq, dev);\n+\tat91ether_interrupt(netdev-\u003eirq, netdev);\n \tlocal_irq_restore(flags);\n }\n #endif\n@@ -5296,17 +5566,17 @@ static int at91ether_clk_init(struct platform_device *pdev, struct clk **pclk,\n \n static int at91ether_init(struct platform_device *pdev)\n {\n-\tstruct net_device *dev = platform_get_drvdata(pdev);\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct net_device *netdev = platform_get_drvdata(pdev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tint err;\n \n \tbp-\u003equeues[0].bp = bp;\n \n-\tdev-\u003enetdev_ops = \u0026at91ether_netdev_ops;\n-\tdev-\u003eethtool_ops = \u0026macb_ethtool_ops;\n+\tnetdev-\u003enetdev_ops = \u0026at91ether_netdev_ops;\n+\tnetdev-\u003eethtool_ops = \u0026macb_ethtool_ops;\n \n-\terr = devm_request_irq(\u0026pdev-\u003edev, dev-\u003eirq, at91ether_interrupt,\n-\t\t\t 0, dev-\u003ename, dev);\n+\terr = devm_request_irq(\u0026pdev-\u003edev, netdev-\u003eirq, at91ether_interrupt,\n+\t\t\t 0, netdev-\u003ename, netdev);\n \tif (err)\n \t\treturn err;\n \n@@ -5435,8 +5705,8 @@ static int fu540_c000_init(struct platform_device *pdev)\n \n static int init_reset_optional(struct platform_device *pdev)\n {\n-\tstruct net_device *dev = platform_get_drvdata(pdev);\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct net_device *netdev = platform_get_drvdata(pdev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tint ret;\n \n \tif (bp-\u003ephy_interface == PHY_INTERFACE_MODE_SGMII) {\n@@ -5511,6 +5781,38 @@ static int eyeq5_init(struct platform_device *pdev)\n \treturn ret;\n }\n \n+static int macb_alloc_tieoff(struct macb *bp)\n+{\n+\t/* Tieoff is a workaround in case HW cannot disable queues, for PM. */\n+\tif (bp-\u003ecaps \u0026 MACB_CAPS_QUEUE_DISABLE)\n+\t\treturn 0;\n+\n+\tbp-\u003erx_ring_tieoff = dma_alloc_coherent(\u0026bp-\u003epdev-\u003edev,\n+\t\t\t\t\t\tmacb_dma_desc_get_size(\u0026bp-\u003einfo),\n+\t\t\t\t\t\t\u0026bp-\u003erx_ring_tieoff_dma,\n+\t\t\t\t\t\tGFP_KERNEL);\n+\tif (!bp-\u003erx_ring_tieoff)\n+\t\treturn -ENOMEM;\n+\n+\tmacb_set_addr(\u0026bp-\u003einfo, bp-\u003erx_ring_tieoff,\n+\t\t MACB_BIT(RX_WRAP) | MACB_BIT(RX_USED));\n+\n+\tbp-\u003erx_ring_tieoff-\u003ectrl = 0;\n+\n+\treturn 0;\n+}\n+\n+static void macb_free_tieoff(struct macb *bp)\n+{\n+\tif (!bp-\u003erx_ring_tieoff)\n+\t\treturn;\n+\n+\tdma_free_coherent(\u0026bp-\u003epdev-\u003edev, macb_dma_desc_get_size(\u0026bp-\u003einfo),\n+\t\t\t bp-\u003erx_ring_tieoff,\n+\t\t\t bp-\u003erx_ring_tieoff_dma);\n+\tbp-\u003erx_ring_tieoff = NULL;\n+}\n+\n static const struct macb_usrio_config mpfs_usrio = {\n \t.tsu_source = 0,\n };\n@@ -5744,7 +6046,7 @@ static int macb_probe(struct platform_device *pdev)\n \tconst struct macb_config *macb_config;\n \tstruct clk *tsu_clk = NULL;\n \tphy_interface_t interface;\n-\tstruct net_device *dev;\n+\tstruct net_device *netdev;\n \tstruct resource *regs;\n \tu32 wtrmrk_rst_val;\n \tvoid __iomem *mem;\n@@ -5779,19 +6081,19 @@ static int macb_probe(struct platform_device *pdev)\n \t\tgoto err_disable_clocks;\n \t}\n \n-\tdev = alloc_etherdev_mq(sizeof(*bp), num_queues);\n-\tif (!dev) {\n+\tnetdev = alloc_etherdev_mq(sizeof(*bp), num_queues);\n+\tif (!netdev) {\n \t\terr = -ENOMEM;\n \t\tgoto err_disable_clocks;\n \t}\n \n-\tdev-\u003ebase_addr = regs-\u003estart;\n+\tnetdev-\u003ebase_addr = regs-\u003estart;\n \n-\tSET_NETDEV_DEV(dev, \u0026pdev-\u003edev);\n+\tSET_NETDEV_DEV(netdev, \u0026pdev-\u003edev);\n \n-\tbp = netdev_priv(dev);\n+\tbp = netdev_priv(netdev);\n \tbp-\u003epdev = pdev;\n-\tbp-\u003edev = dev;\n+\tbp-\u003enetdev = netdev;\n \tbp-\u003eregs = mem;\n \tbp-\u003enative_io = native_io;\n \tif (native_io) {\n@@ -5809,6 +6111,8 @@ static int macb_probe(struct platform_device *pdev)\n \tbp-\u003erx_clk = rx_clk;\n \tbp-\u003etsu_clk = tsu_clk;\n \tbp-\u003ejumbo_max_len = macb_config-\u003ejumbo_max_len;\n+\tbp-\u003econfigured_rx_ring_size = DEFAULT_RX_RING_SIZE;\n+\tbp-\u003econfigured_tx_ring_size = DEFAULT_TX_RING_SIZE;\n \n \tif (!hw_is_gem(bp-\u003eregs, bp-\u003enative_io))\n \t\tbp-\u003emax_tx_length = MACB_MAX_TX_LEN;\n@@ -5850,6 +6154,7 @@ static int macb_probe(struct platform_device *pdev)\n \t}\n \tspin_lock_init(\u0026bp-\u003elock);\n \tspin_lock_init(\u0026bp-\u003estats_lock);\n+\tmutex_init(\u0026bp-\u003emac_cfg_lock);\n \n \t/* setup capabilities */\n \tmacb_configure_caps(bp, macb_config);\n@@ -5864,39 +6169,39 @@ static int macb_probe(struct platform_device *pdev)\n \t\tbp-\u003ecaps |= MACB_CAPS_DMA_64B;\n \t}\n #endif\n-\tplatform_set_drvdata(pdev, dev);\n+\tplatform_set_drvdata(pdev, netdev);\n \n-\tdev-\u003eirq = platform_get_irq(pdev, 0);\n-\tif (dev-\u003eirq \u003c 0) {\n-\t\terr = dev-\u003eirq;\n+\tnetdev-\u003eirq = platform_get_irq(pdev, 0);\n+\tif (netdev-\u003eirq \u003c 0) {\n+\t\terr = netdev-\u003eirq;\n \t\tgoto err_out_free_netdev;\n \t}\n \n \t/* MTU range: 68 - 1518 or 10240 */\n-\tdev-\u003emin_mtu = GEM_MTU_MIN_SIZE;\n+\tnetdev-\u003emin_mtu = GEM_MTU_MIN_SIZE;\n \tif ((bp-\u003ecaps \u0026 MACB_CAPS_JUMBO) \u0026\u0026 bp-\u003ejumbo_max_len)\n-\t\tdev-\u003emax_mtu = MIN(bp-\u003ejumbo_max_len, RX_BUFFER_MAX) -\n+\t\tnetdev-\u003emax_mtu = MIN(bp-\u003ejumbo_max_len, RX_BUFFER_MAX) -\n \t\t\t\tETH_HLEN - ETH_FCS_LEN;\n \telse\n-\t\tdev-\u003emax_mtu = 1536 - ETH_HLEN - ETH_FCS_LEN;\n+\t\tnetdev-\u003emax_mtu = 1536 - ETH_HLEN - ETH_FCS_LEN;\n \n \tif (bp-\u003ecaps \u0026 MACB_CAPS_BD_RD_PREFETCH) {\n \t\tval = GEM_BFEXT(RXBD_RDBUFF, gem_readl(bp, DCFG10));\n \t\tif (val)\n \t\t\tbp-\u003erx_bd_rd_prefetch = (2 \u003c\u003c (val - 1)) *\n-\t\t\t\t\t\tmacb_dma_desc_get_size(bp);\n+\t\t\t\t\t\tmacb_dma_desc_get_size(\u0026bp-\u003einfo);\n \n \t\tval = GEM_BFEXT(TXBD_RDBUFF, gem_readl(bp, DCFG10));\n \t\tif (val)\n \t\t\tbp-\u003etx_bd_rd_prefetch = (2 \u003c\u003c (val - 1)) *\n-\t\t\t\t\t\tmacb_dma_desc_get_size(bp);\n+\t\t\t\t\t\tmacb_dma_desc_get_size(\u0026bp-\u003einfo);\n \t}\n \n \tbp-\u003erx_intr_mask = MACB_RX_INT_FLAGS;\n \tif (bp-\u003ecaps \u0026 MACB_CAPS_NEEDS_RSTONUBR)\n \t\tbp-\u003erx_intr_mask |= MACB_BIT(RXUBR);\n \n-\terr = of_get_ethdev_address(np, bp-\u003edev);\n+\terr = of_get_ethdev_address(np, bp-\u003enetdev);\n \tif (err == -EPROBE_DEFER)\n \t\tgoto err_out_free_netdev;\n \telse if (err)\n@@ -5918,25 +6223,33 @@ static int macb_probe(struct platform_device *pdev)\n \tif (err)\n \t\tgoto err_out_phy_exit;\n \n-\tnetif_carrier_off(dev);\n+\tnetif_carrier_off(netdev);\n+\n+\terr = macb_alloc_tieoff(bp);\n+\tif (err)\n+\t\tgoto err_out_unregister_mdio;\n \n-\terr = register_netdev(dev);\n+\terr = register_netdev(netdev);\n \tif (err) {\n \t\tdev_err(\u0026pdev-\u003edev, \"Cannot register net device, aborting.\\n\");\n-\t\tgoto err_out_unregister_mdio;\n+\t\tgoto err_out_free_tieoff;\n \t}\n \n \tINIT_WORK(\u0026bp-\u003ehresp_err_bh_work, macb_hresp_error_task);\n \tINIT_DELAYED_WORK(\u0026bp-\u003etx_lpi_work, macb_tx_lpi_work_fn);\n \n-\tnetdev_info(dev, \"Cadence %s rev 0x%08x at 0x%08lx irq %d (%pM)\\n\",\n-\t\t macb_is_gem(bp) ? \"GEM\" : \"MACB\", macb_readl(bp, MID),\n-\t\t dev-\u003ebase_addr, dev-\u003eirq, dev-\u003edev_addr);\n+\tnetdev_info(netdev, \"Cadence %s rev 0x%08x at 0x%08lx irq %d (%pM)\\n\",\n+\t\t macb_is_gem(\u0026bp-\u003einfo) ? \"GEM\" : \"MACB\",\n+\t\t macb_readl(bp, MID), netdev-\u003ebase_addr, netdev-\u003eirq,\n+\t\t netdev-\u003edev_addr);\n \n \tpm_runtime_put_autosuspend(\u0026bp-\u003epdev-\u003edev);\n \n \treturn 0;\n \n+err_out_free_tieoff:\n+\tmacb_free_tieoff(bp);\n+\n err_out_unregister_mdio:\n \tmdiobus_unregister(bp-\u003emii_bus);\n \tmdiobus_free(bp-\u003emii_bus);\n@@ -5945,7 +6258,7 @@ static int macb_probe(struct platform_device *pdev)\n \tphy_exit(bp-\u003ephy);\n \n err_out_free_netdev:\n-\tfree_netdev(dev);\n+\tfree_netdev(netdev);\n \n err_disable_clocks:\n \tmacb_clks_disable(pclk, hclk, tx_clk, rx_clk, tsu_clk);\n@@ -5958,14 +6271,15 @@ static int macb_probe(struct platform_device *pdev)\n \n static void macb_remove(struct platform_device *pdev)\n {\n-\tstruct net_device *dev;\n+\tstruct net_device *netdev;\n \tstruct macb *bp;\n \n-\tdev = platform_get_drvdata(pdev);\n+\tnetdev = platform_get_drvdata(pdev);\n \n-\tif (dev) {\n-\t\tbp = netdev_priv(dev);\n-\t\tunregister_netdev(dev);\n+\tif (netdev) {\n+\t\tbp = netdev_priv(netdev);\n+\t\tunregister_netdev(netdev);\n+\t\tmacb_free_tieoff(bp);\n \t\tphy_exit(bp-\u003ephy);\n \t\tmdiobus_unregister(bp-\u003emii_bus);\n \t\tmdiobus_free(bp-\u003emii_bus);\n@@ -5977,7 +6291,7 @@ static void macb_remove(struct platform_device *pdev)\n \t\tpm_runtime_dont_use_autosuspend(\u0026pdev-\u003edev);\n \t\tpm_runtime_set_suspended(\u0026pdev-\u003edev);\n \t\tphylink_destroy(bp-\u003ephylink);\n-\t\tfree_netdev(dev);\n+\t\tfree_netdev(netdev);\n \t}\n }\n \n@@ -5992,7 +6306,7 @@ static int __maybe_unused macb_suspend(struct device *dev)\n \tu32 tmp, ifa_local;\n \tunsigned int q;\n \n-\tif (!device_may_wakeup(\u0026bp-\u003edev-\u003edev))\n+\tif (!device_may_wakeup(\u0026bp-\u003enetdev-\u003edev))\n \t\tphy_exit(bp-\u003ephy);\n \n \tif (!netif_running(netdev))\n@@ -6002,7 +6316,7 @@ static int __maybe_unused macb_suspend(struct device *dev)\n \t\tif (bp-\u003ewolopts \u0026 WAKE_ARP) {\n \t\t\t/* Check for IP address in WOL ARP mode */\n \t\t\trcu_read_lock();\n-\t\t\tidev = __in_dev_get_rcu(bp-\u003edev);\n+\t\t\tidev = __in_dev_get_rcu(bp-\u003enetdev);\n \t\t\tif (idev)\n \t\t\t\tifa = rcu_dereference(idev-\u003eifa_list);\n \t\t\tif (!ifa) {\n@@ -6054,7 +6368,7 @@ static int __maybe_unused macb_suspend(struct device *dev)\n \t\t\ttmp |= MACB_BFEXT(IP, ifa_local);\n \t\t}\n \n-\t\tif (macb_is_gem(bp)) {\n+\t\tif (macb_is_gem(\u0026bp-\u003einfo)) {\n \t\t\tqueue_writel(bp-\u003equeues, IER, GEM_BIT(WOL));\n \t\t\tgem_writel(bp, WOL, tmp);\n \t\t} else {\n@@ -6100,11 +6414,12 @@ static int __maybe_unused macb_resume(struct device *dev)\n {\n \tstruct net_device *netdev = dev_get_drvdata(dev);\n \tstruct macb *bp = netdev_priv(netdev);\n+\tstruct macb_context *ctx = bp-\u003ectx;\n \tstruct macb_queue *queue;\n \tunsigned long flags;\n \tunsigned int q;\n \n-\tif (!device_may_wakeup(\u0026bp-\u003edev-\u003edev))\n+\tif (!device_may_wakeup(\u0026bp-\u003enetdev-\u003edev))\n \t\tphy_init(bp-\u003ephy);\n \n \tif (!netif_running(netdev))\n@@ -6116,7 +6431,7 @@ static int __maybe_unused macb_resume(struct device *dev)\n \tif (bp-\u003ewol \u0026 MACB_WOL_ENABLED) {\n \t\tspin_lock_irqsave(\u0026bp-\u003elock, flags);\n \t\t/* Disable WoL */\n-\t\tif (macb_is_gem(bp)) {\n+\t\tif (macb_is_gem(\u0026bp-\u003einfo)) {\n \t\t\tqueue_writel(bp-\u003equeues, IDR, GEM_BIT(WOL));\n \t\t\tgem_writel(bp, WOL, 0);\n \t\t} else {\n@@ -6144,10 +6459,10 @@ static int __maybe_unused macb_resume(struct device *dev)\n \tfor (q = 0, queue = bp-\u003equeues; q \u003c bp-\u003enum_queues;\n \t ++q, ++queue) {\n \t\tif (!(bp-\u003ecaps \u0026 MACB_CAPS_MACB_IS_EMAC)) {\n-\t\t\tif (macb_is_gem(bp))\n-\t\t\t\tgem_init_rx_ring(queue);\n+\t\t\tif (macb_is_gem(\u0026bp-\u003einfo))\n+\t\t\t\tgem_init_rx_ring(ctx, q);\n \t\t\telse\n-\t\t\t\tmacb_init_rx_ring(queue);\n+\t\t\t\tmacb_init_rx_ring(ctx, q);\n \t\t}\n \n \t\tnapi_enable(\u0026queue-\u003enapi_rx);\ndiff --git a/drivers/net/ethernet/cadence/macb_pci.c b/drivers/net/ethernet/cadence/macb_pci.c\nindex b79dec17e6b099..ac009007118f31 100644\n--- a/drivers/net/ethernet/cadence/macb_pci.c\n+++ b/drivers/net/ethernet/cadence/macb_pci.c\n@@ -24,48 +24,48 @@\n #define GEM_PCLK_RATE 50000000\n #define GEM_HCLK_RATE 50000000\n \n-static int macb_probe(struct pci_dev *pdev, const struct pci_device_id *id)\n+static int macb_probe(struct pci_dev *pci, const struct pci_device_id *id)\n {\n \tint err;\n-\tstruct platform_device *plat_dev;\n+\tstruct platform_device *pdev;\n \tstruct platform_device_info plat_info;\n \tstruct macb_platform_data plat_data;\n \tstruct resource res[2];\n \n \t/* enable pci device */\n-\terr = pcim_enable_device(pdev);\n+\terr = pcim_enable_device(pci);\n \tif (err \u003c 0) {\n-\t\tdev_err(\u0026pdev-\u003edev, \"Enabling PCI device has failed: %d\", err);\n+\t\tdev_err(\u0026pci-\u003edev, \"Enabling PCI device has failed: %d\", err);\n \t\treturn err;\n \t}\n \n-\tpci_set_master(pdev);\n+\tpci_set_master(pci);\n \n \t/* set up resources */\n \tmemset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));\n-\tres[0].start = pci_resource_start(pdev, 0);\n-\tres[0].end = pci_resource_end(pdev, 0);\n+\tres[0].start = pci_resource_start(pci, 0);\n+\tres[0].end = pci_resource_end(pci, 0);\n \tres[0].name = PCI_DRIVER_NAME;\n \tres[0].flags = IORESOURCE_MEM;\n-\tres[1].start = pci_irq_vector(pdev, 0);\n+\tres[1].start = pci_irq_vector(pci, 0);\n \tres[1].name = PCI_DRIVER_NAME;\n \tres[1].flags = IORESOURCE_IRQ;\n \n-\tdev_info(\u0026pdev-\u003edev, \"EMAC physical base addr: %pa\\n\",\n+\tdev_info(\u0026pci-\u003edev, \"EMAC physical base addr: %pa\\n\",\n \t\t \u0026res[0].start);\n \n \t/* set up macb platform data */\n \tmemset(\u0026plat_data, 0, sizeof(plat_data));\n \n \t/* initialize clocks */\n-\tplat_data.pclk = clk_register_fixed_rate(\u0026pdev-\u003edev, \"pclk\", NULL, 0,\n+\tplat_data.pclk = clk_register_fixed_rate(\u0026pci-\u003edev, \"pclk\", NULL, 0,\n \t\t\t\t\t\t GEM_PCLK_RATE);\n \tif (IS_ERR(plat_data.pclk)) {\n \t\terr = PTR_ERR(plat_data.pclk);\n \t\tgoto err_pclk_register;\n \t}\n \n-\tplat_data.hclk = clk_register_fixed_rate(\u0026pdev-\u003edev, \"hclk\", NULL, 0,\n+\tplat_data.hclk = clk_register_fixed_rate(\u0026pci-\u003edev, \"hclk\", NULL, 0,\n \t\t\t\t\t\t GEM_HCLK_RATE);\n \tif (IS_ERR(plat_data.hclk)) {\n \t\terr = PTR_ERR(plat_data.hclk);\n@@ -74,24 +74,24 @@ static int macb_probe(struct pci_dev *pdev, const struct pci_device_id *id)\n \n \t/* set up platform device info */\n \tmemset(\u0026plat_info, 0, sizeof(plat_info));\n-\tplat_info.parent = \u0026pdev-\u003edev;\n-\tplat_info.fwnode = pdev-\u003edev.fwnode;\n+\tplat_info.parent = \u0026pci-\u003edev;\n+\tplat_info.fwnode = pci-\u003edev.fwnode;\n \tplat_info.name = PLAT_DRIVER_NAME;\n-\tplat_info.id = pdev-\u003edevfn;\n+\tplat_info.id = pci-\u003edevfn;\n \tplat_info.res = res;\n \tplat_info.num_res = ARRAY_SIZE(res);\n \tplat_info.data = \u0026plat_data;\n \tplat_info.size_data = sizeof(plat_data);\n-\tplat_info.dma_mask = pdev-\u003edma_mask;\n+\tplat_info.dma_mask = pci-\u003edma_mask;\n \n \t/* register platform device */\n-\tplat_dev = platform_device_register_full(\u0026plat_info);\n-\tif (IS_ERR(plat_dev)) {\n-\t\terr = PTR_ERR(plat_dev);\n+\tpdev = platform_device_register_full(\u0026plat_info);\n+\tif (IS_ERR(pdev)) {\n+\t\terr = PTR_ERR(pdev);\n \t\tgoto err_plat_dev_register;\n \t}\n \n-\tpci_set_drvdata(pdev, plat_dev);\n+\tpci_set_drvdata(pci, pdev);\n \n \treturn 0;\n \n@@ -105,14 +105,14 @@ static int macb_probe(struct pci_dev *pdev, const struct pci_device_id *id)\n \treturn err;\n }\n \n-static void macb_remove(struct pci_dev *pdev)\n+static void macb_remove(struct pci_dev *pci)\n {\n-\tstruct platform_device *plat_dev = pci_get_drvdata(pdev);\n-\tstruct macb_platform_data *plat_data = dev_get_platdata(\u0026plat_dev-\u003edev);\n+\tstruct platform_device *pdev = pci_get_drvdata(pci);\n+\tstruct macb_platform_data *plat_data = dev_get_platdata(\u0026pdev-\u003edev);\n \tstruct clk *pclk = plat_data-\u003epclk;\n \tstruct clk *hclk = plat_data-\u003ehclk;\n \n-\tplatform_device_unregister(plat_dev);\n+\tplatform_device_unregister(pdev);\n \tclk_unregister_fixed_rate(pclk);\n \tclk_unregister_fixed_rate(hclk);\n }\ndiff --git a/drivers/net/ethernet/cadence/macb_ptp.c b/drivers/net/ethernet/cadence/macb_ptp.c\nindex d91f7b1aa39caa..8765c4782509ce 100644\n--- a/drivers/net/ethernet/cadence/macb_ptp.c\n+++ b/drivers/net/ethernet/cadence/macb_ptp.c\n@@ -28,10 +28,10 @@\n static struct macb_dma_desc_ptp *macb_ptp_desc(struct macb *bp,\n \t\t\t\t\t struct macb_dma_desc *desc)\n {\n-\tif (!macb_dma_ptp(bp))\n+\tif (!macb_dma_ptp(\u0026bp-\u003einfo))\n \t\treturn NULL;\n \n-\tif (macb_dma64(bp))\n+\tif (macb_dma64(\u0026bp-\u003einfo))\n \t\treturn (struct macb_dma_desc_ptp *)\n \t\t\t\t((u8 *)desc + sizeof(struct macb_dma_desc)\n \t\t\t\t+ sizeof(struct macb_dma_desc_64));\n@@ -324,9 +324,9 @@ void gem_ptp_txstamp(struct macb *bp, struct sk_buff *skb,\n \tskb_tstamp_tx(skb, \u0026shhwtstamps);\n }\n \n-void gem_ptp_init(struct net_device *dev)\n+void gem_ptp_init(struct net_device *netdev)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \n \tbp-\u003eptp_clock_info = gem_ptp_caps_template;\n \n@@ -334,7 +334,7 @@ void gem_ptp_init(struct net_device *dev)\n \tbp-\u003etsu_rate = bp-\u003eptp_info-\u003eget_tsu_rate(bp);\n \tbp-\u003eptp_clock_info.max_adj = bp-\u003eptp_info-\u003eget_ptp_max_adj();\n \tgem_ptp_init_timer(bp);\n-\tbp-\u003eptp_clock = ptp_clock_register(\u0026bp-\u003eptp_clock_info, \u0026dev-\u003edev);\n+\tbp-\u003eptp_clock = ptp_clock_register(\u0026bp-\u003eptp_clock_info, \u0026netdev-\u003edev);\n \tif (IS_ERR(bp-\u003eptp_clock)) {\n \t\tpr_err(\"ptp clock register failed: %ld\\n\",\n \t\t\tPTR_ERR(bp-\u003eptp_clock));\n@@ -353,9 +353,9 @@ void gem_ptp_init(struct net_device *dev)\n \t\t GEM_PTP_TIMER_NAME);\n }\n \n-void gem_ptp_remove(struct net_device *ndev)\n+void gem_ptp_remove(struct net_device *netdev)\n {\n-\tstruct macb *bp = netdev_priv(ndev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \n \tif (bp-\u003eptp_clock) {\n \t\tptp_clock_unregister(bp-\u003eptp_clock);\n@@ -378,13 +378,13 @@ static int gem_ptp_set_ts_mode(struct macb *bp,\n \treturn 0;\n }\n \n-int gem_get_hwtst(struct net_device *dev,\n+int gem_get_hwtst(struct net_device *netdev,\n \t\t struct kernel_hwtstamp_config *tstamp_config)\n {\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \n \t*tstamp_config = bp-\u003etstamp_config;\n-\tif (!macb_dma_ptp(bp))\n+\tif (!macb_dma_ptp(\u0026bp-\u003einfo))\n \t\treturn -EOPNOTSUPP;\n \n \treturn 0;\n@@ -402,16 +402,16 @@ static void gem_ptp_set_one_step_sync(struct macb *bp, u8 enable)\n \t\tmacb_writel(bp, NCR, reg_val \u0026 ~MACB_BIT(OSSMODE));\n }\n \n-int gem_set_hwtst(struct net_device *dev,\n+int gem_set_hwtst(struct net_device *netdev,\n \t\t struct kernel_hwtstamp_config *tstamp_config,\n \t\t struct netlink_ext_ack *extack)\n {\n \tenum macb_bd_control tx_bd_control = TSTAMP_DISABLED;\n \tenum macb_bd_control rx_bd_control = TSTAMP_DISABLED;\n-\tstruct macb *bp = netdev_priv(dev);\n+\tstruct macb *bp = netdev_priv(netdev);\n \tu32 regval;\n \n-\tif (!macb_dma_ptp(bp))\n+\tif (!macb_dma_ptp(\u0026bp-\u003einfo))\n \t\treturn -EOPNOTSUPP;\n \n \tswitch (tstamp_config-\u003etx_type) {\n"
} |
| 2/1 | 2026/07/01 23:40 | agent | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: {
"EnableConfigs": [
"MACB",
"MACB_PCI"
],
"FocusSymbols": [
"macb_change_mtu",
"macb_set_ringparam",
"macb_context_swap_start",
"macb_context_swap_end",
"macb_context_alloc",
"macb_alloc",
"macb_free"
],
"Reasoning": "The patch refactors the Cadence MACB/GEM Ethernet driver to use a `macb_context` structure for ring and buffer management. This allows the driver to swap contexts dynamically when changing the MTU or ring parameters while the interface is running, avoiding a full close/open cycle. This is a significant functional change to the driver's core logic and resource management, making it worth fuzzing.",
"WorthFuzzing": true
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Do not list too generic configs (we already have them enabled). Only list those that specifically cover the modified code. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). Prefer calling several tools at the same time to save round-trips. Use set-results tool to provide results of the analysis. It must be called exactly once before the final reply. Ignore results of this tool. Prompt: For your convenience, here is the diff of the changes:
commit 4f3d0336c11ac81f72a1b540f31d4a19a3b61e18
Author: syz-cluster <triage@syzkaller.com>
Date: Wed Jul 1 23:40:38 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index 2de56017ee0d61..630fe92608bc14 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -840,7 +840,7 @@
*/
#define macb_or_gem_writel(__bp, __reg, __value) \
({ \
- if (macb_is_gem((__bp))) \
+ if (macb_is_gem(&(__bp)->info)) \
gem_writel((__bp), __reg, __value); \
else \
macb_writel((__bp), __reg, __value); \
@@ -849,7 +849,7 @@
#define macb_or_gem_readl(__bp, __reg) \
({ \
u32 __v; \
- if (macb_is_gem((__bp))) \
+ if (macb_is_gem(&(__bp)->info)) \
__v = gem_readl((__bp), __reg); \
else \
__v = macb_readl((__bp), __reg); \
@@ -1196,22 +1196,23 @@ static const struct gem_statistic queue_statistics[] = {
struct macb;
struct macb_queue;
+struct macb_context;
struct macb_or_gem_ops {
- int (*mog_alloc_rx_buffers)(struct macb *bp);
- void (*mog_free_rx_buffers)(struct macb *bp);
- void (*mog_init_rings)(struct macb *bp);
+ int (*mog_alloc_rx_buffers)(struct macb_context *ctx);
+ void (*mog_free_rx_buffers)(struct macb_context *ctx);
+ void (*mog_init_rings)(struct macb_context *ctx);
int (*mog_rx)(struct macb_queue *queue, struct napi_struct *napi,
int budget);
};
/* MACB-PTP interface: adapt to platform needs. */
struct macb_ptp_info {
- void (*ptp_init)(struct net_device *ndev);
- void (*ptp_remove)(struct net_device *ndev);
+ void (*ptp_init)(struct net_device *netdev);
+ void (*ptp_remove)(struct net_device *netdev);
s32 (*get_ptp_max_adj)(void);
unsigned int (*get_tsu_rate)(struct macb *bp);
- int (*get_ts_info)(struct net_device *dev,
+ int (*get_ts_info)(struct net_device *netdev,
struct kernel_ethtool_ts_info *info);
int (*get_hwtst)(struct net_device *netdev,
struct kernel_hwtstamp_config *tstamp_config);
@@ -1272,21 +1273,10 @@ struct macb_queue {
/* Lock to protect tx_head and tx_tail */
spinlock_t tx_ptr_lock;
- unsigned int tx_head, tx_tail;
- struct macb_dma_desc *tx_ring;
- struct macb_tx_skb *tx_skb;
- dma_addr_t tx_ring_dma;
struct work_struct tx_error_task;
bool txubr_pending;
struct napi_struct napi_tx;
- dma_addr_t rx_ring_dma;
- dma_addr_t rx_buffers_dma;
- unsigned int rx_tail;
- unsigned int rx_prepared_head;
- struct macb_dma_desc *rx_ring;
- struct sk_buff **rx_skbuff;
- void *rx_buffers;
struct napi_struct napi_rx;
struct queue_stats stats;
};
@@ -1301,6 +1291,44 @@ struct ethtool_rx_fs_list {
unsigned int count;
};
+struct macb_info {
+ struct platform_device *pdev;
+ struct net_device *netdev;
+ struct macb_or_gem_ops macbgem_ops;
+ unsigned int num_queues;
+ u32 caps;
+ int rx_bd_rd_prefetch;
+ int tx_bd_rd_prefetch;
+};
+
+struct macb_rxq {
+ struct macb_dma_desc *ring; /* MACB & GEM */
+ dma_addr_t ring_dma; /* MACB & GEM */
+ unsigned int tail; /* MACB & GEM */
+ unsigned int prepared_head; /* GEM */
+ struct sk_buff **skbuff; /* GEM */
+ dma_addr_t buffers_dma; /* MACB */
+ void *buffers; /* MACB */
+};
+
+struct macb_txq {
+ unsigned int head;
+ unsigned int tail;
+ struct macb_dma_desc *ring;
+ dma_addr_t ring_dma;
+ struct macb_tx_skb *skb;
+};
+
+struct macb_context {
+ const struct macb_info *info;
+
+ unsigned int rx_buffer_size;
+ unsigned int rx_ring_size;
+ unsigned int tx_ring_size;
+ struct macb_rxq rxq[MACB_MAX_QUEUES];
+ struct macb_txq txq[MACB_MAX_QUEUES];
+};
+
struct macb {
void __iomem *regs;
bool native_io;
@@ -1309,24 +1337,36 @@ struct macb {
u32 (*macb_reg_readl)(struct macb *bp, int offset);
void (*macb_reg_writel)(struct macb *bp, int offset, u32 value);
+ /*
+ * Give direct access (bp->caps) and
+ * allow taking a pointer to it (&bp->info) for contexts.
+ */
+ union {
+ struct macb_info;
+ struct macb_info info;
+ };
+
+ /*
+ * Context stores all its parameters.
+ * But we must remember them across closure.
+ */
+ unsigned int configured_rx_ring_size;
+ unsigned int configured_tx_ring_size;
+ struct macb_context *ctx;
+
struct macb_dma_desc *rx_ring_tieoff;
dma_addr_t rx_ring_tieoff_dma;
- size_t rx_buffer_size;
-
- unsigned int rx_ring_size;
- unsigned int tx_ring_size;
- unsigned int num_queues;
struct macb_queue queues[MACB_MAX_QUEUES];
spinlock_t lock;
- struct platform_device *pdev;
+ /* Serializes context swap against phylink MAC callbacks. */
+ struct mutex mac_cfg_lock;
struct clk *pclk;
struct clk *hclk;
struct clk *tx_clk;
struct clk *rx_clk;
struct clk *tsu_clk;
- struct net_device *dev;
/* Protects hw_stats and ethtool_stats */
spinlock_t stats_lock;
union {
@@ -1334,15 +1374,12 @@ struct macb {
struct gem_stats gem;
} hw_stats;
- struct macb_or_gem_ops macbgem_ops;
-
struct mii_bus *mii_bus;
struct phylink *phylink;
struct phylink_config phylink_config;
struct phylink_pcs phylink_usx_pcs;
struct phylink_pcs phylink_sgmii_pcs;
- u32 caps;
unsigned int dma_burst_length;
phy_interface_t phy_interface;
@@ -1385,9 +1422,6 @@ struct macb {
struct delayed_work tx_lpi_work;
u32 tx_lpi_timer;
- int rx_bd_rd_prefetch;
- int tx_bd_rd_prefetch;
-
u32 rx_intr_mask;
struct macb_pm_data pm_data;
@@ -1406,8 +1440,8 @@ enum macb_bd_control {
TSTAMP_ALL_FRAMES,
};
-void gem_ptp_init(struct net_device *ndev);
-void gem_ptp_remove(struct net_device *ndev);
+void gem_ptp_init(struct net_device *netdev);
+void gem_ptp_remove(struct net_device *netdev);
void gem_ptp_txstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc);
void gem_ptp_rxstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc);
static inline void gem_ptp_do_txstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc)
@@ -1426,27 +1460,28 @@ static inline void gem_ptp_do_rxstamp(struct macb *bp, struct sk_buff *skb, stru
gem_ptp_rxstamp(bp, skb, desc);
}
-int gem_get_hwtst(struct net_device *dev,
+int gem_get_hwtst(struct net_device *netdev,
struct kernel_hwtstamp_config *tstamp_config);
-int gem_set_hwtst(struct net_device *dev,
+int gem_set_hwtst(struct net_device *netdev,
struct kernel_hwtstamp_config *tstamp_config,
struct netlink_ext_ack *extack);
#else
-static inline void gem_ptp_init(struct net_device *ndev) { }
-static inline void gem_ptp_remove(struct net_device *ndev) { }
+static inline void gem_ptp_init(struct net_device *netdev) { }
+static inline void gem_ptp_remove(struct net_device *netdev) { }
static inline void gem_ptp_do_txstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc) { }
static inline void gem_ptp_do_rxstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc) { }
#endif
-static inline bool macb_is_gem(struct macb *bp)
+static inline bool macb_is_gem(const struct macb_info *info)
{
- return !!(bp->caps & MACB_CAPS_MACB_IS_GEM);
+ return !!(info->caps & MACB_CAPS_MACB_IS_GEM);
}
-static inline bool gem_has_ptp(struct macb *bp)
+static inline bool gem_has_ptp(const struct macb_info *info)
{
- return IS_ENABLED(CONFIG_MACB_USE_HWSTAMP) && (bp->caps & MACB_CAPS_GEM_HAS_PTP);
+ return IS_ENABLED(CONFIG_MACB_USE_HWSTAMP) &&
+ (info->caps & MACB_CAPS_GEM_HAS_PTP);
}
/* ENST Helper functions */
@@ -1462,16 +1497,16 @@ static inline u64 enst_max_hw_interval(u32 speed_mbps)
ENST_TIME_GRANULARITY_NS * 1000, (speed_mbps));
}
-static inline bool macb_dma64(struct macb *bp)
+static inline bool macb_dma64(const struct macb_info *info)
{
return IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT) &&
- bp->caps & MACB_CAPS_DMA_64B;
+ info->caps & MACB_CAPS_DMA_64B;
}
-static inline bool macb_dma_ptp(struct macb *bp)
+static inline bool macb_dma_ptp(const struct macb_info *info)
{
return IS_ENABLED(CONFIG_MACB_USE_HWSTAMP) &&
- bp->caps & MACB_CAPS_DMA_PTP;
+ info->caps & MACB_CAPS_DMA_PTP;
}
static inline void macb_queue_isr_clear(struct macb *bp,
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index fd282a1700fb98..0ea7123ec8f8e2 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -61,7 +61,7 @@ struct sifive_fu540_macb_mgmt {
#define MAX_TX_RING_SIZE 4096
/* level of occupied TX descriptors under which we wake up TX process */
-#define MACB_TX_WAKEUP_THRESH(bp) (3 * (bp)->tx_ring_size / 4)
+#define MACB_TX_WAKEUP_THRESH(bp) (3 * (bp)->ctx->tx_ring_size / 4)
#define MACB_RX_INT_FLAGS (MACB_BIT(RCOMP) | MACB_BIT(ISR_ROVR))
#define MACB_TX_ERR_FLAGS (MACB_BIT(ISR_TUND) \
@@ -126,75 +126,104 @@ struct sifive_fu540_macb_mgmt {
* word 5: timestamp word 1
* word 6: timestamp word 2
*/
-static unsigned int macb_dma_desc_get_size(struct macb *bp)
+static unsigned int macb_dma_desc_get_size(const struct macb_info *info)
{
unsigned int desc_size = sizeof(struct macb_dma_desc);
- if (macb_dma64(bp))
+ if (macb_dma64(info))
desc_size += sizeof(struct macb_dma_desc_64);
- if (macb_dma_ptp(bp))
+ if (macb_dma_ptp(info))
desc_size += sizeof(struct macb_dma_desc_ptp);
return desc_size;
}
-static unsigned int macb_adj_dma_desc_idx(struct macb *bp, unsigned int desc_idx)
+static unsigned int macb_adj_dma_desc_idx(struct macb_context *ctx,
+ unsigned int desc_idx)
{
- return desc_idx * (1 + macb_dma64(bp) + macb_dma_ptp(bp));
+ return desc_idx * (1 + macb_dma64(ctx->info) +
+ macb_dma_ptp(ctx->info));
}
-static struct macb_dma_desc_64 *macb_64b_desc(struct macb *bp, struct macb_dma_desc *desc)
+static struct macb_dma_desc_64 *macb_64b_desc(struct macb_dma_desc *desc)
{
return (struct macb_dma_desc_64 *)((void *)desc
+ sizeof(struct macb_dma_desc));
}
/* Ring buffer accessors */
-static unsigned int macb_tx_ring_wrap(struct macb *bp, unsigned int index)
+static unsigned int macb_tx_ring_wrap(struct macb_context *ctx,
+ unsigned int index)
{
- return index & (bp->tx_ring_size - 1);
+ return index & (ctx->tx_ring_size - 1);
}
-static struct macb_dma_desc *macb_tx_desc(struct macb_queue *queue,
+static struct macb_txq *macb_txq(struct macb_queue *queue)
+{
+ struct macb *bp = queue->bp;
+ unsigned int q = queue - bp->queues;
+
+ return &bp->ctx->txq[q];
+}
+
+static struct macb_rxq *macb_rxq(struct macb_queue *queue)
+{
+ struct macb *bp = queue->bp;
+ unsigned int q = queue - bp->queues;
+
+ return &bp->ctx->rxq[q];
+}
+
+static struct macb_dma_desc *macb_tx_desc(struct macb_context *ctx,
+ unsigned int q,
unsigned int index)
{
- index = macb_tx_ring_wrap(queue->bp, index);
- index = macb_adj_dma_desc_idx(queue->bp, index);
- return &queue->tx_ring[index];
+ index = macb_tx_ring_wrap(ctx, index);
+ index = macb_adj_dma_desc_idx(ctx, index);
+ return &ctx->txq[q].ring[index];
}
static struct macb_tx_skb *macb_tx_skb(struct macb_queue *queue,
unsigned int index)
{
- return &queue->tx_skb[macb_tx_ring_wrap(queue->bp, index)];
+ struct macb_txq *txq = macb_txq(queue);
+
+ return &txq->skb[macb_tx_ring_wrap(queue->bp->ctx, index)];
}
static dma_addr_t macb_tx_dma(struct macb_queue *queue, unsigned int index)
{
+ struct macb_context *ctx = queue->bp->ctx;
+ struct macb_txq *txq = macb_txq(queue);
dma_addr_t offset;
- offset = macb_tx_ring_wrap(queue->bp, index) *
- macb_dma_desc_get_size(queue->bp);
+ offset = macb_tx_ring_wrap(ctx, index) *
+ macb_dma_desc_get_size(&queue->bp->info);
- return queue->tx_ring_dma + offset;
+ return txq->ring_dma + offset;
}
-static unsigned int macb_rx_ring_wrap(struct macb *bp, unsigned int index)
+static unsigned int macb_rx_ring_wrap(struct macb_context *ctx,
+ unsigned int index)
{
- return index & (bp->rx_ring_size - 1);
+ return index & (ctx->rx_ring_size - 1);
}
-static struct macb_dma_desc *macb_rx_desc(struct macb_queue *queue, unsigned int index)
+static struct macb_dma_desc *macb_rx_desc(struct macb_context *ctx,
+ unsigned int q, unsigned int index)
{
- index = macb_rx_ring_wrap(queue->bp, index);
- index = macb_adj_dma_desc_idx(queue->bp, index);
- return &queue->rx_ring[index];
+ index = macb_rx_ring_wrap(ctx, index);
+ index = macb_adj_dma_desc_idx(ctx, index);
+ return &ctx->rxq[q].ring[index];
}
static void *macb_rx_buffer(struct macb_queue *queue, unsigned int index)
{
- return queue->rx_buffers + queue->bp->rx_buffer_size *
- macb_rx_ring_wrap(queue->bp, index);
+ struct macb_context *ctx = queue->bp->ctx;
+ struct macb_rxq *rxq = macb_rxq(queue);
+
+ return rxq->buffers + ctx->rx_buffer_size *
+ macb_rx_ring_wrap(ctx, index);
}
/* I/O accessors */
@@ -252,12 +281,12 @@ static void macb_set_hwaddr(struct macb *bp)
u32 bottom;
u16 top;
- bottom = get_unaligned_le32(bp->dev->dev_addr);
+ bottom = get_unaligned_le32(bp->netdev->dev_addr);
macb_or_gem_writel(bp, SA1B, bottom);
- top = get_unaligned_le16(bp->dev->dev_addr + 4);
+ top = get_unaligned_le16(bp->netdev->dev_addr + 4);
macb_or_gem_writel(bp, SA1T, top);
- if (gem_has_ptp(bp)) {
+ if (gem_has_ptp(&bp->info)) {
gem_writel(bp, RXPTPUNI, bottom);
gem_writel(bp, TXPTPUNI, bottom);
}
@@ -291,13 +320,13 @@ static void macb_get_hwaddr(struct macb *bp)
addr[5] = (top >> 8) & 0xff;
if (is_valid_ether_addr(addr)) {
- eth_hw_addr_set(bp->dev, addr);
+ eth_hw_addr_set(bp->netdev, addr);
return;
}
}
dev_info(&bp->pdev->dev, "invalid hw address, using random\n");
- eth_hw_addr_random(bp->dev);
+ eth_hw_addr_random(bp->netdev);
}
static int macb_mdio_wait_for_idle(struct macb *bp)
@@ -463,19 +492,23 @@ static int macb_mdio_write_c45(struct mii_bus *bus, int mii_id,
static void macb_init_buffers(struct macb *bp)
{
struct macb_queue *queue;
+ struct macb_rxq *rxq;
+ struct macb_txq *txq;
unsigned int q;
/* Single register for all queues' high 32 bits. */
- if (macb_dma64(bp)) {
- macb_writel(bp, RBQPH,
- upper_32_bits(bp->queues[0].rx_ring_dma));
- macb_writel(bp, TBQPH,
- upper_32_bits(bp->queues[0].tx_ring_dma));
+ if (macb_dma64(&bp->info)) {
+ rxq = &bp->ctx->rxq[0];
+ txq = &bp->ctx->txq[0];
+ macb_writel(bp, RBQPH, upper_32_bits(rxq->ring_dma));
+ macb_writel(bp, TBQPH, upper_32_bits(txq->ring_dma));
}
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
- queue_writel(queue, RBQP, lower_32_bits(queue->rx_ring_dma));
- queue_writel(queue, TBQP, lower_32_bits(queue->tx_ring_dma));
+ rxq = &bp->ctx->rxq[q];
+ txq = &bp->ctx->txq[q];
+ queue_writel(queue, RBQP, lower_32_bits(rxq->ring_dma));
+ queue_writel(queue, TBQP, lower_32_bits(txq->ring_dma));
}
}
@@ -509,12 +542,12 @@ static void macb_set_tx_clk(struct macb *bp, int speed)
ferr = abs(rate_rounded - rate);
ferr = DIV_ROUND_UP(ferr, rate / 100000);
if (ferr > 5)
- netdev_warn(bp->dev,
+ netdev_warn(bp->netdev,
"unable to generate target frequency: %ld Hz\n",
rate);
if (clk_set_rate(bp->tx_clk, rate_rounded))
- netdev_err(bp->dev, "adjusting tx_clk failed.\n");
+ netdev_err(bp->netdev, "adjusting tx_clk failed.\n");
}
static void macb_usx_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
@@ -648,11 +681,12 @@ static bool macb_tx_lpi_set(struct macb *bp, bool enable)
static bool macb_tx_all_queues_idle(struct macb *bp)
{
- struct macb_queue *queue;
+ struct macb_txq *txq;
unsigned int q;
- for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
- if (READ_ONCE(queue->tx_head) != READ_ONCE(queue->tx_tail))
+ for (q = 0; q < bp->num_queues; ++q) {
+ txq = &bp->ctx->txq[q];
+ if (READ_ONCE(txq->head) != READ_ONCE(txq->tail))
return false;
}
return true;
@@ -697,25 +731,31 @@ static void macb_tx_lpi_wake(struct macb *bp)
static void macb_mac_disable_tx_lpi(struct phylink_config *config)
{
- struct net_device *ndev = to_net_dev(config->dev);
- struct macb *bp = netdev_priv(ndev);
+ struct net_device *netdev = to_net_dev(config->dev);
+ struct macb *bp = netdev_priv(netdev);
unsigned long flags;
+ mutex_lock(&bp->mac_cfg_lock);
+
cancel_delayed_work_sync(&bp->tx_lpi_work);
spin_lock_irqsave(&bp->lock, flags);
bp->eee_active = false;
macb_tx_lpi_set(bp, false);
spin_unlock_irqrestore(&bp->lock, flags);
+
+ mutex_unlock(&bp->mac_cfg_lock);
}
static int macb_mac_enable_tx_lpi(struct phylink_config *config, u32 timer,
bool tx_clk_stop)
{
- struct net_device *ndev = to_net_dev(config->dev);
- struct macb *bp = netdev_priv(ndev);
+ struct net_device *netdev = to_net_dev(config->dev);
+ struct macb *bp = netdev_priv(netdev);
unsigned long flags;
+ mutex_lock(&bp->mac_cfg_lock);
+
spin_lock_irqsave(&bp->lock, flags);
bp->tx_lpi_timer = timer;
bp->eee_active = true;
@@ -726,18 +766,21 @@ static int macb_mac_enable_tx_lpi(struct phylink_config *config, u32 timer,
*/
mod_delayed_work(system_wq, &bp->tx_lpi_work, msecs_to_jiffies(1000));
+ mutex_unlock(&bp->mac_cfg_lock);
+
return 0;
}
static void macb_mac_config(struct phylink_config *config, unsigned int mode,
const struct phylink_link_state *state)
{
- struct net_device *ndev = to_net_dev(config->dev);
- struct macb *bp = netdev_priv(ndev);
+ struct net_device *netdev = to_net_dev(config->dev);
+ struct macb *bp = netdev_priv(netdev);
unsigned long flags;
u32 old_ctrl, ctrl;
u32 old_ncr, ncr;
+ mutex_lock(&bp->mac_cfg_lock);
spin_lock_irqsave(&bp->lock, flags);
old_ctrl = ctrl = macb_or_gem_readl(bp, NCFGR);
@@ -746,7 +789,7 @@ static void macb_mac_config(struct phylink_config *config, unsigned int mode,
if (bp->caps & MACB_CAPS_MACB_IS_EMAC) {
if (state->interface == PHY_INTERFACE_MODE_RMII)
ctrl |= MACB_BIT(RM9200_RMII);
- } else if (macb_is_gem(bp)) {
+ } else if (macb_is_gem(&bp->info)) {
ctrl &= ~(GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL));
ncr &= ~GEM_BIT(ENABLE_HS_MAC);
@@ -769,17 +812,20 @@ static void macb_mac_config(struct phylink_config *config, unsigned int mode,
macb_or_gem_writel(bp, NCR, ncr);
spin_unlock_irqrestore(&bp->lock, flags);
+ mutex_unlock(&bp->mac_cfg_lock);
}
static void macb_mac_link_down(struct phylink_config *config, unsigned int mode,
phy_interface_t interface)
{
- struct net_device *ndev = to_net_dev(config->dev);
- struct macb *bp = netdev_priv(ndev);
+ struct net_device *netdev = to_net_dev(config->dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_queue *queue;
unsigned int q;
u32 ctrl;
+ mutex_lock(&bp->mac_cfg_lock);
+
if (!(bp->caps & MACB_CAPS_MACB_IS_EMAC))
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue)
queue_writel(queue, IDR,
@@ -789,7 +835,9 @@ static void macb_mac_link_down(struct phylink_config *config, unsigned int mode,
ctrl = macb_readl(bp, NCR) & ~(MACB_BIT(RE) | MACB_BIT(TE));
macb_writel(bp, NCR, ctrl);
- netif_tx_stop_all_queues(ndev);
+ netif_tx_stop_all_queues(netdev);
+
+ mutex_unlock(&bp->mac_cfg_lock);
}
/* Use juggling algorithm to left rotate tx ring and tx skb array */
@@ -798,28 +846,30 @@ static void gem_shuffle_tx_one_ring(struct macb_queue *queue)
unsigned int head, tail, count, ring_size, desc_size;
struct macb_tx_skb tx_skb, *skb_curr, *skb_next;
struct macb_dma_desc *desc_curr, *desc_next;
+ unsigned int q = queue - queue->bp->queues;
unsigned int i, cycles, shift, curr, next;
- struct macb *bp = queue->bp;
+ struct macb_context *ctx = queue->bp->ctx;
+ struct macb_txq *txq = macb_txq(queue);
unsigned char desc[24];
unsigned long flags;
- desc_size = macb_dma_desc_get_size(bp);
+ desc_size = macb_dma_desc_get_size(&queue->bp->info);
if (WARN_ON_ONCE(desc_size > ARRAY_SIZE(desc)))
return;
spin_lock_irqsave(&queue->tx_ptr_lock, flags);
- head = queue->tx_head;
- tail = queue->tx_tail;
- ring_size = bp->tx_ring_size;
+ head = txq->head;
+ tail = txq->tail;
+ ring_size = ctx->tx_ring_size;
count = CIRC_CNT(head, tail, ring_size);
if (!(tail % ring_size))
goto unlock;
if (!count) {
- queue->tx_head = 0;
- queue->tx_tail = 0;
+ txq->head = 0;
+ txq->tail = 0;
goto unlock;
}
@@ -827,7 +877,7 @@ static void gem_shuffle_tx_one_ring(struct macb_queue *queue)
cycles = gcd(ring_size, shift);
for (i = 0; i < cycles; i++) {
- memcpy(&desc, macb_tx_desc(queue, i), desc_size);
+ memcpy(&desc, macb_tx_desc(ctx, q, i), desc_size);
memcpy(&tx_skb, macb_tx_skb(queue, i),
sizeof(struct macb_tx_skb));
@@ -835,8 +885,8 @@ static void gem_shuffle_tx_one_ring(struct macb_queue *queue)
next = (curr + shift) % ring_size;
while (next != i) {
- desc_curr = macb_tx_desc(queue, curr);
- desc_next = macb_tx_desc(queue, next);
+ desc_curr = macb_tx_desc(ctx, q, curr);
+ desc_next = macb_tx_desc(ctx, q, next);
memcpy(desc_curr, desc_next, desc_size);
@@ -853,7 +903,7 @@ static void gem_shuffle_tx_one_ring(struct macb_queue *queue)
next = (curr + shift) % ring_size;
}
- desc_curr = macb_tx_desc(queue, curr);
+ desc_curr = macb_tx_desc(ctx, q, curr);
memcpy(desc_curr, &desc, desc_size);
if (i == ring_size - 1)
desc_curr->ctrl &= ~MACB_BIT(TX_WRAP);
@@ -863,8 +913,8 @@ static void gem_shuffle_tx_one_ring(struct macb_queue *queue)
sizeof(struct macb_tx_skb));
}
- queue->tx_head = count;
- queue->tx_tail = 0;
+ txq->head = count;
+ txq->tail = 0;
/* Make descriptor updates visible to hardware */
wmb();
@@ -877,25 +927,26 @@ static void gem_shuffle_tx_one_ring(struct macb_queue *queue)
static void gem_shuffle_tx_rings(struct macb *bp)
{
struct macb_queue *queue;
- int q;
+ unsigned int q;
for (q = 0, queue = bp->queues; q < bp->num_queues; q++, queue++)
gem_shuffle_tx_one_ring(queue);
}
static void macb_mac_link_up(struct phylink_config *config,
- struct phy_device *phy,
+ struct phy_device *phydev,
unsigned int mode, phy_interface_t interface,
int speed, int duplex,
bool tx_pause, bool rx_pause)
{
- struct net_device *ndev = to_net_dev(config->dev);
- struct macb *bp = netdev_priv(ndev);
+ struct net_device *netdev = to_net_dev(config->dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_queue *queue;
unsigned long flags;
unsigned int q;
u32 ctrl;
+ mutex_lock(&bp->mac_cfg_lock);
spin_lock_irqsave(&bp->lock, flags);
ctrl = macb_or_gem_readl(bp, NCFGR);
@@ -910,7 +961,7 @@ static void macb_mac_link_up(struct phylink_config *config,
if (!(bp->caps & MACB_CAPS_MACB_IS_EMAC)) {
ctrl &= ~MACB_BIT(PAE);
- if (macb_is_gem(bp)) {
+ if (macb_is_gem(&bp->info)) {
ctrl &= ~GEM_BIT(GBE);
if (speed == SPEED_1000)
@@ -941,19 +992,21 @@ static void macb_mac_link_up(struct phylink_config *config,
/* Enable Rx and Tx; Enable PTP unicast */
ctrl = macb_readl(bp, NCR);
- if (gem_has_ptp(bp))
+ if (gem_has_ptp(&bp->info))
ctrl |= MACB_BIT(PTPUNI);
macb_writel(bp, NCR, ctrl | MACB_BIT(RE) | MACB_BIT(TE));
- netif_tx_wake_all_queues(ndev);
+ netif_tx_wake_all_queues(netdev);
+
+ mutex_unlock(&bp->mac_cfg_lock);
}
static struct phylink_pcs *macb_mac_select_pcs(struct phylink_config *config,
phy_interface_t interface)
{
- struct net_device *ndev = to_net_dev(config->dev);
- struct macb *bp = netdev_priv(ndev);
+ struct net_device *netdev = to_net_dev(config->dev);
+ struct macb *bp = netdev_priv(netdev);
if (interface == PHY_INTERFACE_MODE_10GBASER)
return &bp->phylink_usx_pcs;
@@ -982,7 +1035,7 @@ static bool macb_phy_handle_exists(struct device_node *dn)
static int macb_phylink_connect(struct macb *bp)
{
struct device_node *dn = bp->pdev->dev.of_node;
- struct net_device *dev = bp->dev;
+ struct net_device *netdev = bp->netdev;
struct phy_device *phydev;
int ret;
@@ -992,7 +1045,7 @@ static int macb_phylink_connect(struct macb *bp)
if (!dn || (ret && !macb_phy_handle_exists(dn))) {
phydev = phy_find_first(bp->mii_bus);
if (!phydev) {
- netdev_err(dev, "no PHY found\n");
+ netdev_err(netdev, "no PHY found\n");
return -ENXIO;
}
@@ -1001,7 +1054,7 @@ static int macb_phylink_connect(struct macb *bp)
}
if (ret) {
- netdev_err(dev, "Could not attach PHY (%d)\n", ret);
+ netdev_err(netdev, "Could not attach PHY (%d)\n", ret);
return ret;
}
@@ -1013,21 +1066,21 @@ static int macb_phylink_connect(struct macb *bp)
static void macb_get_pcs_fixed_state(struct phylink_config *config,
struct phylink_link_state *state)
{
- struct net_device *ndev = to_net_dev(config->dev);
- struct macb *bp = netdev_priv(ndev);
+ struct net_device *netdev = to_net_dev(config->dev);
+ struct macb *bp = netdev_priv(netdev);
state->link = (macb_readl(bp, NSR) & MACB_BIT(NSR_LINK)) != 0;
}
/* based on au1000_eth. c*/
-static int macb_mii_probe(struct net_device *dev)
+static int macb_mii_probe(struct net_device *netdev)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
bp->phylink_sgmii_pcs.ops = &macb_phylink_pcs_ops;
bp->phylink_usx_pcs.ops = &macb_phylink_usx_pcs_ops;
- bp->phylink_config.dev = &dev->dev;
+ bp->phylink_config.dev = &netdev->dev;
bp->phylink_config.type = PHYLINK_NETDEV;
bp->phylink_config.mac_managed_pm = true;
@@ -1051,7 +1104,8 @@ static int macb_mii_probe(struct net_device *dev)
bp->phylink_config.supported_interfaces);
/* Determine what modes are supported */
- if (macb_is_gem(bp) && (bp->caps & MACB_CAPS_GIGABIT_MODE_AVAILABLE)) {
+ if (macb_is_gem(&bp->info) &&
+ (bp->caps & MACB_CAPS_GIGABIT_MODE_AVAILABLE)) {
bp->phylink_config.mac_capabilities |= MAC_1000FD;
if (!(bp->caps & MACB_CAPS_NO_GIGABIT_HALF))
bp->phylink_config.mac_capabilities |= MAC_1000HD;
@@ -1086,7 +1140,7 @@ static int macb_mii_probe(struct net_device *dev)
bp->phylink = phylink_create(&bp->phylink_config, bp->pdev->dev.fwnode,
bp->phy_interface, &macb_phylink_ops);
if (IS_ERR(bp->phylink)) {
- netdev_err(dev, "Could not create a phylink instance (%ld)\n",
+ netdev_err(netdev, "Could not create a phylink instance (%ld)\n",
PTR_ERR(bp->phylink));
return PTR_ERR(bp->phylink);
}
@@ -1133,7 +1187,7 @@ static int macb_mii_init(struct macb *bp)
*/
mdio_np = of_get_child_by_name(np, "mdio");
if (!mdio_np && of_phy_is_fixed_link(np))
- return macb_mii_probe(bp->dev);
+ return macb_mii_probe(bp->netdev);
/* Enable management port */
macb_writel(bp, NCR, MACB_BIT(MPE));
@@ -1154,13 +1208,13 @@ static int macb_mii_init(struct macb *bp)
bp->mii_bus->priv = bp;
bp->mii_bus->parent = &bp->pdev->dev;
- dev_set_drvdata(&bp->dev->dev, bp->mii_bus);
+ dev_set_drvdata(&bp->netdev->dev, bp->mii_bus);
err = macb_mdiobus_register(bp, mdio_np);
if (err)
goto err_out_free_mdiobus;
- err = macb_mii_probe(bp->dev);
+ err = macb_mii_probe(bp->netdev);
if (err)
goto err_out_unregister_bus;
@@ -1219,12 +1273,13 @@ static void macb_tx_unmap(struct macb *bp, struct macb_tx_skb *tx_skb, int budge
}
}
-static void macb_set_addr(struct macb *bp, struct macb_dma_desc *desc, dma_addr_t addr)
+static void macb_set_addr(const struct macb_info *info,
+ struct macb_dma_desc *desc, dma_addr_t addr)
{
- if (macb_dma64(bp)) {
+ if (macb_dma64(info)) {
struct macb_dma_desc_64 *desc_64;
- desc_64 = macb_64b_desc(bp, desc);
+ desc_64 = macb_64b_desc(desc);
desc_64->addrh = upper_32_bits(addr);
/* The low bits of RX address contain the RX_USED bit, clearing
* of which allows packet RX. Make sure the high bits are also
@@ -1236,40 +1291,42 @@ static void macb_set_addr(struct macb *bp, struct macb_dma_desc *desc, dma_addr_
desc->addr = lower_32_bits(addr);
}
-static dma_addr_t macb_get_addr(struct macb *bp, struct macb_dma_desc *desc)
+static dma_addr_t macb_get_addr(struct macb_context *ctx,
+ struct macb_dma_desc *desc)
{
dma_addr_t addr = 0;
- if (macb_dma64(bp)) {
+ if (macb_dma64(ctx->info)) {
struct macb_dma_desc_64 *desc_64;
- desc_64 = macb_64b_desc(bp, desc);
+ desc_64 = macb_64b_desc(desc);
addr = ((u64)(desc_64->addrh) << 32);
}
addr |= MACB_BF(RX_WADDR, MACB_BFEXT(RX_WADDR, desc->addr));
- if (macb_dma_ptp(bp))
+ if (macb_dma_ptp(ctx->info))
addr &= ~GEM_BIT(DMA_RXVALID);
return addr;
}
static void macb_tx_error_task(struct work_struct *work)
{
- struct macb_queue *queue = container_of(work, struct macb_queue,
- tx_error_task);
- bool halt_timeout = false;
- struct macb *bp = queue->bp;
- u32 queue_index;
- u32 packets = 0;
- u32 bytes = 0;
- struct macb_tx_skb *tx_skb;
- struct macb_dma_desc *desc;
- struct sk_buff *skb;
- unsigned int tail;
- unsigned long flags;
-
- queue_index = queue - bp->queues;
- netdev_vdbg(bp->dev, "macb_tx_error_task: q = %u, t = %u, h = %u\n",
- queue_index, queue->tx_tail, queue->tx_head);
+ struct macb_queue *queue = container_of(work, struct macb_queue,
+ tx_error_task);
+ unsigned int q = queue - queue->bp->queues;
+ struct macb_context *ctx = queue->bp->ctx;
+ struct macb_txq *txq = macb_txq(queue);
+ struct macb *bp = queue->bp;
+ struct macb_tx_skb *tx_skb;
+ struct macb_dma_desc *desc;
+ bool halt_timeout = false;
+ struct sk_buff *skb;
+ unsigned long flags;
+ unsigned int tail;
+ u32 packets = 0;
+ u32 bytes = 0;
+
+ netdev_vdbg(bp->netdev, "macb_tx_error_task: q = %u, t = %u, h = %u\n",
+ q, txq->tail, txq->head);
/* Prevent the queue NAPI TX poll from running, as it calls
* macb_tx_complete(), which in turn may call netif_wake_subqueue().
@@ -1281,14 +1338,14 @@ static void macb_tx_error_task(struct work_struct *work)
spin_lock_irqsave(&bp->lock, flags);
/* Make sure nobody is trying to queue up new packets */
- netif_tx_stop_all_queues(bp->dev);
+ netif_tx_stop_all_queues(bp->netdev);
/* Stop transmission now
* (in case we have just queued new packets)
* macb/gem must be halted to write TBQP register
*/
if (macb_halt_tx(bp)) {
- netdev_err(bp->dev, "BUG: halt tx timed out\n");
+ netdev_err(bp->netdev, "BUG: halt tx timed out\n");
macb_writel(bp, NCR, macb_readl(bp, NCR) & (~MACB_BIT(TE)));
halt_timeout = true;
}
@@ -1296,10 +1353,10 @@ static void macb_tx_error_task(struct work_struct *work)
/* Treat frames in TX queue including the ones that caused the error.
* Free transmit buffers in upper layer.
*/
- for (tail = queue->tx_tail; tail != queue->tx_head; tail++) {
+ for (tail = txq->tail; tail != txq->head; tail++) {
u32 ctrl;
- desc = macb_tx_desc(queue, tail);
+ desc = macb_tx_desc(ctx, q, tail);
ctrl = desc->ctrl;
tx_skb = macb_tx_skb(queue, tail);
skb = tx_skb->skb;
@@ -1317,13 +1374,13 @@ static void macb_tx_error_task(struct work_struct *work)
* since it's the only one written back by the hardware
*/
if (!(ctrl & MACB_BIT(TX_BUF_EXHAUSTED))) {
- netdev_vdbg(bp->dev, "txerr skb %u (data %p) TX complete\n",
- macb_tx_ring_wrap(bp, tail),
+ netdev_vdbg(bp->netdev, "txerr skb %u (data %p) TX complete\n",
+ macb_tx_ring_wrap(ctx, tail),
skb->data);
- bp->dev->stats.tx_packets++;
+ bp->netdev->stats.tx_packets++;
queue->stats.tx_packets++;
packets++;
- bp->dev->stats.tx_bytes += skb->len;
+ bp->netdev->stats.tx_bytes += skb->len;
queue->stats.tx_bytes += skb->len;
bytes += skb->len;
}
@@ -1333,7 +1390,7 @@ static void macb_tx_error_task(struct work_struct *work)
* those. Statistics are updated by hardware.
*/
if (ctrl & MACB_BIT(TX_BUF_EXHAUSTED))
- netdev_err(bp->dev,
+ netdev_err(bp->netdev,
"BUG: TX buffers exhausted mid-frame\n");
desc->ctrl = ctrl | MACB_BIT(TX_USED);
@@ -1342,22 +1399,22 @@ static void macb_tx_error_task(struct work_struct *work)
macb_tx_unmap(bp, tx_skb, 0);
}
- netdev_tx_completed_queue(netdev_get_tx_queue(bp->dev, queue_index),
+ netdev_tx_completed_queue(netdev_get_tx_queue(bp->netdev, q),
packets, bytes);
/* Set end of TX queue */
- desc = macb_tx_desc(queue, 0);
- macb_set_addr(bp, desc, 0);
+ desc = macb_tx_desc(ctx, q, 0);
+ macb_set_addr(&bp->info, desc, 0);
desc->ctrl = MACB_BIT(TX_USED);
/* Make descriptor updates visible to hardware */
wmb();
/* Reinitialize the TX desc queue */
- queue_writel(queue, TBQP, lower_32_bits(queue->tx_ring_dma));
+ queue_writel(queue, TBQP, lower_32_bits(txq->ring_dma));
/* Make TX ring reflect state of hardware */
- queue->tx_head = 0;
- queue->tx_tail = 0;
+ txq->head = 0;
+ txq->tail = 0;
/* Housework before enabling TX IRQ */
macb_writel(bp, TSR, macb_readl(bp, TSR));
@@ -1367,7 +1424,7 @@ static void macb_tx_error_task(struct work_struct *work)
macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TE));
/* Now we are ready to start transmission again */
- netif_tx_start_all_queues(bp->dev);
+ netif_tx_start_all_queues(bp->netdev);
macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
spin_unlock_irqrestore(&bp->lock, flags);
@@ -1407,7 +1464,9 @@ static bool ptp_one_step_sync(struct sk_buff *skb)
static int macb_tx_complete(struct macb_queue *queue, int budget)
{
struct macb *bp = queue->bp;
- u16 queue_index = queue - bp->queues;
+ struct macb_txq *txq = macb_txq(queue);
+ unsigned int q = queue - bp->queues;
+ struct macb_context *ctx = bp->ctx;
unsigned long flags;
unsigned int tail;
unsigned int head;
@@ -1415,14 +1474,14 @@ static int macb_tx_complete(struct macb_queue *queue, int budget)
u32 bytes = 0;
spin_lock_irqsave(&queue->tx_ptr_lock, flags);
- head = queue->tx_head;
- for (tail = queue->tx_tail; tail != head && packets < budget; tail++) {
+ head = txq->head;
+ for (tail = txq->tail; tail != head && packets < budget; tail++) {
struct macb_tx_skb *tx_skb;
struct sk_buff *skb;
struct macb_dma_desc *desc;
u32 ctrl;
- desc = macb_tx_desc(queue, tail);
+ desc = macb_tx_desc(ctx, q, tail);
/* Make hw descriptor updates visible to CPU */
rmb();
@@ -1446,12 +1505,12 @@ static int macb_tx_complete(struct macb_queue *queue, int budget)
!ptp_one_step_sync(skb))
gem_ptp_do_txstamp(bp, skb, desc);
- netdev_vdbg(bp->dev, "skb %u (data %p) TX complete\n",
- macb_tx_ring_wrap(bp, tail),
+ netdev_vdbg(bp->netdev, "skb %u (data %p) TX complete\n",
+ macb_tx_ring_wrap(ctx, tail),
skb->data);
- bp->dev->stats.tx_packets++;
+ bp->netdev->stats.tx_packets++;
queue->stats.tx_packets++;
- bp->dev->stats.tx_bytes += skb->len;
+ bp->netdev->stats.tx_bytes += skb->len;
queue->stats.tx_bytes += skb->len;
packets++;
bytes += skb->len;
@@ -1469,14 +1528,14 @@ static int macb_tx_complete(struct macb_queue *queue, int budget)
}
}
- netdev_tx_completed_queue(netdev_get_tx_queue(bp->dev, queue_index),
+ netdev_tx_completed_queue(netdev_get_tx_queue(bp->netdev, q),
packets, bytes);
- queue->tx_tail = tail;
- if (__netif_subqueue_stopped(bp->dev, queue_index) &&
- CIRC_CNT(queue->tx_head, queue->tx_tail,
- bp->tx_ring_size) <= MACB_TX_WAKEUP_THRESH(bp))
- netif_wake_subqueue(bp->dev, queue_index);
+ txq->tail = tail;
+ if (__netif_subqueue_stopped(bp->netdev, q) &&
+ CIRC_CNT(txq->head, txq->tail,
+ bp->ctx->tx_ring_size) <= MACB_TX_WAKEUP_THRESH(bp))
+ netif_wake_subqueue(bp->netdev, q);
spin_unlock_irqrestore(&queue->tx_ptr_lock, flags);
if (packets)
@@ -1485,51 +1544,53 @@ static int macb_tx_complete(struct macb_queue *queue, int budget)
return packets;
}
-static void gem_rx_refill(struct macb_queue *queue)
+static void gem_rx_refill(struct macb_context *ctx, unsigned int q)
{
- unsigned int entry;
- struct sk_buff *skb;
- dma_addr_t paddr;
- struct macb *bp = queue->bp;
+ struct device *dev = &ctx->info->pdev->dev;
+ struct macb_rxq *rxq = &ctx->rxq[q];
struct macb_dma_desc *desc;
+ struct sk_buff *skb;
+ unsigned int entry;
+ dma_addr_t paddr;
- while (CIRC_SPACE(queue->rx_prepared_head, queue->rx_tail,
- bp->rx_ring_size) > 0) {
- entry = macb_rx_ring_wrap(bp, queue->rx_prepared_head);
+ while (CIRC_SPACE(rxq->prepared_head, rxq->tail,
+ ctx->rx_ring_size) > 0) {
+ entry = macb_rx_ring_wrap(ctx, rxq->prepared_head);
/* Make hw descriptor updates visible to CPU */
rmb();
- desc = macb_rx_desc(queue, entry);
+ desc = macb_rx_desc(ctx, q, entry);
- if (!queue->rx_skbuff[entry]) {
+ if (!rxq->skbuff[entry]) {
/* allocate sk_buff for this free entry in ring */
- skb = netdev_alloc_skb(bp->dev, bp->rx_buffer_size);
+ skb = netdev_alloc_skb(ctx->info->netdev,
+ ctx->rx_buffer_size);
if (unlikely(!skb)) {
- netdev_err(bp->dev,
+ netdev_err(ctx->info->netdev,
"Unable to allocate sk_buff\n");
break;
}
/* now fill corresponding descriptor entry */
- paddr = dma_map_single(&bp->pdev->dev, skb->data,
- bp->rx_buffer_size,
+ paddr = dma_map_single(dev, skb->data,
+ ctx->rx_buffer_size,
DMA_FROM_DEVICE);
- if (dma_mapping_error(&bp->pdev->dev, paddr)) {
+ if (dma_mapping_error(dev, paddr)) {
dev_kfree_skb(skb);
break;
}
- queue->rx_skbuff[entry] = skb;
+ rxq->skbuff[entry] = skb;
- if (entry == bp->rx_ring_size - 1)
+ if (entry == ctx->rx_ring_size - 1)
paddr |= MACB_BIT(RX_WRAP);
desc->ctrl = 0;
/* Setting addr clears RX_USED and allows reception,
* make sure ctrl is cleared first to avoid a race.
*/
dma_wmb();
- macb_set_addr(bp, desc, paddr);
+ macb_set_addr(ctx->info, desc, paddr);
/* Properly align Ethernet header.
*
@@ -1542,31 +1603,34 @@ static void gem_rx_refill(struct macb_queue *queue)
* setting the low 2/3 bits.
* It is 3 bits if HW_DMA_CAP_PTP, else 2 bits.
*/
- if (!(bp->caps & MACB_CAPS_RSC))
+ if (!(ctx->info->caps & MACB_CAPS_RSC))
skb_reserve(skb, NET_IP_ALIGN);
} else {
desc->ctrl = 0;
dma_wmb();
desc->addr &= ~MACB_BIT(RX_USED);
}
- queue->rx_prepared_head++;
+ rxq->prepared_head++;
}
/* Make descriptor updates visible to hardware */
wmb();
- netdev_vdbg(bp->dev, "rx ring: queue: %p, prepared head %d, tail %d\n",
- queue, queue->rx_prepared_head, queue->rx_tail);
+ netdev_vdbg(ctx->info->netdev,
+ "rx ring: queue: %u, prepared head %d, tail %d\n",
+ q, rxq->prepared_head, rxq->tail);
}
/* Mark DMA descriptors from begin up to and not including end as unused */
static void discard_partial_frame(struct macb_queue *queue, unsigned int begin,
unsigned int end)
{
+ unsigned int q = queue - queue->bp->queues;
+ struct macb_context *ctx = queue->bp->ctx;
unsigned int frag;
for (frag = begin; frag != end; frag++) {
- struct macb_dma_desc *desc = macb_rx_desc(queue, frag);
+ struct macb_dma_desc *desc = macb_rx_desc(ctx, q, frag);
desc->addr &= ~MACB_BIT(RX_USED);
}
@@ -1583,26 +1647,29 @@ static void discard_partial_frame(struct macb_queue *queue, unsigned int begin,
static int gem_rx(struct macb_queue *queue, struct napi_struct *napi,
int budget)
{
+ unsigned int q = queue - queue->bp->queues;
+ struct macb_context *ctx = queue->bp->ctx;
+ struct macb_rxq *rxq = macb_rxq(queue);
struct macb *bp = queue->bp;
- unsigned int len;
- unsigned int entry;
- struct sk_buff *skb;
- struct macb_dma_desc *desc;
- int count = 0;
+ struct macb_dma_desc *desc;
+ struct sk_buff *skb;
+ unsigned int entry;
+ unsigned int len;
+ int count = 0;
while (count < budget) {
u32 ctrl;
dma_addr_t addr;
bool rxused;
- entry = macb_rx_ring_wrap(bp, queue->rx_tail);
- desc = macb_rx_desc(queue, entry);
+ entry = macb_rx_ring_wrap(ctx, rxq->tail);
+ desc = macb_rx_desc(ctx, q, entry);
/* Make hw descriptor updates visible to CPU */
rmb();
rxused = (desc->addr & MACB_BIT(RX_USED)) ? true : false;
- addr = macb_get_addr(bp, desc);
+ addr = macb_get_addr(ctx, desc);
if (!rxused)
break;
@@ -1612,50 +1679,50 @@ static int gem_rx(struct macb_queue *queue, struct napi_struct *napi,
ctrl = desc->ctrl;
- queue->rx_tail++;
+ rxq->tail++;
count++;
if (!(ctrl & MACB_BIT(RX_SOF) && ctrl & MACB_BIT(RX_EOF))) {
- netdev_err(bp->dev,
+ netdev_err(bp->netdev,
"not whole frame pointed by descriptor\n");
- bp->dev->stats.rx_dropped++;
+ bp->netdev->stats.rx_dropped++;
queue->stats.rx_dropped++;
break;
}
- skb = queue->rx_skbuff[entry];
+ skb = rxq->skbuff[entry];
if (unlikely(!skb)) {
- netdev_err(bp->dev,
+ netdev_err(bp->netdev,
"inconsistent Rx descriptor chain\n");
- bp->dev->stats.rx_dropped++;
+ bp->netdev->stats.rx_dropped++;
queue->stats.rx_dropped++;
break;
}
/* now everything is ready for receiving packet */
- queue->rx_skbuff[entry] = NULL;
+ rxq->skbuff[entry] = NULL;
len = ctrl & bp->rx_frm_len_mask;
- netdev_vdbg(bp->dev, "gem_rx %u (len %u)\n", entry, len);
+ netdev_vdbg(bp->netdev, "gem_rx %u (len %u)\n", entry, len);
skb_put(skb, len);
dma_unmap_single(&bp->pdev->dev, addr,
- bp->rx_buffer_size, DMA_FROM_DEVICE);
+ bp->ctx->rx_buffer_size, DMA_FROM_DEVICE);
- skb->protocol = eth_type_trans(skb, bp->dev);
+ skb->protocol = eth_type_trans(skb, bp->netdev);
skb_checksum_none_assert(skb);
- if (bp->dev->features & NETIF_F_RXCSUM &&
- !(bp->dev->flags & IFF_PROMISC) &&
+ if (bp->netdev->features & NETIF_F_RXCSUM &&
+ !(bp->netdev->flags & IFF_PROMISC) &&
GEM_BFEXT(RX_CSUM, ctrl) & GEM_RX_CSUM_CHECKED_MASK)
skb->ip_summed = CHECKSUM_UNNECESSARY;
- bp->dev->stats.rx_packets++;
+ bp->netdev->stats.rx_packets++;
queue->stats.rx_packets++;
- bp->dev->stats.rx_bytes += skb->len;
+ bp->netdev->stats.rx_bytes += skb->len;
queue->stats.rx_bytes += skb->len;
gem_ptp_do_rxstamp(bp, skb, desc);
#if defined(DEBUG) && defined(VERBOSE_DEBUG)
- netdev_vdbg(bp->dev, "received skb of length %u, csum: %08x\n",
+ netdev_vdbg(bp->netdev, "received skb of length %u, csum: %08x\n",
skb->len, skb->csum);
print_hex_dump(KERN_DEBUG, " mac: ", DUMP_PREFIX_ADDRESS, 16, 1,
skb_mac_header(skb), 16, true);
@@ -1666,7 +1733,7 @@ static int gem_rx(struct macb_queue *queue, struct napi_struct *napi,
napi_gro_receive(napi, skb);
}
- gem_rx_refill(queue);
+ gem_rx_refill(ctx, q);
return count;
}
@@ -1674,19 +1741,21 @@ static int gem_rx(struct macb_queue *queue, struct napi_struct *napi,
static int macb_rx_frame(struct macb_queue *queue, struct napi_struct *napi,
unsigned int first_frag, unsigned int last_frag)
{
- unsigned int len;
- unsigned int frag;
+ unsigned int q = queue - queue->bp->queues;
+ struct macb_context *ctx = queue->bp->ctx;
+ struct macb *bp = queue->bp;
+ struct macb_dma_desc *desc;
unsigned int offset;
struct sk_buff *skb;
- struct macb_dma_desc *desc;
- struct macb *bp = queue->bp;
+ unsigned int frag;
+ unsigned int len;
- desc = macb_rx_desc(queue, last_frag);
+ desc = macb_rx_desc(ctx, q, last_frag);
len = desc->ctrl & bp->rx_frm_len_mask;
- netdev_vdbg(bp->dev, "macb_rx_frame frags %u - %u (len %u)\n",
- macb_rx_ring_wrap(bp, first_frag),
- macb_rx_ring_wrap(bp, last_frag), len);
+ netdev_vdbg(bp->netdev, "macb_rx_frame frags %u - %u (len %u)\n",
+ macb_rx_ring_wrap(ctx, first_frag),
+ macb_rx_ring_wrap(ctx, last_frag), len);
/* The ethernet header starts NET_IP_ALIGN bytes into the
* first buffer. Since the header is 14 bytes, this makes the
@@ -1696,11 +1765,11 @@ static int macb_rx_frame(struct macb_queue *queue, struct napi_struct *napi,
* the two padding bytes into the skb so that we avoid hitting
* the slowpath in memcpy(), and pull them off afterwards.
*/
- skb = netdev_alloc_skb(bp->dev, len + NET_IP_ALIGN);
+ skb = netdev_alloc_skb(bp->netdev, len + NET_IP_ALIGN);
if (!skb) {
- bp->dev->stats.rx_dropped++;
+ bp->netdev->stats.rx_dropped++;
for (frag = first_frag; ; frag++) {
- desc = macb_rx_desc(queue, frag);
+ desc = macb_rx_desc(ctx, q, frag);
desc->addr &= ~MACB_BIT(RX_USED);
if (frag == last_frag)
break;
@@ -1718,7 +1787,7 @@ static int macb_rx_frame(struct macb_queue *queue, struct napi_struct *napi,
skb_put(skb, len);
for (frag = first_frag; ; frag++) {
- unsigned int frag_len = bp->rx_buffer_size;
+ unsigned int frag_len = bp->ctx->rx_buffer_size;
if (offset + frag_len > len) {
if (unlikely(frag != last_frag)) {
@@ -1730,8 +1799,8 @@ static int macb_rx_frame(struct macb_queue *queue, struct napi_struct *napi,
skb_copy_to_linear_data_offset(skb, offset,
macb_rx_buffer(queue, frag),
frag_len);
- offset += bp->rx_buffer_size;
- desc = macb_rx_desc(queue, frag);
+ offset += bp->ctx->rx_buffer_size;
+ desc = macb_rx_desc(ctx, q, frag);
desc->addr &= ~MACB_BIT(RX_USED);
if (frag == last_frag)
@@ -1742,46 +1811,49 @@ static int macb_rx_frame(struct macb_queue *queue, struct napi_struct *napi,
wmb();
__skb_pull(skb, NET_IP_ALIGN);
- skb->protocol = eth_type_trans(skb, bp->dev);
+ skb->protocol = eth_type_trans(skb, bp->netdev);
- bp->dev->stats.rx_packets++;
- bp->dev->stats.rx_bytes += skb->len;
- netdev_vdbg(bp->dev, "received skb of length %u, csum: %08x\n",
+ bp->netdev->stats.rx_packets++;
+ bp->netdev->stats.rx_bytes += skb->len;
+ netdev_vdbg(bp->netdev, "received skb of length %u, csum: %08x\n",
skb->len, skb->csum);
napi_gro_receive(napi, skb);
return 0;
}
-static inline void macb_init_rx_ring(struct macb_queue *queue)
+static inline void macb_init_rx_ring(struct macb_context *ctx, unsigned int q)
{
- struct macb *bp = queue->bp;
- dma_addr_t addr;
+ struct macb_rxq *rxq = &ctx->rxq[q];
struct macb_dma_desc *desc = NULL;
+ dma_addr_t addr;
int i;
- addr = queue->rx_buffers_dma;
- for (i = 0; i < bp->rx_ring_size; i++) {
- desc = macb_rx_desc(queue, i);
- macb_set_addr(bp, desc, addr);
+ addr = rxq->buffers_dma;
+ for (i = 0; i < ctx->rx_ring_size; i++) {
+ desc = macb_rx_desc(ctx, q, i);
+ macb_set_addr(ctx->info, desc, addr);
desc->ctrl = 0;
- addr += bp->rx_buffer_size;
+ addr += ctx->rx_buffer_size;
}
desc->addr |= MACB_BIT(RX_WRAP);
- queue->rx_tail = 0;
+ rxq->tail = 0;
}
static int macb_rx(struct macb_queue *queue, struct napi_struct *napi,
int budget)
{
+ unsigned int q = queue - queue->bp->queues;
+ struct macb_context *ctx = queue->bp->ctx;
+ struct macb_rxq *rxq = macb_rxq(queue);
struct macb *bp = queue->bp;
bool reset_rx_queue = false;
- int received = 0;
- unsigned int tail;
int first_frag = -1;
+ unsigned int tail;
+ int received = 0;
- for (tail = queue->rx_tail; budget > 0; tail++) {
- struct macb_dma_desc *desc = macb_rx_desc(queue, tail);
+ for (tail = rxq->tail; budget > 0; tail++) {
+ struct macb_dma_desc *desc = macb_rx_desc(ctx, q, tail);
u32 ctrl;
/* Make hw descriptor updates visible to CPU */
@@ -1826,15 +1898,15 @@ static int macb_rx(struct macb_queue *queue, struct napi_struct *napi,
unsigned long flags;
u32 ctrl;
- netdev_err(bp->dev, "RX queue corruption: reset it\n");
+ netdev_err(bp->netdev, "RX queue corruption: reset it\n");
spin_lock_irqsave(&bp->lock, flags);
ctrl = macb_readl(bp, NCR);
macb_writel(bp, NCR, ctrl & ~MACB_BIT(RE));
- macb_init_rx_ring(queue);
- queue_writel(queue, RBQP, queue->rx_ring_dma);
+ macb_init_rx_ring(ctx, q);
+ queue_writel(queue, RBQP, rxq->ring_dma);
macb_writel(bp, NCR, ctrl | MACB_BIT(RE));
@@ -1843,21 +1915,23 @@ static int macb_rx(struct macb_queue *queue, struct napi_struct *napi,
}
if (first_frag != -1)
- queue->rx_tail = first_frag;
+ rxq->tail = first_frag;
else
- queue->rx_tail = tail;
+ rxq->tail = tail;
return received;
}
static bool macb_rx_pending(struct macb_queue *queue)
{
- struct macb *bp = queue->bp;
- unsigned int entry;
- struct macb_dma_desc *desc;
+ unsigned int q = queue - queue->bp->queues;
+ struct macb_context *ctx = queue->bp->ctx;
+ struct macb_rxq *rxq = macb_rxq(queue);
+ struct macb_dma_desc *desc;
+ unsigned int entry;
- entry = macb_rx_ring_wrap(bp, queue->rx_tail);
- desc = macb_rx_desc(queue, entry);
+ entry = macb_rx_ring_wrap(ctx, rxq->tail);
+ desc = macb_rx_desc(ctx, q, entry);
/* Make hw descriptor updates visible to CPU */
rmb();
@@ -1873,7 +1947,7 @@ static int macb_rx_poll(struct napi_struct *napi, int budget)
work_done = bp->macbgem_ops.mog_rx(queue, napi, budget);
- netdev_vdbg(bp->dev, "RX poll: queue = %u, work_done = %d, budget = %d\n",
+ netdev_vdbg(bp->netdev, "RX poll: queue = %u, work_done = %d, budget = %d\n",
(unsigned int)(queue - bp->queues), work_done, budget);
if (work_done < budget && napi_complete_done(napi, work_done)) {
@@ -1892,7 +1966,7 @@ static int macb_rx_poll(struct napi_struct *napi, int budget)
if (macb_rx_pending(queue)) {
queue_writel(queue, IDR, bp->rx_intr_mask);
macb_queue_isr_clear(bp, queue, MACB_BIT(RCOMP));
- netdev_vdbg(bp->dev, "poll: packets pending, reschedule\n");
+ netdev_vdbg(bp->netdev, "poll: packets pending, reschedule\n");
napi_schedule(napi);
}
}
@@ -1904,18 +1978,20 @@ static int macb_rx_poll(struct napi_struct *napi, int budget)
static void macb_tx_restart(struct macb_queue *queue)
{
+ struct macb_context *ctx = queue->bp->ctx;
+ struct macb_txq *txq = macb_txq(queue);
struct macb *bp = queue->bp;
unsigned int head_idx, tbqp;
unsigned long flags;
spin_lock_irqsave(&queue->tx_ptr_lock, flags);
- if (queue->tx_head == queue->tx_tail)
+ if (txq->head == txq->tail)
goto out_tx_ptr_unlock;
- tbqp = queue_readl(queue, TBQP) / macb_dma_desc_get_size(bp);
- tbqp = macb_adj_dma_desc_idx(bp, macb_tx_ring_wrap(bp, tbqp));
- head_idx = macb_adj_dma_desc_idx(bp, macb_tx_ring_wrap(bp, queue->tx_head));
+ tbqp = queue_readl(queue, TBQP) / macb_dma_desc_get_size(ctx->info);
+ tbqp = macb_adj_dma_desc_idx(ctx, macb_tx_ring_wrap(ctx, tbqp));
+ head_idx = macb_adj_dma_desc_idx(ctx, macb_tx_ring_wrap(ctx, txq->head));
if (tbqp == head_idx)
goto out_tx_ptr_unlock;
@@ -1930,15 +2006,18 @@ static void macb_tx_restart(struct macb_queue *queue)
static bool macb_tx_complete_pending(struct macb_queue *queue)
{
+ unsigned int q = queue - queue->bp->queues;
+ struct macb_context *ctx = queue->bp->ctx;
+ struct macb_txq *txq = macb_txq(queue);
bool retval = false;
unsigned long flags;
spin_lock_irqsave(&queue->tx_ptr_lock, flags);
- if (queue->tx_head != queue->tx_tail) {
+ if (txq->head != txq->tail) {
/* Make hw descriptor updates visible to CPU */
rmb();
- if (macb_tx_desc(queue, queue->tx_tail)->ctrl & MACB_BIT(TX_USED))
+ if (macb_tx_desc(ctx, q, txq->tail)->ctrl & MACB_BIT(TX_USED))
retval = true;
}
spin_unlock_irqrestore(&queue->tx_ptr_lock, flags);
@@ -1956,11 +2035,11 @@ static int macb_tx_poll(struct napi_struct *napi, int budget)
rmb(); // ensure txubr_pending is up to date
if (queue->txubr_pending) {
queue->txubr_pending = false;
- netdev_vdbg(bp->dev, "poll: tx restart\n");
+ netdev_vdbg(bp->netdev, "poll: tx restart\n");
macb_tx_restart(queue);
}
- netdev_vdbg(bp->dev, "TX poll: queue = %u, work_done = %d, budget = %d\n",
+ netdev_vdbg(bp->netdev, "TX poll: queue = %u, work_done = %d, budget = %d\n",
(unsigned int)(queue - bp->queues), work_done, budget);
if (work_done < budget && napi_complete_done(napi, work_done)) {
@@ -1979,7 +2058,7 @@ static int macb_tx_poll(struct napi_struct *napi, int budget)
if (macb_tx_complete_pending(queue)) {
queue_writel(queue, IDR, MACB_BIT(TCOMP));
macb_queue_isr_clear(bp, queue, MACB_BIT(TCOMP));
- netdev_vdbg(bp->dev, "TX poll: packets pending, reschedule\n");
+ netdev_vdbg(bp->netdev, "TX poll: packets pending, reschedule\n");
napi_schedule(napi);
}
}
@@ -1990,7 +2069,8 @@ static int macb_tx_poll(struct napi_struct *napi, int budget)
static void macb_hresp_error_task(struct work_struct *work)
{
struct macb *bp = from_work(bp, work, hresp_err_bh_work);
- struct net_device *dev = bp->dev;
+ struct net_device *netdev = bp->netdev;
+ struct macb_context *ctx = bp->ctx;
struct macb_queue *queue;
unsigned int q;
u32 ctrl;
@@ -2004,10 +2084,10 @@ static void macb_hresp_error_task(struct work_struct *work)
ctrl &= ~(MACB_BIT(RE) | MACB_BIT(TE));
macb_writel(bp, NCR, ctrl);
- netif_tx_stop_all_queues(dev);
- netif_carrier_off(dev);
+ netif_tx_stop_all_queues(netdev);
+ netif_carrier_off(netdev);
- bp->macbgem_ops.mog_init_rings(bp);
+ bp->macbgem_ops.mog_init_rings(ctx);
/* Initialize TX and RX buffers */
macb_init_buffers(bp);
@@ -2022,8 +2102,8 @@ static void macb_hresp_error_task(struct work_struct *work)
ctrl |= MACB_BIT(RE) | MACB_BIT(TE);
macb_writel(bp, NCR, ctrl);
- netif_carrier_on(dev);
- netif_tx_start_all_queues(dev);
+ netif_carrier_on(netdev);
+ netif_tx_start_all_queues(netdev);
}
static void macb_wol_interrupt(struct macb_queue *queue, u32 status)
@@ -2032,7 +2112,7 @@ static void macb_wol_interrupt(struct macb_queue *queue, u32 status)
queue_writel(queue, IDR, MACB_BIT(WOL));
macb_writel(bp, WOL, 0);
- netdev_vdbg(bp->dev, "MACB WoL: queue = %u, isr = 0x%08lx\n",
+ netdev_vdbg(bp->netdev, "MACB WoL: queue = %u, isr = 0x%08lx\n",
(unsigned int)(queue - bp->queues),
(unsigned long)status);
macb_queue_isr_clear(bp, queue, MACB_BIT(WOL));
@@ -2045,7 +2125,7 @@ static void gem_wol_interrupt(struct macb_queue *queue, u32 status)
queue_writel(queue, IDR, GEM_BIT(WOL));
gem_writel(bp, WOL, 0);
- netdev_vdbg(bp->dev, "GEM WoL: queue = %u, isr = 0x%08lx\n",
+ netdev_vdbg(bp->netdev, "GEM WoL: queue = %u, isr = 0x%08lx\n",
(unsigned int)(queue - bp->queues),
(unsigned long)status);
macb_queue_isr_clear(bp, queue, GEM_BIT(WOL));
@@ -2055,10 +2135,10 @@ static void gem_wol_interrupt(struct macb_queue *queue, u32 status)
static int macb_interrupt_misc(struct macb_queue *queue, u32 status)
{
struct macb *bp = queue->bp;
- struct net_device *dev;
+ struct net_device *netdev;
u32 ctrl;
- dev = bp->dev;
+ netdev = bp->netdev;
if (unlikely(status & (MACB_TX_ERR_FLAGS))) {
queue_writel(queue, IDR, MACB_TX_INT_FLAGS);
@@ -2089,7 +2169,7 @@ static int macb_interrupt_misc(struct macb_queue *queue, u32 status)
if (status & MACB_BIT(ISR_ROVR)) {
/* We missed at least one packet */
spin_lock(&bp->stats_lock);
- if (macb_is_gem(bp))
+ if (macb_is_gem(&bp->info))
bp->hw_stats.gem.rx_overruns++;
else
bp->hw_stats.macb.rx_overruns++;
@@ -2099,11 +2179,11 @@ static int macb_interrupt_misc(struct macb_queue *queue, u32 status)
if (status & MACB_BIT(HRESP)) {
queue_work(system_bh_wq, &bp->hresp_err_bh_work);
- netdev_err(dev, "DMA bus error: HRESP not OK\n");
+ netdev_err(netdev, "DMA bus error: HRESP not OK\n");
macb_queue_isr_clear(bp, queue, MACB_BIT(HRESP));
}
- if (macb_is_gem(bp)) {
+ if (macb_is_gem(&bp->info)) {
if (status & GEM_BIT(WOL))
gem_wol_interrupt(queue, status);
} else {
@@ -2118,25 +2198,33 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
{
struct macb_queue *queue = dev_id;
struct macb *bp = queue->bp;
- struct net_device *dev = bp->dev;
+ struct net_device *netdev = bp->netdev;
u32 status;
- status = queue_readl(queue, ISR);
-
- if (unlikely(!status))
- return IRQ_NONE;
+ /* detect spurious interrupts without grabbing bp->lock */
+ if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) {
+ status = queue_readl(queue, ISR);
+ if (unlikely(!status))
+ return IRQ_NONE;
+ }
spin_lock(&bp->lock);
+ status = queue_readl(queue, ISR);
+ if (unlikely(!status)) {
+ spin_unlock(&bp->lock);
+ return IRQ_NONE;
+ }
+
while (status) {
/* close possible race with dev_close */
- if (unlikely(!netif_running(dev))) {
+ if (unlikely(!netif_running(netdev))) {
queue_writel(queue, IDR, -1);
macb_queue_isr_clear(bp, queue, -1);
break;
}
- netdev_vdbg(bp->dev, "queue = %u, isr = 0x%08lx\n",
+ netdev_vdbg(netdev, "queue = %u, isr = 0x%08lx\n",
(unsigned int)(queue - bp->queues),
(unsigned long)status);
@@ -2181,16 +2269,16 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
/* Polling receive - used by netconsole and other diagnostic tools
* to allow network i/o with interrupts disabled.
*/
-static void macb_poll_controller(struct net_device *dev)
+static void macb_poll_controller(struct net_device *netdev)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_queue *queue;
unsigned long flags;
unsigned int q;
local_irq_save(flags);
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue)
- macb_interrupt(dev->irq, queue);
+ macb_interrupt(netdev->irq, queue);
local_irq_restore(flags);
}
#endif
@@ -2200,9 +2288,12 @@ static unsigned int macb_tx_map(struct macb *bp,
struct sk_buff *skb,
unsigned int hdrlen)
{
+ struct macb_txq *txq = macb_txq(queue);
unsigned int f, nr_frags = skb_shinfo(skb)->nr_frags;
- unsigned int len, i, tx_head = queue->tx_head;
+ unsigned int len, i, tx_head = txq->head;
u32 ctrl, lso_ctrl = 0, seq_ctrl = 0;
+ unsigned int q = queue - bp->queues;
+ struct macb_context *ctx = bp->ctx;
unsigned int eof = 1, mss_mfs = 0;
struct macb_tx_skb *tx_skb = NULL;
struct macb_dma_desc *desc;
@@ -2277,7 +2368,7 @@ static unsigned int macb_tx_map(struct macb *bp,
/* Should never happen */
if (unlikely(!tx_skb)) {
- netdev_err(bp->dev, "BUG! empty skb!\n");
+ netdev_err(bp->netdev, "BUG! empty skb!\n");
return 0;
}
@@ -2293,7 +2384,7 @@ static unsigned int macb_tx_map(struct macb *bp,
*/
i = tx_head;
ctrl = MACB_BIT(TX_USED);
- desc = macb_tx_desc(queue, i);
+ desc = macb_tx_desc(ctx, q, i);
desc->ctrl = ctrl;
if (lso_ctrl) {
@@ -2314,21 +2405,22 @@ static unsigned int macb_tx_map(struct macb *bp,
do {
i--;
tx_skb = macb_tx_skb(queue, i);
- desc = macb_tx_desc(queue, i);
+ desc = macb_tx_desc(ctx, q, i);
ctrl = (u32)tx_skb->size;
if (eof) {
ctrl |= MACB_BIT(TX_LAST);
eof = 0;
}
- if (unlikely(macb_tx_ring_wrap(bp, i) == bp->tx_ring_size - 1))
+ if (unlikely(macb_tx_ring_wrap(ctx, i) ==
+ bp->ctx->tx_ring_size - 1))
ctrl |= MACB_BIT(TX_WRAP);
/* First descriptor is header descriptor */
- if (i == queue->tx_head) {
+ if (i == txq->head) {
ctrl |= MACB_BF(TX_LSO, lso_ctrl);
ctrl |= MACB_BF(TX_TCP_SEQ_SRC, seq_ctrl);
- if ((bp->dev->features & NETIF_F_HW_CSUM) &&
+ if ((bp->netdev->features & NETIF_F_HW_CSUM) &&
skb->ip_summed != CHECKSUM_PARTIAL && !lso_ctrl &&
!ptp_one_step_sync(skb))
ctrl |= MACB_BIT(TX_NOCRC);
@@ -2339,22 +2431,22 @@ static unsigned int macb_tx_map(struct macb *bp,
ctrl |= MACB_BF(MSS_MFS, mss_mfs);
/* Set TX buffer descriptor */
- macb_set_addr(bp, desc, tx_skb->mapping);
+ macb_set_addr(&bp->info, desc, tx_skb->mapping);
/* desc->addr must be visible to hardware before clearing
* 'TX_USED' bit in desc->ctrl.
*/
wmb();
desc->ctrl = ctrl;
- } while (i != queue->tx_head);
+ } while (i != txq->head);
- queue->tx_head = tx_head;
+ txq->head = tx_head;
return 0;
dma_error:
- netdev_err(bp->dev, "TX DMA map failed\n");
+ netdev_err(bp->netdev, "TX DMA map failed\n");
- for (i = queue->tx_head; i != tx_head; i++) {
+ for (i = txq->head; i != tx_head; i++) {
tx_skb = macb_tx_skb(queue, i);
macb_tx_unmap(bp, tx_skb, 0);
@@ -2364,7 +2456,7 @@ static unsigned int macb_tx_map(struct macb *bp,
}
static netdev_features_t macb_features_check(struct sk_buff *skb,
- struct net_device *dev,
+ struct net_device *netdev,
netdev_features_t features)
{
unsigned int nr_frags, f;
@@ -2416,7 +2508,7 @@ static inline int macb_clear_csum(struct sk_buff *skb)
return 0;
}
-static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)
+static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *netdev)
{
bool cloned = skb_cloned(*skb) || skb_header_cloned(*skb) ||
skb_is_nonlinear(*skb);
@@ -2425,7 +2517,7 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)
struct sk_buff *nskb;
u32 fcs;
- if (!(ndev->features & NETIF_F_HW_CSUM) ||
+ if (!(netdev->features & NETIF_F_HW_CSUM) ||
!((*skb)->ip_summed != CHECKSUM_PARTIAL) ||
skb_shinfo(*skb)->gso_size || ptp_one_step_sync(*skb))
return 0;
@@ -2467,28 +2559,30 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)
return 0;
}
-static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t macb_start_xmit(struct sk_buff *skb,
+ struct net_device *netdev)
{
- u16 queue_index = skb_get_queue_mapping(skb);
- struct macb *bp = netdev_priv(dev);
- struct macb_queue *queue = &bp->queues[queue_index];
+ struct macb *bp = netdev_priv(netdev);
+ unsigned int q = skb_get_queue_mapping(skb);
unsigned int desc_cnt, nr_frags, frag_size, f;
+ struct macb_queue *queue = &bp->queues[q];
+ struct macb_txq *txq = macb_txq(queue);
+ netdev_tx_t ret = NETDEV_TX_OK;
unsigned int hdrlen;
unsigned long flags;
bool is_lso;
- netdev_tx_t ret = NETDEV_TX_OK;
if (macb_clear_csum(skb)) {
dev_kfree_skb_any(skb);
return ret;
}
- if (macb_pad_and_fcs(&skb, dev)) {
+ if (macb_pad_and_fcs(&skb, netdev)) {
dev_kfree_skb_any(skb);
return ret;
}
- if (macb_dma_ptp(bp) &&
+ if (macb_dma_ptp(&bp->info) &&
(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
@@ -2502,7 +2596,7 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
else
hdrlen = skb_tcp_all_headers(skb);
if (skb_headlen(skb) < hdrlen) {
- netdev_err(bp->dev, "Error - LSO headers fragmented!!!\n");
+ netdev_err(bp->netdev, "Error - LSO headers fragmented!!!\n");
/* if this is required, would need to copy to single buffer */
return NETDEV_TX_BUSY;
}
@@ -2510,9 +2604,9 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
hdrlen = umin(skb_headlen(skb), bp->max_tx_length);
#if defined(DEBUG) && defined(VERBOSE_DEBUG)
- netdev_vdbg(bp->dev,
- "start_xmit: queue %hu len %u head %p data %p tail %p end %p\n",
- queue_index, skb->len, skb->head, skb->data,
+ netdev_vdbg(bp->netdev,
+ "start_xmit: queue %u len %u head %p data %p tail %p end %p\n",
+ q, skb->len, skb->head, skb->data,
skb_tail_pointer(skb), skb_end_pointer(skb));
print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_OFFSET, 16, 1,
skb->data, 16, true);
@@ -2536,11 +2630,11 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_lock_irqsave(&queue->tx_ptr_lock, flags);
/* This is a hard error, log it. */
- if (CIRC_SPACE(queue->tx_head, queue->tx_tail,
- bp->tx_ring_size) < desc_cnt) {
- netif_stop_subqueue(dev, queue_index);
- netdev_dbg(bp->dev, "tx_head = %u, tx_tail = %u\n",
- queue->tx_head, queue->tx_tail);
+ if (CIRC_SPACE(txq->head, txq->tail,
+ bp->ctx->tx_ring_size) < desc_cnt) {
+ netif_stop_subqueue(netdev, q);
+ netdev_dbg(netdev, "tx_head = %u, tx_tail = %u\n",
+ txq->head, txq->tail);
ret = NETDEV_TX_BUSY;
goto unlock;
}
@@ -2554,7 +2648,7 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Make newly initialized descriptor visible to hardware */
wmb();
skb_tx_timestamp(skb);
- netdev_tx_sent_queue(netdev_get_tx_queue(bp->dev, queue_index),
+ netdev_tx_sent_queue(netdev_get_tx_queue(bp->netdev, q),
skb->len);
spin_lock(&bp->lock);
@@ -2562,8 +2656,8 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
spin_unlock(&bp->lock);
- if (CIRC_SPACE(queue->tx_head, queue->tx_tail, bp->tx_ring_size) < 1)
- netif_stop_subqueue(dev, queue_index);
+ if (CIRC_SPACE(txq->head, txq->tail, bp->ctx->tx_ring_size) < 1)
+ netif_stop_subqueue(netdev, q);
unlock:
spin_unlock_irqrestore(&queue->tx_ptr_lock, flags);
@@ -2571,151 +2665,163 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
return ret;
}
-static void macb_init_rx_buffer_size(struct macb *bp, size_t size)
+static unsigned int macb_rx_buffer_size(struct macb *bp, unsigned int mtu)
{
- if (!macb_is_gem(bp)) {
- bp->rx_buffer_size = MACB_RX_BUFFER_SIZE;
+ unsigned int size;
+
+ if (!macb_is_gem(&bp->info)) {
+ size = MACB_RX_BUFFER_SIZE;
} else {
- bp->rx_buffer_size = MIN(size, RX_BUFFER_MAX);
+ size = mtu + ETH_HLEN + ETH_FCS_LEN + NET_IP_ALIGN;
+ size = MIN(size, RX_BUFFER_MAX);
- if (bp->rx_buffer_size % RX_BUFFER_MULTIPLE) {
- netdev_dbg(bp->dev,
+ if (size % RX_BUFFER_MULTIPLE) {
+ netdev_dbg(bp->netdev,
"RX buffer must be multiple of %d bytes, expanding\n",
RX_BUFFER_MULTIPLE);
- bp->rx_buffer_size =
- roundup(bp->rx_buffer_size, RX_BUFFER_MULTIPLE);
+ size = roundup(size, RX_BUFFER_MULTIPLE);
}
}
- netdev_dbg(bp->dev, "mtu [%u] rx_buffer_size [%zu]\n",
- bp->dev->mtu, bp->rx_buffer_size);
+ netdev_dbg(bp->netdev, "mtu [%u] rx_buffer_size [%u]\n", mtu, size);
+ return size;
}
-static void gem_free_rx_buffers(struct macb *bp)
+static void gem_free_rx_buffers(struct macb_context *ctx)
{
- struct sk_buff *skb;
- struct macb_dma_desc *desc;
- struct macb_queue *queue;
- dma_addr_t addr;
+ struct device *dev = &ctx->info->pdev->dev;
+ struct macb_dma_desc *desc;
+ struct macb_rxq *rxq;
+ struct sk_buff *skb;
+ dma_addr_t addr;
unsigned int q;
int i;
- for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
- if (!queue->rx_skbuff)
+ for (q = 0; q < ctx->info->num_queues; ++q) {
+ rxq = &ctx->rxq[q];
+
+ if (!rxq->skbuff)
continue;
- for (i = 0; i < bp->rx_ring_size; i++) {
- skb = queue->rx_skbuff[i];
+ for (i = 0; i < ctx->rx_ring_size; i++) {
+ skb = rxq->skbuff[i];
if (!skb)
continue;
- desc = macb_rx_desc(queue, i);
- addr = macb_get_addr(bp, desc);
+ desc = macb_rx_desc(ctx, q, i);
+ addr = macb_get_addr(ctx, desc);
- dma_unmap_single(&bp->pdev->dev, addr, bp->rx_buffer_size,
- DMA_FROM_DEVICE);
+ dma_unmap_single(dev, addr, ctx->rx_buffer_size,
+ DMA_FROM_DEVICE);
dev_kfree_skb_any(skb);
skb = NULL;
}
- kfree(queue->rx_skbuff);
- queue->rx_skbuff = NULL;
+ kfree(rxq->skbuff);
+ rxq->skbuff = NULL;
}
}
-static void macb_free_rx_buffers(struct macb *bp)
+static void macb_free_rx_buffers(struct macb_context *ctx)
{
- struct macb_queue *queue = &bp->queues[0];
+ struct device *dev = &ctx->info->pdev->dev;
+ struct macb_rxq *rxq = &ctx->rxq[0];
- if (queue->rx_buffers) {
- dma_free_coherent(&bp->pdev->dev,
- bp->rx_ring_size * bp->rx_buffer_size,
- queue->rx_buffers, queue->rx_buffers_dma);
- queue->rx_buffers = NULL;
+ if (rxq->buffers) {
+ dma_free_coherent(dev,
+ ctx->rx_ring_size * ctx->rx_buffer_size,
+ rxq->buffers, rxq->buffers_dma);
+ rxq->buffers = NULL;
}
}
-static unsigned int macb_tx_ring_size_per_queue(struct macb *bp)
+static unsigned int macb_tx_ring_size_per_queue(struct macb_context *ctx)
{
- return macb_dma_desc_get_size(bp) * bp->tx_ring_size + bp->tx_bd_rd_prefetch;
+ return macb_dma_desc_get_size(ctx->info) * ctx->tx_ring_size +
+ ctx->info->tx_bd_rd_prefetch;
}
-static unsigned int macb_rx_ring_size_per_queue(struct macb *bp)
+static unsigned int macb_rx_ring_size_per_queue(struct macb_context *ctx)
{
- return macb_dma_desc_get_size(bp) * bp->rx_ring_size + bp->rx_bd_rd_prefetch;
+ return macb_dma_desc_get_size(ctx->info) * ctx->rx_ring_size +
+ ctx->info->rx_bd_rd_prefetch;
}
-static void macb_free_consistent(struct macb *bp)
+static void macb_free(struct macb_context *ctx)
{
- struct device *dev = &bp->pdev->dev;
- struct macb_queue *queue;
+ struct device *dev = &ctx->info->pdev->dev;
+ struct macb_txq *txq;
+ struct macb_rxq *rxq;
unsigned int q;
size_t size;
- if (bp->rx_ring_tieoff) {
- dma_free_coherent(dev, macb_dma_desc_get_size(bp),
- bp->rx_ring_tieoff, bp->rx_ring_tieoff_dma);
- bp->rx_ring_tieoff = NULL;
- }
+ ctx->info->macbgem_ops.mog_free_rx_buffers(ctx);
- bp->macbgem_ops.mog_free_rx_buffers(bp);
+ txq = &ctx->txq[0];
+ size = ctx->info->num_queues * macb_tx_ring_size_per_queue(ctx);
+ dma_free_coherent(dev, size, txq->ring, txq->ring_dma);
- size = bp->num_queues * macb_tx_ring_size_per_queue(bp);
- dma_free_coherent(dev, size, bp->queues[0].tx_ring, bp->queues[0].tx_ring_dma);
+ rxq = &ctx->rxq[0];
+ size = ctx->info->num_queues * macb_rx_ring_size_per_queue(ctx);
+ dma_free_coherent(dev, size, rxq->ring, rxq->ring_dma);
- size = bp->num_queues * macb_rx_ring_size_per_queue(bp);
- dma_free_coherent(dev, size, bp->queues[0].rx_ring, bp->queues[0].rx_ring_dma);
+ for (q = 0; q < ctx->info->num_queues; ++q) {
+ txq = &ctx->txq[q];
+ rxq = &ctx->rxq[q];
- for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
- kfree(queue->tx_skb);
- queue->tx_skb = NULL;
- queue->tx_ring = NULL;
- queue->rx_ring = NULL;
+ kfree(txq->skb);
+ txq->skb = NULL;
+ txq->ring = NULL;
+ rxq->ring = NULL;
}
}
-static int gem_alloc_rx_buffers(struct macb *bp)
+static int gem_alloc_rx_buffers(struct macb_context *ctx)
{
- struct macb_queue *queue;
+ struct macb_rxq *rxq;
unsigned int q;
int size;
- for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
- size = bp->rx_ring_size * sizeof(struct sk_buff *);
- queue->rx_skbuff = kzalloc(size, GFP_KERNEL);
- if (!queue->rx_skbuff)
+ for (q = 0; q < ctx->info->num_queues; ++q) {
+ rxq = &ctx->rxq[q];
+ size = ctx->rx_ring_size * sizeof(struct sk_buff *);
+ rxq->skbuff = kzalloc(size, GFP_KERNEL);
+ if (!rxq->skbuff)
return -ENOMEM;
else
- netdev_dbg(bp->dev,
+ netdev_dbg(ctx->info->netdev,
"Allocated %d RX struct sk_buff entries at %p\n",
- bp->rx_ring_size, queue->rx_skbuff);
+ ctx->rx_ring_size, rxq->skbuff);
}
return 0;
}
-static int macb_alloc_rx_buffers(struct macb *bp)
+static int macb_alloc_rx_buffers(struct macb_context *ctx)
{
- struct macb_queue *queue = &bp->queues[0];
+ struct device *dev = &ctx->info->pdev->dev;
+ struct macb_rxq *rxq = &ctx->rxq[0];
int size;
- size = bp->rx_ring_size * bp->rx_buffer_size;
- queue->rx_buffers = dma_alloc_coherent(&bp->pdev->dev, size,
- &queue->rx_buffers_dma, GFP_KERNEL);
- if (!queue->rx_buffers)
+ size = ctx->rx_ring_size * ctx->rx_buffer_size;
+ rxq->buffers = dma_alloc_coherent(dev, size,
+ &rxq->buffers_dma, GFP_KERNEL);
+ if (!rxq->buffers)
return -ENOMEM;
- netdev_dbg(bp->dev,
+ netdev_dbg(ctx->info->netdev,
"Allocated RX buffers of %d bytes at %08lx (mapped %p)\n",
- size, (unsigned long)queue->rx_buffers_dma, queue->rx_buffers);
+ size, (unsigned long)rxq->buffers_dma, rxq->buffers);
return 0;
}
-static int macb_alloc_consistent(struct macb *bp)
+static int macb_alloc(struct macb_context *ctx)
{
- struct device *dev = &bp->pdev->dev;
+ unsigned int num_queues = ctx->info->num_queues;
+ struct device *dev = &ctx->info->pdev->dev;
dma_addr_t tx_dma, rx_dma;
- struct macb_queue *queue;
+ struct macb_txq *txq;
+ struct macb_rxq *rxq;
unsigned int q;
void *tx, *rx;
size_t size;
@@ -2727,113 +2833,125 @@ static int macb_alloc_consistent(struct macb *bp)
* natural alignment of physical addresses.
*/
- size = bp->num_queues * macb_tx_ring_size_per_queue(bp);
+ size = num_queues * macb_tx_ring_size_per_queue(ctx);
tx = dma_alloc_coherent(dev, size, &tx_dma, GFP_KERNEL);
if (!tx || upper_32_bits(tx_dma) != upper_32_bits(tx_dma + size - 1))
goto out_err;
- netdev_dbg(bp->dev, "Allocated %zu bytes for %u TX rings at %08lx (mapped %p)\n",
- size, bp->num_queues, (unsigned long)tx_dma, tx);
+ netdev_dbg(ctx->info->netdev,
+ "Allocated %zu bytes for %u TX rings at %08lx (mapped %p)\n",
+ size, num_queues, (unsigned long)tx_dma, tx);
- size = bp->num_queues * macb_rx_ring_size_per_queue(bp);
+ size = num_queues * macb_rx_ring_size_per_queue(ctx);
rx = dma_alloc_coherent(dev, size, &rx_dma, GFP_KERNEL);
if (!rx || upper_32_bits(rx_dma) != upper_32_bits(rx_dma + size - 1))
goto out_err;
- netdev_dbg(bp->dev, "Allocated %zu bytes for %u RX rings at %08lx (mapped %p)\n",
- size, bp->num_queues, (unsigned long)rx_dma, rx);
+ netdev_dbg(ctx->info->netdev,
+ "Allocated %zu bytes for %u RX rings at %08lx (mapped %p)\n",
+ size, num_queues, (unsigned long)rx_dma, rx);
- for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
- queue->tx_ring = tx + macb_tx_ring_size_per_queue(bp) * q;
- queue->tx_ring_dma = tx_dma + macb_tx_ring_size_per_queue(bp) * q;
+ for (q = 0; q < num_queues; ++q) {
+ txq = &ctx->txq[q];
+ rxq = &ctx->rxq[q];
- queue->rx_ring = rx + macb_rx_ring_size_per_queue(bp) * q;
- queue->rx_ring_dma = rx_dma + macb_rx_ring_size_per_queue(bp) * q;
+ txq->ring = tx + macb_tx_ring_size_per_queue(ctx) * q;
+ txq->ring_dma = tx_dma + macb_tx_ring_size_per_queue(ctx) * q;
- size = bp->tx_ring_size * sizeof(struct macb_tx_skb);
- queue->tx_skb = kmalloc(size, GFP_KERNEL);
- if (!queue->tx_skb)
- goto out_err;
- }
- if (bp->macbgem_ops.mog_alloc_rx_buffers(bp))
- goto out_err;
+ rxq->ring = rx + macb_rx_ring_size_per_queue(ctx) * q;
+ rxq->ring_dma = rx_dma + macb_rx_ring_size_per_queue(ctx) * q;
- /* Required for tie off descriptor for PM cases */
- if (!(bp->caps & MACB_CAPS_QUEUE_DISABLE)) {
- bp->rx_ring_tieoff = dma_alloc_coherent(&bp->pdev->dev,
- macb_dma_desc_get_size(bp),
- &bp->rx_ring_tieoff_dma,
- GFP_KERNEL);
- if (!bp->rx_ring_tieoff)
+ size = ctx->tx_ring_size * sizeof(struct macb_tx_skb);
+ txq->skb = kmalloc(size, GFP_KERNEL);
+ if (!txq->skb)
goto out_err;
}
+ if (ctx->info->macbgem_ops.mog_alloc_rx_buffers(ctx))
+ goto out_err;
return 0;
out_err:
- macb_free_consistent(bp);
+ macb_free(ctx);
return -ENOMEM;
}
-static void macb_init_tieoff(struct macb *bp)
+static struct macb_context *macb_context_alloc(struct macb *bp,
+ unsigned int mtu,
+ unsigned int rx_ring_size,
+ unsigned int tx_ring_size)
{
- struct macb_dma_desc *desc = bp->rx_ring_tieoff;
+ struct macb_context *ctx;
+ int err;
- if (bp->caps & MACB_CAPS_QUEUE_DISABLE)
- return;
- /* Setup a wrapping descriptor with no free slots
- * (WRAP and USED) to tie off/disable unused RX queues.
- */
- macb_set_addr(bp, desc, MACB_BIT(RX_WRAP) | MACB_BIT(RX_USED));
- desc->ctrl = 0;
+ ctx = kzalloc_obj(*ctx);
+ if (!ctx)
+ return ERR_PTR(-ENOMEM);
+
+ ctx->info = &bp->info;
+ ctx->rx_buffer_size = macb_rx_buffer_size(bp, mtu);
+ ctx->rx_ring_size = rx_ring_size;
+ ctx->tx_ring_size = tx_ring_size;
+
+ err = macb_alloc(ctx);
+ if (err) {
+ netdev_err(bp->netdev,
+ "Unable to allocate DMA memory (error %d)\n", err);
+ kfree(ctx);
+ return ERR_PTR(err);
+ }
+
+ bp->macbgem_ops.mog_init_rings(ctx);
+
+ return ctx;
}
-static void gem_init_rx_ring(struct macb_queue *queue)
+static void gem_init_rx_ring(struct macb_context *ctx, unsigned int q)
{
- queue->rx_tail = 0;
- queue->rx_prepared_head = 0;
+ struct macb_rxq *rxq = &ctx->rxq[q];
- gem_rx_refill(queue);
+ rxq->tail = 0;
+ rxq->prepared_head = 0;
+
+ gem_rx_refill(ctx, q);
}
-static void gem_init_rings(struct macb *bp)
+static void gem_init_rings(struct macb_context *ctx)
{
- struct macb_queue *queue;
struct macb_dma_desc *desc = NULL;
+ struct macb_txq *txq;
unsigned int q;
int i;
- for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
- for (i = 0; i < bp->tx_ring_size; i++) {
- desc = macb_tx_desc(queue, i);
- macb_set_addr(bp, desc, 0);
+ for (q = 0; q < ctx->info->num_queues; ++q) {
+ txq = &ctx->txq[q];
+ for (i = 0; i < ctx->tx_ring_size; i++) {
+ desc = macb_tx_desc(ctx, q, i);
+ macb_set_addr(ctx->info, desc, 0);
desc->ctrl = MACB_BIT(TX_USED);
}
desc->ctrl |= MACB_BIT(TX_WRAP);
- queue->tx_head = 0;
- queue->tx_tail = 0;
+ txq->head = 0;
+ txq->tail = 0;
- gem_init_rx_ring(queue);
+ gem_init_rx_ring(ctx, q);
}
-
- macb_init_tieoff(bp);
}
-static void macb_init_rings(struct macb *bp)
+static void macb_init_rings(struct macb_context *ctx)
{
- int i;
+ struct macb_txq *txq = &ctx->txq[0];
struct macb_dma_desc *desc = NULL;
+ int i;
- macb_init_rx_ring(&bp->queues[0]);
+ macb_init_rx_ring(ctx, 0);
- for (i = 0; i < bp->tx_ring_size; i++) {
- desc = macb_tx_desc(&bp->queues[0], i);
- macb_set_addr(bp, desc, 0);
+ for (i = 0; i < ctx->tx_ring_size; i++) {
+ desc = macb_tx_desc(ctx, 0, i);
+ macb_set_addr(ctx->info, desc, 0);
desc->ctrl = MACB_BIT(TX_USED);
}
- bp->queues[0].tx_head = 0;
- bp->queues[0].tx_tail = 0;
+ txq->head = 0;
+ txq->tail = 0;
desc->ctrl |= MACB_BIT(TX_WRAP);
-
- macb_init_tieoff(bp);
}
static void macb_reset_hw(struct macb *bp)
@@ -2897,7 +3015,7 @@ static u32 macb_mdc_clk_div(struct macb *bp)
u32 config;
unsigned long pclk_hz;
- if (macb_is_gem(bp))
+ if (macb_is_gem(&bp->info))
return gem_mdc_clk_div(bp);
pclk_hz = clk_get_rate(bp->pclk);
@@ -2919,7 +3037,7 @@ static u32 macb_mdc_clk_div(struct macb *bp)
*/
static u32 macb_dbw(struct macb *bp)
{
- if (!macb_is_gem(bp))
+ if (!macb_is_gem(&bp->info))
return 0;
switch (GEM_BFEXT(DBWDEF, gem_readl(bp, DCFG1))) {
@@ -2947,8 +3065,8 @@ static void macb_configure_dma(struct macb *bp)
unsigned int q;
u32 dmacfg;
- buffer_size = bp->rx_buffer_size / RX_BUFFER_MULTIPLE;
- if (macb_is_gem(bp)) {
+ buffer_size = bp->ctx->rx_buffer_size / RX_BUFFER_MULTIPLE;
+ if (macb_is_gem(&bp->info)) {
dmacfg = gem_readl(bp, DMACFG) & ~GEM_BF(RXBS, -1L);
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
if (q)
@@ -2966,22 +3084,123 @@ static void macb_configure_dma(struct macb *bp)
else
dmacfg |= GEM_BIT(ENDIA_DESC); /* CPU in big endian */
- if (bp->dev->features & NETIF_F_HW_CSUM)
+ if (bp->netdev->features & NETIF_F_HW_CSUM)
dmacfg |= GEM_BIT(TXCOEN);
else
dmacfg &= ~GEM_BIT(TXCOEN);
dmacfg &= ~GEM_BIT(ADDR64);
- if (macb_dma64(bp))
+ if (macb_dma64(&bp->info))
dmacfg |= GEM_BIT(ADDR64);
- if (macb_dma_ptp(bp))
+ if (macb_dma_ptp(&bp->info))
dmacfg |= GEM_BIT(RXEXT) | GEM_BIT(TXEXT);
- netdev_dbg(bp->dev, "Cadence configure DMA with 0x%08x\n",
+ netdev_dbg(bp->netdev, "Cadence configure DMA with 0x%08x\n",
dmacfg);
gem_writel(bp, DMACFG, dmacfg);
}
}
+static void macb_context_swap_start(struct macb *bp)
+{
+ struct macb_queue *queue;
+ unsigned long flags;
+ unsigned int q;
+ u32 ctrl;
+
+ mutex_lock(&bp->mac_cfg_lock);
+
+ /* Mask interrupts before disabling BH features. */
+ spin_lock_irqsave(&bp->lock, flags);
+ for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
+ queue_writel(queue, IDR, -1);
+ queue_readl(queue, ISR);
+ macb_queue_isr_clear(bp, queue, -1);
+ }
+ spin_unlock_irqrestore(&bp->lock, flags);
+
+ /* Drain BH features. HW is still active and usable at this point. */
+
+ cancel_work_sync(&bp->hresp_err_bh_work);
+ cancel_delayed_work_sync(&bp->tx_lpi_work);
+
+ for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
+ napi_disable(&queue->napi_rx);
+ napi_disable(&queue->napi_tx);
+ cancel_work_sync(&queue->tx_error_task);
+ netdev_tx_reset_queue(netdev_get_tx_queue(bp->netdev, q));
+ }
+
+ /* Can finally disable software Tx; need to wait until napi_tx and
+ * tx_error_task cannot be scheduled as either might wakeup Tx.
+ */
+ netif_tx_disable(bp->netdev);
+
+ spin_lock_irqsave(&bp->lock, flags);
+
+ /* Whether it fails or not we'll disable TE/RE next.
+ * We were just trying to be nice.
+ */
+ macb_halt_tx(bp);
+
+ ctrl = macb_readl(bp, NCR);
+ macb_writel(bp, NCR, ctrl & ~(MACB_BIT(RE) | MACB_BIT(TE)));
+
+ macb_writel(bp, TSR, -1);
+ macb_writel(bp, RSR, -1);
+
+ spin_unlock_irqrestore(&bp->lock, flags);
+}
+
+static void macb_context_swap_end(struct macb *bp,
+ struct macb_context *new_ctx)
+{
+ struct macb_context *old_ctx;
+ struct macb_queue *queue;
+ unsigned long flags;
+ unsigned int q;
+ u32 ctrl;
+
+ lockdep_assert_held(&bp->mac_cfg_lock);
+
+ /* Swap contexts & give buffer pointers to HW. */
+
+ old_ctx = bp->ctx;
+ bp->ctx = new_ctx;
+ macb_init_buffers(bp);
+
+ /* Start NAPI, HW Tx/Rx and software Tx. */
+
+ for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
+ napi_enable(&queue->napi_rx);
+ napi_enable(&queue->napi_tx);
+ }
+
+ spin_lock_irqsave(&bp->lock, flags);
+
+ macb_configure_dma(bp);
+
+ for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
+ queue_writel(queue, IER,
+ bp->rx_intr_mask |
+ MACB_TX_INT_FLAGS |
+ MACB_BIT(HRESP));
+ }
+
+ ctrl = macb_readl(bp, NCR);
+ macb_writel(bp, NCR, ctrl | MACB_BIT(RE) | MACB_BIT(TE));
+
+ spin_unlock_irqrestore(&bp->lock, flags);
+
+ mutex_unlock(&bp->mac_cfg_lock);
+
+ netif_tx_start_all_queues(bp->netdev);
+
+ /* Free old context. */
+
+ macb_free(old_ctx);
+ kfree(old_ctx);
+}
+
static void macb_init_hw(struct macb *bp)
{
u32 config;
@@ -3000,11 +3219,11 @@ static void macb_init_hw(struct macb *bp)
config |= MACB_BIT(JFRAME); /* Enable jumbo frames */
else
config |= MACB_BIT(BIG); /* Receive oversized frames */
- if (bp->dev->flags & IFF_PROMISC)
+ if (bp->netdev->flags & IFF_PROMISC)
config |= MACB_BIT(CAF); /* Copy All Frames */
- else if (macb_is_gem(bp) && bp->dev->features & NETIF_F_RXCSUM)
+ else if (macb_is_gem(&bp->info) && bp->netdev->features & NETIF_F_RXCSUM)
config |= GEM_BIT(RXCOEN);
- if (!(bp->dev->flags & IFF_BROADCAST))
+ if (!(bp->netdev->flags & IFF_BROADCAST))
config |= MACB_BIT(NBC); /* No BroadCast */
config |= macb_dbw(bp);
macb_writel(bp, NCFGR, config);
@@ -3078,17 +3297,17 @@ static int hash_get_index(__u8 *addr)
}
/* Add multicast addresses to the internal multicast-hash table. */
-static void macb_sethashtable(struct net_device *dev)
+static void macb_sethashtable(struct net_device *netdev)
{
struct netdev_hw_addr *ha;
unsigned long mc_filter[2];
unsigned int bitnr;
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
mc_filter[0] = 0;
mc_filter[1] = 0;
- netdev_for_each_mc_addr(ha, dev) {
+ netdev_for_each_mc_addr(ha, netdev) {
bitnr = hash_get_index(ha->addr);
mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
}
@@ -3098,39 +3317,39 @@ static void macb_sethashtable(struct net_device *dev)
}
/* Enable/Disable promiscuous and multicast modes. */
-static void macb_set_rx_mode(struct net_device *dev)
+static void macb_set_rx_mode(struct net_device *netdev)
{
unsigned long cfg;
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
cfg = macb_readl(bp, NCFGR);
- if (dev->flags & IFF_PROMISC) {
+ if (netdev->flags & IFF_PROMISC) {
/* Enable promiscuous mode */
cfg |= MACB_BIT(CAF);
/* Disable RX checksum offload */
- if (macb_is_gem(bp))
+ if (macb_is_gem(&bp->info))
cfg &= ~GEM_BIT(RXCOEN);
} else {
/* Disable promiscuous mode */
cfg &= ~MACB_BIT(CAF);
/* Enable RX checksum offload only if requested */
- if (macb_is_gem(bp) && dev->features & NETIF_F_RXCSUM)
+ if (macb_is_gem(&bp->info) && netdev->features & NETIF_F_RXCSUM)
cfg |= GEM_BIT(RXCOEN);
}
- if (dev->flags & IFF_ALLMULTI) {
+ if (netdev->flags & IFF_ALLMULTI) {
/* Enable all multicast mode */
macb_or_gem_writel(bp, HRB, -1);
macb_or_gem_writel(bp, HRT, -1);
cfg |= MACB_BIT(NCFGR_MTI);
- } else if (!netdev_mc_empty(dev)) {
+ } else if (!netdev_mc_empty(netdev)) {
/* Enable specific multicasts */
- macb_sethashtable(dev);
+ macb_sethashtable(netdev);
cfg |= MACB_BIT(NCFGR_MTI);
- } else if (dev->flags & (~IFF_ALLMULTI)) {
+ } else if (netdev->flags & (~IFF_ALLMULTI)) {
/* Disable all multicast mode */
macb_or_gem_writel(bp, HRB, 0);
macb_or_gem_writel(bp, HRT, 0);
@@ -3140,31 +3359,28 @@ static void macb_set_rx_mode(struct net_device *dev)
macb_writel(bp, NCFGR, cfg);
}
-static int macb_open(struct net_device *dev)
+static int macb_open(struct net_device *netdev)
{
- size_t bufsz = dev->mtu + ETH_HLEN + ETH_FCS_LEN + NET_IP_ALIGN;
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_queue *queue;
unsigned int q;
int err;
- netdev_dbg(bp->dev, "open\n");
+ netdev_dbg(bp->netdev, "open\n");
err = pm_runtime_resume_and_get(&bp->pdev->dev);
if (err < 0)
return err;
- /* RX buffers initialization */
- macb_init_rx_buffer_size(bp, bufsz);
-
- err = macb_alloc_consistent(bp);
- if (err) {
- netdev_err(dev, "Unable to allocate DMA memory (error %d)\n",
- err);
+ bp->ctx = macb_context_alloc(bp, netdev->mtu,
+ bp->configured_rx_ring_size,
+ bp->configured_tx_ring_size);
+ if (IS_ERR(bp->ctx)) {
+ err = PTR_ERR(bp->ctx);
+ bp->ctx = NULL;
goto pm_exit;
}
- bp->macbgem_ops.mog_init_rings(bp);
macb_init_buffers(bp);
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
@@ -3186,10 +3402,10 @@ static int macb_open(struct net_device *dev)
if (err)
goto phy_off;
- netif_tx_start_all_queues(dev);
+ netif_tx_start_all_queues(netdev);
if (bp->ptp_info)
- bp->ptp_info->ptp_init(dev);
+ bp->ptp_info->ptp_init(netdev);
return 0;
@@ -3202,25 +3418,27 @@ static int macb_open(struct net_device *dev)
napi_disable(&queue->napi_rx);
napi_disable(&queue->napi_tx);
}
- macb_free_consistent(bp);
+ macb_free(bp->ctx);
+ kfree(bp->ctx);
+ bp->ctx = NULL;
pm_exit:
pm_runtime_put_sync(&bp->pdev->dev);
return err;
}
-static int macb_close(struct net_device *dev)
+static int macb_close(struct net_device *netdev)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_queue *queue;
unsigned long flags;
unsigned int q;
- netif_tx_stop_all_queues(dev);
+ netif_tx_stop_all_queues(netdev);
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
napi_disable(&queue->napi_rx);
napi_disable(&queue->napi_tx);
- netdev_tx_reset_queue(netdev_get_tx_queue(dev, q));
+ netdev_tx_reset_queue(netdev_get_tx_queue(netdev, q));
}
cancel_delayed_work_sync(&bp->tx_lpi_work);
@@ -3232,38 +3450,58 @@ static int macb_close(struct net_device *dev)
spin_lock_irqsave(&bp->lock, flags);
macb_reset_hw(bp);
- netif_carrier_off(dev);
+ netif_carrier_off(netdev);
spin_unlock_irqrestore(&bp->lock, flags);
- macb_free_consistent(bp);
+ macb_free(bp->ctx);
+ kfree(bp->ctx);
+ bp->ctx = NULL;
if (bp->ptp_info)
- bp->ptp_info->ptp_remove(dev);
+ bp->ptp_info->ptp_remove(netdev);
pm_runtime_put(&bp->pdev->dev);
return 0;
}
-static int macb_change_mtu(struct net_device *dev, int new_mtu)
+static int macb_change_mtu(struct net_device *netdev, int new_mtu)
{
- if (netif_running(dev))
- return -EBUSY;
+ struct macb *bp = netdev_priv(netdev);
+ bool running = netif_running(netdev);
+ struct macb_context *new_ctx;
+
+ if (running) {
+ /* Context swapping is not supported for AT91. */
+ if (bp->caps & MACB_CAPS_MACB_IS_EMAC)
+ return -EBUSY;
+
+ new_ctx = macb_context_alloc(bp, new_mtu,
+ bp->configured_rx_ring_size,
+ bp->configured_tx_ring_size);
+ if (IS_ERR(new_ctx))
+ return PTR_ERR(new_ctx);
+
+ macb_context_swap_start(bp);
+ }
+
+ WRITE_ONCE(netdev->mtu, new_mtu);
- WRITE_ONCE(dev->mtu, new_mtu);
+ if (running)
+ macb_context_swap_end(bp, new_ctx);
return 0;
}
-static int macb_set_mac_addr(struct net_device *dev, void *addr)
+static int macb_set_mac_addr(struct net_device *netdev, void *addr)
{
int err;
- err = eth_mac_addr(dev, addr);
+ err = eth_mac_addr(netdev, addr);
if (err < 0)
return err;
- macb_set_hwaddr(netdev_priv(dev));
+ macb_set_hwaddr(netdev_priv(netdev));
return 0;
}
@@ -3301,7 +3539,7 @@ static void gem_get_stats(struct macb *bp, struct rtnl_link_stats64 *nstat)
struct gem_stats *hwstat = &bp->hw_stats.gem;
spin_lock_irq(&bp->stats_lock);
- if (netif_running(bp->dev))
+ if (netif_running(bp->netdev))
gem_update_stats(bp);
nstat->rx_errors = (hwstat->rx_frame_check_sequence_errors +
@@ -3334,10 +3572,10 @@ static void gem_get_stats(struct macb *bp, struct rtnl_link_stats64 *nstat)
spin_unlock_irq(&bp->stats_lock);
}
-static void gem_get_ethtool_stats(struct net_device *dev,
+static void gem_get_ethtool_stats(struct net_device *netdev,
struct ethtool_stats *stats, u64 *data)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
spin_lock_irq(&bp->stats_lock);
gem_update_stats(bp);
@@ -3346,9 +3584,9 @@ static void gem_get_ethtool_stats(struct net_device *dev,
spin_unlock_irq(&bp->stats_lock);
}
-static int gem_get_sset_count(struct net_device *dev, int sset)
+static int gem_get_sset_count(struct net_device *netdev, int sset)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
switch (sset) {
case ETH_SS_STATS:
@@ -3358,9 +3596,9 @@ static int gem_get_sset_count(struct net_device *dev, int sset)
}
}
-static void gem_get_ethtool_strings(struct net_device *dev, u32 sset, u8 *p)
+static void gem_get_ethtool_strings(struct net_device *netdev, u32 sset, u8 *p)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_queue *queue;
unsigned int i;
unsigned int q;
@@ -3379,14 +3617,14 @@ static void gem_get_ethtool_strings(struct net_device *dev, u32 sset, u8 *p)
}
}
-static void macb_get_stats(struct net_device *dev,
+static void macb_get_stats(struct net_device *netdev,
struct rtnl_link_stats64 *nstat)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_stats *hwstat = &bp->hw_stats.macb;
- netdev_stats_to_stats64(nstat, &bp->dev->stats);
- if (macb_is_gem(bp)) {
+ netdev_stats_to_stats64(nstat, &bp->netdev->stats);
+ if (macb_is_gem(&bp->info)) {
gem_get_stats(bp, nstat);
return;
}
@@ -3429,10 +3667,10 @@ static void macb_get_stats(struct net_device *dev,
spin_unlock_irq(&bp->stats_lock);
}
-static void macb_get_pause_stats(struct net_device *dev,
+static void macb_get_pause_stats(struct net_device *netdev,
struct ethtool_pause_stats *pause_stats)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_stats *hwstat = &bp->hw_stats.macb;
spin_lock_irq(&bp->stats_lock);
@@ -3442,10 +3680,10 @@ static void macb_get_pause_stats(struct net_device *dev,
spin_unlock_irq(&bp->stats_lock);
}
-static void gem_get_pause_stats(struct net_device *dev,
+static void gem_get_pause_stats(struct net_device *netdev,
struct ethtool_pause_stats *pause_stats)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct gem_stats *hwstat = &bp->hw_stats.gem;
spin_lock_irq(&bp->stats_lock);
@@ -3455,10 +3693,10 @@ static void gem_get_pause_stats(struct net_device *dev,
spin_unlock_irq(&bp->stats_lock);
}
-static void macb_get_eth_mac_stats(struct net_device *dev,
+static void macb_get_eth_mac_stats(struct net_device *netdev,
struct ethtool_eth_mac_stats *mac_stats)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_stats *hwstat = &bp->hw_stats.macb;
spin_lock_irq(&bp->stats_lock);
@@ -3480,10 +3718,10 @@ static void macb_get_eth_mac_stats(struct net_device *dev,
spin_unlock_irq(&bp->stats_lock);
}
-static void gem_get_eth_mac_stats(struct net_device *dev,
+static void gem_get_eth_mac_stats(struct net_device *netdev,
struct ethtool_eth_mac_stats *mac_stats)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct gem_stats *hwstat = &bp->hw_stats.gem;
spin_lock_irq(&bp->stats_lock);
@@ -3513,10 +3751,10 @@ static void gem_get_eth_mac_stats(struct net_device *dev,
}
/* TODO: Report SQE test errors when added to phy_stats */
-static void macb_get_eth_phy_stats(struct net_device *dev,
+static void macb_get_eth_phy_stats(struct net_device *netdev,
struct ethtool_eth_phy_stats *phy_stats)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_stats *hwstat = &bp->hw_stats.macb;
spin_lock_irq(&bp->stats_lock);
@@ -3525,10 +3763,10 @@ static void macb_get_eth_phy_stats(struct net_device *dev,
spin_unlock_irq(&bp->stats_lock);
}
-static void gem_get_eth_phy_stats(struct net_device *dev,
+static void gem_get_eth_phy_stats(struct net_device *netdev,
struct ethtool_eth_phy_stats *phy_stats)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct gem_stats *hwstat = &bp->hw_stats.gem;
spin_lock_irq(&bp->stats_lock);
@@ -3537,11 +3775,11 @@ static void gem_get_eth_phy_stats(struct net_device *dev,
spin_unlock_irq(&bp->stats_lock);
}
-static void macb_get_rmon_stats(struct net_device *dev,
+static void macb_get_rmon_stats(struct net_device *netdev,
struct ethtool_rmon_stats *rmon_stats,
const struct ethtool_rmon_hist_range **ranges)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_stats *hwstat = &bp->hw_stats.macb;
spin_lock_irq(&bp->stats_lock);
@@ -3563,11 +3801,11 @@ static const struct ethtool_rmon_hist_range gem_rmon_ranges[] = {
{ },
};
-static void gem_get_rmon_stats(struct net_device *dev,
+static void gem_get_rmon_stats(struct net_device *netdev,
struct ethtool_rmon_stats *rmon_stats,
const struct ethtool_rmon_hist_range **ranges)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct gem_stats *hwstat = &bp->hw_stats.gem;
spin_lock_irq(&bp->stats_lock);
@@ -3598,18 +3836,25 @@ static int macb_get_regs_len(struct net_device *netdev)
return MACB_GREGS_NBR * sizeof(u32);
}
-static void macb_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+static void macb_get_regs(struct net_device *netdev, struct ethtool_regs *regs,
void *p)
{
- struct macb *bp = netdev_priv(dev);
- unsigned int tail, head;
+ dma_addr_t tx_dma_tail = 0, tx_dma_head = 0;
+ struct macb *bp = netdev_priv(netdev);
+ unsigned int tail = 0, head = 0;
+ struct macb_txq *txq;
u32 *regs_buff = p;
regs->version = (macb_readl(bp, MID) & ((1 << MACB_REV_SIZE) - 1))
| MACB_GREGS_VERSION;
- tail = macb_tx_ring_wrap(bp, bp->queues[0].tx_tail);
- head = macb_tx_ring_wrap(bp, bp->queues[0].tx_head);
+ if (bp->ctx) {
+ txq = &bp->ctx->txq[0];
+ tail = macb_tx_ring_wrap(bp->ctx, txq->tail);
+ head = macb_tx_ring_wrap(bp->ctx, txq->head);
+ tx_dma_tail = macb_tx_dma(&bp->queues[0], tail);
+ tx_dma_head = macb_tx_dma(&bp->queues[0], head);
+ }
regs_buff[0] = macb_readl(bp, NCR);
regs_buff[1] = macb_or_gem_readl(bp, NCFGR);
@@ -3622,12 +3867,12 @@ static void macb_get_regs(struct net_device *dev, struct ethtool_regs *regs,
regs_buff[8] = tail;
regs_buff[9] = head;
- regs_buff[10] = macb_tx_dma(&bp->queues[0], tail);
- regs_buff[11] = macb_tx_dma(&bp->queues[0], head);
+ regs_buff[10] = tx_dma_tail;
+ regs_buff[11] = tx_dma_head;
if (!(bp->caps & MACB_CAPS_USRIO_DISABLED))
regs_buff[12] = macb_or_gem_readl(bp, USRIO);
- if (macb_is_gem(bp))
+ if (macb_is_gem(&bp->info))
regs_buff[13] = gem_readl(bp, DMACFG);
}
@@ -3688,8 +3933,8 @@ static void macb_get_ringparam(struct net_device *netdev,
ring->rx_max_pending = MAX_RX_RING_SIZE;
ring->tx_max_pending = MAX_TX_RING_SIZE;
- ring->rx_pending = bp->rx_ring_size;
- ring->tx_pending = bp->tx_ring_size;
+ ring->rx_pending = bp->configured_rx_ring_size;
+ ring->tx_pending = bp->configured_tx_ring_size;
}
static int macb_set_ringparam(struct net_device *netdev,
@@ -3697,9 +3942,10 @@ static int macb_set_ringparam(struct net_device *netdev,
struct kernel_ethtool_ringparam *kernel_ring,
struct netlink_ext_ack *extack)
{
+ unsigned int new_rx_size, new_tx_size;
struct macb *bp = netdev_priv(netdev);
- u32 new_rx_size, new_tx_size;
- unsigned int reset = 0;
+ bool running = netif_running(netdev);
+ struct macb_context *new_ctx;
if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
return -EINVAL;
@@ -3712,22 +3958,30 @@ static int macb_set_ringparam(struct net_device *netdev,
MIN_TX_RING_SIZE, MAX_TX_RING_SIZE);
new_tx_size = roundup_pow_of_two(new_tx_size);
- if ((new_tx_size == bp->tx_ring_size) &&
- (new_rx_size == bp->rx_ring_size)) {
+ if (new_tx_size == bp->configured_tx_ring_size &&
+ new_rx_size == bp->configured_rx_ring_size) {
/* nothing to do */
return 0;
}
- if (netif_running(bp->dev)) {
- reset = 1;
- macb_close(bp->dev);
+ if (running) {
+ /* Context swapping is not supported for AT91. */
+ if (bp->caps & MACB_CAPS_MACB_IS_EMAC)
+ return -EBUSY;
+
+ new_ctx = macb_context_alloc(bp, netdev->mtu,
+ new_rx_size, new_tx_size);
+ if (IS_ERR(new_ctx))
+ return PTR_ERR(new_ctx);
+
+ macb_context_swap_start(bp);
}
- bp->rx_ring_size = new_rx_size;
- bp->tx_ring_size = new_tx_size;
+ bp->configured_rx_ring_size = new_rx_size;
+ bp->configured_tx_ring_size = new_tx_size;
- if (reset)
- macb_open(bp->dev);
+ if (running)
+ macb_context_swap_end(bp, new_ctx);
return 0;
}
@@ -3754,13 +4008,13 @@ static s32 gem_get_ptp_max_adj(void)
return 64000000;
}
-static int gem_get_ts_info(struct net_device *dev,
+static int gem_get_ts_info(struct net_device *netdev,
struct kernel_ethtool_ts_info *info)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
- if (!macb_dma_ptp(bp)) {
- ethtool_op_get_ts_info(dev, info);
+ if (!macb_dma_ptp(&bp->info)) {
+ ethtool_op_get_ts_info(netdev, info);
return 0;
}
@@ -3807,7 +4061,7 @@ static int macb_get_ts_info(struct net_device *netdev,
static void gem_enable_flow_filters(struct macb *bp, bool enable)
{
- struct net_device *netdev = bp->dev;
+ struct net_device *netdev = bp->netdev;
struct ethtool_rx_fs_item *item;
u32 t2_scr;
int num_t2_scr;
@@ -3860,7 +4114,7 @@ static void gem_prog_cmp_regs(struct macb *bp, struct ethtool_rx_flow_spec *fs)
bool cmp_b = false;
bool cmp_c = false;
- if (!macb_is_gem(bp))
+ if (!macb_is_gem(&bp->info))
return;
tp4sp_v = &(fs->h_u.tcp_ip4_spec);
@@ -4137,16 +4391,16 @@ static const struct ethtool_ops macb_ethtool_ops = {
.set_ringparam = macb_set_ringparam,
};
-static int macb_get_eee(struct net_device *dev, struct ethtool_keee *eee)
+static int macb_get_eee(struct net_device *netdev, struct ethtool_keee *eee)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
return phylink_ethtool_get_eee(bp->phylink, eee);
}
-static int macb_set_eee(struct net_device *dev, struct ethtool_keee *eee)
+static int macb_set_eee(struct net_device *netdev, struct ethtool_keee *eee)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
return phylink_ethtool_set_eee(bp->phylink, eee);
}
@@ -4177,43 +4431,43 @@ static const struct ethtool_ops gem_ethtool_ops = {
.set_eee = macb_set_eee,
};
-static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static int macb_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
- if (!netif_running(dev))
+ if (!netif_running(netdev))
return -EINVAL;
return phylink_mii_ioctl(bp->phylink, rq, cmd);
}
-static int macb_hwtstamp_get(struct net_device *dev,
+static int macb_hwtstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *cfg)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
- if (!netif_running(dev))
+ if (!netif_running(netdev))
return -EINVAL;
if (!bp->ptp_info)
return -EOPNOTSUPP;
- return bp->ptp_info->get_hwtst(dev, cfg);
+ return bp->ptp_info->get_hwtst(netdev, cfg);
}
-static int macb_hwtstamp_set(struct net_device *dev,
+static int macb_hwtstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *cfg,
struct netlink_ext_ack *extack)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
- if (!netif_running(dev))
+ if (!netif_running(netdev))
return -EINVAL;
if (!bp->ptp_info)
return -EOPNOTSUPP;
- return bp->ptp_info->set_hwtst(dev, cfg, extack);
+ return bp->ptp_info->set_hwtst(netdev, cfg, extack);
}
static inline void macb_set_txcsum_feature(struct macb *bp,
@@ -4221,7 +4475,7 @@ static inline void macb_set_txcsum_feature(struct macb *bp,
{
u32 val;
- if (!macb_is_gem(bp))
+ if (!macb_is_gem(&bp->info))
return;
val = gem_readl(bp, DMACFG);
@@ -4236,10 +4490,10 @@ static inline void macb_set_txcsum_feature(struct macb *bp,
static inline void macb_set_rxcsum_feature(struct macb *bp,
netdev_features_t features)
{
- struct net_device *netdev = bp->dev;
+ struct net_device *netdev = bp->netdev;
u32 val;
- if (!macb_is_gem(bp))
+ if (!macb_is_gem(&bp->info))
return;
val = gem_readl(bp, NCFGR);
@@ -4254,7 +4508,7 @@ static inline void macb_set_rxcsum_feature(struct macb *bp,
static inline void macb_set_rxflow_feature(struct macb *bp,
netdev_features_t features)
{
- if (!macb_is_gem(bp))
+ if (!macb_is_gem(&bp->info))
return;
gem_enable_flow_filters(bp, !!(features & NETIF_F_NTUPLE));
@@ -4283,7 +4537,7 @@ static int macb_set_features(struct net_device *netdev,
static void macb_restore_features(struct macb *bp)
{
- struct net_device *netdev = bp->dev;
+ struct net_device *netdev = bp->netdev;
netdev_features_t features = netdev->features;
struct ethtool_rx_fs_item *item;
@@ -4300,14 +4554,14 @@ static void macb_restore_features(struct macb *bp)
macb_set_rxflow_feature(bp, features);
}
-static int macb_taprio_setup_replace(struct net_device *ndev,
+static int macb_taprio_setup_replace(struct net_device *netdev,
struct tc_taprio_qopt_offload *conf)
{
u64 total_on_time = 0, start_time_sec = 0, start_time = conf->base_time;
u32 configured_queues = 0, speed = 0, start_time_nsec;
struct macb_queue_enst_config *enst_queue;
struct tc_taprio_sched_entry *entry;
- struct macb *bp = netdev_priv(ndev);
+ struct macb *bp = netdev_priv(netdev);
struct ethtool_link_ksettings kset;
struct macb_queue *queue;
u32 queue_mask;
@@ -4316,13 +4570,13 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
int err;
if (conf->num_entries > bp->num_queues) {
- netdev_err(ndev, "Too many TAPRIO entries: %zu > %d queues\n",
+ netdev_err(netdev, "Too many TAPRIO entries: %zu > %d queues\n",
conf->num_entries, bp->num_queues);
return -EINVAL;
}
if (conf->base_time < 0) {
- netdev_err(ndev, "Invalid base_time: must be 0 or positive, got %lld\n",
+ netdev_err(netdev, "Invalid base_time: must be 0 or positive, got %lld\n",
conf->base_time);
return -ERANGE;
}
@@ -4330,13 +4584,13 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
/* Get the current link speed */
err = phylink_ethtool_ksettings_get(bp->phylink, &kset);
if (unlikely(err)) {
- netdev_err(ndev, "Failed to get link settings: %d\n", err);
+ netdev_err(netdev, "Failed to get link settings: %d\n", err);
return err;
}
speed = kset.base.speed;
if (unlikely(speed <= 0)) {
- netdev_err(ndev, "Invalid speed: %d\n", speed);
+ netdev_err(netdev, "Invalid speed: %d\n", speed);
return -EINVAL;
}
@@ -4349,7 +4603,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
entry = &conf->entries[i];
if (entry->command != TC_TAPRIO_CMD_SET_GATES) {
- netdev_err(ndev, "Entry %zu: unsupported command %d\n",
+ netdev_err(netdev, "Entry %zu: unsupported command %d\n",
i, entry->command);
err = -EOPNOTSUPP;
goto cleanup;
@@ -4357,7 +4611,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
/* Validate gate_mask: must be nonzero, single queue, and within range */
if (!is_power_of_2(entry->gate_mask)) {
- netdev_err(ndev, "Entry %zu: gate_mask 0x%x is not a power of 2 (only one queue per entry allowed)\n",
+ netdev_err(netdev, "Entry %zu: gate_mask 0x%x is not a power of 2 (only one queue per entry allowed)\n",
i, entry->gate_mask);
err = -EINVAL;
goto cleanup;
@@ -4366,7 +4620,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
/* gate_mask must not select queues outside the valid queues */
queue_id = order_base_2(entry->gate_mask);
if (queue_id >= bp->num_queues) {
- netdev_err(ndev, "Entry %zu: gate_mask 0x%x exceeds queue range (max_queues=%d)\n",
+ netdev_err(netdev, "Entry %zu: gate_mask 0x%x exceeds queue range (max_queues=%d)\n",
i, entry->gate_mask, bp->num_queues);
err = -EINVAL;
goto cleanup;
@@ -4376,7 +4630,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
start_time_sec = start_time;
start_time_nsec = do_div(start_time_sec, NSEC_PER_SEC);
if (start_time_sec > GENMASK(GEM_START_TIME_SEC_SIZE - 1, 0)) {
- netdev_err(ndev, "Entry %zu: Start time %llu s exceeds hardware limit\n",
+ netdev_err(netdev, "Entry %zu: Start time %llu s exceeds hardware limit\n",
i, start_time_sec);
err = -ERANGE;
goto cleanup;
@@ -4384,7 +4638,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
/* Check for on time limit */
if (entry->interval > enst_max_hw_interval(speed)) {
- netdev_err(ndev, "Entry %zu: interval %u ns exceeds hardware limit %llu ns\n",
+ netdev_err(netdev, "Entry %zu: interval %u ns exceeds hardware limit %llu ns\n",
i, entry->interval, enst_max_hw_interval(speed));
err = -ERANGE;
goto cleanup;
@@ -4392,7 +4646,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
/* Check for off time limit*/
if ((conf->cycle_time - entry->interval) > enst_max_hw_interval(speed)) {
- netdev_err(ndev, "Entry %zu: off_time %llu ns exceeds hardware limit %llu ns\n",
+ netdev_err(netdev, "Entry %zu: off_time %llu ns exceeds hardware limit %llu ns\n",
i, conf->cycle_time - entry->interval,
enst_max_hw_interval(speed));
err = -ERANGE;
@@ -4415,13 +4669,13 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
/* Check total interval doesn't exceed cycle time */
if (total_on_time > conf->cycle_time) {
- netdev_err(ndev, "Total ON %llu ns exceeds cycle time %llu ns\n",
+ netdev_err(netdev, "Total ON %llu ns exceeds cycle time %llu ns\n",
total_on_time, conf->cycle_time);
err = -EINVAL;
goto cleanup;
}
- netdev_dbg(ndev, "TAPRIO setup: %zu entries, base_time=%lld ns, cycle_time=%llu ns\n",
+ netdev_dbg(netdev, "TAPRIO setup: %zu entries, base_time=%lld ns, cycle_time=%llu ns\n",
conf->num_entries, conf->base_time, conf->cycle_time);
/* All validations passed - proceed with hardware configuration */
@@ -4446,7 +4700,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
gem_writel(bp, ENST_CONTROL, configured_queues);
}
- netdev_info(ndev, "TAPRIO configuration completed successfully: %zu entries, %d queues configured\n",
+ netdev_info(netdev, "TAPRIO configuration completed successfully: %zu entries, %d queues configured\n",
conf->num_entries, hweight32(configured_queues));
cleanup:
@@ -4454,14 +4708,14 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
return err;
}
-static void macb_taprio_destroy(struct net_device *ndev)
+static void macb_taprio_destroy(struct net_device *netdev)
{
- struct macb *bp = netdev_priv(ndev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_queue *queue;
u32 queue_mask;
unsigned int q;
- netdev_reset_tc(ndev);
+ netdev_reset_tc(netdev);
queue_mask = BIT_U32(bp->num_queues) - 1;
scoped_guard(spinlock_irqsave, &bp->lock) {
@@ -4476,30 +4730,30 @@ static void macb_taprio_destroy(struct net_device *ndev)
queue_writel(queue, ENST_OFF_TIME, 0);
}
}
- netdev_info(ndev, "TAPRIO destroy: All gates disabled\n");
+ netdev_info(netdev, "TAPRIO destroy: All gates disabled\n");
}
-static int macb_setup_taprio(struct net_device *ndev,
+static int macb_setup_taprio(struct net_device *netdev,
struct tc_taprio_qopt_offload *taprio)
{
- struct macb *bp = netdev_priv(ndev);
+ struct macb *bp = netdev_priv(netdev);
int err = 0;
- if (unlikely(!(ndev->hw_features & NETIF_F_HW_TC)))
+ if (unlikely(!(netdev->hw_features & NETIF_F_HW_TC)))
return -EOPNOTSUPP;
/* Check if Device is in runtime suspend */
if (unlikely(pm_runtime_suspended(&bp->pdev->dev))) {
- netdev_err(ndev, "Device is in runtime suspend\n");
+ netdev_err(netdev, "Device is in runtime suspend\n");
return -EOPNOTSUPP;
}
switch (taprio->cmd) {
case TAPRIO_CMD_REPLACE:
- err = macb_taprio_setup_replace(ndev, taprio);
+ err = macb_taprio_setup_replace(netdev, taprio);
break;
case TAPRIO_CMD_DESTROY:
- macb_taprio_destroy(ndev);
+ macb_taprio_destroy(netdev);
break;
default:
err = -EOPNOTSUPP;
@@ -4508,23 +4762,23 @@ static int macb_setup_taprio(struct net_device *ndev,
return err;
}
-static int macb_setup_tc(struct net_device *dev, enum tc_setup_type type,
+static int macb_setup_tc(struct net_device *netdev, enum tc_setup_type type,
void *type_data)
{
- if (!dev || !type_data)
+ if (!netdev || !type_data)
return -EINVAL;
switch (type) {
case TC_SETUP_QDISC_TAPRIO:
- return macb_setup_taprio(dev, type_data);
+ return macb_setup_taprio(netdev, type_data);
default:
return -EOPNOTSUPP;
}
}
-static void macb_tx_timeout(struct net_device *dev, unsigned int q)
+static void macb_tx_timeout(struct net_device *netdev, unsigned int q)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
macb_tx_restart(&bp->queues[q]);
}
@@ -4581,7 +4835,7 @@ static void macb_configure_caps(struct macb *bp,
bp->caps |= MACB_CAPS_FIFO_MODE;
if (GEM_BFEXT(PBUF_RSC, gem_readl(bp, DCFG6)))
bp->caps |= MACB_CAPS_RSC;
- if (gem_has_ptp(bp)) {
+ if (gem_has_ptp(&bp->info)) {
if (!GEM_BFEXT(TSU, gem_readl(bp, DCFG5)))
dev_err(&bp->pdev->dev,
"GEM doesn't support hardware ptp.\n");
@@ -4732,16 +4986,13 @@ static int macb_clk_init(struct platform_device *pdev, struct clk **pclk,
static int macb_init_dflt(struct platform_device *pdev)
{
- struct net_device *dev = platform_get_drvdata(pdev);
+ struct net_device *netdev = platform_get_drvdata(pdev);
unsigned int hw_q, q;
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_queue *queue;
int err;
u32 val, reg;
- bp->tx_ring_size = DEFAULT_TX_RING_SIZE;
- bp->rx_ring_size = DEFAULT_RX_RING_SIZE;
-
/* set the queue register mapping once for all: queue0 has a special
* register mapping but we don't want to test the queue index then
* compute the corresponding register offset at run time.
@@ -4750,8 +5001,8 @@ static int macb_init_dflt(struct platform_device *pdev)
queue = &bp->queues[q];
queue->bp = bp;
spin_lock_init(&queue->tx_ptr_lock);
- netif_napi_add(dev, &queue->napi_rx, macb_rx_poll);
- netif_napi_add_tx(dev, &queue->napi_tx, macb_tx_poll);
+ netif_napi_add(netdev, &queue->napi_rx, macb_rx_poll);
+ netif_napi_add_tx(netdev, &queue->napi_tx, macb_tx_poll);
if (hw_q) {
queue->ISR = GEM_ISR(hw_q - 1);
queue->IER = GEM_IER(hw_q - 1);
@@ -4781,7 +5032,7 @@ static int macb_init_dflt(struct platform_device *pdev)
*/
queue->irq = platform_get_irq(pdev, q);
err = devm_request_irq(&pdev->dev, queue->irq, macb_interrupt,
- IRQF_SHARED, dev->name, queue);
+ IRQF_SHARED, netdev->name, queue);
if (err) {
dev_err(&pdev->dev,
"Unable to request IRQ %d (error %d)\n",
@@ -4793,47 +5044,47 @@ static int macb_init_dflt(struct platform_device *pdev)
q++;
}
- dev->netdev_ops = &macb_netdev_ops;
+ netdev->netdev_ops = &macb_netdev_ops;
/* setup appropriated routines according to adapter type */
- if (macb_is_gem(bp)) {
+ if (macb_is_gem(&bp->info)) {
bp->macbgem_ops.mog_alloc_rx_buffers = gem_alloc_rx_buffers;
bp->macbgem_ops.mog_free_rx_buffers = gem_free_rx_buffers;
bp->macbgem_ops.mog_init_rings = gem_init_rings;
bp->macbgem_ops.mog_rx = gem_rx;
- dev->ethtool_ops = &gem_ethtool_ops;
+ netdev->ethtool_ops = &gem_ethtool_ops;
} else {
bp->macbgem_ops.mog_alloc_rx_buffers = macb_alloc_rx_buffers;
bp->macbgem_ops.mog_free_rx_buffers = macb_free_rx_buffers;
bp->macbgem_ops.mog_init_rings = macb_init_rings;
bp->macbgem_ops.mog_rx = macb_rx;
- dev->ethtool_ops = &macb_ethtool_ops;
+ netdev->ethtool_ops = &macb_ethtool_ops;
}
- netdev_sw_irq_coalesce_default_on(dev);
+ netdev_sw_irq_coalesce_default_on(netdev);
- dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
+ netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
/* Set features */
- dev->hw_features = NETIF_F_SG;
+ netdev->hw_features = NETIF_F_SG;
/* Check LSO capability; runtime detection can be overridden by a cap
* flag if the hardware is known to be buggy
*/
if (!(bp->caps & MACB_CAPS_NO_LSO) &&
GEM_BFEXT(PBUF_LSO, gem_readl(bp, DCFG6)))
- dev->hw_features |= MACB_NETIF_LSO;
+ netdev->hw_features |= MACB_NETIF_LSO;
/* Checksum offload is only available on gem with packet buffer */
- if (macb_is_gem(bp) && !(bp->caps & MACB_CAPS_FIFO_MODE))
- dev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
+ if (macb_is_gem(&bp->info) && !(bp->caps & MACB_CAPS_FIFO_MODE))
+ netdev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
if (bp->caps & MACB_CAPS_SG_DISABLED)
- dev->hw_features &= ~NETIF_F_SG;
+ netdev->hw_features &= ~NETIF_F_SG;
/* Enable HW_TC if hardware supports QBV */
if (bp->caps & MACB_CAPS_QBV)
- dev->hw_features |= NETIF_F_HW_TC;
+ netdev->hw_features |= NETIF_F_HW_TC;
- dev->features = dev->hw_features;
+ netdev->features = netdev->hw_features;
/* Check RX Flow Filters support.
* Max Rx flows set by availability of screeners & compare regs:
@@ -4851,7 +5102,7 @@ static int macb_init_dflt(struct platform_device *pdev)
reg = GEM_BFINS(ETHTCMP, (uint16_t)ETH_P_IP, reg);
gem_writel_n(bp, ETHT, SCRT2_ETHT, reg);
/* Filtering is supported in hw but don't enable it in kernel now */
- dev->hw_features |= NETIF_F_NTUPLE;
+ netdev->hw_features |= NETIF_F_NTUPLE;
/* init Rx flow definitions */
bp->rx_fs_list.count = 0;
spin_lock_init(&bp->rx_fs_lock);
@@ -4945,71 +5196,72 @@ static const struct macb_usrio_config at91_default_usrio = {
static struct sifive_fu540_macb_mgmt *mgmt;
-static int at91ether_alloc_coherent(struct macb *lp)
+static int at91ether_alloc_coherent(struct macb *bp)
{
- struct macb_queue *q = &lp->queues[0];
+ struct macb_rxq *rxq = &bp->ctx->rxq[0];
- q->rx_ring = dma_alloc_coherent(&lp->pdev->dev,
- (AT91ETHER_MAX_RX_DESCR *
- macb_dma_desc_get_size(lp)),
- &q->rx_ring_dma, GFP_KERNEL);
- if (!q->rx_ring)
+ rxq->ring = dma_alloc_coherent(&bp->pdev->dev,
+ (AT91ETHER_MAX_RX_DESCR *
+ macb_dma_desc_get_size(&bp->info)),
+ &rxq->ring_dma, GFP_KERNEL);
+ if (!rxq->ring)
return -ENOMEM;
- q->rx_buffers = dma_alloc_coherent(&lp->pdev->dev,
- AT91ETHER_MAX_RX_DESCR *
- AT91ETHER_MAX_RBUFF_SZ,
- &q->rx_buffers_dma, GFP_KERNEL);
- if (!q->rx_buffers) {
- dma_free_coherent(&lp->pdev->dev,
+ rxq->buffers = dma_alloc_coherent(&bp->pdev->dev,
+ AT91ETHER_MAX_RX_DESCR *
+ AT91ETHER_MAX_RBUFF_SZ,
+ &rxq->buffers_dma,
+ GFP_KERNEL);
+ if (!rxq->buffers) {
+ dma_free_coherent(&bp->pdev->dev,
AT91ETHER_MAX_RX_DESCR *
- macb_dma_desc_get_size(lp),
- q->rx_ring, q->rx_ring_dma);
- q->rx_ring = NULL;
+ macb_dma_desc_get_size(&bp->info),
+ rxq->ring, rxq->ring_dma);
+ rxq->ring = NULL;
return -ENOMEM;
}
return 0;
}
-static void at91ether_free_coherent(struct macb *lp)
+static void at91ether_free_coherent(struct macb *bp)
{
- struct macb_queue *q = &lp->queues[0];
+ struct macb_rxq *rxq = &bp->ctx->rxq[0];
- if (q->rx_ring) {
- dma_free_coherent(&lp->pdev->dev,
+ if (rxq->ring) {
+ dma_free_coherent(&bp->pdev->dev,
AT91ETHER_MAX_RX_DESCR *
- macb_dma_desc_get_size(lp),
- q->rx_ring, q->rx_ring_dma);
- q->rx_ring = NULL;
+ macb_dma_desc_get_size(&bp->info),
+ rxq->ring, rxq->ring_dma);
+ rxq->ring = NULL;
}
- if (q->rx_buffers) {
- dma_free_coherent(&lp->pdev->dev,
+ if (rxq->buffers) {
+ dma_free_coherent(&bp->pdev->dev,
AT91ETHER_MAX_RX_DESCR *
AT91ETHER_MAX_RBUFF_SZ,
- q->rx_buffers, q->rx_buffers_dma);
- q->rx_buffers = NULL;
+ rxq->buffers, rxq->buffers_dma);
+ rxq->buffers = NULL;
}
}
/* Initialize and start the Receiver and Transmit subsystems */
-static int at91ether_start(struct macb *lp)
+static int at91ether_start(struct macb *bp)
{
- struct macb_queue *q = &lp->queues[0];
+ struct macb_rxq *rxq = &bp->ctx->rxq[0];
struct macb_dma_desc *desc;
dma_addr_t addr;
u32 ctl;
int i, ret;
- ret = at91ether_alloc_coherent(lp);
+ ret = at91ether_alloc_coherent(bp);
if (ret)
return ret;
- addr = q->rx_buffers_dma;
+ addr = rxq->buffers_dma;
for (i = 0; i < AT91ETHER_MAX_RX_DESCR; i++) {
- desc = macb_rx_desc(q, i);
- macb_set_addr(lp, desc, addr);
+ desc = macb_rx_desc(bp->ctx, 0, i);
+ macb_set_addr(&bp->info, desc, addr);
desc->ctrl = 0;
addr += AT91ETHER_MAX_RBUFF_SZ;
}
@@ -5018,17 +5270,17 @@ static int at91ether_start(struct macb *lp)
desc->addr |= MACB_BIT(RX_WRAP);
/* Reset buffer index */
- q->rx_tail = 0;
+ rxq->tail = 0;
/* Program address of descriptor list in Rx Buffer Queue register */
- macb_writel(lp, RBQP, q->rx_ring_dma);
+ macb_writel(bp, RBQP, rxq->ring_dma);
/* Enable Receive and Transmit */
- ctl = macb_readl(lp, NCR);
- macb_writel(lp, NCR, ctl | MACB_BIT(RE) | MACB_BIT(TE));
+ ctl = macb_readl(bp, NCR);
+ macb_writel(bp, NCR, ctl | MACB_BIT(RE) | MACB_BIT(TE));
/* Enable MAC interrupts */
- macb_writel(lp, IER, MACB_BIT(RCOMP) |
+ macb_writel(bp, IER, MACB_BIT(RCOMP) |
MACB_BIT(RXUBR) |
MACB_BIT(ISR_TUND) |
MACB_BIT(ISR_RLE) |
@@ -5039,12 +5291,12 @@ static int at91ether_start(struct macb *lp)
return 0;
}
-static void at91ether_stop(struct macb *lp)
+static void at91ether_stop(struct macb *bp)
{
u32 ctl;
/* Disable MAC interrupts */
- macb_writel(lp, IDR, MACB_BIT(RCOMP) |
+ macb_writel(bp, IDR, MACB_BIT(RCOMP) |
MACB_BIT(RXUBR) |
MACB_BIT(ISR_TUND) |
MACB_BIT(ISR_RLE) |
@@ -5053,96 +5305,112 @@ static void at91ether_stop(struct macb *lp)
MACB_BIT(HRESP));
/* Disable Receiver and Transmitter */
- ctl = macb_readl(lp, NCR);
- macb_writel(lp, NCR, ctl & ~(MACB_BIT(TE) | MACB_BIT(RE)));
+ ctl = macb_readl(bp, NCR);
+ macb_writel(bp, NCR, ctl & ~(MACB_BIT(TE) | MACB_BIT(RE)));
/* Free resources. */
- at91ether_free_coherent(lp);
+ at91ether_free_coherent(bp);
}
/* Open the ethernet interface */
-static int at91ether_open(struct net_device *dev)
+static int at91ether_open(struct net_device *netdev)
{
- struct macb *lp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
u32 ctl;
int ret;
- ret = pm_runtime_resume_and_get(&lp->pdev->dev);
+ ret = pm_runtime_resume_and_get(&bp->pdev->dev);
if (ret < 0)
return ret;
+ bp->ctx = kzalloc_obj(*bp->ctx);
+ if (!bp->ctx) {
+ ret = -ENOMEM;
+ goto pm_exit;
+ }
+ bp->ctx->info = &bp->info;
+
/* Clear internal statistics */
- ctl = macb_readl(lp, NCR);
- macb_writel(lp, NCR, ctl | MACB_BIT(CLRSTAT));
+ ctl = macb_readl(bp, NCR);
+ macb_writel(bp, NCR, ctl | MACB_BIT(CLRSTAT));
- macb_set_hwaddr(lp);
+ macb_set_hwaddr(bp);
- ret = at91ether_start(lp);
+ ret = at91ether_start(bp);
if (ret)
- goto pm_exit;
+ goto free_ctx;
- ret = macb_phylink_connect(lp);
+ ret = macb_phylink_connect(bp);
if (ret)
goto stop;
- netif_start_queue(dev);
+ netif_start_queue(netdev);
return 0;
stop:
- at91ether_stop(lp);
+ at91ether_stop(bp);
+free_ctx:
+ kfree(bp->ctx);
+ bp->ctx = NULL;
pm_exit:
- pm_runtime_put_sync(&lp->pdev->dev);
+ pm_runtime_put_sync(&bp->pdev->dev);
return ret;
}
/* Close the interface */
-static int at91ether_close(struct net_device *dev)
+static int at91ether_close(struct net_device *netdev)
{
- struct macb *lp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
- netif_stop_queue(dev);
+ netif_stop_queue(netdev);
- phylink_stop(lp->phylink);
- phylink_disconnect_phy(lp->phylink);
+ phylink_stop(bp->phylink);
+ phylink_disconnect_phy(bp->phylink);
- at91ether_stop(lp);
+ at91ether_stop(bp);
- pm_runtime_put(&lp->pdev->dev);
+ kfree(bp->ctx);
+ bp->ctx = NULL;
+
+ pm_runtime_put(&bp->pdev->dev);
return 0;
}
/* Transmit packet */
static netdev_tx_t at91ether_start_xmit(struct sk_buff *skb,
- struct net_device *dev)
+ struct net_device *netdev)
{
- struct macb *lp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
+ struct device *dev = &bp->pdev->dev;
- if (macb_readl(lp, TSR) & MACB_BIT(RM9200_BNQ)) {
+ if (macb_readl(bp, TSR) & MACB_BIT(RM9200_BNQ)) {
int desc = 0;
- netif_stop_queue(dev);
+ netif_stop_queue(netdev);
/* Store packet information (to free when Tx completed) */
- lp->rm9200_txq[desc].skb = skb;
- lp->rm9200_txq[desc].size = skb->len;
- lp->rm9200_txq[desc].mapping = dma_map_single(&lp->pdev->dev, skb->data,
- skb->len, DMA_TO_DEVICE);
- if (dma_mapping_error(&lp->pdev->dev, lp->rm9200_txq[desc].mapping)) {
+ bp->rm9200_txq[desc].skb = skb;
+ bp->rm9200_txq[desc].size = skb->len;
+ bp->rm9200_txq[desc].mapping = dma_map_single(dev, skb->data,
+ skb->len,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(dev, bp->rm9200_txq[desc].mapping)) {
dev_kfree_skb_any(skb);
- dev->stats.tx_dropped++;
- netdev_err(dev, "%s: DMA mapping error\n", __func__);
+ netdev->stats.tx_dropped++;
+ netdev_err(netdev, "%s: DMA mapping error\n", __func__);
return NETDEV_TX_OK;
}
/* Set address of the data in the Transmit Address register */
- macb_writel(lp, TAR, lp->rm9200_txq[desc].mapping);
+ macb_writel(bp, TAR, bp->rm9200_txq[desc].mapping);
/* Set length of the packet in the Transmit Control register */
- macb_writel(lp, TCR, skb->len);
+ macb_writel(bp, TCR, skb->len);
} else {
- netdev_err(dev, "%s called, but device is busy!\n", __func__);
+ netdev_err(netdev, "%s called, but device is busy!\n",
+ __func__);
return NETDEV_TX_BUSY;
}
@@ -5152,104 +5420,106 @@ static netdev_tx_t at91ether_start_xmit(struct sk_buff *skb,
/* Extract received frame from buffer descriptors and sent to upper layers.
* (Called from interrupt context)
*/
-static void at91ether_rx(struct net_device *dev)
+static void at91ether_rx(struct net_device *netdev)
{
- struct macb *lp = netdev_priv(dev);
- struct macb_queue *q = &lp->queues[0];
+ struct macb *bp = netdev_priv(netdev);
+ struct macb_rxq *rxq = &bp->ctx->rxq[0];
struct macb_dma_desc *desc;
unsigned char *p_recv;
struct sk_buff *skb;
unsigned int pktlen;
- desc = macb_rx_desc(q, q->rx_tail);
+ desc = macb_rx_desc(bp->ctx, 0, rxq->tail);
while (desc->addr & MACB_BIT(RX_USED)) {
- p_recv = q->rx_buffers + q->rx_tail * AT91ETHER_MAX_RBUFF_SZ;
+ p_recv = rxq->buffers + rxq->tail * AT91ETHER_MAX_RBUFF_SZ;
pktlen = MACB_BF(RX_FRMLEN, desc->ctrl);
- skb = netdev_alloc_skb(dev, pktlen + 2);
+ skb = netdev_alloc_skb(netdev, pktlen + 2);
if (skb) {
skb_reserve(skb, 2);
skb_put_data(skb, p_recv, pktlen);
- skb->protocol = eth_type_trans(skb, dev);
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pktlen;
+ skb->protocol = eth_type_trans(skb, netdev);
+ netdev->stats.rx_packets++;
+ netdev->stats.rx_bytes += pktlen;
netif_rx(skb);
} else {
- dev->stats.rx_dropped++;
+ netdev->stats.rx_dropped++;
}
if (desc->ctrl & MACB_BIT(RX_MHASH_MATCH))
- dev->stats.multicast++;
+ netdev->stats.multicast++;
/* reset ownership bit */
desc->addr &= ~MACB_BIT(RX_USED);
/* wrap after last buffer */
- if (q->rx_tail == AT91ETHER_MAX_RX_DESCR - 1)
- q->rx_tail = 0;
+ if (rxq->tail == AT91ETHER_MAX_RX_DESCR - 1)
+ rxq->tail = 0;
else
- q->rx_tail++;
+ rxq->tail++;
- desc = macb_rx_desc(q, q->rx_tail);
+ desc = macb_rx_desc(bp->ctx, 0, rxq->tail);
}
}
/* MAC interrupt handler */
static irqreturn_t at91ether_interrupt(int irq, void *dev_id)
{
- struct net_device *dev = dev_id;
- struct macb *lp = netdev_priv(dev);
+ struct net_device *netdev = dev_id;
+ struct macb *bp = netdev_priv(netdev);
u32 intstatus, ctl;
unsigned int desc;
/* MAC Interrupt Status register indicates what interrupts are pending.
* It is automatically cleared once read.
*/
- intstatus = macb_readl(lp, ISR);
+ intstatus = macb_readl(bp, ISR);
/* Receive complete */
if (intstatus & MACB_BIT(RCOMP))
- at91ether_rx(dev);
+ at91ether_rx(netdev);
/* Transmit complete */
if (intstatus & MACB_BIT(TCOMP)) {
/* The TCOM bit is set even if the transmission failed */
if (intstatus & (MACB_BIT(ISR_TUND) | MACB_BIT(ISR_RLE)))
- dev->stats.tx_errors++;
+ netdev->stats.tx_errors++;
desc = 0;
- if (lp->rm9200_txq[desc].skb) {
- dev_consume_skb_irq(lp->rm9200_txq[desc].skb);
- lp->rm9200_txq[desc].skb = NULL;
- dma_unmap_single(&lp->pdev->dev, lp->rm9200_txq[desc].mapping,
- lp->rm9200_txq[desc].size, DMA_TO_DEVICE);
- dev->stats.tx_packets++;
- dev->stats.tx_bytes += lp->rm9200_txq[desc].size;
+ if (bp->rm9200_txq[desc].skb) {
+ dev_consume_skb_irq(bp->rm9200_txq[desc].skb);
+ bp->rm9200_txq[desc].skb = NULL;
+ dma_unmap_single(&bp->pdev->dev,
+ bp->rm9200_txq[desc].mapping,
+ bp->rm9200_txq[desc].size,
+ DMA_TO_DEVICE);
+ netdev->stats.tx_packets++;
+ netdev->stats.tx_bytes += bp->rm9200_txq[desc].size;
}
- netif_wake_queue(dev);
+ netif_wake_queue(netdev);
}
/* Work-around for EMAC Errata section 41.3.1 */
if (intstatus & MACB_BIT(RXUBR)) {
- ctl = macb_readl(lp, NCR);
- macb_writel(lp, NCR, ctl & ~MACB_BIT(RE));
+ ctl = macb_readl(bp, NCR);
+ macb_writel(bp, NCR, ctl & ~MACB_BIT(RE));
wmb();
- macb_writel(lp, NCR, ctl | MACB_BIT(RE));
+ macb_writel(bp, NCR, ctl | MACB_BIT(RE));
}
if (intstatus & MACB_BIT(ISR_ROVR))
- netdev_err(dev, "ROVR error\n");
+ netdev_err(netdev, "ROVR error\n");
return IRQ_HANDLED;
}
#ifdef CONFIG_NET_POLL_CONTROLLER
-static void at91ether_poll_controller(struct net_device *dev)
+static void at91ether_poll_controller(struct net_device *netdev)
{
unsigned long flags;
local_irq_save(flags);
- at91ether_interrupt(dev->irq, dev);
+ at91ether_interrupt(netdev->irq, netdev);
local_irq_restore(flags);
}
#endif
@@ -5296,17 +5566,17 @@ static int at91ether_clk_init(struct platform_device *pdev, struct clk **pclk,
static int at91ether_init(struct platform_device *pdev)
{
- struct net_device *dev = platform_get_drvdata(pdev);
- struct macb *bp = netdev_priv(dev);
+ struct net_device *netdev = platform_get_drvdata(pdev);
+ struct macb *bp = netdev_priv(netdev);
int err;
bp->queues[0].bp = bp;
- dev->netdev_ops = &at91ether_netdev_ops;
- dev->ethtool_ops = &macb_ethtool_ops;
+ netdev->netdev_ops = &at91ether_netdev_ops;
+ netdev->ethtool_ops = &macb_ethtool_ops;
- err = devm_request_irq(&pdev->dev, dev->irq, at91ether_interrupt,
- 0, dev->name, dev);
+ err = devm_request_irq(&pdev->dev, netdev->irq, at91ether_interrupt,
+ 0, netdev->name, netdev);
if (err)
return err;
@@ -5435,8 +5705,8 @@ static int fu540_c000_init(struct platform_device *pdev)
static int init_reset_optional(struct platform_device *pdev)
{
- struct net_device *dev = platform_get_drvdata(pdev);
- struct macb *bp = netdev_priv(dev);
+ struct net_device *netdev = platform_get_drvdata(pdev);
+ struct macb *bp = netdev_priv(netdev);
int ret;
if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII) {
@@ -5511,6 +5781,38 @@ static int eyeq5_init(struct platform_device *pdev)
return ret;
}
+static int macb_alloc_tieoff(struct macb *bp)
+{
+ /* Tieoff is a workaround in case HW cannot disable queues, for PM. */
+ if (bp->caps & MACB_CAPS_QUEUE_DISABLE)
+ return 0;
+
+ bp->rx_ring_tieoff = dma_alloc_coherent(&bp->pdev->dev,
+ macb_dma_desc_get_size(&bp->info),
+ &bp->rx_ring_tieoff_dma,
+ GFP_KERNEL);
+ if (!bp->rx_ring_tieoff)
+ return -ENOMEM;
+
+ macb_set_addr(&bp->info, bp->rx_ring_tieoff,
+ MACB_BIT(RX_WRAP) | MACB_BIT(RX_USED));
+
+ bp->rx_ring_tieoff->ctrl = 0;
+
+ return 0;
+}
+
+static void macb_free_tieoff(struct macb *bp)
+{
+ if (!bp->rx_ring_tieoff)
+ return;
+
+ dma_free_coherent(&bp->pdev->dev, macb_dma_desc_get_size(&bp->info),
+ bp->rx_ring_tieoff,
+ bp->rx_ring_tieoff_dma);
+ bp->rx_ring_tieoff = NULL;
+}
+
static const struct macb_usrio_config mpfs_usrio = {
.tsu_source = 0,
};
@@ -5744,7 +6046,7 @@ static int macb_probe(struct platform_device *pdev)
const struct macb_config *macb_config;
struct clk *tsu_clk = NULL;
phy_interface_t interface;
- struct net_device *dev;
+ struct net_device *netdev;
struct resource *regs;
u32 wtrmrk_rst_val;
void __iomem *mem;
@@ -5779,19 +6081,19 @@ static int macb_probe(struct platform_device *pdev)
goto err_disable_clocks;
}
- dev = alloc_etherdev_mq(sizeof(*bp), num_queues);
- if (!dev) {
+ netdev = alloc_etherdev_mq(sizeof(*bp), num_queues);
+ if (!netdev) {
err = -ENOMEM;
goto err_disable_clocks;
}
- dev->base_addr = regs->start;
+ netdev->base_addr = regs->start;
- SET_NETDEV_DEV(dev, &pdev->dev);
+ SET_NETDEV_DEV(netdev, &pdev->dev);
- bp = netdev_priv(dev);
+ bp = netdev_priv(netdev);
bp->pdev = pdev;
- bp->dev = dev;
+ bp->netdev = netdev;
bp->regs = mem;
bp->native_io = native_io;
if (native_io) {
@@ -5809,6 +6111,8 @@ static int macb_probe(struct platform_device *pdev)
bp->rx_clk = rx_clk;
bp->tsu_clk = tsu_clk;
bp->jumbo_max_len = macb_config->jumbo_max_len;
+ bp->configured_rx_ring_size = DEFAULT_RX_RING_SIZE;
+ bp->configured_tx_ring_size = DEFAULT_TX_RING_SIZE;
if (!hw_is_gem(bp->regs, bp->native_io))
bp->max_tx_length = MACB_MAX_TX_LEN;
@@ -5850,6 +6154,7 @@ static int macb_probe(struct platform_device *pdev)
}
spin_lock_init(&bp->lock);
spin_lock_init(&bp->stats_lock);
+ mutex_init(&bp->mac_cfg_lock);
/* setup capabilities */
macb_configure_caps(bp, macb_config);
@@ -5864,39 +6169,39 @@ static int macb_probe(struct platform_device *pdev)
bp->caps |= MACB_CAPS_DMA_64B;
}
#endif
- platform_set_drvdata(pdev, dev);
+ platform_set_drvdata(pdev, netdev);
- dev->irq = platform_get_irq(pdev, 0);
- if (dev->irq < 0) {
- err = dev->irq;
+ netdev->irq = platform_get_irq(pdev, 0);
+ if (netdev->irq < 0) {
+ err = netdev->irq;
goto err_out_free_netdev;
}
/* MTU range: 68 - 1518 or 10240 */
- dev->min_mtu = GEM_MTU_MIN_SIZE;
+ netdev->min_mtu = GEM_MTU_MIN_SIZE;
if ((bp->caps & MACB_CAPS_JUMBO) && bp->jumbo_max_len)
- dev->max_mtu = MIN(bp->jumbo_max_len, RX_BUFFER_MAX) -
+ netdev->max_mtu = MIN(bp->jumbo_max_len, RX_BUFFER_MAX) -
ETH_HLEN - ETH_FCS_LEN;
else
- dev->max_mtu = 1536 - ETH_HLEN - ETH_FCS_LEN;
+ netdev->max_mtu = 1536 - ETH_HLEN - ETH_FCS_LEN;
if (bp->caps & MACB_CAPS_BD_RD_PREFETCH) {
val = GEM_BFEXT(RXBD_RDBUFF, gem_readl(bp, DCFG10));
if (val)
bp->rx_bd_rd_prefetch = (2 << (val - 1)) *
- macb_dma_desc_get_size(bp);
+ macb_dma_desc_get_size(&bp->info);
val = GEM_BFEXT(TXBD_RDBUFF, gem_readl(bp, DCFG10));
if (val)
bp->tx_bd_rd_prefetch = (2 << (val - 1)) *
- macb_dma_desc_get_size(bp);
+ macb_dma_desc_get_size(&bp->info);
}
bp->rx_intr_mask = MACB_RX_INT_FLAGS;
if (bp->caps & MACB_CAPS_NEEDS_RSTONUBR)
bp->rx_intr_mask |= MACB_BIT(RXUBR);
- err = of_get_ethdev_address(np, bp->dev);
+ err = of_get_ethdev_address(np, bp->netdev);
if (err == -EPROBE_DEFER)
goto err_out_free_netdev;
else if (err)
@@ -5918,25 +6223,33 @@ static int macb_probe(struct platform_device *pdev)
if (err)
goto err_out_phy_exit;
- netif_carrier_off(dev);
+ netif_carrier_off(netdev);
+
+ err = macb_alloc_tieoff(bp);
+ if (err)
+ goto err_out_unregister_mdio;
- err = register_netdev(dev);
+ err = register_netdev(netdev);
if (err) {
dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
- goto err_out_unregister_mdio;
+ goto err_out_free_tieoff;
}
INIT_WORK(&bp->hresp_err_bh_work, macb_hresp_error_task);
INIT_DELAYED_WORK(&bp->tx_lpi_work, macb_tx_lpi_work_fn);
- netdev_info(dev, "Cadence %s rev 0x%08x at 0x%08lx irq %d (%pM)\n",
- macb_is_gem(bp) ? "GEM" : "MACB", macb_readl(bp, MID),
- dev->base_addr, dev->irq, dev->dev_addr);
+ netdev_info(netdev, "Cadence %s rev 0x%08x at 0x%08lx irq %d (%pM)\n",
+ macb_is_gem(&bp->info) ? "GEM" : "MACB",
+ macb_readl(bp, MID), netdev->base_addr, netdev->irq,
+ netdev->dev_addr);
pm_runtime_put_autosuspend(&bp->pdev->dev);
return 0;
+err_out_free_tieoff:
+ macb_free_tieoff(bp);
+
err_out_unregister_mdio:
mdiobus_unregister(bp->mii_bus);
mdiobus_free(bp->mii_bus);
@@ -5945,7 +6258,7 @@ static int macb_probe(struct platform_device *pdev)
phy_exit(bp->phy);
err_out_free_netdev:
- free_netdev(dev);
+ free_netdev(netdev);
err_disable_clocks:
macb_clks_disable(pclk, hclk, tx_clk, rx_clk, tsu_clk);
@@ -5958,14 +6271,15 @@ static int macb_probe(struct platform_device *pdev)
static void macb_remove(struct platform_device *pdev)
{
- struct net_device *dev;
+ struct net_device *netdev;
struct macb *bp;
- dev = platform_get_drvdata(pdev);
+ netdev = platform_get_drvdata(pdev);
- if (dev) {
- bp = netdev_priv(dev);
- unregister_netdev(dev);
+ if (netdev) {
+ bp = netdev_priv(netdev);
+ unregister_netdev(netdev);
+ macb_free_tieoff(bp);
phy_exit(bp->phy);
mdiobus_unregister(bp->mii_bus);
mdiobus_free(bp->mii_bus);
@@ -5977,7 +6291,7 @@ static void macb_remove(struct platform_device *pdev)
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
phylink_destroy(bp->phylink);
- free_netdev(dev);
+ free_netdev(netdev);
}
}
@@ -5992,7 +6306,7 @@ static int __maybe_unused macb_suspend(struct device *dev)
u32 tmp, ifa_local;
unsigned int q;
- if (!device_may_wakeup(&bp->dev->dev))
+ if (!device_may_wakeup(&bp->netdev->dev))
phy_exit(bp->phy);
if (!netif_running(netdev))
@@ -6002,7 +6316,7 @@ static int __maybe_unused macb_suspend(struct device *dev)
if (bp->wolopts & WAKE_ARP) {
/* Check for IP address in WOL ARP mode */
rcu_read_lock();
- idev = __in_dev_get_rcu(bp->dev);
+ idev = __in_dev_get_rcu(bp->netdev);
if (idev)
ifa = rcu_dereference(idev->ifa_list);
if (!ifa) {
@@ -6054,7 +6368,7 @@ static int __maybe_unused macb_suspend(struct device *dev)
tmp |= MACB_BFEXT(IP, ifa_local);
}
- if (macb_is_gem(bp)) {
+ if (macb_is_gem(&bp->info)) {
queue_writel(bp->queues, IER, GEM_BIT(WOL));
gem_writel(bp, WOL, tmp);
} else {
@@ -6100,11 +6414,12 @@ static int __maybe_unused macb_resume(struct device *dev)
{
struct net_device *netdev = dev_get_drvdata(dev);
struct macb *bp = netdev_priv(netdev);
+ struct macb_context *ctx = bp->ctx;
struct macb_queue *queue;
unsigned long flags;
unsigned int q;
- if (!device_may_wakeup(&bp->dev->dev))
+ if (!device_may_wakeup(&bp->netdev->dev))
phy_init(bp->phy);
if (!netif_running(netdev))
@@ -6116,7 +6431,7 @@ static int __maybe_unused macb_resume(struct device *dev)
if (bp->wol & MACB_WOL_ENABLED) {
spin_lock_irqsave(&bp->lock, flags);
/* Disable WoL */
- if (macb_is_gem(bp)) {
+ if (macb_is_gem(&bp->info)) {
queue_writel(bp->queues, IDR, GEM_BIT(WOL));
gem_writel(bp, WOL, 0);
} else {
@@ -6144,10 +6459,10 @@ static int __maybe_unused macb_resume(struct device *dev)
for (q = 0, queue = bp->queues; q < bp->num_queues;
++q, ++queue) {
if (!(bp->caps & MACB_CAPS_MACB_IS_EMAC)) {
- if (macb_is_gem(bp))
- gem_init_rx_ring(queue);
+ if (macb_is_gem(&bp->info))
+ gem_init_rx_ring(ctx, q);
else
- macb_init_rx_ring(queue);
+ macb_init_rx_ring(ctx, q);
}
napi_enable(&queue->napi_rx);
diff --git a/drivers/net/ethernet/cadence/macb_pci.c b/drivers/net/ethernet/cadence/macb_pci.c
index b79dec17e6b099..ac009007118f31 100644
--- a/drivers/net/ethernet/cadence/macb_pci.c
+++ b/drivers/net/ethernet/cadence/macb_pci.c
@@ -24,48 +24,48 @@
#define GEM_PCLK_RATE 50000000
#define GEM_HCLK_RATE 50000000
-static int macb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+static int macb_probe(struct pci_dev *pci, const struct pci_device_id *id)
{
int err;
- struct platform_device *plat_dev;
+ struct platform_device *pdev;
struct platform_device_info plat_info;
struct macb_platform_data plat_data;
struct resource res[2];
/* enable pci device */
- err = pcim_enable_device(pdev);
+ err = pcim_enable_device(pci);
if (err < 0) {
- dev_err(&pdev->dev, "Enabling PCI device has failed: %d", err);
+ dev_err(&pci->dev, "Enabling PCI device has failed: %d", err);
return err;
}
- pci_set_master(pdev);
+ pci_set_master(pci);
/* set up resources */
memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
- res[0].start = pci_resource_start(pdev, 0);
- res[0].end = pci_resource_end(pdev, 0);
+ res[0].start = pci_resource_start(pci, 0);
+ res[0].end = pci_resource_end(pci, 0);
res[0].name = PCI_DRIVER_NAME;
res[0].flags = IORESOURCE_MEM;
- res[1].start = pci_irq_vector(pdev, 0);
+ res[1].start = pci_irq_vector(pci, 0);
res[1].name = PCI_DRIVER_NAME;
res[1].flags = IORESOURCE_IRQ;
- dev_info(&pdev->dev, "EMAC physical base addr: %pa\n",
+ dev_info(&pci->dev, "EMAC physical base addr: %pa\n",
&res[0].start);
/* set up macb platform data */
memset(&plat_data, 0, sizeof(plat_data));
/* initialize clocks */
- plat_data.pclk = clk_register_fixed_rate(&pdev->dev, "pclk", NULL, 0,
+ plat_data.pclk = clk_register_fixed_rate(&pci->dev, "pclk", NULL, 0,
GEM_PCLK_RATE);
if (IS_ERR(plat_data.pclk)) {
err = PTR_ERR(plat_data.pclk);
goto err_pclk_register;
}
- plat_data.hclk = clk_register_fixed_rate(&pdev->dev, "hclk", NULL, 0,
+ plat_data.hclk = clk_register_fixed_rate(&pci->dev, "hclk", NULL, 0,
GEM_HCLK_RATE);
if (IS_ERR(plat_data.hclk)) {
err = PTR_ERR(plat_data.hclk);
@@ -74,24 +74,24 @@ static int macb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* set up platform device info */
memset(&plat_info, 0, sizeof(plat_info));
- plat_info.parent = &pdev->dev;
- plat_info.fwnode = pdev->dev.fwnode;
+ plat_info.parent = &pci->dev;
+ plat_info.fwnode = pci->dev.fwnode;
plat_info.name = PLAT_DRIVER_NAME;
- plat_info.id = pdev->devfn;
+ plat_info.id = pci->devfn;
plat_info.res = res;
plat_info.num_res = ARRAY_SIZE(res);
plat_info.data = &plat_data;
plat_info.size_data = sizeof(plat_data);
- plat_info.dma_mask = pdev->dma_mask;
+ plat_info.dma_mask = pci->dma_mask;
/* register platform device */
- plat_dev = platform_device_register_full(&plat_info);
- if (IS_ERR(plat_dev)) {
- err = PTR_ERR(plat_dev);
+ pdev = platform_device_register_full(&plat_info);
+ if (IS_ERR(pdev)) {
+ err = PTR_ERR(pdev);
goto err_plat_dev_register;
}
- pci_set_drvdata(pdev, plat_dev);
+ pci_set_drvdata(pci, pdev);
return 0;
@@ -105,14 +105,14 @@ static int macb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return err;
}
-static void macb_remove(struct pci_dev *pdev)
+static void macb_remove(struct pci_dev *pci)
{
- struct platform_device *plat_dev = pci_get_drvdata(pdev);
- struct macb_platform_data *plat_data = dev_get_platdata(&plat_dev->dev);
+ struct platform_device *pdev = pci_get_drvdata(pci);
+ struct macb_platform_data *plat_data = dev_get_platdata(&pdev->dev);
struct clk *pclk = plat_data->pclk;
struct clk *hclk = plat_data->hclk;
- platform_device_unregister(plat_dev);
+ platform_device_unregister(pdev);
clk_unregister_fixed_rate(pclk);
clk_unregister_fixed_rate(hclk);
}
diff --git a/drivers/net/ethernet/cadence/macb_ptp.c b/drivers/net/ethernet/cadence/macb_ptp.c
index d91f7b1aa39caa..8765c4782509ce 100644
--- a/drivers/net/ethernet/cadence/macb_ptp.c
+++ b/drivers/net/ethernet/cadence/macb_ptp.c
@@ -28,10 +28,10 @@
static struct macb_dma_desc_ptp *macb_ptp_desc(struct macb *bp,
struct macb_dma_desc *desc)
{
- if (!macb_dma_ptp(bp))
+ if (!macb_dma_ptp(&bp->info))
return NULL;
- if (macb_dma64(bp))
+ if (macb_dma64(&bp->info))
return (struct macb_dma_desc_ptp *)
((u8 *)desc + sizeof(struct macb_dma_desc)
+ sizeof(struct macb_dma_desc_64));
@@ -324,9 +324,9 @@ void gem_ptp_txstamp(struct macb *bp, struct sk_buff *skb,
skb_tstamp_tx(skb, &shhwtstamps);
}
-void gem_ptp_init(struct net_device *dev)
+void gem_ptp_init(struct net_device *netdev)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
bp->ptp_clock_info = gem_ptp_caps_template;
@@ -334,7 +334,7 @@ void gem_ptp_init(struct net_device *dev)
bp->tsu_rate = bp->ptp_info->get_tsu_rate(bp);
bp->ptp_clock_info.max_adj = bp->ptp_info->get_ptp_max_adj();
gem_ptp_init_timer(bp);
- bp->ptp_clock = ptp_clock_register(&bp->ptp_clock_info, &dev->dev);
+ bp->ptp_clock = ptp_clock_register(&bp->ptp_clock_info, &netdev->dev);
if (IS_ERR(bp->ptp_clock)) {
pr_err("ptp clock register failed: %ld\n",
PTR_ERR(bp->ptp_clock));
@@ -353,9 +353,9 @@ void gem_ptp_init(struct net_device *dev)
GEM_PTP_TIMER_NAME);
}
-void gem_ptp_remove(struct net_device *ndev)
+void gem_ptp_remove(struct net_device *netdev)
{
- struct macb *bp = netdev_priv(ndev);
+ struct macb *bp = netdev_priv(netdev);
if (bp->ptp_clock) {
ptp_clock_unregister(bp->ptp_clock);
@@ -378,13 +378,13 @@ static int gem_ptp_set_ts_mode(struct macb *bp,
return 0;
}
-int gem_get_hwtst(struct net_device *dev,
+int gem_get_hwtst(struct net_device *netdev,
struct kernel_hwtstamp_config *tstamp_config)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
*tstamp_config = bp->tstamp_config;
- if (!macb_dma_ptp(bp))
+ if (!macb_dma_ptp(&bp->info))
return -EOPNOTSUPP;
return 0;
@@ -402,16 +402,16 @@ static void gem_ptp_set_one_step_sync(struct macb *bp, u8 enable)
macb_writel(bp, NCR, reg_val & ~MACB_BIT(OSSMODE));
}
-int gem_set_hwtst(struct net_device *dev,
+int gem_set_hwtst(struct net_device *netdev,
struct kernel_hwtstamp_config *tstamp_config,
struct netlink_ext_ack *extack)
{
enum macb_bd_control tx_bd_control = TSTAMP_DISABLED;
enum macb_bd_control rx_bd_control = TSTAMP_DISABLED;
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
u32 regval;
- if (!macb_dma_ptp(bp))
+ if (!macb_dma_ptp(&bp->info))
return -EOPNOTSUPP;
switch (tstamp_config->tx_type) {
|
| 3/2 | 2026/07/01 23:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 65142 output: 35 thoughts: 265 Thoughts: **Analyzing the Cadence MACB Ethernet Driver Patch** Okay, so we've got this patch affecting the `cadence` ethernet driver. Specifically, it touches files like `macb_main.c`, `macb.h`, `macb_pci.c`, and `macb_ptp.c`. Seems like a significant refactor is in play, introducing a `struct macb_context`. This looks like they're trying to allow context swapping – presumably for changing the Maximum Transmission Unit (MTU) while the interface is active. Interesting. That's definitely a core functional change, dealing with ring management and MTU adjustments. This driver is for Cadence MACB/GEM Ethernet controllers, right? The next question in my mind is always: where does this show up? Is this driver reachable within a virtualized setup? We're looking at the `cadence` MACB, and it's used in QEMU. Ah, right, QEMU has that `cadence_gem` device model, `hw/net/cadence_gem.c`. Hold on... the `cadence_gem` device model is used in things like Xilinx Zynq and SiFive U, and it's based on this driver! So the question is: can we actually *reach* this driver in an x86 environment? Or at least, can we compile it? Okay, let's see. This driver is controlled by `CONFIG_MACB`, which is a start. Need to look in `drivers/net/ethernet/cadence/Kconfig` to see the options. That's the key to finding its availability. |
| 4/2 | 2026/07/01 23:40 | tool | grepper |
0mArgs:{
"Expression": "config MACB",
"PathPrefix": "drivers/net/ethernet/cadence/Kconfig"
}Results: {
"Output": "drivers/net/ethernet/cadence/Kconfig=20=if NET_VENDOR_CADENCE\ndrivers/net/ethernet/cadence/Kconfig-21-\ndrivers/net/ethernet/cadence/Kconfig:22:config MACB\ndrivers/net/ethernet/cadence/Kconfig-23-\ttristate \"Cadence MACB/GEM support\"\n--\ndrivers/net/ethernet/cadence/Kconfig-36-\ndrivers/net/ethernet/cadence/Kconfig:37:config MACB_USE_HWSTAMP\ndrivers/net/ethernet/cadence/Kconfig-38-\tbool \"Use IEEE 1588 hwstamp\"\n--\ndrivers/net/ethernet/cadence/Kconfig-44-\ndrivers/net/ethernet/cadence/Kconfig:45:config MACB_PCI\ndrivers/net/ethernet/cadence/Kconfig-46-\ttristate \"Cadence PCI MACB/GEM support\"\n"
} |
| 5/2 | 2026/07/01 23:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 66048 output: 43 thoughts: 121 Thoughts: **Analyzing the MACB_PCI Configuration** Okay, so I'm looking at this `MACB_PCI` setup. Right, it's essentially a PCI wrapper for the Cadence MACB/GEM. The implications are clear: we *should* be able to attach this as a PCI device in QEMU, assuming QEMU has the necessary support. Or, I wonder if it might still function as just a platform device. Hmm, wait a second, I recall that QEMU *does* have `cadence_gem`, but that's implemented as a platform device through sysbus. But the beauty of `MACB_PCI` is that it allows the MACB/GEM to be *probed* as a PCI device! That's the key difference. Okay, let's confirm this by digging into the source code, specifically `drivers/net/ethernet/cadence/macb_pci.c`. Time to see how this all connects. |
| 6/2 | 2026/07/01 23:40 | tool | grepper |
0mArgs:{
"Expression": "pci_device_id",
"PathPrefix": "drivers/net/ethernet/cadence/macb_pci.c"
}Results: {
"Output": "drivers/net/ethernet/cadence/macb_pci.c-26-\ndrivers/net/ethernet/cadence/macb_pci.c:27:static int macb_probe(struct pci_dev *pci, const struct pci_device_id *id)\ndrivers/net/ethernet/cadence/macb_pci.c-28-{\n--\ndrivers/net/ethernet/cadence/macb_pci.c=108=static void macb_remove(struct pci_dev *pci)\n--\ndrivers/net/ethernet/cadence/macb_pci.c-119-\ndrivers/net/ethernet/cadence/macb_pci.c:120:static const struct pci_device_id dev_id_table[] = {\ndrivers/net/ethernet/cadence/macb_pci.c-121-\t{ PCI_VDEVICE(CDNS, PCI_DEVICE_ID_CDNS_MACB) },\n"
} |
| 7/2 | 2026/07/01 23:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 66676 output: 31 thoughts: 24 Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience: **Analyzing the Device ID: `PCI_DEVICE_ID_CDNS_MACB`** Okay, here we go. The `PCI_DEVICE_ID_CDNS_MACB` device ID…right, I need to immediately pinpoint what hardware we're dealing with here. My initial thought is to pull up the relevant documentation or the source code to determine what the specific ID points to. I'm assuming this is a Cadence MACB Ethernet controller – that's a pretty common implementation. I need to refresh my memory on the likely register maps and driver architectures associated with that. Time to get to work to see where this is used within the code base. |
| 8/2 | 2026/07/01 23:40 | tool | grepper |
0mArgs:{
"Expression": "PCI_DEVICE_ID_CDNS_MACB",
"PathPrefix": ""
}Results: {
"Output": "drivers/net/ethernet/cadence/macb_pci.c-21-\ndrivers/net/ethernet/cadence/macb_pci.c:22:#define PCI_DEVICE_ID_CDNS_MACB 0xe007\ndrivers/net/ethernet/cadence/macb_pci.c-23-\n--\ndrivers/net/ethernet/cadence/macb_pci.c=120=static const struct pci_device_id dev_id_table[] = {\ndrivers/net/ethernet/cadence/macb_pci.c:121:\t{ PCI_VDEVICE(CDNS, PCI_DEVICE_ID_CDNS_MACB) },\ndrivers/net/ethernet/cadence/macb_pci.c-122-\t{ 0, }\n"
} |
| 9/2 | 2026/07/01 23:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 67102 output: 43 thoughts: 270 Thoughts: **Analyzing the MACB Driver Patch** Okay, so this patch is aimed at the MACB Ethernet driver, and the fact that it's being fuzzed with syzkaller immediately piques my interest. Right, syzkaller can either inject PCI devices directly using something like `syz_pci_setup` and then interact with the driver that way, or it's fuzzing the PCI subsystem itself. Since this is a network driver, it makes things even more interesting because a probed driver exposes a network device, meaning we can hit it with socket ioctls, netlink messages, the whole gamut. The patch itself targets several key functions in the driver: `macb_change_mtu`, `macb_open`, `macb_close`, `macb_start_xmit`, and `macb_rx`, among others. It seems to be focusing on context swapping with the introduction of `macb_context_swap_start` and `macb_context_swap_end`. My immediate instinct is to identify the critical symbols involved in this patch. Let me list the relevant functions. Alright, the core functions I need to focus on are: * `macb_change_mtu` * `macb_context_swap_start` * `macb_context_swap_end` * `macb_context_alloc` * `macb_alloc` * `macb_free` * `macb_set_ringparam` Next, I need to see if the driver is even compiled in the kernel I'm looking at. Let's make sure the essential configurations are enabled, specifically `MACB` and `MACB_PCI`. Now, let's dive into the code for `macb_change_mtu` and see how it interacts with the rest of the driver. I will be looking specifically in `macb_main.c` . |
| 10/2 | 2026/07/01 23:41 | tool | grepper |
0mArgs:{
"Expression": "macb_change_mtu",
"PathPrefix": "drivers/net/ethernet/cadence/macb_main.c"
}Results: {
"Output": "drivers/net/ethernet/cadence/macb_main.c=3429=static int macb_close(struct net_device *netdev)\n--\ndrivers/net/ethernet/cadence/macb_main.c-3467-\ndrivers/net/ethernet/cadence/macb_main.c:3468:static int macb_change_mtu(struct net_device *netdev, int new_mtu)\ndrivers/net/ethernet/cadence/macb_main.c-3469-{\n--\ndrivers/net/ethernet/cadence/macb_main.c=4786=static const struct net_device_ops macb_netdev_ops = {\n--\ndrivers/net/ethernet/cadence/macb_main.c-4793-\t.ndo_validate_addr\t= eth_validate_addr,\ndrivers/net/ethernet/cadence/macb_main.c:4794:\t.ndo_change_mtu\t\t= macb_change_mtu,\ndrivers/net/ethernet/cadence/macb_main.c-4795-\t.ndo_set_mac_address\t= macb_set_mac_addr,\n"
} |
| 11/2 | 2026/07/01 23:41 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 68145 output: 43 thoughts: 25 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience: **Analyzing MACB Driver Functionality** Right, so the initial check confirms it: `macb_change_mtu` *is* present. That's good. It suggests we're dealing with a driver implementation that's at least considering MTU adjustments, which is a fundamental requirement. Now, let's see how well it's implemented. I'm immediately thinking about the implications for jumbo frames and the associated buffer size management. We'll need to dig into the surrounding code to see if there are any potential gotchas with descriptor re-allocation or potential issues when dealing with various hardware setups. And then, looking further... also, `macb_set_ringparam`. Interesting. That function name immediately screams "descriptor ring parameters." This is key. The presence of a function dedicated to ring parameter configuration strongly indicates a DMA-centric approach to data transfer within the MACB driver. I'll need to examine this function very carefully. The efficiency of the driver, and its ability to handle different traffic loads, will hinge on how effectively it manages the ring parameters. I'm mentally making a note to check how the ring sizes are initialized, if there's any dynamic adjustment based on MTU, and how the driver deals with descriptor chaining and buffer management. This is definitely a significant point to explore. There’s potentially a significant impact on performance here, especially under load. |
| 12/2 | 2026/07/01 23:41 | tool | grepper |
0mArgs:{
"Expression": "macb_set_ringparam",
"PathPrefix": "drivers/net/ethernet/cadence/macb_main.c"
}Results: {
"Output": "drivers/net/ethernet/cadence/macb_main.c=3926=static void macb_get_ringparam(struct net_device *netdev,\n--\ndrivers/net/ethernet/cadence/macb_main.c-3939-\ndrivers/net/ethernet/cadence/macb_main.c:3940:static int macb_set_ringparam(struct net_device *netdev,\ndrivers/net/ethernet/cadence/macb_main.c-3941-\t\t\t struct ethtool_ringparam *ring,\n--\ndrivers/net/ethernet/cadence/macb_main.c=4377=static const struct ethtool_ops macb_ethtool_ops = {\n--\ndrivers/net/ethernet/cadence/macb_main.c-4390-\t.get_ringparam\t\t= macb_get_ringparam,\ndrivers/net/ethernet/cadence/macb_main.c:4391:\t.set_ringparam\t\t= macb_set_ringparam,\ndrivers/net/ethernet/cadence/macb_main.c-4392-};\n--\ndrivers/net/ethernet/cadence/macb_main.c=4408=static const struct ethtool_ops gem_ethtool_ops = {\n--\ndrivers/net/ethernet/cadence/macb_main.c-4424-\t.get_ringparam\t\t= macb_get_ringparam,\ndrivers/net/ethernet/cadence/macb_main.c:4425:\t.set_ringparam\t\t= macb_set_ringparam,\ndrivers/net/ethernet/cadence/macb_main.c-4426-\t.get_rxnfc\t\t\t= gem_get_rxnfc,\n"
} |
| 13/2 | 2026/07/01 23:41 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 68984 output: 44 thoughts: 24 Thoughts: Here's a summary of my thoughts, presented as if they were my own: **Context Switching in the MACB Driver** Okay, so this patch is introducing a couple of new functions into the MACB driver: `macb_context_swap_start` and `macb_context_swap_end`. This immediately sparks some questions. What's the context being swapped? I'm assuming we're talking about a hardware context, likely related to DMA descriptors or some other state the MACB controller maintains internally. The names strongly suggest that these functions delineate a start and end point for some context switching operation. I'd need to dig deeper into the code, and probably the hardware documentation, to fully understand the specifics. I'd want to know why this is necessary now, what's triggered the need for context swaps, and what potential performance implications there are, both positive and negative. Is this related to virtualization? Power management? Or perhaps supporting multiple network interfaces on the same MACB controller? The "context" could be a set of registers, DMA settings, interrupt masks, or something else entirely. I'll need to analyze the surrounding code to determine how these functions are used. |
| 14/2 | 2026/07/01 23:41 | tool | grepper |
0mArgs:{
"Expression": "macb_context_swap_start",
"PathPrefix": "drivers/net/ethernet/cadence/macb_main.c"
}Results: {
"Output": "drivers/net/ethernet/cadence/macb_main.c=3061=static void macb_configure_dma(struct macb *bp)\n--\ndrivers/net/ethernet/cadence/macb_main.c-3102-\ndrivers/net/ethernet/cadence/macb_main.c:3103:static void macb_context_swap_start(struct macb *bp)\ndrivers/net/ethernet/cadence/macb_main.c-3104-{\n--\ndrivers/net/ethernet/cadence/macb_main.c=3468=static int macb_change_mtu(struct net_device *netdev, int new_mtu)\n--\ndrivers/net/ethernet/cadence/macb_main.c-3484-\ndrivers/net/ethernet/cadence/macb_main.c:3485:\t\tmacb_context_swap_start(bp);\ndrivers/net/ethernet/cadence/macb_main.c-3486-\t}\n--\ndrivers/net/ethernet/cadence/macb_main.c=3940=static int macb_set_ringparam(struct net_device *netdev,\n--\ndrivers/net/ethernet/cadence/macb_main.c-3976-\ndrivers/net/ethernet/cadence/macb_main.c:3977:\t\tmacb_context_swap_start(bp);\ndrivers/net/ethernet/cadence/macb_main.c-3978-\t}\n"
} |
| 15/2 | 2026/07/01 23:41 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 69702 output: 35 thoughts: 710 Thoughts: **Fuzzing Target Assessment: MACB Driver** Okay, so this patch introduces functional changes to the kernel, and it's looking like we should definitely consider it for fuzzing. The key entry points appear to be `macb_change_mtu` and `macb_set_ringparam`, and those are reachable when the network interface is up and running. The relevant drivers are `MACB` and `MACB_PCI`. The question now is, how readily accessible is this for Syzkaller? We need to figure out if `MACB_PCI` is *the* only path to reach the code in our QEMU environment. Cadence GEM devices are typically sysbus devices in QEMU, and usually instantiated by the machine itself (like with `xilinx-zynq-a9` or `sifive_u`). But Syzkaller typically runs on x86_64 or arm64. If it were arm64, maybe the device is instantiated then? No, Syzkaller usually uses the `virt` machine for arm64. But, and here's the crucial point, `MACB_PCI` allows the driver to be probed as a PCI device, which Syzkaller *could* potentially inject using... wait, what's the mechanism? I thought it had something like `syz_pci_setup`, but that doesn't exist. Syzkaller does have calls for USB injection (`syz_usb_connect`), 802.11 frame injection, and so on. For PCI devices, Syzkaller generally uses either `vfio` or relies on the kernel being able to probe the virtual PCI devices if QEMU supports it. Hmm, there *is* a PCI subsystem fuzzer, but it's not clear if that can instantiate arbitrary PCI devices. Okay, let's think this through: if `MACB_PCI` is enabled, the driver registers a PCI driver. If QEMU doesn't *specifically* emulate this particular PCI device, it's not going to be probed automatically. So, no direct injection via `vhci` or a `syz_pci_setup` call (which doesn't exist). But wait, does it have something similar to `syz_kvm_setup_cpu` which would help? No. Ah, right. Syzkaller can fuzz PCI devices via `vfio`. Or, it is expected that QEMU will provide the device. So, no luck here. But the key here is, is it *reachable*? `WorthFuzzing` should be true if it's reachable. If we enable both `MACB` and `MACB_PCI`, the driver *can* be loaded. Even if it's not instantiated by default in Syzkaller's setup, this is a core driver. Therefore, we should return `WorthFuzzing=true`. So, the configs needed are: `MACB`, `MACB_PCI`. The most critical symbols for focus during fuzzing are: `macb_change_mtu`, `macb_set_ringparam`, `macb_context_swap_start`, `macb_context_swap_end`, `macb_context_alloc`, `macb_alloc`, and `macb_free`. I'll double-check the exact names of the configs to be absolutely sure. |
| 16/2 | 2026/07/01 23:41 | tool | grepper |
0mArgs:{
"Expression": "config MACB",
"PathPrefix": "drivers/net/ethernet/cadence/Kconfig"
}Results: {
"Output": "drivers/net/ethernet/cadence/Kconfig=20=if NET_VENDOR_CADENCE\ndrivers/net/ethernet/cadence/Kconfig-21-\ndrivers/net/ethernet/cadence/Kconfig:22:config MACB\ndrivers/net/ethernet/cadence/Kconfig-23-\ttristate \"Cadence MACB/GEM support\"\n--\ndrivers/net/ethernet/cadence/Kconfig-36-\ndrivers/net/ethernet/cadence/Kconfig:37:config MACB_USE_HWSTAMP\ndrivers/net/ethernet/cadence/Kconfig-38-\tbool \"Use IEEE 1588 hwstamp\"\n--\ndrivers/net/ethernet/cadence/Kconfig-44-\ndrivers/net/ethernet/cadence/Kconfig:45:config MACB_PCI\ndrivers/net/ethernet/cadence/Kconfig-46-\ttristate \"Cadence PCI MACB/GEM support\"\n"
} |
| 17/2 | 2026/07/01 23:41 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 71430 output: 43 thoughts: 452 Thoughts: **My Assessment of the MACB/GEM Driver Refactoring** Okay, let's break this down. First, I'm noting the configurations involved: `MACB` and `MACB_PCI`. I want to quickly identify any other functions that have been modified which might be good entry points for deeper analysis, and the list is extensive: `macb_tx_error_task`, `macb_hresp_error_task`, `gem_rx_refill`, `macb_rx_frame`, `macb_rx`, `gem_rx`, `macb_tx_complete`, `macb_tx_restart`, `macb_tx_poll`, `macb_rx_poll`, `macb_interrupt`, `macb_start_xmit`, `macb_open`, `macb_close`. That's a lot to consider, but I need to hone in on what's *new*. Ah, here we go. The core of this seems to be context swapping. I'm seeing `macb_context_swap_start`, `macb_context_swap_end`, `macb_context_alloc`, `macb_alloc`, and `macb_free`. These are definitely interesting. And the entry points for the new logic, how the user interacts with this, are `macb_change_mtu` and `macb_set_ringparam`. These are my primary focus symbols. They're the critical functions to zero in on. Okay, let's verify my initial impression. The patch is refactoring the Cadence MACB/GEM Ethernet driver to manage rings and buffers using a `macb_context` structure. The aim is to perform dynamic context swapping when the MTU or ring parameters are changed *while the interface is running*, instead of the old-school close/open approach. This is a pretty significant architectural shift in the driver's core logic and resource management. That sounds like a textbook case for fuzzing. It's almost guaranteed to expose subtle bugs related to race conditions, memory management, or unexpected states. So, to summarize my key findings, and remind myself of what to target, my core configurations are `MACB` and `MACB_PCI`, and the focus symbols for fuzzing are: `macb_change_mtu`, `macb_set_ringparam`, `macb_context_swap_start`, `macb_context_swap_end`, `macb_context_alloc`, `macb_alloc`, and `macb_free`. Wait a second… `macb_alloc` and `macb_free` are listed as static functions in `macb_main.c`? That's unusual. I need to double-check that they exist. Just because they're listed doesn't mean they're actually exported and callable. I need to make sure I'm not chasing a phantom function. |
| 18/2 | 2026/07/01 23:41 | tool | grepper |
0mArgs:{
"Expression": "static int macb_alloc\\(",
"PathPrefix": "drivers/net/ethernet/cadence/macb_main.c"
}Results: {
"Output": "drivers/net/ethernet/cadence/macb_main.c=2800=static int macb_alloc_rx_buffers(struct macb_context *ctx)\n--\ndrivers/net/ethernet/cadence/macb_main.c-2817-\ndrivers/net/ethernet/cadence/macb_main.c:2818:static int macb_alloc(struct macb_context *ctx)\ndrivers/net/ethernet/cadence/macb_main.c-2819-{\n"
} |
| 19/2 | 2026/07/01 23:41 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 72691 output: 43 thoughts: 10 Thoughts: Okay, here's my interpretation of that thought process, tailored for an expert audience, and presented as if it's my own internal dialogue: **Affirmative: `macb_alloc`'s Presence Confirmed** Alright, yep, that checks out. `macb_alloc` is definitely a thing. No need to second-guess its existence. It's a standard part of the toolkit. Moving on, it's safe to assume from this that the current line of thinking or problem I'm addressing involves interacting with or managing resources related to an Ethernet interface and likely the Media Access Controller (MAC) itself, given the `macb` prefix. This knowledge serves as a foundational element, allowing me to formulate a plan in the subsequent steps. Time to move forward with that assumption. |
| 20/2 | 2026/07/01 23:41 | tool | grepper |
0mArgs:{
"Expression": "static void macb_free\\(",
"PathPrefix": "drivers/net/ethernet/cadence/macb_main.c"
}Results: {
"Output": "drivers/net/ethernet/cadence/macb_main.c=2745=static unsigned int macb_rx_ring_size_per_queue(struct macb_context *ctx)\n--\ndrivers/net/ethernet/cadence/macb_main.c-2750-\ndrivers/net/ethernet/cadence/macb_main.c:2751:static void macb_free(struct macb_context *ctx)\ndrivers/net/ethernet/cadence/macb_main.c-2752-{\n"
} |
| 21/2 | 2026/07/01 23:41 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 73057 output: 188 thoughts: 70 Thoughts: Okay, here's my breakdown of this. **Confirming and Refining the Configuration** Alright, so `macb_free` definitely exists, that’s confirmed. Now, I should double check, are there any other related configurations I need to consider? Ah yes, `MACB_USE_HWSTAMP`. However, that one isn't a *hard* requirement, is it? We're good without it. So I can streamline things. For this particular feature, I can just stick with including `MACB` and `MACB_PCI`. Those should cover the essentials. That keeps it clean and avoids unnecessary dependencies. And from there, it's just a matter of executing `set-results`. |
| 22/2 | 2026/07/01 23:41 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"MACB",
"MACB_PCI"
],
"FocusSymbols": [
"macb_change_mtu",
"macb_set_ringparam",
"macb_context_swap_start",
"macb_context_swap_end",
"macb_context_alloc",
"macb_alloc",
"macb_free"
],
"Reasoning": "The patch refactors the Cadence MACB/GEM Ethernet driver to use a `macb_context` structure for ring and buffer management. This allows the driver to swap contexts dynamically when changing the MTU or ring parameters while the interface is running, avoiding a full close/open cycle. This is a significant functional change to the driver's core logic and resource management, making it worth fuzzing.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"MACB",
"MACB_PCI"
],
"FocusSymbols": [
"macb_change_mtu",
"macb_set_ringparam",
"macb_context_swap_start",
"macb_context_swap_end",
"macb_context_alloc",
"macb_alloc",
"macb_free"
],
"Reasoning": "The patch refactors the Cadence MACB/GEM Ethernet driver to use a `macb_context` structure for ring and buffer management. This allows the driver to swap contexts dynamically when changing the MTU or ring parameters while the interface is running, avoiding a full close/open cycle. This is a significant functional change to the driver's core logic and resource management, making it worth fuzzing.",
"WorthFuzzing": true
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|