1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun
4*4882a593Smuzhiyun Broadcom B43 wireless driver
5*4882a593Smuzhiyun Bus abstraction layer
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun Copyright (c) 2011 Rafał Miłecki <zajec5@gmail.com>
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun */
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #ifdef CONFIG_BCM47XX_BCMA
13*4882a593Smuzhiyun #include <asm/mach-bcm47xx/bcm47xx.h>
14*4882a593Smuzhiyun #endif
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #include "b43.h"
17*4882a593Smuzhiyun #include "bus.h"
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun /* BCMA */
20*4882a593Smuzhiyun #ifdef CONFIG_B43_BCMA
b43_bus_bcma_bus_may_powerdown(struct b43_bus_dev * dev)21*4882a593Smuzhiyun static int b43_bus_bcma_bus_may_powerdown(struct b43_bus_dev *dev)
22*4882a593Smuzhiyun {
23*4882a593Smuzhiyun return 0; /* bcma_bus_may_powerdown(dev->bdev->bus); */
24*4882a593Smuzhiyun }
b43_bus_bcma_bus_powerup(struct b43_bus_dev * dev,bool dynamic_pctl)25*4882a593Smuzhiyun static int b43_bus_bcma_bus_powerup(struct b43_bus_dev *dev,
26*4882a593Smuzhiyun bool dynamic_pctl)
27*4882a593Smuzhiyun {
28*4882a593Smuzhiyun return 0; /* bcma_bus_powerup(dev->sdev->bus, dynamic_pctl); */
29*4882a593Smuzhiyun }
b43_bus_bcma_device_is_enabled(struct b43_bus_dev * dev)30*4882a593Smuzhiyun static int b43_bus_bcma_device_is_enabled(struct b43_bus_dev *dev)
31*4882a593Smuzhiyun {
32*4882a593Smuzhiyun return bcma_core_is_enabled(dev->bdev);
33*4882a593Smuzhiyun }
b43_bus_bcma_device_enable(struct b43_bus_dev * dev,u32 core_specific_flags)34*4882a593Smuzhiyun static void b43_bus_bcma_device_enable(struct b43_bus_dev *dev,
35*4882a593Smuzhiyun u32 core_specific_flags)
36*4882a593Smuzhiyun {
37*4882a593Smuzhiyun bcma_core_enable(dev->bdev, core_specific_flags);
38*4882a593Smuzhiyun }
b43_bus_bcma_device_disable(struct b43_bus_dev * dev,u32 core_specific_flags)39*4882a593Smuzhiyun static void b43_bus_bcma_device_disable(struct b43_bus_dev *dev,
40*4882a593Smuzhiyun u32 core_specific_flags)
41*4882a593Smuzhiyun {
42*4882a593Smuzhiyun bcma_core_disable(dev->bdev, core_specific_flags);
43*4882a593Smuzhiyun }
b43_bus_bcma_read16(struct b43_bus_dev * dev,u16 offset)44*4882a593Smuzhiyun static u16 b43_bus_bcma_read16(struct b43_bus_dev *dev, u16 offset)
45*4882a593Smuzhiyun {
46*4882a593Smuzhiyun return bcma_read16(dev->bdev, offset);
47*4882a593Smuzhiyun }
b43_bus_bcma_read32(struct b43_bus_dev * dev,u16 offset)48*4882a593Smuzhiyun static u32 b43_bus_bcma_read32(struct b43_bus_dev *dev, u16 offset)
49*4882a593Smuzhiyun {
50*4882a593Smuzhiyun return bcma_read32(dev->bdev, offset);
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun static
b43_bus_bcma_write16(struct b43_bus_dev * dev,u16 offset,u16 value)53*4882a593Smuzhiyun void b43_bus_bcma_write16(struct b43_bus_dev *dev, u16 offset, u16 value)
54*4882a593Smuzhiyun {
55*4882a593Smuzhiyun bcma_write16(dev->bdev, offset, value);
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun static
b43_bus_bcma_write32(struct b43_bus_dev * dev,u16 offset,u32 value)58*4882a593Smuzhiyun void b43_bus_bcma_write32(struct b43_bus_dev *dev, u16 offset, u32 value)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun bcma_write32(dev->bdev, offset, value);
61*4882a593Smuzhiyun }
62*4882a593Smuzhiyun static
b43_bus_bcma_block_read(struct b43_bus_dev * dev,void * buffer,size_t count,u16 offset,u8 reg_width)63*4882a593Smuzhiyun void b43_bus_bcma_block_read(struct b43_bus_dev *dev, void *buffer,
64*4882a593Smuzhiyun size_t count, u16 offset, u8 reg_width)
65*4882a593Smuzhiyun {
66*4882a593Smuzhiyun bcma_block_read(dev->bdev, buffer, count, offset, reg_width);
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun static
b43_bus_bcma_block_write(struct b43_bus_dev * dev,const void * buffer,size_t count,u16 offset,u8 reg_width)69*4882a593Smuzhiyun void b43_bus_bcma_block_write(struct b43_bus_dev *dev, const void *buffer,
70*4882a593Smuzhiyun size_t count, u16 offset, u8 reg_width)
71*4882a593Smuzhiyun {
72*4882a593Smuzhiyun bcma_block_write(dev->bdev, buffer, count, offset, reg_width);
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun
b43_bus_dev_bcma_init(struct bcma_device * core)75*4882a593Smuzhiyun struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core)
76*4882a593Smuzhiyun {
77*4882a593Smuzhiyun struct b43_bus_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL);
78*4882a593Smuzhiyun if (!dev)
79*4882a593Smuzhiyun return NULL;
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun dev->bus_type = B43_BUS_BCMA;
82*4882a593Smuzhiyun dev->bdev = core;
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun dev->bus_may_powerdown = b43_bus_bcma_bus_may_powerdown;
85*4882a593Smuzhiyun dev->bus_powerup = b43_bus_bcma_bus_powerup;
86*4882a593Smuzhiyun dev->device_is_enabled = b43_bus_bcma_device_is_enabled;
87*4882a593Smuzhiyun dev->device_enable = b43_bus_bcma_device_enable;
88*4882a593Smuzhiyun dev->device_disable = b43_bus_bcma_device_disable;
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun dev->read16 = b43_bus_bcma_read16;
91*4882a593Smuzhiyun dev->read32 = b43_bus_bcma_read32;
92*4882a593Smuzhiyun dev->write16 = b43_bus_bcma_write16;
93*4882a593Smuzhiyun dev->write32 = b43_bus_bcma_write32;
94*4882a593Smuzhiyun dev->block_read = b43_bus_bcma_block_read;
95*4882a593Smuzhiyun dev->block_write = b43_bus_bcma_block_write;
96*4882a593Smuzhiyun #ifdef CONFIG_BCM47XX_BCMA
97*4882a593Smuzhiyun if (b43_bus_host_is_pci(dev) &&
98*4882a593Smuzhiyun bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA &&
99*4882a593Smuzhiyun bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4716)
100*4882a593Smuzhiyun dev->flush_writes = true;
101*4882a593Smuzhiyun #endif
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun dev->dev = &core->dev;
104*4882a593Smuzhiyun dev->dma_dev = core->dma_dev;
105*4882a593Smuzhiyun dev->irq = core->irq;
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun dev->board_vendor = core->bus->boardinfo.vendor;
108*4882a593Smuzhiyun dev->board_type = core->bus->boardinfo.type;
109*4882a593Smuzhiyun dev->board_rev = core->bus->sprom.board_rev;
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun dev->chip_id = core->bus->chipinfo.id;
112*4882a593Smuzhiyun dev->chip_rev = core->bus->chipinfo.rev;
113*4882a593Smuzhiyun dev->chip_pkg = core->bus->chipinfo.pkg;
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun dev->bus_sprom = &core->bus->sprom;
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun dev->core_id = core->id.id;
118*4882a593Smuzhiyun dev->core_rev = core->id.rev;
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun return dev;
121*4882a593Smuzhiyun }
122*4882a593Smuzhiyun #endif /* CONFIG_B43_BCMA */
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun /* SSB */
125*4882a593Smuzhiyun #ifdef CONFIG_B43_SSB
b43_bus_ssb_bus_may_powerdown(struct b43_bus_dev * dev)126*4882a593Smuzhiyun static int b43_bus_ssb_bus_may_powerdown(struct b43_bus_dev *dev)
127*4882a593Smuzhiyun {
128*4882a593Smuzhiyun return ssb_bus_may_powerdown(dev->sdev->bus);
129*4882a593Smuzhiyun }
b43_bus_ssb_bus_powerup(struct b43_bus_dev * dev,bool dynamic_pctl)130*4882a593Smuzhiyun static int b43_bus_ssb_bus_powerup(struct b43_bus_dev *dev,
131*4882a593Smuzhiyun bool dynamic_pctl)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun return ssb_bus_powerup(dev->sdev->bus, dynamic_pctl);
134*4882a593Smuzhiyun }
b43_bus_ssb_device_is_enabled(struct b43_bus_dev * dev)135*4882a593Smuzhiyun static int b43_bus_ssb_device_is_enabled(struct b43_bus_dev *dev)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun return ssb_device_is_enabled(dev->sdev);
138*4882a593Smuzhiyun }
b43_bus_ssb_device_enable(struct b43_bus_dev * dev,u32 core_specific_flags)139*4882a593Smuzhiyun static void b43_bus_ssb_device_enable(struct b43_bus_dev *dev,
140*4882a593Smuzhiyun u32 core_specific_flags)
141*4882a593Smuzhiyun {
142*4882a593Smuzhiyun ssb_device_enable(dev->sdev, core_specific_flags);
143*4882a593Smuzhiyun }
b43_bus_ssb_device_disable(struct b43_bus_dev * dev,u32 core_specific_flags)144*4882a593Smuzhiyun static void b43_bus_ssb_device_disable(struct b43_bus_dev *dev,
145*4882a593Smuzhiyun u32 core_specific_flags)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun ssb_device_disable(dev->sdev, core_specific_flags);
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun
b43_bus_ssb_read16(struct b43_bus_dev * dev,u16 offset)150*4882a593Smuzhiyun static u16 b43_bus_ssb_read16(struct b43_bus_dev *dev, u16 offset)
151*4882a593Smuzhiyun {
152*4882a593Smuzhiyun return ssb_read16(dev->sdev, offset);
153*4882a593Smuzhiyun }
b43_bus_ssb_read32(struct b43_bus_dev * dev,u16 offset)154*4882a593Smuzhiyun static u32 b43_bus_ssb_read32(struct b43_bus_dev *dev, u16 offset)
155*4882a593Smuzhiyun {
156*4882a593Smuzhiyun return ssb_read32(dev->sdev, offset);
157*4882a593Smuzhiyun }
b43_bus_ssb_write16(struct b43_bus_dev * dev,u16 offset,u16 value)158*4882a593Smuzhiyun static void b43_bus_ssb_write16(struct b43_bus_dev *dev, u16 offset, u16 value)
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun ssb_write16(dev->sdev, offset, value);
161*4882a593Smuzhiyun }
b43_bus_ssb_write32(struct b43_bus_dev * dev,u16 offset,u32 value)162*4882a593Smuzhiyun static void b43_bus_ssb_write32(struct b43_bus_dev *dev, u16 offset, u32 value)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun ssb_write32(dev->sdev, offset, value);
165*4882a593Smuzhiyun }
b43_bus_ssb_block_read(struct b43_bus_dev * dev,void * buffer,size_t count,u16 offset,u8 reg_width)166*4882a593Smuzhiyun static void b43_bus_ssb_block_read(struct b43_bus_dev *dev, void *buffer,
167*4882a593Smuzhiyun size_t count, u16 offset, u8 reg_width)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun ssb_block_read(dev->sdev, buffer, count, offset, reg_width);
170*4882a593Smuzhiyun }
171*4882a593Smuzhiyun static
b43_bus_ssb_block_write(struct b43_bus_dev * dev,const void * buffer,size_t count,u16 offset,u8 reg_width)172*4882a593Smuzhiyun void b43_bus_ssb_block_write(struct b43_bus_dev *dev, const void *buffer,
173*4882a593Smuzhiyun size_t count, u16 offset, u8 reg_width)
174*4882a593Smuzhiyun {
175*4882a593Smuzhiyun ssb_block_write(dev->sdev, buffer, count, offset, reg_width);
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun
b43_bus_dev_ssb_init(struct ssb_device * sdev)178*4882a593Smuzhiyun struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev)
179*4882a593Smuzhiyun {
180*4882a593Smuzhiyun struct b43_bus_dev *dev;
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun dev = kzalloc(sizeof(*dev), GFP_KERNEL);
183*4882a593Smuzhiyun if (!dev)
184*4882a593Smuzhiyun return NULL;
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun dev->bus_type = B43_BUS_SSB;
187*4882a593Smuzhiyun dev->sdev = sdev;
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun dev->bus_may_powerdown = b43_bus_ssb_bus_may_powerdown;
190*4882a593Smuzhiyun dev->bus_powerup = b43_bus_ssb_bus_powerup;
191*4882a593Smuzhiyun dev->device_is_enabled = b43_bus_ssb_device_is_enabled;
192*4882a593Smuzhiyun dev->device_enable = b43_bus_ssb_device_enable;
193*4882a593Smuzhiyun dev->device_disable = b43_bus_ssb_device_disable;
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun dev->read16 = b43_bus_ssb_read16;
196*4882a593Smuzhiyun dev->read32 = b43_bus_ssb_read32;
197*4882a593Smuzhiyun dev->write16 = b43_bus_ssb_write16;
198*4882a593Smuzhiyun dev->write32 = b43_bus_ssb_write32;
199*4882a593Smuzhiyun dev->block_read = b43_bus_ssb_block_read;
200*4882a593Smuzhiyun dev->block_write = b43_bus_ssb_block_write;
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun dev->dev = sdev->dev;
203*4882a593Smuzhiyun dev->dma_dev = sdev->dma_dev;
204*4882a593Smuzhiyun dev->irq = sdev->irq;
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun dev->board_vendor = sdev->bus->boardinfo.vendor;
207*4882a593Smuzhiyun dev->board_type = sdev->bus->boardinfo.type;
208*4882a593Smuzhiyun dev->board_rev = sdev->bus->sprom.board_rev;
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun dev->chip_id = sdev->bus->chip_id;
211*4882a593Smuzhiyun dev->chip_rev = sdev->bus->chip_rev;
212*4882a593Smuzhiyun dev->chip_pkg = sdev->bus->chip_package;
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun dev->bus_sprom = &sdev->bus->sprom;
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun dev->core_id = sdev->id.coreid;
217*4882a593Smuzhiyun dev->core_rev = sdev->id.revision;
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun return dev;
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun #endif /* CONFIG_B43_SSB */
222*4882a593Smuzhiyun
b43_bus_get_wldev(struct b43_bus_dev * dev)223*4882a593Smuzhiyun void *b43_bus_get_wldev(struct b43_bus_dev *dev)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun switch (dev->bus_type) {
226*4882a593Smuzhiyun #ifdef CONFIG_B43_BCMA
227*4882a593Smuzhiyun case B43_BUS_BCMA:
228*4882a593Smuzhiyun return bcma_get_drvdata(dev->bdev);
229*4882a593Smuzhiyun #endif
230*4882a593Smuzhiyun #ifdef CONFIG_B43_SSB
231*4882a593Smuzhiyun case B43_BUS_SSB:
232*4882a593Smuzhiyun return ssb_get_drvdata(dev->sdev);
233*4882a593Smuzhiyun #endif
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun return NULL;
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun
b43_bus_set_wldev(struct b43_bus_dev * dev,void * wldev)238*4882a593Smuzhiyun void b43_bus_set_wldev(struct b43_bus_dev *dev, void *wldev)
239*4882a593Smuzhiyun {
240*4882a593Smuzhiyun switch (dev->bus_type) {
241*4882a593Smuzhiyun #ifdef CONFIG_B43_BCMA
242*4882a593Smuzhiyun case B43_BUS_BCMA:
243*4882a593Smuzhiyun bcma_set_drvdata(dev->bdev, wldev);
244*4882a593Smuzhiyun break;
245*4882a593Smuzhiyun #endif
246*4882a593Smuzhiyun #ifdef CONFIG_B43_SSB
247*4882a593Smuzhiyun case B43_BUS_SSB:
248*4882a593Smuzhiyun ssb_set_drvdata(dev->sdev, wldev);
249*4882a593Smuzhiyun break;
250*4882a593Smuzhiyun #endif
251*4882a593Smuzhiyun }
252*4882a593Smuzhiyun }
253