2 * Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
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.
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.
17 #include <linux/etherdevice.h>
21 static int wil_open(struct net_device
*ndev
)
23 struct wil6210_priv
*wil
= ndev_to_wil(ndev
);
25 wil_dbg_misc(wil
, "%s()\n", __func__
);
28 wil_err(wil
, "%s() while in debug_fw mode\n", __func__
);
35 static int wil_stop(struct net_device
*ndev
)
37 struct wil6210_priv
*wil
= ndev_to_wil(ndev
);
39 wil_dbg_misc(wil
, "%s()\n", __func__
);
44 static int wil_change_mtu(struct net_device
*ndev
, int new_mtu
)
46 struct wil6210_priv
*wil
= ndev_to_wil(ndev
);
48 if (new_mtu
< 68 || new_mtu
> mtu_max
) {
49 wil_err(wil
, "invalid MTU %d\n", new_mtu
);
53 wil_dbg_misc(wil
, "change MTU %d -> %d\n", ndev
->mtu
, new_mtu
);
59 static int wil_do_ioctl(struct net_device
*ndev
, struct ifreq
*ifr
, int cmd
)
61 struct wil6210_priv
*wil
= ndev_to_wil(ndev
);
63 return wil_ioctl(wil
, ifr
->ifr_data
, cmd
);
66 static const struct net_device_ops wil_netdev_ops
= {
69 .ndo_start_xmit
= wil_start_xmit
,
70 .ndo_set_mac_address
= eth_mac_addr
,
71 .ndo_validate_addr
= eth_validate_addr
,
72 .ndo_change_mtu
= wil_change_mtu
,
73 .ndo_do_ioctl
= wil_do_ioctl
,
76 static int wil6210_netdev_poll_rx(struct napi_struct
*napi
, int budget
)
78 struct wil6210_priv
*wil
= container_of(napi
, struct wil6210_priv
,
83 wil_rx_handle(wil
, "a
);
84 done
= budget
- quota
;
88 wil6210_unmask_irq_rx(wil
);
89 wil_dbg_txrx(wil
, "NAPI RX complete\n");
92 wil_dbg_txrx(wil
, "NAPI RX poll(%d) done %d\n", budget
, done
);
97 static int wil6210_netdev_poll_tx(struct napi_struct
*napi
, int budget
)
99 struct wil6210_priv
*wil
= container_of(napi
, struct wil6210_priv
,
104 /* always process ALL Tx complete, regardless budget - it is fast */
105 for (i
= 0; i
< WIL6210_MAX_TX_RINGS
; i
++) {
106 struct vring
*vring
= &wil
->vring_tx
[i
];
107 struct vring_tx_data
*txdata
= &wil
->vring_tx_data
[i
];
109 if (!vring
->va
|| !txdata
->enabled
)
112 tx_done
+= wil_tx_complete(wil
, i
);
115 if (tx_done
< budget
) {
117 wil6210_unmask_irq_tx(wil
);
118 wil_dbg_txrx(wil
, "NAPI TX complete\n");
121 wil_dbg_txrx(wil
, "NAPI TX poll(%d) done %d\n", budget
, tx_done
);
123 return min(tx_done
, budget
);
126 static void wil_dev_setup(struct net_device
*dev
)
129 dev
->tx_queue_len
= WIL_TX_Q_LEN_DEFAULT
;
132 void *wil_if_alloc(struct device
*dev
)
134 struct net_device
*ndev
;
135 struct wireless_dev
*wdev
;
136 struct wil6210_priv
*wil
;
137 struct ieee80211_channel
*ch
;
140 wdev
= wil_cfg80211_init(dev
);
142 dev_err(dev
, "wil_cfg80211_init failed\n");
146 wil
= wdev_to_wil(wdev
);
148 wil
->radio_wdev
= wdev
;
150 wil_dbg_misc(wil
, "%s()\n", __func__
);
152 rc
= wil_priv_init(wil
);
154 dev_err(dev
, "wil_priv_init failed\n");
158 wdev
->iftype
= NL80211_IFTYPE_STATION
; /* TODO */
159 /* default monitor channel */
160 ch
= wdev
->wiphy
->bands
[NL80211_BAND_60GHZ
]->channels
;
161 cfg80211_chandef_create(&wdev
->preset_chandef
, ch
, NL80211_CHAN_NO_HT
);
163 ndev
= alloc_netdev(0, "wlan%d", NET_NAME_UNKNOWN
, wil_dev_setup
);
165 dev_err(dev
, "alloc_netdev_mqs failed\n");
170 ndev
->netdev_ops
= &wil_netdev_ops
;
171 wil_set_ethtoolops(ndev
);
172 ndev
->ieee80211_ptr
= wdev
;
173 ndev
->hw_features
= NETIF_F_HW_CSUM
| NETIF_F_RXCSUM
|
174 NETIF_F_SG
| NETIF_F_GRO
|
175 NETIF_F_TSO
| NETIF_F_TSO6
|
178 ndev
->features
|= ndev
->hw_features
;
179 SET_NETDEV_DEV(ndev
, wiphy_dev(wdev
->wiphy
));
182 netif_napi_add(ndev
, &wil
->napi_rx
, wil6210_netdev_poll_rx
,
183 WIL6210_NAPI_BUDGET
);
184 netif_tx_napi_add(ndev
, &wil
->napi_tx
, wil6210_netdev_poll_tx
,
185 WIL6210_NAPI_BUDGET
);
187 netif_tx_stop_all_queues(ndev
);
192 wil_priv_deinit(wil
);
200 void wil_if_free(struct wil6210_priv
*wil
)
202 struct net_device
*ndev
= wil_to_ndev(wil
);
204 wil_dbg_misc(wil
, "%s()\n", __func__
);
209 wil_priv_deinit(wil
);
211 wil_to_ndev(wil
) = NULL
;
217 int wil_if_add(struct wil6210_priv
*wil
)
219 struct net_device
*ndev
= wil_to_ndev(wil
);
222 wil_dbg_misc(wil
, "%s()\n", __func__
);
224 rc
= register_netdev(ndev
);
226 dev_err(&ndev
->dev
, "Failed to register netdev: %d\n", rc
);
233 void wil_if_remove(struct wil6210_priv
*wil
)
235 struct net_device
*ndev
= wil_to_ndev(wil
);
237 wil_dbg_misc(wil
, "%s()\n", __func__
);
239 unregister_netdev(ndev
);