xref: /openbmc/linux/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c (revision 5ee9cd065836e5934710ca35653bce7905add20b)
105491d2cSKalle Valo /*
205491d2cSKalle Valo  * Copyright (c) 2010 Broadcom Corporation
305491d2cSKalle Valo  *
405491d2cSKalle Valo  * Permission to use, copy, modify, and/or distribute this software for any
505491d2cSKalle Valo  * purpose with or without fee is hereby granted, provided that the above
605491d2cSKalle Valo  * copyright notice and this permission notice appear in all copies.
705491d2cSKalle Valo  *
805491d2cSKalle Valo  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
905491d2cSKalle Valo  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1005491d2cSKalle Valo  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
1105491d2cSKalle Valo  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1205491d2cSKalle Valo  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
1305491d2cSKalle Valo  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
1405491d2cSKalle Valo  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1505491d2cSKalle Valo  */
1605491d2cSKalle Valo 
1705491d2cSKalle Valo /*
1805491d2cSKalle Valo  * This is "two-way" interface, acting as the SHIM layer between driver
1905491d2cSKalle Valo  * and PHY layer. The driver can optionally call this translation layer
2005491d2cSKalle Valo  * to do some preprocessing, then reach PHY. On the PHY->driver direction,
2105491d2cSKalle Valo  * all calls go through this layer since PHY doesn't have access to the
2205491d2cSKalle Valo  * driver's brcms_hardware pointer.
2305491d2cSKalle Valo  */
2405491d2cSKalle Valo #include <linux/slab.h>
2505491d2cSKalle Valo #include <net/mac80211.h>
2605491d2cSKalle Valo 
2705491d2cSKalle Valo #include "main.h"
2805491d2cSKalle Valo #include "mac80211_if.h"
2905491d2cSKalle Valo #include "phy_shim.h"
3005491d2cSKalle Valo 
3105491d2cSKalle Valo /* PHY SHIM module specific state */
3205491d2cSKalle Valo struct phy_shim_info {
3305491d2cSKalle Valo 	struct brcms_hardware *wlc_hw;	/* pointer to main wlc_hw structure */
3405491d2cSKalle Valo 	struct brcms_c_info *wlc;	/* pointer to main wlc structure */
3505491d2cSKalle Valo 	struct brcms_info *wl; /* pointer to os-specific private state */
3605491d2cSKalle Valo };
3705491d2cSKalle Valo 
wlc_phy_shim_attach(struct brcms_hardware * wlc_hw,struct brcms_info * wl,struct brcms_c_info * wlc)3805491d2cSKalle Valo struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw,
3905491d2cSKalle Valo 					  struct brcms_info *wl,
4005491d2cSKalle Valo 					  struct brcms_c_info *wlc) {
4105491d2cSKalle Valo 	struct phy_shim_info *physhim = NULL;
4205491d2cSKalle Valo 
4305491d2cSKalle Valo 	physhim = kzalloc(sizeof(struct phy_shim_info), GFP_ATOMIC);
4405491d2cSKalle Valo 	if (!physhim)
4505491d2cSKalle Valo 		return NULL;
4605491d2cSKalle Valo 
4705491d2cSKalle Valo 	physhim->wlc_hw = wlc_hw;
4805491d2cSKalle Valo 	physhim->wlc = wlc;
4905491d2cSKalle Valo 	physhim->wl = wl;
5005491d2cSKalle Valo 
5105491d2cSKalle Valo 	return physhim;
5205491d2cSKalle Valo }
5305491d2cSKalle Valo 
wlc_phy_shim_detach(struct phy_shim_info * physhim)5405491d2cSKalle Valo void wlc_phy_shim_detach(struct phy_shim_info *physhim)
5505491d2cSKalle Valo {
5605491d2cSKalle Valo 	kfree(physhim);
5705491d2cSKalle Valo }
5805491d2cSKalle Valo 
wlapi_init_timer(struct phy_shim_info * physhim,void (* fn)(void * pi),void * arg,const char * name)5905491d2cSKalle Valo struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
60*f8e360c7SArnd Bergmann 				     void (*fn)(void *pi),
6105491d2cSKalle Valo 				     void *arg, const char *name)
6205491d2cSKalle Valo {
6305491d2cSKalle Valo 	return (struct wlapi_timer *)
64*f8e360c7SArnd Bergmann 			brcms_init_timer(physhim->wl, fn, arg, name);
6505491d2cSKalle Valo }
6605491d2cSKalle Valo 
wlapi_free_timer(struct wlapi_timer * t)6705491d2cSKalle Valo void wlapi_free_timer(struct wlapi_timer *t)
6805491d2cSKalle Valo {
6905491d2cSKalle Valo 	brcms_free_timer((struct brcms_timer *)t);
7005491d2cSKalle Valo }
7105491d2cSKalle Valo 
7205491d2cSKalle Valo void
wlapi_add_timer(struct wlapi_timer * t,uint ms,int periodic)7305491d2cSKalle Valo wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic)
7405491d2cSKalle Valo {
7505491d2cSKalle Valo 	brcms_add_timer((struct brcms_timer *)t, ms, periodic);
7605491d2cSKalle Valo }
7705491d2cSKalle Valo 
wlapi_del_timer(struct wlapi_timer * t)7805491d2cSKalle Valo bool wlapi_del_timer(struct wlapi_timer *t)
7905491d2cSKalle Valo {
8005491d2cSKalle Valo 	return brcms_del_timer((struct brcms_timer *)t);
8105491d2cSKalle Valo }
8205491d2cSKalle Valo 
wlapi_intrson(struct phy_shim_info * physhim)8305491d2cSKalle Valo void wlapi_intrson(struct phy_shim_info *physhim)
8405491d2cSKalle Valo {
8505491d2cSKalle Valo 	brcms_intrson(physhim->wl);
8605491d2cSKalle Valo }
8705491d2cSKalle Valo 
wlapi_intrsoff(struct phy_shim_info * physhim)8805491d2cSKalle Valo u32 wlapi_intrsoff(struct phy_shim_info *physhim)
8905491d2cSKalle Valo {
9005491d2cSKalle Valo 	return brcms_intrsoff(physhim->wl);
9105491d2cSKalle Valo }
9205491d2cSKalle Valo 
wlapi_intrsrestore(struct phy_shim_info * physhim,u32 macintmask)9305491d2cSKalle Valo void wlapi_intrsrestore(struct phy_shim_info *physhim, u32 macintmask)
9405491d2cSKalle Valo {
9505491d2cSKalle Valo 	brcms_intrsrestore(physhim->wl, macintmask);
9605491d2cSKalle Valo }
9705491d2cSKalle Valo 
wlapi_bmac_write_shm(struct phy_shim_info * physhim,uint offset,u16 v)9805491d2cSKalle Valo void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset, u16 v)
9905491d2cSKalle Valo {
10005491d2cSKalle Valo 	brcms_b_write_shm(physhim->wlc_hw, offset, v);
10105491d2cSKalle Valo }
10205491d2cSKalle Valo 
wlapi_bmac_read_shm(struct phy_shim_info * physhim,uint offset)10305491d2cSKalle Valo u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset)
10405491d2cSKalle Valo {
10505491d2cSKalle Valo 	return brcms_b_read_shm(physhim->wlc_hw, offset);
10605491d2cSKalle Valo }
10705491d2cSKalle Valo 
10805491d2cSKalle Valo void
wlapi_bmac_mhf(struct phy_shim_info * physhim,u8 idx,u16 mask,u16 val,int bands)10905491d2cSKalle Valo wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx, u16 mask,
11005491d2cSKalle Valo 	       u16 val, int bands)
11105491d2cSKalle Valo {
11205491d2cSKalle Valo 	brcms_b_mhf(physhim->wlc_hw, idx, mask, val, bands);
11305491d2cSKalle Valo }
11405491d2cSKalle Valo 
wlapi_bmac_corereset(struct phy_shim_info * physhim,u32 flags)11505491d2cSKalle Valo void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags)
11605491d2cSKalle Valo {
11705491d2cSKalle Valo 	brcms_b_corereset(physhim->wlc_hw, flags);
11805491d2cSKalle Valo }
11905491d2cSKalle Valo 
wlapi_suspend_mac_and_wait(struct phy_shim_info * physhim)12005491d2cSKalle Valo void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim)
12105491d2cSKalle Valo {
12205491d2cSKalle Valo 	brcms_c_suspend_mac_and_wait(physhim->wlc);
12305491d2cSKalle Valo }
12405491d2cSKalle Valo 
wlapi_switch_macfreq(struct phy_shim_info * physhim,u8 spurmode)12505491d2cSKalle Valo void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode)
12605491d2cSKalle Valo {
12705491d2cSKalle Valo 	brcms_b_switch_macfreq(physhim->wlc_hw, spurmode);
12805491d2cSKalle Valo }
12905491d2cSKalle Valo 
wlapi_enable_mac(struct phy_shim_info * physhim)13005491d2cSKalle Valo void wlapi_enable_mac(struct phy_shim_info *physhim)
13105491d2cSKalle Valo {
13205491d2cSKalle Valo 	brcms_c_enable_mac(physhim->wlc);
13305491d2cSKalle Valo }
13405491d2cSKalle Valo 
wlapi_bmac_mctrl(struct phy_shim_info * physhim,u32 mask,u32 val)13505491d2cSKalle Valo void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask, u32 val)
13605491d2cSKalle Valo {
13705491d2cSKalle Valo 	brcms_b_mctrl(physhim->wlc_hw, mask, val);
13805491d2cSKalle Valo }
13905491d2cSKalle Valo 
wlapi_bmac_phy_reset(struct phy_shim_info * physhim)14005491d2cSKalle Valo void wlapi_bmac_phy_reset(struct phy_shim_info *physhim)
14105491d2cSKalle Valo {
14205491d2cSKalle Valo 	brcms_b_phy_reset(physhim->wlc_hw);
14305491d2cSKalle Valo }
14405491d2cSKalle Valo 
wlapi_bmac_bw_set(struct phy_shim_info * physhim,u16 bw)14505491d2cSKalle Valo void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw)
14605491d2cSKalle Valo {
14705491d2cSKalle Valo 	brcms_b_bw_set(physhim->wlc_hw, bw);
14805491d2cSKalle Valo }
14905491d2cSKalle Valo 
wlapi_bmac_get_txant(struct phy_shim_info * physhim)15005491d2cSKalle Valo u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim)
15105491d2cSKalle Valo {
15205491d2cSKalle Valo 	return brcms_b_get_txant(physhim->wlc_hw);
15305491d2cSKalle Valo }
15405491d2cSKalle Valo 
wlapi_bmac_phyclk_fgc(struct phy_shim_info * physhim,bool clk)15505491d2cSKalle Valo void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk)
15605491d2cSKalle Valo {
15705491d2cSKalle Valo 	brcms_b_phyclk_fgc(physhim->wlc_hw, clk);
15805491d2cSKalle Valo }
15905491d2cSKalle Valo 
wlapi_bmac_macphyclk_set(struct phy_shim_info * physhim,bool clk)16005491d2cSKalle Valo void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk)
16105491d2cSKalle Valo {
16205491d2cSKalle Valo 	brcms_b_macphyclk_set(physhim->wlc_hw, clk);
16305491d2cSKalle Valo }
16405491d2cSKalle Valo 
wlapi_bmac_core_phypll_ctl(struct phy_shim_info * physhim,bool on)16505491d2cSKalle Valo void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on)
16605491d2cSKalle Valo {
16705491d2cSKalle Valo 	brcms_b_core_phypll_ctl(physhim->wlc_hw, on);
16805491d2cSKalle Valo }
16905491d2cSKalle Valo 
wlapi_bmac_core_phypll_reset(struct phy_shim_info * physhim)17005491d2cSKalle Valo void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim)
17105491d2cSKalle Valo {
17205491d2cSKalle Valo 	brcms_b_core_phypll_reset(physhim->wlc_hw);
17305491d2cSKalle Valo }
17405491d2cSKalle Valo 
wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info * physhim)17505491d2cSKalle Valo void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *physhim)
17605491d2cSKalle Valo {
17705491d2cSKalle Valo 	brcms_c_ucode_wake_override_set(physhim->wlc_hw,
17805491d2cSKalle Valo 					BRCMS_WAKE_OVERRIDE_PHYREG);
17905491d2cSKalle Valo }
18005491d2cSKalle Valo 
wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info * physhim)18105491d2cSKalle Valo void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *physhim)
18205491d2cSKalle Valo {
18305491d2cSKalle Valo 	brcms_c_ucode_wake_override_clear(physhim->wlc_hw,
18405491d2cSKalle Valo 					  BRCMS_WAKE_OVERRIDE_PHYREG);
18505491d2cSKalle Valo }
18605491d2cSKalle Valo 
18705491d2cSKalle Valo void
wlapi_bmac_write_template_ram(struct phy_shim_info * physhim,int offset,int len,void * buf)18805491d2cSKalle Valo wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int offset,
18905491d2cSKalle Valo 			      int len, void *buf)
19005491d2cSKalle Valo {
19105491d2cSKalle Valo 	brcms_b_write_template_ram(physhim->wlc_hw, offset, len, buf);
19205491d2cSKalle Valo }
19305491d2cSKalle Valo 
wlapi_bmac_rate_shm_offset(struct phy_shim_info * physhim,u8 rate)19405491d2cSKalle Valo u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim, u8 rate)
19505491d2cSKalle Valo {
19605491d2cSKalle Valo 	return brcms_b_rate_shm_offset(physhim->wlc_hw, rate);
19705491d2cSKalle Valo }
19805491d2cSKalle Valo 
wlapi_ucode_sample_init(struct phy_shim_info * physhim)19905491d2cSKalle Valo void wlapi_ucode_sample_init(struct phy_shim_info *physhim)
20005491d2cSKalle Valo {
20105491d2cSKalle Valo }
20205491d2cSKalle Valo 
20305491d2cSKalle Valo void
wlapi_copyfrom_objmem(struct phy_shim_info * physhim,uint offset,void * buf,int len,u32 sel)20405491d2cSKalle Valo wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint offset, void *buf,
20505491d2cSKalle Valo 		      int len, u32 sel)
20605491d2cSKalle Valo {
20705491d2cSKalle Valo 	brcms_b_copyfrom_objmem(physhim->wlc_hw, offset, buf, len, sel);
20805491d2cSKalle Valo }
20905491d2cSKalle Valo 
21005491d2cSKalle Valo void
wlapi_copyto_objmem(struct phy_shim_info * physhim,uint offset,const void * buf,int l,u32 sel)21105491d2cSKalle Valo wlapi_copyto_objmem(struct phy_shim_info *physhim, uint offset, const void *buf,
21205491d2cSKalle Valo 		    int l, u32 sel)
21305491d2cSKalle Valo {
21405491d2cSKalle Valo 	brcms_b_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel);
21505491d2cSKalle Valo }
216