mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-04 03:33:58 +08:00
Merge branch 's390-qeth-updates-2020-11-17'
Julian Wiedmann says: ==================== s390/qeth: updates 2020-11-17 This brings some cleanups, and a bunch of improvements for our .get_link_ksettings() code. ==================== Link: https://lore.kernel.org/r/20201117161520.1089-1-jwi@linux.ibm.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
aa8f2cbd57
@ -701,6 +701,19 @@ enum qeth_pnso_mode {
|
||||
QETH_PNSO_ADDR_INFO,
|
||||
};
|
||||
|
||||
enum qeth_link_mode {
|
||||
QETH_LINK_MODE_UNKNOWN,
|
||||
QETH_LINK_MODE_FIBRE_SHORT,
|
||||
QETH_LINK_MODE_FIBRE_LONG,
|
||||
};
|
||||
|
||||
struct qeth_link_info {
|
||||
u32 speed;
|
||||
u8 duplex;
|
||||
u8 port;
|
||||
enum qeth_link_mode link_mode;
|
||||
};
|
||||
|
||||
#define QETH_BROADCAST_WITH_ECHO 0x01
|
||||
#define QETH_BROADCAST_WITHOUT_ECHO 0x02
|
||||
struct qeth_card_info {
|
||||
@ -732,6 +745,7 @@ struct qeth_card_info {
|
||||
struct qeth_card_blkt blkt;
|
||||
__u32 diagass_support;
|
||||
__u32 hwtrap;
|
||||
struct qeth_link_info link_info;
|
||||
};
|
||||
|
||||
enum qeth_discipline_id {
|
||||
@ -796,12 +810,6 @@ struct qeth_rx {
|
||||
u8 bufs_refill;
|
||||
};
|
||||
|
||||
struct carrier_info {
|
||||
__u8 card_type;
|
||||
__u16 port_mode;
|
||||
__u32 port_speed;
|
||||
};
|
||||
|
||||
struct qeth_switch_info {
|
||||
__u32 capabilities;
|
||||
__u32 settings;
|
||||
@ -1108,7 +1116,7 @@ void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
|
||||
int qeth_query_switch_attributes(struct qeth_card *card,
|
||||
struct qeth_switch_info *sw_info);
|
||||
int qeth_query_card_info(struct qeth_card *card,
|
||||
struct carrier_info *carrier_info);
|
||||
struct qeth_link_info *link_info);
|
||||
int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
|
||||
enum qeth_ipa_isolation_modes mode);
|
||||
|
||||
|
@ -4868,8 +4868,8 @@ out_free:
|
||||
static int qeth_query_card_info_cb(struct qeth_card *card,
|
||||
struct qeth_reply *reply, unsigned long data)
|
||||
{
|
||||
struct carrier_info *carrier_info = (struct carrier_info *)reply->param;
|
||||
struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *)data;
|
||||
struct qeth_link_info *link_info = reply->param;
|
||||
struct qeth_query_card_info *card_info;
|
||||
|
||||
QETH_CARD_TEXT(card, 2, "qcrdincb");
|
||||
@ -4877,14 +4877,67 @@ static int qeth_query_card_info_cb(struct qeth_card *card,
|
||||
return -EIO;
|
||||
|
||||
card_info = &cmd->data.setadapterparms.data.card_info;
|
||||
carrier_info->card_type = card_info->card_type;
|
||||
carrier_info->port_mode = card_info->port_mode;
|
||||
carrier_info->port_speed = card_info->port_speed;
|
||||
netdev_dbg(card->dev,
|
||||
"card info: card_type=0x%02x, port_mode=0x%04x, port_speed=0x%08x\n",
|
||||
card_info->card_type, card_info->port_mode,
|
||||
card_info->port_speed);
|
||||
|
||||
switch (card_info->port_mode) {
|
||||
case CARD_INFO_PORTM_FULLDUPLEX:
|
||||
link_info->duplex = DUPLEX_FULL;
|
||||
break;
|
||||
case CARD_INFO_PORTM_HALFDUPLEX:
|
||||
link_info->duplex = DUPLEX_HALF;
|
||||
break;
|
||||
default:
|
||||
link_info->duplex = DUPLEX_UNKNOWN;
|
||||
}
|
||||
|
||||
switch (card_info->card_type) {
|
||||
case CARD_INFO_TYPE_1G_COPPER_A:
|
||||
case CARD_INFO_TYPE_1G_COPPER_B:
|
||||
link_info->speed = SPEED_1000;
|
||||
link_info->port = PORT_TP;
|
||||
break;
|
||||
case CARD_INFO_TYPE_1G_FIBRE_A:
|
||||
case CARD_INFO_TYPE_1G_FIBRE_B:
|
||||
link_info->speed = SPEED_1000;
|
||||
link_info->port = PORT_FIBRE;
|
||||
break;
|
||||
case CARD_INFO_TYPE_10G_FIBRE_A:
|
||||
case CARD_INFO_TYPE_10G_FIBRE_B:
|
||||
link_info->speed = SPEED_10000;
|
||||
link_info->port = PORT_FIBRE;
|
||||
break;
|
||||
default:
|
||||
switch (card_info->port_speed) {
|
||||
case CARD_INFO_PORTS_10M:
|
||||
link_info->speed = SPEED_10;
|
||||
break;
|
||||
case CARD_INFO_PORTS_100M:
|
||||
link_info->speed = SPEED_100;
|
||||
break;
|
||||
case CARD_INFO_PORTS_1G:
|
||||
link_info->speed = SPEED_1000;
|
||||
break;
|
||||
case CARD_INFO_PORTS_10G:
|
||||
link_info->speed = SPEED_10000;
|
||||
break;
|
||||
case CARD_INFO_PORTS_25G:
|
||||
link_info->speed = SPEED_25000;
|
||||
break;
|
||||
default:
|
||||
link_info->speed = SPEED_UNKNOWN;
|
||||
}
|
||||
|
||||
link_info->port = PORT_OTHER;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qeth_query_card_info(struct qeth_card *card,
|
||||
struct carrier_info *carrier_info)
|
||||
struct qeth_link_info *link_info)
|
||||
{
|
||||
struct qeth_cmd_buffer *iob;
|
||||
|
||||
@ -4894,8 +4947,162 @@ int qeth_query_card_info(struct qeth_card *card,
|
||||
iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_CARD_INFO, 0);
|
||||
if (!iob)
|
||||
return -ENOMEM;
|
||||
return qeth_send_ipa_cmd(card, iob, qeth_query_card_info_cb,
|
||||
(void *)carrier_info);
|
||||
|
||||
return qeth_send_ipa_cmd(card, iob, qeth_query_card_info_cb, link_info);
|
||||
}
|
||||
|
||||
static int qeth_init_link_info_oat_cb(struct qeth_card *card,
|
||||
struct qeth_reply *reply_priv,
|
||||
unsigned long data)
|
||||
{
|
||||
struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *)data;
|
||||
struct qeth_link_info *link_info = reply_priv->param;
|
||||
struct qeth_query_oat_physical_if *phys_if;
|
||||
struct qeth_query_oat_reply *reply;
|
||||
|
||||
if (qeth_setadpparms_inspect_rc(cmd))
|
||||
return -EIO;
|
||||
|
||||
/* Multi-part reply is unexpected, don't bother: */
|
||||
if (cmd->data.setadapterparms.hdr.used_total > 1)
|
||||
return -EINVAL;
|
||||
|
||||
/* Expect the reply to start with phys_if data: */
|
||||
reply = &cmd->data.setadapterparms.data.query_oat.reply[0];
|
||||
if (reply->type != QETH_QOAT_REPLY_TYPE_PHYS_IF ||
|
||||
reply->length < sizeof(*reply))
|
||||
return -EINVAL;
|
||||
|
||||
phys_if = &reply->phys_if;
|
||||
|
||||
switch (phys_if->speed_duplex) {
|
||||
case QETH_QOAT_PHYS_SPEED_10M_HALF:
|
||||
link_info->speed = SPEED_10;
|
||||
link_info->duplex = DUPLEX_HALF;
|
||||
break;
|
||||
case QETH_QOAT_PHYS_SPEED_10M_FULL:
|
||||
link_info->speed = SPEED_10;
|
||||
link_info->duplex = DUPLEX_FULL;
|
||||
break;
|
||||
case QETH_QOAT_PHYS_SPEED_100M_HALF:
|
||||
link_info->speed = SPEED_100;
|
||||
link_info->duplex = DUPLEX_HALF;
|
||||
break;
|
||||
case QETH_QOAT_PHYS_SPEED_100M_FULL:
|
||||
link_info->speed = SPEED_100;
|
||||
link_info->duplex = DUPLEX_FULL;
|
||||
break;
|
||||
case QETH_QOAT_PHYS_SPEED_1000M_HALF:
|
||||
link_info->speed = SPEED_1000;
|
||||
link_info->duplex = DUPLEX_HALF;
|
||||
break;
|
||||
case QETH_QOAT_PHYS_SPEED_1000M_FULL:
|
||||
link_info->speed = SPEED_1000;
|
||||
link_info->duplex = DUPLEX_FULL;
|
||||
break;
|
||||
case QETH_QOAT_PHYS_SPEED_10G_FULL:
|
||||
link_info->speed = SPEED_10000;
|
||||
link_info->duplex = DUPLEX_FULL;
|
||||
break;
|
||||
case QETH_QOAT_PHYS_SPEED_25G_FULL:
|
||||
link_info->speed = SPEED_25000;
|
||||
link_info->duplex = DUPLEX_FULL;
|
||||
break;
|
||||
case QETH_QOAT_PHYS_SPEED_UNKNOWN:
|
||||
default:
|
||||
link_info->speed = SPEED_UNKNOWN;
|
||||
link_info->duplex = DUPLEX_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (phys_if->media_type) {
|
||||
case QETH_QOAT_PHYS_MEDIA_COPPER:
|
||||
link_info->port = PORT_TP;
|
||||
link_info->link_mode = QETH_LINK_MODE_UNKNOWN;
|
||||
break;
|
||||
case QETH_QOAT_PHYS_MEDIA_FIBRE_SHORT:
|
||||
link_info->port = PORT_FIBRE;
|
||||
link_info->link_mode = QETH_LINK_MODE_FIBRE_SHORT;
|
||||
break;
|
||||
case QETH_QOAT_PHYS_MEDIA_FIBRE_LONG:
|
||||
link_info->port = PORT_FIBRE;
|
||||
link_info->link_mode = QETH_LINK_MODE_FIBRE_LONG;
|
||||
break;
|
||||
default:
|
||||
link_info->port = PORT_OTHER;
|
||||
link_info->link_mode = QETH_LINK_MODE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void qeth_init_link_info(struct qeth_card *card)
|
||||
{
|
||||
card->info.link_info.duplex = DUPLEX_FULL;
|
||||
|
||||
if (IS_IQD(card) || IS_VM_NIC(card)) {
|
||||
card->info.link_info.speed = SPEED_10000;
|
||||
card->info.link_info.port = PORT_FIBRE;
|
||||
card->info.link_info.link_mode = QETH_LINK_MODE_FIBRE_SHORT;
|
||||
} else {
|
||||
switch (card->info.link_type) {
|
||||
case QETH_LINK_TYPE_FAST_ETH:
|
||||
case QETH_LINK_TYPE_LANE_ETH100:
|
||||
card->info.link_info.speed = SPEED_100;
|
||||
card->info.link_info.port = PORT_TP;
|
||||
break;
|
||||
case QETH_LINK_TYPE_GBIT_ETH:
|
||||
case QETH_LINK_TYPE_LANE_ETH1000:
|
||||
card->info.link_info.speed = SPEED_1000;
|
||||
card->info.link_info.port = PORT_FIBRE;
|
||||
break;
|
||||
case QETH_LINK_TYPE_10GBIT_ETH:
|
||||
card->info.link_info.speed = SPEED_10000;
|
||||
card->info.link_info.port = PORT_FIBRE;
|
||||
break;
|
||||
case QETH_LINK_TYPE_25GBIT_ETH:
|
||||
card->info.link_info.speed = SPEED_25000;
|
||||
card->info.link_info.port = PORT_FIBRE;
|
||||
break;
|
||||
default:
|
||||
dev_info(&card->gdev->dev, "Unknown link type %x\n",
|
||||
card->info.link_type);
|
||||
card->info.link_info.speed = SPEED_UNKNOWN;
|
||||
card->info.link_info.port = PORT_OTHER;
|
||||
}
|
||||
|
||||
card->info.link_info.link_mode = QETH_LINK_MODE_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Get more accurate data via QUERY OAT: */
|
||||
if (qeth_adp_supported(card, IPA_SETADP_QUERY_OAT)) {
|
||||
struct qeth_link_info link_info;
|
||||
struct qeth_cmd_buffer *iob;
|
||||
|
||||
iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_OAT,
|
||||
SETADP_DATA_SIZEOF(query_oat));
|
||||
if (iob) {
|
||||
struct qeth_ipa_cmd *cmd = __ipa_cmd(iob);
|
||||
struct qeth_query_oat *oat_req;
|
||||
|
||||
oat_req = &cmd->data.setadapterparms.data.query_oat;
|
||||
oat_req->subcmd_code = QETH_QOAT_SCOPE_INTERFACE;
|
||||
|
||||
if (!qeth_send_ipa_cmd(card, iob,
|
||||
qeth_init_link_info_oat_cb,
|
||||
&link_info)) {
|
||||
if (link_info.speed != SPEED_UNKNOWN)
|
||||
card->info.link_info.speed = link_info.speed;
|
||||
if (link_info.duplex != DUPLEX_UNKNOWN)
|
||||
card->info.link_info.duplex = link_info.duplex;
|
||||
if (link_info.port != PORT_OTHER)
|
||||
card->info.link_info.port = link_info.port;
|
||||
if (link_info.link_mode != QETH_LINK_MODE_UNKNOWN)
|
||||
card->info.link_info.link_mode = link_info.link_mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -5282,6 +5489,8 @@ retriable:
|
||||
goto out;
|
||||
}
|
||||
|
||||
qeth_init_link_info(card);
|
||||
|
||||
rc = qeth_init_qdio_queues(card);
|
||||
if (rc) {
|
||||
QETH_CARD_TEXT_(card, 2, "9err%d", rc);
|
||||
|
@ -489,9 +489,45 @@ struct qeth_set_access_ctrl {
|
||||
__u8 reserved[8];
|
||||
} __attribute__((packed));
|
||||
|
||||
#define QETH_QOAT_PHYS_SPEED_UNKNOWN 0x00
|
||||
#define QETH_QOAT_PHYS_SPEED_10M_HALF 0x01
|
||||
#define QETH_QOAT_PHYS_SPEED_10M_FULL 0x02
|
||||
#define QETH_QOAT_PHYS_SPEED_100M_HALF 0x03
|
||||
#define QETH_QOAT_PHYS_SPEED_100M_FULL 0x04
|
||||
#define QETH_QOAT_PHYS_SPEED_1000M_HALF 0x05
|
||||
#define QETH_QOAT_PHYS_SPEED_1000M_FULL 0x06
|
||||
// n/a 0x07
|
||||
#define QETH_QOAT_PHYS_SPEED_10G_FULL 0x08
|
||||
// n/a 0x09
|
||||
#define QETH_QOAT_PHYS_SPEED_25G_FULL 0x0A
|
||||
|
||||
#define QETH_QOAT_PHYS_MEDIA_COPPER 0x01
|
||||
#define QETH_QOAT_PHYS_MEDIA_FIBRE_SHORT 0x02
|
||||
#define QETH_QOAT_PHYS_MEDIA_FIBRE_LONG 0x04
|
||||
|
||||
struct qeth_query_oat_physical_if {
|
||||
u8 res_head[33];
|
||||
u8 speed_duplex;
|
||||
u8 media_type;
|
||||
u8 res_tail[29];
|
||||
};
|
||||
|
||||
#define QETH_QOAT_REPLY_TYPE_PHYS_IF 0x0004
|
||||
|
||||
struct qeth_query_oat_reply {
|
||||
u16 type;
|
||||
u16 length;
|
||||
u16 version;
|
||||
u8 res[10];
|
||||
struct qeth_query_oat_physical_if phys_if;
|
||||
};
|
||||
|
||||
#define QETH_QOAT_SCOPE_INTERFACE 0x00000001
|
||||
|
||||
struct qeth_query_oat {
|
||||
__u32 subcmd_code;
|
||||
__u8 reserved[12];
|
||||
u32 subcmd_code;
|
||||
u8 reserved[12];
|
||||
struct qeth_query_oat_reply reply[];
|
||||
} __packed;
|
||||
|
||||
struct qeth_qoat_priv {
|
||||
|
@ -324,8 +324,8 @@ static int qeth_set_per_queue_coalesce(struct net_device *dev, u32 queue,
|
||||
/* Autoneg and full-duplex are supported and advertised unconditionally. */
|
||||
/* Always advertise and support all speeds up to specified, and only one */
|
||||
/* specified port type. */
|
||||
static void qeth_set_cmd_adv_sup(struct ethtool_link_ksettings *cmd,
|
||||
int maxspeed, int porttype)
|
||||
static void qeth_set_ethtool_link_modes(struct ethtool_link_ksettings *cmd,
|
||||
enum qeth_link_mode link_mode)
|
||||
{
|
||||
ethtool_link_ksettings_zero_link_mode(cmd, supported);
|
||||
ethtool_link_ksettings_zero_link_mode(cmd, advertising);
|
||||
@ -334,186 +334,119 @@ static void qeth_set_cmd_adv_sup(struct ethtool_link_ksettings *cmd,
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg);
|
||||
|
||||
switch (porttype) {
|
||||
switch (cmd->base.port) {
|
||||
case PORT_TP:
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported, TP);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising, TP);
|
||||
|
||||
switch (cmd->base.speed) {
|
||||
case SPEED_10000:
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
10000baseT_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
10000baseT_Full);
|
||||
fallthrough;
|
||||
case SPEED_1000:
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
1000baseT_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
1000baseT_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
1000baseT_Half);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
1000baseT_Half);
|
||||
fallthrough;
|
||||
case SPEED_100:
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
100baseT_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
100baseT_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
100baseT_Half);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
100baseT_Half);
|
||||
fallthrough;
|
||||
case SPEED_10:
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
10baseT_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
10baseT_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
10baseT_Half);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
10baseT_Half);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case PORT_FIBRE:
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE);
|
||||
break;
|
||||
default:
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported, TP);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising, TP);
|
||||
WARN_ON_ONCE(1);
|
||||
}
|
||||
|
||||
/* partially does fall through, to also select lower speeds */
|
||||
switch (maxspeed) {
|
||||
case SPEED_25000:
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
25000baseSR_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
25000baseSR_Full);
|
||||
break;
|
||||
case SPEED_10000:
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
10000baseT_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
10000baseT_Full);
|
||||
fallthrough;
|
||||
case SPEED_1000:
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
1000baseT_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
1000baseT_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
1000baseT_Half);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
1000baseT_Half);
|
||||
fallthrough;
|
||||
case SPEED_100:
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
100baseT_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
100baseT_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
100baseT_Half);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
100baseT_Half);
|
||||
fallthrough;
|
||||
case SPEED_10:
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
10baseT_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
10baseT_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
10baseT_Half);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
10baseT_Half);
|
||||
switch (cmd->base.speed) {
|
||||
case SPEED_25000:
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
25000baseSR_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
25000baseSR_Full);
|
||||
break;
|
||||
case SPEED_10000:
|
||||
if (link_mode == QETH_LINK_MODE_FIBRE_LONG) {
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
10000baseLR_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
10000baseLR_Full);
|
||||
} else if (link_mode == QETH_LINK_MODE_FIBRE_SHORT) {
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
10000baseSR_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
10000baseSR_Full);
|
||||
}
|
||||
break;
|
||||
case SPEED_1000:
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
1000baseX_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
1000baseX_Full);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
10baseT_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
10baseT_Full);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, supported,
|
||||
10baseT_Half);
|
||||
ethtool_link_ksettings_add_link_mode(cmd, advertising,
|
||||
10baseT_Half);
|
||||
WARN_ON_ONCE(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int qeth_get_link_ksettings(struct net_device *netdev,
|
||||
struct ethtool_link_ksettings *cmd)
|
||||
{
|
||||
struct qeth_card *card = netdev->ml_priv;
|
||||
enum qeth_link_types link_type;
|
||||
struct carrier_info carrier_info;
|
||||
int rc;
|
||||
struct qeth_link_info link_info;
|
||||
|
||||
if (IS_IQD(card) || IS_VM_NIC(card))
|
||||
link_type = QETH_LINK_TYPE_10GBIT_ETH;
|
||||
else
|
||||
link_type = card->info.link_type;
|
||||
|
||||
cmd->base.duplex = DUPLEX_FULL;
|
||||
cmd->base.speed = card->info.link_info.speed;
|
||||
cmd->base.duplex = card->info.link_info.duplex;
|
||||
cmd->base.port = card->info.link_info.port;
|
||||
cmd->base.autoneg = AUTONEG_ENABLE;
|
||||
cmd->base.phy_address = 0;
|
||||
cmd->base.mdio_support = 0;
|
||||
cmd->base.eth_tp_mdix = ETH_TP_MDI_INVALID;
|
||||
cmd->base.eth_tp_mdix_ctrl = ETH_TP_MDI_INVALID;
|
||||
|
||||
switch (link_type) {
|
||||
case QETH_LINK_TYPE_FAST_ETH:
|
||||
case QETH_LINK_TYPE_LANE_ETH100:
|
||||
cmd->base.speed = SPEED_100;
|
||||
cmd->base.port = PORT_TP;
|
||||
break;
|
||||
case QETH_LINK_TYPE_GBIT_ETH:
|
||||
case QETH_LINK_TYPE_LANE_ETH1000:
|
||||
cmd->base.speed = SPEED_1000;
|
||||
cmd->base.port = PORT_FIBRE;
|
||||
break;
|
||||
case QETH_LINK_TYPE_10GBIT_ETH:
|
||||
cmd->base.speed = SPEED_10000;
|
||||
cmd->base.port = PORT_FIBRE;
|
||||
break;
|
||||
case QETH_LINK_TYPE_25GBIT_ETH:
|
||||
cmd->base.speed = SPEED_25000;
|
||||
cmd->base.port = PORT_FIBRE;
|
||||
break;
|
||||
default:
|
||||
cmd->base.speed = SPEED_10;
|
||||
cmd->base.port = PORT_TP;
|
||||
}
|
||||
qeth_set_cmd_adv_sup(cmd, cmd->base.speed, cmd->base.port);
|
||||
|
||||
/* Check if we can obtain more accurate information. */
|
||||
/* If QUERY_CARD_INFO command is not supported or fails, */
|
||||
/* just return the heuristics that was filled above. */
|
||||
rc = qeth_query_card_info(card, &carrier_info);
|
||||
if (rc == -EOPNOTSUPP) /* for old hardware, return heuristic */
|
||||
return 0;
|
||||
if (rc) /* report error from the hardware operation */
|
||||
return rc;
|
||||
/* on success, fill in the information got from the hardware */
|
||||
|
||||
netdev_dbg(netdev,
|
||||
"card info: card_type=0x%02x, port_mode=0x%04x, port_speed=0x%08x\n",
|
||||
carrier_info.card_type,
|
||||
carrier_info.port_mode,
|
||||
carrier_info.port_speed);
|
||||
|
||||
/* Update attributes for which we've obtained more authoritative */
|
||||
/* information, leave the rest the way they where filled above. */
|
||||
switch (carrier_info.card_type) {
|
||||
case CARD_INFO_TYPE_1G_COPPER_A:
|
||||
case CARD_INFO_TYPE_1G_COPPER_B:
|
||||
cmd->base.port = PORT_TP;
|
||||
qeth_set_cmd_adv_sup(cmd, SPEED_1000, cmd->base.port);
|
||||
break;
|
||||
case CARD_INFO_TYPE_1G_FIBRE_A:
|
||||
case CARD_INFO_TYPE_1G_FIBRE_B:
|
||||
cmd->base.port = PORT_FIBRE;
|
||||
qeth_set_cmd_adv_sup(cmd, SPEED_1000, cmd->base.port);
|
||||
break;
|
||||
case CARD_INFO_TYPE_10G_FIBRE_A:
|
||||
case CARD_INFO_TYPE_10G_FIBRE_B:
|
||||
cmd->base.port = PORT_FIBRE;
|
||||
qeth_set_cmd_adv_sup(cmd, SPEED_10000, cmd->base.port);
|
||||
break;
|
||||
if (!qeth_query_card_info(card, &link_info)) {
|
||||
if (link_info.speed != SPEED_UNKNOWN)
|
||||
cmd->base.speed = link_info.speed;
|
||||
if (link_info.duplex != DUPLEX_UNKNOWN)
|
||||
cmd->base.duplex = link_info.duplex;
|
||||
if (link_info.port != PORT_OTHER)
|
||||
cmd->base.port = link_info.port;
|
||||
}
|
||||
|
||||
switch (carrier_info.port_mode) {
|
||||
case CARD_INFO_PORTM_FULLDUPLEX:
|
||||
cmd->base.duplex = DUPLEX_FULL;
|
||||
break;
|
||||
case CARD_INFO_PORTM_HALFDUPLEX:
|
||||
cmd->base.duplex = DUPLEX_HALF;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (carrier_info.port_speed) {
|
||||
case CARD_INFO_PORTS_10M:
|
||||
cmd->base.speed = SPEED_10;
|
||||
break;
|
||||
case CARD_INFO_PORTS_100M:
|
||||
cmd->base.speed = SPEED_100;
|
||||
break;
|
||||
case CARD_INFO_PORTS_1G:
|
||||
cmd->base.speed = SPEED_1000;
|
||||
break;
|
||||
case CARD_INFO_PORTS_10G:
|
||||
cmd->base.speed = SPEED_10000;
|
||||
break;
|
||||
case CARD_INFO_PORTS_25G:
|
||||
cmd->base.speed = SPEED_25000;
|
||||
break;
|
||||
}
|
||||
qeth_set_ethtool_link_modes(cmd, card->info.link_info.link_mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -737,8 +737,6 @@ static void qeth_l2_dev2br_an_set_cb(void *priv,
|
||||
*
|
||||
* On enable, emits a series of address notifications for all
|
||||
* currently registered hosts.
|
||||
*
|
||||
* Must be called under rtnl_lock
|
||||
*/
|
||||
static int qeth_l2_dev2br_an_set(struct qeth_card *card, bool enable)
|
||||
{
|
||||
@ -1289,16 +1287,19 @@ static void qeth_l2_dev2br_worker(struct work_struct *work)
|
||||
if (READ_ONCE(card->info.pnso_mode) == QETH_PNSO_NONE)
|
||||
goto free;
|
||||
|
||||
/* Potential re-config in progress, try again later: */
|
||||
if (!rtnl_trylock()) {
|
||||
queue_delayed_work(card->event_wq, dwork,
|
||||
msecs_to_jiffies(100));
|
||||
return;
|
||||
}
|
||||
if (!netif_device_present(card->dev))
|
||||
goto out_unlock;
|
||||
|
||||
if (data->ac_event.lost_event_mask) {
|
||||
/* Potential re-config in progress, try again later: */
|
||||
if (!rtnl_trylock()) {
|
||||
queue_delayed_work(card->event_wq, dwork,
|
||||
msecs_to_jiffies(100));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!netif_device_present(card->dev)) {
|
||||
rtnl_unlock();
|
||||
goto free;
|
||||
}
|
||||
|
||||
QETH_DBF_MESSAGE(3,
|
||||
"Address change notification overflow on device %x\n",
|
||||
CARD_DEVID(card));
|
||||
@ -1328,6 +1329,8 @@ static void qeth_l2_dev2br_worker(struct work_struct *work)
|
||||
"Address Notification resynced on device %x\n",
|
||||
CARD_DEVID(card));
|
||||
}
|
||||
|
||||
rtnl_unlock();
|
||||
} else {
|
||||
for (i = 0; i < data->ac_event.num_entries; i++) {
|
||||
struct qeth_ipacmd_addr_change_entry *entry =
|
||||
@ -1339,9 +1342,6 @@ static void qeth_l2_dev2br_worker(struct work_struct *work)
|
||||
}
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
rtnl_unlock();
|
||||
|
||||
free:
|
||||
kfree(data);
|
||||
}
|
||||
@ -2310,11 +2310,8 @@ static void qeth_l2_set_offline(struct qeth_card *card)
|
||||
card->state = CARD_STATE_DOWN;
|
||||
|
||||
qeth_l2_set_pnso_mode(card, QETH_PNSO_NONE);
|
||||
if (priv->brport_features & BR_LEARNING_SYNC) {
|
||||
rtnl_lock();
|
||||
if (priv->brport_features & BR_LEARNING_SYNC)
|
||||
qeth_l2_dev2br_fdb_flush(card);
|
||||
rtnl_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns zero if the command is successfully "consumed" */
|
||||
|
@ -104,10 +104,7 @@ static bool qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card,
|
||||
qeth_l3_convert_addr_to_bits(ipatoe->addr, ipatoe_bits,
|
||||
(ipatoe->proto == QETH_PROT_IPV4) ?
|
||||
4 : 16);
|
||||
if (addr->proto == QETH_PROT_IPV4)
|
||||
rc = !memcmp(addr_bits, ipatoe_bits, ipatoe->mask_bits);
|
||||
else
|
||||
rc = !memcmp(addr_bits, ipatoe_bits, ipatoe->mask_bits);
|
||||
rc = !memcmp(addr_bits, ipatoe_bits, ipatoe->mask_bits);
|
||||
if (rc)
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user