static void c2_reset(struct c2_port *c2_port) { struct c2_dev *c2dev = c2_port->c2dev; unsigned int cur_rx = c2dev->cur_rx; /* Tell the hardware to quiesce */ C2_SET_CUR_RX(c2dev, cur_rx | C2_PCI_HRX_QUI); /* * The hardware will reset the C2_PCI_HRX_QUI bit once * the RXP is quiesced. Wait 2 seconds for this. */ ssleep(2); cur_rx = C2_GET_CUR_RX(c2dev); if (cur_rx & C2_PCI_HRX_QUI) pr_debug("c2_reset: failed to quiesce the hardware!\n"); cur_rx &= ~C2_PCI_HRX_QUI; c2dev->cur_rx = cur_rx; pr_debug("Current RX: %u\n", c2dev->cur_rx); }
static void c2_reset(struct c2_port *c2_port) { struct c2_dev *c2dev = c2_port->c2dev; unsigned int cur_rx = c2dev->cur_rx; C2_SET_CUR_RX(c2dev, cur_rx | C2_PCI_HRX_QUI); ssleep(2); cur_rx = C2_GET_CUR_RX(c2dev); if (cur_rx & C2_PCI_HRX_QUI) pr_debug("c2_reset: failed to quiesce the hardware!\n"); cur_rx &= ~C2_PCI_HRX_QUI; c2dev->cur_rx = cur_rx; pr_debug("Current RX: %u\n", c2dev->cur_rx); }
static int __devinit c2_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) { int ret = 0, i; unsigned long reg0_start, reg0_flags, reg0_len; unsigned long reg2_start, reg2_flags, reg2_len; unsigned long reg4_start, reg4_flags, reg4_len; unsigned kva_map_size; struct net_device *netdev = NULL; struct c2_dev *c2dev = NULL; void __iomem *mmio_regs = NULL; printk(KERN_INFO PFX "AMSO1100 Gigabit Ethernet driver v%s loaded\n", DRV_VERSION); ret = pci_enable_device(pcidev); if (ret) { printk(KERN_ERR PFX "%s: Unable to enable PCI device\n", pci_name(pcidev)); goto bail0; } reg0_start = pci_resource_start(pcidev, BAR_0); reg0_len = pci_resource_len(pcidev, BAR_0); reg0_flags = pci_resource_flags(pcidev, BAR_0); reg2_start = pci_resource_start(pcidev, BAR_2); reg2_len = pci_resource_len(pcidev, BAR_2); reg2_flags = pci_resource_flags(pcidev, BAR_2); reg4_start = pci_resource_start(pcidev, BAR_4); reg4_len = pci_resource_len(pcidev, BAR_4); reg4_flags = pci_resource_flags(pcidev, BAR_4); pr_debug("BAR0 size = 0x%lX bytes\n", reg0_len); pr_debug("BAR2 size = 0x%lX bytes\n", reg2_len); pr_debug("BAR4 size = 0x%lX bytes\n", reg4_len); if (!(reg0_flags & IORESOURCE_MEM) || !(reg2_flags & IORESOURCE_MEM) || !(reg4_flags & IORESOURCE_MEM)) { printk(KERN_ERR PFX "PCI regions not an MMIO resource\n"); ret = -ENODEV; goto bail1; } if ((reg0_len < C2_REG0_SIZE) || (reg2_len < C2_REG2_SIZE) || (reg4_len < C2_REG4_SIZE)) { printk(KERN_ERR PFX "Invalid PCI region sizes\n"); ret = -ENODEV; goto bail1; } ret = pci_request_regions(pcidev, DRV_NAME); if (ret) { printk(KERN_ERR PFX "%s: Unable to request regions\n", pci_name(pcidev)); goto bail1; } if ((sizeof(dma_addr_t) > 4)) { ret = pci_set_dma_mask(pcidev, DMA_BIT_MASK(64)); if (ret < 0) { printk(KERN_ERR PFX "64b DMA configuration failed\n"); goto bail2; } } else { ret = pci_set_dma_mask(pcidev, DMA_BIT_MASK(32)); if (ret < 0) { printk(KERN_ERR PFX "32b DMA configuration failed\n"); goto bail2; } } pci_set_master(pcidev); mmio_regs = ioremap_nocache(reg4_start + C2_PCI_REGS_OFFSET, sizeof(struct c2_adapter_pci_regs)); if (!mmio_regs) { printk(KERN_ERR PFX "Unable to remap adapter PCI registers in BAR4\n"); ret = -EIO; goto bail2; } for (i = 0; i < sizeof(c2_magic); i++) { if (c2_magic[i] != readb(mmio_regs + C2_REGS_MAGIC + i)) { printk(KERN_ERR PFX "Downlevel Firmware boot loader " "[%d/%Zd: got 0x%x, exp 0x%x]. Use the cc_flash " "utility to update your boot loader\n", i + 1, sizeof(c2_magic), readb(mmio_regs + C2_REGS_MAGIC + i), c2_magic[i]); printk(KERN_ERR PFX "Adapter not claimed\n"); iounmap(mmio_regs); ret = -EIO; goto bail2; } } if (be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_VERS)) != C2_VERSION) { printk(KERN_ERR PFX "Version mismatch " "[fw=%u, c2=%u], Adapter not claimed\n", be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_VERS)), C2_VERSION); ret = -EINVAL; iounmap(mmio_regs); goto bail2; } if (be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_IVN)) != C2_IVN) { printk(KERN_ERR PFX "Downlevel FIrmware level. You should be using " "the OpenIB device support kit. " "[fw=0x%x, c2=0x%x], Adapter not claimed\n", be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_IVN)), C2_IVN); ret = -EINVAL; iounmap(mmio_regs); goto bail2; } c2dev = (struct c2_dev *) ib_alloc_device(sizeof(*c2dev)); if (!c2dev) { printk(KERN_ERR PFX "%s: Unable to alloc hardware struct\n", pci_name(pcidev)); ret = -ENOMEM; iounmap(mmio_regs); goto bail2; } memset(c2dev, 0, sizeof(*c2dev)); spin_lock_init(&c2dev->lock); c2dev->pcidev = pcidev; c2dev->cur_tx = 0; c2dev->cur_rx = (be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_HRX_CUR)) - 0xffffc000) / sizeof(struct c2_rxp_desc); ret = request_irq(pcidev->irq, c2_interrupt, IRQF_SHARED, DRV_NAME, c2dev); if (ret) { printk(KERN_ERR PFX "%s: requested IRQ %u is busy\n", pci_name(pcidev), pcidev->irq); iounmap(mmio_regs); goto bail3; } pci_set_drvdata(pcidev, c2dev); if ((netdev = c2_devinit(c2dev, mmio_regs)) == NULL) { iounmap(mmio_regs); goto bail4; } kva_map_size = be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_PCI_WINSIZE)); iounmap(mmio_regs); ret = register_netdev(netdev); if (ret) { printk(KERN_ERR PFX "Unable to register netdev, ret = %d\n", ret); goto bail5; } netif_stop_queue(netdev); c2dev->mmio_rxp_ring = ioremap_nocache(reg4_start + C2_RXP_HRXDQ_OFFSET, C2_RXP_HRXDQ_SIZE); if (!c2dev->mmio_rxp_ring) { printk(KERN_ERR PFX "Unable to remap MMIO HRXDQ region\n"); ret = -EIO; goto bail6; } c2dev->mmio_txp_ring = ioremap_nocache(reg4_start + C2_TXP_HTXDQ_OFFSET, C2_TXP_HTXDQ_SIZE); if (!c2dev->mmio_txp_ring) { printk(KERN_ERR PFX "Unable to remap MMIO HTXDQ region\n"); ret = -EIO; goto bail7; } C2_SET_CUR_RX(c2dev, c2dev->cur_rx); c2dev->regs = ioremap_nocache(reg0_start, reg0_len); if (!c2dev->regs) { printk(KERN_ERR PFX "Unable to remap BAR0\n"); ret = -EIO; goto bail8; } c2dev->pa = reg4_start + C2_PCI_REGS_OFFSET; c2dev->kva = ioremap_nocache(reg4_start + C2_PCI_REGS_OFFSET, kva_map_size); if (!c2dev->kva) { printk(KERN_ERR PFX "Unable to remap BAR4\n"); ret = -EIO; goto bail9; } c2_print_macaddr(netdev); ret = c2_rnic_init(c2dev); if (ret) { printk(KERN_ERR PFX "c2_rnic_init failed: %d\n", ret); goto bail10; } if (c2_register_device(c2dev)) goto bail10; return 0; bail10: iounmap(c2dev->kva); bail9: iounmap(c2dev->regs); bail8: iounmap(c2dev->mmio_txp_ring); bail7: iounmap(c2dev->mmio_rxp_ring); bail6: unregister_netdev(netdev); bail5: free_netdev(netdev); bail4: free_irq(pcidev->irq, c2dev); bail3: ib_dealloc_device(&c2dev->ibdev); bail2: pci_release_regions(pcidev); bail1: pci_disable_device(pcidev); bail0: return ret; }
static void c2_rx_interrupt(struct net_device *netdev) { struct c2_port *c2_port = netdev_priv(netdev); struct c2_dev *c2dev = c2_port->c2dev; struct c2_ring *rx_ring = &c2_port->rx_ring; struct c2_element *elem; struct c2_rx_desc *rx_desc; struct c2_rxp_hdr *rxp_hdr; struct sk_buff *skb; dma_addr_t mapaddr; u32 maplen, buflen; unsigned long flags; spin_lock_irqsave(&c2dev->lock, flags); rx_ring->to_clean = rx_ring->start + c2dev->cur_rx; for (elem = rx_ring->to_clean; elem->next != rx_ring->to_clean; elem = elem->next) { rx_desc = elem->ht_desc; mapaddr = elem->mapaddr; maplen = elem->maplen; skb = elem->skb; rxp_hdr = (struct c2_rxp_hdr *) skb->data; if (rxp_hdr->flags != RXP_HRXD_DONE) break; buflen = rxp_hdr->len; if (rxp_hdr->status != RXP_HRXD_OK || buflen > (rx_desc->len - sizeof(*rxp_hdr))) { c2_rx_error(c2_port, elem); continue; } if (c2_rx_alloc(c2_port, elem)) { c2_rx_error(c2_port, elem); continue; } pci_unmap_single(c2dev->pcidev, mapaddr, maplen, PCI_DMA_FROMDEVICE); prefetch(skb->data); skb->data += sizeof(*rxp_hdr); skb_set_tail_pointer(skb, buflen); skb->len = buflen; skb->protocol = eth_type_trans(skb, netdev); netif_rx(skb); netdev->stats.rx_packets++; netdev->stats.rx_bytes += buflen; } rx_ring->to_clean = elem; c2dev->cur_rx = elem - rx_ring->start; C2_SET_CUR_RX(c2dev, c2dev->cur_rx); spin_unlock_irqrestore(&c2dev->lock, flags); }
static void c2_rx_interrupt(struct net_device *netdev) { struct c2_port *c2_port = netdev_priv(netdev); struct c2_dev *c2dev = c2_port->c2dev; struct c2_ring *rx_ring = &c2_port->rx_ring; struct c2_element *elem; struct c2_rx_desc *rx_desc; struct c2_rxp_hdr *rxp_hdr; struct sk_buff *skb; dma_addr_t mapaddr; u32 maplen, buflen; unsigned long flags; spin_lock_irqsave(&c2dev->lock, flags); /* Begin where we left off */ rx_ring->to_clean = rx_ring->start + c2dev->cur_rx; for (elem = rx_ring->to_clean; elem->next != rx_ring->to_clean; elem = elem->next) { rx_desc = elem->ht_desc; mapaddr = elem->mapaddr; maplen = elem->maplen; skb = elem->skb; rxp_hdr = (struct c2_rxp_hdr *) skb->data; if (rxp_hdr->flags != RXP_HRXD_DONE) break; buflen = rxp_hdr->len; /* Sanity check the RXP header */ if (rxp_hdr->status != RXP_HRXD_OK || buflen > (rx_desc->len - sizeof(*rxp_hdr))) { c2_rx_error(c2_port, elem); continue; } /* * Allocate and map a new skb for replenishing the host * RX desc */ if (c2_rx_alloc(c2_port, elem)) { c2_rx_error(c2_port, elem); continue; } /* Unmap the old skb */ pci_unmap_single(c2dev->pcidev, mapaddr, maplen, PCI_DMA_FROMDEVICE); prefetch(skb->data); /* * Skip past the leading 8 bytes comprising of the * "struct c2_rxp_hdr", prepended by the adapter * to the usual Ethernet header ("struct ethhdr"), * to the start of the raw Ethernet packet. * * Fix up the various fields in the sk_buff before * passing it up to netif_rx(). The transfer size * (in bytes) specified by the adapter len field of * the "struct rxp_hdr_t" does NOT include the * "sizeof(struct c2_rxp_hdr)". */ skb->data += sizeof(*rxp_hdr); skb_set_tail_pointer(skb, buflen); skb->len = buflen; skb->protocol = eth_type_trans(skb, netdev); netif_rx(skb); netdev->last_rx = jiffies; netdev->stats.rx_packets++; netdev->stats.rx_bytes += buflen; } /* Save where we left off */ rx_ring->to_clean = elem; c2dev->cur_rx = elem - rx_ring->start; C2_SET_CUR_RX(c2dev, c2dev->cur_rx); spin_unlock_irqrestore(&c2dev->lock, flags); }