Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8ce7a9e0 authored by Julian Wiedmann's avatar Julian Wiedmann Committed by David S. Miller
Browse files

s390/qeth: simplify max MTU handling



When the MPC initialization code discovers the HW-specific max MTU,
apply the resulting changes straight to the netdevice.

If this is the device's first initialization, also set its MTU
(HiperSockets: the max MTU; else: a layer-specific default value).
Then cap the current MTU by the new max MTU.

Signed-off-by: default avatarJulian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 92d27209
Loading
Loading
Loading
Loading
+0 −2
Original line number Original line Diff line number Diff line
@@ -660,8 +660,6 @@ struct qeth_card_info {
	int mac_bits;
	int mac_bits;
	enum qeth_card_types type;
	enum qeth_card_types type;
	enum qeth_link_types link_type;
	enum qeth_link_types link_type;
	int initial_mtu;
	int max_mtu;
	int broadcast_capable;
	int broadcast_capable;
	int unique_id;
	int unique_id;
	bool layer_enforced;
	bool layer_enforced;
+45 −37
Original line number Original line Diff line number Diff line
@@ -2278,19 +2278,42 @@ static int qeth_cm_setup(struct qeth_card *card)


}
}


static int qeth_get_initial_mtu_for_card(struct qeth_card *card)
static int qeth_update_max_mtu(struct qeth_card *card, unsigned int max_mtu)
{
{
	switch (card->info.type) {
	struct net_device *dev = card->dev;
	case QETH_CARD_TYPE_IQD:
	unsigned int new_mtu;
		return card->info.max_mtu;

	case QETH_CARD_TYPE_OSD:
	if (!max_mtu) {
	case QETH_CARD_TYPE_OSX:
		/* IQD needs accurate max MTU to set up its RX buffers: */
		if (!card->options.layer2)
		if (IS_IQD(card))
			return ETH_DATA_LEN - 8; /* L3: allow for LLC + SNAP */
			return -EINVAL;
		/* fall through */
		/* tolerate quirky HW: */
	default:
		max_mtu = ETH_MAX_MTU;
		return ETH_DATA_LEN;
	}
	}

	rtnl_lock();
	if (IS_IQD(card)) {
		/* move any device with default MTU to new max MTU: */
		new_mtu = (dev->mtu == dev->max_mtu) ? max_mtu : dev->mtu;

		/* adjust RX buffer size to new max MTU: */
		card->qdio.in_buf_size = max_mtu + 2 * PAGE_SIZE;
		if (dev->max_mtu && dev->max_mtu != max_mtu)
			qeth_free_qdio_buffers(card);
	} else {
		if (dev->mtu)
			new_mtu = dev->mtu;
		/* default MTUs for first setup: */
		else if (card->options.layer2)
			new_mtu = ETH_DATA_LEN;
		else
			new_mtu = ETH_DATA_LEN - 8; /* allow for LLC + SNAP */
	}

	dev->max_mtu = max_mtu;
	dev->mtu = min(new_mtu, max_mtu);
	rtnl_unlock();
	return 0;
}
}


static int qeth_get_mtu_outof_framesize(int framesize)
static int qeth_get_mtu_outof_framesize(int framesize)
@@ -2316,8 +2339,7 @@ static int qeth_mtu_is_valid(struct qeth_card *card, int mtu)
	case QETH_CARD_TYPE_OSM:
	case QETH_CARD_TYPE_OSM:
	case QETH_CARD_TYPE_OSX:
	case QETH_CARD_TYPE_OSX:
	case QETH_CARD_TYPE_IQD:
	case QETH_CARD_TYPE_IQD:
		return ((mtu >= 576) &&
		return ((mtu >= 576) && (mtu <= card->dev->max_mtu));
			(mtu <= card->info.max_mtu));
	case QETH_CARD_TYPE_OSN:
	case QETH_CARD_TYPE_OSN:
	default:
	default:
		return 1;
		return 1;
