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>
This commit is contained in:
Jayachandran C. 2013-09-07 18:26:16 +00:00
parent cbd49bff46
commit 485a81908b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=255368
10 changed files with 229 additions and 308 deletions

View File

@ -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,88 +403,48 @@ 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;
/* XXXJC: check for boards with right CPLD, for now
* 4xx PCI cards don't have CPLD with daughter
* card info */
usecpld = !nlm_is_xlp4xx();
/* frequency at which network block runs */
naep->freq = 500;
for (node = 0; node < XLP_MAX_NODES; node++) {
if ((boardp->nodemask & (1 << node)) == 0)
continue;
nae_pcibase = nlm_get_nae_pcibase(node);
nodep = &boardp->nodes[node];
naep = &nodep->nae_ivars;
naep->node = node;
/* 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->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 */
if (block == 4) {
/* management block 4 on 8xx */
blockp->type = SGMIIC;
blockp->portmask = 0x3;
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;
}
}
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->port = port;
portp->block = block;
portp->node = node;
portp->type = blockp->type;
nlm_setup_port_defaults(portp);
}
}
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");
@ -498,30 +452,86 @@ nlm_setup_xlp_board(void)
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 = "???";
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;
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;
}
printf(" [%d %s]", block, s);
}
printf("\n");
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)
{
nlm_setup_xlp_board();
if (nlm_setup_xlp_board(0) != 0)
return (-1);
return (0);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}
}
for (i = 0; i < (maxports/2); i++) {
id = 0x12 + i; /* RX_IF_BASE_CONFIG0 */
id = 0x12 + (i * 2); /* 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;
int start = 0, maxbufpool;
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;
}
}
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;

View File

@ -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 */

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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));
}

View File

@ -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