00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 #include <linux/kernel.h>
00210 #include <linux/module.h>
00211 #include <linux/pci.h>
00212 #include <linux/config.h>
00213 #include <linux/module.h>
00214 #include <linux/kernel.h>
00215 #include <linux/sched.h>
00216 #include <linux/string.h>
00217 #include <linux/timer.h>
00218 #include <linux/errno.h>
00219 #include <linux/in.h>
00220 #include <linux/ioport.h>
00221 #include <linux/slab.h>
00222 #include <linux/interrupt.h>
00223 #include <linux/mii.h>
00224 #include <linux/init.h>
00225 #include <linux/netdevice.h>
00226 #include <linux/etherdevice.h>
00227 #include <linux/skbuff.h>
00228 #include <linux/ethtool.h>
00229 #include <linux/highmem.h>
00230 #include <asm/irq.h>
00231 #include <asm/bitops.h>
00232 #include <asm/io.h>
00233 #include <asm/uaccess.h>
00234
00235 #include <rtl_sched.h>
00236 #include <signal.h>
00237 #include <time.h>
00238
00239 #define DRV_NAME "3c59x"
00240 #define DRV_VERSION "0.1"
00241 #define DRV_RELDATE "27 december 2002"
00242
00243 #define MAX_THREADS 10
00244
00245 #define COM3_VENDOR_ID 0x10B7
00246 #define COM3_DEVICE_ID 0X9200
00247
00248 #define BFEXT(value, offset, bitcount) \
00249 ((((unsigned long)(value)) >> (offset)) & ((1 << (bitcount)) - 1))
00250
00251 #define BFINS(lhs, rhs, offset, bitcount) \
00252 (((lhs) & ~((((1 << (bitcount)) - 1)) << (offset))) | \
00253 (((rhs) & ((1 << (bitcount)) - 1)) << (offset)))
00254
00255 #define RAM_SIZE(v) BFEXT(v, 0, 3)
00256 #define RAM_WIDTH(v) BFEXT(v, 3, 1)
00257 #define RAM_SPEED(v) BFEXT(v, 4, 2)
00258 #define ROM_SIZE(v) BFEXT(v, 6, 2)
00259 #define RAM_SPLIT(v) BFEXT(v, 16, 2)
00260 #define XCVR(v) BFEXT(v, 20, 4)
00261 #define AUTOSELECT(v) BFEXT(v, 24, 1)
00262
00263
00264
00265
00266
00267
00268
00269
00270 #define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
00271 #define EL3_CMD 0x0e
00272 #define EL3_STATUS 0x0e
00273
00274
00275
00276 #define TX_RING_SIZE 16
00277 #define RX_RING_SIZE 32
00278 #define PKT_BUF_SZ 1536
00279 #define MAX_ADDR_LEN 8
00280
00281
00282
00283
00284
00285
00286
00287 enum vortex_cmd {
00288 TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11,
00289 RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11,
00290 UpStall = 6<<11, UpUnstall = (6<<11)+1,
00291 DownStall = (6<<11)+2, DownUnstall = (6<<11)+3,
00292 RxDiscard = 8<<11, TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11,
00293 FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11,
00294 SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11,
00295 SetTxThreshold = 18<<11, SetTxStart = 19<<11,
00296 StartDMAUp = 20<<11, StartDMADown = (20<<11)+1, StatsEnable = 21<<11,
00297 StatsDisable = 22<<11, StopCoax = 23<<11, SetFilterBit = 25<<11,};
00298
00299
00300 enum RxFilter {
00301 RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8 };
00302
00303
00304 enum vortex_status {
00305 IntLatch = 0x0001, HostError = 0x0002, TxComplete = 0x0004,
00306 TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020,
00307 IntReq = 0x0040, StatsFull = 0x0080,
00308 DMADone = 1<<8, DownComplete = 1<<9, UpComplete = 1<<10,
00309 DMAInProgress = 1<<11,
00310 CmdInProgress = 1<<12,
00311 };
00312
00313
00314
00315 enum Window1 {
00316 TX_FIFO = 0x10, RX_FIFO = 0x10, RxErrors = 0x14,
00317 RxStatus = 0x18, Timer=0x1A, TxStatus = 0x1B,
00318 TxFree = 0x1C,
00319 };
00320 enum Window0 {
00321 Wn0EepromCmd = 10,
00322 Wn0EepromData = 12,
00323 IntrStatus=0x0E,
00324 };
00325 enum Win0_EEPROM_bits {
00326 EEPROM_Read = 0x80, EEPROM_WRITE = 0x40, EEPROM_ERASE = 0xC0,
00327 EEPROM_EWENB = 0x30,
00328 EEPROM_EWDIS = 0x00,
00329 };
00330
00331 enum eeprom_offset {
00332 PhysAddr01=0, PhysAddr23=1, PhysAddr45=2, ModelID=3,
00333 EtherLink3ID=7, IFXcvrIO=8, IRQLine=9,
00334 NodeAddr01=10, NodeAddr23=11, NodeAddr45=12,
00335 DriverTune=13, Checksum=15};
00336
00337 enum Window2 {
00338 Wn2_ResetOptions=12,
00339 };
00340 enum Window3 {
00341 Wn3_Config=0, Wn3_MAC_Ctrl=6, Wn3_Options=8,
00342 };
00343
00344 enum Window4 {
00345 Wn4_FIFODiag = 4, Wn4_NetDiag = 6, Wn4_PhysicalMgmt=8, Wn4_Media = 10,
00346 };
00347 enum Win4_Media_bits {
00348 Media_SQE = 0x0008,
00349 Media_10TP = 0x00C0,
00350 Media_Lnk = 0x0080,
00351 Media_LnkBeat = 0x0800,
00352 };
00353
00354 enum Window7 {
00355 Wn7_MasterAddr = 0, Wn7_MasterLen = 6, Wn7_MasterStatus = 12,
00356 };
00357
00358 enum MasterCtrl {
00359 PktStatus = 0x20, DownListPtr = 0x24, FragAddr = 0x28, FragLen = 0x2c,
00360 TxFreeThreshold = 0x2f, UpPktStatus = 0x30, UpListPtr = 0x38,
00361 };
00362
00363
00364
00365
00366 #define LAST_FRAG 0x80000000
00367 #define DN_COMPLETE 0x00010000
00368
00369
00370 enum rx_desc_status {
00371 RxDComplete=0x00008000, RxDError=0x4000,
00372
00373 IPChksumErr=1<<25, TCPChksumErr=1<<26, UDPChksumErr=1<<27,
00374 IPChksumValid=1<<29, TCPChksumValid=1<<30, UDPChksumValid=1<<31,
00375 };
00376
00377
00378 enum tx_desc_status {
00379 CRCDisable=0x2000, TxDComplete=0x8000,
00380 AddIPChksum=0x02000000, AddTCPChksum=0x04000000, AddUDPChksum=0x08000000,
00381 TxIntrUploaded=0x80000000,
00382 };
00383
00384
00385
00386
00387 enum xcvr_types {
00388 XCVR_10baseT=0, XCVR_AUI, XCVR_10baseTOnly, XCVR_10base2, XCVR_100baseTx,
00389 XCVR_100baseFx, XCVR_MII=6, XCVR_NWAY=8, XCVR_ExtMII=9, XCVR_Default=10,
00390 };
00391
00392
00393 enum ChipCaps { CapBusMaster=0x20, CapPwrMgmt=0x2000 };
00394
00395
00396
00397
00398
00399 enum pci_flags_bit {
00400 PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
00401 PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3,
00402 };
00403
00404 enum { IS_VORTEX=1, IS_BOOMERANG=2, IS_CYCLONE=4, IS_TORNADO=8,
00405 EEPROM_8BIT=0x10,
00406 HAS_PWR_CTRL=0x20, HAS_MII=0x40, HAS_NWAY=0x80, HAS_CB_FNS=0x100,
00407 INVERT_MII_PWR=0x200, INVERT_LED_PWR=0x400, MAX_COLLISION_RESET=0x800,
00408 EEPROM_OFFSET=0x1000, HAS_HWCKSM=0x2000 };
00409
00410 #define DO_ZEROCOPY 0
00411
00412 struct boom_rx_desc {
00413 u32 next;
00414 s32 status;
00415 u32 addr;
00416 s32 length;
00417 };
00418
00419 struct boom_tx_desc {
00420 u32 next;
00421 s32 status;
00422 u32 addr;
00423 s32 length;
00424 };
00425
00426 struct vortex_private {
00427
00428 struct boom_rx_desc* rx_ring;
00429 struct boom_tx_desc* tx_ring;
00430 dma_addr_t rx_ring_dma;
00431 dma_addr_t tx_ring_dma;
00432
00433 unsigned char *rx_skbuff[RX_RING_SIZE];
00434 unsigned char *tx_skbuff[TX_RING_SIZE];
00435 struct net_device *next_module;
00436 unsigned int cur_rx, cur_tx;
00437 unsigned int dirty_rx, dirty_tx;
00438 struct net_device_stats stats;
00439 struct sk_buff *tx_skb;
00440 dma_addr_t tx_skb_dma;
00441
00442 struct pci_dev *pdev;
00443 char *cb_fn_base;
00444
00445
00446 int rx_nocopy, rx_copy, queued_packet, rx_csumhits;
00447 int card_idx;
00448
00449 int options;
00450 unsigned int media_override:4,
00451 default_media:4,
00452 full_duplex:1,
00453 force_fd:1,
00454 autoselect:1,
00455 bus_master:1,
00456 full_bus_master_tx:1, full_bus_master_rx:2,
00457 flow_ctrl:1,
00458 partner_flow_ctrl:1,
00459 has_nway:1,
00460 enable_wol:1,
00461 pm_state_valid:1,
00462 open:1,
00463 medialock:1,
00464 must_free_region:1;
00465 int drv_flags;
00466 u16 status_enable;
00467 u16 intr_enable;
00468 u16 available_media;
00469 u16 capabilities, info1, info2;
00470 u16 advertising;
00471 unsigned char phys[2];
00472 u16 deferred;
00473
00474 u16 io_size;
00475 spinlock_t lock;
00476 spinlock_t mdio_lock;
00477 u32 power_state[16];
00478 int mtu;
00479 unsigned char dev_addr[MAX_ADDR_LEN];
00480 long ioaddr;
00481 unsigned long rx_packets;
00482 unsigned long rx_frames_for_us;
00483 unsigned char if_port;
00484 int must_free_irq;
00485 };
00486
00487 static struct vortex_chip_info {
00488 const char *name;
00489 int flags;
00490 int drv_flags;
00491 int io_size;
00492 } vortex_info = {"3c905C Tornado",
00493 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, };
00494
00495 enum vortex_chips {
00496 CH_3C590 = 0,
00497 CH_3C592,
00498 CH_3C597,
00499 CH_3C595_1,
00500 CH_3C595_2,
00501
00502 CH_3C595_3,
00503 CH_3C900_1,
00504 CH_3C900_2,
00505 CH_3C900_3,
00506 CH_3C900_4,
00507
00508 CH_3C900_5,
00509 CH_3C900B_FL,
00510 CH_3C905_1,
00511 CH_3C905_2,
00512 CH_3C905B_1,
00513
00514 CH_3C905B_2,
00515 CH_3C905B_FX,
00516 CH_3C905C,
00517 CH_3C980,
00518 CH_3C9805,
00519
00520 CH_3CSOHO100_TX,
00521 CH_3C555,
00522 CH_3C556,
00523 CH_3C556B,
00524 CH_3C575,
00525
00526 CH_3C575_1,
00527 CH_3CCFE575,
00528 CH_3CCFE575CT,
00529 CH_3CCFE656,
00530 CH_3CCFEM656,
00531
00532 CH_3CCFEM656_1,
00533 CH_3C450,
00534 };
00535
00536 static struct media_table {
00537 char *name;
00538 unsigned int media_bits:16,
00539 mask:8,
00540 next:8;
00541 int wait;
00542 } media_tbl[] = {
00543 { "10baseT", Media_10TP,0x08, XCVR_10base2, (14*HZ)/10},
00544 { "10Mbs AUI", Media_SQE, 0x20, XCVR_Default, (1*HZ)/10},
00545 { "undefined", 0, 0x80, XCVR_10baseT, 10000},
00546 { "10base2", 0, 0x10, XCVR_AUI, (1*HZ)/10},
00547 { "100baseTX", Media_Lnk, 0x02, XCVR_100baseFx, (14*HZ)/10},
00548 { "100baseFX", Media_Lnk, 0x04, XCVR_MII, (14*HZ)/10},
00549 { "MII", 0, 0x41, XCVR_10baseT, 3*HZ },
00550 { "undefined", 0, 0x01, XCVR_10baseT, 10000},
00551 { "Autonegotiate", 0, 0x41, XCVR_10baseT, 3*HZ},
00552 { "MII-External", 0, 0x41, XCVR_10baseT, 3*HZ },
00553 { "Default", 0, 0xFF, XCVR_10baseT, 10000},
00554 };
00555
00556 static char mii_preamble_required;
00557 static const int mtu = 1500;
00558
00559 static int max_interrupt_work = 32;
00560
00561
00562
00563
00564 #ifndef __arm__
00565 static const int rx_copybreak = 200;
00566 #else
00567
00568
00569 static const int rx_copybreak = 1513;
00570 #endif
00571
00572 struct pci_dev *rtl_3COM905C_init_device(void);
00573 int rtl_3COM905C_start_up_device(struct pci_dev *dev);
00574 static void rtl_3COM905C_mdio_write(int phy_id, int location, int value);
00575 static int rtl_3COM905C_mdio_read(int phy_id, int location);
00576 static void rtl_3COM905C_mdio_sync(long ioaddr, int bits);
00577 static int vortex_open(struct pci_dev *dev);
00578 static void vortex_up(struct pci_dev *dev);
00579 static void rtl_3COM905C_issue_and_wait(int cmd);
00580 static void rtl_3COM905C_set_rx_mode(void);
00581 static void rtl_3COM905C_acpi_set_WOL(void);
00582 static int boomerang_rx(struct pci_dev *dev);
00583 static void vortex_down(struct pci_dev *dev);
00584 static void vortex_error(struct pci_dev *dev, int status);
00585 static int vortex_close(struct pci_dev *dev);
00586 static void vortex_remove_one (struct pci_dev *pdev);
00587 static int rt_3c905c_send_packet(const char *buffer, size_t size);
00588 void rt_3c905c_send_signal(void);
00589
00590 #define PCI_DEBUG 0
00591 #define EEPROM_CONTENTS_DEBUG 0
00592 #define MAC_ADDRESS_DEBUG 0
00593 #define FUNCTION_CALL_DEBUG 0
00594 #define INITIALIZATION_DEBUG 0
00595 #define RECEIVE_DEBUG 0
00596 #define PACKET_DATA_DEBUG 0
00597 #define INTERRUPT_DEBUG 0
00598 #define TRANSMIT_DEBUG 0
00599 #define ERROR_DEBUG 1
00600
00601 #define SIGALRM2 RTL_SIGUSR1
00602
00603 #define DEBUG(x,y) if(x) printk y
00604
00605 #include <rtl_sync.h>
00606 #include <rtl_core.h>
00607 #include <rtl_printf.h>
00608 #include <time.h>
00609 #include <asm/io.h>
00610 #include <rtl_posixio.h>
00611 #include <sys/mman.h>
00612 #include <errno.h>
00613 #include <unistd.h>
00614 #include <rtl.h>
00615 #include <rtl_malloc.h>
00616 #include <rtl_sema.h>
00617 #include <rtl_sync.h>
00618 #include "memcopy.h"
00619
00620 static int rtl_3COM905C_open (struct rtl_file *filp);
00621 static int rtl_3COM905C_release (struct rtl_file *filp);
00622 static ssize_t rtl_3COM905C_write(struct rtl_file *filp, const char *buf, size_t count, loff_t* ppos);
00623 static int rtl_3COM905C_ioctl(struct rtl_file * filp, unsigned int request, unsigned long other);
00624 static ssize_t rtl_3COM905C_read(struct rtl_file *filp, char *buf, size_t count, loff_t* ppos);
00625
00626
00627
00628
00629
00630