6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22 #include <exec/types.h>
23 #include <exec/resident.h>
25 #include <exec/ports.h>
27 #include <aros/libcall.h>
28 #include <aros/macros.h>
33 #include <devices/sana2.h>
34 #include <devices/sana2specialstats.h>
36 #include <utility/utility.h>
37 #include <utility/tagitem.h>
38 #include <utility/hooks.h>
43 #include <proto/oop.h>
44 #include <proto/exec.h>
45 #include <proto/dos.h>
46 #include <proto/battclock.h>
52 #include LC_LIBDEFS_FILE
54 /* A bit fixed linux stuff here :) */
57 #define LIBBASE (unit->sis900u_device)
59 #define net_device SiS900Unit
61 static struct mii_chip_info
{
70 } mii_chip_table
[] = {
71 { "SiS 900 Internal MII PHY", 0x001d, 0x8000, LAN
},
72 { "SiS 7014 Physical Layer Solution", 0x0016, 0xf830, LAN
},
73 { "Altimata AC101LF PHY", 0x0022, 0x5520, LAN
},
74 { "AMD 79C901 10BASE-T PHY", 0x0000, 0x6B70, LAN
},
75 { "AMD 79C901 HomePNA PHY", 0x0000, 0x6B90, HOME
},
76 { "ICS LAN PHY", 0x0015, 0xF440, LAN
},
77 { "NS 83851 PHY", 0x2000, 0x5C20, MIX
},
78 { "NS 83847 PHY", 0x2000, 0x5C30, MIX
},
79 { "Realtek RTL8201 PHY", 0x0000, 0x8200, LAN
},
80 { "VIA 6103 PHY", 0x0101, 0x8f20, LAN
},
84 #define TIMER_RPROK 3599597124UL
86 const UBYTE byte_rev_table
[256] = {
87 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
88 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
89 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
90 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
91 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
92 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
93 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
94 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
95 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
96 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
97 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
98 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
99 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
100 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
101 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
102 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
103 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
104 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
105 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
106 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
107 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
108 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
109 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
110 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
111 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
112 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
113 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
114 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
115 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
116 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
117 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
118 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
121 #define CRCPOLY_LE 0xedb88320
123 ULONG
crc32_le(ULONG crc
, unsigned char const *p
, int len
)
128 for (i
= 0; i
< 8; i
++)
129 crc
= (crc
>> 1) ^ ((crc
& 1) ? CRCPOLY_LE
: 0);
134 static inline UBYTE
bitrev8(UBYTE byte
)
136 return byte_rev_table
[byte
];
139 UWORD
bitrev16(UWORD x
)
141 return (bitrev8(x
& 0xff) << 8) | bitrev8(x
>> 8);
145 * bitrev32 - reverse the order of bits in a u32 value
146 * @x: value to be bit-reversed
148 ULONG
bitrev32(ULONG x
)
150 return (bitrev16(x
& 0xffff) << 16) | bitrev16(x
>> 16);
153 #define ether_crc(length, data) bitrev32(crc32_le(~0, data, length))
156 static ULONG
usec2tick(ULONG usec
)
158 ULONG ret
, timer_rpr
= TIMER_RPROK
;
159 asm volatile("movl $0,%%eax; divl %2":"=a"(ret
):"d"(usec
),"m"(timer_rpr
));
163 void udelay(LONG usec
)
166 usec
= usec2tick(usec
);
169 oldtick
= BYTEIN(0x42);
170 oldtick
+= BYTEIN(0x42) << 8;
176 tick
+= BYTEIN(0x42) << 8;
178 usec
-= (oldtick
- tick
);
179 if (tick
> oldtick
) usec
-= 0x10000;
184 /* sis900_mcast_bitnr - compute hashtable index
185 * @addr: multicast address
186 * @revision: revision id of chip
188 * SiS 900 uses the most sigificant 7 bits to index a 128 bits multicast
189 * hash table, which makes this function a little bit different from other drivers
190 * SiS 900 B0 & 635 M/B uses the most significat 8 bits to index 256 bits
191 * multicast hash table.
193 static inline UWORD
sis900_mcast_bitnr(UBYTE
*addr
, UBYTE revision
)
196 ULONG crc
= ether_crc(6, addr
);
198 /* leave 8 or 7 most siginifant bits */
199 if ((revision
>= SIS635A_900_REV
) || (revision
== SIS900B_900_REV
))
200 return ((int)(crc
>> 24));
202 return ((int)(crc
>> 25));
205 /* Delay between EEPROM clock transitions. */
206 #define eeprom_delay() LONGIN(ee_addr)
208 static UWORD
read_eeprom(long ioaddr
, int location
)
212 IPTR ee_addr
= ioaddr
+ mear
;
213 ULONG read_cmd
= location
| EEread
;
217 LONGOUT(ee_addr
, EECS
);
220 /* Shift the read command (9) bits out. */
221 for (i
= 8; i
>= 0; i
--) {
222 ULONG dataval
= (read_cmd
& (1 << i
)) ? EEDI
| EECS
: EECS
;
223 LONGOUT(ee_addr
, dataval
);
225 LONGOUT(ee_addr
, dataval
| EECLK
);
228 LONGOUT(ee_addr
, EECS
);
231 /* read the 16-bits data in */
232 for (i
= 16; i
> 0; i
--) {
233 LONGOUT(ee_addr
, EECS
);
235 LONGOUT(ee_addr
, EECS
| EECLK
);
237 retval
= (retval
<< 1) | ((LONGIN(ee_addr
) & EEDO
) ? 1 : 0);
241 /* Terminate the EEPROM access. */
248 /* Read and write the MII management registers using software-generated
249 serial MDIO protocol. Note that the command bits and data bits are
250 send out separately */
251 #define mdio_delay() LONGIN(mdio_addr)
253 static void mdio_idle(long mdio_addr
)
255 LONGOUT(mdio_addr
, MDIO
| MDDIR
);
257 LONGOUT(mdio_addr
, MDIO
| MDDIR
| MDC
);
260 /* Syncronize the MII management interface by shifting 32 one bits out. */
261 static void mdio_reset(long mdio_addr
)
265 for (i
= 31; i
>= 0; i
--) {
266 LONGOUT(mdio_addr
, MDDIR
| MDIO
);
268 LONGOUT(mdio_addr
, MDDIR
| MDIO
| MDC
);
275 * mdio_read - read MII PHY register
276 * @unit: the net device to read
277 * @phy_id: the phy address to read
278 * @location: the phy regiester id to read
280 * Read MII registers through MDIO and MDC
281 * using MDIO management frame structure and protocol(defined by ISO/IEC).
282 * Please see SiS7014 or ICS spec
284 int mdio_read(struct net_device
*unit
, int phy_id
, int location
)
286 long mdio_addr
= unit
->sis900u_BaseMem
+ mear
;
287 int mii_cmd
= MIIread
| (phy_id
<< MIIpmdShift
) | (location
<< MIIregShift
);
291 mdio_reset(mdio_addr
);
292 mdio_idle(mdio_addr
);
294 for (i
= 15; i
>= 0; i
--) {
295 int dataval
= (mii_cmd
& (1 << i
)) ? MDDIR
| MDIO
: MDDIR
;
296 LONGOUT(mdio_addr
, dataval
);
298 LONGOUT(mdio_addr
, dataval
| MDC
);
302 /* Read the 16 data bits. */
303 for (i
= 16; i
> 0; i
--) {
304 LONGOUT(mdio_addr
, 0);
306 retval
= (retval
<< 1) | ((LONGIN(mdio_addr
) & MDIO
) ? 1 : 0);
307 LONGOUT(mdio_addr
, MDC
);
310 LONGOUT(mdio_addr
, 0x00);
316 * mdio_write - write MII PHY register
317 * @unit: the net device to write
318 * @phy_id: the phy address to write
319 * @location: the phy regiester id to write
320 * @value: the register value to write with
322 * Write MII registers with @value through MDIO and MDC
323 * using MDIO management frame structure and protocol(defined by ISO/IEC)
324 * please see SiS7014 or ICS spec
326 static void mdio_write(struct net_device
*unit
, int phy_id
, int location
, int value
)
328 long mdio_addr
= unit
->sis900u_BaseMem
+ mear
;
329 int mii_cmd
= MIIwrite
| (phy_id
<< MIIpmdShift
) | (location
<< MIIregShift
);
332 mdio_reset(mdio_addr
);
333 mdio_idle(mdio_addr
);
335 /* Shift the command bits out. */
336 for (i
= 15; i
>= 0; i
--) {
337 int dataval
= (mii_cmd
& (1 << i
)) ? MDDIR
| MDIO
: MDDIR
;
338 BYTEOUT(mdio_addr
, dataval
);
340 BYTEOUT(mdio_addr
, dataval
| MDC
);
345 /* Shift the value bits out. */
346 for (i
= 15; i
>= 0; i
--) {
347 int dataval
= (value
& (1 << i
)) ? MDDIR
| MDIO
: MDDIR
;
348 LONGOUT(mdio_addr
, dataval
);
350 LONGOUT(mdio_addr
, dataval
| MDC
);
355 /* Clear out extra bits. */
356 for (i
= 2; i
> 0; i
--) {
357 BYTEOUT(mdio_addr
, 0);
359 BYTEOUT(mdio_addr
, MDC
);
362 LONGOUT(mdio_addr
, 0x00);
368 * sis900_set_capability - set the media capability of network adapter.
369 * @unit : the net device to probe for
372 * Set the media capability of network adapter according to
373 * mii status register. It's necessary before auto-negotiate.
375 static void sis900_set_capability(struct net_device
*unit
, struct mii_phy
*phy
)
380 D(bug("[%s] sis900_set_capability(phy:%d)\n", unit
->sis900u_name
, phy
->phy_addr
));
382 status
= mdio_read(unit
, phy
->phy_addr
, MII_STATUS
);
383 status
= mdio_read(unit
, phy
->phy_addr
, MII_STATUS
);
385 cap
= MII_NWAY_CSMA_CD
|
386 ((phy
->status
& MII_STAT_CAN_TX_FDX
)? MII_NWAY_TX_FDX
:0) |
387 ((phy
->status
& MII_STAT_CAN_TX
) ? MII_NWAY_TX
:0) |
388 ((phy
->status
& MII_STAT_CAN_T_FDX
) ? MII_NWAY_T_FDX
:0)|
389 ((phy
->status
& MII_STAT_CAN_T
) ? MII_NWAY_T
:0);
391 mdio_write(unit
, phy
->phy_addr
, MII_ANADV
, cap
);
395 * sis900_auto_negotiate - Set the Auto-Negotiation Enable/Reset bit.
396 * @unit: the net device to read mode for
397 * @phy_addr: mii phy address
399 * If the adapter is link-on, set the auto-negotiate enable/reset bit.
400 * autong_complete should be set to 0 when starting auto-negotiation.
401 * autong_complete should be set to 1 if we didn't start auto-negotiation.
402 * sis900_timer will wait for link on again if autong_complete = 0.
404 static void sis900_auto_negotiate(struct net_device
*unit
, int phy_addr
)
409 D(bug("[%s] sis900_auto_negotiate(phy:%d)\n", unit
->sis900u_name
, phy_addr
));
412 status
= mdio_read(unit
, phy_addr
, MII_STATUS
);
414 if (!(status
& MII_STAT_LINK
)){
415 //if(netif_msg_link(sis_priv))
416 D(bug("[%s]: sis900_auto_negotiate: Media Link Off\n", unit
->sis900u_name
));
417 unit
->autong_complete
= 1;
418 netif_carrier_off(unit
);
422 /* (Re)start AutoNegotiate */
423 mdio_write(unit
, phy_addr
, MII_CONTROL
, MII_CNTL_AUTO
| MII_CNTL_RST_AUTO
);
424 unit
->autong_complete
= 0;
428 * sis900_default_phy - Select default PHY for sis900 mac.
429 * @unit: the net device to probe for
431 * Select first detected PHY with link as default.
432 * If no one is link on, select PHY whose types is HOME as default.
433 * If HOME doesn't exist, select LAN.
435 static UWORD
sis900_default_phy(struct net_device
*unit
)
437 struct mii_phy
*phy
= NULL
, *phy_home
= NULL
, *default_phy
= NULL
, *phy_lan
= NULL
;
440 D(bug("[%s] sis900_default_phy()\n", unit
->sis900u_name
));
442 for (phy
= unit
->first_mii
; phy
; phy
= phy
->next
)
444 status
= mdio_read(unit
, phy
->phy_addr
, MII_STATUS
);
445 status
= mdio_read(unit
, phy
->phy_addr
, MII_STATUS
);
447 /* Link ON & Not select default PHY & not ghost PHY */
448 if ((status
& MII_STAT_LINK
) && !default_phy
&& (phy
->phy_types
!= UNKNOWN
))
451 status
= mdio_read(unit
, phy
->phy_addr
, MII_CONTROL
);
452 mdio_write(unit
, phy
->phy_addr
, MII_CONTROL
, status
| MII_CNTL_AUTO
| MII_CNTL_ISOLATE
);
453 if (phy
->phy_types
== HOME
)
455 else if(phy
->phy_types
== LAN
)
460 if (!default_phy
&& phy_home
)
461 default_phy
= phy_home
;
462 else if (!default_phy
&& phy_lan
)
463 default_phy
= phy_lan
;
464 else if (!default_phy
)
465 default_phy
= unit
->first_mii
;
467 if (unit
->mii
!= default_phy
) {
468 unit
->mii
= default_phy
;
469 unit
->cur_phy
= default_phy
->phy_addr
;
470 D(bug("[%s]: sis900_default_phy: Using transceiver found at address %d as default\n", unit
->sis900u_name
, unit
->cur_phy
));
473 // unit->mii_info.phy_id = unit->cur_phy;
475 status
= mdio_read(unit
, unit
->cur_phy
, MII_CONTROL
);
476 status
&= (~MII_CNTL_ISOLATE
);
478 mdio_write(unit
, unit
->cur_phy
, MII_CONTROL
, status
);
479 status
= mdio_read(unit
, unit
->cur_phy
, MII_STATUS
);
480 status
= mdio_read(unit
, unit
->cur_phy
, MII_STATUS
);
486 * sis900_reset_phy - reset sis900 mii phy.
487 * @unit: the net device to write
488 * @phy_addr: default phy address
490 * Some specific phy can't work properly without reset.
491 * This function will be called during initialization and
492 * link status change from ON to DOWN.
494 static UWORD
sis900_reset_phy(struct net_device
*unit
, int phy_addr
)
499 D(bug("[%s] sis900_reset_phy(phy:%d)\n", unit
->sis900u_name
, phy_addr
));
502 status
= mdio_read(unit
, phy_addr
, MII_STATUS
);
504 mdio_write(unit
, phy_addr
, MII_CONTROL
, MII_CNTL_RESET
);
510 * sis900_mii_probe - Probe MII PHY for sis900
511 * @unit: the net device to probe for
513 * Search for total of 32 possible mii phy addresses.
514 * Identify and set current phy if found one,
515 * return error if it failed to found.
517 static int sis900_mii_probe(struct net_device
*unit
)
519 UWORD poll_bit
= MII_STAT_LINK
, status
= 0;
520 #warning "TODO: Replace jiffies"
522 unsigned long timeout
= jiffies
+ 5 * HZ
;
525 D(bug("[%s] sis900_mii_probe()\n", unit
->sis900u_name
));
529 /* search for total of 32 possible mii phy addresses */
530 for (phy_addr
= 0; phy_addr
< 32; phy_addr
++) {
531 struct mii_phy
* mii_phy
= NULL
;
536 for(i
= 0; i
< 2; i
++)
537 mii_status
= mdio_read(unit
, phy_addr
, MII_STATUS
);
539 if (mii_status
== 0xffff || mii_status
== 0x0000) {
540 D(bug("[%s]: sis900_mii_probe: MII at address %d not accessible\n", unit
->sis900u_name
, phy_addr
));
544 if ((mii_phy
= AllocMem(sizeof(struct mii_phy
), MEMF_PUBLIC
| MEMF_CLEAR
)) == NULL
) {
545 D(bug("[%s]: sis900_mii_probe: MII %d: Cannot allocate mem for struct mii_phy\n", unit
->sis900u_name
, phy_addr
));
546 mii_phy
= unit
->first_mii
;
550 mii_phy
= mii_phy
->next
;
551 FreeMem(phy
, sizeof(struct mii_phy
));
556 mii_phy
->phy_id0
= mdio_read(unit
, phy_addr
, MII_PHY_ID0
);
557 mii_phy
->phy_id1
= mdio_read(unit
, phy_addr
, MII_PHY_ID1
);
558 mii_phy
->phy_addr
= phy_addr
;
559 mii_phy
->status
= mii_status
;
560 mii_phy
->next
= unit
->mii
;
562 unit
->first_mii
= mii_phy
;
564 for (i
= 0; mii_chip_table
[i
].phy_id1
; i
++)
565 if ((mii_phy
->phy_id0
== mii_chip_table
[i
].phy_id0
) &&
566 ((mii_phy
->phy_id1
& 0xFFF0) == mii_chip_table
[i
].phy_id1
)){
567 mii_phy
->phy_types
= mii_chip_table
[i
].phy_types
;
568 if (mii_chip_table
[i
].phy_types
== MIX
)
570 (mii_status
& (MII_STAT_CAN_TX_FDX
| MII_STAT_CAN_TX
)) ? LAN
: HOME
;
571 D(bug("[%s]: sis900_mii_probe: %s transceiver found at address %d.\n", unit
->sis900u_name
, mii_chip_table
[i
].name
, phy_addr
));
575 if( !mii_chip_table
[i
].phy_id1
) {
576 D(bug("[%s]: sis900_mii_probe: Unknown PHY transceiver found at address %d.\n", unit
->sis900u_name
, phy_addr
));
577 mii_phy
->phy_types
= UNKNOWN
;
581 if (unit
->mii
== NULL
) {
582 D(bug("[%s]: sis900_mii_probe: No MII transceivers found!\n", unit
->sis900u_name
));
586 /* select default PHY for mac */
588 sis900_default_phy(unit
);
590 /* Reset phy if default phy is internal sis900 */
591 if ((unit
->mii
->phy_id0
== 0x001D) &&
592 ((unit
->mii
->phy_id1
&0xFFF0) == 0x8000))
593 status
= sis900_reset_phy(unit
, unit
->cur_phy
);
595 /* workaround for ICS1893 PHY */
596 if ((unit
->mii
->phy_id0
== 0x0015) &&
597 ((unit
->mii
->phy_id1
&0xFFF0) == 0xF440))
598 mdio_write(unit
, unit
->cur_phy
, 0x0018, 0xD200);
600 if(status
& MII_STAT_LINK
){
604 poll_bit
^= (mdio_read(unit
, unit
->cur_phy
, MII_STATUS
) & poll_bit
);
605 // if (time_after_eq(jiffies, timeout)) {
606 //D(bug("[%s]: sis900_mii_probe: reset phy and link down now\n", unit->sis900u_name));
607 #warning "TODO: Return -ETIME!"
614 if (unit
->sis900u_RevisionID
== SIS630E_900_REV
) {
615 /* SiS 630E has some bugs on default value of PHY registers */
616 mdio_write(unit
, unit
->cur_phy
, MII_ANADV
, 0x05e1);
617 mdio_write(unit
, unit
->cur_phy
, MII_CONFIG1
, 0x22);
618 mdio_write(unit
, unit
->cur_phy
, MII_CONFIG2
, 0xff00);
619 mdio_write(unit
, unit
->cur_phy
, MII_MASK
, 0xffc0);
620 //mdio_write(unit, unit->cur_phy, MII_CONTROL, 0x1000);
623 if (unit
->mii
->status
& MII_STAT_LINK
)
624 netif_carrier_on(unit
);
626 netif_carrier_off(unit
);
631 static void sis900func_start_rx(struct net_device
*unit
)
633 D(bug("[%s]: sis900func_start_rx\n", unit
->sis900u_name
));
634 // Already running? Stop it.
635 #warning "TODO: Handle starting/stopping Rx"
638 static void sis900func_stop_rx(struct net_device
*unit
)
640 D(bug("[%s]: sis900func_stop_rx\n", unit
->sis900u_name
));
641 #warning "TODO: Handle starting/stopping Rx"
644 static void sis900func_start_tx(struct net_device
*unit
)
646 D(bug("[%s]: sis900func_start_tx()\n", unit
->sis900u_name
));
647 #warning "TODO: Handle starting/stopping Tx"
650 static void sis900func_stop_tx(struct net_device
*unit
)
652 D(bug("[%s]: sis900func_stop_tx()\n", unit
->sis900u_name
));
653 #warning "TODO: Handle starting/stopping Tx"
656 static void sis900func_txrx_reset(struct net_device
*unit
)
658 D(bug("[%s]: sis900func_txrx_reset()\n", unit
->sis900u_name
));
662 * sis900_get_mac_addr - Get MAC address for stand alone SiS900 model
663 * @unit: the net device to get address for
665 * Older SiS900 and friends, use EEPROM to store MAC address.
666 * MAC address is read from read_eeprom() into @net_dev->dev_addr.
668 static int sis900_get_mac_addr(struct net_device
*unit
)
673 D(bug("[%s] sis900_get_mac_addr()\n", unit
->sis900u_name
));
675 /* check to see if we have sane EEPROM */
676 signature
= (UWORD
) read_eeprom(unit
->sis900u_BaseMem
, EEPROMSignature
);
677 if (signature
== 0xffff || signature
== 0x0000) {
678 D(bug("[%s]: sis900_get_mac_addr: Error EERPOM read %x\n", unit
->sis900u_name
, signature
));
682 /* get MAC address from EEPROM */
683 for (i
= 0; i
< 3; i
++)
685 unit
->sis900u_org_addr
[i
] = (UWORD
)read_eeprom(unit
->sis900u_BaseMem
, i
+ EEPROMMACAddr
);
692 * sis630e_get_mac_addr - Get MAC address for SiS630E model
693 * @unit: the net device to get address for
695 * SiS630E model, use APC CMOS RAM to store MAC address.
696 * APC CMOS RAM is accessed through ISA bridge.
697 * MAC address is read into @net_dev->dev_addr.
699 static int sis630e_get_mac_addr(struct net_device
*unit
)
701 // struct pci_dev *isa_bridge = NULL;
705 D(bug("[%s] sis630e_get_mac_addr()\n", unit
->sis900u_name
));
707 // isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0008, isa_bridge);
709 // isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0018, isa_bridge);
710 // if (!isa_bridge) {
711 // printk(KERN_WARNING "%s: Can not find ISA bridge\n",
712 // pci_name(pci_dev));
715 // pci_read_config_byte(isa_bridge, 0x48, ®);
716 // pci_write_config_byte(isa_bridge, 0x48, reg | 0x40);
718 for (i
= 0; i
< 3; i
++) {
719 BYTEOUT(0x70, 0x09 + (i
* 2));
720 unit
->sis900u_org_addr
[i
] = 0x0000 + (BYTEIN(0x71) << 8);
721 BYTEOUT(0x70, 0x09 + (i
* 2) + 1);
722 unit
->sis900u_org_addr
[i
] |= BYTEIN(0x71);
724 // pci_write_config_byte(isa_bridge, 0x48, reg & ~0x40);
725 // pci_dev_put(isa_bridge);
731 * sis635_get_mac_addr - Get MAC address for SIS635 model
732 * @unit: the net device to get address for
734 * SiS635 model, set MAC Reload Bit to load Mac address from APC
735 * to rfdr. rfdr is accessed through rfcr. MAC address is read into
736 * @net_dev->dev_addr.
738 static int sis635_get_mac_addr(struct net_device
*unit
)
740 long ioaddr
= unit
->sis900u_BaseMem
;
744 D(bug("[%s] sis635_get_mac_addr()\n", unit
->sis900u_name
));
746 rfcrSave
= LONGIN(rfcr
+ ioaddr
);
748 LONGOUT(ioaddr
+ cr
, rfcrSave
| RELOAD
);
749 LONGOUT(ioaddr
+ cr
, 0);
751 /* disable packet filtering before setting filter */
752 LONGOUT(rfcr
+ ioaddr
, rfcrSave
& ~RFEN
);
754 /* load MAC addr to filter data register */
755 for (i
= 0 ; i
< 3 ; i
++) {
756 LONGOUT(ioaddr
+ rfcr
, i
<< RFADDR_shift
);
757 unit
->sis900u_org_addr
[i
] = WORDIN(ioaddr
+ rfdr
);
760 /* enable packet filtering */
761 LONGOUT(rfcr
+ ioaddr
, rfcrSave
| RFEN
);
767 * sis96x_get_mac_addr - Get MAC address for SiS962 or SiS963 model
768 * @unit: the net device to get address for
770 * SiS962 or SiS963 model, use EEPROM to store MAC address. And EEPROM
772 * LAN and 1394. When access EEPROM, send EEREQ signal to hardware first
773 * and wait for EEGNT. If EEGNT is ON, EEPROM is permitted to be access
774 * by LAN, otherwise is not. After MAC address is read from EEPROM, send
775 * EEDONE signal to refuse EEPROM access by LAN.
776 * The EEPROM map of SiS962 or SiS963 is different to SiS900.
777 * The signature field in SiS962 or SiS963 spec is meaningless.
778 * MAC address is read into @net_dev->dev_addr.
780 static int sis96x_get_mac_addr(struct net_device
*unit
)
782 long ioaddr
= unit
->sis900u_BaseMem
;
783 long ee_addr
= ioaddr
+ mear
;
787 D(bug("[%s] sis96x_get_mac_addr()\n", unit
->sis900u_name
));
789 LONGOUT(ee_addr
, EEREQ
);
790 while(waittime
< 2000) {
791 if(LONGIN(ee_addr
) & EEGNT
) {
793 /* get MAC address from EEPROM */
794 for (i
= 0; i
< 3; i
++)
795 unit
->sis900u_org_addr
[i
] = read_eeprom(ioaddr
, i
+EEPROMMACAddr
);
797 LONGOUT(ee_addr
, EEDONE
);
804 LONGOUT(ee_addr
, EEDONE
);
809 * sis900func_set_multicast: unit->set_multicast function
810 * Called with unit->xmit_lock held.
812 void sis900func_set_multicast(struct net_device
*unit
)
818 D(bug("[%s]: sis900func_set_multicast()\n", unit
->sis900u_name
));
820 memset(addr
, 0, sizeof(addr
));
821 memset(mask
, 0, sizeof(mask
));
824 void sis900func_deinitialize(struct net_device
*unit
)
826 D(bug("[%s] sis900func_deinitialize()\n", unit
->sis900u_name
));
829 void sis900func_initialize(struct net_device
*unit
)
833 D(bug("[%s] sis900func_initialize()\n", unit
->sis900u_name
));
836 if (unit
->sis900u_RevisionID
== SIS630E_900_REV
)
837 ret
= sis630e_get_mac_addr(unit
);
838 else if ((unit
->sis900u_RevisionID
> 0x81) && (unit
->sis900u_RevisionID
<= 0x90) )
839 ret
= sis635_get_mac_addr(unit
);
840 else if (unit
->sis900u_RevisionID
== SIS96x_900_REV
)
841 ret
= sis96x_get_mac_addr(unit
);
843 ret
= sis900_get_mac_addr(unit
);
846 D(bug("[%s]: Cannot read MAC address.\n", unit
->sis900u_name
));
850 unit
->sis900u_dev_addr
[0] = unit
->sis900u_org_addr
[0] & 0xff;
851 unit
->sis900u_dev_addr
[1] = (unit
->sis900u_org_addr
[0] >> 8) & 0xff;
853 unit
->sis900u_dev_addr
[2] = unit
->sis900u_org_addr
[1] & 0xff;
854 unit
->sis900u_dev_addr
[3] = (unit
->sis900u_org_addr
[1] >> 8) & 0xff;
856 unit
->sis900u_dev_addr
[4] = unit
->sis900u_org_addr
[2] & 0xff;
857 unit
->sis900u_dev_addr
[5] = (unit
->sis900u_org_addr
[2] >> 8) & 0xff;
859 D(bug("[%s]: MAC Address %02x:%02x:%02x:%02x:%02x:%02x\n", unit
->sis900u_name
,
860 unit
->sis900u_dev_addr
[0], unit
->sis900u_dev_addr
[1], unit
->sis900u_dev_addr
[2],
861 unit
->sis900u_dev_addr
[3], unit
->sis900u_dev_addr
[4], unit
->sis900u_dev_addr
[5]));
863 /* 630ET : set the mii access mode as software-mode */
864 if (unit
->sis900u_RevisionID
== SIS630ET_900_REV
)
866 LONGOUT(unit
->sis900u_BaseMem
+ cr
, ACCESSMODE
| LONGIN(unit
->sis900u_BaseMem
+ cr
));
869 /* probe for mii transceiver */
870 if (sis900_mii_probe(unit
) == 0) {
871 D(bug("[%s]: Error probing MII device.\n", unit
->sis900u_name
));
876 static void sis900func_drain_tx(struct net_device
*unit
)
879 for (i
= 0; i
< NUM_TX_DESC
; i
++) {
880 #warning "TODO: sis900func_drain_tx does nothing atm."
884 static void sis900func_drain_rx(struct net_device
*unit
)
887 for (i
= 0; i
< NUM_RX_DESC
; i
++) {
888 #warning "TODO: sis900func_drain_rx does nothing atm."
892 static void drain_ring(struct net_device
*unit
)
894 sis900func_drain_tx(unit
);
895 sis900func_drain_rx(unit
);
898 static int request_irq(struct net_device
*unit
)
900 OOP_Object
*irq
= OOP_NewObject(NULL
, CLID_Hidd_IRQ
, NULL
);
903 D(bug("[%s]: request_irq()\n", unit
->sis900u_name
));
907 ret
= HIDD_IRQ_AddHandler(irq
, unit
->sis900u_irqhandler
, unit
->sis900u_IRQ
);
908 HIDD_IRQ_AddHandler(irq
, unit
->sis900u_touthandler
, vHidd_IRQ_Timer
);
910 D(bug("[%s]: request_irq: IRQ Handlers configured\n", unit
->sis900u_name
));
912 OOP_DisposeObject(irq
);
922 static void free_irq(struct net_device
*unit
)
924 OOP_Object
*irq
= OOP_NewObject(NULL
, CLID_Hidd_IRQ
, NULL
);
927 HIDD_IRQ_RemHandler(irq
, unit
->sis900u_irqhandler
);
928 HIDD_IRQ_RemHandler(irq
, unit
->sis900u_touthandler
);
929 OOP_DisposeObject(irq
);
933 void sis900func_set_mac(struct net_device
*unit
)
937 D(bug("[%s]: sis900func_set_mac()\n", unit
->sis900u_name
));
939 /* BYTEOUT(base + RTLr_Cfg9346, 0xc0);
940 LONGOUT(base + RTLr_MAC0 + 0, (
941 ( unit->sis900u_dev_addr[3] << 24 ) |
942 ( unit->sis900u_dev_addr[2] << 16 ) |
943 ( unit->sis900u_dev_addr[1] << 8 ) |
944 unit->sis900u_dev_addr[0]
947 LONGOUT(base + RTLr_MAC0 + 4, (
948 ( unit->sis900u_dev_addr[5] << 8 ) |
949 unit->sis900u_dev_addr[4]
951 BYTEOUT(base + RTLr_Cfg9346, 0x00);*/
955 * sis900_reset - Reset sis900 MAC
956 * @unit: the net device to reset
958 * reset sis900 MAC and wait until finished
959 * reset through command register
960 * change backoff algorithm for 900B0 & 635 M/B
962 static void sis900_reset(struct net_device
*unit
)
964 long ioaddr
= unit
->sis900u_BaseMem
;
966 ULONG status
= TxRCMP
| RxRCMP
;
968 D(bug("[%s]: sis900_reset()\n", unit
->sis900u_name
));
970 LONGOUT(ioaddr
+ ier
, 0);
971 LONGOUT(ioaddr
+ imr
, 0);
972 LONGOUT(ioaddr
+ rfcr
, 0);
974 LONGOUT(ioaddr
+ cr
, RxRESET
| TxRESET
| RESET
| LONGIN(ioaddr
+ cr
));
976 /* Check that the chip has finished the reset. */
977 while (status
&& (i
++ < 1000)) {
978 status
^= (LONGIN(isr
+ ioaddr
) & status
);
981 if( (unit
->sis900u_RevisionID
>= SIS635A_900_REV
) || (unit
->sis900u_RevisionID
== SIS900B_900_REV
) )
982 LONGOUT(ioaddr
+ cfg
, PESEL
| RND_CNT
);
984 LONGOUT(ioaddr
+ cfg
, PESEL
);
988 * sis630_set_eq - set phy equalizer value for 630 LAN
989 * @unit: the net device to set equalizer value
990 * @revision: 630 LAN revision number
992 * 630E equalizer workaround rule(Cyrus Huang 08/15)
993 * PHY register 14h(Test)
994 * Bit 14: 0 -- Automatically dectect (default)
995 * 1 -- Manually set Equalizer filter
996 * Bit 13: 0 -- (Default)
997 * 1 -- Speed up convergence of equalizer setting
998 * Bit 9 : 0 -- (Default)
999 * 1 -- Disable Baseline Wander
1000 * Bit 3~7 -- Equalizer filter setting
1001 * Link ON: Set Bit 9, 13 to 1, Bit 14 to 0
1002 * Then calculate equalizer value
1003 * Then set equalizer value, and set Bit 14 to 1, Bit 9 to 0
1004 * Link Off:Set Bit 13 to 1, Bit 14 to 0
1005 * Calculate Equalizer value:
1006 * When Link is ON and Bit 14 is 0, SIS900PHY will auto-dectect proper equalizer value.
1007 * When the equalizer is stable, this value is not a fixed value. It will be within
1008 * a small range(eg. 7~9). Then we get a minimum and a maximum value(eg. min=7, max=9)
1009 * 0 <= max <= 4 --> set equalizer to max
1010 * 5 <= max <= 14 --> set equalizer to max+1 or set equalizer to max+2 if max == min
1011 * max >= 15 --> set equalizer to max+5 or set equalizer to max+6 if max == min
1013 static void sis630_set_eq(struct net_device
*unit
, UBYTE revision
)
1015 UWORD reg14h
, eq_value
=0, max_value
=0, min_value
=0;
1018 D(bug("[%s]: sis630_set_eq()\n", unit
->sis900u_name
));
1020 if ( !(revision
== SIS630E_900_REV
|| revision
== SIS630EA1_900_REV
||
1021 revision
== SIS630A_900_REV
|| revision
== SIS630ET_900_REV
) )
1023 D(bug("[%s]: sis630_set_eq: Skipping for revision %d chipset\n", unit
->sis900u_name
, revision
));
1027 if (netif_carrier_ok(unit
)) {
1028 reg14h
= mdio_read(unit
, unit
->cur_phy
, MII_RESV
);
1029 mdio_write(unit
, unit
->cur_phy
, MII_RESV
,
1030 (0x2200 | reg14h
) & 0xBFFF);
1031 for (i
=0; i
< maxcount
; i
++) {
1032 eq_value
= (0x00F8 & mdio_read(unit
,
1033 unit
->cur_phy
, MII_RESV
)) >> 3;
1035 max_value
=min_value
=eq_value
;
1036 max_value
= (eq_value
> max_value
) ?
1037 eq_value
: max_value
;
1038 min_value
= (eq_value
< min_value
) ?
1039 eq_value
: min_value
;
1041 /* 630E rule to determine the equalizer value */
1042 if (revision
== SIS630E_900_REV
|| revision
== SIS630EA1_900_REV
||
1043 revision
== SIS630ET_900_REV
) {
1045 eq_value
= max_value
;
1046 else if (max_value
>= 5 && max_value
< 15)
1047 eq_value
= (max_value
== min_value
) ?
1048 max_value
+2 : max_value
+1;
1049 else if (max_value
>= 15)
1050 eq_value
=(max_value
== min_value
) ?
1051 max_value
+6 : max_value
+5;
1053 /* 630B0&B1 rule to determine the equalizer value */
1054 if (revision
== SIS630A_900_REV
&&
1055 (unit
->sis900u_HostRevisionID
== SIS630B0
||
1056 unit
->sis900u_HostRevisionID
== SIS630B1
)) {
1060 eq_value
= (max_value
+ min_value
+ 1)/2;
1062 /* write equalizer value and setting */
1063 reg14h
= mdio_read(unit
, unit
->cur_phy
, MII_RESV
);
1064 reg14h
= (reg14h
& 0xFF07) | ((eq_value
<< 3) & 0x00F8);
1065 reg14h
= (reg14h
| 0x6000) & 0xFDFF;
1066 mdio_write(unit
, unit
->cur_phy
, MII_RESV
, reg14h
);
1068 reg14h
= mdio_read(unit
, unit
->cur_phy
, MII_RESV
);
1069 if (revision
== SIS630A_900_REV
&&
1070 (unit
->sis900u_HostRevisionID
== SIS630B0
||
1071 unit
->sis900u_HostRevisionID
== SIS630B1
))
1072 mdio_write(unit
, unit
->cur_phy
, MII_RESV
,
1073 (reg14h
| 0x2200) & 0xBFFF);
1075 mdio_write(unit
, unit
->cur_phy
, MII_RESV
,
1076 (reg14h
| 0x2000) & 0xBFFF);
1082 * sis900_init_rxfilter - Initialize the Rx filter
1083 * @unit: the net device to initialize for
1085 * Set receive filter address to our MAC address
1086 * and enable packet filtering.
1088 static void sis900_init_rxfilter(struct net_device
*unit
)
1090 long ioaddr
= unit
->sis900u_BaseMem
;
1094 D(bug("[%s]: sis900_init_rxfilter()\n", unit
->sis900u_name
));
1096 rfcrSave
= LONGIN(rfcr
+ ioaddr
);
1098 /* disable packet filtering before setting filter */
1099 LONGOUT(rfcr
+ ioaddr
, rfcrSave
& ~RFEN
);
1101 /* load MAC addr to filter data register */
1102 for (i
= 0 ; i
< 3 ; i
++) {
1105 w
= (unit
->sis900u_dev_addr
[(i
* 2)] << 8 ) + unit
->sis900u_dev_addr
[(i
* 2) + 1];
1106 LONGOUT(ioaddr
+ rfcr
, (i
<< RFADDR_shift
));
1107 LONGOUT(ioaddr
+ rfdr
, w
);
1109 //if (netif_msg_hw(unit)) {
1110 D(bug("[%s]: sis900_init_rxfilter: Receive Filter Addrss[%d]=%x\n",unit
->sis900u_name
, i
, LONGIN(ioaddr
+ rfdr
)));
1114 /* enable packet filtering */
1115 LONGOUT(rfcr
+ ioaddr
, rfcrSave
| RFEN
);
1119 * sis900_init_tx_ring - Initialize the Tx descriptor ring
1120 * @unit: the net device to initialize for
1122 * Initialize the Tx descriptor ring,
1124 static void sis900_init_tx_ring(struct net_device
*unit
)
1126 long ioaddr
= unit
->sis900u_BaseMem
;
1127 int i
, allocate
= 1;
1129 D(bug("[%s]: sis900_init_tx_ring()\n", unit
->sis900u_name
));
1132 unit
->dirty_tx
= unit
->cur_tx
= 0;
1134 for (i
= 0; i
< NUM_TX_DESC
; i
++) {
1137 if ((allocate
) && ((framebuffer
= AllocMem(TX_BUF_SIZE
, MEMF_PUBLIC
| MEMF_CLEAR
)) == NULL
)) {
1138 /* not enough memory for framebuffer this makes a "hole"
1139 on the buffer ring, it is not clear how the
1140 hardware will react to this kind of degenerated
1145 unit
->tx_ring
[i
].link
= unit
->tx_ring_dma
+
1146 ((i
+1)%NUM_TX_DESC
)*sizeof(BufferDesc
);
1147 unit
->tx_ring
[i
].cmdsts
= 0;
1150 unit
->tx_buffers
[i
] = framebuffer
;
1151 unit
->tx_ring
[i
].bufptr
= HIDD_PCIDriver_CPUtoPCI(unit
->sis900u_PCIDriver
, framebuffer
);
1153 D(bug("[%s]: sis900_init_tx_ring: Buffer %d @ %p\n", unit
->sis900u_name
, i
, framebuffer
));
1156 /* load Transmit Descriptor Register */
1157 LONGOUT(ioaddr
+ txdp
, unit
->tx_ring_dma
);
1158 // if (netif_msg_hw(unit))
1159 D(bug("[%s]: sis900_init_tx_ring: TX descriptor register loaded with: %8.8x\n",unit
->sis900u_name
, LONGIN(ioaddr
+ txdp
)));
1163 * sis900_init_rx_ring - Initialize the Rx descriptor ring
1164 * @unit: the net device to initialize for
1166 * Initialize the Rx descriptor ring,
1167 * and pre-allocate recevie buffers (socket buffer)
1169 static void sis900_init_rx_ring(struct net_device
*unit
)
1171 long ioaddr
= unit
->sis900u_BaseMem
;
1172 int i
, allocate
= 1;
1174 D(bug("[%s]: sis900_init_rx_ring()\n", unit
->sis900u_name
));
1179 /* init RX descriptor and allocate buffers */
1180 for (i
= 0; i
< NUM_RX_DESC
; i
++) {
1183 if ((allocate
) && ((framebuffer
= AllocMem(RX_BUF_SIZE
, MEMF_PUBLIC
| MEMF_CLEAR
)) == NULL
)) {
1184 /* not enough memory for framebuffer this makes a "hole"
1185 on the buffer ring, it is not clear how the
1186 hardware will react to this kind of degenerated
1190 unit
->rx_ring
[i
].link
= unit
->rx_ring_dma
+
1191 ((i
+1)%NUM_RX_DESC
)*sizeof(BufferDesc
);
1192 unit
->rx_ring
[i
].cmdsts
= RX_BUF_SIZE
;
1195 unit
->rx_buffers
[i
] = framebuffer
;
1196 unit
->rx_ring
[i
].bufptr
= HIDD_PCIDriver_CPUtoPCI(unit
->sis900u_PCIDriver
, framebuffer
);
1198 D(bug("[%s]: sis900_init_rx_ring: Buffer %d @ %p\n", unit
->sis900u_name
, i
, framebuffer
));
1200 unit
->dirty_rx
= (unsigned int) (i
- NUM_RX_DESC
);
1202 /* load Receive Descriptor Register */
1203 LONGOUT(ioaddr
+ rxdp
, unit
->rx_ring_dma
);
1204 // if (netif_msg_hw(sis_priv))
1205 D(bug("[%s]: sis900_init_rx_ring: RX descriptor register loaded with: %8.8x\n",unit
->sis900u_name
, LONGIN(ioaddr
+ rxdp
)));
1210 * set_rx_mode - Set SiS900 receive mode
1211 * @unit: the net device to be set
1213 * Set SiS900 receive mode for promiscuous, multicast, or broadcast mode.
1214 * And set the appropriate multicast filter.
1215 * Multicast hash table changes from 128 to 256 bits for 635M/B & 900B0.
1217 static void set_rx_mode(struct net_device
*unit
)
1219 long ioaddr
= unit
->sis900u_BaseMem
;
1220 UWORD mc_filter
[16] = {0}; /* 256/128 bits multicast hash table */
1221 int i
, table_entries
;
1224 D(bug("[%s]: set_rx_mode()\n", unit
->sis900u_name
));
1226 /* 635 Hash Table entires = 256(2^16) */
1227 if((unit
->sis900u_RevisionID
>= SIS635A_900_REV
) ||
1228 (unit
->sis900u_RevisionID
== SIS900B_900_REV
))
1233 #warning "TODO: Fix multicast settings"
1234 //if (unit->sis900u_ifflags & IFF_PROMISC) {
1235 // Accept any kinds of packets
1236 rx_mode
= RFPromiscuous
;
1237 for (i
= 0; i
< table_entries
; i
++)
1238 mc_filter
[i
] = 0xffff;
1239 /*} else if ((unit->mc_count > multicast_filter_limit) ||
1240 (unit->sis900u_ifflags & IFF_ALLMULTI)) {
1241 // too many multicast addresses or accept all multicast packet
1242 rx_mode = RFAAB | RFAAM;
1243 for (i = 0; i < table_entries; i++)
1244 mc_filter[i] = 0xffff;
1246 // Accept Broadcast packet, destination address matchs our
1247 // MAC address, use Receive Filter to reject unwanted MCAST
1249 struct dev_mc_list *mclist;
1251 for (i = 0, mclist = unit->mc_list;
1252 mclist && i < unit->mc_count;
1253 i++, mclist = mclist->next) {
1254 unsigned int bit_nr =
1255 sis900_mcast_bitnr(mclist->dmi_addr, unit->sis900u_RevisionID);
1256 mc_filter[bit_nr >> 4] |= (1 << (bit_nr & 0xf));
1260 /* update Multicast Hash Table in Receive Filter */
1261 for (i
= 0; i
< table_entries
; i
++) {
1262 /* why plus 0x04 ??, That makes the correct value for hash table. */
1263 LONGOUT(ioaddr
+ rfcr
, (ULONG
)(0x00000004+i
) << RFADDR_shift
);
1264 LONGOUT(ioaddr
+ rfdr
, mc_filter
[i
]);
1267 LONGOUT(ioaddr
+ rfcr
, RFEN
| rx_mode
);
1269 /* sis900 is capable of looping back packets at MAC level for
1270 * debugging purpose */
1271 if (unit
->sis900u_ifflags
& IFF_LOOPBACK
) {
1273 /* We must disable Tx/Rx before setting loopback mode */
1274 cr_saved
= LONGIN(ioaddr
+ cr
);
1275 LONGOUT(ioaddr
+ cr
, cr_saved
| TxDIS
| RxDIS
);
1276 /* enable loopback */
1277 LONGOUT(ioaddr
+ txcfg
, LONGIN(ioaddr
+ txcfg
) | TxMLB
);
1278 LONGOUT(ioaddr
+ rxcfg
, LONGIN(ioaddr
+ rxcfg
) | RxATX
);
1280 LONGOUT(ioaddr
+ cr
, cr_saved
);
1287 * sis900_set_mode - Set the media mode of mac register.
1288 * @ioaddr: the address of the device
1289 * @speed : the transmit speed to be determined
1290 * @duplex: the duplex mode to be determined
1292 * Set the media mode of mac register txcfg/rxcfg according to
1293 * speed and duplex of phy. Bit EDB_MASTER_EN indicates the EDB
1294 * bus is used instead of PCI bus. When this bit is set 1, the
1295 * Max DMA Burst Size for TX/RX DMA should be no larger than 16
1298 static void sis900_set_mode(long ioaddr
, int speed
, int duplex
)
1300 ULONG tx_flags
= 0, rx_flags
= 0;
1302 //D(bug("[%s]: sis900_set_mode()\n", unit->sis900u_name));
1304 if (LONGIN(ioaddr
+ cfg
) & EDB_MASTER_EN
) {
1305 tx_flags
= TxATP
| (DMA_BURST_64
<< TxMXDMA_shift
) |
1306 (TX_FILL_THRESH
<< TxFILLT_shift
);
1307 rx_flags
= DMA_BURST_64
<< RxMXDMA_shift
;
1309 tx_flags
= TxATP
| (DMA_BURST_512
<< TxMXDMA_shift
) |
1310 (TX_FILL_THRESH
<< TxFILLT_shift
);
1311 rx_flags
= DMA_BURST_512
<< RxMXDMA_shift
;
1314 if (speed
== HW_SPEED_HOME
|| speed
== HW_SPEED_10_MBPS
) {
1315 rx_flags
|= (RxDRNT_10
<< RxDRNT_shift
);
1316 tx_flags
|= (TxDRNT_10
<< TxDRNT_shift
);
1318 rx_flags
|= (RxDRNT_100
<< RxDRNT_shift
);
1319 tx_flags
|= (TxDRNT_100
<< TxDRNT_shift
);
1322 if (duplex
== FDX_CAPABLE_FULL_SELECTED
) {
1323 tx_flags
|= (TxCSI
| TxHBI
);
1327 LONGOUT(ioaddr
+ txcfg
, tx_flags
);
1328 LONGOUT(ioaddr
+ rxcfg
, rx_flags
);
1332 * sis900_check_mode - check the media mode for sis900
1333 * @unit: the net device to be checked
1334 * @mii_phy: the mii phy
1336 * Older driver gets the media mode from mii status output
1337 * register. Now we set our media capability and auto-negotiate
1338 * to get the upper bound of speed and duplex between two ends.
1339 * If the types of mii phy is HOME, it doesn't need to auto-negotiate
1340 * and autong_complete should be set to 1.
1342 static void sis900_check_mode(struct net_device
*unit
, struct mii_phy
*mii_phy
)
1344 long ioaddr
= unit
->sis900u_BaseMem
;
1347 D(bug("[%s]: sis900_check_mode()\n", unit
->sis900u_name
));
1349 if (mii_phy
->phy_types
== LAN
) {
1350 LONGOUT(ioaddr
+ cfg
, ~EXD
& LONGIN(ioaddr
+ cfg
));
1351 sis900_set_capability(unit
, mii_phy
);
1352 sis900_auto_negotiate(unit
, unit
->cur_phy
);
1354 LONGOUT(ioaddr
+ cfg
, EXD
| LONGIN(ioaddr
+ cfg
));
1355 speed
= HW_SPEED_HOME
;
1356 duplex
= FDX_CAPABLE_HALF_SELECTED
;
1357 sis900_set_mode(ioaddr
, speed
, duplex
);
1358 unit
->autong_complete
= 1;
1362 int sis900func_open(struct net_device
*unit
)
1364 int ret
, i
, rx_buf_len_idx
;
1366 D(bug("[%s]: sis900func_open()\n", unit
->sis900u_name
));
1368 /* Soft reset the chip. */
1371 /* Equalizer workaround Rule */
1372 sis630_set_eq(unit
, unit
->sis900u_RevisionID
);
1374 ret
= request_irq(unit
);
1378 sis900_init_rxfilter(unit
);
1380 sis900_init_tx_ring(unit
);
1381 sis900_init_rx_ring(unit
);
1385 // netif_start_queue(unit);
1387 /* Workaround for EDB */
1388 sis900_set_mode(unit
->sis900u_BaseMem
, HW_SPEED_10_MBPS
, FDX_CAPABLE_HALF_SELECTED
);
1390 D(bug("[%s]: sis900func_open: Enabling NIC's interupts .. \n", unit
->sis900u_name
));
1391 /* Enable all known interrupts by setting the interrupt mask. */
1392 LONGOUT(unit
->sis900u_BaseMem
+ imr
, (RxSOVR
|RxORN
|RxERR
|RxOK
|TxURN
|TxERR
|TxIDLE
));
1393 LONGOUT(unit
->sis900u_BaseMem
+ cr
, RxENA
| LONGIN(unit
->sis900u_BaseMem
+ cr
));
1394 LONGOUT(unit
->sis900u_BaseMem
+ ier
, IE
);
1396 sis900_check_mode(unit
, unit
->mii
);
1398 unit
->sis900u_ifflags
|= IFF_UP
;
1399 ReportEvents(LIBBASE
, unit
, S2EVENT_ONLINE
);
1400 D(bug("[%s]: sis900func_open: Device set as ONLINE\n",unit
->sis900u_name
));
1409 int sis900func_close(struct net_device
*unit
)
1413 D(bug("[%s]: sis900func_close()\n", unit
->sis900u_name
));
1415 unit
->sis900u_ifflags
&= ~IFF_UP
;
1417 // ObtainSemaphore(&np->lock);
1418 // np->in_shutdown = 1;
1419 // ReleaseSemaphore(&np->lock);
1421 // unit->sis900u_toutNEED = FALSE;
1423 netif_stop_queue(unit
);
1424 // ObtainSemaphore(&np->lock);
1426 sis900func_deinitialize(unit
); // Stop the chipset and set it in 16bit-mode
1428 // base = get_hwbase(unit);
1430 // ReleaseSemaphore(&np->lock);
1436 // HIDD_PCIDriver_FreePCIMem(unit->sis900u_PCIDriver, np->rx_buffer);
1437 // HIDD_PCIDriver_FreePCIMem(unit->sis900u_PCIDriver, np->tx_buffer);
1439 ReportEvents(LIBBASE
, unit
, S2EVENT_OFFLINE
);