@@ -2342,28 +2364,10 @@ static int qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply,
	if (card->info.type == QETH_CARD_TYPE_IQD) {
	if (card->info.type == QETH_CARD_TYPE_IQD) {
		memcpy(&framesize, QETH_ULP_ENABLE_RESP_MAX_MTU(iob->data), 2);
		memcpy(&framesize, QETH_ULP_ENABLE_RESP_MAX_MTU(iob->data), 2);
		mtu = qeth_get_mtu_outof_framesize(framesize);
		mtu = qeth_get_mtu_outof_framesize(framesize);
		if (!mtu) {
			iob->rc = -EINVAL;
			QETH_DBF_TEXT_(SETUP, 2, "  rc%d", iob->rc);
			return 0;
		}
		if (card->info.initial_mtu && (card->info.initial_mtu != mtu)) {
			/* frame size has changed */
			if ((card->dev->mtu == card->info.initial_mtu) ||
			    (card->dev->mtu > mtu))
				card->dev->mtu = mtu;
			qeth_free_qdio_buffers(card);
		}
		card->info.initial_mtu = mtu;
		card->info.max_mtu = mtu;
		card->qdio.in_buf_size = mtu + 2 * PAGE_SIZE;
	} else {
	} else {
		card->info.max_mtu = *(__u16 *)QETH_ULP_ENABLE_RESP_MAX_MTU(
		mtu = *(__u16 *)QETH_ULP_ENABLE_RESP_MAX_MTU(iob->data);
			iob->data);
		card->info.initial_mtu = min(card->info.max_mtu,
					qeth_get_initial_mtu_for_card(card));
		card->qdio.in_buf_size = QETH_IN_BUF_SIZE_DEFAULT;
	}
	}
	*(u16 *)reply->param = mtu;


	memcpy(&len, QETH_ULP_ENABLE_RESP_DIFINFO_LEN(iob->data), 2);
	memcpy(&len, QETH_ULP_ENABLE_RESP_DIFINFO_LEN(iob->data), 2);
	if (len >= QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE) {
	if (len >= QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE) {
@@ -2382,6 +2386,7 @@ static int qeth_ulp_enable(struct qeth_card *card)
	int rc;
	int rc;
	char prot_type;
	char prot_type;
	struct qeth_cmd_buffer *iob;
	struct qeth_cmd_buffer *iob;
	u16 max_mtu;


	/*FIXME: trace view callbacks*/
	/*FIXME: trace view callbacks*/
	QETH_DBF_TEXT(SETUP, 2, "ulpenabl");
	QETH_DBF_TEXT(SETUP, 2, "ulpenabl");
@@ -2404,9 +2409,10 @@ static int qeth_ulp_enable(struct qeth_card *card)
	memcpy(QETH_ULP_ENABLE_FILTER_TOKEN(iob->data),
	memcpy(QETH_ULP_ENABLE_FILTER_TOKEN(iob->data),
	       &card->token.ulp_filter_w, QETH_MPC_TOKEN_LENGTH);
	       &card->token.ulp_filter_w, QETH_MPC_TOKEN_LENGTH);
	rc = qeth_send_control_data(card, ULP_ENABLE_SIZE, iob,
	rc = qeth_send_control_data(card, ULP_ENABLE_SIZE, iob,
				    qeth_ulp_enable_cb, NULL);
				    qeth_ulp_enable_cb, &max_mtu);
	if (rc)
		return rc;
		return rc;

	return qeth_update_max_mtu(card, max_mtu);
}
}


static int qeth_ulp_setup_cb(struct qeth_card *card, struct qeth_reply *reply,
static int qeth_ulp_setup_cb(struct qeth_card *card, struct qeth_reply *reply,
@@ -5691,7 +5697,9 @@ static struct net_device *qeth_alloc_netdev(struct qeth_card *card)
	dev->ml_priv = card;
	dev->ml_priv = card;
	dev->watchdog_timeo = QETH_TX_TIMEOUT;
	dev->watchdog_timeo = QETH_TX_TIMEOUT;
	dev->min_mtu = 64;
	dev->min_mtu = 64;
	dev->max_mtu = ETH_MAX_MTU;
	 /* initialized when device first goes online: */
	dev->max_mtu = 0;
	dev->mtu = 0;
	SET_NETDEV_DEV(dev, &card->gdev->dev);
	SET_NETDEV_DEV(dev, &card->gdev->dev);
	netif_carrier_off(dev);
	netif_carrier_off(dev);
	return dev;
	return dev;
+0 −1
Original line number Original line Diff line number Diff line
@@ -944,7 +944,6 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
		return 0;
		return 0;


	card->dev->priv_flags |= IFF_UNICAST_FLT;
	card->dev->priv_flags |= IFF_UNICAST_FLT;
	card->dev->mtu = card->info.initial_mtu;
	card->dev->netdev_ops = &qeth_l2_netdev_ops;
	card->dev->netdev_ops = &qeth_l2_netdev_ops;
	if (card->info.type == QETH_CARD_TYPE_OSN) {
	if (card->info.type == QETH_CARD_TYPE_OSN) {
		card->dev->ethtool_ops = &qeth_l2_osn_ops;
		card->dev->ethtool_ops = &qeth_l2_osn_ops;
+0 −1
Original line number Original line Diff line number Diff line
@@ -2579,7 +2579,6 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
	} else
	} else
		return -ENODEV;
		return -ENODEV;


	card->dev->mtu = card->info.initial_mtu;
	card->dev->ethtool_ops = &qeth_l3_ethtool_ops;
	card->dev->ethtool_ops = &qeth_l3_ethtool_ops;
	card->dev->priv_flags &= ~IFF_TX_SKB_SHARING;
	card->dev->priv_flags &= ~IFF_TX_SKB_SHARING;
	card->dev->needed_headroom = sizeof(struct qeth_hdr) - ETH_HLEN;
	card->dev->needed_headroom = sizeof(struct qeth_hdr) - ETH_HLEN;