~ubuntu-branches/ubuntu/natty/linux-backports-modules-2.6.38/natty-updates

« back to all changes in this revision

Viewing changes to updates/cw-2.6.39/drivers/net/wireless/iwmc3200wifi/netdev.c

  • Committer: Bazaar Package Importer
  • Author(s): Tim Gardner, Tim Gardner
  • Date: 2011-06-08 10:44:09 UTC
  • Revision ID: james.westby@ubuntu.com-20110608104409-fnl8carkdo15bwsz
Tags: 2.6.38-10.6
[ Tim Gardner ]

Shorten compat-wireless package name to cw to accomodate
CDROM file name length restrictions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Intel Wireless Multicomm 3200 WiFi driver
 
3
 *
 
4
 * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
 
5
 * Samuel Ortiz <samuel.ortiz@intel.com>
 
6
 * Zhu Yi <yi.zhu@intel.com>
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or
 
9
 * modify it under the terms of the GNU General Public License version
 
10
 * 2 as published by the Free Software Foundation.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
20
 * 02110-1301, USA.
 
21
 *
 
22
 */
 
23
 
 
24
/*
 
25
 * This is the netdev related hooks for iwm.
 
26
 *
 
27
 * Some interesting code paths:
 
28
 *
 
29
 * iwm_open() (Called at netdev interface bringup time)
 
30
 *  -> iwm_up() (main.c)
 
31
 *      -> iwm_bus_enable()
 
32
 *          -> if_sdio_enable() (In case of an SDIO bus)
 
33
 *              -> sdio_enable_func()
 
34
 *      -> iwm_notif_wait(BARKER_REBOOT) (wait for reboot barker)
 
35
 *      -> iwm_notif_wait(ACK_BARKER) (wait for ACK barker)
 
36
 *      -> iwm_load_fw() (fw.c)
 
37
 *          -> iwm_load_umac()
 
38
 *          -> iwm_load_lmac() (Calibration LMAC)
 
39
 *          -> iwm_load_lmac() (Operational LMAC)
 
40
 *      -> iwm_send_umac_config()
 
41
 *
 
42
 * iwm_stop() (Called at netdev interface bringdown time)
 
43
 *  -> iwm_down()
 
44
 *      -> iwm_bus_disable()
 
45
 *          -> if_sdio_disable() (In case of an SDIO bus)
 
46
 *              -> sdio_disable_func()
 
47
 */
 
48
#include <linux/netdevice.h>
 
49
#include <linux/slab.h>
 
50
 
 
51
#include "iwm.h"
 
52
#include "commands.h"
 
53
#include "cfg80211.h"
 
54
#include "debug.h"
 
55
 
 
56
static int iwm_open(struct net_device *ndev)
 
57
{
 
58
        struct iwm_priv *iwm = ndev_to_iwm(ndev);
 
59
 
 
60
        return iwm_up(iwm);
 
61
}
 
62
 
 
63
static int iwm_stop(struct net_device *ndev)
 
64
{
 
65
        struct iwm_priv *iwm = ndev_to_iwm(ndev);
 
66
 
 
67
        return iwm_down(iwm);
 
68
}
 
69
 
 
70
/*
 
71
 * iwm AC to queue mapping
 
72
 *
 
73
 * AC_VO -> queue 3
 
74
 * AC_VI -> queue 2
 
75
 * AC_BE -> queue 1
 
76
 * AC_BK -> queue 0
 
77
 */
 
78
static const u16 iwm_1d_to_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
 
79
 
 
80
int iwm_tid_to_queue(u16 tid)
 
81
{
 
82
        if (tid > IWM_UMAC_TID_NR - 2)
 
83
                return -EINVAL;
 
84
 
 
85
        return iwm_1d_to_queue[tid];
 
86
}
 
87
 
 
88
static u16 iwm_select_queue(struct net_device *dev, struct sk_buff *skb)
 
89
{
 
90
        skb->priority = cfg80211_classify8021d(skb);
 
91
 
 
92
        return iwm_1d_to_queue[skb->priority];
 
93
}
 
