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 17 #include <linux/module.h> 18 #include <linux/netdevice.h> 19 #include <linux/etherdevice.h> 20 #include <linux/slab.h> 21 22 #include "wil6210.h" 23 24 static int wil_open(struct net_device *ndev) 25 { 26 struct wil6210_priv *wil = ndev_to_wil(ndev); 27 28 return wil_up(wil); 29 } 30 31 static int wil_stop(struct net_device *ndev) 32 { 33 struct wil6210_priv *wil = ndev_to_wil(ndev); 34 35 return wil_down(wil); 36 } 37 38 /* 39 * AC to queue mapping 40 * 41 * AC_VO -> queue 3 42 * AC_VI -> queue 2 43 * AC_BE -> queue 1 44 * AC_BK -> queue 0 45 */ 46 static u16 wil_select_queue(struct net_device *ndev, struct sk_buff *skb) 47 { 48 static const u16 wil_1d_to_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; 49 struct wil6210_priv *wil = ndev_to_wil(ndev); 50 u16 rc; 51 52 skb->priority = cfg80211_classify8021d(skb); 53 54 rc = wil_1d_to_queue[skb->priority]; 55 56 wil_dbg_TXRX(wil, "%s() %d -> %d\n", __func__, (int)skb->priority, 57 (int)rc); 58 59 return rc; 60 } 61 62 static const struct net_device_ops wil_netdev_ops = { 63 .ndo_open = wil_open, 64 .ndo_stop = wil_stop, 65 .ndo_start_xmit = wil_start_xmit, 66 .ndo_select_queue = wil_select_queue, 67 .ndo_set_mac_address = eth_mac_addr, 68 .ndo_validate_addr = eth_validate_addr, 69 }; 70 71 void *wil_if_alloc(struct device *dev, void __iomem *csr) 72 { 73 struct net_device *ndev; 74 struct wireless_dev *wdev; 75 struct wil6210_priv *wil; 76 struct ieee80211_channel *ch; 77 int rc = 0; 78 79 wdev = wil_cfg80211_init(dev); 80 if (IS_ERR(wdev)) { 81 dev_err(dev, "wil_cfg80211_init failed\n"); 82 return wdev; 83 } 84 85 wil = wdev_to_wil(wdev); 86 wil->csr = csr; 87 wil->wdev = wdev; 88 89 rc = wil_priv_init(wil); 90 if (rc) { 91 dev_err(dev, "wil_priv_init failed\n"); 92 goto out_wdev; 93 } 94 95 wdev->iftype = NL80211_IFTYPE_STATION; /* TODO */ 96 /* default monitor channel */ 97 ch = wdev->wiphy->bands[IEEE80211_BAND_60GHZ]->channels; 98 cfg80211_chandef_create(&wdev->preset_chandef, ch, NL80211_CHAN_NO_HT); 99 100 ndev = alloc_netdev_mqs(0, "wlan%d", ether_setup, WIL6210_TX_QUEUES, 1); 101 if (!ndev) { 102 dev_err(dev, "alloc_netdev_mqs failed\n"); 103 rc = -ENOMEM; 104 goto out_priv; 105 } 106 107 ndev->netdev_ops = &wil_netdev_ops; 108 ndev->ieee80211_ptr = wdev; 109 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); 110 wdev->netdev = ndev; 111 112 wil_link_off(wil); 113 114 return wil; 115 116 out_priv: 117 wil_priv_deinit(wil); 118 119 out_wdev: 120 wil_wdev_free(wil); 121 122 return ERR_PTR(rc); 123 } 124 125 void wil_if_free(struct wil6210_priv *wil) 126 { 127 struct net_device *ndev = wil_to_ndev(wil); 128 if (!ndev) 129 return; 130 131 free_netdev(ndev); 132 wil_priv_deinit(wil); 133 wil_wdev_free(wil); 134 } 135 136 int wil_if_add(struct wil6210_priv *wil) 137 { 138 struct net_device *ndev = wil_to_ndev(wil); 139 int rc; 140 141 rc = register_netdev(ndev); 142 if (rc < 0) { 143 dev_err(&ndev->dev, "Failed to register netdev: %d\n", rc); 144 return rc; 145 } 146 147 wil_link_off(wil); 148 149 return 0; 150 } 151 152 void wil_if_remove(struct wil6210_priv *wil) 153 { 154 struct net_device *ndev = wil_to_ndev(wil); 155 156 unregister_netdev(ndev); 157 } 158