diff options
Diffstat (limited to 'drivers/net/wireless/ath/wil6210/netdev.c')
| -rw-r--r-- | drivers/net/wireless/ath/wil6210/netdev.c | 132 | 
1 files changed, 132 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c new file mode 100644 index 00000000000..8ce2e33dce2 --- /dev/null +++ b/drivers/net/wireless/ath/wil6210/netdev.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2012 Qualcomm Atheros, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <linux/module.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/slab.h> + +#include "wil6210.h" + +static int wil_open(struct net_device *ndev) +{ +	struct wil6210_priv *wil = ndev_to_wil(ndev); + +	return wil_up(wil); +} + +static int wil_stop(struct net_device *ndev) +{ +	struct wil6210_priv *wil = ndev_to_wil(ndev); + +	return wil_down(wil); +} + +static const struct net_device_ops wil_netdev_ops = { +	.ndo_open		= wil_open, +	.ndo_stop		= wil_stop, +	.ndo_start_xmit		= wil_start_xmit, +	.ndo_set_mac_address	= eth_mac_addr, +	.ndo_validate_addr	= eth_validate_addr, +}; + +void *wil_if_alloc(struct device *dev, void __iomem *csr) +{ +	struct net_device *ndev; +	struct wireless_dev *wdev; +	struct wil6210_priv *wil; +	struct ieee80211_channel *ch; +	int rc = 0; + +	wdev = wil_cfg80211_init(dev); +	if (IS_ERR(wdev)) { +		dev_err(dev, "wil_cfg80211_init failed\n"); +		return wdev; +	} + +	wil = wdev_to_wil(wdev); +	wil->csr = csr; +	wil->wdev = wdev; + +	rc = wil_priv_init(wil); +	if (rc) { +		dev_err(dev, "wil_priv_init failed\n"); +		goto out_wdev; +	} + +	wdev->iftype = NL80211_IFTYPE_STATION; /* TODO */ +	/* default monitor channel */ +	ch = wdev->wiphy->bands[IEEE80211_BAND_60GHZ]->channels; +	cfg80211_chandef_create(&wdev->preset_chandef, ch, NL80211_CHAN_NO_HT); + +	ndev = alloc_netdev(0, "wlan%d", ether_setup); +	if (!ndev) { +		dev_err(dev, "alloc_netdev_mqs failed\n"); +		rc = -ENOMEM; +		goto out_priv; +	} + +	ndev->netdev_ops = &wil_netdev_ops; +	ndev->ieee80211_ptr = wdev; +	SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); +	wdev->netdev = ndev; + +	wil_link_off(wil); + +	return wil; + + out_priv: +	wil_priv_deinit(wil); + + out_wdev: +	wil_wdev_free(wil); + +	return ERR_PTR(rc); +} + +void wil_if_free(struct wil6210_priv *wil) +{ +	struct net_device *ndev = wil_to_ndev(wil); +	if (!ndev) +		return; + +	free_netdev(ndev); +	wil_priv_deinit(wil); +	wil_wdev_free(wil); +} + +int wil_if_add(struct wil6210_priv *wil) +{ +	struct net_device *ndev = wil_to_ndev(wil); +	int rc; + +	rc = register_netdev(ndev); +	if (rc < 0) { +		dev_err(&ndev->dev, "Failed to register netdev: %d\n", rc); +		return rc; +	} + +	wil_link_off(wil); + +	return 0; +} + +void wil_if_remove(struct wil6210_priv *wil) +{ +	struct net_device *ndev = wil_to_ndev(wil); + +	unregister_netdev(ndev); +}  |