Skip to content

Commit

Permalink
qeth layer 2 and layer 3 common feature handling
Browse files Browse the repository at this point in the history
This patch introduces a common set of fix_features and set_features
functions for layer 2 and layer 3. The RX, TX and TSO offload
functionality on the OSA card is enabled using ethtool at user's
request and not at device initialization as done before.

For layer 3 the RX checksum offloading is disabled at device
initialization time.

Signed-off-by: Thomas Richter <tmricht@linux.vnet.ibm.com>
Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Thomas Richter authored and David S. Miller committed Jun 17, 2016
1 parent 5f78e29 commit 8f43fb0
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 198 deletions.
5 changes: 3 additions & 2 deletions drivers/s390/net/qeth_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -993,12 +993,13 @@ int qeth_send_setassparms(struct qeth_card *, struct qeth_cmd_buffer *, __u16,
int (*reply_cb)(struct qeth_card *,
struct qeth_reply *, unsigned long),
void *);
int qeth_setassparms_cb(struct qeth_card *, struct qeth_reply *, unsigned long);
struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *,
enum qeth_ipa_funcs,
__u16, __u16,
enum qeth_prot_versions);
int qeth_start_ipa_tx_checksum(struct qeth_card *);
int qeth_set_rx_csum(struct qeth_card *, int);
int qeth_set_features(struct net_device *, netdev_features_t);
netdev_features_t qeth_fix_features(struct net_device *, netdev_features_t);

/* exports for OSN */
int qeth_osn_assist(struct net_device *, void *, int);
Expand Down
127 changes: 87 additions & 40 deletions drivers/s390/net/qeth_core_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5268,8 +5268,8 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
}
EXPORT_SYMBOL_GPL(qeth_core_get_next_skb);

