netdev.c 4.3 KB

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