ixgbe_main.c revision 1878b97151eb2746480d8b2139fa08a2e8f14df3
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * CDDL HEADER START
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * The contents of this file are subject to the terms of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Common Development and Distribution License (the "License").
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * You may not use this file except in compliance with the License.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * See the License for the specific language governing permissions
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * and limitations under the License.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * When distributing Covered Code, include this CDDL HEADER in each
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * If applicable, add the following below this CDDL HEADER, with the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * fields enclosed by brackets "[]" replaced with your own identifying
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * information: Portions Copyright [yyyy] [name of copyright owner]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * CDDL HEADER END
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Use is subject to license terms.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Local function protoypes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic int ixgbe_unicst_find(ixgbe_t *, const uint8_t *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic void ixgbe_setup_vmdq_rss_conf(ixgbe_t *ixgbe);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic int ixgbe_get_prop(ixgbe_t *, char *, int, int, int);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic void ixgbe_sfp_check(void *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic void ixgbe_link_timer(void *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic void ixgbe_local_timer(void *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic void ixgbe_restart_watchdog_timer(ixgbe_t *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic void ixgbe_disable_adapter_interrupts(ixgbe_t *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic void ixgbe_enable_adapter_interrupts(ixgbe_t *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic boolean_t ixgbe_set_loopback_mode(ixgbe_t *, uint32_t);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic void ixgbe_set_internal_mac_loopback(ixgbe_t *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic int ixgbe_alloc_intr_handles(ixgbe_t *, int);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic void ixgbe_map_rxring_to_vector(ixgbe_t *, int, int);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic void ixgbe_map_txring_to_vector(ixgbe_t *, int, int);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic void ixgbe_setup_ivar(ixgbe_t *, uint16_t, uint8_t, int8_t);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic void ixgbe_enable_ivar(ixgbe_t *, uint16_t, int8_t);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic void ixgbe_disable_ivar(ixgbe_t *, uint16_t, int8_t);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic uint32_t ixgbe_get_hw_rx_index(ixgbe_t *ixgbe, uint32_t sw_rx_index);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic void ixgbe_intr_other_work(ixgbe_t *, uint32_t);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic void ixgbe_get_driver_control(struct ixgbe_hw *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic void ixgbe_release_driver_control(struct ixgbe_hw *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic int ixgbe_attach(dev_info_t *, ddi_attach_cmd_t);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic int ixgbe_detach(dev_info_t *, ddi_detach_cmd_t);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic void ixgbe_unconfigure(dev_info_t *, ixgbe_t *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic uint8_t *ixgbe_mc_table_itr(struct ixgbe_hw *, uint8_t **, uint32_t *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic int ixgbe_cbfunc(dev_info_t *, ddi_cb_action_t, void *, void *, void *);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic int ixgbe_intr_adjust(ixgbe_t *, ddi_cb_action_t, int);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic int ixgbe_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync const void *impl_data);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "_tx_copy_thresh",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "_tx_recycle_thresh",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "_tx_overload_thresh",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "_tx_resched_thresh",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "_rx_copy_thresh",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "_rx_limit_per_intr",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "_intr_throttling",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "_adv_pause_cap",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "_adv_asym_pause_cap",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (sizeof (ixgbe_priv_props) / sizeof (mac_priv_prop_t))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0, /* devo_refcnt */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mod_driverops, /* Type of module. This one is a driver */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Access attributes for register mapping
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Loopback property
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (MC_IOCTL | MC_GETCAPAB | MC_SETPROP | MC_GETPROP | MC_PROPINFO)
NULL,
NULL,
NULL,
NULL,
NULL,
_init(void)
int status;
return (status);
_fini(void)
int status;
return (status);
int status;
return (status);
int instance;
switch (cmd) {
return (DDI_FAILURE);
case DDI_RESUME:
case DDI_ATTACH:
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;
goto attach_fail;
goto attach_fail;
goto attach_fail;
goto attach_fail;
goto attach_fail;
return (DDI_SUCCESS);
return (DDI_FAILURE);
switch (cmd) {
return (DDI_FAILURE);
case DDI_SUSPEND:
case DDI_DETACH:
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_SUCCESS);
int status;
return (IXGBE_FAILURE);
return (IXGBE_FAILURE);
case ixgbe_mac_82598EB:
case ixgbe_mac_82599EB:
return (IXGBE_FAILURE);
return (IXGBE_SUCCESS);
!= DDI_SUCCESS) {
return (IXGBE_FAILURE);
return (IXGBE_FAILURE);
return (IXGBE_SUCCESS);
return (IXGBE_FAILURE);
return (IXGBE_SUCCESS);
return (DDI_FAILURE);
return (DDI_FAILURE);
return (DDI_SUCCESS);
return (DDI_FAILURE);
return (DDI_SUCCESS);
return (DDI_SUCCESS);
goto init_fail;
goto init_fail;
goto init_fail;
* & flow control type is controlled by ixgbe.conf
goto init_fail;
goto init_fail;
return (IXGBE_SUCCESS);
return (IXGBE_FAILURE);
int ret_val, i;
return (IXGBE_FAILURE);
return (IXGBE_FAILURE);
* Configure/Initialize hardware
return (IXGBE_FAILURE);
return (IXGBE_SUCCESS);
return (IXGBE_FAILURE);
return (IXGBE_SUCCESS);
desc_num = 0;
if (desc_num > 0) {
static boolean_t
for (i = 0; i < TX_DRAIN_TIME; i++) {
if (done)
return (done);
static boolean_t
for (i = 0; i < RX_DRAIN_TIME; i++) {
if (done)
return (done);
if (alloc_buffer) {
return (IXGBE_FAILURE);
return (IXGBE_FAILURE);
goto start_failure;
goto start_failure;
return (IXGBE_SUCCESS);
return (IXGBE_FAILURE);
if (free_buffer) {
switch (cbaction) {
int count;
case DDI_CB_INTR_ADD:
case DDI_CB_INTR_REMOVE:
DDI_SUCCESS) {
goto cb_fail;
cbaction);
return (DDI_ENOTSUP);
return (DDI_SUCCESS);
return (DDI_FAILURE);
if (count == 0)
return (DDI_SUCCESS);
return (DDI_FAILURE);
return (DDI_FAILURE);
switch (cbaction) {
case DDI_CB_INTR_ADD:
goto intr_adjust_fail;
case DDI_CB_INTR_REMOVE:
goto intr_adjust_fail;
goto intr_adjust_fail;
goto intr_adjust_fail;
goto intr_adjust_fail;
goto intr_adjust_fail;
goto intr_adjust_fail;
goto intr_adjust_fail;
return (DDI_SUCCESS);
return (DDI_FAILURE);
return (IXGBE_FAILURE);
return (IXGBE_SUCCESS);
return (IXGBE_FAILURE);
return (IXGBE_FAILURE);
return (IXGBE_FAILURE);
return (IXGBE_SUCCESS);
goto alloc_rx_rings_failure;
return (IXGBE_SUCCESS);
return (IXGBE_FAILURE);
* 3. Initialize software pointers/parameters for receive/transmit;
case IXGBE_CLASSIFY_RSS:
case IXGBE_CLASSIFY_VMDQ:
case IXGBE_CLASSIFY_VMDQ_RSS:
ring_mapping = 0;
ring_mapping = 0;
ring_mapping = 0;
reta = 0;
sizeof (uint32_t));
case ixgbe_mac_82598EB:
case ixgbe_mac_82599EB:
reta = 0;
sizeof (uint32_t));
case ixgbe_mac_82598EB:
case ixgbe_mac_82599EB:
int slot;
int slot;
return (slot);
return (EINVAL);
return (ENOENT);
return (EIO);
ETHERADDRL) == 0) {
return (EIO);
case ixgbe_mac_82598EB:
case ixgbe_mac_82599EB:
* ixgbe_get_conf - Get driver configurations set in driver.conf.
* file ixgbe.conf.
* fc.current_mode will be the flow_control mode that was negotiated.
* ixgbe.conf.
int value;
return (value);
if (setup_hw) {
return (IXGBE_FAILURE);
return (IXGBE_SUCCESS);
if (link_up) {
switch (speed) {
if (servicing_interrupt() != 0) {
if (link_changed) {
static boolean_t
return (B_FALSE);
if (result) {
return (result);
static boolean_t
return (B_FALSE);
return (B_TRUE);
static boolean_t
#ifdef __sparc
int err;
while (nelts--)
while (nelts--)
if (found) {
return (B_TRUE);
return (B_TRUE);
#pragma inline(ixgbe_arm_watchdog_timer)
if (tid != 0)
if (tid != 0)
| IXGBE_GPIE_EIAME);
eiac = 0;
enum ioc_reply
return (IOC_INVAL);
return (IOC_INVAL);
case LB_GET_INFO_SIZE:
return (IOC_INVAL);
case LB_GET_INFO:
return (IOC_INVAL);
value = 0;
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
return (B_TRUE);
return (B_TRUE);
switch (mode) {
return (B_FALSE);
case IXGBE_LB_EXTERNAL:
case IXGBE_LB_INTERNAL_MAC:
return (B_TRUE);
&atlas);
atlas);
&atlas);
atlas);
&atlas);
atlas);
&atlas);
atlas);
#pragma inline(ixgbe_intr_rx_work)
#pragma inline(ixgbe_intr_tx_work)
#pragma inline(ixgbe_intr_other_work)
static uint_t
return (DDI_INTR_UNCLAIMED);
return (DDI_INTR_CLAIMED);
if (eicr) {
if (tx_reschedule) {
return (result);
static uint_t
return (DDI_INTR_CLAIMED);
return (DDI_INTR_CLAIMED);
static uint_t
int r_idx = 0;
while (r_idx >= 0) {
while (r_idx >= 0) {
DDI_FM_OK) {
return (DDI_INTR_CLAIMED);
return (DDI_INTR_CLAIMED);
int intr_types;
int rc;
return (IXGBE_FAILURE);
return (IXGBE_SUCCESS);
return (IXGBE_SUCCESS);
return (IXGBE_SUCCESS);
return (IXGBE_FAILURE);
int minimum;
int rc;
switch (intr_type) {
case DDI_INTR_TYPE_FIXED:
case DDI_INTR_TYPE_MSI:
case DDI_INTR_TYPE_MSIX:
return (IXGBE_FAILURE);
return (IXGBE_FAILURE);
actual = 0;
goto alloc_handle_fail;
actual);
goto alloc_handle_fail;
goto alloc_handle_fail;
goto alloc_handle_fail;
return (IXGBE_SUCCESS);
return (IXGBE_FAILURE);
int vector = 0;
int rc;
case DDI_INTR_TYPE_MSIX:
(void) ddi_intr_remove_handler(
return (IXGBE_FAILURE);
case DDI_INTR_TYPE_MSI:
return (IXGBE_FAILURE);
case DDI_INTR_TYPE_FIXED:
return (IXGBE_FAILURE);
return (IXGBE_FAILURE);
return (IXGBE_SUCCESS);
#pragma inline(ixgbe_map_rxring_to_vector)
#pragma inline(ixgbe_map_txring_to_vector)
case ixgbe_mac_82598EB:
cause = 0;
case ixgbe_mac_82599EB:
ivar);
case ixgbe_mac_82598EB:
cause = 0;
case ixgbe_mac_82599EB:
ivar);
case ixgbe_mac_82598EB:
cause = 0;
case ixgbe_mac_82599EB:
ivar);
static uint32_t
return (sw_rx_index);
return (sw_rx_index);
return (hw_rx_index);
return (hw_rx_index);
return (sw_rx_index);
int i, vector = 0;
return (IXGBE_SUCCESS);
* Interrupts/vectors mapping for MSI-X
return (IXGBE_SUCCESS);
case ixgbe_mac_82598EB:
case ixgbe_mac_82599EB:
while (r_idx >= 0) {
while (r_idx >= 0) {
int rc;
int rc;
int rc;
return (IXGBE_FAILURE);
return (IXGBE_FAILURE);
return (IXGBE_SUCCESS);
int rc;
return (IXGBE_FAILURE);
return (IXGBE_FAILURE);
return (IXGBE_SUCCESS);
if (link_up) {
if (oldval < n)
return (newval);
static uint8_t *
return (addr);
int fma_dma_flag;
fma_dma_flag = 0;
rindex--;
if (rindex < 0)
switch (rtype) {
case MAC_RING_TYPE_RX: {
case MAC_RING_TYPE_TX: {
switch (rtype) {
case MAC_RING_TYPE_RX: {
case MAC_RING_TYPE_TX:
int slot, i;
return (ECANCELED);
return (ENOSPC);
slot = i;
return (ENOSPC);
int slot;
return (ECANCELED);
return (EINVAL);
return (EINVAL);