e1000g_main.c revision 47b7744cbea59975a6b583125b7ed1ff2ac45313
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This file is provided under a CDDLv1 license. When using or
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * redistributing this file, you may do so under this license.
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * In redistributing this file this license must be included
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * and no other modification of this header file is permitted.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * CDDL LICENSE SUMMARY
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Copyright(c) 1999 - 2008 Intel Corporation. All rights reserved.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The contents of this file are subject to the terms of Version
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 1.0 of the Common Development and Distribution License (the "License").
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * You should have received a copy of the License with this software.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * You can obtain a copy of the License at
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * See the License for the specific language governing permissions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * and limitations under the License.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Use is subject to license terms of the CDDLv1.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma ident "%Z%%M% %I% %E% SMI"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * **********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Module Name: *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Abstract: *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This file contains the interface routines for the solaris OS. *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * It has all DDI entry point routines and GLD entry point routines. *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This file also contains routines that take care of initialization *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * uninit routine and interrupt routine. *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * **********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char ident[] = "Intel PRO/1000 Ethernet 5.2.4";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char e1000g_string[] = "Intel(R) PRO/1000 Network Connection";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Proto types for DDI entry points
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int e1000g_attach(dev_info_t *, ddi_attach_cmd_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int e1000g_detach(dev_info_t *, ddi_detach_cmd_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * init and intr routines prototype
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void e1000g_intr_work(struct e1000g *, uint32_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma inline(e1000g_intr_work)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic uint32_t e1000g_get_itr(uint32_t, uint32_t, uint32_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma inline(e1000g_get_itr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int e1000g_m_start(void *);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void e1000g_m_stop(void *);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic boolean_t e1000g_m_getcapab(void *, mac_capab_t, void *);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int e1000g_m_unicst_add(void *, mac_multi_addr_t *);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int e1000g_m_unicst_remove(void *, mac_addr_slot_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int e1000g_m_unicst_modify(void *, mac_multi_addr_t *);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int e1000g_m_unicst_get(void *, mac_multi_addr_t *);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int e1000g_m_multicst(void *, boolean_t, const uint8_t *);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void e1000g_m_ioctl(void *, queue_t *, mblk_t *);
static void e1000g_link_timer(void *);
static void e1000g_local_timer(void *);
#ifdef E1000G_DEBUG
#ifdef __sparc
const void *impl_data);
NULL,
#ifdef __sparc
_init(void)
int status;
return (status);
_fini(void)
int status;
if (e1000g_mblks_pending != 0) {
return (EBUSY);
if (e1000g_force_detach) {
sizeof (struct dev_info));
sizeof (private_devi_list_t));
return (status);
int instance;
switch (cmd) {
return (DDI_FAILURE);
case DDI_RESUME:
case DDI_ATTACH:
Adapter =
goto attach_fail;
goto attach_fail;
goto attach_fail;
goto attach_fail;
goto attach_fail;
goto attach_fail;
goto attach_fail;
goto attach_fail;
goto attach_fail;
goto attach_fail;
goto attach_fail;
if (e1000g_force_detach) {
sizeof (struct dev_info));
return (DDI_SUCCESS);
return (DDI_FAILURE);
int err;
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_SUCCESS);
return (DDI_FAILURE);
goto regs_map_fail;
goto regs_map_fail;
goto regs_map_fail;
return (DDI_SUCCESS);
return (DDI_FAILURE);
#ifdef __sparc
return (DDI_FAILURE);
return (DDI_FAILURE);
if (bar64) {
#ifdef __sparc
#ifdef __sparc
if (iommu_pagesize != 0) {
case ETHERMAX:
case FRAME_SIZE_UPTO_4K:
case FRAME_SIZE_UPTO_8K:
case FRAME_SIZE_UPTO_9K:
case FRAME_SIZE_UPTO_16K:
#ifndef NO_82542_SUPPORT
* aligned...so all wiseman boards to have 256 byte aligned
return (DDI_SUCCESS);
switch (cmd) {
return (DDI_FAILURE);
case DDI_SUSPEND:
case DDI_DETACH:
return (DDI_FAILURE);
return (DDI_FAILURE);
if (e1000g_force_detach) {
if (!rx_drain)
return (DDI_FAILURE);
return (DDI_SUCCESS);
if (free_flag) {
sizeof (struct dev_info));
sizeof (private_devi_list_t));
if (free_flag) {
sizeof (struct dev_info));
sizeof (private_devi_list_t));
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_SUCCESS);
return (DDI_FAILURE);
return (DDI_SUCCESS);
goto init_fail;
goto init_fail;
#ifdef __sparc
goto init_fail;
goto init_fail;
goto init_fail;
goto init_fail;
* Configure/Initialize hardware
goto init_fail;
goto init_fail;
goto init_fail;
return (DDI_SUCCESS);
return (DDI_FAILURE);
static boolean_t
return (link_up);
int err;
case LB_GET_INFO_SIZE:
case LB_GET_INFO:
case LB_GET_MODE:
case LB_SET_MODE:
case ND_GET:
case ND_SET:
#ifdef E1000G_DEBUG
case E1000G_IOC_REG_PEEK:
case E1000G_IOC_REG_POKE:
case E1000G_IOC_CHIP_RESET:
switch (status) {
case IOC_INVAL:
case IOC_DONE:
case IOC_ACK:
case IOC_REPLY:
if (global) {
return (ENOTACTIVE);
if (global)
return (ENOTACTIVE);
return (ENOTACTIVE);
if (global)
packet_count = 0;
packet_count++;
if (packet_count > 0) {
static boolean_t
for (i = 0; i < TX_DRAIN_TIME; i++) {
if (done)
return (done);
static boolean_t
return (done);
return (B_FALSE);
return (B_TRUE);
return (B_FALSE);
return (B_TRUE);
static uint_t
return (DDI_INTR_CLAIMED);
return (DDI_INTR_UNCLAIMED);
static uint_t
if (icr) {
return (DDI_INTR_CLAIMED);
return (DDI_INTR_UNCLAIMED);
if (itr) {
if (link_changed) {
if (tid != 0)
static uint32_t
goto itr_done;
goto itr_done;
return (new_itr);
int slot;
#ifndef NO_82542_SUPPORT
if (slot == 0) {
#ifndef NO_82542_SUPPORT
return (EIO);
int err;
return (EINVAL);
return (ENOSPC);
return (err);
int err;
return (EINVAL);
return (err);
return (EINVAL);
return (EINVAL);
return (EINVAL);
return (EINVAL);
return (EINVAL);
int res = 0;
goto done;
goto done;
#ifndef NO_82542_SUPPORT
done:
return (res);
ETHERADDRL) == 0) {
#ifndef NO_82542_SUPPORT
done:
return (EIO);
* address registers for its node/network/mac/individual address.
#ifndef NO_82542_SUPPORT
#ifndef NO_82542_SUPPORT
if (on)
rctl |=
return (EIO);
static boolean_t
switch (cap) {
case MAC_CAPAB_HCKSUM: {
case e1000_82540:
case e1000_82544:
case e1000_82545:
case e1000_82545_rev_3:
case e1000_82546:
case e1000_82546_rev_3:
case e1000_82571:
case e1000_82572:
case e1000_82573:
case e1000_80003es2lan:
return (B_FALSE);
case MAC_CAPAB_POLL:
case MAC_CAPAB_MULTIADDRESS: {
return (B_FALSE);
return (B_TRUE);
* e1000g_get_conf - get configurations set in e1000g.conf
* file e1000g.conf.
* get each configurable property from e1000g.conf
* file e1000g.conf.
"Not Enough %s values found in e1000g.conf"
"Too High %s value in e1000g.conf - set to %d\n",
"Too Low %s value in e1000g.conf - set to %d\n",
return (propval);
static boolean_t
return (link_changed);
if (link_changed) {
* e1000g_force_speed_duplex - read forced speed/duplex out of e1000g.conf
* and also for 1000 Mbps speeds from the e1000g.conf file
int forced;
switch (forced) {
case GDIAG_10_HALF:
case GDIAG_10_FULL:
case GDIAG_100_HALF:
case GDIAG_100_FULL:
case GDIAG_1000_FULL:
* e1000g_get_max_frame_size - get jumbo frame setting from e1000g.conf
* This function reads MaxFrameSize from e1000g.conf
int max_frame;
switch (max_frame) {
#pragma inline(arm_watchdog_timer)
if (tid != 0)
if (tid != 0)
if (tid != 0)
if (tid != 0)
phy_ctrl |=
static boolean_t
return (B_FALSE);
return (B_TRUE);
static boolean_t
return (B_FALSE);
return (B_FALSE);
return (B_TRUE);
#ifdef E1000G_DEBUG
static enum ioc_reply
case E1000G_IOC_REG_PEEK:
case E1000G_IOC_REG_POKE:
return (IOC_INVAL);
return (IOC_INVAL);
return (IOC_INVAL);
return (IOC_INVAL);
case E1000G_PP_SPACE_REG:
return (IOC_INVAL);
return (IOC_INVAL);
mem_va = 0;
case E1000G_PP_SPACE_E1000G:
return (IOC_INVAL);
return (IOC_INVAL);
regaddr =
regaddr =
void *vaddr;
void *vaddr;
static enum ioc_reply
return (IOC_INVAL);
return (IOC_INVAL);
case LB_GET_INFO_SIZE:
return (IOC_INVAL);
case e1000_82571:
case e1000_82572:
case LB_GET_INFO:
case e1000_82571:
case e1000_82572:
return (IOC_INVAL);
value = 0;
case e1000_82571:
case e1000_82572:
case LB_GET_MODE:
return (IOC_INVAL);
case LB_SET_MODE:
size = 0;
return (IOC_INVAL);
return (IOC_INVAL);
return (IOC_INVAL);
return (IOC_REPLY);
static boolean_t
int i, times;
return (B_TRUE);
times = 0;
return (B_TRUE);
switch (mode) {
return (B_FALSE);
case E1000G_LB_EXTERNAL_1000:
case E1000G_LB_EXTERNAL_100:
case E1000G_LB_EXTERNAL_10:
case E1000G_LB_INTERNAL_PHY:
times++;
if (!link_up) {
goto again;
return (B_TRUE);
case e1000_82540:
case e1000_82545:
case e1000_82545_rev_3:
case e1000_82546:
case e1000_82546_rev_3:
case e1000_82573:
case e1000_82540:
case e1000_82545:
case e1000_82545_rev_3:
case e1000_82546:
case e1000_82546_rev_3:
case e1000_82571:
case e1000_82572:
case e1000_82573:
case e1000_media_type_copper:
case e1000_media_type_fiber:
#ifdef __sparc
static boolean_t
int err;
while (nelts--)
while (nelts--)
if (found) {
return (found);
int intr_types;
int rc;
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_SUCCESS);
int flag;
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_FAILURE);
for (y = 0; y < actual; y++)
return (DDI_FAILURE);
for (x = 0; x < actual; x++) {
(void) ddi_intr_remove_handler(
for (y = 0; y < actual; y++)
return (DDI_FAILURE);
for (y = 0; y < actual; y++) {
return (DDI_FAILURE);
return (DDI_SUCCESS);
int rc;
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_SUCCESS);
int rc;
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_SUCCESS);
int rc;
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_SUCCESS);
fma_acc_flag = 0;
fma_dma_flag = 0;