91 #define virt_to_le32desc(addr) virt_to_bus(addr) 92 #define le32desc_to_virt(addr) bus_to_virt(addr) 106 #define TX_RING_SIZE 2 107 #define RX_RING_SIZE 2 113 #define TX_FIFO_SIZE (2048) 114 #define TX_BUG_FIFO_LIMIT (TX_FIFO_SIZE-1514-16) 118 #define TX_TIMEOUT (10*1000) 120 #define PKT_BUF_SZ 1536 128 #if !defined(__OPTIMIZE__) 129 #warning You must compile this file with the correct options! 130 #warning See the last lines of the source file. 131 #error You must compile this driver with "-O". 137 #define W840_FLAGS (PCI_USES_IO | PCI_ADDR0 | PCI_USES_MASTER) 139 #define W840_FLAGS (PCI_USES_MEM | PCI_ADDR1 | PCI_USES_MASTER) 221 #define PRIV_ALIGN 15 222 #define PRIV_ALIGN_BYTES 32 263 static int mdio_read(
int base_address,
int phy_id,
int location);
265 static void mdio_write(
int base_address,
int phy_id,
int location,
int value);
272 #if defined(W89C840_DEBUG) 273 static void decode_interrupt(
u32 intr_status)
275 printf(
"Interrupt status: ");
277 #define TRACE_INTR(_intr_) \ 278 if (intr_status & (_intr_)) { printf (" " #_intr_); } 341 #if defined(W89C840_DEBUG) 342 printf(
"winbond-840 : Done reset.\n");
347 static void handle_intr(
u32 intr_stat)
359 printf(
"\n-=- Abnormal interrupt.\n");
361 #if defined(W89C840_DEBUG) 362 decode_interrupt(intr_stat);
367 printf(
"-=- <=> No receive buffers available.\n");
382 int packet_received = 0;
384 #if defined(W89C840_DEBUG) 407 if ((
status & 0x38008300) != 0x0300) {
408 if ((
status & 0x38000300) != 0x0300) {
410 if ((
status & 0xffff) != 0x7fff) {
411 printf(
"winbond-840 : Oversized Ethernet frame spanned " 412 "multiple buffers, entry %d status %X !\n",
415 }
else if (
status & 0x8000) {
417 #if defined(W89C840_DEBUG) 418 printf(
"winbond-840 : Receive error, Rx status %X :",
status);
441 #if defined(W89C840_DEBUG) 442 printf(
" netdev_rx() normal Rx pkt ring %d length %d status %X\n", entry,
pkt_len,
status);
456 #if defined(W89C840_DEBUG) 458 printf(
" Rx data %hhX:%hhX:%hhX:%hhX:%hhX:" 459 "%hhX %hhX:%hhX:%hhX:%hhX:%hhX:%hhX %hhX%hhX " 460 "%hhX.%hhX.%hhX.%hhX.\n",
475 return packet_received;
503 *((
char *) w89c840_buf.tx_packet + 12) = t >> 8;
504 *((
char *) w89c840_buf.tx_packet + 13) = t;
510 *((
char *) w89c840_buf.tx_packet +
ETH_HLEN + (s++)) = 0;
534 #if defined(W89C840_DEBUG) 543 #if defined W89C840_DEBUG 548 #if defined(W89C840_DEBUG) 549 decode_interrupt(intr_stat);
561 if ((transmit_status &
DescOwn) == 0) {
563 #if defined(W89C840_DEBUG) 564 printf(
"winbond-840 : transmission complete after wait loop iterations, status %X\n",
573 printf(
"winbond-840 : transmission TIMEOUT : status %X\n",
616 PCI_ROM(0x1050, 0x0840,
"winbond840",
"Winbond W89C840F", 0),
617 PCI_ROM(0x11f6, 0x2011,
"compexrl100atx",
"Compex RL100ATX", 0),
630 unsigned short value;
638 #if defined(W89C840_DEBUG) 639 printf(
"winbond-840: PCI bus %hhX device function %hhX: I/O address: %hX\n", p->bus, p->devfn,
ioaddr);
644 #define PCI_VENDOR_ID_WINBOND2 0x1050 645 #define PCI_DEVICE_ID_WINBOND2_89C840 0x0840 646 #define PCI_VENDOR_ID_COMPEX 0x11f6 647 #define PCI_DEVICE_ID_COMPEX_RL100ATX 0x2011 662 printf(
"device ID : %X - is not a Compex RL100ATX NIC.\n",
672 for (i = 0; i < 0x40; i++) {
684 #if defined(W89C840_DEBUG) 685 printf(
"winbond-840: EEPROM checksum %hX, got eeprom", sum);
693 int phy, phy_idx = 0;
694 for (phy = 1; phy < 32 && phy_idx < 4; phy++) {
696 if (mii_status != 0xffff && mii_status != 0x0000) {
700 #if defined(W89C840_DEBUG) 701 printf(
"winbond-840 : MII PHY found at address %d, status " 711 printf(
"winbond-840 : MII PHY not found -- this device may not operate correctly.\n");
734 #define eeprom_delay(ee_addr) readl(ee_addr) 755 for (i = 10; i >= 0; i--) {
764 for (i = 16; i > 0; i--) {
784 #define mdio_delay(mdio_addr) readl(mdio_addr) 791 #define MDIO_WRITE0 (MDIO_EnbOutput) 792 #define MDIO_WRITE1 (MDIO_DataOut | MDIO_EnbOutput) 801 while (--
bits >= 0) {
809 static int mdio_read(
int base_address,
int phy_id,
int location)
811 long mdio_addr = base_address +
MIICtrl;
812 int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
819 for (i = 15; i >= 0; i--) {
822 writel(dataval, mdio_addr);
828 for (i = 20; i > 0; i--) {
835 return (
retval>>1) & 0xffff;
839 static void mdio_write(
int base_address,
int phy_id,
int location,
int value)
841 long mdio_addr = base_address +
MIICtrl;
842 int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) |
value;
852 for (i = 31; i >= 0; i--) {
855 writel(dataval, mdio_addr);
861 for (i = 2; i > 0; i--) {
880 duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040;
884 #if defined(W89C840_DEBUG) 885 printf(
"winbond-840 : Setting %s-duplex based on MII # %d negotiated capability %X\n",
900 memset(mc_filter, 0xff,
sizeof(mc_filter));
914 #if defined(W89C840_DEBUG) 915 printf(
"winbond-840 : Done setting RX mode.\n");
934 p = &w89c840_buf.rx_packet[0];
#define virt_to_le32desc(addr)
#define eeprom_delay(ee_addr)
int printf(const char *fmt,...)
Write a formatted string to the console.
unsigned long ioaddr
I/O address.
static void w89c840_reset(struct nic *nic)
struct w840_tx_desc tx_ring[TX_RING_SIZE]
uint64_t desc
Microcode descriptor list physical address.
const char * product_name
static int mdio_read(int base_address, int phy_id, int location)
struct net_device * next_module
static int eeprom_read(long ioaddr, int location)
char rx_packet[PKT_BUF_SZ *RX_RING_SIZE]
static void w89c840_disable(struct nic *nic)
PCI_DRIVER(w89c840_driver, w89c840_nics, PCI_NO_CLASS)
static void set_rx_mode(void)
void adjust_pci_device(struct pci_device *pci)
Enable PCI device.
struct w840_rx_desc * rx_head_desc
int dummy_connect(struct nic *nic __unused)
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static __always_inline unsigned long virt_to_bus(volatile const void *addr)
Convert virtual address to a bus address.
uint16_t device
Device ID.
#define le32desc_to_virt(addr)
pseudo_bit_t value[0x00020]
#define __unused
Declare a variable or data structure as unused.
#define PCI_DEVICE_ID_COMPEX_RL100ATX
void mdio_write(struct nic *nic __unused, int phy_id, int location, int value)
unsigned int default_port
static int w89c840_probe(struct nic *nic, struct pci_device *p)
static void init_ring(void)
static int w89c840_poll(struct nic *nic, int retrieve)
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
FILE_LICENCE(GPL2_OR_LATER)
DRIVER("W89C840F", nic_driver, pci_driver, w89c840_driver, w89c840_probe, w89c840_disable)
static void mdio_sync(long mdio_addr)
A PCI device ID list entry.
#define PCI_VENDOR_ID_WINBOND2
uint16_t vendor
Vendor ID.
static char mii_preamble_required
static const char * w89c840_version
unsigned char * node_addr
static volatile void * bits
static void check_duplex(void)
static struct pci_device_id w89c840_nics[]
#define TX_BUG_FIFO_LIMIT
#define PCI_VENDOR_ID_COMPEX
static struct nic_operations w89c840_operations
static void w89c840_irq(struct nic *nic __unused, irq_action_t action __unused)
unsigned long currticks(void)
Get current system time in ticks.
#define DBG(...)
Print a debugging message.
struct nic_operations * nic_op
static struct winbond_private w840private
char tx_packet[PKT_BUF_SZ *TX_RING_SIZE]
struct w840_rx_desc rx_ring[RX_RING_SIZE]
#define PCI_DEVICE_ID_WINBOND2_89C840
static struct command_descriptor read_cmd
"read" command descriptor
int(* connect)(struct nic *)
#define PCI_ROM(_vendor, _device, _name, _description, _data)
#define mdio_delay(mdio_addr)
static void w89c840_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p)
void * memset(void *dest, int character, size_t len) __nonnull