brintos

brintos / linux-shallow public Read only

0
0
Text · 10.6 KiB · 9fae8bd Raw
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