at v2.6.17-rc2 372 lines 9.0 kB view raw
1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 */ 6 7#define DEBUG 8 9#include <linux/init.h> 10#include <linux/kernel.h> 11#include <linux/module.h> 12#include <linux/netdevice.h> 13#include <linux/sched.h> 14#include <linux/etherdevice.h> 15#include <linux/netdevice.h> 16#include <linux/platform_device.h> 17#include <asm/io.h> 18#include <asm/mips-boards/simint.h> 19 20#include "mipsnet.h" /* actual device IO mapping */ 21 22#define MIPSNET_VERSION "2005-06-20" 23 24#define mipsnet_reg_address(dev, field) (dev->base_addr + field_offset(field)) 25 26struct mipsnet_priv { 27 struct net_device_stats stats; 28}; 29 30static struct platform_device *mips_plat_dev; 31 32static char mipsnet_string[] = "mipsnet"; 33 34/* 35 * Copy data from the MIPSNET rx data port 36 */ 37static int ioiocpy_frommipsnet(struct net_device *dev, unsigned char *kdata, 38 int len) 39{ 40 uint32_t available_len = inl(mipsnet_reg_address(dev, rxDataCount)); 41 if (available_len < len) 42 return -EFAULT; 43 44 for (; len > 0; len--, kdata++) { 45 *kdata = inb(mipsnet_reg_address(dev, rxDataBuffer)); 46 } 47 48 return inl(mipsnet_reg_address(dev, rxDataCount)); 49} 50 51static inline ssize_t mipsnet_put_todevice(struct net_device *dev, 52 struct sk_buff *skb) 53{ 54 int count_to_go = skb->len; 55 char *buf_ptr = skb->data; 56 struct mipsnet_priv *mp = netdev_priv(dev); 57 58 pr_debug("%s: %s(): telling MIPSNET txDataCount(%d)\n", 59 dev->name, __FUNCTION__, skb->len); 60 61 outl(skb->len, mipsnet_reg_address(dev, txDataCount)); 62 63 pr_debug("%s: %s(): sending data to MIPSNET txDataBuffer(%d)\n", 64 dev->name, __FUNCTION__, skb->len); 65 66 for (; count_to_go; buf_ptr++, count_to_go--) { 67 outb(*buf_ptr, mipsnet_reg_address(dev, txDataBuffer)); 68 } 69 70 mp->stats.tx_packets++; 71 mp->stats.tx_bytes += skb->len; 72 73 return skb->len; 74} 75 76static int mipsnet_xmit(struct sk_buff *skb, struct net_device *dev) 77{ 78 pr_debug("%s:%s(): transmitting %d bytes\n", 79 dev->name, __FUNCTION__, skb->len); 80 81 /* Only one packet at a time. Once TXDONE interrupt is serviced, the 82 * queue will be restarted. 83 */ 84 netif_stop_queue(dev); 85 mipsnet_put_todevice(dev, skb); 86 87 return 0; 88} 89 90static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t count) 91{ 92 struct sk_buff *skb; 93 size_t len = count; 94 struct mipsnet_priv *mp = netdev_priv(dev); 95 96 if (!(skb = alloc_skb(len + 2, GFP_KERNEL))) { 97 mp->stats.rx_dropped++; 98 return -ENOMEM; 99 } 100 101 skb_reserve(skb, 2); 102 if (ioiocpy_frommipsnet(dev, skb_put(skb, len), len)) 103 return -EFAULT; 104 105 skb->dev = dev; 106 skb->protocol = eth_type_trans(skb, dev); 107 skb->ip_summed = CHECKSUM_UNNECESSARY; 108 109 pr_debug("%s:%s(): pushing RXed data to kernel\n", 110 dev->name, __FUNCTION__); 111 netif_rx(skb); 112 113 mp->stats.rx_packets++; 114 mp->stats.rx_bytes += len; 115 116 return count; 117} 118 119static irqreturn_t 120mipsnet_interrupt(int irq, void *dev_id, struct pt_regs *regs) 121{ 122 struct net_device *dev = dev_id; 123 124 irqreturn_t retval = IRQ_NONE; 125 uint64_t interruptFlags; 126 127 if (irq == dev->irq) { 128 pr_debug("%s:%s(): irq %d for device\n", 129 dev->name, __FUNCTION__, irq); 130 131 retval = IRQ_HANDLED; 132 133 interruptFlags = 134 inl(mipsnet_reg_address(dev, interruptControl)); 135 pr_debug("%s:%s(): intCtl=0x%016llx\n", dev->name, 136 __FUNCTION__, interruptFlags); 137 138 if (interruptFlags & MIPSNET_INTCTL_TXDONE) { 139 pr_debug("%s:%s(): got TXDone\n", 140 dev->name, __FUNCTION__); 141 outl(MIPSNET_INTCTL_TXDONE, 142 mipsnet_reg_address(dev, interruptControl)); 143 // only one packet at a time, we are done. 144 netif_wake_queue(dev); 145 } else if (interruptFlags & MIPSNET_INTCTL_RXDONE) { 146 pr_debug("%s:%s(): got RX data\n", 147 dev->name, __FUNCTION__); 148 mipsnet_get_fromdev(dev, 149 inl(mipsnet_reg_address(dev, rxDataCount))); 150 pr_debug("%s:%s(): clearing RX int\n", 151 dev->name, __FUNCTION__); 152 outl(MIPSNET_INTCTL_RXDONE, 153 mipsnet_reg_address(dev, interruptControl)); 154 155 } else if (interruptFlags & MIPSNET_INTCTL_TESTBIT) { 156 pr_debug("%s:%s(): got test interrupt\n", 157 dev->name, __FUNCTION__); 158 // TESTBIT is cleared on read. 159 // And takes effect after a write with 0 160 outl(0, mipsnet_reg_address(dev, interruptControl)); 161 } else { 162 pr_debug("%s:%s(): no valid fags 0x%016llx\n", 163 dev->name, __FUNCTION__, interruptFlags); 164 // Maybe shared IRQ, just ignore, no clearing. 165 retval = IRQ_NONE; 166 } 167 168 } else { 169 printk(KERN_INFO "%s: %s(): irq %d for unknown device\n", 170 dev->name, __FUNCTION__, irq); 171 retval = IRQ_NONE; 172 } 173 return retval; 174} //mipsnet_interrupt() 175 176static int mipsnet_open(struct net_device *dev) 177{ 178 int err; 179 pr_debug("%s: mipsnet_open\n", dev->name); 180 181 err = request_irq(dev->irq, &mipsnet_interrupt, 182 SA_SHIRQ, dev->name, (void *) dev); 183 184 if (err) { 185 pr_debug("%s: %s(): can't get irq %d\n", 186 dev->name, __FUNCTION__, dev->irq); 187 release_region(dev->base_addr, MIPSNET_IO_EXTENT); 188 return err; 189 } 190 191 pr_debug("%s: %s(): got IO region at 0x%04lx and irq %d for dev.\n", 192 dev->name, __FUNCTION__, dev->base_addr, dev->irq); 193 194 195 netif_start_queue(dev); 196 197 // test interrupt handler 198 outl(MIPSNET_INTCTL_TESTBIT, 199 mipsnet_reg_address(dev, interruptControl)); 200 201 202 return 0; 203} 204 205static int mipsnet_close(struct net_device *dev) 206{ 207 pr_debug("%s: %s()\n", dev->name, __FUNCTION__); 208 netif_stop_queue(dev); 209 return 0; 210} 211 212static struct net_device_stats *mipsnet_get_stats(struct net_device *dev) 213{ 214 struct mipsnet_priv *mp = netdev_priv(dev); 215 216 return &mp->stats; 217} 218 219static void mipsnet_set_mclist(struct net_device *dev) 220{ 221 // we don't do anything 222 return; 223} 224 225static int __init mipsnet_probe(struct device *dev) 226{ 227 struct net_device *netdev; 228 int err; 229 230 netdev = alloc_etherdev(sizeof(struct mipsnet_priv)); 231 if (!netdev) { 232 err = -ENOMEM; 233 goto out; 234 } 235 236 dev_set_drvdata(dev, netdev); 237 238 netdev->open = mipsnet_open; 239 netdev->stop = mipsnet_close; 240 netdev->hard_start_xmit = mipsnet_xmit; 241 netdev->get_stats = mipsnet_get_stats; 242 netdev->set_multicast_list = mipsnet_set_mclist; 243 244 /* 245 * TODO: probe for these or load them from PARAM 246 */ 247 netdev->base_addr = 0x4200; 248 netdev->irq = MIPSCPU_INT_BASE + MIPSCPU_INT_MB0 + 249 inl(mipsnet_reg_address(netdev, interruptInfo)); 250 251 // Get the io region now, get irq on open() 252 if (!request_region(netdev->base_addr, MIPSNET_IO_EXTENT, "mipsnet")) { 253 pr_debug("%s: %s(): IO region {start: 0x%04lux, len: %d} " 254 "for dev is not availble.\n", netdev->name, 255 __FUNCTION__, netdev->base_addr, MIPSNET_IO_EXTENT); 256 err = -EBUSY; 257 goto out_free_netdev; 258 } 259 260 /* 261 * Lacking any better mechanism to allocate a MAC address we use a 262 * random one ... 263 */ 264 random_ether_addr(netdev->dev_addr); 265 266 err = register_netdev(netdev); 267 if (err) { 268 printk(KERN_ERR "MIPSNet: failed to register netdev.\n"); 269 goto out_free_region; 270 } 271 272 return 0; 273 274out_free_region: 275 release_region(netdev->base_addr, MIPSNET_IO_EXTENT); 276 277out_free_netdev: 278 free_netdev(netdev); 279 280out: 281 return err; 282} 283 284static int __devexit mipsnet_device_remove(struct device *device) 285{ 286 struct net_device *dev = dev_get_drvdata(device); 287 288 unregister_netdev(dev); 289 release_region(dev->base_addr, MIPSNET_IO_EXTENT); 290 free_netdev(dev); 291 dev_set_drvdata(device, NULL); 292 293 return 0; 294} 295 296static struct device_driver mipsnet_driver = { 297 .name = mipsnet_string, 298 .bus = &platform_bus_type, 299 .probe = mipsnet_probe, 300 .remove = __devexit_p(mipsnet_device_remove), 301}; 302 303static void mipsnet_platform_release(struct device *device) 304{ 305 struct platform_device *pldev; 306 307 /* free device */ 308 pldev = to_platform_device(device); 309 kfree(pldev); 310} 311 312static int __init mipsnet_init_module(void) 313{ 314 struct platform_device *pldev; 315 int err; 316 317 printk(KERN_INFO "MIPSNet Ethernet driver. Version: %s. " 318 "(c)2005 MIPS Technologies, Inc.\n", MIPSNET_VERSION); 319 320 if (driver_register(&mipsnet_driver)) { 321 printk(KERN_ERR "Driver registration failed\n"); 322 err = -ENODEV; 323 goto out; 324 } 325 326 if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) { 327 err = -ENOMEM; 328 goto out_unregister_driver; 329 } 330 331 memset (pldev, 0, sizeof (*pldev)); 332 pldev->name = mipsnet_string; 333 pldev->id = 0; 334 pldev->dev.release = mipsnet_platform_release; 335 336 if (platform_device_register(pldev)) { 337 err = -ENODEV; 338 goto out_free_pldev; 339 } 340 341 if (!pldev->dev.driver) { 342 /* 343 * The driver was not bound to this device, there was 344 * no hardware at this address. Unregister it, as the 345 * release fuction will take care of freeing the 346 * allocated structure 347 */ 348 platform_device_unregister (pldev); 349 } 350 351 mips_plat_dev = pldev; 352 353 return 0; 354 355out_free_pldev: 356 kfree(pldev); 357 358out_unregister_driver: 359 driver_unregister(&mipsnet_driver); 360out: 361 return err; 362} 363 364static void __exit mipsnet_exit_module(void) 365{ 366 pr_debug("MIPSNet Ethernet driver exiting\n"); 367 368 driver_unregister(&mipsnet_driver); 369} 370 371module_init(mipsnet_init_module); 372module_exit(mipsnet_exit_module);