netdev.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  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 "commands.h"
  50. #include "cfg80211.h"
  51. #include "debug.h"
  52. static int iwm_open(struct net_device *ndev)
  53. {
  54. struct iwm_priv *iwm = ndev_to_iwm(ndev);
  55. int ret = 0;
  56. if (!test_bit(IWM_RADIO_RFKILL_SW, &iwm->radio))
  57. ret = iwm_up(iwm);
  58. return ret;
  59. }
  60. static int iwm_stop(struct net_device *ndev)
  61. {
  62. struct iwm_priv *iwm = ndev_to_iwm(ndev);
  63. int ret = 0;
  64. if (!test_bit(IWM_RADIO_RFKILL_SW, &iwm->radio))
  65. ret = iwm_down(iwm);
  66. return ret;
  67. }
  68. /*
  69. * iwm AC to queue mapping
  70. *
  71. * AC_VO -> queue 3
  72. * AC_VI -> queue 2
  73. * AC_BE -> queue 1
  74. * AC_BK -> queue 0
  75. */
  76. static const u16 iwm_1d_to_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
  77. static u16 iwm_select_queue(struct net_device *dev, struct sk_buff *skb)
  78. {
  79. skb->priority = cfg80211_classify8021d(skb);
  80. return iwm_1d_to_queue[skb->priority];
  81. }
  82. static const struct net_device_ops iwm_netdev_ops = {
  83. .ndo_open = iwm_open,
  84. .ndo_stop = iwm_stop,
  85. .ndo_start_xmit = iwm_xmit_frame,
  86. .ndo_select_queue = iwm_select_queue,
  87. };
  88. void *iwm_if_alloc(int sizeof_bus, struct device *dev,
  89. struct iwm_if_ops *if_ops)
  90. {
  91. struct net_device *ndev;
  92. struct wireless_dev *wdev;
  93. struct iwm_priv *iwm;
  94. int ret = 0;
  95. wdev = iwm_wdev_alloc(sizeof_bus, dev);
  96. if (!wdev) {
  97. dev_err(dev, "no memory for wireless device instance\n");
  98. return ERR_PTR(-ENOMEM);
  99. }
  100. iwm = wdev_to_iwm(wdev);
  101. iwm->bus_ops = if_ops;
  102. iwm->wdev = wdev;
  103. ret = iwm_priv_init(iwm);
  104. if (ret) {
  105. dev_err(dev, "failed to init iwm_priv\n");
  106. goto out_wdev;
  107. }
  108. wdev->iftype = iwm_mode_to_nl80211_iftype(iwm->conf.mode);
  109. ndev = alloc_netdev_mq(0, "wlan%d", ether_setup, IWM_TX_QUEUES);
  110. if (!ndev) {
  111. dev_err(dev, "no memory for network device instance\n");
  112. goto out_priv;
  113. }
  114. ndev->netdev_ops = &iwm_netdev_ops;
  115. ndev->wireless_handlers = &iwm_iw_handler_def;
  116. ndev->ieee80211_ptr = wdev;
  117. SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
  118. wdev->netdev = ndev;
  119. iwm->umac_profile = kmalloc(sizeof(struct iwm_umac_profile),
  120. GFP_KERNEL);
  121. if (!iwm->umac_profile) {
  122. dev_err(dev, "Couldn't alloc memory for profile\n");
  123. goto out_profile;
  124. }
  125. iwm_init_default_profile(iwm, iwm->umac_profile);
  126. return iwm;
  127. out_profile:
  128. free_netdev(ndev);
  129. out_priv:
  130. iwm_priv_deinit(iwm);
  131. out_wdev:
  132. iwm_wdev_free(iwm);
  133. return ERR_PTR(ret);
  134. }
  135. void iwm_if_free(struct iwm_priv *iwm)
  136. {
  137. if (!iwm_to_ndev(iwm))
  138. return;
  139. free_netdev(iwm_to_ndev(iwm));
  140. iwm_wdev_free(iwm);
  141. iwm_priv_deinit(iwm);
  142. kfree(iwm->umac_profile);
  143. iwm->umac_profile = NULL;
  144. }
  145. int iwm_if_add(struct iwm_priv *iwm)
  146. {
  147. struct net_device *ndev = iwm_to_ndev(iwm);
  148. int ret;
  149. ret = register_netdev(ndev);
  150. if (ret < 0) {
  151. dev_err(&ndev->dev, "Failed to register netdev: %d\n", ret);
  152. return ret;
  153. }
  154. return 0;
  155. }
  156. void iwm_if_remove(struct iwm_priv *iwm)
  157. {
  158. unregister_netdev(iwm_to_ndev(iwm));
  159. }