FreeBSD/Linux Kernel Cross Reference
sys/mips/nlm/board.c
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights
5 * reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 * THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * NETLOGIC_BSD */
31
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/bus.h>
37 #include <sys/kernel.h>
38 #include <sys/lock.h>
39 #include <sys/mutex.h>
40
41 #include <net/ethernet.h>
42
43 #include <mips/nlm/hal/mips-extns.h>
44 #include <mips/nlm/hal/haldefs.h>
45 #include <mips/nlm/hal/iomap.h>
46 #include <mips/nlm/hal/fmn.h>
47 #include <mips/nlm/hal/pic.h>
48 #include <mips/nlm/hal/sys.h>
49 #include <mips/nlm/hal/nae.h>
50 #include <mips/nlm/hal/uart.h>
51 #include <mips/nlm/hal/poe.h>
52
53 #include <mips/nlm/xlp.h>
54 #include <mips/nlm/board.h>
55 #include <mips/nlm/msgring.h>
56
57 static uint8_t board_eeprom_buf[EEPROM_SIZE];
58 static int board_eeprom_set;
59
60 struct xlp_board_info xlp_board_info;
61
62 struct vfbid_tbl {
63 int vfbid;
64 int dest_vc;
65 };
66
67 /* XXXJC : this should be derived from msg thread mask */
68 static struct vfbid_tbl nlm_vfbid[] = {
69 /* NULL FBID should map to cpu0 to detect NAE send msg errors */
70 {127, 0}, /* NAE <-> NAE mappings */
71 {51, 1019}, {50, 1018}, {49, 1017}, {48, 1016},
72 {47, 1015}, {46, 1014}, {45, 1013}, {44, 1012},
73 {43, 1011}, {42, 1010}, {41, 1009}, {40, 1008},
74 {39, 1007}, {38, 1006}, {37, 1005}, {36, 1004},
75 {35, 1003}, {34, 1002}, {33, 1001}, {32, 1000},
76 /* NAE <-> CPU mappings, freeback got to vc 3 of each thread */
77 {31, 127}, {30, 123}, {29, 119}, {28, 115},
78 {27, 111}, {26, 107}, {25, 103}, {24, 99},
79 {23, 95}, {22, 91}, {21, 87}, {20, 83},
80 {19, 79}, {18, 75}, {17, 71}, {16, 67},
81 {15, 63}, {14, 59}, {13, 55}, {12, 51},
82 {11, 47}, {10, 43}, { 9, 39}, { 8, 35},
83 { 7, 31}, { 6, 27}, { 5, 23}, { 4, 19},
84 { 3, 15}, { 2, 11}, { 1, 7}, { 0, 3},
85 };
86
87 static struct vfbid_tbl nlm3xx_vfbid[] = {
88 /* NULL FBID should map to cpu0 to detect NAE send msg errors */
89 {127, 0}, /* NAE <-> NAE mappings */
90 {39, 503}, {38, 502}, {37, 501}, {36, 500},
91 {35, 499}, {34, 498}, {33, 497}, {32, 496},
92 /* NAE <-> CPU mappings, freeback got to vc 3 of each thread */
93 {31, 127}, {30, 123}, {29, 119}, {28, 115},
94 {27, 111}, {26, 107}, {25, 103}, {24, 99},
95 {23, 95}, {22, 91}, {21, 87}, {20, 83},
96 {19, 79}, {18, 75}, {17, 71}, {16, 67},
97 {15, 63}, {14, 59}, {13, 55}, {12, 51},
98 {11, 47}, {10, 43}, { 9, 39}, { 8, 35},
99 { 7, 31}, { 6, 27}, { 5, 23}, { 4, 19},
100 { 3, 15}, { 2, 11}, { 1, 7}, { 0, 3},
101 };
102
103 int
104 nlm_get_vfbid_mapping(int vfbid)
105 {
106 int i, nentries;
107 struct vfbid_tbl *p;
108
109 if (nlm_is_xlp3xx()) {
110 nentries = nitems(nlm3xx_vfbid);
111 p = nlm3xx_vfbid;
112 } else {
113 nentries = nitems(nlm_vfbid);
114 p = nlm_vfbid;
115 }
116
117 for (i = 0; i < nentries; i++) {
118 if (p[i].vfbid == vfbid)
119 return (p[i].dest_vc);
120 }
121
122 return (-1);
123 }
124
125 int
126 nlm_get_poe_distvec(int vec, uint32_t *distvec)
127 {
128
129 if (vec != 0)
130 return (-1); /* we support just vec 0 */
131 nlm_calc_poe_distvec(xlp_msg_thread_mask, 0, 0, 0,
132 0x1 << XLPGE_RX_VC, distvec);
133 return (0);
134 }
135
136 /*
137 * All our knowledge of chip and board that cannot be detected by probing
138 * at run-time goes here
139 */
140
141 void
142 xlpge_get_macaddr(uint8_t *macaddr)
143 {
144
145 if (board_eeprom_set == 0) {
146 /* No luck, take some reasonable value */
147 macaddr[0] = 0x00; macaddr[1] = 0x0f; macaddr[2] = 0x30;
148 macaddr[3] = 0x20; macaddr[4] = 0x0d; macaddr[5] = 0x5b;
149 } else
150 memcpy(macaddr, &board_eeprom_buf[EEPROM_MACADDR_OFFSET],
151 ETHER_ADDR_LEN);
152 }
153
154 static void
155 nlm_setup_port_defaults(struct xlp_port_ivars *p)
156 {
157 p->loopback_mode = 0;
158 p->num_channels = 1;
159 p->free_desc_sizes = 2048;
160 p->vlan_pri_en = 0;
161 p->hw_parser_en = 1;
162 p->ieee1588_userval = 0;
163 p->ieee1588_ptpoff = 0;
164 p->ieee1588_tmr1 = 0;
165 p->ieee1588_tmr2 = 0;
166 p->ieee1588_tmr3 = 0;
167 p->ieee1588_inc_intg = 0;
168 p->ieee1588_inc_den = 1;
169 p->ieee1588_inc_num = 1;
170
171 if (nlm_is_xlp3xx()) {
172 p->stg2_fifo_size = XLP3XX_STG2_FIFO_SZ;
173 p->eh_fifo_size = XLP3XX_EH_FIFO_SZ;
174 p->frout_fifo_size = XLP3XX_FROUT_FIFO_SZ;
175 p->ms_fifo_size = XLP3XX_MS_FIFO_SZ;
176 p->pkt_fifo_size = XLP3XX_PKT_FIFO_SZ;
177 p->pktlen_fifo_size = XLP3XX_PKTLEN_FIFO_SZ;
178 p->max_stg2_offset = XLP3XX_MAX_STG2_OFFSET;
179 p->max_eh_offset = XLP3XX_MAX_EH_OFFSET;
180 p->max_frout_offset = XLP3XX_MAX_FREE_OUT_OFFSET;
181 p->max_ms_offset = XLP3XX_MAX_MS_OFFSET;
182 p->max_pmem_offset = XLP3XX_MAX_PMEM_OFFSET;
183 p->stg1_2_credit = XLP3XX_STG1_2_CREDIT;
184 p->stg2_eh_credit = XLP3XX_STG2_EH_CREDIT;
185 p->stg2_frout_credit = XLP3XX_STG2_FROUT_CREDIT;
186 p->stg2_ms_credit = XLP3XX_STG2_MS_CREDIT;
187 } else {
188 p->stg2_fifo_size = XLP8XX_STG2_FIFO_SZ;
189 p->eh_fifo_size = XLP8XX_EH_FIFO_SZ;
190 p->frout_fifo_size = XLP8XX_FROUT_FIFO_SZ;
191 p->ms_fifo_size = XLP8XX_MS_FIFO_SZ;
192 p->pkt_fifo_size = XLP8XX_PKT_FIFO_SZ;
193 p->pktlen_fifo_size = XLP8XX_PKTLEN_FIFO_SZ;
194 p->max_stg2_offset = XLP8XX_MAX_STG2_OFFSET;
195 p->max_eh_offset = XLP8XX_MAX_EH_OFFSET;
196 p->max_frout_offset = XLP8XX_MAX_FREE_OUT_OFFSET;
197 p->max_ms_offset = XLP8XX_MAX_MS_OFFSET;
198 p->max_pmem_offset = XLP8XX_MAX_PMEM_OFFSET;
199 p->stg1_2_credit = XLP8XX_STG1_2_CREDIT;
200 p->stg2_eh_credit = XLP8XX_STG2_EH_CREDIT;
201 p->stg2_frout_credit = XLP8XX_STG2_FROUT_CREDIT;
202 p->stg2_ms_credit = XLP8XX_STG2_MS_CREDIT;
203 }
204
205 switch (p->type) {
206 case SGMIIC:
207 p->num_free_descs = 52;
208 p->iface_fifo_size = 13;
209 p->rxbuf_size = 128;
210 p->rx_slots_reqd = SGMII_CAL_SLOTS;
211 p->tx_slots_reqd = SGMII_CAL_SLOTS;
212 if (nlm_is_xlp3xx())
213 p->pseq_fifo_size = 30;
214 else
215 p->pseq_fifo_size = 62;
216 break;
217 case ILC:
218 p->num_free_descs = 150;
219 p->rxbuf_size = 944;
220 p->rx_slots_reqd = IL8_CAL_SLOTS;
221 p->tx_slots_reqd = IL8_CAL_SLOTS;
222 p->pseq_fifo_size = 225;
223 p->iface_fifo_size = 55;
224 break;
225 case XAUIC:
226 default:
227 p->num_free_descs = 150;
228 p->rxbuf_size = 944;
229 p->rx_slots_reqd = XAUI_CAL_SLOTS;
230 p->tx_slots_reqd = XAUI_CAL_SLOTS;
231 if (nlm_is_xlp3xx()) {
232 p->pseq_fifo_size = 120;
233 p->iface_fifo_size = 52;
234 } else {
235 p->pseq_fifo_size = 225;
236 p->iface_fifo_size = 55;
237 }
238 break;
239 }
240 }
241
242 /* XLP 8XX evaluation boards have the following phy-addr
243 * assignment. There are two external mdio buses in XLP --
244 * bus 0 and bus 1. The management ports (16 and 17) are
245 * on mdio bus 0 while blocks/complexes[0 to 3] are all
246 * on mdio bus 1. The phy_addr on bus 0 (mgmt ports 16
247 * and 17) match the port numbers.
248 * These are the details:
249 * block port phy_addr mdio_bus
250 * ====================================
251 * 0 0 4 1
252 * 0 1 7 1
253 * 0 2 6 1
254 * 0 3 5 1
255 * 1 0 8 1
256 * 1 1 11 1
257 * 1 2 10 1
258 * 1 3 9 1
259 * 2 0 0 1
260 * 2 1 3 1
261 * 2 2 2 1
262 * 2 3 1 1
263 * 3 0 12 1
264 * 3 1 15 1
265 * 3 2 14 1
266 * 3 3 13 1
267 *
268 * 4 0 16 0
269 * 4 1 17 0
270 *
271 * The XLP 3XX evaluation boards have the following phy-addr
272 * assignments.
273 * block port phy_addr mdio_bus
274 * ====================================
275 * 0 0 4 0
276 * 0 1 7 0
277 * 0 2 6 0
278 * 0 3 5 0
279 * 1 0 8 0
280 * 1 1 11 0
281 * 1 2 10 0
282 * 1 3 9 0
283 */
284 static void
285 nlm_board_get_phyaddr(int block, int port, int *phyaddr)
286 {
287 switch (block) {
288 case 0: switch (port) {
289 case 0: *phyaddr = 4; break;
290 case 1: *phyaddr = 7; break;
291 case 2: *phyaddr = 6; break;
292 case 3: *phyaddr = 5; break;
293 }
294 break;
295 case 1: switch (port) {
296 case 0: *phyaddr = 8; break;
297 case 1: *phyaddr = 11; break;
298 case 2: *phyaddr = 10; break;
299 case 3: *phyaddr = 9; break;
300 }
301 break;
302 case 2: switch (port) {
303 case 0: *phyaddr = 0; break;
304 case 1: *phyaddr = 3; break;
305 case 2: *phyaddr = 2; break;
306 case 3: *phyaddr = 1; break;
307 }
308 break;
309 case 3: switch (port) {
310 case 0: *phyaddr = 12; break;
311 case 1: *phyaddr = 15; break;
312 case 2: *phyaddr = 14; break;
313 case 3: *phyaddr = 13; break;
314 }
315 break;
316 case 4: switch (port) { /* management SGMII */
317 case 0: *phyaddr = 16; break;
318 case 1: *phyaddr = 17; break;
319 }
320 break;
321 }
322 }
323
324
325 static void
326 nlm_print_processor_info(void)
327 {
328 uint32_t procid;
329 int prid, rev;
330 char *chip, *revstr;
331
332 procid = mips_rd_prid();
333 prid = (procid >> 8) & 0xff;
334 rev = procid & 0xff;
335
336 switch (prid) {
337 case CHIP_PROCESSOR_ID_XLP_8XX:
338 chip = "XLP 832";
339 break;
340 case CHIP_PROCESSOR_ID_XLP_3XX:
341 chip = "XLP 3xx";
342 break;
343 case CHIP_PROCESSOR_ID_XLP_432:
344 case CHIP_PROCESSOR_ID_XLP_416:
345 chip = "XLP 4xx";
346 break;
347 default:
348 chip = "XLP ?xx";
349 break;
350 }
351 switch (rev) {
352 case 0:
353 revstr = "A0"; break;
354 case 1:
355 revstr = "A1"; break;
356 case 2:
357 revstr = "A2"; break;
358 case 3:
359 revstr = "B0"; break;
360 case 4:
361 revstr = "B1"; break;
362 default:
363 revstr = "??"; break;
364 }
365
366 printf("Processor info:\n");
367 printf(" Netlogic %s %s [%x]\n", chip, revstr, procid);
368 }
369
370 /*
371 * All our knowledge of chip and board that cannot be detected by probing
372 * at run-time goes here
373 */
374 static int
375 nlm_setup_xlp_board(int node)
376 {
377 struct xlp_board_info *boardp;
378 struct xlp_node_info *nodep;
379 struct xlp_nae_ivars *naep;
380 struct xlp_block_ivars *blockp;
381 struct xlp_port_ivars *portp;
382 uint64_t cpldbase, nae_pcibase;
383 int block, port, rv, dbtype, usecpld = 0, evp = 0, svp = 0;
384 uint8_t *b;
385
386 /* start with a clean slate */
387 boardp = &xlp_board_info;
388 if (boardp->nodemask == 0)
389 memset(boardp, 0, sizeof(xlp_board_info));
390 boardp->nodemask |= (1 << node);
391 nlm_print_processor_info();
392
393 b = board_eeprom_buf;
394 rv = nlm_board_eeprom_read(node, EEPROM_I2CBUS, EEPROM_I2CADDR, 0, b,
395 EEPROM_SIZE);
396 if (rv == 0) {
397 board_eeprom_set = 1;
398 printf("Board info (EEPROM on i2c@%d at %#X):\n",
399 EEPROM_I2CBUS, EEPROM_I2CADDR);
400 printf(" Model: %7.7s %2.2s\n", &b[16], &b[24]);
401 printf(" Serial #: %3.3s-%2.2s\n", &b[27], &b[31]);
402 printf(" MAC addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
403 b[2], b[3], b[4], b[5], b[6], b[7]);
404 } else
405 printf("Board Info: Error on EEPROM read (i2c@%d %#X).\n",
406 EEPROM_I2CBUS, EEPROM_I2CADDR);
407
408 nae_pcibase = nlm_get_nae_pcibase(node);
409 nodep = &boardp->nodes[node];
410 naep = &nodep->nae_ivars;
411 naep->node = node;
412
413 /* frequency at which network block runs */
414 naep->freq = 500;
415
416 /* CRC16 polynomial used for flow table generation */
417 naep->flow_crc_poly = 0xffff;
418 naep->hw_parser_en = 1;
419 naep->prepad_en = 1;
420 naep->prepad_size = 3; /* size in 16 byte units */
421 naep->ieee_1588_en = 1;
422
423 naep->ilmask = 0x0; /* set this based on daughter card */
424 naep->xauimask = 0x0; /* set this based on daughter card */
425 naep->sgmiimask = 0x0; /* set this based on daughter card */
426 naep->nblocks = nae_num_complex(nae_pcibase);
427 if (strncmp(&b[16], "PCIE", 4) == 0) {
428 usecpld = 0; /* XLP PCIe card */
429 /* Broadcom's XLP PCIe card has the following
430 * blocks fixed.
431 * blk 0-XAUI, 1-XAUI, 4-SGMII(one port) */
432 naep->blockmask = 0x13;
433 } else if (strncmp(&b[16], "MB-EVP", 6) == 0) {
434 usecpld = 1; /* XLP non-PCIe card which has CPLD */
435 evp = 1;
436 naep->blockmask = (1 << naep->nblocks) - 1;
437 } else if ((strncmp(&b[16], "MB-S", 4) == 0) ||
438 (strncmp(&b[16], "MB_S", 4) == 0)) {
439 usecpld = 1; /* XLP non-PCIe card which has CPLD */
440 svp = 1;
441 /* 3xx chip reports one block extra which is a bug */
442 naep->nblocks = naep->nblocks - 1;
443 naep->blockmask = (1 << naep->nblocks) - 1;
444 } else {
445 printf("ERROR!!! Board type:%7s didn't match any board"
446 " type we support\n", &b[16]);
447 return (-1);
448 }
449 cpldbase = nlm_board_cpld_base(node, XLP_EVB_CPLD_CHIPSELECT);
450
451 /* pretty print network config */
452 printf("Network config");
453 if (usecpld)
454 printf("(from CPLD@%d):\n", XLP_EVB_CPLD_CHIPSELECT);
455 else
456 printf("(defaults):\n");
457 printf(" NAE@%d Blocks: ", node);
458 for (block = 0; block < naep->nblocks; block++) {
459 char *s = "???";
460
461 if ((naep->blockmask & (1 << block)) == 0)
462 continue;
463 blockp = &naep->block_ivars[block];
464 blockp->block = block;
465 if (usecpld)
466 dbtype = nlm_board_cpld_dboard_type(cpldbase, block);
467 else
468 dbtype = DCARD_XAUI; /* default XAUI */
469
470 /* XLP PCIe cards */
471 if ((!evp && !svp) && ((block == 2) || (block == 3)))
472 dbtype = DCARD_NOT_PRSNT;
473
474 if (block == 4) {
475 /* management block 4 on 8xx or XLP PCIe */
476 blockp->type = SGMIIC;
477 if (evp)
478 blockp->portmask = 0x3;
479 else
480 blockp->portmask = 0x1;
481 naep->sgmiimask |= (1 << block);
482 } else {
483 switch (dbtype) {
484 case DCARD_ILAKEN:
485 blockp->type = ILC;
486 blockp->portmask = 0x1;
487 naep->ilmask |= (1 << block);
488 break;
489 case DCARD_SGMII:
490 blockp->type = SGMIIC;
491 blockp->portmask = 0xf;
492 naep->sgmiimask |= (1 << block);
493 break;
494 case DCARD_XAUI:
495 blockp->type = XAUIC;
496 blockp->portmask = 0x1;
497 naep->xauimask |= (1 << block);
498 break;
499 default: /* DCARD_NOT_PRSNT */
500 blockp->type = UNKNOWN;
501 blockp->portmask = 0;
502 break;
503 }
504 }
505 if (blockp->type != UNKNOWN) {
506 for (port = 0; port < PORTS_PER_CMPLX; port++) {
507 if ((blockp->portmask & (1 << port)) == 0)
508 continue;
509 portp = &blockp->port_ivars[port];
510 nlm_board_get_phyaddr(block, port,
511 &portp->phy_addr);
512 if (svp || (block == 4))
513 portp->mdio_bus = 0;
514 else
515 portp->mdio_bus = 1;
516 portp->port = port;
517 portp->block = block;
518 portp->node = node;
519 portp->type = blockp->type;
520 nlm_setup_port_defaults(portp);
521 }
522 }
523 switch (blockp->type) {
524 case SGMIIC : s = "SGMII"; break;
525 case XAUIC : s = "XAUI"; break;
526 case ILC : s = "IL"; break;
527 }
528 printf(" [%d %s]", block, s);
529 }
530 printf("\n");
531 return (0);
532 }
533
534 int nlm_board_info_setup(void)
535 {
536 if (nlm_setup_xlp_board(0) != 0)
537 return (-1);
538 return (0);
539 }
Cache object: 28b3ece24f47f1f6b8211f3651c175a2
|