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