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

Commit 4cce0e7e authored by Jack Pham's avatar Jack Pham
Browse files

usb: gadget: u_ether: Add RMNET extended IOCTLs



Support IOCTL calls for setting/getting MRU, which is an
RMNET extension that can be set independently of MTU. This
value will limit the size of packets received from USB
OUT endpoint. Also add other required RMNET IOCTLs.

Change-Id: Ib8c50d6ac598095ccf881ad89c75337afc1bda0c
Signed-off-by: default avatarJack Pham <jackp@codeaurora.org>
parent 22b4738a
Loading
Loading
Loading
Loading
+60 −0
Original line number Diff line number Diff line
@@ -1062,6 +1062,62 @@ static const struct net_device_ops eth_netdev_ops_ip = {
	.ndo_validate_addr	= 0,
};

static int rmnet_ioctl_extended(struct net_device *dev, struct ifreq *ifr)
{
	struct rmnet_ioctl_extended_s ext_cmd;
	struct eth_dev *eth_dev = netdev_priv(dev);
	int rc = 0;

	rc = copy_from_user(&ext_cmd, ifr->ifr_ifru.ifru_data,
			    sizeof(struct rmnet_ioctl_extended_s));

	if (rc) {
		DBG("%s(): copy_from_user() failed\n", __func__);
		return rc;
	}

	switch (ext_cmd.extended_ioctl) {
	case RMNET_IOCTL_GET_SUPPORTED_FEATURES:
		ext_cmd.u.data = 0;
		break;

	case RMNET_IOCTL_SET_MRU:
		if (netif_running(dev))
			return -EBUSY;

		/* 16K max */
		if ((size_t)ext_cmd.u.data > 0x4000)
			return -EINVAL;

		eth_dev->port_usb->is_fixed = true;
		eth_dev->port_usb->fixed_out_len = (size_t) ext_cmd.u.data;
		DBG("[%s] rmnet_ioctl(): SET MRU to %u\n", dev->name,
				eth_dev->mru);
		break;

	case RMNET_IOCTL_GET_MRU:
		ext_cmd.u.data = eth_dev->port_usb->is_fixed ?
					eth_dev->port_usb->fixed_out_len :
					dev->mtu;
		break;

	case RMNET_IOCTL_GET_DRIVER_NAME:
		strlcpy(ext_cmd.u.if_name, dev->name,
			sizeof(ext_cmd.u.if_name));
		break;

	default:
		break;
	}

	rc = copy_to_user(ifr->ifr_ifru.ifru_data, &ext_cmd,
			  sizeof(struct rmnet_ioctl_extended_s));

	if (rc)
		DBG("%s(): copy_to_user() failed\n", __func__);
	return rc;
}

static int ether_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	struct eth_dev	*eth_dev = netdev_priv(dev);
@@ -1125,6 +1181,10 @@ static int ether_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
		rc = 0;
		break;

	case RMNET_IOCTL_EXTENDED:
		rc = rmnet_ioctl_extended(dev, ifr);
		break;

	default:
		pr_err("[%s] error: ioctl called for unsupported cmd[%d]",
			dev->name, cmd);