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