94
 
 
95
static const struct net_device_ops iwm_netdev_ops = {
 
96
        .ndo_open               = iwm_open,
 
97
        .ndo_stop               = iwm_stop,
 
98
        .ndo_start_xmit         = iwm_xmit_frame,
 
99
        .ndo_select_queue       = iwm_select_queue,
 
100
};
 
101
 
 
102
void *iwm_if_alloc(int sizeof_bus, struct device *dev,
 
103
                   struct iwm_if_ops *if_ops)
 
104
{
 
105
        struct net_device *ndev;
 
106
        struct wireless_dev *wdev;
 
107
        struct iwm_priv *iwm;
 
108
        int ret = 0;
 
109
 
 
110
        wdev = iwm_wdev_alloc(sizeof_bus, dev);
 
111
        if (IS_ERR(wdev))
 
112
                return wdev;
 
113
 
 
114
        iwm = wdev_to_iwm(wdev);
 
115
        iwm->bus_ops = if_ops;
 
116
        iwm->wdev = wdev;
 
117
 
 
118
        ret = iwm_priv_init(iwm);
 
119
        if (ret) {
 
120
                dev_err(dev, "failed to init iwm_priv\n");
 
121
                goto out_wdev;
 
122
        }
 
123
 
 
124
        wdev->iftype = iwm_mode_to_nl80211_iftype(iwm->conf.mode);
 
125
 
 
126
        ndev = alloc_netdev_mq(0, "wlan%d", ether_setup, IWM_TX_QUEUES);
 
127
        if (!ndev) {
 
128
                dev_err(dev, "no memory for network device instance\n");
 
129
                ret = -ENOMEM;
 
130
                goto out_priv;
 
131
        }
 
132
 
 
133
        netdev_attach_ops(ndev, &iwm_netdev_ops);
 
134
        ndev->ieee80211_ptr = wdev;
 
135
        SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
 
136
        wdev->netdev = ndev;
 
137
 
 
138
        iwm->umac_profile = kmalloc(sizeof(struct iwm_umac_profile),
 
139
                                    GFP_KERNEL);
 
140
        if (!iwm->umac_profile) {
 
141
                dev_err(dev, "Couldn't alloc memory for profile\n");
 
142
                ret = -ENOMEM;
 
143
                goto out_profile;
 
144
        }
 
145
 
 
146
        iwm_init_default_profile(iwm, iwm->umac_profile);
 
147
 
 
148
        return iwm;
 
149
 
 
150
 out_profile:
 
151
        free_netdev(ndev);
 
152
 
 
153
 out_priv:
 
154
        iwm_priv_deinit(iwm);
 
155
 
 
156
 out_wdev:
 
157
        iwm_wdev_free(iwm);
 
158
        return ERR_PTR(ret);
 
159
}
 
160
 
 
161
void iwm_if_free(struct iwm_priv *iwm)
 
162
{
 
163
        if (!iwm_to_ndev(iwm))
 
164
                return;
 
165
 
 
166
        cancel_delayed_work_sync(&iwm->ct_kill_delay);
 
167
        free_netdev(iwm_to_ndev(iwm));
 
168
        iwm_priv_deinit(iwm);
 
169
        kfree(iwm->umac_profile);
 
170
        iwm->umac_profile = NULL;
 
171
        iwm_wdev_free(iwm);
 
172
}
 
173
 
 
174
int iwm_if_add(struct iwm_priv *iwm)
 
175
{
 
176
        struct net_device *ndev = iwm_to_ndev(iwm);
 
177
        int ret;
 
178
 
 
179
        ret = register_netdev(ndev);
 
180
        if (ret < 0) {
 
181
                dev_err(&ndev->dev, "Failed to register netdev: %d\n", ret);
 
182
                return ret;
 
183
        }
 
184
 
 
185
        return 0;
 
186
}
 
187
 
 
188
void iwm_if_remove(struct iwm_priv *iwm)
 
189
{
 
190
        unregister_netdev(iwm_to_ndev(iwm));
 
191
}