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