e779d3b344e8f8e6e4cb9dcec6f3075e98aaf321
[openwrt/staging/ldir.git] /
1 From patchwork Thu Sep 8 19:33:39 2022
2 Content-Type: text/plain; charset="utf-8"
3 MIME-Version: 1.0
4 Content-Transfer-Encoding: 7bit
5 X-Patchwork-Submitter: Lorenzo Bianconi <lorenzo@kernel.org>
6 X-Patchwork-Id: 12970559
7 X-Patchwork-Delegate: kuba@kernel.org
8 Return-Path: <netdev-owner@kernel.org>
9 From: Lorenzo Bianconi <lorenzo@kernel.org>
10 To: netdev@vger.kernel.org
11 Cc: nbd@nbd.name, john@phrozen.org, sean.wang@mediatek.com,
12 Mark-MC.Lee@mediatek.com, davem@davemloft.net, edumazet@google.com,
13 kuba@kernel.org, pabeni@redhat.com, matthias.bgg@gmail.com,
14 linux-mediatek@lists.infradead.org, lorenzo.bianconi@redhat.com,
15 Bo.Jiao@mediatek.com, sujuan.chen@mediatek.com,
16 ryder.Lee@mediatek.com, evelyn.tsai@mediatek.com,
17 devicetree@vger.kernel.org, robh@kernel.org
18 Subject: [PATCH net-next 05/12] net: ethernet: mtk_eth_soc: add the capability
19 to run multiple ppe
20 Date: Thu, 8 Sep 2022 21:33:39 +0200
21 Message-Id:
22 <dd0254775390eb031c67c448df8b19e87df58558.1662661555.git.lorenzo@kernel.org>
23 X-Mailer: git-send-email 2.37.3
24 In-Reply-To: <cover.1662661555.git.lorenzo@kernel.org>
25 References: <cover.1662661555.git.lorenzo@kernel.org>
26 MIME-Version: 1.0
27 Precedence: bulk
28 List-ID: <netdev.vger.kernel.org>
29 X-Mailing-List: netdev@vger.kernel.org
30 X-Patchwork-Delegate: kuba@kernel.org
31
32 mt7986 chipset support multiple packet engines for wlan <-> eth
33 packet forwarding.
34
35 Co-developed-by: Bo Jiao <Bo.Jiao@mediatek.com>
36 Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
37 Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
38 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
39 Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
40 ---
41 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 35 ++++++++++++-------
42 drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +-
43 drivers/net/ethernet/mediatek/mtk_ppe.c | 14 +++++---
44 drivers/net/ethernet/mediatek/mtk_ppe.h | 9 +++--
45 .../net/ethernet/mediatek/mtk_ppe_debugfs.c | 8 ++---
46 .../net/ethernet/mediatek/mtk_ppe_offload.c | 13 +++----
47 6 files changed, 48 insertions(+), 33 deletions(-)
48
49 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
50 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
51 @@ -1872,7 +1872,7 @@ static int mtk_poll_rx(struct napi_struc
52
53 reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4);
54 if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
55 - mtk_ppe_check_skb(eth->ppe, skb, hash);
56 + mtk_ppe_check_skb(eth->ppe[0], skb, hash);
57
58 if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
59 if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
60 @@ -2933,7 +2933,8 @@ static int mtk_open(struct net_device *d
61 /* we run 2 netdevs on the same dma ring so we only bring it up once */
62 if (!refcount_read(&eth->dma_refcnt)) {
63 const struct mtk_soc_data *soc = eth->soc;
64 - u32 gdm_config = MTK_GDMA_TO_PDMA;
65 + u32 gdm_config;
66 + int i;
67 int err;
68
69 err = mtk_start_dma(eth);
70 @@ -2942,8 +2943,11 @@ static int mtk_open(struct net_device *d
71 return err;
72 }
73
74 - if (soc->offload_version && mtk_ppe_start(eth->ppe) == 0)
75 - gdm_config = soc->reg_map->gdma_to_ppe0;
76 + for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
77 + mtk_ppe_start(eth->ppe[i]);
78 +
79 + gdm_config = soc->offload_version ? soc->reg_map->gdma_to_ppe0
80 + : MTK_GDMA_TO_PDMA;
81
82 mtk_gdm_config(eth, gdm_config);
83
84 @@ -2988,6 +2992,7 @@ static int mtk_stop(struct net_device *d
85 {
86 struct mtk_mac *mac = netdev_priv(dev);
87 struct mtk_eth *eth = mac->hw;
88 + int i;
89
90 phylink_stop(mac->phylink);
91
92 @@ -3015,8 +3020,8 @@ static int mtk_stop(struct net_device *d
93
94 mtk_dma_free(eth);
95
96 - if (eth->soc->offload_version)
97 - mtk_ppe_stop(eth->ppe);
98 + for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
99 + mtk_ppe_stop(eth->ppe[i]);
100
101 return 0;
102 }
103 @@ -4049,12 +4054,19 @@ static int mtk_probe(struct platform_dev
104 }
105
106 if (eth->soc->offload_version) {
107 - u32 ppe_addr = eth->soc->reg_map->ppe_base;
108 + u32 num_ppe;
109
110 - eth->ppe = mtk_ppe_init(eth, eth->base + ppe_addr, 2);
111 - if (!eth->ppe) {
112 - err = -ENOMEM;
113 - goto err_free_dev;
114 + num_ppe = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
115 + num_ppe = min_t(u32, ARRAY_SIZE(eth->ppe), num_ppe);
116 + for (i = 0; i < num_ppe; i++) {
117 + u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
118 +
119 + eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr,
120 + eth->soc->offload_version, i);
121 + if (!eth->ppe[i]) {
122 + err = -ENOMEM;
123 + goto err_free_dev;
124 + }
125 }
126
127 err = mtk_eth_offload_init(eth);
128 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
129 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
130 @@ -1112,7 +1112,7 @@ struct mtk_eth {
131
132 int ip_align;
133
134 - struct mtk_ppe *ppe;
135 + struct mtk_ppe *ppe[2];
136 struct rhashtable flow_table;
137
138 struct bpf_prog __rcu *prog;
139 --- a/drivers/net/ethernet/mediatek/mtk_ppe.c
140 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
141 @@ -682,7 +682,7 @@ int mtk_foe_entry_idle_time(struct mtk_p
142 }
143
144 struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
145 - int version)
146 + int version, int index)
147 {
148 const struct mtk_soc_data *soc = eth->soc;
149 struct device *dev = eth->dev;
150 @@ -717,7 +717,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
151 if (!ppe->foe_flow)
152 return NULL;
153
154 - mtk_ppe_debugfs_init(ppe);
155 + mtk_ppe_debugfs_init(ppe, index);
156
157 return ppe;
158 }
159 @@ -738,10 +738,13 @@ static void mtk_ppe_init_foe_table(struc
160 ppe->foe_table[i + skip[k]].ib1 |= MTK_FOE_IB1_STATIC;
161 }
162
163 -int mtk_ppe_start(struct mtk_ppe *ppe)
164 +void mtk_ppe_start(struct mtk_ppe *ppe)
165 {
166 u32 val;
167
168 + if (!ppe)
169 + return;
170 +
171 mtk_ppe_init_foe_table(ppe);
172 ppe_w32(ppe, MTK_PPE_TB_BASE, ppe->foe_phys);
173
174 @@ -809,8 +812,6 @@ int mtk_ppe_start(struct mtk_ppe *ppe)
175 ppe_w32(ppe, MTK_PPE_GLO_CFG, val);
176
177 ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0);
178 -
179 - return 0;
180 }
181
182 int mtk_ppe_stop(struct mtk_ppe *ppe)
183 @@ -818,6 +819,9 @@ int mtk_ppe_stop(struct mtk_ppe *ppe)
184 u32 val;
185 int i;
186
187 + if (!ppe)
188 + return 0;
189 +
190 for (i = 0; i < MTK_PPE_ENTRIES; i++)
191 ppe->foe_table[i].ib1 = FIELD_PREP(MTK_FOE_IB1_STATE,
192 MTK_FOE_STATE_INVALID);
193 --- a/drivers/net/ethernet/mediatek/mtk_ppe.h
194 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
195 @@ -247,6 +247,7 @@ struct mtk_flow_entry {
196 };
197 u8 type;
198 s8 wed_index;
199 + u8 ppe_index;
200 u16 hash;
201 union {
202 struct mtk_foe_entry data;
203 @@ -265,6 +266,7 @@ struct mtk_ppe {
204 struct device *dev;
205 void __iomem *base;
206 int version;
207 + char dirname[5];
208
209 struct mtk_foe_entry *foe_table;
210 dma_addr_t foe_phys;
211 @@ -277,8 +279,9 @@ struct mtk_ppe {
212 void *acct_table;
213 };
214
215 -struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version);
216 -int mtk_ppe_start(struct mtk_ppe *ppe);
217 +struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
218 + int version, int index);
219 +void mtk_ppe_start(struct mtk_ppe *ppe);
220 int mtk_ppe_stop(struct mtk_ppe *ppe);
221
222 void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash);
223 @@ -317,6 +320,6 @@ int mtk_foe_entry_set_wdma(struct mtk_fo
224 int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
225 void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
226 int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
227 -int mtk_ppe_debugfs_init(struct mtk_ppe *ppe);
228 +int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index);
229
230 #endif
231 --- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
232 +++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
233 @@ -187,7 +187,7 @@ mtk_ppe_debugfs_foe_open_bind(struct ino
234 inode->i_private);
235 }
236
237 -int mtk_ppe_debugfs_init(struct mtk_ppe *ppe)
238 +int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index)
239 {
240 static const struct file_operations fops_all = {
241 .open = mtk_ppe_debugfs_foe_open_all,
242 @@ -195,17 +195,17 @@ int mtk_ppe_debugfs_init(struct mtk_ppe
243 .llseek = seq_lseek,
244 .release = single_release,
245 };
246 -
247 static const struct file_operations fops_bind = {
248 .open = mtk_ppe_debugfs_foe_open_bind,
249 .read = seq_read,
250 .llseek = seq_lseek,
251 .release = single_release,
252 };
253 -
254 struct dentry *root;
255
256 - root = debugfs_create_dir("mtk_ppe", NULL);
257 + snprintf(ppe->dirname, sizeof(ppe->dirname), "ppe%d", index);
258 +
259 + root = debugfs_create_dir(ppe->dirname, NULL);
260 if (!root)
261 return -ENOMEM;
262
263 --- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
264 +++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
265 @@ -434,7 +434,7 @@ mtk_flow_offload_replace(struct mtk_eth
266 memcpy(&entry->data, &foe, sizeof(entry->data));
267 entry->wed_index = wed_index;
268
269 - err = mtk_foe_entry_commit(eth->ppe, entry);
270 + err = mtk_foe_entry_commit(eth->ppe[entry->ppe_index], entry);
271 if (err < 0)
272 goto free;
273
274 @@ -446,7 +446,7 @@ mtk_flow_offload_replace(struct mtk_eth
275 return 0;
276
277 clear:
278 - mtk_foe_entry_clear(eth->ppe, entry);
279 + mtk_foe_entry_clear(eth->ppe[entry->ppe_index], entry);
280 free:
281 kfree(entry);
282 if (wed_index >= 0)
283 @@ -464,7 +464,7 @@ mtk_flow_offload_destroy(struct mtk_eth
284 if (!entry)
285 return -ENOENT;
286
287 - mtk_foe_entry_clear(eth->ppe, entry);
288 + mtk_foe_entry_clear(eth->ppe[entry->ppe_index], entry);
289 rhashtable_remove_fast(&eth->flow_table, &entry->node,
290 mtk_flow_ht_params);
291 if (entry->wed_index >= 0)
292 @@ -485,7 +485,7 @@ mtk_flow_offload_stats(struct mtk_eth *e
293 if (!entry)
294 return -ENOENT;
295
296 - idle = mtk_foe_entry_idle_time(eth->ppe, entry);
297 + idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry);
298 f->stats.lastused = jiffies - idle * HZ;
299
300 return 0;
301 @@ -537,7 +537,7 @@ mtk_eth_setup_tc_block(struct net_device
302 struct flow_block_cb *block_cb;
303 flow_setup_cb_t *cb;
304
305 - if (!eth->ppe || !eth->ppe->foe_table)
306 + if (!eth->soc->offload_version)
307 return -EOPNOTSUPP;
308
309 if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
310 @@ -590,8 +590,5 @@ int mtk_eth_setup_tc(struct net_device *
311
312 int mtk_eth_offload_init(struct mtk_eth *eth)
313 {
314 - if (!eth->ppe || !eth->ppe->foe_table)
315 - return 0;
316 -
317 return rhashtable_init(&eth->flow_table, &mtk_flow_ht_params);
318 }