15b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* -*- Mode:C; c-basic-offset:4; -*- */ 25b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 35b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* 45b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900.c: An SiS 900/7016 PCI Fast Ethernet driver for Etherboot 55b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Copyright (C) 2001 Entity Cyber, Inc. 65b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 75b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Revision: 1.0 March 1, 2001 85b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 95b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Author: Marty Connor (mdc@thinguin.org) 105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Adapted from a Linux driver which was written by Donald Becker 125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project and modified by Ollie Lho and Chin-Shan Li of SiS Corporation. 135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Rewritten for Etherboot by Marty Connor. 145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project This software may be used and distributed according to the terms 165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project of the GNU Public License (GPL), incorporated herein by reference. 175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project References: 195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project SiS 7016 Fast Ethernet PCI Bus 10/100 Mbps LAN Controller with OnNow Support, 205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project preliminary Rev. 1.0 Jan. 14, 1998 215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project SiS 900 Fast Ethernet PCI Bus 10/100 Mbps LAN Single Chip with OnNow Support, 225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project preliminary Rev. 1.0 Nov. 10, 1998 235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project SiS 7014 Single Chip 100BASE-TX/10BASE-T Physical Layer Solution, 245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project preliminary Rev. 1.0 Jan. 18, 1998 255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project http://www.sis.com.tw/support/databook.htm */ 265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Revision History */ 285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* 305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 01 March 2001 mdc 1.0 315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Initial Release. Tested with PCI based sis900 card and ThinkNIC 325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project computer. 335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 20 March 2001 P.Koegel 345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project added support for sis630e and PHY ICS1893 and RTL8201 355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Testet with SIS730S chipset + ICS1893 365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*/ 375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Includes */ 405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "etherboot.h" 425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "nic.h" 435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "pci.h" 445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "cards.h" 455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "sis900.h" 475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Globals */ 495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int sis900_debug = 0; 515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned short vendor, dev_id; 535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned long ioaddr; 545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned int cur_phy; 565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned int cur_rx; 585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic BufferDesc txd; 605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic BufferDesc rxd[NUM_RX_DESC]; 615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef USE_LOWMEM_BUFFER 635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define txb ((char *)0x10000 - TX_BUF_SIZE) 645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define rxb ((char *)0x10000 - NUM_RX_DESC*RX_BUF_SIZE - TX_BUF_SIZE) 655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else 665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned char txb[TX_BUF_SIZE]; 675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE]; 685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic struct mac_chip_info { 715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project const char *name; 725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u16 vendor_id, device_id, flags; 735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int io_size; 745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} mac_chip_table[] = { 755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { "SiS 900 PCI Fast Ethernet", PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS900, 765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project PCI_COMMAND_IO|PCI_COMMAND_MASTER, SIS900_TOTAL_SIZE}, 775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { "SiS 7016 PCI Fast Ethernet",PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS7016, 785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project PCI_COMMAND_IO|PCI_COMMAND_MASTER, SIS900_TOTAL_SIZE}, 795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {0,0,0,0,0} /* 0 terminated list. */ 805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}; 815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void sis900_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex); 835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void amd79c901_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex); 845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void ics1893_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex); 855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void rtl8201_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex); 865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic struct mii_chip_info { 885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project const char * name; 895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u16 phy_id0; 905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u16 phy_id1; 915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project void (*read_mode) (struct nic *nic, int phy_addr, int *speed, int *duplex); 925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} mii_chip_table[] = { 935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"SiS 900 Internal MII PHY", 0x001d, 0x8000, sis900_read_mode}, 945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"SiS 7014 Physical Layer Solution", 0x0016, 0xf830,sis900_read_mode}, 955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"AMD 79C901 10BASE-T PHY", 0x0000, 0x35b9, amd79c901_read_mode}, 965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"AMD 79C901 HomePNA PHY", 0x0000, 0x35c8, amd79c901_read_mode}, 975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"ICS 1893 Integrated PHYceiver" , 0x0015, 0xf441,ics1893_read_mode}, 985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"RTL 8201 10/100Mbps Phyceiver" , 0x0000, 0x8201,rtl8201_read_mode}, 995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {0,0,0,0} 1005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}; 1015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic struct mii_phy { 1035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project struct mii_phy * next; 1045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project struct mii_chip_info * chip_info; 1055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int phy_addr; 1065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u16 status; 1075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} mii; 1085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project// PCI to ISA bridge for SIS640E access 1115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic struct pci_device pci_isa_bridge_list[] = { 1125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 0x1039, 0x0008, 1135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project "SIS 85C503/5513 PCI to ISA bridge", 0, 0, 0, 0}, 1145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {0, 0, NULL, 0, 0, 0, 0} 1155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}; 1165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Function Prototypes */ 1185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct nic *sis900_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci); 1205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic u16 sis900_read_eeprom(int location); 1225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void sis900_mdio_reset(long mdio_addr); 1235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void sis900_mdio_idle(long mdio_addr); 1245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic u16 sis900_mdio_read(int phy_id, int location); 1255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void sis900_mdio_write(int phy_id, int location, int val); 1265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void sis900_init(struct nic *nic); 1285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void sis900_reset(struct nic *nic); 1305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void sis900_init_rxfilter(struct nic *nic); 1325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void sis900_init_txd(struct nic *nic); 1335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void sis900_init_rxd(struct nic *nic); 1345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void sis900_set_rx_mode(struct nic *nic); 1355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void sis900_check_mode(struct nic *nic); 1365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void sis900_transmit(struct nic *nic, const char *d, 1385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned int t, unsigned int s, const char *p); 1395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int sis900_poll(struct nic *nic); 1405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void sis900_disable(struct nic *nic); 1425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/** 1445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * sis900_get_mac_addr: - Get MAC address for stand alone SiS900 model 1455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * @pci_dev: the sis900 pci device 1465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * @net_dev: the net device to get address for 1475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 1485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Older SiS900 and friends, use EEPROM to store MAC address. 1495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * MAC address is read from read_eeprom() into @net_dev->dev_addr. 1505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 1515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int sis900_get_mac_addr(struct pci_device * pci_dev , struct nic *nic) 1535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 1545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u16 signature; 1555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int i; 1565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* check to see if we have sane EEPROM */ 1585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project signature = (u16) sis900_read_eeprom( EEPROMSignature); 1595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (signature == 0xffff || signature == 0x0000) { 1605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf ("sis900_probe: Error EERPOM read %hX\n", signature); 1615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return 0; 1625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 1635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* get MAC address from EEPROM */ 1655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 0; i < 3; i++) 1665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ((u16 *)(nic->node_addr))[i] = sis900_read_eeprom(i+EEPROMMACAddr); 1675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return 1; 1685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 1695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/** 1715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * sis630e_get_mac_addr: - Get MAC address for SiS630E model 1725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * @pci_dev: the sis900 pci device 1735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * @net_dev: the net device to get address for 1745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 1755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * SiS630E model, use APC CMOS RAM to store MAC address. 1765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * APC CMOS RAM is accessed through ISA bridge. 1775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * MAC address is read into @net_dev->dev_addr. 1785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 1795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int sis630e_get_mac_addr(struct pci_device * pci_dev, struct nic *nic) 1815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 1825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u8 reg; 1835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int i; 1845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project struct pci_device *p; 1855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project // find PCI to ISA bridge 1875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_pci_init(pci_isa_bridge_list); 1885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* the firts entry in this list should contain bus/devfn */ 1905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project p = pci_isa_bridge_list; 1915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project pcibios_read_config_byte(p->bus,p->devfn, 0x48, ®); 1935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project pcibios_write_config_byte(p->bus,p->devfn, 0x48, reg | 0x40); 1945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 0; i < ETH_ALEN; i++) 1965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 1975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0x09 + i, 0x70); 1985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ((u8 *)(nic->node_addr))[i] = inb(0x71); 1995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 2005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project pcibios_write_config_byte(p->bus,p->devfn, 0x48, reg & ~0x40); 2015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return 1; 2035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 2045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* 2065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Function: sis900_probe 2075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 2085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Description: initializes initializes the NIC, retrieves the 2095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * MAC address of the card, and sets up some globals required by 2105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * other routines. 2115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 2125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Side effects: 2135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * leaves the ioaddress of the sis900 chip in the variable ioaddr. 2145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * leaves the sis900 initialized, and ready to recieve packets. 2155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 2165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Returns: struct nic *: pointer to NIC data structure 2175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 2185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct nic *sis900_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci) 2205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 2215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int i; 2225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int found=0; 2235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int phy_addr; 2245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u16 signature; 2255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u8 revision; 2265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int ret; 2275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (io_addrs == 0 || *io_addrs == 0) 2295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return NULL; 2305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ioaddr = *io_addrs & ~3; 2325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project vendor = pci->vendor; 2335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project dev_id = pci->dev_id; 2345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* wakeup chip */ 2365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project pcibios_write_config_dword(pci->bus, pci->devfn, 0x40, 0x00000000); 2375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project adjust_pci_device(pci); 2395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* get MAC address */ 2415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ret = 0; 2425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project pcibios_read_config_byte(pci->bus,pci->devfn, PCI_REVISION, &revision); 2435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (revision == SIS630E_900_REV || revision == SIS630EA1_900_REV) 2445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ret = sis630e_get_mac_addr(pci, nic); 2455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else if (revision == SIS630S_900_REV) 2465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ret = sis630e_get_mac_addr(pci, nic); 2475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 2485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ret = sis900_get_mac_addr(pci, nic); 2495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (ret == 0) 2515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 2525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf ("sis900_probe: Error MAC address not found\n"); 2535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return NULL; 2545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 2555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("\nsis900_probe: MAC addr %! at ioaddr %#hX\n", 2575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->node_addr, ioaddr); 2585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("sis900_probe: Vendor:%#hX Device:%#hX\n", vendor, dev_id); 2595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* probe for mii transceiver */ 2615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* search for total of 32 possible mii phy addresses */ 2625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project found = 0; 2645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (phy_addr = 0; phy_addr < 32; phy_addr++) { 2655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u16 mii_status; 2665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u16 phy_id0, phy_id1; 2675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mii_status = sis900_mdio_read(phy_addr, MII_STATUS); 2695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (mii_status == 0xffff || mii_status == 0x0000) 2705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* the mii is not accessable, try next one */ 2715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project continue; 2725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project phy_id0 = sis900_mdio_read(phy_addr, MII_PHY_ID0); 2745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project phy_id1 = sis900_mdio_read(phy_addr, MII_PHY_ID1); 2755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* search our mii table for the current mii */ 2775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 0; mii_chip_table[i].phy_id1; i++) { 2785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (phy_id0 == mii_chip_table[i].phy_id0) { 2805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("sis900_probe: %s transceiver found at address %d.\n", 2825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mii_chip_table[i].name, phy_addr); 2835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mii.chip_info = &mii_chip_table[i]; 2855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mii.phy_addr = phy_addr; 2865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mii.status = sis900_mdio_read(phy_addr, MII_STATUS); 2875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mii.next = NULL; 2885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project found=1; 2905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 2915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 2925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 2935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 2945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (found == 0) { 2965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("sis900_probe: No MII transceivers found!\n"); 2975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return NULL; 2985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 2995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Arbitrarily select the last PHY found as current PHY */ 3015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_phy = mii.phy_addr; 3025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("sis900_probe: Using %s as default\n", mii.chip_info->name); 3035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* initialize device */ 3055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_init(nic); 3065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->reset = sis900_init; 3085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->poll = sis900_poll; 3095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->transmit = sis900_transmit; 3105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->disable = sis900_disable; 3115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return nic; 3135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 3145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* 3175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * EEPROM Routines: These functions read and write to EEPROM for 3185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * retrieving the MAC address and other configuration information about 3195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * the card. 3205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 3215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Delay between EEPROM clock transitions. */ 3235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define eeprom_delay() inl(ee_addr) 3245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Function: sis900_read_eeprom 3275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 3285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Description: reads and returns a given location from EEPROM 3295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 3305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Arguments: int location: requested EEPROM location 3315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 3325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Returns: u16: contents of requested EEPROM location 3335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 3345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 3355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Read Serial EEPROM through EEPROM Access Register, Note that location is 3375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project in word (16 bits) unit */ 3385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic u16 sis900_read_eeprom(int location) 3395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 3405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int i; 3415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u16 retval = 0; 3425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project long ee_addr = ioaddr + mear; 3435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u32 read_cmd = location | EEread; 3445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(0, ee_addr); 3465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eeprom_delay(); 3475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(EECLK, ee_addr); 3485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eeprom_delay(); 3495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Shift the read command (9) bits out. */ 3515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 8; i >= 0; i--) { 3525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u32 dataval = (read_cmd & (1 << i)) ? EEDI | EECS : EECS; 3535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(dataval, ee_addr); 3545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eeprom_delay(); 3555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(dataval | EECLK, ee_addr); 3565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eeprom_delay(); 3575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 3585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(EECS, ee_addr); 3595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eeprom_delay(); 3605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* read the 16-bits data in */ 3625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 16; i > 0; i--) { 3635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(EECS, ee_addr); 3645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eeprom_delay(); 3655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(EECS | EECLK, ee_addr); 3665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eeprom_delay(); 3675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project retval = (retval << 1) | ((inl(ee_addr) & EEDO) ? 1 : 0); 3685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eeprom_delay(); 3695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 3705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Terminate the EEPROM access. */ 3725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(0, ee_addr); 3735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eeprom_delay(); 3745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(EECLK, ee_addr); 3755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return (retval); 3775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 3785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define sis900_mdio_delay() inl(mdio_addr) 3805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* 3835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Read and write the MII management registers using software-generated 3845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project serial MDIO protocol. Note that the command bits and data bits are 3855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project send out seperately 3865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*/ 3875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void sis900_mdio_idle(long mdio_addr) 3895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 3905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(MDIO | MDDIR, mdio_addr); 3915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_mdio_delay(); 3925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(MDIO | MDDIR | MDC, mdio_addr); 3935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 3945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Syncronize the MII management interface by shifting 32 one bits out. */ 3965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void sis900_mdio_reset(long mdio_addr) 3975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 3985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int i; 3995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 31; i >= 0; i--) { 4015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(MDDIR | MDIO, mdio_addr); 4025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_mdio_delay(); 4035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(MDDIR | MDIO | MDC, mdio_addr); 4045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_mdio_delay(); 4055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return; 4075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 4085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic u16 sis900_mdio_read(int phy_id, int location) 4105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 4115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project long mdio_addr = ioaddr + mear; 4125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int mii_cmd = MIIread|(phy_id<<MIIpmdShift)|(location<<MIIregShift); 4135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u16 retval = 0; 4145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int i; 4155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_mdio_reset(mdio_addr); 4175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_mdio_idle(mdio_addr); 4185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 15; i >= 0; i--) { 4205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR; 4215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(dataval, mdio_addr); 4225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_mdio_delay(); 4235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(dataval | MDC, mdio_addr); 4245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_mdio_delay(); 4255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Read the 16 data bits. */ 4285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 16; i > 0; i--) { 4295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(0, mdio_addr); 4305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_mdio_delay(); 4315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project retval = (retval << 1) | ((inl(mdio_addr) & MDIO) ? 1 : 0); 4325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(MDC, mdio_addr); 4335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_mdio_delay(); 4345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return retval; 4365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 4375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void sis900_mdio_write(int phy_id, int location, int value) 4395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 4405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project long mdio_addr = ioaddr + mear; 4415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int mii_cmd = MIIwrite|(phy_id<<MIIpmdShift)|(location<<MIIregShift); 4425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int i; 4435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_mdio_reset(mdio_addr); 4455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_mdio_idle(mdio_addr); 4465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Shift the command bits out. */ 4485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 15; i >= 0; i--) { 4495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR; 4505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(dataval, mdio_addr); 4515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_mdio_delay(); 4525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(dataval | MDC, mdio_addr); 4535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_mdio_delay(); 4545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_mdio_delay(); 4565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Shift the value bits out. */ 4585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 15; i >= 0; i--) { 4595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int dataval = (value & (1 << i)) ? MDDIR | MDIO : MDDIR; 4605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(dataval, mdio_addr); 4615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_mdio_delay(); 4625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(dataval | MDC, mdio_addr); 4635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_mdio_delay(); 4645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_mdio_delay(); 4665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Clear out extra bits. */ 4685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 2; i > 0; i--) { 4695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0, mdio_addr); 4705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_mdio_delay(); 4715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(MDC, mdio_addr); 4725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_mdio_delay(); 4735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return; 4755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 4765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Function: sis900_init 4795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 4805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Description: resets the ethernet controller chip and various 4815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * data structures required for sending and receiving packets. 4825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 4835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Arguments: struct nic *nic: NIC data structure 4845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 4855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * returns: void. 4865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 4875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void 4895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectsis900_init(struct nic *nic) 4905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 4915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Soft reset the chip. */ 4925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_reset(nic); 4935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_init_rxfilter(nic); 4955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_init_txd(nic); 4975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_init_rxd(nic); 4985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_set_rx_mode(nic); 5005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project sis900_check_mode(nic); 5025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(RxENA, ioaddr + cr); 5045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 5055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* 5085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Function: sis900_reset 5095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 5105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Description: disables interrupts and soft resets the controller chip 5115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 5125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Arguments: struct nic *nic: NIC data structure 5135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 5145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Returns: void. 5155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 5165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void 5185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectsis900_reset(struct nic *nic) 5195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 5205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int i = 0; 5215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u32 status = TxRCMP | RxRCMP; 5225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(0, ioaddr + ier); 5245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(0, ioaddr + imr); 5255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(0, ioaddr + rfcr); 5265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(RxRESET | TxRESET | RESET, ioaddr + cr); 5285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Check that the chip has finished the reset. */ 5305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project while (status && (i++ < 1000)) { 5315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project status ^= (inl(isr + ioaddr) & status); 5325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(PESEL, ioaddr + cfg); 5345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 5355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Function: sis_init_rxfilter 5385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 5395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Description: sets receive filter address to our MAC address 5405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 5415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Arguments: struct nic *nic: NIC data structure 5425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 5435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * returns: void. 5445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 5455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void 5475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectsis900_init_rxfilter(struct nic *nic) 5485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 5495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u32 rfcrSave; 5505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int i; 5515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project rfcrSave = inl(rfcr + ioaddr); 5535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* disable packet filtering before setting filter */ 5555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(rfcrSave & ~RFEN, rfcr); 5565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* load MAC addr to filter data register */ 5585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 0 ; i < 3 ; i++) { 5595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u32 w; 5605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project w = (u32) *((u16 *)(nic->node_addr)+i); 5625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl((i << RFADDR_shift), ioaddr + rfcr); 5635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(w, ioaddr + rfdr); 5645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (sis900_debug > 0) 5665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("sis900_init_rxfilter: Receive Filter Addrss[%d]=%X\n", 5675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project i, inl(ioaddr + rfdr)); 5685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* enable packet filitering */ 5715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(rfcrSave | RFEN, rfcr + ioaddr); 5725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 5735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* 5765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Function: sis_init_txd 5775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 5785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Description: initializes the Tx descriptor 5795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 5805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Arguments: struct nic *nic: NIC data structure 5815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 5825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * returns: void. 5835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 5845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void 5865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectsis900_init_txd(struct nic *nic) 5875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 5885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project txd.link = (u32) 0; 5895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project txd.cmdsts = (u32) 0; 5905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project txd.bufptr = (u32) &txb[0]; 5915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* load Transmit Descriptor Register */ 5935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl((u32) &txd, ioaddr + txdp); 5945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (sis900_debug > 0) 5955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("sis900_init_txd: TX descriptor register loaded with: %X\n", 5965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project inl(ioaddr + txdp)); 5975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 5985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Function: sis_init_rxd 6015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 6025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Description: initializes the Rx descriptor ring 6035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 6045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Arguments: struct nic *nic: NIC data structure 6055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 6065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Returns: void. 6075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 6085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void 6105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectsis900_init_rxd(struct nic *nic) 6115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 6125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int i; 6135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_rx = 0; 6155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* init RX descriptor */ 6175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 0; i < NUM_RX_DESC; i++) { 6185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project rxd[i].link = (i+1 < NUM_RX_DESC) ? (u32) &rxd[i+1] : (u32) &rxd[0]; 6195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project rxd[i].cmdsts = (u32) RX_BUF_SIZE; 6205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project rxd[i].bufptr = (u32) &rxb[i*RX_BUF_SIZE]; 6215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (sis900_debug > 0) 6225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("sis900_init_rxd: rxd[%d]=%X link=%X cmdsts=%X bufptr=%X\n", 6235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project i, &rxd[i], rxd[i].link, rxd[i].cmdsts, rxd[i].bufptr); 6245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 6255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* load Receive Descriptor Register */ 6275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl((u32) &rxd[0], ioaddr + rxdp); 6285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (sis900_debug > 0) 6305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("sis900_init_rxd: RX descriptor register loaded with: %X\n", 6315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project inl(ioaddr + rxdp)); 6325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 6345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Function: sis_init_rxd 6375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 6385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Description: 6395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * sets the receive mode to accept all broadcast packets and packets 6405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * with our MAC address, and reject all multicast packets. 6415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 6425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Arguments: struct nic *nic: NIC data structure 6435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 6445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Returns: void. 6455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 6465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void sis900_set_rx_mode(struct nic *nic) 6485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 6495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int i; 6505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Configure Multicast Hash Table in Receive Filter 6525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project to reject all MCAST packets */ 6535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 0; i < 8; i++) { 6545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* why plus 0x04? That makes the correct value for hash table. */ 6555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl((u32)(0x00000004+i) << RFADDR_shift, ioaddr + rfcr); 6565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl((u32)(0x0), ioaddr + rfdr); 6575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 6585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Accept Broadcast packets, destination addresses that match 6595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project our MAC address */ 6605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(RFEN | RFAAB, ioaddr + rfcr); 6615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return; 6635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 6645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Function: sis900_check_mode 6675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 6685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Description: checks the state of transmit and receive 6695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * parameters on the NIC, and updates NIC registers to match 6705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 6715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Arguments: struct nic *nic: NIC data structure 6725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 6735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Returns: void. 6745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 6755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void 6775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectsis900_check_mode (struct nic *nic) 6785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 6795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int speed, duplex; 6805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u32 tx_flags = 0, rx_flags = 0; 6815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project mii.chip_info->read_mode(nic, cur_phy, &speed, &duplex); 6835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project tx_flags = TxATP | (TX_DMA_BURST << TxMXDMA_shift) | (TX_FILL_THRESH << TxFILLT_shift); 6855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project rx_flags = RX_DMA_BURST << RxMXDMA_shift; 6865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (speed == HW_SPEED_HOME || speed == HW_SPEED_10_MBPS) { 6885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project rx_flags |= (RxDRNT_10 << RxDRNT_shift); 6895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project tx_flags |= (TxDRNT_10 << TxDRNT_shift); 6905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 6915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else { 6925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project rx_flags |= (RxDRNT_100 << RxDRNT_shift); 6935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project tx_flags |= (TxDRNT_100 << TxDRNT_shift); 6945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 6955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (duplex == FDX_CAPABLE_FULL_SELECTED) { 6975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project tx_flags |= (TxCSI | TxHBI); 6985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project rx_flags |= RxATX; 6995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 7005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl (tx_flags, ioaddr + txcfg); 7025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl (rx_flags, ioaddr + rxcfg); 7035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 7045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Function: sis900_read_mode 7075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 7085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Description: retrieves and displays speed and duplex 7095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * parameters from the NIC 7105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 7115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Arguments: struct nic *nic: NIC data structure 7125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 7135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Returns: void. 7145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 7155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void 7175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectsis900_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex) 7185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 7195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int i = 0; 7205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u32 status; 7215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* STSOUT register is Latched on Transition, read operation updates it */ 7235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project while (i++ < 2) 7245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project status = sis900_mdio_read(phy_addr, MII_STSOUT); 7255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (status & MII_STSOUT_SPD) 7275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *speed = HW_SPEED_100_MBPS; 7285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 7295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *speed = HW_SPEED_10_MBPS; 7305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (status & MII_STSOUT_DPLX) 7325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *duplex = FDX_CAPABLE_FULL_SELECTED; 7335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 7345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *duplex = FDX_CAPABLE_HALF_SELECTED; 7355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (status & MII_STSOUT_LINK_FAIL) 7375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("sis900_read_mode: Media Link Off\n"); 7385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 7395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("sis900_read_mode: Media Link On %s %s-duplex \n", 7405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *speed == HW_SPEED_100_MBPS ? 7415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project "100mbps" : "10mbps", 7425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *duplex == FDX_CAPABLE_FULL_SELECTED ? 7435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project "full" : "half"); 7445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 7455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Function: amd79c901_read_mode 7485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 7495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Description: retrieves and displays speed and duplex 7505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * parameters from the NIC 7515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 7525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Arguments: struct nic *nic: NIC data structure 7535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 7545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Returns: void. 7555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 7565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void 7585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectamd79c901_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex) 7595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 7605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int i; 7615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u16 status; 7625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 0; i < 2; i++) 7645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project status = sis900_mdio_read(phy_addr, MII_STATUS); 7655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (status & MII_STAT_CAN_AUTO) { 7675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* 10BASE-T PHY */ 7685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 0; i < 2; i++) 7695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project status = sis900_mdio_read(phy_addr, MII_STATUS_SUMMARY); 7705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (status & MII_STSSUM_SPD) 7715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *speed = HW_SPEED_100_MBPS; 7725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 7735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *speed = HW_SPEED_10_MBPS; 7745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (status & MII_STSSUM_DPLX) 7755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *duplex = FDX_CAPABLE_FULL_SELECTED; 7765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 7775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *duplex = FDX_CAPABLE_HALF_SELECTED; 7785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (status & MII_STSSUM_LINK) 7805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("amd79c901_read_mode: Media Link On %s %s-duplex \n", 7815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *speed == HW_SPEED_100_MBPS ? 7825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project "100mbps" : "10mbps", 7835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *duplex == FDX_CAPABLE_FULL_SELECTED ? 7845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project "full" : "half"); 7855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 7865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("amd79c901_read_mode: Media Link Off\n"); 7875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 7885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else { 7895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* HomePNA */ 7905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *speed = HW_SPEED_HOME; 7915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *duplex = FDX_CAPABLE_HALF_SELECTED; 7925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (status & MII_STAT_LINK) 7935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("amd79c901_read_mode:Media Link On 1mbps half-duplex \n"); 7945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 7955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("amd79c901_read_mode: Media Link Off\n"); 7965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 7975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 7985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/** 8015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * ics1893_read_mode: - read media mode for ICS1893 PHY 8025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * @net_dev: the net device to read mode for 8035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * @phy_addr: mii phy address 8045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * @speed: the transmit speed to be determined 8055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * @duplex: the duplex mode to be determined 8065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 8075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * ICS1893 PHY use Quick Poll Detailed Status register 8085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * to determine the speed and duplex mode for sis900 8095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 8105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void ics1893_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex) 8125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 8135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int i = 0; 8145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u32 status; 8155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* MII_QPDSTS is Latched, read twice in succession will reflect the current state */ 8175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 0; i < 2; i++) 8185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project status = sis900_mdio_read(phy_addr, MII_QPDSTS); 8195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (status & MII_STSICS_SPD) 8215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *speed = HW_SPEED_100_MBPS; 8225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 8235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *speed = HW_SPEED_10_MBPS; 8245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (status & MII_STSICS_DPLX) 8265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *duplex = FDX_CAPABLE_FULL_SELECTED; 8275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 8285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *duplex = FDX_CAPABLE_HALF_SELECTED; 8295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (status & MII_STSICS_LINKSTS) 8315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("ics1893_read_mode: Media Link On %s %s-duplex \n", 8325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *speed == HW_SPEED_100_MBPS ? 8335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project "100mbps" : "10mbps", 8345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *duplex == FDX_CAPABLE_FULL_SELECTED ? 8355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project "full" : "half"); 8365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 8375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("ics1893_read_mode: Media Link Off\n"); 8385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 8395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/** 8415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * rtl8201_read_mode: - read media mode for rtl8201 phy 8425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * @nic: the net device to read mode for 8435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * @phy_addr: mii phy address 8445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * @speed: the transmit speed to be determined 8455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * @duplex: the duplex mode to be determined 8465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 8475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * read MII_STATUS register from rtl8201 phy 8485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * to determine the speed and duplex mode for sis900 8495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 8505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void rtl8201_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex) 8525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 8535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u32 status; 8545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project status = sis900_mdio_read(phy_addr, MII_STATUS); 8565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (status & MII_STAT_CAN_TX_FDX) { 8585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *speed = HW_SPEED_100_MBPS; 8595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *duplex = FDX_CAPABLE_FULL_SELECTED; 8605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 8615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else if (status & MII_STAT_CAN_TX) { 8625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *speed = HW_SPEED_100_MBPS; 8635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *duplex = FDX_CAPABLE_HALF_SELECTED; 8645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 8655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else if (status & MII_STAT_CAN_T_FDX) { 8665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *speed = HW_SPEED_10_MBPS; 8675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *duplex = FDX_CAPABLE_FULL_SELECTED; 8685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 8695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else if (status & MII_STAT_CAN_T) { 8705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *speed = HW_SPEED_10_MBPS; 8715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *duplex = FDX_CAPABLE_HALF_SELECTED; 8725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 8735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (status & MII_STAT_LINK) 8755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("rtl8201_read_mode: Media Link On %s %s-duplex \n", 8765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *speed == HW_SPEED_100_MBPS ? 8775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project "100mbps" : "10mbps", 8785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *duplex == FDX_CAPABLE_FULL_SELECTED ? 8795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project "full" : "half"); 8805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 8815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("rtl9201_read_config_mode: Media Link Off\n"); 8825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 8835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Function: sis900_transmit 8855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 8865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Description: transmits a packet and waits for completion or timeout. 8875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 8885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Arguments: char d[6]: destination ethernet address. 8895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * unsigned short t: ethernet protocol type. 8905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * unsigned short s: size of the data-part of the packet. 8915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * char *p: the data for the packet. 8925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 8935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Returns: void. 8945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 8955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void 8975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectsis900_transmit(struct nic *nic, 8985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project const char *d, /* Destination */ 8995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned int t, /* Type */ 9005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned int s, /* size */ 9015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project const char *p) /* Packet */ 9025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 9035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u32 status, to, nstype; 9045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u32 tx_status; 9055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Stop the transmitter */ 9075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(TxDIS, ioaddr + cr); 9085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* load Transmit Descriptor Register */ 9105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl((u32) &txd, ioaddr + txdp); 9115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (sis900_debug > 1) 9125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("sis900_transmit: TX descriptor register loaded with: %X\n", 9135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project inl(ioaddr + txdp)); 9145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memcpy(txb, d, ETH_ALEN); 9165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN); 9175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nstype = htons(t); 9185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memcpy(txb + 2 * ETH_ALEN, (char*)&nstype, 2); 9195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memcpy(txb + ETH_HLEN, p, s); 9205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project s += ETH_HLEN; 9225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project s &= DSIZE; 9235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (sis900_debug > 1) 9255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("sis900_transmit: sending %d bytes ethtype %hX\n", (int) s, t); 9265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* pad to minimum packet size */ 9285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project while (s < ETH_ZLEN) 9295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project txb[s++] = '\0'; 9305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* set the transmit buffer descriptor and enable Transmit State Machine */ 9325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project txd.bufptr = (u32) &txb[0]; 9335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project txd.cmdsts = (u32) OWN | s; 9345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* restart the transmitter */ 9365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(TxENA, ioaddr + cr); 9375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (sis900_debug > 1) 9395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("sis900_transmit: Queued Tx packet size %d.\n", (int) s); 9405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project to = currticks() + TX_TIMEOUT; 9425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project while ((((volatile u32) tx_status=txd.cmdsts) & OWN) && (currticks() < to)) 9445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* wait */ ; 9455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (currticks() >= to) { 9475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("sis900_transmit: TX Timeout! Tx status %X.\n", tx_status); 9485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 9495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (tx_status & (ABORT | UNDERRUN | OWCOLL)) { 9515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* packet unsuccessfully transmited */ 9525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("sis900_transmit: Transmit error, Tx status %X.\n", tx_status); 9535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 9545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Disable interrupts by clearing the interrupt mask. */ 9555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(0, ioaddr + imr); 9565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 9575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Function: sis900_poll 9605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 9615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Description: checks for a received packet and returns it if found. 9625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 9635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Arguments: struct nic *nic: NIC data structure 9645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 9655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Returns: 1 if a packet was recieved. 9665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 0 if no pacet was recieved. 9675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 9685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Side effects: 9695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Returns (copies) the packet to the array nic->packet. 9705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Returns the length of the packet in nic->packetlen. 9715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 9725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int 9745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectsis900_poll(struct nic *nic) 9755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 9765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u32 rx_status = rxd[cur_rx].cmdsts; 9775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int retstat = 0; 9785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (sis900_debug > 2) 9805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("sis900_poll: cur_rx:%d, status:%X\n", cur_rx, rx_status); 9815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (!(rx_status & OWN)) 9835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return retstat; 9845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (sis900_debug > 1) 9865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("sis900_poll: got a packet: cur_rx:%d, status:%X\n", 9875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_rx, rx_status); 9885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->packetlen = (rx_status & DSIZE) - CRC_SIZE; 9905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 9915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) { 9925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* corrupted packet received */ 9935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("sis900_poll: Corrupted packet received, buffer status = %X\n", 9945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project rx_status); 9955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project retstat = 0; 9965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } else { 9975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* give packet to higher level routine */ 9985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memcpy(nic->packet, (rxb + cur_rx*RX_BUF_SIZE), nic->packetlen); 9995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project retstat = 1; 10005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 10015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 10025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* return the descriptor and buffer to receive ring */ 10035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project rxd[cur_rx].cmdsts = RX_BUF_SIZE; 10045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project rxd[cur_rx].bufptr = (u32) &rxb[cur_rx*RX_BUF_SIZE]; 10055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 10065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (++cur_rx == NUM_RX_DESC) 10075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cur_rx = 0; 10085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 10095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* re-enable the potentially idle receive state machine */ 10105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(RxENA , ioaddr + cr); 10115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 10125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return retstat; 10135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 10145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 10155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 10165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Function: sis900_disable 10175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 10185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Description: Turns off interrupts and stops Tx and Rx engines 10195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 10205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Arguments: struct nic *nic: NIC data structure 10215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 10225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Returns: void. 10235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 10245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 10255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void 10265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectsis900_disable(struct nic *nic) 10275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 10285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Disable interrupts by clearing the interrupt mask. */ 10295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(0, ioaddr + imr); 10305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(0, ioaddr + ier); 10315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 10325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Stop the chip's Tx and Rx Status Machine */ 10335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(RxDIS | TxDIS, ioaddr + cr); 10345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 1035