539 lines
15 KiB
C
539 lines
15 KiB
C
/*-
|
|
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
|
*
|
|
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights
|
|
* reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in
|
|
* the documentation and/or other materials provided with the
|
|
* distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* NETLOGIC_BSD */
|
|
|
|
#include <sys/cdefs.h>
|
|
__FBSDID("$FreeBSD$");
|
|
#include <sys/param.h>
|
|
#include <sys/systm.h>
|
|
#include <sys/bus.h>
|
|
#include <sys/kernel.h>
|
|
#include <sys/lock.h>
|
|
#include <sys/mutex.h>
|
|
|
|
#include <net/ethernet.h>
|
|
|
|
#include <mips/nlm/hal/mips-extns.h>
|
|
#include <mips/nlm/hal/haldefs.h>
|
|
#include <mips/nlm/hal/iomap.h>
|
|
#include <mips/nlm/hal/fmn.h>
|
|
#include <mips/nlm/hal/pic.h>
|
|
#include <mips/nlm/hal/sys.h>
|
|
#include <mips/nlm/hal/nae.h>
|
|
#include <mips/nlm/hal/uart.h>
|
|
#include <mips/nlm/hal/poe.h>
|
|
|
|
#include <mips/nlm/xlp.h>
|
|
#include <mips/nlm/board.h>
|
|
#include <mips/nlm/msgring.h>
|
|
|
|
static uint8_t board_eeprom_buf[EEPROM_SIZE];
|
|
static int board_eeprom_set;
|
|
|
|
struct xlp_board_info xlp_board_info;
|
|
|
|
struct vfbid_tbl {
|
|
int vfbid;
|
|
int dest_vc;
|
|
};
|
|
|
|
/* XXXJC : this should be derived from msg thread mask */
|
|
static struct vfbid_tbl nlm_vfbid[] = {
|
|
/* NULL FBID should map to cpu0 to detect NAE send msg errors */
|
|
{127, 0}, /* NAE <-> NAE mappings */
|
|
{51, 1019}, {50, 1018}, {49, 1017}, {48, 1016},
|
|
{47, 1015}, {46, 1014}, {45, 1013}, {44, 1012},
|
|
{43, 1011}, {42, 1010}, {41, 1009}, {40, 1008},
|
|
{39, 1007}, {38, 1006}, {37, 1005}, {36, 1004},
|
|
{35, 1003}, {34, 1002}, {33, 1001}, {32, 1000},
|
|
/* NAE <-> CPU mappings, freeback got to vc 3 of each thread */
|
|
{31, 127}, {30, 123}, {29, 119}, {28, 115},
|
|
{27, 111}, {26, 107}, {25, 103}, {24, 99},
|
|
{23, 95}, {22, 91}, {21, 87}, {20, 83},
|
|
{19, 79}, {18, 75}, {17, 71}, {16, 67},
|
|
{15, 63}, {14, 59}, {13, 55}, {12, 51},
|
|
{11, 47}, {10, 43}, { 9, 39}, { 8, 35},
|
|
{ 7, 31}, { 6, 27}, { 5, 23}, { 4, 19},
|
|
{ 3, 15}, { 2, 11}, { 1, 7}, { 0, 3},
|
|
};
|
|
|
|
static struct vfbid_tbl nlm3xx_vfbid[] = {
|
|
/* NULL FBID should map to cpu0 to detect NAE send msg errors */
|
|
{127, 0}, /* NAE <-> NAE mappings */
|
|
{39, 503}, {38, 502}, {37, 501}, {36, 500},
|
|
{35, 499}, {34, 498}, {33, 497}, {32, 496},
|
|
/* NAE <-> CPU mappings, freeback got to vc 3 of each thread */
|
|
{31, 127}, {30, 123}, {29, 119}, {28, 115},
|
|
{27, 111}, {26, 107}, {25, 103}, {24, 99},
|
|
{23, 95}, {22, 91}, {21, 87}, {20, 83},
|
|
{19, 79}, {18, 75}, {17, 71}, {16, 67},
|
|
{15, 63}, {14, 59}, {13, 55}, {12, 51},
|
|
{11, 47}, {10, 43}, { 9, 39}, { 8, 35},
|
|
{ 7, 31}, { 6, 27}, { 5, 23}, { 4, 19},
|
|
{ 3, 15}, { 2, 11}, { 1, 7}, { 0, 3},
|
|
};
|
|
|
|
int
|
|
nlm_get_vfbid_mapping(int vfbid)
|
|
{
|
|
int i, nentries;
|
|
struct vfbid_tbl *p;
|
|
|
|
if (nlm_is_xlp3xx()) {
|
|
nentries = nitems(nlm3xx_vfbid);
|
|
p = nlm3xx_vfbid;
|
|
} else {
|
|
nentries = nitems(nlm_vfbid);
|
|
p = nlm_vfbid;
|
|
}
|
|
|
|
for (i = 0; i < nentries; i++) {
|
|
if (p[i].vfbid == vfbid)
|
|
return (p[i].dest_vc);
|
|
}
|
|
|
|
return (-1);
|
|
}
|
|
|
|
int
|
|
nlm_get_poe_distvec(int vec, uint32_t *distvec)
|
|
{
|
|
|
|
if (vec != 0)
|
|
return (-1); /* we support just vec 0 */
|
|
nlm_calc_poe_distvec(xlp_msg_thread_mask, 0, 0, 0,
|
|
0x1 << XLPGE_RX_VC, distvec);
|
|
return (0);
|
|
}
|
|
|
|
/*
|
|
* All our knowledge of chip and board that cannot be detected by probing
|
|
* at run-time goes here
|
|
*/
|
|
|
|
void
|
|
xlpge_get_macaddr(uint8_t *macaddr)
|
|
{
|
|
|
|
if (board_eeprom_set == 0) {
|
|
/* No luck, take some reasonable value */
|
|
macaddr[0] = 0x00; macaddr[1] = 0x0f; macaddr[2] = 0x30;
|
|
macaddr[3] = 0x20; macaddr[4] = 0x0d; macaddr[5] = 0x5b;
|
|
} else
|
|
memcpy(macaddr, &board_eeprom_buf[EEPROM_MACADDR_OFFSET],
|
|
ETHER_ADDR_LEN);
|
|
}
|
|
|
|
static void
|
|
nlm_setup_port_defaults(struct xlp_port_ivars *p)
|
|
{
|
|
p->loopback_mode = 0;
|
|
p->num_channels = 1;
|
|
p->free_desc_sizes = 2048;
|
|
p->vlan_pri_en = 0;
|
|
p->hw_parser_en = 1;
|
|
p->ieee1588_userval = 0;
|
|
p->ieee1588_ptpoff = 0;
|
|
p->ieee1588_tmr1 = 0;
|
|
p->ieee1588_tmr2 = 0;
|
|
p->ieee1588_tmr3 = 0;
|
|
p->ieee1588_inc_intg = 0;
|
|
p->ieee1588_inc_den = 1;
|
|
p->ieee1588_inc_num = 1;
|
|
|
|
if (nlm_is_xlp3xx()) {
|
|
p->stg2_fifo_size = XLP3XX_STG2_FIFO_SZ;
|
|
p->eh_fifo_size = XLP3XX_EH_FIFO_SZ;
|
|
p->frout_fifo_size = XLP3XX_FROUT_FIFO_SZ;
|
|
p->ms_fifo_size = XLP3XX_MS_FIFO_SZ;
|
|
p->pkt_fifo_size = XLP3XX_PKT_FIFO_SZ;
|
|
p->pktlen_fifo_size = XLP3XX_PKTLEN_FIFO_SZ;
|
|
p->max_stg2_offset = XLP3XX_MAX_STG2_OFFSET;
|
|
p->max_eh_offset = XLP3XX_MAX_EH_OFFSET;
|
|
p->max_frout_offset = XLP3XX_MAX_FREE_OUT_OFFSET;
|
|
p->max_ms_offset = XLP3XX_MAX_MS_OFFSET;
|
|
p->max_pmem_offset = XLP3XX_MAX_PMEM_OFFSET;
|
|
p->stg1_2_credit = XLP3XX_STG1_2_CREDIT;
|
|
p->stg2_eh_credit = XLP3XX_STG2_EH_CREDIT;
|
|
p->stg2_frout_credit = XLP3XX_STG2_FROUT_CREDIT;
|
|
p->stg2_ms_credit = XLP3XX_STG2_MS_CREDIT;
|
|
} else {
|
|
p->stg2_fifo_size = XLP8XX_STG2_FIFO_SZ;
|
|
p->eh_fifo_size = XLP8XX_EH_FIFO_SZ;
|
|
p->frout_fifo_size = XLP8XX_FROUT_FIFO_SZ;
|
|
p->ms_fifo_size = XLP8XX_MS_FIFO_SZ;
|
|
p->pkt_fifo_size = XLP8XX_PKT_FIFO_SZ;
|
|
p->pktlen_fifo_size = XLP8XX_PKTLEN_FIFO_SZ;
|
|
p->max_stg2_offset = XLP8XX_MAX_STG2_OFFSET;
|
|
p->max_eh_offset = XLP8XX_MAX_EH_OFFSET;
|
|
p->max_frout_offset = XLP8XX_MAX_FREE_OUT_OFFSET;
|
|
p->max_ms_offset = XLP8XX_MAX_MS_OFFSET;
|
|
p->max_pmem_offset = XLP8XX_MAX_PMEM_OFFSET;
|
|
p->stg1_2_credit = XLP8XX_STG1_2_CREDIT;
|
|
p->stg2_eh_credit = XLP8XX_STG2_EH_CREDIT;
|
|
p->stg2_frout_credit = XLP8XX_STG2_FROUT_CREDIT;
|
|
p->stg2_ms_credit = XLP8XX_STG2_MS_CREDIT;
|
|
}
|
|
|
|
switch (p->type) {
|
|
case SGMIIC:
|
|
p->num_free_descs = 52;
|
|
p->iface_fifo_size = 13;
|
|
p->rxbuf_size = 128;
|
|
p->rx_slots_reqd = SGMII_CAL_SLOTS;
|
|
p->tx_slots_reqd = SGMII_CAL_SLOTS;
|
|
if (nlm_is_xlp3xx())
|
|
p->pseq_fifo_size = 30;
|
|
else
|
|
p->pseq_fifo_size = 62;
|
|
break;
|
|
case ILC:
|
|
p->num_free_descs = 150;
|
|
p->rxbuf_size = 944;
|
|
p->rx_slots_reqd = IL8_CAL_SLOTS;
|
|
p->tx_slots_reqd = IL8_CAL_SLOTS;
|
|
p->pseq_fifo_size = 225;
|
|
p->iface_fifo_size = 55;
|
|
break;
|
|
case XAUIC:
|
|
default:
|
|
p->num_free_descs = 150;
|
|
p->rxbuf_size = 944;
|
|
p->rx_slots_reqd = XAUI_CAL_SLOTS;
|
|
p->tx_slots_reqd = XAUI_CAL_SLOTS;
|
|
if (nlm_is_xlp3xx()) {
|
|
p->pseq_fifo_size = 120;
|
|
p->iface_fifo_size = 52;
|
|
} else {
|
|
p->pseq_fifo_size = 225;
|
|
p->iface_fifo_size = 55;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* XLP 8XX evaluation boards have the following phy-addr
|
|
* assignment. There are two external mdio buses in XLP --
|
|
* bus 0 and bus 1. The management ports (16 and 17) are
|
|
* on mdio bus 0 while blocks/complexes[0 to 3] are all
|
|
* on mdio bus 1. The phy_addr on bus 0 (mgmt ports 16
|
|
* and 17) match the port numbers.
|
|
* These are the details:
|
|
* block port phy_addr mdio_bus
|
|
* ====================================
|
|
* 0 0 4 1
|
|
* 0 1 7 1
|
|
* 0 2 6 1
|
|
* 0 3 5 1
|
|
* 1 0 8 1
|
|
* 1 1 11 1
|
|
* 1 2 10 1
|
|
* 1 3 9 1
|
|
* 2 0 0 1
|
|
* 2 1 3 1
|
|
* 2 2 2 1
|
|
* 2 3 1 1
|
|
* 3 0 12 1
|
|
* 3 1 15 1
|
|
* 3 2 14 1
|
|
* 3 3 13 1
|
|
*
|
|
* 4 0 16 0
|
|
* 4 1 17 0
|
|
*
|
|
* The XLP 3XX evaluation boards have the following phy-addr
|
|
* assignments.
|
|
* block port phy_addr mdio_bus
|
|
* ====================================
|
|
* 0 0 4 0
|
|
* 0 1 7 0
|
|
* 0 2 6 0
|
|
* 0 3 5 0
|
|
* 1 0 8 0
|
|
* 1 1 11 0
|
|
* 1 2 10 0
|
|
* 1 3 9 0
|
|
*/
|
|
static void
|
|
nlm_board_get_phyaddr(int block, int port, int *phyaddr)
|
|
{
|
|
switch (block) {
|
|
case 0: switch (port) {
|
|
case 0: *phyaddr = 4; break;
|
|
case 1: *phyaddr = 7; break;
|
|
case 2: *phyaddr = 6; break;
|
|
case 3: *phyaddr = 5; break;
|
|
}
|
|
break;
|
|
case 1: switch (port) {
|
|
case 0: *phyaddr = 8; break;
|
|
case 1: *phyaddr = 11; break;
|
|
case 2: *phyaddr = 10; break;
|
|
case 3: *phyaddr = 9; break;
|
|
}
|
|
break;
|
|
case 2: switch (port) {
|
|
case 0: *phyaddr = 0; break;
|
|
case 1: *phyaddr = 3; break;
|
|
case 2: *phyaddr = 2; break;
|
|
case 3: *phyaddr = 1; break;
|
|
}
|
|
break;
|
|
case 3: switch (port) {
|
|
case 0: *phyaddr = 12; break;
|
|
case 1: *phyaddr = 15; break;
|
|
case 2: *phyaddr = 14; break;
|
|
case 3: *phyaddr = 13; break;
|
|
}
|
|
break;
|
|
case 4: switch (port) { /* management SGMII */
|
|
case 0: *phyaddr = 16; break;
|
|
case 1: *phyaddr = 17; break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
nlm_print_processor_info(void)
|
|
{
|
|
uint32_t procid;
|
|
int prid, rev;
|
|
char *chip, *revstr;
|
|
|
|
procid = mips_rd_prid();
|
|
prid = (procid >> 8) & 0xff;
|
|
rev = procid & 0xff;
|
|
|
|
switch (prid) {
|
|
case CHIP_PROCESSOR_ID_XLP_8XX:
|
|
chip = "XLP 832";
|
|
break;
|
|
case CHIP_PROCESSOR_ID_XLP_3XX:
|
|
chip = "XLP 3xx";
|
|
break;
|
|
case CHIP_PROCESSOR_ID_XLP_432:
|
|
case CHIP_PROCESSOR_ID_XLP_416:
|
|
chip = "XLP 4xx";
|
|
break;
|
|
default:
|
|
chip = "XLP ?xx";
|
|
break;
|
|
}
|
|
switch (rev) {
|
|
case 0:
|
|
revstr = "A0"; break;
|
|
case 1:
|
|
revstr = "A1"; break;
|
|
case 2:
|
|
revstr = "A2"; break;
|
|
case 3:
|
|
revstr = "B0"; break;
|
|
case 4:
|
|
revstr = "B1"; break;
|
|
default:
|
|
revstr = "??"; break;
|
|
}
|
|
|
|
printf("Processor info:\n");
|
|
printf(" Netlogic %s %s [%x]\n", chip, revstr, procid);
|
|
}
|
|
|
|
/*
|
|
* All our knowledge of chip and board that cannot be detected by probing
|
|
* at run-time goes here
|
|
*/
|
|
static int
|
|
nlm_setup_xlp_board(int node)
|
|
{
|
|
struct xlp_board_info *boardp;
|
|
struct xlp_node_info *nodep;
|
|
struct xlp_nae_ivars *naep;
|
|
struct xlp_block_ivars *blockp;
|
|
struct xlp_port_ivars *portp;
|
|
uint64_t cpldbase, nae_pcibase;
|
|
int block, port, rv, dbtype, usecpld = 0, evp = 0, svp = 0;
|
|
uint8_t *b;
|
|
|
|
/* start with a clean slate */
|
|
boardp = &xlp_board_info;
|
|
if (boardp->nodemask == 0)
|
|
memset(boardp, 0, sizeof(xlp_board_info));
|
|
boardp->nodemask |= (1 << node);
|
|
nlm_print_processor_info();
|
|
|
|
b = board_eeprom_buf;
|
|
rv = nlm_board_eeprom_read(node, EEPROM_I2CBUS, EEPROM_I2CADDR, 0, b,
|
|
EEPROM_SIZE);
|
|
if (rv == 0) {
|
|
board_eeprom_set = 1;
|
|
printf("Board info (EEPROM on i2c@%d at %#X):\n",
|
|
EEPROM_I2CBUS, EEPROM_I2CADDR);
|
|
printf(" Model: %7.7s %2.2s\n", &b[16], &b[24]);
|
|
printf(" Serial #: %3.3s-%2.2s\n", &b[27], &b[31]);
|
|
printf(" MAC addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
|
b[2], b[3], b[4], b[5], b[6], b[7]);
|
|
} else
|
|
printf("Board Info: Error on EEPROM read (i2c@%d %#X).\n",
|
|
EEPROM_I2CBUS, EEPROM_I2CADDR);
|
|
|
|
nae_pcibase = nlm_get_nae_pcibase(node);
|
|
nodep = &boardp->nodes[node];
|
|
naep = &nodep->nae_ivars;
|
|
naep->node = node;
|
|
|
|
/* frequency at which network block runs */
|
|
naep->freq = 500;
|
|
|
|
/* CRC16 polynomial used for flow table generation */
|
|
naep->flow_crc_poly = 0xffff;
|
|
naep->hw_parser_en = 1;
|
|
naep->prepad_en = 1;
|
|
naep->prepad_size = 3; /* size in 16 byte units */
|
|
naep->ieee_1588_en = 1;
|
|
|
|
naep->ilmask = 0x0; /* set this based on daughter card */
|
|
naep->xauimask = 0x0; /* set this based on daughter card */
|
|
naep->sgmiimask = 0x0; /* set this based on daughter card */
|
|
naep->nblocks = nae_num_complex(nae_pcibase);
|
|
if (strncmp(&b[16], "PCIE", 4) == 0) {
|
|
usecpld = 0; /* XLP PCIe card */
|
|
/* Broadcom's XLP PCIe card has the following
|
|
* blocks fixed.
|
|
* blk 0-XAUI, 1-XAUI, 4-SGMII(one port) */
|
|
naep->blockmask = 0x13;
|
|
} else if (strncmp(&b[16], "MB-EVP", 6) == 0) {
|
|
usecpld = 1; /* XLP non-PCIe card which has CPLD */
|
|
evp = 1;
|
|
naep->blockmask = (1 << naep->nblocks) - 1;
|
|
} else if ((strncmp(&b[16], "MB-S", 4) == 0) ||
|
|
(strncmp(&b[16], "MB_S", 4) == 0)) {
|
|
usecpld = 1; /* XLP non-PCIe card which has CPLD */
|
|
svp = 1;
|
|
/* 3xx chip reports one block extra which is a bug */
|
|
naep->nblocks = naep->nblocks - 1;
|
|
naep->blockmask = (1 << naep->nblocks) - 1;
|
|
} else {
|
|
printf("ERROR!!! Board type:%7s didn't match any board"
|
|
" type we support\n", &b[16]);
|
|
return (-1);
|
|
}
|
|
cpldbase = nlm_board_cpld_base(node, XLP_EVB_CPLD_CHIPSELECT);
|
|
|
|
/* pretty print network config */
|
|
printf("Network config");
|
|
if (usecpld)
|
|
printf("(from CPLD@%d):\n", XLP_EVB_CPLD_CHIPSELECT);
|
|
else
|
|
printf("(defaults):\n");
|
|
printf(" NAE@%d Blocks: ", node);
|
|
for (block = 0; block < naep->nblocks; block++) {
|
|
char *s = "???";
|
|
|
|
if ((naep->blockmask & (1 << block)) == 0)
|
|
continue;
|
|
blockp = &naep->block_ivars[block];
|
|
blockp->block = block;
|
|
if (usecpld)
|
|
dbtype = nlm_board_cpld_dboard_type(cpldbase, block);
|
|
else
|
|
dbtype = DCARD_XAUI; /* default XAUI */
|
|
|
|
/* XLP PCIe cards */
|
|
if ((!evp && !svp) && ((block == 2) || (block == 3)))
|
|
dbtype = DCARD_NOT_PRSNT;
|
|
|
|
if (block == 4) {
|
|
/* management block 4 on 8xx or XLP PCIe */
|
|
blockp->type = SGMIIC;
|
|
if (evp)
|
|
blockp->portmask = 0x3;
|
|
else
|
|
blockp->portmask = 0x1;
|
|
naep->sgmiimask |= (1 << block);
|
|
} else {
|
|
switch (dbtype) {
|
|
case DCARD_ILAKEN:
|
|
blockp->type = ILC;
|
|
blockp->portmask = 0x1;
|
|
naep->ilmask |= (1 << block);
|
|
break;
|
|
case DCARD_SGMII:
|
|
blockp->type = SGMIIC;
|
|
blockp->portmask = 0xf;
|
|
naep->sgmiimask |= (1 << block);
|
|
break;
|
|
case DCARD_XAUI:
|
|
blockp->type = XAUIC;
|
|
blockp->portmask = 0x1;
|
|
naep->xauimask |= (1 << block);
|
|
break;
|
|
default: /* DCARD_NOT_PRSNT */
|
|
blockp->type = UNKNOWN;
|
|
blockp->portmask = 0;
|
|
break;
|
|
}
|
|
}
|
|
if (blockp->type != UNKNOWN) {
|
|
for (port = 0; port < PORTS_PER_CMPLX; port++) {
|
|
if ((blockp->portmask & (1 << port)) == 0)
|
|
continue;
|
|
portp = &blockp->port_ivars[port];
|
|
nlm_board_get_phyaddr(block, port,
|
|
&portp->phy_addr);
|
|
if (svp || (block == 4))
|
|
portp->mdio_bus = 0;
|
|
else
|
|
portp->mdio_bus = 1;
|
|
portp->port = port;
|
|
portp->block = block;
|
|
portp->node = node;
|
|
portp->type = blockp->type;
|
|
nlm_setup_port_defaults(portp);
|
|
}
|
|
}
|
|
switch (blockp->type) {
|
|
case SGMIIC : s = "SGMII"; break;
|
|
case XAUIC : s = "XAUI"; break;
|
|
case ILC : s = "IL"; break;
|
|
}
|
|
printf(" [%d %s]", block, s);
|
|
}
|
|
printf("\n");
|
|
return (0);
|
|
}
|
|
|
|
int nlm_board_info_setup(void)
|
|
{
|
|
if (nlm_setup_xlp_board(0) != 0)
|
|
return (-1);
|
|
return (0);
|
|
}
|