]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Jesse Brandeburg <jesse.brandeburg@intel.com> |
2 | Date: Fri, 31 Oct 2008 07:46:40 +0000 (-0700) | |
3 | Subject: ixgbe: add device support for 82598AT (copper 10GbE) adapters | |
4 | X-Git-Url: http://gitlad.jf.intel.com/git/?p=davem%2Fnet-next-2.6%2F.git;a=commitdiff_plain;h=0befdb3e0a26a8949063915274e1bec8873c526b | |
5 | Acked-by: Karsten Keil <kkeil@novell.com> | |
6 | Reference: bnc#441471 | |
7 | ||
8 | ixgbe: add device support for 82598AT (copper 10GbE) adapters | |
9 | ||
10 | Intel is currently shipping support for adapters with a phy | |
11 | that does 10GBase-T (copper), which is 10 Gigabit ethernet | |
12 | over standard Category 6 cabling. | |
13 | ||
14 | Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> | |
15 | Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> | |
16 | Signed-off-by: Jeff Garzik <jgarzik@redhat.com> | |
17 | --- | |
18 | ||
19 | Index: linux-2.6.27/drivers/net/ixgbe/ixgbe.h | |
20 | =================================================================== | |
21 | --- linux-2.6.27.orig/drivers/net/ixgbe/ixgbe.h | |
22 | +++ linux-2.6.27/drivers/net/ixgbe/ixgbe.h | |
23 | @@ -282,6 +282,7 @@ struct ixgbe_adapter { | |
24 | #define IXGBE_FLAG_RSS_CAPABLE (u32)(1 << 17) | |
25 | #define IXGBE_FLAG_VMDQ_CAPABLE (u32)(1 << 18) | |
26 | #define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 19) | |
27 | +#define IXGBE_FLAG_FAN_FAIL_CAPABLE (u32)(1 << 20) | |
28 | #define IXGBE_FLAG_NEED_LINK_UPDATE (u32)(1 << 22) | |
29 | #define IXGBE_FLAG_IN_WATCHDOG_TASK (u32)(1 << 23) | |
30 | #define IXGBE_FLAG_DCB_ENABLED (u32)(1 << 24) | |
31 | Index: linux-2.6.27/drivers/net/ixgbe/ixgbe_82598.c | |
32 | =================================================================== | |
33 | --- linux-2.6.27.orig/drivers/net/ixgbe/ixgbe_82598.c | |
34 | +++ linux-2.6.27/drivers/net/ixgbe/ixgbe_82598.c | |
35 | @@ -59,6 +59,11 @@ static s32 ixgbe_get_invariants_82598(st | |
36 | ||
37 | /* PHY Init */ | |
38 | switch (phy->type) { | |
39 | + case ixgbe_phy_tn: | |
40 | + phy->ops.check_link = &ixgbe_check_phy_link_tnx; | |
41 | + phy->ops.get_firmware_version = | |
42 | + &ixgbe_get_phy_firmware_version_tnx; | |
43 | + break; | |
44 | default: | |
45 | break; | |
46 | } | |
47 | @@ -189,6 +194,9 @@ static enum ixgbe_media_type ixgbe_get_m | |
48 | case IXGBE_DEV_ID_82598EB_XF_LR: | |
49 | media_type = ixgbe_media_type_fiber; | |
50 | break; | |
51 | + case IXGBE_DEV_ID_82598AT: | |
52 | + media_type = ixgbe_media_type_copper; | |
53 | + break; | |
54 | default: | |
55 | media_type = ixgbe_media_type_unknown; | |
56 | break; | |
57 | @@ -872,6 +880,10 @@ s32 ixgbe_get_supported_physical_layer_8 | |
58 | case IXGBE_DEV_ID_82598EB_XF_LR: | |
59 | physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR; | |
60 | break; | |
61 | + case IXGBE_DEV_ID_82598AT: | |
62 | + physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_T | | |
63 | + IXGBE_PHYSICAL_LAYER_1000BASE_T); | |
64 | + break; | |
65 | ||
66 | default: | |
67 | physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; | |
68 | Index: linux-2.6.27/drivers/net/ixgbe/ixgbe_ethtool.c | |
69 | =================================================================== | |
70 | --- linux-2.6.27.orig/drivers/net/ixgbe/ixgbe_ethtool.c | |
71 | +++ linux-2.6.27/drivers/net/ixgbe/ixgbe_ethtool.c | |
72 | @@ -160,6 +160,8 @@ static int ixgbe_set_settings(struct net | |
73 | { | |
74 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | |
75 | struct ixgbe_hw *hw = &adapter->hw; | |
76 | + u32 advertised, old; | |
77 | + s32 err; | |
78 | ||
79 | switch (hw->phy.media_type) { | |
80 | case ixgbe_media_type_fiber: | |
81 | @@ -168,6 +170,31 @@ static int ixgbe_set_settings(struct net | |
82 | return -EINVAL; | |
83 | /* in this case we currently only support 10Gb/FULL */ | |
84 | break; | |
85 | + case ixgbe_media_type_copper: | |
86 | + /* 10000/copper and 1000/copper must autoneg | |
87 | + * this function does not support any duplex forcing, but can | |
88 | + * limit the advertising of the adapter to only 10000 or 1000 */ | |
89 | + if (ecmd->autoneg == AUTONEG_DISABLE) | |
90 | + return -EINVAL; | |
91 | + | |
92 | + old = hw->phy.autoneg_advertised; | |
93 | + advertised = 0; | |
94 | + if (ecmd->advertising & ADVERTISED_10000baseT_Full) | |
95 | + advertised |= IXGBE_LINK_SPEED_10GB_FULL; | |
96 | + | |
97 | + if (ecmd->advertising & ADVERTISED_1000baseT_Full) | |
98 | + advertised |= IXGBE_LINK_SPEED_1GB_FULL; | |
99 | + | |
100 | + if (old == advertised) | |
101 | + break; | |
102 | + /* this sets the link speed and restarts auto-neg */ | |
103 | + err = hw->mac.ops.setup_link_speed(hw, advertised, true, true); | |
104 | + if (err) { | |
105 | + DPRINTK(PROBE, INFO, | |
106 | + "setup link failed with code %d\n", err); | |
107 | + hw->mac.ops.setup_link_speed(hw, old, true, true); | |
108 | + } | |
109 | + break; | |
110 | default: | |
111 | break; | |
112 | } | |
113 | Index: linux-2.6.27/drivers/net/ixgbe/ixgbe_main.c | |
114 | =================================================================== | |
115 | --- linux-2.6.27.orig/drivers/net/ixgbe/ixgbe_main.c | |
116 | +++ linux-2.6.27/drivers/net/ixgbe/ixgbe_main.c | |
117 | @@ -68,6 +68,8 @@ static struct pci_device_id ixgbe_pci_tb | |
118 | board_82598 }, | |
119 | {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_SINGLE_PORT), | |
120 | board_82598 }, | |
121 | + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AT), | |
122 | + board_82598 }, | |
123 | {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4), | |
124 | board_82598 }, | |
125 | {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_CX4_DUAL_PORT), | |
126 | @@ -910,6 +912,17 @@ static void ixgbe_set_itr_msix(struct ix | |
127 | return; | |
128 | } | |
129 | ||
130 | +static void ixgbe_check_fan_failure(struct ixgbe_adapter *adapter, u32 eicr) | |
131 | +{ | |
132 | + struct ixgbe_hw *hw = &adapter->hw; | |
133 | + | |
134 | + if ((adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) && | |
135 | + (eicr & IXGBE_EICR_GPI_SDP1)) { | |
136 | + DPRINTK(PROBE, CRIT, "Fan has stopped, replace the adapter\n"); | |
137 | + /* write to clear the interrupt */ | |
138 | + IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1); | |
139 | + } | |
140 | +} | |
141 | ||
142 | static void ixgbe_check_lsc(struct ixgbe_adapter *adapter) | |
143 | { | |
144 | @@ -934,6 +947,8 @@ static irqreturn_t ixgbe_msix_lsc(int ir | |
145 | if (eicr & IXGBE_EICR_LSC) | |
146 | ixgbe_check_lsc(adapter); | |
147 | ||
148 | + ixgbe_check_fan_failure(adapter, eicr); | |
149 | + | |
150 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) | |
151 | IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER); | |
152 | ||
153 | @@ -1322,6 +1337,8 @@ static irqreturn_t ixgbe_intr(int irq, v | |
154 | if (eicr & IXGBE_EICR_LSC) | |
155 | ixgbe_check_lsc(adapter); | |
156 | ||
157 | + ixgbe_check_fan_failure(adapter, eicr); | |
158 | + | |
159 | if (netif_rx_schedule_prep(netdev, &adapter->q_vector[0].napi)) { | |
160 | adapter->tx_ring[0].total_packets = 0; | |
161 | adapter->tx_ring[0].total_bytes = 0; | |
162 | @@ -1424,6 +1441,8 @@ static inline void ixgbe_irq_enable(stru | |
163 | { | |
164 | u32 mask; | |
165 | mask = IXGBE_EIMS_ENABLE_MASK; | |
166 | + if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) | |
167 | + mask |= IXGBE_EIMS_GPI_SDP1; | |
168 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); | |
169 | IXGBE_WRITE_FLUSH(&adapter->hw); | |
170 | } | |
171 | @@ -1983,6 +2002,13 @@ static int ixgbe_up_complete(struct ixgb | |
172 | IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE); | |
173 | } | |
174 | ||
175 | + /* Enable fan failure interrupt if media type is copper */ | |
176 | + if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) { | |
177 | + gpie = IXGBE_READ_REG(hw, IXGBE_GPIE); | |
178 | + gpie |= IXGBE_SDP1_GPIEN; | |
179 | + IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); | |
180 | + } | |
181 | + | |
182 | mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD); | |
183 | if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) { | |
184 | mhadd &= ~IXGBE_MHADD_MFS_MASK; | |
185 | @@ -2679,6 +2705,9 @@ static int __devinit ixgbe_sw_init(struc | |
186 | rss = min(IXGBE_MAX_RSS_INDICES, (int)num_online_cpus()); | |
187 | adapter->ring_feature[RING_F_RSS].indices = rss; | |
188 | adapter->flags |= IXGBE_FLAG_RSS_ENABLED; | |
189 | + if (hw->mac.ops.get_media_type && | |
190 | + (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper)) | |
191 | + adapter->flags |= IXGBE_FLAG_FAN_FAIL_CAPABLE; | |
192 | adapter->ring_feature[RING_F_DCB].indices = IXGBE_MAX_DCB_INDICES; | |
193 | ||
194 | /* Configure DCB traffic classes */ | |
195 | @@ -3851,6 +3880,10 @@ static int ixgbe_link_config(struct ixgb | |
196 | /* must always autoneg for both 1G and 10G link */ | |
197 | hw->mac.autoneg = true; | |
198 | ||
199 | + if ((hw->mac.type == ixgbe_mac_82598EB) && | |
200 | + (hw->phy.media_type == ixgbe_media_type_copper)) | |
201 | + autoneg = IXGBE_LINK_SPEED_82598_AUTONEG; | |
202 | + | |
203 | return hw->mac.ops.setup_link_speed(hw, autoneg, true, true); | |
204 | } | |
205 | ||
206 | Index: linux-2.6.27/drivers/net/ixgbe/ixgbe_phy.c | |
207 | =================================================================== | |
208 | --- linux-2.6.27.orig/drivers/net/ixgbe/ixgbe_phy.c | |
209 | +++ linux-2.6.27/drivers/net/ixgbe/ixgbe_phy.c | |
210 | @@ -121,6 +121,9 @@ static enum ixgbe_phy_type ixgbe_get_phy | |
211 | enum ixgbe_phy_type phy_type; | |
212 | ||
213 | switch (phy_id) { | |
214 | + case TN1010_PHY_ID: | |
215 | + phy_type = ixgbe_phy_tn; | |
216 | + break; | |
217 | case QT2022_PHY_ID: | |
218 | phy_type = ixgbe_phy_qt; | |
219 | break; | |
220 | @@ -426,3 +429,68 @@ s32 ixgbe_setup_phy_link_speed_generic(s | |
221 | return 0; | |
222 | } | |
223 | ||
224 | +/** | |
225 | + * ixgbe_check_phy_link_tnx - Determine link and speed status | |
226 | + * @hw: pointer to hardware structure | |
227 | + * | |
228 | + * Reads the VS1 register to determine if link is up and the current speed for | |
229 | + * the PHY. | |
230 | + **/ | |
231 | +s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed, | |
232 | + bool *link_up) | |
233 | +{ | |
234 | + s32 status = 0; | |
235 | + u32 time_out; | |
236 | + u32 max_time_out = 10; | |
237 | + u16 phy_link = 0; | |
238 | + u16 phy_speed = 0; | |
239 | + u16 phy_data = 0; | |
240 | + | |
241 | + /* Initialize speed and link to default case */ | |
242 | + *link_up = false; | |
243 | + *speed = IXGBE_LINK_SPEED_10GB_FULL; | |
244 | + | |
245 | + /* | |
246 | + * Check current speed and link status of the PHY register. | |
247 | + * This is a vendor specific register and may have to | |
248 | + * be changed for other copper PHYs. | |
249 | + */ | |
250 | + for (time_out = 0; time_out < max_time_out; time_out++) { | |
251 | + udelay(10); | |
252 | + status = hw->phy.ops.read_reg(hw, | |
253 | + IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS, | |
254 | + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, | |
255 | + &phy_data); | |
256 | + phy_link = phy_data & | |
257 | + IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS; | |
258 | + phy_speed = phy_data & | |
259 | + IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS; | |
260 | + if (phy_link == IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS) { | |
261 | + *link_up = true; | |
262 | + if (phy_speed == | |
263 | + IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS) | |
264 | + *speed = IXGBE_LINK_SPEED_1GB_FULL; | |
265 | + break; | |
266 | + } | |
267 | + } | |
268 | + | |
269 | + return status; | |
270 | +} | |
271 | + | |
272 | +/** | |
273 | + * ixgbe_get_phy_firmware_version_tnx - Gets the PHY Firmware Version | |
274 | + * @hw: pointer to hardware structure | |
275 | + * @firmware_version: pointer to the PHY Firmware Version | |
276 | + **/ | |
277 | +s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, | |
278 | + u16 *firmware_version) | |
279 | +{ | |
280 | + s32 status = 0; | |
281 | + | |
282 | + status = hw->phy.ops.read_reg(hw, TNX_FW_REV, | |
283 | + IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, | |
284 | + firmware_version); | |
285 | + | |
286 | + return status; | |
287 | +} | |
288 | + | |
289 | Index: linux-2.6.27/drivers/net/ixgbe/ixgbe_phy.h | |
290 | =================================================================== | |
291 | --- linux-2.6.27.orig/drivers/net/ixgbe/ixgbe_phy.h | |
292 | +++ linux-2.6.27/drivers/net/ixgbe/ixgbe_phy.h | |
293 | @@ -77,4 +77,11 @@ s32 ixgbe_setup_phy_link_speed_generic(s | |
294 | bool autoneg, | |
295 | bool autoneg_wait_to_complete); | |
296 | ||
297 | +/* PHY specific */ | |
298 | +s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, | |
299 | + ixgbe_link_speed *speed, | |
300 | + bool *link_up); | |
301 | +s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, | |
302 | + u16 *firmware_version); | |
303 | + | |
304 | #endif /* _IXGBE_PHY_H_ */ | |
305 | Index: linux-2.6.27/drivers/net/ixgbe/ixgbe_type.h | |
306 | =================================================================== | |
307 | --- linux-2.6.27.orig/drivers/net/ixgbe/ixgbe_type.h | |
308 | +++ linux-2.6.27/drivers/net/ixgbe/ixgbe_type.h | |
309 | @@ -36,6 +36,7 @@ | |
310 | /* Device IDs */ | |
311 | #define IXGBE_DEV_ID_82598AF_DUAL_PORT 0x10C6 | |
312 | #define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7 | |
313 | +#define IXGBE_DEV_ID_82598AT 0x10C8 | |
314 | #define IXGBE_DEV_ID_82598EB_CX4 0x10DD | |
315 | #define IXGBE_DEV_ID_82598_CX4_DUAL_PORT 0x10EC | |
316 | #define IXGBE_DEV_ID_82598EB_XF_LR 0x10F4 | |
317 | @@ -488,6 +489,8 @@ | |
318 | #define IXGBE_MAX_PHY_ADDR 32 | |
319 | ||
320 | /* PHY IDs*/ | |
321 | +#define TN1010_PHY_ID 0x00A19410 | |
322 | +#define TNX_FW_REV 0xB | |
323 | #define QT2022_PHY_ID 0x0043A400 | |
324 | ||
325 | /* PHY Types */ | |
326 | @@ -1202,6 +1205,7 @@ enum ixgbe_mac_type { | |
327 | ||
328 | enum ixgbe_phy_type { | |
329 | ixgbe_phy_unknown = 0, | |
330 | + ixgbe_phy_tn, | |
331 | ixgbe_phy_qt, | |
332 | ixgbe_phy_xaui, | |
333 | ixgbe_phy_tw_tyco, | |
334 | @@ -1396,6 +1400,8 @@ struct ixgbe_phy_operations { | |
335 | s32 (*setup_link)(struct ixgbe_hw *); | |
336 | s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool, | |
337 | bool); | |
338 | + s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *); | |
339 | + s32 (*get_firmware_version)(struct ixgbe_hw *, u16 *); | |
340 | s32 (*read_i2c_byte)(struct ixgbe_hw *, u8, u8, u8 *); | |
341 | s32 (*write_i2c_byte)(struct ixgbe_hw *, u8, u8, u8); | |
342 | s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *); |