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

Commit 08ad1ba9 authored by Harout Hedeshian's avatar Harout Hedeshian
Browse files

net: usb: Update new IOCTLs to meet new spec



Update the USB RmNet driver to support the extended IOCTL specification
for RmNet Data. New extended structure is used for supporting IOCTLs
above and beyond the 16 IOCTL limitation.

CRs-Fixed: 554883
Change-Id: I99a2778f5dee1c88a830f887c89c9ee8f5512000
Signed-off-by: default avatarHarout Hedeshian <harouth@codeaurora.org>
parent 099576a6
Loading
Loading
Loading
Loading
+52 −22
Original line number Diff line number Diff line
@@ -495,6 +495,56 @@ static const struct net_device_ops rmnet_usb_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;
	int rc = 0;
	struct usbnet *unet = netdev_priv(dev);

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

	if (rc) {
		DBG0("%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 (test_bit(EVENT_DEV_OPEN, &unet->flags))
			return -EBUSY;

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

		unet->rx_urb_size = (size_t) ext_cmd.u.data;
		DBG0("[%s] rmnet_ioctl(): SET MRU to %u\n", dev->name,
				unet->rx_urb_size);
		break;

	case RMNET_IOCTL_GET_MRU:
		ext_cmd.u.data = (uint32_t)unet->rx_urb_size;
		break;

	case RMNET_IOCTL_GET_DRIVER_NAME:
		strlcpy(ext_cmd.u.if_name, unet->driver_name,
			sizeof(ext_cmd.u.if_name));
		break;
	}

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

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

static int rmnet_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	struct usbnet	*unet = netdev_priv(dev);
@@ -575,30 +625,10 @@ static int rmnet_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
		DBG0("[%s] rmnet_ioctl(): close transport port\n", dev->name);
		break;

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

	case RMNET_IOCTL_SET_MRU:
		if (test_bit(EVENT_DEV_OPEN, &unet->flags))
			return -EBUSY;

		/* 16K max */
		if ((size_t)ifr->ifr_ifru.ifru_data > 0x4000)
			return -EINVAL;

		unet->rx_urb_size = (size_t)ifr->ifr_ifru.ifru_data;
		DBG0("[%s] rmnet_ioctl(): SET MRU to %u\n", dev->name,
				unet->rx_urb_size);
		break;

	case RMNET_IOCTL_GET_MRU:
		ifr->ifr_ifru.ifru_data = (void *)unet->rx_urb_size;
		break;

	case RMNET_IOCTL_GET_DRIVER_NAME:
		rc = copy_to_user(ifr->ifr_ifru.ifru_data, unet->driver_name,
				strlen(unet->driver_name));
		break;
	default:
		dev_err(&unet->intf->dev, "[%s] error: "
			"rmnet_ioct called for unsupported cmd[%d]",