forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-04 1543e317f1da31b75942316931e8f491a8920811
kernel/drivers/net/ethernet/hisilicon/hip04_eth.c
....@@ -1,11 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12
23 /* Copyright (c) 2014 Linaro Ltd.
34 * Copyright (c) 2014 Hisilicon Limited.
4
- *
5
- * This program is free software; you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License as published by
7
- * the Free Software Foundation; either version 2 of the License, or
8
- * (at your option) any later version.
95 */
106
117 #include <linux/module.h>
....@@ -19,6 +15,8 @@
1915 #include <linux/of_net.h>
2016 #include <linux/mfd/syscon.h>
2117 #include <linux/regmap.h>
18
+
19
+#define SC_PPE_RESET_DREQ 0x026C
2220
2321 #define PPE_CFG_RX_ADDR 0x100
2422 #define PPE_CFG_POOL_GRP 0x300
....@@ -37,10 +35,23 @@
3735 #define GE_MODE_CHANGE_REG 0x1b4
3836 #define GE_RECV_CONTROL_REG 0x1e0
3937 #define GE_STATION_MAC_ADDRESS 0x210
40
-#define PPE_CFG_CPU_ADD_ADDR 0x580
41
-#define PPE_CFG_MAX_FRAME_LEN_REG 0x408
38
+
4239 #define PPE_CFG_BUS_CTRL_REG 0x424
4340 #define PPE_CFG_RX_CTRL_REG 0x428
41
+
42
+#if defined(CONFIG_HI13X1_GMAC)
43
+#define PPE_CFG_CPU_ADD_ADDR 0x6D0
44
+#define PPE_CFG_MAX_FRAME_LEN_REG 0x500
45
+#define PPE_CFG_RX_PKT_MODE_REG 0x504
46
+#define PPE_CFG_QOS_VMID_GEN 0x520
47
+#define PPE_CFG_RX_PKT_INT 0x740
48
+#define PPE_INTEN 0x700
49
+#define PPE_INTSTS 0x708
50
+#define PPE_RINT 0x704
51
+#define PPE_CFG_STS_MODE 0x880
52
+#else
53
+#define PPE_CFG_CPU_ADD_ADDR 0x580
54
+#define PPE_CFG_MAX_FRAME_LEN_REG 0x408
4455 #define PPE_CFG_RX_PKT_MODE_REG 0x438
4556 #define PPE_CFG_QOS_VMID_GEN 0x500
4657 #define PPE_CFG_RX_PKT_INT 0x538
....@@ -48,7 +59,11 @@
4859 #define PPE_INTSTS 0x608
4960 #define PPE_RINT 0x604
5061 #define PPE_CFG_STS_MODE 0x700
62
+#endif /* CONFIG_HI13X1_GMAC */
63
+
5164 #define PPE_HIS_RX_PKT_CNT 0x804
65
+
66
+#define RESET_DREQ_ALL 0xffffffff
5267
5368 /* REG_INTERRUPT */
5469 #define RCV_INT BIT(10)
....@@ -61,8 +76,15 @@
6176 /* TX descriptor config */
6277 #define TX_FREE_MEM BIT(0)
6378 #define TX_READ_ALLOC_L3 BIT(1)
64
-#define TX_FINISH_CACHE_INV BIT(2)
79
+#if defined(CONFIG_HI13X1_GMAC)
80
+#define TX_CLEAR_WB BIT(7)
81
+#define TX_RELEASE_TO_PPE BIT(4)
82
+#define TX_FINISH_CACHE_INV BIT(6)
83
+#define TX_POOL_SHIFT 16
84
+#else
6585 #define TX_CLEAR_WB BIT(4)
86
+#define TX_FINISH_CACHE_INV BIT(2)
87
+#endif
6688 #define TX_L3_CHECKSUM BIT(5)
6789 #define TX_LOOP_BACK BIT(11)
6890
....@@ -97,18 +119,35 @@
97119 #define GE_RX_PORT_EN BIT(1)
98120 #define GE_TX_PORT_EN BIT(2)
99121
100
-#define PPE_CFG_STS_RX_PKT_CNT_RC BIT(12)
101
-
102122 #define PPE_CFG_RX_PKT_ALIGN BIT(18)
103
-#define PPE_CFG_QOS_VMID_MODE BIT(14)
123
+
124
+#if defined(CONFIG_HI13X1_GMAC)
125
+#define PPE_CFG_QOS_VMID_GRP_SHIFT 4
126
+#define PPE_CFG_RX_CTRL_ALIGN_SHIFT 7
127
+#define PPE_CFG_STS_RX_PKT_CNT_RC BIT(0)
128
+#define PPE_CFG_QOS_VMID_MODE BIT(15)
129
+#define PPE_CFG_BUS_LOCAL_REL (BIT(9) | BIT(15) | BIT(19) | BIT(23))
130
+
131
+/* buf unit size is cache_line_size, which is 64, so the shift is 6 */
132
+#define PPE_BUF_SIZE_SHIFT 6
133
+#define PPE_TX_BUF_HOLD BIT(31)
134
+#define SOC_CACHE_LINE_MASK 0x3F
135
+#else
104136 #define PPE_CFG_QOS_VMID_GRP_SHIFT 8
137
+#define PPE_CFG_RX_CTRL_ALIGN_SHIFT 11
138
+#define PPE_CFG_STS_RX_PKT_CNT_RC BIT(12)
139
+#define PPE_CFG_QOS_VMID_MODE BIT(14)
140
+#define PPE_CFG_BUS_LOCAL_REL BIT(14)
141
+
142
+/* buf unit size is 1, so the shift is 6 */
143
+#define PPE_BUF_SIZE_SHIFT 0
144
+#define PPE_TX_BUF_HOLD 0
145
+#endif /* CONFIG_HI13X1_GMAC */
105146
106147 #define PPE_CFG_RX_FIFO_FSFU BIT(11)
107148 #define PPE_CFG_RX_DEPTH_SHIFT 16
108149 #define PPE_CFG_RX_START_SHIFT 0
109
-#define PPE_CFG_RX_CTRL_ALIGN_SHIFT 11
110150
111
-#define PPE_CFG_BUS_LOCAL_REL BIT(14)
112151 #define PPE_CFG_BUS_BIG_ENDIEN BIT(0)
113152
114153 #define RX_DESC_NUM 128
....@@ -132,26 +171,50 @@
132171 #define HIP04_MIN_TX_COALESCE_FRAMES 100
133172
134173 struct tx_desc {
174
+#if defined(CONFIG_HI13X1_GMAC)
175
+ u32 reserved1[2];
176
+ u32 send_addr;
177
+ u16 send_size;
178
+ u16 data_offset;
179
+ u32 reserved2[7];
180
+ u32 cfg;
181
+ u32 wb_addr;
182
+ u32 reserved3[3];
183
+#else
135184 u32 send_addr;
136185 u32 send_size;
137186 u32 next_addr;
138187 u32 cfg;
139188 u32 wb_addr;
189
+#endif
140190 } __aligned(64);
141191
142192 struct rx_desc {
193
+#if defined(CONFIG_HI13X1_GMAC)
194
+ u32 reserved1[3];
195
+ u16 pkt_len;
196
+ u16 reserved_16;
197
+ u32 reserved2[6];
198
+ u32 pkt_err;
199
+ u32 reserved3[5];
200
+#else
143201 u16 reserved_16;
144202 u16 pkt_len;
145203 u32 reserve1[3];
146204 u32 pkt_err;
147205 u32 reserve2[4];
206
+#endif
148207 };
149208
150209 struct hip04_priv {
151210 void __iomem *base;
152
- int phy_mode;
211
+#if defined(CONFIG_HI13X1_GMAC)
212
+ void __iomem *sysctrl_base;
213
+#endif
214
+ phy_interface_t phy_mode;
153215 int chan;
154216 unsigned int port;
217
+ unsigned int group;
155218 unsigned int speed;
156219 unsigned int duplex;
157220 unsigned int reg_inten;
....@@ -227,6 +290,13 @@
227290 writel_relaxed(val, priv->base + GE_MODE_CHANGE_REG);
228291 }
229292
293
+static void hip04_reset_dreq(struct hip04_priv *priv)
294
+{
295
+#if defined(CONFIG_HI13X1_GMAC)
296
+ writel_relaxed(RESET_DREQ_ALL, priv->sysctrl_base + SC_PPE_RESET_DREQ);
297
+#endif
298
+}
299
+
230300 static void hip04_reset_ppe(struct hip04_priv *priv)
231301 {
232302 u32 val, tmp, timeout = 0;
....@@ -247,14 +317,14 @@
247317 val |= PPE_CFG_STS_RX_PKT_CNT_RC;
248318 writel_relaxed(val, priv->base + PPE_CFG_STS_MODE);
249319
250
- val = BIT(priv->port);
320
+ val = BIT(priv->group);
251321 regmap_write(priv->map, priv->port * 4 + PPE_CFG_POOL_GRP, val);
252322
253
- val = priv->port << PPE_CFG_QOS_VMID_GRP_SHIFT;
323
+ val = priv->group << PPE_CFG_QOS_VMID_GRP_SHIFT;
254324 val |= PPE_CFG_QOS_VMID_MODE;
255325 writel_relaxed(val, priv->base + PPE_CFG_QOS_VMID_GEN);
256326
257
- val = RX_BUF_SIZE;
327
+ val = RX_BUF_SIZE >> PPE_BUF_SIZE_SHIFT;
258328 regmap_write(priv->map, priv->port * 4 + PPE_CFG_RX_BUF_SIZE, val);
259329
260330 val = RX_DESC_NUM << PPE_CFG_RX_DEPTH_SHIFT;
....@@ -291,8 +361,10 @@
291361 val |= GE_RX_STRIP_PAD | GE_RX_PAD_EN;
292362 writel_relaxed(val, priv->base + GE_RECV_CONTROL_REG);
293363
364
+#ifndef CONFIG_HI13X1_GMAC
294365 val = GE_AUTO_NEG_CTL;
295366 writel_relaxed(val, priv->base + GE_TX_LOCAL_PAGE_REG);
367
+#endif
296368 }
297369
298370 static void hip04_mac_enable(struct net_device *ndev)
....@@ -335,12 +407,18 @@
335407
336408 static void hip04_set_xmit_desc(struct hip04_priv *priv, dma_addr_t phys)
337409 {
338
- writel(phys, priv->base + PPE_CFG_CPU_ADD_ADDR);
410
+ u32 val;
411
+
412
+ val = phys >> PPE_BUF_SIZE_SHIFT | PPE_TX_BUF_HOLD;
413
+ writel(val, priv->base + PPE_CFG_CPU_ADD_ADDR);
339414 }
340415
341416 static void hip04_set_recv_desc(struct hip04_priv *priv, dma_addr_t phys)
342417 {
343
- regmap_write(priv->map, priv->port * 4 + PPE_CFG_RX_ADDR, phys);
418
+ u32 val;
419
+
420
+ val = phys >> PPE_BUF_SIZE_SHIFT;
421
+ regmap_write(priv->map, priv->port * 4 + PPE_CFG_RX_ADDR, val);
344422 }
345423
346424 static u32 hip04_recv_cnt(struct hip04_priv *priv)
....@@ -448,11 +526,20 @@
448526
449527 priv->tx_skb[tx_head] = skb;
450528 priv->tx_phys[tx_head] = phys;
451
- desc->send_addr = cpu_to_be32(phys);
452
- desc->send_size = cpu_to_be32(skb->len);
453
- desc->cfg = cpu_to_be32(TX_CLEAR_WB | TX_FINISH_CACHE_INV);
529
+
530
+ desc->send_size = (__force u32)cpu_to_be32(skb->len);
531
+#if defined(CONFIG_HI13X1_GMAC)
532
+ desc->cfg = (__force u32)cpu_to_be32(TX_CLEAR_WB | TX_FINISH_CACHE_INV
533
+ | TX_RELEASE_TO_PPE | priv->port << TX_POOL_SHIFT);
534
+ desc->data_offset = (__force u32)cpu_to_be32(phys & SOC_CACHE_LINE_MASK);
535
+ desc->send_addr = (__force u32)cpu_to_be32(phys & ~SOC_CACHE_LINE_MASK);
536
+#else
537
+ desc->cfg = (__force u32)cpu_to_be32(TX_CLEAR_WB | TX_FINISH_CACHE_INV);
538
+ desc->send_addr = (__force u32)cpu_to_be32(phys);
539
+#endif
454540 phys = priv->tx_desc_dma + tx_head * sizeof(struct tx_desc);
455
- desc->wb_addr = cpu_to_be32(phys);
541
+ desc->wb_addr = (__force u32)cpu_to_be32(phys +
542
+ offsetof(struct tx_desc, send_addr));
456543 skb_tx_timestamp(skb);
457544
458545 hip04_set_xmit_desc(priv, phys);
....@@ -515,8 +602,8 @@
515602 priv->rx_phys[priv->rx_head] = 0;
516603
517604 desc = (struct rx_desc *)skb->data;
518
- len = be16_to_cpu(desc->pkt_len);
519
- err = be32_to_cpu(desc->pkt_err);
605
+ len = be16_to_cpu((__force __be16)desc->pkt_len);
606
+ err = be32_to_cpu((__force __be32)desc->pkt_err);
520607
521608 if (0 == len) {
522609 dev_kfree_skb_any(skb);
....@@ -692,7 +779,7 @@
692779 return 0;
693780 }
694781
695
-static void hip04_timeout(struct net_device *ndev)
782
+static void hip04_timeout(struct net_device *ndev, unsigned int txqueue)
696783 {
697784 struct hip04_priv *priv = netdev_priv(ndev);
698785
....@@ -724,20 +811,6 @@
724811 {
725812 struct hip04_priv *priv = netdev_priv(netdev);
726813
727
- /* Check not supported parameters */
728
- if ((ec->rx_max_coalesced_frames) || (ec->rx_coalesce_usecs_irq) ||
729
- (ec->rx_max_coalesced_frames_irq) || (ec->tx_coalesce_usecs_irq) ||
730
- (ec->use_adaptive_rx_coalesce) || (ec->use_adaptive_tx_coalesce) ||
731
- (ec->pkt_rate_low) || (ec->rx_coalesce_usecs_low) ||
732
- (ec->rx_max_coalesced_frames_low) || (ec->tx_coalesce_usecs_high) ||
733
- (ec->tx_max_coalesced_frames_low) || (ec->pkt_rate_high) ||
734
- (ec->tx_coalesce_usecs_low) || (ec->rx_coalesce_usecs_high) ||
735
- (ec->rx_max_coalesced_frames_high) || (ec->rx_coalesce_usecs) ||
736
- (ec->tx_max_coalesced_frames_irq) ||
737
- (ec->stats_block_coalesce_usecs) ||
738
- (ec->tx_max_coalesced_frames_high) || (ec->rate_sample_interval))
739
- return -EOPNOTSUPP;
740
-
741814 if ((ec->tx_coalesce_usecs > HIP04_MAX_TX_COALESCE_USECS ||
742815 ec->tx_coalesce_usecs < HIP04_MIN_TX_COALESCE_USECS) ||
743816 (ec->tx_max_coalesced_frames > HIP04_MAX_TX_COALESCE_FRAMES ||
....@@ -758,6 +831,8 @@
758831 }
759832
760833 static const struct ethtool_ops hip04_ethtool_ops = {
834
+ .supported_coalesce_params = ETHTOOL_COALESCE_TX_USECS |
835
+ ETHTOOL_COALESCE_TX_MAX_FRAMES,
761836 .get_coalesce = hip04_get_coalesce,
762837 .set_coalesce = hip04_set_coalesce,
763838 .get_drvinfo = hip04_get_drvinfo,
....@@ -818,7 +893,6 @@
818893 struct of_phandle_args arg;
819894 struct net_device *ndev;
820895 struct hip04_priv *priv;
821
- struct resource *res;
822896 int irq;
823897 int ret;
824898
....@@ -832,14 +906,21 @@
832906 platform_set_drvdata(pdev, ndev);
833907 SET_NETDEV_DEV(ndev, &pdev->dev);
834908
835
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
836
- priv->base = devm_ioremap_resource(d, res);
909
+ priv->base = devm_platform_ioremap_resource(pdev, 0);
837910 if (IS_ERR(priv->base)) {
838911 ret = PTR_ERR(priv->base);
839912 goto init_fail;
840913 }
841914
842
- ret = of_parse_phandle_with_fixed_args(node, "port-handle", 2, 0, &arg);
915
+#if defined(CONFIG_HI13X1_GMAC)
916
+ priv->sysctrl_base = devm_platform_ioremap_resource(pdev, 1);
917
+ if (IS_ERR(priv->sysctrl_base)) {
918
+ ret = PTR_ERR(priv->sysctrl_base);
919
+ goto init_fail;
920
+ }
921
+#endif
922
+
923
+ ret = of_parse_phandle_with_fixed_args(node, "port-handle", 3, 0, &arg);
843924 if (ret < 0) {
844925 dev_warn(d, "no port-handle\n");
845926 goto init_fail;
....@@ -847,6 +928,7 @@
847928
848929 priv->port = arg.args[0];
849930 priv->chan = arg.args[1] * RX_DESC_NUM;
931
+ priv->group = arg.args[2];
850932
851933 hrtimer_init(&priv->tx_coalesce_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
852934
....@@ -867,10 +949,9 @@
867949 goto init_fail;
868950 }
869951
870
- priv->phy_mode = of_get_phy_mode(node);
871
- if (priv->phy_mode < 0) {
952
+ ret = of_get_phy_mode(node, &priv->phy_mode);
953
+ if (ret) {
872954 dev_warn(d, "not find phy-mode\n");
873
- ret = -EINVAL;
874955 goto init_fail;
875956 }
876957
....@@ -907,6 +988,7 @@
907988 ndev->irq = irq;
908989 netif_napi_add(ndev, &priv->napi, hip04_rx_poll, NAPI_POLL_WEIGHT);
909990
991
+ hip04_reset_dreq(priv);
910992 hip04_reset_ppe(priv);
911993 if (priv->phy_mode == PHY_INTERFACE_MODE_MII)
912994 hip04_config_port(ndev, SPEED_100, DUPLEX_FULL);