From 7c2124cad0542d2b97a55cb8ea5a6b838a6c6770 Mon Sep 17 00:00:00 2001 From: Mario Rossi Date: Mon, 11 Dec 2006 05:37:31 -0300 Subject: [PATCH] --- yaml --- r: 45066 b: refs/heads/master c: a821e990e4db77cd87bec488fb425d8d4ced79bd h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/media/dvb/frontends/dib3000mc.c | 2 +- trunk/drivers/net/8139cp.c | 6 +- trunk/drivers/net/arm/ep93xx_eth.c | 4 +- trunk/drivers/net/b44.c | 6 +- trunk/drivers/net/e1000/e1000_ethtool.c | 3 - trunk/drivers/net/e1000/e1000_hw.c | 296 +++++++-------- trunk/drivers/net/e1000/e1000_hw.h | 310 ++++++++-------- trunk/drivers/net/e1000/e1000_main.c | 345 +++++------------- trunk/drivers/net/e1000/e1000_param.c | 4 +- trunk/drivers/net/forcedeth.c | 16 +- trunk/drivers/net/ibm_emac/ibm_emac_phy.c | 4 +- trunk/drivers/net/myri10ge/myri10ge.c | 163 +++++---- trunk/drivers/net/netxen/netxen_nic.h | 25 +- trunk/drivers/net/netxen/netxen_nic_ethtool.c | 5 +- trunk/drivers/net/netxen/netxen_nic_hw.c | 296 ++++++++++++++- trunk/drivers/net/netxen/netxen_nic_init.c | 251 ++++++++++++- trunk/drivers/net/netxen/netxen_nic_ioctl.h | 77 ++++ trunk/drivers/net/netxen/netxen_nic_isr.c | 3 +- trunk/drivers/net/netxen/netxen_nic_main.c | 85 ++++- trunk/drivers/net/r8169.c | 6 +- trunk/drivers/net/skge.c | 5 +- trunk/drivers/net/sky2.c | 35 +- trunk/drivers/net/via-velocity.c | 18 +- trunk/drivers/net/wireless/zd1211rw/zd_mac.c | 96 ++--- trunk/drivers/net/wireless/zd1211rw/zd_mac.h | 5 +- trunk/drivers/net/wireless/zd1211rw/zd_usb.c | 4 +- trunk/mm/page-writeback.c | 45 +-- .../softmac/ieee80211softmac_assoc.c | 4 +- .../ieee80211/softmac/ieee80211softmac_wx.c | 2 +- 30 files changed, 1253 insertions(+), 870 deletions(-) create mode 100644 trunk/drivers/net/netxen/netxen_nic_ioctl.h diff --git a/[refs] b/[refs] index 8b01c4a79f15..bc76d8d99ed0 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6c722e90d7ede7db2d2b28a3cc69a8545db67ea1 +refs/heads/master: a821e990e4db77cd87bec488fb425d8d4ced79bd diff --git a/trunk/drivers/media/dvb/frontends/dib3000mc.c b/trunk/drivers/media/dvb/frontends/dib3000mc.c index 5da66178006c..23aa75a27c1f 100644 --- a/trunk/drivers/media/dvb/frontends/dib3000mc.c +++ b/trunk/drivers/media/dvb/frontends/dib3000mc.c @@ -515,7 +515,7 @@ static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dibx000 fchan.vit_alpha = 1; fchan.vit_code_rate_hp = 2; fchan.vit_code_rate_lp = 2; fchan.vit_hrch = 0; fchan.vit_select_hp = 1; - dib3000mc_set_channel_cfg(state, &fchan, 7); + dib3000mc_set_channel_cfg(state, &fchan, 11); reg = dib3000mc_read_word(state, 0); dib3000mc_write_word(state, 0, reg | (1 << 8)); diff --git a/trunk/drivers/net/8139cp.c b/trunk/drivers/net/8139cp.c index e2cb19b582a1..458dd9f830c4 100644 --- a/trunk/drivers/net/8139cp.c +++ b/trunk/drivers/net/8139cp.c @@ -617,15 +617,13 @@ static int cp_rx_poll (struct net_device *dev, int *budget) * this round of polling */ if (rx_work) { - unsigned long flags; - if (cpr16(IntrStatus) & cp_rx_intr_mask) goto rx_status_loop; - local_irq_save(flags); + local_irq_disable(); cpw16_f(IntrMask, cp_intr_mask); __netif_rx_complete(dev); - local_irq_restore(flags); + local_irq_enable(); return 0; /* done */ } diff --git a/trunk/drivers/net/arm/ep93xx_eth.c b/trunk/drivers/net/arm/ep93xx_eth.c index dd698b033a62..8ebd68e2af98 100644 --- a/trunk/drivers/net/arm/ep93xx_eth.c +++ b/trunk/drivers/net/arm/ep93xx_eth.c @@ -780,10 +780,12 @@ static struct ethtool_ops ep93xx_ethtool_ops = { struct net_device *ep93xx_dev_alloc(struct ep93xx_eth_data *data) { struct net_device *dev; + struct ep93xx_priv *ep; dev = alloc_etherdev(sizeof(struct ep93xx_priv)); if (dev == NULL) return NULL; + ep = netdev_priv(dev); memcpy(dev->dev_addr, data->dev_addr, ETH_ALEN); @@ -838,9 +840,9 @@ static int ep93xx_eth_probe(struct platform_device *pdev) struct ep93xx_priv *ep; int err; + data = pdev->dev.platform_data; if (pdev == NULL) return -ENODEV; - data = pdev->dev.platform_data; dev = ep93xx_dev_alloc(data); if (dev == NULL) { diff --git a/trunk/drivers/net/b44.c b/trunk/drivers/net/b44.c index 5eb2ec68393f..474a4e3438db 100644 --- a/trunk/drivers/net/b44.c +++ b/trunk/drivers/net/b44.c @@ -879,14 +879,12 @@ static int b44_poll(struct net_device *netdev, int *budget) } if (bp->istat & ISTAT_ERRORS) { - unsigned long flags; - - spin_lock_irqsave(&bp->lock, flags); + spin_lock_irq(&bp->lock); b44_halt(bp); b44_init_rings(bp); b44_init_hw(bp, 1); netif_wake_queue(bp->dev); - spin_unlock_irqrestore(&bp->lock, flags); + spin_unlock_irq(&bp->lock); done = 1; } diff --git a/trunk/drivers/net/e1000/e1000_ethtool.c b/trunk/drivers/net/e1000/e1000_ethtool.c index fb96c87f9e56..da459f7177c6 100644 --- a/trunk/drivers/net/e1000/e1000_ethtool.c +++ b/trunk/drivers/net/e1000/e1000_ethtool.c @@ -100,9 +100,6 @@ static const struct e1000_stats e1000_gstrings_stats[] = { { "rx_csum_offload_errors", E1000_STAT(hw_csum_err) }, { "rx_header_split", E1000_STAT(rx_hdr_split) }, { "alloc_rx_buff_failed", E1000_STAT(alloc_rx_buff_failed) }, - { "tx_smbus", E1000_STAT(stats.mgptc) }, - { "rx_smbus", E1000_STAT(stats.mgprc) }, - { "dropped_smbus", E1000_STAT(stats.mgpdc) }, }; #define E1000_QUEUE_STATS_LEN 0 diff --git a/trunk/drivers/net/e1000/e1000_hw.c b/trunk/drivers/net/e1000/e1000_hw.c index 9be44699300b..3655d902b0bd 100644 --- a/trunk/drivers/net/e1000/e1000_hw.c +++ b/trunk/drivers/net/e1000/e1000_hw.c @@ -308,160 +308,141 @@ e1000_phy_init_script(struct e1000_hw *hw) int32_t e1000_set_mac_type(struct e1000_hw *hw) { - DEBUGFUNC("e1000_set_mac_type"); - - switch (hw->device_id) { - case E1000_DEV_ID_82542: - switch (hw->revision_id) { - case E1000_82542_2_0_REV_ID: - hw->mac_type = e1000_82542_rev2_0; - break; - case E1000_82542_2_1_REV_ID: - hw->mac_type = e1000_82542_rev2_1; - break; - default: - /* Invalid 82542 revision ID */ - return -E1000_ERR_MAC_TYPE; - } - break; - case E1000_DEV_ID_82543GC_FIBER: - case E1000_DEV_ID_82543GC_COPPER: - hw->mac_type = e1000_82543; - break; - case E1000_DEV_ID_82544EI_COPPER: - case E1000_DEV_ID_82544EI_FIBER: - case E1000_DEV_ID_82544GC_COPPER: - case E1000_DEV_ID_82544GC_LOM: - hw->mac_type = e1000_82544; - break; - case E1000_DEV_ID_82540EM: - case E1000_DEV_ID_82540EM_LOM: - case E1000_DEV_ID_82540EP: - case E1000_DEV_ID_82540EP_LOM: - case E1000_DEV_ID_82540EP_LP: - hw->mac_type = e1000_82540; - break; - case E1000_DEV_ID_82545EM_COPPER: - case E1000_DEV_ID_82545EM_FIBER: - hw->mac_type = e1000_82545; - break; - case E1000_DEV_ID_82545GM_COPPER: - case E1000_DEV_ID_82545GM_FIBER: - case E1000_DEV_ID_82545GM_SERDES: - hw->mac_type = e1000_82545_rev_3; - break; - case E1000_DEV_ID_82546EB_COPPER: - case E1000_DEV_ID_82546EB_FIBER: - case E1000_DEV_ID_82546EB_QUAD_COPPER: - hw->mac_type = e1000_82546; - break; - case E1000_DEV_ID_82546GB_COPPER: - case E1000_DEV_ID_82546GB_FIBER: - case E1000_DEV_ID_82546GB_SERDES: - case E1000_DEV_ID_82546GB_PCIE: - case E1000_DEV_ID_82546GB_QUAD_COPPER: - case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: - hw->mac_type = e1000_82546_rev_3; - break; - case E1000_DEV_ID_82541EI: - case E1000_DEV_ID_82541EI_MOBILE: - case E1000_DEV_ID_82541ER_LOM: - hw->mac_type = e1000_82541; - break; - case E1000_DEV_ID_82541ER: - case E1000_DEV_ID_82541GI: - case E1000_DEV_ID_82541GI_LF: - case E1000_DEV_ID_82541GI_MOBILE: - hw->mac_type = e1000_82541_rev_2; - break; - case E1000_DEV_ID_82547EI: - case E1000_DEV_ID_82547EI_MOBILE: - hw->mac_type = e1000_82547; - break; - case E1000_DEV_ID_82547GI: - hw->mac_type = e1000_82547_rev_2; - break; - case E1000_DEV_ID_82571EB_COPPER: - case E1000_DEV_ID_82571EB_FIBER: - case E1000_DEV_ID_82571EB_SERDES: - case E1000_DEV_ID_82571EB_QUAD_COPPER: - case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE: - hw->mac_type = e1000_82571; - break; - case E1000_DEV_ID_82572EI_COPPER: - case E1000_DEV_ID_82572EI_FIBER: - case E1000_DEV_ID_82572EI_SERDES: - case E1000_DEV_ID_82572EI: - hw->mac_type = e1000_82572; - break; - case E1000_DEV_ID_82573E: - case E1000_DEV_ID_82573E_IAMT: - case E1000_DEV_ID_82573L: - hw->mac_type = e1000_82573; - break; - case E1000_DEV_ID_80003ES2LAN_COPPER_SPT: - case E1000_DEV_ID_80003ES2LAN_SERDES_SPT: - case E1000_DEV_ID_80003ES2LAN_COPPER_DPT: - case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: - hw->mac_type = e1000_80003es2lan; - break; - case E1000_DEV_ID_ICH8_IGP_M_AMT: - case E1000_DEV_ID_ICH8_IGP_AMT: - case E1000_DEV_ID_ICH8_IGP_C: - case E1000_DEV_ID_ICH8_IFE: - case E1000_DEV_ID_ICH8_IFE_GT: - case E1000_DEV_ID_ICH8_IFE_G: - case E1000_DEV_ID_ICH8_IGP_M: - hw->mac_type = e1000_ich8lan; - break; - default: - /* Should never have loaded on this device */ - return -E1000_ERR_MAC_TYPE; - } - - switch (hw->mac_type) { - case e1000_ich8lan: - hw->swfwhw_semaphore_present = TRUE; - hw->asf_firmware_present = TRUE; - break; - case e1000_80003es2lan: - hw->swfw_sync_present = TRUE; - /* fall through */ - case e1000_82571: - case e1000_82572: - case e1000_82573: - hw->eeprom_semaphore_present = TRUE; - /* fall through */ - case e1000_82541: - case e1000_82547: - case e1000_82541_rev_2: - case e1000_82547_rev_2: - hw->asf_firmware_present = TRUE; - break; - default: - break; - } - - /* The 82543 chip does not count tx_carrier_errors properly in - * FD mode - */ - if (hw->mac_type == e1000_82543) - hw->bad_tx_carr_stats_fd = TRUE; - - /* capable of receiving management packets to the host */ - if (hw->mac_type >= e1000_82571) - hw->has_manc2h = TRUE; - - /* In rare occasions, ESB2 systems would end up started without - * the RX unit being turned on. - */ - if (hw->mac_type == e1000_80003es2lan) - hw->rx_needs_kicking = TRUE; - - if (hw->mac_type > e1000_82544) - hw->has_smbus = TRUE; - - return E1000_SUCCESS; + DEBUGFUNC("e1000_set_mac_type"); + + switch (hw->device_id) { + case E1000_DEV_ID_82542: + switch (hw->revision_id) { + case E1000_82542_2_0_REV_ID: + hw->mac_type = e1000_82542_rev2_0; + break; + case E1000_82542_2_1_REV_ID: + hw->mac_type = e1000_82542_rev2_1; + break; + default: + /* Invalid 82542 revision ID */ + return -E1000_ERR_MAC_TYPE; + } + break; + case E1000_DEV_ID_82543GC_FIBER: + case E1000_DEV_ID_82543GC_COPPER: + hw->mac_type = e1000_82543; + break; + case E1000_DEV_ID_82544EI_COPPER: + case E1000_DEV_ID_82544EI_FIBER: + case E1000_DEV_ID_82544GC_COPPER: + case E1000_DEV_ID_82544GC_LOM: + hw->mac_type = e1000_82544; + break; + case E1000_DEV_ID_82540EM: + case E1000_DEV_ID_82540EM_LOM: + case E1000_DEV_ID_82540EP: + case E1000_DEV_ID_82540EP_LOM: + case E1000_DEV_ID_82540EP_LP: + hw->mac_type = e1000_82540; + break; + case E1000_DEV_ID_82545EM_COPPER: + case E1000_DEV_ID_82545EM_FIBER: + hw->mac_type = e1000_82545; + break; + case E1000_DEV_ID_82545GM_COPPER: + case E1000_DEV_ID_82545GM_FIBER: + case E1000_DEV_ID_82545GM_SERDES: + hw->mac_type = e1000_82545_rev_3; + break; + case E1000_DEV_ID_82546EB_COPPER: + case E1000_DEV_ID_82546EB_FIBER: + case E1000_DEV_ID_82546EB_QUAD_COPPER: + hw->mac_type = e1000_82546; + break; + case E1000_DEV_ID_82546GB_COPPER: + case E1000_DEV_ID_82546GB_FIBER: + case E1000_DEV_ID_82546GB_SERDES: + case E1000_DEV_ID_82546GB_PCIE: + case E1000_DEV_ID_82546GB_QUAD_COPPER: + case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: + hw->mac_type = e1000_82546_rev_3; + break; + case E1000_DEV_ID_82541EI: + case E1000_DEV_ID_82541EI_MOBILE: + case E1000_DEV_ID_82541ER_LOM: + hw->mac_type = e1000_82541; + break; + case E1000_DEV_ID_82541ER: + case E1000_DEV_ID_82541GI: + case E1000_DEV_ID_82541GI_LF: + case E1000_DEV_ID_82541GI_MOBILE: + hw->mac_type = e1000_82541_rev_2; + break; + case E1000_DEV_ID_82547EI: + case E1000_DEV_ID_82547EI_MOBILE: + hw->mac_type = e1000_82547; + break; + case E1000_DEV_ID_82547GI: + hw->mac_type = e1000_82547_rev_2; + break; + case E1000_DEV_ID_82571EB_COPPER: + case E1000_DEV_ID_82571EB_FIBER: + case E1000_DEV_ID_82571EB_SERDES: + case E1000_DEV_ID_82571EB_QUAD_COPPER: + case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE: + hw->mac_type = e1000_82571; + break; + case E1000_DEV_ID_82572EI_COPPER: + case E1000_DEV_ID_82572EI_FIBER: + case E1000_DEV_ID_82572EI_SERDES: + case E1000_DEV_ID_82572EI: + hw->mac_type = e1000_82572; + break; + case E1000_DEV_ID_82573E: + case E1000_DEV_ID_82573E_IAMT: + case E1000_DEV_ID_82573L: + hw->mac_type = e1000_82573; + break; + case E1000_DEV_ID_80003ES2LAN_COPPER_SPT: + case E1000_DEV_ID_80003ES2LAN_SERDES_SPT: + case E1000_DEV_ID_80003ES2LAN_COPPER_DPT: + case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: + hw->mac_type = e1000_80003es2lan; + break; + case E1000_DEV_ID_ICH8_IGP_M_AMT: + case E1000_DEV_ID_ICH8_IGP_AMT: + case E1000_DEV_ID_ICH8_IGP_C: + case E1000_DEV_ID_ICH8_IFE: + case E1000_DEV_ID_ICH8_IFE_GT: + case E1000_DEV_ID_ICH8_IFE_G: + case E1000_DEV_ID_ICH8_IGP_M: + hw->mac_type = e1000_ich8lan; + break; + default: + /* Should never have loaded on this device */ + return -E1000_ERR_MAC_TYPE; + } + + switch (hw->mac_type) { + case e1000_ich8lan: + hw->swfwhw_semaphore_present = TRUE; + hw->asf_firmware_present = TRUE; + break; + case e1000_80003es2lan: + hw->swfw_sync_present = TRUE; + /* fall through */ + case e1000_82571: + case e1000_82572: + case e1000_82573: + hw->eeprom_semaphore_present = TRUE; + /* fall through */ + case e1000_82541: + case e1000_82547: + case e1000_82541_rev_2: + case e1000_82547_rev_2: + hw->asf_firmware_present = TRUE; + break; + default: + break; + } + + return E1000_SUCCESS; } /***************************************************************************** @@ -6594,7 +6575,7 @@ e1000_get_bus_info(struct e1000_hw *hw) switch (hw->mac_type) { case e1000_82542_rev2_0: case e1000_82542_rev2_1: - hw->bus_type = e1000_bus_type_pci; + hw->bus_type = e1000_bus_type_unknown; hw->bus_speed = e1000_bus_speed_unknown; hw->bus_width = e1000_bus_width_unknown; break; @@ -7836,8 +7817,9 @@ e1000_enable_mng_pass_thru(struct e1000_hw *hw) fwsm = E1000_READ_REG(hw, FWSM); factps = E1000_READ_REG(hw, FACTPS); - if ((((fwsm & E1000_FWSM_MODE_MASK) >> E1000_FWSM_MODE_SHIFT) == - e1000_mng_mode_pt) && !(factps & E1000_FACTPS_MNGCG)) + if (((fwsm & E1000_FWSM_MODE_MASK) == + (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT)) && + (factps & E1000_FACTPS_MNGCG)) return TRUE; } else if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN)) diff --git a/trunk/drivers/net/e1000/e1000_hw.h b/trunk/drivers/net/e1000/e1000_hw.h index d67105883341..3321fb13bfa9 100644 --- a/trunk/drivers/net/e1000/e1000_hw.h +++ b/trunk/drivers/net/e1000/e1000_hw.h @@ -1301,170 +1301,165 @@ struct e1000_ffvt_entry { #define E1000_82542_RSSIR E1000_RSSIR #define E1000_82542_KUMCTRLSTA E1000_KUMCTRLSTA #define E1000_82542_SW_FW_SYNC E1000_SW_FW_SYNC -#define E1000_82542_MANC2H E1000_MANC2H /* Statistics counters collected by the MAC */ struct e1000_hw_stats { - uint64_t crcerrs; - uint64_t algnerrc; - uint64_t symerrs; - uint64_t rxerrc; - uint64_t txerrc; - uint64_t mpc; - uint64_t scc; - uint64_t ecol; - uint64_t mcc; - uint64_t latecol; - uint64_t colc; - uint64_t dc; - uint64_t tncrs; - uint64_t sec; - uint64_t cexterr; - uint64_t rlec; - uint64_t xonrxc; - uint64_t xontxc; - uint64_t xoffrxc; - uint64_t xofftxc; - uint64_t fcruc; - uint64_t prc64; - uint64_t prc127; - uint64_t prc255; - uint64_t prc511; - uint64_t prc1023; - uint64_t prc1522; - uint64_t gprc; - uint64_t bprc; - uint64_t mprc; - uint64_t gptc; - uint64_t gorcl; - uint64_t gorch; - uint64_t gotcl; - uint64_t gotch; - uint64_t rnbc; - uint64_t ruc; - uint64_t rfc; - uint64_t roc; - uint64_t rlerrc; - uint64_t rjc; - uint64_t mgprc; - uint64_t mgpdc; - uint64_t mgptc; - uint64_t torl; - uint64_t torh; - uint64_t totl; - uint64_t toth; - uint64_t tpr; - uint64_t tpt; - uint64_t ptc64; - uint64_t ptc127; - uint64_t ptc255; - uint64_t ptc511; - uint64_t ptc1023; - uint64_t ptc1522; - uint64_t mptc; - uint64_t bptc; - uint64_t tsctc; - uint64_t tsctfc; - uint64_t iac; - uint64_t icrxptc; - uint64_t icrxatc; - uint64_t ictxptc; - uint64_t ictxatc; - uint64_t ictxqec; - uint64_t ictxqmtc; - uint64_t icrxdmtc; - uint64_t icrxoc; + uint64_t crcerrs; + uint64_t algnerrc; + uint64_t symerrs; + uint64_t rxerrc; + uint64_t txerrc; + uint64_t mpc; + uint64_t scc; + uint64_t ecol; + uint64_t mcc; + uint64_t latecol; + uint64_t colc; + uint64_t dc; + uint64_t tncrs; + uint64_t sec; + uint64_t cexterr; + uint64_t rlec; + uint64_t xonrxc; + uint64_t xontxc; + uint64_t xoffrxc; + uint64_t xofftxc; + uint64_t fcruc; + uint64_t prc64; + uint64_t prc127; + uint64_t prc255; + uint64_t prc511; + uint64_t prc1023; + uint64_t prc1522; + uint64_t gprc; + uint64_t bprc; + uint64_t mprc; + uint64_t gptc; + uint64_t gorcl; + uint64_t gorch; + uint64_t gotcl; + uint64_t gotch; + uint64_t rnbc; + uint64_t ruc; + uint64_t rfc; + uint64_t roc; + uint64_t rlerrc; + uint64_t rjc; + uint64_t mgprc; + uint64_t mgpdc; + uint64_t mgptc; + uint64_t torl; + uint64_t torh; + uint64_t totl; + uint64_t toth; + uint64_t tpr; + uint64_t tpt; + uint64_t ptc64; + uint64_t ptc127; + uint64_t ptc255; + uint64_t ptc511; + uint64_t ptc1023; + uint64_t ptc1522; + uint64_t mptc; + uint64_t bptc; + uint64_t tsctc; + uint64_t tsctfc; + uint64_t iac; + uint64_t icrxptc; + uint64_t icrxatc; + uint64_t ictxptc; + uint64_t ictxatc; + uint64_t ictxqec; + uint64_t ictxqmtc; + uint64_t icrxdmtc; + uint64_t icrxoc; }; /* Structure containing variables used by the shared code (e1000_hw.c) */ struct e1000_hw { - uint8_t __iomem *hw_addr; - uint8_t __iomem *flash_address; - e1000_mac_type mac_type; - e1000_phy_type phy_type; - uint32_t phy_init_script; - e1000_media_type media_type; - void *back; - struct e1000_shadow_ram *eeprom_shadow_ram; - uint32_t flash_bank_size; - uint32_t flash_base_addr; - e1000_fc_type fc; - e1000_bus_speed bus_speed; - e1000_bus_width bus_width; - e1000_bus_type bus_type; - struct e1000_eeprom_info eeprom; - e1000_ms_type master_slave; - e1000_ms_type original_master_slave; - e1000_ffe_config ffe_config_state; - uint32_t asf_firmware_present; - uint32_t eeprom_semaphore_present; - uint32_t swfw_sync_present; - uint32_t swfwhw_semaphore_present; - unsigned long io_base; - uint32_t phy_id; - uint32_t phy_revision; - uint32_t phy_addr; - uint32_t original_fc; - uint32_t txcw; - uint32_t autoneg_failed; - uint32_t max_frame_size; - uint32_t min_frame_size; - uint32_t mc_filter_type; - uint32_t num_mc_addrs; - uint32_t collision_delta; - uint32_t tx_packet_delta; - uint32_t ledctl_default; - uint32_t ledctl_mode1; - uint32_t ledctl_mode2; - boolean_t tx_pkt_filtering; - struct e1000_host_mng_dhcp_cookie mng_cookie; - uint16_t phy_spd_default; - uint16_t autoneg_advertised; - uint16_t pci_cmd_word; - uint16_t fc_high_water; - uint16_t fc_low_water; - uint16_t fc_pause_time; - uint16_t current_ifs_val; - uint16_t ifs_min_val; - uint16_t ifs_max_val; - uint16_t ifs_step_size; - uint16_t ifs_ratio; - uint16_t device_id; - uint16_t vendor_id; - uint16_t subsystem_id; - uint16_t subsystem_vendor_id; - uint8_t revision_id; - uint8_t autoneg; - uint8_t mdix; - uint8_t forced_speed_duplex; - uint8_t wait_autoneg_complete; - uint8_t dma_fairness; - uint8_t mac_addr[NODE_ADDRESS_SIZE]; - uint8_t perm_mac_addr[NODE_ADDRESS_SIZE]; - boolean_t disable_polarity_correction; - boolean_t speed_downgraded; - e1000_smart_speed smart_speed; - e1000_dsp_config dsp_config_state; - boolean_t get_link_status; - boolean_t serdes_link_down; - boolean_t tbi_compatibility_en; - boolean_t tbi_compatibility_on; - boolean_t laa_is_present; - boolean_t phy_reset_disable; - boolean_t initialize_hw_bits_disable; - boolean_t fc_send_xon; - boolean_t fc_strict_ieee; - boolean_t report_tx_early; - boolean_t adaptive_ifs; - boolean_t ifs_params_forced; - boolean_t in_ifs_mode; - boolean_t mng_reg_access_disabled; - boolean_t leave_av_bit_off; - boolean_t kmrn_lock_loss_workaround_disabled; - boolean_t bad_tx_carr_stats_fd; - boolean_t has_manc2h; - boolean_t rx_needs_kicking; - boolean_t has_smbus; + uint8_t __iomem *hw_addr; + uint8_t __iomem *flash_address; + e1000_mac_type mac_type; + e1000_phy_type phy_type; + uint32_t phy_init_script; + e1000_media_type media_type; + void *back; + struct e1000_shadow_ram *eeprom_shadow_ram; + uint32_t flash_bank_size; + uint32_t flash_base_addr; + e1000_fc_type fc; + e1000_bus_speed bus_speed; + e1000_bus_width bus_width; + e1000_bus_type bus_type; + struct e1000_eeprom_info eeprom; + e1000_ms_type master_slave; + e1000_ms_type original_master_slave; + e1000_ffe_config ffe_config_state; + uint32_t asf_firmware_present; + uint32_t eeprom_semaphore_present; + uint32_t swfw_sync_present; + uint32_t swfwhw_semaphore_present; + unsigned long io_base; + uint32_t phy_id; + uint32_t phy_revision; + uint32_t phy_addr; + uint32_t original_fc; + uint32_t txcw; + uint32_t autoneg_failed; + uint32_t max_frame_size; + uint32_t min_frame_size; + uint32_t mc_filter_type; + uint32_t num_mc_addrs; + uint32_t collision_delta; + uint32_t tx_packet_delta; + uint32_t ledctl_default; + uint32_t ledctl_mode1; + uint32_t ledctl_mode2; + boolean_t tx_pkt_filtering; + struct e1000_host_mng_dhcp_cookie mng_cookie; + uint16_t phy_spd_default; + uint16_t autoneg_advertised; + uint16_t pci_cmd_word; + uint16_t fc_high_water; + uint16_t fc_low_water; + uint16_t fc_pause_time; + uint16_t current_ifs_val; + uint16_t ifs_min_val; + uint16_t ifs_max_val; + uint16_t ifs_step_size; + uint16_t ifs_ratio; + uint16_t device_id; + uint16_t vendor_id; + uint16_t subsystem_id; + uint16_t subsystem_vendor_id; + uint8_t revision_id; + uint8_t autoneg; + uint8_t mdix; + uint8_t forced_speed_duplex; + uint8_t wait_autoneg_complete; + uint8_t dma_fairness; + uint8_t mac_addr[NODE_ADDRESS_SIZE]; + uint8_t perm_mac_addr[NODE_ADDRESS_SIZE]; + boolean_t disable_polarity_correction; + boolean_t speed_downgraded; + e1000_smart_speed smart_speed; + e1000_dsp_config dsp_config_state; + boolean_t get_link_status; + boolean_t serdes_link_down; + boolean_t tbi_compatibility_en; + boolean_t tbi_compatibility_on; + boolean_t laa_is_present; + boolean_t phy_reset_disable; + boolean_t initialize_hw_bits_disable; + boolean_t fc_send_xon; + boolean_t fc_strict_ieee; + boolean_t report_tx_early; + boolean_t adaptive_ifs; + boolean_t ifs_params_forced; + boolean_t in_ifs_mode; + boolean_t mng_reg_access_disabled; + boolean_t leave_av_bit_off; + boolean_t kmrn_lock_loss_workaround_disabled; }; @@ -2423,7 +2418,6 @@ struct e1000_host_command_info { #define E1000_PBA_8K 0x0008 /* 8KB, default Rx allocation */ #define E1000_PBA_12K 0x000C /* 12KB, default Rx allocation */ #define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */ -#define E1000_PBA_20K 0x0014 #define E1000_PBA_22K 0x0016 #define E1000_PBA_24K 0x0018 #define E1000_PBA_30K 0x001E diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index 4c1ff752048c..73f3a85fd238 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -213,12 +213,6 @@ static void e1000_netpoll (struct net_device *netdev); extern void e1000_check_options(struct e1000_adapter *adapter); -#define COPYBREAK_DEFAULT 256 -static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT; -module_param(copybreak, uint, 0644); -MODULE_PARM_DESC(copybreak, - "Maximum size of packet that is copied to a new buffer on receive"); - static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state); static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev); @@ -270,13 +264,7 @@ e1000_init_module(void) printk(KERN_INFO "%s\n", e1000_copyright); ret = pci_register_driver(&e1000_driver); - if (copybreak != COPYBREAK_DEFAULT) { - if (copybreak == 0) - printk(KERN_INFO "e1000: copybreak disabled\n"); - else - printk(KERN_INFO "e1000: copybreak enabled for " - "packets <= %u bytes\n", copybreak); - } + return ret; } @@ -476,52 +464,6 @@ e1000_get_hw_control(struct e1000_adapter *adapter) } } -static void -e1000_init_manageability(struct e1000_adapter *adapter) -{ - if (adapter->en_mng_pt) { - uint32_t manc = E1000_READ_REG(&adapter->hw, MANC); - - /* disable hardware interception of ARP */ - manc &= ~(E1000_MANC_ARP_EN); - - /* enable receiving management packets to the host */ - /* this will probably generate destination unreachable messages - * from the host OS, but the packets will be handled on SMBUS */ - if (adapter->hw.has_manc2h) { - uint32_t manc2h = E1000_READ_REG(&adapter->hw, MANC2H); - - manc |= E1000_MANC_EN_MNG2HOST; -#define E1000_MNG2HOST_PORT_623 (1 << 5) -#define E1000_MNG2HOST_PORT_664 (1 << 6) - manc2h |= E1000_MNG2HOST_PORT_623; - manc2h |= E1000_MNG2HOST_PORT_664; - E1000_WRITE_REG(&adapter->hw, MANC2H, manc2h); - } - - E1000_WRITE_REG(&adapter->hw, MANC, manc); - } -} - -static void -e1000_release_manageability(struct e1000_adapter *adapter) -{ - if (adapter->en_mng_pt) { - uint32_t manc = E1000_READ_REG(&adapter->hw, MANC); - - /* re-enable hardware interception of ARP */ - manc |= E1000_MANC_ARP_EN; - - if (adapter->hw.has_manc2h) - manc &= ~E1000_MANC_EN_MNG2HOST; - - /* don't explicitly have to mess with MANC2H since - * MANC has an enable disable that gates MANC2H */ - - E1000_WRITE_REG(&adapter->hw, MANC, manc); - } -} - int e1000_up(struct e1000_adapter *adapter) { @@ -533,7 +475,6 @@ e1000_up(struct e1000_adapter *adapter) e1000_set_multi(netdev); e1000_restore_vlan(adapter); - e1000_init_manageability(adapter); e1000_configure_tx(adapter); e1000_setup_rctl(adapter); @@ -556,8 +497,7 @@ e1000_up(struct e1000_adapter *adapter) clear_bit(__E1000_DOWN, &adapter->flags); - /* fire a link change interrupt to start the watchdog */ - E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_LSC); + mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); return 0; } @@ -674,34 +614,16 @@ e1000_reinit_locked(struct e1000_adapter *adapter) void e1000_reset(struct e1000_adapter *adapter) { - uint32_t pba = 0, tx_space, min_tx_space, min_rx_space; + uint32_t pba, manc; uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF; - boolean_t legacy_pba_adjust = FALSE; /* Repartition Pba for greater than 9k mtu * To take effect CTRL.RST is required. */ switch (adapter->hw.mac_type) { - case e1000_82542_rev2_0: - case e1000_82542_rev2_1: - case e1000_82543: - case e1000_82544: - case e1000_82540: - case e1000_82541: - case e1000_82541_rev_2: - legacy_pba_adjust = TRUE; - pba = E1000_PBA_48K; - break; - case e1000_82545: - case e1000_82545_rev_3: - case e1000_82546: - case e1000_82546_rev_3: - pba = E1000_PBA_48K; - break; case e1000_82547: case e1000_82547_rev_2: - legacy_pba_adjust = TRUE; pba = E1000_PBA_30K; break; case e1000_82571: @@ -710,80 +632,27 @@ e1000_reset(struct e1000_adapter *adapter) pba = E1000_PBA_38K; break; case e1000_82573: - pba = E1000_PBA_20K; + pba = E1000_PBA_12K; break; case e1000_ich8lan: pba = E1000_PBA_8K; - case e1000_undefined: - case e1000_num_macs: + break; + default: + pba = E1000_PBA_48K; break; } - if (legacy_pba_adjust == TRUE) { - if (adapter->netdev->mtu > E1000_RXBUFFER_8192) - pba -= 8; /* allocate more FIFO for Tx */ + if ((adapter->hw.mac_type != e1000_82573) && + (adapter->netdev->mtu > E1000_RXBUFFER_8192)) + pba -= 8; /* allocate more FIFO for Tx */ - if (adapter->hw.mac_type == e1000_82547) { - adapter->tx_fifo_head = 0; - adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT; - adapter->tx_fifo_size = - (E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT; - atomic_set(&adapter->tx_fifo_stall, 0); - } - } else if (adapter->hw.max_frame_size > MAXIMUM_ETHERNET_FRAME_SIZE) { - /* adjust PBA for jumbo frames */ - E1000_WRITE_REG(&adapter->hw, PBA, pba); - - /* To maintain wire speed transmits, the Tx FIFO should be - * large enough to accomodate two full transmit packets, - * rounded up to the next 1KB and expressed in KB. Likewise, - * the Rx FIFO should be large enough to accomodate at least - * one full receive packet and is similarly rounded up and - * expressed in KB. */ - pba = E1000_READ_REG(&adapter->hw, PBA); - /* upper 16 bits has Tx packet buffer allocation size in KB */ - tx_space = pba >> 16; - /* lower 16 bits has Rx packet buffer allocation size in KB */ - pba &= 0xffff; - /* don't include ethernet FCS because hardware appends/strips */ - min_rx_space = adapter->netdev->mtu + ENET_HEADER_SIZE + - VLAN_TAG_SIZE; - min_tx_space = min_rx_space; - min_tx_space *= 2; - E1000_ROUNDUP(min_tx_space, 1024); - min_tx_space >>= 10; - E1000_ROUNDUP(min_rx_space, 1024); - min_rx_space >>= 10; - - /* If current Tx allocation is less than the min Tx FIFO size, - * and the min Tx FIFO size is less than the current Rx FIFO - * allocation, take space away from current Rx allocation */ - if (tx_space < min_tx_space && - ((min_tx_space - tx_space) < pba)) { - pba = pba - (min_tx_space - tx_space); - - /* PCI/PCIx hardware has PBA alignment constraints */ - switch (adapter->hw.mac_type) { - case e1000_82545 ... e1000_82546_rev_3: - pba &= ~(E1000_PBA_8K - 1); - break; - default: - break; - } - /* if short on rx space, rx wins and must trump tx - * adjustment or use Early Receive if available */ - if (pba < min_rx_space) { - switch (adapter->hw.mac_type) { - case e1000_82573: - /* ERT enabled in e1000_configure_rx */ - break; - default: - pba = min_rx_space; - break; - } - } - } + if (adapter->hw.mac_type == e1000_82547) { + adapter->tx_fifo_head = 0; + adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT; + adapter->tx_fifo_size = + (E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT; + atomic_set(&adapter->tx_fifo_stall, 0); } E1000_WRITE_REG(&adapter->hw, PBA, pba); @@ -816,20 +685,6 @@ e1000_reset(struct e1000_adapter *adapter) if (e1000_init_hw(&adapter->hw)) DPRINTK(PROBE, ERR, "Hardware Error\n"); e1000_update_mng_vlan(adapter); - - /* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */ - if (adapter->hw.mac_type >= e1000_82544 && - adapter->hw.mac_type <= e1000_82547_rev_2 && - adapter->hw.autoneg == 1 && - adapter->hw.autoneg_advertised == ADVERTISE_1000_FULL) { - uint32_t ctrl = E1000_READ_REG(&adapter->hw, CTRL); - /* clear phy power management bit if we are in gig only mode, - * which if enabled will attempt negotiation to 100Mb, which - * can cause a loss of link at power off or driver unload */ - ctrl &= ~E1000_CTRL_SWDPIN3; - E1000_WRITE_REG(&adapter->hw, CTRL, ctrl); - } - /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ E1000_WRITE_REG(&adapter->hw, VET, ETHERNET_IEEE_VLAN_TYPE); @@ -850,7 +705,14 @@ e1000_reset(struct e1000_adapter *adapter) phy_data); } - e1000_release_manageability(adapter); + if ((adapter->en_mng_pt) && + (adapter->hw.mac_type >= e1000_82540) && + (adapter->hw.mac_type < e1000_82571) && + (adapter->hw.media_type == e1000_media_type_copper)) { + manc = E1000_READ_REG(&adapter->hw, MANC); + manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST); + E1000_WRITE_REG(&adapter->hw, MANC, manc); + } } /** @@ -995,12 +857,6 @@ e1000_probe(struct pci_dev *pdev, (adapter->hw.mac_type != e1000_82547)) netdev->features |= NETIF_F_TSO; -#ifdef CONFIG_DEBUG_SLAB - /* 82544's work arounds do not play nicely with DEBUG SLAB */ - if (adapter->hw.mac_type == e1000_82544) - netdev->features &= ~NETIF_F_TSO; -#endif - #ifdef NETIF_F_TSO6 if (adapter->hw.mac_type > e1000_82547_rev_2) netdev->features |= NETIF_F_TSO6; @@ -1222,13 +1078,22 @@ e1000_remove(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); + uint32_t manc; #ifdef CONFIG_E1000_NAPI int i; #endif flush_scheduled_work(); - e1000_release_manageability(adapter); + if (adapter->hw.mac_type >= e1000_82540 && + adapter->hw.mac_type < e1000_82571 && + adapter->hw.media_type == e1000_media_type_copper) { + manc = E1000_READ_REG(&adapter->hw, MANC); + if (manc & E1000_MANC_SMBUS_EN) { + manc |= E1000_MANC_ARP_EN; + E1000_WRITE_REG(&adapter->hw, MANC, manc); + } + } /* Release control of h/w to f/w. If f/w is AMT enabled, this * would have already happened in close and is redundant. */ @@ -1666,9 +1531,9 @@ e1000_configure_tx(struct e1000_adapter *adapter) } /* Set the default values for the Tx Inter Packet Gap timer */ - if (adapter->hw.mac_type <= e1000_82547_rev_2 && - (hw->media_type == e1000_media_type_fiber || - hw->media_type == e1000_media_type_internal_serdes)) + + if (hw->media_type == e1000_media_type_fiber || + hw->media_type == e1000_media_type_internal_serdes) tipg = DEFAULT_82543_TIPG_IPGT_FIBER; else tipg = DEFAULT_82543_TIPG_IPGT_COPPER; @@ -2663,13 +2528,6 @@ e1000_watchdog(unsigned long data) netif_wake_queue(netdev); mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ); adapter->smartspeed = 0; - } else { - /* make sure the receive unit is started */ - if (adapter->hw.rx_needs_kicking) { - struct e1000_hw *hw = &adapter->hw; - uint32_t rctl = E1000_READ_REG(hw, RCTL); - E1000_WRITE_REG(hw, RCTL, rctl | E1000_RCTL_EN); - } } } else { if (netif_carrier_ok(netdev)) { @@ -2770,34 +2628,29 @@ static unsigned int e1000_update_itr(struct e1000_adapter *adapter, if (packets == 0) goto update_itr_done; + switch (itr_setting) { case lowest_latency: - /* jumbo frames get bulk treatment*/ - if (bytes/packets > 8000) - retval = bulk_latency; - else if ((packets < 5) && (bytes > 512)) + if ((packets < 5) && (bytes > 512)) retval = low_latency; break; case low_latency: /* 50 usec aka 20000 ints/s */ if (bytes > 10000) { - /* jumbo frames need bulk latency setting */ - if (bytes/packets > 8000) - retval = bulk_latency; - else if ((packets < 10) || ((bytes/packets) > 1200)) + if ((packets < 10) || + ((bytes/packets) > 1200)) retval = bulk_latency; else if ((packets > 35)) retval = lowest_latency; - } else if (bytes/packets > 2000) - retval = bulk_latency; - else if (packets <= 2 && bytes < 512) + } else if (packets <= 2 && bytes < 512) retval = lowest_latency; break; case bulk_latency: /* 250 usec aka 4000 ints/s */ if (bytes > 25000) { if (packets > 35) retval = low_latency; - } else if (bytes < 6000) { - retval = low_latency; + } else { + if (bytes < 6000) + retval = low_latency; } break; } @@ -2826,20 +2679,17 @@ static void e1000_set_itr(struct e1000_adapter *adapter) adapter->tx_itr, adapter->total_tx_packets, adapter->total_tx_bytes); - /* conservative mode (itr 3) eliminates the lowest_latency setting */ - if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency) - adapter->tx_itr = low_latency; - adapter->rx_itr = e1000_update_itr(adapter, adapter->rx_itr, adapter->total_rx_packets, adapter->total_rx_bytes); - /* conservative mode (itr 3) eliminates the lowest_latency setting */ - if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency) - adapter->rx_itr = low_latency; current_itr = max(adapter->rx_itr, adapter->tx_itr); + /* conservative mode eliminates the lowest_latency setting */ + if (current_itr == lowest_latency && (adapter->itr_setting == 3)) + current_itr = low_latency; + switch (current_itr) { /* counts and packets in update_itr are dependent on these numbers */ case lowest_latency: @@ -3318,16 +3168,6 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if (skb->data_len && (hdr_len == (skb->len - skb->data_len))) { switch (adapter->hw.mac_type) { unsigned int pull_size; - case e1000_82544: - /* Make sure we have room to chop off 4 bytes, - * and that the end alignment will work out to - * this hardware's requirements - * NOTE: this is a TSO only workaround - * if end byte alignment not correct move us - * into the next dword */ - if ((unsigned long)(skb->tail - 1) & 4) - break; - /* fall through */ case e1000_82571: case e1000_82572: case e1000_82573: @@ -3579,11 +3419,12 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE; netdev->mtu = new_mtu; - adapter->hw.max_frame_size = max_frame; if (netif_running(netdev)) e1000_reinit_locked(adapter); + adapter->hw.max_frame_size = max_frame; + return 0; } @@ -3732,11 +3573,6 @@ e1000_update_stats(struct e1000_adapter *adapter) adapter->net_stats.tx_aborted_errors = adapter->stats.ecol; adapter->net_stats.tx_window_errors = adapter->stats.latecol; adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs; - if (adapter->hw.bad_tx_carr_stats_fd && - adapter->link_duplex == FULL_DUPLEX) { - adapter->net_stats.tx_carrier_errors = 0; - adapter->stats.tncrs = 0; - } /* Tx Dropped needs to be maintained elsewhere */ @@ -3754,13 +3590,6 @@ e1000_update_stats(struct e1000_adapter *adapter) adapter->phy_stats.receive_errors += phy_tmp; } - /* Management Stats */ - if (adapter->hw.has_smbus) { - adapter->stats.mgptc += E1000_READ_REG(hw, MGTPTC); - adapter->stats.mgprc += E1000_READ_REG(hw, MGTPRC); - adapter->stats.mgpdc += E1000_READ_REG(hw, MGTPDC); - } - spin_unlock_irqrestore(&adapter->stats_lock, flags); } #ifdef CONFIG_PCI_MSI @@ -4039,11 +3868,11 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, cleaned = (i == eop); if (cleaned) { - struct sk_buff *skb = buffer_info->skb; - unsigned int segs = skb_shinfo(skb)->gso_segs; - total_tx_packets += segs; + /* this packet count is wrong for TSO but has a + * tendency to make dynamic ITR change more + * towards bulk */ total_tx_packets++; - total_tx_bytes += skb->len; + total_tx_bytes += buffer_info->skb->len; } e1000_unmap_and_free_tx_resource(adapter, buffer_info); tx_desc->upper.data = 0; @@ -4265,7 +4094,8 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, /* code added for copybreak, this should improve * performance for small packets with large amounts * of reassembly being done in the stack */ - if (length < copybreak) { +#define E1000_CB_LENGTH 256 + if (length < E1000_CB_LENGTH) { struct sk_buff *new_skb = netdev_alloc_skb(netdev, length + NET_IP_ALIGN); if (new_skb) { @@ -4423,7 +4253,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, /* page alloc/put takes too long and effects small packet * throughput, so unsplit small packets and save the alloc/put*/ - if (l1 && (l1 <= copybreak) && ((length + l1) <= adapter->rx_ps_bsize0)) { + if (l1 && ((length + l1) <= adapter->rx_ps_bsize0)) { u8 *vaddr; /* there is no documentation about how to call * kmap_atomic, so we can't hold the mapping @@ -5168,7 +4998,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); - uint32_t ctrl, ctrl_ext, rctl, status; + uint32_t ctrl, ctrl_ext, rctl, manc, status; uint32_t wufc = adapter->wol; #ifdef CONFIG_PM int retval = 0; @@ -5237,12 +5067,16 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) pci_enable_wake(pdev, PCI_D3cold, 0); } - e1000_release_manageability(adapter); - - /* make sure adapter isn't asleep if manageability is enabled */ - if (adapter->en_mng_pt) { - pci_enable_wake(pdev, PCI_D3hot, 1); - pci_enable_wake(pdev, PCI_D3cold, 1); + if (adapter->hw.mac_type >= e1000_82540 && + adapter->hw.mac_type < e1000_82571 && + adapter->hw.media_type == e1000_media_type_copper) { + manc = E1000_READ_REG(&adapter->hw, MANC); + if (manc & E1000_MANC_SMBUS_EN) { + manc |= E1000_MANC_ARP_EN; + E1000_WRITE_REG(&adapter->hw, MANC, manc); + pci_enable_wake(pdev, PCI_D3hot, 1); + pci_enable_wake(pdev, PCI_D3cold, 1); + } } if (adapter->hw.phy_type == e1000_phy_igp_3) @@ -5268,7 +5102,7 @@ e1000_resume(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); - uint32_t err; + uint32_t manc, err; pci_set_power_state(pdev, PCI_D0); e1000_pci_restore_state(adapter); @@ -5288,13 +5122,19 @@ e1000_resume(struct pci_dev *pdev) e1000_reset(adapter); E1000_WRITE_REG(&adapter->hw, WUS, ~0); - e1000_init_manageability(adapter); - if (netif_running(netdev)) e1000_up(adapter); netif_device_attach(netdev); + if (adapter->hw.mac_type >= e1000_82540 && + adapter->hw.mac_type < e1000_82571 && + adapter->hw.media_type == e1000_media_type_copper) { + manc = E1000_READ_REG(&adapter->hw, MANC); + manc &= ~(E1000_MANC_ARP_EN); + E1000_WRITE_REG(&adapter->hw, MANC, manc); + } + /* If the controller is 82573 and f/w is AMT, do not set * DRV_LOAD until the interface is up. For all other cases, * let the f/w know that the h/w is now under the control @@ -5395,8 +5235,7 @@ static void e1000_io_resume(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev->priv; - - e1000_init_manageability(adapter); + uint32_t manc, swsm; if (netif_running(netdev)) { if (e1000_up(adapter)) { @@ -5407,14 +5246,26 @@ static void e1000_io_resume(struct pci_dev *pdev) netif_device_attach(netdev); - /* If the controller is 82573 and f/w is AMT, do not set - * DRV_LOAD until the interface is up. For all other cases, - * let the f/w know that the h/w is now under the control - * of the driver. */ - if (adapter->hw.mac_type != e1000_82573 || - !e1000_check_mng_mode(&adapter->hw)) - e1000_get_hw_control(adapter); + if (adapter->hw.mac_type >= e1000_82540 && + adapter->hw.mac_type < e1000_82571 && + adapter->hw.media_type == e1000_media_type_copper) { + manc = E1000_READ_REG(&adapter->hw, MANC); + manc &= ~(E1000_MANC_ARP_EN); + E1000_WRITE_REG(&adapter->hw, MANC, manc); + } + + switch (adapter->hw.mac_type) { + case e1000_82573: + swsm = E1000_READ_REG(&adapter->hw, SWSM); + E1000_WRITE_REG(&adapter->hw, SWSM, + swsm | E1000_SWSM_DRV_LOAD); + break; + default: + break; + } + if (netif_running(netdev)) + mod_timer(&adapter->watchdog_timer, jiffies); } /* e1000_main.c */ diff --git a/trunk/drivers/net/e1000/e1000_param.c b/trunk/drivers/net/e1000/e1000_param.c index cf2a279307e1..cbfcd7f2889f 100644 --- a/trunk/drivers/net/e1000/e1000_param.c +++ b/trunk/drivers/net/e1000/e1000_param.c @@ -487,9 +487,7 @@ e1000_check_options(struct e1000_adapter *adapter) e1000_validate_option(&adapter->itr, &opt, adapter); /* save the setting, because the dynamic bits change itr */ - /* clear the lower two bits because they are - * used as control */ - adapter->itr_setting = adapter->itr & ~3; + adapter->itr_setting = adapter->itr; break; } } else { diff --git a/trunk/drivers/net/forcedeth.c b/trunk/drivers/net/forcedeth.c index 2f48fe9a29a7..439f41338291 100644 --- a/trunk/drivers/net/forcedeth.c +++ b/trunk/drivers/net/forcedeth.c @@ -3,7 +3,8 @@ * * Note: This driver is a cleanroom reimplementation based on reverse * engineered documentation written by Carl-Daniel Hailfinger - * and Andrew de Quincey. + * and Andrew de Quincey. It's neither supported nor endorsed + * by NVIDIA Corp. Use at your own risk. * * NVIDIA, nForce and other NVIDIA marks are trademarks or registered * trademarks of NVIDIA Corporation in the United States and other @@ -13,7 +14,7 @@ * Copyright (C) 2004 Andrew de Quincey (wol support) * Copyright (C) 2004 Carl-Daniel Hailfinger (invalid MAC handling, insane * IRQ rate fixes, bigendian fixes, cleanups, verification) - * Copyright (c) 2004,5,6 NVIDIA Corporation + * Copyright (c) 2004 NVIDIA Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -2575,15 +2576,14 @@ static int nv_napi_poll(struct net_device *dev, int *budget) int pkts, limit = min(*budget, dev->quota); struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); - unsigned long flags; pkts = nv_rx_process(dev, limit); if (nv_alloc_rx(dev)) { - spin_lock_irqsave(&np->lock, flags); + spin_lock_irq(&np->lock); if (!np->in_shutdown) mod_timer(&np->oom_kick, jiffies + OOM_REFILL); - spin_unlock_irqrestore(&np->lock, flags); + spin_unlock_irq(&np->lock); } if (pkts < limit) { @@ -2591,15 +2591,13 @@ static int nv_napi_poll(struct net_device *dev, int *budget) netif_rx_complete(dev); /* re-enable receive interrupts */ - spin_lock_irqsave(&np->lock, flags); - + spin_lock_irq(&np->lock); np->irqmask |= NVREG_IRQ_RX_ALL; if (np->msi_flags & NV_MSI_X_ENABLED) writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask); else writel(np->irqmask, base + NvRegIrqMask); - - spin_unlock_irqrestore(&np->lock, flags); + spin_unlock_irq(&np->lock); return 0; } else { /* used up our quantum, so reschedule */ diff --git a/trunk/drivers/net/ibm_emac/ibm_emac_phy.c b/trunk/drivers/net/ibm_emac/ibm_emac_phy.c index 9074f76ee2bf..4a97024061e5 100644 --- a/trunk/drivers/net/ibm_emac/ibm_emac_phy.c +++ b/trunk/drivers/net/ibm_emac/ibm_emac_phy.c @@ -309,7 +309,7 @@ int mii_phy_probe(struct mii_phy *phy, int address) { struct mii_phy_def *def; int i; - int id; + u32 id; phy->autoneg = AUTONEG_DISABLE; phy->advertising = 0; @@ -324,8 +324,6 @@ int mii_phy_probe(struct mii_phy *phy, int address) /* Read ID and find matching entry */ id = (phy_read(phy, MII_PHYSID1) << 16) | phy_read(phy, MII_PHYSID2); - if (id < 0) - return -ENODEV; for (i = 0; (def = mii_phy_table[i]) != NULL; i++) if ((id & def->phy_id_mask) == def->phy_id) break; diff --git a/trunk/drivers/net/myri10ge/myri10ge.c b/trunk/drivers/net/myri10ge/myri10ge.c index 07cf574197e5..94ac168be593 100644 --- a/trunk/drivers/net/myri10ge/myri10ge.c +++ b/trunk/drivers/net/myri10ge/myri10ge.c @@ -199,6 +199,8 @@ struct myri10ge_priv { unsigned long serial_number; int vendor_specific_offset; int fw_multicast_support; + u32 devctl; + u16 msi_flags; u32 read_dma; u32 write_dma; u32 read_write_dma; @@ -226,7 +228,7 @@ module_param(myri10ge_small_bytes, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(myri10ge_small_bytes, "Threshold of small packets\n"); static int myri10ge_msi = 1; /* enable msi by default */ -module_param(myri10ge_msi, int, S_IRUGO | S_IWUSR); +module_param(myri10ge_msi, int, S_IRUGO); MODULE_PARM_DESC(myri10ge_msi, "Enable Message Signalled Interrupts\n"); static int myri10ge_intr_coal_delay = 25; @@ -719,10 +721,12 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd, 0); mgp->irq_claim = (__iomem __be32 *) (mgp->sram + cmd.data0); - status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET, - &cmd, 0); - mgp->irq_deassert = (__iomem __be32 *) (mgp->sram + cmd.data0); + if (!mgp->msi_enabled) { + status |= myri10ge_send_cmd + (mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET, &cmd, 0); + mgp->irq_deassert = (__iomem __be32 *) (mgp->sram + cmd.data0); + } status |= myri10ge_send_cmd (mgp, MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET, &cmd, 0); mgp->intr_coal_delay_ptr = (__iomem __be32 *) (mgp->sram + cmd.data0); @@ -1615,41 +1619,6 @@ static void myri10ge_free_rings(struct net_device *dev) mgp->tx.req_list = NULL; } -static int myri10ge_request_irq(struct myri10ge_priv *mgp) -{ - struct pci_dev *pdev = mgp->pdev; - int status; - - if (myri10ge_msi) { - status = pci_enable_msi(pdev); - if (status != 0) - dev_err(&pdev->dev, - "Error %d setting up MSI; falling back to xPIC\n", - status); - else - mgp->msi_enabled = 1; - } else { - mgp->msi_enabled = 0; - } - status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED, - mgp->dev->name, mgp); - if (status != 0) { - dev_err(&pdev->dev, "failed to allocate IRQ\n"); - if (mgp->msi_enabled) - pci_disable_msi(pdev); - } - return status; -} - -static void myri10ge_free_irq(struct myri10ge_priv *mgp) -{ - struct pci_dev *pdev = mgp->pdev; - - free_irq(pdev->irq, mgp); - if (mgp->msi_enabled) - pci_disable_msi(pdev); -} - static int myri10ge_open(struct net_device *dev) { struct myri10ge_priv *mgp; @@ -1665,13 +1634,10 @@ static int myri10ge_open(struct net_device *dev) status = myri10ge_reset(mgp); if (status != 0) { printk(KERN_ERR "myri10ge: %s: failed reset\n", dev->name); - goto abort_with_nothing; + mgp->running = MYRI10GE_ETH_STOPPED; + return -ENXIO; } - status = myri10ge_request_irq(mgp); - if (status != 0) - goto abort_with_nothing; - /* decide what small buffer size to use. For good TCP rx * performance, it is important to not receive 1514 byte * frames into jumbo buffers, as it confuses the socket buffer @@ -1711,7 +1677,7 @@ static int myri10ge_open(struct net_device *dev) "myri10ge: %s: failed to get ring sizes or locations\n", dev->name); mgp->running = MYRI10GE_ETH_STOPPED; - goto abort_with_irq; + return -ENXIO; } if (mgp->mtrr >= 0) { @@ -1742,7 +1708,7 @@ static int myri10ge_open(struct net_device *dev) status = myri10ge_allocate_rings(dev); if (status != 0) - goto abort_with_irq; + goto abort_with_nothing; /* now give firmware buffers sizes, and MTU */ cmd.data0 = dev->mtu + ETH_HLEN + VLAN_HLEN; @@ -1805,9 +1771,6 @@ static int myri10ge_open(struct net_device *dev) abort_with_rings: myri10ge_free_rings(dev); -abort_with_irq: - myri10ge_free_irq(mgp); - abort_with_nothing: mgp->running = MYRI10GE_ETH_STOPPED; return -ENOMEM; @@ -1844,7 +1807,7 @@ static int myri10ge_close(struct net_device *dev) printk(KERN_ERR "myri10ge: %s never got down irq\n", dev->name); netif_tx_disable(dev); - myri10ge_free_irq(mgp); + myri10ge_free_rings(dev); mgp->running = MYRI10GE_ETH_STOPPED; @@ -2518,6 +2481,34 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp) } } +static void myri10ge_save_state(struct myri10ge_priv *mgp) +{ + struct pci_dev *pdev = mgp->pdev; + int cap; + + pci_save_state(pdev); + /* now save PCIe and MSI state that Linux will not + * save for us */ + cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); + pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL, &mgp->devctl); + cap = pci_find_capability(pdev, PCI_CAP_ID_MSI); + pci_read_config_word(pdev, cap + PCI_MSI_FLAGS, &mgp->msi_flags); +} + +static void myri10ge_restore_state(struct myri10ge_priv *mgp) +{ + struct pci_dev *pdev = mgp->pdev; + int cap; + + /* restore PCIe and MSI state that linux will not */ + cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); + pci_write_config_dword(pdev, cap + PCI_CAP_ID_EXP, mgp->devctl); + cap = pci_find_capability(pdev, PCI_CAP_ID_MSI); + pci_write_config_word(pdev, cap + PCI_MSI_FLAGS, mgp->msi_flags); + + pci_restore_state(pdev); +} + #ifdef CONFIG_PM static int myri10ge_suspend(struct pci_dev *pdev, pm_message_t state) @@ -2538,10 +2529,11 @@ static int myri10ge_suspend(struct pci_dev *pdev, pm_message_t state) rtnl_unlock(); } myri10ge_dummy_rdma(mgp, 0); - pci_save_state(pdev); + free_irq(pdev->irq, mgp); + myri10ge_save_state(mgp); pci_disable_device(pdev); - - return pci_set_power_state(pdev, pci_choose_state(pdev, state)); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); + return 0; } static int myri10ge_resume(struct pci_dev *pdev) @@ -2563,33 +2555,34 @@ static int myri10ge_resume(struct pci_dev *pdev) mgp->dev->name); return -EIO; } - - status = pci_restore_state(pdev); - if (status) - return status; + myri10ge_restore_state(mgp); status = pci_enable_device(pdev); - if (status) { + if (status < 0) { dev_err(&pdev->dev, "failed to enable device\n"); - return status; + return -EIO; } pci_set_master(pdev); + status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED, + netdev->name, mgp); + if (status != 0) { + dev_err(&pdev->dev, "failed to allocate IRQ\n"); + goto abort_with_enabled; + } + myri10ge_reset(mgp); myri10ge_dummy_rdma(mgp, 1); /* Save configuration space to be restored if the * nic resets due to a parity error */ - pci_save_state(pdev); + myri10ge_save_state(mgp); if (netif_running(netdev)) { rtnl_lock(); - status = myri10ge_open(netdev); + myri10ge_open(netdev); rtnl_unlock(); - if (status != 0) - goto abort_with_enabled; - } netif_device_attach(netdev); @@ -2647,11 +2640,7 @@ static void myri10ge_watchdog(struct work_struct *work) * when the driver was loaded, or the last time the * nic was resumed from power saving mode. */ - pci_restore_state(mgp->pdev); - - /* save state again for accounting reasons */ - pci_save_state(mgp->pdev); - + myri10ge_restore_state(mgp); } else { /* if we get back -1's from our slot, perhaps somebody * powered off our card. Don't try to reset it in @@ -2867,6 +2856,23 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto abort_with_firmware; } + if (myri10ge_msi) { + status = pci_enable_msi(pdev); + if (status != 0) + dev_err(&pdev->dev, + "Error %d setting up MSI; falling back to xPIC\n", + status); + else + mgp->msi_enabled = 1; + } + + status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED, + netdev->name, mgp); + if (status != 0) { + dev_err(&pdev->dev, "failed to allocate IRQ\n"); + goto abort_with_firmware; + } + pci_set_drvdata(pdev, mgp); if ((myri10ge_initial_mtu + ETH_HLEN) > MYRI10GE_MAX_ETHER_MTU) myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN; @@ -2890,7 +2896,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* Save configuration space to be restored if the * nic resets due to a parity error */ - pci_save_state(pdev); + myri10ge_save_state(mgp); /* Setup the watchdog timer */ setup_timer(&mgp->watchdog_timer, myri10ge_watchdog_timer, @@ -2901,16 +2907,19 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) status = register_netdev(netdev); if (status != 0) { dev_err(&pdev->dev, "register_netdev failed: %d\n", status); - goto abort_with_state; + goto abort_with_irq; } - dev_info(dev, "%d, tx bndry %d, fw %s, WC %s\n", + dev_info(dev, "%s IRQ %d, tx bndry %d, fw %s, WC %s\n", + (mgp->msi_enabled ? "MSI" : "xPIC"), pdev->irq, mgp->tx.boundary, mgp->fw_name, (mgp->mtrr >= 0 ? "Enabled" : "Disabled")); return 0; -abort_with_state: - pci_restore_state(pdev); +abort_with_irq: + free_irq(pdev->irq, mgp); + if (mgp->msi_enabled) + pci_disable_msi(pdev); abort_with_firmware: myri10ge_dummy_rdma(mgp, 0); @@ -2961,12 +2970,12 @@ static void myri10ge_remove(struct pci_dev *pdev) flush_scheduled_work(); netdev = mgp->dev; unregister_netdev(netdev); + free_irq(pdev->irq, mgp); + if (mgp->msi_enabled) + pci_disable_msi(pdev); myri10ge_dummy_rdma(mgp, 0); - /* avoid a memory leak */ - pci_restore_state(pdev); - bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry); dma_free_coherent(&pdev->dev, bytes, mgp->rx_done.entry, mgp->rx_done.bus); diff --git a/trunk/drivers/net/netxen/netxen_nic.h b/trunk/drivers/net/netxen/netxen_nic.h index 6490acf05305..b5410bee5f21 100644 --- a/trunk/drivers/net/netxen/netxen_nic.h +++ b/trunk/drivers/net/netxen/netxen_nic.h @@ -63,7 +63,7 @@ #include "netxen_nic_hw.h" -#define NETXEN_NIC_BUILD_NO "4" +#define NETXEN_NIC_BUILD_NO "1" #define _NETXEN_NIC_LINUX_MAJOR 3 #define _NETXEN_NIC_LINUX_MINOR 3 #define _NETXEN_NIC_LINUX_SUBVERSION 2 @@ -137,7 +137,7 @@ extern struct workqueue_struct *netxen_workq; #define THIRD_PAGE_GROUP_SIZE THIRD_PAGE_GROUP_END - THIRD_PAGE_GROUP_START #define MAX_RX_BUFFER_LENGTH 1760 -#define MAX_RX_JUMBO_BUFFER_LENGTH 8062 +#define MAX_RX_JUMBO_BUFFER_LENGTH 9046 #define MAX_RX_LRO_BUFFER_LENGTH ((48*1024)-512) #define RX_DMA_MAP_LEN (MAX_RX_BUFFER_LENGTH - 2) #define RX_JUMBO_DMA_MAP_LEN \ @@ -199,9 +199,9 @@ enum { (RCV_DESC_NORMAL))) #define MAX_CMD_DESCRIPTORS 1024 -#define MAX_RCV_DESCRIPTORS 16384 -#define MAX_JUMBO_RCV_DESCRIPTORS 1024 -#define MAX_LRO_RCV_DESCRIPTORS 64 +#define MAX_RCV_DESCRIPTORS 32768 +#define MAX_JUMBO_RCV_DESCRIPTORS 4096 +#define MAX_LRO_RCV_DESCRIPTORS 2048 #define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS #define MAX_JUMBO_RCV_DESC MAX_JUMBO_RCV_DESCRIPTORS #define MAX_RCV_DESC MAX_RCV_DESCRIPTORS @@ -852,6 +852,8 @@ struct netxen_adapter { spinlock_t tx_lock; spinlock_t lock; struct work_struct watchdog_task; + struct work_struct tx_timeout_task; + struct net_device *netdev; struct timer_list watchdog_timer; u32 curr_window; @@ -885,6 +887,7 @@ struct netxen_adapter { struct netxen_recv_context recv_ctx[MAX_RCV_CTX]; int is_up; + int number; struct netxen_dummy_dma dummy_dma; /* Context interface shared between card and host */ @@ -947,7 +950,6 @@ struct netxen_port { struct pci_dev *pdev; struct net_device_stats net_stats; struct netxen_port_stats stats; - struct work_struct tx_timeout_task; }; #define PCI_OFFSET_FIRST_RANGE(adapter, off) \ @@ -1025,6 +1027,14 @@ int netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data, int len); int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data, int len); +int netxen_nic_hw_read_ioctl(struct netxen_adapter *adapter, u64 off, + void *data, int len); +int netxen_nic_hw_write_ioctl(struct netxen_adapter *adapter, u64 off, + void *data, int len); +int netxen_nic_pci_mem_write_ioctl(struct netxen_adapter *adapter, + u64 off, void *data, int size); +int netxen_nic_pci_mem_read_ioctl(struct netxen_adapter *adapter, + u64 off, void *data, int size); void netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off, int data); @@ -1057,6 +1067,9 @@ void netxen_tso_check(struct netxen_adapter *adapter, struct cmd_desc_type0 *desc, struct sk_buff *skb); int netxen_nic_hw_resources(struct netxen_adapter *adapter); void netxen_nic_clear_stats(struct netxen_adapter *adapter); +int +netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data, + struct netxen_port *port); int netxen_nic_rx_has_work(struct netxen_adapter *adapter); int netxen_nic_tx_has_work(struct netxen_adapter *adapter); void netxen_watchdog_task(struct work_struct *work); diff --git a/trunk/drivers/net/netxen/netxen_nic_ethtool.c b/trunk/drivers/net/netxen/netxen_nic_ethtool.c index 34044616b3c8..2ab4885cc950 100644 --- a/trunk/drivers/net/netxen/netxen_nic_ethtool.c +++ b/trunk/drivers/net/netxen/netxen_nic_ethtool.c @@ -42,6 +42,7 @@ #include "netxen_nic_hw.h" #include "netxen_nic.h" #include "netxen_nic_phan_reg.h" +#include "netxen_nic_ioctl.h" struct netxen_nic_stats { char stat_string[ETH_GSTRING_LEN]; @@ -78,7 +79,8 @@ static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = { {"tx_bytes", NETXEN_NIC_STAT(stats.txbytes)}, }; -#define NETXEN_NIC_STATS_LEN ARRAY_SIZE(netxen_nic_gstrings_stats) +#define NETXEN_NIC_STATS_LEN \ + sizeof(netxen_nic_gstrings_stats) / sizeof(struct netxen_nic_stats) static const char netxen_nic_gstrings_test[][ETH_GSTRING_LEN] = { "Register_Test_offline", "EEPROM_Test_offline", @@ -709,6 +711,7 @@ netxen_nic_get_ethtool_stats(struct net_device *dev, (netxen_nic_gstrings_stats[index].sizeof_stat == sizeof(u64)) ? *(u64 *) p : *(u32 *) p; } + } struct ethtool_ops netxen_nic_ethtool_ops = { diff --git a/trunk/drivers/net/netxen/netxen_nic_hw.c b/trunk/drivers/net/netxen/netxen_nic_hw.c index c0c31d1914a7..9147b6048dfb 100644 --- a/trunk/drivers/net/netxen/netxen_nic_hw.c +++ b/trunk/drivers/net/netxen/netxen_nic_hw.c @@ -376,7 +376,7 @@ void netxen_tso_check(struct netxen_adapter *adapter, ((skb->nh.iph)->ihl * sizeof(u32)) + ((skb->h.th)->doff * sizeof(u32)); netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO); - } else if (skb->ip_summed == CHECKSUM_PARTIAL) { + } else if (skb->ip_summed == CHECKSUM_COMPLETE) { if (skb->nh.iph->protocol == IPPROTO_TCP) { netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT); } else if (skb->nh.iph->protocol == IPPROTO_UDP) { @@ -997,3 +997,297 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter) fw_major, fw_minor); } +int netxen_crb_read_val(struct netxen_adapter *adapter, unsigned long off) +{ + int data; + netxen_nic_hw_read_wx(adapter, off, &data, 4); + return data; +} + +int netxen_nic_hw_write_ioctl(struct netxen_adapter *adapter, u64 off, + void *data, int len) +{ + void *addr; + u64 offset = off; + u8 *mem_ptr = NULL; + unsigned long mem_base; + unsigned long mem_page; + + if (ADDR_IN_WINDOW1(off)) { + addr = NETXEN_CRB_NORMALIZE(adapter, off); + if (!addr) { + mem_base = pci_resource_start(adapter->ahw.pdev, 0); + offset = NETXEN_CRB_NORMAL(off); + mem_page = offset & PAGE_MASK; + if (mem_page != ((offset + len - 1) & PAGE_MASK)) + mem_ptr = + ioremap(mem_base + mem_page, PAGE_SIZE * 2); + else + mem_ptr = + ioremap(mem_base + mem_page, PAGE_SIZE); + if (mem_ptr == 0UL) { + return 1; + } + addr = mem_ptr; + addr += offset & (PAGE_SIZE - 1); + } + } else { + addr = pci_base_offset(adapter, off); + if (!addr) { + mem_base = pci_resource_start(adapter->ahw.pdev, 0); + mem_page = off & PAGE_MASK; + if (mem_page != ((off + len - 1) & PAGE_MASK)) + mem_ptr = + ioremap(mem_base + mem_page, PAGE_SIZE * 2); + else + mem_ptr = + ioremap(mem_base + mem_page, PAGE_SIZE); + if (mem_ptr == 0UL) { + return 1; + } + addr = mem_ptr; + addr += off & (PAGE_SIZE - 1); + } + netxen_nic_pci_change_crbwindow(adapter, 0); + } + switch (len) { + case 1: + writeb(*(u8 *) data, addr); + break; + case 2: + writew(*(u16 *) data, addr); + break; + case 4: + writel(*(u32 *) data, addr); + break; + case 8: + writeq(*(u64 *) data, addr); + break; + default: + DPRINTK(INFO, + "writing data %lx to offset %llx, num words=%d\n", + *(unsigned long *)data, off, (len >> 3)); + + netxen_nic_hw_block_write64((u64 __iomem *) data, addr, + (len >> 3)); + break; + } + + if (!ADDR_IN_WINDOW1(off)) + netxen_nic_pci_change_crbwindow(adapter, 1); + if (mem_ptr) + iounmap(mem_ptr); + return 0; +} + +int netxen_nic_hw_read_ioctl(struct netxen_adapter *adapter, u64 off, + void *data, int len) +{ + void *addr; + u64 offset; + u8 *mem_ptr = NULL; + unsigned long mem_base; + unsigned long mem_page; + + if (ADDR_IN_WINDOW1(off)) { + addr = NETXEN_CRB_NORMALIZE(adapter, off); + if (!addr) { + mem_base = pci_resource_start(adapter->ahw.pdev, 0); + offset = NETXEN_CRB_NORMAL(off); + mem_page = offset & PAGE_MASK; + if (mem_page != ((offset + len - 1) & PAGE_MASK)) + mem_ptr = + ioremap(mem_base + mem_page, PAGE_SIZE * 2); + else + mem_ptr = + ioremap(mem_base + mem_page, PAGE_SIZE); + if (mem_ptr == 0UL) { + *(u8 *) data = 0; + return 1; + } + addr = mem_ptr; + addr += offset & (PAGE_SIZE - 1); + } + } else { + addr = pci_base_offset(adapter, off); + if (!addr) { + mem_base = pci_resource_start(adapter->ahw.pdev, 0); + mem_page = off & PAGE_MASK; + if (mem_page != ((off + len - 1) & PAGE_MASK)) + mem_ptr = + ioremap(mem_base + mem_page, PAGE_SIZE * 2); + else + mem_ptr = + ioremap(mem_base + mem_page, PAGE_SIZE); + if (mem_ptr == 0UL) + return 1; + addr = mem_ptr; + addr += off & (PAGE_SIZE - 1); + } + netxen_nic_pci_change_crbwindow(adapter, 0); + } + switch (len) { + case 1: + *(u8 *) data = readb(addr); + break; + case 2: + *(u16 *) data = readw(addr); + break; + case 4: + *(u32 *) data = readl(addr); + break; + case 8: + *(u64 *) data = readq(addr); + break; + default: + netxen_nic_hw_block_read64((u64 __iomem *) data, addr, + (len >> 3)); + break; + } + if (!ADDR_IN_WINDOW1(off)) + netxen_nic_pci_change_crbwindow(adapter, 1); + if (mem_ptr) + iounmap(mem_ptr); + return 0; +} + +int netxen_nic_pci_mem_write_ioctl(struct netxen_adapter *adapter, u64 off, + void *data, int size) +{ + void *addr; + int ret = 0; + u8 *mem_ptr = NULL; + unsigned long mem_base; + unsigned long mem_page; + + if (data == NULL || off > (128 * 1024 * 1024)) { + printk(KERN_ERR "%s: data: %p off:%llx\n", + netxen_nic_driver_name, data, off); + return 1; + } + off = netxen_nic_pci_set_window(adapter, off); + /* Corner case : Malicious user tried to break the driver by reading + last few bytes in ranges and tries to read further addresses. + */ + if (!pci_base(adapter, off + size - 1) && pci_base(adapter, off)) { + printk(KERN_ERR "%s: Invalid access to memory address range" + " 0x%llx - 0x%llx\n", netxen_nic_driver_name, off, + off + size); + return 1; + } + addr = pci_base_offset(adapter, off); + DPRINTK(INFO, "writing data %llx to offset %llx\n", + *(unsigned long long *)data, off); + if (!addr) { + mem_base = pci_resource_start(adapter->ahw.pdev, 0); + mem_page = off & PAGE_MASK; + /* Map two pages whenever user tries to access addresses in two + consecutive pages. + */ + if (mem_page != ((off + size - 1) & PAGE_MASK)) + mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2); + else + mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE); + if (mem_ptr == 0UL) { + return 1; + } + addr = mem_ptr; + addr += off & (PAGE_SIZE - 1); + } + switch (size) { + case 1: + writeb(*(u8 *) data, addr); + break; + case 2: + writew(*(u16 *) data, addr); + break; + case 4: + writel(*(u32 *) data, addr); + break; + case 8: + writeq(*(u64 *) data, addr); + break; + default: + DPRINTK(INFO, + "writing data %lx to offset %llx, num words=%d\n", + *(unsigned long *)data, off, (size >> 3)); + + netxen_nic_hw_block_write64((u64 __iomem *) data, addr, + (size >> 3)); + break; + } + + if (mem_ptr) + iounmap(mem_ptr); + DPRINTK(INFO, "wrote %llx\n", *(unsigned long long *)data); + + return ret; +} + +int netxen_nic_pci_mem_read_ioctl(struct netxen_adapter *adapter, + u64 off, void *data, int size) +{ + void *addr; + int ret = 0; + u8 *mem_ptr = NULL; + unsigned long mem_base; + unsigned long mem_page; + + if (data == NULL || off > (128 * 1024 * 1024)) { + printk(KERN_ERR "%s: data: %p off:%llx\n", + netxen_nic_driver_name, data, off); + return 1; + } + off = netxen_nic_pci_set_window(adapter, off); + /* Corner case : Malicious user tried to break the driver by reading + last few bytes in ranges and tries to read further addresses. + */ + if (!pci_base(adapter, off + size - 1) && pci_base(adapter, off)) { + printk(KERN_ERR "%s: Invalid access to memory address range" + " 0x%llx - 0x%llx\n", netxen_nic_driver_name, off, + off + size); + return 1; + } + addr = pci_base_offset(adapter, off); + if (!addr) { + mem_base = pci_resource_start(adapter->ahw.pdev, 0); + mem_page = off & PAGE_MASK; + /* Map two pages whenever user tries to access addresses in two + consecutive pages. + */ + if (mem_page != ((off + size - 1) & PAGE_MASK)) + mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2); + else + mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE); + if (mem_ptr == 0UL) { + *(u8 *) data = 0; + return 1; + } + addr = mem_ptr; + addr += off & (PAGE_SIZE - 1); + } + switch (size) { + case 1: + *(u8 *) data = readb(addr); + break; + case 2: + *(u16 *) data = readw(addr); + break; + case 4: + *(u32 *) data = readl(addr); + break; + case 8: + *(u64 *) data = readq(addr); + break; + default: + netxen_nic_hw_block_read64((u64 __iomem *) data, addr, + (size >> 3)); + break; + } + + if (mem_ptr) + iounmap(mem_ptr); + DPRINTK(INFO, "read %llx\n", *(unsigned long long *)data); + + return ret; +} diff --git a/trunk/drivers/net/netxen/netxen_nic_init.c b/trunk/drivers/net/netxen/netxen_nic_init.c index c3e41f368554..869725f0bb18 100644 --- a/trunk/drivers/net/netxen/netxen_nic_init.c +++ b/trunk/drivers/net/netxen/netxen_nic_init.c @@ -35,6 +35,7 @@ #include #include "netxen_nic.h" #include "netxen_nic_hw.h" +#include "netxen_nic_ioctl.h" #include "netxen_nic_phan_reg.h" struct crb_addr_pair { @@ -927,7 +928,7 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) } netxen_process_rcv(adapter, ctxid, desc); netxen_clear_sts_owner(desc); - netxen_set_sts_owner(desc, cpu_to_le16(STATUS_OWNER_PHANTOM)); + netxen_set_sts_owner(desc, STATUS_OWNER_PHANTOM); consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1); count++; } @@ -1022,7 +1023,7 @@ int netxen_process_cmd_ring(unsigned long data) && netif_carrier_ok(port->netdev)) && ((jiffies - port->netdev->trans_start) > port->netdev->watchdog_timeo)) { - SCHEDULE_WORK(&port->tx_timeout_task); + SCHEDULE_WORK(&port->adapter->tx_timeout_task); } last_consumer = get_next_index(last_consumer, @@ -1137,13 +1138,13 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) */ dma = pci_map_single(pdev, skb->data, rcv_desc->dma_size, PCI_DMA_FROMDEVICE); - pdesc->addr_buffer = cpu_to_le64(dma); + pdesc->addr_buffer = dma; buffer->skb = skb; buffer->state = NETXEN_BUFFER_BUSY; buffer->dma = dma; /* make a rcv descriptor */ - pdesc->reference_handle = cpu_to_le16(buffer->ref_handle); - pdesc->buffer_length = cpu_to_le32(rcv_desc->dma_size); + pdesc->reference_handle = buffer->ref_handle; + pdesc->buffer_length = rcv_desc->dma_size; DPRINTK(INFO, "done writing descripter\n"); producer = get_next_index(producer, rcv_desc->max_rx_desc_count); @@ -1231,8 +1232,8 @@ void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ctx, PCI_DMA_FROMDEVICE); /* make a rcv descriptor */ - pdesc->reference_handle = cpu_to_le16(buffer->ref_handle); - pdesc->buffer_length = cpu_to_le16(rcv_desc->dma_size); + pdesc->reference_handle = le16_to_cpu(buffer->ref_handle); + pdesc->buffer_length = le16_to_cpu(rcv_desc->dma_size); pdesc->addr_buffer = cpu_to_le64(buffer->dma); DPRINTK(INFO, "done writing descripter\n"); producer = @@ -1272,6 +1273,52 @@ int netxen_nic_tx_has_work(struct netxen_adapter *adapter) return 0; } +int +netxen_nic_fill_statistics(struct netxen_adapter *adapter, + struct netxen_port *port, + struct netxen_statistics *netxen_stats) +{ + void __iomem *addr; + + if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { + netxen_nic_pci_change_crbwindow(adapter, 0); + NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_TX_BYTE_CNT, + &(netxen_stats->tx_bytes)); + NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_TX_FRAME_CNT, + &(netxen_stats->tx_packets)); + NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_RX_BYTE_CNT, + &(netxen_stats->rx_bytes)); + NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_RX_FRAME_CNT, + &(netxen_stats->rx_packets)); + NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_AGGR_ERROR_CNT, + &(netxen_stats->rx_errors)); + NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_CRC_ERROR_CNT, + &(netxen_stats->rx_crc_errors)); + NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_OVERSIZE_FRAME_ERR, + &(netxen_stats-> + rx_long_length_error)); + NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_XGE_UNDERSIZE_FRAME_ERR, + &(netxen_stats-> + rx_short_length_error)); + + netxen_nic_pci_change_crbwindow(adapter, 1); + } else { + spin_lock_bh(&adapter->tx_lock); + netxen_stats->tx_bytes = port->stats.txbytes; + netxen_stats->tx_packets = port->stats.xmitedframes + + port->stats.xmitfinished; + netxen_stats->rx_bytes = port->stats.rxbytes; + netxen_stats->rx_packets = port->stats.no_rcv; + netxen_stats->rx_errors = port->stats.rcvdbadskb; + netxen_stats->tx_errors = port->stats.nocmddescriptor; + netxen_stats->rx_short_length_error = port->stats.uplcong; + netxen_stats->rx_long_length_error = port->stats.uphcong; + netxen_stats->rx_crc_errors = 0; + netxen_stats->rx_mac_errors = 0; + spin_unlock_bh(&adapter->tx_lock); + } + return 0; +} void netxen_nic_clear_stats(struct netxen_adapter *adapter) { @@ -1285,3 +1332,193 @@ void netxen_nic_clear_stats(struct netxen_adapter *adapter) } } +int +netxen_nic_clear_statistics(struct netxen_adapter *adapter, + struct netxen_port *port) +{ + int data = 0; + + netxen_nic_pci_change_crbwindow(adapter, 0); + + netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_TX_BYTE_CNT, &data); + netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_TX_FRAME_CNT, + &data); + netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_RX_BYTE_CNT, &data); + netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_RX_FRAME_CNT, + &data); + netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_AGGR_ERROR_CNT, + &data); + netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_CRC_ERROR_CNT, + &data); + netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_OVERSIZE_FRAME_ERR, + &data); + netxen_nic_locked_write_reg(adapter, NETXEN_NIU_XGE_UNDERSIZE_FRAME_ERR, + &data); + + netxen_nic_pci_change_crbwindow(adapter, 1); + netxen_nic_clear_stats(adapter); + return 0; +} + +int +netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data, + struct netxen_port *port) +{ + struct netxen_nic_ioctl_data data; + struct netxen_nic_ioctl_data *up_data; + int retval = 0; + struct netxen_statistics netxen_stats; + + up_data = (void *)u_data; + + DPRINTK(INFO, "doing ioctl for %p\n", adapter); + if (copy_from_user(&data, (void __user *)up_data, sizeof(data))) { + /* evil user tried to crash the kernel */ + DPRINTK(ERR, "bad copy from userland: %d\n", (int)sizeof(data)); + retval = -EFAULT; + goto error_out; + } + + /* Shouldn't access beyond legal limits of "char u[64];" member */ + if (!data.ptr && (data.size > sizeof(data.u))) { + /* evil user tried to crash the kernel */ + DPRINTK(ERR, "bad size: %d\n", data.size); + retval = -EFAULT; + goto error_out; + } + + switch (data.cmd) { + case netxen_nic_cmd_pci_read: + if ((retval = netxen_nic_hw_read_ioctl(adapter, data.off, + &(data.u), data.size))) + goto error_out; + if (copy_to_user + ((void __user *)&(up_data->u), &(data.u), data.size)) { + DPRINTK(ERR, "bad copy to userland: %d\n", + (int)sizeof(data)); + retval = -EFAULT; + goto error_out; + } + data.rv = 0; + break; + + case netxen_nic_cmd_pci_write: + if ((retval = netxen_nic_hw_write_ioctl(adapter, data.off, + &(data.u), data.size))) + goto error_out; + data.rv = 0; + break; + + case netxen_nic_cmd_pci_mem_read: + if (netxen_nic_pci_mem_read_ioctl(adapter, data.off, &(data.u), + data.size)) { + DPRINTK(ERR, "Failed to read the data.\n"); + retval = -EFAULT; + goto error_out; + } + if (copy_to_user + ((void __user *)&(up_data->u), &(data.u), data.size)) { + DPRINTK(ERR, "bad copy to userland: %d\n", + (int)sizeof(data)); + retval = -EFAULT; + goto error_out; + } + data.rv = 0; + break; + + case netxen_nic_cmd_pci_mem_write: + if ((retval = netxen_nic_pci_mem_write_ioctl(adapter, data.off, + &(data.u), + data.size))) + goto error_out; + data.rv = 0; + break; + + case netxen_nic_cmd_pci_config_read: + switch (data.size) { + case 1: + data.rv = pci_read_config_byte(adapter->ahw.pdev, + data.off, + (char *)&(data.u)); + break; + case 2: + data.rv = pci_read_config_word(adapter->ahw.pdev, + data.off, + (short *)&(data.u)); + break; + case 4: + data.rv = pci_read_config_dword(adapter->ahw.pdev, + data.off, + (u32 *) & (data.u)); + break; + } + if (copy_to_user + ((void __user *)&(up_data->u), &(data.u), data.size)) { + DPRINTK(ERR, "bad copy to userland: %d\n", + (int)sizeof(data)); + retval = -EFAULT; + goto error_out; + } + break; + + case netxen_nic_cmd_pci_config_write: + switch (data.size) { + case 1: + data.rv = pci_write_config_byte(adapter->ahw.pdev, + data.off, + *(char *)&(data.u)); + break; + case 2: + data.rv = pci_write_config_word(adapter->ahw.pdev, + data.off, + *(short *)&(data.u)); + break; + case 4: + data.rv = pci_write_config_dword(adapter->ahw.pdev, + data.off, + *(u32 *) & (data.u)); + break; + } + break; + + case netxen_nic_cmd_get_stats: + data.rv = + netxen_nic_fill_statistics(adapter, port, &netxen_stats); + if (copy_to_user + ((void __user *)(up_data->ptr), (void *)&netxen_stats, + sizeof(struct netxen_statistics))) { + DPRINTK(ERR, "bad copy to userland: %d\n", + (int)sizeof(netxen_stats)); + retval = -EFAULT; + goto error_out; + } + up_data->rv = data.rv; + break; + + case netxen_nic_cmd_clear_stats: + data.rv = netxen_nic_clear_statistics(adapter, port); + up_data->rv = data.rv; + break; + + case netxen_nic_cmd_get_version: + if (copy_to_user + ((void __user *)&(up_data->u), NETXEN_NIC_LINUX_VERSIONID, + sizeof(NETXEN_NIC_LINUX_VERSIONID))) { + DPRINTK(ERR, "bad copy to userland: %d\n", + (int)sizeof(data)); + retval = -EFAULT; + goto error_out; + } + break; + + default: + DPRINTK(INFO, "bad command %d for %p\n", data.cmd, adapter); + retval = -EOPNOTSUPP; + goto error_out; + } + put_user(data.rv, (&(up_data->rv))); + DPRINTK(INFO, "done ioctl for %p well.\n", adapter); + + error_out: + return retval; +} diff --git a/trunk/drivers/net/netxen/netxen_nic_ioctl.h b/trunk/drivers/net/netxen/netxen_nic_ioctl.h new file mode 100644 index 000000000000..1221fa527552 --- /dev/null +++ b/trunk/drivers/net/netxen/netxen_nic_ioctl.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2003 - 2006 NetXen, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE. + * + * Contact Information: + * info@netxen.com + * NetXen, + * 3965 Freedom Circle, Fourth floor, + * Santa Clara, CA 95054 + */ + +#ifndef __NETXEN_NIC_IOCTL_H__ +#define __NETXEN_NIC_IOCTL_H__ + +#include + +#define NETXEN_CMD_START SIOCDEVPRIVATE +#define NETXEN_NIC_CMD (NETXEN_CMD_START + 1) +#define NETXEN_NIC_NAME (NETXEN_CMD_START + 2) +#define NETXEN_NIC_NAME_LEN 16 +#define NETXEN_NIC_NAME_RSP "NETXEN-UNM" + +typedef enum { + netxen_nic_cmd_none = 0, + netxen_nic_cmd_pci_read, + netxen_nic_cmd_pci_write, + netxen_nic_cmd_pci_mem_read, + netxen_nic_cmd_pci_mem_write, + netxen_nic_cmd_pci_config_read, + netxen_nic_cmd_pci_config_write, + netxen_nic_cmd_get_stats, + netxen_nic_cmd_clear_stats, + netxen_nic_cmd_get_version +} netxen_nic_ioctl_cmd_t; + +struct netxen_nic_ioctl_data { + u32 cmd; + u32 unused1; + u64 off; + u32 size; + u32 rv; + char u[64]; + void *ptr; +}; + +struct netxen_statistics { + u64 rx_packets; + u64 tx_packets; + u64 rx_bytes; + u64 rx_errors; + u64 tx_bytes; + u64 tx_errors; + u64 rx_crc_errors; + u64 rx_short_length_error; + u64 rx_long_length_error; + u64 rx_mac_errors; +}; + +#endif /* __NETXEN_NIC_IOCTL_H_ */ diff --git a/trunk/drivers/net/netxen/netxen_nic_isr.c b/trunk/drivers/net/netxen/netxen_nic_isr.c index 06847d4252c3..1b45f50fa6aa 100644 --- a/trunk/drivers/net/netxen/netxen_nic_isr.c +++ b/trunk/drivers/net/netxen/netxen_nic_isr.c @@ -157,8 +157,7 @@ void netxen_nic_isr_other(struct netxen_adapter *adapter) for (portno = 0; portno < NETXEN_NIU_MAX_GBE_PORTS; portno++) { linkup = val & 1; if (linkup != (qg_linksup & 1)) { - printk(KERN_INFO "%s: %s PORT %d link %s\n", - adapter->port[portno]->netdev->name, + printk(KERN_INFO "%s: PORT %d link %s\n", netxen_nic_driver_name, portno, ((linkup == 0) ? "down" : "up")); netxen_indicate_link_status(adapter, portno, linkup); diff --git a/trunk/drivers/net/netxen/netxen_nic_main.c b/trunk/drivers/net/netxen/netxen_nic_main.c index 8a5792fea774..575b71b67202 100644 --- a/trunk/drivers/net/netxen/netxen_nic_main.c +++ b/trunk/drivers/net/netxen/netxen_nic_main.c @@ -38,6 +38,7 @@ #include "netxen_nic.h" #define DEFINE_GLOBAL_RECV_CRB #include "netxen_nic_phan_reg.h" +#include "netxen_nic_ioctl.h" #include #include @@ -52,6 +53,8 @@ char netxen_nic_driver_name[] = "netxen-nic"; static char netxen_nic_driver_string[] = "NetXen Network Driver version " NETXEN_NIC_LINUX_VERSIONID; +struct netxen_adapter *g_adapter = NULL; + #define NETXEN_NETDEV_WEIGHT 120 #define NETXEN_ADAPTER_UP_MAGIC 777 #define NETXEN_NIC_PEG_TUNE 0 @@ -72,6 +75,8 @@ static void netxen_tx_timeout(struct net_device *netdev); static void netxen_tx_timeout_task(struct work_struct *work); static void netxen_watchdog(unsigned long); static int netxen_handle_int(struct netxen_adapter *, struct net_device *); +static int netxen_nic_ioctl(struct net_device *netdev, + struct ifreq *ifr, int cmd); static int netxen_nic_poll(struct net_device *dev, int *budget); #ifdef CONFIG_NET_POLL_CONTROLLER static void netxen_nic_poll_controller(struct net_device *netdev); @@ -85,8 +90,6 @@ static struct pci_device_id netxen_pci_tbl[] __devinitdata = { {PCI_DEVICE(0x4040, 0x0003)}, {PCI_DEVICE(0x4040, 0x0004)}, {PCI_DEVICE(0x4040, 0x0005)}, - {PCI_DEVICE(0x4040, 0x0024)}, - {PCI_DEVICE(0x4040, 0x0025)}, {0,} }; @@ -126,6 +129,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct netxen_cmd_buffer *cmd_buf_arr = NULL; u64 mac_addr[FLASH_NUM_PORTS + 1]; int valid_mac = 0; + static int netxen_cards_found = 0; printk(KERN_INFO "%s \n", netxen_nic_driver_string); /* In current scheme, we use only PCI function 0 */ @@ -216,6 +220,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_dbunmap; } + if (netxen_cards_found == 0) { + g_adapter = adapter; + } adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS; adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS; adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS; @@ -376,6 +383,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->set_multicast_list = netxen_nic_set_multi; netdev->set_mac_address = netxen_nic_set_mac; netdev->change_mtu = netxen_nic_change_mtu; + netdev->do_ioctl = netxen_nic_ioctl; netdev->tx_timeout = netxen_tx_timeout; netdev->watchdog_timeo = HZ; @@ -420,7 +428,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->dev_addr); } } - INIT_WORK(&port->tx_timeout_task, netxen_tx_timeout_task); + adapter->netdev = netdev; + INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); netif_carrier_off(netdev); netif_stop_queue(netdev); @@ -435,11 +444,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->port[i] = port; } - writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); - netxen_pinit_from_rom(adapter, 0); - udelay(500); - netxen_load_firmware(adapter); - netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); /* * delay a while to ensure that the Pegs are up & running. * Otherwise, we might see some flaky behaviour. @@ -457,6 +461,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) break; } + adapter->number = netxen_cards_found; adapter->driver_mismatch = 0; return 0; @@ -526,8 +531,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) netxen_nic_stop_all_ports(adapter); /* leave the hw in the same state as reboot */ - netxen_pinit_from_rom(adapter, 0); - writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); netxen_load_firmware(adapter); netxen_free_adapter_offload(adapter); @@ -818,8 +821,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) /* Take skb->data itself */ pbuf = &adapter->cmd_buf_arr[producer]; if ((netdev->features & NETIF_F_TSO) && skb_shinfo(skb)->gso_size > 0) { - pbuf->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); - hwdesc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); + pbuf->mss = skb_shinfo(skb)->gso_size; + hwdesc->mss = skb_shinfo(skb)->gso_size; } else { pbuf->mss = 0; hwdesc->mss = 0; @@ -953,6 +956,11 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) static void netxen_watchdog(unsigned long v) { struct netxen_adapter *adapter = (struct netxen_adapter *)v; + if (adapter != g_adapter) { + printk("%s: ***BUG*** adapter[%p] != g_adapter[%p]\n", + __FUNCTION__, adapter, g_adapter); + return; + } SCHEDULE_WORK(&adapter->watchdog_task); } @@ -961,23 +969,23 @@ static void netxen_tx_timeout(struct net_device *netdev) { struct netxen_port *port = (struct netxen_port *)netdev_priv(netdev); - SCHEDULE_WORK(&port->tx_timeout_task); + SCHEDULE_WORK(&port->adapter->tx_timeout_task); } static void netxen_tx_timeout_task(struct work_struct *work) { - struct netxen_port *port = - container_of(work, struct netxen_port, tx_timeout_task); - struct net_device *netdev = port->netdev; + struct netxen_adapter *adapter = + container_of(work, struct netxen_adapter, tx_timeout_task); + struct net_device *netdev = adapter->netdev; unsigned long flags; printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", netxen_nic_driver_name, netdev->name); - spin_lock_irqsave(&port->adapter->lock, flags); + spin_lock_irqsave(&adapter->lock, flags); netxen_nic_close(netdev); netxen_nic_open(netdev); - spin_unlock_irqrestore(&port->adapter->lock, flags); + spin_unlock_irqrestore(&adapter->lock, flags); netdev->trans_start = jiffies; netif_wake_queue(netdev); } @@ -1129,6 +1137,47 @@ static void netxen_nic_poll_controller(struct net_device *netdev) enable_irq(adapter->irq); } #endif +/* + * netxen_nic_ioctl () We provide the tcl/phanmon support through these + * ioctls. + */ +static int +netxen_nic_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) +{ + int err = 0; + unsigned long nr_bytes = 0; + struct netxen_port *port = netdev_priv(netdev); + struct netxen_adapter *adapter = port->adapter; + char dev_name[NETXEN_NIC_NAME_LEN]; + + DPRINTK(INFO, "doing ioctl for %s\n", netdev->name); + switch (cmd) { + case NETXEN_NIC_CMD: + err = netxen_nic_do_ioctl(adapter, (void *)ifr->ifr_data, port); + break; + + case NETXEN_NIC_NAME: + DPRINTK(INFO, "ioctl cmd for NetXen\n"); + if (ifr->ifr_data) { + sprintf(dev_name, "%s-%d", NETXEN_NIC_NAME_RSP, + port->portnum); + nr_bytes = + copy_to_user((char __user *)ifr->ifr_data, dev_name, + NETXEN_NIC_NAME_LEN); + if (nr_bytes) + err = -EIO; + + } + break; + + default: + DPRINTK(INFO, "ioctl cmd %x not supported\n", cmd); + err = -EOPNOTSUPP; + break; + } + + return err; +} static struct pci_driver netxen_driver = { .name = netxen_nic_driver_name, diff --git a/trunk/drivers/net/r8169.c b/trunk/drivers/net/r8169.c index 577babd4c938..f83b41d4cb0e 100644 --- a/trunk/drivers/net/r8169.c +++ b/trunk/drivers/net/r8169.c @@ -225,6 +225,7 @@ MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl); static int rx_copybreak = 200; static int use_dac; +static int ignore_parity_err; static struct { u32 msg_enable; } debug = { -1 }; @@ -470,6 +471,8 @@ module_param(use_dac, int, 0); MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot."); module_param_named(debug, debug.msg_enable, int, 0); MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)"); +module_param_named(ignore_parity_err, ignore_parity_err, bool, 0); +MODULE_PARM_DESC(ignore_parity_err, "Ignore PCI parity error as target. Default: false"); MODULE_LICENSE("GPL"); MODULE_VERSION(RTL8169_VERSION); @@ -1882,6 +1885,7 @@ static void rtl8169_hw_start(struct net_device *dev) (tp->mac_version == RTL_GIGA_MAC_VER_02) || (tp->mac_version == RTL_GIGA_MAC_VER_03) || (tp->mac_version == RTL_GIGA_MAC_VER_04)) + RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); rtl8169_set_rx_tx_config_registers(tp); cmd = RTL_R16(CPlusCmd); @@ -2384,7 +2388,7 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) * * Feel free to adjust to your needs. */ - if (pdev->broken_parity_status) + if (ignore_parity_err) pci_cmd &= ~PCI_COMMAND_PARITY; else pci_cmd |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY; diff --git a/trunk/drivers/net/skge.c b/trunk/drivers/net/skge.c index deedfd5f8226..8a39376f87dc 100644 --- a/trunk/drivers/net/skge.c +++ b/trunk/drivers/net/skge.c @@ -2920,7 +2920,6 @@ static int skge_poll(struct net_device *dev, int *budget) struct skge_hw *hw = skge->hw; struct skge_ring *ring = &skge->rx_ring; struct skge_element *e; - unsigned long flags; int to_do = min(dev->quota, *budget); int work_done = 0; @@ -2958,12 +2957,12 @@ static int skge_poll(struct net_device *dev, int *budget) if (work_done >= to_do) return 1; /* not done */ - spin_lock_irqsave(&hw->hw_lock, flags); + spin_lock_irq(&hw->hw_lock); __netif_rx_complete(dev); hw->intr_mask |= irqmask[skge->port]; skge_write32(hw, B0_IMSK, hw->intr_mask); skge_read32(hw, B0_IMSK); - spin_unlock_irqrestore(&hw->hw_lock, flags); + spin_unlock_irq(&hw->hw_lock); return 0; } diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index a6601e8d423c..fb1d2c30c1bb 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -569,8 +569,8 @@ static void sky2_phy_power(struct sky2_hw *hw, unsigned port, int onoff) if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) onoff = !onoff; - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); + if (onoff) /* Turn off phy power saving */ reg1 &= ~phy_power[port]; @@ -579,7 +579,6 @@ static void sky2_phy_power(struct sky2_hw *hw, unsigned port, int onoff) sky2_pci_write32(hw, PCI_DEV_REG1, reg1); sky2_pci_read32(hw, PCI_DEV_REG1); - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); udelay(100); } @@ -1512,13 +1511,6 @@ static int sky2_down(struct net_device *dev) imask &= ~portirq_msk[port]; sky2_write32(hw, B0_IMSK, imask); - /* - * Both ports share the NAPI poll on port 0, so if necessary undo the - * the disable that is done in dev_close. - */ - if (sky2->port == 0 && hw->ports > 1) - netif_poll_enable(dev); - sky2_gmac_reset(hw, port); /* Stop transmitter */ @@ -3639,29 +3631,6 @@ static int sky2_resume(struct pci_dev *pdev) out: return err; } - -/* BIOS resume runs after device (it's a bug in PM) - * as a temporary workaround on suspend/resume leave MSI disabled - */ -static int sky2_suspend_late(struct pci_dev *pdev, pm_message_t state) -{ - struct sky2_hw *hw = pci_get_drvdata(pdev); - - free_irq(pdev->irq, hw); - if (hw->msi) { - pci_disable_msi(pdev); - hw->msi = 0; - } - return 0; -} - -static int sky2_resume_early(struct pci_dev *pdev) -{ - struct sky2_hw *hw = pci_get_drvdata(pdev); - struct net_device *dev = hw->dev[0]; - - return request_irq(pdev->irq, sky2_intr, IRQF_SHARED, dev->name, hw); -} #endif static struct pci_driver sky2_driver = { @@ -3672,8 +3641,6 @@ static struct pci_driver sky2_driver = { #ifdef CONFIG_PM .suspend = sky2_suspend, .resume = sky2_resume, - .suspend_late = sky2_suspend_late, - .resume_early = sky2_resume_early, #endif }; diff --git a/trunk/drivers/net/via-velocity.c b/trunk/drivers/net/via-velocity.c index 8e5d82051bd4..4587f23f4e4b 100644 --- a/trunk/drivers/net/via-velocity.c +++ b/trunk/drivers/net/via-velocity.c @@ -265,19 +265,15 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status); static int velocity_suspend(struct pci_dev *pdev, pm_message_t state); static int velocity_resume(struct pci_dev *pdev); -static DEFINE_SPINLOCK(velocity_dev_list_lock); -static LIST_HEAD(velocity_dev_list); - -#endif - -#if defined(CONFIG_PM) && defined(CONFIG_INET) - static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr); static struct notifier_block velocity_inetaddr_notifier = { .notifier_call = velocity_netdev_event, }; +static DEFINE_SPINLOCK(velocity_dev_list_lock); +static LIST_HEAD(velocity_dev_list); + static void velocity_register_notifier(void) { register_inetaddr_notifier(&velocity_inetaddr_notifier); @@ -288,12 +284,12 @@ static void velocity_unregister_notifier(void) unregister_inetaddr_notifier(&velocity_inetaddr_notifier); } -#else +#else /* CONFIG_PM */ #define velocity_register_notifier() do {} while (0) #define velocity_unregister_notifier() do {} while (0) -#endif +#endif /* !CONFIG_PM */ /* * Internal board variants. At the moment we have only one @@ -3296,8 +3292,6 @@ static int velocity_resume(struct pci_dev *pdev) return 0; } -#ifdef CONFIG_INET - static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr) { struct in_ifaddr *ifa = (struct in_ifaddr *) ptr; @@ -3318,6 +3312,4 @@ static int velocity_netdev_event(struct notifier_block *nb, unsigned long notifi } return NOTIFY_DONE; } - -#endif #endif diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_mac.c b/trunk/drivers/net/wireless/zd1211rw/zd_mac.c index a08524191b5d..00ca704ece35 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/trunk/drivers/net/wireless/zd1211rw/zd_mac.c @@ -41,8 +41,6 @@ static void housekeeping_disable(struct zd_mac *mac); static void set_multicast_hash_handler(struct work_struct *work); -static void do_rx(unsigned long mac_ptr); - int zd_mac_init(struct zd_mac *mac, struct net_device *netdev, struct usb_interface *intf) @@ -55,10 +53,6 @@ int zd_mac_init(struct zd_mac *mac, INIT_DELAYED_WORK(&mac->set_rts_cts_work, set_rts_cts_work); INIT_DELAYED_WORK(&mac->set_basic_rates_work, set_basic_rates_work); - skb_queue_head_init(&mac->rx_queue); - tasklet_init(&mac->rx_tasklet, do_rx, (unsigned long)mac); - tasklet_disable(&mac->rx_tasklet); - ieee_init(ieee); softmac_init(ieee80211_priv(netdev)); zd_chip_init(&mac->chip, netdev, intf); @@ -146,8 +140,6 @@ int zd_mac_init_hw(struct zd_mac *mac, u8 device_type) void zd_mac_clear(struct zd_mac *mac) { flush_workqueue(zd_workqueue); - skb_queue_purge(&mac->rx_queue); - tasklet_kill(&mac->rx_tasklet); zd_chip_clear(&mac->chip); ZD_ASSERT(!spin_is_locked(&mac->lock)); ZD_MEMCLEAR(mac, sizeof(struct zd_mac)); @@ -176,8 +168,6 @@ int zd_mac_open(struct net_device *netdev) struct zd_chip *chip = &mac->chip; int r; - tasklet_enable(&mac->rx_tasklet); - r = zd_chip_enable_int(chip); if (r < 0) goto out; @@ -228,8 +218,6 @@ int zd_mac_stop(struct net_device *netdev) */ zd_chip_disable_rx(chip); - skb_queue_purge(&mac->rx_queue); - tasklet_disable(&mac->rx_tasklet); housekeeping_disable(mac); ieee80211softmac_stop(netdev); @@ -482,13 +470,13 @@ static void bssinfo_change(struct net_device *netdev, u32 changes) if (changes & IEEE80211SOFTMAC_BSSINFOCHG_RATES) { /* Set RTS rate to highest available basic rate */ - u8 hi_rate = ieee80211softmac_highest_supported_rate(softmac, + u8 rate = ieee80211softmac_highest_supported_rate(softmac, &bssinfo->supported_rates, 1); - hi_rate = rate_to_zd_rate(hi_rate); + rate = rate_to_zd_rate(rate); spin_lock_irqsave(&mac->lock, flags); - if (hi_rate != mac->rts_rate) { - mac->rts_rate = hi_rate; + if (rate != mac->rts_rate) { + mac->rts_rate = rate; need_set_rts_cts = 1; } spin_unlock_irqrestore(&mac->lock, flags); @@ -1084,75 +1072,43 @@ static int fill_rx_stats(struct ieee80211_rx_stats *stats, return 0; } -static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb) +int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length) { int r; struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); struct ieee80211_rx_stats stats; const struct rx_status *status; + struct sk_buff *skb; - if (skb->len < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN + - IEEE80211_FCS_LEN + sizeof(struct rx_status)) - { - dev_dbg_f(zd_mac_dev(mac), "Packet with length %u to small.\n", - skb->len); - goto free_skb; - } + if (length < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN + + IEEE80211_FCS_LEN + sizeof(struct rx_status)) + return -EINVAL; - r = fill_rx_stats(&stats, &status, mac, skb->data, skb->len); - if (r) { - /* Only packets with rx errors are included here. */ - goto free_skb; - } + r = fill_rx_stats(&stats, &status, mac, buffer, length); + if (r) + return r; - __skb_pull(skb, ZD_PLCP_HEADER_SIZE); - __skb_trim(skb, skb->len - - (IEEE80211_FCS_LEN + sizeof(struct rx_status))); + length -= ZD_PLCP_HEADER_SIZE+IEEE80211_FCS_LEN+ + sizeof(struct rx_status); + buffer += ZD_PLCP_HEADER_SIZE; - update_qual_rssi(mac, skb->data, skb->len, stats.signal, - status->signal_strength); + update_qual_rssi(mac, buffer, length, stats.signal, stats.rssi); - r = filter_rx(ieee, skb->data, skb->len, &stats); - if (r <= 0) { - if (r < 0) - dev_dbg_f(zd_mac_dev(mac), "Error in packet.\n"); - goto free_skb; - } + r = filter_rx(ieee, buffer, length, &stats); + if (r <= 0) + return r; + skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length); + if (!skb) + return -ENOMEM; if (ieee->iw_mode == IW_MODE_MONITOR) - fill_rt_header(skb_push(skb, sizeof(struct zd_rt_hdr)), mac, + fill_rt_header(skb_put(skb, sizeof(struct zd_rt_hdr)), mac, &stats, status); + memcpy(skb_put(skb, length), buffer, length); r = ieee80211_rx(ieee, skb, &stats); - if (r) - return; -free_skb: - /* We are always in a soft irq. */ - dev_kfree_skb(skb); -} - -static void do_rx(unsigned long mac_ptr) -{ - struct zd_mac *mac = (struct zd_mac *)mac_ptr; - struct sk_buff *skb; - - while ((skb = skb_dequeue(&mac->rx_queue)) != NULL) - zd_mac_rx(mac, skb); -} - -int zd_mac_rx_irq(struct zd_mac *mac, const u8 *buffer, unsigned int length) -{ - struct sk_buff *skb; - - skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length); - if (!skb) { - dev_warn(zd_mac_dev(mac), "Could not allocate skb.\n"); - return -ENOMEM; - } - skb_reserve(skb, sizeof(struct zd_rt_hdr)); - memcpy(__skb_put(skb, length), buffer, length); - skb_queue_tail(&mac->rx_queue, skb); - tasklet_schedule(&mac->rx_tasklet); + if (!r) + dev_kfree_skb_any(skb); return 0; } diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_mac.h b/trunk/drivers/net/wireless/zd1211rw/zd_mac.h index faf4c7828d4e..f0cf05dc7d3e 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/trunk/drivers/net/wireless/zd1211rw/zd_mac.h @@ -138,9 +138,6 @@ struct zd_mac { struct delayed_work set_rts_cts_work; struct delayed_work set_basic_rates_work; - struct tasklet_struct rx_tasklet; - struct sk_buff_head rx_queue; - unsigned int stats_count; u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE]; u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE]; @@ -196,7 +193,7 @@ int zd_mac_stop(struct net_device *netdev); int zd_mac_set_mac_address(struct net_device *dev, void *p); void zd_mac_set_multicast_list(struct net_device *netdev); -int zd_mac_rx_irq(struct zd_mac *mac, const u8 *buffer, unsigned int length); +int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length); int zd_mac_set_regdomain(struct zd_mac *zd_mac, u8 regdomain); u8 zd_mac_get_regdomain(struct zd_mac *zd_mac); diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_usb.c b/trunk/drivers/net/wireless/zd1211rw/zd_usb.c index 605e96e74057..aa782e88754b 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/trunk/drivers/net/wireless/zd1211rw/zd_usb.c @@ -598,13 +598,13 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, n = l+k; if (n > length) return; - zd_mac_rx_irq(mac, buffer+l, k); + zd_mac_rx(mac, buffer+l, k); if (i >= 2) return; l = (n+3) & ~3; } } else { - zd_mac_rx_irq(mac, buffer, length); + zd_mac_rx(mac, buffer, length); } } diff --git a/trunk/mm/page-writeback.c b/trunk/mm/page-writeback.c index 1d2fc89ca56d..b3a198c9248d 100644 --- a/trunk/mm/page-writeback.c +++ b/trunk/mm/page-writeback.c @@ -862,46 +862,17 @@ int clear_page_dirty_for_io(struct page *page) { struct address_space *mapping = page_mapping(page); - if (mapping && mapping_cap_account_dirty(mapping)) { - /* - * Yes, Virginia, this is indeed insane. - * - * We use this sequence to make sure that - * (a) we account for dirty stats properly - * (b) we tell the low-level filesystem to - * mark the whole page dirty if it was - * dirty in a pagetable. Only to then - * (c) clean the page again and return 1 to - * cause the writeback. - * - * This way we avoid all nasty races with the - * dirty bit in multiple places and clearing - * them concurrently from different threads. - * - * Note! Normally the "set_page_dirty(page)" - * has no effect on the actual dirty bit - since - * that will already usually be set. But we - * need the side effects, and it can help us - * avoid races. - * - * We basically use the page "master dirty bit" - * as a serialization point for all the different - * threads doing their things. - * - * FIXME! We still have a race here: if somebody - * adds the page back to the page tables in - * between the "page_mkclean()" and the "TestClearPageDirty()", - * we might have it mapped without the dirty bit set. - */ - if (page_mkclean(page)) - set_page_dirty(page); - if (TestClearPageDirty(page)) { + if (!mapping) + return TestClearPageDirty(page); + + if (TestClearPageDirty(page)) { + if (mapping_cap_account_dirty(mapping)) { + page_mkclean(page); dec_zone_page_state(page, NR_FILE_DIRTY); - return 1; } - return 0; + return 1; } - return TestClearPageDirty(page); + return 0; } EXPORT_SYMBOL(clear_page_dirty_for_io); diff --git a/trunk/net/ieee80211/softmac/ieee80211softmac_assoc.c b/trunk/net/ieee80211/softmac/ieee80211softmac_assoc.c index a824852909e4..e3f37fdda65f 100644 --- a/trunk/net/ieee80211/softmac/ieee80211softmac_assoc.c +++ b/trunk/net/ieee80211/softmac/ieee80211softmac_assoc.c @@ -167,7 +167,7 @@ static void ieee80211softmac_assoc_notify_scan(struct net_device *dev, int event_type, void *context) { struct ieee80211softmac_device *mac = ieee80211_priv(dev); - ieee80211softmac_assoc_work(&mac->associnfo.work.work); + ieee80211softmac_assoc_work((void*)mac); } static void @@ -177,7 +177,7 @@ ieee80211softmac_assoc_notify_auth(struct net_device *dev, int event_type, void switch (event_type) { case IEEE80211SOFTMAC_EVENT_AUTHENTICATED: - ieee80211softmac_assoc_work(&mac->associnfo.work.work); + ieee80211softmac_assoc_work((void*)mac); break; case IEEE80211SOFTMAC_EVENT_AUTH_FAILED: case IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT: diff --git a/trunk/net/ieee80211/softmac/ieee80211softmac_wx.c b/trunk/net/ieee80211/softmac/ieee80211softmac_wx.c index fa2f7da606a9..480d72c7a42c 100644 --- a/trunk/net/ieee80211/softmac/ieee80211softmac_wx.c +++ b/trunk/net/ieee80211/softmac/ieee80211softmac_wx.c @@ -463,7 +463,7 @@ ieee80211softmac_wx_get_genie(struct net_device *dev, err = -E2BIG; } spin_unlock_irqrestore(&mac->lock, flags); - mutex_unlock(&mac->associnfo.mutex); + mutex_lock(&mac->associnfo.mutex); return err; }