static int _rmnet_vnd_do_qos_ioctl(struct net_device *dev,
				   struct ifreq *ifr,
				   int cmd)
{
	struct rmnet_vnd_private_s *dev_conf;
	int rc;
	rc = 0;
	dev_conf = (struct rmnet_vnd_private_s *) netdev_priv(dev);

	switch (cmd) {

	case RMNET_IOCTL_SET_QOS_ENABLE:
		LOGM("%s(): RMNET_IOCTL_SET_QOS_ENABLE on %s\n",
		     __func__, dev->name);
		dev_conf->qos_mode = 1;
		break;

	case RMNET_IOCTL_SET_QOS_DISABLE:
		LOGM("%s(): RMNET_IOCTL_SET_QOS_DISABLE on %s\n",
		     __func__, dev->name);
		dev_conf->qos_mode = 0;
		break;

	case RMNET_IOCTL_FLOW_ENABLE:
		LOGL("%s(): RMNET_IOCTL_FLOW_ENABLE on %s\n",
		     __func__, dev->name);
		tc_qdisc_flow_control(dev, (u32)ifr->ifr_data, 1);
		break;

	case RMNET_IOCTL_FLOW_DISABLE:
		LOGL("%s(): RMNET_IOCTL_FLOW_DISABLE on %s\n",
		     __func__, dev->name);
		tc_qdisc_flow_control(dev, (u32)ifr->ifr_data, 0);
		break;

	case RMNET_IOCTL_GET_QOS:           
		LOGM("%s(): RMNET_IOCTL_GET_QOS on %s\n",
		     __func__, dev->name);
		ifr->ifr_ifru.ifru_data =
			(void *)(dev_conf->qos_mode == 1);
		break;

	default:
		rc = -EINVAL;
	}

	return rc;
}
static int wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	int rc = 0;

	switch (cmd) {
	case RMNET_IOCTL_SET_LLP_IP:        
		break;
	case RMNET_IOCTL_GET_LLP:           
		ifr->ifr_ifru.ifru_data = (void *) RMNET_MODE_LLP_IP;
		break;
	case RMNET_IOCTL_SET_QOS_DISABLE:   
		break;
	case RMNET_IOCTL_FLOW_ENABLE:
		tc_qdisc_flow_control(dev, (u32)ifr->ifr_data, 1);
		pr_debug("[%s] %s: enabled flow", dev->name, __func__);
		break;
	case RMNET_IOCTL_FLOW_DISABLE:
		tc_qdisc_flow_control(dev, (u32)ifr->ifr_data, 0);
		pr_debug("[%s] %s: disabled flow", dev->name, __func__);
		break;
	case RMNET_IOCTL_GET_QOS:           
		
		ifr->ifr_ifru.ifru_data = (void *) 0;
		break;
	case RMNET_IOCTL_GET_OPMODE:        
		ifr->ifr_ifru.ifru_data = (void *) RMNET_MODE_LLP_IP;
		break;
	case RMNET_IOCTL_OPEN:  
		rc = __wwan_open(dev);
		pr_debug("[%s] wwan_ioctl(): open transport port\n",
		     dev->name);
		break;
	case RMNET_IOCTL_CLOSE:  
		rc = __wwan_close(dev);
		pr_debug("[%s] wwan_ioctl(): close transport port\n",
		     dev->name);
		break;
	default:
		pr_err("[%s] error: wwan_ioct called for unsupported cmd[%d]",
		       dev->name, cmd);
		return -EINVAL;
	}
	return rc;
}
static int rmnet_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	struct rmnet_private *p = netdev_priv(dev);
	u32 old_opmode = p->operation_mode;
	unsigned long flags;
	int prev_mtu = dev->mtu;
	int rc = 0;

	/* Process IOCTL command */
	switch (cmd) {
	case RMNET_IOCTL_SET_LLP_ETHERNET:  /* Set Ethernet protocol   */
		/* Perform Ethernet config only if in IP mode currently*/
		if (p->operation_mode & RMNET_MODE_LLP_IP) {
			ether_setup(dev);
			random_ether_addr(dev->dev_addr);
			dev->mtu = prev_mtu;

			dev->netdev_ops = &rmnet_ops_ether;
			spin_lock_irqsave(&p->lock, flags);
			p->operation_mode &= ~RMNET_MODE_LLP_IP;
			p->operation_mode |= RMNET_MODE_LLP_ETH;
			spin_unlock_irqrestore(&p->lock, flags);
			DBG0("[%s] rmnet_ioctl(): "
				"set Ethernet protocol mode\n",
				dev->name);
		}
		break;

	case RMNET_IOCTL_SET_LLP_IP:        /* Set RAWIP protocol      */
		/* Perform IP config only if in Ethernet mode currently*/
		if (p->operation_mode & RMNET_MODE_LLP_ETH) {

			/* Undo config done in ether_setup() */
			dev->header_ops         = 0;  /* No header */
			dev->type               = ARPHRD_RAWIP;
			dev->hard_header_len    = 0;
			dev->mtu                = prev_mtu;
			dev->addr_len           = 0;
			dev->flags              &= ~(IFF_BROADCAST|
						     IFF_MULTICAST);

			dev->needed_headroom = HEADROOM_FOR_BAM +
			  HEADROOM_FOR_QOS;
			dev->needed_tailroom = TAILROOM;
			dev->netdev_ops = &rmnet_ops_ip;
			spin_lock_irqsave(&p->lock, flags);
			p->operation_mode &= ~RMNET_MODE_LLP_ETH;
			p->operation_mode |= RMNET_MODE_LLP_IP;
			spin_unlock_irqrestore(&p->lock, flags);
			DBG0("[%s] rmnet_ioctl(): "
				"set IP protocol mode\n",
				dev->name);
		}
		break;

	case RMNET_IOCTL_GET_LLP:           /* Get link protocol state */
		ifr->ifr_ifru.ifru_data =
			(void *)(p->operation_mode &
				 (RMNET_MODE_LLP_ETH|RMNET_MODE_LLP_IP));
		break;

	case RMNET_IOCTL_SET_QOS_ENABLE:    /* Set QoS header enabled  */
		spin_lock_irqsave(&p->lock, flags);
		p->operation_mode |= RMNET_MODE_QOS;
		spin_unlock_irqrestore(&p->lock, flags);
		DBG0("[%s] rmnet_ioctl(): set QMI QOS header enable\n",
			dev->name);
		break;

	case RMNET_IOCTL_SET_QOS_DISABLE:   /* Set QoS header disabled */
		spin_lock_irqsave(&p->lock, flags);
		p->operation_mode &= ~RMNET_MODE_QOS;
		spin_unlock_irqrestore(&p->lock, flags);
		DBG0("[%s] rmnet_ioctl(): set QMI QOS header disable\n",
			dev->name);
		break;

	case RMNET_IOCTL_FLOW_ENABLE:
		tc_qdisc_flow_control(dev, (u32)ifr->ifr_data, 1);
		DBG0("[%s] rmnet_ioctl(): enabled flow", dev->name);
		break;

	case RMNET_IOCTL_FLOW_DISABLE:
		tc_qdisc_flow_control(dev, (u32)ifr->ifr_data, 0);
		DBG0("[%s] rmnet_ioctl(): disabled flow", dev->name);
		break;

	case RMNET_IOCTL_GET_QOS:           /* Get QoS header state    */
		ifr->ifr_ifru.ifru_data =
			(void *)(p->operation_mode & RMNET_MODE_QOS);
		break;

	case RMNET_IOCTL_GET_OPMODE:        /* Get operation mode      */
		ifr->ifr_ifru.ifru_data = (void *)p->operation_mode;
		break;

	case RMNET_IOCTL_OPEN:              /* Open transport port     */
		rc = __rmnet_open(dev);
		DBG0("[%s] rmnet_ioctl(): open transport port\n",
			dev->name);
		break;

	case RMNET_IOCTL_CLOSE:             /* Close transport port    */
		rc = __rmnet_close(dev);
		DBG0("[%s] rmnet_ioctl(): close transport port\n",
			dev->name);
		break;

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

	DBG2("[%s] %s: cmd=0x%x opmode old=0x%08x new=0x%08x\n",
		dev->name, __func__, cmd, old_opmode, p->operation_mode);
	return rc;
}
/**
 * wwan_ioctl() - I/O control for wwan network driver.
 *
 * @dev: network device
 * @ifr: ignored
 * @cmd: cmd to be excecuded. can be one of the following:
 * WWAN_IOCTL_OPEN - Open the network interface
 * WWAN_IOCTL_CLOSE - Close the network interface
 *
 * Return codes:
 * 0: success
 * NETDEV_TX_BUSY: Error while transmitting the skb. Try again
 * later
 * -EFAULT: Error while transmitting the skb
 */
