summaryrefslogtreecommitdiffstats
path: root/sys/mips
diff options
context:
space:
mode:
authorjchandra <jchandra@FreeBSD.org>2013-09-07 18:26:16 +0000
committerjchandra <jchandra@FreeBSD.org>2013-09-07 18:26:16 +0000
commit0c58b324e7721e5bd0c1e0f78e1dbbe9b091195b (patch)
treee9989f791e2f10c363fc210002c0510c8b7b6494 /sys/mips
parent7618cc8395426b79f319af2310c0d0fd3b4bed02 (diff)
downloadFreeBSD-src-0c58b324e7721e5bd0c1e0f78e1dbbe9b091195b.zip
FreeBSD-src-0c58b324e7721e5bd0c1e0f78e1dbbe9b091195b.tar.gz
Netlogic XLP network driver update
Changes are to - update board and network interface detection logic - fix reading onboard CPLD in little-endian config - print NAE frequency conrrectly for Bx chips - update XAUI config to disable Rx/Tx until interface is up Submitted by: Venkatesh J V <venkatesh.vivekanandan@broadcom.com>
Diffstat (limited to 'sys/mips')
-rw-r--r--sys/mips/nlm/board.c210
-rw-r--r--sys/mips/nlm/board.h1
-rw-r--r--sys/mips/nlm/board_cpld.c4
-rw-r--r--sys/mips/nlm/dev/net/nae.c142
-rw-r--r--sys/mips/nlm/dev/net/xaui.c4
-rw-r--r--sys/mips/nlm/dev/net/xlpge.c140
-rw-r--r--sys/mips/nlm/dev/net/xlpge.h3
-rw-r--r--sys/mips/nlm/hal/nae.h12
-rw-r--r--sys/mips/nlm/hal/nlm_hal.c5
-rw-r--r--sys/mips/nlm/hal/sys.h2
10 files changed, 222 insertions, 301 deletions
diff --git a/sys/mips/nlm/board.c b/sys/mips/nlm/board.c
index c6fd59d..e7fd92e 100644
--- a/sys/mips/nlm/board.c
+++ b/sys/mips/nlm/board.c
@@ -280,15 +280,8 @@ nlm_setup_port_defaults(struct xlp_port_ivars *p)
* 1 3 9 0
*/
static void
-nlm_board_get_phyaddr(int block, int port, int *mdio, int *phyaddr)
+nlm_board_get_phyaddr(int block, int port, int *phyaddr)
{
-
- /* XXXJC: this is a board feature, check for chip not proper */
- if (nlm_is_xlp3xx() || (nlm_is_xlp8xx() && block == 4))
- *mdio = 0;
- else
- *mdio = 1;
-
switch (block) {
case 0: switch (port) {
case 0: *phyaddr = 4; break;
@@ -377,7 +370,7 @@ nlm_print_processor_info(void)
* at run-time goes here
*/
static int
-nlm_setup_xlp_board(void)
+nlm_setup_xlp_board(int node)
{
struct xlp_board_info *boardp;
struct xlp_node_info *nodep;
@@ -385,17 +378,18 @@ nlm_setup_xlp_board(void)
struct xlp_block_ivars *blockp;
struct xlp_port_ivars *portp;
uint64_t cpldbase, nae_pcibase;
- int node, block, port, rv, dbtype, usecpld;
+ int block, port, rv, dbtype, usecpld = 0, evp = 0, svp = 0;
uint8_t *b;
/* start with a clean slate */
boardp = &xlp_board_info;
- memset(boardp, 0, sizeof(xlp_board_info));
- boardp->nodemask = 0x1; /* only node 0 */
+ 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(0, EEPROM_I2CBUS, EEPROM_I2CADDR, 0, b,
+ rv = nlm_board_eeprom_read(node, EEPROM_I2CBUS, EEPROM_I2CADDR, 0, b,
EEPROM_SIZE);
if (rv == 0) {
board_eeprom_set = 1;
@@ -409,80 +403,114 @@ nlm_setup_xlp_board(void)
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);
- /* XXXJC: check for boards with right CPLD, for now
- * 4xx PCI cards don't have CPLD with daughter
- * card info */
- usecpld = !nlm_is_xlp4xx();
+ /* 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 = "???";
- for (node = 0; node < XLP_MAX_NODES; node++) {
- if ((boardp->nodemask & (1 << node)) == 0)
+ if ((naep->blockmask & (1 << block)) == 0)
continue;
- nae_pcibase = nlm_get_nae_pcibase(node);
- nodep = &boardp->nodes[node];
- naep = &nodep->nae_ivars;
- naep->node = node;
+ blockp = &naep->block_ivars[block];
+ blockp->block = block;
+ if (usecpld)
+ dbtype = nlm_board_cpld_dboard_type(cpldbase, block);
+ else
+ dbtype = DCARD_XAUI; /* default XAUI */
- naep->nblocks = nae_num_complex(nae_pcibase);
- /* 3xx chips lie shamelessly about this */
- if (nlm_is_xlp3xx())
- naep->nblocks = naep->nblocks - 1;
- naep->blockmask = (1 << naep->nblocks) - 1; /* XXXJC: redundant */
- naep->xauimask = 0x0; /* set this based on daughter card */
- naep->sgmiimask = 0x0; /* set this based on daughter card */
-
- /* 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;
- cpldbase = nlm_board_cpld_base(node, XLP_EVB_CPLD_CHIPSELECT);
-
- for (block = 0; block < naep->nblocks; block++) {
- 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 */
- blockp->type = SGMIIC;
+ 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);
- } else {
- switch (dbtype) {
- case DCARD_ILAKEN:
- blockp->type = ILC;
- blockp->portmask = 0x1;
- naep->xauimask |= (1 << block);
- break;
- case DCARD_SGMII:
- blockp->type = SGMIIC;
- blockp->portmask = 0xf;
- naep->sgmiimask |= (1 << block);
- break;
- case DCARD_XAUI:
- default:
- blockp->type = XAUIC;
- blockp->portmask = 0x1;
- naep->xauimask |= (1 << block);
- break;
- }
+ 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->mdio_bus, &portp->phy_addr);
+ &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;
@@ -490,38 +518,20 @@ nlm_setup_xlp_board(void)
nlm_setup_port_defaults(portp);
}
}
- }
-
- /* pretty print network config */
- printf("Network config");
- if (usecpld)
- printf("(from CPLD@%d):\n", XLP_EVB_CPLD_CHIPSELECT);
- else
- printf("(defaults):\n");
- for (node = 0; node < XLP_MAX_NODES; node++) {
- if ((boardp->nodemask & (1 << node)) == 0)
- continue;
- nodep = &boardp->nodes[node];
- naep = &nodep->nae_ivars;
- printf(" NAE@%d Blocks: ", node);
- for (block = 0; block < naep->nblocks; block++) {
- char *s = "???";
-
- blockp = &naep->block_ivars[block];
- switch (blockp->type) {
- case SGMIIC : s = "SGMII"; break;
- case XAUIC : s = "XAUI"; break;
- case ILC : s = "IL"; break;
- }
- printf(" [%d %s]", block, s);
+ switch (blockp->type) {
+ case SGMIIC : s = "SGMII"; break;
+ case XAUIC : s = "XAUI"; break;
+ case ILC : s = "IL"; break;
}
- printf("\n");
+ printf(" [%d %s]", block, s);
}
+ printf("\n");
return (0);
}
int nlm_board_info_setup(void)
{
- nlm_setup_xlp_board();
+ if (nlm_setup_xlp_board(0) != 0)
+ return (-1);
return (0);
}
diff --git a/sys/mips/nlm/board.h b/sys/mips/nlm/board.h
index 859a654..2f1b433 100644
--- a/sys/mips/nlm/board.h
+++ b/sys/mips/nlm/board.h
@@ -116,6 +116,7 @@ struct xlp_nae_ivars {
int node;
int nblocks;
u_int blockmask;
+ u_int ilmask;
u_int xauimask;
u_int sgmiimask;
int freq;
diff --git a/sys/mips/nlm/board_cpld.c b/sys/mips/nlm/board_cpld.c
index 883a321..ac55c0b 100644
--- a/sys/mips/nlm/board_cpld.c
+++ b/sys/mips/nlm/board_cpld.c
@@ -55,13 +55,13 @@ int nlm_cpld_read(uint64_t base, int reg)
uint16_t val;
val = *(volatile uint16_t *)(long)(base + reg * 2);
- return bswap16(val);
+ return le16toh(val);
}
static __inline void
nlm_cpld_write(uint64_t base, int reg, uint16_t data)
{
- bswap16(data);
+ data = htole16(data);
*(volatile uint16_t *)(long)(base + reg * 2) = data;
}
diff --git a/sys/mips/nlm/dev/net/nae.c b/sys/mips/nlm/dev/net/nae.c
index d97b290..9f06372 100644
--- a/sys/mips/nlm/dev/net/nae.c
+++ b/sys/mips/nlm/dev/net/nae.c
@@ -59,31 +59,17 @@ nlm_nae_flush_free_fifo(uint64_t nae_base, int nblocks)
}
void
-nlm_program_nae_parser_seq_fifo(uint64_t nae_base, int nblock,
+nlm_program_nae_parser_seq_fifo(uint64_t nae_base, int maxports,
struct nae_port_config *cfg)
{
uint32_t val;
- int start = 0, size, i, j;
-
- for (i = 0; i < nblock; i++) {
- for (j = 0; j < PORTS_PER_CMPLX; j++) {
- if ((i == 4) && (j > 1))
- size = 0;
- else
- size = cfg[(i*4)+j].pseq_fifo_size;
- start += size;
- }
- }
-
- for (j = 0; j < PORTS_PER_CMPLX; j++) {
- if ((i == 4) && (j > 1))
- size = 0;
- else
- size = cfg[(i*4)+j].pseq_fifo_size;
+ int start = 0, size, i;
+ for (i = 0; i < maxports; i++) {
+ size = cfg[i].pseq_fifo_size;
val = (((size & 0x1fff) << 17) |
((start & 0xfff) << 5) |
- (((i * 4) + j) & 0x1f));
+ (i & 0x1f));
nlm_write_nae_reg(nae_base, NAE_PARSER_SEQ_FIFO_CFG, val);
start += size;
}
@@ -255,105 +241,66 @@ nlm_setup_flow_crc_poly(uint64_t nae_base, uint32_t poly)
}
void
-nlm_setup_iface_fifo_cfg(uint64_t nae_base, int nblock,
+nlm_setup_iface_fifo_cfg(uint64_t nae_base, int maxports,
struct nae_port_config *cfg)
{
uint32_t reg;
int fifo_xoff_thresh = 12;
- int i, size, j;
+ int i, size;
int cur_iface_start = 0;
- for (i = 0; i < nblock; i++) {
- for (j = 0; j < PORTS_PER_CMPLX; j++) {
- if ((i == 4) && (j > 1))
- size = 0;
- else
- size = cfg[(i*4)+j].iface_fifo_size;
- cur_iface_start += size;
- }
- }
-
- for (j = 0; j < PORTS_PER_CMPLX; j++) {
- if ((i == 4) && (j > 1))
- size = 0;
- else
- size = cfg[(i*4)+j].iface_fifo_size;
+ for (i = 0; i < maxports; i++) {
+ size = cfg[i].iface_fifo_size;
reg = ((fifo_xoff_thresh << 25) |
((size & 0x1ff) << 16) |
((cur_iface_start & 0xff) << 8) |
- (((i * 4) + j) & 0x1f));
+ (i & 0x1f));
nlm_write_nae_reg(nae_base, NAE_IFACE_FIFO_CFG, reg);
cur_iface_start += size;
}
}
void
-nlm_setup_rx_base_config(uint64_t nae_base, int nblock,
+nlm_setup_rx_base_config(uint64_t nae_base, int maxports,
struct nae_port_config *cfg)
{
- uint32_t val, nc;
int base = 0;
- int i, j;
+ uint32_t val;
+ int i;
int id;
- for (i = 0; i < nblock; i++) {
- for (j = 0; j < (PORTS_PER_CMPLX/2); j++) {
- base += cfg[(i*4)+(2*j)].num_channels;
- base += cfg[(i*4)+(2*j + 1)].num_channels;
- }
- }
-
- id = 0x12 + (i * 2); /* RX_IF_BASE_CONFIG0 */
+ for (i = 0; i < (maxports/2); i++) {
+ id = 0x12 + i; /* RX_IF_BASE_CONFIG0 */
- for (j = 0; j < (PORTS_PER_CMPLX/2); j++) {
val = (base & 0x3ff);
- nc = cfg[(i*4)+(2*j)].num_channels;
- base += nc;
+ base += cfg[(i * 2)].num_channels;
val |= ((base & 0x3ff) << 16);
- nc = cfg[(i*4)+(2*j + 1)].num_channels;
- base += nc;
+ base += cfg[(i * 2) + 1].num_channels;
- nlm_write_nae_reg(nae_base, NAE_REG(7, 0, (id+j)), val);
+ nlm_write_nae_reg(nae_base, NAE_REG(7, 0, id), val);
}
}
void
-nlm_setup_rx_buf_config(uint64_t nae_base, int nblock,
+nlm_setup_rx_buf_config(uint64_t nae_base, int maxports,
struct nae_port_config *cfg)
{
uint32_t val;
- int i, sz, j, k;
+ int i, sz, k;
int context = 0;
int base = 0;
- int nc = 0;
- for (i = 0; i < nblock; i++) {
- for (j = 0; j < PORTS_PER_CMPLX; j++) {
- if ((i == 4) && (j > 1))
- nc = 0;
- else
- nc = cfg[(i*4)+j].num_channels;
- for (k = 0; k < nc; k++) {
- sz = cfg[(i*4)+j].rxbuf_size;
- base += sz;
- }
- context += nc;
- }
- }
-
- for (j = 0; j < PORTS_PER_CMPLX; j++) {
- if ((i == 4) && (j > 1))
- nc = 0;
- else
- nc = cfg[(i*4)+j].num_channels;
- for (k = 0; k < nc; k++) {
+ for (i = 0; i < maxports; i++) {
+ if (cfg[i].type == UNKNOWN)
+ continue;
+ for (k = 0; k < cfg[i].num_channels; k++) {
/* write index (context num) */
nlm_write_nae_reg(nae_base, NAE_RXBUF_BASE_DPTH_ADDR,
(context+k));
/* write value (rx buf sizes) */
- sz = cfg[(i*4)+j].rxbuf_size;
+ sz = cfg[i].rxbuf_size;
val = 0x80000000 | ((base << 2) & 0x3fff); /* base */
val |= (((sz << 2) & 0x3fff) << 16); /* size */
@@ -362,46 +309,29 @@ nlm_setup_rx_buf_config(uint64_t nae_base, int nblock,
(0x7fffffff & val));
base += sz;
}
- context += nc;
+ context += cfg[i].num_channels;
}
}
void
-nlm_setup_freein_fifo_cfg(uint64_t nae_base, int nblock,
- struct nae_port_config *cfg)
+nlm_setup_freein_fifo_cfg(uint64_t nae_base, struct nae_port_config *cfg)
{
- int size, i, cp = 0;
+ int size, i;
uint32_t reg;
- int start = 0;
-
- for (cp = 0 ; cp < nblock; cp++ ) {
- for (i = 0; i < PORTS_PER_CMPLX; i++) { /* 4 interfaces */
- if ((cp == 4) && (i > 1))
- size = 0;
- else {
- /* Each entry represents 2 descs; hence division by 2 */
- size = cfg[(cp*4)+i].num_free_descs / 2;
- }
- if (size == 0)
- size = 8;
- start += size;
- }
- }
+ int start = 0, maxbufpool;
- for (i = 0; i < PORTS_PER_CMPLX; i++) { /* 4 interfaces */
- if ((cp == 4) && (i > 1))
- size = 0;
- else {
- /* Each entry represents 2 descs; hence division by 2 */
- size = cfg[(cp*4)+i].num_free_descs / 2;
- }
+ if (nlm_is_xlp8xx())
+ maxbufpool = MAX_FREE_FIFO_POOL_8XX;
+ else
+ maxbufpool = MAX_FREE_FIFO_POOL_3XX;
+ for (i = 0; i < maxbufpool; i++) {
/* Each entry represents 2 descs; hence division by 2 */
+ size = (cfg[i].num_free_descs / 2);
if (size == 0)
size = 8;
-
reg = ((size & 0x3ff ) << 20) | /* fcSize */
((start & 0x1ff) << 8) | /* fcStart */
- (((cp * 4) + i) & 0x1f);
+ (i & 0x1f);
nlm_write_nae_reg(nae_base, NAE_FREE_IN_FIFO_CFG, reg);
start += size;
diff --git a/sys/mips/nlm/dev/net/xaui.c b/sys/mips/nlm/dev/net/xaui.c
index 8b4c6a9..3b18ef9 100644
--- a/sys/mips/nlm/dev/net/xaui.c
+++ b/sys/mips/nlm/dev/net/xaui.c
@@ -211,12 +211,10 @@ nlm_config_xaui(uint64_t nae_base, int nblock,
nlm_write_nae_reg(nae_base, XAUI_CONFIG0(nblock), 0);
/* Enable tx/rx frame */
- val = 0xF00010A8;
+ val = 0x000010A8;
val |= XAUI_CONFIG_LENCHK;
val |= XAUI_CONFIG_GENFCS;
val |= XAUI_CONFIG_PAD_64;
- val |= XAUI_CONFIG_TFEN;
- val |= XAUI_CONFIG_RFEN;
nlm_write_nae_reg(nae_base, XAUI_CONFIG1(nblock), val);
/* write max frame length */
diff --git a/sys/mips/nlm/dev/net/xlpge.c b/sys/mips/nlm/dev/net/xlpge.c
index 18a14b1..3ae1148 100644
--- a/sys/mips/nlm/dev/net/xlpge.c
+++ b/sys/mips/nlm/dev/net/xlpge.c
@@ -306,29 +306,12 @@ static int
xlpnae_get_maxchannels(struct nlm_xlpnae_softc *sc)
{
int maxchans = 0;
- int i, j, port = 0;
+ int i;
- for (i = 0; i < sc->nblocks; i++) {
- switch (sc->cmplx_type[i]) {
- case SGMIIC:
- for (j = 0; j < 4; j++) { /* 4 ports */
- if ((i == 4) && (j > 1))
- continue;
- maxchans += sc->portcfg[port].num_channels;
- port++;
- }
- break;
- case XAUIC:
- maxchans += sc->portcfg[port].num_channels;
- port += 4;
- break;
- case ILC:
- if (((i%2) == 0) && (i != 4)) {
- maxchans += sc->portcfg[port].num_channels;
- port += 4;
- break;
- }
- }
+ for (i = 0; i < sc->max_ports; i++) {
+ if (sc->portcfg[i].type == UNKNOWN)
+ continue;
+ maxchans += sc->portcfg[i].num_channels;
}
return (maxchans);
@@ -374,7 +357,7 @@ nlm_setup_interfaces(struct nlm_xlpnae_softc *sc)
uint32_t cur_slot, cur_slot_base;
uint32_t cur_flow_base, port, flow_mask;
int max_channels;
- int i, j, context;
+ int i, context;
cur_slot = 0;
cur_slot_base = 0;
@@ -386,39 +369,13 @@ nlm_setup_interfaces(struct nlm_xlpnae_softc *sc)
port = 0;
context = 0;
- for (i = 0; i < sc->nblocks; i++) {
- switch (sc->cmplx_type[i]) {
- case SGMIIC:
- for (j = 0; j < 4; j++) { /* 4 ports */
- if ((i == 4) && (j > 1))
- continue;
- nlm_setup_interface(sc, i, port,
- cur_flow_base, flow_mask,
- max_channels, context);
- cur_flow_base += sc->per_port_num_flows;
- context += sc->portcfg[port].num_channels;
- port++;
- }
- break;
- case XAUIC:
- nlm_setup_interface(sc, i, port, cur_flow_base,
- flow_mask, max_channels, context);
- cur_flow_base += sc->per_port_num_flows;
- context += sc->portcfg[port].num_channels;
- port += 4;
- break;
- case ILC:
- if (((i%2) == 0) && (i != 4)) {
- nlm_setup_interface(sc, i, port,
- cur_flow_base, flow_mask,
- max_channels, context);
- cur_flow_base += sc->per_port_num_flows;
- context += sc->portcfg[port].num_channels;
- port += 4;
- }
- break;
- }
- cur_slot_base++;
+ for (i = 0; i < sc->max_ports; i++) {
+ if (sc->portcfg[i].type == UNKNOWN)
+ continue;
+ nlm_setup_interface(sc, sc->portcfg[i].block, i, cur_flow_base,
+ flow_mask, max_channels, context);
+ cur_flow_base += sc->per_port_num_flows;
+ context += sc->portcfg[i].num_channels;
}
}
@@ -481,8 +438,6 @@ nlm_xlpnae_init(int node, struct nlm_xlpnae_softc *sc)
nlm_setup_interfaces(sc);
nlm_config_poe(sc->poe_base, sc->poedv_base);
- nlm_xlpnae_print_frin_desc_carving(sc);
-
if (sc->hw_parser_en)
nlm_enable_hardware_parser(nae_base);
@@ -530,6 +485,12 @@ nlm_setup_portcfg(struct nlm_xlpnae_softc *sc, struct xlp_nae_ivars *naep,
bp = &(naep->block_ivars[block]);
p = &(bp->port_ivars[port & 0x3]);
+ sc->portcfg[port].node = p->node;
+ sc->portcfg[port].block = p->block;
+ sc->portcfg[port].port = p->port;
+ sc->portcfg[port].type = p->type;
+ sc->portcfg[port].mdio_bus = p->mdio_bus;
+ sc->portcfg[port].phy_addr = p->phy_addr;
sc->portcfg[port].loopback_mode = p->loopback_mode;
sc->portcfg[port].num_channels = p->num_channels;
if (p->free_desc_sizes != MCLBYTES) {
@@ -584,7 +545,7 @@ nlm_xlpnae_attach(device_t dev)
struct nlm_xlpnae_softc *sc;
device_t tmpd;
uint32_t dv[NUM_WORDS_PER_DV];
- int port, i, j, n, nchan, nblock, node, qstart, qnum;
+ int port, i, j, nchan, nblock, node, qstart, qnum;
int offset, context, txq_base, rxvcbase;
uint64_t poe_pcibase, nae_pcibase;
@@ -598,6 +559,8 @@ nlm_xlpnae_attach(device_t dev)
sc->poe_base = nlm_get_poe_regbase(sc->node);
sc->poedv_base = nlm_get_poedv_regbase(sc->node);
sc->portcfg = nae_port_config;
+ sc->blockmask = nae_ivars->blockmask;
+ sc->ilmask = nae_ivars->ilmask;
sc->xauimask = nae_ivars->xauimask;
sc->sgmiimask = nae_ivars->sgmiimask;
sc->nblocks = nae_ivars->nblocks;
@@ -615,9 +578,10 @@ nlm_xlpnae_attach(device_t dev)
sc->ncontexts = nlm_read_reg(nae_pcibase, XLP_PCI_DEVINFO_REG5);
sc->nucores = nlm_num_uengines(nae_pcibase);
- /* Initialize the 1st four complexes from board config */
- for (nblock = 0; nblock < sc->nblocks; nblock++)
+ for (nblock = 0; nblock < sc->nblocks; nblock++) {
sc->cmplx_type[nblock] = nae_ivars->block_ivars[nblock].type;
+ sc->portmask[nblock] = nae_ivars->block_ivars[nblock].portmask;
+ }
for (i = 0; i < sc->ncontexts; i++)
cntx2port[i] = 18; /* 18 is an invalid port */
@@ -627,6 +591,8 @@ nlm_xlpnae_attach(device_t dev)
else
sc->max_ports = sc->nblocks * PORTS_PER_CMPLX;
+ for (i = 0; i < sc->max_ports; i++)
+ sc->portcfg[i].type = UNKNOWN; /* Port Not Present */
/*
* Now setup all internal fifo carvings based on
* total number of ports in the system
@@ -638,13 +604,15 @@ nlm_xlpnae_attach(device_t dev)
txq_base = nlm_qidstart(nae_pcibase);
rxvcbase = txq_base + sc->ncontexts;
for (i = 0; i < sc->nblocks; i++) {
- /* only 2 SGMII ports in last complex */
- n = (sc->cmplx_type[i] == SGMIIC && i == 4) ? 2 : 4;
- for (j = 0; j < n; j++, port++) {
- if (sc->cmplx_type[i] == XAUIC && j != 0)
- continue;
- if (sc->cmplx_type[i] == ILC &&
- (i != 0 || i != 2 || j != 0))
+ uint32_t portmask;
+
+ if ((nae_ivars->blockmask & (1 << i)) == 0) {
+ port += 4;
+ continue;
+ }
+ portmask = nae_ivars->block_ivars[i].portmask;
+ for (j = 0; j < PORTS_PER_CMPLX; j++, port++) {
+ if ((portmask & (1 << j)) == 0)
continue;
nlm_setup_portcfg(sc, nae_ivars, i, port);
nchan = sc->portcfg[port].num_channels;
@@ -687,31 +655,27 @@ nlm_xlpnae_attach(device_t dev)
nlm_xlpnae_init(node, sc);
- for (i = 0; i < sc->nblocks; i++) {
+ for (i = 0; i < sc->max_ports; i++) {
char desc[32];
- struct xlp_block_ivars *bv;
+ int block, port;
- if ((nae_ivars->blockmask & (1 << i)) == 0)
+ if (sc->portcfg[i].type == UNKNOWN)
continue;
- bv = &nae_ivars->block_ivars[i];
- for (j = 0; j < PORTS_PER_CMPLX; j++) {
- int port = i * 4 + j;
-
- if ((bv->portmask & (1 << j)) == 0)
- continue;
- tmpd = device_add_child(dev, "xlpge", port);
- device_set_ivars(tmpd, &(bv->port_ivars[j]));
- sprintf(desc, "XLP NAE Port %d,%d", i, j);
- device_set_desc_copy(tmpd, desc);
- }
-
- nlm_setup_iface_fifo_cfg(sc->base, i, sc->portcfg);
- nlm_setup_rx_base_config(sc->base, i, sc->portcfg);
- nlm_setup_rx_buf_config(sc->base, i, sc->portcfg);
- nlm_setup_freein_fifo_cfg(sc->base, i, sc->portcfg);
- nlm_program_nae_parser_seq_fifo(sc->base, i, sc->portcfg);
+ block = sc->portcfg[i].block;
+ port = sc->portcfg[i].port;
+ tmpd = device_add_child(dev, "xlpge", i);
+ device_set_ivars(tmpd,
+ &(nae_ivars->block_ivars[block].port_ivars[port]));
+ sprintf(desc, "XLP NAE Port %d,%d", block, port);
+ device_set_desc_copy(tmpd, desc);
}
+ nlm_setup_iface_fifo_cfg(sc->base, sc->max_ports, sc->portcfg);
+ nlm_setup_rx_base_config(sc->base, sc->max_ports, sc->portcfg);
+ nlm_setup_rx_buf_config(sc->base, sc->max_ports, sc->portcfg);
+ nlm_setup_freein_fifo_cfg(sc->base, sc->portcfg);
+ nlm_program_nae_parser_seq_fifo(sc->base, sc->max_ports, sc->portcfg);
+ nlm_xlpnae_print_frin_desc_carving(sc);
bus_generic_probe(dev);
bus_generic_attach(dev);
diff --git a/sys/mips/nlm/dev/net/xlpge.h b/sys/mips/nlm/dev/net/xlpge.h
index 883653d..ccf9d12 100644
--- a/sys/mips/nlm/dev/net/xlpge.h
+++ b/sys/mips/nlm/dev/net/xlpge.h
@@ -75,6 +75,9 @@ struct nlm_xlpnae_softc {
/* NetIOR configs */
u_int cmplx_type[8]; /* XXXJC: redundant? */
struct nae_port_config *portcfg;
+ u_int blockmask;
+ u_int portmask[XLP_NAE_NBLOCKS];
+ u_int ilmask;
u_int xauimask;
u_int sgmiimask;
u_int hw_parser_en;
diff --git a/sys/mips/nlm/hal/nae.h b/sys/mips/nlm/hal/nae.h
index 0738bc7..5ebddca 100644
--- a/sys/mips/nlm/hal/nae.h
+++ b/sys/mips/nlm/hal/nae.h
@@ -473,6 +473,9 @@
#define XLP_MAX_PORTS 18
#define XLP_STORM_MAX_PORTS 8
+#define MAX_FREE_FIFO_POOL_8XX 20
+#define MAX_FREE_FIFO_POOL_3XX 9
+
#if !defined(LOCORE) && !defined(__ASSEMBLY__)
#define nlm_read_nae_reg(b, r) nlm_read_reg_xkphys(b, r)
@@ -494,6 +497,7 @@ enum XLPNAE_TX_TYPE {
};
enum nblock_type {
+ UNKNOWN = 0, /* DONT MAKE IT NON-ZERO */
SGMIIC = 1,
XAUIC = 2,
ILC = 3
@@ -550,6 +554,12 @@ nae_num_context(uint64_t nae_pcibase)
/* per port config structure */
struct nae_port_config {
+ int node; /* node id (quickread) */
+ int block; /* network block id (quickread) */
+ int port; /* port id - among the 18 in XLP */
+ int type; /* port type - see xlp_gmac_port_types */
+ int mdio_bus;
+ int phy_addr;
int num_channels;
int num_free_descs;
int free_desc_sizes;
@@ -605,7 +615,7 @@ void nlm_setup_flow_crc_poly(uint64_t, uint32_t);
void nlm_setup_iface_fifo_cfg(uint64_t, int, struct nae_port_config *);
void nlm_setup_rx_base_config(uint64_t, int, struct nae_port_config *);
void nlm_setup_rx_buf_config(uint64_t, int, struct nae_port_config *);
-void nlm_setup_freein_fifo_cfg(uint64_t, int, struct nae_port_config *);
+void nlm_setup_freein_fifo_cfg(uint64_t, struct nae_port_config *);
int nlm_get_flow_mask(int);
void nlm_program_flow_cfg(uint64_t, int, uint32_t, uint32_t);
void xlp_ax_nae_lane_reset_txpll(uint64_t, int, int, int);
diff --git a/sys/mips/nlm/hal/nlm_hal.c b/sys/mips/nlm/hal/nlm_hal.c
index 00b79dd..fa4287e 100644
--- a/sys/mips/nlm/hal/nlm_hal.c
+++ b/sys/mips/nlm/hal/nlm_hal.c
@@ -75,7 +75,10 @@ nlm_get_device_frequency(uint64_t sysbase, int devtype)
dfsdiv = ((div_val >> (devtype << 2)) & 0xf) + 1;
spf = (pllctrl >> 3 & 0x7f) + 1;
spr = (pllctrl >> 1 & 0x03) + 1;
- extra_div = nlm_is_xlp8xx_ax() ? 1 : 2;
+ if (devtype == DFS_DEVICE_NAE && !nlm_is_xlp8xx_ax())
+ extra_div = 2;
+ else
+ extra_div = 1;
return ((400 * spf) / (3 * extra_div * spr * dfsdiv));
}
diff --git a/sys/mips/nlm/hal/sys.h b/sys/mips/nlm/hal/sys.h
index 2092d37..078e63d 100644
--- a/sys/mips/nlm/hal/sys.h
+++ b/sys/mips/nlm/hal/sys.h
@@ -95,9 +95,11 @@
#define SYS_UCO_S_ECC 0x38
#define SYS_UCO_M_ECC 0x39
#define SYS_UCO_ADDR 0x3a
+#define SYS_PLL_DFS_BYP_CTRL 0x3a /* Bx stepping */
#define SYS_UCO_INSTR 0x3b
#define SYS_MEM_BIST0 0x3c
#define SYS_MEM_BIST1 0x3d
+#define SYS_PLL_DFS_DIV_VALUE 0x3d /* Bx stepping */
#define SYS_MEM_BIST2 0x3e
#define SYS_MEM_BIST3 0x3f
#define SYS_MEM_BIST4 0x40
OpenPOWER on IntegriCloud