2 * Copyright (c) 2012-2015 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 int ret
= wil_ioctl(wil
, ifr
->ifr_data
, cmd
);
65 wil_dbg_misc(wil
, "ioctl(0x%04x) -> %d\n", cmd
, ret
);
70 static const struct net_device_ops wil_netdev_ops
= {
73 .ndo_start_xmit
= wil_start_xmit
,
74 .ndo_set_mac_address
= eth_mac_addr
,
75 .ndo_validate_addr
= eth_validate_addr
,
76 .ndo_change_mtu
= wil_change_mtu
,
77 .ndo_do_ioctl
= wil_do_ioctl
,
80 static int wil6210_netdev_poll_rx(struct napi_struct
*napi
, int budget
)
82 struct wil6210_priv
*wil
= container_of(napi
, struct wil6210_priv
,
87 wil_rx_handle(wil
, "a
);
88 done
= budget
- quota
;
92 wil6210_unmask_irq_rx(wil
);
93 wil_dbg_txrx(wil
, "NAPI RX complete\n");
96 wil_dbg_txrx(wil
, "NAPI RX poll(%d) done %d\n", budget
, done
);
101 static int wil6210_netdev_poll_tx(struct napi_struct
*napi
, int budget
)
103 struct wil6210_priv
*wil
= container_of(napi
, struct wil6210_priv
,
108 /* always process ALL Tx complete, regardless budget - it is fast */
109 for (i
= 0; i
< WIL6210_MAX_TX_RINGS
; i
++) {
110 struct vring
*vring
= &wil
->vring_tx
[i
];
115 tx_done
+= wil_tx_complete(wil
, i
);
118 if (tx_done
< budget
) {
120 wil6210_unmask_irq_tx(wil
);
121 wil_dbg_txrx(wil
, "NAPI TX complete\n");
124 wil_dbg_txrx(wil
, "NAPI TX poll(%d) done %d\n", budget
, tx_done
);
126 return min(tx_done
, budget
);
129 static void wil_dev_setup(struct net_device
*dev
)
132 dev
->tx_queue_len
= WIL_TX_Q_LEN_DEFAULT
;
135 void *wil_if_alloc(struct device
*dev
)
137 struct net_device
*ndev
;
138 struct wireless_dev
*wdev
;
139 struct wil6210_priv
*wil
;
140 struct ieee80211_channel
*ch
;
143 wdev
= wil_cfg80211_init(dev
);
145 dev_err(dev
, "wil_cfg80211_init failed\n");
149 wil
= wdev_to_wil(wdev
);
152 wil_dbg_misc(wil
, "%s()\n", __func__
);
154 rc
= wil_priv_init(wil
);
156 dev_err(dev
, "wil_priv_init failed\n");
160 wdev
->iftype
= NL80211_IFTYPE_STATION
; /* TODO */
161 /* default monitor channel */
162 ch
= wdev
->wiphy
->bands
[IEEE80211_BAND_60GHZ
]->channels
;
163 cfg80211_chandef_create(&wdev
->preset_chandef
, ch
, NL80211_CHAN_NO_HT
);
165 ndev
= alloc_netdev(0, "wlan%d", NET_NAME_UNKNOWN
, wil_dev_setup
);
167 dev_err(dev
, "alloc_netdev_mqs failed\n");
172 ndev
->netdev_ops
= &wil_netdev_ops
;
173 wil_set_ethtoolops(ndev
);
174 ndev
->ieee80211_ptr
= wdev
;
175 ndev
->hw_features
= NETIF_F_HW_CSUM
| NETIF_F_RXCSUM
|
176 NETIF_F_SG
| NETIF_F_GRO
|
177 NETIF_F_TSO
| NETIF_F_TSO6
|
180 ndev
->features
|= ndev
->hw_features
;
181 SET_NETDEV_DEV(ndev
, wiphy_dev(wdev
->wiphy
));
184 netif_napi_add(ndev
, &wil
->napi_rx
, wil6210_netdev_poll_rx
,
185 WIL6210_NAPI_BUDGET
);
186 netif_napi_add(ndev
, &wil
->napi_tx
, wil6210_netdev_poll_tx
,
187 WIL6210_NAPI_BUDGET
);
189 netif_tx_stop_all_queues(ndev
);
194 wil_priv_deinit(wil
);
202 void wil_if_free(struct wil6210_priv
*wil
)
204 struct net_device
*ndev
= wil_to_ndev(wil
);
206 wil_dbg_misc(wil
, "%s()\n", __func__
);
211 wil_priv_deinit(wil
);
213 wil_to_ndev(wil
) = NULL
;
219 int wil_if_add(struct wil6210_priv
*wil
)
221 struct net_device
*ndev
= wil_to_ndev(wil
);
224 wil_dbg_misc(wil
, "%s()\n", __func__
);
226 rc
= register_netdev(ndev
);
228 dev_err(&ndev
->dev
, "Failed to register netdev: %d\n", rc
);
235 void wil_if_remove(struct wil6210_priv
*wil
)
237 struct net_device
*ndev
= wil_to_ndev(wil
);
239 wil_dbg_misc(wil
, "%s()\n", __func__
);
241 unregister_netdev(ndev
);