diff options
Diffstat (limited to 'drivers/net/ethernet/xilinx/xilinx_emaclite.c')
| -rw-r--r-- | drivers/net/ethernet/xilinx/xilinx_emaclite.c | 110 | 
1 files changed, 33 insertions, 77 deletions
diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c index 4c619ea5189..8c4aed3053e 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c @@ -14,7 +14,6 @@  #include <linux/module.h>  #include <linux/uaccess.h> -#include <linux/init.h>  #include <linux/netdevice.h>  #include <linux/etherdevice.h>  #include <linux/skbuff.h> @@ -31,7 +30,7 @@  #define DRIVER_NAME "xilinx_emaclite"  /* Register offsets for the EmacLite Core */ -#define XEL_TXBUFF_OFFSET 	0x0		/* Transmit Buffer */ +#define XEL_TXBUFF_OFFSET	0x0		/* Transmit Buffer */  #define XEL_MDIOADDR_OFFSET	0x07E4		/* MDIO Address Register */  #define XEL_MDIOWR_OFFSET	0x07E8		/* MDIO Write Data Register */  #define XEL_MDIORD_OFFSET	0x07EC		/* MDIO Read Data Register */ @@ -63,13 +62,13 @@  #define XEL_MDIOCTRL_MDIOEN_MASK  0x00000008	/* MDIO Enable */  /* Global Interrupt Enable Register (GIER) Bit Masks */ -#define XEL_GIER_GIE_MASK	0x80000000 	/* Global Enable */ +#define XEL_GIER_GIE_MASK	0x80000000	/* Global Enable */  /* Transmit Status Register (TSR) Bit Masks */ -#define XEL_TSR_XMIT_BUSY_MASK	 0x00000001 	/* Tx complete */ -#define XEL_TSR_PROGRAM_MASK	 0x00000002 	/* Program the MAC address */ -#define XEL_TSR_XMIT_IE_MASK	 0x00000008 	/* Tx interrupt enable bit */ -#define XEL_TSR_XMIT_ACTIVE_MASK 0x80000000 	/* Buffer is active, SW bit +#define XEL_TSR_XMIT_BUSY_MASK	 0x00000001	/* Tx complete */ +#define XEL_TSR_PROGRAM_MASK	 0x00000002	/* Program the MAC address */ +#define XEL_TSR_XMIT_IE_MASK	 0x00000008	/* Tx interrupt enable bit */ +#define XEL_TSR_XMIT_ACTIVE_MASK 0x80000000	/* Buffer is active, SW bit  						 * only. This is not documented  						 * in the HW spec */ @@ -77,21 +76,21 @@  #define XEL_TSR_PROG_MAC_ADDR	(XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_PROGRAM_MASK)  /* Receive Status Register (RSR) */ -#define XEL_RSR_RECV_DONE_MASK	0x00000001 	/* Rx complete */ -#define XEL_RSR_RECV_IE_MASK	0x00000008 	/* Rx interrupt enable bit */ +#define XEL_RSR_RECV_DONE_MASK	0x00000001	/* Rx complete */ +#define XEL_RSR_RECV_IE_MASK	0x00000008	/* Rx interrupt enable bit */  /* Transmit Packet Length Register (TPLR) */ -#define XEL_TPLR_LENGTH_MASK	0x0000FFFF 	/* Tx packet length */ +#define XEL_TPLR_LENGTH_MASK	0x0000FFFF	/* Tx packet length */  /* Receive Packet Length Register (RPLR) */ -#define XEL_RPLR_LENGTH_MASK	0x0000FFFF 	/* Rx packet length */ +#define XEL_RPLR_LENGTH_MASK	0x0000FFFF	/* Rx packet length */ -#define XEL_HEADER_OFFSET	12 		/* Offset to length field */ -#define XEL_HEADER_SHIFT	16 		/* Shift value for length */ +#define XEL_HEADER_OFFSET	12		/* Offset to length field */ +#define XEL_HEADER_SHIFT	16		/* Shift value for length */  /* General Ethernet Definitions */ -#define XEL_ARP_PACKET_SIZE		28 	/* Max ARP packet size */ -#define XEL_HEADER_IP_LENGTH_OFFSET	16 	/* IP Length Offset */ +#define XEL_ARP_PACKET_SIZE		28	/* Max ARP packet size */ +#define XEL_HEADER_IP_LENGTH_OFFSET	16	/* IP Length Offset */ @@ -163,26 +162,9 @@ static void xemaclite_enable_interrupts(struct net_local *drvdata)  	__raw_writel(reg_data | XEL_TSR_XMIT_IE_MASK,  		     drvdata->base_addr + XEL_TSR_OFFSET); -	/* Enable the Tx interrupts for the second Buffer if -	 * configured in HW */ -	if (drvdata->tx_ping_pong != 0) { -		reg_data = __raw_readl(drvdata->base_addr + -				   XEL_BUFFER_OFFSET + XEL_TSR_OFFSET); -		__raw_writel(reg_data | XEL_TSR_XMIT_IE_MASK, -			     drvdata->base_addr + XEL_BUFFER_OFFSET + -			     XEL_TSR_OFFSET); -	} -  	/* Enable the Rx interrupts for the first buffer */  	__raw_writel(XEL_RSR_RECV_IE_MASK, drvdata->base_addr + XEL_RSR_OFFSET); -	/* Enable the Rx interrupts for the second Buffer if -	 * configured in HW */ -	if (drvdata->rx_ping_pong != 0) { -		__raw_writel(XEL_RSR_RECV_IE_MASK, drvdata->base_addr + -			     XEL_BUFFER_OFFSET + XEL_RSR_OFFSET); -	} -  	/* Enable the Global Interrupt Enable */  	__raw_writel(XEL_GIER_GIE_MASK, drvdata->base_addr + XEL_GIER_OFFSET);  } @@ -206,31 +188,10 @@ static void xemaclite_disable_interrupts(struct net_local *drvdata)  	__raw_writel(reg_data & (~XEL_TSR_XMIT_IE_MASK),  		     drvdata->base_addr + XEL_TSR_OFFSET); -	/* Disable the Tx interrupts for the second Buffer -	 * if configured in HW */ -	if (drvdata->tx_ping_pong != 0) { -		reg_data = __raw_readl(drvdata->base_addr + XEL_BUFFER_OFFSET + -				   XEL_TSR_OFFSET); -		__raw_writel(reg_data & (~XEL_TSR_XMIT_IE_MASK), -			     drvdata->base_addr + XEL_BUFFER_OFFSET + -			     XEL_TSR_OFFSET); -	} -  	/* Disable the Rx interrupts for the first buffer */  	reg_data = __raw_readl(drvdata->base_addr + XEL_RSR_OFFSET);  	__raw_writel(reg_data & (~XEL_RSR_RECV_IE_MASK),  		     drvdata->base_addr + XEL_RSR_OFFSET); - -	/* Disable the Rx interrupts for the second buffer -	 * if configured in HW */ -	if (drvdata->rx_ping_pong != 0) { - -		reg_data = __raw_readl(drvdata->base_addr + XEL_BUFFER_OFFSET + -				   XEL_RSR_OFFSET); -		__raw_writel(reg_data & (~XEL_RSR_RECV_IE_MASK), -			     drvdata->base_addr + XEL_BUFFER_OFFSET + -			     XEL_RSR_OFFSET); -	}  }  /** @@ -258,6 +219,13 @@ static void xemaclite_aligned_write(void *src_ptr, u32 *dest_ptr,  		*to_u16_ptr++ = *from_u16_ptr++;  		*to_u16_ptr++ = *from_u16_ptr++; +		/* This barrier resolves occasional issues seen around +		 * cases where the data is not properly flushed out +		 * from the processor store buffers to the destination +		 * memory locations. +		 */ +		wmb(); +  		/* Output a word */  		*to_u32_ptr++ = align_buffer;  	} @@ -273,6 +241,12 @@ static void xemaclite_aligned_write(void *src_ptr, u32 *dest_ptr,  		for (; length > 0; length--)  			*to_u8_ptr++ = *from_u8_ptr++; +		/* This barrier resolves occasional issues seen around +		 * cases where the data is not properly flushed out +		 * from the processor store buffers to the destination +		 * memory locations. +		 */ +		wmb();  		*to_u32_ptr = align_buffer;  	}  } @@ -728,7 +702,7 @@ static int xemaclite_mdio_wait(struct net_local *lp)  	*/  	while (__raw_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET) &  			XEL_MDIOCTRL_MDIOSTS_MASK) { -		if (end - jiffies <= 0) { +		if (time_before_eq(end, jiffies)) {  			WARN_ON(1);  			return -ETIMEDOUT;  		} @@ -821,18 +795,6 @@ static int xemaclite_mdio_write(struct mii_bus *bus, int phy_id, int reg,  }  /** - * xemaclite_mdio_reset - Reset the mdio bus. - * @bus:	Pointer to the MII bus - * - * This function is required(?) as per Documentation/networking/phy.txt. - * There is no reset in this device; this function always returns 0. - */ -static int xemaclite_mdio_reset(struct mii_bus *bus) -{ -	return 0; -} - -/**   * xemaclite_mdio_setup - Register mii_bus for the Emaclite device   * @lp:		Pointer to the Emaclite device private data   * @ofdev:	Pointer to OF device structure @@ -887,7 +849,6 @@ static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev)  	bus->name = "Xilinx Emaclite MDIO";  	bus->read = xemaclite_mdio_read;  	bus->write = xemaclite_mdio_write; -	bus->reset = xemaclite_mdio_reset;  	bus->parent = dev;  	bus->irq = lp->mdio_irqs; /* preallocated IRQ table */ @@ -1063,7 +1024,7 @@ static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev)  	skb_tx_timestamp(new_skb);  	dev->stats.tx_bytes += len; -	dev_kfree_skb(new_skb); +	dev_consume_skb_any(new_skb);  	return 0;  } @@ -1075,14 +1036,9 @@ static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev)   * This function un maps the IO region of the Emaclite device and frees the net   * device.   */ -static void xemaclite_remove_ndev(struct net_device *ndev, -				  struct platform_device *pdev) +static void xemaclite_remove_ndev(struct net_device *ndev)  {  	if (ndev) { -		struct net_local *lp = netdev_priv(ndev); - -		if (lp->base_addr) -			devm_iounmap(&pdev->dev, lp->base_addr);  		free_netdev(ndev);  	}  } @@ -1177,7 +1133,7 @@ static int xemaclite_of_probe(struct platform_device *ofdev)  	if (mac_address)  		/* Set the MAC address. */ -		memcpy(ndev->dev_addr, mac_address, 6); +		memcpy(ndev->dev_addr, mac_address, ETH_ALEN);  	else  		dev_warn(dev, "No MAC address found\n"); @@ -1214,7 +1170,7 @@ static int xemaclite_of_probe(struct platform_device *ofdev)  	return 0;  error: -	xemaclite_remove_ndev(ndev, ofdev); +	xemaclite_remove_ndev(ndev);  	return rc;  } @@ -1248,7 +1204,7 @@ static int xemaclite_of_remove(struct platform_device *of_dev)  		of_node_put(lp->phy_node);  	lp->phy_node = NULL; -	xemaclite_remove_ndev(ndev, of_dev); +	xemaclite_remove_ndev(ndev);  	return 0;  }  | 
