Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 135159
b: refs/heads/master
c: bf79209
h: refs/heads/master
i:
  135157: ef149a8
  135155: 8c85a14
  135151: cd6fd38
v: v3
  • Loading branch information
Divy Le Ray authored and David S. Miller committed Mar 13, 2009
1 parent 819e7d2 commit f74aae6
Show file tree
Hide file tree
Showing 7 changed files with 286 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cd40658a616050df0a50d0a3ded06e3ebcc0a04a
refs/heads/master: bf792094ef830117312b3990b63474320ec864c0
5 changes: 5 additions & 0 deletions trunk/drivers/net/cxgb3/adapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ struct port_info {
struct net_device_stats netstats;
int activity;
__be32 iscsi_ipv4addr;

int link_fault; /* link fault was detected */
};

enum { /* adapter flags */
Expand Down Expand Up @@ -241,6 +243,7 @@ struct adapter {
struct delayed_work adap_check_task;
struct work_struct ext_intr_handler_task;
struct work_struct fatal_error_handler_task;
struct work_struct link_fault_handler_task;

struct dentry *debugfs_root;

Expand Down Expand Up @@ -283,6 +286,8 @@ void t3_os_ext_intr_handler(struct adapter *adapter);
void t3_os_link_changed(struct adapter *adapter, int port_id, int link_status,
int speed, int duplex, int fc);
void t3_os_phymod_changed(struct adapter *adap, int port_id);
void t3_os_link_fault(struct adapter *adapter, int port_id, int state);
void t3_os_link_fault_handler(struct adapter *adapter, int port_id);

void t3_sge_start(struct adapter *adap);
void t3_sge_stop(struct adapter *adap);
Expand Down
6 changes: 6 additions & 0 deletions trunk/drivers/net/cxgb3/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ struct mac_stats {
unsigned long num_toggled; /* # times toggled TxEn due to stuck TX */
unsigned long num_resets; /* # times reset due to stuck TX */

unsigned long link_faults; /* # detected link faults */
};

struct tp_mib_stats {
Expand Down Expand Up @@ -701,13 +702,16 @@ int t3_phy_lasi_intr_handler(struct cphy *phy);
void t3_intr_enable(struct adapter *adapter);
void t3_intr_disable(struct adapter *adapter);
void t3_intr_clear(struct adapter *adapter);
void t3_xgm_intr_enable(struct adapter *adapter, int idx);
void t3_xgm_intr_disable(struct adapter *adapter, int idx);
void t3_port_intr_enable(struct adapter *adapter, int idx);
void t3_port_intr_disable(struct adapter *adapter, int idx);
void t3_port_intr_clear(struct adapter *adapter, int idx);
int t3_slow_intr_handler(struct adapter *adapter);
int t3_phy_intr_handler(struct adapter *adapter);

void t3_link_changed(struct adapter *adapter, int port_id);
void t3_link_fault(struct adapter *adapter, int port_id);
int t3_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc);
const struct adapter_info *t3_get_adapter_info(unsigned int board_id);
int t3_seeprom_read(struct adapter *adapter, u32 addr, __le32 *data);
Expand Down Expand Up @@ -744,6 +748,8 @@ int t3_mc7_bd_read(struct mc7 *mc7, unsigned int start, unsigned int n,

int t3_mac_reset(struct cmac *mac);
void t3b_pcs_reset(struct cmac *mac);
void t3_mac_disable_exact_filters(struct cmac *mac);
void t3_mac_enable_exact_filters(struct cmac *mac);
int t3_mac_enable(struct cmac *mac, int which);
int t3_mac_disable(struct cmac *mac, int which);
int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu);
Expand Down
123 changes: 120 additions & 3 deletions trunk/drivers/net/cxgb3/cxgb3_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,40 @@ static void link_report(struct net_device *dev)
}
}

