modem_net_flowcontrol_device.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /* /linux/drivers/misc/modem_if_v2/modem_net_flowcontrol_device.c
  2. *
  3. * Copyright (C) 2012 Samsung Electronics.
  4. *
  5. * This software is licensed under the terms of the GNU General Public
  6. * License version 2, as published by the Free Software Foundation, and
  7. * may be copied, distributed, and modified under those terms.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. */
  15. #include <linux/kernel.h>
  16. #include <linux/fs.h>
  17. #include <linux/errno.h>
  18. #include <linux/types.h>
  19. #include <linux/fcntl.h>
  20. #include <linux/sched.h>
  21. #include <linux/netdevice.h>
  22. #include <linux/if_arp.h>
  23. #include <linux/platform_data/modem.h>
  24. #include <linux/module.h>
  25. #include "modem_prj.h"
  26. #define NET_FLOWCONTROL_DEV_NAME_LEN 8
  27. static int modem_net_flowcontrol_device_open(
  28. struct inode *inode, struct file *filp)
  29. {
  30. return 0;
  31. }
  32. static int modem_net_flowcontrol_device_release(
  33. struct inode *inode, struct file *filp)
  34. {
  35. return 0;
  36. }
  37. static long modem_net_flowcontrol_device_ioctl(
  38. struct file *filp, unsigned int cmd, unsigned long arg)
  39. {
  40. struct net *this_net;
  41. struct net_device *ndev;
  42. char dev_name[NET_FLOWCONTROL_DEV_NAME_LEN];
  43. u8 chan;
  44. if (copy_from_user(&chan, (void __user *)arg, sizeof(char)))
  45. return -EFAULT;
  46. if (chan > 15)
  47. return -ENODEV;
  48. snprintf(dev_name, NET_FLOWCONTROL_DEV_NAME_LEN, "rmnet%d", (int)chan);
  49. this_net = get_net_ns_by_pid(current->pid);
  50. ndev = __dev_get_by_name(this_net, dev_name);
  51. if (unlikely(!ndev)) {
  52. mif_err("device = %s not exist\n", dev_name);
  53. return -ENODEV;
  54. }
  55. switch (cmd) {
  56. case IOCTL_MODEM_NET_SUSPEND:
  57. netif_stop_queue(ndev);
  58. mif_info("NET SUSPEND(%s)\n", dev_name);
  59. break;
  60. case IOCTL_MODEM_NET_RESUME:
  61. netif_wake_queue(ndev);
  62. mif_info("NET RESUME(%s)\n", dev_name);
  63. break;
  64. default:
  65. return -EINVAL;
  66. }
  67. return 0;
  68. }
  69. static const struct file_operations modem_net_flowcontrol_device_fops = {
  70. .owner = THIS_MODULE,
  71. .open = modem_net_flowcontrol_device_open,
  72. .release = modem_net_flowcontrol_device_release,
  73. .unlocked_ioctl = modem_net_flowcontrol_device_ioctl,
  74. };
  75. static int __init modem_net_flowcontrol_device_init(void)
  76. {
  77. int ret = 0;
  78. struct io_device *net_flowcontrol_dev;
  79. net_flowcontrol_dev = kzalloc(sizeof(struct io_device), GFP_KERNEL);
  80. if (!net_flowcontrol_dev) {
  81. mif_err("net_flowcontrol_dev io device memory alloc fail\n");
  82. return -ENOMEM;
  83. }
  84. net_flowcontrol_dev->miscdev.minor = MISC_DYNAMIC_MINOR;
  85. net_flowcontrol_dev->miscdev.name = "modem_br";
  86. net_flowcontrol_dev->miscdev.fops = &modem_net_flowcontrol_device_fops;
  87. ret = misc_register(&net_flowcontrol_dev->miscdev);
  88. if (ret) {
  89. mif_err("failed to register misc br device : %s\n",
  90. net_flowcontrol_dev->miscdev.name);
  91. kfree(net_flowcontrol_dev);
  92. }
  93. return ret;
  94. }
  95. module_init(modem_net_flowcontrol_device_init);
  96. MODULE_LICENSE("GPL");
  97. MODULE_DESCRIPTION("Samsung Modem IF Net Flowcontrol Driver");