mirror of
https://github.com/joel16/android_kernel_sony_msm8994.git
synced 2024-11-24 04:30:23 +00:00
Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
* 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (1519 commits) staging: et131x: Remove redundant check and return statement staging: et131x: Mainly whitespace changes to appease checkpatch staging: et131x: Remove last of the forward declarations staging: et131x: Remove even more forward declarations staging: et131x: Remove yet more forward declarations staging: et131x: Remove more forward declarations staging: et131x: Remove forward declaration of et131x_adapter_setup staging: et131x: Remove some forward declarations staging: et131x: Remove unused rx_ring.recv_packet_pool staging: et131x: Remove call to find pci pm capability staging: et131x: Remove redundant et131x_reset_recv() call staging: et131x: Remove unused rx_ring.recv_buffer_pool Staging: bcm: Fix three initialization errors in InterfaceDld.c Staging: bcm: Fix coding style issues in InterfaceDld.c staging:iio:dac: Add AD5360 driver staging:iio:trigger:bfin-timer: Fix compile error Staging: vt6655: add some range checks before memcpy() Staging: vt6655: whitespace fixes to iotcl.c Staging: vt6656: add some range checks before memcpy() Staging: vt6656: whitespace cleanups in ioctl.c ... Fix up conflicts in: - drivers/{Kconfig,Makefile}, drivers/staging/{Kconfig,Makefile}: vg driver movement - drivers/staging/brcm80211/brcmfmac/{dhd_linux.c,mac80211_if.c}: driver removal vs now stale changes - drivers/staging/rtl8192e/r8192E_core.c: driver removal vs now stale changes - drivers/staging/et131x/et131*: driver consolidation into one file, tried to do fixups
This commit is contained in:
commit
aa77677e0a
14
MAINTAINERS
14
MAINTAINERS
@ -6171,7 +6171,7 @@ S: Maintained
|
||||
|
||||
STAGING SUBSYSTEM
|
||||
M: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
|
||||
L: devel@driverdev.osuosl.org
|
||||
S: Maintained
|
||||
F: drivers/staging/
|
||||
@ -6212,6 +6212,11 @@ M: David Rowe <david@rowetel.com>
|
||||
S: Odd Fixes
|
||||
F: drivers/staging/echo/
|
||||
|
||||
STAGING - ET131X NETWORK DRIVER
|
||||
M: Mark Einon <mark.einon@gmail.com>
|
||||
S: Odd Fixes
|
||||
F: drivers/staging/et131x/
|
||||
|
||||
STAGING - FLARION FT1000 DRIVERS
|
||||
M: Marek Belisko <marek.belisko@gmail.com>
|
||||
S: Odd Fixes
|
||||
@ -6240,6 +6245,13 @@ W: http://www.lirc.org/
|
||||
S: Odd Fixes
|
||||
F: drivers/staging/lirc/
|
||||
|
||||
STAGING - NVIDIA COMPLIANT EMBEDDED CONTROLLER INTERFACE (nvec)
|
||||
M: Julian Andres Klode <jak@jak-linux.org>
|
||||
M: Marc Dietrich <marvin24@gmx.de>
|
||||
L: ac100@lists.launchpad.net (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: drivers/staging/nvec/
|
||||
|
||||
STAGING - OLPC SECONDARY DISPLAY CONTROLLER (DCON)
|
||||
M: Andres Salomon <dilinger@queued.net>
|
||||
M: Chris Ball <cjb@laptop.org>
|
||||
|
@ -189,5 +189,6 @@
|
||||
#define HV_STATUS_INVALID_HYPERCALL_CODE 2
|
||||
#define HV_STATUS_INVALID_HYPERCALL_INPUT 3
|
||||
#define HV_STATUS_INVALID_ALIGNMENT 4
|
||||
#define HV_STATUS_INSUFFICIENT_BUFFERS 19
|
||||
|
||||
#endif
|
||||
|
@ -132,6 +132,8 @@ source "drivers/iommu/Kconfig"
|
||||
|
||||
source "drivers/virt/Kconfig"
|
||||
|
||||
source "drivers/hv/Kconfig"
|
||||
|
||||
source "drivers/devfreq/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
@ -129,5 +129,6 @@ obj-$(CONFIG_IOMMU_SUPPORT) += iommu/
|
||||
|
||||
# Virtualization drivers
|
||||
obj-$(CONFIG_VIRT_DRIVERS) += virt/
|
||||
obj-$(CONFIG_HYPERV) += hv/
|
||||
|
||||
obj-$(CONFIG_PM_DEVFREQ) += devfreq/
|
||||
|
@ -1,613 +0,0 @@
|
||||
/*
|
||||
* atari_SCC.h: Definitions for the Am8530 Serial Communications Controller
|
||||
*
|
||||
* Copyright 1994 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file COPYING in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _SCC_H
|
||||
#define _SCC_H
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
||||
/* Special configuration ioctls for the Atari SCC5380 Serial
|
||||
* Communications Controller
|
||||
*/
|
||||
|
||||
/* ioctl command codes */
|
||||
|
||||
#define TIOCGATSCC 0x54c0 /* get SCC configuration */
|
||||
#define TIOCSATSCC 0x54c1 /* set SCC configuration */
|
||||
#define TIOCDATSCC 0x54c2 /* reset configuration to defaults */
|
||||
|
||||
/* Clock sources */
|
||||
|
||||
#define CLK_RTxC 0
|
||||
#define CLK_TRxC 1
|
||||
#define CLK_PCLK 2
|
||||
|
||||
/* baud_bases for the common clocks in the Atari. These are the real
|
||||
* frequencies divided by 16.
|
||||
*/
|
||||
|
||||
#define SCC_BAUD_BASE_TIMC 19200 /* 0.3072 MHz from TT-MFP, Timer C */
|
||||
#define SCC_BAUD_BASE_BCLK 153600 /* 2.4576 MHz */
|
||||
#define SCC_BAUD_BASE_PCLK4 229500 /* 3.6720 MHz */
|
||||
#define SCC_BAUD_BASE_PCLK 503374 /* 8.0539763 MHz */
|
||||
#define SCC_BAUD_BASE_NONE 0 /* for not connected or unused
|
||||
* clock sources */
|
||||
|
||||
/* The SCC clock configuration structure */
|
||||
|
||||
struct scc_clock_config {
|
||||
unsigned RTxC_base; /* base_baud of RTxC */
|
||||
unsigned TRxC_base; /* base_baud of TRxC */
|
||||
unsigned PCLK_base; /* base_baud of PCLK, both channels! */
|
||||
struct {
|
||||
unsigned clksrc; /* CLK_RTxC, CLK_TRxC or CLK_PCLK */
|
||||
unsigned divisor; /* divisor for base baud, valid values:
|
||||
* see below */
|
||||
} baud_table[17]; /* For 50, 75, 110, 135, 150, 200, 300,
|
||||
* 600, 1200, 1800, 2400, 4800, 9600,
|
||||
* 19200, 38400, 57600 and 115200 bps.
|
||||
* The last two could be replaced by
|
||||
* other rates > 38400 if they're not
|
||||
* possible.
|
||||
*/
|
||||
};
|
||||
|
||||
/* The following divisors are valid:
|
||||
*
|
||||
* - CLK_RTxC: 1 or even (1, 2 and 4 are the direct modes, > 4 use
|
||||
* the BRG)
|
||||
*
|
||||
* - CLK_TRxC: 1, 2 or 4 (no BRG, only direct modes possible)
|
||||
*
|
||||
* - CLK_PCLK: >= 4 and even (no direct modes, only BRG)
|
||||
*
|
||||
*/
|
||||
|
||||
struct scc_port {
|
||||
struct gs_port gs;
|
||||
volatile unsigned char *ctrlp;
|
||||
volatile unsigned char *datap;
|
||||
int x_char; /* xon/xoff character */
|
||||
int c_dcd;
|
||||
int channel;
|
||||
struct scc_port *port_a; /* Reference to port A and B */
|
||||
struct scc_port *port_b; /* structs for reg access */
|
||||
};
|
||||
|
||||
#define SCC_MAGIC 0x52696368
|
||||
|
||||
/***********************************************************************/
|
||||
/* */
|
||||
/* Register Names */
|
||||
/* */
|
||||
/***********************************************************************/
|
||||
|
||||
/* The SCC documentation gives no explicit names to the registers,
|
||||
* they're just called WR0..15 and RR0..15. To make the source code
|
||||
* better readable and make the transparent write reg read access (see
|
||||
* below) possible, I christen them here with self-invented names.
|
||||
* Note that (real) read registers are assigned numbers 16..31. WR7'
|
||||
* has number 33.
|
||||
*/
|
||||
|
||||
#define COMMAND_REG 0 /* wo */
|
||||
#define INT_AND_DMA_REG 1 /* wo */
|
||||
#define INT_VECTOR_REG 2 /* rw, common to both channels */
|
||||
#define RX_CTRL_REG 3 /* rw */
|
||||
#define AUX1_CTRL_REG 4 /* rw */
|
||||
#define TX_CTRL_REG 5 /* rw */
|
||||
#define SYNC_ADR_REG 6 /* wo */
|
||||
#define SYNC_CHAR_REG 7 /* wo */
|
||||
#define SDLC_OPTION_REG 33 /* wo */
|
||||
#define TX_DATA_REG 8 /* wo */
|
||||
#define MASTER_INT_CTRL 9 /* wo, common to both channels */
|
||||
#define AUX2_CTRL_REG 10 /* rw */
|
||||
#define CLK_CTRL_REG 11 /* wo */
|
||||
#define TIMER_LOW_REG 12 /* rw */
|
||||
#define TIMER_HIGH_REG 13 /* rw */
|
||||
#define DPLL_CTRL_REG 14 /* wo */
|
||||
#define INT_CTRL_REG 15 /* rw */
|
||||
|
||||
#define STATUS_REG 16 /* ro */
|
||||
#define SPCOND_STATUS_REG 17 /* wo */
|
||||
/* RR2 is WR2 for Channel A, Channel B gives vector + current status: */
|
||||
#define CURR_VECTOR_REG 18 /* Ch. B only, Ch. A for rw */
|
||||
#define INT_PENDING_REG 19 /* Channel A only! */
|
||||
/* RR4 is WR4, if b6(MR7') == 1 */
|
||||
/* RR5 is WR5, if b6(MR7') == 1 */
|
||||
#define FS_FIFO_LOW_REG 22 /* ro */
|
||||
#define FS_FIFO_HIGH_REG 23 /* ro */
|
||||
#define RX_DATA_REG 24 /* ro */
|
||||
/* RR9 is WR3, if b6(MR7') == 1 */
|
||||
#define DPLL_STATUS_REG 26 /* ro */
|
||||
/* RR11 is WR10, if b6(MR7') == 1 */
|
||||
/* RR12 is WR12 */
|
||||
/* RR13 is WR13 */
|
||||
/* RR14 not present */
|
||||
/* RR15 is WR15 */
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
/* */
|
||||
/* Register Values */
|
||||
/* */
|
||||
/***********************************************************************/
|
||||
|
||||
|
||||
/* WR0: COMMAND_REG "CR" */
|
||||
|
||||
#define CR_RX_CRC_RESET 0x40
|
||||
#define CR_TX_CRC_RESET 0x80
|
||||
#define CR_TX_UNDERRUN_RESET 0xc0
|
||||
|
||||
#define CR_EXTSTAT_RESET 0x10
|
||||
#define CR_SEND_ABORT 0x18
|
||||
#define CR_ENAB_INT_NEXT_RX 0x20
|
||||
#define CR_TX_PENDING_RESET 0x28
|
||||
#define CR_ERROR_RESET 0x30
|
||||
#define CR_HIGHEST_IUS_RESET 0x38
|
||||
|
||||
|
||||
/* WR1: INT_AND_DMA_REG "IDR" */
|
||||
|
||||
#define IDR_EXTSTAT_INT_ENAB 0x01
|
||||
#define IDR_TX_INT_ENAB 0x02
|
||||
#define IDR_PARERR_AS_SPCOND 0x04
|
||||
|
||||
#define IDR_RX_INT_DISAB 0x00
|
||||
#define IDR_RX_INT_FIRST 0x08
|
||||
#define IDR_RX_INT_ALL 0x10
|
||||
#define IDR_RX_INT_SPCOND 0x18
|
||||
#define IDR_RX_INT_MASK 0x18
|
||||
|
||||
#define IDR_WAITREQ_RX 0x20
|
||||
#define IDR_WAITREQ_IS_REQ 0x40
|
||||
#define IDR_WAITREQ_ENAB 0x80
|
||||
|
||||
|
||||
/* WR3: RX_CTRL_REG "RCR" */
|
||||
|
||||
#define RCR_RX_ENAB 0x01
|
||||
#define RCR_DISCARD_SYNC_CHARS 0x02
|
||||
#define RCR_ADDR_SEARCH 0x04
|
||||
#define RCR_CRC_ENAB 0x08
|
||||
#define RCR_SEARCH_MODE 0x10
|
||||
#define RCR_AUTO_ENAB_MODE 0x20
|
||||
|
||||
#define RCR_CHSIZE_MASK 0xc0
|
||||
#define RCR_CHSIZE_5 0x00
|
||||
#define RCR_CHSIZE_6 0x40
|
||||
#define RCR_CHSIZE_7 0x80
|
||||
#define RCR_CHSIZE_8 0xc0
|
||||
|
||||
|
||||
/* WR4: AUX1_CTRL_REG "A1CR" */
|
||||
|
||||
#define A1CR_PARITY_MASK 0x03
|
||||
#define A1CR_PARITY_NONE 0x00
|
||||
#define A1CR_PARITY_ODD 0x01
|
||||
#define A1CR_PARITY_EVEN 0x03
|
||||
|
||||
#define A1CR_MODE_MASK 0x0c
|
||||
#define A1CR_MODE_SYNCR 0x00
|
||||
#define A1CR_MODE_ASYNC_1 0x04
|
||||
#define A1CR_MODE_ASYNC_15 0x08
|
||||
#define A1CR_MODE_ASYNC_2 0x0c
|
||||
|
||||
#define A1CR_SYNCR_MODE_MASK 0x30
|
||||
#define A1CR_SYNCR_MONOSYNC 0x00
|
||||
#define A1CR_SYNCR_BISYNC 0x10
|
||||
#define A1CR_SYNCR_SDLC 0x20
|
||||
#define A1CR_SYNCR_EXTCSYNC 0x30
|
||||
|
||||
#define A1CR_CLKMODE_MASK 0xc0
|
||||
#define A1CR_CLKMODE_x1 0x00
|
||||
#define A1CR_CLKMODE_x16 0x40
|
||||
#define A1CR_CLKMODE_x32 0x80
|
||||
#define A1CR_CLKMODE_x64 0xc0
|
||||
|
||||
|
||||
/* WR5: TX_CTRL_REG "TCR" */
|
||||
|
||||
#define TCR_TX_CRC_ENAB 0x01
|
||||
#define TCR_RTS 0x02
|
||||
#define TCR_USE_CRC_CCITT 0x00
|
||||
#define TCR_USE_CRC_16 0x04
|
||||
#define TCR_TX_ENAB 0x08
|
||||
#define TCR_SEND_BREAK 0x10
|
||||
|
||||
#define TCR_CHSIZE_MASK 0x60
|
||||
#define TCR_CHSIZE_5 0x00
|
||||
#define TCR_CHSIZE_6 0x20
|
||||
#define TCR_CHSIZE_7 0x40
|
||||
#define TCR_CHSIZE_8 0x60
|
||||
|
||||
#define TCR_DTR 0x80
|
||||
|
||||
|
||||
/* WR7': SLDC_OPTION_REG "SOR" */
|
||||
|
||||
#define SOR_AUTO_TX_ENAB 0x01
|
||||
#define SOR_AUTO_EOM_RESET 0x02
|
||||
#define SOR_AUTO_RTS_MODE 0x04
|
||||
#define SOR_NRZI_DISAB_HIGH 0x08
|
||||
#define SOR_ALT_DTRREQ_TIMING 0x10
|
||||
#define SOR_READ_CRC_CHARS 0x20
|
||||
#define SOR_EXTENDED_REG_ACCESS 0x40
|
||||
|
||||
|
||||
/* WR9: MASTER_INT_CTRL "MIC" */
|
||||
|
||||
#define MIC_VEC_INCL_STAT 0x01
|
||||
#define MIC_NO_VECTOR 0x02
|
||||
#define MIC_DISAB_LOWER_CHAIN 0x04
|
||||
#define MIC_MASTER_INT_ENAB 0x08
|
||||
#define MIC_STATUS_HIGH 0x10
|
||||
#define MIC_IGN_INTACK 0x20
|
||||
|
||||
#define MIC_NO_RESET 0x00
|
||||
#define MIC_CH_A_RESET 0x40
|
||||
#define MIC_CH_B_RESET 0x80
|
||||
#define MIC_HARD_RESET 0xc0
|
||||
|
||||
|
||||
/* WR10: AUX2_CTRL_REG "A2CR" */
|
||||
|
||||
#define A2CR_SYNC_6 0x01
|
||||
#define A2CR_LOOP_MODE 0x02
|
||||
#define A2CR_ABORT_ON_UNDERRUN 0x04
|
||||
#define A2CR_MARK_IDLE 0x08
|
||||
#define A2CR_GO_ACTIVE_ON_POLL 0x10
|
||||
|
||||
#define A2CR_CODING_MASK 0x60
|
||||
#define A2CR_CODING_NRZ 0x00
|
||||
#define A2CR_CODING_NRZI 0x20
|
||||
#define A2CR_CODING_FM1 0x40
|
||||
#define A2CR_CODING_FM0 0x60
|
||||
|
||||
#define A2CR_PRESET_CRC_1 0x80
|
||||
|
||||
|
||||
/* WR11: CLK_CTRL_REG "CCR" */
|
||||
|
||||
#define CCR_TRxCOUT_MASK 0x03
|
||||
#define CCR_TRxCOUT_XTAL 0x00
|
||||
#define CCR_TRxCOUT_TXCLK 0x01
|
||||
#define CCR_TRxCOUT_BRG 0x02
|
||||
#define CCR_TRxCOUT_DPLL 0x03
|
||||
|
||||
#define CCR_TRxC_OUTPUT 0x04
|
||||
|
||||
#define CCR_TXCLK_MASK 0x18
|
||||
#define CCR_TXCLK_RTxC 0x00
|
||||
#define CCR_TXCLK_TRxC 0x08
|
||||
#define CCR_TXCLK_BRG 0x10
|
||||
#define CCR_TXCLK_DPLL 0x18
|
||||
|
||||
#define CCR_RXCLK_MASK 0x60
|
||||
#define CCR_RXCLK_RTxC 0x00
|
||||
#define CCR_RXCLK_TRxC 0x20
|
||||
#define CCR_RXCLK_BRG 0x40
|
||||
#define CCR_RXCLK_DPLL 0x60
|
||||
|
||||
#define CCR_RTxC_XTAL 0x80
|
||||
|
||||
|
||||
/* WR14: DPLL_CTRL_REG "DCR" */
|
||||
|
||||
#define DCR_BRG_ENAB 0x01
|
||||
#define DCR_BRG_USE_PCLK 0x02
|
||||
#define DCR_DTRREQ_IS_REQ 0x04
|
||||
#define DCR_AUTO_ECHO 0x08
|
||||
#define DCR_LOCAL_LOOPBACK 0x10
|
||||
|
||||
#define DCR_DPLL_EDGE_SEARCH 0x20
|
||||
#define DCR_DPLL_ERR_RESET 0x40
|
||||
#define DCR_DPLL_DISAB 0x60
|
||||
#define DCR_DPLL_CLK_BRG 0x80
|
||||
#define DCR_DPLL_CLK_RTxC 0xa0
|
||||
#define DCR_DPLL_FM 0xc0
|
||||
#define DCR_DPLL_NRZI 0xe0
|
||||
|
||||
|
||||
/* WR15: INT_CTRL_REG "ICR" */
|
||||
|
||||
#define ICR_OPTIONREG_SELECT 0x01
|
||||
#define ICR_ENAB_BRG_ZERO_INT 0x02
|
||||
#define ICR_USE_FS_FIFO 0x04
|
||||
#define ICR_ENAB_DCD_INT 0x08
|
||||
#define ICR_ENAB_SYNC_INT 0x10
|
||||
#define ICR_ENAB_CTS_INT 0x20
|
||||
#define ICR_ENAB_UNDERRUN_INT 0x40
|
||||
#define ICR_ENAB_BREAK_INT 0x80
|
||||
|
||||
|
||||
/* RR0: STATUS_REG "SR" */
|
||||
|
||||
#define SR_CHAR_AVAIL 0x01
|
||||
#define SR_BRG_ZERO 0x02
|
||||
#define SR_TX_BUF_EMPTY 0x04
|
||||
#define SR_DCD 0x08
|
||||
#define SR_SYNC_ABORT 0x10
|
||||
#define SR_CTS 0x20
|
||||
#define SR_TX_UNDERRUN 0x40
|
||||
#define SR_BREAK 0x80
|
||||
|
||||
|
||||
/* RR1: SPCOND_STATUS_REG "SCSR" */
|
||||
|
||||
#define SCSR_ALL_SENT 0x01
|
||||
#define SCSR_RESIDUAL_MASK 0x0e
|
||||
#define SCSR_PARITY_ERR 0x10
|
||||
#define SCSR_RX_OVERRUN 0x20
|
||||
#define SCSR_CRC_FRAME_ERR 0x40
|
||||
#define SCSR_END_OF_FRAME 0x80
|
||||
|
||||
|
||||
/* RR3: INT_PENDING_REG "IPR" */
|
||||
|
||||
#define IPR_B_EXTSTAT 0x01
|
||||
#define IPR_B_TX 0x02
|
||||
#define IPR_B_RX 0x04
|
||||
#define IPR_A_EXTSTAT 0x08
|
||||
#define IPR_A_TX 0x10
|
||||
#define IPR_A_RX 0x20
|
||||
|
||||
|
||||
/* RR7: FS_FIFO_HIGH_REG "FFHR" */
|
||||
|
||||
#define FFHR_CNT_MASK 0x3f
|
||||
#define FFHR_IS_FROM_FIFO 0x40
|
||||
#define FFHR_FIFO_OVERRUN 0x80
|
||||
|
||||
|
||||
/* RR10: DPLL_STATUS_REG "DSR" */
|
||||
|
||||
#define DSR_ON_LOOP 0x02
|
||||
#define DSR_ON_LOOP_SENDING 0x10
|
||||
#define DSR_TWO_CLK_MISSING 0x40
|
||||
#define DSR_ONE_CLK_MISSING 0x80
|
||||
|
||||
/***********************************************************************/
|
||||
/* */
|
||||
/* Register Access */
|
||||
/* */
|
||||
/***********************************************************************/
|
||||
|
||||
|
||||
/* The SCC needs 3.5 PCLK cycles recovery time between to register
|
||||
* accesses. PCLK runs with 8 MHz on an Atari, so this delay is 3.5 *
|
||||
* 125 ns = 437.5 ns. This is too short for udelay().
|
||||
* 10/16/95: A tstb st_mfp.par_dt_reg takes 600ns (sure?) and thus should be
|
||||
* quite right
|
||||
*/
|
||||
|
||||
#define scc_reg_delay() \
|
||||
do { \
|
||||
if (MACH_IS_MVME16x || MACH_IS_BVME6000 || MACH_IS_MVME147) \
|
||||
__asm__ __volatile__ ( " nop; nop"); \
|
||||
else if (MACH_IS_ATARI) \
|
||||
__asm__ __volatile__ ( "tstb %0" : : "g" (*_scc_del) : "cc" );\
|
||||
} while (0)
|
||||
|
||||
static unsigned char scc_shadow[2][16];
|
||||
|
||||
/* The following functions should relax the somehow complicated
|
||||
* register access of the SCC. _SCCwrite() stores all written values
|
||||
* (except for WR0 and WR8) in shadow registers for later recall. This
|
||||
* removes the burden of remembering written values as needed. The
|
||||
* extra work of storing the value doesn't count, since a delay is
|
||||
* needed after a SCC access anyway. Additionally, _SCCwrite() manages
|
||||
* writes to WR0 and WR8 differently, because these can be accessed
|
||||
* directly with less overhead. Another special case are WR7 and WR7'.
|
||||
* _SCCwrite automatically checks what of this registers is selected
|
||||
* and changes b0 of WR15 if needed.
|
||||
*
|
||||
* _SCCread() for standard read registers is straightforward, except
|
||||
* for RR2 (split into two "virtual" registers: one for the value
|
||||
* written to WR2 (from the shadow) and one for the vector including
|
||||
* status from RR2, Ch. B) and RR3. The latter must be read from
|
||||
* Channel A, because it reads as all zeros on Ch. B. RR0 and RR8 can
|
||||
* be accessed directly as before.
|
||||
*
|
||||
* The two inline function contain complicated switch statements. But
|
||||
* I rely on regno and final_delay being constants, so gcc can reduce
|
||||
* the whole stuff to just some assembler statements.
|
||||
*
|
||||
* _SCCwrite and _SCCread aren't intended to be used directly under
|
||||
* normal circumstances. The macros SCCread[_ND] and SCCwrite[_ND] are
|
||||
* for that purpose. They assume that a local variable 'port' is
|
||||
* declared and pointing to the port's scc_struct entry. The
|
||||
* variants with "_NB" appended should be used if no other SCC
|
||||
* accesses follow immediately (within 0.5 usecs). They just skip the
|
||||
* final delay nops.
|
||||
*
|
||||
* Please note that accesses to SCC registers should only take place
|
||||
* when interrupts are turned off (at least if SCC interrupts are
|
||||
* enabled). Otherwise, an interrupt could interfere with the
|
||||
* two-stage accessing process.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
static __inline__ void _SCCwrite(
|
||||
struct scc_port *port,
|
||||
unsigned char *shadow,
|
||||
volatile unsigned char *_scc_del,
|
||||
int regno,
|
||||
unsigned char val, int final_delay )
|
||||
{
|
||||
switch( regno ) {
|
||||
|
||||
case COMMAND_REG:
|
||||
/* WR0 can be written directly without pointing */
|
||||
*port->ctrlp = val;
|
||||
break;
|
||||
|
||||
case SYNC_CHAR_REG:
|
||||
/* For WR7, first set b0 of WR15 to 0, if needed */
|
||||
if (shadow[INT_CTRL_REG] & ICR_OPTIONREG_SELECT) {
|
||||
*port->ctrlp = 15;
|
||||
shadow[INT_CTRL_REG] &= ~ICR_OPTIONREG_SELECT;
|
||||
scc_reg_delay();
|
||||
*port->ctrlp = shadow[INT_CTRL_REG];
|
||||
scc_reg_delay();
|
||||
}
|
||||
goto normal_case;
|
||||
|
||||
case SDLC_OPTION_REG:
|
||||
/* For WR7', first set b0 of WR15 to 1, if needed */
|
||||
if (!(shadow[INT_CTRL_REG] & ICR_OPTIONREG_SELECT)) {
|
||||
*port->ctrlp = 15;
|
||||
shadow[INT_CTRL_REG] |= ICR_OPTIONREG_SELECT;
|
||||
scc_reg_delay();
|
||||
*port->ctrlp = shadow[INT_CTRL_REG];
|
||||
scc_reg_delay();
|
||||
}
|
||||
*port->ctrlp = 7;
|
||||
shadow[8] = val; /* WR7' shadowed at WR8 */
|
||||
scc_reg_delay();
|
||||
*port->ctrlp = val;
|
||||
break;
|
||||
|
||||
case TX_DATA_REG: /* WR8 */
|
||||
/* TX_DATA_REG can be accessed directly on some h/w */
|
||||
if (MACH_IS_MVME16x || MACH_IS_BVME6000 || MACH_IS_MVME147)
|
||||
{
|
||||
*port->ctrlp = regno;
|
||||
scc_reg_delay();
|
||||
*port->ctrlp = val;
|
||||
}
|
||||
else
|
||||
*port->datap = val;
|
||||
break;
|
||||
|
||||
case MASTER_INT_CTRL:
|
||||
*port->ctrlp = regno;
|
||||
val &= 0x3f; /* bits 6..7 are the reset commands */
|
||||
scc_shadow[0][regno] = val;
|
||||
scc_reg_delay();
|
||||
*port->ctrlp = val;
|
||||
break;
|
||||
|
||||
case DPLL_CTRL_REG:
|
||||
*port->ctrlp = regno;
|
||||
val &= 0x1f; /* bits 5..7 are the DPLL commands */
|
||||
shadow[regno] = val;
|
||||
scc_reg_delay();
|
||||
*port->ctrlp = val;
|
||||
break;
|
||||
|
||||
case 1 ... 6:
|
||||
case 10 ... 13:
|
||||
case 15:
|
||||
normal_case:
|
||||
*port->ctrlp = regno;
|
||||
shadow[regno] = val;
|
||||
scc_reg_delay();
|
||||
*port->ctrlp = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
printk( "Bad SCC write access to WR%d\n", regno );
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (final_delay)
|
||||
scc_reg_delay();
|
||||
}
|
||||
|
||||
|
||||
static __inline__ unsigned char _SCCread(
|
||||
struct scc_port *port,
|
||||
unsigned char *shadow,
|
||||
volatile unsigned char *_scc_del,
|
||||
int regno, int final_delay )
|
||||
{
|
||||
unsigned char rv;
|
||||
|
||||
switch( regno ) {
|
||||
|
||||
/* --- real read registers --- */
|
||||
case STATUS_REG:
|
||||
rv = *port->ctrlp;
|
||||
break;
|
||||
|
||||
case INT_PENDING_REG:
|
||||
/* RR3: read only from Channel A! */
|
||||
port = port->port_a;
|
||||
goto normal_case;
|
||||
|
||||
case RX_DATA_REG:
|
||||
/* RR8 can be accessed directly on some h/w */
|
||||
if (MACH_IS_MVME16x || MACH_IS_BVME6000 || MACH_IS_MVME147)
|
||||
{
|
||||
*port->ctrlp = 8;
|
||||
scc_reg_delay();
|
||||
rv = *port->ctrlp;
|
||||
}
|
||||
else
|
||||
rv = *port->datap;
|
||||
break;
|
||||
|
||||
case CURR_VECTOR_REG:
|
||||
/* RR2 (vector including status) from Ch. B */
|
||||
port = port->port_b;
|
||||
goto normal_case;
|
||||
|
||||
/* --- reading write registers: access the shadow --- */
|
||||
case 1 ... 7:
|
||||
case 10 ... 15:
|
||||
return shadow[regno]; /* no final delay! */
|
||||
|
||||
/* WR7' is special, because it is shadowed at the place of WR8 */
|
||||
case SDLC_OPTION_REG:
|
||||
return shadow[8]; /* no final delay! */
|
||||
|
||||
/* WR9 is special too, because it is common for both channels */
|
||||
case MASTER_INT_CTRL:
|
||||
return scc_shadow[0][9]; /* no final delay! */
|
||||
|
||||
default:
|
||||
printk( "Bad SCC read access to %cR%d\n", (regno & 16) ? 'R' : 'W',
|
||||
regno & ~16 );
|
||||
break;
|
||||
|
||||
case SPCOND_STATUS_REG:
|
||||
case FS_FIFO_LOW_REG:
|
||||
case FS_FIFO_HIGH_REG:
|
||||
case DPLL_STATUS_REG:
|
||||
normal_case:
|
||||
*port->ctrlp = regno & 0x0f;
|
||||
scc_reg_delay();
|
||||
rv = *port->ctrlp;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (final_delay)
|
||||
scc_reg_delay();
|
||||
return rv;
|
||||
}
|
||||
|
||||
#define SCC_ACCESS_INIT(port) \
|
||||
unsigned char *_scc_shadow = &scc_shadow[port->channel][0]
|
||||
|
||||
#define SCCwrite(reg,val) _SCCwrite(port,_scc_shadow,scc_del,(reg),(val),1)
|
||||
#define SCCwrite_NB(reg,val) _SCCwrite(port,_scc_shadow,scc_del,(reg),(val),0)
|
||||
#define SCCread(reg) _SCCread(port,_scc_shadow,scc_del,(reg),1)
|
||||
#define SCCread_NB(reg) _SCCread(port,_scc_shadow,scc_del,(reg),0)
|
||||
|
||||
#define SCCmod(reg,and,or) SCCwrite((reg),(SCCread(reg)&(and))|(or))
|
||||
|
||||
#endif /* _SCC_H */
|
14
drivers/hv/Kconfig
Normal file
14
drivers/hv/Kconfig
Normal file
@ -0,0 +1,14 @@
|
||||
config HYPERV
|
||||
tristate "Microsoft Hyper-V client drivers"
|
||||
depends on X86 && ACPI && PCI
|
||||
help
|
||||
Select this option to run Linux as a Hyper-V client operating
|
||||
system.
|
||||
|
||||
config HYPERV_UTILS
|
||||
tristate "Microsoft Hyper-V Utilities driver"
|
||||
depends on HYPERV && CONNECTOR && NLS
|
||||
help
|
||||
Select this option to enable the Hyper-V Utilities.
|
||||
|
||||
|
7
drivers/hv/Makefile
Normal file
7
drivers/hv/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
obj-$(CONFIG_HYPERV) += hv_vmbus.o
|
||||
obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o
|
||||
|
||||
hv_vmbus-y := vmbus_drv.o \
|
||||
hv.o connection.o channel.o \
|
||||
channel_mgmt.o ring_buffer.o
|
||||
hv_utils-y := hv_util.o hv_kvp.o
|
@ -26,8 +26,8 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/hyperv.h>
|
||||
|
||||
#include "hyperv.h"
|
||||
#include "hyperv_vmbus.h"
|
||||
|
||||
#define NUM_PAGES_SPANNED(addr, len) \
|
||||
@ -76,15 +76,14 @@ void vmbus_get_debug_info(struct vmbus_channel *channel,
|
||||
struct hv_monitor_page *monitorpage;
|
||||
u8 monitor_group = (u8)channel->offermsg.monitorid / 32;
|
||||
u8 monitor_offset = (u8)channel->offermsg.monitorid % 32;
|
||||
/* u32 monitorBit = 1 << monitorOffset; */
|
||||
|
||||
debuginfo->relid = channel->offermsg.child_relid;
|
||||
debuginfo->state = channel->state;
|
||||
memcpy(&debuginfo->interfacetype,
|
||||
&channel->offermsg.offer.if_type, sizeof(struct hv_guid));
|
||||
&channel->offermsg.offer.if_type, sizeof(uuid_le));
|
||||
memcpy(&debuginfo->interface_instance,
|
||||
&channel->offermsg.offer.if_instance,
|
||||
sizeof(struct hv_guid));
|
||||
sizeof(uuid_le));
|
||||
|
||||
monitorpage = (struct hv_monitor_page *)vmbus_connection.monitor_pages;
|
||||
|
||||
@ -119,8 +118,8 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||
u32 recv_ringbuffer_size, void *userdata, u32 userdatalen,
|
||||
void (*onchannelcallback)(void *context), void *context)
|
||||
{
|
||||
struct vmbus_channel_open_channel *openMsg;
|
||||
struct vmbus_channel_msginfo *openInfo = NULL;
|
||||
struct vmbus_channel_open_channel *open_msg;
|
||||
struct vmbus_channel_msginfo *open_info = NULL;
|
||||
void *in, *out;
|
||||
unsigned long flags;
|
||||
int ret, t, err = 0;
|
||||
@ -173,24 +172,24 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||
}
|
||||
|
||||
/* Create and init the channel open message */
|
||||
openInfo = kmalloc(sizeof(*openInfo) +
|
||||
open_info = kmalloc(sizeof(*open_info) +
|
||||
sizeof(struct vmbus_channel_open_channel),
|
||||
GFP_KERNEL);
|
||||
if (!openInfo) {
|
||||
if (!open_info) {
|
||||
err = -ENOMEM;
|
||||
goto errorout;
|
||||
}
|
||||
|
||||
init_completion(&openInfo->waitevent);
|
||||
init_completion(&open_info->waitevent);
|
||||
|
||||
openMsg = (struct vmbus_channel_open_channel *)openInfo->msg;
|
||||
openMsg->header.msgtype = CHANNELMSG_OPENCHANNEL;
|
||||
openMsg->openid = newchannel->offermsg.child_relid;
|
||||
openMsg->child_relid = newchannel->offermsg.child_relid;
|
||||
openMsg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle;
|
||||
openMsg->downstream_ringbuffer_pageoffset = send_ringbuffer_size >>
|
||||
open_msg = (struct vmbus_channel_open_channel *)open_info->msg;
|
||||
open_msg->header.msgtype = CHANNELMSG_OPENCHANNEL;
|
||||
open_msg->openid = newchannel->offermsg.child_relid;
|
||||
open_msg->child_relid = newchannel->offermsg.child_relid;
|
||||
open_msg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle;
|
||||
open_msg->downstream_ringbuffer_pageoffset = send_ringbuffer_size >>
|
||||
PAGE_SHIFT;
|
||||
openMsg->server_contextarea_gpadlhandle = 0;
|
||||
open_msg->server_contextarea_gpadlhandle = 0;
|
||||
|
||||
if (userdatalen > MAX_USER_DEFINED_BYTES) {
|
||||
err = -EINVAL;
|
||||
@ -198,35 +197,35 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||
}
|
||||
|
||||
if (userdatalen)
|
||||
memcpy(openMsg->userdata, userdata, userdatalen);
|
||||
memcpy(open_msg->userdata, userdata, userdatalen);
|
||||
|
||||
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
|
||||
list_add_tail(&openInfo->msglistentry,
|
||||
list_add_tail(&open_info->msglistentry,
|
||||
&vmbus_connection.chn_msg_list);
|
||||
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||
|
||||
ret = vmbus_post_msg(openMsg,
|
||||
ret = vmbus_post_msg(open_msg,
|
||||
sizeof(struct vmbus_channel_open_channel));
|
||||
|
||||
if (ret != 0)
|
||||
goto cleanup;
|
||||
|
||||
t = wait_for_completion_timeout(&openInfo->waitevent, 5*HZ);
|
||||
t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ);
|
||||
if (t == 0) {
|
||||
err = -ETIMEDOUT;
|
||||
goto errorout;
|
||||
}
|
||||
|
||||
|
||||
if (openInfo->response.open_result.status)
|
||||
err = openInfo->response.open_result.status;
|
||||
if (open_info->response.open_result.status)
|
||||
err = open_info->response.open_result.status;
|
||||
|
||||
cleanup:
|
||||
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
|
||||
list_del(&openInfo->msglistentry);
|
||||
list_del(&open_info->msglistentry);
|
||||
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||
|
||||
kfree(openInfo);
|
||||
kfree(open_info);
|
||||
return err;
|
||||
|
||||
errorout:
|
||||
@ -234,56 +233,11 @@ errorout:
|
||||
hv_ringbuffer_cleanup(&newchannel->inbound);
|
||||
free_pages((unsigned long)out,
|
||||
get_order(send_ringbuffer_size + recv_ringbuffer_size));
|
||||
kfree(openInfo);
|
||||
kfree(open_info);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vmbus_open);
|
||||
|
||||
/*
|
||||
* dump_gpadl_body - Dump the gpadl body message to the console for
|
||||
* debugging purposes.
|
||||
*/
|
||||
static void dump_gpadl_body(struct vmbus_channel_gpadl_body *gpadl, u32 len)
|
||||
{
|
||||
int i;
|
||||
int pfncount;
|
||||
|
||||
pfncount = (len - sizeof(struct vmbus_channel_gpadl_body)) /
|
||||
sizeof(u64);
|
||||
|
||||
DPRINT_DBG(VMBUS, "gpadl body - len %d pfn count %d", len, pfncount);
|
||||
|
||||
for (i = 0; i < pfncount; i++)
|
||||
DPRINT_DBG(VMBUS, "gpadl body - %d) pfn %llu",
|
||||
i, gpadl->pfn[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* dump_gpadl_header - Dump the gpadl header message to the console for
|
||||
* debugging purposes.
|
||||
*/
|
||||
static void dump_gpadl_header(struct vmbus_channel_gpadl_header *gpadl)
|
||||
{
|
||||
int i, j;
|
||||
int pagecount;
|
||||
|
||||
DPRINT_DBG(VMBUS,
|
||||
"gpadl header - relid %d, range count %d, range buflen %d",
|
||||
gpadl->child_relid, gpadl->rangecount, gpadl->range_buflen);
|
||||
for (i = 0; i < gpadl->rangecount; i++) {
|
||||
pagecount = gpadl->range[i].byte_count >> PAGE_SHIFT;
|
||||
pagecount = (pagecount > 26) ? 26 : pagecount;
|
||||
|
||||
DPRINT_DBG(VMBUS, "gpadl range %d - len %d offset %d "
|
||||
"page count %d", i, gpadl->range[i].byte_count,
|
||||
gpadl->range[i].byte_offset, pagecount);
|
||||
|
||||
for (j = 0; j < pagecount; j++)
|
||||
DPRINT_DBG(VMBUS, "%d) pfn %llu", j,
|
||||
gpadl->range[i].pfn_array[j]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* create_gpadl_header - Creates a gpadl for the specified buffer
|
||||
*/
|
||||
@ -437,7 +391,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
|
||||
{
|
||||
struct vmbus_channel_gpadl_header *gpadlmsg;
|
||||
struct vmbus_channel_gpadl_body *gpadl_body;
|
||||
/* struct vmbus_channel_gpadl_created *gpadlCreated; */
|
||||
struct vmbus_channel_msginfo *msginfo = NULL;
|
||||
struct vmbus_channel_msginfo *submsginfo;
|
||||
u32 msgcount;
|
||||
@ -461,7 +414,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
|
||||
gpadlmsg->child_relid = channel->offermsg.child_relid;
|
||||
gpadlmsg->gpadl = next_gpadl_handle;
|
||||
|
||||
dump_gpadl_header(gpadlmsg);
|
||||
|
||||
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
|
||||
list_add_tail(&msginfo->msglistentry,
|
||||
@ -485,8 +437,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
|
||||
CHANNELMSG_GPADL_BODY;
|
||||
gpadl_body->gpadl = next_gpadl_handle;
|
||||
|
||||
dump_gpadl_body(gpadl_body, submsginfo->msgsize -
|
||||
sizeof(*submsginfo));
|
||||
ret = vmbus_post_msg(gpadl_body,
|
||||
submsginfo->msgsize -
|
||||
sizeof(*submsginfo));
|
||||
@ -522,8 +472,6 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
|
||||
unsigned long flags;
|
||||
int ret, t;
|
||||
|
||||
/* ASSERT(gpadl_handle != 0); */
|
||||
|
||||
info = kmalloc(sizeof(*info) +
|
||||
sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL);
|
||||
if (!info)
|
||||
@ -565,9 +513,12 @@ void vmbus_close(struct vmbus_channel *channel)
|
||||
{
|
||||
struct vmbus_channel_close_channel *msg;
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
/* Stop callback and cancel the timer asap */
|
||||
spin_lock_irqsave(&channel->inbound_lock, flags);
|
||||
channel->onchannel_callback = NULL;
|
||||
spin_unlock_irqrestore(&channel->inbound_lock, flags);
|
||||
|
||||
/* Send a closing message */
|
||||
|
||||
@ -787,19 +738,15 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
|
||||
u32 packetlen;
|
||||
u32 userlen;
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
*buffer_actual_len = 0;
|
||||
*requestid = 0;
|
||||
|
||||
spin_lock_irqsave(&channel->inbound_lock, flags);
|
||||
|
||||
ret = hv_ringbuffer_peek(&channel->inbound, &desc,
|
||||
sizeof(struct vmpacket_descriptor));
|
||||
if (ret != 0) {
|
||||
spin_unlock_irqrestore(&channel->inbound_lock, flags);
|
||||
if (ret != 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
packetlen = desc.len8 << 3;
|
||||
userlen = packetlen - (desc.offset8 << 3);
|
||||
@ -807,7 +754,6 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
|
||||
*buffer_actual_len = userlen;
|
||||
|
||||
if (userlen > bufferlen) {
|
||||
spin_unlock_irqrestore(&channel->inbound_lock, flags);
|
||||
|
||||
pr_err("Buffer too small - got %d needs %d\n",
|
||||
bufferlen, userlen);
|
||||
@ -820,7 +766,6 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
|
||||
ret = hv_ringbuffer_read(&channel->inbound, buffer, userlen,
|
||||
(desc.offset8 << 3));
|
||||
|
||||
spin_unlock_irqrestore(&channel->inbound_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -837,19 +782,15 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
|
||||
u32 packetlen;
|
||||
u32 userlen;
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
*buffer_actual_len = 0;
|
||||
*requestid = 0;
|
||||
|
||||
spin_lock_irqsave(&channel->inbound_lock, flags);
|
||||
|
||||
ret = hv_ringbuffer_peek(&channel->inbound, &desc,
|
||||
sizeof(struct vmpacket_descriptor));
|
||||
if (ret != 0) {
|
||||
spin_unlock_irqrestore(&channel->inbound_lock, flags);
|
||||
if (ret != 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
packetlen = desc.len8 << 3;
|
||||
@ -858,12 +799,10 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
|
||||
*buffer_actual_len = packetlen;
|
||||
|
||||
if (packetlen > bufferlen) {
|
||||
spin_unlock_irqrestore(&channel->inbound_lock, flags);
|
||||
|
||||
pr_err("Buffer too small - needed %d bytes but "
|
||||
"got space for only %d bytes\n",
|
||||
packetlen, bufferlen);
|
||||
return -2;
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
*requestid = desc.trans_id;
|
||||
@ -871,7 +810,6 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
|
||||
/* Copy over the entire packet to the user buffer */
|
||||
ret = hv_ringbuffer_read(&channel->inbound, buffer, packetlen, 0);
|
||||
|
||||
spin_unlock_irqrestore(&channel->inbound_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw);
|
@ -28,8 +28,8 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/hyperv.h>
|
||||
|
||||
#include "hyperv.h"
|
||||
#include "hyperv_vmbus.h"
|
||||
|
||||
struct vmbus_channel_message_table_entry {
|
||||
@ -40,12 +40,12 @@ struct vmbus_channel_message_table_entry {
|
||||
#define MAX_MSG_TYPES 4
|
||||
#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 8
|
||||
|
||||
static const struct hv_guid
|
||||
static const uuid_le
|
||||
supported_device_classes[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = {
|
||||
/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */
|
||||
/* Storage - SCSI */
|
||||
{
|
||||
.data = {
|
||||
.b = {
|
||||
0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d,
|
||||
0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f
|
||||
}
|
||||
@ -54,7 +54,7 @@ static const struct hv_guid
|
||||
/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
|
||||
/* Network */
|
||||
{
|
||||
.data = {
|
||||
.b = {
|
||||
0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
|
||||
0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E
|
||||
}
|
||||
@ -63,7 +63,7 @@ static const struct hv_guid
|
||||
/* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */
|
||||
/* Input */
|
||||
{
|
||||
.data = {
|
||||
.b = {
|
||||
0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c,
|
||||
0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A
|
||||
}
|
||||
@ -72,7 +72,7 @@ static const struct hv_guid
|
||||
/* {32412632-86cb-44a2-9b5c-50d1417354f5} */
|
||||
/* IDE */
|
||||
{
|
||||
.data = {
|
||||
.b = {
|
||||
0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
|
||||
0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5
|
||||
}
|
||||
@ -80,7 +80,7 @@ static const struct hv_guid
|
||||
/* 0E0B6031-5213-4934-818B-38D90CED39DB */
|
||||
/* Shutdown */
|
||||
{
|
||||
.data = {
|
||||
.b = {
|
||||
0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
|
||||
0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB
|
||||
}
|
||||
@ -88,7 +88,7 @@ static const struct hv_guid
|
||||
/* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */
|
||||
/* TimeSync */
|
||||
{
|
||||
.data = {
|
||||
.b = {
|
||||
0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
|
||||
0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf
|
||||
}
|
||||
@ -96,7 +96,7 @@ static const struct hv_guid
|
||||
/* {57164f39-9115-4e78-ab55-382f3bd5422d} */
|
||||
/* Heartbeat */
|
||||
{
|
||||
.data = {
|
||||
.b = {
|
||||
0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
|
||||
0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d
|
||||
}
|
||||
@ -104,7 +104,7 @@ static const struct hv_guid
|
||||
/* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */
|
||||
/* KVP */
|
||||
{
|
||||
.data = {
|
||||
.b = {
|
||||
0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
|
||||
0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6
|
||||
}
|
||||
@ -114,7 +114,7 @@ static const struct hv_guid
|
||||
|
||||
|
||||
/**
|
||||
* prep_negotiate_resp() - Create default response for Hyper-V Negotiate message
|
||||
* vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate message
|
||||
* @icmsghdrp: Pointer to msg header structure
|
||||
* @icmsg_negotiate: Pointer to negotiate message structure
|
||||
* @buf: Raw buffer channel data
|
||||
@ -128,9 +128,8 @@ static const struct hv_guid
|
||||
*
|
||||
* Mainly used by Hyper-V drivers.
|
||||
*/
|
||||
void prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
|
||||
struct icmsg_negotiate *negop,
|
||||
u8 *buf)
|
||||
void vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
|
||||
struct icmsg_negotiate *negop, u8 *buf)
|
||||
{
|
||||
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
|
||||
icmsghdrp->icmsgsize = 0x10;
|
||||
@ -156,119 +155,7 @@ void prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
|
||||
negop->icmsg_vercnt = 1;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(prep_negotiate_resp);
|
||||
|
||||
/**
|
||||
* chn_cb_negotiate() - Default handler for non IDE/SCSI/NETWORK
|
||||
* Hyper-V requests
|
||||
* @context: Pointer to argument structure.
|
||||
*
|
||||
* Set up the default handler for non device driver specific requests
|
||||
* from Hyper-V. This stub responds to the default negotiate messages
|
||||
* that come in for every non IDE/SCSI/Network request.
|
||||
* This behavior is normally overwritten in the hv_utils driver. That
|
||||
* driver handles requests like graceful shutdown, heartbeats etc.
|
||||
*
|
||||
* Mainly used by Hyper-V drivers.
|
||||
*/
|
||||
void chn_cb_negotiate(void *context)
|
||||
{
|
||||
struct vmbus_channel *channel = context;
|
||||
u8 *buf;
|
||||
u32 buflen, recvlen;
|
||||
u64 requestid;
|
||||
|
||||
struct icmsg_hdr *icmsghdrp;
|
||||
struct icmsg_negotiate *negop = NULL;
|
||||
|
||||
if (channel->util_index >= 0) {
|
||||
/*
|
||||
* This is a properly initialized util channel.
|
||||
* Route this callback appropriately and setup state
|
||||
* so that we don't need to reroute again.
|
||||
*/
|
||||
if (hv_cb_utils[channel->util_index].callback != NULL) {
|
||||
/*
|
||||
* The util driver has established a handler for
|
||||
* this service; do the magic.
|
||||
*/
|
||||
channel->onchannel_callback =
|
||||
hv_cb_utils[channel->util_index].callback;
|
||||
(hv_cb_utils[channel->util_index].callback)(channel);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
buflen = PAGE_SIZE;
|
||||
buf = kmalloc(buflen, GFP_ATOMIC);
|
||||
|
||||
vmbus_recvpacket(channel, buf, buflen, &recvlen, &requestid);
|
||||
|
||||
if (recvlen > 0) {
|
||||
icmsghdrp = (struct icmsg_hdr *)&buf[
|
||||
sizeof(struct vmbuspipe_hdr)];
|
||||
|
||||
prep_negotiate_resp(icmsghdrp, negop, buf);
|
||||
|
||||
icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
|
||||
| ICMSGHDRFLAG_RESPONSE;
|
||||
|
||||
vmbus_sendpacket(channel, buf,
|
||||
recvlen, requestid,
|
||||
VM_PKT_DATA_INBAND, 0);
|
||||
}
|
||||
|
||||
kfree(buf);
|
||||
}
|
||||
EXPORT_SYMBOL(chn_cb_negotiate);
|
||||
|
||||
/*
|
||||
* Function table used for message responses for non IDE/SCSI/Network type
|
||||
* messages. (Such as KVP/Shutdown etc)
|
||||
*/
|
||||
struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = {
|
||||
/* 0E0B6031-5213-4934-818B-38D90CED39DB */
|
||||
/* Shutdown */
|
||||
{
|
||||
.msg_type = HV_SHUTDOWN_MSG,
|
||||
.data = {
|
||||
0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
|
||||
0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB
|
||||
},
|
||||
.log_msg = "Shutdown channel functionality initialized"
|
||||
},
|
||||
|
||||
/* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */
|
||||
/* TimeSync */
|
||||
{
|
||||
.msg_type = HV_TIMESYNC_MSG,
|
||||
.data = {
|
||||
0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
|
||||
0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf
|
||||
},
|
||||
.log_msg = "Timesync channel functionality initialized"
|
||||
},
|
||||
/* {57164f39-9115-4e78-ab55-382f3bd5422d} */
|
||||
/* Heartbeat */
|
||||
{
|
||||
.msg_type = HV_HEARTBEAT_MSG,
|
||||
.data = {
|
||||
0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
|
||||
0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d
|
||||
},
|
||||
.log_msg = "Heartbeat channel functionality initialized"
|
||||
},
|
||||
/* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */
|
||||
/* KVP */
|
||||
{
|
||||
.data = {
|
||||
0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
|
||||
0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6
|
||||
},
|
||||
.log_msg = "KVP channel functionality initialized"
|
||||
},
|
||||
};
|
||||
EXPORT_SYMBOL(hv_cb_utils);
|
||||
EXPORT_SYMBOL_GPL(vmbus_prep_negotiate_resp);
|
||||
|
||||
/*
|
||||
* alloc_channel - Allocate and initialize a vmbus channel object
|
||||
@ -309,7 +196,7 @@ static void release_channel(struct work_struct *work)
|
||||
/*
|
||||
* free_channel - Release the resources used by the vmbus channel object
|
||||
*/
|
||||
void free_channel(struct vmbus_channel *channel)
|
||||
static void free_channel(struct vmbus_channel *channel)
|
||||
{
|
||||
|
||||
/*
|
||||
@ -333,7 +220,7 @@ static void vmbus_process_rescind_offer(struct work_struct *work)
|
||||
struct vmbus_channel,
|
||||
work);
|
||||
|
||||
vmbus_child_device_unregister(channel->device_obj);
|
||||
vmbus_device_unregister(channel->device_obj);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -348,7 +235,6 @@ static void vmbus_process_offer(struct work_struct *work)
|
||||
struct vmbus_channel *channel;
|
||||
bool fnew = true;
|
||||
int ret;
|
||||
int cnt;
|
||||
unsigned long flags;
|
||||
|
||||
/* The next possible work is rescind handling */
|
||||
@ -358,12 +244,10 @@ static void vmbus_process_offer(struct work_struct *work)
|
||||
spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
|
||||
|
||||
list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
|
||||
if (!memcmp(&channel->offermsg.offer.if_type,
|
||||
&newchannel->offermsg.offer.if_type,
|
||||
sizeof(struct hv_guid)) &&
|
||||
!memcmp(&channel->offermsg.offer.if_instance,
|
||||
&newchannel->offermsg.offer.if_instance,
|
||||
sizeof(struct hv_guid))) {
|
||||
if (!uuid_le_cmp(channel->offermsg.offer.if_type,
|
||||
newchannel->offermsg.offer.if_type) &&
|
||||
!uuid_le_cmp(channel->offermsg.offer.if_instance,
|
||||
newchannel->offermsg.offer.if_instance)) {
|
||||
fnew = false;
|
||||
break;
|
||||
}
|
||||
@ -385,7 +269,7 @@ static void vmbus_process_offer(struct work_struct *work)
|
||||
* We need to set the DeviceObject field before calling
|
||||
* vmbus_child_dev_add()
|
||||
*/
|
||||
newchannel->device_obj = vmbus_child_device_create(
|
||||
newchannel->device_obj = vmbus_device_create(
|
||||
&newchannel->offermsg.offer.if_type,
|
||||
&newchannel->offermsg.offer.if_instance,
|
||||
newchannel);
|
||||
@ -395,7 +279,7 @@ static void vmbus_process_offer(struct work_struct *work)
|
||||
* binding which eventually invokes the device driver's AddDevice()
|
||||
* method.
|
||||
*/
|
||||
ret = vmbus_child_device_register(newchannel->device_obj);
|
||||
ret = vmbus_device_register(newchannel->device_obj);
|
||||
if (ret != 0) {
|
||||
pr_err("unable to add child device object (relid %d)\n",
|
||||
newchannel->offermsg.child_relid);
|
||||
@ -412,48 +296,26 @@ static void vmbus_process_offer(struct work_struct *work)
|
||||
* can cleanup properly
|
||||
*/
|
||||
newchannel->state = CHANNEL_OPEN_STATE;
|
||||
newchannel->util_index = -1; /* Invalid index */
|
||||
|
||||
/* Open IC channels */
|
||||
for (cnt = 0; cnt < MAX_MSG_TYPES; cnt++) {
|
||||
if (memcmp(&newchannel->offermsg.offer.if_type,
|
||||
&hv_cb_utils[cnt].data,
|
||||
sizeof(struct hv_guid)) == 0 &&
|
||||
vmbus_open(newchannel, 2 * PAGE_SIZE,
|
||||
2 * PAGE_SIZE, NULL, 0,
|
||||
chn_cb_negotiate,
|
||||
newchannel) == 0) {
|
||||
hv_cb_utils[cnt].channel = newchannel;
|
||||
newchannel->util_index = cnt;
|
||||
|
||||
pr_info("%s\n", hv_cb_utils[cnt].log_msg);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* vmbus_onoffer - Handler for channel offers from vmbus in parent partition.
|
||||
*
|
||||
* We ignore all offers except network and storage offers. For each network and
|
||||
* storage offers, we create a channel object and queue a work item to the
|
||||
* channel object to process the offer synchronously
|
||||
*/
|
||||
static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
|
||||
{
|
||||
struct vmbus_channel_offer_channel *offer;
|
||||
struct vmbus_channel *newchannel;
|
||||
struct hv_guid *guidtype;
|
||||
struct hv_guid *guidinstance;
|
||||
uuid_le *guidtype;
|
||||
uuid_le *guidinstance;
|
||||
int i;
|
||||
int fsupported = 0;
|
||||
|
||||
offer = (struct vmbus_channel_offer_channel *)hdr;
|
||||
for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) {
|
||||
if (memcmp(&offer->offer.if_type,
|
||||
&supported_device_classes[i],
|
||||
sizeof(struct hv_guid)) == 0) {
|
||||
if (!uuid_le_cmp(offer->offer.if_type,
|
||||
supported_device_classes[i])) {
|
||||
fsupported = 1;
|
||||
break;
|
||||
}
|
@ -25,11 +25,12 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include "hyperv.h"
|
||||
#include <linux/hyperv.h>
|
||||
#include <asm/hyperv.h>
|
||||
#include "hyperv_vmbus.h"
|
||||
|
||||
|
||||
@ -49,10 +50,6 @@ int vmbus_connect(void)
|
||||
struct vmbus_channel_initiate_contact *msg;
|
||||
unsigned long flags;
|
||||
|
||||
/* Make sure we are not connecting or connected */
|
||||
if (vmbus_connection.conn_state != DISCONNECTED)
|
||||
return -EISCONN;
|
||||
|
||||
/* Initialize the vmbus connection */
|
||||
vmbus_connection.conn_state = CONNECTING;
|
||||
vmbus_connection.work_queue = create_workqueue("hv_vmbus_con");
|
||||
@ -214,8 +211,7 @@ struct vmbus_channel *relid2channel(u32 relid)
|
||||
static void process_chn_event(u32 relid)
|
||||
{
|
||||
struct vmbus_channel *channel;
|
||||
|
||||
/* ASSERT(relId > 0); */
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* Find the channel based on this relid and invokes the
|
||||
@ -223,11 +219,27 @@ static void process_chn_event(u32 relid)
|
||||
*/
|
||||
channel = relid2channel(relid);
|
||||
|
||||
if (channel) {
|
||||
channel->onchannel_callback(channel->channel_callback_context);
|
||||
} else {
|
||||
if (!channel) {
|
||||
pr_err("channel not found for relid - %u\n", relid);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* A channel once created is persistent even when there
|
||||
* is no driver handling the device. An unloading driver
|
||||
* sets the onchannel_callback to NULL under the
|
||||
* protection of the channel inbound_lock. Thus, checking
|
||||
* and invoking the driver specific callback takes care of
|
||||
* orderly unloading of the driver.
|
||||
*/
|
||||
|
||||
spin_lock_irqsave(&channel->inbound_lock, flags);
|
||||
if (channel->onchannel_callback != NULL)
|
||||
channel->onchannel_callback(channel->channel_callback_context);
|
||||
else
|
||||
pr_err("no channel callback for relid - %u\n", relid);
|
||||
|
||||
spin_unlock_irqrestore(&channel->inbound_lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -248,16 +260,17 @@ void vmbus_on_event(unsigned long data)
|
||||
if (!recv_int_page[dword])
|
||||
continue;
|
||||
for (bit = 0; bit < 32; bit++) {
|
||||
if (sync_test_and_clear_bit(bit, (unsigned long *)&recv_int_page[dword])) {
|
||||
if (sync_test_and_clear_bit(bit,
|
||||
(unsigned long *)&recv_int_page[dword])) {
|
||||
relid = (dword << 5) + bit;
|
||||
|
||||
if (relid == 0) {
|
||||
if (relid == 0)
|
||||
/*
|
||||
* Special case - vmbus
|
||||
* channel protocol msg
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
process_chn_event(relid);
|
||||
}
|
||||
}
|
||||
@ -270,10 +283,25 @@ void vmbus_on_event(unsigned long data)
|
||||
int vmbus_post_msg(void *buffer, size_t buflen)
|
||||
{
|
||||
union hv_connection_id conn_id;
|
||||
int ret = 0;
|
||||
int retries = 0;
|
||||
|
||||
conn_id.asu32 = 0;
|
||||
conn_id.u.id = VMBUS_MESSAGE_CONNECTION_ID;
|
||||
return hv_post_message(conn_id, 1, buffer, buflen);
|
||||
|
||||
/*
|
||||
* hv_post_message() can have transient failures because of
|
||||
* insufficient resources. Retry the operation a couple of
|
||||
* times before giving up.
|
||||
*/
|
||||
while (retries < 3) {
|
||||
ret = hv_post_message(conn_id, 1, buffer, buflen);
|
||||
if (ret != HV_STATUS_INSUFFICIENT_BUFFERS)
|
||||
return ret;
|
||||
retries++;
|
||||
msleep(100);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
@ -25,8 +25,8 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include "hyperv.h"
|
||||
#include <linux/hyperv.h>
|
||||
#include <asm/hyperv.h>
|
||||
#include "hyperv_vmbus.h"
|
||||
|
||||
/* The one and only */
|
||||
@ -111,7 +111,7 @@ static u64 do_hypercall(u64 control, void *input, void *output)
|
||||
u64 hv_status = 0;
|
||||
u64 input_address = (input) ? virt_to_phys(input) : 0;
|
||||
u64 output_address = (output) ? virt_to_phys(output) : 0;
|
||||
volatile void *hypercall_page = hv_context.hypercall_page;
|
||||
void *hypercall_page = hv_context.hypercall_page;
|
||||
|
||||
__asm__ __volatile__("mov %0, %%r8" : : "r" (output_address) : "r8");
|
||||
__asm__ __volatile__("call *%3" : "=a" (hv_status) :
|
||||
@ -132,7 +132,7 @@ static u64 do_hypercall(u64 control, void *input, void *output)
|
||||
u64 output_address = (output) ? virt_to_phys(output) : 0;
|
||||
u32 output_address_hi = output_address >> 32;
|
||||
u32 output_address_lo = output_address & 0xFFFFFFFF;
|
||||
volatile void *hypercall_page = hv_context.hypercall_page;
|
||||
void *hypercall_page = hv_context.hypercall_page;
|
||||
|
||||
__asm__ __volatile__ ("call *%8" : "=d"(hv_status_hi),
|
||||
"=a"(hv_status_lo) : "d" (control_hi),
|
||||
@ -151,7 +151,6 @@ static u64 do_hypercall(u64 control, void *input, void *output)
|
||||
*/
|
||||
int hv_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
int max_leaf;
|
||||
union hv_x64_msr_hypercall_contents hypercall_msr;
|
||||
void *virtaddr = NULL;
|
||||
@ -164,11 +163,7 @@ int hv_init(void)
|
||||
goto cleanup;
|
||||
|
||||
max_leaf = query_hypervisor_info();
|
||||
/* HvQueryHypervisorFeatures(maxLeaf); */
|
||||
|
||||
/*
|
||||
* We only support running on top of Hyper-V
|
||||
*/
|
||||
rdmsrl(HV_X64_MSR_GUEST_OS_ID, hv_context.guestid);
|
||||
|
||||
if (hv_context.guestid != 0)
|
||||
@ -181,10 +176,6 @@ int hv_init(void)
|
||||
/* See if the hypercall page is already set */
|
||||
rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
|
||||
|
||||
/*
|
||||
* Allocate the hypercall page memory
|
||||
* virtaddr = osd_page_alloc(1);
|
||||
*/
|
||||
virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_EXEC);
|
||||
|
||||
if (!virtaddr)
|
||||
@ -222,7 +213,7 @@ int hv_init(void)
|
||||
hv_context.signal_event_param->flag_number = 0;
|
||||
hv_context.signal_event_param->rsvdz = 0;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
if (virtaddr) {
|
||||
@ -233,8 +224,8 @@ cleanup:
|
||||
|
||||
vfree(virtaddr);
|
||||
}
|
||||
ret = -1;
|
||||
return ret;
|
||||
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -378,7 +369,7 @@ void hv_synic_init(void *irqarg)
|
||||
shared_sint.as_uint64 = 0;
|
||||
shared_sint.vector = irq_vector; /* HV_SHARED_SINT_IDT_VECTOR + 0x20; */
|
||||
shared_sint.masked = false;
|
||||
shared_sint.auto_eoi = true;
|
||||
shared_sint.auto_eoi = false;
|
||||
|
||||
wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
|
||||
|
@ -26,8 +26,8 @@
|
||||
#include <linux/nls.h>
|
||||
#include <linux/connector.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/hyperv.h>
|
||||
|
||||
#include "hyperv.h"
|
||||
#include "hv_kvp.h"
|
||||
|
||||
|
||||
@ -44,21 +44,24 @@
|
||||
static struct {
|
||||
bool active; /* transaction status - active or not */
|
||||
int recv_len; /* number of bytes received. */
|
||||
int index; /* current index */
|
||||
struct vmbus_channel *recv_channel; /* chn we got the request */
|
||||
u64 recv_req_id; /* request ID. */
|
||||
} kvp_transaction;
|
||||
|
||||
static int kvp_send_key(int index);
|
||||
static void kvp_send_key(struct work_struct *dummy);
|
||||
|
||||
#define TIMEOUT_FIRED 1
|
||||
|
||||
static void kvp_respond_to_host(char *key, char *value, int error);
|
||||
static void kvp_work_func(struct work_struct *dummy);
|
||||
static void kvp_register(void);
|
||||
|
||||
static DECLARE_DELAYED_WORK(kvp_work, kvp_work_func);
|
||||
static DECLARE_WORK(kvp_sendkey_work, kvp_send_key);
|
||||
|
||||
static struct cb_id kvp_id = { CN_KVP_IDX, CN_KVP_VAL };
|
||||
static const char kvp_name[] = "kvp_kernel_module";
|
||||
static int timeout_fired;
|
||||
static u8 *recv_buffer;
|
||||
/*
|
||||
* Register the kernel component with the user-level daemon.
|
||||
@ -90,8 +93,7 @@ kvp_work_func(struct work_struct *dummy)
|
||||
* If the timer fires, the user-mode component has not responded;
|
||||
* process the pending transaction.
|
||||
*/
|
||||
kvp_respond_to_host("Unknown key", "Guest timed out", timeout_fired);
|
||||
timeout_fired = 1;
|
||||
kvp_respond_to_host("Unknown key", "Guest timed out", TIMEOUT_FIRED);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -121,10 +123,11 @@ kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
kvp_send_key(int index)
|
||||
static void
|
||||
kvp_send_key(struct work_struct *dummy)
|
||||
{
|
||||
struct cn_msg *msg;
|
||||
int index = kvp_transaction.index;
|
||||
|
||||
msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg) , GFP_ATOMIC);
|
||||
|
||||
@ -136,9 +139,8 @@ kvp_send_key(int index)
|
||||
msg->len = sizeof(struct hv_ku_msg);
|
||||
cn_netlink_send(msg, 0, GFP_ATOMIC);
|
||||
kfree(msg);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -177,6 +179,15 @@ kvp_respond_to_host(char *key, char *value, int error)
|
||||
channel = kvp_transaction.recv_channel;
|
||||
req_id = kvp_transaction.recv_req_id;
|
||||
|
||||
kvp_transaction.active = false;
|
||||
|
||||
if (channel->onchannel_callback == NULL)
|
||||
/*
|
||||
* We have raced with util driver being unloaded;
|
||||
* silently return.
|
||||
*/
|
||||
return;
|
||||
|
||||
icmsghdrp = (struct icmsg_hdr *)
|
||||
&recv_buffer[sizeof(struct vmbuspipe_hdr)];
|
||||
kvp_msg = (struct hv_kvp_msg *)
|
||||
@ -217,7 +228,6 @@ response_done:
|
||||
vmbus_sendpacket(channel, recv_buffer, buf_len, req_id,
|
||||
VM_PKT_DATA_INBAND, 0);
|
||||
|
||||
kvp_transaction.active = false;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -243,10 +253,6 @@ void hv_kvp_onchannelcallback(void *context)
|
||||
struct icmsg_negotiate *negop = NULL;
|
||||
|
||||
|
||||
if (kvp_transaction.active)
|
||||
return;
|
||||
|
||||
|
||||
vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE, &recvlen, &requestid);
|
||||
|
||||
if (recvlen > 0) {
|
||||
@ -254,7 +260,7 @@ void hv_kvp_onchannelcallback(void *context)
|
||||
sizeof(struct vmbuspipe_hdr)];
|
||||
|
||||
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
|
||||
prep_negotiate_resp(icmsghdrp, negop, recv_buffer);
|
||||
vmbus_prep_negotiate_resp(icmsghdrp, negop, recv_buffer);
|
||||
} else {
|
||||
kvp_msg = (struct hv_kvp_msg *)&recv_buffer[
|
||||
sizeof(struct vmbuspipe_hdr) +
|
||||
@ -282,6 +288,7 @@ void hv_kvp_onchannelcallback(void *context)
|
||||
kvp_transaction.recv_channel = channel;
|
||||
kvp_transaction.recv_req_id = requestid;
|
||||
kvp_transaction.active = true;
|
||||
kvp_transaction.index = kvp_data->index;
|
||||
|
||||
/*
|
||||
* Get the information from the
|
||||
@ -292,8 +299,8 @@ void hv_kvp_onchannelcallback(void *context)
|
||||
* Set a timeout to deal with
|
||||
* user-mode not responding.
|
||||
*/
|
||||
kvp_send_key(kvp_data->index);
|
||||
schedule_delayed_work(&kvp_work, 100);
|
||||
schedule_work(&kvp_sendkey_work);
|
||||
schedule_delayed_work(&kvp_work, 5*HZ);
|
||||
|
||||
return;
|
||||
|
||||
@ -312,16 +319,14 @@ callback_done:
|
||||
}
|
||||
|
||||
int
|
||||
hv_kvp_init(void)
|
||||
hv_kvp_init(struct hv_util_service *srv)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = cn_add_callback(&kvp_id, kvp_name, kvp_cn_callback);
|
||||
if (err)
|
||||
return err;
|
||||
recv_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
if (!recv_buffer)
|
||||
return -ENOMEM;
|
||||
recv_buffer = srv->recv_buffer;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -330,5 +335,5 @@ void hv_kvp_deinit(void)
|
||||
{
|
||||
cn_del_callback(&kvp_id);
|
||||
cancel_delayed_work_sync(&kvp_work);
|
||||
kfree(recv_buffer);
|
||||
cancel_work_sync(&kvp_sendkey_work);
|
||||
}
|
@ -175,7 +175,7 @@ struct hv_kvp_msg {
|
||||
struct hv_kvp_msg_enumerate kvp_data;
|
||||
};
|
||||
|
||||
int hv_kvp_init(void);
|
||||
int hv_kvp_init(struct hv_util_service *);
|
||||
void hv_kvp_deinit(void);
|
||||
void hv_kvp_onchannelcallback(void *);
|
||||
|
@ -26,15 +26,31 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/hyperv.h>
|
||||
|
||||
#include "hyperv.h"
|
||||
#include "hv_kvp.h"
|
||||
|
||||
static u8 *shut_txf_buf;
|
||||
static u8 *time_txf_buf;
|
||||
static u8 *hbeat_txf_buf;
|
||||
|
||||
static void shutdown_onchannelcallback(void *context);
|
||||
static struct hv_util_service util_shutdown = {
|
||||
.util_cb = shutdown_onchannelcallback,
|
||||
};
|
||||
|
||||
static void timesync_onchannelcallback(void *context);
|
||||
static struct hv_util_service util_timesynch = {
|
||||
.util_cb = timesync_onchannelcallback,
|
||||
};
|
||||
|
||||
static void heartbeat_onchannelcallback(void *context);
|
||||
static struct hv_util_service util_heartbeat = {
|
||||
.util_cb = heartbeat_onchannelcallback,
|
||||
};
|
||||
|
||||
static struct hv_util_service util_kvp = {
|
||||
.util_cb = hv_kvp_onchannelcallback,
|
||||
.util_init = hv_kvp_init,
|
||||
.util_deinit = hv_kvp_deinit,
|
||||
};
|
||||
|
||||
static void shutdown_onchannelcallback(void *context)
|
||||
{
|
||||
@ -42,6 +58,7 @@ static void shutdown_onchannelcallback(void *context)
|
||||
u32 recvlen;
|
||||
u64 requestid;
|
||||
u8 execute_shutdown = false;
|
||||
u8 *shut_txf_buf = util_shutdown.recv_buffer;
|
||||
|
||||
struct shutdown_msg_data *shutdown_msg;
|
||||
|
||||
@ -56,7 +73,7 @@ static void shutdown_onchannelcallback(void *context)
|
||||
sizeof(struct vmbuspipe_hdr)];
|
||||
|
||||
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
|
||||
prep_negotiate_resp(icmsghdrp, negop, shut_txf_buf);
|
||||
vmbus_prep_negotiate_resp(icmsghdrp, negop, shut_txf_buf);
|
||||
} else {
|
||||
shutdown_msg =
|
||||
(struct shutdown_msg_data *)&shut_txf_buf[
|
||||
@ -91,7 +108,7 @@ static void shutdown_onchannelcallback(void *context)
|
||||
}
|
||||
|
||||
if (execute_shutdown == true)
|
||||
orderly_poweroff(false);
|
||||
orderly_poweroff(true);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -108,6 +125,24 @@ static inline void do_adj_guesttime(u64 hosttime)
|
||||
do_settimeofday(&host_ts);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the host time in a process context.
|
||||
*/
|
||||
|
||||
struct adj_time_work {
|
||||
struct work_struct work;
|
||||
u64 host_time;
|
||||
};
|
||||
|
||||
static void hv_set_host_time(struct work_struct *work)
|
||||
{
|
||||
struct adj_time_work *wrk;
|
||||
|
||||
wrk = container_of(work, struct adj_time_work, work);
|
||||
do_adj_guesttime(wrk->host_time);
|
||||
kfree(wrk);
|
||||
}
|
||||
|
||||
/*
|
||||
* Synchronize time with host after reboot, restore, etc.
|
||||
*
|
||||
@ -121,17 +156,26 @@ static inline void do_adj_guesttime(u64 hosttime)
|
||||
*/
|
||||
static inline void adj_guesttime(u64 hosttime, u8 flags)
|
||||
{
|
||||
struct adj_time_work *wrk;
|
||||
static s32 scnt = 50;
|
||||
|
||||
wrk = kmalloc(sizeof(struct adj_time_work), GFP_ATOMIC);
|
||||
if (wrk == NULL)
|
||||
return;
|
||||
|
||||
wrk->host_time = hosttime;
|
||||
if ((flags & ICTIMESYNCFLAG_SYNC) != 0) {
|
||||
do_adj_guesttime(hosttime);
|
||||
INIT_WORK(&wrk->work, hv_set_host_time);
|
||||
schedule_work(&wrk->work);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((flags & ICTIMESYNCFLAG_SAMPLE) != 0 && scnt > 0) {
|
||||
scnt--;
|
||||
do_adj_guesttime(hosttime);
|
||||
}
|
||||
INIT_WORK(&wrk->work, hv_set_host_time);
|
||||
schedule_work(&wrk->work);
|
||||
} else
|
||||
kfree(wrk);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -144,6 +188,7 @@ static void timesync_onchannelcallback(void *context)
|
||||
u64 requestid;
|
||||
struct icmsg_hdr *icmsghdrp;
|
||||
struct ictimesync_data *timedatap;
|
||||
u8 *time_txf_buf = util_timesynch.recv_buffer;
|
||||
|
||||
vmbus_recvpacket(channel, time_txf_buf,
|
||||
PAGE_SIZE, &recvlen, &requestid);
|
||||
@ -153,7 +198,7 @@ static void timesync_onchannelcallback(void *context)
|
||||
sizeof(struct vmbuspipe_hdr)];
|
||||
|
||||
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
|
||||
prep_negotiate_resp(icmsghdrp, NULL, time_txf_buf);
|
||||
vmbus_prep_negotiate_resp(icmsghdrp, NULL, time_txf_buf);
|
||||
} else {
|
||||
timedatap = (struct ictimesync_data *)&time_txf_buf[
|
||||
sizeof(struct vmbuspipe_hdr) +
|
||||
@ -182,6 +227,7 @@ static void heartbeat_onchannelcallback(void *context)
|
||||
u64 requestid;
|
||||
struct icmsg_hdr *icmsghdrp;
|
||||
struct heartbeat_msg_data *heartbeat_msg;
|
||||
u8 *hbeat_txf_buf = util_heartbeat.recv_buffer;
|
||||
|
||||
vmbus_recvpacket(channel, hbeat_txf_buf,
|
||||
PAGE_SIZE, &recvlen, &requestid);
|
||||
@ -191,7 +237,7 @@ static void heartbeat_onchannelcallback(void *context)
|
||||
sizeof(struct vmbuspipe_hdr)];
|
||||
|
||||
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
|
||||
prep_negotiate_resp(icmsghdrp, NULL, hbeat_txf_buf);
|
||||
vmbus_prep_negotiate_resp(icmsghdrp, NULL, hbeat_txf_buf);
|
||||
} else {
|
||||
heartbeat_msg =
|
||||
(struct heartbeat_msg_data *)&hbeat_txf_buf[
|
||||
@ -210,92 +256,94 @@ static void heartbeat_onchannelcallback(void *context)
|
||||
}
|
||||
}
|
||||
|
||||
static const struct pci_device_id __initconst
|
||||
hv_utils_pci_table[] __maybe_unused = {
|
||||
{ PCI_DEVICE(0x1414, 0x5353) }, /* Hyper-V emulated VGA controller */
|
||||
{ 0 }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, hv_utils_pci_table);
|
||||
static int util_probe(struct hv_device *dev,
|
||||
const struct hv_vmbus_device_id *dev_id)
|
||||
{
|
||||
struct hv_util_service *srv =
|
||||
(struct hv_util_service *)dev_id->driver_data;
|
||||
int ret;
|
||||
|
||||
srv->recv_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
if (!srv->recv_buffer)
|
||||
return -ENOMEM;
|
||||
if (srv->util_init) {
|
||||
ret = srv->util_init(srv);
|
||||
if (ret) {
|
||||
ret = -ENODEV;
|
||||
goto error1;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct dmi_system_id __initconst
|
||||
hv_utils_dmi_table[] __maybe_unused = {
|
||||
{
|
||||
.ident = "Hyper-V",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"),
|
||||
},
|
||||
},
|
||||
ret = vmbus_open(dev->channel, 2 * PAGE_SIZE, 2 * PAGE_SIZE, NULL, 0,
|
||||
srv->util_cb, dev->channel);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
hv_set_drvdata(dev, srv);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (srv->util_deinit)
|
||||
srv->util_deinit();
|
||||
error1:
|
||||
kfree(srv->recv_buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int util_remove(struct hv_device *dev)
|
||||
{
|
||||
struct hv_util_service *srv = hv_get_drvdata(dev);
|
||||
|
||||
vmbus_close(dev->channel);
|
||||
if (srv->util_deinit)
|
||||
srv->util_deinit();
|
||||
kfree(srv->recv_buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct hv_vmbus_device_id id_table[] = {
|
||||
/* Shutdown guid */
|
||||
{ VMBUS_DEVICE(0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
|
||||
0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB)
|
||||
.driver_data = (unsigned long)&util_shutdown },
|
||||
/* Time synch guid */
|
||||
{ VMBUS_DEVICE(0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
|
||||
0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf)
|
||||
.driver_data = (unsigned long)&util_timesynch },
|
||||
/* Heartbeat guid */
|
||||
{ VMBUS_DEVICE(0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
|
||||
0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d)
|
||||
.driver_data = (unsigned long)&util_heartbeat },
|
||||
/* KVP guid */
|
||||
{ VMBUS_DEVICE(0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
|
||||
0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6)
|
||||
.driver_data = (unsigned long)&util_kvp },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(dmi, hv_utils_dmi_table);
|
||||
|
||||
MODULE_DEVICE_TABLE(vmbus, id_table);
|
||||
|
||||
/* The one and only one */
|
||||
static struct hv_driver util_drv = {
|
||||
.name = "hv_util",
|
||||
.id_table = id_table,
|
||||
.probe = util_probe,
|
||||
.remove = util_remove,
|
||||
};
|
||||
|
||||
static int __init init_hyperv_utils(void)
|
||||
{
|
||||
pr_info("Registering HyperV Utility Driver\n");
|
||||
|
||||
if (hv_kvp_init())
|
||||
return -ENODEV;
|
||||
|
||||
|
||||
if (!dmi_check_system(hv_utils_dmi_table))
|
||||
return -ENODEV;
|
||||
|
||||
shut_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
time_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
hbeat_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
|
||||
if (!shut_txf_buf || !time_txf_buf || !hbeat_txf_buf) {
|
||||
pr_info("Unable to allocate memory for receive buffer\n");
|
||||
kfree(shut_txf_buf);
|
||||
kfree(time_txf_buf);
|
||||
kfree(hbeat_txf_buf);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback;
|
||||
|
||||
hv_cb_utils[HV_TIMESYNC_MSG].callback = ×ync_onchannelcallback;
|
||||
|
||||
hv_cb_utils[HV_HEARTBEAT_MSG].callback = &heartbeat_onchannelcallback;
|
||||
|
||||
hv_cb_utils[HV_KVP_MSG].callback = &hv_kvp_onchannelcallback;
|
||||
|
||||
return 0;
|
||||
return vmbus_driver_register(&util_drv);
|
||||
}
|
||||
|
||||
static void exit_hyperv_utils(void)
|
||||
{
|
||||
pr_info("De-Registered HyperV Utility Driver\n");
|
||||
|
||||
if (hv_cb_utils[HV_SHUTDOWN_MSG].channel != NULL)
|
||||
hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback =
|
||||
&chn_cb_negotiate;
|
||||
hv_cb_utils[HV_SHUTDOWN_MSG].callback = NULL;
|
||||
|
||||
if (hv_cb_utils[HV_TIMESYNC_MSG].channel != NULL)
|
||||
hv_cb_utils[HV_TIMESYNC_MSG].channel->onchannel_callback =
|
||||
&chn_cb_negotiate;
|
||||
hv_cb_utils[HV_TIMESYNC_MSG].callback = NULL;
|
||||
|
||||
if (hv_cb_utils[HV_HEARTBEAT_MSG].channel != NULL)
|
||||
hv_cb_utils[HV_HEARTBEAT_MSG].channel->onchannel_callback =
|
||||
&chn_cb_negotiate;
|
||||
hv_cb_utils[HV_HEARTBEAT_MSG].callback = NULL;
|
||||
|
||||
if (hv_cb_utils[HV_KVP_MSG].channel != NULL)
|
||||
hv_cb_utils[HV_KVP_MSG].channel->onchannel_callback =
|
||||
&chn_cb_negotiate;
|
||||
hv_cb_utils[HV_KVP_MSG].callback = NULL;
|
||||
|
||||
hv_kvp_deinit();
|
||||
|
||||
kfree(shut_txf_buf);
|
||||
kfree(time_txf_buf);
|
||||
kfree(hbeat_txf_buf);
|
||||
vmbus_driver_unregister(&util_drv);
|
||||
}
|
||||
|
||||
module_init(init_hyperv_utils);
|
@ -28,8 +28,7 @@
|
||||
#include <linux/list.h>
|
||||
#include <asm/sync_bitops.h>
|
||||
#include <linux/atomic.h>
|
||||
|
||||
#include "hyperv.h"
|
||||
#include <linux/hyperv.h>
|
||||
|
||||
/*
|
||||
* The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
|
||||
@ -451,8 +450,8 @@ enum {
|
||||
/* #define VMBUS_PORT_ID 11 */
|
||||
|
||||
/* 628180B8-308D-4c5e-B7DB-1BEB62E62EF4 */
|
||||
static const struct hv_guid VMBUS_SERVICE_ID = {
|
||||
.data = {
|
||||
static const uuid_le VMBUS_SERVICE_ID = {
|
||||
.b = {
|
||||
0xb8, 0x80, 0x81, 0x62, 0x8d, 0x30, 0x5e, 0x4c,
|
||||
0xb7, 0xdb, 0x1b, 0xeb, 0x62, 0xe6, 0x2e, 0xf4
|
||||
},
|
||||
@ -530,8 +529,6 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *ring_info,
|
||||
|
||||
u32 hv_get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *ring_info);
|
||||
|
||||
void hv_dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix);
|
||||
|
||||
void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
|
||||
struct hv_ring_buffer_debug_info *debug_info);
|
||||
|
||||
@ -601,12 +598,12 @@ extern struct vmbus_connection vmbus_connection;
|
||||
|
||||
/* General vmbus interface */
|
||||
|
||||
struct hv_device *vmbus_child_device_create(struct hv_guid *type,
|
||||
struct hv_guid *instance,
|
||||
struct hv_device *vmbus_device_create(uuid_le *type,
|
||||
uuid_le *instance,
|
||||
struct vmbus_channel *channel);
|
||||
|
||||
int vmbus_child_device_register(struct hv_device *child_device_obj);
|
||||
void vmbus_child_device_unregister(struct hv_device *device_obj);
|
||||
int vmbus_device_register(struct hv_device *child_device_obj);
|
||||
void vmbus_device_unregister(struct hv_device *device_obj);
|
||||
|
||||
/* static void */
|
||||
/* VmbusChildDeviceDestroy( */
|
@ -25,8 +25,8 @@
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/hyperv.h>
|
||||
|
||||
#include "hyperv.h"
|
||||
#include "hyperv_vmbus.h"
|
||||
|
||||
|
||||
@ -34,7 +34,8 @@
|
||||
|
||||
|
||||
/* Amount of space to write to */
|
||||
#define BYTES_AVAIL_TO_WRITE(r, w, z) ((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w))
|
||||
#define BYTES_AVAIL_TO_WRITE(r, w, z) \
|
||||
((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w))
|
||||
|
||||
|
||||
/*
|
||||
@ -171,37 +172,6 @@ hv_get_ring_bufferindices(struct hv_ring_buffer_info *ring_info)
|
||||
return (u64)ring_info->ring_buffer->write_index << 32;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hv_dump_ring_info()
|
||||
*
|
||||
* Dump out to console the ring buffer info
|
||||
*
|
||||
*/
|
||||
void hv_dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix)
|
||||
{
|
||||
u32 bytes_avail_towrite;
|
||||
u32 bytes_avail_toread;
|
||||
|
||||
hv_get_ringbuffer_availbytes(ring_info,
|
||||
&bytes_avail_toread,
|
||||
&bytes_avail_towrite);
|
||||
|
||||
DPRINT(VMBUS,
|
||||
DEBUG_RING_LVL,
|
||||
"%s <<ringinfo %p buffer %p avail write %u "
|
||||
"avail read %u read idx %u write idx %u>>",
|
||||
prefix,
|
||||
ring_info,
|
||||
ring_info->ring_buffer->buffer,
|
||||
bytes_avail_towrite,
|
||||
bytes_avail_toread,
|
||||
ring_info->ring_buffer->read_index,
|
||||
ring_info->ring_buffer->write_index);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hv_copyfrom_ringbuffer()
|
||||
@ -390,7 +360,7 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info,
|
||||
/* is empty since the read index == write index */
|
||||
if (bytes_avail_towrite <= totalbytes_towrite) {
|
||||
spin_unlock_irqrestore(&outring_info->ring_lock, flags);
|
||||
return -1;
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* Write to the ring buffer */
|
||||
@ -450,7 +420,7 @@ int hv_ringbuffer_peek(struct hv_ring_buffer_info *Inring_info,
|
||||
|
||||
spin_unlock_irqrestore(&Inring_info->ring_lock, flags);
|
||||
|
||||
return -1;
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* Convert to byte offset */
|
||||
@ -496,7 +466,7 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer,
|
||||
if (bytes_avail_toread < buflen) {
|
||||
spin_unlock_irqrestore(&inring_info->ring_lock, flags);
|
||||
|
||||
return -1;
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
next_read_location =
|
@ -28,14 +28,12 @@
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <acpi/acpi_bus.h>
|
||||
#include <linux/completion.h>
|
||||
|
||||
#include "hyperv.h"
|
||||
#include <linux/hyperv.h>
|
||||
#include <asm/hyperv.h>
|
||||
#include "hyperv_vmbus.h"
|
||||
|
||||
|
||||
@ -43,15 +41,28 @@ static struct acpi_device *hv_acpi_dev;
|
||||
|
||||
static struct tasklet_struct msg_dpc;
|
||||
static struct tasklet_struct event_dpc;
|
||||
|
||||
unsigned int vmbus_loglevel = (ALL_MODULES << 16 | INFO_LVL);
|
||||
EXPORT_SYMBOL(vmbus_loglevel);
|
||||
/* (ALL_MODULES << 16 | DEBUG_LVL_ENTEREXIT); */
|
||||
/* (((VMBUS | VMBUS_DRV)<<16) | DEBUG_LVL_ENTEREXIT); */
|
||||
|
||||
static struct completion probe_event;
|
||||
static int irq;
|
||||
|
||||
struct hv_device_info {
|
||||
u32 chn_id;
|
||||
u32 chn_state;
|
||||
uuid_le chn_type;
|
||||
uuid_le chn_instance;
|
||||
|
||||
u32 monitor_id;
|
||||
u32 server_monitor_pending;
|
||||
u32 server_monitor_latency;
|
||||
u32 server_monitor_conn_id;
|
||||
u32 client_monitor_pending;
|
||||
u32 client_monitor_latency;
|
||||
u32 client_monitor_conn_id;
|
||||
|
||||
struct hv_dev_port_info inbound;
|
||||
struct hv_dev_port_info outbound;
|
||||
};
|
||||
|
||||
|
||||
static void get_channel_info(struct hv_device *device,
|
||||
struct hv_device_info *info)
|
||||
{
|
||||
@ -65,9 +76,9 @@ static void get_channel_info(struct hv_device *device,
|
||||
info->chn_id = debug_info.relid;
|
||||
info->chn_state = debug_info.state;
|
||||
memcpy(&info->chn_type, &debug_info.interfacetype,
|
||||
sizeof(struct hv_guid));
|
||||
sizeof(uuid_le));
|
||||
memcpy(&info->chn_instance, &debug_info.interface_instance,
|
||||
sizeof(struct hv_guid));
|
||||
sizeof(uuid_le));
|
||||
|
||||
info->monitor_id = debug_info.monitorid;
|
||||
|
||||
@ -97,6 +108,14 @@ static void get_channel_info(struct hv_device *device,
|
||||
debug_info.outbound.bytes_avail_towrite;
|
||||
}
|
||||
|
||||
#define VMBUS_ALIAS_LEN ((sizeof((struct hv_vmbus_device_id *)0)->guid) * 2)
|
||||
static void print_alias_name(struct hv_device *hv_dev, char *alias_name)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < VMBUS_ALIAS_LEN; i += 2)
|
||||
sprintf(&alias_name[i], "%02x", hv_dev->dev_type.b[i/2]);
|
||||
}
|
||||
|
||||
/*
|
||||
* vmbus_show_device_attr - Show the device attribute in sysfs.
|
||||
*
|
||||
@ -108,97 +127,105 @@ static ssize_t vmbus_show_device_attr(struct device *dev,
|
||||
char *buf)
|
||||
{
|
||||
struct hv_device *hv_dev = device_to_hv_device(dev);
|
||||
struct hv_device_info device_info;
|
||||
struct hv_device_info *device_info;
|
||||
char alias_name[VMBUS_ALIAS_LEN + 1];
|
||||
int ret = 0;
|
||||
|
||||
memset(&device_info, 0, sizeof(struct hv_device_info));
|
||||
device_info = kzalloc(sizeof(struct hv_device_info), GFP_KERNEL);
|
||||
if (!device_info)
|
||||
return ret;
|
||||
|
||||
get_channel_info(hv_dev, &device_info);
|
||||
get_channel_info(hv_dev, device_info);
|
||||
|
||||
if (!strcmp(dev_attr->attr.name, "class_id")) {
|
||||
return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
|
||||
ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x}\n",
|
||||
device_info.chn_type.data[3],
|
||||
device_info.chn_type.data[2],
|
||||
device_info.chn_type.data[1],
|
||||
device_info.chn_type.data[0],
|
||||
device_info.chn_type.data[5],
|
||||
device_info.chn_type.data[4],
|
||||
device_info.chn_type.data[7],
|
||||
device_info.chn_type.data[6],
|
||||
device_info.chn_type.data[8],
|
||||
device_info.chn_type.data[9],
|
||||
device_info.chn_type.data[10],
|
||||
device_info.chn_type.data[11],
|
||||
device_info.chn_type.data[12],
|
||||
device_info.chn_type.data[13],
|
||||
device_info.chn_type.data[14],
|
||||
device_info.chn_type.data[15]);
|
||||
device_info->chn_type.b[3],
|
||||
device_info->chn_type.b[2],
|
||||
device_info->chn_type.b[1],
|
||||
device_info->chn_type.b[0],
|
||||
device_info->chn_type.b[5],
|
||||
device_info->chn_type.b[4],
|
||||
device_info->chn_type.b[7],
|
||||
device_info->chn_type.b[6],
|
||||
device_info->chn_type.b[8],
|
||||
device_info->chn_type.b[9],
|
||||
device_info->chn_type.b[10],
|
||||
device_info->chn_type.b[11],
|
||||
device_info->chn_type.b[12],
|
||||
device_info->chn_type.b[13],
|
||||
device_info->chn_type.b[14],
|
||||
device_info->chn_type.b[15]);
|
||||
} else if (!strcmp(dev_attr->attr.name, "device_id")) {
|
||||
return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
|
||||
ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x}\n",
|
||||
device_info.chn_instance.data[3],
|
||||
device_info.chn_instance.data[2],
|
||||
device_info.chn_instance.data[1],
|
||||
device_info.chn_instance.data[0],
|
||||
device_info.chn_instance.data[5],
|
||||
device_info.chn_instance.data[4],
|
||||
device_info.chn_instance.data[7],
|
||||
device_info.chn_instance.data[6],
|
||||
device_info.chn_instance.data[8],
|
||||
device_info.chn_instance.data[9],
|
||||
device_info.chn_instance.data[10],
|
||||
device_info.chn_instance.data[11],
|
||||
device_info.chn_instance.data[12],
|
||||
device_info.chn_instance.data[13],
|
||||
device_info.chn_instance.data[14],
|
||||
device_info.chn_instance.data[15]);
|
||||
device_info->chn_instance.b[3],
|
||||
device_info->chn_instance.b[2],
|
||||
device_info->chn_instance.b[1],
|
||||
device_info->chn_instance.b[0],
|
||||
device_info->chn_instance.b[5],
|
||||
device_info->chn_instance.b[4],
|
||||
device_info->chn_instance.b[7],
|
||||
device_info->chn_instance.b[6],
|
||||
device_info->chn_instance.b[8],
|
||||
device_info->chn_instance.b[9],
|
||||
device_info->chn_instance.b[10],
|
||||
device_info->chn_instance.b[11],
|
||||
device_info->chn_instance.b[12],
|
||||
device_info->chn_instance.b[13],
|
||||
device_info->chn_instance.b[14],
|
||||
device_info->chn_instance.b[15]);
|
||||
} else if (!strcmp(dev_attr->attr.name, "modalias")) {
|
||||
print_alias_name(hv_dev, alias_name);
|
||||
ret = sprintf(buf, "vmbus:%s\n", alias_name);
|
||||
} else if (!strcmp(dev_attr->attr.name, "state")) {
|
||||
return sprintf(buf, "%d\n", device_info.chn_state);
|
||||
ret = sprintf(buf, "%d\n", device_info->chn_state);
|
||||
} else if (!strcmp(dev_attr->attr.name, "id")) {
|
||||
return sprintf(buf, "%d\n", device_info.chn_id);
|
||||
ret = sprintf(buf, "%d\n", device_info->chn_id);
|
||||
} else if (!strcmp(dev_attr->attr.name, "out_intr_mask")) {
|
||||
return sprintf(buf, "%d\n", device_info.outbound.int_mask);
|
||||
ret = sprintf(buf, "%d\n", device_info->outbound.int_mask);
|
||||
} else if (!strcmp(dev_attr->attr.name, "out_read_index")) {
|
||||
return sprintf(buf, "%d\n", device_info.outbound.read_idx);
|
||||
ret = sprintf(buf, "%d\n", device_info->outbound.read_idx);
|
||||
} else if (!strcmp(dev_attr->attr.name, "out_write_index")) {
|
||||
return sprintf(buf, "%d\n", device_info.outbound.write_idx);
|
||||
ret = sprintf(buf, "%d\n", device_info->outbound.write_idx);
|
||||
} else if (!strcmp(dev_attr->attr.name, "out_read_bytes_avail")) {
|
||||
return sprintf(buf, "%d\n",
|
||||
device_info.outbound.bytes_avail_toread);
|
||||
ret = sprintf(buf, "%d\n",
|
||||
device_info->outbound.bytes_avail_toread);
|
||||
} else if (!strcmp(dev_attr->attr.name, "out_write_bytes_avail")) {
|
||||
return sprintf(buf, "%d\n",
|
||||
device_info.outbound.bytes_avail_towrite);
|
||||
ret = sprintf(buf, "%d\n",
|
||||
device_info->outbound.bytes_avail_towrite);
|
||||
} else if (!strcmp(dev_attr->attr.name, "in_intr_mask")) {
|
||||
return sprintf(buf, "%d\n", device_info.inbound.int_mask);
|
||||
ret = sprintf(buf, "%d\n", device_info->inbound.int_mask);
|
||||
} else if (!strcmp(dev_attr->attr.name, "in_read_index")) {
|
||||
return sprintf(buf, "%d\n", device_info.inbound.read_idx);
|
||||
ret = sprintf(buf, "%d\n", device_info->inbound.read_idx);
|
||||
} else if (!strcmp(dev_attr->attr.name, "in_write_index")) {
|
||||
return sprintf(buf, "%d\n", device_info.inbound.write_idx);
|
||||
ret = sprintf(buf, "%d\n", device_info->inbound.write_idx);
|
||||
} else if (!strcmp(dev_attr->attr.name, "in_read_bytes_avail")) {
|
||||
return sprintf(buf, "%d\n",
|
||||
device_info.inbound.bytes_avail_toread);
|
||||
ret = sprintf(buf, "%d\n",
|
||||
device_info->inbound.bytes_avail_toread);
|
||||
} else if (!strcmp(dev_attr->attr.name, "in_write_bytes_avail")) {
|
||||
return sprintf(buf, "%d\n",
|
||||
device_info.inbound.bytes_avail_towrite);
|
||||
ret = sprintf(buf, "%d\n",
|
||||
device_info->inbound.bytes_avail_towrite);
|
||||
} else if (!strcmp(dev_attr->attr.name, "monitor_id")) {
|
||||
return sprintf(buf, "%d\n", device_info.monitor_id);
|
||||
ret = sprintf(buf, "%d\n", device_info->monitor_id);
|
||||
} else if (!strcmp(dev_attr->attr.name, "server_monitor_pending")) {
|
||||
return sprintf(buf, "%d\n", device_info.server_monitor_pending);
|
||||
ret = sprintf(buf, "%d\n", device_info->server_monitor_pending);
|
||||
} else if (!strcmp(dev_attr->attr.name, "server_monitor_latency")) {
|
||||
return sprintf(buf, "%d\n", device_info.server_monitor_latency);
|
||||
ret = sprintf(buf, "%d\n", device_info->server_monitor_latency);
|
||||
} else if (!strcmp(dev_attr->attr.name, "server_monitor_conn_id")) {
|
||||
return sprintf(buf, "%d\n",
|
||||
device_info.server_monitor_conn_id);
|
||||
ret = sprintf(buf, "%d\n",
|
||||
device_info->server_monitor_conn_id);
|
||||
} else if (!strcmp(dev_attr->attr.name, "client_monitor_pending")) {
|
||||
return sprintf(buf, "%d\n", device_info.client_monitor_pending);
|
||||
ret = sprintf(buf, "%d\n", device_info->client_monitor_pending);
|
||||
} else if (!strcmp(dev_attr->attr.name, "client_monitor_latency")) {
|
||||
return sprintf(buf, "%d\n", device_info.client_monitor_latency);
|
||||
ret = sprintf(buf, "%d\n", device_info->client_monitor_latency);
|
||||
} else if (!strcmp(dev_attr->attr.name, "client_monitor_conn_id")) {
|
||||
return sprintf(buf, "%d\n",
|
||||
device_info.client_monitor_conn_id);
|
||||
} else {
|
||||
return 0;
|
||||
ret = sprintf(buf, "%d\n",
|
||||
device_info->client_monitor_conn_id);
|
||||
}
|
||||
|
||||
kfree(device_info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
|
||||
@ -208,6 +235,7 @@ static struct device_attribute vmbus_device_attrs[] = {
|
||||
__ATTR(class_id, S_IRUGO, vmbus_show_device_attr, NULL),
|
||||
__ATTR(device_id, S_IRUGO, vmbus_show_device_attr, NULL),
|
||||
__ATTR(monitor_id, S_IRUGO, vmbus_show_device_attr, NULL),
|
||||
__ATTR(modalias, S_IRUGO, vmbus_show_device_attr, NULL),
|
||||
|
||||
__ATTR(server_monitor_pending, S_IRUGO, vmbus_show_device_attr, NULL),
|
||||
__ATTR(server_monitor_latency, S_IRUGO, vmbus_show_device_attr, NULL),
|
||||
@ -238,76 +266,60 @@ static struct device_attribute vmbus_device_attrs[] = {
|
||||
* This routine is invoked when a device is added or removed on the vmbus to
|
||||
* generate a uevent to udev in the userspace. The udev will then look at its
|
||||
* rule and the uevent generated here to load the appropriate driver
|
||||
*
|
||||
* The alias string will be of the form vmbus:guid where guid is the string
|
||||
* representation of the device guid (each byte of the guid will be
|
||||
* represented with two hex characters.
|
||||
*/
|
||||
static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct hv_device *dev = device_to_hv_device(device);
|
||||
int ret;
|
||||
char alias_name[VMBUS_ALIAS_LEN + 1];
|
||||
|
||||
ret = add_uevent_var(env, "VMBUS_DEVICE_CLASS_GUID={"
|
||||
"%02x%02x%02x%02x-%02x%02x-%02x%02x-"
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x}",
|
||||
dev->dev_type.data[3],
|
||||
dev->dev_type.data[2],
|
||||
dev->dev_type.data[1],
|
||||
dev->dev_type.data[0],
|
||||
dev->dev_type.data[5],
|
||||
dev->dev_type.data[4],
|
||||
dev->dev_type.data[7],
|
||||
dev->dev_type.data[6],
|
||||
dev->dev_type.data[8],
|
||||
dev->dev_type.data[9],
|
||||
dev->dev_type.data[10],
|
||||
dev->dev_type.data[11],
|
||||
dev->dev_type.data[12],
|
||||
dev->dev_type.data[13],
|
||||
dev->dev_type.data[14],
|
||||
dev->dev_type.data[15]);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = add_uevent_var(env, "VMBUS_DEVICE_DEVICE_GUID={"
|
||||
"%02x%02x%02x%02x-%02x%02x-%02x%02x-"
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x}",
|
||||
dev->dev_instance.data[3],
|
||||
dev->dev_instance.data[2],
|
||||
dev->dev_instance.data[1],
|
||||
dev->dev_instance.data[0],
|
||||
dev->dev_instance.data[5],
|
||||
dev->dev_instance.data[4],
|
||||
dev->dev_instance.data[7],
|
||||
dev->dev_instance.data[6],
|
||||
dev->dev_instance.data[8],
|
||||
dev->dev_instance.data[9],
|
||||
dev->dev_instance.data[10],
|
||||
dev->dev_instance.data[11],
|
||||
dev->dev_instance.data[12],
|
||||
dev->dev_instance.data[13],
|
||||
dev->dev_instance.data[14],
|
||||
dev->dev_instance.data[15]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
print_alias_name(dev, alias_name);
|
||||
ret = add_uevent_var(env, "MODALIAS=vmbus:%s", alias_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uuid_le null_guid;
|
||||
|
||||
static inline bool is_null_guid(const __u8 *guid)
|
||||
{
|
||||
if (memcmp(guid, &null_guid, sizeof(uuid_le)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a matching hv_vmbus_device_id pointer.
|
||||
* If there is no match, return NULL.
|
||||
*/
|
||||
static const struct hv_vmbus_device_id *hv_vmbus_get_id(
|
||||
const struct hv_vmbus_device_id *id,
|
||||
__u8 *guid)
|
||||
{
|
||||
for (; !is_null_guid(id->guid); id++)
|
||||
if (!memcmp(&id->guid, guid, sizeof(uuid_le)))
|
||||
return id;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* vmbus_match - Attempt to match the specified device to the specified driver
|
||||
*/
|
||||
static int vmbus_match(struct device *device, struct device_driver *driver)
|
||||
{
|
||||
int match = 0;
|
||||
struct hv_driver *drv = drv_to_hv_drv(driver);
|
||||
struct hv_device *hv_dev = device_to_hv_device(device);
|
||||
|
||||
/* We found our driver ? */
|
||||
if (memcmp(&hv_dev->dev_type, &drv->dev_type,
|
||||
sizeof(struct hv_guid)) == 0)
|
||||
match = 1;
|
||||
if (hv_vmbus_get_id(drv->id_table, hv_dev->dev_type.b))
|
||||
return 1;
|
||||
|
||||
return match;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -319,9 +331,11 @@ static int vmbus_probe(struct device *child_device)
|
||||
struct hv_driver *drv =
|
||||
drv_to_hv_drv(child_device->driver);
|
||||
struct hv_device *dev = device_to_hv_device(child_device);
|
||||
const struct hv_vmbus_device_id *dev_id;
|
||||
|
||||
dev_id = hv_vmbus_get_id(drv->id_table, dev->dev_type.b);
|
||||
if (drv->probe) {
|
||||
ret = drv->probe(dev);
|
||||
ret = drv->probe(dev, dev_id);
|
||||
if (ret != 0)
|
||||
pr_err("probe failed for device %s (%d)\n",
|
||||
dev_name(child_device), ret);
|
||||
@ -339,22 +353,14 @@ static int vmbus_probe(struct device *child_device)
|
||||
*/
|
||||
static int vmbus_remove(struct device *child_device)
|
||||
{
|
||||
int ret;
|
||||
struct hv_driver *drv;
|
||||
|
||||
struct hv_driver *drv = drv_to_hv_drv(child_device->driver);
|
||||
struct hv_device *dev = device_to_hv_device(child_device);
|
||||
|
||||
if (child_device->driver) {
|
||||
drv = drv_to_hv_drv(child_device->driver);
|
||||
|
||||
if (drv->remove) {
|
||||
ret = drv->remove(dev);
|
||||
} else {
|
||||
pr_err("remove not set for driver %s\n",
|
||||
dev_name(child_device));
|
||||
ret = -ENODEV;
|
||||
}
|
||||
}
|
||||
if (drv->remove)
|
||||
drv->remove(dev);
|
||||
else
|
||||
pr_err("remove not set for driver %s\n",
|
||||
dev_name(child_device));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -422,9 +428,6 @@ static void vmbus_onmessage_work(struct work_struct *work)
|
||||
kfree(ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* vmbus_on_msg_dpc - DPC routine to handle messages from the hypervisior
|
||||
*/
|
||||
static void vmbus_on_msg_dpc(unsigned long data)
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
@ -468,53 +471,42 @@ static void vmbus_on_msg_dpc(unsigned long data)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* vmbus_on_isr - ISR routine
|
||||
*/
|
||||
static int vmbus_on_isr(void)
|
||||
static irqreturn_t vmbus_isr(int irq, void *dev_id)
|
||||
{
|
||||
int ret = 0;
|
||||
int cpu = smp_processor_id();
|
||||
void *page_addr;
|
||||
struct hv_message *msg;
|
||||
union hv_synic_event_flags *event;
|
||||
bool handled = false;
|
||||
|
||||
page_addr = hv_context.synic_message_page[cpu];
|
||||
msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;
|
||||
|
||||
/* Check if there are actual msgs to be process */
|
||||
if (msg->header.message_type != HVMSG_NONE)
|
||||
ret |= 0x1;
|
||||
/*
|
||||
* Check for events before checking for messages. This is the order
|
||||
* in which events and messages are checked in Windows guests on
|
||||
* Hyper-V, and the Windows team suggested we do the same.
|
||||
*/
|
||||
|
||||
page_addr = hv_context.synic_event_page[cpu];
|
||||
event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT;
|
||||
|
||||
/* Since we are a child, we only need to check bit 0 */
|
||||
if (sync_test_and_clear_bit(0, (unsigned long *) &event->flags32[0]))
|
||||
ret |= 0x2;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static irqreturn_t vmbus_isr(int irq, void *dev_id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = vmbus_on_isr();
|
||||
|
||||
/* Schedules a dpc if necessary */
|
||||
if (ret > 0) {
|
||||
if (test_bit(0, (unsigned long *)&ret))
|
||||
tasklet_schedule(&msg_dpc);
|
||||
|
||||
if (test_bit(1, (unsigned long *)&ret))
|
||||
tasklet_schedule(&event_dpc);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
} else {
|
||||
return IRQ_NONE;
|
||||
if (sync_test_and_clear_bit(0, (unsigned long *) &event->flags32[0])) {
|
||||
handled = true;
|
||||
tasklet_schedule(&event_dpc);
|
||||
}
|
||||
|
||||
page_addr = hv_context.synic_message_page[cpu];
|
||||
msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;
|
||||
|
||||
/* Check if there are actual msgs to be processed */
|
||||
if (msg->header.message_type != HVMSG_NONE) {
|
||||
handled = true;
|
||||
tasklet_schedule(&msg_dpc);
|
||||
}
|
||||
|
||||
if (handled)
|
||||
return IRQ_HANDLED;
|
||||
else
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -538,26 +530,20 @@ static int vmbus_bus_init(int irq)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Initialize the bus context */
|
||||
tasklet_init(&msg_dpc, vmbus_on_msg_dpc, 0);
|
||||
tasklet_init(&event_dpc, vmbus_on_event, 0);
|
||||
|
||||
/* Now, register the bus with LDM */
|
||||
ret = bus_register(&hv_bus);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_cleanup;
|
||||
|
||||
/* Get the interrupt resource */
|
||||
ret = request_irq(irq, vmbus_isr, IRQF_SAMPLE_RANDOM,
|
||||
driver_name, hv_acpi_dev);
|
||||
|
||||
if (ret != 0) {
|
||||
pr_err("Unable to request IRQ %d\n",
|
||||
irq);
|
||||
|
||||
bus_unregister(&hv_bus);
|
||||
|
||||
return ret;
|
||||
goto err_unregister;
|
||||
}
|
||||
|
||||
vector = IRQ0_VECTOR + irq;
|
||||
@ -568,76 +554,81 @@ static int vmbus_bus_init(int irq)
|
||||
*/
|
||||
on_each_cpu(hv_synic_init, (void *)&vector, 1);
|
||||
ret = vmbus_connect();
|
||||
if (ret) {
|
||||
free_irq(irq, hv_acpi_dev);
|
||||
bus_unregister(&hv_bus);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
goto err_irq;
|
||||
|
||||
vmbus_request_offers();
|
||||
|
||||
return 0;
|
||||
|
||||
err_irq:
|
||||
free_irq(irq, hv_acpi_dev);
|
||||
|
||||
err_unregister:
|
||||
bus_unregister(&hv_bus);
|
||||
|
||||
err_cleanup:
|
||||
hv_cleanup();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* vmbus_child_driver_register() - Register a vmbus's child driver
|
||||
* @drv: Pointer to driver structure you want to register
|
||||
*
|
||||
* __vmbus_child_driver_register - Register a vmbus's driver
|
||||
* @drv: Pointer to driver structure you want to register
|
||||
* @owner: owner module of the drv
|
||||
* @mod_name: module name string
|
||||
*
|
||||
* Registers the given driver with Linux through the 'driver_register()' call
|
||||
* And sets up the hyper-v vmbus handling for this driver.
|
||||
* and sets up the hyper-v vmbus handling for this driver.
|
||||
* It will return the state of the 'driver_register()' call.
|
||||
*
|
||||
* Mainly used by Hyper-V drivers.
|
||||
*/
|
||||
int vmbus_child_driver_register(struct device_driver *drv)
|
||||
int __vmbus_driver_register(struct hv_driver *hv_driver, struct module *owner, const char *mod_name)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pr_info("child driver registering - name %s\n", drv->name);
|
||||
pr_info("registering driver %s\n", hv_driver->name);
|
||||
|
||||
/* The child driver on this vmbus */
|
||||
drv->bus = &hv_bus;
|
||||
hv_driver->driver.name = hv_driver->name;
|
||||
hv_driver->driver.owner = owner;
|
||||
hv_driver->driver.mod_name = mod_name;
|
||||
hv_driver->driver.bus = &hv_bus;
|
||||
|
||||
ret = driver_register(drv);
|
||||
ret = driver_register(&hv_driver->driver);
|
||||
|
||||
vmbus_request_offers();
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(vmbus_child_driver_register);
|
||||
EXPORT_SYMBOL_GPL(__vmbus_driver_register);
|
||||
|
||||
/**
|
||||
* vmbus_child_driver_unregister() - Unregister a vmbus's child driver
|
||||
* @drv: Pointer to driver structure you want to un-register
|
||||
* vmbus_driver_unregister() - Unregister a vmbus's driver
|
||||
* @drv: Pointer to driver structure you want to un-register
|
||||
*
|
||||
*
|
||||
* Un-register the given driver with Linux through the 'driver_unregister()'
|
||||
* call. And ungegisters the driver from the Hyper-V vmbus handler.
|
||||
*
|
||||
* Mainly used by Hyper-V drivers.
|
||||
* Un-register the given driver that was previous registered with a call to
|
||||
* vmbus_driver_register()
|
||||
*/
|
||||
void vmbus_child_driver_unregister(struct device_driver *drv)
|
||||
void vmbus_driver_unregister(struct hv_driver *hv_driver)
|
||||
{
|
||||
pr_info("child driver unregistering - name %s\n", drv->name);
|
||||
pr_info("unregistering driver %s\n", hv_driver->name);
|
||||
|
||||
driver_unregister(drv);
|
||||
driver_unregister(&hv_driver->driver);
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(vmbus_child_driver_unregister);
|
||||
EXPORT_SYMBOL_GPL(vmbus_driver_unregister);
|
||||
|
||||
/*
|
||||
* vmbus_child_device_create - Creates and registers a new child device
|
||||
* vmbus_device_create - Creates and registers a new child device
|
||||
* on the vmbus.
|
||||
*/
|
||||
struct hv_device *vmbus_child_device_create(struct hv_guid *type,
|
||||
struct hv_guid *instance,
|
||||
struct hv_device *vmbus_device_create(uuid_le *type,
|
||||
uuid_le *instance,
|
||||
struct vmbus_channel *channel)
|
||||
{
|
||||
struct hv_device *child_device_obj;
|
||||
|
||||
/* Allocate the new child device */
|
||||
child_device_obj = kzalloc(sizeof(struct hv_device), GFP_KERNEL);
|
||||
if (!child_device_obj) {
|
||||
pr_err("Unable to allocate device object for child device\n");
|
||||
@ -645,29 +636,27 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *type,
|
||||
}
|
||||
|
||||
child_device_obj->channel = channel;
|
||||
memcpy(&child_device_obj->dev_type, type, sizeof(struct hv_guid));
|
||||
memcpy(&child_device_obj->dev_type, type, sizeof(uuid_le));
|
||||
memcpy(&child_device_obj->dev_instance, instance,
|
||||
sizeof(struct hv_guid));
|
||||
sizeof(uuid_le));
|
||||
|
||||
|
||||
return child_device_obj;
|
||||
}
|
||||
|
||||
/*
|
||||
* vmbus_child_device_register - Register the child device
|
||||
* vmbus_device_register - Register the child device
|
||||
*/
|
||||
int vmbus_child_device_register(struct hv_device *child_device_obj)
|
||||
int vmbus_device_register(struct hv_device *child_device_obj)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
static atomic_t device_num = ATOMIC_INIT(0);
|
||||
|
||||
/* Set the device name. Otherwise, device_register() will fail. */
|
||||
dev_set_name(&child_device_obj->device, "vmbus_0_%d",
|
||||
atomic_inc_return(&device_num));
|
||||
|
||||
/* The new device belongs to this bus */
|
||||
child_device_obj->device.bus = &hv_bus; /* device->dev.bus; */
|
||||
child_device_obj->device.bus = &hv_bus;
|
||||
child_device_obj->device.parent = &hv_acpi_dev->dev;
|
||||
child_device_obj->device.release = vmbus_device_release;
|
||||
|
||||
@ -687,10 +676,10 @@ int vmbus_child_device_register(struct hv_device *child_device_obj)
|
||||
}
|
||||
|
||||
/*
|
||||
* vmbus_child_device_unregister - Remove the specified child device
|
||||
* vmbus_device_unregister - Remove the specified child device
|
||||
* from the vmbus.
|
||||
*/
|
||||
void vmbus_child_device_unregister(struct hv_device *device_obj)
|
||||
void vmbus_device_unregister(struct hv_device *device_obj)
|
||||
{
|
||||
/*
|
||||
* Kick off the process of unregistering the device.
|
||||
@ -727,9 +716,8 @@ static int vmbus_acpi_add(struct acpi_device *device)
|
||||
|
||||
hv_acpi_dev = device;
|
||||
|
||||
result =
|
||||
acpi_walk_resources(device->handle, METHOD_NAME__CRS,
|
||||
vmbus_walk_resources, &irq);
|
||||
result = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
|
||||
vmbus_walk_resources, &irq);
|
||||
|
||||
if (ACPI_FAILURE(result)) {
|
||||
complete(&probe_event);
|
||||
@ -754,21 +742,9 @@ static struct acpi_driver vmbus_acpi_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* We use a PCI table to determine if we should autoload this driver This is
|
||||
* needed by distro tools to determine if the hyperv drivers should be
|
||||
* installed and/or configured. We don't do anything else with the table, but
|
||||
* it needs to be present.
|
||||
*/
|
||||
static const struct pci_device_id microsoft_hv_pci_table[] = {
|
||||
{ PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */
|
||||
{ 0 }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table);
|
||||
|
||||
static int __init hv_acpi_init(void)
|
||||
{
|
||||
int ret;
|
||||
int ret, t;
|
||||
|
||||
init_completion(&probe_event);
|
||||
|
||||
@ -781,22 +757,30 @@ static int __init hv_acpi_init(void)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
wait_for_completion(&probe_event);
|
||||
t = wait_for_completion_timeout(&probe_event, 5*HZ);
|
||||
if (t == 0) {
|
||||
ret = -ETIMEDOUT;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (irq <= 0) {
|
||||
acpi_bus_unregister_driver(&vmbus_acpi_driver);
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = vmbus_bus_init(irq);
|
||||
if (ret)
|
||||
acpi_bus_unregister_driver(&vmbus_acpi_driver);
|
||||
goto cleanup;
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
acpi_bus_unregister_driver(&vmbus_acpi_driver);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION(HV_DRV_VERSION);
|
||||
module_param(vmbus_loglevel, int, S_IRUGO|S_IWUSR);
|
||||
|
||||
module_init(hv_acpi_init);
|
@ -46,8 +46,6 @@ source "drivers/staging/wlan-ng/Kconfig"
|
||||
|
||||
source "drivers/staging/echo/Kconfig"
|
||||
|
||||
|
||||
|
||||
source "drivers/staging/comedi/Kconfig"
|
||||
|
||||
source "drivers/staging/olpc_dcon/Kconfig"
|
||||
@ -66,6 +64,8 @@ source "drivers/staging/rtl8712/Kconfig"
|
||||
|
||||
source "drivers/staging/rts_pstor/Kconfig"
|
||||
|
||||
source "drivers/staging/rts5139/Kconfig"
|
||||
|
||||
source "drivers/staging/frontier/Kconfig"
|
||||
|
||||
source "drivers/staging/pohmelfs/Kconfig"
|
||||
|
@ -15,8 +15,6 @@ obj-$(CONFIG_USBIP_CORE) += usbip/
|
||||
obj-$(CONFIG_W35UND) += winbond/
|
||||
obj-$(CONFIG_PRISM2_USB) += wlan-ng/
|
||||
obj-$(CONFIG_ECHO) += echo/
|
||||
|
||||
|
||||
obj-$(CONFIG_COMEDI) += comedi/
|
||||
obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/
|
||||
obj-$(CONFIG_ASUS_OLED) += asus_oled/
|
||||
@ -26,6 +24,7 @@ obj-$(CONFIG_RTL8192U) += rtl8192u/
|
||||
obj-$(CONFIG_RTL8192E) += rtl8192e/
|
||||
obj-$(CONFIG_R8712U) += rtl8712/
|
||||
obj-$(CONFIG_RTS_PSTOR) += rts_pstor/
|
||||
obj-$(CONFIG_RTS5139) += rts5139/
|
||||
obj-$(CONFIG_SPECTRA) += spectra/
|
||||
obj-$(CONFIG_TRANZPORT) += frontier/
|
||||
obj-$(CONFIG_POHMELFS) += pohmelfs/
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include "altera.h"
|
||||
#include "altera-exprt.h"
|
||||
#include "altera-jtag.h"
|
||||
@ -2384,7 +2385,7 @@ static int altera_get_act_info(u8 *p,
|
||||
act_proc_attribute =
|
||||
(p[proc_table + (13 * act_proc_id) + 8] & 0x03);
|
||||
|
||||
procptr = (struct altera_procinfo *)
|
||||
procptr =
|
||||
kzalloc(sizeof(struct altera_procinfo),
|
||||
GFP_KERNEL);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,204 +1,183 @@
|
||||
#include "headers.h"
|
||||
|
||||
|
||||
int InterfaceFileDownload( PVOID arg,
|
||||
struct file *flp,
|
||||
unsigned int on_chip_loc)
|
||||
int InterfaceFileDownload(PVOID arg, struct file *flp, unsigned int on_chip_loc)
|
||||
{
|
||||
// unsigned int reg=0;
|
||||
mm_segment_t oldfs={0};
|
||||
int errno=0, len=0 /*,is_config_file = 0*/;
|
||||
loff_t pos=0;
|
||||
/* unsigned int reg = 0; */
|
||||
mm_segment_t oldfs = {0};
|
||||
int errno = 0, len = 0; /* ,is_config_file = 0 */
|
||||
loff_t pos = 0;
|
||||
PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
|
||||
//PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter;
|
||||
char *buff=kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
|
||||
/* PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter; */
|
||||
char *buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
|
||||
|
||||
if(!buff)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
while(1)
|
||||
{
|
||||
oldfs=get_fs(); set_fs(get_ds());
|
||||
len=vfs_read(flp, (void __force __user *)buff, MAX_TRANSFER_CTRL_BYTE_USB, &pos);
|
||||
set_fs(oldfs);
|
||||
if(len<=0)
|
||||
{
|
||||
if(len<0)
|
||||
{
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len < 0");
|
||||
errno=len;
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = 0;
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got end of file!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
//BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, buff, MAX_TRANSFER_CTRL_BYTE_USB);
|
||||
errno = InterfaceWRM(psIntfAdapter, on_chip_loc, buff, len) ;
|
||||
if(errno)
|
||||
{
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "WRM Failed! status: %d", errno);
|
||||
if (!buff)
|
||||
return -ENOMEM;
|
||||
|
||||
while (1) {
|
||||
oldfs = get_fs();
|
||||
set_fs(get_ds());
|
||||
len = vfs_read(flp, (void __force __user *)buff,
|
||||
MAX_TRANSFER_CTRL_BYTE_USB, &pos);
|
||||
set_fs(oldfs);
|
||||
if (len <= 0) {
|
||||
if (len < 0) {
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
|
||||
DBG_TYPE_INITEXIT, MP_INIT,
|
||||
DBG_LVL_ALL, "len < 0");
|
||||
errno = len;
|
||||
} else {
|
||||
errno = 0;
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
|
||||
DBG_TYPE_INITEXIT, MP_INIT,
|
||||
DBG_LVL_ALL,
|
||||
"Got end of file!");
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
on_chip_loc+=MAX_TRANSFER_CTRL_BYTE_USB;
|
||||
}/* End of for(;;)*/
|
||||
/* BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_INITEXIT, MP_INIT,
|
||||
* DBG_LVL_ALL, buff,
|
||||
* MAX_TRANSFER_CTRL_BYTE_USB);
|
||||
*/
|
||||
errno = InterfaceWRM(psIntfAdapter, on_chip_loc, buff, len);
|
||||
if (errno) {
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
|
||||
DBG_TYPE_PRINTK, 0, 0,
|
||||
"WRM Failed! status: %d", errno);
|
||||
break;
|
||||
}
|
||||
on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB;
|
||||
}
|
||||
|
||||
kfree(buff);
|
||||
return errno;
|
||||
return errno;
|
||||
}
|
||||
|
||||
int InterfaceFileReadbackFromChip( PVOID arg,
|
||||
struct file *flp,
|
||||
unsigned int on_chip_loc)
|
||||
int InterfaceFileReadbackFromChip(PVOID arg, struct file *flp, unsigned int on_chip_loc)
|
||||
{
|
||||
char *buff, *buff_readback;
|
||||
unsigned int reg=0;
|
||||
mm_segment_t oldfs={0};
|
||||
int errno=0, len=0, is_config_file = 0;
|
||||
loff_t pos=0;
|
||||
static int fw_down = 0;
|
||||
INT Status = STATUS_SUCCESS;
|
||||
char *buff, *buff_readback;
|
||||
unsigned int reg = 0;
|
||||
mm_segment_t oldfs = {0};
|
||||
int errno = 0, len = 0, is_config_file = 0;
|
||||
loff_t pos = 0;
|
||||
static int fw_down;
|
||||
INT Status = STATUS_SUCCESS;
|
||||
PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
|
||||
|
||||
buff=kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA);
|
||||
buff_readback=kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA);
|
||||
if(!buff || !buff_readback)
|
||||
{
|
||||
kfree(buff);
|
||||
kfree(buff_readback);
|
||||
buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA);
|
||||
buff_readback = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA);
|
||||
if (!buff || !buff_readback) {
|
||||
kfree(buff);
|
||||
kfree(buff_readback);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
is_config_file = (on_chip_loc == CONFIG_BEGIN_ADDR)? 1:0;
|
||||
is_config_file = (on_chip_loc == CONFIG_BEGIN_ADDR) ? 1 : 0;
|
||||
|
||||
memset(buff_readback, 0, MAX_TRANSFER_CTRL_BYTE_USB);
|
||||
memset(buff, 0, MAX_TRANSFER_CTRL_BYTE_USB);
|
||||
while(1)
|
||||
{
|
||||
oldfs=get_fs(); set_fs(get_ds());
|
||||
len=vfs_read(flp, (void __force __user *)buff, MAX_TRANSFER_CTRL_BYTE_USB, &pos);
|
||||
set_fs(oldfs);
|
||||
fw_down++;
|
||||
if(len<=0)
|
||||
{
|
||||
if(len<0)
|
||||
{
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len < 0");
|
||||
errno=len;
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = 0;
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got end of file!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
while (1) {
|
||||
oldfs = get_fs();
|
||||
set_fs(get_ds());
|
||||
len = vfs_read(flp, (void __force __user *)buff, MAX_TRANSFER_CTRL_BYTE_USB, &pos);
|
||||
set_fs(oldfs);
|
||||
fw_down++;
|
||||
|
||||
if (len <= 0) {
|
||||
if (len < 0) {
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len < 0");
|
||||
errno = len;
|
||||
} else {
|
||||
errno = 0;
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got end of file!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Status = InterfaceRDM(psIntfAdapter, on_chip_loc, buff_readback, len);
|
||||
if(Status)
|
||||
{
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "RDM of len %d Failed! %d", len, reg);
|
||||
if (Status) {
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "RDM of len %d Failed! %d", len, reg);
|
||||
goto exit;
|
||||
}
|
||||
reg++;
|
||||
if((len-sizeof(unsigned int))<4)
|
||||
{
|
||||
if(memcmp(buff_readback, buff, len))
|
||||
{
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down);
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT,DBG_LVL_ALL,"Length is: %d",len);
|
||||
if ((len-sizeof(unsigned int)) < 4) {
|
||||
if (memcmp(buff_readback, buff, len)) {
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down);
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Length is: %d", len);
|
||||
Status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len-=4;
|
||||
while(len)
|
||||
{
|
||||
if(*(unsigned int*)&buff_readback[len] != *(unsigned int *)&buff[len])
|
||||
{
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down);
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Val from Binary %x, Val From Read Back %x ", *(unsigned int *)&buff[len], *(unsigned int*)&buff_readback[len]);
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len);
|
||||
}
|
||||
} else {
|
||||
len -= 4;
|
||||
|
||||
while (len) {
|
||||
if (*(unsigned int *)&buff_readback[len] != *(unsigned int *)&buff[len]) {
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down);
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Val from Binary %x, Val From Read Back %x ", *(unsigned int *)&buff[len], *(unsigned int*)&buff_readback[len]);
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len);
|
||||
Status = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
len-=4;
|
||||
}
|
||||
}
|
||||
on_chip_loc+=MAX_TRANSFER_CTRL_BYTE_USB;
|
||||
}/* End of while(1)*/
|
||||
}
|
||||
len -= 4;
|
||||
}
|
||||
}
|
||||
on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB;
|
||||
} /* End of while(1) */
|
||||
|
||||
exit:
|
||||
kfree(buff);
|
||||
kfree(buff_readback);
|
||||
kfree(buff);
|
||||
kfree(buff_readback);
|
||||
return Status;
|
||||
}
|
||||
|
||||
static int bcm_download_config_file(PMINI_ADAPTER Adapter,
|
||||
FIRMWARE_INFO *psFwInfo)
|
||||
static int bcm_download_config_file(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo)
|
||||
{
|
||||
int retval = STATUS_SUCCESS;
|
||||
B_UINT32 value = 0;
|
||||
|
||||
if(Adapter->pstargetparams == NULL)
|
||||
{
|
||||
if((Adapter->pstargetparams =
|
||||
kmalloc(sizeof(STARGETPARAMS), GFP_KERNEL)) == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
if(psFwInfo->u32FirmwareLength != sizeof(STARGETPARAMS))
|
||||
{
|
||||
return -EIO;
|
||||
if (Adapter->pstargetparams == NULL) {
|
||||
Adapter->pstargetparams = kmalloc(sizeof(STARGETPARAMS), GFP_KERNEL);
|
||||
if (Adapter->pstargetparams == NULL)
|
||||
return -ENOMEM;
|
||||
}
|
||||
retval = copy_from_user(Adapter->pstargetparams,
|
||||
psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength);
|
||||
if(retval)
|
||||
{
|
||||
|
||||
if (psFwInfo->u32FirmwareLength != sizeof(STARGETPARAMS))
|
||||
return -EIO;
|
||||
|
||||
retval = copy_from_user(Adapter->pstargetparams, psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength);
|
||||
if (retval) {
|
||||
kfree(Adapter->pstargetparams);
|
||||
Adapter->pstargetparams = NULL;
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* Parse the structure and then Download the Firmware */
|
||||
beceem_parse_target_struct(Adapter);
|
||||
|
||||
//Initializing the NVM.
|
||||
/* Initializing the NVM. */
|
||||
BcmInitNVM(Adapter);
|
||||
retval = InitLedSettings(Adapter);
|
||||
|
||||
retval = InitLedSettings (Adapter);
|
||||
|
||||
if(retval)
|
||||
{
|
||||
BCM_DEBUG_PRINT (Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "INIT LED Failed\n");
|
||||
if (retval) {
|
||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "INIT LED Failed\n");
|
||||
return retval;
|
||||
}
|
||||
|
||||
if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
|
||||
{
|
||||
if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
|
||||
Adapter->LEDInfo.bLedInitDone = FALSE;
|
||||
Adapter->DriverState = DRIVER_INIT;
|
||||
wake_up(&Adapter->LEDInfo.notify_led_event);
|
||||
}
|
||||
|
||||
if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
|
||||
{
|
||||
if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
|
||||
Adapter->DriverState = FW_DOWNLOAD;
|
||||
wake_up(&Adapter->LEDInfo.notify_led_event);
|
||||
}
|
||||
|
||||
/* Initialize the DDR Controller */
|
||||
retval = ddr_init(Adapter);
|
||||
if(retval)
|
||||
{
|
||||
BCM_DEBUG_PRINT (Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "DDR Init Failed\n");
|
||||
if (retval) {
|
||||
BCM_DEBUG_PRINT (Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "DDR Init Failed\n");
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -206,197 +185,166 @@ static int bcm_download_config_file(PMINI_ADAPTER Adapter,
|
||||
wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
|
||||
wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));
|
||||
|
||||
if(Adapter->eNVMType == NVM_FLASH)
|
||||
{
|
||||
if (Adapter->eNVMType == NVM_FLASH) {
|
||||
retval = PropagateCalParamsFromFlashToMemory(Adapter);
|
||||
if(retval)
|
||||
{
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"propagaion of cal param failed with status :%d", retval);
|
||||
if (retval) {
|
||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "propagaion of cal param failed with status :%d", retval);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
retval = buffDnldVerify(Adapter, (PUCHAR)Adapter->pstargetparams, sizeof(STARGETPARAMS), CONFIG_BEGIN_ADDR);
|
||||
|
||||
retval =buffDnldVerify(Adapter,(PUCHAR)Adapter->pstargetparams,sizeof(STARGETPARAMS),CONFIG_BEGIN_ADDR);
|
||||
|
||||
if(retval)
|
||||
{
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "configuration file not downloaded properly");
|
||||
}
|
||||
if (retval)
|
||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "configuration file not downloaded properly");
|
||||
else
|
||||
Adapter->bCfgDownloaded = TRUE;
|
||||
|
||||
|
||||
return retval;
|
||||
}
|
||||
static int bcm_compare_buff_contents(unsigned char *readbackbuff,
|
||||
unsigned char *buff,unsigned int len)
|
||||
|
||||
static int bcm_compare_buff_contents(unsigned char *readbackbuff, unsigned char *buff, unsigned int len)
|
||||
{
|
||||
int retval = STATUS_SUCCESS;
|
||||
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
||||
if((len-sizeof(unsigned int))<4)
|
||||
{
|
||||
if(memcmp(readbackbuff , buff, len))
|
||||
{
|
||||
retval=-EINVAL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len-=4;
|
||||
while(len)
|
||||
{
|
||||
if(*(unsigned int*)&readbackbuff[len] !=
|
||||
*(unsigned int *)&buff[len])
|
||||
{
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper");
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Val from Binary %x, Val From Read Back %x ", *(unsigned int *)&buff[len], *(unsigned int*)&readbackbuff[len]);
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len);
|
||||
retval=-EINVAL;
|
||||
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
||||
if ((len-sizeof(unsigned int)) < 4) {
|
||||
if (memcmp(readbackbuff , buff, len))
|
||||
retval = -EINVAL;
|
||||
} else {
|
||||
len -= 4;
|
||||
|
||||
while (len) {
|
||||
if (*(unsigned int *)&readbackbuff[len] != *(unsigned int *)&buff[len]) {
|
||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper");
|
||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Val from Binary %x, Val From Read Back %x ", *(unsigned int *)&buff[len], *(unsigned int*)&readbackbuff[len]);
|
||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len);
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
len-=4;
|
||||
len -= 4;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo)
|
||||
{
|
||||
int retval = STATUS_SUCCESS;
|
||||
PUCHAR buff = NULL;
|
||||
|
||||
/* Config File is needed for the Driver to download the Config file and
|
||||
Firmware. Check for the Config file to be first to be sent from the
|
||||
Application
|
||||
*/
|
||||
atomic_set (&Adapter->uiMBupdate, FALSE);
|
||||
if(!Adapter->bCfgDownloaded &&
|
||||
psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR)
|
||||
{
|
||||
/*Can't Download Firmware.*/
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Download the config File first\n");
|
||||
/* Config File is needed for the Driver to download the Config file and
|
||||
* Firmware. Check for the Config file to be first to be sent from the
|
||||
* Application
|
||||
*/
|
||||
atomic_set(&Adapter->uiMBupdate, FALSE);
|
||||
if (!Adapter->bCfgDownloaded && psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR) {
|
||||
/* Can't Download Firmware. */
|
||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Download the config File first\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* If Config File, Finish the DDR Settings and then Download CFG File */
|
||||
if(psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR)
|
||||
{
|
||||
retval = bcm_download_config_file (Adapter, psFwInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
buff = kzalloc(psFwInfo->u32FirmwareLength,GFP_KERNEL);
|
||||
if(buff==NULL)
|
||||
{
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Failed in allocation memory");
|
||||
if (psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR) {
|
||||
retval = bcm_download_config_file(Adapter, psFwInfo);
|
||||
} else {
|
||||
buff = kzalloc(psFwInfo->u32FirmwareLength, GFP_KERNEL);
|
||||
if (buff == NULL) {
|
||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed in allocation memory");
|
||||
return -ENOMEM;
|
||||
}
|
||||
retval = copy_from_user(buff,psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength);
|
||||
if(retval != STATUS_SUCCESS)
|
||||
{
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copying buffer from user space failed");
|
||||
|
||||
retval = copy_from_user(buff, psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength);
|
||||
if (retval != STATUS_SUCCESS) {
|
||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copying buffer from user space failed");
|
||||
retval = -EFAULT;
|
||||
goto error ;
|
||||
goto error;
|
||||
}
|
||||
|
||||
retval = buffDnldVerify(Adapter,
|
||||
buff,
|
||||
psFwInfo->u32FirmwareLength,
|
||||
psFwInfo->u32StartingAddress);
|
||||
if(retval != STATUS_SUCCESS)
|
||||
{
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"f/w download failed status :%d", retval);
|
||||
|
||||
if (retval != STATUS_SUCCESS) {
|
||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "f/w download failed status :%d", retval);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
kfree(buff);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static INT buffDnld(PMINI_ADAPTER Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength,
|
||||
ULONG u32StartingAddress)
|
||||
static INT buffDnld(PMINI_ADAPTER Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, ULONG u32StartingAddress)
|
||||
{
|
||||
|
||||
unsigned int len = 0;
|
||||
unsigned int len = 0;
|
||||
int retval = STATUS_SUCCESS;
|
||||
len = u32FirmwareLength;
|
||||
|
||||
while(u32FirmwareLength)
|
||||
{
|
||||
len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
|
||||
retval = wrm (Adapter, u32StartingAddress, mappedbuffer, len);
|
||||
if(retval)
|
||||
{
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "wrm failed with status :%d", retval);
|
||||
while (u32FirmwareLength) {
|
||||
len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
|
||||
retval = wrm(Adapter, u32StartingAddress, mappedbuffer, len);
|
||||
|
||||
if (retval) {
|
||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "wrm failed with status :%d", retval);
|
||||
break;
|
||||
}
|
||||
u32StartingAddress += len;
|
||||
u32FirmwareLength -= len;
|
||||
mappedbuffer +=len;
|
||||
u32StartingAddress += len;
|
||||
u32FirmwareLength -= len;
|
||||
mappedbuffer += len;
|
||||
}
|
||||
return retval;
|
||||
|
||||
}
|
||||
|
||||
static INT buffRdbkVerify(PMINI_ADAPTER Adapter,
|
||||
PUCHAR mappedbuffer, UINT u32FirmwareLength,
|
||||
ULONG u32StartingAddress)
|
||||
static INT buffRdbkVerify(PMINI_ADAPTER Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, ULONG u32StartingAddress)
|
||||
{
|
||||
UINT len = u32FirmwareLength;
|
||||
INT retval = STATUS_SUCCESS;
|
||||
PUCHAR readbackbuff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB,GFP_KERNEL);
|
||||
PUCHAR readbackbuff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
|
||||
|
||||
if(NULL == readbackbuff)
|
||||
{
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "MEMORY ALLOCATION FAILED");
|
||||
if (NULL == readbackbuff) {
|
||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "MEMORY ALLOCATION FAILED");
|
||||
return -ENOMEM;
|
||||
}
|
||||
while (u32FirmwareLength && !retval)
|
||||
{
|
||||
|
||||
len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
|
||||
while (u32FirmwareLength && !retval) {
|
||||
len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
|
||||
retval = rdm(Adapter, u32StartingAddress, readbackbuff, len);
|
||||
|
||||
retval = rdm (Adapter, u32StartingAddress, readbackbuff, len);
|
||||
if(retval)
|
||||
{
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed with status %d" ,retval);
|
||||
if (retval) {
|
||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed with status %d", retval);
|
||||
break;
|
||||
}
|
||||
|
||||
if (STATUS_SUCCESS != (retval = bcm_compare_buff_contents (readbackbuff, mappedbuffer, len)))
|
||||
{
|
||||
retval = bcm_compare_buff_contents(readbackbuff, mappedbuffer, len);
|
||||
if (STATUS_SUCCESS != retval)
|
||||
break;
|
||||
}
|
||||
u32StartingAddress += len;
|
||||
u32FirmwareLength -= len;
|
||||
mappedbuffer +=len;
|
||||
}/* end of while (u32FirmwareLength && !retval) */
|
||||
|
||||
u32StartingAddress += len;
|
||||
u32FirmwareLength -= len;
|
||||
mappedbuffer += len;
|
||||
|
||||
} /* end of while (u32FirmwareLength && !retval) */
|
||||
kfree(readbackbuff);
|
||||
return retval;
|
||||
}
|
||||
|
||||
INT buffDnldVerify(PMINI_ADAPTER Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength,
|
||||
unsigned long u32StartingAddress)
|
||||
INT buffDnldVerify(PMINI_ADAPTER Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength, unsigned long u32StartingAddress)
|
||||
{
|
||||
INT status = STATUS_SUCCESS;
|
||||
|
||||
status = buffDnld(Adapter,mappedbuffer,u32FirmwareLength,u32StartingAddress);
|
||||
if(status != STATUS_SUCCESS)
|
||||
{
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Buffer download failed");
|
||||
status = buffDnld(Adapter, mappedbuffer, u32FirmwareLength, u32StartingAddress);
|
||||
if (status != STATUS_SUCCESS) {
|
||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Buffer download failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
status= buffRdbkVerify(Adapter,mappedbuffer,u32FirmwareLength,u32StartingAddress);
|
||||
if(status != STATUS_SUCCESS)
|
||||
{
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Buffer readback verifier failed");
|
||||
status = buffRdbkVerify(Adapter, mappedbuffer, u32FirmwareLength, u32StartingAddress);
|
||||
if (status != STATUS_SUCCESS) {
|
||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Buffer readback verifier failed");
|
||||
goto error;
|
||||
}
|
||||
error:
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
@ -139,8 +139,7 @@ static void ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter)
|
||||
BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1C2, 4, TRUE);
|
||||
}
|
||||
|
||||
static int
|
||||
usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
{
|
||||
struct usb_device *udev = interface_to_usbdev(intf);
|
||||
int retval;
|
||||
@ -281,8 +280,9 @@ static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter)
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < MAXIMUM_USB_TCB; i++) {
|
||||
if ((psIntfAdapter->asUsbTcb[i].urb =
|
||||
usb_alloc_urb(0, GFP_KERNEL)) == NULL) {
|
||||
psIntfAdapter->asUsbTcb[i].urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
|
||||
if (psIntfAdapter->asUsbTcb[i].urb == NULL) {
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
|
||||
"Can't allocate Tx urb for index %d\n", i);
|
||||
return -ENOMEM;
|
||||
@ -290,14 +290,17 @@ static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter)
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXIMUM_USB_RCB; i++) {
|
||||
if ((psIntfAdapter->asUsbRcb[i].urb =
|
||||
usb_alloc_urb(0, GFP_KERNEL)) == NULL) {
|
||||
psIntfAdapter->asUsbRcb[i].urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
|
||||
if (psIntfAdapter->asUsbRcb[i].urb == NULL) {
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
|
||||
"Can't allocate Rx urb for index %d\n", i);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if ((psIntfAdapter->asUsbRcb[i].urb->transfer_buffer =
|
||||
kmalloc(MAX_DATA_BUFFER_SIZE, GFP_KERNEL)) == NULL) {
|
||||
|
||||
psIntfAdapter->asUsbRcb[i].urb->transfer_buffer = kmalloc(MAX_DATA_BUFFER_SIZE, GFP_KERNEL);
|
||||
|
||||
if (psIntfAdapter->asUsbRcb[i].urb->transfer_buffer == NULL) {
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
|
||||
"Can't allocate Rx buffer for index %d\n", i);
|
||||
return -ENOMEM;
|
||||
@ -389,32 +392,32 @@ static inline int bcm_usb_endpoint_xfer_isoc(const struct usb_endpoint_descripto
|
||||
|
||||
static inline int bcm_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd)
|
||||
{
|
||||
return (bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_in(epd));
|
||||
return bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_in(epd);
|
||||
}
|
||||
|
||||
static inline int bcm_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd)
|
||||
{
|
||||
return (bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_out(epd));
|
||||
return bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_out(epd);
|
||||
}
|
||||
|
||||
static inline int bcm_usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd)
|
||||
{
|
||||
return (bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_in(epd));
|
||||
return bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_in(epd);
|
||||
}
|
||||
|
||||
static inline int bcm_usb_endpoint_is_int_out(const struct usb_endpoint_descriptor *epd)
|
||||
{
|
||||
return (bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_out(epd));
|
||||
return bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_out(epd);
|
||||
}
|
||||
|
||||
static inline int bcm_usb_endpoint_is_isoc_in(const struct usb_endpoint_descriptor *epd)
|
||||
{
|
||||
return (bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_in(epd));
|
||||
return bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_in(epd);
|
||||
}
|
||||
|
||||
static inline int bcm_usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor *epd)
|
||||
{
|
||||
return (bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_out(epd));
|
||||
return bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_out(epd);
|
||||
}
|
||||
|
||||
static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter)
|
||||
@ -462,7 +465,7 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter)
|
||||
if (bBcm16 == TRUE) {
|
||||
/* selecting alternate setting one as a default setting for High Speed modem. */
|
||||
if (psIntfAdapter->bHighSpeedDevice)
|
||||
retval= usb_set_interface(psIntfAdapter->udev, DEFAULT_SETTING_0, ALTERNATE_SETTING_1);
|
||||
retval = usb_set_interface(psIntfAdapter->udev, DEFAULT_SETTING_0, ALTERNATE_SETTING_1);
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
|
||||
"BCM16 is applicable on this dongle\n");
|
||||
if (retval || (psIntfAdapter->bHighSpeedDevice == FALSE)) {
|
||||
@ -497,7 +500,7 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter)
|
||||
if ((psIntfAdapter->bHighSpeedDevice == FALSE) && bcm_usb_endpoint_is_bulk_out(endpoint)) {
|
||||
/* Once BULK is selected in FS mode. Revert it back to INT. Else USB_IF will fail. */
|
||||
UINT _uiData = ntohl(EP2_CFG_INT);
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
|
||||
"Reverting Bulk to INT as it is in Full Speed mode.\n");
|
||||
BeceemEEPROMBulkWrite(psIntfAdapter->psAdapter, (PUCHAR)&_uiData, 0x136, 4, TRUE);
|
||||
}
|
||||
@ -579,7 +582,7 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter)
|
||||
psIntfAdapter->sIntrOut.int_out_size = buffer_size;
|
||||
psIntfAdapter->sIntrOut.int_out_endpointAddr = endpoint->bEndpointAddress;
|
||||
psIntfAdapter->sIntrOut.int_out_interval = endpoint->bInterval;
|
||||
psIntfAdapter->sIntrOut.int_out_buffer= kmalloc(buffer_size, GFP_KERNEL);
|
||||
psIntfAdapter->sIntrOut.int_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
|
||||
if (!psIntfAdapter->sIntrOut.int_out_buffer) {
|
||||
dev_err(&psIntfAdapter->udev->dev,
|
||||
"could not allocate interrupt_out_buffer\n");
|
||||
@ -641,8 +644,8 @@ static int InterfaceSuspend(struct usb_interface *intf, pm_message_t message)
|
||||
static int InterfaceResume(struct usb_interface *intf)
|
||||
{
|
||||
PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf);
|
||||
mdelay(100);
|
||||
|
||||
mdelay(100);
|
||||
psIntfAdapter->bSuspended = FALSE;
|
||||
|
||||
StartInterruptUrb(psIntfAdapter);
|
||||
|
@ -1,246 +1,219 @@
|
||||
#include "headers.h"
|
||||
|
||||
INT
|
||||
InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
|
||||
UINT addr,
|
||||
PVOID buff,
|
||||
INT len)
|
||||
INT InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
|
||||
UINT addr,
|
||||
PVOID buff,
|
||||
INT len)
|
||||
{
|
||||
int retval = 0;
|
||||
USHORT usRetries = 0 ;
|
||||
if(psIntfAdapter == NULL )
|
||||
{
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Interface Adapter is NULL");
|
||||
return -EINVAL ;
|
||||
}
|
||||
USHORT usRetries = 0;
|
||||
|
||||
if(psIntfAdapter->psAdapter->device_removed == TRUE)
|
||||
{
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Device got removed");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB))
|
||||
{
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL,"Currently Xaction is not allowed on the bus");
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if(psIntfAdapter->bSuspended ==TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE)
|
||||
{
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL,"Bus is in suspended states hence RDM not allowed..");
|
||||
return -EACCES;
|
||||
}
|
||||
psIntfAdapter->psAdapter->DeviceAccess = TRUE ;
|
||||
do {
|
||||
retval = usb_control_msg(psIntfAdapter->udev,
|
||||
usb_rcvctrlpipe(psIntfAdapter->udev,0),
|
||||
0x02,
|
||||
0xC2,
|
||||
(addr & 0xFFFF),
|
||||
((addr >> 16) & 0xFFFF),
|
||||
buff,
|
||||
len,
|
||||
5000);
|
||||
|
||||
usRetries++ ;
|
||||
if(-ENODEV == retval)
|
||||
{
|
||||
psIntfAdapter->psAdapter->device_removed =TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
}while((retval < 0) && (usRetries < MAX_RDM_WRM_RETIRES ) );
|
||||
|
||||
if(retval < 0)
|
||||
{
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM failed status :%d, retires :%d", retval,usRetries);
|
||||
psIntfAdapter->psAdapter->DeviceAccess = FALSE ;
|
||||
return retval;
|
||||
}
|
||||
else
|
||||
{
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM sent %d", retval);
|
||||
psIntfAdapter->psAdapter->DeviceAccess = FALSE ;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
INT
|
||||
InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter,
|
||||
UINT addr,
|
||||
PVOID buff,
|
||||
INT len)
|
||||
{
|
||||
int retval = 0;
|
||||
USHORT usRetries = 0 ;
|
||||
|
||||
if(psIntfAdapter == NULL )
|
||||
{
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL");
|
||||
if (psIntfAdapter == NULL) {
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
if(psIntfAdapter->psAdapter->device_removed == TRUE)
|
||||
{
|
||||
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Device got removed");
|
||||
if (psIntfAdapter->psAdapter->device_removed == TRUE) {
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Device got removed");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB))
|
||||
{
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL,"Currently Xaction is not allowed on the bus...");
|
||||
if ((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB)) {
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "Currently Xaction is not allowed on the bus");
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if(psIntfAdapter->bSuspended ==TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE)
|
||||
{
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL,"Bus is in suspended states hence RDM not allowed..");
|
||||
if (psIntfAdapter->bSuspended == TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE) {
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "Bus is in suspended states hence RDM not allowed..");
|
||||
return -EACCES;
|
||||
}
|
||||
psIntfAdapter->psAdapter->DeviceAccess = TRUE ;
|
||||
do{
|
||||
psIntfAdapter->psAdapter->DeviceAccess = TRUE;
|
||||
|
||||
do {
|
||||
retval = usb_control_msg(psIntfAdapter->udev,
|
||||
usb_sndctrlpipe(psIntfAdapter->udev,0),
|
||||
0x01,
|
||||
0x42,
|
||||
(addr & 0xFFFF),
|
||||
((addr >> 16) & 0xFFFF),
|
||||
buff,
|
||||
len,
|
||||
5000);
|
||||
usb_rcvctrlpipe(psIntfAdapter->udev, 0),
|
||||
0x02,
|
||||
0xC2,
|
||||
(addr & 0xFFFF),
|
||||
((addr >> 16) & 0xFFFF),
|
||||
buff,
|
||||
len,
|
||||
5000);
|
||||
|
||||
usRetries++ ;
|
||||
if(-ENODEV == retval)
|
||||
{
|
||||
psIntfAdapter->psAdapter->device_removed = TRUE ;
|
||||
usRetries++;
|
||||
if (-ENODEV == retval) {
|
||||
psIntfAdapter->psAdapter->device_removed = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
}while((retval < 0) && ( usRetries < MAX_RDM_WRM_RETIRES));
|
||||
} while ((retval < 0) && (usRetries < MAX_RDM_WRM_RETIRES));
|
||||
|
||||
if(retval < 0)
|
||||
{
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM failed status :%d, retires :%d", retval, usRetries);
|
||||
psIntfAdapter->psAdapter->DeviceAccess = FALSE ;
|
||||
if (retval < 0) {
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM failed status :%d, retires :%d", retval, usRetries);
|
||||
psIntfAdapter->psAdapter->DeviceAccess = FALSE;
|
||||
return retval;
|
||||
}
|
||||
else
|
||||
{
|
||||
psIntfAdapter->psAdapter->DeviceAccess = FALSE ;
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM sent %d", retval);
|
||||
} else {
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM sent %d", retval);
|
||||
psIntfAdapter->psAdapter->DeviceAccess = FALSE;
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
INT
|
||||
BcmRDM(PVOID arg,
|
||||
UINT addr,
|
||||
PVOID buff,
|
||||
INT len)
|
||||
INT InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter,
|
||||
UINT addr,
|
||||
PVOID buff,
|
||||
INT len)
|
||||
{
|
||||
int retval = 0;
|
||||
USHORT usRetries = 0;
|
||||
|
||||
if (psIntfAdapter == NULL) {
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (psIntfAdapter->psAdapter->device_removed == TRUE) {
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Device got removed");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if ((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB)) {
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "Currently Xaction is not allowed on the bus...");
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (psIntfAdapter->bSuspended == TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE) {
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "Bus is in suspended states hence RDM not allowed..");
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
psIntfAdapter->psAdapter->DeviceAccess = TRUE;
|
||||
|
||||
do {
|
||||
retval = usb_control_msg(psIntfAdapter->udev,
|
||||
usb_sndctrlpipe(psIntfAdapter->udev, 0),
|
||||
0x01,
|
||||
0x42,
|
||||
(addr & 0xFFFF),
|
||||
((addr >> 16) & 0xFFFF),
|
||||
buff,
|
||||
len,
|
||||
5000);
|
||||
|
||||
usRetries++;
|
||||
if (-ENODEV == retval) {
|
||||
psIntfAdapter->psAdapter->device_removed = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
} while ((retval < 0) && (usRetries < MAX_RDM_WRM_RETIRES));
|
||||
|
||||
if (retval < 0) {
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM failed status :%d, retires :%d", retval, usRetries);
|
||||
psIntfAdapter->psAdapter->DeviceAccess = FALSE;
|
||||
return retval;
|
||||
} else {
|
||||
psIntfAdapter->psAdapter->DeviceAccess = FALSE;
|
||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM sent %d", retval);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
INT BcmRDM(PVOID arg,
|
||||
UINT addr,
|
||||
PVOID buff,
|
||||
INT len)
|
||||
{
|
||||
return InterfaceRDM((PS_INTERFACE_ADAPTER)arg, addr, buff, len);
|
||||
}
|
||||
|
||||
INT
|
||||
BcmWRM(PVOID arg,
|
||||
UINT addr,
|
||||
PVOID buff,
|
||||
INT len)
|
||||
INT BcmWRM(PVOID arg,
|
||||
UINT addr,
|
||||
PVOID buff,
|
||||
INT len)
|
||||
{
|
||||
return InterfaceWRM((PS_INTERFACE_ADAPTER)arg, addr, buff, len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
INT Bcm_clear_halt_of_endpoints(PMINI_ADAPTER Adapter)
|
||||
{
|
||||
PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter);
|
||||
INT status = STATUS_SUCCESS ;
|
||||
INT status = STATUS_SUCCESS;
|
||||
|
||||
/*
|
||||
usb_clear_halt - tells device to clear endpoint halt/stall condition
|
||||
@dev: device whose endpoint is halted
|
||||
@pipe: endpoint "pipe" being cleared
|
||||
@ Context: !in_interrupt ()
|
||||
* usb_clear_halt - tells device to clear endpoint halt/stall condition
|
||||
* @dev: device whose endpoint is halted
|
||||
* @pipe: endpoint "pipe" being cleared
|
||||
* @ Context: !in_interrupt ()
|
||||
*
|
||||
* usb_clear_halt is the synchrnous call and returns 0 on success else returns with error code.
|
||||
* This is used to clear halt conditions for bulk and interrupt endpoints only.
|
||||
* Control and isochronous endpoints never halts.
|
||||
*
|
||||
* Any URBs queued for such an endpoint should normally be unlinked by the driver
|
||||
* before clearing the halt condition.
|
||||
*
|
||||
*/
|
||||
|
||||
usb_clear_halt is the synchrnous call and returns 0 on success else returns with error code.
|
||||
This is used to clear halt conditions for bulk and interrupt endpoints only.
|
||||
Control and isochronous endpoints never halts.
|
||||
|
||||
Any URBs queued for such an endpoint should normally be unlinked by the driver
|
||||
before clearing the halt condition.
|
||||
|
||||
*/
|
||||
|
||||
//Killing all the submitted urbs to different end points.
|
||||
/* Killing all the submitted urbs to different end points. */
|
||||
Bcm_kill_all_URBs(psIntfAdapter);
|
||||
|
||||
/* clear the halted/stalled state for every end point */
|
||||
status = usb_clear_halt(psIntfAdapter->udev, psIntfAdapter->sIntrIn.int_in_pipe);
|
||||
if (status != STATUS_SUCCESS)
|
||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Interrupt IN end point. :%d ", status);
|
||||
|
||||
//clear the halted/stalled state for every end point
|
||||
status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sIntrIn.int_in_pipe);
|
||||
if(status != STATUS_SUCCESS)
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Interrupt IN end point. :%d ", status);
|
||||
status = usb_clear_halt(psIntfAdapter->udev, psIntfAdapter->sBulkIn.bulk_in_pipe);
|
||||
if (status != STATUS_SUCCESS)
|
||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk IN end point. :%d ", status);
|
||||
|
||||
status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sBulkIn.bulk_in_pipe);
|
||||
if(status != STATUS_SUCCESS)
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk IN end point. :%d ", status);
|
||||
status = usb_clear_halt(psIntfAdapter->udev, psIntfAdapter->sBulkOut.bulk_out_pipe);
|
||||
if (status != STATUS_SUCCESS)
|
||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk OUT end point. :%d ", status);
|
||||
|
||||
status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sBulkOut.bulk_out_pipe);
|
||||
if(status != STATUS_SUCCESS)
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk OUT end point. :%d ", status);
|
||||
|
||||
return status ;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter)
|
||||
{
|
||||
struct urb *tempUrb = NULL;
|
||||
UINT i;
|
||||
|
||||
/**
|
||||
* usb_kill_urb - cancel a transfer request and wait for it to finish
|
||||
* @urb: pointer to URB describing a previously submitted request,
|
||||
* returns nothing as it is void returned API.
|
||||
*
|
||||
* This routine cancels an in-progress request. It is guaranteed that
|
||||
* upon return all completion handlers will have finished and the URB
|
||||
* will be totally idle and available for reuse
|
||||
|
||||
* This routine may not be used in an interrupt context (such as a bottom
|
||||
* half or a completion handler), or when holding a spinlock, or in other
|
||||
* situations where the caller can't schedule().
|
||||
*
|
||||
**/
|
||||
/*
|
||||
* usb_kill_urb - cancel a transfer request and wait for it to finish
|
||||
* @urb: pointer to URB describing a previously submitted request,
|
||||
* returns nothing as it is void returned API.
|
||||
*
|
||||
* This routine cancels an in-progress request. It is guaranteed that
|
||||
* upon return all completion handlers will have finished and the URB
|
||||
* will be totally idle and available for reuse
|
||||
*
|
||||
* This routine may not be used in an interrupt context (such as a bottom
|
||||
* half or a completion handler), or when holding a spinlock, or in other
|
||||
* situations where the caller can't schedule().
|
||||
*
|
||||
*/
|
||||
|
||||
/* Cancel submitted Interrupt-URB's */
|
||||
if(psIntfAdapter->psInterruptUrb != NULL)
|
||||
{
|
||||
if(psIntfAdapter->psInterruptUrb->status == -EINPROGRESS)
|
||||
usb_kill_urb(psIntfAdapter->psInterruptUrb);
|
||||
if (psIntfAdapter->psInterruptUrb != NULL) {
|
||||
if (psIntfAdapter->psInterruptUrb->status == -EINPROGRESS)
|
||||
usb_kill_urb(psIntfAdapter->psInterruptUrb);
|
||||
}
|
||||
|
||||
/* Cancel All submitted TX URB's */
|
||||
for(i = 0; i < MAXIMUM_USB_TCB; i++)
|
||||
{
|
||||
for (i = 0; i < MAXIMUM_USB_TCB; i++) {
|
||||
tempUrb = psIntfAdapter->asUsbTcb[i].urb;
|
||||
if(tempUrb)
|
||||
{
|
||||
if(tempUrb->status == -EINPROGRESS)
|
||||
if (tempUrb) {
|
||||
if (tempUrb->status == -EINPROGRESS)
|
||||
usb_kill_urb(tempUrb);
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < MAXIMUM_USB_RCB; i++)
|
||||
{
|
||||
for (i = 0; i < MAXIMUM_USB_RCB; i++) {
|
||||
tempUrb = psIntfAdapter->asUsbRcb[i].urb;
|
||||
if(tempUrb)
|
||||
{
|
||||
if(tempUrb->status == -EINPROGRESS)
|
||||
usb_kill_urb(tempUrb);
|
||||
if (tempUrb) {
|
||||
if (tempUrb->status == -EINPROGRESS)
|
||||
usb_kill_urb(tempUrb);
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,13 +226,12 @@ VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter)
|
||||
|
||||
VOID putUsbSuspend(struct work_struct *work)
|
||||
{
|
||||
PS_INTERFACE_ADAPTER psIntfAdapter = NULL ;
|
||||
struct usb_interface *intf = NULL ;
|
||||
psIntfAdapter = container_of(work, S_INTERFACE_ADAPTER,usbSuspendWork);
|
||||
intf=psIntfAdapter->interface ;
|
||||
PS_INTERFACE_ADAPTER psIntfAdapter = NULL;
|
||||
struct usb_interface *intf = NULL;
|
||||
psIntfAdapter = container_of(work, S_INTERFACE_ADAPTER, usbSuspendWork);
|
||||
intf = psIntfAdapter->interface;
|
||||
|
||||
if(psIntfAdapter->bSuspended == FALSE)
|
||||
if (psIntfAdapter->bSuspended == FALSE)
|
||||
usb_autopm_put_interface(intf);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,17 +1,17 @@
|
||||
/*************************************
|
||||
* Macros.h
|
||||
* Macros.h
|
||||
**************************************/
|
||||
#ifndef __MACROS_H__
|
||||
#ifndef __MACROS_H__
|
||||
#define __MACROS_H__
|
||||
|
||||
#define TX_TIMER_PERIOD 10 //10 msec
|
||||
#define TX_TIMER_PERIOD 10 /*10 msec*/
|
||||
#define MAX_CLASSIFIERS 100
|
||||
//#define MAX_CLASSIFIERS_PER_SF 20
|
||||
/* #define MAX_CLASSIFIERS_PER_SF 20 */
|
||||
#define MAX_TARGET_DSX_BUFFERS 24
|
||||
|
||||
#define MAX_CNTRL_PKTS 100
|
||||
#define MAX_DATA_PKTS 200
|
||||
#define MAX_ETH_SIZE 1536
|
||||
#define MAX_CNTRL_PKTS 100
|
||||
#define MAX_DATA_PKTS 200
|
||||
#define MAX_ETH_SIZE 1536
|
||||
#define MAX_CNTL_PKT_SIZE 2048
|
||||
|
||||
#define MTU_SIZE 1400
|
||||
@ -20,102 +20,102 @@
|
||||
#define MAC_ADDR_REGISTER 0xbf60d000
|
||||
|
||||
|
||||
///////////Quality of Service///////////////////////////
|
||||
#define NO_OF_QUEUES 17
|
||||
#define HiPriority NO_OF_QUEUES-1
|
||||
#define LowPriority 0
|
||||
#define BE 2
|
||||
#define rtPS 4
|
||||
#define ERTPS 5
|
||||
#define UGS 6
|
||||
/* Quality of Service */
|
||||
#define NO_OF_QUEUES 17
|
||||
#define HiPriority (NO_OF_QUEUES-1)
|
||||
#define LowPriority 0
|
||||
#define BE 2
|
||||
#define rtPS 4
|
||||
#define ERTPS 5
|
||||
#define UGS 6
|
||||
|
||||
#define BE_BUCKET_SIZE 1024*1024*100 //32kb
|
||||
#define rtPS_BUCKET_SIZE 1024*1024*100 //8kb
|
||||
#define MAX_ALLOWED_RATE 1024*1024*100
|
||||
#define TX_PACKET_THRESHOLD 10
|
||||
#define XSECONDS 1*HZ
|
||||
#define DSC_ACTIVATE_REQUEST 248
|
||||
#define QUEUE_DEPTH_OFFSET 0x1fc01000
|
||||
#define MAX_DEVICE_DESC_SIZE 2040
|
||||
#define MAX_CTRL_QUEUE_LEN 100
|
||||
#define MAX_APP_QUEUE_LEN 200
|
||||
#define MAX_LATENCY_ALLOWED 0xFFFFFFFF
|
||||
#define DEFAULT_UG_INTERVAL 250
|
||||
#define DEFAULT_UGI_FACTOR 4
|
||||
#define BE_BUCKET_SIZE (1024*1024*100) /* 32kb */
|
||||
#define rtPS_BUCKET_SIZE (1024*1024*100) /* 8kb */
|
||||
#define MAX_ALLOWED_RATE (1024*1024*100)
|
||||
#define TX_PACKET_THRESHOLD 10
|
||||
#define XSECONDS (1*HZ)
|
||||
#define DSC_ACTIVATE_REQUEST 248
|
||||
#define QUEUE_DEPTH_OFFSET 0x1fc01000
|
||||
#define MAX_DEVICE_DESC_SIZE 2040
|
||||
#define MAX_CTRL_QUEUE_LEN 100
|
||||
#define MAX_APP_QUEUE_LEN 200
|
||||
#define MAX_LATENCY_ALLOWED 0xFFFFFFFF
|
||||
#define DEFAULT_UG_INTERVAL 250
|
||||
#define DEFAULT_UGI_FACTOR 4
|
||||
|
||||
#define DEFAULT_PERSFCOUNT 60
|
||||
#define MAX_CONNECTIONS 10
|
||||
#define MAX_CLASS_NAME_LENGTH 32
|
||||
#define DEFAULT_PERSFCOUNT 60
|
||||
#define MAX_CONNECTIONS 10
|
||||
#define MAX_CLASS_NAME_LENGTH 32
|
||||
|
||||
#define ETH_LENGTH_OF_ADDRESS 6
|
||||
#define MAX_MULTICAST_ADDRESSES 32
|
||||
#define IP_LENGTH_OF_ADDRESS 4
|
||||
#define ETH_LENGTH_OF_ADDRESS 6
|
||||
#define MAX_MULTICAST_ADDRESSES 32
|
||||
#define IP_LENGTH_OF_ADDRESS 4
|
||||
|
||||
#define IP_PACKET_ONLY_MODE 0
|
||||
#define ETH_PACKET_TUNNELING_MODE 1
|
||||
#define IP_PACKET_ONLY_MODE 0
|
||||
#define ETH_PACKET_TUNNELING_MODE 1
|
||||
|
||||
////////////Link Request//////////////
|
||||
#define SET_MAC_ADDRESS_REQUEST 0
|
||||
#define SYNC_UP_REQUEST 1
|
||||
#define SYNCED_UP 2
|
||||
#define LINK_UP_REQUEST 3
|
||||
#define LINK_CONNECTED 4
|
||||
#define SYNC_UP_NOTIFICATION 2
|
||||
#define LINK_UP_NOTIFICATION 4
|
||||
/* Link Request */
|
||||
#define SET_MAC_ADDRESS_REQUEST 0
|
||||
#define SYNC_UP_REQUEST 1
|
||||
#define SYNCED_UP 2
|
||||
#define LINK_UP_REQUEST 3
|
||||
#define LINK_CONNECTED 4
|
||||
#define SYNC_UP_NOTIFICATION 2
|
||||
#define LINK_UP_NOTIFICATION 4
|
||||
|
||||
|
||||
#define LINK_NET_ENTRY 0x0002
|
||||
#define HMC_STATUS 0x0004
|
||||
#define HMC_STATUS 0x0004
|
||||
#define LINK_UP_CONTROL_REQ 0x83
|
||||
|
||||
#define STATS_POINTER_REQ_STATUS 0x86
|
||||
#define NETWORK_ENTRY_REQ_PAYLOAD 198
|
||||
#define LINK_DOWN_REQ_PAYLOAD 226
|
||||
#define LINK_DOWN_REQ_PAYLOAD 226
|
||||
#define SYNC_UP_REQ_PAYLOAD 228
|
||||
#define STATISTICS_POINTER_REQ 237
|
||||
#define STATISTICS_POINTER_REQ 237
|
||||
#define LINK_UP_REQ_PAYLOAD 245
|
||||
#define LINK_UP_ACK 246
|
||||
|
||||
#define STATS_MSG_SIZE 4
|
||||
#define INDEX_TO_DATA 4
|
||||
|
||||
#define GO_TO_IDLE_MODE_PAYLOAD 210
|
||||
#define COME_UP_FROM_IDLE_MODE_PAYLOAD 211
|
||||
#define IDLE_MODE_SF_UPDATE_MSG 187
|
||||
#define GO_TO_IDLE_MODE_PAYLOAD 210
|
||||
#define COME_UP_FROM_IDLE_MODE_PAYLOAD 211
|
||||
#define IDLE_MODE_SF_UPDATE_MSG 187
|
||||
|
||||
#define SKB_RESERVE_ETHERNET_HEADER 16
|
||||
#define SKB_RESERVE_PHS_BYTES 32
|
||||
#define SKB_RESERVE_ETHERNET_HEADER 16
|
||||
#define SKB_RESERVE_PHS_BYTES 32
|
||||
|
||||
#define IP_PACKET_ONLY_MODE 0
|
||||
#define ETH_PACKET_TUNNELING_MODE 1
|
||||
#define IP_PACKET_ONLY_MODE 0
|
||||
#define ETH_PACKET_TUNNELING_MODE 1
|
||||
|
||||
#define ETH_CS_802_3 1
|
||||
#define ETH_CS_802_1Q_VLAN 3
|
||||
#define IPV4_CS 1
|
||||
#define IPV6_CS 2
|
||||
#define ETH_CS_MASK 0x3f
|
||||
#define ETH_CS_802_3 1
|
||||
#define ETH_CS_802_1Q_VLAN 3
|
||||
#define IPV4_CS 1
|
||||
#define IPV6_CS 2
|
||||
#define ETH_CS_MASK 0x3f
|
||||
|
||||
/** \brief Validity bit maps for TLVs in packet classification rule */
|
||||
|
||||
#define PKT_CLASSIFICATION_USER_PRIORITY_VALID 0
|
||||
#define PKT_CLASSIFICATION_VLANID_VALID 1
|
||||
#define PKT_CLASSIFICATION_USER_PRIORITY_VALID 0
|
||||
#define PKT_CLASSIFICATION_VLANID_VALID 1
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(_a, _b) ((_a) < (_b)? (_a): (_b))
|
||||
#define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b))
|
||||
#endif
|
||||
|
||||
|
||||
/*Leader related terms */
|
||||
#define LEADER_STATUS 0x00
|
||||
#define LEADER_STATUS_TCP_ACK 0x1
|
||||
#define LEADER_SIZE sizeof(LEADER)
|
||||
#define MAC_ADDR_REQ_SIZE sizeof(PACKETTOSEND)
|
||||
#define SS_INFO_REQ_SIZE sizeof(PACKETTOSEND)
|
||||
#define CM_REQUEST_SIZE LEADER_SIZE + sizeof(stLocalSFChangeRequest)
|
||||
#define IDLE_REQ_SIZE sizeof(PACKETTOSEND)
|
||||
#define LEADER_STATUS 0x00
|
||||
#define LEADER_STATUS_TCP_ACK 0x1
|
||||
#define LEADER_SIZE sizeof(LEADER)
|
||||
#define MAC_ADDR_REQ_SIZE sizeof(PACKETTOSEND)
|
||||
#define SS_INFO_REQ_SIZE sizeof(PACKETTOSEND)
|
||||
#define CM_REQUEST_SIZE (LEADER_SIZE + sizeof(stLocalSFChangeRequest))
|
||||
#define IDLE_REQ_SIZE sizeof(PACKETTOSEND)
|
||||
|
||||
|
||||
#define MAX_TRANSFER_CTRL_BYTE_USB 2 * 1024
|
||||
#define MAX_TRANSFER_CTRL_BYTE_USB (2*1024)
|
||||
|
||||
#define GET_MAILBOX1_REG_REQUEST 0x87
|
||||
#define GET_MAILBOX1_REG_RESPONSE 0x67
|
||||
@ -124,40 +124,40 @@
|
||||
#define TRANSMIT_NETWORK_DATA 0x00
|
||||
#define RECEIVED_NETWORK_DATA 0x20
|
||||
|
||||
#define CM_RESPONSES 0xA0
|
||||
#define STATUS_RSP 0xA1
|
||||
#define LINK_CONTROL_RESP 0xA2
|
||||
#define IDLE_MODE_STATUS 0xA3
|
||||
#define STATS_POINTER_RESP 0xA6
|
||||
#define MGMT_MSG_INFO_SW_STATUS 0xA7
|
||||
#define AUTH_SS_HOST_MSG 0xA8
|
||||
#define CM_RESPONSES 0xA0
|
||||
#define STATUS_RSP 0xA1
|
||||
#define LINK_CONTROL_RESP 0xA2
|
||||
#define IDLE_MODE_STATUS 0xA3
|
||||
#define STATS_POINTER_RESP 0xA6
|
||||
#define MGMT_MSG_INFO_SW_STATUS 0xA7
|
||||
#define AUTH_SS_HOST_MSG 0xA8
|
||||
|
||||
#define CM_DSA_ACK_PAYLOAD 247
|
||||
#define CM_DSC_ACK_PAYLOAD 248
|
||||
#define CM_DSD_ACK_PAYLOAD 249
|
||||
#define CM_DSDEACTVATE 250
|
||||
#define TOTAL_MASKED_ADDRESS_IN_BYTES 32
|
||||
#define CM_DSA_ACK_PAYLOAD 247
|
||||
#define CM_DSC_ACK_PAYLOAD 248
|
||||
#define CM_DSD_ACK_PAYLOAD 249
|
||||
#define CM_DSDEACTVATE 250
|
||||
#define TOTAL_MASKED_ADDRESS_IN_BYTES 32
|
||||
|
||||
#define MAC_REQ 0
|
||||
#define LINK_RESP 1
|
||||
#define RSSI_INDICATION 2
|
||||
#define MAC_REQ 0
|
||||
#define LINK_RESP 1
|
||||
#define RSSI_INDICATION 2
|
||||
|
||||
#define SS_INFO 4
|
||||
#define STATISTICS_INFO 5
|
||||
#define CM_INDICATION 6
|
||||
#define PARAM_RESP 7
|
||||
#define BUFFER_1K 1024
|
||||
#define BUFFER_2K BUFFER_1K*2
|
||||
#define BUFFER_4K BUFFER_2K*2
|
||||
#define BUFFER_8K BUFFER_4K*2
|
||||
#define BUFFER_16K BUFFER_8K*2
|
||||
#define DOWNLINK_DIR 0
|
||||
#define UPLINK_DIR 1
|
||||
#define SS_INFO 4
|
||||
#define STATISTICS_INFO 5
|
||||
#define CM_INDICATION 6
|
||||
#define PARAM_RESP 7
|
||||
#define BUFFER_1K 1024
|
||||
#define BUFFER_2K (BUFFER_1K*2)
|
||||
#define BUFFER_4K (BUFFER_2K*2)
|
||||
#define BUFFER_8K (BUFFER_4K*2)
|
||||
#define BUFFER_16K (BUFFER_8K*2)
|
||||
#define DOWNLINK_DIR 0
|
||||
#define UPLINK_DIR 1
|
||||
|
||||
#define BCM_SIGNATURE "BECEEM"
|
||||
#define BCM_SIGNATURE "BECEEM"
|
||||
|
||||
|
||||
#define GPIO_OUTPUT_REGISTER 0x0F00003C
|
||||
#define GPIO_OUTPUT_REGISTER 0x0F00003C
|
||||
#define BCM_GPIO_OUTPUT_SET_REG 0x0F000040
|
||||
#define BCM_GPIO_OUTPUT_CLR_REG 0x0F000044
|
||||
#define GPIO_MODE_REGISTER 0x0F000034
|
||||
@ -165,44 +165,43 @@
|
||||
|
||||
|
||||
typedef struct _LINK_STATE {
|
||||
UCHAR ucLinkStatus;
|
||||
UCHAR bIdleMode;
|
||||
UCHAR bShutdownMode;
|
||||
}LINK_STATE, *PLINK_STATE;
|
||||
UCHAR ucLinkStatus;
|
||||
UCHAR bIdleMode;
|
||||
UCHAR bShutdownMode;
|
||||
} LINK_STATE, *PLINK_STATE;
|
||||
|
||||
|
||||
enum enLinkStatus {
|
||||
WAIT_FOR_SYNC = 1,
|
||||
PHY_SYNC_ACHIVED = 2,
|
||||
LINKUP_IN_PROGRESS = 3,
|
||||
LINKUP_DONE = 4,
|
||||
DREG_RECEIVED = 5,
|
||||
LINK_STATUS_RESET_RECEIVED = 6,
|
||||
PERIODIC_WAKE_UP_NOTIFICATION_FRM_FW = 7,
|
||||
LINK_SHUTDOWN_REQ_FROM_FIRMWARE = 8,
|
||||
COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW =9
|
||||
WAIT_FOR_SYNC = 1,
|
||||
PHY_SYNC_ACHIVED = 2,
|
||||
LINKUP_IN_PROGRESS = 3,
|
||||
LINKUP_DONE = 4,
|
||||
DREG_RECEIVED = 5,
|
||||
LINK_STATUS_RESET_RECEIVED = 6,
|
||||
PERIODIC_WAKE_UP_NOTIFICATION_FRM_FW = 7,
|
||||
LINK_SHUTDOWN_REQ_FROM_FIRMWARE = 8,
|
||||
COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW = 9
|
||||
};
|
||||
|
||||
typedef enum _E_PHS_DSC_ACTION
|
||||
{
|
||||
eAddPHSRule=0,
|
||||
typedef enum _E_PHS_DSC_ACTION {
|
||||
eAddPHSRule = 0,
|
||||
eSetPHSRule,
|
||||
eDeletePHSRule,
|
||||
eDeleteAllPHSRules
|
||||
}E_PHS_DSC_ACTION;
|
||||
} E_PHS_DSC_ACTION;
|
||||
|
||||
|
||||
#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ 0x89 // Host to Mac
|
||||
#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP 0xA9 // Mac to Host
|
||||
#define MASK_DISABLE_HEADER_SUPPRESSION 0x10 //0b000010000
|
||||
#define MINIMUM_PENDING_DESCRIPTORS 5
|
||||
#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ 0x89 /* Host to Mac */
|
||||
#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP 0xA9 /* Mac to Host */
|
||||
#define MASK_DISABLE_HEADER_SUPPRESSION 0x10 /* 0b000010000 */
|
||||
#define MINIMUM_PENDING_DESCRIPTORS 5
|
||||
|
||||
#define SHUTDOWN_HOSTINITIATED_REQUESTPAYLOAD 0xCC
|
||||
#define SHUTDOWN_ACK_FROM_DRIVER 0x1
|
||||
#define SHUTDOWN_NACK_FROM_DRIVER 0x2
|
||||
|
||||
#define LINK_SYNC_UP_SUBTYPE 0x0001
|
||||
#define LINK_SYNC_DOWN_SUBTYPE 0x0001
|
||||
#define LINK_SYNC_UP_SUBTYPE 0x0001
|
||||
#define LINK_SYNC_DOWN_SUBTYPE 0x0001
|
||||
|
||||
|
||||
|
||||
@ -226,9 +225,9 @@ typedef enum _E_PHS_DSC_ACTION
|
||||
|
||||
#define MAX_PENDING_CTRL_PACKET (MAX_CTRL_QUEUE_LEN-10)
|
||||
|
||||
#define WIMAX_MAX_MTU (MTU_SIZE + ETH_HLEN)
|
||||
#define WIMAX_MAX_MTU (MTU_SIZE + ETH_HLEN)
|
||||
#define AUTO_LINKUP_ENABLE 0x2
|
||||
#define AUTO_SYNC_DISABLE 0x1
|
||||
#define AUTO_SYNC_DISABLE 0x1
|
||||
#define AUTO_FIRM_DOWNLOAD 0x1
|
||||
#define SETTLE_DOWN_TIME 50
|
||||
|
||||
@ -242,9 +241,9 @@ typedef enum _E_PHS_DSC_ACTION
|
||||
#define TARGET_CAN_NOT_GO_TO_IDLE_MODE 3
|
||||
#define IDLE_MODE_PAYLOAD_LENGTH 8
|
||||
|
||||
#define IP_HEADER(Buffer) ((IPHeaderFormat*)(Buffer))
|
||||
#define IPV4 4
|
||||
#define IP_VERSION(byte) (((byte&0xF0)>>4))
|
||||
#define IP_HEADER(Buffer) ((IPHeaderFormat *)(Buffer))
|
||||
#define IPV4 4
|
||||
#define IP_VERSION(byte) (((byte&0xF0)>>4))
|
||||
|
||||
#define SET_MAC_ADDRESS 193
|
||||
#define SET_MAC_ADDRESS_RESPONSE 236
|
||||
@ -263,15 +262,15 @@ typedef enum _E_PHS_DSC_ACTION
|
||||
|
||||
#define INVALID_QUEUE_INDEX NO_OF_QUEUES
|
||||
|
||||
#define INVALID_PID (pid_t)-1
|
||||
#define DDR_80_MHZ 0
|
||||
#define DDR_100_MHZ 1
|
||||
#define DDR_120_MHZ 2 // Additional Frequency for T3LP
|
||||
#define DDR_133_MHZ 3
|
||||
#define DDR_140_MHZ 4 // Not Used (Reserved for future)
|
||||
#define DDR_160_MHZ 5 // Additional Frequency for T3LP
|
||||
#define DDR_180_MHZ 6 // Not Used (Reserved for future)
|
||||
#define DDR_200_MHZ 7 // Not Used (Reserved for future)
|
||||
#define INVALID_PID ((pid_t)-1)
|
||||
#define DDR_80_MHZ 0
|
||||
#define DDR_100_MHZ 1
|
||||
#define DDR_120_MHZ 2 /* Additional Frequency for T3LP */
|
||||
#define DDR_133_MHZ 3
|
||||
#define DDR_140_MHZ 4 /* Not Used (Reserved for future) */
|
||||
#define DDR_160_MHZ 5 /* Additional Frequency for T3LP */
|
||||
#define DDR_180_MHZ 6 /* Not Used (Reserved for future) */
|
||||
#define DDR_200_MHZ 7 /* Not Used (Reserved for future) */
|
||||
|
||||
#define MIPS_200_MHZ 0
|
||||
#define MIPS_160_MHZ 1
|
||||
@ -291,27 +290,27 @@ typedef enum _E_PHS_DSC_ACTION
|
||||
#define EEPROM_REJECT_REG_3 0x0f003008
|
||||
#define EEPROM_REJECT_REG_4 0x0f003020
|
||||
#define EEPROM_REJECT_MASK 0x0fffffff
|
||||
#define VSG_MODE 0x3
|
||||
#define VSG_MODE 0x3
|
||||
|
||||
/* Idle Mode Related Registers */
|
||||
#define DEBUG_INTERRUPT_GENERATOR_REGISTOR 0x0F00007C
|
||||
#define SW_ABORT_IDLEMODE_LOC 0x0FF01FFC
|
||||
#define SW_ABORT_IDLEMODE_LOC 0x0FF01FFC
|
||||
|
||||
#define SW_ABORT_IDLEMODE_PATTERN 0xd0ea1d1e
|
||||
#define DEVICE_INT_OUT_EP_REG0 0x0F011870
|
||||
#define DEVICE_INT_OUT_EP_REG1 0x0F011874
|
||||
#define SW_ABORT_IDLEMODE_PATTERN 0xd0ea1d1e
|
||||
#define DEVICE_INT_OUT_EP_REG0 0x0F011870
|
||||
#define DEVICE_INT_OUT_EP_REG1 0x0F011874
|
||||
|
||||
#define BIN_FILE "/lib/firmware/macxvi200.bin"
|
||||
#define CFG_FILE "/lib/firmware/macxvi.cfg"
|
||||
#define SF_MAX_ALLOWED_PACKETS_TO_BACKUP 128
|
||||
#define MIN_VAL(x,y) ((x)<(y)?(x):(y))
|
||||
#define MIN_VAL(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define MAC_ADDRESS_SIZE 6
|
||||
#define EEPROM_COMMAND_Q_REG 0x0F003018
|
||||
#define EEPROM_READ_DATA_Q_REG 0x0F003020
|
||||
#define CHIP_ID_REG 0x0F000000
|
||||
#define GPIO_MODE_REG 0x0F000034
|
||||
#define GPIO_OUTPUT_REG 0x0F00003C
|
||||
#define WIMAX_MAX_ALLOWED_RATE 1024*1024*50
|
||||
#define CHIP_ID_REG 0x0F000000
|
||||
#define GPIO_MODE_REG 0x0F000034
|
||||
#define GPIO_OUTPUT_REG 0x0F00003C
|
||||
#define WIMAX_MAX_ALLOWED_RATE (1024*1024*50)
|
||||
|
||||
#define T3 0xbece0300
|
||||
#define TARGET_SFID_TXDESC_MAP_LOC 0xBFFFF400
|
||||
@ -319,31 +318,29 @@ typedef enum _E_PHS_DSC_ACTION
|
||||
#define RWM_READ 0
|
||||
#define RWM_WRITE 1
|
||||
|
||||
#define T3LPB 0xbece3300
|
||||
#define BCS220_2 0xbece3311
|
||||
#define BCS220_2BC 0xBECE3310
|
||||
#define BCS250_BC 0xbece3301
|
||||
#define BCS220_3 0xbece3321
|
||||
#define T3LPB 0xbece3300
|
||||
#define BCS220_2 0xbece3311
|
||||
#define BCS220_2BC 0xBECE3310
|
||||
#define BCS250_BC 0xbece3301
|
||||
#define BCS220_3 0xbece3321
|
||||
|
||||
|
||||
#define HPM_CONFIG_LDO145 0x0F000D54
|
||||
#define HPM_CONFIG_MSW 0x0F000D58
|
||||
#define HPM_CONFIG_LDO145 0x0F000D54
|
||||
#define HPM_CONFIG_MSW 0x0F000D58
|
||||
|
||||
#define T3B 0xbece0310
|
||||
typedef enum eNVM_TYPE
|
||||
{
|
||||
typedef enum eNVM_TYPE {
|
||||
NVM_AUTODETECT = 0,
|
||||
NVM_EEPROM,
|
||||
NVM_FLASH,
|
||||
NVM_UNKNOWN
|
||||
}NVM_TYPE;
|
||||
} NVM_TYPE;
|
||||
|
||||
typedef enum ePMU_MODES
|
||||
{
|
||||
typedef enum ePMU_MODES {
|
||||
HYBRID_MODE_7C = 0,
|
||||
INTERNAL_MODE_6 = 1,
|
||||
HYBRID_MODE_6 = 2
|
||||
}PMU_MODE;
|
||||
} PMU_MODE;
|
||||
|
||||
#define MAX_RDM_WRM_RETIRES 1
|
||||
|
||||
@ -360,4 +357,4 @@ enum eAbortPattern {
|
||||
#define SKB_CB_LATENCY_OFFSET 1
|
||||
#define SKB_CB_TCPACK_OFFSET 2
|
||||
|
||||
#endif //__MACROS_H__
|
||||
#endif /* __MACROS_H__ */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -74,4 +74,6 @@
|
||||
#define DRV_VERSION VER_FILEVERSION_STR
|
||||
#define PFX DRV_NAME " "
|
||||
|
||||
extern struct class *bcm_class;
|
||||
|
||||
#endif
|
||||
|
@ -4013,7 +4013,8 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut)
|
||||
if(uiTotalDataToCopy < ISOLength)
|
||||
{
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature");
|
||||
return STATUS_FAILURE;
|
||||
Status = STATUS_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
|
||||
@ -4026,7 +4027,8 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut)
|
||||
if(uiTotalDataToCopy < ISOLength)
|
||||
{
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size");
|
||||
return STATUS_FAILURE;
|
||||
Status = STATUS_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
uiTotalDataToCopy = ISOLength;
|
||||
@ -4143,7 +4145,8 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut)
|
||||
if(uiTotalDataToCopy < ISOLength)
|
||||
{
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature");
|
||||
return STATUS_FAILURE;
|
||||
Status = STATUS_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
|
||||
@ -4156,7 +4159,8 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut)
|
||||
if(uiTotalDataToCopy < ISOLength)
|
||||
{
|
||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size");
|
||||
return STATUS_FAILURE;
|
||||
Status = STATUS_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
uiTotalDataToCopy = ISOLength;
|
||||
@ -4257,6 +4261,7 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut)
|
||||
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(Buff);
|
||||
|
||||
return Status;
|
||||
|
@ -1,40 +0,0 @@
|
||||
config BRCMUTIL
|
||||
tristate
|
||||
default n
|
||||
|
||||
config BRCMSMAC
|
||||
tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
|
||||
default n
|
||||
depends on PCI
|
||||
depends on WLAN && MAC80211
|
||||
depends on X86 || MIPS
|
||||
select BRCMUTIL
|
||||
select FW_LOADER
|
||||
select CRC_CCITT
|
||||
---help---
|
||||
This module adds support for PCIe wireless adapters based on Broadcom
|
||||
IEEE802.11n SoftMAC chipsets. If you choose to build a module, it'll
|
||||
be called brcmsmac.ko.
|
||||
|
||||
config BRCMFMAC
|
||||
tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver"
|
||||
default n
|
||||
depends on MMC
|
||||
depends on WLAN && CFG80211
|
||||
depends on X86 || MIPS
|
||||
select BRCMUTIL
|
||||
select FW_LOADER
|
||||
select WIRELESS_EXT
|
||||
select WEXT_PRIV
|
||||
---help---
|
||||
This module adds support for embedded wireless adapters based on
|
||||
Broadcom IEEE802.11n FullMAC chipsets. This driver uses the kernel's
|
||||
wireless extensions subsystem. If you choose to build a module,
|
||||
it'll be called brcmfmac.ko.
|
||||
|
||||
config BRCMDBG
|
||||
bool "Broadcom driver debug functions"
|
||||
default n
|
||||
depends on BRCMSMAC || BRCMFMAC
|
||||
---help---
|
||||
Selecting this enables additional code for debug purposes.
|
@ -1,24 +0,0 @@
|
||||
#
|
||||
# Makefile fragment for Broadcom 802.11n Networking Device Driver
|
||||
#
|
||||
# Copyright (c) 2010 Broadcom Corporation
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# common flags
|
||||
subdir-ccflags-y := -DBCMDMA32
|
||||
subdir-ccflags-$(CONFIG_BRCMDBG) += -DBCMDBG
|
||||
|
||||
obj-$(CONFIG_BRCMUTIL) += brcmutil/
|
||||
obj-$(CONFIG_BRCMFMAC) += brcmfmac/
|
||||
obj-$(CONFIG_BRCMSMAC) += brcmsmac/
|
@ -1 +0,0 @@
|
||||
refer to: http://linuxwireless.org/en/users/Drivers/brcm80211
|
@ -1,13 +0,0 @@
|
||||
To Do List for Broadcom Mac80211 driver before getting in mainline
|
||||
|
||||
Bugs
|
||||
====
|
||||
- none known at this moment
|
||||
|
||||
brcmfmac
|
||||
=====================
|
||||
- ASSERTS deprecated in mainline, replace by warning + error handling
|
||||
|
||||
brcm80211 info page
|
||||
=====================
|
||||
http://linuxwireless.org/en/users/Drivers/brcm80211
|
@ -1,39 +0,0 @@
|
||||
#
|
||||
# Makefile fragment for Broadcom 802.11n Networking Device Driver
|
||||
#
|
||||
# Copyright (c) 2010 Broadcom Corporation
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
ccflags-y := \
|
||||
-DBRCMF_FIRSTREAD=64 \
|
||||
-DBRCMF_SDALIGN=64 \
|
||||
-DMAX_HDR_READ=64
|
||||
|
||||
ccflags-$(CONFIG_BRCMDBG) += -DSHOW_EVENTS
|
||||
|
||||
ccflags-y += \
|
||||
-Idrivers/staging/brcm80211/brcmfmac \
|
||||
-Idrivers/staging/brcm80211/include
|
||||
|
||||
DHDOFILES = \
|
||||
wl_cfg80211.o \
|
||||
dhd_cdc.o \
|
||||
dhd_common.o \
|
||||
dhd_sdio.o \
|
||||
dhd_linux.o \
|
||||
bcmsdh.o \
|
||||
bcmsdh_sdmmc.o
|
||||
|
||||
obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
|
||||
brcmfmac-objs += $(DHDOFILES)
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _bcmchip_h_
|
||||
#define _bcmchip_h_
|
||||
|
||||
/* bcm4329 */
|
||||
/* SDIO device core, ID 0x829 */
|
||||
#define BCM4329_CORE_BUS_BASE 0x18011000
|
||||
/* internal memory core, ID 0x80e */
|
||||
#define BCM4329_CORE_SOCRAM_BASE 0x18003000
|
||||
/* ARM Cortex M3 core, ID 0x82a */
|
||||
#define BCM4329_CORE_ARM_BASE 0x18002000
|
||||
#define BCM4329_RAMSIZE 0x48000
|
||||
/* firmware name */
|
||||
#define BCM4329_FW_NAME "brcm/bcm4329-fullmac-4.bin"
|
||||
#define BCM4329_NV_NAME "brcm/bcm4329-fullmac-4.txt"
|
||||
|
||||
#endif /* _bcmchip_h_ */
|
@ -1,642 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
/* ****************** SDIO CARD Interface Functions **************************/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pci_ids.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/completion.h>
|
||||
|
||||
#include <defs.h>
|
||||
#include <brcm_hw_ids.h>
|
||||
#include <brcmu_utils.h>
|
||||
#include <brcmu_wifi.h>
|
||||
#include <soc.h>
|
||||
#include "dhd.h"
|
||||
#include "dhd_bus.h"
|
||||
#include "sdio_host.h"
|
||||
|
||||
#define SDIOH_API_ACCESS_RETRY_LIMIT 2
|
||||
|
||||
#define BRCMF_SD_ERROR_VAL 0x0001 /* Error */
|
||||
#define BRCMF_SD_INFO_VAL 0x0002 /* Info */
|
||||
|
||||
|
||||
#ifdef BCMDBG
|
||||
#define BRCMF_SD_ERROR(x) \
|
||||
do { \
|
||||
if ((brcmf_sdio_msglevel & BRCMF_SD_ERROR_VAL) && \
|
||||
net_ratelimit()) \
|
||||
printk x; \
|
||||
} while (0)
|
||||
#define BRCMF_SD_INFO(x) \
|
||||
do { \
|
||||
if ((brcmf_sdio_msglevel & BRCMF_SD_INFO_VAL) && \
|
||||
net_ratelimit()) \
|
||||
printk x; \
|
||||
} while (0)
|
||||
#else /* BCMDBG */
|
||||
#define BRCMF_SD_ERROR(x)
|
||||
#define BRCMF_SD_INFO(x)
|
||||
#endif /* BCMDBG */
|
||||
|
||||
/* debugging macros */
|
||||
#define SDLX_MSG(x)
|
||||
|
||||
#define SDIOH_CMD_TYPE_NORMAL 0 /* Normal command */
|
||||
#define SDIOH_CMD_TYPE_APPEND 1 /* Append command */
|
||||
#define SDIOH_CMD_TYPE_CUTTHRU 2 /* Cut-through command */
|
||||
|
||||
#define SDIOH_DATA_PIO 0 /* PIO mode */
|
||||
#define SDIOH_DATA_DMA 1 /* DMA mode */
|
||||
|
||||
struct brcmf_sdio_card {
|
||||
bool init_success; /* underlying driver successfully attached */
|
||||
void *sdioh; /* handler for sdioh */
|
||||
u32 vendevid; /* Target Vendor and Device ID on SD bus */
|
||||
bool regfail; /* Save status of last
|
||||
reg_read/reg_write call */
|
||||
u32 sbwad; /* Save backplane window address */
|
||||
};
|
||||
|
||||
/**
|
||||
* SDIO Host Controller info
|
||||
*/
|
||||
struct sdio_hc {
|
||||
struct sdio_hc *next;
|
||||
struct device *dev; /* platform device handle */
|
||||
void *regs; /* SDIO Host Controller address */
|
||||
struct brcmf_sdio_card *card;
|
||||
void *ch;
|
||||
unsigned int oob_irq;
|
||||
unsigned long oob_flags; /* OOB Host specifiction
|
||||
as edge and etc */
|
||||
bool oob_irq_registered;
|
||||
};
|
||||
|
||||
/* local copy of bcm sd handler */
|
||||
static struct brcmf_sdio_card *l_card;
|
||||
|
||||
const uint brcmf_sdio_msglevel = BRCMF_SD_ERROR_VAL;
|
||||
|
||||
static struct sdio_hc *sdhcinfo;
|
||||
|
||||
/* driver info, initialized when brcmf_sdio_register is called */
|
||||
static struct brcmf_sdioh_driver drvinfo = { NULL, NULL };
|
||||
|
||||
/* Module parameters specific to each host-controller driver */
|
||||
|
||||
module_param(sd_msglevel, uint, 0);
|
||||
|
||||
extern uint sd_f2_blocksize;
|
||||
module_param(sd_f2_blocksize, int, 0);
|
||||
|
||||
/* forward declarations */
|
||||
int brcmf_sdio_probe(struct device *dev);
|
||||
EXPORT_SYMBOL(brcmf_sdio_probe);
|
||||
|
||||
int brcmf_sdio_remove(struct device *dev);
|
||||
EXPORT_SYMBOL(brcmf_sdio_remove);
|
||||
|
||||
struct brcmf_sdio_card*
|
||||
brcmf_sdcard_attach(void *cfghdl, u32 *regsva, uint irq)
|
||||
{
|
||||
struct brcmf_sdio_card *card;
|
||||
|
||||
card = kzalloc(sizeof(struct brcmf_sdio_card), GFP_ATOMIC);
|
||||
if (card == NULL) {
|
||||
BRCMF_SD_ERROR(("sdcard_attach: out of memory"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* save the handler locally */
|
||||
l_card = card;
|
||||
|
||||
card->sdioh = brcmf_sdioh_attach(cfghdl, irq);
|
||||
if (!card->sdioh) {
|
||||
brcmf_sdcard_detach(card);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
card->init_success = true;
|
||||
|
||||
*regsva = SI_ENUM_BASE;
|
||||
|
||||
/* Report the BAR, to fix if needed */
|
||||
card->sbwad = SI_ENUM_BASE;
|
||||
return card;
|
||||
}
|
||||
|
||||
int brcmf_sdcard_detach(struct brcmf_sdio_card *card)
|
||||
{
|
||||
if (card != NULL) {
|
||||
if (card->sdioh) {
|
||||
brcmf_sdioh_detach(card->sdioh);
|
||||
card->sdioh = NULL;
|
||||
}
|
||||
kfree(card);
|
||||
}
|
||||
|
||||
l_card = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
brcmf_sdcard_iovar_op(struct brcmf_sdio_card *card, const char *name,
|
||||
void *params, int plen, void *arg, int len, bool set)
|
||||
{
|
||||
return brcmf_sdioh_iovar_op(card->sdioh, name, params, plen, arg,
|
||||
len, set);
|
||||
}
|
||||
|
||||
int brcmf_sdcard_intr_enable(struct brcmf_sdio_card *card)
|
||||
{
|
||||
return brcmf_sdioh_interrupt_set(card->sdioh, true);
|
||||
}
|
||||
|
||||
int brcmf_sdcard_intr_disable(struct brcmf_sdio_card *card)
|
||||
{
|
||||
return brcmf_sdioh_interrupt_set(card->sdioh, false);
|
||||
}
|
||||
|
||||
int brcmf_sdcard_intr_reg(struct brcmf_sdio_card *card,
|
||||
void (*fn)(void *), void *argh)
|
||||
{
|
||||
return brcmf_sdioh_interrupt_register(card->sdioh, fn, argh);
|
||||
}
|
||||
|
||||
int brcmf_sdcard_intr_dereg(struct brcmf_sdio_card *card)
|
||||
{
|
||||
return brcmf_sdioh_interrupt_deregister(card->sdioh);
|
||||
}
|
||||
|
||||
u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_card *card, uint fnc_num, u32 addr,
|
||||
int *err)
|
||||
{
|
||||
int status;
|
||||
s32 retry = 0;
|
||||
u8 data = 0;
|
||||
|
||||
if (!card)
|
||||
card = l_card;
|
||||
|
||||
do {
|
||||
if (retry) /* wait for 1 ms till bus get settled down */
|
||||
udelay(1000);
|
||||
status =
|
||||
brcmf_sdioh_cfg_read(card->sdioh, fnc_num, addr,
|
||||
(u8 *) &data);
|
||||
} while (status != 0
|
||||
&& (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
|
||||
if (err)
|
||||
*err = status;
|
||||
|
||||
BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
|
||||
__func__, fnc_num, addr, data));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void
|
||||
brcmf_sdcard_cfg_write(struct brcmf_sdio_card *card, uint fnc_num, u32 addr,
|
||||
u8 data, int *err)
|
||||
{
|
||||
int status;
|
||||
s32 retry = 0;
|
||||
|
||||
if (!card)
|
||||
card = l_card;
|
||||
|
||||
do {
|
||||
if (retry) /* wait for 1 ms till bus get settled down */
|
||||
udelay(1000);
|
||||
status =
|
||||
brcmf_sdioh_cfg_write(card->sdioh, fnc_num, addr,
|
||||
(u8 *) &data);
|
||||
} while (status != 0
|
||||
&& (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
|
||||
if (err)
|
||||
*err = status;
|
||||
|
||||
BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
|
||||
__func__, fnc_num, addr, data));
|
||||
}
|
||||
|
||||
u32 brcmf_sdcard_cfg_read_word(struct brcmf_sdio_card *card, uint fnc_num,
|
||||
u32 addr, int *err)
|
||||
{
|
||||
int status;
|
||||
u32 data = 0;
|
||||
|
||||
if (!card)
|
||||
card = l_card;
|
||||
|
||||
status = brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
|
||||
SDIOH_READ, fnc_num, addr, &data, 4);
|
||||
|
||||
if (err)
|
||||
*err = status;
|
||||
|
||||
BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
|
||||
__func__, fnc_num, addr, data));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void
|
||||
brcmf_sdcard_cfg_write_word(struct brcmf_sdio_card *card, uint fnc_num,
|
||||
u32 addr, u32 data, int *err)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (!card)
|
||||
card = l_card;
|
||||
|
||||
status =
|
||||
brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
|
||||
SDIOH_WRITE, fnc_num, addr, &data, 4);
|
||||
|
||||
if (err)
|
||||
*err = status;
|
||||
|
||||
BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
|
||||
__func__, fnc_num, addr, data));
|
||||
}
|
||||
|
||||
int brcmf_sdcard_cis_read(struct brcmf_sdio_card *card, uint func, u8 * cis,
|
||||
uint length)
|
||||
{
|
||||
int status;
|
||||
|
||||
u8 *tmp_buf, *tmp_ptr;
|
||||
u8 *ptr;
|
||||
bool ascii = func & ~0xf;
|
||||
func &= 0x7;
|
||||
|
||||
if (!card)
|
||||
card = l_card;
|
||||
|
||||
status = brcmf_sdioh_cis_read(card->sdioh, func, cis, length);
|
||||
|
||||
if (ascii) {
|
||||
/* Move binary bits to tmp and format them
|
||||
into the provided buffer. */
|
||||
tmp_buf = kmalloc(length, GFP_ATOMIC);
|
||||
if (tmp_buf == NULL) {
|
||||
BRCMF_SD_ERROR(("%s: out of memory\n", __func__));
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(tmp_buf, cis, length);
|
||||
for (tmp_ptr = tmp_buf, ptr = cis; ptr < (cis + length - 4);
|
||||
tmp_ptr++) {
|
||||
ptr += sprintf((char *)ptr, "%.2x ", *tmp_ptr & 0xff);
|
||||
if ((((tmp_ptr - tmp_buf) + 1) & 0xf) == 0)
|
||||
ptr += sprintf((char *)ptr, "\n");
|
||||
}
|
||||
kfree(tmp_buf);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int
|
||||
brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_card *card, u32 address)
|
||||
{
|
||||
int err = 0;
|
||||
brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
|
||||
(address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
|
||||
if (!err)
|
||||
brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
|
||||
SBSDIO_FUNC1_SBADDRMID,
|
||||
(address >> 16) & SBSDIO_SBADDRMID_MASK,
|
||||
&err);
|
||||
if (!err)
|
||||
brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
|
||||
SBSDIO_FUNC1_SBADDRHIGH,
|
||||
(address >> 24) & SBSDIO_SBADDRHIGH_MASK,
|
||||
&err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
u32 brcmf_sdcard_reg_read(struct brcmf_sdio_card *card, u32 addr, uint size)
|
||||
{
|
||||
int status;
|
||||
u32 word = 0;
|
||||
uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
|
||||
|
||||
BRCMF_SD_INFO(("%s:fun = 1, addr = 0x%x, ", __func__, addr));
|
||||
|
||||
if (!card)
|
||||
card = l_card;
|
||||
|
||||
if (bar0 != card->sbwad) {
|
||||
if (brcmf_sdcard_set_sbaddr_window(card, bar0))
|
||||
return 0xFFFFFFFF;
|
||||
|
||||
card->sbwad = bar0;
|
||||
}
|
||||
|
||||
addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
if (size == 4)
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
status = brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
|
||||
SDIOH_READ, SDIO_FUNC_1, addr, &word, size);
|
||||
|
||||
card->regfail = (status != 0);
|
||||
|
||||
BRCMF_SD_INFO(("u32data = 0x%x\n", word));
|
||||
|
||||
/* if ok, return appropriately masked word */
|
||||
if (status == 0) {
|
||||
switch (size) {
|
||||
case sizeof(u8):
|
||||
return word & 0xff;
|
||||
case sizeof(u16):
|
||||
return word & 0xffff;
|
||||
case sizeof(u32):
|
||||
return word;
|
||||
default:
|
||||
card->regfail = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* otherwise, bad sdio access or invalid size */
|
||||
BRCMF_SD_ERROR(("%s: error reading addr 0x%04x size %d\n", __func__,
|
||||
addr, size));
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
u32 brcmf_sdcard_reg_write(struct brcmf_sdio_card *card, u32 addr, uint size,
|
||||
u32 data)
|
||||
{
|
||||
int status;
|
||||
uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
|
||||
int err = 0;
|
||||
|
||||
BRCMF_SD_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
|
||||
__func__, addr, size * 8, data));
|
||||
|
||||
if (!card)
|
||||
card = l_card;
|
||||
|
||||
if (bar0 != card->sbwad) {
|
||||
err = brcmf_sdcard_set_sbaddr_window(card, bar0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
card->sbwad = bar0;
|
||||
}
|
||||
|
||||
addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
if (size == 4)
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
status =
|
||||
brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
|
||||
SDIOH_WRITE, SDIO_FUNC_1, addr, &data, size);
|
||||
card->regfail = (status != 0);
|
||||
|
||||
if (status == 0)
|
||||
return 0;
|
||||
|
||||
BRCMF_SD_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n",
|
||||
__func__, data, addr, size));
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
bool brcmf_sdcard_regfail(struct brcmf_sdio_card *card)
|
||||
{
|
||||
return card->regfail;
|
||||
}
|
||||
|
||||
int
|
||||
brcmf_sdcard_recv_buf(struct brcmf_sdio_card *card, u32 addr, uint fn,
|
||||
uint flags,
|
||||
u8 *buf, uint nbytes, struct sk_buff *pkt,
|
||||
void (*complete)(void *handle, int status,
|
||||
bool sync_waiting),
|
||||
void *handle)
|
||||
{
|
||||
int status;
|
||||
uint incr_fix;
|
||||
uint width;
|
||||
uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
|
||||
int err = 0;
|
||||
|
||||
BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
|
||||
__func__, fn, addr, nbytes));
|
||||
|
||||
/* Async not implemented yet */
|
||||
if (flags & SDIO_REQ_ASYNC)
|
||||
return -ENOTSUPP;
|
||||
|
||||
if (bar0 != card->sbwad) {
|
||||
err = brcmf_sdcard_set_sbaddr_window(card, bar0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
card->sbwad = bar0;
|
||||
}
|
||||
|
||||
addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
|
||||
incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
|
||||
width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
|
||||
if (width == 4)
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
status = brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
|
||||
incr_fix, SDIOH_READ, fn, addr, width, nbytes, buf, pkt);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int
|
||||
brcmf_sdcard_send_buf(struct brcmf_sdio_card *card, u32 addr, uint fn,
|
||||
uint flags, u8 *buf, uint nbytes, void *pkt,
|
||||
void (*complete)(void *handle, int status,
|
||||
bool sync_waiting),
|
||||
void *handle)
|
||||
{
|
||||
uint incr_fix;
|
||||
uint width;
|
||||
uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
|
||||
int err = 0;
|
||||
|
||||
BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
|
||||
__func__, fn, addr, nbytes));
|
||||
|
||||
/* Async not implemented yet */
|
||||
if (flags & SDIO_REQ_ASYNC)
|
||||
return -ENOTSUPP;
|
||||
|
||||
if (bar0 != card->sbwad) {
|
||||
err = brcmf_sdcard_set_sbaddr_window(card, bar0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
card->sbwad = bar0;
|
||||
}
|
||||
|
||||
addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
|
||||
incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
|
||||
width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
|
||||
if (width == 4)
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
return brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
|
||||
incr_fix, SDIOH_WRITE, fn, addr, width, nbytes, buf, pkt);
|
||||
}
|
||||
|
||||
int brcmf_sdcard_rwdata(struct brcmf_sdio_card *card, uint rw, u32 addr,
|
||||
u8 *buf, uint nbytes)
|
||||
{
|
||||
addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
return brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
|
||||
SDIOH_DATA_INC, (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1,
|
||||
addr, 4, nbytes, buf, NULL);
|
||||
}
|
||||
|
||||
int brcmf_sdcard_abort(struct brcmf_sdio_card *card, uint fn)
|
||||
{
|
||||
return brcmf_sdioh_abort(card->sdioh, fn);
|
||||
}
|
||||
|
||||
int brcmf_sdcard_query_device(struct brcmf_sdio_card *card)
|
||||
{
|
||||
card->vendevid = (PCI_VENDOR_ID_BROADCOM << 16) | 0;
|
||||
return card->vendevid;
|
||||
}
|
||||
|
||||
u32 brcmf_sdcard_cur_sbwad(struct brcmf_sdio_card *card)
|
||||
{
|
||||
if (!card)
|
||||
card = l_card;
|
||||
|
||||
return card->sbwad;
|
||||
}
|
||||
|
||||
int brcmf_sdio_probe(struct device *dev)
|
||||
{
|
||||
struct sdio_hc *sdhc = NULL;
|
||||
u32 regs = 0;
|
||||
struct brcmf_sdio_card *card = NULL;
|
||||
int irq = 0;
|
||||
u32 vendevid;
|
||||
unsigned long irq_flags = 0;
|
||||
|
||||
/* allocate SDIO Host Controller state info */
|
||||
sdhc = kzalloc(sizeof(struct sdio_hc), GFP_ATOMIC);
|
||||
if (!sdhc) {
|
||||
SDLX_MSG(("%s: out of memory\n", __func__));
|
||||
goto err;
|
||||
}
|
||||
sdhc->dev = (void *)dev;
|
||||
|
||||
card = brcmf_sdcard_attach((void *)0, ®s, irq);
|
||||
if (!card) {
|
||||
SDLX_MSG(("%s: attach failed\n", __func__));
|
||||
goto err;
|
||||
}
|
||||
|
||||
sdhc->card = card;
|
||||
sdhc->oob_irq = irq;
|
||||
sdhc->oob_flags = irq_flags;
|
||||
sdhc->oob_irq_registered = false; /* to make sure.. */
|
||||
|
||||
/* chain SDIO Host Controller info together */
|
||||
sdhc->next = sdhcinfo;
|
||||
sdhcinfo = sdhc;
|
||||
/* Read the vendor/device ID from the CIS */
|
||||
vendevid = brcmf_sdcard_query_device(card);
|
||||
|
||||
/* try to attach to the target device */
|
||||
sdhc->ch = drvinfo.attach((vendevid >> 16), (vendevid & 0xFFFF),
|
||||
0, 0, 0, 0, regs, card);
|
||||
if (!sdhc->ch) {
|
||||
SDLX_MSG(("%s: device attach failed\n", __func__));
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
/* error handling */
|
||||
err:
|
||||
if (sdhc) {
|
||||
if (sdhc->card)
|
||||
brcmf_sdcard_detach(sdhc->card);
|
||||
kfree(sdhc);
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
int brcmf_sdio_remove(struct device *dev)
|
||||
{
|
||||
struct sdio_hc *sdhc, *prev;
|
||||
|
||||
sdhc = sdhcinfo;
|
||||
drvinfo.detach(sdhc->ch);
|
||||
brcmf_sdcard_detach(sdhc->card);
|
||||
/* find the SDIO Host Controller state for this pdev
|
||||
and take it out from the list */
|
||||
for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) {
|
||||
if (sdhc->dev == (void *)dev) {
|
||||
if (prev)
|
||||
prev->next = sdhc->next;
|
||||
else
|
||||
sdhcinfo = NULL;
|
||||
break;
|
||||
}
|
||||
prev = sdhc;
|
||||
}
|
||||
if (!sdhc) {
|
||||
SDLX_MSG(("%s: failed\n", __func__));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* release SDIO Host Controller info */
|
||||
kfree(sdhc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int brcmf_sdio_register(struct brcmf_sdioh_driver *driver)
|
||||
{
|
||||
drvinfo = *driver;
|
||||
|
||||
SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n"));
|
||||
return brcmf_sdio_function_init();
|
||||
}
|
||||
|
||||
void brcmf_sdio_unregister(void)
|
||||
{
|
||||
brcmf_sdio_function_cleanup();
|
||||
}
|
||||
|
||||
void brcmf_sdio_wdtmr_enable(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
brcmf_sdbrcm_wd_timer(sdhcinfo->ch, brcmf_watchdog_ms);
|
||||
else
|
||||
brcmf_sdbrcm_wd_timer(sdhcinfo->ch, 0);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,904 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/****************
|
||||
* Common types *
|
||||
*/
|
||||
|
||||
#ifndef _BRCMF_H_
|
||||
#define _BRCMF_H_
|
||||
|
||||
#define BRCMF_VERSION_STR "4.218.248.5"
|
||||
|
||||
#define BRCMF_C_IOCTL_SMLEN 256 /* "small" ioctl buffer required */
|
||||
#define BRCMF_C_IOCTL_MEDLEN 1536 /* "med" ioctl buffer required */
|
||||
#define BRCMF_C_IOCTL_MAXLEN 8192
|
||||
|
||||
#define BRCMF_C_UP 2
|
||||
#define BRCMF_C_SET_PROMISC 10
|
||||
#define BRCMF_C_GET_RATE 12
|
||||
#define BRCMF_C_GET_INFRA 19
|
||||
#define BRCMF_C_SET_INFRA 20
|
||||
#define BRCMF_C_GET_AUTH 21
|
||||
#define BRCMF_C_SET_AUTH 22
|
||||
#define BRCMF_C_GET_BSSID 23
|
||||
#define BRCMF_C_GET_SSID 25
|
||||
#define BRCMF_C_SET_SSID 26
|
||||
#define BRCMF_C_GET_CHANNEL 29
|
||||
#define BRCMF_C_GET_SRL 31
|
||||
#define BRCMF_C_GET_LRL 33
|
||||
#define BRCMF_C_GET_RADIO 37
|
||||
#define BRCMF_C_SET_RADIO 38
|
||||
#define BRCMF_C_GET_PHYTYPE 39
|
||||
#define BRCMF_C_SET_KEY 45
|
||||
#define BRCMF_C_SET_PASSIVE_SCAN 49
|
||||
#define BRCMF_C_SCAN 50
|
||||
#define BRCMF_C_SCAN_RESULTS 51
|
||||
#define BRCMF_C_DISASSOC 52
|
||||
#define BRCMF_C_REASSOC 53
|
||||
#define BRCMF_C_SET_ROAM_TRIGGER 55
|
||||
#define BRCMF_C_SET_ROAM_DELTA 57
|
||||
#define BRCMF_C_GET_DTIMPRD 77
|
||||
#define BRCMF_C_SET_COUNTRY 84
|
||||
#define BRCMF_C_GET_PM 85
|
||||
#define BRCMF_C_SET_PM 86
|
||||
#define BRCMF_C_GET_AP 117
|
||||
#define BRCMF_C_SET_AP 118
|
||||
#define BRCMF_C_GET_RSSI 127
|
||||
#define BRCMF_C_GET_WSEC 133
|
||||
#define BRCMF_C_SET_WSEC 134
|
||||
#define BRCMF_C_GET_PHY_NOISE 135
|
||||
#define BRCMF_C_GET_BSS_INFO 136
|
||||
#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185
|
||||
#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187
|
||||
#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201
|
||||
#define BRCMF_C_GET_VALID_CHANNELS 217
|
||||
#define BRCMF_C_GET_KEY_PRIMARY 235
|
||||
#define BRCMF_C_SET_KEY_PRIMARY 236
|
||||
#define BRCMF_C_SET_SCAN_PASSIVE_TIME 258
|
||||
#define BRCMF_C_GET_VAR 262
|
||||
#define BRCMF_C_SET_VAR 263
|
||||
|
||||
/* phy types (returned by WLC_GET_PHYTPE) */
|
||||
#define WLC_PHY_TYPE_A 0
|
||||
#define WLC_PHY_TYPE_B 1
|
||||
#define WLC_PHY_TYPE_G 2
|
||||
#define WLC_PHY_TYPE_N 4
|
||||
#define WLC_PHY_TYPE_LP 5
|
||||
#define WLC_PHY_TYPE_SSN 6
|
||||
#define WLC_PHY_TYPE_HT 7
|
||||
#define WLC_PHY_TYPE_LCN 8
|
||||
#define WLC_PHY_TYPE_NULL 0xf
|
||||
|
||||
#define BRCMF_PKT_FILTER_FIXED_LEN offsetof(struct brcmf_pkt_filter, u)
|
||||
#define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN \
|
||||
offsetof(struct brcmf_pkt_filter_pattern, mask_and_pattern)
|
||||
|
||||
#define BRCMF_EVENTING_MASK_LEN 16
|
||||
|
||||
#define TOE_TX_CSUM_OL 0x00000001
|
||||
#define TOE_RX_CSUM_OL 0x00000002
|
||||
|
||||
/* maximum channels returned by the get valid channels iovar */
|
||||
#define WL_NUMCHANNELS 64
|
||||
|
||||
#define BRCMF_BSS_INFO_VERSION 108 /* current ver of brcmf_bss_info struct */
|
||||
|
||||
/* size of brcmf_scan_params not including variable length array */
|
||||
#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64
|
||||
|
||||
/* masks for channel and ssid count */
|
||||
#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff
|
||||
#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16
|
||||
|
||||
#define BRCMF_SCAN_ACTION_START 1
|
||||
#define BRCMF_SCAN_ACTION_CONTINUE 2
|
||||
#define WL_SCAN_ACTION_ABORT 3
|
||||
|
||||
#define BRCMF_ISCAN_REQ_VERSION 1
|
||||
|
||||
/* brcmf_iscan_results status values */
|
||||
#define BRCMF_SCAN_RESULTS_SUCCESS 0
|
||||
#define BRCMF_SCAN_RESULTS_PARTIAL 1
|
||||
#define BRCMF_SCAN_RESULTS_PENDING 2
|
||||
#define BRCMF_SCAN_RESULTS_ABORTED 3
|
||||
#define BRCMF_SCAN_RESULTS_NO_MEM 4
|
||||
|
||||
#define WL_SOFT_KEY (1 << 0) /* Indicates this key is using soft encrypt */
|
||||
#define BRCMF_PRIMARY_KEY (1 << 1) /* primary (ie tx) key */
|
||||
#define WL_KF_RES_4 (1 << 4) /* Reserved for backward compat */
|
||||
#define WL_KF_RES_5 (1 << 5) /* Reserved for backward compat */
|
||||
#define WL_IBSS_PEER_GROUP_KEY (1 << 6) /* Indicates a group key for a IBSS PEER */
|
||||
|
||||
/* For supporting multiple interfaces */
|
||||
#define BRCMF_MAX_IFS 16
|
||||
#define BRCMF_DEL_IF -0xe
|
||||
#define BRCMF_BAD_IF -0xf
|
||||
|
||||
#define DOT11_BSSTYPE_ANY 2
|
||||
#define DOT11_MAX_DEFAULT_KEYS 4
|
||||
|
||||
#define BRCMF_EVENT_MSG_LINK 0x01
|
||||
#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02
|
||||
#define BRCMF_EVENT_MSG_GROUP 0x04
|
||||
|
||||
struct brcmf_event_msg {
|
||||
u16 version;
|
||||
u16 flags;
|
||||
u32 event_type;
|
||||
u32 status;
|
||||
u32 reason;
|
||||
u32 auth_type;
|
||||
u32 datalen;
|
||||
u8 addr[ETH_ALEN];
|
||||
char ifname[IFNAMSIZ];
|
||||
} __packed;
|
||||
|
||||
struct brcm_ethhdr {
|
||||
u16 subtype;
|
||||
u16 length;
|
||||
u8 version;
|
||||
u8 oui[3];
|
||||
u16 usr_subtype;
|
||||
} __packed;
|
||||
|
||||
struct brcmf_event {
|
||||
struct ethhdr eth;
|
||||
struct brcm_ethhdr hdr;
|
||||
struct brcmf_event_msg msg;
|
||||
} __packed;
|
||||
|
||||
struct dngl_stats {
|
||||
unsigned long rx_packets; /* total packets received */
|
||||
unsigned long tx_packets; /* total packets transmitted */
|
||||
unsigned long rx_bytes; /* total bytes received */
|
||||
unsigned long tx_bytes; /* total bytes transmitted */
|
||||
unsigned long rx_errors; /* bad packets received */
|
||||
unsigned long tx_errors; /* packet transmit problems */
|
||||
unsigned long rx_dropped; /* packets dropped by dongle */
|
||||
unsigned long tx_dropped; /* packets dropped by dongle */
|
||||
unsigned long multicast; /* multicast packets received */
|
||||
};
|
||||
|
||||
#define BRCMF_E_SET_SSID 0
|
||||
#define BRCMF_E_JOIN 1
|
||||
#define BRCMF_E_START 2
|
||||
#define BRCMF_E_AUTH 3
|
||||
#define BRCMF_E_AUTH_IND 4
|
||||
#define BRCMF_E_DEAUTH 5
|
||||
#define BRCMF_E_DEAUTH_IND 6
|
||||
#define BRCMF_E_ASSOC 7
|
||||
#define BRCMF_E_ASSOC_IND 8
|
||||
#define BRCMF_E_REASSOC 9
|
||||
#define BRCMF_E_REASSOC_IND 10
|
||||
#define BRCMF_E_DISASSOC 11
|
||||
#define BRCMF_E_DISASSOC_IND 12
|
||||
#define BRCMF_E_QUIET_START 13
|
||||
#define BRCMF_E_QUIET_END 14
|
||||
#define BRCMF_E_BEACON_RX 15
|
||||
#define BRCMF_E_LINK 16
|
||||
#define BRCMF_E_MIC_ERROR 17
|
||||
#define BRCMF_E_NDIS_LINK 18
|
||||
#define BRCMF_E_ROAM 19
|
||||
#define BRCMF_E_TXFAIL 20
|
||||
#define BRCMF_E_PMKID_CACHE 21
|
||||
#define BRCMF_E_RETROGRADE_TSF 22
|
||||
#define BRCMF_E_PRUNE 23
|
||||
#define BRCMF_E_AUTOAUTH 24
|
||||
#define BRCMF_E_EAPOL_MSG 25
|
||||
#define BRCMF_E_SCAN_COMPLETE 26
|
||||
#define BRCMF_E_ADDTS_IND 27
|
||||
#define BRCMF_E_DELTS_IND 28
|
||||
#define BRCMF_E_BCNSENT_IND 29
|
||||
#define BRCMF_E_BCNRX_MSG 30
|
||||
#define BRCMF_E_BCNLOST_MSG 31
|
||||
#define BRCMF_E_ROAM_PREP 32
|
||||
#define BRCMF_E_PFN_NET_FOUND 33
|
||||
#define BRCMF_E_PFN_NET_LOST 34
|
||||
#define BRCMF_E_RESET_COMPLETE 35
|
||||
#define BRCMF_E_JOIN_START 36
|
||||
#define BRCMF_E_ROAM_START 37
|
||||
#define BRCMF_E_ASSOC_START 38
|
||||
#define BRCMF_E_IBSS_ASSOC 39
|
||||
#define BRCMF_E_RADIO 40
|
||||
#define BRCMF_E_PSM_WATCHDOG 41
|
||||
#define BRCMF_E_PROBREQ_MSG 44
|
||||
#define BRCMF_E_SCAN_CONFIRM_IND 45
|
||||
#define BRCMF_E_PSK_SUP 46
|
||||
#define BRCMF_E_COUNTRY_CODE_CHANGED 47
|
||||
#define BRCMF_E_EXCEEDED_MEDIUM_TIME 48
|
||||
#define BRCMF_E_ICV_ERROR 49
|
||||
#define BRCMF_E_UNICAST_DECODE_ERROR 50
|
||||
#define BRCMF_E_MULTICAST_DECODE_ERROR 51
|
||||
#define BRCMF_E_TRACE 52
|
||||
#define BRCMF_E_IF 54
|
||||
#define BRCMF_E_RSSI 56
|
||||
#define BRCMF_E_PFN_SCAN_COMPLETE 57
|
||||
#define BRCMF_E_EXTLOG_MSG 58
|
||||
#define BRCMF_E_ACTION_FRAME 59
|
||||
#define BRCMF_E_ACTION_FRAME_COMPLETE 60
|
||||
#define BRCMF_E_PRE_ASSOC_IND 61
|
||||
#define BRCMF_E_PRE_REASSOC_IND 62
|
||||
#define BRCMF_E_CHANNEL_ADOPTED 63
|
||||
#define BRCMF_E_AP_STARTED 64
|
||||
#define BRCMF_E_DFS_AP_STOP 65
|
||||
#define BRCMF_E_DFS_AP_RESUME 66
|
||||
#define BRCMF_E_RESERVED1 67
|
||||
#define BRCMF_E_RESERVED2 68
|
||||
#define BRCMF_E_ESCAN_RESULT 69
|
||||
#define BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70
|
||||
#define BRCMF_E_DCS_REQUEST 73
|
||||
|
||||
#define BRCMF_E_FIFO_CREDIT_MAP 74
|
||||
|
||||
#define BRCMF_E_LAST 75
|
||||
|
||||
#define BRCMF_E_STATUS_SUCCESS 0
|
||||
#define BRCMF_E_STATUS_FAIL 1
|
||||
#define BRCMF_E_STATUS_TIMEOUT 2
|
||||
#define BRCMF_E_STATUS_NO_NETWORKS 3
|
||||
#define BRCMF_E_STATUS_ABORT 4
|
||||
#define BRCMF_E_STATUS_NO_ACK 5
|
||||
#define BRCMF_E_STATUS_UNSOLICITED 6
|
||||
#define BRCMF_E_STATUS_ATTEMPT 7
|
||||
#define BRCMF_E_STATUS_PARTIAL 8
|
||||
#define BRCMF_E_STATUS_NEWSCAN 9
|
||||
#define BRCMF_E_STATUS_NEWASSOC 10
|
||||
#define BRCMF_E_STATUS_11HQUIET 11
|
||||
#define BRCMF_E_STATUS_SUPPRESS 12
|
||||
#define BRCMF_E_STATUS_NOCHANS 13
|
||||
#define BRCMF_E_STATUS_CS_ABORT 15
|
||||
#define BRCMF_E_STATUS_ERROR 16
|
||||
|
||||
#define BRCMF_E_REASON_INITIAL_ASSOC 0
|
||||
#define BRCMF_E_REASON_LOW_RSSI 1
|
||||
#define BRCMF_E_REASON_DEAUTH 2
|
||||
#define BRCMF_E_REASON_DISASSOC 3
|
||||
#define BRCMF_E_REASON_BCNS_LOST 4
|
||||
#define BRCMF_E_REASON_MINTXRATE 9
|
||||
#define BRCMF_E_REASON_TXFAIL 10
|
||||
|
||||
#define BRCMF_E_REASON_FAST_ROAM_FAILED 5
|
||||
#define BRCMF_E_REASON_DIRECTED_ROAM 6
|
||||
#define BRCMF_E_REASON_TSPEC_REJECTED 7
|
||||
#define BRCMF_E_REASON_BETTER_AP 8
|
||||
|
||||
#define BRCMF_E_PRUNE_ENCR_MISMATCH 1
|
||||
#define BRCMF_E_PRUNE_BCAST_BSSID 2
|
||||
#define BRCMF_E_PRUNE_MAC_DENY 3
|
||||
#define BRCMF_E_PRUNE_MAC_NA 4
|
||||
#define BRCMF_E_PRUNE_REG_PASSV 5
|
||||
#define BRCMF_E_PRUNE_SPCT_MGMT 6
|
||||
#define BRCMF_E_PRUNE_RADAR 7
|
||||
#define BRCMF_E_RSN_MISMATCH 8
|
||||
#define BRCMF_E_PRUNE_NO_COMMON_RATES 9
|
||||
#define BRCMF_E_PRUNE_BASIC_RATES 10
|
||||
#define BRCMF_E_PRUNE_CIPHER_NA 12
|
||||
#define BRCMF_E_PRUNE_KNOWN_STA 13
|
||||
#define BRCMF_E_PRUNE_WDS_PEER 15
|
||||
#define BRCMF_E_PRUNE_QBSS_LOAD 16
|
||||
#define BRCMF_E_PRUNE_HOME_AP 17
|
||||
|
||||
#define BRCMF_E_SUP_OTHER 0
|
||||
#define BRCMF_E_SUP_DECRYPT_KEY_DATA 1
|
||||
#define BRCMF_E_SUP_BAD_UCAST_WEP128 2
|
||||
#define BRCMF_E_SUP_BAD_UCAST_WEP40 3
|
||||
#define BRCMF_E_SUP_UNSUP_KEY_LEN 4
|
||||
#define BRCMF_E_SUP_PW_KEY_CIPHER 5
|
||||
#define BRCMF_E_SUP_MSG3_TOO_MANY_IE 6
|
||||
#define BRCMF_E_SUP_MSG3_IE_MISMATCH 7
|
||||
#define BRCMF_E_SUP_NO_INSTALL_FLAG 8
|
||||
#define BRCMF_E_SUP_MSG3_NO_GTK 9
|
||||
#define BRCMF_E_SUP_GRP_KEY_CIPHER 10
|
||||
#define BRCMF_E_SUP_GRP_MSG1_NO_GTK 11
|
||||
#define BRCMF_E_SUP_GTK_DECRYPT_FAIL 12
|
||||
#define BRCMF_E_SUP_SEND_FAIL 13
|
||||
#define BRCMF_E_SUP_DEAUTH 14
|
||||
|
||||
#define BRCMF_E_IF_ADD 1
|
||||
#define BRCMF_E_IF_DEL 2
|
||||
#define BRCMF_E_IF_CHANGE 3
|
||||
|
||||
#define BRCMF_E_IF_ROLE_STA 0
|
||||
#define BRCMF_E_IF_ROLE_AP 1
|
||||
#define BRCMF_E_IF_ROLE_WDS 2
|
||||
|
||||
#define BRCMF_E_LINK_BCN_LOSS 1
|
||||
#define BRCMF_E_LINK_DISASSOC 2
|
||||
#define BRCMF_E_LINK_ASSOC_REC 3
|
||||
#define BRCMF_E_LINK_BSSCFG_DIS 4
|
||||
|
||||
/* The level of bus communication with the dongle */
|
||||
enum brcmf_bus_state {
|
||||
BRCMF_BUS_DOWN, /* Not ready for frame transfers */
|
||||
BRCMF_BUS_LOAD, /* Download access only (CPU reset) */
|
||||
BRCMF_BUS_DATA /* Ready for frame transfers */
|
||||
};
|
||||
|
||||
/* Pattern matching filter. Specifies an offset within received packets to
|
||||
* start matching, the pattern to match, the size of the pattern, and a bitmask
|
||||
* that indicates which bits within the pattern should be matched.
|
||||
*/
|
||||
struct brcmf_pkt_filter_pattern {
|
||||
u32 offset; /* Offset within received packet to start pattern matching.
|
||||
* Offset '0' is the first byte of the ethernet header.
|
||||
*/
|
||||
u32 size_bytes; /* Size of the pattern. Bitmask must be the same size. */
|
||||
u8 mask_and_pattern[1]; /* Variable length mask and pattern data. mask starts
|
||||
* at offset 0. Pattern immediately follows mask.
|
||||
*/
|
||||
};
|
||||
|
||||
/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
|
||||
struct brcmf_pkt_filter {
|
||||
u32 id; /* Unique filter id, specified by app. */
|
||||
u32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */
|
||||
u32 negate_match; /* Negate the result of filter matches */
|
||||
union { /* Filter definitions */
|
||||
struct brcmf_pkt_filter_pattern pattern; /* Filter pattern */
|
||||
} u;
|
||||
};
|
||||
|
||||
/* IOVAR "pkt_filter_enable" parameter. */
|
||||
struct brcmf_pkt_filter_enable {
|
||||
u32 id; /* Unique filter id */
|
||||
u32 enable; /* Enable/disable bool */
|
||||
};
|
||||
|
||||
/* BSS info structure
|
||||
* Applications MUST CHECK ie_offset field and length field to access IEs and
|
||||
* next bss_info structure in a vector (in struct brcmf_scan_results)
|
||||
*/
|
||||
struct brcmf_bss_info {
|
||||
u32 version; /* version field */
|
||||
u32 length; /* byte length of data in this record,
|
||||
* starting at version and including IEs
|
||||
*/
|
||||
u8 BSSID[ETH_ALEN];
|
||||
u16 beacon_period; /* units are Kusec */
|
||||
u16 capability; /* Capability information */
|
||||
u8 SSID_len;
|
||||
u8 SSID[32];
|
||||
struct {
|
||||
uint count; /* # rates in this set */
|
||||
u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
|
||||
} rateset; /* supported rates */
|
||||
chanspec_t chanspec; /* chanspec for bss */
|
||||
u16 atim_window; /* units are Kusec */
|
||||
u8 dtim_period; /* DTIM period */
|
||||
s16 RSSI; /* receive signal strength (in dBm) */
|
||||
s8 phy_noise; /* noise (in dBm) */
|
||||
|
||||
u8 n_cap; /* BSS is 802.11N Capable */
|
||||
u32 nbss_cap; /* 802.11N BSS Capabilities (based on HT_CAP_*) */
|
||||
u8 ctl_ch; /* 802.11N BSS control channel number */
|
||||
u32 reserved32[1]; /* Reserved for expansion of BSS properties */
|
||||
u8 flags; /* flags */
|
||||
u8 reserved[3]; /* Reserved for expansion of BSS properties */
|
||||
u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */
|
||||
|
||||
u16 ie_offset; /* offset at which IEs start, from beginning */
|
||||
u32 ie_length; /* byte length of Information Elements */
|
||||
s16 SNR; /* average SNR of during frame reception */
|
||||
/* Add new fields here */
|
||||
/* variable length Information Elements */
|
||||
};
|
||||
|
||||
struct brcmf_ssid {
|
||||
u32 SSID_len;
|
||||
unsigned char SSID[32];
|
||||
};
|
||||
|
||||
struct brcmf_scan_params {
|
||||
struct brcmf_ssid ssid; /* default: {0, ""} */
|
||||
u8 bssid[ETH_ALEN]; /* default: bcast */
|
||||
s8 bss_type; /* default: any,
|
||||
* DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
|
||||
*/
|
||||
u8 scan_type; /* flags, 0 use default */
|
||||
s32 nprobes; /* -1 use default, number of probes per channel */
|
||||
s32 active_time; /* -1 use default, dwell time per channel for
|
||||
* active scanning
|
||||
*/
|
||||
s32 passive_time; /* -1 use default, dwell time per channel
|
||||
* for passive scanning
|
||||
*/
|
||||
s32 home_time; /* -1 use default, dwell time for the home channel
|
||||
* between channel scans
|
||||
*/
|
||||
s32 channel_num; /* count of channels and ssids that follow
|
||||
*
|
||||
* low half is count of channels in
|
||||
* channel_list, 0 means default (use all
|
||||
* available channels)
|
||||
*
|
||||
* high half is entries in struct brcmf_ssid
|
||||
* array that follows channel_list, aligned for
|
||||
* s32 (4 bytes) meaning an odd channel count
|
||||
* implies a 2-byte pad between end of
|
||||
* channel_list and first ssid
|
||||
*
|
||||
* if ssid count is zero, single ssid in the
|
||||
* fixed parameter portion is assumed, otherwise
|
||||
* ssid in the fixed portion is ignored
|
||||
*/
|
||||
u16 channel_list[1]; /* list of chanspecs */
|
||||
};
|
||||
|
||||
/* incremental scan struct */
|
||||
struct brcmf_iscan_params {
|
||||
u32 version;
|
||||
u16 action;
|
||||
u16 scan_duration;
|
||||
struct brcmf_scan_params params;
|
||||
};
|
||||
|
||||
/* 3 fields + size of brcmf_scan_params, not including variable length array */
|
||||
#define BRCMF_ISCAN_PARAMS_FIXED_SIZE \
|
||||
(offsetof(struct brcmf_iscan_params, params) + \
|
||||
sizeof(struct brcmf_ssid))
|
||||
|
||||
struct brcmf_scan_results {
|
||||
u32 buflen;
|
||||
u32 version;
|
||||
u32 count;
|
||||
struct brcmf_bss_info bss_info[1];
|
||||
};
|
||||
|
||||
/* used for association with a specific BSSID and chanspec list */
|
||||
struct brcmf_assoc_params {
|
||||
u8 bssid[ETH_ALEN]; /* 00:00:00:00:00:00: broadcast scan */
|
||||
s32 chanspec_num; /* 0: all available channels,
|
||||
* otherwise count of chanspecs in chanspec_list
|
||||
*/
|
||||
chanspec_t chanspec_list[1]; /* list of chanspecs */
|
||||
};
|
||||
#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
|
||||
(sizeof(struct brcmf_assoc_params) - sizeof(chanspec_t))
|
||||
|
||||
/* used for join with or without a specific bssid and channel list */
|
||||
struct brcmf_join_params {
|
||||
struct brcmf_ssid ssid;
|
||||
struct brcmf_assoc_params params;
|
||||
};
|
||||
|
||||
/* size of brcmf_scan_results not including variable length array */
|
||||
#define BRCMF_SCAN_RESULTS_FIXED_SIZE \
|
||||
(sizeof(struct brcmf_scan_results) - sizeof(struct brcmf_bss_info))
|
||||
|
||||
/* incremental scan results struct */
|
||||
struct brcmf_iscan_results {
|
||||
u32 status;
|
||||
struct brcmf_scan_results results;
|
||||
};
|
||||
|
||||
/* size of brcmf_iscan_results not including variable length array */
|
||||
#define BRCMF_ISCAN_RESULTS_FIXED_SIZE \
|
||||
(BRCMF_SCAN_RESULTS_FIXED_SIZE + \
|
||||
offsetof(struct brcmf_iscan_results, results))
|
||||
|
||||
struct brcmf_wsec_key {
|
||||
u32 index; /* key index */
|
||||
u32 len; /* key length */
|
||||
u8 data[WLAN_MAX_KEY_LEN]; /* key data */
|
||||
u32 pad_1[18];
|
||||
u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
|
||||
u32 flags; /* misc flags */
|
||||
u32 pad_2[2];
|
||||
int pad_3;
|
||||
int iv_initialized; /* has IV been initialized already? */
|
||||
int pad_4;
|
||||
/* Rx IV */
|
||||
struct {
|
||||
u32 hi; /* upper 32 bits of IV */
|
||||
u16 lo; /* lower 16 bits of IV */
|
||||
} rxiv;
|
||||
u32 pad_5[2];
|
||||
u8 ea[ETH_ALEN]; /* per station */
|
||||
};
|
||||
|
||||
/* Used to get specific STA parameters */
|
||||
struct brcmf_scb_val {
|
||||
u32 val;
|
||||
u8 ea[ETH_ALEN];
|
||||
};
|
||||
|
||||
/* channel encoding */
|
||||
struct brcmf_channel_info {
|
||||
int hw_channel;
|
||||
int target_channel;
|
||||
int scan_channel;
|
||||
};
|
||||
|
||||
/* Linux network driver ioctl encoding */
|
||||
struct brcmf_ioctl {
|
||||
uint cmd; /* common ioctl definition */
|
||||
void *buf; /* pointer to user buffer */
|
||||
uint len; /* length of user buffer */
|
||||
u8 set; /* get or set request (optional) */
|
||||
uint used; /* bytes read or written (optional) */
|
||||
uint needed; /* bytes needed (optional) */
|
||||
};
|
||||
|
||||
/* Forward decls for struct brcmf_pub (see below) */
|
||||
struct brcmf_bus; /* device bus info */
|
||||
struct brcmf_proto; /* device communication protocol info */
|
||||
struct brcmf_info; /* device driver info */
|
||||
|
||||
/* Common structure for module and instance linkage */
|
||||
struct brcmf_pub {
|
||||
/* Linkage ponters */
|
||||
struct brcmf_bus *bus;
|
||||
struct brcmf_proto *prot;
|
||||
struct brcmf_info *info;
|
||||
|
||||
/* Internal brcmf items */
|
||||
bool up; /* Driver up/down (to OS) */
|
||||
bool txoff; /* Transmit flow-controlled */
|
||||
bool dongle_reset; /* true = DEVRESET put dongle into reset */
|
||||
enum brcmf_bus_state busstate;
|
||||
uint hdrlen; /* Total BRCMF header length (proto + bus) */
|
||||
uint maxctl; /* Max size rxctl request from proto to bus */
|
||||
uint rxsz; /* Rx buffer size bus module should use */
|
||||
u8 wme_dp; /* wme discard priority */
|
||||
|
||||
/* Dongle media info */
|
||||
bool iswl; /* Dongle-resident driver is wl */
|
||||
unsigned long drv_version; /* Version of dongle-resident driver */
|
||||
u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */
|
||||
struct dngl_stats dstats; /* Stats for dongle-based data */
|
||||
|
||||
/* Additional stats for the bus level */
|
||||
unsigned long tx_packets; /* Data packets sent to dongle */
|
||||
unsigned long tx_multicast; /* Multicast data packets sent to dongle */
|
||||
unsigned long tx_errors; /* Errors in sending data to dongle */
|
||||
unsigned long tx_ctlpkts; /* Control packets sent to dongle */
|
||||
unsigned long tx_ctlerrs; /* Errors sending control frames to dongle */
|
||||
unsigned long rx_packets; /* Packets sent up the network interface */
|
||||
unsigned long rx_multicast; /* Multicast packets sent up the network
|
||||
interface */
|
||||
unsigned long rx_errors; /* Errors processing rx data packets */
|
||||
unsigned long rx_ctlpkts; /* Control frames processed from dongle */
|
||||
unsigned long rx_ctlerrs; /* Errors in processing rx control frames */
|
||||
unsigned long rx_dropped; /* Packets dropped locally (no memory) */
|
||||
unsigned long rx_flushed; /* Packets flushed due to
|
||||
unscheduled sendup thread */
|
||||
unsigned long wd_dpc_sched; /* Number of times dpc scheduled by
|
||||
watchdog timer */
|
||||
|
||||
unsigned long rx_readahead_cnt; /* Number of packets where header read-ahead
|
||||
was used. */
|
||||
unsigned long tx_realloc; /* Number of tx packets we had to realloc for
|
||||
headroom */
|
||||
unsigned long fc_packets; /* Number of flow control pkts recvd */
|
||||
|
||||
/* Last error return */
|
||||
int bcmerror;
|
||||
uint tickcnt;
|
||||
|
||||
/* Last error from dongle */
|
||||
int dongle_error;
|
||||
|
||||
/* Suspend disable flag flag */
|
||||
int suspend_disable_flag; /* "1" to disable all extra powersaving
|
||||
during suspend */
|
||||
int in_suspend; /* flag set to 1 when early suspend called */
|
||||
int dtim_skip; /* dtim skip , default 0 means wake each dtim */
|
||||
|
||||
/* Pkt filter defination */
|
||||
char *pktfilter[100];
|
||||
int pktfilter_count;
|
||||
|
||||
u8 country_code[BRCM_CNTRY_BUF_SZ];
|
||||
char eventmask[BRCMF_EVENTING_MASK_LEN];
|
||||
|
||||
};
|
||||
|
||||
struct brcmf_if_event {
|
||||
u8 ifidx;
|
||||
u8 action;
|
||||
u8 flags;
|
||||
u8 bssidx;
|
||||
};
|
||||
|
||||
struct brcmf_timeout {
|
||||
u32 limit; /* Expiration time (usec) */
|
||||
u32 increment; /* Current expiration increment (usec) */
|
||||
u32 elapsed; /* Current elapsed time (usec) */
|
||||
u32 tick; /* O/S tick time (usec) */
|
||||
};
|
||||
|
||||
struct bcmevent_name {
|
||||
uint event;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_PM_SLEEP)
|
||||
extern atomic_t brcmf_mmc_suspend;
|
||||
#define BRCMF_PM_RESUME_WAIT_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a);
|
||||
#define _BRCMF_PM_RESUME_WAIT(a, b) do { \
|
||||
int retry = 0; \
|
||||
while (atomic_read(&brcmf_mmc_suspend) && retry++ != b) { \
|
||||
wait_event_timeout(a, false, HZ/100); \
|
||||
} \
|
||||
} while (0)
|
||||
#define BRCMF_PM_RESUME_WAIT(a) _BRCMF_PM_RESUME_WAIT(a, 30)
|
||||
#define BRCMF_PM_RESUME_RETURN_ERROR(a) \
|
||||
do { if (atomic_read(&brcmf_mmc_suspend)) return a; } while (0)
|
||||
|
||||
#define BRCMF_SPINWAIT_SLEEP_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a);
|
||||
#define BRCMF_SPINWAIT_SLEEP(a, exp, us) do { \
|
||||
uint countdown = (us) + 9999; \
|
||||
while ((exp) && (countdown >= 10000)) { \
|
||||
wait_event_timeout(a, false, HZ/100); \
|
||||
countdown -= 10000; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define BRCMF_PM_RESUME_WAIT_INIT(a)
|
||||
#define BRCMF_PM_RESUME_WAIT(a)
|
||||
#define BRCMF_PM_RESUME_RETURN_ERROR(a)
|
||||
|
||||
#define BRCMF_SPINWAIT_SLEEP_INIT(a)
|
||||
#define BRCMF_SPINWAIT_SLEEP(a, exp, us) do { \
|
||||
uint countdown = (us) + 9; \
|
||||
while ((exp) && (countdown >= 10)) { \
|
||||
udelay(10); \
|
||||
countdown -= 10; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif /* defined(CONFIG_PM_SLEEP) */
|
||||
|
||||
/*
|
||||
* Insmod parameters for debug/test
|
||||
*/
|
||||
|
||||
/* Use interrupts */
|
||||
extern uint brcmf_intr;
|
||||
|
||||
/* Use polling */
|
||||
extern uint brcmf_poll;
|
||||
|
||||
/* ARP offload agent mode */
|
||||
extern uint brcmf_arp_mode;
|
||||
|
||||
/* ARP offload enable */
|
||||
extern uint brcmf_arp_enable;
|
||||
|
||||
/* Pkt filte enable control */
|
||||
extern uint brcmf_pkt_filter_enable;
|
||||
|
||||
/* Pkt filter init setup */
|
||||
extern uint brcmf_pkt_filter_init;
|
||||
|
||||
/* Pkt filter mode control */
|
||||
extern uint brcmf_master_mode;
|
||||
|
||||
/* Roaming mode control */
|
||||
extern uint brcmf_roam;
|
||||
|
||||
/* Roaming mode control */
|
||||
extern uint brcmf_radio_up;
|
||||
|
||||
/* Initial idletime ticks (may be -1 for immediate idle, 0 for no idle) */
|
||||
extern int brcmf_idletime;
|
||||
#define BRCMF_IDLETIME_TICKS 1
|
||||
|
||||
/* SDIO Drive Strength */
|
||||
extern uint brcmf_sdiod_drive_strength;
|
||||
|
||||
/* Override to force tx queueing all the time */
|
||||
extern uint brcmf_force_tx_queueing;
|
||||
|
||||
#ifdef SDTEST
|
||||
/* Echo packet generator (SDIO), pkts/s */
|
||||
extern uint brcmf_pktgen;
|
||||
|
||||
/* Echo packet len (0 => sawtooth, max 1800) */
|
||||
extern uint brcmf_pktgen_len;
|
||||
#define BRCMF_MAX_PKTGEN_LEN 1800
|
||||
#endif
|
||||
|
||||
extern const struct bcmevent_name bcmevent_names[];
|
||||
extern const int bcmevent_names_size;
|
||||
|
||||
|
||||
static inline void MUTEX_LOCK_INIT(struct brcmf_pub *drvr)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void MUTEX_LOCK(struct brcmf_pub *drvr)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void MUTEX_UNLOCK(struct brcmf_pub *drvr)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void MUTEX_LOCK_SOFTAP_SET_INIT(struct brcmf_pub *drvr)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void MUTEX_LOCK_SOFTAP_SET(struct brcmf_pub *drvr)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void MUTEX_UNLOCK_SOFTAP_SET(struct brcmf_pub *drvr)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void MUTEX_LOCK_WL_SCAN_SET_INIT(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void MUTEX_LOCK_WL_SCAN_SET(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void MUTEX_UNLOCK_WL_SCAN_SET(void)
|
||||
{
|
||||
}
|
||||
|
||||
/* Indication from bus module regarding presence/insertion of dongle.
|
||||
* Return struct brcmf_pub pointer, used as handle to OS module in later calls.
|
||||
* Returned structure should have bus and prot pointers filled in.
|
||||
* bus_hdrlen specifies required headroom for bus module header.
|
||||
*/
|
||||
extern struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus,
|
||||
uint bus_hdrlen);
|
||||
extern int brcmf_net_attach(struct brcmf_pub *drvr, int idx);
|
||||
extern int brcmf_netdev_wait_pend8021x(struct net_device *dev);
|
||||
|
||||
/* Indication from bus module regarding removal/absence of dongle */
|
||||
extern void brcmf_detach(struct brcmf_pub *drvr);
|
||||
|
||||
/* Indication from bus module to change flow-control state */
|
||||
extern void brcmf_txflowcontrol(struct brcmf_pub *drvr, int ifidx, bool on);
|
||||
|
||||
extern bool brcmf_c_prec_enq(struct brcmf_pub *drvr, struct pktq *q,
|
||||
struct sk_buff *pkt, int prec);
|
||||
|
||||
/* Receive frame for delivery to OS. Callee disposes of rxp. */
|
||||
extern void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx,
|
||||
struct sk_buff *rxp, int numpkt);
|
||||
|
||||
/* Return pointer to interface name */
|
||||
extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
|
||||
|
||||
/* Notify tx completion */
|
||||
extern void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp,
|
||||
bool success);
|
||||
|
||||
/* Query ioctl */
|
||||
extern int brcmf_proto_cdc_query_ioctl(struct brcmf_pub *drvr, int ifidx,
|
||||
uint cmd, void *buf, uint len);
|
||||
|
||||
/* OS independent layer functions */
|
||||
extern int brcmf_os_proto_block(struct brcmf_pub *drvr);
|
||||
extern int brcmf_os_proto_unblock(struct brcmf_pub *drvr);
|
||||
extern int brcmf_os_ioctl_resp_wait(struct brcmf_pub *drvr, uint *condition,
|
||||
bool *pending);
|
||||
extern int brcmf_os_ioctl_resp_wake(struct brcmf_pub *drvr);
|
||||
extern unsigned int brcmf_os_get_ioctl_resp_timeout(void);
|
||||
extern void brcmf_os_set_ioctl_resp_timeout(unsigned int timeout_msec);
|
||||
#ifdef BCMDBG
|
||||
extern int brcmf_write_to_file(struct brcmf_pub *drvr, u8 *buf, int size);
|
||||
#endif /* BCMDBG */
|
||||
|
||||
extern void brcmf_timeout_start(struct brcmf_timeout *tmo, uint usec);
|
||||
extern int brcmf_timeout_expired(struct brcmf_timeout *tmo);
|
||||
|
||||
extern int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name);
|
||||
extern int brcmf_c_host_event(struct brcmf_info *drvr_priv, int *idx,
|
||||
void *pktdata, struct brcmf_event_msg *,
|
||||
void **data_ptr);
|
||||
|
||||
extern void brcmf_c_init(void);
|
||||
|
||||
extern int brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, void *handle,
|
||||
char *name, u8 *mac_addr, u32 flags, u8 bssidx);
|
||||
extern void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx);
|
||||
|
||||
/* Send packet to dongle via data channel */
|
||||
extern int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx,\
|
||||
struct sk_buff *pkt);
|
||||
|
||||
extern int brcmf_bus_devreset(struct brcmf_pub *drvr, u8 flag);
|
||||
extern int brcmf_bus_start(struct brcmf_pub *drvr);
|
||||
|
||||
extern void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg);
|
||||
extern void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg,
|
||||
int enable, int master_mode);
|
||||
|
||||
/* Linux network driver ioctl encoding */
|
||||
struct brcmf_c_ioctl {
|
||||
uint cmd; /* common ioctl definition */
|
||||
void *buf; /* pointer to user buffer */
|
||||
uint len; /* length of user buffer */
|
||||
bool set; /* get or set request (optional) */
|
||||
uint used; /* bytes read or written (optional) */
|
||||
uint needed; /* bytes needed (optional) */
|
||||
uint driver; /* to identify target driver */
|
||||
};
|
||||
|
||||
/* per-driver magic numbers */
|
||||
#define BRCMF_IOCTL_MAGIC 0x00444944
|
||||
|
||||
/* bump this number if you change the ioctl interface */
|
||||
#define BRCMF_IOCTL_VERSION 1
|
||||
#define BRCMF_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */
|
||||
|
||||
/* common ioctl definitions */
|
||||
#define BRCMF_GET_MAGIC 0
|
||||
#define BRCMF_GET_VERSION 1
|
||||
#define BRCMF_GET_VAR 2
|
||||
#define BRCMF_SET_VAR 3
|
||||
|
||||
/* message levels */
|
||||
#define BRCMF_ERROR_VAL 0x0001
|
||||
#define BRCMF_TRACE_VAL 0x0002
|
||||
#define BRCMF_INFO_VAL 0x0004
|
||||
#define BRCMF_DATA_VAL 0x0008
|
||||
#define BRCMF_CTL_VAL 0x0010
|
||||
#define BRCMF_TIMER_VAL 0x0020
|
||||
#define BRCMF_HDRS_VAL 0x0040
|
||||
#define BRCMF_BYTES_VAL 0x0080
|
||||
#define BRCMF_INTR_VAL 0x0100
|
||||
#define BRCMF_GLOM_VAL 0x0400
|
||||
#define BRCMF_EVENT_VAL 0x0800
|
||||
#define BRCMF_BTA_VAL 0x1000
|
||||
#define BRCMF_ISCAN_VAL 0x2000
|
||||
|
||||
#ifdef SDTEST
|
||||
/* For pktgen iovar */
|
||||
struct brcmf_pktgen {
|
||||
uint version; /* To allow structure change tracking */
|
||||
uint freq; /* Max ticks between tx/rx attempts */
|
||||
uint count; /* Test packets to send/rcv each attempt */
|
||||
uint print; /* Print counts every <print> attempts */
|
||||
uint total; /* Total packets (or bursts) */
|
||||
uint minlen; /* Minimum length of packets to send */
|
||||
uint maxlen; /* Maximum length of packets to send */
|
||||
uint numsent; /* Count of test packets sent */
|
||||
uint numrcvd; /* Count of test packets received */
|
||||
uint numfail; /* Count of test send failures */
|
||||
uint mode; /* Test mode (type of test packets) */
|
||||
uint stop; /* Stop after this many tx failures */
|
||||
};
|
||||
|
||||
/* Version in case structure changes */
|
||||
#define BRCMF_PKTGEN_VERSION 2
|
||||
|
||||
/* Type of test packets to use */
|
||||
#define BRCMF_PKTGEN_ECHO 1 /* Send echo requests */
|
||||
#define BRCMF_PKTGEN_SEND 2 /* Send discard packets */
|
||||
#define BRCMF_PKTGEN_RXBURST 3 /* Request dongle send N packets */
|
||||
#define BRCMF_PKTGEN_RECV 4 /* Continuous rx from continuous
|
||||
tx dongle */
|
||||
#endif /* SDTEST */
|
||||
|
||||
/* Enter idle immediately (no timeout) */
|
||||
#define BRCMF_IDLE_IMMEDIATE (-1)
|
||||
|
||||
/* Values for idleclock iovar: other values are the sd_divisor to use
|
||||
when idle */
|
||||
#define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change
|
||||
when idle */
|
||||
|
||||
#endif /* _BRCMF_H_ */
|
@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCMF_BUS_H_
|
||||
#define _BRCMF_BUS_H_
|
||||
|
||||
/* Packet alignment for most efficient SDIO (can change based on platform) */
|
||||
#ifndef BRCMF_SDALIGN
|
||||
#define BRCMF_SDALIGN 32
|
||||
#endif
|
||||
#if !ISPOWEROF2(BRCMF_SDALIGN)
|
||||
#error BRCMF_SDALIGN is not a power of 2!
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Exported from brcmf bus module (brcmf_usb, brcmf_sdio)
|
||||
*/
|
||||
|
||||
/* dongle ram module parameter */
|
||||
extern int brcmf_dongle_memsize;
|
||||
|
||||
/* Tx/Rx bounds module parameters */
|
||||
extern uint brcmf_txbound;
|
||||
extern uint brcmf_rxbound;
|
||||
|
||||
/* Watchdog timer interval */
|
||||
extern uint brcmf_watchdog_ms;
|
||||
|
||||
/* Indicate (dis)interest in finding dongles. */
|
||||
extern int brcmf_bus_register(void);
|
||||
extern void brcmf_bus_unregister(void);
|
||||
|
||||
/* Stop bus module: clear pending frames, disable data flow */
|
||||
extern void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus, bool enforce_mutex);
|
||||
|
||||
/* Initialize bus module: prepare for communication w/dongle */
|
||||
extern int brcmf_sdbrcm_bus_init(struct brcmf_pub *drvr, bool enforce_mutex);
|
||||
|
||||
/* Send a data frame to the dongle. Callee disposes of txp. */
|
||||
extern int brcmf_sdbrcm_bus_txdata(struct brcmf_bus *bus, struct sk_buff *txp);
|
||||
|
||||
/* Send/receive a control message to/from the dongle.
|
||||
* Expects caller to enforce a single outstanding transaction.
|
||||
*/
|
||||
extern int
|
||||
brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen);
|
||||
|
||||
extern int
|
||||
brcmf_sdbrcm_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen);
|
||||
|
||||
/* Check for and handle local prot-specific iovar commands */
|
||||
extern int brcmf_sdbrcm_bus_iovar_op(struct brcmf_pub *drvr, const char *name,
|
||||
void *params, int plen, void *arg, int len,
|
||||
bool set);
|
||||
|
||||
/* Add bus dump output to a buffer */
|
||||
extern void brcmf_sdbrcm_bus_dump(struct brcmf_pub *drvr,
|
||||
struct brcmu_strbuf *strbuf);
|
||||
|
||||
/* Clear any bus counters */
|
||||
extern void brcmf_bus_clearcounts(struct brcmf_pub *drvr);
|
||||
|
||||
extern void brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick);
|
||||
|
||||
#endif /* _BRCMF_BUS_H_ */
|
@ -1,502 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/sched.h>
|
||||
#include <defs.h>
|
||||
|
||||
#include <brcmu_utils.h>
|
||||
#include <brcmu_wifi.h>
|
||||
|
||||
#include "dhd.h"
|
||||
#include "dhd_proto.h"
|
||||
#include "dhd_bus.h"
|
||||
#include "dhd_dbg.h"
|
||||
|
||||
struct brcmf_proto_cdc_ioctl {
|
||||
u32 cmd; /* ioctl command value */
|
||||
u32 len; /* lower 16: output buflen;
|
||||
* upper 16: input buflen (excludes header) */
|
||||
u32 flags; /* flag defns given below */
|
||||
u32 status; /* status code returned from the device */
|
||||
};
|
||||
|
||||
/* Max valid buffer size that can be sent to the dongle */
|
||||
#define CDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN)
|
||||
|
||||
/* CDC flag definitions */
|
||||
#define CDCF_IOC_ERROR 0x01 /* 1=ioctl cmd failed */
|
||||
#define CDCF_IOC_SET 0x02 /* 0=get, 1=set cmd */
|
||||
#define CDCF_IOC_IF_MASK 0xF000 /* I/F index */
|
||||
#define CDCF_IOC_IF_SHIFT 12
|
||||
#define CDCF_IOC_ID_MASK 0xFFFF0000 /* id an ioctl pairing */
|
||||
#define CDCF_IOC_ID_SHIFT 16 /* ID Mask shift bits */
|
||||
#define CDC_IOC_ID(flags) \
|
||||
(((flags) & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT)
|
||||
#define CDC_SET_IF_IDX(hdr, idx) \
|
||||
((hdr)->flags = (((hdr)->flags & ~CDCF_IOC_IF_MASK) | \
|
||||
((idx) << CDCF_IOC_IF_SHIFT)))
|
||||
|
||||
/*
|
||||
* BDC header - Broadcom specific extension of CDC.
|
||||
* Used on data packets to convey priority across USB.
|
||||
*/
|
||||
#define BDC_HEADER_LEN 4
|
||||
#define BDC_PROTO_VER 1 /* Protocol version */
|
||||
#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */
|
||||
#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */
|
||||
#define BDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */
|
||||
#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */
|
||||
#define BDC_PRIORITY_MASK 0x7
|
||||
#define BDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */
|
||||
#define BDC_FLAG2_IF_SHIFT 0
|
||||
|
||||
#define BDC_GET_IF_IDX(hdr) \
|
||||
((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT))
|
||||
#define BDC_SET_IF_IDX(hdr, idx) \
|
||||
((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \
|
||||
((idx) << BDC_FLAG2_IF_SHIFT)))
|
||||
|
||||
struct brcmf_proto_bdc_header {
|
||||
u8 flags;
|
||||
u8 priority; /* 802.1d Priority, 4:7 flow control info for usb */
|
||||
u8 flags2;
|
||||
u8 rssi;
|
||||
};
|
||||
|
||||
|
||||
#define RETRIES 2 /* # of retries to retrieve matching ioctl response */
|
||||
#define BUS_HEADER_LEN (16+BRCMF_SDALIGN) /* Must be atleast SDPCM_RESERVE
|
||||
* (amount of header tha might be added)
|
||||
* plus any space that might be needed
|
||||
* for alignment padding.
|
||||
*/
|
||||
#define ROUND_UP_MARGIN 2048 /* Biggest SDIO block size possible for
|
||||
* round off at the end of buffer
|
||||
*/
|
||||
|
||||
struct brcmf_proto {
|
||||
u16 reqid;
|
||||
u8 pending;
|
||||
u32 lastcmd;
|
||||
u8 bus_header[BUS_HEADER_LEN];
|
||||
struct brcmf_proto_cdc_ioctl msg;
|
||||
unsigned char buf[BRCMF_C_IOCTL_MAXLEN + ROUND_UP_MARGIN];
|
||||
};
|
||||
|
||||
static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct brcmf_proto *prot = drvr->prot;
|
||||
int len = le32_to_cpu(prot->msg.len) +
|
||||
sizeof(struct brcmf_proto_cdc_ioctl);
|
||||
|
||||
BRCMF_TRACE(("%s: Enter\n", __func__));
|
||||
|
||||
/* NOTE : cdc->msg.len holds the desired length of the buffer to be
|
||||
* returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
|
||||
* is actually sent to the dongle
|
||||
*/
|
||||
if (len > CDC_MAX_MSG_SIZE)
|
||||
len = CDC_MAX_MSG_SIZE;
|
||||
|
||||
/* Send request */
|
||||
return brcmf_sdbrcm_bus_txctl(drvr->bus, (unsigned char *)&prot->msg,
|
||||
len);
|
||||
}
|
||||
|
||||
static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
|
||||
{
|
||||
int ret;
|
||||
struct brcmf_proto *prot = drvr->prot;
|
||||
|
||||
BRCMF_TRACE(("%s: Enter\n", __func__));
|
||||
|
||||
do {
|
||||
ret = brcmf_sdbrcm_bus_rxctl(drvr->bus,
|
||||
(unsigned char *)&prot->msg,
|
||||
len + sizeof(struct brcmf_proto_cdc_ioctl));
|
||||
if (ret < 0)
|
||||
break;
|
||||
} while (CDC_IOC_ID(le32_to_cpu(prot->msg.flags)) != id);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
brcmf_proto_cdc_query_ioctl(struct brcmf_pub *drvr, int ifidx, uint cmd,
|
||||
void *buf, uint len)
|
||||
{
|
||||
struct brcmf_proto *prot = drvr->prot;
|
||||
struct brcmf_proto_cdc_ioctl *msg = &prot->msg;
|
||||
void *info;
|
||||
int ret = 0, retries = 0;
|
||||
u32 id, flags = 0;
|
||||
|
||||
BRCMF_TRACE(("%s: Enter\n", __func__));
|
||||
BRCMF_CTL(("%s: cmd %d len %d\n", __func__, cmd, len));
|
||||
|
||||
/* Respond "bcmerror" and "bcmerrorstr" with local cache */
|
||||
if (cmd == BRCMF_C_GET_VAR && buf) {
|
||||
if (!strcmp((char *)buf, "bcmerrorstr")) {
|
||||
strncpy((char *)buf, "bcm_error",
|
||||
BCME_STRLEN);
|
||||
goto done;
|
||||
} else if (!strcmp((char *)buf, "bcmerror")) {
|
||||
*(int *)buf = drvr->dongle_error;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
memset(msg, 0, sizeof(struct brcmf_proto_cdc_ioctl));
|
||||
|
||||
msg->cmd = cpu_to_le32(cmd);
|
||||
msg->len = cpu_to_le32(len);
|
||||
msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT);
|
||||
CDC_SET_IF_IDX(msg, ifidx);
|
||||
msg->flags = cpu_to_le32(msg->flags);
|
||||
|
||||
if (buf)
|
||||
memcpy(prot->buf, buf, len);
|
||||
|
||||
ret = brcmf_proto_cdc_msg(drvr);
|
||||
if (ret < 0) {
|
||||
BRCMF_ERROR(("brcmf_proto_cdc_query_ioctl: brcmf_proto_cdc_msg "
|
||||
"failed w/status %d\n", ret));
|
||||
goto done;
|
||||
}
|
||||
|
||||
retry:
|
||||
/* wait for interrupt and get first fragment */
|
||||
ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
|
||||
flags = le32_to_cpu(msg->flags);
|
||||
id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT;
|
||||
|
||||
if ((id < prot->reqid) && (++retries < RETRIES))
|
||||
goto retry;
|
||||
if (id != prot->reqid) {
|
||||
BRCMF_ERROR(("%s: %s: unexpected request id %d (expected %d)\n",
|
||||
brcmf_ifname(drvr, ifidx), __func__, id,
|
||||
prot->reqid));
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Check info buffer */
|
||||
info = (void *)&msg[1];
|
||||
|
||||
/* Copy info buffer */
|
||||
if (buf) {
|
||||
if (ret < (int)len)
|
||||
len = ret;
|
||||
memcpy(buf, info, len);
|
||||
}
|
||||
|
||||
/* Check the ERROR flag */
|
||||
if (flags & CDCF_IOC_ERROR) {
|
||||
ret = le32_to_cpu(msg->status);
|
||||
/* Cache error from dongle */
|
||||
drvr->dongle_error = ret;
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int brcmf_proto_cdc_set_ioctl(struct brcmf_pub *drvr, int ifidx, uint cmd,
|
||||
void *buf, uint len)
|
||||
{
|
||||
struct brcmf_proto *prot = drvr->prot;
|
||||
struct brcmf_proto_cdc_ioctl *msg = &prot->msg;
|
||||
int ret = 0;
|
||||
u32 flags, id;
|
||||
|
||||
BRCMF_TRACE(("%s: Enter\n", __func__));
|
||||
BRCMF_CTL(("%s: cmd %d len %d\n", __func__, cmd, len));
|
||||
|
||||
memset(msg, 0, sizeof(struct brcmf_proto_cdc_ioctl));
|
||||
|
||||
msg->cmd = cpu_to_le32(cmd);
|
||||
msg->len = cpu_to_le32(len);
|
||||
msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT) | CDCF_IOC_SET;
|
||||
CDC_SET_IF_IDX(msg, ifidx);
|
||||
msg->flags = cpu_to_le32(msg->flags);
|
||||
|
||||
if (buf)
|
||||
memcpy(prot->buf, buf, len);
|
||||
|
||||
ret = brcmf_proto_cdc_msg(drvr);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
|
||||
ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
|
||||
flags = le32_to_cpu(msg->flags);
|
||||
id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT;
|
||||
|
||||
if (id != prot->reqid) {
|
||||
BRCMF_ERROR(("%s: %s: unexpected request id %d (expected %d)\n",
|
||||
brcmf_ifname(drvr, ifidx), __func__, id,
|
||||
prot->reqid));
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Check the ERROR flag */
|
||||
if (flags & CDCF_IOC_ERROR) {
|
||||
ret = le32_to_cpu(msg->status);
|
||||
/* Cache error from dongle */
|
||||
drvr->dongle_error = ret;
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
brcmf_proto_ioctl(struct brcmf_pub *drvr, int ifidx, struct brcmf_ioctl *ioc,
|
||||
void *buf, int len)
|
||||
{
|
||||
struct brcmf_proto *prot = drvr->prot;
|
||||
int ret = -1;
|
||||
|
||||
if (drvr->busstate == BRCMF_BUS_DOWN) {
|
||||
BRCMF_ERROR(("%s : bus is down. we have nothing to do\n",
|
||||
__func__));
|
||||
return ret;
|
||||
}
|
||||
brcmf_os_proto_block(drvr);
|
||||
|
||||
BRCMF_TRACE(("%s: Enter\n", __func__));
|
||||
|
||||
if (len > BRCMF_C_IOCTL_MAXLEN)
|
||||
goto done;
|
||||
|
||||
if (prot->pending == true) {
|
||||
BRCMF_TRACE(("CDC packet is pending!!!! cmd=0x%x (%lu) "
|
||||
"lastcmd=0x%x (%lu)\n",
|
||||
ioc->cmd, (unsigned long)ioc->cmd, prot->lastcmd,
|
||||
(unsigned long)prot->lastcmd));
|
||||
if ((ioc->cmd == BRCMF_C_SET_VAR) ||
|
||||
(ioc->cmd == BRCMF_C_GET_VAR))
|
||||
BRCMF_TRACE(("iovar cmd=%s\n", (char *)buf));
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
prot->pending = true;
|
||||
prot->lastcmd = ioc->cmd;
|
||||
if (ioc->set)
|
||||
ret = brcmf_proto_cdc_set_ioctl(drvr, ifidx, ioc->cmd,
|
||||
buf, len);
|
||||
else {
|
||||
ret = brcmf_proto_cdc_query_ioctl(drvr, ifidx, ioc->cmd,
|
||||
buf, len);
|
||||
if (ret > 0)
|
||||
ioc->used = ret - sizeof(struct brcmf_proto_cdc_ioctl);
|
||||
}
|
||||
|
||||
/* Too many programs assume ioctl() returns 0 on success */
|
||||
if (ret >= 0)
|
||||
ret = 0;
|
||||
else {
|
||||
struct brcmf_proto_cdc_ioctl *msg = &prot->msg;
|
||||
/* len == needed when set/query fails from dongle */
|
||||
ioc->needed = le32_to_cpu(msg->len);
|
||||
}
|
||||
|
||||
/* Intercept the wme_dp ioctl here */
|
||||
if (!ret && ioc->cmd == BRCMF_C_SET_VAR &&
|
||||
!strcmp(buf, "wme_dp")) {
|
||||
int slen, val = 0;
|
||||
|
||||
slen = strlen("wme_dp") + 1;
|
||||
if (len >= (int)(slen + sizeof(int)))
|
||||
memcpy(&val, (char *)buf + slen, sizeof(int));
|
||||
drvr->wme_dp = (u8) le32_to_cpu(val);
|
||||
}
|
||||
|
||||
prot->pending = false;
|
||||
|
||||
done:
|
||||
brcmf_os_proto_unblock(drvr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define PKTSUMNEEDED(skb) \
|
||||
(((struct sk_buff *)(skb))->ip_summed == CHECKSUM_PARTIAL)
|
||||
#define PKTSETSUMGOOD(skb, x) \
|
||||
(((struct sk_buff *)(skb))->ip_summed = \
|
||||
((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE))
|
||||
|
||||
void brcmf_proto_dump(struct brcmf_pub *drvr, struct brcmu_strbuf *strbuf)
|
||||
{
|
||||
brcmu_bprintf(strbuf, "Protocol CDC: reqid %d\n", drvr->prot->reqid);
|
||||
}
|
||||
|
||||
void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
|
||||
struct sk_buff *pktbuf)
|
||||
{
|
||||
struct brcmf_proto_bdc_header *h;
|
||||
|
||||
BRCMF_TRACE(("%s: Enter\n", __func__));
|
||||
|
||||
/* Push BDC header used to convey priority for buses that don't */
|
||||
|
||||
skb_push(pktbuf, BDC_HEADER_LEN);
|
||||
|
||||
h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
|
||||
|
||||
h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
|
||||
if (PKTSUMNEEDED(pktbuf))
|
||||
h->flags |= BDC_FLAG_SUM_NEEDED;
|
||||
|
||||
h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
|
||||
h->flags2 = 0;
|
||||
h->rssi = 0;
|
||||
BDC_SET_IF_IDX(h, ifidx);
|
||||
}
|
||||
|
||||
int brcmf_proto_hdrpull(struct brcmf_pub *drvr, int *ifidx,
|
||||
struct sk_buff *pktbuf)
|
||||
{
|
||||
struct brcmf_proto_bdc_header *h;
|
||||
|
||||
BRCMF_TRACE(("%s: Enter\n", __func__));
|
||||
|
||||
/* Pop BDC header used to convey priority for buses that don't */
|
||||
|
||||
if (pktbuf->len < BDC_HEADER_LEN) {
|
||||
BRCMF_ERROR(("%s: rx data too short (%d < %d)\n", __func__,
|
||||
pktbuf->len, BDC_HEADER_LEN));
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
|
||||
|
||||
*ifidx = BDC_GET_IF_IDX(h);
|
||||
if (*ifidx >= BRCMF_MAX_IFS) {
|
||||
BRCMF_ERROR(("%s: rx data ifnum out of range (%d)\n",
|
||||
__func__, *ifidx));
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) !=
|
||||
BDC_PROTO_VER) {
|
||||
BRCMF_ERROR(("%s: non-BDC packet received, flags 0x%x\n",
|
||||
brcmf_ifname(drvr, *ifidx), h->flags));
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
if (h->flags & BDC_FLAG_SUM_GOOD) {
|
||||
BRCMF_INFO(("%s: BDC packet received with good rx-csum, "
|
||||
"flags 0x%x\n",
|
||||
brcmf_ifname(drvr, *ifidx), h->flags));
|
||||
PKTSETSUMGOOD(pktbuf, true);
|
||||
}
|
||||
|
||||
pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
|
||||
|
||||
skb_pull(pktbuf, BDC_HEADER_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int brcmf_proto_attach(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct brcmf_proto *cdc;
|
||||
|
||||
cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC);
|
||||
if (!cdc) {
|
||||
BRCMF_ERROR(("%s: kmalloc failed\n", __func__));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* ensure that the msg buf directly follows the cdc msg struct */
|
||||
if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) {
|
||||
BRCMF_ERROR(("struct brcmf_proto is not correctly defined\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
drvr->prot = cdc;
|
||||
drvr->hdrlen += BDC_HEADER_LEN;
|
||||
drvr->maxctl = BRCMF_C_IOCTL_MAXLEN +
|
||||
sizeof(struct brcmf_proto_cdc_ioctl) + ROUND_UP_MARGIN;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
kfree(cdc);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */
|
||||
void brcmf_proto_detach(struct brcmf_pub *drvr)
|
||||
{
|
||||
kfree(drvr->prot);
|
||||
drvr->prot = NULL;
|
||||
}
|
||||
|
||||
void brcmf_proto_dstats(struct brcmf_pub *drvr)
|
||||
{
|
||||
/* No stats from dongle added yet, copy bus stats */
|
||||
drvr->dstats.tx_packets = drvr->tx_packets;
|
||||
drvr->dstats.tx_errors = drvr->tx_errors;
|
||||
drvr->dstats.rx_packets = drvr->rx_packets;
|
||||
drvr->dstats.rx_errors = drvr->rx_errors;
|
||||
drvr->dstats.rx_dropped = drvr->rx_dropped;
|
||||
drvr->dstats.multicast = drvr->rx_multicast;
|
||||
return;
|
||||
}
|
||||
|
||||
int brcmf_proto_init(struct brcmf_pub *drvr)
|
||||
{
|
||||
int ret = 0;
|
||||
char buf[128];
|
||||
|
||||
BRCMF_TRACE(("%s: Enter\n", __func__));
|
||||
|
||||
brcmf_os_proto_block(drvr);
|
||||
|
||||
/* Get the device MAC address */
|
||||
strcpy(buf, "cur_etheraddr");
|
||||
ret = brcmf_proto_cdc_query_ioctl(drvr, 0, BRCMF_C_GET_VAR,
|
||||
buf, sizeof(buf));
|
||||
if (ret < 0) {
|
||||
brcmf_os_proto_unblock(drvr);
|
||||
return ret;
|
||||
}
|
||||
memcpy(drvr->mac, buf, ETH_ALEN);
|
||||
|
||||
brcmf_os_proto_unblock(drvr);
|
||||
|
||||
ret = brcmf_c_preinit_ioctls(drvr);
|
||||
|
||||
/* Always assumes wl for now */
|
||||
drvr->iswl = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void brcmf_proto_stop(struct brcmf_pub *drvr)
|
||||
{
|
||||
/* Nothing to do for CDC */
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCMF_DBG_H_
|
||||
#define _BRCMF_DBG_H_
|
||||
|
||||
#if defined(BCMDBG)
|
||||
|
||||
#define BRCMF_ERROR(args) \
|
||||
do {if ((brcmf_msg_level & BRCMF_ERROR_VAL) && (net_ratelimit())) \
|
||||
printk args; } while (0)
|
||||
#define BRCMF_TRACE(args) do {if (brcmf_msg_level & BRCMF_TRACE_VAL) \
|
||||
printk args; } while (0)
|
||||
#define BRCMF_INFO(args) do {if (brcmf_msg_level & BRCMF_INFO_VAL) \
|
||||
printk args; } while (0)
|
||||
#define BRCMF_DATA(args) do {if (brcmf_msg_level & BRCMF_DATA_VAL) \
|
||||
printk args; } while (0)
|
||||
#define BRCMF_CTL(args) do {if (brcmf_msg_level & BRCMF_CTL_VAL) \
|
||||
printk args; } while (0)
|
||||
#define BRCMF_TIMER(args) do {if (brcmf_msg_level & BRCMF_TIMER_VAL) \
|
||||
printk args; } while (0)
|
||||
#define BRCMF_INTR(args) do {if (brcmf_msg_level & BRCMF_INTR_VAL) \
|
||||
printk args; } while (0)
|
||||
#define BRCMF_GLOM(args) do {if (brcmf_msg_level & BRCMF_GLOM_VAL) \
|
||||
printk args; } while (0)
|
||||
#define BRCMF_EVENT(args) do {if (brcmf_msg_level & BRCMF_EVENT_VAL) \
|
||||
printk args; } while (0)
|
||||
|
||||
#define BRCMF_DATA_ON() (brcmf_msg_level & BRCMF_DATA_VAL)
|
||||
#define BRCMF_CTL_ON() (brcmf_msg_level & BRCMF_CTL_VAL)
|
||||
#define BRCMF_HDRS_ON() (brcmf_msg_level & BRCMF_HDRS_VAL)
|
||||
#define BRCMF_BYTES_ON() (brcmf_msg_level & BRCMF_BYTES_VAL)
|
||||
#define BRCMF_GLOM_ON() (brcmf_msg_level & BRCMF_GLOM_VAL)
|
||||
|
||||
#else /* (defined BCMDBG) || (defined BCMDBG) */
|
||||
|
||||
#define BRCMF_ERROR(args) do {if (net_ratelimit()) printk args; } while (0)
|
||||
#define BRCMF_TRACE(args)
|
||||
#define BRCMF_INFO(args)
|
||||
#define BRCMF_DATA(args)
|
||||
#define BRCMF_CTL(args)
|
||||
#define BRCMF_TIMER(args)
|
||||
#define BRCMF_INTR(args)
|
||||
#define BRCMF_GLOM(args)
|
||||
#define BRCMF_EVENT(args)
|
||||
|
||||
#define BRCMF_DATA_ON() 0
|
||||
#define BRCMF_CTL_ON() 0
|
||||
#define BRCMF_HDRS_ON() 0
|
||||
#define BRCMF_BYTES_ON() 0
|
||||
#define BRCMF_GLOM_ON() 0
|
||||
|
||||
#endif /* defined(BCMDBG) */
|
||||
|
||||
extern int brcmf_msg_level;
|
||||
|
||||
#endif /* _BRCMF_DBG_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCMF_PROTO_H_
|
||||
#define _BRCMF_PROTO_H_
|
||||
|
||||
#ifndef IOCTL_RESP_TIMEOUT
|
||||
#define IOCTL_RESP_TIMEOUT 2000 /* In milli second */
|
||||
#endif
|
||||
|
||||
#ifndef IOCTL_CHIP_ACTIVE_TIMEOUT
|
||||
#define IOCTL_CHIP_ACTIVE_TIMEOUT 10 /* In milli second */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Exported from the brcmf protocol module (brcmf_cdc)
|
||||
*/
|
||||
|
||||
/* Linkage, sets prot link and updates hdrlen in pub */
|
||||
extern int brcmf_proto_attach(struct brcmf_pub *drvr);
|
||||
|
||||
/* Unlink, frees allocated protocol memory (including brcmf_proto) */
|
||||
extern void brcmf_proto_detach(struct brcmf_pub *drvr);
|
||||
|
||||
/* Initialize protocol: sync w/dongle state.
|
||||
* Sets dongle media info (iswl, drv_version, mac address).
|
||||
*/
|
||||
extern int brcmf_proto_init(struct brcmf_pub *drvr);
|
||||
|
||||
/* Stop protocol: sync w/dongle state. */
|
||||
extern void brcmf_proto_stop(struct brcmf_pub *drvr);
|
||||
|
||||
/* Add any protocol-specific data header.
|
||||
* Caller must reserve prot_hdrlen prepend space.
|
||||
*/
|
||||
extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx,
|
||||
struct sk_buff *txp);
|
||||
|
||||
/* Remove any protocol-specific data header. */
|
||||
extern int brcmf_proto_hdrpull(struct brcmf_pub *, int *ifidx,
|
||||
struct sk_buff *rxp);
|
||||
|
||||
/* Use protocol to issue ioctl to dongle */
|
||||
extern int brcmf_proto_ioctl(struct brcmf_pub *drvr, int ifidx,
|
||||
struct brcmf_ioctl *ioc, void *buf, int len);
|
||||
|
||||
/* Add prot dump output to a buffer */
|
||||
extern void brcmf_proto_dump(struct brcmf_pub *drvr,
|
||||
struct brcmu_strbuf *strbuf);
|
||||
|
||||
/* Update local copy of dongle statistics */
|
||||
extern void brcmf_proto_dstats(struct brcmf_pub *drvr);
|
||||
|
||||
extern int brcmf_c_ioctl(struct brcmf_pub *drvr, struct brcmf_c_ioctl *ioc,
|
||||
void *buf, uint buflen);
|
||||
|
||||
extern int brcmf_c_preinit_ioctls(struct brcmf_pub *drvr);
|
||||
|
||||
extern int brcmf_proto_cdc_set_ioctl(struct brcmf_pub *drvr, int ifidx,
|
||||
uint cmd, void *buf, uint len);
|
||||
|
||||
#endif /* _BRCMF_PROTO_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,347 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_SDH_H_
|
||||
#define _BRCM_SDH_H_
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
extern const uint brcmf_sdio_msglevel;
|
||||
|
||||
#define SDIO_FUNC_0 0
|
||||
#define SDIO_FUNC_1 1
|
||||
#define SDIO_FUNC_2 2
|
||||
|
||||
#define SDIOD_FBR_SIZE 0x100
|
||||
|
||||
/* io_en */
|
||||
#define SDIO_FUNC_ENABLE_1 0x02
|
||||
#define SDIO_FUNC_ENABLE_2 0x04
|
||||
|
||||
/* io_rdys */
|
||||
#define SDIO_FUNC_READY_1 0x02
|
||||
#define SDIO_FUNC_READY_2 0x04
|
||||
|
||||
/* intr_status */
|
||||
#define INTR_STATUS_FUNC1 0x2
|
||||
#define INTR_STATUS_FUNC2 0x4
|
||||
|
||||
/* Maximum number of I/O funcs */
|
||||
#define SDIOD_MAX_IOFUNCS 7
|
||||
|
||||
#define SBSDIO_NUM_FUNCTION 3 /* as of sdiod rev 0, supports 3 functions */
|
||||
|
||||
/* function 1 miscellaneous registers */
|
||||
#define SBSDIO_SPROM_CS 0x10000 /* sprom command and status */
|
||||
#define SBSDIO_SPROM_INFO 0x10001 /* sprom info register */
|
||||
#define SBSDIO_SPROM_DATA_LOW 0x10002 /* sprom indirect access data byte 0 */
|
||||
#define SBSDIO_SPROM_DATA_HIGH 0x10003 /* sprom indirect access data byte 1 */
|
||||
#define SBSDIO_SPROM_ADDR_LOW 0x10004 /* sprom indirect access addr byte 0 */
|
||||
#define SBSDIO_SPROM_ADDR_HIGH 0x10005 /* sprom indirect access addr byte 0 */
|
||||
#define SBSDIO_CHIP_CTRL_DATA 0x10006 /* xtal_pu (gpio) output */
|
||||
#define SBSDIO_CHIP_CTRL_EN 0x10007 /* xtal_pu (gpio) enable */
|
||||
#define SBSDIO_WATERMARK 0x10008 /* rev < 7, watermark for sdio device */
|
||||
#define SBSDIO_DEVICE_CTL 0x10009 /* control busy signal generation */
|
||||
|
||||
/* registers introduced in rev 8, some content (mask/bits) defs in sbsdpcmdev.h */
|
||||
#define SBSDIO_FUNC1_SBADDRLOW 0x1000A /* SB Address Window Low (b15) */
|
||||
#define SBSDIO_FUNC1_SBADDRMID 0x1000B /* SB Address Window Mid (b23:b16) */
|
||||
#define SBSDIO_FUNC1_SBADDRHIGH 0x1000C /* SB Address Window High (b31:b24) */
|
||||
#define SBSDIO_FUNC1_FRAMECTRL 0x1000D /* Frame Control (frame term/abort) */
|
||||
#define SBSDIO_FUNC1_CHIPCLKCSR 0x1000E /* ChipClockCSR (ALP/HT ctl/status) */
|
||||
#define SBSDIO_FUNC1_SDIOPULLUP 0x1000F /* SdioPullUp (on cmd, d0-d2) */
|
||||
#define SBSDIO_FUNC1_WFRAMEBCLO 0x10019 /* Write Frame Byte Count Low */
|
||||
#define SBSDIO_FUNC1_WFRAMEBCHI 0x1001A /* Write Frame Byte Count High */
|
||||
#define SBSDIO_FUNC1_RFRAMEBCLO 0x1001B /* Read Frame Byte Count Low */
|
||||
#define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C /* Read Frame Byte Count High */
|
||||
|
||||
#define SBSDIO_FUNC1_MISC_REG_START 0x10000 /* f1 misc register start */
|
||||
#define SBSDIO_FUNC1_MISC_REG_LIMIT 0x1001C /* f1 misc register end */
|
||||
|
||||
/* function 1 OCP space */
|
||||
#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF /* sb offset addr is <= 15 bits, 32k */
|
||||
#define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000
|
||||
#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000 /* with b15, maps to 32-bit SB access */
|
||||
|
||||
/* some duplication with sbsdpcmdev.h here */
|
||||
/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
|
||||
#define SBSDIO_SBADDRLOW_MASK 0x80 /* Valid bits in SBADDRLOW */
|
||||
#define SBSDIO_SBADDRMID_MASK 0xff /* Valid bits in SBADDRMID */
|
||||
#define SBSDIO_SBADDRHIGH_MASK 0xffU /* Valid bits in SBADDRHIGH */
|
||||
#define SBSDIO_SBWINDOW_MASK 0xffff8000 /* Address bits from SBADDR regs */
|
||||
|
||||
#define SDIOH_READ 0 /* Read request */
|
||||
#define SDIOH_WRITE 1 /* Write request */
|
||||
|
||||
#define SDIOH_DATA_FIX 0 /* Fixed addressing */
|
||||
#define SDIOH_DATA_INC 1 /* Incremental addressing */
|
||||
|
||||
/* internal return code */
|
||||
#define SUCCESS 0
|
||||
#define ERROR 1
|
||||
|
||||
/* forward declarations */
|
||||
struct brcmf_sdio_card;
|
||||
|
||||
struct brcmf_sdreg {
|
||||
int func;
|
||||
int offset;
|
||||
int value;
|
||||
};
|
||||
|
||||
struct sdioh_info {
|
||||
struct osl_info *osh; /* osh handler */
|
||||
bool client_intr_enabled; /* interrupt connnected flag */
|
||||
bool intr_handler_valid; /* client driver interrupt handler valid */
|
||||
void (*intr_handler)(void *); /* registered interrupt handler */
|
||||
void *intr_handler_arg; /* argument to call interrupt handler */
|
||||
u16 intmask; /* Current active interrupts */
|
||||
void *sdos_info; /* Pointer to per-OS private data */
|
||||
|
||||
uint irq; /* Client irq */
|
||||
int intrcount; /* Client interrupts */
|
||||
bool sd_blockmode; /* sd_blockmode == false => 64 Byte Cmd 53s. */
|
||||
/* Must be on for sd_multiblock to be effective */
|
||||
bool use_client_ints; /* If this is false, make sure to restore */
|
||||
int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */
|
||||
u8 num_funcs; /* Supported funcs on client */
|
||||
u32 com_cis_ptr;
|
||||
u32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
|
||||
uint max_dma_len;
|
||||
uint max_dma_descriptors; /* DMA Descriptors supported by this controller. */
|
||||
/* SDDMA_DESCRIPTOR SGList[32]; *//* Scatter/Gather DMA List */
|
||||
};
|
||||
|
||||
struct brcmf_sdmmc_instance {
|
||||
struct sdioh_info *sd;
|
||||
struct sdio_func *func[SDIOD_MAX_IOFUNCS];
|
||||
u32 host_claimed;
|
||||
};
|
||||
|
||||
/* Attach and build an interface to the underlying SD host driver.
|
||||
* - Allocates resources (structs, arrays, mem, OS handles, etc) needed by
|
||||
* brcmf_sdcard.
|
||||
* - Returns the sdio card handle and virtual address base for register access.
|
||||
* The returned handle should be used in all subsequent calls, but the bcmsh
|
||||
* implementation may maintain a single "default" handle (e.g. the first or
|
||||
* most recent one) to enable single-instance implementations to pass NULL.
|
||||
*/
|
||||
extern struct brcmf_sdio_card*
|
||||
brcmf_sdcard_attach(void *cfghdl, u32 *regsva, uint irq);
|
||||
|
||||
/* Detach - freeup resources allocated in attach */
|
||||
extern int brcmf_sdcard_detach(struct brcmf_sdio_card *card);
|
||||
|
||||
/* Enable/disable SD interrupt */
|
||||
extern int brcmf_sdcard_intr_enable(struct brcmf_sdio_card *card);
|
||||
extern int brcmf_sdcard_intr_disable(struct brcmf_sdio_card *card);
|
||||
|
||||
/* Register/deregister device interrupt handler. */
|
||||
extern int
|
||||
brcmf_sdcard_intr_reg(struct brcmf_sdio_card *card,
|
||||
void (*fn)(void *), void *argh);
|
||||
|
||||
extern int brcmf_sdcard_intr_dereg(struct brcmf_sdio_card *card);
|
||||
|
||||
/* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface).
|
||||
* fn: function number
|
||||
* addr: unmodified SDIO-space address
|
||||
* data: data byte to write
|
||||
* err: pointer to error code (or NULL)
|
||||
*/
|
||||
extern u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_card *card, uint func,
|
||||
u32 addr, int *err);
|
||||
extern void brcmf_sdcard_cfg_write(struct brcmf_sdio_card *card, uint func,
|
||||
u32 addr, u8 data, int *err);
|
||||
|
||||
/* Read/Write 4bytes from/to cfg space */
|
||||
extern u32
|
||||
brcmf_sdcard_cfg_read_word(struct brcmf_sdio_card *card, uint fnc_num,
|
||||
u32 addr, int *err);
|
||||
|
||||
extern void brcmf_sdcard_cfg_write_word(struct brcmf_sdio_card *card,
|
||||
uint fnc_num, u32 addr,
|
||||
u32 data, int *err);
|
||||
|
||||
/* Read CIS content for specified function.
|
||||
* fn: function whose CIS is being requested (0 is common CIS)
|
||||
* cis: pointer to memory location to place results
|
||||
* length: number of bytes to read
|
||||
* Internally, this routine uses the values from the cis base regs (0x9-0xB)
|
||||
* to form an SDIO-space address to read the data from.
|
||||
*/
|
||||
extern int brcmf_sdcard_cis_read(struct brcmf_sdio_card *card, uint func,
|
||||
u8 *cis, uint length);
|
||||
|
||||
/* Synchronous access to device (client) core registers via CMD53 to F1.
|
||||
* addr: backplane address (i.e. >= regsva from attach)
|
||||
* size: register width in bytes (2 or 4)
|
||||
* data: data for register write
|
||||
*/
|
||||
extern u32
|
||||
brcmf_sdcard_reg_read(struct brcmf_sdio_card *card, u32 addr, uint size);
|
||||
|
||||
extern u32
|
||||
brcmf_sdcard_reg_write(struct brcmf_sdio_card *card, u32 addr, uint size,
|
||||
u32 data);
|
||||
|
||||
/* Indicate if last reg read/write failed */
|
||||
extern bool brcmf_sdcard_regfail(struct brcmf_sdio_card *card);
|
||||
|
||||
/* Buffer transfer to/from device (client) core via cmd53.
|
||||
* fn: function number
|
||||
* addr: backplane address (i.e. >= regsva from attach)
|
||||
* flags: backplane width, address increment, sync/async
|
||||
* buf: pointer to memory data buffer
|
||||
* nbytes: number of bytes to transfer to/from buf
|
||||
* pkt: pointer to packet associated with buf (if any)
|
||||
* complete: callback function for command completion (async only)
|
||||
* handle: handle for completion callback (first arg in callback)
|
||||
* Returns 0 or error code.
|
||||
* NOTE: Async operation is not currently supported.
|
||||
*/
|
||||
extern int
|
||||
brcmf_sdcard_send_buf(struct brcmf_sdio_card *card, u32 addr, uint fn,
|
||||
uint flags, u8 *buf, uint nbytes, void *pkt,
|
||||
void (*complete)(void *handle, int status,
|
||||
bool sync_waiting),
|
||||
void *handle);
|
||||
extern int
|
||||
brcmf_sdcard_recv_buf(struct brcmf_sdio_card *card, u32 addr, uint fn,
|
||||
uint flags, u8 *buf, uint nbytes, struct sk_buff *pkt,
|
||||
void (*complete)(void *handle, int status,
|
||||
bool sync_waiting),
|
||||
void *handle);
|
||||
|
||||
/* Flags bits */
|
||||
#define SDIO_REQ_4BYTE 0x1 /* Four-byte target (backplane) width (vs. two-byte) */
|
||||
#define SDIO_REQ_FIXED 0x2 /* Fixed address (FIFO) (vs. incrementing address) */
|
||||
#define SDIO_REQ_ASYNC 0x4 /* Async request (vs. sync request) */
|
||||
|
||||
/* Pending (non-error) return code */
|
||||
#define BCME_PENDING 1
|
||||
|
||||
/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only).
|
||||
* rw: read or write (0/1)
|
||||
* addr: direct SDIO address
|
||||
* buf: pointer to memory data buffer
|
||||
* nbytes: number of bytes to transfer to/from buf
|
||||
* Returns 0 or error code.
|
||||
*/
|
||||
extern int brcmf_sdcard_rwdata(struct brcmf_sdio_card *card, uint rw, u32 addr,
|
||||
u8 *buf, uint nbytes);
|
||||
|
||||
/* Issue an abort to the specified function */
|
||||
extern int brcmf_sdcard_abort(struct brcmf_sdio_card *card, uint fn);
|
||||
|
||||
/* Returns the "Device ID" of target device on the SDIO bus. */
|
||||
extern int brcmf_sdcard_query_device(struct brcmf_sdio_card *card);
|
||||
|
||||
/* Miscellaneous knob tweaker. */
|
||||
extern int brcmf_sdcard_iovar_op(struct brcmf_sdio_card *card, const char *name,
|
||||
void *params, int plen, void *arg, int len,
|
||||
bool set);
|
||||
|
||||
/* helper functions */
|
||||
|
||||
/* callback functions */
|
||||
struct brcmf_sdioh_driver {
|
||||
/* attach to device */
|
||||
void *(*attach) (u16 vend_id, u16 dev_id, u16 bus, u16 slot,
|
||||
u16 func, uint bustype, u32 regsva, void *param);
|
||||
/* detach from device */
|
||||
void (*detach) (void *ch);
|
||||
};
|
||||
|
||||
struct sdioh_info;
|
||||
|
||||
/* platform specific/high level functions */
|
||||
extern int brcmf_sdio_function_init(void);
|
||||
extern int brcmf_sdio_register(struct brcmf_sdioh_driver *driver);
|
||||
extern void brcmf_sdio_unregister(void);
|
||||
extern void brcmf_sdio_function_cleanup(void);
|
||||
extern int brcmf_sdio_probe(struct device *dev);
|
||||
extern int brcmf_sdio_remove(struct device *dev);
|
||||
|
||||
/* Function to return current window addr */
|
||||
extern u32 brcmf_sdcard_cur_sbwad(struct brcmf_sdio_card *card);
|
||||
|
||||
/* Allocate/init/free per-OS private data */
|
||||
extern int brcmf_sdioh_osinit(struct sdioh_info *sd);
|
||||
extern void brcmf_sdioh_osfree(struct sdioh_info *sd);
|
||||
|
||||
/* Core interrupt enable/disable of device interrupts */
|
||||
extern void brcmf_sdioh_dev_intr_on(struct sdioh_info *sd);
|
||||
extern void brcmf_sdioh_dev_intr_off(struct sdioh_info *sd);
|
||||
|
||||
/* attach, return handler on success, NULL if failed.
|
||||
* The handler shall be provided by all subsequent calls. No local cache
|
||||
* cfghdl points to the starting address of pci device mapped memory
|
||||
*/
|
||||
extern struct sdioh_info *brcmf_sdioh_attach(void *cfghdl, uint irq);
|
||||
extern int brcmf_sdioh_detach(struct sdioh_info *si);
|
||||
|
||||
extern int
|
||||
brcmf_sdioh_interrupt_register(struct sdioh_info *si,
|
||||
void (*sdioh_cb_fn)(void *), void *argh);
|
||||
|
||||
extern int brcmf_sdioh_interrupt_deregister(struct sdioh_info *si);
|
||||
|
||||
/* enable or disable SD interrupt */
|
||||
extern int
|
||||
brcmf_sdioh_interrupt_set(struct sdioh_info *si, bool enable_disable);
|
||||
|
||||
/* read or write one byte using cmd52 */
|
||||
extern int
|
||||
brcmf_sdioh_request_byte(struct sdioh_info *si, uint rw, uint fnc, uint addr,
|
||||
u8 *byte);
|
||||
|
||||
/* read or write 2/4 bytes using cmd53 */
|
||||
extern int
|
||||
brcmf_sdioh_request_word(struct sdioh_info *si, uint cmd_type,
|
||||
uint rw, uint fnc, uint addr,
|
||||
u32 *word, uint nbyte);
|
||||
|
||||
/* read or write any buffer using cmd53 */
|
||||
extern int
|
||||
brcmf_sdioh_request_buffer(struct sdioh_info *si, uint pio_dma,
|
||||
uint fix_inc, uint rw, uint fnc_num,
|
||||
u32 addr, uint regwidth,
|
||||
u32 buflen, u8 *buffer, struct sk_buff *pkt);
|
||||
|
||||
/* get cis data */
|
||||
extern int
|
||||
brcmf_sdioh_cis_read(struct sdioh_info *si, uint fuc, u8 *cis, u32 length);
|
||||
|
||||
extern int
|
||||
brcmf_sdioh_cfg_read(struct sdioh_info *si, uint fuc, u32 addr, u8 *data);
|
||||
extern int
|
||||
brcmf_sdioh_cfg_write(struct sdioh_info *si, uint fuc, u32 addr, u8 *data);
|
||||
|
||||
/* handle iovars */
|
||||
extern int brcmf_sdioh_iovar_op(struct sdioh_info *si, const char *name,
|
||||
void *params, int plen, void *arg, int len, bool set);
|
||||
|
||||
/* Issue abort to the specified function and clear controller as needed */
|
||||
extern int brcmf_sdioh_abort(struct sdioh_info *si, uint fnc);
|
||||
|
||||
/* Watchdog timer interface for pm ops */
|
||||
extern void brcmf_sdio_wdtmr_enable(bool enable);
|
||||
|
||||
extern uint sd_msglevel; /* Debug message level */
|
||||
|
||||
extern struct brcmf_sdmmc_instance *gInstance;
|
||||
|
||||
#endif /* _BRCM_SDH_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,356 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _wl_cfg80211_h_
|
||||
#define _wl_cfg80211_h_
|
||||
|
||||
struct brcmf_cfg80211_conf;
|
||||
struct brcmf_cfg80211_iface;
|
||||
struct brcmf_cfg80211_priv;
|
||||
struct brcmf_cfg80211_security;
|
||||
struct brcmf_cfg80211_ibss;
|
||||
|
||||
#define WL_DBG_NONE 0
|
||||
#define WL_DBG_CONN (1 << 5)
|
||||
#define WL_DBG_SCAN (1 << 4)
|
||||
#define WL_DBG_TRACE (1 << 3)
|
||||
#define WL_DBG_INFO (1 << 1)
|
||||
#define WL_DBG_ERR (1 << 0)
|
||||
#define WL_DBG_MASK ((WL_DBG_INFO | WL_DBG_ERR | WL_DBG_TRACE) | \
|
||||
(WL_DBG_SCAN) | (WL_DBG_CONN))
|
||||
|
||||
#define WL_ERR(fmt, args...) \
|
||||
do { \
|
||||
if (brcmf_dbg_level & WL_DBG_ERR) { \
|
||||
if (net_ratelimit()) { \
|
||||
printk(KERN_ERR "ERROR @%s : " fmt, \
|
||||
__func__, ##args); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#if (defined BCMDBG)
|
||||
#define WL_INFO(fmt, args...) \
|
||||
do { \
|
||||
if (brcmf_dbg_level & WL_DBG_INFO) { \
|
||||
if (net_ratelimit()) { \
|
||||
printk(KERN_ERR "INFO @%s : " fmt, \
|
||||
__func__, ##args); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define WL_TRACE(fmt, args...) \
|
||||
do { \
|
||||
if (brcmf_dbg_level & WL_DBG_TRACE) { \
|
||||
if (net_ratelimit()) { \
|
||||
printk(KERN_ERR "TRACE @%s : " fmt, \
|
||||
__func__, ##args); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define WL_SCAN(fmt, args...) \
|
||||
do { \
|
||||
if (brcmf_dbg_level & WL_DBG_SCAN) { \
|
||||
if (net_ratelimit()) { \
|
||||
printk(KERN_ERR "SCAN @%s : " fmt, \
|
||||
__func__, ##args); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define WL_CONN(fmt, args...) \
|
||||
do { \
|
||||
if (brcmf_dbg_level & WL_DBG_CONN) { \
|
||||
if (net_ratelimit()) { \
|
||||
printk(KERN_ERR "CONN @%s : " fmt, \
|
||||
__func__, ##args); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else /* (defined BCMDBG) */
|
||||
#define WL_INFO(fmt, args...)
|
||||
#define WL_TRACE(fmt, args...)
|
||||
#define WL_SCAN(fmt, args...)
|
||||
#define WL_CONN(fmt, args...)
|
||||
#endif /* (defined BCMDBG) */
|
||||
|
||||
#define WL_NUM_SCAN_MAX 1
|
||||
#define WL_NUM_PMKIDS_MAX MAXPMKID /* will be used
|
||||
* for 2.6.33 kernel
|
||||
* or later
|
||||
*/
|
||||
#define WL_SCAN_BUF_MAX (1024 * 8)
|
||||
#define WL_TLV_INFO_MAX 1024
|
||||
#define WL_BSS_INFO_MAX 2048
|
||||
#define WL_ASSOC_INFO_MAX 512 /*
|
||||
* needs to grab assoc info from dongle to
|
||||
* report it to cfg80211 through "connect"
|
||||
* event
|
||||
*/
|
||||
#define WL_IOCTL_LEN_MAX 1024
|
||||
#define WL_EXTRA_BUF_MAX 2048
|
||||
#define WL_ISCAN_BUF_MAX 2048 /*
|
||||
* the buf length can be BRCMF_C_IOCTL_MAXLEN
|
||||
* to reduce iteration
|
||||
*/
|
||||
#define WL_ISCAN_TIMER_INTERVAL_MS 3000
|
||||
#define WL_SCAN_ERSULTS_LAST (BRCMF_SCAN_RESULTS_NO_MEM+1)
|
||||
#define WL_AP_MAX 256 /* virtually unlimitted as long
|
||||
* as kernel memory allows
|
||||
*/
|
||||
|
||||
#define WL_ROAM_TRIGGER_LEVEL -75
|
||||
#define WL_ROAM_DELTA 20
|
||||
#define WL_BEACON_TIMEOUT 3
|
||||
|
||||
#define WL_SCAN_CHANNEL_TIME 40
|
||||
#define WL_SCAN_UNASSOC_TIME 40
|
||||
#define WL_SCAN_PASSIVE_TIME 120
|
||||
|
||||
/* dongle status */
|
||||
enum wl_status {
|
||||
WL_STATUS_READY,
|
||||
WL_STATUS_SCANNING,
|
||||
WL_STATUS_SCAN_ABORTING,
|
||||
WL_STATUS_CONNECTING,
|
||||
WL_STATUS_CONNECTED
|
||||
};
|
||||
|
||||
/* wi-fi mode */
|
||||
enum wl_mode {
|
||||
WL_MODE_BSS,
|
||||
WL_MODE_IBSS,
|
||||
WL_MODE_AP
|
||||
};
|
||||
|
||||
/* dongle profile list */
|
||||
enum wl_prof_list {
|
||||
WL_PROF_MODE,
|
||||
WL_PROF_SSID,
|
||||
WL_PROF_SEC,
|
||||
WL_PROF_IBSS,
|
||||
WL_PROF_BAND,
|
||||
WL_PROF_BSSID,
|
||||
WL_PROF_ACT,
|
||||
WL_PROF_BEACONINT,
|
||||
WL_PROF_DTIMPERIOD
|
||||
};
|
||||
|
||||
/* dongle iscan state */
|
||||
enum wl_iscan_state {
|
||||
WL_ISCAN_STATE_IDLE,
|
||||
WL_ISCAN_STATE_SCANING
|
||||
};
|
||||
|
||||
/* dongle configuration */
|
||||
struct brcmf_cfg80211_conf {
|
||||
u32 mode; /* adhoc , infrastructure or ap */
|
||||
u32 frag_threshold;
|
||||
u32 rts_threshold;
|
||||
u32 retry_short;
|
||||
u32 retry_long;
|
||||
s32 tx_power;
|
||||
struct ieee80211_channel channel;
|
||||
};
|
||||
|
||||
/* cfg80211 main event loop */
|
||||
struct brcmf_cfg80211_event_loop {
|
||||
s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_priv *cfg_priv,
|
||||
struct net_device *ndev,
|
||||
const struct brcmf_event_msg *e,
|
||||
void *data);
|
||||
};
|
||||
|
||||
/* representing interface of cfg80211 plane */
|
||||
struct brcmf_cfg80211_iface {
|
||||
struct brcmf_cfg80211_priv *cfg_priv;
|
||||
};
|
||||
|
||||
struct brcmf_cfg80211_dev {
|
||||
void *driver_data; /* to store cfg80211 object information */
|
||||
};
|
||||
|
||||
/* basic structure of scan request */
|
||||
struct brcmf_cfg80211_scan_req {
|
||||
struct brcmf_ssid ssid;
|
||||
};
|
||||
|
||||
/* basic structure of information element */
|
||||
struct brcmf_cfg80211_ie {
|
||||
u16 offset;
|
||||
u8 buf[WL_TLV_INFO_MAX];
|
||||
};
|
||||
|
||||
/* event queue for cfg80211 main event */
|
||||
struct brcmf_cfg80211_event_q {
|
||||
struct list_head eq_list;
|
||||
u32 etype;
|
||||
struct brcmf_event_msg emsg;
|
||||
s8 edata[1];
|
||||
};
|
||||
|
||||
/* security information with currently associated ap */
|
||||
struct brcmf_cfg80211_security {
|
||||
u32 wpa_versions;
|
||||
u32 auth_type;
|
||||
u32 cipher_pairwise;
|
||||
u32 cipher_group;
|
||||
u32 wpa_auth;
|
||||
};
|
||||
|
||||
/* ibss information for currently joined ibss network */
|
||||
struct brcmf_cfg80211_ibss {
|
||||
u8 beacon_interval; /* in millisecond */
|
||||
u8 atim; /* in millisecond */
|
||||
s8 join_only;
|
||||
u8 band;
|
||||
u8 channel;
|
||||
};
|
||||
|
||||
/* dongle profile */
|
||||
struct brcmf_cfg80211_profile {
|
||||
u32 mode;
|
||||
struct brcmf_ssid ssid;
|
||||
u8 bssid[ETH_ALEN];
|
||||
u16 beacon_interval;
|
||||
u8 dtim_period;
|
||||
struct brcmf_cfg80211_security sec;
|
||||
struct brcmf_cfg80211_ibss ibss;
|
||||
s32 band;
|
||||
};
|
||||
|
||||
/* dongle iscan event loop */
|
||||
struct brcmf_cfg80211_iscan_eloop {
|
||||
s32 (*handler[WL_SCAN_ERSULTS_LAST])
|
||||
(struct brcmf_cfg80211_priv *cfg_priv);
|
||||
};
|
||||
|
||||
/* dongle iscan controller */
|
||||
struct brcmf_cfg80211_iscan_ctrl {
|
||||
struct net_device *dev;
|
||||
struct timer_list timer;
|
||||
u32 timer_ms;
|
||||
u32 timer_on;
|
||||
s32 state;
|
||||
struct task_struct *tsk;
|
||||
struct semaphore sync;
|
||||
struct brcmf_cfg80211_iscan_eloop el;
|
||||
void *data;
|
||||
s8 ioctl_buf[BRCMF_C_IOCTL_SMLEN];
|
||||
s8 scan_buf[WL_ISCAN_BUF_MAX];
|
||||
};
|
||||
|
||||
/* association inform */
|
||||
struct brcmf_cfg80211_connect_info {
|
||||
u8 *req_ie;
|
||||
s32 req_ie_len;
|
||||
u8 *resp_ie;
|
||||
s32 resp_ie_len;
|
||||
};
|
||||
|
||||
/* assoc ie length */
|
||||
struct brcmf_cfg80211_assoc_ielen {
|
||||
u32 req_len;
|
||||
u32 resp_len;
|
||||
};
|
||||
|
||||
/* wpa2 pmk list */
|
||||
struct brcmf_cfg80211_pmk_list {
|
||||
pmkid_list_t pmkids;
|
||||
pmkid_t foo[MAXPMKID - 1];
|
||||
};
|
||||
|
||||
/* dongle private data of cfg80211 interface */
|
||||
struct brcmf_cfg80211_priv {
|
||||
struct wireless_dev *wdev; /* representing wl cfg80211 device */
|
||||
struct brcmf_cfg80211_conf *conf; /* dongle configuration */
|
||||
struct cfg80211_scan_request *scan_request; /* scan request
|
||||
object */
|
||||
struct brcmf_cfg80211_event_loop el; /* main event loop */
|
||||
struct list_head eq_list; /* used for event queue */
|
||||
spinlock_t eq_lock; /* for event queue synchronization */
|
||||
struct mutex usr_sync; /* maily for dongle up/down synchronization */
|
||||
struct brcmf_scan_results *bss_list; /* bss_list holding scanned
|
||||
ap information */
|
||||
struct brcmf_scan_results *scan_results;
|
||||
struct brcmf_cfg80211_scan_req *scan_req_int; /* scan request object
|
||||
for internal purpose */
|
||||
struct wl_cfg80211_bss_info *bss_info; /* bss information for
|
||||
cfg80211 layer */
|
||||
struct brcmf_cfg80211_ie ie; /* information element object for
|
||||
internal purpose */
|
||||
struct semaphore event_sync; /* for synchronization of main event
|
||||
thread */
|
||||
struct brcmf_cfg80211_profile *profile; /* holding dongle profile */
|
||||
struct brcmf_cfg80211_iscan_ctrl *iscan; /* iscan controller */
|
||||
struct brcmf_cfg80211_connect_info conn_info; /* association info */
|
||||
struct brcmf_cfg80211_pmk_list *pmk_list; /* wpa2 pmk list */
|
||||
struct task_struct *event_tsk; /* task of main event handler thread */
|
||||
unsigned long status; /* current dongle status */
|
||||
void *pub;
|
||||
u32 channel; /* current channel */
|
||||
bool iscan_on; /* iscan on/off switch */
|
||||
bool iscan_kickstart; /* indicate iscan already started */
|
||||
bool active_scan; /* current scan mode */
|
||||
bool ibss_starter; /* indicates this sta is ibss starter */
|
||||
bool link_up; /* link/connection up flag */
|
||||
bool pwr_save; /* indicate whether dongle to support
|
||||
power save mode */
|
||||
bool dongle_up; /* indicate whether dongle up or not */
|
||||
bool roam_on; /* on/off switch for dongle self-roaming */
|
||||
bool scan_tried; /* indicates if first scan attempted */
|
||||
u8 *ioctl_buf; /* ioctl buffer */
|
||||
u8 *extra_buf; /* maily to grab assoc information */
|
||||
struct dentry *debugfsdir;
|
||||
u8 ci[0] __attribute__ ((__aligned__(NETDEV_ALIGN)));
|
||||
};
|
||||
|
||||
#define cfg_to_wiphy(w) (w->wdev->wiphy)
|
||||
#define wiphy_to_cfg(w) ((struct brcmf_cfg80211_priv *)(wiphy_priv(w)))
|
||||
#define cfg_to_wdev(w) (w->wdev)
|
||||
#define wdev_to_cfg(w) ((struct brcmf_cfg80211_priv *)(wdev_priv(w)))
|
||||
#define cfg_to_ndev(w) (w->wdev->netdev)
|
||||
#define ndev_to_cfg(n) (wdev_to_cfg(n->ieee80211_ptr))
|
||||
#define iscan_to_cfg(i) ((struct brcmf_cfg80211_priv *)(i->data))
|
||||
#define cfg_to_iscan(w) (w->iscan)
|
||||
#define cfg_to_conn(w) (&w->conn_info)
|
||||
|
||||
static inline struct brcmf_bss_info *next_bss(struct brcmf_scan_results *list,
|
||||
struct brcmf_bss_info *bss)
|
||||
{
|
||||
return bss = bss ?
|
||||
(struct brcmf_bss_info *)((unsigned long)bss +
|
||||
le32_to_cpu(bss->length)) :
|
||||
list->bss_info;
|
||||
}
|
||||
|
||||
#define for_each_bss(list, bss, __i) \
|
||||
for (__i = 0; __i < list->count && __i < WL_AP_MAX; __i++, bss = next_bss(list, bss))
|
||||
|
||||
extern s32 brcmf_cfg80211_attach(struct net_device *ndev, void *data);
|
||||
extern void brcmf_cfg80211_detach(void);
|
||||
/* event handler from dongle */
|
||||
extern void brcmf_cfg80211_event(struct net_device *ndev,
|
||||
const struct brcmf_event_msg *e, void *data);
|
||||
extern void brcmf_cfg80211_sdio_func(void *func); /* set sdio function info */
|
||||
extern struct sdio_func *brcmf_cfg80211_get_sdio_func(void);
|
||||
extern s32 brcmf_cfg80211_up(void); /* dongle up */
|
||||
extern s32 brcmf_cfg80211_down(void); /* dongle down */
|
||||
|
||||
#endif /* _wl_cfg80211_h_ */
|
@ -1,58 +0,0 @@
|
||||
#
|
||||
# Makefile fragment for Broadcom 802.11n Networking Device Driver
|
||||
#
|
||||
# Copyright (c) 2010 Broadcom Corporation
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
ccflags-y := \
|
||||
-DWLC_HIGH \
|
||||
-DWLC_LOW \
|
||||
-DSTA \
|
||||
-DWME \
|
||||
-DWL11N \
|
||||
-DDBAND \
|
||||
-DBCMNVRAMR \
|
||||
-Idrivers/staging/brcm80211/brcmsmac \
|
||||
-Idrivers/staging/brcm80211/brcmsmac/phy \
|
||||
-Idrivers/staging/brcm80211/include
|
||||
|
||||
BRCMSMAC_OFILES := \
|
||||
mac80211_if.o \
|
||||
ucode_loader.o \
|
||||
alloc.o \
|
||||
ampdu.o \
|
||||
antsel.o \
|
||||
bmac.o \
|
||||
channel.o \
|
||||
main.o \
|
||||
phy_shim.o \
|
||||
pmu.o \
|
||||
rate.o \
|
||||
stf.o \
|
||||
aiutils.o \
|
||||
phy/phy_cmn.o \
|
||||
phy/phy_lcn.o \
|
||||
phy/phy_n.o \
|
||||
phy/phytbl_lcn.o \
|
||||
phy/phytbl_n.o \
|
||||
phy/phy_qmath.o \
|
||||
otp.o \
|
||||
srom.o \
|
||||
dma.o \
|
||||
nicpci.o
|
||||
|
||||
MODULEPFX := brcmsmac
|
||||
|
||||
obj-$(CONFIG_BRCMSMAC) += $(MODULEPFX).o
|
||||
$(MODULEPFX)-objs = $(BRCMSMAC_OFILES)
|
File diff suppressed because it is too large
Load Diff
@ -1,584 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_AIUTILS_H_
|
||||
#define _BRCM_AIUTILS_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/*
|
||||
* SOC Interconnect Address Map.
|
||||
* All regions may not exist on all chips.
|
||||
*/
|
||||
/* Physical SDRAM */
|
||||
#define SI_SDRAM_BASE 0x00000000
|
||||
/* Host Mode sb2pcitranslation0 (64 MB) */
|
||||
#define SI_PCI_MEM 0x08000000
|
||||
#define SI_PCI_MEM_SZ (64 * 1024 * 1024)
|
||||
/* Host Mode sb2pcitranslation1 (64 MB) */
|
||||
#define SI_PCI_CFG 0x0c000000
|
||||
/* Byteswapped Physical SDRAM */
|
||||
#define SI_SDRAM_SWAPPED 0x10000000
|
||||
/* Region 2 for sdram (512 MB) */
|
||||
#define SI_SDRAM_R2 0x80000000
|
||||
|
||||
#ifdef SI_ENUM_BASE_VARIABLE
|
||||
#define SI_ENUM_BASE (sii->pub.si_enum_base)
|
||||
#else
|
||||
#define SI_ENUM_BASE 0x18000000 /* Enumeration space base */
|
||||
#endif /* SI_ENUM_BASE_VARIABLE */
|
||||
|
||||
/* Wrapper space base */
|
||||
#define SI_WRAP_BASE 0x18100000
|
||||
/* each core gets 4Kbytes for registers */
|
||||
#define SI_CORE_SIZE 0x1000
|
||||
/*
|
||||
* Max cores (this is arbitrary, for software
|
||||
* convenience and could be changed if we
|
||||
* make any larger chips
|
||||
*/
|
||||
#define SI_MAXCORES 16
|
||||
|
||||
/* On-chip RAM on chips that also have DDR */
|
||||
#define SI_FASTRAM 0x19000000
|
||||
#define SI_FASTRAM_SWAPPED 0x19800000
|
||||
|
||||
/* Flash Region 2 (region 1 shadowed here) */
|
||||
#define SI_FLASH2 0x1c000000
|
||||
/* Size of Flash Region 2 */
|
||||
#define SI_FLASH2_SZ 0x02000000
|
||||
/* ARM Cortex-M3 ROM */
|
||||
#define SI_ARMCM3_ROM 0x1e000000
|
||||
/* MIPS Flash Region 1 */
|
||||
#define SI_FLASH1 0x1fc00000
|
||||
/* MIPS Size of Flash Region 1 */
|
||||
#define SI_FLASH1_SZ 0x00400000
|
||||
/* ARM7TDMI-S ROM */
|
||||
#define SI_ARM7S_ROM 0x20000000
|
||||
/* ARM Cortex-M3 SRAM Region 2 */
|
||||
#define SI_ARMCM3_SRAM2 0x60000000
|
||||
/* ARM7TDMI-S SRAM Region 2 */
|
||||
#define SI_ARM7S_SRAM2 0x80000000
|
||||
/* ARM Flash Region 1 */
|
||||
#define SI_ARM_FLASH1 0xffff0000
|
||||
/* ARM Size of Flash Region 1 */
|
||||
#define SI_ARM_FLASH1_SZ 0x00010000
|
||||
|
||||
/* Client Mode sb2pcitranslation2 (1 GB) */
|
||||
#define SI_PCI_DMA 0x40000000
|
||||
/* Client Mode sb2pcitranslation2 (1 GB) */
|
||||
#define SI_PCI_DMA2 0x80000000
|
||||
/* Client Mode sb2pcitranslation2 size in bytes */
|
||||
#define SI_PCI_DMA_SZ 0x40000000
|
||||
/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */
|
||||
#define SI_PCIE_DMA_L32 0x00000000
|
||||
/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */
|
||||
#define SI_PCIE_DMA_H32 0x80000000
|
||||
|
||||
/* core codes */
|
||||
#define NODEV_CORE_ID 0x700 /* Invalid coreid */
|
||||
#define CC_CORE_ID 0x800 /* chipcommon core */
|
||||
#define ILINE20_CORE_ID 0x801 /* iline20 core */
|
||||
#define SRAM_CORE_ID 0x802 /* sram core */
|
||||
#define SDRAM_CORE_ID 0x803 /* sdram core */
|
||||
#define PCI_CORE_ID 0x804 /* pci core */
|
||||
#define MIPS_CORE_ID 0x805 /* mips core */
|
||||
#define ENET_CORE_ID 0x806 /* enet mac core */
|
||||
#define CODEC_CORE_ID 0x807 /* v90 codec core */
|
||||
#define USB_CORE_ID 0x808 /* usb 1.1 host/device core */
|
||||
#define ADSL_CORE_ID 0x809 /* ADSL core */
|
||||
#define ILINE100_CORE_ID 0x80a /* iline100 core */
|
||||
#define IPSEC_CORE_ID 0x80b /* ipsec core */
|
||||
#define UTOPIA_CORE_ID 0x80c /* utopia core */
|
||||
#define PCMCIA_CORE_ID 0x80d /* pcmcia core */
|
||||
#define SOCRAM_CORE_ID 0x80e /* internal memory core */
|
||||
#define MEMC_CORE_ID 0x80f /* memc sdram core */
|
||||
#define OFDM_CORE_ID 0x810 /* OFDM phy core */
|
||||
#define EXTIF_CORE_ID 0x811 /* external interface core */
|
||||
#define D11_CORE_ID 0x812 /* 802.11 MAC core */
|
||||
#define APHY_CORE_ID 0x813 /* 802.11a phy core */
|
||||
#define BPHY_CORE_ID 0x814 /* 802.11b phy core */
|
||||
#define GPHY_CORE_ID 0x815 /* 802.11g phy core */
|
||||
#define MIPS33_CORE_ID 0x816 /* mips3302 core */
|
||||
#define USB11H_CORE_ID 0x817 /* usb 1.1 host core */
|
||||
#define USB11D_CORE_ID 0x818 /* usb 1.1 device core */
|
||||
#define USB20H_CORE_ID 0x819 /* usb 2.0 host core */
|
||||
#define USB20D_CORE_ID 0x81a /* usb 2.0 device core */
|
||||
#define SDIOH_CORE_ID 0x81b /* sdio host core */
|
||||
#define ROBO_CORE_ID 0x81c /* roboswitch core */
|
||||
#define ATA100_CORE_ID 0x81d /* parallel ATA core */
|
||||
#define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */
|
||||
#define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */
|
||||
#define PCIE_CORE_ID 0x820 /* pci express core */
|
||||
#define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */
|
||||
#define SRAMC_CORE_ID 0x822 /* SRAM controller core */
|
||||
#define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */
|
||||
#define ARM11_CORE_ID 0x824 /* ARM 1176 core */
|
||||
#define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */
|
||||
#define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */
|
||||
#define PMU_CORE_ID 0x827 /* PMU core */
|
||||
#define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */
|
||||
#define SDIOD_CORE_ID 0x829 /* SDIO device core */
|
||||
#define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */
|
||||
#define HTPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */
|
||||
#define MIPS74K_CORE_ID 0x82c /* mips 74k core */
|
||||
#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */
|
||||
#define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */
|
||||
#define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */
|
||||
#define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */
|
||||
#define SC_CORE_ID 0x831 /* shared common core */
|
||||
#define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */
|
||||
#define SPIH_CORE_ID 0x833 /* SPI host core */
|
||||
#define I2S_CORE_ID 0x834 /* I2S core */
|
||||
#define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */
|
||||
#define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */
|
||||
#define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */
|
||||
#define DEF_AI_COMP 0xfff /* Default component, in ai chips it
|
||||
* maps all unused address ranges
|
||||
*/
|
||||
|
||||
/* chipcommon being the first core: */
|
||||
#define SI_CC_IDX 0
|
||||
|
||||
/* SOC Interconnect types (aka chip types) */
|
||||
#define SOCI_AI 1
|
||||
|
||||
/* Common core control flags */
|
||||
#define SICF_BIST_EN 0x8000
|
||||
#define SICF_PME_EN 0x4000
|
||||
#define SICF_CORE_BITS 0x3ffc
|
||||
#define SICF_FGC 0x0002
|
||||
#define SICF_CLOCK_EN 0x0001
|
||||
|
||||
/* Common core status flags */
|
||||
#define SISF_BIST_DONE 0x8000
|
||||
#define SISF_BIST_ERROR 0x4000
|
||||
#define SISF_GATED_CLK 0x2000
|
||||
#define SISF_DMA64 0x1000
|
||||
#define SISF_CORE_BITS 0x0fff
|
||||
|
||||
/* A register that is common to all cores to
|
||||
* communicate w/PMU regarding clock control.
|
||||
*/
|
||||
#define SI_CLK_CTL_ST 0x1e0 /* clock control and status */
|
||||
|
||||
/* clk_ctl_st register */
|
||||
#define CCS_FORCEALP 0x00000001 /* force ALP request */
|
||||
#define CCS_FORCEHT 0x00000002 /* force HT request */
|
||||
#define CCS_FORCEILP 0x00000004 /* force ILP request */
|
||||
#define CCS_ALPAREQ 0x00000008 /* ALP Avail Request */
|
||||
#define CCS_HTAREQ 0x00000010 /* HT Avail Request */
|
||||
#define CCS_FORCEHWREQOFF 0x00000020 /* Force HW Clock Request Off */
|
||||
#define CCS_ERSRC_REQ_MASK 0x00000700 /* external resource requests */
|
||||
#define CCS_ERSRC_REQ_SHIFT 8
|
||||
#define CCS_ALPAVAIL 0x00010000 /* ALP is available */
|
||||
#define CCS_HTAVAIL 0x00020000 /* HT is available */
|
||||
#define CCS_BP_ON_APL 0x00040000 /* RO: running on ALP clock */
|
||||
#define CCS_BP_ON_HT 0x00080000 /* RO: running on HT clock */
|
||||
#define CCS_ERSRC_STS_MASK 0x07000000 /* external resource status */
|
||||
#define CCS_ERSRC_STS_SHIFT 24
|
||||
|
||||
/* HT avail in chipc and pcmcia on 4328a0 */
|
||||
#define CCS0_HTAVAIL 0x00010000
|
||||
/* ALP avail in chipc and pcmcia on 4328a0 */
|
||||
#define CCS0_ALPAVAIL 0x00020000
|
||||
|
||||
/* Not really related to SOC Interconnect, but a couple of software
|
||||
* conventions for the use the flash space:
|
||||
*/
|
||||
|
||||
/* Minumum amount of flash we support */
|
||||
#define FLASH_MIN 0x00020000 /* Minimum flash size */
|
||||
|
||||
/* A boot/binary may have an embedded block that describes its size */
|
||||
#define BISZ_OFFSET 0x3e0 /* At this offset into the binary */
|
||||
#define BISZ_MAGIC 0x4249535a /* Marked with value: 'BISZ' */
|
||||
#define BISZ_MAGIC_IDX 0 /* Word 0: magic */
|
||||
#define BISZ_TXTST_IDX 1 /* 1: text start */
|
||||
#define BISZ_TXTEND_IDX 2 /* 2: text end */
|
||||
#define BISZ_DATAST_IDX 3 /* 3: data start */
|
||||
#define BISZ_DATAEND_IDX 4 /* 4: data end */
|
||||
#define BISZ_BSSST_IDX 5 /* 5: bss start */
|
||||
#define BISZ_BSSEND_IDX 6 /* 6: bss end */
|
||||
#define BISZ_SIZE 7 /* descriptor size in 32-bit integers */
|
||||
|
||||
#define CC_SROM_OTP 0x800 /* SROM/OTP address space */
|
||||
|
||||
/* gpiotimerval */
|
||||
#define GPIO_ONTIME_SHIFT 16
|
||||
|
||||
/* Fields in clkdiv */
|
||||
#define CLKD_OTP 0x000f0000
|
||||
#define CLKD_OTP_SHIFT 16
|
||||
|
||||
/* When Srom support present, fields in sromcontrol */
|
||||
#define SRC_START 0x80000000
|
||||
#define SRC_BUSY 0x80000000
|
||||
#define SRC_OPCODE 0x60000000
|
||||
#define SRC_OP_READ 0x00000000
|
||||
#define SRC_OP_WRITE 0x20000000
|
||||
#define SRC_OP_WRDIS 0x40000000
|
||||
#define SRC_OP_WREN 0x60000000
|
||||
#define SRC_OTPSEL 0x00000010
|
||||
#define SRC_LOCK 0x00000008
|
||||
#define SRC_SIZE_MASK 0x00000006
|
||||
#define SRC_SIZE_1K 0x00000000
|
||||
#define SRC_SIZE_4K 0x00000002
|
||||
#define SRC_SIZE_16K 0x00000004
|
||||
#define SRC_SIZE_SHIFT 1
|
||||
#define SRC_PRESENT 0x00000001
|
||||
|
||||
/* 4330 chip-specific ChipStatus register bits */
|
||||
#define CST4330_CHIPMODE_SDIOD(cs) (((cs) & 0x7) < 6) /* SDIO || gSPI */
|
||||
#define CST4330_CHIPMODE_USB20D(cs) (((cs) & 0x7) >= 6) /* USB || USBDA */
|
||||
#define CST4330_CHIPMODE_SDIO(cs) (((cs) & 0x4) == 0) /* SDIO */
|
||||
#define CST4330_CHIPMODE_GSPI(cs) (((cs) & 0x6) == 4) /* gSPI */
|
||||
#define CST4330_CHIPMODE_USB(cs) (((cs) & 0x7) == 6) /* USB packet-oriented */
|
||||
#define CST4330_CHIPMODE_USBDA(cs) (((cs) & 0x7) == 7) /* USB Direct Access */
|
||||
#define CST4330_OTP_PRESENT 0x00000010
|
||||
#define CST4330_LPO_AUTODET_EN 0x00000020
|
||||
#define CST4330_ARMREMAP_0 0x00000040
|
||||
#define CST4330_SPROM_PRESENT 0x00000080 /* takes priority over OTP if both set */
|
||||
#define CST4330_ILPDIV_EN 0x00000100
|
||||
#define CST4330_LPO_SEL 0x00000200
|
||||
#define CST4330_RES_INIT_MODE_SHIFT 10
|
||||
#define CST4330_RES_INIT_MODE_MASK 0x00000c00
|
||||
#define CST4330_CBUCK_MODE_SHIFT 12
|
||||
#define CST4330_CBUCK_MODE_MASK 0x00003000
|
||||
#define CST4330_CBUCK_POWER_OK 0x00004000
|
||||
#define CST4330_BB_PLL_LOCKED 0x00008000
|
||||
|
||||
/* Package IDs */
|
||||
#define BCM4329_289PIN_PKG_ID 0 /* 4329 289-pin package id */
|
||||
#define BCM4329_182PIN_PKG_ID 1 /* 4329N 182-pin package id */
|
||||
#define BCM4717_PKG_ID 9 /* 4717 package id */
|
||||
#define BCM4718_PKG_ID 10 /* 4718 package id */
|
||||
#define HDLSIM_PKG_ID 14 /* HDL simulator package id */
|
||||
#define HWSIM_PKG_ID 15 /* Hardware simulator package id */
|
||||
#define BCM43224_FAB_SMIC 0xa /* the chip is manufactured by SMIC */
|
||||
|
||||
/* these are router chips */
|
||||
#define BCM4716_CHIP_ID 0x4716 /* 4716 chipcommon chipid */
|
||||
#define BCM47162_CHIP_ID 47162 /* 47162 chipcommon chipid */
|
||||
#define BCM4748_CHIP_ID 0x4748 /* 4716 chipcommon chipid (OTP, RBBU) */
|
||||
#define BCM5356_CHIP_ID 0x5356 /* 5356 chipcommon chipid */
|
||||
#define BCM5357_CHIP_ID 0x5357 /* 5357 chipcommon chipid */
|
||||
|
||||
|
||||
#define SI_INFO(sih) ((struct si_info *)sih)
|
||||
|
||||
#define GOODCOREADDR(x, b) \
|
||||
(((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \
|
||||
IS_ALIGNED((x), SI_CORE_SIZE))
|
||||
#define GOODREGS(regs) \
|
||||
((regs) != NULL && IS_ALIGNED((unsigned long)(regs), SI_CORE_SIZE))
|
||||
#define BADCOREADDR 0
|
||||
#define GOODIDX(idx) (((uint)idx) < SI_MAXCORES)
|
||||
#define NOREV -1 /* Invalid rev */
|
||||
|
||||
/* Newer chips can access PCI/PCIE and CC core without requiring to change
|
||||
* PCI BAR0 WIN
|
||||
*/
|
||||
#define SI_FAST(si) (((si)->pub.buscoretype == PCIE_CORE_ID) || \
|
||||
(((si)->pub.buscoretype == PCI_CORE_ID) && \
|
||||
(si)->pub.buscorerev >= 13))
|
||||
|
||||
#define PCIEREGS(si) (((char *)((si)->curmap) + PCI_16KB0_PCIREGS_OFFSET))
|
||||
#define CCREGS_FAST(si) (((char *)((si)->curmap) + PCI_16KB0_CCREGS_OFFSET))
|
||||
|
||||
/*
|
||||
* Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts
|
||||
* before after core switching to avoid invalid register accesss inside ISR.
|
||||
*/
|
||||
#define INTR_OFF(si, intr_val) \
|
||||
if ((si)->intrsoff_fn && \
|
||||
(si)->coreid[(si)->curidx] == (si)->dev_coreid) \
|
||||
intr_val = (*(si)->intrsoff_fn)((si)->intr_arg)
|
||||
#define INTR_RESTORE(si, intr_val) \
|
||||
if ((si)->intrsrestore_fn && \
|
||||
(si)->coreid[(si)->curidx] == (si)->dev_coreid) \
|
||||
(*(si)->intrsrestore_fn)((si)->intr_arg, intr_val)
|
||||
|
||||
/* dynamic clock control defines */
|
||||
#define LPOMINFREQ 25000 /* low power oscillator min */
|
||||
#define LPOMAXFREQ 43000 /* low power oscillator max */
|
||||
#define XTALMINFREQ 19800000 /* 20 MHz - 1% */
|
||||
#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */
|
||||
#define PCIMINFREQ 25000000 /* 25 MHz */
|
||||
#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */
|
||||
|
||||
#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */
|
||||
#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */
|
||||
|
||||
#define PCI(si) (((si)->pub.bustype == PCI_BUS) && \
|
||||
((si)->pub.buscoretype == PCI_CORE_ID))
|
||||
#define PCIE(si) (((si)->pub.bustype == PCI_BUS) && \
|
||||
((si)->pub.buscoretype == PCIE_CORE_ID))
|
||||
#define PCI_FORCEHT(si) \
|
||||
(PCIE(si) && (si->pub.chip == BCM4716_CHIP_ID))
|
||||
|
||||
/* GPIO Based LED powersave defines */
|
||||
#define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */
|
||||
#define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */
|
||||
|
||||
#ifndef DEFAULT_GPIOTIMERVAL
|
||||
#define DEFAULT_GPIOTIMERVAL \
|
||||
((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Data structure to export all chip specific common variables
|
||||
* public (read-only) portion of aiutils handle returned by si_attach()
|
||||
*/
|
||||
struct si_pub {
|
||||
uint bustype; /* SI_BUS, PCI_BUS */
|
||||
uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */
|
||||
uint buscorerev; /* buscore rev */
|
||||
uint buscoreidx; /* buscore index */
|
||||
int ccrev; /* chip common core rev */
|
||||
u32 cccaps; /* chip common capabilities */
|
||||
u32 cccaps_ext; /* chip common capabilities extension */
|
||||
int pmurev; /* pmu core rev */
|
||||
u32 pmucaps; /* pmu capabilities */
|
||||
uint boardtype; /* board type */
|
||||
uint boardvendor; /* board vendor */
|
||||
uint boardflags; /* board flags */
|
||||
uint boardflags2; /* board flags2 */
|
||||
uint chip; /* chip number */
|
||||
uint chiprev; /* chip revision */
|
||||
uint chippkg; /* chip package option */
|
||||
u32 chipst; /* chip status */
|
||||
bool issim; /* chip is in simulation or emulation */
|
||||
uint socirev; /* SOC interconnect rev */
|
||||
bool pci_pr32414;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* Many of the routines below take an 'sih' handle as their first arg.
|
||||
* Allocate this by calling si_attach(). Free it by calling si_detach().
|
||||
* At any one time, the sih is logically focused on one particular si core
|
||||
* (the "current core").
|
||||
* Use si_setcore() or si_setcoreidx() to change the association to another core
|
||||
*/
|
||||
|
||||
#define BADIDX (SI_MAXCORES + 1)
|
||||
|
||||
/* clkctl xtal what flags */
|
||||
#define XTAL 0x1 /* primary crystal oscillator (2050) */
|
||||
#define PLL 0x2 /* main chip pll */
|
||||
|
||||
/* clkctl clk mode */
|
||||
#define CLK_FAST 0 /* force fast (pll) clock */
|
||||
#define CLK_DYNAMIC 2 /* enable dynamic clock control */
|
||||
|
||||
/* GPIO usage priorities */
|
||||
#define GPIO_DRV_PRIORITY 0 /* Driver */
|
||||
#define GPIO_APP_PRIORITY 1 /* Application */
|
||||
#define GPIO_HI_PRIORITY 2 /* Highest priority. Ignore GPIO
|
||||
* reservation
|
||||
*/
|
||||
|
||||
/* GPIO pull up/down */
|
||||
#define GPIO_PULLUP 0
|
||||
#define GPIO_PULLDN 1
|
||||
|
||||
/* GPIO event regtype */
|
||||
#define GPIO_REGEVT 0 /* GPIO register event */
|
||||
#define GPIO_REGEVT_INTMSK 1 /* GPIO register event int mask */
|
||||
#define GPIO_REGEVT_INTPOL 2 /* GPIO register event int polarity */
|
||||
|
||||
/* device path */
|
||||
#define SI_DEVPATH_BUFSZ 16 /* min buffer size in bytes */
|
||||
|
||||
/* SI routine enumeration: to be used by update function with multiple hooks */
|
||||
#define SI_DOATTACH 1
|
||||
#define SI_PCIDOWN 2
|
||||
#define SI_PCIUP 3
|
||||
|
||||
/* PMU clock/power control */
|
||||
#if defined(BCMPMUCTL)
|
||||
#define PMUCTL_ENAB(sih) (BCMPMUCTL)
|
||||
#else
|
||||
#define PMUCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PMU)
|
||||
#endif
|
||||
|
||||
/* chipcommon clock/power control (exclusive with PMU's) */
|
||||
#if defined(BCMPMUCTL) && BCMPMUCTL
|
||||
#define CCCTL_ENAB(sih) (0)
|
||||
#define CCPLL_ENAB(sih) (0)
|
||||
#else
|
||||
#define CCCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PWR_CTL)
|
||||
#define CCPLL_ENAB(sih) ((sih)->cccaps & CC_CAP_PLL_MASK)
|
||||
#endif
|
||||
|
||||
typedef void (*gpio_handler_t) (u32 stat, void *arg);
|
||||
|
||||
/* External PA enable mask */
|
||||
#define GPIO_CTRL_EPA_EN_MASK 0x40
|
||||
|
||||
#define SI_ERROR(args)
|
||||
|
||||
#ifdef BCMDBG
|
||||
#define SI_MSG(args) printk args
|
||||
#else
|
||||
#define SI_MSG(args)
|
||||
#endif /* BCMDBG */
|
||||
|
||||
/* Define SI_VMSG to printf for verbose debugging, but don't check it in */
|
||||
#define SI_VMSG(args)
|
||||
|
||||
#define IS_SIM(chippkg) \
|
||||
((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID))
|
||||
|
||||
typedef u32(*si_intrsoff_t) (void *intr_arg);
|
||||
typedef void (*si_intrsrestore_t) (void *intr_arg, u32 arg);
|
||||
typedef bool(*si_intrsenabled_t) (void *intr_arg);
|
||||
|
||||
struct gpioh_item {
|
||||
void *arg;
|
||||
bool level;
|
||||
gpio_handler_t handler;
|
||||
u32 event;
|
||||
struct gpioh_item *next;
|
||||
};
|
||||
|
||||
/* misc si info needed by some of the routines */
|
||||
struct si_info {
|
||||
struct si_pub pub; /* back plane public state (must be first) */
|
||||
void *pbus; /* handle to bus (pci/sdio/..) */
|
||||
uint dev_coreid; /* the core provides driver functions */
|
||||
void *intr_arg; /* interrupt callback function arg */
|
||||
si_intrsoff_t intrsoff_fn; /* turns chip interrupts off */
|
||||
si_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */
|
||||
si_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */
|
||||
|
||||
void *pch; /* PCI/E core handle */
|
||||
|
||||
char *vars;
|
||||
uint varsz;
|
||||
|
||||
void *curmap; /* current regs va */
|
||||
void *regs[SI_MAXCORES]; /* other regs va */
|
||||
|
||||
uint curidx; /* current core index */
|
||||
uint numcores; /* # discovered cores */
|
||||
uint coreid[SI_MAXCORES]; /* id of each core */
|
||||
u32 coresba[SI_MAXCORES]; /* backplane address of each core */
|
||||
void *regs2[SI_MAXCORES]; /* 2nd virtual address per core (usbh20) */
|
||||
u32 coresba2[SI_MAXCORES]; /* 2nd phys address per core (usbh20) */
|
||||
u32 coresba_size[SI_MAXCORES]; /* backplane address space size */
|
||||
u32 coresba2_size[SI_MAXCORES]; /* second address space size */
|
||||
|
||||
void *curwrap; /* current wrapper va */
|
||||
void *wrappers[SI_MAXCORES]; /* other cores wrapper va */
|
||||
u32 wrapba[SI_MAXCORES]; /* address of controlling wrapper */
|
||||
|
||||
u32 cia[SI_MAXCORES]; /* erom cia entry for each core */
|
||||
u32 cib[SI_MAXCORES]; /* erom cia entry for each core */
|
||||
u32 oob_router; /* oob router registers for axi */
|
||||
};
|
||||
|
||||
/* AMBA Interconnect exported externs */
|
||||
extern void ai_scan(struct si_pub *sih, void *regs);
|
||||
|
||||
extern uint ai_flag(struct si_pub *sih);
|
||||
extern void ai_setint(struct si_pub *sih, int siflag);
|
||||
extern uint ai_coreidx(struct si_pub *sih);
|
||||
extern uint ai_corevendor(struct si_pub *sih);
|
||||
extern uint ai_corerev(struct si_pub *sih);
|
||||
extern bool ai_iscoreup(struct si_pub *sih);
|
||||
extern void *ai_setcoreidx(struct si_pub *sih, uint coreidx);
|
||||
extern u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val);
|
||||
extern void ai_core_cflags_wo(struct si_pub *sih, u32 mask, u32 val);
|
||||
extern u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val);
|
||||
extern uint ai_corereg(struct si_pub *sih, uint coreidx, uint regoff, uint mask,
|
||||
uint val);
|
||||
extern void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits);
|
||||
extern void ai_core_disable(struct si_pub *sih, u32 bits);
|
||||
extern int ai_numaddrspaces(struct si_pub *sih);
|
||||
extern u32 ai_addrspace(struct si_pub *sih, uint asidx);
|
||||
extern u32 ai_addrspacesize(struct si_pub *sih, uint asidx);
|
||||
extern void ai_write_wrap_reg(struct si_pub *sih, u32 offset, u32 val);
|
||||
|
||||
/* === exported functions === */
|
||||
extern struct si_pub *ai_attach(void *regs, uint bustype,
|
||||
void *sdh, char **vars, uint *varsz);
|
||||
|
||||
extern void ai_detach(struct si_pub *sih);
|
||||
extern bool ai_pci_war16165(struct si_pub *sih);
|
||||
|
||||
extern uint ai_coreid(struct si_pub *sih);
|
||||
extern uint ai_corerev(struct si_pub *sih);
|
||||
extern uint ai_corereg(struct si_pub *sih, uint coreidx, uint regoff, uint mask,
|
||||
uint val);
|
||||
extern void ai_write_wrapperreg(struct si_pub *sih, u32 offset, u32 val);
|
||||
extern u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val);
|
||||
extern u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val);
|
||||
extern bool ai_iscoreup(struct si_pub *sih);
|
||||
extern uint ai_findcoreidx(struct si_pub *sih, uint coreid, uint coreunit);
|
||||
extern void *ai_setcoreidx(struct si_pub *sih, uint coreidx);
|
||||
extern void *ai_setcore(struct si_pub *sih, uint coreid, uint coreunit);
|
||||
extern void *ai_switch_core(struct si_pub *sih, uint coreid, uint *origidx,
|
||||
uint *intr_val);
|
||||
extern void ai_restore_core(struct si_pub *sih, uint coreid, uint intr_val);
|
||||
extern void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits);
|
||||
extern void ai_core_disable(struct si_pub *sih, u32 bits);
|
||||
extern u32 ai_alp_clock(struct si_pub *sih);
|
||||
extern u32 ai_ilp_clock(struct si_pub *sih);
|
||||
extern void ai_pci_setup(struct si_pub *sih, uint coremask);
|
||||
extern void ai_setint(struct si_pub *sih, int siflag);
|
||||
extern bool ai_backplane64(struct si_pub *sih);
|
||||
extern void ai_register_intr_callback(struct si_pub *sih, void *intrsoff_fn,
|
||||
void *intrsrestore_fn,
|
||||
void *intrsenabled_fn, void *intr_arg);
|
||||
extern void ai_deregister_intr_callback(struct si_pub *sih);
|
||||
extern void ai_clkctl_init(struct si_pub *sih);
|
||||
extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih);
|
||||
extern bool ai_clkctl_cc(struct si_pub *sih, uint mode);
|
||||
extern int ai_clkctl_xtal(struct si_pub *sih, uint what, bool on);
|
||||
extern bool ai_deviceremoved(struct si_pub *sih);
|
||||
extern u32 ai_gpiocontrol(struct si_pub *sih, u32 mask, u32 val,
|
||||
u8 priority);
|
||||
|
||||
/* OTP status */
|
||||
extern bool ai_is_otp_disabled(struct si_pub *sih);
|
||||
|
||||
/* SPROM availability */
|
||||
extern bool ai_is_sprom_available(struct si_pub *sih);
|
||||
|
||||
/*
|
||||
* Build device path. Path size must be >= SI_DEVPATH_BUFSZ.
|
||||
* The returned path is NULL terminated and has trailing '/'.
|
||||
* Return 0 on success, nonzero otherwise.
|
||||
*/
|
||||
extern int ai_devpath(struct si_pub *sih, char *path, int size);
|
||||
/* Read variable with prepending the devpath to the name */
|
||||
extern char *ai_getdevpathvar(struct si_pub *sih, const char *name);
|
||||
extern int ai_getdevpathintvar(struct si_pub *sih, const char *name);
|
||||
|
||||
extern void ai_pci_sleep(struct si_pub *sih);
|
||||
extern void ai_pci_down(struct si_pub *sih);
|
||||
extern void ai_pci_up(struct si_pub *sih);
|
||||
extern int ai_pci_fixcfg(struct si_pub *sih);
|
||||
|
||||
extern void ai_chipcontrl_epa4331(struct si_pub *sih, bool on);
|
||||
/* Enable Ex-PA for 4313 */
|
||||
extern void ai_epa_4313war(struct si_pub *sih);
|
||||
|
||||
char *ai_getnvramflvar(struct si_pub *sih, const char *name);
|
||||
|
||||
#endif /* _BRCM_AIUTILS_H_ */
|
@ -1,275 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <brcmu_utils.h>
|
||||
#include "types.h"
|
||||
#include "pub.h"
|
||||
#include "main.h"
|
||||
#include "alloc.h"
|
||||
|
||||
static struct brcms_bss_cfg *brcms_c_bsscfg_malloc(uint unit);
|
||||
static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg);
|
||||
static struct brcms_pub *brcms_c_pub_malloc(uint unit,
|
||||
uint *err, uint devid);
|
||||
static void brcms_c_pub_mfree(struct brcms_pub *pub);
|
||||
static void brcms_c_tunables_init(struct brcms_tunables *tunables, uint devid);
|
||||
|
||||
static void brcms_c_tunables_init(struct brcms_tunables *tunables, uint devid)
|
||||
{
|
||||
tunables->ntxd = NTXD;
|
||||
tunables->nrxd = NRXD;
|
||||
tunables->rxbufsz = RXBUFSZ;
|
||||
tunables->nrxbufpost = NRXBUFPOST;
|
||||
tunables->maxscb = MAXSCB;
|
||||
tunables->ampdunummpdu = AMPDU_NUM_MPDU;
|
||||
tunables->maxpktcb = MAXPKTCB;
|
||||
tunables->maxucodebss = BRCMS_MAX_UCODE_BSS;
|
||||
tunables->maxucodebss4 = BRCMS_MAX_UCODE_BSS4;
|
||||
tunables->maxbss = MAXBSS;
|
||||
tunables->datahiwat = BRCMS_DATAHIWAT;
|
||||
tunables->ampdudatahiwat = BRCMS_AMPDUDATAHIWAT;
|
||||
tunables->rxbnd = RXBND;
|
||||
tunables->txsbnd = TXSBND;
|
||||
}
|
||||
|
||||
static struct brcms_pub *brcms_c_pub_malloc(uint unit, uint *err, uint devid)
|
||||
{
|
||||
struct brcms_pub *pub;
|
||||
|
||||
pub = kzalloc(sizeof(struct brcms_pub), GFP_ATOMIC);
|
||||
if (pub == NULL) {
|
||||
*err = 1001;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pub->tunables = kzalloc(sizeof(struct brcms_tunables), GFP_ATOMIC);
|
||||
if (pub->tunables == NULL) {
|
||||
*err = 1028;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* need to init the tunables now */
|
||||
brcms_c_tunables_init(pub->tunables, devid);
|
||||
|
||||
pub->multicast = kzalloc(ETH_ALEN * MAXMULTILIST, GFP_ATOMIC);
|
||||
if (pub->multicast == NULL) {
|
||||
*err = 1003;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return pub;
|
||||
|
||||
fail:
|
||||
brcms_c_pub_mfree(pub);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void brcms_c_pub_mfree(struct brcms_pub *pub)
|
||||
{
|
||||
if (pub == NULL)
|
||||
return;
|
||||
|
||||
kfree(pub->multicast);
|
||||
kfree(pub->tunables);
|
||||
kfree(pub);
|
||||
}
|
||||
|
||||
static struct brcms_bss_cfg *brcms_c_bsscfg_malloc(uint unit)
|
||||
{
|
||||
struct brcms_bss_cfg *cfg;
|
||||
|
||||
cfg = kzalloc(sizeof(struct brcms_bss_cfg), GFP_ATOMIC);
|
||||
if (cfg == NULL)
|
||||
goto fail;
|
||||
|
||||
cfg->current_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC);
|
||||
if (cfg->current_bss == NULL)
|
||||
goto fail;
|
||||
|
||||
return cfg;
|
||||
|
||||
fail:
|
||||
brcms_c_bsscfg_mfree(cfg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg)
|
||||
{
|
||||
if (cfg == NULL)
|
||||
return;
|
||||
|
||||
kfree(cfg->maclist);
|
||||
kfree(cfg->current_bss);
|
||||
kfree(cfg);
|
||||
}
|
||||
|
||||
static void brcms_c_bsscfg_ID_assign(struct brcms_c_info *wlc,
|
||||
struct brcms_bss_cfg *bsscfg)
|
||||
{
|
||||
bsscfg->ID = wlc->next_bsscfg_ID;
|
||||
wlc->next_bsscfg_ID++;
|
||||
}
|
||||
|
||||
/*
|
||||
* The common driver entry routine. Error codes should be unique
|
||||
*/
|
||||
struct brcms_c_info *brcms_c_attach_malloc(uint unit, uint *err, uint devid)
|
||||
{
|
||||
struct brcms_c_info *wlc;
|
||||
|
||||
wlc = kzalloc(sizeof(struct brcms_c_info), GFP_ATOMIC);
|
||||
if (wlc == NULL) {
|
||||
*err = 1002;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* allocate struct brcms_c_pub state structure */
|
||||
wlc->pub = brcms_c_pub_malloc(unit, err, devid);
|
||||
if (wlc->pub == NULL) {
|
||||
*err = 1003;
|
||||
goto fail;
|
||||
}
|
||||
wlc->pub->wlc = wlc;
|
||||
|
||||
/* allocate struct brcms_hardware state structure */
|
||||
|
||||
wlc->hw = kzalloc(sizeof(struct brcms_hardware), GFP_ATOMIC);
|
||||
if (wlc->hw == NULL) {
|
||||
*err = 1005;
|
||||
goto fail;
|
||||
}
|
||||
wlc->hw->wlc = wlc;
|
||||
|
||||
wlc->hw->bandstate[0] =
|
||||
kzalloc(sizeof(struct brcms_hw_band) * MAXBANDS, GFP_ATOMIC);
|
||||
if (wlc->hw->bandstate[0] == NULL) {
|
||||
*err = 1006;
|
||||
goto fail;
|
||||
} else {
|
||||
int i;
|
||||
|
||||
for (i = 1; i < MAXBANDS; i++) {
|
||||
wlc->hw->bandstate[i] = (struct brcms_hw_band *)
|
||||
((unsigned long)wlc->hw->bandstate[0] +
|
||||
(sizeof(struct brcms_hw_band) * i));
|
||||
}
|
||||
}
|
||||
|
||||
wlc->modulecb =
|
||||
kzalloc(sizeof(struct modulecb) * BRCMS_MAXMODULES, GFP_ATOMIC);
|
||||
if (wlc->modulecb == NULL) {
|
||||
*err = 1009;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
wlc->default_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC);
|
||||
if (wlc->default_bss == NULL) {
|
||||
*err = 1010;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
wlc->cfg = brcms_c_bsscfg_malloc(unit);
|
||||
if (wlc->cfg == NULL) {
|
||||
*err = 1011;
|
||||
goto fail;
|
||||
}
|
||||
brcms_c_bsscfg_ID_assign(wlc, wlc->cfg);
|
||||
|
||||
wlc->wsec_def_keys[0] =
|
||||
kzalloc(sizeof(struct wsec_key) * BRCMS_DEFAULT_KEYS,
|
||||
GFP_ATOMIC);
|
||||
if (wlc->wsec_def_keys[0] == NULL) {
|
||||
*err = 1015;
|
||||
goto fail;
|
||||
} else {
|
||||
int i;
|
||||
for (i = 1; i < BRCMS_DEFAULT_KEYS; i++) {
|
||||
wlc->wsec_def_keys[i] = (struct wsec_key *)
|
||||
((unsigned long)wlc->wsec_def_keys[0] +
|
||||
(sizeof(struct wsec_key) * i));
|
||||
}
|
||||
}
|
||||
|
||||
wlc->protection = kzalloc(sizeof(struct brcms_protection),
|
||||
GFP_ATOMIC);
|
||||
if (wlc->protection == NULL) {
|
||||
*err = 1016;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
wlc->stf = kzalloc(sizeof(struct brcms_stf), GFP_ATOMIC);
|
||||
if (wlc->stf == NULL) {
|
||||
*err = 1017;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
wlc->bandstate[0] =
|
||||
kzalloc(sizeof(struct brcms_band)*MAXBANDS, GFP_ATOMIC);
|
||||
if (wlc->bandstate[0] == NULL) {
|
||||
*err = 1025;
|
||||
goto fail;
|
||||
} else {
|
||||
int i;
|
||||
|
||||
for (i = 1; i < MAXBANDS; i++) {
|
||||
wlc->bandstate[i] = (struct brcms_band *)
|
||||
((unsigned long)wlc->bandstate[0]
|
||||
+ (sizeof(struct brcms_band)*i));
|
||||
}
|
||||
}
|
||||
|
||||
wlc->corestate = kzalloc(sizeof(struct brcms_core), GFP_ATOMIC);
|
||||
if (wlc->corestate == NULL) {
|
||||
*err = 1026;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
wlc->corestate->macstat_snapshot =
|
||||
kzalloc(sizeof(struct macstat), GFP_ATOMIC);
|
||||
if (wlc->corestate->macstat_snapshot == NULL) {
|
||||
*err = 1027;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return wlc;
|
||||
|
||||
fail:
|
||||
brcms_c_detach_mfree(wlc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void brcms_c_detach_mfree(struct brcms_c_info *wlc)
|
||||
{
|
||||
if (wlc == NULL)
|
||||
return;
|
||||
|
||||
brcms_c_bsscfg_mfree(wlc->cfg);
|
||||
brcms_c_pub_mfree(wlc->pub);
|
||||
kfree(wlc->modulecb);
|
||||
kfree(wlc->default_bss);
|
||||
kfree(wlc->wsec_def_keys[0]);
|
||||
kfree(wlc->protection);
|
||||
kfree(wlc->stf);
|
||||
kfree(wlc->bandstate[0]);
|
||||
kfree(wlc->corestate->macstat_snapshot);
|
||||
kfree(wlc->corestate);
|
||||
kfree(wlc->hw->bandstate[0]);
|
||||
kfree(wlc->hw);
|
||||
|
||||
/* free the wlc */
|
||||
kfree(wlc);
|
||||
wlc = NULL;
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
extern struct brcms_c_info *brcms_c_attach_malloc(uint unit, uint *err,
|
||||
uint devid);
|
||||
extern void brcms_c_detach_mfree(struct brcms_c_info *wlc);
|
File diff suppressed because it is too large
Load Diff
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_AMPDU_H_
|
||||
#define _BRCM_AMPDU_H_
|
||||
|
||||
extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu);
|
||||
extern int brcms_c_sendampdu(struct ampdu_info *ampdu,
|
||||
struct brcms_txq_info *qi,
|
||||
struct sk_buff **aggp, int prec);
|
||||
extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
|
||||
struct sk_buff *p, struct tx_status *txs);
|
||||
extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu);
|
||||
|
||||
#endif /* _BRCM_AMPDU_H_ */
|
@ -1,311 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "bmac.h"
|
||||
#include "main.h"
|
||||
#include "phy_shim.h"
|
||||
#include "antsel.h"
|
||||
|
||||
#define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */
|
||||
#define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */
|
||||
#define ANT_SELCFG_TX_UNICAST 0 /* unicast tx antenna configuration */
|
||||
#define ANT_SELCFG_RX_UNICAST 1 /* unicast rx antenna configuration */
|
||||
#define ANT_SELCFG_TX_DEF 2 /* default tx antenna configuration */
|
||||
#define ANT_SELCFG_RX_DEF 3 /* default rx antenna configuration */
|
||||
|
||||
/* useful macros */
|
||||
#define BRCMS_ANTSEL_11N_0(ant) ((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf)
|
||||
#define BRCMS_ANTSEL_11N_1(ant) (((ant) & ANT_SELCFG_MASK) & 0xf)
|
||||
#define BRCMS_ANTIDX_11N(ant) (((BRCMS_ANTSEL_11N_0(ant)) << 2) +\
|
||||
(BRCMS_ANTSEL_11N_1(ant)))
|
||||
#define BRCMS_ANT_ISAUTO_11N(ant) (((ant) & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO)
|
||||
#define BRCMS_ANTSEL_11N(ant) ((ant) & ANT_SELCFG_MASK)
|
||||
|
||||
/* antenna switch */
|
||||
/* defines for no boardlevel antenna diversity */
|
||||
#define ANT_SELCFG_DEF_2x2 0x01 /* default antenna configuration */
|
||||
|
||||
/* 2x3 antdiv defines and tables for GPIO communication */
|
||||
#define ANT_SELCFG_NUM_2x3 3
|
||||
#define ANT_SELCFG_DEF_2x3 0x01 /* default antenna configuration */
|
||||
|
||||
/* 2x4 antdiv rev4 defines and tables for GPIO communication */
|
||||
#define ANT_SELCFG_NUM_2x4 4
|
||||
#define ANT_SELCFG_DEF_2x4 0x02 /* default antenna configuration */
|
||||
|
||||
/* static functions */
|
||||
static int brcms_c_antsel_cfgupd(struct antsel_info *asi,
|
||||
struct brcms_antselcfg *antsel);
|
||||
static u8 brcms_c_antsel_id2antcfg(struct antsel_info *asi, u8 id);
|
||||
static u16 brcms_c_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg);
|
||||
static void brcms_c_antsel_init_cfg(struct antsel_info *asi,
|
||||
struct brcms_antselcfg *antsel,
|
||||
bool auto_sel);
|
||||
|
||||
const u16 mimo_2x4_div_antselpat_tbl[] = {
|
||||
0, 0, 0x9, 0xa, /* ant0: 0 ant1: 2,3 */
|
||||
0, 0, 0x5, 0x6, /* ant0: 1 ant1: 2,3 */
|
||||
0, 0, 0, 0, /* n.a. */
|
||||
0, 0, 0, 0 /* n.a. */
|
||||
};
|
||||
|
||||
const u8 mimo_2x4_div_antselid_tbl[16] = {
|
||||
0, 0, 0, 0, 0, 2, 3, 0,
|
||||
0, 0, 1, 0, 0, 0, 0, 0 /* pat to antselid */
|
||||
};
|
||||
|
||||
const u16 mimo_2x3_div_antselpat_tbl[] = {
|
||||
16, 0, 1, 16, /* ant0: 0 ant1: 1,2 */
|
||||
16, 16, 16, 16, /* n.a. */
|
||||
16, 2, 16, 16, /* ant0: 2 ant1: 1 */
|
||||
16, 16, 16, 16 /* n.a. */
|
||||
};
|
||||
|
||||
const u8 mimo_2x3_div_antselid_tbl[16] = {
|
||||
0, 1, 2, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0 /* pat to antselid */
|
||||
};
|
||||
|
||||
struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
|
||||
{
|
||||
struct antsel_info *asi;
|
||||
|
||||
asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC);
|
||||
if (!asi) {
|
||||
wiphy_err(wlc->wiphy, "wl%d: brcms_c_antsel_attach: out of "
|
||||
"mem\n", wlc->pub->unit);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
asi->wlc = wlc;
|
||||
asi->pub = wlc->pub;
|
||||
asi->antsel_type = ANTSEL_NA;
|
||||
asi->antsel_avail = false;
|
||||
asi->antsel_antswitch = (u8) getintvar(asi->pub->vars, "antswitch");
|
||||
|
||||
if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) {
|
||||
switch (asi->antsel_antswitch) {
|
||||
case ANTSWITCH_TYPE_1:
|
||||
case ANTSWITCH_TYPE_2:
|
||||
case ANTSWITCH_TYPE_3:
|
||||
/* 4321/2 board with 2x3 switch logic */
|
||||
asi->antsel_type = ANTSEL_2x3;
|
||||
/* Antenna selection availability */
|
||||
if (((u16) getintvar(asi->pub->vars, "aa2g") == 7) ||
|
||||
((u16) getintvar(asi->pub->vars, "aa5g") == 7)) {
|
||||
asi->antsel_avail = true;
|
||||
} else
|
||||
if (((u16) getintvar(asi->pub->vars, "aa2g") ==
|
||||
3)
|
||||
|| ((u16) getintvar(asi->pub->vars, "aa5g")
|
||||
== 3)) {
|
||||
asi->antsel_avail = false;
|
||||
} else {
|
||||
asi->antsel_avail = false;
|
||||
wiphy_err(wlc->wiphy, "antsel_attach: 2o3 "
|
||||
"board cfg invalid\n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if ((asi->pub->sromrev == 4) &&
|
||||
((u16) getintvar(asi->pub->vars, "aa2g") == 7) &&
|
||||
((u16) getintvar(asi->pub->vars, "aa5g") == 0)) {
|
||||
/* hack to match old 4321CB2 cards with 2of3 antenna switch */
|
||||
asi->antsel_type = ANTSEL_2x3;
|
||||
asi->antsel_avail = true;
|
||||
} else if (asi->pub->boardflags2 & BFL2_2X4_DIV) {
|
||||
asi->antsel_type = ANTSEL_2x4;
|
||||
asi->antsel_avail = true;
|
||||
}
|
||||
|
||||
/* Set the antenna selection type for the low driver */
|
||||
brcms_b_antsel_type_set(wlc->hw, asi->antsel_type);
|
||||
|
||||
/* Init (auto/manual) antenna selection */
|
||||
brcms_c_antsel_init_cfg(asi, &asi->antcfg_11n, true);
|
||||
brcms_c_antsel_init_cfg(asi, &asi->antcfg_cur, true);
|
||||
|
||||
return asi;
|
||||
}
|
||||
|
||||
void brcms_c_antsel_detach(struct antsel_info *asi)
|
||||
{
|
||||
kfree(asi);
|
||||
}
|
||||
|
||||
void brcms_c_antsel_init(struct antsel_info *asi)
|
||||
{
|
||||
if ((asi->antsel_type == ANTSEL_2x3) ||
|
||||
(asi->antsel_type == ANTSEL_2x4))
|
||||
brcms_c_antsel_cfgupd(asi, &asi->antcfg_11n);
|
||||
}
|
||||
|
||||
/* boardlevel antenna selection: init antenna selection structure */
|
||||
static void
|
||||
brcms_c_antsel_init_cfg(struct antsel_info *asi, struct brcms_antselcfg *antsel,
|
||||
bool auto_sel)
|
||||
{
|
||||
if (asi->antsel_type == ANTSEL_2x3) {
|
||||
u8 antcfg_def = ANT_SELCFG_DEF_2x3 |
|
||||
((asi->antsel_avail && auto_sel) ? ANT_SELCFG_AUTO : 0);
|
||||
antsel->ant_config[ANT_SELCFG_TX_DEF] = antcfg_def;
|
||||
antsel->ant_config[ANT_SELCFG_TX_UNICAST] = antcfg_def;
|
||||
antsel->ant_config[ANT_SELCFG_RX_DEF] = antcfg_def;
|
||||
antsel->ant_config[ANT_SELCFG_RX_UNICAST] = antcfg_def;
|
||||
antsel->num_antcfg = ANT_SELCFG_NUM_2x3;
|
||||
|
||||
} else if (asi->antsel_type == ANTSEL_2x4) {
|
||||
|
||||
antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x4;
|
||||
antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x4;
|
||||
antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x4;
|
||||
antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x4;
|
||||
antsel->num_antcfg = ANT_SELCFG_NUM_2x4;
|
||||
|
||||
} else { /* no antenna selection available */
|
||||
|
||||
antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x2;
|
||||
antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x2;
|
||||
antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x2;
|
||||
antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x2;
|
||||
antsel->num_antcfg = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel,
|
||||
u8 antselid, u8 fbantselid, u8 *antcfg,
|
||||
u8 *fbantcfg)
|
||||
{
|
||||
u8 ant;
|
||||
|
||||
/* if use default, assign it and return */
|
||||
if (usedef) {
|
||||
*antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_DEF];
|
||||
*fbantcfg = *antcfg;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sel) {
|
||||
*antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
|
||||
*fbantcfg = *antcfg;
|
||||
|
||||
} else {
|
||||
ant = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
|
||||
if ((ant & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) {
|
||||
*antcfg = brcms_c_antsel_id2antcfg(asi, antselid);
|
||||
*fbantcfg = brcms_c_antsel_id2antcfg(asi, fbantselid);
|
||||
} else {
|
||||
*antcfg =
|
||||
asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
|
||||
*fbantcfg = *antcfg;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* boardlevel antenna selection: convert mimo_antsel (ucode interface) to id */
|
||||
u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel)
|
||||
{
|
||||
u8 antselid = 0;
|
||||
|
||||
if (asi->antsel_type == ANTSEL_2x4) {
|
||||
/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
|
||||
antselid = mimo_2x4_div_antselid_tbl[(antsel & 0xf)];
|
||||
return antselid;
|
||||
|
||||
} else if (asi->antsel_type == ANTSEL_2x3) {
|
||||
/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
|
||||
antselid = mimo_2x3_div_antselid_tbl[(antsel & 0xf)];
|
||||
return antselid;
|
||||
}
|
||||
|
||||
return antselid;
|
||||
}
|
||||
|
||||
/* boardlevel antenna selection: convert id to ant_cfg */
|
||||
static u8 brcms_c_antsel_id2antcfg(struct antsel_info *asi, u8 id)
|
||||
{
|
||||
u8 antcfg = ANT_SELCFG_DEF_2x2;
|
||||
|
||||
if (asi->antsel_type == ANTSEL_2x4) {
|
||||
/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
|
||||
antcfg = (((id & 0x2) << 3) | ((id & 0x1) + 2));
|
||||
return antcfg;
|
||||
|
||||
} else if (asi->antsel_type == ANTSEL_2x3) {
|
||||
/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
|
||||
antcfg = (((id & 0x02) << 4) | ((id & 0x1) + 1));
|
||||
return antcfg;
|
||||
}
|
||||
|
||||
return antcfg;
|
||||
}
|
||||
|
||||
/* boardlevel antenna selection: convert ant_cfg to mimo_antsel (ucode interface) */
|
||||
static u16 brcms_c_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg)
|
||||
{
|
||||
u8 idx = BRCMS_ANTIDX_11N(BRCMS_ANTSEL_11N(ant_cfg));
|
||||
u16 mimo_antsel = 0;
|
||||
|
||||
if (asi->antsel_type == ANTSEL_2x4) {
|
||||
/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
|
||||
mimo_antsel = (mimo_2x4_div_antselpat_tbl[idx] & 0xf);
|
||||
return mimo_antsel;
|
||||
|
||||
} else if (asi->antsel_type == ANTSEL_2x3) {
|
||||
/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
|
||||
mimo_antsel = (mimo_2x3_div_antselpat_tbl[idx] & 0xf);
|
||||
return mimo_antsel;
|
||||
}
|
||||
|
||||
return mimo_antsel;
|
||||
}
|
||||
|
||||
/* boardlevel antenna selection: ucode interface control */
|
||||
static int brcms_c_antsel_cfgupd(struct antsel_info *asi,
|
||||
struct brcms_antselcfg *antsel)
|
||||
{
|
||||
struct brcms_c_info *wlc = asi->wlc;
|
||||
u8 ant_cfg;
|
||||
u16 mimo_antsel;
|
||||
|
||||
/* 1) Update TX antconfig for all frames that are not unicast data
|
||||
* (aka default TX)
|
||||
*/
|
||||
ant_cfg = antsel->ant_config[ANT_SELCFG_TX_DEF];
|
||||
mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg);
|
||||
brcms_c_write_shm(wlc, M_MIMO_ANTSEL_TXDFLT, mimo_antsel);
|
||||
/* Update driver stats for currently selected default tx/rx antenna config */
|
||||
asi->antcfg_cur.ant_config[ANT_SELCFG_TX_DEF] = ant_cfg;
|
||||
|
||||
/* 2) Update RX antconfig for all frames that are not unicast data
|
||||
* (aka default RX)
|
||||
*/
|
||||
ant_cfg = antsel->ant_config[ANT_SELCFG_RX_DEF];
|
||||
mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg);
|
||||
brcms_c_write_shm(wlc, M_MIMO_ANTSEL_RXDFLT, mimo_antsel);
|
||||
/* Update driver stats for currently selected default tx/rx antenna config */
|
||||
asi->antcfg_cur.ant_config[ANT_SELCFG_RX_DEF] = ant_cfg;
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_ANTSEL_H_
|
||||
#define _BRCM_ANTSEL_H_
|
||||
|
||||
extern struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_antsel_detach(struct antsel_info *asi);
|
||||
extern void brcms_c_antsel_init(struct antsel_info *asi);
|
||||
extern void brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef,
|
||||
bool sel,
|
||||
u8 id, u8 fbid, u8 *antcfg,
|
||||
u8 *fbantcfg);
|
||||
extern u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel);
|
||||
|
||||
#endif /* _BRCM_ANTSEL_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,174 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef _BRCM_BOTTOM_MAC_H_
|
||||
#define _BRCM_BOTTOM_MAC_H_
|
||||
|
||||
#include <brcmu_wifi.h>
|
||||
#include "types.h"
|
||||
|
||||
/* dup state between BMAC(struct brcms_hardware) and HIGH(struct brcms_c_info)
|
||||
driver */
|
||||
struct brcms_b_state {
|
||||
u32 machwcap; /* mac hw capibility */
|
||||
u32 preamble_ovr; /* preamble override */
|
||||
};
|
||||
|
||||
enum {
|
||||
IOV_BMAC_DIAG,
|
||||
IOV_BMAC_SBGPIOTIMERVAL,
|
||||
IOV_BMAC_SBGPIOOUT,
|
||||
IOV_BMAC_CCGPIOCTRL, /* CC GPIOCTRL REG */
|
||||
IOV_BMAC_CCGPIOOUT, /* CC GPIOOUT REG */
|
||||
IOV_BMAC_CCGPIOOUTEN, /* CC GPIOOUTEN REG */
|
||||
IOV_BMAC_CCGPIOIN, /* CC GPIOIN REG */
|
||||
IOV_BMAC_WPSGPIO, /* WPS push button GPIO pin */
|
||||
IOV_BMAC_OTPDUMP,
|
||||
IOV_BMAC_OTPSTAT,
|
||||
IOV_BMAC_PCIEASPM, /* obfuscation clkreq/aspm control */
|
||||
IOV_BMAC_PCIEADVCORRMASK, /* advanced correctable error mask */
|
||||
IOV_BMAC_PCIECLKREQ, /* PCIE 1.1 clockreq enab support */
|
||||
IOV_BMAC_PCIELCREG, /* PCIE LCREG */
|
||||
IOV_BMAC_SBGPIOTIMERMASK,
|
||||
IOV_BMAC_RFDISABLEDLY,
|
||||
IOV_BMAC_PCIEREG, /* PCIE REG */
|
||||
IOV_BMAC_PCICFGREG, /* PCI Config register */
|
||||
IOV_BMAC_PCIESERDESREG, /* PCIE SERDES REG (dev, 0}offset) */
|
||||
IOV_BMAC_PCIEGPIOOUT, /* PCIEOUT REG */
|
||||
IOV_BMAC_PCIEGPIOOUTEN, /* PCIEOUTEN REG */
|
||||
IOV_BMAC_PCIECLKREQENCTRL, /* clkreqenctrl REG (PCIE REV > 6.0 */
|
||||
IOV_BMAC_DMALPBK,
|
||||
IOV_BMAC_CCREG,
|
||||
IOV_BMAC_COREREG,
|
||||
IOV_BMAC_SDCIS,
|
||||
IOV_BMAC_SDIO_DRIVE,
|
||||
IOV_BMAC_OTPW,
|
||||
IOV_BMAC_NVOTPW,
|
||||
IOV_BMAC_SROM,
|
||||
IOV_BMAC_SRCRC,
|
||||
IOV_BMAC_CIS_SOURCE,
|
||||
IOV_BMAC_CISVAR,
|
||||
IOV_BMAC_OTPLOCK,
|
||||
IOV_BMAC_OTP_CHIPID,
|
||||
IOV_BMAC_CUSTOMVAR1,
|
||||
IOV_BMAC_BOARDFLAGS,
|
||||
IOV_BMAC_BOARDFLAGS2,
|
||||
IOV_BMAC_WPSLED,
|
||||
IOV_BMAC_NVRAM_SOURCE,
|
||||
IOV_BMAC_OTP_RAW_READ,
|
||||
IOV_BMAC_LAST
|
||||
};
|
||||
|
||||
extern int brcms_b_attach(struct brcms_c_info *wlc, u16 vendor, u16 device,
|
||||
uint unit, bool piomode, void *regsva, uint bustype,
|
||||
void *btparam);
|
||||
extern int brcms_b_detach(struct brcms_c_info *wlc);
|
||||
extern void brcms_b_watchdog(void *arg);
|
||||
|
||||
/* up/down, reset, clk */
|
||||
extern void brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw,
|
||||
uint offset, const void *buf, int len,
|
||||
u32 sel);
|
||||
extern void brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset,
|
||||
void *buf, int len, u32 sel);
|
||||
#define brcms_b_copyfrom_shm(wlc_hw, offset, buf, len) \
|
||||
brcms_b_copyfrom_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL)
|
||||
#define brcms_b_copyto_shm(wlc_hw, offset, buf, len) \
|
||||
brcms_b_copyto_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL)
|
||||
|
||||
extern void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw);
|
||||
extern void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on);
|
||||
extern void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk);
|
||||
extern void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk);
|
||||
extern void brcms_b_phy_reset(struct brcms_hardware *wlc_hw);
|
||||
extern void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags);
|
||||
extern void brcms_b_reset(struct brcms_hardware *wlc_hw);
|
||||
extern void brcms_b_init(struct brcms_hardware *wlc_hw, chanspec_t chanspec,
|
||||
bool mute);
|
||||
extern int brcms_b_up_prep(struct brcms_hardware *wlc_hw);
|
||||
extern int brcms_b_up_finish(struct brcms_hardware *wlc_hw);
|
||||
extern int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw);
|
||||
extern int brcms_b_down_finish(struct brcms_hardware *wlc_hw);
|
||||
extern void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode);
|
||||
|
||||
/* chanspec, ucode interface */
|
||||
extern void brcms_b_set_chanspec(struct brcms_hardware *wlc_hw,
|
||||
chanspec_t chanspec,
|
||||
bool mute, struct txpwr_limits *txpwr);
|
||||
|
||||
extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
|
||||
uint *blocks);
|
||||
extern void brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask,
|
||||
u16 val, int bands);
|
||||
extern void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val);
|
||||
extern u16 brcms_b_mhf_get(struct brcms_hardware *wlc_hw, u8 idx, int bands);
|
||||
extern void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant);
|
||||
extern u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw);
|
||||
extern void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw,
|
||||
u8 antsel_type);
|
||||
extern int brcms_b_state_get(struct brcms_hardware *wlc_hw,
|
||||
struct brcms_b_state *state);
|
||||
extern void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset,
|
||||
u16 v);
|
||||
extern u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset);
|
||||
extern void brcms_b_write_template_ram(struct brcms_hardware *wlc_hw,
|
||||
int offset, int len, void *buf);
|
||||
extern void brcms_b_copyfrom_vars(struct brcms_hardware *wlc_hw, char **buf,
|
||||
uint *len);
|
||||
|
||||
extern void brcms_b_hw_etheraddr(struct brcms_hardware *wlc_hw,
|
||||
u8 *ea);
|
||||
|
||||
extern bool brcms_b_radio_read_hwdisabled(struct brcms_hardware *wlc_hw);
|
||||
extern void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw,
|
||||
bool shortslot);
|
||||
extern void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw,
|
||||
u8 stf_mode);
|
||||
|
||||
extern void brcms_b_wait_for_wake(struct brcms_hardware *wlc_hw);
|
||||
|
||||
extern void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw,
|
||||
u32 override_bit);
|
||||
extern void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw,
|
||||
u32 override_bit);
|
||||
|
||||
extern void brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw,
|
||||
int match_reg_offset,
|
||||
const u8 *addr);
|
||||
extern void brcms_b_write_hw_bcntemplates(struct brcms_hardware *wlc_hw,
|
||||
void *bcn, int len, bool both);
|
||||
|
||||
extern void brcms_b_read_tsf(struct brcms_hardware *wlc_hw, u32 *tsf_l_ptr,
|
||||
u32 *tsf_h_ptr);
|
||||
extern void brcms_b_set_cwmin(struct brcms_hardware *wlc_hw, u16 newmin);
|
||||
extern void brcms_b_set_cwmax(struct brcms_hardware *wlc_hw, u16 newmax);
|
||||
|
||||
extern void brcms_b_retrylimit_upd(struct brcms_hardware *wlc_hw, u16 SRL,
|
||||
u16 LRL);
|
||||
|
||||
extern void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw);
|
||||
|
||||
|
||||
/* API for BMAC driver (e.g. wlc_phy.c etc) */
|
||||
|
||||
extern void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw);
|
||||
extern void brcms_b_pllreq(struct brcms_hardware *wlc_hw, bool set,
|
||||
mbool req_bit);
|
||||
extern void brcms_b_hw_up(struct brcms_hardware *wlc_hw);
|
||||
extern u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate);
|
||||
extern void brcms_b_antsel_set(struct brcms_hardware *wlc_hw,
|
||||
u32 antsel_avail);
|
||||
|
||||
#endif /* _BRCM_BOTTOM_MAC_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_CHANNEL_H_
|
||||
#define _BRCM_CHANNEL_H_
|
||||
|
||||
/* conversion for phy txpwr calculations that use .25 dB units */
|
||||
#define BRCMS_TXPWR_DB_FACTOR 4
|
||||
|
||||
|
||||
/* maxpwr mapping to 5GHz band channels:
|
||||
* maxpwr[0] - channels [34-48]
|
||||
* maxpwr[1] - channels [52-60]
|
||||
* maxpwr[2] - channels [62-64]
|
||||
* maxpwr[3] - channels [100-140]
|
||||
* maxpwr[4] - channels [149-165]
|
||||
*/
|
||||
#define BAND_5G_PWR_LVLS 5 /* 5 power levels for 5G */
|
||||
|
||||
/* power level in group of 2.4GHz band channels:
|
||||
* maxpwr[0] - CCK channels [1]
|
||||
* maxpwr[1] - CCK channels [2-10]
|
||||
* maxpwr[2] - CCK channels [11-14]
|
||||
* maxpwr[3] - OFDM channels [1]
|
||||
* maxpwr[4] - OFDM channels [2-10]
|
||||
* maxpwr[5] - OFDM channels [11-14]
|
||||
*/
|
||||
|
||||
/* macro to get 2.4 GHz channel group index for tx power */
|
||||
#define CHANNEL_POWER_IDX_2G_CCK(c) (((c) < 2) ? 0 : (((c) < 11) ? 1 : 2)) /* cck index */
|
||||
#define CHANNEL_POWER_IDX_2G_OFDM(c) (((c) < 2) ? 3 : (((c) < 11) ? 4 : 5)) /* ofdm index */
|
||||
|
||||
/* macro to get 5 GHz channel group index for tx power */
|
||||
#define CHANNEL_POWER_IDX_5G(c) \
|
||||
(((c) < 52) ? 0 : (((c) < 62) ? 1 : (((c) < 100) ? 2 : (((c) < 149) ? 3 : 4))))
|
||||
|
||||
/* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */
|
||||
#define BRCMS_MAXPWR_TBL_SIZE 6
|
||||
/* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */
|
||||
#define BRCMS_MAXPWR_MIMO_TBL_SIZE 14
|
||||
|
||||
#define NBANDS(wlc) ((wlc)->pub->_nbands)
|
||||
#define NBANDS_PUB(pub) ((pub)->_nbands)
|
||||
#define NBANDS_HW(hw) ((hw)->_nbands)
|
||||
|
||||
#define IS_SINGLEBAND_5G(device) 0
|
||||
|
||||
/* locale channel and power info. */
|
||||
struct locale_info {
|
||||
u32 valid_channels;
|
||||
/* List of radar sensitive channels */
|
||||
u8 radar_channels;
|
||||
/* List of channels used only if APs are detected */
|
||||
u8 restricted_channels;
|
||||
/* Max tx pwr in qdBm for each sub-band */
|
||||
s8 maxpwr[BRCMS_MAXPWR_TBL_SIZE];
|
||||
s8 pub_maxpwr[BAND_5G_PWR_LVLS]; /* Country IE advertised max tx pwr in dBm
|
||||
* per sub-band
|
||||
*/
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
/* bits for locale_info flags */
|
||||
#define BRCMS_PEAK_CONDUCTED 0x00 /* Peak for locals */
|
||||
#define BRCMS_EIRP 0x01 /* Flag for EIRP */
|
||||
#define BRCMS_DFS_TPC 0x02 /* Flag for DFS TPC */
|
||||
#define BRCMS_NO_OFDM 0x04 /* Flag for No OFDM */
|
||||
#define BRCMS_NO_40MHZ 0x08 /* Flag for No MIMO 40MHz */
|
||||
#define BRCMS_NO_MIMO 0x10 /* Flag for No MIMO, 20 or 40 MHz */
|
||||
#define BRCMS_RADAR_TYPE_EU 0x20 /* Flag for EU */
|
||||
#define BRCMS_DFS_FCC BRCMS_DFS_TPC /* Flag for DFS FCC */
|
||||
#define BRCMS_DFS_EU (BRCMS_DFS_TPC | BRCMS_RADAR_TYPE_EU) /* Flag for DFS EU */
|
||||
|
||||
#define ISDFS_EU(fl) (((fl) & BRCMS_DFS_EU) == BRCMS_DFS_EU)
|
||||
|
||||
/* locale per-channel tx power limits for MIMO frames
|
||||
* maxpwr arrays are index by channel for 2.4 GHz limits, and
|
||||
* by sub-band for 5 GHz limits using CHANNEL_POWER_IDX_5G(channel)
|
||||
*/
|
||||
struct locale_mimo_info {
|
||||
/* tx 20 MHz power limits, qdBm units */
|
||||
s8 maxpwr20[BRCMS_MAXPWR_MIMO_TBL_SIZE];
|
||||
/* tx 40 MHz power limits, qdBm units */
|
||||
s8 maxpwr40[BRCMS_MAXPWR_MIMO_TBL_SIZE];
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
extern const chanvec_t chanvec_all_2G;
|
||||
extern const chanvec_t chanvec_all_5G;
|
||||
|
||||
/*
|
||||
* Country names and abbreviations with locale defined from ISO 3166
|
||||
*/
|
||||
struct country_info {
|
||||
const u8 locale_2G; /* 2.4G band locale */
|
||||
const u8 locale_5G; /* 5G band locale */
|
||||
const u8 locale_mimo_2G; /* 2.4G mimo info */
|
||||
const u8 locale_mimo_5G; /* 5G mimo info */
|
||||
};
|
||||
|
||||
extern struct brcms_cm_info *
|
||||
brcms_c_channel_mgr_attach(struct brcms_c_info *wlc);
|
||||
|
||||
extern void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm);
|
||||
|
||||
extern u8 brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm,
|
||||
uint bandunit);
|
||||
|
||||
extern bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm,
|
||||
chanspec_t chspec);
|
||||
|
||||
extern void brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm,
|
||||
chanspec_t chanspec,
|
||||
struct txpwr_limits *txpwr);
|
||||
extern void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm,
|
||||
chanspec_t chanspec,
|
||||
u8 local_constraint_qdbm);
|
||||
|
||||
#endif /* _WLC_CHANNEL_H */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,250 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_DMA_H_
|
||||
#define _BRCM_DMA_H_
|
||||
|
||||
#include "types.h" /* forward structure declarations */
|
||||
|
||||
/* DMA structure:
|
||||
* support two DMA engines: 32 bits address or 64 bit addressing
|
||||
* basic DMA register set is per channel(transmit or receive)
|
||||
* a pair of channels is defined for convenience
|
||||
*/
|
||||
|
||||
/* 32 bits addressing */
|
||||
|
||||
struct dma32diag { /* diag access */
|
||||
u32 fifoaddr; /* diag address */
|
||||
u32 fifodatalow; /* low 32bits of data */
|
||||
u32 fifodatahigh; /* high 32bits of data */
|
||||
u32 pad; /* reserved */
|
||||
};
|
||||
|
||||
/* 64 bits addressing */
|
||||
|
||||
/* dma registers per channel(xmt or rcv) */
|
||||
struct dma64regs {
|
||||
u32 control; /* enable, et al */
|
||||
u32 ptr; /* last descriptor posted to chip */
|
||||
u32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */
|
||||
u32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */
|
||||
u32 status0; /* current descriptor, xmt state */
|
||||
u32 status1; /* active descriptor, xmt error */
|
||||
};
|
||||
|
||||
/* map/unmap direction */
|
||||
#define DMA_TX 1 /* TX direction for DMA */
|
||||
#define DMA_RX 2 /* RX direction for DMA */
|
||||
#define BUS_SWAP32(v) (v)
|
||||
|
||||
/* range param for dma_getnexttxp() and dma_txreclaim */
|
||||
enum txd_range {
|
||||
DMA_RANGE_ALL = 1,
|
||||
DMA_RANGE_TRANSMITTED,
|
||||
DMA_RANGE_TRANSFERED
|
||||
};
|
||||
|
||||
/* dma function type */
|
||||
typedef void (*di_detach_t) (struct dma_pub *dmah);
|
||||
typedef bool(*di_txreset_t) (struct dma_pub *dmah);
|
||||
typedef bool(*di_rxreset_t) (struct dma_pub *dmah);
|
||||
typedef bool(*di_rxidle_t) (struct dma_pub *dmah);
|
||||
typedef void (*di_txinit_t) (struct dma_pub *dmah);
|
||||
typedef bool(*di_txenabled_t) (struct dma_pub *dmah);
|
||||
typedef void (*di_rxinit_t) (struct dma_pub *dmah);
|
||||
typedef void (*di_txsuspend_t) (struct dma_pub *dmah);
|
||||
typedef void (*di_txresume_t) (struct dma_pub *dmah);
|
||||
typedef bool(*di_txsuspended_t) (struct dma_pub *dmah);
|
||||
typedef bool(*di_txsuspendedidle_t) (struct dma_pub *dmah);
|
||||
typedef int (*di_txfast_t) (struct dma_pub *dmah, struct sk_buff *p,
|
||||
bool commit);
|
||||
typedef int (*di_txunframed_t) (struct dma_pub *dmah, void *p, uint len,
|
||||
bool commit);
|
||||
typedef void *(*di_getpos_t) (struct dma_pub *di, bool direction);
|
||||
typedef void (*di_fifoloopbackenable_t) (struct dma_pub *dmah);
|
||||
typedef bool(*di_txstopped_t) (struct dma_pub *dmah);
|
||||
typedef bool(*di_rxstopped_t) (struct dma_pub *dmah);
|
||||
typedef bool(*di_rxenable_t) (struct dma_pub *dmah);
|
||||
typedef bool(*di_rxenabled_t) (struct dma_pub *dmah);
|
||||
typedef void *(*di_rx_t) (struct dma_pub *dmah);
|
||||
typedef bool(*di_rxfill_t) (struct dma_pub *dmah);
|
||||
typedef void (*di_txreclaim_t) (struct dma_pub *dmah, enum txd_range range);
|
||||
typedef void (*di_rxreclaim_t) (struct dma_pub *dmah);
|
||||
typedef unsigned long (*di_getvar_t) (struct dma_pub *dmah,
|
||||
const char *name);
|
||||
typedef void *(*di_getnexttxp_t) (struct dma_pub *dmah, enum txd_range range);
|
||||
typedef void *(*di_getnextrxp_t) (struct dma_pub *dmah, bool forceall);
|
||||
typedef void *(*di_peeknexttxp_t) (struct dma_pub *dmah);
|
||||
typedef void *(*di_peeknextrxp_t) (struct dma_pub *dmah);
|
||||
typedef void (*di_rxparam_get_t) (struct dma_pub *dmah, u16 *rxoffset,
|
||||
u16 *rxbufsize);
|
||||
typedef void (*di_txblock_t) (struct dma_pub *dmah);
|
||||
typedef void (*di_txunblock_t) (struct dma_pub *dmah);
|
||||
typedef uint(*di_txactive_t) (struct dma_pub *dmah);
|
||||
typedef void (*di_txrotate_t) (struct dma_pub *dmah);
|
||||
typedef void (*di_counterreset_t) (struct dma_pub *dmah);
|
||||
typedef uint(*di_ctrlflags_t) (struct dma_pub *dmah, uint mask, uint flags);
|
||||
typedef char *(*di_dump_t) (struct dma_pub *dmah, struct brcmu_strbuf *b,
|
||||
bool dumpring);
|
||||
typedef char *(*di_dumptx_t) (struct dma_pub *dmah, struct brcmu_strbuf *b,
|
||||
bool dumpring);
|
||||
typedef char *(*di_dumprx_t) (struct dma_pub *dmah, struct brcmu_strbuf *b,
|
||||
bool dumpring);
|
||||
typedef uint(*di_rxactive_t) (struct dma_pub *dmah);
|
||||
typedef uint(*di_txpending_t) (struct dma_pub *dmah);
|
||||
typedef uint(*di_txcommitted_t) (struct dma_pub *dmah);
|
||||
|
||||
/* dma opsvec */
|
||||
struct di_fcn_s {
|
||||
di_detach_t detach;
|
||||
di_txinit_t txinit;
|
||||
di_txreset_t txreset;
|
||||
di_txenabled_t txenabled;
|
||||
di_txsuspend_t txsuspend;
|
||||
di_txresume_t txresume;
|
||||
di_txsuspended_t txsuspended;
|
||||
di_txsuspendedidle_t txsuspendedidle;
|
||||
di_txfast_t txfast;
|
||||
di_txunframed_t txunframed;
|
||||
di_getpos_t getpos;
|
||||
di_txstopped_t txstopped;
|
||||
di_txreclaim_t txreclaim;
|
||||
di_getnexttxp_t getnexttxp;
|
||||
di_peeknexttxp_t peeknexttxp;
|
||||
di_txblock_t txblock;
|
||||
di_txunblock_t txunblock;
|
||||
di_txactive_t txactive;
|
||||
di_txrotate_t txrotate;
|
||||
|
||||
di_rxinit_t rxinit;
|
||||
di_rxreset_t rxreset;
|
||||
di_rxidle_t rxidle;
|
||||
di_rxstopped_t rxstopped;
|
||||
di_rxenable_t rxenable;
|
||||
di_rxenabled_t rxenabled;
|
||||
di_rx_t rx;
|
||||
di_rxfill_t rxfill;
|
||||
di_rxreclaim_t rxreclaim;
|
||||
di_getnextrxp_t getnextrxp;
|
||||
di_peeknextrxp_t peeknextrxp;
|
||||
di_rxparam_get_t rxparam_get;
|
||||
|
||||
di_fifoloopbackenable_t fifoloopbackenable;
|
||||
di_getvar_t d_getvar;
|
||||
di_counterreset_t counterreset;
|
||||
di_ctrlflags_t ctrlflags;
|
||||
di_dump_t dump;
|
||||
di_dumptx_t dumptx;
|
||||
di_dumprx_t dumprx;
|
||||
di_rxactive_t rxactive;
|
||||
di_txpending_t txpending;
|
||||
di_txcommitted_t txcommitted;
|
||||
uint endnum;
|
||||
};
|
||||
|
||||
/*
|
||||
* Exported data structure (read-only)
|
||||
*/
|
||||
/* export structure */
|
||||
struct dma_pub {
|
||||
const struct di_fcn_s *di_fn; /* DMA function pointers */
|
||||
uint txavail; /* # free tx descriptors */
|
||||
uint dmactrlflags; /* dma control flags */
|
||||
|
||||
/* rx error counters */
|
||||
uint rxgiants; /* rx giant frames */
|
||||
uint rxnobuf; /* rx out of dma descriptors */
|
||||
/* tx error counters */
|
||||
uint txnobuf; /* tx out of dma descriptors */
|
||||
};
|
||||
|
||||
extern struct dma_pub *dma_attach(char *name, struct si_pub *sih,
|
||||
void *dmaregstx, void *dmaregsrx, uint ntxd,
|
||||
uint nrxd, uint rxbufsize, int rxextheadroom,
|
||||
uint nrxpost, uint rxoffset, uint *msg_level);
|
||||
|
||||
extern const struct di_fcn_s dma64proc;
|
||||
|
||||
#define dma_detach(di) (dma64proc.detach(di))
|
||||
#define dma_txreset(di) (dma64proc.txreset(di))
|
||||
#define dma_rxreset(di) (dma64proc.rxreset(di))
|
||||
#define dma_rxidle(di) (dma64proc.rxidle(di))
|
||||
#define dma_txinit(di) (dma64proc.txinit(di))
|
||||
#define dma_txenabled(di) (dma64proc.txenabled(di))
|
||||
#define dma_rxinit(di) (dma64proc.rxinit(di))
|
||||
#define dma_txsuspend(di) (dma64proc.txsuspend(di))
|
||||
#define dma_txresume(di) (dma64proc.txresume(di))
|
||||
#define dma_txsuspended(di) (dma64proc.txsuspended(di))
|
||||
#define dma_txsuspendedidle(di) (dma64proc.txsuspendedidle(di))
|
||||
#define dma_txfast(di, p, commit) (dma64proc.txfast(di, p, commit))
|
||||
#define dma_txunframed(di, p, l, commit)(dma64proc.txunframed(di, p, l, commit))
|
||||
#define dma_getpos(di, dir) (dma64proc.getpos(di, dir))
|
||||
#define dma_fifoloopbackenable(di) (dma64proc.fifoloopbackenable(di))
|
||||
#define dma_txstopped(di) (dma64proc.txstopped(di))
|
||||
#define dma_rxstopped(di) (dma64proc.rxstopped(di))
|
||||
#define dma_rxenable(di) (dma64proc.rxenable(di))
|
||||
#define dma_rxenabled(di) (dma64proc.rxenabled(di))
|
||||
#define dma_rx(di) (dma64proc.rx(di))
|
||||
#define dma_rxfill(di) (dma64proc.rxfill(di))
|
||||
#define dma_txreclaim(di, range) (dma64proc.txreclaim(di, range))
|
||||
#define dma_rxreclaim(di) (dma64proc.rxreclaim(di))
|
||||
#define dma_getvar(di, name) (dma64proc.d_getvar(di, name))
|
||||
#define dma_getnexttxp(di, range) (dma64proc.getnexttxp(di, range))
|
||||
#define dma_getnextrxp(di, forceall) (dma64proc.getnextrxp(di, forceall))
|
||||
#define dma_peeknexttxp(di) (dma64proc.peeknexttxp(di))
|
||||
#define dma_peeknextrxp(di) (dma64proc.peeknextrxp(di))
|
||||
#define dma_rxparam_get(di, off, bufs) (dma64proc.rxparam_get(di, off, bufs))
|
||||
|
||||
#define dma_txblock(di) (dma64proc.txblock(di))
|
||||
#define dma_txunblock(di) (dma64proc.txunblock(di))
|
||||
#define dma_txactive(di) (dma64proc.txactive(di))
|
||||
#define dma_rxactive(di) (dma64proc.rxactive(di))
|
||||
#define dma_txrotate(di) (dma64proc.txrotate(di))
|
||||
#define dma_counterreset(di) (dma64proc.counterreset(di))
|
||||
#define dma_ctrlflags(di, mask, flags) (dma64proc.ctrlflags((di), (mask), (flags)))
|
||||
#define dma_txpending(di) (dma64proc.txpending(di))
|
||||
#define dma_txcommitted(di) (dma64proc.txcommitted(di))
|
||||
|
||||
|
||||
/* return addresswidth allowed
|
||||
* This needs to be done after SB attach but before dma attach.
|
||||
* SB attach provides ability to probe backplane and dma core capabilities
|
||||
* This info is needed by DMA_ALLOC_CONSISTENT in dma attach
|
||||
*/
|
||||
extern uint dma_addrwidth(struct si_pub *sih, void *dmaregs);
|
||||
void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
|
||||
(void *pkt, void *arg_a), void *arg_a);
|
||||
|
||||
/*
|
||||
* DMA(Bug) on some chips seems to declare that the packet is ready, but the
|
||||
* packet length is not updated yet (by DMA) on the expected time.
|
||||
* Workaround is to hold processor till DMA updates the length, and stay off
|
||||
* the bus to allow DMA update the length in buffer
|
||||
*/
|
||||
static inline void dma_spin_for_len(uint len, struct sk_buff *head)
|
||||
{
|
||||
#if defined(__mips__)
|
||||
if (!len) {
|
||||
while (!(len = *(u16 *) KSEG1ADDR(head->data)))
|
||||
udelay(1);
|
||||
|
||||
*(u16 *) (head->data) = cpu_to_le16((u16) len);
|
||||
}
|
||||
#endif /* defined(__mips__) */
|
||||
}
|
||||
|
||||
#endif /* _BRCM_DMA_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_MAC80211_IF_H_
|
||||
#define _BRCM_MAC80211_IF_H_
|
||||
|
||||
#include <linux/timer.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
/* softmac ioctl definitions */
|
||||
#define BRCMS_SET_SHORTSLOT_OVERRIDE 146
|
||||
|
||||
|
||||
/* BMAC Note: High-only driver is no longer working in softirq context as it needs to block and
|
||||
* sleep so perimeter lock has to be a semaphore instead of spinlock. This requires timers to be
|
||||
* submitted to workqueue instead of being on kernel timer
|
||||
*/
|
||||
struct brcms_timer {
|
||||
struct timer_list timer;
|
||||
struct brcms_info *wl;
|
||||
void (*fn) (void *);
|
||||
void *arg; /* argument to fn */
|
||||
uint ms;
|
||||
bool periodic;
|
||||
bool set;
|
||||
struct brcms_timer *next;
|
||||
#ifdef BCMDBG
|
||||
char *name; /* Description of the timer */
|
||||
#endif
|
||||
};
|
||||
|
||||
struct brcms_if {
|
||||
uint subunit; /* WDS/BSS unit */
|
||||
struct pci_dev *pci_dev;
|
||||
};
|
||||
|
||||
#define MAX_FW_IMAGES 4
|
||||
struct brcms_firmware {
|
||||
u32 fw_cnt;
|
||||
const struct firmware *fw_bin[MAX_FW_IMAGES];
|
||||
const struct firmware *fw_hdr[MAX_FW_IMAGES];
|
||||
u32 hdr_num_entries[MAX_FW_IMAGES];
|
||||
};
|
||||
|
||||
struct brcms_info {
|
||||
struct brcms_pub *pub; /* pointer to public wlc state */
|
||||
void *wlc; /* pointer to private common os-independent data */
|
||||
u32 magic;
|
||||
|
||||
int irq;
|
||||
|
||||
spinlock_t lock; /* per-device perimeter lock */
|
||||
spinlock_t isr_lock; /* per-device ISR synchronization lock */
|
||||
|
||||
/* bus type and regsva for unmap in brcms_free() */
|
||||
uint bcm_bustype; /* bus type */
|
||||
void *regsva; /* opaque chip registers virtual address */
|
||||
|
||||
/* timer related fields */
|
||||
atomic_t callbacks; /* # outstanding callback functions */
|
||||
struct brcms_timer *timers; /* timer cleanup queue */
|
||||
|
||||
struct tasklet_struct tasklet; /* dpc tasklet */
|
||||
bool resched; /* dpc needs to be and is rescheduled */
|
||||
#ifdef LINUXSTA_PS
|
||||
u32 pci_psstate[16]; /* pci ps-state save/restore */
|
||||
#endif
|
||||
struct brcms_firmware fw;
|
||||
struct wiphy *wiphy;
|
||||
};
|
||||
|
||||
/* misc callbacks */
|
||||
extern void brcms_init(struct brcms_info *wl);
|
||||
extern uint brcms_reset(struct brcms_info *wl);
|
||||
extern void brcms_intrson(struct brcms_info *wl);
|
||||
extern u32 brcms_intrsoff(struct brcms_info *wl);
|
||||
extern void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask);
|
||||
extern int brcms_up(struct brcms_info *wl);
|
||||
extern void brcms_down(struct brcms_info *wl);
|
||||
extern void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif,
|
||||
bool state, int prio);
|
||||
extern bool wl_alloc_dma_resources(struct brcms_info *wl, uint dmaddrwidth);
|
||||
extern bool brcms_rfkill_set_hw_state(struct brcms_info *wl);
|
||||
|
||||
/* timer functions */
|
||||
extern struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
|
||||
void (*fn) (void *arg), void *arg,
|
||||
const char *name);
|
||||
extern void brcms_free_timer(struct brcms_info *wl, struct brcms_timer *timer);
|
||||
extern void brcms_add_timer(struct brcms_info *wl, struct brcms_timer *timer,
|
||||
uint ms, int periodic);
|
||||
extern bool brcms_del_timer(struct brcms_info *wl, struct brcms_timer *timer);
|
||||
extern void brcms_msleep(struct brcms_info *wl, uint ms);
|
||||
|
||||
#endif /* _BRCM_MAC80211_IF_H_ */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,850 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <defs.h>
|
||||
#include <soc.h>
|
||||
#include <chipcommon.h>
|
||||
#include "aiutils.h"
|
||||
#include "pub.h"
|
||||
#include "nicpci.h"
|
||||
|
||||
/* SPROM offsets */
|
||||
#define SRSH_ASPM_OFFSET 4 /* word 4 */
|
||||
#define SRSH_ASPM_ENB 0x18 /* bit 3, 4 */
|
||||
#define SRSH_ASPM_L1_ENB 0x10 /* bit 4 */
|
||||
#define SRSH_ASPM_L0s_ENB 0x8 /* bit 3 */
|
||||
|
||||
#define SRSH_PCIE_MISC_CONFIG 5 /* word 5 */
|
||||
#define SRSH_L23READY_EXIT_NOPERST 0x8000 /* bit 15 */
|
||||
#define SRSH_CLKREQ_OFFSET_REV5 20 /* word 20 for srom rev <= 5 */
|
||||
#define SRSH_CLKREQ_ENB 0x0800 /* bit 11 */
|
||||
#define SRSH_BD_OFFSET 6 /* word 6 */
|
||||
|
||||
/* chipcontrol */
|
||||
#define CHIPCTRL_4321_PLL_DOWN 0x800000/* serdes PLL down override */
|
||||
|
||||
/* MDIO control */
|
||||
#define MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */
|
||||
#define MDIOCTL_DIVISOR_VAL 0x2
|
||||
#define MDIOCTL_PREAM_EN 0x80 /* Enable preamble sequnce */
|
||||
#define MDIOCTL_ACCESS_DONE 0x100 /* Transaction complete */
|
||||
|
||||
/* MDIO Data */
|
||||
#define MDIODATA_MASK 0x0000ffff /* data 2 bytes */
|
||||
#define MDIODATA_TA 0x00020000 /* Turnaround */
|
||||
|
||||
#define MDIODATA_REGADDR_SHF 18 /* Regaddr shift */
|
||||
#define MDIODATA_REGADDR_MASK 0x007c0000 /* Regaddr Mask */
|
||||
#define MDIODATA_DEVADDR_SHF 23 /* Physmedia devaddr shift */
|
||||
#define MDIODATA_DEVADDR_MASK 0x0f800000
|
||||
/* Physmedia devaddr Mask */
|
||||
|
||||
/* MDIO Data for older revisions < 10 */
|
||||
#define MDIODATA_REGADDR_SHF_OLD 18 /* Regaddr shift */
|
||||
#define MDIODATA_REGADDR_MASK_OLD 0x003c0000
|
||||
/* Regaddr Mask */
|
||||
#define MDIODATA_DEVADDR_SHF_OLD 22 /* Physmedia devaddr shift */
|
||||
#define MDIODATA_DEVADDR_MASK_OLD 0x0fc00000
|
||||
/* Physmedia devaddr Mask */
|
||||
|
||||
/* Transactions flags */
|
||||
#define MDIODATA_WRITE 0x10000000
|
||||
#define MDIODATA_READ 0x20000000
|
||||
#define MDIODATA_START 0x40000000
|
||||
|
||||
#define MDIODATA_DEV_ADDR 0x0 /* dev address for serdes */
|
||||
#define MDIODATA_BLK_ADDR 0x1F /* blk address for serdes */
|
||||
|
||||
/* serdes regs (rev < 10) */
|
||||
#define MDIODATA_DEV_PLL 0x1d /* SERDES PLL Dev */
|
||||
#define MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */
|
||||
#define MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */
|
||||
|
||||
/* SERDES RX registers */
|
||||
#define SERDES_RX_CTRL 1 /* Rx cntrl */
|
||||
#define SERDES_RX_TIMER1 2 /* Rx Timer1 */
|
||||
#define SERDES_RX_CDR 6 /* CDR */
|
||||
#define SERDES_RX_CDRBW 7 /* CDR BW */
|
||||
/* SERDES RX control register */
|
||||
#define SERDES_RX_CTRL_FORCE 0x80 /* rxpolarity_force */
|
||||
#define SERDES_RX_CTRL_POLARITY 0x40 /* rxpolarity_value */
|
||||
|
||||
/* SERDES PLL registers */
|
||||
#define SERDES_PLL_CTRL 1 /* PLL control reg */
|
||||
#define PLL_CTRL_FREQDET_EN 0x4000 /* bit 14 is FREQDET on */
|
||||
|
||||
/* Linkcontrol reg offset in PCIE Cap */
|
||||
#define PCIE_CAP_LINKCTRL_OFFSET 16 /* offset in pcie cap */
|
||||
#define PCIE_CAP_LCREG_ASPML0s 0x01 /* ASPM L0s in linkctrl */
|
||||
#define PCIE_CAP_LCREG_ASPML1 0x02 /* ASPM L1 in linkctrl */
|
||||
#define PCIE_CLKREQ_ENAB 0x100 /* CLKREQ Enab in linkctrl */
|
||||
|
||||
#define PCIE_ASPM_ENAB 3 /* ASPM L0s & L1 in linkctrl */
|
||||
#define PCIE_ASPM_L1_ENAB 2 /* ASPM L0s & L1 in linkctrl */
|
||||
#define PCIE_ASPM_L0s_ENAB 1 /* ASPM L0s & L1 in linkctrl */
|
||||
#define PCIE_ASPM_DISAB 0 /* ASPM L0s & L1 in linkctrl */
|
||||
|
||||
/* Power management threshold */
|
||||
#define PCIE_L1THRESHOLDTIME_MASK 0xFF00 /* bits 8 - 15 */
|
||||
#define PCIE_L1THRESHOLDTIME_SHIFT 8 /* PCIE_L1THRESHOLDTIME_SHIFT */
|
||||
#define PCIE_L1THRESHOLD_WARVAL 0x72 /* WAR value */
|
||||
#define PCIE_ASPMTIMER_EXTEND 0x01000000
|
||||
/* > rev7:
|
||||
* enable extend ASPM timer
|
||||
*/
|
||||
|
||||
/* different register spaces to access thru pcie indirect access */
|
||||
#define PCIE_CONFIGREGS 1 /* Access to config space */
|
||||
#define PCIE_PCIEREGS 2 /* Access to pcie registers */
|
||||
|
||||
/* PCIE protocol PHY diagnostic registers */
|
||||
#define PCIE_PLP_STATUSREG 0x204 /* Status */
|
||||
|
||||
/* Status reg PCIE_PLP_STATUSREG */
|
||||
#define PCIE_PLP_POLARITYINV_STAT 0x10
|
||||
|
||||
/* PCIE protocol DLLP diagnostic registers */
|
||||
#define PCIE_DLLP_LCREG 0x100 /* Link Control */
|
||||
#define PCIE_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold */
|
||||
|
||||
/* PCIE protocol TLP diagnostic registers */
|
||||
#define PCIE_TLP_WORKAROUNDSREG 0x004 /* TLP Workarounds */
|
||||
|
||||
/* Sonics side: PCI core and host control registers */
|
||||
struct sbpciregs {
|
||||
u32 control; /* PCI control */
|
||||
u32 PAD[3];
|
||||
u32 arbcontrol; /* PCI arbiter control */
|
||||
u32 clkrun; /* Clkrun Control (>=rev11) */
|
||||
u32 PAD[2];
|
||||
u32 intstatus; /* Interrupt status */
|
||||
u32 intmask; /* Interrupt mask */
|
||||
u32 sbtopcimailbox; /* Sonics to PCI mailbox */
|
||||
u32 PAD[9];
|
||||
u32 bcastaddr; /* Sonics broadcast address */
|
||||
u32 bcastdata; /* Sonics broadcast data */
|
||||
u32 PAD[2];
|
||||
u32 gpioin; /* ro: gpio input (>=rev2) */
|
||||
u32 gpioout; /* rw: gpio output (>=rev2) */
|
||||
u32 gpioouten; /* rw: gpio output enable (>= rev2) */
|
||||
u32 gpiocontrol; /* rw: gpio control (>= rev2) */
|
||||
u32 PAD[36];
|
||||
u32 sbtopci0; /* Sonics to PCI translation 0 */
|
||||
u32 sbtopci1; /* Sonics to PCI translation 1 */
|
||||
u32 sbtopci2; /* Sonics to PCI translation 2 */
|
||||
u32 PAD[189];
|
||||
u32 pcicfg[4][64]; /* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */
|
||||
u16 sprom[36]; /* SPROM shadow Area */
|
||||
u32 PAD[46];
|
||||
};
|
||||
|
||||
/* SB side: PCIE core and host control registers */
|
||||
struct sbpcieregs {
|
||||
u32 control; /* host mode only */
|
||||
u32 PAD[2];
|
||||
u32 biststatus; /* bist Status: 0x00C */
|
||||
u32 gpiosel; /* PCIE gpio sel: 0x010 */
|
||||
u32 gpioouten; /* PCIE gpio outen: 0x14 */
|
||||
u32 PAD[2];
|
||||
u32 intstatus; /* Interrupt status: 0x20 */
|
||||
u32 intmask; /* Interrupt mask: 0x24 */
|
||||
u32 sbtopcimailbox; /* sb to pcie mailbox: 0x028 */
|
||||
u32 PAD[53];
|
||||
u32 sbtopcie0; /* sb to pcie translation 0: 0x100 */
|
||||
u32 sbtopcie1; /* sb to pcie translation 1: 0x104 */
|
||||
u32 sbtopcie2; /* sb to pcie translation 2: 0x108 */
|
||||
u32 PAD[5];
|
||||
|
||||
/* pcie core supports in direct access to config space */
|
||||
u32 configaddr; /* pcie config space access: Address field: 0x120 */
|
||||
u32 configdata; /* pcie config space access: Data field: 0x124 */
|
||||
|
||||
/* mdio access to serdes */
|
||||
u32 mdiocontrol; /* controls the mdio access: 0x128 */
|
||||
u32 mdiodata; /* Data to the mdio access: 0x12c */
|
||||
|
||||
/* pcie protocol phy/dllp/tlp register indirect access mechanism */
|
||||
u32 pcieindaddr; /* indirect access to
|
||||
* the internal register: 0x130
|
||||
*/
|
||||
u32 pcieinddata; /* Data to/from the internal regsiter: 0x134 */
|
||||
|
||||
u32 clkreqenctrl; /* >= rev 6, Clkreq rdma control : 0x138 */
|
||||
u32 PAD[177];
|
||||
u32 pciecfg[4][64]; /* 0x400 - 0x7FF, PCIE Cfg Space */
|
||||
u16 sprom[64]; /* SPROM shadow Area */
|
||||
};
|
||||
|
||||
struct pcicore_info {
|
||||
union {
|
||||
struct sbpcieregs *pcieregs;
|
||||
struct sbpciregs *pciregs;
|
||||
} regs; /* Memory mapped register to the core */
|
||||
|
||||
struct si_pub *sih; /* System interconnect handle */
|
||||
struct pci_dev *dev;
|
||||
u8 pciecap_lcreg_offset;/* PCIE capability LCreg offset
|
||||
* in the config space
|
||||
*/
|
||||
bool pcie_pr42767;
|
||||
u8 pcie_polarity;
|
||||
u8 pcie_war_aspm_ovr; /* Override ASPM/Clkreq settings */
|
||||
|
||||
u8 pmecap_offset; /* PM Capability offset in the config space */
|
||||
bool pmecap; /* Capable of generating PME */
|
||||
};
|
||||
|
||||
/* debug/trace */
|
||||
#define PCI_ERROR(args)
|
||||
#define PCIE_PUB(sih) \
|
||||
(((sih)->bustype == PCI_BUS) && \
|
||||
((sih)->buscoretype == PCIE_CORE_ID))
|
||||
|
||||
/* routines to access mdio slave device registers */
|
||||
static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk);
|
||||
static int pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr,
|
||||
bool write, uint *val);
|
||||
static int pcie_mdiowrite(struct pcicore_info *pi, uint physmedia, uint readdr,
|
||||
uint val);
|
||||
static int pcie_mdioread(struct pcicore_info *pi, uint physmedia, uint readdr,
|
||||
uint *ret_val);
|
||||
|
||||
static void pcie_extendL1timer(struct pcicore_info *pi, bool extend);
|
||||
static void pcie_clkreq_upd(struct pcicore_info *pi, uint state);
|
||||
|
||||
static void pcie_war_aspm_clkreq(struct pcicore_info *pi);
|
||||
static void pcie_war_serdes(struct pcicore_info *pi);
|
||||
static void pcie_war_noplldown(struct pcicore_info *pi);
|
||||
static void pcie_war_polarity(struct pcicore_info *pi);
|
||||
static void pcie_war_pci_setup(struct pcicore_info *pi);
|
||||
|
||||
#define PCIE_ASPM(sih) \
|
||||
((PCIE_PUB(sih)) && \
|
||||
(((sih)->buscorerev >= 3) && \
|
||||
((sih)->buscorerev <= 5)))
|
||||
|
||||
|
||||
/* delay needed between the mdio control/ mdiodata register data access */
|
||||
#define PR28829_DELAY() udelay(10)
|
||||
|
||||
/* Initialize the PCI core.
|
||||
* It's caller's responsibility to make sure that this is done only once
|
||||
*/
|
||||
void *pcicore_init(struct si_pub *sih, void *pdev, void *regs)
|
||||
{
|
||||
struct pcicore_info *pi;
|
||||
|
||||
/* alloc struct pcicore_info */
|
||||
pi = kzalloc(sizeof(struct pcicore_info), GFP_ATOMIC);
|
||||
if (pi == NULL) {
|
||||
PCI_ERROR(("pci_attach: malloc failed!\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pi->sih = sih;
|
||||
pi->dev = pdev;
|
||||
|
||||
if (sih->buscoretype == PCIE_CORE_ID) {
|
||||
u8 cap_ptr;
|
||||
pi->regs.pcieregs = regs;
|
||||
cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_EXP,
|
||||
NULL, NULL);
|
||||
pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET;
|
||||
} else
|
||||
pi->regs.pciregs = regs;
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
void pcicore_deinit(void *pch)
|
||||
{
|
||||
kfree(pch);
|
||||
}
|
||||
|
||||
/* return cap_offset if requested capability exists in the PCI config space */
|
||||
/* Note that it's caller's responsibility to make sure it's a pci bus */
|
||||
u8
|
||||
pcicore_find_pci_capability(void *dev, u8 req_cap_id,
|
||||
unsigned char *buf, u32 *buflen)
|
||||
{
|
||||
u8 cap_id;
|
||||
u8 cap_ptr = 0;
|
||||
u32 bufsize;
|
||||
u8 byte_val;
|
||||
|
||||
/* check for Header type 0 */
|
||||
pci_read_config_byte(dev, PCI_HEADER_TYPE, &byte_val);
|
||||
if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
|
||||
goto end;
|
||||
|
||||
/* check if the capability pointer field exists */
|
||||
pci_read_config_byte(dev, PCI_STATUS, &byte_val);
|
||||
if (!(byte_val & PCI_STATUS_CAP_LIST))
|
||||
goto end;
|
||||
|
||||
pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &cap_ptr);
|
||||
/* check if the capability pointer is 0x00 */
|
||||
if (cap_ptr == 0x00)
|
||||
goto end;
|
||||
|
||||
/* loop thru the capability list
|
||||
* and see if the pcie capability exists
|
||||
*/
|
||||
|
||||
pci_read_config_byte(dev, cap_ptr, &cap_id);
|
||||
|
||||
while (cap_id != req_cap_id) {
|
||||
pci_read_config_byte(dev, cap_ptr + 1, &cap_ptr);
|
||||
if (cap_ptr == 0x00)
|
||||
break;
|
||||
pci_read_config_byte(dev, cap_ptr, &cap_id);
|
||||
}
|
||||
if (cap_id != req_cap_id)
|
||||
goto end;
|
||||
|
||||
/* found the caller requested capability */
|
||||
if (buf != NULL && buflen != NULL) {
|
||||
u8 cap_data;
|
||||
|
||||
bufsize = *buflen;
|
||||
if (!bufsize)
|
||||
goto end;
|
||||
*buflen = 0;
|
||||
/* copy the capability data excluding cap ID and next ptr */
|
||||
cap_data = cap_ptr + 2;
|
||||
if ((bufsize + cap_data) > PCI_SZPCR)
|
||||
bufsize = PCI_SZPCR - cap_data;
|
||||
*buflen = bufsize;
|
||||
while (bufsize--) {
|
||||
pci_read_config_byte(dev, cap_data, buf);
|
||||
cap_data++;
|
||||
buf++;
|
||||
}
|
||||
}
|
||||
end:
|
||||
return cap_ptr;
|
||||
}
|
||||
|
||||
/* ***** Register Access API */
|
||||
static uint
|
||||
pcie_readreg(struct sbpcieregs *pcieregs, uint addrtype, uint offset)
|
||||
{
|
||||
uint retval = 0xFFFFFFFF;
|
||||
|
||||
switch (addrtype) {
|
||||
case PCIE_CONFIGREGS:
|
||||
W_REG(&pcieregs->configaddr, offset);
|
||||
(void)R_REG((&pcieregs->configaddr));
|
||||
retval = R_REG(&pcieregs->configdata);
|
||||
break;
|
||||
case PCIE_PCIEREGS:
|
||||
W_REG(&pcieregs->pcieindaddr, offset);
|
||||
(void)R_REG(&pcieregs->pcieindaddr);
|
||||
retval = R_REG(&pcieregs->pcieinddata);
|
||||
break;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static uint
|
||||
pcie_writereg(struct sbpcieregs *pcieregs, uint addrtype, uint offset, uint val)
|
||||
{
|
||||
switch (addrtype) {
|
||||
case PCIE_CONFIGREGS:
|
||||
W_REG((&pcieregs->configaddr), offset);
|
||||
W_REG((&pcieregs->configdata), val);
|
||||
break;
|
||||
case PCIE_PCIEREGS:
|
||||
W_REG((&pcieregs->pcieindaddr), offset);
|
||||
W_REG((&pcieregs->pcieinddata), val);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk)
|
||||
{
|
||||
struct sbpcieregs *pcieregs = pi->regs.pcieregs;
|
||||
uint mdiodata, i = 0;
|
||||
uint pcie_serdes_spinwait = 200;
|
||||
|
||||
mdiodata = (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
|
||||
(MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
|
||||
(MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) |
|
||||
(blk << 4));
|
||||
W_REG(&pcieregs->mdiodata, mdiodata);
|
||||
|
||||
PR28829_DELAY();
|
||||
/* retry till the transaction is complete */
|
||||
while (i < pcie_serdes_spinwait) {
|
||||
if (R_REG(&pcieregs->mdiocontrol) & MDIOCTL_ACCESS_DONE)
|
||||
break;
|
||||
udelay(1000);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i >= pcie_serdes_spinwait) {
|
||||
PCI_ERROR(("pcie_mdiosetblock: timed out\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write,
|
||||
uint *val)
|
||||
{
|
||||
struct sbpcieregs *pcieregs = pi->regs.pcieregs;
|
||||
uint mdiodata;
|
||||
uint i = 0;
|
||||
uint pcie_serdes_spinwait = 10;
|
||||
|
||||
/* enable mdio access to SERDES */
|
||||
W_REG(&pcieregs->mdiocontrol, MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
|
||||
|
||||
if (pi->sih->buscorerev >= 10) {
|
||||
/* new serdes is slower in rw,
|
||||
* using two layers of reg address mapping
|
||||
*/
|
||||
if (!pcie_mdiosetblock(pi, physmedia))
|
||||
return 1;
|
||||
mdiodata = ((MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
|
||||
(regaddr << MDIODATA_REGADDR_SHF));
|
||||
pcie_serdes_spinwait *= 20;
|
||||
} else {
|
||||
mdiodata = ((physmedia << MDIODATA_DEVADDR_SHF_OLD) |
|
||||
(regaddr << MDIODATA_REGADDR_SHF_OLD));
|
||||
}
|
||||
|
||||
if (!write)
|
||||
mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA);
|
||||
else
|
||||
mdiodata |= (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
|
||||
*val);
|
||||
|
||||
W_REG(&pcieregs->mdiodata, mdiodata);
|
||||
|
||||
PR28829_DELAY();
|
||||
|
||||
/* retry till the transaction is complete */
|
||||
while (i < pcie_serdes_spinwait) {
|
||||
if (R_REG(&pcieregs->mdiocontrol) & MDIOCTL_ACCESS_DONE) {
|
||||
if (!write) {
|
||||
PR28829_DELAY();
|
||||
*val = (R_REG(&pcieregs->mdiodata) &
|
||||
MDIODATA_MASK);
|
||||
}
|
||||
/* Disable mdio access to SERDES */
|
||||
W_REG(&pcieregs->mdiocontrol, 0);
|
||||
return 0;
|
||||
}
|
||||
udelay(1000);
|
||||
i++;
|
||||
}
|
||||
|
||||
PCI_ERROR(("pcie_mdioop: timed out op: %d\n", write));
|
||||
/* Disable mdio access to SERDES */
|
||||
W_REG(&pcieregs->mdiocontrol, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* use the mdio interface to read from mdio slaves */
|
||||
static int
|
||||
pcie_mdioread(struct pcicore_info *pi, uint physmedia, uint regaddr,
|
||||
uint *regval)
|
||||
{
|
||||
return pcie_mdioop(pi, physmedia, regaddr, false, regval);
|
||||
}
|
||||
|
||||
/* use the mdio interface to write to mdio slaves */
|
||||
static int
|
||||
pcie_mdiowrite(struct pcicore_info *pi, uint physmedia, uint regaddr, uint val)
|
||||
{
|
||||
return pcie_mdioop(pi, physmedia, regaddr, true, &val);
|
||||
}
|
||||
|
||||
/* ***** Support functions ***** */
|
||||
static u8 pcie_clkreq(void *pch, u32 mask, u32 val)
|
||||
{
|
||||
struct pcicore_info *pi = pch;
|
||||
u32 reg_val;
|
||||
u8 offset;
|
||||
|
||||
offset = pi->pciecap_lcreg_offset;
|
||||
if (!offset)
|
||||
return 0;
|
||||
|
||||
pci_read_config_dword(pi->dev, offset, ®_val);
|
||||
/* set operation */
|
||||
if (mask) {
|
||||
if (val)
|
||||
reg_val |= PCIE_CLKREQ_ENAB;
|
||||
else
|
||||
reg_val &= ~PCIE_CLKREQ_ENAB;
|
||||
pci_write_config_dword(pi->dev, offset, reg_val);
|
||||
pci_read_config_dword(pi->dev, offset, ®_val);
|
||||
}
|
||||
if (reg_val & PCIE_CLKREQ_ENAB)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pcie_extendL1timer(struct pcicore_info *pi, bool extend)
|
||||
{
|
||||
u32 w;
|
||||
struct si_pub *sih = pi->sih;
|
||||
struct sbpcieregs *pcieregs = pi->regs.pcieregs;
|
||||
|
||||
if (!PCIE_PUB(sih) || sih->buscorerev < 7)
|
||||
return;
|
||||
|
||||
w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
|
||||
if (extend)
|
||||
w |= PCIE_ASPMTIMER_EXTEND;
|
||||
else
|
||||
w &= ~PCIE_ASPMTIMER_EXTEND;
|
||||
pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w);
|
||||
w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
|
||||
}
|
||||
|
||||
/* centralized clkreq control policy */
|
||||
static void pcie_clkreq_upd(struct pcicore_info *pi, uint state)
|
||||
{
|
||||
struct si_pub *sih = pi->sih;
|
||||
|
||||
switch (state) {
|
||||
case SI_DOATTACH:
|
||||
if (PCIE_ASPM(sih))
|
||||
pcie_clkreq((void *)pi, 1, 0);
|
||||
break;
|
||||
case SI_PCIDOWN:
|
||||
if (sih->buscorerev == 6) { /* turn on serdes PLL down */
|
||||
ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(chipcregs_t, chipcontrol_addr),
|
||||
~0, 0);
|
||||
ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(chipcregs_t, chipcontrol_data),
|
||||
~0x40, 0);
|
||||
} else if (pi->pcie_pr42767) {
|
||||
pcie_clkreq((void *)pi, 1, 1);
|
||||
}
|
||||
break;
|
||||
case SI_PCIUP:
|
||||
if (sih->buscorerev == 6) { /* turn off serdes PLL down */
|
||||
ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(chipcregs_t, chipcontrol_addr),
|
||||
~0, 0);
|
||||
ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(chipcregs_t, chipcontrol_data),
|
||||
~0x40, 0x40);
|
||||
} else if (PCIE_ASPM(sih)) { /* disable clkreq */
|
||||
pcie_clkreq((void *)pi, 1, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* ***** PCI core WARs ***** */
|
||||
/* Done only once at attach time */
|
||||
static void pcie_war_polarity(struct pcicore_info *pi)
|
||||
{
|
||||
u32 w;
|
||||
|
||||
if (pi->pcie_polarity != 0)
|
||||
return;
|
||||
|
||||
w = pcie_readreg(pi->regs.pcieregs, PCIE_PCIEREGS, PCIE_PLP_STATUSREG);
|
||||
|
||||
/* Detect the current polarity at attach and force that polarity and
|
||||
* disable changing the polarity
|
||||
*/
|
||||
if ((w & PCIE_PLP_POLARITYINV_STAT) == 0)
|
||||
pi->pcie_polarity = SERDES_RX_CTRL_FORCE;
|
||||
else
|
||||
pi->pcie_polarity = (SERDES_RX_CTRL_FORCE |
|
||||
SERDES_RX_CTRL_POLARITY);
|
||||
}
|
||||
|
||||
/* enable ASPM and CLKREQ if srom doesn't have it */
|
||||
/* Needs to happen when update to shadow SROM is needed
|
||||
* : Coming out of 'standby'/'hibernate'
|
||||
* : If pcie_war_aspm_ovr state changed
|
||||
*/
|
||||
static void pcie_war_aspm_clkreq(struct pcicore_info *pi)
|
||||
{
|
||||
struct sbpcieregs *pcieregs = pi->regs.pcieregs;
|
||||
struct si_pub *sih = pi->sih;
|
||||
u16 val16, *reg16;
|
||||
u32 w;
|
||||
|
||||
if (!PCIE_ASPM(sih))
|
||||
return;
|
||||
|
||||
/* bypass this on QT or VSIM */
|
||||
reg16 = &pcieregs->sprom[SRSH_ASPM_OFFSET];
|
||||
val16 = R_REG(reg16);
|
||||
|
||||
val16 &= ~SRSH_ASPM_ENB;
|
||||
if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB)
|
||||
val16 |= SRSH_ASPM_ENB;
|
||||
else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L1_ENAB)
|
||||
val16 |= SRSH_ASPM_L1_ENB;
|
||||
else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB)
|
||||
val16 |= SRSH_ASPM_L0s_ENB;
|
||||
|
||||
W_REG(reg16, val16);
|
||||
|
||||
pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
|
||||
w &= ~PCIE_ASPM_ENAB;
|
||||
w |= pi->pcie_war_aspm_ovr;
|
||||
pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
|
||||
|
||||
reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET_REV5];
|
||||
val16 = R_REG(reg16);
|
||||
|
||||
if (pi->pcie_war_aspm_ovr != PCIE_ASPM_DISAB) {
|
||||
val16 |= SRSH_CLKREQ_ENB;
|
||||
pi->pcie_pr42767 = true;
|
||||
} else
|
||||
val16 &= ~SRSH_CLKREQ_ENB;
|
||||
|
||||
W_REG(reg16, val16);
|
||||
}
|
||||
|
||||
/* Apply the polarity determined at the start */
|
||||
/* Needs to happen when coming out of 'standby'/'hibernate' */
|
||||
static void pcie_war_serdes(struct pcicore_info *pi)
|
||||
{
|
||||
u32 w = 0;
|
||||
|
||||
if (pi->pcie_polarity != 0)
|
||||
pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CTRL,
|
||||
pi->pcie_polarity);
|
||||
|
||||
pcie_mdioread(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, &w);
|
||||
if (w & PLL_CTRL_FREQDET_EN) {
|
||||
w &= ~PLL_CTRL_FREQDET_EN;
|
||||
pcie_mdiowrite(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, w);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
|
||||
/* Needs to happen when coming out of 'standby'/'hibernate' */
|
||||
static void pcie_misc_config_fixup(struct pcicore_info *pi)
|
||||
{
|
||||
struct sbpcieregs *pcieregs = pi->regs.pcieregs;
|
||||
u16 val16, *reg16;
|
||||
|
||||
reg16 = &pcieregs->sprom[SRSH_PCIE_MISC_CONFIG];
|
||||
val16 = R_REG(reg16);
|
||||
|
||||
if ((val16 & SRSH_L23READY_EXIT_NOPERST) == 0) {
|
||||
val16 |= SRSH_L23READY_EXIT_NOPERST;
|
||||
W_REG(reg16, val16);
|
||||
}
|
||||
}
|
||||
|
||||
/* quick hack for testing */
|
||||
/* Needs to happen when coming out of 'standby'/'hibernate' */
|
||||
static void pcie_war_noplldown(struct pcicore_info *pi)
|
||||
{
|
||||
struct sbpcieregs *pcieregs = pi->regs.pcieregs;
|
||||
u16 *reg16;
|
||||
|
||||
/* turn off serdes PLL down */
|
||||
ai_corereg(pi->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol),
|
||||
CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN);
|
||||
|
||||
/* clear srom shadow backdoor */
|
||||
reg16 = &pcieregs->sprom[SRSH_BD_OFFSET];
|
||||
W_REG(reg16, 0);
|
||||
}
|
||||
|
||||
/* Needs to happen when coming out of 'standby'/'hibernate' */
|
||||
static void pcie_war_pci_setup(struct pcicore_info *pi)
|
||||
{
|
||||
struct si_pub *sih = pi->sih;
|
||||
struct sbpcieregs *pcieregs = pi->regs.pcieregs;
|
||||
u32 w;
|
||||
|
||||
if (sih->buscorerev == 0 || sih->buscorerev == 1) {
|
||||
w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
|
||||
PCIE_TLP_WORKAROUNDSREG);
|
||||
w |= 0x8;
|
||||
pcie_writereg(pcieregs, PCIE_PCIEREGS,
|
||||
PCIE_TLP_WORKAROUNDSREG, w);
|
||||
}
|
||||
|
||||
if (sih->buscorerev == 1) {
|
||||
w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG);
|
||||
w |= 0x40;
|
||||
pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w);
|
||||
}
|
||||
|
||||
if (sih->buscorerev == 0) {
|
||||
pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128);
|
||||
pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100);
|
||||
pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466);
|
||||
} else if (PCIE_ASPM(sih)) {
|
||||
/* Change the L1 threshold for better performance */
|
||||
w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
|
||||
PCIE_DLLP_PMTHRESHREG);
|
||||
w &= ~PCIE_L1THRESHOLDTIME_MASK;
|
||||
w |= PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT;
|
||||
pcie_writereg(pcieregs, PCIE_PCIEREGS,
|
||||
PCIE_DLLP_PMTHRESHREG, w);
|
||||
|
||||
pcie_war_serdes(pi);
|
||||
|
||||
pcie_war_aspm_clkreq(pi);
|
||||
} else if (pi->sih->buscorerev == 7)
|
||||
pcie_war_noplldown(pi);
|
||||
|
||||
/* Note that the fix is actually in the SROM,
|
||||
* that's why this is open-ended
|
||||
*/
|
||||
if (pi->sih->buscorerev >= 6)
|
||||
pcie_misc_config_fixup(pi);
|
||||
}
|
||||
|
||||
/* ***** Functions called during driver state changes ***** */
|
||||
void pcicore_attach(void *pch, char *pvars, int state)
|
||||
{
|
||||
struct pcicore_info *pi = pch;
|
||||
struct si_pub *sih = pi->sih;
|
||||
|
||||
/* Determine if this board needs override */
|
||||
if (PCIE_ASPM(sih)) {
|
||||
if ((u32)getintvar(pvars, "boardflags2") & BFL2_PCIEWAR_OVR)
|
||||
pi->pcie_war_aspm_ovr = PCIE_ASPM_DISAB;
|
||||
else
|
||||
pi->pcie_war_aspm_ovr = PCIE_ASPM_ENAB;
|
||||
}
|
||||
|
||||
/* These need to happen in this order only */
|
||||
pcie_war_polarity(pi);
|
||||
|
||||
pcie_war_serdes(pi);
|
||||
|
||||
pcie_war_aspm_clkreq(pi);
|
||||
|
||||
pcie_clkreq_upd(pi, state);
|
||||
|
||||
}
|
||||
|
||||
void pcicore_hwup(void *pch)
|
||||
{
|
||||
struct pcicore_info *pi = pch;
|
||||
|
||||
if (!pi || !PCIE_PUB(pi->sih))
|
||||
return;
|
||||
|
||||
pcie_war_pci_setup(pi);
|
||||
}
|
||||
|
||||
void pcicore_up(void *pch, int state)
|
||||
{
|
||||
struct pcicore_info *pi = pch;
|
||||
|
||||
if (!pi || !PCIE_PUB(pi->sih))
|
||||
return;
|
||||
|
||||
/* Restore L1 timer for better performance */
|
||||
pcie_extendL1timer(pi, true);
|
||||
|
||||
pcie_clkreq_upd(pi, state);
|
||||
}
|
||||
|
||||
/* When the device is going to enter D3 state
|
||||
* (or the system is going to enter S3/S4 states)
|
||||
*/
|
||||
void pcicore_sleep(void *pch)
|
||||
{
|
||||
struct pcicore_info *pi = pch;
|
||||
u32 w;
|
||||
|
||||
if (!pi || !PCIE_ASPM(pi->sih))
|
||||
return;
|
||||
|
||||
pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
|
||||
w &= ~PCIE_CAP_LCREG_ASPML1;
|
||||
pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
|
||||
|
||||
pi->pcie_pr42767 = false;
|
||||
}
|
||||
|
||||
void pcicore_down(void *pch, int state)
|
||||
{
|
||||
struct pcicore_info *pi = pch;
|
||||
|
||||
if (!pi || !PCIE_PUB(pi->sih))
|
||||
return;
|
||||
|
||||
pcie_clkreq_upd(pi, state);
|
||||
|
||||
/* Reduce L1 timer for better power savings */
|
||||
pcie_extendL1timer(pi, false);
|
||||
}
|
||||
|
||||
/* precondition: current core is sii->buscoretype */
|
||||
void pcicore_fixcfg(void *pch, void *regs)
|
||||
{
|
||||
struct pcicore_info *pi = pch;
|
||||
struct si_info *sii = SI_INFO(pi->sih);
|
||||
struct sbpciregs *pciregs = regs;
|
||||
struct sbpcieregs *pcieregs = regs;
|
||||
u16 val16, *reg16 = NULL;
|
||||
uint pciidx;
|
||||
|
||||
/* check 'pi' is correct and fix it if not */
|
||||
if (sii->pub.buscoretype == PCIE_CORE_ID)
|
||||
reg16 = &pcieregs->sprom[SRSH_PI_OFFSET];
|
||||
else if (sii->pub.buscoretype == PCI_CORE_ID)
|
||||
reg16 = &pciregs->sprom[SRSH_PI_OFFSET];
|
||||
pciidx = ai_coreidx(&sii->pub);
|
||||
val16 = R_REG(reg16);
|
||||
if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (u16)pciidx) {
|
||||
val16 = (u16)(pciidx << SRSH_PI_SHIFT) |
|
||||
(val16 & ~SRSH_PI_MASK);
|
||||
W_REG(reg16, val16);
|
||||
}
|
||||
}
|
||||
|
||||
/* precondition: current core is pci core */
|
||||
void pcicore_pci_setup(void *pch, void *regs)
|
||||
{
|
||||
struct pcicore_info *pi = pch;
|
||||
struct sbpciregs *pciregs = regs;
|
||||
u32 w;
|
||||
|
||||
OR_REG(&pciregs->sbtopci2, SBTOPCI_PREF | SBTOPCI_BURST);
|
||||
|
||||
if (SI_INFO(pi->sih)->pub.buscorerev >= 11) {
|
||||
OR_REG(&pciregs->sbtopci2, SBTOPCI_RC_READMULTI);
|
||||
w = R_REG(&pciregs->clkrun);
|
||||
W_REG(&pciregs->clkrun, w | PCI_CLKRUN_DSBL);
|
||||
w = R_REG(&pciregs->clkrun);
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_NICPCI_H_
|
||||
#define _BRCM_NICPCI_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/* PCI configuration address space size */
|
||||
#define PCI_SZPCR 256
|
||||
|
||||
/* Brcm PCI configuration registers */
|
||||
/* backplane address space accessed by BAR0 */
|
||||
#define PCI_BAR0_WIN 0x80
|
||||
/* sprom property control */
|
||||
#define PCI_SPROM_CONTROL 0x88
|
||||
/* mask of PCI and other cores interrupts */
|
||||
#define PCI_INT_MASK 0x94
|
||||
/* backplane core interrupt mask bits offset */
|
||||
#define PCI_SBIM_SHIFT 8
|
||||
/* backplane address space accessed by second 4KB of BAR0 */
|
||||
#define PCI_BAR0_WIN2 0xac
|
||||
/* pci config space gpio input (>=rev3) */
|
||||
#define PCI_GPIO_IN 0xb0
|
||||
/* pci config space gpio output (>=rev3) */
|
||||
#define PCI_GPIO_OUT 0xb4
|
||||
/* pci config space gpio output enable (>=rev3) */
|
||||
#define PCI_GPIO_OUTEN 0xb8
|
||||
|
||||
/* bar0 + 4K accesses external sprom */
|
||||
#define PCI_BAR0_SPROM_OFFSET (4 * 1024)
|
||||
/* bar0 + 6K accesses pci core registers */
|
||||
#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024)
|
||||
/*
|
||||
* pci core SB registers are at the end of the
|
||||
* 8KB window, so their address is the "regular"
|
||||
* address plus 4K
|
||||
*/
|
||||
#define PCI_BAR0_PCISBR_OFFSET (4 * 1024)
|
||||
/* bar0 window size Match with corerev 13 */
|
||||
#define PCI_BAR0_WINSZ (16 * 1024)
|
||||
/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */
|
||||
/* bar0 + 8K accesses pci/pcie core registers */
|
||||
#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024)
|
||||
/* bar0 + 12K accesses chipc core registers */
|
||||
#define PCI_16KB0_CCREGS_OFFSET (12 * 1024)
|
||||
|
||||
#define PCI_CLKRUN_DSBL 0x8000 /* Bit 15 forceClkrun */
|
||||
|
||||
/* Sonics to PCI translation types */
|
||||
#define SBTOPCI_PREF 0x4 /* prefetch enable */
|
||||
#define SBTOPCI_BURST 0x8 /* burst enable */
|
||||
#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */
|
||||
|
||||
/* PCI core index in SROM shadow area */
|
||||
#define SRSH_PI_OFFSET 0 /* first word */
|
||||
#define SRSH_PI_MASK 0xf000 /* bit 15:12 */
|
||||
#define SRSH_PI_SHIFT 12 /* bit 15:12 */
|
||||
|
||||
extern void *pcicore_init(struct si_pub *sih, void *pdev, void *regs);
|
||||
extern void pcicore_deinit(void *pch);
|
||||
extern void pcicore_attach(void *pch, char *pvars, int state);
|
||||
extern void pcicore_hwup(void *pch);
|
||||
extern void pcicore_up(void *pch, int state);
|
||||
extern void pcicore_sleep(void *pch);
|
||||
extern void pcicore_down(void *pch, int state);
|
||||
extern u8 pcicore_find_pci_capability(void *dev, u8 req_cap_id,
|
||||
unsigned char *buf, u32 *buflen);
|
||||
extern void pcicore_fixcfg(void *pch, void *regs);
|
||||
extern void pcicore_pci_setup(void *pch, void *regs);
|
||||
|
||||
#endif /* _BRCM_NICPCI_H_ */
|
@ -1,545 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include <brcm_hw_ids.h>
|
||||
#include <chipcommon.h>
|
||||
#include "aiutils.h"
|
||||
#include "otp.h"
|
||||
|
||||
#define OTPS_GUP_MASK 0x00000f00
|
||||
#define OTPS_GUP_SHIFT 8
|
||||
#define OTPS_GUP_HW 0x00000100 /* h/w subregion is programmed */
|
||||
#define OTPS_GUP_SW 0x00000200 /* s/w subregion is programmed */
|
||||
#define OTPS_GUP_CI 0x00000400 /* chipid/pkgopt subregion is programmed */
|
||||
#define OTPS_GUP_FUSE 0x00000800 /* fuse subregion is programmed */
|
||||
|
||||
/* Fields in otpprog in rev >= 21 */
|
||||
#define OTPP_COL_MASK 0x000000ff
|
||||
#define OTPP_COL_SHIFT 0
|
||||
#define OTPP_ROW_MASK 0x0000ff00
|
||||
#define OTPP_ROW_SHIFT 8
|
||||
#define OTPP_OC_MASK 0x0f000000
|
||||
#define OTPP_OC_SHIFT 24
|
||||
#define OTPP_READERR 0x10000000
|
||||
#define OTPP_VALUE_MASK 0x20000000
|
||||
#define OTPP_VALUE_SHIFT 29
|
||||
#define OTPP_START_BUSY 0x80000000
|
||||
#define OTPP_READ 0x40000000
|
||||
|
||||
/* Opcodes for OTPP_OC field */
|
||||
#define OTPPOC_READ 0
|
||||
#define OTPPOC_BIT_PROG 1
|
||||
#define OTPPOC_VERIFY 3
|
||||
#define OTPPOC_INIT 4
|
||||
#define OTPPOC_SET 5
|
||||
#define OTPPOC_RESET 6
|
||||
#define OTPPOC_OCST 7
|
||||
#define OTPPOC_ROW_LOCK 8
|
||||
#define OTPPOC_PRESCN_TEST 9
|
||||
|
||||
#define OTPTYPE_IPX(ccrev) ((ccrev) == 21 || (ccrev) >= 23)
|
||||
|
||||
#define OTPP_TRIES 10000000 /* # of tries for OTPP */
|
||||
|
||||
#define MAXNUMRDES 9 /* Maximum OTP redundancy entries */
|
||||
|
||||
/* OTP common function type */
|
||||
typedef int (*otp_status_t) (void *oh);
|
||||
typedef int (*otp_size_t) (void *oh);
|
||||
typedef void *(*otp_init_t) (struct si_pub *sih);
|
||||
typedef u16(*otp_read_bit_t) (void *oh, chipcregs_t *cc, uint off);
|
||||
typedef int (*otp_read_region_t) (struct si_pub *sih, int region, u16 *data,
|
||||
uint *wlen);
|
||||
typedef int (*otp_nvread_t) (void *oh, char *data, uint *len);
|
||||
|
||||
/* OTP function struct */
|
||||
struct otp_fn_s {
|
||||
otp_size_t size;
|
||||
otp_read_bit_t read_bit;
|
||||
otp_init_t init;
|
||||
otp_read_region_t read_region;
|
||||
otp_nvread_t nvread;
|
||||
otp_status_t status;
|
||||
};
|
||||
|
||||
struct otpinfo {
|
||||
uint ccrev; /* chipc revision */
|
||||
struct otp_fn_s *fn; /* OTP functions */
|
||||
struct si_pub *sih; /* Saved sb handle */
|
||||
|
||||
/* IPX OTP section */
|
||||
u16 wsize; /* Size of otp in words */
|
||||
u16 rows; /* Geometry */
|
||||
u16 cols; /* Geometry */
|
||||
u32 status; /* Flag bits (lock/prog/rv).
|
||||
* (Reflected only when OTP is power cycled)
|
||||
*/
|
||||
u16 hwbase; /* hardware subregion offset */
|
||||
u16 hwlim; /* hardware subregion boundary */
|
||||
u16 swbase; /* software subregion offset */
|
||||
u16 swlim; /* software subregion boundary */
|
||||
u16 fbase; /* fuse subregion offset */
|
||||
u16 flim; /* fuse subregion boundary */
|
||||
int otpgu_base; /* offset to General Use Region */
|
||||
};
|
||||
|
||||
static struct otpinfo otpinfo;
|
||||
|
||||
/*
|
||||
* IPX OTP Code
|
||||
*
|
||||
* Exported functions:
|
||||
* ipxotp_status()
|
||||
* ipxotp_size()
|
||||
* ipxotp_init()
|
||||
* ipxotp_read_bit()
|
||||
* ipxotp_read_region()
|
||||
* ipxotp_nvread()
|
||||
*
|
||||
*/
|
||||
|
||||
#define HWSW_RGN(rgn) (((rgn) == OTP_HW_RGN) ? "h/w" : "s/w")
|
||||
|
||||
/* OTP layout */
|
||||
/* CC revs 21, 24 and 27 OTP General Use Region word offset */
|
||||
#define REVA4_OTPGU_BASE 12
|
||||
|
||||
/* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */
|
||||
#define REVB8_OTPGU_BASE 20
|
||||
|
||||
/* CC rev 36 OTP General Use Region word offset */
|
||||
#define REV36_OTPGU_BASE 12
|
||||
|
||||
/* Subregion word offsets in General Use region */
|
||||
#define OTPGU_HSB_OFF 0
|
||||
#define OTPGU_SFB_OFF 1
|
||||
#define OTPGU_CI_OFF 2
|
||||
#define OTPGU_P_OFF 3
|
||||
#define OTPGU_SROM_OFF 4
|
||||
|
||||
/* Flag bit offsets in General Use region */
|
||||
#define OTPGU_HWP_OFF 60
|
||||
#define OTPGU_SWP_OFF 61
|
||||
#define OTPGU_CIP_OFF 62
|
||||
#define OTPGU_FUSEP_OFF 63
|
||||
#define OTPGU_CIP_MSK 0x4000
|
||||
#define OTPGU_P_MSK 0xf000
|
||||
#define OTPGU_P_SHIFT (OTPGU_HWP_OFF % 16)
|
||||
|
||||
/* OTP Size */
|
||||
#define OTP_SZ_FU_324 ((roundup(324, 8))/8) /* 324 bits */
|
||||
#define OTP_SZ_FU_288 (288/8) /* 288 bits */
|
||||
#define OTP_SZ_FU_216 (216/8) /* 216 bits */
|
||||
#define OTP_SZ_FU_72 (72/8) /* 72 bits */
|
||||
#define OTP_SZ_CHECKSUM (16/8) /* 16 bits */
|
||||
#define OTP4315_SWREG_SZ 178 /* 178 bytes */
|
||||
#define OTP_SZ_FU_144 (144/8) /* 144 bits */
|
||||
|
||||
static int ipxotp_status(void *oh)
|
||||
{
|
||||
struct otpinfo *oi = (struct otpinfo *) oh;
|
||||
return (int)(oi->status);
|
||||
}
|
||||
|
||||
/* Return size in bytes */
|
||||
static int ipxotp_size(void *oh)
|
||||
{
|
||||
struct otpinfo *oi = (struct otpinfo *) oh;
|
||||
return (int)oi->wsize * 2;
|
||||
}
|
||||
|
||||
static u16 ipxotp_otpr(void *oh, chipcregs_t *cc, uint wn)
|
||||
{
|
||||
struct otpinfo *oi;
|
||||
|
||||
oi = (struct otpinfo *) oh;
|
||||
|
||||
return R_REG(&cc->sromotp[wn]);
|
||||
}
|
||||
|
||||
static u16 ipxotp_read_bit(void *oh, chipcregs_t *cc, uint off)
|
||||
{
|
||||
struct otpinfo *oi = (struct otpinfo *) oh;
|
||||
uint k, row, col;
|
||||
u32 otpp, st;
|
||||
|
||||
row = off / oi->cols;
|
||||
col = off % oi->cols;
|
||||
|
||||
otpp = OTPP_START_BUSY |
|
||||
((OTPPOC_READ << OTPP_OC_SHIFT) & OTPP_OC_MASK) |
|
||||
((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) |
|
||||
((col << OTPP_COL_SHIFT) & OTPP_COL_MASK);
|
||||
W_REG(&cc->otpprog, otpp);
|
||||
|
||||
for (k = 0;
|
||||
((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
|
||||
&& (k < OTPP_TRIES); k++)
|
||||
;
|
||||
if (k >= OTPP_TRIES) {
|
||||
return 0xffff;
|
||||
}
|
||||
if (st & OTPP_READERR) {
|
||||
return 0xffff;
|
||||
}
|
||||
st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;
|
||||
|
||||
return (int)st;
|
||||
}
|
||||
|
||||
/* Calculate max HW/SW region byte size by subtracting fuse region and checksum size,
|
||||
* osizew is oi->wsize (OTP size - GU size) in words
|
||||
*/
|
||||
static int ipxotp_max_rgnsz(struct si_pub *sih, int osizew)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (sih->chip) {
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
|
||||
break;
|
||||
case BCM4313_CHIP_ID:
|
||||
ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
|
||||
break;
|
||||
default:
|
||||
break; /* Don't know about this chip */
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void _ipxotp_init(struct otpinfo *oi, chipcregs_t *cc)
|
||||
{
|
||||
uint k;
|
||||
u32 otpp, st;
|
||||
|
||||
/* record word offset of General Use Region for various chipcommon revs */
|
||||
if (oi->sih->ccrev == 21 || oi->sih->ccrev == 24
|
||||
|| oi->sih->ccrev == 27) {
|
||||
oi->otpgu_base = REVA4_OTPGU_BASE;
|
||||
} else if (oi->sih->ccrev == 36) {
|
||||
/* OTP size greater than equal to 2KB (128 words), otpgu_base is similar to rev23 */
|
||||
if (oi->wsize >= 128)
|
||||
oi->otpgu_base = REVB8_OTPGU_BASE;
|
||||
else
|
||||
oi->otpgu_base = REV36_OTPGU_BASE;
|
||||
} else if (oi->sih->ccrev == 23 || oi->sih->ccrev >= 25) {
|
||||
oi->otpgu_base = REVB8_OTPGU_BASE;
|
||||
}
|
||||
|
||||
/* First issue an init command so the status is up to date */
|
||||
otpp =
|
||||
OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK);
|
||||
|
||||
W_REG(&cc->otpprog, otpp);
|
||||
for (k = 0;
|
||||
((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
|
||||
&& (k < OTPP_TRIES); k++)
|
||||
;
|
||||
if (k >= OTPP_TRIES) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read OTP lock bits and subregion programmed indication bits */
|
||||
oi->status = R_REG(&cc->otpstatus);
|
||||
|
||||
if ((oi->sih->chip == BCM43224_CHIP_ID)
|
||||
|| (oi->sih->chip == BCM43225_CHIP_ID)) {
|
||||
u32 p_bits;
|
||||
p_bits =
|
||||
(ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_P_OFF) &
|
||||
OTPGU_P_MSK)
|
||||
>> OTPGU_P_SHIFT;
|
||||
oi->status |= (p_bits << OTPS_GUP_SHIFT);
|
||||
}
|
||||
|
||||
/*
|
||||
* h/w region base and fuse region limit are fixed to the top and
|
||||
* the bottom of the general use region. Everything else can be flexible.
|
||||
*/
|
||||
oi->hwbase = oi->otpgu_base + OTPGU_SROM_OFF;
|
||||
oi->hwlim = oi->wsize;
|
||||
if (oi->status & OTPS_GUP_HW) {
|
||||
oi->hwlim =
|
||||
ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF) / 16;
|
||||
oi->swbase = oi->hwlim;
|
||||
} else
|
||||
oi->swbase = oi->hwbase;
|
||||
|
||||
/* subtract fuse and checksum from beginning */
|
||||
oi->swlim = ipxotp_max_rgnsz(oi->sih, oi->wsize) / 2;
|
||||
|
||||
if (oi->status & OTPS_GUP_SW) {
|
||||
oi->swlim =
|
||||
ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_SFB_OFF) / 16;
|
||||
oi->fbase = oi->swlim;
|
||||
} else
|
||||
oi->fbase = oi->swbase;
|
||||
|
||||
oi->flim = oi->wsize;
|
||||
}
|
||||
|
||||
static void *ipxotp_init(struct si_pub *sih)
|
||||
{
|
||||
uint idx;
|
||||
chipcregs_t *cc;
|
||||
struct otpinfo *oi;
|
||||
|
||||
/* Make sure we're running IPX OTP */
|
||||
if (!OTPTYPE_IPX(sih->ccrev))
|
||||
return NULL;
|
||||
|
||||
/* Make sure OTP is not disabled */
|
||||
if (ai_is_otp_disabled(sih))
|
||||
return NULL;
|
||||
|
||||
/* OTP is always powered */
|
||||
oi = &otpinfo;
|
||||
|
||||
/* Check for otp size */
|
||||
switch ((sih->cccaps & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) {
|
||||
case 0:
|
||||
/* Nothing there */
|
||||
return NULL;
|
||||
case 1: /* 32x64 */
|
||||
oi->rows = 32;
|
||||
oi->cols = 64;
|
||||
oi->wsize = 128;
|
||||
break;
|
||||
case 2: /* 64x64 */
|
||||
oi->rows = 64;
|
||||
oi->cols = 64;
|
||||
oi->wsize = 256;
|
||||
break;
|
||||
case 5: /* 96x64 */
|
||||
oi->rows = 96;
|
||||
oi->cols = 64;
|
||||
oi->wsize = 384;
|
||||
break;
|
||||
case 7: /* 16x64 *//* 1024 bits */
|
||||
oi->rows = 16;
|
||||
oi->cols = 64;
|
||||
oi->wsize = 64;
|
||||
break;
|
||||
default:
|
||||
/* Don't know the geometry */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Retrieve OTP region info */
|
||||
idx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
_ipxotp_init(oi, cc);
|
||||
|
||||
ai_setcoreidx(sih, idx);
|
||||
|
||||
return (void *)oi;
|
||||
}
|
||||
|
||||
static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen)
|
||||
{
|
||||
struct otpinfo *oi = (struct otpinfo *) oh;
|
||||
uint idx;
|
||||
chipcregs_t *cc;
|
||||
uint base, i, sz;
|
||||
|
||||
/* Validate region selection */
|
||||
switch (region) {
|
||||
case OTP_HW_RGN:
|
||||
sz = (uint) oi->hwlim - oi->hwbase;
|
||||
if (!(oi->status & OTPS_GUP_HW)) {
|
||||
*wlen = sz;
|
||||
return -ENODATA;
|
||||
}
|
||||
if (*wlen < sz) {
|
||||
*wlen = sz;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
base = oi->hwbase;
|
||||
break;
|
||||
case OTP_SW_RGN:
|
||||
sz = ((uint) oi->swlim - oi->swbase);
|
||||
if (!(oi->status & OTPS_GUP_SW)) {
|
||||
*wlen = sz;
|
||||
return -ENODATA;
|
||||
}
|
||||
if (*wlen < sz) {
|
||||
*wlen = sz;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
base = oi->swbase;
|
||||
break;
|
||||
case OTP_CI_RGN:
|
||||
sz = OTPGU_CI_SZ;
|
||||
if (!(oi->status & OTPS_GUP_CI)) {
|
||||
*wlen = sz;
|
||||
return -ENODATA;
|
||||
}
|
||||
if (*wlen < sz) {
|
||||
*wlen = sz;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
base = oi->otpgu_base + OTPGU_CI_OFF;
|
||||
break;
|
||||
case OTP_FUSE_RGN:
|
||||
sz = (uint) oi->flim - oi->fbase;
|
||||
if (!(oi->status & OTPS_GUP_FUSE)) {
|
||||
*wlen = sz;
|
||||
return -ENODATA;
|
||||
}
|
||||
if (*wlen < sz) {
|
||||
*wlen = sz;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
base = oi->fbase;
|
||||
break;
|
||||
case OTP_ALL_RGN:
|
||||
sz = ((uint) oi->flim - oi->hwbase);
|
||||
if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) {
|
||||
*wlen = sz;
|
||||
return -ENODATA;
|
||||
}
|
||||
if (*wlen < sz) {
|
||||
*wlen = sz;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
base = oi->hwbase;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
idx = ai_coreidx(oi->sih);
|
||||
cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
|
||||
|
||||
/* Read the data */
|
||||
for (i = 0; i < sz; i++)
|
||||
data[i] = ipxotp_otpr(oh, cc, base + i);
|
||||
|
||||
ai_setcoreidx(oi->sih, idx);
|
||||
*wlen = sz;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ipxotp_nvread(void *oh, char *data, uint *len)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static struct otp_fn_s ipxotp_fn = {
|
||||
(otp_size_t) ipxotp_size,
|
||||
(otp_read_bit_t) ipxotp_read_bit,
|
||||
|
||||
(otp_init_t) ipxotp_init,
|
||||
(otp_read_region_t) ipxotp_read_region,
|
||||
(otp_nvread_t) ipxotp_nvread,
|
||||
|
||||
(otp_status_t) ipxotp_status
|
||||
};
|
||||
|
||||
/*
|
||||
* otp_status()
|
||||
* otp_size()
|
||||
* otp_read_bit()
|
||||
* otp_init()
|
||||
* otp_read_region()
|
||||
* otp_nvread()
|
||||
*/
|
||||
|
||||
int otp_status(void *oh)
|
||||
{
|
||||
struct otpinfo *oi = (struct otpinfo *) oh;
|
||||
|
||||
return oi->fn->status(oh);
|
||||
}
|
||||
|
||||
int otp_size(void *oh)
|
||||
{
|
||||
struct otpinfo *oi = (struct otpinfo *) oh;
|
||||
|
||||
return oi->fn->size(oh);
|
||||
}
|
||||
|
||||
u16 otp_read_bit(void *oh, uint offset)
|
||||
{
|
||||
struct otpinfo *oi = (struct otpinfo *) oh;
|
||||
uint idx = ai_coreidx(oi->sih);
|
||||
chipcregs_t *cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
|
||||
u16 readBit = (u16) oi->fn->read_bit(oh, cc, offset);
|
||||
ai_setcoreidx(oi->sih, idx);
|
||||
return readBit;
|
||||
}
|
||||
|
||||
void *otp_init(struct si_pub *sih)
|
||||
{
|
||||
struct otpinfo *oi;
|
||||
void *ret = NULL;
|
||||
|
||||
oi = &otpinfo;
|
||||
memset(oi, 0, sizeof(struct otpinfo));
|
||||
|
||||
oi->ccrev = sih->ccrev;
|
||||
|
||||
if (OTPTYPE_IPX(oi->ccrev))
|
||||
oi->fn = &ipxotp_fn;
|
||||
|
||||
if (oi->fn == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
oi->sih = sih;
|
||||
|
||||
ret = (oi->fn->init) (sih);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
otp_read_region(struct si_pub *sih, int region, u16 *data,
|
||||
uint *wlen) {
|
||||
void *oh;
|
||||
int err = 0;
|
||||
|
||||
if (ai_is_otp_disabled(sih)) {
|
||||
err = -EPERM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
oh = otp_init(sih);
|
||||
if (oh == NULL) {
|
||||
err = -EBADE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = (((struct otpinfo *) oh)->fn->read_region)
|
||||
(oh, region, data, wlen);
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
int otp_nvread(void *oh, char *data, uint *len)
|
||||
{
|
||||
struct otpinfo *oi = (struct otpinfo *) oh;
|
||||
|
||||
return oi->fn->nvread(oh, data, len);
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_OTP_H_
|
||||
#define _BRCM_OTP_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/* OTP regions */
|
||||
#define OTP_HW_RGN 1
|
||||
#define OTP_SW_RGN 2
|
||||
#define OTP_CI_RGN 4
|
||||
#define OTP_FUSE_RGN 8
|
||||
#define OTP_ALL_RGN 0xf /* From h/w region to end of OTP including checksum */
|
||||
|
||||
/* OTP Size */
|
||||
#define OTP_SZ_MAX (6144/8) /* maximum bytes in one CIS */
|
||||
|
||||
/* Fixed size subregions sizes in words */
|
||||
#define OTPGU_CI_SZ 2
|
||||
|
||||
/* OTP usage */
|
||||
#define OTP4325_FM_DISABLED_OFFSET 188
|
||||
|
||||
/* Exported functions */
|
||||
extern int otp_status(void *oh);
|
||||
extern int otp_size(void *oh);
|
||||
extern u16 otp_read_bit(void *oh, uint offset);
|
||||
extern void *otp_init(struct si_pub *sih);
|
||||
extern int otp_read_region(struct si_pub *sih, int region, u16 *data,
|
||||
uint *wlen);
|
||||
extern int otp_nvread(void *oh, char *data, uint *len);
|
||||
|
||||
#endif /* _BRCM_OTP_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,294 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* phy_hal.h: functionality exported from the phy to higher layers
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_PHY_HAL_H_
|
||||
#define _BRCM_PHY_HAL_H_
|
||||
|
||||
#include <brcmu_utils.h>
|
||||
#include <brcmu_wifi.h>
|
||||
#include <phy_shim.h>
|
||||
|
||||
#define IDCODE_VER_MASK 0x0000000f
|
||||
#define IDCODE_VER_SHIFT 0
|
||||
#define IDCODE_MFG_MASK 0x00000fff
|
||||
#define IDCODE_MFG_SHIFT 0
|
||||
#define IDCODE_ID_MASK 0x0ffff000
|
||||
#define IDCODE_ID_SHIFT 12
|
||||
#define IDCODE_REV_MASK 0xf0000000
|
||||
#define IDCODE_REV_SHIFT 28
|
||||
|
||||
#define NORADIO_ID 0xe4f5
|
||||
#define NORADIO_IDCODE 0x4e4f5246
|
||||
|
||||
#define BCM2055_ID 0x2055
|
||||
#define BCM2055_IDCODE 0x02055000
|
||||
#define BCM2055A0_IDCODE 0x1205517f
|
||||
|
||||
#define BCM2056_ID 0x2056
|
||||
#define BCM2056_IDCODE 0x02056000
|
||||
#define BCM2056A0_IDCODE 0x1205617f
|
||||
|
||||
#define BCM2057_ID 0x2057
|
||||
#define BCM2057_IDCODE 0x02057000
|
||||
#define BCM2057A0_IDCODE 0x1205717f
|
||||
|
||||
#define BCM2064_ID 0x2064
|
||||
#define BCM2064_IDCODE 0x02064000
|
||||
#define BCM2064A0_IDCODE 0x0206417f
|
||||
|
||||
#define PHY_TPC_HW_OFF false
|
||||
#define PHY_TPC_HW_ON true
|
||||
|
||||
#define PHY_PERICAL_DRIVERUP 1
|
||||
#define PHY_PERICAL_WATCHDOG 2
|
||||
#define PHY_PERICAL_PHYINIT 3
|
||||
#define PHY_PERICAL_JOIN_BSS 4
|
||||
#define PHY_PERICAL_START_IBSS 5
|
||||
#define PHY_PERICAL_UP_BSS 6
|
||||
#define PHY_PERICAL_CHAN 7
|
||||
#define PHY_FULLCAL 8
|
||||
|
||||
#define PHY_PERICAL_DISABLE 0
|
||||
#define PHY_PERICAL_SPHASE 1
|
||||
#define PHY_PERICAL_MPHASE 2
|
||||
#define PHY_PERICAL_MANUAL 3
|
||||
|
||||
#define PHY_HOLD_FOR_ASSOC 1
|
||||
#define PHY_HOLD_FOR_SCAN 2
|
||||
#define PHY_HOLD_FOR_RM 4
|
||||
#define PHY_HOLD_FOR_PLT 8
|
||||
#define PHY_HOLD_FOR_MUTE 16
|
||||
#define PHY_HOLD_FOR_NOT_ASSOC 0x20
|
||||
|
||||
#define PHY_MUTE_FOR_PREISM 1
|
||||
#define PHY_MUTE_ALL 0xffffffff
|
||||
|
||||
#define PHY_NOISE_FIXED_VAL (-95)
|
||||
#define PHY_NOISE_FIXED_VAL_NPHY (-92)
|
||||
#define PHY_NOISE_FIXED_VAL_LCNPHY (-92)
|
||||
|
||||
#define PHY_MODE_CAL 0x0002
|
||||
#define PHY_MODE_NOISEM 0x0004
|
||||
|
||||
#define BRCMS_TXPWR_DB_FACTOR 4
|
||||
|
||||
/* a large TX Power as an init value to factor out of min() calculations,
|
||||
* keep low enough to fit in an s8, units are .25 dBm
|
||||
*/
|
||||
#define BRCMS_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */
|
||||
|
||||
#define BRCMS_NUM_RATES_CCK 4
|
||||
#define BRCMS_NUM_RATES_OFDM 8
|
||||
#define BRCMS_NUM_RATES_MCS_1_STREAM 8
|
||||
#define BRCMS_NUM_RATES_MCS_2_STREAM 8
|
||||
#define BRCMS_NUM_RATES_MCS_3_STREAM 8
|
||||
#define BRCMS_NUM_RATES_MCS_4_STREAM 8
|
||||
|
||||
#define BRCMS_RSSI_INVALID 0 /* invalid RSSI value */
|
||||
|
||||
struct txpwr_limits {
|
||||
u8 cck[BRCMS_NUM_RATES_CCK];
|
||||
u8 ofdm[BRCMS_NUM_RATES_OFDM];
|
||||
|
||||
u8 ofdm_cdd[BRCMS_NUM_RATES_OFDM];
|
||||
|
||||
u8 ofdm_40_siso[BRCMS_NUM_RATES_OFDM];
|
||||
u8 ofdm_40_cdd[BRCMS_NUM_RATES_OFDM];
|
||||
|
||||
u8 mcs_20_siso[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_20_cdd[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_20_stbc[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_20_mimo[BRCMS_NUM_RATES_MCS_2_STREAM];
|
||||
|
||||
u8 mcs_40_siso[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_40_cdd[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_40_stbc[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_40_mimo[BRCMS_NUM_RATES_MCS_2_STREAM];
|
||||
u8 mcs32;
|
||||
};
|
||||
|
||||
struct tx_power {
|
||||
u32 flags;
|
||||
chanspec_t chanspec; /* txpwr report for this channel */
|
||||
chanspec_t local_chanspec; /* channel on which we are associated */
|
||||
u8 local_max; /* local max according to the AP */
|
||||
u8 local_constraint; /* local constraint according to the AP */
|
||||
s8 antgain[2]; /* Ant gain for each band - from SROM */
|
||||
u8 rf_cores; /* count of RF Cores being reported */
|
||||
u8 est_Pout[4]; /* Latest tx power out estimate per RF chain */
|
||||
u8 est_Pout_act[4]; /* Latest tx power out estimate per RF chain
|
||||
* without adjustment
|
||||
*/
|
||||
u8 est_Pout_cck; /* Latest CCK tx power out estimate */
|
||||
u8 tx_power_max[4]; /* Maximum target power among all rates */
|
||||
u8 tx_power_max_rate_ind[4]; /* Index of the rate with the max target power */
|
||||
u8 user_limit[WL_TX_POWER_RATES]; /* User limit */
|
||||
u8 reg_limit[WL_TX_POWER_RATES]; /* Regulatory power limit */
|
||||
u8 board_limit[WL_TX_POWER_RATES]; /* Max power board can support (SROM) */
|
||||
u8 target[WL_TX_POWER_RATES]; /* Latest target power */
|
||||
};
|
||||
|
||||
struct tx_inst_power {
|
||||
u8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */
|
||||
u8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */
|
||||
};
|
||||
|
||||
struct chanvec {
|
||||
u8 vec[MAXCHANNEL / NBBY];
|
||||
};
|
||||
|
||||
struct shared_phy_params {
|
||||
struct si_pub *sih;
|
||||
void *physhim;
|
||||
uint unit;
|
||||
uint corerev;
|
||||
uint bustype;
|
||||
uint buscorerev;
|
||||
char *vars;
|
||||
u16 vid;
|
||||
u16 did;
|
||||
uint chip;
|
||||
uint chiprev;
|
||||
uint chippkg;
|
||||
uint sromrev;
|
||||
uint boardtype;
|
||||
uint boardrev;
|
||||
uint boardvendor;
|
||||
u32 boardflags;
|
||||
u32 boardflags2;
|
||||
};
|
||||
|
||||
|
||||
extern struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp);
|
||||
extern struct brcms_phy_pub *wlc_phy_attach(struct shared_phy *sh, void *regs,
|
||||
int bandtype, char *vars, struct wiphy *wiphy);
|
||||
extern void wlc_phy_detach(struct brcms_phy_pub *ppi);
|
||||
|
||||
extern bool wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype,
|
||||
u16 *phyrev, u16 *radioid,
|
||||
u16 *radiover);
|
||||
extern bool wlc_phy_get_encore(struct brcms_phy_pub *pih);
|
||||
extern u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih);
|
||||
|
||||
extern void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *ppi, bool newstate);
|
||||
extern void wlc_phy_hw_state_upd(struct brcms_phy_pub *ppi, bool newstate);
|
||||
extern void wlc_phy_init(struct brcms_phy_pub *ppi, chanspec_t chanspec);
|
||||
extern void wlc_phy_watchdog(struct brcms_phy_pub *ppi);
|
||||
extern int wlc_phy_down(struct brcms_phy_pub *ppi);
|
||||
extern u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih);
|
||||
extern void wlc_phy_cal_init(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init);
|
||||
|
||||
extern void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi,
|
||||
chanspec_t chanspec);
|
||||
extern chanspec_t wlc_phy_chanspec_get(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi,
|
||||
chanspec_t newch);
|
||||
extern u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw);
|
||||
|
||||
extern void wlc_phy_rssi_compute(struct brcms_phy_pub *pih, void *ctx);
|
||||
extern void wlc_phy_por_inform(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_noise_sample_intr(struct brcms_phy_pub *ppi);
|
||||
extern bool wlc_phy_bist_check_phy(struct brcms_phy_pub *ppi);
|
||||
|
||||
extern void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag);
|
||||
|
||||
extern void wlc_phy_switch_radio(struct brcms_phy_pub *ppi, bool on);
|
||||
extern void wlc_phy_anacore(struct brcms_phy_pub *ppi, bool on);
|
||||
|
||||
|
||||
extern void wlc_phy_BSSinit(struct brcms_phy_pub *ppi, bool bonlyap, int rssi);
|
||||
|
||||
extern void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi,
|
||||
bool wide_filter);
|
||||
extern void wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band,
|
||||
chanvec_t *channels);
|
||||
extern chanspec_t wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi,
|
||||
uint band);
|
||||
|
||||
extern void wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint chan,
|
||||
u8 *_min_, u8 *_max_, int rate);
|
||||
extern void wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi,
|
||||
uint chan, u8 *_max_, u8 *_min_);
|
||||
extern void wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi,
|
||||
uint band, s32 *, s32 *, u32 *);
|
||||
extern void wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi,
|
||||
struct txpwr_limits *,
|
||||
chanspec_t chanspec);
|
||||
extern int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm,
|
||||
bool *override);
|
||||
extern int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm,
|
||||
bool override);
|
||||
extern void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi,
|
||||
struct txpwr_limits *);
|
||||
extern bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi,
|
||||
bool hwpwrctrl);
|
||||
extern u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi);
|
||||
extern u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi);
|
||||
extern bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *pih);
|
||||
|
||||
extern void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain,
|
||||
u8 rxchain);
|
||||
extern void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain,
|
||||
u8 rxchain);
|
||||
extern void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain,
|
||||
u8 *rxchain);
|
||||
extern u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih);
|
||||
extern s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih,
|
||||
chanspec_t chanspec);
|
||||
extern void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool val);
|
||||
|
||||
extern void wlc_phy_cal_perical(struct brcms_phy_pub *ppi, u8 reason);
|
||||
extern void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock);
|
||||
extern void wlc_phy_cal_papd_recal(struct brcms_phy_pub *ppi);
|
||||
|
||||
extern void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val);
|
||||
extern void wlc_phy_clear_tssi(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_hold_upd(struct brcms_phy_pub *ppi, mbool id, bool val);
|
||||
extern void wlc_phy_mute_upd(struct brcms_phy_pub *ppi, bool val, mbool flags);
|
||||
|
||||
extern void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type);
|
||||
|
||||
extern void wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi,
|
||||
struct tx_power *power, uint channel);
|
||||
|
||||
extern void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal);
|
||||
extern bool wlc_phy_test_ison(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi,
|
||||
u8 txpwr_percent);
|
||||
extern void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war);
|
||||
extern void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih,
|
||||
bool bf_preempt);
|
||||
extern void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap);
|
||||
|
||||
extern void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end);
|
||||
|
||||
extern void wlc_phy_freqtrack_start(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_freqtrack_end(struct brcms_phy_pub *ppi);
|
||||
|
||||
extern const u8 *wlc_phy_get_ofdm_rate_lookup(void);
|
||||
|
||||
extern s8 wlc_phy_get_tx_power_offset_by_mcs(struct brcms_phy_pub *ppi,
|
||||
u8 mcs_offset);
|
||||
extern s8 wlc_phy_get_tx_power_offset(struct brcms_phy_pub *ppi, u8 tbl_offset);
|
||||
#endif /* _BRCM_PHY_HAL_H_ */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,121 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_PHY_LCN_H_
|
||||
#define _BRCM_PHY_LCN_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
struct brcms_phy_lcnphy {
|
||||
int lcnphy_txrf_sp_9_override;
|
||||
u8 lcnphy_full_cal_channel;
|
||||
u8 lcnphy_cal_counter;
|
||||
u16 lcnphy_cal_temper;
|
||||
bool lcnphy_recal;
|
||||
|
||||
u8 lcnphy_rc_cap;
|
||||
u32 lcnphy_mcs20_po;
|
||||
|
||||
u8 lcnphy_tr_isolation_mid;
|
||||
u8 lcnphy_tr_isolation_low;
|
||||
u8 lcnphy_tr_isolation_hi;
|
||||
|
||||
u8 lcnphy_bx_arch;
|
||||
u8 lcnphy_rx_power_offset;
|
||||
u8 lcnphy_rssi_vf;
|
||||
u8 lcnphy_rssi_vc;
|
||||
u8 lcnphy_rssi_gs;
|
||||
u8 lcnphy_tssi_val;
|
||||
u8 lcnphy_rssi_vf_lowtemp;
|
||||
u8 lcnphy_rssi_vc_lowtemp;
|
||||
u8 lcnphy_rssi_gs_lowtemp;
|
||||
|
||||
u8 lcnphy_rssi_vf_hightemp;
|
||||
u8 lcnphy_rssi_vc_hightemp;
|
||||
u8 lcnphy_rssi_gs_hightemp;
|
||||
|
||||
s16 lcnphy_pa0b0;
|
||||
s16 lcnphy_pa0b1;
|
||||
s16 lcnphy_pa0b2;
|
||||
|
||||
u16 lcnphy_rawtempsense;
|
||||
u8 lcnphy_measPower;
|
||||
u8 lcnphy_tempsense_slope;
|
||||
u8 lcnphy_freqoffset_corr;
|
||||
u8 lcnphy_tempsense_option;
|
||||
u8 lcnphy_tempcorrx;
|
||||
bool lcnphy_iqcal_swp_dis;
|
||||
bool lcnphy_hw_iqcal_en;
|
||||
uint lcnphy_bandedge_corr;
|
||||
bool lcnphy_spurmod;
|
||||
u16 lcnphy_tssi_tx_cnt;
|
||||
u16 lcnphy_tssi_idx;
|
||||
u16 lcnphy_tssi_npt;
|
||||
|
||||
u16 lcnphy_target_tx_freq;
|
||||
s8 lcnphy_tx_power_idx_override;
|
||||
u16 lcnphy_noise_samples;
|
||||
|
||||
u32 lcnphy_papdRxGnIdx;
|
||||
u32 lcnphy_papd_rxGnCtrl_init;
|
||||
|
||||
u32 lcnphy_gain_idx_14_lowword;
|
||||
u32 lcnphy_gain_idx_14_hiword;
|
||||
u32 lcnphy_gain_idx_27_lowword;
|
||||
u32 lcnphy_gain_idx_27_hiword;
|
||||
s16 lcnphy_ofdmgainidxtableoffset;
|
||||
s16 lcnphy_dsssgainidxtableoffset;
|
||||
u32 lcnphy_tr_R_gain_val;
|
||||
u32 lcnphy_tr_T_gain_val;
|
||||
s8 lcnphy_input_pwr_offset_db;
|
||||
u16 lcnphy_Med_Low_Gain_db;
|
||||
u16 lcnphy_Very_Low_Gain_db;
|
||||
s8 lcnphy_lastsensed_temperature;
|
||||
s8 lcnphy_pkteng_rssi_slope;
|
||||
u8 lcnphy_saved_tx_user_target[TXP_NUM_RATES];
|
||||
u8 lcnphy_volt_winner;
|
||||
u8 lcnphy_volt_low;
|
||||
u8 lcnphy_54_48_36_24mbps_backoff;
|
||||
u8 lcnphy_11n_backoff;
|
||||
u8 lcnphy_lowerofdm;
|
||||
u8 lcnphy_cck;
|
||||
u8 lcnphy_psat_2pt3_detected;
|
||||
s32 lcnphy_lowest_Re_div_Im;
|
||||
s8 lcnphy_final_papd_cal_idx;
|
||||
u16 lcnphy_extstxctrl4;
|
||||
u16 lcnphy_extstxctrl0;
|
||||
u16 lcnphy_extstxctrl1;
|
||||
s16 lcnphy_cck_dig_filt_type;
|
||||
s16 lcnphy_ofdm_dig_filt_type;
|
||||
struct lcnphy_cal_results lcnphy_cal_results;
|
||||
|
||||
u8 lcnphy_psat_pwr;
|
||||
u8 lcnphy_psat_indx;
|
||||
s32 lcnphy_min_phase;
|
||||
u8 lcnphy_final_idx;
|
||||
u8 lcnphy_start_idx;
|
||||
u8 lcnphy_current_index;
|
||||
u16 lcnphy_logen_buf_1;
|
||||
u16 lcnphy_local_ovr_2;
|
||||
u16 lcnphy_local_oval_6;
|
||||
u16 lcnphy_local_oval_5;
|
||||
u16 lcnphy_logen_mixer_1;
|
||||
|
||||
u8 lcnphy_aci_stat;
|
||||
uint lcnphy_aci_start_time;
|
||||
s8 lcnphy_tx_power_offset[TXP_NUM_RATES];
|
||||
};
|
||||
#endif /* _BRCM_PHY_LCN_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,294 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "phy_qmath.h"
|
||||
|
||||
/*
|
||||
Description: This function make 16 bit unsigned multiplication. To fit the output into
|
||||
16 bits the 32 bit multiplication result is right shifted by 16 bits.
|
||||
*/
|
||||
u16 qm_mulu16(u16 op1, u16 op2)
|
||||
{
|
||||
return (u16) (((u32) op1 * (u32) op2) >> 16);
|
||||
}
|
||||
|
||||
/*
|
||||
Description: This function make 16 bit multiplication and return the result in 16 bits.
|
||||
To fit the multiplication result into 16 bits the multiplication result is right shifted by
|
||||
15 bits. Right shifting 15 bits instead of 16 bits is done to remove the extra sign bit formed
|
||||
due to the multiplication.
|
||||
When both the 16bit inputs are 0x8000 then the output is saturated to 0x7fffffff.
|
||||
*/
|
||||
s16 qm_muls16(s16 op1, s16 op2)
|
||||
{
|
||||
s32 result;
|
||||
if (op1 == (s16) 0x8000 && op2 == (s16) 0x8000) {
|
||||
result = 0x7fffffff;
|
||||
} else {
|
||||
result = ((s32) (op1) * (s32) (op2));
|
||||
}
|
||||
return (s16) (result >> 15);
|
||||
}
|
||||
|
||||
/*
|
||||
Description: This function add two 32 bit numbers and return the 32bit result.
|
||||
If the result overflow 32 bits, the output will be saturated to 32bits.
|
||||
*/
|
||||
s32 qm_add32(s32 op1, s32 op2)
|
||||
{
|
||||
s32 result;
|
||||
result = op1 + op2;
|
||||
if (op1 < 0 && op2 < 0 && result > 0) {
|
||||
result = 0x80000000;
|
||||
} else if (op1 > 0 && op2 > 0 && result < 0) {
|
||||
result = 0x7fffffff;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
Description: This function add two 16 bit numbers and return the 16bit result.
|
||||
If the result overflow 16 bits, the output will be saturated to 16bits.
|
||||
*/
|
||||
s16 qm_add16(s16 op1, s16 op2)
|
||||
{
|
||||
s16 result;
|
||||
s32 temp = (s32) op1 + (s32) op2;
|
||||
if (temp > (s32) 0x7fff) {
|
||||
result = (s16) 0x7fff;
|
||||
} else if (temp < (s32) 0xffff8000) {
|
||||
result = (s16) 0xffff8000;
|
||||
} else {
|
||||
result = (s16) temp;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
Description: This function make 16 bit subtraction and return the 16bit result.
|
||||
If the result overflow 16 bits, the output will be saturated to 16bits.
|
||||
*/
|
||||
s16 qm_sub16(s16 op1, s16 op2)
|
||||
{
|
||||
s16 result;
|
||||
s32 temp = (s32) op1 - (s32) op2;
|
||||
if (temp > (s32) 0x7fff) {
|
||||
result = (s16) 0x7fff;
|
||||
} else if (temp < (s32) 0xffff8000) {
|
||||
result = (s16) 0xffff8000;
|
||||
} else {
|
||||
result = (s16) temp;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
Description: This function make a 32 bit saturated left shift when the specified shift
|
||||
is +ve. This function will make a 32 bit right shift when the specified shift is -ve.
|
||||
This function return the result after shifting operation.
|
||||
*/
|
||||
s32 qm_shl32(s32 op, int shift)
|
||||
{
|
||||
int i;
|
||||
s32 result;
|
||||
result = op;
|
||||
if (shift > 31)
|
||||
shift = 31;
|
||||
else if (shift < -31)
|
||||
shift = -31;
|
||||
if (shift >= 0) {
|
||||
for (i = 0; i < shift; i++) {
|
||||
result = qm_add32(result, result);
|
||||
}
|
||||
} else {
|
||||
result = result >> (-shift);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
Description: This function make a 16 bit saturated left shift when the specified shift
|
||||
is +ve. This function will make a 16 bit right shift when the specified shift is -ve.
|
||||
This function return the result after shifting operation.
|
||||
*/
|
||||
s16 qm_shl16(s16 op, int shift)
|
||||
{
|
||||
int i;
|
||||
s16 result;
|
||||
result = op;
|
||||
if (shift > 15)
|
||||
shift = 15;
|
||||
else if (shift < -15)
|
||||
shift = -15;
|
||||
if (shift > 0) {
|
||||
for (i = 0; i < shift; i++) {
|
||||
result = qm_add16(result, result);
|
||||
}
|
||||
} else {
|
||||
result = result >> (-shift);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
Description: This function make a 16 bit right shift when shift is +ve.
|
||||
This function make a 16 bit saturated left shift when shift is -ve. This function
|
||||
return the result of the shift operation.
|
||||
*/
|
||||
s16 qm_shr16(s16 op, int shift)
|
||||
{
|
||||
return qm_shl16(op, -shift);
|
||||
}
|
||||
|
||||
/*
|
||||
Description: This function return the number of redundant sign bits in a 32 bit number.
|
||||
Example: qm_norm32(0x00000080) = 23
|
||||
*/
|
||||
s16 qm_norm32(s32 op)
|
||||
{
|
||||
u16 u16extraSignBits;
|
||||
if (op == 0) {
|
||||
return 31;
|
||||
} else {
|
||||
u16extraSignBits = 0;
|
||||
while ((op >> 31) == (op >> 30)) {
|
||||
u16extraSignBits++;
|
||||
op = op << 1;
|
||||
}
|
||||
}
|
||||
return u16extraSignBits;
|
||||
}
|
||||
|
||||
/* This table is log2(1+(i/32)) where i=[0:1:31], in q.15 format */
|
||||
static const s16 log_table[] = {
|
||||
0,
|
||||
1455,
|
||||
2866,
|
||||
4236,
|
||||
5568,
|
||||
6863,
|
||||
8124,
|
||||
9352,
|
||||
10549,
|
||||
11716,
|
||||
12855,
|
||||
13968,
|
||||
15055,
|
||||
16117,
|
||||
17156,
|
||||
18173,
|
||||
19168,
|
||||
20143,
|
||||
21098,
|
||||
22034,
|
||||
22952,
|
||||
23852,
|
||||
24736,
|
||||
25604,
|
||||
26455,
|
||||
27292,
|
||||
28114,
|
||||
28922,
|
||||
29717,
|
||||
30498,
|
||||
31267,
|
||||
32024
|
||||
};
|
||||
|
||||
#define LOG_TABLE_SIZE 32 /* log_table size */
|
||||
#define LOG2_LOG_TABLE_SIZE 5 /* log2(log_table size) */
|
||||
#define Q_LOG_TABLE 15 /* qformat of log_table */
|
||||
#define LOG10_2 19728 /* log10(2) in q.16 */
|
||||
|
||||
/*
|
||||
Description:
|
||||
This routine takes the input number N and its q format qN and compute
|
||||
the log10(N). This routine first normalizes the input no N. Then N is in mag*(2^x) format.
|
||||
mag is any number in the range 2^30-(2^31 - 1). Then log2(mag * 2^x) = log2(mag) + x is computed.
|
||||
From that log10(mag * 2^x) = log2(mag * 2^x) * log10(2) is computed.
|
||||
This routine looks the log2 value in the table considering LOG2_LOG_TABLE_SIZE+1 MSBs.
|
||||
As the MSB is always 1, only next LOG2_OF_LOG_TABLE_SIZE MSBs are used for table lookup.
|
||||
Next 16 MSBs are used for interpolation.
|
||||
Inputs:
|
||||
N - number to which log10 has to be found.
|
||||
qN - q format of N
|
||||
log10N - address where log10(N) will be written.
|
||||
qLog10N - address where log10N qformat will be written.
|
||||
Note/Problem:
|
||||
For accurate results input should be in normalized or near normalized form.
|
||||
*/
|
||||
void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N)
|
||||
{
|
||||
s16 s16norm, s16tableIndex, s16errorApproximation;
|
||||
u16 u16offset;
|
||||
s32 s32log;
|
||||
|
||||
/* normalize the N. */
|
||||
s16norm = qm_norm32(N);
|
||||
N = N << s16norm;
|
||||
|
||||
/* The qformat of N after normalization.
|
||||
* -30 is added to treat the no as between 1.0 to 2.0
|
||||
* i.e. after adding the -30 to the qformat the decimal point will be
|
||||
* just rigtht of the MSB. (i.e. after sign bit and 1st MSB). i.e.
|
||||
* at the right side of 30th bit.
|
||||
*/
|
||||
qN = qN + s16norm - 30;
|
||||
|
||||
/* take the table index as the LOG2_OF_LOG_TABLE_SIZE bits right of the MSB */
|
||||
s16tableIndex = (s16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE)));
|
||||
|
||||
/* remove the MSB. the MSB is always 1 after normalization. */
|
||||
s16tableIndex =
|
||||
s16tableIndex & (s16) ((1 << LOG2_LOG_TABLE_SIZE) - 1);
|
||||
|
||||
/* remove the (1+LOG2_OF_LOG_TABLE_SIZE) MSBs in the N. */
|
||||
N = N & ((1 << (32 - (2 + LOG2_LOG_TABLE_SIZE))) - 1);
|
||||
|
||||
/* take the offset as the 16 MSBS after table index.
|
||||
*/
|
||||
u16offset = (u16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE + 16)));
|
||||
|
||||
/* look the log value in the table. */
|
||||
s32log = log_table[s16tableIndex]; /* q.15 format */
|
||||
|
||||
/* interpolate using the offset. */
|
||||
s16errorApproximation = (s16) qm_mulu16(u16offset, (u16) (log_table[s16tableIndex + 1] - log_table[s16tableIndex])); /* q.15 */
|
||||
|
||||
s32log = qm_add16((s16) s32log, s16errorApproximation); /* q.15 format */
|
||||
|
||||
/* adjust for the qformat of the N as
|
||||
* log2(mag * 2^x) = log2(mag) + x
|
||||
*/
|
||||
s32log = qm_add32(s32log, ((s32) -qN) << 15); /* q.15 format */
|
||||
|
||||
/* normalize the result. */
|
||||
s16norm = qm_norm32(s32log);
|
||||
|
||||
/* bring all the important bits into lower 16 bits */
|
||||
s32log = qm_shl32(s32log, s16norm - 16); /* q.15+s16norm-16 format */
|
||||
|
||||
/* compute the log10(N) by multiplying log2(N) with log10(2).
|
||||
* as log10(mag * 2^x) = log2(mag * 2^x) * log10(2)
|
||||
* log10N in q.15+s16norm-16+1 (LOG10_2 is in q.16)
|
||||
*/
|
||||
*log10N = qm_muls16((s16) s32log, (s16) LOG10_2);
|
||||
|
||||
/* write the q format of the result. */
|
||||
*qLog10N = 15 + s16norm - 16 + 1;
|
||||
|
||||
return;
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_QMATH_H_
|
||||
#define _BRCM_QMATH_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
u16 qm_mulu16(u16 op1, u16 op2);
|
||||
|
||||
s16 qm_muls16(s16 op1, s16 op2);
|
||||
|
||||
s32 qm_add32(s32 op1, s32 op2);
|
||||
|
||||
s16 qm_add16(s16 op1, s16 op2);
|
||||
|
||||
s16 qm_sub16(s16 op1, s16 op2);
|
||||
|
||||
s32 qm_shl32(s32 op, int shift);
|
||||
|
||||
s16 qm_shl16(s16 op, int shift);
|
||||
|
||||
s16 qm_shr16(s16 op, int shift);
|
||||
|
||||
s16 qm_norm32(s32 op);
|
||||
|
||||
void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N);
|
||||
|
||||
#endif /* #ifndef _BRCM_QMATH_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,167 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#define NPHY_TBL_ID_GAIN1 0
|
||||
#define NPHY_TBL_ID_GAIN2 1
|
||||
#define NPHY_TBL_ID_GAINBITS1 2
|
||||
#define NPHY_TBL_ID_GAINBITS2 3
|
||||
#define NPHY_TBL_ID_GAINLIMIT 4
|
||||
#define NPHY_TBL_ID_WRSSIGainLimit 5
|
||||
#define NPHY_TBL_ID_RFSEQ 7
|
||||
#define NPHY_TBL_ID_AFECTRL 8
|
||||
#define NPHY_TBL_ID_ANTSWCTRLLUT 9
|
||||
#define NPHY_TBL_ID_IQLOCAL 15
|
||||
#define NPHY_TBL_ID_NOISEVAR 16
|
||||
#define NPHY_TBL_ID_SAMPLEPLAY 17
|
||||
#define NPHY_TBL_ID_CORE1TXPWRCTL 26
|
||||
#define NPHY_TBL_ID_CORE2TXPWRCTL 27
|
||||
#define NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL 30
|
||||
|
||||
#define NPHY_TBL_ID_EPSILONTBL0 31
|
||||
#define NPHY_TBL_ID_SCALARTBL0 32
|
||||
#define NPHY_TBL_ID_EPSILONTBL1 33
|
||||
#define NPHY_TBL_ID_SCALARTBL1 34
|
||||
|
||||
#define NPHY_TO_BPHY_OFF 0xc00
|
||||
|
||||
#define NPHY_BandControl_currentBand 0x0001
|
||||
#define RFCC_CHIP0_PU 0x0400
|
||||
#define RFCC_POR_FORCE 0x0040
|
||||
#define RFCC_OE_POR_FORCE 0x0080
|
||||
#define NPHY_RfctrlIntc_override_OFF 0
|
||||
#define NPHY_RfctrlIntc_override_TRSW 1
|
||||
#define NPHY_RfctrlIntc_override_PA 2
|
||||
#define NPHY_RfctrlIntc_override_EXT_LNA_PU 3
|
||||
#define NPHY_RfctrlIntc_override_EXT_LNA_GAIN 4
|
||||
#define RIFS_ENABLE 0x80
|
||||
#define BPHY_BAND_SEL_UP20 0x10
|
||||
#define NPHY_MLenable 0x02
|
||||
|
||||
#define NPHY_RfseqMode_CoreActv_override 0x0001
|
||||
#define NPHY_RfseqMode_Trigger_override 0x0002
|
||||
#define NPHY_RfseqCoreActv_TxRxChain0 (0x11)
|
||||
#define NPHY_RfseqCoreActv_TxRxChain1 (0x22)
|
||||
|
||||
#define NPHY_RfseqTrigger_rx2tx 0x0001
|
||||
#define NPHY_RfseqTrigger_tx2rx 0x0002
|
||||
#define NPHY_RfseqTrigger_updategainh 0x0004
|
||||
#define NPHY_RfseqTrigger_updategainl 0x0008
|
||||
#define NPHY_RfseqTrigger_updategainu 0x0010
|
||||
#define NPHY_RfseqTrigger_reset2rx 0x0020
|
||||
#define NPHY_RfseqStatus_rx2tx 0x0001
|
||||
#define NPHY_RfseqStatus_tx2rx 0x0002
|
||||
#define NPHY_RfseqStatus_updategainh 0x0004
|
||||
#define NPHY_RfseqStatus_updategainl 0x0008
|
||||
#define NPHY_RfseqStatus_updategainu 0x0010
|
||||
#define NPHY_RfseqStatus_reset2rx 0x0020
|
||||
#define NPHY_ClassifierCtrl_cck_en 0x1
|
||||
#define NPHY_ClassifierCtrl_ofdm_en 0x2
|
||||
#define NPHY_ClassifierCtrl_waited_en 0x4
|
||||
#define NPHY_IQFlip_ADC1 0x0001
|
||||
#define NPHY_IQFlip_ADC2 0x0010
|
||||
#define NPHY_sampleCmd_STOP 0x0002
|
||||
|
||||
#define RX_GF_OR_MM 0x0004
|
||||
#define RX_GF_MM_AUTO 0x0100
|
||||
|
||||
#define NPHY_iqloCalCmdGctl_IQLO_CAL_EN 0x8000
|
||||
|
||||
#define NPHY_IqestCmd_iqstart 0x1
|
||||
#define NPHY_IqestCmd_iqMode 0x2
|
||||
|
||||
#define NPHY_TxPwrCtrlCmd_pwrIndex_init 0x40
|
||||
#define NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 0x19
|
||||
|
||||
#define PRIM_SEL_UP20 0x8000
|
||||
|
||||
#define NPHY_RFSEQ_RX2TX 0x0
|
||||
#define NPHY_RFSEQ_TX2RX 0x1
|
||||
#define NPHY_RFSEQ_RESET2RX 0x2
|
||||
#define NPHY_RFSEQ_UPDATEGAINH 0x3
|
||||
#define NPHY_RFSEQ_UPDATEGAINL 0x4
|
||||
#define NPHY_RFSEQ_UPDATEGAINU 0x5
|
||||
|
||||
#define NPHY_RFSEQ_CMD_NOP 0x0
|
||||
#define NPHY_RFSEQ_CMD_RXG_FBW 0x1
|
||||
#define NPHY_RFSEQ_CMD_TR_SWITCH 0x2
|
||||
#define NPHY_RFSEQ_CMD_EXT_PA 0x3
|
||||
#define NPHY_RFSEQ_CMD_RXPD_TXPD 0x4
|
||||
#define NPHY_RFSEQ_CMD_TX_GAIN 0x5
|
||||
#define NPHY_RFSEQ_CMD_RX_GAIN 0x6
|
||||
#define NPHY_RFSEQ_CMD_SET_HPF_BW 0x7
|
||||
#define NPHY_RFSEQ_CMD_CLR_HIQ_DIS 0x8
|
||||
#define NPHY_RFSEQ_CMD_END 0xf
|
||||
|
||||
#define NPHY_REV3_RFSEQ_CMD_NOP 0x0
|
||||
#define NPHY_REV3_RFSEQ_CMD_RXG_FBW 0x1
|
||||
#define NPHY_REV3_RFSEQ_CMD_TR_SWITCH 0x2
|
||||
#define NPHY_REV3_RFSEQ_CMD_INT_PA_PU 0x3
|
||||
#define NPHY_REV3_RFSEQ_CMD_EXT_PA 0x4
|
||||
#define NPHY_REV3_RFSEQ_CMD_RXPD_TXPD 0x5
|
||||
#define NPHY_REV3_RFSEQ_CMD_TX_GAIN 0x6
|
||||
#define NPHY_REV3_RFSEQ_CMD_RX_GAIN 0x7
|
||||
#define NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS 0x8
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_HPF_H_HPC 0x9
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_LPF_H_HPC 0xa
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_HPF_M_HPC 0xb
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_LPF_M_HPC 0xc
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_HPF_L_HPC 0xd
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_LPF_L_HPC 0xe
|
||||
#define NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS 0xf
|
||||
#define NPHY_REV3_RFSEQ_CMD_END 0x1f
|
||||
|
||||
#define NPHY_RSSI_SEL_W1 0x0
|
||||
#define NPHY_RSSI_SEL_W2 0x1
|
||||
#define NPHY_RSSI_SEL_NB 0x2
|
||||
#define NPHY_RSSI_SEL_IQ 0x3
|
||||
#define NPHY_RSSI_SEL_TSSI_2G 0x4
|
||||
#define NPHY_RSSI_SEL_TSSI_5G 0x5
|
||||
#define NPHY_RSSI_SEL_TBD 0x6
|
||||
|
||||
#define NPHY_RAIL_I 0x0
|
||||
#define NPHY_RAIL_Q 0x1
|
||||
|
||||
#define NPHY_FORCESIG_DECODEGATEDCLKS 0x8
|
||||
|
||||
#define NPHY_REV7_RfctrlOverride_cmd_rxrf_pu 0x0
|
||||
#define NPHY_REV7_RfctrlOverride_cmd_rx_pu 0x1
|
||||
#define NPHY_REV7_RfctrlOverride_cmd_tx_pu 0x2
|
||||
#define NPHY_REV7_RfctrlOverride_cmd_rxgain 0x3
|
||||
#define NPHY_REV7_RfctrlOverride_cmd_txgain 0x4
|
||||
|
||||
#define NPHY_REV7_RXGAINCODE_RFMXGAIN_MASK 0x000ff
|
||||
#define NPHY_REV7_RXGAINCODE_LPFGAIN_MASK 0x0ff00
|
||||
#define NPHY_REV7_RXGAINCODE_DVGAGAIN_MASK 0xf0000
|
||||
|
||||
#define NPHY_REV7_TXGAINCODE_TGAIN_MASK 0x7fff
|
||||
#define NPHY_REV7_TXGAINCODE_LPFGAIN_MASK 0x8000
|
||||
#define NPHY_REV7_TXGAINCODE_BIQ0GAIN_SHIFT 14
|
||||
|
||||
#define NPHY_REV7_RFCTRLOVERRIDE_ID0 0x0
|
||||
#define NPHY_REV7_RFCTRLOVERRIDE_ID1 0x1
|
||||
#define NPHY_REV7_RFCTRLOVERRIDE_ID2 0x2
|
||||
|
||||
#define NPHY_IqestIqAccLo(core) ((core == 0) ? 0x12c : 0x134)
|
||||
|
||||
#define NPHY_IqestIqAccHi(core) ((core == 0) ? 0x12d : 0x135)
|
||||
|
||||
#define NPHY_IqestipwrAccLo(core) ((core == 0) ? 0x12e : 0x136)
|
||||
|
||||
#define NPHY_IqestipwrAccHi(core) ((core == 0) ? 0x12f : 0x137)
|
||||
|
||||
#define NPHY_IqestqpwrAccLo(core) ((core == 0) ? 0x130 : 0x138)
|
||||
|
||||
#define NPHY_IqestqpwrAccHi(core) ((core == 0) ? 0x131 : 0x139)
|
File diff suppressed because it is too large
Load Diff
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include "phy_int.h"
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev0[];
|
||||
extern const u32 dot11lcnphytbl_rx_gain_info_sz_rev0;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa_combo;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250;
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_info_rev0[];
|
||||
extern const u32 dot11lcnphytbl_info_sz_rev0;
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_2G_rev2[];
|
||||
extern const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz;
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_5G_rev2[];
|
||||
extern const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz;
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[];
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[];
|
||||
|
||||
struct lcnphy_tx_gain_tbl_entry {
|
||||
unsigned char gm;
|
||||
unsigned char pga;
|
||||
unsigned char pad;
|
||||
unsigned char dac;
|
||||
unsigned char bb_mult;
|
||||
};
|
||||
|
||||
extern const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[];
|
||||
|
||||
extern const struct
|
||||
lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[];
|
||||
|
||||
extern const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[];
|
File diff suppressed because it is too large
Load Diff
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#define ANT_SWCTRL_TBL_REV3_IDX (0)
|
||||
|
||||
#include <types.h>
|
||||
#include "phy_int.h"
|
||||
|
||||
extern const struct phytbl_info mimophytbl_info_rev0[],
|
||||
mimophytbl_info_rev0_volatile[];
|
||||
extern const u32 mimophytbl_info_sz_rev0, mimophytbl_info_sz_rev0_volatile;
|
||||
|
||||
extern const struct phytbl_info mimophytbl_info_rev3[],
|
||||
mimophytbl_info_rev3_volatile[], mimophytbl_info_rev3_volatile1[],
|
||||
mimophytbl_info_rev3_volatile2[], mimophytbl_info_rev3_volatile3[];
|
||||
extern const u32 mimophytbl_info_sz_rev3, mimophytbl_info_sz_rev3_volatile,
|
||||
mimophytbl_info_sz_rev3_volatile1, mimophytbl_info_sz_rev3_volatile2,
|
||||
mimophytbl_info_sz_rev3_volatile3;
|
||||
|
||||
extern const u32 noise_var_tbl_rev3[];
|
||||
|
||||
extern const struct phytbl_info mimophytbl_info_rev7[];
|
||||
extern const u32 mimophytbl_info_sz_rev7;
|
||||
extern const u32 noise_var_tbl_rev7[];
|
||||
|
||||
extern const struct phytbl_info mimophytbl_info_rev16[];
|
||||
extern const u32 mimophytbl_info_sz_rev16;
|
@ -1,218 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is "two-way" interface, acting as the SHIM layer between WL and PHY layer.
|
||||
* WL driver can optinally call this translation layer to do some preprocessing, then reach PHY.
|
||||
* On the PHY->WL driver direction, all calls go through this layer since PHY doesn't have the
|
||||
* access to wlc_hw pointer.
|
||||
*/
|
||||
#include <linux/slab.h>
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "bmac.h"
|
||||
#include "main.h"
|
||||
#include "mac80211_if.h"
|
||||
#include "phy_shim.h"
|
||||
|
||||
/* PHY SHIM module specific state */
|
||||
struct phy_shim_info {
|
||||
struct brcms_hardware *wlc_hw; /* pointer to main wlc_hw structure */
|
||||
void *wlc; /* pointer to main wlc structure */
|
||||
void *wl; /* pointer to os-specific private state */
|
||||
};
|
||||
|
||||
struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw,
|
||||
void *wl, void *wlc) {
|
||||
struct phy_shim_info *physhim = NULL;
|
||||
|
||||
physhim = kzalloc(sizeof(struct phy_shim_info), GFP_ATOMIC);
|
||||
if (!physhim) {
|
||||
wiphy_err(wlc_hw->wlc->wiphy,
|
||||
"wl%d: wlc_phy_shim_attach: out of mem\n",
|
||||
wlc_hw->unit);
|
||||
return NULL;
|
||||
}
|
||||
physhim->wlc_hw = wlc_hw;
|
||||
physhim->wlc = wlc;
|
||||
physhim->wl = wl;
|
||||
|
||||
return physhim;
|
||||
}
|
||||
|
||||
void wlc_phy_shim_detach(struct phy_shim_info *physhim)
|
||||
{
|
||||
kfree(physhim);
|
||||
}
|
||||
|
||||
struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
|
||||
void (*fn) (void *arg), void *arg,
|
||||
const char *name)
|
||||
{
|
||||
return (struct wlapi_timer *)
|
||||
brcms_init_timer(physhim->wl, fn, arg, name);
|
||||
}
|
||||
|
||||
void wlapi_free_timer(struct phy_shim_info *physhim, struct wlapi_timer *t)
|
||||
{
|
||||
brcms_free_timer(physhim->wl, (struct brcms_timer *)t);
|
||||
}
|
||||
|
||||
void
|
||||
wlapi_add_timer(struct phy_shim_info *physhim, struct wlapi_timer *t, uint ms,
|
||||
int periodic)
|
||||
{
|
||||
brcms_add_timer(physhim->wl, (struct brcms_timer *)t, ms, periodic);
|
||||
}
|
||||
|
||||
bool wlapi_del_timer(struct phy_shim_info *physhim, struct wlapi_timer *t)
|
||||
{
|
||||
return brcms_del_timer(physhim->wl, (struct brcms_timer *)t);
|
||||
}
|
||||
|
||||
void wlapi_intrson(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_intrson(physhim->wl);
|
||||
}
|
||||
|
||||
u32 wlapi_intrsoff(struct phy_shim_info *physhim)
|
||||
{
|
||||
return brcms_intrsoff(physhim->wl);
|
||||
}
|
||||
|
||||
void wlapi_intrsrestore(struct phy_shim_info *physhim, u32 macintmask)
|
||||
{
|
||||
brcms_intrsrestore(physhim->wl, macintmask);
|
||||
}
|
||||
|
||||
void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset, u16 v)
|
||||
{
|
||||
brcms_b_write_shm(physhim->wlc_hw, offset, v);
|
||||
}
|
||||
|
||||
u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset)
|
||||
{
|
||||
return brcms_b_read_shm(physhim->wlc_hw, offset);
|
||||
}
|
||||
|
||||
void
|
||||
wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx, u16 mask,
|
||||
u16 val, int bands)
|
||||
{
|
||||
brcms_b_mhf(physhim->wlc_hw, idx, mask, val, bands);
|
||||
}
|
||||
|
||||
void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags)
|
||||
{
|
||||
brcms_b_corereset(physhim->wlc_hw, flags);
|
||||
}
|
||||
|
||||
void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_c_suspend_mac_and_wait(physhim->wlc);
|
||||
}
|
||||
|
||||
void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode)
|
||||
{
|
||||
brcms_b_switch_macfreq(physhim->wlc_hw, spurmode);
|
||||
}
|
||||
|
||||
void wlapi_enable_mac(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_c_enable_mac(physhim->wlc);
|
||||
}
|
||||
|
||||
void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask, u32 val)
|
||||
{
|
||||
brcms_b_mctrl(physhim->wlc_hw, mask, val);
|
||||
}
|
||||
|
||||
void wlapi_bmac_phy_reset(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_b_phy_reset(physhim->wlc_hw);
|
||||
}
|
||||
|
||||
void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw)
|
||||
{
|
||||
brcms_b_bw_set(physhim->wlc_hw, bw);
|
||||
}
|
||||
|
||||
u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim)
|
||||
{
|
||||
return brcms_b_get_txant(physhim->wlc_hw);
|
||||
}
|
||||
|
||||
void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk)
|
||||
{
|
||||
brcms_b_phyclk_fgc(physhim->wlc_hw, clk);
|
||||
}
|
||||
|
||||
void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk)
|
||||
{
|
||||
brcms_b_macphyclk_set(physhim->wlc_hw, clk);
|
||||
}
|
||||
|
||||
void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on)
|
||||
{
|
||||
brcms_b_core_phypll_ctl(physhim->wlc_hw, on);
|
||||
}
|
||||
|
||||
void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_b_core_phypll_reset(physhim->wlc_hw);
|
||||
}
|
||||
|
||||
void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_c_ucode_wake_override_set(physhim->wlc_hw,
|
||||
BRCMS_WAKE_OVERRIDE_PHYREG);
|
||||
}
|
||||
|
||||
void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_c_ucode_wake_override_clear(physhim->wlc_hw,
|
||||
BRCMS_WAKE_OVERRIDE_PHYREG);
|
||||
}
|
||||
|
||||
void
|
||||
wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int offset,
|
||||
int len, void *buf)
|
||||
{
|
||||
brcms_b_write_template_ram(physhim->wlc_hw, offset, len, buf);
|
||||
}
|
||||
|
||||
u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim, u8 rate)
|
||||
{
|
||||
return brcms_b_rate_shm_offset(physhim->wlc_hw, rate);
|
||||
}
|
||||
|
||||
void wlapi_ucode_sample_init(struct phy_shim_info *physhim)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint offset, void *buf,
|
||||
int len, u32 sel)
|
||||
{
|
||||
brcms_b_copyfrom_objmem(physhim->wlc_hw, offset, buf, len, sel);
|
||||
}
|
||||
|
||||
void
|
||||
wlapi_copyto_objmem(struct phy_shim_info *physhim, uint offset, const void *buf,
|
||||
int l, u32 sel)
|
||||
{
|
||||
brcms_b_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel);
|
||||
}
|
@ -1,164 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* phy_shim.h: stuff defined in phy_shim.c and included only by the phy
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_PHY_SHIM_H_
|
||||
#define _BRCM_PHY_SHIM_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define RADAR_TYPE_NONE 0 /* Radar type None */
|
||||
#define RADAR_TYPE_ETSI_1 1 /* ETSI 1 Radar type */
|
||||
#define RADAR_TYPE_ETSI_2 2 /* ETSI 2 Radar type */
|
||||
#define RADAR_TYPE_ETSI_3 3 /* ETSI 3 Radar type */
|
||||
#define RADAR_TYPE_ITU_E 4 /* ITU E Radar type */
|
||||
#define RADAR_TYPE_ITU_K 5 /* ITU K Radar type */
|
||||
#define RADAR_TYPE_UNCLASSIFIED 6 /* Unclassified Radar type */
|
||||
#define RADAR_TYPE_BIN5 7 /* long pulse radar type */
|
||||
#define RADAR_TYPE_STG2 8 /* staggered-2 radar */
|
||||
#define RADAR_TYPE_STG3 9 /* staggered-3 radar */
|
||||
#define RADAR_TYPE_FRA 10 /* French radar */
|
||||
|
||||
/* French radar pulse widths */
|
||||
#define FRA_T1_20MHZ 52770
|
||||
#define FRA_T2_20MHZ 61538
|
||||
#define FRA_T3_20MHZ 66002
|
||||
#define FRA_T1_40MHZ 105541
|
||||
#define FRA_T2_40MHZ 123077
|
||||
#define FRA_T3_40MHZ 132004
|
||||
#define FRA_ERR_20MHZ 60
|
||||
#define FRA_ERR_40MHZ 120
|
||||
|
||||
#define ANTSEL_NA 0 /* No boardlevel selection available */
|
||||
#define ANTSEL_2x4 1 /* 2x4 boardlevel selection available */
|
||||
#define ANTSEL_2x3 2 /* 2x3 CB2 boardlevel selection available */
|
||||
|
||||
/* Rx Antenna diversity control values */
|
||||
#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */
|
||||
#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */
|
||||
#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */
|
||||
#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */
|
||||
#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */
|
||||
#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */
|
||||
|
||||
#define WL_ANT_RX_MAX 2 /* max 2 receive antennas */
|
||||
#define WL_ANT_HT_RX_MAX 3 /* max 3 receive antennas/cores */
|
||||
#define WL_ANT_IDX_1 0 /* antenna index 1 */
|
||||
#define WL_ANT_IDX_2 1 /* antenna index 2 */
|
||||
|
||||
/* values for n_preamble_type */
|
||||
#define BRCMS_N_PREAMBLE_MIXEDMODE 0
|
||||
#define BRCMS_N_PREAMBLE_GF 1
|
||||
#define BRCMS_N_PREAMBLE_GF_BRCM 2
|
||||
|
||||
#define WL_TX_POWER_RATES_LEGACY 45
|
||||
#define WL_TX_POWER_MCS20_FIRST 12
|
||||
#define WL_TX_POWER_MCS20_NUM 16
|
||||
#define WL_TX_POWER_MCS40_FIRST 28
|
||||
#define WL_TX_POWER_MCS40_NUM 17
|
||||
|
||||
|
||||
#define WL_TX_POWER_RATES 101
|
||||
#define WL_TX_POWER_CCK_FIRST 0
|
||||
#define WL_TX_POWER_CCK_NUM 4
|
||||
#define WL_TX_POWER_OFDM_FIRST 4 /* Index for first 20MHz OFDM SISO rate */
|
||||
#define WL_TX_POWER_OFDM20_CDD_FIRST 12 /* Index for first 20MHz OFDM CDD rate */
|
||||
#define WL_TX_POWER_OFDM40_SISO_FIRST 52 /* Index for first 40MHz OFDM SISO rate */
|
||||
#define WL_TX_POWER_OFDM40_CDD_FIRST 60 /* Index for first 40MHz OFDM CDD rate */
|
||||
#define WL_TX_POWER_OFDM_NUM 8
|
||||
#define WL_TX_POWER_MCS20_SISO_FIRST 20 /* Index for first 20MHz MCS SISO rate */
|
||||
#define WL_TX_POWER_MCS20_CDD_FIRST 28 /* Index for first 20MHz MCS CDD rate */
|
||||
#define WL_TX_POWER_MCS20_STBC_FIRST 36 /* Index for first 20MHz MCS STBC rate */
|
||||
#define WL_TX_POWER_MCS20_SDM_FIRST 44 /* Index for first 20MHz MCS SDM rate */
|
||||
#define WL_TX_POWER_MCS40_SISO_FIRST 68 /* Index for first 40MHz MCS SISO rate */
|
||||
#define WL_TX_POWER_MCS40_CDD_FIRST 76 /* Index for first 40MHz MCS CDD rate */
|
||||
#define WL_TX_POWER_MCS40_STBC_FIRST 84 /* Index for first 40MHz MCS STBC rate */
|
||||
#define WL_TX_POWER_MCS40_SDM_FIRST 92 /* Index for first 40MHz MCS SDM rate */
|
||||
#define WL_TX_POWER_MCS_1_STREAM_NUM 8
|
||||
#define WL_TX_POWER_MCS_2_STREAM_NUM 8
|
||||
#define WL_TX_POWER_MCS_32 100 /* Index for 40MHz rate MCS 32 */
|
||||
#define WL_TX_POWER_MCS_32_NUM 1
|
||||
|
||||
/* sslpnphy specifics */
|
||||
#define WL_TX_POWER_MCS20_SISO_FIRST_SSN 12 /* Index for first 20MHz MCS SISO rate */
|
||||
|
||||
/* struct tx_power::flags bits */
|
||||
#define WL_TX_POWER_F_ENABLED 1
|
||||
#define WL_TX_POWER_F_HW 2
|
||||
#define WL_TX_POWER_F_MIMO 4
|
||||
#define WL_TX_POWER_F_SISO 8
|
||||
|
||||
/* values to force tx/rx chain */
|
||||
#define BRCMS_N_TXRX_CHAIN0 0
|
||||
#define BRCMS_N_TXRX_CHAIN1 1
|
||||
|
||||
extern struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw,
|
||||
void *wl, void *wlc);
|
||||
extern void wlc_phy_shim_detach(struct phy_shim_info *physhim);
|
||||
|
||||
/* PHY to WL utility functions */
|
||||
extern struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
|
||||
void (*fn) (void *arg), void *arg,
|
||||
const char *name);
|
||||
extern void wlapi_free_timer(struct phy_shim_info *physhim,
|
||||
struct wlapi_timer *t);
|
||||
extern void wlapi_add_timer(struct phy_shim_info *physhim,
|
||||
struct wlapi_timer *t, uint ms, int periodic);
|
||||
extern bool wlapi_del_timer(struct phy_shim_info *physhim,
|
||||
struct wlapi_timer *t);
|
||||
extern void wlapi_intrson(struct phy_shim_info *physhim);
|
||||
extern u32 wlapi_intrsoff(struct phy_shim_info *physhim);
|
||||
extern void wlapi_intrsrestore(struct phy_shim_info *physhim,
|
||||
u32 macintmask);
|
||||
|
||||
extern void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset,
|
||||
u16 v);
|
||||
extern u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset);
|
||||
extern void wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx,
|
||||
u16 mask, u16 val, int bands);
|
||||
extern void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags);
|
||||
extern void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim);
|
||||
extern void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode);
|
||||
extern void wlapi_enable_mac(struct phy_shim_info *physhim);
|
||||
extern void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask,
|
||||
u32 val);
|
||||
extern void wlapi_bmac_phy_reset(struct phy_shim_info *physhim);
|
||||
extern void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw);
|
||||
extern void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk);
|
||||
extern void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk);
|
||||
extern void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on);
|
||||
extern void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim);
|
||||
extern void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *
|
||||
physhim);
|
||||
extern void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *
|
||||
physhim);
|
||||
extern void wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int o,
|
||||
int len, void *buf);
|
||||
extern u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim,
|
||||
u8 rate);
|
||||
extern void wlapi_ucode_sample_init(struct phy_shim_info *physhim);
|
||||
extern void wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint,
|
||||
void *buf, int, u32 sel);
|
||||
extern void wlapi_copyto_objmem(struct phy_shim_info *physhim, uint,
|
||||
const void *buf, int, u32);
|
||||
|
||||
extern void wlapi_high_update_phy_mode(struct phy_shim_info *physhim,
|
||||
u32 phy_mode);
|
||||
extern u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim);
|
||||
#endif /* _BRCM_PHY_SHIM_H_ */
|
@ -1,474 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <brcm_hw_ids.h>
|
||||
#include <chipcommon.h>
|
||||
#include <brcmu_utils.h>
|
||||
#include "pub.h"
|
||||
#include "aiutils.h"
|
||||
#include "pmu.h"
|
||||
|
||||
/*
|
||||
* external LPO crystal frequency
|
||||
*/
|
||||
#define EXT_ILP_HZ 32768
|
||||
|
||||
/*
|
||||
* Duration for ILP clock frequency measurment in milliseconds
|
||||
*
|
||||
* remark: 1000 must be an integer multiple of this duration
|
||||
*/
|
||||
#define ILP_CALC_DUR 10
|
||||
|
||||
/* Fields in pmucontrol */
|
||||
#define PCTL_ILP_DIV_MASK 0xffff0000
|
||||
#define PCTL_ILP_DIV_SHIFT 16
|
||||
#define PCTL_PLL_PLLCTL_UPD 0x00000400 /* rev 2 */
|
||||
#define PCTL_NOILP_ON_WAIT 0x00000200 /* rev 1 */
|
||||
#define PCTL_HT_REQ_EN 0x00000100
|
||||
#define PCTL_ALP_REQ_EN 0x00000080
|
||||
#define PCTL_XTALFREQ_MASK 0x0000007c
|
||||
#define PCTL_XTALFREQ_SHIFT 2
|
||||
#define PCTL_ILP_DIV_EN 0x00000002
|
||||
#define PCTL_LPO_SEL 0x00000001
|
||||
|
||||
/* ILP clock */
|
||||
#define ILP_CLOCK 32000
|
||||
|
||||
/* ALP clock on pre-PMU chips */
|
||||
#define ALP_CLOCK 20000000
|
||||
|
||||
/* pmustatus */
|
||||
#define PST_EXTLPOAVAIL 0x0100
|
||||
#define PST_WDRESET 0x0080
|
||||
#define PST_INTPEND 0x0040
|
||||
#define PST_SBCLKST 0x0030
|
||||
#define PST_SBCLKST_ILP 0x0010
|
||||
#define PST_SBCLKST_ALP 0x0020
|
||||
#define PST_SBCLKST_HT 0x0030
|
||||
#define PST_ALPAVAIL 0x0008
|
||||
#define PST_HTAVAIL 0x0004
|
||||
#define PST_RESINIT 0x0003
|
||||
|
||||
/* PMU resource bit position */
|
||||
#define PMURES_BIT(bit) (1 << (bit))
|
||||
|
||||
/* PMU corerev and chip specific PLL controls.
|
||||
* PMU<rev>_PLL<num>_XX where <rev> is PMU corerev and <num> is an arbitrary number
|
||||
* to differentiate different PLLs controlled by the same PMU rev.
|
||||
*/
|
||||
/* pllcontrol registers */
|
||||
/* ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>, p1div, p2div, _bypass_sdmod */
|
||||
#define PMU1_PLL0_PLLCTL0 0
|
||||
#define PMU1_PLL0_PLLCTL1 1
|
||||
#define PMU1_PLL0_PLLCTL2 2
|
||||
#define PMU1_PLL0_PLLCTL3 3
|
||||
#define PMU1_PLL0_PLLCTL4 4
|
||||
#define PMU1_PLL0_PLLCTL5 5
|
||||
|
||||
/* pmu XtalFreqRatio */
|
||||
#define PMU_XTALFREQ_REG_ILPCTR_MASK 0x00001FFF
|
||||
#define PMU_XTALFREQ_REG_MEASURE_MASK 0x80000000
|
||||
#define PMU_XTALFREQ_REG_MEASURE_SHIFT 31
|
||||
|
||||
/* 4313 resources */
|
||||
#define RES4313_BB_PU_RSRC 0
|
||||
#define RES4313_ILP_REQ_RSRC 1
|
||||
#define RES4313_XTAL_PU_RSRC 2
|
||||
#define RES4313_ALP_AVAIL_RSRC 3
|
||||
#define RES4313_RADIO_PU_RSRC 4
|
||||
#define RES4313_BG_PU_RSRC 5
|
||||
#define RES4313_VREG1P4_PU_RSRC 6
|
||||
#define RES4313_AFE_PWRSW_RSRC 7
|
||||
#define RES4313_RX_PWRSW_RSRC 8
|
||||
#define RES4313_TX_PWRSW_RSRC 9
|
||||
#define RES4313_BB_PWRSW_RSRC 10
|
||||
#define RES4313_SYNTH_PWRSW_RSRC 11
|
||||
#define RES4313_MISC_PWRSW_RSRC 12
|
||||
#define RES4313_BB_PLL_PWRSW_RSRC 13
|
||||
#define RES4313_HT_AVAIL_RSRC 14
|
||||
#define RES4313_MACPHY_CLK_AVAIL_RSRC 15
|
||||
|
||||
/* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
|
||||
static void si_pmu_res_masks(struct si_pub *sih, u32 * pmin, u32 * pmax)
|
||||
{
|
||||
u32 min_mask = 0, max_mask = 0;
|
||||
uint rsrcs;
|
||||
|
||||
/* # resources */
|
||||
rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
|
||||
|
||||
/* determine min/max rsrc masks */
|
||||
switch (sih->chip) {
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
/* ??? */
|
||||
break;
|
||||
|
||||
case BCM4313_CHIP_ID:
|
||||
min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
|
||||
PMURES_BIT(RES4313_XTAL_PU_RSRC) |
|
||||
PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
|
||||
PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
|
||||
max_mask = 0xffff;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
*pmin = min_mask;
|
||||
*pmax = max_mask;
|
||||
}
|
||||
|
||||
static void
|
||||
si_pmu_spuravoid_pllupdate(struct si_pub *sih, chipcregs_t *cc, u8 spuravoid)
|
||||
{
|
||||
u32 tmp = 0;
|
||||
|
||||
switch (sih->chip) {
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
if (spuravoid == 1) {
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
|
||||
W_REG(&cc->pllcontrol_data, 0x11500010);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
|
||||
W_REG(&cc->pllcontrol_data, 0x000C0C06);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
|
||||
W_REG(&cc->pllcontrol_data, 0x0F600a08);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
|
||||
W_REG(&cc->pllcontrol_data, 0x00000000);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
|
||||
W_REG(&cc->pllcontrol_data, 0x2001E920);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
|
||||
W_REG(&cc->pllcontrol_data, 0x88888815);
|
||||
} else {
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
|
||||
W_REG(&cc->pllcontrol_data, 0x11100010);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
|
||||
W_REG(&cc->pllcontrol_data, 0x000c0c06);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
|
||||
W_REG(&cc->pllcontrol_data, 0x03000a08);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
|
||||
W_REG(&cc->pllcontrol_data, 0x00000000);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
|
||||
W_REG(&cc->pllcontrol_data, 0x200005c0);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
|
||||
W_REG(&cc->pllcontrol_data, 0x88888815);
|
||||
}
|
||||
tmp = 1 << 10;
|
||||
break;
|
||||
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
|
||||
W_REG(&cc->pllcontrol_data, 0x11100008);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
|
||||
W_REG(&cc->pllcontrol_data, 0x0c000c06);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
|
||||
W_REG(&cc->pllcontrol_data, 0x03000a08);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
|
||||
W_REG(&cc->pllcontrol_data, 0x00000000);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
|
||||
W_REG(&cc->pllcontrol_data, 0x200005c0);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
|
||||
W_REG(&cc->pllcontrol_data, 0x88888855);
|
||||
|
||||
tmp = 1 << 10;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* bail out */
|
||||
return;
|
||||
}
|
||||
|
||||
tmp |= R_REG(&cc->pmucontrol);
|
||||
W_REG(&cc->pmucontrol, tmp);
|
||||
}
|
||||
|
||||
u32 si_pmu_ilp_clock(struct si_pub *sih)
|
||||
{
|
||||
static u32 ilpcycles_per_sec;
|
||||
|
||||
if (!PMUCTL_ENAB(sih))
|
||||
return ILP_CLOCK;
|
||||
|
||||
if (ilpcycles_per_sec == 0) {
|
||||
u32 start, end, delta;
|
||||
u32 origidx = ai_coreidx(sih);
|
||||
chipcregs_t *cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
start = R_REG(&cc->pmutimer);
|
||||
mdelay(ILP_CALC_DUR);
|
||||
end = R_REG(&cc->pmutimer);
|
||||
delta = end - start;
|
||||
ilpcycles_per_sec = delta * (1000 / ILP_CALC_DUR);
|
||||
ai_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
return ilpcycles_per_sec;
|
||||
}
|
||||
|
||||
u16 si_pmu_fast_pwrup_delay(struct si_pub *sih)
|
||||
{
|
||||
uint delay = PMU_MAX_TRANSITION_DLY;
|
||||
|
||||
switch (sih->chip) {
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
case BCM4313_CHIP_ID:
|
||||
delay = 3700;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return (u16) delay;
|
||||
}
|
||||
|
||||
void si_pmu_sprom_enable(struct si_pub *sih, bool enable)
|
||||
{
|
||||
chipcregs_t *cc;
|
||||
uint origidx;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
origidx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
/* Read/write a chipcontrol reg */
|
||||
u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
|
||||
{
|
||||
ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0,
|
||||
reg);
|
||||
return ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(chipcregs_t, chipcontrol_data), mask, val);
|
||||
}
|
||||
|
||||
/* Read/write a regcontrol reg */
|
||||
u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
|
||||
{
|
||||
ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr), ~0,
|
||||
reg);
|
||||
return ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(chipcregs_t, regcontrol_data), mask, val);
|
||||
}
|
||||
|
||||
/* Read/write a pllcontrol reg */
|
||||
u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
|
||||
{
|
||||
ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pllcontrol_addr), ~0,
|
||||
reg);
|
||||
return ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(chipcregs_t, pllcontrol_data), mask, val);
|
||||
}
|
||||
|
||||
/* PMU PLL update */
|
||||
void si_pmu_pllupd(struct si_pub *sih)
|
||||
{
|
||||
ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmucontrol),
|
||||
PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
|
||||
}
|
||||
|
||||
/* query alp/xtal clock frequency */
|
||||
u32 si_pmu_alp_clock(struct si_pub *sih)
|
||||
{
|
||||
u32 clock = ALP_CLOCK;
|
||||
|
||||
/* bail out with default */
|
||||
if (!PMUCTL_ENAB(sih))
|
||||
return clock;
|
||||
|
||||
switch (sih->chip) {
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
case BCM4313_CHIP_ID:
|
||||
/* always 20Mhz */
|
||||
clock = 20000 * 1000;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return clock;
|
||||
}
|
||||
|
||||
void si_pmu_spuravoid(struct si_pub *sih, u8 spuravoid)
|
||||
{
|
||||
chipcregs_t *cc;
|
||||
uint origidx, intr_val;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
cc = (chipcregs_t *) ai_switch_core(sih, CC_CORE_ID, &origidx,
|
||||
&intr_val);
|
||||
|
||||
/* update the pll changes */
|
||||
si_pmu_spuravoid_pllupdate(sih, cc, spuravoid);
|
||||
|
||||
/* Return to original core */
|
||||
ai_restore_core(sih, origidx, intr_val);
|
||||
}
|
||||
|
||||
/* initialize PMU */
|
||||
void si_pmu_init(struct si_pub *sih)
|
||||
{
|
||||
chipcregs_t *cc;
|
||||
uint origidx;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
origidx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
if (sih->pmurev == 1)
|
||||
AND_REG(&cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
|
||||
else if (sih->pmurev >= 2)
|
||||
OR_REG(&cc->pmucontrol, PCTL_NOILP_ON_WAIT);
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
/* initialize PMU chip controls and other chip level stuff */
|
||||
void si_pmu_chip_init(struct si_pub *sih)
|
||||
{
|
||||
uint origidx;
|
||||
|
||||
/* Gate off SPROM clock and chip select signals */
|
||||
si_pmu_sprom_enable(sih, false);
|
||||
|
||||
/* Remember original core */
|
||||
origidx = ai_coreidx(sih);
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
/* initialize PMU switch/regulators */
|
||||
void si_pmu_swreg_init(struct si_pub *sih)
|
||||
{
|
||||
}
|
||||
|
||||
/* initialize PLL */
|
||||
void si_pmu_pll_init(struct si_pub *sih, uint xtalfreq)
|
||||
{
|
||||
chipcregs_t *cc;
|
||||
uint origidx;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
origidx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
switch (sih->chip) {
|
||||
case BCM4313_CHIP_ID:
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
/* ??? */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
/* initialize PMU resources */
|
||||
void si_pmu_res_init(struct si_pub *sih)
|
||||
{
|
||||
chipcregs_t *cc;
|
||||
uint origidx;
|
||||
u32 min_mask = 0, max_mask = 0;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
origidx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
/* Determine min/max rsrc masks */
|
||||
si_pmu_res_masks(sih, &min_mask, &max_mask);
|
||||
|
||||
/* It is required to program max_mask first and then min_mask */
|
||||
|
||||
/* Program max resource mask */
|
||||
|
||||
if (max_mask)
|
||||
W_REG(&cc->max_res_mask, max_mask);
|
||||
|
||||
/* Program min resource mask */
|
||||
|
||||
if (min_mask)
|
||||
W_REG(&cc->min_res_mask, min_mask);
|
||||
|
||||
/* Add some delay; allow resources to come up and settle. */
|
||||
mdelay(2);
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
u32 si_pmu_measure_alpclk(struct si_pub *sih)
|
||||
{
|
||||
chipcregs_t *cc;
|
||||
uint origidx;
|
||||
u32 alp_khz;
|
||||
|
||||
if (sih->pmurev < 10)
|
||||
return 0;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
origidx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) {
|
||||
u32 ilp_ctr, alp_hz;
|
||||
|
||||
/*
|
||||
* Enable the reg to measure the freq,
|
||||
* in case it was disabled before
|
||||
*/
|
||||
W_REG(&cc->pmu_xtalfreq,
|
||||
1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
|
||||
|
||||
/* Delay for well over 4 ILP clocks */
|
||||
udelay(1000);
|
||||
|
||||
/* Read the latched number of ALP ticks per 4 ILP ticks */
|
||||
ilp_ctr =
|
||||
R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK;
|
||||
|
||||
/*
|
||||
* Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT
|
||||
* bit to save power
|
||||
*/
|
||||
W_REG(&cc->pmu_xtalfreq, 0);
|
||||
|
||||
/* Calculate ALP frequency */
|
||||
alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
|
||||
|
||||
/*
|
||||
* Round to nearest 100KHz, and at
|
||||
* the same time convert to KHz
|
||||
*/
|
||||
alp_khz = (alp_hz + 50000) / 100000 * 100;
|
||||
} else
|
||||
alp_khz = 0;
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
|
||||
return alp_khz;
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _BRCM_PMU_H_
|
||||
#define _BRCM_PMU_H_
|
||||
|
||||
#include "types.h"
|
||||
/*
|
||||
* LDO selections used in si_pmu_set_ldo_voltage
|
||||
*/
|
||||
#define SET_LDO_VOLTAGE_LDO1 1
|
||||
#define SET_LDO_VOLTAGE_LDO2 2
|
||||
#define SET_LDO_VOLTAGE_LDO3 3
|
||||
#define SET_LDO_VOLTAGE_PAREF 4
|
||||
#define SET_LDO_VOLTAGE_CLDO_PWM 5
|
||||
#define SET_LDO_VOLTAGE_CLDO_BURST 6
|
||||
#define SET_LDO_VOLTAGE_CBUCK_PWM 7
|
||||
#define SET_LDO_VOLTAGE_CBUCK_BURST 8
|
||||
#define SET_LDO_VOLTAGE_LNLDO1 9
|
||||
#define SET_LDO_VOLTAGE_LNLDO2_SEL 10
|
||||
|
||||
extern u16 si_pmu_fast_pwrup_delay(struct si_pub *sih);
|
||||
extern void si_pmu_sprom_enable(struct si_pub *sih, bool enable);
|
||||
extern u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
|
||||
extern u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
|
||||
extern u32 si_pmu_ilp_clock(struct si_pub *sih);
|
||||
extern u32 si_pmu_alp_clock(struct si_pub *sih);
|
||||
extern void si_pmu_pllupd(struct si_pub *sih);
|
||||
extern void si_pmu_spuravoid(struct si_pub *sih, u8 spuravoid);
|
||||
extern u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
|
||||
extern void si_pmu_init(struct si_pub *sih);
|
||||
extern void si_pmu_chip_init(struct si_pub *sih);
|
||||
extern void si_pmu_pll_init(struct si_pub *sih, u32 xtalfreq);
|
||||
extern void si_pmu_res_init(struct si_pub *sih);
|
||||
extern void si_pmu_swreg_init(struct si_pub *sih);
|
||||
extern u32 si_pmu_measure_alpclk(struct si_pub *sih);
|
||||
|
||||
#endif /* _BRCM_PMU_H_ */
|
@ -1,665 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_PUB_H_
|
||||
#define _BRCM_PUB_H_
|
||||
|
||||
#include <brcmu_wifi.h>
|
||||
#include "types.h"
|
||||
#include "defs.h"
|
||||
|
||||
#define BRCMS_NUMRATES 16 /* max # of rates in a rateset */
|
||||
#define MAXMULTILIST 32 /* max # multicast addresses */
|
||||
#define D11_PHY_HDR_LEN 6 /* Phy header length - 6 bytes */
|
||||
|
||||
/* phy types */
|
||||
#define PHY_TYPE_A 0 /* Phy type A */
|
||||
#define PHY_TYPE_G 2 /* Phy type G */
|
||||
#define PHY_TYPE_N 4 /* Phy type N */
|
||||
#define PHY_TYPE_LP 5 /* Phy type Low Power A/B/G */
|
||||
#define PHY_TYPE_SSN 6 /* Phy type Single Stream N */
|
||||
#define PHY_TYPE_LCN 8 /* Phy type Single Stream N */
|
||||
#define PHY_TYPE_LCNXN 9 /* Phy type 2-stream N */
|
||||
#define PHY_TYPE_HT 7 /* Phy type 3-Stream N */
|
||||
|
||||
/* bw */
|
||||
#define BRCMS_10_MHZ 10 /* 10Mhz nphy channel bandwidth */
|
||||
#define BRCMS_20_MHZ 20 /* 20Mhz nphy channel bandwidth */
|
||||
#define BRCMS_40_MHZ 40 /* 40Mhz nphy channel bandwidth */
|
||||
|
||||
#define CHSPEC_WLC_BW(chanspec) (CHSPEC_IS40(chanspec) ? BRCMS_40_MHZ : \
|
||||
CHSPEC_IS20(chanspec) ? BRCMS_20_MHZ : \
|
||||
BRCMS_10_MHZ)
|
||||
|
||||
#define BRCMS_RSSI_MINVAL -200 /* Low value, e.g. for forcing roam */
|
||||
#define BRCMS_RSSI_NO_SIGNAL -91 /* NDIS RSSI link quality cutoffs */
|
||||
#define BRCMS_RSSI_VERY_LOW -80 /* Very low quality cutoffs */
|
||||
#define BRCMS_RSSI_LOW -70 /* Low quality cutoffs */
|
||||
#define BRCMS_RSSI_GOOD -68 /* Good quality cutoffs */
|
||||
#define BRCMS_RSSI_VERY_GOOD -58 /* Very good quality cutoffs */
|
||||
#define BRCMS_RSSI_EXCELLENT -57 /* Excellent quality cutoffs */
|
||||
|
||||
/* macro to perform PHY -> D11 PHY TYPE, currently 1:1 */
|
||||
#define BRCMS_PHYTYPE(_x) (_x)
|
||||
|
||||
#define MA_WINDOW_SZ 8 /* moving average window size */
|
||||
|
||||
#define BRCMS_SNR_INVALID 0 /* invalid SNR value */
|
||||
|
||||
/* a large TX Power as an init value to factor out of min() calculations,
|
||||
* keep low enough to fit in an s8, units are .25 dBm
|
||||
*/
|
||||
#define BRCMS_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */
|
||||
|
||||
/* rate related definitions */
|
||||
#define BRCMS_RATE_FLAG 0x80 /* Flag to indicate it is a basic rate */
|
||||
#define BRCMS_RATE_MASK 0x7f /* Rate value mask w/o basic rate flag */
|
||||
|
||||
/* legacy rx Antenna diversity for SISO rates */
|
||||
#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */
|
||||
#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */
|
||||
#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */
|
||||
#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */
|
||||
#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */
|
||||
#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */
|
||||
|
||||
/* legacy rx Antenna diversity for SISO rates */
|
||||
#define ANT_TX_FORCE_0 0 /* Tx on antenna 0, "legacy term Main" */
|
||||
#define ANT_TX_FORCE_1 1 /* Tx on antenna 1, "legacy term Aux" */
|
||||
#define ANT_TX_LAST_RX 3 /* Tx on phy's last good Rx antenna */
|
||||
#define ANT_TX_DEF 3 /* driver's default tx antenna setting */
|
||||
|
||||
#define TXCORE_POLICY_ALL 0x1 /* use all available core for transmit */
|
||||
|
||||
/* Tx Chain values */
|
||||
#define TXCHAIN_DEF 0x1 /* def bitmap of txchain */
|
||||
#define TXCHAIN_DEF_NPHY 0x3 /* default bitmap of tx chains for nphy */
|
||||
#define TXCHAIN_DEF_HTPHY 0x7 /* default bitmap of tx chains for nphy */
|
||||
#define RXCHAIN_DEF 0x1 /* def bitmap of rxchain */
|
||||
#define RXCHAIN_DEF_NPHY 0x3 /* default bitmap of rx chains for nphy */
|
||||
#define RXCHAIN_DEF_HTPHY 0x7 /* default bitmap of rx chains for nphy */
|
||||
#define ANTSWITCH_NONE 0 /* no antenna switch */
|
||||
#define ANTSWITCH_TYPE_1 1 /* antenna switch on 4321CB2, 2of3 */
|
||||
#define ANTSWITCH_TYPE_2 2 /* antenna switch on 4321MPCI, 2of3 */
|
||||
#define ANTSWITCH_TYPE_3 3 /* antenna switch on 4322, 2of3 */
|
||||
|
||||
#define RXBUFSZ PKTBUFSZ
|
||||
#ifndef AIDMAPSZ
|
||||
#define AIDMAPSZ (roundup(MAXSCB, NBBY)/NBBY) /* aid bitmap size in bytes */
|
||||
#endif /* AIDMAPSZ */
|
||||
|
||||
#define MAX_STREAMS_SUPPORTED 4 /* max number of streams supported */
|
||||
|
||||
#define WL_SPURAVOID_OFF 0
|
||||
#define WL_SPURAVOID_ON1 1
|
||||
#define WL_SPURAVOID_ON2 2
|
||||
|
||||
struct brcms_tunables {
|
||||
int ntxd; /* size of tx descriptor table */
|
||||
int nrxd; /* size of rx descriptor table */
|
||||
int rxbufsz; /* size of rx buffers to post */
|
||||
int nrxbufpost; /* # of rx buffers to post */
|
||||
int maxscb; /* # of SCBs supported */
|
||||
int ampdunummpdu; /* max number of mpdu in an ampdu */
|
||||
int maxpktcb; /* max # of packet callbacks */
|
||||
int maxucodebss; /* max # of BSS handled in ucode bcn/prb */
|
||||
int maxucodebss4; /* max # of BSS handled in sw bcn/prb */
|
||||
int maxbss; /* max # of bss info elements in scan list */
|
||||
int datahiwat; /* data msg txq hiwat mark */
|
||||
int ampdudatahiwat; /* AMPDU msg txq hiwat mark */
|
||||
int rxbnd; /* max # of rx bufs to process before deferring to dpc */
|
||||
int txsbnd; /* max # tx status to process in wlc_txstatus() */
|
||||
int memreserved; /* memory reserved for BMAC's USB dma rx */
|
||||
};
|
||||
|
||||
struct brcms_rateset {
|
||||
uint count; /* number of rates in rates[] */
|
||||
/* rates in 500kbps units w/hi bit set if basic */
|
||||
u8 rates[BRCMS_NUMRATES];
|
||||
u8 htphy_membership; /* HT PHY Membership */
|
||||
u8 mcs[MCSSET_LEN]; /* supported mcs index bit map */
|
||||
};
|
||||
|
||||
struct rsn_parms {
|
||||
u8 flags; /* misc booleans (e.g., supported) */
|
||||
u8 multicast; /* multicast cipher */
|
||||
u8 ucount; /* count of unicast ciphers */
|
||||
u8 unicast[4]; /* unicast ciphers */
|
||||
u8 acount; /* count of auth modes */
|
||||
u8 auth[4]; /* Authentication modes */
|
||||
u8 PAD[4]; /* padding for future growth */
|
||||
};
|
||||
|
||||
/*
|
||||
* 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL.
|
||||
*/
|
||||
#define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1)
|
||||
|
||||
#define RSN_FLAGS_SUPPORTED 0x1 /* Flag for rsn_params */
|
||||
#define RSN_FLAGS_PREAUTH 0x2 /* Flag for WPA2 rsn_params */
|
||||
|
||||
/* All the HT-specific default advertised capabilities (including AMPDU)
|
||||
* should be grouped here at one place
|
||||
*/
|
||||
#define AMPDU_DEF_MPDU_DENSITY 6 /* default mpdu density (110 ==> 4us) */
|
||||
|
||||
/* defaults for the HT (MIMO) bss */
|
||||
#define HT_CAP (IEEE80211_HT_CAP_SM_PS |\
|
||||
IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_GRN_FLD |\
|
||||
IEEE80211_HT_CAP_MAX_AMSDU | IEEE80211_HT_CAP_DSSSCCK40)
|
||||
|
||||
/* wlc internal bss_info */
|
||||
struct brcms_bss_info {
|
||||
u8 BSSID[ETH_ALEN]; /* network BSSID */
|
||||
u16 flags; /* flags for internal attributes */
|
||||
u8 SSID_len; /* the length of SSID */
|
||||
u8 SSID[32]; /* SSID string */
|
||||
s16 RSSI; /* receive signal strength (in dBm) */
|
||||
s16 SNR; /* receive signal SNR in dB */
|
||||
u16 beacon_period; /* units are Kusec */
|
||||
u16 atim_window; /* units are Kusec */
|
||||
chanspec_t chanspec; /* Channel num, bw, ctrl_sb and band */
|
||||
s8 infra; /* 0=IBSS, 1=infrastructure, 2=unknown */
|
||||
wlc_rateset_t rateset; /* supported rates */
|
||||
u8 dtim_period; /* DTIM period */
|
||||
s8 phy_noise; /* noise right after tx (in dBm) */
|
||||
u16 capability; /* Capability information */
|
||||
u8 wme_qosinfo; /* QoS Info from WME IE; valid if BSS_WME flag set */
|
||||
struct rsn_parms wpa;
|
||||
struct rsn_parms wpa2;
|
||||
u16 qbss_load_aac; /* qbss load available admission capacity */
|
||||
/* qbss_load_chan_free <- (0xff - channel_utilization of qbss_load_ie_t) */
|
||||
u8 qbss_load_chan_free; /* indicates how free the channel is */
|
||||
u8 mcipher; /* multicast cipher */
|
||||
u8 wpacfg; /* wpa config index */
|
||||
};
|
||||
|
||||
/* IOVar flags for common error checks */
|
||||
#define IOVF_MFG (1<<3) /* flag for mfgtest iovars */
|
||||
#define IOVF_WHL (1<<4) /* value must be whole (0-max) */
|
||||
#define IOVF_NTRL (1<<5) /* value must be natural (1-max) */
|
||||
|
||||
#define IOVF_SET_UP (1<<6) /* set requires driver be up */
|
||||
#define IOVF_SET_DOWN (1<<7) /* set requires driver be down */
|
||||
#define IOVF_SET_CLK (1<<8) /* set requires core clock */
|
||||
#define IOVF_SET_BAND (1<<9) /* set requires fixed band */
|
||||
|
||||
#define IOVF_GET_UP (1<<10) /* get requires driver be up */
|
||||
#define IOVF_GET_DOWN (1<<11) /* get requires driver be down */
|
||||
#define IOVF_GET_CLK (1<<12) /* get requires core clock */
|
||||
#define IOVF_GET_BAND (1<<13) /* get requires fixed band */
|
||||
#define IOVF_OPEN_ALLOW (1<<14) /* set allowed iovar for opensrc */
|
||||
|
||||
/* watchdog down and dump callback function proto's */
|
||||
typedef int (*watchdog_fn_t) (void *handle);
|
||||
typedef int (*down_fn_t) (void *handle);
|
||||
typedef int (*dump_fn_t) (void *handle, struct brcmu_strbuf *b);
|
||||
|
||||
/* IOVar handler
|
||||
*
|
||||
* handle - a pointer value registered with the function
|
||||
* vi - iovar_info that was looked up
|
||||
* actionid - action ID, calculated by IOV_GVAL() and IOV_SVAL() based on varid.
|
||||
* name - the actual iovar name
|
||||
* params/plen - parameters and length for a get, input only.
|
||||
* arg/len - buffer and length for value to be set or retrieved, input or output.
|
||||
* vsize - value size, valid for integer type only.
|
||||
* wlcif - interface context (brcms_c_if pointer)
|
||||
*
|
||||
* All pointers may point into the same buffer.
|
||||
*/
|
||||
typedef int (*iovar_fn_t) (void *handle, const struct brcmu_iovar *vi,
|
||||
u32 actionid, const char *name, void *params,
|
||||
uint plen, void *arg, int alen, int vsize,
|
||||
struct brcms_c_if *wlcif);
|
||||
|
||||
#define MAC80211_PROMISC_BCNS (1 << 0)
|
||||
#define MAC80211_SCAN (1 << 1)
|
||||
|
||||
/*
|
||||
* Public portion of "common" os-independent state structure.
|
||||
* The wlc handle points at this.
|
||||
*/
|
||||
struct brcms_pub {
|
||||
void *wlc;
|
||||
|
||||
struct ieee80211_hw *ieee_hw;
|
||||
struct scb *global_scb;
|
||||
struct scb_ampdu *global_ampdu;
|
||||
uint mac80211_state;
|
||||
uint unit; /* device instance number */
|
||||
uint corerev; /* core revision */
|
||||
struct si_pub *sih; /* SI handle (cookie for siutils calls) */
|
||||
char *vars; /* "environment" name=value */
|
||||
bool up; /* interface up and running */
|
||||
bool hw_off; /* HW is off */
|
||||
/* tunables: ntxd, nrxd, maxscb, etc. */
|
||||
struct brcms_tunables *tunables;
|
||||
bool hw_up; /* one time hw up/down(from boot or hibernation) */
|
||||
bool _piomode; /* true if pio mode *//* BMAC_NOTE: NEED In both */
|
||||
uint _nbands; /* # bands supported */
|
||||
uint now; /* # elapsed seconds */
|
||||
|
||||
bool promisc; /* promiscuous destination address */
|
||||
bool delayed_down; /* down delayed */
|
||||
bool _ap; /* AP mode enabled */
|
||||
bool _apsta; /* simultaneous AP/STA mode enabled */
|
||||
bool _assoc_recreate; /* association recreation on up transitions */
|
||||
int _wme; /* WME QoS mode */
|
||||
u8 _mbss; /* MBSS mode on */
|
||||
bool allmulti; /* enable all multicasts */
|
||||
bool associated; /* true:part of [I]BSS, false: not */
|
||||
/* (union of stas_associated, aps_associated) */
|
||||
bool phytest_on; /* whether a PHY test is running */
|
||||
bool bf_preempt_4306; /* True to enable 'darwin' mode */
|
||||
bool _ampdu; /* ampdu enabled or not */
|
||||
bool _cac; /* 802.11e CAC enabled */
|
||||
u8 _n_enab; /* bitmap of 11N + HT support */
|
||||
bool _n_reqd; /* N support required for clients */
|
||||
|
||||
s8 _coex; /* 20/40 MHz BSS Management AUTO, ENAB, DISABLE */
|
||||
bool _priofc; /* Priority-based flowcontrol */
|
||||
|
||||
u8 cur_etheraddr[ETH_ALEN]; /* our local ethernet address */
|
||||
|
||||
u8 *multicast; /* ptr to list of multicast addresses */
|
||||
uint nmulticast; /* # enabled multicast addresses */
|
||||
|
||||
u32 wlfeatureflag; /* Flags to control sw features from registry */
|
||||
int psq_pkts_total; /* total num of ps pkts */
|
||||
|
||||
u16 txmaxpkts; /* max number of large pkts allowed to be pending */
|
||||
|
||||
/* s/w decryption counters */
|
||||
u32 swdecrypt; /* s/w decrypt attempts */
|
||||
|
||||
int bcmerror; /* last bcm error */
|
||||
|
||||
mbool radio_disabled; /* bit vector for radio disabled reasons */
|
||||
bool radio_active; /* radio on/off state */
|
||||
u16 roam_time_thresh; /* Max. # secs. of not hearing beacons
|
||||
* before roaming.
|
||||
*/
|
||||
bool align_wd_tbtt; /* Align watchdog with tbtt indication
|
||||
* handling. This flag is cleared by default
|
||||
* and is set by per port code explicitly and
|
||||
* you need to make sure the OSL_SYSUPTIME()
|
||||
* is implemented properly in osl of that port
|
||||
* when it enables this Power Save feature.
|
||||
*/
|
||||
|
||||
u16 boardrev; /* version # of particular board */
|
||||
u8 sromrev; /* version # of the srom */
|
||||
char srom_ccode[BRCM_CNTRY_BUF_SZ]; /* Country Code in SROM */
|
||||
u32 boardflags; /* Board specific flags from srom */
|
||||
u32 boardflags2; /* More board flags if sromrev >= 4 */
|
||||
bool tempsense_disable; /* disable periodic tempsense check */
|
||||
bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */
|
||||
bool _ampdumac; /* mac assist ampdu enabled or not */
|
||||
|
||||
struct wl_cnt *_cnt; /* low-level counters in driver */
|
||||
};
|
||||
|
||||
/* wl_monitor rx status per packet */
|
||||
struct wl_rxsts {
|
||||
uint pkterror; /* error flags per pkt */
|
||||
uint phytype; /* 802.11 A/B/G ... */
|
||||
uint channel; /* channel */
|
||||
uint datarate; /* rate in 500kbps */
|
||||
uint antenna; /* antenna pkts received on */
|
||||
uint pktlength; /* pkt length minus bcm phy hdr */
|
||||
u32 mactime; /* time stamp from mac, count per 1us */
|
||||
uint sq; /* signal quality */
|
||||
s32 signal; /* in dbm */
|
||||
s32 noise; /* in dbm */
|
||||
uint preamble; /* Unknown, short, long */
|
||||
uint encoding; /* Unknown, CCK, PBCC, OFDM */
|
||||
uint nfrmtype; /* special 802.11n frames(AMPDU, AMSDU) */
|
||||
struct brcms_if *wlif; /* wl interface */
|
||||
};
|
||||
|
||||
/* status per error RX pkt */
|
||||
#define WL_RXS_CRC_ERROR 0x00000001 /* CRC Error in packet */
|
||||
#define WL_RXS_RUNT_ERROR 0x00000002 /* Runt packet */
|
||||
#define WL_RXS_ALIGN_ERROR 0x00000004 /* Misaligned packet */
|
||||
#define WL_RXS_OVERSIZE_ERROR 0x00000008 /* packet bigger than RX_LENGTH (usually 1518) */
|
||||
#define WL_RXS_WEP_ICV_ERROR 0x00000010 /* Integrity Check Value error */
|
||||
#define WL_RXS_WEP_ENCRYPTED 0x00000020 /* Encrypted with WEP */
|
||||
#define WL_RXS_PLCP_SHORT 0x00000040 /* Short PLCP error */
|
||||
#define WL_RXS_DECRYPT_ERR 0x00000080 /* Decryption error */
|
||||
#define WL_RXS_OTHER_ERR 0x80000000 /* Other errors */
|
||||
|
||||
/* phy type */
|
||||
#define WL_RXS_PHY_A 0x00000000 /* A phy type */
|
||||
#define WL_RXS_PHY_B 0x00000001 /* B phy type */
|
||||
#define WL_RXS_PHY_G 0x00000002 /* G phy type */
|
||||
#define WL_RXS_PHY_N 0x00000004 /* N phy type */
|
||||
|
||||
/* encoding */
|
||||
#define WL_RXS_ENCODING_CCK 0x00000000 /* CCK encoding */
|
||||
#define WL_RXS_ENCODING_OFDM 0x00000001 /* OFDM encoding */
|
||||
|
||||
/* preamble */
|
||||
#define WL_RXS_UNUSED_STUB 0x0 /* stub to match with wlc_ethereal.h */
|
||||
#define WL_RXS_PREAMBLE_SHORT 0x00000001 /* Short preamble */
|
||||
#define WL_RXS_PREAMBLE_LONG 0x00000002 /* Long preamble */
|
||||
#define WL_RXS_PREAMBLE_MIMO_MM 0x00000003 /* MIMO mixed mode preamble */
|
||||
#define WL_RXS_PREAMBLE_MIMO_GF 0x00000004 /* MIMO green field preamble */
|
||||
|
||||
#define WL_RXS_NFRM_AMPDU_FIRST 0x00000001 /* first MPDU in A-MPDU */
|
||||
#define WL_RXS_NFRM_AMPDU_SUB 0x00000002 /* subsequent MPDU(s) in A-MPDU */
|
||||
#define WL_RXS_NFRM_AMSDU_FIRST 0x00000004 /* first MSDU in A-MSDU */
|
||||
#define WL_RXS_NFRM_AMSDU_SUB 0x00000008 /* subsequent MSDU(s) in A-MSDU */
|
||||
|
||||
enum wlc_par_id {
|
||||
IOV_MPC = 1,
|
||||
IOV_RTSTHRESH,
|
||||
IOV_QTXPOWER,
|
||||
IOV_BCN_LI_BCN /* Beacon listen interval in # of beacons */
|
||||
};
|
||||
|
||||
/***********************************************
|
||||
* Feature-related macros to optimize out code *
|
||||
* *********************************************
|
||||
*/
|
||||
|
||||
/* AP Support (versus STA) */
|
||||
#define AP_ENAB(pub) (0)
|
||||
|
||||
/* Macro to check if APSTA mode enabled */
|
||||
#define APSTA_ENAB(pub) (0)
|
||||
|
||||
/* Some useful combinations */
|
||||
#define STA_ONLY(pub) (!AP_ENAB(pub))
|
||||
#define AP_ONLY(pub) (AP_ENAB(pub) && !APSTA_ENAB(pub))
|
||||
|
||||
#define ENAB_1x1 0x01
|
||||
#define ENAB_2x2 0x02
|
||||
#define ENAB_3x3 0x04
|
||||
#define ENAB_4x4 0x08
|
||||
#define SUPPORT_11N (ENAB_1x1|ENAB_2x2)
|
||||
#define SUPPORT_HT (ENAB_1x1|ENAB_2x2|ENAB_3x3)
|
||||
/* WL11N Support */
|
||||
#if ((defined(NCONF) && (NCONF != 0)) || (defined(LCNCONF) && (LCNCONF != 0)) || \
|
||||
(defined(HTCONF) && (HTCONF != 0)) || (defined(SSLPNCONF) && (SSLPNCONF != 0)))
|
||||
#define N_ENAB(pub) ((pub)->_n_enab & SUPPORT_11N)
|
||||
#define N_REQD(pub) ((pub)->_n_reqd)
|
||||
#else
|
||||
#define N_ENAB(pub) 0
|
||||
#define N_REQD(pub) 0
|
||||
#endif
|
||||
|
||||
#if (defined(HTCONF) && (HTCONF != 0))
|
||||
#define HT_ENAB(pub) (((pub)->_n_enab & SUPPORT_HT) == SUPPORT_HT)
|
||||
#else
|
||||
#define HT_ENAB(pub) 0
|
||||
#endif
|
||||
|
||||
#define AMPDU_AGG_HOST 1
|
||||
#define AMPDU_ENAB(pub) ((pub)->_ampdu)
|
||||
|
||||
#define EDCF_ENAB(pub) (WME_ENAB(pub))
|
||||
#define QOS_ENAB(pub) (WME_ENAB(pub) || N_ENAB(pub))
|
||||
|
||||
#define MONITOR_ENAB(wlc) ((wlc)->monitor)
|
||||
|
||||
#define PROMISC_ENAB(wlc) ((wlc)->promisc)
|
||||
|
||||
#define BRCMS_PREC_COUNT 16 /* Max precedence level implemented */
|
||||
|
||||
/* pri is priority encoded in the packet. This maps the Packet priority to
|
||||
* enqueue precedence as defined in wlc_prec_map
|
||||
*/
|
||||
extern const u8 wlc_prio2prec_map[];
|
||||
#define BRCMS_PRIO_TO_PREC(pri) wlc_prio2prec_map[(pri) & 7]
|
||||
|
||||
/* This maps priority to one precedence higher - Used by PS-Poll response packets to
|
||||
* simulate enqueue-at-head operation, but still maintain the order on the queue
|
||||
*/
|
||||
#define BRCMS_PRIO_TO_HI_PREC(pri) min(BRCMS_PRIO_TO_PREC(pri) + 1,\
|
||||
BRCMS_PREC_COUNT - 1)
|
||||
|
||||
extern const u8 wme_fifo2ac[];
|
||||
#define WME_PRIO2AC(prio) wme_fifo2ac[prio2fifo[(prio)]]
|
||||
|
||||
/* Mask to describe all precedence levels */
|
||||
#define BRCMS_PREC_BMP_ALL MAXBITVAL(BRCMS_PREC_COUNT)
|
||||
|
||||
/* Define a bitmap of precedences comprised by each AC */
|
||||
#define BRCMS_PREC_BMP_AC_BE (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BE)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BE)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_EE)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_EE)))
|
||||
#define BRCMS_PREC_BMP_AC_BK (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BK)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BK)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NONE)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NONE)))
|
||||
#define BRCMS_PREC_BMP_AC_VI (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_CL)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_CL)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VI)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VI)))
|
||||
#define BRCMS_PREC_BMP_AC_VO (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VO)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VO)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NC)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NC)))
|
||||
|
||||
/* WME Support */
|
||||
#define WME_ENAB(pub) ((pub)->_wme != OFF)
|
||||
#define WME_AUTO(wlc) ((wlc)->pub->_wme == AUTO)
|
||||
|
||||
/* invalid core flags, use the saved coreflags */
|
||||
#define BRCMS_USE_COREFLAGS 0xffffffff
|
||||
|
||||
|
||||
/* network protection config */
|
||||
#define BRCMS_PROT_G_SPEC 1 /* SPEC g protection */
|
||||
#define BRCMS_PROT_G_OVR 2 /* SPEC g prot override */
|
||||
#define BRCMS_PROT_G_USER 3 /* gmode specified by user */
|
||||
#define BRCMS_PROT_OVERLAP 4 /* overlap */
|
||||
#define BRCMS_PROT_N_USER 10 /* nmode specified by user */
|
||||
#define BRCMS_PROT_N_CFG 11 /* n protection */
|
||||
#define BRCMS_PROT_N_CFG_OVR 12 /* n protection override */
|
||||
#define BRCMS_PROT_N_NONGF 13 /* non-GF protection */
|
||||
#define BRCMS_PROT_N_NONGF_OVR 14 /* non-GF protection override */
|
||||
#define BRCMS_PROT_N_PAM_OVR 15 /* n preamble override */
|
||||
#define BRCMS_PROT_N_OBSS 16 /* non-HT OBSS present */
|
||||
|
||||
/*
|
||||
* 54g modes (basic bits may still be overridden)
|
||||
*
|
||||
* GMODE_LEGACY_B Rateset: 1b, 2b, 5.5, 11
|
||||
* Preamble: Long
|
||||
* Shortslot: Off
|
||||
* GMODE_AUTO Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
|
||||
* Extended Rateset: 6, 9, 12, 48
|
||||
* Preamble: Long
|
||||
* Shortslot: Auto
|
||||
* GMODE_ONLY Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54
|
||||
* Extended Rateset: 6b, 9, 12b, 48
|
||||
* Preamble: Short required
|
||||
* Shortslot: Auto
|
||||
* GMODE_B_DEFERRED Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
|
||||
* Extended Rateset: 6, 9, 12, 48
|
||||
* Preamble: Long
|
||||
* Shortslot: On
|
||||
* GMODE_PERFORMANCE Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54
|
||||
* Preamble: Short required
|
||||
* Shortslot: On and required
|
||||
* GMODE_LRS Rateset: 1b, 2b, 5.5b, 11b
|
||||
* Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54
|
||||
* Preamble: Long
|
||||
* Shortslot: Auto
|
||||
*/
|
||||
#define GMODE_LEGACY_B 0
|
||||
#define GMODE_AUTO 1
|
||||
#define GMODE_ONLY 2
|
||||
#define GMODE_B_DEFERRED 3
|
||||
#define GMODE_PERFORMANCE 4
|
||||
#define GMODE_LRS 5
|
||||
#define GMODE_MAX 6
|
||||
|
||||
/* values for PLCPHdr_override */
|
||||
#define BRCMS_PLCP_AUTO -1
|
||||
#define BRCMS_PLCP_SHORT 0
|
||||
#define BRCMS_PLCP_LONG 1
|
||||
|
||||
/* values for g_protection_override and n_protection_override */
|
||||
#define BRCMS_PROTECTION_AUTO -1
|
||||
#define BRCMS_PROTECTION_OFF 0
|
||||
#define BRCMS_PROTECTION_ON 1
|
||||
#define BRCMS_PROTECTION_MMHDR_ONLY 2
|
||||
#define BRCMS_PROTECTION_CTS_ONLY 3
|
||||
|
||||
/* values for g_protection_control and n_protection_control */
|
||||
#define BRCMS_PROTECTION_CTL_OFF 0
|
||||
#define BRCMS_PROTECTION_CTL_LOCAL 1
|
||||
#define BRCMS_PROTECTION_CTL_OVERLAP 2
|
||||
|
||||
/* values for n_protection */
|
||||
#define BRCMS_N_PROTECTION_OFF 0
|
||||
#define BRCMS_N_PROTECTION_OPTIONAL 1
|
||||
#define BRCMS_N_PROTECTION_20IN40 2
|
||||
#define BRCMS_N_PROTECTION_MIXEDMODE 3
|
||||
|
||||
/* values for band specific 40MHz capabilities */
|
||||
#define BRCMS_N_BW_20ALL 0
|
||||
#define BRCMS_N_BW_40ALL 1
|
||||
#define BRCMS_N_BW_20IN2G_40IN5G 2
|
||||
|
||||
/* bitflags for SGI support (sgi_rx iovar) */
|
||||
#define BRCMS_N_SGI_20 0x01
|
||||
#define BRCMS_N_SGI_40 0x02
|
||||
|
||||
/* defines used by the nrate iovar */
|
||||
#define NRATE_MCS_INUSE 0x00000080 /* MSC in use,indicates b0-6 holds an mcs */
|
||||
#define NRATE_RATE_MASK 0x0000007f /* rate/mcs value */
|
||||
#define NRATE_STF_MASK 0x0000ff00 /* stf mode mask: siso, cdd, stbc, sdm */
|
||||
#define NRATE_STF_SHIFT 8 /* stf mode shift */
|
||||
#define NRATE_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */
|
||||
#define NRATE_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicate to override mcs only */
|
||||
#define NRATE_SGI_MASK 0x00800000 /* sgi mode */
|
||||
#define NRATE_SGI_SHIFT 23 /* sgi mode */
|
||||
#define NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */
|
||||
#define NRATE_LDPC_SHIFT 22 /* ldpc shift */
|
||||
|
||||
#define NRATE_STF_SISO 0 /* stf mode SISO */
|
||||
#define NRATE_STF_CDD 1 /* stf mode CDD */
|
||||
#define NRATE_STF_STBC 2 /* stf mode STBC */
|
||||
#define NRATE_STF_SDM 3 /* stf mode SDM */
|
||||
|
||||
#define ANT_SELCFG_MAX 4 /* max number of antenna configurations */
|
||||
|
||||
#define HIGHEST_SINGLE_STREAM_MCS 7 /* MCS values greater than this enable multiple streams */
|
||||
|
||||
struct brcms_antselcfg {
|
||||
u8 ant_config[ANT_SELCFG_MAX]; /* antenna configuration */
|
||||
u8 num_antcfg; /* number of available antenna configurations */
|
||||
};
|
||||
|
||||
/* common functions for every port */
|
||||
extern void *brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device,
|
||||
uint unit, bool piomode, void *regsva, uint bustype,
|
||||
void *btparam, uint *perr);
|
||||
extern uint brcms_c_detach(struct brcms_c_info *wlc);
|
||||
extern int brcms_c_up(struct brcms_c_info *wlc);
|
||||
extern uint brcms_c_down(struct brcms_c_info *wlc);
|
||||
|
||||
extern int brcms_c_set(struct brcms_c_info *wlc, int cmd, int arg);
|
||||
extern int brcms_c_get(struct brcms_c_info *wlc, int cmd, int *arg);
|
||||
extern bool brcms_c_chipmatch(u16 vendor, u16 device);
|
||||
extern void brcms_c_init(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_reset(struct brcms_c_info *wlc);
|
||||
|
||||
extern void brcms_c_intrson(struct brcms_c_info *wlc);
|
||||
extern u32 brcms_c_intrsoff(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask);
|
||||
extern bool brcms_c_intrsupd(struct brcms_c_info *wlc);
|
||||
extern bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc);
|
||||
extern bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded);
|
||||
extern bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc,
|
||||
struct sk_buff *sdu,
|
||||
struct ieee80211_hw *hw);
|
||||
extern int brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len,
|
||||
struct brcms_c_if *wlcif);
|
||||
extern bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid);
|
||||
|
||||
/* helper functions */
|
||||
extern void brcms_c_statsupd(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx,
|
||||
int val);
|
||||
extern int brcms_c_get_header_len(void);
|
||||
extern void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc,
|
||||
bool promisc);
|
||||
extern void brcms_c_set_addrmatch(struct brcms_c_info *wlc,
|
||||
int match_reg_offset,
|
||||
const u8 *addr);
|
||||
extern void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
|
||||
const struct ieee80211_tx_queue_params *arg,
|
||||
bool suspend);
|
||||
extern struct brcms_pub *brcms_c_pub(void *wlc);
|
||||
|
||||
/* common functions for every port */
|
||||
extern void brcms_c_mhf(struct brcms_c_info *wlc, u8 idx, u16 mask, u16 val,
|
||||
int bands);
|
||||
extern void brcms_c_rate_lookup_init(struct brcms_c_info *wlc,
|
||||
wlc_rateset_t *rateset);
|
||||
extern void brcms_default_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs);
|
||||
|
||||
extern void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
|
||||
struct ieee80211_sta *sta, u16 tid);
|
||||
extern void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
|
||||
u8 ba_wsize, uint max_rx_ampdu_bytes);
|
||||
extern int brcms_c_set_par(struct brcms_c_info *wlc, enum wlc_par_id par_id,
|
||||
int val);
|
||||
extern int brcms_c_get_par(struct brcms_c_info *wlc, enum wlc_par_id par_id,
|
||||
int *ret_int_ptr);
|
||||
extern char *getvar(char *vars, const char *name);
|
||||
extern int getintvar(char *vars, const char *name);
|
||||
|
||||
/* wlc_phy.c helper functions */
|
||||
extern void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_mctrl(struct brcms_c_info *wlc, u32 mask, u32 val);
|
||||
|
||||
extern int brcms_c_module_register(struct brcms_pub *pub,
|
||||
const char *name, void *hdl,
|
||||
watchdog_fn_t watchdog_fn, down_fn_t down_fn);
|
||||
extern int brcms_c_module_unregister(struct brcms_pub *pub, const char *name,
|
||||
void *hdl);
|
||||
extern void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_enable_mac(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state);
|
||||
extern void brcms_c_scan_start(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_scan_stop(struct brcms_c_info *wlc);
|
||||
extern int brcms_c_get_curband(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc,
|
||||
bool drop);
|
||||
|
||||
/* helper functions */
|
||||
extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
|
||||
extern bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc);
|
||||
|
||||
#define MAXBANDS 2 /* Maximum #of bands */
|
||||
/* bandstate array indices */
|
||||
#define BAND_2G_INDEX 0 /* wlc->bandstate[x] index */
|
||||
#define BAND_5G_INDEX 1 /* wlc->bandstate[x] index */
|
||||
|
||||
#define BAND_2G_NAME "2.4G"
|
||||
#define BAND_5G_NAME "5G"
|
||||
|
||||
/* BMAC RPC: 7 u32 params: pkttotlen, fifo, commit, fid, txpktpend, pktflag, rpc_id */
|
||||
#define BRCMS_RPCTX_PARAMS 32
|
||||
|
||||
#endif /* _BRCM_PUB_H_ */
|
@ -1,498 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <brcmu_wifi.h>
|
||||
#include <brcmu_utils.h>
|
||||
|
||||
#include "d11.h"
|
||||
#include "pub.h"
|
||||
#include "rate.h"
|
||||
|
||||
/* Rate info per rate: It tells whether a rate is ofdm or not and its phy_rate value */
|
||||
const u8 rate_info[BRCM_MAXRATE + 1] = {
|
||||
/* 0 1 2 3 4 5 6 7 8 9 */
|
||||
/* 0 */ 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 10 */ 0x00, 0x37, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00,
|
||||
/* 20 */ 0x00, 0x00, 0x6e, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00,
|
||||
/* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00,
|
||||
/* 50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 70 */ 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
|
||||
/* 100 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c
|
||||
};
|
||||
|
||||
/* rates are in units of Kbps */
|
||||
const struct brcms_mcs_info mcs_table[MCS_TABLE_SIZE] = {
|
||||
/* MCS 0: SS 1, MOD: BPSK, CR 1/2 */
|
||||
{6500, 13500, CEIL(6500 * 10, 9), CEIL(13500 * 10, 9), 0x00,
|
||||
BRCM_RATE_6M},
|
||||
/* MCS 1: SS 1, MOD: QPSK, CR 1/2 */
|
||||
{13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x08,
|
||||
BRCM_RATE_12M},
|
||||
/* MCS 2: SS 1, MOD: QPSK, CR 3/4 */
|
||||
{19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x0A,
|
||||
BRCM_RATE_18M},
|
||||
/* MCS 3: SS 1, MOD: 16QAM, CR 1/2 */
|
||||
{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x10,
|
||||
BRCM_RATE_24M},
|
||||
/* MCS 4: SS 1, MOD: 16QAM, CR 3/4 */
|
||||
{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x12,
|
||||
BRCM_RATE_36M},
|
||||
/* MCS 5: SS 1, MOD: 64QAM, CR 2/3 */
|
||||
{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x19,
|
||||
BRCM_RATE_48M},
|
||||
/* MCS 6: SS 1, MOD: 64QAM, CR 3/4 */
|
||||
{58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x1A,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 7: SS 1, MOD: 64QAM, CR 5/6 */
|
||||
{65000, 135000, CEIL(65000 * 10, 9), CEIL(135000 * 10, 9), 0x1C,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 8: SS 2, MOD: BPSK, CR 1/2 */
|
||||
{13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x40,
|
||||
BRCM_RATE_6M},
|
||||
/* MCS 9: SS 2, MOD: QPSK, CR 1/2 */
|
||||
{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x48,
|
||||
BRCM_RATE_12M},
|
||||
/* MCS 10: SS 2, MOD: QPSK, CR 3/4 */
|
||||
{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x4A,
|
||||
BRCM_RATE_18M},
|
||||
/* MCS 11: SS 2, MOD: 16QAM, CR 1/2 */
|
||||
{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x50,
|
||||
BRCM_RATE_24M},
|
||||
/* MCS 12: SS 2, MOD: 16QAM, CR 3/4 */
|
||||
{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x52,
|
||||
BRCM_RATE_36M},
|
||||
/* MCS 13: SS 2, MOD: 64QAM, CR 2/3 */
|
||||
{104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0x59,
|
||||
BRCM_RATE_48M},
|
||||
/* MCS 14: SS 2, MOD: 64QAM, CR 3/4 */
|
||||
{117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x5A,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 15: SS 2, MOD: 64QAM, CR 5/6 */
|
||||
{130000, 270000, CEIL(130000 * 10, 9), CEIL(270000 * 10, 9), 0x5C,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 16: SS 3, MOD: BPSK, CR 1/2 */
|
||||
{19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x80,
|
||||
BRCM_RATE_6M},
|
||||
/* MCS 17: SS 3, MOD: QPSK, CR 1/2 */
|
||||
{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x88,
|
||||
BRCM_RATE_12M},
|
||||
/* MCS 18: SS 3, MOD: QPSK, CR 3/4 */
|
||||
{58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x8A,
|
||||
BRCM_RATE_18M},
|
||||
/* MCS 19: SS 3, MOD: 16QAM, CR 1/2 */
|
||||
{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x90,
|
||||
BRCM_RATE_24M},
|
||||
/* MCS 20: SS 3, MOD: 16QAM, CR 3/4 */
|
||||
{117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x92,
|
||||
BRCM_RATE_36M},
|
||||
/* MCS 21: SS 3, MOD: 64QAM, CR 2/3 */
|
||||
{156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0x99,
|
||||
BRCM_RATE_48M},
|
||||
/* MCS 22: SS 3, MOD: 64QAM, CR 3/4 */
|
||||
{175500, 364500, CEIL(175500 * 10, 9), CEIL(364500 * 10, 9), 0x9A,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 23: SS 3, MOD: 64QAM, CR 5/6 */
|
||||
{195000, 405000, CEIL(195000 * 10, 9), CEIL(405000 * 10, 9), 0x9B,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 24: SS 4, MOD: BPSK, CR 1/2 */
|
||||
{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0xC0,
|
||||
BRCM_RATE_6M},
|
||||
/* MCS 25: SS 4, MOD: QPSK, CR 1/2 */
|
||||
{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0xC8,
|
||||
BRCM_RATE_12M},
|
||||
/* MCS 26: SS 4, MOD: QPSK, CR 3/4 */
|
||||
{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0xCA,
|
||||
BRCM_RATE_18M},
|
||||
/* MCS 27: SS 4, MOD: 16QAM, CR 1/2 */
|
||||
{104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0xD0,
|
||||
BRCM_RATE_24M},
|
||||
/* MCS 28: SS 4, MOD: 16QAM, CR 3/4 */
|
||||
{156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0xD2,
|
||||
BRCM_RATE_36M},
|
||||
/* MCS 29: SS 4, MOD: 64QAM, CR 2/3 */
|
||||
{208000, 432000, CEIL(208000 * 10, 9), CEIL(432000 * 10, 9), 0xD9,
|
||||
BRCM_RATE_48M},
|
||||
/* MCS 30: SS 4, MOD: 64QAM, CR 3/4 */
|
||||
{234000, 486000, CEIL(234000 * 10, 9), CEIL(486000 * 10, 9), 0xDA,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 31: SS 4, MOD: 64QAM, CR 5/6 */
|
||||
{260000, 540000, CEIL(260000 * 10, 9), CEIL(540000 * 10, 9), 0xDB,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 32: SS 1, MOD: BPSK, CR 1/2 */
|
||||
{0, 6000, 0, CEIL(6000 * 10, 9), 0x00, BRCM_RATE_6M},
|
||||
};
|
||||
|
||||
/* phycfg for legacy OFDM frames: code rate, modulation scheme, spatial streams
|
||||
* Number of spatial streams: always 1
|
||||
* other fields: refer to table 78 of section 17.3.2.2 of the original .11a standard
|
||||
*/
|
||||
struct legacy_phycfg {
|
||||
u32 rate_ofdm; /* ofdm mac rate */
|
||||
u8 tx_phy_ctl3; /* phy ctl byte 3, code rate, modulation type, # of streams */
|
||||
};
|
||||
|
||||
#define LEGACY_PHYCFG_TABLE_SIZE 12 /* Number of legacy_rate_cfg entries in the table */
|
||||
|
||||
/* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */
|
||||
/* Eventually MIMOPHY would also be converted to this format */
|
||||
/* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */
|
||||
static const struct
|
||||
legacy_phycfg legacy_phycfg_table[LEGACY_PHYCFG_TABLE_SIZE] = {
|
||||
{BRCM_RATE_1M, 0x00}, /* CCK 1Mbps, data rate 0 */
|
||||
{BRCM_RATE_2M, 0x08}, /* CCK 2Mbps, data rate 1 */
|
||||
{BRCM_RATE_5M5, 0x10}, /* CCK 5.5Mbps, data rate 2 */
|
||||
{BRCM_RATE_11M, 0x18}, /* CCK 11Mbps, data rate 3 */
|
||||
/* OFDM 6Mbps, code rate 1/2, BPSK, 1 spatial stream */
|
||||
{BRCM_RATE_6M, 0x00},
|
||||
/* OFDM 9Mbps, code rate 3/4, BPSK, 1 spatial stream */
|
||||
{BRCM_RATE_9M, 0x02},
|
||||
/* OFDM 12Mbps, code rate 1/2, QPSK, 1 spatial stream */
|
||||
{BRCM_RATE_12M, 0x08},
|
||||
/* OFDM 18Mbps, code rate 3/4, QPSK, 1 spatial stream */
|
||||
{BRCM_RATE_18M, 0x0A},
|
||||
/* OFDM 24Mbps, code rate 1/2, 16-QAM, 1 spatial stream */
|
||||
{BRCM_RATE_24M, 0x10},
|
||||
/* OFDM 36Mbps, code rate 3/4, 16-QAM, 1 spatial stream */
|
||||
{BRCM_RATE_36M, 0x12},
|
||||
/* OFDM 48Mbps, code rate 2/3, 64-QAM, 1 spatial stream */
|
||||
{BRCM_RATE_48M, 0x19},
|
||||
/* OFDM 54Mbps, code rate 3/4, 64-QAM, 1 spatial stream */
|
||||
{BRCM_RATE_54M, 0x1A},
|
||||
};
|
||||
|
||||
/* Hardware rates (also encodes default basic rates) */
|
||||
|
||||
const wlc_rateset_t cck_ofdm_mimo_rates = {
|
||||
12,
|
||||
{ /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */
|
||||
0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
|
||||
0x6c},
|
||||
0x00,
|
||||
{0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
const wlc_rateset_t ofdm_mimo_rates = {
|
||||
8,
|
||||
{ /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */
|
||||
0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
|
||||
0x00,
|
||||
{0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
/* Default ratesets that include MCS32 for 40BW channels */
|
||||
const wlc_rateset_t cck_ofdm_40bw_mimo_rates = {
|
||||
12,
|
||||
{ /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */
|
||||
0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
|
||||
0x6c},
|
||||
0x00,
|
||||
{0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
const wlc_rateset_t ofdm_40bw_mimo_rates = {
|
||||
8,
|
||||
{ /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */
|
||||
0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
|
||||
0x00,
|
||||
{0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
const wlc_rateset_t cck_ofdm_rates = {
|
||||
12,
|
||||
{ /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */
|
||||
0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
|
||||
0x6c},
|
||||
0x00,
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
const wlc_rateset_t gphy_legacy_rates = {
|
||||
4,
|
||||
{ /* 1b, 2b, 5.5b, 11b Mbps */
|
||||
0x82, 0x84, 0x8b, 0x96},
|
||||
0x00,
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
const wlc_rateset_t ofdm_rates = {
|
||||
8,
|
||||
{ /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */
|
||||
0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
|
||||
0x00,
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
const wlc_rateset_t cck_rates = {
|
||||
4,
|
||||
{ /* 1b, 2b, 5.5, 11 Mbps */
|
||||
0x82, 0x84, 0x0b, 0x16},
|
||||
0x00,
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
/* check if rateset is valid.
|
||||
* if check_brate is true, rateset without a basic rate is considered NOT valid.
|
||||
*/
|
||||
static bool brcms_c_rateset_valid(wlc_rateset_t *rs, bool check_brate)
|
||||
{
|
||||
uint idx;
|
||||
|
||||
if (!rs->count)
|
||||
return false;
|
||||
|
||||
if (!check_brate)
|
||||
return true;
|
||||
|
||||
/* error if no basic rates */
|
||||
for (idx = 0; idx < rs->count; idx++) {
|
||||
if (rs->rates[idx] & BRCMS_RATE_FLAG)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void brcms_c_rateset_mcs_upd(wlc_rateset_t *rs, u8 txstreams)
|
||||
{
|
||||
int i;
|
||||
for (i = txstreams; i < MAX_STREAMS_SUPPORTED; i++)
|
||||
rs->mcs[i] = 0;
|
||||
}
|
||||
|
||||
/* filter based on hardware rateset, and sort filtered rateset with basic bit(s) preserved,
|
||||
* and check if resulting rateset is valid.
|
||||
*/
|
||||
bool
|
||||
brcms_c_rate_hwrs_filter_sort_validate(wlc_rateset_t *rs,
|
||||
const wlc_rateset_t *hw_rs,
|
||||
bool check_brate, u8 txstreams)
|
||||
{
|
||||
u8 rateset[BRCM_MAXRATE + 1];
|
||||
u8 r;
|
||||
uint count;
|
||||
uint i;
|
||||
|
||||
memset(rateset, 0, sizeof(rateset));
|
||||
count = rs->count;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
/* mask off "basic rate" bit, BRCMS_RATE_FLAG */
|
||||
r = (int)rs->rates[i] & BRCMS_RATE_MASK;
|
||||
if ((r > BRCM_MAXRATE) || (rate_info[r] == 0))
|
||||
continue;
|
||||
rateset[r] = rs->rates[i]; /* preserve basic bit! */
|
||||
}
|
||||
|
||||
/* fill out the rates in order, looking at only supported rates */
|
||||
count = 0;
|
||||
for (i = 0; i < hw_rs->count; i++) {
|
||||
r = hw_rs->rates[i] & BRCMS_RATE_MASK;
|
||||
if (rateset[r])
|
||||
rs->rates[count++] = rateset[r];
|
||||
}
|
||||
|
||||
rs->count = count;
|
||||
|
||||
/* only set the mcs rate bit if the equivalent hw mcs bit is set */
|
||||
for (i = 0; i < MCSSET_LEN; i++)
|
||||
rs->mcs[i] = (rs->mcs[i] & hw_rs->mcs[i]);
|
||||
|
||||
if (brcms_c_rateset_valid(rs, check_brate))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/* calculate the rate of a rx'd frame and return it as a ratespec */
|
||||
ratespec_t brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp)
|
||||
{
|
||||
int phy_type;
|
||||
ratespec_t rspec = PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT;
|
||||
|
||||
phy_type =
|
||||
((rxh->RxChan & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT);
|
||||
|
||||
if ((phy_type == PHY_TYPE_N) || (phy_type == PHY_TYPE_SSN) ||
|
||||
(phy_type == PHY_TYPE_LCN) || (phy_type == PHY_TYPE_HT)) {
|
||||
switch (rxh->PhyRxStatus_0 & PRXS0_FT_MASK) {
|
||||
case PRXS0_CCK:
|
||||
rspec =
|
||||
CCK_PHY2MAC_RATE(
|
||||
((struct cck_phy_hdr *) plcp)->signal);
|
||||
break;
|
||||
case PRXS0_OFDM:
|
||||
rspec =
|
||||
OFDM_PHY2MAC_RATE(
|
||||
((struct ofdm_phy_hdr *) plcp)->rlpt[0]);
|
||||
break;
|
||||
case PRXS0_PREN:
|
||||
rspec = (plcp[0] & MIMO_PLCP_MCS_MASK) | RSPEC_MIMORATE;
|
||||
if (plcp[0] & MIMO_PLCP_40MHZ) {
|
||||
/* indicate rspec is for 40 MHz mode */
|
||||
rspec &= ~RSPEC_BW_MASK;
|
||||
rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
|
||||
}
|
||||
break;
|
||||
case PRXS0_STDN:
|
||||
/* fallthru */
|
||||
default:
|
||||
/* not supported, error condition */
|
||||
break;
|
||||
}
|
||||
if (PLCP3_ISSGI(plcp[3]))
|
||||
rspec |= RSPEC_SHORT_GI;
|
||||
} else
|
||||
if ((phy_type == PHY_TYPE_A) || (rxh->PhyRxStatus_0 & PRXS0_OFDM))
|
||||
rspec = OFDM_PHY2MAC_RATE(
|
||||
((struct ofdm_phy_hdr *) plcp)->rlpt[0]);
|
||||
else
|
||||
rspec = CCK_PHY2MAC_RATE(
|
||||
((struct cck_phy_hdr *) plcp)->signal);
|
||||
|
||||
return rspec;
|
||||
}
|
||||
|
||||
/* copy rateset src to dst as-is (no masking or sorting) */
|
||||
void brcms_c_rateset_copy(const wlc_rateset_t *src, wlc_rateset_t *dst)
|
||||
{
|
||||
memcpy(dst, src, sizeof(wlc_rateset_t));
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy and selectively filter one rateset to another.
|
||||
* 'basic_only' means only copy basic rates.
|
||||
* 'rates' indicates cck (11b) and ofdm rates combinations.
|
||||
* - 0: cck and ofdm
|
||||
* - 1: cck only
|
||||
* - 2: ofdm only
|
||||
* 'xmask' is the copy mask (typically 0x7f or 0xff).
|
||||
*/
|
||||
void
|
||||
brcms_c_rateset_filter(wlc_rateset_t *src, wlc_rateset_t *dst, bool basic_only,
|
||||
u8 rates, uint xmask, bool mcsallow)
|
||||
{
|
||||
uint i;
|
||||
uint r;
|
||||
uint count;
|
||||
|
||||
count = 0;
|
||||
for (i = 0; i < src->count; i++) {
|
||||
r = src->rates[i];
|
||||
if (basic_only && !(r & BRCMS_RATE_FLAG))
|
||||
continue;
|
||||
if (rates == BRCMS_RATES_CCK && IS_OFDM((r & BRCMS_RATE_MASK)))
|
||||
continue;
|
||||
if (rates == BRCMS_RATES_OFDM && IS_CCK((r & BRCMS_RATE_MASK)))
|
||||
continue;
|
||||
dst->rates[count++] = r & xmask;
|
||||
}
|
||||
dst->count = count;
|
||||
dst->htphy_membership = src->htphy_membership;
|
||||
|
||||
if (mcsallow && rates != BRCMS_RATES_CCK)
|
||||
memcpy(&dst->mcs[0], &src->mcs[0], MCSSET_LEN);
|
||||
else
|
||||
brcms_c_rateset_mcs_clear(dst);
|
||||
}
|
||||
|
||||
/* select rateset for a given phy_type and bandtype and filter it, sort it
|
||||
* and fill rs_tgt with result
|
||||
*/
|
||||
void
|
||||
brcms_c_rateset_default(wlc_rateset_t *rs_tgt, const wlc_rateset_t *rs_hw,
|
||||
uint phy_type, int bandtype, bool cck_only, uint rate_mask,
|
||||
bool mcsallow, u8 bw, u8 txstreams)
|
||||
{
|
||||
const wlc_rateset_t *rs_dflt;
|
||||
wlc_rateset_t rs_sel;
|
||||
if ((PHYTYPE_IS(phy_type, PHY_TYPE_HT)) ||
|
||||
(PHYTYPE_IS(phy_type, PHY_TYPE_N)) ||
|
||||
(PHYTYPE_IS(phy_type, PHY_TYPE_LCN)) ||
|
||||
(PHYTYPE_IS(phy_type, PHY_TYPE_SSN))) {
|
||||
if (BAND_5G(bandtype)) {
|
||||
rs_dflt = (bw == BRCMS_20_MHZ ?
|
||||
&ofdm_mimo_rates : &ofdm_40bw_mimo_rates);
|
||||
} else {
|
||||
rs_dflt = (bw == BRCMS_20_MHZ ?
|
||||
&cck_ofdm_mimo_rates :
|
||||
&cck_ofdm_40bw_mimo_rates);
|
||||
}
|
||||
} else if (PHYTYPE_IS(phy_type, PHY_TYPE_LP)) {
|
||||
rs_dflt = (BAND_5G(bandtype)) ? &ofdm_rates : &cck_ofdm_rates;
|
||||
} else if (PHYTYPE_IS(phy_type, PHY_TYPE_A)) {
|
||||
rs_dflt = &ofdm_rates;
|
||||
} else if (PHYTYPE_IS(phy_type, PHY_TYPE_G)) {
|
||||
rs_dflt = &cck_ofdm_rates;
|
||||
} else {
|
||||
/* should not happen, error condition */
|
||||
rs_dflt = &cck_rates; /* force cck */
|
||||
}
|
||||
|
||||
/* if hw rateset is not supplied, assign selected rateset to it */
|
||||
if (!rs_hw)
|
||||
rs_hw = rs_dflt;
|
||||
|
||||
brcms_c_rateset_copy(rs_dflt, &rs_sel);
|
||||
brcms_c_rateset_mcs_upd(&rs_sel, txstreams);
|
||||
brcms_c_rateset_filter(&rs_sel, rs_tgt, false,
|
||||
cck_only ? BRCMS_RATES_CCK : BRCMS_RATES_CCK_OFDM,
|
||||
rate_mask, mcsallow);
|
||||
brcms_c_rate_hwrs_filter_sort_validate(rs_tgt, rs_hw, false,
|
||||
mcsallow ? txstreams : 1);
|
||||
}
|
||||
|
||||
s16 brcms_c_rate_legacy_phyctl(uint rate)
|
||||
{
|
||||
uint i;
|
||||
for (i = 0; i < LEGACY_PHYCFG_TABLE_SIZE; i++)
|
||||
if (rate == legacy_phycfg_table[i].rate_ofdm)
|
||||
return legacy_phycfg_table[i].tx_phy_ctl3;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void brcms_c_rateset_mcs_clear(wlc_rateset_t *rateset)
|
||||
{
|
||||
uint i;
|
||||
for (i = 0; i < MCSSET_LEN; i++)
|
||||
rateset->mcs[i] = 0;
|
||||
}
|
||||
|
||||
void brcms_c_rateset_mcs_build(wlc_rateset_t *rateset, u8 txstreams)
|
||||
{
|
||||
memcpy(&rateset->mcs[0], &cck_ofdm_mimo_rates.mcs[0], MCSSET_LEN);
|
||||
brcms_c_rateset_mcs_upd(rateset, txstreams);
|
||||
}
|
||||
|
||||
/* Based on bandwidth passed, allow/disallow MCS 32 in the rateset */
|
||||
void brcms_c_rateset_bw_mcs_filter(wlc_rateset_t *rateset, u8 bw)
|
||||
{
|
||||
if (bw == BRCMS_40_MHZ)
|
||||
setbit(rateset->mcs, 32);
|
||||
else
|
||||
clrbit(rateset->mcs, 32);
|
||||
}
|
@ -1,173 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_RATE_H_
|
||||
#define _BRCM_RATE_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
extern const u8 rate_info[];
|
||||
extern const struct brcms_rateset cck_ofdm_mimo_rates;
|
||||
extern const struct brcms_rateset ofdm_mimo_rates;
|
||||
extern const struct brcms_rateset cck_ofdm_rates;
|
||||
extern const struct brcms_rateset ofdm_rates;
|
||||
extern const struct brcms_rateset cck_rates;
|
||||
extern const struct brcms_rateset gphy_legacy_rates;
|
||||
extern const struct brcms_rateset wlc_lrs_rates;
|
||||
extern const struct brcms_rateset rate_limit_1_2;
|
||||
|
||||
struct brcms_mcs_info {
|
||||
u32 phy_rate_20; /* phy rate in kbps [20Mhz] */
|
||||
u32 phy_rate_40; /* phy rate in kbps [40Mhz] */
|
||||
u32 phy_rate_20_sgi; /* phy rate in kbps [20Mhz] with SGI */
|
||||
u32 phy_rate_40_sgi; /* phy rate in kbps [40Mhz] with SGI */
|
||||
u8 tx_phy_ctl3; /* phy ctl byte 3, code rate, modulation type, # of streams */
|
||||
u8 leg_ofdm; /* matching legacy ofdm rate in 500bkps */
|
||||
};
|
||||
|
||||
#define BRCMS_MAXMCS 32 /* max valid mcs index */
|
||||
#define MCS_TABLE_SIZE 33 /* Number of mcs entries in the table */
|
||||
extern const struct brcms_mcs_info mcs_table[];
|
||||
|
||||
#define MCS_INVALID 0xFF
|
||||
#define MCS_CR_MASK 0x07 /* Code Rate bit mask */
|
||||
#define MCS_MOD_MASK 0x38 /* Modulation bit shift */
|
||||
#define MCS_MOD_SHIFT 3 /* MOdulation bit shift */
|
||||
#define MCS_TXS_MASK 0xc0 /* num tx streams - 1 bit mask */
|
||||
#define MCS_TXS_SHIFT 6 /* num tx streams - 1 bit shift */
|
||||
#define MCS_CR(_mcs) (mcs_table[_mcs].tx_phy_ctl3 & MCS_CR_MASK)
|
||||
#define MCS_MOD(_mcs) ((mcs_table[_mcs].tx_phy_ctl3 & MCS_MOD_MASK) >> MCS_MOD_SHIFT)
|
||||
#define MCS_TXS(_mcs) ((mcs_table[_mcs].tx_phy_ctl3 & MCS_TXS_MASK) >> MCS_TXS_SHIFT)
|
||||
#define MCS_RATE(_mcs, _is40, _sgi) (_sgi ? \
|
||||
(_is40 ? mcs_table[_mcs].phy_rate_40_sgi : mcs_table[_mcs].phy_rate_20_sgi) : \
|
||||
(_is40 ? mcs_table[_mcs].phy_rate_40 : mcs_table[_mcs].phy_rate_20))
|
||||
#define VALID_MCS(_mcs) ((_mcs < MCS_TABLE_SIZE))
|
||||
|
||||
/* Macro to use the rate_info table */
|
||||
#define BRCMS_RATE_MASK_FULL 0xff /* Rate value mask with basic rate flag */
|
||||
|
||||
/* convert 500kbps to bps */
|
||||
#define BRCMS_RATE_500K_TO_BPS(rate) ((rate) * 500000)
|
||||
|
||||
/* rate spec : holds rate and mode specific information required to generate a tx frame. */
|
||||
/* Legacy CCK and OFDM information is held in the same manner as was done in the past */
|
||||
/* (in the lower byte) the upper 3 bytes primarily hold MIMO specific information */
|
||||
|
||||
/* rate spec bit fields */
|
||||
#define RSPEC_RATE_MASK 0x0000007F /* Either 500Kbps units or MIMO MCS idx */
|
||||
#define RSPEC_MIMORATE 0x08000000 /* mimo MCS is stored in RSPEC_RATE_MASK */
|
||||
#define RSPEC_BW_MASK 0x00000700 /* mimo bw mask */
|
||||
#define RSPEC_BW_SHIFT 8 /* mimo bw shift */
|
||||
#define RSPEC_STF_MASK 0x00003800 /* mimo Space/Time/Frequency mode mask */
|
||||
#define RSPEC_STF_SHIFT 11 /* mimo Space/Time/Frequency mode shift */
|
||||
#define RSPEC_CT_MASK 0x0000C000 /* mimo coding type mask */
|
||||
#define RSPEC_CT_SHIFT 14 /* mimo coding type shift */
|
||||
#define RSPEC_STC_MASK 0x00300000 /* mimo num STC streams per PLCP defn. */
|
||||
#define RSPEC_STC_SHIFT 20 /* mimo num STC streams per PLCP defn. */
|
||||
#define RSPEC_LDPC_CODING 0x00400000 /* mimo bit indicates adv coding in use */
|
||||
#define RSPEC_SHORT_GI 0x00800000 /* mimo bit indicates short GI in use */
|
||||
#define RSPEC_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */
|
||||
#define RSPEC_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicates override rate only */
|
||||
|
||||
#define BRCMS_HTPHY 127 /* HT PHY Membership */
|
||||
|
||||
#define RSPEC_ACTIVE(rspec) (rspec & (RSPEC_RATE_MASK | RSPEC_MIMORATE))
|
||||
#define RSPEC2RATE(rspec) ((rspec & RSPEC_MIMORATE) ? \
|
||||
MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec)) : \
|
||||
(rspec & RSPEC_RATE_MASK))
|
||||
/* return rate in unit of 500Kbps -- for internal use in wlc_rate_sel.c */
|
||||
#define RSPEC2RATE500K(rspec) ((rspec & RSPEC_MIMORATE) ? \
|
||||
MCS_RATE((rspec & RSPEC_RATE_MASK), state->is40bw, RSPEC_ISSGI(rspec))/500 : \
|
||||
(rspec & RSPEC_RATE_MASK))
|
||||
#define CRSPEC2RATE500K(rspec) ((rspec & RSPEC_MIMORATE) ? \
|
||||
MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec))/500 :\
|
||||
(rspec & RSPEC_RATE_MASK))
|
||||
|
||||
#define RSPEC2KBPS(rspec) (IS_MCS(rspec) ? RSPEC2RATE(rspec) : RSPEC2RATE(rspec)*500)
|
||||
#define RSPEC_PHYTXBYTE2(rspec) ((rspec & 0xff00) >> 8)
|
||||
#define RSPEC_GET_BW(rspec) ((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT)
|
||||
#define RSPEC_IS40MHZ(rspec) ((((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT) == \
|
||||
PHY_TXC1_BW_40MHZ) || (((rspec & RSPEC_BW_MASK) >> \
|
||||
RSPEC_BW_SHIFT) == PHY_TXC1_BW_40MHZ_DUP))
|
||||
#define RSPEC_ISSGI(rspec) ((rspec & RSPEC_SHORT_GI) == RSPEC_SHORT_GI)
|
||||
#define RSPEC_MIMOPLCP3(rspec) ((rspec & 0xf00000) >> 16)
|
||||
#define PLCP3_ISSGI(plcp) (plcp & (RSPEC_SHORT_GI >> 16))
|
||||
#define RSPEC_STC(rspec) ((rspec & RSPEC_STC_MASK) >> RSPEC_STC_SHIFT)
|
||||
#define RSPEC_STF(rspec) ((rspec & RSPEC_STF_MASK) >> RSPEC_STF_SHIFT)
|
||||
#define PLCP3_ISSTBC(plcp) ((plcp & (RSPEC_STC_MASK) >> 16) == 0x10)
|
||||
#define PLCP3_STC_MASK 0x30
|
||||
#define PLCP3_STC_SHIFT 4
|
||||
|
||||
/* Rate info table; takes a legacy rate or ratespec_t */
|
||||
#define IS_MCS(r) (r & RSPEC_MIMORATE)
|
||||
#define IS_OFDM(r) (!IS_MCS(r) && (rate_info[(r) & RSPEC_RATE_MASK] & \
|
||||
BRCMS_RATE_FLAG))
|
||||
#define IS_CCK(r) (!IS_MCS(r) && ( \
|
||||
((r) & BRCMS_RATE_MASK) == BRCM_RATE_1M || \
|
||||
((r) & BRCMS_RATE_MASK) == BRCM_RATE_2M || \
|
||||
((r) & BRCMS_RATE_MASK) == BRCM_RATE_5M5 || \
|
||||
((r) & BRCMS_RATE_MASK) == BRCM_RATE_11M))
|
||||
#define IS_SINGLE_STREAM(mcs) (((mcs) <= HIGHEST_SINGLE_STREAM_MCS) || ((mcs) == 32))
|
||||
#define CCK_RSPEC(cck) ((cck) & RSPEC_RATE_MASK)
|
||||
#define OFDM_RSPEC(ofdm) (((ofdm) & RSPEC_RATE_MASK) |\
|
||||
(PHY_TXC1_MODE_CDD << RSPEC_STF_SHIFT))
|
||||
#define LEGACY_RSPEC(rate) (IS_CCK(rate) ? CCK_RSPEC(rate) : OFDM_RSPEC(rate))
|
||||
|
||||
#define MCS_RSPEC(mcs) (((mcs) & RSPEC_RATE_MASK) | RSPEC_MIMORATE | \
|
||||
(IS_SINGLE_STREAM(mcs) ? (PHY_TXC1_MODE_CDD << RSPEC_STF_SHIFT) : \
|
||||
(PHY_TXC1_MODE_SDM << RSPEC_STF_SHIFT)))
|
||||
|
||||
/* Convert encoded rate value in plcp header to numerical rates in 500 KHz increments */
|
||||
extern const u8 ofdm_rate_lookup[];
|
||||
#define OFDM_PHY2MAC_RATE(rlpt) (ofdm_rate_lookup[rlpt & 0x7])
|
||||
#define CCK_PHY2MAC_RATE(signal) (signal/5)
|
||||
|
||||
/* Rates specified in brcms_c_rateset_filter() */
|
||||
#define BRCMS_RATES_CCK_OFDM 0
|
||||
#define BRCMS_RATES_CCK 1
|
||||
#define BRCMS_RATES_OFDM 2
|
||||
|
||||
/* sanitize, and sort a rateset with the basic bit(s) preserved, validate rateset */
|
||||
extern bool
|
||||
brcms_c_rate_hwrs_filter_sort_validate(struct brcms_rateset *rs,
|
||||
const struct brcms_rateset *hw_rs,
|
||||
bool check_brate, u8 txstreams);
|
||||
/* copy rateset src to dst as-is (no masking or sorting) */
|
||||
extern void brcms_c_rateset_copy(const struct brcms_rateset *src,
|
||||
struct brcms_rateset *dst);
|
||||
|
||||
/* would be nice to have these documented ... */
|
||||
extern ratespec_t brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp);
|
||||
|
||||
extern void brcms_c_rateset_filter(struct brcms_rateset *src,
|
||||
struct brcms_rateset *dst, bool basic_only, u8 rates, uint xmask,
|
||||
bool mcsallow);
|
||||
|
||||
extern void
|
||||
brcms_c_rateset_default(struct brcms_rateset *rs_tgt,
|
||||
const struct brcms_rateset *rs_hw, uint phy_type,
|
||||
int bandtype, bool cck_only, uint rate_mask,
|
||||
bool mcsallow, u8 bw, u8 txstreams);
|
||||
|
||||
extern s16 brcms_c_rate_legacy_phyctl(uint rate);
|
||||
|
||||
extern void brcms_c_rateset_mcs_upd(struct brcms_rateset *rs, u8 txstreams);
|
||||
extern void brcms_c_rateset_mcs_clear(struct brcms_rateset *rateset);
|
||||
extern void brcms_c_rateset_mcs_build(struct brcms_rateset *rateset,
|
||||
u8 txstreams);
|
||||
extern void brcms_c_rateset_bw_mcs_filter(struct brcms_rateset *rateset, u8 bw);
|
||||
|
||||
#endif /* _BRCM_RATE_H_ */
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_SCB_H_
|
||||
#define _BRCM_SCB_H_
|
||||
|
||||
#include <linux/if_ether.h>
|
||||
#include <brcmu_utils.h>
|
||||
#include <defs.h>
|
||||
#include "types.h"
|
||||
|
||||
#define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */
|
||||
/* structure to store per-tid state for the ampdu initiator */
|
||||
struct scb_ampdu_tid_ini {
|
||||
u8 tx_in_transit; /* number of pending mpdus in transit in driver */
|
||||
u8 tid; /* initiator tid for easy lookup */
|
||||
u8 txretry[AMPDU_TX_BA_MAX_WSIZE]; /* tx retry count; indexed by seq modulo */
|
||||
struct scb *scb; /* backptr for easy lookup */
|
||||
u8 ba_wsize; /* negotiated ba window size (in pdu) */
|
||||
};
|
||||
|
||||
#define AMPDU_MAX_SCB_TID NUMPRIO
|
||||
|
||||
struct scb_ampdu {
|
||||
struct scb *scb; /* back pointer for easy reference */
|
||||
u8 mpdu_density; /* mpdu density */
|
||||
u8 max_pdu; /* max pdus allowed in ampdu */
|
||||
u8 release; /* # of mpdus released at a time */
|
||||
u16 min_len; /* min mpdu len to support the density */
|
||||
u32 max_rx_ampdu_bytes; /* max ampdu rcv length; 8k, 16k, 32k, 64k */
|
||||
struct pktq txq; /* sdu transmit queue pending aggregation */
|
||||
|
||||
/* This could easily be a ini[] pointer and we keep this info in wl itself instead
|
||||
* of having mac80211 hold it for us. Also could be made dynamic per tid instead of
|
||||
* static.
|
||||
*/
|
||||
/* initiator info - per tid (NUMPRIO): */
|
||||
struct scb_ampdu_tid_ini ini[AMPDU_MAX_SCB_TID];
|
||||
};
|
||||
|
||||
#define SCB_MAGIC 0xbeefcafe
|
||||
|
||||
/* station control block - one per remote MAC address */
|
||||
struct scb {
|
||||
u32 magic;
|
||||
u32 flags; /* various bit flags as defined below */
|
||||
u32 flags2; /* various bit flags2 as defined below */
|
||||
u8 state; /* current state bitfield of auth/assoc process */
|
||||
u8 ea[ETH_ALEN]; /* station address */
|
||||
void *fragbuf[NUMPRIO]; /* defragmentation buffer per prio */
|
||||
uint fragresid[NUMPRIO]; /* #bytes unused in frag buffer per prio */
|
||||
|
||||
u16 seqctl[NUMPRIO]; /* seqctl of last received frame (for dups) */
|
||||
u16 seqctl_nonqos; /* seqctl of last received frame (for dups) for
|
||||
* non-QoS data and management
|
||||
*/
|
||||
u16 seqnum[NUMPRIO]; /* WME: driver maintained sw seqnum per priority */
|
||||
|
||||
struct scb_ampdu scb_ampdu; /* AMPDU state including per tid info */
|
||||
};
|
||||
|
||||
/* scb flags */
|
||||
#define SCB_WMECAP 0x0040 /* may ONLY be set if WME_ENAB(wlc) */
|
||||
#define SCB_HTCAP 0x10000 /* HT (MIMO) capable device */
|
||||
#define SCB_IS40 0x80000 /* 40MHz capable */
|
||||
#define SCB_STBCCAP 0x40000000 /* STBC Capable */
|
||||
#define SCB_WME(a) ((a)->flags & SCB_WMECAP)/* implies WME_ENAB */
|
||||
#define SCB_SEQNUM(scb, prio) ((scb)->seqnum[(prio)])
|
||||
#define SCB_PS(a) NULL
|
||||
#define SCB_STBC_CAP(a) ((a)->flags & SCB_STBCCAP)
|
||||
#define SCB_AMPDU(a) true
|
||||
#endif /* _BRCM_SCB_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_SROM_H_
|
||||
#define _BRCM_SROM_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/* Prototypes */
|
||||
extern int srom_var_init(struct si_pub *sih, uint bus, void *curmap,
|
||||
char **vars, uint *count);
|
||||
|
||||
extern int srom_read(struct si_pub *sih, uint bus, void *curmap,
|
||||
uint byteoff, uint nbytes, u16 *buf, bool check_crc);
|
||||
|
||||
/* parse standard PCMCIA cis, normally used by SB/PCMCIA/SDIO/SPI/OTP
|
||||
* and extract from it into name=value pairs
|
||||
*/
|
||||
extern int srom_parsecis(u8 **pcis, uint ciscnt,
|
||||
char **vars, uint *count);
|
||||
#endif /* _BRCM_SROM_H_ */
|
@ -1,477 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "d11.h"
|
||||
#include "rate.h"
|
||||
#include "phy/phy_hal.h"
|
||||
#include "channel.h"
|
||||
#include "main.h"
|
||||
#include "bmac.h"
|
||||
#include "stf.h"
|
||||
|
||||
#define MIN_SPATIAL_EXPANSION 0
|
||||
#define MAX_SPATIAL_EXPANSION 1
|
||||
|
||||
#define BRCMS_STF_SS_STBC_RX(wlc) (BRCMS_ISNPHY(wlc->band) && \
|
||||
NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6))
|
||||
|
||||
static bool brcms_c_stf_stbc_tx_set(struct brcms_c_info *wlc, s32 int_val);
|
||||
static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts, u8 val);
|
||||
static int brcms_c_stf_spatial_policy_set(struct brcms_c_info *wlc, int val);
|
||||
static void brcms_c_stf_stbc_rx_ht_update(struct brcms_c_info *wlc, int val);
|
||||
|
||||
static void _brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc);
|
||||
static u16 _brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc,
|
||||
ratespec_t rspec);
|
||||
|
||||
#define NSTS_1 1
|
||||
#define NSTS_2 2
|
||||
#define NSTS_3 3
|
||||
#define NSTS_4 4
|
||||
const u8 txcore_default[5] = {
|
||||
(0), /* bitmap of the core enabled */
|
||||
(0x01), /* For Nsts = 1, enable core 1 */
|
||||
(0x03), /* For Nsts = 2, enable core 1 & 2 */
|
||||
(0x07), /* For Nsts = 3, enable core 1, 2 & 3 */
|
||||
(0x0f) /* For Nsts = 4, enable all cores */
|
||||
};
|
||||
|
||||
static void brcms_c_stf_stbc_rx_ht_update(struct brcms_c_info *wlc, int val)
|
||||
{
|
||||
/* MIMOPHYs rev3-6 cannot receive STBC with only one rx core active */
|
||||
if (BRCMS_STF_SS_STBC_RX(wlc)) {
|
||||
if ((wlc->stf->rxstreams == 1) && (val != HT_CAP_RX_STBC_NO))
|
||||
return;
|
||||
}
|
||||
|
||||
wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_RX_STBC;
|
||||
wlc->ht_cap.cap_info |= (val << IEEE80211_HT_CAP_RX_STBC_SHIFT);
|
||||
|
||||
if (wlc->pub->up) {
|
||||
brcms_c_update_beacon(wlc);
|
||||
brcms_c_update_probe_resp(wlc, true);
|
||||
}
|
||||
}
|
||||
|
||||
/* every WLC_TEMPSENSE_PERIOD seconds temperature check to decide whether to turn on/off txchain */
|
||||
void brcms_c_tempsense_upd(struct brcms_c_info *wlc)
|
||||
{
|
||||
struct brcms_phy_pub *pi = wlc->band->pi;
|
||||
uint active_chains, txchain;
|
||||
|
||||
/* Check if the chip is too hot. Disable one Tx chain, if it is */
|
||||
/* high 4 bits are for Rx chain, low 4 bits are for Tx chain */
|
||||
active_chains = wlc_phy_stf_chain_active_get(pi);
|
||||
txchain = active_chains & 0xf;
|
||||
|
||||
if (wlc->stf->txchain == wlc->stf->hw_txchain) {
|
||||
if (txchain && (txchain < wlc->stf->hw_txchain)) {
|
||||
/* turn off 1 tx chain */
|
||||
brcms_c_stf_txchain_set(wlc, txchain, true);
|
||||
}
|
||||
} else if (wlc->stf->txchain < wlc->stf->hw_txchain) {
|
||||
if (txchain == wlc->stf->hw_txchain) {
|
||||
/* turn back on txchain */
|
||||
brcms_c_stf_txchain_set(wlc, txchain, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, u16 *ss_algo_channel,
|
||||
chanspec_t chanspec)
|
||||
{
|
||||
struct tx_power power;
|
||||
u8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id;
|
||||
|
||||
/* Clear previous settings */
|
||||
*ss_algo_channel = 0;
|
||||
|
||||
if (!wlc->pub->up) {
|
||||
*ss_algo_channel = (u16) -1;
|
||||
return;
|
||||
}
|
||||
|
||||
wlc_phy_txpower_get_current(wlc->band->pi, &power,
|
||||
CHSPEC_CHANNEL(chanspec));
|
||||
|
||||
siso_mcs_id = (CHSPEC_IS40(chanspec)) ?
|
||||
WL_TX_POWER_MCS40_SISO_FIRST : WL_TX_POWER_MCS20_SISO_FIRST;
|
||||
cdd_mcs_id = (CHSPEC_IS40(chanspec)) ?
|
||||
WL_TX_POWER_MCS40_CDD_FIRST : WL_TX_POWER_MCS20_CDD_FIRST;
|
||||
stbc_mcs_id = (CHSPEC_IS40(chanspec)) ?
|
||||
WL_TX_POWER_MCS40_STBC_FIRST : WL_TX_POWER_MCS20_STBC_FIRST;
|
||||
|
||||
/* criteria to choose stf mode */
|
||||
|
||||
/* the "+3dbm (12 0.25db units)" is to account for the fact that with CDD, tx occurs
|
||||
* on both chains
|
||||
*/
|
||||
if (power.target[siso_mcs_id] > (power.target[cdd_mcs_id] + 12))
|
||||
setbit(ss_algo_channel, PHY_TXC1_MODE_SISO);
|
||||
else
|
||||
setbit(ss_algo_channel, PHY_TXC1_MODE_CDD);
|
||||
|
||||
/* STBC is ORed into to algo channel as STBC requires per-packet SCB capability check
|
||||
* so cannot be default mode of operation. One of SISO, CDD have to be set
|
||||
*/
|
||||
if (power.target[siso_mcs_id] <= (power.target[stbc_mcs_id] + 12))
|
||||
setbit(ss_algo_channel, PHY_TXC1_MODE_STBC);
|
||||
}
|
||||
|
||||
static bool brcms_c_stf_stbc_tx_set(struct brcms_c_info *wlc, s32 int_val)
|
||||
{
|
||||
if ((int_val != AUTO) && (int_val != OFF) && (int_val != ON)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((int_val == ON) && (wlc->stf->txstreams == 1))
|
||||
return false;
|
||||
|
||||
if ((int_val == OFF) || (wlc->stf->txstreams == 1)
|
||||
|| !BRCMS_STBC_CAP_PHY(wlc))
|
||||
wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC;
|
||||
else
|
||||
wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_TX_STBC;
|
||||
|
||||
wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = (s8) int_val;
|
||||
wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = (s8) int_val;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val)
|
||||
{
|
||||
if ((int_val != HT_CAP_RX_STBC_NO)
|
||||
&& (int_val != HT_CAP_RX_STBC_ONE_STREAM)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (BRCMS_STF_SS_STBC_RX(wlc)) {
|
||||
if ((int_val != HT_CAP_RX_STBC_NO)
|
||||
&& (wlc->stf->rxstreams == 1))
|
||||
return false;
|
||||
}
|
||||
|
||||
brcms_c_stf_stbc_rx_ht_update(wlc, int_val);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts,
|
||||
u8 core_mask)
|
||||
{
|
||||
BCMMSG(wlc->wiphy, "wl%d: Nsts %d core_mask %x\n",
|
||||
wlc->pub->unit, Nsts, core_mask);
|
||||
|
||||
if (BRCMS_BITSCNT(core_mask) > wlc->stf->txstreams) {
|
||||
core_mask = 0;
|
||||
}
|
||||
|
||||
if ((BRCMS_BITSCNT(core_mask) == wlc->stf->txstreams) &&
|
||||
((core_mask & ~wlc->stf->txchain)
|
||||
|| !(core_mask & wlc->stf->txchain))) {
|
||||
core_mask = wlc->stf->txchain;
|
||||
}
|
||||
|
||||
wlc->stf->txcore[Nsts] = core_mask;
|
||||
/* Nsts = 1..4, txcore index = 1..4 */
|
||||
if (Nsts == 1) {
|
||||
/* Needs to update beacon and ucode generated response
|
||||
* frames when 1 stream core map changed
|
||||
*/
|
||||
wlc->stf->phytxant = core_mask << PHY_TXC_ANT_SHIFT;
|
||||
brcms_b_txant_set(wlc->hw, wlc->stf->phytxant);
|
||||
if (wlc->clk) {
|
||||
brcms_c_suspend_mac_and_wait(wlc);
|
||||
brcms_c_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec);
|
||||
brcms_c_enable_mac(wlc);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int brcms_c_stf_spatial_policy_set(struct brcms_c_info *wlc, int val)
|
||||
{
|
||||
int i;
|
||||
u8 core_mask = 0;
|
||||
|
||||
BCMMSG(wlc->wiphy, "wl%d: val %x\n", wlc->pub->unit, val);
|
||||
|
||||
wlc->stf->spatial_policy = (s8) val;
|
||||
for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) {
|
||||
core_mask = (val == MAX_SPATIAL_EXPANSION) ?
|
||||
wlc->stf->txchain : txcore_default[i];
|
||||
brcms_c_stf_txcore_set(wlc, (u8) i, core_mask);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val, bool force)
|
||||
{
|
||||
u8 txchain = (u8) int_val;
|
||||
u8 txstreams;
|
||||
uint i;
|
||||
|
||||
if (wlc->stf->txchain == txchain)
|
||||
return 0;
|
||||
|
||||
if ((txchain & ~wlc->stf->hw_txchain)
|
||||
|| !(txchain & wlc->stf->hw_txchain))
|
||||
return -EINVAL;
|
||||
|
||||
/* if nrate override is configured to be non-SISO STF mode, reject reducing txchain to 1 */
|
||||
txstreams = (u8) BRCMS_BITSCNT(txchain);
|
||||
if (txstreams > MAX_STREAMS_SUPPORTED)
|
||||
return -EINVAL;
|
||||
|
||||
if (txstreams == 1) {
|
||||
for (i = 0; i < NBANDS(wlc); i++)
|
||||
if ((RSPEC_STF(wlc->bandstate[i]->rspec_override) !=
|
||||
PHY_TXC1_MODE_SISO)
|
||||
|| (RSPEC_STF(wlc->bandstate[i]->mrspec_override) !=
|
||||
PHY_TXC1_MODE_SISO)) {
|
||||
if (!force)
|
||||
return -EBADE;
|
||||
|
||||
/* over-write the override rspec */
|
||||
if (RSPEC_STF(wlc->bandstate[i]->rspec_override)
|
||||
!= PHY_TXC1_MODE_SISO) {
|
||||
wlc->bandstate[i]->rspec_override = 0;
|
||||
wiphy_err(wlc->wiphy, "%s(): temp "
|
||||
"sense override non-SISO "
|
||||
"rspec_override\n",
|
||||
__func__);
|
||||
}
|
||||
if (RSPEC_STF
|
||||
(wlc->bandstate[i]->mrspec_override) !=
|
||||
PHY_TXC1_MODE_SISO) {
|
||||
wlc->bandstate[i]->mrspec_override = 0;
|
||||
wiphy_err(wlc->wiphy, "%s(): temp "
|
||||
"sense override non-SISO "
|
||||
"mrspec_override\n",
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wlc->stf->txchain = txchain;
|
||||
wlc->stf->txstreams = txstreams;
|
||||
brcms_c_stf_stbc_tx_set(wlc, wlc->band->band_stf_stbc_tx);
|
||||
brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
|
||||
brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
|
||||
wlc->stf->txant =
|
||||
(wlc->stf->txstreams == 1) ? ANT_TX_FORCE_0 : ANT_TX_DEF;
|
||||
_brcms_c_stf_phy_txant_upd(wlc);
|
||||
|
||||
wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain,
|
||||
wlc->stf->rxchain);
|
||||
|
||||
for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++)
|
||||
brcms_c_stf_txcore_set(wlc, (u8) i, txcore_default[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* update wlc->stf->ss_opmode which represents the operational stf_ss mode we're using */
|
||||
int brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band)
|
||||
{
|
||||
int ret_code = 0;
|
||||
u8 prev_stf_ss;
|
||||
u8 upd_stf_ss;
|
||||
|
||||
prev_stf_ss = wlc->stf->ss_opmode;
|
||||
|
||||
/* NOTE: opmode can only be SISO or CDD as STBC is decided on a per-packet basis */
|
||||
if (BRCMS_STBC_CAP_PHY(wlc) &&
|
||||
wlc->stf->ss_algosel_auto
|
||||
&& (wlc->stf->ss_algo_channel != (u16) -1)) {
|
||||
upd_stf_ss = (wlc->stf->no_cddstbc || (wlc->stf->txstreams == 1)
|
||||
|| isset(&wlc->stf->ss_algo_channel,
|
||||
PHY_TXC1_MODE_SISO)) ? PHY_TXC1_MODE_SISO
|
||||
: PHY_TXC1_MODE_CDD;
|
||||
} else {
|
||||
if (wlc->band != band)
|
||||
return ret_code;
|
||||
upd_stf_ss = (wlc->stf->no_cddstbc
|
||||
|| (wlc->stf->txstreams ==
|
||||
1)) ? PHY_TXC1_MODE_SISO : band->
|
||||
band_stf_ss_mode;
|
||||
}
|
||||
if (prev_stf_ss != upd_stf_ss) {
|
||||
wlc->stf->ss_opmode = upd_stf_ss;
|
||||
brcms_b_band_stf_ss_set(wlc->hw, upd_stf_ss);
|
||||
}
|
||||
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
int brcms_c_stf_attach(struct brcms_c_info *wlc)
|
||||
{
|
||||
wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_SISO;
|
||||
wlc->bandstate[BAND_5G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_CDD;
|
||||
|
||||
if (BRCMS_ISNPHY(wlc->band) &&
|
||||
(wlc_phy_txpower_hw_ctrl_get(wlc->band->pi) != PHY_TPC_HW_ON))
|
||||
wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode =
|
||||
PHY_TXC1_MODE_CDD;
|
||||
brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
|
||||
brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
|
||||
|
||||
brcms_c_stf_stbc_rx_ht_update(wlc, HT_CAP_RX_STBC_NO);
|
||||
wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF;
|
||||
wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF;
|
||||
|
||||
if (BRCMS_STBC_CAP_PHY(wlc)) {
|
||||
wlc->stf->ss_algosel_auto = true;
|
||||
wlc->stf->ss_algo_channel = (u16) -1; /* Init the default value */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void brcms_c_stf_detach(struct brcms_c_info *wlc)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Centralized txant update function. call it whenever wlc->stf->txant and/or wlc->stf->txchain
|
||||
* change
|
||||
*
|
||||
* Antennas are controlled by ucode indirectly, which drives PHY or GPIO to
|
||||
* achieve various tx/rx antenna selection schemes
|
||||
*
|
||||
* legacy phy, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 means auto(last rx)
|
||||
* for NREV<3, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 means last rx and
|
||||
* do tx-antenna selection for SISO transmissions
|
||||
* for NREV=3, bit 6 and bit _8_ means antenna 0 and 1 respectively, bit6+bit7 means last rx and
|
||||
* do tx-antenna selection for SISO transmissions
|
||||
* for NREV>=7, bit 6 and bit 7 mean antenna 0 and 1 respectively, nit6+bit7 means both cores active
|
||||
*/
|
||||
static void _brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc)
|
||||
{
|
||||
s8 txant;
|
||||
|
||||
txant = (s8) wlc->stf->txant;
|
||||
if (BRCMS_PHY_11N_CAP(wlc->band)) {
|
||||
if (txant == ANT_TX_FORCE_0) {
|
||||
wlc->stf->phytxant = PHY_TXC_ANT_0;
|
||||
} else if (txant == ANT_TX_FORCE_1) {
|
||||
wlc->stf->phytxant = PHY_TXC_ANT_1;
|
||||
|
||||
if (BRCMS_ISNPHY(wlc->band) &&
|
||||
NREV_GE(wlc->band->phyrev, 3)
|
||||
&& NREV_LT(wlc->band->phyrev, 7)) {
|
||||
wlc->stf->phytxant = PHY_TXC_ANT_2;
|
||||
}
|
||||
} else {
|
||||
if (BRCMS_ISLCNPHY(wlc->band) ||
|
||||
BRCMS_ISSSLPNPHY(wlc->band))
|
||||
wlc->stf->phytxant = PHY_TXC_LCNPHY_ANT_LAST;
|
||||
else {
|
||||
/* catch out of sync wlc->stf->txcore */
|
||||
WARN_ON(wlc->stf->txchain <= 0);
|
||||
wlc->stf->phytxant =
|
||||
wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (txant == ANT_TX_FORCE_0)
|
||||
wlc->stf->phytxant = PHY_TXC_OLD_ANT_0;
|
||||
else if (txant == ANT_TX_FORCE_1)
|
||||
wlc->stf->phytxant = PHY_TXC_OLD_ANT_1;
|
||||
else
|
||||
wlc->stf->phytxant = PHY_TXC_OLD_ANT_LAST;
|
||||
}
|
||||
|
||||
brcms_b_txant_set(wlc->hw, wlc->stf->phytxant);
|
||||
}
|
||||
|
||||
void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc)
|
||||
{
|
||||
_brcms_c_stf_phy_txant_upd(wlc);
|
||||
}
|
||||
|
||||
void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc)
|
||||
{
|
||||
/* get available rx/tx chains */
|
||||
wlc->stf->hw_txchain = (u8) getintvar(wlc->pub->vars, "txchain");
|
||||
wlc->stf->hw_rxchain = (u8) getintvar(wlc->pub->vars, "rxchain");
|
||||
|
||||
/* these parameter are intended to be used for all PHY types */
|
||||
if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) {
|
||||
if (BRCMS_ISNPHY(wlc->band)) {
|
||||
wlc->stf->hw_txchain = TXCHAIN_DEF_NPHY;
|
||||
} else {
|
||||
wlc->stf->hw_txchain = TXCHAIN_DEF;
|
||||
}
|
||||
}
|
||||
|
||||
wlc->stf->txchain = wlc->stf->hw_txchain;
|
||||
wlc->stf->txstreams = (u8) BRCMS_BITSCNT(wlc->stf->hw_txchain);
|
||||
|
||||
if (wlc->stf->hw_rxchain == 0 || wlc->stf->hw_rxchain == 0xf) {
|
||||
if (BRCMS_ISNPHY(wlc->band)) {
|
||||
wlc->stf->hw_rxchain = RXCHAIN_DEF_NPHY;
|
||||
} else {
|
||||
wlc->stf->hw_rxchain = RXCHAIN_DEF;
|
||||
}
|
||||
}
|
||||
|
||||
wlc->stf->rxchain = wlc->stf->hw_rxchain;
|
||||
wlc->stf->rxstreams = (u8) BRCMS_BITSCNT(wlc->stf->hw_rxchain);
|
||||
|
||||
/* initialize the txcore table */
|
||||
memcpy(wlc->stf->txcore, txcore_default, sizeof(wlc->stf->txcore));
|
||||
|
||||
/* default spatial_policy */
|
||||
wlc->stf->spatial_policy = MIN_SPATIAL_EXPANSION;
|
||||
brcms_c_stf_spatial_policy_set(wlc, MIN_SPATIAL_EXPANSION);
|
||||
}
|
||||
|
||||
static u16 _brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc,
|
||||
ratespec_t rspec)
|
||||
{
|
||||
u16 phytxant = wlc->stf->phytxant;
|
||||
|
||||
if (RSPEC_STF(rspec) != PHY_TXC1_MODE_SISO) {
|
||||
phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
|
||||
} else if (wlc->stf->txant == ANT_TX_DEF)
|
||||
phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
|
||||
phytxant &= PHY_TXC_ANT_MASK;
|
||||
return phytxant;
|
||||
}
|
||||
|
||||
u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, ratespec_t rspec)
|
||||
{
|
||||
return _brcms_c_stf_phytxchain_sel(wlc, rspec);
|
||||
}
|
||||
|
||||
u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc, ratespec_t rspec)
|
||||
{
|
||||
u16 phytxant = wlc->stf->phytxant;
|
||||
u16 mask = PHY_TXC_ANT_MASK;
|
||||
|
||||
/* for non-siso rates or default setting, use the available chains */
|
||||
if (BRCMS_ISNPHY(wlc->band)) {
|
||||
phytxant = _brcms_c_stf_phytxchain_sel(wlc, rspec);
|
||||
mask = PHY_TXC_HTANT_MASK;
|
||||
}
|
||||
phytxant |= phytxant & mask;
|
||||
return phytxant;
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_STF_H_
|
||||
#define _BRCM_STF_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
extern int brcms_c_stf_attach(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_stf_detach(struct brcms_c_info *wlc);
|
||||
|
||||
extern void brcms_c_tempsense_upd(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc,
|
||||
u16 *ss_algo_channel,
|
||||
chanspec_t chanspec);
|
||||
extern int brcms_c_stf_ss_update(struct brcms_c_info *wlc,
|
||||
struct brcms_band *band);
|
||||
extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc);
|
||||
extern int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val,
|
||||
bool force);
|
||||
extern bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val);
|
||||
extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc);
|
||||
extern u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc,
|
||||
ratespec_t rspec);
|
||||
extern u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc,
|
||||
ratespec_t rspec);
|
||||
|
||||
#endif /* _BRCM_STF_H_ */
|
@ -1,399 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_TYPES_H_
|
||||
#define _BRCM_TYPES_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
/* Bus types */
|
||||
#define SI_BUS 0 /* SOC Interconnect */
|
||||
#define PCI_BUS 1 /* PCI target */
|
||||
#define SDIO_BUS 3 /* SDIO target */
|
||||
#define JTAG_BUS 4 /* JTAG */
|
||||
#define USB_BUS 5 /* USB (does not support R/W REG) */
|
||||
#define SPI_BUS 6 /* gSPI target */
|
||||
#define RPC_BUS 7 /* RPC target */
|
||||
|
||||
#define WL_CHAN_FREQ_RANGE_2G 0
|
||||
#define WL_CHAN_FREQ_RANGE_5GL 1
|
||||
#define WL_CHAN_FREQ_RANGE_5GM 2
|
||||
#define WL_CHAN_FREQ_RANGE_5GH 3
|
||||
|
||||
#define MAX_DMA_SEGS 4
|
||||
|
||||
/* boardflags */
|
||||
#define BFL_PACTRL 0x00000002 /* Board has gpio 9 controlling the PA */
|
||||
#define BFL_NOPLLDOWN 0x00000020 /* Not ok to power down the chip pll and oscillator */
|
||||
#define BFL_FEM 0x00000800 /* Board supports the Front End Module */
|
||||
#define BFL_EXTLNA 0x00001000 /* Board has an external LNA in 2.4GHz band */
|
||||
#define BFL_NOPA 0x00010000 /* Board has no PA */
|
||||
#define BFL_BUCKBOOST 0x00200000 /* Power topology uses BUCKBOOST */
|
||||
#define BFL_FEM_BT 0x00400000 /* Board has FEM and switch to share antenna w/ BT */
|
||||
#define BFL_NOCBUCK 0x00800000 /* Power topology doesn't use CBUCK */
|
||||
#define BFL_PALDO 0x02000000 /* Power topology uses PALDO */
|
||||
#define BFL_EXTLNA_5GHz 0x10000000 /* Board has an external LNA in 5GHz band */
|
||||
|
||||
/* boardflags2 */
|
||||
#define BFL2_RXBB_INT_REG_DIS 0x00000001 /* Board has an external rxbb regulator */
|
||||
#define BFL2_APLL_WAR 0x00000002 /* Flag to implement alternative A-band PLL settings */
|
||||
#define BFL2_TXPWRCTRL_EN 0x00000004 /* Board permits enabling TX Power Control */
|
||||
#define BFL2_2X4_DIV 0x00000008 /* Board supports the 2X4 diversity switch */
|
||||
#define BFL2_5G_PWRGAIN 0x00000010 /* Board supports 5G band power gain */
|
||||
#define BFL2_PCIEWAR_OVR 0x00000020 /* Board overrides ASPM and Clkreq settings */
|
||||
#define BFL2_LEGACY 0x00000080
|
||||
#define BFL2_SKWRKFEM_BRD 0x00000100 /* 4321mcm93 board uses Skyworks FEM */
|
||||
#define BFL2_SPUR_WAR 0x00000200 /* Board has a WAR for clock-harmonic spurs */
|
||||
#define BFL2_GPLL_WAR 0x00000400 /* Flag to narrow G-band PLL loop b/w */
|
||||
#define BFL2_SINGLEANT_CCK 0x00001000 /* Tx CCK pkts on Ant 0 only */
|
||||
#define BFL2_2G_SPUR_WAR 0x00002000 /* WAR to reduce and avoid clock-harmonic spurs in 2G */
|
||||
#define BFL2_GPLL_WAR2 0x00010000 /* Flag to widen G-band PLL loop b/w */
|
||||
#define BFL2_IPALVLSHIFT_3P3 0x00020000
|
||||
#define BFL2_INTERNDET_TXIQCAL 0x00040000 /* Use internal envelope detector for TX IQCAL */
|
||||
#define BFL2_XTALBUFOUTEN 0x00080000 /* Keep the buffered Xtal output from radio "ON"
|
||||
* Most drivers will turn it off without this flag
|
||||
* to save power.
|
||||
*/
|
||||
|
||||
/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */
|
||||
#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */
|
||||
#define BOARD_GPIO_12 0x1000 /* gpio 12 */
|
||||
#define BOARD_GPIO_13 0x2000 /* gpio 13 */
|
||||
|
||||
/* **** Core type/rev defaults **** */
|
||||
#define D11CONF 0x0fffffb0 /* Supported D11 revs: 4, 5, 7-27
|
||||
* also need to update wlc.h MAXCOREREV
|
||||
*/
|
||||
|
||||
#define NCONF 0x000001ff /* Supported nphy revs:
|
||||
* 0 4321a0
|
||||
* 1 4321a1
|
||||
* 2 4321b0/b1/c0/c1
|
||||
* 3 4322a0
|
||||
* 4 4322a1
|
||||
* 5 4716a0
|
||||
* 6 43222a0, 43224a0
|
||||
* 7 43226a0
|
||||
* 8 5357a0, 43236a0
|
||||
*/
|
||||
|
||||
#define LCNCONF 0x00000007 /* Supported lcnphy revs:
|
||||
* 0 4313a0, 4336a0, 4330a0
|
||||
* 1
|
||||
* 2 4330a0
|
||||
*/
|
||||
|
||||
#define SSLPNCONF 0x0000000f /* Supported sslpnphy revs:
|
||||
* 0 4329a0/k0
|
||||
* 1 4329b0/4329C0
|
||||
* 2 4319a0
|
||||
* 3 5356a0
|
||||
*/
|
||||
|
||||
/********************************************************************
|
||||
* Phy/Core Configuration. Defines macros to to check core phy/rev *
|
||||
* compile-time configuration. Defines default core support. *
|
||||
* ******************************************************************
|
||||
*/
|
||||
|
||||
/* Basic macros to check a configuration bitmask */
|
||||
|
||||
#define CONF_HAS(config, val) ((config) & (1 << (val)))
|
||||
#define CONF_MSK(config, mask) ((config) & (mask))
|
||||
#define MSK_RANGE(low, hi) ((1 << ((hi)+1)) - (1 << (low)))
|
||||
#define CONF_RANGE(config, low, hi) (CONF_MSK(config, MSK_RANGE(low, high)))
|
||||
|
||||
#define CONF_IS(config, val) ((config) == (1 << (val)))
|
||||
#define CONF_GE(config, val) ((config) & (0-(1 << (val))))
|
||||
#define CONF_GT(config, val) ((config) & (0-2*(1 << (val))))
|
||||
#define CONF_LT(config, val) ((config) & ((1 << (val))-1))
|
||||
#define CONF_LE(config, val) ((config) & (2*(1 << (val))-1))
|
||||
|
||||
/* Wrappers for some of the above, specific to config constants */
|
||||
|
||||
#define NCONF_HAS(val) CONF_HAS(NCONF, val)
|
||||
#define NCONF_MSK(mask) CONF_MSK(NCONF, mask)
|
||||
#define NCONF_IS(val) CONF_IS(NCONF, val)
|
||||
#define NCONF_GE(val) CONF_GE(NCONF, val)
|
||||
#define NCONF_GT(val) CONF_GT(NCONF, val)
|
||||
#define NCONF_LT(val) CONF_LT(NCONF, val)
|
||||
#define NCONF_LE(val) CONF_LE(NCONF, val)
|
||||
|
||||
#define LCNCONF_HAS(val) CONF_HAS(LCNCONF, val)
|
||||
#define LCNCONF_MSK(mask) CONF_MSK(LCNCONF, mask)
|
||||
#define LCNCONF_IS(val) CONF_IS(LCNCONF, val)
|
||||
#define LCNCONF_GE(val) CONF_GE(LCNCONF, val)
|
||||
#define LCNCONF_GT(val) CONF_GT(LCNCONF, val)
|
||||
#define LCNCONF_LT(val) CONF_LT(LCNCONF, val)
|
||||
#define LCNCONF_LE(val) CONF_LE(LCNCONF, val)
|
||||
|
||||
#define D11CONF_HAS(val) CONF_HAS(D11CONF, val)
|
||||
#define D11CONF_MSK(mask) CONF_MSK(D11CONF, mask)
|
||||
#define D11CONF_IS(val) CONF_IS(D11CONF, val)
|
||||
#define D11CONF_GE(val) CONF_GE(D11CONF, val)
|
||||
#define D11CONF_GT(val) CONF_GT(D11CONF, val)
|
||||
#define D11CONF_LT(val) CONF_LT(D11CONF, val)
|
||||
#define D11CONF_LE(val) CONF_LE(D11CONF, val)
|
||||
|
||||
#define PHYCONF_HAS(val) CONF_HAS(PHYTYPE, val)
|
||||
#define PHYCONF_IS(val) CONF_IS(PHYTYPE, val)
|
||||
|
||||
#define NREV_IS(var, val) (NCONF_HAS(val) && (NCONF_IS(val) || ((var) == (val))))
|
||||
#define NREV_GE(var, val) (NCONF_GE(val) && (!NCONF_LT(val) || ((var) >= (val))))
|
||||
#define NREV_GT(var, val) (NCONF_GT(val) && (!NCONF_LE(val) || ((var) > (val))))
|
||||
#define NREV_LT(var, val) (NCONF_LT(val) && (!NCONF_GE(val) || ((var) < (val))))
|
||||
#define NREV_LE(var, val) (NCONF_LE(val) && (!NCONF_GT(val) || ((var) <= (val))))
|
||||
|
||||
#define LCNREV_IS(var, val) (LCNCONF_HAS(val) && (LCNCONF_IS(val) || ((var) == (val))))
|
||||
#define LCNREV_GE(var, val) (LCNCONF_GE(val) && (!LCNCONF_LT(val) || ((var) >= (val))))
|
||||
#define LCNREV_GT(var, val) (LCNCONF_GT(val) && (!LCNCONF_LE(val) || ((var) > (val))))
|
||||
#define LCNREV_LT(var, val) (LCNCONF_LT(val) && (!LCNCONF_GE(val) || ((var) < (val))))
|
||||
#define LCNREV_LE(var, val) (LCNCONF_LE(val) && (!LCNCONF_GT(val) || ((var) <= (val))))
|
||||
|
||||
#define D11REV_IS(var, val) (D11CONF_HAS(val) && (D11CONF_IS(val) || ((var) == (val))))
|
||||
#define D11REV_GE(var, val) (D11CONF_GE(val) && (!D11CONF_LT(val) || ((var) >= (val))))
|
||||
#define D11REV_GT(var, val) (D11CONF_GT(val) && (!D11CONF_LE(val) || ((var) > (val))))
|
||||
#define D11REV_LT(var, val) (D11CONF_LT(val) && (!D11CONF_GE(val) || ((var) < (val))))
|
||||
#define D11REV_LE(var, val) (D11CONF_LE(val) && (!D11CONF_GT(val) || ((var) <= (val))))
|
||||
|
||||
#define PHYTYPE_IS(var, val) (PHYCONF_HAS(val) && (PHYCONF_IS(val) || ((var) == (val))))
|
||||
|
||||
/* Finally, early-exit from switch case if anyone wants it... */
|
||||
|
||||
#define CASECHECK(config, val) if (!(CONF_HAS(config, val))) break
|
||||
#define CASEMSK(config, mask) if (!(CONF_MSK(config, mask))) break
|
||||
|
||||
/* Set up PHYTYPE automatically: (depends on PHY_TYPE_X, from d11.h) */
|
||||
|
||||
#define _PHYCONF_N (1 << PHY_TYPE_N)
|
||||
#define _PHYCONF_LCN (1 << PHY_TYPE_LCN)
|
||||
#define _PHYCONF_SSLPN (1 << PHY_TYPE_SSN)
|
||||
|
||||
#define PHYTYPE (_PHYCONF_N | _PHYCONF_LCN | _PHYCONF_SSLPN)
|
||||
|
||||
/* Utility macro to identify 802.11n (HT) capable PHYs */
|
||||
#define PHYTYPE_11N_CAP(phytype) \
|
||||
(PHYTYPE_IS(phytype, PHY_TYPE_N) || \
|
||||
PHYTYPE_IS(phytype, PHY_TYPE_LCN) || \
|
||||
PHYTYPE_IS(phytype, PHY_TYPE_SSN))
|
||||
|
||||
/* Last but not least: shorter wlc-specific var checks */
|
||||
#define BRCMS_ISNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_N)
|
||||
#define BRCMS_ISLCNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_LCN)
|
||||
#define BRCMS_ISSSLPNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_SSN)
|
||||
|
||||
#define BRCMS_PHY_11N_CAP(band) PHYTYPE_11N_CAP((band)->phytype)
|
||||
|
||||
/**********************************************************************
|
||||
* ------------- End of Core phy/rev configuration. ----------------- *
|
||||
* ********************************************************************
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
* Defaults for tunables (e.g. sizing constants)
|
||||
*
|
||||
* For each new tunable, add a member to the end
|
||||
* of struct brcms_tunables in brcms_c_pub.h to enable
|
||||
* runtime checks of tunable values. (Directly
|
||||
* using the macros in code invalidates ROM code)
|
||||
*
|
||||
* ***********************************************
|
||||
*/
|
||||
#define NTXD 256 /* Max # of entries in Tx FIFO based on 4kb page size */
|
||||
#define NRXD 256 /* Max # of entries in Rx FIFO based on 4kb page size */
|
||||
#define NRXBUFPOST 32 /* try to keep this # rbufs posted to the chip */
|
||||
#define MAXSCB 32 /* Maximum SCBs in cache for STA */
|
||||
#define AMPDU_NUM_MPDU 16 /* max allowed number of mpdus in an ampdu (2 streams) */
|
||||
|
||||
/* Count of packet callback structures. either of following
|
||||
* 1. Set to the number of SCBs since a STA
|
||||
* can queue up a rate callback for each IBSS STA it knows about, and an AP can
|
||||
* queue up an "are you there?" Null Data callback for each associated STA
|
||||
* 2. controlled by tunable config file
|
||||
*/
|
||||
#define MAXPKTCB MAXSCB /* Max number of packet callbacks */
|
||||
|
||||
/* NetBSD also needs to keep track of this */
|
||||
|
||||
/* Number of BSS handled in ucode bcn/prb */
|
||||
#define BRCMS_MAX_UCODE_BSS (16)
|
||||
/* Number of BSS handled in sw bcn/prb */
|
||||
#define BRCMS_MAX_UCODE_BSS4 (4)
|
||||
/* max # BSS configs */
|
||||
#define BRCMS_MAXBSSCFG (1)
|
||||
/* max # available networks */
|
||||
#define MAXBSS 64
|
||||
/* data msg txq hiwat mark */
|
||||
#define BRCMS_DATAHIWAT 50
|
||||
#define BRCMS_AMPDUDATAHIWAT 255
|
||||
|
||||
/* bounded rx loops */
|
||||
#define RXBND 8 /* max # frames to process in brcms_c_recv() */
|
||||
#define TXSBND 8 /* max # tx status to process in wlc_txstatus() */
|
||||
|
||||
#define BAND_5G(bt) ((bt) == BRCM_BAND_5G)
|
||||
#define BAND_2G(bt) ((bt) == BRCM_BAND_2G)
|
||||
|
||||
#define BCMMSG(dev, fmt, args...) \
|
||||
do { \
|
||||
if (brcm_msg_level & LOG_TRACE_VAL) \
|
||||
wiphy_err(dev, "%s: " fmt, __func__, ##args); \
|
||||
} while (0)
|
||||
|
||||
#define WL_ERROR_ON() (brcm_msg_level & LOG_ERROR_VAL)
|
||||
|
||||
/* register access macros */
|
||||
#ifndef __BIG_ENDIAN
|
||||
#ifndef __mips__
|
||||
#define R_REG(r) \
|
||||
({\
|
||||
sizeof(*(r)) == sizeof(u8) ? \
|
||||
readb((u8 *)(r)) : \
|
||||
sizeof(*(r)) == sizeof(u16) ? readw((u16 *)(r)) : \
|
||||
readl((u32 *)(r)); \
|
||||
})
|
||||
#else /* __mips__ */
|
||||
#define R_REG(r) \
|
||||
({ \
|
||||
__typeof(*(r)) __osl_v; \
|
||||
__asm__ __volatile__("sync"); \
|
||||
switch (sizeof(*(r))) { \
|
||||
case sizeof(u8): \
|
||||
__osl_v = readb((u8 *)(r)); \
|
||||
break; \
|
||||
case sizeof(u16): \
|
||||
__osl_v = readw((u16 *)(r)); \
|
||||
break; \
|
||||
case sizeof(u32): \
|
||||
__osl_v = \
|
||||
readl((u32 *)(r)); \
|
||||
break; \
|
||||
} \
|
||||
__asm__ __volatile__("sync"); \
|
||||
__osl_v; \
|
||||
})
|
||||
#endif /* __mips__ */
|
||||
|
||||
#define W_REG(r, v) do { \
|
||||
switch (sizeof(*(r))) { \
|
||||
case sizeof(u8): \
|
||||
writeb((u8)(v), (u8 *)(r)); break; \
|
||||
case sizeof(u16): \
|
||||
writew((u16)(v), (u16 *)(r)); break; \
|
||||
case sizeof(u32): \
|
||||
writel((u32)(v), (u32 *)(r)); break; \
|
||||
}; \
|
||||
} while (0)
|
||||
#else /* __BIG_ENDIAN */
|
||||
#define R_REG(r) \
|
||||
({ \
|
||||
__typeof(*(r)) __osl_v; \
|
||||
switch (sizeof(*(r))) { \
|
||||
case sizeof(u8): \
|
||||
__osl_v = \
|
||||
readb((u8 *)((r)^3)); \
|
||||
break; \
|
||||
case sizeof(u16): \
|
||||
__osl_v = \
|
||||
readw((u16 *)((r)^2)); \
|
||||
break; \
|
||||
case sizeof(u32): \
|
||||
__osl_v = readl((u32 *)(r)); \
|
||||
break; \
|
||||
} \
|
||||
__osl_v; \
|
||||
})
|
||||
|
||||
#define W_REG(r, v) do { \
|
||||
switch (sizeof(*(r))) { \
|
||||
case sizeof(u8): \
|
||||
writeb((u8)(v), \
|
||||
(u8 *)((r)^3)); break; \
|
||||
case sizeof(u16): \
|
||||
writew((u16)(v), \
|
||||
(u16 *)((r)^2)); break; \
|
||||
case sizeof(u32): \
|
||||
writel((u32)(v), \
|
||||
(u32 *)(r)); break; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif /* __BIG_ENDIAN */
|
||||
|
||||
#ifdef __mips__
|
||||
/*
|
||||
* bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder
|
||||
* transactions. As a fix, a read after write is performed on certain places
|
||||
* in the code. Older chips and the newer 5357 family don't require this fix.
|
||||
*/
|
||||
#define W_REG_FLUSH(r, v) ({ W_REG((r), (v)); (void)R_REG(r); })
|
||||
#else
|
||||
#define W_REG_FLUSH(r, v) W_REG((r), (v))
|
||||
#endif /* __mips__ */
|
||||
|
||||
#define AND_REG(r, v) W_REG((r), R_REG(r) & (v))
|
||||
#define OR_REG(r, v) W_REG((r), R_REG(r) | (v))
|
||||
|
||||
#define SET_REG(r, mask, val) \
|
||||
W_REG((r), ((R_REG(r) & ~(mask)) | (val)))
|
||||
|
||||
/* multi-bool data type: set of bools, mbool is true if any is set */
|
||||
typedef u32 mbool;
|
||||
#define mboolset(mb, bit) ((mb) |= (bit)) /* set one bool */
|
||||
#define mboolclr(mb, bit) ((mb) &= ~(bit)) /* clear one bool */
|
||||
#define mboolisset(mb, bit) (((mb) & (bit)) != 0) /* true if one bool is set */
|
||||
#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val)))
|
||||
|
||||
/* forward declarations */
|
||||
struct wiphy;
|
||||
struct ieee80211_sta;
|
||||
struct ieee80211_tx_queue_params;
|
||||
struct brcms_info;
|
||||
struct brcms_c_info;
|
||||
struct brcms_hardware;
|
||||
struct brcms_c_if;
|
||||
struct brcmu_iovar;
|
||||
struct brcmu_strbuf;
|
||||
struct brcms_txq_info;
|
||||
struct brcms_band;
|
||||
struct dma_pub;
|
||||
struct si_pub;
|
||||
struct tx_status;
|
||||
struct d11rxhdr;
|
||||
struct brcms_d11rxhdr;
|
||||
struct txpwr_limits;
|
||||
struct brcms_phy;
|
||||
|
||||
typedef volatile struct intctrlregs intctrlregs_t;
|
||||
typedef volatile struct pio2regs pio2regs_t;
|
||||
typedef volatile struct pio2regp pio2regp_t;
|
||||
typedef volatile struct pio4regs pio4regs_t;
|
||||
typedef volatile struct pio4regp pio4regp_t;
|
||||
typedef volatile struct fifo64 fifo64_t;
|
||||
typedef volatile struct d11regs d11regs_t;
|
||||
typedef volatile struct dma32diag dma32diag_t;
|
||||
typedef volatile struct dma64regs dma64regs_t;
|
||||
typedef struct brcms_rateset wlc_rateset_t;
|
||||
typedef u32 ratespec_t;
|
||||
typedef struct chanvec chanvec_t;
|
||||
typedef s32 fixed;
|
||||
typedef struct _cs32 cs32;
|
||||
typedef volatile union pmqreg pmqreg_t;
|
||||
|
||||
/* brcm_msg_level is a bit vector with defs in defs.h */
|
||||
extern u32 brcm_msg_level;
|
||||
|
||||
#endif /* _BRCM_TYPES_H_ */
|
@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <defs.h>
|
||||
#include "types.h"
|
||||
#include <ucode_loader.h>
|
||||
|
||||
enum {
|
||||
D11UCODE_NAMETAG_START = 0,
|
||||
D11LCN0BSINITVALS24,
|
||||
D11LCN0INITVALS24,
|
||||
D11LCN1BSINITVALS24,
|
||||
D11LCN1INITVALS24,
|
||||
D11LCN2BSINITVALS24,
|
||||
D11LCN2INITVALS24,
|
||||
D11N0ABSINITVALS16,
|
||||
D11N0BSINITVALS16,
|
||||
D11N0INITVALS16,
|
||||
D11UCODE_OVERSIGHT16_MIMO,
|
||||
D11UCODE_OVERSIGHT16_MIMOSZ,
|
||||
D11UCODE_OVERSIGHT24_LCN,
|
||||
D11UCODE_OVERSIGHT24_LCNSZ,
|
||||
D11UCODE_OVERSIGHT_BOMMAJOR,
|
||||
D11UCODE_OVERSIGHT_BOMMINOR
|
||||
};
|
||||
|
||||
struct d11init *d11lcn0bsinitvals24;
|
||||
struct d11init *d11lcn0initvals24;
|
||||
struct d11init *d11lcn1bsinitvals24;
|
||||
struct d11init *d11lcn1initvals24;
|
||||
struct d11init *d11lcn2bsinitvals24;
|
||||
struct d11init *d11lcn2initvals24;
|
||||
struct d11init *d11n0absinitvals16;
|
||||
struct d11init *d11n0bsinitvals16;
|
||||
struct d11init *d11n0initvals16;
|
||||
u32 *bcm43xx_16_mimo;
|
||||
u32 bcm43xx_16_mimosz;
|
||||
u32 *bcm43xx_24_lcn;
|
||||
u32 bcm43xx_24_lcnsz;
|
||||
u32 *bcm43xx_bommajor;
|
||||
u32 *bcm43xx_bomminor;
|
||||
|
||||
int brcms_ucode_data_init(struct brcms_info *wl)
|
||||
{
|
||||
int rc;
|
||||
rc = brcms_check_firmwares(wl);
|
||||
|
||||
rc = rc < 0 ? rc :
|
||||
brcms_ucode_init_buf(wl, (void **)&d11lcn0bsinitvals24,
|
||||
D11LCN0BSINITVALS24);
|
||||
rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&d11lcn0initvals24,
|
||||
D11LCN0INITVALS24);
|
||||
rc = rc < 0 ? rc :
|
||||
brcms_ucode_init_buf(wl, (void **)&d11lcn1bsinitvals24,
|
||||
D11LCN1BSINITVALS24);
|
||||
rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&d11lcn1initvals24,
|
||||
D11LCN1INITVALS24);
|
||||
rc = rc < 0 ? rc :
|
||||
brcms_ucode_init_buf(wl, (void **)&d11lcn2bsinitvals24,
|
||||
D11LCN2BSINITVALS24);
|
||||
rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&d11lcn2initvals24,
|
||||
D11LCN2INITVALS24);
|
||||
rc = rc < 0 ? rc :
|
||||
brcms_ucode_init_buf(wl, (void **)&d11n0absinitvals16,
|
||||
D11N0ABSINITVALS16);
|
||||
rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&d11n0bsinitvals16,
|
||||
D11N0BSINITVALS16);
|
||||
rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&d11n0initvals16,
|
||||
D11N0INITVALS16);
|
||||
rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&bcm43xx_16_mimo,
|
||||
D11UCODE_OVERSIGHT16_MIMO);
|
||||
rc = rc < 0 ? rc : brcms_ucode_init_uint(wl, &bcm43xx_16_mimosz,
|
||||
D11UCODE_OVERSIGHT16_MIMOSZ);
|
||||
rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&bcm43xx_24_lcn,
|
||||
D11UCODE_OVERSIGHT24_LCN);
|
||||
rc = rc < 0 ? rc : brcms_ucode_init_uint(wl, &bcm43xx_24_lcnsz,
|
||||
D11UCODE_OVERSIGHT24_LCNSZ);
|
||||
rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&bcm43xx_bommajor,
|
||||
D11UCODE_OVERSIGHT_BOMMAJOR);
|
||||
rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&bcm43xx_bomminor,
|
||||
D11UCODE_OVERSIGHT_BOMMINOR);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void brcms_ucode_data_free(void)
|
||||
{
|
||||
brcms_ucode_free_buf((void *)d11lcn0bsinitvals24);
|
||||
brcms_ucode_free_buf((void *)d11lcn0initvals24);
|
||||
brcms_ucode_free_buf((void *)d11lcn1bsinitvals24);
|
||||
brcms_ucode_free_buf((void *)d11lcn1initvals24);
|
||||
brcms_ucode_free_buf((void *)d11lcn2bsinitvals24);
|
||||
brcms_ucode_free_buf((void *)d11lcn2initvals24);
|
||||
brcms_ucode_free_buf((void *)d11n0absinitvals16);
|
||||
brcms_ucode_free_buf((void *)d11n0bsinitvals16);
|
||||
brcms_ucode_free_buf((void *)d11n0initvals16);
|
||||
brcms_ucode_free_buf((void *)bcm43xx_16_mimo);
|
||||
brcms_ucode_free_buf((void *)bcm43xx_24_lcn);
|
||||
brcms_ucode_free_buf((void *)bcm43xx_bommajor);
|
||||
brcms_ucode_free_buf((void *)bcm43xx_bomminor);
|
||||
|
||||
return;
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "types.h" /* forward structure declarations */
|
||||
|
||||
#define MIN_FW_SIZE 40000 /* minimum firmware file size in bytes */
|
||||
#define MAX_FW_SIZE 150000
|
||||
|
||||
#define UCODE_LOADER_API_VER 0
|
||||
|
||||
struct d11init {
|
||||
u16 addr;
|
||||
u16 size;
|
||||
u32 value;
|
||||
};
|
||||
|
||||
extern struct d11init *d11lcn0bsinitvals24;
|
||||
extern struct d11init *d11lcn0initvals24;
|
||||
extern struct d11init *d11lcn1bsinitvals24;
|
||||
extern struct d11init *d11lcn1initvals24;
|
||||
extern struct d11init *d11lcn2bsinitvals24;
|
||||
extern struct d11init *d11lcn2initvals24;
|
||||
extern struct d11init *d11n0absinitvals16;
|
||||
extern struct d11init *d11n0bsinitvals16;
|
||||
extern struct d11init *d11n0initvals16;
|
||||
extern u32 *bcm43xx_16_mimo;
|
||||
extern u32 bcm43xx_16_mimosz;
|
||||
extern u32 *bcm43xx_24_lcn;
|
||||
extern u32 bcm43xx_24_lcnsz;
|
||||
|
||||
extern int brcms_ucode_data_init(struct brcms_info *wl);
|
||||
extern void brcms_ucode_data_free(void);
|
||||
|
||||
extern int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf,
|
||||
unsigned int idx);
|
||||
extern int brcms_ucode_init_uint(struct brcms_info *wl, unsigned *data,
|
||||
unsigned int idx);
|
||||
extern void brcms_ucode_free_buf(void *);
|
||||
extern int brcms_check_firmwares(struct brcms_info *wl);
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user