void t3_os_link_fault(struct adapter *adap, int port_id, int state)
{
struct net_device *dev = adap->port[port_id];
struct port_info *pi = netdev_priv(dev);

if (state == netif_carrier_ok(dev))
return;

if (state) {
struct cmac *mac = &pi->mac;

netif_carrier_on(dev);

/* Clear local faults */
t3_xgm_intr_disable(adap, pi->port_id);
t3_read_reg(adap, A_XGM_INT_STATUS +
pi->mac.offset);
t3_write_reg(adap,
A_XGM_INT_CAUSE + pi->mac.offset,
F_XGM_INT);

t3_set_reg_field(adap,
A_XGM_INT_ENABLE +
pi->mac.offset,
F_XGM_INT, F_XGM_INT);
t3_xgm_intr_enable(adap, pi->port_id);

t3_mac_enable(mac, MAC_DIRECTION_TX);
} else
netif_carrier_off(dev);

link_report(dev);
}

/**
* t3_os_link_changed - handle link status changes
* @adapter: the adapter associated with the link change
Expand Down Expand Up @@ -197,10 +231,34 @@ void t3_os_link_changed(struct adapter *adapter, int port_id, int link_stat,
if (link_stat != netif_carrier_ok(dev)) {
if (link_stat) {
t3_mac_enable(mac, MAC_DIRECTION_RX);

/* Clear local faults */
t3_xgm_intr_disable(adapter, pi->port_id);
t3_read_reg(adapter, A_XGM_INT_STATUS +
pi->mac.offset);
t3_write_reg(adapter,
A_XGM_INT_CAUSE + pi->mac.offset,
F_XGM_INT);

t3_set_reg_field(adapter,
A_XGM_INT_ENABLE + pi->mac.offset,
F_XGM_INT, F_XGM_INT);
t3_xgm_intr_enable(adapter, pi->port_id);

netif_carrier_on(dev);
} else {
netif_carrier_off(dev);
pi->phy.ops->power_down(&pi->phy, 1);

t3_xgm_intr_disable(adapter, pi->port_id);
t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset);
t3_set_reg_field(adapter,
A_XGM_INT_ENABLE + pi->mac.offset,
F_XGM_INT, 0);

if (is_10G(adapter))
pi->phy.ops->power_down(&pi->phy, 1);

t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset);
t3_mac_disable(mac, MAC_DIRECTION_RX);
t3_link_start(&pi->phy, mac, &pi->link_config);
}
Expand Down Expand Up @@ -1173,6 +1231,10 @@ static int cxgb_close(struct net_device *dev)
struct port_info *pi = netdev_priv(dev);
struct adapter *adapter = pi->adapter;

/* Stop link fault interrupts */
t3_xgm_intr_disable(adapter, pi->port_id);
t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset);

t3_port_intr_disable(adapter, pi->port_id);
netif_tx_stop_all_queues(dev);
pi->phy.ops->power_down(&pi->phy, 1);
Expand Down Expand Up @@ -1299,6 +1361,7 @@ static char stats_strings[][ETH_GSTRING_LEN] = {
"CheckTXEnToggled ",
"CheckResets ",

"LinkFaults ",
};

static int get_sset_count(struct net_device *dev, int sset)
Expand Down Expand Up @@ -1431,6 +1494,8 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats,

*data++ = s->num_toggled;
*data++ = s->num_resets;

*data++ = s->link_faults;
}

static inline void reg_block_dump(struct adapter *ap, void *buf,
Expand Down Expand Up @@ -2425,8 +2490,20 @@ static void check_link_status(struct adapter *adapter)
struct net_device *dev = adapter->port[i];
struct port_info *p = netdev_priv(dev);

if (!(p->phy.caps & SUPPORTED_IRQ) && netif_running(dev))
spin_lock_irq(&adapter->work_lock);
if (p->link_fault) {
spin_unlock_irq(&adapter->work_lock);
continue;
}
spin_unlock_irq(&adapter->work_lock);

if (!(p->phy.caps & SUPPORTED_IRQ) && netif_running(dev)) {
t3_xgm_intr_disable(adapter, i);
t3_read_reg(adapter, A_XGM_INT_STATUS + p->mac.offset);

t3_link_changed(adapter, i);
t3_xgm_intr_enable(adapter, i);
}
}
}

