static int rmnet_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct usbnet *unet = netdev_priv(dev); u32 old_opmode; int prev_mtu = dev->mtu; int rc = 0; old_opmode = unet->data[0]; switch (cmd) { case RMNET_IOCTL_SET_LLP_ETHERNET: if (test_bit(RMNET_MODE_LLP_IP, &unet->data[0])) { ether_setup(dev); random_ether_addr(dev->dev_addr); dev->mtu = prev_mtu; dev->netdev_ops = &rmnet_usb_ops_ether; clear_bit(RMNET_MODE_LLP_IP, &unet->data[0]); set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]); DBG0("[%s] rmnet_ioctl(): set Ethernet protocol mode\n", dev->name); } break; case RMNET_IOCTL_SET_LLP_IP: if (test_bit(RMNET_MODE_LLP_ETH, &unet->data[0])) { dev->header_ops = 0; dev->type = ARPHRD_RAWIP; dev->hard_header_len = 0; dev->mtu = prev_mtu; dev->addr_len = 0; dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); dev->netdev_ops = &rmnet_usb_ops_ip; clear_bit(RMNET_MODE_LLP_ETH, &unet->data[0]); set_bit(RMNET_MODE_LLP_IP, &unet->data[0]); DBG0("[%s] rmnet_ioctl(): set IP protocol mode\n", dev->name); } break; case RMNET_IOCTL_GET_LLP: ifr->ifr_ifru.ifru_data = (void *)(unet->data[0] & (RMNET_MODE_LLP_ETH | RMNET_MODE_LLP_IP)); break; case RMNET_IOCTL_SET_ALIGNED_QOS_ENABLE: set_bit(RMNET_MODE_ALIGNED_QOS, &unet->data[0]); DBG0("[%s] rmnet_ioctl(): set QMI QOS Aligned header enable\n", dev->name); break; case RMNET_IOCTL_SET_QOS_ENABLE: set_bit(RMNET_MODE_QOS, &unet->data[0]); DBG0("[%s] rmnet_ioctl(): set QMI QOS header enable\n", dev->name); break; case RMNET_IOCTL_SET_QOS_DISABLE: clear_bit(RMNET_MODE_QOS, &unet->data[0]); DBG0("[%s] rmnet_ioctl(): set QMI QOS header disable\n", dev->name); break; case RMNET_IOCTL_GET_QOS: ifr->ifr_ifru.ifru_data = (void *)(unet->data[0] & RMNET_MODE_QOS); break; case RMNET_IOCTL_GET_OPMODE: ifr->ifr_ifru.ifru_data = (void *)unet->data[0]; break; case RMNET_IOCTL_OPEN: rc = usbnet_open(dev); DBG0("[%s] rmnet_ioctl(): open transport port\n", dev->name); break; case RMNET_IOCTL_CLOSE: rc = usbnet_stop(dev); DBG0("[%s] rmnet_ioctl(): close transport port\n", dev->name); break; default: dev_err(&unet->intf->dev, "[%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%08lx\n", dev->name, __func__, cmd, old_opmode, unet->data[0]); return rc; }
static int rmnet_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct usbnet *unet = netdev_priv(dev); u32 old_opmode; int prev_mtu = dev->mtu; int rc = 0; old_opmode = unet->data[0]; /*data[0] saves operation mode*/ /* Process IOCTL command */ switch (cmd) { case RMNET_IOCTL_SET_LLP_ETHERNET: /*Set Ethernet protocol*/ /* Perform Ethernet config only if in IP mode currently*/ if (test_bit(RMNET_MODE_LLP_IP, &unet->data[0])) { ether_setup(dev); random_ether_addr(dev->dev_addr); dev->mtu = prev_mtu; dev->netdev_ops = &rmnet_usb_ops_ether; clear_bit(RMNET_MODE_LLP_IP, &unet->data[0]); set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]); 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 (test_bit(RMNET_MODE_LLP_ETH, &unet->data[0])) { /* 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_QOS; dev->netdev_ops = &rmnet_usb_ops_ip; clear_bit(RMNET_MODE_LLP_ETH, &unet->data[0]); set_bit(RMNET_MODE_LLP_IP, &unet->data[0]); 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 *)(unet->data[0] & (RMNET_MODE_LLP_ETH | RMNET_MODE_LLP_IP)); break; case RMNET_IOCTL_SET_QOS_ENABLE: /* Set QoS header enabled*/ set_bit(RMNET_MODE_QOS, &unet->data[0]); DBG0("[%s] rmnet_ioctl(): set QMI QOS header enable\n", dev->name); break; case RMNET_IOCTL_SET_QOS_DISABLE: /* Set QoS header disabled */ clear_bit(RMNET_MODE_QOS, &unet->data[0]); DBG0("[%s] rmnet_ioctl(): set QMI QOS header disable\n", dev->name); break; case RMNET_IOCTL_GET_QOS: /* Get QoS header state */ ifr->ifr_ifru.ifru_data = (void *)(unet->data[0] & RMNET_MODE_QOS); break; case RMNET_IOCTL_GET_OPMODE: /* Get operation mode*/ ifr->ifr_ifru.ifru_data = (void *)unet->data[0]; break; case RMNET_IOCTL_OPEN: /* Open transport port */ rc = usbnet_open(dev); DBG0("[%s] rmnet_ioctl(): open transport port\n", dev->name); break; case RMNET_IOCTL_CLOSE: /* Close transport port*/ rc = usbnet_stop(dev); DBG0("[%s] rmnet_ioctl(): close transport port\n", dev->name); break; default: dev_err(&unet->intf->dev, "[%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%08lx\n", dev->name, __func__, cmd, old_opmode, unet->data[0]); return rc; }