11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 23396c7823efb3a5b8630388c464e1034ea031cedPaul Gortmaker drivers/net/ethernet/dec/tulip/pnic2.c 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Copyright 2000,2001 The Linux Kernel Team 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Written/copyright 1994-2001 by Donald Becker. 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Modified to hep support PNIC_II by Kevin B. Hendricks 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds This software may be used and distributed according to the terms 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds of the GNU General Public License, incorporated herein by reference. 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1178a655181409d9d0f2b730ccb897c18794826495Grant Grundler Please submit bugs to http://bugzilla.kernel.org/ . 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Understanding the PNIC_II - everything is this file is based 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * on the PNIC_II_PDF datasheet which is sorely lacking in detail 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * As I understand things, here are the registers and bits that 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * explain the masks and constants used in this file that are 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * either different from the 21142/3 or important for basic operation. 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * CSR 6 (mask = 0xfe3bd1fd of bits not to change) 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ----- 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 24 - SCR 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 23 - PCS 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 22 - TTM (Trasmit Threshold Mode) 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 18 - Port Select 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 13 - Start - 1, Stop - 0 Transmissions 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 11:10 - Loop Back Operation Mode 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 9 - Full Duplex mode (Advertise 10BaseT-FD is CSR14<7> is set) 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 1 - Start - 1, Stop - 0 Receive 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * CSR 14 (mask = 0xfff0ee39 of bits not to change) 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ------ 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 19 - PAUSE-Pause 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 18 - Advertise T4 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 17 - Advertise 100baseTx-FD 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 16 - Advertise 100baseTx-HD 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 12 - LTE - Link Test Enable 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 7 - ANE - Auto Negotiate Enable 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 6 - HDE - Advertise 10baseT-HD 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 2 - Reset to Power down - kept as 1 for normal operation 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 1 - Loop Back enable for 10baseT MCC 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * CSR 12 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ------ 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 25 - Partner can do T4 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 24 - Partner can do 100baseTx-FD 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 23 - Partner can do 100baseTx-HD 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 22 - Partner can do 10baseT-FD 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 21 - Partner can do 10baseT-HD 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 15 - LPN is 1 if all above bits are valid other wise 0 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 14:12 - autonegotiation state (write 001 to start autonegotiate) 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 3 - Autopolarity state 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 2 - LS10B - link state of 10baseT 0 - good, 1 - failed 59426d31071ac476ea62c62656b242930c17b58c00Paul Bolle * Bit 1 - LS100B - link state of 100baseT 0 - good, 1 - failed 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Data Port Selection Info 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *------------------------- 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * CSR14<7> CSR6<18> CSR6<22> CSR6<23> CSR6<24> MODE/PORT 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1 0 0 (X) 0 (X) 1 NWAY 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 0 1 0 (X) 0 10baseT 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 1 0 1 1 (X) 100baseT 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "tulip.h" 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid pnic2_timer(unsigned long data) 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct net_device *dev = (struct net_device *)data; 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct tulip_private *tp = netdev_priv(dev); 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ioaddr = tp->base_addr; 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int next_tick = 60*HZ; 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tulip_debug > 3) 8722086a1172b69b9f6200e169dc99a252a204affbJoe Perches dev_info(&dev->dev, "PNIC2 negotiation status %08x\n", 8822086a1172b69b9f6200e169dc99a252a204affbJoe Perches ioread32(ioaddr + CSR12)); 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (next_tick) { 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mod_timer(&tp->timer, RUN_AT(next_tick)); 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid pnic2_start_nway(struct net_device *dev) 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct tulip_private *tp = netdev_priv(dev); 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ioaddr = tp->base_addr; 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int csr14; 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int csr12; 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* set up what to advertise during the negotiation */ 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* load in csr14 and mask off bits not to touch 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * comment at top of file explains mask value 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds csr14 = (ioread32(ioaddr + CSR14) & 0xfff0ee39); 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* bit 17 - advetise 100baseTx-FD */ 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tp->sym_advertise & 0x0100) csr14 |= 0x00020000; 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* bit 16 - advertise 100baseTx-HD */ 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tp->sym_advertise & 0x0080) csr14 |= 0x00010000; 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* bit 6 - advertise 10baseT-HD */ 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tp->sym_advertise & 0x0020) csr14 |= 0x00000040; 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Now set bit 12 Link Test Enable, Bit 7 Autonegotiation Enable 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and bit 0 Don't PowerDown 10baseT 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds csr14 |= 0x00001184; 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tulip_debug > 1) 125726b65ad444dd142e34d0087fcbba03d16b34ca6Joe Perches netdev_dbg(dev, "Restarting PNIC2 autonegotiation, csr14=%08x\n", 126726b65ad444dd142e34d0087fcbba03d16b34ca6Joe Perches csr14); 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* tell pnic2_lnk_change we are doing an nway negotiation */ 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->if_port = 0; 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->nway = tp->mediasense = 1; 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->nwayset = tp->lpar = 0; 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* now we have to set up csr6 for NWAY state */ 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->csr6 = ioread32(ioaddr + CSR6); 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tulip_debug > 1) 137726b65ad444dd142e34d0087fcbba03d16b34ca6Joe Perches netdev_dbg(dev, "On Entry to Nway, csr6=%08x\n", tp->csr6); 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* mask off any bits not to touch 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * comment at top of file explains mask value 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->csr6 = tp->csr6 & 0xfe3bd1fd; 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* don't forget that bit 9 is also used for advertising */ 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* advertise 10baseT-FD for the negotiation (bit 9) */ 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tp->sym_advertise & 0x0040) tp->csr6 |= 0x00000200; 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* set bit 24 for nway negotiation mode ... 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * see Data Port Selection comment at top of file 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and "Stop" - reset both Transmit (bit 13) and Receive (bit 1) 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->csr6 |= 0x01000000; 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iowrite32(csr14, ioaddr + CSR14); 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iowrite32(tp->csr6, ioaddr + CSR6); 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(100); 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* all set up so now force the negotiation to begin */ 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* read in current values and mask off all but the 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Autonegotiation bits 14:12. Writing a 001 to those bits 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * should start the autonegotiation 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds csr12 = (ioread32(ioaddr + CSR12) & 0xffff8fff); 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds csr12 |= 0x1000; 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iowrite32(csr12, ioaddr + CSR12); 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid pnic2_lnk_change(struct net_device *dev, int csr5) 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct tulip_private *tp = netdev_priv(dev); 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ioaddr = tp->base_addr; 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int csr14; 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* read the staus register to find out what is up */ 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int csr12 = ioread32(ioaddr + CSR12); 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tulip_debug > 1) 18022086a1172b69b9f6200e169dc99a252a204affbJoe Perches dev_info(&dev->dev, 18122086a1172b69b9f6200e169dc99a252a204affbJoe Perches "PNIC2 link status interrupt %08x, CSR5 %x, %08x\n", 18222086a1172b69b9f6200e169dc99a252a204affbJoe Perches csr12, csr5, ioread32(ioaddr + CSR14)); 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* If NWay finished and we have a negotiated partner capability. 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * check bits 14:12 for bit pattern 101 - all is good 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tp->nway && !tp->nwayset) { 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* we did an auto negotiation */ 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((csr12 & 0x7000) == 0x5000) { 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* negotiation ended successfully */ 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* get the link partners reply and mask out all but 1967f927fcc2fd1575d01efb4b76665975007945690Alexey Dobriyan * bits 24-21 which show the partners capabilities 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and match those to what we advertised 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * then begin to interpret the results of the negotiation. 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Always go in this order : (we are ignoring T4 for now) 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 100baseTx-FD, 100baseTx-HD, 10baseT-FD, 10baseT-HD 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int negotiated = ((csr12 >> 16) & 0x01E0) & tp->sym_advertise; 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->lpar = (csr12 >> 16); 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->nwayset = 1; 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (negotiated & 0x0100) dev->if_port = 5; 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (negotiated & 0x0080) dev->if_port = 3; 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (negotiated & 0x0040) dev->if_port = 4; 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (negotiated & 0x0020) dev->if_port = 0; 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tulip_debug > 1) 21422086a1172b69b9f6200e169dc99a252a204affbJoe Perches dev_info(&dev->dev, 21522086a1172b69b9f6200e169dc99a252a204affbJoe Perches "funny autonegotiate result csr12 %08x advertising %04x\n", 21622086a1172b69b9f6200e169dc99a252a204affbJoe Perches csr12, tp->sym_advertise); 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->nwayset = 0; 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* so check if 100baseTx link state is okay */ 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((csr12 & 2) == 0 && (tp->sym_advertise & 0x0180)) 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->if_port = 3; 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* now record the duplex that was negotiated */ 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->full_duplex = 0; 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((dev->if_port == 4) || (dev->if_port == 5)) 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->full_duplex = 1; 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tulip_debug > 1) { 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tp->nwayset) 23022086a1172b69b9f6200e169dc99a252a204affbJoe Perches dev_info(&dev->dev, 23122086a1172b69b9f6200e169dc99a252a204affbJoe Perches "Switching to %s based on link negotiation %04x & %04x = %04x\n", 23222086a1172b69b9f6200e169dc99a252a204affbJoe Perches medianame[dev->if_port], 23322086a1172b69b9f6200e169dc99a252a204affbJoe Perches tp->sym_advertise, tp->lpar, 23422086a1172b69b9f6200e169dc99a252a204affbJoe Perches negotiated); 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* remember to turn off bit 7 - autonegotiate 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * enable so we can properly end nway mode and 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * set duplex (ie. use csr6<9> again) 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds csr14 = (ioread32(ioaddr + CSR14) & 0xffffff7f); 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iowrite32(csr14,ioaddr + CSR14); 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* now set the data port and operating mode 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (see the Data Port Selection comments at 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the top of the file 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* get current csr6 and mask off bits not to touch */ 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* see comment at top of file */ 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->csr6 = (ioread32(ioaddr + CSR6) & 0xfe3bd1fd); 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* so if using if_port 3 or 5 then select the 100baseT 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * port else select the 10baseT port. 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * See the Data Port Selection table at the top 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of the file which was taken from the PNIC_II.PDF 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * datasheet 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev->if_port & 1) tp->csr6 |= 0x01840000; 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else tp->csr6 |= 0x00400000; 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* now set the full duplex bit appropriately */ 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tp->full_duplex) tp->csr6 |= 0x00000200; 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iowrite32(1, ioaddr + CSR13); 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tulip_debug > 2) 270726b65ad444dd142e34d0087fcbba03d16b34ca6Joe Perches netdev_dbg(dev, "Setting CSR6 %08x/%x CSR12 %08x\n", 271726b65ad444dd142e34d0087fcbba03d16b34ca6Joe Perches tp->csr6, 272726b65ad444dd142e34d0087fcbba03d16b34ca6Joe Perches ioread32(ioaddr + CSR6), 273726b65ad444dd142e34d0087fcbba03d16b34ca6Joe Perches ioread32(ioaddr + CSR12)); 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* now the following actually writes out the 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * new csr6 values 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tulip_start_rxtx(tp); 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 28322086a1172b69b9f6200e169dc99a252a204affbJoe Perches dev_info(&dev->dev, 28422086a1172b69b9f6200e169dc99a252a204affbJoe Perches "Autonegotiation failed, using %s, link beat status %04x\n", 28522086a1172b69b9f6200e169dc99a252a204affbJoe Perches medianame[dev->if_port], csr12); 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* remember to turn off bit 7 - autonegotiate 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * enable so we don't forget 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds csr14 = (ioread32(ioaddr + CSR14) & 0xffffff7f); 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iowrite32(csr14,ioaddr + CSR14); 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* what should we do when autonegotiate fails? 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * should we try again or default to baseline 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * case. I just don't know. 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for now default to some baseline case 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->if_port = 0; 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->nway = 0; 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->nwayset = 1; 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* set to 10baseTx-HD - see Data Port Selection 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * comment given at the top of the file 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->csr6 = (ioread32(ioaddr + CSR6) & 0xfe3bd1fd); 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->csr6 |= 0x00400000; 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tulip_restart_rxtx(tp); 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3178e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if ((tp->nwayset && (csr5 & 0x08000000) && 3188e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches (dev->if_port == 3 || dev->if_port == 5) && 3198e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches (csr12 & 2) == 2) || (tp->nway && (csr5 & (TPLnkFail)))) { 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Link blew? Maybe restart NWay. */ 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tulip_debug > 2) 324726b65ad444dd142e34d0087fcbba03d16b34ca6Joe Perches netdev_dbg(dev, "Ugh! Link blew?\n"); 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds del_timer_sync(&tp->timer); 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnic2_start_nway(dev); 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->timer.expires = RUN_AT(3*HZ); 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add_timer(&tp->timer); 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev->if_port == 3 || dev->if_port == 5) { 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* we are at 100mb and a potential link change occurred */ 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tulip_debug > 1) 34022086a1172b69b9f6200e169dc99a252a204affbJoe Perches dev_info(&dev->dev, "PNIC2 %s link beat %s\n", 34122086a1172b69b9f6200e169dc99a252a204affbJoe Perches medianame[dev->if_port], 34222086a1172b69b9f6200e169dc99a252a204affbJoe Perches (csr12 & 2) ? "failed" : "good"); 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check 100 link beat */ 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->nway = 0; 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->nwayset = 1; 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* if failed then try doing an nway to get in sync */ 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((csr12 & 2) && ! tp->medialock) { 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds del_timer_sync(&tp->timer); 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnic2_start_nway(dev); 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->timer.expires = RUN_AT(3*HZ); 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add_timer(&tp->timer); 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev->if_port == 0 || dev->if_port == 4) { 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* we are at 10mb and a potential link change occurred */ 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tulip_debug > 1) 36522086a1172b69b9f6200e169dc99a252a204affbJoe Perches dev_info(&dev->dev, "PNIC2 %s link beat %s\n", 36622086a1172b69b9f6200e169dc99a252a204affbJoe Perches medianame[dev->if_port], 36722086a1172b69b9f6200e169dc99a252a204affbJoe Perches (csr12 & 4) ? "failed" : "good"); 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->nway = 0; 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->nwayset = 1; 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* if failed, try doing an nway to get in sync */ 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((csr12 & 4) && ! tp->medialock) { 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds del_timer_sync(&tp->timer); 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnic2_start_nway(dev); 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->timer.expires = RUN_AT(3*HZ); 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add_timer(&tp->timer); 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tulip_debug > 1) 38622086a1172b69b9f6200e169dc99a252a204affbJoe Perches dev_info(&dev->dev, "PNIC2 Link Change Default?\n"); 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* if all else fails default to trying 10baseT-HD */ 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->if_port = 0; 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* make sure autonegotiate enable is off */ 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds csr14 = (ioread32(ioaddr + CSR14) & 0xffffff7f); 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iowrite32(csr14,ioaddr + CSR14); 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* set to 10baseTx-HD - see Data Port Selection 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * comment given at the top of the file 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->csr6 = (ioread32(ioaddr + CSR6) & 0xfe3bd1fd); 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp->csr6 |= 0x00400000; 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tulip_restart_rxtx(tp); 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 404