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