提交 12dfac6c 编写于 作者: D David S. Miller

Merge branch 'qeth'

Merge s390 networking changes from Frank Blaschka.
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
...@@ -74,8 +74,8 @@ config QETH ...@@ -74,8 +74,8 @@ config QETH
depends on CCW && NETDEVICES && IP_MULTICAST && QDIO depends on CCW && NETDEVICES && IP_MULTICAST && QDIO
help help
This driver supports the IBM System z OSA Express adapters This driver supports the IBM System z OSA Express adapters
in QDIO mode (all media types), HiperSockets interfaces and VM GuestLAN in QDIO mode (all media types), HiperSockets interfaces and z/VM
interfaces in QDIO and HIPER mode. virtual NICs for Guest LAN and VSWITCH.
For details please refer to the documentation provided by IBM at For details please refer to the documentation provided by IBM at
<http://www.ibm.com/developerworks/linux/linux390> <http://www.ibm.com/developerworks/linux/linux390>
......
...@@ -678,6 +678,7 @@ struct qeth_card_options { ...@@ -678,6 +678,7 @@ struct qeth_card_options {
int performance_stats; int performance_stats;
int rx_sg_cb; int rx_sg_cb;
enum qeth_ipa_isolation_modes isolation; enum qeth_ipa_isolation_modes isolation;
enum qeth_ipa_isolation_modes prev_isolation;
int sniffer; int sniffer;
enum qeth_cq cq; enum qeth_cq cq;
char hsuid[9]; char hsuid[9];
...@@ -789,6 +790,7 @@ struct qeth_card { ...@@ -789,6 +790,7 @@ struct qeth_card {
struct qeth_rx rx; struct qeth_rx rx;
struct delayed_work buffer_reclaim_work; struct delayed_work buffer_reclaim_work;
int reclaim_index; int reclaim_index;
struct work_struct close_dev_work;
}; };
struct qeth_card_list_struct { struct qeth_card_list_struct {
...@@ -909,9 +911,6 @@ struct qeth_cmd_buffer *qeth_wait_for_buffer(struct qeth_channel *); ...@@ -909,9 +911,6 @@ struct qeth_cmd_buffer *qeth_wait_for_buffer(struct qeth_channel *);
int qeth_mdio_read(struct net_device *, int, int); int qeth_mdio_read(struct net_device *, int, int);
int qeth_snmp_command(struct qeth_card *, char __user *); int qeth_snmp_command(struct qeth_card *, char __user *);
int qeth_query_oat_command(struct qeth_card *, char __user *); int qeth_query_oat_command(struct qeth_card *, char __user *);
struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *, __u32, __u32);
int qeth_default_setadapterparms_cb(struct qeth_card *, struct qeth_reply *,
unsigned long);
int qeth_send_control_data(struct qeth_card *, int, struct qeth_cmd_buffer *, int qeth_send_control_data(struct qeth_card *, int, struct qeth_cmd_buffer *,
int (*reply_cb)(struct qeth_card *, struct qeth_reply*, unsigned long), int (*reply_cb)(struct qeth_card *, struct qeth_reply*, unsigned long),
void *reply_param); void *reply_param);
...@@ -928,12 +927,13 @@ void qeth_core_get_strings(struct net_device *, u32, u8 *); ...@@ -928,12 +927,13 @@ void qeth_core_get_strings(struct net_device *, u32, u8 *);
void qeth_core_get_drvinfo(struct net_device *, struct ethtool_drvinfo *); void qeth_core_get_drvinfo(struct net_device *, struct ethtool_drvinfo *);
void qeth_dbf_longtext(debug_info_t *id, int level, char *text, ...); void qeth_dbf_longtext(debug_info_t *id, int level, char *text, ...);
int qeth_core_ethtool_get_settings(struct net_device *, struct ethtool_cmd *); int qeth_core_ethtool_get_settings(struct net_device *, struct ethtool_cmd *);
int qeth_set_access_ctrl_online(struct qeth_card *card); int qeth_set_access_ctrl_online(struct qeth_card *card, int fallback);
int qeth_hdr_chk_and_bounce(struct sk_buff *, int); int qeth_hdr_chk_and_bounce(struct sk_buff *, int);
int qeth_configure_cq(struct qeth_card *, enum qeth_cq); int qeth_configure_cq(struct qeth_card *, enum qeth_cq);
int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action); int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action);
int qeth_query_ipassists(struct qeth_card *, enum qeth_prot_versions prot); int qeth_query_ipassists(struct qeth_card *, enum qeth_prot_versions prot);
void qeth_trace_features(struct qeth_card *); void qeth_trace_features(struct qeth_card *);
void qeth_close_dev(struct qeth_card *);
/* exports for OSN */ /* exports for OSN */
int qeth_osn_assist(struct net_device *, void *, int); int qeth_osn_assist(struct net_device *, void *, int);
......
...@@ -68,6 +68,27 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, ...@@ -68,6 +68,27 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
enum qeth_qdio_buffer_states newbufstate); enum qeth_qdio_buffer_states newbufstate);
static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *, int); static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *, int);
static struct workqueue_struct *qeth_wq;
static void qeth_close_dev_handler(struct work_struct *work)
{
struct qeth_card *card;
card = container_of(work, struct qeth_card, close_dev_work);
QETH_CARD_TEXT(card, 2, "cldevhdl");
rtnl_lock();
dev_close(card->dev);
rtnl_unlock();
ccwgroup_set_offline(card->gdev);
}
void qeth_close_dev(struct qeth_card *card)
{
QETH_CARD_TEXT(card, 2, "cldevsubm");
queue_work(qeth_wq, &card->close_dev_work);
}
EXPORT_SYMBOL_GPL(qeth_close_dev);
static inline const char *qeth_get_cardname(struct qeth_card *card) static inline const char *qeth_get_cardname(struct qeth_card *card)
{ {
if (card->info.guestlan) { if (card->info.guestlan) {
...@@ -542,11 +563,23 @@ static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card, ...@@ -542,11 +563,23 @@ static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card,
} else { } else {
switch (cmd->hdr.command) { switch (cmd->hdr.command) {
case IPA_CMD_STOPLAN: case IPA_CMD_STOPLAN:
dev_warn(&card->gdev->dev, if (cmd->hdr.return_code ==
IPA_RC_VEPA_TO_VEB_TRANSITION) {
dev_err(&card->gdev->dev,
"Interface %s is down because the "
"adjacent port is no longer in "
"reflective relay mode\n",
QETH_CARD_IFNAME(card));
qeth_close_dev(card);
} else {
dev_warn(&card->gdev->dev,
"The link for interface %s on CHPID" "The link for interface %s on CHPID"
" 0x%X failed\n", " 0x%X failed\n",
QETH_CARD_IFNAME(card), QETH_CARD_IFNAME(card),
card->info.chpid); card->info.chpid);
qeth_issue_ipa_msg(cmd,
cmd->hdr.return_code, card);
}
card->lan_online = 0; card->lan_online = 0;
if (card->dev && netif_carrier_ok(card->dev)) if (card->dev && netif_carrier_ok(card->dev))
netif_carrier_off(card->dev); netif_carrier_off(card->dev);
...@@ -1416,6 +1449,7 @@ static int qeth_setup_card(struct qeth_card *card) ...@@ -1416,6 +1449,7 @@ static int qeth_setup_card(struct qeth_card *card)
/* init QDIO stuff */ /* init QDIO stuff */
qeth_init_qdio_info(card); qeth_init_qdio_info(card);
INIT_DELAYED_WORK(&card->buffer_reclaim_work, qeth_buffer_reclaim_work); INIT_DELAYED_WORK(&card->buffer_reclaim_work, qeth_buffer_reclaim_work);
INIT_WORK(&card->close_dev_work, qeth_close_dev_handler);
return 0; return 0;
} }
...@@ -2868,7 +2902,7 @@ int qeth_send_startlan(struct qeth_card *card) ...@@ -2868,7 +2902,7 @@ int qeth_send_startlan(struct qeth_card *card)
} }
EXPORT_SYMBOL_GPL(qeth_send_startlan); EXPORT_SYMBOL_GPL(qeth_send_startlan);
int qeth_default_setadapterparms_cb(struct qeth_card *card, static int qeth_default_setadapterparms_cb(struct qeth_card *card,
struct qeth_reply *reply, unsigned long data) struct qeth_reply *reply, unsigned long data)
{ {
struct qeth_ipa_cmd *cmd; struct qeth_ipa_cmd *cmd;
...@@ -2881,7 +2915,6 @@ int qeth_default_setadapterparms_cb(struct qeth_card *card, ...@@ -2881,7 +2915,6 @@ int qeth_default_setadapterparms_cb(struct qeth_card *card,
cmd->data.setadapterparms.hdr.return_code; cmd->data.setadapterparms.hdr.return_code;
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(qeth_default_setadapterparms_cb);
static int qeth_query_setadapterparms_cb(struct qeth_card *card, static int qeth_query_setadapterparms_cb(struct qeth_card *card,
struct qeth_reply *reply, unsigned long data) struct qeth_reply *reply, unsigned long data)
...@@ -2901,7 +2934,7 @@ static int qeth_query_setadapterparms_cb(struct qeth_card *card, ...@@ -2901,7 +2934,7 @@ static int qeth_query_setadapterparms_cb(struct qeth_card *card,
return qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd); return qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd);
} }
struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *card, static struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *card,
__u32 command, __u32 cmdlen) __u32 command, __u32 cmdlen)
{ {
struct qeth_cmd_buffer *iob; struct qeth_cmd_buffer *iob;
...@@ -2917,7 +2950,6 @@ struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *card, ...@@ -2917,7 +2950,6 @@ struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *card,
return iob; return iob;
} }
EXPORT_SYMBOL_GPL(qeth_get_adapter_cmd);
int qeth_query_setadapterparms(struct qeth_card *card) int qeth_query_setadapterparms(struct qeth_card *card)
{ {
...@@ -4059,6 +4091,7 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card, ...@@ -4059,6 +4091,7 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
{ {
struct qeth_ipa_cmd *cmd; struct qeth_ipa_cmd *cmd;
struct qeth_set_access_ctrl *access_ctrl_req; struct qeth_set_access_ctrl *access_ctrl_req;
int fallback = *(int *)reply->param;
QETH_CARD_TEXT(card, 4, "setaccb"); QETH_CARD_TEXT(card, 4, "setaccb");
...@@ -4068,12 +4101,14 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card, ...@@ -4068,12 +4101,14 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
QETH_DBF_TEXT_(SETUP, 2, "%s", card->gdev->dev.kobj.name); QETH_DBF_TEXT_(SETUP, 2, "%s", card->gdev->dev.kobj.name);
QETH_DBF_TEXT_(SETUP, 2, "rc=%d", QETH_DBF_TEXT_(SETUP, 2, "rc=%d",
cmd->data.setadapterparms.hdr.return_code); cmd->data.setadapterparms.hdr.return_code);
if (cmd->data.setadapterparms.hdr.return_code !=
SET_ACCESS_CTRL_RC_SUCCESS)
QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_CTRL(%s,%d)==%d\n",
card->gdev->dev.kobj.name,
access_ctrl_req->subcmd_code,
cmd->data.setadapterparms.hdr.return_code);
switch (cmd->data.setadapterparms.hdr.return_code) { switch (cmd->data.setadapterparms.hdr.return_code) {
case SET_ACCESS_CTRL_RC_SUCCESS: case SET_ACCESS_CTRL_RC_SUCCESS:
case SET_ACCESS_CTRL_RC_ALREADY_NOT_ISOLATED:
case SET_ACCESS_CTRL_RC_ALREADY_ISOLATED:
{
card->options.isolation = access_ctrl_req->subcmd_code;
if (card->options.isolation == ISOLATION_MODE_NONE) { if (card->options.isolation == ISOLATION_MODE_NONE) {
dev_info(&card->gdev->dev, dev_info(&card->gdev->dev,
"QDIO data connection isolation is deactivated\n"); "QDIO data connection isolation is deactivated\n");
...@@ -4081,72 +4116,64 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card, ...@@ -4081,72 +4116,64 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
dev_info(&card->gdev->dev, dev_info(&card->gdev->dev,
"QDIO data connection isolation is activated\n"); "QDIO data connection isolation is activated\n");
} }
QETH_DBF_MESSAGE(3, "OK:SET_ACCESS_CTRL(%s, %d)==%d\n",
card->gdev->dev.kobj.name,
access_ctrl_req->subcmd_code,
cmd->data.setadapterparms.hdr.return_code);
break; break;
} case SET_ACCESS_CTRL_RC_ALREADY_NOT_ISOLATED:
QETH_DBF_MESSAGE(2, "%s QDIO data connection isolation already "
"deactivated\n", dev_name(&card->gdev->dev));
if (fallback)
card->options.isolation = card->options.prev_isolation;
break;
case SET_ACCESS_CTRL_RC_ALREADY_ISOLATED:
QETH_DBF_MESSAGE(2, "%s QDIO data connection isolation already"
" activated\n", dev_name(&card->gdev->dev));
if (fallback)
card->options.isolation = card->options.prev_isolation;
break;
case SET_ACCESS_CTRL_RC_NOT_SUPPORTED: case SET_ACCESS_CTRL_RC_NOT_SUPPORTED:
{
QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_CTRL(%s,%d)==%d\n",
card->gdev->dev.kobj.name,
access_ctrl_req->subcmd_code,
cmd->data.setadapterparms.hdr.return_code);
dev_err(&card->gdev->dev, "Adapter does not " dev_err(&card->gdev->dev, "Adapter does not "
"support QDIO data connection isolation\n"); "support QDIO data connection isolation\n");
/* ensure isolation mode is "none" */
card->options.isolation = ISOLATION_MODE_NONE;
break; break;
}
case SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER: case SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER:
{
QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d\n",
card->gdev->dev.kobj.name,
access_ctrl_req->subcmd_code,
cmd->data.setadapterparms.hdr.return_code);
dev_err(&card->gdev->dev, dev_err(&card->gdev->dev,
"Adapter is dedicated. " "Adapter is dedicated. "
"QDIO data connection isolation not supported\n"); "QDIO data connection isolation not supported\n");
if (fallback)
/* ensure isolation mode is "none" */ card->options.isolation = card->options.prev_isolation;
card->options.isolation = ISOLATION_MODE_NONE;
break; break;
}
case SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF: case SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF:
{
QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d\n",
card->gdev->dev.kobj.name,
access_ctrl_req->subcmd_code,
cmd->data.setadapterparms.hdr.return_code);
dev_err(&card->gdev->dev, dev_err(&card->gdev->dev,
"TSO does not permit QDIO data connection isolation\n"); "TSO does not permit QDIO data connection isolation\n");
if (fallback)
/* ensure isolation mode is "none" */ card->options.isolation = card->options.prev_isolation;
card->options.isolation = ISOLATION_MODE_NONE; break;
case SET_ACCESS_CTRL_RC_REFLREL_UNSUPPORTED:
dev_err(&card->gdev->dev, "The adjacent switch port does not "
"support reflective relay mode\n");
if (fallback)
card->options.isolation = card->options.prev_isolation;
break;
case SET_ACCESS_CTRL_RC_REFLREL_FAILED:
dev_err(&card->gdev->dev, "The reflective relay mode cannot be "
"enabled at the adjacent switch port");
if (fallback)
card->options.isolation = card->options.prev_isolation;
break;
case SET_ACCESS_CTRL_RC_REFLREL_DEACT_FAILED:
dev_warn(&card->gdev->dev, "Turning off reflective relay mode "
"at the adjacent switch failed\n");
break; break;
}
default: default:
{
/* this should never happen */ /* this should never happen */
QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_MODE(%s,%d)==%d" if (fallback)
"==UNKNOWN\n", card->options.isolation = card->options.prev_isolation;
card->gdev->dev.kobj.name,
access_ctrl_req->subcmd_code,
cmd->data.setadapterparms.hdr.return_code);
/* ensure isolation mode is "none" */
card->options.isolation = ISOLATION_MODE_NONE;
break; break;
} }
}
qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd); qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);
return 0; return 0;
} }
static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card, static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
enum qeth_ipa_isolation_modes isolation) enum qeth_ipa_isolation_modes isolation, int fallback)
{ {
int rc; int rc;
struct qeth_cmd_buffer *iob; struct qeth_cmd_buffer *iob;
...@@ -4166,12 +4193,12 @@ static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card, ...@@ -4166,12 +4193,12 @@ static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
access_ctrl_req->subcmd_code = isolation; access_ctrl_req->subcmd_code = isolation;
rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_set_access_ctrl_cb, rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_set_access_ctrl_cb,
NULL); &fallback);
QETH_DBF_TEXT_(SETUP, 2, "rc=%d", rc); QETH_DBF_TEXT_(SETUP, 2, "rc=%d", rc);
return rc; return rc;
} }
int qeth_set_access_ctrl_online(struct qeth_card *card) int qeth_set_access_ctrl_online(struct qeth_card *card, int fallback)
{ {
int rc = 0; int rc = 0;
...@@ -4181,12 +4208,13 @@ int qeth_set_access_ctrl_online(struct qeth_card *card) ...@@ -4181,12 +4208,13 @@ int qeth_set_access_ctrl_online(struct qeth_card *card)
card->info.type == QETH_CARD_TYPE_OSX) && card->info.type == QETH_CARD_TYPE_OSX) &&
qeth_adp_supported(card, IPA_SETADP_SET_ACCESS_CONTROL)) { qeth_adp_supported(card, IPA_SETADP_SET_ACCESS_CONTROL)) {
rc = qeth_setadpparms_set_access_ctrl(card, rc = qeth_setadpparms_set_access_ctrl(card,
card->options.isolation); card->options.isolation, fallback);
if (rc) { if (rc) {
QETH_DBF_MESSAGE(3, QETH_DBF_MESSAGE(3,
"IPA(SET_ACCESS_CTRL,%s,%d) sent failed\n", "IPA(SET_ACCESS_CTRL,%s,%d) sent failed\n",
card->gdev->dev.kobj.name, card->gdev->dev.kobj.name,
rc); rc);
rc = -EOPNOTSUPP;
} }
} else if (card->options.isolation != ISOLATION_MODE_NONE) { } else if (card->options.isolation != ISOLATION_MODE_NONE) {
card->options.isolation = ISOLATION_MODE_NONE; card->options.isolation = ISOLATION_MODE_NONE;
...@@ -4672,7 +4700,7 @@ static int qeth_qdio_establish(struct qeth_card *card) ...@@ -4672,7 +4700,7 @@ static int qeth_qdio_establish(struct qeth_card *card)
init_data.output_sbal_addr_array = (void **) out_sbal_ptrs; init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;
init_data.output_sbal_state_array = card->qdio.out_bufstates; init_data.output_sbal_state_array = card->qdio.out_bufstates;
init_data.scan_threshold = init_data.scan_threshold =
(card->info.type == QETH_CARD_TYPE_IQD) ? 8 : 32; (card->info.type == QETH_CARD_TYPE_IQD) ? 1 : 32;
if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ALLOCATED, if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ALLOCATED,
QETH_QDIO_ESTABLISHED) == QETH_QDIO_ALLOCATED) { QETH_QDIO_ESTABLISHED) == QETH_QDIO_ALLOCATED) {
...@@ -4765,14 +4793,14 @@ static struct ccw_driver qeth_ccw_driver = { ...@@ -4765,14 +4793,14 @@ static struct ccw_driver qeth_ccw_driver = {
int qeth_core_hardsetup_card(struct qeth_card *card) int qeth_core_hardsetup_card(struct qeth_card *card)
{ {
int retries = 0; int retries = 3;
int rc; int rc;
QETH_DBF_TEXT(SETUP, 2, "hrdsetup"); QETH_DBF_TEXT(SETUP, 2, "hrdsetup");
atomic_set(&card->force_alloc_skb, 0); atomic_set(&card->force_alloc_skb, 0);
qeth_update_from_chp_desc(card); qeth_update_from_chp_desc(card);
retry: retry:
if (retries) if (retries < 3)
QETH_DBF_MESSAGE(2, "%s Retrying to do IDX activates.\n", QETH_DBF_MESSAGE(2, "%s Retrying to do IDX activates.\n",
dev_name(&card->gdev->dev)); dev_name(&card->gdev->dev));
ccw_device_set_offline(CARD_DDEV(card)); ccw_device_set_offline(CARD_DDEV(card));
...@@ -4794,7 +4822,7 @@ int qeth_core_hardsetup_card(struct qeth_card *card) ...@@ -4794,7 +4822,7 @@ int qeth_core_hardsetup_card(struct qeth_card *card)
return rc; return rc;
} else if (rc) { } else if (rc) {
QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
if (++retries > 3) if (--retries < 0)
goto out; goto out;
else else
goto retry; goto retry;
...@@ -5094,13 +5122,81 @@ static const struct device_type qeth_osn_devtype = { ...@@ -5094,13 +5122,81 @@ static const struct device_type qeth_osn_devtype = {
.groups = qeth_osn_attr_groups, .groups = qeth_osn_attr_groups,
}; };
#define DBF_NAME_LEN 20
struct qeth_dbf_entry {
char dbf_name[DBF_NAME_LEN];
debug_info_t *dbf_info;
struct list_head dbf_list;
};
static LIST_HEAD(qeth_dbf_list);
static DEFINE_MUTEX(qeth_dbf_list_mutex);
static debug_info_t *qeth_get_dbf_entry(char *name)
{
struct qeth_dbf_entry *entry;
debug_info_t *rc = NULL;
mutex_lock(&qeth_dbf_list_mutex);
list_for_each_entry(entry, &qeth_dbf_list, dbf_list) {
if (strcmp(entry->dbf_name, name) == 0) {
rc = entry->dbf_info;
break;
}
}
mutex_unlock(&qeth_dbf_list_mutex);
return rc;
}
static int qeth_add_dbf_entry(struct qeth_card *card, char *name)
{
struct qeth_dbf_entry *new_entry;
card->debug = debug_register(name, 2, 1, 8);
if (!card->debug) {
QETH_DBF_TEXT_(SETUP, 2, "%s", "qcdbf");
goto err;
}
if (debug_register_view(card->debug, &debug_hex_ascii_view))
goto err_dbg;
new_entry = kzalloc(sizeof(struct qeth_dbf_entry), GFP_KERNEL);
if (!new_entry)
goto err_dbg;
strncpy(new_entry->dbf_name, name, DBF_NAME_LEN);
new_entry->dbf_info = card->debug;
mutex_lock(&qeth_dbf_list_mutex);
list_add(&new_entry->dbf_list, &qeth_dbf_list);
mutex_unlock(&qeth_dbf_list_mutex);
return 0;
err_dbg:
debug_unregister(card->debug);
err:
return -ENOMEM;
}
static void qeth_clear_dbf_list(void)
{
struct qeth_dbf_entry *entry, *tmp;
mutex_lock(&qeth_dbf_list_mutex);
list_for_each_entry_safe(entry, tmp, &qeth_dbf_list, dbf_list) {
list_del(&entry->dbf_list);
debug_unregister(entry->dbf_info);
kfree(entry);
}
mutex_unlock(&qeth_dbf_list_mutex);
}
static int qeth_core_probe_device(struct ccwgroup_device *gdev) static int qeth_core_probe_device(struct ccwgroup_device *gdev)
{ {
struct qeth_card *card; struct qeth_card *card;
struct device *dev; struct device *dev;
int rc; int rc;
unsigned long flags; unsigned long flags;
char dbf_name[20]; char dbf_name[DBF_NAME_LEN];
QETH_DBF_TEXT(SETUP, 2, "probedev"); QETH_DBF_TEXT(SETUP, 2, "probedev");
...@@ -5119,13 +5215,12 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) ...@@ -5119,13 +5215,12 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
snprintf(dbf_name, sizeof(dbf_name), "qeth_card_%s", snprintf(dbf_name, sizeof(dbf_name), "qeth_card_%s",
dev_name(&gdev->dev)); dev_name(&gdev->dev));
card->debug = debug_register(dbf_name, 2, 1, 8); card->debug = qeth_get_dbf_entry(dbf_name);
if (!card->debug) { if (!card->debug) {
QETH_DBF_TEXT_(SETUP, 2, "%s", "qcdbf"); rc = qeth_add_dbf_entry(card, dbf_name);
rc = -ENOMEM; if (rc)
goto err_card; goto err_card;
} }
debug_register_view(card->debug, &debug_hex_ascii_view);
card->read.ccwdev = gdev->cdev[0]; card->read.ccwdev = gdev->cdev[0];
card->write.ccwdev = gdev->cdev[1]; card->write.ccwdev = gdev->cdev[1];
...@@ -5139,12 +5234,12 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) ...@@ -5139,12 +5234,12 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
rc = qeth_determine_card_type(card); rc = qeth_determine_card_type(card);
if (rc) { if (rc) {
QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
goto err_dbf; goto err_card;
} }
rc = qeth_setup_card(card); rc = qeth_setup_card(card);
if (rc) { if (rc) {
QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
goto err_dbf; goto err_card;
} }
if (card->info.type == QETH_CARD_TYPE_OSN) if (card->info.type == QETH_CARD_TYPE_OSN)
...@@ -5157,7 +5252,7 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) ...@@ -5157,7 +5252,7 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
case QETH_CARD_TYPE_OSM: case QETH_CARD_TYPE_OSM:
rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2); rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2);
if (rc) if (rc)
goto err_dbf; goto err_card;
rc = card->discipline->setup(card->gdev); rc = card->discipline->setup(card->gdev);
if (rc) if (rc)
goto err_disc; goto err_disc;
...@@ -5176,8 +5271,6 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) ...@@ -5176,8 +5271,6 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
err_disc: err_disc:
qeth_core_free_discipline(card); qeth_core_free_discipline(card);
err_dbf:
debug_unregister(card->debug);
err_card: err_card:
qeth_core_free_card(card); qeth_core_free_card(card);
err_dev: err_dev:
...@@ -5197,7 +5290,6 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev) ...@@ -5197,7 +5290,6 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev)
qeth_core_free_discipline(card); qeth_core_free_discipline(card);
} }
debug_unregister(card->debug);
write_lock_irqsave(&qeth_core_card_list.rwlock, flags); write_lock_irqsave(&qeth_core_card_list.rwlock, flags);
list_del(&card->list); list_del(&card->list);
write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags); write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
...@@ -5551,9 +5643,12 @@ static int __init qeth_core_init(void) ...@@ -5551,9 +5643,12 @@ static int __init qeth_core_init(void)
pr_info("loading core functions\n"); pr_info("loading core functions\n");
INIT_LIST_HEAD(&qeth_core_card_list.list); INIT_LIST_HEAD(&qeth_core_card_list.list);
INIT_LIST_HEAD(&qeth_dbf_list);
rwlock_init(&qeth_core_card_list.rwlock); rwlock_init(&qeth_core_card_list.rwlock);
mutex_init(&qeth_mod_mutex); mutex_init(&qeth_mod_mutex);
qeth_wq = create_singlethread_workqueue("qeth_wq");
rc = qeth_register_dbf_views(); rc = qeth_register_dbf_views();
if (rc) if (rc)
goto out_err; goto out_err;
...@@ -5600,6 +5695,8 @@ static int __init qeth_core_init(void) ...@@ -5600,6 +5695,8 @@ static int __init qeth_core_init(void)
static void __exit qeth_core_exit(void) static void __exit qeth_core_exit(void)
{ {
qeth_clear_dbf_list();
destroy_workqueue(qeth_wq);
ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver); ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver);
ccw_driver_unregister(&qeth_ccw_driver); ccw_driver_unregister(&qeth_ccw_driver);
kmem_cache_destroy(qeth_qdio_outbuf_cache); kmem_cache_destroy(qeth_qdio_outbuf_cache);
......
...@@ -204,6 +204,7 @@ static struct ipa_rc_msg qeth_ipa_rc_msg[] = { ...@@ -204,6 +204,7 @@ static struct ipa_rc_msg qeth_ipa_rc_msg[] = {
{IPA_RC_INVALID_SETRTG_INDICATOR, "Invalid SETRTG indicator"}, {IPA_RC_INVALID_SETRTG_INDICATOR, "Invalid SETRTG indicator"},
{IPA_RC_MC_ADDR_ALREADY_DEFINED, "Multicast address already defined"}, {IPA_RC_MC_ADDR_ALREADY_DEFINED, "Multicast address already defined"},
{IPA_RC_LAN_OFFLINE, "STRTLAN_LAN_DISABLED - LAN offline"}, {IPA_RC_LAN_OFFLINE, "STRTLAN_LAN_DISABLED - LAN offline"},
{IPA_RC_VEPA_TO_VEB_TRANSITION, "Adj. switch disabled port mode RR"},
{IPA_RC_INVALID_IP_VERSION2, "Invalid IP version"}, {IPA_RC_INVALID_IP_VERSION2, "Invalid IP version"},
{IPA_RC_ENOMEM, "Memory problem"}, {IPA_RC_ENOMEM, "Memory problem"},
{IPA_RC_FFFF, "Unknown Error"} {IPA_RC_FFFF, "Unknown Error"}
......
...@@ -177,6 +177,7 @@ enum qeth_ipa_return_codes { ...@@ -177,6 +177,7 @@ enum qeth_ipa_return_codes {
IPA_RC_INVALID_SETRTG_INDICATOR = 0xe012, IPA_RC_INVALID_SETRTG_INDICATOR = 0xe012,
IPA_RC_MC_ADDR_ALREADY_DEFINED = 0xe013, IPA_RC_MC_ADDR_ALREADY_DEFINED = 0xe013,
IPA_RC_LAN_OFFLINE = 0xe080, IPA_RC_LAN_OFFLINE = 0xe080,
IPA_RC_VEPA_TO_VEB_TRANSITION = 0xe090,
IPA_RC_INVALID_IP_VERSION2 = 0xf001, IPA_RC_INVALID_IP_VERSION2 = 0xf001,
IPA_RC_ENOMEM = 0xfffe, IPA_RC_ENOMEM = 0xfffe,
IPA_RC_FFFF = 0xffff IPA_RC_FFFF = 0xffff
...@@ -269,6 +270,9 @@ enum qeth_ipa_set_access_mode_rc { ...@@ -269,6 +270,9 @@ enum qeth_ipa_set_access_mode_rc {
SET_ACCESS_CTRL_RC_ALREADY_ISOLATED = 0x0010, SET_ACCESS_CTRL_RC_ALREADY_ISOLATED = 0x0010,
SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER = 0x0014, SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER = 0x0014,
SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF = 0x0018, SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF = 0x0018,
SET_ACCESS_CTRL_RC_REFLREL_UNSUPPORTED = 0x0022,
SET_ACCESS_CTRL_RC_REFLREL_FAILED = 0x0024,
SET_ACCESS_CTRL_RC_REFLREL_DEACT_FAILED = 0x0028,
}; };
...@@ -386,6 +390,7 @@ struct qeth_snmp_ureq { ...@@ -386,6 +390,7 @@ struct qeth_snmp_ureq {
/* SET_ACCESS_CONTROL: same format for request and reply */ /* SET_ACCESS_CONTROL: same format for request and reply */
struct qeth_set_access_ctrl { struct qeth_set_access_ctrl {
__u32 subcmd_code; __u32 subcmd_code;
__u8 reserved[8];
} __attribute__((packed)); } __attribute__((packed));
struct qeth_query_oat { struct qeth_query_oat {
......
...@@ -513,10 +513,11 @@ static ssize_t qeth_dev_isolation_store(struct device *dev, ...@@ -513,10 +513,11 @@ static ssize_t qeth_dev_isolation_store(struct device *dev,
rc = count; rc = count;
/* defer IP assist if device is offline (until discipline->set_online)*/ /* defer IP assist if device is offline (until discipline->set_online)*/
card->options.prev_isolation = card->options.isolation;
card->options.isolation = isolation; card->options.isolation = isolation;
if (card->state == CARD_STATE_SOFTSETUP || if (card->state == CARD_STATE_SOFTSETUP ||
card->state == CARD_STATE_UP) { card->state == CARD_STATE_UP) {
int ipa_rc = qeth_set_access_ctrl_online(card); int ipa_rc = qeth_set_access_ctrl_online(card, 1);
if (ipa_rc != 0) if (ipa_rc != 0)
rc = ipa_rc; rc = ipa_rc;
} }
......
...@@ -1025,9 +1025,14 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) ...@@ -1025,9 +1025,14 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
contin: contin:
if ((card->info.type == QETH_CARD_TYPE_OSD) || if ((card->info.type == QETH_CARD_TYPE_OSD) ||
(card->info.type == QETH_CARD_TYPE_OSX)) (card->info.type == QETH_CARD_TYPE_OSX)) {
/* configure isolation level */ /* configure isolation level */
qeth_set_access_ctrl_online(card); rc = qeth_set_access_ctrl_online(card, 0);
if (rc) {
rc = -ENODEV;
goto out_remove;
}
}
if (card->info.type != QETH_CARD_TYPE_OSN && if (card->info.type != QETH_CARD_TYPE_OSN &&
card->info.type != QETH_CARD_TYPE_OSM) card->info.type != QETH_CARD_TYPE_OSM)
...@@ -1144,12 +1149,9 @@ static int qeth_l2_recover(void *ptr) ...@@ -1144,12 +1149,9 @@ static int qeth_l2_recover(void *ptr)
dev_info(&card->gdev->dev, dev_info(&card->gdev->dev,
"Device successfully recovered!\n"); "Device successfully recovered!\n");
else { else {
if (rtnl_trylock()) { qeth_close_dev(card);
dev_close(card->dev); dev_warn(&card->gdev->dev, "The qeth device driver "
rtnl_unlock();
dev_warn(&card->gdev->dev, "The qeth device driver "
"failed to recover an error on the device\n"); "failed to recover an error on the device\n");
}
} }
qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
......
...@@ -1449,7 +1449,8 @@ static int qeth_l3_start_ipassists(struct qeth_card *card) ...@@ -1449,7 +1449,8 @@ static int qeth_l3_start_ipassists(struct qeth_card *card)
{ {
QETH_CARD_TEXT(card, 3, "strtipas"); QETH_CARD_TEXT(card, 3, "strtipas");
qeth_set_access_ctrl_online(card); /* go on*/ if (qeth_set_access_ctrl_online(card, 0))
return -EIO;
qeth_l3_start_ipa_arp_processing(card); /* go on*/ qeth_l3_start_ipa_arp_processing(card); /* go on*/
qeth_l3_start_ipa_ip_fragmentation(card); /* go on*/ qeth_l3_start_ipa_ip_fragmentation(card); /* go on*/
qeth_l3_start_ipa_source_mac(card); /* go on*/ qeth_l3_start_ipa_source_mac(card); /* go on*/
...@@ -3388,8 +3389,10 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) ...@@ -3388,8 +3389,10 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
if (!card->options.sniffer) { if (!card->options.sniffer) {
rc = qeth_l3_start_ipassists(card); rc = qeth_l3_start_ipassists(card);
if (rc) if (rc) {
QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
goto out_remove;
}
rc = qeth_l3_setrouting_v4(card); rc = qeth_l3_setrouting_v4(card);
if (rc) if (rc)
QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc); QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc);
...@@ -3511,12 +3514,9 @@ static int qeth_l3_recover(void *ptr) ...@@ -3511,12 +3514,9 @@ static int qeth_l3_recover(void *ptr)
dev_info(&card->gdev->dev, dev_info(&card->gdev->dev,
"Device successfully recovered!\n"); "Device successfully recovered!\n");
else { else {
if (rtnl_trylock()) { qeth_close_dev(card);
dev_close(card->dev); dev_warn(&card->gdev->dev, "The qeth device driver "
rtnl_unlock();
dev_warn(&card->gdev->dev, "The qeth device driver "
"failed to recover an error on the device\n"); "failed to recover an error on the device\n");
}
} }
qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册