• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/net/wireless/b43/
1/*
2
3  Broadcom B43 wireless driver
4
5  Copyright (c) 2007 Michael Buesch <mb@bu3sch.de>
6
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
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; see the file COPYING.  If not, write to
19  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
20  Boston, MA 02110-1301, USA.
21
22*/
23
24#include "pcmcia.h"
25
26#include <linux/ssb/ssb.h>
27#include <linux/slab.h>
28
29#include <pcmcia/cs.h>
30#include <pcmcia/cistpl.h>
31#include <pcmcia/ciscode.h>
32#include <pcmcia/ds.h>
33#include <pcmcia/cisreg.h>
34
35
36static /*const */ struct pcmcia_device_id b43_pcmcia_tbl[] = {
37	PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x448),
38	PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x476),
39	PCMCIA_DEVICE_NULL,
40};
41
42MODULE_DEVICE_TABLE(pcmcia, b43_pcmcia_tbl);
43
44#ifdef CONFIG_PM
45static int b43_pcmcia_suspend(struct pcmcia_device *dev)
46{
47	struct ssb_bus *ssb = dev->priv;
48
49	return ssb_bus_suspend(ssb);
50}
51
52static int b43_pcmcia_resume(struct pcmcia_device *dev)
53{
54	struct ssb_bus *ssb = dev->priv;
55
56	return ssb_bus_resume(ssb);
57}
58#else /* CONFIG_PM */
59# define b43_pcmcia_suspend		NULL
60# define b43_pcmcia_resume		NULL
61#endif /* CONFIG_PM */
62
63static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
64{
65	struct ssb_bus *ssb;
66	win_req_t win;
67	int err = -ENOMEM;
68	int res = 0;
69
70	ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
71	if (!ssb)
72		goto out_error;
73
74	err = -ENODEV;
75
76	dev->conf.Attributes = CONF_ENABLE_IRQ;
77	dev->conf.IntType = INT_MEMORY_AND_IO;
78
79	win.Attributes =  WIN_ENABLE | WIN_DATA_WIDTH_16 |
80			 WIN_USE_WAIT;
81	win.Base = 0;
82	win.Size = SSB_CORE_SIZE;
83	win.AccessSpeed = 250;
84	res = pcmcia_request_window(dev, &win, &dev->win);
85	if (res != 0)
86		goto err_kfree_ssb;
87
88	res = pcmcia_map_mem_page(dev, dev->win, 0);
89	if (res != 0)
90		goto err_disable;
91
92	if (!dev->irq)
93		goto err_disable;
94
95	res = pcmcia_request_configuration(dev, &dev->conf);
96	if (res != 0)
97		goto err_disable;
98
99	err = ssb_bus_pcmciabus_register(ssb, dev, win.Base);
100	if (err)
101		goto err_disable;
102	dev->priv = ssb;
103
104	return 0;
105
106err_disable:
107	pcmcia_disable_device(dev);
108err_kfree_ssb:
109	kfree(ssb);
110out_error:
111	printk(KERN_ERR "b43-pcmcia: Initialization failed (%d, %d)\n",
112	       res, err);
113	return err;
114}
115
116static void __devexit b43_pcmcia_remove(struct pcmcia_device *dev)
117{
118	struct ssb_bus *ssb = dev->priv;
119
120	ssb_bus_unregister(ssb);
121	pcmcia_disable_device(dev);
122	kfree(ssb);
123	dev->priv = NULL;
124}
125
126static struct pcmcia_driver b43_pcmcia_driver = {
127	.owner		= THIS_MODULE,
128	.drv		= {
129				.name = "b43-pcmcia",
130			},
131	.id_table	= b43_pcmcia_tbl,
132	.probe		= b43_pcmcia_probe,
133	.remove		= __devexit_p(b43_pcmcia_remove),
134	.suspend	= b43_pcmcia_suspend,
135	.resume		= b43_pcmcia_resume,
136};
137
138int b43_pcmcia_init(void)
139{
140	return pcmcia_register_driver(&b43_pcmcia_driver);
141}
142
143void b43_pcmcia_exit(void)
144{
145	pcmcia_unregister_driver(&b43_pcmcia_driver);
146}
147