cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

igc_base.c (10412B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Copyright (c)  2018 Intel Corporation */
      3
      4#include <linux/delay.h>
      5
      6#include "igc_hw.h"
      7#include "igc_i225.h"
      8#include "igc_mac.h"
      9#include "igc_base.h"
     10#include "igc.h"
     11
     12/**
     13 * igc_reset_hw_base - Reset hardware
     14 * @hw: pointer to the HW structure
     15 *
     16 * This resets the hardware into a known state.  This is a
     17 * function pointer entry point called by the api module.
     18 */
     19static s32 igc_reset_hw_base(struct igc_hw *hw)
     20{
     21	s32 ret_val;
     22	u32 ctrl;
     23
     24	/* Prevent the PCI-E bus from sticking if there is no TLP connection
     25	 * on the last TLP read/write transaction when MAC is reset.
     26	 */
     27	ret_val = igc_disable_pcie_master(hw);
     28	if (ret_val)
     29		hw_dbg("PCI-E Master disable polling has failed\n");
     30
     31	hw_dbg("Masking off all interrupts\n");
     32	wr32(IGC_IMC, 0xffffffff);
     33
     34	wr32(IGC_RCTL, 0);
     35	wr32(IGC_TCTL, IGC_TCTL_PSP);
     36	wrfl();
     37
     38	usleep_range(10000, 20000);
     39
     40	ctrl = rd32(IGC_CTRL);
     41
     42	hw_dbg("Issuing a global reset to MAC\n");
     43	wr32(IGC_CTRL, ctrl | IGC_CTRL_RST);
     44
     45	ret_val = igc_get_auto_rd_done(hw);
     46	if (ret_val) {
     47		/* When auto config read does not complete, do not
     48		 * return with an error. This can happen in situations
     49		 * where there is no eeprom and prevents getting link.
     50		 */
     51		hw_dbg("Auto Read Done did not complete\n");
     52	}
     53
     54	/* Clear any pending interrupt events. */
     55	wr32(IGC_IMC, 0xffffffff);
     56	rd32(IGC_ICR);
     57
     58	return ret_val;
     59}
     60
     61/**
     62 * igc_init_nvm_params_base - Init NVM func ptrs.
     63 * @hw: pointer to the HW structure
     64 */
     65static s32 igc_init_nvm_params_base(struct igc_hw *hw)
     66{
     67	struct igc_nvm_info *nvm = &hw->nvm;
     68	u32 eecd = rd32(IGC_EECD);
     69	u16 size;
     70
     71	size = (u16)((eecd & IGC_EECD_SIZE_EX_MASK) >>
     72		     IGC_EECD_SIZE_EX_SHIFT);
     73
     74	/* Added to a constant, "size" becomes the left-shift value
     75	 * for setting word_size.
     76	 */
     77	size += NVM_WORD_SIZE_BASE_SHIFT;
     78
     79	/* Just in case size is out of range, cap it to the largest
     80	 * EEPROM size supported
     81	 */
     82	if (size > 15)
     83		size = 15;
     84
     85	nvm->type = igc_nvm_eeprom_spi;
     86	nvm->word_size = BIT(size);
     87	nvm->opcode_bits = 8;
     88	nvm->delay_usec = 1;
     89
     90	nvm->page_size = eecd & IGC_EECD_ADDR_BITS ? 32 : 8;
     91	nvm->address_bits = eecd & IGC_EECD_ADDR_BITS ?
     92			    16 : 8;
     93
     94	if (nvm->word_size == BIT(15))
     95		nvm->page_size = 128;
     96
     97	return 0;
     98}
     99
    100/**
    101 * igc_setup_copper_link_base - Configure copper link settings
    102 * @hw: pointer to the HW structure
    103 *
    104 * Configures the link for auto-neg or forced speed and duplex.  Then we check
    105 * for link, once link is established calls to configure collision distance
    106 * and flow control are called.
    107 */
    108static s32 igc_setup_copper_link_base(struct igc_hw *hw)
    109{
    110	s32  ret_val = 0;
    111	u32 ctrl;
    112
    113	ctrl = rd32(IGC_CTRL);
    114	ctrl |= IGC_CTRL_SLU;
    115	ctrl &= ~(IGC_CTRL_FRCSPD | IGC_CTRL_FRCDPX);
    116	wr32(IGC_CTRL, ctrl);
    117
    118	ret_val = igc_setup_copper_link(hw);
    119
    120	return ret_val;
    121}
    122
    123/**
    124 * igc_init_mac_params_base - Init MAC func ptrs.
    125 * @hw: pointer to the HW structure
    126 */
    127static s32 igc_init_mac_params_base(struct igc_hw *hw)
    128{
    129	struct igc_dev_spec_base *dev_spec = &hw->dev_spec._base;
    130	struct igc_mac_info *mac = &hw->mac;
    131
    132	/* Set mta register count */
    133	mac->mta_reg_count = 128;
    134	mac->rar_entry_count = IGC_RAR_ENTRIES;
    135
    136	/* reset */
    137	mac->ops.reset_hw = igc_reset_hw_base;
    138
    139	mac->ops.acquire_swfw_sync = igc_acquire_swfw_sync_i225;
    140	mac->ops.release_swfw_sync = igc_release_swfw_sync_i225;
    141
    142	/* Allow a single clear of the SW semaphore on I225 */
    143	if (mac->type == igc_i225)
    144		dev_spec->clear_semaphore_once = true;
    145
    146	/* physical interface link setup */
    147	mac->ops.setup_physical_interface = igc_setup_copper_link_base;
    148
    149	return 0;
    150}
    151
    152/**
    153 * igc_init_phy_params_base - Init PHY func ptrs.
    154 * @hw: pointer to the HW structure
    155 */
    156static s32 igc_init_phy_params_base(struct igc_hw *hw)
    157{
    158	struct igc_phy_info *phy = &hw->phy;
    159	s32 ret_val = 0;
    160
    161	phy->autoneg_mask	= AUTONEG_ADVERTISE_SPEED_DEFAULT_2500;
    162	phy->reset_delay_us	= 100;
    163
    164	/* set lan id */
    165	hw->bus.func = (rd32(IGC_STATUS) & IGC_STATUS_FUNC_MASK) >>
    166			IGC_STATUS_FUNC_SHIFT;
    167
    168	/* Make sure the PHY is in a good state. Several people have reported
    169	 * firmware leaving the PHY's page select register set to something
    170	 * other than the default of zero, which causes the PHY ID read to
    171	 * access something other than the intended register.
    172	 */
    173	ret_val = hw->phy.ops.reset(hw);
    174	if (ret_val) {
    175		hw_dbg("Error resetting the PHY\n");
    176		goto out;
    177	}
    178
    179	ret_val = igc_get_phy_id(hw);
    180	if (ret_val)
    181		return ret_val;
    182
    183	igc_check_for_copper_link(hw);
    184
    185out:
    186	return ret_val;
    187}
    188
    189static s32 igc_get_invariants_base(struct igc_hw *hw)
    190{
    191	struct igc_mac_info *mac = &hw->mac;
    192	s32 ret_val = 0;
    193
    194	switch (hw->device_id) {
    195	case IGC_DEV_ID_I225_LM:
    196	case IGC_DEV_ID_I225_V:
    197	case IGC_DEV_ID_I225_I:
    198	case IGC_DEV_ID_I220_V:
    199	case IGC_DEV_ID_I225_K:
    200	case IGC_DEV_ID_I225_K2:
    201	case IGC_DEV_ID_I226_K:
    202	case IGC_DEV_ID_I225_LMVP:
    203	case IGC_DEV_ID_I226_LMVP:
    204	case IGC_DEV_ID_I225_IT:
    205	case IGC_DEV_ID_I226_LM:
    206	case IGC_DEV_ID_I226_V:
    207	case IGC_DEV_ID_I226_IT:
    208	case IGC_DEV_ID_I221_V:
    209	case IGC_DEV_ID_I226_BLANK_NVM:
    210	case IGC_DEV_ID_I225_BLANK_NVM:
    211		mac->type = igc_i225;
    212		break;
    213	default:
    214		return -IGC_ERR_MAC_INIT;
    215	}
    216
    217	hw->phy.media_type = igc_media_type_copper;
    218
    219	/* mac initialization and operations */
    220	ret_val = igc_init_mac_params_base(hw);
    221	if (ret_val)
    222		goto out;
    223
    224	/* NVM initialization */
    225	ret_val = igc_init_nvm_params_base(hw);
    226	switch (hw->mac.type) {
    227	case igc_i225:
    228		ret_val = igc_init_nvm_params_i225(hw);
    229		break;
    230	default:
    231		break;
    232	}
    233
    234	/* setup PHY parameters */
    235	ret_val = igc_init_phy_params_base(hw);
    236	if (ret_val)
    237		goto out;
    238
    239out:
    240	return ret_val;
    241}
    242
    243/**
    244 * igc_acquire_phy_base - Acquire rights to access PHY
    245 * @hw: pointer to the HW structure
    246 *
    247 * Acquire access rights to the correct PHY.  This is a
    248 * function pointer entry point called by the api module.
    249 */
    250static s32 igc_acquire_phy_base(struct igc_hw *hw)
    251{
    252	u16 mask = IGC_SWFW_PHY0_SM;
    253
    254	return hw->mac.ops.acquire_swfw_sync(hw, mask);
    255}
    256
    257/**
    258 * igc_release_phy_base - Release rights to access PHY
    259 * @hw: pointer to the HW structure
    260 *
    261 * A wrapper to release access rights to the correct PHY.  This is a
    262 * function pointer entry point called by the api module.
    263 */
    264static void igc_release_phy_base(struct igc_hw *hw)
    265{
    266	u16 mask = IGC_SWFW_PHY0_SM;
    267
    268	hw->mac.ops.release_swfw_sync(hw, mask);
    269}
    270
    271/**
    272 * igc_init_hw_base - Initialize hardware
    273 * @hw: pointer to the HW structure
    274 *
    275 * This inits the hardware readying it for operation.
    276 */
    277static s32 igc_init_hw_base(struct igc_hw *hw)
    278{
    279	struct igc_mac_info *mac = &hw->mac;
    280	u16 i, rar_count = mac->rar_entry_count;
    281	s32 ret_val = 0;
    282
    283	/* Setup the receive address */
    284	igc_init_rx_addrs(hw, rar_count);
    285
    286	/* Zero out the Multicast HASH table */
    287	hw_dbg("Zeroing the MTA\n");
    288	for (i = 0; i < mac->mta_reg_count; i++)
    289		array_wr32(IGC_MTA, i, 0);
    290
    291	/* Zero out the Unicast HASH table */
    292	hw_dbg("Zeroing the UTA\n");
    293	for (i = 0; i < mac->uta_reg_count; i++)
    294		array_wr32(IGC_UTA, i, 0);
    295
    296	/* Setup link and flow control */
    297	ret_val = igc_setup_link(hw);
    298
    299	/* Clear all of the statistics registers (clear on read).  It is
    300	 * important that we do this after we have tried to establish link
    301	 * because the symbol error count will increment wildly if there
    302	 * is no link.
    303	 */
    304	igc_clear_hw_cntrs_base(hw);
    305
    306	return ret_val;
    307}
    308
    309/**
    310 * igc_power_down_phy_copper_base - Remove link during PHY power down
    311 * @hw: pointer to the HW structure
    312 *
    313 * In the case of a PHY power down to save power, or to turn off link during a
    314 * driver unload, or wake on lan is not enabled, remove the link.
    315 */
    316void igc_power_down_phy_copper_base(struct igc_hw *hw)
    317{
    318	/* If the management interface is not enabled, then power down */
    319	if (!(igc_enable_mng_pass_thru(hw) || igc_check_reset_block(hw)))
    320		igc_power_down_phy_copper(hw);
    321}
    322
    323/**
    324 * igc_rx_fifo_flush_base - Clean rx fifo after Rx enable
    325 * @hw: pointer to the HW structure
    326 *
    327 * After Rx enable, if manageability is enabled then there is likely some
    328 * bad data at the start of the fifo and possibly in the DMA fifo.  This
    329 * function clears the fifos and flushes any packets that came in as rx was
    330 * being enabled.
    331 */
    332void igc_rx_fifo_flush_base(struct igc_hw *hw)
    333{
    334	u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
    335	int i, ms_wait;
    336
    337	/* disable IPv6 options as per hardware errata */
    338	rfctl = rd32(IGC_RFCTL);
    339	rfctl |= IGC_RFCTL_IPV6_EX_DIS;
    340	wr32(IGC_RFCTL, rfctl);
    341
    342	if (!(rd32(IGC_MANC) & IGC_MANC_RCV_TCO_EN))
    343		return;
    344
    345	/* Disable all Rx queues */
    346	for (i = 0; i < 4; i++) {
    347		rxdctl[i] = rd32(IGC_RXDCTL(i));
    348		wr32(IGC_RXDCTL(i),
    349		     rxdctl[i] & ~IGC_RXDCTL_QUEUE_ENABLE);
    350	}
    351	/* Poll all queues to verify they have shut down */
    352	for (ms_wait = 0; ms_wait < 10; ms_wait++) {
    353		usleep_range(1000, 2000);
    354		rx_enabled = 0;
    355		for (i = 0; i < 4; i++)
    356			rx_enabled |= rd32(IGC_RXDCTL(i));
    357		if (!(rx_enabled & IGC_RXDCTL_QUEUE_ENABLE))
    358			break;
    359	}
    360
    361	if (ms_wait == 10)
    362		hw_dbg("Queue disable timed out after 10ms\n");
    363
    364	/* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
    365	 * incoming packets are rejected.  Set enable and wait 2ms so that
    366	 * any packet that was coming in as RCTL.EN was set is flushed
    367	 */
    368	wr32(IGC_RFCTL, rfctl & ~IGC_RFCTL_LEF);
    369
    370	rlpml = rd32(IGC_RLPML);
    371	wr32(IGC_RLPML, 0);
    372
    373	rctl = rd32(IGC_RCTL);
    374	temp_rctl = rctl & ~(IGC_RCTL_EN | IGC_RCTL_SBP);
    375	temp_rctl |= IGC_RCTL_LPE;
    376
    377	wr32(IGC_RCTL, temp_rctl);
    378	wr32(IGC_RCTL, temp_rctl | IGC_RCTL_EN);
    379	wrfl();
    380	usleep_range(2000, 3000);
    381
    382	/* Enable Rx queues that were previously enabled and restore our
    383	 * previous state
    384	 */
    385	for (i = 0; i < 4; i++)
    386		wr32(IGC_RXDCTL(i), rxdctl[i]);
    387	wr32(IGC_RCTL, rctl);
    388	wrfl();
    389
    390	wr32(IGC_RLPML, rlpml);
    391	wr32(IGC_RFCTL, rfctl);
    392
    393	/* Flush receive errors generated by workaround */
    394	rd32(IGC_ROC);
    395	rd32(IGC_RNBC);
    396	rd32(IGC_MPC);
    397}
    398
    399static struct igc_mac_operations igc_mac_ops_base = {
    400	.init_hw		= igc_init_hw_base,
    401	.check_for_link		= igc_check_for_copper_link,
    402	.rar_set		= igc_rar_set,
    403	.read_mac_addr		= igc_read_mac_addr,
    404	.get_speed_and_duplex	= igc_get_speed_and_duplex_copper,
    405};
    406
    407static const struct igc_phy_operations igc_phy_ops_base = {
    408	.acquire		= igc_acquire_phy_base,
    409	.release		= igc_release_phy_base,
    410	.reset			= igc_phy_hw_reset,
    411	.read_reg		= igc_read_phy_reg_gpy,
    412	.write_reg		= igc_write_phy_reg_gpy,
    413};
    414
    415const struct igc_info igc_base_info = {
    416	.get_invariants		= igc_get_invariants_base,
    417	.mac_ops		= &igc_mac_ops_base,
    418	.phy_ops		= &igc_phy_ops_base,
    419};