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