Commit | Line | Data |
---|---|---|
cfb739b4 GKH |
1 | /* |
2 | * Agere Systems Inc. | |
3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs | |
4 | * | |
64f93036 | 5 | * Copyright © 2005 Agere Systems Inc. |
cfb739b4 GKH |
6 | * All rights reserved. |
7 | * http://www.agere.com | |
8 | * | |
9 | *------------------------------------------------------------------------------ | |
10 | * | |
11 | * et131x_initpci.c - Routines and data used to register the driver with the | |
12 | * PCI (and PCI Express) subsystem, as well as basic driver | |
13 | * init and startup. | |
14 | * | |
15 | *------------------------------------------------------------------------------ | |
16 | * | |
17 | * SOFTWARE LICENSE | |
18 | * | |
19 | * This software is provided subject to the following terms and conditions, | |
20 | * which you should read carefully before using the software. Using this | |
21 | * software indicates your acceptance of these terms and conditions. If you do | |
22 | * not agree with these terms and conditions, do not use the software. | |
23 | * | |
64f93036 | 24 | * Copyright © 2005 Agere Systems Inc. |
cfb739b4 GKH |
25 | * All rights reserved. |
26 | * | |
27 | * Redistribution and use in source or binary forms, with or without | |
28 | * modifications, are permitted provided that the following conditions are met: | |
29 | * | |
30 | * . Redistributions of source code must retain the above copyright notice, this | |
31 | * list of conditions and the following Disclaimer as comments in the code as | |
32 | * well as in the documentation and/or other materials provided with the | |
33 | * distribution. | |
34 | * | |
35 | * . Redistributions in binary form must reproduce the above copyright notice, | |
36 | * this list of conditions and the following Disclaimer in the documentation | |
37 | * and/or other materials provided with the distribution. | |
38 | * | |
39 | * . Neither the name of Agere Systems Inc. nor the names of the contributors | |
40 | * may be used to endorse or promote products derived from this software | |
41 | * without specific prior written permission. | |
42 | * | |
43 | * Disclaimer | |
44 | * | |
64f93036 | 45 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
cfb739b4 GKH |
46 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF |
47 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY | |
48 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN | |
49 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY | |
50 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
51 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
52 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
53 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT | |
54 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |
55 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | |
56 | * DAMAGE. | |
57 | * | |
58 | */ | |
59 | ||
60 | #include "et131x_version.h" | |
61 | #include "et131x_debug.h" | |
62 | #include "et131x_defs.h" | |
63 | ||
64 | #include <linux/pci.h> | |
65 | #include <linux/init.h> | |
66 | #include <linux/module.h> | |
67 | #include <linux/types.h> | |
68 | #include <linux/kernel.h> | |
69 | ||
70 | #include <linux/sched.h> | |
71 | #include <linux/ptrace.h> | |
72 | #include <linux/slab.h> | |
73 | #include <linux/ctype.h> | |
74 | #include <linux/string.h> | |
75 | #include <linux/timer.h> | |
76 | #include <linux/interrupt.h> | |
77 | #include <linux/in.h> | |
78 | #include <linux/delay.h> | |
64f93036 AC |
79 | #include <linux/io.h> |
80 | #include <linux/bitops.h> | |
cfb739b4 | 81 | #include <asm/system.h> |
cfb739b4 GKH |
82 | |
83 | #include <linux/netdevice.h> | |
84 | #include <linux/etherdevice.h> | |
85 | #include <linux/skbuff.h> | |
86 | #include <linux/if_arp.h> | |
87 | #include <linux/ioport.h> | |
88 | #include <linux/random.h> | |
89 | ||
90 | #include "et1310_phy.h" | |
91 | #include "et1310_pm.h" | |
92 | #include "et1310_jagcore.h" | |
93 | ||
94 | #include "et131x_adapter.h" | |
95 | #include "et131x_netdev.h" | |
96 | #include "et131x_config.h" | |
97 | #include "et131x_isr.h" | |
98 | ||
99 | #include "et1310_address_map.h" | |
cfb739b4 GKH |
100 | #include "et1310_tx.h" |
101 | #include "et1310_rx.h" | |
102 | #include "et1310_mac.h" | |
103 | #include "et1310_eeprom.h" | |
104 | ||
105 | ||
106 | int __devinit et131x_pci_setup(struct pci_dev *pdev, | |
107 | const struct pci_device_id *ent); | |
108 | void __devexit et131x_pci_remove(struct pci_dev *pdev); | |
109 | ||
110 | ||
111 | /* Modinfo parameters (filled out using defines from et131x_version.h) */ | |
112 | MODULE_AUTHOR(DRIVER_AUTHOR); | |
113 | MODULE_DESCRIPTION(DRIVER_INFO); | |
114 | MODULE_LICENSE(DRIVER_LICENSE); | |
115 | ||
116 | /* Module Parameters and related data for debugging facilities */ | |
117 | #ifdef CONFIG_ET131X_DEBUG | |
118 | static u32 et131x_debug_level = DBG_LVL; | |
119 | static u32 et131x_debug_flags = DBG_DEFAULTS; | |
120 | ||
121 | /* | |
122 | et131x_debug_level : | |
123 | Level of debugging desired (0-7) | |
124 | 7 : DBG_RX_ON | DBG_TX_ON | |
125 | 6 : DBG_PARAM_ON | |
126 | 5 : DBG_VERBOSE_ON | |
127 | 4 : DBG_TRACE_ON | |
128 | 3 : DBG_NOTICE_ON | |
129 | 2 : no debug info | |
130 | 1 : no debug info | |
131 | 0 : no debug info | |
132 | */ | |
133 | ||
134 | module_param(et131x_debug_level, uint, 0); | |
135 | module_param(et131x_debug_flags, uint, 0); | |
136 | ||
137 | MODULE_PARM_DESC(et131x_debug_level, "Level of debugging desired (0-7)"); | |
138 | ||
139 | static dbg_info_t et131x_info = { DRIVER_NAME_EXT, 0, 0 }; | |
140 | dbg_info_t *et131x_dbginfo = &et131x_info; | |
141 | #endif /* CONFIG_ET131X_DEBUG */ | |
142 | ||
8c5f20f3 AC |
143 | /* Defines for Parameter Default/Min/Max vaules */ |
144 | #define PARM_SPEED_DUPLEX_MIN 0 | |
145 | #define PARM_SPEED_DUPLEX_MAX 5 | |
146 | ||
147 | /* Module parameter for disabling NMI | |
148 | * et131x_nmi_disable : | |
149 | * Disable NMI (0-2) [0] | |
150 | * 0 : | |
151 | * 1 : | |
152 | * 2 : | |
153 | */ | |
154 | static u32 et131x_nmi_disable; /* 0-2 */ | |
155 | module_param(et131x_nmi_disable, uint, 0); | |
156 | MODULE_PARM_DESC(et131x_nmi_disable, "Disable NMI (0-2) [0]"); | |
157 | ||
158 | /* Module parameter for manual speed setting | |
159 | * Set Link speed and dublex manually (0-5) [0] | |
160 | * 1 : 10Mb Half-Duplex | |
161 | * 2 : 10Mb Full-Duplex | |
162 | * 3 : 100Mb Half-Duplex | |
163 | * 4 : 100Mb Full-Duplex | |
164 | * 5 : 1000Mb Full-Duplex | |
165 | * 0 : Auto Speed Auto Duplex // default | |
166 | */ | |
167 | static u32 et131x_speed_set; | |
168 | module_param(et131x_speed_set, uint, 0); | |
169 | MODULE_PARM_DESC(et131x_speed_set, | |
170 | "Set Link speed and dublex manually (0-5) [0] \n 1 : 10Mb Half-Duplex \n 2 : 10Mb Full-Duplex \n 3 : 100Mb Half-Duplex \n 4 : 100Mb Full-Duplex \n 5 : 1000Mb Full-Duplex \n 0 : Auto Speed Auto Dublex"); | |
171 | ||
172 | ||
173 | ||
cfb739b4 GKH |
174 | static struct pci_device_id et131x_pci_table[] __devinitdata = { |
175 | {ET131X_PCI_VENDOR_ID, ET131X_PCI_DEVICE_ID_GIG, PCI_ANY_ID, | |
176 | PCI_ANY_ID, 0, 0, 0UL}, | |
177 | {ET131X_PCI_VENDOR_ID, ET131X_PCI_DEVICE_ID_FAST, PCI_ANY_ID, | |
178 | PCI_ANY_ID, 0, 0, 0UL}, | |
179 | {0,} | |
180 | }; | |
181 | ||
182 | MODULE_DEVICE_TABLE(pci, et131x_pci_table); | |
183 | ||
184 | static struct pci_driver et131x_driver = { | |
185 | .name = DRIVER_NAME, | |
186 | .id_table = et131x_pci_table, | |
187 | .probe = et131x_pci_setup, | |
188 | .remove = __devexit_p(et131x_pci_remove), | |
64f93036 AC |
189 | .suspend = NULL, /* et131x_pci_suspend */ |
190 | .resume = NULL, /* et131x_pci_resume */ | |
cfb739b4 GKH |
191 | }; |
192 | ||
193 | ||
194 | /** | |
195 | * et131x_init_module - The "main" entry point called on driver initialization | |
196 | * | |
197 | * Returns 0 on success, errno on failure (as defined in errno.h) | |
198 | */ | |
199 | int et131x_init_module(void) | |
200 | { | |
201 | int result; | |
202 | ||
203 | #ifdef CONFIG_ET131X_DEBUG | |
204 | /* Set the level of debug messages displayed using the module | |
205 | * parameter | |
206 | */ | |
207 | et131x_dbginfo->dbgFlags = et131x_debug_flags; | |
208 | ||
209 | switch (et131x_debug_level) { | |
210 | case 7: | |
211 | et131x_dbginfo->dbgFlags |= (DBG_RX_ON | DBG_TX_ON); | |
212 | ||
213 | case 6: | |
214 | et131x_dbginfo->dbgFlags |= DBG_PARAM_ON; | |
215 | ||
216 | case 5: | |
217 | et131x_dbginfo->dbgFlags |= DBG_VERBOSE_ON; | |
218 | ||
219 | case 4: | |
220 | et131x_dbginfo->dbgFlags |= DBG_TRACE_ON; | |
221 | ||
222 | case 3: | |
223 | et131x_dbginfo->dbgFlags |= DBG_NOTICE_ON; | |
224 | ||
225 | case 2: | |
226 | case 1: | |
227 | case 0: | |
228 | default: | |
229 | break; | |
230 | } | |
231 | #endif /* CONFIG_ET131X_DEBUG */ | |
232 | ||
233 | DBG_ENTER(et131x_dbginfo); | |
234 | DBG_PRINT("%s\n", DRIVER_INFO); | |
235 | ||
8c5f20f3 AC |
236 | if (et131x_speed_set < PARM_SPEED_DUPLEX_MIN || |
237 | et131x_speed_set > PARM_SPEED_DUPLEX_MAX) { | |
238 | printk(KERN_WARNING "et131x: invalid speed setting ignored.\n"); | |
239 | et131x_speed_set = 0; | |
240 | } | |
241 | ||
cfb739b4 GKH |
242 | result = pci_register_driver(&et131x_driver); |
243 | ||
244 | DBG_LEAVE(et131x_dbginfo); | |
245 | return result; | |
246 | } | |
247 | ||
248 | /** | |
249 | * et131x_cleanup_module - The entry point called on driver cleanup | |
250 | */ | |
251 | void et131x_cleanup_module(void) | |
252 | { | |
253 | DBG_ENTER(et131x_dbginfo); | |
254 | ||
255 | pci_unregister_driver(&et131x_driver); | |
256 | ||
257 | DBG_LEAVE(et131x_dbginfo); | |
258 | } | |
259 | ||
260 | /* | |
261 | * These macros map the driver-specific init_module() and cleanup_module() | |
262 | * routines so they can be called by the kernel. | |
263 | */ | |
264 | module_init(et131x_init_module); | |
265 | module_exit(et131x_cleanup_module); | |
266 | ||
267 | ||
268 | /** | |
269 | * et131x_find_adapter - Find the adapter and get all the assigned resources | |
270 | * @adapter: pointer to our private adapter structure | |
271 | * | |
272 | * Returns 0 on success, errno on failure (as defined in errno.h) | |
273 | */ | |
274 | int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev) | |
275 | { | |
276 | int result; | |
277 | uint8_t eepromStat; | |
278 | uint8_t maxPayload = 0; | |
279 | uint8_t read_size_reg; | |
5ec3487a | 280 | u8 rev; |
cfb739b4 GKH |
281 | |
282 | DBG_ENTER(et131x_dbginfo); | |
283 | ||
284 | /* Allow disabling of Non-Maskable Interrupts in I/O space, to | |
285 | * support validation. | |
286 | */ | |
287 | if (adapter->RegistryNMIDisable) { | |
288 | uint8_t RegisterVal; | |
289 | ||
290 | RegisterVal = inb(ET1310_NMI_DISABLE); | |
291 | RegisterVal &= 0xf3; | |
292 | ||
64f93036 | 293 | if (adapter->RegistryNMIDisable == 2) |
cfb739b4 | 294 | RegisterVal |= 0xc; |
cfb739b4 GKH |
295 | |
296 | outb(ET1310_NMI_DISABLE, RegisterVal); | |
297 | } | |
298 | ||
299 | /* We first need to check the EEPROM Status code located at offset | |
300 | * 0xB2 of config space | |
301 | */ | |
302 | result = pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS, | |
303 | &eepromStat); | |
304 | ||
305 | /* THIS IS A WORKAROUND: | |
64f93036 | 306 | * I need to call this function twice to get my card in a |
cfb739b4 GKH |
307 | * LG M1 Express Dual running. I tried also a msleep before this |
308 | * function, because I thougth there could be some time condidions | |
309 | * but it didn't work. Call the whole function twice also work. | |
310 | */ | |
311 | result = pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS, | |
312 | &eepromStat); | |
313 | if (result != PCIBIOS_SUCCESSFUL) { | |
314 | DBG_ERROR(et131x_dbginfo, "Could not read PCI config space for " | |
315 | "EEPROM Status\n"); | |
316 | DBG_LEAVE(et131x_dbginfo); | |
317 | return -EIO; | |
318 | } | |
319 | ||
320 | /* Determine if the error(s) we care about are present. If they are | |
321 | * present, we need to fail. | |
322 | */ | |
323 | if (eepromStat & 0x4C) { | |
5ec3487a | 324 | result = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); |
cfb739b4 GKH |
325 | if (result != PCIBIOS_SUCCESSFUL) { |
326 | DBG_ERROR(et131x_dbginfo, | |
327 | "Could not read PCI config space for " | |
328 | "Revision ID\n"); | |
329 | DBG_LEAVE(et131x_dbginfo); | |
330 | return -EIO; | |
5ec3487a | 331 | } else if (rev == 0x01) { |
cfb739b4 | 332 | int32_t nLoop; |
9fa81099 | 333 | uint8_t temp[4] = { 0xFE, 0x13, 0x10, 0xFF }; |
cfb739b4 GKH |
334 | |
335 | /* Re-write the first 4 bytes if we have an eeprom | |
336 | * present and the revision id is 1, this fixes the | |
337 | * corruption seen with 1310 B Silicon | |
338 | */ | |
339 | for (nLoop = 0; nLoop < 3; nLoop++) { | |
13071fde | 340 | EepromWriteByte(adapter, nLoop, temp[nLoop]); |
cfb739b4 GKH |
341 | } |
342 | } | |
343 | ||
344 | DBG_ERROR(et131x_dbginfo, | |
345 | "Fatal EEPROM Status Error - 0x%04x\n", eepromStat); | |
346 | ||
347 | /* This error could mean that there was an error reading the | |
348 | * eeprom or that the eeprom doesn't exist. We will treat | |
349 | * each case the same and not try to gather additional | |
350 | * information that normally would come from the eeprom, like | |
351 | * MAC Address | |
352 | */ | |
9fa81099 | 353 | adapter->has_eeprom = 0; |
cfb739b4 GKH |
354 | |
355 | DBG_LEAVE(et131x_dbginfo); | |
356 | return -EIO; | |
357 | } else { | |
358 | DBG_TRACE(et131x_dbginfo, "EEPROM Status Code - 0x%04x\n", | |
359 | eepromStat); | |
9fa81099 | 360 | adapter->has_eeprom = 1; |
cfb739b4 GKH |
361 | } |
362 | ||
363 | /* Read the EEPROM for information regarding LED behavior. Refer to | |
364 | * ET1310_phy.c, et131x_xcvr_init(), for its use. | |
365 | */ | |
13071fde AC |
366 | EepromReadByte(adapter, 0x70, &adapter->eepromData[0]); |
367 | EepromReadByte(adapter, 0x71, &adapter->eepromData[1]); | |
cfb739b4 | 368 | |
64f93036 AC |
369 | if (adapter->eepromData[0] != 0xcd) |
370 | /* Disable all optional features */ | |
371 | adapter->eepromData[1] = 0x00; | |
cfb739b4 GKH |
372 | |
373 | /* Let's set up the PORT LOGIC Register. First we need to know what | |
374 | * the max_payload_size is | |
375 | */ | |
376 | result = pci_read_config_byte(pdev, ET1310_PCI_MAX_PYLD, &maxPayload); | |
377 | if (result != PCIBIOS_SUCCESSFUL) { | |
378 | DBG_ERROR(et131x_dbginfo, "Could not read PCI config space for " | |
379 | "Max Payload Size\n"); | |
380 | DBG_LEAVE(et131x_dbginfo); | |
381 | return -EIO; | |
382 | } | |
383 | ||
384 | /* Program the Ack/Nak latency and replay timers */ | |
64f93036 | 385 | maxPayload &= 0x07; /* Only the lower 3 bits are valid */ |
cfb739b4 GKH |
386 | |
387 | if (maxPayload < 2) { | |
388 | const uint16_t AckNak[2] = { 0x76, 0xD0 }; | |
389 | const uint16_t Replay[2] = { 0x1E0, 0x2ED }; | |
390 | ||
391 | result = pci_write_config_word(pdev, ET1310_PCI_ACK_NACK, | |
392 | AckNak[maxPayload]); | |
393 | if (result != PCIBIOS_SUCCESSFUL) { | |
394 | DBG_ERROR(et131x_dbginfo, | |
395 | "Could not write PCI config space " | |
396 | "for ACK/NAK\n"); | |
397 | DBG_LEAVE(et131x_dbginfo); | |
398 | return -EIO; | |
399 | } | |
400 | ||
401 | result = pci_write_config_word(pdev, ET1310_PCI_REPLAY, | |
402 | Replay[maxPayload]); | |
403 | if (result != PCIBIOS_SUCCESSFUL) { | |
404 | DBG_ERROR(et131x_dbginfo, | |
405 | "Could not write PCI config space " | |
406 | "for Replay Timer\n"); | |
407 | DBG_LEAVE(et131x_dbginfo); | |
408 | return -EIO; | |
409 | } | |
410 | } | |
411 | ||
412 | /* l0s and l1 latency timers. We are using default values. | |
413 | * Representing 001 for L0s and 010 for L1 | |
414 | */ | |
415 | result = pci_write_config_byte(pdev, ET1310_PCI_L0L1LATENCY, 0x11); | |
416 | if (result != PCIBIOS_SUCCESSFUL) { | |
417 | DBG_ERROR(et131x_dbginfo, | |
418 | "Could not write PCI config space for " | |
419 | "Latency Timers\n"); | |
420 | DBG_LEAVE(et131x_dbginfo); | |
421 | return -EIO; | |
422 | } | |
423 | ||
424 | /* Change the max read size to 2k */ | |
425 | result = pci_read_config_byte(pdev, 0x51, &read_size_reg); | |
426 | if (result != PCIBIOS_SUCCESSFUL) { | |
427 | DBG_ERROR(et131x_dbginfo, | |
64f93036 | 428 | "Could not read PCI config space for Max read size\n"); |
cfb739b4 GKH |
429 | DBG_LEAVE(et131x_dbginfo); |
430 | return -EIO; | |
431 | } | |
432 | ||
433 | read_size_reg &= 0x8f; | |
434 | read_size_reg |= 0x40; | |
435 | ||
436 | result = pci_write_config_byte(pdev, 0x51, read_size_reg); | |
437 | if (result != PCIBIOS_SUCCESSFUL) { | |
438 | DBG_ERROR(et131x_dbginfo, | |
64f93036 | 439 | "Could not write PCI config space for Max read size\n"); |
cfb739b4 GKH |
440 | DBG_LEAVE(et131x_dbginfo); |
441 | return -EIO; | |
442 | } | |
443 | ||
cfb739b4 GKH |
444 | /* Get MAC address from config space if an eeprom exists, otherwise |
445 | * the MAC address there will not be valid | |
446 | */ | |
9fa81099 | 447 | if (adapter->has_eeprom) { |
cfb739b4 GKH |
448 | int i; |
449 | ||
450 | for (i = 0; i < ETH_ALEN; i++) { | |
451 | result = pci_read_config_byte( | |
452 | pdev, ET1310_PCI_MAC_ADDRESS + i, | |
453 | adapter->PermanentAddress + i); | |
454 | if (result != PCIBIOS_SUCCESSFUL) { | |
455 | DBG_ERROR(et131x_dbginfo, | |
64f93036 | 456 | "Could not read PCI config space for MAC address\n"); |
cfb739b4 GKH |
457 | DBG_LEAVE(et131x_dbginfo); |
458 | return -EIO; | |
459 | } | |
460 | } | |
461 | } | |
462 | ||
463 | DBG_LEAVE(et131x_dbginfo); | |
464 | return 0; | |
465 | } | |
466 | ||
467 | /** | |
468 | * et131x_error_timer_handler | |
469 | * @data: timer-specific variable; here a pointer to our adapter structure | |
470 | * | |
471 | * The routine called when the error timer expires, to track the number of | |
472 | * recurring errors. | |
473 | */ | |
474 | void et131x_error_timer_handler(unsigned long data) | |
475 | { | |
25ad00bb | 476 | struct et131x_adapter *etdev = (struct et131x_adapter *) data; |
f2c98d27 | 477 | u32 pm_csr; |
cfb739b4 | 478 | |
f2c98d27 | 479 | pm_csr = readl(&etdev->regs->global.pm_csr); |
cfb739b4 | 480 | |
f2c98d27 | 481 | if ((pm_csr & ET_PM_PHY_SW_COMA) == 0) |
94831463 AC |
482 | UpdateMacStatHostCounters(etdev); |
483 | else | |
cfb739b4 GKH |
484 | DBG_VERBOSE(et131x_dbginfo, |
485 | "No interrupts, in PHY coma, pm_csr = 0x%x\n", | |
f2c98d27 | 486 | pm_csr); |
cfb739b4 | 487 | |
25ad00bb AC |
488 | if (!etdev->Bmsr.bits.link_status && |
489 | etdev->RegistryPhyComa && | |
490 | etdev->PoMgmt.TransPhyComaModeOnBoot < 11) { | |
491 | etdev->PoMgmt.TransPhyComaModeOnBoot++; | |
cfb739b4 GKH |
492 | } |
493 | ||
25ad00bb AC |
494 | if (etdev->PoMgmt.TransPhyComaModeOnBoot == 10) { |
495 | if (!etdev->Bmsr.bits.link_status | |
496 | && etdev->RegistryPhyComa) { | |
f2c98d27 | 497 | if ((pm_csr & ET_PM_PHY_SW_COMA) == 0) { |
64f93036 AC |
498 | /* NOTE - This was originally a 'sync with |
499 | * interrupt'. How to do that under Linux? | |
500 | */ | |
25ad00bb AC |
501 | et131x_enable_interrupts(etdev); |
502 | EnablePhyComa(etdev); | |
cfb739b4 GKH |
503 | } |
504 | } | |
505 | } | |
506 | ||
507 | /* This is a periodic timer, so reschedule */ | |
25ad00bb | 508 | mod_timer(&etdev->ErrorTimer, jiffies + |
64f93036 | 509 | TX_ERROR_PERIOD * HZ / 1000); |
cfb739b4 GKH |
510 | } |
511 | ||
512 | /** | |
513 | * et131x_link_detection_handler | |
514 | * | |
515 | * Timer function for link up at driver load time | |
516 | */ | |
517 | void et131x_link_detection_handler(unsigned long data) | |
518 | { | |
25ad00bb | 519 | struct et131x_adapter *etdev = (struct et131x_adapter *) data; |
37628606 | 520 | unsigned long flags; |
cfb739b4 | 521 | |
25ad00bb | 522 | if (etdev->MediaState == 0) { |
37628606 | 523 | spin_lock_irqsave(&etdev->Lock, flags); |
cfb739b4 | 524 | |
25ad00bb AC |
525 | etdev->MediaState = NETIF_STATUS_MEDIA_DISCONNECT; |
526 | MP_CLEAR_FLAG(etdev, fMP_ADAPTER_LINK_DETECTION); | |
cfb739b4 | 527 | |
37628606 | 528 | spin_unlock_irqrestore(&etdev->Lock, flags); |
cfb739b4 | 529 | |
25ad00bb | 530 | netif_carrier_off(etdev->netdev); |
cfb739b4 GKH |
531 | } |
532 | } | |
533 | ||
534 | /** | |
535 | * et131x_adapter_setup - Set the adapter up as per cassini+ documentation | |
536 | * @adapter: pointer to our private adapter structure | |
537 | * | |
538 | * Returns 0 on success, errno on failure (as defined in errno.h) | |
539 | */ | |
25ad00bb | 540 | int et131x_adapter_setup(struct et131x_adapter *etdev) |
cfb739b4 GKH |
541 | { |
542 | int status = 0; | |
543 | ||
544 | DBG_ENTER(et131x_dbginfo); | |
545 | ||
546 | /* Configure the JAGCore */ | |
25ad00bb | 547 | ConfigGlobalRegs(etdev); |
cfb739b4 | 548 | |
25ad00bb AC |
549 | ConfigMACRegs1(etdev); |
550 | ConfigMMCRegs(etdev); | |
cfb739b4 | 551 | |
25ad00bb AC |
552 | ConfigRxMacRegs(etdev); |
553 | ConfigTxMacRegs(etdev); | |
cfb739b4 | 554 | |
25ad00bb AC |
555 | ConfigRxDmaRegs(etdev); |
556 | ConfigTxDmaRegs(etdev); | |
cfb739b4 | 557 | |
25ad00bb | 558 | ConfigMacStatRegs(etdev); |
cfb739b4 GKH |
559 | |
560 | /* Move the following code to Timer function?? */ | |
25ad00bb | 561 | status = et131x_xcvr_find(etdev); |
cfb739b4 | 562 | |
64f93036 | 563 | if (status != 0) |
cfb739b4 | 564 | DBG_WARNING(et131x_dbginfo, "Could not find the xcvr\n"); |
cfb739b4 GKH |
565 | |
566 | /* Prepare the TRUEPHY library. */ | |
25ad00bb | 567 | ET1310_PhyInit(etdev); |
cfb739b4 GKH |
568 | |
569 | /* Reset the phy now so changes take place */ | |
25ad00bb | 570 | ET1310_PhyReset(etdev); |
cfb739b4 GKH |
571 | |
572 | /* Power down PHY */ | |
25ad00bb | 573 | ET1310_PhyPowerDown(etdev, 1); |
cfb739b4 GKH |
574 | |
575 | /* | |
576 | * We need to turn off 1000 base half dulplex, the mac does not | |
577 | * support it. For the 10/100 part, turn off all gig advertisement | |
578 | */ | |
5ec3487a | 579 | if (etdev->pdev->device != ET131X_PCI_DEVICE_ID_FAST) |
25ad00bb | 580 | ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL); |
64f93036 | 581 | else |
25ad00bb | 582 | ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); |
cfb739b4 GKH |
583 | |
584 | /* Power up PHY */ | |
25ad00bb | 585 | ET1310_PhyPowerDown(etdev, 0); |
cfb739b4 | 586 | |
25ad00bb | 587 | et131x_setphy_normal(etdev); |
cfb739b4 GKH |
588 | |
589 | DBG_LEAVE(et131x_dbginfo); | |
590 | return status; | |
591 | } | |
592 | ||
593 | /** | |
594 | * et131x_setup_hardware_properties - set up the MAC Address on the ET1310 | |
595 | * @adapter: pointer to our private adapter structure | |
596 | */ | |
597 | void et131x_setup_hardware_properties(struct et131x_adapter *adapter) | |
598 | { | |
599 | DBG_ENTER(et131x_dbginfo); | |
600 | ||
601 | /* If have our default mac from registry and no mac address from | |
602 | * EEPROM then we need to generate the last octet and set it on the | |
603 | * device | |
604 | */ | |
9fa81099 AC |
605 | if (adapter->PermanentAddress[0] == 0x00 && |
606 | adapter->PermanentAddress[1] == 0x00 && | |
607 | adapter->PermanentAddress[2] == 0x00 && | |
608 | adapter->PermanentAddress[3] == 0x00 && | |
609 | adapter->PermanentAddress[4] == 0x00 && | |
610 | adapter->PermanentAddress[5] == 0x00) { | |
611 | /* | |
612 | * We need to randomly generate the last octet so we | |
613 | * decrease our chances of setting the mac address to | |
614 | * same as another one of our cards in the system | |
615 | */ | |
616 | get_random_bytes(&adapter->CurrentAddress[5], 1); | |
617 | /* | |
618 | * We have the default value in the register we are | |
619 | * working with so we need to copy the current | |
620 | * address into the permanent address | |
621 | */ | |
622 | memcpy(adapter->PermanentAddress, | |
623 | adapter->CurrentAddress, ETH_ALEN); | |
624 | } else { | |
625 | /* We do not have an override address, so set the | |
626 | * current address to the permanent address and add | |
627 | * it to the device | |
628 | */ | |
629 | memcpy(adapter->CurrentAddress, | |
630 | adapter->PermanentAddress, ETH_ALEN); | |
cfb739b4 GKH |
631 | } |
632 | ||
633 | DBG_LEAVE(et131x_dbginfo); | |
634 | } | |
635 | ||
636 | /** | |
637 | * et131x_soft_reset - Issue a soft reset to the hardware, complete for ET1310 | |
638 | * @adapter: pointer to our private adapter structure | |
639 | */ | |
640 | void et131x_soft_reset(struct et131x_adapter *adapter) | |
641 | { | |
642 | DBG_ENTER(et131x_dbginfo); | |
643 | ||
644 | /* Disable MAC Core */ | |
f3f415a3 | 645 | writel(0xc00f0000, &adapter->regs->mac.cfg1.value); |
cfb739b4 GKH |
646 | |
647 | /* Set everything to a reset value */ | |
f3f415a3 AC |
648 | writel(0x7F, &adapter->regs->global.sw_reset.value); |
649 | writel(0x000f0000, &adapter->regs->mac.cfg1.value); | |
650 | writel(0x00000000, &adapter->regs->mac.cfg1.value); | |
cfb739b4 GKH |
651 | |
652 | DBG_LEAVE(et131x_dbginfo); | |
653 | } | |
654 | ||
655 | /** | |
656 | * et131x_align_allocated_memory - Align allocated memory on a given boundary | |
657 | * @adapter: pointer to our adapter structure | |
658 | * @phys_addr: pointer to Physical address | |
659 | * @offset: pointer to the offset variable | |
660 | * @mask: correct mask | |
661 | */ | |
662 | void et131x_align_allocated_memory(struct et131x_adapter *adapter, | |
663 | uint64_t *phys_addr, | |
664 | uint64_t *offset, uint64_t mask) | |
665 | { | |
666 | uint64_t new_addr; | |
667 | ||
668 | DBG_ENTER(et131x_dbginfo); | |
669 | ||
670 | *offset = 0; | |
671 | ||
672 | new_addr = *phys_addr & ~mask; | |
673 | ||
674 | if (new_addr != *phys_addr) { | |
675 | /* Move to next aligned block */ | |
676 | new_addr += mask + 1; | |
677 | /* Return offset for adjusting virt addr */ | |
678 | *offset = new_addr - *phys_addr; | |
679 | /* Return new physical address */ | |
680 | *phys_addr = new_addr; | |
681 | } | |
682 | ||
683 | DBG_LEAVE(et131x_dbginfo); | |
684 | } | |
685 | ||
686 | /** | |
687 | * et131x_adapter_memory_alloc | |
688 | * @adapter: pointer to our private adapter structure | |
689 | * | |
690 | * Returns 0 on success, errno on failure (as defined in errno.h). | |
691 | * | |
692 | * Allocate all the memory blocks for send, receive and others. | |
693 | */ | |
694 | int et131x_adapter_memory_alloc(struct et131x_adapter *adapter) | |
695 | { | |
696 | int status = 0; | |
697 | ||
698 | DBG_ENTER(et131x_dbginfo); | |
699 | ||
700 | do { | |
701 | /* Allocate memory for the Tx Ring */ | |
702 | status = et131x_tx_dma_memory_alloc(adapter); | |
703 | if (status != 0) { | |
704 | DBG_ERROR(et131x_dbginfo, | |
705 | "et131x_tx_dma_memory_alloc FAILED\n"); | |
706 | break; | |
707 | } | |
708 | ||
709 | /* Receive buffer memory allocation */ | |
710 | status = et131x_rx_dma_memory_alloc(adapter); | |
711 | if (status != 0) { | |
712 | DBG_ERROR(et131x_dbginfo, | |
713 | "et131x_rx_dma_memory_alloc FAILED\n"); | |
714 | et131x_tx_dma_memory_free(adapter); | |
715 | break; | |
716 | } | |
717 | ||
718 | /* Init receive data structures */ | |
719 | status = et131x_init_recv(adapter); | |
720 | if (status != 0) { | |
721 | DBG_ERROR(et131x_dbginfo, "et131x_init_recv FAILED\n"); | |
722 | et131x_tx_dma_memory_free(adapter); | |
723 | et131x_rx_dma_memory_free(adapter); | |
724 | break; | |
725 | } | |
726 | } while (0); | |
727 | ||
728 | DBG_LEAVE(et131x_dbginfo); | |
729 | return status; | |
730 | } | |
731 | ||
732 | /** | |
733 | * et131x_adapter_memory_free - Free all memory allocated for use by Tx & Rx | |
734 | * @adapter: pointer to our private adapter structure | |
735 | */ | |
736 | void et131x_adapter_memory_free(struct et131x_adapter *adapter) | |
737 | { | |
738 | DBG_ENTER(et131x_dbginfo); | |
739 | ||
740 | /* Free DMA memory */ | |
741 | et131x_tx_dma_memory_free(adapter); | |
742 | et131x_rx_dma_memory_free(adapter); | |
743 | ||
744 | DBG_LEAVE(et131x_dbginfo); | |
745 | } | |
746 | ||
747 | /** | |
748 | * et131x_pci_remove | |
749 | * @pdev: a pointer to the device's pci_dev structure | |
750 | * | |
751 | * Registered in the pci_driver structure, this function is called when the | |
752 | * PCI subsystem detects that a PCI device which matches the information | |
753 | * contained in the pci_device_id table has been removed. | |
754 | */ | |
755 | void __devexit et131x_pci_remove(struct pci_dev *pdev) | |
756 | { | |
757 | struct net_device *netdev; | |
758 | struct et131x_adapter *adapter; | |
759 | ||
760 | DBG_ENTER(et131x_dbginfo); | |
761 | ||
762 | /* Retrieve the net_device pointer from the pci_dev struct, as well | |
763 | * as the private adapter struct | |
764 | */ | |
765 | netdev = (struct net_device *) pci_get_drvdata(pdev); | |
766 | adapter = netdev_priv(netdev); | |
767 | ||
768 | /* Perform device cleanup */ | |
769 | unregister_netdev(netdev); | |
770 | et131x_adapter_memory_free(adapter); | |
f3f415a3 | 771 | iounmap(adapter->regs); |
6ae56042 | 772 | pci_dev_put(adapter->pdev); |
cfb739b4 GKH |
773 | free_netdev(netdev); |
774 | pci_release_regions(pdev); | |
775 | pci_disable_device(pdev); | |
776 | ||
777 | DBG_LEAVE(et131x_dbginfo); | |
778 | } | |
779 | ||
8c5f20f3 AC |
780 | /** |
781 | * et131x_config_parse | |
782 | * @etdev: pointer to the private adapter struct | |
783 | * | |
784 | * Parses a configuration from some location (module parameters, for example) | |
785 | * into the private adapter struct. This really has no sensible analogy in | |
786 | * Linux as sysfs parameters are dynamic. Several things that were hee could | |
787 | * go into sysfs, but other stuff like speed handling is part of the mii | |
788 | * interfaces/ethtool. | |
789 | */ | |
790 | void et131x_config_parse(struct et131x_adapter *etdev) | |
791 | { | |
792 | static const u8 default_mac[] = { 0x00, 0x05, 0x3d, 0x00, 0x02, 0x00 }; | |
793 | static const u8 duplex[] = { 0, 1, 2, 1, 2, 2 }; | |
794 | static const u16 speed[] = { 0, 10, 10, 100, 100, 1000 }; | |
795 | ||
796 | DBG_ENTER(et131x_dbginfo); | |
797 | ||
798 | if (et131x_speed_set) | |
799 | DBG_VERBOSE(et131x_dbginfo, "Speed set manually to : %d \n", | |
800 | et131x_speed_set); | |
801 | ||
802 | etdev->SpeedDuplex = et131x_speed_set; | |
803 | etdev->RegistryJumboPacket = 1514; /* 1514-9216 */ | |
804 | ||
805 | etdev->RegistryNMIDisable = et131x_nmi_disable; | |
806 | ||
807 | /* Set the MAC address to a default */ | |
808 | memcpy(etdev->CurrentAddress, default_mac, ETH_ALEN); | |
809 | ||
810 | /* Decode SpeedDuplex | |
811 | * | |
812 | * Set up as if we are auto negotiating always and then change if we | |
813 | * go into force mode | |
814 | * | |
815 | * If we are the 10/100 device, and gigabit is somehow requested then | |
816 | * knock it down to 100 full. | |
817 | */ | |
818 | if (etdev->pdev->device == ET131X_PCI_DEVICE_ID_FAST && | |
819 | etdev->SpeedDuplex == 5) | |
820 | etdev->SpeedDuplex = 4; | |
821 | ||
822 | etdev->AiForceSpeed = speed[etdev->SpeedDuplex]; | |
823 | etdev->AiForceDpx = duplex[etdev->SpeedDuplex]; /* Auto FDX */ | |
824 | ||
825 | DBG_LEAVE(et131x_dbginfo); | |
826 | } | |
827 | ||
828 | ||
cfb739b4 GKH |
829 | /** |
830 | * et131x_pci_setup - Perform device initialization | |
831 | * @pdev: a pointer to the device's pci_dev structure | |
832 | * @ent: this device's entry in the pci_device_id table | |
833 | * | |
834 | * Returns 0 on success, errno on failure (as defined in errno.h) | |
835 | * | |
836 | * Registered in the pci_driver structure, this function is called when the | |
837 | * PCI subsystem finds a new PCI device which matches the information | |
838 | * contained in the pci_device_id table. This routine is the equivalent to | |
839 | * a device insertion routine. | |
840 | */ | |
841 | int __devinit et131x_pci_setup(struct pci_dev *pdev, | |
842 | const struct pci_device_id *ent) | |
843 | { | |
844 | int result = 0; | |
845 | int pm_cap; | |
846 | bool pci_using_dac; | |
847 | struct net_device *netdev = NULL; | |
848 | struct et131x_adapter *adapter = NULL; | |
849 | ||
850 | DBG_ENTER(et131x_dbginfo); | |
851 | ||
852 | /* Enable the device via the PCI subsystem */ | |
853 | result = pci_enable_device(pdev); | |
854 | if (result != 0) { | |
855 | DBG_ERROR(et131x_dbginfo, "pci_enable_device() failed\n"); | |
856 | goto out; | |
857 | } | |
858 | ||
859 | /* Perform some basic PCI checks */ | |
860 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { | |
861 | DBG_ERROR(et131x_dbginfo, | |
862 | "Can't find PCI device's base address\n"); | |
863 | result = -ENODEV; | |
864 | goto out; | |
865 | } | |
866 | ||
867 | result = pci_request_regions(pdev, DRIVER_NAME); | |
868 | if (result != 0) { | |
869 | DBG_ERROR(et131x_dbginfo, "Can't get PCI resources\n"); | |
870 | goto err_disable; | |
871 | } | |
872 | ||
873 | /* Enable PCI bus mastering */ | |
874 | DBG_TRACE(et131x_dbginfo, "Setting PCI Bus Mastering...\n"); | |
875 | pci_set_master(pdev); | |
876 | ||
877 | /* Query PCI for Power Mgmt Capabilities | |
878 | * | |
879 | * NOTE: Now reading PowerMgmt in another location; is this still | |
880 | * needed? | |
881 | */ | |
882 | pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); | |
883 | if (pm_cap == 0) { | |
884 | DBG_ERROR(et131x_dbginfo, | |
885 | "Cannot find Power Management capabilities\n"); | |
886 | result = -EIO; | |
887 | goto err_release_res; | |
888 | } | |
889 | ||
890 | /* Check the DMA addressing support of this device */ | |
891 | if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) { | |
892 | DBG_TRACE(et131x_dbginfo, "64-bit DMA addressing supported\n"); | |
893 | pci_using_dac = true; | |
894 | ||
895 | result = | |
896 | pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL); | |
897 | if (result != 0) { | |
898 | DBG_ERROR(et131x_dbginfo, | |
899 | "Unable to obtain 64 bit DMA for consistent allocations\n"); | |
900 | goto err_release_res; | |
901 | } | |
902 | } else if (!pci_set_dma_mask(pdev, 0xffffffffULL)) { | |
903 | DBG_TRACE(et131x_dbginfo, | |
904 | "64-bit DMA addressing NOT supported\n"); | |
905 | DBG_TRACE(et131x_dbginfo, | |
906 | "32-bit DMA addressing will be used\n"); | |
907 | pci_using_dac = false; | |
908 | } else { | |
909 | DBG_ERROR(et131x_dbginfo, "No usable DMA addressing method\n"); | |
910 | result = -EIO; | |
911 | goto err_release_res; | |
912 | } | |
913 | ||
914 | /* Allocate netdev and private adapter structs */ | |
915 | DBG_TRACE(et131x_dbginfo, | |
916 | "Allocate netdev and private adapter structs...\n"); | |
917 | netdev = et131x_device_alloc(); | |
918 | if (netdev == NULL) { | |
919 | DBG_ERROR(et131x_dbginfo, "Couldn't alloc netdev struct\n"); | |
920 | result = -ENOMEM; | |
921 | goto err_release_res; | |
922 | } | |
923 | ||
924 | /* Setup the fundamental net_device and private adapter structure elements */ | |
925 | DBG_TRACE(et131x_dbginfo, "Setting fundamental net_device info...\n"); | |
926 | SET_NETDEV_DEV(netdev, &pdev->dev); | |
64f93036 | 927 | /* |
cfb739b4 | 928 | if (pci_using_dac) { |
64f93036 | 929 | netdev->features |= NETIF_F_HIGHDMA; |
cfb739b4 | 930 | } |
64f93036 | 931 | */ |
cfb739b4 GKH |
932 | |
933 | /* | |
934 | * NOTE - Turn this on when we're ready to deal with SG-DMA | |
935 | * | |
936 | * NOTE: According to "Linux Device Drivers", 3rd ed, Rubini et al, | |
937 | * if checksumming is not performed in HW, then the kernel will not | |
938 | * use SG. | |
939 | * From pp 510-511: | |
940 | * | |
941 | * "Note that the kernel does not perform scatter/gather I/O to your | |
942 | * device if it does not also provide some form of checksumming as | |
943 | * well. The reason is that, if the kernel has to make a pass over a | |
944 | * fragmented ("nonlinear") packet to calculate the checksum, it | |
945 | * might as well copy the data and coalesce the packet at the same | |
946 | * time." | |
947 | * | |
948 | * This has been verified by setting the flags below and still not | |
949 | * receiving a scattered buffer from the network stack, so leave it | |
950 | * off until checksums are calculated in HW. | |
951 | */ | |
64f93036 AC |
952 | /* netdev->features |= NETIF_F_SG; */ |
953 | /* netdev->features |= NETIF_F_NO_CSUM; */ | |
954 | /* netdev->features |= NETIF_F_LLTX; */ | |
cfb739b4 GKH |
955 | |
956 | /* Allocate private adapter struct and copy in relevant information */ | |
957 | adapter = netdev_priv(netdev); | |
6ae56042 | 958 | adapter->pdev = pci_dev_get(pdev); |
cfb739b4 | 959 | adapter->netdev = netdev; |
cfb739b4 GKH |
960 | |
961 | /* Do the same for the netdev struct */ | |
962 | netdev->irq = pdev->irq; | |
963 | netdev->base_addr = pdev->resource[0].start; | |
964 | ||
965 | /* Initialize spinlocks here */ | |
966 | DBG_TRACE(et131x_dbginfo, "Initialize spinlocks...\n"); | |
967 | ||
968 | spin_lock_init(&adapter->Lock); | |
969 | spin_lock_init(&adapter->TCBSendQLock); | |
970 | spin_lock_init(&adapter->TCBReadyQLock); | |
971 | spin_lock_init(&adapter->SendHWLock); | |
972 | spin_lock_init(&adapter->SendWaitLock); | |
973 | spin_lock_init(&adapter->RcvLock); | |
974 | spin_lock_init(&adapter->RcvPendLock); | |
975 | spin_lock_init(&adapter->FbrLock); | |
976 | spin_lock_init(&adapter->PHYLock); | |
977 | ||
978 | /* Parse configuration parameters into the private adapter struct */ | |
979 | et131x_config_parse(adapter); | |
980 | ||
981 | /* Find the physical adapter | |
982 | * | |
983 | * NOTE: This is the equivalent of the MpFindAdapter() routine; can we | |
984 | * lump it's init with the device specific init below into a | |
985 | * single init function? | |
986 | */ | |
64f93036 | 987 | /* while (et131x_find_adapter(adapter, pdev) != 0); */ |
cfb739b4 GKH |
988 | et131x_find_adapter(adapter, pdev); |
989 | ||
990 | /* Map the bus-relative registers to system virtual memory */ | |
991 | DBG_TRACE(et131x_dbginfo, | |
992 | "Mapping bus-relative registers to virtual memory...\n"); | |
993 | ||
f3f415a3 | 994 | adapter->regs = ioremap_nocache(pci_resource_start(pdev, 0), |
cfb739b4 | 995 | pci_resource_len(pdev, 0)); |
f3f415a3 | 996 | if (adapter->regs == NULL) { |
cfb739b4 GKH |
997 | DBG_ERROR(et131x_dbginfo, "Cannot map device registers\n"); |
998 | result = -ENOMEM; | |
999 | goto err_free_dev; | |
1000 | } | |
1001 | ||
1002 | /* Perform device-specific initialization here (See code below) */ | |
1003 | ||
1004 | /* If Phy COMA mode was enabled when we went down, disable it here. */ | |
f2c98d27 | 1005 | writel(ET_PMCSR_INIT, &adapter->regs->global.pm_csr); |
cfb739b4 GKH |
1006 | |
1007 | /* Issue a global reset to the et1310 */ | |
1008 | DBG_TRACE(et131x_dbginfo, "Issuing soft reset...\n"); | |
1009 | et131x_soft_reset(adapter); | |
1010 | ||
1011 | /* Disable all interrupts (paranoid) */ | |
1012 | DBG_TRACE(et131x_dbginfo, "Disable device interrupts...\n"); | |
1013 | et131x_disable_interrupts(adapter); | |
1014 | ||
1015 | /* Allocate DMA memory */ | |
1016 | result = et131x_adapter_memory_alloc(adapter); | |
1017 | if (result != 0) { | |
1018 | DBG_ERROR(et131x_dbginfo, | |
1019 | "Could not alloc adapater memory (DMA)\n"); | |
1020 | goto err_iounmap; | |
1021 | } | |
1022 | ||
1023 | /* Init send data structures */ | |
1024 | DBG_TRACE(et131x_dbginfo, "Init send data structures...\n"); | |
1025 | et131x_init_send(adapter); | |
1026 | ||
cfb739b4 GKH |
1027 | /* Register the interrupt |
1028 | * | |
1029 | * NOTE - This is being done in the open routine, where most other | |
1030 | * Linux drivers setup IRQ handlers. Make sure device | |
1031 | * interrupts are not turned on before the IRQ is registered!! | |
1032 | * | |
1033 | * What we will do here is setup the task structure for the | |
1034 | * ISR's deferred handler | |
1035 | */ | |
1036 | INIT_WORK(&adapter->task, et131x_isr_handler); | |
1037 | ||
1038 | /* Determine MAC Address, and copy into the net_device struct */ | |
1039 | DBG_TRACE(et131x_dbginfo, "Retrieve MAC address...\n"); | |
1040 | et131x_setup_hardware_properties(adapter); | |
1041 | ||
1042 | memcpy(netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN); | |
1043 | ||
1044 | /* Setup et1310 as per the documentation */ | |
1045 | DBG_TRACE(et131x_dbginfo, "Setup the adapter...\n"); | |
1046 | et131x_adapter_setup(adapter); | |
1047 | ||
1048 | /* Create a timer to count errors received by the NIC */ | |
1049 | init_timer(&adapter->ErrorTimer); | |
1050 | ||
1051 | adapter->ErrorTimer.expires = jiffies + TX_ERROR_PERIOD * HZ / 1000; | |
1052 | adapter->ErrorTimer.function = et131x_error_timer_handler; | |
1053 | adapter->ErrorTimer.data = (unsigned long)adapter; | |
1054 | ||
1055 | /* Initialize link state */ | |
1056 | et131x_link_detection_handler((unsigned long)adapter); | |
1057 | ||
64f93036 AC |
1058 | /* Intialize variable for counting how long we do not have |
1059 | link status */ | |
cfb739b4 GKH |
1060 | adapter->PoMgmt.TransPhyComaModeOnBoot = 0; |
1061 | ||
1062 | /* We can enable interrupts now | |
1063 | * | |
1064 | * NOTE - Because registration of interrupt handler is done in the | |
1065 | * device's open(), defer enabling device interrupts to that | |
1066 | * point | |
1067 | */ | |
1068 | ||
1069 | /* Register the net_device struct with the Linux network layer */ | |
1070 | DBG_TRACE(et131x_dbginfo, "Registering net_device...\n"); | |
64f93036 AC |
1071 | result = register_netdev(netdev); |
1072 | if (result != 0) { | |
cfb739b4 GKH |
1073 | DBG_ERROR(et131x_dbginfo, "register_netdev() failed\n"); |
1074 | goto err_mem_free; | |
1075 | } | |
1076 | ||
1077 | /* Register the net_device struct with the PCI subsystem. Save a copy | |
1078 | * of the PCI config space for this device now that the device has | |
1079 | * been initialized, just in case it needs to be quickly restored. | |
1080 | */ | |
1081 | pci_set_drvdata(pdev, netdev); | |
1082 | ||
1083 | pci_save_state(adapter->pdev); | |
1084 | ||
1085 | out: | |
1086 | DBG_LEAVE(et131x_dbginfo); | |
1087 | return result; | |
1088 | ||
1089 | err_mem_free: | |
1090 | et131x_adapter_memory_free(adapter); | |
1091 | err_iounmap: | |
f3f415a3 | 1092 | iounmap(adapter->regs); |
cfb739b4 | 1093 | err_free_dev: |
6ae56042 | 1094 | pci_dev_put(pdev); |
cfb739b4 GKH |
1095 | free_netdev(netdev); |
1096 | err_release_res: | |
1097 | pci_release_regions(pdev); | |
1098 | err_disable: | |
1099 | pci_disable_device(pdev); | |
1100 | goto out; | |
1101 | } |