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:
parent
cbd49bff46
commit
485a81908b
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user