diff options
author | Saul Wold <Saul.Wold@intel.com> | 2010-09-24 15:36:24 -0700 |
---|---|---|
committer | Saul Wold <Saul.Wold@intel.com> | 2010-09-24 16:43:21 -0700 |
commit | 239a368d5715d8f5b7733f9400339c2350c49369 (patch) | |
tree | 2953f12b45e590d9e14b6f72f8e4ee7188e41508 /meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-gbe.patch | |
parent | c5b9525263dac6844d152e40acf8cee4d27b60bc (diff) | |
download | poky-239a368d5715d8f5b7733f9400339c2350c49369.tar.gz |
netbook: Correct netbook build by moving netbook configuration from moblin to meta
Signed-off-by: Saul Wold <Saul.Wold@intel.com>
Diffstat (limited to 'meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-gbe.patch')
-rw-r--r-- | meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-gbe.patch | 8889 |
1 files changed, 8889 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-gbe.patch b/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-gbe.patch new file mode 100644 index 0000000000..e1d51e78f7 --- /dev/null +++ b/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-gbe.patch | |||
@@ -0,0 +1,8889 @@ | |||
1 | |||
2 | |||
3 | From: Masayuki Ohtake <masa-korg@dsn.okisemi.com> | ||
4 | Subject: OKI Semiconductor PCH GbE driver | ||
5 | |||
6 | This driver implements GbE controls for PCH. | ||
7 | |||
8 | Signed-off-by: Masayuki Ohtake <masa-korg@dsn.okisemi.com> | ||
9 | Acked-by: Wang Qi <qi.wang@intel.com> | ||
10 | |||
11 | --- | ||
12 | drivers/net/Kconfig | 5 ++ | ||
13 | drivers/net/Makefile | 1 | ||
14 | drivers/net/pch_gbe/Makefile | 6 | ||
15 | drivers/net/pch_gbe/pch_gbe_api.c | 644 | ||
16 | drivers/net/pch_gbe/pch_gbe_api.h | 252 | ||
17 | drivers/net/pch_gbe/pch_gbe_defines.h | 367 | ||
18 | drivers/net/pch_gbe/pch_gbe_ethtool.c | 1306 | ||
19 | drivers/net/pch_gbe/pch_gbe.h | 230 | ||
20 | drivers/net/pch_gbe/pch_gbe_hw.h | 259 | ||
21 | drivers/net/pch_gbe/pch_gbe_mac.c | 522 | ||
22 | drivers/net/pch_gbe/pch_gbe_mac.h | 121 | ||
23 | drivers/net/pch_gbe/pch_gbe_main.c | 2973 | ||
24 | drivers/net/pch_gbe/pch_gbe_nvm.c | 129 | ||
25 | drivers/net/pch_gbe/pch_gbe_nvm.h | 85 | ||
26 | drivers/net/pch_gbe/pch_gbe_osdep.h | 74 | ||
27 | drivers/net/pch_gbe/pch_gbe_param.c | 594 | ||
28 | drivers/net/pch_gbe/pch_gbe_pci_ids.h | 38 | ||
29 | drivers/net/pch_gbe/pch_gbe_phy.c | 493 | ||
30 | drivers/net/pch_gbe/pch_gbe_phy.h | 136 | ||
31 | drivers/net/pch_gbe/pch_gbe_plat.c | 175 | ||
32 | drivers/net/pch_gbe/pch_gbe_regs.h | 351 | ||
33 | +++++++++++++++++++++++++++++++ 21 files changed, 8761 insertions(+) | ||
34 | diff -urN linux-2.6.33-rc3/drivers/net/Kconfig topcliff-2.6.33-rc3/drivers/net/Kconfig | ||
35 | --- linux-2.6.33-rc3/drivers/net/Kconfig 2010-01-06 09:02:46.000000000 +0900 | ||
36 | +++ topcliff-2.6.33-rc3/drivers/net/Kconfig 2010-03-12 16:24:03.000000000 +0900 | ||
37 | @@ -1977,6 +1977,11 @@ | ||
38 | If you say N, all options in this submenu will be skipped and disabled. | ||
39 | |||
40 | if NETDEV_1000 | ||
41 | +config PCH_GBE | ||
42 | + tristate "PCH Gigabit Ethernet" | ||
43 | + ---help--- | ||
44 | + This is an gigabit ethernet driver for PCH. | ||
45 | + resources. | ||
46 | |||
47 | config ACENIC | ||
48 | tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support" | ||
49 | diff -urN linux-2.6.33-rc3/drivers/net/Makefile topcliff-2.6.33-rc3/drivers/net/Makefile | ||
50 | --- linux-2.6.33-rc3/drivers/net/Makefile 2010-01-06 09:02:46.000000000 +0900 | ||
51 | +++ topcliff-2.6.33-rc3/drivers/net/Makefile 2010-03-05 10:25:56.000000000 +0900 | ||
52 | @@ -287,3 +287,4 @@ | ||
53 | obj-$(CONFIG_WIMAX) += wimax/ | ||
54 | |||
55 | obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/ | ||
56 | +obj-$(CONFIG_PCH_GBE) += pch_gbe/ | ||
57 | diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/Makefile topcliff-2.6.33-rc3/drivers/net/pch_gbe/Makefile | ||
58 | --- linux-2.6.33-rc3/drivers/net/pch_gbe/Makefile 1970-01-01 09:00:00.000000000 +0900 | ||
59 | +++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/Makefile 2010-03-11 09:35:16.000000000 +0900 | ||
60 | @@ -0,0 +1,6 @@ | ||
61 | +ifeq ($(CONFIG_PCH_GBE_DEBUG_CORE),y) | ||
62 | +EXTRA_CFLAGS += -DDEBUG | ||
63 | +endif | ||
64 | + | ||
65 | +obj-$(CONFIG_PCH_GBE) += pch_gbe.o | ||
66 | +pch_gbe-objs := pch_gbe_mac.o pch_gbe_phy.o pch_gbe_nvm.o pch_gbe_ethtool.o pch_gbe_plat.o pch_gbe_param.o pch_gbe_api.o pch_gbe_main.o | ||
67 | diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_api.c topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_api.c | ||
68 | --- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_api.c 1970-01-01 09:00:00.000000000 +0900 | ||
69 | +++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_api.c 2010-03-11 15:12:34.000000000 +0900 | ||
70 | @@ -0,0 +1,646 @@ | ||
71 | +/*! | ||
72 | + * @file ioh_gbe_api.c | ||
73 | + * @brief Linux IOH Gigabit Ethernet Driver HAL API source file | ||
74 | + * | ||
75 | + * @version 0.90 | ||
76 | + * | ||
77 | + * @section | ||
78 | + * This program is free software; you can redistribute it and/or modify | ||
79 | + * it under the terms of the GNU General Public License as published by | ||
80 | + * the Free Software Foundation; version 2 of the License. | ||
81 | + * | ||
82 | + * This program is distributed in the hope that it will be useful, | ||
83 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
84 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
85 | + * GNU General Public License for more details. | ||
86 | + * | ||
87 | + * You should have received a copy of the GNU General Public License | ||
88 | + * along with this program; if not, write to the Free Software | ||
89 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
90 | + */ | ||
91 | + | ||
92 | +/* | ||
93 | + * History: | ||
94 | + * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD. | ||
95 | + * All rights reserved. | ||
96 | + * | ||
97 | + * created: | ||
98 | + * OKI SEMICONDUCTOR 09/21/2009 | ||
99 | + * modified: | ||
100 | + * | ||
101 | + */ | ||
102 | + | ||
103 | +#include "pch_gbe_osdep.h" | ||
104 | +#include "pch_gbe_defines.h" | ||
105 | +#include "pch_gbe_hw.h" | ||
106 | +#include "pch_gbe_mac.h" | ||
107 | +#include "pch_gbe_api.h" | ||
108 | + | ||
109 | +/*! | ||
110 | + * @ingroup HAL API Layer | ||
111 | + * @fn s32 ioh_gbe_hal_set_mac_type(struct ioh_gbe_hw *hw) | ||
112 | + * @brief Sets MAC type | ||
113 | + * @param hw [INOUT] Pointer to the HW structure | ||
114 | + * @return IOH_GBE_SUCCESS: Successfully | ||
115 | + * @return Negative value: Failed | ||
116 | + * @remarks This function sets the mac type of the adapter based on the | ||
117 | + * device ID stored in the hw structure. | ||
118 | + * MUST BE FIRST FUNCTION CALLED (explicitly or through | ||
119 | + * ioh_gbe_hal_setup_init_funcs()). | ||
120 | + */ | ||
121 | +s32 ioh_gbe_hal_set_mac_type(struct ioh_gbe_hw *hw) | ||
122 | +{ | ||
123 | + struct ioh_gbe_mac_info *mac = &hw->mac; | ||
124 | + s32 ret_val = IOH_GBE_SUCCESS; | ||
125 | + | ||
126 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_set_mac_type"); | ||
127 | + | ||
128 | + switch ((u16) hw->device_id) { | ||
129 | + case PCI_DEVICE_ID_INTEL_IOH1_GBE: | ||
130 | + mac->type = IOH_GBE_MAC_TYPE_IOH1; | ||
131 | + break; | ||
132 | + default: | ||
133 | + /* Should never have loaded on this device */ | ||
134 | + mac->type = IOH_GBE_MAC_TYPE_UNDEFINED; | ||
135 | + ret_val = -IOH_GBE_ERR_MAC_INIT; | ||
136 | + break; | ||
137 | + } | ||
138 | + IOH_GBE_TESTOUT("mac->type:0x%x ret_val:0x%x\n", mac->type, ret_val); | ||
139 | + return ret_val; | ||
140 | +} | ||
141 | + | ||
142 | +/*! | ||
143 | + * @ingroup HAL API Layer | ||
144 | + * @fn s32 ioh_gbe_hal_setup_init_funcs(struct ioh_gbe_hw *hw) | ||
145 | + * @brief Initializes function pointers | ||
146 | + * @param hw [INOUT] pointer to the HW structure | ||
147 | + * @return IOH_GBE_SUCCESS: Successfully | ||
148 | + * @return Negative value: Failed | ||
149 | + * @remarks This function must be called by a driver in order to use the rest | ||
150 | + * of the 'shared' code files. Called by drivers only. | ||
151 | + */ | ||
152 | +s32 ioh_gbe_hal_setup_init_funcs(struct ioh_gbe_hw *hw) | ||
153 | +{ | ||
154 | + s32 ret_val; | ||
155 | + | ||
156 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_setup_init_funcs"); | ||
157 | + | ||
158 | + /* Can't do much good without knowing the MAC type. | ||
159 | + */ | ||
160 | + ret_val = ioh_gbe_hal_set_mac_type(hw); | ||
161 | + if (ret_val) { | ||
162 | + IOH_GBE_DBGOUT("ERROR: MAC type could not be set properly.\n"); | ||
163 | + goto out; | ||
164 | + } | ||
165 | + | ||
166 | + if (!hw->hw_addr) { | ||
167 | + IOH_GBE_DBGOUT("ERROR: Registers not mapped\n"); | ||
168 | + ret_val = -IOH_GBE_ERR_CONFIG; | ||
169 | + goto out; | ||
170 | + } | ||
171 | + | ||
172 | + /* Set up the init function pointers. These are functions within the | ||
173 | + * adapter family file that sets up function pointers for the rest of | ||
174 | + * the functions in that family. | ||
175 | + */ | ||
176 | + switch (hw->mac.type) { | ||
177 | + case IOH_GBE_MAC_TYPE_IOH1: | ||
178 | + case IOH_GBE_MAC_TYPE_IOH2: | ||
179 | + ioh_gbe_plat_init_function_pointers(hw); | ||
180 | + break; | ||
181 | + default: | ||
182 | + IOH_GBE_DBGOUT("Hardware not supported\n"); | ||
183 | + ret_val = -IOH_GBE_ERR_CONFIG; | ||
184 | + break; | ||
185 | + } | ||
186 | +out: | ||
187 | + IOH_GBE_TESTOUT("ret_val:0x%x\n", ret_val); | ||
188 | + return ret_val; | ||
189 | +} | ||
190 | + | ||
191 | +/*! | ||
192 | + * @ingroup HAL API Layer | ||
193 | + * @fn void ioh_gbe_hal_get_bus_info(struct ioh_gbe_hw *hw) | ||
194 | + * @brief Obtain bus information for adapter | ||
195 | + * @param hw [INOUT] pointer to the HW structure | ||
196 | + * @return None | ||
197 | + * @remarks This will obtain information about the HW bus for which the | ||
198 | + * adaper is attached and stores it in the hw structure. This is a | ||
199 | + * function pointer entry point called by drivers. | ||
200 | + */ | ||
201 | +void ioh_gbe_hal_get_bus_info(struct ioh_gbe_hw *hw) | ||
202 | +{ | ||
203 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_get_bus_info"); | ||
204 | + | ||
205 | + if (hw->func.get_bus_info != NULL) | ||
206 | + hw->func.get_bus_info(hw); | ||
207 | + else | ||
208 | + IOH_GBE_ERR("Error: configuration\n"); | ||
209 | +} | ||
210 | + | ||
211 | +/*! | ||
212 | + * @ingroup HAL API Layer | ||
213 | + * @fn void ioh_gbe_hal_mc_addr_list_update(struct ioh_gbe_hw *hw, | ||
214 | + * u8 *mc_addr_list, u32 mc_addr_count, | ||
215 | + * u32 mar_used_count, u32 mar_count) | ||
216 | + * @brief Update Multicast addresses | ||
217 | + * @param hw [INOUT] Pointer to the HW structure | ||
218 | + * @param mc_addr_list [IN]Array of multicast addresses to program | ||
219 | + * @param mc_addr_count [IN]Number of multicast addresses to program | ||
220 | + * @param mar_used_count [IN]The first MAC Address register free to program | ||
221 | + * @param mar_count [IN]Total number of supported MAC Address Registers | ||
222 | + * @return None | ||
223 | + * @remarks | ||
224 | + * Updates the MAC Address Registers and Multicast Table Array. | ||
225 | + * The caller must have a packed mc_addr_list of multicast addresses. | ||
226 | + * The parameter mar_count will usually be hw->mac.mar_entry_count | ||
227 | + * unless there are workarounds that change this. Currently no func pointer | ||
228 | + * exists and all implementations are handled in the generic version of this | ||
229 | + * function. | ||
230 | + */ | ||
231 | +void | ||
232 | +ioh_gbe_hal_mc_addr_list_update(struct ioh_gbe_hw *hw, | ||
233 | + u8 *mc_addr_list, | ||
234 | + u32 mc_addr_count, | ||
235 | + u32 mar_used_count, u32 mar_count) | ||
236 | +{ | ||
237 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_mc_addr_list_update"); | ||
238 | + | ||
239 | + if (hw->func.mc_addr_list_update != NULL) { | ||
240 | + hw->func.mc_addr_list_update(hw, | ||
241 | + mc_addr_list, | ||
242 | + mc_addr_count, | ||
243 | + mar_used_count, mar_count); | ||
244 | + } | ||
245 | +} | ||
246 | + | ||
247 | +/*! | ||
248 | + * @ingroup HAL API Layer | ||
249 | + * @fn s32 ioh_gbe_hal_force_mac_fc(struct ioh_gbe_hw *hw) | ||
250 | + * @brief Force MAC flow control | ||
251 | + * @param hw [INOUT] Pointer to the HW structure | ||
252 | + * @return IOH_GBE_SUCCESS: Successfully | ||
253 | + * @return Negative value: Failed | ||
254 | + * @remarks | ||
255 | + * Force the MAC's flow control settings. Currently no func pointer exists | ||
256 | + * and all implementations are handled in the generic version of this | ||
257 | + * function. | ||
258 | + */ | ||
259 | +s32 ioh_gbe_hal_force_mac_fc(struct ioh_gbe_hw *hw) | ||
260 | +{ | ||
261 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_force_mac_fc"); | ||
262 | + | ||
263 | + return ioh_gbe_mac_force_mac_fc(hw); | ||
264 | +} | ||
265 | + | ||
266 | +/*! | ||
267 | + * @ingroup HAL API Layer | ||
268 | + * @fn s32 ioh_gbe_hal_reset_hw(struct ioh_gbe_hw *hw) | ||
269 | + * @brief Reset hardware | ||
270 | + * @param hw [INOUT] Pointer to the HW structure | ||
271 | + * @return IOH_GBE_SUCCESS: Successfully | ||
272 | + * @return Negative value: Failed | ||
273 | + * @remarks | ||
274 | + * This resets the hardware into a known state. This is a function pointer | ||
275 | + * entry point called by drivers. | ||
276 | + */ | ||
277 | +s32 ioh_gbe_hal_reset_hw(struct ioh_gbe_hw *hw) | ||
278 | +{ | ||
279 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_reset_hw"); | ||
280 | + | ||
281 | + if (hw->func.reset_hw != NULL) { | ||
282 | + hw->func.reset_hw(hw); | ||
283 | + return IOH_GBE_SUCCESS; | ||
284 | + } else { | ||
285 | + IOH_GBE_ERR("Error: configuration\n"); | ||
286 | + return -IOH_GBE_ERR_CONFIG; | ||
287 | + } | ||
288 | +} | ||
289 | + | ||
290 | +/*! | ||
291 | + * @ingroup HAL API Layer | ||
292 | + * @fn s32 ioh_gbe_hal_init_hw(struct ioh_gbe_hw *hw) | ||
293 | + * @brief Initialize hardware | ||
294 | + * @param hw [INOUT] Pointer to the HW structure | ||
295 | + * @return IOH_GBE_SUCCESS: Successfully | ||
296 | + * @return Negative value: Failed | ||
297 | + * @remarks | ||
298 | + * This inits the hardware readying it for operation. This is a function | ||
299 | + * pointer entry point called by drivers. | ||
300 | + */ | ||
301 | +s32 ioh_gbe_hal_init_hw(struct ioh_gbe_hw *hw) | ||
302 | +{ | ||
303 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_init_hw"); | ||
304 | + | ||
305 | + if (hw->func.init_hw != NULL) { | ||
306 | + return hw->func.init_hw(hw); | ||
307 | + } else { | ||
308 | + IOH_GBE_ERR("Error: configuration\n"); | ||
309 | + return -IOH_GBE_ERR_CONFIG; | ||
310 | + } | ||
311 | +} | ||
312 | + | ||
313 | +/*! | ||
314 | + * @ingroup HAL API Layer | ||
315 | + * @fn s32 ioh_gbe_hal_setup_link(struct ioh_gbe_hw *hw) | ||
316 | + * @brief Configures link and flow control | ||
317 | + * @param hw [INOUT] Pointer to the HW structure | ||
318 | + * @return IOH_GBE_SUCCESS: Successfully | ||
319 | + * @return Negative value: Failed | ||
320 | + * @remarks | ||
321 | + * This configures link and flow control settings for the adapter. This | ||
322 | + * is a function pointer entry point called by drivers. While modules can | ||
323 | + * also call this, they probably call their own version of this function. | ||
324 | + */ | ||
325 | +s32 ioh_gbe_hal_setup_link(struct ioh_gbe_hw *hw) | ||
326 | +{ | ||
327 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_setup_link"); | ||
328 | + | ||
329 | + if (hw->func.setup_link != NULL) { | ||
330 | + return hw->func.setup_link(hw); | ||
331 | + } else { | ||
332 | + IOH_GBE_ERR("Error: configuration\n"); | ||
333 | + return -IOH_GBE_ERR_CONFIG; | ||
334 | + } | ||
335 | +} | ||
336 | + | ||
337 | +/*! | ||
338 | + * @ingroup HAL API Layer | ||
339 | + * @fn s32 ioh_gbe_hal_setup_led(struct ioh_gbe_hw *hw) | ||
340 | + * @brief Configures SW controllable LED | ||
341 | + * @param hw [INOUT] Pointer to the HW structure | ||
342 | + * @return IOH_GBE_SUCCESS: Successfully | ||
343 | + * @return Negative value: Failed | ||
344 | + * @remarks | ||
345 | + * This prepares the SW controllable LED for use and saves the current state | ||
346 | + * of the LED so it can be later restored. This is a function pointer entry | ||
347 | + * point called by drivers. | ||
348 | + */ | ||
349 | +s32 ioh_gbe_hal_setup_led(struct ioh_gbe_hw *hw) | ||
350 | +{ | ||
351 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_setup_led"); | ||
352 | + | ||
353 | + if (hw->func.setup_led != NULL) | ||
354 | + return hw->func.setup_led(hw); | ||
355 | + else | ||
356 | + return IOH_GBE_SUCCESS; | ||
357 | +} | ||
358 | + | ||
359 | +/*! | ||
360 | + * @ingroup HAL API Layer | ||
361 | + * @fn s32 ioh_gbe_hal_cleanup_led(struct ioh_gbe_hw *hw) | ||
362 | + * @brief Restores SW controllable LED | ||
363 | + * @param hw [INOUT] Pointer to the HW structure | ||
364 | + * @return IOH_GBE_SUCCESS: Successfully | ||
365 | + * @return Negative value: Failed | ||
366 | + * @remarks | ||
367 | + * This restores the SW controllable LED to the value saved off by | ||
368 | + * ioh_gbe_hal_setup_led. | ||
369 | + * This is a function pointer entry point called by drivers. | ||
370 | + */ | ||
371 | +s32 ioh_gbe_hal_cleanup_led(struct ioh_gbe_hw *hw) | ||
372 | +{ | ||
373 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_cleanup_led"); | ||
374 | + | ||
375 | + if (hw->func.cleanup_led != NULL) | ||
376 | + return hw->func.cleanup_led(hw); | ||
377 | + else | ||
378 | + return IOH_GBE_SUCCESS; | ||
379 | +} | ||
380 | + | ||
381 | +/*! | ||
382 | + * @ingroup HAL API Layer | ||
383 | + * @fn s32 ioh_gbe_hal_led_on(struct ioh_gbe_hw *hw) | ||
384 | + * @brief Turn on SW controllable LED | ||
385 | + * @param hw [INOUT] Pointer to the HW structure | ||
386 | + * @return IOH_GBE_SUCCESS: Successfully | ||
387 | + * @return Negative value: Failed | ||
388 | + * @remarks | ||
389 | + * Turns the SW defined LED on. This is a function pointer entry point | ||
390 | + * called by drivers. | ||
391 | + */ | ||
392 | +s32 ioh_gbe_hal_led_on(struct ioh_gbe_hw *hw) | ||
393 | +{ | ||
394 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_led_on"); | ||
395 | + | ||
396 | + if (hw->func.led_on != NULL) | ||
397 | + return hw->func.led_on(hw); | ||
398 | + else | ||
399 | + return IOH_GBE_SUCCESS; | ||
400 | +} | ||
401 | + | ||
402 | +/*! | ||
403 | + * @ingroup HAL API Layer | ||
404 | + * @fn s32 ioh_gbe_hal_led_off(struct ioh_gbe_hw *hw) | ||
405 | + * @brief Turn off SW controllable LED | ||
406 | + * @param hw [INOUT] Pointer to the HW structure | ||
407 | + * @return IOH_GBE_SUCCESS: Successfully | ||
408 | + * @return Negative value: Failed | ||
409 | + * @remarks | ||
410 | + * Turns the SW defined LED off. This is a function pointer entry point | ||
411 | + * called by drivers. | ||
412 | + */ | ||
413 | +s32 ioh_gbe_hal_led_off(struct ioh_gbe_hw *hw) | ||
414 | +{ | ||
415 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_led_off"); | ||
416 | + | ||
417 | + if (hw->func.led_off != NULL) | ||
418 | + return hw->func.led_off(hw); | ||
419 | + else | ||
420 | + return IOH_GBE_SUCCESS; | ||
421 | +} | ||
422 | + | ||
423 | +/*! | ||
424 | + * @ingroup HAL API Layer | ||
425 | + * @fn void ioh_gbe_hal_mar_set(struct ioh_gbe_hw *hw, u8 *addr, u32 index) | ||
426 | + * @brief Sets a MAC address register | ||
427 | + * @param hw [INOUT] Pointer to the HW structure | ||
428 | + * @param addr [IN] Address to set the RAR to | ||
429 | + * @param index [IN] The RAR to set | ||
430 | + * @return None | ||
431 | + * @remarks | ||
432 | + * Sets a MAC Address Register (RAR) to the specified address. | ||
433 | + * Currently no func pointer exists and all implementations are | ||
434 | + * handled in the generic version of this function. | ||
435 | + */ | ||
436 | +void ioh_gbe_hal_mar_set(struct ioh_gbe_hw *hw, u8 *addr, u32 index) | ||
437 | +{ | ||
438 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_mar_set"); | ||
439 | + | ||
440 | + ioh_gbe_mac_mar_set(hw, addr, index); | ||
441 | +} | ||
442 | + | ||
443 | +/*! | ||
444 | + * @ingroup HAL API Layer | ||
445 | + * @fn s32 ioh_gbe_hal_read_phy_reg(struct ioh_gbe_hw *hw, | ||
446 | + * u32 offset, u16 *data) | ||
447 | + * @brief Reads PHY register | ||
448 | + * @param hw [INOUT] Pointer to the HW structure | ||
449 | + * @param offset [IN] The register to read | ||
450 | + * @param data [IN] The buffer to store the 16-bit read. | ||
451 | + * @return IOH_GBE_SUCCESS: Successfully | ||
452 | + * @return Negative value: Failed | ||
453 | + * @remarks | ||
454 | + * Reads the PHY register and returns the value in data. | ||
455 | + * This is a function pointer entry point called by drivers. | ||
456 | + */ | ||
457 | +s32 ioh_gbe_hal_read_phy_reg(struct ioh_gbe_hw *hw, u32 offset, u16 *data) | ||
458 | +{ | ||
459 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_read_phy_reg"); | ||
460 | + | ||
461 | + if (hw->func.read_phy_reg != NULL) | ||
462 | + return hw->func.read_phy_reg(hw, offset, data); | ||
463 | + else | ||
464 | + return IOH_GBE_SUCCESS; | ||
465 | +} | ||
466 | + | ||
467 | +/*! | ||
468 | + * @ingroup HAL API Layer | ||
469 | + * @fn s32 ioh_gbe_hal_write_phy_reg(struct ioh_gbe_hw *hw, | ||
470 | + * u32 offset, u16 data) | ||
471 | + * @brief Writes PHY register | ||
472 | + * @param hw [INOUT] Pointer to the HW structure | ||
473 | + * @param offset [IN] The register to write | ||
474 | + * @param data [IN] The value to write. | ||
475 | + * @return IOH_GBE_SUCCESS: Successfully | ||
476 | + * @return Negative value: Failed | ||
477 | + * @remarks | ||
478 | + * Writes the PHY register at offset with the value in data. | ||
479 | + * This is a function pointer entry point called by drivers. | ||
480 | + */ | ||
481 | +s32 ioh_gbe_hal_write_phy_reg(struct ioh_gbe_hw *hw, u32 offset, u16 data) | ||
482 | +{ | ||
483 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_write_phy_reg"); | ||
484 | + | ||
485 | + if (hw->func.write_phy_reg != NULL) | ||
486 | + return hw->func.write_phy_reg(hw, offset, data); | ||
487 | + else | ||
488 | + return IOH_GBE_SUCCESS; | ||
489 | +} | ||
490 | + | ||
491 | +/*! | ||
492 | + * @ingroup HAL API Layer | ||
493 | + * @fn void ioh_gbe_hal_phy_hw_reset(struct ioh_gbe_hw *hw) | ||
494 | + * @brief Hard PHY reset | ||
495 | + * @param hw [INOUT] Pointer to the HW structure | ||
496 | + * @return None | ||
497 | + * @remarks | ||
498 | + * Performs a hard PHY reset. This is a function pointer entry point called | ||
499 | + * by drivers. | ||
500 | + */ | ||
501 | +void ioh_gbe_hal_phy_hw_reset(struct ioh_gbe_hw *hw) | ||
502 | +{ | ||
503 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_phy_hw_reset"); | ||
504 | + | ||
505 | + if (hw->func.reset_phy != NULL) | ||
506 | + hw->func.reset_phy(hw); | ||
507 | + else | ||
508 | + IOH_GBE_ERR("Error: configuration\n"); | ||
509 | +} | ||
510 | + | ||
511 | +/*! | ||
512 | + * @ingroup HAL API Layer | ||
513 | + * @fn void ioh_gbe_hal_phy_sw_reset(struct ioh_gbe_hw *hw) | ||
514 | + * @brief Soft PHY reset | ||
515 | + * @param hw [INOUT] Pointer to the HW structure | ||
516 | + * @return None | ||
517 | + * @remarks | ||
518 | + * Performs a soft PHY reset on those that apply. This is a function pointer | ||
519 | + * entry point called by drivers. | ||
520 | + */ | ||
521 | +void ioh_gbe_hal_phy_sw_reset(struct ioh_gbe_hw *hw) | ||
522 | +{ | ||
523 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_phy_sw_reset"); | ||
524 | + | ||
525 | + if (hw->func.sw_reset_phy != NULL) | ||
526 | + hw->func.sw_reset_phy(hw); | ||
527 | + else | ||
528 | + IOH_GBE_ERR("Error: configuration\n"); | ||
529 | +} | ||
530 | + | ||
531 | +/*! | ||
532 | + * @ingroup HAL API Layer | ||
533 | + * @fn s32 ioh_gbe_hal_read_mac_addr(struct ioh_gbe_hw *hw) | ||
534 | + * @brief Reads MAC address | ||
535 | + * @param hw [INOUT] Pointer to the HW structure | ||
536 | + * @return IOH_GBE_SUCCESS: Successfully | ||
537 | + * @return Negative value: Failed | ||
538 | + * @remarks | ||
539 | + * Reads the MAC address out of the adapter and stores it in the HW structure. | ||
540 | + * Currently no func pointer exists and all implementations are handled in the | ||
541 | + * generic version of this function. | ||
542 | + */ | ||
543 | +s32 ioh_gbe_hal_read_mac_addr(struct ioh_gbe_hw *hw) | ||
544 | +{ | ||
545 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_read_mac_addr"); | ||
546 | + | ||
547 | + if (hw->func.read_mac_addr != NULL) { | ||
548 | + return hw->func.read_mac_addr(hw); | ||
549 | + } else { | ||
550 | + IOH_GBE_ERR("Error: configuration\n"); | ||
551 | + return -IOH_GBE_ERR_CONFIG; | ||
552 | + } | ||
553 | +} | ||
554 | + | ||
555 | +#ifdef CONFIG_PCH_PCIEQOS | ||
556 | +/*! | ||
557 | + * @ingroup HAL API Layer | ||
558 | + * @fn s32 ioh_gbe_hal_validate_nvm_checksum(struct ioh_gbe_hw *hw) | ||
559 | + * @brief Verifies NVM (EEPROM) checksum | ||
560 | + * @param hw [INOUT] Pointer to the HW structure | ||
561 | + * @return IOH_GBE_SUCCESS: Successfully | ||
562 | + * @return Negative value: Failed | ||
563 | + * @remarks | ||
564 | + * Validates the NVM checksum is correct. This is a function pointer entry | ||
565 | + * point called by drivers. | ||
566 | + */ | ||
567 | +s32 ioh_gbe_hal_validate_nvm_checksum(struct ioh_gbe_hw *hw) | ||
568 | +{ | ||
569 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_validate_nvm_checksum"); | ||
570 | + | ||
571 | + if (hw->func.validate_nvm != NULL) { | ||
572 | + return hw->func.validate_nvm(hw); | ||
573 | + } else { | ||
574 | + IOH_GBE_ERR("Error: configuration\n"); | ||
575 | + return -IOH_GBE_ERR_CONFIG; | ||
576 | + } | ||
577 | +} | ||
578 | + | ||
579 | +/*! | ||
580 | + * @ingroup HAL API Layer | ||
581 | + * @fn s32 ioh_gbe_hal_read_nvm(struct ioh_gbe_hw *hw, | ||
582 | + * u32 offset, u8 *data) | ||
583 | + * @brief Reads NVM (EEPROM) | ||
584 | + * @param hw [INOUT] Pointer to the HW structure | ||
585 | + * @param offset [IN] The word offset to read | ||
586 | + * @param data [IN] Pointer to the properly sized buffer for the data. | ||
587 | + * @return IOH_GBE_SUCCESS: Successfully | ||
588 | + * @return Negative value: Failed | ||
589 | + * @remarks | ||
590 | + * Reads 16-bit chunks of data from the NVM (EEPROM). This is a function | ||
591 | + * pointer entry point called by drivers. | ||
592 | + */ | ||
593 | +s32 ioh_gbe_hal_read_nvm(struct ioh_gbe_hw *hw, u32 offset, u8 *data) | ||
594 | +{ | ||
595 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_read_nvm"); | ||
596 | + | ||
597 | + if (hw->func.read_nvm != NULL) { | ||
598 | + return hw->func.read_nvm(hw, offset, data); | ||
599 | + } else { | ||
600 | + IOH_GBE_ERR("Error: configuration\n"); | ||
601 | + return -IOH_GBE_ERR_CONFIG; | ||
602 | + } | ||
603 | +} | ||
604 | + | ||
605 | +/*! | ||
606 | + * @ingroup HAL API Layer | ||
607 | + * @fn s32 ioh_gbe_hal_write_nvm(struct ioh_gbe_hw *hw, | ||
608 | + * u32 offset, u8 *data) | ||
609 | + * @brief Writes to NVM (EEPROM) | ||
610 | + * @param hw [INOUT] Pointer to the HW structure | ||
611 | + * @param offset [IN] The word offset to read | ||
612 | + * @param data [IN] Pointer to the properly sized buffer for the data. | ||
613 | + * @return IOH_GBE_SUCCESS: Successfully | ||
614 | + * @return Negative value: Failed | ||
615 | + * @remarks | ||
616 | + * Writes 16-bit chunks of data to the NVM (EEPROM). This is a function | ||
617 | + * pointer entry point called by drivers. | ||
618 | + */ | ||
619 | +s32 ioh_gbe_hal_write_nvm(struct ioh_gbe_hw *hw, u32 offset, u8 *data) | ||
620 | +{ | ||
621 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_write_nvm"); | ||
622 | + | ||
623 | + if (hw->func.write_nvm != NULL) | ||
624 | + return hw->func.write_nvm(hw, offset, data); | ||
625 | + else | ||
626 | + return IOH_GBE_SUCCESS; | ||
627 | +} | ||
628 | +#endif /* CONFIG_PCH_PCIEQOS */ | ||
629 | + | ||
630 | +/*! | ||
631 | + * @ingroup HAL API Layer | ||
632 | + * @fn void ioh_gbe_hal_set_wol_event(struct ioh_gbe_hw *hw, u32 wu_evt) | ||
633 | + * @brief Set wake-on-lan event | ||
634 | + * @param hw [INOUT] Pointer to the HW structure | ||
635 | + * @param wu_evt [IN] Wake up event | ||
636 | + * @return None | ||
637 | + */ | ||
638 | +void ioh_gbe_hal_set_wol_event(struct ioh_gbe_hw *hw, u32 wu_evt) | ||
639 | +{ | ||
640 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_set_wol_event"); | ||
641 | + | ||
642 | + ioh_gbe_mac_set_wol_event(hw, wu_evt); | ||
643 | +} | ||
644 | + | ||
645 | +/*! | ||
646 | + * @ingroup HAL API Layer | ||
647 | + * @fn void ioh_gbe_hal_power_up_phy(struct ioh_gbe_hw *hw) | ||
648 | + * @brief Power up PHY | ||
649 | + * @param hw [INOUT] Pointer to the HW structure | ||
650 | + * @return None | ||
651 | + */ | ||
652 | +void ioh_gbe_hal_power_up_phy(struct ioh_gbe_hw *hw) | ||
653 | +{ | ||
654 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_power_up_phy"); | ||
655 | + | ||
656 | + if (hw->func.power_up_phy != NULL) | ||
657 | + hw->func.power_up_phy(hw); | ||
658 | +} | ||
659 | + | ||
660 | +/*! | ||
661 | + * @ingroup HAL API Layer | ||
662 | + * @fn void ioh_gbe_hal_power_down_phy(struct ioh_gbe_hw *hw) | ||
663 | + * @brief Power down PHY | ||
664 | + * @param hw [INOUT] Pointer to the HW structure | ||
665 | + * @return None | ||
666 | + */ | ||
667 | +void ioh_gbe_hal_power_down_phy(struct ioh_gbe_hw *hw) | ||
668 | +{ | ||
669 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_power_down_phy"); | ||
670 | + | ||
671 | + if (hw->func.power_down_phy != NULL) | ||
672 | + hw->func.power_down_phy(hw); | ||
673 | +} | ||
674 | + | ||
675 | +/*! | ||
676 | + * @ingroup HAL API Layer | ||
677 | + * @fn u16 ioh_gbe_hal_ctrl_miim(struct ioh_gbe_hw *hw, | ||
678 | + * u32 addr, u32 dir, u32 reg, u16 data) | ||
679 | + * @brief Control MII Management IF | ||
680 | + * @param hw [INOUT] Pointer to the HW structure | ||
681 | + * @param addr [IN] Address of PHY | ||
682 | + * @param dir [IN] Operetion. (Write or Read) | ||
683 | + * @param reg [IN] Access register of PHY | ||
684 | + * @param data [IN] Write data | ||
685 | + * @return None | ||
686 | + */ | ||
687 | +u16 | ||
688 | +ioh_gbe_hal_ctrl_miim(struct ioh_gbe_hw *hw, u32 addr, u32 dir, u32 reg, | ||
689 | + u16 data) | ||
690 | +{ | ||
691 | + IOH_GBE_DBGOUT2("ioh_gbe_hal_ctrl_miim\n"); | ||
692 | + | ||
693 | + if (hw->func.ctrl_miim != NULL) { | ||
694 | + return hw->func.ctrl_miim(hw, addr, dir, reg, data); | ||
695 | + } else { | ||
696 | + IOH_GBE_ERR("Error: configuration\n"); | ||
697 | + return IOH_GBE_SUCCESS; | ||
698 | + } | ||
699 | +} | ||
700 | + | ||
701 | +/*! | ||
702 | + * @ingroup HAL API Layer | ||
703 | + * @fn void ioh_gbe_hal_set_pause_packet(struct ioh_gbe_hw *hw) | ||
704 | + * @brief Set pause packet | ||
705 | + * @param hw [INOUT] Pointer to the HW structure | ||
706 | + * @return None | ||
707 | + */ | ||
708 | +void ioh_gbe_hal_set_pause_packet(struct ioh_gbe_hw *hw) | ||
709 | +{ | ||
710 | + IOH_GBE_DBGFUNC("ioh_gbe_hal_set_pause_packet"); | ||
711 | + | ||
712 | + if (hw->func.pause_packet != NULL) | ||
713 | + hw->func.pause_packet(hw); | ||
714 | + else | ||
715 | + IOH_GBE_ERR("Error: configuration\n"); | ||
716 | +} | ||
717 | diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_api.h topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_api.h | ||
718 | --- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_api.h 1970-01-01 09:00:00.000000000 +0900 | ||
719 | +++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_api.h 2010-03-11 15:11:51.000000000 +0900 | ||
720 | @@ -0,0 +1,252 @@ | ||
721 | +/*! | ||
722 | + * @file ioh_gbe_api.h | ||
723 | + * @brief Linux IOH Gigabit Ethernet Driver HAL API header file | ||
724 | + * | ||
725 | + * @version 0.90 | ||
726 | + * | ||
727 | + * @section | ||
728 | + * This program is free software; you can redistribute it and/or modify | ||
729 | + * it under the terms of the GNU General Public License as published by | ||
730 | + * the Free Software Foundation; version 2 of the License. | ||
731 | + * | ||
732 | + * This program is distributed in the hope that it will be useful, | ||
733 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
734 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
735 | + * GNU General Public License for more details. | ||
736 | + * | ||
737 | + * You should have received a copy of the GNU General Public License | ||
738 | + * along with this program; if not, write to the Free Software | ||
739 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
740 | + */ | ||
741 | + | ||
742 | +/* | ||
743 | + * History: | ||
744 | + * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD. | ||
745 | + * All rights reserved. | ||
746 | + * | ||
747 | + * created: | ||
748 | + * OKI SEMICONDUCTOR 09/21/2009 | ||
749 | + * modified: | ||
750 | + * | ||
751 | + */ | ||
752 | + | ||
753 | +#ifndef _IOH_GBE_API_H_ | ||
754 | +#define _IOH_GBE_API_H_ | ||
755 | + | ||
756 | +/*! | ||
757 | + * @ingroup HAL API Layer | ||
758 | + * @fn s32 ioh_gbe_hal_set_mac_type(struct ioh_gbe_hw *hw) | ||
759 | + * @brief Sets MAC type | ||
760 | + */ | ||
761 | +s32 ioh_gbe_hal_set_mac_type(struct ioh_gbe_hw *hw); | ||
762 | + | ||
763 | +/*! | ||
764 | + * @ingroup HAL API Layer | ||
765 | + * @fn s32 ioh_gbe_hal_setup_init_funcs(struct ioh_gbe_hw *hw) | ||
766 | + * @brief Initializes function pointers | ||
767 | + */ | ||
768 | +s32 ioh_gbe_hal_setup_init_funcs(struct ioh_gbe_hw *hw); | ||
769 | + | ||
770 | +/*! | ||
771 | + * @ingroup HAL API Layer | ||
772 | + * @fn void ioh_gbe_hal_get_bus_info(struct ioh_gbe_hw *hw) | ||
773 | + * @brief Obtain bus information for adapter | ||
774 | + */ | ||
775 | +void ioh_gbe_hal_get_bus_info(struct ioh_gbe_hw *hw); | ||
776 | + | ||
777 | +/*! | ||
778 | + * @ingroup HAL API Layer | ||
779 | + * @fn void ioh_gbe_hal_mc_addr_list_update(struct ioh_gbe_hw *hw, | ||
780 | + * u8 *mc_addr_list, u32 mc_addr_count, | ||
781 | + * u32 mar_used_count, u32 mar_count) | ||
782 | + * @brief Update Multicast addresses | ||
783 | + */ | ||
784 | +void ioh_gbe_hal_mc_addr_list_update(struct ioh_gbe_hw *hw, | ||
785 | + u8 *mc_addr_list, u32 mc_addr_count, | ||
786 | + u32 mar_used_count, u32 mar_count); | ||
787 | + | ||
788 | +/* | ||
789 | + * @ingroup HAL API Layer | ||
790 | + * @fn s32 ioh_gbe_hal_force_mac_fc(struct ioh_gbe_hw *hw) | ||
791 | + * @brief Force MAC flow control | ||
792 | + */ | ||
793 | +s32 ioh_gbe_hal_force_mac_fc(struct ioh_gbe_hw *hw); | ||
794 | + | ||
795 | +/*! | ||
796 | + * @ingroup HAL API Layer | ||
797 | + * @fn s32 ioh_gbe_hal_reset_hw(struct ioh_gbe_hw *hw) | ||
798 | + * @brief Reset hardware | ||
799 | + */ | ||
800 | +s32 ioh_gbe_hal_reset_hw(struct ioh_gbe_hw *hw); | ||
801 | + | ||
802 | +/*! | ||
803 | + * @ingroup HAL API Layer | ||
804 | + * @fn s32 ioh_gbe_hal_init_hw(struct ioh_gbe_hw *hw) | ||
805 | + * @brief Initialize hardware | ||
806 | + */ | ||
807 | +s32 ioh_gbe_hal_init_hw(struct ioh_gbe_hw *hw); | ||
808 | + | ||
809 | +/*! | ||
810 | + * @ingroup HAL API Layer | ||
811 | + * @fn s32 ioh_gbe_hal_setup_link(struct ioh_gbe_hw *hw) | ||
812 | + * @brief Configures link and flow control | ||
813 | + */ | ||
814 | +s32 ioh_gbe_hal_setup_link(struct ioh_gbe_hw *hw); | ||
815 | + | ||
816 | +/*! | ||
817 | + * @ingroup HAL API Layer | ||
818 | + * @fn s32 ioh_gbe_hal_setup_led(struct ioh_gbe_hw *hw) | ||
819 | + * @brief Configures SW controllable LED | ||
820 | + */ | ||
821 | +s32 ioh_gbe_hal_setup_led(struct ioh_gbe_hw *hw); | ||
822 | + | ||
823 | +/*! | ||
824 | + * @ingroup HAL API Layer | ||
825 | + * @fn s32 ioh_gbe_hal_cleanup_led(struct ioh_gbe_hw *hw) | ||
826 | + * @brief Restores SW controllable LED | ||
827 | + */ | ||
828 | +s32 ioh_gbe_hal_cleanup_led(struct ioh_gbe_hw *hw); | ||
829 | + | ||
830 | +/*! | ||
831 | + * @ingroup HAL API Layer | ||
832 | + * @fn s32 ioh_gbe_hal_led_on(struct ioh_gbe_hw *hw) | ||
833 | + * @brief Turn on SW controllable LED | ||
834 | + */ | ||
835 | +s32 ioh_gbe_hal_led_on(struct ioh_gbe_hw *hw); | ||
836 | + | ||
837 | +/*! | ||
838 | + * @ingroup HAL API Layer | ||
839 | + * @fn s32 ioh_gbe_hal_led_off(struct ioh_gbe_hw *hw) | ||
840 | + * @brief Turn off SW controllable LED | ||
841 | + */ | ||
842 | +s32 ioh_gbe_hal_led_off(struct ioh_gbe_hw *hw); | ||
843 | + | ||
844 | +/*! | ||
845 | + * @ingroup HAL API Layer | ||
846 | + * @fn void ioh_gbe_hal_mar_set(struct ioh_gbe_hw *hw, u8 *addr, u32 index) | ||
847 | + * @brief Sets a MAC address register | ||
848 | + */ | ||
849 | +void ioh_gbe_hal_mar_set(struct ioh_gbe_hw *hw, u8 *addr, u32 index); | ||
850 | + | ||
851 | +/*! | ||
852 | + * @ingroup HAL API Layer | ||
853 | + * @fn s32 ioh_gbe_hal_read_phy_reg(struct ioh_gbe_hw *hw, | ||
854 | + * u32 offset, u16 *data) | ||
855 | + * @brief Reads PHY register | ||
856 | + */ | ||
857 | +s32 ioh_gbe_hal_read_phy_reg(struct ioh_gbe_hw *hw, u32 offset, u16 *data); | ||
858 | + | ||
859 | +/*! | ||
860 | + * @ingroup HAL API Layer | ||
861 | + * @fn s32 ioh_gbe_hal_write_phy_reg(struct ioh_gbe_hw *hw, | ||
862 | + * u32 offset, u16 data) | ||
863 | + * @brief Writes PHY register | ||
864 | + */ | ||
865 | +s32 ioh_gbe_hal_write_phy_reg(struct ioh_gbe_hw *hw, u32 offset, u16 data); | ||
866 | + | ||
867 | +/*! | ||
868 | + * @ingroup HAL API Layer | ||
869 | + * @fn void ioh_gbe_hal_phy_hw_reset(struct ioh_gbe_hw *hw) | ||
870 | + * @brief Hard PHY reset | ||
871 | + */ | ||
872 | +void ioh_gbe_hal_phy_hw_reset(struct ioh_gbe_hw *hw); | ||
873 | + | ||
874 | +/*! | ||
875 | + * @ingroup HAL API Layer | ||
876 | + * @fn void ioh_gbe_hal_phy_sw_reset(struct ioh_gbe_hw *hw) | ||
877 | + * @brief Soft PHY reset | ||
878 | + */ | ||
879 | +void ioh_gbe_hal_phy_sw_reset(struct ioh_gbe_hw *hw); | ||
880 | + | ||
881 | +/*! | ||
882 | + * @ingroup HAL API Layer | ||
883 | + * @fn s32 ioh_gbe_hal_read_mac_addr(struct ioh_gbe_hw *hw) | ||
884 | + * @brief Reads MAC address | ||
885 | + */ | ||
886 | +s32 ioh_gbe_hal_read_mac_addr(struct ioh_gbe_hw *hw); | ||
887 | + | ||
888 | +#ifdef CONFIG_PCH_PCIEQOS | ||
889 | +/*! | ||
890 | + * @ingroup HAL API Layer | ||
891 | + * @fn s32 ioh_gbe_hal_validate_nvm_checksum(struct ioh_gbe_hw *hw) | ||
892 | + * @brief Verifies NVM (EEPROM) checksum | ||
893 | + */ | ||
894 | +s32 ioh_gbe_hal_validate_nvm_checksum(struct ioh_gbe_hw *hw); | ||
895 | + | ||
896 | +/*! | ||
897 | + * @ingroup HAL API Layer | ||
898 | + * @fn s32 ioh_gbe_hal_read_nvm(struct ioh_gbe_hw *hw, | ||
899 | + * u32 offset, u8 *data) | ||
900 | + * @brief Reads NVM (EEPROM) | ||
901 | + */ | ||
902 | +s32 ioh_gbe_hal_read_nvm(struct ioh_gbe_hw *hw, u32 offset, u8 *data); | ||
903 | + | ||
904 | +/*! | ||
905 | + * @ingroup HAL API Layer | ||
906 | + * @fn s32 ioh_gbe_hal_write_nvm(struct ioh_gbe_hw *hw, | ||
907 | + * u32 offset, u8 *data) | ||
908 | + * @brief Writes to NVM (EEPROM) | ||
909 | + */ | ||
910 | +s32 ioh_gbe_hal_write_nvm(struct ioh_gbe_hw *hw, u32 offset, u8 *data); | ||
911 | +#endif /* CONFIG_PCH_PCIEQOS */ | ||
912 | + | ||
913 | +/*! | ||
914 | + * @ingroup HAL API Layer | ||
915 | + * @fn void ioh_gbe_hal_set_wol_event(struct ioh_gbe_hw *hw, u32 wu_evt) | ||
916 | + * @brief Set wake-on-lan event | ||
917 | + */ | ||
918 | +void ioh_gbe_hal_set_wol_event(struct ioh_gbe_hw *hw, u32 wu_evt); | ||
919 | + | ||
920 | +/*! | ||
921 | + * @ingroup HAL API Layer | ||
922 | + * @fn void ioh_gbe_hal_power_up_phy(struct ioh_gbe_hw *hw) | ||
923 | + * @brief Power up PHY | ||
924 | + */ | ||
925 | +void ioh_gbe_hal_power_up_phy(struct ioh_gbe_hw *hw); | ||
926 | + | ||
927 | +/*! | ||
928 | + * @ingroup HAL API Layer | ||
929 | + * @fn void ioh_gbe_hal_power_down_phy(struct ioh_gbe_hw *hw) | ||
930 | + * @brief Power down PHY | ||
931 | + */ | ||
932 | +void ioh_gbe_hal_power_down_phy(struct ioh_gbe_hw *hw); | ||
933 | + | ||
934 | +/*! | ||
935 | + * @ingroup HAL API Layer | ||
936 | + * @fn u16 ioh_gbe_hal_ctrl_miim(struct ioh_gbe_hw *hw, | ||
937 | + * u32 addr, u32 dir, u32 reg, u16 data) | ||
938 | + * @brief Control MII Management IF | ||
939 | + */ | ||
940 | +u16 ioh_gbe_hal_ctrl_miim(struct ioh_gbe_hw *hw, u32 addr, u32 dir, u32 reg, | ||
941 | + u16 data); | ||
942 | + | ||
943 | +/*! | ||
944 | + * @ingroup HAL API Layer | ||
945 | + * @fn void ioh_gbe_hal_set_pause_packet(struct ioh_gbe_hw *hw) | ||
946 | + * @brief Set pause packet | ||
947 | + */ | ||
948 | +void ioh_gbe_hal_set_pause_packet(struct ioh_gbe_hw *hw); | ||
949 | + | ||
950 | +/*! | ||
951 | + * @ingroup HAL API Layer | ||
952 | + * @def IOH_GBE_HAL_MIIM_READ | ||
953 | + * @brief Read operation is done through MII Management IF | ||
954 | + */ | ||
955 | +#define IOH_GBE_HAL_MIIM_READ ((u32)0x00000000) | ||
956 | + | ||
957 | +/*! | ||
958 | + * @ingroup HAL API Layer | ||
959 | + * @def IOH_GBE_HAL_MIIM_WRITE | ||
960 | + * @brief Write operation is done through MII Management IF | ||
961 | + */ | ||
962 | +#define IOH_GBE_HAL_MIIM_WRITE ((u32)0x04000000) | ||
963 | + | ||
964 | +/* pch_gbe_plat.c */ | ||
965 | +/*! | ||
966 | + * @ingroup HAL internal functions | ||
967 | + * @fn void ioh_gbe_plat_init_function_pointers(struct ioh_gbe_hw *hw) | ||
968 | + * @brief Init func ptrs. | ||
969 | + */ | ||
970 | +void ioh_gbe_plat_init_function_pointers(struct ioh_gbe_hw *hw); | ||
971 | + | ||
972 | +#endif | ||
973 | diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_defines.h topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_defines.h | ||
974 | --- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_defines.h 1970-01-01 09:00:00.000000000 +0900 | ||
975 | +++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_defines.h 2010-03-09 09:27:26.000000000 +0900 | ||
976 | @@ -0,0 +1,367 @@ | ||
977 | +/*! | ||
978 | + * @file ioh_gbe_defines.h | ||
979 | + * @brief Linux IOH Gigabit Ethernet Driver defines macro header file | ||
980 | + * | ||
981 | + * @version 0.90 | ||
982 | + * | ||
983 | + * @section | ||
984 | + * This program is free software; you can redistribute it and/or modify | ||
985 | + * it under the terms of the GNU General Public License as published by | ||
986 | + * the Free Software Foundation; version 2 of the License. | ||
987 | + * | ||
988 | + * This program is distributed in the hope that it will be useful, | ||
989 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
990 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
991 | + * GNU General Public License for more details. | ||
992 | + * | ||
993 | + * You should have received a copy of the GNU General Public License | ||
994 | + * along with this program; if not, write to the Free Software | ||
995 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
996 | + */ | ||
997 | + | ||
998 | +/* | ||
999 | + * History: | ||
1000 | + * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD. | ||
1001 | + * All rights reserved. | ||
1002 | + * | ||
1003 | + * created: | ||
1004 | + * OKI SEMICONDUCTOR 09/21/2009 | ||
1005 | + * modified: | ||
1006 | + * | ||
1007 | + */ | ||
1008 | +#ifndef _IOH_GBE_DEFINES_H_ | ||
1009 | +#define _IOH_GBE_DEFINES_H_ | ||
1010 | + | ||
1011 | +#include "pch_gbe_pci_ids.h" /* Pci vender/device ID */ | ||
1012 | + | ||
1013 | +/* DEBUG OPTION */ | ||
1014 | +/* #define DEBUG_TEST */ | ||
1015 | +/* #define NVM_MAC_FIX *//* MAC: 00 21 97 77 65 13 */ | ||
1016 | +/* #define NVM_DUMMY_READ */ | ||
1017 | +#define PHY_RESET_REG_INIT | ||
1018 | + | ||
1019 | +#ifdef DEBUG_TEST | ||
1020 | +#define IOH_GBE_NETIF_MSG_DEFAULT 0x7fff /* ALL Enable */ | ||
1021 | +#else | ||
1022 | +#define IOH_GBE_NETIF_MSG_DEFAULT 0x0000 /* All Disable */ | ||
1023 | +#endif | ||
1024 | +/*-- Kind of Messege -------------------------- | ||
1025 | + NETIF_MSG_DRV = 0x0001, | ||
1026 | + NETIF_MSG_PROBE = 0x0002, | ||
1027 | + NETIF_MSG_LINK = 0x0004, | ||
1028 | + NETIF_MSG_TIMER = 0x0008, | ||
1029 | + NETIF_MSG_IFDOWN = 0x0010, | ||
1030 | + NETIF_MSG_IFUP = 0x0020, | ||
1031 | + NETIF_MSG_RX_ERR = 0x0040, | ||
1032 | + NETIF_MSG_TX_ERR = 0x0080, | ||
1033 | + NETIF_MSG_TX_QUEUED = 0x0100, | ||
1034 | + NETIF_MSG_INTR = 0x0200, | ||
1035 | + NETIF_MSG_TX_DONE = 0x0400, | ||
1036 | + NETIF_MSG_RX_STATUS = 0x0800, | ||
1037 | + NETIF_MSG_PKTDATA = 0x1000, | ||
1038 | + NETIF_MSG_HW = 0x2000, | ||
1039 | + NETIF_MSG_WOL = 0x4000, | ||
1040 | +-----------------------------------------------*/ | ||
1041 | + | ||
1042 | +#ifdef DEBUG_TEST | ||
1043 | +#define IOH_GBE_ERR(args...) printk(KERN_ERR DRV_NAME": " args) | ||
1044 | +#define IOH_GBE_DBGOUT(S) printk(KERN_INFO S) | ||
1045 | +/* #define IOH_GBE_DBGOUT1(S, A...) printk(KERN_INFO S, A) */ | ||
1046 | +#define IOH_GBE_DBGOUT1(S, A...) | ||
1047 | +/* #define IOH_GBE_DBGOUT2(S) IOH_GBE_DBGOUT(S) */ | ||
1048 | +#define IOH_GBE_DBGOUT2(S, A...) | ||
1049 | +#define IOH_GBE_TESTOUT(S, A...) printk(KERN_INFO " TEST_OUT:"S, A) | ||
1050 | +/* #define IOH_GBE_TESTOUT2(S, A...) printk(KERN_INFO " TEST_OUT:"S, A) */ | ||
1051 | +#define IOH_GBE_TESTOUT2(S, A...) | ||
1052 | +#define IOH_GBE_DBGFUNC(F) (IOH_GBE_DBGOUT(F "\n")) | ||
1053 | +#else | ||
1054 | +#define IOH_GBE_ERR(args...) printk(KERN_ERR DRV_NAME": " args) | ||
1055 | +#define IOH_GBE_DBGOUT(S) | ||
1056 | +#define IOH_GBE_DBGOUT1(S, A...) | ||
1057 | +#define IOH_GBE_DBGOUT2(S, A...) | ||
1058 | +#define IOH_GBE_TESTOUT(S, A...) | ||
1059 | +#define IOH_GBE_TESTOUT2(S, A...) | ||
1060 | +#define IOH_GBE_DBGFUNC(F) | ||
1061 | +#endif | ||
1062 | + | ||
1063 | +/* IF OPTION */ | ||
1064 | +#define IOH_GBE_MAC_IFOP_RGMII | ||
1065 | +#define IOH_GBE_MAC_RGMII_CTRL_SETTING ( \ | ||
1066 | + IOH_GBE_CHIP_TYPE_INTERNAL | \ | ||
1067 | + IOH_GBE_RGMII_MODE_RGMII | \ | ||
1068 | + IOH_GBE_CRS_SEL \ | ||
1069 | + ) | ||
1070 | + | ||
1071 | +/* TX/RX descriptor defines */ | ||
1072 | +#define IOH_GBE_DEFAULT_TXD 256 | ||
1073 | +#define IOH_GBE_MAX_TXD 4096 | ||
1074 | +#define IOH_GBE_MIN_TXD 8 | ||
1075 | +#define IOH_GBE_DEFAULT_RXD 256 | ||
1076 | +#define IOH_GBE_MAX_RXD 4096 | ||
1077 | +#define IOH_GBE_MIN_RXD 8 | ||
1078 | +/* Number of Transmit and Receive Descriptors must be a multiple of 8 */ | ||
1079 | +#define IOH_GBE_TX_DESC_MULTIPLE 8 | ||
1080 | +#define IOH_GBE_RX_DESC_MULTIPLE 8 | ||
1081 | + | ||
1082 | +/* Checksum Offload defines Enable/Disable */ | ||
1083 | +#define IOH_GBE_DEFAULT_RX_CSUM TRUE /* TRUEorFALSE */ | ||
1084 | +#define IOH_GBE_DEFAULT_TX_CSUM TRUE /* TRUEorFALSE */ | ||
1085 | + | ||
1086 | +/* Copybreak default */ | ||
1087 | +#define IOH_GBE_COPYBREAK_DEFAULT 256 | ||
1088 | +#define IOH_GBE_PCI_BAR 1 | ||
1089 | + | ||
1090 | +/* Device Driver infomation */ | ||
1091 | +#define DRV_NAME "ioh_gbe" | ||
1092 | +#define DRV_STRING "IOH Network Driver" | ||
1093 | +#define DRV_EXT "-NAPI" | ||
1094 | +#define DRV_VERSION "0.91"DRV_EXT | ||
1095 | +#define DRV_DESCRIPTION \ | ||
1096 | + "OKI semiconductor sample Linux driver for IOH Gigabit ethernet" | ||
1097 | +#define DRV_COPYRIGHT "Copyright(c) 2009 OKI semiconductor" | ||
1098 | +#define FIRM_VERSION "N/A" | ||
1099 | + | ||
1100 | +#define IOH_GBE_MAC_REGS_LEN 76 | ||
1101 | +#define IOH_GBE_PHY_REGS_LEN 32 | ||
1102 | +#define IOH_GBE_REGS_LEN (IOH_GBE_MAC_REGS_LEN + IOH_GBE_PHY_REGS_LEN) | ||
1103 | + | ||
1104 | +/* #define IOH_GBE_DMA_ALIGN 48 */ | ||
1105 | +#define IOH_GBE_DMA_ALIGN (32) /*for 2.6.33-rc3 */ | ||
1106 | +#define IOH_GBE_ETH_ALEN 6 | ||
1107 | + | ||
1108 | +/* Initialize the wake-on-LAN settings */ | ||
1109 | +#define IOH_GBE_WL_INIT_SETTING ( \ | ||
1110 | + IOH_GBE_WLC_BR |\ | ||
1111 | + IOH_GBE_WLC_MLT |\ | ||
1112 | + IOH_GBE_WLC_IND |\ | ||
1113 | + IOH_GBE_WLC_MP \ | ||
1114 | + ) | ||
1115 | + | ||
1116 | +/* This defines the bits that are set in the Interrupt Mask | ||
1117 | + * Set/Read Register. Each bit is documented below: | ||
1118 | + * o RXT0 = Receiver Timer Interrupt (ring 0) | ||
1119 | + * o TXDW = Transmit Descriptor Written Back | ||
1120 | + * o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0) | ||
1121 | + * o RXSEQ = Receive Sequence Error | ||
1122 | + * o LSC = Link Status Change | ||
1123 | + */ | ||
1124 | +#define IOH_GBE_INT_ENABLE_MASK ( \ | ||
1125 | + IOH_GBE_INT_RX_DMA_CMPLT | \ | ||
1126 | + IOH_GBE_INT_RX_DSC_EMP | \ | ||
1127 | + IOH_GBE_INT_WOL_DET | \ | ||
1128 | + IOH_GBE_INT_TX_CMPLT \ | ||
1129 | + ) | ||
1130 | + | ||
1131 | +/* Ethertype field values */ | ||
1132 | +#define IOH_GBE_MAX_JUMBO_FRAME_SIZE (10318) | ||
1133 | +#define IOH_GBE_FRAME_SIZE_2048 (2048) | ||
1134 | +#define IOH_GBE_FRAME_SIZE_4096 (4096) | ||
1135 | +#define IOH_GBE_FRAME_SIZE_8192 (8192) | ||
1136 | + | ||
1137 | +/* watchdog time */ | ||
1138 | +#define IOH_GBE_WATCHDOG_PERIOD (1 * HZ) | ||
1139 | + | ||
1140 | +#define IOH_GBE_TX_WEIGHT 64 | ||
1141 | +#define IOH_GBE_RX_WEIGHT 64 | ||
1142 | +#define IOH_GBE_RX_BUFFER_WRITE 16 | ||
1143 | + | ||
1144 | +#define DSC_INIT16 0xC000 | ||
1145 | + | ||
1146 | +/* MAC Address */ | ||
1147 | +/* Number of high/low register pairs in the MAC_ADR. The MAC_ADR (MAC Address | ||
1148 | + * Registers) holds the directed and multicast addresses that we monitor. | ||
1149 | + * Technically, we have 16 spots. However, we reserve one of these spots | ||
1150 | + * (MAC_ADR[15]) for our directed address used by controllers with | ||
1151 | + * manageability enabled, allowing us room for 15 multicast addresses. | ||
1152 | + */ | ||
1153 | +#define IOH_GBE_MAR_ENTRIES 16 | ||
1154 | +#define IOH_GBE_SHORT_PKT 64 | ||
1155 | + | ||
1156 | +/* PHY param */ | ||
1157 | +#define IOH_GBE_PHY_RESET_DELAY_US 10 | ||
1158 | +/* NVM param */ | ||
1159 | +#define IOH_GBE_NVM_WORD_SIZE 3 /* 16bit word size */ | ||
1160 | + | ||
1161 | +/* Error Codes */ | ||
1162 | +#define IOH_GBE_SUCCESS 0 | ||
1163 | +#define IOH_GBE_ERR_NVM 1 | ||
1164 | +#define IOH_GBE_ERR_PHY 2 | ||
1165 | +#define IOH_GBE_ERR_CONFIG 3 | ||
1166 | +#define IOH_GBE_ERR_PARAM 4 | ||
1167 | +#define IOH_GBE_ERR_MAC_INIT 5 | ||
1168 | +#define IOH_GBE_ERR_PHY_TYPE 6 | ||
1169 | +#define IOH_GBE_ERR_RESET 9 | ||
1170 | +#define IOH_GBE_ERR_MASTER_REQUESTS_PENDING 10 | ||
1171 | +#define IOH_GBE_ERR_HOST_INTERFACE_COMMAND 11 | ||
1172 | +#define IOH_GBE_BLK_PHY_RESET 12 | ||
1173 | +#define IOH_GBE_ERR_SWFW_SYNC 13 | ||
1174 | +#define IOH_GBE_NOT_IMPLEMENTED 14 | ||
1175 | + | ||
1176 | +#define PHY_MAX_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ | ||
1177 | +/* PHY 1000 MII Register/Bit Definitions */ | ||
1178 | +/* PHY Registers defined by IEEE */ | ||
1179 | +#define PHY_CONTROL 0x00 /* Control Register */ | ||
1180 | +#define PHY_STATUS 0x01 /* Status Regiser */ | ||
1181 | +#define PHY_ID1 0x02 /* Phy Id Register (word 1) */ | ||
1182 | +#define PHY_ID2 0x03 /* Phy Id Register (word 2) */ | ||
1183 | +#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */ | ||
1184 | +#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */ | ||
1185 | +#define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Register */ | ||
1186 | +#define PHY_NEXT_PAGE_TX 0x07 /* Next Page TX */ | ||
1187 | +#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */ | ||
1188 | +#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Register */ | ||
1189 | +#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Register */ | ||
1190 | +#define PHY_EXT_STATUS 0x0F /* Extended Status Register */ | ||
1191 | +#define PHY_PHYSP_CONTROL 0x10 /* PHY Specific Control Register */ | ||
1192 | +#define PHY_EXT_PHYSP_CONTROL 0x14 /* Extended PHY Specific Control Register */ | ||
1193 | +#define PHY_LED_CONTROL 0x18 /* LED Control Register */ | ||
1194 | +#define PHY_EXT_PHYSP_STATUS 0x1B /* Extended PHY Specific Status Register */ | ||
1195 | + | ||
1196 | +/* PHY Control Register */ | ||
1197 | +#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */ | ||
1198 | +#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */ | ||
1199 | +#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ | ||
1200 | +#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ | ||
1201 | +#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */ | ||
1202 | +#define MII_CR_POWER_DOWN 0x0800 /* Power down */ | ||
1203 | +#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */ | ||
1204 | +#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */ | ||
1205 | +#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ | ||
1206 | +#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ | ||
1207 | +#define MII_CR_SPEED_1000 0x0040 | ||
1208 | +#define MII_CR_SPEED_100 0x2000 | ||
1209 | +#define MII_CR_SPEED_10 0x0000 | ||
1210 | + | ||
1211 | +/* PHY Status Register */ | ||
1212 | +#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */ | ||
1213 | +#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */ | ||
1214 | +#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */ | ||
1215 | +#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */ | ||
1216 | +#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */ | ||
1217 | +#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ | ||
1218 | +#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */ | ||
1219 | +#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */ | ||
1220 | +#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */ | ||
1221 | +#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */ | ||
1222 | +#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */ | ||
1223 | +#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */ | ||
1224 | +#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */ | ||
1225 | +#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */ | ||
1226 | +#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */ | ||
1227 | + | ||
1228 | +/* Phy Id Register (word 2) */ | ||
1229 | +#define PHY_REVISION_MASK 0x000F | ||
1230 | + | ||
1231 | +/* Autoneg Advertisement Register */ | ||
1232 | +#define NWAY_AR_SELECTOR_FIELD 0x0001 /* indicates IEEE 802.3 CSMA/CD */ | ||
1233 | +#define NWAY_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */ | ||
1234 | +#define NWAY_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */ | ||
1235 | +#define NWAY_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */ | ||
1236 | +#define NWAY_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */ | ||
1237 | +#define NWAY_AR_100T4_CAPS 0x0200 /* 100T4 Capable */ | ||
1238 | +#define NWAY_AR_PAUSE 0x0400 /* Pause operation desired */ | ||
1239 | +#define NWAY_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */ | ||
1240 | +#define NWAY_AR_REMOTE_FAULT 0x2000 /* Remote Fault detected */ | ||
1241 | +#define NWAY_AR_NEXT_PAGE 0x8000 /* Next Page ability supported */ | ||
1242 | + | ||
1243 | +/* Link Partner Ability Register (Base Page) */ | ||
1244 | +#define NWAY_LPAR_SELECTOR_FIELD 0x0000 /* LP protocol selector field */ | ||
1245 | +#define NWAY_LPAR_10T_HD_CAPS 0x0020 /* LP is 10T Half Duplex Capable */ | ||
1246 | +#define NWAY_LPAR_10T_FD_CAPS 0x0040 /* LP is 10T Full Duplex Capable */ | ||
1247 | +#define NWAY_LPAR_100TX_HD_CAPS 0x0080 /* LP is 100TX Half Duplex Capable */ | ||
1248 | +#define NWAY_LPAR_100TX_FD_CAPS 0x0100 /* LP is 100TX Full Duplex Capable */ | ||
1249 | +#define NWAY_LPAR_100T4_CAPS 0x0200 /* LP is 100T4 Capable */ | ||
1250 | +#define NWAY_LPAR_PAUSE 0x0400 /* LP Pause operation desired */ | ||
1251 | +#define NWAY_LPAR_ASM_DIR 0x0800 /* LP Asymmetric Pause Direction bit */ | ||
1252 | +#define NWAY_LPAR_REMOTE_FAULT 0x2000 /* LP has detected Remote Fault */ | ||
1253 | +#define NWAY_LPAR_ACKNOWLEDGE 0x4000 /* LP has rx'd link code word */ | ||
1254 | +#define NWAY_LPAR_NEXT_PAGE 0x8000 /* Next Page ability supported */ | ||
1255 | + | ||
1256 | +/* Autoneg Expansion Register */ | ||
1257 | +#define NWAY_ER_LP_NWAY_CAPS 0x0001 /* LP has Auto Neg Capability */ | ||
1258 | +#define NWAY_ER_PAGE_RXD 0x0002 /* LP is 10T Half Duplex Capable */ | ||
1259 | +#define NWAY_ER_NEXT_PAGE_CAPS 0x0004 /* LP is 10T Full Duplex Capable */ | ||
1260 | +#define NWAY_ER_LP_NEXT_PAGE_CAPS 0x0008 /* LP is 100TX Half Duplex Capable */ | ||
1261 | +#define NWAY_ER_PAR_DETECT_FAULT 0x0010 /* LP is 100TX Full Duplex Capable */ | ||
1262 | + | ||
1263 | +/* 1000BASE-T Control Register */ | ||
1264 | +#define CR_1000T_ASYM_PAUSE 0x0080 /* Advertise asymmetric pause bit */ | ||
1265 | +#define CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */ | ||
1266 | +#define CR_1000T_FD_CAPS 0x0200 /* Advertise 1000T FD capability */ | ||
1267 | +#define CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port */ | ||
1268 | + /* 0=DTE device */ | ||
1269 | +#define CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master */ | ||
1270 | + /* 0=Configure PHY as Slave */ | ||
1271 | +#define CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value */ | ||
1272 | + /* 0=Automatic Master/Slave config */ | ||
1273 | +#define CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */ | ||
1274 | +#define CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */ | ||
1275 | +#define CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */ | ||
1276 | +#define CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */ | ||
1277 | +#define CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */ | ||
1278 | + | ||
1279 | +/* 1000BASE-T Status Register */ | ||
1280 | +#define SR_1000T_IDLE_ERROR_CNT 0x00FF /* Num idle errors since last read */ | ||
1281 | +#define SR_1000T_ASYM_PAUSE_DIR 0x0100 /* LP asymmetric pause direction bit */ | ||
1282 | +#define SR_1000T_LP_HD_CAPS 0x0400 /* LP is 1000T HD capable */ | ||
1283 | +#define SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */ | ||
1284 | +#define SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */ | ||
1285 | +#define SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */ | ||
1286 | +#define SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local TX is Master, 0=Slave */ | ||
1287 | +#define SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */ | ||
1288 | + | ||
1289 | +/* PHY Specific Control Register */ | ||
1290 | +#define PHYSP_CTRL_ASSERT_CRS_TX 0x0800 | ||
1291 | + | ||
1292 | +/* LED Control Register */ | ||
1293 | +#define PHY_LED_CTRL_ON 0x4103 | ||
1294 | +#define PHY_LED_CTRL_OFF 0x4102 | ||
1295 | +#define PHY_LED_CTRL_CLEANUP 0x4100 | ||
1296 | + | ||
1297 | +/* Extended PHY Specific Status Register */ | ||
1298 | +#define HWCFG_MODE_GMII_COPPER 0x000F /* GMII to Copper */ | ||
1299 | +#define HWCFG_MODE_RGMII_COPPER 0x000B /* RGMII/Modiffied MII to Copper */ | ||
1300 | +#define HWCFG_MODE_GMII_FIBER 0x0007 /* GMII to Fiber */ | ||
1301 | +#define HWCFG_MODE_RGMII_FIBER 0x0003 /* RGMII to Fiber */ | ||
1302 | +#define HWCFG_MODE_GMII_SGMII 0x000E /* GMII to SGMII */ | ||
1303 | +#define HWCFG_MODE_RGMII_SGMII 0x0006 /* RGMII to SGMII */ | ||
1304 | +#define HWCFG_MODE_TBI_COPPER 0x000D /* TBI to Copper */ | ||
1305 | +#define HWCFG_MODE_RTBI_COPPER 0x0009 /* RTBI to Copper */ | ||
1306 | +#define HWCFG_MODE_MASK 0x000F | ||
1307 | + | ||
1308 | +#define PHY_SPEED_10 10 | ||
1309 | +#define PHY_SPEED_100 100 | ||
1310 | +#define PHY_SPEED_1000 1000 | ||
1311 | +#define PHY_HALF_DUPLEX 1 | ||
1312 | +#define PHY_FULL_DUPLEX 2 | ||
1313 | + | ||
1314 | +#define PHY_ADVERTISE_10_HALF 0x0001 | ||
1315 | +#define PHY_ADVERTISE_10_FULL 0x0002 | ||
1316 | +#define PHY_ADVERTISE_100_HALF 0x0004 | ||
1317 | +#define PHY_ADVERTISE_100_FULL 0x0008 | ||
1318 | +#define PHY_ADVERTISE_1000_HALF 0x0010 /* Not used, just FYI */ | ||
1319 | +#define PHY_ADVERTISE_1000_FULL 0x0020 | ||
1320 | + | ||
1321 | +/* 1000/H is not supported, nor spec-compliant. */ | ||
1322 | +#define IOH_GBE_ALL_SPEED_DUPLEX (PHY_ADVERTISE_10_HALF | \ | ||
1323 | + PHY_ADVERTISE_10_FULL | \ | ||
1324 | + PHY_ADVERTISE_100_HALF | \ | ||
1325 | + PHY_ADVERTISE_100_FULL | \ | ||
1326 | + PHY_ADVERTISE_1000_FULL) | ||
1327 | +#define IOH_GBE_ALL_NOT_GIG (PHY_ADVERTISE_10_HALF | \ | ||
1328 | + PHY_ADVERTISE_10_FULL | \ | ||
1329 | + PHY_ADVERTISE_100_HALF | \ | ||
1330 | + PHY_ADVERTISE_100_FULL) | ||
1331 | +#define IOH_GBE_ALL_100_SPEED (PHY_ADVERTISE_100_HALF | \ | ||
1332 | + PHY_ADVERTISE_100_FULL) | ||
1333 | +#define IOH_GBE_ALL_10_SPEED (PHY_ADVERTISE_10_HALF | \ | ||
1334 | + PHY_ADVERTISE_10_FULL) | ||
1335 | +#define IOH_GBE_ALL_FULL_DUPLEX (PHY_ADVERTISE_10_FULL | \ | ||
1336 | + PHY_ADVERTISE_100_FULL | \ | ||
1337 | + PHY_ADVERTISE_1000_FULL) | ||
1338 | +#define IOH_GBE_ALL_HALF_DUPLEX (PHY_ADVERTISE_10_HALF | \ | ||
1339 | + PHY_ADVERTISE_100_HALF) | ||
1340 | + | ||
1341 | +#define AUTONEG_ADVERTISE_SPEED_DEFAULT IOH_GBE_ALL_SPEED_DUPLEX | ||
1342 | + | ||
1343 | +#endif | ||
1344 | diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_ethtool.c topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_ethtool.c | ||
1345 | --- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_ethtool.c 1970-01-01 09:00:00.000000000 +0900 | ||
1346 | +++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_ethtool.c 2010-03-11 15:12:31.000000000 +0900 | ||
1347 | @@ -0,0 +1,1306 @@ | ||
1348 | +/*! | ||
1349 | + * @file ioh_gbe_ethtool.c | ||
1350 | + * @brief Linux IOH Gigabit Ethernet Ethtool Driver source file | ||
1351 | + * | ||
1352 | + * @version 0.90 | ||
1353 | + * | ||
1354 | + * @section | ||
1355 | + * This program is free software; you can redistribute it and/or modify | ||
1356 | + * it under the terms of the GNU General Public License as published by | ||
1357 | + * the Free Software Foundation; version 2 of the License. | ||
1358 | + * | ||
1359 | + * This program is distributed in the hope that it will be useful, | ||
1360 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1361 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1362 | + * GNU General Public License for more details. | ||
1363 | + * | ||
1364 | + * You should have received a copy of the GNU General Public License | ||
1365 | + * along with this program; if not, write to the Free Software | ||
1366 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
1367 | + */ | ||
1368 | + | ||
1369 | +/* | ||
1370 | + * History: | ||
1371 | + * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD. | ||
1372 | + * All rights reserved. | ||
1373 | + * | ||
1374 | + * created: | ||
1375 | + * OKI SEMICONDUCTOR 09/21/2009 | ||
1376 | + * modified: | ||
1377 | + * | ||
1378 | + */ | ||
1379 | + | ||
1380 | +#include <linux/pci.h> | ||
1381 | +#include <linux/netdevice.h> | ||
1382 | +#include <linux/ethtool.h> | ||
1383 | +#include <linux/mii.h> | ||
1384 | +#include <linux/sched.h> | ||
1385 | +#include <linux/uaccess.h> | ||
1386 | + | ||
1387 | +#include "pch_gbe_osdep.h" | ||
1388 | +#include "pch_gbe_regs.h" | ||
1389 | +#include "pch_gbe_defines.h" | ||
1390 | +#include "pch_gbe_hw.h" | ||
1391 | +#include "pch_gbe_api.h" | ||
1392 | +#include "pch_gbe.h" | ||
1393 | + | ||
1394 | + | ||
1395 | +/* ---------------------------------------------------------------------------- | ||
1396 | + Function prototype | ||
1397 | +---------------------------------------------------------------------------- */ | ||
1398 | +static int ioh_gbe_get_settings(struct net_device *netdev, | ||
1399 | + struct ethtool_cmd *ecmd); | ||
1400 | +static int ioh_gbe_set_settings(struct net_device *netdev, | ||
1401 | + struct ethtool_cmd *ecmd); | ||
1402 | +static void ioh_gbe_get_drvinfo(struct net_device *netdev, | ||
1403 | + struct ethtool_drvinfo *drvinfo); | ||
1404 | +static int ioh_gbe_get_regs_len(struct net_device *netdev); | ||
1405 | +static void ioh_gbe_get_regs(struct net_device *netdev, | ||
1406 | + struct ethtool_regs *regs, void *p); | ||
1407 | +static void ioh_gbe_get_wol(struct net_device *netdev, | ||
1408 | + struct ethtool_wolinfo *wol); | ||
1409 | +static int ioh_gbe_set_wol(struct net_device *netdev, | ||
1410 | + struct ethtool_wolinfo *wol); | ||
1411 | +static u32 ioh_gbe_get_msglevel(struct net_device *netdev); | ||
1412 | +static void ioh_gbe_set_msglevel(struct net_device *netdev, u32 data); | ||
1413 | +static int ioh_gbe_nway_reset(struct net_device *netdev); | ||
1414 | +#ifdef CONFIG_PCH_PCIEQOS | ||
1415 | +static int ioh_gbe_get_eeprom_len(struct net_device *netdev); | ||
1416 | +static int ioh_gbe_get_eeprom(struct net_device *netdev, | ||
1417 | + struct ethtool_eeprom *eeprom, u8 *bytes); | ||
1418 | +static int ioh_gbe_set_eeprom(struct net_device *netdev, | ||
1419 | + struct ethtool_eeprom *eeprom, u8 *bytes); | ||
1420 | +#endif | ||
1421 | +static void ioh_gbe_get_ringparam(struct net_device *netdev, | ||
1422 | + struct ethtool_ringparam *ring); | ||
1423 | +static int ioh_gbe_set_ringparam(struct net_device *netdev, | ||
1424 | + struct ethtool_ringparam *ring); | ||
1425 | +static void ioh_gbe_get_pauseparam(struct net_device *netdev, | ||
1426 | + struct ethtool_pauseparam *pause); | ||
1427 | +static int ioh_gbe_set_pauseparam(struct net_device *netdev, | ||
1428 | + struct ethtool_pauseparam *pause); | ||
1429 | +static u32 ioh_gbe_get_rx_csum(struct net_device *netdev); | ||
1430 | +static int ioh_gbe_set_rx_csum(struct net_device *netdev, u32 data); | ||
1431 | +static u32 ioh_gbe_get_tx_csum(struct net_device *netdev); | ||
1432 | +static int ioh_gbe_set_tx_csum(struct net_device *netdev, u32 data); | ||
1433 | +static void ioh_gbe_diag_test(struct net_device *netdev, | ||
1434 | + struct ethtool_test *eth_test, u64 *data); | ||
1435 | +static void ioh_gbe_get_strings(struct net_device *netdev, | ||
1436 | + u32 stringset, u8 *data); | ||
1437 | +static void ioh_gbe_led_blink_callback(unsigned long data); | ||
1438 | +static int ioh_gbe_phys_id(struct net_device *netdev, u32 data); | ||
1439 | +static void ioh_gbe_get_ethtool_stats(struct net_device *netdev, | ||
1440 | + struct ethtool_stats *stats, u64 *data); | ||
1441 | +static int ioh_gbe_reg_test(struct ioh_gbe_adapter *adapter, uint64_t *data); | ||
1442 | +static bool reg_pattern_test(struct ioh_gbe_adapter *adapter, uint64_t *data, | ||
1443 | + int reg, uint32_t mask, uint32_t write); | ||
1444 | + | ||
1445 | +/* ---------------------------------------------------------------------------- | ||
1446 | + Data | ||
1447 | +---------------------------------------------------------------------------- */ | ||
1448 | +/*! | ||
1449 | + * @ingroup Ethtool driver Layer | ||
1450 | + * @struct ioh_gbe_stats | ||
1451 | + * @brief Stats item infomation | ||
1452 | + */ | ||
1453 | +struct ioh_gbe_stats { | ||
1454 | + signed char stat_string[ETH_GSTRING_LEN]; | ||
1455 | + int sizeof_stat; | ||
1456 | + int stat_offset; | ||
1457 | +}; | ||
1458 | + | ||
1459 | +#define IOH_GBE_STAT1(m) (int)(sizeof(((struct ioh_gbe_adapter *)0)->m)) | ||
1460 | +#define IOH_GBE_STAT2(m) offsetof(struct ioh_gbe_adapter, m) | ||
1461 | + | ||
1462 | +/*! | ||
1463 | + * @ingroup Ethtool driver Layer | ||
1464 | + * @struct ioh_gbe_gstrings_stats | ||
1465 | + * @brief ethtool information status name list | ||
1466 | + */ | ||
1467 | +static const struct ioh_gbe_stats ioh_gbe_gstrings_stats[] = { | ||
1468 | + {"rx_packets", IOH_GBE_STAT1(stats.rx_packets), | ||
1469 | + IOH_GBE_STAT2(stats.rx_packets)}, | ||
1470 | + {"tx_packets", IOH_GBE_STAT1(stats.tx_packets), | ||
1471 | + IOH_GBE_STAT2(stats.tx_packets)}, | ||
1472 | + {"rx_bytes", IOH_GBE_STAT1(stats.rx_bytes), | ||
1473 | + IOH_GBE_STAT2(stats.rx_bytes)}, | ||
1474 | + {"tx_bytes", IOH_GBE_STAT1(stats.tx_bytes), | ||
1475 | + IOH_GBE_STAT2(stats.tx_bytes)}, | ||
1476 | + {"rx_errors", IOH_GBE_STAT1(stats.rx_errors), | ||
1477 | + IOH_GBE_STAT2(stats.rx_errors)}, | ||
1478 | + {"tx_errors", IOH_GBE_STAT1(stats.tx_errors), | ||
1479 | + IOH_GBE_STAT2(stats.tx_errors)}, | ||
1480 | + {"rx_dropped", IOH_GBE_STAT1(stats.rx_dropped), | ||
1481 | + IOH_GBE_STAT2(stats.rx_dropped)}, | ||
1482 | + {"tx_dropped", IOH_GBE_STAT1(stats.tx_dropped), | ||
1483 | + IOH_GBE_STAT2(stats.tx_dropped)}, | ||
1484 | + {"multicast", IOH_GBE_STAT1(stats.multicast), | ||
1485 | + IOH_GBE_STAT2(stats.multicast)}, | ||
1486 | + {"collisions", IOH_GBE_STAT1(stats.collisions), | ||
1487 | + IOH_GBE_STAT2(stats.collisions)}, | ||
1488 | + {"rx_crc_errors", IOH_GBE_STAT1(stats.rx_crc_errors), | ||
1489 | + IOH_GBE_STAT2(stats.rx_crc_errors)}, | ||
1490 | + {"rx_frame_errors", IOH_GBE_STAT1(stats.rx_frame_errors), | ||
1491 | + IOH_GBE_STAT2(stats.rx_frame_errors)}, | ||
1492 | + {"rx_buff_failed", IOH_GBE_STAT1(stats.rx_alloc_buff_failed), | ||
1493 | + IOH_GBE_STAT2(stats.rx_alloc_buff_failed)}, | ||
1494 | + {"tx_length_errors", IOH_GBE_STAT1(stats.tx_length_errors), | ||
1495 | + IOH_GBE_STAT2(stats.tx_length_errors)}, | ||
1496 | + {"tx_aborted_errors", IOH_GBE_STAT1(stats.tx_aborted_errors), | ||
1497 | + IOH_GBE_STAT2(stats.tx_aborted_errors)}, | ||
1498 | + {"tx_carrier_errors", IOH_GBE_STAT1(stats.tx_carrier_errors), | ||
1499 | + IOH_GBE_STAT2(stats.tx_carrier_errors)}, | ||
1500 | + {"tx_timeout_count", IOH_GBE_STAT1(stats.tx_timeout_count), | ||
1501 | + IOH_GBE_STAT2(stats.tx_timeout_count)}, | ||
1502 | + {"tx_restart_count", IOH_GBE_STAT1(stats.tx_restart_count), | ||
1503 | + IOH_GBE_STAT2(stats.tx_restart_count)}, | ||
1504 | + {"intr_rx_dsc_empty_count", | ||
1505 | + IOH_GBE_STAT1(stats.intr_rx_dsc_empty_count), | ||
1506 | + IOH_GBE_STAT2(stats.intr_rx_dsc_empty_count)}, | ||
1507 | + {"intr_rx_frame_err_count", | ||
1508 | + IOH_GBE_STAT1(stats.intr_rx_frame_err_count), | ||
1509 | + IOH_GBE_STAT2(stats.intr_rx_frame_err_count)}, | ||
1510 | + {"intr_rx_fifo_err_count", IOH_GBE_STAT1(stats.intr_rx_fifo_err_count), | ||
1511 | + IOH_GBE_STAT2(stats.intr_rx_fifo_err_count)}, | ||
1512 | + {"intr_rx_dma_err_count", IOH_GBE_STAT1(stats.intr_rx_dma_err_count), | ||
1513 | + IOH_GBE_STAT2(stats.intr_rx_dma_err_count)}, | ||
1514 | + {"intr_tx_fifo_err_count", IOH_GBE_STAT1(stats.intr_tx_fifo_err_count), | ||
1515 | + IOH_GBE_STAT2(stats.intr_tx_fifo_err_count)}, | ||
1516 | + {"intr_tx_dma_err_count", IOH_GBE_STAT1(stats.intr_tx_dma_err_count), | ||
1517 | + IOH_GBE_STAT2(stats.intr_tx_dma_err_count)}, | ||
1518 | + {"intr_tcpip_err_count", IOH_GBE_STAT1(stats.intr_tcpip_err_count), | ||
1519 | + IOH_GBE_STAT2(stats.intr_tcpip_err_count)} | ||
1520 | +}; | ||
1521 | + | ||
1522 | +#define IOH_GBE_QUEUE_STATS_LEN 0 | ||
1523 | +#define IOH_GBE_GLOBAL_STATS_LEN \ | ||
1524 | +((int)sizeof(ioh_gbe_gstrings_stats) / (int)sizeof(struct ioh_gbe_stats)) | ||
1525 | + | ||
1526 | +/*! | ||
1527 | + * @ingroup Ethtool driver | ||
1528 | + * @def IOH_GBE_STATS_LEN | ||
1529 | + * @brief The size of status | ||
1530 | +*/ | ||
1531 | +#define IOH_GBE_STATS_LEN (IOH_GBE_GLOBAL_STATS_LEN + IOH_GBE_QUEUE_STATS_LEN) | ||
1532 | + | ||
1533 | +/*! | ||
1534 | + * @ingroup Ethtool driver Layer | ||
1535 | + * @struct ioh_gbe_gstrings_test | ||
1536 | + * @brief self test item name list | ||
1537 | + */ | ||
1538 | +static const signed char ioh_gbe_gstrings_test[][ETH_GSTRING_LEN] = { | ||
1539 | + "Register test (offline)" | ||
1540 | +}; | ||
1541 | + | ||
1542 | +/*! | ||
1543 | + * @ingroup Ethtool driver | ||
1544 | + * @def IOH_GBE_TEST_LEN | ||
1545 | + * @brief The size of test packet | ||
1546 | +*/ | ||
1547 | +#define IOH_GBE_TEST_LEN \ | ||
1548 | + ((int)sizeof(ioh_gbe_gstrings_test) / ETH_GSTRING_LEN) | ||
1549 | + | ||
1550 | +/*! | ||
1551 | + * @ingroup Ethtool driver | ||
1552 | + * @def IOH_GBE_ID_INTERVAL | ||
1553 | + * @brief Toggle LED 4 times per second = 2 "blinks" per second | ||
1554 | +*/ | ||
1555 | +#define IOH_GBE_ID_INTERVAL (HZ/4) | ||
1556 | + | ||
1557 | +/*! | ||
1558 | + * @ingroup Ethtool driver | ||
1559 | + * @def IOH_GBE_LED_ON | ||
1560 | + * @brief Bit defines for adapter->led_status | ||
1561 | +*/ | ||
1562 | +#define IOH_GBE_LED_ON 0 | ||
1563 | + | ||
1564 | +/* ---------------------------------------------------------------------------- | ||
1565 | + Function | ||
1566 | +---------------------------------------------------------------------------- */ | ||
1567 | +/*! | ||
1568 | + * @ingroup Ethtool driver | ||
1569 | + * @fn static int ioh_gbe_get_settings(struct net_device *netdev, | ||
1570 | + * struct ethtool_cmd *ecmd) | ||
1571 | + * @brief Get device-specific settings | ||
1572 | + * @param netdev [INOUT] Network interface device structure | ||
1573 | + * @param ecmd [INOUT] Ethtool command | ||
1574 | + * @return IOH_GBE_SUCCESS: Successfully | ||
1575 | + * @return Negative value: Failed | ||
1576 | + */ | ||
1577 | +static int | ||
1578 | +ioh_gbe_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | ||
1579 | +{ | ||
1580 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
1581 | + int ret; | ||
1582 | + | ||
1583 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_settings"); | ||
1584 | + | ||
1585 | + ret = mii_ethtool_gset(&adapter->mii, ecmd); | ||
1586 | + ecmd->supported &= (u32) (~SUPPORTED_TP); | ||
1587 | + ecmd->supported &= (u32) (~SUPPORTED_1000baseT_Half); | ||
1588 | + ecmd->advertising &= (u32) (~ADVERTISED_TP); | ||
1589 | + ecmd->advertising &= (u32) (~ADVERTISED_1000baseT_Half); | ||
1590 | + | ||
1591 | + if (netif_carrier_ok(adapter->netdev)) { | ||
1592 | + ; | ||
1593 | + } else { | ||
1594 | + ecmd->speed = 0xFFFF; | ||
1595 | + ecmd->duplex = 0xFF; | ||
1596 | + } | ||
1597 | + return ret; | ||
1598 | +} | ||
1599 | + | ||
1600 | +/*! | ||
1601 | + * @ingroup Ethtool driver | ||
1602 | + * @fn static int ioh_gbe_set_settings(struct net_device *netdev, | ||
1603 | + * struct ethtool_cmd *ecmd) | ||
1604 | + * @brief Set device-specific settings | ||
1605 | + * @param netdev [INOUT] Network interface device structure | ||
1606 | + * @param ecmd [INOUT] Ethtool command | ||
1607 | + * @return IOH_GBE_SUCCESS: Successfully | ||
1608 | + * @return Negative value: Failed | ||
1609 | + */ | ||
1610 | +static int | ||
1611 | +ioh_gbe_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | ||
1612 | +{ | ||
1613 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
1614 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
1615 | + int ret; | ||
1616 | + | ||
1617 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_set_settings"); | ||
1618 | + | ||
1619 | + while (test_and_set_bit(__IOH_GBE_RESETTING, &adapter->flags) != 0) | ||
1620 | + msleep(1); | ||
1621 | + ioh_gbe_hal_write_phy_reg(hw, MII_BMCR, BMCR_RESET); | ||
1622 | + | ||
1623 | + if (ecmd->speed == 0xFFFF) | ||
1624 | + ecmd->speed = SPEED_1000; | ||
1625 | + if (ecmd->duplex == 0xFF) | ||
1626 | + ecmd->duplex = DUPLEX_FULL; | ||
1627 | + ret = mii_ethtool_sset(&adapter->mii, ecmd); | ||
1628 | + if (ret != 0) { | ||
1629 | + IOH_GBE_ERR("Error: mii_ethtool_sset\n"); | ||
1630 | + clear_bit(__IOH_GBE_RESETTING, &adapter->flags); | ||
1631 | + return ret; | ||
1632 | + } | ||
1633 | + hw->mac.link_speed = ecmd->speed; | ||
1634 | + hw->mac.link_duplex = ecmd->duplex; | ||
1635 | + hw->phy.autoneg_advertised = ecmd->advertising; | ||
1636 | + hw->mac.autoneg = ecmd->autoneg; | ||
1637 | + ioh_gbe_hal_phy_sw_reset(hw); | ||
1638 | + | ||
1639 | + /* reset the link */ | ||
1640 | + if (netif_running(adapter->netdev) != 0) { | ||
1641 | + ioh_gbe_down(adapter); | ||
1642 | + ret = ioh_gbe_up(adapter); | ||
1643 | + } else { | ||
1644 | + ioh_gbe_reset(adapter); | ||
1645 | + } | ||
1646 | + | ||
1647 | + clear_bit(__IOH_GBE_RESETTING, &adapter->flags); | ||
1648 | + return ret; | ||
1649 | +} | ||
1650 | + | ||
1651 | +/*! | ||
1652 | + * @ingroup Ethtool driver | ||
1653 | + * @fn static void ioh_gbe_get_drvinfo(struct net_device *netdev, | ||
1654 | + * struct ethtool_drvinfo *drvinfo) | ||
1655 | + * @brief Report driver information | ||
1656 | + * @param netdev [INOUT] Network interface device structure | ||
1657 | + * @param drvinfo [INOUT] Driver information structure | ||
1658 | + * @return None | ||
1659 | + */ | ||
1660 | +static void | ||
1661 | +ioh_gbe_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) | ||
1662 | +{ | ||
1663 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
1664 | + | ||
1665 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_drvinfo"); | ||
1666 | + | ||
1667 | + strcpy(drvinfo->driver, DRV_NAME); | ||
1668 | + strcpy(drvinfo->version, DRV_VERSION); | ||
1669 | + strcpy(drvinfo->fw_version, FIRM_VERSION); | ||
1670 | + strcpy(drvinfo->bus_info, pci_name(adapter->pdev)); | ||
1671 | + | ||
1672 | + drvinfo->n_stats = IOH_GBE_STATS_LEN; | ||
1673 | + drvinfo->testinfo_len = IOH_GBE_TEST_LEN; | ||
1674 | + drvinfo->regdump_len = ioh_gbe_get_regs_len(netdev); | ||
1675 | +#ifdef CONFIG_PCH_PCIEQOS | ||
1676 | + drvinfo->eedump_len = ioh_gbe_get_eeprom_len(netdev); | ||
1677 | +#endif | ||
1678 | +} | ||
1679 | + | ||
1680 | +/*! | ||
1681 | + * @ingroup Ethtool driver | ||
1682 | + * @fn static int ioh_gbe_get_regs_len(struct net_device *netdev) | ||
1683 | + * @brief Report the size of device registers | ||
1684 | + * @param netdev [INOUT] Network interface device structure | ||
1685 | + * @return IOH_GBE_SUCCESS: Successfully | ||
1686 | + * @return Negative value: Failed | ||
1687 | + */ | ||
1688 | +static int ioh_gbe_get_regs_len(struct net_device *netdev) | ||
1689 | +{ | ||
1690 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_regs_len"); | ||
1691 | + | ||
1692 | + return IOH_GBE_REGS_LEN * (int)sizeof(u32); | ||
1693 | +} | ||
1694 | + | ||
1695 | +/*! | ||
1696 | + * @ingroup Ethtool driver | ||
1697 | + * @fn static void ioh_gbe_get_regs(struct net_device *netdev, | ||
1698 | + * struct ethtool_regs *regs, void *p) | ||
1699 | + * @brief Get device registers | ||
1700 | + * @param netdev [INOUT] Network interface device structure | ||
1701 | + * @param regs [INOUT] Ethtool register structure | ||
1702 | + * @param p [INOUT] Buffer pointer of read device register date | ||
1703 | + * @return None | ||
1704 | + */ | ||
1705 | +static void | ||
1706 | +ioh_gbe_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p) | ||
1707 | +{ | ||
1708 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
1709 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
1710 | + u32 *regs_buff = p; | ||
1711 | + u16 i, reg, tmp; | ||
1712 | + | ||
1713 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_regs"); | ||
1714 | + | ||
1715 | + regs->version = hw->revision_id; | ||
1716 | + regs->version = 0x1000000 | (regs->version << 16) | hw->device_id; | ||
1717 | + | ||
1718 | + memset(p, 0, IOH_GBE_REGS_LEN * (int)sizeof(u32)); | ||
1719 | + /* 000: */ | ||
1720 | + regs_buff[0] = IOH_GBE_READ_REG(hw, INT_ST); | ||
1721 | + regs_buff[1] = IOH_GBE_READ_REG(hw, INT_EN); | ||
1722 | + regs_buff[2] = IOH_GBE_READ_REG(hw, MODE); | ||
1723 | + regs_buff[3] = IOH_GBE_READ_REG(hw, RESET); | ||
1724 | + /* 010: */ | ||
1725 | + regs_buff[4] = IOH_GBE_READ_REG(hw, TCPIP_ACC); | ||
1726 | + regs_buff[5] = IOH_GBE_READ_REG(hw, EX_LIST); | ||
1727 | + regs_buff[6] = IOH_GBE_READ_REG(hw, INT_ST_HOLD); | ||
1728 | + regs_buff[7] = IOH_GBE_READ_REG(hw, PHY_INT_CTRL); | ||
1729 | + /* 020: */ | ||
1730 | + regs_buff[8] = IOH_GBE_READ_REG(hw, MAC_RX_EN); | ||
1731 | + regs_buff[9] = IOH_GBE_READ_REG(hw, RX_FCTRL); | ||
1732 | + regs_buff[10] = IOH_GBE_READ_REG(hw, PAUSE_REQ); | ||
1733 | + regs_buff[11] = IOH_GBE_READ_REG(hw, RX_MODE); | ||
1734 | + /* 030: */ | ||
1735 | + regs_buff[12] = IOH_GBE_READ_REG(hw, TX_MODE); | ||
1736 | + regs_buff[13] = IOH_GBE_READ_REG(hw, RX_FIFO_ST); | ||
1737 | + regs_buff[14] = IOH_GBE_READ_REG(hw, TX_FIFO_ST); | ||
1738 | + regs_buff[15] = IOH_GBE_READ_REG(hw, TX_FID); | ||
1739 | + /* 040: */ | ||
1740 | + regs_buff[16] = IOH_GBE_READ_REG(hw, TX_RESULT); | ||
1741 | + regs_buff[17] = IOH_GBE_READ_REG(hw, PAUSE_PKT1); | ||
1742 | + regs_buff[18] = IOH_GBE_READ_REG(hw, PAUSE_PKT2); | ||
1743 | + regs_buff[19] = IOH_GBE_READ_REG(hw, PAUSE_PKT3); | ||
1744 | + /* 050: */ | ||
1745 | + regs_buff[20] = IOH_GBE_READ_REG(hw, PAUSE_PKT4); | ||
1746 | + regs_buff[21] = IOH_GBE_READ_REG(hw, PAUSE_PKT5); | ||
1747 | + regs_buff[22] = IOH_GBE_READ_REG(hw, MAC_ADR); | ||
1748 | + regs_buff[23] = IOH_GBE_READ_REG(hw, MAC_ADR1A); | ||
1749 | + /* 060: */ | ||
1750 | + regs_buff[24] = IOH_GBE_READ_REG(hw, MAC_ADR1B); | ||
1751 | + regs_buff[25] = IOH_GBE_READ_REG(hw, MAC_ADR2A); | ||
1752 | + regs_buff[26] = IOH_GBE_READ_REG(hw, MAC_ADR2B); | ||
1753 | + regs_buff[27] = IOH_GBE_READ_REG(hw, MAC_ADR3A); | ||
1754 | + /* 070: */ | ||
1755 | + regs_buff[28] = IOH_GBE_READ_REG(hw, MAC_ADR3B); | ||
1756 | + regs_buff[29] = IOH_GBE_READ_REG(hw, MAC_ADR4A); | ||
1757 | + regs_buff[30] = IOH_GBE_READ_REG(hw, MAC_ADR4B); | ||
1758 | + regs_buff[31] = IOH_GBE_READ_REG(hw, MAC_ADR5A); | ||
1759 | + /* 080: */ | ||
1760 | + regs_buff[32] = IOH_GBE_READ_REG(hw, MAC_ADR5B); | ||
1761 | + regs_buff[33] = IOH_GBE_READ_REG(hw, MAC_ADR6A); | ||
1762 | + regs_buff[34] = IOH_GBE_READ_REG(hw, MAC_ADR6B); | ||
1763 | + regs_buff[35] = IOH_GBE_READ_REG(hw, MAC_ADR7A); | ||
1764 | + /* 090: */ | ||
1765 | + regs_buff[36] = IOH_GBE_READ_REG(hw, MAC_ADR7B); | ||
1766 | + regs_buff[37] = IOH_GBE_READ_REG(hw, MAC_ADR8A); | ||
1767 | + regs_buff[38] = IOH_GBE_READ_REG(hw, MAC_ADR8B); | ||
1768 | + regs_buff[39] = IOH_GBE_READ_REG(hw, MAC_ADR9A); | ||
1769 | + /* 0a0: */ | ||
1770 | + regs_buff[40] = IOH_GBE_READ_REG(hw, MAC_ADR9B); | ||
1771 | + regs_buff[41] = IOH_GBE_READ_REG(hw, MAC_ADR10A); | ||
1772 | + regs_buff[42] = IOH_GBE_READ_REG(hw, MAC_ADR10B); | ||
1773 | + regs_buff[43] = IOH_GBE_READ_REG(hw, MAC_ADR11A); | ||
1774 | + /* 0b0: */ | ||
1775 | + regs_buff[44] = IOH_GBE_READ_REG(hw, MAC_ADR11B); | ||
1776 | + regs_buff[45] = IOH_GBE_READ_REG(hw, MAC_ADR12A); | ||
1777 | + regs_buff[46] = IOH_GBE_READ_REG(hw, MAC_ADR12B); | ||
1778 | + regs_buff[47] = IOH_GBE_READ_REG(hw, MAC_ADR13A); | ||
1779 | + /* 0c0: */ | ||
1780 | + regs_buff[48] = IOH_GBE_READ_REG(hw, MAC_ADR13B); | ||
1781 | + regs_buff[49] = IOH_GBE_READ_REG(hw, MAC_ADR14A); | ||
1782 | + regs_buff[50] = IOH_GBE_READ_REG(hw, MAC_ADR14B); | ||
1783 | + regs_buff[51] = IOH_GBE_READ_REG(hw, MAC_ADR15A); | ||
1784 | + /* 0d0: */ | ||
1785 | + regs_buff[52] = IOH_GBE_READ_REG(hw, MAC_ADR15B); | ||
1786 | + regs_buff[53] = IOH_GBE_READ_REG(hw, MAC_ADR16A); | ||
1787 | + regs_buff[54] = IOH_GBE_READ_REG(hw, MAC_ADR16B); | ||
1788 | + regs_buff[55] = IOH_GBE_READ_REG(hw, ADDR_MASK); | ||
1789 | + /* 0e0: */ | ||
1790 | + regs_buff[56] = IOH_GBE_READ_REG(hw, MIIM); | ||
1791 | + regs_buff[57] = IOH_GBE_READ_REG(hw, RGMII_ST); | ||
1792 | + regs_buff[58] = IOH_GBE_READ_REG(hw, RGMII_CTRL); | ||
1793 | + regs_buff[59] = IOH_GBE_READ_REG(hw, DMA_CTRL); | ||
1794 | + /* 0f0: */ | ||
1795 | + regs_buff[60] = IOH_GBE_READ_REG(hw, RX_DSC_BASE); | ||
1796 | + regs_buff[61] = IOH_GBE_READ_REG(hw, RX_DSC_SIZE); | ||
1797 | + regs_buff[62] = IOH_GBE_READ_REG(hw, RX_DSC_HW_P); | ||
1798 | + regs_buff[63] = IOH_GBE_READ_REG(hw, RX_DSC_HW_P_HLD); | ||
1799 | + /* 100: */ | ||
1800 | + regs_buff[64] = IOH_GBE_READ_REG(hw, RX_DSC_SW_P); | ||
1801 | + regs_buff[65] = IOH_GBE_READ_REG(hw, TX_DSC_BASE); | ||
1802 | + regs_buff[66] = IOH_GBE_READ_REG(hw, TX_DSC_SIZE); | ||
1803 | + regs_buff[67] = IOH_GBE_READ_REG(hw, TX_DSC_HW_P); | ||
1804 | + /* 110: */ | ||
1805 | + regs_buff[68] = IOH_GBE_READ_REG(hw, TX_DSC_HW_P_HLD); | ||
1806 | + regs_buff[69] = IOH_GBE_READ_REG(hw, TX_DSC_SW_P); | ||
1807 | + regs_buff[70] = IOH_GBE_READ_REG(hw, RX_DMA_ST); | ||
1808 | + regs_buff[71] = IOH_GBE_READ_REG(hw, TX_DMA_ST); | ||
1809 | + /* 120: */ | ||
1810 | + regs_buff[72] = IOH_GBE_READ_REG(hw, WOL_ST); | ||
1811 | + regs_buff[73] = IOH_GBE_READ_REG(hw, WOL_CTRL); | ||
1812 | + regs_buff[74] = IOH_GBE_READ_REG(hw, WOL_ADDR_MASK); | ||
1813 | + regs_buff[75] = 0x00000000; /* Dummy read */ | ||
1814 | + | ||
1815 | + /* 130: */ | ||
1816 | + /* PHY register */ | ||
1817 | + for (i = IOH_GBE_MAC_REGS_LEN, reg = 0; reg < IOH_GBE_PHY_REGS_LEN; | ||
1818 | + i++, reg++) { | ||
1819 | + ioh_gbe_hal_read_phy_reg(&adapter->hw, reg, &tmp); | ||
1820 | + regs_buff[i] = tmp; | ||
1821 | + } | ||
1822 | + | ||
1823 | +} | ||
1824 | + | ||
1825 | +/*! | ||
1826 | + * @ingroup Ethtool driver | ||
1827 | + * @fn static void ioh_gbe_get_wol(struct net_device *netdev, | ||
1828 | + * struct ethtool_wolinfo *wol) | ||
1829 | + * @brief Report whether Wake-on-Lan is enabled | ||
1830 | + * @param netdev [INOUT] Network interface device structure | ||
1831 | + * @param wol [OUT] Wake-on-Lan information | ||
1832 | + * @return None | ||
1833 | + */ | ||
1834 | +static void | ||
1835 | +ioh_gbe_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | ||
1836 | +{ | ||
1837 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
1838 | + | ||
1839 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_wol"); | ||
1840 | + | ||
1841 | + wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC; | ||
1842 | + wol->wolopts = 0; | ||
1843 | + | ||
1844 | + if ((adapter->wake_up_evt & IOH_GBE_WLC_IND) != 0) | ||
1845 | + wol->wolopts |= WAKE_UCAST; | ||
1846 | + if ((adapter->wake_up_evt & IOH_GBE_WLC_MLT) != 0) | ||
1847 | + wol->wolopts |= WAKE_MCAST; | ||
1848 | + if ((adapter->wake_up_evt & IOH_GBE_WLC_BR) != 0) | ||
1849 | + wol->wolopts |= WAKE_BCAST; | ||
1850 | + if ((adapter->wake_up_evt & IOH_GBE_WLC_MP) != 0) | ||
1851 | + wol->wolopts |= WAKE_MAGIC; | ||
1852 | + return; | ||
1853 | +} | ||
1854 | + | ||
1855 | +/*! | ||
1856 | + * @ingroup Ethtool driver | ||
1857 | + * @fn static int ioh_gbe_set_wol(struct net_device *netdev, | ||
1858 | + * struct ethtool_wolinfo *wol) | ||
1859 | + * @brief Turn Wake-on-Lan on or off | ||
1860 | + * @param netdev [INOUT] Network interface device structure | ||
1861 | + * @param wol [IN] Pointer of wake-on-Lan information straucture | ||
1862 | + * @return IOH_GBE_SUCCESS: Successfully | ||
1863 | + * @return Negative value: Failed | ||
1864 | + */ | ||
1865 | +static int | ||
1866 | +ioh_gbe_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | ||
1867 | +{ | ||
1868 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
1869 | + | ||
1870 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_set_wol"); | ||
1871 | + | ||
1872 | + if ((wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)) != 0) | ||
1873 | + return -EOPNOTSUPP; | ||
1874 | + /* these settings will always override what we currently have */ | ||
1875 | + adapter->wake_up_evt = 0; | ||
1876 | + | ||
1877 | + if ((wol->wolopts & WAKE_UCAST) != 0) | ||
1878 | + adapter->wake_up_evt |= IOH_GBE_WLC_IND; | ||
1879 | + if ((wol->wolopts & WAKE_MCAST) != 0) | ||
1880 | + adapter->wake_up_evt |= IOH_GBE_WLC_MLT; | ||
1881 | + if ((wol->wolopts & WAKE_BCAST) != 0) | ||
1882 | + adapter->wake_up_evt |= IOH_GBE_WLC_BR; | ||
1883 | + if ((wol->wolopts & WAKE_MAGIC) != 0) | ||
1884 | + adapter->wake_up_evt |= IOH_GBE_WLC_MP; | ||
1885 | + return IOH_GBE_SUCCESS; | ||
1886 | +} | ||
1887 | + | ||
1888 | +/*! | ||
1889 | + * @ingroup Ethtool driver | ||
1890 | + * @fn static u32 ioh_gbe_get_msglevel(struct net_device *netdev) | ||
1891 | + * @brief Report driver message level | ||
1892 | + * @param netdev [INOUT] Network interface device structure | ||
1893 | + * @return IOH_GBE_SUCCESS: Successfully | ||
1894 | + * @return Negative value: Failed | ||
1895 | + */ | ||
1896 | +static u32 ioh_gbe_get_msglevel(struct net_device *netdev) | ||
1897 | +{ | ||
1898 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
1899 | + | ||
1900 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_msglevel"); | ||
1901 | + | ||
1902 | + return adapter->msg_enable; | ||
1903 | +} | ||
1904 | + | ||
1905 | +/*! | ||
1906 | + * @ingroup Ethtool driver | ||
1907 | + * @fn static void ioh_gbe_set_msglevel(struct net_device *netdev, | ||
1908 | + * u32 data) | ||
1909 | + * @brief Set driver message level | ||
1910 | + * @param netdev [INOUT] Network interface device structure | ||
1911 | + * @param data [IN] Driver message level | ||
1912 | + * @return None | ||
1913 | + */ | ||
1914 | +static void ioh_gbe_set_msglevel(struct net_device *netdev, u32 data) | ||
1915 | +{ | ||
1916 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
1917 | + | ||
1918 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_set_msglevel"); | ||
1919 | + | ||
1920 | + adapter->msg_enable = data; | ||
1921 | +} | ||
1922 | + | ||
1923 | +/*! | ||
1924 | + * @ingroup Ethtool driver | ||
1925 | + * @fn static int ioh_gbe_nway_reset(struct net_device *netdev) | ||
1926 | + * @brief Restart autonegotiation | ||
1927 | + * @param netdev [INOUT] Network interface device structure | ||
1928 | + * @return IOH_GBE_SUCCESS: Successfully | ||
1929 | + * @return Negative value: Failed | ||
1930 | + */ | ||
1931 | +static int ioh_gbe_nway_reset(struct net_device *netdev) | ||
1932 | +{ | ||
1933 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
1934 | + | ||
1935 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_nway_reset"); | ||
1936 | + | ||
1937 | + return mii_nway_restart(&adapter->mii); | ||
1938 | +} | ||
1939 | + | ||
1940 | +#ifdef CONFIG_PCH_PCIEQOS | ||
1941 | +/*! | ||
1942 | + * @ingroup Ethtool driver | ||
1943 | + * @fn static int ioh_gbe_get_eeprom_len(struct net_device *netdev) | ||
1944 | + * @brief Report the device EEPROM memory size | ||
1945 | + * @param netdev [INOUT] Network interface device structure | ||
1946 | + * @return IOH_GBE_SUCCESS: Successfully | ||
1947 | + * @return Negative value: Failed | ||
1948 | + */ | ||
1949 | +static int ioh_gbe_get_eeprom_len(struct net_device *netdev) | ||
1950 | +{ | ||
1951 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
1952 | + | ||
1953 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_eeprom_len"); | ||
1954 | + | ||
1955 | + return adapter->hw.nvm.word_size * 2; | ||
1956 | +} | ||
1957 | + | ||
1958 | +/*! | ||
1959 | + * @ingroup Ethtool driver | ||
1960 | + * @fn static int ioh_gbe_get_eeprom(struct net_device *netdev, | ||
1961 | + * struct ethtool_eeprom *eeprom, u8 *bytes) | ||
1962 | + * @brief Read data from the device EEPROM | ||
1963 | + * @param netdev [INOUT] Network interface device structure | ||
1964 | + * @param eeprom [INOUT] EEPROM get information structur | ||
1965 | + * @param bytes [OUT] Pointer of read data | ||
1966 | + * @return IOH_GBE_SUCCESS: Successfully | ||
1967 | + * @return Negative value: Failed | ||
1968 | + */ | ||
1969 | +static int | ||
1970 | +ioh_gbe_get_eeprom(struct net_device *netdev, | ||
1971 | + struct ethtool_eeprom *eeprom, u8 *bytes) | ||
1972 | +{ | ||
1973 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
1974 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
1975 | + int ret = IOH_GBE_SUCCESS; | ||
1976 | + u32 offset; | ||
1977 | + u8 i; | ||
1978 | + | ||
1979 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_eeprom"); | ||
1980 | + | ||
1981 | + if (eeprom->len == 0) | ||
1982 | + return -EINVAL; | ||
1983 | + eeprom->magic = (hw->vendor_id); | ||
1984 | + | ||
1985 | + for (i = 0, offset = eeprom->offset; i < (eeprom->len); i++, offset++) { | ||
1986 | + ret = ioh_gbe_hal_read_nvm(hw, offset, (bytes + i)); | ||
1987 | + if (ret) | ||
1988 | + break; | ||
1989 | + } | ||
1990 | + return ret; | ||
1991 | +} | ||
1992 | + | ||
1993 | +/*! | ||
1994 | + * @ingroup Ethtool driver | ||
1995 | + * @fn static int ioh_gbe_set_eeprom(struct net_device *netdev, | ||
1996 | + * struct ethtool_eeprom *eeprom, u8 *bytes) | ||
1997 | + * @brief Write data to the device EEPROM | ||
1998 | + * @param netdev [INOUT] Network interface device structure | ||
1999 | + * @param eeprom [INOUT] EEPROM get information structur | ||
2000 | + * @param bytes [IN] Pointer of write data | ||
2001 | + * @return IOH_GBE_SUCCESS: Successfully | ||
2002 | + * @return Negative value: Failed | ||
2003 | + */ | ||
2004 | +static int | ||
2005 | +ioh_gbe_set_eeprom(struct net_device *netdev, | ||
2006 | + struct ethtool_eeprom *eeprom, u8 *bytes) | ||
2007 | +{ | ||
2008 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
2009 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
2010 | + int ret; | ||
2011 | + u32 offset; | ||
2012 | + u8 i; | ||
2013 | + | ||
2014 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_set_eeprom"); | ||
2015 | + | ||
2016 | + if (eeprom->len == 0) { | ||
2017 | + IOH_GBE_ERR("EOPNOTSUPP\n"); | ||
2018 | + return -EOPNOTSUPP; | ||
2019 | + } | ||
2020 | + if (eeprom->magic != (hw->vendor_id)) { | ||
2021 | + IOH_GBE_ERR("EFAULT\n"); | ||
2022 | + IOH_GBE_TESTOUT("eeprom->magic : 0x%08x magic : %0x\n", | ||
2023 | + eeprom->magic, (hw->vendor_id)); | ||
2024 | + return -EFAULT; | ||
2025 | + } | ||
2026 | + | ||
2027 | + for (i = 0, offset = eeprom->offset; i < (eeprom->len); i++, offset++) { | ||
2028 | + ret = ioh_gbe_hal_write_nvm(hw, offset, (bytes + i)); | ||
2029 | + if (ret) | ||
2030 | + return ret; | ||
2031 | + } | ||
2032 | + return IOH_GBE_SUCCESS; | ||
2033 | +} | ||
2034 | +#endif | ||
2035 | + | ||
2036 | +/*! | ||
2037 | + * @ingroup Ethtool driver | ||
2038 | + * @fn static void ioh_gbe_get_ringparam(struct net_device *netdev, | ||
2039 | + * struct ethtool_ringparam *ring) | ||
2040 | + * @brief Report ring sizes | ||
2041 | + * @param netdev [INOUT] Network interface device structure | ||
2042 | + * @param ring [OUT] Ring param structure | ||
2043 | + * @return None | ||
2044 | + */ | ||
2045 | +static void | ||
2046 | +ioh_gbe_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) | ||
2047 | +{ | ||
2048 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
2049 | + struct ioh_gbe_tx_ring *txdr = adapter->tx_ring; | ||
2050 | + struct ioh_gbe_rx_ring *rxdr = adapter->rx_ring; | ||
2051 | + | ||
2052 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_ringparam"); | ||
2053 | + | ||
2054 | + ring->rx_max_pending = IOH_GBE_MAX_RXD; | ||
2055 | + ring->tx_max_pending = IOH_GBE_MAX_TXD; | ||
2056 | + ring->rx_mini_max_pending = 0; | ||
2057 | + ring->rx_jumbo_max_pending = 0; | ||
2058 | + ring->rx_pending = rxdr->count; | ||
2059 | + ring->tx_pending = txdr->count; | ||
2060 | + ring->rx_mini_pending = 0; | ||
2061 | + ring->rx_jumbo_pending = 0; | ||
2062 | +} | ||
2063 | + | ||
2064 | +/*! | ||
2065 | + * @ingroup Ethtool driver | ||
2066 | + * @fn static int ioh_gbe_set_ringparam(struct net_device *netdev, | ||
2067 | + * struct ethtool_ringparam *ring) | ||
2068 | + * @brief Set ring sizes | ||
2069 | + * @param netdev [INOUT] Network interface device structure | ||
2070 | + * @param ring [IN] Ring param structure | ||
2071 | + * @return IOH_GBE_SUCCESS: Successfully | ||
2072 | + * @return Negative value: Failed | ||
2073 | + */ | ||
2074 | +static int | ||
2075 | +ioh_gbe_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) | ||
2076 | +{ | ||
2077 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
2078 | + struct ioh_gbe_tx_ring *txdr, *tx_old; | ||
2079 | + struct ioh_gbe_rx_ring *rxdr, *rx_old; | ||
2080 | + int tx_ring_size, rx_ring_size; | ||
2081 | + int err = IOH_GBE_SUCCESS; | ||
2082 | + | ||
2083 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_set_ringparam"); | ||
2084 | + | ||
2085 | + if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) | ||
2086 | + return -EINVAL; | ||
2087 | + tx_ring_size = (int)sizeof(struct ioh_gbe_tx_ring); | ||
2088 | + rx_ring_size = (int)sizeof(struct ioh_gbe_rx_ring); | ||
2089 | + | ||
2090 | + while ((test_and_set_bit(__IOH_GBE_RESETTING, &adapter->flags)) != 0) | ||
2091 | + msleep(1); | ||
2092 | + if ((netif_running(adapter->netdev)) != 0) | ||
2093 | + ioh_gbe_down(adapter); | ||
2094 | + tx_old = adapter->tx_ring; | ||
2095 | + rx_old = adapter->rx_ring; | ||
2096 | + | ||
2097 | + txdr = kzalloc(tx_ring_size, GFP_KERNEL); | ||
2098 | + if (!txdr) { | ||
2099 | + err = -ENOMEM; | ||
2100 | + goto err_alloc_tx; | ||
2101 | + } | ||
2102 | + rxdr = kzalloc(rx_ring_size, GFP_KERNEL); | ||
2103 | + if (!rxdr) { | ||
2104 | + err = -ENOMEM; | ||
2105 | + goto err_alloc_rx; | ||
2106 | + } | ||
2107 | + adapter->tx_ring = txdr; | ||
2108 | + adapter->rx_ring = rxdr; | ||
2109 | + | ||
2110 | + rxdr->count = max(ring->rx_pending, (u32) IOH_GBE_MIN_RXD); | ||
2111 | + rxdr->count = min(rxdr->count, (u32) IOH_GBE_MAX_RXD); | ||
2112 | + IOH_GBE_ROUNDUP(rxdr->count, IOH_GBE_RX_DESC_MULTIPLE); | ||
2113 | + | ||
2114 | + txdr->count = max(ring->tx_pending, (u32) IOH_GBE_MIN_TXD); | ||
2115 | + txdr->count = min(txdr->count, (u32) IOH_GBE_MAX_TXD); | ||
2116 | + IOH_GBE_ROUNDUP(txdr->count, IOH_GBE_TX_DESC_MULTIPLE); | ||
2117 | + | ||
2118 | + if ((netif_running(adapter->netdev)) != 0) { | ||
2119 | + /* Try to get new resources before deleting old */ | ||
2120 | + err = ioh_gbe_setup_rx_resources(adapter, adapter->rx_ring); | ||
2121 | + if (err != 0) | ||
2122 | + goto err_setup_rx; | ||
2123 | + err = ioh_gbe_setup_tx_resources(adapter, adapter->tx_ring); | ||
2124 | + if (err != 0) | ||
2125 | + goto err_setup_tx; | ||
2126 | + /* save the new, restore the old in order to free it, | ||
2127 | + * then restore the new back again */ | ||
2128 | + adapter->rx_ring = rx_old; | ||
2129 | + adapter->tx_ring = tx_old; | ||
2130 | + ioh_gbe_free_rx_resources(adapter, adapter->rx_ring); | ||
2131 | + ioh_gbe_free_tx_resources(adapter, adapter->tx_ring); | ||
2132 | + kfree(tx_old); | ||
2133 | + kfree(rx_old); | ||
2134 | + adapter->rx_ring = rxdr; | ||
2135 | + adapter->tx_ring = txdr; | ||
2136 | + err = ioh_gbe_up(adapter); | ||
2137 | + } | ||
2138 | + | ||
2139 | + clear_bit(__IOH_GBE_RESETTING, &adapter->flags); | ||
2140 | + return err; | ||
2141 | + | ||
2142 | +err_setup_tx: | ||
2143 | + ioh_gbe_free_rx_resources(adapter, adapter->rx_ring); | ||
2144 | +err_setup_rx: | ||
2145 | + adapter->rx_ring = rx_old; | ||
2146 | + adapter->tx_ring = tx_old; | ||
2147 | + kfree(rxdr); | ||
2148 | +err_alloc_rx: | ||
2149 | + kfree(txdr); | ||
2150 | +err_alloc_tx: | ||
2151 | + if (netif_running(adapter->netdev)) | ||
2152 | + ioh_gbe_up(adapter); | ||
2153 | + clear_bit(__IOH_GBE_RESETTING, &adapter->flags); | ||
2154 | + return err; | ||
2155 | +} | ||
2156 | + | ||
2157 | +/*! | ||
2158 | + * @ingroup Ethtool driver | ||
2159 | + * @fn static void ioh_gbe_get_pauseparam(struct net_device *netdev, | ||
2160 | + * struct ethtool_pauseparam *pause) | ||
2161 | + * @brief Report pause parameters | ||
2162 | + * @param netdev [INOUT] Network interface device structure | ||
2163 | + * @param pause [OUT] Pause parameters structure | ||
2164 | + * @return None | ||
2165 | + */ | ||
2166 | +static void | ||
2167 | +ioh_gbe_get_pauseparam(struct net_device *netdev, | ||
2168 | + struct ethtool_pauseparam *pause) | ||
2169 | +{ | ||
2170 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
2171 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
2172 | + | ||
2173 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_pauseparam"); | ||
2174 | + | ||
2175 | + pause->autoneg = | ||
2176 | + ((hw->mac.fc_autoneg != 0) ? AUTONEG_ENABLE : AUTONEG_DISABLE); | ||
2177 | + | ||
2178 | + if (hw->mac.fc == ioh_gbe_fc_rx_pause) { | ||
2179 | + pause->rx_pause = 1; | ||
2180 | + } else if (hw->mac.fc == ioh_gbe_fc_tx_pause) { | ||
2181 | + pause->tx_pause = 1; | ||
2182 | + } else if (hw->mac.fc == ioh_gbe_fc_full) { | ||
2183 | + pause->rx_pause = 1; | ||
2184 | + pause->tx_pause = 1; | ||
2185 | + } | ||
2186 | +} | ||
2187 | + | ||
2188 | +/*! | ||
2189 | + * @ingroup Ethtool driver | ||
2190 | + * @fn static int ioh_gbe_set_pauseparam(struct net_device *netdev, | ||
2191 | + * struct ethtool_pauseparam *pause) | ||
2192 | + * @brief Set pause paramters | ||
2193 | + * @param netdev [INOUT] Network interface device structure | ||
2194 | + * @param pause [IN] Pause parameters structure | ||
2195 | + * @return IOH_GBE_SUCCESS: Successfully | ||
2196 | + * @return Negative value: Failed | ||
2197 | + */ | ||
2198 | +static int | ||
2199 | +ioh_gbe_set_pauseparam(struct net_device *netdev, | ||
2200 | + struct ethtool_pauseparam *pause) | ||
2201 | +{ | ||
2202 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
2203 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
2204 | + int ret = IOH_GBE_SUCCESS; | ||
2205 | + | ||
2206 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_set_pauseparam"); | ||
2207 | + | ||
2208 | + hw->mac.fc_autoneg = pause->autoneg; | ||
2209 | + | ||
2210 | + while ((test_and_set_bit(__IOH_GBE_RESETTING, &adapter->flags)) != 0) | ||
2211 | + msleep(1); | ||
2212 | + if ((pause->rx_pause) && (pause->tx_pause)) | ||
2213 | + hw->mac.fc = ioh_gbe_fc_full; | ||
2214 | + else if ((pause->rx_pause) && (!pause->tx_pause)) | ||
2215 | + hw->mac.fc = ioh_gbe_fc_rx_pause; | ||
2216 | + else if ((!pause->rx_pause) && (pause->tx_pause)) | ||
2217 | + hw->mac.fc = ioh_gbe_fc_tx_pause; | ||
2218 | + else if ((!pause->rx_pause) && (!pause->tx_pause)) | ||
2219 | + hw->mac.fc = ioh_gbe_fc_none; | ||
2220 | + | ||
2221 | + if (hw->mac.fc_autoneg == AUTONEG_ENABLE) { | ||
2222 | + if ((netif_running(adapter->netdev)) != 0) { | ||
2223 | + ioh_gbe_down(adapter); | ||
2224 | + ret = ioh_gbe_up(adapter); | ||
2225 | + } else { | ||
2226 | + ioh_gbe_reset(adapter); | ||
2227 | + } | ||
2228 | + } else { | ||
2229 | + ret = ioh_gbe_hal_force_mac_fc(hw); | ||
2230 | + } | ||
2231 | + clear_bit(__IOH_GBE_RESETTING, &adapter->flags); | ||
2232 | + return ret; | ||
2233 | +} | ||
2234 | + | ||
2235 | +/*! | ||
2236 | + * @ingroup Ethtool driver | ||
2237 | + * @fn static u32 ioh_gbe_get_rx_csum(struct net_device *netdev) | ||
2238 | + * @brief Report whether receive checksums are turned on or off | ||
2239 | + * @param netdev [INOUT] Network interface device structure | ||
2240 | + * @return TRUE(1): Checksum On | ||
2241 | + * @return FALSE(0): Checksum Off | ||
2242 | + */ | ||
2243 | +static u32 ioh_gbe_get_rx_csum(struct net_device *netdev) | ||
2244 | +{ | ||
2245 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
2246 | + | ||
2247 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_rx_csum"); | ||
2248 | + | ||
2249 | + return adapter->rx_csum; | ||
2250 | +} | ||
2251 | + | ||
2252 | +/*! | ||
2253 | + * @ingroup Ethtool driver | ||
2254 | + * @fn static int ioh_gbe_set_rx_csum(struct net_device *netdev, u32 data) | ||
2255 | + * @brief Turn receive checksum on or off | ||
2256 | + * @param netdev [INOUT] Network interface device structure | ||
2257 | + * @param data [IN] Checksum On[TRUE] or Off[FALSE] | ||
2258 | + * @return IOH_GBE_SUCCESS: Successfully | ||
2259 | + * @return Negative value: Failed | ||
2260 | + */ | ||
2261 | +static int ioh_gbe_set_rx_csum(struct net_device *netdev, u32 data) | ||
2262 | +{ | ||
2263 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
2264 | + | ||
2265 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_set_rx_csum"); | ||
2266 | + | ||
2267 | + adapter->rx_csum = data; | ||
2268 | + if ((netif_running(netdev)) != 0) | ||
2269 | + ioh_gbe_reinit_locked(adapter); | ||
2270 | + else | ||
2271 | + ioh_gbe_reset(adapter); | ||
2272 | + | ||
2273 | + return IOH_GBE_SUCCESS; | ||
2274 | +} | ||
2275 | + | ||
2276 | +/*! | ||
2277 | + * @ingroup Ethtool driver | ||
2278 | + * @fn static u32 ioh_gbe_get_tx_csum(struct net_device *netdev) | ||
2279 | + * @brief Report whether transmit checksums are turned on or off | ||
2280 | + * @param netdev [INOUT] Network interface device structure | ||
2281 | + * @return TRUE(1): Checksum On | ||
2282 | + * @return FALSE(0): Checksum Off | ||
2283 | + */ | ||
2284 | +static u32 ioh_gbe_get_tx_csum(struct net_device *netdev) | ||
2285 | +{ | ||
2286 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_tx_csum"); | ||
2287 | + | ||
2288 | + return (netdev->features & NETIF_F_HW_CSUM) != 0; | ||
2289 | +} | ||
2290 | + | ||
2291 | +/*! | ||
2292 | + * @ingroup Ethtool driver | ||
2293 | + * @fn static int ioh_gbe_set_tx_csum(struct net_device *netdev, u32 data) | ||
2294 | + * @brief Turn transmit checksums on or off | ||
2295 | + * @param netdev [INOUT] Network interface device structure | ||
2296 | + * @param data [IN] Checksum on[TRUE] or off[FALSE] | ||
2297 | + * @return IOH_GBE_SUCCESS: Successfully | ||
2298 | + * @return Negative value: Failed | ||
2299 | + */ | ||
2300 | +static int ioh_gbe_set_tx_csum(struct net_device *netdev, u32 data) | ||
2301 | +{ | ||
2302 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
2303 | + | ||
2304 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_set_tx_csum"); | ||
2305 | + | ||
2306 | + adapter->tx_csum = data; | ||
2307 | + | ||
2308 | + if (data != 0) | ||
2309 | + netdev->features |= NETIF_F_HW_CSUM; | ||
2310 | + else | ||
2311 | + netdev->features &= ~NETIF_F_HW_CSUM; | ||
2312 | + | ||
2313 | + return IOH_GBE_SUCCESS; | ||
2314 | +} | ||
2315 | + | ||
2316 | +/*! | ||
2317 | + * @ingroup Ethtool driver | ||
2318 | + * @fn static void ioh_gbe_diag_test(struct net_device *netdev, | ||
2319 | + * struct ethtool_test *eth_test, u64 *data) | ||
2320 | + * @brief Run specified self-tests | ||
2321 | + * @param netdev [IN] Network interface device structure | ||
2322 | + * @param eth_test [IN] Ethtool test structure | ||
2323 | + * @param data [OUT] Data for test result. | ||
2324 | + * @return None | ||
2325 | + */ | ||
2326 | +static void | ||
2327 | +ioh_gbe_diag_test(struct net_device *netdev, | ||
2328 | + struct ethtool_test *eth_test, u64 *data) | ||
2329 | +{ | ||
2330 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
2331 | + unsigned char if_running = netif_running(netdev); | ||
2332 | + | ||
2333 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_diag_test"); | ||
2334 | + | ||
2335 | + set_bit(__IOH_GBE_TESTING, &adapter->flags); | ||
2336 | + | ||
2337 | + if (eth_test->flags == ETH_TEST_FL_OFFLINE) { | ||
2338 | + /* Offline tests */ | ||
2339 | + DPRINTK(HW, INFO, "offline testing starting\n"); | ||
2340 | + | ||
2341 | + if (if_running) { | ||
2342 | + /* indicate we're in test mode */ | ||
2343 | + dev_close(netdev); | ||
2344 | + } else { | ||
2345 | + ioh_gbe_reset(adapter); | ||
2346 | + } | ||
2347 | + /* Register test */ | ||
2348 | + if (ioh_gbe_reg_test(adapter, &data[0])) | ||
2349 | + eth_test->flags |= ETH_TEST_FL_FAILED; | ||
2350 | + | ||
2351 | + ioh_gbe_reset(adapter); | ||
2352 | + clear_bit(__IOH_GBE_TESTING, &adapter->flags); | ||
2353 | + if (if_running) | ||
2354 | + dev_open(netdev); | ||
2355 | + | ||
2356 | + } else { | ||
2357 | + /* Online tests */ | ||
2358 | + DPRINTK(HW, INFO, "online testing starting\n"); | ||
2359 | + data[0] = 0; | ||
2360 | + clear_bit(__IOH_GBE_TESTING, &adapter->flags); | ||
2361 | + } | ||
2362 | +} | ||
2363 | + | ||
2364 | +/*! | ||
2365 | + * @ingroup Ethtool driver | ||
2366 | + * @fn static void ioh_gbe_get_strings(struct net_device *netdev, | ||
2367 | + * u32 stringset, u8 *data) | ||
2368 | + * @brief Return a set of strings that describe the requested objects | ||
2369 | + * @param netdev [INOUT] Network interface device structure | ||
2370 | + * @param stringset [IN] Select the stringset. [ETH_SS_TEST] [ETH_SS_STATS] | ||
2371 | + * @param data [OUT]Pointer of read string data. | ||
2372 | + * @return None | ||
2373 | + */ | ||
2374 | +static void | ||
2375 | +ioh_gbe_get_strings(struct net_device *netdev, u32 stringset, u8 *data) | ||
2376 | +{ | ||
2377 | + u8 *p = data; | ||
2378 | + int i; | ||
2379 | + | ||
2380 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_strings"); | ||
2381 | + | ||
2382 | + switch (stringset) { | ||
2383 | + case (u32) ETH_SS_TEST: | ||
2384 | + memcpy(data, *ioh_gbe_gstrings_test, | ||
2385 | + (int)sizeof(ioh_gbe_gstrings_test)); | ||
2386 | + break; | ||
2387 | + case (u32) ETH_SS_STATS: | ||
2388 | + for (i = 0; i < IOH_GBE_GLOBAL_STATS_LEN; i++) { | ||
2389 | + memcpy(p, ioh_gbe_gstrings_stats[i].stat_string, | ||
2390 | + ETH_GSTRING_LEN); | ||
2391 | + p += ETH_GSTRING_LEN; | ||
2392 | + } | ||
2393 | + break; | ||
2394 | + } | ||
2395 | +} | ||
2396 | + | ||
2397 | +/*! | ||
2398 | + * @ingroup Ethtool driver | ||
2399 | + * @fn static void ioh_gbe_led_blink_callback(unsigned long data) | ||
2400 | + * @brief Callback function for blink led | ||
2401 | + * @param data [IN] Pointer Address of Board private structure | ||
2402 | + * @return None | ||
2403 | + */ | ||
2404 | +static void ioh_gbe_led_blink_callback(unsigned long data) | ||
2405 | +{ | ||
2406 | + struct ioh_gbe_adapter *adapter = (struct ioh_gbe_adapter *)data; | ||
2407 | + | ||
2408 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_led_blink_callback"); | ||
2409 | + | ||
2410 | + if ((test_and_change_bit(IOH_GBE_LED_ON, &adapter->led_status)) != 0) | ||
2411 | + ioh_gbe_hal_led_off(&adapter->hw); | ||
2412 | + else | ||
2413 | + ioh_gbe_hal_led_on(&adapter->hw); | ||
2414 | + mod_timer(&adapter->blink_timer, jiffies + IOH_GBE_ID_INTERVAL); | ||
2415 | +} | ||
2416 | + | ||
2417 | +/*! | ||
2418 | + * @ingroup Ethtool driver | ||
2419 | + * @fn static int ioh_gbe_phys_id(struct net_device *netdev, u32 data) | ||
2420 | + * @brief Identify the device | ||
2421 | + * @param netdev [INOUT] Network interface device structure | ||
2422 | + * @param data [IN] Sleep time[ms] | ||
2423 | + * @return IOH_GBE_SUCCESS: Successfully | ||
2424 | + * @return Negative value: Failed | ||
2425 | + */ | ||
2426 | +static int ioh_gbe_phys_id(struct net_device *netdev, u32 data) | ||
2427 | +{ | ||
2428 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
2429 | + | ||
2430 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_phys_id"); | ||
2431 | + | ||
2432 | + if (!data || data > (u32) (MAX_SCHEDULE_TIMEOUT / HZ)) | ||
2433 | + data = (u32) (MAX_SCHEDULE_TIMEOUT / HZ); | ||
2434 | + if (!adapter->blink_timer.function) { | ||
2435 | + init_timer(&adapter->blink_timer); | ||
2436 | + adapter->blink_timer.function = ioh_gbe_led_blink_callback; | ||
2437 | + adapter->blink_timer.data = (unsigned long)adapter; | ||
2438 | + } | ||
2439 | + ioh_gbe_hal_setup_led(&adapter->hw); | ||
2440 | + mod_timer(&adapter->blink_timer, jiffies); | ||
2441 | + msleep_interruptible(data * 1000); | ||
2442 | + del_timer_sync(&adapter->blink_timer); | ||
2443 | + | ||
2444 | + ioh_gbe_hal_led_off(&adapter->hw); | ||
2445 | + clear_bit(IOH_GBE_LED_ON, &adapter->led_status); | ||
2446 | + ioh_gbe_hal_cleanup_led(&adapter->hw); | ||
2447 | + return IOH_GBE_SUCCESS; | ||
2448 | +} | ||
2449 | + | ||
2450 | +/*! | ||
2451 | + * @ingroup Ethtool driver | ||
2452 | + * @fn static void ioh_gbe_get_ethtool_stats(struct net_device *netdev, | ||
2453 | + * struct ethtool_stats *stats, u64 *data) | ||
2454 | + * @brief Return statistics about the device | ||
2455 | + * @param netdev [INOUT] Network interface device structure | ||
2456 | + * @param stats [INOUT] Ethtool statue structure | ||
2457 | + * @param data [OUT] Pointer of read status area | ||
2458 | + * @return None | ||
2459 | + */ | ||
2460 | +static void | ||
2461 | +ioh_gbe_get_ethtool_stats(struct net_device *netdev, | ||
2462 | + struct ethtool_stats *stats, u64 *data) | ||
2463 | +{ | ||
2464 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
2465 | + int i; | ||
2466 | + | ||
2467 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_ethtool_stats"); | ||
2468 | + | ||
2469 | + ioh_gbe_update_stats(adapter); | ||
2470 | + for (i = 0; i < IOH_GBE_GLOBAL_STATS_LEN; i++) { | ||
2471 | + signed char *p = | ||
2472 | + (signed char *)adapter + | ||
2473 | + ioh_gbe_gstrings_stats[i].stat_offset; | ||
2474 | + data[i] = | ||
2475 | + (ioh_gbe_gstrings_stats[i].sizeof_stat == | ||
2476 | + (int)sizeof(u64)) ? *(u64 *) p:(*(u32 *) p); | ||
2477 | + } | ||
2478 | +} | ||
2479 | + | ||
2480 | +/*! | ||
2481 | + * @ingroup Ethtool driver Layer | ||
2482 | + * @struct ioh_gbe_ethtool_ops | ||
2483 | + * @brief Store the pointers of ethtool interfaces to kernel | ||
2484 | + */ | ||
2485 | +static struct ethtool_ops ioh_gbe_ethtool_ops = { | ||
2486 | + .get_settings = ioh_gbe_get_settings, | ||
2487 | + .set_settings = ioh_gbe_set_settings, | ||
2488 | + .get_drvinfo = ioh_gbe_get_drvinfo, | ||
2489 | + .get_regs_len = ioh_gbe_get_regs_len, | ||
2490 | + .get_regs = ioh_gbe_get_regs, | ||
2491 | + .get_wol = ioh_gbe_get_wol, | ||
2492 | + .set_wol = ioh_gbe_set_wol, | ||
2493 | + .get_msglevel = ioh_gbe_get_msglevel, | ||
2494 | + .set_msglevel = ioh_gbe_set_msglevel, | ||
2495 | + .nway_reset = ioh_gbe_nway_reset, | ||
2496 | + .get_link = ethtool_op_get_link, | ||
2497 | +#ifdef CONFIG_PCH_PCIEQOS | ||
2498 | + .get_eeprom_len = ioh_gbe_get_eeprom_len, | ||
2499 | + .get_eeprom = ioh_gbe_get_eeprom, | ||
2500 | + .set_eeprom = ioh_gbe_set_eeprom, | ||
2501 | +#endif | ||
2502 | + .get_ringparam = ioh_gbe_get_ringparam, | ||
2503 | + .set_ringparam = ioh_gbe_set_ringparam, | ||
2504 | + .get_pauseparam = ioh_gbe_get_pauseparam, | ||
2505 | + .set_pauseparam = ioh_gbe_set_pauseparam, | ||
2506 | + .get_rx_csum = ioh_gbe_get_rx_csum, | ||
2507 | + .set_rx_csum = ioh_gbe_set_rx_csum, | ||
2508 | + .get_tx_csum = ioh_gbe_get_tx_csum, | ||
2509 | + .set_tx_csum = ioh_gbe_set_tx_csum, | ||
2510 | + .self_test = ioh_gbe_diag_test, | ||
2511 | + .get_strings = ioh_gbe_get_strings, | ||
2512 | + .phys_id = ioh_gbe_phys_id, | ||
2513 | + .get_ethtool_stats = ioh_gbe_get_ethtool_stats, | ||
2514 | +}; | ||
2515 | + | ||
2516 | +/*! | ||
2517 | + * @ingroup Ethtool driver internal functions | ||
2518 | + * @fn void ioh_gbe_set_ethtool_ops(struct net_device *netdev) | ||
2519 | + * @brief Set the Ethtool to network device data | ||
2520 | + * @param netdev [INOUT] Network interface device structure | ||
2521 | + * @return None | ||
2522 | + */ | ||
2523 | +void ioh_gbe_set_ethtool_ops(struct net_device *netdev) | ||
2524 | +{ | ||
2525 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_set_ethtool_ops"); | ||
2526 | + | ||
2527 | + SET_ETHTOOL_OPS(netdev, &ioh_gbe_ethtool_ops); | ||
2528 | +} | ||
2529 | + | ||
2530 | +#define IOH_GBE_REG_PATTERN_TEST(reg, mask, write) \ | ||
2531 | + do { \ | ||
2532 | + if (reg_pattern_test(adapter, data, \ | ||
2533 | + IOH_GBE_##reg, mask, write)) \ | ||
2534 | + return 1; \ | ||
2535 | + } while (0) | ||
2536 | + | ||
2537 | +/*! | ||
2538 | + * @ingroup Ethtool driver internal functions | ||
2539 | + * @fn static int ioh_gbe_reg_test(struct ioh_gbe_adapter *adapter, uint64_t *data) | ||
2540 | + * @brief Register test | ||
2541 | + * @param adapter [IN] Board private structure | ||
2542 | + * @param data [INOUT] Pointer to test result data | ||
2543 | + * @return IOH_GBE_SUCCESS | ||
2544 | + */ | ||
2545 | +static int ioh_gbe_reg_test(struct ioh_gbe_adapter *adapter, uint64_t *data) | ||
2546 | +{ | ||
2547 | + IOH_GBE_DBGFUNC("ethtool: ioh_gbe_reg_test"); | ||
2548 | + | ||
2549 | + ioh_gbe_reset(adapter); | ||
2550 | + IOH_GBE_REG_PATTERN_TEST(INT_EN, 0x11111F3F, 0x11111F3F); | ||
2551 | + IOH_GBE_REG_PATTERN_TEST(MODE, 0xC2000000, 0xC2000000); | ||
2552 | + IOH_GBE_REG_PATTERN_TEST(TCPIP_ACC, 0x0000000F, 0x0000000F); | ||
2553 | + IOH_GBE_REG_PATTERN_TEST(EX_LIST, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2554 | + IOH_GBE_REG_PATTERN_TEST(PHY_INT_CTRL, 0x00010003, 0x00010003); | ||
2555 | + IOH_GBE_REG_PATTERN_TEST(MAC_RX_EN, 0x00000001, 0x00000001); | ||
2556 | + IOH_GBE_REG_PATTERN_TEST(RX_FCTRL, 0x80000000, 0x80000000); | ||
2557 | + IOH_GBE_REG_PATTERN_TEST(PAUSE_REQ, 0x80000000, 0x80000000); | ||
2558 | + IOH_GBE_REG_PATTERN_TEST(RX_MODE, 0xC000FE00, 0xC000FE00); | ||
2559 | + IOH_GBE_REG_PATTERN_TEST(TX_MODE, 0xF800FE00, 0xF800FE00); | ||
2560 | + IOH_GBE_REG_PATTERN_TEST(PAUSE_PKT1, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2561 | + IOH_GBE_REG_PATTERN_TEST(PAUSE_PKT2, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2562 | + IOH_GBE_REG_PATTERN_TEST(PAUSE_PKT3, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2563 | + IOH_GBE_REG_PATTERN_TEST(PAUSE_PKT4, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2564 | + IOH_GBE_REG_PATTERN_TEST(PAUSE_PKT5, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2565 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR1A, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2566 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR1B, 0x0000FFFF, 0x0000FFFF); | ||
2567 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR2A, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2568 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR2B, 0x0000FFFF, 0x0000FFFF); | ||
2569 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR3A, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2570 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR3B, 0x0000FFFF, 0x0000FFFF); | ||
2571 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR4A, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2572 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR4B, 0x0000FFFF, 0x0000FFFF); | ||
2573 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR5A, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2574 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR5B, 0x0000FFFF, 0x0000FFFF); | ||
2575 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR6A, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2576 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR6B, 0x0000FFFF, 0x0000FFFF); | ||
2577 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR7A, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2578 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR7B, 0x0000FFFF, 0x0000FFFF); | ||
2579 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR8A, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2580 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR8B, 0x0000FFFF, 0x0000FFFF); | ||
2581 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR9A, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2582 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR9B, 0x0000FFFF, 0x0000FFFF); | ||
2583 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR10A, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2584 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR10B, 0x0000FFFF, 0x0000FFFF); | ||
2585 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR11A, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2586 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR11B, 0x0000FFFF, 0x0000FFFF); | ||
2587 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR12A, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2588 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR12B, 0x0000FFFF, 0x0000FFFF); | ||
2589 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR13A, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2590 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR13B, 0x0000FFFF, 0x0000FFFF); | ||
2591 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR14A, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2592 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR14B, 0x0000FFFF, 0x0000FFFF); | ||
2593 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR15A, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2594 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR15B, 0x0000FFFF, 0x0000FFFF); | ||
2595 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR16A, 0xFFFFFFFF, 0xFFFFFFFF); | ||
2596 | + IOH_GBE_REG_PATTERN_TEST(MAC_ADR16B, 0x0000FFFF, 0x0000FFFF); | ||
2597 | + IOH_GBE_REG_PATTERN_TEST(ADDR_MASK, 0x0000FFFF, 0x0000FFFF); | ||
2598 | + IOH_GBE_REG_PATTERN_TEST(RGMII_CTRL, 0x0000001F, 0x0000001F); | ||
2599 | + IOH_GBE_REG_PATTERN_TEST(DMA_CTRL, 0x00000003, 0x00000003); | ||
2600 | + IOH_GBE_REG_PATTERN_TEST(RX_DSC_BASE, 0xFFFFFFF0, 0xFFFFFFF0); | ||
2601 | + IOH_GBE_REG_PATTERN_TEST(RX_DSC_SIZE, 0x0000FFF0, 0x0000FFF0); | ||
2602 | + IOH_GBE_REG_PATTERN_TEST(RX_DSC_HW_P, 0xFFFFFFF0, 0xFFFFFFF0); | ||
2603 | + IOH_GBE_REG_PATTERN_TEST(RX_DSC_SW_P, 0xFFFFFFF0, 0xFFFFFFF0); | ||
2604 | + IOH_GBE_REG_PATTERN_TEST(TX_DSC_BASE, 0xFFFFFFF0, 0xFFFFFFF0); | ||
2605 | + IOH_GBE_REG_PATTERN_TEST(TX_DSC_SIZE, 0x0000FFF0, 0x0000FFF0); | ||
2606 | + IOH_GBE_REG_PATTERN_TEST(TX_DSC_HW_P, 0xFFFFFFF0, 0xFFFFFFF0); | ||
2607 | + IOH_GBE_REG_PATTERN_TEST(TX_DSC_SW_P, 0xFFFFFFF0, 0xFFFFFFF0); | ||
2608 | + IOH_GBE_REG_PATTERN_TEST(WOL_ST, 0x0000000F, 0x0000000F); | ||
2609 | + IOH_GBE_REG_PATTERN_TEST(WOL_CTRL, 0x0001017F, 0x0001017F); | ||
2610 | + IOH_GBE_REG_PATTERN_TEST(WOL_ADDR_MASK, 0x0000FFFF, 0x0000FFFF); | ||
2611 | + | ||
2612 | + *data = 0; | ||
2613 | + return IOH_GBE_SUCCESS; | ||
2614 | +} | ||
2615 | + | ||
2616 | +/*! | ||
2617 | + * @ingroup Ethtool driver internal functions | ||
2618 | + * @fn static bool reg_pattern_test(struct ioh_gbe_adapter *adapter, | ||
2619 | + * uint64_t *data, int reg, | ||
2620 | + * uint32_t mask, uint32_t write) | ||
2621 | + * @brief Register pattern test | ||
2622 | + * @param adapter [IN] Board private structure | ||
2623 | + * @param data [INOUT] Pointer to test result data | ||
2624 | + * @param reg [INOUT] Register address | ||
2625 | + * @param mask [INOUT] Mask pattern | ||
2626 | + * @param write [INOUT] Write data | ||
2627 | + * @return true : Successfully | ||
2628 | + * @return false : Failed | ||
2629 | + */ | ||
2630 | +static bool | ||
2631 | +reg_pattern_test(struct ioh_gbe_adapter *adapter, | ||
2632 | + uint64_t *data, int reg, uint32_t mask, uint32_t write) | ||
2633 | +{ | ||
2634 | + static const uint32_t test[] = { | ||
2635 | + 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF | ||
2636 | + }; | ||
2637 | + uint8_t __iomem *address = adapter->hw.hw_addr + reg; | ||
2638 | + uint32_t read; | ||
2639 | + int i; | ||
2640 | + | ||
2641 | + for (i = 0; i < ARRAY_SIZE(test); i++) { | ||
2642 | + writel(write & test[i], address); | ||
2643 | + read = (readl(address) & mask); | ||
2644 | + if (read != (write & test[i] & mask)) { | ||
2645 | + DPRINTK(DRV, ERR, "pattern test reg %04X failed: " | ||
2646 | + "got 0x%08X expected 0x%08X\n", | ||
2647 | + reg, read, (write & test[i] & mask)); | ||
2648 | + *data = reg; | ||
2649 | + return true; | ||
2650 | + } | ||
2651 | + } | ||
2652 | + return false; | ||
2653 | +} | ||
2654 | diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe.h topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe.h | ||
2655 | --- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe.h 1970-01-01 09:00:00.000000000 +0900 | ||
2656 | +++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe.h 2010-03-09 09:27:26.000000000 +0900 | ||
2657 | @@ -0,0 +1,230 @@ | ||
2658 | +/*! | ||
2659 | + * @file ioh_gbe.h | ||
2660 | + * @brief Linux IOH Gigabit Ethernet Driver main header file | ||
2661 | + * | ||
2662 | + * @version 0.90 | ||
2663 | + * | ||
2664 | + * @section | ||
2665 | + * This program is free software; you can redistribute it and/or modify | ||
2666 | + * it under the terms of the GNU General Public License as published by | ||
2667 | + * the Free Software Foundation; version 2 of the License. | ||
2668 | + * | ||
2669 | + * This program is distributed in the hope that it will be useful, | ||
2670 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2671 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2672 | + * GNU General Public License for more details. | ||
2673 | + * | ||
2674 | + * You should have received a copy of the GNU General Public License | ||
2675 | + * along with this program; if not, write to the Free Software | ||
2676 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
2677 | + */ | ||
2678 | + | ||
2679 | +/* | ||
2680 | + * History: | ||
2681 | + * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD. | ||
2682 | + * All rights reserved. | ||
2683 | + * | ||
2684 | + * created: | ||
2685 | + * OKI SEMICONDUCTOR 09/21/2009 | ||
2686 | + * modified: | ||
2687 | + * | ||
2688 | + */ | ||
2689 | + | ||
2690 | +#ifndef _IOH_GBE_H_ | ||
2691 | +#define _IOH_GBE_H_ | ||
2692 | + | ||
2693 | +struct ioh_gbe_adapter; | ||
2694 | + | ||
2695 | +#define PFX "ioh_gbe: " | ||
2696 | +#define DPRINTK(nlevel, klevel, fmt, args...) \ | ||
2697 | + do { \ | ||
2698 | + if (printk_ratelimit()) \ | ||
2699 | + (void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \ | ||
2700 | + printk(KERN_##klevel PFX "%s: %s: " fmt, \ | ||
2701 | + adapter->netdev->name, __func__ , ## args)); \ | ||
2702 | + } while (0) | ||
2703 | + | ||
2704 | +/* only works for sizes that are powers of 2 */ | ||
2705 | +#define IOH_GBE_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1))) | ||
2706 | + | ||
2707 | +/*! | ||
2708 | + * @ingroup Gigabit Ether driver Layer | ||
2709 | + * @struct ioh_gbe_buffer | ||
2710 | + * @brief Buffer infomation | ||
2711 | + * @remarks | ||
2712 | + * wrapper around a pointer to a socket buffer, | ||
2713 | + * so a DMA handle can be stored along with the buffer | ||
2714 | + */ | ||
2715 | +struct ioh_gbe_buffer { | ||
2716 | + struct sk_buff *skb; /**< pointer to a socket buffer */ | ||
2717 | + struct sk_buff *kernel_skb; | ||
2718 | + /**< pointer to a socket buffer received from the kernel */ | ||
2719 | + dma_addr_t dma; /**< DMA address */ | ||
2720 | + unsigned long time_stamp; /**< time stamp */ | ||
2721 | + u16 length; /**< data size */ | ||
2722 | +}; | ||
2723 | + | ||
2724 | +/*! | ||
2725 | + * @ingroup Gigabit Ether driver Layer | ||
2726 | + * @struct ioh_gbe_tx_ring | ||
2727 | + * @brief tx ring infomation | ||
2728 | + */ | ||
2729 | +struct ioh_gbe_tx_ring { | ||
2730 | + void *desc; /**< pointer to the descriptor ring memory */ | ||
2731 | + dma_addr_t dma; /**< physical address of the descriptor ring */ | ||
2732 | + unsigned int size; /**< length of descriptor ring in bytes */ | ||
2733 | + unsigned int count; /**< number of descriptors in the ring */ | ||
2734 | + unsigned int next_to_use; | ||
2735 | + /**< next descriptor to associate a buffer with */ | ||
2736 | + unsigned int next_to_clean; | ||
2737 | + /**< next descriptor to check for DD status bit */ | ||
2738 | + struct ioh_gbe_buffer *buffer_info; | ||
2739 | + /**< array of buffer information structs */ | ||
2740 | + spinlock_t tx_lock; /**< spinlock structs */ | ||
2741 | +}; | ||
2742 | + | ||
2743 | +/*! | ||
2744 | + * @ingroup Gigabit Ether driver Layer | ||
2745 | + * @struct ioh_gbe_rx_ring | ||
2746 | + * @brief rx ring infomation | ||
2747 | + */ | ||
2748 | +struct ioh_gbe_rx_ring { | ||
2749 | + void *desc; /**< pointer to the descriptor ring memory */ | ||
2750 | + dma_addr_t dma; /**< physical address of the descriptor ring */ | ||
2751 | + unsigned int size; /**< length of descriptor ring in bytes */ | ||
2752 | + unsigned int count; /**< number of descriptors in the ring */ | ||
2753 | + unsigned int next_to_use; | ||
2754 | + /**< next descriptor to associate a buffer with */ | ||
2755 | + unsigned int next_to_clean; | ||
2756 | + /**< next descriptor to check for DD status bit */ | ||
2757 | + struct ioh_gbe_buffer *buffer_info; | ||
2758 | + /**< array of buffer information structs */ | ||
2759 | +}; | ||
2760 | + | ||
2761 | +/*! | ||
2762 | + * @ingroup Gigabit Ether driver Layer | ||
2763 | + * @struct ioh_gbe_hw_stats | ||
2764 | + * @brief Statistics counters collected by the MAC | ||
2765 | + */ | ||
2766 | +struct ioh_gbe_hw_stats { | ||
2767 | + u64 rx_packets; /**< total packets received */ | ||
2768 | + u64 tx_packets; /**< total packets transmitted */ | ||
2769 | + u64 rx_bytes; /**< total bytes received */ | ||
2770 | + u64 tx_bytes; /**< total bytes transmitted */ | ||
2771 | + u64 rx_errors; /**< bad packets received */ | ||
2772 | + u64 tx_errors; /**< packet transmit problems */ | ||
2773 | + u64 rx_dropped; /**< no space in Linux buffers */ | ||
2774 | + u64 tx_dropped; /**< no space available in Linux */ | ||
2775 | + u64 multicast; /**< multicast packets received */ | ||
2776 | + u64 collisions; /**< collisions */ | ||
2777 | + u64 rx_crc_errors; /**< received packet with crc error */ | ||
2778 | + u64 rx_frame_errors; /**< received frame alignment error */ | ||
2779 | + u64 rx_alloc_buff_failed; /**< allocate failure of a receive buffer */ | ||
2780 | + u64 tx_length_errors; /**< transmit length error */ | ||
2781 | + u64 tx_aborted_errors; /**< transmit aborted error */ | ||
2782 | + u64 tx_carrier_errors; /**< transmit carrier error */ | ||
2783 | + u64 tx_timeout_count; /**< Number of transmit timeout */ | ||
2784 | + u64 tx_restart_count; /**< Number of transmit restert */ | ||
2785 | + u64 intr_rx_dsc_empty_count; | ||
2786 | + /**< Interrupt count of receive descriptor empty */ | ||
2787 | + u64 intr_rx_frame_err_count; | ||
2788 | + /**< Interrupt count of receive frame error */ | ||
2789 | + u64 intr_rx_fifo_err_count; | ||
2790 | + /**< Interrupt count of receive FIFO error */ | ||
2791 | + u64 intr_rx_dma_err_count; | ||
2792 | + /**< Interrupt count of receive DMA error */ | ||
2793 | + u64 intr_tx_fifo_err_count; | ||
2794 | + /**< Interrupt count of transmit FIFO error */ | ||
2795 | + u64 intr_tx_dma_err_count; | ||
2796 | + /**< Interrupt count of transmit DMA error */ | ||
2797 | + u64 intr_tcpip_err_count; | ||
2798 | + /**< Interrupt count of TCP/IP Accelerator */ | ||
2799 | +}; | ||
2800 | + | ||
2801 | +/*! | ||
2802 | + * @ingroup Gigabit Ether driver Layer | ||
2803 | + * @struct ioh_gbe_adapter | ||
2804 | + * @brief board specific private data structure | ||
2805 | + */ | ||
2806 | +struct ioh_gbe_adapter { | ||
2807 | + /* OS defined structs */ | ||
2808 | + struct net_device *netdev; /**< Pointer of network device structure */ | ||
2809 | + struct pci_dev *pdev; /**< Pointer of pci device structure */ | ||
2810 | + struct net_device_stats net_stats; /**< Network status */ | ||
2811 | + struct net_device *polling_netdev; | ||
2812 | + /**< Pointer of polling network device structure */ | ||
2813 | + struct napi_struct napi; /**< NAPI structure */ | ||
2814 | + | ||
2815 | + /* structs defined in ioh_gbe_hw.h */ | ||
2816 | + struct ioh_gbe_hw hw; /**< Pointer of hardware structure */ | ||
2817 | + struct ioh_gbe_hw_stats stats; /**< Hardware status */ | ||
2818 | + struct work_struct reset_task; /**< Reset task */ | ||
2819 | + struct mii_if_info mii; /**< MII information structure */ | ||
2820 | + struct timer_list watchdog_timer; /**< Watchdog timer list */ | ||
2821 | + | ||
2822 | + u32 bd_number; /**< The number of the found NIC cards */ | ||
2823 | + u32 wake_up_evt; /**< Wake up event */ | ||
2824 | + u32 *config_space; /**< Configuration space */ | ||
2825 | + int msg_enable; /**< Driver message level */ | ||
2826 | + | ||
2827 | + spinlock_t stats_lock; /**< Spinlock structure for status */ | ||
2828 | + spinlock_t tx_queue_lock; /**< Spinlock structure for transmit */ | ||
2829 | + spinlock_t int_en_lock; /**< Spinlock structure for IRQ enable */ | ||
2830 | + atomic_t irq_sem; /**< Semaphore for interrupt */ | ||
2831 | + | ||
2832 | + struct timer_list blink_timer; /**< LED blink timer list */ | ||
2833 | + unsigned long led_status; /**< LED status */ | ||
2834 | + | ||
2835 | + /* TX,RX */ | ||
2836 | + struct ioh_gbe_tx_ring *tx_ring; | ||
2837 | + /**< Pointer of Tx descriptor ring structure */ | ||
2838 | + struct ioh_gbe_rx_ring *rx_ring; | ||
2839 | + /**< Pointer of Rx descriptor ring structure */ | ||
2840 | + unsigned long rx_buffer_len; /**< Receive buffer length */ | ||
2841 | + unsigned long tx_queue_len; /**< Transmit queue length */ | ||
2842 | + | ||
2843 | + unsigned char rx_csum; | ||
2844 | + /**< Receive TCP/IP checksum enable/disable */ | ||
2845 | + unsigned char tx_csum; | ||
2846 | + /**< Transmit TCP/IP checksum enable/disable */ | ||
2847 | + | ||
2848 | + unsigned char have_msi; /**< PCI MSI mode flag */ | ||
2849 | + | ||
2850 | + /* to not mess up cache alignment, always add to the bottom */ | ||
2851 | + unsigned long flags; /**< Driver status flag */ | ||
2852 | +}; | ||
2853 | + | ||
2854 | +/*! | ||
2855 | + * @ingroup Gigabit Ether driver Layer | ||
2856 | + * @def ioh_gbe_state_t | ||
2857 | + * @brief Driver Status | ||
2858 | + */ | ||
2859 | +enum ioh_gbe_state_t { | ||
2860 | + __IOH_GBE_TESTING, /**< Testing */ | ||
2861 | + __IOH_GBE_RESETTING, /**< Reseting */ | ||
2862 | +}; | ||
2863 | + | ||
2864 | +/* pch_gbe_main.c */ | ||
2865 | +int ioh_gbe_up(struct ioh_gbe_adapter *adapter); | ||
2866 | +void ioh_gbe_down(struct ioh_gbe_adapter *adapter); | ||
2867 | +void ioh_gbe_reinit_locked(struct ioh_gbe_adapter *adapter); | ||
2868 | +void ioh_gbe_reset(struct ioh_gbe_adapter *adapter); | ||
2869 | +int ioh_gbe_setup_tx_resources(struct ioh_gbe_adapter *adapter, | ||
2870 | + struct ioh_gbe_tx_ring *txdr); | ||
2871 | +int ioh_gbe_setup_rx_resources(struct ioh_gbe_adapter *adapter, | ||
2872 | + struct ioh_gbe_rx_ring *rxdr); | ||
2873 | +void ioh_gbe_free_tx_resources(struct ioh_gbe_adapter *adapter, | ||
2874 | + struct ioh_gbe_tx_ring *tx_ring); | ||
2875 | +void ioh_gbe_free_rx_resources(struct ioh_gbe_adapter *adapter, | ||
2876 | + struct ioh_gbe_rx_ring *rx_ring); | ||
2877 | +void ioh_gbe_update_stats(struct ioh_gbe_adapter *adapter); | ||
2878 | +int ioh_gbe_mdio_read(struct net_device *netdev, int addr, int reg); | ||
2879 | +void ioh_gbe_mdio_write(struct net_device *netdev, int addr, int reg, int data); | ||
2880 | +/* ioh_gbe_param.c */ | ||
2881 | +void ioh_gbe_check_options(struct ioh_gbe_adapter *adapter); | ||
2882 | + | ||
2883 | +/* ioh_gbe_ethtool.c */ | ||
2884 | +void ioh_gbe_set_ethtool_ops(struct net_device *netdev); | ||
2885 | + | ||
2886 | + | ||
2887 | +#endif /* _IOH_GBE_H_ */ | ||
2888 | diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_hw.h topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_hw.h | ||
2889 | --- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_hw.h 1970-01-01 09:00:00.000000000 +0900 | ||
2890 | +++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_hw.h 2010-03-11 15:11:49.000000000 +0900 | ||
2891 | @@ -0,0 +1,259 @@ | ||
2892 | +/*! | ||
2893 | + * @file ioh_gbe_hw.h | ||
2894 | + * @brief Linux IOH Gigabit Ethernet Driver Hardware layer header file | ||
2895 | + * | ||
2896 | + * @version 0.90 | ||
2897 | + * | ||
2898 | + * @section | ||
2899 | + * This program is free software; you can redistribute it and/or modify | ||
2900 | + * it under the terms of the GNU General Public License as published by | ||
2901 | + * the Free Software Foundation; version 2 of the License. | ||
2902 | + * | ||
2903 | + * This program is distributed in the hope that it will be useful, | ||
2904 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2905 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2906 | + * GNU General Public License for more details. | ||
2907 | + * | ||
2908 | + * You should have received a copy of the GNU General Public License | ||
2909 | + * along with this program; if not, write to the Free Software | ||
2910 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
2911 | + */ | ||
2912 | + | ||
2913 | +/* | ||
2914 | + * History: | ||
2915 | + * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD. | ||
2916 | + * All rights reserved. | ||
2917 | + * | ||
2918 | + * created: | ||
2919 | + * OKI SEMICONDUCTOR 09/21/2009 | ||
2920 | + * modified: | ||
2921 | + * | ||
2922 | + */ | ||
2923 | +#ifndef _IOH_GBE_HW_H_ | ||
2924 | +#define _IOH_GBE_HW_H_ | ||
2925 | + | ||
2926 | +struct ioh_gbe_hw; | ||
2927 | + | ||
2928 | +/* mac type values */ | ||
2929 | +#define IOH_GBE_MAC_TYPE_UNDEFINED 0 | ||
2930 | +#define IOH_GBE_MAC_TYPE_IOH1 1 | ||
2931 | +#define IOH_GBE_MAC_TYPE_IOH2 2 | ||
2932 | + | ||
2933 | +/* bus type values */ | ||
2934 | +#define ioh_gbe_bus_type_unknown 0 | ||
2935 | +#define ioh_gbe_bus_type_pci 1 | ||
2936 | +#define ioh_gbe_bus_type_pcix 2 | ||
2937 | +#define ioh_gbe_bus_type_pci_express 3 | ||
2938 | +#define ioh_gbe_bus_type_reserved 4 | ||
2939 | + | ||
2940 | +/* bus speed values */ | ||
2941 | +#define ioh_gbe_bus_speed_unknown 0 | ||
2942 | +#define ioh_gbe_bus_speed_33 1 | ||
2943 | +#define ioh_gbe_bus_speed_66 2 | ||
2944 | +#define ioh_gbe_bus_speed_100 3 | ||
2945 | +#define ioh_gbe_bus_speed_120 4 | ||
2946 | +#define ioh_gbe_bus_speed_133 5 | ||
2947 | +#define ioh_gbe_bus_speed_2500 6 | ||
2948 | +#define ioh_gbe_bus_speed_reserved 7 | ||
2949 | + | ||
2950 | +/* bus width values */ | ||
2951 | +#define ioh_gbe_bus_width_unknown 0 | ||
2952 | +#define ioh_gbe_bus_width_pcie_x1 1 | ||
2953 | +#define ioh_gbe_bus_width_pcie_x2 2 | ||
2954 | +#define ioh_gbe_bus_width_pcie_x4 4 | ||
2955 | +#define ioh_gbe_bus_width_32 5 | ||
2956 | +#define ioh_gbe_bus_width_64 6 | ||
2957 | +#define ioh_gbe_bus_width_reserved 7 | ||
2958 | + | ||
2959 | +/* flow control values */ | ||
2960 | +#define ioh_gbe_fc_none 0 | ||
2961 | +#define ioh_gbe_fc_rx_pause 1 | ||
2962 | +#define ioh_gbe_fc_tx_pause 2 | ||
2963 | +#define ioh_gbe_fc_full 3 | ||
2964 | + | ||
2965 | +#define IOH_GBE_FC_DEFAULT ioh_gbe_fc_full | ||
2966 | + | ||
2967 | +/*! | ||
2968 | + * @ingroup Gigabit Ether driver Layer | ||
2969 | + * @struct ioh_gbe_rx_desc | ||
2970 | + * @brief Receive Descriptor | ||
2971 | + */ | ||
2972 | +struct ioh_gbe_rx_desc { | ||
2973 | + u32 buffer_addr; /** RX Frame Buffer Address */ | ||
2974 | + u32 tcp_ip_status; /** TCP/IP Accelerator Status */ | ||
2975 | + u16 rx_words_eob; /** RX word count and Byte position */ | ||
2976 | + u16 gbec_status; /** GMAC Status */ | ||
2977 | + u8 dma_status; /** DMA Status */ | ||
2978 | + u8 reserved1; /** Reserved */ | ||
2979 | + u16 reserved2; /** Reserved */ | ||
2980 | +}; | ||
2981 | + | ||
2982 | +/*! | ||
2983 | + * @ingroup Gigabit Ether driver Layer | ||
2984 | + * @struct ioh_gbe_tx_desc | ||
2985 | + * @brief Transmit Descriptor | ||
2986 | + */ | ||
2987 | +struct ioh_gbe_tx_desc { | ||
2988 | + u32 buffer_addr; /** TX Frame Buffer Address */ | ||
2989 | + u16 length; /** Data buffer length */ | ||
2990 | + u16 reserved1; /** Reserved */ | ||
2991 | + u16 tx_words_eob; /** TX word count and Byte position */ | ||
2992 | + u16 tx_frame_ctrl; /** TX Frame Control */ | ||
2993 | + u8 dma_status; /** DMA Status */ | ||
2994 | + u8 reserved2; /** Reserved */ | ||
2995 | + u16 gbec_status; /** GMAC Status */ | ||
2996 | +}; | ||
2997 | + | ||
2998 | +/*! | ||
2999 | + * @ingroup Gigabit Ether driver Layer | ||
3000 | + * @struct ioh_gbe_functions | ||
3001 | + * @brief HAL APi function pointer | ||
3002 | + */ | ||
3003 | +struct ioh_gbe_functions { | ||
3004 | + /* Function pointers for the MAC. */ | ||
3005 | + s32(*cleanup_led) (struct ioh_gbe_hw *); | ||
3006 | + /** for ioh_gbe_hal_cleanup_led */ | ||
3007 | + | ||
3008 | + void (*get_bus_info) (struct ioh_gbe_hw *); | ||
3009 | + /** for ioh_gbe_hal_get_bus_info */ | ||
3010 | + | ||
3011 | + s32(*led_on) (struct ioh_gbe_hw *); | ||
3012 | + /** for ioh_gbe_hal_led_on */ | ||
3013 | + | ||
3014 | + s32(*led_off) (struct ioh_gbe_hw *); | ||
3015 | + /** for ioh_gbe_hal_led_off */ | ||
3016 | + | ||
3017 | + void (*mc_addr_list_update) (struct ioh_gbe_hw *, u8 *, u32, u32, u32); | ||
3018 | + /** for ioh_gbe_hal_mc_addr_list_update */ | ||
3019 | + | ||
3020 | + void (*reset_hw) (struct ioh_gbe_hw *); | ||
3021 | + /** for ioh_gbe_hal_reset_hw */ | ||
3022 | + | ||
3023 | + s32(*init_hw) (struct ioh_gbe_hw *); | ||
3024 | + /** for ioh_gbe_hal_init_hw */ | ||
3025 | + | ||
3026 | + s32(*setup_link) (struct ioh_gbe_hw *); | ||
3027 | + /** for ioh_gbe_hal_setup_link */ | ||
3028 | + | ||
3029 | + s32(*setup_physical_interface) (struct ioh_gbe_hw *); | ||
3030 | + /** for setup link of PHY */ | ||
3031 | + | ||
3032 | + s32(*setup_led) (struct ioh_gbe_hw *); | ||
3033 | + /** for ioh_gbe_hal_setup_led */ | ||
3034 | + | ||
3035 | + void (*pause_packet) (struct ioh_gbe_hw *); | ||
3036 | + /** for ioh_gbe_hal_set_pause_packet */ | ||
3037 | + | ||
3038 | + /* Function pointers for the PHY. */ | ||
3039 | + s32(*read_phy_reg) (struct ioh_gbe_hw *, u32, u16 *); | ||
3040 | + /** for ioh_gbe_hal_read_phy_reg */ | ||
3041 | + | ||
3042 | + s32(*write_phy_reg) (struct ioh_gbe_hw *, u32, u16); | ||
3043 | + /** for ioh_gbe_hal_write_phy_reg */ | ||
3044 | + | ||
3045 | + void (*reset_phy) (struct ioh_gbe_hw *); | ||
3046 | + /** for ioh_gbe_hal_phy_hw_reset */ | ||
3047 | + | ||
3048 | + void (*sw_reset_phy) (struct ioh_gbe_hw *); | ||
3049 | + /** for ioh_gbe_hal_phy_sw_reset */ | ||
3050 | + | ||
3051 | + void (*power_up_phy) (struct ioh_gbe_hw *hw); | ||
3052 | + /** for ioh_gbe_hal_power_up_phy */ | ||
3053 | + | ||
3054 | + void (*power_down_phy) (struct ioh_gbe_hw *hw); | ||
3055 | + /** for ioh_gbe_hal_power_down_phy */ | ||
3056 | +#ifdef CONFIG_PCH_PCIEQOS | ||
3057 | + /* Function pointers for the NVM. */ | ||
3058 | + s32(*validate_nvm) (struct ioh_gbe_hw *); | ||
3059 | + /** for ioh_gbe_hal_validate_nvm_checksum */ | ||
3060 | + | ||
3061 | + s32(*read_nvm) (struct ioh_gbe_hw *, u32, u8 *); | ||
3062 | + /** for ioh_gbe_hal_read_nvm */ | ||
3063 | + | ||
3064 | + s32(*write_nvm) (struct ioh_gbe_hw *, u32, u8 *); | ||
3065 | + /** for ioh_gbe_hal_write_nvm */ | ||
3066 | +#endif | ||
3067 | + s32(*read_mac_addr) (struct ioh_gbe_hw *); | ||
3068 | + /** for ioh_gbe_hal_read_mac_addr */ | ||
3069 | + | ||
3070 | + u16(*ctrl_miim) (struct ioh_gbe_hw *, u32, u32, u32, u16); | ||
3071 | + /** for ioh_gbe_hal_ctrl_miim */ | ||
3072 | +}; | ||
3073 | + | ||
3074 | +/*! | ||
3075 | + * @ingroup Gigabit Ether driver Layer | ||
3076 | + * @struct ioh_gbe_mac_info | ||
3077 | + * @brief MAC infomation | ||
3078 | + */ | ||
3079 | +struct ioh_gbe_mac_info { | ||
3080 | + u8 addr[6]; /** Store the MAC address */ | ||
3081 | + u8 type; /** Type of MAC */ | ||
3082 | + u8 fc; /** Mode of flow control */ | ||
3083 | + u8 fc_autoneg; /** Auto negotiation enable for flow control setting */ | ||
3084 | + u8 tx_fc_enable; /** Enable flag of Transmit flow control */ | ||
3085 | + u32 max_frame_size; /** Max transmit frame size */ | ||
3086 | + u32 min_frame_size; /** Min transmit frame size */ | ||
3087 | + u16 mar_entry_count; /** Entry count of MAC address registers */ | ||
3088 | + u8 autoneg; /** Auto negotiation enable */ | ||
3089 | + u16 link_speed; /** Link speed */ | ||
3090 | + u16 link_duplex; /** Link duplex */ | ||
3091 | +}; | ||
3092 | + | ||
3093 | +/*! | ||
3094 | + * @ingroup Gigabit Ether driver Layer | ||
3095 | + * @struct ioh_gbe_phy_info | ||
3096 | + * @brief PHY infomation | ||
3097 | + */ | ||
3098 | +struct ioh_gbe_phy_info { | ||
3099 | + u32 addr; /** PHY address */ | ||
3100 | + u32 id; /** PHY's identifier */ | ||
3101 | + u32 revision; /** PHY's revision */ | ||
3102 | + u32 reset_delay_us; /** HW reset delay time[us] */ | ||
3103 | + u16 autoneg_advertised; /** Autoneg advertised */ | ||
3104 | +}; | ||
3105 | + | ||
3106 | +/*! | ||
3107 | + * @ingroup Gigabit Ether driver Layer | ||
3108 | + * @struct ioh_gbe_nvm_info | ||
3109 | + * @brief NVM infomation | ||
3110 | + */ | ||
3111 | +struct ioh_gbe_nvm_info { | ||
3112 | + u16 word_size; | ||
3113 | +}; | ||
3114 | + | ||
3115 | +/*! | ||
3116 | + * @ingroup Gigabit Ether driver Layer | ||
3117 | + * @struct ioh_gbe_bus_info | ||
3118 | + * @brief Bus infomation | ||
3119 | + */ | ||
3120 | +struct ioh_gbe_bus_info { | ||
3121 | + u8 type; | ||
3122 | + u8 speed; | ||
3123 | + u8 width; | ||
3124 | +}; | ||
3125 | + | ||
3126 | +/*! | ||
3127 | + * @ingroup Gigabit Ether driver Layer | ||
3128 | + * @struct ioh_gbe_hw | ||
3129 | + * @brief Hardware infomation | ||
3130 | + */ | ||
3131 | +struct ioh_gbe_hw { | ||
3132 | + void *back; | ||
3133 | + | ||
3134 | + u8 *hw_addr; | ||
3135 | + spinlock_t miim_lock; | ||
3136 | + | ||
3137 | + struct ioh_gbe_functions func; | ||
3138 | + struct ioh_gbe_mac_info mac; | ||
3139 | + struct ioh_gbe_phy_info phy; | ||
3140 | + struct ioh_gbe_nvm_info nvm; | ||
3141 | + struct ioh_gbe_bus_info bus; | ||
3142 | + | ||
3143 | + u16 vendor_id; | ||
3144 | + u16 device_id; | ||
3145 | + u16 subsystem_vendor_id; | ||
3146 | + u16 subsystem_device_id; | ||
3147 | + u8 revision_id; | ||
3148 | +}; | ||
3149 | + | ||
3150 | +#endif | ||
3151 | diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_mac.c topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_mac.c | ||
3152 | --- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_mac.c 1970-01-01 09:00:00.000000000 +0900 | ||
3153 | +++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_mac.c 2010-03-11 15:11:58.000000000 +0900 | ||
3154 | @@ -0,0 +1,522 @@ | ||
3155 | +/*! | ||
3156 | + * @file ioh_gbe_mac.c | ||
3157 | + * @brief Linux IOH Gigabit Ethernet Driver HAL internal function (MAC) source file | ||
3158 | + * | ||
3159 | + * @version 0.90 | ||
3160 | + * | ||
3161 | + * @section | ||
3162 | + * This program is free software; you can redistribute it and/or modify | ||
3163 | + * it under the terms of the GNU General Public License as published by | ||
3164 | + * the Free Software Foundation; version 2 of the License. | ||
3165 | + * | ||
3166 | + * This program is distributed in the hope that it will be useful, | ||
3167 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3168 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3169 | + * GNU General Public License for more details. | ||
3170 | + * | ||
3171 | + * You should have received a copy of the GNU General Public License | ||
3172 | + * along with this program; if not, write to the Free Software | ||
3173 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
3174 | + */ | ||
3175 | + | ||
3176 | +/* | ||
3177 | + * History: | ||
3178 | + * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD. | ||
3179 | + * All rights reserved. | ||
3180 | + * | ||
3181 | + * created: | ||
3182 | + * OKI SEMICONDUCTOR 09/21/2009 | ||
3183 | + * modified: | ||
3184 | + * | ||
3185 | + */ | ||
3186 | +#include <linux/ethtool.h> | ||
3187 | +#include "pch_gbe_osdep.h" | ||
3188 | +#include "pch_gbe_regs.h" | ||
3189 | +#include "pch_gbe_defines.h" | ||
3190 | +#include "pch_gbe_hw.h" | ||
3191 | +#include "pch_gbe_mac.h" | ||
3192 | +#include "pch_gbe_api.h" | ||
3193 | + | ||
3194 | +/* Pause packet value */ | ||
3195 | +#define IOH_GBE_PAUSE_PKT1_VALUE 0x00C28001 | ||
3196 | +#define IOH_GBE_PAUSE_PKT2_VALUE 0x00000100 | ||
3197 | +#define IOH_GBE_PAUSE_PKT4_VALUE 0x01000888 | ||
3198 | +#define IOH_GBE_PAUSE_PKT5_VALUE 0x0000FFFF | ||
3199 | + | ||
3200 | +/*! | ||
3201 | + * @ingroup HAL internal function | ||
3202 | + * @fn void ioh_gbe_mac_reset_hw(struct ioh_gbe_hw *hw) | ||
3203 | + * @brief Reset hardware | ||
3204 | + * @param hw [INOUT] Pointer to the HW structure | ||
3205 | + * @return IOH_GBE_SUCCESS: Successfully | ||
3206 | + * @return Negative value: Failed | ||
3207 | + * @remarks | ||
3208 | + * This resets the hardware into a known state (Reset only MAC). | ||
3209 | + * This is a function pointer entry point called by the api module. | ||
3210 | + */ | ||
3211 | +void ioh_gbe_mac_reset_hw(struct ioh_gbe_hw *hw) | ||
3212 | +{ | ||
3213 | + u32 tmp = 0; | ||
3214 | + | ||
3215 | + IOH_GBE_DBGFUNC("ioh_gbe_mac_reset_hw"); | ||
3216 | + | ||
3217 | +#ifndef CONFIG_PCH_PCIEQOS | ||
3218 | + /* Read the MAC address. and store to the private data */ | ||
3219 | + ioh_gbe_mac_read_mac_addr(hw); | ||
3220 | +#endif | ||
3221 | + | ||
3222 | + IOH_GBE_WRITE_REG(hw, RESET, IOH_GBE_ALL_RST); | ||
3223 | +#ifdef IOH_GBE_MAC_IFOP_RGMII | ||
3224 | + IOH_GBE_WRITE_REG(hw, MODE, IOH_GBE_MODE_GMII_ETHER); | ||
3225 | +#endif | ||
3226 | + while ((IOH_GBE_READ_REG(hw, RESET)) != 0) { | ||
3227 | + udelay(1); | ||
3228 | + tmp++; | ||
3229 | + if (tmp == 5) { | ||
3230 | + IOH_GBE_ERR("MAC HW RESET\n"); | ||
3231 | + break; | ||
3232 | + } | ||
3233 | + } | ||
3234 | +#ifndef CONFIG_PCH_PCIEQOS | ||
3235 | + /* Setup the receive address */ | ||
3236 | + ioh_gbe_mac_mar_set(hw, hw->mac.addr, 0); | ||
3237 | +#endif | ||
3238 | + return; | ||
3239 | +} | ||
3240 | + | ||
3241 | +/*! | ||
3242 | + * @ingroup HAL internal function | ||
3243 | + * @fn void ioh_gbe_mac_init_rx_addrs(struct ioh_gbe_hw *hw, | ||
3244 | + * u16 mar_count) | ||
3245 | + * @brief Initialize receive address's | ||
3246 | + * @param hw [INOUT] Pointer to the HW structure | ||
3247 | + * @param mar_count [IN] Receive address registers | ||
3248 | + * @return None | ||
3249 | + * @remarks | ||
3250 | + * Setups the receive address registers by setting the base receive address | ||
3251 | + * register to the devices MAC address and clearing all the other receive | ||
3252 | + * address registers to 0. | ||
3253 | + * This is a function pointer entry point called by the api module. | ||
3254 | + */ | ||
3255 | +void ioh_gbe_mac_init_rx_addrs(struct ioh_gbe_hw *hw, u16 mar_count) | ||
3256 | +{ | ||
3257 | + u32 i; | ||
3258 | + | ||
3259 | + IOH_GBE_DBGFUNC("ioh_gbe_mac_init_rx_addrs"); | ||
3260 | + IOH_GBE_DBGOUT("Programming MAC Address into MAC_ADDR[0]\n"); | ||
3261 | + IOH_GBE_TESTOUT("Clearing MAC_ADDR[1-%u]\n", mar_count - 1); | ||
3262 | + | ||
3263 | + /* Setup the receive address */ | ||
3264 | + ioh_gbe_hal_mar_set(hw, hw->mac.addr, 0); | ||
3265 | + | ||
3266 | + /* Zero out the other (mar_entry_count - 1) receive addresses */ | ||
3267 | + for (i = 1; i < mar_count; i++) { | ||
3268 | + IOH_GBE_WRITE_REG_ARRAY(hw, MAC_ADR, (i << 1), 0); | ||
3269 | + IOH_GBE_WRITE_REG_ARRAY(hw, MAC_ADR, ((i << 1) + 1), 0); | ||
3270 | + } | ||
3271 | + IOH_GBE_WRITE_REG(hw, ADDR_MASK, 0xFFFE); | ||
3272 | + /* wait busy */ | ||
3273 | + while ((IOH_GBE_READ_REG(hw, ADDR_MASK) & IOH_GBE_BUSY) != 0) | ||
3274 | + ; | ||
3275 | +#ifdef DEBUG_TEST | ||
3276 | + { | ||
3277 | + unsigned char ti; | ||
3278 | + IOH_GBE_TESTOUT("ADDR_MASK reg(check index bit) : 0x%08x\n", | ||
3279 | + IOH_GBE_READ_REG(hw, ADDR_MASK)); | ||
3280 | + for (ti = 0; ti < 16; ti++) { | ||
3281 | + IOH_GBE_TESTOUT("MAC_ADR%dAB reg : 0x%08x 0x%08x\n", | ||
3282 | + (ti + 1), | ||
3283 | + IOH_GBE_READ_REG(hw, | ||
3284 | + MAC_ADR1A + | ||
3285 | + (0x08 * ti)), | ||
3286 | + IOH_GBE_READ_REG(hw, | ||
3287 | + MAC_ADR1B + | ||
3288 | + (0x08 * ti))); | ||
3289 | + } | ||
3290 | + } | ||
3291 | +#endif | ||
3292 | +} | ||
3293 | + | ||
3294 | +/*! | ||
3295 | + * @ingroup HAL internal function | ||
3296 | + * @fn void ioh_gbe_mac_mar_set(struct ioh_gbe_hw *hw, u8 *addr, u32 index) | ||
3297 | + * @brief Set MAC address register | ||
3298 | + * @param hw [INOUT] Pointer to the HW structure | ||
3299 | + * @param addr [IN] Pointer to the MAC address | ||
3300 | + * @param index [IN] MAC address array register | ||
3301 | + * @return None | ||
3302 | + */ | ||
3303 | +void ioh_gbe_mac_mar_set(struct ioh_gbe_hw *hw, u8 * addr, u32 index) | ||
3304 | +{ | ||
3305 | + u32 mar_low, mar_high, adrmask; | ||
3306 | + | ||
3307 | + IOH_GBE_DBGFUNC("ioh_gbe_mac_mar_set"); | ||
3308 | + IOH_GBE_TESTOUT("index : 0x%x\n", index); | ||
3309 | + | ||
3310 | + /* HW expects these in little endian so we reverse the byte order | ||
3311 | + * from network order (big endian) to little endian | ||
3312 | + */ | ||
3313 | + mar_low = ((u32) addr[0] | | ||
3314 | + ((u32) addr[1] << 8) | | ||
3315 | + ((u32) addr[2] << 16) | ((u32) addr[3] << 24)); | ||
3316 | + | ||
3317 | + mar_high = ((u32) addr[4] | ((u32) addr[5] << 8)); | ||
3318 | + /* Stop the MAC Address of index. */ | ||
3319 | + adrmask = IOH_GBE_READ_REG(hw, ADDR_MASK); | ||
3320 | + IOH_GBE_WRITE_REG(hw, ADDR_MASK, (adrmask | (0x0001 << index))); | ||
3321 | + | ||
3322 | + IOH_GBE_TESTOUT("ADDR_MASK reg : 0x%08x\n", adrmask); | ||
3323 | + IOH_GBE_TESTOUT("ADDR_MASK reg(check index bit) : 0x%08x\n", | ||
3324 | + IOH_GBE_READ_REG(hw, ADDR_MASK)); | ||
3325 | + /* wait busy */ | ||
3326 | + while ((IOH_GBE_READ_REG(hw, ADDR_MASK) & IOH_GBE_BUSY) != 0) | ||
3327 | + ; | ||
3328 | + IOH_GBE_TESTOUT("ADDR_MASK reg(check BUSY bit:1) : 0x%08x\n", | ||
3329 | + IOH_GBE_READ_REG(hw, ADDR_MASK)); | ||
3330 | + | ||
3331 | + /* Set the MAC address to the MAC address 1A/1B register */ | ||
3332 | + IOH_GBE_WRITE_REG_ARRAY(hw, MAC_ADR, (index << 1), mar_low); | ||
3333 | + IOH_GBE_WRITE_REG_ARRAY(hw, MAC_ADR, ((index << 1) + 1), mar_high); | ||
3334 | + /* Start the MAC address of index */ | ||
3335 | + IOH_GBE_WRITE_REG(hw, ADDR_MASK, (adrmask & ~(0x0001 << index))); | ||
3336 | + IOH_GBE_TESTOUT("ADDR_MASK reg(check index bit:0) : 0x%08x\n", | ||
3337 | + IOH_GBE_READ_REG(hw, ADDR_MASK)); | ||
3338 | + /* wait busy */ | ||
3339 | + while ((IOH_GBE_READ_REG(hw, ADDR_MASK) & IOH_GBE_BUSY) != 0) | ||
3340 | + ; | ||
3341 | + IOH_GBE_TESTOUT("ADDR_MASK reg(check BUSY bit) : 0x%08x\n", | ||
3342 | + IOH_GBE_READ_REG(hw, ADDR_MASK)); | ||
3343 | + IOH_GBE_DBGFUNC("ioh_gbe_mac_mar_set:End"); | ||
3344 | +} | ||
3345 | + | ||
3346 | +/*! | ||
3347 | + * @ingroup HAL internal function | ||
3348 | + * @fn void ioh_gbe_mac_mc_addr_list_update(struct ioh_gbe_hw *hw, | ||
3349 | + * u8 *mc_addr_list, u32 mc_addr_count, | ||
3350 | + * u32 mar_used_count, u32 mar_total_num) | ||
3351 | + * @brief Update Multicast addresses | ||
3352 | + * @param hw [INOUT] Pointer to the HW structure | ||
3353 | + * @param mc_addr_list [IN] Array of multicast addresses to program | ||
3354 | + * @param mc_addr_count [IN] Number of multicast addresses to program | ||
3355 | + * @param mar_used_count [IN] The first MAC Address register free to program | ||
3356 | + * @param mar_total_num [IN] Total number of supported MAC Address Registers | ||
3357 | + * @return None | ||
3358 | + */ | ||
3359 | +void | ||
3360 | +ioh_gbe_mac_mc_addr_list_update(struct ioh_gbe_hw *hw, | ||
3361 | + u8 *mc_addr_list, u32 mc_addr_count, | ||
3362 | + u32 mar_used_count, u32 mar_total_num) | ||
3363 | +{ | ||
3364 | + u32 i, adrmask; | ||
3365 | + | ||
3366 | + IOH_GBE_DBGFUNC("ioh_gbe_mac_mc_addr_list_update"); | ||
3367 | + | ||
3368 | +#ifdef DEBUG_TEST | ||
3369 | + { | ||
3370 | + u32 ti, tj; | ||
3371 | + IOH_GBE_TESTOUT | ||
3372 | + ("mc_addr_count = %d mar_used_count = %d " | ||
3373 | + "mar_total_num = %d\n", | ||
3374 | + mc_addr_count, mar_used_count, mar_total_num); | ||
3375 | + for (ti = 0; ti < mc_addr_count; ti++) { | ||
3376 | + tj = ti * IOH_GBE_ETH_ALEN; | ||
3377 | + IOH_GBE_TESTOUT | ||
3378 | + ("mc_addr_list[%d] = 0x%02x %02x %02x " | ||
3379 | + "%02x %02x %02x \n", | ||
3380 | + ti, mc_addr_list[tj], mc_addr_list[tj + 1], | ||
3381 | + mc_addr_list[tj + 2], mc_addr_list[tj + 3], | ||
3382 | + mc_addr_list[tj + 4], mc_addr_list[tj + 5]); | ||
3383 | + } | ||
3384 | + } | ||
3385 | +#endif | ||
3386 | + /* Load the first set of multicast addresses into the exact | ||
3387 | + * filters (RAR). If there are not enough to fill the RAR | ||
3388 | + * array, clear the filters. | ||
3389 | + */ | ||
3390 | + for (i = mar_used_count; i < mar_total_num; i++) { | ||
3391 | + if (mc_addr_count != 0) { | ||
3392 | + ioh_gbe_mac_mar_set(hw, mc_addr_list, i); | ||
3393 | + mc_addr_count--; | ||
3394 | + mc_addr_list += IOH_GBE_ETH_ALEN; | ||
3395 | + } else { | ||
3396 | + /* Clear MAC address mask */ | ||
3397 | + adrmask = IOH_GBE_READ_REG(hw, ADDR_MASK); | ||
3398 | + IOH_GBE_WRITE_REG(hw, ADDR_MASK, | ||
3399 | + (adrmask | (0x0001 << i))); | ||
3400 | + /* wait busy */ | ||
3401 | + while ((IOH_GBE_READ_REG(hw, ADDR_MASK) & IOH_GBE_BUSY) | ||
3402 | + != 0) { | ||
3403 | + ; | ||
3404 | + } | ||
3405 | + /* Clear MAC address */ | ||
3406 | + IOH_GBE_WRITE_REG_ARRAY(hw, MAC_ADR, i << 1, 0); | ||
3407 | + IOH_GBE_WRITE_REG_ARRAY(hw, MAC_ADR, (i << 1) + 1, 0); | ||
3408 | + } | ||
3409 | + } | ||
3410 | +#ifdef DEBUG_TEST | ||
3411 | + { | ||
3412 | + unsigned char ti; | ||
3413 | + IOH_GBE_TESTOUT("ADDR_MASK reg(check index bit) : 0x%08x\n", | ||
3414 | + IOH_GBE_READ_REG(hw, ADDR_MASK)); | ||
3415 | + for (ti = 0; ti < 16; ti++) { | ||
3416 | + IOH_GBE_TESTOUT("MAC_ADR%dAB reg : 0x%08x 0x%08x\n", | ||
3417 | + (ti + 1), | ||
3418 | + IOH_GBE_READ_REG(hw, | ||
3419 | + MAC_ADR1A + | ||
3420 | + (0x08 * ti)), | ||
3421 | + IOH_GBE_READ_REG(hw, | ||
3422 | + MAC_ADR1B + | ||
3423 | + (0x08 * ti))); | ||
3424 | + } | ||
3425 | + } | ||
3426 | +#endif | ||
3427 | +} | ||
3428 | + | ||
3429 | +/*! | ||
3430 | + * @ingroup HAL internal function | ||
3431 | + * @fn s32 ioh_gbe_mac_setup_link(struct ioh_gbe_hw *hw) | ||
3432 | + * @brief Setup flow control and link settings | ||
3433 | + * @param hw [INOUT] Pointer to the HW structure | ||
3434 | + * @return IOH_GBE_SUCCESS: Successfully | ||
3435 | + * @return Negative value: Failed | ||
3436 | + */ | ||
3437 | +s32 ioh_gbe_mac_setup_link(struct ioh_gbe_hw *hw) | ||
3438 | +{ | ||
3439 | + struct ioh_gbe_functions *func = &hw->func; | ||
3440 | + s32 ret_val = IOH_GBE_SUCCESS; | ||
3441 | + | ||
3442 | + IOH_GBE_DBGFUNC("ioh_gbe_mac_setup_link"); | ||
3443 | + | ||
3444 | + /* Call the necessary media_type subroutine to configure the link. */ | ||
3445 | + ret_val = func->setup_physical_interface(hw); | ||
3446 | + | ||
3447 | + return ret_val; | ||
3448 | +} | ||
3449 | + | ||
3450 | +/*! | ||
3451 | + * @ingroup HAL internal function | ||
3452 | + * @fn s32 ioh_gbe_mac_force_mac_fc(struct ioh_gbe_hw *hw) | ||
3453 | + * @brief Force the MAC's flow control settings | ||
3454 | + * @param hw [INOUT] Pointer to the HW structure | ||
3455 | + * @return IOH_GBE_SUCCESS: Successfully | ||
3456 | + * @return Negative value: Failed | ||
3457 | + */ | ||
3458 | +s32 ioh_gbe_mac_force_mac_fc(struct ioh_gbe_hw *hw) | ||
3459 | +{ | ||
3460 | + struct ioh_gbe_mac_info *mac = &hw->mac; | ||
3461 | + u32 rx_fctrl; | ||
3462 | + | ||
3463 | + IOH_GBE_DBGFUNC("ioh_gbe_mac_force_mac_fc"); | ||
3464 | + IOH_GBE_TESTOUT("mac->fc = %u\n", mac->fc); | ||
3465 | + | ||
3466 | + rx_fctrl = IOH_GBE_READ_REG(hw, RX_FCTRL); | ||
3467 | + | ||
3468 | + switch (mac->fc) { | ||
3469 | + case ioh_gbe_fc_none: | ||
3470 | + rx_fctrl &= ~IOH_GBE_FL_CTRL_EN; | ||
3471 | + mac->tx_fc_enable = FALSE; | ||
3472 | + break; | ||
3473 | + case ioh_gbe_fc_rx_pause: | ||
3474 | + rx_fctrl |= IOH_GBE_FL_CTRL_EN; | ||
3475 | + mac->tx_fc_enable = FALSE; | ||
3476 | + break; | ||
3477 | + case ioh_gbe_fc_tx_pause: | ||
3478 | + rx_fctrl &= ~IOH_GBE_FL_CTRL_EN; | ||
3479 | + mac->tx_fc_enable = TRUE; | ||
3480 | + break; | ||
3481 | + case ioh_gbe_fc_full: | ||
3482 | + rx_fctrl |= IOH_GBE_FL_CTRL_EN; | ||
3483 | + mac->tx_fc_enable = TRUE; | ||
3484 | + break; | ||
3485 | + default: | ||
3486 | + IOH_GBE_DBGOUT("Flow control param set incorrectly\n"); | ||
3487 | + return -IOH_GBE_ERR_CONFIG; | ||
3488 | + } | ||
3489 | + if (mac->link_duplex == DUPLEX_HALF) | ||
3490 | + rx_fctrl &= ~IOH_GBE_FL_CTRL_EN; | ||
3491 | + IOH_GBE_WRITE_REG(hw, RX_FCTRL, rx_fctrl); | ||
3492 | + IOH_GBE_TESTOUT("RX_FCTRL reg : 0x%08x mac->tx_fc_enable : %d\n", | ||
3493 | + IOH_GBE_READ_REG(hw, RX_FCTRL), mac->tx_fc_enable); | ||
3494 | + return IOH_GBE_SUCCESS; | ||
3495 | +} | ||
3496 | + | ||
3497 | +/*! | ||
3498 | + * @ingroup HAL internal function | ||
3499 | + * @fn s32 ioh_gbe_mac_config_fc_after_link_up(struct ioh_gbe_hw *hw) | ||
3500 | + * @brief Configures flow control after link | ||
3501 | + * @param hw [INOUT] Pointer to the HW structure | ||
3502 | + * @return IOH_GBE_SUCCESS: Successfully | ||
3503 | + */ | ||
3504 | +s32 ioh_gbe_mac_config_fc_after_link_up(struct ioh_gbe_hw *hw) | ||
3505 | +{ | ||
3506 | + IOH_GBE_DBGFUNC("ioh_gbe_mac_config_fc_after_link_up"); | ||
3507 | + return IOH_GBE_SUCCESS; | ||
3508 | +} | ||
3509 | + | ||
3510 | +/*! | ||
3511 | + * @ingroup HAL internal function | ||
3512 | + * @fn void ioh_gbe_mac_set_wol_event(struct ioh_gbe_hw *hw, u32 wu_evt) | ||
3513 | + * @brief Set wake-on-lan event | ||
3514 | + * @param hw [INOUT] Pointer to the HW structure | ||
3515 | + * @param wu_evt [IN] Wake up event | ||
3516 | + * @return None | ||
3517 | + */ | ||
3518 | +void ioh_gbe_mac_set_wol_event(struct ioh_gbe_hw *hw, u32 wu_evt) | ||
3519 | +{ | ||
3520 | + u32 addr_mask; | ||
3521 | + | ||
3522 | + IOH_GBE_DBGFUNC("ioh_gbe_mac_set_wol_event"); | ||
3523 | + IOH_GBE_TESTOUT("wu_evt : 0x%08x ADDR_MASK reg : 0x%08x\n", | ||
3524 | + wu_evt, IOH_GBE_READ_REG(hw, ADDR_MASK)); | ||
3525 | + | ||
3526 | + if (wu_evt != 0) { | ||
3527 | + /* Set Wake-On-Lan address mask */ | ||
3528 | + addr_mask = IOH_GBE_READ_REG(hw, ADDR_MASK); | ||
3529 | + IOH_GBE_WRITE_REG(hw, WOL_ADDR_MASK, addr_mask); | ||
3530 | + /* wait busy */ | ||
3531 | + while ((IOH_GBE_READ_REG(hw, WOL_ADDR_MASK) & IOH_GBE_WLA_BUSY) | ||
3532 | + != 0) { | ||
3533 | + ; | ||
3534 | + } | ||
3535 | + IOH_GBE_WRITE_REG(hw, WOL_ST, 0); | ||
3536 | + IOH_GBE_WRITE_REG(hw, WOL_CTRL, | ||
3537 | + (wu_evt | IOH_GBE_WLC_WOL_MODE)); | ||
3538 | + IOH_GBE_WRITE_REG(hw, INT_EN, IOH_GBE_INT_ENABLE_MASK); | ||
3539 | + } else { | ||
3540 | + IOH_GBE_WRITE_REG(hw, WOL_CTRL, 0); | ||
3541 | + IOH_GBE_WRITE_REG(hw, WOL_ST, 0); | ||
3542 | + } | ||
3543 | + | ||
3544 | +#ifdef DEBUG_TEST | ||
3545 | + IOH_GBE_TESTOUT | ||
3546 | + ("WOL_ADDR_MASK reg : 0x%08x WOL_CTRL reg : 0x%08x " | ||
3547 | + "WOL_ST reg : 0x%08x\n", | ||
3548 | + IOH_GBE_READ_REG(hw, WOL_ADDR_MASK), | ||
3549 | + IOH_GBE_READ_REG(hw, WOL_CTRL), | ||
3550 | + IOH_GBE_READ_REG(hw, WOL_ST)); | ||
3551 | +#endif | ||
3552 | + return; | ||
3553 | +} | ||
3554 | + | ||
3555 | +/*! | ||
3556 | + * @ingroup HAL internal function | ||
3557 | + * @fn u16 ioh_gbe_mac_ctrl_miim(struct ioh_gbe_hw *hw, u32 addr, | ||
3558 | + * u32 dir, u32 reg, u16 data) | ||
3559 | + * @brief Set wake-on-lan event | ||
3560 | + * @param hw [INOUT] Pointer to the HW structure | ||
3561 | + * @param addr [IN] Address of PHY | ||
3562 | + * @param dir [IN] Operetion. (Write or Read) | ||
3563 | + * @param reg [IN] Access register of PHY | ||
3564 | + * @param data [IN] Write data. | ||
3565 | + * @return IOH_GBE_SUCCESS: Successfully | ||
3566 | + * @return Negative value: Failed | ||
3567 | + */ | ||
3568 | +u16 | ||
3569 | +ioh_gbe_mac_ctrl_miim(struct ioh_gbe_hw *hw, u32 addr, u32 dir, u32 reg, | ||
3570 | + u16 data) | ||
3571 | +{ | ||
3572 | + u32 data_out = 0; | ||
3573 | + unsigned int i; | ||
3574 | + unsigned long flags; | ||
3575 | + | ||
3576 | + IOH_GBE_DBGOUT2("ioh_gbe_mac_ctrl_miim\n"); | ||
3577 | + spin_lock_irqsave(&hw->miim_lock, flags); | ||
3578 | + | ||
3579 | + for (i = 100; i; --i) { | ||
3580 | + if ((IOH_GBE_READ_REG(hw, MIIM) & IOH_GBE_MIIM_OPER_READY) != 0) | ||
3581 | + break; | ||
3582 | + udelay(20); | ||
3583 | + } | ||
3584 | + if (i == 0) { | ||
3585 | + IOH_GBE_DBGOUT("ioh-sample-gbe.miim won't go Ready\n"); | ||
3586 | + spin_unlock_irqrestore(&hw->miim_lock, flags); | ||
3587 | + return IOH_GBE_SUCCESS; /* No way to indicate timeout error */ | ||
3588 | + } | ||
3589 | + IOH_GBE_WRITE_REG(hw, MIIM, ((reg << IOH_GBE_MIIM_REG_ADDR_SHIFT) | | ||
3590 | + (addr << IOH_GBE_MIIM_PHY_ADDR_SHIFT) | | ||
3591 | + dir | data)); | ||
3592 | + for (i = 0; i < 100; i++) { | ||
3593 | + udelay(20); | ||
3594 | + data_out = IOH_GBE_READ_REG(hw, MIIM); | ||
3595 | + if ((data_out & IOH_GBE_MIIM_OPER_READY) != 0) | ||
3596 | + break; | ||
3597 | + } | ||
3598 | + spin_unlock_irqrestore(&hw->miim_lock, flags); | ||
3599 | + | ||
3600 | + IOH_GBE_DBGOUT1("%s:addr=%d, reg=%d, data_in=0x%04X, data_out=0x%04X\n", | ||
3601 | + dir == IOH_GBE_MIIM_OPER_READ ? "READ" : "WRITE", | ||
3602 | + addr, reg, data, data_out); | ||
3603 | + return (u16) data_out; | ||
3604 | +} | ||
3605 | + | ||
3606 | +/*! | ||
3607 | + * @ingroup HAL internal function | ||
3608 | + * @fn void ioh_gbe_mac_set_pause_packet(struct ioh_gbe_hw *hw) | ||
3609 | + * @brief Set pause packet | ||
3610 | + * @param hw [INOUT] Pointer to the HW structure | ||
3611 | + * @return None | ||
3612 | + */ | ||
3613 | +void ioh_gbe_mac_set_pause_packet(struct ioh_gbe_hw *hw) | ||
3614 | +{ | ||
3615 | + unsigned long tmp2, tmp3; | ||
3616 | + | ||
3617 | + IOH_GBE_DBGFUNC("ioh_gbe_mac_set_pause_packet"); | ||
3618 | + | ||
3619 | + /* Set Pause packet */ | ||
3620 | + tmp2 = hw->mac.addr[1]; | ||
3621 | + tmp2 = (tmp2 << 8) | hw->mac.addr[0]; | ||
3622 | + tmp2 = IOH_GBE_PAUSE_PKT2_VALUE | (tmp2 << 16); | ||
3623 | + | ||
3624 | + tmp3 = hw->mac.addr[5]; | ||
3625 | + tmp3 = (tmp3 << 8) | hw->mac.addr[4]; | ||
3626 | + tmp3 = (tmp3 << 8) | hw->mac.addr[3]; | ||
3627 | + tmp3 = (tmp3 << 8) | hw->mac.addr[2]; | ||
3628 | + | ||
3629 | + IOH_GBE_WRITE_REG(hw, PAUSE_PKT1, IOH_GBE_PAUSE_PKT1_VALUE); | ||
3630 | + IOH_GBE_WRITE_REG(hw, PAUSE_PKT2, tmp2); | ||
3631 | + IOH_GBE_WRITE_REG(hw, PAUSE_PKT3, tmp3); | ||
3632 | + IOH_GBE_WRITE_REG(hw, PAUSE_PKT4, IOH_GBE_PAUSE_PKT4_VALUE); | ||
3633 | + IOH_GBE_WRITE_REG(hw, PAUSE_PKT5, IOH_GBE_PAUSE_PKT5_VALUE); | ||
3634 | + | ||
3635 | + /* Transmit Pause Packet */ | ||
3636 | + IOH_GBE_WRITE_REG(hw, PAUSE_REQ, IOH_GBE_PS_PKT_RQ); | ||
3637 | + | ||
3638 | + IOH_GBE_TESTOUT | ||
3639 | + ("PAUSE_PKT1-5 reg : 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", | ||
3640 | + IOH_GBE_READ_REG(hw, PAUSE_PKT1), IOH_GBE_READ_REG(hw, PAUSE_PKT2), | ||
3641 | + IOH_GBE_READ_REG(hw, PAUSE_PKT3), IOH_GBE_READ_REG(hw, PAUSE_PKT4), | ||
3642 | + IOH_GBE_READ_REG(hw, PAUSE_PKT5)); | ||
3643 | + | ||
3644 | + return; | ||
3645 | +} | ||
3646 | + | ||
3647 | +#ifndef CONFIG_PCH_PCIEQOS | ||
3648 | +/*! | ||
3649 | + * @ingroup HAL internal function | ||
3650 | + * @fn s32 ioh_gbe_mac_read_mac_addr(struct ioh_gbe_hw *hw) | ||
3651 | + * @brief Read MAC address | ||
3652 | + * @param hw [INOUT] Pointer to the HW structure | ||
3653 | + * @return IOH_GBE_SUCCESS | ||
3654 | + */ | ||
3655 | +s32 ioh_gbe_mac_read_mac_addr(struct ioh_gbe_hw *hw) | ||
3656 | +{ | ||
3657 | + u32 adr1a, adr1b; | ||
3658 | + | ||
3659 | + IOH_GBE_DBGFUNC("ioh_gbe_mac_read_mac_addr"); | ||
3660 | + | ||
3661 | + adr1a = IOH_GBE_READ_REG(hw, MAC_ADR1A); | ||
3662 | + adr1b = IOH_GBE_READ_REG(hw, MAC_ADR1B); | ||
3663 | + | ||
3664 | + hw->mac.addr[0] = (u8)(adr1a & 0xFF); | ||
3665 | + hw->mac.addr[1] = (u8)((adr1a >> 8) & 0xFF); | ||
3666 | + hw->mac.addr[2] = (u8)((adr1a >> 16) & 0xFF); | ||
3667 | + hw->mac.addr[3] = (u8)((adr1a >> 24) & 0xFF); | ||
3668 | + hw->mac.addr[4] = (u8)(adr1b & 0xFF); | ||
3669 | + hw->mac.addr[5] = (u8)((adr1b >> 8) & 0xFF); | ||
3670 | + | ||
3671 | + IOH_GBE_TESTOUT("hw->mac.addr : 0x%02x %02x %02x %02x %02x %02x\n", | ||
3672 | + hw->mac.addr[0], hw->mac.addr[1], hw->mac.addr[2], | ||
3673 | + hw->mac.addr[3], hw->mac.addr[4], hw->mac.addr[5]); | ||
3674 | + return IOH_GBE_SUCCESS; | ||
3675 | +} | ||
3676 | +#endif /* CONFIG_PCH_PCIEQOS */ | ||
3677 | diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_mac.h topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_mac.h | ||
3678 | --- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_mac.h 1970-01-01 09:00:00.000000000 +0900 | ||
3679 | +++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_mac.h 2010-03-11 15:11:47.000000000 +0900 | ||
3680 | @@ -0,0 +1,121 @@ | ||
3681 | +/*! | ||
3682 | + * @file ioh_gbe_mac.h | ||
3683 | + * @brief Linux IOH Gigabit Ethernet Driver HAL internal function (MAC) header file | ||
3684 | + * | ||
3685 | + * @version 0.90 | ||
3686 | + * | ||
3687 | + * @section | ||
3688 | + * This program is free software; you can redistribute it and/or modify | ||
3689 | + * it under the terms of the GNU General Public License as published by | ||
3690 | + * the Free Software Foundation; version 2 of the License. | ||
3691 | + * | ||
3692 | + * This program is distributed in the hope that it will be useful, | ||
3693 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3694 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3695 | + * GNU General Public License for more details. | ||
3696 | + * | ||
3697 | + * You should have received a copy of the GNU General Public License | ||
3698 | + * along with this program; if not, write to the Free Software | ||
3699 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
3700 | + */ | ||
3701 | + | ||
3702 | +/* | ||
3703 | + * History: | ||
3704 | + * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD. | ||
3705 | + * All rights reserved. | ||
3706 | + * | ||
3707 | + * created: | ||
3708 | + * OKI SEMICONDUCTOR 09/21/2009 | ||
3709 | + * modified: | ||
3710 | + * | ||
3711 | + */ | ||
3712 | +#ifndef _IOH_GBE_MAC_H_ | ||
3713 | +#define _IOH_GBE_MAC_H_ | ||
3714 | + | ||
3715 | +/*! | ||
3716 | + * @ingroup HAL internal function | ||
3717 | + * @fn void ioh_gbe_mac_reset_hw(struct ioh_gbe_hw *hw) | ||
3718 | + * @brief Reset hardware | ||
3719 | + */ | ||
3720 | +void ioh_gbe_mac_reset_hw(struct ioh_gbe_hw *hw); | ||
3721 | + | ||
3722 | +/*! | ||
3723 | + * @ingroup HAL internal function | ||
3724 | + * @fn void ioh_gbe_mac_init_rx_addrs(struct ioh_gbe_hw *hw, | ||
3725 | + * u16 mar_count) | ||
3726 | + * @brief Initialize receive address's | ||
3727 | + */ | ||
3728 | +void ioh_gbe_mac_init_rx_addrs(struct ioh_gbe_hw *hw, u16 mar_count); | ||
3729 | + | ||
3730 | +/*! | ||
3731 | + * @ingroup HAL internal function | ||
3732 | + * @fn void ioh_gbe_mac_mar_set(struct ioh_gbe_hw *hw, u8 *addr, u32 index) | ||
3733 | + * @brief Set MAC address register | ||
3734 | + */ | ||
3735 | +void ioh_gbe_mac_mar_set(struct ioh_gbe_hw *hw, u8 *addr, u32 index); | ||
3736 | + | ||
3737 | +/*! | ||
3738 | + * @ingroup HAL internal function | ||
3739 | + * @fn void ioh_gbe_mac_mc_addr_list_update(struct ioh_gbe_hw *hw, | ||
3740 | + * u8 *mc_addr_list, u32 mc_addr_count, | ||
3741 | + * u32 mar_used_count, u32 mar_total_num) | ||
3742 | + * @brief Update Multicast addresses | ||
3743 | + */ | ||
3744 | +void ioh_gbe_mac_mc_addr_list_update(struct ioh_gbe_hw *hw, | ||
3745 | + u8 *mc_addr_list, u32 mc_addr_count, | ||
3746 | + u32 mar_used_count, u32 mar_count); | ||
3747 | + | ||
3748 | +/*! | ||
3749 | + * @ingroup HAL internal function | ||
3750 | + * @fn s32 ioh_gbe_mac_setup_link(struct ioh_gbe_hw *hw) | ||
3751 | + * @brief Setup flow control and link settings | ||
3752 | + */ | ||
3753 | +s32 ioh_gbe_mac_setup_link(struct ioh_gbe_hw *hw); | ||
3754 | + | ||
3755 | +/*! | ||
3756 | + * @ingroup HAL internal function | ||
3757 | + * @fn s32 ioh_gbe_mac_force_mac_fc(struct ioh_gbe_hw *hw) | ||
3758 | + * @brief Force the MAC's flow control settings | ||
3759 | + */ | ||
3760 | +s32 ioh_gbe_mac_force_mac_fc(struct ioh_gbe_hw *hw); | ||
3761 | + | ||
3762 | +/*! | ||
3763 | + * @ingroup HAL internal function | ||
3764 | + * @fn s32 ioh_gbe_mac_config_fc_after_link_up(struct ioh_gbe_hw *hw) | ||
3765 | + * @brief Configures flow control after link | ||
3766 | + */ | ||
3767 | +s32 ioh_gbe_mac_config_fc_after_link_up(struct ioh_gbe_hw *hw); | ||
3768 | + | ||
3769 | +/*! | ||
3770 | + * @ingroup HAL internal function | ||
3771 | + * @fn void ioh_gbe_mac_set_wol_event(struct ioh_gbe_hw *hw, u32 wu_evt) | ||
3772 | + * @brief Set wake-on-lan event | ||
3773 | + */ | ||
3774 | +void ioh_gbe_mac_set_wol_event(struct ioh_gbe_hw *hw, u32 wu_evt); | ||
3775 | + | ||
3776 | +/*! | ||
3777 | + * @ingroup HAL internal function | ||
3778 | + * @fn u16 ioh_gbe_mac_ctrl_miim(struct ioh_gbe_hw *hw, u32 addr, | ||
3779 | + * u32 dir, u32 reg, u16 data) | ||
3780 | + * @brief Set wake-on-lan event | ||
3781 | + */ | ||
3782 | +u16 ioh_gbe_mac_ctrl_miim(struct ioh_gbe_hw *hw, | ||
3783 | + u32 addr, u32 dir, u32 reg, u16 data); | ||
3784 | + | ||
3785 | +/*! | ||
3786 | + * @ingroup HAL internal function | ||
3787 | + * @fn void ioh_gbe_mac_set_pause_packet(struct ioh_gbe_hw *hw) | ||
3788 | + * @brief Set pause packet | ||
3789 | + */ | ||
3790 | +void ioh_gbe_mac_set_pause_packet(struct ioh_gbe_hw *hw); | ||
3791 | + | ||
3792 | +#ifndef CONFIG_PCH_PCIEQOS | ||
3793 | +/*! | ||
3794 | + * @ingroup HAL internal function | ||
3795 | + * @fn s32 ioh_gbe_mac_read_mac_addr(struct ioh_gbe_hw *hw) | ||
3796 | + * @brief Read MAC address | ||
3797 | + */ | ||
3798 | +s32 ioh_gbe_mac_read_mac_addr(struct ioh_gbe_hw *hw); | ||
3799 | +#endif /* CONFIG_PCH_PCIEQOS */ | ||
3800 | + | ||
3801 | +#endif /* _IOH_GBE_MAC_H_ */ | ||
3802 | diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_main.c topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_main.c | ||
3803 | --- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_main.c 1970-01-01 09:00:00.000000000 +0900 | ||
3804 | +++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_main.c 2010-03-11 15:13:21.000000000 +0900 | ||
3805 | @@ -0,0 +1,2973 @@ | ||
3806 | +/*! | ||
3807 | + * @file ioh_gbe_main.c | ||
3808 | + * @brief Linux IOH Gigabit Ethernet Driver main source file | ||
3809 | + * | ||
3810 | + * @version 0.90 | ||
3811 | + * | ||
3812 | + * @section | ||
3813 | + * This program is free software; you can redistribute it and/or modify | ||
3814 | + * it under the terms of the GNU General Public License as published by | ||
3815 | + * the Free Software Foundation; version 2 of the License. | ||
3816 | + * | ||
3817 | + * This program is distributed in the hope that it will be useful, | ||
3818 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3819 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3820 | + * GNU General Public License for more details. | ||
3821 | + * | ||
3822 | + * You should have received a copy of the GNU General Public License | ||
3823 | + * along with this program; if not, write to the Free Software | ||
3824 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
3825 | + */ | ||
3826 | + | ||
3827 | +/* | ||
3828 | + * History: | ||
3829 | + * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD. | ||
3830 | + * All rights reserved. | ||
3831 | + * | ||
3832 | + * created: | ||
3833 | + * OKI SEMICONDUCTOR 09/21/2009 | ||
3834 | + * modified: | ||
3835 | + * | ||
3836 | + */ | ||
3837 | + | ||
3838 | +#include <linux/pci.h> | ||
3839 | +#include <linux/netdevice.h> | ||
3840 | +#include <linux/etherdevice.h> | ||
3841 | +#include <linux/ethtool.h> | ||
3842 | +#include <linux/mii.h> | ||
3843 | + | ||
3844 | +#include <linux/in.h> | ||
3845 | +#include <linux/ip.h> | ||
3846 | +#include <linux/tcp.h> | ||
3847 | +#include <linux/udp.h> | ||
3848 | +#include <net/ip.h> | ||
3849 | + | ||
3850 | +#include "pch_gbe_osdep.h" | ||
3851 | +#include "pch_gbe_regs.h" | ||
3852 | +#include "pch_gbe_defines.h" | ||
3853 | +#include "pch_gbe_hw.h" | ||
3854 | +#include "pch_gbe_api.h" | ||
3855 | +#include "pch_gbe.h" | ||
3856 | + | ||
3857 | +/* ---------------------------------------------------------------------------- | ||
3858 | + Function prototype | ||
3859 | +---------------------------------------------------------------------------- */ | ||
3860 | +static int | ||
3861 | +ioh_gbe_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id); | ||
3862 | +static void ioh_gbe_remove(struct pci_dev *pdev); | ||
3863 | +static int ioh_gbe_suspend(struct pci_dev *pdev, pm_message_t state); | ||
3864 | +static int ioh_gbe_resume(struct pci_dev *pdev); | ||
3865 | +static void ioh_gbe_shutdown(struct pci_dev *pdev); | ||
3866 | +#ifdef CONFIG_NET_POLL_CONTROLLER | ||
3867 | +static void ioh_gbe_netpoll(struct net_device *netdev); | ||
3868 | +#endif | ||
3869 | +static pci_ers_result_t | ||
3870 | +ioh_gbe_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state); | ||
3871 | +static pci_ers_result_t ioh_gbe_io_slot_reset(struct pci_dev *pdev); | ||
3872 | +static void ioh_gbe_io_resume(struct pci_dev *pdev); | ||
3873 | + | ||
3874 | +static int ioh_gbe_init_module(void); | ||
3875 | +static void ioh_gbe_exit_module(void); | ||
3876 | +static int ioh_gbe_open(struct net_device *netdev); | ||
3877 | +static int ioh_gbe_stop(struct net_device *netdev); | ||
3878 | +static int ioh_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev); | ||
3879 | +static struct net_device_stats *ioh_gbe_get_stats(struct net_device *netdev); | ||
3880 | +static void ioh_gbe_set_multi(struct net_device *netdev); | ||
3881 | +static int ioh_gbe_set_mac(struct net_device *netdev, void *p); | ||
3882 | +static int ioh_gbe_change_mtu(struct net_device *netdev, int new_mtu); | ||
3883 | +static int ioh_gbe_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd); | ||
3884 | +static void ioh_gbe_tx_timeout(struct net_device *dev); | ||
3885 | + | ||
3886 | +static int ioh_gbe_sw_init(struct ioh_gbe_adapter *adapter); | ||
3887 | +static int ioh_gbe_alloc_queues(struct ioh_gbe_adapter *adapter); | ||
3888 | +static void ioh_gbe_init_stats(struct ioh_gbe_adapter *adapter); | ||
3889 | +static int ioh_gbe_init_nvm(struct ioh_gbe_adapter *adapter); | ||
3890 | +static int ioh_gbe_init_phy(struct ioh_gbe_adapter *adapter); | ||
3891 | +static void ioh_gbe_reset_task(struct work_struct *work); | ||
3892 | +static int ioh_gbe_request_irq(struct ioh_gbe_adapter *adapter); | ||
3893 | +static void ioh_gbe_free_irq(struct ioh_gbe_adapter *adapter); | ||
3894 | +static void ioh_gbe_irq_disable(struct ioh_gbe_adapter *adapter); | ||
3895 | +static void ioh_gbe_irq_enable(struct ioh_gbe_adapter *adapter); | ||
3896 | +static void ioh_gbe_clean_tx_ring(struct ioh_gbe_adapter *adapter, | ||
3897 | + struct ioh_gbe_tx_ring *tx_ring); | ||
3898 | +static void ioh_gbe_clean_rx_ring(struct ioh_gbe_adapter *adapter, | ||
3899 | + struct ioh_gbe_rx_ring *rx_ring); | ||
3900 | +static void | ||
3901 | +ioh_gbe_unmap_and_free_tx_resource(struct ioh_gbe_adapter *adapter, | ||
3902 | + struct ioh_gbe_buffer *buffer_info); | ||
3903 | +static void | ||
3904 | +ioh_gbe_unmap_and_free_rx_resource(struct ioh_gbe_adapter *adapter, | ||
3905 | + struct ioh_gbe_buffer *buffer_info); | ||
3906 | + | ||
3907 | +static void ioh_gbe_setup_tctl(struct ioh_gbe_adapter *adapter); | ||
3908 | +static void ioh_gbe_configure_tx(struct ioh_gbe_adapter *adapter); | ||
3909 | +static void ioh_gbe_setup_rctl(struct ioh_gbe_adapter *adapter); | ||
3910 | +static void ioh_gbe_configure_rx(struct ioh_gbe_adapter *adapter); | ||
3911 | +static void ioh_gbe_set_rgmii_ctrl(struct ioh_gbe_adapter *adapter, | ||
3912 | + u16 speed, u16 duplex); | ||
3913 | +static void ioh_gbe_set_mode(struct ioh_gbe_adapter *adapter, | ||
3914 | + u16 speed, u16 duplex); | ||
3915 | +static void ioh_gbe_watchdog(unsigned long data); | ||
3916 | +static irqreturn_t ioh_gbe_intr(int irq, void *data); | ||
3917 | +static unsigned char ioh_gbe_clean_tx(struct ioh_gbe_adapter *adapter, | ||
3918 | + struct ioh_gbe_tx_ring *tx_ring); | ||
3919 | +static int ioh_gbe_napi_poll(struct napi_struct *napi, int budget); | ||
3920 | +static unsigned char ioh_gbe_clean_rx(struct ioh_gbe_adapter *adapter, | ||
3921 | + struct ioh_gbe_rx_ring *rx_ring, | ||
3922 | + int *work_done, int work_to_do); | ||
3923 | +static void ioh_gbe_alloc_rx_buffers(struct ioh_gbe_adapter *adapter, | ||
3924 | + struct ioh_gbe_rx_ring *rx_ring, | ||
3925 | + int cleaned_count); | ||
3926 | +static void ioh_gbe_alloc_tx_buffers(struct ioh_gbe_adapter *adapter, | ||
3927 | + struct ioh_gbe_tx_ring *tx_ring); | ||
3928 | +static void ioh_gbe_tx_queue(struct ioh_gbe_adapter *adapter, | ||
3929 | + struct ioh_gbe_tx_ring *tx_ring, | ||
3930 | + struct sk_buff *skb); | ||
3931 | + | ||
3932 | +/* ---------------------------------------------------------------------------- | ||
3933 | + Data | ||
3934 | +---------------------------------------------------------------------------- */ | ||
3935 | +/*! | ||
3936 | + * @ingroup PCI driver Layer | ||
3937 | + * @struct ioh_gbe_pcidev_id | ||
3938 | + * @brief PCI Device ID Table | ||
3939 | + * @remarks | ||
3940 | + * This is an instance of pci_device_id structure defined in linux/pci.h, | ||
3941 | + * and holds information of the PCI devices that are supported by this driver. | ||
3942 | + */ | ||
3943 | +static const struct pci_device_id ioh_gbe_pcidev_id[3] = { | ||
3944 | + {.vendor = PCI_VENDOR_ID_INTEL, | ||
3945 | + .device = PCI_DEVICE_ID_INTEL_IOH1_GBE, | ||
3946 | + .subvendor = PCI_ANY_ID, | ||
3947 | + .subdevice = PCI_ANY_ID, | ||
3948 | + .class = (PCI_CLASS_NETWORK_ETHERNET << 8), | ||
3949 | + .class_mask = (0xFFFF00) | ||
3950 | + }, | ||
3951 | + /* required last entry */ | ||
3952 | + {0} | ||
3953 | +}; | ||
3954 | + | ||
3955 | +/*! | ||
3956 | + * @ingroup PCI driver Layer | ||
3957 | + * @struct ioh_gbe_err_handler | ||
3958 | + * @brief Error handler Table | ||
3959 | + * @remarks | ||
3960 | + * This is an instance of pci_error_handlers structure defined in linux/pci.h, | ||
3961 | + * and holds information of the PCI devices that are supported by this driver. | ||
3962 | + */ | ||
3963 | +static struct pci_error_handlers ioh_gbe_err_handler = { | ||
3964 | + .error_detected = ioh_gbe_io_error_detected, | ||
3965 | + .slot_reset = ioh_gbe_io_slot_reset, | ||
3966 | + .resume = ioh_gbe_io_resume | ||
3967 | +}; | ||
3968 | + | ||
3969 | +/*! | ||
3970 | + * @ingroup PCI driver Layer | ||
3971 | + * @struct ioh_gbe_pcidev | ||
3972 | + * @brief Store the pointers of pci driver interfaces to kernel | ||
3973 | + */ | ||
3974 | +static struct pci_driver ioh_gbe_pcidev = { | ||
3975 | + .name = DRV_NAME, | ||
3976 | + .id_table = ioh_gbe_pcidev_id, | ||
3977 | + .probe = ioh_gbe_probe, | ||
3978 | + .remove = ioh_gbe_remove, | ||
3979 | + /* Power Managment Hooks */ | ||
3980 | +#ifdef CONFIG_PM | ||
3981 | + .suspend = ioh_gbe_suspend, | ||
3982 | + .resume = ioh_gbe_resume, | ||
3983 | +#endif | ||
3984 | + .shutdown = ioh_gbe_shutdown, | ||
3985 | + .err_handler = &ioh_gbe_err_handler | ||
3986 | +}; | ||
3987 | + | ||
3988 | +static int debug = IOH_GBE_NETIF_MSG_DEFAULT; | ||
3989 | +static unsigned int copybreak __read_mostly = IOH_GBE_COPYBREAK_DEFAULT; | ||
3990 | + | ||
3991 | +/* ---------------------------------------------------------------------------- | ||
3992 | + module | ||
3993 | +---------------------------------------------------------------------------- */ | ||
3994 | + | ||
3995 | +MODULE_DESCRIPTION(DRV_DESCRIPTION); | ||
3996 | +MODULE_AUTHOR(DRV_COPYRIGHT); | ||
3997 | +MODULE_LICENSE("GPL"); | ||
3998 | +MODULE_VERSION(DRV_VERSION); | ||
3999 | +MODULE_DEVICE_TABLE(pci, ioh_gbe_pcidev_id); | ||
4000 | + | ||
4001 | +module_param(copybreak, uint, 0644); | ||
4002 | +MODULE_PARM_DESC(copybreak, | ||
4003 | + "Maximum size of packet that is copied to a new buffer on receive"); | ||
4004 | +module_param(debug, int, 0); | ||
4005 | +MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); | ||
4006 | + | ||
4007 | +module_init(ioh_gbe_init_module); | ||
4008 | +module_exit(ioh_gbe_exit_module); | ||
4009 | + | ||
4010 | +/* ---------------------------------------------------------------------------- | ||
4011 | + Macro Function | ||
4012 | +---------------------------------------------------------------------------- */ | ||
4013 | +#define IOH_GBE_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i])) | ||
4014 | +#define IOH_GBE_RX_DESC(R, i) IOH_GBE_GET_DESC(R, i, ioh_gbe_rx_desc) | ||
4015 | +#define IOH_GBE_TX_DESC(R, i) IOH_GBE_GET_DESC(R, i, ioh_gbe_tx_desc) | ||
4016 | +#define IOH_GBE_DESC_UNUSED(R) \ | ||
4017 | + ((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \ | ||
4018 | + (R)->next_to_clean - (R)->next_to_use - 1) | ||
4019 | + | ||
4020 | +/* ---------------------------------------------------------------------------- | ||
4021 | + Function | ||
4022 | +---------------------------------------------------------------------------- */ | ||
4023 | +/* ---------------------------------------------------------------------------- | ||
4024 | + PCI driver methods | ||
4025 | +---------------------------------------------------------------------------- */ | ||
4026 | + | ||
4027 | +static const struct net_device_ops ioh_gbe_netdev_ops = { | ||
4028 | + .ndo_open = ioh_gbe_open, | ||
4029 | + .ndo_stop = ioh_gbe_stop, | ||
4030 | + .ndo_start_xmit = ioh_gbe_xmit_frame, | ||
4031 | + .ndo_get_stats = ioh_gbe_get_stats, | ||
4032 | + .ndo_set_mac_address = ioh_gbe_set_mac, | ||
4033 | + .ndo_tx_timeout = ioh_gbe_tx_timeout, | ||
4034 | + .ndo_change_mtu = ioh_gbe_change_mtu, | ||
4035 | + .ndo_do_ioctl = ioh_gbe_ioctl, | ||
4036 | + .ndo_set_multicast_list = &ioh_gbe_set_multi, | ||
4037 | +#ifdef CONFIG_NET_POLL_CONTROLLER | ||
4038 | + .ndo_poll_controller = ioh_gbe_netpoll, | ||
4039 | +#endif | ||
4040 | +}; | ||
4041 | + | ||
4042 | +/*! | ||
4043 | + * @ingroup PCI driver method | ||
4044 | + * @fn static int ioh_gbe_probe(struct pci_dev *pdev, | ||
4045 | + * const struct pci_device_id *pci_id) | ||
4046 | + * @brief Device Initialization Routine | ||
4047 | + * @param pdev [INOUT] PCI device information struct | ||
4048 | + * @param pci_id [INOUT] Entry in ioh_gbe_pcidev_id | ||
4049 | + * @return IOH_GBE_SUCCESS: Successfully | ||
4050 | + * @return Negative value: Failed | ||
4051 | + * @remarks | ||
4052 | + * This function initializes an adapter identified by a pci_dev structure. | ||
4053 | + * The OS initialization, configuring of the adapter private structure, | ||
4054 | + * and a hardware reset occur. | ||
4055 | + */ | ||
4056 | +static int | ||
4057 | +ioh_gbe_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | ||
4058 | +{ | ||
4059 | + struct net_device *netdev; | ||
4060 | + struct ioh_gbe_adapter *adapter; | ||
4061 | + unsigned long mmio_start; | ||
4062 | + unsigned long mmio_len; | ||
4063 | + static int cards_found; | ||
4064 | + int i, ret; | ||
4065 | + | ||
4066 | + IOH_GBE_DBGFUNC("ioh_gbe_probe"); | ||
4067 | + | ||
4068 | + cards_found = 0; | ||
4069 | + ret = pci_enable_device(pdev); | ||
4070 | + if (ret != 0) | ||
4071 | + return ret; | ||
4072 | + ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
4073 | + if (ret != 0) { | ||
4074 | + ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | ||
4075 | + if (ret != 0) { | ||
4076 | + IOH_GBE_ERR | ||
4077 | + ("ERR: No usable DMA configuration, aborting\n"); | ||
4078 | + goto err_disable_device; | ||
4079 | + } | ||
4080 | + } | ||
4081 | + ret = pci_request_regions(pdev, DRV_NAME); | ||
4082 | + if (ret != 0) { | ||
4083 | + IOH_GBE_ERR | ||
4084 | + ("ERR: Can't reserve PCI I/O and memory resources\n"); | ||
4085 | + goto err_disable_device; | ||
4086 | + } | ||
4087 | + pci_set_master(pdev); | ||
4088 | + | ||
4089 | + netdev = alloc_etherdev((int)sizeof(struct ioh_gbe_adapter)); | ||
4090 | + if (!netdev) { | ||
4091 | + ret = -ENOMEM; | ||
4092 | + IOH_GBE_ERR | ||
4093 | + ("ERR: Can't allocates and sets up an Ethernet device\n"); | ||
4094 | + goto err_release_pci; | ||
4095 | + } | ||
4096 | + SET_NETDEV_DEV(netdev, &pdev->dev); | ||
4097 | + | ||
4098 | + pci_set_drvdata(pdev, netdev); | ||
4099 | + adapter = netdev_priv(netdev); | ||
4100 | + adapter->netdev = netdev; | ||
4101 | + adapter->pdev = pdev; | ||
4102 | + adapter->msg_enable = (1 << debug) - 1; | ||
4103 | + adapter->bd_number = cards_found; | ||
4104 | + adapter->hw.back = adapter; | ||
4105 | + mmio_start = pci_resource_start(pdev, IOH_GBE_PCI_BAR); | ||
4106 | + mmio_len = pci_resource_len(pdev, IOH_GBE_PCI_BAR); | ||
4107 | + adapter->hw.hw_addr = ioremap(mmio_start, mmio_len); | ||
4108 | + if (!adapter->hw.hw_addr) { | ||
4109 | + ret = -EIO; | ||
4110 | + DPRINTK(PROBE, ERR, "Can't ioremap\n"); | ||
4111 | + goto err_free_netdev; | ||
4112 | + } | ||
4113 | + | ||
4114 | + netdev->netdev_ops = &ioh_gbe_netdev_ops; | ||
4115 | + | ||
4116 | + netdev->watchdog_timeo = IOH_GBE_WATCHDOG_PERIOD; | ||
4117 | + netif_napi_add(netdev, &adapter->napi, | ||
4118 | + ioh_gbe_napi_poll, IOH_GBE_RX_WEIGHT); | ||
4119 | + strncpy(netdev->name, pci_name(pdev), (int)sizeof(netdev->name) - 1); | ||
4120 | + netdev->mem_start = mmio_start; | ||
4121 | + netdev->mem_end = mmio_start + mmio_len; | ||
4122 | + netdev->features = NETIF_F_HW_CSUM; | ||
4123 | + ioh_gbe_set_ethtool_ops(netdev); | ||
4124 | + | ||
4125 | + /* setup the private structure */ | ||
4126 | + ret = ioh_gbe_sw_init(adapter); | ||
4127 | + if (ret != 0) | ||
4128 | + goto err_iounmap; | ||
4129 | + | ||
4130 | + ioh_gbe_hal_reset_hw(&adapter->hw); | ||
4131 | + /* Initialize PHY */ | ||
4132 | + ret = ioh_gbe_init_phy(adapter); | ||
4133 | + if (ret != 0) { | ||
4134 | + DPRINTK(PROBE, ERR, "PHY initialize error\n"); | ||
4135 | + goto err_free_adapter; | ||
4136 | + } | ||
4137 | + | ||
4138 | + ioh_gbe_hal_get_bus_info(&adapter->hw); | ||
4139 | + | ||
4140 | + /* Initialize NVM */ | ||
4141 | + ret = ioh_gbe_init_nvm(adapter); | ||
4142 | + if (ret != 0) { | ||
4143 | + DPRINTK(PROBE, ERR, "NVM initialize error\n"); | ||
4144 | + goto err_free_adapter; | ||
4145 | + } | ||
4146 | + | ||
4147 | +#ifdef CONFIG_PCH_PCIEQOS | ||
4148 | + /* Read the MAC address. and store to the private data */ | ||
4149 | + ret = ioh_gbe_hal_read_mac_addr(&adapter->hw); | ||
4150 | + if (ret != 0) { | ||
4151 | + DPRINTK(PROBE, ERR, "MAC address Read Error\n"); | ||
4152 | + goto err_free_adapter; | ||
4153 | + } | ||
4154 | +#endif | ||
4155 | + memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len); | ||
4156 | + if (!is_valid_ether_addr(netdev->dev_addr)) { | ||
4157 | + DPRINTK(PROBE, ERR, "Invalid MAC Address\n"); | ||
4158 | + ret = -EIO; | ||
4159 | + goto err_free_adapter; | ||
4160 | + } | ||
4161 | + | ||
4162 | + init_timer(&adapter->watchdog_timer); | ||
4163 | + adapter->watchdog_timer.function = &ioh_gbe_watchdog; | ||
4164 | + adapter->watchdog_timer.data = (unsigned long)adapter; | ||
4165 | + | ||
4166 | + INIT_WORK(&adapter->reset_task, ioh_gbe_reset_task); | ||
4167 | + | ||
4168 | + ioh_gbe_check_options(adapter); | ||
4169 | + | ||
4170 | + if (adapter->tx_csum != 0) | ||
4171 | + netdev->features |= NETIF_F_HW_CSUM; | ||
4172 | + else | ||
4173 | + netdev->features &= ~NETIF_F_HW_CSUM; | ||
4174 | + | ||
4175 | + /* initialize the wol settings based on the eeprom settings */ | ||
4176 | + adapter->wake_up_evt = IOH_GBE_WL_INIT_SETTING; | ||
4177 | + | ||
4178 | + /* print bus type/speed/width info */ | ||
4179 | + { | ||
4180 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
4181 | + DPRINTK(PROBE, INFO, "(PCI%s:%s:%s) ", | ||
4182 | + ((hw->bus.type == ioh_gbe_bus_type_pcix) ? "-X" : | ||
4183 | + (hw->bus.type == ioh_gbe_bus_type_pci_express) ? " Express" : | ||
4184 | + ""), | ||
4185 | + ((hw->bus.speed == ioh_gbe_bus_speed_2500) ? "2.5Gb/s" : | ||
4186 | + (hw->bus.speed == ioh_gbe_bus_speed_133) ? "133MHz" : | ||
4187 | + (hw->bus.speed == ioh_gbe_bus_speed_120) ? "120MHz" : | ||
4188 | + (hw->bus.speed == ioh_gbe_bus_speed_100) ? "100MHz" : | ||
4189 | + (hw->bus.speed == ioh_gbe_bus_speed_66) ? "66MHz" : | ||
4190 | + (hw->bus.speed == ioh_gbe_bus_speed_33) ? "33MHz" : | ||
4191 | + ""), | ||
4192 | + ((hw->bus.width == ioh_gbe_bus_width_64) ? "64-bit" : | ||
4193 | + (hw->bus.width == ioh_gbe_bus_width_32) ? "32-bit" : | ||
4194 | + (hw->bus.width == ioh_gbe_bus_width_pcie_x4) ? "Width x4" : | ||
4195 | + (hw->bus.width == ioh_gbe_bus_width_pcie_x2) ? "Width x2" : | ||
4196 | + (hw->bus.width == ioh_gbe_bus_width_pcie_x1) ? "Width x1" : | ||
4197 | + "")); | ||
4198 | + } | ||
4199 | + for (i = 0; i < 6; i++) | ||
4200 | + printk(KERN_INFO "%2.2x%c", | ||
4201 | + netdev->dev_addr[i], i == 5 ? '\n' : ':'); | ||
4202 | + | ||
4203 | + /* reset the hardware with the new settings */ | ||
4204 | + ioh_gbe_reset(adapter); | ||
4205 | + | ||
4206 | + strcpy(netdev->name, "eth%d"); | ||
4207 | + ret = register_netdev(netdev); | ||
4208 | + if (ret != 0) | ||
4209 | + goto err_free_adapter; | ||
4210 | + /* tell the stack to leave us alone until ioh_gbe_open() is called */ | ||
4211 | + netif_carrier_off(netdev); | ||
4212 | + netif_stop_queue(netdev); | ||
4213 | + | ||
4214 | + DPRINTK(PROBE, INFO, "OKIsemi(R) IOH Network Connection\n"); | ||
4215 | + | ||
4216 | + cards_found++; | ||
4217 | + device_set_wakeup_enable(&pdev->dev, 1); | ||
4218 | + return IOH_GBE_SUCCESS; | ||
4219 | + | ||
4220 | +err_free_adapter: | ||
4221 | + ioh_gbe_hal_phy_hw_reset(&adapter->hw); | ||
4222 | + dev_put(adapter->polling_netdev); | ||
4223 | + kfree(adapter->tx_ring); | ||
4224 | + kfree(adapter->rx_ring); | ||
4225 | + kfree(adapter->polling_netdev); | ||
4226 | +err_iounmap: | ||
4227 | + iounmap(adapter->hw.hw_addr); | ||
4228 | +err_free_netdev: | ||
4229 | + free_netdev(netdev); | ||
4230 | +err_release_pci: | ||
4231 | + pci_release_regions(pdev); | ||
4232 | +err_disable_device: | ||
4233 | + pci_disable_device(pdev); | ||
4234 | + return ret; | ||
4235 | +} | ||
4236 | + | ||
4237 | +/*! | ||
4238 | + * @ingroup PCI driver method | ||
4239 | + * @fn static void ioh_gbe_remove(struct pci_dev *pdev) | ||
4240 | + * @brief Device Removal Routine | ||
4241 | + * @param pdev [INOUT] PCI device information struct | ||
4242 | + * @return None | ||
4243 | + * @remarks | ||
4244 | + * This function is called by the PCI subsystem to alert the driver | ||
4245 | + * that it should release a PCI device. The could be caused by a | ||
4246 | + * Hot-Plug event, or because the driver is going to be removed from | ||
4247 | + * memory. | ||
4248 | + */ | ||
4249 | +static void ioh_gbe_remove(struct pci_dev *pdev) | ||
4250 | +{ | ||
4251 | + struct net_device *netdev = pci_get_drvdata(pdev); | ||
4252 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
4253 | + | ||
4254 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
4255 | + | ||
4256 | + flush_scheduled_work(); | ||
4257 | + unregister_netdev(netdev); | ||
4258 | + dev_put(adapter->polling_netdev); | ||
4259 | + | ||
4260 | + ioh_gbe_hal_phy_hw_reset(&adapter->hw); | ||
4261 | + | ||
4262 | + kfree(adapter->tx_ring); | ||
4263 | + kfree(adapter->rx_ring); | ||
4264 | + kfree(adapter->polling_netdev); | ||
4265 | + | ||
4266 | + iounmap(adapter->hw.hw_addr); | ||
4267 | + pci_release_regions(pdev); | ||
4268 | + free_netdev(netdev); | ||
4269 | + pci_disable_device(pdev); | ||
4270 | +} | ||
4271 | + | ||
4272 | +/*! | ||
4273 | + * @ingroup PCI driver method | ||
4274 | + * @fn static int ioh_gbe_suspend(struct pci_dev *pdev, pm_message_t state) | ||
4275 | + * @brief Device Suspend Routine | ||
4276 | + * @param pdev [INOUT] PCI device information struct | ||
4277 | + * @param state [IN] Power status | ||
4278 | + * @return None | ||
4279 | + */ | ||
4280 | +static int ioh_gbe_suspend(struct pci_dev *pdev, pm_message_t state) | ||
4281 | +{ | ||
4282 | + struct net_device *netdev = pci_get_drvdata(pdev); | ||
4283 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
4284 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
4285 | + u32 wufc = adapter->wake_up_evt; | ||
4286 | + int retval = IOH_GBE_SUCCESS; | ||
4287 | + | ||
4288 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
4289 | + | ||
4290 | + netif_device_detach(netdev); | ||
4291 | + | ||
4292 | + if (netif_running(netdev) != 0) | ||
4293 | + ioh_gbe_down(adapter); | ||
4294 | +#ifdef CONFIG_PM | ||
4295 | + /* Implement our own version of pci_save_state(pdev) because pci- | ||
4296 | + * express adapters have 256-byte config spaces. */ | ||
4297 | + retval = pci_save_state(pdev); | ||
4298 | + if (retval != 0) { | ||
4299 | + DPRINTK(PROBE, DEBUG, "pci_save_state failed\n"); | ||
4300 | + return retval; | ||
4301 | + } | ||
4302 | +#endif | ||
4303 | + | ||
4304 | + if (wufc != 0) { | ||
4305 | + ioh_gbe_set_multi(netdev); | ||
4306 | + ioh_gbe_setup_rctl(adapter); | ||
4307 | + ioh_gbe_configure_rx(adapter); | ||
4308 | + ioh_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed, | ||
4309 | + hw->mac.link_duplex); | ||
4310 | + ioh_gbe_set_mode(adapter, hw->mac.link_speed, | ||
4311 | + hw->mac.link_duplex); | ||
4312 | + ioh_gbe_hal_set_wol_event(hw, wufc); | ||
4313 | + pci_disable_device(pdev); | ||
4314 | + retval = pci_set_power_state(pdev, PCI_D0); | ||
4315 | + if (retval) | ||
4316 | + DPRINTK(PROBE, DEBUG, "pci_set_power_state failed\n"); | ||
4317 | + retval = pci_enable_wake(pdev, PCI_D0, 1); | ||
4318 | + if (retval) | ||
4319 | + DPRINTK(PROBE, DEBUG, "pci_enable_wake failed\n"); | ||
4320 | + } else { | ||
4321 | + ioh_gbe_hal_power_down_phy(hw); | ||
4322 | + ioh_gbe_hal_set_wol_event(hw, wufc); | ||
4323 | + pci_disable_device(pdev); | ||
4324 | + pci_enable_wake(pdev, PCI_D0, 0); | ||
4325 | + pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
4326 | + } | ||
4327 | + return retval; | ||
4328 | +} | ||
4329 | + | ||
4330 | +#ifdef CONFIG_PM | ||
4331 | +/*! | ||
4332 | + * @ingroup PCI driver method | ||
4333 | + * @fn static int ioh_gbe_resume(struct pci_dev *pdev) | ||
4334 | + * @brief Device Resume Routine | ||
4335 | + * @param pdev [INOUT] PCI device information struct | ||
4336 | + * @return IOH_GBE_SUCCESS: Successfully | ||
4337 | + * @return negative: Failed | ||
4338 | + */ | ||
4339 | +static int ioh_gbe_resume(struct pci_dev *pdev) | ||
4340 | +{ | ||
4341 | + struct net_device *netdev = pci_get_drvdata(pdev); | ||
4342 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
4343 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
4344 | + u32 err; | ||
4345 | + | ||
4346 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
4347 | + | ||
4348 | + pci_enable_wake(pdev, PCI_D0, 0); | ||
4349 | + pci_set_power_state(pdev, PCI_D0); | ||
4350 | + pci_restore_state(pdev); | ||
4351 | + err = pci_enable_device(pdev); | ||
4352 | + if (err != 0) { | ||
4353 | + DPRINTK(PROBE, ERR, "Cannot enable PCI device from suspend\n"); | ||
4354 | + return err; | ||
4355 | + } | ||
4356 | + pci_set_master(pdev); | ||
4357 | + ioh_gbe_hal_power_up_phy(hw); | ||
4358 | + ioh_gbe_reset(adapter); | ||
4359 | + /* Clear wake on lan control and status */ | ||
4360 | + ioh_gbe_hal_set_wol_event(hw, 0); | ||
4361 | + | ||
4362 | + if (netif_running(netdev) != 0) | ||
4363 | + ioh_gbe_up(adapter); | ||
4364 | + netif_device_attach(netdev); | ||
4365 | + | ||
4366 | + return IOH_GBE_SUCCESS; | ||
4367 | +} | ||
4368 | +#endif /* CONFIG_PM */ | ||
4369 | + | ||
4370 | +/*! | ||
4371 | + * @ingroup PCI driver method | ||
4372 | + * @fn static void ioh_gbe_shutdown(struct pci_dev *pdev) | ||
4373 | + * @brief Device shutdown Routine | ||
4374 | + * @param pdev [INOUT] PCI device information struct | ||
4375 | + * @return IOH_GBE_SUCCESS: Successfully | ||
4376 | + * @return Negative value: Failed | ||
4377 | + */ | ||
4378 | +static void ioh_gbe_shutdown(struct pci_dev *pdev) | ||
4379 | +{ | ||
4380 | + struct net_device *netdev = pci_get_drvdata(pdev); | ||
4381 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
4382 | + | ||
4383 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
4384 | + ioh_gbe_suspend(pdev, PMSG_SUSPEND); | ||
4385 | +} | ||
4386 | + | ||
4387 | +/*! | ||
4388 | + * @ingroup PCI driver method | ||
4389 | + * @fn static pci_ers_result_t ioh_gbe_io_error_detected( | ||
4390 | + * struct pci_dev *pdev, | ||
4391 | + * pci_channel_state_t state) | ||
4392 | + * @brief Called when PCI error is detected | ||
4393 | + * @param pdev [INOUT] PCI device information struct | ||
4394 | + * @param state [IN] The current pci connection state | ||
4395 | + * @return PCI_ERS_RESULT_NEED_RESET | ||
4396 | + * @remarks | ||
4397 | + * This function is called after a PCI bus error affecting | ||
4398 | + * this device has been detected. | ||
4399 | + */ | ||
4400 | +static pci_ers_result_t | ||
4401 | +ioh_gbe_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) | ||
4402 | +{ | ||
4403 | + struct net_device *netdev = pci_get_drvdata(pdev); | ||
4404 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
4405 | + | ||
4406 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
4407 | + | ||
4408 | + netif_device_detach(netdev); | ||
4409 | + | ||
4410 | + if (netif_running(netdev) != 0) | ||
4411 | + ioh_gbe_down(adapter); | ||
4412 | + pci_disable_device(pdev); | ||
4413 | + | ||
4414 | + /* Request a slot slot reset. */ | ||
4415 | + return PCI_ERS_RESULT_NEED_RESET; | ||
4416 | +} | ||
4417 | + | ||
4418 | +/*! | ||
4419 | + * @ingroup PCI driver method | ||
4420 | + * @fn static pci_ers_result_t ioh_gbe_io_slot_reset(struct pci_dev *pdev) | ||
4421 | + * @brief Called after the pci bus has been reset. | ||
4422 | + * @param pdev [INOUT] PCI device information struct | ||
4423 | + * @return PCI_ERS_RESULT_DISCONNECT | ||
4424 | + * @return PCI_ERS_RESULT_RECOVERED | ||
4425 | + * @remarks | ||
4426 | + * Restart the card from scratch, as if from a cold-boot. Implementation | ||
4427 | + * resembles the first-half of the ioh_gbe_resume routine. | ||
4428 | + */ | ||
4429 | +static pci_ers_result_t ioh_gbe_io_slot_reset(struct pci_dev *pdev) | ||
4430 | +{ | ||
4431 | + struct net_device *netdev = pci_get_drvdata(pdev); | ||
4432 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
4433 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
4434 | + | ||
4435 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
4436 | + | ||
4437 | + if (pci_enable_device(pdev) != 0) { | ||
4438 | + DPRINTK(PROBE, ERR, | ||
4439 | + "Cannot re-enable PCI device after reset.\n"); | ||
4440 | + return PCI_ERS_RESULT_DISCONNECT; | ||
4441 | + } | ||
4442 | + pci_set_master(pdev); | ||
4443 | + pci_enable_wake(pdev, PCI_D0, 0); | ||
4444 | + ioh_gbe_hal_power_up_phy(hw); | ||
4445 | + ioh_gbe_reset(adapter); | ||
4446 | + /* Clear wake up status */ | ||
4447 | + ioh_gbe_hal_set_wol_event(hw, 0); | ||
4448 | + | ||
4449 | + return PCI_ERS_RESULT_RECOVERED; | ||
4450 | +} | ||
4451 | + | ||
4452 | +/*! | ||
4453 | + * @ingroup PCI driver method | ||
4454 | + * @fn static void ioh_gbe_io_resume(struct pci_dev *pdev) | ||
4455 | + * @brief Called when traffic can start flowing again. | ||
4456 | + * @param pdev [INOUT] PCI device information struct | ||
4457 | + * @return PCI_ERS_RESULT_DISCONNECT | ||
4458 | + * @return PCI_ERS_RESULT_RECOVERED | ||
4459 | + * @remarks | ||
4460 | + * This callback is called when the error recovery driver tells us that | ||
4461 | + * its OK to resume normal operation. Implementation resembles the | ||
4462 | + * second-half of the ioh_gbe_resume routine. | ||
4463 | + */ | ||
4464 | +static void ioh_gbe_io_resume(struct pci_dev *pdev) | ||
4465 | +{ | ||
4466 | + struct net_device *netdev = pci_get_drvdata(pdev); | ||
4467 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
4468 | + | ||
4469 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
4470 | + | ||
4471 | + if (netif_running(netdev) != 0) { | ||
4472 | + if (ioh_gbe_up(adapter) != 0) { | ||
4473 | + DPRINTK(PROBE, DEBUG, | ||
4474 | + "can't bring device back up after reset\n"); | ||
4475 | + return; | ||
4476 | + } | ||
4477 | + } | ||
4478 | + netif_device_attach(netdev); | ||
4479 | +} | ||
4480 | + | ||
4481 | +/* ---------------------------------------------------------------------------- | ||
4482 | + Gigabit Ethernet driver methods | ||
4483 | +---------------------------------------------------------------------------- */ | ||
4484 | +/*! | ||
4485 | + * @ingroup Gigabit Ethernet driver methods | ||
4486 | + * @fn static int __init ioh_gbe_init_module(void) | ||
4487 | + * @brief Driver Registration Routine | ||
4488 | + * @return IOH_GBE_SUCCESS Successfully | ||
4489 | + * @return negative value Failed | ||
4490 | + * @remarks | ||
4491 | + * ioh_gbe_init_module is the first routine called when the driver is | ||
4492 | + * loaded. All it does is register with the PCI subsystem. | ||
4493 | + */ | ||
4494 | +static int __init ioh_gbe_init_module(void) | ||
4495 | +{ | ||
4496 | + int ret; | ||
4497 | + IOH_GBE_DBGFUNC("ioh_gbe_init_module"); | ||
4498 | + printk(KERN_INFO "%s - version %s\n", DRV_STRING, DRV_VERSION); | ||
4499 | + | ||
4500 | + ret = pci_register_driver(&ioh_gbe_pcidev); | ||
4501 | + if (copybreak != IOH_GBE_COPYBREAK_DEFAULT) { | ||
4502 | + if (copybreak == 0) { | ||
4503 | + printk(KERN_INFO "ioh_gbe: copybreak disabled\n"); | ||
4504 | + } else { | ||
4505 | + printk(KERN_INFO "ioh_gbe: copybreak enabled for " | ||
4506 | + "packets <= %u bytes\n", copybreak); | ||
4507 | + } | ||
4508 | + } | ||
4509 | + return ret; | ||
4510 | +} | ||
4511 | + | ||
4512 | +/*! | ||
4513 | + * @ingroup Gigabit Ethernet driver methods | ||
4514 | + * @fn static void __exit ioh_gbe_exit_module(void) | ||
4515 | + * @brief Driver Exit Cleanup Routine | ||
4516 | + * @return None | ||
4517 | + * @remarks | ||
4518 | + * ioh_gbe_exit_module is called just before the driver is removed | ||
4519 | + * from memory. | ||
4520 | + */ | ||
4521 | +static void __exit ioh_gbe_exit_module(void) | ||
4522 | +{ | ||
4523 | + IOH_GBE_DBGFUNC("ioh_gbe_exit_module"); | ||
4524 | + pci_unregister_driver(&ioh_gbe_pcidev); | ||
4525 | + | ||
4526 | + printk(KERN_INFO "%s - unregister\n", DRV_STRING); | ||
4527 | +} | ||
4528 | + | ||
4529 | +/*! | ||
4530 | + * @ingroup Gigabit Ethernet driver methods | ||
4531 | + * @fn static int ioh_gbe_open(struct net_device *netdev) | ||
4532 | + * @brief Called when a network interface is made active | ||
4533 | + * @param netdev [INOUT] network interface device structure | ||
4534 | + * @return IOH_GBE_SUCCESS - Successfully | ||
4535 | + * @return negative value - Failed | ||
4536 | + * @remarks | ||
4537 | + * The open entry point is called when a network interface is made | ||
4538 | + * active by the system (IFF_UP). At this point all resources needed | ||
4539 | + * for transmit and receive operations are allocated, the interrupt | ||
4540 | + * handler is registered with the OS, the watchdog timer is started, | ||
4541 | + * and the stack is notified that the interface is ready. | ||
4542 | + */ | ||
4543 | +static int ioh_gbe_open(struct net_device *netdev) | ||
4544 | +{ | ||
4545 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
4546 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
4547 | + int err; | ||
4548 | + | ||
4549 | + DPRINTK(IFUP, DEBUG, "\n"); | ||
4550 | + | ||
4551 | + /* disallow open during test */ | ||
4552 | + if ((test_bit(__IOH_GBE_TESTING, &adapter->flags)) != 0) | ||
4553 | + return -EBUSY; | ||
4554 | + /* allocate transmit descriptors */ | ||
4555 | + err = ioh_gbe_setup_tx_resources(adapter, adapter->tx_ring); | ||
4556 | + if (err != 0) | ||
4557 | + goto err_setup_tx; | ||
4558 | + /* allocate receive descriptors */ | ||
4559 | + err = ioh_gbe_setup_rx_resources(adapter, adapter->rx_ring); | ||
4560 | + if (err != 0) | ||
4561 | + goto err_setup_rx; | ||
4562 | + ioh_gbe_hal_power_up_phy(hw); | ||
4563 | + err = ioh_gbe_up(adapter); | ||
4564 | + if (err != 0) | ||
4565 | + goto err_up; | ||
4566 | + DPRINTK(PROBE, DEBUG, "Success End\n"); | ||
4567 | + return IOH_GBE_SUCCESS; | ||
4568 | + | ||
4569 | +err_up: | ||
4570 | + if (!adapter->wake_up_evt) | ||
4571 | + ioh_gbe_hal_power_down_phy(hw); | ||
4572 | + ioh_gbe_free_rx_resources(adapter, adapter->rx_ring); | ||
4573 | +err_setup_rx: | ||
4574 | + ioh_gbe_free_tx_resources(adapter, adapter->tx_ring); | ||
4575 | +err_setup_tx: | ||
4576 | + ioh_gbe_reset(adapter); | ||
4577 | + DPRINTK(PROBE, ERR, "Error End\n"); | ||
4578 | + return err; | ||
4579 | +} | ||
4580 | + | ||
4581 | +/*! | ||
4582 | + * @ingroup Gigabit Ethernet driver methods | ||
4583 | + * @fn static int ioh_gbe_stop(struct net_device *netdev) | ||
4584 | + * @brief Disables a network interface | ||
4585 | + * @param netdev [INOUT] network interface device structure | ||
4586 | + * @return IOH_GBE_SUCCESS - Successfully (This is not allowed to fail) | ||
4587 | + * @remarks | ||
4588 | + * The close entry point is called when an interface is de-activated | ||
4589 | + * by the OS. The hardware is still under the drivers control, but | ||
4590 | + * needs to be disabled. A global MAC reset is issued to stop the | ||
4591 | + * hardware, and all transmit and receive resources are freed. | ||
4592 | + */ | ||
4593 | +static int ioh_gbe_stop(struct net_device *netdev) | ||
4594 | +{ | ||
4595 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
4596 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
4597 | + | ||
4598 | + DPRINTK(IFDOWN, DEBUG, "\n"); | ||
4599 | + | ||
4600 | + ioh_gbe_down(adapter); | ||
4601 | + if (!adapter->wake_up_evt) | ||
4602 | + ioh_gbe_hal_power_down_phy(hw); | ||
4603 | + ioh_gbe_free_tx_resources(adapter, adapter->tx_ring); | ||
4604 | + ioh_gbe_free_rx_resources(adapter, adapter->rx_ring); | ||
4605 | + | ||
4606 | + return IOH_GBE_SUCCESS; | ||
4607 | +} | ||
4608 | + | ||
4609 | +/*! | ||
4610 | + * @ingroup Gigabit Ethernet driver methods | ||
4611 | + * @fn static int ioh_gbe_xmit_frame(struct sk_buff *skb, | ||
4612 | + * struct net_device *netdev) | ||
4613 | + * @brief Packet transmitting start | ||
4614 | + * @param skb [INOUT] socket buffer structure | ||
4615 | + * @param netdev [INOUT] network interface device structure | ||
4616 | + * @return NETDEV_TX_OK: Normal end | ||
4617 | + * @return NETDEV_TX_BUSY: Error end | ||
4618 | + */ | ||
4619 | +static int ioh_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | ||
4620 | +{ | ||
4621 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
4622 | + struct ioh_gbe_tx_ring *tx_ring = adapter->tx_ring; | ||
4623 | + unsigned long flags; | ||
4624 | + | ||
4625 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
4626 | + | ||
4627 | + if (unlikely(skb->len <= 0)) { | ||
4628 | + dev_kfree_skb_any(skb); | ||
4629 | + IOH_GBE_TESTOUT("Return : OK skb len : %d\n", skb->len); | ||
4630 | + return NETDEV_TX_OK; | ||
4631 | + } | ||
4632 | + if (unlikely(skb->len > (adapter->hw.mac.max_frame_size - 4))) { | ||
4633 | + DPRINTK(PROBE, ERR, "Transfer length Error: %d over %d\n", | ||
4634 | + skb->len, adapter->hw.mac.max_frame_size); | ||
4635 | + dev_kfree_skb_any(skb); | ||
4636 | + adapter->stats.tx_length_errors++; | ||
4637 | + return NETDEV_TX_BUSY; | ||
4638 | + } | ||
4639 | + if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags)) { | ||
4640 | + /* Collision - tell upper layer to requeue */ | ||
4641 | + return NETDEV_TX_LOCKED; | ||
4642 | + } | ||
4643 | + if (unlikely(!IOH_GBE_DESC_UNUSED(tx_ring))) { | ||
4644 | + netif_stop_queue(netdev); | ||
4645 | + spin_unlock_irqrestore(&tx_ring->tx_lock, flags); | ||
4646 | + IOH_GBE_TESTOUT | ||
4647 | + ("Return : BUSY next_to use : 0x%08x " | ||
4648 | + "next_to clean : 0x%08x\n", | ||
4649 | + tx_ring->next_to_use, tx_ring->next_to_clean); | ||
4650 | + return NETDEV_TX_BUSY; | ||
4651 | + } | ||
4652 | + spin_unlock_irqrestore(&tx_ring->tx_lock, flags); | ||
4653 | + | ||
4654 | + /* CRC,ITAG no support */ | ||
4655 | + ioh_gbe_tx_queue(adapter, tx_ring, skb); | ||
4656 | + netdev->trans_start = jiffies; | ||
4657 | + return NETDEV_TX_OK; | ||
4658 | +} | ||
4659 | + | ||
4660 | +/*! | ||
4661 | + * @ingroup Gigabit Ethernet driver methods | ||
4662 | + * @fn static struct net_device_stats *ioh_gbe_get_stats( | ||
4663 | + * struct net_device *netdev) | ||
4664 | + * @brief Get System Network Statistics | ||
4665 | + * @param netdev [INOUT] network interface device structure | ||
4666 | + * @return The current stats | ||
4667 | + * @remarks | ||
4668 | + * Returns the address of the device statistics structure. | ||
4669 | + * The statistics are actually updated from the timer callback. | ||
4670 | + */ | ||
4671 | +static struct net_device_stats *ioh_gbe_get_stats(struct net_device *netdev) | ||
4672 | +{ | ||
4673 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
4674 | + | ||
4675 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
4676 | + | ||
4677 | + /* only return the current stats */ | ||
4678 | + return &adapter->net_stats; | ||
4679 | +} | ||
4680 | + | ||
4681 | +/*! | ||
4682 | + * @ingroup Gigabit Ethernet driver methods | ||
4683 | + * @fn static void ioh_gbe_set_multi(struct net_device *netdev) | ||
4684 | + * @brief Multicast and Promiscuous mode set | ||
4685 | + * @param netdev [INOUT] network interface device structure | ||
4686 | + * @return None | ||
4687 | + * @remarks | ||
4688 | + * The set_multi entry point is called whenever the multicast address | ||
4689 | + * list or the network interface flags are updated. This routine is | ||
4690 | + * responsible for configuring the hardware for proper multicast, | ||
4691 | + * promiscuous mode, and all-multi behavior. | ||
4692 | + */ | ||
4693 | +static void ioh_gbe_set_multi(struct net_device *netdev) | ||
4694 | +{ | ||
4695 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
4696 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
4697 | + struct ioh_gbe_mac_info *mac = &hw->mac; | ||
4698 | + struct dev_mc_list *mc_ptr; | ||
4699 | + u8 *mta_list; | ||
4700 | + u32 rctl; | ||
4701 | + int i; | ||
4702 | + | ||
4703 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
4704 | + IOH_GBE_TESTOUT("netdev->flags : 0x%08x\n", netdev->flags); | ||
4705 | + | ||
4706 | + /* Check for Promiscuous and All Multicast modes */ | ||
4707 | + rctl = IOH_GBE_READ_REG(hw, RX_MODE); | ||
4708 | + | ||
4709 | + if ((netdev->flags & IFF_PROMISC) != 0) { | ||
4710 | + rctl &= ~IOH_GBE_ADD_FIL_EN; | ||
4711 | + rctl &= ~IOH_GBE_MLT_FIL_EN; | ||
4712 | + } else if ((netdev->flags & IFF_ALLMULTI) != 0) { | ||
4713 | + /* all the multicasting receive permissions */ | ||
4714 | + rctl |= IOH_GBE_ADD_FIL_EN; | ||
4715 | + rctl &= ~IOH_GBE_MLT_FIL_EN; | ||
4716 | + } else { | ||
4717 | + if (netdev->mc_count >= IOH_GBE_MAR_ENTRIES) { | ||
4718 | + /* all the multicasting receive permissions */ | ||
4719 | + rctl |= IOH_GBE_ADD_FIL_EN; | ||
4720 | + rctl &= ~IOH_GBE_MLT_FIL_EN; | ||
4721 | + } else { | ||
4722 | + rctl |= (IOH_GBE_ADD_FIL_EN | IOH_GBE_MLT_FIL_EN); | ||
4723 | + } | ||
4724 | + } | ||
4725 | + IOH_GBE_WRITE_REG(hw, RX_MODE, rctl); | ||
4726 | + | ||
4727 | + if (netdev->mc_count >= IOH_GBE_MAR_ENTRIES) | ||
4728 | + return; | ||
4729 | + mta_list = kmalloc(netdev->mc_count * ETH_ALEN, GFP_ATOMIC); | ||
4730 | + if (!mta_list) | ||
4731 | + return; | ||
4732 | + /* The shared function expects a packed array of only addresses. */ | ||
4733 | + mc_ptr = netdev->mc_list; | ||
4734 | + | ||
4735 | + for (i = 0; i < netdev->mc_count; i++) { | ||
4736 | + if (!mc_ptr) | ||
4737 | + break; | ||
4738 | + memcpy(mta_list + (i * ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN); | ||
4739 | + mc_ptr = mc_ptr->next; | ||
4740 | + } | ||
4741 | + | ||
4742 | + ioh_gbe_hal_mc_addr_list_update(hw, mta_list, i, 1, | ||
4743 | + mac->mar_entry_count); | ||
4744 | + kfree(mta_list); | ||
4745 | + | ||
4746 | + IOH_GBE_TESTOUT | ||
4747 | + ("RX_MODE reg(check bit31,30 ADD,MLT) : 0x%08x " | ||
4748 | + "netdev->mc_count : 0x%08x\n", | ||
4749 | + IOH_GBE_READ_REG(hw, RX_MODE), netdev->mc_count); | ||
4750 | +} | ||
4751 | + | ||
4752 | +/*! | ||
4753 | + * @ingroup Gigabit Ethernet driver methods | ||
4754 | + * @fn static int ioh_gbe_set_mac(struct net_device *netdev, void *addr) | ||
4755 | + * @brief Change the Ethernet Address of the NIC | ||
4756 | + * @param netdev [INOUT] Network interface device structure | ||
4757 | + * @param addr [IN] Pointer to an address structure | ||
4758 | + * @return IOH_GBE_SUCCESS: Successfully | ||
4759 | + * @return -EADDRNOTAVAIL: Failed | ||
4760 | + */ | ||
4761 | +static int ioh_gbe_set_mac(struct net_device *netdev, void *addr) | ||
4762 | +{ | ||
4763 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
4764 | + struct sockaddr *skaddr = addr; | ||
4765 | + int ret_val; | ||
4766 | + | ||
4767 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
4768 | + | ||
4769 | + if (!is_valid_ether_addr(skaddr->sa_data)) { | ||
4770 | + ret_val = -EADDRNOTAVAIL; | ||
4771 | + } else { | ||
4772 | + memcpy(netdev->dev_addr, skaddr->sa_data, netdev->addr_len); | ||
4773 | + memcpy(adapter->hw.mac.addr, skaddr->sa_data, netdev->addr_len); | ||
4774 | + ioh_gbe_hal_mar_set(&adapter->hw, adapter->hw.mac.addr, 0); | ||
4775 | + ret_val = IOH_GBE_SUCCESS; | ||
4776 | + } | ||
4777 | +#ifdef DEBUG_TEST | ||
4778 | + IOH_GBE_TESTOUT("ret_val : 0x%08x\n", ret_val); | ||
4779 | + IOH_GBE_TESTOUT("dev_addr : %02x:%02x:%02x:%02x:%02x:%02x\n", | ||
4780 | + netdev->dev_addr[0], netdev->dev_addr[1], | ||
4781 | + netdev->dev_addr[2], netdev->dev_addr[3], | ||
4782 | + netdev->dev_addr[4], netdev->dev_addr[5]); | ||
4783 | + IOH_GBE_TESTOUT("mac_addr : %02x:%02x:%02x:%02x:%02x:%02x\n", | ||
4784 | + adapter->hw.mac.addr[0], adapter->hw.mac.addr[1], | ||
4785 | + adapter->hw.mac.addr[2], adapter->hw.mac.addr[3], | ||
4786 | + adapter->hw.mac.addr[4], adapter->hw.mac.addr[5]); | ||
4787 | + IOH_GBE_TESTOUT("MAC_ADR1AB reg : 0x%08x 0x%08x\n", | ||
4788 | + IOH_GBE_READ_REG(&adapter->hw, MAC_ADR1A), | ||
4789 | + IOH_GBE_READ_REG(&adapter->hw, MAC_ADR1B)); | ||
4790 | +#endif | ||
4791 | + return ret_val; | ||
4792 | +} | ||
4793 | + | ||
4794 | +/*! | ||
4795 | + * @ingroup Gigabit Ethernet driver methods | ||
4796 | + * @fn static int ioh_gbe_change_mtu(struct net_device *netdev, | ||
4797 | + * int new_mtu) | ||
4798 | + * @brief Change the Maximum Transfer Unit | ||
4799 | + * @param netdev [INOUT] Network interface device structure | ||
4800 | + * @param new_mtu [IN] New value for maximum frame size | ||
4801 | + * @return IOH_GBE_SUCCESS: Successfully | ||
4802 | + * @return -EINVAL: Failed | ||
4803 | + */ | ||
4804 | +static int ioh_gbe_change_mtu(struct net_device *netdev, int new_mtu) | ||
4805 | +{ | ||
4806 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
4807 | + int max_frame; | ||
4808 | + | ||
4809 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
4810 | + | ||
4811 | + max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; | ||
4812 | + if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) || | ||
4813 | + (max_frame > IOH_GBE_MAX_JUMBO_FRAME_SIZE)) { | ||
4814 | + DPRINTK(PROBE, ERR, "Invalid MTU setting\n"); | ||
4815 | + return -EINVAL; | ||
4816 | + } | ||
4817 | + if (max_frame <= IOH_GBE_FRAME_SIZE_2048) | ||
4818 | + adapter->rx_buffer_len = IOH_GBE_FRAME_SIZE_2048; | ||
4819 | + else if (max_frame <= IOH_GBE_FRAME_SIZE_4096) | ||
4820 | + adapter->rx_buffer_len = IOH_GBE_FRAME_SIZE_4096; | ||
4821 | + else if (max_frame <= IOH_GBE_FRAME_SIZE_8192) | ||
4822 | + adapter->rx_buffer_len = IOH_GBE_FRAME_SIZE_8192; | ||
4823 | + else | ||
4824 | + adapter->rx_buffer_len = IOH_GBE_MAX_JUMBO_FRAME_SIZE; | ||
4825 | + netdev->mtu = new_mtu; | ||
4826 | + adapter->hw.mac.max_frame_size = max_frame; | ||
4827 | + | ||
4828 | + if (netif_running(netdev) != 0) | ||
4829 | + ioh_gbe_reinit_locked(adapter); | ||
4830 | + else | ||
4831 | + ioh_gbe_reset(adapter); | ||
4832 | + | ||
4833 | + IOH_GBE_TESTOUT | ||
4834 | + ("max_frame : %d rx_buffer_len : %d mtu : %d max_frame_size : %d\n", | ||
4835 | + max_frame, (u32) adapter->rx_buffer_len, netdev->mtu, | ||
4836 | + adapter->hw.mac.max_frame_size); | ||
4837 | + | ||
4838 | + return IOH_GBE_SUCCESS; | ||
4839 | +} | ||
4840 | + | ||
4841 | +/*! | ||
4842 | + * @ingroup Gigabit Ethernet driver methods | ||
4843 | + * @fn static int ioh_gbe_ioctl(struct net_device *netdev, | ||
4844 | + * struct ifreq *ifr, int cmd) | ||
4845 | + * @brief Controls register through a MII interface | ||
4846 | + * @param netdev [INOUT] Network interface device structure | ||
4847 | + * @param ifr [IN] Pointer to ifr structure | ||
4848 | + * @param cmd [IN] Control command | ||
4849 | + * @return IOH_GBE_SUCCESS: Successfully | ||
4850 | + * @return Negative value: Failed | ||
4851 | + */ | ||
4852 | +static int ioh_gbe_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | ||
4853 | +{ | ||
4854 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
4855 | + | ||
4856 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
4857 | + IOH_GBE_TESTOUT("cmd : 0x%04x\n", cmd); | ||
4858 | + | ||
4859 | + return generic_mii_ioctl(&adapter->mii, if_mii(ifr), cmd, NULL); | ||
4860 | +} | ||
4861 | + | ||
4862 | +/*! | ||
4863 | + * @ingroup Gigabit Ethernet driver methods | ||
4864 | + * @fn static void ioh_gbe_tx_timeout(struct net_device *netdev) | ||
4865 | + * @brief Respond to a Tx Hang | ||
4866 | + * @param netdev [INOUT] Network interface device structure | ||
4867 | + * @return None | ||
4868 | + */ | ||
4869 | +static void ioh_gbe_tx_timeout(struct net_device *netdev) | ||
4870 | +{ | ||
4871 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
4872 | + | ||
4873 | + DPRINTK(TX_ERR, DEBUG, "\n"); | ||
4874 | + | ||
4875 | + /* Do the reset outside of interrupt context */ | ||
4876 | + adapter->stats.tx_timeout_count++; | ||
4877 | + schedule_work(&adapter->reset_task); | ||
4878 | +} | ||
4879 | + | ||
4880 | +/*! | ||
4881 | + * @ingroup Gigabit Ethernet driver methods | ||
4882 | + * @fn static int ioh_gbe_napi_poll(struct napi_struct *napi, int budget) | ||
4883 | + * @brief NAPI receive and transfer polling callback | ||
4884 | + * @param napi [INOUT] Pointer of polling device struct | ||
4885 | + * @param budget [IN] The maximum number of a packet | ||
4886 | + * @return 0 : Exit the polling mode | ||
4887 | + * @return 1 : Continue the polling mode | ||
4888 | + */ | ||
4889 | +static int ioh_gbe_napi_poll(struct napi_struct *napi, int budget) | ||
4890 | +{ | ||
4891 | + struct ioh_gbe_adapter *adapter = | ||
4892 | + container_of(napi, struct ioh_gbe_adapter, napi); | ||
4893 | + struct net_device *netdev = adapter->netdev; | ||
4894 | + int work_done = 0; | ||
4895 | + int poll_end_flag = 0; | ||
4896 | + int cleaned = 0; | ||
4897 | + | ||
4898 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
4899 | + IOH_GBE_TESTOUT("budget : %d\n", budget); | ||
4900 | + | ||
4901 | + /* Keep link state information with original netdev */ | ||
4902 | + if (!netif_carrier_ok(netdev)) { | ||
4903 | + poll_end_flag = 1; | ||
4904 | + } else { | ||
4905 | + cleaned = ioh_gbe_clean_tx(adapter, adapter->tx_ring); | ||
4906 | + ioh_gbe_clean_rx(adapter, adapter->rx_ring, &work_done, budget); | ||
4907 | + | ||
4908 | + if (cleaned) | ||
4909 | + work_done = budget; | ||
4910 | + /* If no Tx and not enough Rx work done, | ||
4911 | + * exit the polling mode | ||
4912 | + */ | ||
4913 | + if ((work_done < budget) || !netif_running(netdev)) | ||
4914 | + poll_end_flag = 1; | ||
4915 | + } | ||
4916 | + | ||
4917 | + if (poll_end_flag == 1) { | ||
4918 | + napi_complete(napi); | ||
4919 | + ioh_gbe_irq_enable(adapter); | ||
4920 | + } | ||
4921 | + | ||
4922 | + IOH_GBE_TESTOUT("poll_end_flag : %d work_done : %d budget : %d\n", | ||
4923 | + poll_end_flag, work_done, budget); | ||
4924 | + return work_done; | ||
4925 | +} | ||
4926 | + | ||
4927 | +#ifdef CONFIG_NET_POLL_CONTROLLER | ||
4928 | +/*! | ||
4929 | + * @ingroup Gigabit Ethernet driver methods | ||
4930 | + * @fn static void ioh_gbe_netpoll(struct net_device *netdev) | ||
4931 | + * @brief Used by things like netconsole to send skbs | ||
4932 | + * @param netdev [INOUT] Network interface device structure | ||
4933 | + * @return None | ||
4934 | + * @remarks | ||
4935 | + * used by things like netconsole to send skbs | ||
4936 | + * without having to re-enable interrupts. | ||
4937 | + * It's not called while the interrupt routine is executing. | ||
4938 | + */ | ||
4939 | +static void ioh_gbe_netpoll(struct net_device *netdev) | ||
4940 | +{ | ||
4941 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
4942 | + | ||
4943 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
4944 | + | ||
4945 | + disable_irq(adapter->pdev->irq); | ||
4946 | + ioh_gbe_intr(adapter->pdev->irq, netdev); | ||
4947 | + enable_irq(adapter->pdev->irq); | ||
4948 | +} | ||
4949 | +#endif | ||
4950 | + | ||
4951 | +/* ---------------------------------------------------------------------------- | ||
4952 | + Linux driver internal function | ||
4953 | +---------------------------------------------------------------------------- */ | ||
4954 | +/*! | ||
4955 | + * @ingroup Linux driver internal function | ||
4956 | + * @fn static int ioh_gbe_sw_init(struct ioh_gbe_adapter *adapter) | ||
4957 | + * @brief Initialize general software structures (struct ioh_gbe_adapter) | ||
4958 | + * @param adapter [INOUT] Board private structure to initialize | ||
4959 | + * @return IOH_GBE_SUCCESS: Successfully | ||
4960 | + * @return Negative value: Failed | ||
4961 | + * @remarks | ||
4962 | + * ioh_gbe_sw_init initializes the Adapter private data structure. | ||
4963 | + * Fields are initialized based on PCI device information and | ||
4964 | + * OS network device settings (MTU size). | ||
4965 | + */ | ||
4966 | +static int ioh_gbe_sw_init(struct ioh_gbe_adapter *adapter) | ||
4967 | +{ | ||
4968 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
4969 | + struct net_device *netdev = adapter->netdev; | ||
4970 | + struct pci_dev *pdev = adapter->pdev; | ||
4971 | + | ||
4972 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
4973 | + | ||
4974 | + /* PCI config space info */ | ||
4975 | + hw->vendor_id = pdev->vendor; | ||
4976 | + hw->device_id = pdev->device; | ||
4977 | + hw->subsystem_vendor_id = pdev->subsystem_vendor; | ||
4978 | + hw->subsystem_device_id = pdev->subsystem_device; | ||
4979 | + | ||
4980 | + pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id); | ||
4981 | + | ||
4982 | + adapter->rx_buffer_len = IOH_GBE_FRAME_SIZE_2048; | ||
4983 | + hw->mac.max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; | ||
4984 | + hw->mac.min_frame_size = ETH_ZLEN + ETH_FCS_LEN; | ||
4985 | + | ||
4986 | + /* Initialize the hardware-specific values */ | ||
4987 | + if (ioh_gbe_hal_setup_init_funcs(hw) != 0) { | ||
4988 | + DPRINTK(PROBE, ERR, "Hardware Initialization Failure\n"); | ||
4989 | + return -EIO; | ||
4990 | + } | ||
4991 | + if (ioh_gbe_alloc_queues(adapter) != 0) { | ||
4992 | + DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n"); | ||
4993 | + return -ENOMEM; | ||
4994 | + } | ||
4995 | + dev_hold(adapter->polling_netdev); | ||
4996 | + set_bit(__LINK_STATE_START, &adapter->polling_netdev->state); | ||
4997 | + | ||
4998 | + spin_lock_init(&adapter->hw.miim_lock); | ||
4999 | + spin_lock_init(&adapter->stats_lock); | ||
5000 | + atomic_set(&adapter->irq_sem, 0); | ||
5001 | + ioh_gbe_irq_disable(adapter); | ||
5002 | + | ||
5003 | + ioh_gbe_init_stats(adapter); | ||
5004 | + | ||
5005 | +#ifdef DEBUG_TEST | ||
5006 | + IOH_GBE_TESTOUT("hw->vendor_id : 0x%08x\n", hw->vendor_id); | ||
5007 | + IOH_GBE_TESTOUT("hw->device_id : 0x%08x\n", hw->device_id); | ||
5008 | + IOH_GBE_TESTOUT("hw->subsystem_vendor_id :0x%08x\n", | ||
5009 | + hw->subsystem_vendor_id); | ||
5010 | + IOH_GBE_TESTOUT("hw->subsystem_device_id :0x%08x\n", | ||
5011 | + hw->subsystem_device_id); | ||
5012 | + IOH_GBE_TESTOUT("hw->revision_id :0x%08x\n", hw->revision_id); | ||
5013 | + IOH_GBE_TESTOUT("adapter->rx_buffer_len : %d\n", | ||
5014 | + (u32) adapter->rx_buffer_len); | ||
5015 | + IOH_GBE_TESTOUT("hw->mac.max_frame_size : %d\n", | ||
5016 | + hw->mac.max_frame_size); | ||
5017 | + IOH_GBE_TESTOUT("hw->mac.min_frame_size : %d\n", | ||
5018 | + hw->mac.min_frame_size); | ||
5019 | +#endif | ||
5020 | + return IOH_GBE_SUCCESS; | ||
5021 | +} | ||
5022 | + | ||
5023 | +/*! | ||
5024 | + * @ingroup Linux driver internal function | ||
5025 | + * @fn static int ioh_gbe_alloc_queues(struct ioh_gbe_adapter *adapter) | ||
5026 | + * @brief Allocate memory for all rings | ||
5027 | + * @param adapter [INOUT] Board private structure to initialize | ||
5028 | + * @return IOH_GBE_SUCCESS: Successfully | ||
5029 | + * @return Negative value: Failed | ||
5030 | + * @remarks | ||
5031 | + * We allocate one ring per queue at run-time since we don't know the | ||
5032 | + * number of queues at compile-time. The polling_netdev array is | ||
5033 | + * intended for Multiqueue, but should work fine with a single queue. | ||
5034 | + */ | ||
5035 | +static int ioh_gbe_alloc_queues(struct ioh_gbe_adapter *adapter) | ||
5036 | +{ | ||
5037 | + int size; | ||
5038 | + | ||
5039 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
5040 | + | ||
5041 | + size = (int)sizeof(struct ioh_gbe_tx_ring); | ||
5042 | + adapter->tx_ring = kmalloc(size, GFP_KERNEL); | ||
5043 | + if (!adapter->tx_ring) | ||
5044 | + return -ENOMEM; | ||
5045 | + memset(adapter->tx_ring, 0, size); | ||
5046 | + | ||
5047 | + size = (int)sizeof(struct ioh_gbe_rx_ring); | ||
5048 | + adapter->rx_ring = kmalloc(size, GFP_KERNEL); | ||
5049 | + if (!adapter->rx_ring) { | ||
5050 | + kfree(adapter->tx_ring); | ||
5051 | + return -ENOMEM; | ||
5052 | + } | ||
5053 | + memset(adapter->rx_ring, 0, size); | ||
5054 | + | ||
5055 | + size = (int)sizeof(struct net_device); | ||
5056 | + adapter->polling_netdev = kmalloc(size, GFP_KERNEL); | ||
5057 | + if (!adapter->polling_netdev) { | ||
5058 | + kfree(adapter->tx_ring); | ||
5059 | + kfree(adapter->rx_ring); | ||
5060 | + return -ENOMEM; | ||
5061 | + } | ||
5062 | + memset(adapter->polling_netdev, 0, size); | ||
5063 | + | ||
5064 | +#ifdef DEBUG_TEST | ||
5065 | + { | ||
5066 | + u32 *st_area, *sp_area; | ||
5067 | + st_area = (u32 *) adapter->tx_ring; | ||
5068 | + sp_area = (u32 *) (adapter->tx_ring + | ||
5069 | + (int)sizeof(struct ioh_gbe_tx_ring) - 1); | ||
5070 | + IOH_GBE_TESTOUT("tx_ring : 0x%08x - 0x%08x\n", *st_area, | ||
5071 | + *sp_area); | ||
5072 | + st_area = (u32 *) adapter->rx_ring; | ||
5073 | + sp_area = (u32 *) (adapter->rx_ring + | ||
5074 | + (int)sizeof(struct ioh_gbe_rx_ring) - 1); | ||
5075 | + IOH_GBE_TESTOUT("rx_ring : 0x%08x - 0x%08x\n", *st_area, | ||
5076 | + *sp_area); | ||
5077 | + st_area = (u32 *) adapter->polling_netdev; | ||
5078 | + sp_area = (u32 *) (adapter->polling_netdev + | ||
5079 | + (int)sizeof(struct net_device) - 1); | ||
5080 | + IOH_GBE_TESTOUT("polling_netdev : 0x%08x - 0x%08x\n", | ||
5081 | + *st_area, *sp_area); | ||
5082 | + } | ||
5083 | +#endif | ||
5084 | + return IOH_GBE_SUCCESS; | ||
5085 | +} | ||
5086 | + | ||
5087 | +/*! | ||
5088 | + * @ingroup Linux driver internal function | ||
5089 | + * @fn static void ioh_gbe_init_stats(struct ioh_gbe_adapter *adapter) | ||
5090 | + * @brief Initialize status | ||
5091 | + * @param adapter [INOUT] Board private structure to initialize | ||
5092 | + * @return None | ||
5093 | + */ | ||
5094 | +static void ioh_gbe_init_stats(struct ioh_gbe_adapter *adapter) | ||
5095 | +{ | ||
5096 | + struct ioh_gbe_hw_stats *stats = &adapter->stats; | ||
5097 | + | ||
5098 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
5099 | + | ||
5100 | + stats->rx_packets = 0; | ||
5101 | + stats->tx_packets = 0; | ||
5102 | + stats->rx_bytes = 0; | ||
5103 | + stats->tx_bytes = 0; | ||
5104 | + stats->rx_errors = 0; | ||
5105 | + stats->tx_errors = 0; | ||
5106 | + stats->rx_dropped = 0; | ||
5107 | + stats->tx_dropped = 0; | ||
5108 | + stats->multicast = 0; | ||
5109 | + stats->collisions = 0; | ||
5110 | + stats->rx_crc_errors = 0; | ||
5111 | + stats->rx_frame_errors = 0; | ||
5112 | + stats->rx_alloc_buff_failed = 0; | ||
5113 | + stats->tx_length_errors = 0; | ||
5114 | + stats->tx_aborted_errors = 0; | ||
5115 | + stats->tx_carrier_errors = 0; | ||
5116 | + stats->tx_timeout_count = 0; | ||
5117 | + stats->tx_restart_count = 0; | ||
5118 | + stats->intr_rx_dsc_empty_count = 0; | ||
5119 | + stats->intr_rx_frame_err_count = 0; | ||
5120 | + stats->intr_rx_fifo_err_count = 0; | ||
5121 | + stats->intr_rx_dma_err_count = 0; | ||
5122 | + stats->intr_tx_fifo_err_count = 0; | ||
5123 | + stats->intr_tx_dma_err_count = 0; | ||
5124 | + stats->intr_tcpip_err_count = 0; | ||
5125 | + return; | ||
5126 | +} | ||
5127 | + | ||
5128 | +/*! | ||
5129 | + * @ingroup Linux driver internal function | ||
5130 | + * @fn static int ioh_gbe_init_nvm(struct ioh_gbe_adapter *adapter) | ||
5131 | + * @brief Initialize NVM | ||
5132 | + * @param adapter [INOUT] Board private structure to initialize | ||
5133 | + * @return IOH_GBE_SUCCESS: Successfully | ||
5134 | + * @return Negative value: Failed | ||
5135 | + */ | ||
5136 | +static int ioh_gbe_init_nvm(struct ioh_gbe_adapter *adapter) | ||
5137 | +{ | ||
5138 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
5139 | + | ||
5140 | +#ifdef CONFIG_PCH_PCIEQOS | ||
5141 | + /* make sure the NVM is good */ | ||
5142 | + if ((ioh_gbe_hal_validate_nvm_checksum(&adapter->hw) < 0)) { | ||
5143 | + DPRINTK(PROBE, ERR, "The NVM Checksum Is Not Valid\n"); | ||
5144 | + return -EIO; | ||
5145 | + } | ||
5146 | +#endif | ||
5147 | + return IOH_GBE_SUCCESS; | ||
5148 | +} | ||
5149 | + | ||
5150 | +/*! | ||
5151 | + * @ingroup Linux driver internal function | ||
5152 | + * @fn static int ioh_gbe_init_phy(struct ioh_gbe_adapter *adapter) | ||
5153 | + * @brief Initialize PHY | ||
5154 | + * @param adapter [INOUT] Board private structure to initialize | ||
5155 | + * @return IOH_GBE_SUCCESS: Successfully | ||
5156 | + * @return Negative value: Failed | ||
5157 | + */ | ||
5158 | +static int ioh_gbe_init_phy(struct ioh_gbe_adapter *adapter) | ||
5159 | +{ | ||
5160 | + struct net_device *netdev = adapter->netdev; | ||
5161 | + u32 addr; | ||
5162 | + u16 bmcr, stat; | ||
5163 | + | ||
5164 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
5165 | + | ||
5166 | + /* Discover phy addr by searching addrs in order {1,0,2,..., 31} */ | ||
5167 | + for (addr = 0; addr <= PHY_MAX_REG_ADDRESS; addr++) { | ||
5168 | + adapter->mii.phy_id = (addr == 0) ? 1 : (addr == 1) ? 0 : addr; | ||
5169 | + bmcr = ioh_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMCR); | ||
5170 | + stat = ioh_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMSR); | ||
5171 | + stat = ioh_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMSR); | ||
5172 | + if (!((bmcr == 0xFFFF) || ((stat == 0) && (bmcr == 0)))) | ||
5173 | + break; | ||
5174 | + } | ||
5175 | + adapter->hw.phy.addr = adapter->mii.phy_id; | ||
5176 | + DPRINTK(PROBE, DEBUG, "phy_addr = %d\n", adapter->mii.phy_id); | ||
5177 | + if (addr == 32) | ||
5178 | + return -EAGAIN; | ||
5179 | + /* Selected the phy and isolate the rest */ | ||
5180 | + for (addr = 0; addr <= PHY_MAX_REG_ADDRESS; addr++) { | ||
5181 | + if (addr != adapter->mii.phy_id) { | ||
5182 | + ioh_gbe_mdio_write(netdev, addr, MII_BMCR, | ||
5183 | + BMCR_ISOLATE); | ||
5184 | + } else { | ||
5185 | + bmcr = ioh_gbe_mdio_read(netdev, addr, MII_BMCR); | ||
5186 | + ioh_gbe_mdio_write(netdev, addr, MII_BMCR, | ||
5187 | + bmcr & ~BMCR_ISOLATE); | ||
5188 | + } | ||
5189 | + } | ||
5190 | + | ||
5191 | + /* MII setup */ | ||
5192 | + adapter->mii.phy_id_mask = 0x1F; | ||
5193 | + adapter->mii.reg_num_mask = 0x1F; | ||
5194 | + adapter->mii.dev = adapter->netdev; | ||
5195 | + adapter->mii.mdio_read = ioh_gbe_mdio_read; | ||
5196 | + adapter->mii.mdio_write = ioh_gbe_mdio_write; | ||
5197 | + adapter->mii.supports_gmii = mii_check_gmii_support(&adapter->mii); | ||
5198 | + return IOH_GBE_SUCCESS; | ||
5199 | +} | ||
5200 | + | ||
5201 | +/*! | ||
5202 | + * @ingroup Linux driver internal function | ||
5203 | + * @fn int ioh_gbe_mdio_read(struct net_device *netdev, int addr, int reg) | ||
5204 | + * @brief The read function for mii | ||
5205 | + * @param netdev [INOUT] Network interface device structure | ||
5206 | + * @param addr [IN] Phy ID | ||
5207 | + * @param reg [IN] Access location | ||
5208 | + * @return IOH_GBE_SUCCESS: Successfully | ||
5209 | + * @return Negative value: Failed | ||
5210 | + */ | ||
5211 | +int ioh_gbe_mdio_read(struct net_device *netdev, int addr, int reg) | ||
5212 | +{ | ||
5213 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
5214 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
5215 | + | ||
5216 | + IOH_GBE_DBGOUT2("ioh_gbe_mdio_read\n"); | ||
5217 | + return ioh_gbe_hal_ctrl_miim(hw, addr, IOH_GBE_HAL_MIIM_READ, | ||
5218 | + reg, (u16) 0); | ||
5219 | +} | ||
5220 | + | ||
5221 | +/*! | ||
5222 | + * @ingroup Linux driver internal function | ||
5223 | + * @fn void ioh_gbe_mdio_write(struct net_device *netdev, | ||
5224 | + * int addr, int reg, int data) | ||
5225 | + * @brief TThe write function for mii | ||
5226 | + * @param netdev [INOUT] Network interface device structure | ||
5227 | + * @param addr [IN] Phy ID (not used) | ||
5228 | + * @param reg [IN]Access location | ||
5229 | + * @param data [IN] Write data | ||
5230 | + * @return None | ||
5231 | + */ | ||
5232 | +void ioh_gbe_mdio_write(struct net_device *netdev, int addr, int reg, int data) | ||
5233 | +{ | ||
5234 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
5235 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
5236 | + | ||
5237 | + IOH_GBE_DBGOUT2("ioh_gbe_mdio_write\n"); | ||
5238 | + ioh_gbe_hal_ctrl_miim(hw, addr, IOH_GBE_HAL_MIIM_WRITE, reg, data); | ||
5239 | +} | ||
5240 | + | ||
5241 | +/*! | ||
5242 | + * @ingroup Linux driver internal function | ||
5243 | + * @fn static void ioh_gbe_reset_task(struct work_struct *work) | ||
5244 | + * @brief Reset processing at the time of transmission timeout | ||
5245 | + * @param work [INOUT] Pointer of board private structure | ||
5246 | + * @return None | ||
5247 | + */ | ||
5248 | +static void ioh_gbe_reset_task(struct work_struct *work) | ||
5249 | +{ | ||
5250 | + struct ioh_gbe_adapter *adapter; | ||
5251 | + adapter = container_of(work, struct ioh_gbe_adapter, reset_task); | ||
5252 | + | ||
5253 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
5254 | + | ||
5255 | + ioh_gbe_reinit_locked(adapter); | ||
5256 | +} | ||
5257 | + | ||
5258 | +/*! | ||
5259 | + * @ingroup Linux driver internal function | ||
5260 | + * @fn void ioh_gbe_reinit_locked(struct ioh_gbe_adapter *adapter) | ||
5261 | + * @brief Re-initialization | ||
5262 | + * @param adapter [INOUT] Board private structure | ||
5263 | + * @return None | ||
5264 | + */ | ||
5265 | +void ioh_gbe_reinit_locked(struct ioh_gbe_adapter *adapter) | ||
5266 | +{ | ||
5267 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
5268 | + | ||
5269 | + while ((test_and_set_bit(__IOH_GBE_RESETTING, &adapter->flags)) != 0) | ||
5270 | + msleep(1); | ||
5271 | + ioh_gbe_down(adapter); | ||
5272 | + ioh_gbe_up(adapter); | ||
5273 | + clear_bit(__IOH_GBE_RESETTING, &adapter->flags); | ||
5274 | +} | ||
5275 | + | ||
5276 | +/*! | ||
5277 | + * @ingroup Linux driver internal function | ||
5278 | + * @fn void ioh_gbe_reset(struct ioh_gbe_adapter *adapter) | ||
5279 | + * @brief Reset GbE | ||
5280 | + * @param adapter [INOUT] Board private structure | ||
5281 | + * @return None | ||
5282 | + */ | ||
5283 | +void ioh_gbe_reset(struct ioh_gbe_adapter *adapter) | ||
5284 | +{ | ||
5285 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
5286 | + | ||
5287 | + ioh_gbe_hal_reset_hw(&adapter->hw); | ||
5288 | + | ||
5289 | + if (ioh_gbe_hal_init_hw(&adapter->hw) != 0) | ||
5290 | + DPRINTK(PROBE, ERR, "Hardware Error\n"); | ||
5291 | +} | ||
5292 | + | ||
5293 | +/*! | ||
5294 | + * @ingroup Linux driver internal function | ||
5295 | + * @fn static int ioh_gbe_request_irq(struct ioh_gbe_adapter *adapter) | ||
5296 | + * @brief Allocate an interrupt line | ||
5297 | + * @param adapter [INOUT] Board private structure | ||
5298 | + * @return IOH_GBE_SUCCESS: Successfully | ||
5299 | + * @return Negative value: Failed | ||
5300 | + */ | ||
5301 | +static int ioh_gbe_request_irq(struct ioh_gbe_adapter *adapter) | ||
5302 | +{ | ||
5303 | + struct net_device *netdev = adapter->netdev; | ||
5304 | + int err; | ||
5305 | + int flags; | ||
5306 | + | ||
5307 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
5308 | + | ||
5309 | + flags = IRQF_SHARED; | ||
5310 | + adapter->have_msi = FALSE; | ||
5311 | + err = pci_enable_msi(adapter->pdev); | ||
5312 | + IOH_GBE_DBGOUT("call pci_enable_msi\n"); | ||
5313 | + if (err != 0) { | ||
5314 | + DPRINTK(PROBE, ERR, | ||
5315 | + "Unable to allocate MSI interrupt Error: %d\n", err); | ||
5316 | + } else { | ||
5317 | + flags = 0; | ||
5318 | + adapter->have_msi = TRUE; | ||
5319 | + } | ||
5320 | + err = request_irq(adapter->pdev->irq, &ioh_gbe_intr, | ||
5321 | + flags, netdev->name, netdev); | ||
5322 | + if (err != 0) { | ||
5323 | + DPRINTK(PROBE, ERR, "Unable to allocate interrupt Error: %d\n", | ||
5324 | + err); | ||
5325 | + } | ||
5326 | + | ||
5327 | + IOH_GBE_TESTOUT | ||
5328 | + ("adapter->have_msi : %d flags : 0x%04x return : 0x%04x\n", | ||
5329 | + adapter->have_msi, flags, err); | ||
5330 | + return err; | ||
5331 | +} | ||
5332 | + | ||
5333 | +/*! | ||
5334 | + * @ingroup Linux driver internal function | ||
5335 | + * @fn static void ioh_gbe_free_irq(struct ioh_gbe_adapter *adapter) | ||
5336 | + * @brief Free an interrupt | ||
5337 | + * @param adapter [INOUT] Board private structure | ||
5338 | + * @return None | ||
5339 | + */ | ||
5340 | +static void ioh_gbe_free_irq(struct ioh_gbe_adapter *adapter) | ||
5341 | +{ | ||
5342 | + struct net_device *netdev = adapter->netdev; | ||
5343 | + | ||
5344 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
5345 | + | ||
5346 | + free_irq(adapter->pdev->irq, netdev); | ||
5347 | + if (adapter->have_msi != 0) { | ||
5348 | + pci_disable_msi(adapter->pdev); | ||
5349 | + IOH_GBE_DBGOUT("call pci_disable_msi"); | ||
5350 | + } | ||
5351 | +} | ||
5352 | + | ||
5353 | +/*! | ||
5354 | + * @ingroup Linux driver internal function | ||
5355 | + * @fn static void ioh_gbe_irq_disable(struct ioh_gbe_adapter *adapter) | ||
5356 | + * @brief Mask off interrupt generation on the NIC | ||
5357 | + * @param adapter [INOUT] Board private structure | ||
5358 | + * @return None | ||
5359 | + */ | ||
5360 | +static void ioh_gbe_irq_disable(struct ioh_gbe_adapter *adapter) | ||
5361 | +{ | ||
5362 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
5363 | + | ||
5364 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
5365 | + | ||
5366 | + atomic_inc(&adapter->irq_sem); | ||
5367 | + IOH_GBE_WRITE_REG(hw, INT_EN, 0); | ||
5368 | + synchronize_irq(adapter->pdev->irq); | ||
5369 | + | ||
5370 | + IOH_GBE_TESTOUT("INT_EN reg : 0x%08x\n", IOH_GBE_READ_REG(hw, INT_EN)); | ||
5371 | +} | ||
5372 | + | ||
5373 | +/*! | ||
5374 | + * @ingroup Linux driver internal function | ||
5375 | + * @fn static void ioh_gbe_irq_enable(struct ioh_gbe_adapter *adapter) | ||
5376 | + * @brief Enable default interrupt generation settings | ||
5377 | + * @param adapter [INOUT] Board private structure | ||
5378 | + * @return None | ||
5379 | + */ | ||
5380 | +static void ioh_gbe_irq_enable(struct ioh_gbe_adapter *adapter) | ||
5381 | +{ | ||
5382 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
5383 | + | ||
5384 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
5385 | + | ||
5386 | + if (likely(atomic_dec_and_test(&adapter->irq_sem))) | ||
5387 | + IOH_GBE_WRITE_REG(hw, INT_EN, IOH_GBE_INT_ENABLE_MASK); | ||
5388 | + IOH_GBE_TESTOUT("INT_EN reg : 0x%08x\n", IOH_GBE_READ_REG(hw, INT_EN)); | ||
5389 | +} | ||
5390 | + | ||
5391 | +/*! | ||
5392 | + * @ingroup Linux driver internal function | ||
5393 | + * @fn int ioh_gbe_up(struct ioh_gbe_adapter *adapter) | ||
5394 | + * @brief Up GbE network device | ||
5395 | + * @param adapter [INOUT] Board private structure | ||
5396 | + * @return IOH_GBE_SUCCESS: Successfully | ||
5397 | + * @return Negative value: Failed | ||
5398 | + */ | ||
5399 | +int ioh_gbe_up(struct ioh_gbe_adapter *adapter) | ||
5400 | +{ | ||
5401 | + struct net_device *netdev = adapter->netdev; | ||
5402 | + struct ioh_gbe_tx_ring *tx_ring = adapter->tx_ring; | ||
5403 | + struct ioh_gbe_rx_ring *rx_ring = adapter->rx_ring; | ||
5404 | + int err; | ||
5405 | + | ||
5406 | + DPRINTK(IFUP, DEBUG, "\n"); | ||
5407 | + | ||
5408 | + /* hardware has been reset, we need to reload some things */ | ||
5409 | + ioh_gbe_set_multi(netdev); | ||
5410 | + | ||
5411 | + ioh_gbe_setup_tctl(adapter); | ||
5412 | + ioh_gbe_configure_tx(adapter); | ||
5413 | + ioh_gbe_setup_rctl(adapter); | ||
5414 | + ioh_gbe_configure_rx(adapter); | ||
5415 | + | ||
5416 | + err = ioh_gbe_request_irq(adapter); | ||
5417 | + if (err != 0) { | ||
5418 | + IOH_GBE_ERR("Error: can't bring device up\n"); | ||
5419 | + return err; | ||
5420 | + } | ||
5421 | + ioh_gbe_alloc_tx_buffers(adapter, tx_ring); | ||
5422 | + ioh_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count); | ||
5423 | + adapter->tx_queue_len = netdev->tx_queue_len; | ||
5424 | + | ||
5425 | + mod_timer(&adapter->watchdog_timer, jiffies); | ||
5426 | + | ||
5427 | + napi_enable(&adapter->napi); | ||
5428 | + ioh_gbe_irq_enable(adapter); | ||
5429 | + netif_start_queue(adapter->netdev); | ||
5430 | + | ||
5431 | + return IOH_GBE_SUCCESS; | ||
5432 | +} | ||
5433 | + | ||
5434 | +/*! | ||
5435 | + * @ingroup Linux driver internal function | ||
5436 | + * @fn void ioh_gbe_down(struct ioh_gbe_adapter *adapter) | ||
5437 | + * @brief Down GbE network device | ||
5438 | + * @param adapter [INOUT] Board private structure | ||
5439 | + * @return None | ||
5440 | + */ | ||
5441 | +void ioh_gbe_down(struct ioh_gbe_adapter *adapter) | ||
5442 | +{ | ||
5443 | + struct net_device *netdev = adapter->netdev; | ||
5444 | + | ||
5445 | + DPRINTK(IFDOWN, DEBUG, "\n"); | ||
5446 | + | ||
5447 | + /* signal that we're down so the interrupt handler does not | ||
5448 | + * reschedule our watchdog timer */ | ||
5449 | + napi_disable(&adapter->napi); | ||
5450 | + atomic_set(&adapter->irq_sem, 0); | ||
5451 | + | ||
5452 | + ioh_gbe_irq_disable(adapter); | ||
5453 | + ioh_gbe_free_irq(adapter); | ||
5454 | + | ||
5455 | + del_timer_sync(&adapter->watchdog_timer); | ||
5456 | + | ||
5457 | + netdev->tx_queue_len = adapter->tx_queue_len; | ||
5458 | + netif_carrier_off(netdev); | ||
5459 | + netif_stop_queue(netdev); | ||
5460 | + | ||
5461 | + ioh_gbe_reset(adapter); | ||
5462 | + ioh_gbe_clean_tx_ring(adapter, adapter->tx_ring); | ||
5463 | + ioh_gbe_clean_rx_ring(adapter, adapter->rx_ring); | ||
5464 | +} | ||
5465 | + | ||
5466 | +/*! | ||
5467 | + * @ingroup Linux driver internal function | ||
5468 | + * @fn int ioh_gbe_setup_tx_resources(struct ioh_gbe_adapter *adapter, | ||
5469 | + * struct ioh_gbe_tx_ring *tx_ring) | ||
5470 | + * @brief Allocate Tx resources (Descriptors) | ||
5471 | + * @param adapter [INOUT] Board private structure | ||
5472 | + * @param tx_ring [OUT] Tx descriptor ring (for a specific queue) to setup | ||
5473 | + * @return IOH_GBE_SUCCESS: Successfully | ||
5474 | + * @return Negative value: Failed | ||
5475 | + */ | ||
5476 | +int | ||
5477 | +ioh_gbe_setup_tx_resources(struct ioh_gbe_adapter *adapter, | ||
5478 | + struct ioh_gbe_tx_ring *tx_ring) | ||
5479 | +{ | ||
5480 | + struct pci_dev *pdev = adapter->pdev; | ||
5481 | + struct ioh_gbe_tx_desc *tx_desc; | ||
5482 | + int size; | ||
5483 | + int desNo; | ||
5484 | + | ||
5485 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
5486 | + | ||
5487 | + size = (int)sizeof(struct ioh_gbe_buffer) * tx_ring->count; | ||
5488 | + tx_ring->buffer_info = vmalloc(size); | ||
5489 | + if (!tx_ring->buffer_info) { | ||
5490 | + DPRINTK(PROBE, ERR, | ||
5491 | + "Unable to allocate memory " | ||
5492 | + "for the buffer infomation\n"); | ||
5493 | + return -ENOMEM; | ||
5494 | + } | ||
5495 | + memset(tx_ring->buffer_info, 0, size); | ||
5496 | + | ||
5497 | + tx_ring->size = tx_ring->count * (int)sizeof(struct ioh_gbe_tx_desc); | ||
5498 | + | ||
5499 | + tx_ring->desc = | ||
5500 | + pci_alloc_consistent(pdev, tx_ring->size, &tx_ring->dma); | ||
5501 | + if (!tx_ring->desc) { | ||
5502 | + vfree(tx_ring->buffer_info); | ||
5503 | + DPRINTK(PROBE, ERR, | ||
5504 | + "Unable to allocate memory " | ||
5505 | + "for the transmit descriptor ring\n"); | ||
5506 | + return -ENOMEM; | ||
5507 | + } | ||
5508 | + memset(tx_ring->desc, 0, tx_ring->size); | ||
5509 | + | ||
5510 | + tx_ring->next_to_use = 0; | ||
5511 | + tx_ring->next_to_clean = 0; | ||
5512 | + spin_lock_init(&tx_ring->tx_lock); | ||
5513 | + | ||
5514 | + for (desNo = 0; desNo < tx_ring->count; desNo++) { | ||
5515 | + tx_desc = IOH_GBE_TX_DESC(*tx_ring, desNo); | ||
5516 | + tx_desc->gbec_status = DSC_INIT16; | ||
5517 | + } | ||
5518 | + | ||
5519 | +#ifdef DEBUG_TEST | ||
5520 | + IOH_GBE_TESTOUT("tx_ring->desc = 0x%08x tx_ring->dma = 0x%08x\n", | ||
5521 | + (u32) tx_ring->desc, tx_ring->dma); | ||
5522 | + IOH_GBE_TESTOUT("next_to_clean = 0x%08x next_to_use = 0x%08x\n", | ||
5523 | + tx_ring->next_to_clean, tx_ring->next_to_use); | ||
5524 | +#endif | ||
5525 | + return IOH_GBE_SUCCESS; | ||
5526 | +} | ||
5527 | + | ||
5528 | +/*! | ||
5529 | + * @ingroup Linux driver internal function | ||
5530 | + * @fn int ioh_gbe_setup_rx_resources(struct ioh_gbe_adapter *adapter, | ||
5531 | + * struct ioh_gbe_rx_ring *rx_ring) | ||
5532 | + * @brief Allocate Rx resources (Descriptors) | ||
5533 | + * @param adapter [INOUT] Board private structure | ||
5534 | + * @param rx_ring [OUT] Rx descriptor ring (for a specific queue) to setup | ||
5535 | + * @return IOH_GBE_SUCCESS: Successfully | ||
5536 | + * @return Negative value: Failed | ||
5537 | + */ | ||
5538 | +int | ||
5539 | +ioh_gbe_setup_rx_resources(struct ioh_gbe_adapter *adapter, | ||
5540 | + struct ioh_gbe_rx_ring *rx_ring) | ||
5541 | +{ | ||
5542 | + struct pci_dev *pdev = adapter->pdev; | ||
5543 | + struct ioh_gbe_rx_desc *rx_desc; | ||
5544 | + int size; | ||
5545 | + int desNo; | ||
5546 | + | ||
5547 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
5548 | + | ||
5549 | + size = (int)sizeof(struct ioh_gbe_buffer) * rx_ring->count; | ||
5550 | + rx_ring->buffer_info = vmalloc(size); | ||
5551 | + if (!rx_ring->buffer_info) { | ||
5552 | + DPRINTK(PROBE, ERR, | ||
5553 | + "Unable to allocate memory " | ||
5554 | + "for the receive descriptor ring\n"); | ||
5555 | + return -ENOMEM; | ||
5556 | + } | ||
5557 | + memset(rx_ring->buffer_info, 0, size); | ||
5558 | + | ||
5559 | + rx_ring->size = rx_ring->count * (int)sizeof(struct ioh_gbe_rx_desc); | ||
5560 | + | ||
5561 | + rx_ring->desc = | ||
5562 | + pci_alloc_consistent(pdev, rx_ring->size, &rx_ring->dma); | ||
5563 | + | ||
5564 | + if (!rx_ring->desc) { | ||
5565 | + DPRINTK(PROBE, ERR, | ||
5566 | + "Unable to allocate memory " | ||
5567 | + "for the receive descriptor ring\n"); | ||
5568 | + vfree(rx_ring->buffer_info); | ||
5569 | + return -ENOMEM; | ||
5570 | + } | ||
5571 | + | ||
5572 | + memset(rx_ring->desc, 0, rx_ring->size); | ||
5573 | + | ||
5574 | + rx_ring->next_to_clean = 0; | ||
5575 | + rx_ring->next_to_use = 0; | ||
5576 | + | ||
5577 | + for (desNo = 0; desNo < rx_ring->count; desNo++) { | ||
5578 | + rx_desc = IOH_GBE_RX_DESC(*rx_ring, desNo); | ||
5579 | + rx_desc->gbec_status = DSC_INIT16; | ||
5580 | + } | ||
5581 | + | ||
5582 | +#ifdef DEBUG_TEST | ||
5583 | + IOH_GBE_TESTOUT("rx_ring->desc = 0x%08x rx_ring->dma = 0x%08x\n", | ||
5584 | + (u32) rx_ring->desc, rx_ring->dma); | ||
5585 | + IOH_GBE_TESTOUT("next_to_clean = 0x%08x next_to_use = 0x%08x\n", | ||
5586 | + rx_ring->next_to_clean, rx_ring->next_to_use); | ||
5587 | +#endif | ||
5588 | + return IOH_GBE_SUCCESS; | ||
5589 | +} | ||
5590 | + | ||
5591 | +/*! | ||
5592 | + * @ingroup Linux driver internal function | ||
5593 | + * @fn void ioh_gbe_free_tx_resources(struct ioh_gbe_adapter *adapter, | ||
5594 | + * struct ioh_gbe_tx_ring *tx_ring) | ||
5595 | + * @brief Free Tx Resources | ||
5596 | + * @param adapter [INOUT] Board private structure | ||
5597 | + * @param tx_ring [OUT] Tx descriptor ring for a specific queue | ||
5598 | + * @return None | ||
5599 | + * @remarks | ||
5600 | + * Free all transmit software resources | ||
5601 | + */ | ||
5602 | +void | ||
5603 | +ioh_gbe_free_tx_resources(struct ioh_gbe_adapter *adapter, | ||
5604 | + struct ioh_gbe_tx_ring *tx_ring) | ||
5605 | +{ | ||
5606 | + struct pci_dev *pdev = adapter->pdev; | ||
5607 | + | ||
5608 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
5609 | + | ||
5610 | + ioh_gbe_clean_tx_ring(adapter, tx_ring); | ||
5611 | + vfree(tx_ring->buffer_info); | ||
5612 | + tx_ring->buffer_info = NULL; | ||
5613 | + pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma); | ||
5614 | + tx_ring->desc = NULL; | ||
5615 | +} | ||
5616 | + | ||
5617 | +/*! | ||
5618 | + * @ingroup Linux driver internal function | ||
5619 | + * @fn void ioh_gbe_free_rx_resources(struct ioh_gbe_adapter *adapter, | ||
5620 | + * struct ioh_gbe_rx_ring *rx_ring) | ||
5621 | + * @brief Free Rx Resources | ||
5622 | + * @param adapter [INOUT] Board private structure | ||
5623 | + * @param rx_ring [OUT] ring to clean the resources from | ||
5624 | + * @return None | ||
5625 | + * @remarks | ||
5626 | + * Free all receive software resources | ||
5627 | + */ | ||
5628 | +void | ||
5629 | +ioh_gbe_free_rx_resources(struct ioh_gbe_adapter *adapter, | ||
5630 | + struct ioh_gbe_rx_ring *rx_ring) | ||
5631 | +{ | ||
5632 | + struct pci_dev *pdev = adapter->pdev; | ||
5633 | + | ||
5634 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
5635 | + | ||
5636 | + ioh_gbe_clean_rx_ring(adapter, rx_ring); | ||
5637 | + vfree(rx_ring->buffer_info); | ||
5638 | + rx_ring->buffer_info = NULL; | ||
5639 | + pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma); | ||
5640 | + rx_ring->desc = NULL; | ||
5641 | +} | ||
5642 | + | ||
5643 | +/*! | ||
5644 | + * @ingroup Linux driver internal function | ||
5645 | + * @fn static void ioh_gbe_setup_tctl(struct ioh_gbe_adapter *adapter) | ||
5646 | + * @brief configure the Transmit control registers | ||
5647 | + * @param adapter [INOUT] Board private structure | ||
5648 | + * @return None | ||
5649 | + */ | ||
5650 | +static void ioh_gbe_setup_tctl(struct ioh_gbe_adapter *adapter) | ||
5651 | +{ | ||
5652 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
5653 | + u32 tx_mode, tcpip; | ||
5654 | + | ||
5655 | + DPRINTK(IFUP, DEBUG, "\n"); | ||
5656 | + | ||
5657 | + tx_mode = IOH_GBE_TM_LONG_PKT | | ||
5658 | + IOH_GBE_TM_ST_AND_FD | | ||
5659 | + IOH_GBE_TM_SHORT_PKT | | ||
5660 | + IOH_GBE_TM_TH_TX_STRT_8 | | ||
5661 | + IOH_GBE_TM_TH_ALM_EMP_4 | IOH_GBE_TM_TH_ALM_FULL_8; | ||
5662 | + | ||
5663 | + IOH_GBE_WRITE_REG(hw, TX_MODE, tx_mode); | ||
5664 | + | ||
5665 | + tcpip = IOH_GBE_READ_REG(hw, TCPIP_ACC); | ||
5666 | + tcpip |= IOH_GBE_TX_TCPIPACC_EN; | ||
5667 | + IOH_GBE_WRITE_REG(hw, TCPIP_ACC, tcpip); | ||
5668 | + | ||
5669 | +#ifdef DEBUG_TEST | ||
5670 | + IOH_GBE_TESTOUT("TX_MODE reg = 0x%08x TCPIP_ACC reg = 0x%08x\n", | ||
5671 | + IOH_GBE_READ_REG(hw, TX_MODE), | ||
5672 | + IOH_GBE_READ_REG(hw, TCPIP_ACC)); | ||
5673 | +#endif | ||
5674 | + return; | ||
5675 | +} | ||
5676 | + | ||
5677 | +/*! | ||
5678 | + * @ingroup Linux driver internal function | ||
5679 | + * @fn static void ioh_gbe_configure_tx(struct ioh_gbe_adapter *adapter) | ||
5680 | + * @brief Configure Transmit Unit after Reset | ||
5681 | + * @param adapter [INOUT] Board private structure | ||
5682 | + * @return None | ||
5683 | + * @remarks | ||
5684 | + * Configure the Tx unit of the MAC after a reset. | ||
5685 | + */ | ||
5686 | +static void ioh_gbe_configure_tx(struct ioh_gbe_adapter *adapter) | ||
5687 | +{ | ||
5688 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
5689 | + u32 tdba, tdlen, dctrl; | ||
5690 | + | ||
5691 | + DPRINTK(IFUP, DEBUG, "\n"); | ||
5692 | + IOH_GBE_TESTOUT("dma adr = 0x%08x size = 0x%08x\n", | ||
5693 | + adapter->tx_ring->dma, adapter->tx_ring->size); | ||
5694 | + | ||
5695 | + /* Setup the HW Tx Head and Tail descriptor pointers */ | ||
5696 | + tdba = adapter->tx_ring->dma; | ||
5697 | + tdlen = adapter->tx_ring->size - 0x10; | ||
5698 | + IOH_GBE_WRITE_REG(hw, TX_DSC_BASE, tdba); | ||
5699 | + IOH_GBE_WRITE_REG(hw, TX_DSC_SIZE, tdlen); | ||
5700 | + IOH_GBE_WRITE_REG(hw, TX_DSC_SW_P, tdba); | ||
5701 | + | ||
5702 | + /* Enables Transmission DMA */ | ||
5703 | + dctrl = IOH_GBE_READ_REG(hw, DMA_CTRL); | ||
5704 | + dctrl |= IOH_GBE_TX_DMA_EN; | ||
5705 | + IOH_GBE_WRITE_REG(hw, DMA_CTRL, dctrl); | ||
5706 | + | ||
5707 | +#ifdef DEBUG_TEST | ||
5708 | + IOH_GBE_TESTOUT | ||
5709 | + ("BASE = 0x%08x HW_P = 0x%08x SIZE = 0x%08x SW_P = 0x%08x\n", | ||
5710 | + IOH_GBE_READ_REG(hw, TX_DSC_BASE), | ||
5711 | + IOH_GBE_READ_REG(hw, TX_DSC_HW_P), | ||
5712 | + IOH_GBE_READ_REG(hw, TX_DSC_SIZE), | ||
5713 | + IOH_GBE_READ_REG(hw, TX_DSC_SW_P)); | ||
5714 | + IOH_GBE_TESTOUT("DMA_CTRL reg[bit0] = 0x%08x\n", | ||
5715 | + IOH_GBE_READ_REG(hw, DMA_CTRL)); | ||
5716 | +#endif | ||
5717 | +} | ||
5718 | + | ||
5719 | +/*! | ||
5720 | + * @ingroup Linux driver internal function | ||
5721 | + * @fn static void ioh_gbe_setup_rctl(struct ioh_gbe_adapter *adapter) | ||
5722 | + * @brief Configure the receive control registers | ||
5723 | + * @param adapter [INOUT] Board private structure | ||
5724 | + * @return None | ||
5725 | + * @remarks | ||
5726 | + * Configure the Tx unit of the MAC after a reset. | ||
5727 | + */ | ||
5728 | +static void ioh_gbe_setup_rctl(struct ioh_gbe_adapter *adapter) | ||
5729 | +{ | ||
5730 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
5731 | + u32 rx_mode, tcpip; | ||
5732 | + | ||
5733 | + DPRINTK(IFUP, DEBUG, "\n"); | ||
5734 | + | ||
5735 | + rx_mode = IOH_GBE_ADD_FIL_EN | IOH_GBE_MLT_FIL_EN | | ||
5736 | + IOH_GBE_RH_ALM_EMP_4 | IOH_GBE_RH_ALM_FULL_4 | IOH_GBE_RH_RD_TRG_8; | ||
5737 | + | ||
5738 | + IOH_GBE_WRITE_REG(hw, RX_MODE, rx_mode); | ||
5739 | + | ||
5740 | + tcpip = IOH_GBE_READ_REG(hw, TCPIP_ACC); | ||
5741 | + | ||
5742 | + if (adapter->rx_csum == TRUE) { | ||
5743 | + tcpip &= ~IOH_GBE_RX_TCPIPACC_OFF; | ||
5744 | + tcpip |= IOH_GBE_RX_TCPIPACC_EN; | ||
5745 | + } else { | ||
5746 | + tcpip |= IOH_GBE_RX_TCPIPACC_OFF; | ||
5747 | + tcpip &= ~IOH_GBE_RX_TCPIPACC_EN; | ||
5748 | + } | ||
5749 | + IOH_GBE_WRITE_REG(hw, TCPIP_ACC, tcpip); | ||
5750 | + | ||
5751 | +#ifdef DEBUG_TEST | ||
5752 | + IOH_GBE_TESTOUT("RX_MODE reg = 0x%08x TCPIP_ACC reg = 0x%08x\n", | ||
5753 | + IOH_GBE_READ_REG(hw, RX_MODE), | ||
5754 | + IOH_GBE_READ_REG(hw, TCPIP_ACC)); | ||
5755 | +#endif | ||
5756 | + return; | ||
5757 | +} | ||
5758 | + | ||
5759 | +/*! | ||
5760 | + * @ingroup Linux driver internal function | ||
5761 | + * @fn static void ioh_gbe_configure_rx(struct ioh_gbe_adapter *adapter) | ||
5762 | + * @brief Configure Receive Unit after Reset | ||
5763 | + * @param adapter [INOUT] Board private structure | ||
5764 | + * @return None | ||
5765 | + * @remarks | ||
5766 | + * Configure the Rx unit of the MAC after a reset. | ||
5767 | + */ | ||
5768 | +static void ioh_gbe_configure_rx(struct ioh_gbe_adapter *adapter) | ||
5769 | +{ | ||
5770 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
5771 | + u32 rdba, rdlen, rctl, rxdma; | ||
5772 | + | ||
5773 | + DPRINTK(IFUP, DEBUG, "\n"); | ||
5774 | + IOH_GBE_TESTOUT("dma adr = 0x%08x size = 0x%08x\n", | ||
5775 | + adapter->rx_ring->dma, adapter->rx_ring->size); | ||
5776 | + | ||
5777 | + ioh_gbe_hal_force_mac_fc(hw); | ||
5778 | + | ||
5779 | + /* Disables Receive MAC */ | ||
5780 | + rctl = IOH_GBE_READ_REG(hw, MAC_RX_EN); | ||
5781 | + IOH_GBE_WRITE_REG(hw, MAC_RX_EN, (rctl & ~IOH_GBE_MRE_MAC_RX_EN)); | ||
5782 | + | ||
5783 | + /* Disables Receive DMA */ | ||
5784 | + rxdma = IOH_GBE_READ_REG(hw, DMA_CTRL); | ||
5785 | + rxdma &= ~IOH_GBE_RX_DMA_EN; | ||
5786 | + IOH_GBE_WRITE_REG(hw, DMA_CTRL, rxdma); | ||
5787 | + | ||
5788 | + IOH_GBE_TESTOUT("MAC_RX_EN reg = 0x%08x DMA_CTRL reg = 0x%08x\n", | ||
5789 | + IOH_GBE_READ_REG(hw, MAC_RX_EN), | ||
5790 | + IOH_GBE_READ_REG(hw, DMA_CTRL)); | ||
5791 | + | ||
5792 | + /* Setup the HW Rx Head and Tail Descriptor Pointers and | ||
5793 | + * the Base and Length of the Rx Descriptor Ring */ | ||
5794 | + rdba = adapter->rx_ring->dma; | ||
5795 | + rdlen = adapter->rx_ring->size - 0x10; | ||
5796 | + IOH_GBE_WRITE_REG(hw, RX_DSC_BASE, rdba); | ||
5797 | + IOH_GBE_WRITE_REG(hw, RX_DSC_SIZE, rdlen); | ||
5798 | + IOH_GBE_WRITE_REG(hw, RX_DSC_SW_P, rdba + rdlen); | ||
5799 | + | ||
5800 | + /* Enables Receive DMA */ | ||
5801 | + rxdma = IOH_GBE_READ_REG(hw, DMA_CTRL); | ||
5802 | + rxdma |= IOH_GBE_RX_DMA_EN; | ||
5803 | + IOH_GBE_WRITE_REG(hw, DMA_CTRL, rxdma); | ||
5804 | + /* Enables Receive */ | ||
5805 | + IOH_GBE_WRITE_REG(hw, MAC_RX_EN, IOH_GBE_MRE_MAC_RX_EN); | ||
5806 | + | ||
5807 | +#ifdef DEBUG_TEST | ||
5808 | + IOH_GBE_TESTOUT | ||
5809 | + ("BASE = 0x%08x HW_P = 0x%08x SIZE = 0x%08x SW_P = 0x%08x\n", | ||
5810 | + IOH_GBE_READ_REG(hw, RX_DSC_BASE), | ||
5811 | + IOH_GBE_READ_REG(hw, RX_DSC_HW_P), | ||
5812 | + IOH_GBE_READ_REG(hw, RX_DSC_SIZE), | ||
5813 | + IOH_GBE_READ_REG(hw, RX_DSC_SW_P)); | ||
5814 | + IOH_GBE_TESTOUT("MAC_RX_EN reg = 0x%08x DMA_CTRL reg = 0x%08x\n", | ||
5815 | + IOH_GBE_READ_REG(hw, MAC_RX_EN), | ||
5816 | + IOH_GBE_READ_REG(hw, DMA_CTRL)); | ||
5817 | +#endif | ||
5818 | +} | ||
5819 | + | ||
5820 | +/*! | ||
5821 | + * @ingroup Linux driver internal function | ||
5822 | + * @fn static void ioh_gbe_unmap_and_free_tx_resource( | ||
5823 | + * struct ioh_gbe_adapter *adapter, | ||
5824 | + * struct ioh_gbe_buffer *buffer_info) | ||
5825 | + * @brief Unmap and free tx socket buffer | ||
5826 | + * @param adapter [INOUT] Board private structure | ||
5827 | + * @param buffer_info [OUT] Buffer information structure | ||
5828 | + * @return None | ||
5829 | + */ | ||
5830 | +static void | ||
5831 | +ioh_gbe_unmap_and_free_tx_resource(struct ioh_gbe_adapter *adapter, | ||
5832 | + struct ioh_gbe_buffer *buffer_info) | ||
5833 | +{ | ||
5834 | + IOH_GBE_DBGOUT2("ioh_gbe_unmap_and_free_tx_resource\n"); | ||
5835 | + | ||
5836 | + if (buffer_info->dma != 0) { | ||
5837 | + pci_unmap_page(adapter->pdev, buffer_info->dma, | ||
5838 | + buffer_info->length, PCI_DMA_TODEVICE); | ||
5839 | + buffer_info->dma = 0; | ||
5840 | + } | ||
5841 | + if (buffer_info->skb != 0) { | ||
5842 | + dev_kfree_skb_any(buffer_info->skb); | ||
5843 | + buffer_info->skb = NULL; | ||
5844 | + } | ||
5845 | + if (buffer_info->kernel_skb != 0) { | ||
5846 | + dev_kfree_skb_any(buffer_info->kernel_skb); | ||
5847 | + buffer_info->kernel_skb = NULL; | ||
5848 | + } | ||
5849 | + IOH_GBE_TESTOUT2 | ||
5850 | + ("buffer_info->dma : 0x%08x buffer_info->skb : 0x%08x\n", | ||
5851 | + buffer_info->dma, buffer_info->skb); | ||
5852 | +} | ||
5853 | + | ||
5854 | +/*! | ||
5855 | + * @ingroup Linux driver internal function | ||
5856 | + * @fn static void ioh_gbe_unmap_and_free_rx_resource( | ||
5857 | + * struct ioh_gbe_adapter *adapter, | ||
5858 | + * struct ioh_gbe_buffer *buffer_info) | ||
5859 | + * @brief Unmap and free rx socket buffer | ||
5860 | + * @param adapter [INOUT] Board private structure | ||
5861 | + * @param buffer_info [OUT] Buffer information structure | ||
5862 | + * @return None | ||
5863 | + */ | ||
5864 | +static void | ||
5865 | +ioh_gbe_unmap_and_free_rx_resource(struct ioh_gbe_adapter *adapter, | ||
5866 | + struct ioh_gbe_buffer *buffer_info) | ||
5867 | +{ | ||
5868 | + IOH_GBE_DBGOUT2("ioh_gbe_unmap_and_free_rx_resource\n"); | ||
5869 | + | ||
5870 | + if (buffer_info->dma != 0) { | ||
5871 | + pci_unmap_single(adapter->pdev, buffer_info->dma, | ||
5872 | + buffer_info->length, PCI_DMA_FROMDEVICE); | ||
5873 | + buffer_info->dma = 0; | ||
5874 | + } | ||
5875 | + if (buffer_info->skb != 0) { | ||
5876 | + dev_kfree_skb_any(buffer_info->skb); | ||
5877 | + buffer_info->skb = NULL; | ||
5878 | + } | ||
5879 | + IOH_GBE_TESTOUT2 | ||
5880 | + ("buffer_info->dma : 0x%08x buffer_info->skb : 0x%08x\n", | ||
5881 | + buffer_info->dma, buffer_info->skb); | ||
5882 | +} | ||
5883 | + | ||
5884 | +/*! | ||
5885 | + * @ingroup Linux driver internal function | ||
5886 | + * @fn static void ioh_gbe_clean_tx_ring(struct ioh_gbe_adapter *adapter, | ||
5887 | + * struct ioh_gbe_tx_ring *tx_ring) | ||
5888 | + * @brief Free Tx Buffers | ||
5889 | + * @param adapter [INOUT] Board private structure | ||
5890 | + * @param tx_ring [OUT] Ring to be cleaned | ||
5891 | + * @return None | ||
5892 | + */ | ||
5893 | +static void | ||
5894 | +ioh_gbe_clean_tx_ring(struct ioh_gbe_adapter *adapter, | ||
5895 | + struct ioh_gbe_tx_ring *tx_ring) | ||
5896 | +{ | ||
5897 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
5898 | + struct ioh_gbe_buffer *buffer_info; | ||
5899 | + unsigned long size; | ||
5900 | + unsigned int i; | ||
5901 | + | ||
5902 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
5903 | + | ||
5904 | + /* Free all the Tx ring sk_buffs */ | ||
5905 | + for (i = 0; i < tx_ring->count; i++) { | ||
5906 | + buffer_info = &tx_ring->buffer_info[i]; | ||
5907 | + ioh_gbe_unmap_and_free_tx_resource(adapter, buffer_info); | ||
5908 | + } | ||
5909 | + IOH_GBE_TESTOUT("call ioh_gbe_unmap_and_free_tx_resource() %d count\n", | ||
5910 | + i); | ||
5911 | + | ||
5912 | + size = (unsigned long)sizeof(struct ioh_gbe_buffer) * tx_ring->count; | ||
5913 | + memset(tx_ring->buffer_info, 0, size); | ||
5914 | + | ||
5915 | + /* Zero out the descriptor ring */ | ||
5916 | + memset(tx_ring->desc, 0, tx_ring->size); | ||
5917 | + | ||
5918 | + tx_ring->next_to_use = 0; | ||
5919 | + tx_ring->next_to_clean = 0; | ||
5920 | + | ||
5921 | + IOH_GBE_WRITE_REG(hw, TX_DSC_HW_P, tx_ring->dma); | ||
5922 | + IOH_GBE_WRITE_REG(hw, TX_DSC_SIZE, (tx_ring->size - 0x10)); | ||
5923 | + | ||
5924 | +#ifdef DEBUG_TEST | ||
5925 | + IOH_GBE_TESTOUT("next_to_use : %d next_to_clean : %d\n", | ||
5926 | + tx_ring->next_to_use, tx_ring->next_to_clean); | ||
5927 | + IOH_GBE_TESTOUT("TX_DSC_HW_P reg : 0x%08x TX_DSC_SIZE reg : 0x%08x\n", | ||
5928 | + IOH_GBE_READ_REG(hw, TX_DSC_HW_P), | ||
5929 | + IOH_GBE_READ_REG(hw, TX_DSC_SIZE)); | ||
5930 | +#endif | ||
5931 | +} | ||
5932 | + | ||
5933 | +/*! | ||
5934 | + * @ingroup Linux driver internal function | ||
5935 | + * @fn static void ioh_gbe_clean_rx_ring(struct ioh_gbe_adapter *adapter, | ||
5936 | + * struct ioh_gbe_rx_ring *rx_ring) | ||
5937 | + * @brief Free Rx Buffers | ||
5938 | + * @param adapter [INOUT] Board private structure | ||
5939 | + * @param rx_ring [OUT] Ring to free buffers from | ||
5940 | + * @return None | ||
5941 | + */ | ||
5942 | +static void | ||
5943 | +ioh_gbe_clean_rx_ring(struct ioh_gbe_adapter *adapter, | ||
5944 | + struct ioh_gbe_rx_ring *rx_ring) | ||
5945 | +{ | ||
5946 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
5947 | + struct ioh_gbe_buffer *buffer_info; | ||
5948 | + unsigned long size; | ||
5949 | + unsigned int i; | ||
5950 | + | ||
5951 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
5952 | + | ||
5953 | + /* Free all the Rx ring sk_buffs */ | ||
5954 | + for (i = 0; i < rx_ring->count; i++) { | ||
5955 | + buffer_info = &rx_ring->buffer_info[i]; | ||
5956 | + ioh_gbe_unmap_and_free_rx_resource(adapter, buffer_info); | ||
5957 | + } | ||
5958 | + IOH_GBE_TESTOUT("call ioh_gbe_unmap_and_free_rx_resource() %d count\n", | ||
5959 | + i); | ||
5960 | + | ||
5961 | + size = (unsigned long)sizeof(struct ioh_gbe_buffer) * rx_ring->count; | ||
5962 | + memset(rx_ring->buffer_info, 0, size); | ||
5963 | + | ||
5964 | + /* Zero out the descriptor ring */ | ||
5965 | + memset(rx_ring->desc, 0, rx_ring->size); | ||
5966 | + | ||
5967 | + rx_ring->next_to_clean = 0; | ||
5968 | + rx_ring->next_to_use = 0; | ||
5969 | + | ||
5970 | + IOH_GBE_WRITE_REG(hw, RX_DSC_HW_P, rx_ring->dma); | ||
5971 | + IOH_GBE_WRITE_REG(hw, RX_DSC_SIZE, (rx_ring->size - 0x10)); | ||
5972 | +#ifdef DEBUG_TEST | ||
5973 | + IOH_GBE_TESTOUT("next_to_use : %d next_to_clean : %d\n", | ||
5974 | + rx_ring->next_to_use, rx_ring->next_to_clean); | ||
5975 | + IOH_GBE_TESTOUT("RX_DSC_HW_P reg : 0x%08x RX_DSC_SIZE reg : 0x%08x\n", | ||
5976 | + IOH_GBE_READ_REG(hw, RX_DSC_HW_P), | ||
5977 | + IOH_GBE_READ_REG(hw, RX_DSC_SIZE)); | ||
5978 | +#endif | ||
5979 | +} | ||
5980 | + | ||
5981 | +static void | ||
5982 | +ioh_gbe_set_rgmii_ctrl(struct ioh_gbe_adapter *adapter, u16 speed, u16 duplex) | ||
5983 | +{ | ||
5984 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
5985 | + unsigned long rgmii = 0; | ||
5986 | + | ||
5987 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
5988 | + /* Set the RGMII control. */ | ||
5989 | +#ifdef IOH_GBE_MAC_IFOP_RGMII | ||
5990 | + switch (speed) { | ||
5991 | + case SPEED_10: | ||
5992 | + rgmii = (IOH_GBE_RGMII_RATE_2_5M | | ||
5993 | + IOH_GBE_MAC_RGMII_CTRL_SETTING); | ||
5994 | + break; | ||
5995 | + case SPEED_100: | ||
5996 | + rgmii = (IOH_GBE_RGMII_RATE_25M | | ||
5997 | + IOH_GBE_MAC_RGMII_CTRL_SETTING); | ||
5998 | + break; | ||
5999 | + case SPEED_1000: | ||
6000 | + rgmii = (IOH_GBE_RGMII_RATE_125M | | ||
6001 | + IOH_GBE_MAC_RGMII_CTRL_SETTING); | ||
6002 | + break; | ||
6003 | + } | ||
6004 | + IOH_GBE_WRITE_REG(hw, RGMII_CTRL, rgmii); | ||
6005 | +#else /* GMII */ | ||
6006 | + rgmii = 0; | ||
6007 | + IOH_GBE_WRITE_REG(hw, RGMII_CTRL, rgmii); | ||
6008 | +#endif | ||
6009 | +} | ||
6010 | +static void | ||
6011 | +ioh_gbe_set_mode(struct ioh_gbe_adapter *adapter, u16 speed, u16 duplex) | ||
6012 | +{ | ||
6013 | + struct net_device *netdev = adapter->netdev; | ||
6014 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
6015 | + unsigned long mode = 0; | ||
6016 | + | ||
6017 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
6018 | + /* Set the communication mode */ | ||
6019 | + switch (speed) { | ||
6020 | + case SPEED_10: | ||
6021 | + mode = IOH_GBE_MODE_MII_ETHER; | ||
6022 | + netdev->tx_queue_len = 10; | ||
6023 | + break; | ||
6024 | + case SPEED_100: | ||
6025 | + mode = IOH_GBE_MODE_MII_ETHER; | ||
6026 | + netdev->tx_queue_len = 100; | ||
6027 | + break; | ||
6028 | + case SPEED_1000: | ||
6029 | + mode = IOH_GBE_MODE_GMII_ETHER; | ||
6030 | + break; | ||
6031 | + } | ||
6032 | + if (duplex == DUPLEX_FULL) | ||
6033 | + mode |= IOH_GBE_MODE_FULL_DUPLEX; | ||
6034 | + else | ||
6035 | + mode |= IOH_GBE_MODE_HALF_DUPLEX; | ||
6036 | + IOH_GBE_WRITE_REG(hw, MODE, mode); | ||
6037 | +} | ||
6038 | + | ||
6039 | +/*! | ||
6040 | + * @ingroup Linux driver internal function | ||
6041 | + * @fn static void ioh_gbe_watchdog(unsigned long data) | ||
6042 | + * @brief Watchdog process | ||
6043 | + * @param data [INOUT] Board private structure | ||
6044 | + * @return None | ||
6045 | + */ | ||
6046 | +static void ioh_gbe_watchdog(unsigned long data) | ||
6047 | +{ | ||
6048 | + struct ioh_gbe_adapter *adapter = (struct ioh_gbe_adapter *)data; | ||
6049 | + struct net_device *netdev = adapter->netdev; | ||
6050 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
6051 | + struct ethtool_cmd cmd; | ||
6052 | + | ||
6053 | + DPRINTK(TIMER, DEBUG, "right now = %ld\n", jiffies); | ||
6054 | + | ||
6055 | + ioh_gbe_update_stats(adapter); | ||
6056 | + if ((mii_link_ok(&adapter->mii)) && (!netif_carrier_ok(netdev))) { | ||
6057 | + netdev->tx_queue_len = adapter->tx_queue_len; | ||
6058 | + /* mii library handles link maintenance tasks */ | ||
6059 | + if (mii_ethtool_gset(&adapter->mii, &cmd) != 0) { | ||
6060 | + DPRINTK(PROBE, ERR, "ethtool get setting Error\n"); | ||
6061 | + mod_timer(&adapter->watchdog_timer, | ||
6062 | + round_jiffies(jiffies + | ||
6063 | + IOH_GBE_WATCHDOG_PERIOD)); | ||
6064 | + return; | ||
6065 | + } | ||
6066 | + hw->mac.link_speed = cmd.speed; | ||
6067 | + hw->mac.link_duplex = cmd.duplex; | ||
6068 | + /* Set the RGMII control. */ | ||
6069 | + ioh_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed, | ||
6070 | + hw->mac.link_duplex); | ||
6071 | + /* Set the communication mode */ | ||
6072 | + ioh_gbe_set_mode(adapter, hw->mac.link_speed, | ||
6073 | + hw->mac.link_duplex); | ||
6074 | + DPRINTK(LINK, INFO, "NIC Link is Up %d Mbps %s-Duplex\n", | ||
6075 | + cmd.speed, cmd.duplex == DUPLEX_FULL ? "Full" : "Half"); | ||
6076 | + netif_carrier_on(netdev); | ||
6077 | + netif_wake_queue(netdev); | ||
6078 | + } else if ((!mii_link_ok(&adapter->mii)) && | ||
6079 | + (netif_carrier_ok(netdev))) { | ||
6080 | + DPRINTK(LINK, INFO, "NIC Link is Down\n"); | ||
6081 | + hw->mac.link_speed = SPEED_10; | ||
6082 | + hw->mac.link_duplex = DUPLEX_HALF; | ||
6083 | + netif_carrier_off(netdev); | ||
6084 | + netif_stop_queue(netdev); | ||
6085 | + } | ||
6086 | + mod_timer(&adapter->watchdog_timer, | ||
6087 | + round_jiffies(jiffies + IOH_GBE_WATCHDOG_PERIOD)); | ||
6088 | +#ifdef DEBUG_TEST | ||
6089 | + IOH_GBE_TESTOUT | ||
6090 | + ("RGMII_CTRL reg : 0x%08x RGMII_ST reg : 0x%08x " | ||
6091 | + " MODE reg : 0x%08x\n", | ||
6092 | + IOH_GBE_READ_REG(hw, RGMII_CTRL), | ||
6093 | + IOH_GBE_READ_REG(hw, RGMII_ST), | ||
6094 | + IOH_GBE_READ_REG(hw, MODE)); | ||
6095 | + IOH_GBE_TESTOUT | ||
6096 | + ("link_speed : %d link_duplex : %d tx_queue_len : %d\n", | ||
6097 | + hw->mac.link_speed, hw->mac.link_duplex, | ||
6098 | + (u32) netdev->tx_queue_len); | ||
6099 | +#endif | ||
6100 | +} | ||
6101 | + | ||
6102 | +/*! | ||
6103 | + * @ingroup Linux driver internal function | ||
6104 | + * @fn static void ioh_gbe_tx_queue(struct ioh_gbe_adapter *adapter, | ||
6105 | + * struct ioh_gbe_tx_ring *tx_ring, struct sk_buff *skb) | ||
6106 | + * @brief Carry out queuing of the transmission data | ||
6107 | + * @param adapter [INOUT] Board private structure | ||
6108 | + * @param tx_ring [OUT] Tx descriptor ring structure | ||
6109 | + * @param skb [IN] Sockt buffer structure | ||
6110 | + * @return None | ||
6111 | + */ | ||
6112 | +static void | ||
6113 | +ioh_gbe_tx_queue(struct ioh_gbe_adapter *adapter, | ||
6114 | + struct ioh_gbe_tx_ring *tx_ring, struct sk_buff *skb) | ||
6115 | +{ | ||
6116 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
6117 | + struct ioh_gbe_tx_desc *tx_desc; | ||
6118 | + struct ioh_gbe_buffer *buffer_info; | ||
6119 | + struct sk_buff *tmp_skb; | ||
6120 | + unsigned int frame_ctrl; | ||
6121 | + unsigned int ring_num; | ||
6122 | + unsigned long flags; | ||
6123 | + | ||
6124 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
6125 | + | ||
6126 | + /*-- Set frame control --*/ | ||
6127 | + frame_ctrl = 0; | ||
6128 | + if (unlikely(skb->len < IOH_GBE_SHORT_PKT)) | ||
6129 | + frame_ctrl |= IOH_GBE_TXD_CTRL_APAD; | ||
6130 | + if (unlikely(adapter->tx_csum == FALSE)) | ||
6131 | + frame_ctrl |= IOH_GBE_TXD_CTRL_TCPIP_ACC_OFF; | ||
6132 | + | ||
6133 | + /* Performs checksum processing */ | ||
6134 | + /* | ||
6135 | + * It is because the hardware accelerator does not support a checksum, | ||
6136 | + * when the received data size is less than 64 bytes. | ||
6137 | + */ | ||
6138 | + if ((skb->len < IOH_GBE_SHORT_PKT) && (adapter->tx_csum == TRUE)) { | ||
6139 | + frame_ctrl |= | ||
6140 | + IOH_GBE_TXD_CTRL_APAD | IOH_GBE_TXD_CTRL_TCPIP_ACC_OFF; | ||
6141 | + if (skb->protocol == htons(ETH_P_IP)) { | ||
6142 | + struct iphdr *iph = ip_hdr(skb); | ||
6143 | + unsigned int offset; | ||
6144 | + iph->check = 0; | ||
6145 | + iph->check = ip_fast_csum((u8 *) iph, iph->ihl); | ||
6146 | + offset = skb_transport_offset(skb); | ||
6147 | + if (iph->protocol == IPPROTO_TCP) { | ||
6148 | + skb->csum = 0; | ||
6149 | + tcp_hdr(skb)->check = 0; | ||
6150 | + skb->csum = | ||
6151 | + skb_checksum(skb, offset, | ||
6152 | + skb->len - offset, 0); | ||
6153 | + tcp_hdr(skb)->check = | ||
6154 | + csum_tcpudp_magic(iph->saddr, | ||
6155 | + iph->daddr, | ||
6156 | + skb->len - offset, | ||
6157 | + IPPROTO_TCP, skb->csum); | ||
6158 | + } else if (iph->protocol == IPPROTO_UDP) { | ||
6159 | + skb->csum = 0; | ||
6160 | + udp_hdr(skb)->check = 0; | ||
6161 | + skb->csum = | ||
6162 | + skb_checksum(skb, offset, | ||
6163 | + skb->len - offset, 0); | ||
6164 | + udp_hdr(skb)->check = | ||
6165 | + csum_tcpudp_magic(iph->saddr, | ||
6166 | + iph->daddr, | ||
6167 | + skb->len - offset, | ||
6168 | + IPPROTO_UDP, skb->csum); | ||
6169 | + } | ||
6170 | + } | ||
6171 | + } | ||
6172 | + | ||
6173 | + spin_lock_irqsave(&tx_ring->tx_lock, flags); | ||
6174 | + ring_num = tx_ring->next_to_use; | ||
6175 | + if (unlikely((ring_num + 1) == tx_ring->count)) | ||
6176 | + tx_ring->next_to_use = 0; | ||
6177 | + else | ||
6178 | + tx_ring->next_to_use = ring_num + 1; | ||
6179 | + | ||
6180 | + spin_unlock_irqrestore(&tx_ring->tx_lock, flags); | ||
6181 | + buffer_info = &tx_ring->buffer_info[ring_num]; | ||
6182 | + tmp_skb = buffer_info->skb; | ||
6183 | + | ||
6184 | + /* [Header:14][payload] ---> [Header:14][paddong:2][payload] */ | ||
6185 | + memcpy(tmp_skb->data, skb->data, ETH_HLEN); | ||
6186 | + tmp_skb->data[ETH_HLEN] = 0x00; | ||
6187 | + tmp_skb->data[ETH_HLEN + 1] = 0x00; | ||
6188 | + tmp_skb->len = skb->len; | ||
6189 | + memcpy(&tmp_skb->data[ETH_HLEN + 2], &skb->data[ETH_HLEN], | ||
6190 | + (skb->len - ETH_HLEN)); | ||
6191 | + buffer_info->kernel_skb = skb; | ||
6192 | + skb = tmp_skb; | ||
6193 | + | ||
6194 | + /*-- Set Buffer infomation --*/ | ||
6195 | + buffer_info->length = skb->len; | ||
6196 | + buffer_info->dma = | ||
6197 | + pci_map_single(adapter->pdev, skb->data, buffer_info->length, | ||
6198 | + PCI_DMA_TODEVICE); | ||
6199 | + buffer_info->time_stamp = jiffies; | ||
6200 | + | ||
6201 | + /*-- Set Tx descriptor --*/ | ||
6202 | + tx_desc = IOH_GBE_TX_DESC(*tx_ring, ring_num); | ||
6203 | + tx_desc->buffer_addr = (buffer_info->dma); | ||
6204 | + tx_desc->length = (skb->len); | ||
6205 | + tx_desc->tx_words_eob = ((skb->len + 3)); | ||
6206 | + tx_desc->tx_frame_ctrl = (frame_ctrl); | ||
6207 | + tx_desc->gbec_status = (DSC_INIT16); | ||
6208 | + | ||
6209 | + if (unlikely(++ring_num == tx_ring->count)) | ||
6210 | + ring_num = 0; | ||
6211 | + | ||
6212 | +#ifdef DEBUG_TEST | ||
6213 | + { | ||
6214 | + unsigned char *rd_data; | ||
6215 | + | ||
6216 | + rd_data = (unsigned char *)tx_desc; | ||
6217 | + IOH_GBE_TESTOUT | ||
6218 | + ("buffer_info->dma : 0x%08x skb->len : 0x%08x " | ||
6219 | + "frame_ctrl : 0x%08x\n", | ||
6220 | + buffer_info->dma, skb->len, frame_ctrl); | ||
6221 | + IOH_GBE_TESTOUT | ||
6222 | + ("tx_desc: \n 0x%02x 0x%02x 0x%02x 0x%02x\n 0x%02x " | ||
6223 | + "0x%02x 0x%02x 0x%02x\n 0x%02x 0x%02x 0x%02x 0x%02x\n " | ||
6224 | + "0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
6225 | + rd_data[0], rd_data[1], rd_data[2], rd_data[3], rd_data[4], | ||
6226 | + rd_data[5], rd_data[6], rd_data[7], rd_data[8], rd_data[9], | ||
6227 | + rd_data[10], rd_data[11], rd_data[12], rd_data[13], | ||
6228 | + rd_data[14], rd_data[15]); | ||
6229 | + } | ||
6230 | +#endif | ||
6231 | + | ||
6232 | + /* Update software pointer of TX descriptor */ | ||
6233 | + IOH_GBE_WRITE_REG(hw, TX_DSC_SW_P, | ||
6234 | + tx_ring->dma + | ||
6235 | + (int)sizeof(struct ioh_gbe_tx_desc) * ring_num); | ||
6236 | +} | ||
6237 | + | ||
6238 | +/*! | ||
6239 | + * @ingroup Linux driver internal function | ||
6240 | + * @fn void ioh_gbe_update_stats(struct ioh_gbe_adapter *adapter) | ||
6241 | + * @brief Update the board statistics counters | ||
6242 | + * @param adapter [INOUT] Board private structure | ||
6243 | + * @return None | ||
6244 | + */ | ||
6245 | +void ioh_gbe_update_stats(struct ioh_gbe_adapter *adapter) | ||
6246 | +{ | ||
6247 | + struct pci_dev *pdev = adapter->pdev; | ||
6248 | + struct ioh_gbe_hw_stats *stats = &adapter->stats; | ||
6249 | + struct net_device_stats *net_stats = &adapter->net_stats; | ||
6250 | + unsigned long flags; | ||
6251 | + | ||
6252 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
6253 | + /* | ||
6254 | + * Prevent stats update while adapter is being reset, or if the pci | ||
6255 | + * connection is down. | ||
6256 | + */ | ||
6257 | + if ((pdev->error_state) && (pdev->error_state != pci_channel_io_normal)) | ||
6258 | + return; | ||
6259 | + | ||
6260 | + spin_lock_irqsave(&adapter->stats_lock, flags); | ||
6261 | + | ||
6262 | + /* Update device status "adapter->stats" */ | ||
6263 | + stats->rx_errors = stats->rx_crc_errors + stats->rx_frame_errors; | ||
6264 | + stats->tx_errors = stats->tx_length_errors + | ||
6265 | + stats->tx_aborted_errors + | ||
6266 | + stats->tx_carrier_errors + stats->tx_timeout_count; | ||
6267 | + | ||
6268 | + /* Update network device status "adapter->net_stats" */ | ||
6269 | + net_stats->rx_packets = stats->rx_packets; | ||
6270 | + net_stats->tx_packets = stats->tx_packets; | ||
6271 | + net_stats->rx_bytes = stats->rx_bytes; | ||
6272 | + net_stats->tx_bytes = stats->tx_bytes; | ||
6273 | + net_stats->rx_errors = stats->rx_errors; | ||
6274 | + net_stats->tx_errors = stats->tx_errors; | ||
6275 | + net_stats->rx_dropped = stats->rx_dropped; | ||
6276 | + net_stats->tx_dropped = stats->tx_dropped; | ||
6277 | + net_stats->multicast = stats->multicast; | ||
6278 | + net_stats->collisions = stats->collisions; | ||
6279 | + net_stats->rx_crc_errors = stats->rx_crc_errors; | ||
6280 | + net_stats->rx_frame_errors = stats->rx_frame_errors; | ||
6281 | + net_stats->tx_aborted_errors = stats->tx_aborted_errors; | ||
6282 | + net_stats->tx_carrier_errors = stats->tx_carrier_errors; | ||
6283 | + | ||
6284 | + spin_unlock_irqrestore(&adapter->stats_lock, flags); | ||
6285 | +} | ||
6286 | + | ||
6287 | +/*! | ||
6288 | + * @ingroup Linux driver internal function | ||
6289 | + * @fn static irqreturn_t ioh_gbe_intr(int irq, void *data) | ||
6290 | + * @brief Interrupt Handler | ||
6291 | + * @param irq [IN] Interrupt number | ||
6292 | + * @param data [INOUT] Pointer to a network interface device structure | ||
6293 | + * @return None | ||
6294 | + */ | ||
6295 | +static irqreturn_t ioh_gbe_intr(int irq, void *data) | ||
6296 | +{ | ||
6297 | + struct net_device *netdev = data; | ||
6298 | + struct ioh_gbe_adapter *adapter = netdev_priv(netdev); | ||
6299 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
6300 | + u32 int_st; | ||
6301 | + u32 int_en; | ||
6302 | + | ||
6303 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
6304 | + | ||
6305 | + /* Check request status */ | ||
6306 | + int_st = IOH_GBE_READ_REG(hw, INT_ST); | ||
6307 | + IOH_GBE_TESTOUT("int_st = 0x%08x\n", int_st); | ||
6308 | + | ||
6309 | + int_st = int_st & IOH_GBE_READ_REG(hw, INT_EN); | ||
6310 | + /* When request status is no interruption factor */ | ||
6311 | + if (unlikely(!int_st)) { | ||
6312 | + /* End processing. */ | ||
6313 | + IOH_GBE_TESTOUT("return = 0x%08x\n", IRQ_NONE); | ||
6314 | + return IRQ_NONE; /* Not our interrupt */ | ||
6315 | + } | ||
6316 | + if (int_st & IOH_GBE_INT_RX_FRAME_ERR) | ||
6317 | + adapter->stats.intr_rx_frame_err_count++; | ||
6318 | + if (int_st & IOH_GBE_INT_RX_FIFO_ERR) | ||
6319 | + adapter->stats.intr_rx_fifo_err_count++; | ||
6320 | + if (int_st & IOH_GBE_INT_RX_DMA_ERR) | ||
6321 | + adapter->stats.intr_rx_dma_err_count++; | ||
6322 | + if (int_st & IOH_GBE_INT_TX_FIFO_ERR) | ||
6323 | + adapter->stats.intr_tx_fifo_err_count++; | ||
6324 | + if (int_st & IOH_GBE_INT_TX_DMA_ERR) | ||
6325 | + adapter->stats.intr_tx_dma_err_count++; | ||
6326 | + if (int_st & IOH_GBE_INT_TCPIP_ERR) | ||
6327 | + adapter->stats.intr_tcpip_err_count++; | ||
6328 | + /* When Rx descriptor is empty */ | ||
6329 | + if ((int_st & IOH_GBE_INT_RX_DSC_EMP) != 0) { | ||
6330 | + adapter->stats.intr_rx_dsc_empty_count++; | ||
6331 | + DPRINTK(PROBE, ERR, "Rx descriptor is empty\n"); | ||
6332 | + int_en = IOH_GBE_READ_REG(hw, INT_EN); | ||
6333 | + IOH_GBE_WRITE_REG(hw, INT_EN, | ||
6334 | + (int_en & ~IOH_GBE_INT_RX_DSC_EMP)); | ||
6335 | + if (hw->mac.tx_fc_enable == TRUE) { | ||
6336 | + /* Set Pause packet */ | ||
6337 | + ioh_gbe_hal_set_pause_packet(hw); | ||
6338 | + } | ||
6339 | + if ((int_en & (IOH_GBE_INT_RX_DMA_CMPLT | IOH_GBE_INT_TX_CMPLT)) | ||
6340 | + == 0) { | ||
6341 | + return IRQ_HANDLED; | ||
6342 | + } | ||
6343 | + } | ||
6344 | + | ||
6345 | + /* When request status is Receive interruption */ | ||
6346 | + if ((int_st & (IOH_GBE_INT_RX_DMA_CMPLT | IOH_GBE_INT_TX_CMPLT)) != 0) { | ||
6347 | + if (likely(napi_schedule_prep(&adapter->napi))) { | ||
6348 | + /* Enable only Rx Descriptor empty */ | ||
6349 | + atomic_inc(&adapter->irq_sem); | ||
6350 | + int_en = IOH_GBE_READ_REG(hw, INT_EN); | ||
6351 | + int_en &= | ||
6352 | + ~(IOH_GBE_INT_RX_DMA_CMPLT | IOH_GBE_INT_TX_CMPLT); | ||
6353 | + IOH_GBE_WRITE_REG(hw, INT_EN, int_en); | ||
6354 | + /* Start polling for NAPI */ | ||
6355 | + __napi_schedule(&adapter->napi); | ||
6356 | + } | ||
6357 | + } | ||
6358 | + IOH_GBE_TESTOUT("return = 0x%08x INT_EN reg = 0x%08x\n", | ||
6359 | + IRQ_HANDLED, IOH_GBE_READ_REG(hw, INT_EN)); | ||
6360 | + return IRQ_HANDLED; | ||
6361 | +} | ||
6362 | + | ||
6363 | +/*! | ||
6364 | + * @ingroup Linux driver internal function | ||
6365 | + * @fn static unsigned char ioh_gbe_clean_tx(struct ioh_gbe_adapter *adapter, | ||
6366 | + * struct ioh_gbe_tx_ring *tx_ring) | ||
6367 | + * @brief Reclaim resources after transmit completes | ||
6368 | + * @param adapter [INOUT] Board private structure | ||
6369 | + * @param tx_ring [OUT] Tx descriptor ring | ||
6370 | + * @return TRUE: Cleaned the descriptor | ||
6371 | + * @return FALSE: Not cleaned the descriptor | ||
6372 | + */ | ||
6373 | +static unsigned char | ||
6374 | +ioh_gbe_clean_tx(struct ioh_gbe_adapter *adapter, | ||
6375 | + struct ioh_gbe_tx_ring *tx_ring) | ||
6376 | +{ | ||
6377 | + struct ioh_gbe_tx_desc *tx_desc; | ||
6378 | + struct ioh_gbe_buffer *buffer_info; | ||
6379 | + struct sk_buff *skb; | ||
6380 | + unsigned int i; | ||
6381 | + unsigned int cleaned_count = 0; | ||
6382 | + unsigned char cleaned = FALSE; | ||
6383 | + | ||
6384 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
6385 | + IOH_GBE_TESTOUT("next_to_clean : %d\n", tx_ring->next_to_clean); | ||
6386 | + | ||
6387 | + i = tx_ring->next_to_clean; | ||
6388 | + tx_desc = IOH_GBE_TX_DESC(*tx_ring, i); | ||
6389 | + IOH_GBE_TESTOUT("gbec_status:0x%04x dma_status:0x%04x\n", | ||
6390 | + tx_desc->gbec_status, tx_desc->dma_status); | ||
6391 | + | ||
6392 | + while ((tx_desc->gbec_status & DSC_INIT16) == 0x0000) { | ||
6393 | + IOH_GBE_TESTOUT("gbec_status:0x%04x\n", tx_desc->gbec_status); | ||
6394 | + cleaned = TRUE; | ||
6395 | + buffer_info = &tx_ring->buffer_info[i]; | ||
6396 | + skb = buffer_info->skb; | ||
6397 | + | ||
6398 | + if ((tx_desc->gbec_status & IOH_GBE_TXD_GMAC_STAT_ABT) != 0) { | ||
6399 | + adapter->stats.tx_aborted_errors++; | ||
6400 | + DPRINTK(PROBE, ERR, "Transfer Aboat Error\n"); | ||
6401 | + } else if ((tx_desc->gbec_status & IOH_GBE_TXD_GMAC_STAT_CRSER) | ||
6402 | + != 0) { | ||
6403 | + adapter->stats.tx_carrier_errors++; | ||
6404 | + DPRINTK(PROBE, ERR, "Transfer Carrier Sense Error\n"); | ||
6405 | + } else if ((tx_desc->gbec_status & IOH_GBE_TXD_GMAC_STAT_EXCOL) | ||
6406 | + != 0) { | ||
6407 | + adapter->stats.tx_aborted_errors++; | ||
6408 | + DPRINTK(PROBE, ERR, "Transfer Collision Abort Error\n"); | ||
6409 | + } else if ((tx_desc->gbec_status & | ||
6410 | + (IOH_GBE_TXD_GMAC_STAT_SNGCOL | | ||
6411 | + IOH_GBE_TXD_GMAC_STAT_MLTCOL)) != 0) { | ||
6412 | + adapter->stats.collisions++; | ||
6413 | + adapter->stats.tx_packets++; | ||
6414 | + adapter->stats.tx_bytes += skb->len; | ||
6415 | + DPRINTK(PROBE, DEBUG, "Transfer Collision\n"); | ||
6416 | + } else if ((tx_desc->gbec_status & IOH_GBE_TXD_GMAC_STAT_CMPLT) | ||
6417 | + != 0) { | ||
6418 | + adapter->stats.tx_packets++; | ||
6419 | + adapter->stats.tx_bytes += skb->len; | ||
6420 | + } | ||
6421 | + if (buffer_info->dma != 0) { | ||
6422 | + IOH_GBE_TESTOUT("unmap buffer_info->dma : %d\n", i); | ||
6423 | + pci_unmap_page(adapter->pdev, buffer_info->dma, | ||
6424 | + buffer_info->length, PCI_DMA_TODEVICE); | ||
6425 | + buffer_info->dma = 0; | ||
6426 | + } | ||
6427 | + if (buffer_info->skb != 0) { | ||
6428 | + IOH_GBE_TESTOUT("trim buffer_info->skb : %d\n", i); | ||
6429 | + skb_trim(buffer_info->skb, 0); | ||
6430 | + } | ||
6431 | + if (buffer_info->kernel_skb != 0) { | ||
6432 | + IOH_GBE_TESTOUT | ||
6433 | + ("free buffer_info->kernel_skb adr: 0x%x\n", | ||
6434 | + (u32)(buffer_info->kernel_skb)); | ||
6435 | + dev_kfree_skb(buffer_info->kernel_skb); | ||
6436 | + buffer_info->kernel_skb = NULL; | ||
6437 | + } | ||
6438 | + tx_desc->gbec_status = DSC_INIT16; | ||
6439 | + if (unlikely(++i == tx_ring->count)) | ||
6440 | + i = 0; | ||
6441 | + tx_desc = IOH_GBE_TX_DESC(*tx_ring, i); | ||
6442 | + | ||
6443 | + /* weight of a sort for tx, to avoid endless transmit cleanup */ | ||
6444 | + if (cleaned_count++ == IOH_GBE_TX_WEIGHT) | ||
6445 | + break; | ||
6446 | + } | ||
6447 | + IOH_GBE_TESTOUT("called ioh_gbe_unmap_and_free_tx_resource() %dcount\n", | ||
6448 | + cleaned_count); | ||
6449 | + /* Recover from running out of Tx resources in xmit_frame */ | ||
6450 | + if (unlikely(cleaned && (netif_queue_stopped(adapter->netdev)))) { | ||
6451 | + netif_wake_queue(adapter->netdev); | ||
6452 | + adapter->stats.tx_restart_count++; | ||
6453 | + DPRINTK(HW, DEBUG, "Tx wake queue\n"); | ||
6454 | + } | ||
6455 | + spin_lock(&adapter->tx_queue_lock); | ||
6456 | + tx_ring->next_to_clean = i; | ||
6457 | + spin_unlock(&adapter->tx_queue_lock); | ||
6458 | + IOH_GBE_TESTOUT("next_to_clean : %d\n", tx_ring->next_to_clean); | ||
6459 | + return cleaned; | ||
6460 | +} | ||
6461 | + | ||
6462 | +/*! | ||
6463 | + * @ingroup Linux driver internal function | ||
6464 | + * @fn static unsigned char ioh_gbe_clean_rx(struct ioh_gbe_adapter *adapter, | ||
6465 | + * struct ioh_gbe_rx_ring *rx_ring, | ||
6466 | + * int *work_done, int work_to_do) | ||
6467 | + * @brief Send received data up the network stack; legacy | ||
6468 | + * @param adapter [INOUT] Board private structure | ||
6469 | + * @param rx_ring [OUT] Rx descriptor ring | ||
6470 | + * @param work_done [OUT] Completed count | ||
6471 | + * @param work_to_do [IN] Request count | ||
6472 | + * @return TRUE: Cleaned the descriptor | ||
6473 | + * @return FALSE: Not cleaned the descriptor | ||
6474 | + */ | ||
6475 | +static unsigned char | ||
6476 | +ioh_gbe_clean_rx(struct ioh_gbe_adapter *adapter, | ||
6477 | + struct ioh_gbe_rx_ring *rx_ring, | ||
6478 | + int *work_done, int work_to_do) | ||
6479 | +{ | ||
6480 | + struct net_device *netdev = adapter->netdev; | ||
6481 | + struct pci_dev *pdev = adapter->pdev; | ||
6482 | + struct ioh_gbe_buffer *buffer_info; | ||
6483 | + struct ioh_gbe_rx_desc *rx_desc; | ||
6484 | + u32 length; | ||
6485 | + unsigned char tmp_packet[ETH_HLEN]; | ||
6486 | + unsigned int i; | ||
6487 | + unsigned int cleaned_count = 0; | ||
6488 | + unsigned char cleaned = FALSE; | ||
6489 | + struct sk_buff *skb; | ||
6490 | + u8 dma_status; | ||
6491 | + u16 gbec_status; | ||
6492 | + u32 tcp_ip_status; | ||
6493 | + u8 skb_copy_flag = 0; | ||
6494 | + u8 skb_padding_flag = 0; | ||
6495 | + | ||
6496 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
6497 | + | ||
6498 | + i = rx_ring->next_to_clean; | ||
6499 | + | ||
6500 | + while (*work_done < work_to_do) { | ||
6501 | + /* Check Rx descriptor status */ | ||
6502 | + rx_desc = IOH_GBE_RX_DESC(*rx_ring, i); | ||
6503 | + if (rx_desc->gbec_status == DSC_INIT16) | ||
6504 | + break; | ||
6505 | + cleaned = TRUE; | ||
6506 | + cleaned_count++; | ||
6507 | + | ||
6508 | + dma_status = rx_desc->dma_status; | ||
6509 | + gbec_status = rx_desc->gbec_status; | ||
6510 | + tcp_ip_status = rx_desc->tcp_ip_status; | ||
6511 | + rx_desc->gbec_status = DSC_INIT16; | ||
6512 | + buffer_info = &rx_ring->buffer_info[i]; | ||
6513 | + skb = buffer_info->skb; | ||
6514 | + | ||
6515 | + /* unmap dma */ | ||
6516 | + pci_unmap_single(pdev, buffer_info->dma, buffer_info->length, | ||
6517 | + PCI_DMA_FROMDEVICE); | ||
6518 | + buffer_info->dma = 0; | ||
6519 | + /* Prefetch the packet */ | ||
6520 | + prefetch(skb->data); | ||
6521 | + | ||
6522 | + IOH_GBE_TESTOUT | ||
6523 | + ("RxDecNo = 0x%04x Status[DMA:0x%02x GBE:0x%04x " | ||
6524 | + "TCP:0x%08x] BufInf = 0x%08x\n", | ||
6525 | + i, dma_status, gbec_status, tcp_ip_status, | ||
6526 | + (u32) (buffer_info)); | ||
6527 | + /* Error check */ | ||
6528 | + if (unlikely(gbec_status & IOH_GBE_RXD_GMAC_STAT_NOTOCTAL)) { | ||
6529 | + adapter->stats.rx_frame_errors++; | ||
6530 | + DPRINTK(PROBE, ERR, "Receive Not Octal Error\n"); | ||
6531 | + } else if (unlikely(gbec_status & | ||
6532 | + IOH_GBE_RXD_GMAC_STAT_NBLERR)) { | ||
6533 | + adapter->stats.rx_frame_errors++; | ||
6534 | + DPRINTK(PROBE, ERR, "Receive Nibble Error\n"); | ||
6535 | + } else if (unlikely(gbec_status & | ||
6536 | + IOH_GBE_RXD_GMAC_STAT_CRCERR)) { | ||
6537 | + adapter->stats.rx_crc_errors++; | ||
6538 | + DPRINTK(PROBE, ERR, "Receive CRC Error\n"); | ||
6539 | + } else { | ||
6540 | + /* get receive length */ | ||
6541 | + /* length convert[-3], padding[-2] */ | ||
6542 | + length = (rx_desc->rx_words_eob) - 3 - 2; | ||
6543 | + | ||
6544 | + /* Decide the data conversion method */ | ||
6545 | + if (adapter->rx_csum != TRUE) { | ||
6546 | + /* [Header:14][payload] */ | ||
6547 | + skb_padding_flag = 0; | ||
6548 | + skb_copy_flag = 1; | ||
6549 | + } else { | ||
6550 | + /* [Header:14][padding:2][payload] */ | ||
6551 | + skb_padding_flag = 1; | ||
6552 | + if (length < copybreak) | ||
6553 | + skb_copy_flag = 1; | ||
6554 | + else | ||
6555 | + skb_copy_flag = 0; | ||
6556 | + } | ||
6557 | + | ||
6558 | + /* Data conversion */ | ||
6559 | + if (skb_copy_flag != 0) { /* recycle skb */ | ||
6560 | + struct sk_buff *new_skb; | ||
6561 | + new_skb = | ||
6562 | + netdev_alloc_skb(netdev, | ||
6563 | + length + NET_IP_ALIGN); | ||
6564 | + if (new_skb != 0) { | ||
6565 | + if (!skb_padding_flag) { | ||
6566 | + skb_reserve(new_skb, | ||
6567 | + NET_IP_ALIGN); | ||
6568 | + } | ||
6569 | + memcpy(new_skb->data, skb->data, | ||
6570 | + length); | ||
6571 | + /* save the skb | ||
6572 | + * in buffer_info as good */ | ||
6573 | + skb = new_skb; | ||
6574 | + } else if (!skb_padding_flag) { | ||
6575 | + /* dorrop error */ | ||
6576 | + DPRINTK(PROBE, ERR, | ||
6577 | + "New skb allocation Error\n"); | ||
6578 | + goto dorrop; | ||
6579 | + } | ||
6580 | + } else { | ||
6581 | + buffer_info->skb = NULL; | ||
6582 | + } | ||
6583 | + if (skb_padding_flag != 0) { | ||
6584 | + memcpy(&tmp_packet[0], &skb->data[0], ETH_HLEN); | ||
6585 | + memcpy(&skb->data[NET_IP_ALIGN], &tmp_packet[0], | ||
6586 | + ETH_HLEN); | ||
6587 | + skb_reserve(skb, NET_IP_ALIGN); | ||
6588 | + | ||
6589 | + } | ||
6590 | + | ||
6591 | + /* update status of driver */ | ||
6592 | + adapter->stats.rx_bytes += length; | ||
6593 | + adapter->stats.rx_packets++; | ||
6594 | + if ((gbec_status & IOH_GBE_RXD_GMAC_STAT_MARMLT) != 0) | ||
6595 | + adapter->stats.multicast++; | ||
6596 | + /* Write meta date of skb */ | ||
6597 | + skb_put(skb, length); | ||
6598 | + skb->protocol = eth_type_trans(skb, netdev); | ||
6599 | + if ((tcp_ip_status & IOH_GBE_RXD_ACC_STAT_TCPIPOK) == | ||
6600 | + IOH_GBE_RXD_ACC_STAT_TCPIPOK) { | ||
6601 | + skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
6602 | + } else { | ||
6603 | + skb->ip_summed = CHECKSUM_NONE; | ||
6604 | + } | ||
6605 | + | ||
6606 | + if (netif_receive_skb(skb) == NET_RX_DROP) { | ||
6607 | + adapter->stats.rx_dropped++; | ||
6608 | + DPRINTK(PROBE, ERR, | ||
6609 | + "Receive Netif Receive Dropped Error\n"); | ||
6610 | + } | ||
6611 | + (*work_done)++; | ||
6612 | + netdev->last_rx = jiffies; | ||
6613 | + IOH_GBE_TESTOUT | ||
6614 | + ("Receive skb->ip_summed: %d length: %d\n", | ||
6615 | + skb->ip_summed, length); | ||
6616 | + } | ||
6617 | +dorrop: | ||
6618 | + /* return some buffers to hardware, one at a time is too slow */ | ||
6619 | + if (unlikely(cleaned_count >= IOH_GBE_RX_BUFFER_WRITE)) { | ||
6620 | + ioh_gbe_alloc_rx_buffers(adapter, rx_ring, | ||
6621 | + cleaned_count); | ||
6622 | + cleaned_count = 0; | ||
6623 | + } | ||
6624 | + if (++i == rx_ring->count) | ||
6625 | + i = 0; | ||
6626 | + } | ||
6627 | + rx_ring->next_to_clean = i; | ||
6628 | + if (cleaned_count != 0) | ||
6629 | + ioh_gbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count); | ||
6630 | +#ifdef DEBUG_TEST | ||
6631 | + { | ||
6632 | + u32 tmp1, tmp2, tmp3, tmp4; | ||
6633 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
6634 | + | ||
6635 | + IOH_GBE_TESTOUT | ||
6636 | + ("cleaned_count = %d next_to_clean = %d " | ||
6637 | + "next_to_use = %d\n", | ||
6638 | + cleaned_count, rx_ring->next_to_clean, | ||
6639 | + rx_ring->next_to_use); | ||
6640 | + tmp1 = IOH_GBE_READ_REG(hw, RX_DSC_BASE); | ||
6641 | + tmp2 = IOH_GBE_READ_REG(hw, RX_DSC_HW_P); | ||
6642 | + tmp3 = IOH_GBE_READ_REG(hw, RX_DSC_SIZE); | ||
6643 | + tmp4 = IOH_GBE_READ_REG(hw, RX_DSC_SW_P); | ||
6644 | + IOH_GBE_TESTOUT | ||
6645 | + ("BASE = 0x%08x HW_P = 0x%08x " | ||
6646 | + "SIZE = 0x%08x SW_P = 0x%08x\n", | ||
6647 | + tmp1, tmp2, tmp3, tmp4); | ||
6648 | + tmp1 = IOH_GBE_READ_REG(hw, DMA_CTRL); | ||
6649 | + tmp2 = IOH_GBE_READ_REG(hw, MAC_RX_EN); | ||
6650 | + IOH_GBE_TESTOUT("DMA_CTRL = 0x%08x MAC_RX_EN = 0x%08x\n", tmp1, | ||
6651 | + tmp2); | ||
6652 | + tmp1 = IOH_GBE_READ_REG(hw, RX_MODE); | ||
6653 | + tmp2 = IOH_GBE_READ_REG(hw, ADDR_MASK); | ||
6654 | + tmp3 = IOH_GBE_READ_REG(hw, MAC_ADR1A); | ||
6655 | + tmp4 = IOH_GBE_READ_REG(hw, MAC_ADR1B); | ||
6656 | + IOH_GBE_TESTOUT | ||
6657 | + ("RX_MODE = 0x%08x ADDR_MASK = 0x%08x " | ||
6658 | + "MAC_ADR1A = 0x%08x MAC_ADR1B = 0x%08x\n", | ||
6659 | + tmp1, tmp2, tmp3, tmp4); | ||
6660 | + } | ||
6661 | +#endif | ||
6662 | + return cleaned; | ||
6663 | +} | ||
6664 | + | ||
6665 | +/*! | ||
6666 | + * @ingroup Linux driver internal function | ||
6667 | + * @fn static void ioh_gbe_alloc_rx_buffers( | ||
6668 | + * struct ioh_gbe_adapter *adapter, | ||
6669 | + * struct ioh_gbe_rx_ring *rx_ring, int cleaned_count) | ||
6670 | + * @brief Replace used receive buffers; legacy & extended | ||
6671 | + * @param adapter [INOUT] Board private structure | ||
6672 | + * @param rx_ring [OUT] Rx descriptor ring | ||
6673 | + * @param cleaned_count [IN] Cleaned count | ||
6674 | + * @return None | ||
6675 | + */ | ||
6676 | +static void | ||
6677 | +ioh_gbe_alloc_rx_buffers(struct ioh_gbe_adapter *adapter, | ||
6678 | + struct ioh_gbe_rx_ring *rx_ring, int cleaned_count) | ||
6679 | +{ | ||
6680 | + struct net_device *netdev = adapter->netdev; | ||
6681 | + struct pci_dev *pdev = adapter->pdev; | ||
6682 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
6683 | + struct ioh_gbe_rx_desc *rx_desc; | ||
6684 | + struct ioh_gbe_buffer *buffer_info; | ||
6685 | + struct sk_buff *skb; | ||
6686 | + unsigned int i; | ||
6687 | + unsigned int bufsz; | ||
6688 | + | ||
6689 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
6690 | + | ||
6691 | + bufsz = adapter->rx_buffer_len + IOH_GBE_DMA_ALIGN; | ||
6692 | + i = rx_ring->next_to_use; | ||
6693 | + | ||
6694 | + while ((cleaned_count--) != 0) { | ||
6695 | + buffer_info = &rx_ring->buffer_info[i]; | ||
6696 | + skb = buffer_info->skb; | ||
6697 | + if (skb != 0) { | ||
6698 | + skb_trim(skb, 0); | ||
6699 | + } else { | ||
6700 | + skb = netdev_alloc_skb(netdev, bufsz); | ||
6701 | + if (unlikely(!skb)) { | ||
6702 | + /* Better luck next round */ | ||
6703 | + adapter->stats.rx_alloc_buff_failed++; | ||
6704 | + break; | ||
6705 | + } | ||
6706 | + /* 64byte align */ | ||
6707 | + skb_reserve(skb, IOH_GBE_DMA_ALIGN); | ||
6708 | + | ||
6709 | + buffer_info->skb = skb; | ||
6710 | + buffer_info->length = adapter->rx_buffer_len; | ||
6711 | + } | ||
6712 | + | ||
6713 | + buffer_info->dma = pci_map_single(pdev, | ||
6714 | + skb->data, | ||
6715 | + buffer_info->length, | ||
6716 | + PCI_DMA_FROMDEVICE); | ||
6717 | + | ||
6718 | + rx_desc = IOH_GBE_RX_DESC(*rx_ring, i); | ||
6719 | + rx_desc->buffer_addr = (buffer_info->dma); | ||
6720 | + rx_desc->gbec_status = DSC_INIT16; | ||
6721 | + | ||
6722 | + IOH_GBE_DBGOUT1 | ||
6723 | + ("i = %d buffer_info->dma = 0x%x " | ||
6724 | + "buffer_info->length = 0x%x\n", | ||
6725 | + i, buffer_info->dma, buffer_info->length); | ||
6726 | + | ||
6727 | + if (unlikely(++i == rx_ring->count)) | ||
6728 | + i = 0; | ||
6729 | + } | ||
6730 | + if (likely(rx_ring->next_to_use != i)) { | ||
6731 | + rx_ring->next_to_use = i; | ||
6732 | + if (unlikely(i-- == 0)) | ||
6733 | + i = (rx_ring->count - 1); | ||
6734 | + wmb(); | ||
6735 | + IOH_GBE_WRITE_REG(hw, RX_DSC_SW_P, | ||
6736 | + rx_ring->dma + | ||
6737 | + (int)sizeof(struct ioh_gbe_rx_desc) * i); | ||
6738 | + } | ||
6739 | + return; | ||
6740 | +} | ||
6741 | + | ||
6742 | +/*! | ||
6743 | + * @ingroup Linux driver internal function | ||
6744 | + * @fn static void ioh_gbe_alloc_tx_buffers( | ||
6745 | + * struct ioh_gbe_adapter *adapter, | ||
6746 | + * struct ioh_gbe_tx_ring *tx_ring) | ||
6747 | + * @brief Allocate transmit buffers | ||
6748 | + * @param adapter [INOUT] Board private structure | ||
6749 | + * @param tx_ring [OUT] Tx descriptor ring | ||
6750 | + * @return None | ||
6751 | + */ | ||
6752 | +static void | ||
6753 | +ioh_gbe_alloc_tx_buffers(struct ioh_gbe_adapter *adapter, | ||
6754 | + struct ioh_gbe_tx_ring *tx_ring) | ||
6755 | +{ | ||
6756 | + struct ioh_gbe_buffer *buffer_info; | ||
6757 | + struct sk_buff *skb; | ||
6758 | + unsigned int i; | ||
6759 | + unsigned int bufsz; | ||
6760 | + struct ioh_gbe_tx_desc *tx_desc; | ||
6761 | + | ||
6762 | + DPRINTK(PROBE, DEBUG, "\n"); | ||
6763 | + | ||
6764 | + bufsz = | ||
6765 | + adapter->hw.mac.max_frame_size + IOH_GBE_DMA_ALIGN + NET_IP_ALIGN; | ||
6766 | + | ||
6767 | + for (i = 0; i < tx_ring->count; i++) { | ||
6768 | + buffer_info = &tx_ring->buffer_info[i]; | ||
6769 | + skb = netdev_alloc_skb(adapter->netdev, bufsz); | ||
6770 | + skb_reserve(skb, IOH_GBE_DMA_ALIGN); | ||
6771 | + buffer_info->skb = skb; | ||
6772 | + tx_desc = IOH_GBE_TX_DESC(*tx_ring, i); | ||
6773 | + tx_desc->gbec_status = (DSC_INIT16); | ||
6774 | + } | ||
6775 | + | ||
6776 | + return; | ||
6777 | +} | ||
6778 | +/* ioh_gbe_main.c */ | ||
6779 | diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_nvm.c topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_nvm.c | ||
6780 | --- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_nvm.c 1970-01-01 09:00:00.000000000 +0900 | ||
6781 | +++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_nvm.c 2010-03-11 15:12:00.000000000 +0900 | ||
6782 | @@ -0,0 +1,129 @@ | ||
6783 | +/*! | ||
6784 | + * @file ioh_gbe_nvm.c | ||
6785 | + * @brief Linux IOH Gigabit Ethernet Driver HAL internal function (NVM) source file | ||
6786 | + * | ||
6787 | + * @version 0.90 | ||
6788 | + * | ||
6789 | + * @section | ||
6790 | + * This program is free software; you can redistribute it and/or modify | ||
6791 | + * it under the terms of the GNU General Public License as published by | ||
6792 | + * the Free Software Foundation; version 2 of the License. | ||
6793 | + * | ||
6794 | + * This program is distributed in the hope that it will be useful, | ||
6795 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
6796 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
6797 | + * GNU General Public License for more details. | ||
6798 | + * | ||
6799 | + * You should have received a copy of the GNU General Public License | ||
6800 | + * along with this program; if not, write to the Free Software | ||
6801 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
6802 | + */ | ||
6803 | + | ||
6804 | +/* | ||
6805 | + * History: | ||
6806 | + * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD. | ||
6807 | + * All rights reserved. | ||
6808 | + * | ||
6809 | + * created: | ||
6810 | + * OKI SEMICONDUCTOR 09/21/2009 | ||
6811 | + * modified: | ||
6812 | + * | ||
6813 | + */ | ||
6814 | +#include "pch_gbe_osdep.h" | ||
6815 | +#include "pch_gbe_defines.h" | ||
6816 | +#include "pch_gbe_hw.h" | ||
6817 | +#include "pch_gbe_nvm.h" | ||
6818 | + | ||
6819 | +#ifdef CONFIG_PCH_PCIEQOS | ||
6820 | +/*! | ||
6821 | + * @ingroup HAL internal function | ||
6822 | + * @fn s32 ioh_gbe_nvm_read_mem(struct ioh_gbe_hw *hw, | ||
6823 | + * u32 offset, u8 *data) | ||
6824 | + * @brief Read EEPROM | ||
6825 | + * @param hw [INOUT] Pointer to the HW structure | ||
6826 | + * @param offset [IN] Offset of word in the EEPROM to read | ||
6827 | + * @param data [OUT] Word read from the EEPROM | ||
6828 | + * @return IOH_GBE_SUCCESS: Successfully | ||
6829 | + * @return Negative value: Failed | ||
6830 | + */ | ||
6831 | +s32 ioh_gbe_nvm_read_mem(struct ioh_gbe_hw *hw, u32 offset, u8 *data) | ||
6832 | +{ | ||
6833 | + s32 ret; | ||
6834 | + | ||
6835 | + IOH_GBE_DBGFUNC("ioh_gbe_nvm_read_mem"); | ||
6836 | + IOH_GBE_TESTOUT("offset : 0x%04x\n", offset); | ||
6837 | + ret = ioh_pcieqos_read_gbe_mac_addr(offset, data); | ||
6838 | + return ret; | ||
6839 | +} | ||
6840 | + | ||
6841 | +/*! | ||
6842 | + * @ingroup HAL internal function | ||
6843 | + * @fn s32 ioh_gbe_nvm_write_mem(struct ioh_gbe_hw *hw, | ||
6844 | + * u32 offset, u8 *data) | ||
6845 | + * @brief Write EEPROM | ||
6846 | + * @param hw [INOUT] Pointer to the HW structure | ||
6847 | + * @param offset [IN] Offset of word in the EEPROM to read | ||
6848 | + * @param data [IN] 8bit word(s) to be written to the EEPROM | ||
6849 | + * @return IOH_GBE_SUCCESS: Successfully | ||
6850 | + * @return Negative value: Failed | ||
6851 | + */ | ||
6852 | +s32 ioh_gbe_nvm_write_mem(struct ioh_gbe_hw *hw, u32 offset, u8 *data) | ||
6853 | +{ | ||
6854 | + s32 ret; | ||
6855 | + | ||
6856 | + IOH_GBE_DBGFUNC("ioh_gbe_nvm_write_mem"); | ||
6857 | + IOH_GBE_TESTOUT("offset : 0x%04x\n", offset); | ||
6858 | + ret = ioh_pcieqos_write_gbe_mac_addr(offset, *data); | ||
6859 | + return ret; | ||
6860 | +} | ||
6861 | + | ||
6862 | +/*! | ||
6863 | + * @ingroup HAL internal function | ||
6864 | + * @fn s32 ioh_gbe_nvm_read_mac_addr(struct ioh_gbe_hw *hw) | ||
6865 | + * @brief Read device MAC address | ||
6866 | + * @param hw [INOUT] Pointer to the HW structure | ||
6867 | + * @return IOH_GBE_SUCCESS: Successfully | ||
6868 | + * @return Negative value: Failed | ||
6869 | + */ | ||
6870 | +s32 ioh_gbe_nvm_read_mac_addr(struct ioh_gbe_hw *hw) | ||
6871 | +{ | ||
6872 | + s32 ret; | ||
6873 | + u8 i; | ||
6874 | + u8 *data; | ||
6875 | + | ||
6876 | + IOH_GBE_DBGFUNC("ioh_gbe_nvm_read_mac_addr"); | ||
6877 | + | ||
6878 | +#ifdef NVM_MAC_FIX | ||
6879 | + hw->mac.addr[0] = (u8) (0x00); | ||
6880 | + hw->mac.addr[1] = (u8) (0x21); | ||
6881 | + hw->mac.addr[2] = (u8) (0x97); | ||
6882 | + hw->mac.addr[3] = (u8) (0x77); | ||
6883 | + hw->mac.addr[4] = (u8) (0x65); | ||
6884 | + hw->mac.addr[5] = (u8) (0x13); | ||
6885 | +#else | ||
6886 | + data = hw->mac.addr; | ||
6887 | + for (i = 0; i < (hw->nvm.word_size * 2); i++) { | ||
6888 | + ret = ioh_pcieqos_read_gbe_mac_addr((u32) i, (data + i)); | ||
6889 | + if (ret != 0) | ||
6890 | + break; | ||
6891 | + } | ||
6892 | +#endif | ||
6893 | + | ||
6894 | + IOH_GBE_TESTOUT("hw->mac.addr : 0x%02x %02x %02x %02x %02x %02x\n", | ||
6895 | + hw->mac.addr[0], hw->mac.addr[1], hw->mac.addr[2], | ||
6896 | + hw->mac.addr[3], hw->mac.addr[4], hw->mac.addr[5]); | ||
6897 | + return ret; | ||
6898 | +} | ||
6899 | +#endif | ||
6900 | +/*! | ||
6901 | + * @ingroup HAL internal function | ||
6902 | + * @fn s32 ioh_gbe_nvm_validate_checksum(struct ioh_gbe_hw *hw) | ||
6903 | + * @brief Validate EEPROM checksum | ||
6904 | + * @param hw [INOUT] Pointer to the HW structure | ||
6905 | + * @return IOH_GBE_SUCCESS: Successfully | ||
6906 | + */ | ||
6907 | +s32 ioh_gbe_nvm_validate_checksum(struct ioh_gbe_hw *hw) | ||
6908 | +{ | ||
6909 | + IOH_GBE_DBGFUNC("ioh_gbe_nvm_validate_checksum"); | ||
6910 | + return IOH_GBE_SUCCESS; | ||
6911 | +} | ||
6912 | diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_nvm.h topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_nvm.h | ||
6913 | --- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_nvm.h 1970-01-01 09:00:00.000000000 +0900 | ||
6914 | +++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_nvm.h 2010-03-11 15:12:18.000000000 +0900 | ||
6915 | @@ -0,0 +1,85 @@ | ||
6916 | +/*! | ||
6917 | + * @file ioh_gbe_nvm.h | ||
6918 | + * @brief Linux IOH Gigabit Ethernet Driver HAL internal function (NVM) header file | ||
6919 | + * | ||
6920 | + * @version 0.90 | ||
6921 | + * | ||
6922 | + * @section | ||
6923 | + * This program is free software; you can redistribute it and/or modify | ||
6924 | + * it under the terms of the GNU General Public License as published by | ||
6925 | + * the Free Software Foundation; version 2 of the License. | ||
6926 | + * | ||
6927 | + * This program is distributed in the hope that it will be useful, | ||
6928 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
6929 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
6930 | + * GNU General Public License for more details. | ||
6931 | + * | ||
6932 | + * You should have received a copy of the GNU General Public License | ||
6933 | + * along with this program; if not, write to the Free Software | ||
6934 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
6935 | + */ | ||
6936 | + | ||
6937 | +/* | ||
6938 | + * History: | ||
6939 | + * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD. | ||
6940 | + * All rights reserved. | ||
6941 | + * | ||
6942 | + * created: | ||
6943 | + * OKI SEMICONDUCTOR 09/21/2009 | ||
6944 | + * modified: | ||
6945 | + * | ||
6946 | + */ | ||
6947 | +#ifndef _IOH_GBE_NVM_H_ | ||
6948 | +#define _IOH_GBE_NVM_H_ | ||
6949 | + | ||
6950 | +#ifdef CONFIG_PCH_PCIEQOS | ||
6951 | +/*! | ||
6952 | + * @ingroup HAL internal function | ||
6953 | + * @fn s32 ioh_gbe_nvm_read_mem(struct ioh_gbe_hw *hw, | ||
6954 | + * u32 offset, u8 *data) | ||
6955 | + * @brief Read EEPROM | ||
6956 | + */ | ||
6957 | +s32 ioh_gbe_nvm_read_mem(struct ioh_gbe_hw *hw, u32 offset, u8 * data); | ||
6958 | + | ||
6959 | +/*! | ||
6960 | + * @ingroup HAL internal function | ||
6961 | + * @fn s32 ioh_gbe_nvm_write_mem(struct ioh_gbe_hw *hw, | ||
6962 | + * u32 offset, u8 *data) | ||
6963 | + * @brief Write EEPROM | ||
6964 | + */ | ||
6965 | +s32 ioh_gbe_nvm_write_mem(struct ioh_gbe_hw *hw, u32 offset, u8 * data); | ||
6966 | + | ||
6967 | +/*! | ||
6968 | + * @ingroup HAL internal function | ||
6969 | + * @fn s32 ioh_gbe_nvm_read_mac_addr(struct ioh_gbe_hw *hw) | ||
6970 | + * @brief Read device MAC address | ||
6971 | + */ | ||
6972 | +s32 ioh_gbe_nvm_read_mac_addr(struct ioh_gbe_hw *hw); | ||
6973 | + | ||
6974 | +/*! | ||
6975 | + * @ingroup HAL internal function | ||
6976 | + * @fn s32 ioh_gbe_nvm_validate_checksum(struct ioh_gbe_hw *hw) | ||
6977 | + * @brief Validate EEPROM checksum | ||
6978 | + */ | ||
6979 | +s32 ioh_gbe_nvm_validate_checksum(struct ioh_gbe_hw *hw); | ||
6980 | + | ||
6981 | +/*! | ||
6982 | + * @ingroup PCIe QoS Driver function | ||
6983 | + * @fn int ioh_pcieqos_read_gbe_mac_addr (unsigned long offset_address, | ||
6984 | + * unsigned char *data); | ||
6985 | + * @brief Read MAC address from NVM | ||
6986 | + */ | ||
6987 | +int ioh_pcieqos_read_gbe_mac_addr(unsigned long offset_address, | ||
6988 | + unsigned char *data); | ||
6989 | + | ||
6990 | +/*! | ||
6991 | + * @ingroup PCIe QoS Driver function | ||
6992 | + * @fn int ioh_pcieqos_write_gbe_mac_addr(unsigned long offset_address, | ||
6993 | + * unsigned char data); | ||
6994 | + * @brief Write MAC address from NVM | ||
6995 | + */ | ||
6996 | +int ioh_pcieqos_write_gbe_mac_addr(unsigned long offset_address, | ||
6997 | + unsigned char data); | ||
6998 | +#endif /* CONFIG_PCH_PCIEQOS */ | ||
6999 | + | ||
7000 | +#endif /* _IOH_GBE_NVM_H_ */ | ||
7001 | diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_osdep.h topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_osdep.h | ||
7002 | --- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_osdep.h 1970-01-01 09:00:00.000000000 +0900 | ||
7003 | +++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_osdep.h 2010-03-09 09:27:26.000000000 +0900 | ||
7004 | @@ -0,0 +1,74 @@ | ||
7005 | +/*! | ||
7006 | + * @file ioh_gbe_osdep.h | ||
7007 | + * @brief Linux IOH Gigabit Ethernet Driver OS independent header file | ||
7008 | + * | ||
7009 | + * glue for the OS independent part of ioh | ||
7010 | + * includes register access macros | ||
7011 | + * | ||
7012 | + * @version 0.90 | ||
7013 | + * | ||
7014 | + * @section | ||
7015 | + * This program is free software; you can redistribute it and/or modify | ||
7016 | + * it under the terms of the GNU General Public License as published by | ||
7017 | + * the Free Software Foundation; version 2 of the License. | ||
7018 | + * | ||
7019 | + * This program is distributed in the hope that it will be useful, | ||
7020 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
7021 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
7022 | + * GNU General Public License for more details. | ||
7023 | + * | ||
7024 | + * You should have received a copy of the GNU General Public License | ||
7025 | + * along with this program; if not, write to the Free Software | ||
7026 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
7027 | + */ | ||
7028 | + | ||
7029 | +/* | ||
7030 | + * History: | ||
7031 | + * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD. | ||
7032 | + * All rights reserved. | ||
7033 | + * | ||
7034 | + * created: | ||
7035 | + * OKI SEMICONDUCTOR 09/21/2009 | ||
7036 | + * modified: | ||
7037 | + * | ||
7038 | + */ | ||
7039 | +#ifndef _IOH_GBE_OSDEP_H_ | ||
7040 | +#define _IOH_GBE_OSDEP_H_ | ||
7041 | + | ||
7042 | +#include <linux/delay.h> | ||
7043 | +#include <linux/io.h> | ||
7044 | + | ||
7045 | +#define usec_delay(x) udelay(x) | ||
7046 | +#ifndef msec_delay | ||
7047 | +#define msec_delay(x) do {if (in_interrupt()) { \ | ||
7048 | + /* Don't mdelay in interrupt context! */ \ | ||
7049 | + BUG(); \ | ||
7050 | + } else { \ | ||
7051 | + msleep(x); \ | ||
7052 | + } } while (0) | ||
7053 | + | ||
7054 | +/* Some workarounds require millisecond delays and are run during interrupt | ||
7055 | + * context. Most notably, when establishing link, the phy may need tweaking | ||
7056 | + * but cannot process phy register reads/writes faster than millisecond | ||
7057 | + * intervals...and we establish link due to a "link status change" interrupt. | ||
7058 | + */ | ||
7059 | +#define msec_delay_irq(x) mdelay(x) | ||
7060 | +#endif | ||
7061 | + | ||
7062 | +#undef FALSE | ||
7063 | +#define FALSE 0 | ||
7064 | +#undef TRUE | ||
7065 | +#define TRUE 1 | ||
7066 | + | ||
7067 | + | ||
7068 | +#define IOH_GBE_WRITE_REG(a, reg, value) ( \ | ||
7069 | + writel((value), ((a)->hw_addr + IOH_GBE_##reg))) | ||
7070 | + | ||
7071 | +#define IOH_GBE_READ_REG(a, reg) ( \ | ||
7072 | + readl((a)->hw_addr + IOH_GBE_##reg)) | ||
7073 | + | ||
7074 | +#define IOH_GBE_WRITE_REG_ARRAY(a, reg, offset, value) ( \ | ||
7075 | + writel((value), \ | ||
7076 | + ((a)->hw_addr + IOH_GBE_##reg + ((offset) << 2)))) | ||
7077 | + | ||
7078 | +#endif /* _IOH_GBE_OSDEP_H_ */ | ||
7079 | diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_param.c topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_param.c | ||
7080 | --- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_param.c 1970-01-01 09:00:00.000000000 +0900 | ||
7081 | +++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_param.c 2010-03-09 09:39:22.000000000 +0900 | ||
7082 | @@ -0,0 +1,594 @@ | ||
7083 | +/*! | ||
7084 | + * @file ioh_gbe_param.c | ||
7085 | + * @brief Linux IOH Gigabit Ethernet Driver parameter check source file | ||
7086 | + * | ||
7087 | + * @version 0.90 | ||
7088 | + * | ||
7089 | + * @section | ||
7090 | + * This program is free software; you can redistribute it and/or modify | ||
7091 | + * it under the terms of the GNU General Public License as published by | ||
7092 | + * the Free Software Foundation; version 2 of the License. | ||
7093 | + * | ||
7094 | + * This program is distributed in the hope that it will be useful, | ||
7095 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
7096 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
7097 | + * GNU General Public License for more details. | ||
7098 | + * | ||
7099 | + * You should have received a copy of the GNU General Public License | ||
7100 | + * along with this program; if not, write to the Free Software | ||
7101 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
7102 | + */ | ||
7103 | + | ||
7104 | +/* | ||
7105 | + * History: | ||
7106 | + * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD. | ||
7107 | + * All rights reserved. | ||
7108 | + * | ||
7109 | + * created: | ||
7110 | + * OKI SEMICONDUCTOR 09/21/2009 | ||
7111 | + * modified: | ||
7112 | + * | ||
7113 | + */ | ||
7114 | + | ||
7115 | +#include <linux/netdevice.h> | ||
7116 | +#include <linux/ethtool.h> | ||
7117 | +#include <linux/mii.h> | ||
7118 | + | ||
7119 | +#include "pch_gbe_osdep.h" | ||
7120 | +#include "pch_gbe_defines.h" | ||
7121 | +#include "pch_gbe_hw.h" | ||
7122 | +#include "pch_gbe.h" | ||
7123 | + | ||
7124 | +/* This is the only thing that needs to be changed to adjust the | ||
7125 | + * maximum number of ports that the driver can manage. | ||
7126 | + */ | ||
7127 | + | ||
7128 | +#define IOH_GBE_MAX_NIC 1 | ||
7129 | + | ||
7130 | +#define OPTION_UNSET -1 | ||
7131 | +#define OPTION_DISABLED 0 | ||
7132 | +#define OPTION_ENABLED 1 | ||
7133 | + | ||
7134 | +/* All parameters are treated the same, as an integer array of values. | ||
7135 | + * This macro just reduces the need to repeat the same declaration code | ||
7136 | + * over and over (plus this helps to avoid typo bugs). | ||
7137 | + */ | ||
7138 | + | ||
7139 | +#define IOH_GBE_PARAM_INIT { [0 ... IOH_GBE_MAX_NIC] = OPTION_UNSET } | ||
7140 | +#ifdef IOH_GBE_QAC | ||
7141 | +#define IOH_GBE_PARAM(X, desc) | ||
7142 | +#else | ||
7143 | +#define IOH_GBE_PARAM(X, desc) \ | ||
7144 | + static int X[IOH_GBE_MAX_NIC+1] = IOH_GBE_PARAM_INIT; \ | ||
7145 | + static int num_##X; \ | ||
7146 | + module_param_array_named(X, X, int, &num_##X, 0); \ | ||
7147 | + MODULE_PARM_DESC(X, desc); | ||
7148 | +#endif | ||
7149 | + | ||
7150 | +/* | ||
7151 | + * Transmit Descriptor Count | ||
7152 | + * Valid Range: IOH_GBE_MIN_TXD - IOH_GBE_MAX_TXD | ||
7153 | + * Default Value: IOH_GBE_DEFAULT_TXD | ||
7154 | + */ | ||
7155 | +IOH_GBE_PARAM(TxDescriptors, "Number of transmit descriptors"); | ||
7156 | + | ||
7157 | +/* | ||
7158 | + * Receive Descriptor Count | ||
7159 | + * Valid Range: IOH_GBE_MIN_RXD - IOH_GBE_MAX_RXD | ||
7160 | + * Default Value: IOH_GBE_DEFAULT_RXD | ||
7161 | + */ | ||
7162 | +IOH_GBE_PARAM(RxDescriptors, "Number of receive descriptors"); | ||
7163 | + | ||
7164 | +/* User Specified Speed Override | ||
7165 | + * | ||
7166 | + * Valid Range: 0, 10, 100, 1000 | ||
7167 | + * - 0 - auto-negotiate at all supported speeds | ||
7168 | + * - 10 - only link at 10 Mbps | ||
7169 | + * - 100 - only link at 100 Mbps | ||
7170 | + * - 1000 - only link at 1000 Mbps | ||
7171 | + * | ||
7172 | + * Default Value: 0 | ||
7173 | + */ | ||
7174 | +IOH_GBE_PARAM(Speed, "Speed setting"); | ||
7175 | + | ||
7176 | +/* User Specified Duplex Override | ||
7177 | + * | ||
7178 | + * Valid Range: 0-2 | ||
7179 | + * - 0 - auto-negotiate for duplex | ||
7180 | + * - 1 - only link at half duplex | ||
7181 | + * - 2 - only link at full duplex | ||
7182 | + * | ||
7183 | + * Default Value: 0 | ||
7184 | + */ | ||
7185 | +IOH_GBE_PARAM(Duplex, "Duplex setting"); | ||
7186 | + | ||
7187 | +/* | ||
7188 | + * Auto-negotiation Advertisement Override | ||
7189 | + * Valid Range: 0x01-0x0F, 0x20-0x2F | ||
7190 | + * | ||
7191 | + * The AutoNeg value is a bit mask describing which speed and duplex | ||
7192 | + * combinations should be advertised during auto-negotiation. | ||
7193 | + * The supported speed and duplex modes are listed below | ||
7194 | + * | ||
7195 | + * Bit 7 6 5 4 3 2 1 0 | ||
7196 | + * Speed (Mbps) N/A N/A 1000 N/A 100 100 10 10 | ||
7197 | + * Duplex Full Full Half Full Half | ||
7198 | + * | ||
7199 | + * Default Value: 0x2F (copper) | ||
7200 | + */ | ||
7201 | +IOH_GBE_PARAM(AutoNeg, "Advertised auto-negotiation setting"); | ||
7202 | +#define AUTONEG_ADV_DEFAULT 0x2F | ||
7203 | + | ||
7204 | +/* | ||
7205 | + * User Specified Flow Control Override | ||
7206 | + * Valid Range: 0-3 | ||
7207 | + * - 0 - No Flow Control | ||
7208 | + * - 1 - Rx only, respond to PAUSE frames but do not generate them | ||
7209 | + * - 2 - Tx only, generate PAUSE frames but ignore them on receive | ||
7210 | + * - 3 - Full Flow Control Support | ||
7211 | + * Default Value: Read flow control settings from the EEPROM | ||
7212 | + */ | ||
7213 | +IOH_GBE_PARAM(FlowControl, "Flow Control setting"); | ||
7214 | + | ||
7215 | +/* | ||
7216 | + * XsumRX - Receive Checksum Offload Enable/Disable | ||
7217 | + * Valid Range: 0, 1 | ||
7218 | + * - 0 - disables all checksum offload | ||
7219 | + * - 1 - enables receive IP/TCP/UDP checksum offload | ||
7220 | + * Default Value: IOH_GBE_DEFAULT_RX_CSUM | ||
7221 | + */ | ||
7222 | +IOH_GBE_PARAM(XsumRX, "Disable or enable Receive Checksum offload"); | ||
7223 | + | ||
7224 | +/* | ||
7225 | + * XsumTX - Transmit Checksum Offload Enable/Disable | ||
7226 | + * Valid Range: 0, 1 | ||
7227 | + * - 0 - disables all checksum offload | ||
7228 | + * - 1 - enables transmit IP/TCP/UDP checksum offload | ||
7229 | + * Default Value: IOH_GBE_DEFAULT_TX_CSUM | ||
7230 | + */ | ||
7231 | +IOH_GBE_PARAM(XsumTX, "Disable or enable Transmit Checksum offload"); | ||
7232 | + | ||
7233 | +struct ioh_gbe_option { | ||
7234 | + enum { enable_option, range_option, list_option } type; | ||
7235 | + signed char *name; | ||
7236 | + signed char *err; | ||
7237 | + int def; | ||
7238 | + union { | ||
7239 | + struct { /* range_option info */ | ||
7240 | + int min; | ||
7241 | + int max; | ||
7242 | + } r; | ||
7243 | + struct { /* list_option info */ | ||
7244 | + int nr; | ||
7245 | + struct ioh_gbe_opt_list { int i; signed char *str; } *p; | ||
7246 | + } l; | ||
7247 | + } arg; | ||
7248 | +}; | ||
7249 | + | ||
7250 | +/* ---------------------------------------------------------------------------- | ||
7251 | + Function prototype | ||
7252 | +---------------------------------------------------------------------------- */ | ||
7253 | +static void ioh_gbe_check_copper_options(struct ioh_gbe_adapter *adapter); | ||
7254 | +static int ioh_gbe_validate_option(int *value, | ||
7255 | + struct ioh_gbe_option *opt, | ||
7256 | + struct ioh_gbe_adapter *adapter); | ||
7257 | + | ||
7258 | +/* ---------------------------------------------------------------------------- | ||
7259 | + Function | ||
7260 | +---------------------------------------------------------------------------- */ | ||
7261 | + | ||
7262 | +/*! | ||
7263 | + * @ingroup Linux driver internal function | ||
7264 | + * @fn static int ioh_gbe_validate_option(int *value, | ||
7265 | + * struct ioh_gbe_option *opt, | ||
7266 | + * struct ioh_gbe_adapter *adapter) | ||
7267 | + * @brief Validate option | ||
7268 | + * @param value [IN] value | ||
7269 | + * @param opt [IN] option | ||
7270 | + * @param adapter [IN] Board private structure | ||
7271 | + * @return IOH_GBE_SUCCESS: Successfully | ||
7272 | + * @return Negative value: Failed | ||
7273 | + */ | ||
7274 | +static int | ||
7275 | +ioh_gbe_validate_option(int *value, struct ioh_gbe_option *opt, | ||
7276 | + struct ioh_gbe_adapter *adapter) | ||
7277 | +{ | ||
7278 | + if (*value == OPTION_UNSET) { | ||
7279 | + *value = opt->def; | ||
7280 | + return 0; | ||
7281 | + } | ||
7282 | + | ||
7283 | + switch (opt->type) { | ||
7284 | + case enable_option: | ||
7285 | + switch (*value) { | ||
7286 | + case OPTION_ENABLED: | ||
7287 | + DPRINTK(PROBE, INFO, "%s Enabled\n", opt->name); | ||
7288 | + return 0; | ||
7289 | + case OPTION_DISABLED: | ||
7290 | + DPRINTK(PROBE, INFO, "%s Disabled\n", opt->name); | ||
7291 | + return 0; | ||
7292 | + } | ||
7293 | + break; | ||
7294 | + case range_option: | ||
7295 | + if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) { | ||
7296 | + DPRINTK(PROBE, INFO, | ||
7297 | + "%s set to %i\n", opt->name, *value); | ||
7298 | + return 0; | ||
7299 | + } | ||
7300 | + break; | ||
7301 | + case list_option: { | ||
7302 | + int i; | ||
7303 | + struct ioh_gbe_opt_list *ent; | ||
7304 | + | ||
7305 | + for (i = 0; i < opt->arg.l.nr; i++) { | ||
7306 | + ent = &opt->arg.l.p[i]; | ||
7307 | + if (*value == ent->i) { | ||
7308 | + if (ent->str[0] != '\0') | ||
7309 | + DPRINTK(PROBE, INFO, "%s\n", ent->str); | ||
7310 | + return 0; | ||
7311 | + } | ||
7312 | + } | ||
7313 | + } | ||
7314 | + break; | ||
7315 | + default: | ||
7316 | + BUG(); | ||
7317 | + } | ||
7318 | + | ||
7319 | + DPRINTK(PROBE, INFO, "Invalid %s value specified (%i) %s\n", | ||
7320 | + opt->name, *value, opt->err); | ||
7321 | + *value = opt->def; | ||
7322 | + return -1; | ||
7323 | +} | ||
7324 | + | ||
7325 | +/*! | ||
7326 | + * @ingroup Linux driver internal function | ||
7327 | + * @fn void ioh_gbe_check_options(struct ioh_gbe_adapter *adapter) | ||
7328 | + * @brief Range Checking for Command Line Parameters | ||
7329 | + * @param adapter [IN] Board private structure | ||
7330 | + * @return None | ||
7331 | + * @remarks | ||
7332 | + * This routine checks all command line parameters for valid user | ||
7333 | + * input. If an invalid value is given, or if no user specified | ||
7334 | + * value exists, a default value is used. The final value is stored | ||
7335 | + * in a variable in the adapter structure. | ||
7336 | + */ | ||
7337 | +void | ||
7338 | +ioh_gbe_check_options(struct ioh_gbe_adapter *adapter) | ||
7339 | +{ | ||
7340 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
7341 | + int bd = adapter->bd_number; | ||
7342 | + | ||
7343 | + IOH_GBE_DBGFUNC("ioh_gbe_check_options"); | ||
7344 | + | ||
7345 | + if (bd >= IOH_GBE_MAX_NIC) { | ||
7346 | + DPRINTK(PROBE, NOTICE, | ||
7347 | + "Warning: no configuration for board #%i\n", bd); | ||
7348 | + DPRINTK(PROBE, NOTICE, "Using defaults for all values\n"); | ||
7349 | + } | ||
7350 | + | ||
7351 | + { /* Transmit Descriptor Count */ | ||
7352 | + struct ioh_gbe_option opt = { | ||
7353 | + .type = range_option, | ||
7354 | + .name = "Transmit Descriptors", | ||
7355 | + .err = "using default of " | ||
7356 | + __MODULE_STRING(IOH_GBE_DEFAULT_TXD), | ||
7357 | + .def = IOH_GBE_DEFAULT_TXD, | ||
7358 | + .arg = { .r = { .min = IOH_GBE_MIN_TXD } }, | ||
7359 | + .arg = { .r = { .max = IOH_GBE_MAX_TXD } } | ||
7360 | + }; | ||
7361 | + struct ioh_gbe_tx_ring *tx_ring = adapter->tx_ring; | ||
7362 | + if (num_TxDescriptors > bd) { | ||
7363 | + tx_ring->count = TxDescriptors[bd]; | ||
7364 | + ioh_gbe_validate_option(&tx_ring->count, &opt, adapter); | ||
7365 | + IOH_GBE_ROUNDUP(tx_ring->count, | ||
7366 | + IOH_GBE_TX_DESC_MULTIPLE); | ||
7367 | + } else { | ||
7368 | + tx_ring->count = opt.def; | ||
7369 | + } | ||
7370 | + } | ||
7371 | + { /* Receive Descriptor Count */ | ||
7372 | + struct ioh_gbe_option opt = { | ||
7373 | + .type = range_option, | ||
7374 | + .name = "Receive Descriptors", | ||
7375 | + .err = "using default of " | ||
7376 | + __MODULE_STRING(IOH_GBE_DEFAULT_RXD), | ||
7377 | + .def = IOH_GBE_DEFAULT_RXD, | ||
7378 | + .arg = { .r = { .min = IOH_GBE_MIN_RXD } }, | ||
7379 | + .arg = { .r = { .max = IOH_GBE_MAX_RXD } } | ||
7380 | + }; | ||
7381 | + struct ioh_gbe_rx_ring *rx_ring = adapter->rx_ring; | ||
7382 | + if (num_RxDescriptors > bd) { | ||
7383 | + rx_ring->count = RxDescriptors[bd]; | ||
7384 | + ioh_gbe_validate_option(&rx_ring->count, &opt, adapter); | ||
7385 | + IOH_GBE_ROUNDUP(rx_ring->count, | ||
7386 | + IOH_GBE_RX_DESC_MULTIPLE); | ||
7387 | + } else { | ||
7388 | + rx_ring->count = opt.def; | ||
7389 | + } | ||
7390 | + } | ||
7391 | + { /* Checksum Offload Enable/Disable */ | ||
7392 | + struct ioh_gbe_option opt = { | ||
7393 | + .type = enable_option, | ||
7394 | + .name = "Checksum Offload", | ||
7395 | + .err = "defaulting to Enabled", | ||
7396 | + .def = IOH_GBE_DEFAULT_RX_CSUM | ||
7397 | + }; | ||
7398 | + | ||
7399 | + if (num_XsumRX > bd) { | ||
7400 | + adapter->rx_csum = XsumRX[bd]; | ||
7401 | + ioh_gbe_validate_option((int *)(&adapter->rx_csum), | ||
7402 | + &opt, adapter); | ||
7403 | + } else { | ||
7404 | + adapter->rx_csum = opt.def; | ||
7405 | + } | ||
7406 | + } | ||
7407 | + { /* Checksum Offload Enable/Disable */ | ||
7408 | + struct ioh_gbe_option opt = { | ||
7409 | + .type = enable_option, | ||
7410 | + .name = "Checksum Offload", | ||
7411 | + .err = "defaulting to Enabled", | ||
7412 | + .def = IOH_GBE_DEFAULT_TX_CSUM | ||
7413 | + }; | ||
7414 | + | ||
7415 | + if (num_XsumTX > bd) { | ||
7416 | + adapter->tx_csum = XsumTX[bd]; | ||
7417 | + ioh_gbe_validate_option((int *)(&adapter->tx_csum), | ||
7418 | + &opt, adapter); | ||
7419 | + } else { | ||
7420 | + adapter->tx_csum = opt.def; | ||
7421 | + } | ||
7422 | + } | ||
7423 | + { /* Flow Control */ | ||
7424 | + | ||
7425 | + struct ioh_gbe_opt_list fc_list[] = { | ||
7426 | + {ioh_gbe_fc_none, "Flow Control Disabled"}, | ||
7427 | + {ioh_gbe_fc_rx_pause, "Flow Control Receive Only"}, | ||
7428 | + {ioh_gbe_fc_tx_pause, "Flow Control Transmit Only"}, | ||
7429 | + {ioh_gbe_fc_full, "Flow Control Enabled"} }; | ||
7430 | + | ||
7431 | + struct ioh_gbe_option opt = { | ||
7432 | + .type = list_option, | ||
7433 | + .name = "Flow Control", | ||
7434 | + .err = "reading default settings from EEPROM", | ||
7435 | + .def = IOH_GBE_FC_DEFAULT, | ||
7436 | + .arg = { .l = { .nr = (int)ARRAY_SIZE(fc_list), | ||
7437 | + .p = fc_list } } | ||
7438 | + }; | ||
7439 | + | ||
7440 | + if (num_FlowControl > bd) { | ||
7441 | + hw->mac.fc = FlowControl[bd]; | ||
7442 | + ioh_gbe_validate_option((int *)(&hw->mac.fc), | ||
7443 | + &opt, adapter); | ||
7444 | + } else { | ||
7445 | + hw->mac.fc = opt.def; | ||
7446 | + } | ||
7447 | + } | ||
7448 | + | ||
7449 | + ioh_gbe_check_copper_options(adapter); | ||
7450 | +} | ||
7451 | + | ||
7452 | +/*! | ||
7453 | + * @ingroup Linux driver internal function | ||
7454 | + * @fn static void ioh_gbe_check_copper_options( | ||
7455 | + * struct ioh_gbe_adapter *adapter) | ||
7456 | + * @brief Range Checking for Link Options, Copper Version | ||
7457 | + * @param adapter [IN] Board private structure | ||
7458 | + * @return None | ||
7459 | + * @remarks | ||
7460 | + * Handles speed and duplex options on copper adapters | ||
7461 | + */ | ||
7462 | +static void | ||
7463 | +ioh_gbe_check_copper_options(struct ioh_gbe_adapter *adapter) | ||
7464 | +{ | ||
7465 | + struct ioh_gbe_hw *hw = &adapter->hw; | ||
7466 | + int speed, dplx; | ||
7467 | + int bd = adapter->bd_number; | ||
7468 | + | ||
7469 | + { /* Speed */ | ||
7470 | + struct ioh_gbe_opt_list speed_list[] = { | ||
7471 | + {0, "" }, | ||
7472 | + {SPEED_10, ""}, | ||
7473 | + {SPEED_100, ""}, | ||
7474 | + {SPEED_1000, ""} }; | ||
7475 | + | ||
7476 | + struct ioh_gbe_option opt = { | ||
7477 | + .type = list_option, | ||
7478 | + .name = "Speed", | ||
7479 | + .err = "parameter ignored", | ||
7480 | + .def = 0, | ||
7481 | + .arg = { .l = { .nr = (int)ARRAY_SIZE(speed_list), | ||
7482 | + .p = speed_list } } | ||
7483 | + }; | ||
7484 | + | ||
7485 | + if (num_Speed > bd) { | ||
7486 | + speed = Speed[bd]; | ||
7487 | + ioh_gbe_validate_option(&speed, &opt, adapter); | ||
7488 | + } else { | ||
7489 | + speed = opt.def; | ||
7490 | + } | ||
7491 | + } | ||
7492 | + { /* Duplex */ | ||
7493 | + struct ioh_gbe_opt_list dplx_list[] = { | ||
7494 | + {0, ""}, | ||
7495 | + {PHY_HALF_DUPLEX, ""}, | ||
7496 | + {PHY_FULL_DUPLEX, ""} }; | ||
7497 | + | ||
7498 | + struct ioh_gbe_option opt = { | ||
7499 | + .type = list_option, | ||
7500 | + .name = "Duplex", | ||
7501 | + .err = "parameter ignored", | ||
7502 | + .def = 0, | ||
7503 | + .arg = { .l = { .nr = (int)ARRAY_SIZE(dplx_list), | ||
7504 | + .p = dplx_list } } | ||
7505 | + }; | ||
7506 | + | ||
7507 | + if (num_Duplex > bd) { | ||
7508 | + dplx = Duplex[bd]; | ||
7509 | + ioh_gbe_validate_option(&dplx, &opt, adapter); | ||
7510 | + } else { | ||
7511 | + dplx = opt.def; | ||
7512 | + } | ||
7513 | + } | ||
7514 | + | ||
7515 | + { /* Autoneg */ | ||
7516 | + struct ioh_gbe_opt_list an_list[] = | ||
7517 | + #define AA "AutoNeg advertising " | ||
7518 | + {{ 0x01, AA "10/HD" }, | ||
7519 | + { 0x02, AA "10/FD" }, | ||
7520 | + { 0x03, AA "10/FD, 10/HD" }, | ||
7521 | + { 0x04, AA "100/HD" }, | ||
7522 | + { 0x05, AA "100/HD, 10/HD" }, | ||
7523 | + { 0x06, AA "100/HD, 10/FD" }, | ||
7524 | + { 0x07, AA "100/HD, 10/FD, 10/HD" }, | ||
7525 | + { 0x08, AA "100/FD" }, | ||
7526 | + { 0x09, AA "100/FD, 10/HD" }, | ||
7527 | + { 0x0a, AA "100/FD, 10/FD" }, | ||
7528 | + { 0x0b, AA "100/FD, 10/FD, 10/HD" }, | ||
7529 | + { 0x0c, AA "100/FD, 100/HD" }, | ||
7530 | + { 0x0d, AA "100/FD, 100/HD, 10/HD" }, | ||
7531 | + { 0x0e, AA "100/FD, 100/HD, 10/FD" }, | ||
7532 | + { 0x0f, AA "100/FD, 100/HD, 10/FD, 10/HD" }, | ||
7533 | + { 0x20, AA "1000/FD" }, | ||
7534 | + { 0x21, AA "1000/FD, 10/HD" }, | ||
7535 | + { 0x22, AA "1000/FD, 10/FD" }, | ||
7536 | + { 0x23, AA "1000/FD, 10/FD, 10/HD" }, | ||
7537 | + { 0x24, AA "1000/FD, 100/HD" }, | ||
7538 | + { 0x25, AA "1000/FD, 100/HD, 10/HD" }, | ||
7539 | + { 0x26, AA "1000/FD, 100/HD, 10/FD" }, | ||
7540 | + { 0x27, AA "1000/FD, 100/HD, 10/FD, 10/HD" }, | ||
7541 | + { 0x28, AA "1000/FD, 100/FD" }, | ||
7542 | + { 0x29, AA "1000/FD, 100/FD, 10/HD" }, | ||
7543 | + { 0x2a, AA "1000/FD, 100/FD, 10/FD" }, | ||
7544 | + { 0x2b, AA "1000/FD, 100/FD, 10/FD, 10/HD" }, | ||
7545 | + { 0x2c, AA "1000/FD, 100/FD, 100/HD" }, | ||
7546 | + { 0x2d, AA "1000/FD, 100/FD, 100/HD, 10/HD" }, | ||
7547 | + { 0x2e, AA "1000/FD, 100/FD, 100/HD, 10/FD" }, | ||
7548 | + { 0x2f, AA "1000/FD, 100/FD, 100/HD, 10/FD, 10/HD" } }; | ||
7549 | + | ||
7550 | + struct ioh_gbe_option opt = { | ||
7551 | + .type = list_option, | ||
7552 | + .name = "AutoNeg", | ||
7553 | + .err = "parameter ignored", | ||
7554 | + .def = AUTONEG_ADV_DEFAULT, | ||
7555 | + .arg = { .l = { .nr = (int)ARRAY_SIZE(an_list), | ||
7556 | + .p = an_list} } | ||
7557 | + }; | ||
7558 | + | ||
7559 | + if (num_AutoNeg > bd) { | ||
7560 | + if (speed != 0 || dplx != 0) { | ||
7561 | + DPRINTK(PROBE, INFO, | ||
7562 | + "AutoNeg specified along with Speed or Duplex, " | ||
7563 | + "parameter ignored\n"); | ||
7564 | + hw->phy.autoneg_advertised = opt.def; | ||
7565 | + } else { | ||
7566 | + hw->phy.autoneg_advertised = AutoNeg[bd]; | ||
7567 | + ioh_gbe_validate_option( | ||
7568 | + (int *)(&hw->phy.autoneg_advertised), | ||
7569 | + &opt, adapter); | ||
7570 | + } | ||
7571 | + } else { | ||
7572 | + hw->phy.autoneg_advertised = opt.def; | ||
7573 | + } | ||
7574 | + } | ||
7575 | + | ||
7576 | + switch (speed + dplx) { | ||
7577 | + case 0: | ||
7578 | + hw->mac.autoneg = hw->mac.fc_autoneg = 1; | ||
7579 | + if ((num_Speed > bd) && (speed != 0 || dplx != 0)) | ||
7580 | + DPRINTK(PROBE, INFO, | ||
7581 | + "Speed and duplex autonegotiation enabled\n"); | ||
7582 | + hw->mac.link_speed = SPEED_10; | ||
7583 | + hw->mac.link_duplex = DUPLEX_HALF; | ||
7584 | + break; | ||
7585 | + case PHY_HALF_DUPLEX: | ||
7586 | + DPRINTK(PROBE, INFO, "Half Duplex specified without Speed\n"); | ||
7587 | + DPRINTK(PROBE, INFO, "Using Autonegotiation at " | ||
7588 | + "Half Duplex only\n"); | ||
7589 | + hw->mac.autoneg = hw->mac.fc_autoneg = 1; | ||
7590 | + hw->phy.autoneg_advertised = PHY_ADVERTISE_10_HALF | | ||
7591 | + PHY_ADVERTISE_100_HALF; | ||
7592 | + hw->mac.link_speed = SPEED_10; | ||
7593 | + hw->mac.link_duplex = DUPLEX_HALF; | ||
7594 | + break; | ||
7595 | + case PHY_FULL_DUPLEX: | ||
7596 | + DPRINTK(PROBE, INFO, "Full Duplex specified without Speed\n"); | ||
7597 | + DPRINTK(PROBE, INFO, "Using Autonegotiation at " | ||
7598 | + "Full Duplex only\n"); | ||
7599 | + hw->mac.autoneg = hw->mac.fc_autoneg = 1; | ||
7600 | + hw->phy.autoneg_advertised = PHY_ADVERTISE_10_FULL | | ||
7601 | + PHY_ADVERTISE_100_FULL | | ||
7602 | + PHY_ADVERTISE_1000_FULL; | ||
7603 | + hw->mac.link_speed = SPEED_10; | ||
7604 | + hw->mac.link_duplex = DUPLEX_FULL; | ||
7605 | + break; | ||
7606 | + case PHY_SPEED_10: | ||
7607 | + DPRINTK(PROBE, INFO, "10 Mbps Speed specified " | ||
7608 | + "without Duplex\n"); | ||
7609 | + DPRINTK(PROBE, INFO, "Using Autonegotiation at 10 Mbps only\n"); | ||
7610 | + hw->mac.autoneg = hw->mac.fc_autoneg = 1; | ||
7611 | + hw->phy.autoneg_advertised = PHY_ADVERTISE_10_HALF | | ||
7612 | + PHY_ADVERTISE_10_FULL; | ||
7613 | + hw->mac.link_speed = SPEED_10; | ||
7614 | + hw->mac.link_duplex = DUPLEX_HALF; | ||
7615 | + break; | ||
7616 | + case PHY_SPEED_10 + PHY_HALF_DUPLEX: | ||
7617 | + DPRINTK(PROBE, INFO, "Forcing to 10 Mbps Half Duplex\n"); | ||
7618 | + hw->mac.autoneg = hw->mac.fc_autoneg = 0; | ||
7619 | + hw->phy.autoneg_advertised = 0; | ||
7620 | + hw->mac.link_speed = SPEED_10; | ||
7621 | + hw->mac.link_duplex = DUPLEX_HALF; | ||
7622 | + break; | ||
7623 | + case PHY_SPEED_10 + PHY_FULL_DUPLEX: | ||
7624 | + DPRINTK(PROBE, INFO, "Forcing to 10 Mbps Full Duplex\n"); | ||
7625 | + hw->mac.autoneg = hw->mac.fc_autoneg = 0; | ||
7626 | + hw->phy.autoneg_advertised = 0; | ||
7627 | + hw->mac.link_speed = SPEED_10; | ||
7628 | + hw->mac.link_duplex = DUPLEX_FULL; | ||
7629 | + break; | ||
7630 | + case PHY_SPEED_100: | ||
7631 | + DPRINTK(PROBE, INFO, "100 Mbps Speed specified " | ||
7632 | + "without Duplex\n"); | ||
7633 | + DPRINTK(PROBE, INFO, "Using Autonegotiation at " | ||
7634 | + "100 Mbps only\n"); | ||
7635 | + hw->mac.autoneg = hw->mac.fc_autoneg = 1; | ||
7636 | + hw->phy.autoneg_advertised = PHY_ADVERTISE_100_HALF | | ||
7637 | + PHY_ADVERTISE_100_FULL; | ||
7638 | + hw->mac.link_speed = SPEED_100; | ||
7639 | + hw->mac.link_duplex = DUPLEX_HALF; | ||
7640 | + break; | ||
7641 | + case PHY_SPEED_100 + PHY_HALF_DUPLEX: | ||
7642 | + DPRINTK(PROBE, INFO, "Forcing to 100 Mbps Half Duplex\n"); | ||
7643 | + hw->mac.autoneg = hw->mac.fc_autoneg = 0; | ||
7644 | + hw->phy.autoneg_advertised = 0; | ||
7645 | + hw->mac.link_speed = SPEED_100; | ||
7646 | + hw->mac.link_duplex = DUPLEX_HALF; | ||
7647 | + break; | ||
7648 | + case PHY_SPEED_100 + PHY_FULL_DUPLEX: | ||
7649 | + DPRINTK(PROBE, INFO, "Forcing to 100 Mbps Full Duplex\n"); | ||
7650 | + hw->mac.autoneg = hw->mac.fc_autoneg = 0; | ||
7651 | + hw->phy.autoneg_advertised = 0; | ||
7652 | + hw->mac.link_speed = SPEED_100; | ||
7653 | + hw->mac.link_duplex = DUPLEX_FULL; | ||
7654 | + break; | ||
7655 | + case PHY_SPEED_1000: | ||
7656 | + DPRINTK(PROBE, INFO, "1000 Mbps Speed specified without " | ||
7657 | + "Duplex\n"); | ||
7658 | + goto full_duplex_only; | ||
7659 | + case PHY_SPEED_1000 + PHY_HALF_DUPLEX: | ||
7660 | + DPRINTK(PROBE, INFO, | ||
7661 | + "Half Duplex is not supported at 1000 Mbps\n"); | ||
7662 | + /* fall through */ | ||
7663 | + case PHY_SPEED_1000 + PHY_FULL_DUPLEX: | ||
7664 | +full_duplex_only: | ||
7665 | + DPRINTK(PROBE, INFO, | ||
7666 | + "Using Autonegotiation at 1000 Mbps Full Duplex only\n"); | ||
7667 | + hw->mac.autoneg = hw->mac.fc_autoneg = 1; | ||
7668 | + hw->phy.autoneg_advertised = PHY_ADVERTISE_1000_FULL; | ||
7669 | + hw->mac.link_speed = SPEED_1000; | ||
7670 | + hw->mac.link_duplex = DUPLEX_FULL; | ||
7671 | + break; | ||
7672 | + default: | ||
7673 | + BUG(); | ||
7674 | + } | ||
7675 | +} | ||
7676 | + | ||
7677 | diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_pci_ids.h topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_pci_ids.h | ||
7678 | --- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_pci_ids.h 1970-01-01 09:00:00.000000000 +0900 | ||
7679 | +++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_pci_ids.h 2010-03-09 09:27:26.000000000 +0900 | ||
7680 | @@ -0,0 +1,38 @@ | ||
7681 | +/*! | ||
7682 | + * @file ioh_gbe_pci_ids.h | ||
7683 | + * @brief Linux IOH Gigabit Ethernet Driver PCI ID header file | ||
7684 | + * | ||
7685 | + * @version 0.90 | ||
7686 | + * | ||
7687 | + * @section | ||
7688 | + * This program is free software; you can redistribute it and/or modify | ||
7689 | + * it under the terms of the GNU General Public License as published by | ||
7690 | + * the Free Software Foundation; version 2 of the License. | ||
7691 | + * | ||
7692 | + * This program is distributed in the hope that it will be useful, | ||
7693 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
7694 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
7695 | + * GNU General Public License for more details. | ||
7696 | + * | ||
7697 | + * You should have received a copy of the GNU General Public License | ||
7698 | + * along with this program; if not, write to the Free Software | ||
7699 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
7700 | + */ | ||
7701 | + | ||
7702 | +/* | ||
7703 | + * History: | ||
7704 | + * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD. | ||
7705 | + * All rights reserved. | ||
7706 | + * | ||
7707 | + * created: | ||
7708 | + * OKI SEMICONDUCTOR 09/21/2009 | ||
7709 | + * modified: | ||
7710 | + * | ||
7711 | + */ | ||
7712 | +#ifndef _IOH_GBE_PCI_IDS_H_ | ||
7713 | +#define _IOH_GBE_PCI_IDS_H_ | ||
7714 | + | ||
7715 | +/* Pci vender/device ID */ | ||
7716 | +#define PCI_DEVICE_ID_INTEL_IOH1_GBE (u16)(0x8802) | ||
7717 | + | ||
7718 | +#endif | ||
7719 | diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_phy.c topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_phy.c | ||
7720 | --- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_phy.c 1970-01-01 09:00:00.000000000 +0900 | ||
7721 | +++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_phy.c 2010-03-09 09:27:26.000000000 +0900 | ||
7722 | @@ -0,0 +1,493 @@ | ||
7723 | +/*! | ||
7724 | + * @file ioh_gbe_phy.c | ||
7725 | + * @brief Linux IOH Gigabit Ethernet Driver HAL internal function (PHY) source file | ||
7726 | + * | ||
7727 | + * @version 0.90 | ||
7728 | + * | ||
7729 | + * @section | ||
7730 | + * This program is free software; you can redistribute it and/or modify | ||
7731 | + * it under the terms of the GNU General Public License as published by | ||
7732 | + * the Free Software Foundation; version 2 of the License. | ||
7733 | + * | ||
7734 | + * This program is distributed in the hope that it will be useful, | ||
7735 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
7736 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
7737 | + * GNU General Public License for more details. | ||
7738 | + * | ||
7739 | + * You should have received a copy of the GNU General Public License | ||
7740 | + * along with this program; if not, write to the Free Software | ||
7741 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
7742 | + */ | ||
7743 | + | ||
7744 | +/* | ||
7745 | + * History: | ||
7746 | + * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD. | ||
7747 | + * All rights reserved. | ||
7748 | + * | ||
7749 | + * created: | ||
7750 | + * OKI SEMICONDUCTOR 09/21/2009 | ||
7751 | + * modified: | ||
7752 | + * | ||
7753 | + */ | ||
7754 | +#include <linux/pci.h> | ||
7755 | +#include <linux/netdevice.h> | ||
7756 | +#include <linux/ethtool.h> | ||
7757 | +#include <linux/mii.h> | ||
7758 | + | ||
7759 | +#include "pch_gbe_osdep.h" | ||
7760 | +#include "pch_gbe_defines.h" | ||
7761 | +#include "pch_gbe_hw.h" | ||
7762 | +#include "pch_gbe_phy.h" | ||
7763 | +#include "pch_gbe_api.h" | ||
7764 | +#include "pch_gbe_regs.h" | ||
7765 | +#include "pch_gbe.h" | ||
7766 | + | ||
7767 | + | ||
7768 | +/*! | ||
7769 | + * @ingroup HAL internal function | ||
7770 | + * @def PHY_CONTROL_DEFAULT | ||
7771 | + * @brief Default value of CONTROL register of PHY | ||
7772 | + */ | ||
7773 | +#define PHY_CONTROL_DEFAULT 0x1140 /* Control Register */ | ||
7774 | + | ||
7775 | +/*! | ||
7776 | + * @ingroup HAL internal function | ||
7777 | + * @def PHY_AUTONEG_ADV_DEFAULT | ||
7778 | + * @brief Default value of AUTONEG_ADV register of PHY | ||
7779 | + */ | ||
7780 | +#define PHY_AUTONEG_ADV_DEFAULT 0x01e0 /* Autoneg Advertisement */ | ||
7781 | + | ||
7782 | +/*! | ||
7783 | + * @ingroup HAL internal function | ||
7784 | + * @def PHY_NEXT_PAGE_TX_DEFAULT | ||
7785 | + * @brief Default value of NEXT_PAGE_TX register of PHY | ||
7786 | + */ | ||
7787 | +#define PHY_NEXT_PAGE_TX_DEFAULT 0x2001 /* Next Page TX */ | ||
7788 | + | ||
7789 | +/*! | ||
7790 | + * @ingroup HAL internal function | ||
7791 | + * @def PHY_1000T_CTRL_DEFAULT | ||
7792 | + * @brief Default value of 1000T_CTRL register of PHY | ||
7793 | + */ | ||
7794 | +#define PHY_1000T_CTRL_DEFAULT 0x0300 /* 1000Base-T Control Register */ | ||
7795 | + | ||
7796 | +/*! | ||
7797 | + * @ingroup HAL internal function | ||
7798 | + * @def PHY_PHYSP_CONTROL_DEFAULT | ||
7799 | + * @brief Default value of PHYSP_CONTROL register of PHY | ||
7800 | + */ | ||
7801 | +#ifdef FPGA | ||
7802 | +#define PHY_PHYSP_CONTROL_DEFAULT 0x0078 /* PHY Specific Control Register */ | ||
7803 | +#else | ||
7804 | +#define PHY_PHYSP_CONTROL_DEFAULT 0x01EE /* PHY Specific Control Register */ | ||
7805 | +#endif | ||
7806 | + | ||
7807 | +/*! | ||
7808 | + * @ingroup HAL internal function | ||
7809 | + * @def PHY_EXT_PHYSP_CONTROL_DEFAULT | ||
7810 | + * @brief Default value of EXT_PHYSP_CONTROL register of PHY | ||
7811 | + */ | ||
7812 | +#define PHY_EXT_PHYSP_CONTROL_DEFAULT 0x0c60 | ||
7813 | + | ||
7814 | +/*! | ||
7815 | + * @ingroup HAL internal function | ||
7816 | + * @def PHY_LED_CONTROL_DEFAULT | ||
7817 | + * @brief Default value of LED_CONTROL register of PHY | ||
7818 | + */ | ||
7819 | +#define PHY_LED_CONTROL_DEFAULT 0x4100 | ||
7820 | + | ||
7821 | + | ||
7822 | +/*! | ||
7823 | + * @ingroup HAL internal function | ||
7824 | + * @fn s32 ioh_gbe_phy_get_id(struct ioh_gbe_hw *hw) | ||
7825 | + * @brief Retrieve the PHY ID and revision | ||
7826 | + * @param hw [IN] Pointer to the HW structure | ||
7827 | + * @return IOH_GBE_SUCCESS: Successfully | ||
7828 | + * @return Negative value: Failed | ||
7829 | + * @remarks | ||
7830 | + * Reads the PHY registers and stores the PHY ID and possibly the PHY | ||
7831 | + * revision in the hardware structure. | ||
7832 | + */ | ||
7833 | +s32 | ||
7834 | +ioh_gbe_phy_get_id(struct ioh_gbe_hw *hw) | ||
7835 | +{ | ||
7836 | + struct ioh_gbe_phy_info *phy = &hw->phy; | ||
7837 | + s32 ret; | ||
7838 | + u16 phy_id1; | ||
7839 | + u16 phy_id2; | ||
7840 | + | ||
7841 | + IOH_GBE_DBGFUNC("ioh_gbe_phy_get_id"); | ||
7842 | + | ||
7843 | + ret = ioh_gbe_hal_read_phy_reg(hw, PHY_ID1, &phy_id1); | ||
7844 | + if (ret != 0) | ||
7845 | + return ret; | ||
7846 | + ret = ioh_gbe_hal_read_phy_reg(hw, PHY_ID2, &phy_id2); | ||
7847 | + if (ret != 0) | ||
7848 | + return ret; | ||
7849 | + /* | ||
7850 | + * PHY_ID1: [bit15-0:ID(21-6)] | ||
7851 | + * PHY_ID2: [bit15-10:ID(5-0)][bit9-4:Model][bit3-0:revision] | ||
7852 | + */ | ||
7853 | + phy->id = (u32)phy_id1; | ||
7854 | + phy->id = ((phy->id << 6) | ((phy_id2 & 0xFC00) >> 10)); | ||
7855 | + phy->revision = (u32) (phy_id2 & 0x000F); | ||
7856 | + | ||
7857 | +#ifdef DEBUG_TEST | ||
7858 | + IOH_GBE_TESTOUT("phy->id : 0x%08x phy->revision : 0x%08x\n", | ||
7859 | + phy->id, phy->revision); | ||
7860 | +#endif | ||
7861 | + return IOH_GBE_SUCCESS; | ||
7862 | +} | ||
7863 | + | ||
7864 | +/*! | ||
7865 | + * @ingroup HAL internal function | ||
7866 | + * @fn s32 ioh_gbe_phy_read_reg_miic(struct ioh_gbe_hw *hw, | ||
7867 | + * u32 offset, u16 *data) | ||
7868 | + * @brief Read MII control register | ||
7869 | + * @param hw [IN] Pointer to the HW structure | ||
7870 | + * @param offset [IN] Register offset to be read | ||
7871 | + * @param data [OUT] Pointer to the read data | ||
7872 | + * @return IOH_GBE_SUCCESS: Successfully | ||
7873 | + * @return Negative value: Failed | ||
7874 | + * @remarks | ||
7875 | + * Reads the PHY registers and stores the PHY ID and possibly the PHY | ||
7876 | + * revision in the hardware structure. | ||
7877 | + */ | ||
7878 | +s32 | ||
7879 | +ioh_gbe_phy_read_reg_miic(struct ioh_gbe_hw *hw, u32 offset, u16 *data) | ||
7880 | +{ | ||
7881 | + struct ioh_gbe_phy_info *phy = &hw->phy; | ||
7882 | + s32 ret_val = IOH_GBE_SUCCESS; | ||
7883 | + | ||
7884 | + if (offset > PHY_MAX_REG_ADDRESS) { | ||
7885 | + IOH_GBE_DBGOUT1("PHY Address %d is out of range\n", offset); | ||
7886 | + ret_val = -IOH_GBE_ERR_PARAM; | ||
7887 | + } else { | ||
7888 | + *data = ioh_gbe_hal_ctrl_miim(hw, phy->addr, | ||
7889 | + IOH_GBE_HAL_MIIM_READ, offset, (u16)0); | ||
7890 | + } | ||
7891 | + return ret_val; | ||
7892 | +} | ||
7893 | + | ||
7894 | +/*! | ||
7895 | + * @ingroup HAL internal function | ||
7896 | + * @fn s32 ioh_gbe_phy_write_reg_miic(struct ioh_gbe_hw *hw, | ||
7897 | + * u32 offset, u16 data) | ||
7898 | + * @brief Write MII control register | ||
7899 | + * @param hw [IN] Pointer to the HW structure | ||
7900 | + * @param offset [IN] Register offset to be read | ||
7901 | + * @param data [IN] data to write to register at offset | ||
7902 | + * @return IOH_GBE_SUCCESS: Successfully | ||
7903 | + * @return Negative value: Failed | ||
7904 | + * @remarks | ||
7905 | + * Writes data to MDI control register in the PHY at offset. | ||
7906 | + */ | ||
7907 | +s32 | ||
7908 | +ioh_gbe_phy_write_reg_miic(struct ioh_gbe_hw *hw, u32 offset, u16 data) | ||
7909 | +{ | ||
7910 | + struct ioh_gbe_phy_info *phy = &hw->phy; | ||
7911 | + s32 ret_val = IOH_GBE_SUCCESS; | ||
7912 | + | ||
7913 | + if (offset > PHY_MAX_REG_ADDRESS) { | ||
7914 | + IOH_GBE_DBGOUT1("PHY Address %d is out of range\n", offset); | ||
7915 | + ret_val = -IOH_GBE_ERR_PARAM; | ||
7916 | + } else { | ||
7917 | + ioh_gbe_hal_ctrl_miim(hw, phy->addr, | ||
7918 | + IOH_GBE_HAL_MIIM_WRITE, offset, data); | ||
7919 | + } | ||
7920 | + return ret_val; | ||
7921 | +} | ||
7922 | + | ||
7923 | +/*! | ||
7924 | + * @ingroup HAL internal function | ||
7925 | + * @fn s32 ioh_gbe_phy_setup_link_fpga(struct ioh_gbe_hw *hw) | ||
7926 | + * @brief Configure link settings for FPGA | ||
7927 | + * @param hw [IN] Pointer to the HW structure | ||
7928 | + * @return IOH_GBE_SUCCESS: Successfully | ||
7929 | + * @return Negative value: Failed | ||
7930 | + * @remarks | ||
7931 | + * Calls the appropriate function to configure the link for auto-neg or forced | ||
7932 | + * speed and duplex. Then we check for link, once link is established calls | ||
7933 | + * to configure collision distance and flow control are called. If link is | ||
7934 | + * not established, we return -IOH_GBE_ERR_PHY (-2). | ||
7935 | + */ | ||
7936 | +s32 | ||
7937 | +ioh_gbe_phy_setup_link_fpga(struct ioh_gbe_hw *hw) | ||
7938 | +{ | ||
7939 | + | ||
7940 | + IOH_GBE_DBGFUNC("ioh_gbe_phy_setup_link_fpga"); | ||
7941 | + return IOH_GBE_SUCCESS; | ||
7942 | +} | ||
7943 | + | ||
7944 | +/*! | ||
7945 | + * @ingroup HAL internal function | ||
7946 | + * @fn void ioh_gbe_phy_sw_reset(struct ioh_gbe_hw *hw) | ||
7947 | + * @brief PHY software reset | ||
7948 | + * @param hw [IN] Pointer to the HW structure | ||
7949 | + * @return None | ||
7950 | + * @remarks | ||
7951 | + * Does a software reset of the PHY by reading the PHY control register and | ||
7952 | + * setting/write the control register reset bit to the PHY. | ||
7953 | + */ | ||
7954 | +void | ||
7955 | +ioh_gbe_phy_sw_reset(struct ioh_gbe_hw *hw) | ||
7956 | +{ | ||
7957 | + u16 phy_ctrl; | ||
7958 | + | ||
7959 | + IOH_GBE_DBGFUNC("ioh_gbe_phy_sw_reset"); | ||
7960 | + | ||
7961 | + ioh_gbe_hal_read_phy_reg(hw, PHY_CONTROL, &phy_ctrl); | ||
7962 | + phy_ctrl |= MII_CR_RESET; | ||
7963 | + ioh_gbe_hal_write_phy_reg(hw, PHY_CONTROL, phy_ctrl); | ||
7964 | + usec_delay(1); | ||
7965 | +} | ||
7966 | + | ||
7967 | +/*! | ||
7968 | + * @ingroup HAL internal function | ||
7969 | + * @fn void ioh_gbe_phy_hw_reset(struct ioh_gbe_hw *hw) | ||
7970 | + * @brief PHY hardware reset | ||
7971 | + * @param hw [IN] Pointer to the HW structure | ||
7972 | + * @return None | ||
7973 | + * @remarks | ||
7974 | + * Verify the reset block is not blocking us from resetting. Acquire | ||
7975 | + * semaphore (if necessary) and read/set/write the device control reset | ||
7976 | + * bit in the PHY. Wait the appropriate delay time for the device to | ||
7977 | + * reset and relase the semaphore (if necessary). | ||
7978 | + */ | ||
7979 | +void | ||
7980 | +ioh_gbe_phy_hw_reset(struct ioh_gbe_hw *hw) | ||
7981 | +{ | ||
7982 | +#ifndef PHY_RESET_REG_INIT | ||
7983 | + struct ioh_gbe_phy_info *phy = &hw->phy; | ||
7984 | + | ||
7985 | + IOH_GBE_DBGFUNC("ioh_gbe_phy_hw_reset"); | ||
7986 | + | ||
7987 | + /* ISSUE: reset used GPIO driver */ | ||
7988 | + usec_delay(phy->reset_delay_us); | ||
7989 | + /* ISSUE: release reset used GPIO driver */ | ||
7990 | +#else | ||
7991 | + IOH_GBE_DBGFUNC("ioh_gbe_phy_hw_reset"); | ||
7992 | + | ||
7993 | + ioh_gbe_hal_write_phy_reg(hw, PHY_CONTROL, PHY_CONTROL_DEFAULT); | ||
7994 | + ioh_gbe_hal_write_phy_reg(hw, PHY_AUTONEG_ADV, | ||
7995 | + PHY_AUTONEG_ADV_DEFAULT); | ||
7996 | + ioh_gbe_hal_write_phy_reg(hw, PHY_NEXT_PAGE_TX, | ||
7997 | + PHY_NEXT_PAGE_TX_DEFAULT); | ||
7998 | + ioh_gbe_hal_write_phy_reg(hw, PHY_1000T_CTRL, PHY_1000T_CTRL_DEFAULT); | ||
7999 | + ioh_gbe_hal_write_phy_reg(hw, PHY_PHYSP_CONTROL, | ||
8000 | + PHY_PHYSP_CONTROL_DEFAULT); | ||
8001 | +#ifdef FPGA | ||
8002 | + ioh_gbe_hal_write_phy_reg(hw, PHY_EXT_PHYSP_CONTROL, | ||
8003 | + PHY_EXT_PHYSP_CONTROL_DEFAULT); | ||
8004 | + ioh_gbe_hal_write_phy_reg(hw, PHY_LED_CONTROL, PHY_LED_CONTROL_DEFAULT); | ||
8005 | +#endif | ||
8006 | + | ||
8007 | +#endif | ||
8008 | + | ||
8009 | +} | ||
8010 | + | ||
8011 | +/*! | ||
8012 | + * @ingroup HAL internal function | ||
8013 | + * @fn s32 ioh_gbe_phy_led_on(struct ioh_gbe_hw *hw) | ||
8014 | + * @brief Set ting of led on | ||
8015 | + * @param hw [IN] Pointer to the HW structure | ||
8016 | + * @return IOH_GBE_SUCCESS: Successfully | ||
8017 | + */ | ||
8018 | +s32 | ||
8019 | +ioh_gbe_phy_led_on(struct ioh_gbe_hw *hw) | ||
8020 | +{ | ||
8021 | + IOH_GBE_DBGFUNC("ioh_gbe_phy_led_on"); | ||
8022 | + | ||
8023 | + ioh_gbe_hal_write_phy_reg(hw, PHY_LED_CONTROL, PHY_LED_CTRL_ON); | ||
8024 | + return IOH_GBE_SUCCESS; | ||
8025 | +} | ||
8026 | + | ||
8027 | +/*! | ||
8028 | + * @ingroup HAL internal function | ||
8029 | + * @fn s32 ioh_gbe_phy_led_off(struct ioh_gbe_hw *hw) | ||
8030 | + * @brief Set ting of led off | ||
8031 | + * @param hw [IN] Pointer to the HW structure | ||
8032 | + * @return IOH_GBE_SUCCESS: Successfully | ||
8033 | + */ | ||
8034 | +s32 | ||
8035 | +ioh_gbe_phy_led_off(struct ioh_gbe_hw *hw) | ||
8036 | +{ | ||
8037 | + IOH_GBE_DBGFUNC("ioh_gbe_phy_led_off"); | ||
8038 | + | ||
8039 | + ioh_gbe_hal_write_phy_reg(hw, PHY_LED_CONTROL, PHY_LED_CTRL_OFF); | ||
8040 | + return IOH_GBE_SUCCESS; | ||
8041 | +} | ||
8042 | + | ||
8043 | +/*! | ||
8044 | + * @ingroup HAL internal function | ||
8045 | + * @fn s32 ioh_gbe_phy_led_cleanup(struct ioh_gbe_hw *hw) | ||
8046 | + * @brief Cleanup led control | ||
8047 | + * @param hw [IN] Pointer to the HW structure | ||
8048 | + * @return IOH_GBE_SUCCESS: Successfully | ||
8049 | + */ | ||
8050 | +s32 | ||
8051 | +ioh_gbe_phy_led_cleanup(struct ioh_gbe_hw *hw) | ||
8052 | +{ | ||
8053 | + IOH_GBE_DBGFUNC("ioh_gbe_phy_led_cleanup"); | ||
8054 | + | ||
8055 | + ioh_gbe_hal_write_phy_reg(hw, PHY_LED_CONTROL, PHY_LED_CTRL_CLEANUP); | ||
8056 | + return IOH_GBE_SUCCESS; | ||
8057 | +} | ||
8058 | + | ||
8059 | +/*! | ||
8060 | + * @ingroup HAL internal function | ||
8061 | + * @fn s32 ioh_gbe_phy_led_setup(struct ioh_gbe_hw *hw) | ||
8062 | + * @brief Setup led control | ||
8063 | + * @param hw [IN] Pointer to the HW structure | ||
8064 | + * @return IOH_GBE_SUCCESS: Successfully | ||
8065 | + */ | ||
8066 | +s32 | ||
8067 | +ioh_gbe_phy_led_setup(struct ioh_gbe_hw *hw) | ||
8068 | +{ | ||
8069 | + IOH_GBE_DBGFUNC("ioh_gbe_phy_led_setup"); | ||
8070 | + | ||
8071 | + return IOH_GBE_SUCCESS; | ||
8072 | +} | ||
8073 | + | ||
8074 | +/*! | ||
8075 | + * @ingroup HAL internal function | ||
8076 | + * @fn void ioh_gbe_phy_power_up(struct ioh_gbe_hw *hw) | ||
8077 | + * @brief restore link in case the phy was powered down | ||
8078 | + * @param hw [IN] Pointer to the HW structure | ||
8079 | + * @return None | ||
8080 | + * @remarks | ||
8081 | + * The phy may be powered down to save power and turn off link when the | ||
8082 | + * driver is unloaded and wake on lan is not enabled (among others) | ||
8083 | + * *** this routine MUST be followed by a call to ioh_gbe_reset *** | ||
8084 | + */ | ||
8085 | +void ioh_gbe_phy_power_up(struct ioh_gbe_hw *hw) | ||
8086 | +{ | ||
8087 | + u16 mii_reg; | ||
8088 | + | ||
8089 | + IOH_GBE_DBGFUNC("ioh_gbe_phy_power_up"); | ||
8090 | + | ||
8091 | + mii_reg = 0; | ||
8092 | + /* Just clear the power down bit to wake the phy back up */ | ||
8093 | + /* according to the manual, the phy will retain its | ||
8094 | + * settings across a power-down/up cycle */ | ||
8095 | + ioh_gbe_hal_read_phy_reg(hw, PHY_CONTROL, &mii_reg); | ||
8096 | + mii_reg &= ~MII_CR_POWER_DOWN; | ||
8097 | + ioh_gbe_hal_write_phy_reg(hw, PHY_CONTROL, mii_reg); | ||
8098 | + | ||
8099 | +#ifdef DEBUG_TEST | ||
8100 | + ioh_gbe_hal_read_phy_reg(hw, PHY_CONTROL, &mii_reg); | ||
8101 | + IOH_GBE_TESTOUT("PHY_CONTROL reg : 0x%08x\n", mii_reg); | ||
8102 | +#endif | ||
8103 | + return; | ||
8104 | +} | ||
8105 | + | ||
8106 | +/*! | ||
8107 | + * @ingroup HAL internal function | ||
8108 | + * @fn void ioh_gbe_phy_power_down(struct ioh_gbe_hw *hw) | ||
8109 | + * @brief Power down PHY | ||
8110 | + * @param hw [IN] Pointer to the HW structure | ||
8111 | + * @return None | ||
8112 | + */ | ||
8113 | +void ioh_gbe_phy_power_down(struct ioh_gbe_hw *hw) | ||
8114 | +{ | ||
8115 | + u16 mii_reg; | ||
8116 | + | ||
8117 | + IOH_GBE_DBGFUNC("ioh_gbe_phy_power_down"); | ||
8118 | + | ||
8119 | + mii_reg = 0; | ||
8120 | + /* Power down the PHY so no link is implied when interface is down * | ||
8121 | + * The PHY cannot be powered down if any of the following is TRUE * | ||
8122 | + * (a) WoL is enabled | ||
8123 | + * (b) AMT is active | ||
8124 | + */ | ||
8125 | + ioh_gbe_hal_read_phy_reg(hw, PHY_CONTROL, &mii_reg); | ||
8126 | + mii_reg |= MII_CR_POWER_DOWN; | ||
8127 | + ioh_gbe_hal_write_phy_reg(hw, PHY_CONTROL, mii_reg); | ||
8128 | + mdelay(1); | ||
8129 | + | ||
8130 | +#ifdef DEBUG_TEST | ||
8131 | + ioh_gbe_hal_read_phy_reg(hw, PHY_CONTROL, &mii_reg); | ||
8132 | + IOH_GBE_TESTOUT("PHY_CONTROL reg : 0x%08x\n", mii_reg); | ||
8133 | +#endif | ||
8134 | + return; | ||
8135 | +} | ||
8136 | + | ||
8137 | +/*! | ||
8138 | + * @ingroup HAL internal function | ||
8139 | + * @fn void ioh_gbe_phy_set_rgmii(struct ioh_gbe_hw *hw) | ||
8140 | + * @brief RGMII interface setting | ||
8141 | + * @param hw [IN] Pointer to the HW structure | ||
8142 | + * @return None | ||
8143 | + */ | ||
8144 | +#ifdef FPGA | ||
8145 | +void ioh_gbe_phy_set_rgmii(struct ioh_gbe_hw *hw) | ||
8146 | +{ | ||
8147 | + u16 mii_reg; | ||
8148 | + | ||
8149 | + IOH_GBE_DBGFUNC("ioh_gbe_phy_set_rgmii"); | ||
8150 | + | ||
8151 | + ioh_gbe_hal_read_phy_reg(hw, PHY_EXT_PHYSP_STATUS, &mii_reg); | ||
8152 | + mii_reg &= ~HWCFG_MODE_MASK; | ||
8153 | + mii_reg |= HWCFG_MODE_RGMII_COPPER; | ||
8154 | + ioh_gbe_hal_write_phy_reg(hw, PHY_EXT_PHYSP_STATUS, mii_reg); | ||
8155 | + ioh_gbe_hal_read_phy_reg(hw, PHY_EXT_PHYSP_CONTROL, &mii_reg); | ||
8156 | + mii_reg |= 0x01; /* Transfer enable */ | ||
8157 | + mii_reg |= 0x02; /* add delay to GTX_CLK */ | ||
8158 | + mii_reg |= 0x80; /* add delay to RX_CLK */ | ||
8159 | + ioh_gbe_hal_write_phy_reg(hw, PHY_EXT_PHYSP_CONTROL, mii_reg); | ||
8160 | + ioh_gbe_hal_phy_sw_reset(hw); | ||
8161 | + | ||
8162 | +#ifdef DEBUG_TEST | ||
8163 | + ioh_gbe_hal_read_phy_reg(hw, PHY_EXT_PHYSP_STATUS, &mii_reg); | ||
8164 | + IOH_GBE_TESTOUT("PHY_EXT_PHYSP_STATUS reg : 0x%08x\n", mii_reg); | ||
8165 | + ioh_gbe_hal_read_phy_reg(hw, PHY_EXT_PHYSP_CONTROL, &mii_reg); | ||
8166 | + IOH_GBE_TESTOUT("PHY_EXT_PHYSP_CONTROL reg : 0x%08x\n", mii_reg); | ||
8167 | +#endif | ||
8168 | + return; | ||
8169 | +} | ||
8170 | +#else | ||
8171 | +void ioh_gbe_phy_set_rgmii(struct ioh_gbe_hw *hw) | ||
8172 | +{ | ||
8173 | + IOH_GBE_DBGFUNC("ioh_gbe_phy_set_rgmii"); | ||
8174 | + | ||
8175 | + ioh_gbe_hal_phy_sw_reset(hw); | ||
8176 | + return; | ||
8177 | +} | ||
8178 | +#endif | ||
8179 | +/*! | ||
8180 | + * @ingroup HAL internal function | ||
8181 | + * @fn void ioh_gbe_phy_init_setting(struct ioh_gbe_hw *hw) | ||
8182 | + * @brief PHY initial setting | ||
8183 | + * @param hw [IN] Pointer to the HW structure | ||
8184 | + * @return None | ||
8185 | + */ | ||
8186 | +void ioh_gbe_phy_init_setting(struct ioh_gbe_hw *hw) | ||
8187 | +{ | ||
8188 | + struct ioh_gbe_adapter *adapter; | ||
8189 | + struct ethtool_cmd cmd; | ||
8190 | + int ret; | ||
8191 | + u16 mii_reg; | ||
8192 | + | ||
8193 | + IOH_GBE_DBGFUNC("ioh_gbe_phy_init_setting"); | ||
8194 | + | ||
8195 | + adapter = container_of(hw, struct ioh_gbe_adapter, hw); | ||
8196 | + ret = mii_ethtool_gset(&adapter->mii, &cmd); | ||
8197 | + if (ret != 0) | ||
8198 | + IOH_GBE_ERR("Error: mii_ethtool_gset\n"); | ||
8199 | + | ||
8200 | + cmd.speed = hw->mac.link_speed; | ||
8201 | + cmd.duplex = hw->mac.link_duplex; | ||
8202 | + cmd.advertising = hw->phy.autoneg_advertised; | ||
8203 | + cmd.autoneg = hw->mac.autoneg; | ||
8204 | + ioh_gbe_hal_write_phy_reg(hw, MII_BMCR, BMCR_RESET); | ||
8205 | + ret = mii_ethtool_sset(&adapter->mii, &cmd); | ||
8206 | + if (ret != 0) | ||
8207 | + IOH_GBE_ERR("Error: mii_ethtool_sset\n"); | ||
8208 | + | ||
8209 | + ioh_gbe_hal_phy_sw_reset(hw); | ||
8210 | + | ||
8211 | + ioh_gbe_hal_read_phy_reg(hw, PHY_PHYSP_CONTROL, &mii_reg); | ||
8212 | + mii_reg |= PHYSP_CTRL_ASSERT_CRS_TX; | ||
8213 | + ioh_gbe_hal_write_phy_reg(hw, PHY_PHYSP_CONTROL, mii_reg); | ||
8214 | + | ||
8215 | +} | ||
8216 | diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_phy.h topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_phy.h | ||
8217 | --- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_phy.h 1970-01-01 09:00:00.000000000 +0900 | ||
8218 | +++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_phy.h 2010-03-09 09:27:26.000000000 +0900 | ||
8219 | @@ -0,0 +1,136 @@ | ||
8220 | +/*! | ||
8221 | + * @file ioh_gbe_phy.h | ||
8222 | + * @brief Linux IOH Gigabit Ethernet Driver HAL internal function (PHY) header file | ||
8223 | + * | ||
8224 | + * @version 0.90 | ||
8225 | + * | ||
8226 | + * @section | ||
8227 | + * This program is free software; you can redistribute it and/or modify | ||
8228 | + * it under the terms of the GNU General Public License as published by | ||
8229 | + * the Free Software Foundation; version 2 of the License. | ||
8230 | + * | ||
8231 | + * This program is distributed in the hope that it will be useful, | ||
8232 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8233 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
8234 | + * GNU General Public License for more details. | ||
8235 | + * | ||
8236 | + * You should have received a copy of the GNU General Public License | ||
8237 | + * along with this program; if not, write to the Free Software | ||
8238 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
8239 | + */ | ||
8240 | + | ||
8241 | +/* | ||
8242 | + * History: | ||
8243 | + * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD. | ||
8244 | + * All rights reserved. | ||
8245 | + * | ||
8246 | + * created: | ||
8247 | + * OKI SEMICONDUCTOR 09/21/2009 | ||
8248 | + * modified: | ||
8249 | + * | ||
8250 | + */ | ||
8251 | +#ifndef _IOH_GBE_PHY_H_ | ||
8252 | +#define _IOH_GBE_PHY_H_ | ||
8253 | + | ||
8254 | +/*! | ||
8255 | + * @ingroup HAL internal function | ||
8256 | + * @fn s32 ioh_gbe_phy_get_id(struct ioh_gbe_hw *hw) | ||
8257 | + * @brief Retrieve the PHY ID and revision | ||
8258 | + */ | ||
8259 | +s32 ioh_gbe_phy_get_id(struct ioh_gbe_hw *hw); | ||
8260 | + | ||
8261 | +/*! | ||
8262 | + * @ingroup HAL internal function | ||
8263 | + * @fn s32 ioh_gbe_phy_read_reg_miic(struct ioh_gbe_hw *hw, | ||
8264 | + * u32 offset, u16 *data) | ||
8265 | + * @brief Read MII control register | ||
8266 | + */ | ||
8267 | +s32 ioh_gbe_phy_read_reg_miic(struct ioh_gbe_hw *hw, u32 offset, u16 *data); | ||
8268 | + | ||
8269 | +/*! | ||
8270 | + * @ingroup HAL internal function | ||
8271 | + * @fn s32 ioh_gbe_phy_write_reg_miic(struct ioh_gbe_hw *hw, | ||
8272 | + * u32 offset, u16 data) | ||
8273 | + * @brief Write MII control register | ||
8274 | + */ | ||
8275 | +s32 ioh_gbe_phy_write_reg_miic(struct ioh_gbe_hw *hw, u32 offset, u16 data); | ||
8276 | + | ||
8277 | +/*! | ||
8278 | + * @ingroup HAL internal function | ||
8279 | + * @fn s32 ioh_gbe_phy_setup_link_fpga(struct ioh_gbe_hw *hw) | ||
8280 | + * @brief Configure link settings for FPGA | ||
8281 | + */ | ||
8282 | +s32 ioh_gbe_phy_setup_link_fpga(struct ioh_gbe_hw *hw); | ||
8283 | + | ||
8284 | +/*! | ||
8285 | + * @ingroup HAL internal function | ||
8286 | + * @fn void ioh_gbe_phy_sw_reset(struct ioh_gbe_hw *hw) | ||
8287 | + * @brief PHY software reset | ||
8288 | + */ | ||
8289 | +void ioh_gbe_phy_sw_reset(struct ioh_gbe_hw *hw); | ||
8290 | + | ||
8291 | +/*! | ||
8292 | + * @ingroup HAL internal function | ||
8293 | + * @fn void ioh_gbe_phy_hw_reset(struct ioh_gbe_hw *hw) | ||
8294 | + * @brief PHY hardware reset | ||
8295 | + */ | ||
8296 | +void ioh_gbe_phy_hw_reset(struct ioh_gbe_hw *hw); | ||
8297 | + | ||
8298 | +/*! | ||
8299 | + * @ingroup HAL internal function | ||
8300 | + * @fn s32 ioh_gbe_phy_led_on(struct ioh_gbe_hw *hw) | ||
8301 | + * @brief Set ting of led on | ||
8302 | + */ | ||
8303 | +s32 ioh_gbe_phy_led_on(struct ioh_gbe_hw *hw); | ||
8304 | + | ||
8305 | +/*! | ||
8306 | + * @ingroup HAL internal function | ||
8307 | + * @fn s32 ioh_gbe_phy_led_off(struct ioh_gbe_hw *hw) | ||
8308 | + * @brief Set ting of led off | ||
8309 | + */ | ||
8310 | +s32 ioh_gbe_phy_led_off(struct ioh_gbe_hw *hw); | ||
8311 | + | ||
8312 | +/*! | ||
8313 | + * @ingroup HAL internal function | ||
8314 | + * @fn s32 ioh_gbe_phy_led_cleanup(struct ioh_gbe_hw *hw) | ||
8315 | + * @brief Cleanup led control | ||
8316 | + */ | ||
8317 | +s32 ioh_gbe_phy_led_cleanup(struct ioh_gbe_hw *hw); | ||
8318 | + | ||
8319 | +/*! | ||
8320 | + * @ingroup HAL internal function | ||
8321 | + * @fn s32 ioh_gbe_phy_led_setup(struct ioh_gbe_hw *hw) | ||
8322 | + * @brief Setup led control | ||
8323 | + */ | ||
8324 | +s32 ioh_gbe_phy_led_setup(struct ioh_gbe_hw *hw); | ||
8325 | + | ||
8326 | +/*! | ||
8327 | + * @ingroup HAL internal function | ||
8328 | + * @fn void ioh_gbe_phy_power_up(struct ioh_gbe_hw *hw) | ||
8329 | + * @brief restore link in case the phy was powered down | ||
8330 | + */ | ||
8331 | +void ioh_gbe_phy_power_up(struct ioh_gbe_hw *hw); | ||
8332 | + | ||
8333 | +/*! | ||
8334 | + * @ingroup HAL internal function | ||
8335 | + * @fn void ioh_gbe_phy_power_down(struct ioh_gbe_hw *hw) | ||
8336 | + * @brief Power down PHY | ||
8337 | + */ | ||
8338 | +void ioh_gbe_phy_power_down(struct ioh_gbe_hw *hw); | ||
8339 | + | ||
8340 | +/*! | ||
8341 | + * @ingroup HAL internal function | ||
8342 | + * @fn void ioh_gbe_phy_set_rgmii(struct ioh_gbe_hw *hw) | ||
8343 | + * @brief RGMII interface setting | ||
8344 | + */ | ||
8345 | +void ioh_gbe_phy_set_rgmii(struct ioh_gbe_hw *hw); | ||
8346 | + | ||
8347 | +/*! | ||
8348 | + * @ingroup HAL internal function | ||
8349 | + * @fn void ioh_gbe_phy_init_setting(struct ioh_gbe_hw *hw) | ||
8350 | + * @brief PHY initial setting | ||
8351 | + */ | ||
8352 | +void ioh_gbe_phy_init_setting(struct ioh_gbe_hw *hw); | ||
8353 | + | ||
8354 | + | ||
8355 | +#endif /* _IOH_GBE_PHY_H_ */ | ||
8356 | diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_plat.c topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_plat.c | ||
8357 | --- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_plat.c 1970-01-01 09:00:00.000000000 +0900 | ||
8358 | +++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_plat.c 2010-03-11 15:11:52.000000000 +0900 | ||
8359 | @@ -0,0 +1,175 @@ | ||
8360 | +/*! | ||
8361 | + * @file ioh_gbe_plat.c | ||
8362 | + * @brief Linux IOH Gigabit Ethernet Driver HAL internal function (platform) source file | ||
8363 | + * | ||
8364 | + * @version 0.90 | ||
8365 | + * | ||
8366 | + * @section | ||
8367 | + * This program is free software; you can redistribute it and/or modify | ||
8368 | + * it under the terms of the GNU General Public License as published by | ||
8369 | + * the Free Software Foundation; version 2 of the License. | ||
8370 | + * | ||
8371 | + * This program is distributed in the hope that it will be useful, | ||
8372 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8373 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
8374 | + * GNU General Public License for more details. | ||
8375 | + * | ||
8376 | + * You should have received a copy of the GNU General Public License | ||
8377 | + * along with this program; if not, write to the Free Software | ||
8378 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
8379 | + */ | ||
8380 | + | ||
8381 | +/* | ||
8382 | + * History: | ||
8383 | + * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD. | ||
8384 | + * All rights reserved. | ||
8385 | + * | ||
8386 | + * created: | ||
8387 | + * OKI SEMICONDUCTOR 09/21/2009 | ||
8388 | + * modified: | ||
8389 | + * | ||
8390 | + */ | ||
8391 | + | ||
8392 | +#include "pch_gbe_osdep.h" | ||
8393 | +#include "pch_gbe_defines.h" | ||
8394 | +#include "pch_gbe_hw.h" | ||
8395 | +#include "pch_gbe_mac.h" | ||
8396 | +#include "pch_gbe_nvm.h" | ||
8397 | +#include "pch_gbe_phy.h" | ||
8398 | +#include "pch_gbe_api.h" | ||
8399 | + | ||
8400 | + | ||
8401 | +static void ioh_gbe_plat_get_bus_info(struct ioh_gbe_hw *hw); | ||
8402 | +static s32 ioh_gbe_plat_init_hw(struct ioh_gbe_hw *hw); | ||
8403 | + | ||
8404 | + | ||
8405 | +/*! | ||
8406 | + * @ingroup HAL internal functions | ||
8407 | + * @fn void ioh_gbe_plat_init_function_pointers(struct ioh_gbe_hw *hw) | ||
8408 | + * @brief Init func ptrs. | ||
8409 | + * @param hw [OUT] Pointer to the HW structure | ||
8410 | + * @return None | ||
8411 | + * @remarks | ||
8412 | + * The only function explicitly called by the api module to initialize | ||
8413 | + * all function pointers and parameters. | ||
8414 | + */ | ||
8415 | +void | ||
8416 | +ioh_gbe_plat_init_function_pointers(struct ioh_gbe_hw *hw) | ||
8417 | +{ | ||
8418 | + struct ioh_gbe_mac_info *mac = &hw->mac; | ||
8419 | + struct ioh_gbe_phy_info *phy = &hw->phy; | ||
8420 | + struct ioh_gbe_nvm_info *nvm = &hw->nvm; | ||
8421 | + struct ioh_gbe_functions *func = &hw->func; | ||
8422 | + | ||
8423 | + IOH_GBE_DBGFUNC("ioh_gbe_plat_init_function_pointers"); | ||
8424 | + | ||
8425 | + /* Set MAC address registers entry count */ | ||
8426 | + mac->mar_entry_count = IOH_GBE_MAR_ENTRIES; | ||
8427 | + /* Set PHY parameter */ | ||
8428 | + phy->reset_delay_us = IOH_GBE_PHY_RESET_DELAY_US; | ||
8429 | + /* Set NVM parameter */ | ||
8430 | + nvm->word_size = IOH_GBE_NVM_WORD_SIZE; | ||
8431 | + | ||
8432 | + /* Set function pointers */ | ||
8433 | + func->get_bus_info = ioh_gbe_plat_get_bus_info; | ||
8434 | + func->reset_hw = ioh_gbe_mac_reset_hw; | ||
8435 | + func->init_hw = ioh_gbe_plat_init_hw; | ||
8436 | + func->setup_link = ioh_gbe_mac_setup_link; | ||
8437 | + func->setup_physical_interface = ioh_gbe_phy_setup_link_fpga; | ||
8438 | + func->mc_addr_list_update = ioh_gbe_mac_mc_addr_list_update; | ||
8439 | + func->setup_led = ioh_gbe_phy_led_setup; | ||
8440 | + func->cleanup_led = ioh_gbe_phy_led_cleanup; | ||
8441 | + func->led_on = ioh_gbe_phy_led_on; | ||
8442 | + func->led_off = ioh_gbe_phy_led_off; | ||
8443 | + func->read_phy_reg = ioh_gbe_phy_read_reg_miic; | ||
8444 | + func->write_phy_reg = ioh_gbe_phy_write_reg_miic; | ||
8445 | + func->reset_phy = ioh_gbe_phy_hw_reset; | ||
8446 | + func->sw_reset_phy = ioh_gbe_phy_sw_reset; | ||
8447 | + func->power_up_phy = ioh_gbe_phy_power_up; | ||
8448 | + func->power_down_phy = ioh_gbe_phy_power_down; | ||
8449 | +#ifdef CONFIG_PCH_PCIEQOS | ||
8450 | + func->read_nvm = ioh_gbe_nvm_read_mem; | ||
8451 | + func->write_nvm = ioh_gbe_nvm_write_mem; | ||
8452 | + func->validate_nvm = ioh_gbe_nvm_validate_checksum; | ||
8453 | + func->read_mac_addr = ioh_gbe_nvm_read_mac_addr; | ||
8454 | +#else | ||
8455 | + func->read_mac_addr = ioh_gbe_mac_read_mac_addr; | ||
8456 | +#endif | ||
8457 | + func->ctrl_miim = ioh_gbe_mac_ctrl_miim; | ||
8458 | + func->pause_packet = ioh_gbe_mac_set_pause_packet; | ||
8459 | + | ||
8460 | +#ifdef DEBUG_TEST | ||
8461 | + IOH_GBE_TESTOUT("[MAC]mar_entry_count:%d /[PHY] reset_delay_us:%d\n", | ||
8462 | + mac->mar_entry_count, phy->reset_delay_us); | ||
8463 | + IOH_GBE_TESTOUT("[NVM] word_size:0x%08x\n", nvm->word_size); | ||
8464 | +#endif | ||
8465 | +} | ||
8466 | + | ||
8467 | + | ||
8468 | +/*! | ||
8469 | + * @ingroup HAL internal functions | ||
8470 | + * @fn static void ioh_gbe_plat_get_bus_info(struct ioh_gbe_hw *hw) | ||
8471 | + * @brief Obtain bus information for adapter | ||
8472 | + * @param hw [OUT] Pointer to the HW structure | ||
8473 | + * @return None | ||
8474 | + * @remarks | ||
8475 | + * This will obtain information about the HW bus for which the | ||
8476 | + * adaper is attached and stores it in the hw structure. This is a function | ||
8477 | + * pointer entry point called by the api module. | ||
8478 | + */ | ||
8479 | +static void | ||
8480 | +ioh_gbe_plat_get_bus_info(struct ioh_gbe_hw *hw) | ||
8481 | +{ | ||
8482 | + IOH_GBE_DBGFUNC("ioh_gbe_plat_get_bus_info"); | ||
8483 | + | ||
8484 | + hw->bus.type = ioh_gbe_bus_type_pci_express; | ||
8485 | + hw->bus.speed = ioh_gbe_bus_speed_2500; | ||
8486 | + hw->bus.width = ioh_gbe_bus_width_pcie_x1; | ||
8487 | + | ||
8488 | +#ifdef DEBUG_TEST | ||
8489 | + IOH_GBE_TESTOUT("[BUS] type:0x%08x speed:0x%08x width:0x%08x\n", | ||
8490 | + hw->bus.type, hw->bus.speed, hw->bus.width); | ||
8491 | +#endif | ||
8492 | +} | ||
8493 | + | ||
8494 | +/*! | ||
8495 | + * @ingroup HAL internal functions | ||
8496 | + * @fn static s32 ioh_gbe_plat_init_hw(struct ioh_gbe_hw *hw) | ||
8497 | + * @brief Initialize hardware | ||
8498 | + * @param hw [INOUT] Pointer to the HW structure | ||
8499 | + * @return IOH_GBE_SUCCESS: Successfully | ||
8500 | + * @return Negative value: Failed | ||
8501 | + * @remarks | ||
8502 | + * This inits the hardware readying it for operation. This is a | ||
8503 | + * function pointer entry point called by the api module. | ||
8504 | + */ | ||
8505 | +static s32 | ||
8506 | +ioh_gbe_plat_init_hw(struct ioh_gbe_hw *hw) | ||
8507 | +{ | ||
8508 | + struct ioh_gbe_mac_info *mac = &hw->mac; | ||
8509 | + s32 ret_val; | ||
8510 | + | ||
8511 | + IOH_GBE_DBGFUNC("ioh_gbe_plat_init_hw"); | ||
8512 | + | ||
8513 | + /* Setup the receive address. */ | ||
8514 | + ioh_gbe_mac_init_rx_addrs(hw, mac->mar_entry_count); | ||
8515 | + | ||
8516 | + ret_val = ioh_gbe_phy_get_id(hw); | ||
8517 | + if (ret_val) { | ||
8518 | + IOH_GBE_ERR("ioh_gbe_phy_get_id error\n"); | ||
8519 | + return ret_val; | ||
8520 | + } | ||
8521 | + ioh_gbe_phy_init_setting(hw); | ||
8522 | + /* Setup Mac interface option RGMII */ | ||
8523 | +#ifdef IOH_GBE_MAC_IFOP_RGMII | ||
8524 | + ioh_gbe_phy_set_rgmii(hw); | ||
8525 | +#endif | ||
8526 | + /* Setup link and flow control */ | ||
8527 | + ret_val = ioh_gbe_hal_setup_link(hw); | ||
8528 | +#ifdef DEBUG_TEST | ||
8529 | + if (ret_val) | ||
8530 | + IOH_GBE_ERR("ioh_gbe_phy_get_id error\n"); | ||
8531 | +#endif | ||
8532 | + return ret_val; | ||
8533 | +} | ||
8534 | + | ||
8535 | diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_regs.h topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_regs.h | ||
8536 | --- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_regs.h 1970-01-01 09:00:00.000000000 +0900 | ||
8537 | +++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_regs.h 2010-03-09 09:27:26.000000000 +0900 | ||
8538 | @@ -0,0 +1,351 @@ | ||
8539 | +/*! | ||
8540 | + * @file ioh_gbe_regs.h | ||
8541 | + * @brief Linux IOH Gigabit Ethernet Driver register macro header file | ||
8542 | + * | ||
8543 | + * @version 0.90 | ||
8544 | + * | ||
8545 | + * @section | ||
8546 | + * This program is free software; you can redistribute it and/or modify | ||
8547 | + * it under the terms of the GNU General Public License as published by | ||
8548 | + * the Free Software Foundation; version 2 of the License. | ||
8549 | + * | ||
8550 | + * This program is distributed in the hope that it will be useful, | ||
8551 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8552 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
8553 | + * GNU General Public License for more details. | ||
8554 | + * | ||
8555 | + * You should have received a copy of the GNU General Public License | ||
8556 | + * along with this program; if not, write to the Free Software | ||
8557 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
8558 | + */ | ||
8559 | + | ||
8560 | +/* | ||
8561 | + * History: | ||
8562 | + * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD. | ||
8563 | + * All rights reserved. | ||
8564 | + * | ||
8565 | + * created: | ||
8566 | + * OKI SEMICONDUCTOR 09/21/2009 | ||
8567 | + * modified: | ||
8568 | + * | ||
8569 | + */ | ||
8570 | +#ifndef _IOH_GBE_REGS_H_ | ||
8571 | +#define _IOH_GBE_REGS_H_ | ||
8572 | + | ||
8573 | +/* MAC registers */ | ||
8574 | +#define IOH_GBE_INT_ST 0x0000 /* Interrupt Status */ | ||
8575 | +#define IOH_GBE_INT_EN 0x0004 /* Interrupt Enable */ | ||
8576 | +#define IOH_GBE_MODE 0x0008 /* Mode */ | ||
8577 | +#define IOH_GBE_RESET 0x000C /* Reset */ | ||
8578 | +#define IOH_GBE_TCPIP_ACC 0x0010 /* TCP/IP Accelerator Control */ | ||
8579 | +#define IOH_GBE_EX_LIST 0x0014 /* External List */ | ||
8580 | +#define IOH_GBE_INT_ST_HOLD 0x0018 /* Interrupt Status Hold */ | ||
8581 | +#define IOH_GBE_PHY_INT_CTRL 0x001C /* PHY Interrupt Control */ | ||
8582 | +#define IOH_GBE_MAC_RX_EN 0x0020 /* MAC RX Enable */ | ||
8583 | +#define IOH_GBE_RX_FCTRL 0x0024 /* RX Flow Control */ | ||
8584 | +#define IOH_GBE_PAUSE_REQ 0x0028 /* Pause Packet Request */ | ||
8585 | +#define IOH_GBE_RX_MODE 0x002C /* RX Mode */ | ||
8586 | +#define IOH_GBE_TX_MODE 0x0030 /* TX Mode */ | ||
8587 | +#define IOH_GBE_RX_FIFO_ST 0x0034 /* RX FIFO Status */ | ||
8588 | +#define IOH_GBE_TX_FIFO_ST 0x0038 /* TX FIFO Status */ | ||
8589 | +#define IOH_GBE_TX_FID 0x003C /* TX Frame ID */ | ||
8590 | +#define IOH_GBE_TX_RESULT 0x0040 /* TX Result */ | ||
8591 | +#define IOH_GBE_PAUSE_PKT1 0x0044 /* Pause Packet1 */ | ||
8592 | +#define IOH_GBE_PAUSE_PKT2 0x0048 /* Pause Packet2 */ | ||
8593 | +#define IOH_GBE_PAUSE_PKT3 0x004C /* Pause Packet3 */ | ||
8594 | +#define IOH_GBE_PAUSE_PKT4 0x0050 /* Pause Packet4 */ | ||
8595 | +#define IOH_GBE_PAUSE_PKT5 0x0054 /* Pause Packet5 */ | ||
8596 | +#define IOH_GBE_MAC_ADR 0x0060 /* MAC Address */ | ||
8597 | +#define IOH_GBE_MAC_ADR1A 0x0060 /* MAC Address 1A */ | ||
8598 | +#define IOH_GBE_MAC_ADR1B 0x0064 /* MAC Address 1B */ | ||
8599 | +#define IOH_GBE_MAC_ADR2A 0x0068 /* MAC Address 2A */ | ||
8600 | +#define IOH_GBE_MAC_ADR2B 0x006C /* MAC Address 2B */ | ||
8601 | +#define IOH_GBE_MAC_ADR3A 0x0070 /* MAC Address 3A */ | ||
8602 | +#define IOH_GBE_MAC_ADR3B 0x0074 /* MAC Address 3B */ | ||
8603 | +#define IOH_GBE_MAC_ADR4A 0x0078 /* MAC Address 4A */ | ||
8604 | +#define IOH_GBE_MAC_ADR4B 0x007C /* MAC Address 4B */ | ||
8605 | +#define IOH_GBE_MAC_ADR5A 0x0080 /* MAC Address 5A */ | ||
8606 | +#define IOH_GBE_MAC_ADR5B 0x0084 /* MAC Address 5B */ | ||
8607 | +#define IOH_GBE_MAC_ADR6A 0x0088 /* MAC Address 6A */ | ||
8608 | +#define IOH_GBE_MAC_ADR6B 0x008C /* MAC Address 6B */ | ||
8609 | +#define IOH_GBE_MAC_ADR7A 0x0090 /* MAC Address 7A */ | ||
8610 | +#define IOH_GBE_MAC_ADR7B 0x0094 /* MAC Address 7B */ | ||
8611 | +#define IOH_GBE_MAC_ADR8A 0x0098 /* MAC Address 8A */ | ||
8612 | +#define IOH_GBE_MAC_ADR8B 0x009C /* MAC Address 8B */ | ||
8613 | +#define IOH_GBE_MAC_ADR9A 0x00A0 /* MAC Address 9A */ | ||
8614 | +#define IOH_GBE_MAC_ADR9B 0x00A4 /* MAC Address 9B */ | ||
8615 | +#define IOH_GBE_MAC_ADR10A 0x00A8 /* MAC Address 10A */ | ||
8616 | +#define IOH_GBE_MAC_ADR10B 0x00AC /* MAC Address 10B */ | ||
8617 | +#define IOH_GBE_MAC_ADR11A 0x00B0 /* MAC Address 11A */ | ||
8618 | +#define IOH_GBE_MAC_ADR11B 0x00B4 /* MAC Address 11B */ | ||
8619 | +#define IOH_GBE_MAC_ADR12A 0x00B8 /* MAC Address 12A */ | ||
8620 | +#define IOH_GBE_MAC_ADR12B 0x00BC /* MAC Address 12B */ | ||
8621 | +#define IOH_GBE_MAC_ADR13A 0x00C0 /* MAC Address 13A */ | ||
8622 | +#define IOH_GBE_MAC_ADR13B 0x00C4 /* MAC Address 13B */ | ||
8623 | +#define IOH_GBE_MAC_ADR14A 0x00C8 /* MAC Address 14A */ | ||
8624 | +#define IOH_GBE_MAC_ADR14B 0x0CC /* MAC Address 14B */ | ||
8625 | +#define IOH_GBE_MAC_ADR15A 0x00D0 /* MAC Address 15A */ | ||
8626 | +#define IOH_GBE_MAC_ADR15B 0x00D4 /* MAC Address 15B */ | ||
8627 | +#define IOH_GBE_MAC_ADR16A 0x00D8 /* MAC Address 16A */ | ||
8628 | +#define IOH_GBE_MAC_ADR16B 0x00DC /* MAC Address 16B */ | ||
8629 | +#define IOH_GBE_ADDR_MASK 0x00E0 /* MAC Address Mask */ | ||
8630 | +#define IOH_GBE_MIIM 0x00E4 /* MIIM */ | ||
8631 | +#define IOH_GBE_RGMII_ST 0x00EC /* RGMII Status */ | ||
8632 | +#define IOH_GBE_RGMII_CTRL 0x00F0 /* RGMII Control */ | ||
8633 | +#define IOH_GBE_DMA_CTRL 0x0100 /* DMA Control */ | ||
8634 | +#define IOH_GBE_RX_DSC_BASE 0x0110 /* RX Descriptor Base Address */ | ||
8635 | +#define IOH_GBE_RX_DSC_SIZE 0x0114 /* RX Descriptor Size */ | ||
8636 | +#define IOH_GBE_RX_DSC_HW_P 0x0118 /* RX Descriptor Hard Pointer */ | ||
8637 | +#define IOH_GBE_RX_DSC_HW_P_HLD 0x011C /* RX Descriptor Hard Pointer Hold */ | ||
8638 | +#define IOH_GBE_RX_DSC_SW_P 0x0120 /* RX Descriptor Soft Pointer */ | ||
8639 | +#define IOH_GBE_TX_DSC_BASE 0x0130 /* TX Descriptor Base Address */ | ||
8640 | +#define IOH_GBE_TX_DSC_SIZE 0x0134 /* TX Descriptor Size */ | ||
8641 | +#define IOH_GBE_TX_DSC_HW_P 0x0138 /* TX Descriptor Hard Pointer */ | ||
8642 | +#define IOH_GBE_TX_DSC_HW_P_HLD 0x013C /* TX Descriptor Hard Pointer Hold */ | ||
8643 | +#define IOH_GBE_TX_DSC_SW_P 0x0140 /* TX Descriptor Soft Pointer */ | ||
8644 | +#define IOH_GBE_RX_DMA_ST 0x0150 /* RX DMA Status */ | ||
8645 | +#define IOH_GBE_TX_DMA_ST 0x0154 /* TX DMA Status */ | ||
8646 | +#define IOH_GBE_WOL_ST 0x0160 /* Wake On LAN Status */ | ||
8647 | +#define IOH_GBE_WOL_CTRL 0x0164 /* Wake On LAN Control */ | ||
8648 | +#define IOH_GBE_WOL_ADDR_MASK 0x0168 /* Wake On LAN Address Mask */ | ||
8649 | + | ||
8650 | + | ||
8651 | +/* Definitions for MAC registers */ | ||
8652 | + | ||
8653 | +/* Interrupt Status */ | ||
8654 | +/* Interrupt Status Hold */ | ||
8655 | +/* Interrupt Enable */ | ||
8656 | +#define IOH_GBE_INT_RX_DMA_CMPLT 0x00000001 /* Receive DMA Transfer Complete */ | ||
8657 | +#define IOH_GBE_INT_RX_VALID 0x00000002 /* MAC Normal Receive Complete */ | ||
8658 | +#define IOH_GBE_INT_RX_FRAME_ERR 0x00000004 /* Receive frame error */ | ||
8659 | +#define IOH_GBE_INT_RX_FIFO_ERR 0x00000008 /* Receive FIFO Overflow */ | ||
8660 | +#define IOH_GBE_INT_RX_DMA_ERR 0x00000010 /* Receive DMA Transfer Error */ | ||
8661 | +#define IOH_GBE_INT_RX_DSC_EMP 0x00000020 /* Receive Descriptor Empty */ | ||
8662 | +#define IOH_GBE_INT_TX_CMPLT 0x00000100 /* MAC Transmission Complete */ | ||
8663 | +#define IOH_GBE_INT_TX_DMA_CMPLT 0x00000200 /* DMA Transfer Complete */ | ||
8664 | +#define IOH_GBE_INT_TX_FIFO_ERR 0x00000400 /* Transmission FIFO underflow. */ | ||
8665 | +#define IOH_GBE_INT_TX_DMA_ERR 0x00000800 /* Transmission DMA Error */ | ||
8666 | +#define IOH_GBE_INT_PAUSE_CMPLT 0x00001000 /* Pause Transmission complete */ | ||
8667 | +#define IOH_GBE_INT_MIIM_CMPLT 0x00010000 /* MIIM I/F Read completion */ | ||
8668 | +#define IOH_GBE_INT_PHY_INT 0x00100000 /* Interruption from PHY */ | ||
8669 | +#define IOH_GBE_INT_WOL_DET 0x01000000 /* Wake On LAN Event detection. */ | ||
8670 | +#define IOH_GBE_INT_TCPIP_ERR 0x10000000 /* TCP/IP Accelerator Error */ | ||
8671 | + | ||
8672 | +/* Mode */ | ||
8673 | +#define IOH_GBE_MODE_MII_ETHER 0x00000000 /* GIGA Ethernet Mode [MII] */ | ||
8674 | +#define IOH_GBE_MODE_GMII_ETHER 0x80000000 /* GIGA Ethernet Mode [GMII] */ | ||
8675 | +#define IOH_GBE_MODE_HALF_DUPLEX 0x00000000 /* Duplex Mode [half duplex] */ | ||
8676 | +#define IOH_GBE_MODE_FULL_DUPLEX 0x40000000 /* Duplex Mode [full duplex] */ | ||
8677 | +#define IOH_GBE_MODE_FR_BST 0x04000000 /* Frame bursting is done */ | ||
8678 | + | ||
8679 | +/* Reset */ | ||
8680 | +#define IOH_GBE_ALL_RST 0x80000000 /* All reset */ | ||
8681 | +#define IOH_GBE_TX_RST 0x40000000 /* TX MAC, TX FIFO, TX DMA reset */ | ||
8682 | +#define IOH_GBE_RX_RST 0x04000000 /* RX MAC, RX FIFO, RX DMA reset */ | ||
8683 | + | ||
8684 | +/* TCP/IP Accelerator Control */ | ||
8685 | +/* External List Enable */ | ||
8686 | +#define IOH_GBE_EX_LIST_EN 0x00000008 | ||
8687 | +/* RX TCP/IP accelerator Disabled (Padding Enable) */ | ||
8688 | +#define IOH_GBE_RX_TCPIPACC_OFF 0x00000004 | ||
8689 | +/* TX TCP/IP accelerator and Padding Enable */ | ||
8690 | +#define IOH_GBE_TX_TCPIPACC_EN 0x00000002 | ||
8691 | +/* RX TCP/IP accelerator and Padding Enable */ | ||
8692 | +#define IOH_GBE_RX_TCPIPACC_EN 0x00000001 | ||
8693 | + | ||
8694 | +/* External List */ | ||
8695 | +/* Interrupt Status Hold */ | ||
8696 | +/* PHY Interrupt Control */ | ||
8697 | + | ||
8698 | +/* MAC RX Enable */ | ||
8699 | +#define IOH_GBE_MRE_MAC_RX_EN 0x00000001 /* MAC Receive Enable */ | ||
8700 | + | ||
8701 | +/* RX Flow Control */ | ||
8702 | +/* Pause packet and Transmission Pause are enabled */ | ||
8703 | +#define IOH_GBE_FL_CTRL_EN 0x80000000 | ||
8704 | + | ||
8705 | +/* Pause Packet Request */ | ||
8706 | +#define IOH_GBE_PS_PKT_RQ 0x80000000 /* Pause packet Request */ | ||
8707 | + | ||
8708 | +/* RX Mode */ | ||
8709 | +/* Address Filtering Enable */ | ||
8710 | +#define IOH_GBE_ADD_FIL_EN 0x80000000 | ||
8711 | +/* Multicast Filtering Enable */ | ||
8712 | +#define IOH_GBE_MLT_FIL_EN 0x40000000 | ||
8713 | +/* Receive Almost Empty Threshold */ | ||
8714 | +#define IOH_GBE_RH_ALM_EMP_4 0x00000000 /* 4 words */ | ||
8715 | +#define IOH_GBE_RH_ALM_EMP_8 0x00004000 /* 8 words */ | ||
8716 | +#define IOH_GBE_RH_ALM_EMP_16 0x00008000 /* 16 words */ | ||
8717 | +#define IOH_GBE_RH_ALM_EMP_32 0x0000C000 /* 32 words */ | ||
8718 | +/* Receive Almost Full Threshold */ | ||
8719 | +#define IOH_GBE_RH_ALM_FULL_4 0x00000000 /* 4 words */ | ||
8720 | +#define IOH_GBE_RH_ALM_FULL_8 0x00001000 /* 8 words */ | ||
8721 | +#define IOH_GBE_RH_ALM_FULL_16 0x00002000 /* 16 words */ | ||
8722 | +#define IOH_GBE_RH_ALM_FULL_32 0x00003000 /* 32 words */ | ||
8723 | +/* RX FIFO Read Triger Threshold */ | ||
8724 | +#define IOH_GBE_RH_RD_TRG_4 0x00000000 /* 4 words */ | ||
8725 | +#define IOH_GBE_RH_RD_TRG_8 0x00000200 /* 8 words */ | ||
8726 | +#define IOH_GBE_RH_RD_TRG_16 0x00000400 /* 16 words */ | ||
8727 | +#define IOH_GBE_RH_RD_TRG_32 0x00000600 /* 32 words */ | ||
8728 | +#define IOH_GBE_RH_RD_TRG_64 0x00000800 /* 64 words */ | ||
8729 | +#define IOH_GBE_RH_RD_TRG_128 0x00000A00 /* 128 words */ | ||
8730 | +#define IOH_GBE_RH_RD_TRG_256 0x00000C00 /* 256 words */ | ||
8731 | +#define IOH_GBE_RH_RD_TRG_512 0x00000E00 /* 512 words */ | ||
8732 | + | ||
8733 | + /* Receive Descriptor bit definitions */ | ||
8734 | + #define IOH_GBE_RXD_ACC_STAT_BCAST 0x00000400 | ||
8735 | + #define IOH_GBE_RXD_ACC_STAT_MCAST 0x00000200 | ||
8736 | + #define IOH_GBE_RXD_ACC_STAT_UCAST 0x00000100 | ||
8737 | + #define IOH_GBE_RXD_ACC_STAT_TCPIPOK 0x000000C0 | ||
8738 | + #define IOH_GBE_RXD_ACC_STAT_IPOK 0x00000080 | ||
8739 | + #define IOH_GBE_RXD_ACC_STAT_TCPOK 0x00000040 | ||
8740 | + #define IOH_GBE_RXD_ACC_STAT_IP6ERR 0x00000020 | ||
8741 | + #define IOH_GBE_RXD_ACC_STAT_OFLIST 0x00000010 | ||
8742 | + #define IOH_GBE_RXD_ACC_STAT_TYPEIP 0x00000008 | ||
8743 | + #define IOH_GBE_RXD_ACC_STAT_MACL 0x00000004 | ||
8744 | + #define IOH_GBE_RXD_ACC_STAT_PPPOE 0x00000002 | ||
8745 | + #define IOH_GBE_RXD_ACC_STAT_VTAGT 0x00000001 | ||
8746 | + #define IOH_GBE_RXD_GMAC_STAT_PAUSE 0x0200 | ||
8747 | + #define IOH_GBE_RXD_GMAC_STAT_MARBR 0x0100 | ||
8748 | + #define IOH_GBE_RXD_GMAC_STAT_MARMLT 0x0080 | ||
8749 | + #define IOH_GBE_RXD_GMAC_STAT_MARIND 0x0040 | ||
8750 | + #define IOH_GBE_RXD_GMAC_STAT_MARNOTMT 0x0020 | ||
8751 | + #define IOH_GBE_RXD_GMAC_STAT_TLONG 0x0010 | ||
8752 | + #define IOH_GBE_RXD_GMAC_STAT_TSHRT 0x0008 | ||
8753 | + #define IOH_GBE_RXD_GMAC_STAT_NOTOCTAL 0x0004 | ||
8754 | + #define IOH_GBE_RXD_GMAC_STAT_NBLERR 0x0002 | ||
8755 | + #define IOH_GBE_RXD_GMAC_STAT_CRCERR 0x0001 | ||
8756 | + | ||
8757 | + /* Transmit Descriptor bit definitions */ | ||
8758 | + #define IOH_GBE_TXD_CTRL_TCPIP_ACC_OFF 0x0008 | ||
8759 | + #define IOH_GBE_TXD_CTRL_ITAG 0x0004 | ||
8760 | + #define IOH_GBE_TXD_CTRL_ICRC 0x0002 | ||
8761 | + #define IOH_GBE_TXD_CTRL_APAD 0x0001 | ||
8762 | + #define IOH_GBE_TXD_WORDS_SHIFT 2 | ||
8763 | + #define IOH_GBE_TXD_GMAC_STAT_CMPLT 0x2000 | ||
8764 | + #define IOH_GBE_TXD_GMAC_STAT_ABT 0x1000 | ||
8765 | + #define IOH_GBE_TXD_GMAC_STAT_EXCOL 0x0800 | ||
8766 | + #define IOH_GBE_TXD_GMAC_STAT_SNGCOL 0x0400 | ||
8767 | + #define IOH_GBE_TXD_GMAC_STAT_MLTCOL 0x0200 | ||
8768 | + #define IOH_GBE_TXD_GMAC_STAT_CRSER 0x0100 | ||
8769 | + #define IOH_GBE_TXD_GMAC_STAT_TLNG 0x0080 | ||
8770 | + #define IOH_GBE_TXD_GMAC_STAT_TSHRT 0x0040 | ||
8771 | + #define IOH_GBE_TXD_GMAC_STAT_LTCOL 0x0020 | ||
8772 | + #define IOH_GBE_TXD_GMAC_STAT_TFUNDFLW 0x0010 | ||
8773 | + #define IOH_GBE_TXD_GMAC_STAT_RTYCNT_MASK 0x000F | ||
8774 | + | ||
8775 | +/* TX Mode */ | ||
8776 | +#define IOH_GBE_TM_NO_RTRY 0x80000000 /* No Retransmission */ | ||
8777 | +#define IOH_GBE_TM_LONG_PKT 0x40000000 /* Long Packt TX Enable */ | ||
8778 | +#define IOH_GBE_TM_ST_AND_FD 0x20000000 /* Stare and Forward */ | ||
8779 | +#define IOH_GBE_TM_SHORT_PKT 0x10000000 /* Short Packet TX Enable */ | ||
8780 | +#define IOH_GBE_TM_LTCOL_RETX 0x08000000 /* Retransmission at Late Collision */ | ||
8781 | +/* Frame Start Threshold */ | ||
8782 | +#define IOH_GBE_TM_TH_TX_STRT_4 0x00000000 /* 4 words */ | ||
8783 | +#define IOH_GBE_TM_TH_TX_STRT_8 0x00004000 /* 8 words */ | ||
8784 | +#define IOH_GBE_TM_TH_TX_STRT_16 0x00008000 /* 16 words */ | ||
8785 | +#define IOH_GBE_TM_TH_TX_STRT_32 0x0000C000 /* 32 words */ | ||
8786 | +/* Transmit Almost Empty Threshold */ | ||
8787 | +#define IOH_GBE_TM_TH_ALM_EMP_4 0x00000000 /* 4 words */ | ||
8788 | +#define IOH_GBE_TM_TH_ALM_EMP_8 0x00000800 /* 8 words */ | ||
8789 | +#define IOH_GBE_TM_TH_ALM_EMP_16 0x00001000 /* 16 words */ | ||
8790 | +#define IOH_GBE_TM_TH_ALM_EMP_32 0x00001800 /* 32 words */ | ||
8791 | +#define IOH_GBE_TM_TH_ALM_EMP_64 0x00002000 /* 64 words */ | ||
8792 | +#define IOH_GBE_TM_TH_ALM_EMP_128 0x00002800 /* 128 words */ | ||
8793 | +#define IOH_GBE_TM_TH_ALM_EMP_256 0x00003000 /* 256 words */ | ||
8794 | +#define IOH_GBE_TM_TH_ALM_EMP_512 0x00003800 /* 512 words */ | ||
8795 | +/* Transmit Almost Full Threshold */ | ||
8796 | +#define IOH_GBE_TM_TH_ALM_FULL_4 0x00000000 /* 4 words */ | ||
8797 | +#define IOH_GBE_TM_TH_ALM_FULL_8 0x00000200 /* 8 words */ | ||
8798 | +#define IOH_GBE_TM_TH_ALM_FULL_16 0x00000400 /* 16 words */ | ||
8799 | +#define IOH_GBE_TM_TH_ALM_FULL_32 0x00000600 /* 32 words */ | ||
8800 | + | ||
8801 | +/* RX FIFO Status */ | ||
8802 | +/* RX FIFO is almost full. */ | ||
8803 | +#define IOH_GBE_RF_ALM_FULL 0x80000000 | ||
8804 | +/* RX FIFO is almost empty. */ | ||
8805 | +#define IOH_GBE_RF_ALM_EMP 0x40000000 | ||
8806 | +/* that the data within RX FIFO has become more than RH_RD_TRG. */ | ||
8807 | +#define IOH_GBE_RF_RD_TRG 0x20000000 | ||
8808 | +/* The word count of the data existing within RX FIFO. */ | ||
8809 | +#define IOH_GBE_RF_STRWD 0x1FFE0000 | ||
8810 | +/* that frame which is currently valid/enabled is stored in RX FIFO. */ | ||
8811 | +#define IOH_GBE_RF_RCVING 0x00010000 | ||
8812 | + | ||
8813 | +/* TX FIFO Status */ | ||
8814 | +/* TX Frame ID */ | ||
8815 | +/* TX Result */ | ||
8816 | +/* Pause Packet1-5 */ | ||
8817 | +/* MAC Address 1(A/B)- 16*/ | ||
8818 | +/* MAC Address Mask */ | ||
8819 | +#define IOH_GBE_BUSY 0x80000000 | ||
8820 | + | ||
8821 | +/* MIIM */ | ||
8822 | +#define IOH_GBE_MIIM_OPER_WRITE 0x04000000 | ||
8823 | +#define IOH_GBE_MIIM_OPER_READ 0x00000000 | ||
8824 | +#define IOH_GBE_MIIM_OPER_READY 0x04000000 | ||
8825 | +#define IOH_GBE_MIIM_PHY_ADDR_SHIFT 21 | ||
8826 | +#define IOH_GBE_MIIM_REG_ADDR_SHIFT 16 | ||
8827 | + | ||
8828 | +/* RGMII Status */ | ||
8829 | +#define IOH_GBE_LINK_UP 0x80000008 | ||
8830 | +#define IOH_GBE_RXC_SPEED_MSK 0x00000006 | ||
8831 | +#define IOH_GBE_RXC_SPEED_2_5M 0x00000000 /* 2.5MHz */ | ||
8832 | +#define IOH_GBE_RXC_SPEED_25M 0x00000002 /* 25MHz */ | ||
8833 | +#define IOH_GBE_RXC_SPEED_125M 0x00000004 /* 100MHz */ | ||
8834 | +#define IOH_GBE_DUPLEX_FULL 0x00000001 | ||
8835 | + | ||
8836 | +/* RGMII Control */ | ||
8837 | +#define IOH_GBE_CRS_SEL 0x00000010 | ||
8838 | +#define IOH_GBE_RGMII_RATE_125M 0x00000000 | ||
8839 | +#define IOH_GBE_RGMII_RATE_25M 0x00000008 | ||
8840 | +#define IOH_GBE_RGMII_RATE_2_5M 0x0000000C | ||
8841 | +#define IOH_GBE_RGMII_MODE_GMII 0x00000000 | ||
8842 | +#define IOH_GBE_RGMII_MODE_RGMII 0x00000002 | ||
8843 | +#define IOH_GBE_CHIP_TYPE_EXTERNAL 0x00000000 | ||
8844 | +#define IOH_GBE_CHIP_TYPE_INTERNAL 0x00000001 | ||
8845 | + | ||
8846 | +/* DMA Control */ | ||
8847 | +#define IOH_GBE_RX_DMA_EN 0x00000002 /* Enables Receive DMA */ | ||
8848 | +#define IOH_GBE_TX_DMA_EN 0x00000001 /* Enables Transmission DMA */ | ||
8849 | + | ||
8850 | + | ||
8851 | + | ||
8852 | +/* RX Descriptor Base Address */ | ||
8853 | +/* RX Descriptor Size */ | ||
8854 | +/* RX Descriptor Hard Pointer */ | ||
8855 | +/* RX Descriptor Hard Pointer Hold */ | ||
8856 | +/* RX Descriptor Soft Pointer */ | ||
8857 | +/* TX Descriptor Base Address */ | ||
8858 | +/* TX Descriptor Size */ | ||
8859 | +/* TX Descriptor Hard Pointer */ | ||
8860 | +/* TX Descriptor Hard Pointer Hold */ | ||
8861 | +/* TX Descriptor Soft Pointer */ | ||
8862 | + | ||
8863 | +/* RX DMA Status */ | ||
8864 | +/* TX DMA Status */ | ||
8865 | + | ||
8866 | + | ||
8867 | +/* Wake On LAN Status */ | ||
8868 | +#define IOH_GBE_WLS_BR 0x00000008 /* Broadcas Address */ | ||
8869 | +#define IOH_GBE_WLS_MLT 0x00000004 /* Multicast Address */ | ||
8870 | +/* The Frame registered in Address Recognizer */ | ||
8871 | +#define IOH_GBE_WLS_IND 0x00000002 | ||
8872 | +#define IOH_GBE_WLS_MP 0x00000001 /* Magic packet Address */ | ||
8873 | + | ||
8874 | +/* Wake On LAN Control */ | ||
8875 | +#define IOH_GBE_WLC_WOL_MODE 0x00010000 | ||
8876 | +#define IOH_GBE_WLC_IGN_TLONG 0x00000100 | ||
8877 | +#define IOH_GBE_WLC_IGN_TSHRT 0x00000080 | ||
8878 | +#define IOH_GBE_WLC_IGN_OCTER 0x00000040 | ||
8879 | +#define IOH_GBE_WLC_IGN_NBLER 0x00000020 | ||
8880 | +#define IOH_GBE_WLC_IGN_CRCER 0x00000010 | ||
8881 | +#define IOH_GBE_WLC_BR 0x00000008 | ||
8882 | +#define IOH_GBE_WLC_MLT 0x00000004 | ||
8883 | +#define IOH_GBE_WLC_IND 0x00000002 | ||
8884 | +#define IOH_GBE_WLC_MP 0x00000001 | ||
8885 | + | ||
8886 | +/* Wake On LAN Address Mask */ | ||
8887 | +#define IOH_GBE_WLA_BUSY 0x80000000 | ||
8888 | + | ||
8889 | +#endif | ||