diff --git a/sys/dev/ixgbe/LICENSE b/sys/dev/ixgbe/LICENSE index b6fd3b77edb..39264e087be 100644 --- a/sys/dev/ixgbe/LICENSE +++ b/sys/dev/ixgbe/LICENSE @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2009, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/sys/dev/ixgbe/README b/sys/dev/ixgbe/README index 40bbe5fede5..0b27deb0a08 100644 --- a/sys/dev/ixgbe/README +++ b/sys/dev/ixgbe/README @@ -1,6 +1,8 @@ FreeBSD Driver for 10 Gigabit PCI Express Server Adapters ============================================= -$FreeBSD$ +/*$FreeBSD$*/ + +May 14, 2008 Contents @@ -258,7 +260,7 @@ For general information and support, go to the Intel support website at: If an issue is identified with the released source code on the supported kernel with a supported adapter, email the specific information related to -the issue to freebsdnic@mailbox.intel.com. +the issue to freebsd@intel.com. diff --git a/sys/dev/ixgbe/ixgbe.c b/sys/dev/ixgbe/ixgbe.c index 3b71cb6ce1b..e2827f4c4a4 100644 --- a/sys/dev/ixgbe/ixgbe.c +++ b/sys/dev/ixgbe/ixgbe.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2009, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -46,7 +46,7 @@ int ixgbe_display_debug_stats = 0; /********************************************************************* * Driver version *********************************************************************/ -char ixgbe_driver_version[] = "1.6.2"; +char ixgbe_driver_version[] = "1.7.4"; /********************************************************************* * PCI Device ID Table @@ -71,6 +71,8 @@ static ixgbe_vendor_info_t ixgbe_vendor_info_array[] = {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598AT, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598EB_SFP_LOM, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_KX4, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP, 0, 0, 0}, /* required last entry */ {0, 0, 0, 0, 0} }; @@ -104,7 +106,9 @@ static int ixgbe_allocate_pci_resources(struct adapter *); static int ixgbe_allocate_msix(struct adapter *); static int ixgbe_allocate_legacy(struct adapter *); static int ixgbe_allocate_queues(struct adapter *); +#if __FreeBSD_version >= 602105 static int ixgbe_setup_msix(struct adapter *); +#endif static void ixgbe_free_pci_resources(struct adapter *); static void ixgbe_local_timer(void *); static int ixgbe_hardware_init(struct adapter *); @@ -124,6 +128,7 @@ static void ixgbe_initialize_receive_units(struct adapter *); static void ixgbe_free_receive_structures(struct adapter *); static void ixgbe_free_receive_buffers(struct rx_ring *); +static void ixgbe_init_moderation(struct adapter *); static void ixgbe_enable_intr(struct adapter *); static void ixgbe_disable_intr(struct adapter *); static void ixgbe_update_stats_counters(struct adapter *); @@ -146,7 +151,7 @@ static int ixgbe_dma_malloc(struct adapter *, bus_size_t, static void ixgbe_dma_free(struct adapter *, struct ixgbe_dma_alloc *); static void ixgbe_add_rx_process_limit(struct adapter *, const char *, const char *, int *, int); -static boolean_t ixgbe_tx_ctx_setup(struct tx_ring *, struct mbuf *); +static int ixgbe_tx_ctx_setup(struct tx_ring *, struct mbuf *); static boolean_t ixgbe_tso_setup(struct tx_ring *, struct mbuf *, u32 *); static void ixgbe_set_ivar(struct adapter *, u16, u8, s8); static void ixgbe_configure_ivars(struct adapter *); @@ -157,6 +162,12 @@ static void ixgbe_register_vlan(void *, struct ifnet *, u16); static void ixgbe_unregister_vlan(void *, struct ifnet *, u16); #endif +#ifdef IXGBE_TIMESYNC +/* Precision Time sync support */ +static int ixgbe_tsync_init(struct adapter *); +static void ixgbe_tsync_disable(struct adapter *); +#endif + static void ixgbe_update_aim(struct rx_ring *); /* Support for pluggable optic modules */ @@ -165,14 +176,19 @@ static bool ixgbe_sfp_probe(struct adapter *); /* Legacy (single vector interrupt handler */ static void ixgbe_legacy_irq(void *); +#if __FreeBSD_version >= 602105 /* The MSI/X Interrupt handlers */ static void ixgbe_msix_tx(void *); static void ixgbe_msix_rx(void *); static void ixgbe_msix_link(void *); +#endif -/* Legacy interrupts use deferred handlers */ -static void ixgbe_handle_tx(void *context, int pending); -static void ixgbe_handle_rx(void *context, int pending); +/* Deferred interrupt tasklets */ +static void ixgbe_handle_tx(void *, int); +static void ixgbe_handle_rx(void *, int); +static void ixgbe_handle_link(void *, int); +static void ixgbe_handle_msf(void *, int); +static void ixgbe_handle_mod(void *, int); /********************************************************************* @@ -213,8 +229,8 @@ static int ixgbe_enable_aim = TRUE; TUNABLE_INT("hw.ixgbe.enable_aim", &ixgbe_enable_aim); static int ixgbe_low_latency = IXGBE_LOW_LATENCY; TUNABLE_INT("hw.ixgbe.low_latency", &ixgbe_low_latency); -static int ixgbe_ave_latency = IXGBE_LOW_LATENCY; -TUNABLE_INT("hw.ixgbe.ave_latency", &ixgbe_low_latency); +static int ixgbe_ave_latency = IXGBE_AVE_LATENCY; +TUNABLE_INT("hw.ixgbe.ave_latency", &ixgbe_ave_latency); static int ixgbe_bulk_latency = IXGBE_BULK_LATENCY; TUNABLE_INT("hw.ixgbe.bulk_latency", &ixgbe_bulk_latency); @@ -222,8 +238,8 @@ TUNABLE_INT("hw.ixgbe.bulk_latency", &ixgbe_bulk_latency); static int ixgbe_rx_process_limit = 100; TUNABLE_INT("hw.ixgbe.rx_process_limit", &ixgbe_rx_process_limit); -/* Flow control setting, default to full */ -static int ixgbe_flow_control = ixgbe_fc_none; +/* Flow control setting, default to off */ +static int ixgbe_flow_control = ixgbe_fc_full; TUNABLE_INT("hw.ixgbe.flow_control", &ixgbe_flow_control); /* @@ -239,11 +255,16 @@ TUNABLE_INT("hw.ixgbe.enable_lro", &ixgbe_enable_lro); * MSIX should be the default for best performance, * but this allows it to be forced off for testing. */ +#if __FreeBSD_version >= 602105 static int ixgbe_enable_msix = 1; +#else +static int ixgbe_enable_msix = 0; +#endif TUNABLE_INT("hw.ixgbe.enable_msix", &ixgbe_enable_msix); /* * Enable RX Header Split + * WARNING: disable this if bridging or forwarding!! */ static int ixgbe_rx_hdr_split = 1; TUNABLE_INT("hw.ixgbe.rx_hdr_split", &ixgbe_rx_hdr_split); @@ -268,6 +289,13 @@ TUNABLE_INT("hw.ixgbe.rxd", &ixgbe_rxd); /* Total number of Interfaces - need for config sanity check */ static int ixgbe_total_ports; +/* +** The number of scatter-gather segments +** differs for 82598 and 82599, default to +** the former. +*/ +static int ixgbe_num_segs = IXGBE_82598_SCATTER; + /********************************************************************* * Device identification routine * @@ -312,6 +340,7 @@ ixgbe_probe(device_t dev) ixgbe_strings[ent->index], ixgbe_driver_version); device_set_desc_copy(dev, adapter_name); + ++ixgbe_total_ports; return (0); } ent++; @@ -333,6 +362,7 @@ static int ixgbe_attach(device_t dev) { struct adapter *adapter; + struct ixgbe_hw *hw; int error = 0; u16 pci_device_id; u32 ctrl_ext; @@ -342,37 +372,34 @@ ixgbe_attach(device_t dev) /* Allocate, clear, and link in our adapter structure */ adapter = device_get_softc(dev); adapter->dev = adapter->osdep.dev = dev; + hw = &adapter->hw; /* Core Lock Init*/ IXGBE_CORE_LOCK_INIT(adapter, device_get_nameunit(dev)); - /* Keep track of number of ports and optics */ + /* Keep track of optics */ pci_device_id = pci_get_device(dev); switch (pci_device_id) { case IXGBE_DEV_ID_82598_CX4_DUAL_PORT : + case IXGBE_DEV_ID_82598EB_CX4 : adapter->optics = IFM_10G_CX4; - ixgbe_total_ports += 2; break; case IXGBE_DEV_ID_82598AF_DUAL_PORT : - adapter->optics = IFM_10G_SR; - ixgbe_total_ports += 2; - break; + case IXGBE_DEV_ID_82598_DA_DUAL_PORT : case IXGBE_DEV_ID_82598AF_SINGLE_PORT : + case IXGBE_DEV_ID_82598AT : adapter->optics = IFM_10G_SR; - ixgbe_total_ports += 1; break; case IXGBE_DEV_ID_82598EB_XF_LR : adapter->optics = IFM_10G_LR; - ixgbe_total_ports += 1; break; - case IXGBE_DEV_ID_82598EB_CX4 : + case IXGBE_DEV_ID_82599_SFP : + adapter->optics = IFM_10G_SR; + ixgbe_num_segs = IXGBE_82599_SCATTER; + break; + case IXGBE_DEV_ID_82599_KX4 : adapter->optics = IFM_10G_CX4; - ixgbe_total_ports += 1; - break; - case IXGBE_DEV_ID_82598AT : - ixgbe_total_ports += 1; - case IXGBE_DEV_ID_82598_DA_DUAL_PORT : - ixgbe_total_ports += 2; + ixgbe_num_segs = IXGBE_82599_SCATTER; default: break; } @@ -474,7 +501,7 @@ ixgbe_attach(device_t dev) } /* Initialize the shared code */ - error = ixgbe_init_shared_code(&adapter->hw); + error = ixgbe_init_shared_code(hw); if (error == IXGBE_ERR_SFP_NOT_PRESENT) { /* ** No optics in this port, set up @@ -525,11 +552,11 @@ ixgbe_attach(device_t dev) adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig, ixgbe_unregister_vlan, 0, EVENTHANDLER_PRI_FIRST); #endif - + /* let hardware know driver is loaded */ - ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT); + ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); ctrl_ext |= IXGBE_CTRL_EXT_DRV_LOAD; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT, ctrl_ext); + IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); INIT_DEBUGOUT("ixgbe_attach: end"); return (0); @@ -590,6 +617,14 @@ ixgbe_detach(device_t dev) } } + /* Drain the Link queue */ + if (adapter->tq) { + taskqueue_drain(adapter->tq, &adapter->link_task); + taskqueue_drain(adapter->tq, &adapter->mod_task); + taskqueue_drain(adapter->tq, &adapter->msf_task); + taskqueue_free(adapter->tq); + } + /* let hardware know driver is unloading */ ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT); ctrl_ext &= ~IXGBE_CTRL_EXT_DRV_LOAD; @@ -662,6 +697,19 @@ ixgbe_start_locked(struct tx_ring *txr, struct ifnet * ifp) IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) break; + /* + * Force a cleanup if number of TX descriptors + * available is below the threshold. If it fails + * to get above, then abort transmit. + */ + if (txr->tx_avail <= IXGBE_TX_CLEANUP_THRESHOLD) { + ixgbe_txeof(txr); + /* Make sure things have improved */ + if (txr->tx_avail <= IXGBE_TX_OP_THRESHOLD) { + txr->no_tx_desc_avail++; + break; + } + } if (ixgbe_xmit(txr, &m_head)) { if (m_head == NULL) @@ -701,7 +749,8 @@ ixgbe_start(struct ifnet *ifp) txr = &adapter->tx_rings[queue]; if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - IXGBE_TX_LOCK(txr); + if (IXGBE_TX_TRYLOCK(txr) == 0) + return; ixgbe_start_locked(txr, ifp); IXGBE_TX_UNLOCK(txr); } @@ -803,6 +852,67 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data) #endif break; } +#ifdef IXGBE_TIMESYNC + /* + ** IOCTL support for Precision Time (IEEE 1588) Support + */ + case IXGBE_TIMESYNC_READTS: + { + u32 rx_ctl, tx_ctl; + struct ixgbe_tsync_read *tdata; + + tdata = (struct ixgbe_tsync_read *) ifr->ifr_data; + + if (tdata->read_current_time) { + getnanotime(&tdata->system_time); + tdata->network_time = IXGBE_READ_REG(&adapter->hw, + IXGBE_SYSTIML); + tdata->network_time |= + (u64)IXGBE_READ_REG(&adapter->hw, + IXGBE_SYSTIMH ) << 32; + } + + rx_ctl = IXGBE_READ_REG(&adapter->hw, IXGBE_TSYNCRXCTL); + tx_ctl = IXGBE_READ_REG(&adapter->hw, IXGBE_TSYNCTXCTL); + + if (rx_ctl & 0x1) { + u32 tmp; + unsigned char *tmp_cp; + + tdata->rx_valid = 1; + tdata->rx_stamp = IXGBE_READ_REG(&adapter->hw, + IXGBE_RXSTMPL); + tdata->rx_stamp |= (u64)IXGBE_READ_REG(&adapter->hw, + IXGBE_RXSTMPH) << 32; + + tmp = IXGBE_READ_REG(&adapter->hw, IXGBE_RXSATRL); + tmp_cp = (unsigned char *) &tmp; + tdata->srcid[0] = tmp_cp[0]; + tdata->srcid[1] = tmp_cp[1]; + tdata->srcid[2] = tmp_cp[2]; + tdata->srcid[3] = tmp_cp[3]; + tmp = IXGBE_READ_REG(&adapter->hw, IXGBE_RXSATRH); + tmp_cp = (unsigned char *) &tmp; + tdata->srcid[4] = tmp_cp[0]; + tdata->srcid[5] = tmp_cp[1]; + tdata->seqid = tmp >> 16; + tdata->seqid = htons(tdata->seqid); + } else + tdata->rx_valid = 0; + + if (tx_ctl & 0x1) { + tdata->tx_valid = 1; + tdata->tx_stamp = IXGBE_READ_REG(&adapter->hw, + IXGBE_TXSTMPL); + tdata->tx_stamp |= (u64) IXGBE_READ_REG(&adapter->hw, + IXGBE_TXSTMPH) << 32; + } else + tdata->tx_valid = 0; + + return (0); + } +#endif /* IXGBE_TIMESYNC */ + default: IOCTL_DEBUGOUT1("ioctl: UNKNOWN (0x%X)\n", (int)command); error = ether_ioctl(ifp, command, data); @@ -905,13 +1015,12 @@ ixgbe_watchdog(struct adapter *adapter) static void ixgbe_init_locked(struct adapter *adapter) { - struct rx_ring *rxr = adapter->rx_rings; - struct tx_ring *txr = adapter->tx_rings; struct ifnet *ifp = adapter->ifp; device_t dev = adapter->dev; struct ixgbe_hw *hw; u32 k, txdctl, mhadd, gpie; u32 rxdctl, rxctrl; + int err; INIT_DEBUGOUT("ixgbe_init: begin"); @@ -951,13 +1060,6 @@ ixgbe_init_locked(struct adapter *adapter) ixgbe_initialize_transmit_units(adapter); - /* TX irq moderation rate is fixed */ - for (int i = 0; i < adapter->num_tx_queues; i++, txr++) { - IXGBE_WRITE_REG(&adapter->hw, - IXGBE_EITR(txr->msix), ixgbe_ave_latency); - txr->watchdog_timer = FALSE; - } - /* Setup Multicast table */ ixgbe_set_multi(adapter); @@ -980,23 +1082,21 @@ ixgbe_init_locked(struct adapter *adapter) /* Configure RX settings */ ixgbe_initialize_receive_units(adapter); - /* RX moderation will be adapted over time, set default */ - for (int i = 0; i < adapter->num_rx_queues; i++, rxr++) { - IXGBE_WRITE_REG(&adapter->hw, - IXGBE_EITR(rxr->msix), ixgbe_low_latency); - } - - /* Set Link moderation */ - IXGBE_WRITE_REG(&adapter->hw, - IXGBE_EITR(adapter->linkvec), IXGBE_LINK_ITR); + /* Configure Interrupt Moderation */ + ixgbe_init_moderation(adapter); gpie = IXGBE_READ_REG(&adapter->hw, IXGBE_GPIE); + if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + gpie |= IXGBE_SDP1_GPIEN; + gpie |= IXGBE_SDP2_GPIEN; + } + /* Enable Fan Failure Interrupt */ - if (adapter->hw.phy.media_type == ixgbe_media_type_copper) + if (hw->device_id == IXGBE_DEV_ID_82598AT) gpie |= IXGBE_SDP1_GPIEN; - if (adapter->msix) { + if (adapter->msix > 2) { /* Enable Enhanced MSIX mode */ gpie |= IXGBE_GPIE_MSIX_MODE; gpie |= IXGBE_GPIE_EIAME | IXGBE_GPIE_PBA_SUPPORT | @@ -1058,9 +1158,40 @@ ixgbe_init_locked(struct adapter *adapter) /* Set up MSI/X routing */ if (ixgbe_enable_msix) ixgbe_configure_ivars(adapter); + else { /* Simple settings for Legacy/MSI */ + ixgbe_set_ivar(adapter, 0, 0, 0); + ixgbe_set_ivar(adapter, 0, 0, 1); + } ixgbe_enable_intr(adapter); + /* + ** Check on any SFP devices that + ** need to be kick-started + */ + err = hw->phy.ops.identify(hw); + if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { + device_printf(dev, + "Unsupported SFP+ module type was detected.\n"); + ixgbe_detach(dev); + return; + } + if (ixgbe_is_sfp(hw)) { + if (hw->phy.multispeed_fiber) { + hw->mac.ops.setup_sfp(hw); + taskqueue_enqueue(adapter->tq, &adapter->msf_task); + } else + taskqueue_enqueue(adapter->tq, &adapter->mod_task); + } else + taskqueue_enqueue(adapter->tq, &adapter->link_task); + + +#ifdef IXGBE_TIMESYNC + /* Initialize IEEE 1588 support */ + if (adapter->hw.mac.type == ixgbe_mac_82599EB) + ixgbe_tsync_init(adapter); +#endif + /* Now inform the stack we're ready */ ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; @@ -1081,7 +1212,7 @@ ixgbe_init(void *arg) /* -** MSIX Interrupt Handlers +** MSIX Interrupt Tasklets */ static void @@ -1136,7 +1267,8 @@ ixgbe_legacy_irq(void *arg) struct ixgbe_hw *hw = &adapter->hw; struct tx_ring *txr = adapter->tx_rings; struct rx_ring *rxr = adapter->rx_rings; - u32 reg_eicr; + bool more; + u32 reg_eicr, loop = MAX_LOOP; reg_eicr = IXGBE_READ_REG(hw, IXGBE_EICR); @@ -1148,7 +1280,15 @@ ixgbe_legacy_irq(void *arg) if (ixgbe_rxeof(rxr, adapter->rx_process_limit)) taskqueue_enqueue(rxr->tq, &rxr->rx_task); - if (ixgbe_txeof(txr)) + + IXGBE_TX_LOCK(txr); + ++txr->tx_irq; + do { + more = ixgbe_txeof(txr); + } while (loop-- && more); + IXGBE_TX_UNLOCK(txr); + + if (more) taskqueue_enqueue(txr->tq, &txr->tx_task); /* Check for fan failure */ @@ -1160,20 +1300,27 @@ ixgbe_legacy_irq(void *arg) } /* Link status change */ - if (reg_eicr & IXGBE_EICR_LSC) + if (reg_eicr & IXGBE_EICR_LSC) { + ixgbe_check_link(&adapter->hw, + &adapter->link_speed, &adapter->link_up, 0); ixgbe_update_link_status(adapter); + } + + /* Update interrupt rate */ + if (ixgbe_enable_aim == TRUE) + ixgbe_update_aim(rxr); ixgbe_enable_intr(adapter); return; } +#if __FreeBSD_version >= 602105 /********************************************************************* * * MSI TX Interrupt Service routine * **********************************************************************/ - void ixgbe_msix_tx(void *arg) { @@ -1181,6 +1328,8 @@ ixgbe_msix_tx(void *arg) struct adapter *adapter = txr->adapter; bool more; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, txr->eims); + IXGBE_TX_LOCK(txr); ++txr->tx_irq; more = ixgbe_txeof(txr); @@ -1198,7 +1347,6 @@ ixgbe_msix_tx(void *arg) * MSIX RX Interrupt Service routine * **********************************************************************/ - static void ixgbe_msix_rx(void *arg) { @@ -1206,18 +1354,72 @@ ixgbe_msix_rx(void *arg) struct adapter *adapter = rxr->adapter; bool more; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rxr->eims); + ++rxr->rx_irq; - more = ixgbe_rxeof(rxr, -1); + more = ixgbe_rxeof(rxr, adapter->rx_process_limit); + + /* Update interrupt rate */ + if (ixgbe_enable_aim == TRUE) + ixgbe_update_aim(rxr); + if (more) taskqueue_enqueue(rxr->tq, &rxr->rx_task); else IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, rxr->eims); - /* Update interrupt rate */ - if (ixgbe_enable_aim == TRUE) - ixgbe_update_aim(rxr); return; } + +static void +ixgbe_msix_link(void *arg) +{ + struct adapter *adapter = arg; + struct ixgbe_hw *hw = &adapter->hw; + u32 reg_eicr; + + ++adapter->link_irq; + + /* First get the cause */ + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, IXGBE_EIMS_OTHER); + reg_eicr = IXGBE_READ_REG(hw, IXGBE_EICS); + /* Clear with write */ + IXGBE_WRITE_REG(hw, IXGBE_EICR, reg_eicr); + + /* Link status change */ + if (reg_eicr & IXGBE_EICR_LSC) + taskqueue_enqueue(adapter->tq, &adapter->link_task); + + if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + if (reg_eicr & IXGBE_EICR_ECC) { + device_printf(adapter->dev, "\nCRITICAL: ECC ERROR!! " + "Please Reboot!!\n"); + IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_ECC); + } + if (reg_eicr & IXGBE_EICR_GPI_SDP1) { + /* Clear the interrupt */ + IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1); + taskqueue_enqueue(adapter->tq, &adapter->msf_task); + } else if (reg_eicr & IXGBE_EICR_GPI_SDP2) { + /* Clear the interrupt */ + IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2); + taskqueue_enqueue(adapter->tq, &adapter->mod_task); + } + } + + /* Check for fan failure */ + if ((hw->device_id == IXGBE_DEV_ID_82598AT) && + (reg_eicr & IXGBE_EICR_GPI_SDP1)) { + device_printf(adapter->dev, "\nCRITICAL: FAN FAILURE!! " + "REPLACE IMMEDIATELY!!\n"); + IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1); + } + + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, IXGBE_EIMS_OTHER); + return; +} +#endif /* FreeBSD_version >= 602105 */ + /* ** Routine to do adjust the RX EITR value based on traffic, ** its a simple three state model, but seems to help. @@ -1267,33 +1469,36 @@ ixgbe_update_aim(struct rx_ring *rxr) return; } - static void -ixgbe_msix_link(void *arg) +ixgbe_init_moderation(struct adapter *adapter) { - struct adapter *adapter = arg; - struct ixgbe_hw *hw = &adapter->hw; - u32 reg_eicr; + struct rx_ring *rxr = adapter->rx_rings; + struct tx_ring *txr = adapter->tx_rings; - ++adapter->link_irq; - - reg_eicr = IXGBE_READ_REG(hw, IXGBE_EICR); - - if (reg_eicr & IXGBE_EICR_LSC) - ixgbe_update_link_status(adapter); - - /* Check for fan failure */ - if ((hw->phy.media_type == ixgbe_media_type_copper) && - (reg_eicr & IXGBE_EICR_GPI_SDP1)) { - device_printf(adapter->dev, "\nCRITICAL: FAN FAILURE!! " - "REPLACE IMMEDIATELY!!\n"); - IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EICR_GPI_SDP1); + /* Single interrupt - MSI or Legacy? */ + if (adapter->msix < 2) { + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(0), 100); + return; } - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, IXGBE_EIMS_OTHER); - return; -} + /* TX irq moderation rate is fixed */ + for (int i = 0; i < adapter->num_tx_queues; i++, txr++) { + IXGBE_WRITE_REG(&adapter->hw, + IXGBE_EITR(txr->msix), ixgbe_ave_latency); + txr->watchdog_timer = FALSE; + } + /* RX moderation will be adapted over time, set default */ + for (int i = 0; i < adapter->num_rx_queues; i++, rxr++) { + IXGBE_WRITE_REG(&adapter->hw, + IXGBE_EITR(rxr->msix), ixgbe_low_latency); + } + + /* Set Link moderation */ + IXGBE_WRITE_REG(&adapter->hw, + IXGBE_EITR(adapter->linkvec), IXGBE_LINK_ITR); + +} /********************************************************************* * @@ -1382,12 +1587,12 @@ static int ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp) { struct adapter *adapter = txr->adapter; - u32 olinfo_status = 0, cmd_type_len = 0; + u32 olinfo_status = 0, cmd_type_len; u32 paylen = 0; int i, j, error, nsegs; - int first, last = 0; + int first, last = 0, offload = 0; struct mbuf *m_head; - bus_dma_segment_t segs[IXGBE_MAX_SCATTER]; + bus_dma_segment_t segs[ixgbe_num_segs]; bus_dmamap_t map; struct ixgbe_tx_buf *txbuf, *txbuf_mapped; union ixgbe_adv_tx_desc *txd = NULL; @@ -1395,26 +1600,12 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp) m_head = *m_headp; /* Basic descriptor defines */ - cmd_type_len |= IXGBE_ADVTXD_DTYP_DATA; - cmd_type_len |= IXGBE_ADVTXD_DCMD_IFCS | IXGBE_ADVTXD_DCMD_DEXT; + cmd_type_len = (IXGBE_ADVTXD_DTYP_DATA | + IXGBE_ADVTXD_DCMD_IFCS | IXGBE_ADVTXD_DCMD_DEXT); if (m_head->m_flags & M_VLANTAG) cmd_type_len |= IXGBE_ADVTXD_DCMD_VLE; - /* - * Force a cleanup if number of TX descriptors - * available is below the threshold. If it fails - * to get above, then abort transmit. - */ - if (txr->tx_avail <= IXGBE_TX_CLEANUP_THRESHOLD) { - ixgbe_txeof(txr); - /* Make sure things have improved */ - if (txr->tx_avail <= IXGBE_TX_OP_THRESHOLD) { - txr->no_tx_desc_avail++; - return (ENOBUFS); - } - } - /* * Important to capture the first descriptor * used because it will contain the index of @@ -1475,19 +1666,27 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp) m_head = *m_headp; /* - ** Set the appropriate offload context + ** Set up the appropriate offload context ** this becomes the first descriptor of ** a packet. */ - if (ixgbe_tso_setup(txr, m_head, &paylen)) { - cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE; - olinfo_status |= IXGBE_TXD_POPTS_IXSM << 8; - olinfo_status |= IXGBE_TXD_POPTS_TXSM << 8; - olinfo_status |= paylen << IXGBE_ADVTXD_PAYLEN_SHIFT; - ++adapter->tso_tx; - } else if (ixgbe_tx_ctx_setup(txr, m_head)) + if (m_head->m_pkthdr.csum_flags & CSUM_TSO) { + if (ixgbe_tso_setup(txr, m_head, &paylen)) { + cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE; + olinfo_status |= IXGBE_TXD_POPTS_IXSM << 8; olinfo_status |= IXGBE_TXD_POPTS_TXSM << 8; - + olinfo_status |= paylen << IXGBE_ADVTXD_PAYLEN_SHIFT; + ++adapter->tso_tx; + } else + return (ENXIO); + } else /* Offloads other than TSO */ + offload = ixgbe_tx_ctx_setup(txr, m_head); + if (offload == TRUE) + olinfo_status |= IXGBE_TXD_POPTS_TXSM << 8; +#ifdef IXGBE_TIMESYNC + if (offload == IXGBE_TIMESTAMP) + cmd_type_len |= IXGBE_ADVTXD_TSTAMP; +#endif /* Record payload length */ if (paylen == 0) olinfo_status |= m_head->m_pkthdr.len << @@ -1513,6 +1712,7 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp) i = 0; txbuf->m_head = NULL; + txbuf->eop_index = -1; } txd->read.cmd_type_len |= @@ -1526,6 +1726,7 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp) /* Set the index of the descriptor that will be marked done */ txbuf = &txr->tx_buffers[first]; + txbuf->eop_index = last; bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); @@ -1685,17 +1886,20 @@ out: callout_reset(&adapter->timer, hz, ixgbe_local_timer, adapter); } +/* +** Note: this routine updates the OS on the link state +** the real check of the hardware only happens with +** a link interrupt. +*/ static void ixgbe_update_link_status(struct adapter *adapter) { - boolean_t link_up = FALSE; struct ifnet *ifp = adapter->ifp; struct tx_ring *txr = adapter->tx_rings; device_t dev = adapter->dev; - ixgbe_check_link(&adapter->hw, &adapter->link_speed, &link_up, 0); - if (link_up){ + if (adapter->link_up){ if (adapter->link_active == FALSE) { if (bootverbose) device_printf(dev,"Link is up %d Gbps %s \n", @@ -1720,7 +1924,6 @@ ixgbe_update_link_status(struct adapter *adapter) } - /********************************************************************* * * This routine disables all traffic on the adapter by issuing a @@ -1743,6 +1946,11 @@ ixgbe_stop(void *arg) /* Tell the stack that the interface is no longer active */ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); +#ifdef IXGBE_TIMESYNC + /* Disable IEEE 1588 support */ + if (adapter->hw.mac.type == ixgbe_mac_82599EB) + ixgbe_tsync_disable(adapter); +#endif ixgbe_reset_hw(&adapter->hw); adapter->hw.adapter_stopped = FALSE; ixgbe_stop_adapter(&adapter->hw); @@ -1817,8 +2025,13 @@ ixgbe_allocate_legacy(struct adapter *adapter) device_get_nameunit(adapter->dev)); taskqueue_start_threads(&rxr->tq, 1, PI_NET, "%s rxq", device_get_nameunit(adapter->dev)); + if ((error = bus_setup_intr(dev, adapter->res[0], +#if __FreeBSD_version >= 700000 INTR_TYPE_NET | INTR_MPSAFE, NULL, ixgbe_legacy_irq, +#else + INTR_TYPE_NET | INTR_MPSAFE, ixgbe_legacy_irq, +#endif adapter, &adapter->tag[0])) != 0) { device_printf(dev, "Failed to register fast interrupt " "handler: %d\n", error); @@ -1833,6 +2046,7 @@ ixgbe_allocate_legacy(struct adapter *adapter) } +#if __FreeBSD_version >= 602105 /********************************************************************* * * Setup MSIX Interrupt resources and handlers @@ -1859,7 +2073,10 @@ ixgbe_allocate_msix(struct adapter *adapter) } /* Set the handler function */ error = bus_setup_intr(dev, adapter->res[vector], - INTR_TYPE_NET | INTR_MPSAFE, NULL, + INTR_TYPE_NET | INTR_MPSAFE, +#if __FreeBSD_version > 700000 + NULL, +#endif ixgbe_msix_tx, txr, &adapter->tag[vector]); if (error) { adapter->res[vector] = NULL; @@ -1867,7 +2084,7 @@ ixgbe_allocate_msix(struct adapter *adapter) return (error); } txr->msix = vector; - txr->eims = IXGBE_IVAR_TX_QUEUE(vector); + txr->eims = 1 << vector; TASK_INIT(&txr->tx_task, 0, ixgbe_handle_tx, txr); txr->tq = taskqueue_create_fast("ixgbe_txq", M_NOWAIT, taskqueue_thread_enqueue, &txr->tq); @@ -1888,15 +2105,18 @@ ixgbe_allocate_msix(struct adapter *adapter) } /* Set the handler function */ error = bus_setup_intr(dev, adapter->res[vector], - INTR_TYPE_NET | INTR_MPSAFE, NULL, ixgbe_msix_rx, - rxr, &adapter->tag[vector]); + INTR_TYPE_NET | INTR_MPSAFE, +#if __FreeBSD_version > 700000 + NULL, +#endif + ixgbe_msix_rx, rxr, &adapter->tag[vector]); if (error) { adapter->res[vector] = NULL; device_printf(dev, "Failed to register RX handler"); return (error); } rxr->msix = vector; - rxr->eims = IXGBE_IVAR_RX_QUEUE(vector); + rxr->eims = 1 << vector; /* used in local timer */ adapter->rx_mask |= rxr->eims; TASK_INIT(&rxr->rx_task, 0, ixgbe_handle_rx, rxr); @@ -1916,19 +2136,37 @@ ixgbe_allocate_msix(struct adapter *adapter) } /* Set the link handler function */ error = bus_setup_intr(dev, adapter->res[vector], - INTR_TYPE_NET | INTR_MPSAFE, NULL, ixgbe_msix_link, - adapter, &adapter->tag[vector]); + INTR_TYPE_NET | INTR_MPSAFE, +#if __FreeBSD_version > 700000 + NULL, +#endif + ixgbe_msix_link, adapter, &adapter->tag[vector]); if (error) { adapter->res[vector] = NULL; device_printf(dev, "Failed to register LINK handler"); return (error); } adapter->linkvec = vector; + /* Tasklets for Link, SFP and Multispeed Fiber */ + TASK_INIT(&adapter->link_task, 0, ixgbe_handle_link, adapter); + TASK_INIT(&adapter->mod_task, 0, ixgbe_handle_mod, adapter); + TASK_INIT(&adapter->msf_task, 0, ixgbe_handle_msf, adapter); + adapter->tq = taskqueue_create_fast("ixgbe_link", M_NOWAIT, + taskqueue_thread_enqueue, &adapter->tq); + taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s linkq", + device_get_nameunit(adapter->dev)); return (0); } +#else /* Freebsd 6.1/2 */ +static int +ixgbe_allocate_msix(struct adapter *adapter) +{ + return (1); +} +#endif - +#if __FreeBSD_version >= 602105 /* * Setup Either MSI/X or MSI */ @@ -1996,6 +2234,7 @@ msi: device_printf(adapter->dev,"Using MSI interrupt\n"); return (msgs); } +#endif /* FreeBSD_version >= 602105 */ static int ixgbe_allocate_pci_resources(struct adapter *adapter) @@ -2031,9 +2270,10 @@ ixgbe_allocate_pci_resources(struct adapter *adapter) adapter->num_tx_queues = 1; adapter->num_rx_queues = 1; +#if __FreeBSD_version >= 602105 /* Now setup MSI or MSI/X */ adapter->msix = ixgbe_setup_msix(adapter); - +#endif adapter->hw.back = &adapter->osdep; return (0); } @@ -2051,7 +2291,10 @@ ixgbe_free_pci_resources(struct adapter * adapter) if (adapter->msix == 0) adapter->msix = 1; - rid = PCIR_BAR(MSIX_82598_BAR); + if (adapter->hw.mac.type == ixgbe_mac_82598EB) + rid = PCIR_BAR(MSIX_82598_BAR); + else + rid = PCIR_BAR(MSIX_82599_BAR); /* * First release all the interrupt resources: @@ -2071,12 +2314,14 @@ ixgbe_free_pci_resources(struct adapter * adapter) } } +#if __FreeBSD_version >= 602105 if (adapter->msix) pci_release_msi(dev); if (adapter->msix_mem != NULL) bus_release_resource(dev, SYS_RES_MEMORY, rid, adapter->msix_mem); +#endif if (adapter->pci_mem != NULL) bus_release_resource(dev, SYS_RES_MEMORY, @@ -2215,7 +2460,7 @@ ixgbe_dma_malloc(struct adapter *adapter, bus_size_t size, int r; r = bus_dma_tag_create(NULL, /* parent */ - PAGE_SIZE, 0, /* alignment, bounds */ + 1, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ @@ -2415,12 +2660,12 @@ ixgbe_allocate_transmit_buffers(struct tx_ring *txr) * Setup DMA descriptor areas. */ if ((error = bus_dma_tag_create(NULL, /* parent */ - PAGE_SIZE, 0, /* alignment, bounds */ + 1, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ IXGBE_TSO_SIZE, /* maxsize */ - IXGBE_MAX_SCATTER, /* nsegments */ + ixgbe_num_segs, /* nsegments */ PAGE_SIZE, /* maxsegsize */ 0, /* flags */ NULL, /* lockfunc */ @@ -2484,6 +2729,8 @@ ixgbe_setup_transmit_ring(struct tx_ring *txr) m_freem(txbuf->m_head); txbuf->m_head = NULL; } + /* Clear the EOP index */ + txbuf->eop_index = -1; } /* Set number of descriptors available */ @@ -2491,7 +2738,6 @@ ixgbe_setup_transmit_ring(struct tx_ring *txr) bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - } /********************************************************************* @@ -2524,8 +2770,7 @@ ixgbe_initialize_transmit_units(struct adapter *adapter) /* Setup the Base and Length of the Tx Descriptor Ring */ for (int i = 0; i < adapter->num_tx_queues; i++, txr++) { - u64 txhwb = 0, tdba = txr->txdma.dma_paddr; - u32 txctrl; + u64 tdba = txr->txdma.dma_paddr; IXGBE_WRITE_REG(hw, IXGBE_TDBAL(i), (tdba & 0x00000000ffffffffULL)); @@ -2533,17 +2778,6 @@ ixgbe_initialize_transmit_units(struct adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_TDLEN(i), adapter->num_tx_desc * sizeof(struct ixgbe_legacy_tx_desc)); - /* Setup for Head WriteBack */ - txhwb = (u64)vtophys(&txr->tx_hwb); - txhwb |= IXGBE_TDWBAL_HEAD_WB_ENABLE; - IXGBE_WRITE_REG(hw, IXGBE_TDWBAL(i), - (txhwb & 0x00000000ffffffffULL)); - IXGBE_WRITE_REG(hw, IXGBE_TDWBAH(i), - (txhwb >> 32)); - txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i)); - txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN; - IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), txctrl); - /* Setup the HW Tx Head and Tail descriptor pointers */ IXGBE_WRITE_REG(hw, IXGBE_TDH(i), 0); IXGBE_WRITE_REG(hw, IXGBE_TDT(i), 0); @@ -2554,6 +2788,13 @@ ixgbe_initialize_transmit_units(struct adapter *adapter) txr->watchdog_timer = 0; } + if (hw->mac.type == ixgbe_mac_82599EB) { + u32 dmatxctl; + dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); + dmatxctl |= IXGBE_DMATXCTL_TE; + IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl); + } + return; } @@ -2634,7 +2875,7 @@ ixgbe_free_transmit_buffers(struct tx_ring *txr) * **********************************************************************/ -static boolean_t +static int ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) { struct adapter *adapter = txr->adapter; @@ -2642,12 +2883,12 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) struct ixgbe_tx_buf *tx_buffer; u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0; struct ether_vlan_header *eh; - struct ip *ip; + struct ip *ip = NULL; struct ip6_hdr *ip6; int ehdrlen, ip_hlen = 0; u16 etype; u8 ipproto = 0; - bool offload = TRUE; + bool offload = FALSE; int ctxd = txr->next_avail_tx_desc; #if __FreeBSD_version < 700000 struct m_tag *mtag; @@ -2656,8 +2897,8 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) #endif - if ((mp->m_pkthdr.csum_flags & CSUM_OFFLOAD) == 0) - offload = FALSE; + if (mp->m_pkthdr.csum_flags & CSUM_OFFLOAD) + offload = TRUE; tx_buffer = &txr->tx_buffers[ctxd]; TXD = (struct ixgbe_adv_tx_context_desc *) &txr->tx_base[ctxd]; @@ -2671,14 +2912,14 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) if (mtag != NULL) { vlan_macip_lens |= htole16(VLAN_TAG_VALUE(mtag)) << IXGBE_ADVTXD_VLAN_SHIFT; - } else if (offload == FALSE) - return FALSE; /* No need for CTX */ + offload = TRUE; + } #else if (mp->m_flags & M_VLANTAG) { vtag = htole16(mp->m_pkthdr.ether_vtag); vlan_macip_lens |= (vtag << IXGBE_ADVTXD_VLAN_SHIFT); - } else if (offload == FALSE) - return FALSE; + offload = TRUE; + } #endif /* * Determine where frame payload starts. @@ -2714,9 +2955,12 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) ipproto = ip6->ip6_nxt; type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV6; break; +#ifdef IXGBE_TIMESYNC + case ETHERTYPE_IEEE1588: + return (IXGBE_TIMESTAMP); +#endif default: - offload = FALSE; - break; + return (FALSE); } vlan_macip_lens |= ip_hlen; @@ -2724,18 +2968,36 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) switch (ipproto) { case IPPROTO_TCP: - if (mp->m_pkthdr.csum_flags & CSUM_TCP) + if (mp->m_pkthdr.csum_flags & CSUM_TCP) { type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP; + offload = TRUE; + } break; + case IPPROTO_UDP: - if (mp->m_pkthdr.csum_flags & CSUM_UDP) + { +#ifdef IXGBE_TIMESYNC + void *hdr = (caddr_t) ip + ip_hlen; + struct udphdr *uh = (struct udphdr *)hdr; + + if (uh->uh_dport == htons(TSYNC_UDP_PORT)) + return (IXGBE_TIMESTAMP); +#endif + if (mp->m_pkthdr.csum_flags & CSUM_UDP) { type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_UDP; + offload = TRUE; + } break; + + } + default: - offload = FALSE; - break; + return (FALSE); } + if (offload != TRUE ) + return (FALSE); + /* Now copy bits into descriptor */ TXD->vlan_macip_lens |= htole32(vlan_macip_lens); TXD->type_tucmd_mlhl |= htole32(type_tucmd_mlhl); @@ -2743,6 +3005,7 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) TXD->mss_l4len_idx = htole32(0); tx_buffer->m_head = NULL; + tx_buffer->eop_index = -1; /* We've consumed the first desc, adjust counters */ if (++ctxd == adapter->num_tx_desc) @@ -2750,7 +3013,7 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) txr->next_avail_tx_desc = ctxd; --txr->tx_avail; - return (offload); + return (TRUE); } #if __FreeBSD_version >= 700000 @@ -2774,9 +3037,6 @@ ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen) struct ip *ip; struct tcphdr *th; - if (((mp->m_pkthdr.csum_flags & CSUM_TSO) == 0) || - (mp->m_pkthdr.len <= IXGBE_TX_BUFFER_SIZE)) - return FALSE; /* * Determine where frame payload starts. @@ -2799,7 +3059,6 @@ ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen) ip = (struct ip *)(mp->m_data + ehdrlen); if (ip->ip_p != IPPROTO_TCP) return FALSE; /* 0 */ - ip->ip_len = 0; ip->ip_sum = 0; ip_hlen = ip->ip_hl << 2; th = (struct tcphdr *)((caddr_t)ip + ip_hlen); @@ -2807,6 +3066,7 @@ ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen) ip->ip_dst.s_addr, htons(IPPROTO_TCP)); tcp_hlen = th->th_off << 2; hdrlen = ehdrlen + ip_hlen + tcp_hlen; + /* This is used in the transmit desc in encap */ *paylen = mp->m_pkthdr.len - hdrlen; @@ -2834,6 +3094,7 @@ ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen) TXD->seqnum_seed = htole32(0); tx_buffer->m_head = NULL; + tx_buffer->eop_index = -1; if (++ctxd == adapter->num_tx_desc) ctxd = 0; @@ -2867,9 +3128,9 @@ ixgbe_txeof(struct tx_ring *txr) u32 first, last, done, num_avail; u32 cleaned = 0; struct ixgbe_tx_buf *tx_buffer; - struct ixgbe_legacy_tx_desc *tx_desc; + struct ixgbe_legacy_tx_desc *tx_desc, *eop_desc; - mtx_assert(&txr->mtx, MA_OWNED); + mtx_assert(&txr->tx_mtx, MA_OWNED); if (txr->tx_avail == adapter->num_tx_desc) return FALSE; @@ -2880,16 +3141,28 @@ ixgbe_txeof(struct tx_ring *txr) tx_buffer = &txr->tx_buffers[first]; /* For cleanup we just use legacy struct */ tx_desc = (struct ixgbe_legacy_tx_desc *)&txr->tx_base[first]; + last = tx_buffer->eop_index; + if (last == -1) + return FALSE; - /* Get the HWB */ - rmb(); - done = txr->tx_hwb; + eop_desc = (struct ixgbe_legacy_tx_desc *)&txr->tx_base[last]; + /* + ** Get the index of the first descriptor + ** BEYOND the EOP and call that 'done'. + ** I do this so the comparison in the + ** inner while loop below can be simple + */ + if (++last == adapter->num_tx_desc) last = 0; + done = last; bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, BUS_DMASYNC_POSTREAD); - - while (TRUE) { - /* We clean the range til last head write back */ + /* + ** Only the EOP descriptor of a packet now has the DD + ** bit set, this is what we look for... + */ + while (eop_desc->upper.fields.status & IXGBE_TXD_STAT_DD) { + /* We clean the range of the packet */ while (first != done) { tx_desc->upper.data = 0; tx_desc->lower.data = 0; @@ -2907,6 +3180,7 @@ ixgbe_txeof(struct tx_ring *txr) tx_buffer->m_head = NULL; tx_buffer->map = NULL; } + tx_buffer->eop_index = -1; if (++first == adapter->num_tx_desc) first = 0; @@ -2916,10 +3190,14 @@ ixgbe_txeof(struct tx_ring *txr) (struct ixgbe_legacy_tx_desc *)&txr->tx_base[first]; } /* See if there is more work now */ - last = done; - rmb(); - done = txr->tx_hwb; - if (last == done) + last = tx_buffer->eop_index; + if (last != -1) { + eop_desc = + (struct ixgbe_legacy_tx_desc *)&txr->tx_base[last]; + /* Get next done point */ + if (++last == adapter->num_tx_desc) last = 0; + done = last; + } else break; } bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map, @@ -3091,7 +3369,7 @@ ixgbe_allocate_receive_buffers(struct rx_ring *rxr) ** it may not always use this. */ if ((error = bus_dma_tag_create(NULL, /* parent */ - PAGE_SIZE, 0, /* alignment, bounds */ + 1, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ @@ -3244,7 +3522,7 @@ fail: * the rings that completed, the failing case will have * cleaned up for itself. 'j' failed, so its the terminus. */ - for (int i = 0; i < j; i++) { + for (int i = 0; i < j; ++i) { rxr = &adapter->rx_rings[i]; for (int n = 0; n < adapter->num_rx_desc; n++) { struct ixgbe_rx_buf *rxbuf; @@ -3314,9 +3592,21 @@ ixgbe_initialize_receive_units(struct adapter *adapter) srrctl |= ((IXGBE_RX_HDR << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) & IXGBE_SRRCTL_BSIZEHDR_MASK); srrctl |= IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS; + if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + /* PSRTYPE must be initialized in 82599 */ + u32 psrtype = IXGBE_PSRTYPE_TCPHDR | + IXGBE_PSRTYPE_UDPHDR | + IXGBE_PSRTYPE_IPV4HDR | + IXGBE_PSRTYPE_IPV6HDR; + psrtype |= (7 << 29); + IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(0), psrtype); + } } else srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; + if (adapter->hw.mac.type == ixgbe_mac_82599EB) + srrctl |= IXGBE_SRRCTL_DROP_EN; + IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(0), srrctl); for (int i = 0; i < adapter->num_rx_queues; i++, rxr++) { @@ -3356,6 +3646,9 @@ ixgbe_initialize_receive_units(struct adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), random[i]); /* Perform hash on these packet types */ + if (adapter->hw.mac.type == ixgbe_mac_82599EB) + mrqc = IXGBE_MRQC_VMDQRSS32EN; + mrqc |= IXGBE_MRQC_RSSEN | IXGBE_MRQC_RSS_FIELD_IPV4 | IXGBE_MRQC_RSS_FIELD_IPV4_TCP @@ -3380,6 +3673,14 @@ ixgbe_initialize_receive_units(struct adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum); + if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + u32 rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); + rdrxctl |= IXGBE_RDRXCTL_AGGDIS; + rdrxctl |= IXGBE_RDRXCTL_RSCLLIDIS; + rdrxctl |= IXGBE_RDRXCTL_MVMEN; + IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl); + } + return; } @@ -3594,9 +3895,15 @@ ixgbe_rxeof(struct rx_ring *rxr, int count) else rxr->fmp->m_pkthdr.csum_flags = 0; if (staterr & IXGBE_RXD_STAT_VP) { +#if __FreeBSD_version >= 700000 rxr->fmp->m_pkthdr.ether_vtag = le16toh(cur->wb.upper.vlan); rxr->fmp->m_flags |= M_VLANTAG; +#else + VLAN_INPUT_TAG_NEW(ifp, rxr->fmp, + (le16toh(cur->wb.upper.vlan) & + IXGBE_RX_DESC_SPECIAL_VLAN_MASK)); +#endif } sendmp = rxr->fmp; rxr->fmp = NULL; @@ -3765,14 +4072,23 @@ ixgbe_enable_intr(struct adapter *adapter) struct ixgbe_hw *hw = &adapter->hw; u32 mask = IXGBE_EIMS_ENABLE_MASK; + /* Enable Fan Failure detection */ - if (hw->phy.media_type == ixgbe_media_type_copper) + if (hw->device_id == IXGBE_DEV_ID_82598AT) mask |= IXGBE_EIMS_GPI_SDP1; + /* 82599 specific interrupts */ + if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + mask |= IXGBE_EIMS_ECC; + mask |= IXGBE_EIMS_GPI_SDP1; + mask |= IXGBE_EIMS_GPI_SDP2; + } + IXGBE_WRITE_REG(hw, IXGBE_EIMS, mask); /* With RSS we use auto clear */ if (adapter->msix_mem) { + mask = IXGBE_EIMS_ENABLE_MASK; /* Dont autoclear Link */ mask &= ~IXGBE_EIMS_OTHER; mask &= ~IXGBE_EIMS_LSC; @@ -3805,6 +4121,15 @@ ixgbe_read_pci_cfg(struct ixgbe_hw *hw, u32 reg) return (value); } +void +ixgbe_write_pci_cfg(struct ixgbe_hw *hw, u32 reg, u16 value) +{ + pci_write_config(((struct ixgbe_osdep *)hw->back)->dev, + reg, value, 2); + + return; +} + /* ** Setup the correct IVAR register for a particular MSIX interrupt ** (yes this is all very magic and confusing :) @@ -3834,6 +4159,21 @@ ixgbe_set_ivar(struct adapter *adapter, u16 entry, u8 vector, s8 type) IXGBE_WRITE_REG(&adapter->hw, IXGBE_IVAR(index), ivar); break; + case ixgbe_mac_82599EB: + if (type == -1) { /* MISC IVAR */ + index = (entry & 1) * 8; + ivar = IXGBE_READ_REG(hw, IXGBE_IVAR_MISC); + ivar &= ~(0xFF << index); + ivar |= (vector << index); + IXGBE_WRITE_REG(hw, IXGBE_IVAR_MISC, ivar); + } else { /* RX/TX IVARS */ + index = (16 * (entry & 1)) + (8 * type); + ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(entry >> 1)); + ivar &= ~(0xFF << index); + ivar |= (vector << index); + IXGBE_WRITE_REG(hw, IXGBE_IVAR(entry >> 1), ivar); + } + default: break; } @@ -3886,6 +4226,63 @@ out: return (result); } +/* +** Tasklet handler for MSIX Link interrupts +** - do outside interrupt since it might sleep +*/ +static void +ixgbe_handle_link(void *context, int pending) +{ + struct adapter *adapter = context; + + ixgbe_check_link(&adapter->hw, + &adapter->link_speed, &adapter->link_up, 0); + ixgbe_update_link_status(adapter); +} + +/* +** Tasklet for handling SFP module interrupts +*/ +static void +ixgbe_handle_mod(void *context, int pending) +{ + struct adapter *adapter = context; + struct ixgbe_hw *hw = &adapter->hw; + device_t dev = adapter->dev; + u32 err; + + err = hw->phy.ops.identify_sfp(hw); + if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { + device_printf(dev, + "Unsupported SFP+ module type was detected.\n"); + return; + } + hw->mac.ops.setup_sfp(hw); + taskqueue_enqueue(adapter->tq, &adapter->msf_task); + return; +} + + +/* +** Tasklet for handling MSF (multispeed fiber) interrupts +*/ +static void +ixgbe_handle_msf(void *context, int pending) +{ + struct adapter *adapter = context; + struct ixgbe_hw *hw = &adapter->hw; + u32 autoneg; + + if (hw->mac.ops.get_link_capabilities) + hw->mac.ops.get_link_capabilities(hw, &autoneg, + &hw->mac.autoneg); + if (hw->mac.ops.setup_link_speed) + hw->mac.ops.setup_link_speed(hw, autoneg, TRUE, TRUE); + ixgbe_check_link(&adapter->hw, + &adapter->link_speed, &adapter->link_up, 0); + ixgbe_update_link_status(adapter); + return; +} /********************************************************************** * @@ -3935,6 +4332,9 @@ ixgbe_update_stats_counters(struct adapter *adapter) adapter->stats.prc1522 += IXGBE_READ_REG(hw, IXGBE_PRC1522); adapter->stats.rlec += IXGBE_READ_REG(hw, IXGBE_RLEC); + adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); + adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); + lxon = IXGBE_READ_REG(hw, IXGBE_LXONTXC); adapter->stats.lxontxc += lxon; lxoff = IXGBE_READ_REG(hw, IXGBE_LXOFFTXC); @@ -4147,7 +4547,7 @@ ixgbe_set_flowcntl(SYSCTL_HANDLER_ARGS) adapter->hw.fc.requested_mode = ixgbe_fc_none; } - ixgbe_setup_fc(&adapter->hw, 0); + ixgbe_fc_enable(&adapter->hw, 0); return error; } @@ -4160,3 +4560,97 @@ ixgbe_add_rx_process_limit(struct adapter *adapter, const char *name, SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)), OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description); } + +#ifdef IXGBE_TIMESYNC +/* + * Initialize the Time Sync Feature + */ +static int +ixgbe_tsync_init(struct adapter *adapter) +{ + device_t dev = adapter->dev; + u32 tx_ctl, rx_ctl; + + + IXGBE_WRITE_REG(&adapter->hw, IXGBE_TIMINCA, (1<<24) | + 20833/PICOSECS_PER_TICK); + + adapter->last_stamp = IXGBE_READ_REG(&adapter->hw, IXGBE_SYSTIML); + adapter->last_stamp |= (u64)IXGBE_READ_REG(&adapter->hw, + IXGBE_SYSTIMH) << 32ULL; + + /* Enable the TX side */ + tx_ctl = IXGBE_READ_REG(&adapter->hw, IXGBE_TSYNCTXCTL); + tx_ctl |= 0x10; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_TSYNCTXCTL, tx_ctl); + IXGBE_WRITE_FLUSH(&adapter->hw); + + tx_ctl = IXGBE_READ_REG(&adapter->hw, IXGBE_TSYNCTXCTL); + if ((tx_ctl & 0x10) == 0) { + device_printf(dev, "Failed to enable TX timestamping\n"); + return (ENXIO); + } + + /* Enable RX */ + rx_ctl = IXGBE_READ_REG(&adapter->hw, IXGBE_TSYNCRXCTL); + rx_ctl |= 0x10; /* Enable the feature */ + rx_ctl |= 0x04; /* This value turns on Ver 1 and 2 */ + IXGBE_WRITE_REG(&adapter->hw, IXGBE_TSYNCRXCTL, rx_ctl); + + /* + * Ethertype Filter Queue Filter[0][15:0] = 0x88F7 (Ethertype) + * Ethertype Filter Queue Filter[0][30] = 0x1 (Enable filter) + * Ethertype Filter Queue Filter[0][31] = 0x1 (Enable Timestamping) + */ + IXGBE_WRITE_REG(&adapter->hw, IXGBE_ETQF(0), 0xC00088f7); + + IXGBE_WRITE_FLUSH(&adapter->hw); + + rx_ctl = IXGBE_READ_REG(&adapter->hw, IXGBE_TSYNCRXCTL); + if ((rx_ctl & 0x10) == 0) { + device_printf(dev, "Failed to enable RX timestamping\n"); + return (ENXIO); + } + + device_printf(dev, "IEEE 1588 Precision Time Protocol enabled\n"); + + return (0); +} + +/* + * Disable the Time Sync Feature + */ +static void +ixgbe_tsync_disable(struct adapter *adapter) +{ + u32 tx_ctl, rx_ctl; + + tx_ctl = IXGBE_READ_REG(&adapter->hw, IXGBE_TSYNCTXCTL); + tx_ctl &= ~0x10; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_TSYNCTXCTL, tx_ctl); + IXGBE_WRITE_FLUSH(&adapter->hw); + + /* Invalidate TX Timestamp */ + IXGBE_READ_REG(&adapter->hw, IXGBE_TXSTMPH); + + tx_ctl = IXGBE_READ_REG(&adapter->hw, IXGBE_TSYNCTXCTL); + if (tx_ctl & 0x10) + HW_DEBUGOUT("Failed to disable TX timestamping\n"); + + rx_ctl = IXGBE_READ_REG(&adapter->hw, IXGBE_TSYNCRXCTL); + rx_ctl &= ~0x10; + + IXGBE_WRITE_REG(&adapter->hw, IXGBE_TSYNCRXCTL, rx_ctl); + IXGBE_WRITE_FLUSH(&adapter->hw); + + /* Invalidate RX Timestamp */ + IXGBE_READ_REG(&adapter->hw, IXGBE_RXSATRH); + + rx_ctl = IXGBE_READ_REG(&adapter->hw, IXGBE_TSYNCRXCTL); + if (rx_ctl & 0x10) + HW_DEBUGOUT("Failed to disable RX timestamping\n"); + + return; +} + +#endif /* IXGBE_TIMESYNC */ diff --git a/sys/dev/ixgbe/ixgbe.h b/sys/dev/ixgbe/ixgbe.h index 5a5e2efc615..e6bebd1d200 100644 --- a/sys/dev/ixgbe/ixgbe.h +++ b/sys/dev/ixgbe/ixgbe.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2009, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -64,6 +64,7 @@ #include #include #include +#include #include #include @@ -83,8 +84,12 @@ #include #include +#ifdef IXGBE_TIMESYNC +#include +#include +#endif + #include "ixgbe_api.h" -#include "tcp_lro.h" /* Tunables */ @@ -95,7 +100,7 @@ * bytes. Performance tests have show the 2K value to be optimal for top * performance. */ -#define DEFAULT_TXD 256 +#define DEFAULT_TXD 1024 #define PERFORM_TXD 2048 #define MAX_TXD 4096 #define MIN_TXD 64 @@ -110,7 +115,7 @@ * against the system mbuf pool limit, you can tune nmbclusters * to adjust for this. */ -#define DEFAULT_RXD 256 +#define DEFAULT_RXD 1024 #define PERFORM_RXD 2048 #define MAX_RXD 4096 #define MIN_RXD 64 @@ -159,7 +164,8 @@ #define HW_DEBUGOUT2(S, A, B) if (DEBUG_HW) printf(S "\n", A, B) #define MAX_NUM_MULTICAST_ADDRESSES 128 -#define IXGBE_MAX_SCATTER 100 +#define IXGBE_82598_SCATTER 100 +#define IXGBE_82599_SCATTER 32 #define MSIX_82598_BAR 3 #define MSIX_82599_BAR 4 #define IXGBE_TSO_SIZE 65535 @@ -171,12 +177,13 @@ #define IXGBE_MSGS 18 /* For 6.X code compatibility */ -#if __FreeBSD_version < 700000 +#if !defined(ETHER_BPF_MTAP) #define ETHER_BPF_MTAP BPF_MTAP +#endif + +#if __FreeBSD_version < 700000 #define CSUM_TSO 0 #define IFCAP_TSO4 0 -#define FILTER_STRAY -#define FILTER_HANDLED #endif /* @@ -214,6 +221,7 @@ typedef struct _ixgbe_vendor_info_t { struct ixgbe_tx_buf { + u32 eop_index; struct mbuf *m_head; bus_dmamap_t map; }; @@ -314,8 +322,6 @@ struct adapter { /* * Interrupt resources: - * Oplin has 20 MSIX messages - * so allocate that for now. */ void *tag[IXGBE_MSGS]; struct resource *res[IXGBE_MSGS]; @@ -334,6 +340,7 @@ struct adapter { bool link_active; u16 max_frame_size; u32 link_speed; + bool link_up; u32 linkvec; u32 tx_int_delay; u32 tx_abs_int_delay; @@ -343,8 +350,12 @@ struct adapter { /* Mbuf cluster size */ u32 rx_mbuf_sz; - /* Check for missing optics */ + /* Support for pluggable optics */ bool sfp_probe; + struct task link_task; /* Link tasklet */ + struct task mod_task; /* SFP tasklet */ + struct task msf_task; /* Multispeed Fiber tasklet */ + struct taskqueue *tq; /* * Transmit rings: @@ -364,6 +375,12 @@ struct adapter { u32 rx_mask; u32 rx_process_limit; +#ifdef IXGBE_TIMESYNC + u64 last_stamp; + u64 last_sec; + u32 last_ns; +#endif + /* Misc stats maintained by the driver */ unsigned long dropped_pkts; unsigned long mbuf_defrag_failed; @@ -378,6 +395,32 @@ struct adapter { struct ixgbe_hw_stats stats; }; +#ifdef IXGBE_TIMESYNC +/* Precision Time Sync (IEEE 1588) defines */ +#define ETHERTYPE_IEEE1588 0x88F7 +#define PICOSECS_PER_TICK 20833 +#define TSYNC_UDP_PORT 319 /* UDP port for the protocol */ +#define IXGBE_ADVTXD_TSTAMP 0x00080000 + +/* TIMESYNC IOCTL defines */ +#define IXGBE_TIMESYNC_READTS _IOWR('i', 127, struct ixgbe_tsync_read) +#define IXGBE_TIMESTAMP 5 /* A unique return value */ + +/* Used in the READTS IOCTL */ +struct ixgbe_tsync_read { + int read_current_time; + struct timespec system_time; + u64 network_time; + u64 rx_stamp; + u64 tx_stamp; + u16 seqid; + unsigned char srcid[6]; + int rx_valid; + int tx_valid; +}; + +#endif /* IXGBE_TIMESYNC */ + #define IXGBE_CORE_LOCK_INIT(_sc, _name) \ mtx_init(&(_sc)->core_mtx, _name, "IXGBE Core Lock", MTX_DEF) #define IXGBE_CORE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->core_mtx) @@ -385,6 +428,7 @@ struct adapter { #define IXGBE_RX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rx_mtx) #define IXGBE_CORE_LOCK(_sc) mtx_lock(&(_sc)->core_mtx) #define IXGBE_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_mtx) +#define IXGBE_TX_TRYLOCK(_sc) mtx_trylock(&(_sc)->tx_mtx) #define IXGBE_RX_LOCK(_sc) mtx_lock(&(_sc)->rx_mtx) #define IXGBE_CORE_UNLOCK(_sc) mtx_unlock(&(_sc)->core_mtx) #define IXGBE_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->tx_mtx) @@ -393,4 +437,20 @@ struct adapter { #define IXGBE_TX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->tx_mtx, MA_OWNED) +static inline bool +ixgbe_is_sfp(struct ixgbe_hw *hw) +{ + switch (hw->phy.type) { + case ixgbe_phy_sfp_avago: + case ixgbe_phy_sfp_ftl: + case ixgbe_phy_sfp_intel: + case ixgbe_phy_sfp_unknown: + case ixgbe_phy_tw_tyco: + case ixgbe_phy_tw_unknown: + return TRUE; + default: + return FALSE; + } +} + #endif /* _IXGBE_H_ */ diff --git a/sys/dev/ixgbe/ixgbe_82598.c b/sys/dev/ixgbe/ixgbe_82598.c index c94b2f97893..fd90d16302f 100644 --- a/sys/dev/ixgbe/ixgbe_82598.c +++ b/sys/dev/ixgbe/ixgbe_82598.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2009, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -37,15 +37,12 @@ #include "ixgbe_common.h" #include "ixgbe_phy.h" +u32 ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw); s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw); static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw, ixgbe_link_speed *speed, bool *autoneg); -s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw, - ixgbe_link_speed *speed, - bool *autoneg); static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw); -s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num); s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num); static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw); static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, @@ -60,22 +57,41 @@ static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete); -#ifndef NO_82598_A0_SUPPORT -s32 ixgbe_reset_hw_rev_0_82598(struct ixgbe_hw *hw); -#endif static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw); s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq); static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq); s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on); static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw); -static s32 ixgbe_blink_led_stop_82598(struct ixgbe_hw *hw, u32 index); -static s32 ixgbe_blink_led_start_82598(struct ixgbe_hw *hw, u32 index); s32 ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val); s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val); s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, u8 *eeprom_data); u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw); +s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw); + +/** + * ixgbe_get_pcie_msix_count_82598 - Gets MSI-X vector count + * @hw: pointer to hardware structure + * + * Read PCIe configuration space, and get the MSI-X vector count from + * the capabilities table. + **/ +u32 ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw) +{ + u32 msix_count = 18; + + if (hw->mac.msix_vectors_from_pcie) { + msix_count = IXGBE_READ_PCIE_WORD(hw, + IXGBE_PCIE_MSIX_82598_CAPS); + msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK; + + /* MSI-X count is zero-based in HW, so increment to give + * proper value */ + msix_count++; + } + return msix_count; +} /** * ixgbe_init_ops_82598 - Inits func ptrs and MAC type @@ -89,30 +105,21 @@ s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw) struct ixgbe_mac_info *mac = &hw->mac; struct ixgbe_phy_info *phy = &hw->phy; s32 ret_val; - u16 list_offset, data_offset; ret_val = ixgbe_init_phy_ops_generic(hw); ret_val = ixgbe_init_ops_generic(hw); + /* PHY */ + phy->ops.init = &ixgbe_init_phy_ops_82598; + /* MAC */ -#ifndef NO_82598_A0_SUPPORT - if (hw->revision_id == 0) - mac->ops.reset_hw = &ixgbe_reset_hw_rev_0_82598; - else - mac->ops.reset_hw = &ixgbe_reset_hw_82598; -#else mac->ops.reset_hw = &ixgbe_reset_hw_82598; -#endif mac->ops.get_media_type = &ixgbe_get_media_type_82598; mac->ops.get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82598; mac->ops.read_analog_reg8 = &ixgbe_read_analog_reg8_82598; mac->ops.write_analog_reg8 = &ixgbe_write_analog_reg8_82598; - /* LEDs */ - mac->ops.blink_led_start = &ixgbe_blink_led_start_82598; - mac->ops.blink_led_stop = &ixgbe_blink_led_stop_82598; - /* RAR, Multicast, VLAN */ mac->ops.set_vmdq = &ixgbe_set_vmdq_82598; mac->ops.clear_vmdq = &ixgbe_clear_vmdq_82598; @@ -120,42 +127,67 @@ s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw) mac->ops.clear_vfta = &ixgbe_clear_vfta_82598; /* Flow Control */ - mac->ops.setup_fc = &ixgbe_setup_fc_82598; - - /* Link */ - mac->ops.check_link = &ixgbe_check_mac_link_82598; - if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) { - mac->ops.setup_link = &ixgbe_setup_copper_link_82598; - mac->ops.setup_link_speed = - &ixgbe_setup_copper_link_speed_82598; - mac->ops.get_link_capabilities = - &ixgbe_get_copper_link_capabilities_82598; - } else { - mac->ops.setup_link = &ixgbe_setup_mac_link_82598; - mac->ops.setup_link_speed = &ixgbe_setup_mac_link_speed_82598; - mac->ops.get_link_capabilities = - &ixgbe_get_link_capabilities_82598; - } + mac->ops.fc_enable = &ixgbe_fc_enable_82598; mac->mcft_size = 128; mac->vft_size = 128; mac->num_rar_entries = 16; mac->max_tx_queues = 32; mac->max_rx_queues = 64; + mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82598(hw); /* SFP+ Module */ phy->ops.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_82598; - /* Call PHY identify routine to get the phy type */ + /* Link */ + mac->ops.check_link = &ixgbe_check_mac_link_82598; + mac->ops.setup_link = &ixgbe_setup_mac_link_82598; + mac->ops.setup_link_speed = &ixgbe_setup_mac_link_speed_82598; + mac->ops.get_link_capabilities = + &ixgbe_get_link_capabilities_82598; + + return ret_val; +} + +/** + * ixgbe_init_phy_ops_82598 - PHY/SFP specific init + * @hw: pointer to hardware structure + * + * Initialize any function pointers that were not able to be + * set during init_shared_code because the PHY/SFP type was + * not known. Perform the SFP init if necessary. + * + **/ +s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + struct ixgbe_phy_info *phy = &hw->phy; + s32 ret_val = IXGBE_SUCCESS; + u16 list_offset, data_offset; + + + /* Identify the PHY */ phy->ops.identify(hw); - /* PHY Init */ + /* Overwrite the link function pointers if copper PHY */ + if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) { + mac->ops.setup_link = &ixgbe_setup_copper_link_82598; + mac->ops.setup_link_speed = + &ixgbe_setup_copper_link_speed_82598; + mac->ops.get_link_capabilities = + &ixgbe_get_copper_link_capabilities_generic; + } + switch (hw->phy.type) { case ixgbe_phy_tn: phy->ops.check_link = &ixgbe_check_phy_link_tnx; phy->ops.get_firmware_version = &ixgbe_get_phy_firmware_version_tnx; break; + case ixgbe_phy_aq: + phy->ops.get_firmware_version = + &ixgbe_get_phy_firmware_version_aq; + break; case ixgbe_phy_nl: phy->ops.reset = &ixgbe_reset_phy_nl; @@ -198,18 +230,19 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw, bool *autoneg) { s32 status = IXGBE_SUCCESS; - s32 autoc_reg; + u32 autoc = 0; - autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); + /* + * Determine link capabilities based on the stored value of AUTOC, + * which represents EEPROM defaults. If AUTOC value has not been + * stored, use the current register value. + */ + if (hw->mac.orig_link_settings_stored) + autoc = hw->mac.orig_autoc; + else + autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); - if (hw->mac.link_settings_loaded) { - autoc_reg &= ~IXGBE_AUTOC_LMS_ATTACH_TYPE; - autoc_reg &= ~IXGBE_AUTOC_LMS_MASK; - autoc_reg |= hw->mac.link_attach_type; - autoc_reg |= hw->mac.link_mode_select; - } - - switch (autoc_reg & IXGBE_AUTOC_LMS_MASK) { + switch (autoc & IXGBE_AUTOC_LMS_MASK) { case IXGBE_AUTOC_LMS_1G_LINK_NO_AN: *speed = IXGBE_LINK_SPEED_1GB_FULL; *autoneg = FALSE; @@ -228,9 +261,9 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw, case IXGBE_AUTOC_LMS_KX4_AN: case IXGBE_AUTOC_LMS_KX4_AN_1G_AN: *speed = IXGBE_LINK_SPEED_UNKNOWN; - if (autoc_reg & IXGBE_AUTOC_KX4_SUPP) + if (autoc & IXGBE_AUTOC_KX4_SUPP) *speed |= IXGBE_LINK_SPEED_10GB_FULL; - if (autoc_reg & IXGBE_AUTOC_KX_SUPP) + if (autoc & IXGBE_AUTOC_KX_SUPP) *speed |= IXGBE_LINK_SPEED_1GB_FULL; *autoneg = TRUE; break; @@ -243,38 +276,6 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw, return status; } -/** - * ixgbe_get_copper_link_capabilities_82598 - Determines link capabilities - * @hw: pointer to hardware structure - * @speed: pointer to link speed - * @autoneg: boolean auto-negotiation value - * - * Determines the link capabilities by reading the AUTOC register. - **/ -s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw, - ixgbe_link_speed *speed, - bool *autoneg) -{ - s32 status = IXGBE_ERR_LINK_SETUP; - u16 speed_ability; - - *speed = 0; - *autoneg = TRUE; - - status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY, - IXGBE_MDIO_PMA_PMD_DEV_TYPE, - &speed_ability); - - if (status == IXGBE_SUCCESS) { - if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G) - *speed |= IXGBE_LINK_SPEED_10GB_FULL; - if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G) - *speed |= IXGBE_LINK_SPEED_1GB_FULL; - } - - return status; -} - /** * ixgbe_get_media_type_82598 - Determines media type * @hw: pointer to hardware structure @@ -285,9 +286,18 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw) { enum ixgbe_media_type media_type; + /* Detect if there is a copper PHY attached. */ + if (hw->phy.type == ixgbe_phy_cu_unknown || + hw->phy.type == ixgbe_phy_tn || + hw->phy.type == ixgbe_phy_aq) { + media_type = ixgbe_media_type_copper; + goto out; + } + /* Media type for I82598 is based on device ID */ switch (hw->device_id) { case IXGBE_DEV_ID_82598: + case IXGBE_DEV_ID_82598_BX: /* Default device ID is mezzanine card KX/KX4 */ media_type = ixgbe_media_type_backplane; break; @@ -308,7 +318,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw) media_type = ixgbe_media_type_unknown; break; } - +out: return media_type; } @@ -328,6 +338,12 @@ s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) DEBUGFUNC("ixgbe_fc_enable_82598"); + /* Negotiate the fc mode to use */ + ret_val = ixgbe_fc_autoneg(hw); + if (ret_val) + goto out; + + /* Disable any previous flow control settings */ fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE); @@ -339,14 +355,16 @@ s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) * 0: Flow control is completely disabled * 1: Rx flow control is enabled (we can receive pause frames, * but not send pause frames). - * 2: Tx flow control is enabled (we can send pause frames but + * 2: Tx flow control is enabled (we can send pause frames but * we do not support receiving pause frames). * 3: Both Rx and Tx flow control (symmetric) are enabled. * other: Invalid. */ switch (hw->fc.current_mode) { case ixgbe_fc_none: - /* Flow control completely disabled by software override. */ + /* Flow control is disabled by software override or autoneg. + * The code below will actually disable it in the HW. + */ break; case ixgbe_fc_rx_pause: /* @@ -378,7 +396,8 @@ s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) break; } - /* Enable 802.3x based flow control settings. */ + /* Set 802.3x based flow control settings. */ + fctrl_reg |= IXGBE_FCTRL_DPF; IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg); IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg); @@ -410,73 +429,6 @@ out: return ret_val; } -/** - * ixgbe_setup_fc_82598 - Set up flow control - * @hw: pointer to hardware structure - * - * Sets up flow control. - **/ -s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num) -{ - s32 ret_val = IXGBE_SUCCESS; - ixgbe_link_speed speed; - bool link_up; - - /* Validate the packetbuf configuration */ - if (packetbuf_num < 0 || packetbuf_num > 7) { - DEBUGOUT1("Invalid packet buffer number [%d], expected range is" - " 0-7\n", packetbuf_num); - ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; - goto out; - } - - /* - * Validate the water mark configuration. Zero water marks are invalid - * because it causes the controller to just blast out fc packets. - */ - if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) { - DEBUGOUT("Invalid water mark configuration\n"); - ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; - goto out; - } - - /* - * Validate the requested mode. Strict IEEE mode does not allow - * ixgbe_fc_rx_pause because it will cause testing anomalies. - */ - if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { - DEBUGOUT("ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); - ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; - goto out; - } - - /* - * 10gig parts do not have a word in the EEPROM to determine the - * default flow control setting, so we explicitly set it to full. - */ - if (hw->fc.requested_mode == ixgbe_fc_default) - hw->fc.requested_mode = ixgbe_fc_full; - - /* - * Save off the requested flow control mode for use later. Depending - * on the link partner's capabilities, we may or may not use this mode. - */ - hw->fc.current_mode = hw->fc.requested_mode; - - /* Decide whether to use autoneg or not. */ - hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); - if (hw->phy.multispeed_fiber && (speed == IXGBE_LINK_SPEED_1GB_FULL)) - ret_val = ixgbe_fc_autoneg(hw); - - if (ret_val) - goto out; - - ret_val = ixgbe_fc_enable_82598(hw, packetbuf_num); - -out: - return ret_val; -} - /** * ixgbe_setup_mac_link_82598 - Configures MAC link settings * @hw: pointer to hardware structure @@ -491,27 +443,17 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw) u32 i; s32 status = IXGBE_SUCCESS; - autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); - - if (hw->mac.link_settings_loaded) { - autoc_reg &= ~IXGBE_AUTOC_LMS_ATTACH_TYPE; - autoc_reg &= ~IXGBE_AUTOC_LMS_MASK; - autoc_reg |= hw->mac.link_attach_type; - autoc_reg |= hw->mac.link_mode_select; - - IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); - IXGBE_WRITE_FLUSH(hw); - msec_delay(50); - } - /* Restart link */ + autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); autoc_reg |= IXGBE_AUTOC_AN_RESTART; IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); /* Only poll for autoneg to complete if specified to do so */ if (hw->phy.autoneg_wait_to_complete) { - if (hw->mac.link_mode_select == IXGBE_AUTOC_LMS_KX4_AN || - hw->mac.link_mode_select == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) { + if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) == + IXGBE_AUTOC_LMS_KX4_AN || + (autoc_reg & IXGBE_AUTOC_LMS_MASK) == + IXGBE_AUTOC_LMS_KX4_AN_1G_AN) { links_reg = 0; /* Just in case Autoneg time = 0 */ for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) { links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); @@ -526,9 +468,6 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw) } } - /* Set up flow control */ - status = ixgbe_setup_fc_82598(hw, 0); - /* Add delay to filter out noises during initial link setup */ msec_delay(50); @@ -616,6 +555,11 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, else *speed = IXGBE_LINK_SPEED_1GB_FULL; + /* if link is down, zero out the current_mode */ + if (*link_up == FALSE) { + hw->fc.current_mode = ixgbe_fc_none; + hw->fc.fc_was_autonegged = FALSE; + } out: return IXGBE_SUCCESS; } @@ -633,28 +577,34 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete) { - s32 status = IXGBE_SUCCESS; + s32 status = IXGBE_SUCCESS; + ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN; + u32 curr_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); + u32 autoc = curr_autoc; + u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK; - /* If speed is 10G, then check for CX4 or XAUI. */ - if ((speed == IXGBE_LINK_SPEED_10GB_FULL) && - (!(hw->mac.link_attach_type & IXGBE_AUTOC_10G_KX4))) { - hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN; - } else if ((speed == IXGBE_LINK_SPEED_1GB_FULL) && (!autoneg)) { - hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_LINK_NO_AN; - } else if (autoneg) { - /* BX mode - Autonegotiate 1G */ - if (!(hw->mac.link_attach_type & IXGBE_AUTOC_1G_PMA_PMD)) - hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_AN; - else /* KX/KX4 mode */ - hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN_1G_AN; - } else { + /* Check to see if speed passed in is supported. */ + ixgbe_get_link_capabilities(hw, &link_capabilities, &autoneg); + speed &= link_capabilities; + + if (speed == IXGBE_LINK_SPEED_UNKNOWN) status = IXGBE_ERR_LINK_SETUP; + + /* Set KX4/KX support according to speed requested */ + else if (link_mode == IXGBE_AUTOC_LMS_KX4_AN || + link_mode == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) { + autoc &= ~IXGBE_AUTOC_KX4_KX_SUPP_MASK; + if (speed & IXGBE_LINK_SPEED_10GB_FULL) + autoc |= IXGBE_AUTOC_KX4_SUPP; + if (speed & IXGBE_LINK_SPEED_1GB_FULL) + autoc |= IXGBE_AUTOC_KX_SUPP; + if (autoc != curr_autoc) + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc); } if (status == IXGBE_SUCCESS) { hw->phy.autoneg_wait_to_complete = autoneg_wait_to_complete; - hw->mac.link_settings_loaded = TRUE; /* * Setup and restart the link based on the new values in * ixgbe_hw This will write the AUTOC register based on the new @@ -683,10 +633,6 @@ static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw) /* Restart autonegotiation on PHY */ status = hw->phy.ops.setup_link(hw); - /* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */ - hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX); - hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN; - /* Set up MAC */ ixgbe_setup_mac_link_82598(hw); @@ -712,110 +658,12 @@ static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, /* Setup the PHY according to input speed */ status = hw->phy.ops.setup_link_speed(hw, speed, autoneg, autoneg_wait_to_complete); - - /* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */ - hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX); - hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN; - /* Set up MAC */ ixgbe_setup_mac_link_82598(hw); return status; } -#ifndef NO_82598_A0_SUPPORT -/** - * ixgbe_reset_hw_rev_0_82598 - Performs hardware reset - * @hw: pointer to hardware structure - * - * Resets the hardware by resetting the transmit and receive units, masks and - * clears all interrupts, performing a PHY reset, and performing a link (MAC) - * reset. - **/ -s32 ixgbe_reset_hw_rev_0_82598(struct ixgbe_hw *hw) -{ - s32 status = IXGBE_SUCCESS; - u32 ctrl; - u32 gheccr; - u32 autoc; - u32 i; - u32 resets; - - /* Call adapter stop to disable tx/rx and clear interrupts */ - hw->mac.ops.stop_adapter(hw); - - /* Reset PHY */ - hw->phy.ops.reset(hw); - - for (resets = 0; resets < 10; resets++) { - /* - * Prevent the PCI-E bus from from hanging by disabling PCI-E - * master access and verify no pending requests before reset - */ - if (ixgbe_disable_pcie_master(hw) != IXGBE_SUCCESS) { - status = IXGBE_ERR_MASTER_REQUESTS_PENDING; - DEBUGOUT("PCI-E Master disable polling has failed.\n"); - } - - /* - * Issue global reset to the MAC. This needs to be a SW reset. - * If link reset is used, it might reset the MAC when mng is - * using it. - */ - ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); - IXGBE_WRITE_REG(hw, IXGBE_CTRL, (ctrl | IXGBE_CTRL_RST)); - IXGBE_WRITE_FLUSH(hw); - - /* - * Poll for reset bit to self-clear indicating reset is - * complete - */ - for (i = 0; i < 10; i++) { - usec_delay(1); - ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); - if (!(ctrl & IXGBE_CTRL_RST)) - break; - } - if (ctrl & IXGBE_CTRL_RST) { - status = IXGBE_ERR_RESET_FAILED; - DEBUGOUT("Reset polling failed to complete.\n"); - } - } - - msec_delay(50); - - gheccr = IXGBE_READ_REG(hw, IXGBE_GHECCR); - gheccr &= ~((1 << 21) | (1 << 18) | (1 << 9) | (1 << 6)); - IXGBE_WRITE_REG(hw, IXGBE_GHECCR, gheccr); - - /* - * AUTOC register which stores link settings gets cleared - * and reloaded from EEPROM after reset. We need to restore - * our stored value from init in case SW changed the attach - * type or speed. If this is the first time and link settings - * have not been stored, store default settings from AUTOC. - */ - autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); - if (hw->mac.link_settings_loaded) { - autoc &= ~(IXGBE_AUTOC_LMS_ATTACH_TYPE); - autoc &= ~(IXGBE_AUTOC_LMS_MASK); - autoc |= hw->mac.link_attach_type; - autoc |= hw->mac.link_mode_select; - IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc); - } else { - hw->mac.link_attach_type = - (autoc & IXGBE_AUTOC_LMS_ATTACH_TYPE); - hw->mac.link_mode_select = (autoc & IXGBE_AUTOC_LMS_MASK); - hw->mac.link_settings_loaded = TRUE; - } - - /* Store the permanent mac address */ - hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); - - return status; -} - -#endif /* NO_A0_SUPPORT */ /** * ixgbe_reset_hw_82598 - Performs hardware reset * @hw: pointer to hardware structure @@ -870,14 +718,23 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) } /* Reset PHY */ - if (hw->phy.reset_disable == FALSE) + if (hw->phy.reset_disable == FALSE) { + /* PHY ops must be identified and initialized prior to reset */ + + /* Init PHY and function pointers, perform SFP setup */ + status = hw->phy.ops.init(hw); + if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) + goto reset_hw_out; + hw->phy.ops.reset(hw); + } /* * Prevent the PCI-E bus from from hanging by disabling PCI-E master * access and verify no pending requests before reset */ - if (ixgbe_disable_pcie_master(hw) != IXGBE_SUCCESS) { + status = ixgbe_disable_pcie_master(hw); + if (status != IXGBE_SUCCESS) { status = IXGBE_ERR_MASTER_REQUESTS_PENDING; DEBUGOUT("PCI-E Master disable polling has failed.\n"); } @@ -909,29 +766,27 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) IXGBE_WRITE_REG(hw, IXGBE_GHECCR, gheccr); /* - * AUTOC register which stores link settings gets cleared - * and reloaded from EEPROM after reset. We need to restore - * our stored value from init in case SW changed the attach - * type or speed. If this is the first time and link settings - * have not been stored, store default settings from AUTOC. + * Store the original AUTOC value if it has not been + * stored off yet. Otherwise restore the stored original + * AUTOC value since the reset operation sets back to deaults. */ autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); - if (hw->mac.link_settings_loaded) { - autoc &= ~(IXGBE_AUTOC_LMS_ATTACH_TYPE); - autoc &= ~(IXGBE_AUTOC_LMS_MASK); - autoc |= hw->mac.link_attach_type; - autoc |= hw->mac.link_mode_select; - IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc); - } else { - hw->mac.link_attach_type = - (autoc & IXGBE_AUTOC_LMS_ATTACH_TYPE); - hw->mac.link_mode_select = (autoc & IXGBE_AUTOC_LMS_MASK); - hw->mac.link_settings_loaded = TRUE; - } + if (hw->mac.orig_link_settings_stored == FALSE) { + hw->mac.orig_autoc = autoc; + hw->mac.orig_link_settings_stored = TRUE; + } else if (autoc != hw->mac.orig_autoc) + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc); + + /* + * Store MAC address from RAR0, clear receive address registers, and + * clear the multicast table + */ + hw->mac.ops.init_rx_addrs(hw); /* Store the permanent mac address */ hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); +reset_hw_out: return status; } @@ -1048,61 +903,6 @@ static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw) return IXGBE_SUCCESS; } -/** - * ixgbe_blink_led_start_82598 - Blink LED based on index. - * @hw: pointer to hardware structure - * @index: led number to blink - **/ -static s32 ixgbe_blink_led_start_82598(struct ixgbe_hw *hw, u32 index) -{ - ixgbe_link_speed speed = 0; - bool link_up = 0; - u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); - u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); - - /* - * Link must be up to auto-blink the LEDs on the 82598EB MAC; - * force it if link is down. - */ - hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); - - if (!link_up) { - autoc_reg |= IXGBE_AUTOC_FLU; - IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); - msec_delay(10); - } - - led_reg &= ~IXGBE_LED_MODE_MASK(index); - led_reg |= IXGBE_LED_BLINK(index); - IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); - IXGBE_WRITE_FLUSH(hw); - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_blink_led_stop_82598 - Stop blinking LED based on index. - * @hw: pointer to hardware structure - * @index: led number to stop blinking - **/ -static s32 ixgbe_blink_led_stop_82598(struct ixgbe_hw *hw, u32 index) -{ - u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); - u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); - - autoc_reg &= ~IXGBE_AUTOC_FLU; - autoc_reg |= IXGBE_AUTOC_AN_RESTART; - IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); - - led_reg &= ~IXGBE_LED_MODE_MASK(index); - led_reg &= ~IXGBE_LED_BLINK(index); - led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); - IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); - IXGBE_WRITE_FLUSH(hw); - - return IXGBE_SUCCESS; -} - /** * ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register * @hw: pointer to hardware structure @@ -1216,33 +1016,56 @@ out: u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw) { u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; + u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); + u32 pma_pmd_10g = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK; + u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK; + u16 ext_ability = 0; - switch (hw->device_id) { - case IXGBE_DEV_ID_82598: - /* Default device ID is mezzanine card KX/KX4 */ - physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_KX4 | - IXGBE_PHYSICAL_LAYER_1000BASE_KX); + hw->phy.ops.identify(hw); + + /* Copper PHY must be checked before AUTOC LMS to determine correct + * physical layer because 10GBase-T PHYs use LMS = KX4/KX */ + if (hw->phy.type == ixgbe_phy_tn || + hw->phy.type == ixgbe_phy_cu_unknown) { + hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability); + if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY) + physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; + if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY) + physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; + if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY) + physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; + goto out; + } + + switch (autoc & IXGBE_AUTOC_LMS_MASK) { + case IXGBE_AUTOC_LMS_1G_AN: + case IXGBE_AUTOC_LMS_1G_LINK_NO_AN: + if (pma_pmd_1g == IXGBE_AUTOC_1G_KX) + physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX; + else + physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX; break; - case IXGBE_DEV_ID_82598EB_CX4: - case IXGBE_DEV_ID_82598_CX4_DUAL_PORT: - physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4; + case IXGBE_AUTOC_LMS_10G_LINK_NO_AN: + if (pma_pmd_10g == IXGBE_AUTOC_10G_CX4) + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4; + else if (pma_pmd_10g == IXGBE_AUTOC_10G_KX4) + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4; + else /* XAUI */ + physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; break; - case IXGBE_DEV_ID_82598_DA_DUAL_PORT: - physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU; + case IXGBE_AUTOC_LMS_KX4_AN: + case IXGBE_AUTOC_LMS_KX4_AN_1G_AN: + if (autoc & IXGBE_AUTOC_KX_SUPP) + physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX; + if (autoc & IXGBE_AUTOC_KX4_SUPP) + physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4; break; - case IXGBE_DEV_ID_82598AF_DUAL_PORT: - case IXGBE_DEV_ID_82598AF_SINGLE_PORT: - case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM: - physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR; + default: break; - case IXGBE_DEV_ID_82598EB_XF_LR: - physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR; - break; - case IXGBE_DEV_ID_82598AT: - physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_T | - IXGBE_PHYSICAL_LAYER_1000BASE_T); - break; - case IXGBE_DEV_ID_82598EB_SFP_LOM: + } + + if (hw->phy.type == ixgbe_phy_nl) { hw->phy.ops.identify_sfp(hw); switch (hw->phy.sfp_type) { @@ -1259,12 +1082,24 @@ u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw) physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; break; } - break; + } + switch (hw->device_id) { + case IXGBE_DEV_ID_82598_DA_DUAL_PORT: + physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU; + break; + case IXGBE_DEV_ID_82598AF_DUAL_PORT: + case IXGBE_DEV_ID_82598AF_SINGLE_PORT: + case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM: + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR; + break; + case IXGBE_DEV_ID_82598EB_XF_LR: + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR; + break; default: - physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; break; } +out: return physical_layer; } diff --git a/sys/dev/ixgbe/ixgbe_api.c b/sys/dev/ixgbe/ixgbe_api.c index 49dac7d04fd..a3e7b359534 100644 --- a/sys/dev/ixgbe/ixgbe_api.c +++ b/sys/dev/ixgbe/ixgbe_api.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2009, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -36,6 +36,7 @@ #include "ixgbe_common.h" extern s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw); +extern s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw); /** * ixgbe_init_shared_code - Initialize the shared code @@ -62,6 +63,9 @@ s32 ixgbe_init_shared_code(struct ixgbe_hw *hw) case ixgbe_mac_82598EB: status = ixgbe_init_ops_82598(hw); break; + case ixgbe_mac_82599EB: + status = ixgbe_init_ops_82599(hw); + break; default: status = IXGBE_ERR_DEVICE_NOT_SUPPORTED; break; @@ -86,6 +90,7 @@ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw) if (hw->vendor_id == IXGBE_INTEL_VENDOR_ID) { switch (hw->device_id) { case IXGBE_DEV_ID_82598: + case IXGBE_DEV_ID_82598_BX: case IXGBE_DEV_ID_82598AF_SINGLE_PORT: case IXGBE_DEV_ID_82598AF_DUAL_PORT: case IXGBE_DEV_ID_82598AT: @@ -97,6 +102,11 @@ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw) case IXGBE_DEV_ID_82598EB_SFP_LOM: hw->mac.type = ixgbe_mac_82598EB; break; + case IXGBE_DEV_ID_82599_KX4: + case IXGBE_DEV_ID_82599_SFP: + case IXGBE_DEV_ID_82599_CX4: + hw->mac.type = ixgbe_mac_82599EB; + break; default: ret_val = IXGBE_ERR_DEVICE_NOT_SUPPORTED; break; @@ -192,6 +202,46 @@ s32 ixgbe_get_mac_addr(struct ixgbe_hw *hw, u8 *mac_addr) (hw, mac_addr), IXGBE_NOT_IMPLEMENTED); } +/** + * ixgbe_get_san_mac_addr - Get SAN MAC address + * @hw: pointer to hardware structure + * @san_mac_addr: SAN MAC address + * + * Reads the SAN MAC address from the EEPROM, if it's available. This is + * per-port, so set_lan_id() must be called before reading the addresses. + **/ +s32 ixgbe_get_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr) +{ + return ixgbe_call_func(hw, hw->mac.ops.get_san_mac_addr, + (hw, san_mac_addr), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_set_san_mac_addr - Write a SAN MAC address + * @hw: pointer to hardware structure + * @san_mac_addr: SAN MAC address + * + * Writes A SAN MAC address to the EEPROM. + **/ +s32 ixgbe_set_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr) +{ + return ixgbe_call_func(hw, hw->mac.ops.set_san_mac_addr, + (hw, san_mac_addr), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_get_device_caps - Get additional device capabilities + * @hw: pointer to hardware structure + * @device_caps: the EEPROM word for device capabilities + * + * Reads the extra device capabilities from the EEPROM + **/ +s32 ixgbe_get_device_caps(struct ixgbe_hw *hw, u16 *device_caps) +{ + return ixgbe_call_func(hw, hw->mac.ops.get_device_caps, + (hw, device_caps), IXGBE_NOT_IMPLEMENTED); +} + /** * ixgbe_get_bus_info - Set PCI bus info * @hw: pointer to hardware structure @@ -319,6 +369,9 @@ s32 ixgbe_get_phy_firmware_version(struct ixgbe_hw *hw, u16 *firmware_version) s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, u16 *phy_data) { + if (hw->phy.id == 0) + ixgbe_identify_phy(hw); + return ixgbe_call_func(hw, hw->phy.ops.read_reg, (hw, reg_addr, device_type, phy_data), IXGBE_NOT_IMPLEMENTED); } @@ -334,6 +387,9 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, u16 phy_data) { + if (hw->phy.id == 0) + ixgbe_identify_phy(hw); + return ixgbe_call_func(hw, hw->phy.ops.write_reg, (hw, reg_addr, device_type, phy_data), IXGBE_NOT_IMPLEMENTED); } @@ -556,6 +612,22 @@ s32 ixgbe_update_eeprom_checksum(struct ixgbe_hw *hw) IXGBE_NOT_IMPLEMENTED); } +/** + * ixgbe_insert_mac_addr - Find a RAR for this mac address + * @hw: pointer to hardware structure + * @addr: Address to put into receive address register + * @vmdq: VMDq pool to assign + * + * Puts an ethernet address into a receive address register, or + * finds the rar that it is aleady in; adds to the pool list + **/ +s32 ixgbe_insert_mac_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq) +{ + return ixgbe_call_func(hw, hw->mac.ops.insert_mac_addr, + (hw, addr, vmdq), + IXGBE_NOT_IMPLEMENTED); +} + /** * ixgbe_set_rar - Set Rx address register * @hw: pointer to hardware structure @@ -724,15 +796,15 @@ s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on) } /** - * ixgbe_setup_fc - Set flow control + * ixgbe_fc_enable - Enable flow control * @hw: pointer to hardware structure * @packetbuf_num: packet buffer number (0-7) * * Configures the flow control settings based on SW configuration. **/ -s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) +s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packetbuf_num) { - return ixgbe_call_func(hw, hw->mac.ops.setup_fc, (hw, packetbuf_num), + return ixgbe_call_func(hw, hw->mac.ops.fc_enable, (hw, packetbuf_num), IXGBE_NOT_IMPLEMENTED); } @@ -777,6 +849,53 @@ s32 ixgbe_init_uta_tables(struct ixgbe_hw *hw) IXGBE_NOT_IMPLEMENTED); } +/** + * ixgbe_read_i2c_byte - Reads 8 bit word over I2C at specified device address + * @hw: pointer to hardware structure + * @byte_offset: byte offset to read + * @data: value read + * + * Performs byte read operation to SFP module's EEPROM over I2C interface. + **/ +s32 ixgbe_read_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, + u8 *data) +{ + return ixgbe_call_func(hw, hw->phy.ops.read_i2c_byte, (hw, byte_offset, + dev_addr, data), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_write_i2c_byte - Writes 8 bit word over I2C + * @hw: pointer to hardware structure + * @byte_offset: byte offset to write + * @data: value to write + * + * Performs byte write operation to SFP module's EEPROM over I2C interface + * at a specified device address. + **/ +s32 ixgbe_write_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, + u8 data) +{ + return ixgbe_call_func(hw, hw->phy.ops.write_i2c_byte, (hw, byte_offset, + dev_addr, data), IXGBE_NOT_IMPLEMENTED); +} + +/** + * ixgbe_write_i2c_eeprom - Writes 8 bit EEPROM word over I2C interface + * @hw: pointer to hardware structure + * @byte_offset: EEPROM byte offset to write + * @eeprom_data: value to write + * + * Performs byte write operation to SFP module's EEPROM over I2C interface. + **/ +s32 ixgbe_write_i2c_eeprom(struct ixgbe_hw *hw, + u8 byte_offset, u8 eeprom_data) +{ + return ixgbe_call_func(hw, hw->phy.ops.write_i2c_eeprom, + (hw, byte_offset, eeprom_data), + IXGBE_NOT_IMPLEMENTED); +} + /** * ixgbe_read_i2c_eeprom - Reads 8 bit EEPROM word over I2C interface * @hw: pointer to hardware structure @@ -803,3 +922,16 @@ u32 ixgbe_get_supported_physical_layer(struct ixgbe_hw *hw) return ixgbe_call_func(hw, hw->mac.ops.get_supported_physical_layer, (hw), IXGBE_PHYSICAL_LAYER_UNKNOWN); } + +/** + * ixgbe_enable_rx_dma - Enables Rx DMA unit, dependant on device specifics + * @hw: pointer to hardware structure + * @regval: bitfield to write to the Rx DMA register + * + * Enables the Rx DMA unit of the device. + **/ +s32 ixgbe_enable_rx_dma(struct ixgbe_hw *hw, u32 regval) +{ + return ixgbe_call_func(hw, hw->mac.ops.enable_rx_dma, + (hw, regval), IXGBE_NOT_IMPLEMENTED); +} diff --git a/sys/dev/ixgbe/ixgbe_api.h b/sys/dev/ixgbe/ixgbe_api.h index 8022f90a96e..ba987edb0a2 100644 --- a/sys/dev/ixgbe/ixgbe_api.h +++ b/sys/dev/ixgbe/ixgbe_api.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2009, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -85,6 +85,7 @@ s32 ixgbe_read_eeprom(struct ixgbe_hw *hw, u16 offset, u16 *data); s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val); s32 ixgbe_update_eeprom_checksum(struct ixgbe_hw *hw); +s32 ixgbe_insert_mac_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq); s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, u32 enable_addr); s32 ixgbe_clear_rar(struct ixgbe_hw *hw, u32 index); @@ -102,7 +103,7 @@ s32 ixgbe_clear_vfta(struct ixgbe_hw *hw); s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on); -s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num); +s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packetbuf_num); void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr); s32 ixgbe_get_phy_firmware_version(struct ixgbe_hw *hw, @@ -112,5 +113,54 @@ s32 ixgbe_write_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 val); s32 ixgbe_init_uta_tables(struct ixgbe_hw *hw); s32 ixgbe_read_i2c_eeprom(struct ixgbe_hw *hw, u8 byte_offset, u8 *eeprom_data); u32 ixgbe_get_supported_physical_layer(struct ixgbe_hw *hw); +s32 ixgbe_enable_rx_dma(struct ixgbe_hw *hw, u32 regval); +s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw); +s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc); +s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc); +s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, + struct ixgbe_atr_input *input, + u8 queue); +s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, + struct ixgbe_atr_input *input, + u16 soft_id, + u8 queue); +u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *input, u32 key); +s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, u16 vlan_id); +s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, u32 src_addr); +s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 dst_addr); +s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input, u32 src_addr_1, + u32 src_addr_2, u32 src_addr_3, + u32 src_addr_4); +s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input, u32 dst_addr_1, + u32 dst_addr_2, u32 dst_addr_3, + u32 dst_addr_4); +s32 ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input, u16 src_port); +s32 ixgbe_atr_set_dst_port_82599(struct ixgbe_atr_input *input, u16 dst_port); +s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input, u16 flex_byte); +s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input, u8 vm_pool); +s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input, u8 l4type); +s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input, u16 *vlan_id); +s32 ixgbe_atr_get_src_ipv4_82599(struct ixgbe_atr_input *input, u32 *src_addr); +s32 ixgbe_atr_get_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 *dst_addr); +s32 ixgbe_atr_get_src_ipv6_82599(struct ixgbe_atr_input *input, u32 *src_addr_1, + u32 *src_addr_2, u32 *src_addr_3, + u32 *src_addr_4); +s32 ixgbe_atr_get_dst_ipv6_82599(struct ixgbe_atr_input *input, u32 *dst_addr_1, + u32 *dst_addr_2, u32 *dst_addr_3, + u32 *dst_addr_4); +s32 ixgbe_atr_get_src_port_82599(struct ixgbe_atr_input *input, u16 *src_port); +s32 ixgbe_atr_get_dst_port_82599(struct ixgbe_atr_input *input, u16 *dst_port); +s32 ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input, + u16 *flex_byte); +s32 ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input, u8 *vm_pool); +s32 ixgbe_atr_get_l4type_82599(struct ixgbe_atr_input *input, u8 *l4type); +s32 ixgbe_read_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, + u8 *data); +s32 ixgbe_write_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, + u8 data); +s32 ixgbe_write_i2c_eeprom(struct ixgbe_hw *hw, u8 byte_offset, u8 eeprom_data); +s32 ixgbe_get_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr); +s32 ixgbe_set_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr); +s32 ixgbe_get_device_caps(struct ixgbe_hw *hw, u16 *device_caps); #endif /* _IXGBE_API_H_ */ diff --git a/sys/dev/ixgbe/ixgbe_common.c b/sys/dev/ixgbe/ixgbe_common.c index 53e4afff721..030605c481c 100644 --- a/sys/dev/ixgbe/ixgbe_common.c +++ b/sys/dev/ixgbe/ixgbe_common.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2009, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -49,11 +49,7 @@ static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); static void ixgbe_release_eeprom(struct ixgbe_hw *hw); static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw); -static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index); -static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index); static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr); -void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr); -void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq); /** * ixgbe_init_ops_generic - Inits function ptrs @@ -86,6 +82,7 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw) mac->ops.clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic; mac->ops.get_media_type = NULL; mac->ops.get_supported_physical_layer = NULL; + mac->ops.enable_rx_dma = &ixgbe_enable_rx_dma_generic; mac->ops.get_mac_addr = &ixgbe_get_mac_addr_generic; mac->ops.stop_adapter = &ixgbe_stop_adapter_generic; mac->ops.get_bus_info = &ixgbe_get_bus_info_generic; @@ -94,12 +91,13 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw) /* LEDs */ mac->ops.led_on = &ixgbe_led_on_generic; mac->ops.led_off = &ixgbe_led_off_generic; - mac->ops.blink_led_start = NULL; - mac->ops.blink_led_stop = NULL; + mac->ops.blink_led_start = &ixgbe_blink_led_start_generic; + mac->ops.blink_led_stop = &ixgbe_blink_led_stop_generic; /* RAR, Multicast, VLAN */ mac->ops.set_rar = &ixgbe_set_rar_generic; mac->ops.clear_rar = &ixgbe_clear_rar_generic; + mac->ops.insert_mac_addr = NULL; mac->ops.set_vmdq = NULL; mac->ops.clear_vmdq = NULL; mac->ops.init_rx_addrs = &ixgbe_init_rx_addrs_generic; @@ -111,6 +109,8 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw) mac->ops.set_vfta = NULL; mac->ops.init_uta_tables = NULL; + /* Flow Control */ + mac->ops.fc_enable = &ixgbe_fc_enable_generic; /* Link */ mac->ops.get_link_capabilities = NULL; @@ -133,28 +133,16 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw) s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) { u32 ctrl_ext; + s32 ret_val = IXGBE_SUCCESS; /* Set the media type */ hw->phy.media_type = hw->mac.ops.get_media_type(hw); - /* Set bus info */ - hw->mac.ops.get_bus_info(hw); - - /* Identify the PHY */ - hw->phy.ops.identify(hw); - - /* - * Store MAC address from RAR0, clear receive address registers, and - * clear the multicast table - */ - hw->mac.ops.init_rx_addrs(hw); + /* PHY ops initialization must be done in reset_hw() */ /* Clear the VLAN filter table */ hw->mac.ops.clear_vfta(hw); - /* Set up link */ - hw->mac.ops.setup_link(hw); - /* Clear statistics registers */ hw->mac.ops.clear_hw_cntrs(hw); @@ -164,10 +152,13 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); IXGBE_WRITE_FLUSH(hw); + /* Setup flow control */ + ixgbe_setup_fc(hw, 0); + /* Clear adapter stopped flag */ hw->adapter_stopped = FALSE; - return IXGBE_SUCCESS; + return ret_val; } /** @@ -182,13 +173,17 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) **/ s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw) { + s32 status = IXGBE_SUCCESS; + /* Reset the hardware */ - hw->mac.ops.reset_hw(hw); + status = hw->mac.ops.reset_hw(hw); - /* Start the HW */ - hw->mac.ops.start_hw(hw); + if (status == IXGBE_SUCCESS) { + /* Start the HW */ + status = hw->mac.ops.start_hw(hw); + } - return IXGBE_SUCCESS; + return status; } /** @@ -214,15 +209,28 @@ s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw) IXGBE_READ_REG(hw, IXGBE_RLEC); IXGBE_READ_REG(hw, IXGBE_LXONTXC); IXGBE_READ_REG(hw, IXGBE_LXOFFTXC); - IXGBE_READ_REG(hw, IXGBE_LXONRXC); - IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); + if (hw->mac.type >= ixgbe_mac_82599EB) { + IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); + IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); + } else { + IXGBE_READ_REG(hw, IXGBE_LXONRXC); + IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); + } for (i = 0; i < 8; i++) { IXGBE_READ_REG(hw, IXGBE_PXONTXC(i)); IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i)); - IXGBE_READ_REG(hw, IXGBE_PXONRXC(i)); - IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i)); + if (hw->mac.type >= ixgbe_mac_82599EB) { + IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i)); + IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i)); + } else { + IXGBE_READ_REG(hw, IXGBE_PXONRXC(i)); + IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i)); + } } + if (hw->mac.type >= ixgbe_mac_82599EB) + for (i = 0; i < 8; i++) + IXGBE_READ_REG(hw, IXGBE_PXON2OFFCNT(i)); IXGBE_READ_REG(hw, IXGBE_PRC64); IXGBE_READ_REG(hw, IXGBE_PRC127); IXGBE_READ_REG(hw, IXGBE_PRC255); @@ -391,6 +399,7 @@ void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw) reg = IXGBE_READ_REG(hw, IXGBE_STATUS); bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT; + bus->lan_id = bus->func; /* check for a port swap */ reg = IXGBE_READ_REG(hw, IXGBE_FACTPS); @@ -595,7 +604,6 @@ s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data) ixgbe_shift_out_eeprom_bits(hw, data, 16); ixgbe_standby_eeprom(hw); - msec_delay(hw->eeprom.semaphore_delay); /* Done with writing - release the EEPROM */ ixgbe_release_eeprom(hw); } @@ -802,7 +810,7 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw) status = IXGBE_SUCCESS; break; } - msec_delay(1); + usec_delay(50); } /* Now get the semaphore between SW/FW through the SWESMBI bit */ @@ -830,11 +838,14 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw) * was not granted because we don't have access to the EEPROM */ if (i >= timeout) { - DEBUGOUT("Driver can't access the Eeprom - Semaphore " + DEBUGOUT("SWESMBI Software EEPROM semaphore " "not granted.\n"); ixgbe_release_eeprom_semaphore(hw); status = IXGBE_ERR_EEPROM; } + } else { + DEBUGOUT("Software semaphore SMBI between device drivers " + "not granted.\n"); } return status; @@ -1295,38 +1306,6 @@ s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index) return IXGBE_SUCCESS; } -/** - * ixgbe_enable_rar - Enable Rx address register - * @hw: pointer to hardware structure - * @index: index into the RAR table - * - * Enables the select receive address register. - **/ -static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index) -{ - u32 rar_high; - - rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); - rar_high |= IXGBE_RAH_AV; - IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); -} - -/** - * ixgbe_disable_rar - Disable Rx address register - * @hw: pointer to hardware structure - * @index: index into the RAR table - * - * Disables the select receive address register. - **/ -static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index) -{ - u32 rar_high; - - rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); - rar_high &= (~IXGBE_RAH_AV); - IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); -} - /** * ixgbe_init_rx_addrs_generic - Initializes receive address filters. * @hw: pointer to hardware structure @@ -1378,7 +1357,6 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw) } /* Clear the MTA */ - hw->addr_ctrl.mc_addr_in_rar_count = 0; hw->addr_ctrl.mta_in_use = 0; IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); @@ -1411,8 +1389,7 @@ void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq) * else put the controller into promiscuous mode */ if (hw->addr_ctrl.rar_used_count < rar_entries) { - rar = hw->addr_ctrl.rar_used_count - - hw->addr_ctrl.mc_addr_in_rar_count; + rar = hw->addr_ctrl.rar_used_count; hw->mac.ops.set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); DEBUGOUT1("Added a secondary address to RAR[%d]\n", rar); hw->addr_ctrl.rar_used_count++; @@ -1451,14 +1428,13 @@ s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list, * Clear accounting of old secondary address list, * don't count RAR[0] */ - uc_addr_in_use = hw->addr_ctrl.rar_used_count - - hw->addr_ctrl.mc_addr_in_rar_count - 1; + uc_addr_in_use = hw->addr_ctrl.rar_used_count - 1; hw->addr_ctrl.rar_used_count -= uc_addr_in_use; hw->addr_ctrl.overflow_promisc = 0; /* Zero out the other receive addresses */ - DEBUGOUT1("Clearing RAR[1-%d]\n", uc_addr_in_use); - for (i = 1; i <= uc_addr_in_use; i++) { + DEBUGOUT1("Clearing RAR[1-%d]\n", hw->addr_ctrl.rar_used_count); + for (i = 1; i <= hw->addr_ctrl.rar_used_count; i++) { IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0); IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0); } @@ -1567,40 +1543,6 @@ void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr) IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg); } -/** - * ixgbe_add_mc_addr - Adds a multicast address. - * @hw: pointer to hardware structure - * @mc_addr: new multicast address - * - * Adds it to unused receive address register or to the multicast table. - **/ -void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr) -{ - u32 rar_entries = hw->mac.num_rar_entries; - u32 rar; - - DEBUGOUT6(" MC Addr =%.2X %.2X %.2X %.2X %.2X %.2X\n", - mc_addr[0], mc_addr[1], mc_addr[2], - mc_addr[3], mc_addr[4], mc_addr[5]); - - /* - * Place this multicast address in the RAR if there is room, - * else put it in the MTA - */ - if (hw->addr_ctrl.rar_used_count < rar_entries) { - /* use RAR from the end up for multicast */ - rar = rar_entries - hw->addr_ctrl.mc_addr_in_rar_count - 1; - hw->mac.ops.set_rar(hw, rar, mc_addr, 0, IXGBE_RAH_AV); - DEBUGOUT1("Added a multicast address to RAR[%d]\n", rar); - hw->addr_ctrl.rar_used_count++; - hw->addr_ctrl.mc_addr_in_rar_count++; - } else { - ixgbe_set_mta(hw, mc_addr); - } - - DEBUGOUT("ixgbe_add_mc_addr Complete\n"); -} - /** * ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses * @hw: pointer to hardware structure @@ -1617,7 +1559,6 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, u32 mc_addr_count, ixgbe_mc_addr_itr next) { u32 i; - u32 rar_entries = hw->mac.num_rar_entries; u32 vmdq; /* @@ -1625,18 +1566,8 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, * use. */ hw->addr_ctrl.num_mc_addrs = mc_addr_count; - hw->addr_ctrl.rar_used_count -= hw->addr_ctrl.mc_addr_in_rar_count; - hw->addr_ctrl.mc_addr_in_rar_count = 0; hw->addr_ctrl.mta_in_use = 0; - /* Zero out the other receive addresses. */ - DEBUGOUT2("Clearing RAR[%d-%d]\n", hw->addr_ctrl.rar_used_count, - rar_entries - 1); - for (i = hw->addr_ctrl.rar_used_count; i < rar_entries; i++) { - IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0); - IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0); - } - /* Clear the MTA */ DEBUGOUT(" Clearing MTA\n"); for (i = 0; i < hw->mac.mcft_size; i++) @@ -1645,7 +1576,7 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, /* Add the new addresses */ for (i = 0; i < mc_addr_count; i++) { DEBUGOUT(" Adding the multicast addresses:\n"); - ixgbe_add_mc_addr(hw, next(hw, &mc_addr_list, &vmdq)); + ixgbe_set_mta(hw, next(hw, &mc_addr_list, &vmdq)); } /* Enable mta */ @@ -1665,15 +1596,8 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, **/ s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw) { - u32 i; - u32 rar_entries = hw->mac.num_rar_entries; struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; - if (a->mc_addr_in_rar_count > 0) - for (i = (rar_entries - a->mc_addr_in_rar_count); - i < rar_entries; i++) - ixgbe_enable_rar(hw, i); - if (a->mta_in_use > 0) IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type); @@ -1689,52 +1613,56 @@ s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw) **/ s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw) { - u32 i; - u32 rar_entries = hw->mac.num_rar_entries; struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; - if (a->mc_addr_in_rar_count > 0) - for (i = (rar_entries - a->mc_addr_in_rar_count); - i < rar_entries; i++) - ixgbe_disable_rar(hw, i); - if (a->mta_in_use > 0) IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); return IXGBE_SUCCESS; } - /** - * ixgbe_fc_autoneg - Configure flow control + * ixgbe_fc_enable_generic - Enable flow control * @hw: pointer to hardware structure + * @packetbuf_num: packet buffer number (0-7) * - * Negotiates flow control capabilities with link partner using autoneg and - * applies the results. + * Enable flow control according to the current settings. **/ -s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw) +s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num) { s32 ret_val = IXGBE_SUCCESS; - u32 i, reg, pcs_anadv_reg, pcs_lpab_reg; + u32 mflcn_reg, fccfg_reg; + u32 reg; - DEBUGFUNC("ixgbe_fc_autoneg"); + DEBUGFUNC("ixgbe_fc_enable_generic"); - reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); + /* Negotiate the fc mode to use */ + ret_val = ixgbe_fc_autoneg(hw); + if (ret_val) + goto out; + + /* Disable any previous flow control settings */ + mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); + mflcn_reg &= ~(IXGBE_MFLCN_RFCE | IXGBE_MFLCN_RPFCE); + + fccfg_reg = IXGBE_READ_REG(hw, IXGBE_FCCFG); + fccfg_reg &= ~(IXGBE_FCCFG_TFCE_802_3X | IXGBE_FCCFG_TFCE_PRIORITY); /* * The possible values of fc.current_mode are: - * 0: Flow control is completely disabled - * 1: Rx flow control is enabled (we can receive pause frames, - * but not send pause frames). - * 2: Tx flow control is enabled (we can send pause frames but - * we do not support receiving pause frames). - * 3: Both Rx and Tx flow control (symmetric) are enabled. + * 0: Flow control is completely disabled + * 1: Rx flow control is enabled (we can receive pause frames, + * but not send pause frames). + * 2: Tx flow control is enabled (we can send pause frames but + * we do not support receiving pause frames). + * 3: Both Rx and Tx flow control (symmetric) are enabled. * other: Invalid. */ switch (hw->fc.current_mode) { case ixgbe_fc_none: - /* Flow control completely disabled by software override. */ - reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); + /* Flow control is disabled by software override or autoneg. + * The code below will actually disable it in the HW. + */ break; case ixgbe_fc_rx_pause: /* @@ -1745,19 +1673,19 @@ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw) * symmetric and asymmetric Rx PAUSE. Later, we will * disable the adapter's ability to send PAUSE frames. */ - reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); + mflcn_reg |= IXGBE_MFLCN_RFCE; break; case ixgbe_fc_tx_pause: /* * Tx Flow control is enabled, and Rx Flow control is * disabled by software override. */ - reg |= (IXGBE_PCS1GANA_ASM_PAUSE); - reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE); + fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X; break; case ixgbe_fc_full: /* Flow control (both Rx and Tx) is enabled by SW override. */ - reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); + mflcn_reg |= IXGBE_MFLCN_RFCE; + fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X; break; default: DEBUGOUT("Flow control param set incorrectly\n"); @@ -1766,39 +1694,80 @@ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw) break; } - IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg); - reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL); + /* Set 802.3x based flow control settings. */ + mflcn_reg |= IXGBE_MFLCN_DPF; + IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg); + IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg); - /* Set PCS register for autoneg */ - /* Enable and restart autoneg */ - reg |= IXGBE_PCS1GLCTL_AN_ENABLE | IXGBE_PCS1GLCTL_AN_RESTART; - - /* Disable AN timeout */ - if (hw->fc.strict_ieee) - reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN; - - DEBUGOUT1("Configuring Autoneg; PCS_LCTL = 0x%08X\n", reg); - IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg); - - /* See if autonegotiation has succeeded */ - hw->mac.autoneg_succeeded = 0; - for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) { - msec_delay(10); - reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); - if ((reg & (IXGBE_PCS1GLSTA_LINK_OK | - IXGBE_PCS1GLSTA_AN_COMPLETE)) == - (IXGBE_PCS1GLSTA_LINK_OK | - IXGBE_PCS1GLSTA_AN_COMPLETE)) { - if (!(reg & IXGBE_PCS1GLSTA_AN_TIMED_OUT)) - hw->mac.autoneg_succeeded = 1; - break; + /* Set up and enable Rx high/low water mark thresholds, enable XON. */ + if (hw->fc.current_mode & ixgbe_fc_tx_pause) { + if (hw->fc.send_xon) { + IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), + (hw->fc.low_water | IXGBE_FCRTL_XONE)); + } else { + IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), + hw->fc.low_water); } + + IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), + (hw->fc.high_water | IXGBE_FCRTH_FCEN)); } - if (!hw->mac.autoneg_succeeded) { - /* Autoneg failed to achieve a link, so we turn fc off */ - hw->fc.current_mode = ixgbe_fc_none; - DEBUGOUT("Flow Control = NONE.\n"); + /* Configure pause time (2 TCs per register) */ + reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num)); + if ((packetbuf_num & 1) == 0) + reg = (reg & 0xFFFF0000) | hw->fc.pause_time; + else + reg = (reg & 0x0000FFFF) | (hw->fc.pause_time << 16); + IXGBE_WRITE_REG(hw, IXGBE_FCTTV(packetbuf_num / 2), reg); + + IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1)); + +out: + return ret_val; +} + +/** + * ixgbe_fc_autoneg - Configure flow control + * @hw: pointer to hardware structure + * + * Compares our advertised flow control capabilities to those advertised by + * our link partner, and determines the proper flow control mode to use. + **/ +s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw) +{ + s32 ret_val = IXGBE_SUCCESS; + ixgbe_link_speed speed; + u32 pcs_anadv_reg, pcs_lpab_reg, linkstat; + bool link_up; + + DEBUGFUNC("ixgbe_fc_autoneg"); + + /* + * AN should have completed when the cable was plugged in. + * Look for reasons to bail out. Bail out if: + * - FC autoneg is disabled, or if + * - we don't have multispeed fiber, or if + * - we're not running at 1G, or if + * - link is not up, or if + * - link is up but AN did not complete, or if + * - link is up and AN completed but timed out + * + * Since we're being called from an LSC, link is already know to be up. + * So use link_up_wait_to_complete=FALSE. + */ + hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); + linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); + + if (hw->fc.disable_fc_autoneg || + !hw->phy.multispeed_fiber || + (speed != IXGBE_LINK_SPEED_1GB_FULL) || + !link_up || + ((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) || + ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) { + hw->fc.fc_was_autonegged = FALSE; + hw->fc.current_mode = hw->fc.requested_mode; + DEBUGOUT("Autoneg FC was skipped.\n"); goto out; } @@ -1841,10 +1810,128 @@ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw) DEBUGOUT("Flow Control = NONE.\n"); } + /* Record that current_mode is the result of a successful autoneg */ + hw->fc.fc_was_autonegged = TRUE; + out: return ret_val; } +/** + * ixgbe_setup_fc - Set up flow control + * @hw: pointer to hardware structure + * + * Called at init time to set up flow control. + **/ +s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) +{ + s32 ret_val = IXGBE_SUCCESS; + u32 reg; + + + /* Validate the packetbuf configuration */ + if (packetbuf_num < 0 || packetbuf_num > 7) { + DEBUGOUT1("Invalid packet buffer number [%d], expected range is" + " 0-7\n", packetbuf_num); + ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; + goto out; + } + + /* + * Validate the water mark configuration. Zero water marks are invalid + * because it causes the controller to just blast out fc packets. + */ + if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) { + DEBUGOUT("Invalid water mark configuration\n"); + ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; + goto out; + } + + /* + * Validate the requested mode. Strict IEEE mode does not allow + * ixgbe_fc_rx_pause because it will cause us to fail at UNH. + */ + if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { + DEBUGOUT("ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); + ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; + goto out; + } + + /* + * 10gig parts do not have a word in the EEPROM to determine the + * default flow control setting, so we explicitly set it to full. + */ + if (hw->fc.requested_mode == ixgbe_fc_default) + hw->fc.requested_mode = ixgbe_fc_full; + + /* + * Set up the 1G flow control advertisement registers so the HW will be + * able to do fc autoneg once the cable is plugged in. If we end up + * using 10g instead, this is harmless. + */ + reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); + + /* + * The possible values of fc.requested_mode are: + * 0: Flow control is completely disabled + * 1: Rx flow control is enabled (we can receive pause frames, + * but not send pause frames). + * 2: Tx flow control is enabled (we can send pause frames but + * we do not support receiving pause frames). + * 3: Both Rx and Tx flow control (symmetric) are enabled. + * other: Invalid. + */ + switch (hw->fc.requested_mode) { + case ixgbe_fc_none: + /* Flow control completely disabled by software override. */ + reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); + break; + case ixgbe_fc_rx_pause: + /* + * Rx Flow control is enabled and Tx Flow control is + * disabled by software override. Since there really + * isn't a way to advertise that we are capable of RX + * Pause ONLY, we will advertise that we support both + * symmetric and asymmetric Rx PAUSE. Later, we will + * disable the adapter's ability to send PAUSE frames. + */ + reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); + break; + case ixgbe_fc_tx_pause: + /* + * Tx Flow control is enabled, and Rx Flow control is + * disabled by software override. + */ + reg |= (IXGBE_PCS1GANA_ASM_PAUSE); + reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE); + break; + case ixgbe_fc_full: + /* Flow control (both Rx and Tx) is enabled by SW override. */ + reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); + break; + default: + DEBUGOUT("Flow control param set incorrectly\n"); + ret_val = -IXGBE_ERR_CONFIG; + goto out; + break; + } + + IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg); + reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL); + + /* Enable and restart autoneg to inform the link partner */ + reg |= IXGBE_PCS1GLCTL_AN_ENABLE | IXGBE_PCS1GLCTL_AN_RESTART; + + /* Disable AN timeout */ + if (hw->fc.strict_ieee) + reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN; + + IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg); + DEBUGOUT1("Set up FC; PCS1GLCTL = 0x%08X\n", reg); + +out: + return ret_val; +} /** * ixgbe_disable_pcie_master - Disable PCI-express master access @@ -1904,6 +1991,10 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) s32 timeout = 200; while (timeout) { + /* + * SW EEPROM semaphore bit is used for access to all + * SW_FW_SYNC/GSSR bits (not just EEPROM) + */ if (ixgbe_get_eeprom_semaphore(hw)) return -IXGBE_ERR_SWFW_SYNC; @@ -1921,7 +2012,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) } if (!timeout) { - DEBUGOUT("Driver can't access resource, GSSR timeout.\n"); + DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n"); return -IXGBE_ERR_SWFW_SYNC; } @@ -1952,5 +2043,77 @@ void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask) IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr); ixgbe_release_eeprom_semaphore(hw); + + /* Delay before attempt to obtain semaphore again to allow FW access */ + msec_delay(hw->eeprom.semaphore_delay); +} + +/** + * ixgbe_enable_rx_dma_generic - Enable the Rx DMA unit + * @hw: pointer to hardware structure + * @regval: register value to write to RXCTRL + * + * Enables the Rx DMA unit + **/ +s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval) +{ + IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_blink_led_start_generic - Blink LED based on index. + * @hw: pointer to hardware structure + * @index: led number to blink + **/ +s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) +{ + ixgbe_link_speed speed = 0; + bool link_up = 0; + u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); + u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + + /* + * Link must be up to auto-blink the LEDs; + * Force it if link is down. + */ + hw->mac.ops.check_link(hw, &speed, &link_up, FALSE); + + if (!link_up) { + autoc_reg |= IXGBE_AUTOC_FLU; + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); + msec_delay(10); + } + + led_reg &= ~IXGBE_LED_MODE_MASK(index); + led_reg |= IXGBE_LED_BLINK(index); + IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); + IXGBE_WRITE_FLUSH(hw); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_blink_led_stop_generic - Stop blinking LED based on index. + * @hw: pointer to hardware structure + * @index: led number to stop blinking + **/ +s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index) +{ + u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); + u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + + autoc_reg &= ~IXGBE_AUTOC_FLU; + autoc_reg |= IXGBE_AUTOC_AN_RESTART; + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); + + led_reg &= ~IXGBE_LED_MODE_MASK(index); + led_reg &= ~IXGBE_LED_BLINK(index); + led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); + IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); + IXGBE_WRITE_FLUSH(hw); + + return IXGBE_SUCCESS; } diff --git a/sys/dev/ixgbe/ixgbe_common.h b/sys/dev/ixgbe/ixgbe_common.h index d94f67426c3..0c535751880 100644 --- a/sys/dev/ixgbe/ixgbe_common.h +++ b/sys/dev/ixgbe/ixgbe_common.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2009, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -36,6 +36,11 @@ #define _IXGBE_COMMON_H_ #include "ixgbe_type.h" +#define IXGBE_WRITE_REG64(hw, reg, value) \ + do { \ + IXGBE_WRITE_REG(hw, reg, (u32) value); \ + IXGBE_WRITE_REG(hw, reg + 4, (u32) (value >> 32)); \ + } while (0) s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw); s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw); @@ -68,11 +73,13 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, ixgbe_mc_addr_itr func); s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list, u32 addr_count, ixgbe_mc_addr_itr func); +void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq); s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw); s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw); +s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval); -s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num); -s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packtetbuf_num); +s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num); +s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packtetbuf_num); s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw); s32 ixgbe_validate_mac_addr(u8 *mac_addr); @@ -82,4 +89,7 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw); s32 ixgbe_read_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 *val); s32 ixgbe_write_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 val); +s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index); +s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index); + #endif /* IXGBE_COMMON */ diff --git a/sys/dev/ixgbe/ixgbe_osdep.h b/sys/dev/ixgbe/ixgbe_osdep.h index be6f5773d8b..53b64f531ca 100644 --- a/sys/dev/ixgbe/ixgbe_osdep.h +++ b/sys/dev/ixgbe/ixgbe_osdep.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2009, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -96,6 +96,7 @@ typedef boolean_t bool; #define le16_to_cpu +#if __FreeBSD_version < 800000 #if defined(__i386__) || defined(__amd64__) #define mb() __asm volatile("mfence" ::: "memory") #define wmb() __asm volatile("sfence" ::: "memory") @@ -105,6 +106,7 @@ typedef boolean_t bool; #define rmb() #define wmb() #endif +#endif struct ixgbe_osdep { @@ -113,11 +115,14 @@ struct ixgbe_osdep struct device *dev; }; -/* This is needed by the shared code */ +/* These routines are needed by the shared code */ struct ixgbe_hw; extern u16 ixgbe_read_pci_cfg(struct ixgbe_hw *, u32); #define IXGBE_READ_PCIE_WORD ixgbe_read_pci_cfg +extern void ixgbe_write_pci_cfg(struct ixgbe_hw *, u32, u16); +#define IXGBE_WRITE_PCIE_WORD ixgbe_write_pci_cfg + #define IXGBE_WRITE_FLUSH(a) IXGBE_READ_REG(a, IXGBE_STATUS) #define IXGBE_READ_REG(a, reg) (\ diff --git a/sys/dev/ixgbe/ixgbe_phy.c b/sys/dev/ixgbe/ixgbe_phy.c index 291d454cc50..afd30eee806 100644 --- a/sys/dev/ixgbe/ixgbe_phy.c +++ b/sys/dev/ixgbe/ixgbe_phy.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2009, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -36,6 +36,19 @@ #include "ixgbe_common.h" #include "ixgbe_phy.h" +static void ixgbe_i2c_start(struct ixgbe_hw *hw); +static void ixgbe_i2c_stop(struct ixgbe_hw *hw); +static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data); +static s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data); +static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw); +static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data); +static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data); +static s32 ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl); +static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl); +static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data); +static bool ixgbe_get_i2c_data(u32 *i2cctl); +void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw); + /** * ixgbe_init_phy_ops_generic - Inits PHY function ptrs * @hw: pointer to the hardware structure @@ -55,6 +68,11 @@ s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw) phy->ops.setup_link_speed = &ixgbe_setup_phy_link_speed_generic; phy->ops.check_link = NULL; phy->ops.get_firmware_version = NULL; + phy->ops.read_i2c_byte = &ixgbe_read_i2c_byte_generic; + phy->ops.write_i2c_byte = &ixgbe_write_i2c_byte_generic; + phy->ops.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic; + phy->ops.write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic; + phy->ops.i2c_bus_clear = &ixgbe_i2c_bus_clear; phy->ops.identify_sfp = &ixgbe_identify_sfp_module_generic; phy->sfp_type = ixgbe_sfp_type_unknown; @@ -71,6 +89,7 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) { s32 status = IXGBE_ERR_PHY_ADDR_INVALID; u32 phy_addr; + u16 ext_ability = 0; if (hw->phy.type == ixgbe_phy_unknown) { for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { @@ -79,10 +98,29 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) ixgbe_get_phy_id(hw); hw->phy.type = ixgbe_get_phy_type_from_id(hw->phy.id); + + if (hw->phy.type == ixgbe_phy_unknown) { + hw->phy.ops.read_reg(hw, + IXGBE_MDIO_PHY_EXT_ABILITY, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, + &ext_ability); + if (ext_ability & + IXGBE_MDIO_PHY_10GBASET_ABILITY || + ext_ability & + IXGBE_MDIO_PHY_1000BASET_ABILITY) + hw->phy.type = + ixgbe_phy_cu_unknown; + else + hw->phy.type = + ixgbe_phy_generic; + } + status = IXGBE_SUCCESS; break; } } + if (status != IXGBE_SUCCESS) + hw->phy.addr = 0; } else { status = IXGBE_SUCCESS; } @@ -149,6 +187,9 @@ enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id) case TN1010_PHY_ID: phy_type = ixgbe_phy_tn; break; + case AQ1002_PHY_ID: + phy_type = ixgbe_phy_aq; + break; case QT2022_PHY_ID: phy_type = ixgbe_phy_qt; break; @@ -170,13 +211,40 @@ enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id) **/ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw) { + u32 i; + u16 ctrl = 0; + s32 status = IXGBE_SUCCESS; + + if (hw->phy.type == ixgbe_phy_unknown) + status = ixgbe_identify_phy_generic(hw); + + if (status != IXGBE_SUCCESS || hw->phy.type == ixgbe_phy_none) + goto out; + /* * Perform soft PHY reset to the PHY_XS. * This will cause a soft reset to the PHY */ - return hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, - IXGBE_MDIO_PHY_XS_DEV_TYPE, - IXGBE_MDIO_PHY_XS_RESET); + hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, + IXGBE_MDIO_PHY_XS_DEV_TYPE, + IXGBE_MDIO_PHY_XS_RESET); + + /* Poll for reset bit to self-clear indicating reset is complete */ + for (i = 0; i < 500; i++) { + msec_delay(1); + hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, + IXGBE_MDIO_PHY_XS_DEV_TYPE, &ctrl); + if (!(ctrl & IXGBE_MDIO_PHY_XS_RESET)) + break; + } + + if (ctrl & IXGBE_MDIO_PHY_XS_RESET) { + status = IXGBE_ERR_RESET_FAILED; + DEBUGOUT("PHY reset polling failed to complete.\n"); + } + +out: + return status; } /** @@ -454,12 +522,49 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, if (speed & IXGBE_LINK_SPEED_1GB_FULL) hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL; + if (speed & IXGBE_LINK_SPEED_100_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL; + /* Setup link based on the new speed settings */ hw->phy.ops.setup_link(hw); return IXGBE_SUCCESS; } +/** + * ixgbe_get_copper_link_capabilities_generic - Determines link capabilities + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @autoneg: boolean auto-negotiation value + * + * Determines the link capabilities by reading the AUTOC register. + **/ +s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg) +{ + s32 status = IXGBE_ERR_LINK_SETUP; + u16 speed_ability; + + *speed = 0; + *autoneg = TRUE; + + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, + &speed_ability); + + if (status == IXGBE_SUCCESS) { + if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G) + *speed |= IXGBE_LINK_SPEED_10GB_FULL; + if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G) + *speed |= IXGBE_LINK_SPEED_1GB_FULL; + if (speed_ability & IXGBE_MDIO_PHY_SPEED_100M) + *speed |= IXGBE_LINK_SPEED_100_FULL; + } + + return status; +} + /** * ixgbe_check_phy_link_tnx - Determine link and speed status * @hw: pointer to hardware structure @@ -525,6 +630,24 @@ s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, return status; } + +/** + * ixgbe_get_phy_firmware_version_aq - Gets the PHY Firmware Version + * @hw: pointer to hardware structure + * @firmware_version: pointer to the PHY Firmware Version + **/ +s32 ixgbe_get_phy_firmware_version_aq(struct ixgbe_hw *hw, + u16 *firmware_version) +{ + s32 status = IXGBE_SUCCESS; + + status = hw->phy.ops.read_reg(hw, AQ_FW_REV, + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, + firmware_version); + + return status; +} + /** * ixgbe_reset_phy_nl - Performs a PHY reset * @hw: pointer to hardware structure @@ -632,20 +755,30 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) { s32 status = IXGBE_ERR_PHY_ADDR_INVALID; u32 vendor_oui = 0; + enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type; u8 identifier = 0; u8 comp_codes_1g = 0; u8 comp_codes_10g = 0; - u8 oui_bytes[4] = {0, 0, 0, 0}; + u8 oui_bytes[3] = {0, 0, 0}; u8 transmission_media = 0; + u16 enforce_sfp = 0; status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_IDENTIFIER, &identifier); - if (status == IXGBE_ERR_SFP_NOT_PRESENT) { + if (status == IXGBE_ERR_SFP_NOT_PRESENT || status == IXGBE_ERR_I2C) { + status = IXGBE_ERR_SFP_NOT_PRESENT; hw->phy.sfp_type = ixgbe_sfp_type_not_present; + if (hw->phy.type != ixgbe_phy_nl) { + hw->phy.id = 0; + hw->phy.type = ixgbe_phy_unknown; + } goto out; } + /* LAN ID is needed for sfp_type determination */ + hw->mac.ops.set_lan_id(hw); + if (identifier == IXGBE_SFF_IDENTIFIER_SFP) { hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_1GBE_COMP_CODES, &comp_codes_1g); @@ -659,22 +792,57 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) * 0 SFP_DA_CU * 1 SFP_SR * 2 SFP_LR + * 3 SFP_DA_CORE0 - 82599-specific + * 4 SFP_DA_CORE1 - 82599-specific + * 5 SFP_SR/LR_CORE0 - 82599-specific + * 6 SFP_SR/LR_CORE1 - 82599-specific */ - if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE) - hw->phy.sfp_type = ixgbe_sfp_type_da_cu; - else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE) - hw->phy.sfp_type = ixgbe_sfp_type_sr; - else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE) - hw->phy.sfp_type = ixgbe_sfp_type_lr; - else - hw->phy.sfp_type = ixgbe_sfp_type_unknown; + if (hw->mac.type == ixgbe_mac_82598EB) { + if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE) + hw->phy.sfp_type = ixgbe_sfp_type_da_cu; + else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE) + hw->phy.sfp_type = ixgbe_sfp_type_sr; + else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE) + hw->phy.sfp_type = ixgbe_sfp_type_lr; + else + hw->phy.sfp_type = ixgbe_sfp_type_unknown; + } else if (hw->mac.type == ixgbe_mac_82599EB) { + if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE) + if (hw->bus.lan_id == 0) + hw->phy.sfp_type = + ixgbe_sfp_type_da_cu_core0; + else + hw->phy.sfp_type = + ixgbe_sfp_type_da_cu_core1; + else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE) + if (hw->bus.lan_id == 0) + hw->phy.sfp_type = + ixgbe_sfp_type_srlr_core0; + else + hw->phy.sfp_type = + ixgbe_sfp_type_srlr_core1; + else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE) + if (hw->bus.lan_id == 0) + hw->phy.sfp_type = + ixgbe_sfp_type_srlr_core0; + else + hw->phy.sfp_type = + ixgbe_sfp_type_srlr_core1; + else + hw->phy.sfp_type = ixgbe_sfp_type_unknown; + } + + if (hw->phy.sfp_type != stored_sfp_type) + hw->phy.sfp_setup_needed = TRUE; /* Determine if the SFP+ PHY is dual speed or not. */ - if ((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) && - (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) + if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) && + (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) || + ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) && + (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE))) hw->phy.multispeed_fiber = TRUE; /* Determine PHY vendor */ - if (hw->phy.type == ixgbe_phy_unknown) { + if (hw->phy.type != ixgbe_phy_nl) { hw->phy.id = identifier; hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_VENDOR_OUI_BYTE0, @@ -703,6 +871,9 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) case IXGBE_SFF_VENDOR_OUI_AVAGO: hw->phy.type = ixgbe_phy_sfp_avago; break; + case IXGBE_SFF_VENDOR_OUI_INTEL: + hw->phy.type = ixgbe_phy_sfp_intel; + break; default: if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE) @@ -712,7 +883,34 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) break; } } - status = IXGBE_SUCCESS; + + if (comp_codes_10g == 0) { + hw->phy.type = ixgbe_phy_sfp_unsupported; + status = IXGBE_ERR_SFP_NOT_SUPPORTED; + goto out; + } + if (hw->mac.type == ixgbe_mac_82598EB || + (hw->phy.sfp_type != ixgbe_sfp_type_sr && + hw->phy.sfp_type != ixgbe_sfp_type_lr && + hw->phy.sfp_type != ixgbe_sfp_type_srlr_core0 && + hw->phy.sfp_type != ixgbe_sfp_type_srlr_core1)) { + status = IXGBE_SUCCESS; + goto out; + } + + ixgbe_get_device_caps(hw, &enforce_sfp); + if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)) { + /* Make sure we're a supported PHY type */ + if (hw->phy.type == ixgbe_phy_sfp_intel) { + status = IXGBE_SUCCESS; + } else { + DEBUGOUT("SFP+ module not supported\n"); + hw->phy.type = ixgbe_phy_sfp_unsupported; + status = IXGBE_ERR_SFP_NOT_SUPPORTED; + } + } else { + status = IXGBE_SUCCESS; + } } out: @@ -748,7 +946,7 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset); if ((!*list_offset) || (*list_offset == 0xFFFF)) - return IXGBE_ERR_PHY; + return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT; /* Shift offset to first ID word */ (*list_offset)++; @@ -784,3 +982,549 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, return IXGBE_SUCCESS; } +/** + * ixgbe_read_i2c_eeprom_generic - Reads 8 bit EEPROM word over I2C interface + * @hw: pointer to hardware structure + * @byte_offset: EEPROM byte offset to read + * @eeprom_data: value read + * + * Performs byte read operation to SFP module's EEPROM over I2C interface. + **/ +s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 *eeprom_data) +{ + DEBUGFUNC("ixgbe_read_i2c_eeprom_generic"); + + return hw->phy.ops.read_i2c_byte(hw, byte_offset, + IXGBE_I2C_EEPROM_DEV_ADDR, + eeprom_data); +} + +/** + * ixgbe_write_i2c_eeprom_generic - Writes 8 bit EEPROM word over I2C interface + * @hw: pointer to hardware structure + * @byte_offset: EEPROM byte offset to write + * @eeprom_data: value to write + * + * Performs byte write operation to SFP module's EEPROM over I2C interface. + **/ +s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 eeprom_data) +{ + DEBUGFUNC("ixgbe_write_i2c_eeprom_generic"); + + return hw->phy.ops.write_i2c_byte(hw, byte_offset, + IXGBE_I2C_EEPROM_DEV_ADDR, + eeprom_data); +} + +/** + * ixgbe_read_i2c_byte_generic - Reads 8 bit word over I2C + * @hw: pointer to hardware structure + * @byte_offset: byte offset to read + * @data: value read + * + * Performs byte read operation to SFP module's EEPROM over I2C interface at + * a specified deivce address. + **/ +s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 *data) +{ + s32 status = IXGBE_SUCCESS; + u32 max_retry = 1; + u32 retry = 0; + u16 swfw_mask = 0; + bool nack = 1; + + DEBUGFUNC("ixgbe_read_i2c_byte_generic"); + + if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1) + swfw_mask = IXGBE_GSSR_PHY1_SM; + else + swfw_mask = IXGBE_GSSR_PHY0_SM; + + if (ixgbe_acquire_swfw_sync(hw, swfw_mask) != IXGBE_SUCCESS) { + status = IXGBE_ERR_SWFW_SYNC; + goto read_byte_out; + } + + do { + ixgbe_i2c_start(hw); + + /* Device Address and write indication */ + status = ixgbe_clock_out_i2c_byte(hw, dev_addr); + if (status != IXGBE_SUCCESS) + goto fail; + + status = ixgbe_get_i2c_ack(hw); + if (status != IXGBE_SUCCESS) + goto fail; + + status = ixgbe_clock_out_i2c_byte(hw, byte_offset); + if (status != IXGBE_SUCCESS) + goto fail; + + status = ixgbe_get_i2c_ack(hw); + if (status != IXGBE_SUCCESS) + goto fail; + + ixgbe_i2c_start(hw); + + /* Device Address and read indication */ + status = ixgbe_clock_out_i2c_byte(hw, (dev_addr | 0x1)); + if (status != IXGBE_SUCCESS) + goto fail; + + status = ixgbe_get_i2c_ack(hw); + if (status != IXGBE_SUCCESS) + goto fail; + + status = ixgbe_clock_in_i2c_byte(hw, data); + if (status != IXGBE_SUCCESS) + goto fail; + + status = ixgbe_clock_out_i2c_bit(hw, nack); + if (status != IXGBE_SUCCESS) + goto fail; + + ixgbe_i2c_stop(hw); + break; + +fail: + ixgbe_i2c_bus_clear(hw); + retry++; + if (retry < max_retry) + DEBUGOUT("I2C byte read error - Retrying.\n"); + else + DEBUGOUT("I2C byte read error.\n"); + + } while (retry < max_retry); + + ixgbe_release_swfw_sync(hw, swfw_mask); + +read_byte_out: + return status; +} + +/** + * ixgbe_write_i2c_byte_generic - Writes 8 bit word over I2C + * @hw: pointer to hardware structure + * @byte_offset: byte offset to write + * @data: value to write + * + * Performs byte write operation to SFP module's EEPROM over I2C interface at + * a specified device address. + **/ +s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 data) +{ + s32 status = IXGBE_SUCCESS; + u32 max_retry = 1; + u32 retry = 0; + u16 swfw_mask = 0; + + DEBUGFUNC("ixgbe_write_i2c_byte_generic"); + + if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1) + swfw_mask = IXGBE_GSSR_PHY1_SM; + else + swfw_mask = IXGBE_GSSR_PHY0_SM; + + if (ixgbe_acquire_swfw_sync(hw, swfw_mask) != IXGBE_SUCCESS) { + status = IXGBE_ERR_SWFW_SYNC; + goto write_byte_out; + } + + do { + ixgbe_i2c_start(hw); + + status = ixgbe_clock_out_i2c_byte(hw, dev_addr); + if (status != IXGBE_SUCCESS) + goto fail; + + status = ixgbe_get_i2c_ack(hw); + if (status != IXGBE_SUCCESS) + goto fail; + + status = ixgbe_clock_out_i2c_byte(hw, byte_offset); + if (status != IXGBE_SUCCESS) + goto fail; + + status = ixgbe_get_i2c_ack(hw); + if (status != IXGBE_SUCCESS) + goto fail; + + status = ixgbe_clock_out_i2c_byte(hw, data); + if (status != IXGBE_SUCCESS) + goto fail; + + status = ixgbe_get_i2c_ack(hw); + if (status != IXGBE_SUCCESS) + goto fail; + + ixgbe_i2c_stop(hw); + break; + +fail: + ixgbe_i2c_bus_clear(hw); + retry++; + if (retry < max_retry) + DEBUGOUT("I2C byte write error - Retrying.\n"); + else + DEBUGOUT("I2C byte write error.\n"); + } while (retry < max_retry); + + ixgbe_release_swfw_sync(hw, swfw_mask); + +write_byte_out: + return status; +} + +/** + * ixgbe_i2c_start - Sets I2C start condition + * @hw: pointer to hardware structure + * + * Sets I2C start condition (High -> Low on SDA while SCL is High) + **/ +static void ixgbe_i2c_start(struct ixgbe_hw *hw) +{ + u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); + + DEBUGFUNC("ixgbe_i2c_start"); + + /* Start condition must begin with data and clock high */ + ixgbe_set_i2c_data(hw, &i2cctl, 1); + ixgbe_raise_i2c_clk(hw, &i2cctl); + + /* Setup time for start condition (4.7us) */ + usec_delay(IXGBE_I2C_T_SU_STA); + + ixgbe_set_i2c_data(hw, &i2cctl, 0); + + /* Hold time for start condition (4us) */ + usec_delay(IXGBE_I2C_T_HD_STA); + + ixgbe_lower_i2c_clk(hw, &i2cctl); + + /* Minimum low period of clock is 4.7 us */ + usec_delay(IXGBE_I2C_T_LOW); + +} + +/** + * ixgbe_i2c_stop - Sets I2C stop condition + * @hw: pointer to hardware structure + * + * Sets I2C stop condition (Low -> High on SDA while SCL is High) + **/ +static void ixgbe_i2c_stop(struct ixgbe_hw *hw) +{ + u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); + + DEBUGFUNC("ixgbe_i2c_stop"); + + /* Stop condition must begin with data low and clock high */ + ixgbe_set_i2c_data(hw, &i2cctl, 0); + ixgbe_raise_i2c_clk(hw, &i2cctl); + + /* Setup time for stop condition (4us) */ + usec_delay(IXGBE_I2C_T_SU_STO); + + ixgbe_set_i2c_data(hw, &i2cctl, 1); + + /* bus free time between stop and start (4.7us)*/ + usec_delay(IXGBE_I2C_T_BUF); +} + +/** + * ixgbe_clock_in_i2c_byte - Clocks in one byte via I2C + * @hw: pointer to hardware structure + * @data: data byte to clock in + * + * Clocks in one byte data via I2C data/clock + **/ +static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data) +{ + s32 status = IXGBE_SUCCESS; + s32 i; + bool bit = 0; + + DEBUGFUNC("ixgbe_clock_in_i2c_byte"); + + for (i = 7; i >= 0; i--) { + status = ixgbe_clock_in_i2c_bit(hw, &bit); + *data |= bit<= 0; i--) { + bit = (data >> i) & 0x1; + status = ixgbe_clock_out_i2c_bit(hw, bit); + + if (status != IXGBE_SUCCESS) + break; + } + + /* Release SDA line (set high) */ + i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); + i2cctl |= IXGBE_I2C_DATA_OUT; + IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, i2cctl); + + return status; +} + +/** + * ixgbe_get_i2c_ack - Polls for I2C ACK + * @hw: pointer to hardware structure + * + * Clocks in/out one bit via I2C data/clock + **/ +static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw) +{ + s32 status; + u32 i = 0; + u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); + u32 timeout = 10; + bool ack = 1; + + DEBUGFUNC("ixgbe_get_i2c_ack"); + + status = ixgbe_raise_i2c_clk(hw, &i2cctl); + + if (status != IXGBE_SUCCESS) + goto out; + + /* Minimum high period of clock is 4us */ + usec_delay(IXGBE_I2C_T_HIGH); + + /* Poll for ACK. Note that ACK in I2C spec is + * transition from 1 to 0 */ + for (i = 0; i < timeout; i++) { + i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); + ack = ixgbe_get_i2c_data(&i2cctl); + + usec_delay(1); + if (ack == 0) + break; + } + + if (ack == 1) { + DEBUGOUT("I2C ack was not received.\n"); + status = IXGBE_ERR_I2C; + } + + ixgbe_lower_i2c_clk(hw, &i2cctl); + + /* Minimum low period of clock is 4.7 us */ + usec_delay(IXGBE_I2C_T_LOW); + +out: + return status; +} + +/** + * ixgbe_clock_in_i2c_bit - Clocks in one bit via I2C data/clock + * @hw: pointer to hardware structure + * @data: read data value + * + * Clocks in one bit via I2C data/clock + **/ +static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data) +{ + s32 status; + u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); + + status = ixgbe_raise_i2c_clk(hw, &i2cctl); + + /* Minimum high period of clock is 4us */ + usec_delay(IXGBE_I2C_T_HIGH); + + i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); + *data = ixgbe_get_i2c_data(&i2cctl); + + ixgbe_lower_i2c_clk(hw, &i2cctl); + + /* Minimum low period of clock is 4.7 us */ + usec_delay(IXGBE_I2C_T_LOW); + + return status; +} + +/** + * ixgbe_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock + * @hw: pointer to hardware structure + * @data: data value to write + * + * Clocks out one bit via I2C data/clock + **/ +static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data) +{ + s32 status; + u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); + + status = ixgbe_set_i2c_data(hw, &i2cctl, data); + if (status == IXGBE_SUCCESS) { + status = ixgbe_raise_i2c_clk(hw, &i2cctl); + + /* Minimum high period of clock is 4us */ + usec_delay(IXGBE_I2C_T_HIGH); + + ixgbe_lower_i2c_clk(hw, &i2cctl); + + /* Minimum low period of clock is 4.7 us. + * This also takes care of the data hold time. + */ + usec_delay(IXGBE_I2C_T_LOW); + } else { + status = IXGBE_ERR_I2C; + DEBUGOUT1("I2C data was not set to %X\n", data); + } + + return status; +} +/** + * ixgbe_raise_i2c_clk - Raises the I2C SCL clock + * @hw: pointer to hardware structure + * @i2cctl: Current value of I2CCTL register + * + * Raises the I2C clock line '0'->'1' + **/ +static s32 ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl) +{ + s32 status = IXGBE_SUCCESS; + + *i2cctl |= IXGBE_I2C_CLK_OUT; + + IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl); + + /* SCL rise time (1000ns) */ + usec_delay(IXGBE_I2C_T_RISE); + + return status; +} + +/** + * ixgbe_lower_i2c_clk - Lowers the I2C SCL clock + * @hw: pointer to hardware structure + * @i2cctl: Current value of I2CCTL register + * + * Lowers the I2C clock line '1'->'0' + **/ +static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl) +{ + + *i2cctl &= ~IXGBE_I2C_CLK_OUT; + + IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl); + + /* SCL fall time (300ns) */ + usec_delay(IXGBE_I2C_T_FALL); +} + +/** + * ixgbe_set_i2c_data - Sets the I2C data bit + * @hw: pointer to hardware structure + * @i2cctl: Current value of I2CCTL register + * @data: I2C data value (0 or 1) to set + * + * Sets the I2C data bit + **/ +static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data) +{ + s32 status = IXGBE_SUCCESS; + + if (data) + *i2cctl |= IXGBE_I2C_DATA_OUT; + else + *i2cctl &= ~IXGBE_I2C_DATA_OUT; + + IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl); + + /* Data rise/fall (1000ns/300ns) and set-up time (250ns) */ + usec_delay(IXGBE_I2C_T_RISE + IXGBE_I2C_T_FALL + IXGBE_I2C_T_SU_DATA); + + /* Verify data was set correctly */ + *i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); + if (data != ixgbe_get_i2c_data(i2cctl)) { + status = IXGBE_ERR_I2C; + DEBUGOUT1("Error - I2C data was not set to %X.\n", data); + } + + return status; +} + +/** + * ixgbe_get_i2c_data - Reads the I2C SDA data bit + * @hw: pointer to hardware structure + * @i2cctl: Current value of I2CCTL register + * + * Returns the I2C data bit value + **/ +static bool ixgbe_get_i2c_data(u32 *i2cctl) +{ + bool data; + + if (*i2cctl & IXGBE_I2C_DATA_IN) + data = 1; + else + data = 0; + + return data; +} + +/** + * ixgbe_i2c_bus_clear - Clears the I2C bus + * @hw: pointer to hardware structure + * + * Clears the I2C bus by sending nine clock pulses. + * Used when data line is stuck low. + **/ +void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw) +{ + u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); + u32 i; + + DEBUGFUNC("ixgbe_i2c_bus_clear"); + + ixgbe_i2c_start(hw); + + ixgbe_set_i2c_data(hw, &i2cctl, 1); + + for (i = 0; i < 9; i++) { + ixgbe_raise_i2c_clk(hw, &i2cctl); + + /* Min high period of clock is 4us */ + usec_delay(IXGBE_I2C_T_HIGH); + + ixgbe_lower_i2c_clk(hw, &i2cctl); + + /* Min low period of clock is 4.7us*/ + usec_delay(IXGBE_I2C_T_LOW); + } + + ixgbe_i2c_start(hw); + + /* Put the i2c bus back to default state */ + ixgbe_i2c_stop(hw); +} diff --git a/sys/dev/ixgbe/ixgbe_phy.h b/sys/dev/ixgbe/ixgbe_phy.h index 7a1e4c7d62f..047d31d0c7d 100644 --- a/sys/dev/ixgbe/ixgbe_phy.h +++ b/sys/dev/ixgbe/ixgbe_phy.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2009, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -51,6 +51,7 @@ /* Bitmasks */ #define IXGBE_SFF_TWIN_AX_CAPABLE 0x80 #define IXGBE_SFF_1GBASESX_CAPABLE 0x1 +#define IXGBE_SFF_1GBASELX_CAPABLE 0x2 #define IXGBE_SFF_10GBASESR_CAPABLE 0x10 #define IXGBE_SFF_10GBASELR_CAPABLE 0x20 #define IXGBE_I2C_EEPROM_READ_MASK 0x100 @@ -61,14 +62,15 @@ #define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS 0x3 /* Bit-shift macros */ -#define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT 12 -#define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT 8 -#define IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT 4 +#define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT 24 +#define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT 16 +#define IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT 8 /* Vendor OUIs: format of OUI is 0x[byte0][byte1][byte2][00] */ #define IXGBE_SFF_VENDOR_OUI_TYCO 0x00407600 #define IXGBE_SFF_VENDOR_OUI_FTL 0x00906500 #define IXGBE_SFF_VENDOR_OUI_AVAGO 0x00176A00 +#define IXGBE_SFF_VENDOR_OUI_INTEL 0x001B2100 /* I2C SDA and SCL timing parameters for standard mode */ #define IXGBE_I2C_T_HD_STA 4 @@ -98,6 +100,9 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete); +s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg); /* PHY specific */ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, @@ -105,10 +110,20 @@ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, bool *link_up); s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, u16 *firmware_version); +s32 ixgbe_get_phy_firmware_version_aq(struct ixgbe_hw *hw, + u16 *firmware_version); s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw); s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw); s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, u16 *list_offset, u16 *data_offset); +s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 *data); +s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 dev_addr, u8 data); +s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 *eeprom_data); +s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset, + u8 eeprom_data); #endif /* _IXGBE_PHY_H_ */ diff --git a/sys/dev/ixgbe/ixgbe_type.h b/sys/dev/ixgbe/ixgbe_type.h index f26576839a5..595a8637e7c 100644 --- a/sys/dev/ixgbe/ixgbe_type.h +++ b/sys/dev/ixgbe/ixgbe_type.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2009, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -42,6 +42,7 @@ /* Device IDs */ #define IXGBE_DEV_ID_82598 0x10B6 +#define IXGBE_DEV_ID_82598_BX 0x1508 #define IXGBE_DEV_ID_82598AF_DUAL_PORT 0x10C6 #define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7 #define IXGBE_DEV_ID_82598AT 0x10C8 @@ -51,6 +52,9 @@ #define IXGBE_DEV_ID_82598_DA_DUAL_PORT 0x10F1 #define IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM 0x10E1 #define IXGBE_DEV_ID_82598EB_XF_LR 0x10F4 +#define IXGBE_DEV_ID_82599_KX4 0x10F7 +#define IXGBE_DEV_ID_82599_CX4 0x10F9 +#define IXGBE_DEV_ID_82599_SFP 0x10FB /* General Registers */ #define IXGBE_CTRL 0x00000 @@ -58,9 +62,12 @@ #define IXGBE_CTRL_EXT 0x00018 #define IXGBE_ESDP 0x00020 #define IXGBE_EODSDP 0x00028 +#define IXGBE_I2CCTL 0x00028 #define IXGBE_LEDCTL 0x00200 #define IXGBE_FRTIMER 0x00048 #define IXGBE_TCPTIMER 0x0004C +#define IXGBE_CORESPARE 0x00600 +#define IXGBE_EXVET 0x05078 /* NVM Registers */ #define IXGBE_EEC 0x10010 @@ -74,6 +81,19 @@ #define IXGBE_FLOP 0x1013C #define IXGBE_GRC 0x10200 +/* General Receive Control */ +#define IXGBE_GRC_MNG 0x00000001 /* Manageability Enable */ +#define IXGBE_GRC_APME 0x00000002 /* Advanced Power Management Enable */ + +#define IXGBE_VPDDIAG0 0x10204 +#define IXGBE_VPDDIAG1 0x10208 + +/* I2CCTL Bit Masks */ +#define IXGBE_I2C_CLK_IN 0x00000001 +#define IXGBE_I2C_CLK_OUT 0x00000002 +#define IXGBE_I2C_DATA_IN 0x00000004 +#define IXGBE_I2C_DATA_OUT 0x00000008 + /* Interrupt Registers */ #define IXGBE_EICR 0x00800 #define IXGBE_EICS 0x00808 @@ -81,21 +101,45 @@ #define IXGBE_EIMC 0x00888 #define IXGBE_EIAC 0x00810 #define IXGBE_EIAM 0x00890 +#define IXGBE_EICS_EX(_i) (0x00A90 + (_i) * 4) +#define IXGBE_EIMS_EX(_i) (0x00AA0 + (_i) * 4) +#define IXGBE_EIMC_EX(_i) (0x00AB0 + (_i) * 4) +#define IXGBE_EIAM_EX(_i) (0x00AD0 + (_i) * 4) +/* 82599 EITR is only 12 bits, with the lower 3 always zero */ +/* + * 82598 EITR is 16 bits but set the limits based on the max + * supported by all ixgbe hardware + */ +#define IXGBE_MAX_INT_RATE 488281 +#define IXGBE_MIN_INT_RATE 956 +#define IXGBE_MAX_EITR 0x00000FF8 +#define IXGBE_MIN_EITR 8 #define IXGBE_EITR(_i) (((_i) <= 23) ? (0x00820 + ((_i) * 4)) : \ - (0x012300 + ((_i) * 4))) -#define IXGBE_EITR_ITR_INT_MASK 0x00000FFF + (0x012300 + (((_i) - 24) * 4))) +#define IXGBE_EITR_ITR_INT_MASK 0x00000FF8 +#define IXGBE_EITR_LLI_MOD 0x00008000 +#define IXGBE_EITR_CNT_WDIS 0x80000000 #define IXGBE_IVAR(_i) (0x00900 + ((_i) * 4)) /* 24 at 0x900-0x960 */ +#define IXGBE_IVAR_MISC 0x00A00 /* misc MSI-X interrupt causes */ +#define IXGBE_EITRSEL 0x00894 #define IXGBE_MSIXT 0x00000 /* MSI-X Table. 0x0000 - 0x01C */ #define IXGBE_MSIXPBA 0x02000 /* MSI-X Pending bit array */ #define IXGBE_PBACL(_i) (((_i) == 0) ? (0x11068) : (0x110C0 + ((_i) * 4))) #define IXGBE_GPIE 0x00898 /* Flow Control Registers */ +#define IXGBE_FCADBUL 0x03210 +#define IXGBE_FCADBUH 0x03214 +#define IXGBE_FCAMACL 0x04328 +#define IXGBE_FCAMACH 0x0432C +#define IXGBE_FCRTH_82599(_i) (0x03260 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_FCRTL_82599(_i) (0x03220 + ((_i) * 4)) /* 8 of these (0-7) */ #define IXGBE_PFCTOP 0x03008 #define IXGBE_FCTTV(_i) (0x03200 + ((_i) * 4)) /* 4 of these (0-3) */ #define IXGBE_FCRTL(_i) (0x03220 + ((_i) * 8)) /* 8 of these (0-7) */ #define IXGBE_FCRTH(_i) (0x03260 + ((_i) * 8)) /* 8 of these (0-7) */ #define IXGBE_FCRTV 0x032A0 +#define IXGBE_FCCFG 0x03D00 #define IXGBE_TFCS 0x0CE00 /* Receive DMA Registers */ @@ -111,6 +155,12 @@ (0x0D018 + ((_i - 64) * 0x40))) #define IXGBE_RXDCTL(_i) (((_i) < 64) ? (0x01028 + ((_i) * 0x40)) : \ (0x0D028 + ((_i - 64) * 0x40))) +#define IXGBE_RSCCTL(_i) (((_i) < 64) ? (0x0102C + ((_i) * 0x40)) : \ + (0x0D02C + ((_i - 64) * 0x40))) +#define IXGBE_RSCDBU 0x03028 +#define IXGBE_RDDCC 0x02F20 +#define IXGBE_RXMEMWRAP 0x03190 +#define IXGBE_STARCTRL 0x03024 /* * Split and Replication Receive Control Registers * 00-15 : 0x02100 + n*4 @@ -130,6 +180,7 @@ (((_i) < 64) ? (0x0100C + ((_i) * 0x40)) : \ (0x0D00C + ((_i - 64) * 0x40)))) #define IXGBE_RDRXCTL 0x02F00 +#define IXGBE_RDRXCTL_RSC_PUSH 0x80 #define IXGBE_RXPBSIZE(_i) (0x03C00 + ((_i) * 4)) /* 8 of these 0x03C00 - 0x03C1C */ #define IXGBE_RXCTRL 0x03000 @@ -147,6 +198,8 @@ (0x0A200 + ((_i) * 8))) #define IXGBE_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \ (0x0A204 + ((_i) * 8))) +#define IXGBE_MPSAR_LO(_i) (0x0A600 + ((_i) * 8)) +#define IXGBE_MPSAR_HI(_i) (0x0A604 + ((_i) * 8)) /* Packet split receive type */ #define IXGBE_PSRTYPE(_i) (((_i) <= 15) ? (0x05480 + ((_i) * 4)) : \ (0x0EA00 + ((_i) * 4))) @@ -158,6 +211,28 @@ #define IXGBE_VLNCTRL 0x05088 #define IXGBE_MCSTCTRL 0x05090 #define IXGBE_MRQC 0x05818 +#define IXGBE_SAQF(_i) (0x0E000 + ((_i) * 4)) /* Source Address Queue Filter */ +#define IXGBE_DAQF(_i) (0x0E200 + ((_i) * 4)) /* Dest. Address Queue Filter */ +#define IXGBE_SDPQF(_i) (0x0E400 + ((_i) * 4)) /* Src Dest. Addr Queue Filter */ +#define IXGBE_FTQF(_i) (0x0E600 + ((_i) * 4)) /* Five Tuple Queue Filter */ +#define IXGBE_ETQF(_i) (0x05128 + ((_i) * 4)) /* EType Queue Filter */ +#define IXGBE_ETQS(_i) (0x0EC00 + ((_i) * 4)) /* EType Queue Select */ +#define IXGBE_SYNQF 0x0EC30 /* SYN Packet Queue Filter */ +#define IXGBE_RQTC 0x0EC70 +#define IXGBE_MTQC 0x08120 +#define IXGBE_VLVF(_i) (0x0F100 + ((_i) * 4)) /* 64 of these (0-63) */ +#define IXGBE_VLVFB(_i) (0x0F200 + ((_i) * 4)) /* 128 of these (0-127) */ +#define IXGBE_VT_CTL 0x051B0 +#define IXGBE_VFRE(_i) (0x051E0 + ((_i) * 4)) +#define IXGBE_VFTE(_i) (0x08110 + ((_i) * 4)) +#define IXGBE_QDE 0x2F04 +#define IXGBE_VMOLR(_i) (0x0F000 + ((_i) * 4)) /* 64 total */ +#define IXGBE_UTA(_i) (0x0F400 + ((_i) * 4)) +#define IXGBE_VMRCTL(_i) (0x0F600 + ((_i) * 4)) +#define IXGBE_VMRVLAN(_i) (0x0F610 + ((_i) * 4)) +#define IXGBE_VMRVM(_i) (0x0F630 + ((_i) * 4)) +#define IXGBE_L34T_IMIR(_i) (0x0E800 + ((_i) * 4)) /*128 of these (0-127)*/ +#define IXGBE_LLITHRESH 0x0EC90 #define IXGBE_IMIR(_i) (0x05A80 + ((_i) * 4)) /* 8 of these (0-7) */ #define IXGBE_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* 8 of these (0-7) */ #define IXGBE_IMIRVP 0x05AC0 @@ -165,6 +240,33 @@ #define IXGBE_RETA(_i) (0x05C00 + ((_i) * 4)) /* 32 of these (0-31) */ #define IXGBE_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* 10 of these (0-9) */ +/* Flow Director registers */ +#define IXGBE_FDIRCTRL 0x0EE00 +#define IXGBE_FDIRHKEY 0x0EE68 +#define IXGBE_FDIRSKEY 0x0EE6C +#define IXGBE_FDIRDIP4M 0x0EE3C +#define IXGBE_FDIRSIP4M 0x0EE40 +#define IXGBE_FDIRTCPM 0x0EE44 +#define IXGBE_FDIRUDPM 0x0EE48 +#define IXGBE_FDIRIP6M 0x0EE74 +#define IXGBE_FDIRM 0x0EE70 + +/* Flow Director Stats registers */ +#define IXGBE_FDIRFREE 0x0EE38 +#define IXGBE_FDIRLEN 0x0EE4C +#define IXGBE_FDIRUSTAT 0x0EE50 +#define IXGBE_FDIRFSTAT 0x0EE54 +#define IXGBE_FDIRMATCH 0x0EE58 +#define IXGBE_FDIRMISS 0x0EE5C + +/* Flow Director Programming registers */ +#define IXGBE_FDIRSIPv6(_i) (0x0EE0C + ((_i) * 4)) /* 3 of these (0-2) */ +#define IXGBE_FDIRIPSA 0x0EE18 +#define IXGBE_FDIRIPDA 0x0EE1C +#define IXGBE_FDIRPORT 0x0EE20 +#define IXGBE_FDIRVLAN 0x0EE24 +#define IXGBE_FDIRHASH 0x0EE28 +#define IXGBE_FDIRCMD 0x0EE2C /* Transmit DMA registers */ #define IXGBE_TDBAL(_i) (0x06000 + ((_i) * 0x40)) /* 32 of these (0-31)*/ @@ -177,7 +279,20 @@ #define IXGBE_TDWBAH(_i) (0x0603C + ((_i) * 0x40)) #define IXGBE_DTXCTL 0x07E00 +#define IXGBE_DMATXCTL 0x04A80 +#define IXGBE_DTXMXSZRQ 0x08100 +#define IXGBE_DTXTCPFLGL 0x04A88 +#define IXGBE_DTXTCPFLGH 0x04A8C +#define IXGBE_LBDRPEN 0x0CA00 +#define IXGBE_TXPBTHRESH(_i) (0x04950 + ((_i) * 4)) /* 8 of these 0 - 7 */ + +#define IXGBE_DMATXCTL_TE 0x1 /* Transmit Enable */ +#define IXGBE_DMATXCTL_NS 0x2 /* No Snoop LSO hdr buffer */ +#define IXGBE_DMATXCTL_GDV 0x8 /* Global Double VLAN */ +#define IXGBE_DMATXCTL_VT_SHIFT 16 /* VLAN EtherType */ #define IXGBE_DCA_TXCTRL(_i) (0x07200 + ((_i) * 4)) /* 16 of these (0-15) */ +/* Tx DCA Control register : 128 of these (0-127) */ +#define IXGBE_DCA_TXCTRL_82599(_i) (0x0600C + ((_i) * 0x40)) #define IXGBE_TIPG 0x0CB00 #define IXGBE_TXPBSIZE(_i) (0x0CC00 + ((_i) * 4)) /* 8 of these */ #define IXGBE_MNGTXMAP 0x0CD10 @@ -269,6 +384,193 @@ #define IXGBE_TDPT2TCSR(_i) (0x0CD40 + ((_i) * 4)) /* 8 of these (0-7) */ +/* Security Control Registers */ +#define IXGBE_SECTXCTRL 0x08800 +#define IXGBE_SECTXSTAT 0x08804 +#define IXGBE_SECTXBUFFAF 0x08808 +#define IXGBE_SECTXMINIFG 0x08810 +#define IXGBE_SECTXSTAT 0x08804 +#define IXGBE_SECRXCTRL 0x08D00 +#define IXGBE_SECRXSTAT 0x08D04 + +/* Security Bit Fields and Masks */ +#define IXGBE_SECTXCTRL_SECTX_DIS 0x00000001 +#define IXGBE_SECTXCTRL_TX_DIS 0x00000002 +#define IXGBE_SECTXCTRL_STORE_FORWARD 0x00000004 + +#define IXGBE_SECTXSTAT_SECTX_RDY 0x00000001 +#define IXGBE_SECTXSTAT_ECC_TXERR 0x00000002 + +#define IXGBE_SECRXCTRL_SECRX_DIS 0x00000001 +#define IXGBE_SECRXCTRL_RX_DIS 0x00000002 + +#define IXGBE_SECRXSTAT_SECRX_RDY 0x00000001 +#define IXGBE_SECRXSTAT_ECC_RXERR 0x00000002 + +/* LinkSec (MacSec) Registers */ +#define IXGBE_LSECTXCAP 0x08A00 +#define IXGBE_LSECRXCAP 0x08F00 +#define IXGBE_LSECTXCTRL 0x08A04 +#define IXGBE_LSECTXSCL 0x08A08 /* SCI Low */ +#define IXGBE_LSECTXSCH 0x08A0C /* SCI High */ +#define IXGBE_LSECTXSA 0x08A10 +#define IXGBE_LSECTXPN0 0x08A14 +#define IXGBE_LSECTXPN1 0x08A18 +#define IXGBE_LSECTXKEY0(_n) (0x08A1C + (4 * (_n))) /* 4 of these (0-3) */ +#define IXGBE_LSECTXKEY1(_n) (0x08A2C + (4 * (_n))) /* 4 of these (0-3) */ +#define IXGBE_LSECRXCTRL 0x08F04 +#define IXGBE_LSECRXSCL 0x08F08 +#define IXGBE_LSECRXSCH 0x08F0C +#define IXGBE_LSECRXSA(_i) (0x08F10 + (4 * (_i))) /* 2 of these (0-1) */ +#define IXGBE_LSECRXPN(_i) (0x08F18 + (4 * (_i))) /* 2 of these (0-1) */ +#define IXGBE_LSECRXKEY(_n, _m) (0x08F20 + ((0x10 * (_n)) + (4 * (_m)))) +#define IXGBE_LSECTXUT 0x08A3C /* OutPktsUntagged */ +#define IXGBE_LSECTXPKTE 0x08A40 /* OutPktsEncrypted */ +#define IXGBE_LSECTXPKTP 0x08A44 /* OutPktsProtected */ +#define IXGBE_LSECTXOCTE 0x08A48 /* OutOctetsEncrypted */ +#define IXGBE_LSECTXOCTP 0x08A4C /* OutOctetsProtected */ +#define IXGBE_LSECRXUT 0x08F40 /* InPktsUntagged/InPktsNoTag */ +#define IXGBE_LSECRXOCTD 0x08F44 /* InOctetsDecrypted */ +#define IXGBE_LSECRXOCTV 0x08F48 /* InOctetsValidated */ +#define IXGBE_LSECRXBAD 0x08F4C /* InPktsBadTag */ +#define IXGBE_LSECRXNOSCI 0x08F50 /* InPktsNoSci */ +#define IXGBE_LSECRXUNSCI 0x08F54 /* InPktsUnknownSci */ +#define IXGBE_LSECRXUNCH 0x08F58 /* InPktsUnchecked */ +#define IXGBE_LSECRXDELAY 0x08F5C /* InPktsDelayed */ +#define IXGBE_LSECRXLATE 0x08F60 /* InPktsLate */ +#define IXGBE_LSECRXOK(_n) (0x08F64 + (0x04 * (_n))) /* InPktsOk */ +#define IXGBE_LSECRXINV(_n) (0x08F6C + (0x04 * (_n))) /* InPktsInvalid */ +#define IXGBE_LSECRXNV(_n) (0x08F74 + (0x04 * (_n))) /* InPktsNotValid */ +#define IXGBE_LSECRXUNSA 0x08F7C /* InPktsUnusedSa */ +#define IXGBE_LSECRXNUSA 0x08F80 /* InPktsNotUsingSa */ + +/* LinkSec (MacSec) Bit Fields and Masks */ +#define IXGBE_LSECTXCAP_SUM_MASK 0x00FF0000 +#define IXGBE_LSECTXCAP_SUM_SHIFT 16 +#define IXGBE_LSECRXCAP_SUM_MASK 0x00FF0000 +#define IXGBE_LSECRXCAP_SUM_SHIFT 16 + +#define IXGBE_LSECTXCTRL_EN_MASK 0x00000003 +#define IXGBE_LSECTXCTRL_DISABLE 0x0 +#define IXGBE_LSECTXCTRL_AUTH 0x1 +#define IXGBE_LSECTXCTRL_AUTH_ENCRYPT 0x2 +#define IXGBE_LSECTXCTRL_AISCI 0x00000020 +#define IXGBE_LSECTXCTRL_PNTHRSH_MASK 0xFFFFFF00 +#define IXGBE_LSECTXCTRL_RSV_MASK 0x000000D8 + +#define IXGBE_LSECRXCTRL_EN_MASK 0x0000000C +#define IXGBE_LSECRXCTRL_EN_SHIFT 2 +#define IXGBE_LSECRXCTRL_DISABLE 0x0 +#define IXGBE_LSECRXCTRL_CHECK 0x1 +#define IXGBE_LSECRXCTRL_STRICT 0x2 +#define IXGBE_LSECRXCTRL_DROP 0x3 +#define IXGBE_LSECRXCTRL_PLSH 0x00000040 +#define IXGBE_LSECRXCTRL_RP 0x00000080 +#define IXGBE_LSECRXCTRL_RSV_MASK 0xFFFFFF33 + +/* IpSec Registers */ +#define IXGBE_IPSTXIDX 0x08900 +#define IXGBE_IPSTXSALT 0x08904 +#define IXGBE_IPSTXKEY(_i) (0x08908 + (4 * (_i))) /* 4 of these (0-3) */ +#define IXGBE_IPSRXIDX 0x08E00 +#define IXGBE_IPSRXIPADDR(_i) (0x08E04 + (4 * (_i))) /* 4 of these (0-3) */ +#define IXGBE_IPSRXSPI 0x08E14 +#define IXGBE_IPSRXIPIDX 0x08E18 +#define IXGBE_IPSRXKEY(_i) (0x08E1C + (4 * (_i))) /* 4 of these (0-3) */ +#define IXGBE_IPSRXSALT 0x08E2C +#define IXGBE_IPSRXMOD 0x08E30 + +#define IXGBE_SECTXCTRL_STORE_FORWARD_ENABLE 0x4 + +/* DCB registers */ +#define IXGBE_RTRPCS 0x02430 +#define IXGBE_RTTDCS 0x04900 +#define IXGBE_RTTDCS_ARBDIS 0x00000040 /* DCB arbiter disable */ +#define IXGBE_RTTPCS 0x0CD00 +#define IXGBE_RTRUP2TC 0x03020 +#define IXGBE_RTTUP2TC 0x0C800 +#define IXGBE_RTRPT4C(_i) (0x02140 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_RTRPT4S(_i) (0x02160 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_RTTDT2C(_i) (0x04910 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_RTTDT2S(_i) (0x04930 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_RTTPT2C(_i) (0x0CD20 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_RTTPT2S(_i) (0x0CD40 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_RTTDQSEL 0x04904 +#define IXGBE_RTTDT1C 0x04908 +#define IXGBE_RTTDT1S 0x0490C +#define IXGBE_RTTDTECC 0x04990 +#define IXGBE_RTTDTECC_NO_BCN 0x00000100 + +#define IXGBE_RTTBCNRC 0x04984 + +/* BCN (for DCB) Registers */ +#define IXGBE_RTTBCNRM 0x04980 +#define IXGBE_RTTBCNRS 0x04988 +#define IXGBE_RTTBCNCR 0x08B00 +#define IXGBE_RTTBCNACH 0x08B04 +#define IXGBE_RTTBCNACL 0x08B08 +#define IXGBE_RTTBCNTG 0x04A90 +#define IXGBE_RTTBCNIDX 0x08B0C +#define IXGBE_RTTBCNCP 0x08B10 +#define IXGBE_RTFRTIMER 0x08B14 +#define IXGBE_RTTBCNRTT 0x05150 +#define IXGBE_RTTBCNRD 0x0498C + +/* FCoE DMA Context Registers */ +#define IXGBE_FCPTRL 0x02410 /* FC User Desc. PTR Low */ +#define IXGBE_FCPTRH 0x02414 /* FC USer Desc. PTR High */ +#define IXGBE_FCBUFF 0x02418 /* FC Buffer Control */ +#define IXGBE_FCDMARW 0x02420 /* FC Receive DMA RW */ +#define IXGBE_FCINVST0 0x03FC0 /* FC Invalid DMA Context Status Reg 0 */ +#define IXGBE_FCINVST(_i) (IXGBE_FCINVST0 + ((_i) * 4)) +#define IXGBE_FCBUFF_VALID (1 << 0) /* DMA Context Valid */ +#define IXGBE_FCBUFF_BUFFSIZE (3 << 3) /* User Buffer Size */ +#define IXGBE_FCBUFF_WRCONTX (1 << 7) /* 0: Initiator, 1: Target */ +#define IXGBE_FCBUFF_BUFFCNT 0x0000ff00 /* Number of User Buffers */ +#define IXGBE_FCBUFF_OFFSET 0xffff0000 /* User Buffer Offset */ +#define IXGBE_FCBUFF_BUFFSIZE_SHIFT 3 +#define IXGBE_FCBUFF_BUFFCNT_SHIFT 8 +#define IXGBE_FCBUFF_OFFSET_SHIFT 16 +#define IXGBE_FCDMARW_WE (1 << 14) /* Write enable */ +#define IXGBE_FCDMARW_RE (1 << 15) /* Read enable */ +#define IXGBE_FCDMARW_FCOESEL 0x000001ff /* FC X_ID: 11 bits */ +#define IXGBE_FCDMARW_LASTSIZE 0xffff0000 /* Last User Buffer Size */ +#define IXGBE_FCDMARW_LASTSIZE_SHIFT 16 +/* FCoE SOF/EOF */ +#define IXGBE_TEOFF 0x04A94 /* Tx FC EOF */ +#define IXGBE_TSOFF 0x04A98 /* Tx FC SOF */ +#define IXGBE_REOFF 0x05158 /* Rx FC EOF */ +#define IXGBE_RSOFF 0x051F8 /* Rx FC SOF */ +/* FCoE Filter Context Registers */ +#define IXGBE_FCFLT 0x05108 /* FC FLT Context */ +#define IXGBE_FCFLTRW 0x05110 /* FC Filter RW Control */ +#define IXGBE_FCPARAM 0x051d8 /* FC Offset Parameter */ +#define IXGBE_FCFLT_VALID (1 << 0) /* Filter Context Valid */ +#define IXGBE_FCFLT_FIRST (1 << 1) /* Filter First */ +#define IXGBE_FCFLT_SEQID 0x00ff0000 /* Sequence ID */ +#define IXGBE_FCFLT_SEQCNT 0xff000000 /* Sequence Count */ +#define IXGBE_FCFLTRW_RVALDT (1 << 13) /* Fast Re-Validation */ +#define IXGBE_FCFLTRW_WE (1 << 14) /* Write Enable */ +#define IXGBE_FCFLTRW_RE (1 << 15) /* Read Enable */ +/* FCoE Receive Control */ +#define IXGBE_FCRXCTRL 0x05100 /* FC Receive Control */ +#define IXGBE_FCRXCTRL_FCOELLI (1 << 0) /* Low latency interrupt */ +#define IXGBE_FCRXCTRL_SAVBAD (1 << 1) /* Save Bad Frames */ +#define IXGBE_FCRXCTRL_FRSTRDH (1 << 2) /* EN 1st Read Header */ +#define IXGBE_FCRXCTRL_LASTSEQH (1 << 3) /* EN Last Header in Seq */ +#define IXGBE_FCRXCTRL_ALLH (1 << 4) /* EN All Headers */ +#define IXGBE_FCRXCTRL_FRSTSEQH (1 << 5) /* EN 1st Seq. Header */ +#define IXGBE_FCRXCTRL_ICRC (1 << 6) /* Ignore Bad FC CRC */ +#define IXGBE_FCRXCTRL_FCCRCBO (1 << 7) /* FC CRC Byte Ordering */ +#define IXGBE_FCRXCTRL_FCOEVER 0x00000f00 /* FCoE Version: 4 bits */ +#define IXGBE_FCRXCTRL_FCOEVER_SHIFT 8 +/* FCoE Redirection */ +#define IXGBE_FCRECTL 0x0ED00 /* FC Redirection Control */ +#define IXGBE_FCRETA0 0x0ED10 /* FC Redirection Table 0 */ +#define IXGBE_FCRETA(_i) (IXGBE_FCRETA0 + ((_i) * 4)) /* FCoE Redir */ +#define IXGBE_FCRECTL_ENA 0x1 /* FCoE Redir Table Enable */ +#define IXGBE_FCRETA_SIZE 8 /* Max entries in FCRETA */ +#define IXGBE_FCRETA_ENTRY_MASK 0x0000007f /* 7 bits for the queue index */ /* Stats registers */ #define IXGBE_CRCERRS 0x04000 @@ -283,6 +585,11 @@ #define IXGBE_LXONRXC 0x0CF60 #define IXGBE_LXOFFTXC 0x03F68 #define IXGBE_LXOFFRXC 0x0CF68 +#define IXGBE_LXONRXCNT 0x041A4 +#define IXGBE_LXOFFRXCNT 0x041A8 +#define IXGBE_PXONRXCNT(_i) (0x04140 + ((_i) * 4)) /* 8 of these */ +#define IXGBE_PXOFFRXCNT(_i) (0x04160 + ((_i) * 4)) /* 8 of these */ +#define IXGBE_PXON2OFFCNT(_i) (0x03240 + ((_i) * 4)) /* 8 of these */ #define IXGBE_PXONTXC(_i) (0x03F00 + ((_i) * 4)) /* 8 of these 3F00-3F1C*/ #define IXGBE_PXONRXC(_i) (0x0CF00 + ((_i) * 4)) /* 8 of these CF00-CF1C*/ #define IXGBE_PXOFFTXC(_i) (0x03F20 + ((_i) * 4)) /* 8 of these 3F20-3F3C*/ @@ -322,15 +629,29 @@ #define IXGBE_MPTC 0x040F0 #define IXGBE_BPTC 0x040F4 #define IXGBE_XEC 0x04120 +#define IXGBE_SSVPC 0x08780 #define IXGBE_RQSMR(_i) (0x02300 + ((_i) * 4)) #define IXGBE_TQSMR(_i) (((_i) <= 7) ? (0x07300 + ((_i) * 4)) : \ (0x08600 + ((_i) * 4))) +#define IXGBE_TQSM(_i) (0x08600 + ((_i) * 4)) #define IXGBE_QPRC(_i) (0x01030 + ((_i) * 0x40)) /* 16 of these */ #define IXGBE_QPTC(_i) (0x06030 + ((_i) * 0x40)) /* 16 of these */ #define IXGBE_QBRC(_i) (0x01034 + ((_i) * 0x40)) /* 16 of these */ #define IXGBE_QBTC(_i) (0x06034 + ((_i) * 0x40)) /* 16 of these */ +#define IXGBE_QPRDC(_i) (0x01430 + ((_i) * 0x40)) /* 16 of these */ +#define IXGBE_QBTC_L(_i) (0x08700 + ((_i) * 0x8)) /* 16 of these */ +#define IXGBE_QBTC_H(_i) (0x08704 + ((_i) * 0x8)) /* 16 of these */ +#define IXGBE_FCCRC 0x05118 /* Count of Good Eth CRC w/ Bad FC CRC */ +#define IXGBE_FCOERPDC 0x0241C /* FCoE Rx Packets Dropped Count */ +#define IXGBE_FCLAST 0x02424 /* FCoE Last Error Count */ +#define IXGBE_FCOEPRC 0x02428 /* Number of FCoE Packets Received */ +#define IXGBE_FCOEDWRC 0x0242C /* Number of FCoE DWords Received */ +#define IXGBE_FCOEPTC 0x08784 /* Number of FCoE Packets Transmitted */ +#define IXGBE_FCOEDWTC 0x08788 /* Number of FCoE DWords Transmitted */ +#define IXGBE_FCCRC_CNT_MASK 0x0000FFFF /* CRC_CNT: bit 0 - 15 */ +#define IXGBE_FCLAST_CNT_MASK 0x0000FFFF /* Last_CNT: bit 0 - 15 */ /* Management */ #define IXGBE_MAVTV(_i) (0x05010 + ((_i) * 4)) /* 8 of these (0-7) */ @@ -343,6 +664,9 @@ #define IXGBE_MMAL(_i) (0x05910 + ((_i) * 8)) /* 4 of these (0-3) */ #define IXGBE_MMAH(_i) (0x05914 + ((_i) * 8)) /* 4 of these (0-3) */ #define IXGBE_FTFT 0x09400 /* 0x9400-0x97FC */ +#define IXGBE_METF(_i) (0x05190 + ((_i) * 4)) /* 4 of these (0-3) */ +#define IXGBE_MDEF_EXT(_i) (0x05160 + ((_i) * 4)) /* 8 of these (0-7) */ +#define IXGBE_LSWFW 0x15014 /* ARC Subsystem registers */ #define IXGBE_HICR 0x15F00 @@ -375,16 +699,65 @@ #define IXGBE_DCA_ID 0x11070 #define IXGBE_DCA_CTRL 0x11074 +/* PCI-E registers 82599-Specific */ +#define IXGBE_GCR_EXT 0x11050 +#define IXGBE_GSCL_5_82599 0x11030 +#define IXGBE_GSCL_6_82599 0x11034 +#define IXGBE_GSCL_7_82599 0x11038 +#define IXGBE_GSCL_8_82599 0x1103C +#define IXGBE_PHYADR_82599 0x11040 +#define IXGBE_PHYDAT_82599 0x11044 +#define IXGBE_PHYCTL_82599 0x11048 +#define IXGBE_PBACLR_82599 0x11068 +#define IXGBE_CIAA_82599 0x11088 +#define IXGBE_CIAD_82599 0x1108C +#define IXGBE_PCIE_DIAG_0_82599 0x11090 +#define IXGBE_PCIE_DIAG_1_82599 0x11094 +#define IXGBE_PCIE_DIAG_2_82599 0x11098 +#define IXGBE_PCIE_DIAG_3_82599 0x1109C +#define IXGBE_PCIE_DIAG_4_82599 0x110A0 +#define IXGBE_PCIE_DIAG_5_82599 0x110A4 +#define IXGBE_PCIE_DIAG_6_82599 0x110A8 +#define IXGBE_PCIE_DIAG_7_82599 0x110C0 +#define IXGBE_INTRPT_CSR_82599 0x110B0 +#define IXGBE_INTRPT_MASK_82599 0x110B8 +#define IXGBE_CDQ_MBR_82599 0x110B4 +#define IXGBE_MISC_REG_82599 0x110F0 +#define IXGBE_ECC_CTRL_0_82599 0x11100 +#define IXGBE_ECC_CTRL_1_82599 0x11104 +#define IXGBE_ECC_STATUS_82599 0x110E0 +#define IXGBE_BAR_CTRL_82599 0x110F4 + +/* Time Sync Registers */ +#define IXGBE_TSYNCRXCTL 0x05188 /* Rx Time Sync Control register - RW */ +#define IXGBE_TSYNCTXCTL 0x08C00 /* Tx Time Sync Control register - RW */ +#define IXGBE_RXSTMPL 0x051E8 /* Rx timestamp Low - RO */ +#define IXGBE_RXSTMPH 0x051A4 /* Rx timestamp High - RO */ +#define IXGBE_RXSATRL 0x051A0 /* Rx timestamp attribute low - RO */ +#define IXGBE_RXSATRH 0x051A8 /* Rx timestamp attribute high - RO */ +#define IXGBE_RXMTRL 0x05120 /* RX message type register low - RW */ +#define IXGBE_TXSTMPL 0x08C04 /* Tx timestamp value Low - RO */ +#define IXGBE_TXSTMPH 0x08C08 /* Tx timestamp value High - RO */ +#define IXGBE_SYSTIML 0x08C0C /* System time register Low - RO */ +#define IXGBE_SYSTIMH 0x08C10 /* System time register High - RO */ +#define IXGBE_TIMINCA 0x08C14 /* Increment attributes register - RW */ +#define IXGBE_RXUDP 0x08C1C /* Time Sync Rx UDP Port - RW */ + /* Diagnostic Registers */ #define IXGBE_RDSTATCTL 0x02C20 #define IXGBE_RDSTAT(_i) (0x02C00 + ((_i) * 4)) /* 0x02C00-0x02C1C */ #define IXGBE_RDHMPN 0x02F08 #define IXGBE_RIC_DW(_i) (0x02F10 + ((_i) * 4)) #define IXGBE_RDPROBE 0x02F20 +#define IXGBE_RDMAM 0x02F30 +#define IXGBE_RDMAD 0x02F34 #define IXGBE_TDSTATCTL 0x07C20 #define IXGBE_TDSTAT(_i) (0x07C00 + ((_i) * 4)) /* 0x07C00 - 0x07C1C */ #define IXGBE_TDHMPN 0x07F08 +#define IXGBE_TDHMPN2 0x082FC +#define IXGBE_TXDESCIC 0x082CC #define IXGBE_TIC_DW(_i) (0x07F10 + ((_i) * 4)) +#define IXGBE_TIC_DW2(_i) (0x082B0 + ((_i) * 4)) #define IXGBE_TDPROBE 0x07F20 #define IXGBE_TXBUFCTRL 0x0C600 #define IXGBE_TXBUFDATA0 0x0C610 @@ -412,6 +785,10 @@ #define IXGBE_TXDATARDPTR(_i) (0x0C720 + ((_i) * 4)) /* 8 of these C720-C72C*/ #define IXGBE_TXDESCRDPTR(_i) (0x0C730 + ((_i) * 4)) /* 8 of these C730-C73C*/ #define IXGBE_PCIEECCCTL 0x1106C +#define IXGBE_PCIEECCCTL0 0x11100 +#define IXGBE_PCIEECCCTL1 0x11104 +#define IXGBE_RXDBUECC 0x03F70 +#define IXGBE_TXDBUECC 0x0CF70 #define IXGBE_PBTXECC 0x0C300 #define IXGBE_PBRXECC 0x03300 #define IXGBE_GHECCR 0x110B0 @@ -437,24 +814,74 @@ #define IXGBE_MSRWD 0x04260 #define IXGBE_MLADD 0x04264 #define IXGBE_MHADD 0x04268 +#define IXGBE_MAXFRS 0x04268 #define IXGBE_TREG 0x0426C #define IXGBE_PCSS1 0x04288 #define IXGBE_PCSS2 0x0428C #define IXGBE_XPCSS 0x04290 +#define IXGBE_MFLCN 0x04294 #define IXGBE_SERDESC 0x04298 #define IXGBE_MACS 0x0429C #define IXGBE_AUTOC 0x042A0 #define IXGBE_LINKS 0x042A4 +#define IXGBE_LINKS2 0x04324 #define IXGBE_AUTOC2 0x042A8 #define IXGBE_AUTOC3 0x042AC #define IXGBE_ANLP1 0x042B0 #define IXGBE_ANLP2 0x042B4 #define IXGBE_ATLASCTL 0x04800 +#define IXGBE_MMNGC 0x042D0 +#define IXGBE_ANLPNP1 0x042D4 +#define IXGBE_ANLPNP2 0x042D8 +#define IXGBE_KRPCSFC 0x042E0 +#define IXGBE_KRPCSS 0x042E4 +#define IXGBE_FECS1 0x042E8 +#define IXGBE_FECS2 0x042EC +#define IXGBE_SMADARCTL 0x14F10 +#define IXGBE_MPVC 0x04318 +#define IXGBE_SGMIIC 0x04314 + +/* Omer CORECTL */ +#define IXGBE_CORECTL 0x014F00 +/* BARCTRL */ +#define IXGBE_BARCTRL 0x110F4 +#define IXGBE_BARCTRL_FLSIZE 0x0700 +#define IXGBE_BARCTRL_CSRSIZE 0x2000 + +/* RSCCTL Bit Masks */ +#define IXGBE_RSCCTL_RSCEN 0x01 +#define IXGBE_RSCCTL_MAXDESC_1 0x00 +#define IXGBE_RSCCTL_MAXDESC_4 0x04 +#define IXGBE_RSCCTL_MAXDESC_8 0x08 +#define IXGBE_RSCCTL_MAXDESC_16 0x0C + +/* RSCDBU Bit Masks */ +#define IXGBE_RSCDBU_RSCSMALDIS_MASK 0x0000007F +#define IXGBE_RSCDBU_RSCACKDIS 0x00000080 /* RDRXCTL Bit Masks */ #define IXGBE_RDRXCTL_RDMTS_1_2 0x00000000 /* Rx Desc Min Threshold Size */ +#define IXGBE_RDRXCTL_CRCSTRIP 0x00000002 /* CRC Strip */ #define IXGBE_RDRXCTL_MVMEN 0x00000020 #define IXGBE_RDRXCTL_DMAIDONE 0x00000008 /* DMA init cycle done */ +#define IXGBE_RDRXCTL_AGGDIS 0x00010000 /* Aggregation disable */ +#define IXGBE_RDRXCTL_RSCFRSTSIZE 0x003E0000 /* RSC First packet size */ +#define IXGBE_RDRXCTL_RSCLLIDIS 0x00800000 /* Disable RSC compl on LLI */ + +/* RQTC Bit Masks and Shifts */ +#define IXGBE_RQTC_SHIFT_TC(_i) ((_i) * 4) +#define IXGBE_RQTC_TC0_MASK (0x7 << 0) +#define IXGBE_RQTC_TC1_MASK (0x7 << 4) +#define IXGBE_RQTC_TC2_MASK (0x7 << 8) +#define IXGBE_RQTC_TC3_MASK (0x7 << 12) +#define IXGBE_RQTC_TC4_MASK (0x7 << 16) +#define IXGBE_RQTC_TC5_MASK (0x7 << 20) +#define IXGBE_RQTC_TC6_MASK (0x7 << 24) +#define IXGBE_RQTC_TC7_MASK (0x7 << 28) + +/* PSRTYPE.RQPL Bit masks and shift */ +#define IXGBE_PSRTYPE_RQPL_MASK 0x7 +#define IXGBE_PSRTYPE_RQPL_SHIFT 29 /* CTRL Bit Masks */ #define IXGBE_CTRL_GIO_DIS 0x00000004 /* Global IO Master Disable bit */ @@ -482,11 +909,18 @@ #define IXGBE_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */ #define IXGBE_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */ +#define IXGBE_DCA_RXCTRL_CPUID_MASK_82599 0xFF000000 /* Rx CPUID Mask */ +#define IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599 24 /* Rx CPUID Shift */ #define IXGBE_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */ #define IXGBE_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header enable */ #define IXGBE_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload enable */ +#define IXGBE_DCA_RXCTRL_DESC_RRO_EN (1 << 9) /* DCA Rx rd Desc Relax Order */ +#define IXGBE_DCA_RXCTRL_DESC_WRO_EN (1 << 13) /* DCA Rx wr Desc Relax Order */ +#define IXGBE_DCA_RXCTRL_DESC_HSRO_EN (1 << 15) /* DCA Rx Split Header RO */ #define IXGBE_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */ +#define IXGBE_DCA_TXCTRL_CPUID_MASK_82599 0xFF000000 /* Tx CPUID Mask */ +#define IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599 24 /* Tx CPUID Shift */ #define IXGBE_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */ #define IXGBE_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */ #define IXGBE_DCA_MAX_QUEUES_82598 16 /* DCA regs only on 16 queues */ @@ -530,6 +964,8 @@ #define IXGBE_ATLAS_PDN_TX_1G_QL_ALL 0xF0 #define IXGBE_ATLAS_PDN_TX_AN_QL_ALL 0xF0 +/* Omer bit masks */ +#define IXGBE_CORECTL_WRITE_CMD 0x00010000 /* Device Type definitions for new protocol MDIO commands */ #define IXGBE_MDIO_PMA_PMD_DEV_TYPE 0x1 @@ -557,6 +993,11 @@ #define IXGBE_MDIO_PHY_SPEED_ABILITY 0x4 /* Speed Ability Reg */ #define IXGBE_MDIO_PHY_SPEED_10G 0x0001 /* 10G capable */ #define IXGBE_MDIO_PHY_SPEED_1G 0x0010 /* 1G capable */ +#define IXGBE_MDIO_PHY_SPEED_100M 0x0020 /* 100M capable */ +#define IXGBE_MDIO_PHY_EXT_ABILITY 0xB /* Ext Ability Reg */ +#define IXGBE_MDIO_PHY_10GBASET_ABILITY 0x0004 /* 10GBaseT capable */ +#define IXGBE_MDIO_PHY_1000BASET_ABILITY 0x0020 /* 1000BaseT capable */ +#define IXGBE_MDIO_PHY_100BASETX_ABILITY 0x0080 /* 100BaseTX capable */ #define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR 0xC30A /* PHY_XS SDA/SCL Addr Reg */ #define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA 0xC30B /* PHY_XS SDA/SCL Data Reg */ @@ -576,6 +1017,8 @@ /* PHY IDs*/ #define TN1010_PHY_ID 0x00A19410 #define TNX_FW_REV 0xB +#define AQ1002_PHY_ID 0x03A1B420 +#define AQ_FW_REV 0x20 #define QT2022_PHY_ID 0x0043A400 #define ATH_PHY_ID 0x03429050 @@ -597,11 +1040,17 @@ /* General purpose Interrupt Enable */ #define IXGBE_SDP0_GPIEN 0x00000001 /* SDP0 */ #define IXGBE_SDP1_GPIEN 0x00000002 /* SDP1 */ +#define IXGBE_SDP2_GPIEN 0x00000004 /* SDP2 */ #define IXGBE_GPIE_MSIX_MODE 0x00000010 /* MSI-X mode */ #define IXGBE_GPIE_OCD 0x00000020 /* Other Clear Disable */ #define IXGBE_GPIE_EIMEN 0x00000040 /* Immediate Interrupt Enable */ #define IXGBE_GPIE_EIAME 0x40000000 #define IXGBE_GPIE_PBA_SUPPORT 0x80000000 +#define IXGBE_GPIE_RSC_DELAY_SHIFT 11 +#define IXGBE_GPIE_VTMODE_MASK 0x0000C000 /* VT Mode Mask */ +#define IXGBE_GPIE_VTMODE_16 0x00004000 /* 16 VFs 8 queues per VF */ +#define IXGBE_GPIE_VTMODE_32 0x00008000 /* 32 VFs 4 queues per VF */ +#define IXGBE_GPIE_VTMODE_64 0x0000C000 /* 64 VFs 2 queues per VF */ /* Transmit Flow Control status */ #define IXGBE_TFCS_TXOFF 0x00000001 @@ -642,6 +1091,23 @@ #define IXGBE_VMD_CTL_VMDQ_EN 0x00000001 #define IXGBE_VMD_CTL_VMDQ_FILTER 0x00000002 +/* VT_CTL bitmasks */ +#define IXGBE_VT_CTL_DIS_DEFPL 0x20000000 /* disable default pool */ +#define IXGBE_VT_CTL_REPLEN 0x40000000 /* replication enabled */ +#define IXGBE_VT_CTL_VT_ENABLE 0x00000001 /* Enable VT Mode */ +#define IXGBE_VT_CTL_POOL_SHIFT 7 +#define IXGBE_VT_CTL_POOL_MASK (0x3F << IXGBE_VT_CTL_POOL_SHIFT) + +/* VMOLR bitmasks */ +#define IXGBE_VMOLR_AUPE 0x01000000 /* accept untagged packets */ +#define IXGBE_VMOLR_ROMPE 0x02000000 /* accept packets in MTA tbl */ +#define IXGBE_VMOLR_ROPE 0x04000000 /* accept packets in UC tbl */ +#define IXGBE_VMOLR_BAM 0x08000000 /* accept broadcast packets */ +#define IXGBE_VMOLR_MPE 0x10000000 /* multicast promiscuous */ + +/* VFRE bitmask */ +#define IXGBE_VFRE_ENABLE_ALL 0xFFFFFFFF + /* RDHMPN and TDHMPN bitmasks */ #define IXGBE_RDHMPN_RDICADDR 0x007FF800 #define IXGBE_RDHMPN_RDICRDREQ 0x00800000 @@ -650,6 +1116,41 @@ #define IXGBE_TDHMPN_TDICRDREQ 0x00800000 #define IXGBE_TDHMPN_TDICADDR_SHIFT 11 +#define IXGBE_RDMAM_MEM_SEL_SHIFT 13 +#define IXGBE_RDMAM_DWORD_SHIFT 9 +#define IXGBE_RDMAM_DESC_COMP_FIFO 1 +#define IXGBE_RDMAM_DFC_CMD_FIFO 2 +#define IXGBE_RDMAM_RSC_HEADER_ADDR 3 +#define IXGBE_RDMAM_TCN_STATUS_RAM 4 +#define IXGBE_RDMAM_WB_COLL_FIFO 5 +#define IXGBE_RDMAM_QSC_CNT_RAM 6 +#define IXGBE_RDMAM_QSC_FCOE_RAM 7 +#define IXGBE_RDMAM_QSC_QUEUE_CNT 8 +#define IXGBE_RDMAM_QSC_QUEUE_RAM 0xA +#define IXGBE_RDMAM_QSC_RSC_RAM 0xB +#define IXGBE_RDMAM_DESC_COM_FIFO_RANGE 135 +#define IXGBE_RDMAM_DESC_COM_FIFO_COUNT 4 +#define IXGBE_RDMAM_DFC_CMD_FIFO_RANGE 48 +#define IXGBE_RDMAM_DFC_CMD_FIFO_COUNT 7 +#define IXGBE_RDMAM_RSC_HEADER_ADDR_RANGE 32 +#define IXGBE_RDMAM_RSC_HEADER_ADDR_COUNT 4 +#define IXGBE_RDMAM_TCN_STATUS_RAM_RANGE 256 +#define IXGBE_RDMAM_TCN_STATUS_RAM_COUNT 9 +#define IXGBE_RDMAM_WB_COLL_FIFO_RANGE 8 +#define IXGBE_RDMAM_WB_COLL_FIFO_COUNT 4 +#define IXGBE_RDMAM_QSC_CNT_RAM_RANGE 64 +#define IXGBE_RDMAM_QSC_CNT_RAM_COUNT 4 +#define IXGBE_RDMAM_QSC_FCOE_RAM_RANGE 512 +#define IXGBE_RDMAM_QSC_FCOE_RAM_COUNT 5 +#define IXGBE_RDMAM_QSC_QUEUE_CNT_RANGE 32 +#define IXGBE_RDMAM_QSC_QUEUE_CNT_COUNT 4 +#define IXGBE_RDMAM_QSC_QUEUE_RAM_RANGE 128 +#define IXGBE_RDMAM_QSC_QUEUE_RAM_COUNT 8 +#define IXGBE_RDMAM_QSC_RSC_RAM_RANGE 32 +#define IXGBE_RDMAM_QSC_RSC_RAM_COUNT 8 + +#define IXGBE_TXDESCIC_READY 0x80000000 + /* Receive Checksum Control */ #define IXGBE_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */ #define IXGBE_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */ @@ -670,15 +1171,25 @@ #define IXGBE_RMCS_TFCE_PRIORITY 0x00000010 /* Tx Priority FC ena */ #define IXGBE_RMCS_ARBDIS 0x00000040 /* Arbitration disable bit */ +/* FCCFG Bit Masks */ +#define IXGBE_FCCFG_TFCE_802_3X 0x00000008 /* Tx link FC enable */ +#define IXGBE_FCCFG_TFCE_PRIORITY 0x00000010 /* Tx priority FC enable */ /* Interrupt register bitmasks */ /* Extended Interrupt Cause Read */ #define IXGBE_EICR_RTX_QUEUE 0x0000FFFF /* RTx Queue Interrupt */ +#define IXGBE_EICR_FLOW_DIR 0x00010000 /* FDir Exception */ +#define IXGBE_EICR_RX_MISS 0x00020000 /* Packet Buffer Overrun */ +#define IXGBE_EICR_PCI 0x00040000 /* PCI Exception */ +#define IXGBE_EICR_MAILBOX 0x00080000 /* VF to PF Mailbox Interrupt */ #define IXGBE_EICR_LSC 0x00100000 /* Link Status Change */ +#define IXGBE_EICR_LINKSEC 0x00200000 /* PN Threshold */ #define IXGBE_EICR_MNG 0x00400000 /* Manageability Event Interrupt */ #define IXGBE_EICR_GPI_SDP0 0x01000000 /* Gen Purpose Interrupt on SDP0 */ #define IXGBE_EICR_GPI_SDP1 0x02000000 /* Gen Purpose Interrupt on SDP1 */ +#define IXGBE_EICR_GPI_SDP2 0x04000000 /* Gen Purpose Interrupt on SDP2 */ +#define IXGBE_EICR_ECC 0x10000000 /* ECC Error */ #define IXGBE_EICR_PBUR 0x10000000 /* Packet Buffer Handler Error */ #define IXGBE_EICR_DHER 0x20000000 /* Descriptor Handler Error */ #define IXGBE_EICR_TCP_TIMER 0x40000000 /* TCP Timer */ @@ -686,10 +1197,16 @@ /* Extended Interrupt Cause Set */ #define IXGBE_EICS_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */ +#define IXGBE_EICS_FLOW_DIR IXGBE_EICR_FLOW_DIR /* FDir Exception */ +#define IXGBE_EICS_RX_MISS IXGBE_EICR_RX_MISS /* Pkt Buffer Overrun */ +#define IXGBE_EICS_PCI IXGBE_EICR_PCI /* PCI Exception */ +#define IXGBE_EICS_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */ #define IXGBE_EICS_LSC IXGBE_EICR_LSC /* Link Status Change */ #define IXGBE_EICS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */ #define IXGBE_EICS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */ #define IXGBE_EICS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */ +#define IXGBE_EICS_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */ +#define IXGBE_EICS_ECC IXGBE_EICR_ECC /* ECC Error */ #define IXGBE_EICS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */ #define IXGBE_EICS_DHER IXGBE_EICR_DHER /* Desc Handler Error */ #define IXGBE_EICS_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */ @@ -697,10 +1214,16 @@ /* Extended Interrupt Mask Set */ #define IXGBE_EIMS_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */ +#define IXGBE_EIMS_FLOW_DIR IXGBE_EICR_FLOW_DIR /* FDir Exception */ +#define IXGBE_EIMS_RX_MISS IXGBE_EICR_RX_MISS /* Packet Buffer Overrun */ +#define IXGBE_EIMS_PCI IXGBE_EICR_PCI /* PCI Exception */ +#define IXGBE_EIMS_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */ #define IXGBE_EIMS_LSC IXGBE_EICR_LSC /* Link Status Change */ #define IXGBE_EIMS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */ #define IXGBE_EIMS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */ #define IXGBE_EIMS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */ +#define IXGBE_EIMS_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */ +#define IXGBE_EIMS_ECC IXGBE_EICR_ECC /* ECC Error */ #define IXGBE_EIMS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */ #define IXGBE_EIMS_DHER IXGBE_EICR_DHER /* Descr Handler Error */ #define IXGBE_EIMS_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */ @@ -708,10 +1231,16 @@ /* Extended Interrupt Mask Clear */ #define IXGBE_EIMC_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */ +#define IXGBE_EIMC_FLOW_DIR IXGBE_EICR_FLOW_DIR /* FDir Exception */ +#define IXGBE_EIMC_RX_MISS IXGBE_EICR_RX_MISS /* Packet Buffer Overrun */ +#define IXGBE_EIMC_PCI IXGBE_EICR_PCI /* PCI Exception */ +#define IXGBE_EIMC_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */ #define IXGBE_EIMC_LSC IXGBE_EICR_LSC /* Link Status Change */ #define IXGBE_EIMC_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */ #define IXGBE_EIMC_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */ #define IXGBE_EIMC_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */ +#define IXGBE_EIMC_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */ +#define IXGBE_EIMC_ECC IXGBE_EICR_ECC /* ECC Error */ #define IXGBE_EIMC_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */ #define IXGBE_EIMC_DHER IXGBE_EICR_DHER /* Desc Handler Err */ #define IXGBE_EIMC_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */ @@ -734,12 +1263,45 @@ #define IXGBE_IMIREXT_CTRL_SYN 0x00020000 /* Check SYN bit in header */ #define IXGBE_IMIREXT_CTRL_FIN 0x00040000 /* Check FIN bit in header */ #define IXGBE_IMIREXT_CTRL_BP 0x00080000 /* Bypass check of control bits */ +#define IXGBE_IMIR_SIZE_BP_82599 0x00001000 /* Packet size bypass */ +#define IXGBE_IMIR_CTRL_URG_82599 0x00002000 /* Check URG bit in header */ +#define IXGBE_IMIR_CTRL_ACK_82599 0x00004000 /* Check ACK bit in header */ +#define IXGBE_IMIR_CTRL_PSH_82599 0x00008000 /* Check PSH bit in header */ +#define IXGBE_IMIR_CTRL_RST_82599 0x00010000 /* Check RST bit in header */ +#define IXGBE_IMIR_CTRL_SYN_82599 0x00020000 /* Check SYN bit in header */ +#define IXGBE_IMIR_CTRL_FIN_82599 0x00040000 /* Check FIN bit in header */ +#define IXGBE_IMIR_CTRL_BP_82599 0x00080000 /* Bypass check of control bits */ +#define IXGBE_IMIR_LLI_EN_82599 0x00100000 /* Enables low latency Int */ +#define IXGBE_IMIR_RX_QUEUE_MASK_82599 0x0000007F /* Rx Queue Mask */ +#define IXGBE_IMIR_RX_QUEUE_SHIFT_82599 21 /* Rx Queue Shift */ +#define IXGBE_IMIRVP_PRIORITY_MASK 0x00000007 /* VLAN priority mask */ +#define IXGBE_IMIRVP_PRIORITY_EN 0x00000008 /* VLAN priority enable */ + +#define IXGBE_MAX_FTQF_FILTERS 128 +#define IXGBE_FTQF_PROTOCOL_MASK 0x00000003 +#define IXGBE_FTQF_PROTOCOL_TCP 0x00000000 +#define IXGBE_FTQF_PROTOCOL_UDP 0x00000001 +#define IXGBE_FTQF_PROTOCOL_SCTP 2 +#define IXGBE_FTQF_PRIORITY_MASK 0x00000007 +#define IXGBE_FTQF_PRIORITY_SHIFT 2 +#define IXGBE_FTQF_POOL_MASK 0x0000003F +#define IXGBE_FTQF_POOL_SHIFT 8 +#define IXGBE_FTQF_5TUPLE_MASK_MASK 0x0000001F +#define IXGBE_FTQF_5TUPLE_MASK_SHIFT 25 +#define IXGBE_FTQF_SOURCE_ADDR_MASK 0x1E +#define IXGBE_FTQF_DEST_ADDR_MASK 0x1D +#define IXGBE_FTQF_SOURCE_PORT_MASK 0x1B +#define IXGBE_FTQF_DEST_PORT_MASK 0x17 +#define IXGBE_FTQF_PROTOCOL_COMP_MASK 0x0F +#define IXGBE_FTQF_POOL_MASK_EN 0x40000000 +#define IXGBE_FTQF_QUEUE_ENABLE 0x80000000 /* Interrupt clear mask */ #define IXGBE_IRQ_CLEAR_MASK 0xFFFFFFFF /* Interrupt Vector Allocation Registers */ #define IXGBE_IVAR_REG_NUM 25 +#define IXGBE_IVAR_REG_NUM_82599 64 #define IXGBE_IVAR_TXRX_ENTRY 96 #define IXGBE_IVAR_RX_ENTRY 64 #define IXGBE_IVAR_RX_QUEUE(_i) (0 + (_i)) @@ -753,6 +1315,32 @@ #define IXGBE_IVAR_ALLOC_VAL 0x80 /* Interrupt Allocation valid */ +/* ETYPE Queue Filter/Select Bit Masks */ +#define IXGBE_MAX_ETQF_FILTERS 8 +#define IXGBE_ETQF_FCOE 0x08000000 /* bit 27 */ +#define IXGBE_ETQF_BCN 0x10000000 /* bit 28 */ +#define IXGBE_ETQF_1588 0x40000000 /* bit 30 */ +#define IXGBE_ETQF_FILTER_EN 0x80000000 /* bit 31 */ +#define IXGBE_ETQF_POOL_ENABLE (1 << 26) /* bit 26 */ + +#define IXGBE_ETQS_RX_QUEUE 0x007F0000 /* bits 22:16 */ +#define IXGBE_ETQS_RX_QUEUE_SHIFT 16 +#define IXGBE_ETQS_LLI 0x20000000 /* bit 29 */ +#define IXGBE_ETQS_QUEUE_EN 0x80000000 /* bit 31 */ + +/* + * ETQF filter list: one static filter per filter consumer. This is + * to avoid filter collisions later. Add new filters + * here!! + * + * Current filters: + * EAPOL 802.1x (0x888e): Filter 0 + * FCoE (0x8906): Filter 2 + * 1588 (0x88f7): Filter 3 + */ +#define IXGBE_ETQF_FILTER_EAPOL 0 +#define IXGBE_ETQF_FILTER_FCOE 2 +#define IXGBE_ETQF_FILTER_1588 3 /* VLAN Control Bit Masks */ #define IXGBE_VLNCTRL_VET 0x0000FFFF /* bits 0-15 */ #define IXGBE_VLNCTRL_CFI 0x10000000 /* bit 28 */ @@ -760,6 +1348,9 @@ #define IXGBE_VLNCTRL_VFE 0x40000000 /* bit 30 */ #define IXGBE_VLNCTRL_VME 0x80000000 /* bit 31 */ +/* VLAN pool filtering masks */ +#define IXGBE_VLVF_VIEN 0x80000000 /* filter is valid */ +#define IXGBE_VLVF_ENTRIES 64 #define IXGBE_ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.1q protocol */ @@ -772,7 +1363,8 @@ #define IXGBE_STATUS_LAN_ID_1 0x00000004 /* LAN ID 1 */ /* ESDP Bit Masks */ -#define IXGBE_ESDP_SDP1 0x00000001 +#define IXGBE_ESDP_SDP0 0x00000001 +#define IXGBE_ESDP_SDP1 0x00000002 #define IXGBE_ESDP_SDP4 0x00000010 /* SDP4 Data Value */ #define IXGBE_ESDP_SDP5 0x00000020 /* SDP5 Data Value */ #define IXGBE_ESDP_SDP6 0x00000040 /* SDP6 Data Value */ @@ -800,7 +1392,7 @@ #define IXGBE_LED_OFF 0xF /* AUTOC Bit Masks */ -#define IXGBE_AUTOC_KX4_KX_SUPP 0xC0000000 +#define IXGBE_AUTOC_KX4_KX_SUPP_MASK 0xC0000000 #define IXGBE_AUTOC_KX4_SUPP 0x80000000 #define IXGBE_AUTOC_KX_SUPP 0x40000000 #define IXGBE_AUTOC_PAUSE 0x30000000 @@ -809,9 +1401,17 @@ #define IXGBE_AUTOC_AN_RX_LOOSE 0x01000000 #define IXGBE_AUTOC_AN_RX_DRIFT 0x00800000 #define IXGBE_AUTOC_AN_RX_ALIGN 0x007C0000 +#define IXGBE_AUTOC_FECA 0x00040000 +#define IXGBE_AUTOC_FECR 0x00020000 +#define IXGBE_AUTOC_KR_SUPP 0x00010000 #define IXGBE_AUTOC_AN_RESTART 0x00001000 #define IXGBE_AUTOC_FLU 0x00000001 #define IXGBE_AUTOC_LMS_SHIFT 13 +#define IXGBE_AUTOC_LMS_10G_SERIAL (0x3 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_KX4_KX_KR (0x4 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_SGMII_1G_100M (0x5 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN (0x6 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII (0x7 << IXGBE_AUTOC_LMS_SHIFT) #define IXGBE_AUTOC_LMS_MASK (0x7 << IXGBE_AUTOC_LMS_SHIFT) #define IXGBE_AUTOC_LMS_1G_LINK_NO_AN (0x0 << IXGBE_AUTOC_LMS_SHIFT) #define IXGBE_AUTOC_LMS_10G_LINK_NO_AN (0x1 << IXGBE_AUTOC_LMS_SHIFT) @@ -820,15 +1420,24 @@ #define IXGBE_AUTOC_LMS_KX4_AN_1G_AN (0x6 << IXGBE_AUTOC_LMS_SHIFT) #define IXGBE_AUTOC_LMS_ATTACH_TYPE (0x7 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT) -#define IXGBE_AUTOC_1G_PMA_PMD 0x00000200 -#define IXGBE_AUTOC_10G_PMA_PMD 0x00000180 -#define IXGBE_AUTOC_10G_PMA_PMD_SHIFT 7 -#define IXGBE_AUTOC_1G_PMA_PMD_SHIFT 9 +#define IXGBE_AUTOC_1G_PMA_PMD_MASK 0x00000200 +#define IXGBE_AUTOC_1G_PMA_PMD_SHIFT 9 +#define IXGBE_AUTOC_10G_PMA_PMD_MASK 0x00000180 +#define IXGBE_AUTOC_10G_PMA_PMD_SHIFT 7 #define IXGBE_AUTOC_10G_XAUI (0x0 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT) #define IXGBE_AUTOC_10G_KX4 (0x1 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT) #define IXGBE_AUTOC_10G_CX4 (0x2 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT) #define IXGBE_AUTOC_1G_BX (0x0 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT) #define IXGBE_AUTOC_1G_KX (0x1 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT) +#define IXGBE_AUTOC_1G_SFI (0x0 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT) +#define IXGBE_AUTOC_1G_KX_BX (0x1 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT) + +#define IXGBE_AUTOC2_UPPER_MASK 0xFFFF0000 +#define IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK 0x00030000 +#define IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT 16 +#define IXGBE_AUTOC2_10G_KR (0x0 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT) +#define IXGBE_AUTOC2_10G_XFI (0x1 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT) +#define IXGBE_AUTOC2_10G_SFI (0x2 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT) /* LINKS Bit Masks */ #define IXGBE_LINKS_KX_AN_COMP 0x80000000 @@ -838,6 +1447,7 @@ #define IXGBE_LINKS_RX_MODE 0x06000000 #define IXGBE_LINKS_TX_MODE 0x01800000 #define IXGBE_LINKS_XGXS_EN 0x00400000 +#define IXGBE_LINKS_SGMII_EN 0x02000000 #define IXGBE_LINKS_PCS_1G_EN 0x00200000 #define IXGBE_LINKS_1G_AN_EN 0x00100000 #define IXGBE_LINKS_KX_AN_IDLE 0x00080000 @@ -847,11 +1457,13 @@ #define IXGBE_LINKS_TL_FAULT 0x00001000 #define IXGBE_LINKS_SIGNAL 0x00000F00 +#define IXGBE_LINKS_SPEED_82599 0x30000000 +#define IXGBE_LINKS_SPEED_10G_82599 0x30000000 +#define IXGBE_LINKS_SPEED_1G_82599 0x20000000 +#define IXGBE_LINKS_SPEED_100_82599 0x10000000 #define IXGBE_LINK_UP_TIME 90 /* 9.0 Seconds */ #define IXGBE_AUTO_NEG_TIME 45 /* 4.5 Seconds */ -#define FIBER_LINK_UP_LIMIT 50 - /* PCS1GLSTA Bit Masks */ #define IXGBE_PCS1GLSTA_LINK_OK 1 #define IXGBE_PCS1GLSTA_SYNK_OK 0x10 @@ -923,6 +1535,13 @@ #define IXGBE_FW_PTR 0x0F #define IXGBE_PBANUM0_PTR 0x15 #define IXGBE_PBANUM1_PTR 0x16 +#define IXGBE_SAN_MAC_ADDR_PTR 0x28 +#define IXGBE_DEVICE_CAPS 0x2C +#define IXGBE_PCIE_MSIX_82599_CAPS 0x72 +#define IXGBE_PCIE_MSIX_82598_CAPS 0x62 + +/* MSI-X capability fields masks */ +#define IXGBE_PCIE_MSIX_TBL_SZ_MASK 0x7FF /* Legacy EEPROM word offsets */ #define IXGBE_ISCSI_BOOT_CAPS 0x0033 @@ -961,6 +1580,11 @@ #define IXGBE_EERD_ATTEMPTS 100000 #endif +#define IXGBE_SAN_MAC_ADDR_PORT0_OFFSET 0x0 +#define IXGBE_SAN_MAC_ADDR_PORT1_OFFSET 0x3 +#define IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP 0x1 +#define IXGBE_DEVICE_CAPS_FCOE_OFFLOADS 0x2 + /* PCI Bus Info */ #define IXGBE_PCI_LINK_STATUS 0xB2 #define IXGBE_PCI_LINK_WIDTH 0x3F0 @@ -1025,6 +1649,7 @@ #define IXGBE_RXCTRL_RXEN 0x00000001 /* Enable Receiver */ #define IXGBE_RXCTRL_DMBYPS 0x00000002 /* Descriptor Monitor Bypass */ #define IXGBE_RXDCTL_ENABLE 0x02000000 /* Enable specific Rx Queue */ +#define IXGBE_RXDCTL_VME 0x40000000 /* VLAN mode enable */ #define IXGBE_FCTRL_SBP 0x00000002 /* Store Bad Packet */ #define IXGBE_FCTRL_MPE 0x00000100 /* Multicast Promiscuous Ena*/ @@ -1035,9 +1660,23 @@ /* Receive Priority Flow Control Enable */ #define IXGBE_FCTRL_RPFCE 0x00004000 #define IXGBE_FCTRL_RFCE 0x00008000 /* Receive Flow Control Ena */ +#define IXGBE_MFLCN_PMCF 0x00000001 /* Pass MAC Control Frames */ +#define IXGBE_MFLCN_DPF 0x00000002 /* Discard Pause Frame */ +#define IXGBE_MFLCN_RPFCE 0x00000004 /* Receive Priority FC Enable */ +#define IXGBE_MFLCN_RFCE 0x00000008 /* Receive FC Enable */ /* Multiple Receive Queue Control */ #define IXGBE_MRQC_RSSEN 0x00000001 /* RSS Enable */ +#define IXGBE_MRQC_MRQE_MASK 0xF /* Bits 3:0 */ +#define IXGBE_MRQC_RT8TCEN 0x00000002 /* 8 TC no RSS */ +#define IXGBE_MRQC_RT4TCEN 0x00000003 /* 4 TC no RSS */ +#define IXGBE_MRQC_RTRSS8TCEN 0x00000004 /* 8 TC w/ RSS */ +#define IXGBE_MRQC_RTRSS4TCEN 0x00000005 /* 4 TC w/ RSS */ +#define IXGBE_MRQC_VMDQEN 0x00000008 /* VMDq2 64 pools no RSS */ +#define IXGBE_MRQC_VMDQRSS32EN 0x0000000A /* VMDq2 32 pools w/ RSS */ +#define IXGBE_MRQC_VMDQRSS64EN 0x0000000B /* VMDq2 64 pools w/ RSS */ +#define IXGBE_MRQC_VMDQRT8TCEN 0x0000000C /* VMDq2/RT 16 pool 8 TC */ +#define IXGBE_MRQC_VMDQRT4TCEN 0x0000000D /* VMDq2/RT 32 pool 4 TC */ #define IXGBE_MRQC_RSS_FIELD_MASK 0xFFFF0000 #define IXGBE_MRQC_RSS_FIELD_IPV4_TCP 0x00010000 #define IXGBE_MRQC_RSS_FIELD_IPV4 0x00020000 @@ -1048,6 +1687,12 @@ #define IXGBE_MRQC_RSS_FIELD_IPV4_UDP 0x00400000 #define IXGBE_MRQC_RSS_FIELD_IPV6_UDP 0x00800000 #define IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP 0x01000000 +#define IXGBE_MRQC_L3L4TXSWEN 0x00008000 + +/* Queue Drop Enable */ +#define IXGBE_QDE_ENABLE 0x00000001 +#define IXGBE_QDE_IDX_MASK 0x00007F00 +#define IXGBE_QDE_IDX_SHIFT 8 #define IXGBE_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */ #define IXGBE_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */ @@ -1059,10 +1704,26 @@ #define IXGBE_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */ #define IXGBE_TXD_STAT_DD 0x00000001 /* Descriptor Done */ +#define IXGBE_RXDADV_IPSEC_STATUS_SECP 0x00020000 +#define IXGBE_RXDADV_IPSEC_ERROR_INVALID_PROTOCOL 0x08000000 +#define IXGBE_RXDADV_IPSEC_ERROR_INVALID_LENGTH 0x10000000 +#define IXGBE_RXDADV_IPSEC_ERROR_AUTH_FAILED 0x18000000 +#define IXGBE_RXDADV_IPSEC_ERROR_BIT_MASK 0x18000000 +/* Multiple Transmit Queue Command Register */ +#define IXGBE_MTQC_RT_ENA 0x1 /* DCB Enable */ +#define IXGBE_MTQC_VT_ENA 0x2 /* VMDQ2 Enable */ +#define IXGBE_MTQC_64Q_1PB 0x0 /* 64 queues 1 pack buffer */ +#define IXGBE_MTQC_32VF 0x8 /* 4 TX Queues per pool w/32VF's */ +#define IXGBE_MTQC_64VF 0x4 /* 2 TX Queues per pool w/64VF's */ +#define IXGBE_MTQC_8TC_8TQ 0xC /* 8 TC if RT_ENA or 8 TQ if VT_ENA */ + /* Receive Descriptor bit definitions */ #define IXGBE_RXD_STAT_DD 0x01 /* Descriptor Done */ #define IXGBE_RXD_STAT_EOP 0x02 /* End of Packet */ +#define IXGBE_RXD_STAT_FLM 0x04 /* FDir Match */ #define IXGBE_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */ +#define IXGBE_RXDADV_NEXTP_MASK 0x000FFFF0 /* Next Descriptor Index */ +#define IXGBE_RXDADV_NEXTP_SHIFT 0x00000004 #define IXGBE_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */ #define IXGBE_RXD_STAT_L4CS 0x20 /* L4 xsum calculated */ #define IXGBE_RXD_STAT_IPCS 0x40 /* IP xsum calculated */ @@ -1071,6 +1732,10 @@ #define IXGBE_RXD_STAT_VEXT 0x200 /* 1st VLAN found */ #define IXGBE_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */ #define IXGBE_RXD_STAT_DYNINT 0x800 /* Pkt caused INT via DYNINT */ +#define IXGBE_RXD_STAT_LLINT 0x800 /* Pkt caused Low Latency Interrupt */ +#define IXGBE_RXD_STAT_TS 0x10000 /* Time Stamp */ +#define IXGBE_RXD_STAT_SECP 0x20000 /* Security Processing */ +#define IXGBE_RXD_STAT_LB 0x40000 /* Loopback Status */ #define IXGBE_RXD_STAT_ACK 0x8000 /* ACK Packet indication */ #define IXGBE_RXD_ERR_CE 0x01 /* CRC Error */ #define IXGBE_RXD_ERR_LE 0x02 /* Length Error */ @@ -1079,6 +1744,13 @@ #define IXGBE_RXD_ERR_USE 0x20 /* Undersize Error */ #define IXGBE_RXD_ERR_TCPE 0x40 /* TCP/UDP Checksum Error */ #define IXGBE_RXD_ERR_IPE 0x80 /* IP Checksum Error */ +#define IXGBE_RXDADV_ERR_MASK 0xfff00000 /* RDESC.ERRORS mask */ +#define IXGBE_RXDADV_ERR_SHIFT 20 /* RDESC.ERRORS shift */ +#define IXGBE_RXDADV_ERR_FCEOFE 0x80000000 /* FCoEFe/IPE */ +#define IXGBE_RXDADV_ERR_FCERR 0x00700000 /* FCERR/FDIRERR */ +#define IXGBE_RXDADV_ERR_FDIR_LEN 0x00100000 /* FDIR Length error */ +#define IXGBE_RXDADV_ERR_FDIR_DROP 0x00200000 /* FDIR Drop error */ +#define IXGBE_RXDADV_ERR_FDIR_COLL 0x00400000 /* FDIR Collision error */ #define IXGBE_RXDADV_ERR_HBO 0x00800000 /*Header Buffer Overflow */ #define IXGBE_RXDADV_ERR_CE 0x01000000 /* CRC Error */ #define IXGBE_RXDADV_ERR_LE 0x02000000 /* Length Error */ @@ -1093,9 +1765,29 @@ #define IXGBE_RXD_CFI_MASK 0x1000 /* CFI is bit 12 */ #define IXGBE_RXD_CFI_SHIFT 12 +#define IXGBE_RXDADV_STAT_DD IXGBE_RXD_STAT_DD /* Done */ +#define IXGBE_RXDADV_STAT_EOP IXGBE_RXD_STAT_EOP /* End of Packet */ +#define IXGBE_RXDADV_STAT_FLM IXGBE_RXD_STAT_FLM /* FDir Match */ +#define IXGBE_RXDADV_STAT_VP IXGBE_RXD_STAT_VP /* IEEE VLAN Pkt */ +#define IXGBE_RXDADV_STAT_MASK 0x000fffff /* Stat/NEXTP: bit 0-19 */ +#define IXGBE_RXDADV_STAT_FCEOFS 0x00000040 /* FCoE EOF/SOF Stat */ +#define IXGBE_RXDADV_STAT_FCSTAT 0x00000030 /* FCoE Pkt Stat */ +#define IXGBE_RXDADV_STAT_FCSTAT_NOMTCH 0x00000000 /* 00: No Ctxt Match */ +#define IXGBE_RXDADV_STAT_FCSTAT_NODDP 0x00000010 /* 01: Ctxt w/o DDP */ +#define IXGBE_RXDADV_STAT_FCSTAT_FCPRSP 0x00000020 /* 10: Recv. FCP_RSP */ +#define IXGBE_RXDADV_STAT_FCSTAT_DDP 0x00000030 /* 11: Ctxt w/ DDP */ + +/* PSRTYPE bit definitions */ +#define IXGBE_PSRTYPE_TCPHDR 0x00000010 +#define IXGBE_PSRTYPE_UDPHDR 0x00000020 +#define IXGBE_PSRTYPE_IPV4HDR 0x00000100 +#define IXGBE_PSRTYPE_IPV6HDR 0x00000200 /* SRRCTL bit definitions */ #define IXGBE_SRRCTL_BSIZEPKT_SHIFT 10 /* so many KBs */ +#define IXGBE_SRRCTL_RDMTS_SHIFT 22 +#define IXGBE_SRRCTL_RDMTS_MASK 0x01C00000 +#define IXGBE_SRRCTL_DROP_EN 0x10000000 #define IXGBE_SRRCTL_BSIZEPKT_MASK 0x0000007F #define IXGBE_SRRCTL_BSIZEHDR_MASK 0x00003F00 #define IXGBE_SRRCTL_DESCTYPE_LEGACY 0x00000000 @@ -1110,7 +1802,10 @@ #define IXGBE_RXDADV_RSSTYPE_MASK 0x0000000F #define IXGBE_RXDADV_PKTTYPE_MASK 0x0000FFF0 +#define IXGBE_RXDADV_PKTTYPE_MASK_EX 0x0001FFF0 #define IXGBE_RXDADV_HDRBUFLEN_MASK 0x00007FE0 +#define IXGBE_RXDADV_RSCCNT_MASK 0x001E0000 +#define IXGBE_RXDADV_RSCCNT_SHIFT 17 #define IXGBE_RXDADV_HDRBUFLEN_SHIFT 5 #define IXGBE_RXDADV_SPLITHEADER_EN 0x00001000 #define IXGBE_RXDADV_SPH 0x8000 @@ -1137,6 +1832,20 @@ #define IXGBE_RXDADV_PKTTYPE_UDP 0x00000200 /* UDP hdr present */ #define IXGBE_RXDADV_PKTTYPE_SCTP 0x00000400 /* SCTP hdr present */ #define IXGBE_RXDADV_PKTTYPE_NFS 0x00000800 /* NFS hdr present */ +#define IXGBE_RXDADV_PKTTYPE_IPSEC_ESP 0x00001000 /* IPSec ESP */ +#define IXGBE_RXDADV_PKTTYPE_IPSEC_AH 0x00002000 /* IPSec AH */ +#define IXGBE_RXDADV_PKTTYPE_LINKSEC 0x00004000 /* LinkSec Encap */ +#define IXGBE_RXDADV_PKTTYPE_ETQF 0x00008000 /* PKTTYPE is ETQF index */ +#define IXGBE_RXDADV_PKTTYPE_ETQF_MASK 0x00000070 /* ETQF has 8 indices */ +#define IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT 4 /* Right-shift 4 bits */ + +/* Security Processing bit Indication */ +#define IXGBE_RXDADV_LNKSEC_STATUS_SECP 0x00020000 +#define IXGBE_RXDADV_LNKSEC_ERROR_NO_SA_MATCH 0x08000000 +#define IXGBE_RXDADV_LNKSEC_ERROR_REPLAY_ERROR 0x10000000 +#define IXGBE_RXDADV_LNKSEC_ERROR_BIT_MASK 0x18000000 +#define IXGBE_RXDADV_LNKSEC_ERROR_BAD_SIG 0x18000000 + /* Masks to determine if packets should be dropped due to frame errors */ #define IXGBE_RXD_ERR_FRAME_ERR_MASK ( \ IXGBE_RXD_ERR_CE | \ @@ -1166,10 +1875,14 @@ #define IXGBE_RX_DESC_SPECIAL_PRI_SHIFT 0x000D /* Priority in upper 3 of 16 */ #define IXGBE_TX_DESC_SPECIAL_PRI_SHIFT IXGBE_RX_DESC_SPECIAL_PRI_SHIFT -#ifndef __le16 /* Little Endian defines */ +#ifndef __le16 #define __le16 u16 +#endif +#ifndef __le32 #define __le32 u32 +#endif +#ifndef __le64 #define __le64 u64 #endif @@ -1180,6 +1893,77 @@ #define __be64 u64 #endif +enum ixgbe_fdir_pballoc_type { + IXGBE_FDIR_PBALLOC_64K = 0, + IXGBE_FDIR_PBALLOC_128K, + IXGBE_FDIR_PBALLOC_256K, +}; +#define IXGBE_FDIR_PBALLOC_SIZE_SHIFT 16 + +/* Flow Director register values */ +#define IXGBE_FDIRCTRL_PBALLOC_64K 0x00000001 +#define IXGBE_FDIRCTRL_PBALLOC_128K 0x00000002 +#define IXGBE_FDIRCTRL_PBALLOC_256K 0x00000003 +#define IXGBE_FDIRCTRL_INIT_DONE 0x00000008 +#define IXGBE_FDIRCTRL_PERFECT_MATCH 0x00000010 +#define IXGBE_FDIRCTRL_REPORT_STATUS 0x00000020 +#define IXGBE_FDIRCTRL_REPORT_STATUS_ALWAYS 0x00000080 +#define IXGBE_FDIRCTRL_DROP_Q_SHIFT 8 +#define IXGBE_FDIRCTRL_FLEX_SHIFT 16 +#define IXGBE_FDIRCTRL_SEARCHLIM 0x00800000 +#define IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT 24 +#define IXGBE_FDIRCTRL_FULL_THRESH_MASK 0xF0000000 +#define IXGBE_FDIRCTRL_FULL_THRESH_SHIFT 28 + +#define IXGBE_FDIRTCPM_DPORTM_SHIFT 16 +#define IXGBE_FDIRUDPM_DPORTM_SHIFT 16 +#define IXGBE_FDIRIP6M_DIPM_SHIFT 16 +#define IXGBE_FDIRM_VLANID 0x00000001 +#define IXGBE_FDIRM_VLANP 0x00000002 +#define IXGBE_FDIRM_POOL 0x00000004 +#define IXGBE_FDIRM_L3P 0x00000008 +#define IXGBE_FDIRM_L4P 0x00000010 +#define IXGBE_FDIRM_FLEX 0x00000020 +#define IXGBE_FDIRM_DIPv6 0x00000040 + +#define IXGBE_FDIRFREE_FREE_MASK 0xFFFF +#define IXGBE_FDIRFREE_FREE_SHIFT 0 +#define IXGBE_FDIRFREE_COLL_MASK 0x7FFF0000 +#define IXGBE_FDIRFREE_COLL_SHIFT 16 +#define IXGBE_FDIRLEN_MAXLEN_MASK 0x3F +#define IXGBE_FDIRLEN_MAXLEN_SHIFT 0 +#define IXGBE_FDIRLEN_MAXHASH_MASK 0x7FFF0000 +#define IXGBE_FDIRLEN_MAXHASH_SHIFT 16 +#define IXGBE_FDIRUSTAT_ADD_MASK 0xFFFF +#define IXGBE_FDIRUSTAT_ADD_SHIFT 0 +#define IXGBE_FDIRUSTAT_REMOVE_MASK 0xFFFF0000 +#define IXGBE_FDIRUSTAT_REMOVE_SHIFT 16 +#define IXGBE_FDIRFSTAT_FADD_MASK 0x00FF +#define IXGBE_FDIRFSTAT_FADD_SHIFT 0 +#define IXGBE_FDIRFSTAT_FREMOVE_MASK 0xFF00 +#define IXGBE_FDIRFSTAT_FREMOVE_SHIFT 8 +#define IXGBE_FDIRPORT_DESTINATION_SHIFT 16 +#define IXGBE_FDIRVLAN_FLEX_SHIFT 16 +#define IXGBE_FDIRHASH_BUCKET_VALID_SHIFT 15 +#define IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT 16 + +#define IXGBE_FDIRCMD_CMD_ADD_FLOW 0x00000001 +#define IXGBE_FDIRCMD_CMD_REMOVE_FLOW 0x00000002 +#define IXGBE_FDIRCMD_CMD_QUERY_REM_FILT 0x00000003 +#define IXGBE_FDIRCMD_CMD_QUERY_REM_HASH 0x00000007 +#define IXGBE_FDIRCMD_FILTER_UPDATE 0x00000008 +#define IXGBE_FDIRCMD_IPv6DMATCH 0x00000010 +#define IXGBE_FDIRCMD_L4TYPE_UDP 0x00000020 +#define IXGBE_FDIRCMD_L4TYPE_TCP 0x00000040 +#define IXGBE_FDIRCMD_L4TYPE_SCTP 0x00000060 +#define IXGBE_FDIRCMD_IPV6 0x00000080 +#define IXGBE_FDIRCMD_DROP 0x00000200 +#define IXGBE_FDIRCMD_INT 0x00000400 +#define IXGBE_FDIRCMD_LAST 0x00000800 +#define IXGBE_FDIRCMD_COLLISION 0x00001000 +#define IXGBE_FDIRCMD_QUEUE_EN 0x00008000 +#define IXGBE_FDIRCMD_RX_QUEUE_SHIFT 16 +#define IXGBE_FDIRCMD_VT_POOL_SHIFT 24 /* Transmit Descriptor - Legacy */ struct ixgbe_legacy_tx_desc { @@ -1267,6 +2051,9 @@ struct ixgbe_adv_tx_context_desc { /* Adv Transmit Descriptor Config Masks */ #define IXGBE_ADVTXD_DTALEN_MASK 0x0000FFFF /* Data buf length(bytes) */ +#define IXGBE_ADVTXD_MAC_LINKSEC 0x00040000 /* Insert LinkSec */ +#define IXGBE_ADVTXD_IPSEC_SA_INDEX_MASK 0x000003FF /* IPSec SA index */ +#define IXGBE_ADVTXD_IPSEC_ESP_LEN_MASK 0x000001FF /* IPSec ESP length */ #define IXGBE_ADVTXD_DTYP_MASK 0x00F00000 /* DTYP mask */ #define IXGBE_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Desc */ #define IXGBE_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */ @@ -1301,6 +2088,19 @@ struct ixgbe_adv_tx_context_desc { #define IXGBE_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */ #define IXGBE_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 Packet TYPE of SCTP */ #define IXGBE_ADVTXD_TUCMD_MKRREQ 0x00002000 /*Req requires Markers and CRC*/ +#define IXGBE_ADVTXD_POPTS_IPSEC 0x00000400 /* IPSec offload request */ +#define IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP 0x00002000 /* IPSec Type ESP */ +#define IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN 0x00004000/* ESP Encrypt Enable */ +#define IXGBE_ADVTXT_TUCMD_FCOE 0x00008000 /* FCoE Frame Type */ +#define IXGBE_ADVTXD_FCOEF_EOF_MASK (0x3 << 10) /* FC EOF index */ +#define IXGBE_ADVTXD_FCOEF_SOF ((1 << 2) << 10) /* FC SOF index */ +#define IXGBE_ADVTXD_FCOEF_PARINC ((1 << 3) << 10) /* Rel_Off in F_CTL */ +#define IXGBE_ADVTXD_FCOEF_ORIE ((1 << 4) << 10) /* Orientation: End */ +#define IXGBE_ADVTXD_FCOEF_ORIS ((1 << 5) << 10) /* Orientation: Start */ +#define IXGBE_ADVTXD_FCOEF_EOF_N (0x0 << 10) /* 00: EOFn */ +#define IXGBE_ADVTXD_FCOEF_EOF_T (0x1 << 10) /* 01: EOFt */ +#define IXGBE_ADVTXD_FCOEF_EOF_NI (0x2 << 10) /* 10: EOFni */ +#define IXGBE_ADVTXD_FCOEF_EOF_A (0x3 << 10) /* 11: EOFa */ #define IXGBE_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */ #define IXGBE_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */ @@ -1314,13 +2114,17 @@ typedef u32 ixgbe_link_speed; #define IXGBE_LINK_SPEED_10GB_FULL 0x0080 #define IXGBE_LINK_SPEED_82598_AUTONEG (IXGBE_LINK_SPEED_1GB_FULL | \ IXGBE_LINK_SPEED_10GB_FULL) +#define IXGBE_LINK_SPEED_82599_AUTONEG (IXGBE_LINK_SPEED_100_FULL | \ + IXGBE_LINK_SPEED_1GB_FULL | \ + IXGBE_LINK_SPEED_10GB_FULL) + /* Physical layer type */ typedef u32 ixgbe_physical_layer; #define IXGBE_PHYSICAL_LAYER_UNKNOWN 0 #define IXGBE_PHYSICAL_LAYER_10GBASE_T 0x0001 #define IXGBE_PHYSICAL_LAYER_1000BASE_T 0x0002 -#define IXGBE_PHYSICAL_LAYER_100BASE_T 0x0004 +#define IXGBE_PHYSICAL_LAYER_100BASE_TX 0x0004 #define IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU 0x0008 #define IXGBE_PHYSICAL_LAYER_10GBASE_LR 0x0010 #define IXGBE_PHYSICAL_LAYER_10GBASE_LRM 0x0020 @@ -1329,7 +2133,46 @@ typedef u32 ixgbe_physical_layer; #define IXGBE_PHYSICAL_LAYER_10GBASE_CX4 0x0100 #define IXGBE_PHYSICAL_LAYER_1000BASE_KX 0x0200 #define IXGBE_PHYSICAL_LAYER_1000BASE_BX 0x0400 +#define IXGBE_PHYSICAL_LAYER_10GBASE_KR 0x0800 +/* Software ATR hash keys */ +#define IXGBE_ATR_BUCKET_HASH_KEY 0xE214AD3D +#define IXGBE_ATR_SIGNATURE_HASH_KEY 0x14364D17 + +/* Software ATR input stream offsets and masks */ +#define IXGBE_ATR_VLAN_OFFSET 0 +#define IXGBE_ATR_SRC_IPV6_OFFSET 2 +#define IXGBE_ATR_SRC_IPV4_OFFSET 14 +#define IXGBE_ATR_DST_IPV6_OFFSET 18 +#define IXGBE_ATR_DST_IPV4_OFFSET 30 +#define IXGBE_ATR_SRC_PORT_OFFSET 34 +#define IXGBE_ATR_DST_PORT_OFFSET 36 +#define IXGBE_ATR_FLEX_BYTE_OFFSET 38 +#define IXGBE_ATR_VM_POOL_OFFSET 40 +#define IXGBE_ATR_L4TYPE_OFFSET 41 + +#define IXGBE_ATR_L4TYPE_MASK 0x3 +#define IXGBE_ATR_L4TYPE_IPV6_MASK 0x4 +#define IXGBE_ATR_L4TYPE_UDP 0x1 +#define IXGBE_ATR_L4TYPE_TCP 0x2 +#define IXGBE_ATR_L4TYPE_SCTP 0x3 +#define IXGBE_ATR_HASH_MASK 0x7fff + +/* Flow Director ATR input struct. */ +struct ixgbe_atr_input { + /* Byte layout in order, all values with MSB first: + * + * vlan_id - 2 bytes + * src_ip - 16 bytes + * dst_ip - 16 bytes + * src_port - 2 bytes + * dst_port - 2 bytes + * flex_bytes - 2 bytes + * vm_pool - 1 byte + * l4type - 1 byte + */ + u8 byte_stream[42]; +}; enum ixgbe_eeprom_type { ixgbe_eeprom_uninitialized = 0, @@ -1340,12 +2183,16 @@ enum ixgbe_eeprom_type { enum ixgbe_mac_type { ixgbe_mac_unknown = 0, ixgbe_mac_82598EB, + ixgbe_mac_82599EB, ixgbe_num_macs }; enum ixgbe_phy_type { ixgbe_phy_unknown = 0, + ixgbe_phy_none, ixgbe_phy_tn, + ixgbe_phy_aq, + ixgbe_phy_cu_unknown, ixgbe_phy_qt, ixgbe_phy_xaui, ixgbe_phy_nl, @@ -1354,6 +2201,8 @@ enum ixgbe_phy_type { ixgbe_phy_sfp_avago, ixgbe_phy_sfp_ftl, ixgbe_phy_sfp_unknown, + ixgbe_phy_sfp_intel, + ixgbe_phy_sfp_unsupported, /*Enforce bit set with unsupported module*/ ixgbe_phy_generic }; @@ -1365,11 +2214,19 @@ enum ixgbe_phy_type { * 0 SFP_DA_CU * 1 SFP_SR * 2 SFP_LR + * 3 SFP_DA_CU_CORE0 - 82599-specific + * 4 SFP_DA_CU_CORE1 - 82599-specific + * 5 SFP_SR/LR_CORE0 - 82599-specific + * 6 SFP_SR/LR_CORE1 - 82599-specific */ enum ixgbe_sfp_type { ixgbe_sfp_type_da_cu = 0, ixgbe_sfp_type_sr = 1, ixgbe_sfp_type_lr = 2, + ixgbe_sfp_type_da_cu_core0 = 3, + ixgbe_sfp_type_da_cu_core1 = 4, + ixgbe_sfp_type_srlr_core0 = 5, + ixgbe_sfp_type_srlr_core1 = 6, ixgbe_sfp_type_not_present = 0xFFFE, ixgbe_sfp_type_unknown = 0xFFFF }; @@ -1428,7 +2285,6 @@ enum ixgbe_bus_width { struct ixgbe_addr_filter_info { u32 num_mc_addrs; u32 rar_used_count; - u32 mc_addr_in_rar_count; u32 mta_in_use; u32 overflow_promisc; bool user_set_promisc; @@ -1441,6 +2297,7 @@ struct ixgbe_bus_info { enum ixgbe_bus_type type; u16 func; + u16 lan_id; }; /* Flow control parameters */ @@ -1450,6 +2307,8 @@ struct ixgbe_fc_info { u16 pause_time; /* Flow Control Pause timer */ bool send_xon; /* Flow control send XON */ bool strict_ieee; /* Strict IEEE mode */ + bool disable_fc_autoneg; /* Do not autonegotiate FC */ + bool fc_was_autonegged; /* Is current_mode the result of autonegging? */ enum ixgbe_fc_mode current_mode; /* FC mode in effect */ enum ixgbe_fc_mode requested_mode; /* FC mode requested by caller */ }; @@ -1511,6 +2370,21 @@ struct ixgbe_hw_stats { u64 qptc[16]; u64 qbrc[16]; u64 qbtc[16]; + u64 qprdc[16]; + u64 pxon2offc[8]; + u64 fdirustat_add; + u64 fdirustat_remove; + u64 fdirfstat_fadd; + u64 fdirfstat_fremove; + u64 fdirmatch; + u64 fdirmiss; + u64 fccrc; + u64 fclast; + u64 fcoerpdc; + u64 fcoeprc; + u64 fcoeptc; + u64 fcoedwrc; + u64 fcoedwtc; }; /* forward declaration */ @@ -1537,11 +2411,16 @@ struct ixgbe_mac_operations { enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *); u32 (*get_supported_physical_layer)(struct ixgbe_hw *); s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *); + s32 (*get_san_mac_addr)(struct ixgbe_hw *, u8 *); + s32 (*set_san_mac_addr)(struct ixgbe_hw *, u8 *); + s32 (*get_device_caps)(struct ixgbe_hw *, u16 *); s32 (*stop_adapter)(struct ixgbe_hw *); s32 (*get_bus_info)(struct ixgbe_hw *); void (*set_lan_id)(struct ixgbe_hw *); s32 (*read_analog_reg8)(struct ixgbe_hw*, u32, u8*); s32 (*write_analog_reg8)(struct ixgbe_hw*, u32, u8); + s32 (*setup_sfp)(struct ixgbe_hw *); + s32 (*enable_rx_dma)(struct ixgbe_hw *, u32); /* Link */ s32 (*setup_link)(struct ixgbe_hw *); @@ -1560,6 +2439,7 @@ struct ixgbe_mac_operations { /* RAR, Multicast, VLAN */ s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32, u32); s32 (*clear_rar)(struct ixgbe_hw *, u32); + s32 (*insert_mac_addr)(struct ixgbe_hw *, u8 *, u32); s32 (*set_vmdq)(struct ixgbe_hw *, u32, u32); s32 (*clear_vmdq)(struct ixgbe_hw *, u32, u32); s32 (*init_rx_addrs)(struct ixgbe_hw *); @@ -1574,12 +2454,13 @@ struct ixgbe_mac_operations { s32 (*init_uta_tables)(struct ixgbe_hw *); /* Flow Control */ - s32 (*setup_fc)(struct ixgbe_hw *, s32); + s32 (*fc_enable)(struct ixgbe_hw *, s32); }; struct ixgbe_phy_operations { s32 (*identify)(struct ixgbe_hw *); s32 (*identify_sfp)(struct ixgbe_hw *); + s32 (*init)(struct ixgbe_hw *); s32 (*reset)(struct ixgbe_hw *); s32 (*read_reg)(struct ixgbe_hw *, u32, u32, u16 *); s32 (*write_reg)(struct ixgbe_hw *, u32, u32, u16); @@ -1592,12 +2473,13 @@ struct ixgbe_phy_operations { s32 (*write_i2c_byte)(struct ixgbe_hw *, u8, u8, u8); s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *); s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8); + void (*i2c_bus_clear)(struct ixgbe_hw *); }; struct ixgbe_eeprom_info { struct ixgbe_eeprom_operations ops; enum ixgbe_eeprom_type type; - u32 semaphore_delay; + u32 semaphore_delay; u16 word_size; u16 address_bits; }; @@ -1607,16 +2489,19 @@ struct ixgbe_mac_info { enum ixgbe_mac_type type; u8 addr[IXGBE_ETH_LENGTH_OF_ADDRESS]; u8 perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS]; + u8 san_addr[IXGBE_ETH_LENGTH_OF_ADDRESS]; s32 mc_filter_type; u32 mcft_size; u32 vft_size; u32 num_rar_entries; + u32 rar_highwater; u32 max_tx_queues; u32 max_rx_queues; - u32 link_attach_type; - u32 link_mode_select; - u32 link_kx4_kx_supp; - bool link_settings_loaded; + u32 max_msix_vectors; + bool msix_vectors_from_pcie; + u32 orig_autoc; + u32 orig_autoc2; + bool orig_link_settings_stored; bool autoneg; bool autoneg_succeeded; }; @@ -1627,6 +2512,7 @@ struct ixgbe_phy_info { u32 addr; u32 id; enum ixgbe_sfp_type sfp_type; + bool sfp_setup_needed; u32 revision; enum ixgbe_media_type media_type; bool reset_disable; @@ -1677,6 +2563,8 @@ struct ixgbe_hw { #define IXGBE_ERR_I2C -18 #define IXGBE_ERR_SFP_NOT_SUPPORTED -19 #define IXGBE_ERR_SFP_NOT_PRESENT -20 +#define IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT -21 +#define IXGBE_ERR_NO_SAN_ADDR_PTR -22 #define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF #define UNREFERENCED_PARAMETER(_p)