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 mid@auk.cx 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 struct pci_device_id 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 int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_id *ent) 96{ 97 static int versionprinted; 98 struct net_device *dev; 99 struct net_local *tp; 100 int i, ret, pci_irq_line; 101 unsigned long pci_ioaddr; 102 103 if (versionprinted++ == 0) 104 printk("%s", version); 105 106 if (pci_enable_device(pdev)) 107 return -EIO; 108 109 /* Remove I/O space marker in bit 0. */ 110 pci_irq_line = pdev->irq; 111 pci_ioaddr = pci_resource_start (pdev, 0); 112 113 /* At this point we have found a valid card. */ 114 115 dev = alloc_trdev(sizeof(struct net_local)); 116 if (!dev) 117 return -ENOMEM; 118 119 SET_MODULE_OWNER(dev); 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: ", dev->name); 152 printk("%2.2x", dev->dev_addr[0]); 153 for (i = 1; i < 6; i++) 154 printk(":%2.2x", dev->dev_addr[i]); 155 printk("\n"); 156 157 tp = netdev_priv(dev); 158 tp->setnselout = abyss_setnselout_pins; 159 tp->sifreadb = abyss_sifreadb; 160 tp->sifreadw = abyss_sifreadw; 161 tp->sifwriteb = abyss_sifwriteb; 162 tp->sifwritew = abyss_sifwritew; 163 164 memcpy(tp->ProductID, "Madge PCI 16/4 Mk2", PROD_ID_SIZE + 1); 165 166 dev->open = abyss_open; 167 dev->stop = abyss_close; 168 169 pci_set_drvdata(pdev, dev); 170 SET_NETDEV_DEV(dev, &pdev->dev); 171 172 ret = register_netdev(dev); 173 if (ret) 174 goto err_out_tmsdev; 175 return 0; 176 177err_out_tmsdev: 178 pci_set_drvdata(pdev, NULL); 179 tmsdev_term(dev); 180err_out_irq: 181 free_irq(pdev->irq, dev); 182err_out_region: 183 release_region(pci_ioaddr, ABYSS_IO_EXTENT); 184err_out_trdev: 185 free_netdev(dev); 186 return ret; 187} 188 189static unsigned short abyss_setnselout_pins(struct net_device *dev) 190{ 191 unsigned short val = 0; 192 struct net_local *tp = netdev_priv(dev); 193 194 if(tp->DataRate == SPEED_4) 195 val |= 0x01; /* Set 4Mbps */ 196 else 197 val |= 0x00; /* Set 16Mbps */ 198 199 return val; 200} 201 202/* 203 * The following Madge boards should use this code: 204 * - Smart 16/4 PCI Mk2 (Abyss) 205 * - Smart 16/4 PCI Mk1 (PCI T) 206 * - Smart 16/4 Client Plus PnP (Big Apple) 207 * - Smart 16/4 Cardbus Mk2 208 * 209 * These access an Atmel AT24 SEEPROM using their glue chip registers. 210 * 211 */ 212static void at24_writedatabyte(unsigned long regaddr, unsigned char byte) 213{ 214 int i; 215 216 for (i = 0; i < 8; i++) { 217 at24_setlines(regaddr, 0, (byte >> (7-i))&0x01); 218 at24_setlines(regaddr, 1, (byte >> (7-i))&0x01); 219 at24_setlines(regaddr, 0, (byte >> (7-i))&0x01); 220 } 221} 222 223static int at24_sendfullcmd(unsigned long regaddr, unsigned char cmd, unsigned char addr) 224{ 225 if (at24_sendcmd(regaddr, cmd)) { 226 at24_writedatabyte(regaddr, addr); 227 return at24_waitforack(regaddr); 228 } 229 return 0; 230} 231 232static int at24_sendcmd(unsigned long regaddr, unsigned char cmd) 233{ 234 int i; 235 236 for (i = 0; i < 10; i++) { 237 at24_start(regaddr); 238 at24_writedatabyte(regaddr, cmd); 239 if (at24_waitforack(regaddr)) 240 return 1; 241 } 242 return 0; 243} 244 245static unsigned char at24_readdatabit(unsigned long regaddr) 246{ 247 unsigned char val; 248 249 at24_setlines(regaddr, 0, 1); 250 at24_setlines(regaddr, 1, 1); 251 val = (inb(regaddr) & AT24_DATA)?1:0; 252 at24_setlines(regaddr, 1, 1); 253 at24_setlines(regaddr, 0, 1); 254 return val; 255} 256 257static unsigned char at24_readdatabyte(unsigned long regaddr) 258{ 259 unsigned char data = 0; 260 int i; 261 262 for (i = 0; i < 8; i++) { 263 data <<= 1; 264 data |= at24_readdatabit(regaddr); 265 } 266 267 return data; 268} 269 270static int at24_waitforack(unsigned long regaddr) 271{ 272 int i; 273 274 for (i = 0; i < 10; i++) { 275 if ((at24_readdatabit(regaddr) & 0x01) == 0x00) 276 return 1; 277 } 278 return 0; 279} 280 281static int at24_waitfornack(unsigned long regaddr) 282{ 283 int i; 284 for (i = 0; i < 10; i++) { 285 if ((at24_readdatabit(regaddr) & 0x01) == 0x01) 286 return 1; 287 } 288 return 0; 289} 290 291static void at24_setlines(unsigned long regaddr, unsigned char clock, unsigned char data) 292{ 293 unsigned char val = AT24_ENABLE; 294 if (clock) 295 val |= AT24_CLOCK; 296 if (data) 297 val |= AT24_DATA; 298 299 outb(val, regaddr); 300 tms380tr_wait(20); /* Very necessary. */ 301} 302 303static void at24_start(unsigned long regaddr) 304{ 305 at24_setlines(regaddr, 0, 1); 306 at24_setlines(regaddr, 1, 1); 307 at24_setlines(regaddr, 1, 0); 308 at24_setlines(regaddr, 0, 1); 309} 310 311static unsigned char at24_readb(unsigned long regaddr, unsigned char addr) 312{ 313 unsigned char data = 0xff; 314 315 if (at24_sendfullcmd(regaddr, AT24_WRITE, addr)) { 316 if (at24_sendcmd(regaddr, AT24_READ)) { 317 data = at24_readdatabyte(regaddr); 318 if (!at24_waitfornack(regaddr)) 319 data = 0xff; 320 } 321 } 322 return data; 323} 324 325 326/* 327 * Enable basic functions of the Madge chipset needed 328 * for initialization. 329 */ 330static void abyss_enable(struct net_device *dev) 331{ 332 unsigned char reset_reg; 333 unsigned long ioaddr; 334 335 ioaddr = dev->base_addr; 336 reset_reg = inb(ioaddr + PCIBM2_RESET_REG); 337 reset_reg |= PCIBM2_RESET_REG_CHIP_NRES; 338 outb(reset_reg, ioaddr + PCIBM2_RESET_REG); 339 tms380tr_wait(100); 340} 341 342/* 343 * Enable the functions of the Madge chipset needed for 344 * full working order. 345 */ 346static int abyss_chipset_init(struct net_device *dev) 347{ 348 unsigned char reset_reg; 349 unsigned long ioaddr; 350 351 ioaddr = dev->base_addr; 352 353 reset_reg = inb(ioaddr + PCIBM2_RESET_REG); 354 355 reset_reg |= PCIBM2_RESET_REG_CHIP_NRES; 356 outb(reset_reg, ioaddr + PCIBM2_RESET_REG); 357 358 reset_reg &= ~(PCIBM2_RESET_REG_CHIP_NRES | 359 PCIBM2_RESET_REG_FIFO_NRES | 360 PCIBM2_RESET_REG_SIF_NRES); 361 outb(reset_reg, ioaddr + PCIBM2_RESET_REG); 362 363 tms380tr_wait(100); 364 365 reset_reg |= PCIBM2_RESET_REG_CHIP_NRES; 366 outb(reset_reg, ioaddr + PCIBM2_RESET_REG); 367 368 reset_reg |= PCIBM2_RESET_REG_SIF_NRES; 369 outb(reset_reg, ioaddr + PCIBM2_RESET_REG); 370 371 reset_reg |= PCIBM2_RESET_REG_FIFO_NRES; 372 outb(reset_reg, ioaddr + PCIBM2_RESET_REG); 373 374 outb(PCIBM2_INT_CONTROL_REG_SINTEN | 375 PCIBM2_INT_CONTROL_REG_PCI_ERR_ENABLE, 376 ioaddr + PCIBM2_INT_CONTROL_REG); 377 378 outb(30, ioaddr + PCIBM2_FIFO_THRESHOLD); 379 380 return 0; 381} 382 383static inline void abyss_chipset_close(struct net_device *dev) 384{ 385 unsigned long ioaddr; 386 387 ioaddr = dev->base_addr; 388 outb(0, ioaddr + PCIBM2_RESET_REG); 389} 390 391/* 392 * Read configuration data from the AT24 SEEPROM on Madge cards. 393 * 394 */ 395static void abyss_read_eeprom(struct net_device *dev) 396{ 397 struct net_local *tp; 398 unsigned long ioaddr; 399 unsigned short val; 400 int i; 401 402 tp = netdev_priv(dev); 403 ioaddr = dev->base_addr; 404 405 /* Must enable glue chip first */ 406 abyss_enable(dev); 407 408 val = at24_readb(ioaddr + PCIBM2_SEEPROM_REG, 409 PCIBM2_SEEPROM_RING_SPEED); 410 tp->DataRate = val?SPEED_4:SPEED_16; /* set open speed */ 411 printk("%s: SEEPROM: ring speed: %dMb/sec\n", dev->name, tp->DataRate); 412 413 val = at24_readb(ioaddr + PCIBM2_SEEPROM_REG, 414 PCIBM2_SEEPROM_RAM_SIZE) * 128; 415 printk("%s: SEEPROM: adapter RAM: %dkb\n", dev->name, val); 416 417 dev->addr_len = 6; 418 for (i = 0; i < 6; i++) 419 dev->dev_addr[i] = at24_readb(ioaddr + PCIBM2_SEEPROM_REG, 420 PCIBM2_SEEPROM_BIA+i); 421} 422 423static int abyss_open(struct net_device *dev) 424{ 425 abyss_chipset_init(dev); 426 tms380tr_open(dev); 427 return 0; 428} 429 430static int abyss_close(struct net_device *dev) 431{ 432 tms380tr_close(dev); 433 abyss_chipset_close(dev); 434 return 0; 435} 436 437static void __devexit abyss_detach (struct pci_dev *pdev) 438{ 439 struct net_device *dev = pci_get_drvdata(pdev); 440 441 BUG_ON(!dev); 442 unregister_netdev(dev); 443 release_region(dev->base_addr-0x10, ABYSS_IO_EXTENT); 444 free_irq(dev->irq, dev); 445 tmsdev_term(dev); 446 free_netdev(dev); 447 pci_set_drvdata(pdev, NULL); 448} 449 450static struct pci_driver abyss_driver = { 451 .name = "abyss", 452 .id_table = abyss_pci_tbl, 453 .probe = abyss_attach, 454 .remove = __devexit_p(abyss_detach), 455}; 456 457static int __init abyss_init (void) 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