* Re: Re[2]: [PATCH] netfilter: ipvs: Verify that IP_VS protocol has been registered
From: Sasha Levin @ 2012-04-06 9:22 UTC (permalink / raw)
To: Hans Schillstrom
Cc: Simon Horman, wensong, ja, kaber, davem, davej, netdev, lvs-devel,
netfilter-devel, linux-kernel
In-Reply-To: <6dfqp4f.85748eeb029b04c66ac5e143b62a5455@obelix.schillstrom.com>
On Fri, Apr 6, 2012 at 10:59 AM, Hans Schillstrom <hans@schillstrom.com> wrote:
> Hello Simon
>
>>---- Original Message ----
>>From: Simon Horman <horms@verge.net.au>
>>To: "Sasha Levin" <levinsasha928@gmail.com>
>>Cc: wensong@linux-vs.org, ja@ssi.bg, kaber@trash.net, davem@davemloft.net, davej@redhat.com, netdev@vger.kernel.org, lvs-devel@vger.kernel.org, netfilter-devel@vger.kernel.org, linux-kernel@vger.kernel.org
>>Sent: Fri, Apr 6, 2012, 1:19 AM
>>Subject: Re: [PATCH] netfilter: ipvs: Verify that IP_VS protocol has been registered
>>
>>On Thu, Apr 05, 2012 at 07:24:33PM -0400, Sasha Levin wrote:
>>> The registration of a protocol might fail, there were no checks
>>> and all registrations were assumed to be correct. This lead to
>>> NULL ptr dereferences when apps tried registering.
>>
>>Thanks, I will queue up this fix.
>>
>>Do you have a real-world example of this failing, if so it
>>might be worth pushing your change into stable.
>
> I don't think this is a big thing, the only thing that can cause it is out of memory,
> and that will cause a "kernel death" anyway :-(
>
> here is the code :
>
> register_ip_vs_proto_netns(struct net *net, struct ip_vs_protocol *pp)
> {
> ...
> struct ip_vs_proto_data *pd =
> kzalloc(sizeof(struct ip_vs_proto_data), GFP_ATOMIC);
>
> if (!pd)
> return -ENOMEM;
>
>
Considering that the allocation gfp flag here is GFP_ATOMIC (why is it
GFP_ATOMIC btw?), it might fail for a variety of reasons which may
occur when the system is "healthy", for example - if it needs disk I/O
to allocate.
Either way, you shouldn't be dereferencing NULL ptrs even when the
system is really low on memory.
^ permalink raw reply
* [net-next 0/4 (V3)] stmmac & EEE support
From: Giuseppe CAVALLARO @ 2012-04-06 9:29 UTC (permalink / raw)
To: netdev; +Cc: bhutchings, rayagond, davem, Giuseppe Cavallaro
These patches add the EEE support in the stmmac device driver.
I've tested it on ST STB with the IC+ 101G PHY device that has
this feature.
Initially the EEE for the stmmac has been written by Rayagond
but I reworked all his code adding new parts and especially
performing tests on a real hardware. Thx Rayagond!
In these patches, we can see that the stmmac supports the EEE
only if the DMA HW capability register says that this
feature is actually available. In that case, the driver can enter
in the Tx LPI mode by using a timer as recommended by Synopsys.
Note that EEE is supported in new chip generations; in particular
I used the 3.61a.
At any rate, further information about how the driver treats the EEE
can be found in the stmmac.txt file (there is a patch for that).
These patches also add a new option for ethtool to enable/disable
the EEE. There is a patch for the ethtool user space application;
I'm sending it too.
Another patch is for Physical Abstraction Layer now able to
manage the MMD registers (clause 45).
Maybe, I could directly add the EEE in the mdio driver.
I didn't that because I wanted to keep the stmmac able to access
to the phy registers through the Physical Abstraction Layer and
w/ having any links to the mdio.o.
Please Ben tells me if I well applied all your advice (when you
reviewed the ethtool/phy patches).
Regards
Peppe
Giuseppe CAVALLARO (1):
stmmac: update the driver Documentation and add EEE
Giuseppe Cavallaro (3):
net: ethtool: add the EEE support
phy: add the EEE support and the way to access to the MMD regs
stmmac: add the Energy Efficient Ethernet support
Documentation/networking/stmmac.txt | 36 ++++-
drivers/net/ethernet/stmicro/stmmac/common.h | 27 ++++-
drivers/net/ethernet/stmicro/stmmac/dwmac1000.h | 20 +++
.../net/ethernet/stmicro/stmmac/dwmac1000_core.c | 101 ++++++++++++-
.../net/ethernet/stmicro/stmmac/dwmac100_core.c | 4 +-
drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h | 1 +
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 6 +
.../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 48 ++++++
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 156 +++++++++++++++++++-
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 2 +
drivers/net/phy/phy_device.c | 138 +++++++++++++++++
include/linux/ethtool.h | 6 +
include/linux/mdio.h | 6 +-
include/linux/mii.h | 11 ++
include/linux/phy.h | 3 +
net/core/ethtool.c | 32 ++++
16 files changed, 572 insertions(+), 25 deletions(-)
--
1.7.4.4
^ permalink raw reply
* [net-next 2/4 (V3)] phy: add the EEE support and the way to access to the MMD regs
From: Giuseppe CAVALLARO @ 2012-04-06 9:29 UTC (permalink / raw)
To: netdev; +Cc: bhutchings, rayagond, davem, Giuseppe Cavallaro
In-Reply-To: <1333704559-11251-1-git-send-email-peppe.cavallaro@st.com>
This patch adds the initial support for the Energy-Efficient
Ethernet (EEE). It has been tested on IC+101G device on ST STB.
To support the EEE we have to access to the MMD registers 3.20 and
3.60/61. So I added two new functions to read/write the MMD
registers (clause 45)
The upper-layer will invoke the phy_check_eee to properly check
if the EEE is supported by the PHYs.
The phy_get_eee_err reports the number of time where the PHY
failed to complete its normal wake sequence.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Reviewed-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/phy/phy_device.c | 138 ++++++++++++++++++++++++++++++++++++++++++
include/linux/mdio.h | 6 ++-
include/linux/mii.h | 11 +++
include/linux/phy.h | 3 +
4 files changed, 157 insertions(+), 1 deletions(-)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index e8c42d6..4231baa 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -30,6 +30,7 @@
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/phy.h>
+#include <linux/mdio.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -898,6 +899,143 @@ int genphy_resume(struct phy_device *phydev)
}
EXPORT_SYMBOL(genphy_resume);
+static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
+ int addr)
+{
+ /* Write the desired MMD Devad */
+ bus->write(bus, addr, MII_MMD_CTRL, devad);
+
+ /* Write the desired MMD register address */
+ bus->write(bus, addr, MII_MMD_DATA, prtad);
+
+ /* Select the Function : DATA with no post increment */
+ bus->write(bus, addr, MII_MMD_CTRL,
+ (devad | MII_MMD_CTRL_FUNC_DATA_NOINCR));
+}
+
+/**
+ * phy_read_mmd_indirect - reads data from the MMC register (clause 22 to
+ * access to clause 45)
+ * @bus: the target MII bus
+ * @prtad: MMD Address
+ * @devad: MMD DEVAD
+ * @addr: PHY address on the MII bus
+ *
+ * Description: Reads data from the MMD regisetrs of the
+ * phy addr. To read these register we have:
+ * 1) Write reg 13 // DEVAD
+ * 2) Write reg 14 // MMD Address
+ * 3) Write reg 13 // MMD Data Command for MMD DEVAD
+ * 3) Read reg 14 // Read MMD data
+ */
+static int phy_read_mmd_indirect(struct mii_bus *bus, int prtad, int devad,
+ int addr)
+{
+ u32 ret;
+
+ mmd_phy_indirect(bus, prtad, devad, addr);
+
+ /* Read the content of the MMD's selected register */
+ ret = bus->read(bus, addr, MII_MMD_DATA);
+ if (ret < 0)
+ return -EIO;
+
+ return ret;
+}
+
+/**
+ * phy_write_mmd_indirect - writes data to the MMC register (clause 22 to
+ * access to clause 45)
+ * @bus: the target MII bus
+ * @prtad: MMD Address
+ * @devad: MMD DEVAD
+ * @addr: PHY address on the MII bus
+ * @data: data to write in the MMD register
+ *
+ * Description: Reads data from the MMD regisetrs of the
+ * phy addr. To read these register we have:
+ * 1) Write reg 13 // DEVAD
+ * 2) Write reg 14 // MMD Address
+ * 3) Write reg 13 // MMD Data Command for MMD DEVAD
+ * 3) Write reg 14 // Write MMD data
+ */
+static void phy_write_mmd_indirect(struct mii_bus *bus, int prtad, int devad,
+ int addr, u32 data)
+{
+ mmd_phy_indirect(bus, prtad, devad, addr);
+
+ /* Write the data into MMD's selected register */
+ bus->write(bus, addr, MII_MMD_DATA, data);
+}
+
+/* phy_check_eee
+ * @dev: device to probe and init
+ *
+ * Description: check if the Energy-Efficient Ethernet (EEE)
+ * is supported by looking at the MMD registers 3.20 and 3.60/61
+ */
+int phy_check_eee(struct phy_device *phydev)
+{
+ int ret = -EPROTONOSUPPORT;
+
+ /* According to 802.3az,the EEE is supported only in full duplex-mode.
+ * Also EEE feature is active when core is operating with MII, GMII
+ * or RGMII */
+ if ((phydev->duplex == DUPLEX_FULL) &&
+ ((phydev->interface == PHY_INTERFACE_MODE_MII) ||
+ (phydev->interface == PHY_INTERFACE_MODE_GMII) ||
+ (phydev->interface == PHY_INTERFACE_MODE_RGMII))) {
+ int eee_cap, eee_link;
+
+ /* EEE ability must be supported in both local and remote
+ * PHY devices. */
+ eee_cap = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_LPABLE,
+ MDIO_MMD_AN, phydev->addr);
+ if (eee_cap < 0)
+ return eee_cap;
+
+ eee_link = phy_read_mmd_indirect(phydev->bus, MDIO_PCS_EEE_ABLE,
+ MDIO_MMD_PCS, phydev->addr);
+ if (eee_link < 0)
+ return eee_link;
+
+ if (eee_cap && eee_link) {
+ /* Configure the PHY to stop receiving xMII clock
+ * while it is signaling LPI */
+ int pcs_ctrl = phy_read_mmd_indirect(phydev->bus,
+ MDIO_CTRL1,
+ MDIO_MMD_PCS,
+ phydev->addr);
+ if (pcs_ctrl < 0)
+ return pcs_ctrl;
+
+ pcs_ctrl |= MDIO_PCS_CTRL1_CLKSTOP_EN;
+ phy_write_mmd_indirect(phydev->bus, MDIO_CTRL1,
+ MDIO_MMD_PCS,
+ phydev->addr, pcs_ctrl);
+
+ ret = 0; /* EEE supported */
+ }
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(phy_get_eee_err);
+
+/* phy_get_eee_err
+ * @dev: device to probe and init
+ *
+ * Description: it is to report the number of time where the PHY
+ * failed to complete its normal wake sequence.
+ */
+int phy_get_eee_err(struct phy_device *phydev)
+{
+ return phy_read_mmd_indirect(phydev->bus, MDIO_PCS_EEE_WK_ERR,
+ MDIO_MMD_PCS, phydev->addr);
+
+}
+EXPORT_SYMBOL(phy_check_eee);
+
/**
* phy_probe - probe and init a PHY device
* @dev: device to probe and init
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index dfb9479..49c9a13 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -43,7 +43,11 @@
#define MDIO_PKGID2 15
#define MDIO_AN_ADVERTISE 16 /* AN advertising (base page) */
#define MDIO_AN_LPA 19 /* AN LP abilities (base page) */
+#define MDIO_PCS_EEE_ABLE 20 /* EEE Capability register */
+#define MDIO_PCS_EEE_WK_ERR 22 /* EEE wake error counter */
#define MDIO_PHYXS_LNSTAT 24 /* PHY XGXS lane state */
+#define MDIO_AN_EEE_ADV 60 /* EEE advertisement */
+#define MDIO_AN_EEE_LPABLE 61 /* EEE link partner ability */
/* Media-dependent registers. */
#define MDIO_PMA_10GBT_SWAPPOL 130 /* 10GBASE-T pair swap & polarity */
@@ -56,7 +60,6 @@
#define MDIO_PCS_10GBRT_STAT2 33 /* 10GBASE-R/-T PCS status 2 */
#define MDIO_AN_10GBT_CTRL 32 /* 10GBASE-T auto-negotiation control */
#define MDIO_AN_10GBT_STAT 33 /* 10GBASE-T auto-negotiation status */
-#define MDIO_AN_EEE_ADV 60 /* EEE advertisement */
/* LASI (Link Alarm Status Interrupt) registers, defined by XENPAK MSA. */
#define MDIO_PMA_LASI_RXCTRL 0x9000 /* RX_ALARM control */
@@ -82,6 +85,7 @@
#define MDIO_AN_CTRL1_RESTART BMCR_ANRESTART
#define MDIO_AN_CTRL1_ENABLE BMCR_ANENABLE
#define MDIO_AN_CTRL1_XNP 0x2000 /* Enable extended next page */
+#define MDIO_PCS_CTRL1_CLKSTOP_EN 0x400 /* Stop the clock during LPI */
/* 10 Gb/s */
#define MDIO_CTRL1_SPEED10G (MDIO_CTRL1_SPEEDSELEXT | 0x00)
diff --git a/include/linux/mii.h b/include/linux/mii.h
index 2783eca..35ddda1 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -21,6 +21,8 @@
#define MII_EXPANSION 0x06 /* Expansion register */
#define MII_CTRL1000 0x09 /* 1000BASE-T control */
#define MII_STAT1000 0x0a /* 1000BASE-T status */
+#define MII_MMD_CTRL 0x0d /* MMD Access Control Register */
+#define MII_MMD_DATA 0x0e /* MMD Access Data Register */
#define MII_ESTATUS 0x0f /* Extended Status */
#define MII_DCOUNTER 0x12 /* Disconnect counter */
#define MII_FCSCOUNTER 0x13 /* False carrier counter */
@@ -141,6 +143,15 @@
#define FLOW_CTRL_TX 0x01
#define FLOW_CTRL_RX 0x02
+/* MMD Access Control register fields */
+#define MII_MMD_CTRL_DEVAD_MASK 0x1f /* Mask MMD DEVAD*/
+#define MII_MMD_CTRL_FUNC_ADDR 0x0000 /* Address */
+#define MII_MMD_CTRL_FUNC_DATA_NOINCR 0x4000 /* no post increment */
+#define MII_MMD_CTRL_FUNC_DATA_INCR_ON_RDWT 0x8000 /* post increment on
+ * reads & writes */
+#define MII_MMD_CTRL_FUNC_DATA_INCR_ON_WT 0xC000 /* post increment on
+ * writes only */
+
/* This structure is used in all SIOCxMIIxxx ioctl calls */
struct mii_ioctl_data {
__u16 phy_id;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index f092032..a5d7d0d 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -533,6 +533,9 @@ int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask,
int (*run)(struct phy_device *));
int phy_scan_fixups(struct phy_device *phydev);
+int phy_check_eee(struct phy_device *phydev);
+int phy_get_eee_err(struct phy_device *phydev);
+
int __init mdio_bus_init(void);
void mdio_bus_exit(void);
--
1.7.4.4
^ permalink raw reply related
* [net-next 1/4 (V3)] net: ethtool: add the EEE support
From: Giuseppe CAVALLARO @ 2012-04-06 9:29 UTC (permalink / raw)
To: netdev; +Cc: bhutchings, rayagond, davem, Giuseppe Cavallaro
In-Reply-To: <1333704559-11251-1-git-send-email-peppe.cavallaro@st.com>
This patch adds two new functions to detect if Energy-Efficient
Ethernet (EEE) is supported and the way to enable/disable it.
As Ben said, it is certainly necessary to distinguish:
a. PHY is advertising EEE from
b. Link partner is advertising EEE
or
c. EEE will be used (= a && b)
The logic behind this code, is that .get_eee will pass
to the user-space if the EEE is actually used and available (so point c).
The .set_eee should used to force the MAC to disable/enable the EEE (if
actually supported by MAC+PHY).
I have also added the .set_eee because the Synopsys GMAC manages the TX LPI
path through a SW timer that in this case can be disabled via ethtool.
Indeed, no action should be taken by the user for the PHY side.
Maybe, the only thing that could be changed is the clock stop enable bit
(3.0.10).
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Reviewed-by: Ben Hutchings <bhutchings@solarflare.com>
---
include/linux/ethtool.h | 6 ++++++
net/core/ethtool.c | 32 ++++++++++++++++++++++++++++++++
2 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 560a247..d0150c8 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -920,6 +920,8 @@ static inline u32 ethtool_rxfh_indir_default(u32 index, u32 n_rx_rings)
* @get_ts_info: Get the time stamping and PTP hardware clock capabilities.
* Drivers supporting transmit time stamps in software should set this to
* ethtool_op_get_ts_info().
+ * @get_eee: Get Energy-Efficient Ethernet (EEE) supported and status.
+ * @set_eee: Set EEE status (enable/disable).
*
* All operations are optional (i.e. the function pointer may be set
* to %NULL) and callers must take this into account. Callers must
@@ -984,6 +986,8 @@ struct ethtool_ops {
int (*set_dump)(struct net_device *, struct ethtool_dump *);
int (*get_ts_info)(struct net_device *, struct ethtool_ts_info *);
+ int (*get_eee) (struct net_device *, struct ethtool_value *);
+ int (*set_eee) (struct net_device *, struct ethtool_value *);
};
#endif /* __KERNEL__ */
@@ -1058,6 +1062,8 @@ struct ethtool_ops {
#define ETHTOOL_GET_DUMP_FLAG 0x0000003f /* Get dump settings */
#define ETHTOOL_GET_DUMP_DATA 0x00000040 /* Get dump data */
#define ETHTOOL_GET_TS_INFO 0x00000041 /* Get time stamping and PHC info */
+#define ETHTOOL_GEEE 0x00000042 /* Get EEE */
+#define ETHTOOL_SEEE 0x00000043 /* Set EEE */
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index beacdd9..c2374f9 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -729,6 +729,32 @@ static int ethtool_set_wol(struct net_device *dev, char __user *useraddr)
return dev->ethtool_ops->set_wol(dev, &wol);
}
+static int ethtool_get_eee(struct net_device *dev, char __user *useraddr)
+{
+ struct ethtool_value edata;
+
+ if (!dev->ethtool_ops->get_eee)
+ return -EOPNOTSUPP;
+
+ dev->ethtool_ops->get_eee(dev, &edata);
+
+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
+ return -EFAULT;
+ return 0;
+}
+
+static int ethtool_set_eee(struct net_device *dev, char __user *useraddr)
+{
+ struct ethtool_value edata;
+
+ if (!dev->ethtool_ops->set_eee)
+ return -EOPNOTSUPP;
+
+ if (copy_from_user(&edata, useraddr, sizeof(edata)))
+ return -EFAULT;
+
+ return dev->ethtool_ops->set_eee(dev, &edata);
+}
static int ethtool_nway_reset(struct net_device *dev)
{
if (!dev->ethtool_ops->nway_reset)
@@ -1420,6 +1446,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
rc = ethtool_set_value_void(dev, useraddr,
dev->ethtool_ops->set_msglevel);
break;
+ case ETHTOOL_GEEE:
+ rc = ethtool_get_eee(dev, useraddr);
+ break;
+ case ETHTOOL_SEEE:
+ rc = ethtool_set_eee(dev, useraddr);
+ break;
case ETHTOOL_NWAY_RST:
rc = ethtool_nway_reset(dev);
break;
--
1.7.4.4
^ permalink raw reply related
* [net-next 3/4 (V3)] stmmac: add the Energy Efficient Ethernet support
From: Giuseppe CAVALLARO @ 2012-04-06 9:29 UTC (permalink / raw)
To: netdev; +Cc: bhutchings, rayagond, davem, Giuseppe Cavallaro
In-Reply-To: <1333704559-11251-1-git-send-email-peppe.cavallaro@st.com>
This patch adds the Energy Efficient Ethernet support.
Please see the driver's documentation for further
information about this support in the driver.
Signed-off-by: Rayagond Kokatanur <rayagond@vayavyalabs.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/common.h | 27 ++++-
drivers/net/ethernet/stmicro/stmmac/dwmac1000.h | 20 +++
.../net/ethernet/stmicro/stmmac/dwmac1000_core.c | 101 ++++++++++++-
.../net/ethernet/stmicro/stmmac/dwmac100_core.c | 4 +-
drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h | 1 +
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 6 +
.../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 48 ++++++
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 156 +++++++++++++++++++-
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 2 +
9 files changed, 347 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 9e42b5d..fbeaed3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -95,6 +95,16 @@ struct stmmac_extra_stats {
unsigned long poll_n;
unsigned long sched_timer_n;
unsigned long normal_irq_n;
+ unsigned long mmc_tx_irq_n;
+ unsigned long mmc_rx_irq_n;
+ unsigned long mmc_rx_csum_offload_irq_n;
+ /* EEE */
+ unsigned long irq_receive_pmt_irq_n;
+ unsigned long irq_tx_path_in_lpi_mode_n;
+ unsigned long irq_tx_path_exit_lpi_mode_n;
+ unsigned long irq_rx_path_in_lpi_mode_n;
+ unsigned long irq_rx_path_exit_lpi_mode_n;
+ unsigned long phy_eee_wakeup_error_n;
};
/* CSR Frequency Access Defines*/
@@ -161,6 +171,17 @@ enum tx_dma_irq_status {
handle_tx_rx = 3,
};
+enum core_specific_irq_mask {
+ core_mmc_tx_irq = 1,
+ core_mmc_rx_irq = 2,
+ core_mmc_rx_csum_offload_irq = 4,
+ core_irq_receive_pmt_irq = 8,
+ core_irq_tx_path_in_lpi_mode = 16,
+ core_irq_tx_path_exit_lpi_mode = 32,
+ core_irq_rx_path_in_lpi_mode = 64,
+ core_irq_rx_path_exit_lpi_mode = 128,
+};
+
/* DMA HW capabilities */
struct dma_features {
unsigned int mbps_10_100;
@@ -277,7 +298,7 @@ struct stmmac_ops {
/* Dump MAC registers */
void (*dump_regs) (void __iomem *ioaddr);
/* Handle extra events on specific interrupts hw dependent */
- void (*host_irq_status) (void __iomem *ioaddr);
+ int (*host_irq_status) (void __iomem *ioaddr);
/* Multicast filter setting */
void (*set_filter) (struct net_device *dev);
/* Flow control setting */
@@ -290,6 +311,10 @@ struct stmmac_ops {
unsigned int reg_n);
void (*get_umac_addr) (void __iomem *ioaddr, unsigned char *addr,
unsigned int reg_n);
+ void (*set_eee_mode) (void __iomem *ioaddr);
+ void (*reset_eee_mode) (void __iomem *ioaddr);
+ void (*set_eee_timer) (void __iomem *ioaddr, int ls, int tw);
+ void (*set_eee_pls) (void __iomem *ioaddr, int link);
};
struct mac_link {
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
index 54339a7..3e4265d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
@@ -36,6 +36,7 @@
#define GMAC_INT_STATUS 0x00000038 /* interrupt status register */
enum dwmac1000_irq_status {
+ lpiis_irq = 0x400,
time_stamp_irq = 0x0200,
mmc_rx_csum_offload_irq = 0x0080,
mmc_tx_irq = 0x0040,
@@ -60,6 +61,25 @@ enum power_event {
power_down = 0x00000001,
};
+/* Energy Efficient Ethernet (EEE)
+ *
+ * LPI status, timer and control register offset
+ */
+#define LPI_CTRL_STATUS 0x0030
+#define LPI_TIMER_CTRL 0x0034
+
+/* LPI control and status defines */
+#define LPI_CTRL_STATUS_LPITXA 0x00080000 /* Enable LPI TX Automate */
+#define LPI_CTRL_STATUS_PLSEN 0x00040000 /* Enable PHY Link Status */
+#define LPI_CTRL_STATUS_PLS 0x00020000 /* PHY Link Status */
+#define LPI_CTRL_STATUS_LPIEN 0x00010000 /* LPI Enable */
+#define LPI_CTRL_STATUS_RLPIST 0x00000200 /* Receive LPI state */
+#define LPI_CTRL_STATUS_TLPIST 0x00000100 /* Transmit LPI state */
+#define LPI_CTRL_STATUS_RLPIEX 0x00000008 /* Receive LPI Exit */
+#define LPI_CTRL_STATUS_RLPIEN 0x00000004 /* Receive LPI Entry */
+#define LPI_CTRL_STATUS_TLPIEX 0x00000002 /* Transmit LPI Exit */
+#define LPI_CTRL_STATUS_TLPIEN 0x00000001 /* Transmit LPI Entry */
+
/* GMAC HW ADDR regs */
#define GMAC_ADDR_HIGH(reg) (0x00000040+(reg * 8))
#define GMAC_ADDR_LOW(reg) (0x00000044+(reg * 8))
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
index e7cbcd9..1b3a344 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -187,26 +187,107 @@ static void dwmac1000_pmt(void __iomem *ioaddr, unsigned long mode)
}
-static void dwmac1000_irq_status(void __iomem *ioaddr)
+static int dwmac1000_irq_status(void __iomem *ioaddr)
{
u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
+ int status = 0;
/* Not used events (e.g. MMC interrupts) are not handled. */
- if ((intr_status & mmc_tx_irq))
- CHIP_DBG(KERN_DEBUG "GMAC: MMC tx interrupt: 0x%08x\n",
+ if ((intr_status & mmc_tx_irq)) {
+ CHIP_DBG(KERN_INFO "GMAC: MMC tx interrupt: 0x%08x\n",
readl(ioaddr + GMAC_MMC_TX_INTR));
- if (unlikely(intr_status & mmc_rx_irq))
- CHIP_DBG(KERN_DEBUG "GMAC: MMC rx interrupt: 0x%08x\n",
+ status |= core_mmc_tx_irq;
+ }
+ if (unlikely(intr_status & mmc_rx_irq)) {
+ CHIP_DBG(KERN_INFO "GMAC: MMC rx interrupt: 0x%08x\n",
readl(ioaddr + GMAC_MMC_RX_INTR));
- if (unlikely(intr_status & mmc_rx_csum_offload_irq))
- CHIP_DBG(KERN_DEBUG "GMAC: MMC rx csum offload: 0x%08x\n",
+ status |= core_mmc_rx_irq;
+ }
+ if (unlikely(intr_status & mmc_rx_csum_offload_irq)) {
+ CHIP_DBG(KERN_INFO "GMAC: MMC rx csum offload: 0x%08x\n",
readl(ioaddr + GMAC_MMC_RX_CSUM_OFFLOAD));
+ status |= core_mmc_rx_csum_offload_irq;
+ }
if (unlikely(intr_status & pmt_irq)) {
- CHIP_DBG(KERN_DEBUG "GMAC: received Magic frame\n");
+ CHIP_DBG(KERN_INFO "GMAC: received Magic frame\n");
/* clear the PMT bits 5 and 6 by reading the PMT
* status register. */
readl(ioaddr + GMAC_PMT);
+ status |= core_irq_receive_pmt_irq;
}
+ /* MAC trx/rx EEE LPI entry/exit interrupts */
+ if (intr_status & lpiis_irq) {
+ /* Clean LPI interrupt by reading the Reg 12 */
+ u32 lpi_status = readl(ioaddr + LPI_CTRL_STATUS);
+
+ if (lpi_status & LPI_CTRL_STATUS_TLPIEN) {
+ CHIP_DBG(KERN_INFO "GMAC TX entered in LPI\n");
+ status |= core_irq_tx_path_in_lpi_mode;
+ }
+ if (lpi_status & LPI_CTRL_STATUS_TLPIEX) {
+ CHIP_DBG(KERN_INFO "GMAC TX exit from LPI\n");
+ status |= core_irq_tx_path_exit_lpi_mode;
+ }
+ if (lpi_status & LPI_CTRL_STATUS_RLPIEN) {
+ CHIP_DBG(KERN_INFO "GMAC RX entered in LPI\n");
+ status |= core_irq_rx_path_in_lpi_mode;
+ }
+ if (lpi_status & LPI_CTRL_STATUS_RLPIEX) {
+ CHIP_DBG(KERN_INFO "GMAC RX exit from LPI\n");
+ status |= core_irq_rx_path_exit_lpi_mode;
+ }
+ }
+
+ return status;
+}
+
+static void dwmac1000_set_eee_mode(void __iomem *ioaddr)
+{
+ u32 value;
+
+ /* Enable the link status receive on RGMII, SGMII ore SMII
+ * receive path and instruct the transmit to enter in LPI
+ * state. */
+ value = readl(ioaddr + LPI_CTRL_STATUS);
+ value |= LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA;
+ writel(value, ioaddr + LPI_CTRL_STATUS);
+}
+
+static void dwmac1000_reset_eee_mode(void __iomem *ioaddr)
+{
+ u32 value;
+
+ value = readl(ioaddr + LPI_CTRL_STATUS);
+ value &= ~(LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA);
+ writel(value, ioaddr + LPI_CTRL_STATUS);
+}
+
+static void dwmac1000_set_eee_pls(void __iomem *ioaddr, int link)
+{
+ u32 value;
+
+ value = readl(ioaddr + LPI_CTRL_STATUS);
+
+ if (link)
+ value |= LPI_CTRL_STATUS_PLS;
+ else
+ value &= ~LPI_CTRL_STATUS_PLS;
+
+ writel(value, ioaddr + LPI_CTRL_STATUS);
+}
+
+static void dwmac1000_set_eee_timer(void __iomem *ioaddr, int ls, int tw)
+{
+ int value = ((tw & 0xffff)) | ((ls & 0x7ff) << 16);
+
+ /* Program the timers in the LPI timer control register:
+ * LS: minimum time (ms) for which the link
+ * status from PHY should be ok before transmitting
+ * the LPI pattern.
+ * TW: minimum time (us) for which the core waits
+ * after it has stopped transmitting the LPI pattern.
+ */
+ writel(value, ioaddr + LPI_TIMER_CTRL);
}
static const struct stmmac_ops dwmac1000_ops = {
@@ -219,6 +300,10 @@ static const struct stmmac_ops dwmac1000_ops = {
.pmt = dwmac1000_pmt,
.set_umac_addr = dwmac1000_set_umac_addr,
.get_umac_addr = dwmac1000_get_umac_addr,
+ .set_eee_mode = dwmac1000_set_eee_mode,
+ .reset_eee_mode = dwmac1000_reset_eee_mode,
+ .set_eee_timer = dwmac1000_set_eee_timer,
+ .set_eee_pls = dwmac1000_set_eee_pls,
};
struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
index efde50f..a566903 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
@@ -72,9 +72,9 @@ static int dwmac100_rx_ipc_enable(void __iomem *ioaddr)
return 0;
}
-static void dwmac100_irq_status(void __iomem *ioaddr)
+static int dwmac100_irq_status(void __iomem *ioaddr)
{
- return;
+ return 0;
}
static void dwmac100_set_umac_addr(void __iomem *ioaddr, unsigned char *addr,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
index 6e0360f..e678ce3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
@@ -70,6 +70,7 @@
#define DMA_INTR_DEFAULT_MASK (DMA_INTR_NORMAL | DMA_INTR_ABNORMAL)
/* DMA Status register defines */
+#define DMA_STATUS_GLPII 0x40000000 /* GMAC LPI interrupt */
#define DMA_STATUS_GPI 0x10000000 /* PMT interrupt */
#define DMA_STATUS_GMI 0x08000000 /* MMC interrupt */
#define DMA_STATUS_GLI 0x04000000 /* GMAC Line interface int */
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 9f2435c..04af6e4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -85,6 +85,10 @@ struct stmmac_priv {
struct clk *stmmac_clk;
#endif
int clk_csr;
+ struct timer_list eee_ctrl_timer;
+ bool tx_path_in_lpi_mode;
+ bool eee_enabled;
+ int lpi_irq;
};
extern int phyaddr;
@@ -103,6 +107,8 @@ int stmmac_dvr_remove(struct net_device *ndev);
struct stmmac_priv *stmmac_dvr_probe(struct device *device,
struct plat_stmmacenet_data *plat_dat,
void __iomem *addr);
+void stmmac_disable_eee_mode(struct stmmac_priv *priv);
+bool stmmac_eee_init(struct stmmac_priv *priv);
#ifdef CONFIG_HAVE_CLK
static inline int stmmac_clk_enable(struct stmmac_priv *priv)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index ce43184..0bf411f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -93,6 +93,16 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = {
STMMAC_STAT(poll_n),
STMMAC_STAT(sched_timer_n),
STMMAC_STAT(normal_irq_n),
+ STMMAC_STAT(normal_irq_n),
+ STMMAC_STAT(mmc_tx_irq_n),
+ STMMAC_STAT(mmc_rx_irq_n),
+ STMMAC_STAT(mmc_rx_csum_offload_irq_n),
+ STMMAC_STAT(irq_receive_pmt_irq_n),
+ STMMAC_STAT(irq_tx_path_in_lpi_mode_n),
+ STMMAC_STAT(irq_tx_path_exit_lpi_mode_n),
+ STMMAC_STAT(irq_rx_path_in_lpi_mode_n),
+ STMMAC_STAT(irq_rx_path_exit_lpi_mode_n),
+ STMMAC_STAT(phy_eee_wakeup_error_n),
};
#define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats)
@@ -366,6 +376,11 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
(*(u32 *)p);
}
}
+ if (priv->eee_enabled) {
+ int val = phy_get_eee_err(priv->phydev);
+ if (val)
+ priv->xstats.phy_eee_wakeup_error_n = val;
+ }
}
for (i = 0; i < STMMAC_STATS_LEN; i++) {
char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset;
@@ -464,6 +479,37 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
return 0;
}
+static int stmmac_ethtool_op_get_eee(struct net_device *dev,
+ struct ethtool_value *eee)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+ if (!priv->dma_cap.eee)
+ return -EOPNOTSUPP;
+
+ eee->data = priv->eee_enabled;
+
+ return 0;
+}
+
+static int stmmac_ethtool_op_set_eee(struct net_device *dev,
+ struct ethtool_value *eee)
+{
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+ if ((!eee->data) && (priv->eee_enabled)) {
+ stmmac_disable_eee_mode(priv);
+ priv->eee_enabled = eee->data;
+ } else if ((eee->data) && (!priv->eee_enabled))
+ /* We are asking for enabling the EEE but this
+ * has to be verified by invoking the eee_init function.
+ * For this reason we cannot set eee_enabled to
+ * eee->data, directly. */
+ priv->eee_enabled = stmmac_eee_init(priv);
+
+ return 0;
+}
+
static const struct ethtool_ops stmmac_ethtool_ops = {
.begin = stmmac_check_if_running,
.get_drvinfo = stmmac_ethtool_getdrvinfo,
@@ -480,6 +526,8 @@ static const struct ethtool_ops stmmac_ethtool_ops = {
.get_strings = stmmac_get_strings,
.get_wol = stmmac_get_wol,
.set_wol = stmmac_set_wol,
+ .get_eee = stmmac_ethtool_op_get_eee,
+ .set_eee = stmmac_ethtool_op_set_eee,
.get_sset_count = stmmac_get_sset_count,
.get_ts_info = ethtool_op_get_ts_info,
};
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 90d5c4c..39928fe 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -133,6 +133,11 @@ static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
NETIF_MSG_LINK | NETIF_MSG_IFUP |
NETIF_MSG_IFDOWN | NETIF_MSG_TIMER);
+static int eee_timer = 1000;
+module_param(eee_timer, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(eee_timer, "LPI tx expiration time in msec");
+#define STMMAC_LPI_TIMER(x) (jiffies + msecs_to_jiffies(x))
+
static irqreturn_t stmmac_interrupt(int irq, void *dev_id);
#ifdef CONFIG_STMMAC_DEBUG_FS
@@ -226,6 +231,82 @@ static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv)
phydev->speed);
}
+static void stmmac_enable_eee_mode(struct stmmac_priv *priv)
+{
+ /* Check and enter in LPI mode */
+ if ((priv->dirty_tx == priv->cur_tx) &&
+ (priv->tx_path_in_lpi_mode == false))
+ priv->hw->mac->set_eee_mode(priv->ioaddr);
+}
+
+void stmmac_disable_eee_mode(struct stmmac_priv *priv)
+{
+ /* Exit and disable EEE in case of we are are in LPI state. */
+ priv->hw->mac->reset_eee_mode(priv->ioaddr);
+ del_timer_sync(&priv->eee_ctrl_timer);
+ priv->tx_path_in_lpi_mode = false;
+}
+
+/**
+ * stmmac_eee_ctrl_timer
+ * @arg : data hook
+ * Description:
+ * If there is no data transfer and if we are not in LPI state,
+ * then MAC Transmitter can be moved to LPI state.
+ */
+static void stmmac_eee_ctrl_timer(unsigned long arg)
+{
+ struct stmmac_priv *priv = (struct stmmac_priv *)arg;
+
+ stmmac_enable_eee_mode(priv);
+ mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_TIMER(eee_timer));
+}
+
+/**
+ * stmmac_eee_init
+ * @priv: private device pointer
+ * Description:
+ * If the EEE support has been enabled while configuring the driver,
+ * if the GMAC actually supports the EEE (from the HW cap reg) and the
+ * phy can also manage EEE, so enable the LPI state and start the timer
+ * to verify if the tx path can enter in LPI state.
+ */
+bool stmmac_eee_init(struct stmmac_priv *priv)
+{
+ bool ret = false;
+
+ /* MAC core supports the EEE feature. */
+ if (priv->dma_cap.eee) {
+
+ /* Check if the PHY supports EEE*/
+ if (phy_check_eee(priv->phydev))
+ goto out;
+
+ init_timer(&priv->eee_ctrl_timer);
+ priv->eee_ctrl_timer.function = stmmac_eee_ctrl_timer;
+ priv->eee_ctrl_timer.data = (unsigned long)priv;
+ priv->eee_ctrl_timer.expires = STMMAC_LPI_TIMER(eee_timer);
+ add_timer(&priv->eee_ctrl_timer);
+
+ priv->hw->mac->set_eee_timer(priv->ioaddr, 0x3e8, 0);
+
+ pr_info("stmmac: Energy-Efficient Ethernet initialized\n");
+
+ ret = true;
+ }
+out:
+ return ret;
+}
+
+static void stmmac_eee_adjust(struct stmmac_priv *priv)
+{
+ /* When the EEE has been already initialised we have to
+ * modify the PLS bit in the LPI ctrl & status reg according
+ * to the PHY link status. For this reason. */
+ if (priv->eee_enabled)
+ priv->hw->mac->set_eee_pls(priv->ioaddr, priv->phydev->link);
+}
+
/**
* stmmac_adjust_link
* @dev: net device structure
@@ -246,6 +327,7 @@ static void stmmac_adjust_link(struct net_device *dev)
phydev->addr, phydev->link);
spin_lock_irqsave(&priv->lock, flags);
+
if (phydev->link) {
u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
@@ -312,6 +394,8 @@ static void stmmac_adjust_link(struct net_device *dev)
if (new_state && netif_msg_link(priv))
phy_print_status(phydev);
+ stmmac_eee_adjust(priv);
+
spin_unlock_irqrestore(&priv->lock, flags);
DBG(probe, DEBUG, "stmmac_adjust_link: exiting\n");
@@ -329,7 +413,7 @@ static int stmmac_init_phy(struct net_device *dev)
{
struct stmmac_priv *priv = netdev_priv(dev);
struct phy_device *phydev;
- char phy_id[MII_BUS_ID_SIZE + 3];
+ char phy_id_fmt[MII_BUS_ID_SIZE + 3];
char bus_id[MII_BUS_ID_SIZE];
int interface = priv->plat->interface;
priv->oldlink = 0;
@@ -343,11 +427,12 @@ static int stmmac_init_phy(struct net_device *dev)
snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
priv->plat->bus_id);
- snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
+ snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
priv->plat->phy_addr);
- pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id);
+ pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id_fmt);
- phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0, interface);
+ phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, 0,
+ interface);
if (IS_ERR(phydev)) {
pr_err("%s: Could not attach to PHY\n", dev->name);
@@ -686,6 +771,11 @@ static void stmmac_tx(struct stmmac_priv *priv)
}
netif_tx_unlock(priv->dev);
}
+
+ if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) {
+ stmmac_enable_eee_mode(priv);
+ mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_TIMER(eee_timer));
+ }
spin_unlock(&priv->tx_lock);
}
@@ -1016,6 +1106,17 @@ static int stmmac_open(struct net_device *dev)
}
}
+ /* Request the IRQ lines */
+ if (priv->lpi_irq != -ENXIO) {
+ ret = request_irq(priv->lpi_irq, stmmac_interrupt, IRQF_SHARED,
+ dev->name, dev);
+ if (unlikely(ret < 0)) {
+ pr_err("%s: ERROR: allocating the LPI IRQ %d (%d)\n",
+ __func__, priv->lpi_irq, ret);
+ goto open_error_lpiirq;
+ }
+ }
+
/* Enable the MAC Rx/Tx */
stmmac_set_mac(priv->ioaddr, true);
@@ -1051,12 +1152,18 @@ static int stmmac_open(struct net_device *dev)
if (priv->phydev)
phy_start(priv->phydev);
+ priv->eee_enabled = stmmac_eee_init(priv);
+
napi_enable(&priv->napi);
skb_queue_head_init(&priv->rx_recycle);
netif_start_queue(dev);
return 0;
+open_error_lpiirq:
+ if (priv->wol_irq != dev->irq)
+ free_irq(priv->wol_irq, dev);
+
open_error_wolirq:
free_irq(dev->irq, dev);
@@ -1082,6 +1189,9 @@ static int stmmac_release(struct net_device *dev)
{
struct stmmac_priv *priv = netdev_priv(dev);
+ if (priv->eee_enabled)
+ del_timer_sync(&priv->eee_ctrl_timer);
+
/* Stop and disconnect the PHY */
if (priv->phydev) {
phy_stop(priv->phydev);
@@ -1104,6 +1214,8 @@ static int stmmac_release(struct net_device *dev)
free_irq(dev->irq, dev);
if (priv->wol_irq != dev->irq)
free_irq(priv->wol_irq, dev);
+ if (priv->lpi_irq != -ENXIO)
+ free_irq(priv->lpi_irq, dev);
/* Stop TX/RX DMA and clear the descriptors */
priv->hw->dma->stop_tx(priv->ioaddr);
@@ -1154,6 +1266,9 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
spin_lock(&priv->tx_lock);
+ if (priv->tx_path_in_lpi_mode)
+ stmmac_disable_eee_mode(priv);
+
entry = priv->cur_tx % txsize;
#ifdef STMMAC_XMIT_DEBUG
@@ -1531,10 +1646,37 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
return IRQ_NONE;
}
- if (priv->plat->has_gmac)
- /* To handle GMAC own interrupts */
- priv->hw->mac->host_irq_status((void __iomem *) dev->base_addr);
+ /* To handle GMAC own interrupts */
+ if (priv->plat->has_gmac) {
+ int status = priv->hw->mac->host_irq_status((void __iomem *)
+ dev->base_addr);
+ if (unlikely(status)) {
+ if (status & core_mmc_tx_irq)
+ priv->xstats.mmc_tx_irq_n++;
+ if (status & core_mmc_rx_irq)
+ priv->xstats.mmc_rx_irq_n++;
+ if (status & core_mmc_rx_csum_offload_irq)
+ priv->xstats.mmc_rx_csum_offload_irq_n++;
+ if (status & core_irq_receive_pmt_irq)
+ priv->xstats.irq_receive_pmt_irq_n++;
+
+ /* For LPI we need to save the tx status */
+ if (status & core_irq_tx_path_in_lpi_mode) {
+ priv->xstats.irq_tx_path_in_lpi_mode_n++;
+ priv->tx_path_in_lpi_mode = true;
+ }
+ if (status & core_irq_tx_path_exit_lpi_mode) {
+ priv->xstats.irq_tx_path_exit_lpi_mode_n++;
+ priv->tx_path_in_lpi_mode = false;
+ }
+ if (status & core_irq_rx_path_in_lpi_mode)
+ priv->xstats.irq_rx_path_in_lpi_mode_n++;
+ if (status & core_irq_rx_path_exit_lpi_mode)
+ priv->xstats.irq_rx_path_exit_lpi_mode_n++;
+ }
+ }
+ /* To handle DMA interrupts */
stmmac_dma_interrupt(priv);
return IRQ_HANDLED;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 116529a..06d699e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -157,6 +157,8 @@ static int stmmac_pltfr_probe(struct platform_device *pdev)
if (priv->wol_irq == -ENXIO)
priv->wol_irq = priv->dev->irq;
+ priv->lpi_irq = platform_get_irq_byname(pdev, "eth_lpi");
+
platform_set_drvdata(pdev, priv->dev);
pr_debug("STMMAC platform driver registration completed");
--
1.7.4.4
^ permalink raw reply related
* [net-next 4/4 (V3)] stmmac: update the driver Documentation and add EEE
From: Giuseppe CAVALLARO @ 2012-04-06 9:29 UTC (permalink / raw)
To: netdev; +Cc: bhutchings, rayagond, davem, Giuseppe CAVALLARO
In-Reply-To: <1333704559-11251-1-git-send-email-peppe.cavallaro@st.com>
From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
This patch updates the stmmac's documentation adding
some missing files in the secstion to describe the
driver's structure. Also the patch adds a new section
for the EEE support.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
Documentation/networking/stmmac.txt | 36 +++++++++++++++++++++++++++++-----
1 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt
index ab1e8d7..1cc8b75 100644
--- a/Documentation/networking/stmmac.txt
+++ b/Documentation/networking/stmmac.txt
@@ -251,9 +251,11 @@ reset procedure etc).
o Makefile
o stmmac_main.c: main network device driver;
o stmmac_mdio.c: mdio functions;
+ o stmmac_pci: PCI driver;
+ o stmmac_platform.c: platform driver
o stmmac_ethtool.c: ethtool support;
o stmmac_timer.[ch]: timer code used for mitigating the driver dma interrupts
- Only tested on ST40 platforms based.
+ (only tested on ST40 platforms based);
o stmmac.h: private driver structure;
o common.h: common definitions and VFTs;
o descs.h: descriptor structure definitions;
@@ -263,9 +265,11 @@ reset procedure etc).
o dwmac100_core: MAC 100 core and dma code;
o dwmac100_dma.c: dma funtions for the MAC chip;
o dwmac1000.h: specific header file for the MAC;
- o dwmac_lib.c: generic DMA functions shared among chips
- o enh_desc.c: functions for handling enhanced descriptors
- o norm_desc.c: functions for handling normal descriptors
+ o dwmac_lib.c: generic DMA functions shared among chips;
+ o enh_desc.c: functions for handling enhanced descriptors;
+ o norm_desc.c: functions for handling normal descriptors;
+ o chain_mode.c/ring_mode.c:: functions to manage RING/CHAINED modes;
+ o mmc_core.c/mmc.h: Management MAC Counters;
5) Debug Information
@@ -298,7 +302,27 @@ All these are only useful during the developing stage
and should never enabled inside the code for general usage.
In fact, these can generate an huge amount of debug messages.
-6) TODO:
+6) Energy Efficient Ethernet
+
+Energy Efficient Ethernet(EEE) enables IEEE 802.3 MAC sublayer along
+with a family of Physical layer to operate in the Low power Idle(LPI)
+mode. The EEE mode supports the IEEE 802.3 MAC operation at 100Mbps,
+1000Mbps & 10Gbps.
+
+The LPI mode allows power saving by switching off parts of the
+communication device functionality when there is no data to be
+transmitted & received. The system on both the side of the link can
+disable some functionalities & save power during the period of low-link
+utilization. The MAC controls whether the system should enter or exit
+the LPI mode & communicate this to PHY.
+
+As soon as the interface is opened, the driver verifies if the EEE can
+be supported. This is done by looking at both the DMA HW capability
+register and the PHY devices MCD registers.
+To enter in Tx LPI mode the driver needs to have a software timer
+that enable and disable the LPI mode when there is nothing to be
+transmitted.
+
+7) TODO:
o XGMAC is not supported.
- o Add the EEE - Energy Efficient Ethernet
o Add the PTP - precision time protocol
--
1.7.4.4
^ permalink raw reply related
* [PATCH] ethtool: add the EEE option
From: Giuseppe CAVALLARO @ 2012-04-06 9:29 UTC (permalink / raw)
To: netdev; +Cc: bhutchings, rayagond, davem, Giuseppe Cavallaro
In-Reply-To: <1333704559-11251-1-git-send-email-peppe.cavallaro@st.com>
This patch adds a new option to enable/disable the
Energy Efficient Ethernet support: below some example:
bash-3.00# ethtool -s eth0 eee on
stmmac: Energy-Efficient Ethernet initialized
bash-3.00# ./ethtool eth0
Settings for eth0:
Supported ports: [ TP MII ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
[snip]
Wake-on: d
Current message level: 0x0000003f (63)
drv probe link timer ifdown ifup
Link detected: yes
Energy-Efficient Ethernet: Enabled
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
ethtool-copy.h | 3 +++
ethtool.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 47 insertions(+), 1 deletions(-)
diff --git a/ethtool-copy.h b/ethtool-copy.h
index d904c1a..e17ae37 100644
--- a/ethtool-copy.h
+++ b/ethtool-copy.h
@@ -40,6 +40,7 @@ struct ethtool_cmd {
__u8 eth_tp_mdix;
__u8 reserved2;
__u32 lp_advertising; /* Features the link partner advertises */
+ __u32 eee; /* Energy-Efficient Etehrnet */
__u32 reserved[2];
};
@@ -786,6 +787,8 @@ enum ethtool_sfeatures_retval_bits {
#define ETHTOOL_SET_DUMP 0x0000003e /* Set dump settings */
#define ETHTOOL_GET_DUMP_FLAG 0x0000003f /* Get dump settings */
#define ETHTOOL_GET_DUMP_DATA 0x00000040 /* Get dump data */
+#define ETHTOOL_GEEE 0x00000041 /* Get EEE */
+#define ETHTOOL_SEEE 0x00000042 /* Set EEE */
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
diff --git a/ethtool.c b/ethtool.c
index d0cc7d4..9e63973 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -1840,6 +1840,18 @@ static int do_gset(struct cmd_context *ctx)
} else if (errno != EOPNOTSUPP) {
perror("Cannot get link status");
}
+ edata.cmd = ETHTOOL_GEEE;
+ err = send_ioctl(ctx, &edata);
+ if (err == 0) {
+ fprintf(stdout, " Energy-Efficient Ethernet: %s\n",
+ edata.data ? "enabled" : "disabled");
+ allfail = 0;
+ } else if (errno != EOPNOTSUPP) {
+ perror("Cannot get EEE feature");
+ } else if (errno == EOPNOTSUPP) {
+ fprintf(stdout, " Energy-Efficient Ethernet:"
+ " not supported\n");
+ }
if (allfail) {
fprintf(stdout, "No data available\n");
@@ -1857,6 +1869,8 @@ static int do_sset(struct cmd_context *ctx)
int phyad_wanted = -1;
int xcvr_wanted = -1;
int advertising_wanted = -1;
+ int eee_wanted = -1;
+ int eee_changed = 0;
int gset_changed = 0; /* did anything in GSET change? */
u32 wol_wanted = 0;
int wol_change = 0;
@@ -1983,6 +1997,17 @@ static int do_sset(struct cmd_context *ctx)
ARRAY_SIZE(cmdline_msglvl));
break;
}
+ } else if (!strcmp(argp[i], "eee")) {
+ eee_changed = 1;
+ i++;
+ if (i >= argc)
+ exit_bad_args();
+ if (!strcmp(argp[i], "on"))
+ eee_wanted = 1;
+ else if (!strcmp(argp[i], "off"))
+ eee_wanted = 0;
+ else
+ exit_bad_args();
} else {
exit_bad_args();
}
@@ -2129,6 +2154,23 @@ static int do_sset(struct cmd_context *ctx)
}
}
+ if (eee_changed) {
+ struct ethtool_value edata;
+
+ edata.cmd = ETHTOOL_GEEE;
+ err = send_ioctl(ctx, &edata);
+ if (err < 0)
+ perror("Cannot get current EEE settings");
+ else {
+ edata.cmd = ETHTOOL_SEEE;
+ edata.data = eee_wanted;
+ err = send_ioctl(ctx, &edata);
+ if (err < 0)
+ fprintf(stderr, "Cannot turn %s the EEE",
+ (eee_wanted ? "on" : "off"));
+ }
+ }
+
if (msglvl_changed) {
struct ethtool_value edata;
@@ -3129,7 +3171,8 @@ static const struct option {
" [ xcvr internal|external ]\n"
" [ wol p|u|m|b|a|g|s|d... ]\n"
" [ sopass %x:%x:%x:%x:%x:%x ]\n"
- " [ msglvl %d | msglvl type on|off ... ]\n" },
+ " [ msglvl %d | msglvl type on|off ]\n"
+ " [ eee on|off ... ]\n" },
{ "-a|--show-pause", 1, do_gpause, "Show pause options" },
{ "-A|--pause", 1, do_spause, "Set pause options",
" [ autoneg on|off ]\n"
--
1.7.4.4
^ permalink raw reply related
* Re[2]: Re[2]: [PATCH] netfilter: ipvs: Verify that IP_VS protocol has been registered
From: Hans Schillstrom @ 2012-04-06 9:39 UTC (permalink / raw)
To: Sasha Levin
Cc: Simon Horman, wensong, ja, kaber, davem, davej, netdev, lvs-devel,
netfilter-devel, linux-kernel
Hello Sasha
>---- Original Message ----
>From: Sasha Levin <levinsasha928@gmail.com>
>To: "Hans Schillstrom" <hans@schillstrom.com>
>Cc: "Simon Horman" <horms@verge.net.au>, wensong@linux-vs.org, ja@ssi.bg, kaber@trash.net, davem@davemloft.net, davej@redhat.com, netdev@vger.kernel.org, lvs-devel@vger.kernel.org, netfilter-devel@vger.kernel.org, linux-kernel@vger.kernel.org
>Sent: Fri, Apr 6, 2012, 11:22 AM
>Subject: Re: Re[2]: [PATCH] netfilter: ipvs: Verify that IP_VS protocol has been registered
>
>On Fri, Apr 6, 2012 at 10:59 AM, Hans Schillstrom <hans@schillstrom.com> wrote:
>> Hello Simon
>>
>>>---- Original Message ----
>>>From: Simon Horman <horms@verge.net.au>
>>>To: "Sasha Levin" <levinsasha928@gmail.com>
>>>Cc: wensong@linux-vs.org, ja@ssi.bg, kaber@trash.net, davem@davemloft.net, davej@redhat.com, netdev@vger.kernel.org, lvs-devel@vger.kernel.org, netfilter-devel@vger.kernel.org, linux-kernel@vger.kernel.org
>>>Sent: Fri, Apr 6, 2012, 1:19 AM
>>>Subject: Re: [PATCH] netfilter: ipvs: Verify that IP_VS protocol has been registered
>>>
>>>On Thu, Apr 05, 2012 at 07:24:33PM -0400, Sasha Levin wrote:
>>>> The registration of a protocol might fail, there were no checks
>>>> and all registrations were assumed to be correct. This lead to
>>>> NULL ptr dereferences when apps tried registering.
>>>
>>>Thanks, I will queue up this fix.
>>>
>>>Do you have a real-world example of this failing, if so it
>>>might be worth pushing your change into stable.
>>
>> I don't think this is a big thing, the only thing that can cause it is out of memory,
>> and that will cause a "kernel death" anyway :-(
>>
>> here is the code :
>>
>> register_ip_vs_proto_netns(struct net *net, struct ip_vs_protocol *pp)
>> {
>> ...
>> struct ip_vs_proto_data *pd =
>> kzalloc(sizeof(struct ip_vs_proto_data), GFP_ATOMIC);
>>
>> if (!pd)
>> return -ENOMEM;
>>
>>
>
>Considering that the allocation gfp flag here is GFP_ATOMIC (why is it
>GFP_ATOMIC btw?), it might fail for a variety of reasons which may
>occur when the system is "healthy", for example - if it needs disk I/O
>to allocate.
Hmm, I think it should be GFP_KERNEL
I will have a look at this, and make it consistent with the rest of the netns allocations,
>
>Either way, you shouldn't be dereferencing NULL ptrs even when the
>system is really low on memory.
Of course not, it's a bug
Simon:
I think you should push this one into stable
Thanks Sasha
Regards
Hans
^ permalink raw reply
* [PATCH net-next #2 08/39] sundance: stop using net_device.{base_addr, irq}.
From: Francois Romieu @ 2012-04-06 10:06 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <1333704408.git.romieu@fr.zoreil.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/ethernet/dlink/sundance.c | 12 +++++-------
1 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/dlink/sundance.c b/drivers/net/ethernet/dlink/sundance.c
index d783f4f..d7bb52a 100644
--- a/drivers/net/ethernet/dlink/sundance.c
+++ b/drivers/net/ethernet/dlink/sundance.c
@@ -522,9 +522,6 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
cpu_to_le16(eeprom_read(ioaddr, i + EEPROM_SA_OFFSET));
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
- dev->base_addr = (unsigned long)ioaddr;
- dev->irq = irq;
-
np = netdev_priv(dev);
np->base = ioaddr;
np->pci_dev = pdev;
@@ -828,18 +825,19 @@ static int netdev_open(struct net_device *dev)
{
struct netdev_private *np = netdev_priv(dev);
void __iomem *ioaddr = np->base;
+ const int irq = np->pci_dev->irq;
unsigned long flags;
int i;
/* Do we need to reset the chip??? */
- i = request_irq(dev->irq, intr_handler, IRQF_SHARED, dev->name, dev);
+ i = request_irq(irq, intr_handler, IRQF_SHARED, dev->name, dev);
if (i)
return i;
if (netif_msg_ifup(np))
- printk(KERN_DEBUG "%s: netdev_open() irq %d.\n",
- dev->name, dev->irq);
+ printk(KERN_DEBUG "%s: netdev_open() irq %d\n", dev->name, irq);
+
init_ring(dev);
iowrite32(np->rx_ring_dma, ioaddr + RxListPtr);
@@ -1814,7 +1812,7 @@ static int netdev_close(struct net_device *dev)
}
#endif /* __i386__ debugging only */
- free_irq(dev->irq, dev);
+ free_irq(np->pci_dev->irq, dev);
del_timer_sync(&np->timer);
--
1.7.7.6
^ permalink raw reply related
* [PATCH net-next #2 14/39] yellowfin: stop using net_device.{base_addr, irq}.
From: Francois Romieu @ 2012-04-06 10:06 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <1333704408.git.romieu@fr.zoreil.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/ethernet/packetengines/yellowfin.c | 32 ++++++++++-------------
1 files changed, 14 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/packetengines/yellowfin.c b/drivers/net/ethernet/packetengines/yellowfin.c
index 7757b80..cf5f54b 100644
--- a/drivers/net/ethernet/packetengines/yellowfin.c
+++ b/drivers/net/ethernet/packetengines/yellowfin.c
@@ -427,9 +427,6 @@ static int __devinit yellowfin_init_one(struct pci_dev *pdev,
/* Reset the chip. */
iowrite32(0x80000000, ioaddr + DMACtrl);
- dev->base_addr = (unsigned long)ioaddr;
- dev->irq = irq;
-
pci_set_drvdata(pdev, dev);
spin_lock_init(&np->lock);
@@ -569,25 +566,20 @@ static void mdio_write(void __iomem *ioaddr, int phy_id, int location, int value
static int yellowfin_open(struct net_device *dev)
{
struct yellowfin_private *yp = netdev_priv(dev);
+ const int irq = yp->pci_dev->irq;
void __iomem *ioaddr = yp->base;
- int i, ret;
+ int i, rc;
/* Reset the chip. */
iowrite32(0x80000000, ioaddr + DMACtrl);
- ret = request_irq(dev->irq, yellowfin_interrupt, IRQF_SHARED, dev->name, dev);
- if (ret)
- return ret;
-
- if (yellowfin_debug > 1)
- netdev_printk(KERN_DEBUG, dev, "%s() irq %d\n",
- __func__, dev->irq);
+ rc = request_irq(irq, yellowfin_interrupt, IRQF_SHARED, dev->name, dev);
+ if (rc < 0)
+ goto out;
- ret = yellowfin_init_ring(dev);
- if (ret) {
- free_irq(dev->irq, dev);
- return ret;
- }
+ rc = yellowfin_init_ring(dev);
+ if (rc < 0)
+ goto err_free_irq;
iowrite32(yp->rx_ring_dma, ioaddr + RxPtr);
iowrite32(yp->tx_ring_dma, ioaddr + TxPtr);
@@ -647,8 +639,12 @@ static int yellowfin_open(struct net_device *dev)
yp->timer.data = (unsigned long)dev;
yp->timer.function = yellowfin_timer; /* timer handler */
add_timer(&yp->timer);
+out:
+ return rc;
- return 0;
+err_free_irq:
+ free_irq(irq, dev);
+ goto out;
}
static void yellowfin_timer(unsigned long data)
@@ -1251,7 +1247,7 @@ static int yellowfin_close(struct net_device *dev)
}
#endif /* __i386__ debugging only */
- free_irq(dev->irq, dev);
+ free_irq(yp->pci_dev->irq, dev);
/* Free all the skbuffs in the Rx queue. */
for (i = 0; i < RX_RING_SIZE; i++) {
--
1.7.7.6
^ permalink raw reply related
* [PATCH net-next #2 10/39] fealnx: stop using net_device.{base_addr, irq}.
From: Francois Romieu @ 2012-04-06 10:06 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <1333704408.git.romieu@fr.zoreil.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/ethernet/fealnx.c | 17 ++++++++---------
1 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/fealnx.c b/drivers/net/ethernet/fealnx.c
index 1637b98..328c631 100644
--- a/drivers/net/ethernet/fealnx.c
+++ b/drivers/net/ethernet/fealnx.c
@@ -545,9 +545,6 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev,
/* Reset the chip to erase previous misconfiguration. */
iowrite32(0x00000001, ioaddr + BCR);
- dev->base_addr = (unsigned long)ioaddr;
- dev->irq = irq;
-
/* Make certain the descriptor lists are aligned. */
np = netdev_priv(dev);
np->mem = ioaddr;
@@ -832,12 +829,14 @@ static int netdev_open(struct net_device *dev)
{
struct netdev_private *np = netdev_priv(dev);
void __iomem *ioaddr = np->mem;
- int i;
+ const int irq = np->pci_dev->irq;
+ int rc, i;
iowrite32(0x00000001, ioaddr + BCR); /* Reset */
- if (request_irq(dev->irq, intr_handler, IRQF_SHARED, dev->name, dev))
- return -EAGAIN;
+ rc = request_irq(irq, intr_handler, IRQF_SHARED, dev->name, dev);
+ if (rc < 0)
+ goto out;
for (i = 0; i < 3; i++)
iowrite16(((unsigned short*)dev->dev_addr)[i],
@@ -924,8 +923,8 @@ static int netdev_open(struct net_device *dev)
np->reset_timer.data = (unsigned long) dev;
np->reset_timer.function = reset_timer;
np->reset_timer_armed = 0;
-
- return 0;
+out:
+ return rc;
}
@@ -1910,7 +1909,7 @@ static int netdev_close(struct net_device *dev)
del_timer_sync(&np->timer);
del_timer_sync(&np->reset_timer);
- free_irq(dev->irq, dev);
+ free_irq(np->pci_dev->irq, dev);
/* Free all the skbuffs in the Rx queue. */
for (i = 0; i < RX_RING_SIZE; i++) {
--
1.7.7.6
^ permalink raw reply related
* [PATCH net-next #2 22/39] sunhme: stop using net_device.{base_addr, irq}.
From: Francois Romieu @ 2012-04-06 10:06 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <1333704408.git.romieu@fr.zoreil.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/ethernet/sun/sunhme.c | 20 +++++++++-----------
drivers/net/ethernet/sun/sunhme.h | 1 +
2 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
index 8b627e2..a470f38 100644
--- a/drivers/net/ethernet/sun/sunhme.c
+++ b/drivers/net/ethernet/sun/sunhme.c
@@ -2183,13 +2183,14 @@ static int happy_meal_open(struct net_device *dev)
* into a single source which we register handling at probe time.
*/
if ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO) {
- if (request_irq(dev->irq, happy_meal_interrupt,
- IRQF_SHARED, dev->name, (void *)dev)) {
+ res = request_irq(hp->irq, happy_meal_interrupt, IRQF_SHARED,
+ dev->name, dev);
+ if (res < 0) {
HMD(("EAGAIN\n"));
printk(KERN_ERR "happy_meal(SBUS): Can't order irq %d to go.\n",
- dev->irq);
+ hp->irq);
- return -EAGAIN;
+ return res;
}
}
@@ -2200,7 +2201,7 @@ static int happy_meal_open(struct net_device *dev)
spin_unlock_irq(&hp->happy_lock);
if (res && ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO))
- free_irq(dev->irq, dev);
+ free_irq(hp->irq, dev);
return res;
}
@@ -2222,7 +2223,7 @@ static int happy_meal_close(struct net_device *dev)
* time and never unregister.
*/
if ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO)
- free_irq(dev->irq, dev);
+ free_irq(hp->irq, dev);
return 0;
}
@@ -2778,7 +2779,7 @@ static int __devinit happy_meal_sbus_probe_one(struct platform_device *op, int i
dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM;
dev->features |= dev->hw_features | NETIF_F_RXCSUM;
- dev->irq = op->archdata.irqs[0];
+ hp->irq = op->archdata.irqs[0];
#if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
/* Hook up SBUS register/descriptor accessors. */
@@ -2982,8 +2983,6 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
if (hme_version_printed++ == 0)
printk(KERN_INFO "%s", version);
- dev->base_addr = (long) pdev;
-
hp = netdev_priv(dev);
hp->happy_dev = pdev;
@@ -3088,12 +3087,11 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
init_timer(&hp->happy_timer);
+ hp->irq = pdev->irq;
hp->dev = dev;
dev->netdev_ops = &hme_netdev_ops;
dev->watchdog_timeo = 5*HZ;
dev->ethtool_ops = &hme_ethtool_ops;
- dev->irq = pdev->irq;
- dev->dma = 0;
/* Happy Meal can do it all... */
dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM;
diff --git a/drivers/net/ethernet/sun/sunhme.h b/drivers/net/ethernet/sun/sunhme.h
index 64f2783..f430765 100644
--- a/drivers/net/ethernet/sun/sunhme.h
+++ b/drivers/net/ethernet/sun/sunhme.h
@@ -432,6 +432,7 @@ struct happy_meal {
dma_addr_t hblock_dvma; /* DVMA visible address happy block */
unsigned int happy_flags; /* Driver state flags */
+ int irq;
enum happy_transceiver tcvr_type; /* Kind of transceiver in use */
unsigned int happy_bursts; /* Get your mind out of the gutter */
unsigned int paddr; /* PHY address for transceiver */
--
1.7.7.6
^ permalink raw reply related
* [PATCH net-next #2 07/39] via-velocity: stop using net_device.{base_addr, irq}.
From: Francois Romieu @ 2012-04-06 10:06 UTC (permalink / raw)
To: netdev; +Cc: David Miller, David Lv
In-Reply-To: <1333704408.git.romieu@fr.zoreil.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: David Lv <DavidLv@viatech.com.cn>
---
drivers/net/ethernet/via/via-velocity.c | 9 ++-------
1 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c
index 8a5d7c1..ea3e0a2 100644
--- a/drivers/net/ethernet/via/via-velocity.c
+++ b/drivers/net/ethernet/via/via-velocity.c
@@ -2488,8 +2488,8 @@ static int velocity_close(struct net_device *dev)
if (vptr->flags & VELOCITY_FLAGS_WOL_ENABLED)
velocity_get_ip(vptr);
- if (dev->irq != 0)
- free_irq(dev->irq, dev);
+
+ free_irq(vptr->pdev->irq, dev);
velocity_free_rings(vptr);
@@ -2755,8 +2755,6 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
if (ret < 0)
goto err_free_dev;
- dev->irq = pdev->irq;
-
ret = velocity_get_pci_info(vptr, pdev);
if (ret < 0) {
/* error message already printed */
@@ -2779,8 +2777,6 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
mac_wol_reset(regs);
- dev->base_addr = vptr->ioaddr;
-
for (i = 0; i < 6; i++)
dev->dev_addr[i] = readb(®s->PAR[i]);
@@ -2806,7 +2802,6 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
vptr->phy_id = MII_GET_PHY_ID(vptr->mac_regs);
- dev->irq = pdev->irq;
dev->netdev_ops = &velocity_netdev_ops;
dev->ethtool_ops = &velocity_ethtool_ops;
netif_napi_add(dev, &vptr->napi, velocity_poll, VELOCITY_NAPI_WEIGHT);
--
1.7.7.6
^ permalink raw reply related
* [PATCH net-next #2 20/39] sis190: stop using net_device.{base_addr, irq}
From: Francois Romieu @ 2012-04-06 10:06 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <1333704408.git.romieu@fr.zoreil.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/ethernet/sis/sis190.c | 26 +++++++++++---------------
1 files changed, 11 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/sis/sis190.c b/drivers/net/ethernet/sis/sis190.c
index a9deda8..4613591 100644
--- a/drivers/net/ethernet/sis/sis190.c
+++ b/drivers/net/ethernet/sis/sis190.c
@@ -729,7 +729,7 @@ static void sis190_tx_interrupt(struct net_device *dev,
* The interrupt handler does all of the Rx thread work and cleans up after
* the Tx thread.
*/
-static irqreturn_t sis190_interrupt(int irq, void *__dev)
+static irqreturn_t sis190_irq(int irq, void *__dev)
{
struct net_device *dev = __dev;
struct sis190_private *tp = netdev_priv(dev);
@@ -772,11 +772,11 @@ out:
static void sis190_netpoll(struct net_device *dev)
{
struct sis190_private *tp = netdev_priv(dev);
- struct pci_dev *pdev = tp->pci_dev;
+ const int irq = tp->pci_dev->irq;
- disable_irq(pdev->irq);
- sis190_interrupt(pdev->irq, dev);
- enable_irq(pdev->irq);
+ disable_irq(irq);
+ sis190_irq(irq, dev);
+ enable_irq(irq);
}
#endif
@@ -1085,7 +1085,7 @@ static int sis190_open(struct net_device *dev)
sis190_request_timer(dev);
- rc = request_irq(dev->irq, sis190_interrupt, IRQF_SHARED, dev->name, dev);
+ rc = request_irq(pdev->irq, sis190_irq, IRQF_SHARED, dev->name, dev);
if (rc < 0)
goto err_release_timer_2;
@@ -1097,11 +1097,9 @@ err_release_timer_2:
sis190_delete_timer(dev);
sis190_rx_clear(tp);
err_free_rx_1:
- pci_free_consistent(tp->pci_dev, RX_RING_BYTES, tp->RxDescRing,
- tp->rx_dma);
+ pci_free_consistent(pdev, RX_RING_BYTES, tp->RxDescRing, tp->rx_dma);
err_free_tx_0:
- pci_free_consistent(tp->pci_dev, TX_RING_BYTES, tp->TxDescRing,
- tp->tx_dma);
+ pci_free_consistent(pdev, TX_RING_BYTES, tp->TxDescRing, tp->tx_dma);
goto out;
}
@@ -1141,7 +1139,7 @@ static void sis190_down(struct net_device *dev)
spin_unlock_irq(&tp->lock);
- synchronize_irq(dev->irq);
+ synchronize_irq(tp->pci_dev->irq);
if (!poll_locked)
poll_locked++;
@@ -1161,7 +1159,7 @@ static int sis190_close(struct net_device *dev)
sis190_down(dev);
- free_irq(dev->irq, dev);
+ free_irq(pdev->irq, dev);
pci_free_consistent(pdev, TX_RING_BYTES, tp->TxDescRing, tp->tx_dma);
pci_free_consistent(pdev, RX_RING_BYTES, tp->RxDescRing, tp->rx_dma);
@@ -1884,8 +1882,6 @@ static int __devinit sis190_init_one(struct pci_dev *pdev,
dev->netdev_ops = &sis190_netdev_ops;
SET_ETHTOOL_OPS(dev, &sis190_ethtool_ops);
- dev->irq = pdev->irq;
- dev->base_addr = (unsigned long) 0xdead;
dev->watchdog_timeo = SIS190_TX_TIMEOUT;
spin_lock_init(&tp->lock);
@@ -1902,7 +1898,7 @@ static int __devinit sis190_init_one(struct pci_dev *pdev,
netdev_info(dev, "%s: %s at %p (IRQ: %d), %pM\n",
pci_name(pdev),
sis_chip_info[ent->driver_data].name,
- ioaddr, dev->irq, dev->dev_addr);
+ ioaddr, pdev->irq, dev->dev_addr);
netdev_info(dev, "%s mode.\n",
(tp->features & F_HAS_RGMII) ? "RGMII" : "GMII");
}
--
1.7.7.6
^ permalink raw reply related
* [PATCH net-next #2 19/39] sc92031: stop using net_device.{base_addr, irq}
From: Francois Romieu @ 2012-04-06 10:06 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <1333704408.git.romieu@fr.zoreil.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/ethernet/silan/sc92031.c | 34 +++++++++++-----------------------
1 files changed, 11 insertions(+), 23 deletions(-)
diff --git a/drivers/net/ethernet/silan/sc92031.c b/drivers/net/ethernet/silan/sc92031.c
index a284d64..32e5566 100644
--- a/drivers/net/ethernet/silan/sc92031.c
+++ b/drivers/net/ethernet/silan/sc92031.c
@@ -39,9 +39,7 @@
#define SC92031_NAME "sc92031"
/* BAR 0 is MMIO, BAR 1 is PIO */
-#ifndef SC92031_USE_BAR
-#define SC92031_USE_BAR 0
-#endif
+#define SC92031_USE_PIO 0
/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). */
static int multicast_filter_limit = 64;
@@ -366,7 +364,7 @@ static void sc92031_disable_interrupts(struct net_device *dev)
mmiowb();
/* wait for any concurrent interrupt/tasklet to finish */
- synchronize_irq(dev->irq);
+ synchronize_irq(priv->pdev->irq);
tasklet_disable(&priv->tasklet);
}
@@ -1114,10 +1112,13 @@ static void sc92031_tx_timeout(struct net_device *dev)
#ifdef CONFIG_NET_POLL_CONTROLLER
static void sc92031_poll_controller(struct net_device *dev)
{
- disable_irq(dev->irq);
- if (sc92031_interrupt(dev->irq, dev) != IRQ_NONE)
+ struct sc92031_priv *priv = netdev_priv(dev);
+ const int irq = priv->pdev->irq;
+
+ disable_irq(irq);
+ if (sc92031_interrupt(irq, dev) != IRQ_NONE)
sc92031_tasklet((unsigned long)dev);
- enable_irq(dev->irq);
+ enable_irq(irq);
}
#endif
@@ -1402,7 +1403,6 @@ static int __devinit sc92031_probe(struct pci_dev *pdev,
struct net_device *dev;
struct sc92031_priv *priv;
u32 mac0, mac1;
- unsigned long base_addr;
err = pci_enable_device(pdev);
if (unlikely(err < 0))
@@ -1422,7 +1422,7 @@ static int __devinit sc92031_probe(struct pci_dev *pdev,
if (unlikely(err < 0))
goto out_request_regions;
- port_base = pci_iomap(pdev, SC92031_USE_BAR, 0);
+ port_base = pci_iomap(pdev, SC92031_USE_PIO, 0);
if (unlikely(!port_base)) {
err = -EIO;
goto out_iomap;
@@ -1437,14 +1437,6 @@ static int __devinit sc92031_probe(struct pci_dev *pdev,
pci_set_drvdata(pdev, dev);
SET_NETDEV_DEV(dev, &pdev->dev);
-#if SC92031_USE_BAR == 0
- dev->mem_start = pci_resource_start(pdev, SC92031_USE_BAR);
- dev->mem_end = pci_resource_end(pdev, SC92031_USE_BAR);
-#elif SC92031_USE_BAR == 1
- dev->base_addr = pci_resource_start(pdev, SC92031_USE_BAR);
-#endif
- dev->irq = pdev->irq;
-
/* faked with skb_copy_and_csum_dev */
dev->features = NETIF_F_SG | NETIF_F_HIGHDMA |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
@@ -1478,13 +1470,9 @@ static int __devinit sc92031_probe(struct pci_dev *pdev,
if (err < 0)
goto out_register_netdev;
-#if SC92031_USE_BAR == 0
- base_addr = dev->mem_start;
-#elif SC92031_USE_BAR == 1
- base_addr = dev->base_addr;
-#endif
printk(KERN_INFO "%s: SC92031 at 0x%lx, %pM, IRQ %d\n", dev->name,
- base_addr, dev->dev_addr, dev->irq);
+ (long)pci_resource_start(pdev, SC92031_USE_PIO), dev->dev_addr,
+ pdev->irq);
return 0;
--
1.7.7.6
^ permalink raw reply related
* [PATCH net-next #2 18/39] winbond840: stop using net_device.{base_addr, irq}.
From: Francois Romieu @ 2012-04-06 10:06 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <1333704408.git.romieu@fr.zoreil.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/ethernet/dec/tulip/winbond-840.c | 17 ++++++++---------
1 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/dec/tulip/winbond-840.c b/drivers/net/ethernet/dec/tulip/winbond-840.c
index 2ac6fff..4d1ffca 100644
--- a/drivers/net/ethernet/dec/tulip/winbond-840.c
+++ b/drivers/net/ethernet/dec/tulip/winbond-840.c
@@ -400,9 +400,6 @@ static int __devinit w840_probe1 (struct pci_dev *pdev,
No hold time required! */
iowrite32(0x00000001, ioaddr + PCIBusCfg);
- dev->base_addr = (unsigned long)ioaddr;
- dev->irq = irq;
-
np = netdev_priv(dev);
np->pci_dev = pdev;
np->chip_id = chip_idx;
@@ -635,17 +632,18 @@ static int netdev_open(struct net_device *dev)
{
struct netdev_private *np = netdev_priv(dev);
void __iomem *ioaddr = np->base_addr;
+ const int irq = np->pci_dev->irq;
int i;
iowrite32(0x00000001, ioaddr + PCIBusCfg); /* Reset */
netif_device_detach(dev);
- i = request_irq(dev->irq, intr_handler, IRQF_SHARED, dev->name, dev);
+ i = request_irq(irq, intr_handler, IRQF_SHARED, dev->name, dev);
if (i)
goto out_err;
if (debug > 1)
- netdev_dbg(dev, "w89c840_open() irq %d\n", dev->irq);
+ netdev_dbg(dev, "w89c840_open() irq %d\n", irq);
if((i=alloc_ringdesc(dev)))
goto out_err;
@@ -932,6 +930,7 @@ static void tx_timeout(struct net_device *dev)
{
struct netdev_private *np = netdev_priv(dev);
void __iomem *ioaddr = np->base_addr;
+ const int irq = np->pci_dev->irq;
dev_warn(&dev->dev, "Transmit timed out, status %08x, resetting...\n",
ioread32(ioaddr + IntrStatus));
@@ -951,7 +950,7 @@ static void tx_timeout(struct net_device *dev)
np->cur_tx, np->dirty_tx, np->tx_full, np->tx_q_bytes);
printk(KERN_DEBUG "Tx Descriptor addr %xh\n", ioread32(ioaddr+0x4C));
- disable_irq(dev->irq);
+ disable_irq(irq);
spin_lock_irq(&np->lock);
/*
* Under high load dirty_tx and the internal tx descriptor pointer
@@ -966,7 +965,7 @@ static void tx_timeout(struct net_device *dev)
init_rxtx_rings(dev);
init_registers(dev);
spin_unlock_irq(&np->lock);
- enable_irq(dev->irq);
+ enable_irq(irq);
netif_wake_queue(dev);
dev->trans_start = jiffies; /* prevent tx timeout */
@@ -1500,7 +1499,7 @@ static int netdev_close(struct net_device *dev)
iowrite32(0x0000, ioaddr + IntrEnable);
spin_unlock_irq(&np->lock);
- free_irq(dev->irq, dev);
+ free_irq(np->pci_dev->irq, dev);
wmb();
netif_device_attach(dev);
@@ -1589,7 +1588,7 @@ static int w840_suspend (struct pci_dev *pdev, pm_message_t state)
iowrite32(0, ioaddr + IntrEnable);
spin_unlock_irq(&np->lock);
- synchronize_irq(dev->irq);
+ synchronize_irq(np->pci_dev->irq);
netif_tx_disable(dev);
np->stats.rx_missed_errors += ioread32(ioaddr + RxMissed) & 0xffff;
--
1.7.7.6
^ permalink raw reply related
* [PATCH net-next #2 15/39] starfire: stop using net_device.{base_addr, irq}.
From: Francois Romieu @ 2012-04-06 10:06 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Ion Badulescu
In-Reply-To: <1333704408.git.romieu@fr.zoreil.com>
It's useless to check mem_start on a newly allocated device as well.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Ion Badulescu <ionut@badula.org>
---
drivers/net/ethernet/adaptec/starfire.c | 14 +++++---------
1 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/adaptec/starfire.c b/drivers/net/ethernet/adaptec/starfire.c
index d896816..4f27bff 100644
--- a/drivers/net/ethernet/adaptec/starfire.c
+++ b/drivers/net/ethernet/adaptec/starfire.c
@@ -753,9 +753,6 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
/* wait a little longer */
udelay(1000);
- dev->base_addr = (unsigned long)base;
- dev->irq = irq;
-
np = netdev_priv(dev);
np->dev = dev;
np->base = base;
@@ -773,8 +770,6 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
drv_flags = netdrv_tbl[chip_idx].drv_flags;
option = card_idx < MAX_UNITS ? options[card_idx] : 0;
- if (dev->mem_start)
- option = dev->mem_start;
/* The lower four bits are the media type. */
if (option & 0x200)
@@ -909,13 +904,14 @@ static int netdev_open(struct net_device *dev)
const __be32 *fw_rx_data, *fw_tx_data;
struct netdev_private *np = netdev_priv(dev);
void __iomem *ioaddr = np->base;
+ const int irq = np->pci_dev->irq;
int i, retval;
size_t tx_size, rx_size;
size_t tx_done_q_size, rx_done_q_size, tx_ring_size, rx_ring_size;
/* Do we ever need to reset the chip??? */
- retval = request_irq(dev->irq, intr_handler, IRQF_SHARED, dev->name, dev);
+ retval = request_irq(irq, intr_handler, IRQF_SHARED, dev->name, dev);
if (retval)
return retval;
@@ -924,7 +920,7 @@ static int netdev_open(struct net_device *dev)
writel(1, ioaddr + PCIDeviceConfig);
if (debug > 1)
printk(KERN_DEBUG "%s: netdev_open() irq %d.\n",
- dev->name, dev->irq);
+ dev->name, irq);
/* Allocate the various queues. */
if (!np->queue_mem) {
@@ -935,7 +931,7 @@ static int netdev_open(struct net_device *dev)
np->queue_mem_size = tx_done_q_size + rx_done_q_size + tx_ring_size + rx_ring_size;
np->queue_mem = pci_alloc_consistent(np->pci_dev, np->queue_mem_size, &np->queue_mem_dma);
if (np->queue_mem == NULL) {
- free_irq(dev->irq, dev);
+ free_irq(irq, dev);
return -ENOMEM;
}
@@ -1962,7 +1958,7 @@ static int netdev_close(struct net_device *dev)
}
}
- free_irq(dev->irq, dev);
+ free_irq(np->pci_dev->irq, dev);
/* Free all the skbuffs in the Rx queue. */
for (i = 0; i < RX_RING_SIZE; i++) {
--
1.7.7.6
^ permalink raw reply related
* [PATCH net-next #2 01/39] sungem: stop using net_device.{base_addr, irq}.
From: Francois Romieu @ 2012-04-06 10:06 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <1333704408.git.romieu@fr.zoreil.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/ethernet/sun/sungem.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c
index ba04159..8707d59 100644
--- a/drivers/net/ethernet/sun/sungem.c
+++ b/drivers/net/ethernet/sun/sungem.c
@@ -2899,7 +2899,6 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
}
gp->pdev = pdev;
- dev->base_addr = (long) pdev;
gp->dev = dev;
gp->msg_enable = DEFAULT_MSG;
@@ -2973,7 +2972,6 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
netif_napi_add(dev, &gp->napi, gem_poll, 64);
dev->ethtool_ops = &gem_ethtool_ops;
dev->watchdog_timeo = 5 * HZ;
- dev->irq = pdev->irq;
dev->dma = 0;
/* Set that now, in case PM kicks in now */
--
1.7.7.6
^ permalink raw reply related
* [PATCH net-next #2 06/39] hamachi: stop using net_device.{base_addr, irq}.
From: Francois Romieu @ 2012-04-06 10:06 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <1333704408.git.romieu@fr.zoreil.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/ethernet/packetengines/hamachi.c | 11 +++--------
1 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/packetengines/hamachi.c b/drivers/net/ethernet/packetengines/hamachi.c
index 0d29f5f..c236715 100644
--- a/drivers/net/ethernet/packetengines/hamachi.c
+++ b/drivers/net/ethernet/packetengines/hamachi.c
@@ -683,8 +683,6 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev,
}
hmp->base = ioaddr;
- dev->base_addr = (unsigned long)ioaddr;
- dev->irq = irq;
pci_set_drvdata(pdev, dev);
hmp->chip_id = chip_id;
@@ -859,14 +857,11 @@ static int hamachi_open(struct net_device *dev)
u32 rx_int_var, tx_int_var;
u16 fifo_info;
- i = request_irq(dev->irq, hamachi_interrupt, IRQF_SHARED, dev->name, dev);
+ i = request_irq(hmp->pci_dev->irq, hamachi_interrupt, IRQF_SHARED,
+ dev->name, dev);
if (i)
return i;
- if (hamachi_debug > 1)
- printk(KERN_DEBUG "%s: hamachi_open() irq %d.\n",
- dev->name, dev->irq);
-
hamachi_init_ring(dev);
#if ADDRLEN == 64
@@ -1705,7 +1700,7 @@ static int hamachi_close(struct net_device *dev)
}
#endif /* __i386__ debugging only */
- free_irq(dev->irq, dev);
+ free_irq(hmp->pci_dev->irq, dev);
del_timer_sync(&hmp->timer);
--
1.7.7.6
^ permalink raw reply related
* [PATCH net-next #2 03/39] forcedeth: stop using net_device.{base_addr, irq}.
From: Francois Romieu @ 2012-04-06 10:06 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <1333704408.git.romieu@fr.zoreil.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/ethernet/nvidia/forcedeth.c | 5 -----
1 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index 8561dd2..84952b3 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -3943,13 +3943,11 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
ret = pci_enable_msi(np->pci_dev);
if (ret == 0) {
np->msi_flags |= NV_MSI_ENABLED;
- dev->irq = np->pci_dev->irq;
if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) {
netdev_info(dev, "request_irq failed %d\n",
ret);
pci_disable_msi(np->pci_dev);
np->msi_flags &= ~NV_MSI_ENABLED;
- dev->irq = np->pci_dev->irq;
goto out_err;
}
@@ -5650,9 +5648,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
np->base = ioremap(addr, np->register_size);
if (!np->base)
goto out_relreg;
- dev->base_addr = (unsigned long)np->base;
-
- dev->irq = pci_dev->irq;
np->rx_ring_size = RX_RING_DEFAULT;
np->tx_ring_size = TX_RING_DEFAULT;
--
1.7.7.6
^ permalink raw reply related
* [PATCH net-next #2 17/39] bnx2: stop using net_device.{base_addr, irq}.
From: Francois Romieu @ 2012-04-06 10:06 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Michael Chan
In-Reply-To: <1333704408.git.romieu@fr.zoreil.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/bnx2.c | 41 +++++++++++----------------------
1 files changed, 14 insertions(+), 27 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index 8297e28..36037a6 100644
--- a/drivers/net/ethernet/broadcom/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -7976,7 +7976,6 @@ static int __devinit
bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
{
struct bnx2 *bp;
- unsigned long mem_len;
int rc, i, j;
u32 reg;
u64 dma_mask, persist_dma_mask;
@@ -8036,13 +8035,8 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
#endif
INIT_WORK(&bp->reset_task, bnx2_reset_task);
- dev->base_addr = dev->mem_start = pci_resource_start(pdev, 0);
- mem_len = MB_GET_CID_ADDR(TX_TSS_CID + TX_MAX_TSS_RINGS + 1);
- dev->mem_end = dev->mem_start + mem_len;
- dev->irq = pdev->irq;
-
- bp->regview = ioremap_nocache(dev->base_addr, mem_len);
-
+ bp->regview = pci_iomap(pdev, 0, MB_GET_CID_ADDR(TX_TSS_CID +
+ TX_MAX_TSS_RINGS + 1));
if (!bp->regview) {
dev_err(&pdev->dev, "Cannot map register space, aborting\n");
rc = -ENOMEM;
@@ -8346,10 +8340,8 @@ err_out_unmap:
bp->flags &= ~BNX2_FLAG_AER_ENABLED;
}
- if (bp->regview) {
- iounmap(bp->regview);
- bp->regview = NULL;
- }
+ pci_iounmap(pdev, bp->regview);
+ bp->regview = NULL;
err_out_release:
pci_release_regions(pdev);
@@ -8432,7 +8424,7 @@ static int __devinit
bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int version_printed = 0;
- struct net_device *dev = NULL;
+ struct net_device *dev;
struct bnx2 *bp;
int rc;
char str[40];
@@ -8442,15 +8434,12 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* dev zeroed in init_etherdev */
dev = alloc_etherdev_mq(sizeof(*bp), TX_MAX_RINGS);
-
if (!dev)
return -ENOMEM;
rc = bnx2_init_board(pdev, dev);
- if (rc < 0) {
- free_netdev(dev);
- return rc;
- }
+ if (rc < 0)
+ goto err_free;
dev->netdev_ops = &bnx2_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
@@ -8480,22 +8469,21 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
goto error;
}
- netdev_info(dev, "%s (%c%d) %s found at mem %lx, IRQ %d, node addr %pM\n",
- board_info[ent->driver_data].name,
+ netdev_info(dev, "%s (%c%d) %s found at mem %lx, IRQ %d, "
+ "node addr %pM\n", board_info[ent->driver_data].name,
((CHIP_ID(bp) & 0xf000) >> 12) + 'A',
((CHIP_ID(bp) & 0x0ff0) >> 4),
- bnx2_bus_string(bp, str),
- dev->base_addr,
- bp->pdev->irq, dev->dev_addr);
+ bnx2_bus_string(bp, str), (long)pci_resource_start(pdev, 0),
+ pdev->irq, dev->dev_addr);
return 0;
error:
- if (bp->regview)
- iounmap(bp->regview);
+ iounmap(bp->regview);
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
+err_free:
free_netdev(dev);
return rc;
}
@@ -8511,8 +8499,7 @@ bnx2_remove_one(struct pci_dev *pdev)
del_timer_sync(&bp->timer);
cancel_work_sync(&bp->reset_task);
- if (bp->regview)
- iounmap(bp->regview);
+ pci_iounmap(bp->pdev, bp->regview);
kfree(bp->temp_stats_blk);
--
1.7.7.6
^ permalink raw reply related
* [PATCH net-next #2 36/39] rrunner: stop using net_device.{base_addr, irq}.
From: Francois Romieu @ 2012-04-06 10:06 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <1333704408.git.romieu@fr.zoreil.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/hippi/rrunner.c | 82 ++++++++++++++++++------------------------
1 files changed, 35 insertions(+), 47 deletions(-)
diff --git a/drivers/net/hippi/rrunner.c b/drivers/net/hippi/rrunner.c
index 2a51363..248c4f1 100644
--- a/drivers/net/hippi/rrunner.c
+++ b/drivers/net/hippi/rrunner.c
@@ -114,10 +114,9 @@ static int __devinit rr_init_one(struct pci_dev *pdev,
SET_NETDEV_DEV(dev, &pdev->dev);
- if (pci_request_regions(pdev, "rrunner")) {
- ret = -EIO;
+ ret = pci_request_regions(pdev, "rrunner");
+ if (ret < 0)
goto out;
- }
pci_set_drvdata(pdev, dev);
@@ -125,11 +124,8 @@ static int __devinit rr_init_one(struct pci_dev *pdev,
spin_lock_init(&rrpriv->lock);
- dev->irq = pdev->irq;
dev->netdev_ops = &rr_netdev_ops;
- dev->base_addr = pci_resource_start(pdev, 0);
-
/* display version info if adapter is found */
if (!version_disp) {
/* set display flag to TRUE so that */
@@ -147,16 +143,14 @@ static int __devinit rr_init_one(struct pci_dev *pdev,
pci_set_master(pdev);
printk(KERN_INFO "%s: Essential RoadRunner serial HIPPI "
- "at 0x%08lx, irq %i, PCI latency %i\n", dev->name,
- dev->base_addr, dev->irq, pci_latency);
+ "at 0x%08llx, irq %i, PCI latency %i\n", dev->name,
+ pci_resource_start(pdev, 0), pdev->irq, pci_latency);
/*
- * Remap the regs into kernel space.
+ * Remap the MMIO regs into kernel space.
*/
-
- rrpriv->regs = ioremap(dev->base_addr, 0x1000);
-
- if (!rrpriv->regs){
+ rrpriv->regs = pci_iomap(pdev, 0, 0x1000);
+ if (!rrpriv->regs) {
printk(KERN_ERR "%s: Unable to map I/O register, "
"RoadRunner will be disabled.\n", dev->name);
ret = -EIO;
@@ -203,8 +197,6 @@ static int __devinit rr_init_one(struct pci_dev *pdev,
rr_init(dev);
- dev->base_addr = 0;
-
ret = register_netdev(dev);
if (ret)
goto out;
@@ -218,7 +210,7 @@ static int __devinit rr_init_one(struct pci_dev *pdev,
pci_free_consistent(pdev, TX_TOTAL_SIZE, rrpriv->tx_ring,
rrpriv->tx_ring_dma);
if (rrpriv->regs)
- iounmap(rrpriv->regs);
+ pci_iounmap(pdev, rrpriv->regs);
if (pdev) {
pci_release_regions(pdev);
pci_set_drvdata(pdev, NULL);
@@ -232,29 +224,26 @@ static int __devinit rr_init_one(struct pci_dev *pdev,
static void __devexit rr_remove_one (struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
+ struct rr_private *rr = netdev_priv(dev);
- if (dev) {
- struct rr_private *rr = netdev_priv(dev);
-
- if (!(readl(&rr->regs->HostCtrl) & NIC_HALTED)){
- printk(KERN_ERR "%s: trying to unload running NIC\n",
- dev->name);
- writel(HALT_NIC, &rr->regs->HostCtrl);
- }
-
- pci_free_consistent(pdev, EVT_RING_SIZE, rr->evt_ring,
- rr->evt_ring_dma);
- pci_free_consistent(pdev, RX_TOTAL_SIZE, rr->rx_ring,
- rr->rx_ring_dma);
- pci_free_consistent(pdev, TX_TOTAL_SIZE, rr->tx_ring,
- rr->tx_ring_dma);
- unregister_netdev(dev);
- iounmap(rr->regs);
- free_netdev(dev);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
+ if (!(readl(&rr->regs->HostCtrl) & NIC_HALTED)) {
+ printk(KERN_ERR "%s: trying to unload running NIC\n",
+ dev->name);
+ writel(HALT_NIC, &rr->regs->HostCtrl);
}
+
+ unregister_netdev(dev);
+ pci_free_consistent(pdev, EVT_RING_SIZE, rr->evt_ring,
+ rr->evt_ring_dma);
+ pci_free_consistent(pdev, RX_TOTAL_SIZE, rr->rx_ring,
+ rr->rx_ring_dma);
+ pci_free_consistent(pdev, TX_TOTAL_SIZE, rr->tx_ring,
+ rr->tx_ring_dma);
+ pci_iounmap(pdev, rr->regs);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+ free_netdev(dev);
}
@@ -1230,9 +1219,9 @@ static int rr_open(struct net_device *dev)
readl(®s->HostCtrl);
spin_unlock_irqrestore(&rrpriv->lock, flags);
- if (request_irq(dev->irq, rr_interrupt, IRQF_SHARED, dev->name, dev)) {
+ if (request_irq(pdev->irq, rr_interrupt, IRQF_SHARED, dev->name, dev)) {
printk(KERN_WARNING "%s: Requested IRQ %d is busy\n",
- dev->name, dev->irq);
+ dev->name, pdev->irq);
ecode = -EAGAIN;
goto error;
}
@@ -1339,16 +1328,15 @@ static void rr_dump(struct net_device *dev)
static int rr_close(struct net_device *dev)
{
- struct rr_private *rrpriv;
- struct rr_regs __iomem *regs;
+ struct rr_private *rrpriv = netdev_priv(dev);
+ struct rr_regs __iomem *regs = rrpriv->regs;
+ struct pci_dev *pdev = rrpriv->pci_dev;
unsigned long flags;
u32 tmp;
short i;
netif_stop_queue(dev);
- rrpriv = netdev_priv(dev);
- regs = rrpriv->regs;
/*
* Lock to make sure we are not cleaning up while another CPU
@@ -1387,15 +1375,15 @@ static int rr_close(struct net_device *dev)
rr_raz_tx(rrpriv, dev);
rr_raz_rx(rrpriv, dev);
- pci_free_consistent(rrpriv->pci_dev, 256 * sizeof(struct ring_ctrl),
+ pci_free_consistent(pdev, 256 * sizeof(struct ring_ctrl),
rrpriv->rx_ctrl, rrpriv->rx_ctrl_dma);
rrpriv->rx_ctrl = NULL;
- pci_free_consistent(rrpriv->pci_dev, sizeof(struct rr_info),
- rrpriv->info, rrpriv->info_dma);
+ pci_free_consistent(pdev, sizeof(struct rr_info), rrpriv->info,
+ rrpriv->info_dma);
rrpriv->info = NULL;
- free_irq(dev->irq, dev);
+ free_irq(pdev->irq, dev);
spin_unlock_irqrestore(&rrpriv->lock, flags);
return 0;
--
1.7.7.6
^ permalink raw reply related
* [PATCH net-next #2 29/39] 8139too: dev->{base_addr, irq} removal.
From: Francois Romieu @ 2012-04-06 10:06 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <1333704408.git.romieu@fr.zoreil.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/ethernet/realtek/8139too.c | 136 +++++++++++++-------------------
1 files changed, 56 insertions(+), 80 deletions(-)
diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c
index df7fd8d..03df076 100644
--- a/drivers/net/ethernet/realtek/8139too.c
+++ b/drivers/net/ethernet/realtek/8139too.c
@@ -148,9 +148,9 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
/* Whether to use MMIO or PIO. Default to MMIO. */
#ifdef CONFIG_8139TOO_PIO
-static int use_io = 1;
+static bool use_io = true;
#else
-static int use_io = 0;
+static bool use_io = false;
#endif
/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
@@ -620,7 +620,7 @@ MODULE_DESCRIPTION ("RealTek RTL-8139 Fast Ethernet driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
-module_param(use_io, int, 0);
+module_param(use_io, bool, 0);
MODULE_PARM_DESC(use_io, "Force use of I/O access mode. 0=MMIO 1=PIO");
module_param(multicast_filter_limit, int, 0);
module_param_array(media, int, NULL, 0);
@@ -750,15 +750,22 @@ static void rtl8139_chip_reset (void __iomem *ioaddr)
static __devinit struct net_device * rtl8139_init_board (struct pci_dev *pdev)
{
+ struct device *d = &pdev->dev;
void __iomem *ioaddr;
struct net_device *dev;
struct rtl8139_private *tp;
u8 tmp8;
int rc, disable_dev_on_err = 0;
- unsigned int i;
- unsigned long pio_start, pio_end, pio_flags, pio_len;
- unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
+ unsigned int i, bar;
+ unsigned long io_len;
u32 version;
+ static const struct {
+ unsigned long mask;
+ char *type;
+ } res[] = {
+ { IORESOURCE_IO, "PIO" },
+ { IORESOURCE_MEM, "MMIO" }
+ };
assert (pdev != NULL);
@@ -777,78 +784,45 @@ static __devinit struct net_device * rtl8139_init_board (struct pci_dev *pdev)
if (rc)
goto err_out;
- pio_start = pci_resource_start (pdev, 0);
- pio_end = pci_resource_end (pdev, 0);
- pio_flags = pci_resource_flags (pdev, 0);
- pio_len = pci_resource_len (pdev, 0);
-
- mmio_start = pci_resource_start (pdev, 1);
- mmio_end = pci_resource_end (pdev, 1);
- mmio_flags = pci_resource_flags (pdev, 1);
- mmio_len = pci_resource_len (pdev, 1);
-
- /* set this immediately, we need to know before
- * we talk to the chip directly */
- pr_debug("PIO region size == 0x%02lX\n", pio_len);
- pr_debug("MMIO region size == 0x%02lX\n", mmio_len);
-
-retry:
- if (use_io) {
- /* make sure PCI base addr 0 is PIO */
- if (!(pio_flags & IORESOURCE_IO)) {
- dev_err(&pdev->dev, "region #0 not a PIO resource, aborting\n");
- rc = -ENODEV;
- goto err_out;
- }
- /* check for weird/broken PCI region reporting */
- if (pio_len < RTL_MIN_IO_SIZE) {
- dev_err(&pdev->dev, "Invalid PCI I/O region size(s), aborting\n");
- rc = -ENODEV;
- goto err_out;
- }
- } else {
- /* make sure PCI base addr 1 is MMIO */
- if (!(mmio_flags & IORESOURCE_MEM)) {
- dev_err(&pdev->dev, "region #1 not an MMIO resource, aborting\n");
- rc = -ENODEV;
- goto err_out;
- }
- if (mmio_len < RTL_MIN_IO_SIZE) {
- dev_err(&pdev->dev, "Invalid PCI mem region size(s), aborting\n");
- rc = -ENODEV;
- goto err_out;
- }
- }
-
rc = pci_request_regions (pdev, DRV_NAME);
if (rc)
goto err_out;
disable_dev_on_err = 1;
- /* enable PCI bus-mastering */
pci_set_master (pdev);
- if (use_io) {
- ioaddr = pci_iomap(pdev, 0, 0);
- if (!ioaddr) {
- dev_err(&pdev->dev, "cannot map PIO, aborting\n");
- rc = -EIO;
- goto err_out;
- }
- dev->base_addr = pio_start;
- tp->regs_len = pio_len;
- } else {
- /* ioremap MMIO region */
- ioaddr = pci_iomap(pdev, 1, 0);
- if (ioaddr == NULL) {
- dev_err(&pdev->dev, "cannot remap MMIO, trying PIO\n");
- pci_release_regions(pdev);
- use_io = 1;
+retry:
+ /* PIO bar register comes first. */
+ bar = !use_io;
+
+ io_len = pci_resource_len(pdev, bar);
+
+ dev_dbg(d, "%s region size = 0x%02lX\n", res[bar].type, io_len);
+
+ if (!(pci_resource_flags(pdev, bar) & res[bar].mask)) {
+ dev_err(d, "region #%d not a %s resource, aborting\n", bar,
+ res[bar].type);
+ rc = -ENODEV;
+ goto err_out;
+ }
+ if (io_len < RTL_MIN_IO_SIZE) {
+ dev_err(d, "Invalid PCI %s region size(s), aborting\n",
+ res[bar].type);
+ rc = -ENODEV;
+ goto err_out;
+ }
+
+ ioaddr = pci_iomap(pdev, bar, 0);
+ if (!ioaddr) {
+ dev_err(d, "cannot map %s\n", res[bar].type);
+ if (!use_io) {
+ use_io = true;
goto retry;
}
- dev->base_addr = (long) ioaddr;
- tp->regs_len = mmio_len;
+ rc = -ENODEV;
+ goto err_out;
}
+ tp->regs_len = io_len;
tp->mmio_addr = ioaddr;
/* Bring old chips out of low-power mode. */
@@ -1035,8 +1009,6 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
dev->hw_features |= NETIF_F_RXALL;
dev->hw_features |= NETIF_F_RXFCS;
- dev->irq = pdev->irq;
-
/* tp zeroed and aligned in alloc_etherdev */
tp = netdev_priv(dev);
@@ -1062,9 +1034,9 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
pci_set_drvdata (pdev, dev);
- netdev_info(dev, "%s at 0x%lx, %pM, IRQ %d\n",
+ netdev_info(dev, "%s at 0x%p, %pM, IRQ %d\n",
board_info[ent->driver_data].name,
- dev->base_addr, dev->dev_addr, dev->irq);
+ ioaddr, dev->dev_addr, pdev->irq);
netdev_dbg(dev, "Identified 8139 chip type '%s'\n",
rtl_chip_info[tp->chipset].name);
@@ -1339,10 +1311,11 @@ static void mdio_write (struct net_device *dev, int phy_id, int location,
static int rtl8139_open (struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
- int retval;
void __iomem *ioaddr = tp->mmio_addr;
+ const int irq = tp->pci_dev->irq;
+ int retval;
- retval = request_irq (dev->irq, rtl8139_interrupt, IRQF_SHARED, dev->name, dev);
+ retval = request_irq(irq, rtl8139_interrupt, IRQF_SHARED, dev->name, dev);
if (retval)
return retval;
@@ -1351,7 +1324,7 @@ static int rtl8139_open (struct net_device *dev)
tp->rx_ring = dma_alloc_coherent(&tp->pci_dev->dev, RX_BUF_TOT_LEN,
&tp->rx_ring_dma, GFP_KERNEL);
if (tp->tx_bufs == NULL || tp->rx_ring == NULL) {
- free_irq(dev->irq, dev);
+ free_irq(irq, dev);
if (tp->tx_bufs)
dma_free_coherent(&tp->pci_dev->dev, TX_BUF_TOT_LEN,
@@ -1377,7 +1350,7 @@ static int rtl8139_open (struct net_device *dev)
"%s() ioaddr %#llx IRQ %d GP Pins %02x %s-duplex\n",
__func__,
(unsigned long long)pci_resource_start (tp->pci_dev, 1),
- dev->irq, RTL_R8 (MediaStatus),
+ irq, RTL_R8 (MediaStatus),
tp->mii.full_duplex ? "full" : "half");
rtl8139_start_thread(tp);
@@ -2240,9 +2213,12 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
*/
static void rtl8139_poll_controller(struct net_device *dev)
{
- disable_irq(dev->irq);
- rtl8139_interrupt(dev->irq, dev);
- enable_irq(dev->irq);
+ struct rtl8139_private *tp = netdev_priv(dev);
+ const int irq = tp->pci_dev->irq;
+
+ disable_irq(irq);
+ rtl8139_interrupt(irq, dev);
+ enable_irq(irq);
}
#endif
@@ -2295,7 +2271,7 @@ static int rtl8139_close (struct net_device *dev)
spin_unlock_irqrestore (&tp->lock, flags);
- free_irq (dev->irq, dev);
+ free_irq(tp->pci_dev->irq, dev);
rtl8139_tx_clear (tp);
--
1.7.7.6
^ permalink raw reply related
* [PATCH net-next #2 05/39] via-rhine: stop using net_device.{base_addr, irq}.
From: Francois Romieu @ 2012-04-06 10:06 UTC (permalink / raw)
To: netdev; +Cc: David Miller, David Lv
In-Reply-To: <1333704408.git.romieu@fr.zoreil.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: David Lv <DavidLv@viatech.com.cn>
---
drivers/net/ethernet/via/via-rhine.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 39b8cf3..47b411f 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -687,9 +687,12 @@ static void __devinit rhine_reload_eeprom(long pioaddr, struct net_device *dev)
#ifdef CONFIG_NET_POLL_CONTROLLER
static void rhine_poll(struct net_device *dev)
{
- disable_irq(dev->irq);
- rhine_interrupt(dev->irq, (void *)dev);
- enable_irq(dev->irq);
+ struct rhine_private *rp = netdev_priv(dev);
+ const int irq = rp->pdev->irq;
+
+ disable_irq(irq);
+ rhine_interrupt(irq, dev);
+ enable_irq(irq);
}
#endif
@@ -970,7 +973,6 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
}
#endif /* USE_MMIO */
- dev->base_addr = (unsigned long)ioaddr;
rp->base = ioaddr;
/* Get chip registers into a sane state */
@@ -993,8 +995,6 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
if (!phy_id)
phy_id = ioread8(ioaddr + 0x6C);
- dev->irq = pdev->irq;
-
spin_lock_init(&rp->lock);
mutex_init(&rp->task_lock);
INIT_WORK(&rp->reset_task, rhine_reset_task);
--
1.7.7.6
^ permalink raw reply related
* [PATCH net-next #2 30/39] dl2k: stop using net_device.{base_addr, irq} and convert to __iomem.
From: Francois Romieu @ 2012-04-06 10:06 UTC (permalink / raw)
To: netdev; +Cc: David Miller
In-Reply-To: <1333704408.git.romieu@fr.zoreil.com>
The eeprom registers always use the same PCI bar whereas the general
registers may either use the same mapping as the eeprom registers or
a different one. It is thus possible to simplify parse_eeprom().
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/ethernet/dlink/dl2k.c | 416 ++++++++++++++++++-------------------
drivers/net/ethernet/dlink/dl2k.h | 19 +--
2 files changed, 209 insertions(+), 226 deletions(-)
diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
index b2dc2c8..ef4499d 100644
--- a/drivers/net/ethernet/dlink/dl2k.c
+++ b/drivers/net/ethernet/dlink/dl2k.c
@@ -16,6 +16,13 @@
#include "dl2k.h"
#include <linux/dma-mapping.h>
+#define dw32(reg, val) iowrite32(val, ioaddr + (reg))
+#define dw16(reg, val) iowrite16(val, ioaddr + (reg))
+#define dw8(reg, val) iowrite8(val, ioaddr + (reg))
+#define dr32(reg) ioread32(ioaddr + (reg))
+#define dr16(reg) ioread16(ioaddr + (reg))
+#define dr8(reg) ioread8(ioaddr + (reg))
+
static char version[] __devinitdata =
KERN_INFO DRV_NAME " " DRV_VERSION " " DRV_RELDATE "\n";
#define MAX_UNITS 8
@@ -49,8 +56,13 @@ module_param(tx_coalesce, int, 0); /* HW xmit count each TxDMAComplete */
/* Enable the default interrupts */
#define DEFAULT_INTR (RxDMAComplete | HostError | IntRequested | TxDMAComplete| \
UpdateStats | LinkEvent)
-#define EnableInt() \
-writew(DEFAULT_INTR, ioaddr + IntEnable)
+
+static void dl2k_enable_int(struct netdev_private *np)
+{
+ void __iomem *ioaddr = np->ioaddr;
+
+ dw16(IntEnable, DEFAULT_INTR);
+}
static const int max_intrloop = 50;
static const int multicast_filter_limit = 0x40;
@@ -73,7 +85,7 @@ static int rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
static int rio_close (struct net_device *dev);
static int find_miiphy (struct net_device *dev);
static int parse_eeprom (struct net_device *dev);
-static int read_eeprom (long ioaddr, int eep_addr);
+static int read_eeprom (struct netdev_private *, int eep_addr);
static int mii_wait_link (struct net_device *dev, int wait);
static int mii_set_media (struct net_device *dev);
static int mii_get_media (struct net_device *dev);
@@ -106,7 +118,7 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
static int card_idx;
int chip_idx = ent->driver_data;
int err, irq;
- long ioaddr;
+ void __iomem *ioaddr;
static int version_printed;
void *ring_space;
dma_addr_t ring_dma;
@@ -124,26 +136,29 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_disable;
pci_set_master (pdev);
+
+ err = -ENOMEM;
+
dev = alloc_etherdev (sizeof (*np));
- if (!dev) {
- err = -ENOMEM;
+ if (!dev)
goto err_out_res;
- }
SET_NETDEV_DEV(dev, &pdev->dev);
-#ifdef MEM_MAPPING
- ioaddr = pci_resource_start (pdev, 1);
- ioaddr = (long) ioremap (ioaddr, RIO_IO_SIZE);
- if (!ioaddr) {
- err = -ENOMEM;
+ np = netdev_priv(dev);
+
+ /* IO registers range. */
+ ioaddr = pci_iomap(pdev, 0, 0);
+ if (!ioaddr)
goto err_out_dev;
- }
-#else
- ioaddr = pci_resource_start (pdev, 0);
+ np->eeprom_addr = ioaddr;
+
+#ifdef MEM_MAPPING
+ /* MM registers range. */
+ ioaddr = pci_iomap(pdev, 1, 0);
+ if (!ioaddr)
+ goto err_out_iounmap;
#endif
- dev->base_addr = ioaddr;
- dev->irq = irq;
- np = netdev_priv(dev);
+ np->ioaddr = ioaddr;
np->chip_id = chip_idx;
np->pdev = pdev;
spin_lock_init (&np->tx_lock);
@@ -239,7 +254,7 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_unmap_rx;
/* Fiber device? */
- np->phy_media = (readw(ioaddr + ASICCtrl) & PhyMedia) ? 1 : 0;
+ np->phy_media = (dr16(ASICCtrl) & PhyMedia) ? 1 : 0;
np->link_status = 0;
/* Set media and reset PHY */
if (np->phy_media) {
@@ -276,22 +291,20 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
printk(KERN_INFO "vlan(id):\t%d\n", np->vlan);
return 0;
- err_out_unmap_rx:
+err_out_unmap_rx:
pci_free_consistent (pdev, RX_TOTAL_SIZE, np->rx_ring, np->rx_ring_dma);
- err_out_unmap_tx:
+err_out_unmap_tx:
pci_free_consistent (pdev, TX_TOTAL_SIZE, np->tx_ring, np->tx_ring_dma);
- err_out_iounmap:
+err_out_iounmap:
#ifdef MEM_MAPPING
- iounmap ((void *) ioaddr);
-
- err_out_dev:
+ pci_iounmap(pdev, np->ioaddr);
#endif
+ pci_iounmap(pdev, np->eeprom_addr);
+err_out_dev:
free_netdev (dev);
-
- err_out_res:
+err_out_res:
pci_release_regions (pdev);
-
- err_out_disable:
+err_out_disable:
pci_disable_device (pdev);
return err;
}
@@ -299,11 +312,9 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
static int
find_miiphy (struct net_device *dev)
{
+ struct netdev_private *np = netdev_priv(dev);
int i, phy_found = 0;
- struct netdev_private *np;
- long ioaddr;
np = netdev_priv(dev);
- ioaddr = dev->base_addr;
np->phy_addr = 1;
for (i = 31; i >= 0; i--) {
@@ -323,26 +334,19 @@ find_miiphy (struct net_device *dev)
static int
parse_eeprom (struct net_device *dev)
{
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
int i, j;
- long ioaddr = dev->base_addr;
u8 sromdata[256];
u8 *psib;
u32 crc;
PSROM_t psrom = (PSROM_t) sromdata;
- struct netdev_private *np = netdev_priv(dev);
int cid, next;
-#ifdef MEM_MAPPING
- ioaddr = pci_resource_start (np->pdev, 0);
-#endif
- /* Read eeprom */
- for (i = 0; i < 128; i++) {
- ((__le16 *) sromdata)[i] = cpu_to_le16(read_eeprom (ioaddr, i));
- }
-#ifdef MEM_MAPPING
- ioaddr = dev->base_addr;
-#endif
+ for (i = 0; i < 128; i++)
+ ((__le16 *) sromdata)[i] = cpu_to_le16(read_eeprom(np, i));
+
if (np->pdev->vendor == PCI_VENDOR_ID_DLINK) { /* D-Link Only */
/* Check CRC */
crc = ~ether_crc_le (256 - 4, sromdata);
@@ -378,8 +382,7 @@ parse_eeprom (struct net_device *dev)
return 0;
case 2: /* Duplex Polarity */
np->duplex_polarity = psib[i];
- writeb (readb (ioaddr + PhyCtrl) | psib[i],
- ioaddr + PhyCtrl);
+ dw8(PhyCtrl, dr8(PhyCtrl) | psib[i]);
break;
case 3: /* Wake Polarity */
np->wake_polarity = psib[i];
@@ -407,59 +410,57 @@ static int
rio_open (struct net_device *dev)
{
struct netdev_private *np = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = np->ioaddr;
+ const int irq = np->pdev->irq;
int i;
u16 macctrl;
- i = request_irq (dev->irq, rio_interrupt, IRQF_SHARED, dev->name, dev);
+ i = request_irq(irq, rio_interrupt, IRQF_SHARED, dev->name, dev);
if (i)
return i;
/* Reset all logic functions */
- writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset,
- ioaddr + ASICCtrl + 2);
+ dw16(ASICCtrl + 2,
+ GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset);
mdelay(10);
/* DebugCtrl bit 4, 5, 9 must set */
- writel (readl (ioaddr + DebugCtrl) | 0x0230, ioaddr + DebugCtrl);
+ dw32(DebugCtrl, dr32(DebugCtrl) | 0x0230);
/* Jumbo frame */
if (np->jumbo != 0)
- writew (MAX_JUMBO+14, ioaddr + MaxFrameSize);
+ dw16(MaxFrameSize, MAX_JUMBO+14);
alloc_list (dev);
/* Get station address */
for (i = 0; i < 6; i++)
- writeb (dev->dev_addr[i], ioaddr + StationAddr0 + i);
+ dw8(StationAddr0 + i, dev->dev_addr[i]);
set_multicast (dev);
if (np->coalesce) {
- writel (np->rx_coalesce | np->rx_timeout << 16,
- ioaddr + RxDMAIntCtrl);
+ dw32(RxDMAIntCtrl, np->rx_coalesce | np->rx_timeout << 16);
}
/* Set RIO to poll every N*320nsec. */
- writeb (0x20, ioaddr + RxDMAPollPeriod);
- writeb (0xff, ioaddr + TxDMAPollPeriod);
- writeb (0x30, ioaddr + RxDMABurstThresh);
- writeb (0x30, ioaddr + RxDMAUrgentThresh);
- writel (0x0007ffff, ioaddr + RmonStatMask);
+ dw8(RxDMAPollPeriod, 0x20);
+ dw8(TxDMAPollPeriod, 0xff);
+ dw8(RxDMABurstThresh, 0x30);
+ dw8(RxDMAUrgentThresh, 0x30);
+ dw32(RmonStatMask, 0x0007ffff);
/* clear statistics */
clear_stats (dev);
/* VLAN supported */
if (np->vlan) {
/* priority field in RxDMAIntCtrl */
- writel (readl(ioaddr + RxDMAIntCtrl) | 0x7 << 10,
- ioaddr + RxDMAIntCtrl);
+ dw32(RxDMAIntCtrl, dr32(RxDMAIntCtrl) | 0x7 << 10);
/* VLANId */
- writew (np->vlan, ioaddr + VLANId);
+ dw16(VLANId, np->vlan);
/* Length/Type should be 0x8100 */
- writel (0x8100 << 16 | np->vlan, ioaddr + VLANTag);
+ dw32(VLANTag, 0x8100 << 16 | np->vlan);
/* Enable AutoVLANuntagging, but disable AutoVLANtagging.
VLAN information tagged by TFC' VID, CFI fields. */
- writel (readl (ioaddr + MACCtrl) | AutoVLANuntagging,
- ioaddr + MACCtrl);
+ dw32(MACCtrl, dr32(MACCtrl) | AutoVLANuntagging);
}
init_timer (&np->timer);
@@ -469,20 +470,18 @@ rio_open (struct net_device *dev)
add_timer (&np->timer);
/* Start Tx/Rx */
- writel (readl (ioaddr + MACCtrl) | StatsEnable | RxEnable | TxEnable,
- ioaddr + MACCtrl);
+ dw32(MACCtrl, dr32(MACCtrl) | StatsEnable | RxEnable | TxEnable);
macctrl = 0;
macctrl |= (np->vlan) ? AutoVLANuntagging : 0;
macctrl |= (np->full_duplex) ? DuplexSelect : 0;
macctrl |= (np->tx_flow) ? TxFlowControlEnable : 0;
macctrl |= (np->rx_flow) ? RxFlowControlEnable : 0;
- writew(macctrl, ioaddr + MACCtrl);
+ dw16(MACCtrl, macctrl);
netif_start_queue (dev);
- /* Enable default interrupts */
- EnableInt ();
+ dl2k_enable_int(np);
return 0;
}
@@ -533,10 +532,11 @@ rio_timer (unsigned long data)
static void
rio_tx_timeout (struct net_device *dev)
{
- long ioaddr = dev->base_addr;
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
printk (KERN_INFO "%s: Tx timed out (%4.4x), is buffer full?\n",
- dev->name, readl (ioaddr + TxStatus));
+ dev->name, dr32(TxStatus));
rio_free_tx(dev, 0);
dev->if_port = 0;
dev->trans_start = jiffies; /* prevent tx timeout */
@@ -547,6 +547,7 @@ static void
alloc_list (struct net_device *dev)
{
struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
int i;
np->cur_rx = np->cur_tx = 0;
@@ -594,24 +595,23 @@ alloc_list (struct net_device *dev)
}
/* Set RFDListPtr */
- writel (np->rx_ring_dma, dev->base_addr + RFDListPtr0);
- writel (0, dev->base_addr + RFDListPtr1);
+ dw32(RFDListPtr0, np->rx_ring_dma);
+ dw32(RFDListPtr1, 0);
}
static netdev_tx_t
start_xmit (struct sk_buff *skb, struct net_device *dev)
{
struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
struct netdev_desc *txdesc;
unsigned entry;
- u32 ioaddr;
u64 tfc_vlan_tag = 0;
if (np->link_status == 0) { /* Link Down */
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
- ioaddr = dev->base_addr;
entry = np->cur_tx % TX_RING_SIZE;
np->tx_skbuff[entry] = skb;
txdesc = &np->tx_ring[entry];
@@ -646,9 +646,9 @@ start_xmit (struct sk_buff *skb, struct net_device *dev)
(1 << FragCountShift));
/* TxDMAPollNow */
- writel (readl (ioaddr + DMACtrl) | 0x00001000, ioaddr + DMACtrl);
+ dw32(DMACtrl, dr32(DMACtrl) | 0x00001000);
/* Schedule ISR */
- writel(10000, ioaddr + CountDown);
+ dw32(CountDown, 10000);
np->cur_tx = (np->cur_tx + 1) % TX_RING_SIZE;
if ((np->cur_tx - np->old_tx + TX_RING_SIZE) % TX_RING_SIZE
< TX_QUEUE_LEN - 1 && np->speed != 10) {
@@ -658,10 +658,10 @@ start_xmit (struct sk_buff *skb, struct net_device *dev)
}
/* The first TFDListPtr */
- if (readl (dev->base_addr + TFDListPtr0) == 0) {
- writel (np->tx_ring_dma + entry * sizeof (struct netdev_desc),
- dev->base_addr + TFDListPtr0);
- writel (0, dev->base_addr + TFDListPtr1);
+ if (!dr32(TFDListPtr0)) {
+ dw32(TFDListPtr0, np->tx_ring_dma +
+ entry * sizeof (struct netdev_desc));
+ dw32(TFDListPtr1, 0);
}
return NETDEV_TX_OK;
@@ -671,17 +671,15 @@ static irqreturn_t
rio_interrupt (int irq, void *dev_instance)
{
struct net_device *dev = dev_instance;
- struct netdev_private *np;
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
unsigned int_status;
- long ioaddr;
int cnt = max_intrloop;
int handled = 0;
- ioaddr = dev->base_addr;
- np = netdev_priv(dev);
while (1) {
- int_status = readw (ioaddr + IntStatus);
- writew (int_status, ioaddr + IntStatus);
+ int_status = dr16(IntStatus);
+ dw16(IntStatus, int_status);
int_status &= DEFAULT_INTR;
if (int_status == 0 || --cnt < 0)
break;
@@ -692,7 +690,7 @@ rio_interrupt (int irq, void *dev_instance)
/* TxDMAComplete interrupt */
if ((int_status & (TxDMAComplete|IntRequested))) {
int tx_status;
- tx_status = readl (ioaddr + TxStatus);
+ tx_status = dr32(TxStatus);
if (tx_status & 0x01)
tx_error (dev, tx_status);
/* Free used tx skbuffs */
@@ -705,7 +703,7 @@ rio_interrupt (int irq, void *dev_instance)
rio_error (dev, int_status);
}
if (np->cur_tx != np->old_tx)
- writel (100, ioaddr + CountDown);
+ dw32(CountDown, 100);
return IRQ_RETVAL(handled);
}
@@ -765,13 +763,11 @@ rio_free_tx (struct net_device *dev, int irq)
static void
tx_error (struct net_device *dev, int tx_status)
{
- struct netdev_private *np;
- long ioaddr = dev->base_addr;
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
int frame_id;
int i;
- np = netdev_priv(dev);
-
frame_id = (tx_status & 0xffff0000);
printk (KERN_ERR "%s: Transmit error, TxStatus %4.4x, FrameId %d.\n",
dev->name, tx_status, frame_id);
@@ -779,23 +775,21 @@ tx_error (struct net_device *dev, int tx_status)
/* Ttransmit Underrun */
if (tx_status & 0x10) {
np->stats.tx_fifo_errors++;
- writew (readw (ioaddr + TxStartThresh) + 0x10,
- ioaddr + TxStartThresh);
+ dw16(TxStartThresh, dr16(TxStartThresh) + 0x10);
/* Transmit Underrun need to set TxReset, DMARest, FIFOReset */
- writew (TxReset | DMAReset | FIFOReset | NetworkReset,
- ioaddr + ASICCtrl + 2);
+ dw16(ASICCtrl + 2,
+ TxReset | DMAReset | FIFOReset | NetworkReset);
/* Wait for ResetBusy bit clear */
for (i = 50; i > 0; i--) {
- if ((readw (ioaddr + ASICCtrl + 2) & ResetBusy) == 0)
+ if (!(dr16(ASICCtrl + 2) & ResetBusy))
break;
mdelay (1);
}
rio_free_tx (dev, 1);
/* Reset TFDListPtr */
- writel (np->tx_ring_dma +
- np->old_tx * sizeof (struct netdev_desc),
- dev->base_addr + TFDListPtr0);
- writel (0, dev->base_addr + TFDListPtr1);
+ dw32(TFDListPtr0, np->tx_ring_dma +
+ np->old_tx * sizeof (struct netdev_desc));
+ dw32(TFDListPtr1, 0);
/* Let TxStartThresh stay default value */
}
@@ -803,10 +797,10 @@ tx_error (struct net_device *dev, int tx_status)
if (tx_status & 0x04) {
np->stats.tx_fifo_errors++;
/* TxReset and clear FIFO */
- writew (TxReset | FIFOReset, ioaddr + ASICCtrl + 2);
+ dw16(ASICCtrl + 2, TxReset | FIFOReset);
/* Wait reset done */
for (i = 50; i > 0; i--) {
- if ((readw (ioaddr + ASICCtrl + 2) & ResetBusy) == 0)
+ if (!(dr16(ASICCtrl + 2) & ResetBusy))
break;
mdelay (1);
}
@@ -821,7 +815,7 @@ tx_error (struct net_device *dev, int tx_status)
np->stats.collisions++;
#endif
/* Restart the Tx */
- writel (readw (dev->base_addr + MACCtrl) | TxEnable, ioaddr + MACCtrl);
+ dw32(MACCtrl, dr16(MACCtrl) | TxEnable);
}
static int
@@ -931,8 +925,8 @@ receive_packet (struct net_device *dev)
static void
rio_error (struct net_device *dev, int int_status)
{
- long ioaddr = dev->base_addr;
struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
u16 macctrl;
/* Link change event */
@@ -954,7 +948,7 @@ rio_error (struct net_device *dev, int int_status)
TxFlowControlEnable : 0;
macctrl |= (np->rx_flow) ?
RxFlowControlEnable : 0;
- writew(macctrl, ioaddr + MACCtrl);
+ dw16(MACCtrl, macctrl);
np->link_status = 1;
netif_carrier_on(dev);
} else {
@@ -974,7 +968,7 @@ rio_error (struct net_device *dev, int int_status)
if (int_status & HostError) {
printk (KERN_ERR "%s: HostError! IntStatus %4.4x.\n",
dev->name, int_status);
- writew (GlobalReset | HostReset, ioaddr + ASICCtrl + 2);
+ dw16(ASICCtrl + 2, GlobalReset | HostReset);
mdelay (500);
}
}
@@ -982,8 +976,8 @@ rio_error (struct net_device *dev, int int_status)
static struct net_device_stats *
get_stats (struct net_device *dev)
{
- long ioaddr = dev->base_addr;
struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
#ifdef MEM_MAPPING
int i;
#endif
@@ -992,106 +986,107 @@ get_stats (struct net_device *dev)
/* All statistics registers need to be acknowledged,
else statistic overflow could cause problems */
- np->stats.rx_packets += readl (ioaddr + FramesRcvOk);
- np->stats.tx_packets += readl (ioaddr + FramesXmtOk);
- np->stats.rx_bytes += readl (ioaddr + OctetRcvOk);
- np->stats.tx_bytes += readl (ioaddr + OctetXmtOk);
+ np->stats.rx_packets += dr32(FramesRcvOk);
+ np->stats.tx_packets += dr32(FramesXmtOk);
+ np->stats.rx_bytes += dr32(OctetRcvOk);
+ np->stats.tx_bytes += dr32(OctetXmtOk);
- np->stats.multicast = readl (ioaddr + McstFramesRcvdOk);
- np->stats.collisions += readl (ioaddr + SingleColFrames)
- + readl (ioaddr + MultiColFrames);
+ np->stats.multicast = dr32(McstFramesRcvdOk);
+ np->stats.collisions += dr32(SingleColFrames)
+ + dr32(MultiColFrames);
/* detailed tx errors */
- stat_reg = readw (ioaddr + FramesAbortXSColls);
+ stat_reg = dr16(FramesAbortXSColls);
np->stats.tx_aborted_errors += stat_reg;
np->stats.tx_errors += stat_reg;
- stat_reg = readw (ioaddr + CarrierSenseErrors);
+ stat_reg = dr16(CarrierSenseErrors);
np->stats.tx_carrier_errors += stat_reg;
np->stats.tx_errors += stat_reg;
/* Clear all other statistic register. */
- readl (ioaddr + McstOctetXmtOk);
- readw (ioaddr + BcstFramesXmtdOk);
- readl (ioaddr + McstFramesXmtdOk);
- readw (ioaddr + BcstFramesRcvdOk);
- readw (ioaddr + MacControlFramesRcvd);
- readw (ioaddr + FrameTooLongErrors);
- readw (ioaddr + InRangeLengthErrors);
- readw (ioaddr + FramesCheckSeqErrors);
- readw (ioaddr + FramesLostRxErrors);
- readl (ioaddr + McstOctetXmtOk);
- readl (ioaddr + BcstOctetXmtOk);
- readl (ioaddr + McstFramesXmtdOk);
- readl (ioaddr + FramesWDeferredXmt);
- readl (ioaddr + LateCollisions);
- readw (ioaddr + BcstFramesXmtdOk);
- readw (ioaddr + MacControlFramesXmtd);
- readw (ioaddr + FramesWEXDeferal);
+ dr32(McstOctetXmtOk);
+ dr16(BcstFramesXmtdOk);
+ dr32(McstFramesXmtdOk);
+ dr16(BcstFramesRcvdOk);
+ dr16(MacControlFramesRcvd);
+ dr16(FrameTooLongErrors);
+ dr16(InRangeLengthErrors);
+ dr16(FramesCheckSeqErrors);
+ dr16(FramesLostRxErrors);
+ dr32(McstOctetXmtOk);
+ dr32(BcstOctetXmtOk);
+ dr32(McstFramesXmtdOk);
+ dr32(FramesWDeferredXmt);
+ dr32(LateCollisions);
+ dr16(BcstFramesXmtdOk);
+ dr16(MacControlFramesXmtd);
+ dr16(FramesWEXDeferal);
#ifdef MEM_MAPPING
for (i = 0x100; i <= 0x150; i += 4)
- readl (ioaddr + i);
+ dr32(i);
#endif
- readw (ioaddr + TxJumboFrames);
- readw (ioaddr + RxJumboFrames);
- readw (ioaddr + TCPCheckSumErrors);
- readw (ioaddr + UDPCheckSumErrors);
- readw (ioaddr + IPCheckSumErrors);
+ dr16(TxJumboFrames);
+ dr16(RxJumboFrames);
+ dr16(TCPCheckSumErrors);
+ dr16(UDPCheckSumErrors);
+ dr16(IPCheckSumErrors);
return &np->stats;
}
static int
clear_stats (struct net_device *dev)
{
- long ioaddr = dev->base_addr;
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
#ifdef MEM_MAPPING
int i;
#endif
/* All statistics registers need to be acknowledged,
else statistic overflow could cause problems */
- readl (ioaddr + FramesRcvOk);
- readl (ioaddr + FramesXmtOk);
- readl (ioaddr + OctetRcvOk);
- readl (ioaddr + OctetXmtOk);
-
- readl (ioaddr + McstFramesRcvdOk);
- readl (ioaddr + SingleColFrames);
- readl (ioaddr + MultiColFrames);
- readl (ioaddr + LateCollisions);
+ dr32(FramesRcvOk);
+ dr32(FramesXmtOk);
+ dr32(OctetRcvOk);
+ dr32(OctetXmtOk);
+
+ dr32(McstFramesRcvdOk);
+ dr32(SingleColFrames);
+ dr32(MultiColFrames);
+ dr32(LateCollisions);
/* detailed rx errors */
- readw (ioaddr + FrameTooLongErrors);
- readw (ioaddr + InRangeLengthErrors);
- readw (ioaddr + FramesCheckSeqErrors);
- readw (ioaddr + FramesLostRxErrors);
+ dr16(FrameTooLongErrors);
+ dr16(InRangeLengthErrors);
+ dr16(FramesCheckSeqErrors);
+ dr16(FramesLostRxErrors);
/* detailed tx errors */
- readw (ioaddr + FramesAbortXSColls);
- readw (ioaddr + CarrierSenseErrors);
+ dr16(FramesAbortXSColls);
+ dr16(CarrierSenseErrors);
/* Clear all other statistic register. */
- readl (ioaddr + McstOctetXmtOk);
- readw (ioaddr + BcstFramesXmtdOk);
- readl (ioaddr + McstFramesXmtdOk);
- readw (ioaddr + BcstFramesRcvdOk);
- readw (ioaddr + MacControlFramesRcvd);
- readl (ioaddr + McstOctetXmtOk);
- readl (ioaddr + BcstOctetXmtOk);
- readl (ioaddr + McstFramesXmtdOk);
- readl (ioaddr + FramesWDeferredXmt);
- readw (ioaddr + BcstFramesXmtdOk);
- readw (ioaddr + MacControlFramesXmtd);
- readw (ioaddr + FramesWEXDeferal);
+ dr32(McstOctetXmtOk);
+ dr16(BcstFramesXmtdOk);
+ dr32(McstFramesXmtdOk);
+ dr16(BcstFramesRcvdOk);
+ dr16(MacControlFramesRcvd);
+ dr32(McstOctetXmtOk);
+ dr32(BcstOctetXmtOk);
+ dr32(McstFramesXmtdOk);
+ dr32(FramesWDeferredXmt);
+ dr16(BcstFramesXmtdOk);
+ dr16(MacControlFramesXmtd);
+ dr16(FramesWEXDeferal);
#ifdef MEM_MAPPING
for (i = 0x100; i <= 0x150; i += 4)
- readl (ioaddr + i);
+ dr32(i);
#endif
- readw (ioaddr + TxJumboFrames);
- readw (ioaddr + RxJumboFrames);
- readw (ioaddr + TCPCheckSumErrors);
- readw (ioaddr + UDPCheckSumErrors);
- readw (ioaddr + IPCheckSumErrors);
+ dr16(TxJumboFrames);
+ dr16(RxJumboFrames);
+ dr16(TCPCheckSumErrors);
+ dr16(UDPCheckSumErrors);
+ dr16(IPCheckSumErrors);
return 0;
}
@@ -1114,10 +1109,10 @@ change_mtu (struct net_device *dev, int new_mtu)
static void
set_multicast (struct net_device *dev)
{
- long ioaddr = dev->base_addr;
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
u32 hash_table[2];
u16 rx_mode = 0;
- struct netdev_private *np = netdev_priv(dev);
hash_table[0] = hash_table[1] = 0;
/* RxFlowcontrol DA: 01-80-C2-00-00-01. Hash index=0x39 */
@@ -1153,9 +1148,9 @@ set_multicast (struct net_device *dev)
rx_mode |= ReceiveVLANMatch;
}
- writel (hash_table[0], ioaddr + HashTable0);
- writel (hash_table[1], ioaddr + HashTable1);
- writew (rx_mode, ioaddr + ReceiveMode);
+ dw32(HashTable0, hash_table[0]);
+ dw32(HashTable1, hash_table[1]);
+ dw16(ReceiveMode, rx_mode);
}
static void rio_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
@@ -1318,15 +1313,15 @@ rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
#define EEP_BUSY 0x8000
/* Read the EEPROM word */
/* We use I/O instruction to read/write eeprom to avoid fail on some machines */
-static int
-read_eeprom (long ioaddr, int eep_addr)
+static int read_eeprom(struct netdev_private *np, int eep_addr)
{
+ void __iomem *ioaddr = np->eeprom_addr;
int i = 1000;
- outw (EEP_READ | (eep_addr & 0xff), ioaddr + EepromCtrl);
+
+ dw16(EepromCtrl, EEP_READ | (eep_addr & 0xff));
while (i-- > 0) {
- if (!(inw (ioaddr + EepromCtrl) & EEP_BUSY)) {
- return inw (ioaddr + EepromData);
- }
+ if (!(dr16(EepromCtrl) & EEP_BUSY))
+ return dr16(EepromData);
}
return 0;
}
@@ -1336,38 +1331,40 @@ enum phy_ctrl_bits {
MII_DUPLEX = 0x08,
};
-#define mii_delay() readb(ioaddr)
+#define mii_delay() dr8(PhyCtrl)
static void
mii_sendbit (struct net_device *dev, u32 data)
{
- long ioaddr = dev->base_addr + PhyCtrl;
- data = (data) ? MII_DATA1 : 0;
- data |= MII_WRITE;
- data |= (readb (ioaddr) & 0xf8) | MII_WRITE;
- writeb (data, ioaddr);
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
+
+ data = ((data) ? MII_DATA1 : 0) | (dr8(PhyCtrl) & 0xf8) | MII_WRITE;
+ dw8(PhyCtrl, data);
mii_delay ();
- writeb (data | MII_CLK, ioaddr);
+ dw8(PhyCtrl, data | MII_CLK);
mii_delay ();
}
static int
mii_getbit (struct net_device *dev)
{
- long ioaddr = dev->base_addr + PhyCtrl;
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
u8 data;
- data = (readb (ioaddr) & 0xf8) | MII_READ;
- writeb (data, ioaddr);
+ data = (dr8(PhyCtrl) & 0xf8) | MII_READ;
+ dw8(PhyCtrl, data);
mii_delay ();
- writeb (data | MII_CLK, ioaddr);
+ dw8(PhyCtrl, data | MII_CLK);
mii_delay ();
- return ((readb (ioaddr) >> 1) & 1);
+ return (dr8(PhyCtrl) >> 1) & 1;
}
static void
mii_send_bits (struct net_device *dev, u32 data, int len)
{
int i;
+
for (i = len - 1; i >= 0; i--) {
mii_sendbit (dev, data & (1 << i));
}
@@ -1721,28 +1718,29 @@ mii_set_media_pcs (struct net_device *dev)
static int
rio_close (struct net_device *dev)
{
- long ioaddr = dev->base_addr;
struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
+
+ struct pci_dev *pdev = np->pdev;
struct sk_buff *skb;
int i;
netif_stop_queue (dev);
/* Disable interrupts */
- writew (0, ioaddr + IntEnable);
+ dw16(IntEnable, 0);
/* Stop Tx and Rx logics */
- writel (TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl);
+ dw32(MACCtrl, TxDisable | RxDisable | StatsDisable);
- free_irq (dev->irq, dev);
+ free_irq(pdev->irq, dev);
del_timer_sync (&np->timer);
/* Free all the skbuffs in the queue. */
for (i = 0; i < RX_RING_SIZE; i++) {
skb = np->rx_skbuff[i];
if (skb) {
- pci_unmap_single(np->pdev,
- desc_to_dma(&np->rx_ring[i]),
+ pci_unmap_single(pdev, desc_to_dma(&np->rx_ring[i]),
skb->len, PCI_DMA_FROMDEVICE);
dev_kfree_skb (skb);
np->rx_skbuff[i] = NULL;
@@ -1753,8 +1751,7 @@ rio_close (struct net_device *dev)
for (i = 0; i < TX_RING_SIZE; i++) {
skb = np->tx_skbuff[i];
if (skb) {
- pci_unmap_single(np->pdev,
- desc_to_dma(&np->tx_ring[i]),
+ pci_unmap_single(pdev, desc_to_dma(&np->tx_ring[i]),
skb->len, PCI_DMA_TODEVICE);
dev_kfree_skb (skb);
np->tx_skbuff[i] = NULL;
@@ -1778,8 +1775,9 @@ rio_remove1 (struct pci_dev *pdev)
pci_free_consistent (pdev, TX_TOTAL_SIZE, np->tx_ring,
np->tx_ring_dma);
#ifdef MEM_MAPPING
- iounmap ((char *) (dev->base_addr));
+ pci_iounmap(pdev, np->ioaddr);
#endif
+ pci_iounmap(pdev, np->eeprom_addr);
free_netdev (dev);
pci_release_regions (pdev);
pci_disable_device (pdev);
diff --git a/drivers/net/ethernet/dlink/dl2k.h b/drivers/net/ethernet/dlink/dl2k.h
index ba0adca..40ba6e0 100644
--- a/drivers/net/ethernet/dlink/dl2k.h
+++ b/drivers/net/ethernet/dlink/dl2k.h
@@ -42,23 +42,6 @@
#define TX_TOTAL_SIZE TX_RING_SIZE*sizeof(struct netdev_desc)
#define RX_TOTAL_SIZE RX_RING_SIZE*sizeof(struct netdev_desc)
-/* This driver was written to use PCI memory space, however x86-oriented
- hardware often uses I/O space accesses. */
-#ifndef MEM_MAPPING
-#undef readb
-#undef readw
-#undef readl
-#undef writeb
-#undef writew
-#undef writel
-#define readb inb
-#define readw inw
-#define readl inl
-#define writeb outb
-#define writew outw
-#define writel outl
-#endif
-
/* Offsets to the device registers.
Unlike software-only systems, device drivers interact with complex hardware.
It's not useful to define symbolic names for every register bit in the
@@ -391,6 +374,8 @@ struct netdev_private {
dma_addr_t tx_ring_dma;
dma_addr_t rx_ring_dma;
struct pci_dev *pdev;
+ void __iomem *ioaddr;
+ void __iomem *eeprom_addr;
spinlock_t tx_lock;
spinlock_t rx_lock;
struct net_device_stats stats;
--
1.7.7.6
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox