163b3bba8SJerry Jelinek /******************************************************************************
248ed61a7SRobert Mustacchi SPDX-License-Identifier: BSD-3-Clause
363b3bba8SJerry Jelinek
448ed61a7SRobert Mustacchi Copyright (c) 2001-2017, Intel Corporation
563b3bba8SJerry Jelinek All rights reserved.
648ed61a7SRobert Mustacchi
748ed61a7SRobert Mustacchi Redistribution and use in source and binary forms, with or without
863b3bba8SJerry Jelinek modification, are permitted provided that the following conditions are met:
948ed61a7SRobert Mustacchi
1048ed61a7SRobert Mustacchi 1. Redistributions of source code must retain the above copyright notice,
1163b3bba8SJerry Jelinek this list of conditions and the following disclaimer.
1248ed61a7SRobert Mustacchi
1348ed61a7SRobert Mustacchi 2. Redistributions in binary form must reproduce the above copyright
1448ed61a7SRobert Mustacchi notice, this list of conditions and the following disclaimer in the
1563b3bba8SJerry Jelinek documentation and/or other materials provided with the distribution.
1648ed61a7SRobert Mustacchi
1748ed61a7SRobert Mustacchi 3. Neither the name of the Intel Corporation nor the names of its
1848ed61a7SRobert Mustacchi contributors may be used to endorse or promote products derived from
1963b3bba8SJerry Jelinek this software without specific prior written permission.
2048ed61a7SRobert Mustacchi
2163b3bba8SJerry Jelinek THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2248ed61a7SRobert Mustacchi AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2348ed61a7SRobert Mustacchi IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2448ed61a7SRobert Mustacchi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2548ed61a7SRobert Mustacchi LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2648ed61a7SRobert Mustacchi CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2748ed61a7SRobert Mustacchi SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2848ed61a7SRobert Mustacchi INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2948ed61a7SRobert Mustacchi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3063b3bba8SJerry Jelinek ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3163b3bba8SJerry Jelinek POSSIBILITY OF SUCH DAMAGE.
3263b3bba8SJerry Jelinek
3363b3bba8SJerry Jelinek ******************************************************************************/
34dc0cb1cdSDale Ghent /*$FreeBSD$*/
359da57d7bSbt
369da57d7bSbt #include "ixgbe_type.h"
3769b5a878SDan McDonald #include "ixgbe_82598.h"
389da57d7bSbt #include "ixgbe_api.h"
399da57d7bSbt #include "ixgbe_common.h"
409da57d7bSbt #include "ixgbe_phy.h"
419da57d7bSbt
42dc0cb1cdSDale Ghent #define IXGBE_82598_MAX_TX_QUEUES 32
43dc0cb1cdSDale Ghent #define IXGBE_82598_MAX_RX_QUEUES 64
44dc0cb1cdSDale Ghent #define IXGBE_82598_RAR_ENTRIES 16
45dc0cb1cdSDale Ghent #define IXGBE_82598_MC_TBL_SIZE 128
46dc0cb1cdSDale Ghent #define IXGBE_82598_VFT_TBL_SIZE 128
47dc0cb1cdSDale Ghent #define IXGBE_82598_RX_PB_SIZE 512
48dc0cb1cdSDale Ghent
4913740cb2SPaul Guo static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
5069b5a878SDan McDonald ixgbe_link_speed *speed,
5169b5a878SDan McDonald bool *autoneg);
5213740cb2SPaul Guo static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw);
533cfa0eb9Schenlu chen - Sun Microsystems - Beijing China static s32 ixgbe_start_mac_link_82598(struct ixgbe_hw *hw,
5469b5a878SDan McDonald bool autoneg_wait_to_complete);
5513740cb2SPaul Guo static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
5669b5a878SDan McDonald ixgbe_link_speed *speed, bool *link_up,
5769b5a878SDan McDonald bool link_up_wait_to_complete);
583cfa0eb9Schenlu chen - Sun Microsystems - Beijing China static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
5969b5a878SDan McDonald ixgbe_link_speed speed,
6069b5a878SDan McDonald bool autoneg_wait_to_complete);
613cfa0eb9Schenlu chen - Sun Microsystems - Beijing China static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
6269b5a878SDan McDonald ixgbe_link_speed speed,
6369b5a878SDan McDonald bool autoneg_wait_to_complete);
6413740cb2SPaul Guo static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw);
6513740cb2SPaul Guo static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
6613740cb2SPaul Guo static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw);
6769b5a878SDan McDonald static void ixgbe_set_rxpba_82598(struct ixgbe_hw *hw, int num_pb,
6869b5a878SDan McDonald u32 headroom, int strategy);
69dc0cb1cdSDale Ghent static s32 ixgbe_read_i2c_sff8472_82598(struct ixgbe_hw *hw, u8 byte_offset,
70dc0cb1cdSDale Ghent u8 *sff8472_data);
7163b3bba8SJerry Jelinek /**
7263b3bba8SJerry Jelinek * ixgbe_set_pcie_completion_timeout - set pci-e completion timeout
7363b3bba8SJerry Jelinek * @hw: pointer to the HW structure
743cfa0eb9Schenlu chen - Sun Microsystems - Beijing China *
7563b3bba8SJerry Jelinek * The defaults for 82598 should be in the range of 50us to 50ms,
7663b3bba8SJerry Jelinek * however the hardware default for these parts is 500us to 1ms which is less
7763b3bba8SJerry Jelinek * than the 10ms recommended by the pci-e spec. To address this we need to
7863b3bba8SJerry Jelinek * increase the value to either 10ms to 250ms for capability version 1 config,
7963b3bba8SJerry Jelinek * or 16ms to 55ms for version 2.
8063b3bba8SJerry Jelinek **/
ixgbe_set_pcie_completion_timeout(struct ixgbe_hw * hw)8163b3bba8SJerry Jelinek void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw)
823cfa0eb9Schenlu chen - Sun Microsystems - Beijing China {
833cfa0eb9Schenlu chen - Sun Microsystems - Beijing China u32 gcr = IXGBE_READ_REG(hw, IXGBE_GCR);
843cfa0eb9Schenlu chen - Sun Microsystems - Beijing China u16 pcie_devctl2;
853cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
863cfa0eb9Schenlu chen - Sun Microsystems - Beijing China /* only take action if timeout value is defaulted to 0 */
873cfa0eb9Schenlu chen - Sun Microsystems - Beijing China if (gcr & IXGBE_GCR_CMPL_TMOUT_MASK)
883cfa0eb9Schenlu chen - Sun Microsystems - Beijing China goto out;
893cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
903cfa0eb9Schenlu chen - Sun Microsystems - Beijing China /*
913cfa0eb9Schenlu chen - Sun Microsystems - Beijing China * if capababilities version is type 1 we can write the
923cfa0eb9Schenlu chen - Sun Microsystems - Beijing China * timeout of 10ms to 250ms through the GCR register
933cfa0eb9Schenlu chen - Sun Microsystems - Beijing China */
943cfa0eb9Schenlu chen - Sun Microsystems - Beijing China if (!(gcr & IXGBE_GCR_CAP_VER2)) {
953cfa0eb9Schenlu chen - Sun Microsystems - Beijing China gcr |= IXGBE_GCR_CMPL_TMOUT_10ms;
963cfa0eb9Schenlu chen - Sun Microsystems - Beijing China goto out;
973cfa0eb9Schenlu chen - Sun Microsystems - Beijing China }
983cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
993cfa0eb9Schenlu chen - Sun Microsystems - Beijing China /*
1003cfa0eb9Schenlu chen - Sun Microsystems - Beijing China * for version 2 capabilities we need to write the config space
1013cfa0eb9Schenlu chen - Sun Microsystems - Beijing China * directly in order to set the completion timeout value for
1023cfa0eb9Schenlu chen - Sun Microsystems - Beijing China * 16ms to 55ms
1033cfa0eb9Schenlu chen - Sun Microsystems - Beijing China */
1043cfa0eb9Schenlu chen - Sun Microsystems - Beijing China pcie_devctl2 = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2);
1053cfa0eb9Schenlu chen - Sun Microsystems - Beijing China pcie_devctl2 |= IXGBE_PCI_DEVICE_CONTROL2_16ms;
1063cfa0eb9Schenlu chen - Sun Microsystems - Beijing China IXGBE_WRITE_PCIE_WORD(hw, IXGBE_PCI_DEVICE_CONTROL2, pcie_devctl2);
1073cfa0eb9Schenlu chen - Sun Microsystems - Beijing China out:
1083cfa0eb9Schenlu chen - Sun Microsystems - Beijing China /* disable completion timeout resend */
1093cfa0eb9Schenlu chen - Sun Microsystems - Beijing China gcr &= ~IXGBE_GCR_CMPL_TMOUT_RESEND;
1103cfa0eb9Schenlu chen - Sun Microsystems - Beijing China IXGBE_WRITE_REG(hw, IXGBE_GCR, gcr);
1113cfa0eb9Schenlu chen - Sun Microsystems - Beijing China }
11273cd555cSBin Tu - Sun Microsystems - Beijing China
11363b3bba8SJerry Jelinek /**
11463b3bba8SJerry Jelinek * ixgbe_init_ops_82598 - Inits func ptrs and MAC type
11563b3bba8SJerry Jelinek * @hw: pointer to hardware structure
1169da57d7bSbt *
11763b3bba8SJerry Jelinek * Initialize the function pointers and assign the MAC type for 82598.
11863b3bba8SJerry Jelinek * Does not touch the hardware.
11963b3bba8SJerry Jelinek **/
ixgbe_init_ops_82598(struct ixgbe_hw * hw)12063b3bba8SJerry Jelinek s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw)
1219da57d7bSbt {
1229da57d7bSbt struct ixgbe_mac_info *mac = &hw->mac;
12313740cb2SPaul Guo struct ixgbe_phy_info *phy = &hw->phy;
12473cd555cSBin Tu - Sun Microsystems - Beijing China s32 ret_val;
1259da57d7bSbt
1263cfa0eb9Schenlu chen - Sun Microsystems - Beijing China DEBUGFUNC("ixgbe_init_ops_82598");
1273cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
12873cd555cSBin Tu - Sun Microsystems - Beijing China ret_val = ixgbe_init_phy_ops_generic(hw);
12973cd555cSBin Tu - Sun Microsystems - Beijing China ret_val = ixgbe_init_ops_generic(hw);
13073cd555cSBin Tu - Sun Microsystems - Beijing China
13173cd555cSBin Tu - Sun Microsystems - Beijing China /* PHY */
132dc0cb1cdSDale Ghent phy->ops.init = ixgbe_init_phy_ops_82598;
1339da57d7bSbt
1349da57d7bSbt /* MAC */
135dc0cb1cdSDale Ghent mac->ops.start_hw = ixgbe_start_hw_82598;
136dc0cb1cdSDale Ghent mac->ops.enable_relaxed_ordering = ixgbe_enable_relaxed_ordering_82598;
137dc0cb1cdSDale Ghent mac->ops.reset_hw = ixgbe_reset_hw_82598;
138dc0cb1cdSDale Ghent mac->ops.get_media_type = ixgbe_get_media_type_82598;
13913740cb2SPaul Guo mac->ops.get_supported_physical_layer =
140dc0cb1cdSDale Ghent ixgbe_get_supported_physical_layer_82598;
141dc0cb1cdSDale Ghent mac->ops.read_analog_reg8 = ixgbe_read_analog_reg8_82598;
142dc0cb1cdSDale Ghent mac->ops.write_analog_reg8 = ixgbe_write_analog_reg8_82598;
143dc0cb1cdSDale Ghent mac->ops.set_lan_id = ixgbe_set_lan_id_multi_port_pcie_82598;
144dc0cb1cdSDale Ghent mac->ops.enable_rx_dma = ixgbe_enable_rx_dma_82598;
1459da57d7bSbt
1469da57d7bSbt /* RAR, Multicast, VLAN */
147dc0cb1cdSDale Ghent mac->ops.set_vmdq = ixgbe_set_vmdq_82598;
148dc0cb1cdSDale Ghent mac->ops.clear_vmdq = ixgbe_clear_vmdq_82598;
149dc0cb1cdSDale Ghent mac->ops.set_vfta = ixgbe_set_vfta_82598;
15069b5a878SDan McDonald mac->ops.set_vlvf = NULL;
151dc0cb1cdSDale Ghent mac->ops.clear_vfta = ixgbe_clear_vfta_82598;
1529da57d7bSbt
1539da57d7bSbt /* Flow Control */
154dc0cb1cdSDale Ghent mac->ops.fc_enable = ixgbe_fc_enable_82598;
155dc0cb1cdSDale Ghent
156dc0cb1cdSDale Ghent mac->mcft_size = IXGBE_82598_MC_TBL_SIZE;
157dc0cb1cdSDale Ghent mac->vft_size = IXGBE_82598_VFT_TBL_SIZE;
158dc0cb1cdSDale Ghent mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES;
159dc0cb1cdSDale Ghent mac->rx_pb_size = IXGBE_82598_RX_PB_SIZE;
160dc0cb1cdSDale Ghent mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
161dc0cb1cdSDale Ghent mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
16269b5a878SDan McDonald mac->max_msix_vectors = ixgbe_get_pcie_msix_count_generic(hw);
1639da57d7bSbt
16413740cb2SPaul Guo /* SFP+ Module */
165dc0cb1cdSDale Ghent phy->ops.read_i2c_eeprom = ixgbe_read_i2c_eeprom_82598;
166dc0cb1cdSDale Ghent phy->ops.read_i2c_sff8472 = ixgbe_read_i2c_sff8472_82598;
16713740cb2SPaul Guo
16873cd555cSBin Tu - Sun Microsystems - Beijing China /* Link */
169dc0cb1cdSDale Ghent mac->ops.check_link = ixgbe_check_mac_link_82598;
170dc0cb1cdSDale Ghent mac->ops.setup_link = ixgbe_setup_mac_link_82598;
1715b6dd21fSchenlu chen - Sun Microsystems - Beijing China mac->ops.flap_tx_laser = NULL;
172dc0cb1cdSDale Ghent mac->ops.get_link_capabilities = ixgbe_get_link_capabilities_82598;
173dc0cb1cdSDale Ghent mac->ops.setup_rxpba = ixgbe_set_rxpba_82598;
17469b5a878SDan McDonald
17569b5a878SDan McDonald /* Manageability interface */
17669b5a878SDan McDonald mac->ops.set_fw_drv_ver = NULL;
17773cd555cSBin Tu - Sun Microsystems - Beijing China
178dc0cb1cdSDale Ghent mac->ops.get_rtrup2tc = NULL;
179dc0cb1cdSDale Ghent
18063b3bba8SJerry Jelinek return ret_val;
18173cd555cSBin Tu - Sun Microsystems - Beijing China }
18273cd555cSBin Tu - Sun Microsystems - Beijing China
18363b3bba8SJerry Jelinek /**
18463b3bba8SJerry Jelinek * ixgbe_init_phy_ops_82598 - PHY/SFP specific init
18563b3bba8SJerry Jelinek * @hw: pointer to hardware structure
18673cd555cSBin Tu - Sun Microsystems - Beijing China *
18763b3bba8SJerry Jelinek * Initialize any function pointers that were not able to be
18863b3bba8SJerry Jelinek * set during init_shared_code because the PHY/SFP type was
18963b3bba8SJerry Jelinek * not known. Perform the SFP init if necessary.
19073cd555cSBin Tu - Sun Microsystems - Beijing China *
19163b3bba8SJerry Jelinek **/
ixgbe_init_phy_ops_82598(struct ixgbe_hw * hw)19263b3bba8SJerry Jelinek s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw)
19373cd555cSBin Tu - Sun Microsystems - Beijing China {
19473cd555cSBin Tu - Sun Microsystems - Beijing China struct ixgbe_mac_info *mac = &hw->mac;
19573cd555cSBin Tu - Sun Microsystems - Beijing China struct ixgbe_phy_info *phy = &hw->phy;
19673cd555cSBin Tu - Sun Microsystems - Beijing China s32 ret_val = IXGBE_SUCCESS;
19773cd555cSBin Tu - Sun Microsystems - Beijing China u16 list_offset, data_offset;
19873cd555cSBin Tu - Sun Microsystems - Beijing China
1993cfa0eb9Schenlu chen - Sun Microsystems - Beijing China DEBUGFUNC("ixgbe_init_phy_ops_82598");
2003cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
20173cd555cSBin Tu - Sun Microsystems - Beijing China /* Identify the PHY */
20273cd555cSBin Tu - Sun Microsystems - Beijing China phy->ops.identify(hw);
20373cd555cSBin Tu - Sun Microsystems - Beijing China
20473cd555cSBin Tu - Sun Microsystems - Beijing China /* Overwrite the link function pointers if copper PHY */
20573cd555cSBin Tu - Sun Microsystems - Beijing China if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
206dc0cb1cdSDale Ghent mac->ops.setup_link = ixgbe_setup_copper_link_82598;
20773cd555cSBin Tu - Sun Microsystems - Beijing China mac->ops.get_link_capabilities =
208dc0cb1cdSDale Ghent ixgbe_get_copper_link_capabilities_generic;
20973cd555cSBin Tu - Sun Microsystems - Beijing China }
21073cd555cSBin Tu - Sun Microsystems - Beijing China
21113740cb2SPaul Guo switch (hw->phy.type) {
21213740cb2SPaul Guo case ixgbe_phy_tn:
213dc0cb1cdSDale Ghent phy->ops.setup_link = ixgbe_setup_phy_link_tnx;
214dc0cb1cdSDale Ghent phy->ops.check_link = ixgbe_check_phy_link_tnx;
21513740cb2SPaul Guo phy->ops.get_firmware_version =
216dc0cb1cdSDale Ghent ixgbe_get_phy_firmware_version_tnx;
217185c5677SPaul Guo break;
21813740cb2SPaul Guo case ixgbe_phy_nl:
219dc0cb1cdSDale Ghent phy->ops.reset = ixgbe_reset_phy_nl;
22013740cb2SPaul Guo
22113740cb2SPaul Guo /* Call SFP+ identify routine to get the SFP+ module type */
22213740cb2SPaul Guo ret_val = phy->ops.identify_sfp(hw);
22313740cb2SPaul Guo if (ret_val != IXGBE_SUCCESS)
22413740cb2SPaul Guo goto out;
22513740cb2SPaul Guo else if (hw->phy.sfp_type == ixgbe_sfp_type_unknown) {
22613740cb2SPaul Guo ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED;
22713740cb2SPaul Guo goto out;
22813740cb2SPaul Guo }
22913740cb2SPaul Guo
23013740cb2SPaul Guo /* Check to see if SFP+ module is supported */
23113740cb2SPaul Guo ret_val = ixgbe_get_sfp_init_sequence_offsets(hw,
23269b5a878SDan McDonald &list_offset,
23369b5a878SDan McDonald &data_offset);
23413740cb2SPaul Guo if (ret_val != IXGBE_SUCCESS) {
23513740cb2SPaul Guo ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED;
23613740cb2SPaul Guo goto out;
23713740cb2SPaul Guo }
23813740cb2SPaul Guo break;
23913740cb2SPaul Guo default:
24013740cb2SPaul Guo break;
24113740cb2SPaul Guo }
24263b3bba8SJerry Jelinek
24313740cb2SPaul Guo out:
24463b3bba8SJerry Jelinek return ret_val;
2459da57d7bSbt }
2469da57d7bSbt
24763b3bba8SJerry Jelinek /**
24863b3bba8SJerry Jelinek * ixgbe_start_hw_82598 - Prepare hardware for Tx/Rx
24963b3bba8SJerry Jelinek * @hw: pointer to hardware structure
25063b3bba8SJerry Jelinek *
25163b3bba8SJerry Jelinek * Starts the hardware using the generic start_hw function.
25263b3bba8SJerry Jelinek * Disables relaxed ordering Then set pcie completion timeout
2533cfa0eb9Schenlu chen - Sun Microsystems - Beijing China *
25463b3bba8SJerry Jelinek **/
ixgbe_start_hw_82598(struct ixgbe_hw * hw)25563b3bba8SJerry Jelinek s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw)
2563cfa0eb9Schenlu chen - Sun Microsystems - Beijing China {
25719843f01SPaul Guo u32 regval;
25819843f01SPaul Guo u32 i;
2593cfa0eb9Schenlu chen - Sun Microsystems - Beijing China s32 ret_val = IXGBE_SUCCESS;
2603cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
2613cfa0eb9Schenlu chen - Sun Microsystems - Beijing China DEBUGFUNC("ixgbe_start_hw_82598");
2623cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
2633cfa0eb9Schenlu chen - Sun Microsystems - Beijing China ret_val = ixgbe_start_hw_generic(hw);
264dc0cb1cdSDale Ghent if (ret_val)
265dc0cb1cdSDale Ghent return ret_val;
2663cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
26763b3bba8SJerry Jelinek /* Disable relaxed ordering */
26819843f01SPaul Guo for (i = 0; ((i < hw->mac.max_tx_queues) &&
26963b3bba8SJerry Jelinek (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
27019843f01SPaul Guo regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
27169b5a878SDan McDonald regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN;
27219843f01SPaul Guo IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval);
27319843f01SPaul Guo }
27419843f01SPaul Guo
27519843f01SPaul Guo for (i = 0; ((i < hw->mac.max_rx_queues) &&
27663b3bba8SJerry Jelinek (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
27719843f01SPaul Guo regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
27869b5a878SDan McDonald regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN |
27969b5a878SDan McDonald IXGBE_DCA_RXCTRL_HEAD_WRO_EN);
28019843f01SPaul Guo IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
28119843f01SPaul Guo }
28219843f01SPaul Guo
2833cfa0eb9Schenlu chen - Sun Microsystems - Beijing China /* set the completion timeout for interface */
284dc0cb1cdSDale Ghent ixgbe_set_pcie_completion_timeout(hw);
2853cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
28663b3bba8SJerry Jelinek return ret_val;
2873cfa0eb9Schenlu chen - Sun Microsystems - Beijing China }
2883cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
28963b3bba8SJerry Jelinek /**
29063b3bba8SJerry Jelinek * ixgbe_get_link_capabilities_82598 - Determines link capabilities
29163b3bba8SJerry Jelinek * @hw: pointer to hardware structure
29263b3bba8SJerry Jelinek * @speed: pointer to link speed
29363b3bba8SJerry Jelinek * @autoneg: boolean auto-negotiation value
2949da57d7bSbt *
29563b3bba8SJerry Jelinek * Determines the link capabilities by reading the AUTOC register.
29663b3bba8SJerry Jelinek **/
ixgbe_get_link_capabilities_82598(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * autoneg)29763b3bba8SJerry Jelinek static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
29869b5a878SDan McDonald ixgbe_link_speed *speed,
29969b5a878SDan McDonald bool *autoneg)
3009da57d7bSbt {
3019da57d7bSbt s32 status = IXGBE_SUCCESS;
30273cd555cSBin Tu - Sun Microsystems - Beijing China u32 autoc = 0;
3039da57d7bSbt
3043cfa0eb9Schenlu chen - Sun Microsystems - Beijing China DEBUGFUNC("ixgbe_get_link_capabilities_82598");
3053cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
30673cd555cSBin Tu - Sun Microsystems - Beijing China /*
30773cd555cSBin Tu - Sun Microsystems - Beijing China * Determine link capabilities based on the stored value of AUTOC,
30873cd555cSBin Tu - Sun Microsystems - Beijing China * which represents EEPROM defaults. If AUTOC value has not been
30973cd555cSBin Tu - Sun Microsystems - Beijing China * stored, use the current register value.
31073cd555cSBin Tu - Sun Microsystems - Beijing China */
31173cd555cSBin Tu - Sun Microsystems - Beijing China if (hw->mac.orig_link_settings_stored)
31273cd555cSBin Tu - Sun Microsystems - Beijing China autoc = hw->mac.orig_autoc;
31373cd555cSBin Tu - Sun Microsystems - Beijing China else
31473cd555cSBin Tu - Sun Microsystems - Beijing China autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
3159da57d7bSbt
31673cd555cSBin Tu - Sun Microsystems - Beijing China switch (autoc & IXGBE_AUTOC_LMS_MASK) {
3179da57d7bSbt case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
3189da57d7bSbt *speed = IXGBE_LINK_SPEED_1GB_FULL;
31963b3bba8SJerry Jelinek *autoneg = FALSE;
3209da57d7bSbt break;
3219da57d7bSbt
3229da57d7bSbt case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
3239da57d7bSbt *speed = IXGBE_LINK_SPEED_10GB_FULL;
32463b3bba8SJerry Jelinek *autoneg = FALSE;
3259da57d7bSbt break;
3269da57d7bSbt
3279da57d7bSbt case IXGBE_AUTOC_LMS_1G_AN:
3289da57d7bSbt *speed = IXGBE_LINK_SPEED_1GB_FULL;
32963b3bba8SJerry Jelinek *autoneg = TRUE;
3309da57d7bSbt break;
3319da57d7bSbt
3329da57d7bSbt case IXGBE_AUTOC_LMS_KX4_AN:
3339da57d7bSbt case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
3349da57d7bSbt *speed = IXGBE_LINK_SPEED_UNKNOWN;
33573cd555cSBin Tu - Sun Microsystems - Beijing China if (autoc & IXGBE_AUTOC_KX4_SUPP)
3369da57d7bSbt *speed |= IXGBE_LINK_SPEED_10GB_FULL;
33773cd555cSBin Tu - Sun Microsystems - Beijing China if (autoc & IXGBE_AUTOC_KX_SUPP)
3389da57d7bSbt *speed |= IXGBE_LINK_SPEED_1GB_FULL;
33963b3bba8SJerry Jelinek *autoneg = TRUE;
3409da57d7bSbt break;
3419da57d7bSbt
3429da57d7bSbt default:
3439da57d7bSbt status = IXGBE_ERR_LINK_SETUP;
3449da57d7bSbt break;
3459da57d7bSbt }
3469da57d7bSbt
34763b3bba8SJerry Jelinek return status;
3489da57d7bSbt }
3499da57d7bSbt
35063b3bba8SJerry Jelinek /**
35163b3bba8SJerry Jelinek * ixgbe_get_media_type_82598 - Determines media type
35263b3bba8SJerry Jelinek * @hw: pointer to hardware structure
3539da57d7bSbt *
35463b3bba8SJerry Jelinek * Returns the media type (fiber, copper, backplane)
35563b3bba8SJerry Jelinek **/
ixgbe_get_media_type_82598(struct ixgbe_hw * hw)35663b3bba8SJerry Jelinek static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
3579da57d7bSbt {
3589da57d7bSbt enum ixgbe_media_type media_type;
3599da57d7bSbt
3603cfa0eb9Schenlu chen - Sun Microsystems - Beijing China DEBUGFUNC("ixgbe_get_media_type_82598");
3613cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
36273cd555cSBin Tu - Sun Microsystems - Beijing China /* Detect if there is a copper PHY attached. */
36363b3bba8SJerry Jelinek switch (hw->phy.type) {
36463b3bba8SJerry Jelinek case ixgbe_phy_cu_unknown:
36563b3bba8SJerry Jelinek case ixgbe_phy_tn:
36673cd555cSBin Tu - Sun Microsystems - Beijing China media_type = ixgbe_media_type_copper;
36773cd555cSBin Tu - Sun Microsystems - Beijing China goto out;
36863b3bba8SJerry Jelinek default:
36963b3bba8SJerry Jelinek break;
37073cd555cSBin Tu - Sun Microsystems - Beijing China }
37173cd555cSBin Tu - Sun Microsystems - Beijing China
3729da57d7bSbt /* Media type for I82598 is based on device ID */
3739da57d7bSbt switch (hw->device_id) {
37473cd555cSBin Tu - Sun Microsystems - Beijing China case IXGBE_DEV_ID_82598:
37573cd555cSBin Tu - Sun Microsystems - Beijing China case IXGBE_DEV_ID_82598_BX:
37673cd555cSBin Tu - Sun Microsystems - Beijing China /* Default device ID is mezzanine card KX/KX4 */
37773cd555cSBin Tu - Sun Microsystems - Beijing China media_type = ixgbe_media_type_backplane;
37873cd555cSBin Tu - Sun Microsystems - Beijing China break;
3799da57d7bSbt case IXGBE_DEV_ID_82598AF_DUAL_PORT:
3809da57d7bSbt case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
38113740cb2SPaul Guo case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
38213740cb2SPaul Guo case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
3839da57d7bSbt case IXGBE_DEV_ID_82598EB_XF_LR:
38413740cb2SPaul Guo case IXGBE_DEV_ID_82598EB_SFP_LOM:
3859da57d7bSbt media_type = ixgbe_media_type_fiber;
3869da57d7bSbt break;
3873cfa0eb9Schenlu chen - Sun Microsystems - Beijing China case IXGBE_DEV_ID_82598EB_CX4:
3883cfa0eb9Schenlu chen - Sun Microsystems - Beijing China case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
3893cfa0eb9Schenlu chen - Sun Microsystems - Beijing China media_type = ixgbe_media_type_cx4;
3903cfa0eb9Schenlu chen - Sun Microsystems - Beijing China break;
39113740cb2SPaul Guo case IXGBE_DEV_ID_82598AT:
3923cfa0eb9Schenlu chen - Sun Microsystems - Beijing China case IXGBE_DEV_ID_82598AT2:
39313740cb2SPaul Guo media_type = ixgbe_media_type_copper;
39413740cb2SPaul Guo break;
3959da57d7bSbt default:
3969da57d7bSbt media_type = ixgbe_media_type_unknown;
3979da57d7bSbt break;
3989da57d7bSbt }
39973cd555cSBin Tu - Sun Microsystems - Beijing China out:
40063b3bba8SJerry Jelinek return media_type;
4019da57d7bSbt }
4029da57d7bSbt
40363b3bba8SJerry Jelinek /**
40463b3bba8SJerry Jelinek * ixgbe_fc_enable_82598 - Enable flow control
40563b3bba8SJerry Jelinek * @hw: pointer to hardware structure
4069da57d7bSbt *
40763b3bba8SJerry Jelinek * Enable flow control according to the current settings.
40863b3bba8SJerry Jelinek **/
ixgbe_fc_enable_82598(struct ixgbe_hw * hw)40969b5a878SDan McDonald s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw)
4109da57d7bSbt {
41173cd555cSBin Tu - Sun Microsystems - Beijing China s32 ret_val = IXGBE_SUCCESS;
41273cd555cSBin Tu - Sun Microsystems - Beijing China u32 fctrl_reg;
4139da57d7bSbt u32 rmcs_reg;
41473cd555cSBin Tu - Sun Microsystems - Beijing China u32 reg;
41569b5a878SDan McDonald u32 fcrtl, fcrth;
41619843f01SPaul Guo u32 link_speed = 0;
41769b5a878SDan McDonald int i;
41819843f01SPaul Guo bool link_up;
4199da57d7bSbt
42073cd555cSBin Tu - Sun Microsystems - Beijing China DEBUGFUNC("ixgbe_fc_enable_82598");
42173cd555cSBin Tu - Sun Microsystems - Beijing China
42269b5a878SDan McDonald /* Validate the water mark configuration */
42369b5a878SDan McDonald if (!hw->fc.pause_time) {
42469b5a878SDan McDonald ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
42569b5a878SDan McDonald goto out;
42669b5a878SDan McDonald }
42769b5a878SDan McDonald
42869b5a878SDan McDonald /* Low water mark of zero causes XOFF floods */
42969b5a878SDan McDonald for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
43069b5a878SDan McDonald if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
43169b5a878SDan McDonald hw->fc.high_water[i]) {
43269b5a878SDan McDonald if (!hw->fc.low_water[i] ||
43369b5a878SDan McDonald hw->fc.low_water[i] >= hw->fc.high_water[i]) {
43469b5a878SDan McDonald DEBUGOUT("Invalid water mark configuration\n");
43569b5a878SDan McDonald ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
43669b5a878SDan McDonald goto out;
43769b5a878SDan McDonald }
43869b5a878SDan McDonald }
43969b5a878SDan McDonald }
44069b5a878SDan McDonald
44119843f01SPaul Guo /*
4425b6dd21fSchenlu chen - Sun Microsystems - Beijing China * On 82598 having Rx FC on causes resets while doing 1G
4435b6dd21fSchenlu chen - Sun Microsystems - Beijing China * so if it's on turn it off once we know link_speed. For
4445b6dd21fSchenlu chen - Sun Microsystems - Beijing China * more details see 82598 Specification update.
44519843f01SPaul Guo */
44663b3bba8SJerry Jelinek hw->mac.ops.check_link(hw, &link_speed, &link_up, FALSE);
4475b6dd21fSchenlu chen - Sun Microsystems - Beijing China if (link_up && link_speed == IXGBE_LINK_SPEED_1GB_FULL) {
4485b6dd21fSchenlu chen - Sun Microsystems - Beijing China switch (hw->fc.requested_mode) {
4495b6dd21fSchenlu chen - Sun Microsystems - Beijing China case ixgbe_fc_full:
4505b6dd21fSchenlu chen - Sun Microsystems - Beijing China hw->fc.requested_mode = ixgbe_fc_tx_pause;
4515b6dd21fSchenlu chen - Sun Microsystems - Beijing China break;
4525b6dd21fSchenlu chen - Sun Microsystems - Beijing China case ixgbe_fc_rx_pause:
4535b6dd21fSchenlu chen - Sun Microsystems - Beijing China hw->fc.requested_mode = ixgbe_fc_none;
4545b6dd21fSchenlu chen - Sun Microsystems - Beijing China break;
4555b6dd21fSchenlu chen - Sun Microsystems - Beijing China default:
4565b6dd21fSchenlu chen - Sun Microsystems - Beijing China /* no change */
4575b6dd21fSchenlu chen - Sun Microsystems - Beijing China break;
4585b6dd21fSchenlu chen - Sun Microsystems - Beijing China }
45919843f01SPaul Guo }
46019843f01SPaul Guo
46173cd555cSBin Tu - Sun Microsystems - Beijing China /* Negotiate the fc mode to use */
46269b5a878SDan McDonald ixgbe_fc_autoneg(hw);
4639da57d7bSbt
46473cd555cSBin Tu - Sun Microsystems - Beijing China /* Disable any previous flow control settings */
46573cd555cSBin Tu - Sun Microsystems - Beijing China fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
46673cd555cSBin Tu - Sun Microsystems - Beijing China fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
4679da57d7bSbt
4689da57d7bSbt rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
4699da57d7bSbt rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X);
4709da57d7bSbt
4719da57d7bSbt /*
47273cd555cSBin Tu - Sun Microsystems - Beijing China * The possible values of fc.current_mode are:
4739da57d7bSbt * 0: Flow control is completely disabled
47473cd555cSBin Tu - Sun Microsystems - Beijing China * 1: Rx flow control is enabled (we can receive pause frames,
47573cd555cSBin Tu - Sun Microsystems - Beijing China * but not send pause frames).
47673cd555cSBin Tu - Sun Microsystems - Beijing China * 2: Tx flow control is enabled (we can send pause frames but
47763b3bba8SJerry Jelinek * we do not support receiving pause frames).
4789da57d7bSbt * 3: Both Rx and Tx flow control (symmetric) are enabled.
4799da57d7bSbt * other: Invalid.
4809da57d7bSbt */
48173cd555cSBin Tu - Sun Microsystems - Beijing China switch (hw->fc.current_mode) {
4829da57d7bSbt case ixgbe_fc_none:
48373cd555cSBin Tu - Sun Microsystems - Beijing China /*
48473cd555cSBin Tu - Sun Microsystems - Beijing China * Flow control is disabled by software override or autoneg.
48573cd555cSBin Tu - Sun Microsystems - Beijing China * The code below will actually disable it in the HW.
48673cd555cSBin Tu - Sun Microsystems - Beijing China */
4879da57d7bSbt break;
4889da57d7bSbt case ixgbe_fc_rx_pause:
4899da57d7bSbt /*
49073cd555cSBin Tu - Sun Microsystems - Beijing China * Rx Flow control is enabled and Tx Flow control is
49173cd555cSBin Tu - Sun Microsystems - Beijing China * disabled by software override. Since there really
49273cd555cSBin Tu - Sun Microsystems - Beijing China * isn't a way to advertise that we are capable of RX
49373cd555cSBin Tu - Sun Microsystems - Beijing China * Pause ONLY, we will advertise that we support both
49473cd555cSBin Tu - Sun Microsystems - Beijing China * symmetric and asymmetric Rx PAUSE. Later, we will
49573cd555cSBin Tu - Sun Microsystems - Beijing China * disable the adapter's ability to send PAUSE frames.
4969da57d7bSbt */
49773cd555cSBin Tu - Sun Microsystems - Beijing China fctrl_reg |= IXGBE_FCTRL_RFCE;
4989da57d7bSbt break;
4999da57d7bSbt case ixgbe_fc_tx_pause:
5009da57d7bSbt /*
50173cd555cSBin Tu - Sun Microsystems - Beijing China * Tx Flow control is enabled, and Rx Flow control is
50273cd555cSBin Tu - Sun Microsystems - Beijing China * disabled by software override.
5039da57d7bSbt */
5049da57d7bSbt rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
5059da57d7bSbt break;
5069da57d7bSbt case ixgbe_fc_full:
50773cd555cSBin Tu - Sun Microsystems - Beijing China /* Flow control (both Rx and Tx) is enabled by SW override. */
50873cd555cSBin Tu - Sun Microsystems - Beijing China fctrl_reg |= IXGBE_FCTRL_RFCE;
5099da57d7bSbt rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
5109da57d7bSbt break;
5119da57d7bSbt default:
5129da57d7bSbt DEBUGOUT("Flow control param set incorrectly\n");
5133cfa0eb9Schenlu chen - Sun Microsystems - Beijing China ret_val = IXGBE_ERR_CONFIG;
51473cd555cSBin Tu - Sun Microsystems - Beijing China goto out;
515dc0cb1cdSDale Ghent break;
5169da57d7bSbt }
5179da57d7bSbt
51873cd555cSBin Tu - Sun Microsystems - Beijing China /* Set 802.3x based flow control settings. */
51973cd555cSBin Tu - Sun Microsystems - Beijing China fctrl_reg |= IXGBE_FCTRL_DPF;
52073cd555cSBin Tu - Sun Microsystems - Beijing China IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
5219da57d7bSbt IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
5229da57d7bSbt
52373cd555cSBin Tu - Sun Microsystems - Beijing China /* Set up and enable Rx high/low water mark thresholds, enable XON. */
52469b5a878SDan McDonald for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
52569b5a878SDan McDonald if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
52669b5a878SDan McDonald hw->fc.high_water[i]) {
52769b5a878SDan McDonald fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
52869b5a878SDan McDonald fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
52969b5a878SDan McDonald IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
53069b5a878SDan McDonald IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), fcrth);
53169b5a878SDan McDonald } else {
53269b5a878SDan McDonald IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0);
53369b5a878SDan McDonald IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0);
53469b5a878SDan McDonald }
53563b3bba8SJerry Jelinek
5369da57d7bSbt }
5379da57d7bSbt
53873cd555cSBin Tu - Sun Microsystems - Beijing China /* Configure pause time (2 TCs per register) */
53969b5a878SDan McDonald reg = hw->fc.pause_time * 0x00010001;
54069b5a878SDan McDonald for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++)
54169b5a878SDan McDonald IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
54273cd555cSBin Tu - Sun Microsystems - Beijing China
54369b5a878SDan McDonald /* Configure flow control refresh threshold value */
54469b5a878SDan McDonald IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
5459da57d7bSbt
54673cd555cSBin Tu - Sun Microsystems - Beijing China out:
54763b3bba8SJerry Jelinek return ret_val;
5489da57d7bSbt }
5499da57d7bSbt
55063b3bba8SJerry Jelinek /**
55163b3bba8SJerry Jelinek * ixgbe_start_mac_link_82598 - Configures MAC link settings
55263b3bba8SJerry Jelinek * @hw: pointer to hardware structure
55348ed61a7SRobert Mustacchi * @autoneg_wait_to_complete: TRUE when waiting for completion is needed
5549da57d7bSbt *
55563b3bba8SJerry Jelinek * Configures link settings based on values in the ixgbe_hw struct.
55663b3bba8SJerry Jelinek * Restarts the link. Performs autonegotiation if needed.
55763b3bba8SJerry Jelinek **/
ixgbe_start_mac_link_82598(struct ixgbe_hw * hw,bool autoneg_wait_to_complete)55863b3bba8SJerry Jelinek static s32 ixgbe_start_mac_link_82598(struct ixgbe_hw *hw,
55969b5a878SDan McDonald bool autoneg_wait_to_complete)
5609da57d7bSbt {
5619da57d7bSbt u32 autoc_reg;
5629da57d7bSbt u32 links_reg;
5639da57d7bSbt u32 i;
5649da57d7bSbt s32 status = IXGBE_SUCCESS;
5659da57d7bSbt
5663cfa0eb9Schenlu chen - Sun Microsystems - Beijing China DEBUGFUNC("ixgbe_start_mac_link_82598");
5673cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
5689da57d7bSbt /* Restart link */
56973cd555cSBin Tu - Sun Microsystems - Beijing China autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
5709da57d7bSbt autoc_reg |= IXGBE_AUTOC_AN_RESTART;
5719da57d7bSbt IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
5729da57d7bSbt
5739da57d7bSbt /* Only poll for autoneg to complete if specified to do so */
5743cfa0eb9Schenlu chen - Sun Microsystems - Beijing China if (autoneg_wait_to_complete) {
57573cd555cSBin Tu - Sun Microsystems - Beijing China if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
57663b3bba8SJerry Jelinek IXGBE_AUTOC_LMS_KX4_AN ||
57773cd555cSBin Tu - Sun Microsystems - Beijing China (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
57863b3bba8SJerry Jelinek IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
5799da57d7bSbt links_reg = 0; /* Just in case Autoneg time = 0 */
5809da57d7bSbt for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
5819da57d7bSbt links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
5829da57d7bSbt if (links_reg & IXGBE_LINKS_KX_AN_COMP)
5839da57d7bSbt break;
5849da57d7bSbt msec_delay(100);
5859da57d7bSbt }
5869da57d7bSbt if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
5879da57d7bSbt status = IXGBE_ERR_AUTONEG_NOT_COMPLETE;
5889da57d7bSbt DEBUGOUT("Autonegotiation did not complete.\n");
5899da57d7bSbt }
5909da57d7bSbt }
5919da57d7bSbt }
5929da57d7bSbt
5939da57d7bSbt /* Add delay to filter out noises during initial link setup */
5949da57d7bSbt msec_delay(50);
5959da57d7bSbt
59663b3bba8SJerry Jelinek return status;
5979da57d7bSbt }
5989da57d7bSbt
59963b3bba8SJerry Jelinek /**
60063b3bba8SJerry Jelinek * ixgbe_validate_link_ready - Function looks for phy link
60163b3bba8SJerry Jelinek * @hw: pointer to hardware structure
6029da57d7bSbt *
60363b3bba8SJerry Jelinek * Function indicates success when phy link is available. If phy is not ready
60463b3bba8SJerry Jelinek * within 5 seconds of MAC indicating link, the function returns error.
60563b3bba8SJerry Jelinek **/
ixgbe_validate_link_ready(struct ixgbe_hw * hw)60663b3bba8SJerry Jelinek static s32 ixgbe_validate_link_ready(struct ixgbe_hw *hw)
60763b3bba8SJerry Jelinek {
60863b3bba8SJerry Jelinek u32 timeout;
60963b3bba8SJerry Jelinek u16 an_reg;
61063b3bba8SJerry Jelinek
61163b3bba8SJerry Jelinek if (hw->device_id != IXGBE_DEV_ID_82598AT2)
61263b3bba8SJerry Jelinek return IXGBE_SUCCESS;
61363b3bba8SJerry Jelinek
61463b3bba8SJerry Jelinek for (timeout = 0;
61563b3bba8SJerry Jelinek timeout < IXGBE_VALIDATE_LINK_READY_TIMEOUT; timeout++) {
61663b3bba8SJerry Jelinek hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
61769b5a878SDan McDonald IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &an_reg);
61863b3bba8SJerry Jelinek
61963b3bba8SJerry Jelinek if ((an_reg & IXGBE_MII_AUTONEG_COMPLETE) &&
62063b3bba8SJerry Jelinek (an_reg & IXGBE_MII_AUTONEG_LINK_UP))
62163b3bba8SJerry Jelinek break;
62263b3bba8SJerry Jelinek
62363b3bba8SJerry Jelinek msec_delay(100);
62463b3bba8SJerry Jelinek }
62563b3bba8SJerry Jelinek
62663b3bba8SJerry Jelinek if (timeout == IXGBE_VALIDATE_LINK_READY_TIMEOUT) {
62763b3bba8SJerry Jelinek DEBUGOUT("Link was indicated but link is down\n");
62863b3bba8SJerry Jelinek return IXGBE_ERR_LINK_SETUP;
62963b3bba8SJerry Jelinek }
63063b3bba8SJerry Jelinek
63163b3bba8SJerry Jelinek return IXGBE_SUCCESS;
63263b3bba8SJerry Jelinek }
63363b3bba8SJerry Jelinek
63463b3bba8SJerry Jelinek /**
63563b3bba8SJerry Jelinek * ixgbe_check_mac_link_82598 - Get link/speed status
63663b3bba8SJerry Jelinek * @hw: pointer to hardware structure
63763b3bba8SJerry Jelinek * @speed: pointer to link speed
63863b3bba8SJerry Jelinek * @link_up: TRUE is link is up, FALSE otherwise
63963b3bba8SJerry Jelinek * @link_up_wait_to_complete: bool used to wait for link up or not
64063b3bba8SJerry Jelinek *
64163b3bba8SJerry Jelinek * Reads the links register to determine if link is up and the current speed
64263b3bba8SJerry Jelinek **/
ixgbe_check_mac_link_82598(struct ixgbe_hw * hw,ixgbe_link_speed * speed,bool * link_up,bool link_up_wait_to_complete)64363b3bba8SJerry Jelinek static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
64469b5a878SDan McDonald ixgbe_link_speed *speed, bool *link_up,
64569b5a878SDan McDonald bool link_up_wait_to_complete)
6469da57d7bSbt {
6479da57d7bSbt u32 links_reg;
64813740cb2SPaul Guo u32 i;
64913740cb2SPaul Guo u16 link_reg, adapt_comp_reg;
6509da57d7bSbt
6513cfa0eb9Schenlu chen - Sun Microsystems - Beijing China DEBUGFUNC("ixgbe_check_mac_link_82598");
6523cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
65313740cb2SPaul Guo /*
65413740cb2SPaul Guo * SERDES PHY requires us to read link status from undocumented
65513740cb2SPaul Guo * register 0xC79F. Bit 0 set indicates link is up/ready; clear
65613740cb2SPaul Guo * indicates link down. OxC00C is read to check that the XAUI lanes
65713740cb2SPaul Guo * are active. Bit 0 clear indicates active; set indicates inactive.
65813740cb2SPaul Guo */
65913740cb2SPaul Guo if (hw->phy.type == ixgbe_phy_nl) {
66013740cb2SPaul Guo hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg);
66113740cb2SPaul Guo hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg);
66213740cb2SPaul Guo hw->phy.ops.read_reg(hw, 0xC00C, IXGBE_TWINAX_DEV,
66369b5a878SDan McDonald &adapt_comp_reg);
66413740cb2SPaul Guo if (link_up_wait_to_complete) {
665dc0cb1cdSDale Ghent for (i = 0; i < hw->mac.max_link_up_time; i++) {
66613740cb2SPaul Guo if ((link_reg & 1) &&
66713740cb2SPaul Guo ((adapt_comp_reg & 1) == 0)) {
66863b3bba8SJerry Jelinek *link_up = TRUE;
66913740cb2SPaul Guo break;
67013740cb2SPaul Guo } else {
67163b3bba8SJerry Jelinek *link_up = FALSE;
67213740cb2SPaul Guo }
67313740cb2SPaul Guo msec_delay(100);
67413740cb2SPaul Guo hw->phy.ops.read_reg(hw, 0xC79F,
67569b5a878SDan McDonald IXGBE_TWINAX_DEV,
67669b5a878SDan McDonald &link_reg);
67713740cb2SPaul Guo hw->phy.ops.read_reg(hw, 0xC00C,
67869b5a878SDan McDonald IXGBE_TWINAX_DEV,
67969b5a878SDan McDonald &adapt_comp_reg);
68013740cb2SPaul Guo }
68113740cb2SPaul Guo } else {
68263b3bba8SJerry Jelinek if ((link_reg & 1) && ((adapt_comp_reg & 1) == 0))
68363b3bba8SJerry Jelinek *link_up = TRUE;
68413740cb2SPaul Guo else
68563b3bba8SJerry Jelinek *link_up = FALSE;
68613740cb2SPaul Guo }
6879da57d7bSbt
68863b3bba8SJerry Jelinek if (*link_up == FALSE)
68913740cb2SPaul Guo goto out;
69013740cb2SPaul Guo }
69113740cb2SPaul Guo
69213740cb2SPaul Guo links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
69313740cb2SPaul Guo if (link_up_wait_to_complete) {
694dc0cb1cdSDale Ghent for (i = 0; i < hw->mac.max_link_up_time; i++) {
69513740cb2SPaul Guo if (links_reg & IXGBE_LINKS_UP) {
69663b3bba8SJerry Jelinek *link_up = TRUE;
69713740cb2SPaul Guo break;
69813740cb2SPaul Guo } else {
69963b3bba8SJerry Jelinek *link_up = FALSE;
70013740cb2SPaul Guo }
70113740cb2SPaul Guo msec_delay(100);
70213740cb2SPaul Guo links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
70313740cb2SPaul Guo }
70413740cb2SPaul Guo } else {
70513740cb2SPaul Guo if (links_reg & IXGBE_LINKS_UP)
70663b3bba8SJerry Jelinek *link_up = TRUE;
70713740cb2SPaul Guo else
70863b3bba8SJerry Jelinek *link_up = FALSE;
70913740cb2SPaul Guo }
7109da57d7bSbt
7119da57d7bSbt if (links_reg & IXGBE_LINKS_SPEED)
7129da57d7bSbt *speed = IXGBE_LINK_SPEED_10GB_FULL;
7139da57d7bSbt else
7149da57d7bSbt *speed = IXGBE_LINK_SPEED_1GB_FULL;
7159da57d7bSbt
71663b3bba8SJerry Jelinek if ((hw->device_id == IXGBE_DEV_ID_82598AT2) && (*link_up == TRUE) &&
71719843f01SPaul Guo (ixgbe_validate_link_ready(hw) != IXGBE_SUCCESS))
71863b3bba8SJerry Jelinek *link_up = FALSE;
71919843f01SPaul Guo
72013740cb2SPaul Guo out:
72163b3bba8SJerry Jelinek return IXGBE_SUCCESS;
7229da57d7bSbt }
7239da57d7bSbt
72463b3bba8SJerry Jelinek /**
72563b3bba8SJerry Jelinek * ixgbe_setup_mac_link_82598 - Set MAC link speed
72663b3bba8SJerry Jelinek * @hw: pointer to hardware structure
72763b3bba8SJerry Jelinek * @speed: new link speed
72863b3bba8SJerry Jelinek * @autoneg_wait_to_complete: TRUE when waiting for completion is needed
7299da57d7bSbt *
73063b3bba8SJerry Jelinek * Set the link speed in the AUTOC register and restarts link.
73163b3bba8SJerry Jelinek **/
ixgbe_setup_mac_link_82598(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)73263b3bba8SJerry Jelinek static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
733dc0cb1cdSDale Ghent ixgbe_link_speed speed,
73469b5a878SDan McDonald bool autoneg_wait_to_complete)
7359da57d7bSbt {
736dc0cb1cdSDale Ghent bool autoneg = FALSE;
737dc0cb1cdSDale Ghent s32 status = IXGBE_SUCCESS;
73873cd555cSBin Tu - Sun Microsystems - Beijing China ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
73969b5a878SDan McDonald u32 curr_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
74069b5a878SDan McDonald u32 autoc = curr_autoc;
74169b5a878SDan McDonald u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
7429da57d7bSbt
7433cfa0eb9Schenlu chen - Sun Microsystems - Beijing China DEBUGFUNC("ixgbe_setup_mac_link_82598");
7443cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
74573cd555cSBin Tu - Sun Microsystems - Beijing China /* Check to see if speed passed in is supported. */
746dc0cb1cdSDale Ghent ixgbe_get_link_capabilities(hw, &link_capabilities, &autoneg);
74773cd555cSBin Tu - Sun Microsystems - Beijing China speed &= link_capabilities;
74873cd555cSBin Tu - Sun Microsystems - Beijing China
74963b3bba8SJerry Jelinek if (speed == IXGBE_LINK_SPEED_UNKNOWN)
7509da57d7bSbt status = IXGBE_ERR_LINK_SETUP;
75163b3bba8SJerry Jelinek
75263b3bba8SJerry Jelinek /* Set KX4/KX support according to speed requested */
75363b3bba8SJerry Jelinek else if (link_mode == IXGBE_AUTOC_LMS_KX4_AN ||
75469b5a878SDan McDonald link_mode == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
75573cd555cSBin Tu - Sun Microsystems - Beijing China autoc &= ~IXGBE_AUTOC_KX4_KX_SUPP_MASK;
75673cd555cSBin Tu - Sun Microsystems - Beijing China if (speed & IXGBE_LINK_SPEED_10GB_FULL)
75773cd555cSBin Tu - Sun Microsystems - Beijing China autoc |= IXGBE_AUTOC_KX4_SUPP;
75873cd555cSBin Tu - Sun Microsystems - Beijing China if (speed & IXGBE_LINK_SPEED_1GB_FULL)
75973cd555cSBin Tu - Sun Microsystems - Beijing China autoc |= IXGBE_AUTOC_KX_SUPP;
76073cd555cSBin Tu - Sun Microsystems - Beijing China if (autoc != curr_autoc)
76173cd555cSBin Tu - Sun Microsystems - Beijing China IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
7629da57d7bSbt }
7639da57d7bSbt
7649da57d7bSbt if (status == IXGBE_SUCCESS) {
7659da57d7bSbt /*
7669da57d7bSbt * Setup and restart the link based on the new values in
7679da57d7bSbt * ixgbe_hw This will write the AUTOC register based on the new
7689da57d7bSbt * stored values
7699da57d7bSbt */
7703cfa0eb9Schenlu chen - Sun Microsystems - Beijing China status = ixgbe_start_mac_link_82598(hw,
77169b5a878SDan McDonald autoneg_wait_to_complete);
7729da57d7bSbt }
7739da57d7bSbt
77463b3bba8SJerry Jelinek return status;
7759da57d7bSbt }
7769da57d7bSbt
77763b3bba8SJerry Jelinek
77863b3bba8SJerry Jelinek /**
77963b3bba8SJerry Jelinek * ixgbe_setup_copper_link_82598 - Set the PHY autoneg advertised field
78063b3bba8SJerry Jelinek * @hw: pointer to hardware structure
78163b3bba8SJerry Jelinek * @speed: new link speed
78263b3bba8SJerry Jelinek * @autoneg_wait_to_complete: TRUE if waiting is needed to complete
7839da57d7bSbt *
78463b3bba8SJerry Jelinek * Sets the link speed in the AUTOC register in the MAC and restarts link.
78563b3bba8SJerry Jelinek **/
ixgbe_setup_copper_link_82598(struct ixgbe_hw * hw,ixgbe_link_speed speed,bool autoneg_wait_to_complete)78663b3bba8SJerry Jelinek static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
78769b5a878SDan McDonald ixgbe_link_speed speed,
78869b5a878SDan McDonald bool autoneg_wait_to_complete)
7899da57d7bSbt {
7909da57d7bSbt s32 status;
7919da57d7bSbt
7923cfa0eb9Schenlu chen - Sun Microsystems - Beijing China DEBUGFUNC("ixgbe_setup_copper_link_82598");
7933cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
7949da57d7bSbt /* Setup the PHY according to input speed */
795dc0cb1cdSDale Ghent status = hw->phy.ops.setup_link_speed(hw, speed,
79669b5a878SDan McDonald autoneg_wait_to_complete);
797dc0cb1cdSDale Ghent /* Set up MAC */
798dc0cb1cdSDale Ghent ixgbe_start_mac_link_82598(hw, autoneg_wait_to_complete);
7999da57d7bSbt
80063b3bba8SJerry Jelinek return status;
8019da57d7bSbt }
8029da57d7bSbt
80363b3bba8SJerry Jelinek /**
80463b3bba8SJerry Jelinek * ixgbe_reset_hw_82598 - Performs hardware reset
80563b3bba8SJerry Jelinek * @hw: pointer to hardware structure
8069da57d7bSbt *
80763b3bba8SJerry Jelinek * Resets the hardware by resetting the transmit and receive units, masks and
80863b3bba8SJerry Jelinek * clears all interrupts, performing a PHY reset, and performing a link (MAC)
80963b3bba8SJerry Jelinek * reset.
81063b3bba8SJerry Jelinek **/
ixgbe_reset_hw_82598(struct ixgbe_hw * hw)81163b3bba8SJerry Jelinek static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
8129da57d7bSbt {
8139da57d7bSbt s32 status = IXGBE_SUCCESS;
814185c5677SPaul Guo s32 phy_status = IXGBE_SUCCESS;
8159da57d7bSbt u32 ctrl;
8169da57d7bSbt u32 gheccr;
8179da57d7bSbt u32 i;
8189da57d7bSbt u32 autoc;
8199da57d7bSbt u8 analog_val;
8209da57d7bSbt
8213cfa0eb9Schenlu chen - Sun Microsystems - Beijing China DEBUGFUNC("ixgbe_reset_hw_82598");
8223cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
8239da57d7bSbt /* Call adapter stop to disable tx/rx and clear interrupts */
82469b5a878SDan McDonald status = hw->mac.ops.stop_adapter(hw);
82569b5a878SDan McDonald if (status != IXGBE_SUCCESS)
82669b5a878SDan McDonald goto reset_hw_out;
8279da57d7bSbt
8289da57d7bSbt /*
8299da57d7bSbt * Power up the Atlas Tx lanes if they are currently powered down.
8309da57d7bSbt * Atlas Tx lanes are powered down for MAC loopback tests, but
8319da57d7bSbt * they are not automatically restored on reset.
8329da57d7bSbt */
8339da57d7bSbt hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val);
8349da57d7bSbt if (analog_val & IXGBE_ATLAS_PDN_TX_REG_EN) {
8359da57d7bSbt /* Enable Tx Atlas so packets can be transmitted again */
8369da57d7bSbt hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK,
83769b5a878SDan McDonald &analog_val);
8389da57d7bSbt analog_val &= ~IXGBE_ATLAS_PDN_TX_REG_EN;
8399da57d7bSbt hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK,
84069b5a878SDan McDonald analog_val);
8419da57d7bSbt
8429da57d7bSbt hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G,
84369b5a878SDan McDonald &analog_val);
84413740cb2SPaul Guo analog_val &= ~IXGBE_ATLAS_PDN_TX_10G_QL_ALL;
8459da57d7bSbt hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G,
84669b5a878SDan McDonald analog_val);
8479da57d7bSbt
8489da57d7bSbt hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G,
84969b5a878SDan McDonald &analog_val);
8509da57d7bSbt analog_val &= ~IXGBE_ATLAS_PDN_TX_1G_QL_ALL;
8519da57d7bSbt hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G,
85269b5a878SDan McDonald analog_val);
8539da57d7bSbt
8549da57d7bSbt hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN,
85569b5a878SDan McDonald &analog_val);
8569da57d7bSbt analog_val &= ~IXGBE_ATLAS_PDN_TX_AN_QL_ALL;
8579da57d7bSbt hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN,
85869b5a878SDan McDonald analog_val);
8599da57d7bSbt }
8609da57d7bSbt
8619da57d7bSbt /* Reset PHY */
86263b3bba8SJerry Jelinek if (hw->phy.reset_disable == FALSE) {
86373cd555cSBin Tu - Sun Microsystems - Beijing China /* PHY ops must be identified and initialized prior to reset */
86473cd555cSBin Tu - Sun Microsystems - Beijing China
86573cd555cSBin Tu - Sun Microsystems - Beijing China /* Init PHY and function pointers, perform SFP setup */
866185c5677SPaul Guo phy_status = hw->phy.ops.init(hw);
867185c5677SPaul Guo if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED)
868185c5677SPaul Guo goto reset_hw_out;
86969b5a878SDan McDonald if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT)
87069b5a878SDan McDonald goto mac_reset_top;
87173cd555cSBin Tu - Sun Microsystems - Beijing China
87213740cb2SPaul Guo hw->phy.ops.reset(hw);
87373cd555cSBin Tu - Sun Microsystems - Beijing China }
8749da57d7bSbt
87519843f01SPaul Guo mac_reset_top:
8769da57d7bSbt /*
8779da57d7bSbt * Issue global reset to the MAC. This needs to be a SW reset.
8789da57d7bSbt * If link reset is used, it might reset the MAC when mng is using it
8799da57d7bSbt */
88069b5a878SDan McDonald ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL) | IXGBE_CTRL_RST;
88169b5a878SDan McDonald IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
8829da57d7bSbt IXGBE_WRITE_FLUSH(hw);
8839da57d7bSbt
8849da57d7bSbt /* Poll for reset bit to self-clear indicating reset is complete */
8859da57d7bSbt for (i = 0; i < 10; i++) {
8869da57d7bSbt usec_delay(1);
8879da57d7bSbt ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
8889da57d7bSbt if (!(ctrl & IXGBE_CTRL_RST))
8899da57d7bSbt break;
8909da57d7bSbt }
8919da57d7bSbt if (ctrl & IXGBE_CTRL_RST) {
8929da57d7bSbt status = IXGBE_ERR_RESET_FAILED;
8939da57d7bSbt DEBUGOUT("Reset polling failed to complete.\n");
8949da57d7bSbt }
8959da57d7bSbt
89669b5a878SDan McDonald msec_delay(50);
89769b5a878SDan McDonald
89819843f01SPaul Guo /*
89919843f01SPaul Guo * Double resets are required for recovery from certain error
90019843f01SPaul Guo * conditions. Between resets, it is necessary to stall to allow time
90169b5a878SDan McDonald * for any pending HW events to complete.
90219843f01SPaul Guo */
90319843f01SPaul Guo if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
90419843f01SPaul Guo hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
90519843f01SPaul Guo goto mac_reset_top;
90619843f01SPaul Guo }
90763b3bba8SJerry Jelinek
9089da57d7bSbt gheccr = IXGBE_READ_REG(hw, IXGBE_GHECCR);
9099da57d7bSbt gheccr &= ~((1 << 21) | (1 << 18) | (1 << 9) | (1 << 6));
9109da57d7bSbt IXGBE_WRITE_REG(hw, IXGBE_GHECCR, gheccr);
9119da57d7bSbt
9129da57d7bSbt /*
91373cd555cSBin Tu - Sun Microsystems - Beijing China * Store the original AUTOC value if it has not been
91473cd555cSBin Tu - Sun Microsystems - Beijing China * stored off yet. Otherwise restore the stored original
915*9b622488SToomas Soome * AUTOC value since the reset operation sets back to defaults.
9169da57d7bSbt */
9179da57d7bSbt autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
91863b3bba8SJerry Jelinek if (hw->mac.orig_link_settings_stored == FALSE) {
91973cd555cSBin Tu - Sun Microsystems - Beijing China hw->mac.orig_autoc = autoc;
92063b3bba8SJerry Jelinek hw->mac.orig_link_settings_stored = TRUE;
92173cd555cSBin Tu - Sun Microsystems - Beijing China } else if (autoc != hw->mac.orig_autoc) {
92273cd555cSBin Tu - Sun Microsystems - Beijing China IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc);
9239da57d7bSbt }
9249da57d7bSbt
925185c5677SPaul Guo /* Store the permanent mac address */
926185c5677SPaul Guo hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
927185c5677SPaul Guo
92873cd555cSBin Tu - Sun Microsystems - Beijing China /*
92973cd555cSBin Tu - Sun Microsystems - Beijing China * Store MAC address from RAR0, clear receive address registers, and
93073cd555cSBin Tu - Sun Microsystems - Beijing China * clear the multicast table
93173cd555cSBin Tu - Sun Microsystems - Beijing China */
93273cd555cSBin Tu - Sun Microsystems - Beijing China hw->mac.ops.init_rx_addrs(hw);
93373cd555cSBin Tu - Sun Microsystems - Beijing China
934185c5677SPaul Guo reset_hw_out:
935185c5677SPaul Guo if (phy_status != IXGBE_SUCCESS)
936185c5677SPaul Guo status = phy_status;
9379da57d7bSbt
93863b3bba8SJerry Jelinek return status;
9399da57d7bSbt }
9409da57d7bSbt
94163b3bba8SJerry Jelinek /**
94263b3bba8SJerry Jelinek * ixgbe_set_vmdq_82598 - Associate a VMDq set index with a rx address
94363b3bba8SJerry Jelinek * @hw: pointer to hardware struct
94463b3bba8SJerry Jelinek * @rar: receive address register index to associate with a VMDq index
94563b3bba8SJerry Jelinek * @vmdq: VMDq set index
94663b3bba8SJerry Jelinek **/
ixgbe_set_vmdq_82598(struct ixgbe_hw * hw,u32 rar,u32 vmdq)94763b3bba8SJerry Jelinek s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
9489da57d7bSbt {
9499da57d7bSbt u32 rar_high;
95063b3bba8SJerry Jelinek u32 rar_entries = hw->mac.num_rar_entries;
9519da57d7bSbt
9523cfa0eb9Schenlu chen - Sun Microsystems - Beijing China DEBUGFUNC("ixgbe_set_vmdq_82598");
9533cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
95463b3bba8SJerry Jelinek /* Make sure we are using a valid rar index range */
95563b3bba8SJerry Jelinek if (rar >= rar_entries) {
95663b3bba8SJerry Jelinek DEBUGOUT1("RAR index %d is out of range.\n", rar);
95763b3bba8SJerry Jelinek return IXGBE_ERR_INVALID_ARGUMENT;
95863b3bba8SJerry Jelinek }
95963b3bba8SJerry Jelinek
9609da57d7bSbt rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
9619da57d7bSbt rar_high &= ~IXGBE_RAH_VIND_MASK;
9629da57d7bSbt rar_high |= ((vmdq << IXGBE_RAH_VIND_SHIFT) & IXGBE_RAH_VIND_MASK);
9639da57d7bSbt IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high);
96463b3bba8SJerry Jelinek return IXGBE_SUCCESS;
9659da57d7bSbt }
9669da57d7bSbt
96763b3bba8SJerry Jelinek /**
96863b3bba8SJerry Jelinek * ixgbe_clear_vmdq_82598 - Disassociate a VMDq set index from an rx address
96963b3bba8SJerry Jelinek * @hw: pointer to hardware struct
97063b3bba8SJerry Jelinek * @rar: receive address register index to associate with a VMDq index
97163b3bba8SJerry Jelinek * @vmdq: VMDq clear index (not used in 82598, but elsewhere)
97263b3bba8SJerry Jelinek **/
ixgbe_clear_vmdq_82598(struct ixgbe_hw * hw,u32 rar,u32 vmdq)97363b3bba8SJerry Jelinek static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
97413740cb2SPaul Guo {
97513740cb2SPaul Guo u32 rar_high;
97613740cb2SPaul Guo u32 rar_entries = hw->mac.num_rar_entries;
97713740cb2SPaul Guo
97869b5a878SDan McDonald UNREFERENCED_1PARAMETER(vmdq);
97913740cb2SPaul Guo
98063b3bba8SJerry Jelinek /* Make sure we are using a valid rar index range */
98163b3bba8SJerry Jelinek if (rar >= rar_entries) {
98213740cb2SPaul Guo DEBUGOUT1("RAR index %d is out of range.\n", rar);
98363b3bba8SJerry Jelinek return IXGBE_ERR_INVALID_ARGUMENT;
98463b3bba8SJerry Jelinek }
98563b3bba8SJerry Jelinek
98663b3bba8SJerry Jelinek rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
98763b3bba8SJerry Jelinek if (rar_high & IXGBE_RAH_VIND_MASK) {
98863b3bba8SJerry Jelinek rar_high &= ~IXGBE_RAH_VIND_MASK;
98963b3bba8SJerry Jelinek IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high);
99013740cb2SPaul Guo }
99113740cb2SPaul Guo
99263b3bba8SJerry Jelinek return IXGBE_SUCCESS;
99313740cb2SPaul Guo }
99413740cb2SPaul Guo
99563b3bba8SJerry Jelinek /**
99663b3bba8SJerry Jelinek * ixgbe_set_vfta_82598 - Set VLAN filter table
99763b3bba8SJerry Jelinek * @hw: pointer to hardware structure
99863b3bba8SJerry Jelinek * @vlan: VLAN id to write to VLAN filter
99963b3bba8SJerry Jelinek * @vind: VMDq output index that maps queue to VLAN id in VFTA
100063b3bba8SJerry Jelinek * @vlan_on: boolean flag to turn on/off VLAN in VFTA
100148ed61a7SRobert Mustacchi * @vlvf_bypass: boolean flag - unused
100213740cb2SPaul Guo *
100363b3bba8SJerry Jelinek * Turn on/off specified VLAN in the VLAN filter table.
100463b3bba8SJerry Jelinek **/
ixgbe_set_vfta_82598(struct ixgbe_hw * hw,u32 vlan,u32 vind,bool vlan_on,bool vlvf_bypass)100563b3bba8SJerry Jelinek s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind,
100648ed61a7SRobert Mustacchi bool vlan_on, bool vlvf_bypass)
100713740cb2SPaul Guo {
100813740cb2SPaul Guo u32 regindex;
100913740cb2SPaul Guo u32 bitindex;
101013740cb2SPaul Guo u32 bits;
101113740cb2SPaul Guo u32 vftabyte;
101213740cb2SPaul Guo
101348ed61a7SRobert Mustacchi UNREFERENCED_1PARAMETER(vlvf_bypass);
101448ed61a7SRobert Mustacchi
10153cfa0eb9Schenlu chen - Sun Microsystems - Beijing China DEBUGFUNC("ixgbe_set_vfta_82598");
10163cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
101713740cb2SPaul Guo if (vlan > 4095)
101863b3bba8SJerry Jelinek return IXGBE_ERR_PARAM;
101913740cb2SPaul Guo
102013740cb2SPaul Guo /* Determine 32-bit word position in array */
102113740cb2SPaul Guo regindex = (vlan >> 5) & 0x7F; /* upper seven bits */
102213740cb2SPaul Guo
102313740cb2SPaul Guo /* Determine the location of the (VMD) queue index */
102413740cb2SPaul Guo vftabyte = ((vlan >> 3) & 0x03); /* bits (4:3) indicating byte array */
102513740cb2SPaul Guo bitindex = (vlan & 0x7) << 2; /* lower 3 bits indicate nibble */
102613740cb2SPaul Guo
102713740cb2SPaul Guo /* Set the nibble for VMD queue index */
102813740cb2SPaul Guo bits = IXGBE_READ_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex));
102913740cb2SPaul Guo bits &= (~(0x0F << bitindex));
103013740cb2SPaul Guo bits |= (vind << bitindex);
103113740cb2SPaul Guo IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex), bits);
103213740cb2SPaul Guo
103313740cb2SPaul Guo /* Determine the location of the bit for this VLAN id */
103413740cb2SPaul Guo bitindex = vlan & 0x1F; /* lower five bits */
103513740cb2SPaul Guo
103613740cb2SPaul Guo bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
103713740cb2SPaul Guo if (vlan_on)
103813740cb2SPaul Guo /* Turn on this VLAN id */
103913740cb2SPaul Guo bits |= (1 << bitindex);
104013740cb2SPaul Guo else
104113740cb2SPaul Guo /* Turn off this VLAN id */
104213740cb2SPaul Guo bits &= ~(1 << bitindex);
104313740cb2SPaul Guo IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits);
104413740cb2SPaul Guo
104563b3bba8SJerry Jelinek return IXGBE_SUCCESS;
104613740cb2SPaul Guo }
104713740cb2SPaul Guo
104863b3bba8SJerry Jelinek /**
104963b3bba8SJerry Jelinek * ixgbe_clear_vfta_82598 - Clear VLAN filter table
105063b3bba8SJerry Jelinek * @hw: pointer to hardware structure
105113740cb2SPaul Guo *
105263b3bba8SJerry Jelinek * Clears the VLAN filer table, and the VMDq index associated with the filter
105363b3bba8SJerry Jelinek **/
ixgbe_clear_vfta_82598(struct ixgbe_hw * hw)105463b3bba8SJerry Jelinek static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw)
105513740cb2SPaul Guo {
105613740cb2SPaul Guo u32 offset;
105713740cb2SPaul Guo u32 vlanbyte;
105813740cb2SPaul Guo
10593cfa0eb9Schenlu chen - Sun Microsystems - Beijing China DEBUGFUNC("ixgbe_clear_vfta_82598");
10603cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
106113740cb2SPaul Guo for (offset = 0; offset < hw->mac.vft_size; offset++)
106213740cb2SPaul Guo IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
106313740cb2SPaul Guo
106413740cb2SPaul Guo for (vlanbyte = 0; vlanbyte < 4; vlanbyte++)
106513740cb2SPaul Guo for (offset = 0; offset < hw->mac.vft_size; offset++)
106663b3bba8SJerry Jelinek IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset),
106769b5a878SDan McDonald 0);
106813740cb2SPaul Guo
106963b3bba8SJerry Jelinek return IXGBE_SUCCESS;
107013740cb2SPaul Guo }
107113740cb2SPaul Guo
107263b3bba8SJerry Jelinek /**
107363b3bba8SJerry Jelinek * ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register
107463b3bba8SJerry Jelinek * @hw: pointer to hardware structure
107563b3bba8SJerry Jelinek * @reg: analog register to read
107663b3bba8SJerry Jelinek * @val: read value
107713740cb2SPaul Guo *
107863b3bba8SJerry Jelinek * Performs read operation to Atlas analog register specified.
107963b3bba8SJerry Jelinek **/
ixgbe_read_analog_reg8_82598(struct ixgbe_hw * hw,u32 reg,u8 * val)108063b3bba8SJerry Jelinek s32 ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val)
108113740cb2SPaul Guo {
108213740cb2SPaul Guo u32 atlas_ctl;
108313740cb2SPaul Guo
10843cfa0eb9Schenlu chen - Sun Microsystems - Beijing China DEBUGFUNC("ixgbe_read_analog_reg8_82598");
10853cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
108613740cb2SPaul Guo IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL,
108769b5a878SDan McDonald IXGBE_ATLASCTL_WRITE_CMD | (reg << 8));
108813740cb2SPaul Guo IXGBE_WRITE_FLUSH(hw);
108913740cb2SPaul Guo usec_delay(10);
109013740cb2SPaul Guo atlas_ctl = IXGBE_READ_REG(hw, IXGBE_ATLASCTL);
109113740cb2SPaul Guo *val = (u8)atlas_ctl;
109213740cb2SPaul Guo
109363b3bba8SJerry Jelinek return IXGBE_SUCCESS;
109413740cb2SPaul Guo }
109513740cb2SPaul Guo
109663b3bba8SJerry Jelinek /**
109763b3bba8SJerry Jelinek * ixgbe_write_analog_reg8_82598 - Writes 8 bit Atlas analog register
109863b3bba8SJerry Jelinek * @hw: pointer to hardware structure
109963b3bba8SJerry Jelinek * @reg: atlas register to write
110063b3bba8SJerry Jelinek * @val: value to write
110113740cb2SPaul Guo *
110263b3bba8SJerry Jelinek * Performs write operation to Atlas analog register specified.
110363b3bba8SJerry Jelinek **/
ixgbe_write_analog_reg8_82598(struct ixgbe_hw * hw,u32 reg,u8 val)110463b3bba8SJerry Jelinek s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val)
110513740cb2SPaul Guo {
110613740cb2SPaul Guo u32 atlas_ctl;
110713740cb2SPaul Guo
11083cfa0eb9Schenlu chen - Sun Microsystems - Beijing China DEBUGFUNC("ixgbe_write_analog_reg8_82598");
11093cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
111013740cb2SPaul Guo atlas_ctl = (reg << 8) | val;
111113740cb2SPaul Guo IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, atlas_ctl);
111213740cb2SPaul Guo IXGBE_WRITE_FLUSH(hw);
111313740cb2SPaul Guo usec_delay(10);
111413740cb2SPaul Guo
111563b3bba8SJerry Jelinek return IXGBE_SUCCESS;
111613740cb2SPaul Guo }
111713740cb2SPaul Guo
111863b3bba8SJerry Jelinek /**
1119dc0cb1cdSDale Ghent * ixgbe_read_i2c_phy_82598 - Reads 8 bit word over I2C interface.
112063b3bba8SJerry Jelinek * @hw: pointer to hardware structure
1121dc0cb1cdSDale Ghent * @dev_addr: address to read from
1122dc0cb1cdSDale Ghent * @byte_offset: byte offset to read from dev_addr
112363b3bba8SJerry Jelinek * @eeprom_data: value read
112413740cb2SPaul Guo *
112563b3bba8SJerry Jelinek * Performs 8 byte read operation to SFP module's EEPROM over I2C interface.
112663b3bba8SJerry Jelinek **/
ixgbe_read_i2c_phy_82598(struct ixgbe_hw * hw,u8 dev_addr,u8 byte_offset,u8 * eeprom_data)1127dc0cb1cdSDale Ghent static s32 ixgbe_read_i2c_phy_82598(struct ixgbe_hw *hw, u8 dev_addr,
1128dc0cb1cdSDale Ghent u8 byte_offset, u8 *eeprom_data)
112913740cb2SPaul Guo {
113013740cb2SPaul Guo s32 status = IXGBE_SUCCESS;
113113740cb2SPaul Guo u16 sfp_addr = 0;
113213740cb2SPaul Guo u16 sfp_data = 0;
113313740cb2SPaul Guo u16 sfp_stat = 0;
1134dc0cb1cdSDale Ghent u16 gssr;
113513740cb2SPaul Guo u32 i;
113613740cb2SPaul Guo
1137dc0cb1cdSDale Ghent DEBUGFUNC("ixgbe_read_i2c_phy_82598");
1138dc0cb1cdSDale Ghent
1139dc0cb1cdSDale Ghent if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
1140dc0cb1cdSDale Ghent gssr = IXGBE_GSSR_PHY1_SM;
1141dc0cb1cdSDale Ghent else
1142dc0cb1cdSDale Ghent gssr = IXGBE_GSSR_PHY0_SM;
1143dc0cb1cdSDale Ghent
1144dc0cb1cdSDale Ghent if (hw->mac.ops.acquire_swfw_sync(hw, gssr) != IXGBE_SUCCESS)
1145dc0cb1cdSDale Ghent return IXGBE_ERR_SWFW_SYNC;
11463cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
114713740cb2SPaul Guo if (hw->phy.type == ixgbe_phy_nl) {
114813740cb2SPaul Guo /*
114913740cb2SPaul Guo * NetLogic phy SDA/SCL registers are at addresses 0xC30A to
115013740cb2SPaul Guo * 0xC30D. These registers are used to talk to the SFP+
115113740cb2SPaul Guo * module's EEPROM through the SDA/SCL (I2C) interface.
115213740cb2SPaul Guo */
1153dc0cb1cdSDale Ghent sfp_addr = (dev_addr << 8) + byte_offset;
115413740cb2SPaul Guo sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK);
1155dc0cb1cdSDale Ghent hw->phy.ops.write_reg_mdi(hw,
1156dc0cb1cdSDale Ghent IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR,
1157dc0cb1cdSDale Ghent IXGBE_MDIO_PMA_PMD_DEV_TYPE,
1158dc0cb1cdSDale Ghent sfp_addr);
115913740cb2SPaul Guo
116013740cb2SPaul Guo /* Poll status */
116113740cb2SPaul Guo for (i = 0; i < 100; i++) {
1162dc0cb1cdSDale Ghent hw->phy.ops.read_reg_mdi(hw,
1163dc0cb1cdSDale Ghent IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT,
1164dc0cb1cdSDale Ghent IXGBE_MDIO_PMA_PMD_DEV_TYPE,
1165dc0cb1cdSDale Ghent &sfp_stat);
116613740cb2SPaul Guo sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK;
116713740cb2SPaul Guo if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS)
116813740cb2SPaul Guo break;
116913740cb2SPaul Guo msec_delay(10);
117013740cb2SPaul Guo }
117113740cb2SPaul Guo
117213740cb2SPaul Guo if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_PASS) {
117313740cb2SPaul Guo DEBUGOUT("EEPROM read did not pass.\n");
117413740cb2SPaul Guo status = IXGBE_ERR_SFP_NOT_PRESENT;
117513740cb2SPaul Guo goto out;
117613740cb2SPaul Guo }
117713740cb2SPaul Guo
117813740cb2SPaul Guo /* Read data */
1179dc0cb1cdSDale Ghent hw->phy.ops.read_reg_mdi(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA,
1180dc0cb1cdSDale Ghent IXGBE_MDIO_PMA_PMD_DEV_TYPE, &sfp_data);
118113740cb2SPaul Guo
118213740cb2SPaul Guo *eeprom_data = (u8)(sfp_data >> 8);
118313740cb2SPaul Guo } else {
118413740cb2SPaul Guo status = IXGBE_ERR_PHY;
118513740cb2SPaul Guo }
118613740cb2SPaul Guo
118713740cb2SPaul Guo out:
1188dc0cb1cdSDale Ghent hw->mac.ops.release_swfw_sync(hw, gssr);
118963b3bba8SJerry Jelinek return status;
119013740cb2SPaul Guo }
119113740cb2SPaul Guo
1192dc0cb1cdSDale Ghent /**
1193dc0cb1cdSDale Ghent * ixgbe_read_i2c_eeprom_82598 - Reads 8 bit word over I2C interface.
1194dc0cb1cdSDale Ghent * @hw: pointer to hardware structure
1195dc0cb1cdSDale Ghent * @byte_offset: EEPROM byte offset to read
1196dc0cb1cdSDale Ghent * @eeprom_data: value read
1197dc0cb1cdSDale Ghent *
1198dc0cb1cdSDale Ghent * Performs 8 byte read operation to SFP module's EEPROM over I2C interface.
1199dc0cb1cdSDale Ghent **/
ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw * hw,u8 byte_offset,u8 * eeprom_data)1200dc0cb1cdSDale Ghent s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
1201dc0cb1cdSDale Ghent u8 *eeprom_data)
1202dc0cb1cdSDale Ghent {
1203dc0cb1cdSDale Ghent return ixgbe_read_i2c_phy_82598(hw, IXGBE_I2C_EEPROM_DEV_ADDR,
1204dc0cb1cdSDale Ghent byte_offset, eeprom_data);
1205dc0cb1cdSDale Ghent }
1206dc0cb1cdSDale Ghent
1207dc0cb1cdSDale Ghent /**
1208dc0cb1cdSDale Ghent * ixgbe_read_i2c_sff8472_82598 - Reads 8 bit word over I2C interface.
1209dc0cb1cdSDale Ghent * @hw: pointer to hardware structure
1210dc0cb1cdSDale Ghent * @byte_offset: byte offset at address 0xA2
121148ed61a7SRobert Mustacchi * @sff8472_data: value read
1212dc0cb1cdSDale Ghent *
1213dc0cb1cdSDale Ghent * Performs 8 byte read operation to SFP module's SFF-8472 data over I2C
1214dc0cb1cdSDale Ghent **/
ixgbe_read_i2c_sff8472_82598(struct ixgbe_hw * hw,u8 byte_offset,u8 * sff8472_data)1215dc0cb1cdSDale Ghent static s32 ixgbe_read_i2c_sff8472_82598(struct ixgbe_hw *hw, u8 byte_offset,
1216dc0cb1cdSDale Ghent u8 *sff8472_data)
1217dc0cb1cdSDale Ghent {
1218dc0cb1cdSDale Ghent return ixgbe_read_i2c_phy_82598(hw, IXGBE_I2C_EEPROM_DEV_ADDR2,
1219dc0cb1cdSDale Ghent byte_offset, sff8472_data);
1220dc0cb1cdSDale Ghent }
1221dc0cb1cdSDale Ghent
122263b3bba8SJerry Jelinek /**
122363b3bba8SJerry Jelinek * ixgbe_get_supported_physical_layer_82598 - Returns physical layer type
122463b3bba8SJerry Jelinek * @hw: pointer to hardware structure
122513740cb2SPaul Guo *
122663b3bba8SJerry Jelinek * Determines physical layer capabilities of the current configuration.
122763b3bba8SJerry Jelinek **/
ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw * hw)122848ed61a7SRobert Mustacchi u64 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
122913740cb2SPaul Guo {
123048ed61a7SRobert Mustacchi u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
123173cd555cSBin Tu - Sun Microsystems - Beijing China u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
123273cd555cSBin Tu - Sun Microsystems - Beijing China u32 pma_pmd_10g = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
123373cd555cSBin Tu - Sun Microsystems - Beijing China u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
123473cd555cSBin Tu - Sun Microsystems - Beijing China u16 ext_ability = 0;
123513740cb2SPaul Guo
12363cfa0eb9Schenlu chen - Sun Microsystems - Beijing China DEBUGFUNC("ixgbe_get_supported_physical_layer_82598");
12373cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
123873cd555cSBin Tu - Sun Microsystems - Beijing China hw->phy.ops.identify(hw);
123973cd555cSBin Tu - Sun Microsystems - Beijing China
124063b3bba8SJerry Jelinek /* Copper PHY must be checked before AUTOC LMS to determine correct
124163b3bba8SJerry Jelinek * physical layer because 10GBase-T PHYs use LMS = KX4/KX */
124263b3bba8SJerry Jelinek switch (hw->phy.type) {
124363b3bba8SJerry Jelinek case ixgbe_phy_tn:
124463b3bba8SJerry Jelinek case ixgbe_phy_cu_unknown:
124573cd555cSBin Tu - Sun Microsystems - Beijing China hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
124663b3bba8SJerry Jelinek IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability);
124773cd555cSBin Tu - Sun Microsystems - Beijing China if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
124873cd555cSBin Tu - Sun Microsystems - Beijing China physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
124973cd555cSBin Tu - Sun Microsystems - Beijing China if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
125073cd555cSBin Tu - Sun Microsystems - Beijing China physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
125173cd555cSBin Tu - Sun Microsystems - Beijing China if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY)
125273cd555cSBin Tu - Sun Microsystems - Beijing China physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
125373cd555cSBin Tu - Sun Microsystems - Beijing China goto out;
125463b3bba8SJerry Jelinek default:
125563b3bba8SJerry Jelinek break;
125673cd555cSBin Tu - Sun Microsystems - Beijing China }
125773cd555cSBin Tu - Sun Microsystems - Beijing China
125873cd555cSBin Tu - Sun Microsystems - Beijing China switch (autoc & IXGBE_AUTOC_LMS_MASK) {
125973cd555cSBin Tu - Sun Microsystems - Beijing China case IXGBE_AUTOC_LMS_1G_AN:
126073cd555cSBin Tu - Sun Microsystems - Beijing China case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
126173cd555cSBin Tu - Sun Microsystems - Beijing China if (pma_pmd_1g == IXGBE_AUTOC_1G_KX)
126273cd555cSBin Tu - Sun Microsystems - Beijing China physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX;
126373cd555cSBin Tu - Sun Microsystems - Beijing China else
126473cd555cSBin Tu - Sun Microsystems - Beijing China physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX;
126513740cb2SPaul Guo break;
126673cd555cSBin Tu - Sun Microsystems - Beijing China case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
126773cd555cSBin Tu - Sun Microsystems - Beijing China if (pma_pmd_10g == IXGBE_AUTOC_10G_CX4)
126873cd555cSBin Tu - Sun Microsystems - Beijing China physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
126973cd555cSBin Tu - Sun Microsystems - Beijing China else if (pma_pmd_10g == IXGBE_AUTOC_10G_KX4)
127073cd555cSBin Tu - Sun Microsystems - Beijing China physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
127173cd555cSBin Tu - Sun Microsystems - Beijing China else /* XAUI */
127273cd555cSBin Tu - Sun Microsystems - Beijing China physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
127313740cb2SPaul Guo break;
127473cd555cSBin Tu - Sun Microsystems - Beijing China case IXGBE_AUTOC_LMS_KX4_AN:
127573cd555cSBin Tu - Sun Microsystems - Beijing China case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
127673cd555cSBin Tu - Sun Microsystems - Beijing China if (autoc & IXGBE_AUTOC_KX_SUPP)
127773cd555cSBin Tu - Sun Microsystems - Beijing China physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
127873cd555cSBin Tu - Sun Microsystems - Beijing China if (autoc & IXGBE_AUTOC_KX4_SUPP)
127973cd555cSBin Tu - Sun Microsystems - Beijing China physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
128013740cb2SPaul Guo break;
128173cd555cSBin Tu - Sun Microsystems - Beijing China default:
128213740cb2SPaul Guo break;
128373cd555cSBin Tu - Sun Microsystems - Beijing China }
128473cd555cSBin Tu - Sun Microsystems - Beijing China
128573cd555cSBin Tu - Sun Microsystems - Beijing China if (hw->phy.type == ixgbe_phy_nl) {
128613740cb2SPaul Guo hw->phy.ops.identify_sfp(hw);
128713740cb2SPaul Guo
128813740cb2SPaul Guo switch (hw->phy.sfp_type) {
128913740cb2SPaul Guo case ixgbe_sfp_type_da_cu:
129013740cb2SPaul Guo physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
129113740cb2SPaul Guo break;
129213740cb2SPaul Guo case ixgbe_sfp_type_sr:
129313740cb2SPaul Guo physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
129413740cb2SPaul Guo break;
129513740cb2SPaul Guo case ixgbe_sfp_type_lr:
129613740cb2SPaul Guo physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
129713740cb2SPaul Guo break;
129813740cb2SPaul Guo default:
129913740cb2SPaul Guo physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
130013740cb2SPaul Guo break;
130113740cb2SPaul Guo }
130273cd555cSBin Tu - Sun Microsystems - Beijing China }
130313740cb2SPaul Guo
130473cd555cSBin Tu - Sun Microsystems - Beijing China switch (hw->device_id) {
130573cd555cSBin Tu - Sun Microsystems - Beijing China case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
130673cd555cSBin Tu - Sun Microsystems - Beijing China physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
130773cd555cSBin Tu - Sun Microsystems - Beijing China break;
130873cd555cSBin Tu - Sun Microsystems - Beijing China case IXGBE_DEV_ID_82598AF_DUAL_PORT:
130973cd555cSBin Tu - Sun Microsystems - Beijing China case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
131073cd555cSBin Tu - Sun Microsystems - Beijing China case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
131173cd555cSBin Tu - Sun Microsystems - Beijing China physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
131273cd555cSBin Tu - Sun Microsystems - Beijing China break;
131373cd555cSBin Tu - Sun Microsystems - Beijing China case IXGBE_DEV_ID_82598EB_XF_LR:
131473cd555cSBin Tu - Sun Microsystems - Beijing China physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
131573cd555cSBin Tu - Sun Microsystems - Beijing China break;
131613740cb2SPaul Guo default:
131713740cb2SPaul Guo break;
131813740cb2SPaul Guo }
131913740cb2SPaul Guo
132073cd555cSBin Tu - Sun Microsystems - Beijing China out:
132163b3bba8SJerry Jelinek return physical_layer;
132213740cb2SPaul Guo }
1323185c5677SPaul Guo
132463b3bba8SJerry Jelinek /**
132563b3bba8SJerry Jelinek * ixgbe_set_lan_id_multi_port_pcie_82598 - Set LAN id for PCIe multiple
132663b3bba8SJerry Jelinek * port devices.
132763b3bba8SJerry Jelinek * @hw: pointer to the HW structure
1328185c5677SPaul Guo *
132963b3bba8SJerry Jelinek * Calls common function and corrects issue with some single port devices
133063b3bba8SJerry Jelinek * that enable LAN1 but not LAN0.
133163b3bba8SJerry Jelinek **/
ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw * hw)133263b3bba8SJerry Jelinek void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw)
1333185c5677SPaul Guo {
1334185c5677SPaul Guo struct ixgbe_bus_info *bus = &hw->bus;
133563b3bba8SJerry Jelinek u16 pci_gen = 0;
133663b3bba8SJerry Jelinek u16 pci_ctrl2 = 0;
1337185c5677SPaul Guo
13383cfa0eb9Schenlu chen - Sun Microsystems - Beijing China DEBUGFUNC("ixgbe_set_lan_id_multi_port_pcie_82598");
13393cfa0eb9Schenlu chen - Sun Microsystems - Beijing China
1340185c5677SPaul Guo ixgbe_set_lan_id_multi_port_pcie(hw);
1341185c5677SPaul Guo
1342185c5677SPaul Guo /* check if LAN0 is disabled */
1343185c5677SPaul Guo hw->eeprom.ops.read(hw, IXGBE_PCIE_GENERAL_PTR, &pci_gen);
1344185c5677SPaul Guo if ((pci_gen != 0) && (pci_gen != 0xFFFF)) {
134563b3bba8SJerry Jelinek
1346185c5677SPaul Guo hw->eeprom.ops.read(hw, pci_gen + IXGBE_PCIE_CTRL2, &pci_ctrl2);
1347185c5677SPaul Guo
1348185c5677SPaul Guo /* if LAN0 is completely disabled force function to 0 */
1349185c5677SPaul Guo if ((pci_ctrl2 & IXGBE_PCIE_CTRL2_LAN_DISABLE) &&
1350185c5677SPaul Guo !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DISABLE_SELECT) &&
1351185c5677SPaul Guo !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DUMMY_ENABLE)) {
135263b3bba8SJerry Jelinek
1353185c5677SPaul Guo bus->func = 0;
1354185c5677SPaul Guo }
1355185c5677SPaul Guo }
1356185c5677SPaul Guo }
135719843f01SPaul Guo
135863b3bba8SJerry Jelinek /**
135963b3bba8SJerry Jelinek * ixgbe_enable_relaxed_ordering_82598 - enable relaxed ordering
136063b3bba8SJerry Jelinek * @hw: pointer to hardware structure
136119843f01SPaul Guo *
136263b3bba8SJerry Jelinek **/
ixgbe_enable_relaxed_ordering_82598(struct ixgbe_hw * hw)136363b3bba8SJerry Jelinek void ixgbe_enable_relaxed_ordering_82598(struct ixgbe_hw *hw)
136419843f01SPaul Guo {
136519843f01SPaul Guo u32 regval;
136619843f01SPaul Guo u32 i;
136719843f01SPaul Guo
136819843f01SPaul Guo DEBUGFUNC("ixgbe_enable_relaxed_ordering_82598");
136919843f01SPaul Guo
137019843f01SPaul Guo /* Enable relaxed ordering */
137119843f01SPaul Guo for (i = 0; ((i < hw->mac.max_tx_queues) &&
137263b3bba8SJerry Jelinek (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
137319843f01SPaul Guo regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
137469b5a878SDan McDonald regval |= IXGBE_DCA_TXCTRL_DESC_WRO_EN;
137519843f01SPaul Guo IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval);
137619843f01SPaul Guo }
137719843f01SPaul Guo
137819843f01SPaul Guo for (i = 0; ((i < hw->mac.max_rx_queues) &&
137963b3bba8SJerry Jelinek (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
138019843f01SPaul Guo regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
138169b5a878SDan McDonald regval |= IXGBE_DCA_RXCTRL_DATA_WRO_EN |
138269b5a878SDan McDonald IXGBE_DCA_RXCTRL_HEAD_WRO_EN;
138319843f01SPaul Guo IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
138419843f01SPaul Guo }
138563b3bba8SJerry Jelinek
138619843f01SPaul Guo }
138769b5a878SDan McDonald
138869b5a878SDan McDonald /**
138969b5a878SDan McDonald * ixgbe_set_rxpba_82598 - Initialize RX packet buffer
139069b5a878SDan McDonald * @hw: pointer to hardware structure
139169b5a878SDan McDonald * @num_pb: number of packet buffers to allocate
139269b5a878SDan McDonald * @headroom: reserve n KB of headroom
139369b5a878SDan McDonald * @strategy: packet buffer allocation strategy
139469b5a878SDan McDonald **/
ixgbe_set_rxpba_82598(struct ixgbe_hw * hw,int num_pb,u32 headroom,int strategy)139569b5a878SDan McDonald static void ixgbe_set_rxpba_82598(struct ixgbe_hw *hw, int num_pb,
139669b5a878SDan McDonald u32 headroom, int strategy)
139769b5a878SDan McDonald {
139869b5a878SDan McDonald u32 rxpktsize = IXGBE_RXPBSIZE_64KB;
139969b5a878SDan McDonald u8 i = 0;
140069b5a878SDan McDonald UNREFERENCED_1PARAMETER(headroom);
140169b5a878SDan McDonald
140269b5a878SDan McDonald if (!num_pb)
140369b5a878SDan McDonald return;
140469b5a878SDan McDonald
140569b5a878SDan McDonald /* Setup Rx packet buffer sizes */
140669b5a878SDan McDonald switch (strategy) {
140769b5a878SDan McDonald case PBA_STRATEGY_WEIGHTED:
140869b5a878SDan McDonald /* Setup the first four at 80KB */
140969b5a878SDan McDonald rxpktsize = IXGBE_RXPBSIZE_80KB;
141069b5a878SDan McDonald for (; i < 4; i++)
141169b5a878SDan McDonald IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
141269b5a878SDan McDonald /* Setup the last four at 48KB...don't re-init i */
141369b5a878SDan McDonald rxpktsize = IXGBE_RXPBSIZE_48KB;
141469b5a878SDan McDonald /* Fall Through */
141569b5a878SDan McDonald case PBA_STRATEGY_EQUAL:
141669b5a878SDan McDonald default:
141769b5a878SDan McDonald /* Divide the remaining Rx packet buffer evenly among the TCs */
141869b5a878SDan McDonald for (; i < IXGBE_MAX_PACKET_BUFFERS; i++)
141969b5a878SDan McDonald IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
142069b5a878SDan McDonald break;
142169b5a878SDan McDonald }
142269b5a878SDan McDonald
142369b5a878SDan McDonald /* Setup Tx packet buffer sizes */
142469b5a878SDan McDonald for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++)
142569b5a878SDan McDonald IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), IXGBE_TXPBSIZE_40KB);
142669b5a878SDan McDonald }
1427dc0cb1cdSDale Ghent
1428dc0cb1cdSDale Ghent /**
1429dc0cb1cdSDale Ghent * ixgbe_enable_rx_dma_82598 - Enable the Rx DMA unit
1430dc0cb1cdSDale Ghent * @hw: pointer to hardware structure
1431dc0cb1cdSDale Ghent * @regval: register value to write to RXCTRL
1432dc0cb1cdSDale Ghent *
1433dc0cb1cdSDale Ghent * Enables the Rx DMA unit
1434dc0cb1cdSDale Ghent **/
ixgbe_enable_rx_dma_82598(struct ixgbe_hw * hw,u32 regval)1435dc0cb1cdSDale Ghent s32 ixgbe_enable_rx_dma_82598(struct ixgbe_hw *hw, u32 regval)
1436dc0cb1cdSDale Ghent {
1437dc0cb1cdSDale Ghent DEBUGFUNC("ixgbe_enable_rx_dma_82598");
1438dc0cb1cdSDale Ghent
1439dc0cb1cdSDale Ghent IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
1440dc0cb1cdSDale Ghent
1441dc0cb1cdSDale Ghent return IXGBE_SUCCESS;
1442dc0cb1cdSDale Ghent }
1443