static int qeth_setassparms_cb(struct qeth_card *card,
struct qeth_reply *reply, unsigned long data)
int qeth_setassparms_cb(struct qeth_card *card,
struct qeth_reply *reply, unsigned long data)
{
struct qeth_ipa_cmd *cmd;

Expand Down Expand Up @@ -5297,6 +5297,7 @@ static int qeth_setassparms_cb(struct qeth_card *card,

return 0;
}
EXPORT_SYMBOL_GPL(qeth_setassparms_cb);

struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *card,
enum qeth_ipa_funcs ipa_func,
Expand Down Expand Up @@ -6053,74 +6054,120 @@ int qeth_core_ethtool_get_settings(struct net_device *netdev,
}
EXPORT_SYMBOL_GPL(qeth_core_ethtool_get_settings);

static int qeth_send_checksum_command(struct qeth_card *card)
static int qeth_send_checksum_on(struct qeth_card *card, int cstype)
{
long rxtx_arg;
int rc;

rc = qeth_send_simple_setassparms(card, IPA_INBOUND_CHECKSUM,
IPA_CMD_ASS_START, 0);
rc = qeth_send_simple_setassparms(card, cstype, IPA_CMD_ASS_START, 0);
if (rc) {
dev_warn(&card->gdev->dev, "Starting HW checksumming for %s "
"failed, using SW checksumming\n",
QETH_CARD_IFNAME(card));
dev_warn(&card->gdev->dev,
"Starting HW checksumming for %s failed, using SW checksumming\n",
QETH_CARD_IFNAME(card));
return rc;
}
rc = qeth_send_simple_setassparms(card, IPA_INBOUND_CHECKSUM,
IPA_CMD_ASS_ENABLE,
card->info.csum_mask);
rxtx_arg = (cstype == IPA_OUTBOUND_CHECKSUM) ? card->info.tx_csum_mask
: card->info.csum_mask;
rc = qeth_send_simple_setassparms(card, cstype, IPA_CMD_ASS_ENABLE,
rxtx_arg);
if (rc) {
dev_warn(&card->gdev->dev, "Enabling HW checksumming for %s "
"failed, using SW checksumming\n",
QETH_CARD_IFNAME(card));
dev_warn(&card->gdev->dev,
"Enabling HW checksumming for %s failed, using SW checksumming\n",
QETH_CARD_IFNAME(card));
return rc;
}

dev_info(&card->gdev->dev, "HW Checksumming (%sbound) enabled\n",
cstype == IPA_INBOUND_CHECKSUM ? "in" : "out");
return 0;
}

int qeth_set_rx_csum(struct qeth_card *card, int on)
static int qeth_set_ipa_csum(struct qeth_card *card, int on, int cstype)
{
int rc;

if (on) {
rc = qeth_send_checksum_command(card);
rc = qeth_send_checksum_on(card, cstype);
if (rc)
return -EIO;
dev_info(&card->gdev->dev,
"HW Checksumming (inbound) enabled\n");
} else {
rc = qeth_send_simple_setassparms(card,
IPA_INBOUND_CHECKSUM, IPA_CMD_ASS_STOP, 0);
rc = qeth_send_simple_setassparms(card, cstype,
IPA_CMD_ASS_STOP, 0);
if (rc)
return -EIO;
}
return 0;
}
EXPORT_SYMBOL_GPL(qeth_set_rx_csum);

int qeth_start_ipa_tx_checksum(struct qeth_card *card)
static int qeth_set_ipa_tso(struct qeth_card *card, int on)
{
int rc = 0;
int rc;

if (!qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM))
return rc;
rc = qeth_send_simple_setassparms(card, IPA_OUTBOUND_CHECKSUM,
IPA_CMD_ASS_START, 0);
if (rc)
goto err_out;
rc = qeth_send_simple_setassparms(card, IPA_OUTBOUND_CHECKSUM,
IPA_CMD_ASS_ENABLE,
card->info.tx_csum_mask);
if (rc)
goto err_out;
QETH_CARD_TEXT(card, 3, "sttso");

dev_info(&card->gdev->dev, "HW TX Checksumming enabled\n");
return rc;
err_out:
dev_warn(&card->gdev->dev, "Enabling HW TX checksumming for %s "
"failed, using SW TX checksumming\n", QETH_CARD_IFNAME(card));
if (on) {
rc = qeth_send_simple_setassparms(card, IPA_OUTBOUND_TSO,
IPA_CMD_ASS_START, 0);
if (rc) {
dev_warn(&card->gdev->dev,
"Starting outbound TCP segmentation offload for %s failed\n",
QETH_CARD_IFNAME(card));
return -EIO;
}
dev_info(&card->gdev->dev, "Outbound TSO enabled\n");
} else {
rc = qeth_send_simple_setassparms(card, IPA_OUTBOUND_TSO,
IPA_CMD_ASS_STOP, 0);
}
return rc;
}
EXPORT_SYMBOL_GPL(qeth_start_ipa_tx_checksum);

int qeth_set_features(struct net_device *dev, netdev_features_t features)
{
struct qeth_card *card = dev->ml_priv;
netdev_features_t changed = card->dev->features ^ features;
int rc = 0;

QETH_DBF_TEXT(SETUP, 2, "setfeat");
QETH_DBF_HEX(SETUP, 2, &features, sizeof(features));

if (card->state == CARD_STATE_DOWN ||
card->state == CARD_STATE_RECOVER)
return 0;

if ((changed & NETIF_F_IP_CSUM))
rc = qeth_set_ipa_csum(card,
features & NETIF_F_IP_CSUM ? 1 : 0,
IPA_OUTBOUND_CHECKSUM);
if ((changed & NETIF_F_RXCSUM))
rc |= qeth_set_ipa_csum(card,
features & NETIF_F_RXCSUM ? 1 : 0,
IPA_INBOUND_CHECKSUM);
if ((changed & NETIF_F_TSO))
rc |= qeth_set_ipa_tso(card, features & NETIF_F_TSO ? 1 : 0);
return rc ? -EIO : 0;
}
EXPORT_SYMBOL_GPL(qeth_set_features);

netdev_features_t qeth_fix_features(struct net_device *dev,
netdev_features_t features)
{
struct qeth_card *card = dev->ml_priv;

QETH_DBF_TEXT(SETUP, 2, "fixfeat");
if (!qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM))
features &= ~NETIF_F_IP_CSUM;
if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM))
features &= ~NETIF_F_RXCSUM;
if (!qeth_is_supported(card, IPA_OUTBOUND_TSO)) {
features &= ~NETIF_F_TSO;
dev_info(&card->gdev->dev, "Outbound TSO not supported on %s\n",
QETH_CARD_IFNAME(card));
}
QETH_DBF_HEX(SETUP, 2, &features, sizeof(features));
return features;
}
EXPORT_SYMBOL_GPL(qeth_fix_features);

