summaryrefslogtreecommitdiffstats
path: root/sys/mips
diff options
context:
space:
mode:
authorjchandra <jchandra@FreeBSD.org>2012-03-27 14:05:12 +0000
committerjchandra <jchandra@FreeBSD.org>2012-03-27 14:05:12 +0000
commit2f1011004558a0b27cd95f1374185e37450b80e3 (patch)
treeae659c962d005114389e060c8a8057ddfcad9afd /sys/mips
parent961cc7f6b46bf3162f967f3b4ff8a1d0dce295b1 (diff)
downloadFreeBSD-src-2f1011004558a0b27cd95f1374185e37450b80e3.zip
FreeBSD-src-2f1011004558a0b27cd95f1374185e37450b80e3.tar.gz
xlpge : driver for XLP network accelerator
Features: - network driver for the four 10G interfaces and two management ports on XLP 8xx. - Support 4xx and 3xx variants of the processor. - Source code and firmware building for the 16 mips32r2 micro-code engines in the Network Accelerator. - Basic initialization code for Packet ordering Engine. Submitted by: Prabhath Raman (prabhath at netlogicmicro com) [refactored and fixed up for style by jchandra]
Diffstat (limited to 'sys/mips')
-rw-r--r--sys/mips/conf/std.XLP1
-rw-r--r--sys/mips/nlm/board.c390
-rw-r--r--sys/mips/nlm/board.h73
-rw-r--r--sys/mips/nlm/dev/net/mdio.c301
-rw-r--r--sys/mips/nlm/dev/net/nae.c1536
-rw-r--r--sys/mips/nlm/dev/net/sgmii.c216
-rw-r--r--sys/mips/nlm/dev/net/ucore/crt0_basic.S66
-rw-r--r--sys/mips/nlm/dev/net/ucore/ld.ucore.S162
-rw-r--r--sys/mips/nlm/dev/net/ucore/ucore.h356
-rw-r--r--sys/mips/nlm/dev/net/ucore/ucore_app.c58
-rw-r--r--sys/mips/nlm/dev/net/xaui.c251
-rw-r--r--sys/mips/nlm/dev/net/xlpge.c1574
-rw-r--r--sys/mips/nlm/dev/net/xlpge.h135
-rw-r--r--sys/mips/nlm/files.xlp17
-rw-r--r--sys/mips/nlm/hal/interlaken.h70
-rw-r--r--sys/mips/nlm/hal/iomap.h2
-rw-r--r--sys/mips/nlm/hal/mdio.h104
-rw-r--r--sys/mips/nlm/hal/nae.h646
-rw-r--r--sys/mips/nlm/hal/poe.h352
-rw-r--r--sys/mips/nlm/hal/sgmii.h217
-rw-r--r--sys/mips/nlm/hal/ucore_loader.h141
-rw-r--r--sys/mips/nlm/hal/xaui.h193
-rw-r--r--sys/mips/nlm/msgring.h7
23 files changed, 6861 insertions, 7 deletions
diff --git a/sys/mips/conf/std.XLP b/sys/mips/conf/std.XLP
index 2d867c2..188a2f9 100644
--- a/sys/mips/conf/std.XLP
+++ b/sys/mips/conf/std.XLP
@@ -71,6 +71,7 @@ device bpf
# Network
device miibus
device ether
+device xlpge
#device re
device msk
device em
diff --git a/sys/mips/nlm/board.c b/sys/mips/nlm/board.c
index c84ea33..b4b0439 100644
--- a/sys/mips/nlm/board.c
+++ b/sys/mips/nlm/board.c
@@ -44,16 +44,289 @@ __FBSDID("$FreeBSD$");
#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 = sizeof(nlm3xx_vfbid)/sizeof(struct vfbid_tbl);
+ p = nlm3xx_vfbid;
+ } else {
+ nentries = sizeof(nlm_vfbid)/sizeof(struct vfbid_tbl);
+ 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 *mdio, 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;
+ 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)
{
@@ -105,12 +378,17 @@ static int
nlm_setup_xlp_board(void)
{
struct xlp_board_info *boardp;
- int rv;
+ 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 node, block, port, rv, dbtype, usecpld;
uint8_t *b;
/* start with a clean slate */
boardp = &xlp_board_info;
- memset(boardp, 0, sizeof(*boardp));
+ memset(boardp, 0, sizeof(xlp_board_info));
boardp->nodemask = 0x1; /* only node 0 */
nlm_print_processor_info();
@@ -129,6 +407,114 @@ nlm_setup_xlp_board(void)
printf("Board Info: Error on EEPROM read (i2c@%d %#X).\n",
EEPROM_I2CBUS, EEPROM_I2CADDR);
+
+ /* XXXJC: check for boards with right CPLD, for now
+ * 4xx PCI cards don't have CPLD with daughter
+ * card info */
+ usecpld = !nlm_is_xlp4xx();
+
+ 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;
+
+ 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);
+ }
+ }
+ }
+
+ /* 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);
+ }
+ printf("\n");
+ }
return (0);
}
diff --git a/sys/mips/nlm/board.h b/sys/mips/nlm/board.h
index 3a2ae24..4ef4b37 100644
--- a/sys/mips/nlm/board.h
+++ b/sys/mips/nlm/board.h
@@ -32,9 +32,8 @@
#ifndef __NLM_BOARD_H__
#define __NLM_BOARD_H__
-#define XLP_NAE_NBLOCKS 5
-#define XLP_NAE_NPORTS 4
-#define XLP_I2C_MAXDEVICES 8
+#define XLP_NAE_NBLOCKS 5
+#define XLP_NAE_NPORTS 4
/*
* EVP board EEPROM info
@@ -44,13 +43,62 @@
#define EEPROM_SIZE 48
#define EEPROM_MACADDR_OFFSET 2
+/*
+ * EVP board CPLD chip select and daughter card info field
+ */
+#define XLP_EVB_CPLD_CHIPSELECT 2
+
+#define DCARD_ILAKEN 0x0
+#define DCARD_SGMII 0x1
+#define DCARD_XAUI 0x2
+#define DCARD_NOT_PRSNT 0x3
+
#if !defined(LOCORE) && !defined(__ASSEMBLY__)
+/*
+ * NAE configuration
+ */
struct xlp_port_ivars {
int port;
int block;
+ int node;
int type;
int phy_addr;
+ int mdio_bus;
+ int loopback_mode;
+ int num_channels;
+ int free_desc_sizes;
+ int num_free_descs;
+ int pseq_fifo_size;
+ int iface_fifo_size;
+ int rxbuf_size;
+ int rx_slots_reqd;
+ int tx_slots_reqd;
+ int vlan_pri_en;
+ int stg2_fifo_size;
+ int eh_fifo_size;
+ int frout_fifo_size;
+ int ms_fifo_size;
+ int pkt_fifo_size;
+ int pktlen_fifo_size;
+ int max_stg2_offset;
+ int max_eh_offset;
+ int max_frout_offset;
+ int max_ms_offset;
+ int max_pmem_offset;
+ int stg1_2_credit;
+ int stg2_eh_credit;
+ int stg2_frout_credit;
+ int stg2_ms_credit;
+ int hw_parser_en;
+ u_int ieee1588_inc_intg;
+ u_int ieee1588_inc_den;
+ u_int ieee1588_inc_num;
+ uint64_t ieee1588_userval;
+ uint64_t ieee1588_ptpoff;
+ uint64_t ieee1588_tmr1;
+ uint64_t ieee1588_tmr2;
+ uint64_t ieee1588_tmr3;
};
struct xlp_block_ivars {
@@ -62,7 +110,16 @@ struct xlp_block_ivars {
struct xlp_nae_ivars {
int node;
+ int nblocks;
u_int blockmask;
+ u_int xauimask;
+ u_int sgmiimask;
+ int freq;
+ u_int flow_crc_poly;
+ u_int hw_parser_en;
+ u_int prepad_en;
+ u_int prepad_size; /* size in 16 byte units */
+ u_int ieee_1588_en;
struct xlp_block_ivars block_ivars[XLP_NAE_NBLOCKS];
};
@@ -73,8 +130,16 @@ struct xlp_board_info {
} nodes[XLP_MAX_NODES];
};
+extern struct xlp_board_info xlp_board_info;
+
+/* Network configuration */
+int nlm_get_vfbid_mapping(int);
+int nlm_get_poe_distvec(int vec, uint32_t *distvec);
+void xlpge_get_macaddr(uint8_t *macaddr);
+
int nlm_board_info_setup(void);
+/* EEPROM & CPLD */
int nlm_board_eeprom_read(int node, int i2cbus, int addr, int offs,
uint8_t *buf,int sz);
uint64_t nlm_board_cpld_base(int node, int chipselect);
@@ -82,6 +147,6 @@ int nlm_board_cpld_majorversion(uint64_t cpldbase);
int nlm_board_cpld_minorversion(uint64_t cpldbase);
void nlm_board_cpld_reset(uint64_t cpldbase);
int nlm_board_cpld_dboard_type(uint64_t cpldbase, int slot);
-#endif
#endif
+#endif
diff --git a/sys/mips/nlm/dev/net/mdio.c b/sys/mips/nlm/dev/net/mdio.c
new file mode 100644
index 0000000..362312f
--- /dev/null
+++ b/sys/mips/nlm/dev/net/mdio.c
@@ -0,0 +1,301 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * 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 BROADCOM ``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 BROADCOM 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/types.h>
+#include <sys/systm.h>
+
+#include <mips/nlm/hal/mips-extns.h>
+#include <mips/nlm/hal/haldefs.h>
+#include <mips/nlm/hal/iomap.h>
+#include <mips/nlm/hal/sys.h>
+#include <mips/nlm/hal/nae.h>
+#include <mips/nlm/hal/mdio.h>
+
+/* Internal MDIO READ/WRITE Routines */
+int
+nlm_int_gmac_mdio_read(uint64_t nae_base, int bus, int block,
+ int intf_type, int phyaddr, int regidx)
+{
+ uint32_t mdio_ld_cmd;
+ uint32_t ctrlval;
+
+ ctrlval = INT_MDIO_CTRL_SMP |
+ (phyaddr << INT_MDIO_CTRL_PHYADDR_POS) |
+ (regidx << INT_MDIO_CTRL_DEVTYPE_POS) |
+ (2 << INT_MDIO_CTRL_OP_POS) |
+ (1 << INT_MDIO_CTRL_ST_POS) |
+ (7 << INT_MDIO_CTRL_XDIV_POS) |
+ (2 << INT_MDIO_CTRL_TA_POS) |
+ (2 << INT_MDIO_CTRL_MIIM_POS) |
+ (1 << INT_MDIO_CTRL_MCDIV_POS);
+
+ mdio_ld_cmd = nlm_read_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)));
+ if (mdio_ld_cmd & INT_MDIO_CTRL_CMD_LOAD) {
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus*4)),
+ (mdio_ld_cmd & ~INT_MDIO_CTRL_CMD_LOAD));
+ }
+
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
+ ctrlval);
+
+ /* Toggle Load Cmd Bit */
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
+ ctrlval | (1 << INT_MDIO_CTRL_LOAD_POS));
+
+ /* poll master busy bit until it is not busy */
+ while(nlm_read_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (INT_MDIO_RD_STAT + bus * 4))) &
+ INT_MDIO_STAT_MBSY) {
+ }
+
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
+ ctrlval);
+
+ /* Read the data back */
+ return nlm_read_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (INT_MDIO_RD_STAT + bus * 4)));
+}
+
+/* Internal MDIO WRITE Routines */
+int
+nlm_int_gmac_mdio_write(uint64_t nae_base, int bus, int block,
+ int intf_type, int phyaddr, int regidx, uint16_t val)
+{
+ uint32_t mdio_ld_cmd;
+ uint32_t ctrlval;
+
+ ctrlval = INT_MDIO_CTRL_SMP |
+ (phyaddr << INT_MDIO_CTRL_PHYADDR_POS) |
+ (regidx << INT_MDIO_CTRL_DEVTYPE_POS) |
+ (1 << INT_MDIO_CTRL_OP_POS) |
+ (1 << INT_MDIO_CTRL_ST_POS) |
+ (7 << INT_MDIO_CTRL_XDIV_POS) |
+ (2 << INT_MDIO_CTRL_TA_POS) |
+ (1 << INT_MDIO_CTRL_MIIM_POS) |
+ (1 << INT_MDIO_CTRL_MCDIV_POS);
+
+ mdio_ld_cmd = nlm_read_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)));
+ if (mdio_ld_cmd & INT_MDIO_CTRL_CMD_LOAD) {
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus*4)),
+ (mdio_ld_cmd & ~INT_MDIO_CTRL_CMD_LOAD));
+ }
+
+ /* load data into ctrl data reg */
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (INT_MDIO_CTRL_DATA + bus * 4)),
+ val);
+
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
+ ctrlval);
+
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
+ ctrlval | (1 << INT_MDIO_CTRL_LOAD_POS));
+
+ /* poll master busy bit until it is not busy */
+ while(nlm_read_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (INT_MDIO_RD_STAT + bus * 4))) &
+ INT_MDIO_STAT_MBSY) {
+ }
+
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
+ ctrlval);
+
+ return (0);
+}
+
+int
+nlm_int_gmac_mdio_reset(uint64_t nae_base, int bus, int block,
+ int intf_type)
+{
+ uint32_t val;
+
+ val = (7 << INT_MDIO_CTRL_XDIV_POS) |
+ (1 << INT_MDIO_CTRL_MCDIV_POS);
+
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
+ val | INT_MDIO_CTRL_RST);
+
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
+ val);
+
+ return (0);
+}
+
+/*
+ * nae_gmac_mdio_read - Read sgmii phy register
+ *
+ * Input parameters:
+ * bus - bus number, nae has two external gmac bus: 0 and 1
+ * phyaddr - PHY's address
+ * regidx - index of register to read
+ *
+ * Return value:
+ * value read (16 bits), or 0xffffffff if an error occurred.
+ */
+int
+nlm_gmac_mdio_read(uint64_t nae_base, int bus, int block,
+ int intf_type, int phyaddr, int regidx)
+{
+ uint32_t mdio_ld_cmd;
+ uint32_t val;
+
+ val = EXT_G_MDIO_CMD_SP |
+ (phyaddr << EXT_G_MDIO_PHYADDR_POS) |
+ (regidx << EXT_G_MDIO_REGADDR_POS) |
+ EXT_G_MDIO_DIV;
+
+ mdio_ld_cmd = nlm_read_nae_reg(nae_base, NAE_REG(block, intf_type,
+ (EXT_G0_MDIO_CTRL + bus * 4)));
+ if (mdio_ld_cmd & EXT_G_MDIO_CMD_LCD) {
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
+ (mdio_ld_cmd & ~EXT_G_MDIO_CMD_LCD));
+ while(nlm_read_nae_reg(nae_base,
+ NAE_REG(block, intf_type,
+ (EXT_G0_MDIO_RD_STAT + bus * 4))) &
+ EXT_G_MDIO_STAT_MBSY);
+ }
+
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
+ val);
+
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
+ val | (1<<18));
+
+ /* poll master busy bit until it is not busy */
+ while(nlm_read_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (EXT_G0_MDIO_RD_STAT + bus * 4))) &
+ EXT_G_MDIO_STAT_MBSY);
+
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
+ val);
+
+ /* Read the data back */
+ return nlm_read_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (EXT_G0_MDIO_RD_STAT + bus * 4)));
+}
+
+/*
+ * nae_gmac_mdio_write -Write sgmac mii PHY register.
+ *
+ * Input parameters:
+ * bus - bus number, nae has two external gmac bus: 0 and 1
+ * phyaddr - PHY to use
+ * regidx - register within the PHY
+ * val - data to write to register
+ *
+ * Return value:
+ * 0 - success
+ */
+int
+nlm_gmac_mdio_write(uint64_t nae_base, int bus, int block,
+ int intf_type, int phyaddr, int regidx, uint16_t val)
+{
+ uint32_t mdio_ld_cmd;
+ uint32_t ctrlval;
+
+ ctrlval = EXT_G_MDIO_CMD_SP |
+ (phyaddr << EXT_G_MDIO_PHYADDR_POS) |
+ (regidx << EXT_G_MDIO_REGADDR_POS) |
+ EXT_G_MDIO_DIV;
+
+ mdio_ld_cmd = nlm_read_nae_reg(nae_base, NAE_REG(block, intf_type,
+ (EXT_G0_MDIO_CTRL + bus * 4)));
+ if (mdio_ld_cmd & EXT_G_MDIO_CMD_LCD) {
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
+ (mdio_ld_cmd & ~EXT_G_MDIO_CMD_LCD));
+ while(nlm_read_nae_reg(nae_base,
+ NAE_REG(block, intf_type,
+ (EXT_G0_MDIO_RD_STAT + bus * 4))) &
+ EXT_G_MDIO_STAT_MBSY);
+ }
+
+ /* load data into ctrl data reg */
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL_DATA+bus*4)),
+ val);
+
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
+ ctrlval);
+
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
+ ctrlval | EXT_G_MDIO_CMD_LCD);
+
+ /* poll master busy bit until it is not busy */
+ while(nlm_read_nae_reg(nae_base,
+ NAE_REG(block, intf_type,
+ (EXT_G0_MDIO_RD_STAT + bus * 4))) & EXT_G_MDIO_STAT_MBSY);
+
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
+ ctrlval);
+
+ return (0);
+}
+
+/*
+ * nae_gmac_mdio_reset -Reset sgmii mdio module.
+ *
+ * Input parameters:
+ * bus - bus number, nae has two external gmac bus: 0 and 1
+ *
+ * Return value:
+ * 0 - success
+ */
+int
+nlm_gmac_mdio_reset(uint64_t nae_base, int bus, int block,
+ int intf_type)
+{
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
+ EXT_G_MDIO_MMRST | EXT_G_MDIO_DIV);
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
+ EXT_G_MDIO_DIV);
+ return (0);
+}
diff --git a/sys/mips/nlm/dev/net/nae.c b/sys/mips/nlm/dev/net/nae.c
new file mode 100644
index 0000000..8b02b03
--- /dev/null
+++ b/sys/mips/nlm/dev/net/nae.c
@@ -0,0 +1,1536 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * 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 BROADCOM ``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 BROADCOM 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/types.h>
+#include <sys/systm.h>
+
+#include <mips/nlm/hal/mips-extns.h>
+#include <mips/nlm/hal/haldefs.h>
+#include <mips/nlm/hal/iomap.h>
+#include <mips/nlm/hal/sys.h>
+#include <mips/nlm/hal/nae.h>
+#include <mips/nlm/hal/mdio.h>
+#include <mips/nlm/hal/sgmii.h>
+#include <mips/nlm/hal/xaui.h>
+
+#include <mips/nlm/board.h>
+#include <mips/nlm/xlp.h>
+
+void
+nlm_nae_flush_free_fifo(uint64_t nae_base, int nblocks)
+{
+ uint32_t data, fifo_mask;
+
+ fifo_mask = (1 << (4 * nblocks)) - 1;
+
+ nlm_write_nae_reg(nae_base, NAE_RX_FREE_FIFO_POP, fifo_mask);
+ do {
+ data = nlm_read_nae_reg(nae_base, NAE_RX_FREE_FIFO_POP);
+ } while (data != fifo_mask);
+
+ nlm_write_nae_reg(nae_base, NAE_RX_FREE_FIFO_POP, 0);
+}
+
+void
+nlm_program_nae_parser_seq_fifo(uint64_t nae_base, int nblock,
+ 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;
+
+ val = (((size & 0x1fff) << 17) |
+ ((start & 0xfff) << 5) |
+ (((i * 4) + j) & 0x1f));
+ nlm_write_nae_reg(nae_base, NAE_PARSER_SEQ_FIFO_CFG, val);
+ start += size;
+ }
+}
+
+void
+nlm_setup_rx_cal_cfg(uint64_t nae_base, int total_num_ports,
+ struct nae_port_config *cfg)
+{
+ int rx_slots = 0, port;
+ int cal_len, cal = 0, last_free = 0;
+ uint32_t val;
+
+ for (port = 0; port < total_num_ports; port++) {
+ if (cfg[port].rx_slots_reqd)
+ rx_slots += cfg[port].rx_slots_reqd;
+ if (rx_slots > MAX_CAL_SLOTS) {
+ rx_slots = MAX_CAL_SLOTS;
+ break;
+ }
+ }
+
+ cal_len = rx_slots - 1;
+
+ do {
+ if (cal >= MAX_CAL_SLOTS)
+ break;
+ last_free = cal;
+ for (port = 0; port < total_num_ports; port++) {
+ if (cfg[port].rx_slots_reqd > 0) {
+ val = (cal_len << 16) | (port << 8) | cal;
+ nlm_write_nae_reg(nae_base,
+ NAE_RX_IF_SLOT_CAL, val);
+ cal++;
+ cfg[port].rx_slots_reqd--;
+ }
+ }
+ if (last_free == cal)
+ break;
+ } while (1);
+}
+
+void
+nlm_setup_tx_cal_cfg(uint64_t nae_base, int total_num_ports,
+ struct nae_port_config *cfg)
+{
+ int tx_slots = 0, port;
+ int cal = 0, last_free = 0;
+ uint32_t val;
+
+ for (port = 0; port < total_num_ports; port++) {
+ if (cfg[port].tx_slots_reqd)
+ tx_slots += cfg[port].tx_slots_reqd;
+ if (tx_slots > MAX_CAL_SLOTS) {
+ tx_slots = MAX_CAL_SLOTS;
+ break;
+ }
+ }
+
+ nlm_write_nae_reg(nae_base, NAE_EGR_NIOR_CAL_LEN_REG, tx_slots - 1);
+ do {
+ if (cal >= MAX_CAL_SLOTS)
+ break;
+ last_free = cal;
+ for (port = 0; port < total_num_ports; port++) {
+ if (cfg[port].tx_slots_reqd > 0) {
+ val = (port << 7) | (cal << 1) | 1;
+ nlm_write_nae_reg(nae_base,
+ NAE_EGR_NIOR_CRDT_CAL_PROG, val);
+ cal++;
+ cfg[port].tx_slots_reqd--;
+ }
+ }
+ if (last_free == cal)
+ break;
+ } while (1);
+}
+
+void
+nlm_deflate_frin_fifo_carving(uint64_t nae_base, int total_num_ports)
+{
+ const int minimum_size = 8;
+ uint32_t value;
+ int intf, start;
+
+ for (intf = 0; intf < total_num_ports; intf++) {
+ start = minimum_size * intf;
+ value = (minimum_size << 20) | (start << 8) | (intf);
+ nlm_write_nae_reg(nae_base, NAE_FREE_IN_FIFO_CFG, value);
+ }
+}
+
+void
+nlm_reset_nae(int node)
+{
+ uint64_t sysbase;
+ uint64_t nae_base;
+ uint64_t nae_pcibase;
+ uint32_t rx_config;
+ uint32_t bar0;
+ int reset_bit;
+
+ sysbase = nlm_get_sys_regbase(node);
+ nae_base = nlm_get_nae_regbase(node);
+ nae_pcibase = nlm_get_nae_pcibase(node);
+
+ bar0 = nlm_read_pci_reg(nae_pcibase, XLP_PCI_CFGREG4);
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ if (nlm_is_xlp8xx_ax()) {
+ uchar_t val;
+ /* membar fixup */
+ val = (bar0 >> 24) & 0xff;
+ bar0 = (val << 24) | (val << 16) | (val << 8) | val;
+ }
+#endif
+
+ if (nlm_is_xlp3xx())
+ reset_bit = 6;
+ else
+ reset_bit = 9;
+
+ /* Reset NAE */
+ nlm_write_sys_reg(sysbase, SYS_RESET, (1 << reset_bit));
+
+ /* XXXJC - 1s delay here may be too high */
+ DELAY(1000000);
+ nlm_write_sys_reg(sysbase, SYS_RESET, (0 << reset_bit));
+ DELAY(1000000);
+
+ rx_config = nlm_read_nae_reg(nae_base, NAE_RX_CONFIG);
+ nlm_write_pci_reg(nae_pcibase, XLP_PCI_CFGREG4, bar0);
+}
+
+void
+nlm_setup_poe_class_config(uint64_t nae_base, int max_poe_classes,
+ int num_contexts, int *poe_cl_tbl)
+{
+ uint32_t val;
+ int i, max_poe_class_ctxt_tbl_sz;
+
+ max_poe_class_ctxt_tbl_sz = num_contexts/max_poe_classes;
+ for (i = 0; i < max_poe_class_ctxt_tbl_sz; i++) {
+ val = (poe_cl_tbl[(i/max_poe_classes) & 0x7] << 8) | i;
+ nlm_write_nae_reg(nae_base, NAE_POE_CLASS_SETUP_CFG, val);
+ }
+}
+
+void
+nlm_setup_vfbid_mapping(uint64_t nae_base)
+{
+ uint32_t val;
+ int dest_vc, vfbid;
+
+ /* 127 is max vfbid */
+ for (vfbid = 127; vfbid >= 0; vfbid--) {
+ dest_vc = nlm_get_vfbid_mapping(vfbid);
+ if (dest_vc < 0)
+ continue;
+ val = (dest_vc << 16) | (vfbid << 4) | 1;
+ nlm_write_nae_reg(nae_base, NAE_VFBID_DESTMAP_CMD, val);
+ }
+}
+
+void
+nlm_setup_flow_crc_poly(uint64_t nae_base, uint32_t poly)
+{
+ nlm_write_nae_reg(nae_base, NAE_FLOW_CRC16_POLY_CFG, poly);
+}
+
+void
+nlm_setup_iface_fifo_cfg(uint64_t nae_base, int nblock,
+ struct nae_port_config *cfg)
+{
+ uint32_t reg;
+ int fifo_xoff_thresh = 12;
+ int i, size, j;
+ 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;
+ reg = ((fifo_xoff_thresh << 25) |
+ ((size & 0x1ff) << 16) |
+ ((cur_iface_start & 0xff) << 8) |
+ (((i * 4) + j) & 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,
+ struct nae_port_config *cfg)
+{
+ uint32_t val, nc;
+ int base = 0;
+ int i, j;
+ 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 (j = 0; j < (PORTS_PER_CMPLX/2); j++) {
+ val = (base & 0x3ff);
+ nc = cfg[(i*4)+(2*j)].num_channels;
+ base += nc;
+
+ val |= ((base & 0x3ff) << 16);
+ nc = cfg[(i*4)+(2*j + 1)].num_channels;
+ base += nc;
+
+ nlm_write_nae_reg(nae_base, NAE_REG(7, 0, (id+j)), val);
+ }
+}
+
+void
+nlm_setup_rx_buf_config(uint64_t nae_base, int nblock,
+ struct nae_port_config *cfg)
+{
+ uint32_t val;
+ int i, sz, j, 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++) {
+ /* 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;
+ val = 0x80000000 | ((base << 2) & 0x3fff); /* base */
+ val |= (((sz << 2) & 0x3fff) << 16); /* size */
+
+ nlm_write_nae_reg(nae_base, NAE_RXBUF_BASE_DPTH, val);
+ nlm_write_nae_reg(nae_base, NAE_RXBUF_BASE_DPTH,
+ (0x7fffffff & val));
+ base += sz;
+ }
+ context += nc;
+ }
+}
+
+void
+nlm_setup_freein_fifo_cfg(uint64_t nae_base, int nblock,
+ struct nae_port_config *cfg)
+{
+ int size, i, cp = 0;
+ 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;
+ }
+ }
+
+ 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;
+ }
+ /* Each entry represents 2 descs; hence division by 2 */
+ if (size == 0)
+ size = 8;
+
+ reg = ((size & 0x3ff ) << 20) | /* fcSize */
+ ((start & 0x1ff) << 8) | /* fcStart */
+ (((cp * 4) + i) & 0x1f);
+
+ nlm_write_nae_reg(nae_base, NAE_FREE_IN_FIFO_CFG, reg);
+ start += size;
+ }
+}
+
+/* XXX function name */
+int
+nlm_get_flow_mask(int num_ports)
+{
+ const int max_bits = 5; /* upto 32 ports */
+ int i;
+
+ /* Compute the number of bits to needed to
+ * represent all the ports */
+ for (i = 0; i < max_bits; i++) {
+ if (num_ports <= (2 << i))
+ return (i + 1);
+ }
+ return (max_bits);
+}
+
+void
+nlm_program_flow_cfg(uint64_t nae_base, int port,
+ uint32_t cur_flow_base, uint32_t flow_mask)
+{
+ uint32_t val;
+
+ val = (cur_flow_base << 16) | port;
+ val |= ((flow_mask & 0x1f) << 8);
+ nlm_write_nae_reg(nae_base, NAE_FLOW_BASEMASK_CFG, val);
+}
+
+void
+xlp_ax_nae_lane_reset_txpll(uint64_t nae_base, int block, int lane_ctrl,
+ int mode)
+{
+ uint32_t val = 0, saved_data;
+ int rext_sel = 0;
+
+ val = PHY_LANE_CTRL_RST |
+ PHY_LANE_CTRL_PWRDOWN |
+ (mode << PHY_LANE_CTRL_PHYMODE_POS);
+
+ /* set comma bypass for XAUI */
+ if (mode != PHYMODE_SGMII)
+ val |= PHY_LANE_CTRL_BPC_XAUI;
+
+ nlm_write_nae_reg(nae_base, NAE_REG(block, PHY, lane_ctrl), val);
+
+ if (lane_ctrl != 4) {
+ rext_sel = (1 << 23);
+ if (mode != PHYMODE_SGMII)
+ rext_sel |= PHY_LANE_CTRL_BPC_XAUI;
+
+ val = nlm_read_nae_reg(nae_base,
+ NAE_REG(block, PHY, lane_ctrl));
+ val &= ~PHY_LANE_CTRL_RST;
+ val |= rext_sel;
+
+ /* Resetting PMA for non-zero lanes */
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, PHY, lane_ctrl), val);
+
+ DELAY(20000); /* 20 ms delay, XXXJC: needed? */
+
+ val |= PHY_LANE_CTRL_RST;
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, PHY, lane_ctrl), val);
+
+ val = 0;
+ }
+
+ /* Come out of reset for TXPLL */
+ saved_data = nlm_read_nae_reg(nae_base,
+ NAE_REG(block, PHY, lane_ctrl)) & 0xFFC00000;
+
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, PHY, lane_ctrl),
+ (0x66 << PHY_LANE_CTRL_ADDR_POS)
+ | PHY_LANE_CTRL_CMD_READ
+ | PHY_LANE_CTRL_CMD_START
+ | PHY_LANE_CTRL_RST
+ | rext_sel
+ | val );
+
+ while (((val = nlm_read_nae_reg(nae_base,
+ NAE_REG(block, PHY, lane_ctrl))) &
+ PHY_LANE_CTRL_CMD_PENDING));
+
+ val &= 0xFF;
+ /* set bit[4] to 0 */
+ val &= ~(1 << 4);
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, PHY, lane_ctrl),
+ (0x66 << PHY_LANE_CTRL_ADDR_POS)
+ | PHY_LANE_CTRL_CMD_WRITE
+ | PHY_LANE_CTRL_CMD_START
+ | (0x0 << 19) /* (0x4 << 19) */
+ | rext_sel
+ | saved_data
+ | val );
+
+ /* re-do */
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, PHY, lane_ctrl),
+ (0x66 << PHY_LANE_CTRL_ADDR_POS)
+ | PHY_LANE_CTRL_CMD_WRITE
+ | PHY_LANE_CTRL_CMD_START
+ | (0x0 << 19) /* (0x4 << 19) */
+ | rext_sel
+ | saved_data
+ | val );
+
+ while (!((val = nlm_read_nae_reg(nae_base,
+ NAE_REG(block, PHY, (lane_ctrl - PHY_LANE_0_CTRL)))) &
+ PHY_LANE_STAT_PCR));
+
+ /* Clear the Power Down bit */
+ val = nlm_read_nae_reg(nae_base, NAE_REG(block, PHY, lane_ctrl));
+ val &= ~((1 << 29) | (0x7ffff));
+ nlm_write_nae_reg(nae_base, NAE_REG(block, PHY, lane_ctrl),
+ (rext_sel | val));
+}
+
+void
+xlp_nae_lane_reset_txpll(uint64_t nae_base, int block, int lane_ctrl,
+ int mode)
+{
+ uint32_t val = 0;
+ int rext_sel = 0;
+
+ if (lane_ctrl != 4)
+ rext_sel = (1 << 23);
+
+ val = nlm_read_nae_reg(nae_base,
+ NAE_REG(block, PHY, lane_ctrl));
+
+ /* set comma bypass for XAUI */
+ if (mode != PHYMODE_SGMII)
+ val |= PHY_LANE_CTRL_BPC_XAUI;
+ val |= 0x100000;
+ val |= (mode << PHY_LANE_CTRL_PHYMODE_POS);
+ val &= ~(0x20000);
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, PHY, lane_ctrl), val);
+
+ val = nlm_read_nae_reg(nae_base,
+ NAE_REG(block, PHY, lane_ctrl));
+ val |= 0x40000000;
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, PHY, lane_ctrl), val);
+
+ /* clear the power down bit */
+ val = nlm_read_nae_reg(nae_base,
+ NAE_REG(block, PHY, lane_ctrl));
+ val &= ~( (1 << 29) | (0x7ffff));
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, PHY, lane_ctrl), rext_sel | val);
+}
+
+void
+xlp_nae_config_lane_gmac(uint64_t nae_base, int cplx_mask)
+{
+ int block, lane_ctrl;
+ int cplx_lane_enable;
+ int lane_enable = 0;
+
+ cplx_lane_enable = LM_SGMII |
+ (LM_SGMII << 4) |
+ (LM_SGMII << 8) |
+ (LM_SGMII << 12);
+
+ /* Lane mode progamming */
+ block = 7;
+
+ /* Complexes 0, 1 */
+ if (cplx_mask & 0x1)
+ lane_enable |= cplx_lane_enable;
+
+ if (cplx_mask & 0x2)
+ lane_enable |= (cplx_lane_enable << 16);
+
+ if (lane_enable) {
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_0_1),
+ lane_enable);
+ lane_enable = 0;
+ }
+ /* Complexes 2 3 */
+ if (cplx_mask & 0x4)
+ lane_enable |= cplx_lane_enable;
+
+ if (cplx_mask & 0x8)
+ lane_enable |= (cplx_lane_enable << 16);
+
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_2_3),
+ lane_enable);
+
+ /* complex 4 */
+ /* XXXJC : fix duplicate code */
+ if (cplx_mask & 0x10) {
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_4),
+ ((LM_SGMII << 4) | LM_SGMII));
+ for (lane_ctrl = PHY_LANE_0_CTRL;
+ lane_ctrl <= PHY_LANE_1_CTRL; lane_ctrl++) {
+ if (!nlm_is_xlp8xx_ax())
+ xlp_nae_lane_reset_txpll(nae_base,
+ 4, lane_ctrl, PHYMODE_SGMII);
+ else
+ xlp_ax_nae_lane_reset_txpll(nae_base, 4,
+ lane_ctrl, PHYMODE_SGMII);
+ }
+ }
+
+ for (block = 0; block < 4; block++) {
+ if ((cplx_mask & (1 << block)) == 0)
+ continue;
+
+ for (lane_ctrl = PHY_LANE_0_CTRL;
+ lane_ctrl <= PHY_LANE_3_CTRL; lane_ctrl++) {
+ if (!nlm_is_xlp8xx_ax())
+ xlp_nae_lane_reset_txpll(nae_base,
+ block, lane_ctrl, PHYMODE_SGMII);
+ else
+ xlp_ax_nae_lane_reset_txpll(nae_base, block,
+ lane_ctrl, PHYMODE_SGMII);
+ }
+ }
+}
+
+void
+config_egress_fifo_carvings(uint64_t nae_base, int hwport, int start_ctxt,
+ int num_ctxts, int max_ctxts, struct nae_port_config *cfg)
+{
+ static uint32_t cur_start[6] = {0, 0, 0, 0, 0, 0};
+ uint32_t data = 0;
+ uint32_t start = 0, size, offset;
+ int i, limit;
+
+ limit = start_ctxt + num_ctxts;
+ /* Stage 2 FIFO */
+ start = cur_start[0];
+ for (i = start_ctxt; i < limit; i++) {
+ size = cfg[hwport].stg2_fifo_size / max_ctxts;
+ if (size)
+ offset = size - 1;
+ else
+ offset = size;
+ if (offset > cfg[hwport].max_stg2_offset)
+ offset = cfg[hwport].max_stg2_offset;
+ data = offset << 23 |
+ start << 11 |
+ i << 1 |
+ 1;
+ nlm_write_nae_reg(nae_base, NAE_STG2_PMEM_PROG, data);
+ start += size;
+ }
+ cur_start[0] = start;
+
+ /* EH FIFO */
+ start = cur_start[1];
+ for (i = start_ctxt; i < limit; i++) {
+ size = cfg[hwport].eh_fifo_size / max_ctxts;
+ if (size)
+ offset = size - 1;
+ else
+ offset = size ;
+ if (offset > cfg[hwport].max_eh_offset)
+ offset = cfg[hwport].max_eh_offset;
+ data = offset << 23 |
+ start << 11 |
+ i << 1 |
+ 1;
+ nlm_write_nae_reg(nae_base, NAE_EH_PMEM_PROG, data);
+ start += size;
+ }
+ cur_start[1] = start;
+
+ /* FROUT FIFO */
+ start = cur_start[2];
+ for (i = start_ctxt; i < limit; i++) {
+ size = cfg[hwport].frout_fifo_size / max_ctxts;
+ if (size)
+ offset = size - 1;
+ else
+ offset = size ;
+ if (offset > cfg[hwport].max_frout_offset)
+ offset = cfg[hwport].max_frout_offset;
+ data = offset << 23 |
+ start << 11 |
+ i << 1 |
+ 1;
+ nlm_write_nae_reg(nae_base, NAE_FREE_PMEM_PROG, data);
+ start += size;
+ }
+ cur_start[2] = start;
+
+ /* MS FIFO */
+ start = cur_start[3];
+ for (i = start_ctxt; i < limit; i++) {
+ size = cfg[hwport].ms_fifo_size / max_ctxts;
+ if (size)
+ offset = size - 1;
+ else
+ offset = size ;
+ if (offset > cfg[hwport].max_ms_offset)
+ offset = cfg[hwport].max_ms_offset;
+ data = offset << 22 | /* FIXME in PRM */
+ start << 11 |
+ i << 1 |
+ 1;
+ nlm_write_nae_reg(nae_base, NAE_STR_PMEM_CMD, data);
+ start += size;
+ }
+ cur_start[3] = start;
+
+ /* PKT FIFO */
+ start = cur_start[4];
+ for (i = start_ctxt; i < limit; i++) {
+ size = cfg[hwport].pkt_fifo_size / max_ctxts;
+ if (size)
+ offset = size - 1;
+ else
+ offset = size ;
+ if (offset > cfg[hwport].max_pmem_offset)
+ offset = cfg[hwport].max_pmem_offset;
+ nlm_write_nae_reg(nae_base, NAE_TX_PKT_PMEM_CMD1, offset);
+
+ data = start << 11 |
+ i << 1 |
+ 1;
+ nlm_write_nae_reg(nae_base, NAE_TX_PKT_PMEM_CMD0, data);
+ start += size;
+ }
+ cur_start[4] = start;
+
+ /* PKT LEN FIFO */
+ start = cur_start[5];
+ for (i = start_ctxt; i < limit; i++) {
+ size = cfg[hwport].pktlen_fifo_size / max_ctxts;
+ if (size)
+ offset = size - 1;
+ else
+ offset = size ;
+ data = offset << 22 |
+ start << 11 |
+ i << 1 |
+ 1;
+ nlm_write_nae_reg(nae_base, NAE_TX_PKTLEN_PMEM_CMD, data);
+ start += size;
+ }
+ cur_start[5] = start;
+}
+
+void
+config_egress_fifo_credits(uint64_t nae_base, int hwport, int start_ctxt,
+ int num_ctxts, int max_ctxts, struct nae_port_config *cfg)
+{
+ uint32_t data, credit, max_credit;
+ int i, limit;
+
+ limit = start_ctxt + num_ctxts;
+ /* Stage1 -> Stage2 */
+ max_credit = cfg[hwport].max_stg2_offset + 1;
+ for (i = start_ctxt; i < limit; i++) {
+ credit = cfg[hwport].stg1_2_credit / max_ctxts;
+ if (credit > max_credit)
+ credit = max_credit;
+ data = credit << 16 |
+ i << 4 |
+ 1;
+ nlm_write_nae_reg(nae_base, NAE_STG1_STG2CRDT_CMD, data);
+ }
+
+ /* Stage2 -> EH */
+ max_credit = cfg[hwport].max_eh_offset + 1;
+ for (i = start_ctxt; i < limit; i++) {
+ credit = cfg[hwport].stg2_eh_credit / max_ctxts;
+ if (credit > max_credit)
+ credit = max_credit;
+ data = credit << 16 |
+ i << 4 |
+ 1;
+ nlm_write_nae_reg(nae_base, NAE_STG2_EHCRDT_CMD, data);
+ }
+
+ /* Stage2 -> Frout */
+ max_credit = cfg[hwport].max_frout_offset + 1;
+ for (i = start_ctxt; i < limit; i++) {
+ credit = cfg[hwport].stg2_frout_credit / max_ctxts;
+ if (credit > max_credit)
+ credit = max_credit;
+ data = credit << 16 |
+ i << 4 |
+ 1;
+ nlm_write_nae_reg(nae_base, NAE_EH_FREECRDT_CMD, data);
+ }
+
+ /* Stage2 -> MS */
+ max_credit = cfg[hwport].max_ms_offset + 1;
+ for (i = start_ctxt; i < limit; i++) {
+ credit = cfg[hwport].stg2_ms_credit / max_ctxts;
+ if (credit > max_credit)
+ credit = max_credit;
+ data = credit << 16 |
+ i << 4 |
+ 1;
+ nlm_write_nae_reg(nae_base, NAE_STG2_STRCRDT_CMD, data);
+ }
+}
+
+void
+nlm_config_freein_fifo_uniq_cfg(uint64_t nae_base, int port,
+ int nblock_free_desc)
+{
+ uint32_t val;
+ int size_in_clines;
+
+ size_in_clines = (nblock_free_desc / NAE_CACHELINE_SIZE);
+ val = (size_in_clines << 8) | (port & 0x1f);
+ nlm_write_nae_reg(nae_base, NAE_FREEIN_FIFO_UNIQ_SZ_CFG, val);
+}
+
+/* XXXJC: redundant, see ucore_spray_config() */
+void
+nlm_config_ucore_iface_mask_cfg(uint64_t nae_base, int port,
+ int nblock_ucore_mask)
+{
+ uint32_t val;
+
+ val = ( 0x1U << 31) | ((nblock_ucore_mask & 0xffff) << 8) |
+ (port & 0x1f);
+ nlm_write_nae_reg(nae_base, NAE_UCORE_IFACEMASK_CFG, val);
+}
+
+int
+nlm_nae_init_netior(uint64_t nae_base, int nblocks)
+{
+ uint32_t ctrl1, ctrl2, ctrl3;
+
+ if (nblocks == 5)
+ ctrl3 = 0x07 << 18;
+ else
+ ctrl3 = 0;
+
+ switch (nblocks) {
+ case 2:
+ ctrl1 = 0xff;
+ ctrl2 = 0x0707;
+ break;
+ case 4:
+ case 5:
+ ctrl1 = 0xfffff;
+ ctrl2 = 0x07070707;
+ break;
+ default:
+ printf("WARNING: unsupported blocks %d\n", nblocks);
+ return (-1);
+ }
+
+ nlm_write_nae_reg(nae_base, NAE_LANE_CFG_SOFTRESET, 0);
+ nlm_write_nae_reg(nae_base, NAE_NETIOR_MISC_CTRL3, ctrl3);
+ nlm_write_nae_reg(nae_base, NAE_NETIOR_MISC_CTRL2, ctrl2);
+ nlm_write_nae_reg(nae_base, NAE_NETIOR_MISC_CTRL1, ctrl1);
+ nlm_write_nae_reg(nae_base, NAE_NETIOR_MISC_CTRL1, 0x0);
+ return (0);
+}
+
+void
+nlm_nae_init_ingress(uint64_t nae_base, uint32_t desc_size)
+{
+ uint32_t rx_cfg;
+ uint32_t parser_threshold = 384;
+
+ rx_cfg = nlm_read_nae_reg(nae_base, NAE_RX_CONFIG);
+ rx_cfg &= ~(0x3 << 1); /* reset max message size */
+ rx_cfg &= ~(0xff << 4); /* clear freein desc cluster size */
+ rx_cfg &= ~(0x3f << 24); /* reset rx status mask */ /*XXX: why not 7f */
+
+ rx_cfg |= 1; /* rx enable */
+ rx_cfg |= (0x0 << 1); /* max message size */
+ rx_cfg |= (0x43 & 0x7f) << 24; /* rx status mask */
+ rx_cfg |= ((desc_size / 64) & 0xff) << 4; /* freein desc cluster size */
+ nlm_write_nae_reg(nae_base, NAE_RX_CONFIG, rx_cfg);
+ nlm_write_nae_reg(nae_base, NAE_PARSER_CONFIG,
+ (parser_threshold & 0x3ff) |
+ (((parser_threshold / desc_size) + 1) & 0xff) << 12 |
+ (((parser_threshold / 64) % desc_size) & 0xff) << 20);
+
+ /*nlm_write_nae_reg(nae_base, NAE_RX_FREE_FIFO_THRESH, 33);*/
+}
+
+void
+nlm_nae_init_egress(uint64_t nae_base)
+{
+ uint32_t tx_cfg;
+
+ tx_cfg = nlm_read_nae_reg(nae_base, NAE_TX_CONFIG);
+ if (!nlm_is_xlp8xx_ax()) {
+ nlm_write_nae_reg(nae_base, NAE_TX_CONFIG,
+ tx_cfg |
+ 0x1 | /* tx enable */
+ 0x2 | /* tx ace */
+ 0x4 | /* tx compatible */
+ (1 << 3));
+ } else {
+ nlm_write_nae_reg(nae_base, NAE_TX_CONFIG,
+ tx_cfg |
+ 0x1 | /* tx enable */
+ 0x2); /* tx ace */
+ }
+}
+
+uint32_t
+ucore_spray_config(uint32_t interface, uint32_t ucore_mask, int cmd)
+{
+ return ((cmd & 0x1) << 31) | ((ucore_mask & 0xffff) << 8) |
+ (interface & 0x1f);
+}
+
+void
+nlm_nae_init_ucore(uint64_t nae_base, int if_num, u_int ucore_mask)
+{
+ uint32_t ucfg;
+
+ ucfg = ucore_spray_config(if_num, ucore_mask, 1); /* 1 : write */
+ nlm_write_nae_reg(nae_base, NAE_UCORE_IFACEMASK_CFG, ucfg);
+}
+
+uint64_t
+nae_tx_desc(u_int type, u_int rdex, u_int fbid, u_int len, uint64_t addr)
+{
+ return ((uint64_t)type << 62) |
+ ((uint64_t)rdex << 61) |
+ ((uint64_t)fbid << 54) |
+ ((uint64_t)len << 40) | addr;
+}
+
+void
+nlm_setup_l2type(uint64_t nae_base, int hwport, uint32_t l2extlen,
+ uint32_t l2extoff, uint32_t extra_hdrsize, uint32_t proto_offset,
+ uint32_t fixed_hdroff, uint32_t l2proto)
+{
+ uint32_t val;
+
+ val = ((l2extlen & 0x3f) << 26) |
+ ((l2extoff & 0x3f) << 20) |
+ ((extra_hdrsize & 0x3f) << 14) |
+ ((proto_offset & 0x3f) << 8) |
+ ((fixed_hdroff & 0x3f) << 2) |
+ (l2proto & 0x3);
+ nlm_write_nae_reg(nae_base, (NAE_L2_TYPE_PORT0 + hwport), val);
+}
+
+void
+nlm_setup_l3ctable_mask(uint64_t nae_base, int hwport, uint32_t ptmask,
+ uint32_t l3portmask)
+{
+ uint32_t val;
+
+ val = ((ptmask & 0x1) << 6) |
+ ((l3portmask & 0x1) << 5) |
+ (hwport & 0x1f);
+ nlm_write_nae_reg(nae_base, NAE_L3_CTABLE_MASK0, val);
+}
+
+void
+nlm_setup_l3ctable_even(uint64_t nae_base, int entry, uint32_t l3hdroff,
+ uint32_t ipcsum_en, uint32_t l4protooff,
+ uint32_t l2proto, uint32_t eth_type)
+{
+ uint32_t val;
+
+ val = ((l3hdroff & 0x3f) << 26) |
+ ((l4protooff & 0x3f) << 20) |
+ ((ipcsum_en & 0x1) << 18) |
+ ((l2proto & 0x3) << 16) |
+ (eth_type & 0xffff);
+ nlm_write_nae_reg(nae_base, (NAE_L3CTABLE0 + (entry * 2)), val);
+}
+
+void
+nlm_setup_l3ctable_odd(uint64_t nae_base, int entry, uint32_t l3off0,
+ uint32_t l3len0, uint32_t l3off1, uint32_t l3len1,
+ uint32_t l3off2, uint32_t l3len2)
+{
+ uint32_t val;
+
+ val = ((l3off0 & 0x3f) << 26) |
+ ((l3len0 & 0x1f) << 21) |
+ ((l3off1 & 0x3f) << 15) |
+ ((l3len1 & 0x1f) << 10) |
+ ((l3off2 & 0x3f) << 4) |
+ (l3len2 & 0xf);
+ nlm_write_nae_reg(nae_base, (NAE_L3CTABLE0 + ((entry * 2) + 1)), val);
+}
+
+void
+nlm_setup_l4ctable_even(uint64_t nae_base, int entry, uint32_t im,
+ uint32_t l3cm, uint32_t l4pm, uint32_t port,
+ uint32_t l3camaddr, uint32_t l4proto)
+{
+ uint32_t val;
+
+ val = ((im & 0x1) << 19) |
+ ((l3cm & 0x1) << 18) |
+ ((l4pm & 0x1) << 17) |
+ ((port & 0x1f) << 12) |
+ ((l3camaddr & 0xf) << 8) |
+ (l4proto & 0xff);
+ nlm_write_nae_reg(nae_base, (NAE_L4CTABLE0 + (entry * 2)), val);
+}
+
+void
+nlm_setup_l4ctable_odd(uint64_t nae_base, int entry, uint32_t l4off0,
+ uint32_t l4len0, uint32_t l4off1, uint32_t l4len1)
+{
+ uint32_t val;
+
+ val = ((l4off0 & 0x3f) << 21) |
+ ((l4len0 & 0xf) << 17) |
+ ((l4off1 & 0x3f) << 11) |
+ (l4len1 & 0xf);
+ nlm_write_nae_reg(nae_base, (NAE_L4CTABLE0 + ((entry * 2) + 1)), val);
+}
+
+void
+nlm_enable_hardware_parser(uint64_t nae_base)
+{
+ uint32_t val;
+
+ val = nlm_read_nae_reg(nae_base, NAE_RX_CONFIG);
+ val |= (1 << 12); /* hardware parser enable */
+ nlm_write_nae_reg(nae_base, NAE_RX_CONFIG, val);
+
+ /***********************************************
+ * program L3 CAM table
+ ***********************************************/
+
+ /*
+ * entry-0 is ipv4 MPLS type 1 label
+ */
+ /* l3hdroff = 4 bytes, ether_type = 0x8847 for MPLS_type1 */
+ nlm_setup_l3ctable_even(nae_base, 0, 4, 1, 9, 1, 0x8847);
+ /* l3off0 (8 bytes) -> l3len0 (1 byte) := ip proto
+ * l3off1 (12 bytes) -> l3len1 (4 bytes) := src ip
+ * l3off2 (16 bytes) -> l3len2 (4 bytes) := dst ip
+ */
+ nlm_setup_l3ctable_odd(nae_base, 0, 9, 1, 12, 4, 16, 4);
+
+ /*
+ * entry-1 is for ethernet IPv4 packets
+ */
+ nlm_setup_l3ctable_even(nae_base, 1, 0, 1, 9, 1, 0x0800);
+ /* l3off0 (8 bytes) -> l3len0 (1 byte) := ip proto
+ * l3off1 (12 bytes) -> l3len1 (4 bytes) := src ip
+ * l3off2 (16 bytes) -> l3len2 (4 bytes) := dst ip
+ */
+ nlm_setup_l3ctable_odd(nae_base, 1, 9, 1, 12, 4, 16, 4);
+
+ /*
+ * entry-2 is for ethernet IPv6 packets
+ */
+ nlm_setup_l3ctable_even(nae_base, 2, 0, 1, 6, 1, 0x86dd);
+ /* l3off0 (6 bytes) -> l3len0 (1 byte) := next header (ip proto)
+ * l3off1 (8 bytes) -> l3len1 (16 bytes) := src ip
+ * l3off2 (24 bytes) -> l3len2 (16 bytes) := dst ip
+ */
+ nlm_setup_l3ctable_odd(nae_base, 2, 6, 1, 8, 16, 24, 16);
+
+ /*
+ * entry-3 is for ethernet ARP packets
+ */
+ nlm_setup_l3ctable_even(nae_base, 3, 0, 0, 9, 1, 0x0806);
+ /* extract 30 bytes from packet start */
+ nlm_setup_l3ctable_odd(nae_base, 3, 0, 30, 0, 0, 0, 0);
+
+ /*
+ * entry-4 is for ethernet FCoE packets
+ */
+ nlm_setup_l3ctable_even(nae_base, 4, 0, 0, 9, 1, 0x8906);
+ /* FCoE packet consists of 4 byte start-of-frame,
+ * and 24 bytes of frame header, followed by
+ * 64 bytes of optional-header (ESP, network..),
+ * 2048 bytes of payload, 36 bytes of optional
+ * "fill bytes" or ESP trailer, 4 bytes of CRC,
+ * and 4 bytes of end-of-frame
+ * We extract the first 4 + 24 = 28 bytes
+ */
+ nlm_setup_l3ctable_odd(nae_base, 4, 0, 28, 0, 0, 0, 0);
+
+ /*
+ * entry-5 is for vlan tagged frames (0x8100)
+ */
+ nlm_setup_l3ctable_even(nae_base, 5, 0, 0, 9, 1, 0x8100);
+ /* we extract 31 bytes from the payload */
+ nlm_setup_l3ctable_odd(nae_base, 5, 0, 31, 0, 0, 0, 0);
+
+ /*
+ * entry-6 is for ieee 802.1ad provider bridging
+ * tagged frames (0x88a8)
+ */
+ nlm_setup_l3ctable_even(nae_base, 6, 0, 0, 9, 1, 0x88a8);
+ /* we extract 31 bytes from the payload */
+ nlm_setup_l3ctable_odd(nae_base, 6, 0, 31, 0, 0, 0, 0);
+
+ /*
+ * entry-7 is for Cisco's Q-in-Q tagged frames (0x9100)
+ */
+ nlm_setup_l3ctable_even(nae_base, 7, 0, 0, 9, 1, 0x9100);
+ /* we extract 31 bytes from the payload */
+ nlm_setup_l3ctable_odd(nae_base, 7, 0, 31, 0, 0, 0, 0);
+
+ /*
+ * entry-8 is for Ethernet Jumbo frames (0x8870)
+ */
+ nlm_setup_l3ctable_even(nae_base, 8, 0, 0, 9, 1, 0x8870);
+ /* we extract 31 bytes from the payload */
+ nlm_setup_l3ctable_odd(nae_base, 8, 0, 31, 0, 0, 0, 0);
+
+ /*
+ * entry-9 is for MPLS Multicast frames (0x8848)
+ */
+ nlm_setup_l3ctable_even(nae_base, 9, 0, 0, 9, 1, 0x8848);
+ /* we extract 31 bytes from the payload */
+ nlm_setup_l3ctable_odd(nae_base, 9, 0, 31, 0, 0, 0, 0);
+
+ /*
+ * entry-10 is for IEEE 802.1ae MAC Security frames (0x88e5)
+ */
+ nlm_setup_l3ctable_even(nae_base, 10, 0, 0, 9, 1, 0x88e5);
+ /* we extract 31 bytes from the payload */
+ nlm_setup_l3ctable_odd(nae_base, 10, 0, 31, 0, 0, 0, 0);
+
+ /*
+ * entry-11 is for PTP frames (0x88f7)
+ */
+ nlm_setup_l3ctable_even(nae_base, 11, 0, 0, 9, 1, 0x88f7);
+ /* PTP messages can be sent as UDP messages over
+ * IPv4 or IPv6; and as a raw ethernet message
+ * with ethertype 0x88f7. The message contents
+ * are the same for UDP or ethernet based encapsulations
+ * The header is 34 bytes long, and we extract
+ * it all out.
+ */
+ nlm_setup_l3ctable_odd(nae_base, 11, 0, 31, 31, 2, 0, 0);
+
+ /*
+ * entry-12 is for ethernet Link Control Protocol (LCP)
+ * used with PPPoE
+ */
+ nlm_setup_l3ctable_even(nae_base, 12, 0, 0, 9, 1, 0xc021);
+ /* LCP packet consists of 1 byte of code, 1 byte of
+ * identifier and two bytes of length followed by
+ * data (upto length bytes).
+ * We extract 4 bytes from start of packet
+ */
+ nlm_setup_l3ctable_odd(nae_base, 12, 0, 4, 0, 0, 0, 0);
+
+ /*
+ * entry-13 is for ethernet Link Quality Report (0xc025)
+ * used with PPPoE
+ */
+ nlm_setup_l3ctable_even(nae_base, 13, 0, 0, 9, 1, 0xc025);
+ /* We extract 31 bytes from packet start */
+ nlm_setup_l3ctable_odd(nae_base, 13, 0, 31, 0, 0, 0, 0);
+
+ /*
+ * entry-14 is for PPPoE Session (0x8864)
+ */
+ nlm_setup_l3ctable_even(nae_base, 14, 0, 0, 9, 1, 0x8864);
+ /* We extract 31 bytes from packet start */
+ nlm_setup_l3ctable_odd(nae_base, 14, 0, 31, 0, 0, 0, 0);
+
+ /*
+ * entry-15 - default entry
+ */
+ nlm_setup_l3ctable_even(nae_base, 15, 0, 0, 0, 0, 0x0000);
+ /* We extract 31 bytes from packet start */
+ nlm_setup_l3ctable_odd(nae_base, 15, 0, 31, 0, 0, 0, 0);
+
+ /***********************************************
+ * program L4 CAM table
+ ***********************************************/
+
+ /*
+ * entry-0 - tcp packets (0x6)
+ */
+ nlm_setup_l4ctable_even(nae_base, 0, 0, 0, 1, 0, 0, 0x6);
+ /* tcp header is 20 bytes without tcp options
+ * We extract 20 bytes from tcp start */
+ nlm_setup_l4ctable_odd(nae_base, 0, 0, 15, 15, 5);
+
+ /*
+ * entry-1 - udp packets (0x11)
+ */
+ nlm_setup_l4ctable_even(nae_base, 1, 0, 0, 1, 0, 0, 0x11);
+ /* udp header is 8 bytes in size.
+ * We extract 8 bytes from udp start */
+ nlm_setup_l4ctable_odd(nae_base, 1, 0, 8, 0, 0);
+
+ /*
+ * entry-2 - sctp packets (0x84)
+ */
+ nlm_setup_l4ctable_even(nae_base, 2, 0, 0, 1, 0, 0, 0x84);
+ /* sctp packets have a 12 byte generic header
+ * and various chunks.
+ * We extract 12 bytes from sctp start */
+ nlm_setup_l4ctable_odd(nae_base, 2, 0, 12, 0, 0);
+
+ /*
+ * entry-3 - RDP packets (0x1b)
+ */
+ nlm_setup_l4ctable_even(nae_base, 3, 0, 0, 1, 0, 0, 0x1b);
+ /* RDP packets have 18 bytes of generic header
+ * before variable header starts.
+ * We extract 18 bytes from rdp start */
+ nlm_setup_l4ctable_odd(nae_base, 3, 0, 15, 15, 3);
+
+ /*
+ * entry-4 - DCCP packets (0x21)
+ */
+ nlm_setup_l4ctable_even(nae_base, 4, 0, 0, 1, 0, 0, 0x21);
+ /* DCCP has two types of generic headers of
+ * sizes 16 bytes and 12 bytes if X = 1.
+ * We extract 16 bytes from dccp start */
+ nlm_setup_l4ctable_odd(nae_base, 4, 0, 15, 15, 1);
+
+ /*
+ * entry-5 - ipv6 encapsulated in ipv4 packets (0x29)
+ */
+ nlm_setup_l4ctable_even(nae_base, 5, 0, 0, 1, 0, 0, 0x29);
+ /* ipv4 header is 20 bytes excluding IP options.
+ * We extract 20 bytes from IPv4 start */
+ nlm_setup_l4ctable_odd(nae_base, 5, 0, 15, 15, 5);
+
+ /*
+ * entry-6 - ip in ip encapsulation packets (0x04)
+ */
+ nlm_setup_l4ctable_even(nae_base, 6, 0, 0, 1, 0, 0, 0x04);
+ /* ipv4 header is 20 bytes excluding IP options.
+ * We extract 20 bytes from ipv4 start */
+ nlm_setup_l4ctable_odd(nae_base, 6, 0, 15, 15, 5);
+
+ /*
+ * entry-7 - default entry (0x0)
+ */
+ nlm_setup_l4ctable_even(nae_base, 7, 0, 0, 1, 0, 0, 0x0);
+ /* We extract 20 bytes from packet start */
+ nlm_setup_l4ctable_odd(nae_base, 7, 0, 15, 15, 5);
+}
+
+void
+nlm_enable_hardware_parser_per_port(uint64_t nae_base, int block, int port)
+{
+ int hwport = (block * 4) + (port & 0x3);
+
+ /* program L2 and L3 header extraction for each port */
+ /* enable ethernet L2 mode on port */
+ nlm_setup_l2type(nae_base, hwport, 0, 0, 0, 0, 0, 1);
+
+ /* l2proto and ethtype included in l3cam */
+ nlm_setup_l3ctable_mask(nae_base, hwport, 1, 0);
+}
+
+void
+nlm_prepad_enable(uint64_t nae_base, int size)
+{
+ uint32_t val;
+
+ val = nlm_read_nae_reg(nae_base, NAE_RX_CONFIG);
+ val |= (1 << 13); /* prepad enable */
+ val |= ((size & 0x3) << 22); /* prepad size */
+ nlm_write_nae_reg(nae_base, NAE_RX_CONFIG, val);
+}
+
+void
+nlm_setup_1588_timer(uint64_t nae_base, struct nae_port_config *cfg)
+{
+ uint32_t hi, lo, val;
+
+ hi = cfg[0].ieee1588_userval >> 32;
+ lo = cfg[0].ieee1588_userval & 0xffffffff;
+ nlm_write_nae_reg(nae_base, NAE_1588_PTP_USER_VALUE_HI, hi);
+ nlm_write_nae_reg(nae_base, NAE_1588_PTP_USER_VALUE_LO, lo);
+
+ hi = cfg[0].ieee1588_ptpoff >> 32;
+ lo = cfg[0].ieee1588_ptpoff & 0xffffffff;
+ nlm_write_nae_reg(nae_base, NAE_1588_PTP_OFFSET_HI, hi);
+ nlm_write_nae_reg(nae_base, NAE_1588_PTP_OFFSET_LO, lo);
+
+ hi = cfg[0].ieee1588_tmr1 >> 32;
+ lo = cfg[0].ieee1588_tmr1 & 0xffffffff;
+ nlm_write_nae_reg(nae_base, NAE_1588_PTP_TMR1_HI, hi);
+ nlm_write_nae_reg(nae_base, NAE_1588_PTP_TMR1_LO, lo);
+
+ hi = cfg[0].ieee1588_tmr2 >> 32;
+ lo = cfg[0].ieee1588_tmr2 & 0xffffffff;
+ nlm_write_nae_reg(nae_base, NAE_1588_PTP_TMR2_HI, hi);
+ nlm_write_nae_reg(nae_base, NAE_1588_PTP_TMR2_LO, lo);
+
+ hi = cfg[0].ieee1588_tmr3 >> 32;
+ lo = cfg[0].ieee1588_tmr3 & 0xffffffff;
+ nlm_write_nae_reg(nae_base, NAE_1588_PTP_TMR3_HI, hi);
+ nlm_write_nae_reg(nae_base, NAE_1588_PTP_TMR3_LO, lo);
+
+ nlm_write_nae_reg(nae_base, NAE_1588_PTP_INC_INTG,
+ cfg[0].ieee1588_inc_intg);
+ nlm_write_nae_reg(nae_base, NAE_1588_PTP_INC_NUM,
+ cfg[0].ieee1588_inc_num);
+ nlm_write_nae_reg(nae_base, NAE_1588_PTP_INC_DEN,
+ cfg[0].ieee1588_inc_den);
+
+ val = nlm_read_nae_reg(nae_base, NAE_1588_PTP_CONTROL);
+ /* set and clear freq_mul = 1 */
+ nlm_write_nae_reg(nae_base, NAE_1588_PTP_CONTROL, val | (0x1 << 1));
+ nlm_write_nae_reg(nae_base, NAE_1588_PTP_CONTROL, val);
+ /* set and clear load_user_val = 1 */
+ nlm_write_nae_reg(nae_base, NAE_1588_PTP_CONTROL, val | (0x1 << 6));
+ nlm_write_nae_reg(nae_base, NAE_1588_PTP_CONTROL, val);
+}
+
+void
+nlm_mac_enable(uint64_t nae_base, int nblock, int port_type, int port)
+{
+ uint32_t mac_cfg1, xaui_cfg;
+ uint32_t netwk_inf;
+ int iface = port & 0x3;
+
+ switch(port_type) {
+ case SGMIIC:
+ netwk_inf = nlm_read_nae_reg(nae_base,
+ SGMII_NET_IFACE_CTRL(nblock, iface));
+ nlm_write_nae_reg(nae_base,
+ SGMII_NET_IFACE_CTRL(nblock, iface),
+ netwk_inf |
+ (1 << 2)); /* enable tx */
+ mac_cfg1 = nlm_read_nae_reg(nae_base,
+ SGMII_MAC_CONF1(nblock, iface));
+ nlm_write_nae_reg(nae_base,
+ SGMII_MAC_CONF1(nblock, iface),
+ mac_cfg1 |
+ (1 << 2) | /* rx enable */
+ 1); /* tx enable */
+ break;
+ case XAUIC:
+ xaui_cfg = nlm_read_nae_reg(nae_base,
+ XAUI_CONFIG1(nblock));
+ nlm_write_nae_reg(nae_base,
+ XAUI_CONFIG1(nblock),
+ xaui_cfg |
+ XAUI_CONFIG_TFEN |
+ XAUI_CONFIG_RFEN);
+ break;
+ case ILC:
+ break;
+ }
+}
+
+void
+nlm_mac_disable(uint64_t nae_base, int nblock, int port_type, int port)
+{
+ uint32_t mac_cfg1, xaui_cfg;
+ uint32_t netwk_inf;
+ int iface = port & 0x3;
+
+ switch(port_type) {
+ case SGMIIC:
+ mac_cfg1 = nlm_read_nae_reg(nae_base,
+ SGMII_MAC_CONF1(nblock, iface));
+ nlm_write_nae_reg(nae_base,
+ SGMII_MAC_CONF1(nblock, iface),
+ mac_cfg1 &
+ ~((1 << 2) | /* rx enable */
+ 1)); /* tx enable */
+ netwk_inf = nlm_read_nae_reg(nae_base,
+ SGMII_NET_IFACE_CTRL(nblock, iface));
+ nlm_write_nae_reg(nae_base,
+ SGMII_NET_IFACE_CTRL(nblock, iface),
+ netwk_inf &
+ ~(1 << 2)); /* enable tx */
+ break;
+ case XAUIC:
+ xaui_cfg = nlm_read_nae_reg(nae_base,
+ XAUI_CONFIG1(nblock));
+ nlm_write_nae_reg(nae_base,
+ XAUI_CONFIG1(nblock),
+ xaui_cfg &
+ ~(XAUI_CONFIG_TFEN |
+ XAUI_CONFIG_RFEN));
+ break;
+ case ILC:
+ break;
+ }
+}
+
+/*
+ * Set IOR credits for the ports in ifmask to valmask
+ */
+static void
+nlm_nae_set_ior_credit(uint64_t nae_base, uint32_t ifmask, uint32_t valmask)
+{
+ uint32_t tx_config, tx_ior_credit;
+
+ tx_ior_credit = nlm_read_nae_reg(nae_base, NAE_TX_IORCRDT_INIT);
+ tx_ior_credit &= ~ifmask;
+ tx_ior_credit |= valmask;
+ nlm_write_nae_reg(nae_base, NAE_TX_IORCRDT_INIT, tx_ior_credit);
+
+ tx_config = nlm_read_nae_reg(nae_base, NAE_TX_CONFIG);
+ /* need to toggle these bits for credits to be loaded */
+ nlm_write_nae_reg(nae_base, NAE_TX_CONFIG,
+ tx_config | (TXINITIORCR(ifmask)));
+ nlm_write_nae_reg(nae_base, NAE_TX_CONFIG,
+ tx_config & ~(TXINITIORCR(ifmask)));
+}
+
+int
+nlm_nae_open_if(uint64_t nae_base, int nblock, int port_type,
+ int port, uint32_t desc_size)
+{
+ uint32_t netwk_inf;
+ uint32_t mac_cfg1, mac_cfg2, netior_ctrl3;
+ int iface, speed, duplex, ifmode;
+ int iface_ctrl_reg, iface_ctrl3_reg, conf1_reg, conf2_reg;
+
+ switch (port_type) {
+ case XAUIC:
+ netwk_inf = nlm_read_nae_reg(nae_base,
+ XAUI_NETIOR_XGMAC_CTRL1(nblock));
+ netwk_inf |= (1 << NETIOR_XGMAC_STATS_CLR_POS);
+ nlm_write_nae_reg(nae_base,
+ XAUI_NETIOR_XGMAC_CTRL1(nblock), netwk_inf);
+
+ nlm_nae_set_ior_credit(nae_base, 0xf << port, 0xf << port);
+ break;
+
+ case ILC:
+ nlm_nae_set_ior_credit(nae_base, 0xff << port, 0xff << port);
+ break;
+
+ case SGMIIC:
+ nlm_nae_set_ior_credit(nae_base, 0x1 << port, 0);
+
+ /*
+ * XXXJC: split this and merge to sgmii.c
+ * some of this is duplicated from there.
+ */
+ /* init phy id to access internal PCS */
+ iface = port & 0x3;
+ iface_ctrl_reg = SGMII_NET_IFACE_CTRL(nblock, iface);
+ conf1_reg = SGMII_MAC_CONF1(nblock, iface);
+ conf2_reg = SGMII_MAC_CONF2(nblock, iface);
+
+ netwk_inf = nlm_read_nae_reg(nae_base, iface_ctrl_reg);
+ netwk_inf &= 0x7ffffff;
+ netwk_inf |= (port << 27);
+ nlm_write_nae_reg(nae_base, iface_ctrl_reg, netwk_inf);
+
+ /* Sofreset sgmii port - set bit 11 to 0 */
+ netwk_inf &= 0xfffff7ff;
+ nlm_write_nae_reg(nae_base, iface_ctrl_reg, netwk_inf);
+
+ /* Reset Gmac */
+ mac_cfg1 = nlm_read_nae_reg(nae_base, conf1_reg);
+ nlm_write_nae_reg(nae_base, conf1_reg,
+ mac_cfg1 |
+ (1 << 31) | /* soft reset */
+ (1 << 2) | /* rx enable */
+ (1)); /* tx enable */
+
+ /* default to 1G */
+ nlm_write_nae_reg(nae_base,
+ conf2_reg,
+ (0x7 << 12) | /* interface preamble length */
+ (0x2 << 8) | /* interface mode */
+ (0x1 << 2) | /* pad crc enable */
+ (0x1)); /* full duplex */
+
+ /* clear gmac reset */
+ mac_cfg1 = nlm_read_nae_reg(nae_base, conf1_reg);
+ nlm_write_nae_reg(nae_base, conf1_reg, mac_cfg1 & ~(1 << 31));
+ /* clear speed debug bit */
+ iface_ctrl3_reg = SGMII_NET_IFACE_CTRL3(nblock, iface);
+ netior_ctrl3 = nlm_read_nae_reg(nae_base, iface_ctrl3_reg);
+ nlm_write_nae_reg(nae_base, iface_ctrl3_reg,
+ netior_ctrl3 & ~(1 << 6));
+
+ /* disable TX, RX for now */
+ mac_cfg1 = nlm_read_nae_reg(nae_base, conf1_reg);
+ nlm_write_nae_reg(nae_base, conf1_reg, mac_cfg1 & ~(0x5));
+ netwk_inf = nlm_read_nae_reg(nae_base, iface_ctrl_reg);
+ nlm_write_nae_reg(nae_base, iface_ctrl_reg,
+ netwk_inf & ~(0x1 << 2));
+
+ /* setup defaults */ /* XXXJC: take defaults from sc? */
+ speed = 2;
+ duplex = 1;
+ ifmode = 0x2;
+ netwk_inf = nlm_read_nae_reg(nae_base, iface_ctrl_reg);
+ netwk_inf &= ~(0x3);
+ nlm_write_nae_reg(nae_base, iface_ctrl_reg,
+ netwk_inf | (speed & 0x3));
+ mac_cfg2 = nlm_read_nae_reg(nae_base, conf2_reg);
+ mac_cfg2 &= ~(0x3 << 8);
+ nlm_write_nae_reg(nae_base, conf2_reg,
+ mac_cfg2 |
+ ((ifmode & 0x3) << 8) | /* interface mode */
+ (duplex & 0x1));
+
+ /* clear stats counters */
+ netwk_inf = nlm_read_nae_reg(nae_base, iface_ctrl_reg);
+ nlm_write_nae_reg(nae_base, iface_ctrl_reg,
+ netwk_inf | (1 << 15));
+ /* enable stats counters */
+ netwk_inf = nlm_read_nae_reg(nae_base, iface_ctrl_reg);
+ nlm_write_nae_reg(nae_base, iface_ctrl_reg,
+ (netwk_inf & ~(1 << 15)) | (1 << 16));
+ mac_cfg1 = nlm_read_nae_reg(nae_base, conf1_reg);
+ nlm_write_nae_reg(nae_base, conf1_reg,
+ mac_cfg1 | (0x3 << 4));
+ break;
+ }
+
+ nlm_nae_init_ingress(nae_base, desc_size);
+ nlm_nae_init_egress(nae_base);
+
+ return (0);
+}
diff --git a/sys/mips/nlm/dev/net/sgmii.c b/sys/mips/nlm/dev/net/sgmii.c
new file mode 100644
index 0000000..91f5f7a
--- /dev/null
+++ b/sys/mips/nlm/dev/net/sgmii.c
@@ -0,0 +1,216 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * 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 BROADCOM ``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 BROADCOM 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/types.h>
+#include <sys/systm.h>
+
+#include <mips/nlm/hal/mips-extns.h>
+#include <mips/nlm/hal/haldefs.h>
+#include <mips/nlm/hal/iomap.h>
+#include <mips/nlm/hal/sys.h>
+#include <mips/nlm/hal/nae.h>
+#include <mips/nlm/hal/mdio.h>
+#include <mips/nlm/hal/sgmii.h>
+
+void
+nlm_configure_sgmii_interface(uint64_t nae_base, int block, int port,
+ int mtu, int loopback)
+{
+ uint32_t data1, data2;
+
+ /* Apply a soft reset */
+ data1 = (0x1 << 31); /* soft reset */
+ if (loopback)
+ data1 |= (0x01 << 8);
+ data1 |= (0x01 << 2); /* Rx enable */
+ data1 |= 0x01; /* Tx enable */
+ nlm_write_nae_reg(nae_base, NAE_REG(block, port, MAC_CONF1), data1);
+
+ data2 = (0x7 << 12) | /* pre-amble length=7 */
+ (0x2 << 8) | /* byteMode */
+ 0x1; /* fullDuplex */
+ nlm_write_nae_reg(nae_base, NAE_REG(block, port, MAC_CONF2), data2);
+
+ /* Remove a soft reset */
+ data1 &= ~(0x01 << 31);
+ nlm_write_nae_reg(nae_base, NAE_REG(block, port, MAC_CONF1), data1);
+
+ /* setup sgmii max frame length */
+ nlm_write_nae_reg(nae_base, SGMII_MAX_FRAME(block, port), mtu);
+}
+
+void
+nlm_sgmii_pcs_init(uint64_t nae_base, uint32_t cplx_mask)
+{
+ /* reset internal MDIO */
+ nlm_int_gmac_mdio_reset(nae_base, 0, BLOCK_7, LANE_CFG);
+
+ /* reset external MDIO */
+ nlm_gmac_mdio_reset(nae_base, 0, BLOCK_7, LANE_CFG);
+ nlm_gmac_mdio_reset(nae_base, 1, BLOCK_7, LANE_CFG);
+
+ xlp_nae_config_lane_gmac(nae_base, cplx_mask);
+}
+
+void
+nlm_nae_setup_mac(uint64_t nae_base, int nblock, int iface, int reset,
+ int rx_en, int tx_en, int speed, int duplex)
+{
+ uint32_t mac_cfg1, mac_cfg2, netwk_inf;
+
+ mac_cfg1 = nlm_read_nae_reg(nae_base,
+ SGMII_MAC_CONF1(nblock,iface));
+ mac_cfg2 = nlm_read_nae_reg(nae_base,
+ SGMII_MAC_CONF2(nblock,iface));
+ netwk_inf = nlm_read_nae_reg(nae_base,
+ SGMII_NET_IFACE_CTRL(nblock, iface));
+
+ mac_cfg1 &= ~(0x1 << 31); /* remove reset */
+ mac_cfg1 &= ~(0x1 << 2); /* remove rx */
+ mac_cfg1 &= ~(0x1); /* remove tx */
+ mac_cfg2 &= ~(0x3 << 8); /* remove interface mode bits */
+ mac_cfg2 &= ~(0x1); /* remove duplex */
+ netwk_inf &= ~(0x1 << 2); /* remove tx */
+ netwk_inf &= ~(0x3); /* remove speed */
+
+ switch (speed) {
+ case NLM_SGMII_SPEED_10:
+ netwk_inf |= 0x0; /* 2.5 Mhz clock for 10 Mbps */
+ mac_cfg2 |= (0x1 << 8); /* enable 10/100 Mbps */
+ break;
+ case NLM_SGMII_SPEED_100:
+ netwk_inf |= 0x1; /* 25 Mhz clock for 100 Mbps */
+ mac_cfg2 |= (0x1 << 8); /* enable 10/100 Mbps */
+ break;
+ default: /* make it as 1G */
+ netwk_inf |= 0x2; /* 125 Mhz clock for 1G */
+ mac_cfg2 |= (0x2 << 8); /* enable 1G */
+ break;
+ }
+
+ if (reset)
+ mac_cfg1 |= (0x1 << 31); /* set reset */
+
+ if (rx_en)
+ mac_cfg1 |= (0x1 << 2); /* set rx */
+
+ nlm_write_nae_reg(nae_base,
+ SGMII_NET_IFACE_CTRL(nblock, iface),
+ netwk_inf);
+
+ if (tx_en) {
+ mac_cfg1 |= 0x1; /* set tx */
+ netwk_inf |= (0x1 << 2); /* set tx */
+ }
+
+ switch (duplex) {
+ case NLM_SGMII_DUPLEX_HALF:
+ /* duplexity is already set to half duplex */
+ break;
+ default:
+ mac_cfg2 |= 0x1; /* set full duplex */
+ }
+
+ nlm_write_nae_reg(nae_base, SGMII_MAC_CONF1(nblock, iface), mac_cfg1);
+ nlm_write_nae_reg(nae_base, SGMII_MAC_CONF2(nblock, iface), mac_cfg2);
+ nlm_write_nae_reg(nae_base, SGMII_NET_IFACE_CTRL(nblock, iface),
+ netwk_inf);
+}
+
+void
+nlm_nae_setup_rx_mode_sgmii(uint64_t base, int nblock, int iface, int port_type,
+ int broadcast_en, int multicast_en, int pause_en, int promisc_en)
+{
+ uint32_t val;
+
+ /* bit[17] of vlan_typefilter - allows packet matching in MAC.
+ * When DA filtering is disabled, this bit and bit[16] should
+ * be zero.
+ * bit[16] of vlan_typefilter - Allows hash matching to be used
+ * for DA filtering. When DA filtering is disabled, this bit and
+ * bit[17] should be zero.
+ * Both bits have to be set only if you want to turn on both
+ * features / modes.
+ */
+ if (promisc_en == 1) {
+ val = nlm_read_nae_reg(base,
+ SGMII_NETIOR_VLANTYPE_FILTER(nblock, iface));
+ val &= (~(0x3 << 16));
+ nlm_write_nae_reg(base,
+ SGMII_NETIOR_VLANTYPE_FILTER(nblock, iface), val);
+ } else {
+ val = nlm_read_nae_reg(base,
+ SGMII_NETIOR_VLANTYPE_FILTER(nblock, iface));
+ val |= (0x1 << 17);
+ nlm_write_nae_reg(base,
+ SGMII_NETIOR_VLANTYPE_FILTER(nblock, iface), val);
+ }
+
+ val = ((broadcast_en & 0x1) << 10) |
+ ((pause_en & 0x1) << 9) |
+ ((multicast_en & 0x1) << 8) |
+ ((promisc_en & 0x1) << 7) | /* unicast_enable - enables promisc mode */
+ 1; /* MAC address is always valid */
+
+ nlm_write_nae_reg(base, SGMII_MAC_FILTER_CONFIG(nblock, iface), val);
+
+}
+
+void
+nlm_nae_setup_mac_addr_sgmii(uint64_t base, int nblock, int iface,
+ int port_type, uint8_t *mac_addr)
+{
+ nlm_write_nae_reg(base,
+ SGMII_MAC_ADDR0_LO(nblock, iface),
+ (mac_addr[5] << 24) |
+ (mac_addr[4] << 16) |
+ (mac_addr[3] << 8) |
+ mac_addr[2]);
+
+ nlm_write_nae_reg(base,
+ SGMII_MAC_ADDR0_HI(nblock, iface),
+ (mac_addr[1] << 24) |
+ (mac_addr[0] << 16));
+
+ nlm_write_nae_reg(base,
+ SGMII_MAC_ADDR_MASK0_LO(nblock, iface),
+ 0xffffffff);
+ nlm_write_nae_reg(base,
+ SGMII_MAC_ADDR_MASK0_HI(nblock, iface),
+ 0xffffffff);
+
+ nlm_nae_setup_rx_mode_sgmii(base, nblock, iface,
+ SGMIIC,
+ 1, /* broadcast enabled */
+ 1, /* multicast enabled */
+ 0, /* do not accept pause frames */
+ 0 /* promisc mode disabled */
+ );
+}
diff --git a/sys/mips/nlm/dev/net/ucore/crt0_basic.S b/sys/mips/nlm/dev/net/ucore/crt0_basic.S
new file mode 100644
index 0000000..79f8f4b
--- /dev/null
+++ b/sys/mips/nlm/dev/net/ucore/crt0_basic.S
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * 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 BROADCOM ``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 BROADCOM 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <machine/asm.h>
+
+ .text
+ .align 2
+ .globl _start
+ .ent _start
+_start:
+ .set noreorder
+ la gp, _gp
+ .end _start
+
+ .globl __stack
+
+ .ent zerobss
+zerobss:
+ la v0, _fbss
+ la v1, _end
+3:
+ sw zero, 0(v0)
+ bltu v0,v1,3b
+ addiu v0,v0,4 # executed in delay slot
+ la sp, __stack # set stack pointer
+ .end zerobss
+
+ .ent init
+init:
+ addiu a1,sp,32 # argv = sp + 32
+ addiu a2,sp,40 # envp = sp + 40
+ sw zero,(a1) # argv[argc] = 0
+ sw zero,(a2) # envp[0] = 0
+ jal main # call the program start function
+ move a0,zero # set argc to 0
+1: b 1b
+ nop
+ .end init
+
diff --git a/sys/mips/nlm/dev/net/ucore/ld.ucore.S b/sys/mips/nlm/dev/net/ucore/ld.ucore.S
new file mode 100644
index 0000000..aff83b8
--- /dev/null
+++ b/sys/mips/nlm/dev/net/ucore/ld.ucore.S
@@ -0,0 +1,162 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * 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 BROADCOM ``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 BROADCOM 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.
+ *
+ * $FreeBSD$
+ */
+
+ENTRY(_start)
+OUTPUT_FORMAT(elf32-tradbigmips)
+__DYNAMIC = 0;
+
+SECTIONS
+{
+ . = 0x0;
+ _loadaddr = . ;
+
+ /* ----------------------------------------- */
+
+ .text : {
+ _ftext = . ;
+ PROVIDE (eprol = .);
+ _shim_reg = . ;
+ *(.text)
+ *(.text.*)
+ *(.gnu.linkonce.t*)
+ *(.mips16.fn.*)
+ *(.mips16.call.*)
+ }
+ .init : {
+ KEEP(*(.init))
+ *(.init)
+ }
+ .fini : {
+ *(.fini)
+ }
+ .rel.sdata : {
+ PROVIDE (__runtime_reloc_start = .);
+ *(.rel.sdata)
+ PROVIDE (__runtime_reloc_stop = .);
+ }
+ PROVIDE (etext = .);
+ .ctors :
+ {
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ }
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ }
+ . = .;
+ .rodata : {
+ *(.rdata)
+ *(.rodata)
+ *(.rodata.*)
+ *(.gnu.linkonce.r*)
+ }
+ . = . + (0x1000 - .) ;
+
+ /* ----------------------------------------- */
+
+ . = 0x8000 ;
+ magicstart = . ;
+ .magicregs : {
+ *(.magicregs)
+ }
+ magicend = . ;
+
+ /* ----------------------------------------- */
+
+ . = 0x18000 ;
+ shmemstart = . ;
+ .sharedmem : {
+ *(.sharedmem)
+ }
+ shmemend = . ;
+
+ /* ----------------------------------------- */
+
+ . = 0xFF800 ;
+ .data : {
+ *(.data)
+ *(.data.*)
+ *(.gnu.linkonce.d*)
+ }
+ . = ALIGN(8);
+ .lit8 : {
+ *(.lit8)
+ }
+ .lit4 : {
+ *(.lit4)
+ }
+ .sdata : {
+ *(.sdata)
+ *(.sdata.*)
+ *(.gnu.linkonce.s*)
+ }
+ . = ALIGN (8);
+ PROVIDE (edata = .);
+ _edata = .;
+ _fbss = .;
+ .sbss : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss : {
+ _bss_start = . ;
+ *(.bss)
+ *(COMMON)
+ }
+ _bss_end = . ;
+ _end = .;
+
+ _gp = . ;
+ __global = _gp ;
+ . = ALIGN (8);
+
+ PROVIDE(__stackmarker = .) ;
+
+ . = 0xFFA00 ;
+
+ /* 32 + 4(argc) + 4(argv), aligned to 64 */
+ PROVIDE(__stack = . - 64);
+
+ /* ----------------------------------------- */
+
+ . = 0xFFE00 ;
+ .pktbuf : {
+ *(.pktbuf)
+ }
+ . = . + (0x100000 - .) ;
+
+ PROVIDE(_endaddr = 0x0 + 0x100000);
+}
diff --git a/sys/mips/nlm/dev/net/ucore/ucore.h b/sys/mips/nlm/dev/net/ucore/ucore.h
new file mode 100644
index 0000000..cd3b6bc
--- /dev/null
+++ b/sys/mips/nlm/dev/net/ucore/ucore.h
@@ -0,0 +1,356 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * 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 BROADCOM ``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 BROADCOM 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.
+ *
+ * $FreeBSD$
+ */
+#ifndef __NLM_UCORE_H__
+#define __NLM_UCORE_H__
+
+/* Microcode registers */
+#define UCORE_OUTBUF_DONE 0x8000
+#define UCORE_RX_PKT_RDY 0x8004
+#define UCORE_RX_PKT_INFO 0x8008
+#define UCORE_CAM0 0x800c
+#define UCORE_CAM1 0x8010
+#define UCORE_CAM2 0x8014
+#define UCORE_CAM3 0x8018
+#define UCORE_CAM_RESULT 0x801c
+#define UCORE_CSUMINFO 0x8020
+#define UCORE_CRCINFO 0x8024
+#define UCORE_CRCPOS 0x8028
+#define UCORE_FR_FIFOEMPTY 0x802c
+#define UCORE_PKT_DISTR 0x8030
+
+#define PACKET_MEMORY (0xFFE00)
+#define PACKET_DATA_OFFSET (64)
+#define SHARED_SCRATCH_MEM 0x18000
+
+/* Distribution mode */
+#define VAL_PDM(x) (((x) & 0x7) << 0)
+
+/* Dest distribution or distribution list */
+#define VAL_DEST(x) (((x) & 0x3ff) << 8)
+#define VAL_PDL(x) (((x) & 0xf) << 4)
+
+/*output buffer done*/
+#define VAL_FSV(x) (x<<19)
+#define VAL_FFS(x) (x<<14)
+
+#define FWD_DEST_ONLY 1
+#define FWD_ENQ_DIST_VEC 2
+#define FWD_ENQ_DEST 3
+#define FWD_DIST_VEC 4
+#define FWD_ENQ_DIST_VEC_SER 6
+#define FWD_ENQ_DEST_SER 7
+
+#define USE_HASH_DST (1 << 20)
+
+
+#define NLM_DEFINE_UCORE(name, reg) \
+static __inline__ unsigned int nlm_read_ucore_##name(void) \
+{ \
+ unsigned int __rv; \
+ __asm__ __volatile__ ( \
+ ".set push\n" \
+ ".set noreorder\n" \
+ ".set mips32\n" \
+ "li $8, %1\n" \
+ "lw %0, ($8)\n" \
+ ".set pop\n" \
+ : "=r" (__rv) \
+ : "i" (reg) \
+ : "$8" \
+ ); \
+ return __rv; \
+} \
+ \
+static __inline__ void nlm_write_ucore_##name(unsigned int val) \
+{ \
+ __asm__ __volatile__( \
+ ".set push\n" \
+ ".set noreorder\n" \
+ ".set mips32\n" \
+ "li $8, %1\n" \
+ "sw %0, ($8)\n" \
+ ".set pop\n" \
+ :: "r" (val), "i" (reg) \
+ : "$8" \
+ ); \
+} struct __hack
+
+
+NLM_DEFINE_UCORE(obufdone, UCORE_OUTBUF_DONE);
+NLM_DEFINE_UCORE(rxpktrdy, UCORE_RX_PKT_RDY);
+NLM_DEFINE_UCORE(rxpktinfo, UCORE_RX_PKT_INFO);
+NLM_DEFINE_UCORE(cam0, UCORE_CAM0);
+NLM_DEFINE_UCORE(cam1, UCORE_CAM1);
+NLM_DEFINE_UCORE(cam2, UCORE_CAM2);
+NLM_DEFINE_UCORE(cam3, UCORE_CAM3);
+NLM_DEFINE_UCORE(camresult, UCORE_CAM_RESULT);
+NLM_DEFINE_UCORE(csuminfo, UCORE_CSUMINFO);
+NLM_DEFINE_UCORE(crcinfo, UCORE_CRCINFO);
+NLM_DEFINE_UCORE(crcpos, UCORE_CRCPOS);
+NLM_DEFINE_UCORE(freefifo_empty, UCORE_FR_FIFOEMPTY);
+NLM_DEFINE_UCORE(pktdistr, UCORE_PKT_DISTR);
+
+/*
+ * l3cachelines - number of cache lines to allocate into l3
+ * fsv - 0 : use interface-id for selecting the free fifo pool
+ * 1 : use free fifo pool selected by FFS field
+ * ffs - selects which free fifo pool to use to take a free fifo
+ * prepad_en - If this field is set to 1, part or all of the
+ * 64 byte prepad seen by micro engines, is written
+ * infront of every packet.
+ * prepad_ovride - If this field is 1, the ucore system uses
+ * prepad configuration defined in this register,
+ * 0 means that it uses the configuration defined
+ * in NAE RX_CONFIG register
+ * prepad_size - number of 16 byte words in the 64-byte prepad
+ * seen by micro engines and dma'ed to memory as
+ * pkt prepad. This field is meaningful only if
+ * prepad_en and prepad_ovride is set.
+ * 0 : 1 word
+ * 1 : 2 words
+ * 2 : 3 words
+ * 3 : 4 words
+ * prepad[0-3]: writing 0 to this means that the 1st 16 byte offset
+ * of prepad in micro engine, gets setup as prepad0/1/2/3.
+ * prepad word.
+ * 1 : means 2nd 16 byte chunk in prepad0/1/2/3
+ * 2 : means 3rd 16 byte chunk in prepad0/1/2/3
+ * 3 : means 4rth 16 byte chunk in prepad0/1/2/3
+ * pkt_discard - packet will be discarded if this is set to 1
+ * rd5 - value (single bit) to be inserted in bit 5, the unclassified
+ * pkt bit of receive descriptor. If this bit is set, HPRE bit
+ * should also be set in ucore_rxpktready register
+ */
+static __inline__ void
+nlm_ucore_pkt_done(int l3cachelines, int fsv, int ffs, int prepad_en,
+ int prepad_ovride, int prepad_size, int prepad0, int prepad1,
+ int prepad2, int prepad3, int pkt_discard, int rd5)
+{
+ unsigned int val = 0;
+
+ val |= ((l3cachelines & 0xfff) << 20);
+ val |= ((fsv & 0x1) << 19);
+ val |= ((ffs & 0x1f) << 14);
+ val |= ((prepad_en & 0x1) << 3);
+ val |= ((prepad_ovride & 0x1) << 2);
+ val |= ((prepad_size & 0x3) << 12);
+ val |= ((prepad0 & 0x3) << 4);
+ val |= ((prepad1 & 0x3) << 6);
+ val |= ((prepad2 & 0x3) << 8);
+ val |= ((prepad3 & 0x3) << 10);
+ val |= ((pkt_discard & 0x1) << 1);
+ val |= ((rd5 & 0x1) << 0);
+
+ nlm_write_ucore_obufdone(val);
+}
+
+/* Get the class full vector field from POE.
+ * The POE maintains a threshold for each class.
+ * A bit in this field will be set corresponding to the class approaching
+ * class full status.
+ */
+static __inline__ int
+nlm_ucore_get_rxpkt_poeclassfullvec(unsigned int pktrdy)
+{
+ return ((pktrdy >> 24) & 0xff);
+}
+
+/* This function returns 1 if the hardware parser extraction process
+ * resulted in an error. Else, returns 0.
+ */
+static __inline__ int
+nlm_ucore_get_rxpkt_hwparsererr(unsigned int pktrdy)
+{
+ return ((pktrdy >> 23) & 0x1);
+}
+
+/* This function returns the context number assigned to incoming
+ * packet
+ */
+static __inline__ int
+nlm_ucore_get_rxpkt_context(unsigned int pktrdy)
+{
+ return ((pktrdy >> 13) & 0x3ff);
+}
+
+/* this function returns the channel number of incoming packet,
+ * and applies only to interlaken.
+ */
+static __inline__ int
+nlm_ucore_get_rxpkt_channel(unsigned int pktrdy)
+{
+ return ((pktrdy >> 5) & 0xff);
+}
+
+/* This function returns the interface number on which the pkt
+ * was received
+ */
+static __inline__ int
+nlm_ucore_get_rxpkt_interface(unsigned int pktrdy)
+{
+ return (pktrdy & 0x1f);
+}
+
+/* This function returns 1 if end of packet (EOP) is set in
+ * packet data.
+ */
+static __inline__ int
+nlm_ucore_get_rxpkt_eop(unsigned int rxpkt_info)
+{
+ return ((rxpkt_info >> 9) & 0x1);
+}
+
+/* This function returns packet length of received pkt */
+static __inline__ int
+nlm_ucore_get_rxpktlen(unsigned int rxpkt_info)
+{
+ return (rxpkt_info & 0x1ff);
+}
+
+/* this function sets up the ucore TCAM keys. */
+static __inline__ void
+nlm_ucore_setup_camkey(unsigned int cam_key0, unsigned int cam_key1,
+ unsigned int cam_key2, unsigned int cam_key3)
+{
+ nlm_write_ucore_cam0(cam_key0);
+ nlm_write_ucore_cam1(cam_key1);
+ nlm_write_ucore_cam2(cam_key2);
+ nlm_write_ucore_cam3(cam_key3);
+}
+
+/* This function checks if the cam result is valid or not.
+ * If valid, it returns the result, else it returns 0.
+ */
+static __inline__ int
+nlm_ucore_get_cam_result(unsigned int cam_result)
+{
+ if (((cam_result >> 15) & 0x1) == 1) /* valid result */
+ return (cam_result & 0x3fff);
+
+ return 0;
+}
+
+/* This function sets up the csum in ucore.
+ * iphdr_start - defines the start of ip header (to check - is this byte
+ * position???)
+ * iphdr_len - This field is auto filled by h/w parser if zero, else
+ * the value defined will be used.
+ */
+static __inline__ void
+nlm_ucore_csum_setup(int iphdr_start, int iphdr_len)
+{
+ unsigned int val = 0;
+
+ val |= ((iphdr_len & 0xff) << 8);
+ val |= (iphdr_len & 0xff);
+ nlm_write_ucore_csuminfo(val);
+}
+
+/* crcpos - position of crc in pkt. If crc position is within startcrc and
+ * endcrc, zero out these bytes in the packet before computing crc. This
+ * field is not needed for FCoE.
+ * cps - If 1, uses the polynomial in RX_CRC_POLY1 of NAE register.
+ * if 0, uses the polynomial in RX_CRC_POLY0 of NAE register.
+ * fcoe - If this is 1, crc calculation starts from 'startCRC' and the CRC
+ * engine ends calculation before the last byte.
+ * cbm - if 1, enables crc byte mirroring, where bits within a byte will get
+ * reversed (mirrored) during calculation of crc.
+ * cfi - If 1, performs a final inversion of crc before comarison is done during
+ * pkt reception.
+ * startcrc - This field is always required for both FCoE and SCTP crc.
+ * endcrc - This information needs to be setup only for SCTP. For FCoE this
+ * information is provided by hardware.
+ * valid - if set to 1, CRC status is placed into bit 2 of rx descriptor
+ * if set to 0, TCP checksum status is placed into bit 2 of rx descriptor
+ * keysize - defines the number of bytes in the pre-pad that contains the key
+ */
+static __inline__ void
+nlm_ucore_crc_setup(int crcpos, int cps, int cfi, int cbm, int fcoe,
+ int keysize, int valid, int startcrc, int endcrc)
+{
+ unsigned int val = 0;
+
+ val |= ((cfi & 0x1) << 20);
+ val |= ((cbm & 0x1) << 19);
+ val |= ((fcoe & 0x1) << 18);
+ val |= ((cps & 0x1) << 16);
+ val |= (crcpos & 0xffff);
+
+ nlm_write_ucore_crcpos(val);
+
+ val = 0;
+ val |= ((keysize & 0x3f) << 25);
+ val |= ((valid & 0x1) << 24);
+ val |= ((endcrc & 0xffff) << 8);
+ val |= (startcrc & 0xff);
+
+ nlm_write_ucore_crcinfo(val);
+}
+
+/* This function returns a fifo empty vector, where each bit provides
+ * the status of a fifo pool, where if the pool is empty the bit gets
+ * set to 1.
+ */
+static __inline__ int
+nlm_ucore_get_fifoempty(unsigned int fifoempty)
+{
+ return (fifoempty & 0xfffff);
+}
+
+/* This function controls how POE will distribute the packet.
+ * pdm - is the packet distribution mode, where
+ * 0x0 - means packet distribution mode is not used
+ * 0x1 - means forwarding based on destination only (no enqueue)
+ * 0x2 - means forwarding based on FID and distr vector (enqueue)
+ * 0x3 - means forwarding based on dest and FID (enqueue)
+ * 0x4 - means forwarding based on distr vec (no enqueue)
+ * 0x6 - means forward based on FID (enqueue), distr vec and serial mode
+ * 0x7 - means forward based on FID (enqueue), dest and serial mode
+ * mc3 - If 1, then the 3 most significant bits of distribution list are taken
+ * from context->class_table
+ * pdl - poe distribution list
+ * dest - fixed destination setup
+ * hash - if 1, use hash based destination
+ */
+static __inline__ void
+nlm_ucore_setup_poepktdistr(int pdm, int mc3, int pdl, int dest, int hash)
+{
+ unsigned int val = 0;
+
+ val |= ((hash & 0x1) << 20);
+ val |= ((dest & 0xfff) << 8);
+ val |= ((pdl & 0xf) << 4);
+ val |= ((mc3 & 0x1) << 3);
+ val |= (pdm & 0x7);
+
+ nlm_write_ucore_pktdistr(val);
+}
+
+#endif
diff --git a/sys/mips/nlm/dev/net/ucore/ucore_app.c b/sys/mips/nlm/dev/net/ucore/ucore_app.c
new file mode 100644
index 0000000..57135e8
--- /dev/null
+++ b/sys/mips/nlm/dev/net/ucore/ucore_app.c
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * 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 BROADCOM ``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 BROADCOM 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.
+ *
+ * $FreeBSD$
+ */
+
+#include "ucore.h"
+
+int main(void)
+{
+#if 0
+ volatile unsigned int *pkt =
+ (volatile unsigned int *) (PACKET_MEMORY + PACKET_DATA_OFFSET);
+ int intf, hw_parser_error, context;
+#endif
+ unsigned int pktrdy;
+ int num_cachelines = 1518 >> 6; /* pktsize / L3 cacheline size */
+
+
+ /* Spray packets to using distribution vector */
+ while (1) {
+ pktrdy = nlm_read_ucore_rxpktrdy();
+#if 0
+ intf = pktrdy & 0x1f;
+ context = (pktrdy >> 13) & 0x3ff;
+ hw_parser_error = (pktrdy >> 23) & 0x1;
+#endif
+ nlm_ucore_setup_poepktdistr(FWD_DIST_VEC, 0, 0, 0, 0);
+ nlm_ucore_pkt_done(num_cachelines, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0);
+ }
+
+ return (0);
+}
diff --git a/sys/mips/nlm/dev/net/xaui.c b/sys/mips/nlm/dev/net/xaui.c
new file mode 100644
index 0000000..8b4c6a9
--- /dev/null
+++ b/sys/mips/nlm/dev/net/xaui.c
@@ -0,0 +1,251 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * 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 BROADCOM ``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 BROADCOM 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/types.h>
+#include <sys/systm.h>
+
+#include <mips/nlm/hal/mips-extns.h>
+#include <mips/nlm/hal/haldefs.h>
+#include <mips/nlm/hal/iomap.h>
+#include <mips/nlm/hal/sys.h>
+#include <mips/nlm/hal/nae.h>
+#include <mips/nlm/hal/mdio.h>
+#include <mips/nlm/hal/sgmii.h>
+#include <mips/nlm/hal/xaui.h>
+
+#include <mips/nlm/xlp.h>
+void
+nlm_xaui_pcs_init(uint64_t nae_base, int xaui_cplx_mask)
+{
+ int block, lane_ctrl, reg;
+ int cplx_lane_enable;
+ int lane_enable = 0;
+ uint32_t regval;
+
+ cplx_lane_enable = LM_XAUI |
+ (LM_XAUI << 4) |
+ (LM_XAUI << 8) |
+ (LM_XAUI << 12);
+
+ if (xaui_cplx_mask == 0)
+ return;
+
+ /* write 0x2 to enable SGMII for all lane */
+ block = 7;
+
+ if (xaui_cplx_mask & 0x3) { /* Complexes 0, 1 */
+ lane_enable = nlm_read_nae_reg(nae_base,
+ NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_0_1));
+ if (xaui_cplx_mask & 0x1) { /* Complex 0 */
+ lane_enable &= ~(0xFFFF);
+ lane_enable |= cplx_lane_enable;
+ }
+ if (xaui_cplx_mask & 0x2) { /* Complex 1 */
+ lane_enable &= ~(0xFFFF<<16);
+ lane_enable |= (cplx_lane_enable << 16);
+ }
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_0_1),
+ lane_enable);
+ }
+ lane_enable = 0;
+ if (xaui_cplx_mask & 0xc) { /* Complexes 2, 3 */
+ lane_enable = nlm_read_nae_reg(nae_base,
+ NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_2_3));
+ if (xaui_cplx_mask & 0x4) { /* Complex 2 */
+ lane_enable &= ~(0xFFFF);
+ lane_enable |= cplx_lane_enable;
+ }
+ if (xaui_cplx_mask & 0x8) { /* Complex 3 */
+ lane_enable &= ~(0xFFFF<<16);
+ lane_enable |= (cplx_lane_enable << 16);
+ }
+ nlm_write_nae_reg(nae_base,
+ NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_2_3),
+ lane_enable);
+ }
+
+ /* Bring txpll out of reset */
+ for (block = 0; block < 4; block++) {
+ if ((xaui_cplx_mask & (1 << block)) == 0)
+ continue;
+
+ for (lane_ctrl = PHY_LANE_0_CTRL;
+ lane_ctrl <= PHY_LANE_3_CTRL; lane_ctrl++) {
+ if (!nlm_is_xlp8xx_ax())
+ xlp_nae_lane_reset_txpll(nae_base,
+ block, lane_ctrl, PHYMODE_XAUI);
+ else
+ xlp_ax_nae_lane_reset_txpll(nae_base, block,
+ lane_ctrl, PHYMODE_XAUI);
+ }
+ }
+
+ /* Wait for Rx & TX clock stable */
+ for (block = 0; block < 4; block++) {
+ if ((xaui_cplx_mask & (1 << block)) == 0)
+ continue;
+
+ for (lane_ctrl = PHY_LANE_0_CTRL;
+ lane_ctrl <= PHY_LANE_3_CTRL; lane_ctrl++) {
+
+ reg = NAE_REG(block, PHY, lane_ctrl - 4);
+ /* Wait for TX clock to be set */
+ do {
+ regval = nlm_read_nae_reg(nae_base, reg);
+ } while ((regval & LANE_TX_CLK) == 0);
+
+ /* Wait for RX clock to be set */
+ do {
+ regval = nlm_read_nae_reg(nae_base, reg);
+ } while ((regval & LANE_RX_CLK) == 0);
+
+ /* Wait for XAUI Lane fault to be cleared */
+ do {
+ regval = nlm_read_nae_reg(nae_base, reg);
+ } while ((regval & XAUI_LANE_FAULT) != 0);
+ }
+ }
+}
+
+void
+nlm_nae_setup_rx_mode_xaui(uint64_t base, int nblock, int iface, int port_type,
+ int broadcast_en, int multicast_en, int pause_en, int promisc_en)
+{
+ uint32_t val;
+
+ val = ((broadcast_en & 0x1) << 10) |
+ ((pause_en & 0x1) << 9) |
+ ((multicast_en & 0x1) << 8) |
+ ((promisc_en & 0x1) << 7) | /* unicast_enable - enables promisc mode */
+ 1; /* MAC address is always valid */
+
+ nlm_write_nae_reg(base, XAUI_MAC_FILTER_CFG(nblock), val);
+}
+
+void
+nlm_nae_setup_mac_addr_xaui(uint64_t base, int nblock, int iface,
+ int port_type, unsigned char *mac_addr)
+{
+ nlm_write_nae_reg(base,
+ XAUI_MAC_ADDR0_LO(nblock),
+ (mac_addr[5] << 24) |
+ (mac_addr[4] << 16) |
+ (mac_addr[3] << 8) |
+ mac_addr[2]);
+
+ nlm_write_nae_reg(base,
+ XAUI_MAC_ADDR0_HI(nblock),
+ (mac_addr[1] << 24) |
+ (mac_addr[0] << 16));
+
+ nlm_write_nae_reg(base,
+ XAUI_MAC_ADDR_MASK0_LO(nblock),
+ 0xffffffff);
+ nlm_write_nae_reg(base,
+ XAUI_MAC_ADDR_MASK0_HI(nblock),
+ 0xffffffff);
+
+ nlm_nae_setup_rx_mode_xaui(base, nblock, iface,
+ XAUIC,
+ 1, /* broadcast enabled */
+ 1, /* multicast enabled */
+ 0, /* do not accept pause frames */
+ 0 /* promisc mode disabled */
+ );
+}
+
+void
+nlm_config_xaui_mtu(uint64_t nae_base, int nblock,
+ int max_tx_frame_sz, int max_rx_frame_sz)
+{
+ uint32_t tx_words = max_tx_frame_sz >> 2; /* max_tx_frame_sz / 4 */
+
+ /* write max frame length */
+ nlm_write_nae_reg(nae_base,
+ XAUI_MAX_FRAME_LEN(nblock),
+ ((tx_words & 0x3ff) << 16) | (max_rx_frame_sz & 0xffff));
+}
+
+void
+nlm_config_xaui(uint64_t nae_base, int nblock,
+ int max_tx_frame_sz, int max_rx_frame_sz, int vlan_pri_en)
+{
+ uint32_t val;
+
+ val = nlm_read_nae_reg(nae_base, XAUI_NETIOR_XGMAC_CTRL1(nblock));
+ val &= ~(0x1 << 11); /* clear soft reset */
+ nlm_write_nae_reg(nae_base, XAUI_NETIOR_XGMAC_CTRL1(nblock), val);
+
+ val = nlm_read_nae_reg(nae_base, XAUI_NETIOR_XGMAC_CTRL1(nblock));
+ val &= ~(0x3 << 11); /* clear soft reset and hard reset */
+ nlm_write_nae_reg(nae_base, XAUI_NETIOR_XGMAC_CTRL1(nblock), val);
+ nlm_write_nae_reg(nae_base, XAUI_CONFIG0(nblock), 0xffffffff);
+ nlm_write_nae_reg(nae_base, XAUI_CONFIG0(nblock), 0);
+
+ /* Enable tx/rx frame */
+ val = 0xF00010A8;
+ 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 */
+ nlm_config_xaui_mtu(nae_base, nblock, max_tx_frame_sz,
+ max_rx_frame_sz);
+
+ /* set stats counter */
+ val = nlm_read_nae_reg(nae_base, XAUI_NETIOR_XGMAC_CTRL1(nblock));
+ val |= (0x1 << NETIOR_XGMAC_VLAN_DC_POS);
+ val |= (0x1 << NETIOR_XGMAC_STATS_EN_POS);
+ if (vlan_pri_en) {
+ val |= (0x1 << NETIOR_XGMAC_TX_PFC_EN_POS);
+ val |= (0x1 << NETIOR_XGMAC_RX_PFC_EN_POS);
+ val |= (0x1 << NETIOR_XGMAC_TX_PAUSE_POS);
+ } else {
+ val &= ~(0x1 << NETIOR_XGMAC_TX_PFC_EN_POS);
+ val |= (0x1 << NETIOR_XGMAC_TX_PAUSE_POS);
+ }
+ nlm_write_nae_reg(nae_base, XAUI_NETIOR_XGMAC_CTRL1(nblock), val);
+ /* configure on / off timer */
+ if (vlan_pri_en)
+ val = 0xF1230000; /* PFC mode, offtimer = 0xf123, ontimer = 0 */
+ else
+ val = 0x0000F123; /* link level FC mode, offtimer = 0xf123 */
+ nlm_write_nae_reg(nae_base, XAUI_NETIOR_XGMAC_CTRL2(nblock), val);
+
+ /* set xaui tx threshold */
+ val = nlm_read_nae_reg(nae_base, XAUI_NETIOR_XGMAC_CTRL3(nblock));
+ val &= ~(0x1f << 10);
+ val |= ~(15 << 10);
+ nlm_write_nae_reg(nae_base, XAUI_NETIOR_XGMAC_CTRL3(nblock), val);
+}
diff --git a/sys/mips/nlm/dev/net/xlpge.c b/sys/mips/nlm/dev/net/xlpge.c
new file mode 100644
index 0000000..3af802e
--- /dev/null
+++ b/sys/mips/nlm/dev/net/xlpge.c
@@ -0,0 +1,1574 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * 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 BROADCOM ``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 BROADCOM 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/endian.h>
+#include <sys/systm.h>
+#include <sys/sockio.h>
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/limits.h>
+#include <sys/bus.h>
+#include <sys/mbuf.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/socket.h>
+#define __RMAN_RESOURCE_VISIBLE
+#include <sys/rman.h>
+#include <sys/taskqueue.h>
+
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/ethernet.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/bpf.h>
+#include <net/if_types.h>
+#include <net/if_vlan_var.h>
+
+#include <dev/pci/pcivar.h>
+
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/uma.h>
+
+#include <machine/reg.h>
+#include <machine/cpu.h>
+#include <machine/mips_opcode.h>
+#include <machine/asm.h>
+#include <machine/cpuregs.h>
+
+#include <machine/param.h>
+#include <machine/intr_machdep.h>
+#include <machine/clock.h> /* for DELAY */
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <mips/nlm/hal/haldefs.h>
+#include <mips/nlm/hal/iomap.h>
+#include <mips/nlm/hal/mips-extns.h>
+#include <mips/nlm/hal/cop2.h>
+#include <mips/nlm/hal/fmn.h>
+#include <mips/nlm/hal/sys.h>
+#include <mips/nlm/hal/nae.h>
+#include <mips/nlm/hal/mdio.h>
+#include <mips/nlm/hal/sgmii.h>
+#include <mips/nlm/hal/xaui.h>
+#include <mips/nlm/hal/poe.h>
+#include <ucore_app_bin.h>
+#include <mips/nlm/hal/ucore_loader.h>
+#include <mips/nlm/xlp.h>
+#include <mips/nlm/board.h>
+#include <mips/nlm/msgring.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+#include "miidevs.h"
+#include <dev/mii/brgphyreg.h>
+#include "miibus_if.h"
+#include <sys/sysctl.h>
+
+#include <mips/nlm/dev/net/xlpge.h>
+
+/*#define XLP_DRIVER_LOOPBACK*/
+
+static struct nae_port_config nae_port_config[64];
+
+int poe_cl_tbl[MAX_POE_CLASSES] = {
+ 0x0, 0x249249,
+ 0x492492, 0x6db6db,
+ 0x924924, 0xb6db6d,
+ 0xdb6db6, 0xffffff
+};
+
+/* #define DUMP_PACKET */
+
+static uint64_t
+nlm_paddr_ld(uint64_t paddr)
+{
+ uint64_t xkaddr = 0x9800000000000000 | paddr;
+
+ return (nlm_load_dword_daddr(xkaddr));
+}
+
+struct nlm_xlp_portdata ifp_ports[64];
+static uma_zone_t nl_tx_desc_zone;
+
+/* This implementation will register the following tree of device
+ * registration:
+ * pcibus
+ * |
+ * xlpnae (1 instance - virtual entity)
+ * |
+ * xlpge
+ * (18 sgmii / 4 xaui / 2 interlaken instances)
+ * |
+ * miibus
+ */
+
+static int nlm_xlpnae_probe(device_t);
+static int nlm_xlpnae_attach(device_t);
+static int nlm_xlpnae_detach(device_t);
+static int nlm_xlpnae_suspend(device_t);
+static int nlm_xlpnae_resume(device_t);
+static int nlm_xlpnae_shutdown(device_t);
+
+static device_method_t nlm_xlpnae_methods[] = {
+ /* Methods from the device interface */
+ DEVMETHOD(device_probe, nlm_xlpnae_probe),
+ DEVMETHOD(device_attach, nlm_xlpnae_attach),
+ DEVMETHOD(device_detach, nlm_xlpnae_detach),
+ DEVMETHOD(device_suspend, nlm_xlpnae_suspend),
+ DEVMETHOD(device_resume, nlm_xlpnae_resume),
+ DEVMETHOD(device_shutdown, nlm_xlpnae_shutdown),
+
+ DEVMETHOD(bus_driver_added, bus_generic_driver_added),
+
+ DEVMETHOD_END
+};
+
+static driver_t nlm_xlpnae_driver = {
+ "xlpnae",
+ nlm_xlpnae_methods,
+ sizeof(struct nlm_xlpnae_softc)
+};
+
+static devclass_t nlm_xlpnae_devclass;
+
+static int nlm_xlpge_probe(device_t);
+static int nlm_xlpge_attach(device_t);
+static int nlm_xlpge_detach(device_t);
+static int nlm_xlpge_suspend(device_t);
+static int nlm_xlpge_resume(device_t);
+static int nlm_xlpge_shutdown(device_t);
+
+/* mii override functions */
+static int nlm_xlpge_mii_read(struct device *, int, int);
+static int nlm_xlpge_mii_write(struct device *, int, int, int);
+static void nlm_xlpge_mii_statchg(device_t);
+
+static device_method_t nlm_xlpge_methods[] = {
+ /* Methods from the device interface */
+ DEVMETHOD(device_probe, nlm_xlpge_probe),
+ DEVMETHOD(device_attach, nlm_xlpge_attach),
+ DEVMETHOD(device_detach, nlm_xlpge_detach),
+ DEVMETHOD(device_suspend, nlm_xlpge_suspend),
+ DEVMETHOD(device_resume, nlm_xlpge_resume),
+ DEVMETHOD(device_shutdown, nlm_xlpge_shutdown),
+
+ /* Methods from the nexus bus needed for explicitly
+ * probing children when driver is loaded as a kernel module
+ */
+ DEVMETHOD(miibus_readreg, nlm_xlpge_mii_read),
+ DEVMETHOD(miibus_writereg, nlm_xlpge_mii_write),
+ DEVMETHOD(miibus_statchg, nlm_xlpge_mii_statchg),
+
+ /* Terminate method list */
+ DEVMETHOD_END
+};
+
+static driver_t nlm_xlpge_driver = {
+ "xlpge",
+ nlm_xlpge_methods,
+ sizeof(struct nlm_xlpge_softc)
+};
+
+static devclass_t nlm_xlpge_devclass;
+
+DRIVER_MODULE(xlpnae, pci, nlm_xlpnae_driver, nlm_xlpnae_devclass, 0, 0);
+DRIVER_MODULE(xlpge, xlpnae, nlm_xlpge_driver, nlm_xlpge_devclass, 0, 0);
+DRIVER_MODULE(miibus, xlpge, miibus_driver, miibus_devclass, 0, 0);
+
+MODULE_DEPEND(pci, xlpnae, 1, 1, 1);
+MODULE_DEPEND(xlpnae, xlpge, 1, 1, 1);
+MODULE_DEPEND(xlpge, ether, 1, 1, 1);
+MODULE_DEPEND(xlpge, miibus, 1, 1, 1);
+
+#define SGMII_RCV_CONTEXT_WIDTH 8
+
+/* prototypes */
+static void nlm_xlpge_msgring_handler(int vc, int size,
+ int code, int srcid, struct nlm_fmn_msg *msg, void *data);
+static void nlm_xlpge_submit_rx_free_desc(struct nlm_xlpge_softc *sc, int num);
+static void nlm_xlpge_init(void *addr);
+static void nlm_xlpge_port_disable(struct nlm_xlpge_softc *sc);
+static void nlm_xlpge_port_enable(struct nlm_xlpge_softc *sc);
+
+/* globals */
+int dbg_on = 1;
+int cntx2port[524];
+
+static __inline void
+atomic_incr_long(unsigned long *addr)
+{
+ atomic_add_long(addr, 1);
+}
+
+/*
+ * xlpnae driver implementation
+ */
+static int
+nlm_xlpnae_probe(device_t dev)
+{
+ if (pci_get_vendor(dev) != PCI_VENDOR_NETLOGIC ||
+ pci_get_device(dev) != PCI_DEVICE_ID_NLM_NAE)
+ return (ENXIO);
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static void
+nlm_xlpnae_print_frin_desc_carving(struct nlm_xlpnae_softc *sc)
+{
+ int intf;
+ uint32_t value;
+ int start, size;
+
+ /* XXXJC: use max_ports instead of 20 ? */
+ for (intf = 0; intf < 20; intf++) {
+ nlm_write_nae_reg(sc->base, NAE_FREE_IN_FIFO_CFG,
+ (0x80000000 | intf));
+ value = nlm_read_nae_reg(sc->base, NAE_FREE_IN_FIFO_CFG);
+ size = 2 * ((value >> 20) & 0x3ff);
+ start = 2 * ((value >> 8) & 0x1ff);
+ }
+}
+
+static void
+nlm_config_egress(struct nlm_xlpnae_softc *sc, int nblock,
+ int context_base, int hwport, int max_channels)
+{
+ int offset, num_channels;
+ uint32_t data;
+
+ num_channels = sc->portcfg[hwport].num_channels;
+
+ data = (2048 << 12) | (hwport << 4) | 1;
+ nlm_write_nae_reg(sc->base, NAE_TX_IF_BURSTMAX_CMD, data);
+
+ data = ((context_base + num_channels - 1) << 22) |
+ (context_base << 12) | (hwport << 4) | 1;
+ nlm_write_nae_reg(sc->base, NAE_TX_DDR_ACTVLIST_CMD, data);
+
+ config_egress_fifo_carvings(sc->base, hwport,
+ context_base, num_channels, max_channels, sc->portcfg);
+ config_egress_fifo_credits(sc->base, hwport,
+ context_base, num_channels, max_channels, sc->portcfg);
+
+ data = nlm_read_nae_reg(sc->base, NAE_DMA_TX_CREDIT_TH);
+ data |= (1 << 25) | (1 << 24);
+ nlm_write_nae_reg(sc->base, NAE_DMA_TX_CREDIT_TH, data);
+
+ for (offset = 0; offset < num_channels; offset++) {
+ nlm_write_nae_reg(sc->base, NAE_TX_SCHED_MAP_CMD1,
+ NAE_DRR_QUANTA);
+ data = (hwport << 15) | ((context_base + offset) << 5);
+ if (sc->cmplx_type[nblock] == ILC)
+ data |= (offset << 20);
+ nlm_write_nae_reg(sc->base, NAE_TX_SCHED_MAP_CMD0, data | 1);
+ nlm_write_nae_reg(sc->base, NAE_TX_SCHED_MAP_CMD0, data);
+ }
+}
+
+static int
+xlpnae_get_maxchannels(struct nlm_xlpnae_softc *sc)
+{
+ int maxchans = 0;
+ int i, j, port = 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;
+ 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;
+ }
+ }
+ }
+
+ return (maxchans);
+}
+
+static void
+nlm_setup_interface(struct nlm_xlpnae_softc *sc, int nblock,
+ int port, uint32_t cur_flow_base, uint32_t flow_mask,
+ int max_channels, int context)
+{
+ uint64_t nae_base = sc->base;
+ int mtu = 1536; /* XXXJC: don't hard code */
+ uint32_t ucore_mask;
+
+ if (sc->cmplx_type[nblock] == XAUIC)
+ nlm_config_xaui(nae_base, nblock, mtu,
+ mtu, sc->portcfg[port].vlan_pri_en);
+ nlm_config_freein_fifo_uniq_cfg(nae_base,
+ port, sc->portcfg[port].free_desc_sizes);
+ nlm_config_ucore_iface_mask_cfg(nae_base,
+ port, sc->portcfg[port].ucore_mask);
+
+ nlm_program_flow_cfg(nae_base, port, cur_flow_base, flow_mask);
+
+ if (sc->cmplx_type[nblock] == SGMIIC)
+ nlm_configure_sgmii_interface(nae_base, nblock, port, mtu, 0);
+
+ nlm_config_egress(sc, nblock, context, port, max_channels);
+
+ nlm_nae_init_netior(nae_base, sc->nblocks);
+ nlm_nae_open_if(nae_base, nblock, sc->cmplx_type[nblock], port,
+ sc->portcfg[port].free_desc_sizes);
+
+ /* XXXJC: check mask calculation */
+ ucore_mask = (1 << sc->nucores) - 1;
+ nlm_nae_init_ucore(nae_base, port, ucore_mask);
+}
+
+static void
+nlm_setup_interfaces(struct nlm_xlpnae_softc *sc)
+{
+ uint64_t nae_base;
+ uint32_t cur_slot, cur_slot_base;
+ uint32_t cur_flow_base, port, flow_mask;
+ int max_channels;
+ int i, j, context;
+
+ cur_slot = 0;
+ cur_slot_base = 0;
+ cur_flow_base = 0;
+ nae_base = sc->base;
+ flow_mask = nlm_get_flow_mask(sc->total_num_ports);
+ /* calculate max_channels */
+ max_channels = xlpnae_get_maxchannels(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++;
+ }
+}
+
+static void
+nlm_xlpnae_init(int node, struct nlm_xlpnae_softc *sc)
+{
+ uint64_t nae_base;
+ uint32_t ucoremask = 0;
+ uint32_t val;
+ int i;
+
+ nae_base = sc->base;
+
+ nlm_nae_flush_free_fifo(nae_base, sc->nblocks);
+ nlm_deflate_frin_fifo_carving(nae_base, sc->max_ports);
+ nlm_reset_nae(node);
+
+ for (i = 0; i < sc->nucores; i++) /* XXXJC: code repeated below */
+ ucoremask |= (0x1 << i);
+ printf("Loading 0x%x ucores with microcode\n", ucoremask);
+ nlm_ucore_load_all(nae_base, ucoremask, 1);
+
+ val = nlm_set_device_frequency(node, DFS_DEVICE_NAE, sc->freq);
+ printf("Setup NAE frequency to %dMHz\n", val);
+
+ printf("Initialze SGMII PCS for blocks 0x%x\n", sc->sgmiimask);
+ nlm_sgmii_pcs_init(nae_base, sc->sgmiimask);
+
+ printf("Initialze XAUI PCS for blocks 0x%x\n", sc->xauimask);
+ nlm_xaui_pcs_init(nae_base, sc->xauimask);
+
+ /* clear NETIOR soft reset */
+ nlm_write_nae_reg(nae_base, NAE_LANE_CFG_SOFTRESET, 0x0);
+
+ /* Disable RX enable bit in RX_CONFIG */
+ val = nlm_read_nae_reg(nae_base, NAE_RX_CONFIG);
+ val &= 0xfffffffe;
+ nlm_write_nae_reg(nae_base, NAE_RX_CONFIG, val);
+
+ if (nlm_is_xlp8xx_ax() == 0) {
+ val = nlm_read_nae_reg(nae_base, NAE_TX_CONFIG);
+ val &= ~(1 << 3);
+ nlm_write_nae_reg(nae_base, NAE_TX_CONFIG, val);
+ }
+
+ nlm_setup_poe_class_config(nae_base, MAX_POE_CLASSES,
+ sc->ncontexts, poe_cl_tbl);
+
+ nlm_setup_vfbid_mapping(nae_base);
+
+ nlm_setup_flow_crc_poly(nae_base, sc->flow_crc_poly);
+
+ nlm_setup_rx_cal_cfg(nae_base, sc->max_ports, sc->portcfg);
+ /* note: xlp8xx Ax does not have Tx Calendering */
+ if (!nlm_is_xlp8xx_ax())
+ nlm_setup_tx_cal_cfg(nae_base, sc->max_ports, sc->portcfg);
+
+ 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);
+
+ if (sc->prepad_en)
+ nlm_prepad_enable(nae_base, sc->prepad_size);
+
+ if (sc->ieee_1588_en)
+ nlm_setup_1588_timer(sc->base, sc->portcfg);
+}
+
+static void
+nlm_xlpnae_update_pde(void *dummy __unused)
+{
+ struct nlm_xlpnae_softc *sc;
+ uint32_t dv[NUM_WORDS_PER_DV];
+ device_t dev;
+ int vec;
+
+ dev = devclass_get_device(devclass_find("xlpnae"), 0);
+ sc = device_get_softc(dev);
+
+ nlm_write_poe_reg(sc->poe_base, POE_DISTR_EN, 0);
+ for (vec = 0; vec < NUM_DIST_VEC; vec++) {
+ if (nlm_get_poe_distvec(vec, dv) != 0)
+ continue;
+
+ nlm_write_poe_distvec(sc->poedv_base, vec, dv);
+ }
+ nlm_write_poe_reg(sc->poe_base, POE_DISTR_EN, 1);
+}
+
+SYSINIT(nlm_xlpnae_update_pde, SI_SUB_SMP, SI_ORDER_ANY,
+ nlm_xlpnae_update_pde, NULL);
+
+/* configuration common for sgmii, xaui, ilaken goes here */
+static void
+nlm_setup_portcfg(struct nlm_xlpnae_softc *sc, struct xlp_nae_ivars *naep,
+ int block, int port)
+{
+ int i;
+ uint32_t ucore_mask = 0;
+ struct xlp_block_ivars *bp;
+ struct xlp_port_ivars *p;
+
+ bp = &(naep->block_ivars[block]);
+ p = &(bp->port_ivars[port & 0x3]);
+
+ sc->portcfg[port].loopback_mode = p->loopback_mode;
+ sc->portcfg[port].num_channels = p->num_channels;
+ if (p->free_desc_sizes != MCLBYTES) {
+ printf("[%d, %d] Error: free_desc_sizes %d != %d\n",
+ block, port, p->free_desc_sizes, MCLBYTES);
+ return;
+ }
+ sc->portcfg[port].free_desc_sizes = p->free_desc_sizes;
+ for (i = 0; i < sc->nucores; i++) /* XXXJC: configure this */
+ ucore_mask |= (0x1 << i);
+ sc->portcfg[port].ucore_mask = ucore_mask;
+ sc->portcfg[port].vlan_pri_en = p->vlan_pri_en;
+ sc->portcfg[port].num_free_descs = p->num_free_descs;
+ sc->portcfg[port].iface_fifo_size = p->iface_fifo_size;
+ sc->portcfg[port].rxbuf_size = p->rxbuf_size;
+ sc->portcfg[port].rx_slots_reqd = p->rx_slots_reqd;
+ sc->portcfg[port].tx_slots_reqd = p->tx_slots_reqd;
+ sc->portcfg[port].pseq_fifo_size = p->pseq_fifo_size;
+
+ sc->portcfg[port].stg2_fifo_size = p->stg2_fifo_size;
+ sc->portcfg[port].eh_fifo_size = p->eh_fifo_size;
+ sc->portcfg[port].frout_fifo_size = p->frout_fifo_size;
+ sc->portcfg[port].ms_fifo_size = p->ms_fifo_size;
+ sc->portcfg[port].pkt_fifo_size = p->pkt_fifo_size;
+ sc->portcfg[port].pktlen_fifo_size = p->pktlen_fifo_size;
+ sc->portcfg[port].max_stg2_offset = p->max_stg2_offset;
+ sc->portcfg[port].max_eh_offset = p->max_eh_offset;
+ sc->portcfg[port].max_frout_offset = p->max_frout_offset;
+ sc->portcfg[port].max_ms_offset = p->max_ms_offset;
+ sc->portcfg[port].max_pmem_offset = p->max_pmem_offset;
+ sc->portcfg[port].stg1_2_credit = p->stg1_2_credit;
+ sc->portcfg[port].stg2_eh_credit = p->stg2_eh_credit;
+ sc->portcfg[port].stg2_frout_credit = p->stg2_frout_credit;
+ sc->portcfg[port].stg2_ms_credit = p->stg2_ms_credit;
+ sc->portcfg[port].ieee1588_inc_intg = p->ieee1588_inc_intg;
+ sc->portcfg[port].ieee1588_inc_den = p->ieee1588_inc_den;
+ sc->portcfg[port].ieee1588_inc_num = p->ieee1588_inc_num;
+ sc->portcfg[port].ieee1588_userval = p->ieee1588_userval;
+ sc->portcfg[port].ieee1588_ptpoff = p->ieee1588_ptpoff;
+ sc->portcfg[port].ieee1588_tmr1 = p->ieee1588_tmr1;
+ sc->portcfg[port].ieee1588_tmr2 = p->ieee1588_tmr2;
+ sc->portcfg[port].ieee1588_tmr3 = p->ieee1588_tmr3;
+
+ sc->total_free_desc += sc->portcfg[port].free_desc_sizes;
+ sc->total_num_ports++;
+}
+
+static int
+nlm_xlpnae_attach(device_t dev)
+{
+ struct xlp_nae_ivars *nae_ivars;
+ 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 offset, context, txq_base, rxvcbase;
+ uint64_t poe_pcibase, nae_pcibase;
+
+ node = pci_get_slot(dev) / 8;
+ nae_ivars = &xlp_board_info.nodes[node].nae_ivars;
+
+ sc = device_get_softc(dev);
+ sc->xlpnae_dev = dev;
+ sc->node = nae_ivars->node;
+ sc->base = nlm_get_nae_regbase(sc->node);
+ sc->poe_base = nlm_get_poe_regbase(sc->node);
+ sc->poedv_base = nlm_get_poedv_regbase(sc->node);
+ sc->portcfg = nae_port_config;
+ sc->xauimask = nae_ivars->xauimask;
+ sc->sgmiimask = nae_ivars->sgmiimask;
+ sc->nblocks = nae_ivars->nblocks;
+ sc->freq = nae_ivars->freq;
+
+ /* flow table generation is done by CRC16 polynomial */
+ sc->flow_crc_poly = nae_ivars->flow_crc_poly;
+
+ sc->hw_parser_en = nae_ivars->hw_parser_en;
+ sc->prepad_en = nae_ivars->prepad_en;
+ sc->prepad_size = nae_ivars->prepad_size;
+ sc->ieee_1588_en = nae_ivars->ieee_1588_en;
+
+ nae_pcibase = nlm_get_nae_pcibase(sc->node);
+ 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++)
+ sc->cmplx_type[nblock] = nae_ivars->block_ivars[nblock].type;
+
+ for (i = 0; i < sc->ncontexts; i++)
+ cntx2port[i] = 18; /* 18 is an invalid port */
+
+ if (sc->nblocks == 5)
+ sc->max_ports = 18; /* 8xx has a block 4 with 2 ports */
+ else
+ sc->max_ports = sc->nblocks * PORTS_PER_CMPLX;
+
+ /*
+ * Now setup all internal fifo carvings based on
+ * total number of ports in the system
+ */
+ sc->total_free_desc = 0;
+ sc->total_num_ports = 0;
+ port = 0;
+ context = 0;
+ 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))
+ continue;
+ nlm_setup_portcfg(sc, nae_ivars, i, port);
+ nchan = sc->portcfg[port].num_channels;
+ for (offset = 0; offset < nchan; offset++)
+ cntx2port[context + offset] = port;
+ sc->portcfg[port].txq = txq_base + context;
+ sc->portcfg[port].rxfreeq = rxvcbase + port;
+ context += nchan;
+ }
+ }
+
+ poe_pcibase = nlm_get_poe_pcibase(sc->node);
+ sc->per_port_num_flows =
+ nlm_poe_max_flows(poe_pcibase) / sc->total_num_ports;
+
+ /* zone for P2P descriptors */
+ nl_tx_desc_zone = uma_zcreate("NL Tx Desc",
+ sizeof(struct xlpge_tx_desc), NULL, NULL, NULL, NULL,
+ NAE_CACHELINE_SIZE, 0);
+
+ /* NAE FMN messages have CMS src station id's in the
+ * range of qstart to qnum.
+ */
+ qstart = nlm_qidstart(nae_pcibase);
+ qnum = nlm_qnum(nae_pcibase);
+ if (register_msgring_handler(qstart, qstart + qnum - 1,
+ nlm_xlpge_msgring_handler, sc)) {
+ panic("Couldn't register NAE msgring handler\n");
+ }
+
+ /* POE FMN messages have CMS src station id's in the
+ * range of qstart to qnum.
+ */
+ qstart = nlm_qidstart(poe_pcibase);
+ qnum = nlm_qnum(poe_pcibase);
+ if (register_msgring_handler(qstart, qstart + qnum - 1,
+ nlm_xlpge_msgring_handler, sc)) {
+ panic("Couldn't register POE msgring handler\n");
+ }
+
+ nlm_xlpnae_init(node, sc);
+
+ for (i = 0; i < sc->nblocks; i++) {
+ char desc[32];
+ struct xlp_block_ivars *bv;
+
+ if ((nae_ivars->blockmask & (1 << i)) == 0)
+ 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);
+ }
+
+ bus_generic_probe(dev);
+ bus_generic_attach(dev);
+
+ /*
+ * Enable only boot cpu at this point, full distribution comes
+ * only after SMP is started
+ */
+ nlm_write_poe_reg(sc->poe_base, POE_DISTR_EN, 0);
+ nlm_calc_poe_distvec(0x1, 0, 0, 0, 0x1 << XLPGE_RX_VC, dv);
+ nlm_write_poe_distvec(sc->poedv_base, 0, dv);
+ nlm_write_poe_reg(sc->poe_base, POE_DISTR_EN, 1);
+
+ return (0);
+}
+
+static int
+nlm_xlpnae_detach(device_t dev)
+{
+ /* TODO - free zone here */
+ return (0);
+}
+
+static int
+nlm_xlpnae_suspend(device_t dev)
+{
+ return (0);
+}
+
+static int
+nlm_xlpnae_resume(device_t dev)
+{
+ return (0);
+}
+
+static int
+nlm_xlpnae_shutdown(device_t dev)
+{
+ return (0);
+}
+
+/*
+ * xlpge driver implementation
+ */
+
+static void
+nlm_xlpge_mac_set_rx_mode(struct nlm_xlpge_softc *sc)
+{
+ if (sc->if_flags & IFF_PROMISC) {
+ if (sc->type == SGMIIC)
+ nlm_nae_setup_rx_mode_sgmii(sc->base_addr,
+ sc->block, sc->port, sc->type, 1 /* broadcast */,
+ 1/* multicast */, 0 /* pause */, 1 /* promisc */);
+ else
+ nlm_nae_setup_rx_mode_xaui(sc->base_addr,
+ sc->block, sc->port, sc->type, 1 /* broadcast */,
+ 1/* multicast */, 0 /* pause */, 1 /* promisc */);
+ } else {
+ if (sc->type == SGMIIC)
+ nlm_nae_setup_rx_mode_sgmii(sc->base_addr,
+ sc->block, sc->port, sc->type, 1 /* broadcast */,
+ 1/* multicast */, 0 /* pause */, 0 /* promisc */);
+ else
+ nlm_nae_setup_rx_mode_xaui(sc->base_addr,
+ sc->block, sc->port, sc->type, 1 /* broadcast */,
+ 1/* multicast */, 0 /* pause */, 0 /* promisc */);
+ }
+}
+
+static int
+nlm_xlpge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
+{
+ struct mii_data *mii;
+ struct nlm_xlpge_softc *sc;
+ struct ifreq *ifr;
+ int error;
+
+ sc = ifp->if_softc;
+ error = 0;
+ ifr = (struct ifreq *)data;
+
+ switch (command) {
+ case SIOCSIFFLAGS:
+ XLPGE_LOCK(sc);
+ sc->if_flags = ifp->if_flags;
+ if (ifp->if_flags & IFF_UP) {
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ nlm_xlpge_init(sc);
+ nlm_xlpge_mac_set_rx_mode(sc);
+ nlm_xlpge_port_enable(sc);
+ sc->link = NLM_LINK_UP;
+ } else {
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ nlm_xlpge_port_disable(sc);
+ sc->link = NLM_LINK_DOWN;
+ }
+ XLPGE_UNLOCK(sc);
+ error = 0;
+ break;
+ case SIOCGIFMEDIA:
+ case SIOCSIFMEDIA:
+ if (sc->mii_bus != NULL) {
+ mii = device_get_softc(sc->mii_bus);
+ error = ifmedia_ioctl(ifp, ifr, &mii->mii_media,
+ command);
+ }
+ break;
+ default:
+ error = ether_ioctl(ifp, command, data);
+ break;
+ }
+
+ return (error);
+}
+
+static int
+xlpge_tx(struct ifnet *ifp, struct mbuf *mbuf_chain)
+{
+ struct nlm_fmn_msg msg;
+ struct xlpge_tx_desc *p2p;
+ struct nlm_xlpge_softc *sc;
+ struct mbuf *m;
+ vm_paddr_t paddr;
+ int fbid, dst, pos, err;
+ int ret = 0, tx_msgstatus, retries;
+
+ err = 0;
+ if (mbuf_chain == NULL)
+ return (0);
+
+ sc = ifp->if_softc;
+ p2p = NULL;
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING) ||
+ ifp->if_drv_flags & IFF_DRV_OACTIVE) {
+ err = ENXIO;
+ goto fail;
+ }
+
+ /* free a few in coming messages on the fb vc */
+ xlp_handle_msg_vc(1 << XLPGE_FB_VC, 2);
+
+ /* vfb id table is setup to map cpu to vc 3 of the cpu */
+ fbid = nlm_cpuid();
+ dst = sc->txq;
+
+ pos = 0;
+ p2p = uma_zalloc(nl_tx_desc_zone, M_NOWAIT);
+ if (p2p == NULL) {
+ printf("alloc fail\n");
+ err = ENOBUFS;
+ goto fail;
+ }
+
+ for (m = mbuf_chain; m != NULL; m = m->m_next) {
+ vm_offset_t buf = (vm_offset_t) m->m_data;
+ int len = m->m_len;
+ int frag_sz;
+
+ /*printf("m_data = %p len %d\n", m->m_data, len); */
+ while (len) {
+ if (pos == XLP_NTXFRAGS - 3) {
+ device_printf(sc->xlpge_dev,
+ "packet defrag %d\n",
+ m_length(mbuf_chain, NULL));
+ err = ENOBUFS; /* TODO fix error */
+ goto fail;
+ }
+ paddr = vtophys(buf);
+ frag_sz = PAGE_SIZE - (buf & PAGE_MASK);
+ if (len < frag_sz)
+ frag_sz = len;
+ p2p->frag[pos] = nae_tx_desc(P2D_NEOP, 0, 127,
+ frag_sz, paddr);
+ pos++;
+ len -= frag_sz;
+ buf += frag_sz;
+ }
+ }
+
+ KASSERT(pos != 0, ("Zero-length mbuf chain?\n"));
+
+ /* Make the last one P2D EOP */
+ p2p->frag[pos-1] |= (uint64_t)P2D_EOP << 62;
+
+ /* stash useful pointers in the desc */
+ p2p->frag[XLP_NTXFRAGS-3] = 0xf00bad;
+ p2p->frag[XLP_NTXFRAGS-2] = (uintptr_t)p2p;
+ p2p->frag[XLP_NTXFRAGS-1] = (uintptr_t)mbuf_chain;
+
+ paddr = vtophys(p2p);
+ msg.msg[0] = nae_tx_desc(P2P, 0, fbid, pos, paddr);
+
+ for (retries = 16; retries > 0; retries--) {
+ ret = nlm_fmn_msgsend(dst, 1, FMN_SWCODE_NAE, &msg);
+ if (ret == 0)
+ return (0);
+ }
+
+fail:
+ if (ret != 0) {
+ tx_msgstatus = nlm_read_c2_txmsgstatus();
+ if ((tx_msgstatus >> 24) & 0x1)
+ device_printf(sc->xlpge_dev, "Transmit queue full - ");
+ if ((tx_msgstatus >> 3) & 0x1)
+ device_printf(sc->xlpge_dev, "ECC error - ");
+ if ((tx_msgstatus >> 2) & 0x1)
+ device_printf(sc->xlpge_dev, "Pending Sync - ");
+ if ((tx_msgstatus >> 1) & 0x1)
+ device_printf(sc->xlpge_dev,
+ "Insufficient input queue credits - ");
+ if (tx_msgstatus & 0x1)
+ device_printf(sc->xlpge_dev,
+ "Insufficient output queue credits - ");
+ }
+ device_printf(sc->xlpge_dev, "Send failed! err = %d\n", err);
+ if (p2p)
+ uma_zfree(nl_tx_desc_zone, p2p);
+ m_freem(mbuf_chain);
+ /*atomic_incr_long(&ifp->if_iqdrops); */
+ ifp->if_iqdrops++;
+ return (err);
+}
+
+
+static int
+nlm_xlpge_gmac_config_speed(struct nlm_xlpge_softc *sc)
+{
+ struct mii_data *mii;
+
+ if (sc->type == XAUIC || sc->type == ILC)
+ return (0);
+
+ if (sc->mii_bus) {
+ mii = device_get_softc(sc->mii_bus);
+ mii_pollstat(mii);
+ }
+
+ return (0);
+}
+
+static void
+nlm_xlpge_port_disable(struct nlm_xlpge_softc *sc)
+{
+ struct ifnet *ifp;
+
+ ifp = sc->xlpge_if;
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+
+ callout_stop(&sc->xlpge_callout);
+ nlm_mac_disable(sc->base_addr, sc->block, sc->type, sc->port);
+}
+
+static void
+nlm_mii_pollstat(void *arg)
+{
+ struct nlm_xlpge_softc *sc = (struct nlm_xlpge_softc *)arg;
+ struct mii_data *mii = NULL;
+
+ if (sc->mii_bus) {
+ mii = device_get_softc(sc->mii_bus);
+
+ KASSERT(mii == NULL, ("mii ptr is NULL"));
+
+ mii_pollstat(mii);
+
+ callout_reset(&sc->xlpge_callout, hz,
+ nlm_mii_pollstat, sc);
+ }
+}
+
+static void
+nlm_xlpge_port_enable(struct nlm_xlpge_softc *sc)
+{
+ if ((sc->type != SGMIIC) && (sc->type != XAUIC))
+ return;
+ nlm_mac_enable(sc->base_addr, sc->block, sc->type, sc->port);
+ nlm_mii_pollstat((void *)sc);
+}
+
+static void
+nlm_xlpge_init(void *addr)
+{
+ struct nlm_xlpge_softc *sc;
+ struct ifnet *ifp;
+ struct mii_data *mii = NULL;
+
+ sc = (struct nlm_xlpge_softc *)addr;
+ ifp = sc->xlpge_if;
+
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ return;
+
+ if (sc->mii_bus) {
+ mii = device_get_softc(sc->mii_bus);
+ mii_mediachg(mii);
+ }
+
+ nlm_xlpge_gmac_config_speed(sc);
+ ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ nlm_xlpge_port_enable(sc);
+
+ /* start the callout */
+ callout_reset(&sc->xlpge_callout, hz, nlm_mii_pollstat, sc);
+}
+
+/*
+ * Read the MAC address from FDT or board eeprom.
+ */
+static void
+xlpge_read_mac_addr(struct nlm_xlpge_softc *sc)
+{
+
+ xlpge_get_macaddr(sc->dev_addr);
+ /* last octet is port specific */
+ sc->dev_addr[5] += (sc->block * 4) + sc->port;
+
+ if (sc->type == SGMIIC)
+ nlm_nae_setup_mac_addr_sgmii(sc->base_addr, sc->block,
+ sc->port, sc->type, sc->dev_addr);
+ else if (sc->type == XAUIC)
+ nlm_nae_setup_mac_addr_xaui(sc->base_addr, sc->block,
+ sc->port, sc->type, sc->dev_addr);
+}
+
+
+static int
+xlpge_mediachange(struct ifnet *ifp)
+{
+ return (0);
+}
+
+static void
+xlpge_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+ struct nlm_xlpge_softc *sc;
+ struct mii_data *md;
+
+ md = NULL;
+ sc = ifp->if_softc;
+
+ if (sc->mii_bus)
+ md = device_get_softc(sc->mii_bus);
+
+ ifmr->ifm_status = IFM_AVALID;
+ ifmr->ifm_active = IFM_ETHER;
+
+ if (sc->link == NLM_LINK_DOWN)
+ return;
+
+ if (md != NULL)
+ ifmr->ifm_active = md->mii_media.ifm_cur->ifm_media;
+ ifmr->ifm_status |= IFM_ACTIVE;
+}
+
+static int
+nlm_xlpge_ifinit(struct nlm_xlpge_softc *sc)
+{
+ struct ifnet *ifp;
+ device_t dev;
+ int port = sc->block * 4 + sc->port;
+
+ dev = sc->xlpge_dev;
+ ifp = sc->xlpge_if = if_alloc(IFT_ETHER);
+ /*(sc->network_sc)->ifp_ports[port].xlpge_if = ifp;*/
+ ifp_ports[port].xlpge_if = ifp;
+
+ if (ifp == NULL) {
+ device_printf(dev, "cannot if_alloc()\n");
+ return (ENOSPC);
+ }
+ ifp->if_softc = sc;
+ if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ sc->if_flags = ifp->if_flags;
+ /*ifp->if_capabilities = IFCAP_TXCSUM | IFCAP_VLAN_HWTAGGING;*/
+ ifp->if_capabilities = 0;
+ ifp->if_capenable = ifp->if_capabilities;
+ ifp->if_ioctl = nlm_xlpge_ioctl;
+ ifp->if_init = nlm_xlpge_init ;
+ ifp->if_hwassist = 0;
+ ifp->if_snd.ifq_drv_maxlen = NLM_XLPGE_TXQ_SIZE; /* TODO: make this a sysint */
+ IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
+ IFQ_SET_READY(&ifp->if_snd);
+
+ ifmedia_init(&sc->xlpge_mii.mii_media, 0, xlpge_mediachange,
+ xlpge_mediastatus);
+ ifmedia_add(&sc->xlpge_mii.mii_media, IFM_ETHER | IFM_AUTO, 0, NULL);
+ ifmedia_set(&sc->xlpge_mii.mii_media, IFM_ETHER | IFM_AUTO);
+ sc->xlpge_mii.mii_media.ifm_media =
+ sc->xlpge_mii.mii_media.ifm_cur->ifm_media;
+ xlpge_read_mac_addr(sc);
+
+ ether_ifattach(ifp, sc->dev_addr);
+
+ /* override if_transmit : per ifnet(9), do it after if_attach */
+ ifp->if_transmit = xlpge_tx;
+
+ return (0);
+}
+
+static int
+nlm_xlpge_probe(device_t dev)
+{
+ return (BUS_PROBE_DEFAULT);
+}
+
+static void *
+get_buf(void)
+{
+ struct mbuf *m_new;
+ uint64_t *md;
+#ifdef INVARIANTS
+ vm_paddr_t temp1, temp2;
+#endif
+
+ if ((m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR)) == NULL)
+ return (NULL);
+ m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
+ m_adj(m_new, NAE_CACHELINE_SIZE - ((uintptr_t)m_new->m_data & 0x1f));
+ md = (uint64_t *)m_new->m_data;
+ md[0] = (intptr_t)m_new; /* Back Ptr */
+ md[1] = 0xf00bad;
+ m_adj(m_new, NAE_CACHELINE_SIZE);
+
+#ifdef INVARIANTS
+ temp1 = vtophys((vm_offset_t) m_new->m_data);
+ temp2 = vtophys((vm_offset_t) m_new->m_data + 1536);
+ KASSERT(temp1 + 1536) != temp2,
+ ("Alloced buffer is not contiguous"));
+#endif
+
+ return ((void *)m_new->m_data);
+}
+
+static void
+nlm_xlpge_mii_init(device_t dev, struct nlm_xlpge_softc *sc)
+{
+ int error;
+
+ error = mii_attach(dev, &sc->mii_bus, sc->xlpge_if,
+ xlpge_mediachange, xlpge_mediastatus,
+ BMSR_DEFCAPMASK, sc->phy_addr, MII_OFFSET_ANY, 0);
+
+ if (error) {
+ device_printf(dev, "attaching PHYs failed\n");
+ sc->mii_bus = NULL;
+ }
+
+ if (sc->mii_bus != NULL) {
+ /* enable MDIO interrupts in the PHY */
+ /* XXXJC: TODO */
+ }
+}
+
+static int
+xlpge_stats_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ struct nlm_xlpge_softc *sc;
+ uint32_t val;
+ int reg, field;
+
+ sc = arg1;
+ field = arg2;
+ reg = SGMII_STATS_MLR(sc->block, sc->port) + field;
+ val = nlm_read_nae_reg(sc->base_addr, reg);
+ return (sysctl_handle_int(oidp, &val, 0, req));
+}
+
+static void
+nlm_xlpge_setup_stats_sysctl(device_t dev, struct nlm_xlpge_softc *sc)
+{
+ struct sysctl_ctx_list *ctx;
+ struct sysctl_oid_list *child;
+ struct sysctl_oid *tree;
+
+ ctx = device_get_sysctl_ctx(dev);
+ tree = device_get_sysctl_tree(dev);
+ child = SYSCTL_CHILDREN(tree);
+
+#define XLPGE_STAT(name, offset, desc) \
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, name, \
+ CTLTYPE_UINT | CTLFLAG_RD, sc, offset, \
+ xlpge_stats_sysctl, "IU", desc)
+
+ XLPGE_STAT("tr127", nlm_sgmii_stats_tr127, "TxRx 64 - 127 Bytes");
+ XLPGE_STAT("tr255", nlm_sgmii_stats_tr255, "TxRx 128 - 255 Bytes");
+ XLPGE_STAT("tr511", nlm_sgmii_stats_tr511, "TxRx 256 - 511 Bytes");
+ XLPGE_STAT("tr1k", nlm_sgmii_stats_tr1k, "TxRx 512 - 1023 Bytes");
+ XLPGE_STAT("trmax", nlm_sgmii_stats_trmax, "TxRx 1024 - 1518 Bytes");
+ XLPGE_STAT("trmgv", nlm_sgmii_stats_trmgv, "TxRx 1519 - 1522 Bytes");
+
+ XLPGE_STAT("rbyt", nlm_sgmii_stats_rbyt, "Rx Bytes");
+ XLPGE_STAT("rpkt", nlm_sgmii_stats_rpkt, "Rx Packets");
+ XLPGE_STAT("rfcs", nlm_sgmii_stats_rfcs, "Rx FCS Error");
+ XLPGE_STAT("rmca", nlm_sgmii_stats_rmca, "Rx Multicast Packets");
+ XLPGE_STAT("rbca", nlm_sgmii_stats_rbca, "Rx Broadcast Packets");
+ XLPGE_STAT("rxcf", nlm_sgmii_stats_rxcf, "Rx Control Frames");
+ XLPGE_STAT("rxpf", nlm_sgmii_stats_rxpf, "Rx Pause Frames");
+ XLPGE_STAT("rxuo", nlm_sgmii_stats_rxuo, "Rx Unknown Opcode");
+ XLPGE_STAT("raln", nlm_sgmii_stats_raln, "Rx Alignment Errors");
+ XLPGE_STAT("rflr", nlm_sgmii_stats_rflr, "Rx Framelength Errors");
+ XLPGE_STAT("rcde", nlm_sgmii_stats_rcde, "Rx Code Errors");
+ XLPGE_STAT("rcse", nlm_sgmii_stats_rcse, "Rx Carrier Sense Errors");
+ XLPGE_STAT("rund", nlm_sgmii_stats_rund, "Rx Undersize Packet Errors");
+ XLPGE_STAT("rovr", nlm_sgmii_stats_rovr, "Rx Oversize Packet Errors");
+ XLPGE_STAT("rfrg", nlm_sgmii_stats_rfrg, "Rx Fragments");
+ XLPGE_STAT("rjbr", nlm_sgmii_stats_rjbr, "Rx Jabber");
+
+ XLPGE_STAT("tbyt", nlm_sgmii_stats_tbyt, "Tx Bytes");
+ XLPGE_STAT("tpkt", nlm_sgmii_stats_tpkt, "Tx Packets");
+ XLPGE_STAT("tmca", nlm_sgmii_stats_tmca, "Tx Multicast Packets");
+ XLPGE_STAT("tbca", nlm_sgmii_stats_tbca, "Tx Broadcast Packets");
+ XLPGE_STAT("txpf", nlm_sgmii_stats_txpf, "Tx Pause Frame");
+ XLPGE_STAT("tdfr", nlm_sgmii_stats_tdfr, "Tx Deferral Packets");
+ XLPGE_STAT("tedf", nlm_sgmii_stats_tedf, "Tx Excessive Deferral Pkts");
+ XLPGE_STAT("tscl", nlm_sgmii_stats_tscl, "Tx Single Collisions");
+ XLPGE_STAT("tmcl", nlm_sgmii_stats_tmcl, "Tx Multiple Collisions");
+ XLPGE_STAT("tlcl", nlm_sgmii_stats_tlcl, "Tx Late Collision Pkts");
+ XLPGE_STAT("txcl", nlm_sgmii_stats_txcl, "Tx Excessive Collisions");
+ XLPGE_STAT("tncl", nlm_sgmii_stats_tncl, "Tx Total Collisions");
+ XLPGE_STAT("tjbr", nlm_sgmii_stats_tjbr, "Tx Jabber Frames");
+ XLPGE_STAT("tfcs", nlm_sgmii_stats_tfcs, "Tx FCS Errors");
+ XLPGE_STAT("txcf", nlm_sgmii_stats_txcf, "Tx Control Frames");
+ XLPGE_STAT("tovr", nlm_sgmii_stats_tovr, "Tx Oversize Frames");
+ XLPGE_STAT("tund", nlm_sgmii_stats_tund, "Tx Undersize Frames");
+ XLPGE_STAT("tfrg", nlm_sgmii_stats_tfrg, "Tx Fragments");
+#undef XLPGE_STAT
+}
+
+static int
+nlm_xlpge_attach(device_t dev)
+{
+ struct xlp_port_ivars *pv;
+ struct nlm_xlpge_softc *sc;
+ int port;
+
+ pv = device_get_ivars(dev);
+ sc = device_get_softc(dev);
+ sc->xlpge_dev = dev;
+ sc->mii_bus = NULL;
+ sc->block = pv->block;
+ sc->node = pv->node;
+ sc->port = pv->port;
+ sc->type = pv->type;
+ sc->xlpge_if = NULL;
+ sc->phy_addr = pv->phy_addr;
+ sc->mdio_bus = pv->mdio_bus;
+ sc->portcfg = nae_port_config;
+ sc->hw_parser_en = pv->hw_parser_en;
+
+ /* default settings */
+ sc->speed = NLM_SGMII_SPEED_10;
+ sc->duplexity = NLM_SGMII_DUPLEX_FULL;
+ sc->link = NLM_LINK_DOWN;
+ sc->flowctrl = NLM_FLOWCTRL_DISABLED;
+
+ sc->network_sc = device_get_softc(device_get_parent(dev));
+ sc->base_addr = sc->network_sc->base;
+ sc->prepad_en = sc->network_sc->prepad_en;
+ sc->prepad_size = sc->network_sc->prepad_size;
+
+ callout_init(&sc->xlpge_callout, CALLOUT_MPSAFE);
+
+ XLPGE_LOCK_INIT(sc, device_get_nameunit(dev));
+
+ port = (sc->block*4)+sc->port;
+ sc->nfree_desc = nae_port_config[port].num_free_descs;
+ sc->txq = nae_port_config[port].txq;
+ sc->rxfreeq = nae_port_config[port].rxfreeq;
+
+ nlm_xlpge_submit_rx_free_desc(sc, sc->nfree_desc);
+ if (sc->hw_parser_en)
+ nlm_enable_hardware_parser_per_port(sc->base_addr,
+ sc->block, sc->port);
+
+ nlm_xlpge_ifinit(sc);
+ ifp_ports[port].xlpge_sc = sc;
+ nlm_xlpge_mii_init(dev, sc);
+ nlm_xlpge_setup_stats_sysctl(dev, sc);
+
+ return (0);
+}
+
+static int
+nlm_xlpge_detach(device_t dev)
+{
+ return (0);
+}
+
+static int
+nlm_xlpge_suspend(device_t dev)
+{
+ return (0);
+}
+
+static int
+nlm_xlpge_resume(device_t dev)
+{
+ return (0);
+}
+
+static int
+nlm_xlpge_shutdown(device_t dev)
+{
+ return (0);
+}
+
+/*
+ * miibus function with custom implementation
+ */
+static int
+nlm_xlpge_mii_read(struct device *dev, int phyaddr, int regidx)
+{
+ struct nlm_xlpge_softc *sc;
+ int val;
+
+ sc = device_get_softc(dev);
+ if (sc->type == SGMIIC)
+ val = nlm_gmac_mdio_read(sc->base_addr, sc->mdio_bus,
+ BLOCK_7, LANE_CFG, phyaddr, regidx);
+ else
+ val = 0xffff;
+
+ return (val);
+}
+
+static int
+nlm_xlpge_mii_write(struct device *dev, int phyaddr, int regidx, int val)
+{
+ struct nlm_xlpge_softc *sc;
+
+ sc = device_get_softc(dev);
+ if (sc->type == SGMIIC)
+ nlm_gmac_mdio_write(sc->base_addr, sc->mdio_bus, BLOCK_7,
+ LANE_CFG, phyaddr, regidx, val);
+
+ return (0);
+}
+
+static void
+nlm_xlpge_mii_statchg(device_t dev)
+{
+ struct nlm_xlpge_softc *sc;
+ struct mii_data *mii;
+ char *speed, *duplexity;
+
+ sc = device_get_softc(dev);
+ if (sc->mii_bus == NULL)
+ return;
+
+ mii = device_get_softc(sc->mii_bus);
+ if (mii->mii_media_status & IFM_ACTIVE) {
+ if (IFM_SUBTYPE(mii->mii_media_active) == IFM_10_T) {
+ sc->speed = NLM_SGMII_SPEED_10;
+ speed = "10-Mbps";
+ } else if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) {
+ sc->speed = NLM_SGMII_SPEED_100;
+ speed = "100-Mbps";
+ } else { /* default to 1G */
+ sc->speed = NLM_SGMII_SPEED_1000;
+ speed = "1-Gbps";
+ }
+
+ if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) {
+ sc->duplexity = NLM_SGMII_DUPLEX_FULL;
+ duplexity = "full";
+ } else {
+ sc->duplexity = NLM_SGMII_DUPLEX_HALF;
+ duplexity = "half";
+ }
+
+ printf("Setup [complex=%d, port=%d] with speed=%s duplex=%s\n",
+ sc->block, sc->port, speed, duplexity);
+
+ nlm_nae_setup_mac(sc->base_addr, sc->block, sc->port, 0, 1, 1,
+ sc->speed, sc->duplexity);
+ }
+}
+
+/*
+ * xlpge support function implementations
+ */
+static void
+nlm_xlpge_release_mbuf(uint64_t paddr)
+{
+ uint64_t mag, desc, mbuf;
+
+ paddr += (XLP_NTXFRAGS - 3) * sizeof(uint64_t);
+ mag = nlm_paddr_ld(paddr);
+ desc = nlm_paddr_ld(paddr + sizeof(uint64_t));
+ mbuf = nlm_paddr_ld(paddr + 2 * sizeof(uint64_t));
+
+ if (mag != 0xf00bad) {
+ /* somebody else packet Error - FIXME in intialization */
+ printf("cpu %d: ERR Tx packet paddr %jx, mag %jx, desc %jx mbuf %jx\n",
+ nlm_cpuid(), (uintmax_t)paddr, (uintmax_t)mag,
+ (intmax_t)desc, (uintmax_t)mbuf);
+ return;
+ }
+ m_freem((struct mbuf *)(uintptr_t)mbuf);
+ uma_zfree(nl_tx_desc_zone, (void *)(uintptr_t)desc);
+}
+
+static void
+nlm_xlpge_rx(struct nlm_xlpge_softc *sc, int port, vm_paddr_t paddr, int len)
+{
+ struct ifnet *ifp;
+ struct mbuf *m;
+ vm_offset_t temp;
+ unsigned long mag;
+ int prepad_size;
+
+ ifp = sc->xlpge_if;
+ temp = nlm_paddr_ld(paddr - NAE_CACHELINE_SIZE);
+ mag = nlm_paddr_ld(paddr - NAE_CACHELINE_SIZE + sizeof(uint64_t));
+
+ m = (struct mbuf *)(intptr_t)temp;
+ if (mag != 0xf00bad) {
+ /* somebody else packet Error - FIXME in intialization */
+ printf("cpu %d: ERR Rx packet paddr %jx, temp %p, mag %lx\n",
+ nlm_cpuid(), (uintmax_t)paddr, (void *)temp, mag);
+ return;
+ }
+
+ m->m_pkthdr.rcvif = ifp;
+
+#ifdef DUMP_PACKET
+ {
+ int i = 0, j = 64;
+ unsigned char *buf = (char *)m->m_data;
+ printf("(cpu_%d: nlge_rx, !RX_COPY) Rx Packet: length=%d\n",
+ nlm_cpuid(), len);
+ if (len < j)
+ j = len;
+ if (sc->prepad_en)
+ j += ((sc->prepad_size + 1) * 16);
+ for (i = 0; i < j; i++) {
+ if (i && (i % 16) == 0)
+ printf("\n");
+ printf("%02x ", buf[i]);
+ }
+ printf("\n");
+ }
+#endif
+
+ if (sc->prepad_en) {
+ prepad_size = ((sc->prepad_size + 1) * 16);
+ m->m_data += prepad_size;
+ m->m_pkthdr.len = m->m_len = (len - prepad_size);
+ } else
+ m->m_pkthdr.len = m->m_len = len;
+
+ /*atomic_incr_long(&ifp->if_ipackets);*/
+ ifp->if_ipackets++;
+#ifdef XLP_DRIVER_LOOPBACK
+ if (port == 16 || port == 17)
+ (*ifp->if_input)(ifp, m);
+ else
+ xlpge_tx(ifp, m);
+#else
+ (*ifp->if_input)(ifp, m);
+#endif
+}
+
+void
+nlm_xlpge_submit_rx_free_desc(struct nlm_xlpge_softc *sc, int num)
+{
+ int i, size, ret, n;
+ struct nlm_fmn_msg msg;
+ void *ptr;
+
+ for(i = 0; i < num; i++) {
+ memset(&msg, 0, sizeof(msg));
+ ptr = get_buf();
+ if (!ptr) {
+ device_printf(sc->xlpge_dev, "Cannot allocate mbuf\n");
+ break;
+ }
+
+ msg.msg[0] = vtophys(ptr);
+ if (msg.msg[0] == 0) {
+ printf("Bad ptr for %p\n", ptr);
+ break;
+ }
+ size = 1;
+
+ n = 0;
+ while (1) {
+ /* on success returns 1, else 0 */
+ ret = nlm_fmn_msgsend(sc->rxfreeq, size, 0, &msg);
+ if (ret == 0)
+ break;
+ if (n++ > 10000) {
+ printf("Too many credit fails for send free desc\n");
+ break;
+ }
+ }
+ }
+}
+
+void
+nlm_xlpge_msgring_handler(int vc, int size, int code, int src_id,
+ struct nlm_fmn_msg *msg, void *data)
+{
+ uint64_t phys_addr;
+ struct nlm_xlpnae_softc *sc;
+ struct nlm_xlpge_softc *xlpge_sc;
+ struct ifnet *ifp;
+ uint32_t context;
+ uint32_t port = 0;
+ uint32_t length;
+
+ sc = (struct nlm_xlpnae_softc *)data;
+ KASSERT(sc != NULL, ("Null sc in msgring handler"));
+
+ if (size == 1) { /* process transmit complete */
+ phys_addr = msg->msg[0] & 0xffffffffffULL;
+
+ /* context is SGMII_RCV_CONTEXT_NUM + three bit vlan type
+ * or vlan priority
+ */
+ context = (msg->msg[0] >> 40) & 0x3fff;
+ port = cntx2port[context];
+
+ if (port >= XLP_MAX_PORTS) {
+ printf("%s:%d Bad port %d (context=%d)\n",
+ __func__, __LINE__, port, context);
+ return;
+ }
+ ifp = ifp_ports[port].xlpge_if;
+ xlpge_sc = ifp_ports[port].xlpge_sc;
+
+ nlm_xlpge_release_mbuf(phys_addr);
+
+ /*atomic_incr_long(&ifp->if_opackets);*/
+ ifp->if_opackets++;
+
+ } else if (size > 1) { /* Recieve packet */
+ phys_addr = msg->msg[1] & 0xffffffffe0ULL;
+ length = (msg->msg[1] >> 40) & 0x3fff;
+ length -= MAC_CRC_LEN;
+
+ /* context is SGMII_RCV_CONTEXT_NUM + three bit vlan type
+ * or vlan priority
+ */
+ context = (msg->msg[1] >> 54) & 0x3ff;
+ port = cntx2port[context];
+
+ if (port >= XLP_MAX_PORTS) {
+ printf("%s:%d Bad port %d (context=%d)\n",
+ __func__, __LINE__, port, context);
+ return;
+ }
+
+ ifp = ifp_ports[port].xlpge_if;
+ xlpge_sc = ifp_ports[port].xlpge_sc;
+
+ nlm_xlpge_rx(xlpge_sc, port, phys_addr, length);
+ /* return back a free descriptor to NA */
+ nlm_xlpge_submit_rx_free_desc(xlpge_sc, 1);
+ }
+}
diff --git a/sys/mips/nlm/dev/net/xlpge.h b/sys/mips/nlm/dev/net/xlpge.h
new file mode 100644
index 0000000..883653d
--- /dev/null
+++ b/sys/mips/nlm/dev/net/xlpge.h
@@ -0,0 +1,135 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * 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 BROADCOM ``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 BROADCOM 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __XLPGE_H__
+#define __XLPGE_H__
+
+#define NLM_XLPGE_TXQ_SIZE 1024
+#define MAC_CRC_LEN 4
+
+enum xlpge_link_state {
+ NLM_LINK_DOWN,
+ NLM_LINK_UP
+};
+
+enum xlpge_floctrl_status {
+ NLM_FLOWCTRL_DISABLED,
+ NLM_FLOWCTRL_ENABLED
+};
+
+struct nlm_xlp_portdata {
+ struct ifnet *xlpge_if;
+ struct nlm_xlpge_softc *xlpge_sc;
+};
+
+struct nlm_xlpnae_softc {
+ device_t xlpnae_dev;
+ int node; /* XLP Node id */
+ uint64_t base; /* NAE IO base */
+ uint64_t poe_base; /* POE IO base */
+ uint64_t poedv_base; /* POE distribution vec IO base */
+
+ int freq; /* frequency of nae block */
+ int flow_crc_poly; /* Flow CRC16 polynomial */
+ int total_free_desc; /* total for node */
+ int max_ports;
+ int total_num_ports;
+ int per_port_num_flows;
+
+ u_int nucores;
+ u_int nblocks;
+ u_int num_complex;
+ u_int ncontexts;
+
+ /* Ingress side parameters */
+ u_int num_desc; /* no of descriptors in each packet */
+ u_int parser_threshold;/* threshold of entries above which */
+ /* the parser sequencer is scheduled */
+ /* NetIOR configs */
+ u_int cmplx_type[8]; /* XXXJC: redundant? */
+ struct nae_port_config *portcfg;
+ u_int xauimask;
+ u_int sgmiimask;
+ u_int hw_parser_en;
+ u_int prepad_en;
+ u_int prepad_size;
+ u_int driver_mode;
+ u_int ieee_1588_en;
+};
+
+struct nlm_xlpge_softc {
+ struct ifnet *xlpge_if; /* should be first member */
+ /* see - mii.c:miibus_attach() */
+ device_t xlpge_dev;
+ device_t mii_bus;
+ struct nlm_xlpnae_softc *network_sc;
+ uint64_t base_addr; /* NAE IO base */
+ 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 valid; /* boolean: valid port or not */
+ struct mii_data xlpge_mii;
+ int nfree_desc; /* No of free descriptors sent to port */
+ int phy_addr; /* PHY id for the interface */
+
+ int speed; /* Port speed */
+ int duplexity; /* Port duplexity */
+ int link; /* Port link status */
+ int flowctrl; /* Port flow control setting */
+
+ unsigned char dev_addr[ETHER_ADDR_LEN];
+ struct mtx sc_lock;
+ int if_flags;
+ struct nae_port_config *portcfg;
+ struct callout xlpge_callout;
+ int mdio_bus;
+ int txq;
+ int rxfreeq;
+ int hw_parser_en;
+ int prepad_en;
+ int prepad_size;
+};
+
+#define XLP_NTXFRAGS 16
+#define NULL_VFBID 127
+
+struct xlpge_tx_desc {
+ uint64_t frag[XLP_NTXFRAGS];
+};
+
+#define XLPGE_LOCK_INIT(_sc, _name) \
+ mtx_init(&(_sc)->sc_lock, _name, MTX_NETWORK_LOCK, MTX_DEF)
+#define XLPGE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_lock)
+#define XLPGE_LOCK(_sc) mtx_lock(&(_sc)->sc_lock)
+#define XLPGE_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_lock)
+#define XLPGE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_lock, MA_OWNED)
+
+#endif
diff --git a/sys/mips/nlm/files.xlp b/sys/mips/nlm/files.xlp
index 3d8bb93..fd2e0d0 100644
--- a/sys/mips/nlm/files.xlp
+++ b/sys/mips/nlm/files.xlp
@@ -17,6 +17,23 @@ mips/nlm/uart_pci_xlp.c optional uart
mips/nlm/uart_cpu_xlp.c optional uart
mips/nlm/usb_init.c optional usb
#
+# Network driver and micro-core code
+#
+mips/nlm/dev/net/nae.c optional xlpge
+mips/nlm/dev/net/mdio.c optional xlpge
+mips/nlm/dev/net/sgmii.c optional xlpge
+mips/nlm/dev/net/xaui.c optional xlpge
+mips/nlm/dev/net/xlpge.c optional xlpge
+ucore_app.bin optional xlpge \
+ compile-with "${CC} -march=mips32 -mabi=32 -msoft-float -I. -I$S -O3 -funroll-loops -finline-limit=20000 -fno-tree-loop-optimize -fomit-frame-pointer -mno-branch-likely -fno-pic -mno-abicalls -ffunction-sections -fdata-sections -G0 -Wall -Werror -c $S/$M/nlm/dev/net/ucore/crt0_basic.S $S/$M/nlm/dev/net/ucore/ucore_app.c && ${LD} -melf32btsmip_fbsd -d -warn-common -T$S/$M/nlm/dev/net/ucore/ld.ucore.S crt0_basic.o ucore_app.o -o ucore_app && ${OBJCOPY} -S -O binary -R .note -R .comment ucore_app ${.TARGET}" \
+ no-obj no-implicit-rule before-depend \
+ clean "crt0_basic.o ucore_app.o ucore_app ucore_app.bin"
+ucore_app_bin.h optional xlpge \
+ dependency "ucore_app.bin" \
+ compile-with "file2c -sx 'static char ucore_app_bin[] = {' '};' < ucore_app.bin > ${.TARGET}" \
+ no-obj no-implicit-rule before-depend \
+ clean "ucore_app_bin.h"
+#
# Security Driver
#
mips/nlm/dev/sec/nlmsec.c optional nlmsec
diff --git a/sys/mips/nlm/hal/interlaken.h b/sys/mips/nlm/hal/interlaken.h
new file mode 100644
index 0000000..ce9f840
--- /dev/null
+++ b/sys/mips/nlm/hal/interlaken.h
@@ -0,0 +1,70 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * 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 BROADCOM ``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 BROADCOM 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.
+ *
+ * $FreeBSD$
+ */
+#ifndef __NLM_ILAKEN_H__
+#define __NLM_ILAKEN_H__
+
+/**
+* @file_name interlaken.h
+* @author Netlogic Microsystems
+* @brief Basic definitions of XLP ILAKEN ports
+*/
+
+#define ILK_TX_CONTROL(block) NAE_REG(block, 5, 0x00)
+#define ILK_TX_RATE_LIMIT(block) NAE_REG(block, 5, 0x01)
+#define ILK_TX_META_CTRL(block) NAE_REG(block, 5, 0x02)
+#define ILK_RX_CTRL(block) NAE_REG(block, 5, 0x03)
+#define ILK_RX_STATUS1(block) NAE_REG(block, 5, 0x04)
+#define ILK_RX_STATUS2(block) NAE_REG(block, 5, 0x05)
+#define ILK_GENERAL_CTRL1(block) NAE_REG(block, 5, 0x06)
+#define ILK_STATUS3(block) NAE_REG(block, 5, 0x07)
+#define ILK_RX_FC_TMAP0(block) NAE_REG(block, 5, 0x08)
+#define ILK_RX_FC_TMAP1(block) NAE_REG(block, 5, 0x09)
+#define ILK_RX_FC_TMAP2(block) NAE_REG(block, 5, 0x0a)
+#define ILK_RX_FC_TMAP3(block) NAE_REG(block, 5, 0x0b)
+#define ILK_RX_FC_TMAP4(block) NAE_REG(block, 5, 0x0c)
+#define ILK_RX_FC_TADDR(block) NAE_REG(block, 5, 0x0d)
+#define ILK_GENERAL_CTRL2(block) NAE_REG(block, 5, 0x0e)
+#define ILK_GENERAL_CTRL3(block) NAE_REG(block, 5, 0x0f)
+#define ILK_SMALL_COUNT0(block) NAE_REG(block, 5, 0x10)
+#define ILK_SMALL_COUNT1(block) NAE_REG(block, 5, 0x11)
+#define ILK_SMALL_COUNT2(block) NAE_REG(block, 5, 0x12)
+#define ILK_SMALL_COUNT3(block) NAE_REG(block, 5, 0x13)
+#define ILK_SMALL_COUNT4(block) NAE_REG(block, 5, 0x14)
+#define ILK_SMALL_COUNT5(block) NAE_REG(block, 5, 0x15)
+#define ILK_SMALL_COUNT6(block) NAE_REG(block, 5, 0x16)
+#define ILK_SMALL_COUNT7(block) NAE_REG(block, 5, 0x17)
+#define ILK_MID_COUNT0(block) NAE_REG(block, 5, 0x18)
+#define ILK_MID_COUNT1(block) NAE_REG(block, 5, 0x19)
+#define ILK_LARGE_COUNT0(block) NAE_REG(block, 5, 0x1a)
+#define ILK_LARGE_COUNT1(block) NAE_REG(block, 5, 0x1b)
+#define ILK_LARGE_COUNT_H0(block) NAE_REG(block, 5, 0x1c)
+#define ILK_LARGE_COUNT_H1(block) NAE_REG(block, 5, 0x1d)
+
+#endif
diff --git a/sys/mips/nlm/hal/iomap.h b/sys/mips/nlm/hal/iomap.h
index f2d1dd5..7d9ae10 100644
--- a/sys/mips/nlm/hal/iomap.h
+++ b/sys/mips/nlm/hal/iomap.h
@@ -186,7 +186,7 @@ nlm_irtnum(uint64_t pcibase)
}
static __inline__ int
-nlm_uenginenum(uint64_t pcibase)
+nlm_num_uengines(uint64_t pcibase)
{
return nlm_read_reg(pcibase, XLP_PCI_UCODEINFO_REG);
}
diff --git a/sys/mips/nlm/hal/mdio.h b/sys/mips/nlm/hal/mdio.h
new file mode 100644
index 0000000..6288391
--- /dev/null
+++ b/sys/mips/nlm/hal/mdio.h
@@ -0,0 +1,104 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * 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 BROADCOM ``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 BROADCOM 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __NLM_MDIO_H__
+#define __NLM_MDIO_H__
+
+/**
+* @file_name mdio.h
+* @author Netlogic Microsystems
+* @brief Access functions for XLP MDIO
+*/
+#define INT_MDIO_CTRL 0x19
+#define INT_MDIO_CTRL_DATA 0x1A
+#define INT_MDIO_RD_STAT 0x1B
+#define INT_MDIO_LINK_STAT 0x1C
+#define EXT_G0_MDIO_CTRL 0x1D
+#define EXT_G1_MDIO_CTRL 0x21
+#define EXT_G0_MDIO_CTRL_DATA 0x1E
+#define EXT_G1_MDIO_CTRL_DATA 0x22
+#define EXT_G0_MDIO_LINK_STAT 0x20
+#define EXT_G1_MDIO_LINK_STAT 0x24
+#define EXT_G0_MDIO_RD_STAT 0x1F
+#define EXT_G1_MDIO_RD_STAT 0x23
+
+#define INT_MDIO_CTRL_ST_POS 0
+#define INT_MDIO_CTRL_OP_POS 2
+#define INT_MDIO_CTRL_PHYADDR_POS 4
+#define INT_MDIO_CTRL_DEVTYPE_POS 9
+#define INT_MDIO_CTRL_TA_POS 14
+#define INT_MDIO_CTRL_MIIM_POS 16
+#define INT_MDIO_CTRL_LOAD_POS 19
+#define INT_MDIO_CTRL_XDIV_POS 21
+#define INT_MDIO_CTRL_MCDIV_POS 28
+#define INT_MDIO_CTRL_RST 0x40000000
+#define INT_MDIO_CTRL_SMP 0x00100000
+#define INT_MDIO_CTRL_CMD_LOAD 0x00080000
+
+#define INT_MDIO_RD_STAT_MASK 0x0000FFFF
+#define INT_MDIO_STAT_LFV 0x00010000
+#define INT_MDIO_STAT_SC 0x00020000
+#define INT_MDIO_STAT_SM 0x00040000
+#define INT_MDIO_STAT_MIILFS 0x00080000
+#define INT_MDIO_STAT_MBSY 0x00100000
+
+#define EXT_G_MDIO_CLOCK_DIV_4 0
+#define EXT_G_MDIO_CLOCK_DIV_2 1
+#define EXT_G_MDIO_CLOCK_DIV_1 2
+#define EXT_G_MDIO_REGADDR_POS 5
+#define EXT_G_MDIO_PHYADDR_POS 10
+#define EXT_G_MDIO_CMD_SP 0x00008000
+#define EXT_G_MDIO_CMD_PSIA 0x00010000
+#define EXT_G_MDIO_CMD_LCD 0x00020000
+#define EXT_G_MDIO_CMD_RDS 0x00040000
+#define EXT_G_MDIO_CMD_SC 0x00080000
+#define EXT_G_MDIO_MMRST 0x00100000
+#define EXT_G_MDIO_DIV 0x0000001E
+
+#define EXT_G_MDIO_RD_STAT_MASK 0x0000FFFF
+#define EXT_G_MDIO_STAT_LFV 0x00010000
+#define EXT_G_MDIO_STAT_SC 0x00020000
+#define EXT_G_MDIO_STAT_SM 0x00040000
+#define EXT_G_MDIO_STAT_MIILFS 0x00080000
+#define EXT_G_MDIO_STAT_MBSY 0x80000000
+#define MDIO_OP_CMD_READ 0x10
+#define MDIO_OP_CMD_WRITE 0x01
+
+#if !defined(LOCORE) && !defined(__ASSEMBLY__)
+
+int nlm_int_gmac_mdio_read(uint64_t, int, int, int, int, int);
+int nlm_int_gmac_mdio_write(uint64_t, int, int, int, int, int, uint16_t);
+int nlm_int_gmac_mdio_reset(uint64_t, int, int, int);
+int nlm_gmac_mdio_read(uint64_t, int, int, int, int, int);
+int nlm_gmac_mdio_write(uint64_t, int, int, int, int, int, uint16_t);
+int nlm_gmac_mdio_reset(uint64_t, int, int, int);
+
+#endif /* !(LOCORE) && !(__ASSEMBLY__) */
+#endif
diff --git a/sys/mips/nlm/hal/nae.h b/sys/mips/nlm/hal/nae.h
new file mode 100644
index 0000000..0738bc7
--- /dev/null
+++ b/sys/mips/nlm/hal/nae.h
@@ -0,0 +1,646 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * 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 BROADCOM ``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 BROADCOM 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __NLM_NAE_H__
+#define __NLM_NAE_H__
+
+/**
+* @file_name nae.h
+* @author Netlogic Microsystems
+* @brief Basic definitions of XLP Networt Accelerator Engine
+*/
+
+/* NAE specific registers */
+#define NAE_REG(blk, intf, reg) (((blk) << 11) | ((intf) << 7) | (reg))
+
+/* ingress path registers */
+#define NAE_RX_CONFIG NAE_REG(7, 0, 0x10)
+#define NAE_RX_IF_BASE_CONFIG0 NAE_REG(7, 0, 0x12)
+#define NAE_RX_IF_BASE_CONFIG1 NAE_REG(7, 0, 0x13)
+#define NAE_RX_IF_BASE_CONFIG2 NAE_REG(7, 0, 0x14)
+#define NAE_RX_IF_BASE_CONFIG3 NAE_REG(7, 0, 0x15)
+#define NAE_RX_IF_BASE_CONFIG4 NAE_REG(7, 0, 0x16)
+#define NAE_RX_IF_BASE_CONFIG5 NAE_REG(7, 0, 0x17)
+#define NAE_RX_IF_BASE_CONFIG6 NAE_REG(7, 0, 0x18)
+#define NAE_RX_IF_BASE_CONFIG7 NAE_REG(7, 0, 0x19)
+#define NAE_RX_IF_BASE_CONFIG8 NAE_REG(7, 0, 0x1a)
+#define NAE_RX_IF_BASE_CONFIG9 NAE_REG(7, 0, 0x1b)
+#define NAE_RX_IF_VEC_VALID NAE_REG(7, 0, 0x1c)
+#define NAE_RX_IF_SLOT_CAL NAE_REG(7, 0, 0x1d)
+#define NAE_PARSER_CONFIG NAE_REG(7, 0, 0x1e)
+#define NAE_PARSER_SEQ_FIFO_CFG NAE_REG(7, 0, 0x1f)
+#define NAE_FREE_IN_FIFO_CFG NAE_REG(7, 0, 0x20)
+#define NAE_RXBUF_BASE_DPTH_ADDR NAE_REG(7, 0, 0x21)
+#define NAE_RXBUF_BASE_DPTH NAE_REG(7, 0, 0x22)
+#define NAE_RX_UCORE_CFG NAE_REG(7, 0, 0x23)
+#define NAE_RX_UCORE_CAM_MASK0 NAE_REG(7, 0, 0x24)
+#define NAE_RX_UCORE_CAM_MASK1 NAE_REG(7, 0, 0x25)
+#define NAE_RX_UCORE_CAM_MASK2 NAE_REG(7, 0, 0x26)
+#define NAE_RX_UCORE_CAM_MASK3 NAE_REG(7, 0, 0x27)
+#define NAE_FREEIN_FIFO_UNIQ_SZ_CFG NAE_REG(7, 0, 0x28)
+#define NAE_RX_CRC_POLY0_CFG NAE_REG(7, 0, 0x2a)
+#define NAE_RX_CRC_POLY1_CFG NAE_REG(7, 0, 0x2b)
+#define NAE_FREE_SPILL0_MEM_CFG NAE_REG(7, 0, 0x2c)
+#define NAE_FREE_SPILL1_MEM_CFG NAE_REG(7, 0, 0x2d)
+#define NAE_FREEFIFO_THRESH_CFG NAE_REG(7, 0, 0x2e)
+#define NAE_FLOW_CRC16_POLY_CFG NAE_REG(7, 0, 0x2f)
+#define NAE_EGR_NIOR_CAL_LEN_REG NAE_REG(7, 0, 0x4e)
+#define NAE_EGR_NIOR_CRDT_CAL_PROG NAE_REG(7, 0, 0x52)
+#define NAE_TEST NAE_REG(7, 0, 0x5f)
+#define NAE_BIU_TIMEOUT_CFG NAE_REG(7, 0, 0x60)
+#define NAE_BIU_CFG NAE_REG(7, 0, 0x61)
+#define NAE_RX_FREE_FIFO_POP NAE_REG(7, 0, 0x62)
+#define NAE_RX_DSBL_ECC NAE_REG(7, 0, 0x63)
+#define NAE_FLOW_BASEMASK_CFG NAE_REG(7, 0, 0x80)
+#define NAE_POE_CLASS_SETUP_CFG NAE_REG(7, 0, 0x81)
+#define NAE_UCORE_IFACEMASK_CFG NAE_REG(7, 0, 0x82)
+#define NAE_RXBUF_XOFFON_THRESH NAE_REG(7, 0, 0x83)
+#define NAE_FLOW_TABLE1_CFG NAE_REG(7, 0, 0x84)
+#define NAE_FLOW_TABLE2_CFG NAE_REG(7, 0, 0x85)
+#define NAE_FLOW_TABLE3_CFG NAE_REG(7, 0, 0x86)
+#define NAE_RX_FREE_FIFO_THRESH NAE_REG(7, 0, 0x87)
+#define NAE_RX_PARSER_UNCLA NAE_REG(7, 0, 0x88)
+#define NAE_RX_BUF_INTR_THRESH NAE_REG(7, 0, 0x89)
+#define NAE_IFACE_FIFO_CFG NAE_REG(7, 0, 0x8a)
+#define NAE_PARSER_SEQ_FIFO_THRESH_CFG NAE_REG(7, 0, 0x8b)
+#define NAE_RX_ERRINJ_CTRL0 NAE_REG(7, 0, 0x8c)
+#define NAE_RX_ERRINJ_CTRL1 NAE_REG(7, 0, 0x8d)
+#define NAE_RX_ERR_LATCH0 NAE_REG(7, 0, 0x8e)
+#define NAE_RX_ERR_LATCH1 NAE_REG(7, 0, 0x8f)
+#define NAE_RX_PERF_CTR_CFG NAE_REG(7, 0, 0xa0)
+#define NAE_RX_PERF_CTR_VAL NAE_REG(7, 0, 0xa1)
+
+/* NAE hardware parser registers */
+#define NAE_L2_TYPE_PORT0 NAE_REG(7, 0, 0x210)
+#define NAE_L2_TYPE_PORT1 NAE_REG(7, 0, 0x211)
+#define NAE_L2_TYPE_PORT2 NAE_REG(7, 0, 0x212)
+#define NAE_L2_TYPE_PORT3 NAE_REG(7, 0, 0x213)
+#define NAE_L2_TYPE_PORT4 NAE_REG(7, 0, 0x214)
+#define NAE_L2_TYPE_PORT5 NAE_REG(7, 0, 0x215)
+#define NAE_L2_TYPE_PORT6 NAE_REG(7, 0, 0x216)
+#define NAE_L2_TYPE_PORT7 NAE_REG(7, 0, 0x217)
+#define NAE_L2_TYPE_PORT8 NAE_REG(7, 0, 0x218)
+#define NAE_L2_TYPE_PORT9 NAE_REG(7, 0, 0x219)
+#define NAE_L2_TYPE_PORT10 NAE_REG(7, 0, 0x21a)
+#define NAE_L2_TYPE_PORT11 NAE_REG(7, 0, 0x21b)
+#define NAE_L2_TYPE_PORT12 NAE_REG(7, 0, 0x21c)
+#define NAE_L2_TYPE_PORT13 NAE_REG(7, 0, 0x21d)
+#define NAE_L2_TYPE_PORT14 NAE_REG(7, 0, 0x21e)
+#define NAE_L2_TYPE_PORT15 NAE_REG(7, 0, 0x21f)
+#define NAE_L2_TYPE_PORT16 NAE_REG(7, 0, 0x220)
+#define NAE_L2_TYPE_PORT17 NAE_REG(7, 0, 0x221)
+#define NAE_L2_TYPE_PORT18 NAE_REG(7, 0, 0x222)
+#define NAE_L2_TYPE_PORT19 NAE_REG(7, 0, 0x223)
+#define NAE_L3_CTABLE_MASK0 NAE_REG(7, 0, 0x22c)
+#define NAE_L3_CTABLE_MASK1 NAE_REG(7, 0, 0x22d)
+#define NAE_L3_CTABLE_MASK2 NAE_REG(7, 0, 0x22e)
+#define NAE_L3_CTABLE_MASK3 NAE_REG(7, 0, 0x22f)
+#define NAE_L3CTABLE0 NAE_REG(7, 0, 0x230)
+#define NAE_L3CTABLE1 NAE_REG(7, 0, 0x231)
+#define NAE_L3CTABLE2 NAE_REG(7, 0, 0x232)
+#define NAE_L3CTABLE3 NAE_REG(7, 0, 0x233)
+#define NAE_L3CTABLE4 NAE_REG(7, 0, 0x234)
+#define NAE_L3CTABLE5 NAE_REG(7, 0, 0x235)
+#define NAE_L3CTABLE6 NAE_REG(7, 0, 0x236)
+#define NAE_L3CTABLE7 NAE_REG(7, 0, 0x237)
+#define NAE_L3CTABLE8 NAE_REG(7, 0, 0x238)
+#define NAE_L3CTABLE9 NAE_REG(7, 0, 0x239)
+#define NAE_L3CTABLE10 NAE_REG(7, 0, 0x23a)
+#define NAE_L3CTABLE11 NAE_REG(7, 0, 0x23b)
+#define NAE_L3CTABLE12 NAE_REG(7, 0, 0x23c)
+#define NAE_L3CTABLE13 NAE_REG(7, 0, 0x23d)
+#define NAE_L3CTABLE14 NAE_REG(7, 0, 0x23e)
+#define NAE_L3CTABLE15 NAE_REG(7, 0, 0x23f)
+#define NAE_L4CTABLE0 NAE_REG(7, 0, 0x250)
+#define NAE_L4CTABLE1 NAE_REG(7, 0, 0x251)
+#define NAE_L4CTABLE2 NAE_REG(7, 0, 0x252)
+#define NAE_L4CTABLE3 NAE_REG(7, 0, 0x253)
+#define NAE_L4CTABLE4 NAE_REG(7, 0, 0x254)
+#define NAE_L4CTABLE5 NAE_REG(7, 0, 0x255)
+#define NAE_L4CTABLE6 NAE_REG(7, 0, 0x256)
+#define NAE_L4CTABLE7 NAE_REG(7, 0, 0x257)
+#define NAE_IPV6_EXT_HEADER0 NAE_REG(7, 0, 0x260)
+#define NAE_IPV6_EXT_HEADER1 NAE_REG(7, 0, 0x261)
+#define NAE_VLAN_TYPES01 NAE_REG(7, 0, 0x262)
+#define NAE_VLAN_TYPES23 NAE_REG(7, 0, 0x263)
+
+/* NAE Egress path registers */
+#define NAE_TX_CONFIG NAE_REG(7, 0, 0x11)
+#define NAE_DMA_TX_CREDIT_TH NAE_REG(7, 0, 0x29)
+#define NAE_STG1_STG2CRDT_CMD NAE_REG(7, 0, 0x30)
+#define NAE_STG2_EHCRDT_CMD NAE_REG(7, 0, 0x32)
+#define NAE_EH_FREECRDT_CMD NAE_REG(7, 0, 0x34)
+#define NAE_STG2_STRCRDT_CMD NAE_REG(7, 0, 0x36)
+#define NAE_TXFIFO_IFACEMAP_CMD NAE_REG(7, 0, 0x38)
+#define NAE_VFBID_DESTMAP_CMD NAE_REG(7, 0, 0x3a)
+#define NAE_STG1_PMEM_PROG NAE_REG(7, 0, 0x3c)
+#define NAE_STG2_PMEM_PROG NAE_REG(7, 0, 0x3e)
+#define NAE_EH_PMEM_PROG NAE_REG(7, 0, 0x40)
+#define NAE_FREE_PMEM_PROG NAE_REG(7, 0, 0x42)
+#define NAE_TX_DDR_ACTVLIST_CMD NAE_REG(7, 0, 0x44)
+#define NAE_TX_IF_BURSTMAX_CMD NAE_REG(7, 0, 0x46)
+#define NAE_TX_IF_ENABLE_CMD NAE_REG(7, 0, 0x48)
+#define NAE_TX_PKTLEN_PMEM_CMD NAE_REG(7, 0, 0x4a)
+#define NAE_TX_SCHED_MAP_CMD0 NAE_REG(7, 0, 0x4c)
+#define NAE_TX_SCHED_MAP_CMD1 NAE_REG(7, 0, 0x4d)
+#define NAE_TX_PKT_PMEM_CMD0 NAE_REG(7, 0, 0x50)
+#define NAE_TX_PKT_PMEM_CMD1 NAE_REG(7, 0, 0x51)
+#define NAE_TX_SCHED_CTRL NAE_REG(7, 0, 0x53)
+#define NAE_TX_CRC_POLY0 NAE_REG(7, 0, 0x54)
+#define NAE_TX_CRC_POLY1 NAE_REG(7, 0, 0x55)
+#define NAE_TX_CRC_POLY2 NAE_REG(7, 0, 0x56)
+#define NAE_TX_CRC_POLY3 NAE_REG(7, 0, 0x57)
+#define NAE_STR_PMEM_CMD NAE_REG(7, 0, 0x58)
+#define NAE_TX_IORCRDT_INIT NAE_REG(7, 0, 0x59)
+#define NAE_TX_DSBL_ECC NAE_REG(7, 0, 0x5a)
+#define NAE_TX_IORCRDT_IGNORE NAE_REG(7, 0, 0x5b)
+#define NAE_IF0_1588_TMSTMP_HI NAE_REG(7, 0, 0x300)
+#define NAE_IF1_1588_TMSTMP_HI NAE_REG(7, 0, 0x302)
+#define NAE_IF2_1588_TMSTMP_HI NAE_REG(7, 0, 0x304)
+#define NAE_IF3_1588_TMSTMP_HI NAE_REG(7, 0, 0x306)
+#define NAE_IF4_1588_TMSTMP_HI NAE_REG(7, 0, 0x308)
+#define NAE_IF5_1588_TMSTMP_HI NAE_REG(7, 0, 0x30a)
+#define NAE_IF6_1588_TMSTMP_HI NAE_REG(7, 0, 0x30c)
+#define NAE_IF7_1588_TMSTMP_HI NAE_REG(7, 0, 0x30e)
+#define NAE_IF8_1588_TMSTMP_HI NAE_REG(7, 0, 0x310)
+#define NAE_IF9_1588_TMSTMP_HI NAE_REG(7, 0, 0x312)
+#define NAE_IF10_1588_TMSTMP_HI NAE_REG(7, 0, 0x314)
+#define NAE_IF11_1588_TMSTMP_HI NAE_REG(7, 0, 0x316)
+#define NAE_IF12_1588_TMSTMP_HI NAE_REG(7, 0, 0x318)
+#define NAE_IF13_1588_TMSTMP_HI NAE_REG(7, 0, 0x31a)
+#define NAE_IF14_1588_TMSTMP_HI NAE_REG(7, 0, 0x31c)
+#define NAE_IF15_1588_TMSTMP_HI NAE_REG(7, 0, 0x31e)
+#define NAE_IF16_1588_TMSTMP_HI NAE_REG(7, 0, 0x320)
+#define NAE_IF17_1588_TMSTMP_HI NAE_REG(7, 0, 0x322)
+#define NAE_IF18_1588_TMSTMP_HI NAE_REG(7, 0, 0x324)
+#define NAE_IF19_1588_TMSTMP_HI NAE_REG(7, 0, 0x326)
+#define NAE_IF0_1588_TMSTMP_LO NAE_REG(7, 0, 0x301)
+#define NAE_IF1_1588_TMSTMP_LO NAE_REG(7, 0, 0x303)
+#define NAE_IF2_1588_TMSTMP_LO NAE_REG(7, 0, 0x305)
+#define NAE_IF3_1588_TMSTMP_LO NAE_REG(7, 0, 0x307)
+#define NAE_IF4_1588_TMSTMP_LO NAE_REG(7, 0, 0x309)
+#define NAE_IF5_1588_TMSTMP_LO NAE_REG(7, 0, 0x30b)
+#define NAE_IF6_1588_TMSTMP_LO NAE_REG(7, 0, 0x30d)
+#define NAE_IF7_1588_TMSTMP_LO NAE_REG(7, 0, 0x30f)
+#define NAE_IF8_1588_TMSTMP_LO NAE_REG(7, 0, 0x311)
+#define NAE_IF9_1588_TMSTMP_LO NAE_REG(7, 0, 0x313)
+#define NAE_IF10_1588_TMSTMP_LO NAE_REG(7, 0, 0x315)
+#define NAE_IF11_1588_TMSTMP_LO NAE_REG(7, 0, 0x317)
+#define NAE_IF12_1588_TMSTMP_LO NAE_REG(7, 0, 0x319)
+#define NAE_IF13_1588_TMSTMP_LO NAE_REG(7, 0, 0x31b)
+#define NAE_IF14_1588_TMSTMP_LO NAE_REG(7, 0, 0x31d)
+#define NAE_IF15_1588_TMSTMP_LO NAE_REG(7, 0, 0x31f)
+#define NAE_IF16_1588_TMSTMP_LO NAE_REG(7, 0, 0x321)
+#define NAE_IF17_1588_TMSTMP_LO NAE_REG(7, 0, 0x323)
+#define NAE_IF18_1588_TMSTMP_LO NAE_REG(7, 0, 0x325)
+#define NAE_IF19_1588_TMSTMP_LO NAE_REG(7, 0, 0x327)
+#define NAE_TX_EL0 NAE_REG(7, 0, 0x328)
+#define NAE_TX_EL1 NAE_REG(7, 0, 0x329)
+#define NAE_EIC0 NAE_REG(7, 0, 0x32a)
+#define NAE_EIC1 NAE_REG(7, 0, 0x32b)
+#define NAE_STG1_STG2CRDT_STATUS NAE_REG(7, 0, 0x32c)
+#define NAE_STG2_EHCRDT_STATUS NAE_REG(7, 0, 0x32d)
+#define NAE_STG2_FREECRDT_STATUS NAE_REG(7, 0, 0x32e)
+#define NAE_STG2_STRCRDT_STATUS NAE_REG(7, 0, 0x32f)
+#define NAE_TX_PERF_CNTR_INTR_STATUS NAE_REG(7, 0, 0x330)
+#define NAE_TX_PERF_CNTR_ROLL_STATUS NAE_REG(7, 0, 0x331)
+#define NAE_TX_PERF_CNTR0 NAE_REG(7, 0, 0x332)
+#define NAE_TX_PERF_CNTR1 NAE_REG(7, 0, 0x334)
+#define NAE_TX_PERF_CNTR2 NAE_REG(7, 0, 0x336)
+#define NAE_TX_PERF_CNTR3 NAE_REG(7, 0, 0x338)
+#define NAE_TX_PERF_CNTR4 NAE_REG(7, 0, 0x33a)
+#define NAE_TX_PERF_CNTR0_CTL NAE_REG(7, 0, 0x333)
+#define NAE_TX_PERF_CNTR1_CTL NAE_REG(7, 0, 0x335)
+#define NAE_TX_PERF_CNTR2_CTL NAE_REG(7, 0, 0x337)
+#define NAE_TX_PERF_CNTR3_CTL NAE_REG(7, 0, 0x339)
+#define NAE_TX_PERF_CNTR4_CTL NAE_REG(7, 0, 0x33b)
+#define NAE_VFBID_DESTMAP_STATUS NAE_REG(7, 0, 0x380)
+#define NAE_STG2_PMEM_STATUS NAE_REG(7, 0, 0x381)
+#define NAE_EH_PMEM_STATUS NAE_REG(7, 0, 0x382)
+#define NAE_FREE_PMEM_STATUS NAE_REG(7, 0, 0x383)
+#define NAE_TX_DDR_ACTVLIST_STATUS NAE_REG(7, 0, 0x384)
+#define NAE_TX_IF_BURSTMAX_STATUS NAE_REG(7, 0, 0x385)
+#define NAE_TX_PKTLEN_PMEM_STATUS NAE_REG(7, 0, 0x386)
+#define NAE_TX_SCHED_MAP_STATUS0 NAE_REG(7, 0, 0x387)
+#define NAE_TX_SCHED_MAP_STATUS1 NAE_REG(7, 0, 0x388)
+#define NAE_TX_PKT_PMEM_STATUS NAE_REG(7, 0, 0x389)
+#define NAE_STR_PMEM_STATUS NAE_REG(7, 0, 0x38a)
+
+/* Network interface interrupt registers */
+#define NAE_NET_IF0_INTR_STAT NAE_REG(7, 0, 0x280)
+#define NAE_NET_IF1_INTR_STAT NAE_REG(7, 0, 0x282)
+#define NAE_NET_IF2_INTR_STAT NAE_REG(7, 0, 0x284)
+#define NAE_NET_IF3_INTR_STAT NAE_REG(7, 0, 0x286)
+#define NAE_NET_IF4_INTR_STAT NAE_REG(7, 0, 0x288)
+#define NAE_NET_IF5_INTR_STAT NAE_REG(7, 0, 0x28a)
+#define NAE_NET_IF6_INTR_STAT NAE_REG(7, 0, 0x28c)
+#define NAE_NET_IF7_INTR_STAT NAE_REG(7, 0, 0x28e)
+#define NAE_NET_IF8_INTR_STAT NAE_REG(7, 0, 0x290)
+#define NAE_NET_IF9_INTR_STAT NAE_REG(7, 0, 0x292)
+#define NAE_NET_IF10_INTR_STAT NAE_REG(7, 0, 0x294)
+#define NAE_NET_IF11_INTR_STAT NAE_REG(7, 0, 0x296)
+#define NAE_NET_IF12_INTR_STAT NAE_REG(7, 0, 0x298)
+#define NAE_NET_IF13_INTR_STAT NAE_REG(7, 0, 0x29a)
+#define NAE_NET_IF14_INTR_STAT NAE_REG(7, 0, 0x29c)
+#define NAE_NET_IF15_INTR_STAT NAE_REG(7, 0, 0x29e)
+#define NAE_NET_IF16_INTR_STAT NAE_REG(7, 0, 0x2a0)
+#define NAE_NET_IF17_INTR_STAT NAE_REG(7, 0, 0x2a2)
+#define NAE_NET_IF18_INTR_STAT NAE_REG(7, 0, 0x2a4)
+#define NAE_NET_IF19_INTR_STAT NAE_REG(7, 0, 0x2a6)
+#define NAE_NET_IF0_INTR_MASK NAE_REG(7, 0, 0x281)
+#define NAE_NET_IF1_INTR_MASK NAE_REG(7, 0, 0x283)
+#define NAE_NET_IF2_INTR_MASK NAE_REG(7, 0, 0x285)
+#define NAE_NET_IF3_INTR_MASK NAE_REG(7, 0, 0x287)
+#define NAE_NET_IF4_INTR_MASK NAE_REG(7, 0, 0x289)
+#define NAE_NET_IF5_INTR_MASK NAE_REG(7, 0, 0x28b)
+#define NAE_NET_IF6_INTR_MASK NAE_REG(7, 0, 0x28d)
+#define NAE_NET_IF7_INTR_MASK NAE_REG(7, 0, 0x28f)
+#define NAE_NET_IF8_INTR_MASK NAE_REG(7, 0, 0x291)
+#define NAE_NET_IF9_INTR_MASK NAE_REG(7, 0, 0x293)
+#define NAE_NET_IF10_INTR_MASK NAE_REG(7, 0, 0x295)
+#define NAE_NET_IF11_INTR_MASK NAE_REG(7, 0, 0x297)
+#define NAE_NET_IF12_INTR_MASK NAE_REG(7, 0, 0x299)
+#define NAE_NET_IF13_INTR_MASK NAE_REG(7, 0, 0x29b)
+#define NAE_NET_IF14_INTR_MASK NAE_REG(7, 0, 0x29d)
+#define NAE_NET_IF15_INTR_MASK NAE_REG(7, 0, 0x29f)
+#define NAE_NET_IF16_INTR_MASK NAE_REG(7, 0, 0x2a1)
+#define NAE_NET_IF17_INTR_MASK NAE_REG(7, 0, 0x2a3)
+#define NAE_NET_IF18_INTR_MASK NAE_REG(7, 0, 0x2a5)
+#define NAE_NET_IF19_INTR_MASK NAE_REG(7, 0, 0x2a7)
+#define NAE_COMMON0_INTR_STAT NAE_REG(7, 0, 0x2a8)
+#define NAE_COMMON0_INTR_MASK NAE_REG(7, 0, 0x2a9)
+#define NAE_COMMON1_INTR_STAT NAE_REG(7, 0, 0x2aa)
+#define NAE_COMMON1_INTR_MASK NAE_REG(7, 0, 0x2ab)
+
+/* Network Interface Low-block Registers */
+#define NAE_PHY_LANE0_STATUS(block) NAE_REG(block, 0xe, 0)
+#define NAE_PHY_LANE1_STATUS(block) NAE_REG(block, 0xe, 1)
+#define NAE_PHY_LANE2_STATUS(block) NAE_REG(block, 0xe, 2)
+#define NAE_PHY_LANE3_STATUS(block) NAE_REG(block, 0xe, 3)
+#define NAE_PHY_LANE0_CTRL(block) NAE_REG(block, 0xe, 4)
+#define NAE_PHY_LANE1_CTRL(block) NAE_REG(block, 0xe, 5)
+#define NAE_PHY_LANE2_CTRL(block) NAE_REG(block, 0xe, 6)
+#define NAE_PHY_LANE3_CTRL(block) NAE_REG(block, 0xe, 7)
+
+/* Network interface Top-block registers */
+#define NAE_LANE_CFG_CPLX_0_1 NAE_REG(7, 0, 0x780)
+#define NAE_LANE_CFG_CPLX_2_3 NAE_REG(7, 0, 0x781)
+#define NAE_LANE_CFG_CPLX_4 NAE_REG(7, 0, 0x782)
+#define NAE_LANE_CFG_SOFTRESET NAE_REG(7, 0, 0x783)
+#define NAE_1588_PTP_OFFSET_HI NAE_REG(7, 0, 0x784)
+#define NAE_1588_PTP_OFFSET_LO NAE_REG(7, 0, 0x785)
+#define NAE_1588_PTP_INC_DEN NAE_REG(7, 0, 0x786)
+#define NAE_1588_PTP_INC_NUM NAE_REG(7, 0, 0x787)
+#define NAE_1588_PTP_INC_INTG NAE_REG(7, 0, 0x788)
+#define NAE_1588_PTP_CONTROL NAE_REG(7, 0, 0x789)
+#define NAE_1588_PTP_STATUS NAE_REG(7, 0, 0x78a)
+#define NAE_1588_PTP_USER_VALUE_HI NAE_REG(7, 0, 0x78b)
+#define NAE_1588_PTP_USER_VALUE_LO NAE_REG(7, 0, 0x78c)
+#define NAE_1588_PTP_TMR1_HI NAE_REG(7, 0, 0x78d)
+#define NAE_1588_PTP_TMR1_LO NAE_REG(7, 0, 0x78e)
+#define NAE_1588_PTP_TMR2_HI NAE_REG(7, 0, 0x78f)
+#define NAE_1588_PTP_TMR2_LO NAE_REG(7, 0, 0x790)
+#define NAE_1588_PTP_TMR3_HI NAE_REG(7, 0, 0x791)
+#define NAE_1588_PTP_TMR3_LO NAE_REG(7, 0, 0x792)
+#define NAE_TX_FC_CAL_IDX_TBL_CTRL NAE_REG(7, 0, 0x793)
+#define NAE_TX_FC_CAL_TBL_CTRL NAE_REG(7, 0, 0x794)
+#define NAE_TX_FC_CAL_TBL_DATA0 NAE_REG(7, 0, 0x795)
+#define NAE_TX_FC_CAL_TBL_DATA1 NAE_REG(7, 0, 0x796)
+#define NAE_TX_FC_CAL_TBL_DATA2 NAE_REG(7, 0, 0x797)
+#define NAE_TX_FC_CAL_TBL_DATA3 NAE_REG(7, 0, 0x798)
+#define NAE_INT_MDIO_CTRL NAE_REG(7, 0, 0x799)
+#define NAE_INT_MDIO_CTRL_DATA NAE_REG(7, 0, 0x79a)
+#define NAE_INT_MDIO_RD_STAT NAE_REG(7, 0, 0x79b)
+#define NAE_INT_MDIO_LINK_STAT NAE_REG(7, 0, 0x79c)
+#define NAE_EXT_G0_MDIO_CTRL NAE_REG(7, 0, 0x79d)
+#define NAE_EXT_G1_MDIO_CTRL NAE_REG(7, 0, 0x7a1)
+#define NAE_EXT_G0_MDIO_CTRL_DATA NAE_REG(7, 0, 0x79e)
+#define NAE_EXT_G1_MDIO_CTRL_DATA NAE_REG(7, 0, 0x7a2)
+#define NAE_EXT_G0_MDIO_RD_STAT NAE_REG(7, 0, 0x79f)
+#define NAE_EXT_G1_MDIO_RD_STAT NAE_REG(7, 0, 0x7a3)
+#define NAE_EXT_G0_MDIO_LINK_STAT NAE_REG(7, 0, 0x7a0)
+#define NAE_EXT_G1_MDIO_LINK_STAT NAE_REG(7, 0, 0x7a4)
+#define NAE_EXT_XG0_MDIO_CTRL NAE_REG(7, 0, 0x7a5)
+#define NAE_EXT_XG1_MDIO_CTRL NAE_REG(7, 0, 0x7a9)
+#define NAE_EXT_XG0_MDIO_CTRL_DATA NAE_REG(7, 0, 0x7a6)
+#define NAE_EXT_XG1_MDIO_CTRL_DATA NAE_REG(7, 0, 0x7aa)
+#define NAE_EXT_XG0_MDIO_RD_STAT NAE_REG(7, 0, 0x7a7)
+#define NAE_EXT_XG1_MDIO_RD_STAT NAE_REG(7, 0, 0x7ab)
+#define NAE_EXT_XG0_MDIO_LINK_STAT NAE_REG(7, 0, 0x7a8)
+#define NAE_EXT_XG1_MDIO_LINK_STAT NAE_REG(7, 0, 0x7ac)
+#define NAE_GMAC_FC_SLOT0 NAE_REG(7, 0, 0x7ad)
+#define NAE_GMAC_FC_SLOT1 NAE_REG(7, 0, 0x7ae)
+#define NAE_GMAC_FC_SLOT2 NAE_REG(7, 0, 0x7af)
+#define NAE_GMAC_FC_SLOT3 NAE_REG(7, 0, 0x7b0)
+#define NAE_NETIOR_NTB_SLOT NAE_REG(7, 0, 0x7b1)
+#define NAE_NETIOR_MISC_CTRL0 NAE_REG(7, 0, 0x7b2)
+#define NAE_NETIOR_INT0 NAE_REG(7, 0, 0x7b3)
+#define NAE_NETIOR_INT0_MASK NAE_REG(7, 0, 0x7b4)
+#define NAE_NETIOR_INT1 NAE_REG(7, 0, 0x7b5)
+#define NAE_NETIOR_INT1_MASK NAE_REG(7, 0, 0x7b6)
+#define NAE_GMAC_PFC_REPEAT NAE_REG(7, 0, 0x7b7)
+#define NAE_XGMAC_PFC_REPEAT NAE_REG(7, 0, 0x7b8)
+#define NAE_NETIOR_MISC_CTRL1 NAE_REG(7, 0, 0x7b9)
+#define NAE_NETIOR_MISC_CTRL2 NAE_REG(7, 0, 0x7ba)
+#define NAE_NETIOR_INT2 NAE_REG(7, 0, 0x7bb)
+#define NAE_NETIOR_INT2_MASK NAE_REG(7, 0, 0x7bc)
+#define NAE_NETIOR_MISC_CTRL3 NAE_REG(7, 0, 0x7bd)
+
+/* Network interface lane configuration registers */
+#define NAE_LANE_CFG_MISCREG1 NAE_REG(7, 0xf, 0x39)
+#define NAE_LANE_CFG_MISCREG2 NAE_REG(7, 0xf, 0x3A)
+
+/* Network interface soft reset register */
+#define NAE_SOFT_RESET NAE_REG(7, 0xf, 3)
+
+/* ucore instruction/shared CAM RAM access */
+#define NAE_UCORE_SHARED_RAM_OFFSET 0x10000
+
+#define PORTS_PER_CMPLX 4
+#define NAE_CACHELINE_SIZE 64
+
+#define PHY_LANE_0_CTRL 4
+#define PHY_LANE_1_CTRL 5
+#define PHY_LANE_2_CTRL 6
+#define PHY_LANE_3_CTRL 7
+
+#define PHY_LANE_STAT_SRCS 0x00000001
+#define PHY_LANE_STAT_STD 0x00000010
+#define PHY_LANE_STAT_SFEA 0x00000020
+#define PHY_LANE_STAT_STCS 0x00000040
+#define PHY_LANE_STAT_SPC 0x00000200
+#define PHY_LANE_STAT_XLF 0x00000400
+#define PHY_LANE_STAT_PCR 0x00000800
+
+#define PHY_LANE_CTRL_DATA_POS 0
+#define PHY_LANE_CTRL_ADDR_POS 8
+#define PHY_LANE_CTRL_CMD_READ 0x00010000
+#define PHY_LANE_CTRL_CMD_WRITE 0x00000000
+#define PHY_LANE_CTRL_CMD_START 0x00020000
+#define PHY_LANE_CTRL_CMD_PENDING 0x00040000
+#define PHY_LANE_CTRL_ALL 0x00200000
+#define PHY_LANE_CTRL_FAST_INIT 0x00400000
+#define PHY_LANE_CTRL_REXSEL_POS 23
+#define PHY_LANE_CTRL_PHYMODE_POS 25
+#define PHY_LANE_CTRL_PWRDOWN 0x20000000
+#define PHY_LANE_CTRL_RST 0x40000000
+#define PHY_LANE_CTRL_RST_XAUI 0xc0000000
+#define PHY_LANE_CTRL_BPC_XAUI 0x80000000
+
+#define LANE_CFG_CPLX_0_1 0x0
+#define LANE_CFG_CPLX_2_3 0x1
+#define LANE_CFG_CPLX_4 0x2
+
+#define MAC_CONF1 0x0
+#define MAC_CONF2 0x1
+#define MAX_FRM 0x4
+
+#define NETIOR_GMAC_CTRL1 0x7F
+#define NETIOR_GMAC_CTRL2 0x7E
+#define NETIOR_GMAC_CTRL3 0x7C
+
+#define SGMII_CAL_SLOTS 3
+#define XAUI_CAL_SLOTS 13
+#define IL8_CAL_SLOTS 26
+#define IL4_CAL_SLOTS 10
+
+#define NAE_DRR_QUANTA 2048
+
+#define XLP3XX_STG2_FIFO_SZ 512
+#define XLP3XX_EH_FIFO_SZ 512
+#define XLP3XX_FROUT_FIFO_SZ 512
+#define XLP3XX_MS_FIFO_SZ 512
+#define XLP3XX_PKT_FIFO_SZ 8192
+#define XLP3XX_PKTLEN_FIFO_SZ 512
+
+#define XLP3XX_MAX_STG2_OFFSET 0x7F
+#define XLP3XX_MAX_EH_OFFSET 0x1f
+#define XLP3XX_MAX_FREE_OUT_OFFSET 0x1f
+#define XLP3XX_MAX_MS_OFFSET 0xF
+#define XLP3XX_MAX_PMEM_OFFSET 0x7FE
+
+#define XLP3XX_STG1_2_CREDIT XLP3XX_STG2_FIFO_SZ
+#define XLP3XX_STG2_EH_CREDIT XLP3XX_EH_FIFO_SZ
+#define XLP3XX_STG2_FROUT_CREDIT XLP3XX_FROUT_FIFO_SZ
+#define XLP3XX_STG2_MS_CREDIT XLP3XX_MS_FIFO_SZ
+
+#define XLP8XX_STG2_FIFO_SZ 2048
+#define XLP8XX_EH_FIFO_SZ 4096
+#define XLP8XX_FROUT_FIFO_SZ 4096
+#define XLP8XX_MS_FIFO_SZ 2048
+#define XLP8XX_PKT_FIFO_SZ 16384
+#define XLP8XX_PKTLEN_FIFO_SZ 2048
+
+#define XLP8XX_MAX_STG2_OFFSET 0x7F
+#define XLP8XX_MAX_EH_OFFSET 0x7F
+#define XLP8XX_MAX_FREE_OUT_OFFSET 0x7F
+#define XLP8XX_MAX_MS_OFFSET 0x1F
+#define XLP8XX_MAX_PMEM_OFFSET 0x7FE
+
+#define XLP8XX_STG1_2_CREDIT XLP8XX_STG2_FIFO_SZ
+#define XLP8XX_STG2_EH_CREDIT XLP8XX_EH_FIFO_SZ
+#define XLP8XX_STG2_FROUT_CREDIT XLP8XX_FROUT_FIFO_SZ
+#define XLP8XX_STG2_MS_CREDIT XLP8XX_MS_FIFO_SZ
+
+#define MAX_CAL_SLOTS 64
+#define XLP_MAX_PORTS 18
+#define XLP_STORM_MAX_PORTS 8
+
+#if !defined(LOCORE) && !defined(__ASSEMBLY__)
+
+#define nlm_read_nae_reg(b, r) nlm_read_reg_xkphys(b, r)
+#define nlm_write_nae_reg(b, r, v) nlm_write_reg_xkphys(b, r, v)
+#define nlm_get_nae_pcibase(node) \
+ nlm_pcicfg_base(XLP_IO_NAE_OFFSET(node))
+#define nlm_get_nae_regbase(node) \
+ nlm_xkphys_map_pcibar0(nlm_get_nae_pcibase(node))
+
+#define MAX_POE_CLASSES 8
+#define MAX_POE_CLASS_CTXT_TBL_SZ ((NUM_CONTEXTS / MAX_POE_CLASSES) + 1)
+#define TXINITIORCR(x) (((x) & 0x7ffff) << 8)
+
+enum XLPNAE_TX_TYPE {
+ P2D_NEOP = 0,
+ P2P,
+ P2D_EOP,
+ MSC
+};
+
+enum nblock_type {
+ SGMIIC = 1,
+ XAUIC = 2,
+ ILC = 3
+};
+
+enum nae_interface_type {
+ GMAC_0 = 0,
+ GMAC_1,
+ GMAC_2,
+ GMAC_3,
+ XGMAC,
+ INTERLAKEN,
+ PHY = 0xE,
+ LANE_CFG = 0xF,
+};
+
+enum {
+ LM_UNCONNECTED = 0,
+ LM_SGMII = 1,
+ LM_XAUI = 2,
+ LM_IL = 3,
+};
+
+enum nae_block {
+ BLOCK_0 = 0,
+ BLOCK_1,
+ BLOCK_2,
+ BLOCK_3,
+ BLOCK_4,
+ BLOCK_5,
+ BLOCK_6,
+ BLOCK_7,
+};
+
+enum {
+ PHYMODE_NONE = 0,
+ PHYMODE_HS_SGMII = 1,
+ PHYMODE_XAUI = 1,
+ PHYMODE_SGMII = 2,
+ PHYMODE_IL = 3,
+};
+
+static __inline int
+nae_num_complex(uint64_t nae_pcibase)
+{
+ return (nlm_read_reg(nae_pcibase, XLP_PCI_DEVINFO_REG0) & 0xff);
+}
+
+static __inline int
+nae_num_context(uint64_t nae_pcibase)
+{
+ return (nlm_read_reg(nae_pcibase, XLP_PCI_DEVINFO_REG5));
+}
+
+/* per port config structure */
+struct nae_port_config {
+ int num_channels;
+ int num_free_descs;
+ int free_desc_sizes;
+ int ucore_mask;
+ int loopback_mode; /* is complex is in loopback? */
+ uint32_t freein_spill_size; /* Freein spill size for each port */
+ uint32_t free_fifo_size; /* (512entries x 2desc/entry)1024desc */
+ uint32_t iface_fifo_size;/* 256 entries x 64B/entry = 16KB */
+ uint32_t pseq_fifo_size; /* 1024 entries - 1 pktlen/entry */
+ uint32_t rxbuf_size; /* 4096 entries x 64B = 256KB */
+ uint32_t rx_if_base_config;
+ uint32_t rx_slots_reqd;
+ uint32_t tx_slots_reqd;
+ uint32_t stg2_fifo_size;
+ uint32_t eh_fifo_size;
+ uint32_t frout_fifo_size;
+ uint32_t ms_fifo_size;
+ uint32_t pkt_fifo_size;
+ uint32_t pktlen_fifo_size;
+ uint32_t max_stg2_offset;
+ uint32_t max_eh_offset;
+ uint32_t max_frout_offset;
+ uint32_t max_ms_offset;
+ uint32_t max_pmem_offset;
+ uint32_t stg1_2_credit;
+ uint32_t stg2_eh_credit;
+ uint32_t stg2_frout_credit;
+ uint32_t stg2_ms_credit;
+ uint32_t vlan_pri_en;
+ uint32_t txq;
+ uint32_t rxfreeq;
+ uint32_t ieee1588_inc_intg;
+ uint32_t ieee1588_inc_den;
+ uint32_t ieee1588_inc_num;
+ uint64_t ieee1588_userval;
+ uint64_t ieee1588_ptpoff;
+ uint64_t ieee1588_tmr1;
+ uint64_t ieee1588_tmr2;
+ uint64_t ieee1588_tmr3;
+};
+
+void nlm_nae_flush_free_fifo(uint64_t nae_base, int nblocks);
+void nlm_program_nae_parser_seq_fifo(uint64_t, int, struct nae_port_config *);
+void nlm_setup_rx_cal_cfg(uint64_t, int, struct nae_port_config *);
+void nlm_setup_tx_cal_cfg(uint64_t, int, struct nae_port_config *cfg);
+void nlm_deflate_frin_fifo_carving(uint64_t, int);
+void nlm_reset_nae(int);
+int nlm_set_nae_frequency(int, int);
+void nlm_setup_poe_class_config(uint64_t nae_base, int max_poe_classes,
+ int num_contexts, int *poe_cl_tbl);
+void nlm_setup_vfbid_mapping(uint64_t);
+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 *);
+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);
+void xlp_nae_lane_reset_txpll(uint64_t, int, int, int);
+void xlp_nae_config_lane_gmac(uint64_t, int);
+void config_egress_fifo_carvings(uint64_t, int, int, int, int,
+ struct nae_port_config *);
+void config_egress_fifo_credits(uint64_t, int, int, int, int,
+ struct nae_port_config *);
+void nlm_config_freein_fifo_uniq_cfg(uint64_t, int, int);
+void nlm_config_ucore_iface_mask_cfg(uint64_t, int, int);
+int nlm_nae_init_netior(uint64_t nae_base, int nblocks);
+void nlm_nae_init_ingress(uint64_t, uint32_t);
+void nlm_nae_init_egress(uint64_t);
+uint32_t ucore_spray_config(uint32_t, uint32_t, int);
+void nlm_nae_init_ucore(uint64_t nae_base, int if_num, uint32_t ucore_mask);
+int nlm_nae_open_if(uint64_t, int, int, int, uint32_t);
+void nlm_mac_enable(uint64_t, int, int, int);
+void nlm_mac_disable(uint64_t, int, int, int);
+uint64_t nae_tx_desc(u_int, u_int, u_int, u_int, uint64_t);
+void nlm_setup_l2type(uint64_t, int, uint32_t, uint32_t, uint32_t,
+ uint32_t, uint32_t, uint32_t);
+void nlm_setup_l3ctable_mask(uint64_t, int, uint32_t, uint32_t);
+void nlm_setup_l3ctable_even(uint64_t, int, uint32_t, uint32_t, uint32_t,
+ uint32_t, uint32_t);
+void nlm_setup_l3ctable_odd(uint64_t, int, uint32_t, uint32_t, uint32_t,
+ uint32_t, uint32_t, uint32_t);
+void nlm_setup_l4ctable_even(uint64_t, int, uint32_t, uint32_t, uint32_t,
+ uint32_t, uint32_t, uint32_t);
+void nlm_setup_l4ctable_odd(uint64_t, int, uint32_t, uint32_t, uint32_t, uint32_t);
+void nlm_enable_hardware_parser(uint64_t);
+void nlm_enable_hardware_parser_per_port(uint64_t, int, int);
+void nlm_prepad_enable(uint64_t, int);
+void nlm_setup_1588_timer(uint64_t, struct nae_port_config *);
+
+#endif /* !(LOCORE) && !(__ASSEMBLY__) */
+
+#endif
diff --git a/sys/mips/nlm/hal/poe.h b/sys/mips/nlm/hal/poe.h
new file mode 100644
index 0000000..312dfc0
--- /dev/null
+++ b/sys/mips/nlm/hal/poe.h
@@ -0,0 +1,352 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * 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 BROADCOM ``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 BROADCOM 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __NLM_POE_H__
+#define __NLM_POE_H__
+
+/**
+* @file_name poe.h
+* @author Netlogic Microsystems
+* @brief Basic definitions of XLP Packet Order Engine
+*/
+
+/* POE specific registers */
+#define POE_CL0_ENQ_SPILL_BASE_LO 0x0
+#define POE_CL1_ENQ_SPILL_BASE_LO 0x2
+#define POE_CL2_ENQ_SPILL_BASE_LO 0x4
+#define POE_CL3_ENQ_SPILL_BASE_LO 0x6
+#define POE_CL4_ENQ_SPILL_BASE_LO 0x8
+#define POE_CL5_ENQ_SPILL_BASE_LO 0xa
+#define POE_CL6_ENQ_SPILL_BASE_LO 0xc
+#define POE_CL7_ENQ_SPILL_BASE_LO 0xe
+#define POE_CL0_ENQ_SPILL_BASE_HI 0x1
+#define POE_CL1_ENQ_SPILL_BASE_HI 0x3
+#define POE_CL2_ENQ_SPILL_BASE_HI 0x5
+#define POE_CL3_ENQ_SPILL_BASE_HI 0x7
+#define POE_CL4_ENQ_SPILL_BASE_HI 0x9
+#define POE_CL5_ENQ_SPILL_BASE_HI 0xb
+#define POE_CL6_ENQ_SPILL_BASE_HI 0xd
+#define POE_CL7_ENQ_SPILL_BASE_HI 0xf
+#define POE_CL0_DEQ_SPILL_BASE_LO 0x10
+#define POE_CL1_DEQ_SPILL_BASE_LO 0x12
+#define POE_CL2_DEQ_SPILL_BASE_LO 0x14
+#define POE_CL3_DEQ_SPILL_BASE_LO 0x16
+#define POE_CL4_DEQ_SPILL_BASE_LO 0x18
+#define POE_CL5_DEQ_SPILL_BASE_LO 0x1a
+#define POE_CL6_DEQ_SPILL_BASE_LO 0x1c
+#define POE_CL7_DEQ_SPILL_BASE_LO 0x1e
+#define POE_CL0_DEQ_SPILL_BASE_HI 0x11
+#define POE_CL1_DEQ_SPILL_BASE_HI 0x13
+#define POE_CL2_DEQ_SPILL_BASE_HI 0x15
+#define POE_CL3_DEQ_SPILL_BASE_HI 0x17
+#define POE_CL4_DEQ_SPILL_BASE_HI 0x19
+#define POE_CL5_DEQ_SPILL_BASE_HI 0x1b
+#define POE_CL6_DEQ_SPILL_BASE_HI 0x1d
+#define POE_CL7_DEQ_SPILL_BASE_HI 0x1f
+#define POE_MSG_STORAGE_BASE_ADDR_LO 0x20
+#define POE_MSG_STORAGE_BASE_ADDR_HI 0x21
+#define POE_FBP_BASE_ADDR_LO 0x22
+#define POE_FBP_BASE_ADDR_HI 0x23
+#define POE_CL0_ENQ_SPILL_MAXLINE_LO 0x24
+#define POE_CL1_ENQ_SPILL_MAXLINE_LO 0x25
+#define POE_CL2_ENQ_SPILL_MAXLINE_LO 0x26
+#define POE_CL3_ENQ_SPILL_MAXLINE_LO 0x27
+#define POE_CL4_ENQ_SPILL_MAXLINE_LO 0x28
+#define POE_CL5_ENQ_SPILL_MAXLINE_LO 0x29
+#define POE_CL6_ENQ_SPILL_MAXLINE_LO 0x2a
+#define POE_CL7_ENQ_SPILL_MAXLINE_LO 0x2b
+#define POE_CL0_ENQ_SPILL_MAXLINE_HI 0x2c
+#define POE_CL1_ENQ_SPILL_MAXLINE_HI 0x2d
+#define POE_CL2_ENQ_SPILL_MAXLINE_HI 0x2e
+#define POE_CL3_ENQ_SPILL_MAXLINE_HI 0x2f
+#define POE_CL4_ENQ_SPILL_MAXLINE_HI 0x30
+#define POE_CL5_ENQ_SPILL_MAXLINE_HI 0x31
+#define POE_CL6_ENQ_SPILL_MAXLINE_HI 0x32
+#define POE_CL7_ENQ_SPILL_MAXLINE_HI 0x33
+#define POE_MAX_FLOW_MSG0 0x40
+#define POE_MAX_FLOW_MSG1 0x41
+#define POE_MAX_FLOW_MSG2 0x42
+#define POE_MAX_FLOW_MSG3 0x43
+#define POE_MAX_FLOW_MSG4 0x44
+#define POE_MAX_FLOW_MSG5 0x45
+#define POE_MAX_FLOW_MSG6 0x46
+#define POE_MAX_FLOW_MSG7 0x47
+#define POE_MAX_MSG_CL0 0x48
+#define POE_MAX_MSG_CL1 0x49
+#define POE_MAX_MSG_CL2 0x4a
+#define POE_MAX_MSG_CL3 0x4b
+#define POE_MAX_MSG_CL4 0x4c
+#define POE_MAX_MSG_CL5 0x4d
+#define POE_MAX_MSG_CL6 0x4e
+#define POE_MAX_MSG_CL7 0x4f
+#define POE_MAX_LOC_BUF_STG_CL0 0x50
+#define POE_MAX_LOC_BUF_STG_CL1 0x51
+#define POE_MAX_LOC_BUF_STG_CL2 0x52
+#define POE_MAX_LOC_BUF_STG_CL3 0x53
+#define POE_MAX_LOC_BUF_STG_CL4 0x54
+#define POE_MAX_LOC_BUF_STG_CL5 0x55
+#define POE_MAX_LOC_BUF_STG_CL6 0x56
+#define POE_MAX_LOC_BUF_STG_CL7 0x57
+#define POE_ENQ_MSG_COUNT0_SIZE 0x58
+#define POE_ENQ_MSG_COUNT1_SIZE 0x59
+#define POE_ENQ_MSG_COUNT2_SIZE 0x5a
+#define POE_ENQ_MSG_COUNT3_SIZE 0x5b
+#define POE_ENQ_MSG_COUNT4_SIZE 0x5c
+#define POE_ENQ_MSG_COUNT5_SIZE 0x5d
+#define POE_ENQ_MSG_COUNT6_SIZE 0x5e
+#define POE_ENQ_MSG_COUNT7_SIZE 0x5f
+#define POE_ERR_MSG_DESCRIP_LO0 0x60
+#define POE_ERR_MSG_DESCRIP_LO1 0x62
+#define POE_ERR_MSG_DESCRIP_LO2 0x64
+#define POE_ERR_MSG_DESCRIP_LO3 0x66
+#define POE_ERR_MSG_DESCRIP_HI0 0x61
+#define POE_ERR_MSG_DESCRIP_HI1 0x63
+#define POE_ERR_MSG_DESCRIP_HI2 0x65
+#define POE_ERR_MSG_DESCRIP_HI3 0x67
+#define POE_OOO_MSG_CNT_LO 0x68
+#define POE_IN_ORDER_MSG_CNT_LO 0x69
+#define POE_LOC_BUF_STOR_CNT_LO 0x6a
+#define POE_EXT_BUF_STOR_CNT_LO 0x6b
+#define POE_LOC_BUF_ALLOC_CNT_LO 0x6c
+#define POE_EXT_BUF_ALLOC_CNT_LO 0x6d
+#define POE_OOO_MSG_CNT_HI 0x6e
+#define POE_IN_ORDER_MSG_CNT_HI 0x6f
+#define POE_LOC_BUF_STOR_CNT_HI 0x70
+#define POE_EXT_BUF_STOR_CNT_HI 0x71
+#define POE_LOC_BUF_ALLOC_CNT_HI 0x72
+#define POE_EXT_BUF_ALLOC_CNT_HI 0x73
+#define POE_MODE_ERR_FLOW_ID 0x74
+#define POE_STATISTICS_ENABLE 0x75
+#define POE_MAX_SIZE_FLOW 0x76
+#define POE_MAX_SIZE 0x77
+#define POE_FBP_SP 0x78
+#define POE_FBP_SP_EN 0x79
+#define POE_LOC_ALLOC_EN 0x7a
+#define POE_EXT_ALLOC_EN 0x7b
+#define POE_DISTR_0_DROP_CNT 0xc0
+#define POE_DISTR_1_DROP_CNT 0xc1
+#define POE_DISTR_2_DROP_CNT 0xc2
+#define POE_DISTR_3_DROP_CNT 0xc3
+#define POE_DISTR_4_DROP_CNT 0xc4
+#define POE_DISTR_5_DROP_CNT 0xc5
+#define POE_DISTR_6_DROP_CNT 0xc6
+#define POE_DISTR_7_DROP_CNT 0xc7
+#define POE_DISTR_8_DROP_CNT 0xc8
+#define POE_DISTR_9_DROP_CNT 0xc9
+#define POE_DISTR_10_DROP_CNT 0xca
+#define POE_DISTR_11_DROP_CNT 0xcb
+#define POE_DISTR_12_DROP_CNT 0xcc
+#define POE_DISTR_13_DROP_CNT 0xcd
+#define POE_DISTR_14_DROP_CNT 0xce
+#define POE_DISTR_15_DROP_CNT 0xcf
+#define POE_CLASS_0_DROP_CNT 0xd0
+#define POE_CLASS_1_DROP_CNT 0xd1
+#define POE_CLASS_2_DROP_CNT 0xd2
+#define POE_CLASS_3_DROP_CNT 0xd3
+#define POE_CLASS_4_DROP_CNT 0xd4
+#define POE_CLASS_5_DROP_CNT 0xd5
+#define POE_CLASS_6_DROP_CNT 0xd6
+#define POE_CLASS_7_DROP_CNT 0xd7
+#define POE_DISTR_C0_DROP_CNT 0xd8
+#define POE_DISTR_C1_DROP_CNT 0xd9
+#define POE_DISTR_C2_DROP_CNT 0xda
+#define POE_DISTR_C3_DROP_CNT 0xdb
+#define POE_DISTR_C4_DROP_CNT 0xdc
+#define POE_DISTR_C5_DROP_CNT 0xdd
+#define POE_DISTR_C6_DROP_CNT 0xde
+#define POE_DISTR_C7_DROP_CNT 0xdf
+#define POE_CPU_DROP_CNT 0xe0
+#define POE_MAX_FLOW_DROP_CNT 0xe1
+#define POE_INTERRUPT_VEC 0x140
+#define POE_INTERRUPT_MASK 0x141
+#define POE_FATALERR_MASK 0x142
+#define POE_IDI_CFG 0x143
+#define POE_TIMEOUT_VALUE 0x144
+#define POE_CACHE_ALLOC_EN 0x145
+#define POE_FBP_ECC_ERR_CNT 0x146
+#define POE_MSG_STRG_ECC_ERR_CNT 0x147
+#define POE_FID_INFO_ECC_ERR_CNT 0x148
+#define POE_MSG_INFO_ECC_ERR_CNT 0x149
+#define POE_LL_ECC_ERR_CNT 0x14a
+#define POE_SIZE_ECC_ERR_CNT 0x14b
+#define POE_FMN_TXCR_ECC_ERR_CNT 0x14c
+#define POE_ENQ_INSPIL_ECC_ERR_CNT 0x14d
+#define POE_ENQ_OUTSPIL_ECC_ERR_CNT 0x14e
+#define POE_DEQ_OUTSPIL_ECC_ERR_CNT 0x14f
+#define POE_ENQ_MSG_SENT 0x150
+#define POE_ENQ_MSG_CNT 0x151
+#define POE_FID_RDATA 0x152
+#define POE_FID_WDATA 0x153
+#define POE_FID_CMD 0x154
+#define POE_FID_ADDR 0x155
+#define POE_MSG_INFO_CMD 0x156
+#define POE_MSG_INFO_ADDR 0x157
+#define POE_MSG_INFO_RDATA 0x158
+#define POE_LL_CMD 0x159
+#define POE_LL_ADDR 0x15a
+#define POE_LL_RDATA 0x15b
+#define POE_MSG_STG_CMD 0x15c
+#define POE_MSG_STG_ADDR 0x15d
+#define POE_MSG_STG_RDATA 0x15e
+#define POE_DISTR_THRESHOLD_0 0x1c0
+#define POE_DISTR_THRESHOLD_1 0x1c1
+#define POE_DISTR_THRESHOLD_2 0x1c2
+#define POE_DISTR_THRESHOLD_3 0x1c3
+#define POE_DISTR_THRESHOLD_4 0x1c4
+#define POE_DISTR_THRESHOLD(i) (0x1c0 + (i))
+#define POE_DISTR_EN 0x1c5
+#define POE_ENQ_SPILL_THOLD 0x1c8
+#define POE_DEQ_SPILL_THOLD 0x1c9
+#define POE_DEQ_SPILL_TIMER 0x1ca
+#define POE_DISTR_CLASS_DROP_EN 0x1cb
+#define POE_DISTR_VEC_DROP_EN 0x1cc
+#define POE_DISTR_DROP_TIMER 0x1cd
+#define POE_ERROR_LOG_W0 0x1ce
+#define POE_ERROR_LOG_W1 0x1cf
+#define POE_ERROR_LOG_W2 0x1d0
+#define POE_ERR_INJ_CTRL0 0x1d1
+#define POE_TX_TIMER 0x1d4
+
+#define NUM_DIST_VEC 16
+#define NUM_WORDS_PER_DV 16
+#define MAX_DV_TBL_ENTRIES (NUM_DIST_VEC * NUM_WORDS_PER_DV)
+#define POE_DIST_THRESHOLD_VAL 0xa
+
+/*
+ * POE distribution vectors
+ *
+ * Each vector is 512 bit with msb indicating vc 512 and lsb indicating vc 0
+ * 512-bit-vector is specified as 16 32-bit words.
+ * Left most word has the vc range 511-479 right most word has vc range 31 - 0
+ * Each word has the MSB select higer vc number and LSB select lower vc num
+ */
+#define POE_DISTVECT_BASE 0x100
+#define POE_DISTVECT(vec) (POE_DISTVECT_BASE + 16 * (vec))
+#define POE_DISTVECT_OFFSET(node,cpu) (4 * (3 - (node)) + (3 - (cpu)/8))
+#define POE_DISTVECT_SHIFT(node,cpu) (((cpu) % 8 ) * 4)
+
+#if !defined(LOCORE) && !defined(__ASSEMBLY__)
+
+#define nlm_read_poe_reg(b, r) nlm_read_reg(b, r)
+#define nlm_write_poe_reg(b, r, v) nlm_write_reg(b, r, v)
+#define nlm_read_poedv_reg(b, r) nlm_read_reg_xkphys(b, r)
+#define nlm_write_poedv_reg(b, r, v) nlm_write_reg_xkphys(b, r, v)
+#define nlm_get_poe_pcibase(node) \
+ nlm_pcicfg_base(XLP_IO_POE_OFFSET(node))
+#define nlm_get_poe_regbase(node) \
+ (nlm_get_poe_pcibase(node) + XLP_IO_PCI_HDRSZ)
+#define nlm_get_poedv_regbase(node) \
+ nlm_xkphys_map_pcibar0(nlm_get_poe_pcibase(node))
+
+static __inline int
+nlm_poe_max_flows(uint64_t poe_pcibase)
+{
+ return (nlm_read_reg(poe_pcibase, XLP_PCI_DEVINFO_REG0));
+}
+
+/*
+ * Helper function, calculate the distribution vector
+ * cm0, cm1, cm2, cm3 : CPU masks for nodes 0..3
+ * thr_vcmask: destination VCs for a thread
+ */
+static __inline void
+nlm_calc_poe_distvec(uint32_t cm0, uint32_t cm1, uint32_t cm2, uint32_t cm3,
+ uint32_t thr_vcmask, uint32_t *distvec)
+{
+ uint32_t cpumask = 0, val;
+ int i, cpu, node, startcpu, index;
+
+ thr_vcmask &= 0xf;
+ for (node = 0; node < XLP_MAX_NODES; node++) {
+ switch (node) {
+ case 0: cpumask = cm0; break;
+ case 1: cpumask = cm1; break;
+ case 2: cpumask = cm2; break;
+ case 3: cpumask = cm3; break;
+ }
+
+ for (i = 0; i < 4; i++) {
+ val = 0;
+ startcpu = 31 - i * 8;
+ for (cpu = startcpu; cpu >= startcpu - 7; cpu--) {
+ val <<= 4;
+ if (cpumask & (1U << cpu))
+ val |= thr_vcmask;
+ }
+ index = POE_DISTVECT_OFFSET(node, startcpu);
+ distvec[index] = val;
+ }
+ }
+}
+
+static __inline int
+nlm_write_poe_distvec(uint64_t poedv_base, int vec, uint32_t *distvec)
+{
+ uint32_t reg;
+ int i;
+
+ if (vec < 0 || vec >= NUM_DIST_VEC)
+ return (-1);
+
+ for (i = 0; i < NUM_WORDS_PER_DV; i++) {
+ reg = POE_DISTVECT(vec) + i;
+ nlm_write_poedv_reg(poedv_base, reg, distvec[i]);
+ }
+
+ return (0);
+}
+
+static __inline void
+nlm_config_poe(uint64_t poe_base, uint64_t poedv_base)
+{
+ uint32_t zerodv[NUM_WORDS_PER_DV];
+ int i;
+
+ /* First disable distribution vector logic */
+ nlm_write_poe_reg(poe_base, POE_DISTR_EN, 0);
+
+ memset(zerodv, 0, sizeof(zerodv));
+ for (i = 0; i < NUM_DIST_VEC; i++)
+ nlm_write_poe_distvec(poedv_base, i, zerodv);
+
+ /* set the threshold */
+ for (i = 0; i < 5; i++)
+ nlm_write_poe_reg(poe_base, POE_DISTR_THRESHOLD(i),
+ POE_DIST_THRESHOLD_VAL);
+
+ nlm_write_poe_reg(poe_base, POE_DISTR_EN, 1);
+
+ /* always enable local message store */
+ nlm_write_poe_reg(poe_base, POE_LOC_ALLOC_EN, 1);
+
+ nlm_write_poe_reg(poe_base, POE_TX_TIMER, 0x3);
+}
+#endif /* !(LOCORE) && !(__ASSEMBLY__) */
+#endif
diff --git a/sys/mips/nlm/hal/sgmii.h b/sys/mips/nlm/hal/sgmii.h
new file mode 100644
index 0000000..2bd418b
--- /dev/null
+++ b/sys/mips/nlm/hal/sgmii.h
@@ -0,0 +1,217 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * 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 BROADCOM ``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 BROADCOM 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __NLM_SGMII_H__
+#define __NLM_SGMII_H__
+
+/**
+* @file_name sgmii.h
+* @author Netlogic Microsystems
+* @brief Basic definitions of XLP SGMII ports
+*/
+
+#define SGMII_MAC_CONF1(block, i) NAE_REG(block, i, 0x00)
+#define SGMII_MAC_CONF2(block, i) NAE_REG(block, i, 0x01)
+#define SGMII_IPG_IFG(block, i) NAE_REG(block, i, 0x02)
+#define SGMII_HLF_DUP(block, i) NAE_REG(block, i, 0x03)
+#define SGMII_MAX_FRAME(block, i) NAE_REG(block, i, 0x04)
+#define SGMII_TEST(block, i) NAE_REG(block, i, 0x07)
+#define SGMII_MIIM_CONF(block, i) NAE_REG(block, i, 0x08)
+#define SGMII_MIIM_CMD(block, i) NAE_REG(block, i, 0x09)
+#define SGMII_MIIM_ADDR(block, i) NAE_REG(block, i, 0x0a)
+#define SGMII_MIIM_CTRL(block, i) NAE_REG(block, i, 0x0b)
+#define SGMII_MIIM_STAT(block, i) NAE_REG(block, i, 0x0c)
+#define SGMII_MIIM_IND(block, i) NAE_REG(block, i, 0x0d)
+#define SGMII_IO_CTRL(block, i) NAE_REG(block, i, 0x0e)
+#define SGMII_IO_STAT(block, i) NAE_REG(block, i, 0x0f)
+#define SGMII_STATS_MLR(block, i) NAE_REG(block, i, 0x1f)
+#define SGMII_STATS_TR64(block, i) NAE_REG(block, i, 0x20)
+#define SGMII_STATS_TR127(block, i) NAE_REG(block, i, 0x21)
+#define SGMII_STATS_TR255(block, i) NAE_REG(block, i, 0x22)
+#define SGMII_STATS_TR511(block, i) NAE_REG(block, i, 0x23)
+#define SGMII_STATS_TR1K(block, i) NAE_REG(block, i, 0x24)
+#define SGMII_STATS_TRMAX(block, i) NAE_REG(block, i, 0x25)
+#define SGMII_STATS_TRMGV(block, i) NAE_REG(block, i, 0x26)
+#define SGMII_STATS_RBYT(block, i) NAE_REG(block, i, 0x27)
+#define SGMII_STATS_RPKT(block, i) NAE_REG(block, i, 0x28)
+#define SGMII_STATS_RFCS(block, i) NAE_REG(block, i, 0x29)
+#define SGMII_STATS_RMCA(block, i) NAE_REG(block, i, 0x2a)
+#define SGMII_STATS_RBCA(block, i) NAE_REG(block, i, 0x2b)
+#define SGMII_STATS_RXCF(block, i) NAE_REG(block, i, 0x2c)
+#define SGMII_STATS_RXPF(block, i) NAE_REG(block, i, 0x2d)
+#define SGMII_STATS_RXUO(block, i) NAE_REG(block, i, 0x2e)
+#define SGMII_STATS_RALN(block, i) NAE_REG(block, i, 0x2f)
+#define SGMII_STATS_RFLR(block, i) NAE_REG(block, i, 0x30)
+#define SGMII_STATS_RCDE(block, i) NAE_REG(block, i, 0x31)
+#define SGMII_STATS_RCSE(block, i) NAE_REG(block, i, 0x32)
+#define SGMII_STATS_RUND(block, i) NAE_REG(block, i, 0x33)
+#define SGMII_STATS_ROVR(block, i) NAE_REG(block, i, 0x34)
+#define SGMII_STATS_RFRG(block, i) NAE_REG(block, i, 0x35)
+#define SGMII_STATS_RJBR(block, i) NAE_REG(block, i, 0x36)
+#define SGMII_STATS_TBYT(block, i) NAE_REG(block, i, 0x38)
+#define SGMII_STATS_TPKT(block, i) NAE_REG(block, i, 0x39)
+#define SGMII_STATS_TMCA(block, i) NAE_REG(block, i, 0x3a)
+#define SGMII_STATS_TBCA(block, i) NAE_REG(block, i, 0x3b)
+#define SGMII_STATS_TXPF(block, i) NAE_REG(block, i, 0x3c)
+#define SGMII_STATS_TDFR(block, i) NAE_REG(block, i, 0x3d)
+#define SGMII_STATS_TEDF(block, i) NAE_REG(block, i, 0x3e)
+#define SGMII_STATS_TSCL(block, i) NAE_REG(block, i, 0x3f)
+#define SGMII_STATS_TMCL(block, i) NAE_REG(block, i, 0x40)
+#define SGMII_STATS_TLCL(block, i) NAE_REG(block, i, 0x41)
+#define SGMII_STATS_TXCL(block, i) NAE_REG(block, i, 0x42)
+#define SGMII_STATS_TNCL(block, i) NAE_REG(block, i, 0x43)
+#define SGMII_STATS_TJBR(block, i) NAE_REG(block, i, 0x46)
+#define SGMII_STATS_TFCS(block, i) NAE_REG(block, i, 0x47)
+#define SGMII_STATS_TXCF(block, i) NAE_REG(block, i, 0x48)
+#define SGMII_STATS_TOVR(block, i) NAE_REG(block, i, 0x49)
+#define SGMII_STATS_TUND(block, i) NAE_REG(block, i, 0x4a)
+#define SGMII_STATS_TFRG(block, i) NAE_REG(block, i, 0x4b)
+#define SGMII_STATS_CAR1(block, i) NAE_REG(block, i, 0x4c)
+#define SGMII_STATS_CAR2(block, i) NAE_REG(block, i, 0x4d)
+#define SGMII_STATS_CAM1(block, i) NAE_REG(block, i, 0x4e)
+#define SGMII_STATS_CAM2(block, i) NAE_REG(block, i, 0x4f)
+#define SGMII_MAC_ADDR0_LO(block, i) NAE_REG(block, i, 0x50)
+#define SGMII_MAC_ADDR0_HI(block, i) NAE_REG(block, i, 0x51)
+#define SGMII_MAC_ADDR1_LO(block, i) NAE_REG(block, i, 0x52)
+#define SGMII_MAC_ADDR1_HI(block, i) NAE_REG(block, i, 0x53)
+#define SGMII_MAC_ADDR2_LO(block, i) NAE_REG(block, i, 0x54)
+#define SGMII_MAC_ADDR2_HI(block, i) NAE_REG(block, i, 0x55)
+#define SGMII_MAC_ADDR3_LO(block, i) NAE_REG(block, i, 0x56)
+#define SGMII_MAC_ADDR3_HI(block, i) NAE_REG(block, i, 0x57)
+#define SGMII_MAC_ADDR_MASK0_LO(block, i) NAE_REG(block, i, 0x58)
+#define SGMII_MAC_ADDR_MASK0_HI(block, i) NAE_REG(block, i, 0x59)
+#define SGMII_MAC_ADDR_MASK1_LO(block, i) NAE_REG(block, i, 0x5a)
+#define SGMII_MAC_ADDR_MASK1_HI(block, i) NAE_REG(block, i, 0x5b)
+#define SGMII_MAC_FILTER_CONFIG(block, i) NAE_REG(block, i, 0x5c)
+#define SGMII_HASHTBL_VEC_B31_0(block, i) NAE_REG(block, i, 0x60)
+#define SGMII_HASHTBL_VEC_B63_32(block, i) NAE_REG(block, i, 0x61)
+#define SGMII_HASHTBL_VEC_B95_64(block, i) NAE_REG(block, i, 0x62)
+#define SGMII_HASHTBL_VEC_B127_96(block, i) NAE_REG(block, i, 0x63)
+#define SGMII_HASHTBL_VEC_B159_128(block, i) NAE_REG(block, i, 0x64)
+#define SGMII_HASHTBL_VEC_B191_160(block, i) NAE_REG(block, i, 0x65)
+#define SGMII_HASHTBL_VEC_B223_192(block, i) NAE_REG(block, i, 0x66)
+#define SGMII_HASHTBL_VEC_B255_224(block, i) NAE_REG(block, i, 0x67)
+#define SGMII_HASHTBL_VEC_B287_256(block, i) NAE_REG(block, i, 0x68)
+#define SGMII_HASHTBL_VEC_B319_288(block, i) NAE_REG(block, i, 0x69)
+#define SGMII_HASHTBL_VEC_B351_320(block, i) NAE_REG(block, i, 0x6a)
+#define SGMII_HASHTBL_VEC_B383_352(block, i) NAE_REG(block, i, 0x6b)
+#define SGMII_HASHTBL_VEC_B415_384(block, i) NAE_REG(block, i, 0x6c)
+#define SGMII_HASHTBL_VEC_B447_416(block, i) NAE_REG(block, i, 0x6d)
+#define SGMII_HASHTBL_VEC_B479_448(block, i) NAE_REG(block, i, 0x6e)
+#define SGMII_HASHTBL_VEC_B511_480(block, i) NAE_REG(block, i, 0x6f)
+
+#define SGMII_NETIOR_VLANTYPE_FILTER(block, i) NAE_REG(block, i, 0x76)
+#define SGMII_NETIOR_RXDROP_CNTR(block, i) NAE_REG(block, i, 0x77)
+#define SGMII_NETIOR_PAUSE_QUANTAMULT(block, i) NAE_REG(block, i, 0x78)
+#define SGMII_NETIOR_MAC_CTRL_OPCODE(block, i) NAE_REG(block, i, 0x79)
+#define SGMII_NETIOR_MAC_DA_H(block, i) NAE_REG(block, i, 0x7a)
+#define SGMII_NETIOR_MAC_DA_L(block, i) NAE_REG(block, i, 0x7b)
+#define SGMII_NET_IFACE_CTRL3(block, i) NAE_REG(block, i, 0x7c)
+#define SGMII_NETIOR_GMAC_STAT(block, i) NAE_REG(block, i, 0x7d)
+#define SGMII_NET_IFACE_CTRL2(block, i) NAE_REG(block, i, 0x7e)
+#define SGMII_NET_IFACE_CTRL(block, i) NAE_REG(block, i, 0x7f)
+
+#if !defined(LOCORE) && !defined(__ASSEMBLY__)
+/* speed */
+enum nlm_sgmii_speed {
+ NLM_SGMII_SPEED_10,
+ NLM_SGMII_SPEED_100,
+ NLM_SGMII_SPEED_1000,
+ NLM_SGMII_SPEED_RSVD
+};
+
+/* duplexity */
+enum nlm_sgmii_duplex_mode {
+ NLM_SGMII_DUPLEX_AUTO,
+ NLM_SGMII_DUPLEX_HALF,
+ NLM_SGMII_DUPLEX_FULL
+};
+
+/* stats */
+enum {
+ nlm_sgmii_stats_mlr,
+ nlm_sgmii_stats_tr64,
+ nlm_sgmii_stats_tr127,
+ nlm_sgmii_stats_tr255,
+ nlm_sgmii_stats_tr511,
+ nlm_sgmii_stats_tr1k,
+ nlm_sgmii_stats_trmax,
+ nlm_sgmii_stats_trmgv,
+ nlm_sgmii_stats_rbyt,
+ nlm_sgmii_stats_rpkt,
+ nlm_sgmii_stats_rfcs,
+ nlm_sgmii_stats_rmca,
+ nlm_sgmii_stats_rbca,
+ nlm_sgmii_stats_rxcf,
+ nlm_sgmii_stats_rxpf,
+ nlm_sgmii_stats_rxuo,
+ nlm_sgmii_stats_raln,
+ nlm_sgmii_stats_rflr,
+ nlm_sgmii_stats_rcde,
+ nlm_sgmii_stats_rcse,
+ nlm_sgmii_stats_rund,
+ nlm_sgmii_stats_rovr,
+ nlm_sgmii_stats_rfrg,
+ nlm_sgmii_stats_rjbr,
+ nlm_sgmii_stats_rdummy, /* not used */
+ nlm_sgmii_stats_tbyt,
+ nlm_sgmii_stats_tpkt,
+ nlm_sgmii_stats_tmca,
+ nlm_sgmii_stats_tbca,
+ nlm_sgmii_stats_txpf,
+ nlm_sgmii_stats_tdfr,
+ nlm_sgmii_stats_tedf,
+ nlm_sgmii_stats_tscl,
+ nlm_sgmii_stats_tmcl,
+ nlm_sgmii_stats_tlcl,
+ nlm_sgmii_stats_txcl,
+ nlm_sgmii_stats_tncl,
+ nlm_sgmii_stats_tjbr,
+ nlm_sgmii_stats_tfcs,
+ nlm_sgmii_stats_txcf,
+ nlm_sgmii_stats_tovr,
+ nlm_sgmii_stats_tund,
+ nlm_sgmii_stats_tfrg,
+ nlm_sgmii_stats_car1,
+ nlm_sgmii_stats_car2,
+ nlm_sgmii_stats_cam1,
+ nlm_sgmii_stats_cam2
+};
+
+void nlm_configure_sgmii_interface(uint64_t, int, int, int, int);
+void nlm_sgmii_pcs_init(uint64_t, uint32_t);
+void nlm_nae_setup_mac(uint64_t, int, int, int, int, int, int, int);
+void nlm_nae_setup_rx_mode_sgmii(uint64_t, int, int, int, int, int,
+ int, int);
+void nlm_nae_setup_mac_addr_sgmii(uint64_t, int, int, int, uint8_t *);
+
+#endif /* !(LOCORE) && !(__ASSEMBLY__) */
+
+#endif
diff --git a/sys/mips/nlm/hal/ucore_loader.h b/sys/mips/nlm/hal/ucore_loader.h
new file mode 100644
index 0000000..8298c82
--- /dev/null
+++ b/sys/mips/nlm/hal/ucore_loader.h
@@ -0,0 +1,141 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * 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 BROADCOM ``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 BROADCOM 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __NLM_UCORE_LOADER_H__
+#define __NLM_UCORE_LOADER_H__
+
+/**
+* @file_name ucore_loader.h
+* @author Netlogic Microsystems
+* @brief Ucore loader API header
+*/
+
+#define CODE_SIZE_PER_UCORE (4 << 10)
+
+static __inline__ void
+nlm_ucore_load_image(uint64_t nae_base, int ucore)
+{
+ uint64_t addr = nae_base + NAE_UCORE_SHARED_RAM_OFFSET +
+ (ucore * CODE_SIZE_PER_UCORE);
+ uint32_t *p = (uint32_t *)ucore_app_bin;
+ int i, size;
+
+ size = sizeof(ucore_app_bin)/sizeof(uint32_t);
+ for (i = 0; i < size; i++, addr += 4)
+ nlm_store_word_daddr(addr, p[i]);
+
+ /* add a 'nop' if number of instructions are odd */
+ if (size & 0x1)
+ nlm_store_word_daddr(addr, 0x0);
+}
+
+static __inline int
+nlm_ucore_write_sharedmem(uint64_t nae_base, int index, uint32_t data)
+{
+ uint32_t ucore_cfg;
+ uint64_t addr = nae_base + NAE_UCORE_SHARED_RAM_OFFSET;
+
+ if (index > 128)
+ return (-1);
+
+ ucore_cfg = nlm_read_nae_reg(nae_base, NAE_RX_UCORE_CFG);
+ /* set iram to zero */
+ nlm_write_nae_reg(nae_base, NAE_RX_UCORE_CFG,
+ (ucore_cfg & ~(0x1 << 7)));
+
+ nlm_store_word_daddr(addr + (index * 4), data);
+
+ /* restore ucore config */
+ nlm_write_nae_reg(nae_base, NAE_RX_UCORE_CFG, ucore_cfg);
+ return (0);
+}
+
+static __inline uint32_t
+nlm_ucore_read_sharedmem(uint64_t nae_base, int index)
+{
+ uint64_t addr = nae_base + NAE_UCORE_SHARED_RAM_OFFSET;
+ uint32_t ucore_cfg, val;
+
+ ucore_cfg = nlm_read_nae_reg(nae_base, NAE_RX_UCORE_CFG);
+ /* set iram to zero */
+ nlm_write_nae_reg(nae_base, NAE_RX_UCORE_CFG,
+ (ucore_cfg & ~(0x1 << 7)));
+
+ val = nlm_load_word_daddr(addr + (index * 4));
+
+ /* restore ucore config */
+ nlm_write_nae_reg(nae_base, NAE_RX_UCORE_CFG, ucore_cfg);
+
+ return val;
+}
+
+static __inline__ int
+nlm_ucore_load_all(uint64_t nae_base, uint32_t ucore_mask, int nae_reset_done)
+{
+ int i, count = 0;
+ uint32_t mask;
+ uint32_t ucore_cfg = 0;
+
+ mask = ucore_mask & 0xffff;
+
+ /* Stop all ucores */
+ if (nae_reset_done == 0) { /* Skip the Ucore reset if NAE reset is done */
+ ucore_cfg = nlm_read_nae_reg(nae_base, NAE_RX_UCORE_CFG);
+ nlm_write_nae_reg(nae_base, NAE_RX_UCORE_CFG,
+ ucore_cfg | (1 << 24));
+
+ /* poll for ucore to get in to a wait state */
+ do {
+ ucore_cfg = nlm_read_nae_reg(nae_base,
+ NAE_RX_UCORE_CFG);
+ } while ((ucore_cfg & (1 << 25)) == 0);
+ }
+
+ for (i = 0; i < sizeof(ucore_mask) * NBBY; i++) {
+ if ((mask & (1 << i)) == 0)
+ continue;
+ nlm_ucore_load_image(nae_base, i);
+ count++;
+ }
+
+ /* Enable per-domain ucores */
+ ucore_cfg = nlm_read_nae_reg(nae_base, NAE_RX_UCORE_CFG);
+
+ /* write one to reset bits to put the ucores in reset */
+ ucore_cfg = ucore_cfg | (((mask) & 0xffff) << 8);
+ nlm_write_nae_reg(nae_base, NAE_RX_UCORE_CFG, ucore_cfg);
+
+ /* write zero to reset bits to pull them out of reset */
+ ucore_cfg = ucore_cfg & (~(((mask) & 0xffff) << 8)) & ~(1 << 24);
+ nlm_write_nae_reg(nae_base, NAE_RX_UCORE_CFG, ucore_cfg);
+
+ return (count);
+}
+#endif
diff --git a/sys/mips/nlm/hal/xaui.h b/sys/mips/nlm/hal/xaui.h
new file mode 100644
index 0000000..e73cf38
--- /dev/null
+++ b/sys/mips/nlm/hal/xaui.h
@@ -0,0 +1,193 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * 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 BROADCOM ``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 BROADCOM 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.
+ *
+ * $FreeBSD$
+ */
+#ifndef __NLM_XAUI_H__
+#define __NLM_XAUI_H__
+
+/**
+* @file_name xaui.h
+* @author Netlogic Microsystems
+* @brief Basic definitions of XLP XAUI ports
+*/
+#define XAUI_CONFIG0(block) NAE_REG(block, 4, 0x00)
+#define XAUI_CONFIG1(block) NAE_REG(block, 4, 0x01)
+#define XAUI_CONFIG2(block) NAE_REG(block, 4, 0x02)
+#define XAUI_CONFIG3(block) NAE_REG(block, 4, 0x03)
+/*
+#define XAUI_MAC_ADDR0_LO(block) NAE_REG(block, 4, 0x04)
+#define XAUI_MAC_ADDR0_HI(block) NAE_REG(block, 4, 0x05)
+*/
+#define XAUI_MAX_FRAME_LEN(block) NAE_REG(block, 4, 0x08)
+#define XAUI_REVISION_LVL(block) NAE_REG(block, 4, 0x0b)
+#define XAUI_MII_MGMT_CMD(block) NAE_REG(block, 4, 0x10)
+#define XAUI_MII_MGMT_FIELD(block) NAE_REG(block, 4, 0x11)
+#define XAUI_MII_MGMT_CFG(block) NAE_REG(block, 4, 0x12)
+#define XAUI_MIIM_LINK_FALL_VEC(block) NAE_REG(block, 4, 0x13)
+#define XAUI_MII_MGMT_IND(block) NAE_REG(block, 4, 0x14)
+#define XAUI_STATS_MLR(block) NAE_REG(block, 4, 0x1f)
+#define XAUI_STATS_TR64(block) NAE_REG(block, 4, 0x20)
+#define XAUI_STATS_TR127(block) NAE_REG(block, 4, 0x21)
+#define XAUI_STATS_TR255(block) NAE_REG(block, 4, 0x22)
+#define XAUI_STATS_TR511(block) NAE_REG(block, 4, 0x23)
+#define XAUI_STATS_TR1K(block) NAE_REG(block, 4, 0x24)
+#define XAUI_STATS_TRMAX(block) NAE_REG(block, 4, 0x25)
+#define XAUI_STATS_TRMGV(block) NAE_REG(block, 4, 0x26)
+#define XAUI_STATS_RBYT(block) NAE_REG(block, 4, 0x27)
+#define XAUI_STATS_RPKT(block) NAE_REG(block, 4, 0x28)
+#define XAUI_STATS_RFCS(block) NAE_REG(block, 4, 0x29)
+#define XAUI_STATS_RMCA(block) NAE_REG(block, 4, 0x2a)
+#define XAUI_STATS_RBCA(block) NAE_REG(block, 4, 0x2b)
+#define XAUI_STATS_RXCF(block) NAE_REG(block, 4, 0x2c)
+#define XAUI_STATS_RXPF(block) NAE_REG(block, 4, 0x2d)
+#define XAUI_STATS_RXUO(block) NAE_REG(block, 4, 0x2e)
+#define XAUI_STATS_RALN(block) NAE_REG(block, 4, 0x2f)
+#define XAUI_STATS_RFLR(block) NAE_REG(block, 4, 0x30)
+#define XAUI_STATS_RCDE(block) NAE_REG(block, 4, 0x31)
+#define XAUI_STATS_RCSE(block) NAE_REG(block, 4, 0x32)
+#define XAUI_STATS_RUND(block) NAE_REG(block, 4, 0x33)
+#define XAUI_STATS_ROVR(block) NAE_REG(block, 4, 0x34)
+#define XAUI_STATS_RFRG(block) NAE_REG(block, 4, 0x35)
+#define XAUI_STATS_RJBR(block) NAE_REG(block, 4, 0x36)
+#define XAUI_STATS_TBYT(block) NAE_REG(block, 4, 0x38)
+#define XAUI_STATS_TPKT(block) NAE_REG(block, 4, 0x39)
+#define XAUI_STATS_TMCA(block) NAE_REG(block, 4, 0x3a)
+#define XAUI_STATS_TBCA(block) NAE_REG(block, 4, 0x3b)
+#define XAUI_STATS_TXPF(block) NAE_REG(block, 4, 0x3c)
+#define XAUI_STATS_TDFR(block) NAE_REG(block, 4, 0x3d)
+#define XAUI_STATS_TEDF(block) NAE_REG(block, 4, 0x3e)
+#define XAUI_STATS_TSCL(block) NAE_REG(block, 4, 0x3f)
+#define XAUI_STATS_TMCL(block) NAE_REG(block, 4, 0x40)
+#define XAUI_STATS_TLCL(block) NAE_REG(block, 4, 0x41)
+#define XAUI_STATS_TXCL(block) NAE_REG(block, 4, 0x42)
+#define XAUI_STATS_TNCL(block) NAE_REG(block, 4, 0x43)
+#define XAUI_STATS_TJBR(block) NAE_REG(block, 4, 0x46)
+#define XAUI_STATS_TFCS(block) NAE_REG(block, 4, 0x47)
+#define XAUI_STATS_TXCF(block) NAE_REG(block, 4, 0x48)
+#define XAUI_STATS_TOVR(block) NAE_REG(block, 4, 0x49)
+#define XAUI_STATS_TUND(block) NAE_REG(block, 4, 0x4a)
+#define XAUI_STATS_TFRG(block) NAE_REG(block, 4, 0x4b)
+#define XAUI_STATS_CAR1(block) NAE_REG(block, 4, 0x4c)
+#define XAUI_STATS_CAR2(block) NAE_REG(block, 4, 0x4d)
+#define XAUI_STATS_CAM1(block) NAE_REG(block, 4, 0x4e)
+#define XAUI_STATS_CAM2(block) NAE_REG(block, 4, 0x4f)
+#define XAUI_MAC_ADDR0_LO(block) NAE_REG(block, 4, 0x50)
+#define XAUI_MAC_ADDR0_HI(block) NAE_REG(block, 4, 0x51)
+#define XAUI_MAC_ADDR1_LO(block) NAE_REG(block, 4, 0x52)
+#define XAUI_MAC_ADDR1_HI(block) NAE_REG(block, 4, 0x53)
+#define XAUI_MAC_ADDR2_LO(block) NAE_REG(block, 4, 0x54)
+#define XAUI_MAC_ADDR2_HI(block) NAE_REG(block, 4, 0x55)
+#define XAUI_MAC_ADDR3_LO(block) NAE_REG(block, 4, 0x56)
+#define XAUI_MAC_ADDR3_HI(block) NAE_REG(block, 4, 0x57)
+#define XAUI_MAC_ADDR_MASK0_LO(block) NAE_REG(block, 4, 0x58)
+#define XAUI_MAC_ADDR_MASK0_HI(block) NAE_REG(block, 4, 0x59)
+#define XAUI_MAC_ADDR_MASK1_LO(block) NAE_REG(block, 4, 0x5a)
+#define XAUI_MAC_ADDR_MASK1_HI(block) NAE_REG(block, 4, 0x5b)
+#define XAUI_MAC_FILTER_CFG(block) NAE_REG(block, 4, 0x5c)
+#define XAUI_HASHTBL_VEC_B31_0(block) NAE_REG(block, 4, 0x60)
+#define XAUI_HASHTBL_VEC_B63_32(block) NAE_REG(block, 4, 0x61)
+#define XAUI_HASHTBL_VEC_B95_64(block) NAE_REG(block, 4, 0x62)
+#define XAUI_HASHTBL_VEC_B127_96(block) NAE_REG(block, 4, 0x63)
+#define XAUI_HASHTBL_VEC_B159_128(block) NAE_REG(block, 4, 0x64)
+#define XAUI_HASHTBL_VEC_B191_160(block) NAE_REG(block, 4, 0x65)
+#define XAUI_HASHTBL_VEC_B223_192(block) NAE_REG(block, 4, 0x66)
+#define XAUI_HASHTBL_VEC_B255_224(block) NAE_REG(block, 4, 0x67)
+#define XAUI_HASHTBL_VEC_B287_256(block) NAE_REG(block, 4, 0x68)
+#define XAUI_HASHTBL_VEC_B319_288(block) NAE_REG(block, 4, 0x69)
+#define XAUI_HASHTBL_VEC_B351_320(block) NAE_REG(block, 4, 0x6a)
+#define XAUI_HASHTBL_VEC_B383_352(block) NAE_REG(block, 4, 0x6b)
+#define XAUI_HASHTBL_VEC_B415_384(block) NAE_REG(block, 4, 0x6c)
+#define XAUI_HASHTBL_VEC_B447_416(block) NAE_REG(block, 4, 0x6d)
+#define XAUI_HASHTBL_VEC_B479_448(block) NAE_REG(block, 4, 0x6e)
+#define XAUI_HASHTBL_VEC_B511_480(block) NAE_REG(block, 4, 0x6f)
+
+#define XAUI_NETIOR_XGMAC_MISC0(block) NAE_REG(block, 4, 0x76)
+#define XAUI_NETIOR_RX_ABORT_DROP_COUNT(block) NAE_REG(block, 4, 0x77)
+#define XAUI_NETIOR_MACCTRL_PAUSE_QUANTA(block) NAE_REG(block, 4, 0x78)
+#define XAUI_NETIOR_MACCTRL_OPCODE(block) NAE_REG(block, 4, 0x79)
+#define XAUI_NETIOR_MAC_DA_H(block) NAE_REG(block, 4, 0x7a)
+#define XAUI_NETIOR_MAC_DA_L(block) NAE_REG(block, 4, 0x7b)
+#define XAUI_NETIOR_XGMAC_STAT(block) NAE_REG(block, 4, 0x7c)
+#define XAUI_NETIOR_XGMAC_CTRL3(block) NAE_REG(block, 4, 0x7d)
+#define XAUI_NETIOR_XGMAC_CTRL2(block) NAE_REG(block, 4, 0x7e)
+#define XAUI_NETIOR_XGMAC_CTRL1(block) NAE_REG(block, 4, 0x7f)
+
+#define LANE_RX_CLK (1 << 0)
+#define LANE_TX_CLK (1 << 6)
+
+#define XAUI_LANE_FAULT 0x400
+#define XAUI_CONFIG_0 0
+
+#define XAUI_CONFIG_MACRST 0x80000000
+#define XAUI_CONFIG_RSTRCTL 0x00400000
+#define XAUI_CONFIG_RSTRFN 0x00200000
+#define XAUI_CONFIG_RSTTCTL 0x00040000
+#define XAUI_CONFIG_RSTTFN 0x00020000
+#define XAUI_CONFIG_RSTMIIM 0x00010000
+
+#define XAUI_CONFIG_1 1
+
+#define XAUI_CONFIG_TCTLEN 0x80000000
+#define XAUI_CONFIG_TFEN 0x40000000
+#define XAUI_CONFIG_RCTLEN 0x20000000
+#define XAUI_CONFIG_RFEN 0x10000000
+#define XAUI_CONFIG_DRPLT64 0x00000020
+#define XAUI_CONFIG_LENCHK 0x00000008
+#define XAUI_CONFIG_GENFCS 0x00000004
+#define XAUI_CONFIG_PAD_0 0x00000000
+#define XAUI_CONFIG_PAD_64 0x00000001
+#define XAUI_CONFIG_PAD_COND 0x00000002
+#define XAUI_CONFIG_PAD_68 0x00000003
+
+#define XAUI_PHY_CTRL_1 0x00
+
+#define NETIOR_XGMAC_CTRL1 0x7F
+#define NETIOR_XGMAC_CTRL3 0x7D
+
+#define NETIOR_XGMAC_VLAN_DC_POS 28
+#define NETIOR_XGMAC_PHYADDR_POS 23
+#define NETIOR_XGMAC_DEVID_POS 18
+#define NETIOR_XGMAC_STATS_EN_POS 17
+#define NETIOR_XGMAC_TX_PFC_EN_POS 14
+#define NETIOR_XGMAC_RX_PFC_EN_POS 13
+#define NETIOR_XGMAC_SOFT_RST_POS 11
+#define NETIOR_XGMAC_TX_PAUSE_POS 10
+
+#define NETIOR_XGMAC_STATS_CLR_POS 16
+
+#if !defined(LOCORE) && !defined(__ASSEMBLY__)
+
+void nlm_xaui_pcs_init(uint64_t, int);
+void nlm_nae_setup_rx_mode_xaui(uint64_t, int, int, int, int, int, int, int);
+void nlm_nae_setup_mac_addr_xaui(uint64_t, int, int, int, unsigned char *);
+void nlm_config_xaui_mtu(uint64_t, int, int, int);
+void nlm_config_xaui(uint64_t, int, int, int, int);
+
+#endif /* !(LOCORE) && !(__ASSEMBLY__) */
+
+#endif
diff --git a/sys/mips/nlm/msgring.h b/sys/mips/nlm/msgring.h
index 446bad8..9ce5c43 100644
--- a/sys/mips/nlm/msgring.h
+++ b/sys/mips/nlm/msgring.h
@@ -32,6 +32,13 @@
#ifndef _NLM_MSGRING_H
#define _NLM_MSGRING_H
#define CMS_DEFAULT_CREDIT 50
+/*
+ * packets are sent to VC 0 of a thread
+ * freebacks are sent to VC 3 of a thread
+ */
+#define XLPGE_RX_VC 0
+#define XLPGE_FB_VC 3
+
extern uint32_t xlp_msg_thread_mask;
struct nlm_fmn_msg;
OpenPOWER on IntegriCloud