1 /*********************************************************************
2  * Author: Cavium Networks
3  *
4  * Contact: support@caviumnetworks.com
5  * This file is part of the OCTEON SDK
6  *
7  * Copyright (c) 2003-2007 Cavium Networks
8  *
9  * This file is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License, Version 2, as
11  * published by the Free Software Foundation.
12  *
13  * This file is distributed in the hope that it will be useful, but
14  * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
15  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
16  * NONINFRINGEMENT.  See the GNU General Public License for more
17  * details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this file; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22  * or visit http://www.gnu.org/licenses/.
23  *
24  * This file may also be available under a different license from Cavium.
25  * Contact Cavium Networks for more information
26 **********************************************************************/
27 #include <linux/kernel.h>
28 #include <linux/netdevice.h>
29 #include <linux/interrupt.h>
30 #include <linux/phy.h>
31 #include <linux/ratelimit.h>
32 #include <net/dst.h>
33 
34 #include <asm/octeon/octeon.h>
35 
36 #include "ethernet-defines.h"
37 #include "octeon-ethernet.h"
38 #include "ethernet-util.h"
39 
40 #include <asm/octeon/cvmx-helper.h>
41 
42 #include <asm/octeon/cvmx-ipd-defs.h>
43 #include <asm/octeon/cvmx-npi-defs.h>
44 #include <asm/octeon/cvmx-gmxx-defs.h>
45 
46 DEFINE_SPINLOCK(global_register_lock);
47 
48 static int number_rgmii_ports;
49 
50 static void cvm_oct_rgmii_poll(struct net_device *dev)
51 {
52 	struct octeon_ethernet *priv = netdev_priv(dev);
53 	unsigned long flags = 0;
54 	cvmx_helper_link_info_t link_info;
55 	int use_global_register_lock = (priv->phydev == NULL);
56 
57 	BUG_ON(in_interrupt());
58 	if (use_global_register_lock) {
59 		/*
60 		 * Take the global register lock since we are going to
61 		 * touch registers that affect more than one port.
62 		 */
63 		spin_lock_irqsave(&global_register_lock, flags);
64 	} else {
65 		mutex_lock(&priv->phydev->bus->mdio_lock);
66 	}
67 
68 	link_info = cvmx_helper_link_get(priv->port);
69 	if (link_info.u64 == priv->link_info) {
70 
71 		/*
72 		 * If the 10Mbps preamble workaround is supported and we're
73 		 * at 10Mbps we may need to do some special checking.
74 		 */
75 		if (USE_10MBPS_PREAMBLE_WORKAROUND && (link_info.s.speed == 10)) {
76 
77 			/*
78 			 * Read the GMXX_RXX_INT_REG[PCTERR] bit and
79 			 * see if we are getting preamble errors.
80 			 */
81 			int interface = INTERFACE(priv->port);
82 			int index = INDEX(priv->port);
83 			union cvmx_gmxx_rxx_int_reg gmxx_rxx_int_reg;
84 			gmxx_rxx_int_reg.u64 =
85 			    cvmx_read_csr(CVMX_GMXX_RXX_INT_REG
86 					  (index, interface));
87 			if (gmxx_rxx_int_reg.s.pcterr) {
88 
89 				/*
90 				 * We are getting preamble errors at
91 				 * 10Mbps.  Most likely the PHY is
92 				 * giving us packets with mis aligned
93 				 * preambles. In order to get these
94 				 * packets we need to disable preamble
95 				 * checking and do it in software.
96 				 */
97 				union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
98 				union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs;
99 
100 				/* Disable preamble checking */
101 				gmxx_rxx_frm_ctl.u64 =
102 				    cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL
103 						  (index, interface));
104 				gmxx_rxx_frm_ctl.s.pre_chk = 0;
105 				cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL
106 					       (index, interface),
107 					       gmxx_rxx_frm_ctl.u64);
108 
109 				/* Disable FCS stripping */
110 				ipd_sub_port_fcs.u64 =
111 				    cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS);
112 				ipd_sub_port_fcs.s.port_bit &=
113 				    0xffffffffull ^ (1ull << priv->port);
114 				cvmx_write_csr(CVMX_IPD_SUB_PORT_FCS,
115 					       ipd_sub_port_fcs.u64);
116 
117 				/* Clear any error bits */
118 				cvmx_write_csr(CVMX_GMXX_RXX_INT_REG
119 					       (index, interface),
120 					       gmxx_rxx_int_reg.u64);
121 				printk_ratelimited("%s: Using 10Mbps with software "
122 						   "preamble removal\n",
123 						   dev->name);
124 			}
125 		}
126 
127 		if (use_global_register_lock)
128 			spin_unlock_irqrestore(&global_register_lock, flags);
129 		else
130 			mutex_unlock(&priv->phydev->bus->mdio_lock);
131 		return;
132 	}
133 
134 	/* If the 10Mbps preamble workaround is allowed we need to on
135 	   preamble checking, FCS stripping, and clear error bits on
136 	   every speed change. If errors occur during 10Mbps operation
137 	   the above code will change this stuff */
138 	if (USE_10MBPS_PREAMBLE_WORKAROUND) {
139 
140 		union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
141 		union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs;
142 		union cvmx_gmxx_rxx_int_reg gmxx_rxx_int_reg;
143 		int interface = INTERFACE(priv->port);
144 		int index = INDEX(priv->port);
145 
146 		/* Enable preamble checking */
147 		gmxx_rxx_frm_ctl.u64 =
148 		    cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface));
149 		gmxx_rxx_frm_ctl.s.pre_chk = 1;
150 		cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface),
151 			       gmxx_rxx_frm_ctl.u64);
152 		/* Enable FCS stripping */
153 		ipd_sub_port_fcs.u64 = cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS);
154 		ipd_sub_port_fcs.s.port_bit |= 1ull << priv->port;
155 		cvmx_write_csr(CVMX_IPD_SUB_PORT_FCS, ipd_sub_port_fcs.u64);
156 		/* Clear any error bits */
157 		gmxx_rxx_int_reg.u64 =
158 		    cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(index, interface));
159 		cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, interface),
160 			       gmxx_rxx_int_reg.u64);
161 	}
162 	if (priv->phydev == NULL) {
163 		link_info = cvmx_helper_link_autoconf(priv->port);
164 		priv->link_info = link_info.u64;
165 	}
166 
167 	if (use_global_register_lock)
168 		spin_unlock_irqrestore(&global_register_lock, flags);
169 	else {
170 		mutex_unlock(&priv->phydev->bus->mdio_lock);
171 	}
172 
173 	if (priv->phydev == NULL) {
174 		/* Tell core. */
175 		if (link_info.s.link_up) {
176 			if (!netif_carrier_ok(dev))
177 				netif_carrier_on(dev);
178 			if (priv->queue != -1)
179 				printk_ratelimited("%s: %u Mbps %s duplex, "
180 						   "port %2d, queue %2d\n",
181 						   dev->name, link_info.s.speed,
182 						   (link_info.s.full_duplex) ?
183 						   "Full" : "Half",
184 						   priv->port, priv->queue);
185 			else
186 				printk_ratelimited("%s: %u Mbps %s duplex, "
187 						   "port %2d, POW\n",
188 						   dev->name, link_info.s.speed,
189 						   (link_info.s.full_duplex) ?
190 						   "Full" : "Half",
191 						   priv->port);
192 		} else {
193 			if (netif_carrier_ok(dev))
194 				netif_carrier_off(dev);
195 			printk_ratelimited("%s: Link down\n", dev->name);
196 		}
197 	}
198 }
199 
200 static irqreturn_t cvm_oct_rgmii_rml_interrupt(int cpl, void *dev_id)
201 {
202 	union cvmx_npi_rsl_int_blocks rsl_int_blocks;
203 	int index;
204 	irqreturn_t return_status = IRQ_NONE;
205 
206 	rsl_int_blocks.u64 = cvmx_read_csr(CVMX_NPI_RSL_INT_BLOCKS);
207 
208 	/* Check and see if this interrupt was caused by the GMX0 block */
209 	if (rsl_int_blocks.s.gmx0) {
210 
211 		int interface = 0;
212 		/* Loop through every port of this interface */
213 		for (index = 0;
214 		     index < cvmx_helper_ports_on_interface(interface);
215 		     index++) {
216 
217 			/* Read the GMX interrupt status bits */
218 			union cvmx_gmxx_rxx_int_reg gmx_rx_int_reg;
219 			gmx_rx_int_reg.u64 =
220 			    cvmx_read_csr(CVMX_GMXX_RXX_INT_REG
221 					  (index, interface));
222 			gmx_rx_int_reg.u64 &=
223 			    cvmx_read_csr(CVMX_GMXX_RXX_INT_EN
224 					  (index, interface));
225 			/* Poll the port if inband status changed */
226 			if (gmx_rx_int_reg.s.phy_dupx
227 			    || gmx_rx_int_reg.s.phy_link
228 			    || gmx_rx_int_reg.s.phy_spd) {
229 
230 				struct net_device *dev =
231 				    cvm_oct_device[cvmx_helper_get_ipd_port
232 						   (interface, index)];
233 				struct octeon_ethernet *priv = netdev_priv(dev);
234 
235 				if (dev && !atomic_read(&cvm_oct_poll_queue_stopping))
236 					queue_work(cvm_oct_poll_queue, &priv->port_work);
237 
238 				gmx_rx_int_reg.u64 = 0;
239 				gmx_rx_int_reg.s.phy_dupx = 1;
240 				gmx_rx_int_reg.s.phy_link = 1;
241 				gmx_rx_int_reg.s.phy_spd = 1;
242 				cvmx_write_csr(CVMX_GMXX_RXX_INT_REG
243 					       (index, interface),
244 					       gmx_rx_int_reg.u64);
245 				return_status = IRQ_HANDLED;
246 			}
247 		}
248 	}
249 
250 	/* Check and see if this interrupt was caused by the GMX1 block */
251 	if (rsl_int_blocks.s.gmx1) {
252 
253 		int interface = 1;
254 		/* Loop through every port of this interface */
255 		for (index = 0;
256 		     index < cvmx_helper_ports_on_interface(interface);
257 		     index++) {
258 
259 			/* Read the GMX interrupt status bits */
260 			union cvmx_gmxx_rxx_int_reg gmx_rx_int_reg;
261 			gmx_rx_int_reg.u64 =
262 			    cvmx_read_csr(CVMX_GMXX_RXX_INT_REG
263 					  (index, interface));
264 			gmx_rx_int_reg.u64 &=
265 			    cvmx_read_csr(CVMX_GMXX_RXX_INT_EN
266 					  (index, interface));
267 			/* Poll the port if inband status changed */
268 			if (gmx_rx_int_reg.s.phy_dupx
269 			    || gmx_rx_int_reg.s.phy_link
270 			    || gmx_rx_int_reg.s.phy_spd) {
271 
272 				struct net_device *dev =
273 				    cvm_oct_device[cvmx_helper_get_ipd_port
274 						   (interface, index)];
275 				struct octeon_ethernet *priv = netdev_priv(dev);
276 
277 				if (dev && !atomic_read(&cvm_oct_poll_queue_stopping))
278 					queue_work(cvm_oct_poll_queue, &priv->port_work);
279 
280 				gmx_rx_int_reg.u64 = 0;
281 				gmx_rx_int_reg.s.phy_dupx = 1;
282 				gmx_rx_int_reg.s.phy_link = 1;
283 				gmx_rx_int_reg.s.phy_spd = 1;
284 				cvmx_write_csr(CVMX_GMXX_RXX_INT_REG
285 					       (index, interface),
286 					       gmx_rx_int_reg.u64);
287 				return_status = IRQ_HANDLED;
288 			}
289 		}
290 	}
291 	return return_status;
292 }
293 
294 int cvm_oct_rgmii_open(struct net_device *dev)
295 {
296 	union cvmx_gmxx_prtx_cfg gmx_cfg;
297 	struct octeon_ethernet *priv = netdev_priv(dev);
298 	int interface = INTERFACE(priv->port);
299 	int index = INDEX(priv->port);
300 	cvmx_helper_link_info_t link_info;
301 
302 	gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
303 	gmx_cfg.s.en = 1;
304 	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
305 
306 	if (!octeon_is_simulation()) {
307 		link_info = cvmx_helper_link_get(priv->port);
308 		if (!link_info.s.link_up)
309 			netif_carrier_off(dev);
310 	}
311 
312 	return 0;
313 }
314 
315 int cvm_oct_rgmii_stop(struct net_device *dev)
316 {
317 	union cvmx_gmxx_prtx_cfg gmx_cfg;
318 	struct octeon_ethernet *priv = netdev_priv(dev);
319 	int interface = INTERFACE(priv->port);
320 	int index = INDEX(priv->port);
321 
322 	gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
323 	gmx_cfg.s.en = 0;
324 	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
325 	return 0;
326 }
327 
328 static void cvm_oct_rgmii_immediate_poll(struct work_struct *work)
329 {
330 	struct octeon_ethernet *priv = container_of(work, struct octeon_ethernet, port_work);
331 	cvm_oct_rgmii_poll(cvm_oct_device[priv->port]);
332 }
333 
334 int cvm_oct_rgmii_init(struct net_device *dev)
335 {
336 	struct octeon_ethernet *priv = netdev_priv(dev);
337 	int r;
338 
339 	cvm_oct_common_init(dev);
340 	dev->netdev_ops->ndo_stop(dev);
341 	INIT_WORK(&priv->port_work, cvm_oct_rgmii_immediate_poll);
342 	/*
343 	 * Due to GMX errata in CN3XXX series chips, it is necessary
344 	 * to take the link down immediately when the PHY changes
345 	 * state. In order to do this we call the poll function every
346 	 * time the RGMII inband status changes.  This may cause
347 	 * problems if the PHY doesn't implement inband status
348 	 * properly.
349 	 */
350 	if (number_rgmii_ports == 0) {
351 		r = request_irq(OCTEON_IRQ_RML, cvm_oct_rgmii_rml_interrupt,
352 				IRQF_SHARED, "RGMII", &number_rgmii_ports);
353 		if (r != 0)
354 			return r;
355 	}
356 	number_rgmii_ports++;
357 
358 	/*
359 	 * Only true RGMII ports need to be polled. In GMII mode, port
360 	 * 0 is really a RGMII port.
361 	 */
362 	if (((priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII)
363 	     && (priv->port == 0))
364 	    || (priv->imode == CVMX_HELPER_INTERFACE_MODE_RGMII)) {
365 
366 		if (!octeon_is_simulation()) {
367 
368 			union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
369 			int interface = INTERFACE(priv->port);
370 			int index = INDEX(priv->port);
371 
372 			/*
373 			 * Enable interrupts on inband status changes
374 			 * for this port.
375 			 */
376 			gmx_rx_int_en.u64 = 0;
377 			gmx_rx_int_en.s.phy_dupx = 1;
378 			gmx_rx_int_en.s.phy_link = 1;
379 			gmx_rx_int_en.s.phy_spd = 1;
380 			cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, interface),
381 				       gmx_rx_int_en.u64);
382 			priv->poll = cvm_oct_rgmii_poll;
383 		}
384 	}
385 
386 	return 0;
387 }
388 
389 void cvm_oct_rgmii_uninit(struct net_device *dev)
390 {
391 	struct octeon_ethernet *priv = netdev_priv(dev);
392 	cvm_oct_common_uninit(dev);
393 
394 	/*
395 	 * Only true RGMII ports need to be polled. In GMII mode, port
396 	 * 0 is really a RGMII port.
397 	 */
398 	if (((priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII)
399 	     && (priv->port == 0))
400 	    || (priv->imode == CVMX_HELPER_INTERFACE_MODE_RGMII)) {
401 
402 		if (!octeon_is_simulation()) {
403 
404 			union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
405 			int interface = INTERFACE(priv->port);
406 			int index = INDEX(priv->port);
407 
408 			/*
409 			 * Disable interrupts on inband status changes
410 			 * for this port.
411 			 */
412 			gmx_rx_int_en.u64 =
413 			    cvmx_read_csr(CVMX_GMXX_RXX_INT_EN
414 					  (index, interface));
415 			gmx_rx_int_en.s.phy_dupx = 0;
416 			gmx_rx_int_en.s.phy_link = 0;
417 			gmx_rx_int_en.s.phy_spd = 0;
418 			cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, interface),
419 				       gmx_rx_int_en.u64);
420 		}
421 	}
422 
423 	/* Remove the interrupt handler when the last port is removed. */
424 	number_rgmii_ports--;
425 	if (number_rgmii_ports == 0)
426 		free_irq(OCTEON_IRQ_RML, &number_rgmii_ports);
427 	cancel_work_sync(&priv->port_work);
428 }
429