nxge_mac.c revision 6b4389256364527aaad06f3fd83d4b05358a4c02
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#define LM_WAIT_MULTIPLIER 8
extern uint32_t nxge_no_link_notify;
extern boolean_t nxge_no_msg;
extern uint32_t nxge_lb_dbg;
extern nxge_os_mutex_t nxge_mdio_lock;
extern nxge_os_mutex_t nxge_mii_lock;
extern boolean_t nxge_jumbo_enable;
typedef enum {
/*
* Ethernet broadcast address definition.
*/
static ether_addr_st etherbroadcastaddr =
{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
/*
* Ethernet zero address definition.
*/
static ether_addr_st etherzeroaddr =
{{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
/*
* Supported chip types
*/
#define NUM_CLAUSE_45_IDS (sizeof (nxge_supported_cl45_ids) / \
sizeof (uint32_t))
#define NUM_CLAUSE_22_IDS (sizeof (nxge_supported_cl22_ids) / \
sizeof (uint32_t))
/*
* static functions
*/
static void nxge_bcm5464_link_led_off(p_nxge_t);
/*
* xcvr tables for supported transceivers
*/
static nxge_xcvr_table_t nxge_n2_10G_table = {
};
static nxge_xcvr_table_t nxge_n2_1G_table = {
0
};
static nxge_xcvr_table_t nxge_10G_fiber_table = {
};
static nxge_xcvr_table_t nxge_1G_copper_table = {
NULL,
};
static nxge_xcvr_table_t nxge_1G_fiber_table = {
0
};
static nxge_xcvr_table_t nxge_10G_copper_table = {
NULL,
NULL,
NULL,
NULL,
0
};
#ifdef NXGE_DEBUG
static void nxge_mii_dump(p_nxge_t);
#endif
{
char *phy_type;
char *prop_val;
/* Get property from the driver conf. file */
"found conf file: phy-type %s", prop_val));
"found: 10G Serdes"));
}
"phy-type", prop_val);
"Got phy type [0x%x] from conf file",
return (NXGE_OK);
}
/*
* TODO add MDIO support for Monza RTM card, Glendale (also Goa) -
* only N2-NIU
*/
"10G Fiber Xcvr"));
"1G Copper Xcvr"));
"1G Fiber Xcvr"));
"10G Copper Xcvr"));
"OBP: 10G Serdes"));
"OBP: 1G Serdes"));
} else {
"Unknown phy-type: %s", prop_val));
return (NXGE_ERROR);
}
(void) ddi_prop_update_string(DDI_DEV_T_NONE,
"Got phy type [0x%x] from OBP",
return (status);
} else {
"Exiting...phy-type property not found"));
return (NXGE_ERROR);
}
}
return (NXGE_OK);
}
goto read_seeprom;
}
"Reading phy type from expansion ROM"));
/*
* Try to read the phy type from the vpd data read off the
* expansion ROM.
*/
} else {
"nxge_get_xcvr_type: Unknown phy type [%c%c%c] in EEPROM",
goto read_seeprom;
}
return (status);
/*
* read the phy type from the SEEPROM - NCR registers
*/
"Failed to get phy type"));
}
return (status);
}
/* Set up the PHY specific values. */
{
uint32_t pma_pmd_id = 0;
portn));
case N2_NIU:
case PORT_1G_FIBER:
case PORT_1G_SERDES:
"Serdes"));
break;
case PORT_10G_FIBER:
case PORT_10G_SERDES:
"Serdes"));
break;
default:
"<== nxge_setup_xcvr_table: "
"Unable to determine NIU portmode"));
return (NXGE_ERROR);
}
break;
default:
/*
* Would be the case for platforms like Maramba
* in which the phy type could not be got from conf
* file, OBP, VPD or Serial PROM.
*/
if (!NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
"<== nxge_setup_xcvr_table:"
" Invalid Neptune type [0x%x]",
return (NXGE_ERROR);
}
switch (port_type) {
case NXGE_PORT_1G_COPPER:
break;
case NXGE_PORT_10G_COPPER:
break;
case NXGE_PORT_1G_FIBRE:
break;
case NXGE_PORT_10G_FIBRE:
break;
case NXGE_PORT_1G_SERDES:
break;
case NXGE_PORT_10G_SERDES:
break;
case NXGE_PORT_1G_RGMII_FIBER:
break;
default:
"<== nxge_setup_xcvr_table: "
"Unknown port-type: 0x%x", port_type));
return (NXGE_ERROR);
}
}
case PORT_1G_COPPER:
case PORT_1G_RGMII_FIBER:
/*
* For Altas 4-1G copper, Xcvr port numbers are
* swapped with ethernet port number. This is
* designed for better signal integrity in
* routing. This is also the case for the
* on-board Neptune copper ports on the Maramba
* platform.
*/
switch (nxgep->platform_type) {
case P_NEPTUNE_MARAMBA_P1:
break;
case P_NEPTUNE_MARAMBA_P0:
break;
default:
break;
}
/*
* For Altas 4-1G copper, Xcvr port numbers are
* swapped with ethernet port number. This is
* designed for better signal integrity in
* routing. This is also the case for the
* on-board Neptune copper ports on the Maramba
* platform.
*/
switch (nxgep->platform_type) {
case P_NEPTUNE_ATLAS_4PORT:
case P_NEPTUNE_MARAMBA_P0:
case P_NEPTUNE_MARAMBA_P1:
switch (portn) {
case 0:
break;
case 1:
break;
case 2:
break;
case 3:
break;
default:
return (NXGE_ERROR);
}
break;
case P_NEPTUNE_ALONSO:
/*
* The Alonso Neptune, xcvr port numbers for
* ports 2 and 3 are not swapped. Port 2 has
* the BCM5464_PORT_BASE_ADDR and port 3 has
* next address.
*/
if (portn == 3) {
}
break;
default:
break;
}
"Copper" : "RGMII Fiber"));
break;
case PORT_10G_COPPER:
break;
case PORT_1G_FIBER:
case PORT_1G_SERDES:
"Fiber" : "Serdes"));
break;
case PORT_10G_FIBER:
case PORT_10G_SERDES:
switch (nxgep->platform_type) {
case P_NEPTUNE_MARAMBA_P0:
case P_NEPTUNE_MARAMBA_P1:
/*
* Switch off LED for corresponding copper
* port
*/
break;
default:
break;
}
"Fiber" : "Serdes"));
break;
default:
"Unknown port-type: 0x%x", port_type));
return (NXGE_ERROR);
}
}
/*
* Get the actual device ID value returned by MDIO read.
*/
} else {
} else {
}
}
}
nxgep->platform_type));
return (status);
}
/* Initialize the entire MAC and physical layer */
{
/* Initialize XIF to configure a network mode */
goto fail;
}
goto fail;
}
/* Initialize TX and RX MACs */
/*
* Always perform XIF init first, before TX and RX MAC init
*/
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
/* The Neptune Serdes needs to be reinitialized again */
if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) &&
"nxge_mac_init: reinit Neptune 1G Serdes "));
goto fail;
}
}
return (NXGE_OK);
fail:
"nxge_mac_init: failed to initialize MAC port<%d>",
portn));
return (status);
}
/* Initialize the Ethernet Link */
{
#ifdef NXGE_DEBUG
#endif
(portmode != PORT_1G_SERDES)) {
/* Workaround to get link up in both NIU ports */
goto fail;
}
}
NXGE_DELAY(200000);
/* Initialize internal serdes */
goto fail;
NXGE_DELAY(200000);
goto fail;
return (NXGE_OK);
fail:
"nxge_link_init: ",
"failed to initialize Ethernet link on port<%d>",
portn));
return (status);
}
/* Initialize the XIF sub-block within the MAC */
{
if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) &&
"nxge_xcvr_init: set ATCA mode"));
}
if (portt == PORT_TYPE_XMAC) {
/* Setup XIF Configuration for XMAC */
if ((portmode == PORT_10G_FIBER) ||
(portmode == PORT_10G_COPPER) ||
(portmode == PORT_10G_SERDES))
if (portmode == PORT_1G_COPPER) {
}
/* Set MAC Internal Loopback if necessary */
if ((portmode == PORT_10G_FIBER) ||
(portmode == PORT_10G_SERDES)) {
} else {
}
}
if (rs != NPI_SUCCESS)
goto fail;
/* Set Port Mode */
if ((portmode == PORT_10G_FIBER) ||
(portmode == PORT_10G_COPPER) ||
(portmode == PORT_10G_SERDES)) {
MAC_XGMII_MODE, rs);
if (rs != NPI_SUCCESS)
goto fail;
goto fail;
} else {
goto fail;
}
} else if ((portmode == PORT_1G_FIBER) ||
(portmode == PORT_1G_COPPER) ||
(portmode == PORT_1G_SERDES) ||
(portmode == PORT_1G_RGMII_FIBER)) {
"nxge_xif_init: Port[%d] Mode[%d] Speed[%d]",
MAC_GMII_MODE, rs);
} else {
MAC_MII_MODE, rs);
}
if (rs != NPI_SUCCESS)
goto fail;
} else {
"nxge_xif_init: Unknown port mode (%d)"
goto fail;
}
/* Enable ATCA mode */
} else if (portt == PORT_TYPE_BMAC) {
/* Setup XIF Configuration for BMAC */
if ((portmode == PORT_1G_COPPER) ||
(portmode == PORT_1G_RGMII_FIBER)) {
}
if (rs != NPI_SUCCESS)
goto fail;
}
return (NXGE_OK);
fail:
"nxge_xif_init: Failed to initialize XIF port<%d>",
portn));
return (NXGE_ERROR | rs);
}
/* Initialize the PCS sub-block in the MAC */
{
goto fail;
}
/* Initialize port's PCS */
"==> nxge_pcs_init: (1G) port<%d> write config 0x%llx",
} else if ((portmode == PORT_10G_FIBER) ||
/* Use internal XPCS, bypass 1G PCS */
val &= ~XMAC_XIF_XPCS_BYPASS;
goto fail;
/* Set XPCS Internal Loopback if necessary */
XPCS_REG_CONTROL1, &val))
!= NPI_SUCCESS)
goto fail;
val |= XPCS_CTRL1_LOOPBK;
else
val &= ~XPCS_CTRL1_LOOPBK;
!= NPI_SUCCESS)
goto fail;
/* Clear descw errors */
!= NPI_SUCCESS)
goto fail;
/* Clear symbol errors */
!= NPI_SUCCESS)
goto fail;
!= NPI_SUCCESS)
goto fail;
} else if ((portmode == PORT_1G_COPPER) ||
(portmode == PORT_1G_RGMII_FIBER)) {
"==> nxge_pcs_init: (1G) copper port<%d>", portn));
if (portn < 4) {
}
goto fail;
} else {
goto fail;
}
pass:
return (NXGE_OK);
fail:
"nxge_pcs_init: Failed to initialize PCS port<%d>",
portn));
return (NXGE_ERROR | rs);
}
/* Initialize the Internal Serdes */
{
#ifdef NXGE_DEBUG
#endif
#ifdef NXGE_DEBUG
"==> nxge_serdes_init port<%d>", portn));
#endif
goto fail;
}
portn));
return (NXGE_OK);
fail:
"nxge_serdes_init: Failed to initialize serdes for port<%d>",
portn));
return (status);
}
/* Initialize the TI Hedwig Internal Serdes (N2-NIU only) */
static nxge_status_t
{
int chan;
#ifdef NXGE_DEBUG
#endif
portn));
/* 0x0E01 */
/* 0x9101 */
/* 0x0008 */
/* Set loopback mode if necessary */
!= NXGE_OK)
goto fail;
}
/* Use default PLL value */
/* 0x0E21 */
/* 0x9121 */
if (portn == 0) {
/* 0x8 */
}
/* MPY = 0x100 */
/* Set PLL */
!= NXGE_OK)
goto fail;
goto fail;
#ifdef NXGE_DEBUG
"==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)",
"==> nxge_n2_serdes_init port<%d>: PLL sts.l 0x%x (0x%x)",
#endif
/* Set loopback mode if necessary */
"==> nxge_n2_serdes_init port<%d>: loopback 0x%x",
goto fail;
}
}
} else {
goto fail;
}
/* MIF_REG_WR(handle, MIF_MASK_REG, ~mask); */
NXGE_DELAY(20);
/* init TX channels */
!= NXGE_OK)
goto fail;
!= NXGE_OK)
goto fail;
"==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_l 0x%x",
"==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_h 0x%x",
}
/* init RX channels */
!= NXGE_OK)
goto fail;
!= NXGE_OK)
goto fail;
"==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_l 0x%x",
"==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_h 0x%x",
}
portn));
return (NXGE_OK);
fail:
"nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>",
portn));
return (status);
}
/* Initialize the Neptune Internal Serdes for 10G (Neptune only) */
static nxge_status_t
{
int chan;
return (NXGE_OK);
"==> nxge_neptune_10G_serdes_init port<%d>", portn));
switch (portn) {
case 0:
(0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
(0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
(0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
(0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
(0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
(0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
(0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
(0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
(0x1 << ESR_CTL_LOSADJ_3_SHIFT));
/* Set Serdes0 Internal Loopback if necessary */
} else {
}
break;
case 1:
(0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
(0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
(0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
(0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
(0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
(0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
(0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
(0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
(0x1 << ESR_CTL_LOSADJ_3_SHIFT));
/* Set Serdes1 Internal Loopback if necessary */
} else {
}
break;
default:
/* Nothing to do here */
goto done;
}
/* init TX RX channels */
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
}
/* Apply Tx core reset */
goto fail;
goto fail;
NXGE_DELAY(200);
/* Apply Rx core reset */
goto fail;
NXGE_DELAY(200);
goto fail;
NXGE_DELAY(200);
goto fail;
goto fail;
"Failed to reset port<%d> XAUI Serdes "
"(val16l 0x%x val16h 0x%x)",
}
if (portn == 0) {
if ((val & ESR_SIG_P0_BITS_MASK) !=
goto fail;
}
} else if (portn == 1) {
if ((val & ESR_SIG_P1_BITS_MASK) !=
goto fail;
}
}
done:
"<== nxge_neptune_10G_serdes_init port<%d>", portn));
return (NXGE_OK);
fail:
"nxge_neptune_10G_serdes_init: "
"Failed to initialize Neptune serdes for port<%d>", portn));
return (status);
}
/* Initialize Neptune Internal Serdes for 1G (Neptune only) */
static nxge_status_t
{
int chan;
"==> nxge_1G_serdes_init port<%d>", portn));
switch (portn) {
case 0:
/* Assert the reset register */
val |= ESR_RESET_0;
/* Set the PLL register to 0x79 */
/* Set the control register to 0x249249f */
/* Set Serdes0 Internal Loopback if necessary */
/* Set pad loopback modes 0xaa */
} else {
}
/* Deassert the reset register */
val &= ~ESR_RESET_0;
break;
case 1:
/* Assert the reset register */
val |= ESR_RESET_1;
/* Set PLL register to 0x79 */
/* Set the control register to 0x249249f */
/* Set Serdes1 Internal Loopback if necessary */
/* Set pad loopback mode 0xaa */
} else {
}
/* Deassert the reset register */
val &= ~ESR_RESET_1;
break;
default:
/* Nothing to do here */
goto done;
}
/* init TX RX channels */
goto fail;
}
goto fail;
}
goto fail;
}
goto fail;
}
goto fail;
}
goto fail;
}
goto fail;
}
goto fail;
}
}
goto fail;
}
goto fail;
}
goto fail;
}
goto fail;
}
/* Apply Tx core reset */
goto fail;
}
NXGE_OK) {
goto fail;
}
NXGE_DELAY(200);
/* Apply Rx core reset */
NXGE_OK) {
goto fail;
}
NXGE_DELAY(200);
goto fail;
}
NXGE_DELAY(200);
goto fail;
}
goto fail;
}
"Failed to reset port<%d> XAUI Serdes "
status = NXGE_ERROR;
goto fail;
}
NXGE_DELAY(200);
"nxge_neptune_serdes_init: read internal signal reg port<%d> "
if (portn == 0) {
if ((val & ESR_SIG_P0_BITS_MASK_1G) !=
"nxge_neptune_serdes_init: "
"Failed to get Serdes up for port<%d> val 0x%x",
status = NXGE_ERROR;
goto fail;
}
} else if (portn == 1) {
if ((val & ESR_SIG_P1_BITS_MASK_1G) !=
"nxge_neptune_serdes_init: "
"Failed to get Serdes up for port<%d> val 0x%x",
status = NXGE_ERROR;
goto fail;
}
}
done:
"<== nxge_1G_serdes_init port<%d>", portn));
return (NXGE_OK);
fail:
"nxge_1G_serdes_init: "
"Failed to initialize Neptune serdes for port<%d>",
portn));
return (status);
}
/* Initialize the 10G (BCM8704) Transceiver */
static nxge_status_t
{
#ifdef NXGE_DEBUG
#endif
#ifdef NXGE_DEBUG
#endif
portn));
goto done;
}
/* Disable Link LEDs */
goto fail;
/* Set Clause 45 */
/* Reset the transceiver */
goto fail;
goto fail;
do {
drv_usecwait(500);
goto fail;
delay++;
if (delay == 100) {
"failed to reset Transceiver on port<%d>", portn));
status = NXGE_ERROR;
goto fail;
}
/* Set to 0x7FBF */
!= NXGE_OK)
goto fail;
/* Set to 0x164 */
goto fail;
/*
* According to Broadcom's instruction, SW needs to read
* back these registers twice after written.
*/
!= NXGE_OK)
goto fail;
!= NXGE_OK)
goto fail;
!= NXGE_OK)
goto fail;
!= NXGE_OK)
goto fail;
/* Enable Tx and Rx LEDs to be driven by traffic */
goto fail;
goto fail;
NXGE_DELAY(1000000);
/* Set BCM8704 Internal Loopback mode if necessary */
!= NXGE_OK)
goto fail;
else
!= NXGE_OK)
goto fail;
goto fail;
goto fail;
goto fail;
#ifdef NXGE_DEBUG
/* Diagnose link issue if link is not up */
&val);
goto fail;
&val);
goto fail;
&val1);
goto fail;
&val1);
goto fail;
if (val != 0x3FC) {
"Cable not connected to peer or bad"
" cable on port<%d>\n", portn));
} else if (val == 0x639C) {
"Optical module (XFP) is bad or absent"
" on port<%d>\n", portn));
}
}
#endif
done:
portn));
return (NXGE_OK);
fail:
"nxge_10G_xcvr_init: failed to initialize transceiver for "
"port<%d>", portn));
return (status);
}
/* Initialize the 1G copper (BCM 5464) Transceiver */
static nxge_status_t
{
goto done;
}
/* Set Clause 22 */
/* Set capability flags */
}
done:
return (status);
}
/* Initialize transceiver */
{
#ifdef NXGE_DEBUG
#endif
#ifdef NXGE_DEBUG
#endif
/*
* Initialize the xcvr statistics.
*/
/*
* Initialize the link statistics.
*/
goto fail;
}
portn));
return (NXGE_OK);
fail:
"nxge_xcvr_init: failed to initialize transceiver for port<%d>",
portn));
return (status);
}
/* Look for transceiver type */
{
return (NXGE_ERROR);
return (NXGE_ERROR);
return (NXGE_OK);
}
/* Initialize the TxMAC sub-block */
{
portn));
/* Set Max and Min Frame Size */
} else {
}
if (rs != NPI_SUCCESS)
goto fail;
else
if (portt == PORT_TYPE_XMAC) {
0)) != NPI_SUCCESS)
goto fail;
if ((portmode == PORT_10G_FIBER) ||
(portmode == PORT_10G_COPPER) ||
(portmode == PORT_10G_SERDES)) {
if (rs != NPI_SUCCESS)
goto fail;
} else {
if (rs != NPI_SUCCESS)
goto fail;
}
goto fail;
!= NPI_SUCCESS)
goto fail;
} else {
0)) != NPI_SUCCESS)
goto fail;
rs);
if (rs != NPI_SUCCESS)
goto fail;
if (rs != NPI_SUCCESS)
goto fail;
goto fail;
}
portn));
return (NXGE_OK);
fail:
"nxge_tx_mac_init: failed to initialize port<%d> TXMAC",
portn));
return (NXGE_ERROR | rs);
}
/* Initialize the RxMAC sub-block */
{
uint32_t i;
portn));
rs);
if (rs != NPI_SUCCESS)
goto fail;
if (rs != NPI_SUCCESS)
goto fail;
if (rs != NPI_SUCCESS)
goto fail;
/*
* Load the multicast hash filter bits.
*/
for (i = 0; i < MAC_MAX_HASH_ENTRY; i++) {
if (hash_filter != NULL) {
(NMCFILTER_REGS - 1) - i];
} else {
hashtab_e = 0;
}
goto fail;
}
if (portt == PORT_TYPE_XMAC) {
0)) != NPI_SUCCESS)
goto fail;
(void) nxge_fflp_init_hostinfo(nxgep);
xconfig)) != NPI_SUCCESS)
goto fail;
/* Comparison of mac unique address is always enabled on XMAC */
!= NPI_SUCCESS)
goto fail;
} else {
(void) nxge_fflp_init_hostinfo(nxgep);
0) != NPI_SUCCESS)
goto fail;
bconfig)) != NPI_SUCCESS)
goto fail;
/* Always enable comparison of mac unique address */
!= NPI_SUCCESS)
goto fail;
}
portn));
return (NXGE_OK);
fail:
"nxge_rx_mac_init: Failed to Initialize port<%d> RxMAC",
portn));
return (NXGE_ERROR | rs);
}
/* Enable TXMAC */
{
goto fail;
/* based on speed */
CFG_XMAC_TX)) != NPI_SUCCESS)
goto fail;
} else {
CFG_BMAC_TX)) != NPI_SUCCESS)
goto fail;
}
return (NXGE_OK);
fail:
"nxgep_tx_mac_enable: Failed to enable port<%d> TxMAC",
if (rs != NPI_SUCCESS)
return (NXGE_ERROR | rs);
else
return (status);
}
/* Disable TXMAC */
{
goto fail;
} else {
goto fail;
}
return (NXGE_OK);
fail:
"nxge_tx_mac_disable: Failed to disable port<%d> TxMAC",
return (NXGE_ERROR | rs);
}
/* Enable RXMAC */
{
portn));
goto fail;
CFG_XMAC_RX)) != NPI_SUCCESS)
goto fail;
} else {
CFG_BMAC_RX)) != NPI_SUCCESS)
goto fail;
}
portn));
return (NXGE_OK);
fail:
"nxgep_rx_mac_enable: Failed to enable port<%d> RxMAC",
portn));
if (rs != NPI_SUCCESS)
return (NXGE_ERROR | rs);
else
return (status);
}
/* Disable RXMAC */
{
portn));
CFG_XMAC_RX)) != NPI_SUCCESS)
goto fail;
} else {
CFG_BMAC_RX)) != NPI_SUCCESS)
goto fail;
}
portn));
return (NXGE_OK);
fail:
"nxgep_rx_mac_disable: ",
"Failed to disable port<%d> RxMAC",
portn));
return (NXGE_ERROR | rs);
}
/* Reset TXMAC */
{
portn));
!= NPI_SUCCESS)
goto fail;
} else {
!= NPI_SUCCESS)
goto fail;
}
portn));
return (NXGE_OK);
fail:
"nxge_tx_mac_reset: Failed to Reset TxMAC port<%d>",
portn));
return (NXGE_ERROR | rs);
}
/* Reset RXMAC */
{
portn));
!= NPI_SUCCESS)
goto fail;
} else {
!= NPI_SUCCESS)
goto fail;
}
portn));
return (NXGE_OK);
fail:
"nxge_rx_mac_reset: Failed to Reset RxMAC port<%d>",
portn));
return (NXGE_ERROR | rs);
}
/* 10G fiber link interrupt start routine */
static nxge_status_t
{
if (rs != NPI_SUCCESS)
return (NXGE_ERROR | rs);
else
return (NXGE_OK);
}
/* 10G fiber link interrupt stop routine */
static nxge_status_t
{
if (rs != NPI_SUCCESS)
return (NXGE_ERROR | rs);
else
return (NXGE_OK);
}
/* 1G fiber link interrupt start routine */
static nxge_status_t
{
if (rs != NPI_SUCCESS)
return (NXGE_ERROR | rs);
else
return (NXGE_OK);
}
/* 1G fiber link interrupt stop routine */
static nxge_status_t
{
if (rs != NPI_SUCCESS)
return (NXGE_ERROR | rs);
else
return (NXGE_OK);
}
/* 1G copper link interrupt start routine */
static nxge_status_t
{
if (rs != NPI_SUCCESS)
return (NXGE_ERROR | rs);
else
return (NXGE_OK);
}
/* 1G copper link interrupt stop routine */
static nxge_status_t
{
if (rs != NPI_SUCCESS)
return (NXGE_ERROR | rs);
else
return (NXGE_OK);
}
{
return (NXGE_OK);
if (enable == LINK_INTR_START)
else if (enable == LINK_INTR_STOP)
goto fail;
return (NXGE_OK);
fail:
"nxge_link_intr: Failed to set port<%d> mif intr mode",
portn));
return (status);
}
/* Initialize 1G Fiber / Copper transceiver using Clause 22 */
{
/*
* The mif phy mode may be connected to either a copper link
* or fiber link. Read the mode control register to get the fiber
* configuration if it is hard-wired to fiber link.
*/
(void) nxge_mii_get_link_mode(nxgep);
return (nxge_mii_xcvr_fiber_init(nxgep));
}
/*
* Reset the transceiver.
*/
delay = 0;
#if defined(__i386)
#else
#endif
goto fail;
do {
drv_usecwait(500);
#if defined(__i386)
#else
#endif
!= NXGE_OK)
goto fail;
delay++;
if (delay == 1000) {
goto fail;
}
#if defined(__i386)
#else
#endif
goto fail;
/*
* Initialize the xcvr statistics.
*/
/*
* Initialise the xcvr advertised capability statistics.
*/
/*
* Check for extended status just in case we're
* running a Gigibit phy.
*/
#if defined(__i386)
#else
#endif
!= NXGE_OK)
goto fail;
} else {
}
/*
* Initialize 1G Statistics once the capability is established.
*/
/*
* Initialise the link statistics.
*/
/*
* Switch off Auto-negotiation, 100M and full duplex.
*/
#if defined(__i386)
#else
#endif
goto fail;
} else {
}
bcm5464r_aux.value = 0;
!= NXGE_OK)
goto fail;
}
"Restarting Auto-negotiation."));
/*
* Setup our Auto-negotiation advertisement register.
*/
}
#if defined(__i386)
#else
#endif
!= NXGE_OK)
goto fail;
#if defined(__i386)
#else
#endif
!= NXGE_OK)
goto fail;
}
} else {
#if defined(__i386)
#else
#endif
!= NXGE_OK)
goto fail;
} else
} else
} else {
} else
}
}
/* BCM5464R 1000mbps external loopback mode */
#if defined(__i386)
#else
#endif
!= NXGE_OK)
goto fail;
== nxge_lb_ext100) {
/* BCM5464R 100mbps external loopback mode */
== nxge_lb_ext10) {
/* BCM5464R 10mbps external loopback mode */
}
}
}
#if defined(__i386)
#else
#endif
goto fail;
#if defined(__i386)
#else
#endif
goto fail;
/*
* Initialize the xcvr status kept in the context structure.
*/
#if defined(__i386)
#else
#endif
goto fail;
fail:
"<== nxge_mii_xcvr_init status 0x%x", status));
return (status);
}
{
"nxge_mii_xcvr_fiber_init: "
/*
* Reset the transceiver.
*/
delay = 0;
#if defined(__i386)
goto fail;
#else
goto fail;
#endif
do {
drv_usecwait(500);
#if defined(__i386)
!= NXGE_OK)
goto fail;
#else
!= NXGE_OK)
goto fail;
#endif
delay++;
if (delay == 1000) {
goto fail;
}
#if defined(__i386)
goto fail;
#else
goto fail;
#endif
/*
* Initialize the xcvr statistics.
*/
/*
* Initialize the xcvr advertised capability statistics.
*/
/*
* Check for extended status just in case we're
* running a Gigibit phy.
*/
#if defined(__i386)
goto fail;
#else
goto fail;
#endif
} else {
}
/*
* Initialize 1G Statistics once the capability is established.
*/
/*
* Initialize the link statistics.
*/
/*
* Switch off Auto-negotiation, 100M and full duplex.
*/
#if defined(__i386)
goto fail;
#else
goto fail;
#endif
} else {
}
bcm5464r_aux.value = 0;
goto fail;
}
/* BCM5464R 1000mbps external loopback mode */
#if defined(__i386)
goto fail;
#else
goto fail;
#endif
}
#if defined(__i386)
goto fail;
#else
goto fail;
#endif
"nxge_mii_xcvr_fiber_init: value wrote bmcr = 0x%x",
#if defined(__i386)
goto fail;
#else
goto fail;
#endif
/*
* Initialize the xcvr status kept in the context structure.
*/
#if defined(__i386)
goto fail;
#else
goto fail;
#endif
"<== nxge_mii_xcvr_fiber_init status 0x%x", status));
return (status);
fail:
"<== nxge_mii_xcvr_fiber_init status 0x%x", status));
return (status);
}
/* Read from a MII compliant register */
{
goto fail;
goto fail;
} else
goto fail;
"xcvr_reg<%d> value=0x%x",
return (NXGE_OK);
fail:
"nxge_mii_read: Failed to read mii on xcvr %d",
xcvr_portn));
return (NXGE_ERROR | rs);
}
/* Write to a MII compliant Register */
{
value));
goto fail;
goto fail;
} else
goto fail;
return (NXGE_OK);
fail:
"nxge_mii_write: Failed to write mii on xcvr %d",
xcvr_portn));
return (NXGE_ERROR | rs);
}
/* Perform read from Clause45 serdes / transceiver device */
{
xcvr_portn));
goto fail;
xcvr_portn));
return (NXGE_OK);
fail:
"nxge_mdio_read: Failed to read mdio on xcvr %d",
xcvr_portn));
return (NXGE_ERROR | rs);
}
/* Perform write to Clause45 serdes / transceiver device */
{
xcvr_portn));
goto fail;
xcvr_portn));
return (NXGE_OK);
fail:
"nxge_mdio_write: Failed to write mdio on xcvr %d",
xcvr_portn));
return (NXGE_ERROR | rs);
}
/* Check MII to see if there is any link status change */
{
"==> nxge_mii_check bmsr 0x%x bmsr_int 0x%x",
"==> nxge_mii_check (link up) bmsr 0x%x bmsr_int 0x%x",
"==> nxge_mii_check (link up) soft bmsr 0x%x bmsr_int "
} else {
"Link down cable problem"));
*link_up = LINK_IS_DOWN;
}
}
else
}
}
} else
"==> nxge_mii_check "
"(auto negotiation complete or link up) "
"soft bmsr 0x%x bmsr_int 0x%x",
#if defined(__i386)
#else
#endif
goto fail;
#if defined(__i386)
#else
#endif
goto fail;
#if defined(__i386)
#else
#endif
goto fail;
#if defined(__i386)
#else
#endif
!= NXGE_OK)
goto fail;
} else if (
}
}
} else {
goto fail;
}
}
== 1))
= 0;
else
= 1;
else
}
}
*link_up = LINK_IS_UP;
}
if (nxgep->link_notify) {
}
return (NXGE_OK);
fail:
"nxge_mii_check: Unable to check MII"));
return (status);
}
/* Check PCS to see if there is any link status change */
{
if (linkup) {
if (nxgep->link_notify ||
*link_up = LINK_IS_UP;
}
} else {
if (nxgep->link_notify ||
*link_up = LINK_IS_DOWN;
}
}
return (NXGE_OK);
fail:
"nxge_pcs_check: Unable to check PCS"));
return (status);
}
/* Add a multicast address entry into the HW hash table */
{
uint_t j;
"Allocating hash filter storage."));
KM_SLEEP);
}
j = mchash / HASH_REG_WIDTH;
}
if (rx_init) {
goto fail;
goto fail;
}
return (NXGE_OK);
fail:
"Unable to add multicast address"));
return (status);
}
/* Remove a multicast address entry from the HW hash table */
{
uint_t j;
"Hash filter already de_allocated."));
return (NXGE_OK);
}
j = mchash / HASH_REG_WIDTH;
}
if (hash_filter->hash_ref_cnt == 0) {
"De-allocating hash filter storage."));
}
if (rx_init) {
goto fail;
goto fail;
}
return (NXGE_OK);
fail:
"Unable to remove multicast address"));
return (status);
}
/* Set MAC address into MAC address HW registers */
{
/*
* Exit if the address is same as ouraddr or multicast or broadcast
*/
goto nxge_set_mac_addr_exit;
}
/*
* Set new interface local address and re-init device.
* This is destructive to any other streams attached
* to this device.
*/
goto fail;
goto fail;
goto nxge_set_mac_addr_end;
return (NXGE_OK);
fail:
"Unable to set mac address"));
return (status);
}
static
{
/* If the poll has been cancelled, return STOP. */
nxge->nxge_link_poll_timerid = 0;
"nxge_check_%s_link(port<%d>) stopped.",
return (CHECK_LINK_STOP);
}
return (CHECK_LINK_RESCHEDULE);
}
/* Check status of MII (MIF or PCS) link */
static nxge_status_t
{
return (NXGE_ERROR);
return (NXGE_OK);
portn));
goto nxge_check_mii_link_exit;
default:
#if defined(__i386)
#else
#endif
goto fail;
}
"==> nxge_check_mii_link port<0x%x> "
"RIGHT AFTER READ bmsr_data 0x%x (nxgep->bmsr 0x%x ",
#if defined(__i386)
#else
#endif
goto fail;
#if defined(__i386)
#else
#endif
goto fail;
}
}
}
/* Workaround for link down issue */
goto nxge_check_mii_link_exit;
}
"==> nxge_check_mii_link port<0x%x> :"
"BEFORE BMSR ^ nxgep->bmsr 0x%x bmsr_data 0x%x",
"==> nxge_check_mii_link port<0x%x> CALLING "
"bmsr_data 0x%x bmsr_ints.value 0x%x",
goto fail;
}
break;
case PORT_1G_SERDES:
"==> nxge_check_mii_link port<%d> (SERDES)", portn));
!= NXGE_OK) {
goto fail;
}
break;
}
if (link_up == LINK_IS_UP) {
} else if (link_up == LINK_IS_DOWN) {
}
portn));
return (NXGE_OK);
fail:
"nxge_check_mii_link: Failed to check link port<%d>",
portn));
return (status);
}
/*ARGSUSED*/
static nxge_status_t
{
return (NXGE_ERROR);
return (NXGE_OK);
val = 0;
rs = NPI_SUCCESS;
portn));
default:
goto fail;
break;
case PORT_10G_SERDES:
XPCS_REG_STATUS1, &val);
if (rs != 0)
goto fail;
if (val & XPCS_STATUS1_RX_LINK_STATUS_UP) {
}
"==> nxge_check_10g_link port<%d> "
"XPCS_REG_STATUS1 0x%x xpcs_up %d",
/*
* Read the xMAC internal signal 2 register.
* This register should be the superset of the XPCS when wanting
* to get the link status. If this register read is proved to be
* reliable, there is no need to read the XPCS register.
*/
}
"==> nxge_check_10g_link port<%d> "
"XMAC_INTERN2_REG 0x%x xmac_up %d",
}
break;
}
if (link_up) {
if (nxgep->link_notify ||
goto fail;
}
} else {
if (nxgep->link_notify ||
goto fail;
"Link down cable problem"));
}
}
portn));
return (NXGE_OK);
fail:
(void) nxge_check_link_stop(nxgep);
"nxge_check_10g_link: Failed to check link port<%d>",
portn));
return (status);
}
/* Declare link down */
void
{
char link_stat_msg[64];
if (nxge_no_msg == B_FALSE) {
}
}
/* Declare link up */
void
{
char link_stat_msg[64];
else
(void) nxge_xif_init(nxgep);
/* Clean up symbol errors incurred during link transition */
}
if (nxge_no_msg == B_FALSE) {
}
}
/*
* Calculate the bit in the multicast address filter
* that selects the given * address.
* Note: For GEM, the last 8-bits are used.
*/
{
uint32_t c;
int byte;
int bit;
else
c >>= 1;
}
}
}
/* Reset serdes */
{
drv_usecwait(500);
return (NXGE_OK);
}
/* Monitor link status using interrupt or polling */
{
/*
* Return immediately if this is an imaginary XMAC port.
* (At least, we don't have 4-port XMAC cards yet.)
*/
return (NXGE_OK);
/* stats has not been allocated. */
return (NXGE_OK);
}
/* Don't check link if we're not in internal loopback mode */
return (NXGE_OK);
"==> nxge_link_monitor port<%d> enable=%d",
if (enable == LINK_MONITOR_START) {
!= NXGE_OK)
goto fail;
} else {
return (NXGE_OK);
} else {
return (NXGE_ERROR);
}
}
} else {
!= NXGE_OK)
goto fail;
} else {
/* If <timerid> == 0, the link monitor has */
/* never been started, or just now stopped. */
if (nxgep->nxge_link_poll_timerid == 0) {
return (NXGE_OK);
}
ddi_get_lbolt() +
if (rv == -1) {
"==> stopping port %d: "
"cv_timedwait(%d) timed out",
nxgep->nxge_link_poll_timerid = 0;
}
}
}
"<== nxge_link_monitor port<%d> enable=%d",
return (NXGE_OK);
fail:
return (status);
}
/* Set promiscous mode */
{
goto fail;
}
goto fail;
}
if (on)
else
return (NXGE_OK);
fail:
"Unable to set promisc (%d)", on));
return (status);
}
/*ARGSUSED*/
{
#ifdef NXGE_DEBUG
#endif
#if NXGE_MIF
#endif
#ifdef NXGE_MIF
}
#endif
return (DDI_INTR_CLAIMED);
return (DDI_INTR_UNCLAIMED);
}
/*ARGSUSED*/
{
}
/*
* This interrupt handler is for a specific
* mac port.
*/
"==> nxge_mac_intr: reading mac stats: port<%d>", portn));
(xmac_tx_iconfig_t *)&status);
if (rs != NPI_SUCCESS)
goto npi_fail;
if (status & ICFG_XMAC_TX_ALL) {
if (status & ICFG_XMAC_TX_UNDERRUN) {
}
if (status & ICFG_XMAC_TX_MAX_PACKET_ERR) {
}
if (status & ICFG_XMAC_TX_OVERFLOW) {
}
if (status & ICFG_XMAC_TX_FIFO_XFR_ERR) {
}
if (status & ICFG_XMAC_TX_BYTE_CNT_EXP) {
}
if (status & ICFG_XMAC_TX_FRAME_CNT_EXP) {
}
}
(xmac_rx_iconfig_t *)&status);
if (rs != NPI_SUCCESS)
goto npi_fail;
if (status & ICFG_XMAC_RX_ALL) {
if (status & ICFG_XMAC_RX_OVERFLOW)
if (status & ICFG_XMAC_RX_UNDERFLOW) {
}
if (status & ICFG_XMAC_RX_CRC_ERR_CNT_EXP) {
}
if (status & ICFG_XMAC_RX_LEN_ERR_CNT_EXP) {
}
if (status & ICFG_XMAC_RX_VIOL_ERR_CNT_EXP) {
}
if (status & ICFG_XMAC_RX_OCT_CNT_EXP) {
}
if (status & ICFG_XMAC_RX_HST_CNT1_EXP) {
}
if (status & ICFG_XMAC_RX_HST_CNT2_EXP) {
}
if (status & ICFG_XMAC_RX_HST_CNT3_EXP) {
}
if (status & ICFG_XMAC_RX_HST_CNT4_EXP) {
}
if (status & ICFG_XMAC_RX_HST_CNT5_EXP) {
}
if (status & ICFG_XMAC_RX_HST_CNT6_EXP) {
}
if (status & ICFG_XMAC_RX_BCAST_CNT_EXP) {
}
if (status & ICFG_XMAC_RX_MCAST_CNT_EXP) {
}
if (status & ICFG_XMAC_RX_FRAG_CNT_EXP) {
}
if (status & ICFG_XMAC_RX_ALIGNERR_CNT_EXP) {
}
if (status & ICFG_XMAC_RX_LINK_FLT_CNT_EXP) {
}
if (status & ICFG_XMAC_RX_REMOTE_FLT_DET) {
}
if (status & ICFG_XMAC_RX_LOCAL_FLT_DET) {
}
}
(xmac_ctl_iconfig_t *)&status);
if (rs != NPI_SUCCESS)
goto npi_fail;
if (status & ICFG_XMAC_CTRL_ALL) {
if (status & ICFG_XMAC_CTRL_PAUSE_RCVD)
if (status & ICFG_XMAC_CTRL_PAUSE_STATE)
}
(bmac_tx_iconfig_t *)&status);
if (rs != NPI_SUCCESS)
goto npi_fail;
if (status & ICFG_BMAC_TX_ALL) {
if (status & ICFG_BMAC_TX_UNDERFLOW) {
}
if (status & ICFG_BMAC_TX_MAXPKTSZ_ERR) {
}
if (status & ICFG_BMAC_TX_BYTE_CNT_EXP) {
}
if (status & ICFG_BMAC_TX_FRAME_CNT_EXP) {
}
}
(bmac_rx_iconfig_t *)&status);
if (rs != NPI_SUCCESS)
goto npi_fail;
if (status & ICFG_BMAC_RX_ALL) {
if (status & ICFG_BMAC_RX_OVERFLOW) {
}
if (status & ICFG_BMAC_RX_FRAME_CNT_EXP) {
}
if (status & ICFG_BMAC_RX_CRC_ERR_CNT_EXP) {
}
if (status & ICFG_BMAC_RX_LEN_ERR_CNT_EXP) {
}
}
if (status & ICFG_BMAC_RX_BYTE_CNT_EXP) {
}
if (status & ICFG_BMAC_RX_ALIGNERR_CNT_EXP) {
}
(bmac_ctl_iconfig_t *)&status);
if (rs != NPI_SUCCESS)
goto npi_fail;
if (status & ICFG_BMAC_CTL_ALL) {
if (status & ICFG_BMAC_CTL_RCVPAUSE)
if (status & ICFG_BMAC_CTL_INPAUSE_ST)
}
}
}
return (DDI_INTR_CLAIMED);
return (DDI_INTR_UNCLAIMED);
}
{
#ifdef NXGE_DEBUG_SYMBOL_ERR
#endif
#ifdef NXGE_DEBUG_SYMBOL_ERR
/* Check Device 3 Register Device 3 0xC809 */
if ((val_debug & ~0x200) != 0) {
&val_debug);
}
if (val != 0)
if (val != 0)
if (val != 0)
#endif
/* Check from BCM8704 if 10G link is up or down */
/* Check Device 1 Register 0xA bit0 */
&val1);
goto fail;
/* Check Device 3 Register 0x20 bit0 */
&val2)) != NPI_SUCCESS)
goto fail;
/* Check Device 4 Register 0x18 bit12 */
&val3);
goto fail;
#ifdef NXGE_DEBUG_ALIGN_ERR
/* Temp workaround for link down issue */
if (pcs_blk_lock == B_FALSE) {
if (val2 != 0x4) {
"!LINK DEBUG: port%d PHY Dev3 "
"Reg 0x20 = 0x%x\n",
}
}
if (link_align == B_FALSE) {
if (val3 != 0x140f) {
link_align = B_TRUE;
"!LINK DEBUG: port%d PHY Dev4 "
"Reg 0x18 = 0x%x\n",
}
}
"!LINK DEBUG: port %d Dev3 or Dev4 read zero\n",
}
}
#endif
return (NXGE_OK);
fail:
return (status);
}
{
!= NPI_SUCCESS)
return (NXGE_ERROR);
else
return (NXGE_OK);
}
{
!= NPI_SUCCESS)
return (NXGE_ERROR);
else
return (NXGE_OK);
}
/* Check if the given id read using the given MDIO Clause is supported */
static boolean_t
{
int i;
int cl45_arr_len = NUM_CLAUSE_45_IDS;
int cl22_arr_len = NUM_CLAUSE_22_IDS;
switch (type) {
case CLAUSE_45_TYPE:
for (i = 0; i < cl45_arr_len; i++) {
if ((nxge_supported_cl45_ids[i] & BCM_PHY_ID_MASK) ==
(id & BCM_PHY_ID_MASK)) {
break;
}
}
break;
case CLAUSE_22_TYPE:
for (i = 0; i < cl22_arr_len; i++) {
if ((nxge_supported_cl22_ids[i] & BCM_PHY_ID_MASK) ==
(id & BCM_PHY_ID_MASK)) {
break;
}
}
break;
default:
break;
}
return (found);
}
static uint32_t
{
uint32_t pma_pmd_dev_id = 0;
pma_pmd_dev_id |= val2;
return (pma_pmd_dev_id);
}
static uint32_t
{
uint32_t pcs_dev_id = 0;
pcs_dev_id = val1;
pcs_dev_id |= val2;
return (pcs_dev_id);
}
static uint32_t
{
&val1);
if (npi_status != NPI_SUCCESS) {
"clause 22 read to reg 2 failed!!!"));
goto exit;
}
&val2);
if (npi_status != 0) {
"clause 22 read to reg 3 failed!!!"));
goto exit;
}
exit:
return (phy_id);
}
/*
* Scan the PHY ports 0 through 31 to get the PHY ID using Clause 22 MDIO
* read. Then use the values obtained to determine the phy type of each port
* and the Neptune type.
*/
{
int i, j, k, l;
uint32_t pma_pmd_dev_id = 0;
uint32_t pcs_dev_id = 0;
int prt_id = -1;
"==> nxge_scan_ports_phy: nxge niu_type[0x%x]",
j = k = l = 0;
total_port_fd = total_phy_fd = 0;
/*
* for on chip serdes usages.
*/
for (i = NXGE_EXT_PHY_PORT_ST; i < NXGE_MAX_PHY_PORTS; i++) {
pma_pmd_dev_fd[i] = 1;
if (j < NXGE_PORTS_NEPTUNE) {
j++;
}
} else {
pma_pmd_dev_fd[i] = 0;
}
pcs_dev_fd[i] = 1;
"dev found", i));
if (k < NXGE_PORTS_NEPTUNE) {
port_pcs_dev_id[k] = pcs_dev_id &
k++;
}
} else {
pcs_dev_fd[i] = 0;
}
if (pcs_dev_fd[i] || pma_pmd_dev_fd[i])
port_fd[i] = 1;
else
port_fd[i] = 0;
total_port_fd += port_fd[i];
phy_fd[i] = 1;
"found", i));
if (l < NXGE_PORTS_NEPTUNE) {
l++;
}
} else {
phy_fd[i] = 0;
}
total_phy_fd += phy_fd[i];
}
switch (total_port_fd) {
case 2:
switch (total_phy_fd) {
case 2:
"Unsupported neptune type 1"));
goto error_exit;
case 1:
/* TODO - 2 10G, 1 1G */
"Unsupported neptune type 2 10G, 1 1G"));
goto error_exit;
case 0:
/* 2 10G */
if (((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) &&
((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) &&
/*
* Check the first phy port address against
* the known phy start addresses to determine
* the platform type.
*/
for (i = NXGE_EXT_PHY_PORT_ST;
i < NXGE_MAX_PHY_PORTS; i++) {
if (port_fd[i] == 1)
break;
}
if (i == BCM8704_NEPTUNE_PORT_ADDR_BASE) {
} else {
"Unsupported neptune type 2 - 1"));
goto error_exit;
}
} else {
"Unsupported neptune type 2"));
goto error_exit;
}
break;
case 4:
/* Maramba with 2 XAUI */
if ((((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) &&
((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) &&
((port_phy_id[0] == PHY_BCM5464R_FAMILY) &&
/*
* Check the first phy port address against
* the known phy start addresses to determine
* the platform type.
*/
for (i = NXGE_EXT_PHY_PORT_ST;
i < NXGE_MAX_PHY_PORTS; i++) {
if (phy_fd[i] == 1)
break;
}
if (i == BCM5464_MARAMBA_P0_PORT_ADDR_BASE) {
} else if (i ==
} else {
"Unknown port %d...Cannot "
"determine platform type", i));
goto error_exit;
}
"Maramba with 2 XAUI"));
} else {
"Unsupported neptune type 3"));
goto error_exit;
}
break;
default:
"Unsupported neptune type 5"));
goto error_exit;
}
break;
case 1:
switch (total_phy_fd) {
case 3:
/*
* TODO 3 1G, 1 10G mode.
* Differentiate between 1_1G_1_10G_2_1G and
* 1_10G_3_1G
*/
"Unsupported neptune type 7"));
goto error_exit;
case 2:
/*
* TODO 2 1G, 1 10G mode.
* Differentiate between 1_1G_1_10G_1_1G and
* 1_10G_2_1G
*/
"Unsupported neptune type 8"));
goto error_exit;
case 1:
/*
* TODO 1 1G, 1 10G mode.
* Differentiate between 1_1G_1_10G and
* 1_10G_1_1G
*/
"Unsupported neptune type 9"));
goto error_exit;
case 0:
/* TODO 1 10G mode */
"Unsupported neptune type 10"));
goto error_exit;
case 4:
/* Maramba with 1 XAUI */
if ((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) ||
(port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY)) {
/*
* Check the first phy port address against
* the known phy start addresses to determine
* the platform type.
*/
for (i = NXGE_EXT_PHY_PORT_ST;
i < NXGE_MAX_PHY_PORTS; i++) {
if (phy_fd[i] == 1)
break;
}
if (i == BCM5464_MARAMBA_P0_PORT_ADDR_BASE) {
} else if (i ==
} else {
"Unknown port %d...Cannot "
"determine platform type", i));
goto error_exit;
}
/* The 10G port is BCM8704 */
for (i = NXGE_EXT_PHY_PORT_ST;
i < NXGE_MAX_PHY_PORTS; i++) {
if (port_fd[i] == 1) {
prt_id = i;
break;
}
}
if (prt_id == 0) {
} else if (prt_id == 1) {
} else {
"Unsupported neptune type 11"));
goto error_exit;
}
"Maramba with 1 XAUI"));
} else {
"Unsupported neptune type 12"));
goto error_exit;
}
break;
default:
"Unsupported neptune type 13"));
goto error_exit;
}
break;
case 0:
switch (total_phy_fd) {
case 4:
if ((port_phy_id[0] == PHY_BCM5464R_FAMILY) &&
/*
* Check the first phy port address against
* the known phy start addresses to determine
* the platform type.
*/
for (i = NXGE_EXT_PHY_PORT_ST;
i < NXGE_MAX_PHY_PORTS; i++) {
if (phy_fd[i] == 1)
break;
}
if (i == BCM5464_MARAMBA_P1_PORT_ADDR_BASE) {
} else if (i ==
} else {
"Unknown port %d...Cannot "
"determine platform type", i));
goto error_exit;
}
} else {
"Unsupported neptune type 14"));
goto error_exit;
}
break;
case 3:
/* TODO 3 1G mode */
"Unsupported neptune type 15"));
goto error_exit;
case 2:
/* TODO 2 1G mode */
"Unsupported neptune type 16"));
goto error_exit;
case 1:
/* TODO 1 1G mode */
"Unsupported neptune type 17"));
goto error_exit;
default:
"Unsupported neptune type 18, total phy fd %d",
total_phy_fd));
goto error_exit;
}
break;
default:
"Unsupported neptune type 19"));
goto error_exit;
}
return (status);
return (NXGE_ERROR);
}
{
return (B_FALSE);
else
return (B_TRUE);
}
static void
}
/*
* For Altas 4-1G copper, Xcvr port numbers are
* swapped with ethernet port number. This is
* designed for better signal integrity in routing.
*/
switch (portn) {
case 0:
xcvr_portn += 3;
break;
case 1:
xcvr_portn += 2;
break;
case 2:
xcvr_portn += 1;
break;
case 3:
default:
break;
}
if (rs != NPI_SUCCESS) {
"<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write "
"returned error 0x[%x]", rs));
return;
}
if (rs != NPI_SUCCESS) {
"<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write "
"returned error 0x[%x]", rs));
return;
}
}
static nxge_status_t
{
#if defined(__i386)
goto fail;
#else
goto fail;
#endif
}
#if defined(__i386)
goto fail;
}
#else
goto fail;
}
#endif
"nxge_mii_get_link_mode: fiber mode"));
}
"nxge_mii_get_link_mode: "
"(address 0x%x) port 0x%x mode value 0x%x link mode 0x%x",
"<== nxge_mii_get_link_mode"));
return (status);
fail:
"<== nxge_mii_get_link_mode (failed)"));
return (NXGE_ERROR);
}
#ifdef NXGE_DEBUG
static void
{
#if defined(__i386)
#else
#endif
"nxge_mii_dump: bmcr (0) xcvr 0x%x value 0x%x",
#if defined(__i386)
(void) nxge_mii_read(nxgep,
#else
(void) nxge_mii_read(nxgep,
#endif
"nxge_mii_dump: bmsr (1) xcvr 0x%x value 0x%x",
#if defined(__i386)
(void) nxge_mii_read(nxgep,
#else
(void) nxge_mii_read(nxgep,
#endif
#if defined(__i386)
(void) nxge_mii_read(nxgep,
#else
(void) nxge_mii_read(nxgep,
#endif
"nxge_mii_dump: idr1 (2) xcvr 0x%x value 0x%x",
"nxge_mii_dump: idr2 (3) xcvr 0x%x value 0x%x",
#if defined(__i386)
#else
#endif
"nxge_mii_dump: mode control xcvr 0x%x value 0x%x",
}
#endif