Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 27 Mar 2012 14:05:12 +0000 (UTC)
From:      "Jayachandran C." <jchandra@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r233545 - in head/sys/mips: conf nlm nlm/dev/net nlm/dev/net/ucore nlm/hal
Message-ID:  <201203271405.q2RE5Cip088870@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jchandra
Date: Tue Mar 27 14:05:12 2012
New Revision: 233545
URL: http://svn.freebsd.org/changeset/base/233545

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

Added:
  head/sys/mips/nlm/dev/net/
  head/sys/mips/nlm/dev/net/mdio.c   (contents, props changed)
  head/sys/mips/nlm/dev/net/nae.c   (contents, props changed)
  head/sys/mips/nlm/dev/net/sgmii.c   (contents, props changed)
  head/sys/mips/nlm/dev/net/ucore/
  head/sys/mips/nlm/dev/net/ucore/crt0_basic.S   (contents, props changed)
  head/sys/mips/nlm/dev/net/ucore/ld.ucore.S   (contents, props changed)
  head/sys/mips/nlm/dev/net/ucore/ucore.h   (contents, props changed)
  head/sys/mips/nlm/dev/net/ucore/ucore_app.c   (contents, props changed)
  head/sys/mips/nlm/dev/net/xaui.c   (contents, props changed)
  head/sys/mips/nlm/dev/net/xlpge.c   (contents, props changed)
  head/sys/mips/nlm/dev/net/xlpge.h   (contents, props changed)
  head/sys/mips/nlm/hal/interlaken.h   (contents, props changed)
  head/sys/mips/nlm/hal/mdio.h   (contents, props changed)
  head/sys/mips/nlm/hal/nae.h   (contents, props changed)
  head/sys/mips/nlm/hal/poe.h   (contents, props changed)
  head/sys/mips/nlm/hal/sgmii.h   (contents, props changed)
  head/sys/mips/nlm/hal/ucore_loader.h   (contents, props changed)
  head/sys/mips/nlm/hal/xaui.h   (contents, props changed)
Modified:
  head/sys/mips/conf/std.XLP
  head/sys/mips/nlm/board.c
  head/sys/mips/nlm/board.h
  head/sys/mips/nlm/files.xlp
  head/sys/mips/nlm/hal/iomap.h
  head/sys/mips/nlm/msgring.h

Modified: head/sys/mips/conf/std.XLP
==============================================================================
--- head/sys/mips/conf/std.XLP	Tue Mar 27 14:02:22 2012	(r233544)
+++ head/sys/mips/conf/std.XLP	Tue Mar 27 14:05:12 2012	(r233545)
@@ -71,6 +71,7 @@ device		bpf
 # Network
 device		miibus
 device		ether
+device		xlpge
 #device		re
 device		msk
 device		em

Modified: head/sys/mips/nlm/board.c
==============================================================================
--- head/sys/mips/nlm/board.c	Tue Mar 27 14:02:22 2012	(r233544)
+++ head/sys/mips/nlm/board.c	Tue Mar 27 14:05:12 2012	(r233545)
@@ -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);
 }
 

Modified: head/sys/mips/nlm/board.h
==============================================================================
--- head/sys/mips/nlm/board.h	Tue Mar 27 14:02:22 2012	(r233544)
+++ head/sys/mips/nlm/board.h	Tue Mar 27 14:05:12 2012	(r233545)
@@ -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
 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: head/sys/mips/nlm/dev/net/mdio.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/mips/nlm/dev/net/mdio.c	Tue Mar 27 14:05:12 2012	(r233545)
@@ -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);
+}

Added: head/sys/mips/nlm/dev/net/nae.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/mips/nlm/dev/net/nae.c	Tue Mar 27 14:05:12 2012	(r233545)
@@ -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++) {

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201203271405.q2RE5Cip088870>