netdev.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * Intel Wireless Multicomm 3200 WiFi driver
  3. *
  4. * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
  5. * Samuel Ortiz <samuel.ortiz@intel.com>
  6. * Zhu Yi <yi.zhu@intel.com>
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License version
  10. * 2 as published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  20. * 02110-1301, USA.
  21. *
  22. */
  23. /*
  24. * This is the netdev related hooks for iwm.
  25. *
  26. * Some interesting code paths:
  27. *
  28. * iwm_open() (Called at netdev interface bringup time)
  29. * -> iwm_up() (main.c)
  30. * -> iwm_bus_enable()
  31. * -> if_sdio_enable() (In case of an SDIO bus)
  32. * -> sdio_enable_func()
  33. * -> iwm_notif_wait(BARKER_REBOOT) (wait for reboot barker)
  34. * -> iwm_notif_wait(ACK_BARKER) (wait for ACK barker)
  35. * -> iwm_load_fw() (fw.c)
  36. * -> iwm_load_umac()
  37. * -> iwm_load_lmac() (Calibration LMAC)
  38. * -> iwm_load_lmac() (Operational LMAC)
  39. * -> iwm_send_umac_config()
  40. *
  41. * iwm_stop() (Called at netdev interface bringdown time)
  42. * -> iwm_down()
  43. * -> iwm_bus_disable()
  44. * -> if_sdio_disable() (In case of an SDIO bus)
  45. * -> sdio_disable_func()
  46. */
  47. #include <linux/netdevice.h>
  48. #include "iwm.h"
  49. #include "cfg80211.h"
  50. #include "debug.h"
  51. static int iwm_open(struct net_device *ndev)
  52. {
  53. struct iwm_priv *iwm = ndev_to_iwm(ndev);
  54. int ret = 0;
  55. if (!test_bit(IWM_RADIO_RFKILL_SW, &iwm->radio))
  56. ret = iwm_up(iwm);
  57. return ret;
  58. }
  59. static int iwm_stop(struct net_device *ndev)
  60. {
  61. struct iwm_priv *iwm = ndev_to_iwm(ndev);
  62. int ret = 0;
  63. if (!test_bit(IWM_RADIO_RFKILL_SW, &iwm->radio))
  64. ret = iwm_down(iwm);
  65. return ret;
  66. }
  67. /*
  68. * iwm AC to queue mapping
  69. *
  70. * AC_VO -> queue 3
  71. * AC_VI -> queue 2
  72. * AC_BE -> queue 1
  73. * AC_BK -> queue 0
  74. */
  75. static const u16 iwm_1d_to_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
  76. static u16 iwm_select_queue(struct net_device *dev, struct sk_buff *skb)
  77. {
  78. skb->priority = cfg80211_classify8021d(skb);
  79. return iwm_1d_to_queue[skb->priority];
  80. }
  81. static const struct net_device_ops iwm_netdev_ops = {
  82. .ndo_open = iwm_open,
  83. .ndo_stop = iwm_stop,
  84. .ndo_start_xmit = iwm_xmit_frame,
  85. .ndo_select_queue = iwm_select_queue,
  86. };
  87. void *iwm_if_alloc(int sizeof_bus, struct device *dev,
  88. struct iwm_if_ops *if_ops)
  89. {
  90. struct net_device *ndev;
  91. struct wireless_dev *wdev;
  92. struct iwm_priv *iwm;
  93. int ret = 0;
  94. wdev = iwm_wdev_alloc(sizeof_bus, dev);
  95. if (!wdev) {
  96. dev_err(dev, "no memory for wireless device instance\n");
  97. return ERR_PTR(-ENOMEM);
  98. }
  99. iwm = wdev_to_iwm(wdev);
  100. iwm->bus_ops = if_ops;
  101. iwm->wdev = wdev;
  102. iwm_priv_init(iwm);
  103. wdev->iftype = iwm_mode_to_nl80211_iftype(iwm->conf.mode);
  104. ndev = alloc_netdev_mq(0, "wlan%d", ether_setup,
  105. IWM_TX_QUEUES);
  106. if (!ndev) {
  107. dev_err(dev, "no memory for network device instance\n");
  108. goto out_wdev;
  109. }
  110. ndev->netdev_ops = &iwm_netdev_ops;
  111. ndev->wireless_handlers = &iwm_iw_handler_def;
  112. ndev->ieee80211_ptr = wdev;
  113. SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
  114. ret = register_netdev(ndev);
  115. if (ret < 0) {
  116. dev_err(dev, "Failed to register netdev: %d\n", ret);
  117. goto out_ndev;
  118. }
  119. wdev->netdev = ndev;
  120. return iwm;
  121. out_ndev:
  122. free_netdev(ndev);
  123. out_wdev:
  124. iwm_wdev_free(iwm);
  125. return ERR_PTR(ret);
  126. }
  127. void iwm_if_free(struct iwm_priv *iwm)
  128. {
  129. int i;
  130. if (!iwm_to_ndev(iwm))
  131. return;
  132. unregister_netdev(iwm_to_ndev(iwm));
  133. free_netdev(iwm_to_ndev(iwm));
  134. iwm_wdev_free(iwm);
  135. destroy_workqueue(iwm->rx_wq);
  136. for (i = 0; i < IWM_TX_QUEUES; i++)
  137. destroy_workqueue(iwm->txq[i].wq);
  138. }