2 * Copyright (c) 2012 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
);
28 static int wil_stop(struct net_device
*ndev
)
30 struct wil6210_priv
*wil
= ndev_to_wil(ndev
);
35 static const struct net_device_ops wil_netdev_ops
= {
38 .ndo_start_xmit
= wil_start_xmit
,
39 .ndo_set_mac_address
= eth_mac_addr
,
40 .ndo_validate_addr
= eth_validate_addr
,
43 static int wil6210_netdev_poll_rx(struct napi_struct
*napi
, int budget
)
45 struct wil6210_priv
*wil
= container_of(napi
, struct wil6210_priv
,
50 wil_rx_handle(wil
, "a
);
51 done
= budget
- quota
;
53 if (done
<= 1) { /* burst ends - only one packet processed */
55 wil6210_unmask_irq_rx(wil
);
56 wil_dbg_txrx(wil
, "NAPI RX complete\n");
59 wil_dbg_txrx(wil
, "NAPI RX poll(%d) done %d\n", budget
, done
);
64 static int wil6210_netdev_poll_tx(struct napi_struct
*napi
, int budget
)
66 struct wil6210_priv
*wil
= container_of(napi
, struct wil6210_priv
,
71 /* always process ALL Tx complete, regardless budget - it is fast */
72 for (i
= 0; i
< WIL6210_MAX_TX_RINGS
; i
++) {
73 struct vring
*vring
= &wil
->vring_tx
[i
];
78 tx_done
+= wil_tx_complete(wil
, i
);
81 if (tx_done
<= 1) { /* burst ends - only one packet processed */
83 wil6210_unmask_irq_tx(wil
);
84 wil_dbg_txrx(wil
, "NAPI TX complete\n");
87 wil_dbg_txrx(wil
, "NAPI TX poll(%d) done %d\n", budget
, tx_done
);
89 return min(tx_done
, budget
);
92 void *wil_if_alloc(struct device
*dev
, void __iomem
*csr
)
94 struct net_device
*ndev
;
95 struct wireless_dev
*wdev
;
96 struct wil6210_priv
*wil
;
97 struct ieee80211_channel
*ch
;
100 wdev
= wil_cfg80211_init(dev
);
102 dev_err(dev
, "wil_cfg80211_init failed\n");
106 wil
= wdev_to_wil(wdev
);
110 rc
= wil_priv_init(wil
);
112 dev_err(dev
, "wil_priv_init failed\n");
116 wdev
->iftype
= NL80211_IFTYPE_STATION
; /* TODO */
117 /* default monitor channel */
118 ch
= wdev
->wiphy
->bands
[IEEE80211_BAND_60GHZ
]->channels
;
119 cfg80211_chandef_create(&wdev
->preset_chandef
, ch
, NL80211_CHAN_NO_HT
);
121 ndev
= alloc_netdev(0, "wlan%d", ether_setup
);
123 dev_err(dev
, "alloc_netdev_mqs failed\n");
128 ndev
->netdev_ops
= &wil_netdev_ops
;
129 ndev
->ieee80211_ptr
= wdev
;
130 SET_NETDEV_DEV(ndev
, wiphy_dev(wdev
->wiphy
));
133 netif_napi_add(ndev
, &wil
->napi_rx
, wil6210_netdev_poll_rx
,
134 WIL6210_NAPI_BUDGET
);
135 netif_napi_add(ndev
, &wil
->napi_tx
, wil6210_netdev_poll_tx
,
136 WIL6210_NAPI_BUDGET
);
143 wil_priv_deinit(wil
);
151 void wil_if_free(struct wil6210_priv
*wil
)
153 struct net_device
*ndev
= wil_to_ndev(wil
);
158 wil_priv_deinit(wil
);
162 int wil_if_add(struct wil6210_priv
*wil
)
164 struct net_device
*ndev
= wil_to_ndev(wil
);
167 rc
= register_netdev(ndev
);
169 dev_err(&ndev
->dev
, "Failed to register netdev: %d\n", rc
);
178 void wil_if_remove(struct wil6210_priv
*wil
)
180 struct net_device
*ndev
= wil_to_ndev(wil
);
182 unregister_netdev(ndev
);