netdev.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /*
  2. * Copyright (c) 2012 Qualcomm Atheros, Inc.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include <linux/etherdevice.h>
  17. #include "wil6210.h"
  18. static int wil_open(struct net_device *ndev)
  19. {
  20. struct wil6210_priv *wil = ndev_to_wil(ndev);
  21. return wil_up(wil);
  22. }
  23. static int wil_stop(struct net_device *ndev)
  24. {
  25. struct wil6210_priv *wil = ndev_to_wil(ndev);
  26. return wil_down(wil);
  27. }
  28. static int wil_change_mtu(struct net_device *ndev, int new_mtu)
  29. {
  30. struct wil6210_priv *wil = ndev_to_wil(ndev);
  31. if (new_mtu < 68 || new_mtu > IEEE80211_MAX_DATA_LEN_DMG)
  32. return -EINVAL;
  33. wil_dbg_misc(wil, "change MTU %d -> %d\n", ndev->mtu, new_mtu);
  34. ndev->mtu = new_mtu;
  35. return 0;
  36. }
  37. static const struct net_device_ops wil_netdev_ops = {
  38. .ndo_open = wil_open,
  39. .ndo_stop = wil_stop,
  40. .ndo_start_xmit = wil_start_xmit,
  41. .ndo_set_mac_address = eth_mac_addr,
  42. .ndo_validate_addr = eth_validate_addr,
  43. .ndo_change_mtu = wil_change_mtu,
  44. };
  45. static int wil6210_netdev_poll_rx(struct napi_struct *napi, int budget)
  46. {
  47. struct wil6210_priv *wil = container_of(napi, struct wil6210_priv,
  48. napi_rx);
  49. int quota = budget;
  50. int done;
  51. wil_rx_handle(wil, &quota);
  52. done = budget - quota;
  53. if (done <= 1) { /* burst ends - only one packet processed */
  54. napi_complete(napi);
  55. wil6210_unmask_irq_rx(wil);
  56. wil_dbg_txrx(wil, "NAPI RX complete\n");
  57. }
  58. wil_dbg_txrx(wil, "NAPI RX poll(%d) done %d\n", budget, done);
  59. return done;
  60. }
  61. static int wil6210_netdev_poll_tx(struct napi_struct *napi, int budget)
  62. {
  63. struct wil6210_priv *wil = container_of(napi, struct wil6210_priv,
  64. napi_tx);
  65. int tx_done = 0;
  66. uint i;
  67. /* always process ALL Tx complete, regardless budget - it is fast */
  68. for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
  69. struct vring *vring = &wil->vring_tx[i];
  70. if (!vring->va)
  71. continue;
  72. tx_done += wil_tx_complete(wil, i);
  73. }
  74. if (tx_done <= 1) { /* burst ends - only one packet processed */
  75. napi_complete(napi);
  76. wil6210_unmask_irq_tx(wil);
  77. wil_dbg_txrx(wil, "NAPI TX complete\n");
  78. }
  79. wil_dbg_txrx(wil, "NAPI TX poll(%d) done %d\n", budget, tx_done);
  80. return min(tx_done, budget);
  81. }
  82. void *wil_if_alloc(struct device *dev, void __iomem *csr)
  83. {
  84. struct net_device *ndev;
  85. struct wireless_dev *wdev;
  86. struct wil6210_priv *wil;
  87. struct ieee80211_channel *ch;
  88. int rc = 0;
  89. wdev = wil_cfg80211_init(dev);
  90. if (IS_ERR(wdev)) {
  91. dev_err(dev, "wil_cfg80211_init failed\n");
  92. return wdev;
  93. }
  94. wil = wdev_to_wil(wdev);
  95. wil->csr = csr;
  96. wil->wdev = wdev;
  97. rc = wil_priv_init(wil);
  98. if (rc) {
  99. dev_err(dev, "wil_priv_init failed\n");
  100. goto out_wdev;
  101. }
  102. wdev->iftype = NL80211_IFTYPE_STATION; /* TODO */
  103. /* default monitor channel */
  104. ch = wdev->wiphy->bands[IEEE80211_BAND_60GHZ]->channels;
  105. cfg80211_chandef_create(&wdev->preset_chandef, ch, NL80211_CHAN_NO_HT);
  106. ndev = alloc_netdev(0, "wlan%d", ether_setup);
  107. if (!ndev) {
  108. dev_err(dev, "alloc_netdev_mqs failed\n");
  109. rc = -ENOMEM;
  110. goto out_priv;
  111. }
  112. ndev->netdev_ops = &wil_netdev_ops;
  113. ndev->ieee80211_ptr = wdev;
  114. ndev->hw_features = NETIF_F_HW_CSUM | NETIF_F_RXCSUM |
  115. NETIF_F_SG | NETIF_F_GRO;
  116. ndev->features |= ndev->hw_features;
  117. SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
  118. wdev->netdev = ndev;
  119. netif_napi_add(ndev, &wil->napi_rx, wil6210_netdev_poll_rx,
  120. WIL6210_NAPI_BUDGET);
  121. netif_napi_add(ndev, &wil->napi_tx, wil6210_netdev_poll_tx,
  122. WIL6210_NAPI_BUDGET);
  123. wil_link_off(wil);
  124. return wil;
  125. out_priv:
  126. wil_priv_deinit(wil);
  127. out_wdev:
  128. wil_wdev_free(wil);
  129. return ERR_PTR(rc);
  130. }
  131. void wil_if_free(struct wil6210_priv *wil)
  132. {
  133. struct net_device *ndev = wil_to_ndev(wil);
  134. if (!ndev)
  135. return;
  136. free_netdev(ndev);
  137. wil_priv_deinit(wil);
  138. wil_wdev_free(wil);
  139. }
  140. int wil_if_add(struct wil6210_priv *wil)
  141. {
  142. struct net_device *ndev = wil_to_ndev(wil);
  143. int rc;
  144. rc = register_netdev(ndev);
  145. if (rc < 0) {
  146. dev_err(&ndev->dev, "Failed to register netdev: %d\n", rc);
  147. return rc;
  148. }
  149. wil_link_off(wil);
  150. return 0;
  151. }
  152. void wil_if_remove(struct wil6210_priv *wil)
  153. {
  154. struct net_device *ndev = wil_to_ndev(wil);
  155. unregister_netdev(ndev);
  156. }