netdev.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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. static u16 iwm_select_queue(struct net_device *dev, struct sk_buff *skb)
  72. {
  73. skb->priority = cfg80211_classify8021d(skb);
  74. return iwm_1d_to_queue[skb->priority];
  75. }
  76. static const struct net_device_ops iwm_netdev_ops = {
  77. .ndo_open = iwm_open,
  78. .ndo_stop = iwm_stop,
  79. .ndo_start_xmit = iwm_xmit_frame,
  80. .ndo_select_queue = iwm_select_queue,
  81. };
  82. void *iwm_if_alloc(int sizeof_bus, struct device *dev,
  83. struct iwm_if_ops *if_ops)
  84. {
  85. struct net_device *ndev;
  86. struct wireless_dev *wdev;
  87. struct iwm_priv *iwm;
  88. int ret = 0;
  89. wdev = iwm_wdev_alloc(sizeof_bus, dev);
  90. if (IS_ERR(wdev))
  91. return wdev;
  92. iwm = wdev_to_iwm(wdev);
  93. iwm->bus_ops = if_ops;
  94. iwm->wdev = wdev;
  95. ret = iwm_priv_init(iwm);
  96. if (ret) {
  97. dev_err(dev, "failed to init iwm_priv\n");
  98. goto out_wdev;
  99. }
  100. wdev->iftype = iwm_mode_to_nl80211_iftype(iwm->conf.mode);
  101. ndev = alloc_netdev_mq(0, "wlan%d", ether_setup, IWM_TX_QUEUES);
  102. if (!ndev) {
  103. dev_err(dev, "no memory for network device instance\n");
  104. goto out_priv;
  105. }
  106. ndev->netdev_ops = &iwm_netdev_ops;
  107. ndev->ieee80211_ptr = wdev;
  108. SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
  109. wdev->netdev = ndev;
  110. iwm->umac_profile = kmalloc(sizeof(struct iwm_umac_profile),
  111. GFP_KERNEL);
  112. if (!iwm->umac_profile) {
  113. dev_err(dev, "Couldn't alloc memory for profile\n");
  114. goto out_profile;
  115. }
  116. iwm_init_default_profile(iwm, iwm->umac_profile);
  117. return iwm;
  118. out_profile:
  119. free_netdev(ndev);
  120. out_priv:
  121. iwm_priv_deinit(iwm);
  122. out_wdev:
  123. iwm_wdev_free(iwm);
  124. return ERR_PTR(ret);
  125. }
  126. void iwm_if_free(struct iwm_priv *iwm)
  127. {
  128. if (!iwm_to_ndev(iwm))
  129. return;
  130. free_netdev(iwm_to_ndev(iwm));
  131. iwm_priv_deinit(iwm);
  132. kfree(iwm->umac_profile);
  133. iwm->umac_profile = NULL;
  134. iwm_wdev_free(iwm);
  135. }
  136. int iwm_if_add(struct iwm_priv *iwm)
  137. {
  138. struct net_device *ndev = iwm_to_ndev(iwm);
  139. int ret;
  140. ret = register_netdev(ndev);
  141. if (ret < 0) {
  142. dev_err(&ndev->dev, "Failed to register netdev: %d\n", ret);
  143. return ret;
  144. }
  145. return 0;
  146. }
  147. void iwm_if_remove(struct iwm_priv *iwm)
  148. {
  149. unregister_netdev(iwm_to_ndev(iwm));
  150. }