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 | ||
143 | static struct pci_device_id et131x_pci_table[] __devinitdata = { | |
144 | {ET131X_PCI_VENDOR_ID, ET131X_PCI_DEVICE_ID_GIG, PCI_ANY_ID, | |
145 | PCI_ANY_ID, 0, 0, 0UL}, | |
146 | {ET131X_PCI_VENDOR_ID, ET131X_PCI_DEVICE_ID_FAST, PCI_ANY_ID, | |
147 | PCI_ANY_ID, 0, 0, 0UL}, | |
148 | {0,} | |
149 | }; | |
150 | ||
151 | MODULE_DEVICE_TABLE(pci, et131x_pci_table); | |
152 | ||
153 | static struct pci_driver et131x_driver = { | |
154 | .name = DRIVER_NAME, | |
155 | .id_table = et131x_pci_table, | |
156 | .probe = et131x_pci_setup, | |
157 | .remove = __devexit_p(et131x_pci_remove), | |
64f93036 AC |
158 | .suspend = NULL, /* et131x_pci_suspend */ |
159 | .resume = NULL, /* et131x_pci_resume */ | |
cfb739b4 GKH |
160 | }; |
161 | ||
162 | ||
163 | /** | |
164 | * et131x_init_module - The "main" entry point called on driver initialization | |
165 | * | |
166 | * Returns 0 on success, errno on failure (as defined in errno.h) | |
167 | */ | |
168 | int et131x_init_module(void) | |
169 | { | |
170 | int result; | |
171 | ||
172 | #ifdef CONFIG_ET131X_DEBUG | |
173 | /* Set the level of debug messages displayed using the module | |
174 | * parameter | |
175 | */ | |
176 | et131x_dbginfo->dbgFlags = et131x_debug_flags; | |
177 | ||
178 | switch (et131x_debug_level) { | |
179 | case 7: | |
180 | et131x_dbginfo->dbgFlags |= (DBG_RX_ON | DBG_TX_ON); | |
181 | ||
182 | case 6: | |
183 | et131x_dbginfo->dbgFlags |= DBG_PARAM_ON; | |
184 | ||
185 | case 5: | |
186 | et131x_dbginfo->dbgFlags |= DBG_VERBOSE_ON; | |
187 | ||
188 | case 4: | |
189 | et131x_dbginfo->dbgFlags |= DBG_TRACE_ON; | |
190 | ||
191 | case 3: | |
192 | et131x_dbginfo->dbgFlags |= DBG_NOTICE_ON; | |
193 | ||
194 | case 2: | |
195 | case 1: | |
196 | case 0: | |
197 | default: | |
198 | break; | |
199 | } | |
200 | #endif /* CONFIG_ET131X_DEBUG */ | |
201 | ||
202 | DBG_ENTER(et131x_dbginfo); | |
203 | DBG_PRINT("%s\n", DRIVER_INFO); | |
204 | ||
205 | result = pci_register_driver(&et131x_driver); | |
206 | ||
207 | DBG_LEAVE(et131x_dbginfo); | |
208 | return result; | |
209 | } | |
210 | ||
211 | /** | |
212 | * et131x_cleanup_module - The entry point called on driver cleanup | |
213 | */ | |
214 | void et131x_cleanup_module(void) | |
215 | { | |
216 | DBG_ENTER(et131x_dbginfo); | |
217 | ||
218 | pci_unregister_driver(&et131x_driver); | |
219 | ||
220 | DBG_LEAVE(et131x_dbginfo); | |
221 | } | |
222 | ||
223 | /* | |
224 | * These macros map the driver-specific init_module() and cleanup_module() | |
225 | * routines so they can be called by the kernel. | |
226 | */ | |
227 | module_init(et131x_init_module); | |
228 | module_exit(et131x_cleanup_module); | |
229 | ||
230 | ||
231 | /** | |
232 | * et131x_find_adapter - Find the adapter and get all the assigned resources | |
233 | * @adapter: pointer to our private adapter structure | |
234 | * | |
235 | * Returns 0 on success, errno on failure (as defined in errno.h) | |
236 | */ | |
237 | int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev) | |
238 | { | |
239 | int result; | |
240 | uint8_t eepromStat; | |
241 | uint8_t maxPayload = 0; | |
242 | uint8_t read_size_reg; | |
5ec3487a | 243 | u8 rev; |
cfb739b4 GKH |
244 | |
245 | DBG_ENTER(et131x_dbginfo); | |
246 | ||
247 | /* Allow disabling of Non-Maskable Interrupts in I/O space, to | |
248 | * support validation. | |
249 | */ | |
250 | if (adapter->RegistryNMIDisable) { | |
251 | uint8_t RegisterVal; | |
252 | ||
253 | RegisterVal = inb(ET1310_NMI_DISABLE); | |
254 | RegisterVal &= 0xf3; | |
255 | ||
64f93036 | 256 | if (adapter->RegistryNMIDisable == 2) |
cfb739b4 | 257 | RegisterVal |= 0xc; |
cfb739b4 GKH |
258 | |
259 | outb(ET1310_NMI_DISABLE, RegisterVal); | |
260 | } | |
261 | ||
262 | /* We first need to check the EEPROM Status code located at offset | |
263 | * 0xB2 of config space | |
264 | */ | |
265 | result = pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS, | |
266 | &eepromStat); | |
267 | ||
268 | /* THIS IS A WORKAROUND: | |
64f93036 | 269 | * I need to call this function twice to get my card in a |
cfb739b4 GKH |
270 | * LG M1 Express Dual running. I tried also a msleep before this |
271 | * function, because I thougth there could be some time condidions | |
272 | * but it didn't work. Call the whole function twice also work. | |
273 | */ | |
274 | result = pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS, | |
275 | &eepromStat); | |
276 | if (result != PCIBIOS_SUCCESSFUL) { | |
277 | DBG_ERROR(et131x_dbginfo, "Could not read PCI config space for " | |
278 | "EEPROM Status\n"); | |
279 | DBG_LEAVE(et131x_dbginfo); | |
280 | return -EIO; | |
281 | } | |
282 | ||
283 | /* Determine if the error(s) we care about are present. If they are | |
284 | * present, we need to fail. | |
285 | */ | |
286 | if (eepromStat & 0x4C) { | |
5ec3487a | 287 | result = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); |
cfb739b4 GKH |
288 | if (result != PCIBIOS_SUCCESSFUL) { |
289 | DBG_ERROR(et131x_dbginfo, | |
290 | "Could not read PCI config space for " | |
291 | "Revision ID\n"); | |
292 | DBG_LEAVE(et131x_dbginfo); | |
293 | return -EIO; | |
5ec3487a | 294 | } else if (rev == 0x01) { |
cfb739b4 GKH |
295 | int32_t nLoop; |
296 | uint8_t ucTemp[4] = { 0xFE, 0x13, 0x10, 0xFF }; | |
297 | ||
298 | /* Re-write the first 4 bytes if we have an eeprom | |
299 | * present and the revision id is 1, this fixes the | |
300 | * corruption seen with 1310 B Silicon | |
301 | */ | |
302 | for (nLoop = 0; nLoop < 3; nLoop++) { | |
303 | EepromWriteByte(adapter, nLoop, ucTemp[nLoop], | |
304 | 0, SINGLE_BYTE); | |
305 | } | |
306 | } | |
307 | ||
308 | DBG_ERROR(et131x_dbginfo, | |
309 | "Fatal EEPROM Status Error - 0x%04x\n", eepromStat); | |
310 | ||
311 | /* This error could mean that there was an error reading the | |
312 | * eeprom or that the eeprom doesn't exist. We will treat | |
313 | * each case the same and not try to gather additional | |
314 | * information that normally would come from the eeprom, like | |
315 | * MAC Address | |
316 | */ | |
317 | adapter->bEepromPresent = false; | |
318 | ||
319 | DBG_LEAVE(et131x_dbginfo); | |
320 | return -EIO; | |
321 | } else { | |
322 | DBG_TRACE(et131x_dbginfo, "EEPROM Status Code - 0x%04x\n", | |
323 | eepromStat); | |
324 | adapter->bEepromPresent = true; | |
325 | } | |
326 | ||
327 | /* Read the EEPROM for information regarding LED behavior. Refer to | |
328 | * ET1310_phy.c, et131x_xcvr_init(), for its use. | |
329 | */ | |
330 | EepromReadByte(adapter, 0x70, &adapter->eepromData[0], 0, SINGLE_BYTE); | |
331 | EepromReadByte(adapter, 0x71, &adapter->eepromData[1], 0, SINGLE_BYTE); | |
332 | ||
64f93036 AC |
333 | if (adapter->eepromData[0] != 0xcd) |
334 | /* Disable all optional features */ | |
335 | adapter->eepromData[1] = 0x00; | |
cfb739b4 GKH |
336 | |
337 | /* Let's set up the PORT LOGIC Register. First we need to know what | |
338 | * the max_payload_size is | |
339 | */ | |
340 | result = pci_read_config_byte(pdev, ET1310_PCI_MAX_PYLD, &maxPayload); | |
341 | if (result != PCIBIOS_SUCCESSFUL) { | |
342 | DBG_ERROR(et131x_dbginfo, "Could not read PCI config space for " | |
343 | "Max Payload Size\n"); | |
344 | DBG_LEAVE(et131x_dbginfo); | |
345 | return -EIO; | |
346 | } | |
347 | ||
348 | /* Program the Ack/Nak latency and replay timers */ | |
64f93036 | 349 | maxPayload &= 0x07; /* Only the lower 3 bits are valid */ |
cfb739b4 GKH |
350 | |
351 | if (maxPayload < 2) { | |
352 | const uint16_t AckNak[2] = { 0x76, 0xD0 }; | |
353 | const uint16_t Replay[2] = { 0x1E0, 0x2ED }; | |
354 | ||
355 | result = pci_write_config_word(pdev, ET1310_PCI_ACK_NACK, | |
356 | AckNak[maxPayload]); | |
357 | if (result != PCIBIOS_SUCCESSFUL) { | |
358 | DBG_ERROR(et131x_dbginfo, | |
359 | "Could not write PCI config space " | |
360 | "for ACK/NAK\n"); | |
361 | DBG_LEAVE(et131x_dbginfo); | |
362 | return -EIO; | |
363 | } | |
364 | ||
365 | result = pci_write_config_word(pdev, ET1310_PCI_REPLAY, | |
366 | Replay[maxPayload]); | |
367 | if (result != PCIBIOS_SUCCESSFUL) { | |
368 | DBG_ERROR(et131x_dbginfo, | |
369 | "Could not write PCI config space " | |
370 | "for Replay Timer\n"); | |
371 | DBG_LEAVE(et131x_dbginfo); | |
372 | return -EIO; | |
373 | } | |
374 | } | |
375 | ||
376 | /* l0s and l1 latency timers. We are using default values. | |
377 | * Representing 001 for L0s and 010 for L1 | |
378 | */ | |
379 | result = pci_write_config_byte(pdev, ET1310_PCI_L0L1LATENCY, 0x11); | |
380 | if (result != PCIBIOS_SUCCESSFUL) { | |
381 | DBG_ERROR(et131x_dbginfo, | |
382 | "Could not write PCI config space for " | |
383 | "Latency Timers\n"); | |
384 | DBG_LEAVE(et131x_dbginfo); | |
385 | return -EIO; | |
386 | } | |
387 | ||
388 | /* Change the max read size to 2k */ | |
389 | result = pci_read_config_byte(pdev, 0x51, &read_size_reg); | |
390 | if (result != PCIBIOS_SUCCESSFUL) { | |
391 | DBG_ERROR(et131x_dbginfo, | |
64f93036 | 392 | "Could not read PCI config space for Max read size\n"); |
cfb739b4 GKH |
393 | DBG_LEAVE(et131x_dbginfo); |
394 | return -EIO; | |
395 | } | |
396 | ||
397 | read_size_reg &= 0x8f; | |
398 | read_size_reg |= 0x40; | |
399 | ||
400 | result = pci_write_config_byte(pdev, 0x51, read_size_reg); | |
401 | if (result != PCIBIOS_SUCCESSFUL) { | |
402 | DBG_ERROR(et131x_dbginfo, | |
64f93036 | 403 | "Could not write PCI config space for Max read size\n"); |
cfb739b4 GKH |
404 | DBG_LEAVE(et131x_dbginfo); |
405 | return -EIO; | |
406 | } | |
407 | ||
cfb739b4 GKH |
408 | /* Get MAC address from config space if an eeprom exists, otherwise |
409 | * the MAC address there will not be valid | |
410 | */ | |
411 | if (adapter->bEepromPresent) { | |
412 | int i; | |
413 | ||
414 | for (i = 0; i < ETH_ALEN; i++) { | |
415 | result = pci_read_config_byte( | |
416 | pdev, ET1310_PCI_MAC_ADDRESS + i, | |
417 | adapter->PermanentAddress + i); | |
418 | if (result != PCIBIOS_SUCCESSFUL) { | |
419 | DBG_ERROR(et131x_dbginfo, | |
64f93036 | 420 | "Could not read PCI config space for MAC address\n"); |
cfb739b4 GKH |
421 | DBG_LEAVE(et131x_dbginfo); |
422 | return -EIO; | |
423 | } | |
424 | } | |
425 | } | |
426 | ||
427 | DBG_LEAVE(et131x_dbginfo); | |
428 | return 0; | |
429 | } | |
430 | ||
431 | /** | |
432 | * et131x_error_timer_handler | |
433 | * @data: timer-specific variable; here a pointer to our adapter structure | |
434 | * | |
435 | * The routine called when the error timer expires, to track the number of | |
436 | * recurring errors. | |
437 | */ | |
438 | void et131x_error_timer_handler(unsigned long data) | |
439 | { | |
25ad00bb | 440 | struct et131x_adapter *etdev = (struct et131x_adapter *) data; |
cfb739b4 GKH |
441 | PM_CSR_t pm_csr; |
442 | ||
25ad00bb | 443 | pm_csr.value = readl(&etdev->CSRAddress->global.pm_csr.value); |
cfb739b4 GKH |
444 | |
445 | if (pm_csr.bits.pm_phy_sw_coma == 0) { | |
25ad00bb AC |
446 | if (etdev->RegistryMACStat) |
447 | UpdateMacStatHostCounters(etdev); | |
64f93036 | 448 | } else |
cfb739b4 GKH |
449 | DBG_VERBOSE(et131x_dbginfo, |
450 | "No interrupts, in PHY coma, pm_csr = 0x%x\n", | |
451 | pm_csr.value); | |
cfb739b4 | 452 | |
25ad00bb AC |
453 | if (!etdev->Bmsr.bits.link_status && |
454 | etdev->RegistryPhyComa && | |
455 | etdev->PoMgmt.TransPhyComaModeOnBoot < 11) { | |
456 | etdev->PoMgmt.TransPhyComaModeOnBoot++; | |
cfb739b4 GKH |
457 | } |
458 | ||
25ad00bb AC |
459 | if (etdev->PoMgmt.TransPhyComaModeOnBoot == 10) { |
460 | if (!etdev->Bmsr.bits.link_status | |
461 | && etdev->RegistryPhyComa) { | |
cfb739b4 | 462 | if (pm_csr.bits.pm_phy_sw_coma == 0) { |
64f93036 AC |
463 | /* NOTE - This was originally a 'sync with |
464 | * interrupt'. How to do that under Linux? | |
465 | */ | |
25ad00bb AC |
466 | et131x_enable_interrupts(etdev); |
467 | EnablePhyComa(etdev); | |
cfb739b4 GKH |
468 | } |
469 | } | |
470 | } | |
471 | ||
472 | /* This is a periodic timer, so reschedule */ | |
25ad00bb | 473 | mod_timer(&etdev->ErrorTimer, jiffies + |
64f93036 | 474 | TX_ERROR_PERIOD * HZ / 1000); |
cfb739b4 GKH |
475 | } |
476 | ||
477 | /** | |
478 | * et131x_link_detection_handler | |
479 | * | |
480 | * Timer function for link up at driver load time | |
481 | */ | |
482 | void et131x_link_detection_handler(unsigned long data) | |
483 | { | |
25ad00bb | 484 | struct et131x_adapter *etdev = (struct et131x_adapter *) data; |
37628606 | 485 | unsigned long flags; |
cfb739b4 GKH |
486 | |
487 | /* Let everyone know that we have run */ | |
25ad00bb | 488 | etdev->bLinkTimerActive = false; |
cfb739b4 | 489 | |
25ad00bb | 490 | if (etdev->MediaState == 0) { |
37628606 | 491 | spin_lock_irqsave(&etdev->Lock, flags); |
cfb739b4 | 492 | |
25ad00bb AC |
493 | etdev->MediaState = NETIF_STATUS_MEDIA_DISCONNECT; |
494 | MP_CLEAR_FLAG(etdev, fMP_ADAPTER_LINK_DETECTION); | |
cfb739b4 | 495 | |
37628606 | 496 | spin_unlock_irqrestore(&etdev->Lock, flags); |
cfb739b4 | 497 | |
25ad00bb | 498 | netif_carrier_off(etdev->netdev); |
cfb739b4 | 499 | |
25ad00bb | 500 | etdev->bSetPending = false; |
cfb739b4 GKH |
501 | } |
502 | } | |
503 | ||
504 | /** | |
505 | * et131x_adapter_setup - Set the adapter up as per cassini+ documentation | |
506 | * @adapter: pointer to our private adapter structure | |
507 | * | |
508 | * Returns 0 on success, errno on failure (as defined in errno.h) | |
509 | */ | |
25ad00bb | 510 | int et131x_adapter_setup(struct et131x_adapter *etdev) |
cfb739b4 GKH |
511 | { |
512 | int status = 0; | |
513 | ||
514 | DBG_ENTER(et131x_dbginfo); | |
515 | ||
516 | /* Configure the JAGCore */ | |
25ad00bb | 517 | ConfigGlobalRegs(etdev); |
cfb739b4 | 518 | |
25ad00bb AC |
519 | ConfigMACRegs1(etdev); |
520 | ConfigMMCRegs(etdev); | |
cfb739b4 | 521 | |
25ad00bb AC |
522 | ConfigRxMacRegs(etdev); |
523 | ConfigTxMacRegs(etdev); | |
cfb739b4 | 524 | |
25ad00bb AC |
525 | ConfigRxDmaRegs(etdev); |
526 | ConfigTxDmaRegs(etdev); | |
cfb739b4 | 527 | |
25ad00bb | 528 | ConfigMacStatRegs(etdev); |
cfb739b4 GKH |
529 | |
530 | /* Move the following code to Timer function?? */ | |
25ad00bb | 531 | status = et131x_xcvr_find(etdev); |
cfb739b4 | 532 | |
64f93036 | 533 | if (status != 0) |
cfb739b4 | 534 | DBG_WARNING(et131x_dbginfo, "Could not find the xcvr\n"); |
cfb739b4 GKH |
535 | |
536 | /* Prepare the TRUEPHY library. */ | |
25ad00bb | 537 | ET1310_PhyInit(etdev); |
cfb739b4 GKH |
538 | |
539 | /* Reset the phy now so changes take place */ | |
25ad00bb | 540 | ET1310_PhyReset(etdev); |
cfb739b4 GKH |
541 | |
542 | /* Power down PHY */ | |
25ad00bb | 543 | ET1310_PhyPowerDown(etdev, 1); |
cfb739b4 GKH |
544 | |
545 | /* | |
546 | * We need to turn off 1000 base half dulplex, the mac does not | |
547 | * support it. For the 10/100 part, turn off all gig advertisement | |
548 | */ | |
5ec3487a | 549 | if (etdev->pdev->device != ET131X_PCI_DEVICE_ID_FAST) |
25ad00bb | 550 | ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL); |
64f93036 | 551 | else |
25ad00bb | 552 | ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); |
cfb739b4 GKH |
553 | |
554 | /* Power up PHY */ | |
25ad00bb | 555 | ET1310_PhyPowerDown(etdev, 0); |
cfb739b4 | 556 | |
25ad00bb | 557 | et131x_setphy_normal(etdev); |
cfb739b4 GKH |
558 | |
559 | DBG_LEAVE(et131x_dbginfo); | |
560 | return status; | |
561 | } | |
562 | ||
563 | /** | |
564 | * et131x_setup_hardware_properties - set up the MAC Address on the ET1310 | |
565 | * @adapter: pointer to our private adapter structure | |
566 | */ | |
567 | void et131x_setup_hardware_properties(struct et131x_adapter *adapter) | |
568 | { | |
569 | DBG_ENTER(et131x_dbginfo); | |
570 | ||
571 | /* If have our default mac from registry and no mac address from | |
572 | * EEPROM then we need to generate the last octet and set it on the | |
573 | * device | |
574 | */ | |
575 | if (!adapter->bOverrideAddress) { | |
576 | if (adapter->PermanentAddress[0] == 0x00 && | |
577 | adapter->PermanentAddress[1] == 0x00 && | |
578 | adapter->PermanentAddress[2] == 0x00 && | |
579 | adapter->PermanentAddress[3] == 0x00 && | |
580 | adapter->PermanentAddress[4] == 0x00 && | |
581 | adapter->PermanentAddress[5] == 0x00) { | |
582 | /* | |
583 | * We need to randomly generate the last octet so we | |
584 | * decrease our chances of setting the mac address to | |
585 | * same as another one of our cards in the system | |
586 | */ | |
587 | get_random_bytes(&adapter->CurrentAddress[5], 1); | |
588 | ||
589 | /* | |
590 | * We have the default value in the register we are | |
591 | * working with so we need to copy the current | |
592 | * address into the permanent address | |
593 | */ | |
594 | memcpy(adapter->PermanentAddress, | |
595 | adapter->CurrentAddress, ETH_ALEN); | |
596 | } else { | |
597 | /* We do not have an override address, so set the | |
598 | * current address to the permanent address and add | |
599 | * it to the device | |
600 | */ | |
601 | memcpy(adapter->CurrentAddress, | |
602 | adapter->PermanentAddress, ETH_ALEN); | |
603 | } | |
604 | } | |
605 | ||
606 | DBG_LEAVE(et131x_dbginfo); | |
607 | } | |
608 | ||
609 | /** | |
610 | * et131x_soft_reset - Issue a soft reset to the hardware, complete for ET1310 | |
611 | * @adapter: pointer to our private adapter structure | |
612 | */ | |
613 | void et131x_soft_reset(struct et131x_adapter *adapter) | |
614 | { | |
615 | DBG_ENTER(et131x_dbginfo); | |
616 | ||
617 | /* Disable MAC Core */ | |
618 | writel(0xc00f0000, &adapter->CSRAddress->mac.cfg1.value); | |
619 | ||
620 | /* Set everything to a reset value */ | |
621 | writel(0x7F, &adapter->CSRAddress->global.sw_reset.value); | |
622 | writel(0x000f0000, &adapter->CSRAddress->mac.cfg1.value); | |
623 | writel(0x00000000, &adapter->CSRAddress->mac.cfg1.value); | |
624 | ||
625 | DBG_LEAVE(et131x_dbginfo); | |
626 | } | |
627 | ||
628 | /** | |
629 | * et131x_align_allocated_memory - Align allocated memory on a given boundary | |
630 | * @adapter: pointer to our adapter structure | |
631 | * @phys_addr: pointer to Physical address | |
632 | * @offset: pointer to the offset variable | |
633 | * @mask: correct mask | |
634 | */ | |
635 | void et131x_align_allocated_memory(struct et131x_adapter *adapter, | |
636 | uint64_t *phys_addr, | |
637 | uint64_t *offset, uint64_t mask) | |
638 | { | |
639 | uint64_t new_addr; | |
640 | ||
641 | DBG_ENTER(et131x_dbginfo); | |
642 | ||
643 | *offset = 0; | |
644 | ||
645 | new_addr = *phys_addr & ~mask; | |
646 | ||
647 | if (new_addr != *phys_addr) { | |
648 | /* Move to next aligned block */ | |
649 | new_addr += mask + 1; | |
650 | /* Return offset for adjusting virt addr */ | |
651 | *offset = new_addr - *phys_addr; | |
652 | /* Return new physical address */ | |
653 | *phys_addr = new_addr; | |
654 | } | |
655 | ||
656 | DBG_LEAVE(et131x_dbginfo); | |
657 | } | |
658 | ||
659 | /** | |
660 | * et131x_adapter_memory_alloc | |
661 | * @adapter: pointer to our private adapter structure | |
662 | * | |
663 | * Returns 0 on success, errno on failure (as defined in errno.h). | |
664 | * | |
665 | * Allocate all the memory blocks for send, receive and others. | |
666 | */ | |
667 | int et131x_adapter_memory_alloc(struct et131x_adapter *adapter) | |
668 | { | |
669 | int status = 0; | |
670 | ||
671 | DBG_ENTER(et131x_dbginfo); | |
672 | ||
673 | do { | |
674 | /* Allocate memory for the Tx Ring */ | |
675 | status = et131x_tx_dma_memory_alloc(adapter); | |
676 | if (status != 0) { | |
677 | DBG_ERROR(et131x_dbginfo, | |
678 | "et131x_tx_dma_memory_alloc FAILED\n"); | |
679 | break; | |
680 | } | |
681 | ||
682 | /* Receive buffer memory allocation */ | |
683 | status = et131x_rx_dma_memory_alloc(adapter); | |
684 | if (status != 0) { | |
685 | DBG_ERROR(et131x_dbginfo, | |
686 | "et131x_rx_dma_memory_alloc FAILED\n"); | |
687 | et131x_tx_dma_memory_free(adapter); | |
688 | break; | |
689 | } | |
690 | ||
691 | /* Init receive data structures */ | |
692 | status = et131x_init_recv(adapter); | |
693 | if (status != 0) { | |
694 | DBG_ERROR(et131x_dbginfo, "et131x_init_recv FAILED\n"); | |
695 | et131x_tx_dma_memory_free(adapter); | |
696 | et131x_rx_dma_memory_free(adapter); | |
697 | break; | |
698 | } | |
699 | } while (0); | |
700 | ||
701 | DBG_LEAVE(et131x_dbginfo); | |
702 | return status; | |
703 | } | |
704 | ||
705 | /** | |
706 | * et131x_adapter_memory_free - Free all memory allocated for use by Tx & Rx | |
707 | * @adapter: pointer to our private adapter structure | |
708 | */ | |
709 | void et131x_adapter_memory_free(struct et131x_adapter *adapter) | |
710 | { | |
711 | DBG_ENTER(et131x_dbginfo); | |
712 | ||
713 | /* Free DMA memory */ | |
714 | et131x_tx_dma_memory_free(adapter); | |
715 | et131x_rx_dma_memory_free(adapter); | |
716 | ||
717 | DBG_LEAVE(et131x_dbginfo); | |
718 | } | |
719 | ||
720 | /** | |
721 | * et131x_pci_remove | |
722 | * @pdev: a pointer to the device's pci_dev structure | |
723 | * | |
724 | * Registered in the pci_driver structure, this function is called when the | |
725 | * PCI subsystem detects that a PCI device which matches the information | |
726 | * contained in the pci_device_id table has been removed. | |
727 | */ | |
728 | void __devexit et131x_pci_remove(struct pci_dev *pdev) | |
729 | { | |
730 | struct net_device *netdev; | |
731 | struct et131x_adapter *adapter; | |
732 | ||
733 | DBG_ENTER(et131x_dbginfo); | |
734 | ||
735 | /* Retrieve the net_device pointer from the pci_dev struct, as well | |
736 | * as the private adapter struct | |
737 | */ | |
738 | netdev = (struct net_device *) pci_get_drvdata(pdev); | |
739 | adapter = netdev_priv(netdev); | |
740 | ||
741 | /* Perform device cleanup */ | |
742 | unregister_netdev(netdev); | |
743 | et131x_adapter_memory_free(adapter); | |
744 | iounmap(adapter->CSRAddress); | |
745 | free_netdev(netdev); | |
746 | pci_release_regions(pdev); | |
747 | pci_disable_device(pdev); | |
748 | ||
749 | DBG_LEAVE(et131x_dbginfo); | |
750 | } | |
751 | ||
752 | /** | |
753 | * et131x_pci_setup - Perform device initialization | |
754 | * @pdev: a pointer to the device's pci_dev structure | |
755 | * @ent: this device's entry in the pci_device_id table | |
756 | * | |
757 | * Returns 0 on success, errno on failure (as defined in errno.h) | |
758 | * | |
759 | * Registered in the pci_driver structure, this function is called when the | |
760 | * PCI subsystem finds a new PCI device which matches the information | |
761 | * contained in the pci_device_id table. This routine is the equivalent to | |
762 | * a device insertion routine. | |
763 | */ | |
764 | int __devinit et131x_pci_setup(struct pci_dev *pdev, | |
765 | const struct pci_device_id *ent) | |
766 | { | |
767 | int result = 0; | |
768 | int pm_cap; | |
769 | bool pci_using_dac; | |
770 | struct net_device *netdev = NULL; | |
771 | struct et131x_adapter *adapter = NULL; | |
772 | ||
773 | DBG_ENTER(et131x_dbginfo); | |
774 | ||
775 | /* Enable the device via the PCI subsystem */ | |
776 | result = pci_enable_device(pdev); | |
777 | if (result != 0) { | |
778 | DBG_ERROR(et131x_dbginfo, "pci_enable_device() failed\n"); | |
779 | goto out; | |
780 | } | |
781 | ||
782 | /* Perform some basic PCI checks */ | |
783 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { | |
784 | DBG_ERROR(et131x_dbginfo, | |
785 | "Can't find PCI device's base address\n"); | |
786 | result = -ENODEV; | |
787 | goto out; | |
788 | } | |
789 | ||
790 | result = pci_request_regions(pdev, DRIVER_NAME); | |
791 | if (result != 0) { | |
792 | DBG_ERROR(et131x_dbginfo, "Can't get PCI resources\n"); | |
793 | goto err_disable; | |
794 | } | |
795 | ||
796 | /* Enable PCI bus mastering */ | |
797 | DBG_TRACE(et131x_dbginfo, "Setting PCI Bus Mastering...\n"); | |
798 | pci_set_master(pdev); | |
799 | ||
800 | /* Query PCI for Power Mgmt Capabilities | |
801 | * | |
802 | * NOTE: Now reading PowerMgmt in another location; is this still | |
803 | * needed? | |
804 | */ | |
805 | pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); | |
806 | if (pm_cap == 0) { | |
807 | DBG_ERROR(et131x_dbginfo, | |
808 | "Cannot find Power Management capabilities\n"); | |
809 | result = -EIO; | |
810 | goto err_release_res; | |
811 | } | |
812 | ||
813 | /* Check the DMA addressing support of this device */ | |
814 | if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) { | |
815 | DBG_TRACE(et131x_dbginfo, "64-bit DMA addressing supported\n"); | |
816 | pci_using_dac = true; | |
817 | ||
818 | result = | |
819 | pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL); | |
820 | if (result != 0) { | |
821 | DBG_ERROR(et131x_dbginfo, | |
822 | "Unable to obtain 64 bit DMA for consistent allocations\n"); | |
823 | goto err_release_res; | |
824 | } | |
825 | } else if (!pci_set_dma_mask(pdev, 0xffffffffULL)) { | |
826 | DBG_TRACE(et131x_dbginfo, | |
827 | "64-bit DMA addressing NOT supported\n"); | |
828 | DBG_TRACE(et131x_dbginfo, | |
829 | "32-bit DMA addressing will be used\n"); | |
830 | pci_using_dac = false; | |
831 | } else { | |
832 | DBG_ERROR(et131x_dbginfo, "No usable DMA addressing method\n"); | |
833 | result = -EIO; | |
834 | goto err_release_res; | |
835 | } | |
836 | ||
837 | /* Allocate netdev and private adapter structs */ | |
838 | DBG_TRACE(et131x_dbginfo, | |
839 | "Allocate netdev and private adapter structs...\n"); | |
840 | netdev = et131x_device_alloc(); | |
841 | if (netdev == NULL) { | |
842 | DBG_ERROR(et131x_dbginfo, "Couldn't alloc netdev struct\n"); | |
843 | result = -ENOMEM; | |
844 | goto err_release_res; | |
845 | } | |
846 | ||
847 | /* Setup the fundamental net_device and private adapter structure elements */ | |
848 | DBG_TRACE(et131x_dbginfo, "Setting fundamental net_device info...\n"); | |
849 | SET_NETDEV_DEV(netdev, &pdev->dev); | |
64f93036 | 850 | /* |
cfb739b4 | 851 | if (pci_using_dac) { |
64f93036 | 852 | netdev->features |= NETIF_F_HIGHDMA; |
cfb739b4 | 853 | } |
64f93036 | 854 | */ |
cfb739b4 GKH |
855 | |
856 | /* | |
857 | * NOTE - Turn this on when we're ready to deal with SG-DMA | |
858 | * | |
859 | * NOTE: According to "Linux Device Drivers", 3rd ed, Rubini et al, | |
860 | * if checksumming is not performed in HW, then the kernel will not | |
861 | * use SG. | |
862 | * From pp 510-511: | |
863 | * | |
864 | * "Note that the kernel does not perform scatter/gather I/O to your | |
865 | * device if it does not also provide some form of checksumming as | |
866 | * well. The reason is that, if the kernel has to make a pass over a | |
867 | * fragmented ("nonlinear") packet to calculate the checksum, it | |
868 | * might as well copy the data and coalesce the packet at the same | |
869 | * time." | |
870 | * | |
871 | * This has been verified by setting the flags below and still not | |
872 | * receiving a scattered buffer from the network stack, so leave it | |
873 | * off until checksums are calculated in HW. | |
874 | */ | |
64f93036 AC |
875 | /* netdev->features |= NETIF_F_SG; */ |
876 | /* netdev->features |= NETIF_F_NO_CSUM; */ | |
877 | /* netdev->features |= NETIF_F_LLTX; */ | |
cfb739b4 GKH |
878 | |
879 | /* Allocate private adapter struct and copy in relevant information */ | |
880 | adapter = netdev_priv(netdev); | |
881 | adapter->pdev = pdev; | |
882 | adapter->netdev = netdev; | |
cfb739b4 GKH |
883 | |
884 | /* Do the same for the netdev struct */ | |
885 | netdev->irq = pdev->irq; | |
886 | netdev->base_addr = pdev->resource[0].start; | |
887 | ||
888 | /* Initialize spinlocks here */ | |
889 | DBG_TRACE(et131x_dbginfo, "Initialize spinlocks...\n"); | |
890 | ||
891 | spin_lock_init(&adapter->Lock); | |
892 | spin_lock_init(&adapter->TCBSendQLock); | |
893 | spin_lock_init(&adapter->TCBReadyQLock); | |
894 | spin_lock_init(&adapter->SendHWLock); | |
895 | spin_lock_init(&adapter->SendWaitLock); | |
896 | spin_lock_init(&adapter->RcvLock); | |
897 | spin_lock_init(&adapter->RcvPendLock); | |
898 | spin_lock_init(&adapter->FbrLock); | |
899 | spin_lock_init(&adapter->PHYLock); | |
900 | ||
901 | /* Parse configuration parameters into the private adapter struct */ | |
902 | et131x_config_parse(adapter); | |
903 | ||
904 | /* Find the physical adapter | |
905 | * | |
906 | * NOTE: This is the equivalent of the MpFindAdapter() routine; can we | |
907 | * lump it's init with the device specific init below into a | |
908 | * single init function? | |
909 | */ | |
64f93036 | 910 | /* while (et131x_find_adapter(adapter, pdev) != 0); */ |
cfb739b4 GKH |
911 | et131x_find_adapter(adapter, pdev); |
912 | ||
913 | /* Map the bus-relative registers to system virtual memory */ | |
914 | DBG_TRACE(et131x_dbginfo, | |
915 | "Mapping bus-relative registers to virtual memory...\n"); | |
916 | ||
917 | adapter->CSRAddress = ioremap_nocache(pci_resource_start(pdev, 0), | |
918 | pci_resource_len(pdev, 0)); | |
919 | if (adapter->CSRAddress == NULL) { | |
920 | DBG_ERROR(et131x_dbginfo, "Cannot map device registers\n"); | |
921 | result = -ENOMEM; | |
922 | goto err_free_dev; | |
923 | } | |
924 | ||
925 | /* Perform device-specific initialization here (See code below) */ | |
926 | ||
927 | /* If Phy COMA mode was enabled when we went down, disable it here. */ | |
928 | { | |
929 | PM_CSR_t GlobalPmCSR = { 0 }; | |
930 | ||
931 | GlobalPmCSR.bits.pm_sysclk_gate = 1; | |
932 | GlobalPmCSR.bits.pm_txclk_gate = 1; | |
933 | GlobalPmCSR.bits.pm_rxclk_gate = 1; | |
934 | writel(GlobalPmCSR.value, | |
935 | &adapter->CSRAddress->global.pm_csr.value); | |
936 | } | |
937 | ||
938 | /* Issue a global reset to the et1310 */ | |
939 | DBG_TRACE(et131x_dbginfo, "Issuing soft reset...\n"); | |
940 | et131x_soft_reset(adapter); | |
941 | ||
942 | /* Disable all interrupts (paranoid) */ | |
943 | DBG_TRACE(et131x_dbginfo, "Disable device interrupts...\n"); | |
944 | et131x_disable_interrupts(adapter); | |
945 | ||
946 | /* Allocate DMA memory */ | |
947 | result = et131x_adapter_memory_alloc(adapter); | |
948 | if (result != 0) { | |
949 | DBG_ERROR(et131x_dbginfo, | |
950 | "Could not alloc adapater memory (DMA)\n"); | |
951 | goto err_iounmap; | |
952 | } | |
953 | ||
954 | /* Init send data structures */ | |
955 | DBG_TRACE(et131x_dbginfo, "Init send data structures...\n"); | |
956 | et131x_init_send(adapter); | |
957 | ||
cfb739b4 GKH |
958 | /* Register the interrupt |
959 | * | |
960 | * NOTE - This is being done in the open routine, where most other | |
961 | * Linux drivers setup IRQ handlers. Make sure device | |
962 | * interrupts are not turned on before the IRQ is registered!! | |
963 | * | |
964 | * What we will do here is setup the task structure for the | |
965 | * ISR's deferred handler | |
966 | */ | |
967 | INIT_WORK(&adapter->task, et131x_isr_handler); | |
968 | ||
969 | /* Determine MAC Address, and copy into the net_device struct */ | |
970 | DBG_TRACE(et131x_dbginfo, "Retrieve MAC address...\n"); | |
971 | et131x_setup_hardware_properties(adapter); | |
972 | ||
973 | memcpy(netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN); | |
974 | ||
975 | /* Setup et1310 as per the documentation */ | |
976 | DBG_TRACE(et131x_dbginfo, "Setup the adapter...\n"); | |
977 | et131x_adapter_setup(adapter); | |
978 | ||
979 | /* Create a timer to count errors received by the NIC */ | |
980 | init_timer(&adapter->ErrorTimer); | |
981 | ||
982 | adapter->ErrorTimer.expires = jiffies + TX_ERROR_PERIOD * HZ / 1000; | |
983 | adapter->ErrorTimer.function = et131x_error_timer_handler; | |
984 | adapter->ErrorTimer.data = (unsigned long)adapter; | |
985 | ||
986 | /* Initialize link state */ | |
987 | et131x_link_detection_handler((unsigned long)adapter); | |
988 | ||
64f93036 AC |
989 | /* Intialize variable for counting how long we do not have |
990 | link status */ | |
cfb739b4 GKH |
991 | adapter->PoMgmt.TransPhyComaModeOnBoot = 0; |
992 | ||
993 | /* We can enable interrupts now | |
994 | * | |
995 | * NOTE - Because registration of interrupt handler is done in the | |
996 | * device's open(), defer enabling device interrupts to that | |
997 | * point | |
998 | */ | |
999 | ||
1000 | /* Register the net_device struct with the Linux network layer */ | |
1001 | DBG_TRACE(et131x_dbginfo, "Registering net_device...\n"); | |
64f93036 AC |
1002 | result = register_netdev(netdev); |
1003 | if (result != 0) { | |
cfb739b4 GKH |
1004 | DBG_ERROR(et131x_dbginfo, "register_netdev() failed\n"); |
1005 | goto err_mem_free; | |
1006 | } | |
1007 | ||
1008 | /* Register the net_device struct with the PCI subsystem. Save a copy | |
1009 | * of the PCI config space for this device now that the device has | |
1010 | * been initialized, just in case it needs to be quickly restored. | |
1011 | */ | |
1012 | pci_set_drvdata(pdev, netdev); | |
1013 | ||
1014 | pci_save_state(adapter->pdev); | |
1015 | ||
1016 | out: | |
1017 | DBG_LEAVE(et131x_dbginfo); | |
1018 | return result; | |
1019 | ||
1020 | err_mem_free: | |
1021 | et131x_adapter_memory_free(adapter); | |
1022 | err_iounmap: | |
1023 | iounmap(adapter->CSRAddress); | |
1024 | err_free_dev: | |
1025 | free_netdev(netdev); | |
1026 | err_release_res: | |
1027 | pci_release_regions(pdev); | |
1028 | err_disable: | |
1029 | pci_disable_device(pdev); | |
1030 | goto out; | |
1031 | } |