X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fnet%2Fcassini.c;h=39f36aa05aa8b005bf4b2b2638ef7f1a47810f6e;hb=0612ec48762bf8712db1925b2e67246d2237ebab;hp=dde631f8f685fe6453b6738da508c0a162de3411;hpb=7eb9b2f56c9812d03ac63031869bcc42151067b1;p=linux-2.6-omap-h63xx.git diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index dde631f8f68..a31544ccb3c 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -66,7 +66,6 @@ * by default, the selective clear mask is set up to process rx packets. */ -#include #include #include @@ -91,6 +90,7 @@ #include #include #include +#include #include @@ -191,12 +191,15 @@ static char version[] __devinitdata = DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; +static int cassini_debug = -1; /* -1 == use CAS_DEF_MSG_ENABLE as value */ +static int link_mode; + MODULE_AUTHOR("Adrian Sun (asun@darksunrising.com)"); MODULE_DESCRIPTION("Sun Cassini(+) ethernet driver"); MODULE_LICENSE("GPL"); -MODULE_PARM(cassini_debug, "i"); +module_param(cassini_debug, int, 0); MODULE_PARM_DESC(cassini_debug, "Cassini bitmapped debugging message enable value"); -MODULE_PARM(link_mode, "i"); +module_param(link_mode, int, 0); MODULE_PARM_DESC(link_mode, "default link mode"); /* @@ -208,7 +211,7 @@ MODULE_PARM_DESC(link_mode, "default link mode"); * Value in seconds, for user input. */ static int linkdown_timeout = DEFAULT_LINKDOWN_TIMEOUT; -MODULE_PARM(linkdown_timeout, "i"); +module_param(linkdown_timeout, int, 0); MODULE_PARM_DESC(linkdown_timeout, "min reset interval in sec. for PCS linkdown issue; disabled if not positive"); @@ -220,8 +223,6 @@ MODULE_PARM_DESC(linkdown_timeout, static int link_transition_timeout; -static int cassini_debug = -1; /* -1 == use CAS_DEF_MSG_ENABLE as value */ -static int link_mode; static u16 link_modes[] __devinitdata = { BMCR_ANENABLE, /* 0 : autoneg */ @@ -335,6 +336,30 @@ static inline void cas_mask_intr(struct cas *cp) cas_disable_irq(cp, i); } +static inline void cas_buffer_init(cas_page_t *cp) +{ + struct page *page = cp->buffer; + atomic_set((atomic_t *)&page->lru.next, 1); +} + +static inline int cas_buffer_count(cas_page_t *cp) +{ + struct page *page = cp->buffer; + return atomic_read((atomic_t *)&page->lru.next); +} + +static inline void cas_buffer_inc(cas_page_t *cp) +{ + struct page *page = cp->buffer; + atomic_inc((atomic_t *)&page->lru.next); +} + +static inline void cas_buffer_dec(cas_page_t *cp) +{ + struct page *page = cp->buffer; + atomic_dec((atomic_t *)&page->lru.next); +} + static void cas_enable_irq(struct cas *cp, const int ring) { if (ring == 0) { /* all but TX_DONE */ @@ -472,6 +497,7 @@ static int cas_page_free(struct cas *cp, cas_page_t *page) { pci_unmap_page(cp->pdev, page->dma_addr, cp->page_size, PCI_DMA_FROMDEVICE); + cas_buffer_dec(page); __free_pages(page->buffer, cp->page_order); kfree(page); return 0; @@ -501,6 +527,7 @@ static cas_page_t *cas_page_alloc(struct cas *cp, const gfp_t flags) page->buffer = alloc_pages(flags, cp->page_order); if (!page->buffer) goto page_err; + cas_buffer_init(page); page->dma_addr = pci_map_page(cp->pdev, page->buffer, 0, cp->page_size, PCI_DMA_FROMDEVICE); return page; @@ -579,7 +606,7 @@ static void cas_spare_recover(struct cas *cp, const gfp_t flags) list_for_each_safe(elem, tmp, &list) { cas_page_t *page = list_entry(elem, cas_page_t, list); - if (page_count(page->buffer) > 1) + if (cas_buffer_count(page) > 1) continue; list_del(elem); @@ -1347,7 +1374,7 @@ static inline cas_page_t *cas_page_spare(struct cas *cp, const int index) cas_page_t *page = cp->rx_pages[1][index]; cas_page_t *new; - if (page_count(page->buffer) == 1) + if (cas_buffer_count(page) == 1) return page; new = cas_page_dequeue(cp); @@ -1367,7 +1394,7 @@ static cas_page_t *cas_page_swap(struct cas *cp, const int ring, cas_page_t **page1 = cp->rx_pages[1]; /* swap if buffer is in use */ - if (page_count(page0[index]->buffer) > 1) { + if (cas_buffer_count(page0[index]) > 1) { cas_page_t *new = cas_page_spare(cp, index); if (new) { page1[index] = page0[index]; @@ -2039,6 +2066,7 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc, skb->len += hlen - swivel; get_page(page->buffer); + cas_buffer_inc(page); frag->page = page->buffer; frag->page_offset = off; frag->size = hlen - swivel; @@ -2063,6 +2091,7 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc, frag++; get_page(page->buffer); + cas_buffer_inc(page); frag->page = page->buffer; frag->page_offset = 0; frag->size = hlen; @@ -2225,7 +2254,7 @@ static int cas_post_rxds_ringN(struct cas *cp, int ring, int num) released = 0; while (entry != last) { /* make a new buffer if it's still in use */ - if (page_count(page[entry]->buffer) > 1) { + if (cas_buffer_count(page[entry]) > 1) { cas_page_t *new = cas_page_dequeue(cp); if (!new) { /* let the timer know that we need to @@ -2885,8 +2914,7 @@ static int cas_start_xmit(struct sk_buff *skb, struct net_device *dev) */ static int ring; - skb = skb_padto(skb, cp->min_frame_size); - if (!skb) + if (skb_padto(skb, cp->min_frame_size)) return 0; /* XXX: we need some higher-level QoS hooks to steer packets to @@ -3864,7 +3892,7 @@ static void cas_reset(struct cas *cp, int blkflag) spin_unlock(&cp->stat_lock[N_TX_RINGS]); } -/* Shut down the chip, must be called with pm_sem held. */ +/* Shut down the chip, must be called with pm_mutex held. */ static void cas_shutdown(struct cas *cp) { unsigned long flags; @@ -4283,11 +4311,11 @@ static int cas_open(struct net_device *dev) int hw_was_up, err; unsigned long flags; - down(&cp->pm_sem); + mutex_lock(&cp->pm_mutex); hw_was_up = cp->hw_running; - /* The power-management semaphore protects the hw_running + /* The power-management mutex protects the hw_running * etc. state so it is safe to do this bit without cp->lock */ if (!cp->hw_running) { @@ -4321,7 +4349,7 @@ static int cas_open(struct net_device *dev) * mapping to expose them */ if (request_irq(cp->pdev->irq, cas_interrupt, - SA_SHIRQ, dev->name, (void *) dev)) { + IRQF_SHARED, dev->name, (void *) dev)) { printk(KERN_ERR "%s: failed to request irq !\n", cp->dev->name); err = -EAGAIN; @@ -4336,7 +4364,7 @@ static int cas_open(struct net_device *dev) cas_unlock_all_restore(cp, flags); netif_start_queue(dev); - up(&cp->pm_sem); + mutex_unlock(&cp->pm_mutex); return 0; err_spare: @@ -4344,7 +4372,7 @@ err_spare: cas_free_rxds(cp); err_tx_tiny: cas_tx_tiny_free(cp); - up(&cp->pm_sem); + mutex_unlock(&cp->pm_mutex); return err; } @@ -4354,7 +4382,7 @@ static int cas_close(struct net_device *dev) struct cas *cp = netdev_priv(dev); /* Make sure we don't get distracted by suspend/resume */ - down(&cp->pm_sem); + mutex_lock(&cp->pm_mutex); netif_stop_queue(dev); @@ -4371,7 +4399,7 @@ static int cas_close(struct net_device *dev) cas_spare_free(cp); cas_free_rxds(cp); cas_tx_tiny_free(cp); - up(&cp->pm_sem); + mutex_unlock(&cp->pm_mutex); return 0; } @@ -4806,10 +4834,10 @@ static int cas_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) unsigned long flags; int rc = -EOPNOTSUPP; - /* Hold the PM semaphore while doing ioctl's or we may collide + /* Hold the PM mutex while doing ioctl's or we may collide * with open/close and power management and oops. */ - down(&cp->pm_sem); + mutex_lock(&cp->pm_mutex); switch (cmd) { case SIOCGMIIPHY: /* Get address of MII PHY in use. */ data->phy_id = cp->phy_addr; @@ -4839,7 +4867,7 @@ static int cas_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) break; }; - up(&cp->pm_sem); + mutex_unlock(&cp->pm_mutex); return rc; } @@ -4847,7 +4875,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static int cas_version_printed = 0; - unsigned long casreg_base, casreg_len; + unsigned long casreg_len; struct net_device *dev; struct cas *cp; int i, err, pci_using_dac; @@ -4859,13 +4887,12 @@ static int __devinit cas_init_one(struct pci_dev *pdev, err = pci_enable_device(pdev); if (err) { - printk(KERN_ERR PFX "Cannot enable PCI device, " - "aborting.\n"); + dev_err(&pdev->dev, "Cannot enable PCI device, aborting.\n"); return err; } if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { - printk(KERN_ERR PFX "Cannot find proper PCI device " + dev_err(&pdev->dev, "Cannot find proper PCI device " "base address, aborting.\n"); err = -ENODEV; goto err_out_disable_pdev; @@ -4873,7 +4900,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(*cp)); if (!dev) { - printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n"); + dev_err(&pdev->dev, "Etherdev alloc failed, aborting.\n"); err = -ENOMEM; goto err_out_disable_pdev; } @@ -4882,8 +4909,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev, err = pci_request_regions(pdev, dev->name); if (err) { - printk(KERN_ERR PFX "Cannot obtain PCI resources, " - "aborting.\n"); + dev_err(&pdev->dev, "Cannot obtain PCI resources, aborting.\n"); goto err_out_free_netdev; } pci_set_master(pdev); @@ -4913,7 +4939,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev, if (pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, cas_cacheline_size)) { - printk(KERN_ERR PFX "Could not set PCI cache " + dev_err(&pdev->dev, "Could not set PCI cache " "line size\n"); goto err_write_cacheline; } @@ -4927,7 +4953,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev, err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); if (err < 0) { - printk(KERN_ERR PFX "Unable to obtain 64-bit DMA " + dev_err(&pdev->dev, "Unable to obtain 64-bit DMA " "for consistent allocations\n"); goto err_out_free_res; } @@ -4935,14 +4961,13 @@ static int __devinit cas_init_one(struct pci_dev *pdev, } else { err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); if (err) { - printk(KERN_ERR PFX "No usable DMA configuration, " + dev_err(&pdev->dev, "No usable DMA configuration, " "aborting.\n"); goto err_out_free_res; } pci_using_dac = 0; } - casreg_base = pci_resource_start(pdev, 0); casreg_len = pci_resource_len(pdev, 0); cp = netdev_priv(dev); @@ -4966,7 +4991,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev, spin_lock_init(&cp->tx_lock[i]); } spin_lock_init(&cp->stat_lock[N_TX_RINGS]); - init_MUTEX(&cp->pm_sem); + mutex_init(&cp->pm_mutex); init_timer(&cp->link_timer); cp->link_timer.function = cas_link_timer; @@ -4994,10 +5019,9 @@ static int __devinit cas_init_one(struct pci_dev *pdev, cp->timer_ticks = 0; /* give us access to cassini registers */ - cp->regs = ioremap(casreg_base, casreg_len); + cp->regs = pci_iomap(pdev, 0, casreg_len); if (cp->regs == 0UL) { - printk(KERN_ERR PFX "Cannot map device registers, " - "aborting.\n"); + dev_err(&pdev->dev, "Cannot map device registers, aborting.\n"); goto err_out_free_res; } cp->casreg_len = casreg_len; @@ -5013,8 +5037,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev, pci_alloc_consistent(pdev, sizeof(struct cas_init_block), &cp->block_dvma); if (!cp->init_block) { - printk(KERN_ERR PFX "Cannot allocate init block, " - "aborting.\n"); + dev_err(&pdev->dev, "Cannot allocate init block, aborting.\n"); goto err_out_iounmap; } @@ -5058,8 +5081,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev, dev->features |= NETIF_F_HIGHDMA; if (register_netdev(dev)) { - printk(KERN_ERR PFX "Cannot register net device, " - "aborting.\n"); + dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); goto err_out_free_consistent; } @@ -5088,12 +5110,12 @@ err_out_free_consistent: cp->init_block, cp->block_dvma); err_out_iounmap: - down(&cp->pm_sem); + mutex_lock(&cp->pm_mutex); if (cp->hw_running) cas_shutdown(cp); - up(&cp->pm_sem); + mutex_unlock(&cp->pm_mutex); - iounmap(cp->regs); + pci_iounmap(pdev, cp->regs); err_out_free_res: @@ -5124,11 +5146,11 @@ static void __devexit cas_remove_one(struct pci_dev *pdev) cp = netdev_priv(dev); unregister_netdev(dev); - down(&cp->pm_sem); + mutex_lock(&cp->pm_mutex); flush_scheduled_work(); if (cp->hw_running) cas_shutdown(cp); - up(&cp->pm_sem); + mutex_unlock(&cp->pm_mutex); #if 1 if (cp->orig_cacheline_size) { @@ -5141,7 +5163,7 @@ static void __devexit cas_remove_one(struct pci_dev *pdev) #endif pci_free_consistent(pdev, sizeof(struct cas_init_block), cp->init_block, cp->block_dvma); - iounmap(cp->regs); + pci_iounmap(pdev, cp->regs); free_netdev(dev); pci_release_regions(pdev); pci_disable_device(pdev); @@ -5155,10 +5177,7 @@ static int cas_suspend(struct pci_dev *pdev, pm_message_t state) struct cas *cp = netdev_priv(dev); unsigned long flags; - /* We hold the PM semaphore during entire driver - * sleep time - */ - down(&cp->pm_sem); + mutex_lock(&cp->pm_mutex); /* If the driver is opened, we stop the DMA */ if (cp->opened) { @@ -5178,6 +5197,7 @@ static int cas_suspend(struct pci_dev *pdev, pm_message_t state) if (cp->hw_running) cas_shutdown(cp); + mutex_unlock(&cp->pm_mutex); return 0; } @@ -5189,6 +5209,7 @@ static int cas_resume(struct pci_dev *pdev) printk(KERN_INFO "%s: resuming\n", dev->name); + mutex_lock(&cp->pm_mutex); cas_hard_reset(cp); if (cp->opened) { unsigned long flags; @@ -5201,7 +5222,7 @@ static int cas_resume(struct pci_dev *pdev) netif_device_attach(dev); } - up(&cp->pm_sem); + mutex_unlock(&cp->pm_mutex); return 0; } #endif /* CONFIG_PM */