svn commit: r232049 - in user/jchandra/xlp-merge/sys/mips: conf nlm
nlm/dev/net nlm/dev/net/ucore nlm/hal
Jayachandran C.
jchandra at FreeBSD.org
Thu Feb 23 14:35:56 UTC 2012
Author: jchandra
Date: Thu Feb 23 14:35:56 2012
New Revision: 232049
URL: http://svn.freebsd.org/changeset/base/232049
Log:
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
on the Network Accelerator.
- Basic initialization code for Packet ordering Engine.
Submitted by: Prabhath Raman (prabhath at netlogicmicro com)
[with some fixups/refactoring by jchandra]
Added:
user/jchandra/xlp-merge/sys/mips/nlm/dev/net/
user/jchandra/xlp-merge/sys/mips/nlm/dev/net/mdio.c
user/jchandra/xlp-merge/sys/mips/nlm/dev/net/nae.c
user/jchandra/xlp-merge/sys/mips/nlm/dev/net/sgmii.c
user/jchandra/xlp-merge/sys/mips/nlm/dev/net/ucore/
user/jchandra/xlp-merge/sys/mips/nlm/dev/net/ucore/crt0_basic.S
user/jchandra/xlp-merge/sys/mips/nlm/dev/net/ucore/ld.ucore.S
user/jchandra/xlp-merge/sys/mips/nlm/dev/net/ucore/ucore_app.c
user/jchandra/xlp-merge/sys/mips/nlm/dev/net/xaui.c
user/jchandra/xlp-merge/sys/mips/nlm/dev/net/xlpge.c
user/jchandra/xlp-merge/sys/mips/nlm/dev/net/xlpge.h
user/jchandra/xlp-merge/sys/mips/nlm/hal/interlaken.h
user/jchandra/xlp-merge/sys/mips/nlm/hal/mdio.h
user/jchandra/xlp-merge/sys/mips/nlm/hal/nae.h
user/jchandra/xlp-merge/sys/mips/nlm/hal/poe.h
user/jchandra/xlp-merge/sys/mips/nlm/hal/sgmii.h
user/jchandra/xlp-merge/sys/mips/nlm/hal/ucore.h
user/jchandra/xlp-merge/sys/mips/nlm/hal/ucore_loader.h
user/jchandra/xlp-merge/sys/mips/nlm/hal/xaui.h
Modified:
user/jchandra/xlp-merge/sys/mips/conf/std.XLP
user/jchandra/xlp-merge/sys/mips/nlm/board.c
user/jchandra/xlp-merge/sys/mips/nlm/board.h
user/jchandra/xlp-merge/sys/mips/nlm/files.xlp
user/jchandra/xlp-merge/sys/mips/nlm/hal/iomap.h
user/jchandra/xlp-merge/sys/mips/nlm/msgring.h
Modified: user/jchandra/xlp-merge/sys/mips/conf/std.XLP
==============================================================================
--- user/jchandra/xlp-merge/sys/mips/conf/std.XLP Thu Feb 23 11:50:23 2012 (r232048)
+++ user/jchandra/xlp-merge/sys/mips/conf/std.XLP Thu Feb 23 14:35:56 2012 (r232049)
@@ -71,6 +71,7 @@ device bpf
# Network
device miibus
device ether
+device xlpge
#device re
device msk
device em
Modified: user/jchandra/xlp-merge/sys/mips/nlm/board.c
==============================================================================
--- user/jchandra/xlp-merge/sys/mips/nlm/board.c Thu Feb 23 11:50:23 2012 (r232048)
+++ user/jchandra/xlp-merge/sys/mips/nlm/board.c Thu Feb 23 14:35:56 2012 (r232049)
@@ -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,115 @@ 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->driver_mode = XLPNAE_SPRAY;
+
+ 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);
}
Modified: user/jchandra/xlp-merge/sys/mips/nlm/board.h
==============================================================================
--- user/jchandra/xlp-merge/sys/mips/nlm/board.h Thu Feb 23 11:50:23 2012 (r232048)
+++ user/jchandra/xlp-merge/sys/mips/nlm/board.h Thu Feb 23 14:35:56 2012 (r232049)
@@ -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,78 @@
#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
+ */
+
+enum driver_mode {
+ /* driver is setup in packet spray mode
+ * sending all packets in a round robin
+ * fashion to all cpu VC's configured to
+ * receieve packets
+ */
+ XLPNAE_SPRAY,
+ /* Driver sends all ipv4 and ipv6 packets
+ * into a Jenkin's hash. The src-ip, dst-ip
+ * and port number is used for jhash calculation
+ * which in turn decides on cpu VC that will
+ * receive a particular packet
+ */
+ XLPNAE_JHASH,
+};
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 +126,17 @@ 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 driver_mode;
+ u_int ieee_1588_en;
struct xlp_block_ivars block_ivars[XLP_NAE_NBLOCKS];
};
@@ -73,14 +147,22 @@ struct xlp_board_info {
} nodes[XLP_MAX_NODES];
};
+extern struct xlp_board_info xlp_board_info;
+
+/* network config */
+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 i2cbus, int addr, int offs, uint8_t *buf,int sz);
uint64_t nlm_board_cpld_base(int node, int chipselect);
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
Added: user/jchandra/xlp-merge/sys/mips/nlm/dev/net/mdio.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ user/jchandra/xlp-merge/sys/mips/nlm/dev/net/mdio.c Thu Feb 23 14:35:56 2012 (r232049)
@@ -0,0 +1,308 @@
+/*-
+ * Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * NETLOGIC_BSD */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/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);
+}
Added: user/jchandra/xlp-merge/sys/mips/nlm/dev/net/nae.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ user/jchandra/xlp-merge/sys/mips/nlm/dev/net/nae.c Thu Feb 23 14:35:56 2012 (r232049)
@@ -0,0 +1,1537 @@
+/*-
+ * Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * NETLOGIC_BSD */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/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)
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-user
mailing list