~ubuntu-branches/ubuntu/maverick/linux-backports-modules-2.6.32/maverick

« back to all changes in this revision

Viewing changes to updates/compat-wireless-2.6/drivers/net/wireless/iwmc3200wifi/netdev.c

  • Committer: Bazaar Package Importer
  • Author(s): Andy Whitcroft, Andy Whitcroft
  • Date: 2010-02-04 23:15:51 UTC
  • Revision ID: james.westby@ubuntu.com-20100204231551-vjz5pkvxclukjxm1
Tags: 2.6.32-12.1
[ Andy Whitcroft ]

* initial LBM for lucid
* drop generated files
* printchanges -- rebase tree does not have stable tags use changelog
* printenv -- add revisions to printenv output
* formally rename compat-wireless to linux-backports-modules-wireless
* Update to compat-wireless-2.6.33-rc5
* update nouveau to mainline 2.6.33-rc4
* add new LBM package for nouveau
* nouveau -- fix major numbers and proc entry names
* fix up firmware installs for -wireless
* clean up UPDATE-NOVEAU
* update Nouveau to v2.6.33-rc6

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
 
 
50
#include "iwm.h"
 
51
#include "commands.h"
 
52
#include "cfg80211.h"
 
53
#include "debug.h"
 
54
 
 
55
static int iwm_open(struct net_device *ndev)
 
56
{
 
57
        struct iwm_priv *iwm = ndev_to_iwm(ndev);
 
58
 
 
59
        return iwm_up(iwm);
 
60
}
 
61
 
 
62
static int iwm_stop(struct net_device *ndev)
 
63
{
 
64
        struct iwm_priv *iwm = ndev_to_iwm(ndev);
 
65
 
 
66
        return iwm_down(iwm);
 
67
}
 
68
 
 
69
/*
 
70
 * iwm AC to queue mapping
 
71
 *
 
72
 * AC_VO -> queue 3
 
73
 * AC_VI -> queue 2
 
74
 * AC_BE -> queue 1
 
75
 * AC_BK -> queue 0
 
76
 */
 
77
static const u16 iwm_1d_to_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
 
78
 
 
79
int iwm_tid_to_queue(u16 tid)
 
80
{
 
81
        if (tid > IWM_UMAC_TID_NR - 2)
 
82
                return -EINVAL;
 
83
 
 
84
        return iwm_1d_to_queue[tid];
 
85
}
 
86
 
 
87
static u16 iwm_select_queue(struct net_device *dev, struct sk_buff *skb)
 
88
{
 
89
        skb->priority = cfg80211_classify8021d(skb);
 
90
 
 
91
        return iwm_1d_to_queue[skb->priority];
 
92
}
 
93
 
 
94
static const struct net_device_ops iwm_netdev_ops = {
 
95
        .ndo_open               = iwm_open,
 
96
        .ndo_stop               = iwm_stop,
 
97
        .ndo_start_xmit         = iwm_xmit_frame,
 
98
        .ndo_select_queue       = iwm_select_queue,
 
99
};
 
100
 
 
101
void *iwm_if_alloc(int sizeof_bus, struct device *dev,
 
102
                   struct iwm_if_ops *if_ops)
 
103
{
 
104
        struct net_device *ndev;
 
105
        struct wireless_dev *wdev;
 
106
        struct iwm_priv *iwm;
 
107
        int ret = 0;
 
108
 
 
109
        wdev = iwm_wdev_alloc(sizeof_bus, dev);
 
110
        if (IS_ERR(wdev))
 
111
                return wdev;
 
112
 
 
113
        iwm = wdev_to_iwm(wdev);
 
114
        iwm->bus_ops = if_ops;
 
115
        iwm->wdev = wdev;
 
116
 
 
117
        ret = iwm_priv_init(iwm);
 
118
        if (ret) {
 
119
                dev_err(dev, "failed to init iwm_priv\n");
 
120
                goto out_wdev;
 
121
        }
 
122
 
 
123
        wdev->iftype = iwm_mode_to_nl80211_iftype(iwm->conf.mode);
 
124
 
 
125
        ndev = alloc_netdev_mq(0, "wlan%d", ether_setup, IWM_TX_QUEUES);
 
126
        if (!ndev) {
 
127
                dev_err(dev, "no memory for network device instance\n");
 
128
                goto out_priv;
 
129
        }
 
130
 
 
131
        ndev->netdev_ops = &iwm_netdev_ops;
 
132
        ndev->ieee80211_ptr = wdev;
 
133
        SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
 
134
        wdev->netdev = ndev;
 
135
 
 
136
        iwm->umac_profile = kmalloc(sizeof(struct iwm_umac_profile),
 
137
                                    GFP_KERNEL);
 
138
        if (!iwm->umac_profile) {
 
139
                dev_err(dev, "Couldn't alloc memory for profile\n");
 
140
                goto out_profile;
 
141
        }
 
142
 
 
143
        iwm_init_default_profile(iwm, iwm->umac_profile);
 
144
 
 
145
        return iwm;
 
146
 
 
147
 out_profile:
 
148
        free_netdev(ndev);
 
149
 
 
150
 out_priv:
 
151
        iwm_priv_deinit(iwm);
 
152
 
 
153
 out_wdev:
 
154
        iwm_wdev_free(iwm);
 
155
        return ERR_PTR(ret);
 
156
}
 
157
 
 
158
void iwm_if_free(struct iwm_priv *iwm)
 
159
{
 
160
        if (!iwm_to_ndev(iwm))
 
161
                return;
 
162
 
 
163
        cancel_delayed_work_sync(&iwm->ct_kill_delay);
 
164
        free_netdev(iwm_to_ndev(iwm));
 
165
        iwm_priv_deinit(iwm);
 
166
        kfree(iwm->umac_profile);
 
167
        iwm->umac_profile = NULL;
 
168
        iwm_wdev_free(iwm);
 
169
}
 
170
 
 
171
int iwm_if_add(struct iwm_priv *iwm)
 
172
{
 
173
        struct net_device *ndev = iwm_to_ndev(iwm);
 
174
        int ret;
 
175
 
 
176
        ret = register_netdev(ndev);
 
177
        if (ret < 0) {
 
178
                dev_err(&ndev->dev, "Failed to register netdev: %d\n", ret);
 
179
                return ret;
 
180
        }
 
181
 
 
182
        return 0;
 
183
}
 
184
 
 
185
void iwm_if_remove(struct iwm_priv *iwm)
 
186
{
 
187
        unregister_netdev(iwm_to_ndev(iwm));
 
188
}