ipq-wifi: add BDF for Aruba AP-303
[openwrt/openwrt.git] / target / linux / ipq40xx / patches-4.19 / 712-mr33-essedma.patch
1 --- a/drivers/net/ethernet/qualcomm/essedma/edma.c
2 +++ b/drivers/net/ethernet/qualcomm/essedma/edma.c
3 @@ -161,8 +161,10 @@ static void edma_configure_rx(struct edm
4 /* Set Rx FIFO threshold to start to DMA data to host */
5 rxq_ctrl_data = EDMA_FIFO_THRESH_128_BYTE;
6
7 + if (!edma_cinfo->is_single_phy) {
8 /* Set RX remove vlan bit */
9 rxq_ctrl_data |= EDMA_RXQ_CTRL_RMV_VLAN;
10 + }
11
12 edma_write_reg(EDMA_REG_RXQ_CTRL, rxq_ctrl_data);
13 }
14 @@ -1293,6 +1295,10 @@ void edma_adjust_link(struct net_device
15 if (status == __EDMA_LINKUP && adapter->link_state == __EDMA_LINKDOWN) {
16 dev_info(&adapter->pdev->dev, "%s: GMAC Link is up with phy_speed=%d\n", netdev->name, phydev->speed);
17 adapter->link_state = __EDMA_LINKUP;
18 + if (adapter->edma_cinfo->is_single_phy) {
19 + ess_set_port_status_speed(adapter->edma_cinfo, phydev,
20 + ffs(adapter->dp_bitmap) - 1);
21 + }
22 netif_carrier_on(netdev);
23 if (netif_running(netdev))
24 netif_tx_wake_all_queues(netdev);
25 @@ -1386,10 +1392,12 @@ netdev_tx_t edma_xmit(struct sk_buff *sk
26 }
27
28 /* Check and mark VLAN tag offload */
29 - if (skb_vlan_tag_present(skb))
30 - flags_transmit |= EDMA_VLAN_TX_TAG_INSERT_FLAG;
31 - else if (adapter->default_vlan_tag)
32 - flags_transmit |= EDMA_VLAN_TX_TAG_INSERT_DEFAULT_FLAG;
33 + if (!adapter->edma_cinfo->is_single_phy) {
34 + if (unlikely(skb_vlan_tag_present(skb)))
35 + flags_transmit |= EDMA_VLAN_TX_TAG_INSERT_FLAG;
36 + else if (adapter->default_vlan_tag)
37 + flags_transmit |= EDMA_VLAN_TX_TAG_INSERT_DEFAULT_FLAG;
38 + }
39
40 /* Check and mark checksum offload */
41 if (likely(skb->ip_summed == CHECKSUM_PARTIAL))
42 --- a/drivers/net/ethernet/qualcomm/essedma/edma.h
43 +++ b/drivers/net/ethernet/qualcomm/essedma/edma.h
44 @@ -31,6 +31,7 @@
45 #include <linux/platform_device.h>
46 #include <linux/of.h>
47 #include <linux/of_device.h>
48 +#include <linux/clk.h>
49 #include <linux/kernel.h>
50 #include <linux/device.h>
51 #include <linux/sysctl.h>
52 @@ -332,6 +333,9 @@ struct edma_common_info {
53 struct edma_per_cpu_queues_info edma_percpu_info[CONFIG_NR_CPUS]; /* per cpu information */
54 spinlock_t stats_lock; /* protect edma stats area for updation */
55 struct timer_list edma_stats_timer;
56 + bool is_single_phy;
57 + void __iomem *ess_hw_addr;
58 + struct clk *ess_clk;
59 };
60
61 /* transimit packet descriptor (tpd) ring */
62 @@ -444,4 +448,6 @@ void edma_change_tx_coalesce(int usecs);
63 void edma_change_rx_coalesce(int usecs);
64 void edma_get_tx_rx_coalesce(u32 *reg_val);
65 void edma_clear_irq_status(void);
66 +void ess_set_port_status_speed(struct edma_common_info *edma_cinfo,
67 + struct phy_device *phydev, uint8_t port_id);
68 #endif /* _EDMA_H_ */
69 --- a/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
70 +++ b/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
71 @@ -17,6 +17,11 @@
72 #include <linux/of.h>
73 #include <linux/of_net.h>
74 #include <linux/timer.h>
75 +#include <linux/of_platform.h>
76 +#include <linux/of_address.h>
77 +#include <linux/clk.h>
78 +#include <linux/string.h>
79 +#include <linux/reset.h>
80 #include "edma.h"
81 #include "ess_edma.h"
82
83 @@ -81,6 +86,101 @@ void edma_read_reg(u16 reg_addr, volatil
84 *reg_value = readl((void __iomem *)(edma_hw_addr + reg_addr));
85 }
86
87 +static void ess_write_reg(struct edma_common_info *edma, u16 reg_addr, u32 reg_value)
88 +{
89 + writel(reg_value, ((void __iomem *)
90 + ((unsigned long)edma->ess_hw_addr + reg_addr)));
91 +}
92 +
93 +static void ess_read_reg(struct edma_common_info *edma, u16 reg_addr,
94 + volatile u32 *reg_value)
95 +{
96 + *reg_value = readl((void __iomem *)
97 + ((unsigned long)edma->ess_hw_addr + reg_addr));
98 +}
99 +
100 +static int ess_reset(struct edma_common_info *edma)
101 +{
102 + struct device_node *switch_node = NULL;
103 + struct reset_control *ess_rst;
104 + u32 regval;
105 +
106 + switch_node = of_find_node_by_name(NULL, "ess-switch");
107 + if (!switch_node) {
108 + pr_err("switch-node not found\n");
109 + return -EINVAL;
110 + }
111 +
112 + ess_rst = of_reset_control_get(switch_node, "ess_rst");
113 + of_node_put(switch_node);
114 +
115 + if (IS_ERR(ess_rst)) {
116 + pr_err("failed to find ess_rst!\n");
117 + return -ENOENT;
118 + }
119 +
120 + reset_control_assert(ess_rst);
121 + msleep(10);
122 + reset_control_deassert(ess_rst);
123 + msleep(100);
124 + reset_control_put(ess_rst);
125 +
126 + /* Enable only port 5 <--> port 0
127 + * bits 0:6 bitmap of ports it can fwd to */
128 +#define SET_PORT_BMP(r,v) \
129 + ess_read_reg(edma, r, &regval); \
130 + ess_write_reg(edma, r, ((regval & ~0x3F) | v));
131 +
132 + SET_PORT_BMP(ESS_PORT0_LOOKUP_CTRL,0x20);
133 + SET_PORT_BMP(ESS_PORT1_LOOKUP_CTRL,0x00);
134 + SET_PORT_BMP(ESS_PORT2_LOOKUP_CTRL,0x00);
135 + SET_PORT_BMP(ESS_PORT3_LOOKUP_CTRL,0x00);
136 + SET_PORT_BMP(ESS_PORT4_LOOKUP_CTRL,0x00);
137 + SET_PORT_BMP(ESS_PORT5_LOOKUP_CTRL,0x01);
138 + ess_write_reg(edma, ESS_RGMII_CTRL, 0x400);
139 + ess_write_reg(edma, ESS_PORT0_STATUS, ESS_PORT_1G_FDX);
140 + ess_write_reg(edma, ESS_PORT5_STATUS, ESS_PORT_1G_FDX);
141 + ess_write_reg(edma, ESS_PORT0_HEADER_CTRL, 0);
142 +#undef SET_PORT_BMP
143 +
144 + /* forward multicast and broadcast frames to CPU */
145 + ess_write_reg(edma, ESS_FWD_CTRL1,
146 + (ESS_PORTS_ALL << ESS_FWD_CTRL1_UC_FLOOD_S) |
147 + (ESS_PORTS_ALL << ESS_FWD_CTRL1_MC_FLOOD_S) |
148 + (ESS_PORTS_ALL << ESS_FWD_CTRL1_BC_FLOOD_S));
149 +
150 + return 0;
151 +}
152 +
153 +void ess_set_port_status_speed(struct edma_common_info *edma,
154 + struct phy_device *phydev, uint8_t port_id)
155 +{
156 + uint16_t reg_off = ESS_PORT0_STATUS + (4 * port_id);
157 + uint32_t reg_val = 0;
158 +
159 + ess_read_reg(edma, reg_off, &reg_val);
160 +
161 + /* reset the speed bits [0:1] */
162 + reg_val &= ~ESS_PORT_STATUS_SPEED_INV;
163 +
164 + /* set the new speed */
165 + switch(phydev->speed) {
166 + case SPEED_1000: reg_val |= ESS_PORT_STATUS_SPEED_1000; break;
167 + case SPEED_100: reg_val |= ESS_PORT_STATUS_SPEED_100; break;
168 + case SPEED_10: reg_val |= ESS_PORT_STATUS_SPEED_10; break;
169 + default: reg_val |= ESS_PORT_STATUS_SPEED_INV; break;
170 + }
171 +
172 + /* check full/half duplex */
173 + if (phydev->duplex) {
174 + reg_val |= ESS_PORT_STATUS_DUPLEX_MODE;
175 + } else {
176 + reg_val &= ~ESS_PORT_STATUS_DUPLEX_MODE;
177 + }
178 +
179 + ess_write_reg(edma, reg_off, reg_val);
180 +}
181 +
182 /* edma_change_tx_coalesce()
183 * change tx interrupt moderation timer
184 */
185 @@ -550,6 +650,31 @@ static struct ctl_table edma_table[] = {
186 {}
187 };
188
189 +static int ess_parse(struct edma_common_info *edma)
190 +{
191 + struct device_node *switch_node;
192 + int ret = -EINVAL;
193 +
194 + switch_node = of_find_node_by_name(NULL, "ess-switch");
195 + if (!switch_node) {
196 + pr_err("cannot find ess-switch node\n");
197 + goto out;
198 + }
199 +
200 + edma->ess_hw_addr = of_io_request_and_map(switch_node,
201 + 0, KBUILD_MODNAME);
202 + if (!edma->ess_hw_addr) {
203 + pr_err("%s ioremap fail.", __func__);
204 + goto out;
205 + }
206 +
207 + edma->ess_clk = of_clk_get_by_name(switch_node, "ess_clk");
208 + ret = clk_prepare_enable(edma->ess_clk);
209 +out:
210 + of_node_put(switch_node);
211 + return ret;
212 +}
213 +
214 /* edma_axi_netdev_ops
215 * Describe the operations supported by registered netdevices
216 *
217 @@ -785,6 +910,17 @@ static int edma_axi_probe(struct platfor
218 miibus = mdio_data->mii_bus;
219 }
220
221 + if (of_property_read_bool(np, "qcom,single-phy") &&
222 + edma_cinfo->num_gmac == 1) {
223 + err = ess_parse(edma_cinfo);
224 + if (!err)
225 + err = ess_reset(edma_cinfo);
226 + if (err)
227 + goto err_single_phy_init;
228 + else
229 + edma_cinfo->is_single_phy = true;
230 + }
231 +
232 for_each_available_child_of_node(np, pnp) {
233 const char *mac_addr;
234
235 @@ -1073,11 +1209,15 @@ static int edma_axi_probe(struct platfor
236
237 for (i = 0; i < edma_cinfo->num_gmac; i++) {
238 if (adapter[i]->poll_required) {
239 + int phy_mode = of_get_phy_mode(np);
240 +
241 + if (phy_mode < 0)
242 + phy_mode = PHY_INTERFACE_MODE_SGMII;
243 adapter[i]->phydev =
244 phy_connect(edma_netdev[i],
245 (const char *)adapter[i]->phy_id,
246 &edma_adjust_link,
247 - PHY_INTERFACE_MODE_SGMII);
248 + phy_mode);
249 if (IS_ERR(adapter[i]->phydev)) {
250 dev_dbg(&pdev->dev, "PHY attach FAIL");
251 err = -EIO;
252 @@ -1121,6 +1261,9 @@ err_rmap_alloc_fail:
253 for (i = 0; i < edma_cinfo->num_gmac; i++)
254 unregister_netdev(edma_netdev[i]);
255 err_register:
256 +err_single_phy_init:
257 + iounmap(edma_cinfo->ess_hw_addr);
258 + clk_disable_unprepare(edma_cinfo->ess_clk);
259 err_mdiobus_init_fail:
260 edma_free_rx_rings(edma_cinfo);
261 err_rx_rinit:
262 @@ -1181,6 +1324,8 @@ static int edma_axi_remove(struct platfo
263 del_timer_sync(&edma_cinfo->edma_stats_timer);
264 edma_free_irqs(adapter);
265 unregister_net_sysctl_table(edma_cinfo->edma_ctl_table_hdr);
266 + iounmap(edma_cinfo->ess_hw_addr);
267 + clk_disable_unprepare(edma_cinfo->ess_clk);
268 edma_free_tx_resources(edma_cinfo);
269 edma_free_rx_resources(edma_cinfo);
270 edma_free_tx_rings(edma_cinfo);
271 --- a/drivers/net/ethernet/qualcomm/essedma/ess_edma.h
272 +++ b/drivers/net/ethernet/qualcomm/essedma/ess_edma.h
273 @@ -329,4 +329,61 @@ struct edma_hw;
274 #define EDMA_RRD_PRIORITY_MASK 0x7
275 #define EDMA_RRD_PORT_TYPE_SHIFT 7
276 #define EDMA_RRD_PORT_TYPE_MASK 0x1F
277 +
278 +#define ESS_RGMII_CTRL 0x0004
279 +
280 +/* Port status registers */
281 +#define ESS_PORT0_STATUS 0x007C
282 +#define ESS_PORT1_STATUS 0x0080
283 +#define ESS_PORT2_STATUS 0x0084
284 +#define ESS_PORT3_STATUS 0x0088
285 +#define ESS_PORT4_STATUS 0x008C
286 +#define ESS_PORT5_STATUS 0x0090
287 +
288 +#define ESS_PORT_STATUS_HDX_FLOW_CTL 0x80
289 +#define ESS_PORT_STATUS_DUPLEX_MODE 0x40
290 +#define ESS_PORT_STATUS_RX_FLOW_EN 0x20
291 +#define ESS_PORT_STATUS_TX_FLOW_EN 0x10
292 +#define ESS_PORT_STATUS_RX_MAC_EN 0x08
293 +#define ESS_PORT_STATUS_TX_MAC_EN 0x04
294 +#define ESS_PORT_STATUS_SPEED_INV 0x03
295 +#define ESS_PORT_STATUS_SPEED_1000 0x02
296 +#define ESS_PORT_STATUS_SPEED_100 0x01
297 +#define ESS_PORT_STATUS_SPEED_10 0x00
298 +
299 +#define ESS_PORT_1G_FDX (ESS_PORT_STATUS_DUPLEX_MODE | ESS_PORT_STATUS_RX_FLOW_EN | \
300 + ESS_PORT_STATUS_TX_FLOW_EN | ESS_PORT_STATUS_RX_MAC_EN | \
301 + ESS_PORT_STATUS_TX_MAC_EN | ESS_PORT_STATUS_SPEED_1000)
302 +
303 +#define PHY_STATUS_REG 0x11
304 +#define PHY_STATUS_SPEED 0xC000
305 +#define PHY_STATUS_SPEED_SHIFT 14
306 +#define PHY_STATUS_DUPLEX 0x2000
307 +#define PHY_STATUS_DUPLEX_SHIFT 13
308 +#define PHY_STATUS_SPEED_DUPLEX_RESOLVED 0x0800
309 +#define PHY_STATUS_CARRIER 0x0400
310 +#define PHY_STATUS_CARRIER_SHIFT 10
311 +
312 +/* Port lookup control registers */
313 +#define ESS_PORT0_LOOKUP_CTRL 0x0660
314 +#define ESS_PORT1_LOOKUP_CTRL 0x066C
315 +#define ESS_PORT2_LOOKUP_CTRL 0x0678
316 +#define ESS_PORT3_LOOKUP_CTRL 0x0684
317 +#define ESS_PORT4_LOOKUP_CTRL 0x0690
318 +#define ESS_PORT5_LOOKUP_CTRL 0x069C
319 +
320 +#define ESS_PORT0_HEADER_CTRL 0x009C
321 +
322 +#define ESS_PORTS_ALL 0x3f
323 +
324 +#define ESS_FWD_CTRL1 0x0624
325 +#define ESS_FWD_CTRL1_UC_FLOOD BITS(0, 7)
326 +#define ESS_FWD_CTRL1_UC_FLOOD_S 0
327 +#define ESS_FWD_CTRL1_MC_FLOOD BITS(8, 7)
328 +#define ESS_FWD_CTRL1_MC_FLOOD_S 8
329 +#define ESS_FWD_CTRL1_BC_FLOOD BITS(16, 7)
330 +#define ESS_FWD_CTRL1_BC_FLOOD_S 16
331 +#define ESS_FWD_CTRL1_IGMP BITS(24, 7)
332 +#define ESS_FWD_CTRL1_IGMP_S 24
333 +
334 #endif /* _ESS_EDMA_H_ */