/** * 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_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; }
void ConfigMACRegs2(struct et131x_adapter *etdev) { int32_t delay = 0; struct _MAC_t __iomem *pMac = &etdev->regs->mac; MAC_CFG1_t cfg1; MAC_CFG2_t cfg2; MAC_IF_CTRL_t ifctrl; TXMAC_CTL_t ctl; ctl.value = readl(&etdev->regs->txmac.ctl.value); cfg1.value = readl(&pMac->cfg1.value); cfg2.value = readl(&pMac->cfg2.value); ifctrl.value = readl(&pMac->if_ctrl.value); if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS) { cfg2.bits.if_mode = 0x2; ifctrl.bits.phy_mode = 0x0; } else { cfg2.bits.if_mode = 0x1; ifctrl.bits.phy_mode = 0x1; } cfg1.bits.rx_enable = 0x1; cfg1.bits.tx_enable = 0x1; cfg1.bits.tx_flow = 0x1; if ((etdev->FlowControl == RxOnly) || (etdev->FlowControl == Both)) { cfg1.bits.rx_flow = 0x1; } else { cfg1.bits.rx_flow = 0x0; } cfg1.bits.loop_back = 0; writel(cfg1.value, &pMac->cfg1.value); cfg2.bits.preamble_len = 0x7; cfg2.bits.huge_frame = 0x0; cfg2.bits.len_check = 0x1; if (etdev->RegistryPhyLoopbk == false) { cfg2.bits.pad_crc = 0x1; cfg2.bits.crc_enable = 0x1; } else { cfg2.bits.pad_crc = 0; cfg2.bits.crc_enable = 0; } cfg2.bits.full_duplex = etdev->duplex_mode; ifctrl.bits.ghd_mode = !etdev->duplex_mode; writel(ifctrl.value, &pMac->if_ctrl.value); writel(cfg2.value, &pMac->cfg2.value); do { udelay(10); delay++; cfg1.value = readl(&pMac->cfg1.value); } while ((!cfg1.bits.syncd_rx_en || !cfg1.bits.syncd_tx_en) && delay < 100); if (delay == 100) { dev_warn(&etdev->pdev->dev, "Syncd bits did not respond correctly cfg1 word 0x%08x\n", cfg1.value); } ctl.bits.txmac_en = 0x1; ctl.bits.fc_disable = 0x1; writel(ctl.value, &etdev->regs->txmac.ctl.value); if (etdev->Flags & fMP_ADAPTER_LOWER_POWER) { et131x_rx_dma_enable(etdev); et131x_tx_dma_enable(etdev); } }
/** * ConfigMacRegs2 - Initialize the second part of MAC regs * @pAdpater: pointer to our adapter structure */ void ConfigMACRegs2(struct et131x_adapter *pAdapter) { int32_t delay = 0; struct _MAC_t __iomem *pMac = &pAdapter->CSRAddress->mac; MAC_CFG1_t cfg1; MAC_CFG2_t cfg2; MAC_IF_CTRL_t ifctrl; TXMAC_CTL_t ctl; DBG_ENTER(et131x_dbginfo); ctl.value = readl(&pAdapter->CSRAddress->txmac.ctl.value); cfg1.value = readl(&pMac->cfg1.value); cfg2.value = readl(&pMac->cfg2.value); ifctrl.value = readl(&pMac->if_ctrl.value); if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS) { cfg2.bits.if_mode = 0x2; ifctrl.bits.phy_mode = 0x0; } else { cfg2.bits.if_mode = 0x1; ifctrl.bits.phy_mode = 0x1; } /* We need to enable Rx/Tx */ cfg1.bits.rx_enable = 0x1; cfg1.bits.tx_enable = 0x1; /* Set up flow control */ cfg1.bits.tx_flow = 0x1; if ((pAdapter->FlowControl == RxOnly) || (pAdapter->FlowControl == Both)) { cfg1.bits.rx_flow = 0x1; } else { cfg1.bits.rx_flow = 0x0; } /* Initialize loop back to off */ cfg1.bits.loop_back = 0; writel(cfg1.value, &pMac->cfg1.value); /* Now we need to initialize the MAC Configuration 2 register */ cfg2.bits.preamble_len = 0x7; cfg2.bits.huge_frame = 0x0; /* LENGTH FIELD CHECKING bit4: Set this bit to cause the MAC to check * the frame's length field to ensure it matches the actual data * field length. Clear this bit if no length field checking is * desired. Its default is 0. */ cfg2.bits.len_check = 0x1; if (pAdapter->RegistryPhyLoopbk == false) { cfg2.bits.pad_crc = 0x1; cfg2.bits.crc_enable = 0x1; } else { cfg2.bits.pad_crc = 0; cfg2.bits.crc_enable = 0; } /* 1 - full duplex, 0 - half-duplex */ cfg2.bits.full_duplex = pAdapter->uiDuplexMode; ifctrl.bits.ghd_mode = !pAdapter->uiDuplexMode; writel(ifctrl.value, &pMac->if_ctrl.value); writel(cfg2.value, &pMac->cfg2.value); do { udelay(10); delay++; cfg1.value = readl(&pMac->cfg1.value); } while ((!cfg1.bits.syncd_rx_en || !cfg1.bits.syncd_tx_en) && delay < 100); if (delay == 100) { DBG_ERROR(et131x_dbginfo, "Syncd bits did not respond correctly cfg1 word 0x%08x\n", cfg1.value); } DBG_TRACE(et131x_dbginfo, "Speed %d, Dup %d, CFG1 0x%08x, CFG2 0x%08x, if_ctrl 0x%08x\n", pAdapter->uiLinkSpeed, pAdapter->uiDuplexMode, readl(&pMac->cfg1.value), readl(&pMac->cfg2.value), readl(&pMac->if_ctrl.value)); /* Enable TXMAC */ ctl.bits.txmac_en = 0x1; ctl.bits.fc_disable = 0x1; writel(ctl.value, &pAdapter->CSRAddress->txmac.ctl.value); /* Ready to start the RXDMA/TXDMA engine */ if (!MP_TEST_FLAG(pAdapter, fMP_ADAPTER_LOWER_POWER)) { et131x_rx_dma_enable(pAdapter); et131x_tx_dma_enable(pAdapter); } else { DBG_WARNING(et131x_dbginfo, "Didn't enable Rx/Tx due to low-power mode\n"); } DBG_LEAVE(et131x_dbginfo); }
/** * 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; }
/** * ConfigMacRegs2 - Initialize the second part of MAC regs * @pAdpater: pointer to our adapter structure */ void ConfigMACRegs2(struct et131x_adapter *etdev) { int32_t delay = 0; struct _MAC_t __iomem *pMac = &etdev->regs->mac; u32 cfg1; u32 cfg2; u32 ifctrl; u32 ctl; ctl = readl(&etdev->regs->txmac.ctl); cfg1 = readl(&pMac->cfg1); cfg2 = readl(&pMac->cfg2); ifctrl = readl(&pMac->if_ctrl); /* Set up the if mode bits */ cfg2 &= ~0x300; if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS) { cfg2 |= 0x200; /* Phy mode bit */ ifctrl &= ~(1 << 24); } else { cfg2 |= 0x100; ifctrl |= (1 << 24); } /* We need to enable Rx/Tx */ cfg1 |= CFG1_RX_ENABLE|CFG1_TX_ENABLE|CFG1_TX_FLOW; /* Initialize loop back to off */ cfg1 &= ~(CFG1_LOOPBACK|CFG1_RX_FLOW); if (etdev->flowcontrol == FLOW_RXONLY || etdev->flowcontrol == FLOW_BOTH) cfg1 |= CFG1_RX_FLOW; writel(cfg1, &pMac->cfg1); /* Now we need to initialize the MAC Configuration 2 register */ /* preamble 7, check length, huge frame off, pad crc, crc enable full duplex off */ cfg2 |= 0x7016; cfg2 &= ~0x0021; /* Turn on duplex if needed */ if (etdev->duplex_mode) cfg2 |= 0x01; ifctrl &= ~(1 << 26); if (!etdev->duplex_mode) ifctrl |= (1<<26); /* Enable ghd */ writel(ifctrl, &pMac->if_ctrl); writel(cfg2, &pMac->cfg2); do { udelay(10); delay++; cfg1 = readl(&pMac->cfg1); } while ((cfg1 & CFG1_WAIT) != CFG1_WAIT && delay < 100); if (delay == 100) { dev_warn(&etdev->pdev->dev, "Syncd bits did not respond correctly cfg1 word 0x%08x\n", cfg1); } /* Enable TXMAC */ ctl |= 0x09; /* TX mac enable, FC disable */ writel(ctl, &etdev->regs->txmac.ctl); /* Ready to start the RXDMA/TXDMA engine */ if (etdev->Flags & fMP_ADAPTER_LOWER_POWER) { et131x_rx_dma_enable(etdev); et131x_tx_dma_enable(etdev); } }
/****************************************************************************** ROUTINE: ConfigMacRegs2 ****************************************************************************** DESCRIPTION: Used to configure the second part of MAC regs to a known initialized state PARAMETERS : pAdpater - pointer to our adapter structure RETURNS : NONE *****************************************************************************/ void ConfigMACRegs2( ET131X_ADAPTER *pAdapter ) { INT32 delay = 0; PMAC_t pMac; MAC_CFG1_t cfg1; MAC_CFG2_t cfg2; MAC_IF_CTRL_t ifctrl; TXMAC_CTL_t ctl = pAdapter->CSRAddress->txmac.ctl; /*-----------------------------------------------------------------------*/ DBG_FUNC( "ConfigMACRegs2" ); DBG_ENTER( et131x_dbginfo ); /************************************************************************** Let's get our pointer to the MAC regs *************************************************************************/ pMac = &pAdapter->CSRAddress->mac; cfg1.value = pMac->cfg1.value; cfg2.value = pMac->cfg2.value; ifctrl.value = pMac->if_ctrl.value; if( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS ) { cfg2.bits.if_mode = 0x2; ifctrl.bits.phy_mode = 0x0; } else { cfg2.bits.if_mode = 0x1; ifctrl.bits.phy_mode = 0x1; } /************************************************************************** We need to enable Rx/Tx *************************************************************************/ cfg1.bits.rx_enable = 0x1; cfg1.bits.tx_enable = 0x1; /************************************************************************** Set up flow control *************************************************************************/ cfg1.bits.tx_flow = 0x1; if( ( pAdapter->FlowControl == RxOnly ) || ( pAdapter->FlowControl == Both )) { cfg1.bits.rx_flow = 0x1; } else { cfg1.bits.rx_flow = 0x0; } /************************************************************************** Initialize loop back to off *************************************************************************/ cfg1.bits.loop_back = 0; pAdapter->CSRAddress->mac.cfg1.value = cfg1.value; /************************************************************************** Now we need to initialize the MAC Configuration 2 register *************************************************************************/ cfg2.bits.preamble_len = 0x7; cfg2.bits.huge_frame = 0x0; /* LENGTH FIELD CHECKING bit4: Set this bit to cause the MAC to check the * frame’s length field to ensure it matches the actual data field length. Clear this bit if no * length field checking is desired. Its default is ‘0’. */ cfg2.bits.len_check = 0x1; if ( pAdapter->RegistryPhyLoopbk == FALSE ) { cfg2.bits.pad_crc = 0x1; cfg2.bits.crc_enable = 0x1; } else { cfg2.bits.pad_crc = 0; cfg2.bits.crc_enable = 0; } /************************************************************************** 1 – full duplex, 0 – half-duplex *************************************************************************/ cfg2.bits.full_duplex = pAdapter->uiDuplexMode; ifctrl.bits.ghd_mode = !pAdapter->uiDuplexMode; pAdapter->CSRAddress->mac.if_ctrl = ifctrl; pAdapter->CSRAddress->mac.cfg2.value = cfg2.value; do { udelay( 10 ); delay++; } while(( !pAdapter->CSRAddress->mac.cfg1.bits.syncd_rx_en || !pAdapter->CSRAddress->mac.cfg1.bits.syncd_tx_en ) && ( delay < 100 )); if( delay == 100 ) { DBG_ERROR( et131x_dbginfo, "Syncd bits did not respond correctly cfg1 word 0x%08x\n", pAdapter->CSRAddress->mac.cfg1.value ); } DBG_TRACE( et131x_dbginfo, "Speed %d, Dup %d, CFG1 0x%08x, CFG2 0x%08x, if_ctrl 0x%08x\n", pAdapter->uiLinkSpeed, pAdapter->uiDuplexMode, pAdapter->CSRAddress->mac.cfg1.value, pAdapter->CSRAddress->mac.cfg2.value, pAdapter->CSRAddress->mac.if_ctrl.value ); /************************************************************************** Enable TXMAC *************************************************************************/ ctl.bits.txmac_en = 0x1; ctl.bits.fc_disable = 0x1; pAdapter->CSRAddress->txmac.ctl = ctl; /************************************************************************** Ready to start the RXDMA/TXDMA engine *************************************************************************/ if( !MP_TEST_FLAG( pAdapter, fMP_ADAPTER_LOWER_POWER )) { et131x_rx_dma_enable( pAdapter ); et131x_tx_dma_enable( pAdapter ); } else { DBG_WARNING( et131x_dbginfo, "Didn't enable Rx/Tx due to low-power mode\n" ); } DBG_LEAVE( et131x_dbginfo ); return; }