2 * Copyright (c) 2012-2017 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
);
26 wil_dbg_misc(wil
, "open\n");
29 test_bit(WMI_FW_CAPABILITY_WMI_ONLY
, wil
->fw_capabilities
)) {
30 wil_err(wil
, "while in debug_fw or wmi_only mode\n");
34 rc
= wil_pm_runtime_get(wil
);
40 wil_pm_runtime_put(wil
);
45 static int wil_stop(struct net_device
*ndev
)
47 struct wil6210_priv
*wil
= ndev_to_wil(ndev
);
50 wil_dbg_misc(wil
, "stop\n");
54 wil_pm_runtime_put(wil
);
59 static const struct net_device_ops wil_netdev_ops
= {
62 .ndo_start_xmit
= wil_start_xmit
,
63 .ndo_set_mac_address
= eth_mac_addr
,
64 .ndo_validate_addr
= eth_validate_addr
,
67 static int wil6210_netdev_poll_rx(struct napi_struct
*napi
, int budget
)
69 struct wil6210_priv
*wil
= container_of(napi
, struct wil6210_priv
,
74 wil_rx_handle(wil
, "a
);
75 done
= budget
- quota
;
78 napi_complete_done(napi
, done
);
79 wil6210_unmask_irq_rx(wil
);
80 wil_dbg_txrx(wil
, "NAPI RX complete\n");
83 wil_dbg_txrx(wil
, "NAPI RX poll(%d) done %d\n", budget
, done
);
88 static int wil6210_netdev_poll_tx(struct napi_struct
*napi
, int budget
)
90 struct wil6210_priv
*wil
= container_of(napi
, struct wil6210_priv
,
95 /* always process ALL Tx complete, regardless budget - it is fast */
96 for (i
= 0; i
< WIL6210_MAX_TX_RINGS
; i
++) {
97 struct vring
*vring
= &wil
->vring_tx
[i
];
98 struct vring_tx_data
*txdata
= &wil
->vring_tx_data
[i
];
100 if (!vring
->va
|| !txdata
->enabled
)
103 tx_done
+= wil_tx_complete(wil
, i
);
106 if (tx_done
< budget
) {
108 wil6210_unmask_irq_tx(wil
);
109 wil_dbg_txrx(wil
, "NAPI TX complete\n");
112 wil_dbg_txrx(wil
, "NAPI TX poll(%d) done %d\n", budget
, tx_done
);
114 return min(tx_done
, budget
);
117 static void wil_dev_setup(struct net_device
*dev
)
120 dev
->max_mtu
= mtu_max
;
121 dev
->tx_queue_len
= WIL_TX_Q_LEN_DEFAULT
;
124 void *wil_if_alloc(struct device
*dev
)
126 struct net_device
*ndev
;
127 struct wireless_dev
*wdev
;
128 struct wil6210_priv
*wil
;
129 struct ieee80211_channel
*ch
;
132 wdev
= wil_cfg80211_init(dev
);
134 dev_err(dev
, "wil_cfg80211_init failed\n");
138 wil
= wdev_to_wil(wdev
);
140 wil
->radio_wdev
= wdev
;
142 wil_dbg_misc(wil
, "if_alloc\n");
144 rc
= wil_priv_init(wil
);
146 dev_err(dev
, "wil_priv_init failed\n");
150 wdev
->iftype
= NL80211_IFTYPE_STATION
; /* TODO */
151 /* default monitor channel */
152 ch
= wdev
->wiphy
->bands
[NL80211_BAND_60GHZ
]->channels
;
153 cfg80211_chandef_create(&wil
->monitor_chandef
, ch
, NL80211_CHAN_NO_HT
);
155 ndev
= alloc_netdev(0, "wlan%d", NET_NAME_UNKNOWN
, wil_dev_setup
);
157 dev_err(dev
, "alloc_netdev_mqs failed\n");
162 ndev
->netdev_ops
= &wil_netdev_ops
;
163 wil_set_ethtoolops(ndev
);
164 ndev
->ieee80211_ptr
= wdev
;
165 ndev
->hw_features
= NETIF_F_HW_CSUM
| NETIF_F_RXCSUM
|
166 NETIF_F_SG
| NETIF_F_GRO
|
167 NETIF_F_TSO
| NETIF_F_TSO6
|
170 ndev
->features
|= ndev
->hw_features
;
171 SET_NETDEV_DEV(ndev
, wiphy_dev(wdev
->wiphy
));
177 wil_priv_deinit(wil
);
185 void wil_if_free(struct wil6210_priv
*wil
)
187 struct net_device
*ndev
= wil_to_ndev(wil
);
189 wil_dbg_misc(wil
, "if_free\n");
194 wil_priv_deinit(wil
);
196 wil_to_ndev(wil
) = NULL
;
202 int wil_if_add(struct wil6210_priv
*wil
)
204 struct wireless_dev
*wdev
= wil_to_wdev(wil
);
205 struct wiphy
*wiphy
= wdev
->wiphy
;
206 struct net_device
*ndev
= wil_to_ndev(wil
);
209 wil_dbg_misc(wil
, "entered");
211 strlcpy(wiphy
->fw_version
, wil
->fw_version
, sizeof(wiphy
->fw_version
));
213 rc
= wiphy_register(wiphy
);
215 wil_err(wil
, "failed to register wiphy, err %d\n", rc
);
219 netif_napi_add(ndev
, &wil
->napi_rx
, wil6210_netdev_poll_rx
,
220 WIL6210_NAPI_BUDGET
);
221 netif_tx_napi_add(ndev
, &wil
->napi_tx
, wil6210_netdev_poll_tx
,
222 WIL6210_NAPI_BUDGET
);
224 wil_update_net_queues_bh(wil
, NULL
, true);
226 rc
= register_netdev(ndev
);
228 dev_err(&ndev
->dev
, "Failed to register netdev: %d\n", rc
);
235 wiphy_unregister(wdev
->wiphy
);
239 void wil_if_remove(struct wil6210_priv
*wil
)
241 struct net_device
*ndev
= wil_to_ndev(wil
);
242 struct wireless_dev
*wdev
= wil_to_wdev(wil
);
244 wil_dbg_misc(wil
, "if_remove\n");
246 unregister_netdev(ndev
);
247 wiphy_unregister(wdev
->wiphy
);