static int wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	int rc = 0;
	struct rmnet_ioctl_data_s ioctl_data;

	switch (cmd) {
	case RMNET_IOCTL_SET_LLP_IP:        /* Set RAWIP protocol */
		break;
	case RMNET_IOCTL_GET_LLP:           /* Get link protocol state */
		ioctl_data.u.operation_mode = RMNET_MODE_LLP_IP;
		if (copy_to_user(ifr->ifr_ifru.ifru_data, &ioctl_data,
			sizeof(struct rmnet_ioctl_data_s)))
			rc = -EFAULT;
		break;
	case RMNET_IOCTL_SET_QOS_DISABLE:   /* Set QoS header disabled */
		break;
	case RMNET_IOCTL_FLOW_ENABLE:
		if (copy_from_user(&ioctl_data, ifr->ifr_ifru.ifru_data,
			sizeof(struct rmnet_ioctl_data_s))) {
			rc = -EFAULT;
			break;
		}
		tc_qdisc_flow_control(dev, ioctl_data.u.tcm_handle, 1);
		pr_debug("[%s] %s: enabled flow", dev->name, __func__);
		break;
	case RMNET_IOCTL_FLOW_DISABLE:
		if (copy_from_user(&ioctl_data, ifr->ifr_ifru.ifru_data,
			sizeof(struct rmnet_ioctl_data_s))) {
			rc = -EFAULT;
			break;
		}
		tc_qdisc_flow_control(dev, ioctl_data.u.tcm_handle, 0);
		pr_debug("[%s] %s: disabled flow", dev->name, __func__);
		break;
	case RMNET_IOCTL_GET_QOS:           /* Get QoS header state    */
		/* QoS disabled */
		ioctl_data.u.operation_mode = 0;
		if (copy_to_user(ifr->ifr_ifru.ifru_data, &ioctl_data,
			sizeof(struct rmnet_ioctl_data_s)))
			rc = -EFAULT;
		break;
	case RMNET_IOCTL_GET_OPMODE:        /* Get operation mode      */
		ioctl_data.u.operation_mode = RMNET_MODE_LLP_IP;
		if (copy_to_user(ifr->ifr_ifru.ifru_data, &ioctl_data,
			sizeof(struct rmnet_ioctl_data_s)))
			rc = -EFAULT;
		break;
	case RMNET_IOCTL_OPEN:  /* Open transport port */
		rc = __wwan_open(dev);
		pr_debug("[%s] wwan_ioctl(): open transport port\n",
		     dev->name);
		break;
	case RMNET_IOCTL_CLOSE:  /* Close transport port */
		rc = __wwan_close(dev);
		pr_debug("[%s] wwan_ioctl(): close transport port\n",
		     dev->name);
		break;
	default:
		pr_err("[%s] error: wwan_ioct called for unsupported cmd[%d]",
		       dev->name, cmd);
		return -EINVAL;
	}
	return rc;
}