Commit cb0bc205 authored by Divy Le Ray's avatar Divy Le Ray Committed by David S. Miller

cxgb3: Notify fatal errors

Set up a notification mechanism to inform upper layer modules
(iWARP, iSCSI) of a chip reset due to an EEH event or a fatal error.
Signed-off-by: default avatarDivy Le Ray <divy@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1373c0fd
...@@ -2542,6 +2542,12 @@ static int t3_adapter_error(struct adapter *adapter, int reset) ...@@ -2542,6 +2542,12 @@ static int t3_adapter_error(struct adapter *adapter, int reset)
{ {
int i, ret = 0; int i, ret = 0;
if (is_offload(adapter) &&
test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map)) {
cxgb3_err_notify(&adapter->tdev, OFFLOAD_STATUS_DOWN, 0);
offload_close(&adapter->tdev);
}
/* Stop all ports */ /* Stop all ports */
for_each_port(adapter, i) { for_each_port(adapter, i) {
struct net_device *netdev = adapter->port[i]; struct net_device *netdev = adapter->port[i];
...@@ -2550,10 +2556,6 @@ static int t3_adapter_error(struct adapter *adapter, int reset) ...@@ -2550,10 +2556,6 @@ static int t3_adapter_error(struct adapter *adapter, int reset)
cxgb_close(netdev); cxgb_close(netdev);
} }
if (is_offload(adapter) &&
test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map))
offload_close(&adapter->tdev);
/* Stop SGE timers */ /* Stop SGE timers */
t3_stop_sge_timers(adapter); t3_stop_sge_timers(adapter);
...@@ -2605,6 +2607,9 @@ static void t3_resume_ports(struct adapter *adapter) ...@@ -2605,6 +2607,9 @@ static void t3_resume_ports(struct adapter *adapter)
} }
} }
} }
if (is_offload(adapter) && !ofld_disable)
cxgb3_err_notify(&adapter->tdev, OFFLOAD_STATUS_UP, 0);
} }
/* /*
......
...@@ -153,6 +153,18 @@ void cxgb3_remove_clients(struct t3cdev *tdev) ...@@ -153,6 +153,18 @@ void cxgb3_remove_clients(struct t3cdev *tdev)
mutex_unlock(&cxgb3_db_lock); mutex_unlock(&cxgb3_db_lock);
} }
void cxgb3_err_notify(struct t3cdev *tdev, u32 status, u32 error)
{
struct cxgb3_client *client;
mutex_lock(&cxgb3_db_lock);
list_for_each_entry(client, &client_list, client_list) {
if (client->err_handler)
client->err_handler(tdev, status, error);
}
mutex_unlock(&cxgb3_db_lock);
}
static struct net_device *get_iff_from_mac(struct adapter *adapter, static struct net_device *get_iff_from_mac(struct adapter *adapter,
const unsigned char *mac, const unsigned char *mac,
unsigned int vlan) unsigned int vlan)
......
...@@ -64,10 +64,16 @@ void cxgb3_register_client(struct cxgb3_client *client); ...@@ -64,10 +64,16 @@ void cxgb3_register_client(struct cxgb3_client *client);
void cxgb3_unregister_client(struct cxgb3_client *client); void cxgb3_unregister_client(struct cxgb3_client *client);
void cxgb3_add_clients(struct t3cdev *tdev); void cxgb3_add_clients(struct t3cdev *tdev);
void cxgb3_remove_clients(struct t3cdev *tdev); void cxgb3_remove_clients(struct t3cdev *tdev);
void cxgb3_err_notify(struct t3cdev *tdev, u32 status, u32 error);
typedef int (*cxgb3_cpl_handler_func)(struct t3cdev *dev, typedef int (*cxgb3_cpl_handler_func)(struct t3cdev *dev,
struct sk_buff *skb, void *ctx); struct sk_buff *skb, void *ctx);
enum {
OFFLOAD_STATUS_UP,
OFFLOAD_STATUS_DOWN
};
struct cxgb3_client { struct cxgb3_client {
char *name; char *name;
void (*add) (struct t3cdev *); void (*add) (struct t3cdev *);
...@@ -76,6 +82,7 @@ struct cxgb3_client { ...@@ -76,6 +82,7 @@ struct cxgb3_client {
int (*redirect)(void *ctx, struct dst_entry *old, int (*redirect)(void *ctx, struct dst_entry *old,
struct dst_entry *new, struct l2t_entry *l2t); struct dst_entry *new, struct l2t_entry *l2t);
struct list_head client_list; struct list_head client_list;
void (*err_handler)(struct t3cdev *tdev, u32 status, u32 error);
}; };
/* /*
......
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