netdev.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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. return iwm_up(iwm);
  56. }
  57. static int iwm_stop(struct net_device *ndev)
  58. {
  59. struct iwm_priv *iwm = ndev_to_iwm(ndev);
  60. return iwm_down(iwm);
  61. }
  62. /*
  63. * iwm AC to queue mapping
  64. *
  65. * AC_VO -> queue 3
  66. * AC_VI -> queue 2
  67. * AC_BE -> queue 1
  68. * AC_BK -> queue 0
  69. */
  70. static const u16 iwm_1d_to_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
  71. int iwm_tid_to_queue(u16 tid)
  72. {
  73. if (tid > IWM_UMAC_TID_NR - 2)
  74. return -EINVAL;
  75. return iwm_1d_to_queue[tid];
  76. }
  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 (IS_ERR(wdev))
  97. return wdev;
  98. iwm = wdev_to_iwm(wdev);
  99. iwm->bus_ops = if_ops;
  100. iwm->wdev = wdev;
  101. ret = iwm_priv_init(iwm);
  102. if (ret) {
  103. dev_err(dev, "failed to init iwm_priv\n");
  104. goto out_wdev;
  105. }
  106. wdev->iftype = iwm_mode_to_nl80211_iftype(iwm->conf.mode);
  107. ndev = alloc_netdev_mq(0, "wlan%d", ether_setup, IWM_TX_QUEUES);
  108. if (!ndev) {
  109. dev_err(dev, "no memory for network device instance\n");
  110. goto out_priv;
  111. }
  112. ndev->netdev_ops = &iwm_netdev_ops;
  113. ndev->ieee80211_ptr = wdev;
  114. SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
  115. wdev->netdev = ndev;
  116. iwm->umac_profile = kmalloc(sizeof(struct iwm_umac_profile),
  117. GFP_KERNEL);
  118. if (!iwm->umac_profile) {
  119. dev_err(dev, "Couldn't alloc memory for profile\n");
  120. goto out_profile;
  121. }
  122. iwm_init_default_profile(iwm, iwm->umac_profile);
  123. return iwm;
  124. out_profile:
  125. free_netdev(ndev);
  126. out_priv:
  127. iwm_priv_deinit(iwm);
  128. out_wdev:
  129. iwm_wdev_free(iwm);
  130. return ERR_PTR(ret);
  131. }
  132. void iwm_if_free(struct iwm_priv *iwm)
  133. {
  134. if (!iwm_to_ndev(iwm))
  135. return;
  136. cancel_delayed_work_sync(&iwm->ct_kill_delay);
  137. free_netdev(iwm_to_ndev(iwm));
  138. iwm_priv_deinit(iwm);
  139. kfree(iwm->umac_profile);
  140. iwm->umac_profile = NULL;
  141. iwm_wdev_free(iwm);
  142. }
  143. int iwm_if_add(struct iwm_priv *iwm)
  144. {
  145. struct net_device *ndev = iwm_to_ndev(iwm);
  146. int ret;
  147. ret = register_netdev(ndev);
  148. if (ret < 0) {
  149. dev_err(&ndev->dev, "Failed to register netdev: %d\n", ret);
  150. return ret;
  151. }
  152. return 0;
  153. }
  154. void iwm_if_remove(struct iwm_priv *iwm)
  155. {
  156. unregister_netdev(iwm_to_ndev(iwm));
  157. }