void DisablePhyComa(struct et131x_adapter *etdev) { u32 GlobalPmCSR; GlobalPmCSR = readl(&etdev->regs->global.pm_csr); GlobalPmCSR |= ET_PMCSR_INIT; GlobalPmCSR &= ~ET_PM_PHY_SW_COMA; writel(GlobalPmCSR, &etdev->regs->global.pm_csr); etdev->AiForceSpeed = etdev->PoMgmt.PowerDownSpeed; etdev->AiForceDpx = etdev->PoMgmt.PowerDownDuplex; et131x_init_send(etdev); et131x_reset_recv(etdev); et131x_soft_reset(etdev); et131x_adapter_setup(etdev); etdev->Flags &= ~fMP_ADAPTER_LOWER_POWER; et131x_rx_dma_enable(etdev); }
/** * 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; }
/** * DisablePhyComa - Disable the Phy Coma Mode * @pAdapter: pointer to our adapter structure */ void DisablePhyComa(struct et131x_adapter *pAdapter) { PM_CSR_t GlobalPmCSR; DBG_ENTER(et131x_dbginfo); GlobalPmCSR.value = readl(&pAdapter->CSRAddress->global.pm_csr.value); /* Disable phy_sw_coma register and re-enable JAGCore clocks */ GlobalPmCSR.bits.pm_sysclk_gate = 1; GlobalPmCSR.bits.pm_txclk_gate = 1; GlobalPmCSR.bits.pm_rxclk_gate = 1; GlobalPmCSR.bits.pm_phy_sw_coma = 0; writel(GlobalPmCSR.value, &pAdapter->CSRAddress->global.pm_csr.value); /* Restore the GbE PHY speed and duplex modes; * Reset JAGCore; re-configure and initialize JAGCore and gigE PHY */ pAdapter->AiForceSpeed = pAdapter->PoMgmt.PowerDownSpeed; pAdapter->AiForceDpx = pAdapter->PoMgmt.PowerDownDuplex; /* Re-initialize the send structures */ et131x_init_send(pAdapter); /* Reset the RFD list and re-start RU */ et131x_reset_recv(pAdapter); /* Bring the device back to the state it was during init prior to * autonegotiation being complete. This way, when we get the auto-neg * complete interrupt, we can complete init by calling ConfigMacREGS2. */ et131x_soft_reset(pAdapter); /* setup et1310 as per the documentation ?? */ et131x_adapter_setup(pAdapter); /* Allow Tx to restart */ MP_CLEAR_FLAG(pAdapter, fMP_ADAPTER_LOWER_POWER); /* Need to re-enable Rx. */ et131x_rx_dma_enable(pAdapter); 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; /* 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; }
static int __devinit et131x_pci_setup(struct pci_dev *pdev, const struct pci_device_id *ent) { int result = -EBUSY; int pm_cap; bool pci_using_dac; struct net_device *netdev; struct et131x_adapter *adapter; /* Enable the device via the PCI subsystem */ if (pci_enable_device(pdev) != 0) { dev_err(&pdev->dev, "pci_enable_device() failed\n"); return -EIO; } /* Perform some basic PCI checks */ if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { dev_err(&pdev->dev, "Can't find PCI device's base address\n"); goto err_disable; } if (pci_request_regions(pdev, DRIVER_NAME)) { dev_err(&pdev->dev, "Can't get PCI resources\n"); goto err_disable; } /* Enable PCI bus mastering */ pci_set_master(pdev); /* Query PCI for Power Mgmt Capabilities * * NOTE: Now reading PowerMgmt in another location; is this still * needed? */ pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); if (pm_cap == 0) { dev_err(&pdev->dev, "Cannot find Power Management capabilities\n"); result = -EIO; goto err_release_res; } /* Check the DMA addressing support of this device */ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { pci_using_dac = true; result = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); if (result != 0) { dev_err(&pdev->dev, "Unable to obtain 64 bit DMA for consistent allocations\n"); goto err_release_res; } } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { pci_using_dac = false; } else { dev_err(&pdev->dev, "No usable DMA addressing method\n"); result = -EIO; goto err_release_res; } /* Allocate netdev and private adapter structs */ netdev = et131x_device_alloc(); if (netdev == NULL) { dev_err(&pdev->dev, "Couldn't alloc netdev struct\n"); result = -ENOMEM; goto err_release_res; } adapter = et131x_adapter_init(netdev, pdev); /* Initialise the PCI setup for the device */ et131x_pci_init(adapter, pdev); /* Map the bus-relative registers to system virtual memory */ adapter->regs = pci_ioremap_bar(pdev, 0); if (adapter->regs == NULL) { dev_err(&pdev->dev, "Cannot map device registers\n"); result = -ENOMEM; goto err_free_dev; } /* If Phy COMA mode was enabled when we went down, disable it here. */ writel(ET_PMCSR_INIT, &adapter->regs->global.pm_csr); /* Issue a global reset to the et1310 */ et131x_soft_reset(adapter); /* Disable all interrupts (paranoid) */ et131x_disable_interrupts(adapter); /* Allocate DMA memory */ result = et131x_adapter_memory_alloc(adapter); if (result != 0) { dev_err(&pdev->dev, "Could not alloc adapater memory (DMA)\n"); goto err_iounmap; } /* Init send data structures */ et131x_init_send(adapter); /* * Set up the task structure for the ISR's deferred handler */ INIT_WORK(&adapter->task, et131x_isr_handler); /* Copy address into the net_device struct */ memcpy(netdev->dev_addr, adapter->addr, ETH_ALEN); /* Setup et1310 as per the documentation */ et131x_adapter_setup(adapter); /* Create a timer to count errors received by the NIC */ init_timer(&adapter->ErrorTimer); adapter->ErrorTimer.expires = jiffies + TX_ERROR_PERIOD * HZ / 1000; adapter->ErrorTimer.function = et131x_error_timer_handler; adapter->ErrorTimer.data = (unsigned long)adapter; /* Initialize link state */ et131x_link_detection_handler((unsigned long)adapter); /* Initialize variable for counting how long we do not have link status */ adapter->boot_coma = 0; /* We can enable interrupts now * * NOTE - Because registration of interrupt handler is done in the * device's open(), defer enabling device interrupts to that * point */ /* Register the net_device struct with the Linux network layer */ result = register_netdev(netdev); if (result != 0) { dev_err(&pdev->dev, "register_netdev() failed\n"); goto err_mem_free; } /* Register the net_device struct with the PCI subsystem. Save a copy * of the PCI config space for this device now that the device has * been initialized, just in case it needs to be quickly restored. */ pci_set_drvdata(pdev, netdev); pci_save_state(adapter->pdev); return result; err_mem_free: et131x_adapter_memory_free(adapter); err_iounmap: iounmap(adapter->regs); err_free_dev: pci_dev_put(pdev); free_netdev(netdev); err_release_res: pci_release_regions(pdev); err_disable: pci_disable_device(pdev); return result; }
void et131x_Mii_check(struct et131x_adapter *etdev, MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints) { uint8_t link_status; uint32_t autoneg_status; uint32_t speed; uint32_t duplex; uint32_t mdi_mdix; uint32_t masterslave; uint32_t polarity; unsigned long flags; if (bmsr_ints.bits.link_status) { if (bmsr.bits.link_status) { etdev->PoMgmt.TransPhyComaModeOnBoot = 20; spin_lock_irqsave(&etdev->Lock, flags); etdev->MediaState = NETIF_STATUS_MEDIA_CONNECT; etdev->Flags &= ~fMP_ADAPTER_LINK_DETECTION; spin_unlock_irqrestore(&etdev->Lock, flags); if (etdev->RegistryPhyLoopbk == false) netif_carrier_on(etdev->netdev); } else { dev_warn(&etdev->pdev->dev, "Link down - cable problem ?\n"); if (etdev->linkspeed == TRUEPHY_SPEED_10MBPS) { uint16_t Register18; MiRead(etdev, 0x12, &Register18); MiWrite(etdev, 0x12, Register18 | 0x4); MiWrite(etdev, 0x10, Register18 | 0x8402); MiWrite(etdev, 0x11, Register18 | 511); MiWrite(etdev, 0x12, Register18); } if (!(etdev->Flags & fMP_ADAPTER_LINK_DETECTION) || (etdev->MediaState == NETIF_STATUS_MEDIA_DISCONNECT)) { spin_lock_irqsave(&etdev->Lock, flags); etdev->MediaState = NETIF_STATUS_MEDIA_DISCONNECT; spin_unlock_irqrestore(&etdev->Lock, flags); if (etdev->RegistryPhyLoopbk == false) netif_carrier_off(etdev->netdev); } etdev->linkspeed = 0; etdev->duplex_mode = 0; et131x_free_busy_send_packets(etdev); et131x_init_send(etdev); et131x_reset_recv(etdev); et131x_soft_reset(etdev); et131x_adapter_setup(etdev); if (etdev->RegistryPhyComa == 1) EnablePhyComa(etdev); } } if (bmsr_ints.bits.auto_neg_complete || (etdev->AiForceDpx == 3 && bmsr_ints.bits.link_status)) { if (bmsr.bits.auto_neg_complete || etdev->AiForceDpx == 3) { ET1310_PhyLinkStatus(etdev, &link_status, &autoneg_status, &speed, &duplex, &mdi_mdix, &masterslave, &polarity); etdev->linkspeed = speed; etdev->duplex_mode = duplex; etdev->PoMgmt.TransPhyComaModeOnBoot = 20; if (etdev->linkspeed == TRUEPHY_SPEED_10MBPS) { uint16_t Register18; MiRead(etdev, 0x12, &Register18); MiWrite(etdev, 0x12, Register18 | 0x4); MiWrite(etdev, 0x10, Register18 | 0x8402); MiWrite(etdev, 0x11, Register18 | 511); MiWrite(etdev, 0x12, Register18); } ConfigFlowControl(etdev); if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS && etdev->RegistryJumboPacket > 2048) ET1310_PhyAndOrReg(etdev, 0x16, 0xcfff, 0x2000); SetRxDmaTimer(etdev); ConfigMACRegs2(etdev); } } }
/** * 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; }
int __devinit et131x_pci_setup(struct pci_dev *pdev, const struct pci_device_id *ent) { int result = 0; int pm_cap; bool pci_using_dac; struct net_device *netdev = NULL; struct et131x_adapter *adapter = NULL; /* Enable the device via the PCI subsystem */ result = pci_enable_device(pdev); if (result != 0) { dev_err(&adapter->pdev->dev, "pci_enable_device() failed\n"); goto out; } /* Perform some basic PCI checks */ if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { dev_err(&adapter->pdev->dev, "Can't find PCI device's base address\n"); result = -ENODEV; goto out; } result = pci_request_regions(pdev, DRIVER_NAME); if (result != 0) { dev_err(&adapter->pdev->dev, "Can't get PCI resources\n"); goto err_disable; } /* Enable PCI bus mastering */ pci_set_master(pdev); /* Query PCI for Power Mgmt Capabilities * * NOTE: Now reading PowerMgmt in another location; is this still * needed? */ pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); if (pm_cap == 0) { dev_err(&adapter->pdev->dev, "Cannot find Power Management capabilities\n"); result = -EIO; goto err_release_res; } /* Check the DMA addressing support of this device */ if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) { pci_using_dac = true; result = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL); if (result != 0) { dev_err(&pdev->dev, "Unable to obtain 64 bit DMA for consistent allocations\n"); goto err_release_res; } } else if (!pci_set_dma_mask(pdev, 0xffffffffULL)) { pci_using_dac = false; } else { dev_err(&adapter->pdev->dev, "No usable DMA addressing method\n"); result = -EIO; goto err_release_res; } /* Allocate netdev and private adapter structs */ netdev = et131x_device_alloc(); if (netdev == NULL) { dev_err(&adapter->pdev->dev, "Couldn't alloc netdev struct\n"); result = -ENOMEM; goto err_release_res; } /* Setup the fundamental net_device and private adapter structure elements */ SET_NETDEV_DEV(netdev, &pdev->dev); /* if (pci_using_dac) { netdev->features |= NETIF_F_HIGHDMA; } */ /* * NOTE - Turn this on when we're ready to deal with SG-DMA * * NOTE: According to "Linux Device Drivers", 3rd ed, Rubini et al, * if checksumming is not performed in HW, then the kernel will not * use SG. * From pp 510-511: * * "Note that the kernel does not perform scatter/gather I/O to your * device if it does not also provide some form of checksumming as * well. The reason is that, if the kernel has to make a pass over a * fragmented ("nonlinear") packet to calculate the checksum, it * might as well copy the data and coalesce the packet at the same * time." * * This has been verified by setting the flags below and still not * receiving a scattered buffer from the network stack, so leave it * off until checksums are calculated in HW. */ /* netdev->features |= NETIF_F_SG; */ /* netdev->features |= NETIF_F_NO_CSUM; */ /* netdev->features |= NETIF_F_LLTX; */ /* Allocate private adapter struct and copy in relevant information */ adapter = netdev_priv(netdev); adapter->pdev = pci_dev_get(pdev); adapter->netdev = netdev; /* Do the same for the netdev struct */ netdev->irq = pdev->irq; netdev->base_addr = pdev->resource[0].start; /* Initialize spinlocks here */ spin_lock_init(&adapter->Lock); spin_lock_init(&adapter->TCBSendQLock); spin_lock_init(&adapter->TCBReadyQLock); spin_lock_init(&adapter->SendHWLock); spin_lock_init(&adapter->SendWaitLock); spin_lock_init(&adapter->RcvLock); spin_lock_init(&adapter->RcvPendLock); spin_lock_init(&adapter->FbrLock); spin_lock_init(&adapter->PHYLock); /* Parse configuration parameters into the private adapter struct */ et131x_config_parse(adapter); /* Find the physical adapter * * NOTE: This is the equivalent of the MpFindAdapter() routine; can we * lump it's init with the device specific init below into a * single init function? */ /* while (et131x_find_adapter(adapter, pdev) != 0); */ et131x_find_adapter(adapter, pdev); /* Map the bus-relative registers to system virtual memory */ adapter->regs = ioremap_nocache(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); if (adapter->regs == NULL) { dev_err(&pdev->dev, "Cannot map device registers\n"); result = -ENOMEM; goto err_free_dev; } /* Perform device-specific initialization here (See code below) */ /* If Phy COMA mode was enabled when we went down, disable it here. */ writel(ET_PMCSR_INIT, &adapter->regs->global.pm_csr); /* Issue a global reset to the et1310 */ et131x_soft_reset(adapter); /* Disable all interrupts (paranoid) */ et131x_disable_interrupts(adapter); /* Allocate DMA memory */ result = et131x_adapter_memory_alloc(adapter); if (result != 0) { dev_err(&pdev->dev, "Could not alloc adapater memory (DMA)\n"); goto err_iounmap; } /* Init send data structures */ et131x_init_send(adapter); /* Register the interrupt * * NOTE - This is being done in the open routine, where most other * Linux drivers setup IRQ handlers. Make sure device * interrupts are not turned on before the IRQ is registered!! * * What we will do here is setup the task structure for the * ISR's deferred handler */ INIT_WORK(&adapter->task, et131x_isr_handler); /* Determine MAC Address, and copy into the net_device struct */ et131x_setup_hardware_properties(adapter); memcpy(netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN); /* Setup et1310 as per the documentation */ et131x_adapter_setup(adapter); /* Create a timer to count errors received by the NIC */ init_timer(&adapter->ErrorTimer); adapter->ErrorTimer.expires = jiffies + TX_ERROR_PERIOD * HZ / 1000; adapter->ErrorTimer.function = et131x_error_timer_handler; adapter->ErrorTimer.data = (unsigned long)adapter; /* Initialize link state */ et131x_link_detection_handler((unsigned long)adapter); /* Intialize variable for counting how long we do not have link status */ adapter->PoMgmt.TransPhyComaModeOnBoot = 0; /* We can enable interrupts now * * NOTE - Because registration of interrupt handler is done in the * device's open(), defer enabling device interrupts to that * point */ /* Register the net_device struct with the Linux network layer */ result = register_netdev(netdev); if (result != 0) { dev_err(&pdev->dev, "register_netdev() failed\n"); goto err_mem_free; } /* Register the net_device struct with the PCI subsystem. Save a copy * of the PCI config space for this device now that the device has * been initialized, just in case it needs to be quickly restored. */ pci_set_drvdata(pdev, netdev); pci_save_state(adapter->pdev); out: return result; err_mem_free: et131x_adapter_memory_free(adapter); err_iounmap: iounmap(adapter->regs); err_free_dev: pci_dev_put(pdev); free_netdev(netdev); err_release_res: pci_release_regions(pdev); err_disable: pci_disable_device(pdev); goto out; }
void et131x_Mii_check(struct et131x_adapter *etdev, MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints) { uint8_t link_status; uint32_t autoneg_status; uint32_t speed; uint32_t duplex; uint32_t mdi_mdix; uint32_t masterslave; uint32_t polarity; unsigned long flags; if (bmsr_ints.bits.link_status) { if (bmsr.bits.link_status) { etdev->PoMgmt.TransPhyComaModeOnBoot = 20; /* Update our state variables and indicate the * connected state */ spin_lock_irqsave(&etdev->Lock, flags); etdev->MediaState = NETIF_STATUS_MEDIA_CONNECT; etdev->Flags &= ~fMP_ADAPTER_LINK_DETECTION; spin_unlock_irqrestore(&etdev->Lock, flags); /* Don't indicate state if we're in loopback mode */ if (etdev->RegistryPhyLoopbk == false) netif_carrier_on(etdev->netdev); } else { dev_warn(&etdev->pdev->dev, "Link down - cable problem ?\n"); if (etdev->linkspeed == TRUEPHY_SPEED_10MBPS) { /* NOTE - Is there a way to query this without * TruePHY? * && TRU_QueryCoreType(etdev->hTruePhy, 0) == EMI_TRUEPHY_A13O) { */ uint16_t Register18; MiRead(etdev, 0x12, &Register18); MiWrite(etdev, 0x12, Register18 | 0x4); MiWrite(etdev, 0x10, Register18 | 0x8402); MiWrite(etdev, 0x11, Register18 | 511); MiWrite(etdev, 0x12, Register18); } /* For the first N seconds of life, we are in "link * detection" When we are in this state, we should * only report "connected". When the LinkDetection * Timer expires, we can report disconnected (handled * in the LinkDetectionDPC). */ if (!(etdev->Flags & fMP_ADAPTER_LINK_DETECTION) || (etdev->MediaState == NETIF_STATUS_MEDIA_DISCONNECT)) { spin_lock_irqsave(&etdev->Lock, flags); etdev->MediaState = NETIF_STATUS_MEDIA_DISCONNECT; spin_unlock_irqrestore(&etdev->Lock, flags); /* Only indicate state if we're in loopback * mode */ if (etdev->RegistryPhyLoopbk == false) netif_carrier_off(etdev->netdev); } etdev->linkspeed = 0; etdev->duplex_mode = 0; /* Free the packets being actively sent & stopped */ et131x_free_busy_send_packets(etdev); /* Re-initialize the send structures */ et131x_init_send(etdev); /* Reset the RFD list and re-start RU */ et131x_reset_recv(etdev); /* * Bring the device back to the state it was during * init prior to autonegotiation being complete. This * way, when we get the auto-neg complete interrupt, * we can complete init by calling ConfigMacREGS2. */ et131x_soft_reset(etdev); /* Setup ET1310 as per the documentation */ et131x_adapter_setup(etdev); /* Setup the PHY into coma mode until the cable is * plugged back in */ if (etdev->RegistryPhyComa == 1) EnablePhyComa(etdev); } } if (bmsr_ints.bits.auto_neg_complete || (etdev->AiForceDpx == 3 && bmsr_ints.bits.link_status)) { if (bmsr.bits.auto_neg_complete || etdev->AiForceDpx == 3) { ET1310_PhyLinkStatus(etdev, &link_status, &autoneg_status, &speed, &duplex, &mdi_mdix, &masterslave, &polarity); etdev->linkspeed = speed; etdev->duplex_mode = duplex; etdev->PoMgmt.TransPhyComaModeOnBoot = 20; if (etdev->linkspeed == TRUEPHY_SPEED_10MBPS) { /* * NOTE - Is there a way to query this without * TruePHY? * && TRU_QueryCoreType(etdev->hTruePhy, 0)== EMI_TRUEPHY_A13O) { */ uint16_t Register18; MiRead(etdev, 0x12, &Register18); MiWrite(etdev, 0x12, Register18 | 0x4); MiWrite(etdev, 0x10, Register18 | 0x8402); MiWrite(etdev, 0x11, Register18 | 511); MiWrite(etdev, 0x12, Register18); } ConfigFlowControl(etdev); if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS && etdev->RegistryJumboPacket > 2048) ET1310_PhyAndOrReg(etdev, 0x16, 0xcfff, 0x2000); SetRxDmaTimer(etdev); ConfigMACRegs2(etdev); } } }