linux/drivers/net/wireless/ath/wil6210/netdev.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2012 Qualcomm Atheros, Inc.
   3 *
   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.
   7 *
   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.
  15 */
  16
  17#include <linux/etherdevice.h>
  18
  19#include "wil6210.h"
  20
  21static int wil_open(struct net_device *ndev)
  22{
  23        struct wil6210_priv *wil = ndev_to_wil(ndev);
  24
  25        return wil_up(wil);
  26}
  27
  28static int wil_stop(struct net_device *ndev)
  29{
  30        struct wil6210_priv *wil = ndev_to_wil(ndev);
  31
  32        return wil_down(wil);
  33}
  34
  35static const struct net_device_ops wil_netdev_ops = {
  36        .ndo_open               = wil_open,
  37        .ndo_stop               = wil_stop,
  38        .ndo_start_xmit         = wil_start_xmit,
  39        .ndo_set_mac_address    = eth_mac_addr,
  40        .ndo_validate_addr      = eth_validate_addr,
  41};
  42
  43void *wil_if_alloc(struct device *dev, void __iomem *csr)
  44{
  45        struct net_device *ndev;
  46        struct wireless_dev *wdev;
  47        struct wil6210_priv *wil;
  48        struct ieee80211_channel *ch;
  49        int rc = 0;
  50
  51        wdev = wil_cfg80211_init(dev);
  52        if (IS_ERR(wdev)) {
  53                dev_err(dev, "wil_cfg80211_init failed\n");
  54                return wdev;
  55        }
  56
  57        wil = wdev_to_wil(wdev);
  58        wil->csr = csr;
  59        wil->wdev = wdev;
  60
  61        rc = wil_priv_init(wil);
  62        if (rc) {
  63                dev_err(dev, "wil_priv_init failed\n");
  64                goto out_wdev;
  65        }
  66
  67        wdev->iftype = NL80211_IFTYPE_STATION; /* TODO */
  68        /* default monitor channel */
  69        ch = wdev->wiphy->bands[IEEE80211_BAND_60GHZ]->channels;
  70        cfg80211_chandef_create(&wdev->preset_chandef, ch, NL80211_CHAN_NO_HT);
  71
  72        ndev = alloc_netdev(0, "wlan%d", ether_setup);
  73        if (!ndev) {
  74                dev_err(dev, "alloc_netdev_mqs failed\n");
  75                rc = -ENOMEM;
  76                goto out_priv;
  77        }
  78
  79        ndev->netdev_ops = &wil_netdev_ops;
  80        ndev->ieee80211_ptr = wdev;
  81        SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
  82        wdev->netdev = ndev;
  83
  84        wil_link_off(wil);
  85
  86        return wil;
  87
  88 out_priv:
  89        wil_priv_deinit(wil);
  90
  91 out_wdev:
  92        wil_wdev_free(wil);
  93
  94        return ERR_PTR(rc);
  95}
  96
  97void wil_if_free(struct wil6210_priv *wil)
  98{
  99        struct net_device *ndev = wil_to_ndev(wil);
 100        if (!ndev)
 101                return;
 102
 103        free_netdev(ndev);
 104        wil_priv_deinit(wil);
 105        wil_wdev_free(wil);
 106}
 107
 108int wil_if_add(struct wil6210_priv *wil)
 109{
 110        struct net_device *ndev = wil_to_ndev(wil);
 111        int rc;
 112
 113        rc = register_netdev(ndev);
 114        if (rc < 0) {
 115                dev_err(&ndev->dev, "Failed to register netdev: %d\n", rc);
 116                return rc;
 117        }
 118
 119        wil_link_off(wil);
 120
 121        return 0;
 122}
 123
 124void wil_if_remove(struct wil6210_priv *wil)
 125{
 126        struct net_device *ndev = wil_to_ndev(wil);
 127
 128        unregister_netdev(ndev);
 129}
 130