16621Sbt150084 /*
26621Sbt150084 * CDDL HEADER START
36621Sbt150084 *
46621Sbt150084 * The contents of this file are subject to the terms of the
56621Sbt150084 * Common Development and Distribution License (the "License").
66621Sbt150084 * You may not use this file except in compliance with the License.
76621Sbt150084 *
86621Sbt150084 * You can obtain a copy of the license at:
96621Sbt150084 * http://www.opensolaris.org/os/licensing.
106621Sbt150084 * See the License for the specific language governing permissions
116621Sbt150084 * and limitations under the License.
126621Sbt150084 *
136621Sbt150084 * When using or redistributing this file, you may do so under the
146621Sbt150084 * License only. No other modification of this header is permitted.
156621Sbt150084 *
166621Sbt150084 * If applicable, add the following below this CDDL HEADER, with the
176621Sbt150084 * fields enclosed by brackets "[]" replaced with your own identifying
186621Sbt150084 * information: Portions Copyright [yyyy] [name of copyright owner]
196621Sbt150084 *
206621Sbt150084 * CDDL HEADER END
216621Sbt150084 */
226621Sbt150084
236621Sbt150084 /*
24*13006SChenlu.Chen@Sun.COM * Copyright(c) 2007-2010 Intel Corporation. All rights reserved.
256621Sbt150084 */
266621Sbt150084
27*13006SChenlu.Chen@Sun.COM /*
28*13006SChenlu.Chen@Sun.COM * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
29*13006SChenlu.Chen@Sun.COM */
30*13006SChenlu.Chen@Sun.COM
31*13006SChenlu.Chen@Sun.COM /* IntelVersion: 1.167 scm_061610_003709 */
326621Sbt150084
336621Sbt150084 #include "ixgbe_type.h"
346621Sbt150084 #include "ixgbe_api.h"
356621Sbt150084 #include "ixgbe_common.h"
366621Sbt150084 #include "ixgbe_phy.h"
376621Sbt150084
3810305SPaul.Guo@Sun.COM u32 ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw);
396621Sbt150084 s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw);
408490SPaul.Guo@Sun.COM static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
416621Sbt150084 ixgbe_link_speed *speed, bool *autoneg);
428490SPaul.Guo@Sun.COM static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw);
439353SSamuel.Tu@Sun.COM s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num);
4410998SChenlu.Chen@Sun.COM static s32 ixgbe_start_mac_link_82598(struct ixgbe_hw *hw,
4510998SChenlu.Chen@Sun.COM bool autoneg_wait_to_complete);
468490SPaul.Guo@Sun.COM static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
478490SPaul.Guo@Sun.COM ixgbe_link_speed *speed, bool *link_up, bool link_up_wait_to_complete);
4810998SChenlu.Chen@Sun.COM static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
496621Sbt150084 ixgbe_link_speed speed, bool autoneg,
506621Sbt150084 bool autoneg_wait_to_complete);
5110998SChenlu.Chen@Sun.COM static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
526621Sbt150084 ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete);
538490SPaul.Guo@Sun.COM static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw);
5410998SChenlu.Chen@Sun.COM s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw);
5512003SPaul.Guo@Sun.COM void ixgbe_enable_relaxed_ordering_82598(struct ixgbe_hw *hw);
566621Sbt150084 s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
578490SPaul.Guo@Sun.COM static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
588490SPaul.Guo@Sun.COM s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan,
598490SPaul.Guo@Sun.COM u32 vind, bool vlan_on);
608490SPaul.Guo@Sun.COM static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw);
618490SPaul.Guo@Sun.COM s32 ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val);
628490SPaul.Guo@Sun.COM s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val);
638490SPaul.Guo@Sun.COM s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
648490SPaul.Guo@Sun.COM u8 *eeprom_data);
659353SSamuel.Tu@Sun.COM u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw);
669353SSamuel.Tu@Sun.COM s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw);
6710305SPaul.Guo@Sun.COM void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw);
6810998SChenlu.Chen@Sun.COM void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw);
6912003SPaul.Guo@Sun.COM static s32 ixgbe_validate_link_ready(struct ixgbe_hw *hw);
7010998SChenlu.Chen@Sun.COM
7110998SChenlu.Chen@Sun.COM /*
7210998SChenlu.Chen@Sun.COM * ixgbe_set_pcie_completion_timeout - set pci-e completion timeout
7310998SChenlu.Chen@Sun.COM * @hw: pointer to the HW structure
7410998SChenlu.Chen@Sun.COM *
7510998SChenlu.Chen@Sun.COM * The defaults for 82598 should be in the range of 50us to 50ms,
7610998SChenlu.Chen@Sun.COM * however the hardware default for these parts is 500us to 1ms which is less
7710998SChenlu.Chen@Sun.COM * than the 10ms recommended by the pci-e spec. To address this we need to
7810998SChenlu.Chen@Sun.COM * increase the value to either 10ms to 250ms for capability version 1 config,
7910998SChenlu.Chen@Sun.COM * or 16ms to 55ms for version 2.
8010998SChenlu.Chen@Sun.COM */
8110998SChenlu.Chen@Sun.COM void
ixgbe_set_pcie_completion_timeout(struct ixgbe_hw * hw)8210998SChenlu.Chen@Sun.COM ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw)
8310998SChenlu.Chen@Sun.COM {
8410998SChenlu.Chen@Sun.COM u32 gcr = IXGBE_READ_REG(hw, IXGBE_GCR);
8510998SChenlu.Chen@Sun.COM u16 pcie_devctl2;
8610998SChenlu.Chen@Sun.COM
8710998SChenlu.Chen@Sun.COM /* only take action if timeout value is defaulted to 0 */
8810998SChenlu.Chen@Sun.COM if (gcr & IXGBE_GCR_CMPL_TMOUT_MASK)
8910998SChenlu.Chen@Sun.COM goto out;
9010998SChenlu.Chen@Sun.COM
9110998SChenlu.Chen@Sun.COM /*
9210998SChenlu.Chen@Sun.COM * if capababilities version is type 1 we can write the
9310998SChenlu.Chen@Sun.COM * timeout of 10ms to 250ms through the GCR register
9410998SChenlu.Chen@Sun.COM */
9510998SChenlu.Chen@Sun.COM if (!(gcr & IXGBE_GCR_CAP_VER2)) {
9610998SChenlu.Chen@Sun.COM gcr |= IXGBE_GCR_CMPL_TMOUT_10ms;
9710998SChenlu.Chen@Sun.COM goto out;
9810998SChenlu.Chen@Sun.COM }
9910998SChenlu.Chen@Sun.COM
10010998SChenlu.Chen@Sun.COM /*
10110998SChenlu.Chen@Sun.COM * for version 2 capabilities we need to write the config space
10210998SChenlu.Chen@Sun.COM * directly in order to set the completion timeout value for
10310998SChenlu.Chen@Sun.COM * 16ms to 55ms
10410998SChenlu.Chen@Sun.COM */
10510998SChenlu.Chen@Sun.COM pcie_devctl2 = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2);
10610998SChenlu.Chen@Sun.COM pcie_devctl2 |= IXGBE_PCI_DEVICE_CONTROL2_16ms;
10710998SChenlu.Chen@Sun.COM IXGBE_WRITE_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2, pcie_devctl2);
10810998SChenlu.Chen@Sun.COM out:
10910998SChenlu.Chen@Sun.COM /* disable completion timeout resend */
11010998SChenlu.Chen@Sun.COM gcr &= ~IXGBE_GCR_CMPL_TMOUT_RESEND;
11110998SChenlu.Chen@Sun.COM IXGBE_WRITE_REG(hw, IXGBE_GCR, gcr);
11210998SChenlu.Chen@Sun.COM }
1139353SSamuel.Tu@Sun.COM
1149353SSamuel.Tu@Sun.COM /*
1159353SSamuel.Tu@Sun.COM * ixgbe_get_pcie_msix_count_82598 - Gets MSI-X vector count
1169353SSamuel.Tu@Sun.COM * @hw: pointer to hardware structure
1179353SSamuel.Tu@Sun.COM *
1189353SSamuel.Tu@Sun.COM * Read PCIe configuration space, and get the MSI-X vector count from
1199353SSamuel.Tu@Sun.COM * the capabilities table.
1209353SSamuel.Tu@Sun.COM */
1219353SSamuel.Tu@Sun.COM u32
ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw * hw)1229353SSamuel.Tu@Sun.COM ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw)
1239353SSamuel.Tu@Sun.COM {
1249353SSamuel.Tu@Sun.COM u32 msix_count = 18;
1259353SSamuel.Tu@Sun.COM
12610998SChenlu.Chen@Sun.COM DEBUGFUNC("ixgbe_get_pcie_msix_count_82598");
12710998SChenlu.Chen@Sun.COM
1289353SSamuel.Tu@Sun.COM if (hw->mac.msix_vectors_from_pcie) {
1299353SSamuel.Tu@Sun.COM msix_count = IXGBE_READ_PCIE_WORD(hw,
1309353SSamuel.Tu@Sun.COM IXGBE_PCIE_MSIX_82598_CAPS);
1319353SSamuel.Tu@Sun.COM msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK;
1329353SSamuel.Tu@Sun.COM
1339353SSamuel.Tu@Sun.COM /*
1349353SSamuel.Tu@Sun.COM * MSI-X count is zero-based in HW, so increment to give
1359353SSamuel.Tu@Sun.COM * proper value
1369353SSamuel.Tu@Sun.COM */
1379353SSamuel.Tu@Sun.COM msix_count++;
1389353SSamuel.Tu@Sun.COM }
1399353SSamuel.Tu@Sun.COM return (msix_count);
1409353SSamuel.Tu@Sun.COM }
1416621Sbt150084
1426621Sbt150084 /*
1436621Sbt150084 * ixgbe_init_ops_82598 - Inits func ptrs and MAC type
1446621Sbt150084 * @hw: pointer to hardware structure
1456621Sbt150084 *
1466621Sbt150084 * Initialize the function pointers and assign the MAC type for 82598.
1476621Sbt150084 * Does not touch the hardware.
1486621Sbt150084 */
1496621Sbt150084 s32
ixgbe_init_ops_82598(struct ixgbe_hw * hw)1506621Sbt150084 ixgbe_init_ops_82598(struct ixgbe_hw *hw)
1516621Sbt150084 {
1526621Sbt150084 struct ixgbe_mac_info *mac = &hw->mac;
1538490SPaul.Guo@Sun.COM struct ixgbe_phy_info *phy = &hw->phy;
1549353SSamuel.Tu@Sun.COM s32 ret_val;
1556621Sbt150084
15610998SChenlu.Chen@Sun.COM DEBUGFUNC("ixgbe_init_ops_82598");
15710998SChenlu.Chen@Sun.COM
1589353SSamuel.Tu@Sun.COM ret_val = ixgbe_init_phy_ops_generic(hw);
1599353SSamuel.Tu@Sun.COM ret_val = ixgbe_init_ops_generic(hw);
1609353SSamuel.Tu@Sun.COM
1619353SSamuel.Tu@Sun.COM /* PHY */
1629353SSamuel.Tu@Sun.COM phy->ops.init = &ixgbe_init_phy_ops_82598;
1636621Sbt150084
1646621Sbt150084 /* MAC */
16510998SChenlu.Chen@Sun.COM mac->ops.start_hw = &ixgbe_start_hw_82598;
16612003SPaul.Guo@Sun.COM mac->ops.enable_relaxed_ordering = &ixgbe_enable_relaxed_ordering_82598;
1676621Sbt150084 mac->ops.reset_hw = &ixgbe_reset_hw_82598;
1686621Sbt150084 mac->ops.get_media_type = &ixgbe_get_media_type_82598;
1698490SPaul.Guo@Sun.COM mac->ops.get_supported_physical_layer =
1708490SPaul.Guo@Sun.COM &ixgbe_get_supported_physical_layer_82598;
1718490SPaul.Guo@Sun.COM mac->ops.read_analog_reg8 = &ixgbe_read_analog_reg8_82598;
1728490SPaul.Guo@Sun.COM mac->ops.write_analog_reg8 = &ixgbe_write_analog_reg8_82598;
17310305SPaul.Guo@Sun.COM mac->ops.set_lan_id = &ixgbe_set_lan_id_multi_port_pcie_82598;
1746621Sbt150084
1756621Sbt150084 /* RAR, Multicast, VLAN */
1766621Sbt150084 mac->ops.set_vmdq = &ixgbe_set_vmdq_82598;
1778490SPaul.Guo@Sun.COM mac->ops.clear_vmdq = &ixgbe_clear_vmdq_82598;
1788490SPaul.Guo@Sun.COM mac->ops.set_vfta = &ixgbe_set_vfta_82598;
1798490SPaul.Guo@Sun.COM mac->ops.clear_vfta = &ixgbe_clear_vfta_82598;
1806621Sbt150084
1816621Sbt150084 /* Flow Control */
1829353SSamuel.Tu@Sun.COM mac->ops.fc_enable = &ixgbe_fc_enable_82598;
1836621Sbt150084
1846621Sbt150084 mac->mcft_size = 128;
1856621Sbt150084 mac->vft_size = 128;
1866621Sbt150084 mac->num_rar_entries = 16;
1876621Sbt150084 mac->max_tx_queues = 32;
1886621Sbt150084 mac->max_rx_queues = 64;
1899353SSamuel.Tu@Sun.COM mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82598(hw);
1906621Sbt150084
1918490SPaul.Guo@Sun.COM /* SFP+ Module */
1928490SPaul.Guo@Sun.COM phy->ops.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_82598;
1938490SPaul.Guo@Sun.COM
1949353SSamuel.Tu@Sun.COM /* Link */
1959353SSamuel.Tu@Sun.COM mac->ops.check_link = &ixgbe_check_mac_link_82598;
1969353SSamuel.Tu@Sun.COM mac->ops.setup_link = &ixgbe_setup_mac_link_82598;
197*13006SChenlu.Chen@Sun.COM mac->ops.flap_tx_laser = NULL;
1989353SSamuel.Tu@Sun.COM mac->ops.get_link_capabilities =
1999353SSamuel.Tu@Sun.COM &ixgbe_get_link_capabilities_82598;
2009353SSamuel.Tu@Sun.COM
2019353SSamuel.Tu@Sun.COM return (ret_val);
2029353SSamuel.Tu@Sun.COM }
2039353SSamuel.Tu@Sun.COM
2049353SSamuel.Tu@Sun.COM /*
2059353SSamuel.Tu@Sun.COM * ixgbe_init_phy_ops_82598 - PHY/SFP specific init
2069353SSamuel.Tu@Sun.COM * @hw: pointer to hardware structure
2079353SSamuel.Tu@Sun.COM *
2089353SSamuel.Tu@Sun.COM * Initialize any function pointers that were not able to be
2099353SSamuel.Tu@Sun.COM * set during init_shared_code because the PHY/SFP type was
2109353SSamuel.Tu@Sun.COM * not known. Perform the SFP init if necessary.
2119353SSamuel.Tu@Sun.COM *
2129353SSamuel.Tu@Sun.COM */
2139353SSamuel.Tu@Sun.COM s32
ixgbe_init_phy_ops_82598(struct ixgbe_hw * hw)2149353SSamuel.Tu@Sun.COM ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw)
2159353SSamuel.Tu@Sun.COM {
2169353SSamuel.Tu@Sun.COM struct ixgbe_mac_info *mac = &hw->mac;
2179353SSamuel.Tu@Sun.COM struct ixgbe_phy_info *phy = &hw->phy;
2189353SSamuel.Tu@Sun.COM s32 ret_val = IXGBE_SUCCESS;
2199353SSamuel.Tu@Sun.COM u16 list_offset, data_offset;
2209353SSamuel.Tu@Sun.COM
22110998SChenlu.Chen@Sun.COM DEBUGFUNC("ixgbe_init_phy_ops_82598");
22210998SChenlu.Chen@Sun.COM
2239353SSamuel.Tu@Sun.COM /* Identify the PHY */
2249353SSamuel.Tu@Sun.COM phy->ops.identify(hw);
2259353SSamuel.Tu@Sun.COM
2269353SSamuel.Tu@Sun.COM /* Overwrite the link function pointers if copper PHY */
2279353SSamuel.Tu@Sun.COM if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
2289353SSamuel.Tu@Sun.COM mac->ops.setup_link = &ixgbe_setup_copper_link_82598;
2299353SSamuel.Tu@Sun.COM mac->ops.get_link_capabilities =
2309353SSamuel.Tu@Sun.COM &ixgbe_get_copper_link_capabilities_generic;
2319353SSamuel.Tu@Sun.COM }
2329353SSamuel.Tu@Sun.COM
2338490SPaul.Guo@Sun.COM switch (hw->phy.type) {
2348490SPaul.Guo@Sun.COM case ixgbe_phy_tn:
23510998SChenlu.Chen@Sun.COM phy->ops.setup_link = &ixgbe_setup_phy_link_tnx;
2368490SPaul.Guo@Sun.COM phy->ops.check_link = &ixgbe_check_phy_link_tnx;
2378490SPaul.Guo@Sun.COM phy->ops.get_firmware_version =
2388490SPaul.Guo@Sun.COM &ixgbe_get_phy_firmware_version_tnx;
2398490SPaul.Guo@Sun.COM break;
24010305SPaul.Guo@Sun.COM case ixgbe_phy_aq:
24110305SPaul.Guo@Sun.COM phy->ops.get_firmware_version =
24210998SChenlu.Chen@Sun.COM &ixgbe_get_phy_firmware_version_generic;
24310305SPaul.Guo@Sun.COM break;
2448490SPaul.Guo@Sun.COM case ixgbe_phy_nl:
2458490SPaul.Guo@Sun.COM phy->ops.reset = &ixgbe_reset_phy_nl;
2468490SPaul.Guo@Sun.COM
2478490SPaul.Guo@Sun.COM /* Call SFP+ identify routine to get the SFP+ module type */
2488490SPaul.Guo@Sun.COM ret_val = phy->ops.identify_sfp(hw);
2498490SPaul.Guo@Sun.COM if (ret_val != IXGBE_SUCCESS)
2508490SPaul.Guo@Sun.COM goto out;
2518490SPaul.Guo@Sun.COM else if (hw->phy.sfp_type == ixgbe_sfp_type_unknown) {
2528490SPaul.Guo@Sun.COM ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED;
2538490SPaul.Guo@Sun.COM goto out;
2548490SPaul.Guo@Sun.COM }
2558490SPaul.Guo@Sun.COM
2568490SPaul.Guo@Sun.COM /* Check to see if SFP+ module is supported */
2578490SPaul.Guo@Sun.COM ret_val = ixgbe_get_sfp_init_sequence_offsets(hw,
2588490SPaul.Guo@Sun.COM &list_offset, &data_offset);
2598490SPaul.Guo@Sun.COM if (ret_val != IXGBE_SUCCESS) {
2608490SPaul.Guo@Sun.COM ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED;
2618490SPaul.Guo@Sun.COM goto out;
2628490SPaul.Guo@Sun.COM }
2638490SPaul.Guo@Sun.COM break;
2648490SPaul.Guo@Sun.COM default:
2658490SPaul.Guo@Sun.COM break;
2668490SPaul.Guo@Sun.COM }
2678490SPaul.Guo@Sun.COM out:
2688490SPaul.Guo@Sun.COM return (ret_val);
2696621Sbt150084 }
2706621Sbt150084
2716621Sbt150084 /*
27210998SChenlu.Chen@Sun.COM * ixgbe_start_hw_82598 - Prepare hardware for Tx/Rx
27310998SChenlu.Chen@Sun.COM * @hw: pointer to hardware structure
27410998SChenlu.Chen@Sun.COM *
27510998SChenlu.Chen@Sun.COM * Starts the hardware using the generic start_hw function.
27612003SPaul.Guo@Sun.COM * Disables relaxed ordering Then set pcie completion timeout
27710998SChenlu.Chen@Sun.COM */
27810998SChenlu.Chen@Sun.COM s32
ixgbe_start_hw_82598(struct ixgbe_hw * hw)27910998SChenlu.Chen@Sun.COM ixgbe_start_hw_82598(struct ixgbe_hw *hw)
28010998SChenlu.Chen@Sun.COM {
28112003SPaul.Guo@Sun.COM u32 regval;
28212003SPaul.Guo@Sun.COM u32 i;
28310998SChenlu.Chen@Sun.COM s32 ret_val = IXGBE_SUCCESS;
28410998SChenlu.Chen@Sun.COM
28510998SChenlu.Chen@Sun.COM DEBUGFUNC("ixgbe_start_hw_82598");
28610998SChenlu.Chen@Sun.COM
28710998SChenlu.Chen@Sun.COM ret_val = ixgbe_start_hw_generic(hw);
28810998SChenlu.Chen@Sun.COM
28912003SPaul.Guo@Sun.COM /*
29012003SPaul.Guo@Sun.COM * Disable relaxed ordering
29112003SPaul.Guo@Sun.COM */
29212003SPaul.Guo@Sun.COM for (i = 0; ((i < hw->mac.max_tx_queues) &&
29312003SPaul.Guo@Sun.COM (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
29412003SPaul.Guo@Sun.COM regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
29512003SPaul.Guo@Sun.COM regval &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
29612003SPaul.Guo@Sun.COM IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval);
29712003SPaul.Guo@Sun.COM }
29812003SPaul.Guo@Sun.COM
29912003SPaul.Guo@Sun.COM for (i = 0; ((i < hw->mac.max_rx_queues) &&
30012003SPaul.Guo@Sun.COM (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
30112003SPaul.Guo@Sun.COM regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
30212003SPaul.Guo@Sun.COM regval &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
30312003SPaul.Guo@Sun.COM IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
30412003SPaul.Guo@Sun.COM IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
30512003SPaul.Guo@Sun.COM }
30612003SPaul.Guo@Sun.COM
30710998SChenlu.Chen@Sun.COM /* set the completion timeout for interface */
30810998SChenlu.Chen@Sun.COM if (ret_val == IXGBE_SUCCESS)
30910998SChenlu.Chen@Sun.COM ixgbe_set_pcie_completion_timeout(hw);
31010998SChenlu.Chen@Sun.COM
31110998SChenlu.Chen@Sun.COM return (ret_val);
31210998SChenlu.Chen@Sun.COM }
31310998SChenlu.Chen@Sun.COM
31410998SChenlu.Chen@Sun.COM /*
3156621Sbt150084 * ixgbe_get_link_capabilities_82598 - Determines link capabilities
3166621Sbt150084 * @hw: pointer to hardware structure
3176621Sbt150084 * @speed: pointer to link speed
3186621Sbt150084 * @autoneg: boolean auto-negotiation value
3196621Sbt150084 *
3206621Sbt150084 * Determines the link capabilities by reading the AUTOC register.
3216621Sbt150084 */
3228490SPaul.Guo@Sun.COM static s32
ixgbe_get_link_capabilities_82598(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * autoneg)3236621Sbt150084 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
3248490SPaul.Guo@Sun.COM ixgbe_link_speed *speed, bool *autoneg)
3256621Sbt150084 {
3266621Sbt150084 s32 status = IXGBE_SUCCESS;
3279353SSamuel.Tu@Sun.COM u32 autoc = 0;
3286621Sbt150084
32910998SChenlu.Chen@Sun.COM DEBUGFUNC("ixgbe_get_link_capabilities_82598");
33010998SChenlu.Chen@Sun.COM
3319353SSamuel.Tu@Sun.COM /*
3329353SSamuel.Tu@Sun.COM * Determine link capabilities based on the stored value of AUTOC,
3339353SSamuel.Tu@Sun.COM * which represents EEPROM defaults. If AUTOC value has not been
3349353SSamuel.Tu@Sun.COM * stored, use the current register value.
3359353SSamuel.Tu@Sun.COM */
3369353SSamuel.Tu@Sun.COM if (hw->mac.orig_link_settings_stored)
3379353SSamuel.Tu@Sun.COM autoc = hw->mac.orig_autoc;
3389353SSamuel.Tu@Sun.COM else
3399353SSamuel.Tu@Sun.COM autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
3406621Sbt150084
3419353SSamuel.Tu@Sun.COM switch (autoc & IXGBE_AUTOC_LMS_MASK) {
3426621Sbt150084 case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
3436621Sbt150084 *speed = IXGBE_LINK_SPEED_1GB_FULL;
3448490SPaul.Guo@Sun.COM *autoneg = false;
3456621Sbt150084 break;
3466621Sbt150084
3476621Sbt150084 case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
3486621Sbt150084 *speed = IXGBE_LINK_SPEED_10GB_FULL;
3498490SPaul.Guo@Sun.COM *autoneg = false;
3506621Sbt150084 break;
3516621Sbt150084
3526621Sbt150084 case IXGBE_AUTOC_LMS_1G_AN:
3536621Sbt150084 *speed = IXGBE_LINK_SPEED_1GB_FULL;
3548490SPaul.Guo@Sun.COM *autoneg = true;
3556621Sbt150084 break;
3566621Sbt150084
3576621Sbt150084 case IXGBE_AUTOC_LMS_KX4_AN:
3586621Sbt150084 case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
3596621Sbt150084 *speed = IXGBE_LINK_SPEED_UNKNOWN;
3609353SSamuel.Tu@Sun.COM if (autoc & IXGBE_AUTOC_KX4_SUPP)
3616621Sbt150084 *speed |= IXGBE_LINK_SPEED_10GB_FULL;
3629353SSamuel.Tu@Sun.COM if (autoc & IXGBE_AUTOC_KX_SUPP)
3636621Sbt150084 *speed |= IXGBE_LINK_SPEED_1GB_FULL;
3648490SPaul.Guo@Sun.COM *autoneg = true;
3656621Sbt150084 break;
3666621Sbt150084
3676621Sbt150084 default:
3686621Sbt150084 status = IXGBE_ERR_LINK_SETUP;
3696621Sbt150084 break;
3706621Sbt150084 }
3716621Sbt150084
3726621Sbt150084 return (status);
3736621Sbt150084 }
3746621Sbt150084
3756621Sbt150084 /*
3766621Sbt150084 * ixgbe_get_media_type_82598 - Determines media type
3776621Sbt150084 * @hw: pointer to hardware structure
3786621Sbt150084 *
3796621Sbt150084 * Returns the media type (fiber, copper, backplane)
3806621Sbt150084 */
3818490SPaul.Guo@Sun.COM static enum ixgbe_media_type
ixgbe_get_media_type_82598(struct ixgbe_hw * hw)3826621Sbt150084 ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
3836621Sbt150084 {
3846621Sbt150084 enum ixgbe_media_type media_type;
3856621Sbt150084
38610998SChenlu.Chen@Sun.COM DEBUGFUNC("ixgbe_get_media_type_82598");
38710998SChenlu.Chen@Sun.COM
3889353SSamuel.Tu@Sun.COM /* Detect if there is a copper PHY attached. */
3899353SSamuel.Tu@Sun.COM if (hw->phy.type == ixgbe_phy_cu_unknown ||
39010305SPaul.Guo@Sun.COM hw->phy.type == ixgbe_phy_tn ||
39110305SPaul.Guo@Sun.COM hw->phy.type == ixgbe_phy_aq) {
3929353SSamuel.Tu@Sun.COM media_type = ixgbe_media_type_copper;
3939353SSamuel.Tu@Sun.COM goto out;
3949353SSamuel.Tu@Sun.COM }
3959353SSamuel.Tu@Sun.COM
3966621Sbt150084 /* Media type for I82598 is based on device ID */
3976621Sbt150084 switch (hw->device_id) {
3989353SSamuel.Tu@Sun.COM case IXGBE_DEV_ID_82598:
3999353SSamuel.Tu@Sun.COM case IXGBE_DEV_ID_82598_BX:
4009353SSamuel.Tu@Sun.COM /* Default device ID is mezzanine card KX/KX4 */
4019353SSamuel.Tu@Sun.COM media_type = ixgbe_media_type_backplane;
4029353SSamuel.Tu@Sun.COM break;
4036621Sbt150084 case IXGBE_DEV_ID_82598AF_DUAL_PORT:
4046621Sbt150084 case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
4058490SPaul.Guo@Sun.COM case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
4068490SPaul.Guo@Sun.COM case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
4076621Sbt150084 case IXGBE_DEV_ID_82598EB_XF_LR:
4088490SPaul.Guo@Sun.COM case IXGBE_DEV_ID_82598EB_SFP_LOM:
4096621Sbt150084 media_type = ixgbe_media_type_fiber;
4106621Sbt150084 break;
41110998SChenlu.Chen@Sun.COM case IXGBE_DEV_ID_82598EB_CX4:
41210998SChenlu.Chen@Sun.COM case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
41310998SChenlu.Chen@Sun.COM media_type = ixgbe_media_type_cx4;
41410998SChenlu.Chen@Sun.COM break;
4158490SPaul.Guo@Sun.COM case IXGBE_DEV_ID_82598AT:
41610998SChenlu.Chen@Sun.COM case IXGBE_DEV_ID_82598AT2:
4178490SPaul.Guo@Sun.COM media_type = ixgbe_media_type_copper;
4188490SPaul.Guo@Sun.COM break;
4196621Sbt150084 default:
4206621Sbt150084 media_type = ixgbe_media_type_unknown;
4216621Sbt150084 break;
4226621Sbt150084 }
4239353SSamuel.Tu@Sun.COM out:
4246621Sbt150084 return (media_type);
4256621Sbt150084 }
4266621Sbt150084
4276621Sbt150084 /*
4289353SSamuel.Tu@Sun.COM * ixgbe_fc_enable_82598 - Enable flow control
4296621Sbt150084 * @hw: pointer to hardware structure
4306621Sbt150084 * @packetbuf_num: packet buffer number (0-7)
4316621Sbt150084 *
4329353SSamuel.Tu@Sun.COM * Enable flow control according to the current settings.
4336621Sbt150084 */
4346621Sbt150084 s32
ixgbe_fc_enable_82598(struct ixgbe_hw * hw,s32 packetbuf_num)4359353SSamuel.Tu@Sun.COM ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
4366621Sbt150084 {
4379353SSamuel.Tu@Sun.COM s32 ret_val = IXGBE_SUCCESS;
4389353SSamuel.Tu@Sun.COM u32 fctrl_reg;
4396621Sbt150084 u32 rmcs_reg;
4409353SSamuel.Tu@Sun.COM u32 reg;
44112003SPaul.Guo@Sun.COM u32 link_speed = 0;
44212003SPaul.Guo@Sun.COM bool link_up;
4439353SSamuel.Tu@Sun.COM
4449353SSamuel.Tu@Sun.COM DEBUGFUNC("ixgbe_fc_enable_82598");
4456621Sbt150084
44612003SPaul.Guo@Sun.COM /*
447*13006SChenlu.Chen@Sun.COM * On 82598 having Rx FC on causes resets while doing 1G
448*13006SChenlu.Chen@Sun.COM * so if it's on turn it off once we know link_speed. For
449*13006SChenlu.Chen@Sun.COM * more details see 82598 Specification update.
45012003SPaul.Guo@Sun.COM */
45112003SPaul.Guo@Sun.COM hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
452*13006SChenlu.Chen@Sun.COM if (link_up && link_speed == IXGBE_LINK_SPEED_1GB_FULL) {
453*13006SChenlu.Chen@Sun.COM switch (hw->fc.requested_mode) {
454*13006SChenlu.Chen@Sun.COM case ixgbe_fc_full:
455*13006SChenlu.Chen@Sun.COM hw->fc.requested_mode = ixgbe_fc_tx_pause;
456*13006SChenlu.Chen@Sun.COM break;
457*13006SChenlu.Chen@Sun.COM case ixgbe_fc_rx_pause:
458*13006SChenlu.Chen@Sun.COM hw->fc.requested_mode = ixgbe_fc_none;
459*13006SChenlu.Chen@Sun.COM break;
460*13006SChenlu.Chen@Sun.COM default:
461*13006SChenlu.Chen@Sun.COM /* no change */
462*13006SChenlu.Chen@Sun.COM break;
463*13006SChenlu.Chen@Sun.COM }
46412003SPaul.Guo@Sun.COM }
46512003SPaul.Guo@Sun.COM
4669353SSamuel.Tu@Sun.COM /* Negotiate the fc mode to use */
4679353SSamuel.Tu@Sun.COM ret_val = ixgbe_fc_autoneg(hw);
468*13006SChenlu.Chen@Sun.COM if (ret_val == IXGBE_ERR_FLOW_CONTROL)
4699353SSamuel.Tu@Sun.COM goto out;
4706621Sbt150084
4719353SSamuel.Tu@Sun.COM /* Disable any previous flow control settings */
4729353SSamuel.Tu@Sun.COM fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
4739353SSamuel.Tu@Sun.COM fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
4746621Sbt150084
4756621Sbt150084 rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
4766621Sbt150084 rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X);
4776621Sbt150084
4786621Sbt150084 /*
4799353SSamuel.Tu@Sun.COM * The possible values of fc.current_mode are:
4806621Sbt150084 * 0: Flow control is completely disabled
4819353SSamuel.Tu@Sun.COM * 1: Rx flow control is enabled (we can receive pause frames,
4829353SSamuel.Tu@Sun.COM * but not send pause frames).
4839353SSamuel.Tu@Sun.COM * 2: Tx flow control is enabled (we can send pause frames but
4849353SSamuel.Tu@Sun.COM * we do not support receiving pause frames).
4856621Sbt150084 * 3: Both Rx and Tx flow control (symmetric) are enabled.
4866621Sbt150084 * other: Invalid.
4876621Sbt150084 */
4889353SSamuel.Tu@Sun.COM switch (hw->fc.current_mode) {
4896621Sbt150084 case ixgbe_fc_none:
4909353SSamuel.Tu@Sun.COM /*
4919353SSamuel.Tu@Sun.COM * Flow control is disabled by software override or autoneg.
4929353SSamuel.Tu@Sun.COM * The code below will actually disable it in the HW.
4939353SSamuel.Tu@Sun.COM */
4946621Sbt150084 break;
4956621Sbt150084 case ixgbe_fc_rx_pause:
4966621Sbt150084 /*
4979353SSamuel.Tu@Sun.COM * Rx Flow control is enabled and Tx Flow control is
4989353SSamuel.Tu@Sun.COM * disabled by software override. Since there really
4999353SSamuel.Tu@Sun.COM * isn't a way to advertise that we are capable of RX
5009353SSamuel.Tu@Sun.COM * Pause ONLY, we will advertise that we support both
5019353SSamuel.Tu@Sun.COM * symmetric and asymmetric Rx PAUSE. Later, we will
5029353SSamuel.Tu@Sun.COM * disable the adapter's ability to send PAUSE frames.
5036621Sbt150084 */
5049353SSamuel.Tu@Sun.COM fctrl_reg |= IXGBE_FCTRL_RFCE;
5056621Sbt150084 break;
5066621Sbt150084 case ixgbe_fc_tx_pause:
5076621Sbt150084 /*
5089353SSamuel.Tu@Sun.COM * Tx Flow control is enabled, and Rx Flow control is
5099353SSamuel.Tu@Sun.COM * disabled by software override.
5106621Sbt150084 */
5116621Sbt150084 rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
5126621Sbt150084 break;
5136621Sbt150084 case ixgbe_fc_full:
5149353SSamuel.Tu@Sun.COM /* Flow control (both Rx and Tx) is enabled by SW override. */
5159353SSamuel.Tu@Sun.COM fctrl_reg |= IXGBE_FCTRL_RFCE;
5166621Sbt150084 rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
5176621Sbt150084 break;
5186621Sbt150084 default:
5196621Sbt150084 DEBUGOUT("Flow control param set incorrectly\n");
52010998SChenlu.Chen@Sun.COM ret_val = IXGBE_ERR_CONFIG;
5219353SSamuel.Tu@Sun.COM goto out;
5226621Sbt150084 }
5236621Sbt150084
5249353SSamuel.Tu@Sun.COM /* Set 802.3x based flow control settings. */
5259353SSamuel.Tu@Sun.COM fctrl_reg |= IXGBE_FCTRL_DPF;
5269353SSamuel.Tu@Sun.COM IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
5276621Sbt150084 IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
5286621Sbt150084
5299353SSamuel.Tu@Sun.COM /* Set up and enable Rx high/low water mark thresholds, enable XON. */
5309353SSamuel.Tu@Sun.COM if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
5316621Sbt150084 if (hw->fc.send_xon) {
5326621Sbt150084 IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
5336621Sbt150084 (hw->fc.low_water | IXGBE_FCRTL_XONE));
5346621Sbt150084 } else {
5356621Sbt150084 IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
5366621Sbt150084 hw->fc.low_water);
5376621Sbt150084 }
5389353SSamuel.Tu@Sun.COM
5396621Sbt150084 IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num),
5409353SSamuel.Tu@Sun.COM (hw->fc.high_water | IXGBE_FCRTH_FCEN));
5416621Sbt150084 }
5426621Sbt150084
5439353SSamuel.Tu@Sun.COM /* Configure pause time (2 TCs per register) */
54410305SPaul.Guo@Sun.COM reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num / 2));
5459353SSamuel.Tu@Sun.COM if ((packetbuf_num & 1) == 0)
5469353SSamuel.Tu@Sun.COM reg = (reg & 0xFFFF0000) | hw->fc.pause_time;
5479353SSamuel.Tu@Sun.COM else
5489353SSamuel.Tu@Sun.COM reg = (reg & 0x0000FFFF) | (hw->fc.pause_time << 16);
5499353SSamuel.Tu@Sun.COM IXGBE_WRITE_REG(hw, IXGBE_FCTTV(packetbuf_num / 2), reg);
5509353SSamuel.Tu@Sun.COM
5516621Sbt150084 IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1));
5526621Sbt150084
5539353SSamuel.Tu@Sun.COM out:
5549353SSamuel.Tu@Sun.COM return (ret_val);
5556621Sbt150084 }
5566621Sbt150084
5576621Sbt150084 /*
55810998SChenlu.Chen@Sun.COM * ixgbe_start_mac_link_82598 - Configures MAC link settings
5596621Sbt150084 * @hw: pointer to hardware structure
5606621Sbt150084 *
5616621Sbt150084 * Configures link settings based on values in the ixgbe_hw struct.
5626621Sbt150084 * Restarts the link. Performs autonegotiation if needed.
5636621Sbt150084 */
5648490SPaul.Guo@Sun.COM static s32
ixgbe_start_mac_link_82598(struct ixgbe_hw * hw,bool autoneg_wait_to_complete)56510998SChenlu.Chen@Sun.COM ixgbe_start_mac_link_82598(struct ixgbe_hw *hw, bool autoneg_wait_to_complete)
5666621Sbt150084 {
5676621Sbt150084 u32 autoc_reg;
5686621Sbt150084 u32 links_reg;
5696621Sbt150084 u32 i;
5706621Sbt150084 s32 status = IXGBE_SUCCESS;
5716621Sbt150084
57210998SChenlu.Chen@Sun.COM DEBUGFUNC("ixgbe_start_mac_link_82598");
57310998SChenlu.Chen@Sun.COM
5749353SSamuel.Tu@Sun.COM /* Restart link */
5756621Sbt150084 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
5766621Sbt150084 autoc_reg |= IXGBE_AUTOC_AN_RESTART;
5776621Sbt150084 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
5786621Sbt150084
5796621Sbt150084 /* Only poll for autoneg to complete if specified to do so */
58010998SChenlu.Chen@Sun.COM if (autoneg_wait_to_complete) {
5819353SSamuel.Tu@Sun.COM if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
5829353SSamuel.Tu@Sun.COM IXGBE_AUTOC_LMS_KX4_AN ||
5839353SSamuel.Tu@Sun.COM (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
5849353SSamuel.Tu@Sun.COM IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
5856621Sbt150084 links_reg = 0; /* Just in case Autoneg time = 0 */
5866621Sbt150084 for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
5876621Sbt150084 links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
5886621Sbt150084 if (links_reg & IXGBE_LINKS_KX_AN_COMP)
5896621Sbt150084 break;
5906621Sbt150084 msec_delay(100);
5916621Sbt150084 }
5926621Sbt150084 if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
5936621Sbt150084 status = IXGBE_ERR_AUTONEG_NOT_COMPLETE;
5946621Sbt150084 DEBUGOUT("Autonegotiation did not complete.\n");
5956621Sbt150084 }
5966621Sbt150084 }
5976621Sbt150084 }
5986621Sbt150084
5996621Sbt150084 /* Add delay to filter out noises during initial link setup */
6006621Sbt150084 msec_delay(50);
6016621Sbt150084
6026621Sbt150084 return (status);
6036621Sbt150084 }
6046621Sbt150084
6056621Sbt150084 /*
6066621Sbt150084 * ixgbe_check_mac_link_82598 - Get link/speed status
6076621Sbt150084 * @hw: pointer to hardware structure
6086621Sbt150084 * @speed: pointer to link speed
6099353SSamuel.Tu@Sun.COM * @link_up: true is link is up, false otherwise
6109353SSamuel.Tu@Sun.COM * @link_up_wait_to_complete: bool used to wait for link up or not
6116621Sbt150084 *
6126621Sbt150084 * Reads the links register to determine if link is up and the current speed
6136621Sbt150084 */
6148490SPaul.Guo@Sun.COM static s32
ixgbe_check_mac_link_82598(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * link_up,bool link_up_wait_to_complete)6156621Sbt150084 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
6168490SPaul.Guo@Sun.COM bool *link_up, bool link_up_wait_to_complete)
6176621Sbt150084 {
6186621Sbt150084 u32 links_reg;
6198490SPaul.Guo@Sun.COM u32 i;
6208490SPaul.Guo@Sun.COM u16 link_reg, adapt_comp_reg;
6218490SPaul.Guo@Sun.COM
62210998SChenlu.Chen@Sun.COM DEBUGFUNC("ixgbe_check_mac_link_82598");
62310998SChenlu.Chen@Sun.COM
6248490SPaul.Guo@Sun.COM /*
6258490SPaul.Guo@Sun.COM * SERDES PHY requires us to read link status from undocumented
6268490SPaul.Guo@Sun.COM * register 0xC79F. Bit 0 set indicates link is up/ready; clear
6278490SPaul.Guo@Sun.COM * indicates link down. OxC00C is read to check that the XAUI lanes
6288490SPaul.Guo@Sun.COM * are active. Bit 0 clear indicates active; set indicates inactive.
6298490SPaul.Guo@Sun.COM */
6308490SPaul.Guo@Sun.COM if (hw->phy.type == ixgbe_phy_nl) {
6318490SPaul.Guo@Sun.COM hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg);
6328490SPaul.Guo@Sun.COM hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg);
6338490SPaul.Guo@Sun.COM hw->phy.ops.read_reg(hw, 0xC00C, IXGBE_TWINAX_DEV,
6348490SPaul.Guo@Sun.COM &adapt_comp_reg);
6358490SPaul.Guo@Sun.COM if (link_up_wait_to_complete) {
6368490SPaul.Guo@Sun.COM for (i = 0; i < IXGBE_LINK_UP_TIME; i++) {
6378490SPaul.Guo@Sun.COM if ((link_reg & 1) &&
6388490SPaul.Guo@Sun.COM ((adapt_comp_reg & 1) == 0)) {
6398490SPaul.Guo@Sun.COM *link_up = true;
6408490SPaul.Guo@Sun.COM break;
6418490SPaul.Guo@Sun.COM } else {
6428490SPaul.Guo@Sun.COM *link_up = false;
6438490SPaul.Guo@Sun.COM }
6448490SPaul.Guo@Sun.COM msec_delay(100);
6458490SPaul.Guo@Sun.COM hw->phy.ops.read_reg(hw, 0xC79F,
6468490SPaul.Guo@Sun.COM IXGBE_TWINAX_DEV, &link_reg);
6478490SPaul.Guo@Sun.COM hw->phy.ops.read_reg(hw, 0xC00C,
6488490SPaul.Guo@Sun.COM IXGBE_TWINAX_DEV, &adapt_comp_reg);
6498490SPaul.Guo@Sun.COM }
6508490SPaul.Guo@Sun.COM } else {
6518490SPaul.Guo@Sun.COM if ((link_reg & 1) &&
6528490SPaul.Guo@Sun.COM ((adapt_comp_reg & 1) == 0))
6538490SPaul.Guo@Sun.COM *link_up = true;
6548490SPaul.Guo@Sun.COM else
6558490SPaul.Guo@Sun.COM *link_up = false;
6568490SPaul.Guo@Sun.COM }
6578490SPaul.Guo@Sun.COM
6588490SPaul.Guo@Sun.COM if (*link_up == false)
6598490SPaul.Guo@Sun.COM goto out;
6608490SPaul.Guo@Sun.COM }
6616621Sbt150084
6626621Sbt150084 links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
6638490SPaul.Guo@Sun.COM if (link_up_wait_to_complete) {
6648490SPaul.Guo@Sun.COM for (i = 0; i < IXGBE_LINK_UP_TIME; i++) {
6658490SPaul.Guo@Sun.COM if (links_reg & IXGBE_LINKS_UP) {
6668490SPaul.Guo@Sun.COM *link_up = true;
6678490SPaul.Guo@Sun.COM break;
6688490SPaul.Guo@Sun.COM } else {
6698490SPaul.Guo@Sun.COM *link_up = false;
6708490SPaul.Guo@Sun.COM }
6718490SPaul.Guo@Sun.COM msec_delay(100);
6728490SPaul.Guo@Sun.COM links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
6738490SPaul.Guo@Sun.COM }
6748490SPaul.Guo@Sun.COM } else {
6758490SPaul.Guo@Sun.COM if (links_reg & IXGBE_LINKS_UP)
6768490SPaul.Guo@Sun.COM *link_up = true;
6778490SPaul.Guo@Sun.COM else
6788490SPaul.Guo@Sun.COM *link_up = false;
6798490SPaul.Guo@Sun.COM }
6806621Sbt150084
6816621Sbt150084 if (links_reg & IXGBE_LINKS_SPEED)
6826621Sbt150084 *speed = IXGBE_LINK_SPEED_10GB_FULL;
6836621Sbt150084 else
6846621Sbt150084 *speed = IXGBE_LINK_SPEED_1GB_FULL;
6856621Sbt150084
68612003SPaul.Guo@Sun.COM if ((hw->device_id == IXGBE_DEV_ID_82598AT2) && (*link_up == true) &&
68712003SPaul.Guo@Sun.COM (ixgbe_validate_link_ready(hw) != IXGBE_SUCCESS))
68812003SPaul.Guo@Sun.COM *link_up = false;
68912003SPaul.Guo@Sun.COM
6909353SSamuel.Tu@Sun.COM /* if link is down, zero out the current_mode */
6919353SSamuel.Tu@Sun.COM if (*link_up == false) {
6929353SSamuel.Tu@Sun.COM hw->fc.current_mode = ixgbe_fc_none;
6939353SSamuel.Tu@Sun.COM hw->fc.fc_was_autonegged = false;
6949353SSamuel.Tu@Sun.COM }
69512003SPaul.Guo@Sun.COM
6968490SPaul.Guo@Sun.COM out:
6976621Sbt150084 return (IXGBE_SUCCESS);
6986621Sbt150084 }
6996621Sbt150084
7006621Sbt150084 /*
70110998SChenlu.Chen@Sun.COM * ixgbe_setup_mac_link_82598 - Set MAC link speed
7026621Sbt150084 * @hw: pointer to hardware structure
7036621Sbt150084 * @speed: new link speed
7049353SSamuel.Tu@Sun.COM * @autoneg: true if autonegotiation enabled
7059353SSamuel.Tu@Sun.COM * @autoneg_wait_to_complete: true when waiting for completion is needed
7066621Sbt150084 *
7076621Sbt150084 * Set the link speed in the AUTOC register and restarts link.
7086621Sbt150084 */
7098490SPaul.Guo@Sun.COM static s32
ixgbe_setup_mac_link_82598(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg,bool autoneg_wait_to_complete)71010998SChenlu.Chen@Sun.COM ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
7116621Sbt150084 ixgbe_link_speed speed, bool autoneg,
7126621Sbt150084 bool autoneg_wait_to_complete)
7136621Sbt150084 {
7146621Sbt150084 s32 status = IXGBE_SUCCESS;
7159353SSamuel.Tu@Sun.COM ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
7169353SSamuel.Tu@Sun.COM u32 curr_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
7179353SSamuel.Tu@Sun.COM u32 autoc = curr_autoc;
7189353SSamuel.Tu@Sun.COM u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
7196621Sbt150084
72010998SChenlu.Chen@Sun.COM DEBUGFUNC("ixgbe_setup_mac_link_82598");
72110998SChenlu.Chen@Sun.COM
7229353SSamuel.Tu@Sun.COM /* Check to see if speed passed in is supported. */
7239353SSamuel.Tu@Sun.COM (void) ixgbe_get_link_capabilities(hw, &link_capabilities, &autoneg);
7249353SSamuel.Tu@Sun.COM speed &= link_capabilities;
7259353SSamuel.Tu@Sun.COM
7269353SSamuel.Tu@Sun.COM if (speed == IXGBE_LINK_SPEED_UNKNOWN) {
7276621Sbt150084 status = IXGBE_ERR_LINK_SETUP;
7289353SSamuel.Tu@Sun.COM } else if (link_mode == IXGBE_AUTOC_LMS_KX4_AN ||
7299353SSamuel.Tu@Sun.COM link_mode == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
7309353SSamuel.Tu@Sun.COM /* Set KX4/KX support according to speed requested */
7319353SSamuel.Tu@Sun.COM autoc &= ~IXGBE_AUTOC_KX4_KX_SUPP_MASK;
7329353SSamuel.Tu@Sun.COM if (speed & IXGBE_LINK_SPEED_10GB_FULL)
7339353SSamuel.Tu@Sun.COM autoc |= IXGBE_AUTOC_KX4_SUPP;
7349353SSamuel.Tu@Sun.COM if (speed & IXGBE_LINK_SPEED_1GB_FULL)
7359353SSamuel.Tu@Sun.COM autoc |= IXGBE_AUTOC_KX_SUPP;
7369353SSamuel.Tu@Sun.COM if (autoc != curr_autoc)
7379353SSamuel.Tu@Sun.COM IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
7386621Sbt150084 }
7396621Sbt150084
7406621Sbt150084 if (status == IXGBE_SUCCESS) {
7416621Sbt150084 /*
7426621Sbt150084 * Setup and restart the link based on the new values in
7436621Sbt150084 * ixgbe_hw This will write the AUTOC register based on the new
7446621Sbt150084 * stored values
7456621Sbt150084 */
74610998SChenlu.Chen@Sun.COM status = ixgbe_start_mac_link_82598(hw,
74710998SChenlu.Chen@Sun.COM autoneg_wait_to_complete);
7486621Sbt150084 }
7496621Sbt150084
7506621Sbt150084 return (status);
7516621Sbt150084 }
7526621Sbt150084
7536621Sbt150084 /*
75410998SChenlu.Chen@Sun.COM * ixgbe_setup_copper_link_82598 - Set the PHY autoneg advertised field
7556621Sbt150084 * @hw: pointer to hardware structure
7566621Sbt150084 * @speed: new link speed
7579353SSamuel.Tu@Sun.COM * @autoneg: true if autonegotiation enabled
7589353SSamuel.Tu@Sun.COM * @autoneg_wait_to_complete: true if waiting is needed to complete
7596621Sbt150084 *
7606621Sbt150084 * Sets the link speed in the AUTOC register in the MAC and restarts link.
7616621Sbt150084 */
7628490SPaul.Guo@Sun.COM static s32
ixgbe_setup_copper_link_82598(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg,bool autoneg_wait_to_complete)76310998SChenlu.Chen@Sun.COM ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
7646621Sbt150084 ixgbe_link_speed speed,
7656621Sbt150084 bool autoneg,
7666621Sbt150084 bool autoneg_wait_to_complete)
7676621Sbt150084 {
7686621Sbt150084 s32 status;
7696621Sbt150084
77010998SChenlu.Chen@Sun.COM DEBUGFUNC("ixgbe_setup_copper_link_82598");
77110998SChenlu.Chen@Sun.COM
7726621Sbt150084 /* Setup the PHY according to input speed */
7736621Sbt150084 status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
7746621Sbt150084 autoneg_wait_to_complete);
7756621Sbt150084
7766621Sbt150084 /* Set up MAC */
77710998SChenlu.Chen@Sun.COM (void) ixgbe_start_mac_link_82598(hw, autoneg_wait_to_complete);
7786621Sbt150084
7796621Sbt150084 return (status);
7806621Sbt150084 }
7816621Sbt150084
7826621Sbt150084 /*
7836621Sbt150084 * ixgbe_reset_hw_82598 - Performs hardware reset
7846621Sbt150084 * @hw: pointer to hardware structure
7856621Sbt150084 *
7866621Sbt150084 * Resets the hardware by resetting the transmit and receive units, masks and
7876621Sbt150084 * clears all interrupts, performing a PHY reset, and performing a link (MAC)
7886621Sbt150084 * reset.
7896621Sbt150084 */
7908490SPaul.Guo@Sun.COM static s32
ixgbe_reset_hw_82598(struct ixgbe_hw * hw)7916621Sbt150084 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
7926621Sbt150084 {
7936621Sbt150084 s32 status = IXGBE_SUCCESS;
79410305SPaul.Guo@Sun.COM s32 phy_status = IXGBE_SUCCESS;
7956621Sbt150084 u32 ctrl;
7966621Sbt150084 u32 gheccr;
7976621Sbt150084 u32 i;
7986621Sbt150084 u32 autoc;
7996621Sbt150084 u8 analog_val;
8006621Sbt150084
80110998SChenlu.Chen@Sun.COM DEBUGFUNC("ixgbe_reset_hw_82598");
80210998SChenlu.Chen@Sun.COM
8036621Sbt150084 /* Call adapter stop to disable tx/rx and clear interrupts */
8046621Sbt150084 hw->mac.ops.stop_adapter(hw);
8056621Sbt150084
8066621Sbt150084 /*
8076621Sbt150084 * Power up the Atlas Tx lanes if they are currently powered down.
8086621Sbt150084 * Atlas Tx lanes are powered down for MAC loopback tests, but
8096621Sbt150084 * they are not automatically restored on reset.
8106621Sbt150084 */
8116621Sbt150084 hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val);
8126621Sbt150084 if (analog_val & IXGBE_ATLAS_PDN_TX_REG_EN) {
8136621Sbt150084 /* Enable Tx Atlas so packets can be transmitted again */
8146621Sbt150084 hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK,
8156621Sbt150084 &analog_val);
8166621Sbt150084 analog_val &= ~IXGBE_ATLAS_PDN_TX_REG_EN;
8176621Sbt150084 hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK,
8186621Sbt150084 analog_val);
8196621Sbt150084
8206621Sbt150084 hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G,
8216621Sbt150084 &analog_val);
8228490SPaul.Guo@Sun.COM analog_val &= ~IXGBE_ATLAS_PDN_TX_10G_QL_ALL;
8236621Sbt150084 hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G,
8246621Sbt150084 analog_val);
8256621Sbt150084
8266621Sbt150084 hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G,
8276621Sbt150084 &analog_val);
8286621Sbt150084 analog_val &= ~IXGBE_ATLAS_PDN_TX_1G_QL_ALL;
8296621Sbt150084 hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G,
8306621Sbt150084 analog_val);
8316621Sbt150084
8326621Sbt150084 hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN,
8336621Sbt150084 &analog_val);
8346621Sbt150084 analog_val &= ~IXGBE_ATLAS_PDN_TX_AN_QL_ALL;
8356621Sbt150084 hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN,
8366621Sbt150084 analog_val);
8376621Sbt150084 }
8386621Sbt150084
8396621Sbt150084 /* Reset PHY */
8409353SSamuel.Tu@Sun.COM if (hw->phy.reset_disable == false) {
8419353SSamuel.Tu@Sun.COM /* PHY ops must be identified and initialized prior to reset */
8429353SSamuel.Tu@Sun.COM
8439353SSamuel.Tu@Sun.COM /* Init PHY and function pointers, perform SFP setup */
84410305SPaul.Guo@Sun.COM phy_status = hw->phy.ops.init(hw);
84510305SPaul.Guo@Sun.COM if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED)
84610305SPaul.Guo@Sun.COM goto reset_hw_out;
84710305SPaul.Guo@Sun.COM else if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT)
84810305SPaul.Guo@Sun.COM goto no_phy_reset;
8499353SSamuel.Tu@Sun.COM
8508490SPaul.Guo@Sun.COM hw->phy.ops.reset(hw);
8519353SSamuel.Tu@Sun.COM }
8526621Sbt150084
85310305SPaul.Guo@Sun.COM no_phy_reset:
8546621Sbt150084 /*
8556621Sbt150084 * Prevent the PCI-E bus from from hanging by disabling PCI-E master
8566621Sbt150084 * access and verify no pending requests before reset
8576621Sbt150084 */
85812003SPaul.Guo@Sun.COM (void) ixgbe_disable_pcie_master(hw);
85912003SPaul.Guo@Sun.COM
86012003SPaul.Guo@Sun.COM mac_reset_top:
8616621Sbt150084
8626621Sbt150084 /*
8636621Sbt150084 * Issue global reset to the MAC. This needs to be a SW reset.
8646621Sbt150084 * If link reset is used, it might reset the MAC when mng is using it
8656621Sbt150084 */
8666621Sbt150084 ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
8676621Sbt150084 IXGBE_WRITE_REG(hw, IXGBE_CTRL, (ctrl | IXGBE_CTRL_RST));
8686621Sbt150084 IXGBE_WRITE_FLUSH(hw);
8696621Sbt150084
8706621Sbt150084 /* Poll for reset bit to self-clear indicating reset is complete */
8716621Sbt150084 for (i = 0; i < 10; i++) {
8726621Sbt150084 usec_delay(1);
8736621Sbt150084 ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
8746621Sbt150084 if (!(ctrl & IXGBE_CTRL_RST))
8756621Sbt150084 break;
8766621Sbt150084 }
8776621Sbt150084 if (ctrl & IXGBE_CTRL_RST) {
8786621Sbt150084 status = IXGBE_ERR_RESET_FAILED;
8796621Sbt150084 DEBUGOUT("Reset polling failed to complete.\n");
8806621Sbt150084 }
8816621Sbt150084
88212003SPaul.Guo@Sun.COM /*
88312003SPaul.Guo@Sun.COM * Double resets are required for recovery from certain error
88412003SPaul.Guo@Sun.COM * conditions. Between resets, it is necessary to stall to allow time
88512003SPaul.Guo@Sun.COM * for any pending HW events to complete. We use 1usec since that is
88612003SPaul.Guo@Sun.COM * what is needed for ixgbe_disable_pcie_master(). The second reset
88712003SPaul.Guo@Sun.COM * then clears out any effects of those events.
88812003SPaul.Guo@Sun.COM */
88912003SPaul.Guo@Sun.COM if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
89012003SPaul.Guo@Sun.COM hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
89112003SPaul.Guo@Sun.COM usec_delay(1);
89212003SPaul.Guo@Sun.COM goto mac_reset_top;
89312003SPaul.Guo@Sun.COM }
8946621Sbt150084 msec_delay(50);
8956621Sbt150084
8966621Sbt150084 gheccr = IXGBE_READ_REG(hw, IXGBE_GHECCR);
8976621Sbt150084 gheccr &= ~((1 << 21) | (1 << 18) | (1 << 9) | (1 << 6));
8986621Sbt150084 IXGBE_WRITE_REG(hw, IXGBE_GHECCR, gheccr);
8996621Sbt150084
9006621Sbt150084 /*
9019353SSamuel.Tu@Sun.COM * Store the original AUTOC value if it has not been
9029353SSamuel.Tu@Sun.COM * stored off yet. Otherwise restore the stored original
9039353SSamuel.Tu@Sun.COM * AUTOC value since the reset operation sets back to deaults.
9046621Sbt150084 */
9056621Sbt150084 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
9069353SSamuel.Tu@Sun.COM if (hw->mac.orig_link_settings_stored == false) {
9079353SSamuel.Tu@Sun.COM hw->mac.orig_autoc = autoc;
9089353SSamuel.Tu@Sun.COM hw->mac.orig_link_settings_stored = true;
9099353SSamuel.Tu@Sun.COM } else if (autoc != hw->mac.orig_autoc) {
9109353SSamuel.Tu@Sun.COM IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc);
9116621Sbt150084 }
9126621Sbt150084
91310305SPaul.Guo@Sun.COM /* Store the permanent mac address */
91410305SPaul.Guo@Sun.COM hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
91510305SPaul.Guo@Sun.COM
9169353SSamuel.Tu@Sun.COM /*
9179353SSamuel.Tu@Sun.COM * Store MAC address from RAR0, clear receive address registers, and
9189353SSamuel.Tu@Sun.COM * clear the multicast table
9199353SSamuel.Tu@Sun.COM */
9209353SSamuel.Tu@Sun.COM hw->mac.ops.init_rx_addrs(hw);
9219353SSamuel.Tu@Sun.COM
92210305SPaul.Guo@Sun.COM reset_hw_out:
92310305SPaul.Guo@Sun.COM if (phy_status != IXGBE_SUCCESS)
92410305SPaul.Guo@Sun.COM status = phy_status;
9256621Sbt150084
9266621Sbt150084 return (status);
9276621Sbt150084 }
9286621Sbt150084
9296621Sbt150084 /*
9306621Sbt150084 * ixgbe_set_vmdq_82598 - Associate a VMDq set index with a rx address
9316621Sbt150084 * @hw: pointer to hardware struct
9326621Sbt150084 * @rar: receive address register index to associate with a VMDq index
9336621Sbt150084 * @vmdq: VMDq set index
9346621Sbt150084 */
9356621Sbt150084 s32
ixgbe_set_vmdq_82598(struct ixgbe_hw * hw,u32 rar,u32 vmdq)9366621Sbt150084 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
9376621Sbt150084 {
9386621Sbt150084 u32 rar_high;
9396621Sbt150084
94010998SChenlu.Chen@Sun.COM DEBUGFUNC("ixgbe_set_vmdq_82598");
94110998SChenlu.Chen@Sun.COM
9426621Sbt150084 rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
9436621Sbt150084 rar_high &= ~IXGBE_RAH_VIND_MASK;
9446621Sbt150084 rar_high |= ((vmdq << IXGBE_RAH_VIND_SHIFT) & IXGBE_RAH_VIND_MASK);
9456621Sbt150084 IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high);
9466621Sbt150084 return (IXGBE_SUCCESS);
9476621Sbt150084 }
9486621Sbt150084
9496621Sbt150084 /*
9508490SPaul.Guo@Sun.COM * ixgbe_clear_vmdq_82598 - Disassociate a VMDq set index from an rx address
9518490SPaul.Guo@Sun.COM * @hw: pointer to hardware struct
9528490SPaul.Guo@Sun.COM * @rar: receive address register index to associate with a VMDq index
9538490SPaul.Guo@Sun.COM * @vmdq: VMDq clear index (not used in 82598, but elsewhere)
9548490SPaul.Guo@Sun.COM */
9558490SPaul.Guo@Sun.COM static s32
ixgbe_clear_vmdq_82598(struct ixgbe_hw * hw,u32 rar,u32 vmdq)9568490SPaul.Guo@Sun.COM ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
9578490SPaul.Guo@Sun.COM {
9588490SPaul.Guo@Sun.COM u32 rar_high;
9598490SPaul.Guo@Sun.COM u32 rar_entries = hw->mac.num_rar_entries;
9608490SPaul.Guo@Sun.COM
9618490SPaul.Guo@Sun.COM UNREFERENCED_PARAMETER(vmdq);
9628490SPaul.Guo@Sun.COM
9638490SPaul.Guo@Sun.COM if (rar < rar_entries) {
9648490SPaul.Guo@Sun.COM rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
9658490SPaul.Guo@Sun.COM if (rar_high & IXGBE_RAH_VIND_MASK) {
9668490SPaul.Guo@Sun.COM rar_high &= ~IXGBE_RAH_VIND_MASK;
9678490SPaul.Guo@Sun.COM IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high);
9688490SPaul.Guo@Sun.COM }
9698490SPaul.Guo@Sun.COM } else {
9708490SPaul.Guo@Sun.COM DEBUGOUT1("RAR index %d is out of range.\n", rar);
9718490SPaul.Guo@Sun.COM }
9728490SPaul.Guo@Sun.COM
9738490SPaul.Guo@Sun.COM return (IXGBE_SUCCESS);
9748490SPaul.Guo@Sun.COM }
9758490SPaul.Guo@Sun.COM
9768490SPaul.Guo@Sun.COM /*
9778490SPaul.Guo@Sun.COM * ixgbe_set_vfta_82598 - Set VLAN filter table
9788490SPaul.Guo@Sun.COM * @hw: pointer to hardware structure
9798490SPaul.Guo@Sun.COM * @vlan: VLAN id to write to VLAN filter
9808490SPaul.Guo@Sun.COM * @vind: VMDq output index that maps queue to VLAN id in VFTA
9818490SPaul.Guo@Sun.COM * @vlan_on: boolean flag to turn on/off VLAN in VFTA
9828490SPaul.Guo@Sun.COM *
9838490SPaul.Guo@Sun.COM * Turn on/off specified VLAN in the VLAN filter table.
9848490SPaul.Guo@Sun.COM */
9858490SPaul.Guo@Sun.COM s32
ixgbe_set_vfta_82598(struct ixgbe_hw * hw,u32 vlan,u32 vind,bool vlan_on)9868490SPaul.Guo@Sun.COM ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on)
9878490SPaul.Guo@Sun.COM {
9888490SPaul.Guo@Sun.COM u32 regindex;
9898490SPaul.Guo@Sun.COM u32 bitindex;
9908490SPaul.Guo@Sun.COM u32 bits;
9918490SPaul.Guo@Sun.COM u32 vftabyte;
9928490SPaul.Guo@Sun.COM
99310998SChenlu.Chen@Sun.COM DEBUGFUNC("ixgbe_set_vfta_82598");
99410998SChenlu.Chen@Sun.COM
9958490SPaul.Guo@Sun.COM if (vlan > 4095)
9968490SPaul.Guo@Sun.COM return (IXGBE_ERR_PARAM);
9978490SPaul.Guo@Sun.COM
9988490SPaul.Guo@Sun.COM /* Determine 32-bit word position in array */
9998490SPaul.Guo@Sun.COM regindex = (vlan >> 5) & 0x7F; /* upper seven bits */
10008490SPaul.Guo@Sun.COM
10018490SPaul.Guo@Sun.COM /* Determine the location of the (VMD) queue index */
10028490SPaul.Guo@Sun.COM vftabyte = ((vlan >> 3) & 0x03); /* bits (4:3) indicating byte array */
10038490SPaul.Guo@Sun.COM bitindex = (vlan & 0x7) << 2; /* lower 3 bits indicate nibble */
10048490SPaul.Guo@Sun.COM
10058490SPaul.Guo@Sun.COM /* Set the nibble for VMD queue index */
10068490SPaul.Guo@Sun.COM bits = IXGBE_READ_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex));
10078490SPaul.Guo@Sun.COM bits &= (~(0x0F << bitindex));
10088490SPaul.Guo@Sun.COM bits |= (vind << bitindex);
10098490SPaul.Guo@Sun.COM IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex), bits);
10108490SPaul.Guo@Sun.COM
10118490SPaul.Guo@Sun.COM /* Determine the location of the bit for this VLAN id */
10128490SPaul.Guo@Sun.COM bitindex = vlan & 0x1F; /* lower five bits */
10138490SPaul.Guo@Sun.COM
10148490SPaul.Guo@Sun.COM bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
10158490SPaul.Guo@Sun.COM if (vlan_on)
10168490SPaul.Guo@Sun.COM /* Turn on this VLAN id */
10178490SPaul.Guo@Sun.COM bits |= (1 << bitindex);
10188490SPaul.Guo@Sun.COM else
10198490SPaul.Guo@Sun.COM /* Turn off this VLAN id */
10208490SPaul.Guo@Sun.COM bits &= ~(1 << bitindex);
10218490SPaul.Guo@Sun.COM IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits);
10228490SPaul.Guo@Sun.COM
10238490SPaul.Guo@Sun.COM return (IXGBE_SUCCESS);
10248490SPaul.Guo@Sun.COM }
10258490SPaul.Guo@Sun.COM
10268490SPaul.Guo@Sun.COM /*
10278490SPaul.Guo@Sun.COM * ixgbe_clear_vfta_82598 - Clear VLAN filter table
10288490SPaul.Guo@Sun.COM * @hw: pointer to hardware structure
10298490SPaul.Guo@Sun.COM *
10308490SPaul.Guo@Sun.COM * Clears the VLAN filer table, and the VMDq index associated with the filter
10318490SPaul.Guo@Sun.COM */
10328490SPaul.Guo@Sun.COM static s32
ixgbe_clear_vfta_82598(struct ixgbe_hw * hw)10338490SPaul.Guo@Sun.COM ixgbe_clear_vfta_82598(struct ixgbe_hw *hw)
10348490SPaul.Guo@Sun.COM {
10358490SPaul.Guo@Sun.COM u32 offset;
10368490SPaul.Guo@Sun.COM u32 vlanbyte;
10378490SPaul.Guo@Sun.COM
103810998SChenlu.Chen@Sun.COM DEBUGFUNC("ixgbe_clear_vfta_82598");
103910998SChenlu.Chen@Sun.COM
10408490SPaul.Guo@Sun.COM for (offset = 0; offset < hw->mac.vft_size; offset++)
10418490SPaul.Guo@Sun.COM IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
10428490SPaul.Guo@Sun.COM
10438490SPaul.Guo@Sun.COM for (vlanbyte = 0; vlanbyte < 4; vlanbyte++)
10448490SPaul.Guo@Sun.COM for (offset = 0; offset < hw->mac.vft_size; offset++)
10458490SPaul.Guo@Sun.COM IXGBE_WRITE_REG(hw,
10468490SPaul.Guo@Sun.COM IXGBE_VFTAVIND(vlanbyte, offset), 0);
10478490SPaul.Guo@Sun.COM
10488490SPaul.Guo@Sun.COM return (IXGBE_SUCCESS);
10498490SPaul.Guo@Sun.COM }
10508490SPaul.Guo@Sun.COM
10518490SPaul.Guo@Sun.COM /*
10528490SPaul.Guo@Sun.COM * ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register
10538490SPaul.Guo@Sun.COM * @hw: pointer to hardware structure
10548490SPaul.Guo@Sun.COM * @reg: analog register to read
10558490SPaul.Guo@Sun.COM * @val: read value
10568490SPaul.Guo@Sun.COM *
10578490SPaul.Guo@Sun.COM * Performs read operation to Atlas analog register specified.
10588490SPaul.Guo@Sun.COM */
10598490SPaul.Guo@Sun.COM s32
ixgbe_read_analog_reg8_82598(struct ixgbe_hw * hw,u32 reg,u8 * val)10608490SPaul.Guo@Sun.COM ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val)
10618490SPaul.Guo@Sun.COM {
10628490SPaul.Guo@Sun.COM u32 atlas_ctl;
10638490SPaul.Guo@Sun.COM
106410998SChenlu.Chen@Sun.COM DEBUGFUNC("ixgbe_read_analog_reg8_82598");
106510998SChenlu.Chen@Sun.COM
10668490SPaul.Guo@Sun.COM IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL,
10678490SPaul.Guo@Sun.COM IXGBE_ATLASCTL_WRITE_CMD | (reg << 8));
10688490SPaul.Guo@Sun.COM IXGBE_WRITE_FLUSH(hw);
10698490SPaul.Guo@Sun.COM usec_delay(10);
10708490SPaul.Guo@Sun.COM atlas_ctl = IXGBE_READ_REG(hw, IXGBE_ATLASCTL);
10718490SPaul.Guo@Sun.COM *val = (u8)atlas_ctl;
10728490SPaul.Guo@Sun.COM
10738490SPaul.Guo@Sun.COM return (IXGBE_SUCCESS);
10748490SPaul.Guo@Sun.COM }
10758490SPaul.Guo@Sun.COM
10768490SPaul.Guo@Sun.COM /*
10778490SPaul.Guo@Sun.COM * ixgbe_write_analog_reg8_82598 - Writes 8 bit Atlas analog register
10788490SPaul.Guo@Sun.COM * @hw: pointer to hardware structure
10798490SPaul.Guo@Sun.COM * @reg: atlas register to write
10808490SPaul.Guo@Sun.COM * @val: value to write
10818490SPaul.Guo@Sun.COM *
10828490SPaul.Guo@Sun.COM * Performs write operation to Atlas analog register specified.
10838490SPaul.Guo@Sun.COM */
10848490SPaul.Guo@Sun.COM s32
ixgbe_write_analog_reg8_82598(struct ixgbe_hw * hw,u32 reg,u8 val)10858490SPaul.Guo@Sun.COM ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val)
10868490SPaul.Guo@Sun.COM {
10878490SPaul.Guo@Sun.COM u32 atlas_ctl;
10888490SPaul.Guo@Sun.COM
108910998SChenlu.Chen@Sun.COM DEBUGFUNC("ixgbe_write_analog_reg8_82598");
109010998SChenlu.Chen@Sun.COM
10918490SPaul.Guo@Sun.COM atlas_ctl = (reg << 8) | val;
10928490SPaul.Guo@Sun.COM IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, atlas_ctl);
10938490SPaul.Guo@Sun.COM IXGBE_WRITE_FLUSH(hw);
10948490SPaul.Guo@Sun.COM usec_delay(10);
10958490SPaul.Guo@Sun.COM
10968490SPaul.Guo@Sun.COM return (IXGBE_SUCCESS);
10978490SPaul.Guo@Sun.COM }
10988490SPaul.Guo@Sun.COM
10998490SPaul.Guo@Sun.COM /*
11009353SSamuel.Tu@Sun.COM * ixgbe_read_i2c_eeprom_82598 - Reads 8 bit word over I2C interface.
11018490SPaul.Guo@Sun.COM * @hw: pointer to hardware structure
11028490SPaul.Guo@Sun.COM * @byte_offset: EEPROM byte offset to read
11038490SPaul.Guo@Sun.COM * @eeprom_data: value read
11048490SPaul.Guo@Sun.COM *
11059353SSamuel.Tu@Sun.COM * Performs 8 byte read operation to SFP module's EEPROM over I2C interface.
11068490SPaul.Guo@Sun.COM */
11078490SPaul.Guo@Sun.COM s32
ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw * hw,u8 byte_offset,u8 * eeprom_data)11088490SPaul.Guo@Sun.COM ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
11098490SPaul.Guo@Sun.COM u8 *eeprom_data)
11108490SPaul.Guo@Sun.COM {
11118490SPaul.Guo@Sun.COM s32 status = IXGBE_SUCCESS;
11128490SPaul.Guo@Sun.COM u16 sfp_addr = 0;
11138490SPaul.Guo@Sun.COM u16 sfp_data = 0;
11148490SPaul.Guo@Sun.COM u16 sfp_stat = 0;
11158490SPaul.Guo@Sun.COM u32 i;
11168490SPaul.Guo@Sun.COM
111710998SChenlu.Chen@Sun.COM DEBUGFUNC("ixgbe_read_i2c_eeprom_82598");
111810998SChenlu.Chen@Sun.COM
11198490SPaul.Guo@Sun.COM if (hw->phy.type == ixgbe_phy_nl) {
11208490SPaul.Guo@Sun.COM /*
11218490SPaul.Guo@Sun.COM * NetLogic phy SDA/SCL registers are at addresses 0xC30A to
11228490SPaul.Guo@Sun.COM * 0xC30D. These registers are used to talk to the SFP+
11238490SPaul.Guo@Sun.COM * module's EEPROM through the SDA/SCL (I2C) interface.
11248490SPaul.Guo@Sun.COM */
11258490SPaul.Guo@Sun.COM sfp_addr = (IXGBE_I2C_EEPROM_DEV_ADDR << 8) + byte_offset;
11268490SPaul.Guo@Sun.COM sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK);
11278490SPaul.Guo@Sun.COM hw->phy.ops.write_reg(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR,
11288490SPaul.Guo@Sun.COM IXGBE_MDIO_PMA_PMD_DEV_TYPE, sfp_addr);
11298490SPaul.Guo@Sun.COM
11308490SPaul.Guo@Sun.COM /* Poll status */
11318490SPaul.Guo@Sun.COM for (i = 0; i < 100; i++) {
11328490SPaul.Guo@Sun.COM hw->phy.ops.read_reg(hw,
11338490SPaul.Guo@Sun.COM IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT,
11348490SPaul.Guo@Sun.COM IXGBE_MDIO_PMA_PMD_DEV_TYPE, &sfp_stat);
11358490SPaul.Guo@Sun.COM sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK;
11368490SPaul.Guo@Sun.COM if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS)
11378490SPaul.Guo@Sun.COM break;
11388490SPaul.Guo@Sun.COM msec_delay(10);
11398490SPaul.Guo@Sun.COM }
11408490SPaul.Guo@Sun.COM
11418490SPaul.Guo@Sun.COM if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_PASS) {
11428490SPaul.Guo@Sun.COM DEBUGOUT("EEPROM read did not pass.\n");
11438490SPaul.Guo@Sun.COM status = IXGBE_ERR_SFP_NOT_PRESENT;
11448490SPaul.Guo@Sun.COM goto out;
11458490SPaul.Guo@Sun.COM }
11468490SPaul.Guo@Sun.COM
11478490SPaul.Guo@Sun.COM /* Read data */
11488490SPaul.Guo@Sun.COM hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA,
11498490SPaul.Guo@Sun.COM IXGBE_MDIO_PMA_PMD_DEV_TYPE, &sfp_data);
11508490SPaul.Guo@Sun.COM
11518490SPaul.Guo@Sun.COM *eeprom_data = (u8)(sfp_data >> 8);
11528490SPaul.Guo@Sun.COM } else {
11538490SPaul.Guo@Sun.COM status = IXGBE_ERR_PHY;
11548490SPaul.Guo@Sun.COM goto out;
11558490SPaul.Guo@Sun.COM }
11568490SPaul.Guo@Sun.COM
11578490SPaul.Guo@Sun.COM out:
11588490SPaul.Guo@Sun.COM return (status);
11598490SPaul.Guo@Sun.COM }
11608490SPaul.Guo@Sun.COM
11618490SPaul.Guo@Sun.COM /*
11628490SPaul.Guo@Sun.COM * ixgbe_get_supported_physical_layer_82598 - Returns physical layer type
11638490SPaul.Guo@Sun.COM * @hw: pointer to hardware structure
11648490SPaul.Guo@Sun.COM *
11658490SPaul.Guo@Sun.COM * Determines physical layer capabilities of the current configuration.
11668490SPaul.Guo@Sun.COM */
11679353SSamuel.Tu@Sun.COM u32
ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw * hw)11688490SPaul.Guo@Sun.COM ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
11698490SPaul.Guo@Sun.COM {
11709353SSamuel.Tu@Sun.COM u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
11719353SSamuel.Tu@Sun.COM u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
11729353SSamuel.Tu@Sun.COM u32 pma_pmd_10g = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
11739353SSamuel.Tu@Sun.COM u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
11749353SSamuel.Tu@Sun.COM u16 ext_ability = 0;
11759353SSamuel.Tu@Sun.COM
117610998SChenlu.Chen@Sun.COM DEBUGFUNC("ixgbe_get_supported_physical_layer_82598");
117710998SChenlu.Chen@Sun.COM
11789353SSamuel.Tu@Sun.COM hw->phy.ops.identify(hw);
11798490SPaul.Guo@Sun.COM
11809353SSamuel.Tu@Sun.COM /*
11819353SSamuel.Tu@Sun.COM * Copper PHY must be checked before AUTOC LMS to determine correct
11829353SSamuel.Tu@Sun.COM * physical layer because 10GBase-T PHYs use LMS = KX4/KX
11839353SSamuel.Tu@Sun.COM */
11849353SSamuel.Tu@Sun.COM if (hw->phy.type == ixgbe_phy_tn ||
11859353SSamuel.Tu@Sun.COM hw->phy.type == ixgbe_phy_cu_unknown) {
11869353SSamuel.Tu@Sun.COM hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
11879353SSamuel.Tu@Sun.COM IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability);
11889353SSamuel.Tu@Sun.COM if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
11899353SSamuel.Tu@Sun.COM physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
11909353SSamuel.Tu@Sun.COM if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
11919353SSamuel.Tu@Sun.COM physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
11929353SSamuel.Tu@Sun.COM if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY)
11939353SSamuel.Tu@Sun.COM physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
11949353SSamuel.Tu@Sun.COM goto out;
11959353SSamuel.Tu@Sun.COM }
11969353SSamuel.Tu@Sun.COM
11979353SSamuel.Tu@Sun.COM switch (autoc & IXGBE_AUTOC_LMS_MASK) {
11989353SSamuel.Tu@Sun.COM case IXGBE_AUTOC_LMS_1G_AN:
11999353SSamuel.Tu@Sun.COM case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
12009353SSamuel.Tu@Sun.COM if (pma_pmd_1g == IXGBE_AUTOC_1G_KX)
12019353SSamuel.Tu@Sun.COM physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX;
12029353SSamuel.Tu@Sun.COM else
12039353SSamuel.Tu@Sun.COM physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX;
12048490SPaul.Guo@Sun.COM break;
12059353SSamuel.Tu@Sun.COM case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
12069353SSamuel.Tu@Sun.COM if (pma_pmd_10g == IXGBE_AUTOC_10G_CX4)
12079353SSamuel.Tu@Sun.COM physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
12089353SSamuel.Tu@Sun.COM else if (pma_pmd_10g == IXGBE_AUTOC_10G_KX4)
12099353SSamuel.Tu@Sun.COM physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
12109353SSamuel.Tu@Sun.COM else /* XAUI */
12119353SSamuel.Tu@Sun.COM physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
12128490SPaul.Guo@Sun.COM break;
12139353SSamuel.Tu@Sun.COM case IXGBE_AUTOC_LMS_KX4_AN:
12149353SSamuel.Tu@Sun.COM case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
12159353SSamuel.Tu@Sun.COM if (autoc & IXGBE_AUTOC_KX_SUPP)
12169353SSamuel.Tu@Sun.COM physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
12179353SSamuel.Tu@Sun.COM if (autoc & IXGBE_AUTOC_KX4_SUPP)
12189353SSamuel.Tu@Sun.COM physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
12198490SPaul.Guo@Sun.COM break;
12209353SSamuel.Tu@Sun.COM default:
12218490SPaul.Guo@Sun.COM break;
12229353SSamuel.Tu@Sun.COM }
12239353SSamuel.Tu@Sun.COM
12249353SSamuel.Tu@Sun.COM if (hw->phy.type == ixgbe_phy_nl) {
12258490SPaul.Guo@Sun.COM hw->phy.ops.identify_sfp(hw);
12268490SPaul.Guo@Sun.COM
12278490SPaul.Guo@Sun.COM switch (hw->phy.sfp_type) {
12288490SPaul.Guo@Sun.COM case ixgbe_sfp_type_da_cu:
12298490SPaul.Guo@Sun.COM physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
12308490SPaul.Guo@Sun.COM break;
12318490SPaul.Guo@Sun.COM case ixgbe_sfp_type_sr:
12328490SPaul.Guo@Sun.COM physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
12338490SPaul.Guo@Sun.COM break;
12348490SPaul.Guo@Sun.COM case ixgbe_sfp_type_lr:
12358490SPaul.Guo@Sun.COM physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
12368490SPaul.Guo@Sun.COM break;
12378490SPaul.Guo@Sun.COM default:
12388490SPaul.Guo@Sun.COM physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
12398490SPaul.Guo@Sun.COM break;
12408490SPaul.Guo@Sun.COM }
12419353SSamuel.Tu@Sun.COM }
12428490SPaul.Guo@Sun.COM
12439353SSamuel.Tu@Sun.COM switch (hw->device_id) {
12449353SSamuel.Tu@Sun.COM case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
12459353SSamuel.Tu@Sun.COM physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
12469353SSamuel.Tu@Sun.COM break;
12479353SSamuel.Tu@Sun.COM case IXGBE_DEV_ID_82598AF_DUAL_PORT:
12489353SSamuel.Tu@Sun.COM case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
12499353SSamuel.Tu@Sun.COM case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
12509353SSamuel.Tu@Sun.COM physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
12519353SSamuel.Tu@Sun.COM break;
12529353SSamuel.Tu@Sun.COM case IXGBE_DEV_ID_82598EB_XF_LR:
12539353SSamuel.Tu@Sun.COM physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
12549353SSamuel.Tu@Sun.COM break;
12558490SPaul.Guo@Sun.COM default:
12568490SPaul.Guo@Sun.COM break;
12578490SPaul.Guo@Sun.COM }
12588490SPaul.Guo@Sun.COM
12599353SSamuel.Tu@Sun.COM out:
12608490SPaul.Guo@Sun.COM return (physical_layer);
12618490SPaul.Guo@Sun.COM }
126210305SPaul.Guo@Sun.COM
126310305SPaul.Guo@Sun.COM /*
126410305SPaul.Guo@Sun.COM * ixgbe_set_lan_id_multi_port_pcie_82598 - Set LAN id for PCIe multiple
126510305SPaul.Guo@Sun.COM * port devices.
126610305SPaul.Guo@Sun.COM * @hw: pointer to the HW structure
126710305SPaul.Guo@Sun.COM *
126810305SPaul.Guo@Sun.COM * Calls common function and corrects issue with some single port devices
126910305SPaul.Guo@Sun.COM * that enable LAN1 but not LAN0.
127010305SPaul.Guo@Sun.COM */
127110305SPaul.Guo@Sun.COM void
ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw * hw)127210305SPaul.Guo@Sun.COM ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw)
127310305SPaul.Guo@Sun.COM {
127410305SPaul.Guo@Sun.COM struct ixgbe_bus_info *bus = &hw->bus;
127510305SPaul.Guo@Sun.COM u16 pci_gen, pci_ctrl2;
127610305SPaul.Guo@Sun.COM
127710998SChenlu.Chen@Sun.COM DEBUGFUNC("ixgbe_set_lan_id_multi_port_pcie_82598");
127810998SChenlu.Chen@Sun.COM
127910305SPaul.Guo@Sun.COM ixgbe_set_lan_id_multi_port_pcie(hw);
128010305SPaul.Guo@Sun.COM
128110305SPaul.Guo@Sun.COM /* check if LAN0 is disabled */
128210305SPaul.Guo@Sun.COM hw->eeprom.ops.read(hw, IXGBE_PCIE_GENERAL_PTR, &pci_gen);
128310305SPaul.Guo@Sun.COM if ((pci_gen != 0) && (pci_gen != 0xFFFF)) {
128410305SPaul.Guo@Sun.COM hw->eeprom.ops.read(hw, pci_gen + IXGBE_PCIE_CTRL2, &pci_ctrl2);
128510305SPaul.Guo@Sun.COM
128610305SPaul.Guo@Sun.COM /* if LAN0 is completely disabled force function to 0 */
128710305SPaul.Guo@Sun.COM if ((pci_ctrl2 & IXGBE_PCIE_CTRL2_LAN_DISABLE) &&
128810305SPaul.Guo@Sun.COM !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DISABLE_SELECT) &&
128910305SPaul.Guo@Sun.COM !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DUMMY_ENABLE)) {
129010305SPaul.Guo@Sun.COM bus->func = 0;
129110305SPaul.Guo@Sun.COM }
129210305SPaul.Guo@Sun.COM }
129310305SPaul.Guo@Sun.COM }
129412003SPaul.Guo@Sun.COM
129512003SPaul.Guo@Sun.COM /*
129612003SPaul.Guo@Sun.COM * ixgbe_validate_link_ready - Function looks for phy link
129712003SPaul.Guo@Sun.COM * @hw: pointer to hardware structure
129812003SPaul.Guo@Sun.COM *
129912003SPaul.Guo@Sun.COM * Function indicates success when phy link is available. If phy is not ready
130012003SPaul.Guo@Sun.COM * within 5 seconds of MAC indicating link, the function returns error.
130112003SPaul.Guo@Sun.COM */
130212003SPaul.Guo@Sun.COM static s32
ixgbe_validate_link_ready(struct ixgbe_hw * hw)130312003SPaul.Guo@Sun.COM ixgbe_validate_link_ready(struct ixgbe_hw *hw)
130412003SPaul.Guo@Sun.COM {
130512003SPaul.Guo@Sun.COM u32 timeout;
130612003SPaul.Guo@Sun.COM u16 an_reg;
130712003SPaul.Guo@Sun.COM
130812003SPaul.Guo@Sun.COM if (hw->device_id != IXGBE_DEV_ID_82598AT2)
130912003SPaul.Guo@Sun.COM return (IXGBE_SUCCESS);
131012003SPaul.Guo@Sun.COM
131112003SPaul.Guo@Sun.COM for (timeout = 0;
131212003SPaul.Guo@Sun.COM timeout < IXGBE_VALIDATE_LINK_READY_TIMEOUT; timeout++) {
131312003SPaul.Guo@Sun.COM hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
131412003SPaul.Guo@Sun.COM IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &an_reg);
131512003SPaul.Guo@Sun.COM
131612003SPaul.Guo@Sun.COM if ((an_reg & IXGBE_MII_AUTONEG_COMPLETE) &&
131712003SPaul.Guo@Sun.COM (an_reg & IXGBE_MII_AUTONEG_LINK_UP))
131812003SPaul.Guo@Sun.COM break;
131912003SPaul.Guo@Sun.COM
132012003SPaul.Guo@Sun.COM msec_delay(100);
132112003SPaul.Guo@Sun.COM }
132212003SPaul.Guo@Sun.COM
132312003SPaul.Guo@Sun.COM if (timeout == IXGBE_VALIDATE_LINK_READY_TIMEOUT) {
132412003SPaul.Guo@Sun.COM DEBUGOUT("Link was indicated but link is down\n");
132512003SPaul.Guo@Sun.COM return (IXGBE_ERR_LINK_SETUP);
132612003SPaul.Guo@Sun.COM }
132712003SPaul.Guo@Sun.COM
132812003SPaul.Guo@Sun.COM return (IXGBE_SUCCESS);
132912003SPaul.Guo@Sun.COM }
133012003SPaul.Guo@Sun.COM
133112003SPaul.Guo@Sun.COM /*
133212003SPaul.Guo@Sun.COM * ixgbe_enable_relaxed_ordering_82598 - enable relaxed ordering
133312003SPaul.Guo@Sun.COM * @hw: pointer to hardware structure
133412003SPaul.Guo@Sun.COM */
133512003SPaul.Guo@Sun.COM void
ixgbe_enable_relaxed_ordering_82598(struct ixgbe_hw * hw)133612003SPaul.Guo@Sun.COM ixgbe_enable_relaxed_ordering_82598(struct ixgbe_hw *hw)
133712003SPaul.Guo@Sun.COM {
133812003SPaul.Guo@Sun.COM u32 regval;
133912003SPaul.Guo@Sun.COM u32 i;
134012003SPaul.Guo@Sun.COM
134112003SPaul.Guo@Sun.COM DEBUGFUNC("ixgbe_enable_relaxed_ordering_82598");
134212003SPaul.Guo@Sun.COM
134312003SPaul.Guo@Sun.COM /* Enable relaxed ordering */
134412003SPaul.Guo@Sun.COM for (i = 0; ((i < hw->mac.max_tx_queues) &&
134512003SPaul.Guo@Sun.COM (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
134612003SPaul.Guo@Sun.COM regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
134712003SPaul.Guo@Sun.COM regval |= IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
134812003SPaul.Guo@Sun.COM IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval);
134912003SPaul.Guo@Sun.COM }
135012003SPaul.Guo@Sun.COM
135112003SPaul.Guo@Sun.COM for (i = 0; ((i < hw->mac.max_rx_queues) &&
135212003SPaul.Guo@Sun.COM (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
135312003SPaul.Guo@Sun.COM regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
135412003SPaul.Guo@Sun.COM regval |= (IXGBE_DCA_RXCTRL_DESC_WRO_EN |
135512003SPaul.Guo@Sun.COM IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
135612003SPaul.Guo@Sun.COM IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
135712003SPaul.Guo@Sun.COM }
135812003SPaul.Guo@Sun.COM }
1359