OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
4 | office | 1 | /* This program is free software; you can redistribute it and/or modify |
2 | * it under the terms of the GNU General Public License as published by |
||
3 | * the Free Software Foundation; version 2 of the License |
||
4 | * |
||
5 | * This program is distributed in the hope that it will be useful, |
||
6 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
7 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
8 | * GNU General Public License for more details. |
||
9 | * |
||
10 | * Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org> |
||
11 | * Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name> |
||
12 | * Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com> |
||
13 | */ |
||
14 | |||
15 | #include <linux/module.h> |
||
16 | #include <linux/platform_device.h> |
||
17 | #include <linux/if_vlan.h> |
||
18 | #include <linux/of_net.h> |
||
19 | |||
20 | #include <asm/mach-ralink/ralink_regs.h> |
||
21 | |||
22 | #include "mtk_eth_soc.h" |
||
23 | #include "gsw_mt7620.h" |
||
24 | #include "mt7530.h" |
||
25 | #include "mdio.h" |
||
26 | |||
27 | #define MT7620A_CDMA_CSG_CFG 0x400 |
||
28 | #define MT7621_CDMP_IG_CTRL (MT7620A_CDMA_CSG_CFG + 0x00) |
||
29 | #define MT7621_CDMP_EG_CTRL (MT7620A_CDMA_CSG_CFG + 0x04) |
||
30 | #define MT7621_RESET_FE BIT(6) |
||
31 | #define MT7621_L4_VALID BIT(24) |
||
32 | |||
33 | #define MT7621_TX_DMA_UDF BIT(19) |
||
34 | #define MT7621_TX_DMA_FPORT BIT(25) |
||
35 | |||
36 | #define CDMA_ICS_EN BIT(2) |
||
37 | #define CDMA_UCS_EN BIT(1) |
||
38 | #define CDMA_TCS_EN BIT(0) |
||
39 | |||
40 | #define GDMA_ICS_EN BIT(22) |
||
41 | #define GDMA_TCS_EN BIT(21) |
||
42 | #define GDMA_UCS_EN BIT(20) |
||
43 | |||
44 | /* frame engine counters */ |
||
45 | #define MT7621_REG_MIB_OFFSET 0x2000 |
||
46 | #define MT7621_PPE_AC_BCNT0 (MT7621_REG_MIB_OFFSET + 0x00) |
||
47 | #define MT7621_GDM1_TX_GBCNT (MT7621_REG_MIB_OFFSET + 0x400) |
||
48 | #define MT7621_GDM2_TX_GBCNT (MT7621_GDM1_TX_GBCNT + 0x40) |
||
49 | |||
50 | #define GSW_REG_GDMA1_MAC_ADRL 0x508 |
||
51 | #define GSW_REG_GDMA1_MAC_ADRH 0x50C |
||
52 | |||
53 | #define MT7621_FE_RST_GL (FE_FE_OFFSET + 0x04) |
||
54 | #define MT7620_FE_INT_STATUS2 (FE_FE_OFFSET + 0x08) |
||
55 | |||
56 | /* FE_INT_STATUS reg on mt7620 define CNT_GDM1_AF at BIT(29) |
||
57 | * but after test it should be BIT(13). |
||
58 | */ |
||
59 | #define MT7620_FE_GDM1_AF BIT(13) |
||
60 | #define MT7621_FE_GDM1_AF BIT(28) |
||
61 | #define MT7621_FE_GDM2_AF BIT(29) |
||
62 | |||
63 | static const u16 mt7621_reg_table[FE_REG_COUNT] = { |
||
64 | [FE_REG_PDMA_GLO_CFG] = RT5350_PDMA_GLO_CFG, |
||
65 | [FE_REG_PDMA_RST_CFG] = RT5350_PDMA_RST_CFG, |
||
66 | [FE_REG_DLY_INT_CFG] = RT5350_DLY_INT_CFG, |
||
67 | [FE_REG_TX_BASE_PTR0] = RT5350_TX_BASE_PTR0, |
||
68 | [FE_REG_TX_MAX_CNT0] = RT5350_TX_MAX_CNT0, |
||
69 | [FE_REG_TX_CTX_IDX0] = RT5350_TX_CTX_IDX0, |
||
70 | [FE_REG_TX_DTX_IDX0] = RT5350_TX_DTX_IDX0, |
||
71 | [FE_REG_RX_BASE_PTR0] = RT5350_RX_BASE_PTR0, |
||
72 | [FE_REG_RX_MAX_CNT0] = RT5350_RX_MAX_CNT0, |
||
73 | [FE_REG_RX_CALC_IDX0] = RT5350_RX_CALC_IDX0, |
||
74 | [FE_REG_RX_DRX_IDX0] = RT5350_RX_DRX_IDX0, |
||
75 | [FE_REG_FE_INT_ENABLE] = RT5350_FE_INT_ENABLE, |
||
76 | [FE_REG_FE_INT_STATUS] = RT5350_FE_INT_STATUS, |
||
77 | [FE_REG_FE_DMA_VID_BASE] = 0, |
||
78 | [FE_REG_FE_COUNTER_BASE] = MT7621_GDM1_TX_GBCNT, |
||
79 | [FE_REG_FE_RST_GL] = MT7621_FE_RST_GL, |
||
80 | [FE_REG_FE_INT_STATUS2] = MT7620_FE_INT_STATUS2, |
||
81 | }; |
||
82 | |||
83 | static int mt7621_gsw_config(struct fe_priv *priv) |
||
84 | { |
||
85 | if (priv->mii_bus && mdiobus_get_phy(priv->mii_bus, 0x1f)) |
||
86 | mt7530_probe(priv->dev, NULL, priv->mii_bus, 1); |
||
87 | |||
88 | return 0; |
||
89 | } |
||
90 | |||
91 | static void mt7621_fe_reset(void) |
||
92 | { |
||
93 | fe_reset(MT7621_RESET_FE); |
||
94 | } |
||
95 | |||
96 | static void mt7621_rxcsum_config(bool enable) |
||
97 | { |
||
98 | if (enable) |
||
99 | fe_w32(fe_r32(MT7620A_GDMA1_FWD_CFG) | (GDMA_ICS_EN | |
||
100 | GDMA_TCS_EN | GDMA_UCS_EN), |
||
101 | MT7620A_GDMA1_FWD_CFG); |
||
102 | else |
||
103 | fe_w32(fe_r32(MT7620A_GDMA1_FWD_CFG) & ~(GDMA_ICS_EN | |
||
104 | GDMA_TCS_EN | GDMA_UCS_EN), |
||
105 | MT7620A_GDMA1_FWD_CFG); |
||
106 | } |
||
107 | |||
108 | static void mt7621_rxvlan_config(bool enable) |
||
109 | { |
||
110 | if (enable) |
||
111 | fe_w32(1, MT7621_CDMP_EG_CTRL); |
||
112 | else |
||
113 | fe_w32(0, MT7621_CDMP_EG_CTRL); |
||
114 | } |
||
115 | |||
116 | static int mt7621_fwd_config(struct fe_priv *priv) |
||
117 | { |
||
118 | struct net_device *dev = priv_netdev(priv); |
||
119 | |||
120 | fe_w32(fe_r32(MT7620A_GDMA1_FWD_CFG) & ~0xffff, |
||
121 | MT7620A_GDMA1_FWD_CFG); |
||
122 | |||
123 | /* mt7621 doesn't have txcsum config */ |
||
124 | mt7621_rxcsum_config((dev->features & NETIF_F_RXCSUM)); |
||
125 | mt7621_rxvlan_config(priv->flags & FE_FLAG_RX_VLAN_CTAG); |
||
126 | |||
127 | return 0; |
||
128 | } |
||
129 | |||
130 | static void mt7621_tx_dma(struct fe_tx_dma *txd) |
||
131 | { |
||
132 | txd->txd4 = MT7621_TX_DMA_FPORT; |
||
133 | } |
||
134 | |||
135 | static void mt7621_init_data(struct fe_soc_data *data, |
||
136 | struct net_device *netdev) |
||
137 | { |
||
138 | struct fe_priv *priv = netdev_priv(netdev); |
||
139 | |||
140 | priv->flags = FE_FLAG_PADDING_64B | FE_FLAG_RX_2B_OFFSET | |
||
141 | FE_FLAG_RX_SG_DMA | FE_FLAG_NAPI_WEIGHT | |
||
142 | FE_FLAG_HAS_SWITCH | FE_FLAG_JUMBO_FRAME; |
||
143 | |||
144 | netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | |
||
145 | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_SG | NETIF_F_TSO | |
||
146 | NETIF_F_TSO6 | NETIF_F_IPV6_CSUM; |
||
147 | } |
||
148 | |||
149 | static void mt7621_set_mac(struct fe_priv *priv, unsigned char *mac) |
||
150 | { |
||
151 | unsigned long flags; |
||
152 | |||
153 | spin_lock_irqsave(&priv->page_lock, flags); |
||
154 | fe_w32((mac[0] << 8) | mac[1], GSW_REG_GDMA1_MAC_ADRH); |
||
155 | fe_w32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5], |
||
156 | GSW_REG_GDMA1_MAC_ADRL); |
||
157 | spin_unlock_irqrestore(&priv->page_lock, flags); |
||
158 | } |
||
159 | |||
160 | static struct fe_soc_data mt7621_data = { |
||
161 | .init_data = mt7621_init_data, |
||
162 | .reset_fe = mt7621_fe_reset, |
||
163 | .set_mac = mt7621_set_mac, |
||
164 | .fwd_config = mt7621_fwd_config, |
||
165 | .tx_dma = mt7621_tx_dma, |
||
166 | .switch_init = mtk_gsw_init, |
||
167 | .switch_config = mt7621_gsw_config, |
||
168 | .reg_table = mt7621_reg_table, |
||
169 | .pdma_glo_cfg = FE_PDMA_SIZE_16DWORDS, |
||
170 | .rx_int = RT5350_RX_DONE_INT, |
||
171 | .tx_int = RT5350_TX_DONE_INT, |
||
172 | .status_int = (MT7621_FE_GDM1_AF | MT7621_FE_GDM2_AF), |
||
173 | .checksum_bit = MT7621_L4_VALID, |
||
174 | .has_carrier = mt7620_has_carrier, |
||
175 | .mdio_read = mt7620_mdio_read, |
||
176 | .mdio_write = mt7620_mdio_write, |
||
177 | .mdio_adjust_link = mt7620_mdio_link_adjust, |
||
178 | }; |
||
179 | |||
180 | const struct of_device_id of_fe_match[] = { |
||
181 | { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data }, |
||
182 | {}, |
||
183 | }; |
||
184 | |||
185 | MODULE_DEVICE_TABLE(of, of_fe_match); |