Beispiel #1
0
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;
}
Beispiel #3
0
/**
 * 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;
}
Beispiel #6
0
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);
		}
	}
}
Beispiel #7
0
/**
 * 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;
}
Beispiel #9
0
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);
		}
	}
}