1/* 2 * abyss.c: Network driver for the Madge Smart 16/4 PCI Mk2 token ring card. 3 * 4 * Written 1999-2000 by Adam Fritzler 5 * 6 * This software may be used and distributed according to the terms 7 * of the GNU General Public License, incorporated herein by reference. 8 * 9 * This driver module supports the following cards: 10 * - Madge Smart 16/4 PCI Mk2 11 * 12 * Maintainer(s): 13 * AF Adam Fritzler 14 * 15 * Modification History: 16 * 30-Dec-99 AF Split off from the tms380tr driver. 17 * 22-Jan-00 AF Updated to use indirect read/writes 18 * 23-Nov-00 JG New PCI API, cleanups 19 * 20 * 21 * TODO: 22 * 1. See if we can use MMIO instead of inb/outb/inw/outw 23 * 2. Add support for Mk1 (has AT24 attached to the PCI 24 * config registers) 25 * 26 */ 27 28#include <linux/module.h> 29#include <linux/kernel.h> 30#include <linux/errno.h> 31#include <linux/pci.h> 32#include <linux/init.h> 33#include <linux/netdevice.h> 34#include <linux/trdevice.h> 35 36#include <asm/system.h> 37#include <asm/io.h> 38#include <asm/irq.h> 39 40#include "tms380tr.h" 41#include "abyss.h" /* Madge-specific constants */ 42 43static char version[] __devinitdata = 44"abyss.c: v1.02 23/11/2000 by Adam Fritzler\n"; 45 46#define ABYSS_IO_EXTENT 64 47 48static DEFINE_PCI_DEVICE_TABLE(abyss_pci_tbl) = { 49 { PCI_VENDOR_ID_MADGE, PCI_DEVICE_ID_MADGE_MK2, 50 PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_TOKEN_RING << 8, 0x00ffffff, }, 51 { } /* Terminating entry */ 52}; 53MODULE_DEVICE_TABLE(pci, abyss_pci_tbl); 54 55MODULE_LICENSE("GPL"); 56 57static int abyss_open(struct net_device *dev); 58static int abyss_close(struct net_device *dev); 59static void abyss_enable(struct net_device *dev); 60static int abyss_chipset_init(struct net_device *dev); 61static void abyss_read_eeprom(struct net_device *dev); 62static unsigned short abyss_setnselout_pins(struct net_device *dev); 63 64static void at24_writedatabyte(unsigned long regaddr, unsigned char byte); 65static int at24_sendfullcmd(unsigned long regaddr, unsigned char cmd, unsigned char addr); 66static int at24_sendcmd(unsigned long regaddr, unsigned char cmd); 67static unsigned char at24_readdatabit(unsigned long regaddr); 68static unsigned char at24_readdatabyte(unsigned long regaddr); 69static int at24_waitforack(unsigned long regaddr); 70static int at24_waitfornack(unsigned long regaddr); 71static void at24_setlines(unsigned long regaddr, unsigned char clock, unsigned char data); 72static void at24_start(unsigned long regaddr); 73static unsigned char at24_readb(unsigned long regaddr, unsigned char addr); 74 75static unsigned short abyss_sifreadb(struct net_device *dev, unsigned short reg) 76{ 77 return inb(dev->base_addr + reg); 78} 79 80static unsigned short abyss_sifreadw(struct net_device *dev, unsigned short reg) 81{ 82 return inw(dev->base_addr + reg); 83} 84 85static void abyss_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg) 86{ 87 outb(val, dev->base_addr + reg); 88} 89 90static void abyss_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg) 91{ 92 outw(val, dev->base_addr + reg); 93} 94 95static struct net_device_ops abyss_netdev_ops; 96 97static int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_id *ent) 98{ 99 static int versionprinted; 100 struct net_device *dev; 101 struct net_local *tp; 102 int ret, pci_irq_line; 103 unsigned long pci_ioaddr; 104 105 if (versionprinted++ == 0) 106 printk("%s", version); 107 108 if (pci_enable_device(pdev)) 109 return -EIO; 110 111 /* Remove I/O space marker in bit 0. */ 112 pci_irq_line = pdev->irq; 113 pci_ioaddr = pci_resource_start (pdev, 0); 114 115 /* At this point we have found a valid card. */ 116 117 dev = alloc_trdev(sizeof(struct net_local)); 118 if (!dev) 119 return -ENOMEM; 120 121 if (!request_region(pci_ioaddr, ABYSS_IO_EXTENT, dev->name)) { 122 ret = -EBUSY; 123 goto err_out_trdev; 124 } 125 126 ret = request_irq(pdev->irq, tms380tr_interrupt, IRQF_SHARED, 127 dev->name, dev); 128 if (ret) 129 goto err_out_region; 130 131 dev->base_addr = pci_ioaddr; 132 dev->irq = pci_irq_line; 133 134 printk("%s: Madge Smart 16/4 PCI Mk2 (Abyss)\n", dev->name); 135 printk("%s: IO: %#4lx IRQ: %d\n", 136 dev->name, pci_ioaddr, dev->irq); 137 /* 138 * The TMS SIF registers lay 0x10 above the card base address. 139 */ 140 dev->base_addr += 0x10; 141 142 ret = tmsdev_init(dev, &pdev->dev); 143 if (ret) { 144 printk("%s: unable to get memory for dev->priv.\n", 145 dev->name); 146 goto err_out_irq; 147 } 148 149 abyss_read_eeprom(dev); 150 151 printk("%s: Ring Station Address: %pM\n", dev->name, dev->dev_addr); 152 153 tp = netdev_priv(dev); 154 tp->setnselout = abyss_setnselout_pins; 155 tp->sifreadb = abyss_sifreadb; 156 tp->sifreadw = abyss_sifreadw; 157 tp->sifwriteb = abyss_sifwriteb; 158 tp->sifwritew = abyss_sifwritew; 159 160 memcpy(tp->ProductID, "Madge PCI 16/4 Mk2", PROD_ID_SIZE + 1); 161 162 dev->netdev_ops = &abyss_netdev_ops; 163 164 pci_set_drvdata(pdev, dev); 165 SET_NETDEV_DEV(dev, &pdev->dev); 166 167 ret = register_netdev(dev); 168 if (ret) 169 goto err_out_tmsdev; 170 return 0; 171 172err_out_tmsdev: 173 pci_set_drvdata(pdev, NULL); 174 tmsdev_term(dev); 175err_out_irq: 176 free_irq(pdev->irq, dev); 177err_out_region: 178 release_region(pci_ioaddr, ABYSS_IO_EXTENT); 179err_out_trdev: 180 free_netdev(dev); 181 return ret; 182} 183 184static unsigned short abyss_setnselout_pins(struct net_device *dev) 185{ 186 unsigned short val = 0; 187 struct net_local *tp = netdev_priv(dev); 188 189 if(tp->DataRate == SPEED_4) 190 val |= 0x01; /* Set 4Mbps */ 191 else 192 val |= 0x00; /* Set 16Mbps */ 193 194 return val; 195} 196 197/* 198 * The following Madge boards should use this code: 199 * - Smart 16/4 PCI Mk2 (Abyss) 200 * - Smart 16/4 PCI Mk1 (PCI T) 201 * - Smart 16/4 Client Plus PnP (Big Apple) 202 * - Smart 16/4 Cardbus Mk2 203 * 204 * These access an Atmel AT24 SEEPROM using their glue chip registers. 205 * 206 */ 207static void at24_writedatabyte(unsigned long regaddr, unsigned char byte) 208{ 209 int i; 210 211 for (i = 0; i < 8; i++) { 212 at24_setlines(regaddr, 0, (byte >> (7-i))&0x01); 213 at24_setlines(regaddr, 1, (byte >> (7-i))&0x01); 214 at24_setlines(regaddr, 0, (byte >> (7-i))&0x01); 215 } 216} 217 218static int at24_sendfullcmd(unsigned long regaddr, unsigned char cmd, unsigned char addr) 219{ 220 if (at24_sendcmd(regaddr, cmd)) { 221 at24_writedatabyte(regaddr, addr); 222 return at24_waitforack(regaddr); 223 } 224 return 0; 225} 226 227static int at24_sendcmd(unsigned long regaddr, unsigned char cmd) 228{ 229 int i; 230 231 for (i = 0; i < 10; i++) { 232 at24_start(regaddr); 233 at24_writedatabyte(regaddr, cmd); 234 if (at24_waitforack(regaddr)) 235 return 1; 236 } 237 return 0; 238} 239 240static unsigned char at24_readdatabit(unsigned long regaddr) 241{ 242 unsigned char val; 243 244 at24_setlines(regaddr, 0, 1); 245 at24_setlines(regaddr, 1, 1); 246 val = (inb(regaddr) & AT24_DATA)?1:0; 247 at24_setlines(regaddr, 1, 1); 248 at24_setlines(regaddr, 0, 1); 249 return val; 250} 251 252static unsigned char at24_readdatabyte(unsigned long regaddr) 253{ 254 unsigned char data = 0; 255 int i; 256 257 for (i = 0; i < 8; i++) { 258 data <<= 1; 259 data |= at24_readdatabit(regaddr); 260 } 261 262 return data; 263} 264 265static int at24_waitforack(unsigned long regaddr) 266{ 267 int i; 268 269 for (i = 0; i < 10; i++) { 270 if ((at24_readdatabit(regaddr) & 0x01) == 0x00) 271 return 1; 272 } 273 return 0; 274} 275 276static int at24_waitfornack(unsigned long regaddr) 277{ 278 int i; 279 for (i = 0; i < 10; i++) { 280 if ((at24_readdatabit(regaddr) & 0x01) == 0x01) 281 return 1; 282 } 283 return 0; 284} 285 286static void at24_setlines(unsigned long regaddr, unsigned char clock, unsigned char data) 287{ 288 unsigned char val = AT24_ENABLE; 289 if (clock) 290 val |= AT24_CLOCK; 291 if (data) 292 val |= AT24_DATA; 293 294 outb(val, regaddr); 295 tms380tr_wait(20); /* Very necessary. */ 296} 297 298static void at24_start(unsigned long regaddr) 299{ 300 at24_setlines(regaddr, 0, 1); 301 at24_setlines(regaddr, 1, 1); 302 at24_setlines(regaddr, 1, 0); 303 at24_setlines(regaddr, 0, 1); 304} 305 306static unsigned char at24_readb(unsigned long regaddr, unsigned char addr) 307{ 308 unsigned char data = 0xff; 309 310 if (at24_sendfullcmd(regaddr, AT24_WRITE, addr)) { 311 if (at24_sendcmd(regaddr, AT24_READ)) { 312 data = at24_readdatabyte(regaddr); 313 if (!at24_waitfornack(regaddr)) 314 data = 0xff; 315 } 316 } 317 return data; 318} 319 320 321/* 322 * Enable basic functions of the Madge chipset needed 323 * for initialization. 324 */ 325static void abyss_enable(struct net_device *dev) 326{ 327 unsigned char reset_reg; 328 unsigned long ioaddr; 329 330 ioaddr = dev->base_addr; 331 reset_reg = inb(ioaddr + PCIBM2_RESET_REG); 332 reset_reg |= PCIBM2_RESET_REG_CHIP_NRES; 333 outb(reset_reg, ioaddr + PCIBM2_RESET_REG); 334 tms380tr_wait(100); 335} 336 337/* 338 * Enable the functions of the Madge chipset needed for 339 * full working order. 340 */ 341static int abyss_chipset_init(struct net_device *dev) 342{ 343 unsigned char reset_reg; 344 unsigned long ioaddr; 345 346 ioaddr = dev->base_addr; 347 348 reset_reg = inb(ioaddr + PCIBM2_RESET_REG); 349 350 reset_reg |= PCIBM2_RESET_REG_CHIP_NRES; 351 outb(reset_reg, ioaddr + PCIBM2_RESET_REG); 352 353 reset_reg &= ~(PCIBM2_RESET_REG_CHIP_NRES | 354 PCIBM2_RESET_REG_FIFO_NRES | 355 PCIBM2_RESET_REG_SIF_NRES); 356 outb(reset_reg, ioaddr + PCIBM2_RESET_REG); 357 358 tms380tr_wait(100); 359 360 reset_reg |= PCIBM2_RESET_REG_CHIP_NRES; 361 outb(reset_reg, ioaddr + PCIBM2_RESET_REG); 362 363 reset_reg |= PCIBM2_RESET_REG_SIF_NRES; 364 outb(reset_reg, ioaddr + PCIBM2_RESET_REG); 365 366 reset_reg |= PCIBM2_RESET_REG_FIFO_NRES; 367 outb(reset_reg, ioaddr + PCIBM2_RESET_REG); 368 369 outb(PCIBM2_INT_CONTROL_REG_SINTEN | 370 PCIBM2_INT_CONTROL_REG_PCI_ERR_ENABLE, 371 ioaddr + PCIBM2_INT_CONTROL_REG); 372 373 outb(30, ioaddr + PCIBM2_FIFO_THRESHOLD); 374 375 return 0; 376} 377 378static inline void abyss_chipset_close(struct net_device *dev) 379{ 380 unsigned long ioaddr; 381 382 ioaddr = dev->base_addr; 383 outb(0, ioaddr + PCIBM2_RESET_REG); 384} 385 386/* 387 * Read configuration data from the AT24 SEEPROM on Madge cards. 388 * 389 */ 390static void abyss_read_eeprom(struct net_device *dev) 391{ 392 struct net_local *tp; 393 unsigned long ioaddr; 394 unsigned short val; 395 int i; 396 397 tp = netdev_priv(dev); 398 ioaddr = dev->base_addr; 399 400 /* Must enable glue chip first */ 401 abyss_enable(dev); 402 403 val = at24_readb(ioaddr + PCIBM2_SEEPROM_REG, 404 PCIBM2_SEEPROM_RING_SPEED); 405 tp->DataRate = val?SPEED_4:SPEED_16; /* set open speed */ 406 printk("%s: SEEPROM: ring speed: %dMb/sec\n", dev->name, tp->DataRate); 407 408 val = at24_readb(ioaddr + PCIBM2_SEEPROM_REG, 409 PCIBM2_SEEPROM_RAM_SIZE) * 128; 410 printk("%s: SEEPROM: adapter RAM: %dkb\n", dev->name, val); 411 412 dev->addr_len = 6; 413 for (i = 0; i < 6; i++) 414 dev->dev_addr[i] = at24_readb(ioaddr + PCIBM2_SEEPROM_REG, 415 PCIBM2_SEEPROM_BIA+i); 416} 417 418static int abyss_open(struct net_device *dev) 419{ 420 abyss_chipset_init(dev); 421 tms380tr_open(dev); 422 return 0; 423} 424 425static int abyss_close(struct net_device *dev) 426{ 427 tms380tr_close(dev); 428 abyss_chipset_close(dev); 429 return 0; 430} 431 432static void __devexit abyss_detach (struct pci_dev *pdev) 433{ 434 struct net_device *dev = pci_get_drvdata(pdev); 435 436 BUG_ON(!dev); 437 unregister_netdev(dev); 438 release_region(dev->base_addr-0x10, ABYSS_IO_EXTENT); 439 free_irq(dev->irq, dev); 440 tmsdev_term(dev); 441 free_netdev(dev); 442 pci_set_drvdata(pdev, NULL); 443} 444 445static struct pci_driver abyss_driver = { 446 .name = "abyss", 447 .id_table = abyss_pci_tbl, 448 .probe = abyss_attach, 449 .remove = __devexit_p(abyss_detach), 450}; 451 452static int __init abyss_init (void) 453{ 454 abyss_netdev_ops = tms380tr_netdev_ops; 455 456 abyss_netdev_ops.ndo_open = abyss_open; 457 abyss_netdev_ops.ndo_stop = abyss_close; 458 459 return pci_register_driver(&abyss_driver); 460} 461 462static void __exit abyss_rmmod (void) 463{ 464 pci_unregister_driver (&abyss_driver); 465} 466 467module_init(abyss_init); 468module_exit(abyss_rmmod); 469 470