Expand Down Expand Up @@ -2553,9 +2630,23 @@ static void ext_intr_task(struct work_struct *work)
{
struct adapter *adapter = container_of(work, struct adapter,
ext_intr_handler_task);
int i;

/* Disable link fault interrupts */
for_each_port(adapter, i) {
struct net_device *dev = adapter->port[i];
struct port_info *p = netdev_priv(dev);

t3_xgm_intr_disable(adapter, i);
t3_read_reg(adapter, A_XGM_INT_STATUS + p->mac.offset);
}

/* Re-enable link fault interrupts */
t3_phy_intr_handler(adapter);

for_each_port(adapter, i)
t3_xgm_intr_enable(adapter, i);

/* Now reenable external interrupts */
spin_lock_irq(&adapter->work_lock);
if (adapter->slow_intr_mask) {
Expand Down Expand Up @@ -2588,6 +2679,32 @@ void t3_os_ext_intr_handler(struct adapter *adapter)
spin_unlock(&adapter->work_lock);
}

static void link_fault_task(struct work_struct *work)
{
struct adapter *adapter = container_of(work, struct adapter,
link_fault_handler_task);
int i;

for_each_port(adapter, i) {
struct net_device *netdev = adapter->port[i];
struct port_info *pi = netdev_priv(netdev);

if (pi->link_fault)
t3_link_fault(adapter, i);
}
}

void t3_os_link_fault_handler(struct adapter *adapter, int port_id)
{
struct net_device *netdev = adapter->port[port_id];
struct port_info *pi = netdev_priv(netdev);

spin_lock(&adapter->work_lock);
pi->link_fault = 1;
queue_work(cxgb3_wq, &adapter->link_fault_handler_task);
spin_unlock(&adapter->work_lock);
}

static int t3_adapter_error(struct adapter *adapter, int reset)
{
int i, ret = 0;
Expand Down Expand Up @@ -2704,7 +2821,6 @@ void t3_fatal_err(struct adapter *adapter)
CH_ALERT(adapter, "FW status: 0x%x, 0x%x, 0x%x, 0x%x\n",
fw_status[0], fw_status[1],
fw_status[2], fw_status[3]);

}

/**
Expand Down Expand Up @@ -2962,6 +3078,7 @@ static int __devinit init_one(struct pci_dev *pdev,

INIT_LIST_HEAD(&adapter->adapter_list);
INIT_WORK(&adapter->ext_intr_handler_task, ext_intr_task);
INIT_WORK(&adapter->link_fault_handler_task, link_fault_task);
INIT_WORK(&adapter->fatal_error_handler_task, fatal_error_task);
INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task);

Expand Down
13 changes: 13 additions & 0 deletions trunk/drivers/net/cxgb3/regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -2215,6 +2215,15 @@

#define A_XGM_RX_EXACT_MATCH_LOW_8 0x854

#define A_XGM_INT_STATUS 0x86c

#define S_LINKFAULTCHANGE 9
#define V_LINKFAULTCHANGE(x) ((x) << S_LINKFAULTCHANGE)
#define F_LINKFAULTCHANGE V_LINKFAULTCHANGE(1U)

#define A_XGM_XGM_INT_ENABLE 0x874
#define A_XGM_XGM_INT_DISABLE 0x878

#define A_XGM_STAT_CTRL 0x880

#define S_CLRSTATS 2
Expand Down Expand Up @@ -2413,6 +2422,10 @@
#define V_XAUIPCSALIGNCHANGE(x) ((x) << S_XAUIPCSALIGNCHANGE)
#define F_XAUIPCSALIGNCHANGE V_XAUIPCSALIGNCHANGE(1U)

#define S_XGM_INT 0
#define V_XGM_INT(x) ((x) << S_XGM_INT)
#define F_XGM_INT V_XGM_INT(1U)

#define A_XGM_INT_CAUSE 0x8d8

#define A_XGM_XAUI_ACT_CTRL 0x8dc
Expand Down
Loading

0 comments on commit f74aae6

Please sign in to comment.