netdev.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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 const struct net_device_ops wil_netdev_ops = {
  29. .ndo_open = wil_open,
  30. .ndo_stop = wil_stop,
  31. .ndo_start_xmit = wil_start_xmit,
  32. .ndo_set_mac_address = eth_mac_addr,
  33. .ndo_validate_addr = eth_validate_addr,
  34. };
  35. void *wil_if_alloc(struct device *dev, void __iomem *csr)
  36. {
  37. struct net_device *ndev;
  38. struct wireless_dev *wdev;
  39. struct wil6210_priv *wil;
  40. struct ieee80211_channel *ch;
  41. int rc = 0;
  42. wdev = wil_cfg80211_init(dev);
  43. if (IS_ERR(wdev)) {
  44. dev_err(dev, "wil_cfg80211_init failed\n");
  45. return wdev;
  46. }
  47. wil = wdev_to_wil(wdev);
  48. wil->csr = csr;
  49. wil->wdev = wdev;
  50. rc = wil_priv_init(wil);
  51. if (rc) {
  52. dev_err(dev, "wil_priv_init failed\n");
  53. goto out_wdev;
  54. }
  55. wdev->iftype = NL80211_IFTYPE_STATION; /* TODO */
  56. /* default monitor channel */
  57. ch = wdev->wiphy->bands[IEEE80211_BAND_60GHZ]->channels;
  58. cfg80211_chandef_create(&wdev->preset_chandef, ch, NL80211_CHAN_NO_HT);
  59. ndev = alloc_netdev(0, "wlan%d", ether_setup);
  60. if (!ndev) {
  61. dev_err(dev, "alloc_netdev_mqs failed\n");
  62. rc = -ENOMEM;
  63. goto out_priv;
  64. }
  65. ndev->netdev_ops = &wil_netdev_ops;
  66. ndev->ieee80211_ptr = wdev;
  67. SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
  68. wdev->netdev = ndev;
  69. wil_link_off(wil);
  70. return wil;
  71. out_priv:
  72. wil_priv_deinit(wil);
  73. out_wdev:
  74. wil_wdev_free(wil);
  75. return ERR_PTR(rc);
  76. }
  77. void wil_if_free(struct wil6210_priv *wil)
  78. {
  79. struct net_device *ndev = wil_to_ndev(wil);
  80. if (!ndev)
  81. return;
  82. free_netdev(ndev);
  83. wil_priv_deinit(wil);
  84. wil_wdev_free(wil);
  85. }
  86. int wil_if_add(struct wil6210_priv *wil)
  87. {
  88. struct net_device *ndev = wil_to_ndev(wil);
  89. int rc;
  90. rc = register_netdev(ndev);
  91. if (rc < 0) {
  92. dev_err(&ndev->dev, "Failed to register netdev: %d\n", rc);
  93. return rc;
  94. }
  95. wil_link_off(wil);
  96. return 0;
  97. }
  98. void wil_if_remove(struct wil6210_priv *wil)
  99. {
  100. struct net_device *ndev = wil_to_ndev(wil);
  101. unregister_netdev(ndev);
  102. }