0001
0002
0003
0004 #include <linux/delay.h>
0005
0006 #include "igc_hw.h"
0007 #include "igc_i225.h"
0008 #include "igc_mac.h"
0009 #include "igc_base.h"
0010 #include "igc.h"
0011
0012
0013
0014
0015
0016
0017
0018
0019 static s32 igc_reset_hw_base(struct igc_hw *hw)
0020 {
0021 s32 ret_val;
0022 u32 ctrl;
0023
0024
0025
0026
0027 ret_val = igc_disable_pcie_master(hw);
0028 if (ret_val)
0029 hw_dbg("PCI-E Master disable polling has failed\n");
0030
0031 hw_dbg("Masking off all interrupts\n");
0032 wr32(IGC_IMC, 0xffffffff);
0033
0034 wr32(IGC_RCTL, 0);
0035 wr32(IGC_TCTL, IGC_TCTL_PSP);
0036 wrfl();
0037
0038 usleep_range(10000, 20000);
0039
0040 ctrl = rd32(IGC_CTRL);
0041
0042 hw_dbg("Issuing a global reset to MAC\n");
0043 wr32(IGC_CTRL, ctrl | IGC_CTRL_RST);
0044
0045 ret_val = igc_get_auto_rd_done(hw);
0046 if (ret_val) {
0047
0048
0049
0050
0051 hw_dbg("Auto Read Done did not complete\n");
0052 }
0053
0054
0055 wr32(IGC_IMC, 0xffffffff);
0056 rd32(IGC_ICR);
0057
0058 return ret_val;
0059 }
0060
0061
0062
0063
0064
0065 static s32 igc_init_nvm_params_base(struct igc_hw *hw)
0066 {
0067 struct igc_nvm_info *nvm = &hw->nvm;
0068 u32 eecd = rd32(IGC_EECD);
0069 u16 size;
0070
0071 size = (u16)((eecd & IGC_EECD_SIZE_EX_MASK) >>
0072 IGC_EECD_SIZE_EX_SHIFT);
0073
0074
0075
0076
0077 size += NVM_WORD_SIZE_BASE_SHIFT;
0078
0079
0080
0081
0082 if (size > 15)
0083 size = 15;
0084
0085 nvm->type = igc_nvm_eeprom_spi;
0086 nvm->word_size = BIT(size);
0087 nvm->opcode_bits = 8;
0088 nvm->delay_usec = 1;
0089
0090 nvm->page_size = eecd & IGC_EECD_ADDR_BITS ? 32 : 8;
0091 nvm->address_bits = eecd & IGC_EECD_ADDR_BITS ?
0092 16 : 8;
0093
0094 if (nvm->word_size == BIT(15))
0095 nvm->page_size = 128;
0096
0097 return 0;
0098 }
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108 static s32 igc_setup_copper_link_base(struct igc_hw *hw)
0109 {
0110 s32 ret_val = 0;
0111 u32 ctrl;
0112
0113 ctrl = rd32(IGC_CTRL);
0114 ctrl |= IGC_CTRL_SLU;
0115 ctrl &= ~(IGC_CTRL_FRCSPD | IGC_CTRL_FRCDPX);
0116 wr32(IGC_CTRL, ctrl);
0117
0118 ret_val = igc_setup_copper_link(hw);
0119
0120 return ret_val;
0121 }
0122
0123
0124
0125
0126
0127 static s32 igc_init_mac_params_base(struct igc_hw *hw)
0128 {
0129 struct igc_dev_spec_base *dev_spec = &hw->dev_spec._base;
0130 struct igc_mac_info *mac = &hw->mac;
0131
0132
0133 mac->mta_reg_count = 128;
0134 mac->rar_entry_count = IGC_RAR_ENTRIES;
0135
0136
0137 mac->ops.reset_hw = igc_reset_hw_base;
0138
0139 mac->ops.acquire_swfw_sync = igc_acquire_swfw_sync_i225;
0140 mac->ops.release_swfw_sync = igc_release_swfw_sync_i225;
0141
0142
0143 if (mac->type == igc_i225)
0144 dev_spec->clear_semaphore_once = true;
0145
0146
0147 mac->ops.setup_physical_interface = igc_setup_copper_link_base;
0148
0149 return 0;
0150 }
0151
0152
0153
0154
0155
0156 static s32 igc_init_phy_params_base(struct igc_hw *hw)
0157 {
0158 struct igc_phy_info *phy = &hw->phy;
0159 s32 ret_val = 0;
0160
0161 phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT_2500;
0162 phy->reset_delay_us = 100;
0163
0164
0165 hw->bus.func = (rd32(IGC_STATUS) & IGC_STATUS_FUNC_MASK) >>
0166 IGC_STATUS_FUNC_SHIFT;
0167
0168
0169
0170
0171
0172
0173 ret_val = hw->phy.ops.reset(hw);
0174 if (ret_val) {
0175 hw_dbg("Error resetting the PHY\n");
0176 goto out;
0177 }
0178
0179 ret_val = igc_get_phy_id(hw);
0180 if (ret_val)
0181 return ret_val;
0182
0183 igc_check_for_copper_link(hw);
0184
0185 out:
0186 return ret_val;
0187 }
0188
0189 static s32 igc_get_invariants_base(struct igc_hw *hw)
0190 {
0191 struct igc_mac_info *mac = &hw->mac;
0192 s32 ret_val = 0;
0193
0194 switch (hw->device_id) {
0195 case IGC_DEV_ID_I225_LM:
0196 case IGC_DEV_ID_I225_V:
0197 case IGC_DEV_ID_I225_I:
0198 case IGC_DEV_ID_I220_V:
0199 case IGC_DEV_ID_I225_K:
0200 case IGC_DEV_ID_I225_K2:
0201 case IGC_DEV_ID_I226_K:
0202 case IGC_DEV_ID_I225_LMVP:
0203 case IGC_DEV_ID_I226_LMVP:
0204 case IGC_DEV_ID_I225_IT:
0205 case IGC_DEV_ID_I226_LM:
0206 case IGC_DEV_ID_I226_V:
0207 case IGC_DEV_ID_I226_IT:
0208 case IGC_DEV_ID_I221_V:
0209 case IGC_DEV_ID_I226_BLANK_NVM:
0210 case IGC_DEV_ID_I225_BLANK_NVM:
0211 mac->type = igc_i225;
0212 break;
0213 default:
0214 return -IGC_ERR_MAC_INIT;
0215 }
0216
0217 hw->phy.media_type = igc_media_type_copper;
0218
0219
0220 ret_val = igc_init_mac_params_base(hw);
0221 if (ret_val)
0222 goto out;
0223
0224
0225 ret_val = igc_init_nvm_params_base(hw);
0226 switch (hw->mac.type) {
0227 case igc_i225:
0228 ret_val = igc_init_nvm_params_i225(hw);
0229 break;
0230 default:
0231 break;
0232 }
0233
0234
0235 ret_val = igc_init_phy_params_base(hw);
0236 if (ret_val)
0237 goto out;
0238
0239 out:
0240 return ret_val;
0241 }
0242
0243
0244
0245
0246
0247
0248
0249
0250 static s32 igc_acquire_phy_base(struct igc_hw *hw)
0251 {
0252 u16 mask = IGC_SWFW_PHY0_SM;
0253
0254 return hw->mac.ops.acquire_swfw_sync(hw, mask);
0255 }
0256
0257
0258
0259
0260
0261
0262
0263
0264 static void igc_release_phy_base(struct igc_hw *hw)
0265 {
0266 u16 mask = IGC_SWFW_PHY0_SM;
0267
0268 hw->mac.ops.release_swfw_sync(hw, mask);
0269 }
0270
0271
0272
0273
0274
0275
0276
0277 static s32 igc_init_hw_base(struct igc_hw *hw)
0278 {
0279 struct igc_mac_info *mac = &hw->mac;
0280 u16 i, rar_count = mac->rar_entry_count;
0281 s32 ret_val = 0;
0282
0283
0284 igc_init_rx_addrs(hw, rar_count);
0285
0286
0287 hw_dbg("Zeroing the MTA\n");
0288 for (i = 0; i < mac->mta_reg_count; i++)
0289 array_wr32(IGC_MTA, i, 0);
0290
0291
0292 hw_dbg("Zeroing the UTA\n");
0293 for (i = 0; i < mac->uta_reg_count; i++)
0294 array_wr32(IGC_UTA, i, 0);
0295
0296
0297 ret_val = igc_setup_link(hw);
0298
0299
0300
0301
0302
0303
0304 igc_clear_hw_cntrs_base(hw);
0305
0306 return ret_val;
0307 }
0308
0309
0310
0311
0312
0313
0314
0315
0316 void igc_power_down_phy_copper_base(struct igc_hw *hw)
0317 {
0318
0319 if (!(igc_enable_mng_pass_thru(hw) || igc_check_reset_block(hw)))
0320 igc_power_down_phy_copper(hw);
0321 }
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332 void igc_rx_fifo_flush_base(struct igc_hw *hw)
0333 {
0334 u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
0335 int i, ms_wait;
0336
0337
0338 rfctl = rd32(IGC_RFCTL);
0339 rfctl |= IGC_RFCTL_IPV6_EX_DIS;
0340 wr32(IGC_RFCTL, rfctl);
0341
0342 if (!(rd32(IGC_MANC) & IGC_MANC_RCV_TCO_EN))
0343 return;
0344
0345
0346 for (i = 0; i < 4; i++) {
0347 rxdctl[i] = rd32(IGC_RXDCTL(i));
0348 wr32(IGC_RXDCTL(i),
0349 rxdctl[i] & ~IGC_RXDCTL_QUEUE_ENABLE);
0350 }
0351
0352 for (ms_wait = 0; ms_wait < 10; ms_wait++) {
0353 usleep_range(1000, 2000);
0354 rx_enabled = 0;
0355 for (i = 0; i < 4; i++)
0356 rx_enabled |= rd32(IGC_RXDCTL(i));
0357 if (!(rx_enabled & IGC_RXDCTL_QUEUE_ENABLE))
0358 break;
0359 }
0360
0361 if (ms_wait == 10)
0362 hw_dbg("Queue disable timed out after 10ms\n");
0363
0364
0365
0366
0367
0368 wr32(IGC_RFCTL, rfctl & ~IGC_RFCTL_LEF);
0369
0370 rlpml = rd32(IGC_RLPML);
0371 wr32(IGC_RLPML, 0);
0372
0373 rctl = rd32(IGC_RCTL);
0374 temp_rctl = rctl & ~(IGC_RCTL_EN | IGC_RCTL_SBP);
0375 temp_rctl |= IGC_RCTL_LPE;
0376
0377 wr32(IGC_RCTL, temp_rctl);
0378 wr32(IGC_RCTL, temp_rctl | IGC_RCTL_EN);
0379 wrfl();
0380 usleep_range(2000, 3000);
0381
0382
0383
0384
0385 for (i = 0; i < 4; i++)
0386 wr32(IGC_RXDCTL(i), rxdctl[i]);
0387 wr32(IGC_RCTL, rctl);
0388 wrfl();
0389
0390 wr32(IGC_RLPML, rlpml);
0391 wr32(IGC_RFCTL, rfctl);
0392
0393
0394 rd32(IGC_ROC);
0395 rd32(IGC_RNBC);
0396 rd32(IGC_MPC);
0397 }
0398
0399 static struct igc_mac_operations igc_mac_ops_base = {
0400 .init_hw = igc_init_hw_base,
0401 .check_for_link = igc_check_for_copper_link,
0402 .rar_set = igc_rar_set,
0403 .read_mac_addr = igc_read_mac_addr,
0404 .get_speed_and_duplex = igc_get_speed_and_duplex_copper,
0405 };
0406
0407 static const struct igc_phy_operations igc_phy_ops_base = {
0408 .acquire = igc_acquire_phy_base,
0409 .release = igc_release_phy_base,
0410 .reset = igc_phy_hw_reset,
0411 .read_reg = igc_read_phy_reg_gpy,
0412 .write_reg = igc_write_phy_reg_gpy,
0413 };
0414
0415 const struct igc_info igc_base_info = {
0416 .get_invariants = igc_get_invariants_base,
0417 .mac_ops = &igc_mac_ops_base,
0418 .phy_ops = &igc_phy_ops_base,
0419 };