Commit 0ab602e5 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6

* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6:
  [netdrvr] ewrk3: correct card detection bug
  cxgb3 - fix white spaces in drivers/net/Kconfig
  myri10ge: update driver version to 1.3.0-1.226
  myri10ge: fix management of >4kB allocated pages
  myri10ge: update wcfifo and intr_coal_delay default values
  myri10ge: Serverworks HT2100 provides aligned PCIe completion
  mv643xx_eth: add mv643xx_eth_shutdown function
  SAA9730: Fix large pile of warnings
  Revert "ucc_geth: returns NETDEV_TX_BUSY when BD ring is full"
  cxgb3 - T3B2 pcie config space
  cxgb3 - Fix potential MAC hang
  cxgb3 - Auto-load FW if mismatch detected
  cxgb3 - fix ethtool cmd on multiple queues port
  Fix return code in pci-skeleton.c
  skge: use per-port phy locking
  skge: mask irqs when device down
  skge: deadlock on tx timeout
  [PATCH] airo: Fix an error path memory leak
  [PATCH] bcm43xx: MANUALWLAN fixes
parents 105fd108 991b5557
...@@ -2372,22 +2372,23 @@ config CHELSIO_T1_NAPI ...@@ -2372,22 +2372,23 @@ config CHELSIO_T1_NAPI
when the driver is receiving lots of packets from the card. when the driver is receiving lots of packets from the card.
config CHELSIO_T3 config CHELSIO_T3
tristate "Chelsio Communications T3 10Gb Ethernet support" tristate "Chelsio Communications T3 10Gb Ethernet support"
depends on PCI depends on PCI
help select FW_LOADER
This driver supports Chelsio T3-based gigabit and 10Gb Ethernet help
adapters. This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
adapters.
For general information about Chelsio and our products, visit For general information about Chelsio and our products, visit
our website at <http://www.chelsio.com>. our website at <http://www.chelsio.com>.
For customer support, please visit our customer support page at For customer support, please visit our customer support page at
<http://www.chelsio.com/support.htm>. <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 To compile this driver as a module, choose M here: the module
will be called cxgb3. will be called cxgb3.
config EHEA config EHEA
tristate "eHEA Ethernet support" tristate "eHEA Ethernet support"
......
...@@ -260,6 +260,10 @@ struct mac_stats { ...@@ -260,6 +260,10 @@ struct mac_stats {
unsigned long serdes_signal_loss; unsigned long serdes_signal_loss;
unsigned long xaui_pcs_ctc_err; unsigned long xaui_pcs_ctc_err;
unsigned long xaui_pcs_align_change; 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 { struct tp_mib_stats {
...@@ -400,6 +404,12 @@ struct adapter_params { ...@@ -400,6 +404,12 @@ struct adapter_params {
unsigned int rev; /* chip revision */ unsigned int rev; /* chip revision */
}; };
enum { /* chip revisions */
T3_REV_A = 0,
T3_REV_B = 2,
T3_REV_B2 = 3,
};
struct trace_params { struct trace_params {
u32 sip; u32 sip;
u32 sip_mask; u32 sip_mask;
...@@ -465,6 +475,10 @@ struct cmac { ...@@ -465,6 +475,10 @@ struct cmac {
struct adapter *adapter; struct adapter *adapter;
unsigned int offset; unsigned int offset;
unsigned int nucast; /* # of address filters for unicast MACs */ unsigned int nucast; /* # of address filters for unicast MACs */
unsigned int tcnt;
unsigned int xcnt;
unsigned int toggle_cnt;
unsigned int txen;
struct mac_stats stats; struct mac_stats stats;
}; };
...@@ -666,6 +680,7 @@ int t3_mac_set_address(struct cmac *mac, unsigned int idx, u8 addr[6]); ...@@ -666,6 +680,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); int t3_mac_set_num_ucast(struct cmac *mac, int n);
const struct mac_stats *t3_mac_update_stats(struct cmac *mac); 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 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); 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, int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters,
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <linux/firmware.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "common.h" #include "common.h"
...@@ -707,6 +708,28 @@ static void bind_qsets(struct adapter *adap) ...@@ -707,6 +708,28 @@ static void bind_qsets(struct adapter *adap)
} }
} }
#define FW_FNAME "t3fw-%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);
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 * cxgb_up - enable the adapter
* @adapter: adapter being enabled * @adapter: adapter being enabled
...@@ -723,6 +746,8 @@ static int cxgb_up(struct adapter *adap) ...@@ -723,6 +746,8 @@ static int cxgb_up(struct adapter *adap)
if (!(adap->flags & FULL_INIT_DONE)) { if (!(adap->flags & FULL_INIT_DONE)) {
err = t3_check_fw_version(adap); err = t3_check_fw_version(adap);
if (err == -EINVAL)
err = upgrade_fw(adap);
if (err) if (err)
goto out; goto out;
...@@ -1031,7 +1056,11 @@ static char stats_strings[][ETH_GSTRING_LEN] = { ...@@ -1031,7 +1056,11 @@ static char stats_strings[][ETH_GSTRING_LEN] = {
"VLANinsertions ", "VLANinsertions ",
"TxCsumOffload ", "TxCsumOffload ",
"RxCsumGood ", "RxCsumGood ",
"RxDrops " "RxDrops ",
"CheckTXEnToggled ",
"CheckResets ",
}; };
static int get_stats_count(struct net_device *dev) static int get_stats_count(struct net_device *dev)
...@@ -1145,6 +1174,9 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats, ...@@ -1145,6 +1174,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_TX_CSUM);
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_RX_CSUM_GOOD); *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_RX_CSUM_GOOD);
*data++ = s->rx_cong_drops; *data++ = s->rx_cong_drops;
*data++ = s->num_toggled;
*data++ = s->num_resets;
} }
static inline void reg_block_dump(struct adapter *ap, void *buf, static inline void reg_block_dump(struct adapter *ap, void *buf,
...@@ -1362,23 +1394,27 @@ static int set_rx_csum(struct net_device *dev, u32 data) ...@@ -1362,23 +1394,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) 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_max_pending = MAX_RX_BUFFERS;
e->rx_mini_max_pending = 0; e->rx_mini_max_pending = 0;
e->rx_jumbo_max_pending = MAX_RX_JUMBO_BUFFERS; e->rx_jumbo_max_pending = MAX_RX_JUMBO_BUFFERS;
e->tx_max_pending = MAX_TXQ_ENTRIES; e->tx_max_pending = MAX_TXQ_ENTRIES;
e->rx_pending = adapter->params.sge.qset[0].fl_size; e->rx_pending = q->fl_size;
e->rx_mini_pending = adapter->params.sge.qset[0].rspq_size; e->rx_mini_pending = q->rspq_size;
e->rx_jumbo_pending = adapter->params.sge.qset[0].jumbo_size; e->rx_jumbo_pending = q->jumbo_size;
e->tx_pending = adapter->params.sge.qset[0].txq_size[0]; e->tx_pending = q->txq_size[0];
} }
static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e) static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
{ {
int i; int i;
struct qset_params *q;
struct adapter *adapter = dev->priv; struct adapter *adapter = dev->priv;
const struct port_info *pi = netdev_priv(dev);
if (e->rx_pending > MAX_RX_BUFFERS || if (e->rx_pending > MAX_RX_BUFFERS ||
e->rx_jumbo_pending > MAX_RX_JUMBO_BUFFERS || e->rx_jumbo_pending > MAX_RX_JUMBO_BUFFERS ||
...@@ -1393,9 +1429,8 @@ static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e) ...@@ -1393,9 +1429,8 @@ static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
if (adapter->flags & FULL_INIT_DONE) if (adapter->flags & FULL_INIT_DONE)
return -EBUSY; return -EBUSY;
for (i = 0; i < SGE_QSETS; ++i) { q = &adapter->params.sge.qset[pi->first_qset];
struct qset_params *q = &adapter->params.sge.qset[i]; for (i = 0; i < pi->nqsets; ++i, ++q) {
q->rspq_size = e->rx_mini_pending; q->rspq_size = e->rx_mini_pending;
q->fl_size = e->rx_pending; q->fl_size = e->rx_pending;
q->jumbo_size = e->rx_jumbo_pending; q->jumbo_size = e->rx_jumbo_pending;
...@@ -2067,6 +2102,40 @@ static void check_link_status(struct adapter *adapter) ...@@ -2067,6 +2102,40 @@ static void check_link_status(struct adapter *adapter)
} }
} }
static void check_t3b2_mac(struct adapter *adapter)
{
int i;
rtnl_lock(); /* synchronize with ifdown */
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))
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) static void t3_adap_check_task(struct work_struct *work)
{ {
struct adapter *adapter = container_of(work, struct adapter, struct adapter *adapter = container_of(work, struct adapter,
...@@ -2087,6 +2156,9 @@ static void t3_adap_check_task(struct work_struct *work) ...@@ -2087,6 +2156,9 @@ static void t3_adap_check_task(struct work_struct *work)
adapter->check_task_cnt = 0; 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. */ /* Schedule the next check update if any port is active. */
spin_lock(&adapter->work_lock); spin_lock(&adapter->work_lock);
if (adapter->open_device_map & PORT_MASK) if (adapter->open_device_map & PORT_MASK)
......
...@@ -1206,6 +1206,14 @@ ...@@ -1206,6 +1206,14 @@
#define A_TP_RX_TRC_KEY0 0x120 #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 A_ULPRX_CTL 0x500
#define S_ROUND_ROBIN 4 #define S_ROUND_ROBIN 4
...@@ -1834,6 +1842,8 @@ ...@@ -1834,6 +1842,8 @@
#define V_TXPAUSEEN(x) ((x) << S_TXPAUSEEN) #define V_TXPAUSEEN(x) ((x) << S_TXPAUSEEN)
#define F_TXPAUSEEN V_TXPAUSEEN(1U) #define F_TXPAUSEEN V_TXPAUSEEN(1U)
#define A_XGM_TX_PAUSE_QUANTA 0x808
#define A_XGM_RX_CTRL 0x80c #define A_XGM_RX_CTRL 0x80c
#define S_RXEN 0 #define S_RXEN 0
...@@ -1920,6 +1930,11 @@ ...@@ -1920,6 +1930,11 @@
#define A_XGM_TXFIFO_CFG 0x888 #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 S_TXFIFOTHRESH 4
#define M_TXFIFOTHRESH 0x1ff #define M_TXFIFOTHRESH 0x1ff
...@@ -2190,6 +2205,13 @@ ...@@ -2190,6 +2205,13 @@
#define A_XGM_RX_MAX_PKT_SIZE_ERR_CNT 0x9a4 #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 A_XGM_RX_SPI4_SOP_EOP_CNT 0x9ac
#define XGMAC0_1_BASE_ADDR 0xa00 #define XGMAC0_1_BASE_ADDR 0xa00
...@@ -681,7 +681,8 @@ enum { ...@@ -681,7 +681,8 @@ enum {
SF_ERASE_SECTOR = 0xd8, /* erase sector */ SF_ERASE_SECTOR = 0xd8, /* erase sector */
FW_FLASH_BOOT_ADDR = 0x70000, /* start address of FW in flash */ 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) ...@@ -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; const u32 *p = (const u32 *)fw_data;
int ret, addr, fw_sector = FW_FLASH_BOOT_ADDR >> 16; int ret, addr, fw_sector = FW_FLASH_BOOT_ADDR >> 16;
if (size & 3) if ((size & 3) || size < FW_MIN_SIZE)
return -EINVAL; return -EINVAL;
if (size > FW_VERS_ADDR + 8 - FW_FLASH_BOOT_ADDR) if (size > FW_VERS_ADDR + 8 - FW_FLASH_BOOT_ADDR)
return -EFBIG; return -EFBIG;
...@@ -3243,15 +3244,17 @@ void early_hw_init(struct adapter *adapter, const struct adapter_info *ai) ...@@ -3243,15 +3244,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. * ones don't.
*/ */
int t3_reset_adapter(struct adapter *adapter) 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; uint16_t devid = 0;
if (is_pcie(adapter)) if (save_and_restore_pcie)
pci_save_state(adapter->pdev); pci_save_state(adapter->pdev);
t3_write_reg(adapter, A_PL_RST, F_CRSTWRM | F_CRSTWRMMODE); t3_write_reg(adapter, A_PL_RST, F_CRSTWRM | F_CRSTWRMMODE);
...@@ -3269,7 +3272,7 @@ int t3_reset_adapter(struct adapter *adapter) ...@@ -3269,7 +3272,7 @@ int t3_reset_adapter(struct adapter *adapter)
if (devid != 0x1425) if (devid != 0x1425)
return -1; return -1;
if (is_pcie(adapter)) if (save_and_restore_pcie)
pci_restore_state(adapter->pdev); pci_restore_state(adapter->pdev);
return 0; return 0;
} }
......
...@@ -124,9 +124,6 @@ int t3_mac_reset(struct cmac *mac) ...@@ -124,9 +124,6 @@ int t3_mac_reset(struct cmac *mac)
xaui_serdes_reset(mac); xaui_serdes_reset(mac);
} }
if (adap->params.rev > 0)
t3_write_reg(adap, A_XGM_PAUSE_TIMER + oft, 0xf000);
val = F_MAC_RESET_; val = F_MAC_RESET_;
if (is_10G(adap)) if (is_10G(adap))
val |= F_PCS_RESET_; val |= F_PCS_RESET_;
...@@ -145,6 +142,58 @@ int t3_mac_reset(struct cmac *mac) ...@@ -145,6 +142,58 @@ int t3_mac_reset(struct cmac *mac)
return 0; 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. * 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) ...@@ -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 * Adjust the PAUSE frame watermarks. We always set the LWM, and the
* HWM only if flow-control is enabled. * HWM only if flow-control is enabled.
*/ */
hwm = max(MAC_RXFIFO_SIZE - 3 * mtu, MAC_RXFIFO_SIZE / 2U); hwm = max_t(unsigned int, MAC_RXFIFO_SIZE - 3 * mtu,
hwm = min(hwm, 3 * MAC_RXFIFO_SIZE / 4 + 1024); MAC_RXFIFO_SIZE * 38 / 100);
lwm = hwm - 1024; 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 = t3_read_reg(adap, A_XGM_RXFIFO_CFG + mac->offset);
v &= ~V_RXFIFOPAUSELWM(M_RXFIFOPAUSELWM); v &= ~V_RXFIFOPAUSELWM(M_RXFIFOPAUSELWM);
v |= V_RXFIFOPAUSELWM(lwm / 8); v |= V_RXFIFOPAUSELWM(lwm / 8);
...@@ -270,7 +321,15 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu) ...@@ -270,7 +321,15 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
thres = mtu > thres ? (mtu - thres + 7) / 8 : 0; thres = mtu > thres ? (mtu - thres + 7) / 8 : 0;
thres = max(thres, 8U); /* need at least 8 */ thres = max(thres, 8U); /* need at least 8 */
t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + mac->offset, 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; return 0;
} }
...@@ -298,12 +357,6 @@ int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc) ...@@ -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); 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, t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN,
(fc & PAUSE_RX) ? F_TXPAUSEEN : 0); (fc & PAUSE_RX) ? F_TXPAUSEEN : 0);
return 0; return 0;
...@@ -318,9 +371,17 @@ int t3_mac_enable(struct cmac *mac, int which) ...@@ -318,9 +371,17 @@ int t3_mac_enable(struct cmac *mac, int which)
if (which & MAC_DIRECTION_TX) { if (which & MAC_DIRECTION_TX) {
t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN); 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_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_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_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->tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap,
A_TP_PIO_DATA)));
mac->xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
A_XGM_TX_SPI4_SOP_EOP_CNT)));
mac->txen = F_TXEN;
mac->toggle_cnt = 0;
} }
if (which & MAC_DIRECTION_RX) if (which & MAC_DIRECTION_RX)
t3_write_reg(adap, A_XGM_RX_CTRL + oft, F_RXEN); t3_write_reg(adap, A_XGM_RX_CTRL + oft, F_RXEN);
...@@ -337,13 +398,50 @@ int t3_mac_disable(struct cmac *mac, int which) ...@@ -337,13 +398,50 @@ int t3_mac_disable(struct cmac *mac, int which)
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx); 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_DATA, 0xc000001f);
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_MODE); 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_write_reg(adap, A_XGM_RX_CTRL + mac->offset, 0); t3_write_reg(adap, A_XGM_RX_CTRL + mac->offset, 0);
return 0; return 0;
} }
int t3b2_mac_watchdog_task(struct cmac *mac)
{
struct adapter *adap = mac->adapter;
unsigned int tcnt, xcnt;
int status;
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CNT_CH0 + macidx(mac));
tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap, A_TP_PIO_DATA)));
xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
A_XGM_TX_SPI4_SOP_EOP_CNT +
mac->offset)));
if (tcnt != mac->tcnt && xcnt == 0 && mac->xcnt == 0) {
if (mac->toggle_cnt > 4) {
t3b2_mac_reset(mac);
mac->toggle_cnt = 0;
status = 2;
} else {
t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0);
t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset);
t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset,
mac->txen);
t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset);
mac->toggle_cnt++;
status = 1;
}
} else {
mac->toggle_cnt = 0;
status = 0;
}
mac->tcnt = tcnt;
mac->xcnt = xcnt;
return status;
}
/* /*
* This function is called periodically to accumulate the current values of the * This function is called periodically to accumulate the current values of the
* RMON counters into the port statistics. Since the packet counters are only * RMON counters into the port statistics. Since the packet counters are only
...@@ -375,6 +473,11 @@ const struct mac_stats *t3_mac_update_stats(struct cmac *mac) ...@@ -375,6 +473,11 @@ const struct mac_stats *t3_mac_update_stats(struct cmac *mac)
RMON_UPDATE(mac, rx_too_long, RX_OVERSIZE_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); 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_64, RX_64B_FRAMES);
RMON_UPDATE(mac, rx_frames_65_127, RX_65_127B_FRAMES); RMON_UPDATE(mac, rx_frames_65_127, RX_65_127B_FRAMES);
RMON_UPDATE(mac, rx_frames_128_255, RX_128_255B_FRAMES); RMON_UPDATE(mac, rx_frames_128_255, RX_128_255B_FRAMES);
......
...@@ -414,10 +414,9 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase) ...@@ -414,10 +414,9 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
icr &= 0x70; icr &= 0x70;
outb(icr, EWRK3_ICR); /* Disable all the IRQs */ outb(icr, EWRK3_ICR); /* Disable all the IRQs */
if (nicsr == (CSR_TXD | CSR_RXD)) if (nicsr != (CSR_TXD | CSR_RXD))
return -ENXIO; return -ENXIO;
/* Check that the EEPROM is alive and well and not living on Pluto... */ /* Check that the EEPROM is alive and well and not living on Pluto... */
for (chksum = 0, i = 0; i < EEPROM_MAX; i += 2) { for (chksum = 0, i = 0; i < EEPROM_MAX; i += 2) {
union { union {
......
...@@ -1516,9 +1516,23 @@ static int mv643xx_eth_shared_remove(struct platform_device *pdev) ...@@ -1516,9 +1516,23 @@ static int mv643xx_eth_shared_remove(struct platform_device *pdev)
return 0; 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 = { static struct platform_driver mv643xx_eth_driver = {
.probe = mv643xx_eth_probe, .probe = mv643xx_eth_probe,
.remove = mv643xx_eth_remove, .remove = mv643xx_eth_remove,
.shutdown = mv643xx_eth_shutdown,
.driver = { .driver = {
.name = MV643XX_ETH_NAME, .name = MV643XX_ETH_NAME,
}, },
......
...@@ -71,7 +71,7 @@ ...@@ -71,7 +71,7 @@
#include "myri10ge_mcp.h" #include "myri10ge_mcp.h"
#include "myri10ge_mcp_gen_header.h" #include "myri10ge_mcp_gen_header.h"
#define MYRI10GE_VERSION_STR "1.2.0" #define MYRI10GE_VERSION_STR "1.3.0-1.226"
MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
MODULE_AUTHOR("Maintainer: help@myri.com"); MODULE_AUTHOR("Maintainer: help@myri.com");
...@@ -234,7 +234,7 @@ static int myri10ge_msi = 1; /* enable msi by default */ ...@@ -234,7 +234,7 @@ static int myri10ge_msi = 1; /* enable msi by default */
module_param(myri10ge_msi, int, S_IRUGO | S_IWUSR); module_param(myri10ge_msi, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(myri10ge_msi, "Enable Message Signalled Interrupts\n"); 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_param(myri10ge_intr_coal_delay, int, S_IRUGO);
MODULE_PARM_DESC(myri10ge_intr_coal_delay, "Interrupt coalescing delay\n"); MODULE_PARM_DESC(myri10ge_intr_coal_delay, "Interrupt coalescing delay\n");
...@@ -279,7 +279,7 @@ static int myri10ge_fill_thresh = 256; ...@@ -279,7 +279,7 @@ static int myri10ge_fill_thresh = 256;
module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR); module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed\n"); 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_param(myri10ge_wcfifo, int, S_IRUGO);
MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n"); MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n");
...@@ -905,6 +905,14 @@ myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, ...@@ -905,6 +905,14 @@ myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
(rx->page_offset + bytes <= MYRI10GE_ALLOC_SIZE)) { (rx->page_offset + bytes <= MYRI10GE_ALLOC_SIZE)) {
/* we can use part of previous page */ /* we can use part of previous page */
get_page(rx->page); get_page(rx->page);
#if MYRI10GE_ALLOC_SIZE > 4096
/* Firmware cannot cross 4K boundary.. */
if ((rx->page_offset >> 12) !=
((rx->page_offset + bytes - 1) >> 12)) {
rx->page_offset =
(rx->page_offset + bytes) & ~4095;
}
#endif
} else { } else {
/* we need a new page */ /* we need a new page */
page = page =
...@@ -2483,6 +2491,8 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) ...@@ -2483,6 +2491,8 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
#define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7 #define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7
#define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa #define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa
#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) static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
{ {
...@@ -2514,6 +2524,12 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp) ...@@ -2514,6 +2524,12 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
((bridge->vendor == PCI_VENDOR_ID_SERVERWORKS ((bridge->vendor == PCI_VENDOR_ID_SERVERWORKS
&& bridge->device == && bridge->device ==
PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE) 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 E5000 PCIE ports */ /* All Intel E5000 PCIE ports */
|| (bridge->vendor == PCI_VENDOR_ID_INTEL || (bridge->vendor == PCI_VENDOR_ID_INTEL
&& bridge->device >= && bridge->device >=
......
...@@ -710,8 +710,8 @@ static int __devinit netdrv_init_board (struct pci_dev *pdev, ...@@ -710,8 +710,8 @@ static int __devinit netdrv_init_board (struct pci_dev *pdev,
tp->chipset, tp->chipset,
rtl_chip_info[tp->chipset].name); rtl_chip_info[tp->chipset].name);
i = register_netdev (dev); rc = register_netdev (dev);
if (i) if (rc)
goto err_out_unmap; goto err_out_unmap;
DPRINTK ("EXIT, returning 0\n"); DPRINTK ("EXIT, returning 0\n");
......
This diff is collapsed.
This diff is collapsed.
...@@ -2424,8 +2424,8 @@ struct skge_hw { ...@@ -2424,8 +2424,8 @@ struct skge_hw {
u32 ram_size; u32 ram_size;
u32 ram_offset; u32 ram_offset;
u16 phy_addr; u16 phy_addr;
struct work_struct phy_work; spinlock_t phy_lock;
struct mutex phy_mutex; struct tasklet_struct phy_task;
}; };
enum pause_control { enum pause_control {
...@@ -2457,7 +2457,7 @@ struct skge_port { ...@@ -2457,7 +2457,7 @@ struct skge_port {
struct net_device_stats net_stats; struct net_device_stats net_stats;
struct delayed_work link_thread; struct timer_list link_timer;
enum pause_control flow_control; enum pause_control flow_control;
enum pause_status flow_status; enum pause_status flow_status;
u8 rx_csum; u8 rx_csum;
......
...@@ -3607,7 +3607,6 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -3607,7 +3607,6 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (bd == ugeth->confBd[txQ]) { if (bd == ugeth->confBd[txQ]) {
if (!netif_queue_stopped(dev)) if (!netif_queue_stopped(dev))
netif_stop_queue(dev); netif_stop_queue(dev);
return NETDEV_TX_BUSY;
} }
ugeth->txBd[txQ] = bd; ugeth->txBd[txQ] = bd;
...@@ -3623,7 +3622,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -3623,7 +3622,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irq(&ugeth->lock); 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) static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit)
......
...@@ -2852,7 +2852,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, ...@@ -2852,7 +2852,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
if (rc) { if (rc) {
airo_print_err(dev->name, "register interrupt %d failed, rc %d", airo_print_err(dev->name, "register interrupt %d failed, rc %d",
irq, rc); irq, rc);
goto err_out_unlink; goto err_out_nets;
} }
if (!is_pcmcia) { if (!is_pcmcia) {
if (!request_region( dev->base_addr, 64, dev->name )) { if (!request_region( dev->base_addr, 64, dev->name )) {
...@@ -2935,6 +2935,8 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, ...@@ -2935,6 +2935,8 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
release_region( dev->base_addr, 64 ); release_region( dev->base_addr, 64 );
err_out_irq: err_out_irq:
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
err_out_nets:
airo_networks_free(ai);
err_out_unlink: err_out_unlink:
del_airo_dev(dev); del_airo_dev(dev);
err_out_thr: err_out_thr:
......
...@@ -882,10 +882,10 @@ static void _stack_save(u32 *_stackptr, size_t *stackidx, ...@@ -882,10 +882,10 @@ static void _stack_save(u32 *_stackptr, size_t *stackidx,
{ {
u32 *stackptr = &(_stackptr[*stackidx]); u32 *stackptr = &(_stackptr[*stackidx]);
assert((offset & 0xF000) == 0x0000); assert((offset & 0xE000) == 0x0000);
assert((id & 0xF0) == 0x00); assert((id & 0xF8) == 0x00);
*stackptr = offset; *stackptr = offset;
*stackptr |= ((u32)id) << 12; *stackptr |= ((u32)id) << 13;
*stackptr |= ((u32)value) << 16; *stackptr |= ((u32)value) << 16;
(*stackidx)++; (*stackidx)++;
assert(*stackidx < BCM43xx_INTERFSTACK_SIZE); assert(*stackidx < BCM43xx_INTERFSTACK_SIZE);
...@@ -896,12 +896,12 @@ static u16 _stack_restore(u32 *stackptr, ...@@ -896,12 +896,12 @@ static u16 _stack_restore(u32 *stackptr,
{ {
size_t i; size_t i;
assert((offset & 0xF000) == 0x0000); assert((offset & 0xE000) == 0x0000);
assert((id & 0xF0) == 0x00); assert((id & 0xF8) == 0x00);
for (i = 0; i < BCM43xx_INTERFSTACK_SIZE; i++, stackptr++) { for (i = 0; i < BCM43xx_INTERFSTACK_SIZE; i++, stackptr++) {
if ((*stackptr & 0x00000FFF) != offset) if ((*stackptr & 0x00001FFF) != offset)
continue; continue;
if (((*stackptr & 0x0000F000) >> 12) != id) if (((*stackptr & 0x00007000) >> 13) != id)
continue; continue;
return ((*stackptr & 0xFFFF0000) >> 16); return ((*stackptr & 0xFFFF0000) >> 16);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment