]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
net: get rid of SET_ETHTOOL_OPS
[mirror_ubuntu-artful-kernel.git] / drivers / staging / ft1000 / ft1000-pcmcia / ft1000_hw.c
CommitLineData
f7c1be0c
MB
1/*---------------------------------------------------------------------------
2 FT1000 driver for Flarion Flash OFDM NIC Device
bf3146c8 3
f7c1be0c
MB
4 Copyright (C) 2002 Flarion Technologies, All rights reserved.
5 Copyright (C) 2006 Patrik Ostrihon, All rights reserved.
6 Copyright (C) 2006 ProWeb Consulting, a.s, All rights reserved.
bf3146c8
GKH
7
8 This program is free software; you can redistribute it and/or modify it
f7c1be0c 9 under the terms of the GNU General Public License as published by the Free
bf3146c8
GKH
10 Software Foundation; either version 2 of the License, or (at your option) any
11 later version. This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 more details. You should have received a copy of the GNU General Public
15 License along with this program; if not, write to the
16 Free Software Foundation, Inc., 59 Temple Place -
17 Suite 330, Boston, MA 02111-1307, USA.
588c31ea 18 -------------------------------------------------------------------------*/
f7c1be0c
MB
19
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/proc_fs.h>
23
24#include <linux/sched.h>
25#include <linux/ptrace.h>
26#include <linux/slab.h>
27#include <linux/string.h>
28#include <linux/timer.h>
29#include <linux/interrupt.h>
30#include <linux/in.h>
31#include <asm/io.h>
f7c1be0c
MB
32#include <asm/bitops.h>
33
34#include <linux/netdevice.h>
35#include <linux/etherdevice.h>
36#include <linux/skbuff.h>
37#include <linux/if_arp.h>
38#include <linux/ioport.h>
39#include <linux/wait.h>
40#include <linux/vmalloc.h>
41
42#include <linux/firmware.h>
43#include <linux/ethtool.h>
44
c331e766
MB
45#include <pcmcia/cistpl.h>
46#include <pcmcia/cisreg.h>
47#include <pcmcia/ds.h>
48
f7c1be0c
MB
49#ifdef FT_DEBUG
50#define DEBUG(n, args...) printk(KERN_DEBUG args);
51#else
52#define DEBUG(n, args...)
53#endif
54
55#include <linux/delay.h>
f7c1be0c
MB
56#include "ft1000.h"
57
eb93ca4e 58static const struct firmware *fw_entry;
f7c1be0c
MB
59
60static void ft1000_hbchk(u_long data);
61static struct timer_list poll_timer = {
eb93ca4e 62 .function = ft1000_hbchk
f7c1be0c
MB
63};
64
65static u16 cmdbuffer[1024];
66static u8 tempbuffer[1600];
67static u8 ft1000_card_present = 0;
68static u8 flarion_ft1000_cnt = 0;
69
70static irqreturn_t ft1000_interrupt(int irq, void *dev_id);
71static void ft1000_enable_interrupts(struct net_device *dev);
72static void ft1000_disable_interrupts(struct net_device *dev);
73
74/* new kernel */
75MODULE_AUTHOR("");
76MODULE_DESCRIPTION
77 ("Support for Flarion Flash OFDM NIC Device. Support for PCMCIA when used with ft1000_cs.");
78MODULE_LICENSE("GPL");
79MODULE_SUPPORTED_DEVICE("FT1000");
80
81#define MAX_RCV_LOOP 100
82
588c31ea
DD
83/*---------------------------------------------------------------------------
84
85 Function: ft1000_read_fifo_len
86 Description: This function will read the ASIC Uplink FIFO status register
87 which will return the number of bytes remaining in the Uplink FIFO.
88 Sixteen bytes are subtracted to make sure that the ASIC does not
89 reach its threshold.
90 Input:
91 dev - network device structure
92 Output:
93 value - number of bytes available in the ASIC Uplink FIFO.
94
95 -------------------------------------------------------------------------*/
f7c1be0c
MB
96static inline u16 ft1000_read_fifo_len(struct net_device *dev)
97{
d3706552 98 struct ft1000_info *info = netdev_priv(dev);
f7c1be0c 99
b3a87c37 100 if (info->AsicID == ELECTRABUZZ_ID)
f7c1be0c 101 return (ft1000_read_reg(dev, FT1000_REG_UFIFO_STAT) - 16);
b3a87c37 102 else
f7c1be0c 103 return (ft1000_read_reg(dev, FT1000_REG_MAG_UFSR) - 16);
f7c1be0c
MB
104}
105
588c31ea
DD
106/*---------------------------------------------------------------------------
107
108 Function: ft1000_read_dpram
109 Description: This function will read the specific area of dpram
110 (Electrabuzz ASIC only)
111 Input:
112 dev - device structure
113 offset - index of dpram
114 Output:
115 value - value of dpram
116
117 -------------------------------------------------------------------------*/
cfe116c2 118u16 ft1000_read_dpram(struct net_device *dev, int offset)
f7c1be0c 119{
d3706552 120 struct ft1000_info *info = netdev_priv(dev);
f7c1be0c
MB
121 unsigned long flags;
122 u16 data;
123
588c31ea 124 /* Provide mutual exclusive access while reading ASIC registers. */
f7c1be0c
MB
125 spin_lock_irqsave(&info->dpram_lock, flags);
126 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
127 data = ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
128 spin_unlock_irqrestore(&info->dpram_lock, flags);
129
130 return (data);
131}
132
588c31ea
DD
133/*---------------------------------------------------------------------------
134
135 Function: ft1000_write_dpram
136 Description: This function will write to a specific area of dpram
137 (Electrabuzz ASIC only)
138 Input:
139 dev - device structure
140 offset - index of dpram
141 value - value to write
142 Output:
143 none.
144
145 -------------------------------------------------------------------------*/
f7c1be0c
MB
146static inline void ft1000_write_dpram(struct net_device *dev,
147 int offset, u16 value)
148{
d3706552 149 struct ft1000_info *info = netdev_priv(dev);
f7c1be0c
MB
150 unsigned long flags;
151
588c31ea 152 /* Provide mutual exclusive access while reading ASIC registers. */
f7c1be0c
MB
153 spin_lock_irqsave(&info->dpram_lock, flags);
154 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
155 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, value);
156 spin_unlock_irqrestore(&info->dpram_lock, flags);
157}
158
588c31ea
DD
159/*---------------------------------------------------------------------------
160
161 Function: ft1000_read_dpram_mag_16
162 Description: This function will read the specific area of dpram
163 (Magnemite ASIC only)
164 Input:
165 dev - device structure
166 offset - index of dpram
167 Output:
168 value - value of dpram
169
170 -------------------------------------------------------------------------*/
f7c1be0c
MB
171u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index)
172{
d3706552 173 struct ft1000_info *info = netdev_priv(dev);
f7c1be0c
MB
174 unsigned long flags;
175 u16 data;
176
588c31ea 177 /* Provide mutual exclusive access while reading ASIC registers. */
f7c1be0c
MB
178 spin_lock_irqsave(&info->dpram_lock, flags);
179 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
588c31ea 180 /* check if we want to read upper or lower 32-bit word */
f7c1be0c
MB
181 if (Index) {
182 data = ft1000_read_reg(dev, FT1000_REG_MAG_DPDATAL);
183 } else {
184 data = ft1000_read_reg(dev, FT1000_REG_MAG_DPDATAH);
185 }
186 spin_unlock_irqrestore(&info->dpram_lock, flags);
187
188 return (data);
189}
190
588c31ea
DD
191/*---------------------------------------------------------------------------
192
193 Function: ft1000_write_dpram_mag_16
194 Description: This function will write to a specific area of dpram
195 (Magnemite ASIC only)
196 Input:
197 dev - device structure
198 offset - index of dpram
199 value - value to write
200 Output:
201 none.
202
203 -------------------------------------------------------------------------*/
f7c1be0c
MB
204static inline void ft1000_write_dpram_mag_16(struct net_device *dev,
205 int offset, u16 value, int Index)
206{
d3706552 207 struct ft1000_info *info = netdev_priv(dev);
f7c1be0c
MB
208 unsigned long flags;
209
588c31ea 210 /* Provide mutual exclusive access while reading ASIC registers. */
f7c1be0c
MB
211 spin_lock_irqsave(&info->dpram_lock, flags);
212 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
213 if (Index) {
214 ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAL, value);
215 } else {
216 ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAH, value);
217 }
218 spin_unlock_irqrestore(&info->dpram_lock, flags);
219}
220
588c31ea
DD
221/*---------------------------------------------------------------------------
222
223 Function: ft1000_read_dpram_mag_32
224 Description: This function will read the specific area of dpram
225 (Magnemite ASIC only)
226 Input:
227 dev - device structure
228 offset - index of dpram
229 Output:
230 value - value of dpram
231
232 -------------------------------------------------------------------------*/
f7c1be0c
MB
233u32 ft1000_read_dpram_mag_32(struct net_device *dev, int offset)
234{
d3706552 235 struct ft1000_info *info = netdev_priv(dev);
f7c1be0c
MB
236 unsigned long flags;
237 u32 data;
238
588c31ea 239 /* Provide mutual exclusive access while reading ASIC registers. */
f7c1be0c
MB
240 spin_lock_irqsave(&info->dpram_lock, flags);
241 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
242 data = inl(dev->base_addr + FT1000_REG_MAG_DPDATAL);
243 spin_unlock_irqrestore(&info->dpram_lock, flags);
244
245 return (data);
246}
247
588c31ea
DD
248/*---------------------------------------------------------------------------
249
250 Function: ft1000_write_dpram_mag_32
251 Description: This function will write to a specific area of dpram
252 (Magnemite ASIC only)
253 Input:
254 dev - device structure
255 offset - index of dpram
256 value - value to write
257 Output:
258 none.
259
260 -------------------------------------------------------------------------*/
f7c1be0c
MB
261void ft1000_write_dpram_mag_32(struct net_device *dev, int offset, u32 value)
262{
d3706552 263 struct ft1000_info *info = netdev_priv(dev);
f7c1be0c
MB
264 unsigned long flags;
265
588c31ea 266 /* Provide mutual exclusive access while reading ASIC registers. */
f7c1be0c
MB
267 spin_lock_irqsave(&info->dpram_lock, flags);
268 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
269 outl(value, dev->base_addr + FT1000_REG_MAG_DPDATAL);
270 spin_unlock_irqrestore(&info->dpram_lock, flags);
271}
272
588c31ea
DD
273/*---------------------------------------------------------------------------
274
275 Function: ft1000_enable_interrupts
276 Description: This function will enable interrupts base on the current interrupt mask.
277 Input:
278 dev - device structure
279 Output:
280 None.
281
282 -------------------------------------------------------------------------*/
f7c1be0c
MB
283static void ft1000_enable_interrupts(struct net_device *dev)
284{
f7c1be0c
MB
285 u16 tempword;
286
287 DEBUG(1, "ft1000_hw:ft1000_enable_interrupts()\n");
cefe8adb 288 ft1000_write_reg(dev, FT1000_REG_SUP_IMASK, ISR_DEFAULT_MASK);
f7c1be0c
MB
289 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK);
290 DEBUG(1,
291 "ft1000_hw:ft1000_enable_interrupts:current interrupt enable mask = 0x%x\n",
292 tempword);
f7c1be0c
MB
293}
294
588c31ea
DD
295/*---------------------------------------------------------------------------
296
297 Function: ft1000_disable_interrupts
298 Description: This function will disable all interrupts.
299 Input:
300 dev - device structure
301 Output:
302 None.
303
304 -------------------------------------------------------------------------*/
f7c1be0c
MB
305static void ft1000_disable_interrupts(struct net_device *dev)
306{
f7c1be0c
MB
307 u16 tempword;
308
309 DEBUG(1, "ft1000_hw: ft1000_disable_interrupts()\n");
310 ft1000_write_reg(dev, FT1000_REG_SUP_IMASK, ISR_MASK_ALL);
311 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK);
312 DEBUG(1,
313 "ft1000_hw:ft1000_disable_interrupts:current interrupt enable mask = 0x%x\n",
314 tempword);
f7c1be0c
MB
315}
316
588c31ea
DD
317/*---------------------------------------------------------------------------
318
319 Function: ft1000_reset_asic
320 Description: This function will call the Card Service function to reset the
321 ASIC.
322 Input:
323 dev - device structure
324 Output:
325 none
326
327 -------------------------------------------------------------------------*/
f7c1be0c
MB
328static void ft1000_reset_asic(struct net_device *dev)
329{
d3706552 330 struct ft1000_info *info = netdev_priv(dev);
3aa2303a 331 struct ft1000_pcmcia *pcmcia = info->priv;
f7c1be0c
MB
332 u16 tempword;
333
334 DEBUG(1, "ft1000_hw:ft1000_reset_asic called\n");
335
3aa2303a 336 (*info->ft1000_reset) (pcmcia->link);
f7c1be0c 337
588c31ea
DD
338 /*
339 * Let's use the register provided by the Magnemite ASIC to reset the
340 * ASIC and DSP.
341 */
f7c1be0c
MB
342 if (info->AsicID == MAGNEMITE_ID) {
343 ft1000_write_reg(dev, FT1000_REG_RESET,
344 (DSP_RESET_BIT | ASIC_RESET_BIT));
345 }
346 mdelay(1);
347 if (info->AsicID == ELECTRABUZZ_ID) {
588c31ea 348 /* set watermark to -1 in order to not generate an interrupt */
f7c1be0c
MB
349 ft1000_write_reg(dev, FT1000_REG_WATERMARK, 0xffff);
350 } else {
588c31ea 351 /* set watermark to -1 in order to not generate an interrupt */
f7c1be0c
MB
352 ft1000_write_reg(dev, FT1000_REG_MAG_WATERMARK, 0xffff);
353 }
588c31ea 354 /* clear interrupts */
f7c1be0c
MB
355 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
356 DEBUG(1, "ft1000_hw: interrupt status register = 0x%x\n", tempword);
357 ft1000_write_reg(dev, FT1000_REG_SUP_ISR, tempword);
358 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
359 DEBUG(1, "ft1000_hw: interrupt status register = 0x%x\n", tempword);
360
361}
362
588c31ea
DD
363/*---------------------------------------------------------------------------
364
365 Function: ft1000_reset_card
366 Description: This function will reset the card
367 Input:
368 dev - device structure
369 Output:
370 status - false (card reset fail)
371 true (card reset successful)
372
373 -------------------------------------------------------------------------*/
f7c1be0c
MB
374static int ft1000_reset_card(struct net_device *dev)
375{
d3706552 376 struct ft1000_info *info = netdev_priv(dev);
f7c1be0c
MB
377 u16 tempword;
378 int i;
379 unsigned long flags;
3aaf8073 380 struct prov_record *ptr;
f7c1be0c
MB
381
382 DEBUG(1, "ft1000_hw:ft1000_reset_card called.....\n");
383
384 info->CardReady = 0;
385 info->ProgConStat = 0;
386 info->squeseqnum = 0;
387 ft1000_disable_interrupts(dev);
388
588c31ea 389 /* del_timer(&poll_timer); */
f7c1be0c 390
588c31ea 391 /* Make sure we free any memory reserve for provisioning */
f7c1be0c
MB
392 while (list_empty(&info->prov_list) == 0) {
393 DEBUG(0,
394 "ft1000_hw:ft1000_reset_card:deleting provisioning record\n");
3aaf8073 395 ptr = list_entry(info->prov_list.next, struct prov_record, list);
f7c1be0c
MB
396 list_del(&ptr->list);
397 kfree(ptr->pprov_data);
398 kfree(ptr);
399 }
400
401 if (info->AsicID == ELECTRABUZZ_ID) {
402 DEBUG(1, "ft1000_hw:ft1000_reset_card:resetting DSP\n");
403 ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT);
404 } else {
405 DEBUG(1,
406 "ft1000_hw:ft1000_reset_card:resetting ASIC and DSP\n");
407 ft1000_write_reg(dev, FT1000_REG_RESET,
408 (DSP_RESET_BIT | ASIC_RESET_BIT));
409 }
410
588c31ea 411 /* Copy DSP session record into info block if this is not a coldstart */
f7c1be0c
MB
412 if (ft1000_card_present == 1) {
413 spin_lock_irqsave(&info->dpram_lock, flags);
414 if (info->AsicID == ELECTRABUZZ_ID) {
cefe8adb
OZ
415 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
416 FT1000_DPRAM_RX_BASE);
417 for (i = 0; i < MAX_DSP_SESS_REC; i++) {
418 info->DSPSess.Rec[i] =
419 ft1000_read_reg(dev,
420 FT1000_REG_DPRAM_DATA);
f7c1be0c
MB
421 }
422 } else {
423 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
424 FT1000_DPRAM_MAG_RX_BASE);
425 for (i = 0; i < MAX_DSP_SESS_REC / 2; i++) {
426 info->DSPSess.MagRec[i] =
427 inl(dev->base_addr + FT1000_REG_MAG_DPDATA);
428 }
429 }
430 spin_unlock_irqrestore(&info->dpram_lock, flags);
431 }
432
433 DEBUG(1, "ft1000_hw:ft1000_reset_card:resetting ASIC\n");
434 mdelay(10);
588c31ea 435 /* reset ASIC */
f7c1be0c
MB
436 ft1000_reset_asic(dev);
437
f7c1be0c
MB
438 DEBUG(1, "ft1000_hw:ft1000_reset_card:downloading dsp image\n");
439
440 if (info->AsicID == MAGNEMITE_ID) {
588c31ea 441 /* Put dsp in reset and take ASIC out of reset */
f7c1be0c
MB
442 DEBUG(0,
443 "ft1000_hw:ft1000_reset_card:Put DSP in reset and take ASIC out of reset\n");
444 ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT);
445
588c31ea 446 /* Setting MAGNEMITE ASIC to big endian mode */
f7c1be0c 447 ft1000_write_reg(dev, FT1000_REG_SUP_CTRL, HOST_INTF_BE);
588c31ea 448 /* Download bootloader */
f7c1be0c
MB
449 card_bootload(dev);
450
588c31ea 451 /* Take DSP out of reset */
f7c1be0c 452 ft1000_write_reg(dev, FT1000_REG_RESET, 0);
588c31ea 453 /* FLARION_DSP_ACTIVE; */
f7c1be0c
MB
454 mdelay(10);
455 DEBUG(0, "ft1000_hw:ft1000_reset_card:Take DSP out of reset\n");
456
588c31ea 457 /* Wait for 0xfefe indicating dsp ready before starting download */
f7c1be0c
MB
458 for (i = 0; i < 50; i++) {
459 tempword =
460 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DPRAM_FEFE,
461 FT1000_MAG_DPRAM_FEFE_INDX);
462 if (tempword == 0xfefe) {
463 break;
464 }
465 mdelay(20);
466 }
467
468 if (i == 50) {
469 DEBUG(0,
470 "ft1000_hw:ft1000_reset_card:No FEFE detected from DSP\n");
ca145277 471 return false;
f7c1be0c
MB
472 }
473
474 } else {
588c31ea 475 /* Take DSP out of reset */
f7c1be0c
MB
476 ft1000_write_reg(dev, FT1000_REG_RESET, ~DSP_RESET_BIT);
477 mdelay(10);
478 }
479
480 if (card_download(dev, fw_entry->data, fw_entry->size)) {
481 DEBUG(1, "card download unsuccessful\n");
ca145277 482 return false;
f7c1be0c
MB
483 } else {
484 DEBUG(1, "card download successful\n");
485 }
486
487 mdelay(10);
488
489 if (info->AsicID == ELECTRABUZZ_ID) {
588c31ea
DD
490 /*
491 * Need to initialize the FIFO length counter to zero in order to sync up
492 * with the DSP
493 */
f7c1be0c
MB
494 info->fifo_cnt = 0;
495 ft1000_write_dpram(dev, FT1000_FIFO_LEN, info->fifo_cnt);
588c31ea 496 /* Initialize DSP heartbeat area to ho */
f7c1be0c
MB
497 ft1000_write_dpram(dev, FT1000_HI_HO, ho);
498 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
499 DEBUG(1, "ft1000_hw:ft1000_reset_asic:hi_ho value = 0x%x\n",
500 tempword);
501 } else {
588c31ea 502 /* Initialize DSP heartbeat area to ho */
f7c1be0c
MB
503 ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, ho_mag,
504 FT1000_MAG_HI_HO_INDX);
505 tempword =
506 ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO,
507 FT1000_MAG_HI_HO_INDX);
508 DEBUG(1, "ft1000_hw:ft1000_reset_card:hi_ho value = 0x%x\n",
509 tempword);
510 }
511
512 info->CardReady = 1;
513 ft1000_enable_interrupts(dev);
514
515 /* Schedule heartbeat process to run every 2 seconds */
588c31ea
DD
516 /* poll_timer.expires = jiffies + (2*HZ); */
517 /* poll_timer.data = (u_long)dev; */
518 /* add_timer(&poll_timer); */
f7c1be0c 519
ca145277 520 return true;
f7c1be0c
MB
521
522}
523
588c31ea
DD
524/*---------------------------------------------------------------------------
525
526 Function: ft1000_chkcard
527 Description: This function will check if the device is presently available on
528 the system.
529 Input:
530 dev - device structure
531 Output:
532 status - false (device is not present)
533 true (device is present)
534
535 -------------------------------------------------------------------------*/
f7c1be0c
MB
536static int ft1000_chkcard(struct net_device *dev)
537{
538 u16 tempword;
539
588c31ea
DD
540 /*
541 * Mask register is used to check for device presence since it is never
542 * set to zero.
543 */
f7c1be0c
MB
544 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK);
545 if (tempword == 0) {
546 DEBUG(1,
547 "ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n");
ca145277 548 return false;
f7c1be0c 549 }
588c31ea
DD
550 /*
551 * The system will return the value of 0xffff for the version register
552 * if the device is not present.
553 */
f7c1be0c
MB
554 tempword = ft1000_read_reg(dev, FT1000_REG_ASIC_ID);
555 if (tempword == 0xffff) {
556 DEBUG(1,
557 "ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n");
ca145277 558 return false;
f7c1be0c 559 }
ca145277 560 return true;
f7c1be0c
MB
561}
562
563
588c31ea
DD
564/*---------------------------------------------------------------------------
565
566 Function: ft1000_hbchk
567 Description: This function will perform the heart beat check of the DSP as
568 well as the ASIC.
569 Input:
570 dev - device structure
571 Output:
572 none
573
574 -------------------------------------------------------------------------*/
f7c1be0c
MB
575static void ft1000_hbchk(u_long data)
576{
577 struct net_device *dev = (struct net_device *)data;
578
d3706552 579 struct ft1000_info *info;
ca145277 580 u16 tempword;
f7c1be0c 581
e33196e1 582 info = netdev_priv(dev);
f7c1be0c
MB
583
584 if (info->CardReady == 1) {
588c31ea 585 /* Perform dsp heartbeat check */
f7c1be0c
MB
586 if (info->AsicID == ELECTRABUZZ_ID) {
587 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
588 } else {
589 tempword =
590 ntohs(ft1000_read_dpram_mag_16
591 (dev, FT1000_MAG_HI_HO,
592 FT1000_MAG_HI_HO_INDX));
593 }
594 DEBUG(1, "ft1000_hw:ft1000_hbchk:hi_ho value = 0x%x\n",
595 tempword);
588c31ea 596 /* Let's perform another check if ho is not detected */
f7c1be0c
MB
597 if (tempword != ho) {
598 if (info->AsicID == ELECTRABUZZ_ID) {
599 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
600 }
601 else {
602 tempword = ntohs(ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO, FT1000_MAG_HI_HO_INDX));
603 }
bf3146c8 604 }
f7c1be0c
MB
605 if (tempword != ho) {
606 printk(KERN_INFO
607 "ft1000: heartbeat failed - no ho detected\n");
608 if (info->AsicID == ELECTRABUZZ_ID) {
609 info->DSP_TIME[0] =
610 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
611 info->DSP_TIME[1] =
612 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
613 info->DSP_TIME[2] =
614 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
615 info->DSP_TIME[3] =
616 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
617 } else {
618 info->DSP_TIME[0] =
619 ft1000_read_dpram_mag_16(dev,
620 FT1000_MAG_DSP_TIMER0,
621 FT1000_MAG_DSP_TIMER0_INDX);
622 info->DSP_TIME[1] =
623 ft1000_read_dpram_mag_16(dev,
624 FT1000_MAG_DSP_TIMER1,
625 FT1000_MAG_DSP_TIMER1_INDX);
626 info->DSP_TIME[2] =
627 ft1000_read_dpram_mag_16(dev,
628 FT1000_MAG_DSP_TIMER2,
629 FT1000_MAG_DSP_TIMER2_INDX);
630 info->DSP_TIME[3] =
631 ft1000_read_dpram_mag_16(dev,
632 FT1000_MAG_DSP_TIMER3,
633 FT1000_MAG_DSP_TIMER3_INDX);
634 }
635 info->DrvErrNum = DSP_HB_INFO;
636 if (ft1000_reset_card(dev) == 0) {
637 printk(KERN_INFO
638 "ft1000: Hardware Failure Detected - PC Card disabled\n");
639 info->ProgConStat = 0xff;
640 return;
641 }
642 /* Schedule this module to run every 2 seconds */
643 poll_timer.expires = jiffies + (2*HZ);
644 poll_timer.data = (u_long)dev;
645 add_timer(&poll_timer);
646 return;
647 }
648
649 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
588c31ea 650 /* Let's check doorbell again if fail */
f7c1be0c
MB
651 if (tempword & FT1000_DB_HB) {
652 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
bf3146c8 653 }
f7c1be0c
MB
654 if (tempword & FT1000_DB_HB) {
655 printk(KERN_INFO
656 "ft1000: heartbeat doorbell not clear by firmware\n");
657 if (info->AsicID == ELECTRABUZZ_ID) {
658 info->DSP_TIME[0] =
659 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
660 info->DSP_TIME[1] =
661 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
662 info->DSP_TIME[2] =
663 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
664 info->DSP_TIME[3] =
665 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
666 } else {
667 info->DSP_TIME[0] =
668 ft1000_read_dpram_mag_16(dev,
669 FT1000_MAG_DSP_TIMER0,
670 FT1000_MAG_DSP_TIMER0_INDX);
671 info->DSP_TIME[1] =
672 ft1000_read_dpram_mag_16(dev,
673 FT1000_MAG_DSP_TIMER1,
674 FT1000_MAG_DSP_TIMER1_INDX);
675 info->DSP_TIME[2] =
676 ft1000_read_dpram_mag_16(dev,
677 FT1000_MAG_DSP_TIMER2,
678 FT1000_MAG_DSP_TIMER2_INDX);
679 info->DSP_TIME[3] =
680 ft1000_read_dpram_mag_16(dev,
681 FT1000_MAG_DSP_TIMER3,
682 FT1000_MAG_DSP_TIMER3_INDX);
683 }
684 info->DrvErrNum = DSP_HB_INFO;
685 if (ft1000_reset_card(dev) == 0) {
686 printk(KERN_INFO
687 "ft1000: Hardware Failure Detected - PC Card disabled\n");
688 info->ProgConStat = 0xff;
689 return;
690 }
691 /* Schedule this module to run every 2 seconds */
692 poll_timer.expires = jiffies + (2*HZ);
693 poll_timer.data = (u_long)dev;
694 add_timer(&poll_timer);
695 return;
696 }
588c31ea
DD
697 /*
698 * Set dedicated area to hi and ring appropriate doorbell according
699 * to hi/ho heartbeat protocol
700 */
f7c1be0c
MB
701 if (info->AsicID == ELECTRABUZZ_ID) {
702 ft1000_write_dpram(dev, FT1000_HI_HO, hi);
703 } else {
704 ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, hi_mag,
705 FT1000_MAG_HI_HO_INDX);
706 }
707
708 if (info->AsicID == ELECTRABUZZ_ID) {
709 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
710 } else {
711 tempword =
712 ntohs(ft1000_read_dpram_mag_16
713 (dev, FT1000_MAG_HI_HO,
714 FT1000_MAG_HI_HO_INDX));
715 }
588c31ea 716 /* Let's write hi again if fail */
f7c1be0c
MB
717 if (tempword != hi) {
718 if (info->AsicID == ELECTRABUZZ_ID) {
719 ft1000_write_dpram(dev, FT1000_HI_HO, hi);
720 }
721 else {
722 ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, hi_mag, FT1000_MAG_HI_HO_INDX);
723 }
724
725 if (info->AsicID == ELECTRABUZZ_ID) {
726 tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
727 }
728 else {
729 tempword = ntohs(ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO, FT1000_MAG_HI_HO_INDX));
730 }
bf3146c8 731
f7c1be0c 732 }
bf3146c8 733
f7c1be0c
MB
734 if (tempword != hi) {
735 printk(KERN_INFO
736 "ft1000: heartbeat failed - cannot write hi into DPRAM\n");
737 if (info->AsicID == ELECTRABUZZ_ID) {
738 info->DSP_TIME[0] =
739 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
740 info->DSP_TIME[1] =
741 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
742 info->DSP_TIME[2] =
743 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
744 info->DSP_TIME[3] =
745 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
746 } else {
747 info->DSP_TIME[0] =
748 ft1000_read_dpram_mag_16(dev,
749 FT1000_MAG_DSP_TIMER0,
750 FT1000_MAG_DSP_TIMER0_INDX);
751 info->DSP_TIME[1] =
752 ft1000_read_dpram_mag_16(dev,
753 FT1000_MAG_DSP_TIMER1,
754 FT1000_MAG_DSP_TIMER1_INDX);
755 info->DSP_TIME[2] =
756 ft1000_read_dpram_mag_16(dev,
757 FT1000_MAG_DSP_TIMER2,
758 FT1000_MAG_DSP_TIMER2_INDX);
759 info->DSP_TIME[3] =
760 ft1000_read_dpram_mag_16(dev,
761 FT1000_MAG_DSP_TIMER3,
762 FT1000_MAG_DSP_TIMER3_INDX);
763 }
764 info->DrvErrNum = DSP_HB_INFO;
765 if (ft1000_reset_card(dev) == 0) {
766 printk(KERN_INFO
767 "ft1000: Hardware Failure Detected - PC Card disabled\n");
768 info->ProgConStat = 0xff;
769 return;
770 }
771 /* Schedule this module to run every 2 seconds */
772 poll_timer.expires = jiffies + (2*HZ);
773 poll_timer.data = (u_long)dev;
774 add_timer(&poll_timer);
775 return;
776 }
777 ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_HB);
778
779 }
780
781 /* Schedule this module to run every 2 seconds */
782 poll_timer.expires = jiffies + (2 * HZ);
783 poll_timer.data = (u_long) dev;
784 add_timer(&poll_timer);
785}
786
588c31ea
DD
787/*---------------------------------------------------------------------------
788
789 Function: ft1000_send_cmd
790 Description:
791 Input:
792 Output:
793
794 -------------------------------------------------------------------------*/
eb93ca4e 795static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, u16 qtype)
f7c1be0c 796{
d3706552 797 struct ft1000_info *info = netdev_priv(dev);
f7c1be0c
MB
798 int i;
799 u16 tempword;
800 unsigned long flags;
801
e1328c62 802 size += sizeof(struct pseudo_hdr);
588c31ea 803 /* check for odd byte and increment to 16-bit word align value */
f7c1be0c
MB
804 if ((size & 0x0001)) {
805 size++;
806 }
807 DEBUG(1, "FT1000:ft1000_send_cmd:total length = %d\n", size);
808 DEBUG(1, "FT1000:ft1000_send_cmd:length = %d\n", ntohs(*ptempbuffer));
588c31ea
DD
809 /*
810 * put message into slow queue area
811 * All messages are in the form total_len + pseudo header + message body
812 */
f7c1be0c
MB
813 spin_lock_irqsave(&info->dpram_lock, flags);
814
588c31ea 815 /* Make sure SLOWQ doorbell is clear */
f7c1be0c
MB
816 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
817 i=0;
818 while (tempword & FT1000_DB_DPRAM_TX) {
819 mdelay(10);
820 i++;
821 if (i==10) {
822 spin_unlock_irqrestore(&info->dpram_lock, flags);
823 return;
824 }
825 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
826 }
827
828 if (info->AsicID == ELECTRABUZZ_ID) {
829 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
830 FT1000_DPRAM_TX_BASE);
588c31ea 831 /* Write total length to dpram */
f7c1be0c 832 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, size);
588c31ea 833 /* Write pseudo header and messgae body */
f7c1be0c
MB
834 for (i = 0; i < (size >> 1); i++) {
835 DEBUG(1, "FT1000:ft1000_send_cmd:data %d = 0x%x\n", i,
836 *ptempbuffer);
837 tempword = htons(*ptempbuffer++);
838 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, tempword);
839 }
840 } else {
841 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
842 FT1000_DPRAM_MAG_TX_BASE);
588c31ea 843 /* Write total length to dpram */
f7c1be0c 844 ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAH, htons(size));
588c31ea 845 /* Write pseudo header and messgae body */
f7c1be0c
MB
846 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
847 FT1000_DPRAM_MAG_TX_BASE + 1);
848 for (i = 0; i < (size >> 2); i++) {
849 DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n",
850 *ptempbuffer);
851 outw(*ptempbuffer++,
852 dev->base_addr + FT1000_REG_MAG_DPDATAL);
853 DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n",
854 *ptempbuffer);
855 outw(*ptempbuffer++,
856 dev->base_addr + FT1000_REG_MAG_DPDATAH);
857 }
858 DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n", *ptempbuffer);
859 outw(*ptempbuffer++, dev->base_addr + FT1000_REG_MAG_DPDATAL);
860 DEBUG(1, "FT1000:ft1000_send_cmd:data = 0x%x\n", *ptempbuffer);
861 outw(*ptempbuffer++, dev->base_addr + FT1000_REG_MAG_DPDATAH);
862 }
863 spin_unlock_irqrestore(&info->dpram_lock, flags);
864
588c31ea 865 /* ring doorbell to notify DSP that we have a message ready */
f7c1be0c
MB
866 ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_DPRAM_TX);
867}
868
588c31ea
DD
869/*---------------------------------------------------------------------------
870
871 Function: ft1000_receive_cmd
872 Description: This function will read a message from the dpram area.
873 Input:
874 dev - network device structure
875 pbuffer - caller supply address to buffer
876 pnxtph - pointer to next pseudo header
877 Output:
878 Status = 0 (unsuccessful)
879 = 1 (successful)
880
881 -------------------------------------------------------------------------*/
eb93ca4e
RD
882static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer,
883 int maxsz, u16 *pnxtph)
f7c1be0c 884{
d3706552 885 struct ft1000_info *info = netdev_priv(dev);
f7c1be0c
MB
886 u16 size;
887 u16 *ppseudohdr;
888 int i;
889 u16 tempword;
890 unsigned long flags;
891
892 if (info->AsicID == ELECTRABUZZ_ID) {
e1328c62 893 size = ( ft1000_read_dpram(dev, *pnxtph) ) + sizeof(struct pseudo_hdr);
f7c1be0c
MB
894 } else {
895 size =
896 ntohs(ft1000_read_dpram_mag_16
897 (dev, FT1000_MAG_PH_LEN,
e1328c62 898 FT1000_MAG_PH_LEN_INDX)) + sizeof(struct pseudo_hdr);
f7c1be0c
MB
899 }
900 if (size > maxsz) {
901 DEBUG(1,
902 "FT1000:ft1000_receive_cmd:Invalid command length = %d\n",
903 size);
ca145277 904 return false;
f7c1be0c
MB
905 } else {
906 ppseudohdr = (u16 *) pbuffer;
907 spin_lock_irqsave(&info->dpram_lock, flags);
908 if (info->AsicID == ELECTRABUZZ_ID) {
909 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
910 FT1000_DPRAM_RX_BASE + 2);
911 for (i = 0; i <= (size >> 1); i++) {
912 tempword =
913 ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
914 *pbuffer++ = ntohs(tempword);
915 }
916 } else {
917 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
918 FT1000_DPRAM_MAG_RX_BASE);
919 *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAH);
920 DEBUG(1, "ft1000_hw:received data = 0x%x\n", *pbuffer);
921 pbuffer++;
922 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
923 FT1000_DPRAM_MAG_RX_BASE + 1);
924 for (i = 0; i <= (size >> 2); i++) {
925 *pbuffer =
926 inw(dev->base_addr +
927 FT1000_REG_MAG_DPDATAL);
928 pbuffer++;
929 *pbuffer =
930 inw(dev->base_addr +
931 FT1000_REG_MAG_DPDATAH);
932 pbuffer++;
933 }
588c31ea 934 /* copy odd aligned word */
f7c1be0c
MB
935 *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAL);
936 DEBUG(1, "ft1000_hw:received data = 0x%x\n", *pbuffer);
937 pbuffer++;
938 *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAH);
939 DEBUG(1, "ft1000_hw:received data = 0x%x\n", *pbuffer);
940 pbuffer++;
941 }
942 if (size & 0x0001) {
588c31ea 943 /* copy odd byte from fifo */
f7c1be0c
MB
944 tempword = ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA);
945 *pbuffer = ntohs(tempword);
946 }
947 spin_unlock_irqrestore(&info->dpram_lock, flags);
948
588c31ea
DD
949 /*
950 * Check if pseudo header checksum is good
951 * Calculate pseudo header checksum
952 */
f7c1be0c
MB
953 tempword = *ppseudohdr++;
954 for (i = 1; i < 7; i++) {
955 tempword ^= *ppseudohdr++;
956 }
957 if ((tempword != *ppseudohdr)) {
958 DEBUG(1,
959 "FT1000:ft1000_receive_cmd:Pseudo header checksum mismatch\n");
588c31ea 960 /* Drop this message */
ca145277 961 return false;
f7c1be0c 962 }
ca145277 963 return true;
f7c1be0c
MB
964 }
965}
966
588c31ea
DD
967/*---------------------------------------------------------------------------
968
969 Function: ft1000_proc_drvmsg
970 Description: This function will process the various driver messages.
971 Input:
972 dev - device structure
973 pnxtph - pointer to next pseudo header
974 Output:
975 none
976
977 -------------------------------------------------------------------------*/
eb93ca4e 978static void ft1000_proc_drvmsg(struct net_device *dev)
f7c1be0c 979{
d3706552 980 struct ft1000_info *info = netdev_priv(dev);
f7c1be0c
MB
981 u16 msgtype;
982 u16 tempword;
24c5b19e 983 struct media_msg *pmediamsg;
2cbdcdc1 984 struct dsp_init_msg *pdspinitmsg;
8bc0d6fb 985 struct drv_msg *pdrvmsg;
f7c1be0c
MB
986 u16 len;
987 u16 i;
3aaf8073 988 struct prov_record *ptr;
2c9bf839 989 struct pseudo_hdr *ppseudo_hdr;
ca145277 990 u16 *pmsg;
f7c1be0c
MB
991 struct timeval tv;
992 union {
993 u8 byte[2];
994 u16 wrd;
995 } convert;
996
997 if (info->AsicID == ELECTRABUZZ_ID) {
998 tempword = FT1000_DPRAM_RX_BASE+2;
999 }
1000 else {
1001 tempword = FT1000_DPRAM_MAG_RX_BASE;
1002 }
1003 if ( ft1000_receive_cmd(dev, &cmdbuffer[0], MAX_CMD_SQSIZE, &tempword) ) {
1004
588c31ea 1005 /* Get the message type which is total_len + PSEUDO header + msgtype + message body */
8bc0d6fb 1006 pdrvmsg = (struct drv_msg *) & cmdbuffer[0];
f7c1be0c
MB
1007 msgtype = ntohs(pdrvmsg->type);
1008 DEBUG(1, "Command message type = 0x%x\n", msgtype);
1009 switch (msgtype) {
1010 case DSP_PROVISION:
1011 DEBUG(0,
1012 "Got a provisioning request message from DSP\n");
1013 mdelay(25);
1014 while (list_empty(&info->prov_list) == 0) {
1015 DEBUG(0, "Sending a provisioning message\n");
588c31ea 1016 /* Make sure SLOWQ doorbell is clear */
f7c1be0c
MB
1017 tempword =
1018 ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1019 i = 0;
1020 while (tempword & FT1000_DB_DPRAM_TX) {
1021 mdelay(5);
1022 i++;
1023 if (i == 10) {
1024 break;
1025 }
1026 }
1027 ptr =
1028 list_entry(info->prov_list.next,
3aaf8073 1029 struct prov_record, list);
f7c1be0c
MB
1030 len = *(u16 *) ptr->pprov_data;
1031 len = htons(len);
1032
ca145277 1033 pmsg = (u16 *) ptr->pprov_data;
2c9bf839 1034 ppseudo_hdr = (struct pseudo_hdr *) pmsg;
588c31ea 1035 /* Insert slow queue sequence number */
f7c1be0c
MB
1036 ppseudo_hdr->seq_num = info->squeseqnum++;
1037 ppseudo_hdr->portsrc = 0;
588c31ea 1038 /* Calculate new checksum */
f7c1be0c
MB
1039 ppseudo_hdr->checksum = *pmsg++;
1040 DEBUG(1, "checksum = 0x%x\n",
1041 ppseudo_hdr->checksum);
1042 for (i = 1; i < 7; i++) {
1043 ppseudo_hdr->checksum ^= *pmsg++;
1044 DEBUG(1, "checksum = 0x%x\n",
1045 ppseudo_hdr->checksum);
1046 }
1047
1048 ft1000_send_cmd (dev, (u16 *)ptr->pprov_data, len, SLOWQ_TYPE);
1049 list_del(&ptr->list);
1050 kfree(ptr->pprov_data);
1051 kfree(ptr);
1052 }
588c31ea
DD
1053 /*
1054 * Indicate adapter is ready to take application messages after all
1055 * provisioning messages are sent
1056 */
f7c1be0c
MB
1057 info->CardReady = 1;
1058 break;
1059 case MEDIA_STATE:
24c5b19e 1060 pmediamsg = (struct media_msg *) & cmdbuffer[0];
f7c1be0c
MB
1061 if (info->ProgConStat != 0xFF) {
1062 if (pmediamsg->state) {
1063 DEBUG(1, "Media is up\n");
1064 if (info->mediastate == 0) {
1065 netif_carrier_on(dev);
1066 netif_wake_queue(dev);
1067 info->mediastate = 1;
1068 do_gettimeofday(&tv);
1069 info->ConTm = tv.tv_sec;
1070 }
1071 } else {
1072 DEBUG(1, "Media is down\n");
1073 if (info->mediastate == 1) {
1074 info->mediastate = 0;
1075 netif_carrier_off(dev);
1076 netif_stop_queue(dev);
1077 info->ConTm = 0;
bf3146c8 1078 }
f7c1be0c
MB
1079 }
1080 }
1081 else {
1082 DEBUG(1,"Media is down\n");
1083 if (info->mediastate == 1) {
1084 info->mediastate = 0;
1085 netif_carrier_off(dev);
1086 netif_stop_queue(dev);
1087 info->ConTm = 0;
1088 }
1089 }
1090 break;
1091 case DSP_INIT_MSG:
2cbdcdc1 1092 pdspinitmsg = (struct dsp_init_msg *) & cmdbuffer[0];
f7c1be0c
MB
1093 memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ);
1094 DEBUG(1, "DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n",
1095 info->DspVer[0], info->DspVer[1], info->DspVer[2],
1096 info->DspVer[3]);
1097 memcpy(info->HwSerNum, pdspinitmsg->HwSerNum,
1098 HWSERNUMSZ);
1099 memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ);
1100 memcpy(info->eui64, pdspinitmsg->eui64, EUISZ);
1101 dev->dev_addr[0] = info->eui64[0];
1102 dev->dev_addr[1] = info->eui64[1];
1103 dev->dev_addr[2] = info->eui64[2];
1104 dev->dev_addr[3] = info->eui64[5];
1105 dev->dev_addr[4] = info->eui64[6];
1106 dev->dev_addr[5] = info->eui64[7];
1107
1108 if (ntohs(pdspinitmsg->length) ==
2cbdcdc1 1109 (sizeof(struct dsp_init_msg) - 20)) {
f7c1be0c
MB
1110 memcpy(info->ProductMode,
1111 pdspinitmsg->ProductMode, MODESZ);
1112 memcpy(info->RfCalVer, pdspinitmsg->RfCalVer,
1113 CALVERSZ);
1114 memcpy(info->RfCalDate, pdspinitmsg->RfCalDate,
1115 CALDATESZ);
1116 DEBUG(1, "RFCalVer = 0x%2x 0x%2x\n",
1117 info->RfCalVer[0], info->RfCalVer[1]);
1118 }
1119
1120 break ;
1121 case DSP_STORE_INFO:
1122 DEBUG(1, "FT1000:drivermsg:Got DSP_STORE_INFO\n");
1123 tempword = ntohs(pdrvmsg->length);
1124 info->DSPInfoBlklen = tempword;
1125 if (tempword < (MAX_DSP_SESS_REC - 4)) {
ca145277 1126 pmsg = (u16 *) & pdrvmsg->data[0];
f7c1be0c
MB
1127 for (i = 0; i < ((tempword + 1) / 2); i++) {
1128 DEBUG(1,
1129 "FT1000:drivermsg:dsp info data = 0x%x\n",
1130 *pmsg);
1131 info->DSPInfoBlk[i + 10] = *pmsg++;
1132 }
1133 }
1134 break;
1135 case DSP_GET_INFO:
1136 DEBUG(1, "FT1000:drivermsg:Got DSP_GET_INFO\n");
588c31ea
DD
1137 /*
1138 * copy dsp info block to dsp
1139 * allow any outstanding ioctl to finish
1140 */
f7c1be0c
MB
1141 mdelay(10);
1142 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1143 if (tempword & FT1000_DB_DPRAM_TX) {
1144 mdelay(10);
1145 tempword =
1146 ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1147 if (tempword & FT1000_DB_DPRAM_TX) {
1148 mdelay(10);
1149 }
1150 }
1151
1152 if ((tempword & FT1000_DB_DPRAM_TX) == 0) {
588c31ea
DD
1153 /*
1154 * Put message into Slow Queue
1155 * Form Pseudo header
1156 */
ca145277 1157 pmsg = (u16 *) info->DSPInfoBlk;
2c9bf839 1158 ppseudo_hdr = (struct pseudo_hdr *) pmsg;
f7c1be0c
MB
1159 ppseudo_hdr->length =
1160 htons(info->DSPInfoBlklen + 4);
1161 ppseudo_hdr->source = 0x10;
1162 ppseudo_hdr->destination = 0x20;
1163 ppseudo_hdr->portdest = 0;
1164 ppseudo_hdr->portsrc = 0;
1165 ppseudo_hdr->sh_str_id = 0;
1166 ppseudo_hdr->control = 0;
1167 ppseudo_hdr->rsvd1 = 0;
1168 ppseudo_hdr->rsvd2 = 0;
1169 ppseudo_hdr->qos_class = 0;
588c31ea 1170 /* Insert slow queue sequence number */
f7c1be0c 1171 ppseudo_hdr->seq_num = info->squeseqnum++;
588c31ea 1172 /* Insert application id */
f7c1be0c 1173 ppseudo_hdr->portsrc = 0;
588c31ea 1174 /* Calculate new checksum */
f7c1be0c
MB
1175 ppseudo_hdr->checksum = *pmsg++;
1176 for (i = 1; i < 7; i++) {
1177 ppseudo_hdr->checksum ^= *pmsg++;
1178 }
1179 info->DSPInfoBlk[8] = 0x7200;
1180 info->DSPInfoBlk[9] =
1181 htons(info->DSPInfoBlklen);
ca145277 1182 ft1000_send_cmd (dev, (u16 *)info->DSPInfoBlk, (u16)(info->DSPInfoBlklen+4), 0);
f7c1be0c 1183 }
f7c1be0c
MB
1184
1185 break;
1186 case GET_DRV_ERR_RPT_MSG:
1187 DEBUG(1, "FT1000:drivermsg:Got GET_DRV_ERR_RPT_MSG\n");
588c31ea
DD
1188 /*
1189 * copy driver error message to dsp
1190 * allow any outstanding ioctl to finish
1191 */
f7c1be0c
MB
1192 mdelay(10);
1193 tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1194 if (tempword & FT1000_DB_DPRAM_TX) {
1195 mdelay(10);
1196 tempword =
1197 ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1198 if (tempword & FT1000_DB_DPRAM_TX) {
1199 mdelay(10);
1200 }
1201 }
1202
1203 if ((tempword & FT1000_DB_DPRAM_TX) == 0) {
588c31ea
DD
1204 /*
1205 * Put message into Slow Queue
1206 * Form Pseudo header
1207 */
ca145277 1208 pmsg = (u16 *) & tempbuffer[0];
2c9bf839 1209 ppseudo_hdr = (struct pseudo_hdr *) pmsg;
f7c1be0c
MB
1210 ppseudo_hdr->length = htons(0x0012);
1211 ppseudo_hdr->source = 0x10;
1212 ppseudo_hdr->destination = 0x20;
1213 ppseudo_hdr->portdest = 0;
1214 ppseudo_hdr->portsrc = 0;
1215 ppseudo_hdr->sh_str_id = 0;
1216 ppseudo_hdr->control = 0;
1217 ppseudo_hdr->rsvd1 = 0;
1218 ppseudo_hdr->rsvd2 = 0;
1219 ppseudo_hdr->qos_class = 0;
588c31ea 1220 /* Insert slow queue sequence number */
f7c1be0c 1221 ppseudo_hdr->seq_num = info->squeseqnum++;
588c31ea 1222 /* Insert application id */
f7c1be0c 1223 ppseudo_hdr->portsrc = 0;
588c31ea 1224 /* Calculate new checksum */
f7c1be0c
MB
1225 ppseudo_hdr->checksum = *pmsg++;
1226 for (i=1; i<7; i++) {
1227 ppseudo_hdr->checksum ^= *pmsg++;
1228 }
ca145277 1229 pmsg = (u16 *) & tempbuffer[16];
f7c1be0c
MB
1230 *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG);
1231 *pmsg++ = htons(0x000e);
1232 *pmsg++ = htons(info->DSP_TIME[0]);
1233 *pmsg++ = htons(info->DSP_TIME[1]);
1234 *pmsg++ = htons(info->DSP_TIME[2]);
1235 *pmsg++ = htons(info->DSP_TIME[3]);
1236 convert.byte[0] = info->DspVer[0];
1237 convert.byte[1] = info->DspVer[1];
1238 *pmsg++ = convert.wrd;
1239 convert.byte[0] = info->DspVer[2];
1240 convert.byte[1] = info->DspVer[3];
1241 *pmsg++ = convert.wrd;
1242 *pmsg++ = htons(info->DrvErrNum);
1243
ca145277 1244 ft1000_send_cmd (dev, (u16 *)&tempbuffer[0], (u16)(0x0012), 0);
f7c1be0c
MB
1245 info->DrvErrNum = 0;
1246 }
f7c1be0c
MB
1247
1248 break;
1249 default:
1250 break;
1251 }
1252 }
1253}
1254
588c31ea
DD
1255/*---------------------------------------------------------------------------
1256
1257 Function: ft1000_parse_dpram_msg
1258 Description: This function will parse the message received from the DSP
1259 via the DPRAM interface.
1260 Input:
1261 dev - device structure
1262 Output:
1263 status - FAILURE
1264 SUCCESS
1265
1266 -------------------------------------------------------------------------*/
eb93ca4e 1267static int ft1000_parse_dpram_msg(struct net_device *dev)
f7c1be0c 1268{
d3706552 1269 struct ft1000_info *info = netdev_priv(dev);
f7c1be0c
MB
1270 u16 doorbell;
1271 u16 portid;
1272 u16 nxtph;
1273 u16 total_len;
1274 int i = 0;
1275 int cnt;
1276 unsigned long flags;
1277
1278 doorbell = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
1279 DEBUG(1, "Doorbell = 0x%x\n", doorbell);
1280
1281 if (doorbell & FT1000_ASIC_RESET_REQ) {
588c31ea 1282 /* Copy DSP session record from info block */
f7c1be0c
MB
1283 spin_lock_irqsave(&info->dpram_lock, flags);
1284 if (info->AsicID == ELECTRABUZZ_ID) {
1285 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
1286 FT1000_DPRAM_RX_BASE);
1287 for (i = 0; i < MAX_DSP_SESS_REC; i++) {
1288 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA,
1289 info->DSPSess.Rec[i]);
1290 }
1291 } else {
1292 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR,
1293 FT1000_DPRAM_MAG_RX_BASE);
1294 for (i = 0; i < MAX_DSP_SESS_REC / 2; i++) {
1295 outl(info->DSPSess.MagRec[i],
1296 dev->base_addr + FT1000_REG_MAG_DPDATA);
1297 }
1298 }
1299 spin_unlock_irqrestore(&info->dpram_lock, flags);
1300
588c31ea 1301 /* clear ASIC RESET request */
f7c1be0c
MB
1302 ft1000_write_reg(dev, FT1000_REG_DOORBELL,
1303 FT1000_ASIC_RESET_REQ);
1304 DEBUG(1, "Got an ASIC RESET Request\n");
1305 ft1000_write_reg(dev, FT1000_REG_DOORBELL,
1306 FT1000_ASIC_RESET_DSP);
1307
1308 if (info->AsicID == MAGNEMITE_ID) {
588c31ea 1309 /* Setting MAGNEMITE ASIC to big endian mode */
f7c1be0c
MB
1310 ft1000_write_reg(dev, FT1000_REG_SUP_CTRL,
1311 HOST_INTF_BE);
1312 }
f7c1be0c
MB
1313 }
1314
1315 if (doorbell & FT1000_DSP_ASIC_RESET) {
1316 DEBUG(0,
1317 "FT1000:ft1000_parse_dpram_msg: Got a dsp ASIC reset message\n");
f7c1be0c
MB
1318 ft1000_write_reg(dev, FT1000_REG_DOORBELL,
1319 FT1000_DSP_ASIC_RESET);
1320 udelay(200);
1321 return SUCCESS;
1322 }
1323
1324 if (doorbell & FT1000_DB_DPRAM_RX) {
1325 DEBUG(1,
1326 "FT1000:ft1000_parse_dpram_msg: Got a slow queue message\n");
1327 nxtph = FT1000_DPRAM_RX_BASE + 2;
1328 if (info->AsicID == ELECTRABUZZ_ID) {
1329 total_len =
1330 ft1000_read_dpram(dev, FT1000_DPRAM_RX_BASE);
1331 } else {
1332 total_len =
1333 ntohs(ft1000_read_dpram_mag_16
1334 (dev, FT1000_MAG_TOTAL_LEN,
1335 FT1000_MAG_TOTAL_LEN_INDX));
1336 }
1337 DEBUG(1, "FT1000:ft1000_parse_dpram_msg:total length = %d\n",
1338 total_len);
e1328c62 1339 if ((total_len < MAX_CMD_SQSIZE) && (total_len > sizeof(struct pseudo_hdr))) {
f7c1be0c
MB
1340 total_len += nxtph;
1341 cnt = 0;
588c31ea
DD
1342 /*
1343 * ft1000_read_reg will return a value that needs to be byteswap
1344 * in order to get DSP_QID_OFFSET.
1345 */
f7c1be0c
MB
1346 if (info->AsicID == ELECTRABUZZ_ID) {
1347 portid =
1348 (ft1000_read_dpram
1349 (dev,
1350 DSP_QID_OFFSET + FT1000_DPRAM_RX_BASE +
1351 2) >> 8) & 0xff;
1352 } else {
1353 portid =
1354 (ft1000_read_dpram_mag_16
1355 (dev, FT1000_MAG_PORT_ID,
1356 FT1000_MAG_PORT_ID_INDX) & 0xff);
1357 }
1358 DEBUG(1, "DSP_QID = 0x%x\n", portid);
1359
1360 if (portid == DRIVERID) {
588c31ea 1361 /* We are assumming one driver message from the DSP at a time. */
f7c1be0c
MB
1362 ft1000_proc_drvmsg(dev);
1363 }
1364 }
1365 ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_DPRAM_RX);
1366 }
1367
1368 if (doorbell & FT1000_DB_COND_RESET) {
588c31ea 1369 /* Reset ASIC and DSP */
f7c1be0c
MB
1370 if (info->AsicID == ELECTRABUZZ_ID) {
1371 info->DSP_TIME[0] =
1372 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
1373 info->DSP_TIME[1] =
1374 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
1375 info->DSP_TIME[2] =
1376 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
1377 info->DSP_TIME[3] =
1378 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
1379 } else {
1380 info->DSP_TIME[0] =
1381 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER0,
1382 FT1000_MAG_DSP_TIMER0_INDX);
1383 info->DSP_TIME[1] =
1384 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER1,
1385 FT1000_MAG_DSP_TIMER1_INDX);
1386 info->DSP_TIME[2] =
1387 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER2,
1388 FT1000_MAG_DSP_TIMER2_INDX);
1389 info->DSP_TIME[3] =
1390 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER3,
1391 FT1000_MAG_DSP_TIMER3_INDX);
1392 }
1393 info->DrvErrNum = DSP_CONDRESET_INFO;
1394 DEBUG(1, "ft1000_hw:DSP conditional reset requested\n");
1395 ft1000_reset_card(dev);
1396 ft1000_write_reg(dev, FT1000_REG_DOORBELL,
1397 FT1000_DB_COND_RESET);
1398 }
588c31ea 1399 /* let's clear any unexpected doorbells from DSP */
f7c1be0c
MB
1400 doorbell =
1401 doorbell & ~(FT1000_DB_DPRAM_RX | FT1000_ASIC_RESET_REQ |
1402 FT1000_DB_COND_RESET | 0xff00);
1403 if (doorbell) {
1404 DEBUG(1, "Clearing unexpected doorbell = 0x%x\n", doorbell);
1405 ft1000_write_reg(dev, FT1000_REG_DOORBELL, doorbell);
1406 }
1407
1408 return SUCCESS;
1409
1410}
1411
588c31ea
DD
1412/*---------------------------------------------------------------------------
1413
1414 Function: ft1000_flush_fifo
1415 Description: This function will flush one packet from the downlink
1416 FIFO.
1417 Input:
1418 dev - device structure
1419 drv_err - driver error causing the flush fifo
1420 Output:
1421 None.
1422
1423 -------------------------------------------------------------------------*/
f7c1be0c
MB
1424static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum)
1425{
d3706552 1426 struct ft1000_info *info = netdev_priv(dev);
3aa2303a 1427 struct ft1000_pcmcia *pcmcia = info->priv;
f7c1be0c
MB
1428 u16 i;
1429 u32 templong;
1430 u16 tempword;
1431
1432 DEBUG(1, "ft1000:ft1000_hw:ft1000_flush_fifo called\n");
3aa2303a 1433 if (pcmcia->PktIntfErr > MAX_PH_ERR) {
f7c1be0c
MB
1434 if (info->AsicID == ELECTRABUZZ_ID) {
1435 info->DSP_TIME[0] =
1436 ft1000_read_dpram(dev, FT1000_DSP_TIMER0);
1437 info->DSP_TIME[1] =
1438 ft1000_read_dpram(dev, FT1000_DSP_TIMER1);
1439 info->DSP_TIME[2] =
1440 ft1000_read_dpram(dev, FT1000_DSP_TIMER2);
1441 info->DSP_TIME[3] =
1442 ft1000_read_dpram(dev, FT1000_DSP_TIMER3);
1443 } else {
1444 info->DSP_TIME[0] =
1445 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER0,
1446 FT1000_MAG_DSP_TIMER0_INDX);
1447 info->DSP_TIME[1] =
1448 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER1,
1449 FT1000_MAG_DSP_TIMER1_INDX);
1450 info->DSP_TIME[2] =
1451 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER2,
1452 FT1000_MAG_DSP_TIMER2_INDX);
1453 info->DSP_TIME[3] =
1454 ft1000_read_dpram_mag_16(dev, FT1000_MAG_DSP_TIMER3,
1455 FT1000_MAG_DSP_TIMER3_INDX);
1456 }
1457 info->DrvErrNum = DrvErrNum;
1458 ft1000_reset_card(dev);
1459 return;
1460 } else {
588c31ea 1461 /* Flush corrupted pkt from FIFO */
f7c1be0c
MB
1462 i = 0;
1463 do {
1464 if (info->AsicID == ELECTRABUZZ_ID) {
1465 tempword =
1466 ft1000_read_reg(dev, FT1000_REG_DFIFO);
1467 tempword =
1468 ft1000_read_reg(dev, FT1000_REG_DFIFO_STAT);
1469 } else {
1470 templong =
1471 inl(dev->base_addr + FT1000_REG_MAG_DFR);
1472 tempword =
1473 inw(dev->base_addr + FT1000_REG_MAG_DFSR);
1474 }
1475 i++;
588c31ea
DD
1476 /*
1477 * This should never happen unless the ASIC is broken.
1478 * We must reset to recover.
1479 */
f7c1be0c
MB
1480 if ((i > 2048) || (tempword == 0)) {
1481 if (info->AsicID == ELECTRABUZZ_ID) {
1482 info->DSP_TIME[0] =
1483 ft1000_read_dpram(dev,
1484 FT1000_DSP_TIMER0);
1485 info->DSP_TIME[1] =
1486 ft1000_read_dpram(dev,
1487 FT1000_DSP_TIMER1);
1488 info->DSP_TIME[2] =
1489 ft1000_read_dpram(dev,
1490 FT1000_DSP_TIMER2);
1491 info->DSP_TIME[3] =
1492 ft1000_read_dpram(dev,
1493 FT1000_DSP_TIMER3);
1494 } else {
1495 info->DSP_TIME[0] =
1496 ft1000_read_dpram_mag_16(dev,
1497 FT1000_MAG_DSP_TIMER0,
1498 FT1000_MAG_DSP_TIMER0_INDX);
1499 info->DSP_TIME[1] =
1500 ft1000_read_dpram_mag_16(dev,
1501 FT1000_MAG_DSP_TIMER1,
1502 FT1000_MAG_DSP_TIMER1_INDX);
1503 info->DSP_TIME[2] =
1504 ft1000_read_dpram_mag_16(dev,
1505 FT1000_MAG_DSP_TIMER2,
1506 FT1000_MAG_DSP_TIMER2_INDX);
1507 info->DSP_TIME[3] =
1508 ft1000_read_dpram_mag_16(dev,
1509 FT1000_MAG_DSP_TIMER3,
1510 FT1000_MAG_DSP_TIMER3_INDX);
1511 }
1512 if (tempword == 0) {
588c31ea
DD
1513 /*
1514 * Let's check if ASIC reads are still ok by reading the Mask register
1515 * which is never zero at this point of the code.
1516 */
f7c1be0c
MB
1517 tempword =
1518 inw(dev->base_addr +
1519 FT1000_REG_SUP_IMASK);
1520 if (tempword == 0) {
588c31ea 1521 /* This indicates that we can not communicate with the ASIC */
f7c1be0c
MB
1522 info->DrvErrNum =
1523 FIFO_FLUSH_BADCNT;
1524 } else {
588c31ea 1525 /* Let's assume that we really flush the FIFO */
3aa2303a 1526 pcmcia->PktIntfErr++;
f7c1be0c
MB
1527 return;
1528 }
1529 } else {
1530 info->DrvErrNum = FIFO_FLUSH_MAXLIMIT;
1531 }
1532 return;
1533 }
1534 tempword = inw(dev->base_addr + FT1000_REG_SUP_STAT);
1535 } while ((tempword & 0x03) != 0x03);
1536 if (info->AsicID == ELECTRABUZZ_ID) {
1537 i++;
1538 DEBUG(0, "Flushing FIFO complete = %x\n", tempword);
588c31ea 1539 /* Flush last word in FIFO. */
f7c1be0c 1540 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
588c31ea 1541 /* Update FIFO counter for DSP */
f7c1be0c
MB
1542 i = i * 2;
1543 DEBUG(0, "Flush Data byte count to dsp = %d\n", i);
1544 info->fifo_cnt += i;
1545 ft1000_write_dpram(dev, FT1000_FIFO_LEN,
1546 info->fifo_cnt);
1547 } else {
1548 DEBUG(0, "Flushing FIFO complete = %x\n", tempword);
588c31ea 1549 /* Flush last word in FIFO */
f7c1be0c
MB
1550 templong = inl(dev->base_addr + FT1000_REG_MAG_DFR);
1551 tempword = inw(dev->base_addr + FT1000_REG_SUP_STAT);
1552 DEBUG(0, "FT1000_REG_SUP_STAT = 0x%x\n", tempword);
1553 tempword = inw(dev->base_addr + FT1000_REG_MAG_DFSR);
1554 DEBUG(0, "FT1000_REG_MAG_DFSR = 0x%x\n", tempword);
1555 }
1556 if (DrvErrNum) {
3aa2303a 1557 pcmcia->PktIntfErr++;
f7c1be0c
MB
1558 }
1559 }
1560}
1561
588c31ea
DD
1562/*---------------------------------------------------------------------------
1563
1564 Function: ft1000_copy_up_pkt
1565 Description: This function will pull Flarion packets out of the Downlink
1566 FIFO and convert it to an ethernet packet. The ethernet packet will
1567 then be deliver to the TCP/IP stack.
1568 Input:
1569 dev - device structure
1570 Output:
1571 status - FAILURE
1572 SUCCESS
1573
1574 -------------------------------------------------------------------------*/
eb93ca4e 1575static int ft1000_copy_up_pkt(struct net_device *dev)
f7c1be0c
MB
1576{
1577 u16 tempword;
d3706552 1578 struct ft1000_info *info = netdev_priv(dev);
f7c1be0c
MB
1579 u16 len;
1580 struct sk_buff *skb;
1581 u16 i;
1582 u8 *pbuffer = NULL;
1583 u8 *ptemp = NULL;
1584 u16 chksum;
1585 u32 *ptemplong;
1586 u32 templong;
1587
1588 DEBUG(1, "ft1000_copy_up_pkt\n");
588c31ea 1589 /* Read length */
f7c1be0c
MB
1590 if (info->AsicID == ELECTRABUZZ_ID) {
1591 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1592 len = tempword;
1593 } else {
1594 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
1595 len = ntohs(tempword);
1596 }
1597 chksum = tempword;
1598 DEBUG(1, "Number of Bytes in FIFO = %d\n", len);
1599
1600 if (len > ENET_MAX_SIZE) {
1601 DEBUG(0, "size of ethernet packet invalid\n");
1602 if (info->AsicID == MAGNEMITE_ID) {
588c31ea 1603 /* Read High word to complete 32 bit access */
f7c1be0c
MB
1604 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1605 }
1606 ft1000_flush_fifo(dev, DSP_PKTLEN_INFO);
1607 info->stats.rx_errors++;
1608 return FAILURE;
1609 }
1610
1611 skb = dev_alloc_skb(len + 12 + 2);
1612
1613 if (skb == NULL) {
1614 DEBUG(0, "No Network buffers available\n");
588c31ea 1615 /* Read High word to complete 32 bit access */
f7c1be0c
MB
1616 if (info->AsicID == MAGNEMITE_ID) {
1617 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1618 }
1619 ft1000_flush_fifo(dev, 0);
1620 info->stats.rx_errors++;
1621 return FAILURE;
1622 }
1623 pbuffer = (u8 *) skb_put(skb, len + 12);
1624
588c31ea 1625 /* Pseudo header */
f7c1be0c
MB
1626 if (info->AsicID == ELECTRABUZZ_ID) {
1627 for (i = 1; i < 7; i++) {
1628 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1629 chksum ^= tempword;
1630 }
588c31ea 1631 /* read checksum value */
f7c1be0c
MB
1632 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1633 } else {
1634 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1635 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1636 chksum ^= tempword;
1637
1638 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
1639 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1640 chksum ^= tempword;
1641
1642 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1643 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1644 chksum ^= tempword;
1645
1646 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
1647 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1648 chksum ^= tempword;
1649
1650 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1651 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1652 chksum ^= tempword;
1653
1654 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRL);
1655 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1656 chksum ^= tempword;
1657
588c31ea 1658 /* read checksum value */
f7c1be0c
MB
1659 tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
1660 DEBUG(1, "Pseudo = 0x%x\n", tempword);
1661 }
1662
1663 if (chksum != tempword) {
1664 DEBUG(0, "Packet checksum mismatch 0x%x 0x%x\n", chksum,
1665 tempword);
1666 ft1000_flush_fifo(dev, DSP_PKTPHCKSUM_INFO);
1667 info->stats.rx_errors++;
c95aef41 1668 kfree_skb(skb);
f7c1be0c
MB
1669 return FAILURE;
1670 }
588c31ea 1671 /* subtract the number of bytes read already */
f7c1be0c
MB
1672 ptemp = pbuffer;
1673
588c31ea 1674 /* fake MAC address */
f7c1be0c
MB
1675 *pbuffer++ = dev->dev_addr[0];
1676 *pbuffer++ = dev->dev_addr[1];
1677 *pbuffer++ = dev->dev_addr[2];
1678 *pbuffer++ = dev->dev_addr[3];
1679 *pbuffer++ = dev->dev_addr[4];
1680 *pbuffer++ = dev->dev_addr[5];
1681 *pbuffer++ = 0x00;
1682 *pbuffer++ = 0x07;
1683 *pbuffer++ = 0x35;
1684 *pbuffer++ = 0xff;
1685 *pbuffer++ = 0xff;
1686 *pbuffer++ = 0xfe;
1687
1688 if (info->AsicID == ELECTRABUZZ_ID) {
1689 for (i = 0; i < len / 2; i++) {
1690 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1691 *pbuffer++ = (u8) (tempword >> 8);
1692 *pbuffer++ = (u8) tempword;
ca145277 1693 if (ft1000_chkcard(dev) == false) {
c95aef41 1694 kfree_skb(skb);
f7c1be0c
MB
1695 return FAILURE;
1696 }
1697 }
1698
588c31ea 1699 /* Need to read one more word if odd byte */
f7c1be0c
MB
1700 if (len & 0x0001) {
1701 tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO);
1702 *pbuffer++ = (u8) (tempword >> 8);
1703 }
1704 } else {
1705 ptemplong = (u32 *) pbuffer;
1706 for (i = 0; i < len / 4; i++) {
1707 templong = inl(dev->base_addr + FT1000_REG_MAG_DFR);
1708 DEBUG(1, "Data = 0x%8x\n", templong);
1709 *ptemplong++ = templong;
1710 }
1711
588c31ea 1712 /* Need to read one more word if odd align. */
f7c1be0c
MB
1713 if (len & 0x0003) {
1714 templong = inl(dev->base_addr + FT1000_REG_MAG_DFR);
1715 DEBUG(1, "Data = 0x%8x\n", templong);
1716 *ptemplong++ = templong;
1717 }
1718
1719 }
1720
1721 DEBUG(1, "Data passed to Protocol layer:\n");
1722 for (i = 0; i < len + 12; i++) {
1723 DEBUG(1, "Protocol Data: 0x%x\n ", *ptemp++);
1724 }
1725
1726 skb->dev = dev;
1727 skb->protocol = eth_type_trans(skb, dev);
1728 skb->ip_summed = CHECKSUM_UNNECESSARY;
1729 netif_rx(skb);
1730
1731 info->stats.rx_packets++;
588c31ea 1732 /* Add on 12 bytes for MAC address which was removed */
f7c1be0c
MB
1733 info->stats.rx_bytes += (len + 12);
1734
1735 if (info->AsicID == ELECTRABUZZ_ID) {
588c31ea 1736 /* track how many bytes have been read from FIFO - round up to 16 bit word */
f7c1be0c
MB
1737 tempword = len + 16;
1738 if (tempword & 0x01)
1739 tempword++;
1740 info->fifo_cnt += tempword;
1741 ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, FT1000_FIFO_LEN);
1742 ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, info->fifo_cnt);
1743 }
1744
1745 return SUCCESS;
1746}
1747
588c31ea
DD
1748/*---------------------------------------------------------------------------
1749
1750 Function: ft1000_copy_down_pkt
1751 Description: This function will take an ethernet packet and convert it to
1752 a Flarion packet prior to sending it to the ASIC Downlink
1753 FIFO.
1754 Input:
1755 dev - device structure
1756 packet - address of ethernet packet
1757 len - length of IP packet
1758 Output:
1759 status - FAILURE
1760 SUCCESS
1761
1762 -------------------------------------------------------------------------*/
eb93ca4e 1763static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len)
f7c1be0c 1764{
d3706552 1765 struct ft1000_info *info = netdev_priv(dev);
3aa2303a 1766 struct ft1000_pcmcia *pcmcia = info->priv;
f7c1be0c 1767 union {
2c9bf839
OZ
1768 struct pseudo_hdr blk;
1769 u16 buff[sizeof(struct pseudo_hdr) >> 1];
1770 u8 buffc[sizeof(struct pseudo_hdr)];
f7c1be0c
MB
1771 } pseudo;
1772 int i;
1773 u32 *plong;
1774
1775 DEBUG(1, "ft1000_hw: copy_down_pkt()\n");
1776
588c31ea 1777 /* Check if there is room on the FIFO */
f7c1be0c
MB
1778 if (len > ft1000_read_fifo_len(dev)) {
1779 udelay(10);
1780 if (len > ft1000_read_fifo_len(dev)) {
1781 udelay(20);
1782 }
1783 if (len > ft1000_read_fifo_len(dev)) {
1784 udelay(20);
1785 }
1786 if (len > ft1000_read_fifo_len(dev)) {
1787 udelay(20);
1788 }
1789 if (len > ft1000_read_fifo_len(dev)) {
1790 udelay(20);
1791 }
1792 if (len > ft1000_read_fifo_len(dev)) {
1793 udelay(20);
1794 }
1795 if (len > ft1000_read_fifo_len(dev)) {
1796 DEBUG(1,
1797 "ft1000_hw:ft1000_copy_down_pkt:Transmit FIFO is fulli - pkt drop\n");
1798 info->stats.tx_errors++;
1799 return SUCCESS;
1800 }
1801 }
588c31ea 1802 /* Create pseudo header and send pseudo/ip to hardware */
f7c1be0c
MB
1803 if (info->AsicID == ELECTRABUZZ_ID) {
1804 pseudo.blk.length = len;
1805 } else {
1806 pseudo.blk.length = ntohs(len);
1807 }
588c31ea 1808 pseudo.blk.source = DSPID; /* Need to swap to get in correct order */
f7c1be0c 1809 pseudo.blk.destination = HOSTID;
588c31ea 1810 pseudo.blk.portdest = NETWORKID; /* Need to swap to get in correct order */
f7c1be0c
MB
1811 pseudo.blk.portsrc = DSPAIRID;
1812 pseudo.blk.sh_str_id = 0;
1813 pseudo.blk.control = 0;
1814 pseudo.blk.rsvd1 = 0;
1815 pseudo.blk.seq_num = 0;
3aa2303a 1816 pseudo.blk.rsvd2 = pcmcia->packetseqnum++;
f7c1be0c
MB
1817 pseudo.blk.qos_class = 0;
1818 /* Calculate pseudo header checksum */
1819 pseudo.blk.checksum = pseudo.buff[0];
1820 for (i = 1; i < 7; i++) {
1821 pseudo.blk.checksum ^= pseudo.buff[i];
1822 }
1823
588c31ea 1824 /* Production Mode */
f7c1be0c 1825 if (info->AsicID == ELECTRABUZZ_ID) {
588c31ea 1826 /* copy first word to UFIFO_BEG reg */
f7c1be0c
MB
1827 ft1000_write_reg(dev, FT1000_REG_UFIFO_BEG, pseudo.buff[0]);
1828 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 0 BEG = 0x%04x\n",
1829 pseudo.buff[0]);
1830
588c31ea 1831 /* copy subsequent words to UFIFO_MID reg */
f7c1be0c
MB
1832 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[1]);
1833 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 1 MID = 0x%04x\n",
1834 pseudo.buff[1]);
1835 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[2]);
1836 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 2 MID = 0x%04x\n",
1837 pseudo.buff[2]);
1838 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[3]);
1839 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 3 MID = 0x%04x\n",
1840 pseudo.buff[3]);
1841 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[4]);
1842 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 4 MID = 0x%04x\n",
1843 pseudo.buff[4]);
1844 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[5]);
1845 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 5 MID = 0x%04x\n",
1846 pseudo.buff[5]);
1847 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[6]);
1848 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 6 MID = 0x%04x\n",
1849 pseudo.buff[6]);
1850 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[7]);
1851 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 7 MID = 0x%04x\n",
1852 pseudo.buff[7]);
1853
588c31ea 1854 /* Write PPP type + IP Packet into Downlink FIFO */
f7c1be0c
MB
1855 for (i = 0; i < (len >> 1) - 1; i++) {
1856 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID,
1857 htons(*packet));
1858 DEBUG(1,
1859 "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n",
1860 i + 8, htons(*packet));
1861 packet++;
1862 }
1863
588c31ea 1864 /* Check for odd byte */
f7c1be0c
MB
1865 if (len & 0x0001) {
1866 ft1000_write_reg(dev, FT1000_REG_UFIFO_MID,
1867 htons(*packet));
1868 DEBUG(1,
1869 "ft1000_hw:ft1000_copy_down_pkt:data MID = 0x%04x\n",
1870 htons(*packet));
1871 packet++;
1872 ft1000_write_reg(dev, FT1000_REG_UFIFO_END,
1873 htons(*packet));
1874 DEBUG(1,
1875 "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n",
1876 i + 8, htons(*packet));
1877 } else {
1878 ft1000_write_reg(dev, FT1000_REG_UFIFO_END,
1879 htons(*packet));
1880 DEBUG(1,
1881 "ft1000_hw:ft1000_copy_down_pkt:data %d MID = 0x%04x\n",
1882 i + 8, htons(*packet));
1883 }
1884 } else {
1885 outl(*(u32 *) & pseudo.buff[0],
1886 dev->base_addr + FT1000_REG_MAG_UFDR);
1887 DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n",
1888 *(u32 *) & pseudo.buff[0]);
1889 outl(*(u32 *) & pseudo.buff[2],
1890 dev->base_addr + FT1000_REG_MAG_UFDR);
1891 DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n",
1892 *(u32 *) & pseudo.buff[2]);
1893 outl(*(u32 *) & pseudo.buff[4],
1894 dev->base_addr + FT1000_REG_MAG_UFDR);
1895 DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n",
1896 *(u32 *) & pseudo.buff[4]);
1897 outl(*(u32 *) & pseudo.buff[6],
1898 dev->base_addr + FT1000_REG_MAG_UFDR);
1899 DEBUG(1, "ft1000_copy_down_pkt: Pseudo = 0x%8x\n",
1900 *(u32 *) & pseudo.buff[6]);
1901
1902 plong = (u32 *) packet;
588c31ea 1903 /* Write PPP type + IP Packet into Downlink FIFO */
f7c1be0c
MB
1904 for (i = 0; i < (len >> 2); i++) {
1905 outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR);
1906 }
1907
588c31ea 1908 /* Check for odd alignment */
f7c1be0c
MB
1909 if (len & 0x0003) {
1910 DEBUG(1,
1911 "ft1000_hw:ft1000_copy_down_pkt:data = 0x%8x\n",
1912 *plong);
1913 outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR);
1914 }
1915 outl(1, dev->base_addr + FT1000_REG_MAG_UFER);
1916 }
1917
1918 info->stats.tx_packets++;
588c31ea 1919 /* Add 14 bytes for MAC address plus ethernet type */
f7c1be0c
MB
1920 info->stats.tx_bytes += (len + 14);
1921 return SUCCESS;
1922}
1923
1924static struct net_device_stats *ft1000_stats(struct net_device *dev)
1925{
d3706552 1926 struct ft1000_info *info = netdev_priv(dev);
f7c1be0c
MB
1927 return (&info->stats);
1928}
1929
1930static int ft1000_open(struct net_device *dev)
1931{
1932
1933 DEBUG(0, "ft1000_hw: ft1000_open is called\n");
1934
1935 ft1000_reset_card(dev);
1936 DEBUG(0, "ft1000_hw: ft1000_open is ended\n");
1937
1938 /* schedule ft1000_hbchk to perform periodic heartbeat checks on DSP and ASIC */
1939 init_timer(&poll_timer);
1940 poll_timer.expires = jiffies + (2 * HZ);
1941 poll_timer.data = (u_long) dev;
1942 add_timer(&poll_timer);
1943
1944 DEBUG(0, "ft1000_hw: ft1000_open is ended2\n");
1945 return 0;
1946}
1947
1948static int ft1000_close(struct net_device *dev)
1949{
d3706552 1950 struct ft1000_info *info = netdev_priv(dev);
f7c1be0c
MB
1951
1952 DEBUG(0, "ft1000_hw: ft1000_close()\n");
1953
1954 info->CardReady = 0;
1955 del_timer(&poll_timer);
1956
1957 if (ft1000_card_present == 1) {
1958 DEBUG(0, "Media is down\n");
1959 netif_stop_queue(dev);
1960
1961 ft1000_disable_interrupts(dev);
1962 ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT);
1963
588c31ea 1964 /* reset ASIC */
f7c1be0c
MB
1965 ft1000_reset_asic(dev);
1966 }
1967 return 0;
1968}
1969
1970static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev)
1971{
d3706552 1972 struct ft1000_info *info = netdev_priv(dev);
f7c1be0c
MB
1973 u8 *pdata;
1974
1975 DEBUG(1, "ft1000_hw: ft1000_start_xmit()\n");
1976 if (skb == NULL) {
1977 DEBUG(1, "ft1000_hw: ft1000_start_xmit:skb == NULL!!!\n");
1978 return 0;
1979 }
1980
1981 DEBUG(1, "ft1000_hw: ft1000_start_xmit:length of packet = %d\n",
1982 skb->len);
1983
1984 pdata = (u8 *) skb->data;
1985
1986 if (info->mediastate == 0) {
1987 /* Drop packet is mediastate is down */
1988 DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:mediastate is down\n");
1989 return SUCCESS;
1990 }
1991
1992 if ((skb->len < ENET_HEADER_SIZE) || (skb->len > ENET_MAX_SIZE)) {
1993 /* Drop packet which has invalid size */
1994 DEBUG(1,
1995 "ft1000_hw:ft1000_copy_down_pkt:invalid ethernet length\n");
1996 return SUCCESS;
1997 }
1998 ft1000_copy_down_pkt(dev, (u16 *) (pdata + ENET_HEADER_SIZE - 2),
1999 skb->len - ENET_HEADER_SIZE + 2);
2000
2001 dev_kfree_skb(skb);
2002
2003 return 0;
2004}
2005
2006static irqreturn_t ft1000_interrupt(int irq, void *dev_id)
2007{
2008 struct net_device *dev = (struct net_device *)dev_id;
d3706552 2009 struct ft1000_info *info = netdev_priv(dev);
f7c1be0c
MB
2010 u16 tempword;
2011 u16 inttype;
2012 int cnt;
2013
2014 DEBUG(1, "ft1000_hw: ft1000_interrupt()\n");
2015
2016 if (info->CardReady == 0) {
2017 ft1000_disable_interrupts(dev);
2018 return IRQ_HANDLED;
2019 }
2020
ca145277 2021 if (ft1000_chkcard(dev) == false) {
f7c1be0c
MB
2022 ft1000_disable_interrupts(dev);
2023 return IRQ_HANDLED;
2024 }
2025
2026 ft1000_disable_interrupts(dev);
2027
588c31ea 2028 /* Read interrupt type */
f7c1be0c
MB
2029 inttype = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
2030
588c31ea 2031 /* Make sure we process all interrupt before leaving the ISR due to the edge trigger interrupt type */
80145a57 2032 while (inttype) {
64cab4e2
DN
2033 if (inttype & ISR_DOORBELL_PEND)
2034 ft1000_parse_dpram_msg(dev);
f7c1be0c 2035
80145a57
DN
2036 if (inttype & ISR_RCV) {
2037 DEBUG(1, "Data in FIFO\n");
f7c1be0c 2038
80145a57
DN
2039 cnt = 0;
2040 do {
588c31ea 2041 /* Check if we have packets in the Downlink FIFO */
80145a57
DN
2042 if (info->AsicID == ELECTRABUZZ_ID) {
2043 tempword =
2044 ft1000_read_reg(dev,
2045 FT1000_REG_DFIFO_STAT);
2046 } else {
2047 tempword =
2048 ft1000_read_reg(dev,
2049 FT1000_REG_MAG_DFSR);
2050 }
2051 if (tempword & 0x1f) {
2052 ft1000_copy_up_pkt(dev);
2053 } else {
2054 break;
2055 }
2056 cnt++;
2057 } while (cnt < MAX_RCV_LOOP);
f7c1be0c 2058
80145a57 2059 }
588c31ea 2060 /* clear interrupts */
80145a57
DN
2061 tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR);
2062 DEBUG(1, "ft1000_hw: interrupt status register = 0x%x\n", tempword);
2063 ft1000_write_reg(dev, FT1000_REG_SUP_ISR, tempword);
2064
588c31ea 2065 /* Read interrupt type */
80145a57
DN
2066 inttype = ft1000_read_reg (dev, FT1000_REG_SUP_ISR);
2067 DEBUG(1,"ft1000_hw: interrupt status register after clear = 0x%x\n",inttype);
f7c1be0c 2068 }
f7c1be0c
MB
2069 ft1000_enable_interrupts(dev);
2070 return IRQ_HANDLED;
2071}
2072
2073void stop_ft1000_card(struct net_device *dev)
2074{
d3706552 2075 struct ft1000_info *info = netdev_priv(dev);
3aaf8073 2076 struct prov_record *ptr;
588c31ea 2077 /* int cnt; */
f7c1be0c
MB
2078
2079 DEBUG(0, "ft1000_hw: stop_ft1000_card()\n");
2080
2081 info->CardReady = 0;
2082 ft1000_card_present = 0;
2083 netif_stop_queue(dev);
2084 ft1000_disable_interrupts(dev);
2085
588c31ea 2086 /* Make sure we free any memory reserve for provisioning */
f7c1be0c 2087 while (list_empty(&info->prov_list) == 0) {
3aaf8073 2088 ptr = list_entry(info->prov_list.next, struct prov_record, list);
f7c1be0c
MB
2089 list_del(&ptr->list);
2090 kfree(ptr->pprov_data);
2091 kfree(ptr);
2092 }
2093
3aa2303a
OZ
2094 kfree(info->priv);
2095
f7c1be0c
MB
2096 if (info->registered) {
2097 unregister_netdev(dev);
2098 info->registered = 0;
2099 }
2100
2101 free_irq(dev->irq, dev);
2102 release_region(dev->base_addr,256);
2103 release_firmware(fw_entry);
2104 flarion_ft1000_cnt--;
2105 ft1000CleanupProc(dev);
2106
2107}
2108
2109static void ft1000_get_drvinfo(struct net_device *dev,
2110 struct ethtool_drvinfo *info)
2111{
d3706552 2112 struct ft1000_info *ft_info;
e33196e1 2113 ft_info = netdev_priv(dev);
f7c1be0c 2114
7826d43f
JP
2115 strlcpy(info->driver, "ft1000", sizeof(info->driver));
2116 snprintf(info->bus_info, sizeof(info->bus_info), "PCMCIA 0x%lx",
f7c1be0c 2117 dev->base_addr);
7826d43f
JP
2118 snprintf(info->fw_version, sizeof(info->fw_version), "%d.%d.%d.%d",
2119 ft_info->DspVer[0], ft_info->DspVer[1], ft_info->DspVer[2],
2120 ft_info->DspVer[3]);
f7c1be0c
MB
2121}
2122
2123static u32 ft1000_get_link(struct net_device *dev)
2124{
d3706552 2125 struct ft1000_info *info;
e33196e1 2126 info = netdev_priv(dev);
f7c1be0c
MB
2127 return info->mediastate;
2128}
2129
2130static const struct ethtool_ops ops = {
2131 .get_drvinfo = ft1000_get_drvinfo,
2132 .get_link = ft1000_get_link
2133};
2134
c331e766 2135struct net_device *init_ft1000_card(struct pcmcia_device *link,
eb93ca4e 2136 void *ft1000_reset)
f7c1be0c 2137{
d3706552 2138 struct ft1000_info *info;
3aa2303a 2139 struct ft1000_pcmcia *pcmcia;
f7c1be0c 2140 struct net_device *dev;
f7c1be0c 2141
588c31ea 2142 static const struct net_device_ops ft1000ops = /* Slavius 21.10.2009 due to kernel changes */
f7c1be0c
MB
2143 {
2144 .ndo_open = &ft1000_open,
2145 .ndo_stop = &ft1000_close,
2146 .ndo_start_xmit = &ft1000_start_xmit,
2147 .ndo_get_stats = &ft1000_stats,
2148 };
2149
2150 DEBUG(1, "ft1000_hw: init_ft1000_card()\n");
c331e766
MB
2151 DEBUG(1, "ft1000_hw: irq = %d\n", link->irq);
2152 DEBUG(1, "ft1000_hw: port = 0x%04x\n", link->resource[0]->start);
f7c1be0c
MB
2153
2154 flarion_ft1000_cnt++;
2155
2156 if (flarion_ft1000_cnt > 1) {
2157 flarion_ft1000_cnt--;
2158
2159 printk(KERN_INFO
2160 "ft1000: This driver can not support more than one instance\n");
2161 return NULL;
2162 }
2163
d3706552 2164 dev = alloc_etherdev(sizeof(struct ft1000_info));
f7c1be0c
MB
2165 if (!dev) {
2166 printk(KERN_ERR "ft1000: failed to allocate etherdev\n");
2167 return NULL;
2168 }
2169
c331e766 2170 SET_NETDEV_DEV(dev, &link->dev);
e33196e1 2171 info = netdev_priv(dev);
f7c1be0c 2172
d3706552 2173 memset(info, 0, sizeof(struct ft1000_info));
f7c1be0c
MB
2174
2175 DEBUG(1, "address of dev = 0x%8x\n", (u32) dev);
2176 DEBUG(1, "address of dev info = 0x%8x\n", (u32) info);
2177 DEBUG(0, "device name = %s\n", dev->name);
2178
2179 memset(&info->stats, 0, sizeof(struct net_device_stats));
2180
3aa2303a
OZ
2181 info->priv = kzalloc(sizeof(struct ft1000_pcmcia), GFP_KERNEL);
2182 pcmcia = info->priv;
2183 pcmcia->link = link;
2184
f7c1be0c
MB
2185 spin_lock_init(&info->dpram_lock);
2186 info->DrvErrNum = 0;
f7c1be0c 2187 info->registered = 1;
f7c1be0c
MB
2188 info->ft1000_reset = ft1000_reset;
2189 info->mediastate = 0;
2190 info->fifo_cnt = 0;
f7c1be0c
MB
2191 info->CardReady = 0;
2192 info->DSP_TIME[0] = 0;
2193 info->DSP_TIME[1] = 0;
2194 info->DSP_TIME[2] = 0;
2195 info->DSP_TIME[3] = 0;
2196 flarion_ft1000_cnt = 0;
2197
2198 INIT_LIST_HEAD(&info->prov_list);
2199
2200 info->squeseqnum = 0;
2201
588c31ea
DD
2202 /* dev->hard_start_xmit = &ft1000_start_xmit; */
2203 /* dev->get_stats = &ft1000_stats; */
2204 /* dev->open = &ft1000_open; */
2205 /* dev->stop = &ft1000_close; */
f7c1be0c 2206
588c31ea 2207 dev->netdev_ops = &ft1000ops; /* Slavius 21.10.2009 due to kernel changes */
f7c1be0c
MB
2208
2209 DEBUG(0, "device name = %s\n", dev->name);
2210
c331e766
MB
2211 dev->irq = link->irq;
2212 dev->base_addr = link->resource[0]->start;
2213 if (pcmcia_get_mac_from_cis(link, dev)) {
2214 printk(KERN_ERR "ft1000: Could not read mac address\n");
2215 goto err_dev;
f7c1be0c
MB
2216 }
2217
f7c1be0c
MB
2218 if (request_irq(dev->irq, ft1000_interrupt, IRQF_SHARED, dev->name, dev)) {
2219 printk(KERN_ERR "ft1000: Could not request_irq\n");
c95aef41 2220 goto err_dev;
f7c1be0c
MB
2221 }
2222
c95aef41
VK
2223 if (request_region(dev->base_addr, 256, dev->name) == NULL) {
2224 printk(KERN_ERR "ft1000: Could not request_region\n");
2225 goto err_irq;
2226 }
f7c1be0c
MB
2227
2228 if (register_netdev(dev) != 0) {
2229 DEBUG(0, "ft1000: Could not register netdev");
c95aef41 2230 goto err_reg;
f7c1be0c
MB
2231 }
2232
2233 info->AsicID = ft1000_read_reg(dev, FT1000_REG_ASIC_ID);
2234 if (info->AsicID == ELECTRABUZZ_ID) {
2235 DEBUG(0, "ft1000_hw: ELECTRABUZZ ASIC\n");
c331e766 2236 if (request_firmware(&fw_entry, "ft1000.img", &link->dev) != 0) {
f7c1be0c 2237 printk(KERN_INFO "ft1000: Could not open ft1000.img\n");
c95aef41 2238 goto err_unreg;
f7c1be0c
MB
2239 }
2240 } else {
2241 DEBUG(0, "ft1000_hw: MAGNEMITE ASIC\n");
c331e766 2242 if (request_firmware(&fw_entry, "ft2000.img", &link->dev) != 0) {
f7c1be0c 2243 printk(KERN_INFO "ft1000: Could not open ft2000.img\n");
c95aef41 2244 goto err_unreg;
f7c1be0c
MB
2245 }
2246 }
2247
2248 ft1000_enable_interrupts(dev);
2249
2250 ft1000InitProc(dev);
2251 ft1000_card_present = 1;
7ad24ea4 2252 dev->ethtool_ops = &ops;
3274ce71
DK
2253 printk(KERN_INFO "ft1000: %s: addr 0x%04lx irq %d, MAC addr %pM\n",
2254 dev->name, dev->base_addr, dev->irq, dev->dev_addr);
f7c1be0c 2255 return dev;
c95aef41
VK
2256
2257err_unreg:
2258 unregister_netdev(dev);
2259err_reg:
2260 release_region(dev->base_addr, 256);
2261err_irq:
2262 free_irq(dev->irq, dev);
2263err_dev:
2264 free_netdev(dev);
2265 return NULL;
f7c1be0c 2266}