xref: /linux/drivers/rapidio/switches/idt_gen3.c (revision f3a8b6645dc2e60d11f20c1c23afd964ff4e55ae)
1 /*
2  * IDT RXS Gen.3 Serial RapidIO switch family support
3  *
4  * Copyright 2016 Integrated Device Technology, Inc.
5  *
6  * This program is free software; you can redistribute  it and/or modify it
7  * under  the terms of  the GNU General  Public License as published by the
8  * Free Software Foundation;  either version 2 of the  License, or (at your
9  * option) any later version.
10  */
11 
12 #include <linux/stat.h>
13 #include <linux/module.h>
14 #include <linux/rio.h>
15 #include <linux/rio_drv.h>
16 #include <linux/rio_ids.h>
17 #include <linux/delay.h>
18 
19 #include <asm/page.h>
20 #include "../rio.h"
21 
22 #define RIO_EM_PW_STAT		0x40020
23 #define RIO_PW_CTL		0x40204
24 #define RIO_PW_CTL_PW_TMR		0xffffff00
25 #define RIO_PW_ROUTE		0x40208
26 
27 #define RIO_EM_DEV_INT_EN	0x40030
28 
29 #define RIO_PLM_SPx_IMP_SPEC_CTL(x)	(0x10100 + (x)*0x100)
30 #define RIO_PLM_SPx_IMP_SPEC_CTL_SOFT_RST	0x02000000
31 
32 #define RIO_PLM_SPx_PW_EN(x)	(0x10118 + (x)*0x100)
33 #define RIO_PLM_SPx_PW_EN_OK2U	0x40000000
34 #define RIO_PLM_SPx_PW_EN_LINIT 0x10000000
35 
36 #define RIO_BC_L2_Gn_ENTRYx_CSR(n, x)	(0x31000 + (n)*0x400 + (x)*0x4)
37 #define RIO_SPx_L2_Gn_ENTRYy_CSR(x, n, y) \
38 				(0x51000 + (x)*0x2000 + (n)*0x400 + (y)*0x4)
39 
40 static int
41 idtg3_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
42 		       u16 table, u16 route_destid, u8 route_port)
43 {
44 	u32 rval;
45 	u32 entry = route_port;
46 	int err = 0;
47 
48 	pr_debug("RIO: %s t=0x%x did_%x to p_%x\n",
49 		 __func__, table, route_destid, entry);
50 
51 	if (route_destid > 0xFF)
52 		return -EINVAL;
53 
54 	if (route_port == RIO_INVALID_ROUTE)
55 		entry = RIO_RT_ENTRY_DROP_PKT;
56 
57 	if (table == RIO_GLOBAL_TABLE) {
58 		/* Use broadcast register to update all per-port tables */
59 		err = rio_mport_write_config_32(mport, destid, hopcount,
60 				RIO_BC_L2_Gn_ENTRYx_CSR(0, route_destid),
61 				entry);
62 		return err;
63 	}
64 
65 	/*
66 	 * Verify that specified port/table number is valid
67 	 */
68 	err = rio_mport_read_config_32(mport, destid, hopcount,
69 				       RIO_SWP_INFO_CAR, &rval);
70 	if (err)
71 		return err;
72 
73 	if (table >= RIO_GET_TOTAL_PORTS(rval))
74 		return -EINVAL;
75 
76 	err = rio_mport_write_config_32(mport, destid, hopcount,
77 			RIO_SPx_L2_Gn_ENTRYy_CSR(table, 0, route_destid),
78 			entry);
79 	return err;
80 }
81 
82 static int
83 idtg3_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
84 		       u16 table, u16 route_destid, u8 *route_port)
85 {
86 	u32 rval;
87 	int err;
88 
89 	if (route_destid > 0xFF)
90 		return -EINVAL;
91 
92 	err = rio_mport_read_config_32(mport, destid, hopcount,
93 				       RIO_SWP_INFO_CAR, &rval);
94 	if (err)
95 		return err;
96 
97 	/*
98 	 * This switch device does not have the dedicated global routing table.
99 	 * It is substituted by reading routing table of the ingress port of
100 	 * maintenance read requests.
101 	 */
102 	if (table == RIO_GLOBAL_TABLE)
103 		table = RIO_GET_PORT_NUM(rval);
104 	else if (table >= RIO_GET_TOTAL_PORTS(rval))
105 		return -EINVAL;
106 
107 	err = rio_mport_read_config_32(mport, destid, hopcount,
108 			RIO_SPx_L2_Gn_ENTRYy_CSR(table, 0, route_destid),
109 			&rval);
110 	if (err)
111 		return err;
112 
113 	if (rval == RIO_RT_ENTRY_DROP_PKT)
114 		*route_port = RIO_INVALID_ROUTE;
115 	else
116 		*route_port = (u8)rval;
117 
118 	return 0;
119 }
120 
121 static int
122 idtg3_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
123 		       u16 table)
124 {
125 	u32 i;
126 	u32 rval;
127 	int err;
128 
129 	if (table == RIO_GLOBAL_TABLE) {
130 		for (i = 0; i <= 0xff; i++) {
131 			err = rio_mport_write_config_32(mport, destid, hopcount,
132 						RIO_BC_L2_Gn_ENTRYx_CSR(0, i),
133 						RIO_RT_ENTRY_DROP_PKT);
134 			if (err)
135 				break;
136 		}
137 
138 		return err;
139 	}
140 
141 	err = rio_mport_read_config_32(mport, destid, hopcount,
142 				       RIO_SWP_INFO_CAR, &rval);
143 	if (err)
144 		return err;
145 
146 	if (table >= RIO_GET_TOTAL_PORTS(rval))
147 		return -EINVAL;
148 
149 	for (i = 0; i <= 0xff; i++) {
150 		err = rio_mport_write_config_32(mport, destid, hopcount,
151 					RIO_SPx_L2_Gn_ENTRYy_CSR(table, 0, i),
152 					RIO_RT_ENTRY_DROP_PKT);
153 		if (err)
154 			break;
155 	}
156 
157 	return err;
158 }
159 
160 /*
161  * This routine performs device-specific initialization only.
162  * All standard EM configuration should be performed at upper level.
163  */
164 static int
165 idtg3_em_init(struct rio_dev *rdev)
166 {
167 	int i, tmp;
168 	u32 rval;
169 
170 	pr_debug("RIO: %s [%d:%d]\n", __func__, rdev->destid, rdev->hopcount);
171 
172 	/* Disable assertion of interrupt signal */
173 	rio_write_config_32(rdev, RIO_EM_DEV_INT_EN, 0);
174 
175 	/* Disable port-write event notifications during initialization */
176 	rio_write_config_32(rdev, rdev->em_efptr + RIO_EM_PW_TX_CTRL,
177 			    RIO_EM_PW_TX_CTRL_PW_DIS);
178 
179 	/* Configure Port-Write notifications for hot-swap events */
180 	tmp = RIO_GET_TOTAL_PORTS(rdev->swpinfo);
181 	for (i = 0; i < tmp; i++) {
182 
183 		rio_read_config_32(rdev,
184 			RIO_DEV_PORT_N_ERR_STS_CSR(rdev, i),
185 			&rval);
186 		if (rval & RIO_PORT_N_ERR_STS_PORT_UA)
187 			continue;
188 
189 		/* Clear events signaled before enabling notification */
190 		rio_write_config_32(rdev,
191 			rdev->em_efptr + RIO_EM_PN_ERR_DETECT(i), 0);
192 
193 		/* Enable event notifications */
194 		rio_write_config_32(rdev,
195 			rdev->em_efptr + RIO_EM_PN_ERRRATE_EN(i),
196 			RIO_EM_PN_ERRRATE_EN_OK2U | RIO_EM_PN_ERRRATE_EN_U2OK);
197 		/* Enable port-write generation on events */
198 		rio_write_config_32(rdev, RIO_PLM_SPx_PW_EN(i),
199 			RIO_PLM_SPx_PW_EN_OK2U | RIO_PLM_SPx_PW_EN_LINIT);
200 
201 	}
202 
203 	/* Set Port-Write destination port */
204 	tmp = RIO_GET_PORT_NUM(rdev->swpinfo);
205 	rio_write_config_32(rdev, RIO_PW_ROUTE, 1 << tmp);
206 
207 
208 	/* Enable sending port-write event notifications */
209 	rio_write_config_32(rdev, rdev->em_efptr + RIO_EM_PW_TX_CTRL, 0);
210 
211 	/* set TVAL = ~50us */
212 	rio_write_config_32(rdev,
213 		rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8);
214 	return 0;
215 }
216 
217 
218 /*
219  * idtg3_em_handler - device-specific error handler
220  *
221  * If the link is down (PORT_UNINIT) does nothing - this is considered
222  * as link partner removal from the port.
223  *
224  * If the link is up (PORT_OK) - situation is handled as *new* device insertion.
225  * In this case ERR_STOP bits are cleared by issuing soft reset command to the
226  * reporting port. Inbound and outbound ackIDs are cleared by the reset as well.
227  * This way the port is synchronized with freshly inserted device (assuming it
228  * was reset/powered-up on insertion).
229  *
230  * TODO: This is not sufficient in a situation when a link between two devices
231  * was down and up again (e.g. cable disconnect). For that situation full ackID
232  * realignment process has to be implemented.
233  */
234 static int
235 idtg3_em_handler(struct rio_dev *rdev, u8 pnum)
236 {
237 	u32 err_status;
238 	u32 rval;
239 
240 	rio_read_config_32(rdev,
241 			RIO_DEV_PORT_N_ERR_STS_CSR(rdev, pnum),
242 			&err_status);
243 
244 	/* Do nothing for device/link removal */
245 	if (err_status & RIO_PORT_N_ERR_STS_PORT_UNINIT)
246 		return 0;
247 
248 	/* When link is OK we have a device insertion.
249 	 * Request port soft reset to clear errors if they present.
250 	 * Inbound and outbound ackIDs will be 0 after reset.
251 	 */
252 	if (err_status & (RIO_PORT_N_ERR_STS_OUT_ES |
253 				RIO_PORT_N_ERR_STS_INP_ES)) {
254 		rio_read_config_32(rdev, RIO_PLM_SPx_IMP_SPEC_CTL(pnum), &rval);
255 		rio_write_config_32(rdev, RIO_PLM_SPx_IMP_SPEC_CTL(pnum),
256 				    rval | RIO_PLM_SPx_IMP_SPEC_CTL_SOFT_RST);
257 		udelay(10);
258 		rio_write_config_32(rdev, RIO_PLM_SPx_IMP_SPEC_CTL(pnum), rval);
259 		msleep(500);
260 	}
261 
262 	return 0;
263 }
264 
265 static struct rio_switch_ops idtg3_switch_ops = {
266 	.owner = THIS_MODULE,
267 	.add_entry = idtg3_route_add_entry,
268 	.get_entry = idtg3_route_get_entry,
269 	.clr_table = idtg3_route_clr_table,
270 	.em_init   = idtg3_em_init,
271 	.em_handle = idtg3_em_handler,
272 };
273 
274 static int idtg3_probe(struct rio_dev *rdev, const struct rio_device_id *id)
275 {
276 	pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
277 
278 	spin_lock(&rdev->rswitch->lock);
279 
280 	if (rdev->rswitch->ops) {
281 		spin_unlock(&rdev->rswitch->lock);
282 		return -EINVAL;
283 	}
284 
285 	rdev->rswitch->ops = &idtg3_switch_ops;
286 
287 	if (rdev->do_enum) {
288 		/* Disable hierarchical routing support: Existing fabric
289 		 * enumeration/discovery process (see rio-scan.c) uses 8-bit
290 		 * flat destination ID routing only.
291 		 */
292 		rio_write_config_32(rdev, 0x5000 + RIO_BC_RT_CTL_CSR, 0);
293 	}
294 
295 	spin_unlock(&rdev->rswitch->lock);
296 
297 	return 0;
298 }
299 
300 static void idtg3_remove(struct rio_dev *rdev)
301 {
302 	pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
303 	spin_lock(&rdev->rswitch->lock);
304 	if (rdev->rswitch->ops == &idtg3_switch_ops)
305 		rdev->rswitch->ops = NULL;
306 	spin_unlock(&rdev->rswitch->lock);
307 }
308 
309 /*
310  * Gen3 switches repeat sending PW messages until a corresponding event flag
311  * is cleared. Use shutdown notification to disable generation of port-write
312  * messages if their destination node is shut down.
313  */
314 static void idtg3_shutdown(struct rio_dev *rdev)
315 {
316 	int i;
317 	u32 rval;
318 	u16 destid;
319 
320 	/* Currently the enumerator node acts also as PW handler */
321 	if (!rdev->do_enum)
322 		return;
323 
324 	pr_debug("RIO: %s(%s)\n", __func__, rio_name(rdev));
325 
326 	rio_read_config_32(rdev, RIO_PW_ROUTE, &rval);
327 	i = RIO_GET_PORT_NUM(rdev->swpinfo);
328 
329 	/* Check port-write destination port */
330 	if (!((1 << i) & rval))
331 		return;
332 
333 	/* Disable sending port-write event notifications if PW destID
334 	 * matches to one of the enumerator node
335 	 */
336 	rio_read_config_32(rdev, rdev->em_efptr + RIO_EM_PW_TGT_DEVID, &rval);
337 
338 	if (rval & RIO_EM_PW_TGT_DEVID_DEV16)
339 		destid = rval >> 16;
340 	else
341 		destid = ((rval & RIO_EM_PW_TGT_DEVID_D8) >> 16);
342 
343 	if (rdev->net->hport->host_deviceid == destid) {
344 		rio_write_config_32(rdev,
345 				    rdev->em_efptr + RIO_EM_PW_TX_CTRL, 0);
346 		pr_debug("RIO: %s(%s) PW transmission disabled\n",
347 			 __func__, rio_name(rdev));
348 	}
349 }
350 
351 static struct rio_device_id idtg3_id_table[] = {
352 	{RIO_DEVICE(RIO_DID_IDTRXS1632, RIO_VID_IDT)},
353 	{RIO_DEVICE(RIO_DID_IDTRXS2448, RIO_VID_IDT)},
354 	{ 0, }	/* terminate list */
355 };
356 
357 static struct rio_driver idtg3_driver = {
358 	.name = "idt_gen3",
359 	.id_table = idtg3_id_table,
360 	.probe = idtg3_probe,
361 	.remove = idtg3_remove,
362 	.shutdown = idtg3_shutdown,
363 };
364 
365 static int __init idtg3_init(void)
366 {
367 	return rio_register_driver(&idtg3_driver);
368 }
369 
370 static void __exit idtg3_exit(void)
371 {
372 	pr_debug("RIO: %s\n", __func__);
373 	rio_unregister_driver(&idtg3_driver);
374 	pr_debug("RIO: %s done\n", __func__);
375 }
376 
377 device_initcall(idtg3_init);
378 module_exit(idtg3_exit);
379 
380 MODULE_DESCRIPTION("IDT RXS Gen.3 Serial RapidIO switch family driver");
381 MODULE_AUTHOR("Integrated Device Technology, Inc.");
382 MODULE_LICENSE("GPL");
383