/** * et131x_open - Open the device for use. * @netdev: device to be opened * * Returns 0 on success, errno on failure (as defined in errno.h) */ int et131x_open(struct net_device *netdev) { int result = 0; struct et131x_adapter *adapter = netdev_priv(netdev); /* Start the timer to track NIC errors */ add_timer(&adapter->ErrorTimer); /* Register our IRQ */ result = request_irq(netdev->irq, et131x_isr, IRQF_SHARED, netdev->name, netdev); if (result) { dev_err(&adapter->pdev->dev, "c ould not register IRQ %d\n", netdev->irq); return result; } /* Enable the Tx and Rx DMA engines (if not already enabled) */ et131x_rx_dma_enable(adapter); et131x_tx_dma_enable(adapter); /* Enable device interrupts */ et131x_enable_interrupts(adapter); adapter->Flags |= fMP_ADAPTER_INTERRUPT_IN_USE; /* We're ready to move some data, so start the queue */ netif_start_queue(netdev); return result; }
/** * et131x_change_mtu - The handler called to change the MTU for the device * @netdev: device whose MTU is to be changed * @new_mtu: the desired MTU * * Returns 0 on success, errno on failure (as defined in errno.h) */ int et131x_change_mtu(struct net_device *netdev, int new_mtu) { int result = 0; struct et131x_adapter *adapter = netdev_priv(netdev); /* Make sure the requested MTU is valid */ if (new_mtu < 64 || new_mtu > 9216) return -EINVAL; /* Stop the netif queue */ netif_stop_queue(netdev); /* Stop the Tx and Rx DMA engines */ et131x_rx_dma_disable(adapter); et131x_tx_dma_disable(adapter); /* Disable device interrupts */ et131x_disable_interrupts(adapter); et131x_handle_send_interrupt(adapter); et131x_handle_recv_interrupt(adapter); /* Set the new MTU */ netdev->mtu = new_mtu; /* Free Rx DMA memory */ et131x_adapter_memory_free(adapter); /* Set the config parameter for Jumbo Packet support */ adapter->RegistryJumboPacket = new_mtu + 14; et131x_soft_reset(adapter); /* Alloc and init Rx DMA memory */ result = et131x_adapter_memory_alloc(adapter); if (result != 0) { dev_warn(&adapter->pdev->dev, "Change MTU failed; couldn't re-alloc DMA memory\n"); return result; } et131x_init_send(adapter); et131x_hwaddr_init(adapter); memcpy(netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN); /* Init the device with the new settings */ et131x_adapter_setup(adapter); /* Enable interrupts */ if (adapter->Flags & fMP_ADAPTER_INTERRUPT_IN_USE) et131x_enable_interrupts(adapter); /* Restart the Tx and Rx DMA engines */ et131x_rx_dma_enable(adapter); et131x_tx_dma_enable(adapter); /* Restart the netif queue */ netif_wake_queue(netdev); return result; }
/** * et131x_open - Open the device for use. * @netdev: device to be opened * * Returns 0 on success, errno on failure (as defined in errno.h) */ int et131x_open(struct net_device *netdev) { int result = 0; struct et131x_adapter *adapter = netdev_priv(netdev); DBG_ENTER(et131x_dbginfo); /* Start the timer to track NIC errors */ add_timer(&adapter->ErrorTimer); /* Register our ISR */ DBG_TRACE(et131x_dbginfo, "Registering ISR...\n"); result = request_irq(netdev->irq, et131x_isr, IRQF_SHARED, netdev->name, netdev); if (result) { DBG_ERROR(et131x_dbginfo, "Could not register ISR\n"); DBG_LEAVE(et131x_dbginfo); return result; } /* Enable the Tx and Rx DMA engines (if not already enabled) */ et131x_rx_dma_enable(adapter); et131x_tx_dma_enable(adapter); /* Enable device interrupts */ et131x_enable_interrupts(adapter); MP_SET_FLAG(adapter, fMP_ADAPTER_INTERRUPT_IN_USE); /* We're ready to move some data, so start the queue */ netif_start_queue(netdev); DBG_LEAVE(et131x_dbginfo); return result; }
/** * et131x_error_timer_handler * @data: timer-specific variable; here a pointer to our adapter structure * * The routine called when the error timer expires, to track the number of * recurring errors. */ void et131x_error_timer_handler(unsigned long data) { struct et131x_adapter *etdev = (struct et131x_adapter *) data; u32 pm_csr; pm_csr = readl(&etdev->regs->global.pm_csr); if ((pm_csr & ET_PM_PHY_SW_COMA) == 0) UpdateMacStatHostCounters(etdev); else dev_err(&etdev->pdev->dev, "No interrupts, in PHY coma, pm_csr = 0x%x\n", pm_csr); if (!etdev->Bmsr.bits.link_status && etdev->RegistryPhyComa && etdev->boot_coma < 11) { etdev->boot_coma++; } if (etdev->boot_coma == 10) { if (!etdev->Bmsr.bits.link_status && etdev->RegistryPhyComa) { if ((pm_csr & ET_PM_PHY_SW_COMA) == 0) { /* NOTE - This was originally a 'sync with * interrupt'. How to do that under Linux? */ et131x_enable_interrupts(etdev); EnablePhyComa(etdev); } } } /* This is a periodic timer, so reschedule */ mod_timer(&etdev->ErrorTimer, jiffies + TX_ERROR_PERIOD * HZ / 1000); }
/** * et131x_set_mac_addr - handler to change the MAC address for the device * @netdev: device whose MAC is to be changed * @new_mac: the desired MAC address * * Returns 0 on success, errno on failure (as defined in errno.h) * * IMPLEMENTED BY : blux http://berndlux.de 22.01.2007 21:14 */ int et131x_set_mac_addr(struct net_device *netdev, void *new_mac) { int result = 0; struct et131x_adapter *adapter = netdev_priv(netdev); struct sockaddr *address = new_mac; /* begin blux */ if (adapter == NULL) return -ENODEV; /* Make sure the requested MAC is valid */ if (!is_valid_ether_addr(address->sa_data)) return -EINVAL; /* Stop the netif queue */ netif_stop_queue(netdev); /* Stop the Tx and Rx DMA engines */ et131x_rx_dma_disable(adapter); et131x_tx_dma_disable(adapter); /* Disable device interrupts */ et131x_disable_interrupts(adapter); et131x_handle_send_interrupt(adapter); et131x_handle_recv_interrupt(adapter); /* Set the new MAC */ /* netdev->set_mac_address = &new_mac; */ /* netdev->mtu = new_mtu; */ memcpy(netdev->dev_addr, address->sa_data, netdev->addr_len); printk(KERN_INFO "%s: Setting MAC address to %pM\n", netdev->name, netdev->dev_addr); /* Free Rx DMA memory */ et131x_adapter_memory_free(adapter); /* Set the config parameter for Jumbo Packet support */ /* adapter->RegistryJumboPacket = new_mtu + 14; */ /* blux: not needet here, we'll change the MAC */ et131x_soft_reset(adapter); /* Alloc and init Rx DMA memory */ result = et131x_adapter_memory_alloc(adapter); if (result != 0) { dev_err(&adapter->pdev->dev, "Change MAC failed; couldn't re-alloc DMA memory\n"); return result; } et131x_init_send(adapter); et131x_hwaddr_init(adapter); /* Init the device with the new settings */ et131x_adapter_setup(adapter); /* Enable interrupts */ if (adapter->Flags & fMP_ADAPTER_INTERRUPT_IN_USE) et131x_enable_interrupts(adapter); /* Restart the Tx and Rx DMA engines */ et131x_rx_dma_enable(adapter); et131x_tx_dma_enable(adapter); /* Restart the netif queue */ netif_wake_queue(netdev); return result; }
irqreturn_t et131x_isr(int irq, void *dev_id) { bool handled = true; struct net_device *netdev = (struct net_device *)dev_id; struct et131x_adapter *adapter = NULL; u32 status; if (!netif_device_present(netdev)) { handled = false; goto out; } adapter = netdev_priv(netdev); /* If the adapter is in low power state, then it should not * recognize any interrupt */ /* Disable Device Interrupts */ et131x_disable_interrupts(adapter); /* Get a copy of the value in the interrupt status register * so we can process the interrupting section */ status = readl(&adapter->regs->global.int_status); if (adapter->flowcontrol == FLOW_TXONLY || adapter->flowcontrol == FLOW_BOTH) { status &= ~INT_MASK_ENABLE; } else { status &= ~INT_MASK_ENABLE_NO_FLOW; } /* Make sure this is our interrupt */ if (!status) { handled = false; et131x_enable_interrupts(adapter); goto out; } /* This is our interrupt, so process accordingly */ if (status & ET_INTR_WATCHDOG) { struct tcb *tcb = adapter->tx_ring.send_head; if (tcb) if (++tcb->stale > 1) status |= ET_INTR_TXDMA_ISR; if (adapter->rx_ring.UnfinishedReceives) status |= ET_INTR_RXDMA_XFR_DONE; else if (tcb == NULL) writel(0, &adapter->regs->global.watchdog_timer); status &= ~ET_INTR_WATCHDOG; } if (status == 0) { /* This interrupt has in some way been "handled" by * the ISR. Either it was a spurious Rx interrupt, or * it was a Tx interrupt that has been filtered by * the ISR. */ et131x_enable_interrupts(adapter); goto out; } /* We need to save the interrupt status value for use in our * DPC. We will clear the software copy of that in that * routine. */ adapter->stats.InterruptStatus = status; /* Schedule the ISR handler as a bottom-half task in the * kernel's tq_immediate queue, and mark the queue for * execution */ schedule_work(&adapter->task); out: return IRQ_RETVAL(handled); }
/** * et131x_set_mac_addr - handler to change the MAC address for the device * @netdev: device whose MAC is to be changed * @new_mac: the desired MAC address * * Returns 0 on success, errno on failure (as defined in errno.h) * * IMPLEMENTED BY : blux http://berndlux.de 22.01.2007 21:14 */ int et131x_set_mac_addr(struct net_device *netdev, void *new_mac) { int result = 0; struct et131x_adapter *adapter = netdev_priv(netdev); struct sockaddr *address = new_mac; DBG_ENTER(et131x_dbginfo); // begin blux // DBG_VERBOSE( et131x_dbginfo, "Function not implemented!!\n" ); if (adapter == NULL) { DBG_LEAVE(et131x_dbginfo); return -ENODEV; } /* Make sure the requested MAC is valid */ if (!is_valid_ether_addr(address->sa_data)) { DBG_LEAVE(et131x_dbginfo); return -EINVAL; } /* Stop the netif queue */ netif_stop_queue(netdev); /* Stop the Tx and Rx DMA engines */ et131x_rx_dma_disable(adapter); et131x_tx_dma_disable(adapter); /* Disable device interrupts */ et131x_disable_interrupts(adapter); et131x_handle_send_interrupt(adapter); et131x_handle_recv_interrupt(adapter); /* Set the new MAC */ // netdev->set_mac_address = &new_mac; // netdev->mtu = new_mtu; memcpy(netdev->dev_addr, address->sa_data, netdev->addr_len); printk("%s: Setting MAC address to %02x:%02x:%02x:%02x:%02x:%02x\n", netdev->name, netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2], netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]); /* Free Rx DMA memory */ et131x_adapter_memory_free(adapter); /* Set the config parameter for Jumbo Packet support */ // adapter->RegistryJumboPacket = new_mtu + 14; // blux: not needet here, w'll change the MAC et131x_soft_reset(adapter); /* Alloc and init Rx DMA memory */ result = et131x_adapter_memory_alloc(adapter); if (result != 0) { DBG_WARNING(et131x_dbginfo, "Change MAC failed; couldn't re-alloc DMA memory\n"); return result; } et131x_init_send(adapter); et131x_setup_hardware_properties(adapter); // memcpy( netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN ); // blux: no, do not override our nice address /* Init the device with the new settings */ et131x_adapter_setup(adapter); /* Enable interrupts */ if (MP_TEST_FLAG(adapter, fMP_ADAPTER_INTERRUPT_IN_USE)) { et131x_enable_interrupts(adapter); } /* Restart the Tx and Rx DMA engines */ et131x_rx_dma_enable(adapter); et131x_tx_dma_enable(adapter); /* Restart the netif queue */ netif_wake_queue(netdev); DBG_LEAVE(et131x_dbginfo); return result; }