static int __init qeth_core_init(void)
{
Expand Down
54 changes: 12 additions & 42 deletions drivers/s390/net/qeth_l2_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,38 +404,6 @@ static int qeth_l2_vlan_rx_kill_vid(struct net_device *dev,
return rc;
}

static netdev_features_t qeth_l2_fix_features(struct net_device *dev,
netdev_features_t features)
{
struct qeth_card *card = dev->ml_priv;

QETH_DBF_TEXT(SETUP, 2, "fixfeat");
if (!qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM))
features &= ~NETIF_F_IP_CSUM;
if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM))
features &= ~NETIF_F_RXCSUM;
QETH_DBF_HEX(SETUP, 2, &features, sizeof(features));
return features;
}

static int qeth_l2_set_features(struct net_device *dev,
netdev_features_t features)
{
struct qeth_card *card = dev->ml_priv;
netdev_features_t changed = dev->features ^ features;

QETH_DBF_TEXT(SETUP, 2, "setfeat");
QETH_DBF_HEX(SETUP, 2, &features, sizeof(features));

if (card->state == CARD_STATE_DOWN ||
card->state == CARD_STATE_RECOVER)
return 0;

if (!(changed & NETIF_F_RXCSUM))
return 0;
return qeth_set_rx_csum(card, features & NETIF_F_RXCSUM ? 1 : 0);
}

static void qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
{
QETH_DBF_TEXT(SETUP , 2, "stopcard");
Expand Down Expand Up @@ -1112,8 +1080,8 @@ static const struct net_device_ops qeth_l2_netdev_ops = {
.ndo_vlan_rx_add_vid = qeth_l2_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = qeth_l2_vlan_rx_kill_vid,
.ndo_tx_timeout = qeth_tx_timeout,
.ndo_fix_features = qeth_l2_fix_features,
.ndo_set_features = qeth_l2_set_features
.ndo_fix_features = qeth_fix_features,
.ndo_set_features = qeth_set_features
};

static int qeth_l2_setup_netdev(struct qeth_card *card)
Expand Down Expand Up @@ -1144,10 +1112,14 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
&qeth_l2_ethtool_ops : &qeth_l2_osn_ops;
card->dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
if (card->info.type == QETH_CARD_TYPE_OSD && !card->info.guestlan) {
card->dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
NETIF_F_SG;
/* Turn on RX offloading and SG per default */
card->dev->features |= NETIF_F_RXCSUM | NETIF_F_SG;
card->dev->hw_features = NETIF_F_SG;
/* OSA 3S and earlier has no RX/TX support */
if (qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM))
card->dev->hw_features |= NETIF_F_IP_CSUM;
if (qeth_is_supported(card, IPA_INBOUND_CHECKSUM))
card->dev->hw_features |= NETIF_F_RXCSUM;
/* Turn on SG per default */
card->dev->features |= NETIF_F_SG;
}
card->info.broadcast_capable = 1;
qeth_l2_request_initial_mac(card);
Expand All @@ -1165,9 +1137,6 @@ static int qeth_l2_start_ipassists(struct qeth_card *card)
/* configure isolation level */
if (qeth_set_access_ctrl_online(card, 0))
return -ENODEV;
if (qeth_is_supported(card, IPA_INBOUND_CHECKSUM))
qeth_set_rx_csum(card, 1);
qeth_start_ipa_tx_checksum(card);
return 0;
}

Expand Down Expand Up @@ -1236,7 +1205,8 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
contin:
if ((card->info.type == QETH_CARD_TYPE_OSD) ||
(card->info.type == QETH_CARD_TYPE_OSX)) {
if (qeth_l2_start_ipassists(card))
rc = qeth_l2_start_ipassists(card);
if (rc)
goto out_remove;
}

Expand Down
Loading

0 comments on commit 8f43fb0

Please sign in to comment.