summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/3c59x.c28
-rw-r--r--drivers/net/Kconfig25
-rw-r--r--drivers/net/atl1/atl1_hw.c1
-rw-r--r--drivers/net/atl1/atl1_main.c14
-rw-r--r--drivers/net/b44.c2
-rw-r--r--drivers/net/bnx2.c38
-rw-r--r--drivers/net/cxgb3/common.h27
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c121
-rw-r--r--drivers/net/cxgb3/cxgb3_offload.c18
-rw-r--r--drivers/net/cxgb3/mc5.c3
-rw-r--r--drivers/net/cxgb3/regs.h32
-rw-r--r--drivers/net/cxgb3/sge.c2
-rw-r--r--drivers/net/cxgb3/t3_hw.c39
-rw-r--r--drivers/net/cxgb3/version.h5
-rw-r--r--drivers/net/cxgb3/xgmac.c191
-rw-r--r--drivers/net/ewrk3.c3
-rw-r--r--drivers/net/forcedeth.c8
-rw-r--r--drivers/net/ifb.c35
-rw-r--r--drivers/net/irda/irda-usb.c2
-rw-r--r--drivers/net/irda/pxaficp_ir.c30
-rw-r--r--drivers/net/mv643xx_eth.c28
-rw-r--r--drivers/net/myri10ge/myri10ge.c88
-rw-r--r--drivers/net/natsemi.c58
-rw-r--r--drivers/net/netxen/netxen_nic.h1
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c1
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c10
-rw-r--r--drivers/net/netxen/netxen_nic_init.c14
-rw-r--r--drivers/net/pci-skeleton.c4
-rw-r--r--drivers/net/pcmcia/ibmtr_cs.c4
-rw-r--r--drivers/net/ppp_generic.c3
-rwxr-xr-xdrivers/net/qla3xxx.c110
-rwxr-xr-xdrivers/net/qla3xxx.h3
-rw-r--r--drivers/net/r8169.c60
-rw-r--r--drivers/net/saa9730.c177
-rw-r--r--drivers/net/sb1250-mac.c2
-rw-r--r--drivers/net/sc92031.c20
-rw-r--r--drivers/net/sis190.c1
-rw-r--r--drivers/net/skge.c215
-rw-r--r--drivers/net/skge.h6
-rw-r--r--drivers/net/sky2.c36
-rw-r--r--drivers/net/sun3lance.c16
-rw-r--r--drivers/net/sungem.c30
-rw-r--r--drivers/net/tg3.c136
-rw-r--r--drivers/net/tg3.h5
-rw-r--r--drivers/net/tokenring/ibmtr.c25
-rw-r--r--drivers/net/tulip/dmfe.c6
-rw-r--r--drivers/net/ucc_geth.c3
-rw-r--r--drivers/net/via-rhine.c32
-rw-r--r--drivers/net/wan/lmc/lmc_media.h65
-rw-r--r--drivers/net/wan/z85230.c2
-rw-r--r--drivers/net/wireless/airo.c4
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c26
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_phy.c71
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_radio.c26
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_wx.c10
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c12
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h4
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al2230.c6
58 files changed, 1235 insertions, 709 deletions
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 72995777f809..b406ecfa7268 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -858,19 +858,7 @@ static struct eisa_device_id vortex_eisa_ids[] = {
};
MODULE_DEVICE_TABLE(eisa, vortex_eisa_ids);
-static int vortex_eisa_probe(struct device *device);
-static int vortex_eisa_remove(struct device *device);
-
-static struct eisa_driver vortex_eisa_driver = {
- .id_table = vortex_eisa_ids,
- .driver = {
- .name = "3c59x",
- .probe = vortex_eisa_probe,
- .remove = vortex_eisa_remove
- }
-};
-
-static int vortex_eisa_probe(struct device *device)
+static int __init vortex_eisa_probe(struct device *device)
{
void __iomem *ioaddr;
struct eisa_device *edev;
@@ -893,7 +881,7 @@ static int vortex_eisa_probe(struct device *device)
return 0;
}
-static int vortex_eisa_remove(struct device *device)
+static int __devexit vortex_eisa_remove(struct device *device)
{
struct eisa_device *edev;
struct net_device *dev;
@@ -918,7 +906,17 @@ static int vortex_eisa_remove(struct device *device)
free_netdev(dev);
return 0;
}
-#endif
+
+static struct eisa_driver vortex_eisa_driver = {
+ .id_table = vortex_eisa_ids,
+ .driver = {
+ .name = "3c59x",
+ .probe = vortex_eisa_probe,
+ .remove = __devexit_p(vortex_eisa_remove)
+ }
+};
+
+#endif /* CONFIG_EISA */
/* returns count found (>= 0), or negative on error */
static int __init vortex_eisa_init(void)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index dae0aa408bc4..753695b624b3 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2373,22 +2373,23 @@ config CHELSIO_T1_NAPI
when the driver is receiving lots of packets from the card.
config CHELSIO_T3
- tristate "Chelsio Communications T3 10Gb Ethernet support"
- depends on PCI
- help
- This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
- adapters.
+ tristate "Chelsio Communications T3 10Gb Ethernet support"
+ depends on PCI
+ select FW_LOADER
+ help
+ This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
+ adapters.
- For general information about Chelsio and our products, visit
- our website at <http://www.chelsio.com>.
+ For general information about Chelsio and our products, visit
+ our website at <http://www.chelsio.com>.
- For customer support, please visit our customer support page at
- <http://www.chelsio.com/support.htm>.
+ For customer support, please visit our customer support page at
+ <http://www.chelsio.com/support.htm>.
- Please send feedback to <linux-bugs@chelsio.com>.
+ Please send feedback to <linux-bugs@chelsio.com>.
- To compile this driver as a module, choose M here: the module
- will be called cxgb3.
+ To compile this driver as a module, choose M here: the module
+ will be called cxgb3.
config EHEA
tristate "eHEA Ethernet support"
diff --git a/drivers/net/atl1/atl1_hw.c b/drivers/net/atl1/atl1_hw.c
index 314dbaabb642..69482e0d849b 100644
--- a/drivers/net/atl1/atl1_hw.c
+++ b/drivers/net/atl1/atl1_hw.c
@@ -334,7 +334,6 @@ u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr)
int i;
crc32 = ether_crc_le(6, mc_addr);
- crc32 = ~crc32;
for (i = 0; i < 32; i++)
value |= (((crc32 >> i) & 1) << (31 - i));
diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c
index 88d4f70035bb..8606eac5bec8 100644
--- a/drivers/net/atl1/atl1_main.c
+++ b/drivers/net/atl1/atl1_main.c
@@ -1328,7 +1328,7 @@ static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
cso = skb->h.raw - skb->data;
- css = (skb->h.raw + skb->csum) - skb->data;
+ css = (skb->h.raw + skb->csum_offset) - skb->data;
if (unlikely(cso & 0x1)) {
printk(KERN_DEBUG "%s: payload offset != even number\n",
atl1_driver_name);
@@ -1562,7 +1562,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
/* mss will be nonzero if we're doing segment offload (TSO/GSO) */
mss = skb_shinfo(skb)->gso_size;
if (mss) {
- if (skb->protocol == ntohs(ETH_P_IP)) {
+ if (skb->protocol == htons(ETH_P_IP)) {
proto_hdr_len = ((skb->h.raw - skb->data) +
(skb->h.th->doff << 2));
if (unlikely(proto_hdr_len > len)) {
@@ -2320,6 +2320,16 @@ static void __devexit atl1_remove(struct pci_dev *pdev)
return;
adapter = netdev_priv(netdev);
+
+ /* Some atl1 boards lack persistent storage for their MAC, and get it
+ * from the BIOS during POST. If we've been messing with the MAC
+ * address, we need to save the permanent one.
+ */
+ if (memcmp(adapter->hw.mac_addr, adapter->hw.perm_mac_addr, ETH_ALEN)) {
+ memcpy(adapter->hw.mac_addr, adapter->hw.perm_mac_addr, ETH_ALEN);
+ atl1_set_mac_addr(&adapter->hw);
+ }
+
iowrite16(0, adapter->hw.hw_addr + REG_GPHY_ENABLE);
unregister_netdev(netdev);
pci_iounmap(pdev, adapter->hw.hw_addr);
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index aaada572732a..d742bfe24471 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1709,7 +1709,7 @@ static void __b44_set_rx_mode(struct net_device *dev)
bw32(bp, B44_RXCONFIG, val);
} else {
unsigned char zero[6] = {0, 0, 0, 0, 0, 0};
- int i = 0;
+ int i = 1;
__b44_set_mac_addr(bp);
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index c12e5ea61819..0b7aded8dcfd 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -54,8 +54,8 @@
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "1.5.5"
-#define DRV_MODULE_RELDATE "February 1, 2007"
+#define DRV_MODULE_VERSION "1.5.7"
+#define DRV_MODULE_RELDATE "March 29, 2007"
#define RUN_AT(x) (jiffies + (x))
@@ -2033,8 +2033,8 @@ bnx2_has_work(struct bnx2 *bp)
(sblk->status_tx_quick_consumer_index0 != bp->hw_tx_cons))
return 1;
- if (((sblk->status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) != 0) !=
- bp->link_up)
+ if ((sblk->status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) !=
+ (sblk->status_attn_bits_ack & STATUS_ATTN_BITS_LINK_STATE))
return 1;
return 0;
@@ -3099,20 +3099,18 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf,
if ((align_start = (offset32 & 3))) {
offset32 &= ~3;
- len32 += (4 - align_start);
+ len32 += align_start;
+ if (len32 < 4)
+ len32 = 4;
if ((rc = bnx2_nvram_read(bp, offset32, start, 4)))
return rc;
}
if (len32 & 3) {
- if ((len32 > 4) || !align_start) {
- align_end = 4 - (len32 & 3);
- len32 += align_end;
- if ((rc = bnx2_nvram_read(bp, offset32 + len32 - 4,
- end, 4))) {
- return rc;
- }
- }
+ align_end = 4 - (len32 & 3);
+ len32 += align_end;
+ if ((rc = bnx2_nvram_read(bp, offset32 + len32 - 4, end, 4)))
+ return rc;
}
if (align_start || align_end) {
@@ -3187,17 +3185,17 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf,
if ((rc = bnx2_enable_nvram_write(bp)) != 0)
goto nvram_write_end;
- /* Erase the page */
- if ((rc = bnx2_nvram_erase_page(bp, page_start)) != 0)
- goto nvram_write_end;
-
- /* Re-enable the write again for the actual write */
- bnx2_enable_nvram_write(bp);
-
/* Loop to write back the buffer data from page_start to
* data_start */
i = 0;
if (bp->flash_info->buffered == 0) {
+ /* Erase the page */
+ if ((rc = bnx2_nvram_erase_page(bp, page_start)) != 0)
+ goto nvram_write_end;
+
+ /* Re-enable the write again for the actual write */
+ bnx2_enable_nvram_write(bp);
+
for (addr = page_start; addr < data_start;
addr += 4, i += 4) {
diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h
index e23deeb7d06d..8d1379633698 100644
--- a/drivers/net/cxgb3/common.h
+++ b/drivers/net/cxgb3/common.h
@@ -112,8 +112,7 @@ enum {
};
enum {
- SUPPORTED_OFFLOAD = 1 << 24,
- SUPPORTED_IRQ = 1 << 25
+ SUPPORTED_IRQ = 1 << 24
};
enum { /* adapter interrupt-maintained statistics */
@@ -260,6 +259,10 @@ struct mac_stats {
unsigned long serdes_signal_loss;
unsigned long xaui_pcs_ctc_err;
unsigned long xaui_pcs_align_change;
+
+ unsigned long num_toggled; /* # times toggled TxEn due to stuck TX */
+ unsigned long num_resets; /* # times reset due to stuck TX */
+
};
struct tp_mib_stats {
@@ -354,6 +357,9 @@ enum {
MC5_MODE_72_BIT = 2
};
+/* MC5 min active region size */
+enum { MC5_MIN_TIDS = 16 };
+
struct vpd_params {
unsigned int cclk;
unsigned int mclk;
@@ -398,6 +404,13 @@ struct adapter_params {
unsigned int stats_update_period; /* MAC stats accumulation period */
unsigned int linkpoll_period; /* link poll period in 0.1s */
unsigned int rev; /* chip revision */
+ unsigned int offload;
+};
+
+enum { /* chip revisions */
+ T3_REV_A = 0,
+ T3_REV_B = 2,
+ T3_REV_B2 = 3,
};
struct trace_params {
@@ -465,6 +478,13 @@ struct cmac {
struct adapter *adapter;
unsigned int offset;
unsigned int nucast; /* # of address filters for unicast MACs */
+ unsigned int tx_tcnt;
+ unsigned int tx_xcnt;
+ u64 tx_mcnt;
+ unsigned int rx_xcnt;
+ u64 rx_mcnt;
+ unsigned int toggle_cnt;
+ unsigned int txen;
struct mac_stats stats;
};
@@ -588,7 +608,7 @@ static inline int is_10G(const struct adapter *adap)
static inline int is_offload(const struct adapter *adap)
{
- return adapter_info(adap)->caps & SUPPORTED_OFFLOAD;
+ return adap->params.offload;
}
static inline unsigned int core_ticks_per_usec(const struct adapter *adap)
@@ -666,6 +686,7 @@ int t3_mac_set_address(struct cmac *mac, unsigned int idx, u8 addr[6]);
int t3_mac_set_num_ucast(struct cmac *mac, int n);
const struct mac_stats *t3_mac_update_stats(struct cmac *mac);
int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc);
+int t3b2_mac_watchdog_task(struct cmac *mac);
void t3_mc5_prep(struct adapter *adapter, struct mc5 *mc5, int mode);
int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters,
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 7ff834e45d6b..67b4b219d927 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -42,6 +42,7 @@
#include <linux/workqueue.h>
#include <linux/proc_fs.h>
#include <linux/rtnetlink.h>
+#include <linux/firmware.h>
#include <asm/uaccess.h>
#include "common.h"
@@ -184,16 +185,24 @@ void t3_os_link_changed(struct adapter *adapter, int port_id, int link_stat,
int speed, int duplex, int pause)
{
struct net_device *dev = adapter->port[port_id];
+ struct port_info *pi = netdev_priv(dev);
+ struct cmac *mac = &pi->mac;
/* Skip changes from disabled ports. */
if (!netif_running(dev))
return;
if (link_stat != netif_carrier_ok(dev)) {
- if (link_stat)
+ if (link_stat) {
+ t3_mac_enable(mac, MAC_DIRECTION_RX);
netif_carrier_on(dev);
- else
+ } else {
netif_carrier_off(dev);
+ pi->phy.ops->power_down(&pi->phy, 1);
+ t3_mac_disable(mac, MAC_DIRECTION_RX);
+ t3_link_start(&pi->phy, mac, &pi->link_config);
+ }
+
link_report(dev);
}
}
@@ -406,7 +415,7 @@ static void quiesce_rx(struct adapter *adap)
static int setup_sge_qsets(struct adapter *adap)
{
int i, j, err, irq_idx = 0, qset_idx = 0, dummy_dev_idx = 0;
- unsigned int ntxq = is_offload(adap) ? SGE_TXQ_PER_SET : 1;
+ unsigned int ntxq = SGE_TXQ_PER_SET;
if (adap->params.rev > 0 && !(adap->flags & USING_MSI))
irq_idx = -1;
@@ -484,12 +493,14 @@ static ssize_t show_##name(struct device *d, struct device_attribute *attr, \
static ssize_t set_nfilters(struct net_device *dev, unsigned int val)
{
struct adapter *adap = dev->priv;
+ int min_tids = is_offload(adap) ? MC5_MIN_TIDS : 0;
if (adap->flags & FULL_INIT_DONE)
return -EBUSY;
if (val && adap->params.rev == 0)
return -EINVAL;
- if (val > t3_mc5_size(&adap->mc5) - adap->params.mc5.nservers)
+ if (val > t3_mc5_size(&adap->mc5) - adap->params.mc5.nservers -
+ min_tids)
return -EINVAL;
adap->params.mc5.nfilters = val;
return 0;
@@ -507,7 +518,8 @@ static ssize_t set_nservers(struct net_device *dev, unsigned int val)
if (adap->flags & FULL_INIT_DONE)
return -EBUSY;
- if (val > t3_mc5_size(&adap->mc5) - adap->params.mc5.nfilters)
+ if (val > t3_mc5_size(&adap->mc5) - adap->params.mc5.nfilters -
+ MC5_MIN_TIDS)
return -EINVAL;
adap->params.mc5.nservers = val;
return 0;
@@ -707,6 +719,28 @@ static void bind_qsets(struct adapter *adap)
}
}
+#define FW_FNAME "t3fw-%d.%d.%d.bin"
+
+static int upgrade_fw(struct adapter *adap)
+{
+ int ret;
+ char buf[64];
+ const struct firmware *fw;
+ struct device *dev = &adap->pdev->dev;
+
+ snprintf(buf, sizeof(buf), FW_FNAME, FW_VERSION_MAJOR,
+ FW_VERSION_MINOR, FW_VERSION_MICRO);
+ ret = request_firmware(&fw, buf, dev);
+ if (ret < 0) {
+ dev_err(dev, "could not upgrade firmware: unable to load %s\n",
+ buf);
+ return ret;
+ }
+ ret = t3_load_fw(adap, fw->data, fw->size);
+ release_firmware(fw);
+ return ret;
+}
+
/**
* cxgb_up - enable the adapter
* @adapter: adapter being enabled
@@ -723,6 +757,8 @@ static int cxgb_up(struct adapter *adap)
if (!(adap->flags & FULL_INIT_DONE)) {
err = t3_check_fw_version(adap);
+ if (err == -EINVAL)
+ err = upgrade_fw(adap);
if (err)
goto out;
@@ -734,6 +770,8 @@ static int cxgb_up(struct adapter *adap)
if (err)
goto out;
+ t3_write_reg(adap, A_ULPRX_TDDP_PSZ, V_HPZ0(PAGE_SHIFT - 12));
+
err = setup_sge_qsets(adap);
if (err)
goto out;
@@ -894,7 +932,7 @@ static int cxgb_open(struct net_device *dev)
return err;
set_bit(pi->port_id, &adapter->open_device_map);
- if (!ofld_disable) {
+ if (is_offload(adapter) && !ofld_disable) {
err = offload_open(dev);
if (err)
printk(KERN_WARNING
@@ -1031,7 +1069,11 @@ static char stats_strings[][ETH_GSTRING_LEN] = {
"VLANinsertions ",
"TxCsumOffload ",
"RxCsumGood ",
- "RxDrops "
+ "RxDrops ",
+
+ "CheckTXEnToggled ",
+ "CheckResets ",
+
};
static int get_stats_count(struct net_device *dev)
@@ -1145,6 +1187,9 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_TX_CSUM);
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_RX_CSUM_GOOD);
*data++ = s->rx_cong_drops;
+
+ *data++ = s->num_toggled;
+ *data++ = s->num_resets;
}
static inline void reg_block_dump(struct adapter *ap, void *buf,
@@ -1362,23 +1407,27 @@ static int set_rx_csum(struct net_device *dev, u32 data)
static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
{
- struct adapter *adapter = dev->priv;
+ const struct adapter *adapter = dev->priv;
+ const struct port_info *pi = netdev_priv(dev);
+ const struct qset_params *q = &adapter->params.sge.qset[pi->first_qset];
e->rx_max_pending = MAX_RX_BUFFERS;
e->rx_mini_max_pending = 0;
e->rx_jumbo_max_pending = MAX_RX_JUMBO_BUFFERS;
e->tx_max_pending = MAX_TXQ_ENTRIES;
- e->rx_pending = adapter->params.sge.qset[0].fl_size;
- e->rx_mini_pending = adapter->params.sge.qset[0].rspq_size;
- e->rx_jumbo_pending = adapter->params.sge.qset[0].jumbo_size;
- e->tx_pending = adapter->params.sge.qset[0].txq_size[0];
+ e->rx_pending = q->fl_size;
+ e->rx_mini_pending = q->rspq_size;
+ e->rx_jumbo_pending = q->jumbo_size;
+ e->tx_pending = q->txq_size[0];
}
static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
{
int i;
+ struct qset_params *q;
struct adapter *adapter = dev->priv;
+ const struct port_info *pi = netdev_priv(dev);
if (e->rx_pending > MAX_RX_BUFFERS ||
e->rx_jumbo_pending > MAX_RX_JUMBO_BUFFERS ||
@@ -1393,9 +1442,8 @@ static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
if (adapter->flags & FULL_INIT_DONE)
return -EBUSY;
- for (i = 0; i < SGE_QSETS; ++i) {
- struct qset_params *q = &adapter->params.sge.qset[i];
-
+ q = &adapter->params.sge.qset[pi->first_qset];
+ for (i = 0; i < pi->nqsets; ++i, ++q) {
q->rspq_size = e->rx_mini_pending;
q->fl_size = e->rx_pending;
q->jumbo_size = e->rx_jumbo_pending;
@@ -2067,6 +2115,42 @@ static void check_link_status(struct adapter *adapter)
}
}
+static void check_t3b2_mac(struct adapter *adapter)
+{
+ int i;
+
+ if (!rtnl_trylock()) /* synchronize with ifdown */
+ return;
+
+ for_each_port(adapter, i) {
+ struct net_device *dev = adapter->port[i];
+ struct port_info *p = netdev_priv(dev);
+ int status;
+
+ if (!netif_running(dev))
+ continue;
+
+ status = 0;
+ if (netif_running(dev) && netif_carrier_ok(dev))
+ status = t3b2_mac_watchdog_task(&p->mac);
+ if (status == 1)
+ p->mac.stats.num_toggled++;
+ else if (status == 2) {
+ struct cmac *mac = &p->mac;
+
+ t3_mac_set_mtu(mac, dev->mtu);
+ t3_mac_set_address(mac, 0, dev->dev_addr);
+ cxgb_set_rxmode(dev);
+ t3_link_start(&p->phy, mac, &p->link_config);
+ t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
+ t3_port_intr_enable(adapter, p->port_id);
+ p->mac.stats.num_resets++;
+ }
+ }
+ rtnl_unlock();
+}
+
+
static void t3_adap_check_task(struct work_struct *work)
{
struct adapter *adapter = container_of(work, struct adapter,
@@ -2087,6 +2171,9 @@ static void t3_adap_check_task(struct work_struct *work)
adapter->check_task_cnt = 0;
}
+ if (p->rev == T3_REV_B2)
+ check_t3b2_mac(adapter);
+
/* Schedule the next check update if any port is active. */
spin_lock(&adapter->work_lock);
if (adapter->open_device_map & PORT_MASK)
@@ -2195,9 +2282,9 @@ static void __devinit print_port_info(struct adapter *adap,
if (!test_bit(i, &adap->registered_device_map))
continue;
- printk(KERN_INFO "%s: %s %s RNIC (rev %d) %s%s\n",
+ printk(KERN_INFO "%s: %s %s %sNIC (rev %d) %s%s\n",
dev->name, ai->desc, pi->port_type->desc,
- adap->params.rev, buf,
+ is_offload(adap) ? "R" : "", adap->params.rev, buf,
(adap->flags & USING_MSIX) ? " MSI-X" :
(adap->flags & USING_MSI) ? " MSI" : "");
if (adap->name == dev->name && adap->params.vpd.mclk)
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index f6ed033efb56..48649244673e 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -553,7 +553,9 @@ int cxgb3_alloc_atid(struct t3cdev *tdev, struct cxgb3_client *client,
struct tid_info *t = &(T3C_DATA(tdev))->tid_maps;
spin_lock_bh(&t->atid_lock);
- if (t->afree) {
+ if (t->afree &&
+ t->atids_in_use + atomic_read(&t->tids_in_use) + MC5_MIN_TIDS <=
+ t->ntids) {
union active_open_entry *p = t->afree;
atid = (p - t->atid_tab) + t->atid_base;
@@ -741,17 +743,6 @@ static int do_act_establish(struct t3cdev *dev, struct sk_buff *skb)
}
}
-static int do_set_tcb_rpl(struct t3cdev *dev, struct sk_buff *skb)
-{
- struct cpl_set_tcb_rpl *rpl = cplhdr(skb);
-
- if (rpl->status != CPL_ERR_NONE)
- printk(KERN_ERR
- "Unexpected SET_TCB_RPL status %u for tid %u\n",
- rpl->status, GET_TID(rpl));
- return CPL_RET_BUF_DONE;
-}
-
static int do_trace(struct t3cdev *dev, struct sk_buff *skb)
{
struct cpl_trace_pkt *p = cplhdr(skb);
@@ -1213,7 +1204,8 @@ void __init cxgb3_offload_init(void)
t3_register_cpl_handler(CPL_CLOSE_CON_RPL, do_hwtid_rpl);
t3_register_cpl_handler(CPL_ABORT_REQ_RSS, do_abort_req_rss);
t3_register_cpl_handler(CPL_ACT_ESTABLISH, do_act_establish);
- t3_register_cpl_handler(CPL_SET_TCB_RPL, do_set_tcb_rpl);
+ t3_register_cpl_handler(CPL_SET_TCB_RPL, do_hwtid_rpl);
+ t3_register_cpl_handler(CPL_GET_TCB_RPL, do_hwtid_rpl);
t3_register_cpl_handler(CPL_RDMA_TERMINATE, do_term);
t3_register_cpl_handler(CPL_RDMA_EC_STATUS, do_hwtid_rpl);
t3_register_cpl_handler(CPL_TRACE_PKT, do_trace);
diff --git a/drivers/net/cxgb3/mc5.c b/drivers/net/cxgb3/mc5.c
index 644d62ea86a6..84c1ffa8e2d3 100644
--- a/drivers/net/cxgb3/mc5.c
+++ b/drivers/net/cxgb3/mc5.c
@@ -328,6 +328,9 @@ int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters,
unsigned int tcam_size = mc5->tcam_size;
struct adapter *adap = mc5->adapter;
+ if (!tcam_size)
+ return 0;
+
if (nroutes > MAX_ROUTES || nroutes + nservers + nfilters > tcam_size)
return -EINVAL;
diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h
index b56c5f52bcdc..e5a553410e24 100644
--- a/drivers/net/cxgb3/regs.h
+++ b/drivers/net/cxgb3/regs.h
@@ -1206,6 +1206,14 @@
#define A_TP_RX_TRC_KEY0 0x120
+#define A_TP_TX_DROP_CNT_CH0 0x12d
+
+#define S_TXDROPCNTCH0RCVD 0
+#define M_TXDROPCNTCH0RCVD 0xffff
+#define V_TXDROPCNTCH0RCVD(x) ((x) << S_TXDROPCNTCH0RCVD)
+#define G_TXDROPCNTCH0RCVD(x) (((x) >> S_TXDROPCNTCH0RCVD) & \
+ M_TXDROPCNTCH0RCVD)
+
#define A_ULPRX_CTL 0x500
#define S_ROUND_ROBIN 4
@@ -1226,9 +1234,15 @@
#define A_ULPRX_ISCSI_TAGMASK 0x514
+#define S_HPZ0 0
+#define M_HPZ0 0xf
+#define V_HPZ0(x) ((x) << S_HPZ0)
+#define G_HPZ0(x) (((x) >> S_HPZ0) & M_HPZ0)
+
#define A_ULPRX_TDDP_LLIMIT 0x51c
#define A_ULPRX_TDDP_ULIMIT 0x520
+#define A_ULPRX_TDDP_PSZ 0x528
#define A_ULPRX_STAG_LLIMIT 0x52c
@@ -1834,6 +1848,8 @@
#define V_TXPAUSEEN(x) ((x) << S_TXPAUSEEN)
#define F_TXPAUSEEN V_TXPAUSEEN(1U)
+#define A_XGM_TX_PAUSE_QUANTA 0x808
+
#define A_XGM_RX_CTRL 0x80c
#define S_RXEN 0
@@ -1920,11 +1936,20 @@
#define A_XGM_TXFIFO_CFG 0x888
+#define S_TXIPG 13
+#define M_TXIPG 0xff
+#define V_TXIPG(x) ((x) << S_TXIPG)
+#define G_TXIPG(x) (((x) >> S_TXIPG) & M_TXIPG)
+
#define S_TXFIFOTHRESH 4
#define M_TXFIFOTHRESH 0x1ff
#define V_TXFIFOTHRESH(x) ((x) << S_TXFIFOTHRESH)
+#define S_ENDROPPKT 21
+#define V_ENDROPPKT(x) ((x) << S_ENDROPPKT)
+#define F_ENDROPPKT V_ENDROPPKT(1U)
+
#define A_XGM_SERDES_CTRL 0x890
#define A_XGM_SERDES_CTRL0 0x8e0
@@ -2190,6 +2215,13 @@
#define A_XGM_RX_MAX_PKT_SIZE_ERR_CNT 0x9a4
+#define A_XGM_TX_SPI4_SOP_EOP_CNT 0x9a8
+
+#define S_TXSPI4SOPCNT 16
+#define M_TXSPI4SOPCNT 0xffff
+#define V_TXSPI4SOPCNT(x) ((x) << S_TXSPI4SOPCNT)
+#define G_TXSPI4SOPCNT(x) (((x) >> S_TXSPI4SOPCNT) & M_TXSPI4SOPCNT)
+
#define A_XGM_RX_SPI4_SOP_EOP_CNT 0x9ac
#define XGMAC0_1_BASE_ADDR 0xa00
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index c23783432e51..027ab2c3825c 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -2631,7 +2631,7 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
q->txq[TXQ_ETH].stop_thres = nports *
flits_to_desc(sgl_len(MAX_SKB_FRAGS + 1) + 3);
- if (ntxq == 1) {
+ if (!is_offload(adapter)) {
#ifdef USE_RX_PAGE
q->fl[0].buf_size = RX_PAGE_SIZE;
#else
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index eaa7a2e89a30..d83f075ef2d7 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -438,23 +438,23 @@ static const struct adapter_info t3_adap_info[] = {
{2, 0, 0, 0,
F_GPIO2_OEN | F_GPIO4_OEN |
F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5,
- SUPPORTED_OFFLOAD,
+ 0,
&mi1_mdio_ops, "Chelsio PE9000"},
{2, 0, 0, 0,
F_GPIO2_OEN | F_GPIO4_OEN |
F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5,
- SUPPORTED_OFFLOAD,
+ 0,
&mi1_mdio_ops, "Chelsio T302"},
{1, 0, 0, 0,
F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO10_OEN |
F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, 0,
- SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_OFFLOAD,
+ SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
&mi1_mdio_ext_ops, "Chelsio T310"},
{2, 0, 0, 0,
F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO5_OEN | F_GPIO6_OEN |
F_GPIO7_OEN | F_GPIO10_OEN | F_GPIO11_OEN | F_GPIO1_OUT_VAL |
F_GPIO5_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, 0,
- SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_OFFLOAD,
+ SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
&mi1_mdio_ext_ops, "Chelsio T320"},
};
@@ -681,7 +681,8 @@ enum {
SF_ERASE_SECTOR = 0xd8, /* erase sector */
FW_FLASH_BOOT_ADDR = 0x70000, /* start address of FW in flash */
- FW_VERS_ADDR = 0x77ffc /* flash address holding FW version */
+ FW_VERS_ADDR = 0x77ffc, /* flash address holding FW version */
+ FW_MIN_SIZE = 8 /* at least version and csum */
};
/**
@@ -935,7 +936,7 @@ int t3_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size)
const u32 *p = (const u32 *)fw_data;
int ret, addr, fw_sector = FW_FLASH_BOOT_ADDR >> 16;
- if (size & 3)
+ if ((size & 3) || size < FW_MIN_SIZE)
return -EINVAL;
if (size > FW_VERS_ADDR + 8 - FW_FLASH_BOOT_ADDR)
return -EFBIG;
@@ -2899,6 +2900,9 @@ static int mc7_init(struct mc7 *mc7, unsigned int mc7_clock, int mem_type)
struct adapter *adapter = mc7->adapter;
const struct mc7_timing_params *p = &mc7_timings[mem_type];
+ if (!mc7->size)
+ return 0;
+
val = t3_read_reg(adapter, mc7->offset + A_MC7_CFG);
slow = val & F_SLOW;
width = G_WIDTH(val);
@@ -3099,8 +3103,10 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params)
do { /* wait for uP to initialize */
msleep(20);
} while (t3_read_reg(adapter, A_CIM_HOST_ACC_DATA) && --attempts);
- if (!attempts)
+ if (!attempts) {
+ CH_ERR(adapter, "uP initialization timed out\n");
goto out_err;
+ }
err = 0;
out_err:
@@ -3200,7 +3206,7 @@ static void __devinit mc7_prep(struct adapter *adapter, struct mc7 *mc7,
mc7->name = name;
mc7->offset = base_addr - MC7_PMRX_BASE_ADDR;
cfg = t3_read_reg(adapter, mc7->offset + A_MC7_CFG);
- mc7->size = mc7_calc_size(cfg);
+ mc7->size = mc7->size = G_DEN(cfg) == M_DEN ? 0 : mc7_calc_size(cfg);
mc7->width = G_WIDTH(cfg);
}
@@ -3227,6 +3233,7 @@ void early_hw_init(struct adapter *adapter, const struct adapter_info *ai)
V_I2C_CLKDIV(adapter->params.vpd.cclk / 80 - 1));
t3_write_reg(adapter, A_T3DBG_GPIO_EN,
ai->gpio_out | F_GPIO0_OEN | F_GPIO0_OUT_VAL);
+ t3_write_reg(adapter, A_MC5_DB_SERVER_INDEX, 0);
if (adapter->params.rev == 0 || !uses_xaui(adapter))
val |= F_ENRGMII;
@@ -3243,15 +3250,17 @@ void early_hw_init(struct adapter *adapter, const struct adapter_info *ai)
}
/*
- * Reset the adapter. PCIe cards lose their config space during reset, PCI-X
+ * Reset the adapter.
+ * Older PCIe cards lose their config space during reset, PCI-X
* ones don't.
*/
int t3_reset_adapter(struct adapter *adapter)
{
- int i;
+ int i, save_and_restore_pcie =
+ adapter->params.rev < T3_REV_B2 && is_pcie(adapter);
uint16_t devid = 0;
- if (is_pcie(adapter))
+ if (save_and_restore_pcie)
pci_save_state(adapter->pdev);
t3_write_reg(adapter, A_PL_RST, F_CRSTWRM | F_CRSTWRMMODE);
@@ -3269,7 +3278,7 @@ int t3_reset_adapter(struct adapter *adapter)
if (devid != 0x1425)
return -1;
- if (is_pcie(adapter))
+ if (save_and_restore_pcie)
pci_restore_state(adapter->pdev);
return 0;
}
@@ -3323,7 +3332,13 @@ int __devinit t3_prep_adapter(struct adapter *adapter,
p->tx_num_pgs = pm_num_pages(p->chan_tx_size, p->tx_pg_size);
p->ntimer_qs = p->cm_size >= (128 << 20) ||
adapter->params.rev > 0 ? 12 : 6;
+ }
+
+ adapter->params.offload = t3_mc7_size(&adapter->pmrx) &&
+ t3_mc7_size(&adapter->pmtx) &&
+ t3_mc7_size(&adapter->cm);
+ if (is_offload(adapter)) {
adapter->params.mc5.nservers = DEFAULT_NSERVERS;
adapter->params.mc5.nfilters = adapter->params.rev > 0 ?
DEFAULT_NFILTERS : 0;
diff --git a/drivers/net/cxgb3/version.h b/drivers/net/cxgb3/version.h
index 82278f850259..042e27e291cd 100644
--- a/drivers/net/cxgb3/version.h
+++ b/drivers/net/cxgb3/version.h
@@ -36,6 +36,9 @@
#define DRV_NAME "cxgb3"
/* Driver version */
#define DRV_VERSION "1.0-ko"
+
+/* Firmware version */
#define FW_VERSION_MAJOR 3
-#define FW_VERSION_MINOR 2
+#define FW_VERSION_MINOR 3
+#define FW_VERSION_MICRO 0
#endif /* __CHELSIO_VERSION_H */
diff --git a/drivers/net/cxgb3/xgmac.c b/drivers/net/cxgb3/xgmac.c
index 907a272ae32d..a506792f9575 100644
--- a/drivers/net/cxgb3/xgmac.c
+++ b/drivers/net/cxgb3/xgmac.c
@@ -124,9 +124,6 @@ int t3_mac_reset(struct cmac *mac)
xaui_serdes_reset(mac);
}
- if (adap->params.rev > 0)
- t3_write_reg(adap, A_XGM_PAUSE_TIMER + oft, 0xf000);
-
val = F_MAC_RESET_;
if (is_10G(adap))
val |= F_PCS_RESET_;
@@ -145,6 +142,58 @@ int t3_mac_reset(struct cmac *mac)
return 0;
}
+int t3b2_mac_reset(struct cmac *mac)
+{
+ struct adapter *adap = mac->adapter;
+ unsigned int oft = mac->offset;
+ u32 val;
+
+ if (!macidx(mac))
+ t3_set_reg_field(adap, A_MPS_CFG, F_PORT0ACTIVE, 0);
+ else
+ t3_set_reg_field(adap, A_MPS_CFG, F_PORT1ACTIVE, 0);
+
+ t3_write_reg(adap, A_XGM_RESET_CTRL + oft, F_MAC_RESET_);
+ t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */
+
+ msleep(10);
+
+ /* Check for xgm Rx fifo empty */
+ if (t3_wait_op_done(adap, A_XGM_RX_MAX_PKT_SIZE_ERR_CNT + oft,
+ 0x80000000, 1, 5, 2)) {
+ CH_ERR(adap, "MAC %d Rx fifo drain failed\n",
+ macidx(mac));
+ return -1;
+ }
+
+ t3_write_reg(adap, A_XGM_RESET_CTRL + oft, 0);
+ t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */
+
+ val = F_MAC_RESET_;
+ if (is_10G(adap))
+ val |= F_PCS_RESET_;
+ else if (uses_xaui(adap))
+ val |= F_PCS_RESET_ | F_XG2G_RESET_;
+ else
+ val |= F_RGMII_RESET_ | F_XG2G_RESET_;
+ t3_write_reg(adap, A_XGM_RESET_CTRL + oft, val);
+ t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */
+ if ((val & F_PCS_RESET_) && adap->params.rev) {
+ msleep(1);
+ t3b_pcs_reset(mac);
+ }
+ t3_write_reg(adap, A_XGM_RX_CFG + oft,
+ F_DISPAUSEFRAMES | F_EN1536BFRAMES |
+ F_RMFCS | F_ENJUMBO | F_ENHASHMCAST);
+
+ if (!macidx(mac))
+ t3_set_reg_field(adap, A_MPS_CFG, 0, F_PORT0ACTIVE);
+ else
+ t3_set_reg_field(adap, A_MPS_CFG, 0, F_PORT1ACTIVE);
+
+ return 0;
+}
+
/*
* Set the exact match register 'idx' to recognize the given Ethernet address.
*/
@@ -251,9 +300,11 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
* Adjust the PAUSE frame watermarks. We always set the LWM, and the
* HWM only if flow-control is enabled.
*/
- hwm = max(MAC_RXFIFO_SIZE - 3 * mtu, MAC_RXFIFO_SIZE / 2U);
- hwm = min(hwm, 3 * MAC_RXFIFO_SIZE / 4 + 1024);
- lwm = hwm - 1024;
+ hwm = max_t(unsigned int, MAC_RXFIFO_SIZE - 3 * mtu,
+ MAC_RXFIFO_SIZE * 38 / 100);
+ hwm = min(hwm, MAC_RXFIFO_SIZE - 8192);
+ lwm = min(3 * (int)mtu, MAC_RXFIFO_SIZE / 4);
+
v = t3_read_reg(adap, A_XGM_RXFIFO_CFG + mac->offset);
v &= ~V_RXFIFOPAUSELWM(M_RXFIFOPAUSELWM);
v |= V_RXFIFOPAUSELWM(lwm / 8);
@@ -270,7 +321,15 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
thres = mtu > thres ? (mtu - thres + 7) / 8 : 0;
thres = max(thres, 8U); /* need at least 8 */
t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + mac->offset,
- V_TXFIFOTHRESH(M_TXFIFOTHRESH), V_TXFIFOTHRESH(thres));
+ V_TXFIFOTHRESH(M_TXFIFOTHRESH) | V_TXIPG(M_TXIPG),
+ V_TXFIFOTHRESH(thres) | V_TXIPG(1));
+
+ if (adap->params.rev > 0)
+ t3_write_reg(adap, A_XGM_PAUSE_TIMER + mac->offset,
+ (hwm - lwm) * 4 / 8);
+ t3_write_reg(adap, A_XGM_TX_PAUSE_QUANTA + mac->offset,
+ MAC_RXFIFO_SIZE * 4 * 8 / 512);
+
return 0;
}
@@ -298,12 +357,6 @@ int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc)
V_PORTSPEED(M_PORTSPEED), val);
}
- val = t3_read_reg(adap, A_XGM_RXFIFO_CFG + oft);
- val &= ~V_RXFIFOPAUSEHWM(M_RXFIFOPAUSEHWM);
- if (fc & PAUSE_TX)
- val |= V_RXFIFOPAUSEHWM(G_RXFIFOPAUSELWM(val) + 128); /* +1KB */
- t3_write_reg(adap, A_XGM_RXFIFO_CFG + oft, val);
-
t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN,
(fc & PAUSE_RX) ? F_TXPAUSEEN : 0);
return 0;
@@ -314,13 +367,28 @@ int t3_mac_enable(struct cmac *mac, int which)
int idx = macidx(mac);
struct adapter *adap = mac->adapter;
unsigned int oft = mac->offset;
-
+ struct mac_stats *s = &mac->stats;
+
if (which & MAC_DIRECTION_TX) {
t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN);
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
- t3_write_reg(adap, A_TP_PIO_DATA, 0xbf000001);
+ t3_write_reg(adap, A_TP_PIO_DATA, 0xc0ede401);
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_MODE);
t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx);
+
+ t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CNT_CH0 + idx);
+ mac->tx_mcnt = s->tx_frames;
+ mac->tx_tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap,
+ A_TP_PIO_DATA)));
+ mac->tx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
+ A_XGM_TX_SPI4_SOP_EOP_CNT +
+ oft)));
+ mac->rx_mcnt = s->rx_frames;
+ mac->rx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
+ A_XGM_RX_SPI4_SOP_EOP_CNT +
+ oft)));
+ mac->txen = F_TXEN;
+ mac->toggle_cnt = 0;
}
if (which & MAC_DIRECTION_RX)
t3_write_reg(adap, A_XGM_RX_CTRL + oft, F_RXEN);
@@ -331,19 +399,102 @@ int t3_mac_disable(struct cmac *mac, int which)
{
int idx = macidx(mac);
struct adapter *adap = mac->adapter;
+ int val;
if (which & MAC_DIRECTION_TX) {
t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0);
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
t3_write_reg(adap, A_TP_PIO_DATA, 0xc000001f);
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_MODE);
- t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 0);
+ t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx);
+ mac->txen = 0;
}
- if (which & MAC_DIRECTION_RX)
+ if (which & MAC_DIRECTION_RX) {
+ t3_set_reg_field(mac->adapter, A_XGM_RESET_CTRL + mac->offset,
+ F_PCS_RESET_, 0);
+ msleep(100);
t3_write_reg(adap, A_XGM_RX_CTRL + mac->offset, 0);
+ val = F_MAC_RESET_;
+ if (is_10G(adap))
+ val |= F_PCS_RESET_;
+ else if (uses_xaui(adap))
+ val |= F_PCS_RESET_ | F_XG2G_RESET_;
+ else
+ val |= F_RGMII_RESET_ | F_XG2G_RESET_;
+ t3_write_reg(mac->adapter, A_XGM_RESET_CTRL + mac->offset, val);
+ }
return 0;
}
+int t3b2_mac_watchdog_task(struct cmac *mac)
+{
+ struct adapter *adap = mac->adapter;
+ struct mac_stats *s = &mac->stats;
+ unsigned int tx_tcnt, tx_xcnt;
+ unsigned int tx_mcnt = s->tx_frames;
+ unsigned int rx_mcnt = s->rx_frames;
+ unsigned int rx_xcnt;
+ int status;
+
+ if (tx_mcnt == mac->tx_mcnt) {
+ tx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
+ A_XGM_TX_SPI4_SOP_EOP_CNT +
+ mac->offset)));
+ if (tx_xcnt == 0) {
+ t3_write_reg(adap, A_TP_PIO_ADDR,
+ A_TP_TX_DROP_CNT_CH0 + macidx(mac));
+ tx_tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap,
+ A_TP_PIO_DATA)));
+ } else {
+ mac->toggle_cnt = 0;
+ return 0;
+ }
+ } else {
+ mac->toggle_cnt = 0;
+ return 0;
+ }
+
+ if (((tx_tcnt != mac->tx_tcnt) &&
+ (tx_xcnt == 0) && (mac->tx_xcnt == 0)) ||
+ ((mac->tx_mcnt == tx_mcnt) &&
+ (tx_xcnt != 0) && (mac->tx_xcnt != 0))) {
+ if (mac->toggle_cnt > 4)
+ status = 2;
+ else
+ status = 1;
+ } else {
+ mac->toggle_cnt = 0;
+ return 0;
+ }
+
+ if (rx_mcnt != mac->rx_mcnt)
+ rx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
+ A_XGM_RX_SPI4_SOP_EOP_CNT +
+ mac->offset)));
+ else
+ return 0;
+
+ if (mac->rx_mcnt != s->rx_frames && rx_xcnt == 0 && mac->rx_xcnt == 0)
+ status = 2;
+
+ mac->tx_tcnt = tx_tcnt;
+ mac->tx_xcnt = tx_xcnt;
+ mac->tx_mcnt = s->tx_frames;
+ mac->rx_xcnt = rx_xcnt;
+ mac->rx_mcnt = s->rx_frames;
+ if (status == 1) {
+ t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0);
+ t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset); /* flush */
+ t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, mac->txen);
+ t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset); /* flush */
+ mac->toggle_cnt++;
+ } else if (status == 2) {
+ t3b2_mac_reset(mac);
+ mac->toggle_cnt = 0;
+ }
+ return status;
+}
+
/*
* This function is called periodically to accumulate the current values of the
* RMON counters into the port statistics. Since the packet counters are only
@@ -373,7 +524,11 @@ const struct mac_stats *t3_mac_update_stats(struct cmac *mac)
RMON_UPDATE(mac, rx_symbol_errs, RX_SYM_CODE_ERR_FRAMES);
RMON_UPDATE(mac, rx_too_long, RX_OVERSIZE_FRAMES);
- mac->stats.rx_too_long += RMON_READ(mac, A_XGM_RX_MAX_PKT_SIZE_ERR_CNT);
+
+ v = RMON_READ(mac, A_XGM_RX_MAX_PKT_SIZE_ERR_CNT);
+ if (mac->adapter->params.rev == T3_REV_B2)
+ v &= 0x7fffffff;
+ mac->stats.rx_too_long += v;
RMON_UPDATE(mac, rx_frames_64, RX_64B_FRAMES);
RMON_UPDATE(mac, rx_frames_65_127, RX_65_127B_FRAMES);
diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c
index c8c41f0a47d6..714ea1176ec7 100644
--- a/drivers/net/ewrk3.c
+++ b/drivers/net/ewrk3.c
@@ -414,10 +414,9 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
icr &= 0x70;
outb(icr, EWRK3_ICR); /* Disable all the IRQs */
- if (nicsr == (CSR_TXD | CSR_RXD))
+ if (nicsr != (CSR_TXD | CSR_RXD))
return -ENXIO;
-
/* Check that the EEPROM is alive and well and not living on Pluto... */
for (chksum = 0, i = 0; i < EEPROM_MAX; i += 2) {
union {
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 46e1697d9cfd..d04214e4e581 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -2050,9 +2050,10 @@ static void nv_tx_timeout(struct net_device *dev)
nv_drain_tx(dev);
nv_init_tx(dev);
setup_hw_rings(dev, NV_SETUP_TX_RING);
- netif_wake_queue(dev);
}
+ netif_wake_queue(dev);
+
/* 4) restart tx engine */
nv_start_tx(dev);
spin_unlock_irq(&np->lock);
@@ -3536,7 +3537,10 @@ static void nv_do_nic_poll(unsigned long data)
pci_push(base);
if (!using_multi_irqs(dev)) {
- nv_nic_irq(0, dev);
+ if (np->desc_ver == DESC_VER_3)
+ nv_nic_irq_optimized(0, dev);
+ else
+ nv_nic_irq(0, dev);
if (np->msi_flags & NV_MSI_X_ENABLED)
enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index ca2b21f9d444..07b4c0d7a75c 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -96,17 +96,24 @@ static void ri_tasklet(unsigned long dev)
skb->tc_verd = SET_TC_NCLS(skb->tc_verd);
stats->tx_packets++;
stats->tx_bytes +=skb->len;
+
+ skb->dev = __dev_get_by_index(skb->iif);
+ if (!skb->dev) {
+ dev_kfree_skb(skb);
+ stats->tx_dropped++;
+ break;
+ }
+ skb->iif = _dev->ifindex;
+
if (from & AT_EGRESS) {
dp->st_rx_frm_egr++;
dev_queue_xmit(skb);
} else if (from & AT_INGRESS) {
-
dp->st_rx_frm_ing++;
+ skb_pull(skb, skb->dev->hard_header_len);
netif_rx(skb);
- } else {
- dev_kfree_skb(skb);
- stats->tx_dropped++;
- }
+ } else
+ BUG();
}
if (netif_tx_trylock(_dev)) {
@@ -157,26 +164,10 @@ static int ifb_xmit(struct sk_buff *skb, struct net_device *dev)
stats->rx_packets++;
stats->rx_bytes+=skb->len;
- if (!from || !skb->input_dev) {
-dropped:
+ if (!(from & (AT_INGRESS|AT_EGRESS)) || !skb->iif) {
dev_kfree_skb(skb);
stats->rx_dropped++;
return ret;
- } else {
- /*
- * note we could be going
- * ingress -> egress or
- * egress -> ingress
- */
- skb->dev = skb->input_dev;
- skb->input_dev = dev;
- if (from & AT_INGRESS) {
- skb_pull(skb, skb->dev->hard_header_len);
- } else {
- if (!(from & AT_EGRESS)) {
- goto dropped;
- }
- }
}
if (skb_queue_len(&dp->rq) >= dev->tx_queue_len) {
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 340ee99652eb..1d510bdc9b84 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -1057,6 +1057,8 @@ static int stir421x_fw_upload(struct irda_usb_cb *self,
if (ret < 0)
break;
+
+ mdelay(10);
}
kfree(patch_block);
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 9137e239fac2..2272156af31e 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -321,15 +321,22 @@ static void pxa_irda_fir_dma_tx_irq(int channel, void *data)
pxa_irda_set_speed(si, si->newspeed);
si->newspeed = 0;
} else {
+ int i = 64;
+
ICCR0 = 0;
pxa_irda_fir_dma_rx_start(si);
+ while ((ICSR1 & ICSR1_RNE) && i--)
+ (void)ICDR;
ICCR0 = ICCR0_ITR | ICCR0_RXE;
+
+ if (i < 0)
+ printk(KERN_ERR "pxa_ir: cannot clear Rx FIFO!\n");
}
netif_wake_queue(dev);
}
/* EIF(Error in FIFO/End in Frame) handler for FIR */
-static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev)
+static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev, int icsr0)
{
unsigned int len, stat, data;
@@ -350,7 +357,7 @@ static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev)
}
if (stat & ICSR1_ROR) {
printk(KERN_DEBUG "pxa_ir: fir receive overrun\n");
- si->stats.rx_frame_errors++;
+ si->stats.rx_over_errors++;
}
} else {
si->dma_rx_buff[len++] = data;
@@ -362,7 +369,15 @@ static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev)
if (stat & ICSR1_EOF) {
/* end of frame. */
- struct sk_buff *skb = alloc_skb(len+1,GFP_ATOMIC);
+ struct sk_buff *skb;
+
+ if (icsr0 & ICSR0_FRE) {
+ printk(KERN_ERR "pxa_ir: dropping erroneous frame\n");
+ si->stats.rx_dropped++;
+ return;
+ }
+
+ skb = alloc_skb(len+1,GFP_ATOMIC);
if (!skb) {
printk(KERN_ERR "pxa_ir: fir out of memory for receive skb\n");
si->stats.rx_dropped++;
@@ -392,7 +407,7 @@ static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
struct pxa_irda *si = netdev_priv(dev);
- int icsr0;
+ int icsr0, i = 64;
/* stop RX DMA */
DCSR(si->rxdma) &= ~DCSR_RUN;
@@ -412,13 +427,18 @@ static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id)
if (icsr0 & ICSR0_EIF) {
/* An error in FIFO occured, or there is a end of frame */
- pxa_irda_fir_irq_eif(si, dev);
+ pxa_irda_fir_irq_eif(si, dev, icsr0);
}
ICCR0 = 0;
pxa_irda_fir_dma_rx_start(si);
+ while ((ICSR1 & ICSR1_RNE) && i--)
+ (void)ICDR;
ICCR0 = ICCR0_ITR | ICCR0_RXE;
+ if (i < 0)
+ printk(KERN_ERR "pxa_ir: cannot clear Rx FIFO!\n");
+
return IRQ_HANDLED;
}
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 9ba21e0f27c5..8015a7c5b0c9 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -787,6 +787,12 @@ static int mv643xx_eth_open(struct net_device *dev)
unsigned int size;
int err;
+ /* Clear any pending ethernet port interrupts */
+ mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
+ mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
+ /* wait for previous write to complete */
+ mv_read (MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num));
+
err = request_irq(dev->irq, mv643xx_eth_int_handler,
IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, dev);
if (err) {
@@ -875,10 +881,6 @@ static int mv643xx_eth_open(struct net_device *dev)
mv643xx_eth_rx_refill_descs(dev); /* Fill RX ring with skb's */
- /* Clear any pending ethernet port interrupts */
- mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
- mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
-
eth_port_start(dev);
/* Interrupt Coalescing */
@@ -1377,7 +1379,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
spin_lock_init(&mp->lock);
- port_num = pd->port_number;
+ port_num = mp->port_num = pd->port_number;
/* set default config values */
eth_port_uc_addr_get(dev, dev->dev_addr);
@@ -1409,8 +1411,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
duplex = pd->duplex;
speed = pd->speed;
- mp->port_num = port_num;
-
/* Hook up MII support for ethtool */
mp->mii.dev = dev;
mp->mii.mdio_read = mv643xx_mdio_read;
@@ -1514,9 +1514,23 @@ static int mv643xx_eth_shared_remove(struct platform_device *pdev)
return 0;
}
+static void mv643xx_eth_shutdown(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct mv643xx_private *mp = netdev_priv(dev);
+ unsigned int port_num = mp->port_num;
+
+ /* Mask all interrupts on ethernet port */
+ mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), 0);
+ mv_read (MV643XX_ETH_INTERRUPT_MASK_REG(port_num));
+
+ eth_port_reset(port_num);
+}
+
static struct platform_driver mv643xx_eth_driver = {
.probe = mv643xx_eth_probe,
.remove = mv643xx_eth_remove,
+ .shutdown = mv643xx_eth_shutdown,
.driver = {
.name = MV643XX_ETH_NAME,
},
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index b05dc6ed7fb7..f8efe0e70a6b 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -71,7 +71,7 @@
#include "myri10ge_mcp.h"
#include "myri10ge_mcp_gen_header.h"
-#define MYRI10GE_VERSION_STR "1.2.0"
+#define MYRI10GE_VERSION_STR "1.3.0-1.233"
MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -181,6 +181,7 @@ struct myri10ge_priv {
int intr_coal_delay;
__be32 __iomem *intr_coal_delay_ptr;
int mtrr;
+ int wc_enabled;
int wake_queue;
int stop_queue;
int down_cnt;
@@ -233,7 +234,7 @@ static int myri10ge_msi = 1; /* enable msi by default */
module_param(myri10ge_msi, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(myri10ge_msi, "Enable Message Signalled Interrupts\n");
-static int myri10ge_intr_coal_delay = 25;
+static int myri10ge_intr_coal_delay = 75;
module_param(myri10ge_intr_coal_delay, int, S_IRUGO);
MODULE_PARM_DESC(myri10ge_intr_coal_delay, "Interrupt coalescing delay\n");
@@ -278,7 +279,7 @@ static int myri10ge_fill_thresh = 256;
module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed\n");
-static int myri10ge_wcfifo = 1;
+static int myri10ge_wcfifo = 0;
module_param(myri10ge_wcfifo, int, S_IRUGO);
MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n");
@@ -717,6 +718,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
int status;
size_t bytes;
u32 len;
+ struct page *dmatest_page;
+ dma_addr_t dmatest_bus;
/* try to send a reset command to the card to see if it
* is alive */
@@ -726,6 +729,11 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
dev_err(&mgp->pdev->dev, "failed reset\n");
return -ENXIO;
}
+ dmatest_page = alloc_page(GFP_KERNEL);
+ if (!dmatest_page)
+ return -ENOMEM;
+ dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE,
+ DMA_BIDIRECTIONAL);
/* Now exchange information about interrupts */
@@ -764,8 +772,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
len = mgp->tx.boundary;
- cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus);
- cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus);
+ cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
+ cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
cmd.data2 = len * 0x10000;
status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
if (status == 0)
@@ -774,8 +782,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
else
dev_warn(&mgp->pdev->dev, "DMA read benchmark failed: %d\n",
status);
- cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus);
- cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus);
+ cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
+ cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
cmd.data2 = len * 0x1;
status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
if (status == 0)
@@ -785,8 +793,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
dev_warn(&mgp->pdev->dev, "DMA write benchmark failed: %d\n",
status);
- cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus);
- cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus);
+ cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
+ cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
cmd.data2 = len * 0x10001;
status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
if (status == 0)
@@ -796,6 +804,9 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
dev_warn(&mgp->pdev->dev,
"DMA read/write benchmark failed: %d\n", status);
+ pci_unmap_page(mgp->pdev, dmatest_bus, PAGE_SIZE, DMA_BIDIRECTIONAL);
+ put_page(dmatest_page);
+
memset(mgp->rx_done.entry, 0, bytes);
/* reset mcp/driver shared state back to 0 */
@@ -889,9 +900,7 @@ myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
/* try to refill entire ring */
while (rx->fill_cnt != (rx->cnt + rx->mask + 1)) {
idx = rx->fill_cnt & rx->mask;
-
- if ((bytes < MYRI10GE_ALLOC_SIZE / 2) &&
- (rx->page_offset + bytes <= MYRI10GE_ALLOC_SIZE)) {
+ if (rx->page_offset + bytes <= MYRI10GE_ALLOC_SIZE) {
/* we can use part of previous page */
get_page(rx->page);
} else {
@@ -922,6 +931,13 @@ myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
/* start next packet on a cacheline boundary */
rx->page_offset += SKB_DATA_ALIGN(bytes);
+
+#if MYRI10GE_ALLOC_SIZE > 4096
+ /* don't cross a 4KB boundary */
+ if ((rx->page_offset >> 12) !=
+ ((rx->page_offset + bytes - 1) >> 12))
+ rx->page_offset = (rx->page_offset + 4096) & ~4095;
+#endif
rx->fill_cnt++;
/* copy 8 descriptors to the firmware at a time */
@@ -1375,7 +1391,7 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
data[i] = ((unsigned long *)&mgp->stats)[i];
data[i++] = (unsigned int)mgp->tx.boundary;
- data[i++] = (unsigned int)(mgp->mtrr >= 0);
+ data[i++] = (unsigned int)mgp->wc_enabled;
data[i++] = (unsigned int)mgp->pdev->irq;
data[i++] = (unsigned int)mgp->msi_enabled;
data[i++] = (unsigned int)mgp->read_dma;
@@ -1456,6 +1472,8 @@ static int myri10ge_allocate_rings(struct net_device *dev)
status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_RING_SIZE, &cmd, 0);
tx_ring_size = cmd.data0;
status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_RX_RING_SIZE, &cmd, 0);
+ if (status != 0)
+ return status;
rx_ring_size = cmd.data0;
tx_ring_entries = tx_ring_size / sizeof(struct mcp_kreq_ether_send);
@@ -1463,6 +1481,8 @@ static int myri10ge_allocate_rings(struct net_device *dev)
mgp->tx.mask = tx_ring_entries - 1;
mgp->rx_small.mask = mgp->rx_big.mask = rx_ring_entries - 1;
+ status = -ENOMEM;
+
/* allocate the host shadow rings */
bytes = 8 + (MYRI10GE_MAX_SEND_DESC_TSO + 4)
@@ -1735,7 +1755,7 @@ static int myri10ge_open(struct net_device *dev)
goto abort_with_irq;
}
- if (myri10ge_wcfifo && mgp->mtrr >= 0) {
+ if (myri10ge_wcfifo && mgp->wc_enabled) {
mgp->tx.wc_fifo = (u8 __iomem *) mgp->sram + MXGEFW_ETH_SEND_4;
mgp->rx_small.wc_fifo =
(u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_SMALL;
@@ -1992,10 +2012,9 @@ again:
mss = 0;
max_segments = MXGEFW_MAX_SEND_DESC;
- if (skb->len > (dev->mtu + ETH_HLEN)) {
+ if (skb_is_gso(skb)) {
mss = skb_shinfo(skb)->gso_size;
- if (mss != 0)
- max_segments = MYRI10GE_MAX_SEND_DESC_TSO;
+ max_segments = MYRI10GE_MAX_SEND_DESC_TSO;
}
if ((unlikely(avail < max_segments))) {
@@ -2468,6 +2487,12 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
#define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7
#define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa
+#define PCI_DEVICE_ID_INTEL_6300ESB_PCIEE1 0x3510
+#define PCI_DEVICE_ID_INTEL_6300ESB_PCIEE4 0x351b
+#define PCI_DEVICE_ID_INTEL_E3000_PCIE 0x2779
+#define PCI_DEVICE_ID_INTEL_E3010_PCIE 0x277a
+#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST 0x140
+#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST 0x142
static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
{
@@ -2499,6 +2524,24 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
((bridge->vendor == PCI_VENDOR_ID_SERVERWORKS
&& bridge->device ==
PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE)
+ /* ServerWorks HT2100 */
+ || (bridge->vendor == PCI_VENDOR_ID_SERVERWORKS
+ && bridge->device >=
+ PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST
+ && bridge->device <=
+ PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST)
+ /* All Intel E3000/E3010 PCIE ports */
+ || (bridge->vendor == PCI_VENDOR_ID_INTEL
+ && (bridge->device ==
+ PCI_DEVICE_ID_INTEL_E3000_PCIE
+ || bridge->device ==
+ PCI_DEVICE_ID_INTEL_E3010_PCIE))
+ /* All Intel 6310/6311/6321ESB PCIE ports */
+ || (bridge->vendor == PCI_VENDOR_ID_INTEL
+ && bridge->device >=
+ PCI_DEVICE_ID_INTEL_6300ESB_PCIEE1
+ && bridge->device <=
+ PCI_DEVICE_ID_INTEL_6300ESB_PCIEE4)
/* All Intel E5000 PCIE ports */
|| (bridge->vendor == PCI_VENDOR_ID_INTEL
&& bridge->device >=
@@ -2510,6 +2553,12 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
bridge->vendor, bridge->device);
mgp->tx.boundary = 4096;
mgp->fw_name = myri10ge_fw_aligned;
+ } else if (bridge &&
+ bridge->vendor == PCI_VENDOR_ID_SGI &&
+ bridge->device == 0x4002 /* TIOCE pcie-port */ ) {
+ /* this pcie bridge does not support 4K rdma request */
+ mgp->tx.boundary = 2048;
+ mgp->fw_name = myri10ge_fw_aligned;
}
} else {
if (myri10ge_force_firmware == 1) {
@@ -2830,9 +2879,12 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
mgp->board_span = pci_resource_len(pdev, 0);
mgp->iomem_base = pci_resource_start(pdev, 0);
mgp->mtrr = -1;
+ mgp->wc_enabled = 0;
#ifdef CONFIG_MTRR
mgp->mtrr = mtrr_add(mgp->iomem_base, mgp->board_span,
MTRR_TYPE_WRCOMB, 1);
+ if (mgp->mtrr >= 0)
+ mgp->wc_enabled = 1;
#endif
/* Hack. need to get rid of these magic numbers */
mgp->sram_size =
@@ -2927,7 +2979,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dev_info(dev, "%s IRQ %d, tx bndry %d, fw %s, WC %s\n",
(mgp->msi_enabled ? "MSI" : "xPIC"),
netdev->irq, mgp->tx.boundary, mgp->fw_name,
- (mgp->mtrr >= 0 ? "Enabled" : "Disabled"));
+ (mgp->wc_enabled ? "Enabled" : "Disabled"));
return 0;
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index c6172a77a6d7..349b96a3ec4c 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -1712,7 +1712,7 @@ static void init_registers(struct net_device *dev)
/* Enable interrupts by setting the interrupt mask. */
writel(DEFAULT_INTR, ioaddr + IntrMask);
- writel(1, ioaddr + IntrEnable);
+ natsemi_irq_enable(dev);
writel(RxOn | TxOn, ioaddr + ChipCmd);
writel(StatsClear, ioaddr + StatsCtrl); /* Clear Stats */
@@ -2119,28 +2119,35 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
struct netdev_private *np = netdev_priv(dev);
void __iomem * ioaddr = ns_ioaddr(dev);
- if (np->hands_off)
+ /* Reading IntrStatus automatically acknowledges so don't do
+ * that while interrupts are disabled, (for example, while a
+ * poll is scheduled). */
+ if (np->hands_off || !readl(ioaddr + IntrEnable))
return IRQ_NONE;
- /* Reading automatically acknowledges. */
np->intr_status = readl(ioaddr + IntrStatus);
+ if (!np->intr_status)
+ return IRQ_NONE;
+
if (netif_msg_intr(np))
printk(KERN_DEBUG
"%s: Interrupt, status %#08x, mask %#08x.\n",
dev->name, np->intr_status,
readl(ioaddr + IntrMask));
- if (!np->intr_status)
- return IRQ_NONE;
-
prefetch(&np->rx_skbuff[np->cur_rx % RX_RING_SIZE]);
if (netif_rx_schedule_prep(dev)) {
/* Disable interrupts and register for poll */
natsemi_irq_disable(dev);
__netif_rx_schedule(dev);
- }
+ } else
+ printk(KERN_WARNING
+ "%s: Ignoring interrupt, status %#08x, mask %#08x.\n",
+ dev->name, np->intr_status,
+ readl(ioaddr + IntrMask));
+
return IRQ_HANDLED;
}
@@ -2156,6 +2163,20 @@ static int natsemi_poll(struct net_device *dev, int *budget)
int work_done = 0;
do {
+ if (netif_msg_intr(np))
+ printk(KERN_DEBUG
+ "%s: Poll, status %#08x, mask %#08x.\n",
+ dev->name, np->intr_status,
+ readl(ioaddr + IntrMask));
+
+ /* netdev_rx() may read IntrStatus again if the RX state
+ * machine falls over so do it first. */
+ if (np->intr_status &
+ (IntrRxDone | IntrRxIntr | RxStatusFIFOOver |
+ IntrRxErr | IntrRxOverrun)) {
+ netdev_rx(dev, &work_done, work_to_do);
+ }
+
if (np->intr_status &
(IntrTxDone | IntrTxIntr | IntrTxIdle | IntrTxErr)) {
spin_lock(&np->lock);
@@ -2167,12 +2188,6 @@ static int natsemi_poll(struct net_device *dev, int *budget)
if (np->intr_status & IntrAbnormalSummary)
netdev_error(dev, np->intr_status);
- if (np->intr_status &
- (IntrRxDone | IntrRxIntr | RxStatusFIFOOver |
- IntrRxErr | IntrRxOverrun)) {
- netdev_rx(dev, &work_done, work_to_do);
- }
-
*budget -= work_done;
dev->quota -= work_done;
@@ -2399,19 +2414,8 @@ static struct net_device_stats *get_stats(struct net_device *dev)
#ifdef CONFIG_NET_POLL_CONTROLLER
static void natsemi_poll_controller(struct net_device *dev)
{
- struct netdev_private *np = netdev_priv(dev);
-
disable_irq(dev->irq);
-
- /*
- * A real interrupt might have already reached us at this point
- * but NAPI might still haven't called us back. As the interrupt
- * status register is cleared by reading, we should prevent an
- * interrupt loss in this case...
- */
- if (!np->intr_status)
- intr_handler(dev->irq, dev);
-
+ intr_handler(dev->irq, dev);
enable_irq(dev->irq);
}
#endif
@@ -3071,7 +3075,7 @@ static void enable_wol_mode(struct net_device *dev, int enable_intr)
* Could be used to send a netlink message.
*/
writel(WOLPkt | LinkChange, ioaddr + IntrMask);
- writel(1, ioaddr + IntrEnable);
+ natsemi_irq_enable(dev);
}
}
@@ -3202,7 +3206,7 @@ static int natsemi_suspend (struct pci_dev *pdev, pm_message_t state)
disable_irq(dev->irq);
spin_lock_irq(&np->lock);
- writel(0, ioaddr + IntrEnable);
+ natsemi_irq_disable(dev);
np->hands_off = 1;
natsemi_stop_rxtx(dev);
netif_stop_queue(dev);
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 81742e4e5610..dd8ce35332fe 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -232,6 +232,7 @@ enum {
#define MPORT_SINGLE_FUNCTION_MODE 0x1111
extern unsigned long long netxen_dma_mask;
+extern unsigned long last_schedule_time;
/*
* NetXen host-peg signal message structure
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index 986ef98db229..ee1b5a24cbe7 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -462,6 +462,7 @@ netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
}
printk(KERN_INFO "%s: flash unlocked. \n",
netxen_nic_driver_name);
+ last_schedule_time = jiffies;
ret = netxen_flash_erase_secondary(adapter);
if (ret != FLASH_SUCCESS) {
printk(KERN_ERR "%s: Flash erase failed.\n",
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index a2877f33fa85..6537574a9cda 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -228,7 +228,7 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
&adapter->ctx_desc_pdev);
printk("ctx_desc_phys_addr: 0x%llx\n",
- (u64) adapter->ctx_desc_phys_addr);
+ (unsigned long long) adapter->ctx_desc_phys_addr);
if (addr == NULL) {
DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
err = -ENOMEM;
@@ -247,7 +247,8 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
adapter->max_tx_desc_count,
(dma_addr_t *) & hw->cmd_desc_phys_addr,
&adapter->ahw.cmd_desc_pdev);
- printk("cmd_desc_phys_addr: 0x%llx\n", (u64) hw->cmd_desc_phys_addr);
+ printk("cmd_desc_phys_addr: 0x%llx\n",
+ (unsigned long long) hw->cmd_desc_phys_addr);
if (addr == NULL) {
DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
@@ -821,7 +822,10 @@ int netxen_nic_set_mtu_xgb(struct netxen_port *port, int new_mtu)
{
struct netxen_adapter *adapter = port->adapter;
new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE;
- netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu);
+ if (port->portnum == 0)
+ netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu);
+ else if (port->portnum == 1)
+ netxen_nic_write_w0(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE, new_mtu);
return 0;
}
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 586d32b676af..eff965dc5fff 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -42,6 +42,8 @@ struct crb_addr_pair {
u32 data;
};
+unsigned long last_schedule_time;
+
#define NETXEN_MAX_CRB_XFORM 60
static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM];
#define NETXEN_ADDR_ERROR (0xffffffff)
@@ -404,9 +406,14 @@ static inline int do_rom_fast_write(struct netxen_adapter *adapter, int addr,
static inline int
do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
{
+ if (jiffies > (last_schedule_time + (8 * HZ))) {
+ last_schedule_time = jiffies;
+ schedule();
+ }
+
netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
- udelay(70); /* prevent bursting on CRB */
+ udelay(100); /* prevent bursting on CRB */
netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb);
if (netxen_wait_rom_done(adapter)) {
@@ -415,7 +422,7 @@ do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
}
/* reset abyte_cnt and dummy_byte_cnt */
netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
- udelay(70); /* prevent bursting on CRB */
+ udelay(100); /* prevent bursting on CRB */
netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
*valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA);
@@ -431,6 +438,7 @@ do_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
for (addridx = addr; addridx < (addr + size); addridx += 4) {
ret = do_rom_fast_read(adapter, addridx, (int *)bytes);
+ *(int *)bytes = cpu_to_le32(*(int *)bytes);
if (ret != 0)
break;
bytes += 4;
@@ -490,7 +498,7 @@ static inline int do_rom_fast_write_words(struct netxen_adapter *adapter,
int timeout = 0;
int data;
- data = *(u32*)bytes;
+ data = le32_to_cpu((*(u32*)bytes));
ret = do_rom_fast_write(adapter, addridx, data);
if (ret < 0)
diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c
index 00ca0fdb837b..6ca4e4fa6b88 100644
--- a/drivers/net/pci-skeleton.c
+++ b/drivers/net/pci-skeleton.c
@@ -710,8 +710,8 @@ match:
tp->chipset,
rtl_chip_info[tp->chipset].name);
- i = register_netdev (dev);
- if (i)
+ rc = register_netdev (dev);
+ if (rc)
goto err_out_unmap;
DPRINTK ("EXIT, returning 0\n");
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
index a956a51d284f..1060154ae750 100644
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -138,7 +138,7 @@ static const struct ethtool_ops netdev_ethtool_ops = {
======================================================================*/
-static int ibmtr_attach(struct pcmcia_device *link)
+static int __devinit ibmtr_attach(struct pcmcia_device *link)
{
ibmtr_dev_t *info;
struct net_device *dev;
@@ -217,7 +217,7 @@ static void ibmtr_detach(struct pcmcia_device *link)
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-static int ibmtr_config(struct pcmcia_device *link)
+static int __devinit ibmtr_config(struct pcmcia_device *link)
{
ibmtr_dev_t *info = link->priv;
struct net_device *dev = info->dev;
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 11b575f89856..ef58e4128782 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -2544,6 +2544,9 @@ static void ppp_destroy_interface(struct ppp *ppp)
ppp->active_filter = NULL;
#endif /* CONFIG_PPP_FILTER */
+ if (ppp->xmit_pending)
+ kfree_skb(ppp->xmit_pending);
+
kfree(ppp);
}
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index d3f65dab306c..a8246eb2f8d9 100755
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -1691,6 +1691,27 @@ static int ql_populate_free_queue(struct ql3_adapter *qdev)
/*
* Caller holds hw_lock.
*/
+static void ql_update_small_bufq_prod_index(struct ql3_adapter *qdev)
+{
+ struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers;
+ if (qdev->small_buf_release_cnt >= 16) {
+ while (qdev->small_buf_release_cnt >= 16) {
+ qdev->small_buf_q_producer_index++;
+
+ if (qdev->small_buf_q_producer_index ==
+ NUM_SBUFQ_ENTRIES)
+ qdev->small_buf_q_producer_index = 0;
+ qdev->small_buf_release_cnt -= 8;
+ }
+ wmb();
+ writel(qdev->small_buf_q_producer_index,
+ &port_regs->CommonRegs.rxSmallQProducerIndex);
+ }
+}
+
+/*
+ * Caller holds hw_lock.
+ */
static void ql_update_lrg_bufq_prod_index(struct ql3_adapter *qdev)
{
struct bufq_addr_element *lrg_buf_q_ele;
@@ -1732,13 +1753,10 @@ static void ql_update_lrg_bufq_prod_index(struct ql3_adapter *qdev)
lrg_buf_q_ele = qdev->lrg_buf_q_virt_addr;
}
}
-
+ wmb();
qdev->lrg_buf_next_free = lrg_buf_q_ele;
-
- ql_write_common_reg(qdev,
- &port_regs->CommonRegs.
- rxLargeQProducerIndex,
- qdev->lrg_buf_q_producer_index);
+ writel(qdev->lrg_buf_q_producer_index,
+ &port_regs->CommonRegs.rxLargeQProducerIndex);
}
}
@@ -1915,17 +1933,18 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev,
u16 checksum = le16_to_cpu(ib_ip_rsp_ptr->checksum);
if (checksum &
(IB_IP_IOCB_RSP_3032_ICE |
- IB_IP_IOCB_RSP_3032_CE |
- IB_IP_IOCB_RSP_3032_NUC)) {
+ IB_IP_IOCB_RSP_3032_CE)) {
printk(KERN_ERR
"%s: Bad checksum for this %s packet, checksum = %x.\n",
__func__,
((checksum &
IB_IP_IOCB_RSP_3032_TCP) ? "TCP" :
"UDP"),checksum);
- } else if (checksum & IB_IP_IOCB_RSP_3032_TCP) {
+ } else if ((checksum & IB_IP_IOCB_RSP_3032_TCP) ||
+ (checksum & IB_IP_IOCB_RSP_3032_UDP &&
+ !(checksum & IB_IP_IOCB_RSP_3032_NUC))) {
skb2->ip_summed = CHECKSUM_UNNECESSARY;
- }
+ }
}
skb2->dev = qdev->ndev;
skb2->protocol = eth_type_trans(skb2, qdev->ndev);
@@ -1944,16 +1963,12 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev,
static int ql_tx_rx_clean(struct ql3_adapter *qdev,
int *tx_cleaned, int *rx_cleaned, int work_to_do)
{
- struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers;
struct net_rsp_iocb *net_rsp;
struct net_device *ndev = qdev->ndev;
- unsigned long hw_flags;
int work_done = 0;
- u32 rsp_producer_index = le32_to_cpu(*(qdev->prsp_producer_index));
-
/* While there are entries in the completion queue. */
- while ((rsp_producer_index !=
+ while ((le32_to_cpu(*(qdev->prsp_producer_index)) !=
qdev->rsp_consumer_index) && (work_done < work_to_do)) {
net_rsp = qdev->rsp_current;
@@ -2009,33 +2024,7 @@ static int ql_tx_rx_clean(struct ql3_adapter *qdev,
work_done = *tx_cleaned + *rx_cleaned;
}
- if(work_done) {
- spin_lock_irqsave(&qdev->hw_lock, hw_flags);
-
- ql_update_lrg_bufq_prod_index(qdev);
-
- if (qdev->small_buf_release_cnt >= 16) {
- while (qdev->small_buf_release_cnt >= 16) {
- qdev->small_buf_q_producer_index++;
-
- if (qdev->small_buf_q_producer_index ==
- NUM_SBUFQ_ENTRIES)
- qdev->small_buf_q_producer_index = 0;
- qdev->small_buf_release_cnt -= 8;
- }
-
- wmb();
- ql_write_common_reg(qdev,
- &port_regs->CommonRegs.
- rxSmallQProducerIndex,
- qdev->small_buf_q_producer_index);
-
- }
-
- spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
- }
-
- return *tx_cleaned + *rx_cleaned;
+ return work_done;
}
static int ql_poll(struct net_device *ndev, int *budget)
@@ -2059,9 +2048,10 @@ quit_polling:
netif_rx_complete(ndev);
spin_lock_irqsave(&qdev->hw_lock, hw_flags);
- ql_write_common_reg(qdev,
- &port_regs->CommonRegs.rspQConsumerIndex,
- qdev->rsp_consumer_index);
+ ql_update_small_bufq_prod_index(qdev);
+ ql_update_lrg_bufq_prod_index(qdev);
+ writel(qdev->rsp_consumer_index,
+ &port_regs->CommonRegs.rspQConsumerIndex);
spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
ql_enable_interrupts(qdev);
@@ -2217,12 +2207,7 @@ static int ql_send_map(struct ql3_adapter *qdev,
int seg_cnt, seg = 0;
int frag_cnt = (int)skb_shinfo(skb)->nr_frags;
- seg_cnt = tx_cb->seg_count = ql_get_seg_count(qdev,
- (skb_shinfo(skb)->nr_frags));
- if(seg_cnt == -1) {
- printk(KERN_ERR PFX"%s: invalid segment count!\n",__func__);
- return NETDEV_TX_BUSY;
- }
+ seg_cnt = tx_cb->seg_count;
/*
* Map the skb buffer first.
*/
@@ -2278,7 +2263,7 @@ static int ql_send_map(struct ql3_adapter *qdev,
pci_unmap_addr_set(&tx_cb->map[seg], mapaddr,
map);
pci_unmap_len_set(&tx_cb->map[seg], maplen,
- len);
+ sizeof(struct oal));
oal_entry = (struct oal_entry *)oal;
oal++;
seg++;
@@ -2380,6 +2365,7 @@ static int ql3xxx_send(struct sk_buff *skb, struct net_device *ndev)
}
mac_iocb_ptr = tx_cb->queue_entry;
+ memset((void *)mac_iocb_ptr, 0, sizeof(struct ob_mac_iocb_req));
mac_iocb_ptr->opcode = qdev->mac_ob_opcode;
mac_iocb_ptr->flags = OB_MAC_IOCB_REQ_X;
mac_iocb_ptr->flags |= qdev->mb_bit_mask;
@@ -3054,15 +3040,6 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev)
goto out;
}
- if (qdev->mac_index)
- ql_write_page0_reg(qdev,
- &port_regs->mac1MaxFrameLengthReg,
- qdev->max_frame_size);
- else
- ql_write_page0_reg(qdev,
- &port_regs->mac0MaxFrameLengthReg,
- qdev->max_frame_size);
-
value = qdev->nvram_data.tcpMaxWindowSize;
ql_write_page0_reg(qdev, &port_regs->tcpMaxWindow, value);
@@ -3082,6 +3059,14 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev)
ql_sem_unlock(qdev, QL_FLASH_SEM_MASK);
}
+ if (qdev->mac_index)
+ ql_write_page0_reg(qdev,
+ &port_regs->mac1MaxFrameLengthReg,
+ qdev->max_frame_size);
+ else
+ ql_write_page0_reg(qdev,
+ &port_regs->mac0MaxFrameLengthReg,
+ qdev->max_frame_size);
if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK,
(QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) *
@@ -3152,7 +3137,8 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev)
if (qdev->device_id == QL3032_DEVICE_ID) {
value =
(QL3032_PORT_CONTROL_EF | QL3032_PORT_CONTROL_KIE |
- QL3032_PORT_CONTROL_EIv6 | QL3032_PORT_CONTROL_EIv4);
+ QL3032_PORT_CONTROL_EIv6 | QL3032_PORT_CONTROL_EIv4 |
+ QL3032_PORT_CONTROL_ET);
ql_write_page0_reg(qdev, &port_regs->functionControl,
((value << 16) | value));
} else {
diff --git a/drivers/net/qla3xxx.h b/drivers/net/qla3xxx.h
index 34cd6580fd07..0203f88f0544 100755
--- a/drivers/net/qla3xxx.h
+++ b/drivers/net/qla3xxx.h
@@ -1014,8 +1014,7 @@ struct eeprom_data {
/* Transmit and Receive Buffers */
#define NUM_LBUFQ_ENTRIES 128
-#define JUMBO_NUM_LBUFQ_ENTRIES \
-(NUM_LBUFQ_ENTRIES/(JUMBO_MTU_SIZE/NORMAL_MTU_SIZE))
+#define JUMBO_NUM_LBUFQ_ENTRIES 32
#define NUM_SBUFQ_ENTRIES 64
#define QL_SMALL_BUFFER_SIZE 32
#define QL_ADDR_ELE_PER_BUFQ_ENTRY \
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 15d954e50cae..6a77b8a92245 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -66,6 +66,7 @@ VERSION 2.2LK <2005/01/25>
#include <linux/init.h>
#include <linux/dma-mapping.h>
+#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -486,6 +487,7 @@ static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *,
void __iomem *);
static int rtl8169_change_mtu(struct net_device *dev, int new_mtu);
static void rtl8169_down(struct net_device *dev);
+static void rtl8169_rx_clear(struct rtl8169_private *tp);
#ifdef CONFIG_R8169_NAPI
static int rtl8169_poll(struct net_device *dev, int *budget);
@@ -572,8 +574,8 @@ static void rtl8169_xmii_reset_enable(void __iomem *ioaddr)
{
unsigned int val;
- mdio_write(ioaddr, MII_BMCR, BMCR_RESET);
- val = mdio_read(ioaddr, MII_BMCR);
+ val = mdio_read(ioaddr, MII_BMCR) | BMCR_RESET;
+ mdio_write(ioaddr, MII_BMCR, val & 0xffff);
}
static void rtl8169_check_link_status(struct net_device *dev,
@@ -1368,11 +1370,7 @@ static inline void rtl8169_request_timer(struct net_device *dev)
(tp->phy_version >= RTL_GIGA_PHY_VER_H))
return;
- init_timer(timer);
- timer->expires = jiffies + RTL8169_PHY_TIMEOUT;
- timer->data = (unsigned long)(dev);
- timer->function = rtl8169_phy_timer;
- add_timer(timer);
+ mod_timer(timer, jiffies + RTL8169_PHY_TIMEOUT);
}
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -1685,6 +1683,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->mmio_addr = ioaddr;
tp->align = rtl_cfg_info[ent->driver_data].align;
+ init_timer(&tp->timer);
+ tp->timer.data = (unsigned long) dev;
+ tp->timer.function = rtl8169_phy_timer;
+
spin_lock_init(&tp->lock);
rc = register_netdev(dev);
@@ -1751,16 +1753,10 @@ static int rtl8169_open(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
struct pci_dev *pdev = tp->pci_dev;
- int retval;
-
- rtl8169_set_rxbufsize(tp, dev);
+ int retval = -ENOMEM;
- retval =
- request_irq(dev->irq, rtl8169_interrupt, IRQF_SHARED, dev->name, dev);
- if (retval < 0)
- goto out;
- retval = -ENOMEM;
+ rtl8169_set_rxbufsize(tp, dev);
/*
* Rx and Tx desscriptors needs 256 bytes alignment.
@@ -1769,19 +1765,26 @@ static int rtl8169_open(struct net_device *dev)
tp->TxDescArray = pci_alloc_consistent(pdev, R8169_TX_RING_BYTES,
&tp->TxPhyAddr);
if (!tp->TxDescArray)
- goto err_free_irq;
+ goto out;
tp->RxDescArray = pci_alloc_consistent(pdev, R8169_RX_RING_BYTES,
&tp->RxPhyAddr);
if (!tp->RxDescArray)
- goto err_free_tx;
+ goto err_free_tx_0;
retval = rtl8169_init_ring(dev);
if (retval < 0)
- goto err_free_rx;
+ goto err_free_rx_1;
INIT_DELAYED_WORK(&tp->task, NULL);
+ smp_mb();
+
+ retval = request_irq(dev->irq, rtl8169_interrupt, IRQF_SHARED,
+ dev->name, dev);
+ if (retval < 0)
+ goto err_release_ring_2;
+
rtl8169_hw_start(dev);
rtl8169_request_timer(dev);
@@ -1790,14 +1793,14 @@ static int rtl8169_open(struct net_device *dev)
out:
return retval;
-err_free_rx:
+err_release_ring_2:
+ rtl8169_rx_clear(tp);
+err_free_rx_1:
pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray,
tp->RxPhyAddr);
-err_free_tx:
+err_free_tx_0:
pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray,
tp->TxPhyAddr);
-err_free_irq:
- free_irq(dev->irq, dev);
goto out;
}
@@ -2887,7 +2890,7 @@ static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
void __iomem *ioaddr = tp->mmio_addr;
if (!netif_running(dev))
- goto out;
+ goto out_pci_suspend;
netif_device_detach(dev);
netif_stop_queue(dev);
@@ -2901,10 +2904,11 @@ static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
spin_unlock_irq(&tp->lock);
+out_pci_suspend:
pci_save_state(pdev);
pci_enable_wake(pdev, pci_choose_state(pdev, state), tp->wol_enabled);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
-out:
+
return 0;
}
@@ -2912,15 +2916,15 @@ static int rtl8169_resume(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+ pci_enable_wake(pdev, PCI_D0, 0);
+
if (!netif_running(dev))
goto out;
netif_device_attach(dev);
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- pci_enable_wake(pdev, PCI_D0, 0);
-
rtl8169_schedule_work(dev, rtl8169_reset_task);
out:
return 0;
diff --git a/drivers/net/saa9730.c b/drivers/net/saa9730.c
index b269513cde45..143958f1ef0a 100644
--- a/drivers/net/saa9730.c
+++ b/drivers/net/saa9730.c
@@ -64,37 +64,37 @@ static unsigned int pci_irq_line;
static void evm_saa9730_enable_lan_int(struct lan_saa9730_private *lp)
{
- outl(readl(&lp->evm_saa9730_regs->InterruptBlock1) | EVM_LAN_INT,
- &lp->evm_saa9730_regs->InterruptBlock1);
- outl(readl(&lp->evm_saa9730_regs->InterruptStatus1) | EVM_LAN_INT,
- &lp->evm_saa9730_regs->InterruptStatus1);
- outl(readl(&lp->evm_saa9730_regs->InterruptEnable1) | EVM_LAN_INT |
- EVM_MASTER_EN, &lp->evm_saa9730_regs->InterruptEnable1);
+ writel(readl(&lp->evm_saa9730_regs->InterruptBlock1) | EVM_LAN_INT,
+ &lp->evm_saa9730_regs->InterruptBlock1);
+ writel(readl(&lp->evm_saa9730_regs->InterruptStatus1) | EVM_LAN_INT,
+ &lp->evm_saa9730_regs->InterruptStatus1);
+ writel(readl(&lp->evm_saa9730_regs->InterruptEnable1) | EVM_LAN_INT |
+ EVM_MASTER_EN, &lp->evm_saa9730_regs->InterruptEnable1);
}
static void evm_saa9730_disable_lan_int(struct lan_saa9730_private *lp)
{
- outl(readl(&lp->evm_saa9730_regs->InterruptBlock1) & ~EVM_LAN_INT,
- &lp->evm_saa9730_regs->InterruptBlock1);
- outl(readl(&lp->evm_saa9730_regs->InterruptEnable1) & ~EVM_LAN_INT,
- &lp->evm_saa9730_regs->InterruptEnable1);
+ writel(readl(&lp->evm_saa9730_regs->InterruptBlock1) & ~EVM_LAN_INT,
+ &lp->evm_saa9730_regs->InterruptBlock1);
+ writel(readl(&lp->evm_saa9730_regs->InterruptEnable1) & ~EVM_LAN_INT,
+ &lp->evm_saa9730_regs->InterruptEnable1);
}
static void evm_saa9730_clear_lan_int(struct lan_saa9730_private *lp)
{
- outl(EVM_LAN_INT, &lp->evm_saa9730_regs->InterruptStatus1);
+ writel(EVM_LAN_INT, &lp->evm_saa9730_regs->InterruptStatus1);
}
static void evm_saa9730_block_lan_int(struct lan_saa9730_private *lp)
{
- outl(readl(&lp->evm_saa9730_regs->InterruptBlock1) & ~EVM_LAN_INT,
- &lp->evm_saa9730_regs->InterruptBlock1);
+ writel(readl(&lp->evm_saa9730_regs->InterruptBlock1) & ~EVM_LAN_INT,
+ &lp->evm_saa9730_regs->InterruptBlock1);
}
static void evm_saa9730_unblock_lan_int(struct lan_saa9730_private *lp)
{
- outl(readl(&lp->evm_saa9730_regs->InterruptBlock1) | EVM_LAN_INT,
- &lp->evm_saa9730_regs->InterruptBlock1);
+ writel(readl(&lp->evm_saa9730_regs->InterruptBlock1) | EVM_LAN_INT,
+ &lp->evm_saa9730_regs->InterruptBlock1);
}
static void __attribute_used__ show_saa9730_regs(struct lan_saa9730_private *lp)
@@ -147,7 +147,7 @@ static void __attribute_used__ show_saa9730_regs(struct lan_saa9730_private *lp)
printk("lp->lan_saa9730_regs->RxStatus = %x\n",
readl(&lp->lan_saa9730_regs->RxStatus));
for (i = 0; i < LAN_SAA9730_CAM_DWORDS; i++) {
- outl(i, &lp->lan_saa9730_regs->CamAddress);
+ writel(i, &lp->lan_saa9730_regs->CamAddress);
printk("lp->lan_saa9730_regs->CamData = %x\n",
readl(&lp->lan_saa9730_regs->CamData));
}
@@ -288,28 +288,27 @@ static int lan_saa9730_allocate_buffers(struct pci_dev *pdev,
* Set rx buffer A and rx buffer B to point to the first two buffer
* spaces.
*/
- outl(lp->dma_addr + rxoffset,
- &lp->lan_saa9730_regs->RxBuffA);
- outl(lp->dma_addr + rxoffset +
- LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_RCV_Q_SIZE,
- &lp->lan_saa9730_regs->RxBuffB);
+ writel(lp->dma_addr + rxoffset, &lp->lan_saa9730_regs->RxBuffA);
+ writel(lp->dma_addr + rxoffset +
+ LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_RCV_Q_SIZE,
+ &lp->lan_saa9730_regs->RxBuffB);
/*
* Set txm_buf_a and txm_buf_b to point to the first two buffer
* space
*/
- outl(lp->dma_addr + txoffset,
- &lp->lan_saa9730_regs->TxBuffA);
- outl(lp->dma_addr + txoffset +
- LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_TXM_Q_SIZE,
- &lp->lan_saa9730_regs->TxBuffB);
+ writel(lp->dma_addr + txoffset,
+ &lp->lan_saa9730_regs->TxBuffA);
+ writel(lp->dma_addr + txoffset +
+ LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_TXM_Q_SIZE,
+ &lp->lan_saa9730_regs->TxBuffB);
/* Set packet number */
- outl((lp->DmaRcvPackets << PK_COUNT_RX_A_SHF) |
- (lp->DmaRcvPackets << PK_COUNT_RX_B_SHF) |
- (lp->DmaTxmPackets << PK_COUNT_TX_A_SHF) |
- (lp->DmaTxmPackets << PK_COUNT_TX_B_SHF),
- &lp->lan_saa9730_regs->PacketCount);
+ writel((lp->DmaRcvPackets << PK_COUNT_RX_A_SHF) |
+ (lp->DmaRcvPackets << PK_COUNT_RX_B_SHF) |
+ (lp->DmaTxmPackets << PK_COUNT_TX_A_SHF) |
+ (lp->DmaTxmPackets << PK_COUNT_TX_B_SHF),
+ &lp->lan_saa9730_regs->PacketCount);
return 0;
@@ -326,10 +325,10 @@ static int lan_saa9730_cam_load(struct lan_saa9730_private *lp)
for (i = 0; i < LAN_SAA9730_CAM_DWORDS; i++) {
/* First set address to where data is written */
- outl(i, &lp->lan_saa9730_regs->CamAddress);
- outl((NetworkAddress[0] << 24) | (NetworkAddress[1] << 16)
- | (NetworkAddress[2] << 8) | NetworkAddress[3],
- &lp->lan_saa9730_regs->CamData);
+ writel(i, &lp->lan_saa9730_regs->CamAddress);
+ writel((NetworkAddress[0] << 24) | (NetworkAddress[1] << 16) |
+ (NetworkAddress[2] << 8) | NetworkAddress[3],
+ &lp->lan_saa9730_regs->CamData);
NetworkAddress += 4;
}
return 0;
@@ -365,8 +364,8 @@ static int lan_saa9730_mii_init(struct lan_saa9730_private *lp)
}
/* Now set the control and address register. */
- outl(MD_CA_BUSY | PHY_STATUS | PHY_ADDRESS << MD_CA_PHY_SHF,
- &lp->lan_saa9730_regs->StationMgmtCtl);
+ writel(MD_CA_BUSY | PHY_STATUS | PHY_ADDRESS << MD_CA_PHY_SHF,
+ &lp->lan_saa9730_regs->StationMgmtCtl);
/* check link status, spin here till station is not busy */
i = 0;
@@ -391,23 +390,23 @@ static int lan_saa9730_mii_init(struct lan_saa9730_private *lp)
/* Link is down, reset the PHY first. */
/* set PHY address = 'CONTROL' */
- outl(PHY_ADDRESS << MD_CA_PHY_SHF | MD_CA_WR | PHY_CONTROL,
- &lp->lan_saa9730_regs->StationMgmtCtl);
+ writel(PHY_ADDRESS << MD_CA_PHY_SHF | MD_CA_WR | PHY_CONTROL,
+ &lp->lan_saa9730_regs->StationMgmtCtl);
/* Wait for 1 ms. */
mdelay(1);
/* set 'CONTROL' = force reset and renegotiate */
- outl(PHY_CONTROL_RESET | PHY_CONTROL_AUTO_NEG |
- PHY_CONTROL_RESTART_AUTO_NEG,
- &lp->lan_saa9730_regs->StationMgmtData);
+ writel(PHY_CONTROL_RESET | PHY_CONTROL_AUTO_NEG |
+ PHY_CONTROL_RESTART_AUTO_NEG,
+ &lp->lan_saa9730_regs->StationMgmtData);
/* Wait for 50 ms. */
mdelay(50);
/* set 'BUSY' to start operation */
- outl(MD_CA_BUSY | PHY_ADDRESS << MD_CA_PHY_SHF | MD_CA_WR |
- PHY_CONTROL, &lp->lan_saa9730_regs->StationMgmtCtl);
+ writel(MD_CA_BUSY | PHY_ADDRESS << MD_CA_PHY_SHF | MD_CA_WR |
+ PHY_CONTROL, &lp->lan_saa9730_regs->StationMgmtCtl);
/* await completion */
i = 0;
@@ -427,9 +426,9 @@ static int lan_saa9730_mii_init(struct lan_saa9730_private *lp)
for (l = 0; l < 2; l++) {
/* set PHY address = 'STATUS' */
- outl(MD_CA_BUSY | PHY_ADDRESS << MD_CA_PHY_SHF |
- PHY_STATUS,
- &lp->lan_saa9730_regs->StationMgmtCtl);
+ writel(MD_CA_BUSY | PHY_ADDRESS << MD_CA_PHY_SHF |
+ PHY_STATUS,
+ &lp->lan_saa9730_regs->StationMgmtCtl);
/* await completion */
i = 0;
@@ -462,35 +461,35 @@ static int lan_saa9730_mii_init(struct lan_saa9730_private *lp)
static int lan_saa9730_control_init(struct lan_saa9730_private *lp)
{
/* Initialize DMA control register. */
- outl((LANMB_ANY << DMA_CTL_MAX_XFER_SHF) |
- (LANEND_LITTLE << DMA_CTL_ENDIAN_SHF) |
- (LAN_SAA9730_RCV_Q_INT_THRESHOLD << DMA_CTL_RX_INT_COUNT_SHF)
- | DMA_CTL_RX_INT_TO_EN | DMA_CTL_RX_INT_EN |
- DMA_CTL_MAC_RX_INT_EN | DMA_CTL_MAC_TX_INT_EN,
- &lp->lan_saa9730_regs->LanDmaCtl);
+ writel((LANMB_ANY << DMA_CTL_MAX_XFER_SHF) |
+ (LANEND_LITTLE << DMA_CTL_ENDIAN_SHF) |
+ (LAN_SAA9730_RCV_Q_INT_THRESHOLD << DMA_CTL_RX_INT_COUNT_SHF)
+ | DMA_CTL_RX_INT_TO_EN | DMA_CTL_RX_INT_EN |
+ DMA_CTL_MAC_RX_INT_EN | DMA_CTL_MAC_TX_INT_EN,
+ &lp->lan_saa9730_regs->LanDmaCtl);
/* Initial MAC control register. */
- outl((MACCM_MII << MAC_CONTROL_CONN_SHF) | MAC_CONTROL_FULL_DUP,
- &lp->lan_saa9730_regs->MacCtl);
+ writel((MACCM_MII << MAC_CONTROL_CONN_SHF) | MAC_CONTROL_FULL_DUP,
+ &lp->lan_saa9730_regs->MacCtl);
/* Initialize CAM control register. */
- outl(CAM_CONTROL_COMP_EN | CAM_CONTROL_BROAD_ACC,
- &lp->lan_saa9730_regs->CamCtl);
+ writel(CAM_CONTROL_COMP_EN | CAM_CONTROL_BROAD_ACC,
+ &lp->lan_saa9730_regs->CamCtl);
/*
* Initialize CAM enable register, only turn on first entry, should
* contain own addr.
*/
- outl(0x0001, &lp->lan_saa9730_regs->CamEnable);
+ writel(0x0001, &lp->lan_saa9730_regs->CamEnable);
/* Initialize Tx control register */
- outl(TX_CTL_EN_COMP, &lp->lan_saa9730_regs->TxCtl);
+ writel(TX_CTL_EN_COMP, &lp->lan_saa9730_regs->TxCtl);
/* Initialize Rcv control register */
- outl(RX_CTL_STRIP_CRC, &lp->lan_saa9730_regs->RxCtl);
+ writel(RX_CTL_STRIP_CRC, &lp->lan_saa9730_regs->RxCtl);
/* Reset DMA engine */
- outl(DMA_TEST_SW_RESET, &lp->lan_saa9730_regs->DmaTest);
+ writel(DMA_TEST_SW_RESET, &lp->lan_saa9730_regs->DmaTest);
return 0;
}
@@ -500,14 +499,14 @@ static int lan_saa9730_stop(struct lan_saa9730_private *lp)
int i;
/* Stop DMA first */
- outl(readl(&lp->lan_saa9730_regs->LanDmaCtl) &
- ~(DMA_CTL_EN_TX_DMA | DMA_CTL_EN_RX_DMA),
- &lp->lan_saa9730_regs->LanDmaCtl);
+ writel(readl(&lp->lan_saa9730_regs->LanDmaCtl) &
+ ~(DMA_CTL_EN_TX_DMA | DMA_CTL_EN_RX_DMA),
+ &lp->lan_saa9730_regs->LanDmaCtl);
/* Set the SW Reset bits in DMA and MAC control registers */
- outl(DMA_TEST_SW_RESET, &lp->lan_saa9730_regs->DmaTest);
- outl(readl(&lp->lan_saa9730_regs->MacCtl) | MAC_CONTROL_RESET,
- &lp->lan_saa9730_regs->MacCtl);
+ writel(DMA_TEST_SW_RESET, &lp->lan_saa9730_regs->DmaTest);
+ writel(readl(&lp->lan_saa9730_regs->MacCtl) | MAC_CONTROL_RESET,
+ &lp->lan_saa9730_regs->MacCtl);
/*
* Wait for MAC reset to have finished. The reset bit is auto cleared
@@ -532,8 +531,8 @@ static int lan_saa9730_dma_init(struct lan_saa9730_private *lp)
/* Stop lan controller. */
lan_saa9730_stop(lp);
- outl(LAN_SAA9730_DEFAULT_TIME_OUT_CNT,
- &lp->lan_saa9730_regs->Timeout);
+ writel(LAN_SAA9730_DEFAULT_TIME_OUT_CNT,
+ &lp->lan_saa9730_regs->Timeout);
return 0;
}
@@ -552,19 +551,19 @@ static int lan_saa9730_start(struct lan_saa9730_private *lp)
lp->PendingTxmPacketIndex = 0;
lp->PendingTxmBufferIndex = 0;
- outl(readl(&lp->lan_saa9730_regs->LanDmaCtl) | DMA_CTL_EN_TX_DMA |
- DMA_CTL_EN_RX_DMA, &lp->lan_saa9730_regs->LanDmaCtl);
+ writel(readl(&lp->lan_saa9730_regs->LanDmaCtl) | DMA_CTL_EN_TX_DMA |
+ DMA_CTL_EN_RX_DMA, &lp->lan_saa9730_regs->LanDmaCtl);
/* For Tx, turn on MAC then DMA */
- outl(readl(&lp->lan_saa9730_regs->TxCtl) | TX_CTL_TX_EN,
- &lp->lan_saa9730_regs->TxCtl);
+ writel(readl(&lp->lan_saa9730_regs->TxCtl) | TX_CTL_TX_EN,
+ &lp->lan_saa9730_regs->TxCtl);
/* For Rx, turn on DMA then MAC */
- outl(readl(&lp->lan_saa9730_regs->RxCtl) | RX_CTL_RX_EN,
- &lp->lan_saa9730_regs->RxCtl);
+ writel(readl(&lp->lan_saa9730_regs->RxCtl) | RX_CTL_RX_EN,
+ &lp->lan_saa9730_regs->RxCtl);
/* Set Ok2Use to let hardware own the buffers. */
- outl(OK2USE_RX_A | OK2USE_RX_B, &lp->lan_saa9730_regs->Ok2Use);
+ writel(OK2USE_RX_A | OK2USE_RX_B, &lp->lan_saa9730_regs->Ok2Use);
return 0;
}
@@ -587,7 +586,7 @@ static int lan_saa9730_tx(struct net_device *dev)
printk("lan_saa9730_tx interrupt\n");
/* Clear interrupt. */
- outl(DMA_STATUS_MAC_TX_INT, &lp->lan_saa9730_regs->DmaStatus);
+ writel(DMA_STATUS_MAC_TX_INT, &lp->lan_saa9730_regs->DmaStatus);
while (1) {
pPacket = lp->TxmBuffer[lp->PendingTxmBufferIndex]
@@ -660,8 +659,8 @@ static int lan_saa9730_rx(struct net_device *dev)
printk("lan_saa9730_rx interrupt\n");
/* Clear receive interrupts. */
- outl(DMA_STATUS_MAC_RX_INT | DMA_STATUS_RX_INT |
- DMA_STATUS_RX_TO_INT, &lp->lan_saa9730_regs->DmaStatus);
+ writel(DMA_STATUS_MAC_RX_INT | DMA_STATUS_RX_INT |
+ DMA_STATUS_RX_TO_INT, &lp->lan_saa9730_regs->DmaStatus);
/* Address next packet */
BufferIndex = lp->NextRcvBufferIndex;
@@ -725,8 +724,8 @@ static int lan_saa9730_rx(struct net_device *dev)
*pPacket = cpu_to_le32(RXSF_READY << RX_STAT_CTL_OWNER_SHF);
/* Make sure A or B is available to hardware as appropriate. */
- outl(BufferIndex ? OK2USE_RX_B : OK2USE_RX_A,
- &lp->lan_saa9730_regs->Ok2Use);
+ writel(BufferIndex ? OK2USE_RX_B : OK2USE_RX_A,
+ &lp->lan_saa9730_regs->Ok2Use);
/* Go to next packet in sequence. */
lp->NextRcvPacketIndex++;
@@ -844,8 +843,8 @@ static int lan_saa9730_write(struct lan_saa9730_private *lp,
(len << TX_STAT_CTL_LENGTH_SHF));
/* Make sure A or B is available to hardware as appropriate. */
- outl(BufferIndex ? OK2USE_TX_B : OK2USE_TX_A,
- &lp->lan_saa9730_regs->Ok2Use);
+ writel(BufferIndex ? OK2USE_TX_B : OK2USE_TX_A,
+ &lp->lan_saa9730_regs->Ok2Use);
return 0;
}
@@ -938,15 +937,15 @@ static void lan_saa9730_set_multicast(struct net_device *dev)
if (dev->flags & IFF_PROMISC) {
/* accept all packets */
- outl(CAM_CONTROL_COMP_EN | CAM_CONTROL_STATION_ACC |
- CAM_CONTROL_GROUP_ACC | CAM_CONTROL_BROAD_ACC,
- &lp->lan_saa9730_regs->CamCtl);
+ writel(CAM_CONTROL_COMP_EN | CAM_CONTROL_STATION_ACC |
+ CAM_CONTROL_GROUP_ACC | CAM_CONTROL_BROAD_ACC,
+ &lp->lan_saa9730_regs->CamCtl);
} else {
if (dev->flags & IFF_ALLMULTI) {
/* accept all multicast packets */
- outl(CAM_CONTROL_COMP_EN | CAM_CONTROL_GROUP_ACC |
- CAM_CONTROL_BROAD_ACC,
- &lp->lan_saa9730_regs->CamCtl);
+ writel(CAM_CONTROL_COMP_EN | CAM_CONTROL_GROUP_ACC |
+ CAM_CONTROL_BROAD_ACC,
+ &lp->lan_saa9730_regs->CamCtl);
} else {
/*
* Will handle the multicast stuff later. -carstenl
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 1eae16b72b4b..103c3174ab54 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -243,7 +243,7 @@ struct sbmac_softc {
* Controller-specific things
*/
- volatile void __iomem *sbm_base; /* MAC's base address */
+ void __iomem *sbm_base; /* MAC's base address */
sbmac_state_t sbm_state; /* current state */
volatile void __iomem *sbm_macenable; /* MAC Enable Register */
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c
index 4a926f20b6ea..c32c21af3fdd 100644
--- a/drivers/net/sc92031.c
+++ b/drivers/net/sc92031.c
@@ -964,7 +964,7 @@ static int sc92031_start_xmit(struct sk_buff *skb, struct net_device *dev)
goto out;
}
- spin_lock_bh(&priv->lock);
+ spin_lock(&priv->lock);
if (unlikely(!netif_carrier_ok(dev))) {
err = -ENOLINK;
@@ -1005,7 +1005,7 @@ static int sc92031_start_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
out_unlock:
- spin_unlock_bh(&priv->lock);
+ spin_unlock(&priv->lock);
out:
dev_kfree_skb(skb);
@@ -1042,12 +1042,12 @@ static int sc92031_open(struct net_device *dev)
priv->pm_config = 0;
/* Interrupts already disabled by sc92031_stop or sc92031_probe */
- spin_lock(&priv->lock);
+ spin_lock_bh(&priv->lock);
_sc92031_reset(dev);
mmiowb();
- spin_unlock(&priv->lock);
+ spin_unlock_bh(&priv->lock);
sc92031_enable_interrupts(dev);
if (netif_carrier_ok(dev))
@@ -1077,13 +1077,13 @@ static int sc92031_stop(struct net_device *dev)
/* Disable interrupts, stop Tx and Rx. */
sc92031_disable_interrupts(dev);
- spin_lock(&priv->lock);
+ spin_lock_bh(&priv->lock);
_sc92031_disable_tx_rx(dev);
_sc92031_tx_clear(dev);
mmiowb();
- spin_unlock(&priv->lock);
+ spin_unlock_bh(&priv->lock);
free_irq(pdev->irq, dev);
pci_free_consistent(pdev, TX_BUF_TOT_LEN, priv->tx_bufs,
@@ -1539,13 +1539,13 @@ static int sc92031_suspend(struct pci_dev *pdev, pm_message_t state)
/* Disable interrupts, stop Tx and Rx. */
sc92031_disable_interrupts(dev);
- spin_lock(&priv->lock);
+ spin_lock_bh(&priv->lock);
_sc92031_disable_tx_rx(dev);
_sc92031_tx_clear(dev);
mmiowb();
- spin_unlock(&priv->lock);
+ spin_unlock_bh(&priv->lock);
out:
pci_set_power_state(pdev, pci_choose_state(pdev, state));
@@ -1565,12 +1565,12 @@ static int sc92031_resume(struct pci_dev *pdev)
goto out;
/* Interrupts already disabled by sc92031_suspend */
- spin_lock(&priv->lock);
+ spin_lock_bh(&priv->lock);
_sc92031_reset(dev);
mmiowb();
- spin_unlock(&priv->lock);
+ spin_unlock_bh(&priv->lock);
sc92031_enable_interrupts(dev);
netif_device_attach(dev);
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index b08508b35833..34463ce6f132 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -324,6 +324,7 @@ static struct mii_chip_info {
u32 feature;
} mii_chip_table[] = {
{ "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, F_PHY_BCM5461 },
+ { "Broadcom PHY AC131", { 0x0143, 0xbc70 }, LAN, 0 },
{ "Agere PHY ET1101B", { 0x0282, 0xf010 }, LAN, 0 },
{ "Marvell PHY 88E1111", { 0x0141, 0x0cc0 }, LAN, F_PHY_88E1111 },
{ "Realtek PHY RTL8201", { 0x0000, 0x8200 }, LAN, 0 },
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index eea75a401b0c..d476a3cc2e94 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -105,7 +105,8 @@ static const int txqaddr[] = { Q_XA1, Q_XA2 };
static const int rxqaddr[] = { Q_R1, Q_R2 };
static const u32 rxirqmask[] = { IS_R1_F, IS_R2_F };
static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F };
-static const u32 irqmask[] = { IS_R1_F|IS_XA1_F, IS_R2_F|IS_XA2_F };
+static const u32 napimask[] = { IS_R1_F|IS_XA1_F, IS_R2_F|IS_XA2_F };
+static const u32 portmask[] = { IS_PORT_1, IS_PORT_2 };
static int skge_get_regs_len(struct net_device *dev)
{
@@ -162,27 +163,46 @@ static void skge_wol_init(struct skge_port *skge)
{
struct skge_hw *hw = skge->hw;
int port = skge->port;
- enum pause_control save_mode;
- u32 ctrl;
+ u16 ctrl;
- /* Bring hardware out of reset */
skge_write16(hw, B0_CTST, CS_RST_CLR);
skge_write16(hw, SK_REG(port, GMAC_LINK_CTRL), GMLC_RST_CLR);
- skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
- skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
+ /* Turn on Vaux */
+ skge_write8(hw, B0_POWER_CTRL,
+ PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_ON | PC_VCC_OFF);
- /* Force to 10/100 skge_reset will re-enable on resume */
- save_mode = skge->flow_control;
- skge->flow_control = FLOW_MODE_SYMMETRIC;
+ /* WA code for COMA mode -- clear PHY reset */
+ if (hw->chip_id == CHIP_ID_YUKON_LITE &&
+ hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
+ u32 reg = skge_read32(hw, B2_GP_IO);
+ reg |= GP_DIR_9;
+ reg &= ~GP_IO_9;
+ skge_write32(hw, B2_GP_IO, reg);
+ }
- ctrl = skge->advertising;
- skge->advertising &= ~(ADVERTISED_1000baseT_Half|ADVERTISED_1000baseT_Full);
+ skge_write32(hw, SK_REG(port, GPHY_CTRL),
+ GPC_DIS_SLEEP |
+ GPC_HWCFG_M_3 | GPC_HWCFG_M_2 | GPC_HWCFG_M_1 | GPC_HWCFG_M_0 |
+ GPC_ANEG_1 | GPC_RST_SET);
- skge_phy_reset(skge);
+ skge_write32(hw, SK_REG(port, GPHY_CTRL),
+ GPC_DIS_SLEEP |
+ GPC_HWCFG_M_3 | GPC_HWCFG_M_2 | GPC_HWCFG_M_1 | GPC_HWCFG_M_0 |
+ GPC_ANEG_1 | GPC_RST_CLR);
+
+ skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
+
+ /* Force to 10/100 skge_reset will re-enable on resume */
+ gm_phy_write(hw, port, PHY_MARV_AUNE_ADV,
+ PHY_AN_100FULL | PHY_AN_100HALF |
+ PHY_AN_10FULL | PHY_AN_10HALF| PHY_AN_CSMA);
+ /* no 1000 HD/FD */
+ gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, 0);
+ gm_phy_write(hw, port, PHY_MARV_CTRL,
+ PHY_CT_RESET | PHY_CT_SPS_LSB | PHY_CT_ANE |
+ PHY_CT_RE_CFG | PHY_CT_DUP_MD);
- skge->flow_control = save_mode;
- skge->advertising = ctrl;
/* Set GMAC to no flow control and auto update for speed/duplex */
gma_write16(hw, port, GM_GP_CTRL,
@@ -226,12 +246,10 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
struct skge_port *skge = netdev_priv(dev);
struct skge_hw *hw = skge->hw;
- if (wol->wolopts & wol_supported(hw))
+ if (wol->wolopts & ~wol_supported(hw))
return -EOPNOTSUPP;
skge->wol = wol->wolopts;
- if (!netif_running(dev))
- skge_wol_init(skge);
return 0;
}
@@ -671,7 +689,7 @@ static void skge_led(struct skge_port *skge, enum led_mode mode)
struct skge_hw *hw = skge->hw;
int port = skge->port;
- mutex_lock(&hw->phy_mutex);
+ spin_lock_bh(&hw->phy_lock);
if (hw->chip_id == CHIP_ID_GENESIS) {
switch (mode) {
case LED_MODE_OFF:
@@ -742,7 +760,7 @@ static void skge_led(struct skge_port *skge, enum led_mode mode)
PHY_M_LED_MO_RX(MO_LED_ON));
}
}
- mutex_unlock(&hw->phy_mutex);
+ spin_unlock_bh(&hw->phy_lock);
}
/* blink LED's for finding board */
@@ -1316,7 +1334,7 @@ static void xm_phy_init(struct skge_port *skge)
xm_phy_write(hw, port, PHY_XMAC_CTRL, ctrl);
/* Poll PHY for status changes */
- schedule_delayed_work(&skge->link_thread, LINK_HZ);
+ mod_timer(&skge->link_timer, jiffies + LINK_HZ);
}
static void xm_check_link(struct net_device *dev)
@@ -1391,10 +1409,9 @@ static void xm_check_link(struct net_device *dev)
* Since internal PHY is wired to a level triggered pin, can't
* get an interrupt when carrier is detected.
*/
-static void xm_link_timer(struct work_struct *work)
+static void xm_link_timer(unsigned long arg)
{
- struct skge_port *skge =
- container_of(work, struct skge_port, link_thread.work);
+ struct skge_port *skge = (struct skge_port *) arg;
struct net_device *dev = skge->netdev;
struct skge_hw *hw = skge->hw;
int port = skge->port;
@@ -1414,13 +1431,13 @@ static void xm_link_timer(struct work_struct *work)
goto nochange;
}
- mutex_lock(&hw->phy_mutex);
+ spin_lock(&hw->phy_lock);
xm_check_link(dev);
- mutex_unlock(&hw->phy_mutex);
+ spin_unlock(&hw->phy_lock);
nochange:
if (netif_running(dev))
- schedule_delayed_work(&skge->link_thread, LINK_HZ);
+ mod_timer(&skge->link_timer, jiffies + LINK_HZ);
}
static void genesis_mac_init(struct skge_hw *hw, int port)
@@ -2323,7 +2340,7 @@ static void skge_phy_reset(struct skge_port *skge)
netif_stop_queue(skge->netdev);
netif_carrier_off(skge->netdev);
- mutex_lock(&hw->phy_mutex);
+ spin_lock_bh(&hw->phy_lock);
if (hw->chip_id == CHIP_ID_GENESIS) {
genesis_reset(hw, port);
genesis_mac_init(hw, port);
@@ -2331,7 +2348,7 @@ static void skge_phy_reset(struct skge_port *skge)
yukon_reset(hw, port);
yukon_init(hw, port);
}
- mutex_unlock(&hw->phy_mutex);
+ spin_unlock_bh(&hw->phy_lock);
dev->set_multicast_list(dev);
}
@@ -2354,12 +2371,12 @@ static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
/* fallthru */
case SIOCGMIIREG: {
u16 val = 0;
- mutex_lock(&hw->phy_mutex);
+ spin_lock_bh(&hw->phy_lock);
if (hw->chip_id == CHIP_ID_GENESIS)
err = __xm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val);
else
err = __gm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val);
- mutex_unlock(&hw->phy_mutex);
+ spin_unlock_bh(&hw->phy_lock);
data->val_out = val;
break;
}
@@ -2368,14 +2385,14 @@ static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- mutex_lock(&hw->phy_mutex);
+ spin_lock_bh(&hw->phy_lock);
if (hw->chip_id == CHIP_ID_GENESIS)
err = xm_phy_write(hw, skge->port, data->reg_num & 0x1f,
data->val_in);
else
err = gm_phy_write(hw, skge->port, data->reg_num & 0x1f,
data->val_in);
- mutex_unlock(&hw->phy_mutex);
+ spin_unlock_bh(&hw->phy_lock);
break;
}
return err;
@@ -2481,12 +2498,12 @@ static int skge_up(struct net_device *dev)
goto free_rx_ring;
/* Initialize MAC */
- mutex_lock(&hw->phy_mutex);
+ spin_lock_bh(&hw->phy_lock);
if (hw->chip_id == CHIP_ID_GENESIS)
genesis_mac_init(hw, port);
else
yukon_mac_init(hw, port);
- mutex_unlock(&hw->phy_mutex);
+ spin_unlock_bh(&hw->phy_lock);
/* Configure RAMbuffers */
chunk = hw->ram_size / ((hw->ports + 1)*2);
@@ -2504,6 +2521,11 @@ static int skge_up(struct net_device *dev)
skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F);
skge_led(skge, LED_MODE_ON);
+ spin_lock_irq(&hw->hw_lock);
+ hw->intr_mask |= portmask[port];
+ skge_write32(hw, B0_IMSK, hw->intr_mask);
+ spin_unlock_irq(&hw->hw_lock);
+
netif_poll_enable(dev);
return 0;
@@ -2530,8 +2552,17 @@ static int skge_down(struct net_device *dev)
printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
netif_stop_queue(dev);
+
if (hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC)
- cancel_delayed_work(&skge->link_thread);
+ del_timer_sync(&skge->link_timer);
+
+ netif_poll_disable(dev);
+ netif_carrier_off(dev);
+
+ spin_lock_irq(&hw->hw_lock);
+ hw->intr_mask &= ~portmask[port];
+ skge_write32(hw, B0_IMSK, hw->intr_mask);
+ spin_unlock_irq(&hw->hw_lock);
skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF);
if (hw->chip_id == CHIP_ID_GENESIS)
@@ -2575,8 +2606,10 @@ static int skge_down(struct net_device *dev)
skge_led(skge, LED_MODE_OFF);
- netif_poll_disable(dev);
+ netif_tx_lock_bh(dev);
skge_tx_clean(dev);
+ netif_tx_unlock_bh(dev);
+
skge_rx_clean(skge);
kfree(skge->rx_ring.start);
@@ -2721,7 +2754,6 @@ static void skge_tx_clean(struct net_device *dev)
struct skge_port *skge = netdev_priv(dev);
struct skge_element *e;
- netif_tx_lock_bh(dev);
for (e = skge->tx_ring.to_clean; e != skge->tx_ring.to_use; e = e->next) {
struct skge_tx_desc *td = e->desc;
skge_tx_free(skge, e, td->control);
@@ -2730,7 +2762,6 @@ static void skge_tx_clean(struct net_device *dev)
skge->tx_ring.to_clean = e;
netif_wake_queue(dev);
- netif_tx_unlock_bh(dev);
}
static void skge_tx_timeout(struct net_device *dev)
@@ -3049,7 +3080,7 @@ static int skge_poll(struct net_device *dev, int *budget)
spin_lock_irqsave(&hw->hw_lock, flags);
__netif_rx_complete(dev);
- hw->intr_mask |= irqmask[skge->port];
+ hw->intr_mask |= napimask[skge->port];
skge_write32(hw, B0_IMSK, hw->intr_mask);
skge_read32(hw, B0_IMSK);
spin_unlock_irqrestore(&hw->hw_lock, flags);
@@ -3160,28 +3191,29 @@ static void skge_error_irq(struct skge_hw *hw)
}
/*
- * Interrupt from PHY are handled in work queue
+ * Interrupt from PHY are handled in tasklet (softirq)
* because accessing phy registers requires spin wait which might
* cause excess interrupt latency.
*/
-static void skge_extirq(struct work_struct *work)
+static void skge_extirq(unsigned long arg)
{
- struct skge_hw *hw = container_of(work, struct skge_hw, phy_work);
+ struct skge_hw *hw = (struct skge_hw *) arg;
int port;
- mutex_lock(&hw->phy_mutex);
for (port = 0; port < hw->ports; port++) {
struct net_device *dev = hw->dev[port];
- struct skge_port *skge = netdev_priv(dev);
if (netif_running(dev)) {
+ struct skge_port *skge = netdev_priv(dev);
+
+ spin_lock(&hw->phy_lock);
if (hw->chip_id != CHIP_ID_GENESIS)
yukon_phy_intr(skge);
else if (hw->phy_type == SK_PHY_BCOM)
bcom_phy_intr(skge);
+ spin_unlock(&hw->phy_lock);
}
}
- mutex_unlock(&hw->phy_mutex);
spin_lock_irq(&hw->hw_lock);
hw->intr_mask |= IS_EXT_REG;
@@ -3206,7 +3238,7 @@ static irqreturn_t skge_intr(int irq, void *dev_id)
status &= hw->intr_mask;
if (status & IS_EXT_REG) {
hw->intr_mask &= ~IS_EXT_REG;
- schedule_work(&hw->phy_work);
+ tasklet_schedule(&hw->phy_task);
}
if (status & (IS_XA1_F|IS_R1_F)) {
@@ -3275,24 +3307,35 @@ static int skge_set_mac_address(struct net_device *dev, void *p)
struct skge_hw *hw = skge->hw;
unsigned port = skge->port;
const struct sockaddr *addr = p;
+ u16 ctrl;
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
- mutex_lock(&hw->phy_mutex);
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
- memcpy_toio(hw->regs + B2_MAC_1 + port*8,
- dev->dev_addr, ETH_ALEN);
- memcpy_toio(hw->regs + B2_MAC_2 + port*8,
- dev->dev_addr, ETH_ALEN);
- if (hw->chip_id == CHIP_ID_GENESIS)
- xm_outaddr(hw, port, XM_SA, dev->dev_addr);
- else {
- gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr);
- gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr);
+ if (!netif_running(dev)) {
+ memcpy_toio(hw->regs + B2_MAC_1 + port*8, dev->dev_addr, ETH_ALEN);
+ memcpy_toio(hw->regs + B2_MAC_2 + port*8, dev->dev_addr, ETH_ALEN);
+ } else {
+ /* disable Rx */
+ spin_lock_bh(&hw->phy_lock);
+ ctrl = gma_read16(hw, port, GM_GP_CTRL);
+ gma_write16(hw, port, GM_GP_CTRL, ctrl & ~GM_GPCR_RX_ENA);
+
+ memcpy_toio(hw->regs + B2_MAC_1 + port*8, dev->dev_addr, ETH_ALEN);
+ memcpy_toio(hw->regs + B2_MAC_2 + port*8, dev->dev_addr, ETH_ALEN);
+
+ if (hw->chip_id == CHIP_ID_GENESIS)
+ xm_outaddr(hw, port, XM_SA, dev->dev_addr);
+ else {
+ gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr);
+ gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr);
+ }
+
+ gma_write16(hw, port, GM_GP_CTRL, ctrl);
+ spin_unlock_bh(&hw->phy_lock);
}
- mutex_unlock(&hw->phy_mutex);
return 0;
}
@@ -3407,10 +3450,9 @@ static int skge_reset(struct skge_hw *hw)
else
hw->ram_size = t8 * 4096;
- hw->intr_mask = IS_HW_ERR | IS_PORT_1;
- if (hw->ports > 1)
- hw->intr_mask |= IS_PORT_2;
+ hw->intr_mask = IS_HW_ERR;
+ /* Use PHY IRQ for all but fiber based Genesis board */
if (!(hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC))
hw->intr_mask |= IS_EXT_REG;
@@ -3478,14 +3520,12 @@ static int skge_reset(struct skge_hw *hw)
skge_write32(hw, B0_IMSK, hw->intr_mask);
- mutex_lock(&hw->phy_mutex);
for (i = 0; i < hw->ports; i++) {
if (hw->chip_id == CHIP_ID_GENESIS)
genesis_reset(hw, i);
else
yukon_reset(hw, i);
}
- mutex_unlock(&hw->phy_mutex);
return 0;
}
@@ -3533,6 +3573,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
skge->netdev = dev;
skge->hw = hw;
skge->msg_enable = netif_msg_init(debug, default_msg);
+
skge->tx_ring.count = DEFAULT_TX_RING_SIZE;
skge->rx_ring.count = DEFAULT_RX_RING_SIZE;
@@ -3549,7 +3590,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
skge->port = port;
/* Only used for Genesis XMAC */
- INIT_DELAYED_WORK(&skge->link_thread, xm_link_timer);
+ setup_timer(&skge->link_timer, xm_link_timer, (unsigned long) skge);
if (hw->chip_id != CHIP_ID_GENESIS) {
dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
@@ -3631,9 +3672,9 @@ static int __devinit skge_probe(struct pci_dev *pdev,
}
hw->pdev = pdev;
- mutex_init(&hw->phy_mutex);
- INIT_WORK(&hw->phy_work, skge_extirq);
spin_lock_init(&hw->hw_lock);
+ spin_lock_init(&hw->phy_lock);
+ tasklet_init(&hw->phy_task, &skge_extirq, (unsigned long) hw);
hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000);
if (!hw->regs) {
@@ -3719,6 +3760,8 @@ static void __devexit skge_remove(struct pci_dev *pdev)
dev0 = hw->dev[0];
unregister_netdev(dev0);
+ tasklet_disable(&hw->phy_task);
+
spin_lock_irq(&hw->hw_lock);
hw->intr_mask = 0;
skge_write32(hw, B0_IMSK, 0);
@@ -3741,21 +3784,6 @@ static void __devexit skge_remove(struct pci_dev *pdev)
}
#ifdef CONFIG_PM
-static int vaux_avail(struct pci_dev *pdev)
-{
- int pm_cap;
-
- pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
- if (pm_cap) {
- u16 ctl;
- pci_read_config_word(pdev, pm_cap + PCI_PM_PMC, &ctl);
- if (ctl & PCI_PM_CAP_AUX_POWER)
- return 1;
- }
- return 0;
-}
-
-
static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct skge_hw *hw = pci_get_drvdata(pdev);
@@ -3777,10 +3805,6 @@ static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
wol |= skge->wol;
}
- if (wol && vaux_avail(pdev))
- skge_write8(hw, B0_POWER_CTRL,
- PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_ON | PC_VCC_OFF);
-
skge_write32(hw, B0_IMSK, 0);
pci_enable_wake(pdev, pci_choose_state(pdev, state), wol);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
@@ -3826,6 +3850,28 @@ out:
}
#endif
+static void skge_shutdown(struct pci_dev *pdev)
+{
+ struct skge_hw *hw = pci_get_drvdata(pdev);
+ int i, wol = 0;
+
+ for (i = 0; i < hw->ports; i++) {
+ struct net_device *dev = hw->dev[i];
+ struct skge_port *skge = netdev_priv(dev);
+
+ if (skge->wol)
+ skge_wol_init(skge);
+ wol |= skge->wol;
+ }
+
+ pci_enable_wake(pdev, PCI_D3hot, wol);
+ pci_enable_wake(pdev, PCI_D3cold, wol);
+
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+
+}
+
static struct pci_driver skge_driver = {
.name = DRV_NAME,
.id_table = skge_id_table,
@@ -3835,6 +3881,7 @@ static struct pci_driver skge_driver = {
.suspend = skge_suspend,
.resume = skge_resume,
#endif
+ .shutdown = skge_shutdown,
};
static int __init skge_init_module(void)
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index e9354dfa7e9a..86467ae74d45 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -2424,8 +2424,8 @@ struct skge_hw {
u32 ram_size;
u32 ram_offset;
u16 phy_addr;
- struct work_struct phy_work;
- struct mutex phy_mutex;
+ spinlock_t phy_lock;
+ struct tasklet_struct phy_task;
};
enum pause_control {
@@ -2457,7 +2457,7 @@ struct skge_port {
struct net_device_stats net_stats;
- struct delayed_work link_thread;
+ struct timer_list link_timer;
enum pause_control flow_control;
enum pause_status flow_status;
u8 rx_csum;
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 53839979cfb8..4a009b7b1777 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -510,9 +510,9 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
ledover &= ~PHY_M_LED_MO_RX;
}
- if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == CHIP_REV_YU_EC_A1) {
+ if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
+ hw->chip_rev == CHIP_REV_YU_EC_U_A1) {
/* apply fixes in PHY AFE */
- pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 255);
/* increase differential signal amplitude in 10BASE-T */
@@ -524,7 +524,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
gm_phy_write(hw, port, 0x17, 0x2002);
/* set page register to 0 */
- gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+ gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
} else if (hw->chip_id != CHIP_ID_YUKON_EX) {
gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
@@ -1561,6 +1561,7 @@ static int sky2_down(struct net_device *dev)
/* Stop more packets from being queued */
netif_stop_queue(dev);
+ netif_carrier_off(dev);
/* Disable port IRQ */
imask = sky2_read32(hw, B0_IMSK);
@@ -2165,9 +2166,27 @@ force_update:
/* fall through */
#endif
case OP_RXCHKS:
- skb = sky2->rx_ring[sky2->rx_next].skb;
- skb->ip_summed = CHECKSUM_COMPLETE;
- skb->csum = status & 0xffff;
+ if (!sky2->rx_csum)
+ break;
+
+ /* Both checksum counters are programmed to start at
+ * the same offset, so unless there is a problem they
+ * should match. This failure is an early indication that
+ * hardware receive checksumming won't work.
+ */
+ if (likely(status >> 16 == (status & 0xffff))) {
+ skb = sky2->rx_ring[sky2->rx_next].skb;
+ skb->ip_summed = CHECKSUM_COMPLETE;
+ skb->csum = status & 0xffff;
+ } else {
+ printk(KERN_NOTICE PFX "%s: hardware receive "
+ "checksum problem (status = %#x)\n",
+ dev->name, status);
+ sky2->rx_csum = 0;
+ sky2_write32(sky2->hw,
+ Q_ADDR(rxqaddr[le->link], Q_CSR),
+ BMU_DIS_RX_CHKSUM);
+ }
break;
case OP_TXINDEXLE:
@@ -3751,6 +3770,11 @@ static int sky2_resume(struct pci_dev *pdev)
goto out;
pci_enable_wake(pdev, PCI_D0, 0);
+
+ /* Re-enable all clocks */
+ if (hw->chip_id == CHIP_ID_YUKON_EX || hw->chip_id == CHIP_ID_YUKON_EC_U)
+ sky2_pci_write32(hw, PCI_DEV_REG3, 0);
+
sky2_reset(hw);
sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c
index c62e85d89f41..7bee45b42a2c 100644
--- a/drivers/net/sun3lance.c
+++ b/drivers/net/sun3lance.c
@@ -336,13 +336,27 @@ static int __init lance_probe( struct net_device *dev)
/* XXX - leak? */
MEM = dvma_malloc_align(sizeof(struct lance_memory), 0x10000);
+ if (MEM == NULL) {
+#ifdef CONFIG_SUN3
+ iounmap((void __iomem *)ioaddr);
+#endif
+ printk(KERN_WARNING "SUN3 Lance couldn't allocate DVMA memory\n");
+ return 0;
+ }
lp->iobase = (volatile unsigned short *)ioaddr;
dev->base_addr = (unsigned long)ioaddr; /* informational only */
REGA(CSR0) = CSR0_STOP;
- request_irq(LANCE_IRQ, lance_interrupt, IRQF_DISABLED, "SUN3 Lance", dev);
+ if (request_irq(LANCE_IRQ, lance_interrupt, IRQF_DISABLED, "SUN3 Lance", dev) < 0) {
+#ifdef CONFIG_SUN3
+ iounmap((void __iomem *)ioaddr);
+#endif
+ dvma_free((void *)MEM);
+ printk(KERN_WARNING "SUN3 Lance unable to allocate IRQ\n");
+ return 0;
+ }
dev->irq = (unsigned short)LANCE_IRQ;
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 616be8d0fa85..08ea61db46fe 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -2530,6 +2530,35 @@ static struct net_device_stats *gem_get_stats(struct net_device *dev)
return &gp->net_stats;
}
+static int gem_set_mac_address(struct net_device *dev, void *addr)
+{
+ struct sockaddr *macaddr = (struct sockaddr *) addr;
+ struct gem *gp = dev->priv;
+ unsigned char *e = &dev->dev_addr[0];
+
+ if (!is_valid_ether_addr(macaddr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ if (!netif_running(dev) || !netif_device_present(dev)) {
+ /* We'll just catch it later when the
+ * device is up'd or resumed.
+ */
+ memcpy(dev->dev_addr, macaddr->sa_data, dev->addr_len);
+ return 0;
+ }
+
+ mutex_lock(&gp->pm_mutex);
+ memcpy(dev->dev_addr, macaddr->sa_data, dev->addr_len);
+ if (gp->running) {
+ writel((e[4] << 8) | e[5], gp->regs + MAC_ADDR0);
+ writel((e[2] << 8) | e[3], gp->regs + MAC_ADDR1);
+ writel((e[0] << 8) | e[1], gp->regs + MAC_ADDR2);
+ }
+ mutex_unlock(&gp->pm_mutex);
+
+ return 0;
+}
+
static void gem_set_multicast(struct net_device *dev)
{
struct gem *gp = dev->priv;
@@ -3122,6 +3151,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
dev->change_mtu = gem_change_mtu;
dev->irq = pdev->irq;
dev->dma = 0;
+ dev->set_mac_address = gem_set_mac_address;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = gem_poll_controller;
#endif
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 8c8f9f4d47a5..256969e1300c 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -64,8 +64,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.74"
-#define DRV_MODULE_RELDATE "February 20, 2007"
+#define DRV_MODULE_VERSION "3.75"
+#define DRV_MODULE_RELDATE "March 23, 2007"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -3568,32 +3568,34 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id)
* Reading the PCI State register will confirm whether the
* interrupt is ours and will flush the status block.
*/
- if ((sblk->status & SD_STATUS_UPDATED) ||
- !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
- /*
- * Writing any value to intr-mbox-0 clears PCI INTA# and
- * chip-internal interrupt pending events.
- * Writing non-zero to intr-mbox-0 additional tells the
- * NIC to stop sending us irqs, engaging "in-intr-handler"
- * event coalescing.
- */
- tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
- 0x00000001);
- if (tg3_irq_sync(tp))
+ if (unlikely(!(sblk->status & SD_STATUS_UPDATED))) {
+ if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) ||
+ (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
+ handled = 0;
goto out;
- sblk->status &= ~SD_STATUS_UPDATED;
- if (likely(tg3_has_work(tp))) {
- prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
- netif_rx_schedule(dev); /* schedule NAPI poll */
- } else {
- /* No work, shared interrupt perhaps? re-enable
- * interrupts, and flush that PCI write
- */
- tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
- 0x00000000);
}
- } else { /* shared interrupt */
- handled = 0;
+ }
+
+ /*
+ * Writing any value to intr-mbox-0 clears PCI INTA# and
+ * chip-internal interrupt pending events.
+ * Writing non-zero to intr-mbox-0 additional tells the
+ * NIC to stop sending us irqs, engaging "in-intr-handler"
+ * event coalescing.
+ */
+ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+ if (tg3_irq_sync(tp))
+ goto out;
+ sblk->status &= ~SD_STATUS_UPDATED;
+ if (likely(tg3_has_work(tp))) {
+ prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+ netif_rx_schedule(dev); /* schedule NAPI poll */
+ } else {
+ /* No work, shared interrupt perhaps? re-enable
+ * interrupts, and flush that PCI write
+ */
+ tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
+ 0x00000000);
}
out:
return IRQ_RETVAL(handled);
@@ -3611,31 +3613,33 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
* Reading the PCI State register will confirm whether the
* interrupt is ours and will flush the status block.
*/
- if ((sblk->status_tag != tp->last_tag) ||
- !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
- /*
- * writing any value to intr-mbox-0 clears PCI INTA# and
- * chip-internal interrupt pending events.
- * writing non-zero to intr-mbox-0 additional tells the
- * NIC to stop sending us irqs, engaging "in-intr-handler"
- * event coalescing.
- */
- tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
- 0x00000001);
- if (tg3_irq_sync(tp))
+ if (unlikely(sblk->status_tag == tp->last_tag)) {
+ if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) ||
+ (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
+ handled = 0;
goto out;
- if (netif_rx_schedule_prep(dev)) {
- prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
- /* Update last_tag to mark that this status has been
- * seen. Because interrupt may be shared, we may be
- * racing with tg3_poll(), so only update last_tag
- * if tg3_poll() is not scheduled.
- */
- tp->last_tag = sblk->status_tag;
- __netif_rx_schedule(dev);
}
- } else { /* shared interrupt */
- handled = 0;
+ }
+
+ /*
+ * writing any value to intr-mbox-0 clears PCI INTA# and
+ * chip-internal interrupt pending events.
+ * writing non-zero to intr-mbox-0 additional tells the
+ * NIC to stop sending us irqs, engaging "in-intr-handler"
+ * event coalescing.
+ */
+ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+ if (tg3_irq_sync(tp))
+ goto out;
+ if (netif_rx_schedule_prep(dev)) {
+ prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+ /* Update last_tag to mark that this status has been
+ * seen. Because interrupt may be shared, we may be
+ * racing with tg3_poll(), so only update last_tag
+ * if tg3_poll() is not scheduled.
+ */
+ tp->last_tag = sblk->status_tag;
+ __netif_rx_schedule(dev);
}
out:
return IRQ_RETVAL(handled);
@@ -4823,6 +4827,21 @@ static int tg3_chip_reset(struct tg3 *tp)
if (write_op == tg3_write_flush_reg32)
tp->write32 = tg3_write32;
+ /* Prevent the irq handler from reading or writing PCI registers
+ * during chip reset when the memory enable bit in the PCI command
+ * register may be cleared. The chip does not generate interrupt
+ * at this time, but the irq handler may still be called due to irq
+ * sharing or irqpoll.
+ */
+ tp->tg3_flags |= TG3_FLAG_CHIP_RESETTING;
+ if (tp->hw_status) {
+ tp->hw_status->status = 0;
+ tp->hw_status->status_tag = 0;
+ }
+ tp->last_tag = 0;
+ smp_mb();
+ synchronize_irq(tp->pdev->irq);
+
/* do the reset */
val = GRC_MISC_CFG_CORECLK_RESET;
@@ -4904,6 +4923,8 @@ static int tg3_chip_reset(struct tg3 *tp)
pci_restore_state(tp->pdev);
+ tp->tg3_flags &= ~TG3_FLAG_CHIP_RESETTING;
+
/* Make sure PCI-X relaxed ordering bit is clear. */
pci_read_config_dword(tp->pdev, TG3PCI_X_CAPS, &val);
val &= ~PCIX_CAPS_RELAXED_ORDERING;
@@ -6321,8 +6342,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB |
RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
RDMAC_MODE_LNGREAD_ENAB);
- if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE)
- rdmac_mode |= RDMAC_MODE_SPLIT_ENABLE;
/* If statement applies to 5705 and 5750 PCI devices only */
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
@@ -6495,9 +6514,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
val &= ~(PCIX_CAPS_SPLIT_MASK | PCIX_CAPS_BURST_MASK);
val |= (PCIX_CAPS_MAX_BURST_CPIOB << PCIX_CAPS_BURST_SHIFT);
- if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE)
- val |= (tp->split_mode_max_reqs <<
- PCIX_CAPS_SPLIT_SHIFT);
}
tw32(TG3PCI_X_CAPS, val);
}
@@ -10863,14 +10879,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
grc_misc_cfg = tr32(GRC_MISC_CFG);
grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK;
- /* Broadcom's driver says that CIOBE multisplit has a bug */
-#if 0
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
- grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5704CIOBE) {
- tp->tg3_flags |= TG3_FLAG_SPLIT_MODE;
- tp->split_mode_max_reqs = SPLIT_MODE_5704_MAX_REQ;
- }
-#endif
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
(grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788 ||
grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M))
@@ -11968,14 +11976,12 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
i == 5 ? '\n' : ':');
printk(KERN_INFO "%s: RXcsums[%d] LinkChgREG[%d] "
- "MIirq[%d] ASF[%d] Split[%d] WireSpeed[%d] "
- "TSOcap[%d] \n",
+ "MIirq[%d] ASF[%d] WireSpeed[%d] TSOcap[%d]\n",
dev->name,
(tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0,
(tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0,
(tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) != 0,
(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0,
- (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) != 0,
(tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0,
(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0);
printk(KERN_INFO "%s: dma_rwctrl[%08x] dma_mask[%d-bit]\n",
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 086892d8c1f1..d515ed23841b 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2223,7 +2223,7 @@ struct tg3 {
#define TG3_FLAG_40BIT_DMA_BUG 0x08000000
#define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000
#define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000
-#define TG3_FLAG_SPLIT_MODE 0x40000000
+#define TG3_FLAG_CHIP_RESETTING 0x40000000
#define TG3_FLAG_INIT_COMPLETE 0x80000000
u32 tg3_flags2;
#define TG3_FLG2_RESTART_TIMER 0x00000001
@@ -2262,9 +2262,6 @@ struct tg3 {
#define TG3_FLG2_NO_FWARE_REPORTED 0x40000000
#define TG3_FLG2_PHY_ADJUST_TRIM 0x80000000
- u32 split_mode_max_reqs;
-#define SPLIT_MODE_5704_MAX_REQ 3
-
struct timer_list timer;
u16 timer_counter;
u16 timer_multiplier;
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
index 0d97e10ccac5..01d55315ee8c 100644
--- a/drivers/net/tokenring/ibmtr.c
+++ b/drivers/net/tokenring/ibmtr.c
@@ -186,7 +186,6 @@ static char __devinit *adapter_def(char type)
#define TRC_INITV 0x02 /* verbose init trace points */
static unsigned char ibmtr_debug_trace = 0;
-static int ibmtr_probe(struct net_device *dev);
static int ibmtr_probe1(struct net_device *dev, int ioaddr);
static unsigned char get_sram_size(struct tok_info *adapt_info);
static int trdev_init(struct net_device *dev);
@@ -335,17 +334,6 @@ static void ibmtr_cleanup_card(struct net_device *dev)
#endif
}
-int ibmtr_probe_card(struct net_device *dev)
-{
- int err = ibmtr_probe(dev);
- if (!err) {
- err = register_netdev(dev);
- if (err)
- ibmtr_cleanup_card(dev);
- }
- return err;
-}
-
/****************************************************************************
* ibmtr_probe(): Routine specified in the network device structure
* to probe for an IBM Token Ring Adapter. Routine outline:
@@ -358,7 +346,7 @@ int ibmtr_probe_card(struct net_device *dev)
* which references it.
****************************************************************************/
-static int ibmtr_probe(struct net_device *dev)
+static int __devinit ibmtr_probe(struct net_device *dev)
{
int i;
int base_addr = dev->base_addr;
@@ -378,6 +366,17 @@ static int ibmtr_probe(struct net_device *dev)
return -ENODEV;
}
+int __devinit ibmtr_probe_card(struct net_device *dev)
+{
+ int err = ibmtr_probe(dev);
+ if (!err) {
+ err = register_netdev(dev);
+ if (err)
+ ibmtr_cleanup_card(dev);
+ }
+ return err;
+}
+
/*****************************************************************************/
static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr)
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
index 24a29c99ba94..9aeac76184f3 100644
--- a/drivers/net/tulip/dmfe.c
+++ b/drivers/net/tulip/dmfe.c
@@ -190,13 +190,13 @@
/* Structure/enum declaration ------------------------------- */
struct tx_desc {
- u32 tdes0, tdes1, tdes2, tdes3; /* Data for the card */
+ __le32 tdes0, tdes1, tdes2, tdes3; /* Data for the card */
char *tx_buf_ptr; /* Data for us */
struct tx_desc *next_tx_desc;
} __attribute__(( aligned(32) ));
struct rx_desc {
- u32 rdes0, rdes1, rdes2, rdes3; /* Data for the card */
+ __le32 rdes0, rdes1, rdes2, rdes3; /* Data for the card */
struct sk_buff *rx_skb_ptr; /* Data for us */
struct rx_desc *next_rx_desc;
} __attribute__(( aligned(32) ));
@@ -458,7 +458,7 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
/* read 64 word srom data */
for (i = 0; i < 64; i++)
- ((u16 *) db->srom)[i] =
+ ((__le16 *) db->srom)[i] =
cpu_to_le16(read_srom_word(db->ioaddr, i));
/* Set Node address */
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index dab88b958d6e..639e1e6913bf 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -3607,7 +3607,6 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (bd == ugeth->confBd[txQ]) {
if (!netif_queue_stopped(dev))
netif_stop_queue(dev);
- return NETDEV_TX_BUSY;
}
ugeth->txBd[txQ] = bd;
@@ -3623,7 +3622,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irq(&ugeth->lock);
- return NETDEV_TX_OK;
+ return 0;
}
static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit)
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index ebbda1d8f542..f3a972e74e9a 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -30,8 +30,8 @@
*/
#define DRV_NAME "via-rhine"
-#define DRV_VERSION "1.4.2"
-#define DRV_RELDATE "Sept-11-2006"
+#define DRV_VERSION "1.4.3"
+#define DRV_RELDATE "2007-03-06"
/* A few user-configurable values.
@@ -105,6 +105,7 @@ static const int multicast_filter_limit = 32;
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
+#include <linux/dmi.h>
/* These identify the driver base version and may not be removed. */
static char version[] __devinitdata =
@@ -1995,6 +1996,23 @@ static struct pci_driver rhine_driver = {
.shutdown = rhine_shutdown,
};
+static struct dmi_system_id __initdata rhine_dmi_table[] = {
+ {
+ .ident = "EPIA-M",
+ .matches = {
+ DMI_MATCH(DMI_BIOS_VENDOR, "Award Software International, Inc."),
+ DMI_MATCH(DMI_BIOS_VERSION, "6.00 PG"),
+ },
+ },
+ {
+ .ident = "KV7",
+ .matches = {
+ DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"),
+ DMI_MATCH(DMI_BIOS_VERSION, "6.00 PG"),
+ },
+ },
+ { NULL }
+};
static int __init rhine_init(void)
{
@@ -2002,6 +2020,16 @@ static int __init rhine_init(void)
#ifdef MODULE
printk(version);
#endif
+ if (dmi_check_system(rhine_dmi_table)) {
+ /* these BIOSes fail at PXE boot if chip is in D3 */
+ avoid_D3 = 1;
+ printk(KERN_WARNING "%s: Broken BIOS detected, avoid_D3 "
+ "enabled.\n",
+ DRV_NAME);
+ }
+ else if (avoid_D3)
+ printk(KERN_INFO "%s: avoid_D3 set.\n", DRV_NAME);
+
return pci_register_driver(&rhine_driver);
}
diff --git a/drivers/net/wan/lmc/lmc_media.h b/drivers/net/wan/lmc/lmc_media.h
deleted file mode 100644
index ddcc00403563..000000000000
--- a/drivers/net/wan/lmc/lmc_media.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef _LMC_MEDIA_H_
-#define _LMC_MEDIA_H_
-
-lmc_media_t lmc_ds3_media = {
- lmc_ds3_init, /* special media init stuff */
- lmc_ds3_default, /* reset to default state */
- lmc_ds3_set_status, /* reset status to state provided */
- lmc_dummy_set_1, /* set clock source */
- lmc_dummy_set2_1, /* set line speed */
- lmc_ds3_set_100ft, /* set cable length */
- lmc_ds3_set_scram, /* set scrambler */
- lmc_ds3_get_link_status, /* get link status */
- lmc_dummy_set_1, /* set link status */
- lmc_ds3_set_crc_length, /* set CRC length */
- lmc_dummy_set_1, /* set T1 or E1 circuit type */
- lmc_ds3_watchdog
-};
-
-lmc_media_t lmc_hssi_media = {
- lmc_hssi_init, /* special media init stuff */
- lmc_hssi_default, /* reset to default state */
- lmc_hssi_set_status, /* reset status to state provided */
- lmc_hssi_set_clock, /* set clock source */
- lmc_dummy_set2_1, /* set line speed */
- lmc_dummy_set_1, /* set cable length */
- lmc_dummy_set_1, /* set scrambler */
- lmc_hssi_get_link_status, /* get link status */
- lmc_hssi_set_link_status, /* set link status */
- lmc_hssi_set_crc_length, /* set CRC length */
- lmc_dummy_set_1, /* set T1 or E1 circuit type */
- lmc_hssi_watchdog
-};
-
-lmc_media_t lmc_ssi_media = { lmc_ssi_init, /* special media init stuff */
- lmc_ssi_default, /* reset to default state */
- lmc_ssi_set_status, /* reset status to state provided */
- lmc_ssi_set_clock, /* set clock source */
- lmc_ssi_set_speed, /* set line speed */
- lmc_dummy_set_1, /* set cable length */
- lmc_dummy_set_1, /* set scrambler */
- lmc_ssi_get_link_status, /* get link status */
- lmc_ssi_set_link_status, /* set link status */
- lmc_ssi_set_crc_length, /* set CRC length */
- lmc_dummy_set_1, /* set T1 or E1 circuit type */
- lmc_ssi_watchdog
-};
-
-lmc_media_t lmc_t1_media = {
- lmc_t1_init, /* special media init stuff */
- lmc_t1_default, /* reset to default state */
- lmc_t1_set_status, /* reset status to state provided */
- lmc_t1_set_clock, /* set clock source */
- lmc_dummy_set2_1, /* set line speed */
- lmc_dummy_set_1, /* set cable length */
- lmc_dummy_set_1, /* set scrambler */
- lmc_t1_get_link_status, /* get link status */
- lmc_dummy_set_1, /* set link status */
- lmc_t1_set_crc_length, /* set CRC length */
- lmc_t1_set_circuit_type, /* set T1 or E1 circuit type */
- lmc_t1_watchdog
-};
-
-
-#endif
-
diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c
index 8dbcf83bb5f3..8b4540bfc1b0 100644
--- a/drivers/net/wan/z85230.c
+++ b/drivers/net/wan/z85230.c
@@ -407,7 +407,7 @@ static void z8530_tx(struct z8530_channel *c)
while(c->txcount) {
/* FIFO full ? */
if(!(read_zsreg(c, R0)&4))
- break;
+ return;
c->txcount--;
/*
* Shovel out the byte
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index a8c2bfe26c27..2ada76a93cb6 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -2852,7 +2852,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
if (rc) {
airo_print_err(dev->name, "register interrupt %d failed, rc %d",
irq, rc);
- goto err_out_unlink;
+ goto err_out_nets;
}
if (!is_pcmcia) {
if (!request_region( dev->base_addr, 64, dev->name )) {
@@ -2935,6 +2935,8 @@ err_out_res:
release_region( dev->base_addr, 64 );
err_out_irq:
free_irq(dev->irq, dev);
+err_out_nets:
+ airo_networks_free(ai);
err_out_unlink:
del_airo_dev(dev);
err_out_thr:
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index e594af46ff05..a38e7eec0e62 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -946,6 +946,7 @@ static int bcm43xx_geo_init(struct bcm43xx_private *bcm)
u8 channel;
struct bcm43xx_phyinfo *phy;
const char *iso_country;
+ u8 max_bg_channel;
geo = kzalloc(sizeof(*geo), GFP_KERNEL);
if (!geo)
@@ -967,6 +968,23 @@ static int bcm43xx_geo_init(struct bcm43xx_private *bcm)
}
iso_country = bcm43xx_locale_iso(bcm->sprom.locale);
+/* set the maximum channel based on locale set in sprom or witle locale option */
+ switch (bcm->sprom.locale) {
+ case BCM43xx_LOCALE_THAILAND:
+ case BCM43xx_LOCALE_ISRAEL:
+ case BCM43xx_LOCALE_JORDAN:
+ case BCM43xx_LOCALE_USA_CANADA_ANZ:
+ case BCM43xx_LOCALE_USA_LOW:
+ max_bg_channel = 11;
+ break;
+ case BCM43xx_LOCALE_JAPAN:
+ case BCM43xx_LOCALE_JAPAN_HIGH:
+ max_bg_channel = 14;
+ break;
+ default:
+ max_bg_channel = 13;
+ }
+
if (have_a) {
for (i = 0, channel = IEEE80211_52GHZ_MIN_CHANNEL;
channel <= IEEE80211_52GHZ_MAX_CHANNEL; channel++) {
@@ -978,7 +996,7 @@ static int bcm43xx_geo_init(struct bcm43xx_private *bcm)
}
if (have_bg) {
for (i = 0, channel = IEEE80211_24GHZ_MIN_CHANNEL;
- channel <= IEEE80211_24GHZ_MAX_CHANNEL; channel++) {
+ channel <= max_bg_channel; channel++) {
chan = &geo->bg[i++];
chan->freq = bcm43xx_channel_to_freq_bg(channel);
chan->channel = channel;
@@ -1858,9 +1876,6 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id)
spin_lock(&bcm->irq_lock);
- assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
- assert(bcm->current_core->id == BCM43xx_COREID_80211);
-
reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
if (reason == 0xffffffff) {
/* irq not for us (shared irq) */
@@ -1871,6 +1886,9 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id)
if (!reason)
goto out;
+ assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
+ assert(bcm->current_core->id == BCM43xx_COREID_80211);
+
bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA0_REASON)
& 0x0001DC00;
bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
index 3a5c9c2b2150..72529a440f15 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
@@ -757,7 +757,7 @@ static void bcm43xx_phy_initb5(struct bcm43xx_private *bcm)
if (radio->version == 0x2050)
bcm43xx_phy_write(bcm, 0x0038, 0x0667);
- if (phy->type == BCM43xx_PHYTYPE_G) {
+ if (phy->connected) {
if (radio->version == 0x2050) {
bcm43xx_radio_write16(bcm, 0x007A,
bcm43xx_radio_read16(bcm, 0x007A)
@@ -859,6 +859,11 @@ static void bcm43xx_phy_initb6(struct bcm43xx_private *bcm)
bcm43xx_radio_write16(bcm, 0x005D, 0x0088);
bcm43xx_radio_write16(bcm, 0x005E, 0x0088);
bcm43xx_radio_write16(bcm, 0x007D, 0x0088);
+ bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
+ BCM43xx_UCODEFLAGS_OFFSET,
+ (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
+ BCM43xx_UCODEFLAGS_OFFSET)
+ | 0x00000200));
}
if (radio->revision == 8) {
bcm43xx_radio_write16(bcm, 0x0051, 0x0000);
@@ -941,7 +946,8 @@ static void bcm43xx_phy_initb6(struct bcm43xx_private *bcm)
bcm43xx_phy_write(bcm, 0x0038, 0x0668);
bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF);
if (radio->revision <= 5)
- bcm43xx_phy_write(bcm, 0x005D, bcm43xx_phy_read(bcm, 0x005D) | 0x0003);
+ bcm43xx_phy_write(bcm, 0x005D, (bcm43xx_phy_read(bcm, 0x005D)
+ & 0xFF80) | 0x0003);
if (radio->revision <= 2)
bcm43xx_radio_write16(bcm, 0x005D, 0x000D);
@@ -958,7 +964,7 @@ static void bcm43xx_phy_initb6(struct bcm43xx_private *bcm)
bcm43xx_phy_write(bcm, 0x0016, 0x0410);
bcm43xx_phy_write(bcm, 0x0017, 0x0820);
bcm43xx_phy_write(bcm, 0x0062, 0x0007);
- (void) bcm43xx_radio_calibrationvalue(bcm);
+ bcm43xx_radio_init2050(bcm);
bcm43xx_phy_lo_g_measure(bcm);
if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {
bcm43xx_calc_nrssi_slope(bcm);
@@ -972,7 +978,7 @@ static void bcm43xx_calc_loopback_gain(struct bcm43xx_private *bcm)
{
struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u16 backup_phy[15];
+ u16 backup_phy[15] = {0};
u16 backup_radio[3];
u16 backup_bband;
u16 i;
@@ -983,8 +989,10 @@ static void bcm43xx_calc_loopback_gain(struct bcm43xx_private *bcm)
backup_phy[1] = bcm43xx_phy_read(bcm, 0x0001);
backup_phy[2] = bcm43xx_phy_read(bcm, 0x0811);
backup_phy[3] = bcm43xx_phy_read(bcm, 0x0812);
- backup_phy[4] = bcm43xx_phy_read(bcm, 0x0814);
- backup_phy[5] = bcm43xx_phy_read(bcm, 0x0815);
+ if (phy->rev != 1) {
+ backup_phy[4] = bcm43xx_phy_read(bcm, 0x0814);
+ backup_phy[5] = bcm43xx_phy_read(bcm, 0x0815);
+ }
backup_phy[6] = bcm43xx_phy_read(bcm, 0x005A);
backup_phy[7] = bcm43xx_phy_read(bcm, 0x0059);
backup_phy[8] = bcm43xx_phy_read(bcm, 0x0058);
@@ -1012,14 +1020,16 @@ static void bcm43xx_calc_loopback_gain(struct bcm43xx_private *bcm)
bcm43xx_phy_read(bcm, 0x0811) | 0x0001);
bcm43xx_phy_write(bcm, 0x0812,
bcm43xx_phy_read(bcm, 0x0812) & 0xFFFE);
- bcm43xx_phy_write(bcm, 0x0814,
- bcm43xx_phy_read(bcm, 0x0814) | 0x0001);
- bcm43xx_phy_write(bcm, 0x0815,
- bcm43xx_phy_read(bcm, 0x0815) & 0xFFFE);
- bcm43xx_phy_write(bcm, 0x0814,
- bcm43xx_phy_read(bcm, 0x0814) | 0x0002);
- bcm43xx_phy_write(bcm, 0x0815,
- bcm43xx_phy_read(bcm, 0x0815) & 0xFFFD);
+ if (phy->rev != 1) {
+ bcm43xx_phy_write(bcm, 0x0814,
+ bcm43xx_phy_read(bcm, 0x0814) | 0x0001);
+ bcm43xx_phy_write(bcm, 0x0815,
+ bcm43xx_phy_read(bcm, 0x0815) & 0xFFFE);
+ bcm43xx_phy_write(bcm, 0x0814,
+ bcm43xx_phy_read(bcm, 0x0814) | 0x0002);
+ bcm43xx_phy_write(bcm, 0x0815,
+ bcm43xx_phy_read(bcm, 0x0815) & 0xFFFD);
+ }
bcm43xx_phy_write(bcm, 0x0811,
bcm43xx_phy_read(bcm, 0x0811) | 0x000C);
bcm43xx_phy_write(bcm, 0x0812,
@@ -1042,10 +1052,12 @@ static void bcm43xx_calc_loopback_gain(struct bcm43xx_private *bcm)
bcm43xx_phy_read(bcm, 0x000A)
| 0x2000);
}
- bcm43xx_phy_write(bcm, 0x0814,
- bcm43xx_phy_read(bcm, 0x0814) | 0x0004);
- bcm43xx_phy_write(bcm, 0x0815,
- bcm43xx_phy_read(bcm, 0x0815) & 0xFFFB);
+ if (phy->rev != 1) {
+ bcm43xx_phy_write(bcm, 0x0814,
+ bcm43xx_phy_read(bcm, 0x0814) | 0x0004);
+ bcm43xx_phy_write(bcm, 0x0815,
+ bcm43xx_phy_read(bcm, 0x0815) & 0xFFFB);
+ }
bcm43xx_phy_write(bcm, 0x0003,
(bcm43xx_phy_read(bcm, 0x0003)
& 0xFF9F) | 0x0040);
@@ -1132,8 +1144,10 @@ static void bcm43xx_calc_loopback_gain(struct bcm43xx_private *bcm)
}
}
- bcm43xx_phy_write(bcm, 0x0814, backup_phy[4]);
- bcm43xx_phy_write(bcm, 0x0815, backup_phy[5]);
+ if (phy->rev != 1) {
+ bcm43xx_phy_write(bcm, 0x0814, backup_phy[4]);
+ bcm43xx_phy_write(bcm, 0x0815, backup_phy[5]);
+ }
bcm43xx_phy_write(bcm, 0x005A, backup_phy[6]);
bcm43xx_phy_write(bcm, 0x0059, backup_phy[7]);
bcm43xx_phy_write(bcm, 0x0058, backup_phy[8]);
@@ -1182,24 +1196,23 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
bcm43xx_phy_write(bcm, 0x0811, 0x0000);
bcm43xx_phy_write(bcm, 0x0015, 0x00C0);
}
- if (phy->rev >= 3) {
+ if (phy->rev > 5) {
bcm43xx_phy_write(bcm, 0x0811, 0x0400);
bcm43xx_phy_write(bcm, 0x0015, 0x00C0);
}
- if (phy->connected) {
+ if (phy->rev >= 2 && phy->connected) {
tmp = bcm43xx_phy_read(bcm, 0x0400) & 0xFF;
- if (tmp < 6) {
+ if (tmp ==3 || tmp == 5) {
bcm43xx_phy_write(bcm, 0x04C2, 0x1816);
bcm43xx_phy_write(bcm, 0x04C3, 0x8006);
- if (tmp != 3) {
+ if (tmp == 5) {
bcm43xx_phy_write(bcm, 0x04CC,
(bcm43xx_phy_read(bcm, 0x04CC)
& 0x00FF) | 0x1F00);
}
}
- }
- if (phy->rev < 3 && phy->connected)
bcm43xx_phy_write(bcm, 0x047E, 0x0078);
+ }
if (radio->revision == 8) {
bcm43xx_phy_write(bcm, 0x0801, bcm43xx_phy_read(bcm, 0x0801) | 0x0080);
bcm43xx_phy_write(bcm, 0x043E, bcm43xx_phy_read(bcm, 0x043E) | 0x0004);
@@ -1226,7 +1239,7 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
if (phy->rev >= 6) {
bcm43xx_phy_write(bcm, 0x0036,
(bcm43xx_phy_read(bcm, 0x0036)
- & 0xF000) | (radio->txctl2 << 12));
+ & 0x0FFF) | (radio->txctl2 << 12));
}
if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL)
bcm43xx_phy_write(bcm, 0x002E, 0x8075);
@@ -1237,7 +1250,7 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
else
bcm43xx_phy_write(bcm, 0x002F, 0x0202);
}
- if (phy->connected) {
+ if (phy->connected || phy->rev >= 2) {
bcm43xx_phy_lo_adjust(bcm, 0);
bcm43xx_phy_write(bcm, 0x080F, 0x8078);
}
@@ -1251,7 +1264,7 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
*/
bcm43xx_nrssi_hw_update(bcm, 0xFFFF);
bcm43xx_calc_nrssi_threshold(bcm);
- } else if (phy->connected) {
+ } else if (phy->connected || phy->rev >= 2) {
if (radio->nrssi[0] == -1000) {
assert(radio->nrssi[1] == -1000);
bcm43xx_calc_nrssi_slope(bcm);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
index 32beb91b7164..4025dd0089d2 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
@@ -458,7 +458,7 @@ static void bcm43xx_calc_nrssi_offset(struct bcm43xx_private *bcm)
bcm43xx_phy_write(bcm, 0x005A, 0x0480);
bcm43xx_phy_write(bcm, 0x0059, 0x0810);
bcm43xx_phy_write(bcm, 0x0058, 0x000D);
- if (phy->rev == 0) {
+ if (phy->analog == 0) {
bcm43xx_phy_write(bcm, 0x0003, 0x0122);
} else {
bcm43xx_phy_write(bcm, 0x000A,
@@ -570,9 +570,9 @@ void bcm43xx_calc_nrssi_slope(struct bcm43xx_private *bcm)
nrssi0 = (s16)bcm43xx_phy_read(bcm, 0x0027);
bcm43xx_radio_write16(bcm, 0x007A,
bcm43xx_radio_read16(bcm, 0x007A) & 0x007F);
- if (phy->rev >= 2) {
+ if (phy->analog >= 2) {
bcm43xx_write16(bcm, 0x03E6, 0x0040);
- } else if (phy->rev == 0) {
+ } else if (phy->analog == 0) {
bcm43xx_write16(bcm, 0x03E6, 0x0122);
} else {
bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT,
@@ -596,7 +596,7 @@ void bcm43xx_calc_nrssi_slope(struct bcm43xx_private *bcm)
bcm43xx_phy_write(bcm, 0x0015, backup[5]);
bcm43xx_phy_write(bcm, 0x002A, backup[6]);
bcm43xx_synth_pu_workaround(bcm, radio->channel);
- if (phy->rev != 0)
+ if (phy->analog != 0)
bcm43xx_write16(bcm, 0x03F4, backup[13]);
bcm43xx_phy_write(bcm, 0x0020, backup[7]);
@@ -692,7 +692,7 @@ void bcm43xx_calc_nrssi_slope(struct bcm43xx_private *bcm)
bcm43xx_radio_write16(bcm, 0x007A,
bcm43xx_radio_read16(bcm, 0x007A) & 0x007F);
- if (phy->rev >= 2) {
+ if (phy->analog >= 2) {
bcm43xx_phy_write(bcm, 0x0003,
(bcm43xx_phy_read(bcm, 0x0003)
& 0xFF9F) | 0x0040);
@@ -882,10 +882,10 @@ static void _stack_save(u32 *_stackptr, size_t *stackidx,
{
u32 *stackptr = &(_stackptr[*stackidx]);
- assert((offset & 0xF000) == 0x0000);
- assert((id & 0xF0) == 0x00);
+ assert((offset & 0xE000) == 0x0000);
+ assert((id & 0xF8) == 0x00);
*stackptr = offset;
- *stackptr |= ((u32)id) << 12;
+ *stackptr |= ((u32)id) << 13;
*stackptr |= ((u32)value) << 16;
(*stackidx)++;
assert(*stackidx < BCM43xx_INTERFSTACK_SIZE);
@@ -896,12 +896,12 @@ static u16 _stack_restore(u32 *stackptr,
{
size_t i;
- assert((offset & 0xF000) == 0x0000);
- assert((id & 0xF0) == 0x00);
+ assert((offset & 0xE000) == 0x0000);
+ assert((id & 0xF8) == 0x00);
for (i = 0; i < BCM43xx_INTERFSTACK_SIZE; i++, stackptr++) {
- if ((*stackptr & 0x00000FFF) != offset)
+ if ((*stackptr & 0x00001FFF) != offset)
continue;
- if (((*stackptr & 0x0000F000) >> 12) != id)
+ if (((*stackptr & 0x00007000) >> 13) != id)
continue;
return ((*stackptr & 0xFFFF0000) >> 16);
}
@@ -1579,7 +1579,7 @@ void bcm43xx_radio_set_tx_iq(struct bcm43xx_private *bcm)
for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++) {
- if (tmp == (data_high[i] << 4 | data_low[j])) {
+ if (tmp == (data_high[i] | data_low[j])) {
bcm43xx_phy_write(bcm, 0x0069, (i - j) << 8 | 0x00C0);
return;
}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
index 7b665e2386a8..d6d9413d7f23 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
@@ -105,18 +105,24 @@ static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev,
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
unsigned long flags;
u8 channel;
+ s8 expon;
int freq;
int err = -EINVAL;
mutex_lock(&bcm->mutex);
spin_lock_irqsave(&bcm->irq_lock, flags);
- if ((data->freq.m >= 0) && (data->freq.m <= 1000)) {
+ if ((data->freq.e == 0) &&
+ (data->freq.m >= 0) && (data->freq.m <= 1000)) {
channel = data->freq.m;
freq = bcm43xx_channel_to_freq(bcm, channel);
} else {
- channel = bcm43xx_freq_to_channel(bcm, data->freq.m);
freq = data->freq.m;
+ expon = 6 - data->freq.e;
+ while (--expon >= 0) /* scale down the frequency to MHz */
+ freq /= 10;
+ assert(freq > 1000);
+ channel = bcm43xx_freq_to_channel(bcm, freq);
}
if (!ieee80211_is_valid_channel(bcm->ieee, channel))
goto out_unlock;
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index 9c64f894b71b..87ee3ee020fe 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -337,6 +337,7 @@ static int read_pod(struct zd_chip *chip, u8 *rf_type)
chip->patch_cr157 = (value >> 13) & 0x1;
chip->patch_6m_band_edge = (value >> 21) & 0x1;
chip->new_phy_layout = (value >> 31) & 0x1;
+ chip->al2230s_bit = (value >> 7) & 0x1;
chip->link_led = ((value >> 4) & 1) ? LED1 : LED2;
chip->supports_tx_led = 1;
if (value & (1 << 24)) { /* LED scenario */
@@ -591,16 +592,16 @@ int zd_chip_unlock_phy_regs(struct zd_chip *chip)
return r;
}
-/* CR157 can be optionally patched by the EEPROM */
+/* CR157 can be optionally patched by the EEPROM for original ZD1211 */
static int patch_cr157(struct zd_chip *chip)
{
int r;
- u32 value;
+ u16 value;
if (!chip->patch_cr157)
return 0;
- r = zd_ioread32_locked(chip, &value, E2P_PHY_REG);
+ r = zd_ioread16_locked(chip, &value, E2P_PHY_REG);
if (r)
return r;
@@ -790,11 +791,6 @@ static int zd1211b_hw_reset_phy(struct zd_chip *chip)
goto out;
r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
- if (r)
- goto unlock;
-
- r = patch_cr157(chip);
-unlock:
t = zd_chip_unlock_phy_regs(chip);
if (t && !r)
r = t;
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index b07569e391ee..e57ed75d9425 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -641,8 +641,8 @@ enum {
* also only 11 channels. */
#define E2P_ALLOWED_CHANNEL E2P_DATA(0x18)
-#define E2P_PHY_REG E2P_DATA(0x1a)
#define E2P_DEVICE_VER E2P_DATA(0x20)
+#define E2P_PHY_REG E2P_DATA(0x25)
#define E2P_36M_CAL_VALUE1 E2P_DATA(0x28)
#define E2P_36M_CAL_VALUE2 E2P_DATA(0x2a)
#define E2P_36M_CAL_VALUE3 E2P_DATA(0x2c)
@@ -711,7 +711,7 @@ struct zd_chip {
u16 link_led;
unsigned int pa_type:4,
patch_cck_gain:1, patch_cr157:1, patch_6m_band_edge:1,
- new_phy_layout:1,
+ new_phy_layout:1, al2230s_bit:1,
is_zd1211b:1, supports_tx_led:1;
};
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
index 25323a13a3db..5235a7827ac5 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
@@ -358,6 +358,12 @@ int zd_rf_init_al2230(struct zd_rf *rf)
{
struct zd_chip *chip = zd_rf_to_chip(rf);
+ if (chip->al2230s_bit) {
+ dev_err(zd_chip_dev(chip), "AL2230S devices are not yet "
+ "supported by this driver.\n");
+ return -ENODEV;
+ }
+
rf->switch_radio_off = al2230_switch_radio_off;
if (chip->is_zd1211b) {
rf->init_hw = zd1211b_al2230_init_hw;
OpenPOWER on IntegriCloud