447 lines · c
1// SPDX-License-Identifier: GPL-2.02/* 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 hardware14 * @hw: pointer to the HW structure15 *16 * This resets the hardware into a known state. This is a17 * 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 connection25 * 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 not48 * return with an error. This can happen in situations49 * 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 structure64 */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 = FIELD_GET(IGC_EECD_SIZE_EX_MASK, eecd);72 73 /* Added to a constant, "size" becomes the left-shift value74 * for setting word_size.75 */76 size += NVM_WORD_SIZE_BASE_SHIFT;77 78 /* Just in case size is out of range, cap it to the largest79 * EEPROM size supported80 */81 if (size > 15)82 size = 15;83 84 nvm->type = igc_nvm_eeprom_spi;85 nvm->word_size = BIT(size);86 nvm->opcode_bits = 8;87 nvm->delay_usec = 1;88 89 nvm->page_size = eecd & IGC_EECD_ADDR_BITS ? 32 : 8;90 nvm->address_bits = eecd & IGC_EECD_ADDR_BITS ?91 16 : 8;92 93 if (nvm->word_size == BIT(15))94 nvm->page_size = 128;95 96 return 0;97}98 99/**100 * igc_setup_copper_link_base - Configure copper link settings101 * @hw: pointer to the HW structure102 *103 * Configures the link for auto-neg or forced speed and duplex. Then we check104 * for link, once link is established calls to configure collision distance105 * and flow control are called.106 */107static s32 igc_setup_copper_link_base(struct igc_hw *hw)108{109 s32 ret_val = 0;110 u32 ctrl;111 112 ctrl = rd32(IGC_CTRL);113 ctrl |= IGC_CTRL_SLU;114 ctrl &= ~(IGC_CTRL_FRCSPD | IGC_CTRL_FRCDPX);115 wr32(IGC_CTRL, ctrl);116 117 ret_val = igc_setup_copper_link(hw);118 119 return ret_val;120}121 122/**123 * igc_init_mac_params_base - Init MAC func ptrs.124 * @hw: pointer to the HW structure125 */126static s32 igc_init_mac_params_base(struct igc_hw *hw)127{128 struct igc_dev_spec_base *dev_spec = &hw->dev_spec._base;129 struct igc_mac_info *mac = &hw->mac;130 131 /* Set mta register count */132 mac->mta_reg_count = 128;133 mac->rar_entry_count = IGC_RAR_ENTRIES;134 135 /* reset */136 mac->ops.reset_hw = igc_reset_hw_base;137 138 mac->ops.acquire_swfw_sync = igc_acquire_swfw_sync_i225;139 mac->ops.release_swfw_sync = igc_release_swfw_sync_i225;140 141 /* Allow a single clear of the SW semaphore on I225 */142 if (mac->type == igc_i225)143 dev_spec->clear_semaphore_once = true;144 145 /* physical interface link setup */146 mac->ops.setup_physical_interface = igc_setup_copper_link_base;147 148 return 0;149}150 151/**152 * igc_init_phy_params_base - Init PHY func ptrs.153 * @hw: pointer to the HW structure154 */155static s32 igc_init_phy_params_base(struct igc_hw *hw)156{157 struct igc_phy_info *phy = &hw->phy;158 s32 ret_val = 0;159 160 phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT_2500;161 phy->reset_delay_us = 100;162 163 /* set lan id */164 hw->bus.func = FIELD_GET(IGC_STATUS_FUNC_MASK, rd32(IGC_STATUS));165 166 /* Make sure the PHY is in a good state. Several people have reported167 * firmware leaving the PHY's page select register set to something168 * other than the default of zero, which causes the PHY ID read to169 * access something other than the intended register.170 */171 ret_val = hw->phy.ops.reset(hw);172 if (ret_val) {173 hw_dbg("Error resetting the PHY\n");174 goto out;175 }176 177 ret_val = igc_get_phy_id(hw);178 if (ret_val)179 return ret_val;180 181 igc_check_for_copper_link(hw);182 183out:184 return ret_val;185}186 187static s32 igc_get_invariants_base(struct igc_hw *hw)188{189 struct igc_mac_info *mac = &hw->mac;190 s32 ret_val = 0;191 192 switch (hw->device_id) {193 case IGC_DEV_ID_I225_LM:194 case IGC_DEV_ID_I225_V:195 case IGC_DEV_ID_I225_I:196 case IGC_DEV_ID_I220_V:197 case IGC_DEV_ID_I225_K:198 case IGC_DEV_ID_I225_K2:199 case IGC_DEV_ID_I226_K:200 case IGC_DEV_ID_I225_LMVP:201 case IGC_DEV_ID_I226_LMVP:202 case IGC_DEV_ID_I225_IT:203 case IGC_DEV_ID_I226_LM:204 case IGC_DEV_ID_I226_V:205 case IGC_DEV_ID_I226_IT:206 case IGC_DEV_ID_I221_V:207 case IGC_DEV_ID_I226_BLANK_NVM:208 case IGC_DEV_ID_I225_BLANK_NVM:209 mac->type = igc_i225;210 break;211 default:212 return -IGC_ERR_MAC_INIT;213 }214 215 hw->phy.media_type = igc_media_type_copper;216 217 /* mac initialization and operations */218 ret_val = igc_init_mac_params_base(hw);219 if (ret_val)220 goto out;221 222 /* NVM initialization */223 ret_val = igc_init_nvm_params_base(hw);224 switch (hw->mac.type) {225 case igc_i225:226 ret_val = igc_init_nvm_params_i225(hw);227 break;228 default:229 break;230 }231 232 /* setup PHY parameters */233 ret_val = igc_init_phy_params_base(hw);234 if (ret_val)235 goto out;236 237out:238 return ret_val;239}240 241/**242 * igc_acquire_phy_base - Acquire rights to access PHY243 * @hw: pointer to the HW structure244 *245 * Acquire access rights to the correct PHY. This is a246 * function pointer entry point called by the api module.247 */248static s32 igc_acquire_phy_base(struct igc_hw *hw)249{250 u16 mask = IGC_SWFW_PHY0_SM;251 252 return hw->mac.ops.acquire_swfw_sync(hw, mask);253}254 255/**256 * igc_release_phy_base - Release rights to access PHY257 * @hw: pointer to the HW structure258 *259 * A wrapper to release access rights to the correct PHY. This is a260 * function pointer entry point called by the api module.261 */262static void igc_release_phy_base(struct igc_hw *hw)263{264 u16 mask = IGC_SWFW_PHY0_SM;265 266 hw->mac.ops.release_swfw_sync(hw, mask);267}268 269/**270 * igc_init_hw_base - Initialize hardware271 * @hw: pointer to the HW structure272 *273 * This inits the hardware readying it for operation.274 */275static s32 igc_init_hw_base(struct igc_hw *hw)276{277 struct igc_mac_info *mac = &hw->mac;278 u16 i, rar_count = mac->rar_entry_count;279 s32 ret_val = 0;280 281 /* Setup the receive address */282 igc_init_rx_addrs(hw, rar_count);283 284 /* Zero out the Multicast HASH table */285 hw_dbg("Zeroing the MTA\n");286 for (i = 0; i < mac->mta_reg_count; i++)287 array_wr32(IGC_MTA, i, 0);288 289 /* Zero out the Unicast HASH table */290 hw_dbg("Zeroing the UTA\n");291 for (i = 0; i < mac->uta_reg_count; i++)292 array_wr32(IGC_UTA, i, 0);293 294 /* Setup link and flow control */295 ret_val = igc_setup_link(hw);296 297 /* Clear all of the statistics registers (clear on read). It is298 * important that we do this after we have tried to establish link299 * because the symbol error count will increment wildly if there300 * is no link.301 */302 igc_clear_hw_cntrs_base(hw);303 304 return ret_val;305}306 307/**308 * igc_power_down_phy_copper_base - Remove link during PHY power down309 * @hw: pointer to the HW structure310 *311 * In the case of a PHY power down to save power, or to turn off link during a312 * driver unload, or wake on lan is not enabled, remove the link.313 */314void igc_power_down_phy_copper_base(struct igc_hw *hw)315{316 /* If the management interface is not enabled, then power down */317 if (!(igc_enable_mng_pass_thru(hw) || igc_check_reset_block(hw)))318 igc_power_down_phy_copper(hw);319}320 321/**322 * igc_rx_fifo_flush_base - Clean rx fifo after Rx enable323 * @hw: pointer to the HW structure324 *325 * After Rx enable, if manageability is enabled then there is likely some326 * bad data at the start of the fifo and possibly in the DMA fifo. This327 * function clears the fifos and flushes any packets that came in as rx was328 * being enabled.329 */330void igc_rx_fifo_flush_base(struct igc_hw *hw)331{332 u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;333 int i, ms_wait;334 335 /* disable IPv6 options as per hardware errata */336 rfctl = rd32(IGC_RFCTL);337 rfctl |= IGC_RFCTL_IPV6_EX_DIS;338 wr32(IGC_RFCTL, rfctl);339 340 if (!(rd32(IGC_MANC) & IGC_MANC_RCV_TCO_EN))341 return;342 343 /* Disable all Rx queues */344 for (i = 0; i < 4; i++) {345 rxdctl[i] = rd32(IGC_RXDCTL(i));346 wr32(IGC_RXDCTL(i),347 rxdctl[i] & ~IGC_RXDCTL_QUEUE_ENABLE);348 }349 /* Poll all queues to verify they have shut down */350 for (ms_wait = 0; ms_wait < 10; ms_wait++) {351 usleep_range(1000, 2000);352 rx_enabled = 0;353 for (i = 0; i < 4; i++)354 rx_enabled |= rd32(IGC_RXDCTL(i));355 if (!(rx_enabled & IGC_RXDCTL_QUEUE_ENABLE))356 break;357 }358 359 if (ms_wait == 10)360 hw_dbg("Queue disable timed out after 10ms\n");361 362 /* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all363 * incoming packets are rejected. Set enable and wait 2ms so that364 * any packet that was coming in as RCTL.EN was set is flushed365 */366 wr32(IGC_RFCTL, rfctl & ~IGC_RFCTL_LEF);367 368 rlpml = rd32(IGC_RLPML);369 wr32(IGC_RLPML, 0);370 371 rctl = rd32(IGC_RCTL);372 temp_rctl = rctl & ~(IGC_RCTL_EN | IGC_RCTL_SBP);373 temp_rctl |= IGC_RCTL_LPE;374 375 wr32(IGC_RCTL, temp_rctl);376 wr32(IGC_RCTL, temp_rctl | IGC_RCTL_EN);377 wrfl();378 usleep_range(2000, 3000);379 380 /* Enable Rx queues that were previously enabled and restore our381 * previous state382 */383 for (i = 0; i < 4; i++)384 wr32(IGC_RXDCTL(i), rxdctl[i]);385 wr32(IGC_RCTL, rctl);386 wrfl();387 388 wr32(IGC_RLPML, rlpml);389 wr32(IGC_RFCTL, rfctl);390 391 /* Flush receive errors generated by workaround */392 rd32(IGC_ROC);393 rd32(IGC_RNBC);394 rd32(IGC_MPC);395}396 397bool igc_is_device_id_i225(struct igc_hw *hw)398{399 switch (hw->device_id) {400 case IGC_DEV_ID_I225_LM:401 case IGC_DEV_ID_I225_V:402 case IGC_DEV_ID_I225_I:403 case IGC_DEV_ID_I225_K:404 case IGC_DEV_ID_I225_K2:405 case IGC_DEV_ID_I225_LMVP:406 case IGC_DEV_ID_I225_IT:407 return true;408 default:409 return false;410 }411}412 413bool igc_is_device_id_i226(struct igc_hw *hw)414{415 switch (hw->device_id) {416 case IGC_DEV_ID_I226_LM:417 case IGC_DEV_ID_I226_V:418 case IGC_DEV_ID_I226_K:419 case IGC_DEV_ID_I226_IT:420 return true;421 default:422 return false;423 }424}425 426static struct igc_mac_operations igc_mac_ops_base = {427 .init_hw = igc_init_hw_base,428 .check_for_link = igc_check_for_copper_link,429 .rar_set = igc_rar_set,430 .read_mac_addr = igc_read_mac_addr,431 .get_speed_and_duplex = igc_get_speed_and_duplex_copper,432};433 434static const struct igc_phy_operations igc_phy_ops_base = {435 .acquire = igc_acquire_phy_base,436 .release = igc_release_phy_base,437 .reset = igc_phy_hw_reset,438 .read_reg = igc_read_phy_reg_gpy,439 .write_reg = igc_write_phy_reg_gpy,440};441 442const struct igc_info igc_base_info = {443 .get_invariants = igc_get_invariants_base,444 .mac_ops = &igc_mac_ops_base,445 .phy_ops = &igc_phy_ops_base,446};447