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; }