1224110Sjchandra/*-
2224110Sjchandra * Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights
3224110Sjchandra * reserved.
4224110Sjchandra *
5224110Sjchandra * Redistribution and use in source and binary forms, with or without
6224110Sjchandra * modification, are permitted provided that the following conditions are
7224110Sjchandra * met:
8224110Sjchandra *
9224110Sjchandra * 1. Redistributions of source code must retain the above copyright
10224110Sjchandra *    notice, this list of conditions and the following disclaimer.
11224110Sjchandra * 2. Redistributions in binary form must reproduce the above copyright
12224110Sjchandra *    notice, this list of conditions and the following disclaimer in
13224110Sjchandra *    the documentation and/or other materials provided with the
14224110Sjchandra *    distribution.
15224110Sjchandra *
16224110Sjchandra * THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND
17224110Sjchandra * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18224110Sjchandra * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19224110Sjchandra * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE
20224110Sjchandra * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21224110Sjchandra * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22224110Sjchandra * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23224110Sjchandra * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24224110Sjchandra * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25224110Sjchandra * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26224110Sjchandra * THE POSSIBILITY OF SUCH DAMAGE.
27224110Sjchandra *
28224110Sjchandra * NETLOGIC_BSD */
29224110Sjchandra
30224110Sjchandra#include <sys/cdefs.h>
31224110Sjchandra__FBSDID("$FreeBSD: releng/10.2/sys/mips/nlm/board.c 255368 2013-09-07 18:26:16Z jchandra $");
32224110Sjchandra#include <sys/param.h>
33224110Sjchandra#include <sys/systm.h>
34224110Sjchandra#include <sys/bus.h>
35224110Sjchandra#include <sys/kernel.h>
36224110Sjchandra#include <sys/lock.h>
37224110Sjchandra#include <sys/mutex.h>
38224110Sjchandra
39233542Sjchandra#include <net/ethernet.h>
40233542Sjchandra
41224110Sjchandra#include <mips/nlm/hal/mips-extns.h>
42225394Sjchandra#include <mips/nlm/hal/haldefs.h>
43224110Sjchandra#include <mips/nlm/hal/iomap.h>
44224110Sjchandra#include <mips/nlm/hal/fmn.h>
45224110Sjchandra#include <mips/nlm/hal/pic.h>
46233542Sjchandra#include <mips/nlm/hal/sys.h>
47233545Sjchandra#include <mips/nlm/hal/nae.h>
48224110Sjchandra#include <mips/nlm/hal/uart.h>
49233545Sjchandra#include <mips/nlm/hal/poe.h>
50224110Sjchandra
51233542Sjchandra#include <mips/nlm/xlp.h>
52224110Sjchandra#include <mips/nlm/board.h>
53233545Sjchandra#include <mips/nlm/msgring.h>
54224110Sjchandra
55233542Sjchandrastatic uint8_t board_eeprom_buf[EEPROM_SIZE];
56233542Sjchandrastatic int board_eeprom_set;
57233542Sjchandra
58224110Sjchandrastruct xlp_board_info xlp_board_info;
59224110Sjchandra
60233545Sjchandrastruct vfbid_tbl {
61233545Sjchandra	int vfbid;
62233545Sjchandra	int dest_vc;
63233545Sjchandra};
64233545Sjchandra
65233545Sjchandra/* XXXJC : this should be derived from msg thread mask */
66233545Sjchandrastatic struct vfbid_tbl nlm_vfbid[] = {
67233545Sjchandra	/* NULL FBID should map to cpu0 to detect NAE send msg errors */
68233545Sjchandra	{127,   0}, /* NAE <-> NAE mappings */
69233545Sjchandra	{51, 1019}, {50, 1018}, {49, 1017}, {48, 1016},
70233545Sjchandra	{47, 1015}, {46, 1014}, {45, 1013}, {44, 1012},
71233545Sjchandra	{43, 1011}, {42, 1010}, {41, 1009}, {40, 1008},
72233545Sjchandra	{39, 1007}, {38, 1006}, {37, 1005}, {36, 1004},
73233545Sjchandra	{35, 1003}, {34, 1002}, {33, 1001}, {32, 1000},
74233545Sjchandra	/* NAE <-> CPU mappings, freeback got to vc 3 of each thread */
75233545Sjchandra	{31,  127}, {30,  123}, {29,  119}, {28,  115},
76233545Sjchandra	{27,  111}, {26,  107}, {25,  103}, {24,   99},
77233545Sjchandra	{23,   95}, {22,   91}, {21,   87}, {20,   83},
78233545Sjchandra	{19,   79}, {18,   75}, {17,   71}, {16,   67},
79233545Sjchandra	{15,   63}, {14,   59}, {13,   55}, {12,   51},
80233545Sjchandra	{11,   47}, {10,   43}, { 9,   39}, { 8,   35},
81233545Sjchandra	{ 7,   31}, { 6,   27}, { 5,   23}, { 4,   19},
82233545Sjchandra	{ 3,   15}, { 2,   11}, { 1,    7}, { 0,    3},
83233545Sjchandra};
84233545Sjchandra
85233545Sjchandrastatic struct vfbid_tbl nlm3xx_vfbid[] = {
86233545Sjchandra	/* NULL FBID should map to cpu0 to detect NAE send msg errors */
87233545Sjchandra	{127,   0}, /* NAE <-> NAE mappings */
88233545Sjchandra	{39,  503}, {38,  502}, {37,  501}, {36,  500},
89233545Sjchandra	{35,  499}, {34,  498}, {33,  497}, {32,  496},
90233545Sjchandra	/* NAE <-> CPU mappings, freeback got to vc 3 of each thread */
91233545Sjchandra	{31,  127}, {30,  123}, {29,  119}, {28,  115},
92233545Sjchandra	{27,  111}, {26,  107}, {25,  103}, {24,   99},
93233545Sjchandra	{23,   95}, {22,   91}, {21,   87}, {20,   83},
94233545Sjchandra	{19,   79}, {18,   75}, {17,   71}, {16,   67},
95233545Sjchandra	{15,   63}, {14,   59}, {13,   55}, {12,   51},
96233545Sjchandra	{11,   47}, {10,   43}, { 9,   39}, { 8,   35},
97233545Sjchandra	{ 7,   31}, { 6,   27}, { 5,   23}, { 4,   19},
98233545Sjchandra	{ 3,   15}, { 2,   11}, { 1,    7}, { 0,    3},
99233545Sjchandra};
100233545Sjchandra
101233545Sjchandraint
102233545Sjchandranlm_get_vfbid_mapping(int vfbid)
103233545Sjchandra{
104233545Sjchandra	int i, nentries;
105233545Sjchandra	struct vfbid_tbl *p;
106233545Sjchandra
107233545Sjchandra	if (nlm_is_xlp3xx()) {
108233545Sjchandra		nentries = sizeof(nlm3xx_vfbid)/sizeof(struct vfbid_tbl);
109233545Sjchandra		p = nlm3xx_vfbid;
110233545Sjchandra	} else {
111233545Sjchandra		nentries = sizeof(nlm_vfbid)/sizeof(struct vfbid_tbl);
112233545Sjchandra		p = nlm_vfbid;
113233545Sjchandra	}
114233545Sjchandra
115233545Sjchandra	for (i = 0; i < nentries; i++) {
116233545Sjchandra		if (p[i].vfbid == vfbid)
117233545Sjchandra		    return (p[i].dest_vc);
118233545Sjchandra	}
119233545Sjchandra
120233545Sjchandra	return (-1);
121233545Sjchandra}
122233545Sjchandra
123233545Sjchandraint
124233545Sjchandranlm_get_poe_distvec(int vec, uint32_t *distvec)
125233545Sjchandra{
126233545Sjchandra
127233545Sjchandra	if (vec != 0)
128233545Sjchandra		return (-1);  /* we support just vec 0 */
129233545Sjchandra	nlm_calc_poe_distvec(xlp_msg_thread_mask, 0, 0, 0,
130233545Sjchandra	    0x1 << XLPGE_RX_VC, distvec);
131233545Sjchandra	return (0);
132233545Sjchandra}
133233545Sjchandra
134233545Sjchandra/*
135233545Sjchandra * All our knowledge of chip and board that cannot be detected by probing
136233545Sjchandra * at run-time goes here
137233545Sjchandra */
138233545Sjchandra
139233545Sjchandravoid
140233545Sjchandraxlpge_get_macaddr(uint8_t *macaddr)
141233545Sjchandra{
142233545Sjchandra
143233545Sjchandra	if (board_eeprom_set == 0) {
144233545Sjchandra		/* No luck, take some reasonable value */
145233545Sjchandra		macaddr[0] = 0x00; macaddr[1] = 0x0f; macaddr[2] = 0x30;
146233545Sjchandra		macaddr[3] = 0x20; macaddr[4] = 0x0d; macaddr[5] = 0x5b;
147233545Sjchandra	} else
148233545Sjchandra		memcpy(macaddr, &board_eeprom_buf[EEPROM_MACADDR_OFFSET],
149233545Sjchandra		    ETHER_ADDR_LEN);
150233545Sjchandra}
151233545Sjchandra
152233542Sjchandrastatic void
153233545Sjchandranlm_setup_port_defaults(struct xlp_port_ivars *p)
154233545Sjchandra{
155233545Sjchandra	p->loopback_mode = 0;
156233545Sjchandra	p->num_channels = 1;
157233545Sjchandra	p->free_desc_sizes = 2048;
158233545Sjchandra	p->vlan_pri_en = 0;
159233545Sjchandra	p->hw_parser_en = 1;
160233545Sjchandra	p->ieee1588_userval = 0;
161233545Sjchandra	p->ieee1588_ptpoff = 0;
162233545Sjchandra	p->ieee1588_tmr1 = 0;
163233545Sjchandra	p->ieee1588_tmr2 = 0;
164233545Sjchandra	p->ieee1588_tmr3 = 0;
165233545Sjchandra	p->ieee1588_inc_intg = 0;
166233545Sjchandra	p->ieee1588_inc_den = 1;
167233545Sjchandra	p->ieee1588_inc_num = 1;
168233545Sjchandra
169233545Sjchandra	if (nlm_is_xlp3xx()) {
170233545Sjchandra		p->stg2_fifo_size = XLP3XX_STG2_FIFO_SZ;
171233545Sjchandra		p->eh_fifo_size = XLP3XX_EH_FIFO_SZ;
172233545Sjchandra		p->frout_fifo_size = XLP3XX_FROUT_FIFO_SZ;
173233545Sjchandra		p->ms_fifo_size = XLP3XX_MS_FIFO_SZ;
174233545Sjchandra		p->pkt_fifo_size = XLP3XX_PKT_FIFO_SZ;
175233545Sjchandra		p->pktlen_fifo_size = XLP3XX_PKTLEN_FIFO_SZ;
176233545Sjchandra		p->max_stg2_offset = XLP3XX_MAX_STG2_OFFSET;
177233545Sjchandra		p->max_eh_offset = XLP3XX_MAX_EH_OFFSET;
178233545Sjchandra		p->max_frout_offset = XLP3XX_MAX_FREE_OUT_OFFSET;
179233545Sjchandra		p->max_ms_offset = XLP3XX_MAX_MS_OFFSET;
180233545Sjchandra		p->max_pmem_offset = XLP3XX_MAX_PMEM_OFFSET;
181233545Sjchandra		p->stg1_2_credit = XLP3XX_STG1_2_CREDIT;
182233545Sjchandra		p->stg2_eh_credit = XLP3XX_STG2_EH_CREDIT;
183233545Sjchandra		p->stg2_frout_credit = XLP3XX_STG2_FROUT_CREDIT;
184233545Sjchandra		p->stg2_ms_credit = XLP3XX_STG2_MS_CREDIT;
185233545Sjchandra	} else {
186233545Sjchandra		p->stg2_fifo_size = XLP8XX_STG2_FIFO_SZ;
187233545Sjchandra		p->eh_fifo_size = XLP8XX_EH_FIFO_SZ;
188233545Sjchandra		p->frout_fifo_size = XLP8XX_FROUT_FIFO_SZ;
189233545Sjchandra		p->ms_fifo_size = XLP8XX_MS_FIFO_SZ;
190233545Sjchandra		p->pkt_fifo_size = XLP8XX_PKT_FIFO_SZ;
191233545Sjchandra		p->pktlen_fifo_size = XLP8XX_PKTLEN_FIFO_SZ;
192233545Sjchandra		p->max_stg2_offset = XLP8XX_MAX_STG2_OFFSET;
193233545Sjchandra		p->max_eh_offset = XLP8XX_MAX_EH_OFFSET;
194233545Sjchandra		p->max_frout_offset = XLP8XX_MAX_FREE_OUT_OFFSET;
195233545Sjchandra		p->max_ms_offset = XLP8XX_MAX_MS_OFFSET;
196233545Sjchandra		p->max_pmem_offset = XLP8XX_MAX_PMEM_OFFSET;
197233545Sjchandra		p->stg1_2_credit = XLP8XX_STG1_2_CREDIT;
198233545Sjchandra		p->stg2_eh_credit = XLP8XX_STG2_EH_CREDIT;
199233545Sjchandra		p->stg2_frout_credit = XLP8XX_STG2_FROUT_CREDIT;
200233545Sjchandra		p->stg2_ms_credit = XLP8XX_STG2_MS_CREDIT;
201233545Sjchandra	}
202233545Sjchandra
203233545Sjchandra	switch (p->type) {
204233545Sjchandra	case SGMIIC:
205233545Sjchandra		p->num_free_descs = 52;
206233545Sjchandra		p->iface_fifo_size = 13;
207233545Sjchandra		p->rxbuf_size = 128;
208233545Sjchandra		p->rx_slots_reqd = SGMII_CAL_SLOTS;
209233545Sjchandra		p->tx_slots_reqd = SGMII_CAL_SLOTS;
210233545Sjchandra		if (nlm_is_xlp3xx())
211233545Sjchandra		    p->pseq_fifo_size = 30;
212233545Sjchandra		else
213233545Sjchandra		    p->pseq_fifo_size = 62;
214233545Sjchandra		break;
215233545Sjchandra	case ILC:
216233545Sjchandra		p->num_free_descs = 150;
217233545Sjchandra		p->rxbuf_size = 944;
218233545Sjchandra		p->rx_slots_reqd = IL8_CAL_SLOTS;
219233545Sjchandra		p->tx_slots_reqd = IL8_CAL_SLOTS;
220233545Sjchandra		p->pseq_fifo_size = 225;
221233545Sjchandra		p->iface_fifo_size = 55;
222233545Sjchandra		break;
223233545Sjchandra	case XAUIC:
224233545Sjchandra	default:
225233545Sjchandra		p->num_free_descs = 150;
226233545Sjchandra		p->rxbuf_size = 944;
227233545Sjchandra		p->rx_slots_reqd = XAUI_CAL_SLOTS;
228233545Sjchandra		p->tx_slots_reqd = XAUI_CAL_SLOTS;
229233545Sjchandra		if (nlm_is_xlp3xx()) {
230233545Sjchandra		    p->pseq_fifo_size = 120;
231233545Sjchandra		    p->iface_fifo_size = 52;
232233545Sjchandra		} else {
233233545Sjchandra		    p->pseq_fifo_size = 225;
234233545Sjchandra		    p->iface_fifo_size = 55;
235233545Sjchandra		}
236233545Sjchandra		break;
237233545Sjchandra	}
238233545Sjchandra}
239233545Sjchandra
240233545Sjchandra/* XLP 8XX evaluation boards have the following phy-addr
241233545Sjchandra * assignment. There are two external mdio buses in XLP --
242233545Sjchandra * bus 0 and bus 1. The management ports (16 and 17) are
243233545Sjchandra * on mdio bus 0 while blocks/complexes[0 to 3] are all
244233545Sjchandra * on mdio bus 1. The phy_addr on bus 0 (mgmt ports 16
245233545Sjchandra * and 17) match the port numbers.
246233545Sjchandra * These are the details:
247233545Sjchandra * block  port   phy_addr   mdio_bus
248233545Sjchandra * ====================================
249233545Sjchandra * 0         0     4          1
250233545Sjchandra * 0         1     7          1
251233545Sjchandra * 0         2     6          1
252233545Sjchandra * 0         3     5          1
253233545Sjchandra * 1         0     8          1
254233545Sjchandra * 1         1     11         1
255233545Sjchandra * 1         2     10         1
256233545Sjchandra * 1         3     9          1
257233545Sjchandra * 2         0     0          1
258233545Sjchandra * 2         1     3          1
259233545Sjchandra * 2         2     2          1
260233545Sjchandra * 2         3     1          1
261233545Sjchandra * 3         0     12         1
262233545Sjchandra * 3         1     15         1
263233545Sjchandra * 3         2     14         1
264233545Sjchandra * 3         3     13         1
265233545Sjchandra *
266233545Sjchandra * 4         0     16         0
267233545Sjchandra * 4         1     17         0
268233545Sjchandra *
269233545Sjchandra * The XLP 3XX evaluation boards have the following phy-addr
270233545Sjchandra * assignments.
271233545Sjchandra * block  port   phy_addr   mdio_bus
272233545Sjchandra * ====================================
273233545Sjchandra * 0         0     4          0
274233545Sjchandra * 0         1     7          0
275233545Sjchandra * 0         2     6          0
276233545Sjchandra * 0         3     5          0
277233545Sjchandra * 1         0     8          0
278233545Sjchandra * 1         1     11         0
279233545Sjchandra * 1         2     10         0
280233545Sjchandra * 1         3     9          0
281233545Sjchandra */
282233545Sjchandrastatic void
283255368Sjchandranlm_board_get_phyaddr(int block, int port, int *phyaddr)
284233545Sjchandra{
285233545Sjchandra	switch (block) {
286233545Sjchandra	case 0: switch (port) {
287233545Sjchandra		case 0: *phyaddr = 4; break;
288233545Sjchandra		case 1: *phyaddr = 7; break;
289233545Sjchandra		case 2: *phyaddr = 6; break;
290233545Sjchandra		case 3: *phyaddr = 5; break;
291233545Sjchandra		}
292233545Sjchandra		break;
293233545Sjchandra	case 1: switch (port) {
294233545Sjchandra		case 0: *phyaddr = 8; break;
295233545Sjchandra		case 1: *phyaddr = 11; break;
296233545Sjchandra		case 2: *phyaddr = 10; break;
297233545Sjchandra		case 3: *phyaddr = 9; break;
298233545Sjchandra		}
299233545Sjchandra		break;
300233545Sjchandra	case 2: switch (port) {
301233545Sjchandra		case 0: *phyaddr = 0; break;
302233545Sjchandra		case 1: *phyaddr = 3; break;
303233545Sjchandra		case 2: *phyaddr = 2; break;
304233545Sjchandra		case 3: *phyaddr = 1; break;
305233545Sjchandra		}
306233545Sjchandra		break;
307233545Sjchandra	case 3: switch (port) {
308233545Sjchandra		case 0: *phyaddr = 12; break;
309233545Sjchandra		case 1: *phyaddr = 15; break;
310233545Sjchandra		case 2: *phyaddr = 14; break;
311233545Sjchandra		case 3: *phyaddr = 13; break;
312233545Sjchandra		}
313233545Sjchandra		break;
314233545Sjchandra	case 4: switch (port) { /* management SGMII */
315233545Sjchandra		case 0: *phyaddr = 16; break;
316233545Sjchandra		case 1: *phyaddr = 17; break;
317233545Sjchandra		}
318233545Sjchandra		break;
319233545Sjchandra	}
320233545Sjchandra}
321233545Sjchandra
322233545Sjchandra
323233545Sjchandrastatic void
324233542Sjchandranlm_print_processor_info(void)
325233542Sjchandra{
326233542Sjchandra	uint32_t procid;
327233542Sjchandra	int prid, rev;
328233542Sjchandra	char *chip, *revstr;
329224110Sjchandra
330233542Sjchandra	procid = mips_rd_prid();
331233542Sjchandra	prid = (procid >> 8) & 0xff;
332233542Sjchandra	rev = procid & 0xff;
333233542Sjchandra
334233542Sjchandra	switch (prid) {
335233542Sjchandra	case CHIP_PROCESSOR_ID_XLP_8XX:
336233542Sjchandra		chip = "XLP 832";
337233542Sjchandra		break;
338233542Sjchandra	case CHIP_PROCESSOR_ID_XLP_3XX:
339233542Sjchandra		chip = "XLP 3xx";
340233542Sjchandra		break;
341233542Sjchandra	case CHIP_PROCESSOR_ID_XLP_432:
342233542Sjchandra	case CHIP_PROCESSOR_ID_XLP_416:
343233542Sjchandra		chip = "XLP 4xx";
344233542Sjchandra		break;
345233542Sjchandra	default:
346233542Sjchandra		chip = "XLP ?xx";
347233542Sjchandra		break;
348233542Sjchandra	}
349233542Sjchandra	switch (rev) {
350233542Sjchandra	case 0:
351233542Sjchandra		revstr = "A0"; break;
352233542Sjchandra	case 1:
353233542Sjchandra		revstr = "A1"; break;
354233542Sjchandra	case 2:
355233542Sjchandra		revstr = "A2"; break;
356233542Sjchandra	case 3:
357233542Sjchandra		revstr = "B0"; break;
358238290Sjchandra	case 4:
359238290Sjchandra		revstr = "B1"; break;
360233542Sjchandra	default:
361233542Sjchandra		revstr = "??"; break;
362233542Sjchandra	}
363233542Sjchandra
364233542Sjchandra	printf("Processor info:\n");
365233542Sjchandra	printf("  Netlogic %s %s [%x]\n", chip, revstr, procid);
366233542Sjchandra}
367233542Sjchandra
368224110Sjchandra/*
369233542Sjchandra * All our knowledge of chip and board that cannot be detected by probing
370224110Sjchandra * at run-time goes here
371224110Sjchandra */
372233542Sjchandrastatic int
373255368Sjchandranlm_setup_xlp_board(int node)
374224110Sjchandra{
375224110Sjchandra	struct xlp_board_info	*boardp;
376233545Sjchandra	struct xlp_node_info	*nodep;
377233545Sjchandra	struct xlp_nae_ivars	*naep;
378233545Sjchandra	struct xlp_block_ivars	*blockp;
379233545Sjchandra	struct xlp_port_ivars	*portp;
380233545Sjchandra	uint64_t cpldbase, nae_pcibase;
381255368Sjchandra	int	block, port, rv, dbtype, usecpld = 0, evp = 0, svp = 0;
382233542Sjchandra	uint8_t *b;
383224110Sjchandra
384224110Sjchandra	/* start with a clean slate */
385224110Sjchandra	boardp = &xlp_board_info;
386255368Sjchandra	if (boardp->nodemask == 0)
387255368Sjchandra		memset(boardp, 0, sizeof(xlp_board_info));
388255368Sjchandra	boardp->nodemask |= (1 << node);
389233542Sjchandra	nlm_print_processor_info();
390224110Sjchandra
391233542Sjchandra	b =  board_eeprom_buf;
392255368Sjchandra	rv = nlm_board_eeprom_read(node, EEPROM_I2CBUS, EEPROM_I2CADDR, 0, b,
393233542Sjchandra	    EEPROM_SIZE);
394233542Sjchandra	if (rv == 0) {
395233542Sjchandra		board_eeprom_set = 1;
396233542Sjchandra		printf("Board info (EEPROM on i2c@%d at %#X):\n",
397233542Sjchandra		    EEPROM_I2CBUS, EEPROM_I2CADDR);
398233542Sjchandra		printf("  Model:      %7.7s %2.2s\n", &b[16], &b[24]);
399233542Sjchandra		printf("  Serial #:   %3.3s-%2.2s\n", &b[27], &b[31]);
400233542Sjchandra		printf("  MAC addr:   %02x:%02x:%02x:%02x:%02x:%02x\n",
401233542Sjchandra		    b[2], b[3], b[4], b[5], b[6], b[7]);
402233542Sjchandra	} else
403233542Sjchandra		printf("Board Info: Error on EEPROM read (i2c@%d %#X).\n",
404233542Sjchandra		    EEPROM_I2CBUS, EEPROM_I2CADDR);
405233542Sjchandra
406255368Sjchandra	nae_pcibase = nlm_get_nae_pcibase(node);
407255368Sjchandra	nodep = &boardp->nodes[node];
408255368Sjchandra	naep = &nodep->nae_ivars;
409255368Sjchandra	naep->node = node;
410233545Sjchandra
411255368Sjchandra	/* frequency at which network block runs */
412255368Sjchandra	naep->freq = 500;
413233545Sjchandra
414255368Sjchandra	/* CRC16 polynomial used for flow table generation */
415255368Sjchandra	naep->flow_crc_poly = 0xffff;
416255368Sjchandra	naep->hw_parser_en = 1;
417255368Sjchandra	naep->prepad_en = 1;
418255368Sjchandra	naep->prepad_size = 3; /* size in 16 byte units */
419255368Sjchandra	naep->ieee_1588_en = 1;
420233545Sjchandra
421255368Sjchandra	naep->ilmask = 0x0;	/* set this based on daughter card */
422255368Sjchandra	naep->xauimask = 0x0;	/* set this based on daughter card */
423255368Sjchandra	naep->sgmiimask = 0x0;	/* set this based on daughter card */
424255368Sjchandra	naep->nblocks = nae_num_complex(nae_pcibase);
425255368Sjchandra	if (strncmp(&b[16], "PCIE", 4) == 0) {
426255368Sjchandra		usecpld = 0; /* XLP PCIe card */
427255368Sjchandra		/* Broadcom's XLP PCIe card has the following
428255368Sjchandra		 * blocks fixed.
429255368Sjchandra		 * blk 0-XAUI, 1-XAUI, 4-SGMII(one port) */
430255368Sjchandra		naep->blockmask = 0x13;
431255368Sjchandra	} else if (strncmp(&b[16], "MB-EVP", 6) == 0) {
432255368Sjchandra		usecpld = 1; /* XLP non-PCIe card which has CPLD */
433255368Sjchandra		evp = 1;
434255368Sjchandra		naep->blockmask = (1 << naep->nblocks) - 1;
435255368Sjchandra	} else if ((strncmp(&b[16], "MB-S", 4) == 0) ||
436255368Sjchandra	    (strncmp(&b[16], "MB_S", 4) == 0)) {
437255368Sjchandra		usecpld = 1; /* XLP non-PCIe card which has CPLD */
438255368Sjchandra		svp = 1;
439255368Sjchandra		/* 3xx chip reports one block extra which is a bug */
440255368Sjchandra		naep->nblocks = naep->nblocks - 1;
441255368Sjchandra		naep->blockmask = (1 << naep->nblocks) - 1;
442255368Sjchandra	} else {
443255368Sjchandra		printf("ERROR!!! Board type:%7s didn't match any board"
444255368Sjchandra		    " type we support\n", &b[16]);
445255368Sjchandra		return (-1);
446255368Sjchandra	}
447255368Sjchandra	cpldbase = nlm_board_cpld_base(node, XLP_EVB_CPLD_CHIPSELECT);
448233545Sjchandra
449255368Sjchandra	/* pretty print network config */
450255368Sjchandra	printf("Network config");
451255368Sjchandra	if (usecpld)
452255368Sjchandra		printf("(from CPLD@%d):\n", XLP_EVB_CPLD_CHIPSELECT);
453255368Sjchandra	else
454255368Sjchandra		printf("(defaults):\n");
455255368Sjchandra	printf("  NAE@%d Blocks: ", node);
456255368Sjchandra	for (block = 0; block < naep->nblocks; block++) {
457255368Sjchandra		char *s = "???";
458233545Sjchandra
459255368Sjchandra		if ((naep->blockmask & (1 << block)) == 0)
460255368Sjchandra			continue;
461255368Sjchandra		blockp = &naep->block_ivars[block];
462255368Sjchandra		blockp->block = block;
463255368Sjchandra		if (usecpld)
464255368Sjchandra			dbtype = nlm_board_cpld_dboard_type(cpldbase, block);
465255368Sjchandra		else
466255368Sjchandra			dbtype = DCARD_XAUI;  /* default XAUI */
467233545Sjchandra
468255368Sjchandra		/* XLP PCIe cards */
469255368Sjchandra		if ((!evp && !svp) && ((block == 2) || (block == 3)))
470255368Sjchandra			dbtype = DCARD_NOT_PRSNT;
471233545Sjchandra
472255368Sjchandra		if (block == 4) {
473255368Sjchandra			/* management block 4 on 8xx or XLP PCIe */
474255368Sjchandra			blockp->type = SGMIIC;
475255368Sjchandra			if (evp)
476255368Sjchandra				blockp->portmask = 0x3;
477233545Sjchandra			else
478255368Sjchandra				blockp->portmask = 0x1;
479255368Sjchandra			naep->sgmiimask |= (1 << block);
480255368Sjchandra		} else {
481255368Sjchandra			switch (dbtype) {
482255368Sjchandra			case DCARD_ILAKEN:
483255368Sjchandra				blockp->type = ILC;
484255368Sjchandra				blockp->portmask = 0x1;
485255368Sjchandra				naep->ilmask |= (1 << block);
486255368Sjchandra				break;
487255368Sjchandra			case DCARD_SGMII:
488233545Sjchandra				blockp->type = SGMIIC;
489255368Sjchandra				blockp->portmask = 0xf;
490233545Sjchandra				naep->sgmiimask |= (1 << block);
491255368Sjchandra				break;
492255368Sjchandra			case DCARD_XAUI:
493255368Sjchandra				blockp->type = XAUIC;
494255368Sjchandra				blockp->portmask = 0x1;
495255368Sjchandra				naep->xauimask |= (1 << block);
496255368Sjchandra				break;
497255368Sjchandra			default: /* DCARD_NOT_PRSNT */
498255368Sjchandra				blockp->type = UNKNOWN;
499255368Sjchandra				blockp->portmask = 0;
500255368Sjchandra				break;
501233545Sjchandra			}
502255368Sjchandra		}
503255368Sjchandra		if (blockp->type != UNKNOWN) {
504233545Sjchandra			for (port = 0; port < PORTS_PER_CMPLX; port++) {
505233545Sjchandra				if ((blockp->portmask & (1 << port)) == 0)
506233545Sjchandra					continue;
507233545Sjchandra				portp = &blockp->port_ivars[port];
508233545Sjchandra				nlm_board_get_phyaddr(block, port,
509255368Sjchandra				    &portp->phy_addr);
510255368Sjchandra				if (svp || (block == 4))
511255368Sjchandra					portp->mdio_bus = 0;
512255368Sjchandra				else
513255368Sjchandra					portp->mdio_bus = 1;
514233545Sjchandra				portp->port = port;
515233545Sjchandra				portp->block = block;
516233545Sjchandra				portp->node = node;
517233545Sjchandra				portp->type = blockp->type;
518233545Sjchandra				nlm_setup_port_defaults(portp);
519233545Sjchandra			}
520233545Sjchandra		}
521255368Sjchandra		switch (blockp->type) {
522255368Sjchandra		case SGMIIC : s = "SGMII"; break;
523255368Sjchandra		case XAUIC  : s = "XAUI"; break;
524255368Sjchandra		case ILC    : s = "IL"; break;
525233545Sjchandra		}
526255368Sjchandra		printf(" [%d %s]", block, s);
527233545Sjchandra	}
528255368Sjchandra	printf("\n");
529233542Sjchandra	return (0);
530224110Sjchandra}
531224110Sjchandra
532233542Sjchandraint nlm_board_info_setup(void)
533224110Sjchandra{
534255368Sjchandra	if (nlm_setup_xlp_board(0) != 0)
535255368Sjchandra		return (-1);
536233542Sjchandra	return (0);
537224110Sjchandra}
538