]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Bruce Allan <bruce.w.allan@intel.com> |
2 | Acked-by: Karsten Keil <kkeil@novell.com> | |
3 | Subject: e1000e: add support for new 82574L part | |
4 | Reference: fate 303916,303898 | |
5 | ||
6 | This new part has the same feature set as previous parts with the addition | |
7 | of MSI-X support. | |
8 | ||
9 | Signed-off-by: Bruce Allan <bruce.w.allan@intel.com> | |
10 | Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> | |
11 | --- | |
12 | ||
13 | drivers/net/e1000e/82571.c | 153 ++++++++++++++-- | |
14 | drivers/net/e1000e/defines.h | 13 + | |
15 | drivers/net/e1000e/e1000.h | 28 ++ | |
16 | drivers/net/e1000e/es2lan.c | 2 | |
17 | drivers/net/e1000e/ethtool.c | 38 +++- | |
18 | drivers/net/e1000e/hw.h | 11 - | |
19 | drivers/net/e1000e/ich8lan.c | 18 + | |
20 | drivers/net/e1000e/lib.c | 7 | |
21 | drivers/net/e1000e/netdev.c | 405 ++++++++++++++++++++++++++++++++++++++----- | |
22 | drivers/net/e1000e/param.c | 27 ++ | |
23 | drivers/net/e1000e/phy.c | 109 +++++++++++ | |
24 | 11 files changed, 736 insertions(+), 75 deletions(-) | |
25 | ||
26 | --- a/drivers/net/e1000e/82571.c | |
27 | +++ b/drivers/net/e1000e/82571.c | |
28 | @@ -38,6 +38,7 @@ | |
29 | * 82573V Gigabit Ethernet Controller (Copper) | |
30 | * 82573E Gigabit Ethernet Controller (Copper) | |
31 | * 82573L Gigabit Ethernet Controller | |
32 | + * 82574L Gigabit Network Connection | |
33 | */ | |
34 | ||
35 | #include <linux/netdevice.h> | |
36 | @@ -54,6 +55,8 @@ | |
37 | ||
38 | #define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 | |
39 | ||
40 | +#define E1000_NVM_INIT_CTRL2_MNGM 0x6000 /* Manageability Operation Mode mask */ | |
41 | + | |
42 | static s32 e1000_get_phy_id_82571(struct e1000_hw *hw); | |
43 | static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw); | |
44 | static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw); | |
45 | @@ -63,6 +66,8 @@ static s32 e1000_fix_nvm_checksum_82571( | |
46 | static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw); | |
47 | static s32 e1000_setup_link_82571(struct e1000_hw *hw); | |
48 | static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw); | |
49 | +static bool e1000_check_mng_mode_82574(struct e1000_hw *hw); | |
50 | +static s32 e1000_led_on_82574(struct e1000_hw *hw); | |
51 | ||
52 | /** | |
53 | * e1000_init_phy_params_82571 - Init PHY func ptrs. | |
54 | @@ -92,6 +97,9 @@ static s32 e1000_init_phy_params_82571(s | |
55 | case e1000_82573: | |
56 | phy->type = e1000_phy_m88; | |
57 | break; | |
58 | + case e1000_82574: | |
59 | + phy->type = e1000_phy_bm; | |
60 | + break; | |
61 | default: | |
62 | return -E1000_ERR_PHY; | |
63 | break; | |
64 | @@ -111,6 +119,10 @@ static s32 e1000_init_phy_params_82571(s | |
65 | if (phy->id != M88E1111_I_PHY_ID) | |
66 | return -E1000_ERR_PHY; | |
67 | break; | |
68 | + case e1000_82574: | |
69 | + if (phy->id != BME1000_E_PHY_ID_R2) | |
70 | + return -E1000_ERR_PHY; | |
71 | + break; | |
72 | default: | |
73 | return -E1000_ERR_PHY; | |
74 | break; | |
75 | @@ -150,6 +162,7 @@ static s32 e1000_init_nvm_params_82571(s | |
76 | ||
77 | switch (hw->mac.type) { | |
78 | case e1000_82573: | |
79 | + case e1000_82574: | |
80 | if (((eecd >> 15) & 0x3) == 0x3) { | |
81 | nvm->type = e1000_nvm_flash_hw; | |
82 | nvm->word_size = 2048; | |
83 | @@ -245,6 +258,17 @@ static s32 e1000_init_mac_params_82571(s | |
84 | break; | |
85 | } | |
86 | ||
87 | + switch (hw->mac.type) { | |
88 | + case e1000_82574: | |
89 | + func->check_mng_mode = e1000_check_mng_mode_82574; | |
90 | + func->led_on = e1000_led_on_82574; | |
91 | + break; | |
92 | + default: | |
93 | + func->check_mng_mode = e1000e_check_mng_mode_generic; | |
94 | + func->led_on = e1000e_led_on_generic; | |
95 | + break; | |
96 | + } | |
97 | + | |
98 | return 0; | |
99 | } | |
100 | ||
101 | @@ -330,6 +354,8 @@ static s32 e1000_get_variants_82571(stru | |
102 | static s32 e1000_get_phy_id_82571(struct e1000_hw *hw) | |
103 | { | |
104 | struct e1000_phy_info *phy = &hw->phy; | |
105 | + s32 ret_val; | |
106 | + u16 phy_id = 0; | |
107 | ||
108 | switch (hw->mac.type) { | |
109 | case e1000_82571: | |
110 | @@ -345,6 +371,20 @@ static s32 e1000_get_phy_id_82571(struct | |
111 | case e1000_82573: | |
112 | return e1000e_get_phy_id(hw); | |
113 | break; | |
114 | + case e1000_82574: | |
115 | + ret_val = e1e_rphy(hw, PHY_ID1, &phy_id); | |
116 | + if (ret_val) | |
117 | + return ret_val; | |
118 | + | |
119 | + phy->id = (u32)(phy_id << 16); | |
120 | + udelay(20); | |
121 | + ret_val = e1e_rphy(hw, PHY_ID2, &phy_id); | |
122 | + if (ret_val) | |
123 | + return ret_val; | |
124 | + | |
125 | + phy->id |= (u32)(phy_id); | |
126 | + phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK); | |
127 | + break; | |
128 | default: | |
129 | return -E1000_ERR_PHY; | |
130 | break; | |
131 | @@ -421,7 +461,7 @@ static s32 e1000_acquire_nvm_82571(struc | |
132 | if (ret_val) | |
133 | return ret_val; | |
134 | ||
135 | - if (hw->mac.type != e1000_82573) | |
136 | + if (hw->mac.type != e1000_82573 && hw->mac.type != e1000_82574) | |
137 | ret_val = e1000e_acquire_nvm(hw); | |
138 | ||
139 | if (ret_val) | |
140 | @@ -461,6 +501,7 @@ static s32 e1000_write_nvm_82571(struct | |
141 | ||
142 | switch (hw->mac.type) { | |
143 | case e1000_82573: | |
144 | + case e1000_82574: | |
145 | ret_val = e1000_write_nvm_eewr_82571(hw, offset, words, data); | |
146 | break; | |
147 | case e1000_82571: | |
148 | @@ -735,7 +776,7 @@ static s32 e1000_reset_hw_82571(struct e | |
149 | * Must acquire the MDIO ownership before MAC reset. | |
150 | * Ownership defaults to firmware after a reset. | |
151 | */ | |
152 | - if (hw->mac.type == e1000_82573) { | |
153 | + if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) { | |
154 | extcnf_ctrl = er32(EXTCNF_CTRL); | |
155 | extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; | |
156 | ||
157 | @@ -776,7 +817,7 @@ static s32 e1000_reset_hw_82571(struct e | |
158 | * Need to wait for Phy configuration completion before accessing | |
159 | * NVM and Phy. | |
160 | */ | |
161 | - if (hw->mac.type == e1000_82573) | |
162 | + if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) | |
163 | msleep(25); | |
164 | ||
165 | /* Clear any pending interrupt events. */ | |
166 | @@ -843,7 +884,7 @@ static s32 e1000_init_hw_82571(struct e1 | |
167 | ew32(TXDCTL(0), reg_data); | |
168 | ||
169 | /* ...for both queues. */ | |
170 | - if (mac->type != e1000_82573) { | |
171 | + if (mac->type != e1000_82573 && mac->type != e1000_82574) { | |
172 | reg_data = er32(TXDCTL(1)); | |
173 | reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | | |
174 | E1000_TXDCTL_FULL_TX_DESC_WB | | |
175 | @@ -918,19 +959,28 @@ static void e1000_initialize_hw_bits_825 | |
176 | } | |
177 | ||
178 | /* Device Control */ | |
179 | - if (hw->mac.type == e1000_82573) { | |
180 | + if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) { | |
181 | reg = er32(CTRL); | |
182 | reg &= ~(1 << 29); | |
183 | ew32(CTRL, reg); | |
184 | } | |
185 | ||
186 | /* Extended Device Control */ | |
187 | - if (hw->mac.type == e1000_82573) { | |
188 | + if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) { | |
189 | reg = er32(CTRL_EXT); | |
190 | reg &= ~(1 << 23); | |
191 | reg |= (1 << 22); | |
192 | ew32(CTRL_EXT, reg); | |
193 | } | |
194 | + | |
195 | + /* PCI-Ex Control Register */ | |
196 | + if (hw->mac.type == e1000_82574) { | |
197 | + reg = er32(GCR); | |
198 | + reg |= (1 << 22); | |
199 | + ew32(GCR, reg); | |
200 | + } | |
201 | + | |
202 | + return; | |
203 | } | |
204 | ||
205 | /** | |
206 | @@ -947,7 +997,7 @@ void e1000e_clear_vfta(struct e1000_hw * | |
207 | u32 vfta_offset = 0; | |
208 | u32 vfta_bit_in_reg = 0; | |
209 | ||
210 | - if (hw->mac.type == e1000_82573) { | |
211 | + if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) { | |
212 | if (hw->mng_cookie.vlan_id != 0) { | |
213 | /* | |
214 | * The VFTA is a 4096b bit-field, each identifying | |
215 | @@ -976,6 +1026,48 @@ void e1000e_clear_vfta(struct e1000_hw * | |
216 | } | |
217 | ||
218 | /** | |
219 | + * e1000_check_mng_mode_82574 - Check manageability is enabled | |
220 | + * @hw: pointer to the HW structure | |
221 | + * | |
222 | + * Reads the NVM Initialization Control Word 2 and returns true | |
223 | + * (>0) if any manageability is enabled, else false (0). | |
224 | + **/ | |
225 | +static bool e1000_check_mng_mode_82574(struct e1000_hw *hw) | |
226 | +{ | |
227 | + u16 data; | |
228 | + | |
229 | + e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data); | |
230 | + return (data & E1000_NVM_INIT_CTRL2_MNGM) != 0; | |
231 | +} | |
232 | + | |
233 | +/** | |
234 | + * e1000_led_on_82574 - Turn LED on | |
235 | + * @hw: pointer to the HW structure | |
236 | + * | |
237 | + * Turn LED on. | |
238 | + **/ | |
239 | +static s32 e1000_led_on_82574(struct e1000_hw *hw) | |
240 | +{ | |
241 | + u32 ctrl; | |
242 | + u32 i; | |
243 | + | |
244 | + ctrl = hw->mac.ledctl_mode2; | |
245 | + if (!(E1000_STATUS_LU & er32(STATUS))) { | |
246 | + /* | |
247 | + * If no link, then turn LED on by setting the invert bit | |
248 | + * for each LED that's "on" (0x0E) in ledctl_mode2. | |
249 | + */ | |
250 | + for (i = 0; i < 4; i++) | |
251 | + if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) == | |
252 | + E1000_LEDCTL_MODE_LED_ON) | |
253 | + ctrl |= (E1000_LEDCTL_LED0_IVRT << (i * 8)); | |
254 | + } | |
255 | + ew32(LEDCTL, ctrl); | |
256 | + | |
257 | + return 0; | |
258 | +} | |
259 | + | |
260 | +/** | |
261 | * e1000_update_mc_addr_list_82571 - Update Multicast addresses | |
262 | * @hw: pointer to the HW structure | |
263 | * @mc_addr_list: array of multicast addresses to program | |
264 | @@ -1018,7 +1110,8 @@ static s32 e1000_setup_link_82571(struct | |
265 | * the default flow control setting, so we explicitly | |
266 | * set it to full. | |
267 | */ | |
268 | - if (hw->mac.type == e1000_82573) | |
269 | + if ((hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) && | |
270 | + hw->fc.type == e1000_fc_default) | |
271 | hw->fc.type = e1000_fc_full; | |
272 | ||
273 | return e1000e_setup_link(hw); | |
274 | @@ -1045,6 +1138,7 @@ static s32 e1000_setup_copper_link_82571 | |
275 | ||
276 | switch (hw->phy.type) { | |
277 | case e1000_phy_m88: | |
278 | + case e1000_phy_bm: | |
279 | ret_val = e1000e_copper_link_setup_m88(hw); | |
280 | break; | |
281 | case e1000_phy_igp_2: | |
282 | @@ -1114,11 +1208,10 @@ static s32 e1000_valid_led_default_82571 | |
283 | return ret_val; | |
284 | } | |
285 | ||
286 | - if (hw->mac.type == e1000_82573 && | |
287 | + if ((hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) && | |
288 | *data == ID_LED_RESERVED_F746) | |
289 | *data = ID_LED_DEFAULT_82573; | |
290 | - else if (*data == ID_LED_RESERVED_0000 || | |
291 | - *data == ID_LED_RESERVED_FFFF) | |
292 | + else if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) | |
293 | *data = ID_LED_DEFAULT; | |
294 | ||
295 | return 0; | |
296 | @@ -1265,13 +1358,13 @@ static void e1000_clear_hw_cntrs_82571(s | |
297 | } | |
298 | ||
299 | static struct e1000_mac_operations e82571_mac_ops = { | |
300 | - .mng_mode_enab = E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT, | |
301 | + /* .check_mng_mode: mac type dependent */ | |
302 | /* .check_for_link: media type dependent */ | |
303 | .cleanup_led = e1000e_cleanup_led_generic, | |
304 | .clear_hw_cntrs = e1000_clear_hw_cntrs_82571, | |
305 | .get_bus_info = e1000e_get_bus_info_pcie, | |
306 | /* .get_link_up_info: media type dependent */ | |
307 | - .led_on = e1000e_led_on_generic, | |
308 | + /* .led_on: mac type dependent */ | |
309 | .led_off = e1000e_led_off_generic, | |
310 | .update_mc_addr_list = e1000_update_mc_addr_list_82571, | |
311 | .reset_hw = e1000_reset_hw_82571, | |
312 | @@ -1312,6 +1405,22 @@ static struct e1000_phy_operations e82_p | |
313 | .write_phy_reg = e1000e_write_phy_reg_m88, | |
314 | }; | |
315 | ||
316 | +static struct e1000_phy_operations e82_phy_ops_bm = { | |
317 | + .acquire_phy = e1000_get_hw_semaphore_82571, | |
318 | + .check_reset_block = e1000e_check_reset_block_generic, | |
319 | + .commit_phy = e1000e_phy_sw_reset, | |
320 | + .force_speed_duplex = e1000e_phy_force_speed_duplex_m88, | |
321 | + .get_cfg_done = e1000e_get_cfg_done, | |
322 | + .get_cable_length = e1000e_get_cable_length_m88, | |
323 | + .get_phy_info = e1000e_get_phy_info_m88, | |
324 | + .read_phy_reg = e1000e_read_phy_reg_bm2, | |
325 | + .release_phy = e1000_put_hw_semaphore_82571, | |
326 | + .reset_phy = e1000e_phy_hw_reset_generic, | |
327 | + .set_d0_lplu_state = e1000_set_d0_lplu_state_82571, | |
328 | + .set_d3_lplu_state = e1000e_set_d3_lplu_state, | |
329 | + .write_phy_reg = e1000e_write_phy_reg_bm2, | |
330 | +}; | |
331 | + | |
332 | static struct e1000_nvm_operations e82571_nvm_ops = { | |
333 | .acquire_nvm = e1000_acquire_nvm_82571, | |
334 | .read_nvm = e1000e_read_nvm_eerd, | |
335 | @@ -1375,3 +1484,21 @@ struct e1000_info e1000_82573_info = { | |
336 | .nvm_ops = &e82571_nvm_ops, | |
337 | }; | |
338 | ||
339 | +struct e1000_info e1000_82574_info = { | |
340 | + .mac = e1000_82574, | |
341 | + .flags = FLAG_HAS_HW_VLAN_FILTER | |
342 | + | FLAG_HAS_MSIX | |
343 | + | FLAG_HAS_JUMBO_FRAMES | |
344 | + | FLAG_HAS_WOL | |
345 | + | FLAG_APME_IN_CTRL3 | |
346 | + | FLAG_RX_CSUM_ENABLED | |
347 | + | FLAG_HAS_SMART_POWER_DOWN | |
348 | + | FLAG_HAS_AMT | |
349 | + | FLAG_HAS_CTRLEXT_ON_LOAD, | |
350 | + .pba = 20, | |
351 | + .get_variants = e1000_get_variants_82571, | |
352 | + .mac_ops = &e82571_mac_ops, | |
353 | + .phy_ops = &e82_phy_ops_bm, | |
354 | + .nvm_ops = &e82571_nvm_ops, | |
355 | +}; | |
356 | + | |
357 | --- a/drivers/net/e1000e/defines.h | |
358 | +++ b/drivers/net/e1000e/defines.h | |
359 | @@ -71,9 +71,11 @@ | |
360 | #define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */ | |
361 | #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000 | |
362 | #define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000 | |
363 | +#define E1000_CTRL_EXT_EIAME 0x01000000 | |
364 | #define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */ | |
365 | #define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */ | |
366 | #define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */ | |
367 | +#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */ | |
368 | ||
369 | /* Receive Descriptor bit definitions */ | |
370 | #define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */ | |
371 | @@ -299,6 +301,7 @@ | |
372 | #define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */ | |
373 | ||
374 | /* Header split receive */ | |
375 | +#define E1000_RFCTL_ACK_DIS 0x00001000 | |
376 | #define E1000_RFCTL_EXTEN 0x00008000 | |
377 | #define E1000_RFCTL_IPV6_EX_DIS 0x00010000 | |
378 | #define E1000_RFCTL_NEW_IPV6_EXT_DIS 0x00020000 | |
379 | @@ -363,6 +366,11 @@ | |
380 | #define E1000_ICR_RXDMT0 0x00000010 /* Rx desc min. threshold (0) */ | |
381 | #define E1000_ICR_RXT0 0x00000080 /* Rx timer intr (ring 0) */ | |
382 | #define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver should claim the interrupt */ | |
383 | +#define E1000_ICR_RXQ0 0x00100000 /* Rx Queue 0 Interrupt */ | |
384 | +#define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */ | |
385 | +#define E1000_ICR_TXQ0 0x00400000 /* Tx Queue 0 Interrupt */ | |
386 | +#define E1000_ICR_TXQ1 0x00800000 /* Tx Queue 1 Interrupt */ | |
387 | +#define E1000_ICR_OTHER 0x01000000 /* Other Interrupts */ | |
388 | ||
389 | /* | |
390 | * This defines the bits that are set in the Interrupt Mask | |
391 | @@ -386,6 +394,11 @@ | |
392 | #define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */ | |
393 | #define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */ | |
394 | #define E1000_IMS_RXT0 E1000_ICR_RXT0 /* Rx timer intr */ | |
395 | +#define E1000_IMS_RXQ0 E1000_ICR_RXQ0 /* Rx Queue 0 Interrupt */ | |
396 | +#define E1000_IMS_RXQ1 E1000_ICR_RXQ1 /* Rx Queue 1 Interrupt */ | |
397 | +#define E1000_IMS_TXQ0 E1000_ICR_TXQ0 /* Tx Queue 0 Interrupt */ | |
398 | +#define E1000_IMS_TXQ1 E1000_ICR_TXQ1 /* Tx Queue 1 Interrupt */ | |
399 | +#define E1000_IMS_OTHER E1000_ICR_OTHER /* Other Interrupts */ | |
400 | ||
401 | /* Interrupt Cause Set */ | |
402 | #define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */ | |
403 | --- a/drivers/net/e1000e/e1000.h | |
404 | +++ b/drivers/net/e1000e/e1000.h | |
405 | @@ -62,6 +62,11 @@ struct e1000_info; | |
406 | e_printk(KERN_NOTICE, adapter, format, ## arg) | |
407 | ||
408 | ||
409 | +/* Interrupt modes, as used by the IntMode paramter */ | |
410 | +#define E1000E_INT_MODE_LEGACY 0 | |
411 | +#define E1000E_INT_MODE_MSI 1 | |
412 | +#define E1000E_INT_MODE_MSIX 2 | |
413 | + | |
414 | /* Tx/Rx descriptor defines */ | |
415 | #define E1000_DEFAULT_TXD 256 | |
416 | #define E1000_MAX_TXD 4096 | |
417 | @@ -95,6 +100,7 @@ enum e1000_boards { | |
418 | board_82571, | |
419 | board_82572, | |
420 | board_82573, | |
421 | + board_82574, | |
422 | board_80003es2lan, | |
423 | board_ich8lan, | |
424 | board_ich9lan, | |
425 | @@ -146,6 +152,12 @@ struct e1000_ring { | |
426 | /* array of buffer information structs */ | |
427 | struct e1000_buffer *buffer_info; | |
428 | ||
429 | + char name[IFNAMSIZ + 5]; | |
430 | + u32 ims_val; | |
431 | + u32 itr_val; | |
432 | + u16 itr_register; | |
433 | + int set_itr; | |
434 | + | |
435 | struct sk_buff *rx_skb_top; | |
436 | ||
437 | struct e1000_queue_stats stats; | |
438 | @@ -273,6 +285,9 @@ struct e1000_adapter { | |
439 | u32 test_icr; | |
440 | ||
441 | u32 msg_enable; | |
442 | + struct msix_entry *msix_entries; | |
443 | + int int_mode; | |
444 | + u32 eiac_mask; | |
445 | ||
446 | u32 eeprom_wol; | |
447 | u32 wol; | |
448 | @@ -310,6 +325,7 @@ struct e1000_info { | |
449 | #define FLAG_HAS_JUMBO_FRAMES (1 << 7) | |
450 | #define FLAG_READ_ONLY_NVM (1 << 8) | |
451 | #define FLAG_IS_ICH (1 << 9) | |
452 | +#define FLAG_HAS_MSIX (1 << 10) | |
453 | #define FLAG_HAS_SMART_POWER_DOWN (1 << 11) | |
454 | #define FLAG_IS_QUAD_PORT_A (1 << 12) | |
455 | #define FLAG_IS_QUAD_PORT (1 << 13) | |
456 | @@ -371,6 +387,8 @@ extern int e1000e_setup_tx_resources(str | |
457 | extern void e1000e_free_rx_resources(struct e1000_adapter *adapter); | |
458 | extern void e1000e_free_tx_resources(struct e1000_adapter *adapter); | |
459 | extern void e1000e_update_stats(struct e1000_adapter *adapter); | |
460 | +extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter); | |
461 | +extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter); | |
462 | ||
463 | extern unsigned int copybreak; | |
464 | ||
465 | @@ -379,6 +397,7 @@ extern char *e1000e_get_hw_dev_name(stru | |
466 | extern struct e1000_info e1000_82571_info; | |
467 | extern struct e1000_info e1000_82572_info; | |
468 | extern struct e1000_info e1000_82573_info; | |
469 | +extern struct e1000_info e1000_82574_info; | |
470 | extern struct e1000_info e1000_ich8_info; | |
471 | extern struct e1000_info e1000_ich9_info; | |
472 | extern struct e1000_info e1000_es2_info; | |
473 | @@ -458,6 +477,8 @@ extern enum e1000_phy_type e1000e_get_ph | |
474 | extern s32 e1000e_determine_phy_address(struct e1000_hw *hw); | |
475 | extern s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data); | |
476 | extern s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data); | |
477 | +extern s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data); | |
478 | +extern s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data); | |
479 | extern void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl); | |
480 | extern s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data); | |
481 | extern s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data); | |
482 | @@ -528,7 +549,12 @@ static inline s32 e1000_get_phy_info(str | |
483 | return hw->phy.ops.get_phy_info(hw); | |
484 | } | |
485 | ||
486 | -extern bool e1000e_check_mng_mode(struct e1000_hw *hw); | |
487 | +static inline s32 e1000e_check_mng_mode(struct e1000_hw *hw) | |
488 | +{ | |
489 | + return hw->mac.ops.check_mng_mode(hw); | |
490 | +} | |
491 | + | |
492 | +extern bool e1000e_check_mng_mode_generic(struct e1000_hw *hw); | |
493 | extern bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw); | |
494 | extern s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length); | |
495 | ||
496 | --- a/drivers/net/e1000e/es2lan.c | |
497 | +++ b/drivers/net/e1000e/es2lan.c | |
498 | @@ -1247,7 +1247,7 @@ static void e1000_clear_hw_cntrs_80003es | |
499 | } | |
500 | ||
501 | static struct e1000_mac_operations es2_mac_ops = { | |
502 | - .mng_mode_enab = E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT, | |
503 | + .check_mng_mode = e1000e_check_mng_mode_generic, | |
504 | /* check_for_link dependent on media type */ | |
505 | .cleanup_led = e1000e_cleanup_led_generic, | |
506 | .clear_hw_cntrs = e1000_clear_hw_cntrs_80003es2lan, | |
507 | --- a/drivers/net/e1000e/ethtool.c | |
508 | +++ b/drivers/net/e1000e/ethtool.c | |
509 | @@ -575,6 +575,7 @@ static int e1000_set_eeprom(struct net_d | |
510 | * and flush shadow RAM for 82573 controllers | |
511 | */ | |
512 | if ((ret_val == 0) && ((first_word <= NVM_CHECKSUM_REG) || | |
513 | + (hw->mac.type == e1000_82574) || | |
514 | (hw->mac.type == e1000_82573))) | |
515 | e1000e_update_nvm_checksum(hw); | |
516 | ||
517 | @@ -786,6 +787,7 @@ static int e1000_reg_test(struct e1000_a | |
518 | toggle = 0x7FFFF3FF; | |
519 | break; | |
520 | case e1000_82573: | |
521 | + case e1000_82574: | |
522 | case e1000_ich8lan: | |
523 | case e1000_ich9lan: | |
524 | toggle = 0x7FFFF033; | |
525 | @@ -891,10 +893,18 @@ static int e1000_intr_test(struct e1000_ | |
526 | u32 shared_int = 1; | |
527 | u32 irq = adapter->pdev->irq; | |
528 | int i; | |
529 | + int ret_val = 0; | |
530 | + int int_mode = E1000E_INT_MODE_LEGACY; | |
531 | ||
532 | *data = 0; | |
533 | ||
534 | - /* NOTE: we don't test MSI interrupts here, yet */ | |
535 | + /* NOTE: we don't test MSI/MSI-X interrupts here, yet */ | |
536 | + if (adapter->int_mode == E1000E_INT_MODE_MSIX) { | |
537 | + int_mode = adapter->int_mode; | |
538 | + e1000e_reset_interrupt_capability(adapter); | |
539 | + adapter->int_mode = E1000E_INT_MODE_LEGACY; | |
540 | + e1000e_set_interrupt_capability(adapter); | |
541 | + } | |
542 | /* Hook up test interrupt handler just for this test */ | |
543 | if (!request_irq(irq, &e1000_test_intr, IRQF_PROBE_SHARED, netdev->name, | |
544 | netdev)) { | |
545 | @@ -902,7 +912,8 @@ static int e1000_intr_test(struct e1000_ | |
546 | } else if (request_irq(irq, &e1000_test_intr, IRQF_SHARED, | |
547 | netdev->name, netdev)) { | |
548 | *data = 1; | |
549 | - return -1; | |
550 | + ret_val = -1; | |
551 | + goto out; | |
552 | } | |
553 | e_info("testing %s interrupt\n", (shared_int ? "shared" : "unshared")); | |
554 | ||
555 | @@ -981,7 +992,14 @@ static int e1000_intr_test(struct e1000_ | |
556 | /* Unhook test interrupt handler */ | |
557 | free_irq(irq, netdev); | |
558 | ||
559 | - return *data; | |
560 | +out: | |
561 | + if (int_mode == E1000E_INT_MODE_MSIX) { | |
562 | + e1000e_reset_interrupt_capability(adapter); | |
563 | + adapter->int_mode = int_mode; | |
564 | + e1000e_set_interrupt_capability(adapter); | |
565 | + } | |
566 | + | |
567 | + return ret_val; | |
568 | } | |
569 | ||
570 | static void e1000_free_desc_rings(struct e1000_adapter *adapter) | |
571 | @@ -1766,11 +1784,13 @@ static void e1000_led_blink_callback(uns | |
572 | static int e1000_phys_id(struct net_device *netdev, u32 data) | |
573 | { | |
574 | struct e1000_adapter *adapter = netdev_priv(netdev); | |
575 | + struct e1000_hw *hw = &adapter->hw; | |
576 | ||
577 | if (!data) | |
578 | data = INT_MAX; | |
579 | ||
580 | - if (adapter->hw.phy.type == e1000_phy_ife) { | |
581 | + if ((hw->phy.type == e1000_phy_ife) || | |
582 | + (hw->mac.type == e1000_82574)) { | |
583 | if (!adapter->blink_timer.function) { | |
584 | init_timer(&adapter->blink_timer); | |
585 | adapter->blink_timer.function = | |
586 | @@ -1780,16 +1800,16 @@ static int e1000_phys_id(struct net_devi | |
587 | mod_timer(&adapter->blink_timer, jiffies); | |
588 | msleep_interruptible(data * 1000); | |
589 | del_timer_sync(&adapter->blink_timer); | |
590 | - e1e_wphy(&adapter->hw, | |
591 | - IFE_PHY_SPECIAL_CONTROL_LED, 0); | |
592 | + if (hw->phy.type == e1000_phy_ife) | |
593 | + e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED, 0); | |
594 | } else { | |
595 | - e1000e_blink_led(&adapter->hw); | |
596 | + e1000e_blink_led(hw); | |
597 | msleep_interruptible(data * 1000); | |
598 | } | |
599 | ||
600 | - adapter->hw.mac.ops.led_off(&adapter->hw); | |
601 | + hw->mac.ops.led_off(hw); | |
602 | clear_bit(E1000_LED_ON, &adapter->led_status); | |
603 | - adapter->hw.mac.ops.cleanup_led(&adapter->hw); | |
604 | + hw->mac.ops.cleanup_led(hw); | |
605 | ||
606 | return 0; | |
607 | } | |
608 | --- a/drivers/net/e1000e/hw.h | |
609 | +++ b/drivers/net/e1000e/hw.h | |
610 | @@ -65,7 +65,11 @@ enum e1e_registers { | |
611 | E1000_ICS = 0x000C8, /* Interrupt Cause Set - WO */ | |
612 | E1000_IMS = 0x000D0, /* Interrupt Mask Set - RW */ | |
613 | E1000_IMC = 0x000D8, /* Interrupt Mask Clear - WO */ | |
614 | + E1000_EIAC_82574 = 0x000DC, /* Ext. Interrupt Auto Clear - RW */ | |
615 | E1000_IAM = 0x000E0, /* Interrupt Acknowledge Auto Mask */ | |
616 | + E1000_IVAR = 0x000E4, /* Interrupt Vector Allocation - RW */ | |
617 | + E1000_EITR_82574_BASE = 0x000E8, /* Interrupt Throttling - RW */ | |
618 | +#define E1000_EITR_82574(_n) (E1000_EITR_82574_BASE + (_n << 2)) | |
619 | E1000_RCTL = 0x00100, /* Rx Control - RW */ | |
620 | E1000_FCTTV = 0x00170, /* Flow Control Transmit Timer Value - RW */ | |
621 | E1000_TXCW = 0x00178, /* Tx Configuration Word - RW */ | |
622 | @@ -332,6 +336,7 @@ enum e1e_registers { | |
623 | #define E1000_DEV_ID_82573E 0x108B | |
624 | #define E1000_DEV_ID_82573E_IAMT 0x108C | |
625 | #define E1000_DEV_ID_82573L 0x109A | |
626 | +#define E1000_DEV_ID_82574L 0x10D3 | |
627 | ||
628 | #define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096 | |
629 | #define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098 | |
630 | @@ -357,12 +362,15 @@ enum e1e_registers { | |
631 | #define E1000_DEV_ID_ICH10_R_BM_LF 0x10CD | |
632 | #define E1000_DEV_ID_ICH10_R_BM_V 0x10CE | |
633 | ||
634 | +#define E1000_REVISION_4 4 | |
635 | + | |
636 | #define E1000_FUNC_1 1 | |
637 | ||
638 | enum e1000_mac_type { | |
639 | e1000_82571, | |
640 | e1000_82572, | |
641 | e1000_82573, | |
642 | + e1000_82574, | |
643 | e1000_80003es2lan, | |
644 | e1000_ich8lan, | |
645 | e1000_ich9lan, | |
646 | @@ -696,8 +704,7 @@ struct e1000_host_mng_command_info { | |
647 | ||
648 | /* Function pointers and static data for the MAC. */ | |
649 | struct e1000_mac_operations { | |
650 | - u32 mng_mode_enab; | |
651 | - | |
652 | + bool (*check_mng_mode)(struct e1000_hw *); | |
653 | s32 (*check_for_link)(struct e1000_hw *); | |
654 | s32 (*cleanup_led)(struct e1000_hw *); | |
655 | void (*clear_hw_cntrs)(struct e1000_hw *); | |
656 | --- a/drivers/net/e1000e/ich8lan.c | |
657 | +++ b/drivers/net/e1000e/ich8lan.c | |
658 | @@ -448,6 +448,22 @@ static void e1000_release_swflag_ich8lan | |
659 | } | |
660 | ||
661 | /** | |
662 | + * e1000_check_mng_mode_ich8lan - Checks management mode | |
663 | + * @hw: pointer to the HW structure | |
664 | + * | |
665 | + * This checks if the adapter has manageability enabled. | |
666 | + * This is a function pointer entry point only called by read/write | |
667 | + * routines for the PHY and NVM parts. | |
668 | + **/ | |
669 | +static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw) | |
670 | +{ | |
671 | + u32 fwsm = er32(FWSM); | |
672 | + | |
673 | + return (fwsm & E1000_FWSM_MODE_MASK) == | |
674 | + (E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT); | |
675 | +} | |
676 | + | |
677 | +/** | |
678 | * e1000_check_reset_block_ich8lan - Check if PHY reset is blocked | |
679 | * @hw: pointer to the HW structure | |
680 | * | |
681 | @@ -2365,7 +2381,7 @@ static void e1000_clear_hw_cntrs_ich8lan | |
682 | } | |
683 | ||
684 | static struct e1000_mac_operations ich8_mac_ops = { | |
685 | - .mng_mode_enab = E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT, | |
686 | + .check_mng_mode = e1000_check_mng_mode_ich8lan, | |
687 | .check_for_link = e1000e_check_for_copper_link, | |
688 | .cleanup_led = e1000_cleanup_led_ich8lan, | |
689 | .clear_hw_cntrs = e1000_clear_hw_cntrs_ich8lan, | |
690 | --- a/drivers/net/e1000e/lib.c | |
691 | +++ b/drivers/net/e1000e/lib.c | |
692 | @@ -2222,17 +2222,18 @@ static s32 e1000_mng_enable_host_if(stru | |
693 | } | |
694 | ||
695 | /** | |
696 | - * e1000e_check_mng_mode - check management mode | |
697 | + * e1000e_check_mng_mode_generic - check management mode | |
698 | * @hw: pointer to the HW structure | |
699 | * | |
700 | * Reads the firmware semaphore register and returns true (>0) if | |
701 | * manageability is enabled, else false (0). | |
702 | **/ | |
703 | -bool e1000e_check_mng_mode(struct e1000_hw *hw) | |
704 | +bool e1000e_check_mng_mode_generic(struct e1000_hw *hw) | |
705 | { | |
706 | u32 fwsm = er32(FWSM); | |
707 | ||
708 | - return (fwsm & E1000_FWSM_MODE_MASK) == hw->mac.ops.mng_mode_enab; | |
709 | + return (fwsm & E1000_FWSM_MODE_MASK) == | |
710 | + (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT); | |
711 | } | |
712 | ||
713 | /** | |
714 | --- a/drivers/net/e1000e/netdev.c | |
715 | +++ b/drivers/net/e1000e/netdev.c | |
716 | @@ -55,6 +55,7 @@ static const struct e1000_info *e1000_in | |
717 | [board_82571] = &e1000_82571_info, | |
718 | [board_82572] = &e1000_82572_info, | |
719 | [board_82573] = &e1000_82573_info, | |
720 | + [board_82574] = &e1000_82574_info, | |
721 | [board_80003es2lan] = &e1000_es2_info, | |
722 | [board_ich8lan] = &e1000_ich8_info, | |
723 | [board_ich9lan] = &e1000_ich9_info, | |
724 | @@ -1201,8 +1202,8 @@ static irqreturn_t e1000_intr(int irq, v | |
725 | struct net_device *netdev = data; | |
726 | struct e1000_adapter *adapter = netdev_priv(netdev); | |
727 | struct e1000_hw *hw = &adapter->hw; | |
728 | - | |
729 | u32 rctl, icr = er32(ICR); | |
730 | + | |
731 | if (!icr) | |
732 | return IRQ_NONE; /* Not our interrupt */ | |
733 | ||
734 | @@ -1258,6 +1259,263 @@ static irqreturn_t e1000_intr(int irq, v | |
735 | return IRQ_HANDLED; | |
736 | } | |
737 | ||
738 | +static irqreturn_t e1000_msix_other(int irq, void *data) | |
739 | +{ | |
740 | + struct net_device *netdev = data; | |
741 | + struct e1000_adapter *adapter = netdev_priv(netdev); | |
742 | + struct e1000_hw *hw = &adapter->hw; | |
743 | + u32 icr = er32(ICR); | |
744 | + | |
745 | + if (!(icr & E1000_ICR_INT_ASSERTED)) { | |
746 | + ew32(IMS, E1000_IMS_OTHER); | |
747 | + return IRQ_NONE; | |
748 | + } | |
749 | + | |
750 | + if (icr & adapter->eiac_mask) | |
751 | + ew32(ICS, (icr & adapter->eiac_mask)); | |
752 | + | |
753 | + if (icr & E1000_ICR_OTHER) { | |
754 | + if (!(icr & E1000_ICR_LSC)) | |
755 | + goto no_link_interrupt; | |
756 | + hw->mac.get_link_status = 1; | |
757 | + /* guard against interrupt when we're going down */ | |
758 | + if (!test_bit(__E1000_DOWN, &adapter->state)) | |
759 | + mod_timer(&adapter->watchdog_timer, jiffies + 1); | |
760 | + } | |
761 | + | |
762 | +no_link_interrupt: | |
763 | + ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER); | |
764 | + | |
765 | + return IRQ_HANDLED; | |
766 | +} | |
767 | + | |
768 | + | |
769 | +static irqreturn_t e1000_intr_msix_tx(int irq, void *data) | |
770 | +{ | |
771 | + struct net_device *netdev = data; | |
772 | + struct e1000_adapter *adapter = netdev_priv(netdev); | |
773 | + struct e1000_hw *hw = &adapter->hw; | |
774 | + struct e1000_ring *tx_ring = adapter->tx_ring; | |
775 | + | |
776 | + | |
777 | + adapter->total_tx_bytes = 0; | |
778 | + adapter->total_tx_packets = 0; | |
779 | + | |
780 | + if (!e1000_clean_tx_irq(adapter)) | |
781 | + /* Ring was not completely cleaned, so fire another interrupt */ | |
782 | + ew32(ICS, tx_ring->ims_val); | |
783 | + | |
784 | + return IRQ_HANDLED; | |
785 | +} | |
786 | + | |
787 | +static irqreturn_t e1000_intr_msix_rx(int irq, void *data) | |
788 | +{ | |
789 | + struct net_device *netdev = data; | |
790 | + struct e1000_adapter *adapter = netdev_priv(netdev); | |
791 | + | |
792 | + /* Write the ITR value calculated at the end of the | |
793 | + * previous interrupt. | |
794 | + */ | |
795 | + if (adapter->rx_ring->set_itr) { | |
796 | + writel(1000000000 / (adapter->rx_ring->itr_val * 256), | |
797 | + adapter->hw.hw_addr + adapter->rx_ring->itr_register); | |
798 | + adapter->rx_ring->set_itr = 0; | |
799 | + } | |
800 | + | |
801 | + if (netif_rx_schedule_prep(netdev, &adapter->napi)) { | |
802 | + adapter->total_rx_bytes = 0; | |
803 | + adapter->total_rx_packets = 0; | |
804 | + __netif_rx_schedule(netdev, &adapter->napi); | |
805 | + } | |
806 | + return IRQ_HANDLED; | |
807 | +} | |
808 | + | |
809 | +/** | |
810 | + * e1000_configure_msix - Configure MSI-X hardware | |
811 | + * | |
812 | + * e1000_configure_msix sets up the hardware to properly | |
813 | + * generate MSI-X interrupts. | |
814 | + **/ | |
815 | +static void e1000_configure_msix(struct e1000_adapter *adapter) | |
816 | +{ | |
817 | + struct e1000_hw *hw = &adapter->hw; | |
818 | + struct e1000_ring *rx_ring = adapter->rx_ring; | |
819 | + struct e1000_ring *tx_ring = adapter->tx_ring; | |
820 | + int vector = 0; | |
821 | + u32 ctrl_ext, ivar = 0; | |
822 | + | |
823 | + adapter->eiac_mask = 0; | |
824 | + | |
825 | + /* Workaround issue with spurious interrupts on 82574 in MSI-X mode */ | |
826 | + if (hw->mac.type == e1000_82574) { | |
827 | + u32 rfctl = er32(RFCTL); | |
828 | + rfctl |= E1000_RFCTL_ACK_DIS; | |
829 | + ew32(RFCTL, rfctl); | |
830 | + } | |
831 | + | |
832 | +#define E1000_IVAR_INT_ALLOC_VALID 0x8 | |
833 | + /* Configure Rx vector */ | |
834 | + rx_ring->ims_val = E1000_IMS_RXQ0; | |
835 | + adapter->eiac_mask |= rx_ring->ims_val; | |
836 | + if (rx_ring->itr_val) | |
837 | + writel(1000000000 / (rx_ring->itr_val * 256), | |
838 | + hw->hw_addr + rx_ring->itr_register); | |
839 | + else | |
840 | + writel(1, hw->hw_addr + rx_ring->itr_register); | |
841 | + ivar = E1000_IVAR_INT_ALLOC_VALID | vector; | |
842 | + | |
843 | + /* Configure Tx vector */ | |
844 | + tx_ring->ims_val = E1000_IMS_TXQ0; | |
845 | + vector++; | |
846 | + if (tx_ring->itr_val) | |
847 | + writel(1000000000 / (tx_ring->itr_val * 256), | |
848 | + hw->hw_addr + tx_ring->itr_register); | |
849 | + else | |
850 | + writel(1, hw->hw_addr + tx_ring->itr_register); | |
851 | + adapter->eiac_mask |= tx_ring->ims_val; | |
852 | + ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 8); | |
853 | + | |
854 | + /* set vector for Other Causes, e.g. link changes */ | |
855 | + vector++; | |
856 | + ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 16); | |
857 | + if (rx_ring->itr_val) | |
858 | + writel(1000000000 / (rx_ring->itr_val * 256), | |
859 | + hw->hw_addr + E1000_EITR_82574(vector)); | |
860 | + else | |
861 | + writel(1, hw->hw_addr + E1000_EITR_82574(vector)); | |
862 | + | |
863 | + /* Cause Tx interrupts on every write back */ | |
864 | + ivar |= (1 << 31); | |
865 | + | |
866 | + ew32(IVAR, ivar); | |
867 | + | |
868 | + /* enable MSI-X PBA support */ | |
869 | + ctrl_ext = er32(CTRL_EXT); | |
870 | + ctrl_ext |= E1000_CTRL_EXT_PBA_CLR; | |
871 | + | |
872 | + /* Auto-Mask Other interrupts upon ICR read */ | |
873 | +#define E1000_EIAC_MASK_82574 0x01F00000 | |
874 | + ew32(IAM, ~E1000_EIAC_MASK_82574 | E1000_IMS_OTHER); | |
875 | + ctrl_ext |= E1000_CTRL_EXT_EIAME; | |
876 | + ew32(CTRL_EXT, ctrl_ext); | |
877 | + e1e_flush(); | |
878 | +} | |
879 | + | |
880 | +void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter) | |
881 | +{ | |
882 | + if (adapter->msix_entries) { | |
883 | + pci_disable_msix(adapter->pdev); | |
884 | + kfree(adapter->msix_entries); | |
885 | + adapter->msix_entries = NULL; | |
886 | + } else if (adapter->flags & FLAG_MSI_ENABLED) { | |
887 | + pci_disable_msi(adapter->pdev); | |
888 | + adapter->flags &= ~FLAG_MSI_ENABLED; | |
889 | + } | |
890 | + | |
891 | + return; | |
892 | +} | |
893 | + | |
894 | +/** | |
895 | + * e1000e_set_interrupt_capability - set MSI or MSI-X if supported | |
896 | + * | |
897 | + * Attempt to configure interrupts using the best available | |
898 | + * capabilities of the hardware and kernel. | |
899 | + **/ | |
900 | +void e1000e_set_interrupt_capability(struct e1000_adapter *adapter) | |
901 | +{ | |
902 | + int err; | |
903 | + int numvecs, i; | |
904 | + | |
905 | + | |
906 | + switch (adapter->int_mode) { | |
907 | + case E1000E_INT_MODE_MSIX: | |
908 | + if (adapter->flags & FLAG_HAS_MSIX) { | |
909 | + numvecs = 3; /* RxQ0, TxQ0 and other */ | |
910 | + adapter->msix_entries = kcalloc(numvecs, | |
911 | + sizeof(struct msix_entry), | |
912 | + GFP_KERNEL); | |
913 | + if (adapter->msix_entries) { | |
914 | + for (i = 0; i < numvecs; i++) | |
915 | + adapter->msix_entries[i].entry = i; | |
916 | + | |
917 | + err = pci_enable_msix(adapter->pdev, | |
918 | + adapter->msix_entries, | |
919 | + numvecs); | |
920 | + if (err == 0) | |
921 | + return; | |
922 | + } | |
923 | + /* MSI-X failed, so fall through and try MSI */ | |
924 | + e_err("Failed to initialize MSI-X interrupts. " | |
925 | + "Falling back to MSI interrupts.\n"); | |
926 | + e1000e_reset_interrupt_capability(adapter); | |
927 | + } | |
928 | + adapter->int_mode = E1000E_INT_MODE_MSI; | |
929 | + /* Fall through */ | |
930 | + case E1000E_INT_MODE_MSI: | |
931 | + if (!pci_enable_msi(adapter->pdev)) { | |
932 | + adapter->flags |= FLAG_MSI_ENABLED; | |
933 | + } else { | |
934 | + adapter->int_mode = E1000E_INT_MODE_LEGACY; | |
935 | + e_err("Failed to initialize MSI interrupts. Falling " | |
936 | + "back to legacy interrupts.\n"); | |
937 | + } | |
938 | + /* Fall through */ | |
939 | + case E1000E_INT_MODE_LEGACY: | |
940 | + /* Don't do anything; this is the system default */ | |
941 | + break; | |
942 | + } | |
943 | + | |
944 | + return; | |
945 | +} | |
946 | + | |
947 | +/** | |
948 | + * e1000_request_msix - Initialize MSI-X interrupts | |
949 | + * | |
950 | + * e1000_request_msix allocates MSI-X vectors and requests interrupts from the | |
951 | + * kernel. | |
952 | + **/ | |
953 | +static int e1000_request_msix(struct e1000_adapter *adapter) | |
954 | +{ | |
955 | + struct net_device *netdev = adapter->netdev; | |
956 | + int err = 0, vector = 0; | |
957 | + | |
958 | + if (strlen(netdev->name) < (IFNAMSIZ - 5)) | |
959 | + sprintf(adapter->rx_ring->name, "%s-rx0", netdev->name); | |
960 | + else | |
961 | + memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ); | |
962 | + err = request_irq(adapter->msix_entries[vector].vector, | |
963 | + &e1000_intr_msix_rx, 0, adapter->rx_ring->name, | |
964 | + netdev); | |
965 | + if (err) | |
966 | + goto out; | |
967 | + adapter->rx_ring->itr_register = E1000_EITR_82574(vector); | |
968 | + adapter->rx_ring->itr_val = adapter->itr; | |
969 | + vector++; | |
970 | + | |
971 | + if (strlen(netdev->name) < (IFNAMSIZ - 5)) | |
972 | + sprintf(adapter->tx_ring->name, "%s-tx0", netdev->name); | |
973 | + else | |
974 | + memcpy(adapter->tx_ring->name, netdev->name, IFNAMSIZ); | |
975 | + err = request_irq(adapter->msix_entries[vector].vector, | |
976 | + &e1000_intr_msix_tx, 0, adapter->tx_ring->name, | |
977 | + netdev); | |
978 | + if (err) | |
979 | + goto out; | |
980 | + adapter->tx_ring->itr_register = E1000_EITR_82574(vector); | |
981 | + adapter->tx_ring->itr_val = adapter->itr; | |
982 | + vector++; | |
983 | + | |
984 | + err = request_irq(adapter->msix_entries[vector].vector, | |
985 | + &e1000_msix_other, 0, netdev->name, netdev); | |
986 | + if (err) | |
987 | + goto out; | |
988 | + | |
989 | + e1000_configure_msix(adapter); | |
990 | + return 0; | |
991 | +out: | |
992 | + return err; | |
993 | +} | |
994 | + | |
995 | /** | |
996 | * e1000_request_irq - initialize interrupts | |
997 | * | |
998 | @@ -1267,29 +1525,33 @@ static irqreturn_t e1000_intr(int irq, v | |
999 | static int e1000_request_irq(struct e1000_adapter *adapter) | |
1000 | { | |
1001 | struct net_device *netdev = adapter->netdev; | |
1002 | - int irq_flags = IRQF_SHARED; | |
1003 | int err; | |
1004 | ||
1005 | - if (!(adapter->flags & FLAG_MSI_TEST_FAILED)) { | |
1006 | - err = pci_enable_msi(adapter->pdev); | |
1007 | - if (!err) { | |
1008 | - adapter->flags |= FLAG_MSI_ENABLED; | |
1009 | - irq_flags = 0; | |
1010 | - } | |
1011 | + if (adapter->msix_entries) { | |
1012 | + err = e1000_request_msix(adapter); | |
1013 | + if (!err) | |
1014 | + return err; | |
1015 | + /* fall back to MSI */ | |
1016 | + e1000e_reset_interrupt_capability(adapter); | |
1017 | + adapter->int_mode = E1000E_INT_MODE_MSI; | |
1018 | + e1000e_set_interrupt_capability(adapter); | |
1019 | } | |
1020 | + if (adapter->flags & FLAG_MSI_ENABLED) { | |
1021 | + err = request_irq(adapter->pdev->irq, &e1000_intr_msi, 0, | |
1022 | + netdev->name, netdev); | |
1023 | + if (!err) | |
1024 | + return err; | |
1025 | ||
1026 | - err = request_irq(adapter->pdev->irq, | |
1027 | - ((adapter->flags & FLAG_MSI_ENABLED) ? | |
1028 | - &e1000_intr_msi : &e1000_intr), | |
1029 | - irq_flags, netdev->name, netdev); | |
1030 | - if (err) { | |
1031 | - if (adapter->flags & FLAG_MSI_ENABLED) { | |
1032 | - pci_disable_msi(adapter->pdev); | |
1033 | - adapter->flags &= ~FLAG_MSI_ENABLED; | |
1034 | - } | |
1035 | - e_err("Unable to allocate interrupt, Error: %d\n", err); | |
1036 | + /* fall back to legacy interrupt */ | |
1037 | + e1000e_reset_interrupt_capability(adapter); | |
1038 | + adapter->int_mode = E1000E_INT_MODE_LEGACY; | |
1039 | } | |
1040 | ||
1041 | + err = request_irq(adapter->pdev->irq, &e1000_intr, IRQF_SHARED, | |
1042 | + netdev->name, netdev); | |
1043 | + if (err) | |
1044 | + e_err("Unable to allocate interrupt, Error: %d\n", err); | |
1045 | + | |
1046 | return err; | |
1047 | } | |
1048 | ||
1049 | @@ -1297,11 +1559,21 @@ static void e1000_free_irq(struct e1000_ | |
1050 | { | |
1051 | struct net_device *netdev = adapter->netdev; | |
1052 | ||
1053 | - free_irq(adapter->pdev->irq, netdev); | |
1054 | - if (adapter->flags & FLAG_MSI_ENABLED) { | |
1055 | - pci_disable_msi(adapter->pdev); | |
1056 | - adapter->flags &= ~FLAG_MSI_ENABLED; | |
1057 | + if (adapter->msix_entries) { | |
1058 | + int vector = 0; | |
1059 | + | |
1060 | + free_irq(adapter->msix_entries[vector].vector, netdev); | |
1061 | + vector++; | |
1062 | + | |
1063 | + free_irq(adapter->msix_entries[vector].vector, netdev); | |
1064 | + vector++; | |
1065 | + | |
1066 | + /* Other Causes interrupt vector */ | |
1067 | + free_irq(adapter->msix_entries[vector].vector, netdev); | |
1068 | + return; | |
1069 | } | |
1070 | + | |
1071 | + free_irq(adapter->pdev->irq, netdev); | |
1072 | } | |
1073 | ||
1074 | /** | |
1075 | @@ -1312,6 +1584,8 @@ static void e1000_irq_disable(struct e10 | |
1076 | struct e1000_hw *hw = &adapter->hw; | |
1077 | ||
1078 | ew32(IMC, ~0); | |
1079 | + if (adapter->msix_entries) | |
1080 | + ew32(EIAC_82574, 0); | |
1081 | e1e_flush(); | |
1082 | synchronize_irq(adapter->pdev->irq); | |
1083 | } | |
1084 | @@ -1323,7 +1597,12 @@ static void e1000_irq_enable(struct e100 | |
1085 | { | |
1086 | struct e1000_hw *hw = &adapter->hw; | |
1087 | ||
1088 | - ew32(IMS, IMS_ENABLE_MASK); | |
1089 | + if (adapter->msix_entries) { | |
1090 | + ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574); | |
1091 | + ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC); | |
1092 | + } else { | |
1093 | + ew32(IMS, IMS_ENABLE_MASK); | |
1094 | + } | |
1095 | e1e_flush(); | |
1096 | } | |
1097 | ||
1098 | @@ -1573,9 +1852,8 @@ void e1000e_free_rx_resources(struct e10 | |
1099 | * traffic pattern. Constants in this function were computed | |
1100 | * based on theoretical maximum wire speed and thresholds were set based | |
1101 | * on testing data as well as attempting to minimize response time | |
1102 | - * while increasing bulk throughput. | |
1103 | - * this functionality is controlled by the InterruptThrottleRate module | |
1104 | - * parameter (see e1000_param.c) | |
1105 | + * while increasing bulk throughput. This functionality is controlled | |
1106 | + * by the InterruptThrottleRate module parameter. | |
1107 | **/ | |
1108 | static unsigned int e1000_update_itr(struct e1000_adapter *adapter, | |
1109 | u16 itr_setting, int packets, | |
1110 | @@ -1683,11 +1961,37 @@ set_itr_now: | |
1111 | min(adapter->itr + (new_itr >> 2), new_itr) : | |
1112 | new_itr; | |
1113 | adapter->itr = new_itr; | |
1114 | - ew32(ITR, 1000000000 / (new_itr * 256)); | |
1115 | + adapter->rx_ring->itr_val = new_itr; | |
1116 | + if (adapter->msix_entries) | |
1117 | + adapter->rx_ring->set_itr = 1; | |
1118 | + else | |
1119 | + ew32(ITR, 1000000000 / (new_itr * 256)); | |
1120 | } | |
1121 | } | |
1122 | ||
1123 | /** | |
1124 | + * e1000_alloc_queues - Allocate memory for all rings | |
1125 | + * @adapter: board private structure to initialize | |
1126 | + **/ | |
1127 | +static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter) | |
1128 | +{ | |
1129 | + adapter->tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); | |
1130 | + if (!adapter->tx_ring) | |
1131 | + goto err; | |
1132 | + | |
1133 | + adapter->rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); | |
1134 | + if (!adapter->rx_ring) | |
1135 | + goto err; | |
1136 | + | |
1137 | + return 0; | |
1138 | +err: | |
1139 | + e_err("Unable to allocate memory for queues\n"); | |
1140 | + kfree(adapter->rx_ring); | |
1141 | + kfree(adapter->tx_ring); | |
1142 | + return -ENOMEM; | |
1143 | +} | |
1144 | + | |
1145 | +/** | |
1146 | * e1000_clean - NAPI Rx polling callback | |
1147 | * @napi: struct associated with this polling callback | |
1148 | * @budget: amount of packets driver is allowed to process this poll | |
1149 | @@ -1695,12 +1999,17 @@ set_itr_now: | |
1150 | static int e1000_clean(struct napi_struct *napi, int budget) | |
1151 | { | |
1152 | struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi); | |
1153 | + struct e1000_hw *hw = &adapter->hw; | |
1154 | struct net_device *poll_dev = adapter->netdev; | |
1155 | int tx_cleaned = 0, work_done = 0; | |
1156 | ||
1157 | /* Must NOT use netdev_priv macro here. */ | |
1158 | adapter = poll_dev->priv; | |
1159 | ||
1160 | + if (adapter->msix_entries && | |
1161 | + !(adapter->rx_ring->ims_val & adapter->tx_ring->ims_val)) | |
1162 | + goto clean_rx; | |
1163 | + | |
1164 | /* | |
1165 | * e1000_clean is called per-cpu. This lock protects | |
1166 | * tx_ring from being cleaned by multiple cpus | |
1167 | @@ -1712,6 +2021,7 @@ static int e1000_clean(struct napi_struc | |
1168 | spin_unlock(&adapter->tx_queue_lock); | |
1169 | } | |
1170 | ||
1171 | +clean_rx: | |
1172 | adapter->clean_rx(adapter, &work_done, budget); | |
1173 | ||
1174 | if (tx_cleaned) | |
1175 | @@ -1722,7 +2032,10 @@ static int e1000_clean(struct napi_struc | |
1176 | if (adapter->itr_setting & 3) | |
1177 | e1000_set_itr(adapter); | |
1178 | netif_rx_complete(poll_dev, napi); | |
1179 | - e1000_irq_enable(adapter); | |
1180 | + if (adapter->msix_entries) | |
1181 | + ew32(IMS, adapter->rx_ring->ims_val); | |
1182 | + else | |
1183 | + e1000_irq_enable(adapter); | |
1184 | } | |
1185 | ||
1186 | return work_done; | |
1187 | @@ -2522,6 +2835,8 @@ int e1000e_up(struct e1000_adapter *adap | |
1188 | clear_bit(__E1000_DOWN, &adapter->state); | |
1189 | ||
1190 | napi_enable(&adapter->napi); | |
1191 | + if (adapter->msix_entries) | |
1192 | + e1000_configure_msix(adapter); | |
1193 | e1000_irq_enable(adapter); | |
1194 | ||
1195 | /* fire a link change interrupt to start the watchdog */ | |
1196 | @@ -2605,13 +2920,10 @@ static int __devinit e1000_sw_init(struc | |
1197 | adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; | |
1198 | adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN; | |
1199 | ||
1200 | - adapter->tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); | |
1201 | - if (!adapter->tx_ring) | |
1202 | - goto err; | |
1203 | + e1000e_set_interrupt_capability(adapter); | |
1204 | ||
1205 | - adapter->rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); | |
1206 | - if (!adapter->rx_ring) | |
1207 | - goto err; | |
1208 | + if (e1000_alloc_queues(adapter)) | |
1209 | + return -ENOMEM; | |
1210 | ||
1211 | spin_lock_init(&adapter->tx_queue_lock); | |
1212 | ||
1213 | @@ -2620,12 +2932,6 @@ static int __devinit e1000_sw_init(struc | |
1214 | ||
1215 | set_bit(__E1000_DOWN, &adapter->state); | |
1216 | return 0; | |
1217 | - | |
1218 | -err: | |
1219 | - e_err("Unable to allocate memory for queues\n"); | |
1220 | - kfree(adapter->rx_ring); | |
1221 | - kfree(adapter->tx_ring); | |
1222 | - return -ENOMEM; | |
1223 | } | |
1224 | ||
1225 | /** | |
1226 | @@ -2667,6 +2973,7 @@ static int e1000_test_msi_interrupt(stru | |
1227 | ||
1228 | /* free the real vector and request a test handler */ | |
1229 | e1000_free_irq(adapter); | |
1230 | + e1000e_reset_interrupt_capability(adapter); | |
1231 | ||
1232 | /* Assume that the test fails, if it succeeds then the test | |
1233 | * MSI irq handler will unset this flag */ | |
1234 | @@ -2697,6 +3004,7 @@ static int e1000_test_msi_interrupt(stru | |
1235 | rmb(); | |
1236 | ||
1237 | if (adapter->flags & FLAG_MSI_TEST_FAILED) { | |
1238 | + adapter->int_mode = E1000E_INT_MODE_LEGACY; | |
1239 | err = -EIO; | |
1240 | e_info("MSI interrupt test failed!\n"); | |
1241 | } | |
1242 | @@ -2710,7 +3018,7 @@ static int e1000_test_msi_interrupt(stru | |
1243 | /* okay so the test worked, restore settings */ | |
1244 | e_dbg("%s: MSI interrupt test succeeded!\n", netdev->name); | |
1245 | msi_test_failed: | |
1246 | - /* restore the original vector, even if it failed */ | |
1247 | + e1000e_set_interrupt_capability(adapter); | |
1248 | e1000_request_irq(adapter); | |
1249 | return err; | |
1250 | } | |
1251 | @@ -2820,7 +3128,7 @@ static int e1000_open(struct net_device | |
1252 | * ignore e1000e MSI messages, which means we need to test our MSI | |
1253 | * interrupt now | |
1254 | */ | |
1255 | - { | |
1256 | + if (adapter->int_mode != E1000E_INT_MODE_LEGACY) { | |
1257 | err = e1000_test_msi(adapter); | |
1258 | if (err) { | |
1259 | e_err("Interrupt allocation failed\n"); | |
1260 | @@ -3015,7 +3323,8 @@ void e1000e_update_stats(struct e1000_ad | |
1261 | ||
1262 | adapter->stats.algnerrc += er32(ALGNERRC); | |
1263 | adapter->stats.rxerrc += er32(RXERRC); | |
1264 | - adapter->stats.tncrs += er32(TNCRS); | |
1265 | + if (hw->mac.type != e1000_82574) | |
1266 | + adapter->stats.tncrs += er32(TNCRS); | |
1267 | adapter->stats.cexterr += er32(CEXTERR); | |
1268 | adapter->stats.tsctc += er32(TSCTC); | |
1269 | adapter->stats.tsctfc += er32(TSCTFC); | |
1270 | @@ -3325,7 +3634,10 @@ link_up: | |
1271 | } | |
1272 | ||
1273 | /* Cause software interrupt to ensure Rx ring is cleaned */ | |
1274 | - ew32(ICS, E1000_ICS_RXDMT0); | |
1275 | + if (adapter->msix_entries) | |
1276 | + ew32(ICS, adapter->rx_ring->ims_val); | |
1277 | + else | |
1278 | + ew32(ICS, E1000_ICS_RXDMT0); | |
1279 | ||
1280 | /* Force detection of hung controller every watchdog period */ | |
1281 | adapter->detect_tx_hung = 1; | |
1282 | @@ -4042,6 +4354,7 @@ static int e1000_suspend(struct pci_dev | |
1283 | e1000e_down(adapter); | |
1284 | e1000_free_irq(adapter); | |
1285 | } | |
1286 | + e1000e_reset_interrupt_capability(adapter); | |
1287 | ||
1288 | retval = pci_save_state(pdev); | |
1289 | if (retval) | |
1290 | @@ -4168,6 +4481,7 @@ static int e1000_resume(struct pci_dev * | |
1291 | pci_enable_wake(pdev, PCI_D3hot, 0); | |
1292 | pci_enable_wake(pdev, PCI_D3cold, 0); | |
1293 | ||
1294 | + e1000e_set_interrupt_capability(adapter); | |
1295 | if (netif_running(netdev)) { | |
1296 | err = e1000_request_irq(adapter); | |
1297 | if (err) | |
1298 | @@ -4722,6 +5036,7 @@ static void __devexit e1000_remove(struc | |
1299 | if (!e1000_check_reset_block(&adapter->hw)) | |
1300 | e1000_phy_hw_reset(&adapter->hw); | |
1301 | ||
1302 | + e1000e_reset_interrupt_capability(adapter); | |
1303 | kfree(adapter->tx_ring); | |
1304 | kfree(adapter->rx_ring); | |
1305 | ||
1306 | @@ -4763,6 +5078,8 @@ static struct pci_device_id e1000_pci_tb | |
1307 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E_IAMT), board_82573 }, | |
1308 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_82573L), board_82573 }, | |
1309 | ||
1310 | + { PCI_VDEVICE(INTEL, E1000_DEV_ID_82574L), board_82574 }, | |
1311 | + | |
1312 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_DPT), | |
1313 | board_80003es2lan }, | |
1314 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_SPT), | |
1315 | --- a/drivers/net/e1000e/param.c | |
1316 | +++ b/drivers/net/e1000e/param.c | |
1317 | @@ -114,6 +114,15 @@ E1000_PARAM(InterruptThrottleRate, "Inte | |
1318 | #define DEFAULT_ITR 3 | |
1319 | #define MAX_ITR 100000 | |
1320 | #define MIN_ITR 100 | |
1321 | +/* IntMode (Interrupt Mode) | |
1322 | + * | |
1323 | + * Valid Range: 0 - 2 | |
1324 | + * | |
1325 | + * Default Value: 2 (MSI-X) | |
1326 | + */ | |
1327 | +E1000_PARAM(IntMode, "Interrupt Mode"); | |
1328 | +#define MAX_INTMODE 2 | |
1329 | +#define MIN_INTMODE 0 | |
1330 | ||
1331 | /* | |
1332 | * Enable Smart Power Down of the PHY | |
1333 | @@ -371,6 +380,24 @@ void __devinit e1000e_check_options(stru | |
1334 | adapter->itr = 20000; | |
1335 | } | |
1336 | } | |
1337 | + { /* Interrupt Mode */ | |
1338 | + struct e1000_option opt = { | |
1339 | + .type = range_option, | |
1340 | + .name = "Interrupt Mode", | |
1341 | + .err = "defaulting to 2 (MSI-X)", | |
1342 | + .def = E1000E_INT_MODE_MSIX, | |
1343 | + .arg = { .r = { .min = MIN_INTMODE, | |
1344 | + .max = MAX_INTMODE } } | |
1345 | + }; | |
1346 | + | |
1347 | + if (num_IntMode > bd) { | |
1348 | + unsigned int int_mode = IntMode[bd]; | |
1349 | + e1000_validate_option(&int_mode, &opt, adapter); | |
1350 | + adapter->int_mode = int_mode; | |
1351 | + } else { | |
1352 | + adapter->int_mode = opt.def; | |
1353 | + } | |
1354 | + } | |
1355 | { /* Smart Power Down */ | |
1356 | const struct e1000_option opt = { | |
1357 | .type = enable_option, | |
1358 | --- a/drivers/net/e1000e/phy.c | |
1359 | +++ b/drivers/net/e1000e/phy.c | |
1360 | @@ -476,7 +476,9 @@ s32 e1000e_copper_link_setup_m88(struct | |
1361 | if (ret_val) | |
1362 | return ret_val; | |
1363 | ||
1364 | - if ((phy->type == e1000_phy_m88) && (phy->revision < 4)) { | |
1365 | + if ((phy->type == e1000_phy_m88) && | |
1366 | + (phy->revision < E1000_REVISION_4) && | |
1367 | + (phy->id != BME1000_E_PHY_ID_R2)) { | |
1368 | /* | |
1369 | * Force TX_CLK in the Extended PHY Specific Control Register | |
1370 | * to 25MHz clock. | |
1371 | @@ -504,6 +506,18 @@ s32 e1000e_copper_link_setup_m88(struct | |
1372 | return ret_val; | |
1373 | } | |
1374 | ||
1375 | + if ((phy->type == e1000_phy_bm) && (phy->id == BME1000_E_PHY_ID_R2)) { | |
1376 | + /* Set PHY page 0, register 29 to 0x0003 */ | |
1377 | + ret_val = e1e_wphy(hw, 29, 0x0003); | |
1378 | + if (ret_val) | |
1379 | + return ret_val; | |
1380 | + | |
1381 | + /* Set PHY page 0, register 30 to 0x0000 */ | |
1382 | + ret_val = e1e_wphy(hw, 30, 0x0000); | |
1383 | + if (ret_val) | |
1384 | + return ret_val; | |
1385 | + } | |
1386 | + | |
1387 | /* Commit the changes. */ | |
1388 | ret_val = e1000e_commit_phy(hw); | |
1389 | if (ret_val) | |
1390 | @@ -1969,6 +1983,99 @@ out: | |
1391 | } | |
1392 | ||
1393 | /** | |
1394 | + * e1000e_read_phy_reg_bm2 - Read BM PHY register | |
1395 | + * @hw: pointer to the HW structure | |
1396 | + * @offset: register offset to be read | |
1397 | + * @data: pointer to the read data | |
1398 | + * | |
1399 | + * Acquires semaphore, if necessary, then reads the PHY register at offset | |
1400 | + * and storing the retrieved information in data. Release any acquired | |
1401 | + * semaphores before exiting. | |
1402 | + **/ | |
1403 | +s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data) | |
1404 | +{ | |
1405 | + s32 ret_val; | |
1406 | + u16 page = (u16)(offset >> IGP_PAGE_SHIFT); | |
1407 | + | |
1408 | + /* Page 800 works differently than the rest so it has its own func */ | |
1409 | + if (page == BM_WUC_PAGE) { | |
1410 | + ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, | |
1411 | + true); | |
1412 | + return ret_val; | |
1413 | + } | |
1414 | + | |
1415 | + ret_val = hw->phy.ops.acquire_phy(hw); | |
1416 | + if (ret_val) | |
1417 | + return ret_val; | |
1418 | + | |
1419 | + hw->phy.addr = 1; | |
1420 | + | |
1421 | + if (offset > MAX_PHY_MULTI_PAGE_REG) { | |
1422 | + | |
1423 | + /* Page is shifted left, PHY expects (page x 32) */ | |
1424 | + ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT, | |
1425 | + page); | |
1426 | + | |
1427 | + if (ret_val) { | |
1428 | + hw->phy.ops.release_phy(hw); | |
1429 | + return ret_val; | |
1430 | + } | |
1431 | + } | |
1432 | + | |
1433 | + ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, | |
1434 | + data); | |
1435 | + hw->phy.ops.release_phy(hw); | |
1436 | + | |
1437 | + return ret_val; | |
1438 | +} | |
1439 | + | |
1440 | +/** | |
1441 | + * e1000e_write_phy_reg_bm2 - Write BM PHY register | |
1442 | + * @hw: pointer to the HW structure | |
1443 | + * @offset: register offset to write to | |
1444 | + * @data: data to write at register offset | |
1445 | + * | |
1446 | + * Acquires semaphore, if necessary, then writes the data to PHY register | |
1447 | + * at the offset. Release any acquired semaphores before exiting. | |
1448 | + **/ | |
1449 | +s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data) | |
1450 | +{ | |
1451 | + s32 ret_val; | |
1452 | + u16 page = (u16)(offset >> IGP_PAGE_SHIFT); | |
1453 | + | |
1454 | + /* Page 800 works differently than the rest so it has its own func */ | |
1455 | + if (page == BM_WUC_PAGE) { | |
1456 | + ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, | |
1457 | + false); | |
1458 | + return ret_val; | |
1459 | + } | |
1460 | + | |
1461 | + ret_val = hw->phy.ops.acquire_phy(hw); | |
1462 | + if (ret_val) | |
1463 | + return ret_val; | |
1464 | + | |
1465 | + hw->phy.addr = 1; | |
1466 | + | |
1467 | + if (offset > MAX_PHY_MULTI_PAGE_REG) { | |
1468 | + /* Page is shifted left, PHY expects (page x 32) */ | |
1469 | + ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT, | |
1470 | + page); | |
1471 | + | |
1472 | + if (ret_val) { | |
1473 | + hw->phy.ops.release_phy(hw); | |
1474 | + return ret_val; | |
1475 | + } | |
1476 | + } | |
1477 | + | |
1478 | + ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, | |
1479 | + data); | |
1480 | + | |
1481 | + hw->phy.ops.release_phy(hw); | |
1482 | + | |
1483 | + return ret_val; | |
1484 | +} | |
1485 | + | |
1486 | +/** | |
1487 | * e1000_access_phy_wakeup_reg_bm - Read BM PHY wakeup register | |
1488 | * @hw: pointer to the HW structure | |
1489 | * @offset: register offset to be read or written |