Commit dc319c4b authored by David S. Miller's avatar David S. Miller

Merge branch 's390-net-fixes'

Julian Wiedmann says:

====================
s390/net fixes

some qeth fixes for -net, the OSM/OSN one being the most crucial.
Please also queue these up for stable.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b6016166 ebccc739
...@@ -701,6 +701,7 @@ enum qeth_discipline_id { ...@@ -701,6 +701,7 @@ enum qeth_discipline_id {
}; };
struct qeth_discipline { struct qeth_discipline {
const struct device_type *devtype;
void (*start_poll)(struct ccw_device *, int, unsigned long); void (*start_poll)(struct ccw_device *, int, unsigned long);
qdio_handler_t *input_handler; qdio_handler_t *input_handler;
qdio_handler_t *output_handler; qdio_handler_t *output_handler;
...@@ -875,6 +876,9 @@ extern struct qeth_discipline qeth_l2_discipline; ...@@ -875,6 +876,9 @@ extern struct qeth_discipline qeth_l2_discipline;
extern struct qeth_discipline qeth_l3_discipline; extern struct qeth_discipline qeth_l3_discipline;
extern const struct attribute_group *qeth_generic_attr_groups[]; extern const struct attribute_group *qeth_generic_attr_groups[];
extern const struct attribute_group *qeth_osn_attr_groups[]; extern const struct attribute_group *qeth_osn_attr_groups[];
extern const struct attribute_group qeth_device_attr_group;
extern const struct attribute_group qeth_device_blkt_group;
extern const struct device_type qeth_generic_devtype;
extern struct workqueue_struct *qeth_wq; extern struct workqueue_struct *qeth_wq;
int qeth_card_hw_is_reachable(struct qeth_card *); int qeth_card_hw_is_reachable(struct qeth_card *);
......
...@@ -5530,10 +5530,12 @@ void qeth_core_free_discipline(struct qeth_card *card) ...@@ -5530,10 +5530,12 @@ void qeth_core_free_discipline(struct qeth_card *card)
card->discipline = NULL; card->discipline = NULL;
} }
static const struct device_type qeth_generic_devtype = { const struct device_type qeth_generic_devtype = {
.name = "qeth_generic", .name = "qeth_generic",
.groups = qeth_generic_attr_groups, .groups = qeth_generic_attr_groups,
}; };
EXPORT_SYMBOL_GPL(qeth_generic_devtype);
static const struct device_type qeth_osn_devtype = { static const struct device_type qeth_osn_devtype = {
.name = "qeth_osn", .name = "qeth_osn",
.groups = qeth_osn_attr_groups, .groups = qeth_osn_attr_groups,
...@@ -5659,23 +5661,22 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) ...@@ -5659,23 +5661,22 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
goto err_card; goto err_card;
} }
if (card->info.type == QETH_CARD_TYPE_OSN)
gdev->dev.type = &qeth_osn_devtype;
else
gdev->dev.type = &qeth_generic_devtype;
switch (card->info.type) { switch (card->info.type) {
case QETH_CARD_TYPE_OSN: case QETH_CARD_TYPE_OSN:
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_card; goto err_card;
gdev->dev.type = (card->info.type != QETH_CARD_TYPE_OSN)
? card->discipline->devtype
: &qeth_osn_devtype;
rc = card->discipline->setup(card->gdev); rc = card->discipline->setup(card->gdev);
if (rc) if (rc)
goto err_disc; goto err_disc;
case QETH_CARD_TYPE_OSD: break;
case QETH_CARD_TYPE_OSX:
default: default:
gdev->dev.type = &qeth_generic_devtype;
break; break;
} }
...@@ -5731,8 +5732,10 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev) ...@@ -5731,8 +5732,10 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev)
if (rc) if (rc)
goto err; goto err;
rc = card->discipline->setup(card->gdev); rc = card->discipline->setup(card->gdev);
if (rc) if (rc) {
qeth_core_free_discipline(card);
goto err; goto err;
}
} }
rc = card->discipline->set_online(gdev); rc = card->discipline->set_online(gdev);
err: err:
......
...@@ -413,12 +413,16 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, ...@@ -413,12 +413,16 @@ static ssize_t qeth_dev_layer2_store(struct device *dev,
if (card->options.layer2 == newdis) if (card->options.layer2 == newdis)
goto out; goto out;
else { if (card->info.type == QETH_CARD_TYPE_OSM) {
card->info.mac_bits = 0; /* fixed layer, can't switch */
if (card->discipline) { rc = -EOPNOTSUPP;
card->discipline->remove(card->gdev); goto out;
qeth_core_free_discipline(card); }
}
card->info.mac_bits = 0;
if (card->discipline) {
card->discipline->remove(card->gdev);
qeth_core_free_discipline(card);
} }
rc = qeth_core_load_discipline(card, newdis); rc = qeth_core_load_discipline(card, newdis);
...@@ -426,6 +430,8 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, ...@@ -426,6 +430,8 @@ static ssize_t qeth_dev_layer2_store(struct device *dev,
goto out; goto out;
rc = card->discipline->setup(card->gdev); rc = card->discipline->setup(card->gdev);
if (rc)
qeth_core_free_discipline(card);
out: out:
mutex_unlock(&card->discipline_mutex); mutex_unlock(&card->discipline_mutex);
return rc ? rc : count; return rc ? rc : count;
...@@ -703,10 +709,11 @@ static struct attribute *qeth_blkt_device_attrs[] = { ...@@ -703,10 +709,11 @@ static struct attribute *qeth_blkt_device_attrs[] = {
&dev_attr_inter_jumbo.attr, &dev_attr_inter_jumbo.attr,
NULL, NULL,
}; };
static struct attribute_group qeth_device_blkt_group = { const struct attribute_group qeth_device_blkt_group = {
.name = "blkt", .name = "blkt",
.attrs = qeth_blkt_device_attrs, .attrs = qeth_blkt_device_attrs,
}; };
EXPORT_SYMBOL_GPL(qeth_device_blkt_group);
static struct attribute *qeth_device_attrs[] = { static struct attribute *qeth_device_attrs[] = {
&dev_attr_state.attr, &dev_attr_state.attr,
...@@ -726,9 +733,10 @@ static struct attribute *qeth_device_attrs[] = { ...@@ -726,9 +733,10 @@ static struct attribute *qeth_device_attrs[] = {
&dev_attr_switch_attrs.attr, &dev_attr_switch_attrs.attr,
NULL, NULL,
}; };
static struct attribute_group qeth_device_attr_group = { const struct attribute_group qeth_device_attr_group = {
.attrs = qeth_device_attrs, .attrs = qeth_device_attrs,
}; };
EXPORT_SYMBOL_GPL(qeth_device_attr_group);
const struct attribute_group *qeth_generic_attr_groups[] = { const struct attribute_group *qeth_generic_attr_groups[] = {
&qeth_device_attr_group, &qeth_device_attr_group,
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include "qeth_core.h" #include "qeth_core.h"
extern const struct attribute_group *qeth_l2_attr_groups[];
int qeth_l2_create_device_attributes(struct device *); int qeth_l2_create_device_attributes(struct device *);
void qeth_l2_remove_device_attributes(struct device *); void qeth_l2_remove_device_attributes(struct device *);
void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card); void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card);
......
...@@ -880,11 +880,21 @@ static int qeth_l2_stop(struct net_device *dev) ...@@ -880,11 +880,21 @@ static int qeth_l2_stop(struct net_device *dev)
return 0; return 0;
} }
static const struct device_type qeth_l2_devtype = {
.name = "qeth_layer2",
.groups = qeth_l2_attr_groups,
};
static int qeth_l2_probe_device(struct ccwgroup_device *gdev) static int qeth_l2_probe_device(struct ccwgroup_device *gdev)
{ {
struct qeth_card *card = dev_get_drvdata(&gdev->dev); struct qeth_card *card = dev_get_drvdata(&gdev->dev);
int rc;
qeth_l2_create_device_attributes(&gdev->dev); if (gdev->dev.type == &qeth_generic_devtype) {
rc = qeth_l2_create_device_attributes(&gdev->dev);
if (rc)
return rc;
}
INIT_LIST_HEAD(&card->vid_list); INIT_LIST_HEAD(&card->vid_list);
hash_init(card->mac_htable); hash_init(card->mac_htable);
card->options.layer2 = 1; card->options.layer2 = 1;
...@@ -896,7 +906,8 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev) ...@@ -896,7 +906,8 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev)
{ {
struct qeth_card *card = dev_get_drvdata(&cgdev->dev); struct qeth_card *card = dev_get_drvdata(&cgdev->dev);
qeth_l2_remove_device_attributes(&cgdev->dev); if (cgdev->dev.type == &qeth_generic_devtype)
qeth_l2_remove_device_attributes(&cgdev->dev);
qeth_set_allowed_threads(card, 0, 1); qeth_set_allowed_threads(card, 0, 1);
wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
...@@ -954,7 +965,6 @@ static int qeth_l2_setup_netdev(struct qeth_card *card) ...@@ -954,7 +965,6 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
case QETH_CARD_TYPE_OSN: case QETH_CARD_TYPE_OSN:
card->dev = alloc_netdev(0, "osn%d", NET_NAME_UNKNOWN, card->dev = alloc_netdev(0, "osn%d", NET_NAME_UNKNOWN,
ether_setup); ether_setup);
card->dev->flags |= IFF_NOARP;
break; break;
default: default:
card->dev = alloc_etherdev(0); card->dev = alloc_etherdev(0);
...@@ -969,9 +979,12 @@ static int qeth_l2_setup_netdev(struct qeth_card *card) ...@@ -969,9 +979,12 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
card->dev->min_mtu = 64; card->dev->min_mtu = 64;
card->dev->max_mtu = ETH_MAX_MTU; card->dev->max_mtu = ETH_MAX_MTU;
card->dev->netdev_ops = &qeth_l2_netdev_ops; card->dev->netdev_ops = &qeth_l2_netdev_ops;
card->dev->ethtool_ops = if (card->info.type == QETH_CARD_TYPE_OSN) {
(card->info.type != QETH_CARD_TYPE_OSN) ? card->dev->ethtool_ops = &qeth_l2_osn_ops;
&qeth_l2_ethtool_ops : &qeth_l2_osn_ops; card->dev->flags |= IFF_NOARP;
} else {
card->dev->ethtool_ops = &qeth_l2_ethtool_ops;
}
card->dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; card->dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
if (card->info.type == QETH_CARD_TYPE_OSD && !card->info.guestlan) { if (card->info.type == QETH_CARD_TYPE_OSD && !card->info.guestlan) {
card->dev->hw_features = NETIF_F_SG; card->dev->hw_features = NETIF_F_SG;
...@@ -1269,6 +1282,7 @@ static int qeth_l2_control_event(struct qeth_card *card, ...@@ -1269,6 +1282,7 @@ static int qeth_l2_control_event(struct qeth_card *card,
} }
struct qeth_discipline qeth_l2_discipline = { struct qeth_discipline qeth_l2_discipline = {
.devtype = &qeth_l2_devtype,
.start_poll = qeth_qdio_start_poll, .start_poll = qeth_qdio_start_poll,
.input_handler = (qdio_handler_t *) qeth_qdio_input_handler, .input_handler = (qdio_handler_t *) qeth_qdio_input_handler,
.output_handler = (qdio_handler_t *) qeth_qdio_output_handler, .output_handler = (qdio_handler_t *) qeth_qdio_output_handler,
......
...@@ -269,3 +269,11 @@ void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card) ...@@ -269,3 +269,11 @@ void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card)
} else } else
qeth_bridgeport_an_set(card, 0); qeth_bridgeport_an_set(card, 0);
} }
const struct attribute_group *qeth_l2_attr_groups[] = {
&qeth_device_attr_group,
&qeth_device_blkt_group,
/* l2 specific, see l2_{create,remove}_device_attributes(): */
&qeth_l2_bridgeport_attr_group,
NULL,
};
...@@ -3039,8 +3039,13 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) ...@@ -3039,8 +3039,13 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
static int qeth_l3_probe_device(struct ccwgroup_device *gdev) static int qeth_l3_probe_device(struct ccwgroup_device *gdev)
{ {
struct qeth_card *card = dev_get_drvdata(&gdev->dev); struct qeth_card *card = dev_get_drvdata(&gdev->dev);
int rc;
qeth_l3_create_device_attributes(&gdev->dev); rc = qeth_l3_create_device_attributes(&gdev->dev);
if (rc)
return rc;
hash_init(card->ip_htable);
hash_init(card->ip_mc_htable);
card->options.layer2 = 0; card->options.layer2 = 0;
card->info.hwtrap = 0; card->info.hwtrap = 0;
return 0; return 0;
...@@ -3306,6 +3311,7 @@ static int qeth_l3_control_event(struct qeth_card *card, ...@@ -3306,6 +3311,7 @@ static int qeth_l3_control_event(struct qeth_card *card,
} }
struct qeth_discipline qeth_l3_discipline = { struct qeth_discipline qeth_l3_discipline = {
.devtype = &qeth_generic_devtype,
.start_poll = qeth_qdio_start_poll, .start_poll = qeth_qdio_start_poll,
.input_handler = (qdio_handler_t *) qeth_qdio_input_handler, .input_handler = (qdio_handler_t *) qeth_qdio_input_handler,
.output_handler = (qdio_handler_t *) qeth_qdio_output_handler, .output_handler = (qdio_handler_t *) qeth_qdio_output_handler,
......
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