123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592 |
-
-
-
-
-
- #include "etherboot.h"
-
- #include "nic.h"
-
- #include "isa.h"
-
- #include "hardware.h"
- #include "mii.h"
- #include "timer.h"
-
-
-
- static unsigned char MAC_HW_ADDR[6]={MAC_HW_ADDR_DRV};
-
-
- #define NUM_RX_DESC 4
- #define DMA_BUF_SIZE 2048
- static DMA_DSC txd __attribute__ ((__section__(".dma.desc")));
- static DMA_DSC rxd[NUM_RX_DESC] __attribute__ ((__section__(".dma.desc")));
- static char rxb[NUM_RX_DESC * DMA_BUF_SIZE] __attribute__ ((__section__(".dma.buffer")));
- static char txb[ DMA_BUF_SIZE] __attribute__ ((__section__(".dma.buffer")));
- static unsigned int cur_rx;
-
-
- static unsigned int cur_channel;
- static unsigned int cur_phy;
- static P2001_ETH_regs_ptr EU;
-
-
- static int p2001_eth_mdio_read (int phy_id, int location);
- static void p2001_eth_mdio_write(int phy_id, int location, int val);
-
-
- static int p2001_eth_poll (struct nic *nic, int retrieve);
- static void p2001_eth_transmit (struct nic *nic, const char *d,
- unsigned int t, unsigned int s, const char *p);
-
- static void p2001_eth_irq (struct nic *nic, irq_action_t action);
-
- static void p2001_eth_init ();
- static void p2001_eth_disable (struct dev *dev);
-
- static int p2001_eth_check_link(unsigned int phy);
- static int link;
- static void p2001_eth_phyreset ();
- static int p2001_eth_probe (struct dev *dev, unsigned short *probe_addrs __unused);
-
-
- static struct mii_chip_info {
- const char * name;
- unsigned int physid;
- } mii_chip_table[] = {
- { "Intel LXT971A", 0x78e20013 },
- { "Altima AC104-QF", 0x55410022 },
- {NULL,0},
- };
-
-
-
-
-
-
- static int p2001_eth_mdio_read(int phy_id, int location)
- {
- int result, boguscnt = 1000;
-
- do {
-
- while (P2001_MU->MU_CNTL & 0x8000)
- barrier();
-
-
- P2001_MU->MU_CNTL = location + (phy_id<<5) + (2<<10);
-
-
- while ((P2001_MU->MU_CNTL & 0x8000) == 0)
- barrier();
-
-
-
- while (P2001_MU->MU_CNTL & 0x8000)
- barrier();
-
-
- } while ((P2001_MU->MU_CNTL & 0x4000) && (--boguscnt > 0));
-
-
- result = P2001_MU->MU_DATA;
-
- if (boguscnt == 0)
- return 0;
- if ((result & 0xffff) == 0xffff)
- return 0;
-
- return result & 0xffff;
- }
-
-
-
- static void p2001_eth_mdio_write(int phy_id, int location, int val)
- {
-
- while (P2001_MU->MU_CNTL & 0x8000)
- barrier();
-
-
- P2001_MU->MU_DATA = val;
-
-
- P2001_MU->MU_CNTL = location + (phy_id<<5) + (1<<10);
-
-
- while ((P2001_MU->MU_CNTL & 0x8000) == 0)
- barrier();
-
-
-
- while (P2001_MU->MU_CNTL & 0x8000)
- barrier();
- }
-
-
-
-
-
-
- static int p2001_eth_poll(struct nic *nic, int retrieve)
- {
-
-
-
-
- int retstat = 0;
-
- if (rxd[cur_rx].stat & (1<<31))
- return retstat;
-
- if (!retrieve)
- return 1;
-
- nic->packetlen = rxd[cur_rx].cntl & 0xffff;
-
- if (rxd[cur_rx].stat & ((1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22))) {
-
- printf("p2001_eth_poll: Corrupted packet received, stat = %X\n",
- rxd[cur_rx].stat);
- retstat = 0;
- } else {
-
- memcpy(nic->packet, (rxb + cur_rx*DMA_BUF_SIZE), nic->packetlen);
- retstat = 1;
- }
-
- #ifdef DEBUG_NIC
- printf("p2001_eth_poll: packet from %! to %! received\n",
- (rxb+cur_rx*DMA_BUF_SIZE)+ETH_ALEN,
- (rxb+cur_rx*DMA_BUF_SIZE));
- #endif
-
-
-
- EU->RMAC_DMA_EN = 0;
-
-
- rxd[cur_rx].stat = (1<<31) | (1<<30) | (1<<29);
- rxd[cur_rx].cntl = (1<<23);
- rxd[cur_rx].cntl |= cur_channel << 16;
- rxd[cur_rx].cntl |= DMA_BUF_SIZE;
-
- if (++cur_rx == NUM_RX_DESC)
- cur_rx = 0;
-
-
- if (!(EU->RMAC_DMA_EN & 0x01))
- EU->RMAC_DMA_EN = 0x01;
-
- #ifdef DEBUG_NIC
- printf("RMAC_MIB0..5: %d:%d:%d:%d:%d:%d\n",
- EU->RMAC_MIB0, EU->RMAC_MIB1,
- EU->RMAC_MIB2, EU->RMAC_MIB3,
- EU->RMAC_MIB4, EU->RMAC_MIB5);
- #endif
-
- return retstat;
- }
-
-
-
-
-
-
- static void p2001_eth_transmit(
- struct nic *nic __unused,
- const char *d,
- unsigned int t,
- unsigned int s,
- const char *p)
- {
- unsigned int nstype;
- #ifdef DEBUG_NIC
- unsigned int status;
- #endif
-
-
- memcpy(txb, d, ETH_ALEN);
- memcpy(txb+ETH_ALEN, nic->node_addr, ETH_ALEN);
- nstype = htons(t);
- memcpy(txb+2*ETH_ALEN, (char*)&nstype, 2);
- memcpy(txb+ETH_HLEN, p, s);
- s += ETH_HLEN;
-
-
-
-
-
-
- #ifdef DEBUG_NIC
- printf("p2001_eth_transmit: packet from %! to %! sent (size: %d)\n", txb+ETH_ALEN, txb, s);
- #endif
-
-
- txd.stat = (1<<31) | (1<<30) | (1<<29);
- txd.cntl = cur_channel << 16;
- txd.cntl |= s;
-
-
- EU->TMAC_DMA_EN = 0x01;
- while(EU->TMAC_DMA_EN & 0x01);
-
- #ifdef DEBUG_NIC
-
- status = EU->TMAC_DMA_STAT;
- if (status & ~(0x40))
- printf("p2001_eth_transmit: dma status=0x%hx\n", status);
-
- printf("TMAC_MIB6..7: %d:%d\n", EU->TMAC_MIB6, EU->TMAC_MIB7);
- #endif
- }
-
-
-
-
-
-
-
- static void
- p2001_eth_irq(struct nic *nic __unused, irq_action_t action __unused)
- {
- switch ( action ) {
- case DISABLE :
- break;
- case ENABLE :
- break;
- case FORCE :
- break;
- }
- }
-
-
-
-
-
-
- static void p2001_eth_init()
- {
- static int i;
-
-
- if (cur_channel == 3)
- P2001_GPIO->PIN_MUX |= (1<<8);
-
- #ifdef RMII
-
- if (link & LPA_100) {
- EU->CONF_RMII = (1<<2) | (1<<1);
- EU->CONF_RMII = (1<<2) | (1<<1) | (1<<0);
- EU->CONF_RMII = (1<<1) | (1<<0);
- } else {
- EU->CONF_RMII = (1<<2);
- EU->CONF_RMII = (1<<2) | (1<<0);
- EU->CONF_RMII = (1<<0);
- }
- #endif
-
-
-
-
-
-
- EU->RMAC_PHYU =
- (MAC_HW_ADDR[0]<< 8) +
- (MAC_HW_ADDR[1]<< 0);
- EU->RMAC_PHYL =
- (MAC_HW_ADDR[2]<<24) +
- (MAC_HW_ADDR[3]<<16) +
- (MAC_HW_ADDR[4]<<8 ) +
- (MAC_HW_ADDR[5]<<0 );
-
-
-
-
-
- txd.buf = (char *)&txb;
- txd.next = &txd;
- EU->TMAC_DMA_DESC = &txd;
-
-
- cur_rx = 0;
- for (i = 0; i < NUM_RX_DESC; i++) {
- rxd[i].stat = (1<<31) | (1<<30) | (1<<29);
- rxd[i].cntl = (1<<23);
- rxd[i].cntl |= cur_channel << 16;
- rxd[i].cntl |= DMA_BUF_SIZE;
- rxd[i].buf = &rxb[i*DMA_BUF_SIZE];
- rxd[i].next = &rxd[i+1];
- }
- rxd[NUM_RX_DESC-1].next = &rxd[0];
- EU->RMAC_DMA_DESC = &rxd[0];
-
-
- if (link & LPA_DUPLEX)
- EU->TMAC_CNTL = (1<<4) |
- (1<<3) |
- (1<<2);
- else
- EU->TMAC_CNTL = (1<<2);
-
-
- EU->RMAC_CNTL = (1<<3) |
- (1<<1);
-
-
- EU->RMAC_DMA_EN = 1;
- }
-
-
-
-
- static void p2001_eth_disable(struct dev *dev __unused)
- {
-
-
-
-
-
- EU->TMAC_DMA_EN = 0;
-
-
- EU->RMAC_DMA_EN = 0;
- }
-
-
-
-
- static int p2001_eth_check_link(unsigned int phy)
- {
- static int status;
- static unsigned int i, physid;
-
-
- physid = (p2001_eth_mdio_read(phy, MII_PHYSID2) << 16) |
- p2001_eth_mdio_read(phy, MII_PHYSID1);
- printf("PHY %d, ID 0x%x ", phy, physid);
- for (i = 0; mii_chip_table[i].physid; i++)
- if (mii_chip_table[i].physid == physid) {
- printf("(%s).\n", mii_chip_table[i].name);
- break;
- }
- if (!mii_chip_table[i].physid)
- printf("(unknown).\n");
-
-
- printf("Starting auto-negotiation... ");
- p2001_eth_mdio_write(phy, MII_BMCR, 0x3300);
-
-
- i = 0;
- do {
- mdelay(500);
- status = p2001_eth_mdio_read(phy, MII_BMSR);
- if (!status || (i++ > 6))
- goto failed;
- } while (!(status & BMSR_ANEGCOMPLETE));
-
-
- if ((status = p2001_eth_mdio_read(phy, MII_BMSR)) & BMSR_LSTATUS) {
- link = p2001_eth_mdio_read(phy, MII_ADVERTISE) &
- p2001_eth_mdio_read(phy, MII_LPA);
- printf(" Valid link, operating at: %sMb-%s\n",
- (link & LPA_100) ? "100" : "10",
- (link & LPA_DUPLEX) ? "FD" : "HD");
- return 1;
- }
-
- failed:
- if (!status)
- printf("Failed\n");
- else
- printf("No valid link\n");
- return 0;
- }
-
-
-
-
-
-
- static void p2001_eth_phyreset()
- {
-
-
- P2001_GPIO->PIN_MUX |= 0x0018;
-
- P2001_GPIO->GPIO2_En |= 0x0400;
-
- P2001_GPIO->GPIO2_Out |= 0x04000000;
- P2001_GPIO->GPIO2_Out &= ~0x0400;
- mdelay(500);
- P2001_GPIO->GPIO2_Out |= 0x0400;
-
- #ifdef RMII
-
-
-
-
-
- P2001_GPIO->PIN_MUX |= (4 << 13);
- #endif
- }
-
-
-
-
-
- static int p2001_eth_probe(struct dev *dev, unsigned short *probe_addrs __unused)
- {
- struct nic *nic = (struct nic *)dev;
-
-
-
- printf("Resetting PHYs...\n");
- p2001_eth_phyreset();
-
-
-
- P2001_MU->MU_DIV = (SYSCLK/4096000)-1;
-
-
-
- printf("Searching for P2001 NICs...\n");
- cur_phy = -1;
- for (cur_channel=0; cur_channel<4; cur_channel++) {
- EU = P2001_EU(cur_channel);
-
-
- while (++cur_phy < 16) {
-
- if (p2001_eth_mdio_read(cur_phy, MII_BMSR) != 0)
- break;
- }
- if (cur_phy == 16) {
- printf("no more MII PHYs found\n");
- break;
- }
-
-
- if (EU->RMAC_TLEN == 1518) {
- printf("Checking EU%d...\n", cur_channel);
-
- if (p2001_eth_check_link(cur_phy)) {
-
- p2001_eth_init(nic);
-
-
- printf("Setting MAC address to %!\n", MAC_HW_ADDR);
- memcpy(nic->node_addr, MAC_HW_ADDR, 6);
-
-
- dev->disable = p2001_eth_disable;
- nic->poll = p2001_eth_poll;
- nic->transmit = p2001_eth_transmit;
- nic->irq = p2001_eth_irq;
-
-
- dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR);
- return 1;
- }
- }
- }
-
- return 0;
- }
-
- ISA_ROM("p2001_eth", "P2001 Ethernet Driver")
- static struct isa_driver p2001_eth_driver __isa_driver = {
- .type = NIC_DRIVER,
- .name = "P2001 Ethernet Driver",
- .probe = p2001_eth_probe,
- .ioaddrs = 0,
- };
|