* '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
Unified · Split
| @@ -6171,7 +6171,7 @@ S: Maintained · 6170 unmodified lines | ||
| 6171 | 6171 | |
| 6172 | 6172 | STAGING SUBSYSTEM |
| 6173 | 6173 | M: Greg Kroah-Hartman <gregkh@suse.de> |
| 6174 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6.git | |
| 6174 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git | |
| 6175 | 6175 | L: devel@driverdev.osuosl.org |
| 6176 | 6176 | S: Maintained |
| 6177 | 6177 | F: drivers/staging/ |
| @@ -6212,6 +6212,11 @@ M: David Rowe <david@rowetel.com> · 34 unmodified lines | ||
| 6212 | 6212 | S: Odd Fixes |
| 6213 | 6213 | F: drivers/staging/echo/ |
| 6214 | 6214 | |
| 6215 | +STAGING - ET131X NETWORK DRIVER | |
| 6216 | +M: Mark Einon <mark.einon@gmail.com> | |
| 6217 | +S: Odd Fixes | |
| 6218 | +F: drivers/staging/et131x/ | |
| 6219 | + | |
| 6215 | 6220 | STAGING - FLARION FT1000 DRIVERS |
| 6216 | 6221 | M: Marek Belisko <marek.belisko@gmail.com> |
| 6217 | 6222 | S: Odd Fixes |
| @@ -6240,6 +6245,13 @@ W: http://www.lirc.org/ · 22 unmodified lines | ||
| 6240 | 6245 | S: Odd Fixes |
| 6241 | 6246 | F: drivers/staging/lirc/ |
| 6242 | 6247 | |
| 6248 | +STAGING - NVIDIA COMPLIANT EMBEDDED CONTROLLER INTERFACE (nvec) | |
| 6249 | +M: Julian Andres Klode <jak@jak-linux.org> | |
| 6250 | +M: Marc Dietrich <marvin24@gmx.de> | |
| 6251 | +L: ac100@lists.launchpad.net (moderated for non-subscribers) | |
| 6252 | +S: Maintained | |
| 6253 | +F: drivers/staging/nvec/ | |
| 6254 | + | |
| 6243 | 6255 | STAGING - OLPC SECONDARY DISPLAY CONTROLLER (DCON) |
| 6244 | 6256 | M: Andres Salomon <dilinger@queued.net> |
| 6245 | 6257 | M: Chris Ball <cjb@laptop.org> |
| @@ -189,5 +189,6 @@ · 188 unmodified lines | ||
| 189 | 189 | #define HV_STATUS_INVALID_HYPERCALL_CODE 2 |
| 190 | 190 | #define HV_STATUS_INVALID_HYPERCALL_INPUT 3 |
| 191 | 191 | #define HV_STATUS_INVALID_ALIGNMENT 4 |
| 192 | +#define HV_STATUS_INSUFFICIENT_BUFFERS 19 | |
| 192 | 193 | |
| 193 | 194 | #endif |
| @@ -132,6 +132,8 @@ source "drivers/iommu/Kconfig" · 131 unmodified lines | ||
| 132 | 132 | |
| 133 | 133 | source "drivers/virt/Kconfig" |
| 134 | 134 | |
| 135 | +source "drivers/hv/Kconfig" | |
| 136 | + | |
| 135 | 137 | source "drivers/devfreq/Kconfig" |
| 136 | 138 | |
| 137 | 139 | endmenu |
| @@ -129,5 +129,6 @@ obj-$(CONFIG_IOMMU_SUPPORT) += iommu/ · 128 unmodified lines | ||
| 129 | 129 | |
| 130 | 130 | # Virtualization drivers |
| 131 | 131 | obj-$(CONFIG_VIRT_DRIVERS) += virt/ |
| 132 | +obj-$(CONFIG_HYPERV) += hv/ | |
| 132 | 133 | |
| 133 | 134 | obj-$(CONFIG_PM_DEVFREQ) += devfreq/ |
| @@ -1,613 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * atari_SCC.h: Definitions for the Am8530 Serial Communications Controller | |
| 3 | − * | |
| 4 | − * Copyright 1994 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> | |
| 5 | − * | |
| 6 | − * This file is subject to the terms and conditions of the GNU General Public | |
| 7 | − * License. See the file COPYING in the main directory of this archive | |
| 8 | − * for more details. | |
| 9 | − * | |
| 10 | − */ | |
| 11 | − | |
| 12 | − | |
| 13 | −#ifndef _SCC_H | |
| 14 | −#define _SCC_H | |
| 15 | − | |
| 16 | −#include <linux/delay.h> | |
| 17 | − | |
| 18 | −/* Special configuration ioctls for the Atari SCC5380 Serial | |
| 19 | − * Communications Controller | |
| 20 | − */ | |
| 21 | − | |
| 22 | −/* ioctl command codes */ | |
| 23 | − | |
| 24 | −#define TIOCGATSCC 0x54c0 /* get SCC configuration */ | |
| 25 | −#define TIOCSATSCC 0x54c1 /* set SCC configuration */ | |
| 26 | −#define TIOCDATSCC 0x54c2 /* reset configuration to defaults */ | |
| 27 | − | |
| 28 | −/* Clock sources */ | |
| 29 | − | |
| 30 | −#define CLK_RTxC 0 | |
| 31 | −#define CLK_TRxC 1 | |
| 32 | −#define CLK_PCLK 2 | |
| 33 | − | |
| 34 | −/* baud_bases for the common clocks in the Atari. These are the real | |
| 35 | − * frequencies divided by 16. | |
| 36 | − */ | |
| 37 | − | |
| 38 | −#define SCC_BAUD_BASE_TIMC 19200 /* 0.3072 MHz from TT-MFP, Timer C */ | |
| 39 | −#define SCC_BAUD_BASE_BCLK 153600 /* 2.4576 MHz */ | |
| 40 | −#define SCC_BAUD_BASE_PCLK4 229500 /* 3.6720 MHz */ | |
| 41 | −#define SCC_BAUD_BASE_PCLK 503374 /* 8.0539763 MHz */ | |
| 42 | −#define SCC_BAUD_BASE_NONE 0 /* for not connected or unused | |
| 43 | − * clock sources */ | |
| 44 | − | |
| 45 | −/* The SCC clock configuration structure */ | |
| 46 | − | |
| 47 | −struct scc_clock_config { | |
| 48 | − unsigned RTxC_base; /* base_baud of RTxC */ | |
| 49 | − unsigned TRxC_base; /* base_baud of TRxC */ | |
| 50 | − unsigned PCLK_base; /* base_baud of PCLK, both channels! */ | |
| 51 | − struct { | |
| 52 | − unsigned clksrc; /* CLK_RTxC, CLK_TRxC or CLK_PCLK */ | |
| 53 | − unsigned divisor; /* divisor for base baud, valid values: | |
| 54 | − * see below */ | |
| 55 | − } baud_table[17]; /* For 50, 75, 110, 135, 150, 200, 300, | |
| 56 | − * 600, 1200, 1800, 2400, 4800, 9600, | |
| 57 | − * 19200, 38400, 57600 and 115200 bps. | |
| 58 | − * The last two could be replaced by | |
| 59 | − * other rates > 38400 if they're not | |
| 60 | − * possible. | |
| 61 | − */ | |
| 62 | −}; | |
| 63 | − | |
| 64 | −/* The following divisors are valid: | |
| 65 | − * | |
| 66 | − * - CLK_RTxC: 1 or even (1, 2 and 4 are the direct modes, > 4 use | |
| 67 | − * the BRG) | |
| 68 | − * | |
| 69 | − * - CLK_TRxC: 1, 2 or 4 (no BRG, only direct modes possible) | |
| 70 | − * | |
| 71 | − * - CLK_PCLK: >= 4 and even (no direct modes, only BRG) | |
| 72 | − * | |
| 73 | − */ | |
| 74 | − | |
| 75 | −struct scc_port { | |
| 76 | − struct gs_port gs; | |
| 77 | − volatile unsigned char *ctrlp; | |
| 78 | − volatile unsigned char *datap; | |
| 79 | − int x_char; /* xon/xoff character */ | |
| 80 | − int c_dcd; | |
| 81 | − int channel; | |
| 82 | − struct scc_port *port_a; /* Reference to port A and B */ | |
| 83 | − struct scc_port *port_b; /* structs for reg access */ | |
| 84 | −}; | |
| 85 | − | |
| 86 | −#define SCC_MAGIC 0x52696368 | |
| 87 | − | |
| 88 | −/***********************************************************************/ | |
| 89 | −/* */ | |
| 90 | −/* Register Names */ | |
| 91 | −/* */ | |
| 92 | −/***********************************************************************/ | |
| 93 | − | |
| 94 | −/* The SCC documentation gives no explicit names to the registers, | |
| 95 | − * they're just called WR0..15 and RR0..15. To make the source code | |
| 96 | − * better readable and make the transparent write reg read access (see | |
| 97 | − * below) possible, I christen them here with self-invented names. | |
| 98 | − * Note that (real) read registers are assigned numbers 16..31. WR7' | |
| 99 | − * has number 33. | |
| 100 | − */ | |
| 101 | − | |
| 102 | −#define COMMAND_REG 0 /* wo */ | |
| 103 | −#define INT_AND_DMA_REG 1 /* wo */ | |
| 104 | −#define INT_VECTOR_REG 2 /* rw, common to both channels */ | |
| 105 | −#define RX_CTRL_REG 3 /* rw */ | |
| 106 | −#define AUX1_CTRL_REG 4 /* rw */ | |
| 107 | −#define TX_CTRL_REG 5 /* rw */ | |
| 108 | −#define SYNC_ADR_REG 6 /* wo */ | |
| 109 | −#define SYNC_CHAR_REG 7 /* wo */ | |
| 110 | −#define SDLC_OPTION_REG 33 /* wo */ | |
| 111 | −#define TX_DATA_REG 8 /* wo */ | |
| 112 | −#define MASTER_INT_CTRL 9 /* wo, common to both channels */ | |
| 113 | −#define AUX2_CTRL_REG 10 /* rw */ | |
| 114 | −#define CLK_CTRL_REG 11 /* wo */ | |
| 115 | −#define TIMER_LOW_REG 12 /* rw */ | |
| 116 | −#define TIMER_HIGH_REG 13 /* rw */ | |
| 117 | −#define DPLL_CTRL_REG 14 /* wo */ | |
| 118 | −#define INT_CTRL_REG 15 /* rw */ | |
| 119 | − | |
| 120 | −#define STATUS_REG 16 /* ro */ | |
| 121 | −#define SPCOND_STATUS_REG 17 /* wo */ | |
| 122 | −/* RR2 is WR2 for Channel A, Channel B gives vector + current status: */ | |
| 123 | −#define CURR_VECTOR_REG 18 /* Ch. B only, Ch. A for rw */ | |
| 124 | −#define INT_PENDING_REG 19 /* Channel A only! */ | |
| 125 | −/* RR4 is WR4, if b6(MR7') == 1 */ | |
| 126 | −/* RR5 is WR5, if b6(MR7') == 1 */ | |
| 127 | −#define FS_FIFO_LOW_REG 22 /* ro */ | |
| 128 | −#define FS_FIFO_HIGH_REG 23 /* ro */ | |
| 129 | −#define RX_DATA_REG 24 /* ro */ | |
| 130 | −/* RR9 is WR3, if b6(MR7') == 1 */ | |
| 131 | −#define DPLL_STATUS_REG 26 /* ro */ | |
| 132 | −/* RR11 is WR10, if b6(MR7') == 1 */ | |
| 133 | −/* RR12 is WR12 */ | |
| 134 | −/* RR13 is WR13 */ | |
| 135 | −/* RR14 not present */ | |
| 136 | −/* RR15 is WR15 */ | |
| 137 | − | |
| 138 | − | |
| 139 | −/***********************************************************************/ | |
| 140 | −/* */ | |
| 141 | −/* Register Values */ | |
| 142 | −/* */ | |
| 143 | −/***********************************************************************/ | |
| 144 | − | |
| 145 | − | |
| 146 | −/* WR0: COMMAND_REG "CR" */ | |
| 147 | − | |
| 148 | −#define CR_RX_CRC_RESET 0x40 | |
| 149 | −#define CR_TX_CRC_RESET 0x80 | |
| 150 | −#define CR_TX_UNDERRUN_RESET 0xc0 | |
| 151 | − | |
| 152 | −#define CR_EXTSTAT_RESET 0x10 | |
| 153 | −#define CR_SEND_ABORT 0x18 | |
| 154 | −#define CR_ENAB_INT_NEXT_RX 0x20 | |
| 155 | −#define CR_TX_PENDING_RESET 0x28 | |
| 156 | −#define CR_ERROR_RESET 0x30 | |
| 157 | −#define CR_HIGHEST_IUS_RESET 0x38 | |
| 158 | − | |
| 159 | − | |
| 160 | −/* WR1: INT_AND_DMA_REG "IDR" */ | |
| 161 | − | |
| 162 | −#define IDR_EXTSTAT_INT_ENAB 0x01 | |
| 163 | −#define IDR_TX_INT_ENAB 0x02 | |
| 164 | −#define IDR_PARERR_AS_SPCOND 0x04 | |
| 165 | − | |
| 166 | −#define IDR_RX_INT_DISAB 0x00 | |
| 167 | −#define IDR_RX_INT_FIRST 0x08 | |
| 168 | −#define IDR_RX_INT_ALL 0x10 | |
| 169 | −#define IDR_RX_INT_SPCOND 0x18 | |
| 170 | −#define IDR_RX_INT_MASK 0x18 | |
| 171 | − | |
| 172 | −#define IDR_WAITREQ_RX 0x20 | |
| 173 | −#define IDR_WAITREQ_IS_REQ 0x40 | |
| 174 | −#define IDR_WAITREQ_ENAB 0x80 | |
| 175 | − | |
| 176 | − | |
| 177 | −/* WR3: RX_CTRL_REG "RCR" */ | |
| 178 | − | |
| 179 | −#define RCR_RX_ENAB 0x01 | |
| 180 | −#define RCR_DISCARD_SYNC_CHARS 0x02 | |
| 181 | −#define RCR_ADDR_SEARCH 0x04 | |
| 182 | −#define RCR_CRC_ENAB 0x08 | |
| 183 | −#define RCR_SEARCH_MODE 0x10 | |
| 184 | −#define RCR_AUTO_ENAB_MODE 0x20 | |
| 185 | − | |
| 186 | −#define RCR_CHSIZE_MASK 0xc0 | |
| 187 | −#define RCR_CHSIZE_5 0x00 | |
| 188 | −#define RCR_CHSIZE_6 0x40 | |
| 189 | −#define RCR_CHSIZE_7 0x80 | |
| 190 | −#define RCR_CHSIZE_8 0xc0 | |
| 191 | − | |
| 192 | − | |
| 193 | −/* WR4: AUX1_CTRL_REG "A1CR" */ | |
| 194 | − | |
| 195 | −#define A1CR_PARITY_MASK 0x03 | |
| 196 | −#define A1CR_PARITY_NONE 0x00 | |
| 197 | −#define A1CR_PARITY_ODD 0x01 | |
| 198 | −#define A1CR_PARITY_EVEN 0x03 | |
| 199 | − | |
| 200 | −#define A1CR_MODE_MASK 0x0c | |
| 201 | −#define A1CR_MODE_SYNCR 0x00 | |
| 202 | −#define A1CR_MODE_ASYNC_1 0x04 | |
| 203 | −#define A1CR_MODE_ASYNC_15 0x08 | |
| 204 | −#define A1CR_MODE_ASYNC_2 0x0c | |
| 205 | − | |
| 206 | −#define A1CR_SYNCR_MODE_MASK 0x30 | |
| 207 | −#define A1CR_SYNCR_MONOSYNC 0x00 | |
| 208 | −#define A1CR_SYNCR_BISYNC 0x10 | |
| 209 | −#define A1CR_SYNCR_SDLC 0x20 | |
| 210 | −#define A1CR_SYNCR_EXTCSYNC 0x30 | |
| 211 | − | |
| 212 | −#define A1CR_CLKMODE_MASK 0xc0 | |
| 213 | −#define A1CR_CLKMODE_x1 0x00 | |
| 214 | −#define A1CR_CLKMODE_x16 0x40 | |
| 215 | −#define A1CR_CLKMODE_x32 0x80 | |
| 216 | −#define A1CR_CLKMODE_x64 0xc0 | |
| 217 | − | |
| 218 | − | |
| 219 | −/* WR5: TX_CTRL_REG "TCR" */ | |
| 220 | − | |
| 221 | −#define TCR_TX_CRC_ENAB 0x01 | |
| 222 | −#define TCR_RTS 0x02 | |
| 223 | −#define TCR_USE_CRC_CCITT 0x00 | |
| 224 | −#define TCR_USE_CRC_16 0x04 | |
| 225 | −#define TCR_TX_ENAB 0x08 | |
| 226 | −#define TCR_SEND_BREAK 0x10 | |
| 227 | − | |
| 228 | −#define TCR_CHSIZE_MASK 0x60 | |
| 229 | −#define TCR_CHSIZE_5 0x00 | |
| 230 | −#define TCR_CHSIZE_6 0x20 | |
| 231 | −#define TCR_CHSIZE_7 0x40 | |
| 232 | −#define TCR_CHSIZE_8 0x60 | |
| 233 | − | |
| 234 | −#define TCR_DTR 0x80 | |
| 235 | − | |
| 236 | − | |
| 237 | −/* WR7': SLDC_OPTION_REG "SOR" */ | |
| 238 | − | |
| 239 | −#define SOR_AUTO_TX_ENAB 0x01 | |
| 240 | −#define SOR_AUTO_EOM_RESET 0x02 | |
| 241 | −#define SOR_AUTO_RTS_MODE 0x04 | |
| 242 | −#define SOR_NRZI_DISAB_HIGH 0x08 | |
| 243 | −#define SOR_ALT_DTRREQ_TIMING 0x10 | |
| 244 | −#define SOR_READ_CRC_CHARS 0x20 | |
| 245 | −#define SOR_EXTENDED_REG_ACCESS 0x40 | |
| 246 | − | |
| 247 | − | |
| 248 | −/* WR9: MASTER_INT_CTRL "MIC" */ | |
| 249 | − | |
| 250 | −#define MIC_VEC_INCL_STAT 0x01 | |
| 251 | −#define MIC_NO_VECTOR 0x02 | |
| 252 | −#define MIC_DISAB_LOWER_CHAIN 0x04 | |
| 253 | −#define MIC_MASTER_INT_ENAB 0x08 | |
| 254 | −#define MIC_STATUS_HIGH 0x10 | |
| 255 | −#define MIC_IGN_INTACK 0x20 | |
| 256 | − | |
| 257 | −#define MIC_NO_RESET 0x00 | |
| 258 | −#define MIC_CH_A_RESET 0x40 | |
| 259 | −#define MIC_CH_B_RESET 0x80 | |
| 260 | −#define MIC_HARD_RESET 0xc0 | |
| 261 | − | |
| 262 | − | |
| 263 | −/* WR10: AUX2_CTRL_REG "A2CR" */ | |
| 264 | − | |
| 265 | −#define A2CR_SYNC_6 0x01 | |
| 266 | −#define A2CR_LOOP_MODE 0x02 | |
| 267 | −#define A2CR_ABORT_ON_UNDERRUN 0x04 | |
| 268 | −#define A2CR_MARK_IDLE 0x08 | |
| 269 | −#define A2CR_GO_ACTIVE_ON_POLL 0x10 | |
| 270 | − | |
| 271 | −#define A2CR_CODING_MASK 0x60 | |
| 272 | −#define A2CR_CODING_NRZ 0x00 | |
| 273 | −#define A2CR_CODING_NRZI 0x20 | |
| 274 | −#define A2CR_CODING_FM1 0x40 | |
| 275 | −#define A2CR_CODING_FM0 0x60 | |
| 276 | − | |
| 277 | −#define A2CR_PRESET_CRC_1 0x80 | |
| 278 | − | |
| 279 | − | |
| 280 | −/* WR11: CLK_CTRL_REG "CCR" */ | |
| 281 | − | |
| 282 | −#define CCR_TRxCOUT_MASK 0x03 | |
| 283 | −#define CCR_TRxCOUT_XTAL 0x00 | |
| 284 | −#define CCR_TRxCOUT_TXCLK 0x01 | |
| 285 | −#define CCR_TRxCOUT_BRG 0x02 | |
| 286 | −#define CCR_TRxCOUT_DPLL 0x03 | |
| 287 | − | |
| 288 | −#define CCR_TRxC_OUTPUT 0x04 | |
| 289 | − | |
| 290 | −#define CCR_TXCLK_MASK 0x18 | |
| 291 | −#define CCR_TXCLK_RTxC 0x00 | |
| 292 | −#define CCR_TXCLK_TRxC 0x08 | |
| 293 | −#define CCR_TXCLK_BRG 0x10 | |
| 294 | −#define CCR_TXCLK_DPLL 0x18 | |
| 295 | − | |
| 296 | −#define CCR_RXCLK_MASK 0x60 | |
| 297 | −#define CCR_RXCLK_RTxC 0x00 | |
| 298 | −#define CCR_RXCLK_TRxC 0x20 | |
| 299 | −#define CCR_RXCLK_BRG 0x40 | |
| 300 | −#define CCR_RXCLK_DPLL 0x60 | |
| 301 | − | |
| 302 | −#define CCR_RTxC_XTAL 0x80 | |
| 303 | − | |
| 304 | − | |
| 305 | −/* WR14: DPLL_CTRL_REG "DCR" */ | |
| 306 | − | |
| 307 | −#define DCR_BRG_ENAB 0x01 | |
| 308 | −#define DCR_BRG_USE_PCLK 0x02 | |
| 309 | −#define DCR_DTRREQ_IS_REQ 0x04 | |
| 310 | −#define DCR_AUTO_ECHO 0x08 | |
| 311 | −#define DCR_LOCAL_LOOPBACK 0x10 | |
| 312 | − | |
| 313 | −#define DCR_DPLL_EDGE_SEARCH 0x20 | |
| 314 | −#define DCR_DPLL_ERR_RESET 0x40 | |
| 315 | −#define DCR_DPLL_DISAB 0x60 | |
| 316 | −#define DCR_DPLL_CLK_BRG 0x80 | |
| 317 | −#define DCR_DPLL_CLK_RTxC 0xa0 | |
| 318 | −#define DCR_DPLL_FM 0xc0 | |
| 319 | −#define DCR_DPLL_NRZI 0xe0 | |
| 320 | − | |
| 321 | − | |
| 322 | −/* WR15: INT_CTRL_REG "ICR" */ | |
| 323 | − | |
| 324 | −#define ICR_OPTIONREG_SELECT 0x01 | |
| 325 | −#define ICR_ENAB_BRG_ZERO_INT 0x02 | |
| 326 | −#define ICR_USE_FS_FIFO 0x04 | |
| 327 | −#define ICR_ENAB_DCD_INT 0x08 | |
| 328 | −#define ICR_ENAB_SYNC_INT 0x10 | |
| 329 | −#define ICR_ENAB_CTS_INT 0x20 | |
| 330 | −#define ICR_ENAB_UNDERRUN_INT 0x40 | |
| 331 | −#define ICR_ENAB_BREAK_INT 0x80 | |
| 332 | − | |
| 333 | − | |
| 334 | −/* RR0: STATUS_REG "SR" */ | |
| 335 | − | |
| 336 | −#define SR_CHAR_AVAIL 0x01 | |
| 337 | −#define SR_BRG_ZERO 0x02 | |
| 338 | −#define SR_TX_BUF_EMPTY 0x04 | |
| 339 | −#define SR_DCD 0x08 | |
| 340 | −#define SR_SYNC_ABORT 0x10 | |
| 341 | −#define SR_CTS 0x20 | |
| 342 | −#define SR_TX_UNDERRUN 0x40 | |
| 343 | −#define SR_BREAK 0x80 | |
| 344 | − | |
| 345 | − | |
| 346 | −/* RR1: SPCOND_STATUS_REG "SCSR" */ | |
| 347 | − | |
| 348 | −#define SCSR_ALL_SENT 0x01 | |
| 349 | −#define SCSR_RESIDUAL_MASK 0x0e | |
| 350 | −#define SCSR_PARITY_ERR 0x10 | |
| 351 | −#define SCSR_RX_OVERRUN 0x20 | |
| 352 | −#define SCSR_CRC_FRAME_ERR 0x40 | |
| 353 | −#define SCSR_END_OF_FRAME 0x80 | |
| 354 | − | |
| 355 | − | |
| 356 | −/* RR3: INT_PENDING_REG "IPR" */ | |
| 357 | − | |
| 358 | −#define IPR_B_EXTSTAT 0x01 | |
| 359 | −#define IPR_B_TX 0x02 | |
| 360 | −#define IPR_B_RX 0x04 | |
| 361 | −#define IPR_A_EXTSTAT 0x08 | |
| 362 | −#define IPR_A_TX 0x10 | |
| 363 | −#define IPR_A_RX 0x20 | |
| 364 | − | |
| 365 | − | |
| 366 | −/* RR7: FS_FIFO_HIGH_REG "FFHR" */ | |
| 367 | − | |
| 368 | −#define FFHR_CNT_MASK 0x3f | |
| 369 | −#define FFHR_IS_FROM_FIFO 0x40 | |
| 370 | −#define FFHR_FIFO_OVERRUN 0x80 | |
| 371 | − | |
| 372 | − | |
| 373 | −/* RR10: DPLL_STATUS_REG "DSR" */ | |
| 374 | − | |
| 375 | −#define DSR_ON_LOOP 0x02 | |
| 376 | −#define DSR_ON_LOOP_SENDING 0x10 | |
| 377 | −#define DSR_TWO_CLK_MISSING 0x40 | |
| 378 | −#define DSR_ONE_CLK_MISSING 0x80 | |
| 379 | − | |
| 380 | −/***********************************************************************/ | |
| 381 | −/* */ | |
| 382 | −/* Register Access */ | |
| 383 | −/* */ | |
| 384 | −/***********************************************************************/ | |
| 385 | − | |
| 386 | − | |
| 387 | −/* The SCC needs 3.5 PCLK cycles recovery time between to register | |
| 388 | − * accesses. PCLK runs with 8 MHz on an Atari, so this delay is 3.5 * | |
| 389 | − * 125 ns = 437.5 ns. This is too short for udelay(). | |
| 390 | − * 10/16/95: A tstb st_mfp.par_dt_reg takes 600ns (sure?) and thus should be | |
| 391 | − * quite right | |
| 392 | − */ | |
| 393 | − | |
| 394 | −#define scc_reg_delay() \ | |
| 395 | − do { \ | |
| 396 | − if (MACH_IS_MVME16x || MACH_IS_BVME6000 || MACH_IS_MVME147) \ | |
| 397 | − __asm__ __volatile__ ( " nop; nop"); \ | |
| 398 | − else if (MACH_IS_ATARI) \ | |
| 399 | − __asm__ __volatile__ ( "tstb %0" : : "g" (*_scc_del) : "cc" );\ | |
| 400 | − } while (0) | |
| 401 | − | |
| 402 | −static unsigned char scc_shadow[2][16]; | |
| 403 | − | |
| 404 | −/* The following functions should relax the somehow complicated | |
| 405 | − * register access of the SCC. _SCCwrite() stores all written values | |
| 406 | − * (except for WR0 and WR8) in shadow registers for later recall. This | |
| 407 | − * removes the burden of remembering written values as needed. The | |
| 408 | − * extra work of storing the value doesn't count, since a delay is | |
| 409 | − * needed after a SCC access anyway. Additionally, _SCCwrite() manages | |
| 410 | − * writes to WR0 and WR8 differently, because these can be accessed | |
| 411 | − * directly with less overhead. Another special case are WR7 and WR7'. | |
| 412 | − * _SCCwrite automatically checks what of this registers is selected | |
| 413 | − * and changes b0 of WR15 if needed. | |
| 414 | − * | |
| 415 | − * _SCCread() for standard read registers is straightforward, except | |
| 416 | − * for RR2 (split into two "virtual" registers: one for the value | |
| 417 | − * written to WR2 (from the shadow) and one for the vector including | |
| 418 | − * status from RR2, Ch. B) and RR3. The latter must be read from | |
| 419 | − * Channel A, because it reads as all zeros on Ch. B. RR0 and RR8 can | |
| 420 | − * be accessed directly as before. | |
| 421 | − * | |
| 422 | − * The two inline function contain complicated switch statements. But | |
| 423 | − * I rely on regno and final_delay being constants, so gcc can reduce | |
| 424 | − * the whole stuff to just some assembler statements. | |
| 425 | − * | |
| 426 | − * _SCCwrite and _SCCread aren't intended to be used directly under | |
| 427 | − * normal circumstances. The macros SCCread[_ND] and SCCwrite[_ND] are | |
| 428 | − * for that purpose. They assume that a local variable 'port' is | |
| 429 | − * declared and pointing to the port's scc_struct entry. The | |
| 430 | − * variants with "_NB" appended should be used if no other SCC | |
| 431 | − * accesses follow immediately (within 0.5 usecs). They just skip the | |
| 432 | − * final delay nops. | |
| 433 | − * | |
| 434 | − * Please note that accesses to SCC registers should only take place | |
| 435 | − * when interrupts are turned off (at least if SCC interrupts are | |
| 436 | − * enabled). Otherwise, an interrupt could interfere with the | |
| 437 | − * two-stage accessing process. | |
| 438 | − * | |
| 439 | − */ | |
| 440 | − | |
| 441 | − | |
| 442 | −static __inline__ void _SCCwrite( | |
| 443 | − struct scc_port *port, | |
| 444 | − unsigned char *shadow, | |
| 445 | − volatile unsigned char *_scc_del, | |
| 446 | − int regno, | |
| 447 | − unsigned char val, int final_delay ) | |
| 448 | −{ | |
| 449 | − switch( regno ) { | |
| 450 | − | |
| 451 | − case COMMAND_REG: | |
| 452 | − /* WR0 can be written directly without pointing */ | |
| 453 | − *port->ctrlp = val; | |
| 454 | − break; | |
| 455 | − | |
| 456 | − case SYNC_CHAR_REG: | |
| 457 | − /* For WR7, first set b0 of WR15 to 0, if needed */ | |
| 458 | − if (shadow[INT_CTRL_REG] & ICR_OPTIONREG_SELECT) { | |
| 459 | − *port->ctrlp = 15; | |
| 460 | − shadow[INT_CTRL_REG] &= ~ICR_OPTIONREG_SELECT; | |
| 461 | − scc_reg_delay(); | |
| 462 | − *port->ctrlp = shadow[INT_CTRL_REG]; | |
| 463 | − scc_reg_delay(); | |
| 464 | − } | |
| 465 | − goto normal_case; | |
| 466 | − | |
| 467 | − case SDLC_OPTION_REG: | |
| 468 | − /* For WR7', first set b0 of WR15 to 1, if needed */ | |
| 469 | − if (!(shadow[INT_CTRL_REG] & ICR_OPTIONREG_SELECT)) { | |
| 470 | − *port->ctrlp = 15; | |
| 471 | − shadow[INT_CTRL_REG] |= ICR_OPTIONREG_SELECT; | |
| 472 | − scc_reg_delay(); | |
| 473 | − *port->ctrlp = shadow[INT_CTRL_REG]; | |
| 474 | − scc_reg_delay(); | |
| 475 | − } | |
| 476 | − *port->ctrlp = 7; | |
| 477 | − shadow[8] = val; /* WR7' shadowed at WR8 */ | |
| 478 | − scc_reg_delay(); | |
| 479 | − *port->ctrlp = val; | |
| 480 | − break; | |
| 481 | − | |
| 482 | − case TX_DATA_REG: /* WR8 */ | |
| 483 | − /* TX_DATA_REG can be accessed directly on some h/w */ | |
| 484 | − if (MACH_IS_MVME16x || MACH_IS_BVME6000 || MACH_IS_MVME147) | |
| 485 | − { | |
| 486 | − *port->ctrlp = regno; | |
| 487 | − scc_reg_delay(); | |
| 488 | − *port->ctrlp = val; | |
| 489 | − } | |
| 490 | − else | |
| 491 | − *port->datap = val; | |
| 492 | − break; | |
| 493 | − | |
| 494 | − case MASTER_INT_CTRL: | |
| 495 | − *port->ctrlp = regno; | |
| 496 | − val &= 0x3f; /* bits 6..7 are the reset commands */ | |
| 497 | − scc_shadow[0][regno] = val; | |
| 498 | − scc_reg_delay(); | |
| 499 | − *port->ctrlp = val; | |
| 500 | − break; | |
| 501 | − | |
| 502 | − case DPLL_CTRL_REG: | |
| 503 | − *port->ctrlp = regno; | |
| 504 | − val &= 0x1f; /* bits 5..7 are the DPLL commands */ | |
| 505 | − shadow[regno] = val; | |
| 506 | − scc_reg_delay(); | |
| 507 | − *port->ctrlp = val; | |
| 508 | − break; | |
| 509 | − | |
| 510 | − case 1 ... 6: | |
| 511 | − case 10 ... 13: | |
| 512 | − case 15: | |
| 513 | − normal_case: | |
| 514 | − *port->ctrlp = regno; | |
| 515 | − shadow[regno] = val; | |
| 516 | − scc_reg_delay(); | |
| 517 | − *port->ctrlp = val; | |
| 518 | − break; | |
| 519 | − | |
| 520 | − default: | |
| 521 | − printk( "Bad SCC write access to WR%d\n", regno ); | |
| 522 | − break; | |
| 523 | − | |
| 524 | − } | |
| 525 | − | |
| 526 | − if (final_delay) | |
| 527 | − scc_reg_delay(); | |
| 528 | −} | |
| 529 | − | |
| 530 | − | |
| 531 | −static __inline__ unsigned char _SCCread( | |
| 532 | − struct scc_port *port, | |
| 533 | − unsigned char *shadow, | |
| 534 | − volatile unsigned char *_scc_del, | |
| 535 | − int regno, int final_delay ) | |
| 536 | −{ | |
| 537 | − unsigned char rv; | |
| 538 | − | |
| 539 | − switch( regno ) { | |
| 540 | − | |
| 541 | − /* --- real read registers --- */ | |
| 542 | − case STATUS_REG: | |
| 543 | − rv = *port->ctrlp; | |
| 544 | − break; | |
| 545 | − | |
| 546 | − case INT_PENDING_REG: | |
| 547 | − /* RR3: read only from Channel A! */ | |
| 548 | − port = port->port_a; | |
| 549 | − goto normal_case; | |
| 550 | − | |
| 551 | − case RX_DATA_REG: | |
| 552 | − /* RR8 can be accessed directly on some h/w */ | |
| 553 | − if (MACH_IS_MVME16x || MACH_IS_BVME6000 || MACH_IS_MVME147) | |
| 554 | − { | |
| 555 | − *port->ctrlp = 8; | |
| 556 | − scc_reg_delay(); | |
| 557 | − rv = *port->ctrlp; | |
| 558 | − } | |
| 559 | − else | |
| 560 | − rv = *port->datap; | |
| 561 | − break; | |
| 562 | − | |
| 563 | − case CURR_VECTOR_REG: | |
| 564 | − /* RR2 (vector including status) from Ch. B */ | |
| 565 | − port = port->port_b; | |
| 566 | − goto normal_case; | |
| 567 | − | |
| 568 | − /* --- reading write registers: access the shadow --- */ | |
| 569 | − case 1 ... 7: | |
| 570 | − case 10 ... 15: | |
| 571 | − return shadow[regno]; /* no final delay! */ | |
| 572 | − | |
| 573 | − /* WR7' is special, because it is shadowed at the place of WR8 */ | |
| 574 | − case SDLC_OPTION_REG: | |
| 575 | − return shadow[8]; /* no final delay! */ | |
| 576 | − | |
| 577 | − /* WR9 is special too, because it is common for both channels */ | |
| 578 | − case MASTER_INT_CTRL: | |
| 579 | − return scc_shadow[0][9]; /* no final delay! */ | |
| 580 | − | |
| 581 | − default: | |
| 582 | − printk( "Bad SCC read access to %cR%d\n", (regno & 16) ? 'R' : 'W', | |
| 583 | − regno & ~16 ); | |
| 584 | − break; | |
| 585 | − | |
| 586 | − case SPCOND_STATUS_REG: | |
| 587 | − case FS_FIFO_LOW_REG: | |
| 588 | − case FS_FIFO_HIGH_REG: | |
| 589 | − case DPLL_STATUS_REG: | |
| 590 | − normal_case: | |
| 591 | − *port->ctrlp = regno & 0x0f; | |
| 592 | − scc_reg_delay(); | |
| 593 | − rv = *port->ctrlp; | |
| 594 | − break; | |
| 595 | − | |
| 596 | − } | |
| 597 | − | |
| 598 | − if (final_delay) | |
| 599 | − scc_reg_delay(); | |
| 600 | − return rv; | |
| 601 | −} | |
| 602 | − | |
| 603 | −#define SCC_ACCESS_INIT(port) \ | |
| 604 | − unsigned char *_scc_shadow = &scc_shadow[port->channel][0] | |
| 605 | − | |
| 606 | −#define SCCwrite(reg,val) _SCCwrite(port,_scc_shadow,scc_del,(reg),(val),1) | |
| 607 | −#define SCCwrite_NB(reg,val) _SCCwrite(port,_scc_shadow,scc_del,(reg),(val),0) | |
| 608 | −#define SCCread(reg) _SCCread(port,_scc_shadow,scc_del,(reg),1) | |
| 609 | −#define SCCread_NB(reg) _SCCread(port,_scc_shadow,scc_del,(reg),0) | |
| 610 | − | |
| 611 | −#define SCCmod(reg,and,or) SCCwrite((reg),(SCCread(reg)&(and))|(or)) | |
| 612 | − | |
| 613 | −#endif /* _SCC_H */ | |
| @@ -0,0 +1,14 @@ | ||
| 1 | +config HYPERV | |
| 2 | + tristate "Microsoft Hyper-V client drivers" | |
| 3 | + depends on X86 && ACPI && PCI | |
| 4 | + help | |
| 5 | + Select this option to run Linux as a Hyper-V client operating | |
| 6 | + system. | |
| 7 | + | |
| 8 | +config HYPERV_UTILS | |
| 9 | + tristate "Microsoft Hyper-V Utilities driver" | |
| 10 | + depends on HYPERV && CONNECTOR && NLS | |
| 11 | + help | |
| 12 | + Select this option to enable the Hyper-V Utilities. | |
| 13 | + | |
| 14 | + | |
| @@ -0,0 +1,7 @@ | ||
| 1 | +obj-$(CONFIG_HYPERV) += hv_vmbus.o | |
| 2 | +obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o | |
| 3 | + | |
| 4 | +hv_vmbus-y := vmbus_drv.o \ | |
| 5 | + hv.o connection.o channel.o \ | |
| 6 | + channel_mgmt.o ring_buffer.o | |
| 7 | +hv_utils-y := hv_util.o hv_kvp.o | |
| @@ -26,8 +26,8 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <linux/mm.h> |
| 27 | 27 | #include <linux/slab.h> |
| 28 | 28 | #include <linux/module.h> |
| 29 | +#include <linux/hyperv.h> | |
| 29 | 30 | |
| 30 | −#include "hyperv.h" | |
| 31 | 31 | #include "hyperv_vmbus.h" |
| 32 | 32 | |
| 33 | 33 | #define NUM_PAGES_SPANNED(addr, len) \ |
| @@ -76,15 +76,14 @@ void vmbus_get_debug_info(struct vmbus_channel *channel, · 42 unmodified lines | ||
| 76 | 76 | struct hv_monitor_page *monitorpage; |
| 77 | 77 | u8 monitor_group = (u8)channel->offermsg.monitorid / 32; |
| 78 | 78 | u8 monitor_offset = (u8)channel->offermsg.monitorid % 32; |
| 79 | − /* u32 monitorBit = 1 << monitorOffset; */ | |
| 80 | 79 | |
| 81 | 80 | debuginfo->relid = channel->offermsg.child_relid; |
| 82 | 81 | debuginfo->state = channel->state; |
| 83 | 82 | memcpy(&debuginfo->interfacetype, |
| 84 | − &channel->offermsg.offer.if_type, sizeof(struct hv_guid)); | |
| 83 | + &channel->offermsg.offer.if_type, sizeof(uuid_le)); | |
| 85 | 84 | memcpy(&debuginfo->interface_instance, |
| 86 | 85 | &channel->offermsg.offer.if_instance, |
| 87 | − sizeof(struct hv_guid)); | |
| 86 | + sizeof(uuid_le)); | |
| 88 | 87 | |
| 89 | 88 | monitorpage = (struct hv_monitor_page *)vmbus_connection.monitor_pages; |
| 90 | 89 | |
| @@ -119,8 +118,8 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, · 28 unmodified lines | ||
| 119 | 118 | u32 recv_ringbuffer_size, void *userdata, u32 userdatalen, |
| 120 | 119 | void (*onchannelcallback)(void *context), void *context) |
| 121 | 120 | { |
| 122 | − struct vmbus_channel_open_channel *openMsg; | |
| 123 | − struct vmbus_channel_msginfo *openInfo = NULL; | |
| 121 | + struct vmbus_channel_open_channel *open_msg; | |
| 122 | + struct vmbus_channel_msginfo *open_info = NULL; | |
| 124 | 123 | void *in, *out; |
| 125 | 124 | unsigned long flags; |
| 126 | 125 | int ret, t, err = 0; |
| @@ -173,24 +172,24 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, · 46 unmodified lines | ||
| 173 | 172 | } |
| 174 | 173 | |
| 175 | 174 | /* Create and init the channel open message */ |
| 176 | − openInfo = kmalloc(sizeof(*openInfo) + | |
| 175 | + open_info = kmalloc(sizeof(*open_info) + | |
| 177 | 176 | sizeof(struct vmbus_channel_open_channel), |
| 178 | 177 | GFP_KERNEL); |
| 179 | − if (!openInfo) { | |
| 178 | + if (!open_info) { | |
| 180 | 179 | err = -ENOMEM; |
| 181 | 180 | goto errorout; |
| 182 | 181 | } |
| 183 | 182 | |
| 184 | − init_completion(&openInfo->waitevent); | |
| 183 | + init_completion(&open_info->waitevent); | |
| 185 | 184 | |
| 186 | − openMsg = (struct vmbus_channel_open_channel *)openInfo->msg; | |
| 187 | − openMsg->header.msgtype = CHANNELMSG_OPENCHANNEL; | |
| 188 | − openMsg->openid = newchannel->offermsg.child_relid; | |
| 189 | − openMsg->child_relid = newchannel->offermsg.child_relid; | |
| 190 | − openMsg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle; | |
| 191 | − openMsg->downstream_ringbuffer_pageoffset = send_ringbuffer_size >> | |
| 185 | + open_msg = (struct vmbus_channel_open_channel *)open_info->msg; | |
| 186 | + open_msg->header.msgtype = CHANNELMSG_OPENCHANNEL; | |
| 187 | + open_msg->openid = newchannel->offermsg.child_relid; | |
| 188 | + open_msg->child_relid = newchannel->offermsg.child_relid; | |
| 189 | + open_msg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle; | |
| 190 | + open_msg->downstream_ringbuffer_pageoffset = send_ringbuffer_size >> | |
| 192 | 191 | PAGE_SHIFT; |
| 193 | − openMsg->server_contextarea_gpadlhandle = 0; | |
| 192 | + open_msg->server_contextarea_gpadlhandle = 0; | |
| 194 | 193 | |
| 195 | 194 | if (userdatalen > MAX_USER_DEFINED_BYTES) { |
| 196 | 195 | err = -EINVAL; |
| @@ -198,35 +197,35 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, · 1 unmodified line | ||
| 198 | 197 | } |
| 199 | 198 | |
| 200 | 199 | if (userdatalen) |
| 201 | − memcpy(openMsg->userdata, userdata, userdatalen); | |
| 200 | + memcpy(open_msg->userdata, userdata, userdatalen); | |
| 202 | 201 | |
| 203 | 202 | spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); |
| 204 | − list_add_tail(&openInfo->msglistentry, | |
| 203 | + list_add_tail(&open_info->msglistentry, | |
| 205 | 204 | &vmbus_connection.chn_msg_list); |
| 206 | 205 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); |
| 207 | 206 | |
| 208 | − ret = vmbus_post_msg(openMsg, | |
| 207 | + ret = vmbus_post_msg(open_msg, | |
| 209 | 208 | sizeof(struct vmbus_channel_open_channel)); |
| 210 | 209 | |
| 211 | 210 | if (ret != 0) |
| 212 | 211 | goto cleanup; |
| 213 | 212 | |
| 214 | − t = wait_for_completion_timeout(&openInfo->waitevent, 5*HZ); | |
| 213 | + t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ); | |
| 215 | 214 | if (t == 0) { |
| 216 | 215 | err = -ETIMEDOUT; |
| 217 | 216 | goto errorout; |
| 218 | 217 | } |
| 219 | 218 | |
| 220 | 219 | |
| 221 | − if (openInfo->response.open_result.status) | |
| 222 | − err = openInfo->response.open_result.status; | |
| 220 | + if (open_info->response.open_result.status) | |
| 221 | + err = open_info->response.open_result.status; | |
| 223 | 222 | |
| 224 | 223 | cleanup: |
| 225 | 224 | spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); |
| 226 | − list_del(&openInfo->msglistentry); | |
| 225 | + list_del(&open_info->msglistentry); | |
| 227 | 226 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); |
| 228 | 227 | |
| 229 | − kfree(openInfo); | |
| 228 | + kfree(open_info); | |
| 230 | 229 | return err; |
| 231 | 230 | |
| 232 | 231 | errorout: |
| @@ -234,56 +233,11 @@ errorout: · 1 unmodified line | ||
| 234 | 233 | hv_ringbuffer_cleanup(&newchannel->inbound); |
| 235 | 234 | free_pages((unsigned long)out, |
| 236 | 235 | get_order(send_ringbuffer_size + recv_ringbuffer_size)); |
| 237 | − kfree(openInfo); | |
| 236 | + kfree(open_info); | |
| 238 | 237 | return err; |
| 239 | 238 | } |
| 240 | 239 | EXPORT_SYMBOL_GPL(vmbus_open); |
| 241 | 240 | |
| 242 | −/* | |
| 243 | − * dump_gpadl_body - Dump the gpadl body message to the console for | |
| 244 | − * debugging purposes. | |
| 245 | − */ | |
| 246 | −static void dump_gpadl_body(struct vmbus_channel_gpadl_body *gpadl, u32 len) | |
| 247 | −{ | |
| 248 | − int i; | |
| 249 | − int pfncount; | |
| 250 | − | |
| 251 | − pfncount = (len - sizeof(struct vmbus_channel_gpadl_body)) / | |
| 252 | − sizeof(u64); | |
| 253 | − | |
| 254 | − DPRINT_DBG(VMBUS, "gpadl body - len %d pfn count %d", len, pfncount); | |
| 255 | − | |
| 256 | − for (i = 0; i < pfncount; i++) | |
| 257 | − DPRINT_DBG(VMBUS, "gpadl body - %d) pfn %llu", | |
| 258 | − i, gpadl->pfn[i]); | |
| 259 | −} | |
| 260 | − | |
| 261 | −/* | |
| 262 | − * dump_gpadl_header - Dump the gpadl header message to the console for | |
| 263 | − * debugging purposes. | |
| 264 | − */ | |
| 265 | −static void dump_gpadl_header(struct vmbus_channel_gpadl_header *gpadl) | |
| 266 | −{ | |
| 267 | − int i, j; | |
| 268 | − int pagecount; | |
| 269 | − | |
| 270 | − DPRINT_DBG(VMBUS, | |
| 271 | − "gpadl header - relid %d, range count %d, range buflen %d", | |
| 272 | − gpadl->child_relid, gpadl->rangecount, gpadl->range_buflen); | |
| 273 | − for (i = 0; i < gpadl->rangecount; i++) { | |
| 274 | − pagecount = gpadl->range[i].byte_count >> PAGE_SHIFT; | |
| 275 | − pagecount = (pagecount > 26) ? 26 : pagecount; | |
| 276 | − | |
| 277 | − DPRINT_DBG(VMBUS, "gpadl range %d - len %d offset %d " | |
| 278 | − "page count %d", i, gpadl->range[i].byte_count, | |
| 279 | − gpadl->range[i].byte_offset, pagecount); | |
| 280 | − | |
| 281 | − for (j = 0; j < pagecount; j++) | |
| 282 | − DPRINT_DBG(VMBUS, "%d) pfn %llu", j, | |
| 283 | − gpadl->range[i].pfn_array[j]); | |
| 284 | − } | |
| 285 | −} | |
| 286 | − | |
| 287 | 241 | /* |
| 288 | 242 | * create_gpadl_header - Creates a gpadl for the specified buffer |
| 289 | 243 | */ |
| @@ -437,7 +391,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, · 147 unmodified lines | ||
| 437 | 391 | { |
| 438 | 392 | struct vmbus_channel_gpadl_header *gpadlmsg; |
| 439 | 393 | struct vmbus_channel_gpadl_body *gpadl_body; |
| 440 | − /* struct vmbus_channel_gpadl_created *gpadlCreated; */ | |
| 441 | 394 | struct vmbus_channel_msginfo *msginfo = NULL; |
| 442 | 395 | struct vmbus_channel_msginfo *submsginfo; |
| 443 | 396 | u32 msgcount; |
| @@ -461,7 +414,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, · 17 unmodified lines | ||
| 461 | 414 | gpadlmsg->child_relid = channel->offermsg.child_relid; |
| 462 | 415 | gpadlmsg->gpadl = next_gpadl_handle; |
| 463 | 416 | |
| 464 | − dump_gpadl_header(gpadlmsg); | |
| 465 | 417 | |
| 466 | 418 | spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); |
| 467 | 419 | list_add_tail(&msginfo->msglistentry, |
| @@ -485,8 +437,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, · 17 unmodified lines | ||
| 485 | 437 | CHANNELMSG_GPADL_BODY; |
| 486 | 438 | gpadl_body->gpadl = next_gpadl_handle; |
| 487 | 439 | |
| 488 | − dump_gpadl_body(gpadl_body, submsginfo->msgsize - | |
| 489 | − sizeof(*submsginfo)); | |
| 490 | 440 | ret = vmbus_post_msg(gpadl_body, |
| 491 | 441 | submsginfo->msgsize - |
| 492 | 442 | sizeof(*submsginfo)); |
| @@ -522,8 +472,6 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) · 29 unmodified lines | ||
| 522 | 472 | unsigned long flags; |
| 523 | 473 | int ret, t; |
| 524 | 474 | |
| 525 | − /* ASSERT(gpadl_handle != 0); */ | |
| 526 | − | |
| 527 | 475 | info = kmalloc(sizeof(*info) + |
| 528 | 476 | sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL); |
| 529 | 477 | if (!info) |
| @@ -565,9 +513,12 @@ void vmbus_close(struct vmbus_channel *channel) · 35 unmodified lines | ||
| 565 | 513 | { |
| 566 | 514 | struct vmbus_channel_close_channel *msg; |
| 567 | 515 | int ret; |
| 516 | + unsigned long flags; | |
| 568 | 517 | |
| 569 | 518 | /* Stop callback and cancel the timer asap */ |
| 519 | + spin_lock_irqsave(&channel->inbound_lock, flags); | |
| 570 | 520 | channel->onchannel_callback = NULL; |
| 521 | + spin_unlock_irqrestore(&channel->inbound_lock, flags); | |
| 571 | 522 | |
| 572 | 523 | /* Send a closing message */ |
| 573 | 524 | |
| @@ -787,19 +738,15 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, · 213 unmodified lines | ||
| 787 | 738 | u32 packetlen; |
| 788 | 739 | u32 userlen; |
| 789 | 740 | int ret; |
| 790 | − unsigned long flags; | |
| 791 | 741 | |
| 792 | 742 | *buffer_actual_len = 0; |
| 793 | 743 | *requestid = 0; |
| 794 | 744 | |
| 795 | − spin_lock_irqsave(&channel->inbound_lock, flags); | |
| 796 | 745 | |
| 797 | 746 | ret = hv_ringbuffer_peek(&channel->inbound, &desc, |
| 798 | 747 | sizeof(struct vmpacket_descriptor)); |
| 799 | − if (ret != 0) { | |
| 800 | − spin_unlock_irqrestore(&channel->inbound_lock, flags); | |
| 748 | + if (ret != 0) | |
| 801 | 749 | return 0; |
| 802 | − } | |
| 803 | 750 | |
| 804 | 751 | packetlen = desc.len8 << 3; |
| 805 | 752 | userlen = packetlen - (desc.offset8 << 3); |
| @@ -807,7 +754,6 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, · 1 unmodified line | ||
| 807 | 754 | *buffer_actual_len = userlen; |
| 808 | 755 | |
| 809 | 756 | if (userlen > bufferlen) { |
| 810 | − spin_unlock_irqrestore(&channel->inbound_lock, flags); | |
| 811 | 757 | |
| 812 | 758 | pr_err("Buffer too small - got %d needs %d\n", |
| 813 | 759 | bufferlen, userlen); |
| @@ -820,7 +766,6 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, · 6 unmodified lines | ||
| 820 | 766 | ret = hv_ringbuffer_read(&channel->inbound, buffer, userlen, |
| 821 | 767 | (desc.offset8 << 3)); |
| 822 | 768 | |
| 823 | − spin_unlock_irqrestore(&channel->inbound_lock, flags); | |
| 824 | 769 | |
| 825 | 770 | return 0; |
| 826 | 771 | } |
| @@ -837,19 +782,15 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer, · 10 unmodified lines | ||
| 837 | 782 | u32 packetlen; |
| 838 | 783 | u32 userlen; |
| 839 | 784 | int ret; |
| 840 | − unsigned long flags; | |
| 841 | 785 | |
| 842 | 786 | *buffer_actual_len = 0; |
| 843 | 787 | *requestid = 0; |
| 844 | 788 | |
| 845 | − spin_lock_irqsave(&channel->inbound_lock, flags); | |
| 846 | 789 | |
| 847 | 790 | ret = hv_ringbuffer_peek(&channel->inbound, &desc, |
| 848 | 791 | sizeof(struct vmpacket_descriptor)); |
| 849 | − if (ret != 0) { | |
| 850 | − spin_unlock_irqrestore(&channel->inbound_lock, flags); | |
| 792 | + if (ret != 0) | |
| 851 | 793 | return 0; |
| 852 | − } | |
| 853 | 794 | |
| 854 | 795 | |
| 855 | 796 | packetlen = desc.len8 << 3; |
| @@ -858,12 +799,10 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer, · 2 unmodified lines | ||
| 858 | 799 | *buffer_actual_len = packetlen; |
| 859 | 800 | |
| 860 | 801 | if (packetlen > bufferlen) { |
| 861 | − spin_unlock_irqrestore(&channel->inbound_lock, flags); | |
| 862 | − | |
| 863 | 802 | pr_err("Buffer too small - needed %d bytes but " |
| 864 | 803 | "got space for only %d bytes\n", |
| 865 | 804 | packetlen, bufferlen); |
| 866 | − return -2; | |
| 805 | + return -ENOBUFS; | |
| 867 | 806 | } |
| 868 | 807 | |
| 869 | 808 | *requestid = desc.trans_id; |
| @@ -871,7 +810,6 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer, · 1 unmodified line | ||
| 871 | 810 | /* Copy over the entire packet to the user buffer */ |
| 872 | 811 | ret = hv_ringbuffer_read(&channel->inbound, buffer, packetlen, 0); |
| 873 | 812 | |
| 874 | − spin_unlock_irqrestore(&channel->inbound_lock, flags); | |
| 875 | 813 | return 0; |
| 876 | 814 | } |
| 877 | 815 | EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw); |
| @@ -28,8 +28,8 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <linux/list.h> |
| 29 | 29 | #include <linux/module.h> |
| 30 | 30 | #include <linux/completion.h> |
| 31 | +#include <linux/hyperv.h> | |
| 31 | 32 | |
| 32 | −#include "hyperv.h" | |
| 33 | 33 | #include "hyperv_vmbus.h" |
| 34 | 34 | |
| 35 | 35 | struct vmbus_channel_message_table_entry { |
| @@ -40,12 +40,12 @@ struct vmbus_channel_message_table_entry { · 4 unmodified lines | ||
| 40 | 40 | #define MAX_MSG_TYPES 4 |
| 41 | 41 | #define MAX_NUM_DEVICE_CLASSES_SUPPORTED 8 |
| 42 | 42 | |
| 43 | −static const struct hv_guid | |
| 43 | +static const uuid_le | |
| 44 | 44 | supported_device_classes[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = { |
| 45 | 45 | /* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ |
| 46 | 46 | /* Storage - SCSI */ |
| 47 | 47 | { |
| 48 | − .data = { | |
| 48 | + .b = { | |
| 49 | 49 | 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, |
| 50 | 50 | 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f |
| 51 | 51 | } |
| @@ -54,7 +54,7 @@ static const struct hv_guid · 2 unmodified lines | ||
| 54 | 54 | /* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */ |
| 55 | 55 | /* Network */ |
| 56 | 56 | { |
| 57 | − .data = { | |
| 57 | + .b = { | |
| 58 | 58 | 0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, |
| 59 | 59 | 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E |
| 60 | 60 | } |
| @@ -63,7 +63,7 @@ static const struct hv_guid · 2 unmodified lines | ||
| 63 | 63 | /* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */ |
| 64 | 64 | /* Input */ |
| 65 | 65 | { |
| 66 | − .data = { | |
| 66 | + .b = { | |
| 67 | 67 | 0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c, |
| 68 | 68 | 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A |
| 69 | 69 | } |
| @@ -72,7 +72,7 @@ static const struct hv_guid · 2 unmodified lines | ||
| 72 | 72 | /* {32412632-86cb-44a2-9b5c-50d1417354f5} */ |
| 73 | 73 | /* IDE */ |
| 74 | 74 | { |
| 75 | − .data = { | |
| 75 | + .b = { | |
| 76 | 76 | 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, |
| 77 | 77 | 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 |
| 78 | 78 | } |
| @@ -80,7 +80,7 @@ static const struct hv_guid · 1 unmodified line | ||
| 80 | 80 | /* 0E0B6031-5213-4934-818B-38D90CED39DB */ |
| 81 | 81 | /* Shutdown */ |
| 82 | 82 | { |
| 83 | − .data = { | |
| 83 | + .b = { | |
| 84 | 84 | 0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49, |
| 85 | 85 | 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB |
| 86 | 86 | } |
| @@ -88,7 +88,7 @@ static const struct hv_guid · 1 unmodified line | ||
| 88 | 88 | /* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */ |
| 89 | 89 | /* TimeSync */ |
| 90 | 90 | { |
| 91 | − .data = { | |
| 91 | + .b = { | |
| 92 | 92 | 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, |
| 93 | 93 | 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf |
| 94 | 94 | } |
| @@ -96,7 +96,7 @@ static const struct hv_guid · 1 unmodified line | ||
| 96 | 96 | /* {57164f39-9115-4e78-ab55-382f3bd5422d} */ |
| 97 | 97 | /* Heartbeat */ |
| 98 | 98 | { |
| 99 | − .data = { | |
| 99 | + .b = { | |
| 100 | 100 | 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, |
| 101 | 101 | 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d |
| 102 | 102 | } |
| @@ -104,7 +104,7 @@ static const struct hv_guid · 1 unmodified line | ||
| 104 | 104 | /* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */ |
| 105 | 105 | /* KVP */ |
| 106 | 106 | { |
| 107 | − .data = { | |
| 107 | + .b = { | |
| 108 | 108 | 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, |
| 109 | 109 | 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6 |
| 110 | 110 | } |
| @@ -114,7 +114,7 @@ static const struct hv_guid · 3 unmodified lines | ||
| 114 | 114 | |
| 115 | 115 | |
| 116 | 116 | /** |
| 117 | − * prep_negotiate_resp() - Create default response for Hyper-V Negotiate message | |
| 117 | + * vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate message | |
| 118 | 118 | * @icmsghdrp: Pointer to msg header structure |
| 119 | 119 | * @icmsg_negotiate: Pointer to negotiate message structure |
| 120 | 120 | * @buf: Raw buffer channel data |
| @@ -128,9 +128,8 @@ static const struct hv_guid · 7 unmodified lines | ||
| 128 | 128 | * |
| 129 | 129 | * Mainly used by Hyper-V drivers. |
| 130 | 130 | */ |
| 131 | −void prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, | |
| 132 | − struct icmsg_negotiate *negop, | |
| 133 | − u8 *buf) | |
| 131 | +void vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, | |
| 132 | + struct icmsg_negotiate *negop, u8 *buf) | |
| 134 | 133 | { |
| 135 | 134 | if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { |
| 136 | 135 | icmsghdrp->icmsgsize = 0x10; |
| @@ -156,119 +155,7 @@ void prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, · 19 unmodified lines | ||
| 156 | 155 | negop->icmsg_vercnt = 1; |
| 157 | 156 | } |
| 158 | 157 | } |
| 159 | −EXPORT_SYMBOL(prep_negotiate_resp); | |
| 160 | − | |
| 161 | −/** | |
| 162 | − * chn_cb_negotiate() - Default handler for non IDE/SCSI/NETWORK | |
| 163 | − * Hyper-V requests | |
| 164 | − * @context: Pointer to argument structure. | |
| 165 | − * | |
| 166 | − * Set up the default handler for non device driver specific requests | |
| 167 | − * from Hyper-V. This stub responds to the default negotiate messages | |
| 168 | − * that come in for every non IDE/SCSI/Network request. | |
| 169 | − * This behavior is normally overwritten in the hv_utils driver. That | |
| 170 | − * driver handles requests like graceful shutdown, heartbeats etc. | |
| 171 | − * | |
| 172 | − * Mainly used by Hyper-V drivers. | |
| 173 | − */ | |
| 174 | −void chn_cb_negotiate(void *context) | |
| 175 | −{ | |
| 176 | − struct vmbus_channel *channel = context; | |
| 177 | − u8 *buf; | |
| 178 | − u32 buflen, recvlen; | |
| 179 | − u64 requestid; | |
| 180 | − | |
| 181 | − struct icmsg_hdr *icmsghdrp; | |
| 182 | − struct icmsg_negotiate *negop = NULL; | |
| 183 | − | |
| 184 | − if (channel->util_index >= 0) { | |
| 185 | − /* | |
| 186 | − * This is a properly initialized util channel. | |
| 187 | − * Route this callback appropriately and setup state | |
| 188 | − * so that we don't need to reroute again. | |
| 189 | − */ | |
| 190 | − if (hv_cb_utils[channel->util_index].callback != NULL) { | |
| 191 | − /* | |
| 192 | − * The util driver has established a handler for | |
| 193 | − * this service; do the magic. | |
| 194 | − */ | |
| 195 | − channel->onchannel_callback = | |
| 196 | − hv_cb_utils[channel->util_index].callback; | |
| 197 | − (hv_cb_utils[channel->util_index].callback)(channel); | |
| 198 | − return; | |
| 199 | − } | |
| 200 | − } | |
| 201 | − | |
| 202 | − buflen = PAGE_SIZE; | |
| 203 | − buf = kmalloc(buflen, GFP_ATOMIC); | |
| 204 | − | |
| 205 | − vmbus_recvpacket(channel, buf, buflen, &recvlen, &requestid); | |
| 206 | − | |
| 207 | − if (recvlen > 0) { | |
| 208 | − icmsghdrp = (struct icmsg_hdr *)&buf[ | |
| 209 | − sizeof(struct vmbuspipe_hdr)]; | |
| 210 | − | |
| 211 | − prep_negotiate_resp(icmsghdrp, negop, buf); | |
| 212 | − | |
| 213 | − icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | |
| 214 | − | ICMSGHDRFLAG_RESPONSE; | |
| 215 | − | |
| 216 | − vmbus_sendpacket(channel, buf, | |
| 217 | − recvlen, requestid, | |
| 218 | − VM_PKT_DATA_INBAND, 0); | |
| 219 | − } | |
| 220 | − | |
| 221 | − kfree(buf); | |
| 222 | −} | |
| 223 | −EXPORT_SYMBOL(chn_cb_negotiate); | |
| 224 | − | |
| 225 | −/* | |
| 226 | − * Function table used for message responses for non IDE/SCSI/Network type | |
| 227 | − * messages. (Such as KVP/Shutdown etc) | |
| 228 | − */ | |
| 229 | −struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = { | |
| 230 | − /* 0E0B6031-5213-4934-818B-38D90CED39DB */ | |
| 231 | − /* Shutdown */ | |
| 232 | − { | |
| 233 | − .msg_type = HV_SHUTDOWN_MSG, | |
| 234 | − .data = { | |
| 235 | − 0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49, | |
| 236 | − 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB | |
| 237 | − }, | |
| 238 | − .log_msg = "Shutdown channel functionality initialized" | |
| 239 | − }, | |
| 240 | − | |
| 241 | − /* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */ | |
| 242 | − /* TimeSync */ | |
| 243 | − { | |
| 244 | − .msg_type = HV_TIMESYNC_MSG, | |
| 245 | − .data = { | |
| 246 | − 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, | |
| 247 | − 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf | |
| 248 | − }, | |
| 249 | − .log_msg = "Timesync channel functionality initialized" | |
| 250 | − }, | |
| 251 | − /* {57164f39-9115-4e78-ab55-382f3bd5422d} */ | |
| 252 | − /* Heartbeat */ | |
| 253 | − { | |
| 254 | − .msg_type = HV_HEARTBEAT_MSG, | |
| 255 | − .data = { | |
| 256 | − 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, | |
| 257 | − 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d | |
| 258 | − }, | |
| 259 | − .log_msg = "Heartbeat channel functionality initialized" | |
| 260 | − }, | |
| 261 | − /* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */ | |
| 262 | − /* KVP */ | |
| 263 | − { | |
| 264 | − .data = { | |
| 265 | − 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, | |
| 266 | − 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6 | |
| 267 | − }, | |
| 268 | − .log_msg = "KVP channel functionality initialized" | |
| 269 | − }, | |
| 270 | −}; | |
| 271 | −EXPORT_SYMBOL(hv_cb_utils); | |
| 158 | +EXPORT_SYMBOL_GPL(vmbus_prep_negotiate_resp); | |
| 272 | 159 | |
| 273 | 160 | /* |
| 274 | 161 | * alloc_channel - Allocate and initialize a vmbus channel object |
| @@ -309,7 +196,7 @@ static void release_channel(struct work_struct *work) · 34 unmodified lines | ||
| 309 | 196 | /* |
| 310 | 197 | * free_channel - Release the resources used by the vmbus channel object |
| 311 | 198 | */ |
| 312 | −void free_channel(struct vmbus_channel *channel) | |
| 199 | +static void free_channel(struct vmbus_channel *channel) | |
| 313 | 200 | { |
| 314 | 201 | |
| 315 | 202 | /* |
| @@ -333,7 +220,7 @@ static void vmbus_process_rescind_offer(struct work_struct *work) · 17 unmodified lines | ||
| 333 | 220 | struct vmbus_channel, |
| 334 | 221 | work); |
| 335 | 222 | |
| 336 | − vmbus_child_device_unregister(channel->device_obj); | |
| 223 | + vmbus_device_unregister(channel->device_obj); | |
| 337 | 224 | } |
| 338 | 225 | |
| 339 | 226 | /* |
| @@ -348,7 +235,6 @@ static void vmbus_process_offer(struct work_struct *work) · 8 unmodified lines | ||
| 348 | 235 | struct vmbus_channel *channel; |
| 349 | 236 | bool fnew = true; |
| 350 | 237 | int ret; |
| 351 | − int cnt; | |
| 352 | 238 | unsigned long flags; |
| 353 | 239 | |
| 354 | 240 | /* The next possible work is rescind handling */ |
| @@ -358,12 +244,10 @@ static void vmbus_process_offer(struct work_struct *work) · 3 unmodified lines | ||
| 358 | 244 | spin_lock_irqsave(&vmbus_connection.channel_lock, flags); |
| 359 | 245 | |
| 360 | 246 | list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) { |
| 361 | − if (!memcmp(&channel->offermsg.offer.if_type, | |
| 362 | − &newchannel->offermsg.offer.if_type, | |
| 363 | − sizeof(struct hv_guid)) && | |
| 364 | − !memcmp(&channel->offermsg.offer.if_instance, | |
| 365 | − &newchannel->offermsg.offer.if_instance, | |
| 366 | − sizeof(struct hv_guid))) { | |
| 247 | + if (!uuid_le_cmp(channel->offermsg.offer.if_type, | |
| 248 | + newchannel->offermsg.offer.if_type) && | |
| 249 | + !uuid_le_cmp(channel->offermsg.offer.if_instance, | |
| 250 | + newchannel->offermsg.offer.if_instance)) { | |
| 367 | 251 | fnew = false; |
| 368 | 252 | break; |
| 369 | 253 | } |
| @@ -385,7 +269,7 @@ static void vmbus_process_offer(struct work_struct *work) · 15 unmodified lines | ||
| 385 | 269 | * We need to set the DeviceObject field before calling |
| 386 | 270 | * vmbus_child_dev_add() |
| 387 | 271 | */ |
| 388 | − newchannel->device_obj = vmbus_child_device_create( | |
| 272 | + newchannel->device_obj = vmbus_device_create( | |
| 389 | 273 | &newchannel->offermsg.offer.if_type, |
| 390 | 274 | &newchannel->offermsg.offer.if_instance, |
| 391 | 275 | newchannel); |
| @@ -395,7 +279,7 @@ static void vmbus_process_offer(struct work_struct *work) · 3 unmodified lines | ||
| 395 | 279 | * binding which eventually invokes the device driver's AddDevice() |
| 396 | 280 | * method. |
| 397 | 281 | */ |
| 398 | − ret = vmbus_child_device_register(newchannel->device_obj); | |
| 282 | + ret = vmbus_device_register(newchannel->device_obj); | |
| 399 | 283 | if (ret != 0) { |
| 400 | 284 | pr_err("unable to add child device object (relid %d)\n", |
| 401 | 285 | newchannel->offermsg.child_relid); |
| @@ -412,48 +296,26 @@ static void vmbus_process_offer(struct work_struct *work) · 10 unmodified lines | ||
| 412 | 296 | * can cleanup properly |
| 413 | 297 | */ |
| 414 | 298 | newchannel->state = CHANNEL_OPEN_STATE; |
| 415 | − newchannel->util_index = -1; /* Invalid index */ | |
| 416 | − | |
| 417 | − /* Open IC channels */ | |
| 418 | − for (cnt = 0; cnt < MAX_MSG_TYPES; cnt++) { | |
| 419 | − if (memcmp(&newchannel->offermsg.offer.if_type, | |
| 420 | − &hv_cb_utils[cnt].data, | |
| 421 | − sizeof(struct hv_guid)) == 0 && | |
| 422 | − vmbus_open(newchannel, 2 * PAGE_SIZE, | |
| 423 | − 2 * PAGE_SIZE, NULL, 0, | |
| 424 | − chn_cb_negotiate, | |
| 425 | − newchannel) == 0) { | |
| 426 | − hv_cb_utils[cnt].channel = newchannel; | |
| 427 | − newchannel->util_index = cnt; | |
| 428 | − | |
| 429 | − pr_info("%s\n", hv_cb_utils[cnt].log_msg); | |
| 430 | − | |
| 431 | − } | |
| 432 | − } | |
| 433 | 299 | } |
| 434 | 300 | } |
| 435 | 301 | |
| 436 | 302 | /* |
| 437 | 303 | * vmbus_onoffer - Handler for channel offers from vmbus in parent partition. |
| 438 | 304 | * |
| 439 | − * We ignore all offers except network and storage offers. For each network and | |
| 440 | − * storage offers, we create a channel object and queue a work item to the | |
| 441 | − * channel object to process the offer synchronously | |
| 442 | 305 | */ |
| 443 | 306 | static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) |
| 444 | 307 | { |
| 445 | 308 | struct vmbus_channel_offer_channel *offer; |
| 446 | 309 | struct vmbus_channel *newchannel; |
| 447 | − struct hv_guid *guidtype; | |
| 448 | − struct hv_guid *guidinstance; | |
| 310 | + uuid_le *guidtype; | |
| 311 | + uuid_le *guidinstance; | |
| 449 | 312 | int i; |
| 450 | 313 | int fsupported = 0; |
| 451 | 314 | |
| 452 | 315 | offer = (struct vmbus_channel_offer_channel *)hdr; |
| 453 | 316 | for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) { |
| 454 | − if (memcmp(&offer->offer.if_type, | |
| 455 | − &supported_device_classes[i], | |
| 456 | − sizeof(struct hv_guid)) == 0) { | |
| 317 | + if (!uuid_le_cmp(offer->offer.if_type, | |
| 318 | + supported_device_classes[i])) { | |
| 457 | 319 | fsupported = 1; |
| 458 | 320 | break; |
| 459 | 321 | } |
| @@ -25,11 +25,12 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <linux/kernel.h> |
| 26 | 26 | #include <linux/sched.h> |
| 27 | 27 | #include <linux/wait.h> |
| 28 | +#include <linux/delay.h> | |
| 28 | 29 | #include <linux/mm.h> |
| 29 | 30 | #include <linux/slab.h> |
| 30 | 31 | #include <linux/vmalloc.h> |
| 31 | − | |
| 32 | −#include "hyperv.h" | |
| 32 | +#include <linux/hyperv.h> | |
| 33 | +#include <asm/hyperv.h> | |
| 33 | 34 | #include "hyperv_vmbus.h" |
| 34 | 35 | |
| 35 | 36 | |
| @@ -49,10 +50,6 @@ int vmbus_connect(void) · 13 unmodified lines | ||
| 49 | 50 | struct vmbus_channel_initiate_contact *msg; |
| 50 | 51 | unsigned long flags; |
| 51 | 52 | |
| 52 | − /* Make sure we are not connecting or connected */ | |
| 53 | − if (vmbus_connection.conn_state != DISCONNECTED) | |
| 54 | − return -EISCONN; | |
| 55 | − | |
| 56 | 53 | /* Initialize the vmbus connection */ |
| 57 | 54 | vmbus_connection.conn_state = CONNECTING; |
| 58 | 55 | vmbus_connection.work_queue = create_workqueue("hv_vmbus_con"); |
| @@ -214,8 +211,7 @@ struct vmbus_channel *relid2channel(u32 relid) · 155 unmodified lines | ||
| 214 | 211 | static void process_chn_event(u32 relid) |
| 215 | 212 | { |
| 216 | 213 | struct vmbus_channel *channel; |
| 217 | − | |
| 218 | − /* ASSERT(relId > 0); */ | |
| 214 | + unsigned long flags; | |
| 219 | 215 | |
| 220 | 216 | /* |
| 221 | 217 | * Find the channel based on this relid and invokes the |
| @@ -223,11 +219,27 @@ static void process_chn_event(u32 relid) · 1 unmodified line | ||
| 223 | 219 | */ |
| 224 | 220 | channel = relid2channel(relid); |
| 225 | 221 | |
| 226 | − if (channel) { | |
| 227 | − channel->onchannel_callback(channel->channel_callback_context); | |
| 228 | − } else { | |
| 222 | + if (!channel) { | |
| 229 | 223 | pr_err("channel not found for relid - %u\n", relid); |
| 224 | + return; | |
| 230 | 225 | } |
| 226 | + | |
| 227 | + /* | |
| 228 | + * A channel once created is persistent even when there | |
| 229 | + * is no driver handling the device. An unloading driver | |
| 230 | + * sets the onchannel_callback to NULL under the | |
| 231 | + * protection of the channel inbound_lock. Thus, checking | |
| 232 | + * and invoking the driver specific callback takes care of | |
| 233 | + * orderly unloading of the driver. | |
| 234 | + */ | |
| 235 | + | |
| 236 | + spin_lock_irqsave(&channel->inbound_lock, flags); | |
| 237 | + if (channel->onchannel_callback != NULL) | |
| 238 | + channel->onchannel_callback(channel->channel_callback_context); | |
| 239 | + else | |
| 240 | + pr_err("no channel callback for relid - %u\n", relid); | |
| 241 | + | |
| 242 | + spin_unlock_irqrestore(&channel->inbound_lock, flags); | |
| 231 | 243 | } |
| 232 | 244 | |
| 233 | 245 | /* |
| @@ -248,16 +260,17 @@ void vmbus_on_event(unsigned long data) · 14 unmodified lines | ||
| 248 | 260 | if (!recv_int_page[dword]) |
| 249 | 261 | continue; |
| 250 | 262 | for (bit = 0; bit < 32; bit++) { |
| 251 | − if (sync_test_and_clear_bit(bit, (unsigned long *)&recv_int_page[dword])) { | |
| 263 | + if (sync_test_and_clear_bit(bit, | |
| 264 | + (unsigned long *)&recv_int_page[dword])) { | |
| 252 | 265 | relid = (dword << 5) + bit; |
| 253 | 266 | |
| 254 | − if (relid == 0) { | |
| 267 | + if (relid == 0) | |
| 255 | 268 | /* |
| 256 | 269 | * Special case - vmbus |
| 257 | 270 | * channel protocol msg |
| 258 | 271 | */ |
| 259 | 272 | continue; |
| 260 | − } | |
| 273 | + | |
| 261 | 274 | process_chn_event(relid); |
| 262 | 275 | } |
| 263 | 276 | } |
| @@ -270,10 +283,25 @@ void vmbus_on_event(unsigned long data) · 6 unmodified lines | ||
| 270 | 283 | int vmbus_post_msg(void *buffer, size_t buflen) |
| 271 | 284 | { |
| 272 | 285 | union hv_connection_id conn_id; |
| 286 | + int ret = 0; | |
| 287 | + int retries = 0; | |
| 273 | 288 | |
| 274 | 289 | conn_id.asu32 = 0; |
| 275 | 290 | conn_id.u.id = VMBUS_MESSAGE_CONNECTION_ID; |
| 276 | − return hv_post_message(conn_id, 1, buffer, buflen); | |
| 291 | + | |
| 292 | + /* | |
| 293 | + * hv_post_message() can have transient failures because of | |
| 294 | + * insufficient resources. Retry the operation a couple of | |
| 295 | + * times before giving up. | |
| 296 | + */ | |
| 297 | + while (retries < 3) { | |
| 298 | + ret = hv_post_message(conn_id, 1, buffer, buflen); | |
| 299 | + if (ret != HV_STATUS_INSUFFICIENT_BUFFERS) | |
| 300 | + return ret; | |
| 301 | + retries++; | |
| 302 | + msleep(100); | |
| 303 | + } | |
| 304 | + return ret; | |
| 277 | 305 | } |
| 278 | 306 | |
| 279 | 307 | /* |
| @@ -25,8 +25,8 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <linux/mm.h> |
| 26 | 26 | #include <linux/slab.h> |
| 27 | 27 | #include <linux/vmalloc.h> |
| 28 | − | |
| 29 | −#include "hyperv.h" | |
| 28 | +#include <linux/hyperv.h> | |
| 29 | +#include <asm/hyperv.h> | |
| 30 | 30 | #include "hyperv_vmbus.h" |
| 31 | 31 | |
| 32 | 32 | /* The one and only */ |
| @@ -111,7 +111,7 @@ static u64 do_hypercall(u64 control, void *input, void *output) · 78 unmodified lines | ||
| 111 | 111 | u64 hv_status = 0; |
| 112 | 112 | u64 input_address = (input) ? virt_to_phys(input) : 0; |
| 113 | 113 | u64 output_address = (output) ? virt_to_phys(output) : 0; |
| 114 | − volatile void *hypercall_page = hv_context.hypercall_page; | |
| 114 | + void *hypercall_page = hv_context.hypercall_page; | |
| 115 | 115 | |
| 116 | 116 | __asm__ __volatile__("mov %0, %%r8" : : "r" (output_address) : "r8"); |
| 117 | 117 | __asm__ __volatile__("call *%3" : "=a" (hv_status) : |
| @@ -132,7 +132,7 @@ static u64 do_hypercall(u64 control, void *input, void *output) · 14 unmodified lines | ||
| 132 | 132 | u64 output_address = (output) ? virt_to_phys(output) : 0; |
| 133 | 133 | u32 output_address_hi = output_address >> 32; |
| 134 | 134 | u32 output_address_lo = output_address & 0xFFFFFFFF; |
| 135 | − volatile void *hypercall_page = hv_context.hypercall_page; | |
| 135 | + void *hypercall_page = hv_context.hypercall_page; | |
| 136 | 136 | |
| 137 | 137 | __asm__ __volatile__ ("call *%8" : "=d"(hv_status_hi), |
| 138 | 138 | "=a"(hv_status_lo) : "d" (control_hi), |
| @@ -151,7 +151,6 @@ static u64 do_hypercall(u64 control, void *input, void *output) · 12 unmodified lines | ||
| 151 | 151 | */ |
| 152 | 152 | int hv_init(void) |
| 153 | 153 | { |
| 154 | − int ret = 0; | |
| 155 | 154 | int max_leaf; |
| 156 | 155 | union hv_x64_msr_hypercall_contents hypercall_msr; |
| 157 | 156 | void *virtaddr = NULL; |
| @@ -164,11 +163,7 @@ int hv_init(void) · 6 unmodified lines | ||
| 164 | 163 | goto cleanup; |
| 165 | 164 | |
| 166 | 165 | max_leaf = query_hypervisor_info(); |
| 167 | − /* HvQueryHypervisorFeatures(maxLeaf); */ | |
| 168 | 166 | |
| 169 | − /* | |
| 170 | − * We only support running on top of Hyper-V | |
| 171 | − */ | |
| 172 | 167 | rdmsrl(HV_X64_MSR_GUEST_OS_ID, hv_context.guestid); |
| 173 | 168 | |
| 174 | 169 | if (hv_context.guestid != 0) |
| @@ -181,10 +176,6 @@ int hv_init(void) · 6 unmodified lines | ||
| 181 | 176 | /* See if the hypercall page is already set */ |
| 182 | 177 | rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); |
| 183 | 178 | |
| 184 | − /* | |
| 185 | − * Allocate the hypercall page memory | |
| 186 | − * virtaddr = osd_page_alloc(1); | |
| 187 | − */ | |
| 188 | 179 | virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_EXEC); |
| 189 | 180 | |
| 190 | 181 | if (!virtaddr) |
| @@ -222,7 +213,7 @@ int hv_init(void) · 31 unmodified lines | ||
| 222 | 213 | hv_context.signal_event_param->flag_number = 0; |
| 223 | 214 | hv_context.signal_event_param->rsvdz = 0; |
| 224 | 215 | |
| 225 | − return ret; | |
| 216 | + return 0; | |
| 226 | 217 | |
| 227 | 218 | cleanup: |
| 228 | 219 | if (virtaddr) { |
| @@ -233,8 +224,8 @@ cleanup: · 4 unmodified lines | ||
| 233 | 224 | |
| 234 | 225 | vfree(virtaddr); |
| 235 | 226 | } |
| 236 | − ret = -1; | |
| 237 | − return ret; | |
| 227 | + | |
| 228 | + return -ENOTSUPP; | |
| 238 | 229 | } |
| 239 | 230 | |
| 240 | 231 | /* |
| @@ -378,7 +369,7 @@ void hv_synic_init(void *irqarg) · 137 unmodified lines | ||
| 378 | 369 | shared_sint.as_uint64 = 0; |
| 379 | 370 | shared_sint.vector = irq_vector; /* HV_SHARED_SINT_IDT_VECTOR + 0x20; */ |
| 380 | 371 | shared_sint.masked = false; |
| 381 | − shared_sint.auto_eoi = true; | |
| 372 | + shared_sint.auto_eoi = false; | |
| 382 | 373 | |
| 383 | 374 | wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64); |
| 384 | 375 | |
| @@ -26,8 +26,8 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <linux/nls.h> |
| 27 | 27 | #include <linux/connector.h> |
| 28 | 28 | #include <linux/workqueue.h> |
| 29 | +#include <linux/hyperv.h> | |
| 29 | 30 | |
| 30 | −#include "hyperv.h" | |
| 31 | 31 | #include "hv_kvp.h" |
| 32 | 32 | |
| 33 | 33 | |
| @@ -44,21 +44,24 @@ · 10 unmodified lines | ||
| 44 | 44 | static struct { |
| 45 | 45 | bool active; /* transaction status - active or not */ |
| 46 | 46 | int recv_len; /* number of bytes received. */ |
| 47 | + int index; /* current index */ | |
| 47 | 48 | struct vmbus_channel *recv_channel; /* chn we got the request */ |
| 48 | 49 | u64 recv_req_id; /* request ID. */ |
| 49 | 50 | } kvp_transaction; |
| 50 | 51 | |
| 51 | −static int kvp_send_key(int index); | |
| 52 | +static void kvp_send_key(struct work_struct *dummy); | |
| 53 | + | |
| 54 | +#define TIMEOUT_FIRED 1 | |
| 52 | 55 | |
| 53 | 56 | static void kvp_respond_to_host(char *key, char *value, int error); |
| 54 | 57 | static void kvp_work_func(struct work_struct *dummy); |
| 55 | 58 | static void kvp_register(void); |
| 56 | 59 | |
| 57 | 60 | static DECLARE_DELAYED_WORK(kvp_work, kvp_work_func); |
| 61 | +static DECLARE_WORK(kvp_sendkey_work, kvp_send_key); | |
| 58 | 62 | |
| 59 | 63 | static struct cb_id kvp_id = { CN_KVP_IDX, CN_KVP_VAL }; |
| 60 | 64 | static const char kvp_name[] = "kvp_kernel_module"; |
| 61 | −static int timeout_fired; | |
| 62 | 65 | static u8 *recv_buffer; |
| 63 | 66 | /* |
| 64 | 67 | * Register the kernel component with the user-level daemon. |
| @@ -90,8 +93,7 @@ kvp_work_func(struct work_struct *dummy) · 25 unmodified lines | ||
| 90 | 93 | * If the timer fires, the user-mode component has not responded; |
| 91 | 94 | * process the pending transaction. |
| 92 | 95 | */ |
| 93 | − kvp_respond_to_host("Unknown key", "Guest timed out", timeout_fired); | |
| 94 | − timeout_fired = 1; | |
| 96 | + kvp_respond_to_host("Unknown key", "Guest timed out", TIMEOUT_FIRED); | |
| 95 | 97 | } |
| 96 | 98 | |
| 97 | 99 | /* |
| @@ -121,10 +123,11 @@ kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) · 23 unmodified lines | ||
| 121 | 123 | } |
| 122 | 124 | } |
| 123 | 125 | |
| 124 | −static int | |
| 125 | −kvp_send_key(int index) | |
| 126 | +static void | |
| 127 | +kvp_send_key(struct work_struct *dummy) | |
| 126 | 128 | { |
| 127 | 129 | struct cn_msg *msg; |
| 130 | + int index = kvp_transaction.index; | |
| 128 | 131 | |
| 129 | 132 | msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg) , GFP_ATOMIC); |
| 130 | 133 | |
| @@ -136,9 +139,8 @@ kvp_send_key(int index) · 5 unmodified lines | ||
| 136 | 139 | msg->len = sizeof(struct hv_ku_msg); |
| 137 | 140 | cn_netlink_send(msg, 0, GFP_ATOMIC); |
| 138 | 141 | kfree(msg); |
| 139 | − return 0; | |
| 140 | 142 | } |
| 141 | − return 1; | |
| 143 | + return; | |
| 142 | 144 | } |
| 143 | 145 | |
| 144 | 146 | /* |
| @@ -177,6 +179,15 @@ kvp_respond_to_host(char *key, char *value, int error) · 32 unmodified lines | ||
| 177 | 179 | channel = kvp_transaction.recv_channel; |
| 178 | 180 | req_id = kvp_transaction.recv_req_id; |
| 179 | 181 | |
| 182 | + kvp_transaction.active = false; | |
| 183 | + | |
| 184 | + if (channel->onchannel_callback == NULL) | |
| 185 | + /* | |
| 186 | + * We have raced with util driver being unloaded; | |
| 187 | + * silently return. | |
| 188 | + */ | |
| 189 | + return; | |
| 190 | + | |
| 180 | 191 | icmsghdrp = (struct icmsg_hdr *) |
| 181 | 192 | &recv_buffer[sizeof(struct vmbuspipe_hdr)]; |
| 182 | 193 | kvp_msg = (struct hv_kvp_msg *) |
| @@ -217,7 +228,6 @@ response_done: · 34 unmodified lines | ||
| 217 | 228 | vmbus_sendpacket(channel, recv_buffer, buf_len, req_id, |
| 218 | 229 | VM_PKT_DATA_INBAND, 0); |
| 219 | 230 | |
| 220 | − kvp_transaction.active = false; | |
| 221 | 231 | } |
| 222 | 232 | |
| 223 | 233 | /* |
| @@ -243,10 +253,6 @@ void hv_kvp_onchannelcallback(void *context) · 19 unmodified lines | ||
| 243 | 253 | struct icmsg_negotiate *negop = NULL; |
| 244 | 254 | |
| 245 | 255 | |
| 246 | − if (kvp_transaction.active) | |
| 247 | − return; | |
| 248 | − | |
| 249 | − | |
| 250 | 256 | vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE, &recvlen, &requestid); |
| 251 | 257 | |
| 252 | 258 | if (recvlen > 0) { |
| @@ -254,7 +260,7 @@ void hv_kvp_onchannelcallback(void *context) · 1 unmodified line | ||
| 254 | 260 | sizeof(struct vmbuspipe_hdr)]; |
| 255 | 261 | |
| 256 | 262 | if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { |
| 257 | − prep_negotiate_resp(icmsghdrp, negop, recv_buffer); | |
| 263 | + vmbus_prep_negotiate_resp(icmsghdrp, negop, recv_buffer); | |
| 258 | 264 | } else { |
| 259 | 265 | kvp_msg = (struct hv_kvp_msg *)&recv_buffer[ |
| 260 | 266 | sizeof(struct vmbuspipe_hdr) + |
| @@ -282,6 +288,7 @@ void hv_kvp_onchannelcallback(void *context) · 21 unmodified lines | ||
| 282 | 288 | kvp_transaction.recv_channel = channel; |
| 283 | 289 | kvp_transaction.recv_req_id = requestid; |
| 284 | 290 | kvp_transaction.active = true; |
| 291 | + kvp_transaction.index = kvp_data->index; | |
| 285 | 292 | |
| 286 | 293 | /* |
| 287 | 294 | * Get the information from the |
| @@ -292,8 +299,8 @@ void hv_kvp_onchannelcallback(void *context) · 4 unmodified lines | ||
| 292 | 299 | * Set a timeout to deal with |
| 293 | 300 | * user-mode not responding. |
| 294 | 301 | */ |
| 295 | − kvp_send_key(kvp_data->index); | |
| 296 | − schedule_delayed_work(&kvp_work, 100); | |
| 302 | + schedule_work(&kvp_sendkey_work); | |
| 303 | + schedule_delayed_work(&kvp_work, 5*HZ); | |
| 297 | 304 | |
| 298 | 305 | return; |
| 299 | 306 | |
| @@ -312,16 +319,14 @@ callback_done: · 12 unmodified lines | ||
| 312 | 319 | } |
| 313 | 320 | |
| 314 | 321 | int |
| 315 | −hv_kvp_init(void) | |
| 322 | +hv_kvp_init(struct hv_util_service *srv) | |
| 316 | 323 | { |
| 317 | 324 | int err; |
| 318 | 325 | |
| 319 | 326 | err = cn_add_callback(&kvp_id, kvp_name, kvp_cn_callback); |
| 320 | 327 | if (err) |
| 321 | 328 | return err; |
| 322 | − recv_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); | |
| 323 | − if (!recv_buffer) | |
| 324 | − return -ENOMEM; | |
| 329 | + recv_buffer = srv->recv_buffer; | |
| 325 | 330 | |
| 326 | 331 | return 0; |
| 327 | 332 | } |
| @@ -330,5 +335,5 @@ void hv_kvp_deinit(void) · 2 unmodified lines | ||
| 330 | 335 | { |
| 331 | 336 | cn_del_callback(&kvp_id); |
| 332 | 337 | cancel_delayed_work_sync(&kvp_work); |
| 333 | − kfree(recv_buffer); | |
| 338 | + cancel_work_sync(&kvp_sendkey_work); | |
| 334 | 339 | } |
| @@ -175,7 +175,7 @@ struct hv_kvp_msg { · 174 unmodified lines | ||
| 175 | 175 | struct hv_kvp_msg_enumerate kvp_data; |
| 176 | 176 | }; |
| 177 | 177 | |
| 178 | −int hv_kvp_init(void); | |
| 178 | +int hv_kvp_init(struct hv_util_service *); | |
| 179 | 179 | void hv_kvp_deinit(void); |
| 180 | 180 | void hv_kvp_onchannelcallback(void *); |
| 181 | 181 | |
| @@ -26,15 +26,31 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <linux/slab.h> |
| 27 | 27 | #include <linux/sysctl.h> |
| 28 | 28 | #include <linux/reboot.h> |
| 29 | −#include <linux/dmi.h> | |
| 30 | −#include <linux/pci.h> | |
| 29 | +#include <linux/hyperv.h> | |
| 31 | 30 | |
| 32 | −#include "hyperv.h" | |
| 33 | 31 | #include "hv_kvp.h" |
| 34 | 32 | |
| 35 | −static u8 *shut_txf_buf; | |
| 36 | −static u8 *time_txf_buf; | |
| 37 | −static u8 *hbeat_txf_buf; | |
| 33 | + | |
| 34 | +static void shutdown_onchannelcallback(void *context); | |
| 35 | +static struct hv_util_service util_shutdown = { | |
| 36 | + .util_cb = shutdown_onchannelcallback, | |
| 37 | +}; | |
| 38 | + | |
| 39 | +static void timesync_onchannelcallback(void *context); | |
| 40 | +static struct hv_util_service util_timesynch = { | |
| 41 | + .util_cb = timesync_onchannelcallback, | |
| 42 | +}; | |
| 43 | + | |
| 44 | +static void heartbeat_onchannelcallback(void *context); | |
| 45 | +static struct hv_util_service util_heartbeat = { | |
| 46 | + .util_cb = heartbeat_onchannelcallback, | |
| 47 | +}; | |
| 48 | + | |
| 49 | +static struct hv_util_service util_kvp = { | |
| 50 | + .util_cb = hv_kvp_onchannelcallback, | |
| 51 | + .util_init = hv_kvp_init, | |
| 52 | + .util_deinit = hv_kvp_deinit, | |
| 53 | +}; | |
| 38 | 54 | |
| 39 | 55 | static void shutdown_onchannelcallback(void *context) |
| 40 | 56 | { |
| @@ -42,6 +58,7 @@ static void shutdown_onchannelcallback(void *context) · 1 unmodified line | ||
| 42 | 58 | u32 recvlen; |
| 43 | 59 | u64 requestid; |
| 44 | 60 | u8 execute_shutdown = false; |
| 61 | + u8 *shut_txf_buf = util_shutdown.recv_buffer; | |
| 45 | 62 | |
| 46 | 63 | struct shutdown_msg_data *shutdown_msg; |
| 47 | 64 | |
| @@ -56,7 +73,7 @@ static void shutdown_onchannelcallback(void *context) · 8 unmodified lines | ||
| 56 | 73 | sizeof(struct vmbuspipe_hdr)]; |
| 57 | 74 | |
| 58 | 75 | if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { |
| 59 | − prep_negotiate_resp(icmsghdrp, negop, shut_txf_buf); | |
| 76 | + vmbus_prep_negotiate_resp(icmsghdrp, negop, shut_txf_buf); | |
| 60 | 77 | } else { |
| 61 | 78 | shutdown_msg = |
| 62 | 79 | (struct shutdown_msg_data *)&shut_txf_buf[ |
| @@ -91,7 +108,7 @@ static void shutdown_onchannelcallback(void *context) · 28 unmodified lines | ||
| 91 | 108 | } |
| 92 | 109 | |
| 93 | 110 | if (execute_shutdown == true) |
| 94 | − orderly_poweroff(false); | |
| 111 | + orderly_poweroff(true); | |
| 95 | 112 | } |
| 96 | 113 | |
| 97 | 114 | /* |
| @@ -108,6 +125,24 @@ static inline void do_adj_guesttime(u64 hosttime) · 10 unmodified lines | ||
| 108 | 125 | do_settimeofday(&host_ts); |
| 109 | 126 | } |
| 110 | 127 | |
| 128 | +/* | |
| 129 | + * Set the host time in a process context. | |
| 130 | + */ | |
| 131 | + | |
| 132 | +struct adj_time_work { | |
| 133 | + struct work_struct work; | |
| 134 | + u64 host_time; | |
| 135 | +}; | |
| 136 | + | |
| 137 | +static void hv_set_host_time(struct work_struct *work) | |
| 138 | +{ | |
| 139 | + struct adj_time_work *wrk; | |
| 140 | + | |
| 141 | + wrk = container_of(work, struct adj_time_work, work); | |
| 142 | + do_adj_guesttime(wrk->host_time); | |
| 143 | + kfree(wrk); | |
| 144 | +} | |
| 145 | + | |
| 111 | 146 | /* |
| 112 | 147 | * Synchronize time with host after reboot, restore, etc. |
| 113 | 148 | * |
| @@ -121,17 +156,26 @@ static inline void do_adj_guesttime(u64 hosttime) · 7 unmodified lines | ||
| 121 | 156 | */ |
| 122 | 157 | static inline void adj_guesttime(u64 hosttime, u8 flags) |
| 123 | 158 | { |
| 159 | + struct adj_time_work *wrk; | |
| 124 | 160 | static s32 scnt = 50; |
| 125 | 161 | |
| 162 | + wrk = kmalloc(sizeof(struct adj_time_work), GFP_ATOMIC); | |
| 163 | + if (wrk == NULL) | |
| 164 | + return; | |
| 165 | + | |
| 166 | + wrk->host_time = hosttime; | |
| 126 | 167 | if ((flags & ICTIMESYNCFLAG_SYNC) != 0) { |
| 127 | − do_adj_guesttime(hosttime); | |
| 168 | + INIT_WORK(&wrk->work, hv_set_host_time); | |
| 169 | + schedule_work(&wrk->work); | |
| 128 | 170 | return; |
| 129 | 171 | } |
| 130 | 172 | |
| 131 | 173 | if ((flags & ICTIMESYNCFLAG_SAMPLE) != 0 && scnt > 0) { |
| 132 | 174 | scnt--; |
| 133 | − do_adj_guesttime(hosttime); | |
| 134 | − } | |
| 175 | + INIT_WORK(&wrk->work, hv_set_host_time); | |
| 176 | + schedule_work(&wrk->work); | |
| 177 | + } else | |
| 178 | + kfree(wrk); | |
| 135 | 179 | } |
| 136 | 180 | |
| 137 | 181 | /* |
| @@ -144,6 +188,7 @@ static void timesync_onchannelcallback(void *context) · 6 unmodified lines | ||
| 144 | 188 | u64 requestid; |
| 145 | 189 | struct icmsg_hdr *icmsghdrp; |
| 146 | 190 | struct ictimesync_data *timedatap; |
| 191 | + u8 *time_txf_buf = util_timesynch.recv_buffer; | |
| 147 | 192 | |
| 148 | 193 | vmbus_recvpacket(channel, time_txf_buf, |
| 149 | 194 | PAGE_SIZE, &recvlen, &requestid); |
| @@ -153,7 +198,7 @@ static void timesync_onchannelcallback(void *context) · 3 unmodified lines | ||
| 153 | 198 | sizeof(struct vmbuspipe_hdr)]; |
| 154 | 199 | |
| 155 | 200 | if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { |
| 156 | − prep_negotiate_resp(icmsghdrp, NULL, time_txf_buf); | |
| 201 | + vmbus_prep_negotiate_resp(icmsghdrp, NULL, time_txf_buf); | |
| 157 | 202 | } else { |
| 158 | 203 | timedatap = (struct ictimesync_data *)&time_txf_buf[ |
| 159 | 204 | sizeof(struct vmbuspipe_hdr) + |
| @@ -182,6 +227,7 @@ static void heartbeat_onchannelcallback(void *context) · 22 unmodified lines | ||
| 182 | 227 | u64 requestid; |
| 183 | 228 | struct icmsg_hdr *icmsghdrp; |
| 184 | 229 | struct heartbeat_msg_data *heartbeat_msg; |
| 230 | + u8 *hbeat_txf_buf = util_heartbeat.recv_buffer; | |
| 185 | 231 | |
| 186 | 232 | vmbus_recvpacket(channel, hbeat_txf_buf, |
| 187 | 233 | PAGE_SIZE, &recvlen, &requestid); |
| @@ -191,7 +237,7 @@ static void heartbeat_onchannelcallback(void *context) · 3 unmodified lines | ||
| 191 | 237 | sizeof(struct vmbuspipe_hdr)]; |
| 192 | 238 | |
| 193 | 239 | if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { |
| 194 | − prep_negotiate_resp(icmsghdrp, NULL, hbeat_txf_buf); | |
| 240 | + vmbus_prep_negotiate_resp(icmsghdrp, NULL, hbeat_txf_buf); | |
| 195 | 241 | } else { |
| 196 | 242 | heartbeat_msg = |
| 197 | 243 | (struct heartbeat_msg_data *)&hbeat_txf_buf[ |
| @@ -210,92 +256,94 @@ static void heartbeat_onchannelcallback(void *context) · 12 unmodified lines | ||
| 210 | 256 | } |
| 211 | 257 | } |
| 212 | 258 | |
| 213 | −static const struct pci_device_id __initconst | |
| 214 | −hv_utils_pci_table[] __maybe_unused = { | |
| 215 | − { PCI_DEVICE(0x1414, 0x5353) }, /* Hyper-V emulated VGA controller */ | |
| 216 | − { 0 } | |
| 217 | −}; | |
| 218 | −MODULE_DEVICE_TABLE(pci, hv_utils_pci_table); | |
| 219 | − | |
| 220 | − | |
| 221 | −static const struct dmi_system_id __initconst | |
| 222 | −hv_utils_dmi_table[] __maybe_unused = { | |
| 223 | − { | |
| 224 | − .ident = "Hyper-V", | |
| 225 | − .matches = { | |
| 226 | − DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), | |
| 227 | − DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), | |
| 228 | − DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"), | |
| 229 | − }, | |
| 230 | − }, | |
| 231 | − { }, | |
| 232 | −}; | |
| 233 | −MODULE_DEVICE_TABLE(dmi, hv_utils_dmi_table); | |
| 234 | − | |
| 235 | − | |
| 236 | −static int __init init_hyperv_utils(void) | |
| 259 | +static int util_probe(struct hv_device *dev, | |
| 260 | + const struct hv_vmbus_device_id *dev_id) | |
| 237 | 261 | { |
| 238 | − pr_info("Registering HyperV Utility Driver\n"); | |
| 239 | − | |
| 240 | − if (hv_kvp_init()) | |
| 241 | − return -ENODEV; | |
| 242 | − | |
| 243 | − | |
| 244 | − if (!dmi_check_system(hv_utils_dmi_table)) | |
| 245 | − return -ENODEV; | |
| 246 | − | |
| 247 | − shut_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | |
| 248 | − time_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | |
| 249 | − hbeat_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | |
| 262 | + struct hv_util_service *srv = | |
| 263 | + (struct hv_util_service *)dev_id->driver_data; | |
| 264 | + int ret; | |
| 250 | 265 | |
| 251 | − if (!shut_txf_buf || !time_txf_buf || !hbeat_txf_buf) { | |
| 252 | − pr_info("Unable to allocate memory for receive buffer\n"); | |
| 253 | − kfree(shut_txf_buf); | |
| 254 | − kfree(time_txf_buf); | |
| 255 | − kfree(hbeat_txf_buf); | |
| 266 | + srv->recv_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); | |
| 267 | + if (!srv->recv_buffer) | |
| 256 | 268 | return -ENOMEM; |
| 269 | + if (srv->util_init) { | |
| 270 | + ret = srv->util_init(srv); | |
| 271 | + if (ret) { | |
| 272 | + ret = -ENODEV; | |
| 273 | + goto error1; | |
| 274 | + } | |
| 257 | 275 | } |
| 258 | 276 | |
| 259 | − hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback; | |
| 277 | + ret = vmbus_open(dev->channel, 2 * PAGE_SIZE, 2 * PAGE_SIZE, NULL, 0, | |
| 278 | + srv->util_cb, dev->channel); | |
| 279 | + if (ret) | |
| 280 | + goto error; | |
| 281 | + | |
| 282 | + hv_set_drvdata(dev, srv); | |
| 283 | + return 0; | |
| 260 | 284 | |
| 261 | − hv_cb_utils[HV_TIMESYNC_MSG].callback = ×ync_onchannelcallback; | |
| 285 | +error: | |
| 286 | + if (srv->util_deinit) | |
| 287 | + srv->util_deinit(); | |
| 288 | +error1: | |
| 289 | + kfree(srv->recv_buffer); | |
| 290 | + return ret; | |
| 291 | +} | |
| 262 | 292 | |
| 263 | − hv_cb_utils[HV_HEARTBEAT_MSG].callback = &heartbeat_onchannelcallback; | |
| 293 | +static int util_remove(struct hv_device *dev) | |
| 294 | +{ | |
| 295 | + struct hv_util_service *srv = hv_get_drvdata(dev); | |
| 264 | 296 | |
| 265 | − hv_cb_utils[HV_KVP_MSG].callback = &hv_kvp_onchannelcallback; | |
| 297 | + vmbus_close(dev->channel); | |
| 298 | + if (srv->util_deinit) | |
| 299 | + srv->util_deinit(); | |
| 300 | + kfree(srv->recv_buffer); | |
| 266 | 301 | |
| 267 | 302 | return 0; |
| 268 | 303 | } |
| 269 | 304 | |
| 270 | −static void exit_hyperv_utils(void) | |
| 271 | −{ | |
| 272 | − pr_info("De-Registered HyperV Utility Driver\n"); | |
| 305 | +static const struct hv_vmbus_device_id id_table[] = { | |
| 306 | + /* Shutdown guid */ | |
| 307 | + { VMBUS_DEVICE(0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49, | |
| 308 | + 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB) | |
| 309 | + .driver_data = (unsigned long)&util_shutdown }, | |
| 310 | + /* Time synch guid */ | |
| 311 | + { VMBUS_DEVICE(0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, | |
| 312 | + 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf) | |
| 313 | + .driver_data = (unsigned long)&util_timesynch }, | |
| 314 | + /* Heartbeat guid */ | |
| 315 | + { VMBUS_DEVICE(0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, | |
| 316 | + 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d) | |
| 317 | + .driver_data = (unsigned long)&util_heartbeat }, | |
| 318 | + /* KVP guid */ | |
| 319 | + { VMBUS_DEVICE(0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, | |
| 320 | + 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6) | |
| 321 | + .driver_data = (unsigned long)&util_kvp }, | |
| 322 | + { }, | |
| 323 | +}; | |
| 273 | 324 | |
| 274 | − if (hv_cb_utils[HV_SHUTDOWN_MSG].channel != NULL) | |
| 275 | − hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback = | |
| 276 | − &chn_cb_negotiate; | |
| 277 | − hv_cb_utils[HV_SHUTDOWN_MSG].callback = NULL; | |
| 325 | +MODULE_DEVICE_TABLE(vmbus, id_table); | |
| 278 | 326 | |
| 279 | − if (hv_cb_utils[HV_TIMESYNC_MSG].channel != NULL) | |
| 280 | − hv_cb_utils[HV_TIMESYNC_MSG].channel->onchannel_callback = | |
| 281 | − &chn_cb_negotiate; | |
| 282 | − hv_cb_utils[HV_TIMESYNC_MSG].callback = NULL; | |
| 327 | +/* The one and only one */ | |
| 328 | +static struct hv_driver util_drv = { | |
| 329 | + .name = "hv_util", | |
| 330 | + .id_table = id_table, | |
| 331 | + .probe = util_probe, | |
| 332 | + .remove = util_remove, | |
| 333 | +}; | |
| 283 | 334 | |
| 284 | − if (hv_cb_utils[HV_HEARTBEAT_MSG].channel != NULL) | |
| 285 | − hv_cb_utils[HV_HEARTBEAT_MSG].channel->onchannel_callback = | |
| 286 | − &chn_cb_negotiate; | |
| 287 | − hv_cb_utils[HV_HEARTBEAT_MSG].callback = NULL; | |
| 335 | +static int __init init_hyperv_utils(void) | |
| 336 | +{ | |
| 337 | + pr_info("Registering HyperV Utility Driver\n"); | |
| 288 | 338 | |
| 289 | − if (hv_cb_utils[HV_KVP_MSG].channel != NULL) | |
| 290 | − hv_cb_utils[HV_KVP_MSG].channel->onchannel_callback = | |
| 291 | − &chn_cb_negotiate; | |
| 292 | − hv_cb_utils[HV_KVP_MSG].callback = NULL; | |
| 339 | + return vmbus_driver_register(&util_drv); | |
| 340 | +} | |
| 293 | 341 | |
| 294 | − hv_kvp_deinit(); | |
| 342 | +static void exit_hyperv_utils(void) | |
| 343 | +{ | |
| 344 | + pr_info("De-Registered HyperV Utility Driver\n"); | |
| 295 | 345 | |
| 296 | − kfree(shut_txf_buf); | |
| 297 | − kfree(time_txf_buf); | |
| 298 | − kfree(hbeat_txf_buf); | |
| 346 | + vmbus_driver_unregister(&util_drv); | |
| 299 | 347 | } |
| 300 | 348 | |
| 301 | 349 | module_init(init_hyperv_utils); |
| @@ -28,8 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <linux/list.h> |
| 29 | 29 | #include <asm/sync_bitops.h> |
| 30 | 30 | #include <linux/atomic.h> |
| 31 | − | |
| 32 | −#include "hyperv.h" | |
| 31 | +#include <linux/hyperv.h> | |
| 33 | 32 | |
| 34 | 33 | /* |
| 35 | 34 | * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent |
| @@ -451,8 +450,8 @@ enum { · 415 unmodified lines | ||
| 451 | 450 | /* #define VMBUS_PORT_ID 11 */ |
| 452 | 451 | |
| 453 | 452 | /* 628180B8-308D-4c5e-B7DB-1BEB62E62EF4 */ |
| 454 | −static const struct hv_guid VMBUS_SERVICE_ID = { | |
| 455 | − .data = { | |
| 453 | +static const uuid_le VMBUS_SERVICE_ID = { | |
| 454 | + .b = { | |
| 456 | 455 | 0xb8, 0x80, 0x81, 0x62, 0x8d, 0x30, 0x5e, 0x4c, |
| 457 | 456 | 0xb7, 0xdb, 0x1b, 0xeb, 0x62, 0xe6, 0x2e, 0xf4 |
| 458 | 457 | }, |
| @@ -530,8 +529,6 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *ring_info, · 71 unmodified lines | ||
| 530 | 529 | |
| 531 | 530 | u32 hv_get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *ring_info); |
| 532 | 531 | |
| 533 | −void hv_dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix); | |
| 534 | − | |
| 535 | 532 | void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info, |
| 536 | 533 | struct hv_ring_buffer_debug_info *debug_info); |
| 537 | 534 | |
| @@ -601,12 +598,12 @@ extern struct vmbus_connection vmbus_connection; · 63 unmodified lines | ||
| 601 | 598 | |
| 602 | 599 | /* General vmbus interface */ |
| 603 | 600 | |
| 604 | −struct hv_device *vmbus_child_device_create(struct hv_guid *type, | |
| 605 | − struct hv_guid *instance, | |
| 601 | +struct hv_device *vmbus_device_create(uuid_le *type, | |
| 602 | + uuid_le *instance, | |
| 606 | 603 | struct vmbus_channel *channel); |
| 607 | 604 | |
| 608 | −int vmbus_child_device_register(struct hv_device *child_device_obj); | |
| 609 | −void vmbus_child_device_unregister(struct hv_device *device_obj); | |
| 605 | +int vmbus_device_register(struct hv_device *child_device_obj); | |
| 606 | +void vmbus_device_unregister(struct hv_device *device_obj); | |
| 610 | 607 | |
| 611 | 608 | /* static void */ |
| 612 | 609 | /* VmbusChildDeviceDestroy( */ |
| @@ -25,8 +25,8 @@ · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | #include <linux/kernel.h> |
| 27 | 27 | #include <linux/mm.h> |
| 28 | +#include <linux/hyperv.h> | |
| 28 | 29 | |
| 29 | −#include "hyperv.h" | |
| 30 | 30 | #include "hyperv_vmbus.h" |
| 31 | 31 | |
| 32 | 32 | |
| @@ -34,7 +34,8 @@ · 1 unmodified line | ||
| 34 | 34 | |
| 35 | 35 | |
| 36 | 36 | /* Amount of space to write to */ |
| 37 | −#define BYTES_AVAIL_TO_WRITE(r, w, z) ((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w)) | |
| 37 | +#define BYTES_AVAIL_TO_WRITE(r, w, z) \ | |
| 38 | + ((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w)) | |
| 38 | 39 | |
| 39 | 40 | |
| 40 | 41 | /* |
| @@ -171,37 +172,6 @@ hv_get_ring_bufferindices(struct hv_ring_buffer_info *ring_info) · 130 unmodified lines | ||
| 171 | 172 | return (u64)ring_info->ring_buffer->write_index << 32; |
| 172 | 173 | } |
| 173 | 174 | |
| 174 | − | |
| 175 | −/* | |
| 176 | − * | |
| 177 | − * hv_dump_ring_info() | |
| 178 | − * | |
| 179 | − * Dump out to console the ring buffer info | |
| 180 | − * | |
| 181 | − */ | |
| 182 | −void hv_dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix) | |
| 183 | −{ | |
| 184 | − u32 bytes_avail_towrite; | |
| 185 | − u32 bytes_avail_toread; | |
| 186 | − | |
| 187 | − hv_get_ringbuffer_availbytes(ring_info, | |
| 188 | − &bytes_avail_toread, | |
| 189 | − &bytes_avail_towrite); | |
| 190 | − | |
| 191 | − DPRINT(VMBUS, | |
| 192 | − DEBUG_RING_LVL, | |
| 193 | − "%s <<ringinfo %p buffer %p avail write %u " | |
| 194 | − "avail read %u read idx %u write idx %u>>", | |
| 195 | − prefix, | |
| 196 | − ring_info, | |
| 197 | − ring_info->ring_buffer->buffer, | |
| 198 | − bytes_avail_towrite, | |
| 199 | − bytes_avail_toread, | |
| 200 | − ring_info->ring_buffer->read_index, | |
| 201 | − ring_info->ring_buffer->write_index); | |
| 202 | −} | |
| 203 | − | |
| 204 | − | |
| 205 | 175 | /* |
| 206 | 176 | * |
| 207 | 177 | * hv_copyfrom_ringbuffer() |
| @@ -390,7 +360,7 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info, · 182 unmodified lines | ||
| 390 | 360 | /* is empty since the read index == write index */ |
| 391 | 361 | if (bytes_avail_towrite <= totalbytes_towrite) { |
| 392 | 362 | spin_unlock_irqrestore(&outring_info->ring_lock, flags); |
| 393 | − return -1; | |
| 363 | + return -EAGAIN; | |
| 394 | 364 | } |
| 395 | 365 | |
| 396 | 366 | /* Write to the ring buffer */ |
| @@ -450,7 +420,7 @@ int hv_ringbuffer_peek(struct hv_ring_buffer_info *Inring_info, · 53 unmodified lines | ||
| 450 | 420 | |
| 451 | 421 | spin_unlock_irqrestore(&Inring_info->ring_lock, flags); |
| 452 | 422 | |
| 453 | − return -1; | |
| 423 | + return -EAGAIN; | |
| 454 | 424 | } |
| 455 | 425 | |
| 456 | 426 | /* Convert to byte offset */ |
| @@ -496,7 +466,7 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer, · 39 unmodified lines | ||
| 496 | 466 | if (bytes_avail_toread < buflen) { |
| 497 | 467 | spin_unlock_irqrestore(&inring_info->ring_lock, flags); |
| 498 | 468 | |
| 499 | − return -1; | |
| 469 | + return -EAGAIN; | |
| 500 | 470 | } |
| 501 | 471 | |
| 502 | 472 | next_read_location = |
| @@ -28,14 +28,12 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <linux/irq.h> |
| 29 | 29 | #include <linux/interrupt.h> |
| 30 | 30 | #include <linux/sysctl.h> |
| 31 | −#include <linux/pci.h> | |
| 32 | −#include <linux/dmi.h> | |
| 33 | 31 | #include <linux/slab.h> |
| 34 | 32 | #include <linux/acpi.h> |
| 35 | 33 | #include <acpi/acpi_bus.h> |
| 36 | 34 | #include <linux/completion.h> |
| 37 | − | |
| 38 | −#include "hyperv.h" | |
| 35 | +#include <linux/hyperv.h> | |
| 36 | +#include <asm/hyperv.h> | |
| 39 | 37 | #include "hyperv_vmbus.h" |
| 40 | 38 | |
| 41 | 39 | |
| @@ -43,15 +41,28 @@ static struct acpi_device *hv_acpi_dev; · 1 unmodified line | ||
| 43 | 41 | |
| 44 | 42 | static struct tasklet_struct msg_dpc; |
| 45 | 43 | static struct tasklet_struct event_dpc; |
| 46 | − | |
| 47 | −unsigned int vmbus_loglevel = (ALL_MODULES << 16 | INFO_LVL); | |
| 48 | −EXPORT_SYMBOL(vmbus_loglevel); | |
| 49 | − /* (ALL_MODULES << 16 | DEBUG_LVL_ENTEREXIT); */ | |
| 50 | − /* (((VMBUS | VMBUS_DRV)<<16) | DEBUG_LVL_ENTEREXIT); */ | |
| 51 | − | |
| 52 | 44 | static struct completion probe_event; |
| 53 | 45 | static int irq; |
| 54 | 46 | |
| 47 | +struct hv_device_info { | |
| 48 | + u32 chn_id; | |
| 49 | + u32 chn_state; | |
| 50 | + uuid_le chn_type; | |
| 51 | + uuid_le chn_instance; | |
| 52 | + | |
| 53 | + u32 monitor_id; | |
| 54 | + u32 server_monitor_pending; | |
| 55 | + u32 server_monitor_latency; | |
| 56 | + u32 server_monitor_conn_id; | |
| 57 | + u32 client_monitor_pending; | |
| 58 | + u32 client_monitor_latency; | |
| 59 | + u32 client_monitor_conn_id; | |
| 60 | + | |
| 61 | + struct hv_dev_port_info inbound; | |
| 62 | + struct hv_dev_port_info outbound; | |
| 63 | +}; | |
| 64 | + | |
| 65 | + | |
| 55 | 66 | static void get_channel_info(struct hv_device *device, |
| 56 | 67 | struct hv_device_info *info) |
| 57 | 68 | { |
| @@ -65,9 +76,9 @@ static void get_channel_info(struct hv_device *device, · 7 unmodified lines | ||
| 65 | 76 | info->chn_id = debug_info.relid; |
| 66 | 77 | info->chn_state = debug_info.state; |
| 67 | 78 | memcpy(&info->chn_type, &debug_info.interfacetype, |
| 68 | − sizeof(struct hv_guid)); | |
| 79 | + sizeof(uuid_le)); | |
| 69 | 80 | memcpy(&info->chn_instance, &debug_info.interface_instance, |
| 70 | − sizeof(struct hv_guid)); | |
| 81 | + sizeof(uuid_le)); | |
| 71 | 82 | |
| 72 | 83 | info->monitor_id = debug_info.monitorid; |
| 73 | 84 | |
| @@ -97,6 +108,14 @@ static void get_channel_info(struct hv_device *device, · 23 unmodified lines | ||
| 97 | 108 | debug_info.outbound.bytes_avail_towrite; |
| 98 | 109 | } |
| 99 | 110 | |
| 111 | +#define VMBUS_ALIAS_LEN ((sizeof((struct hv_vmbus_device_id *)0)->guid) * 2) | |
| 112 | +static void print_alias_name(struct hv_device *hv_dev, char *alias_name) | |
| 113 | +{ | |
| 114 | + int i; | |
| 115 | + for (i = 0; i < VMBUS_ALIAS_LEN; i += 2) | |
| 116 | + sprintf(&alias_name[i], "%02x", hv_dev->dev_type.b[i/2]); | |
| 117 | +} | |
| 118 | + | |
| 100 | 119 | /* |
| 101 | 120 | * vmbus_show_device_attr - Show the device attribute in sysfs. |
| 102 | 121 | * |
| @@ -108,97 +127,105 @@ static ssize_t vmbus_show_device_attr(struct device *dev, · 5 unmodified lines | ||
| 108 | 127 | char *buf) |
| 109 | 128 | { |
| 110 | 129 | struct hv_device *hv_dev = device_to_hv_device(dev); |
| 111 | − struct hv_device_info device_info; | |
| 130 | + struct hv_device_info *device_info; | |
| 131 | + char alias_name[VMBUS_ALIAS_LEN + 1]; | |
| 132 | + int ret = 0; | |
| 112 | 133 | |
| 113 | − memset(&device_info, 0, sizeof(struct hv_device_info)); | |
| 134 | + device_info = kzalloc(sizeof(struct hv_device_info), GFP_KERNEL); | |
| 135 | + if (!device_info) | |
| 136 | + return ret; | |
| 114 | 137 | |
| 115 | − get_channel_info(hv_dev, &device_info); | |
| 138 | + get_channel_info(hv_dev, device_info); | |
| 116 | 139 | |
| 117 | 140 | if (!strcmp(dev_attr->attr.name, "class_id")) { |
| 118 | − return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-" | |
| 141 | + ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-" | |
| 119 | 142 | "%02x%02x%02x%02x%02x%02x%02x%02x}\n", |
| 120 | − device_info.chn_type.data[3], | |
| 121 | − device_info.chn_type.data[2], | |
| 122 | − device_info.chn_type.data[1], | |
| 123 | − device_info.chn_type.data[0], | |
| 124 | − device_info.chn_type.data[5], | |
| 125 | − device_info.chn_type.data[4], | |
| 126 | − device_info.chn_type.data[7], | |
| 127 | − device_info.chn_type.data[6], | |
| 128 | − device_info.chn_type.data[8], | |
| 129 | − device_info.chn_type.data[9], | |
| 130 | − device_info.chn_type.data[10], | |
| 131 | − device_info.chn_type.data[11], | |
| 132 | − device_info.chn_type.data[12], | |
| 133 | − device_info.chn_type.data[13], | |
| 134 | − device_info.chn_type.data[14], | |
| 135 | − device_info.chn_type.data[15]); | |
| 143 | + device_info->chn_type.b[3], | |
| 144 | + device_info->chn_type.b[2], | |
| 145 | + device_info->chn_type.b[1], | |
| 146 | + device_info->chn_type.b[0], | |
| 147 | + device_info->chn_type.b[5], | |
| 148 | + device_info->chn_type.b[4], | |
| 149 | + device_info->chn_type.b[7], | |
| 150 | + device_info->chn_type.b[6], | |
| 151 | + device_info->chn_type.b[8], | |
| 152 | + device_info->chn_type.b[9], | |
| 153 | + device_info->chn_type.b[10], | |
| 154 | + device_info->chn_type.b[11], | |
| 155 | + device_info->chn_type.b[12], | |
| 156 | + device_info->chn_type.b[13], | |
| 157 | + device_info->chn_type.b[14], | |
| 158 | + device_info->chn_type.b[15]); | |
| 136 | 159 | } else if (!strcmp(dev_attr->attr.name, "device_id")) { |
| 137 | − return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-" | |
| 160 | + ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-" | |
| 138 | 161 | "%02x%02x%02x%02x%02x%02x%02x%02x}\n", |
| 139 | − device_info.chn_instance.data[3], | |
| 140 | − device_info.chn_instance.data[2], | |
| 141 | − device_info.chn_instance.data[1], | |
| 142 | − device_info.chn_instance.data[0], | |
| 143 | − device_info.chn_instance.data[5], | |
| 144 | − device_info.chn_instance.data[4], | |
| 145 | − device_info.chn_instance.data[7], | |
| 146 | − device_info.chn_instance.data[6], | |
| 147 | − device_info.chn_instance.data[8], | |
| 148 | − device_info.chn_instance.data[9], | |
| 149 | − device_info.chn_instance.data[10], | |
| 150 | − device_info.chn_instance.data[11], | |
| 151 | − device_info.chn_instance.data[12], | |
| 152 | − device_info.chn_instance.data[13], | |
| 153 | − device_info.chn_instance.data[14], | |
| 154 | − device_info.chn_instance.data[15]); | |
| 162 | + device_info->chn_instance.b[3], | |
| 163 | + device_info->chn_instance.b[2], | |
| 164 | + device_info->chn_instance.b[1], | |
| 165 | + device_info->chn_instance.b[0], | |
| 166 | + device_info->chn_instance.b[5], | |
| 167 | + device_info->chn_instance.b[4], | |
| 168 | + device_info->chn_instance.b[7], | |
| 169 | + device_info->chn_instance.b[6], | |
| 170 | + device_info->chn_instance.b[8], | |
| 171 | + device_info->chn_instance.b[9], | |
| 172 | + device_info->chn_instance.b[10], | |
| 173 | + device_info->chn_instance.b[11], | |
| 174 | + device_info->chn_instance.b[12], | |
| 175 | + device_info->chn_instance.b[13], | |
| 176 | + device_info->chn_instance.b[14], | |
| 177 | + device_info->chn_instance.b[15]); | |
| 178 | + } else if (!strcmp(dev_attr->attr.name, "modalias")) { | |
| 179 | + print_alias_name(hv_dev, alias_name); | |
| 180 | + ret = sprintf(buf, "vmbus:%s\n", alias_name); | |
| 155 | 181 | } else if (!strcmp(dev_attr->attr.name, "state")) { |
| 156 | − return sprintf(buf, "%d\n", device_info.chn_state); | |
| 182 | + ret = sprintf(buf, "%d\n", device_info->chn_state); | |
| 157 | 183 | } else if (!strcmp(dev_attr->attr.name, "id")) { |
| 158 | − return sprintf(buf, "%d\n", device_info.chn_id); | |
| 184 | + ret = sprintf(buf, "%d\n", device_info->chn_id); | |
| 159 | 185 | } else if (!strcmp(dev_attr->attr.name, "out_intr_mask")) { |
| 160 | − return sprintf(buf, "%d\n", device_info.outbound.int_mask); | |
| 186 | + ret = sprintf(buf, "%d\n", device_info->outbound.int_mask); | |
| 161 | 187 | } else if (!strcmp(dev_attr->attr.name, "out_read_index")) { |
| 162 | − return sprintf(buf, "%d\n", device_info.outbound.read_idx); | |
| 188 | + ret = sprintf(buf, "%d\n", device_info->outbound.read_idx); | |
| 163 | 189 | } else if (!strcmp(dev_attr->attr.name, "out_write_index")) { |
| 164 | − return sprintf(buf, "%d\n", device_info.outbound.write_idx); | |
| 190 | + ret = sprintf(buf, "%d\n", device_info->outbound.write_idx); | |
| 165 | 191 | } else if (!strcmp(dev_attr->attr.name, "out_read_bytes_avail")) { |
| 166 | − return sprintf(buf, "%d\n", | |
| 167 | − device_info.outbound.bytes_avail_toread); | |
| 192 | + ret = sprintf(buf, "%d\n", | |
| 193 | + device_info->outbound.bytes_avail_toread); | |
| 168 | 194 | } else if (!strcmp(dev_attr->attr.name, "out_write_bytes_avail")) { |
| 169 | − return sprintf(buf, "%d\n", | |
| 170 | − device_info.outbound.bytes_avail_towrite); | |
| 195 | + ret = sprintf(buf, "%d\n", | |
| 196 | + device_info->outbound.bytes_avail_towrite); | |
| 171 | 197 | } else if (!strcmp(dev_attr->attr.name, "in_intr_mask")) { |
| 172 | − return sprintf(buf, "%d\n", device_info.inbound.int_mask); | |
| 198 | + ret = sprintf(buf, "%d\n", device_info->inbound.int_mask); | |
| 173 | 199 | } else if (!strcmp(dev_attr->attr.name, "in_read_index")) { |
| 174 | − return sprintf(buf, "%d\n", device_info.inbound.read_idx); | |
| 200 | + ret = sprintf(buf, "%d\n", device_info->inbound.read_idx); | |
| 175 | 201 | } else if (!strcmp(dev_attr->attr.name, "in_write_index")) { |
| 176 | − return sprintf(buf, "%d\n", device_info.inbound.write_idx); | |
| 202 | + ret = sprintf(buf, "%d\n", device_info->inbound.write_idx); | |
| 177 | 203 | } else if (!strcmp(dev_attr->attr.name, "in_read_bytes_avail")) { |
| 178 | − return sprintf(buf, "%d\n", | |
| 179 | − device_info.inbound.bytes_avail_toread); | |
| 204 | + ret = sprintf(buf, "%d\n", | |
| 205 | + device_info->inbound.bytes_avail_toread); | |
| 180 | 206 | } else if (!strcmp(dev_attr->attr.name, "in_write_bytes_avail")) { |
| 181 | − return sprintf(buf, "%d\n", | |
| 182 | − device_info.inbound.bytes_avail_towrite); | |
| 207 | + ret = sprintf(buf, "%d\n", | |
| 208 | + device_info->inbound.bytes_avail_towrite); | |
| 183 | 209 | } else if (!strcmp(dev_attr->attr.name, "monitor_id")) { |
| 184 | − return sprintf(buf, "%d\n", device_info.monitor_id); | |
| 210 | + ret = sprintf(buf, "%d\n", device_info->monitor_id); | |
| 185 | 211 | } else if (!strcmp(dev_attr->attr.name, "server_monitor_pending")) { |
| 186 | − return sprintf(buf, "%d\n", device_info.server_monitor_pending); | |
| 212 | + ret = sprintf(buf, "%d\n", device_info->server_monitor_pending); | |
| 187 | 213 | } else if (!strcmp(dev_attr->attr.name, "server_monitor_latency")) { |
| 188 | − return sprintf(buf, "%d\n", device_info.server_monitor_latency); | |
| 214 | + ret = sprintf(buf, "%d\n", device_info->server_monitor_latency); | |
| 189 | 215 | } else if (!strcmp(dev_attr->attr.name, "server_monitor_conn_id")) { |
| 190 | − return sprintf(buf, "%d\n", | |
| 191 | − device_info.server_monitor_conn_id); | |
| 216 | + ret = sprintf(buf, "%d\n", | |
| 217 | + device_info->server_monitor_conn_id); | |
| 192 | 218 | } else if (!strcmp(dev_attr->attr.name, "client_monitor_pending")) { |
| 193 | − return sprintf(buf, "%d\n", device_info.client_monitor_pending); | |
| 219 | + ret = sprintf(buf, "%d\n", device_info->client_monitor_pending); | |
| 194 | 220 | } else if (!strcmp(dev_attr->attr.name, "client_monitor_latency")) { |
| 195 | − return sprintf(buf, "%d\n", device_info.client_monitor_latency); | |
| 221 | + ret = sprintf(buf, "%d\n", device_info->client_monitor_latency); | |
| 196 | 222 | } else if (!strcmp(dev_attr->attr.name, "client_monitor_conn_id")) { |
| 197 | − return sprintf(buf, "%d\n", | |
| 198 | − device_info.client_monitor_conn_id); | |
| 199 | − } else { | |
| 200 | − return 0; | |
| 223 | + ret = sprintf(buf, "%d\n", | |
| 224 | + device_info->client_monitor_conn_id); | |
| 201 | 225 | } |
| 226 | + | |
| 227 | + kfree(device_info); | |
| 228 | + return ret; | |
| 202 | 229 | } |
| 203 | 230 | |
| 204 | 231 | /* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */ |
| @@ -208,6 +235,7 @@ static struct device_attribute vmbus_device_attrs[] = { · 3 unmodified lines | ||
| 208 | 235 | __ATTR(class_id, S_IRUGO, vmbus_show_device_attr, NULL), |
| 209 | 236 | __ATTR(device_id, S_IRUGO, vmbus_show_device_attr, NULL), |
| 210 | 237 | __ATTR(monitor_id, S_IRUGO, vmbus_show_device_attr, NULL), |
| 238 | + __ATTR(modalias, S_IRUGO, vmbus_show_device_attr, NULL), | |
| 211 | 239 | |
| 212 | 240 | __ATTR(server_monitor_pending, S_IRUGO, vmbus_show_device_attr, NULL), |
| 213 | 241 | __ATTR(server_monitor_latency, S_IRUGO, vmbus_show_device_attr, NULL), |
| @@ -238,76 +266,60 @@ static struct device_attribute vmbus_device_attrs[] = { · 24 unmodified lines | ||
| 238 | 266 | * This routine is invoked when a device is added or removed on the vmbus to |
| 239 | 267 | * generate a uevent to udev in the userspace. The udev will then look at its |
| 240 | 268 | * rule and the uevent generated here to load the appropriate driver |
| 269 | + * | |
| 270 | + * The alias string will be of the form vmbus:guid where guid is the string | |
| 271 | + * representation of the device guid (each byte of the guid will be | |
| 272 | + * represented with two hex characters. | |
| 241 | 273 | */ |
| 242 | 274 | static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) |
| 243 | 275 | { |
| 244 | 276 | struct hv_device *dev = device_to_hv_device(device); |
| 245 | 277 | int ret; |
| 278 | + char alias_name[VMBUS_ALIAS_LEN + 1]; | |
| 246 | 279 | |
| 247 | − ret = add_uevent_var(env, "VMBUS_DEVICE_CLASS_GUID={" | |
| 248 | − "%02x%02x%02x%02x-%02x%02x-%02x%02x-" | |
| 249 | − "%02x%02x%02x%02x%02x%02x%02x%02x}", | |
| 250 | − dev->dev_type.data[3], | |
| 251 | − dev->dev_type.data[2], | |
| 252 | − dev->dev_type.data[1], | |
| 253 | − dev->dev_type.data[0], | |
| 254 | − dev->dev_type.data[5], | |
| 255 | − dev->dev_type.data[4], | |
| 256 | − dev->dev_type.data[7], | |
| 257 | − dev->dev_type.data[6], | |
| 258 | − dev->dev_type.data[8], | |
| 259 | − dev->dev_type.data[9], | |
| 260 | − dev->dev_type.data[10], | |
| 261 | − dev->dev_type.data[11], | |
| 262 | − dev->dev_type.data[12], | |
| 263 | − dev->dev_type.data[13], | |
| 264 | − dev->dev_type.data[14], | |
| 265 | − dev->dev_type.data[15]); | |
| 280 | + print_alias_name(dev, alias_name); | |
| 281 | + ret = add_uevent_var(env, "MODALIAS=vmbus:%s", alias_name); | |
| 282 | + return ret; | |
| 283 | +} | |
| 266 | 284 | |
| 267 | − if (ret) | |
| 268 | − return ret; | |
| 285 | +static uuid_le null_guid; | |
| 269 | 286 | |
| 270 | − ret = add_uevent_var(env, "VMBUS_DEVICE_DEVICE_GUID={" | |
| 271 | − "%02x%02x%02x%02x-%02x%02x-%02x%02x-" | |
| 272 | − "%02x%02x%02x%02x%02x%02x%02x%02x}", | |
| 273 | − dev->dev_instance.data[3], | |
| 274 | − dev->dev_instance.data[2], | |
| 275 | − dev->dev_instance.data[1], | |
| 276 | − dev->dev_instance.data[0], | |
| 277 | − dev->dev_instance.data[5], | |
| 278 | − dev->dev_instance.data[4], | |
| 279 | − dev->dev_instance.data[7], | |
| 280 | − dev->dev_instance.data[6], | |
| 281 | − dev->dev_instance.data[8], | |
| 282 | − dev->dev_instance.data[9], | |
| 283 | − dev->dev_instance.data[10], | |
| 284 | − dev->dev_instance.data[11], | |
| 285 | − dev->dev_instance.data[12], | |
| 286 | − dev->dev_instance.data[13], | |
| 287 | − dev->dev_instance.data[14], | |
| 288 | − dev->dev_instance.data[15]); | |
| 289 | − if (ret) | |
| 290 | − return ret; | |
| 287 | +static inline bool is_null_guid(const __u8 *guid) | |
| 288 | +{ | |
| 289 | + if (memcmp(guid, &null_guid, sizeof(uuid_le))) | |
| 290 | + return false; | |
| 291 | + return true; | |
| 292 | +} | |
| 291 | 293 | |
| 292 | − return 0; | |
| 294 | +/* | |
| 295 | + * Return a matching hv_vmbus_device_id pointer. | |
| 296 | + * If there is no match, return NULL. | |
| 297 | + */ | |
| 298 | +static const struct hv_vmbus_device_id *hv_vmbus_get_id( | |
| 299 | + const struct hv_vmbus_device_id *id, | |
| 300 | + __u8 *guid) | |
| 301 | +{ | |
| 302 | + for (; !is_null_guid(id->guid); id++) | |
| 303 | + if (!memcmp(&id->guid, guid, sizeof(uuid_le))) | |
| 304 | + return id; | |
| 305 | + | |
| 306 | + return NULL; | |
| 293 | 307 | } |
| 294 | 308 | |
| 295 | 309 | |
| 310 | + | |
| 296 | 311 | /* |
| 297 | 312 | * vmbus_match - Attempt to match the specified device to the specified driver |
| 298 | 313 | */ |
| 299 | 314 | static int vmbus_match(struct device *device, struct device_driver *driver) |
| 300 | 315 | { |
| 301 | − int match = 0; | |
| 302 | 316 | struct hv_driver *drv = drv_to_hv_drv(driver); |
| 303 | 317 | struct hv_device *hv_dev = device_to_hv_device(device); |
| 304 | 318 | |
| 305 | − /* We found our driver ? */ | |
| 306 | − if (memcmp(&hv_dev->dev_type, &drv->dev_type, | |
| 307 | − sizeof(struct hv_guid)) == 0) | |
| 308 | − match = 1; | |
| 319 | + if (hv_vmbus_get_id(drv->id_table, hv_dev->dev_type.b)) | |
| 320 | + return 1; | |
| 309 | 321 | |
| 310 | − return match; | |
| 322 | + return 0; | |
| 311 | 323 | } |
| 312 | 324 | |
| 313 | 325 | /* |
| @@ -319,9 +331,11 @@ static int vmbus_probe(struct device *child_device) · 5 unmodified lines | ||
| 319 | 331 | struct hv_driver *drv = |
| 320 | 332 | drv_to_hv_drv(child_device->driver); |
| 321 | 333 | struct hv_device *dev = device_to_hv_device(child_device); |
| 334 | + const struct hv_vmbus_device_id *dev_id; | |
| 322 | 335 | |
| 336 | + dev_id = hv_vmbus_get_id(drv->id_table, dev->dev_type.b); | |
| 323 | 337 | if (drv->probe) { |
| 324 | − ret = drv->probe(dev); | |
| 338 | + ret = drv->probe(dev, dev_id); | |
| 325 | 339 | if (ret != 0) |
| 326 | 340 | pr_err("probe failed for device %s (%d)\n", |
| 327 | 341 | dev_name(child_device), ret); |
| @@ -339,22 +353,14 @@ static int vmbus_probe(struct device *child_device) · 11 unmodified lines | ||
| 339 | 353 | */ |
| 340 | 354 | static int vmbus_remove(struct device *child_device) |
| 341 | 355 | { |
| 342 | − int ret; | |
| 343 | − struct hv_driver *drv; | |
| 344 | − | |
| 356 | + struct hv_driver *drv = drv_to_hv_drv(child_device->driver); | |
| 345 | 357 | struct hv_device *dev = device_to_hv_device(child_device); |
| 346 | 358 | |
| 347 | − if (child_device->driver) { | |
| 348 | − drv = drv_to_hv_drv(child_device->driver); | |
| 349 | − | |
| 350 | − if (drv->remove) { | |
| 351 | − ret = drv->remove(dev); | |
| 352 | − } else { | |
| 353 | − pr_err("remove not set for driver %s\n", | |
| 354 | − dev_name(child_device)); | |
| 355 | − ret = -ENODEV; | |
| 356 | − } | |
| 357 | − } | |
| 359 | + if (drv->remove) | |
| 360 | + drv->remove(dev); | |
| 361 | + else | |
| 362 | + pr_err("remove not set for driver %s\n", | |
| 363 | + dev_name(child_device)); | |
| 358 | 364 | |
| 359 | 365 | return 0; |
| 360 | 366 | } |
| @@ -422,9 +428,6 @@ static void vmbus_onmessage_work(struct work_struct *work) · 61 unmodified lines | ||
| 422 | 428 | kfree(ctx); |
| 423 | 429 | } |
| 424 | 430 | |
| 425 | −/* | |
| 426 | − * vmbus_on_msg_dpc - DPC routine to handle messages from the hypervisior | |
| 427 | − */ | |
| 428 | 431 | static void vmbus_on_msg_dpc(unsigned long data) |
| 429 | 432 | { |
| 430 | 433 | int cpu = smp_processor_id(); |
| @@ -468,53 +471,42 @@ static void vmbus_on_msg_dpc(unsigned long data) · 37 unmodified lines | ||
| 468 | 471 | } |
| 469 | 472 | } |
| 470 | 473 | |
| 471 | −/* | |
| 472 | − * vmbus_on_isr - ISR routine | |
| 473 | − */ | |
| 474 | −static int vmbus_on_isr(void) | |
| 474 | +static irqreturn_t vmbus_isr(int irq, void *dev_id) | |
| 475 | 475 | { |
| 476 | − int ret = 0; | |
| 477 | 476 | int cpu = smp_processor_id(); |
| 478 | 477 | void *page_addr; |
| 479 | 478 | struct hv_message *msg; |
| 480 | 479 | union hv_synic_event_flags *event; |
| 480 | + bool handled = false; | |
| 481 | 481 | |
| 482 | − page_addr = hv_context.synic_message_page[cpu]; | |
| 483 | − msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; | |
| 484 | − | |
| 485 | − /* Check if there are actual msgs to be process */ | |
| 486 | − if (msg->header.message_type != HVMSG_NONE) | |
| 487 | − ret |= 0x1; | |
| 482 | + /* | |
| 483 | + * Check for events before checking for messages. This is the order | |
| 484 | + * in which events and messages are checked in Windows guests on | |
| 485 | + * Hyper-V, and the Windows team suggested we do the same. | |
| 486 | + */ | |
| 488 | 487 | |
| 489 | 488 | page_addr = hv_context.synic_event_page[cpu]; |
| 490 | 489 | event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT; |
| 491 | 490 | |
| 492 | 491 | /* Since we are a child, we only need to check bit 0 */ |
| 493 | − if (sync_test_and_clear_bit(0, (unsigned long *) &event->flags32[0])) | |
| 494 | − ret |= 0x2; | |
| 495 | − | |
| 496 | − return ret; | |
| 497 | −} | |
| 498 | − | |
| 499 | − | |
| 500 | −static irqreturn_t vmbus_isr(int irq, void *dev_id) | |
| 501 | −{ | |
| 502 | − int ret; | |
| 503 | − | |
| 504 | − ret = vmbus_on_isr(); | |
| 492 | + if (sync_test_and_clear_bit(0, (unsigned long *) &event->flags32[0])) { | |
| 493 | + handled = true; | |
| 494 | + tasklet_schedule(&event_dpc); | |
| 495 | + } | |
| 505 | 496 | |
| 506 | − /* Schedules a dpc if necessary */ | |
| 507 | − if (ret > 0) { | |
| 508 | − if (test_bit(0, (unsigned long *)&ret)) | |
| 509 | − tasklet_schedule(&msg_dpc); | |
| 497 | + page_addr = hv_context.synic_message_page[cpu]; | |
| 498 | + msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; | |
| 510 | 499 | |
| 511 | − if (test_bit(1, (unsigned long *)&ret)) | |
| 512 | − tasklet_schedule(&event_dpc); | |
| 500 | + /* Check if there are actual msgs to be processed */ | |
| 501 | + if (msg->header.message_type != HVMSG_NONE) { | |
| 502 | + handled = true; | |
| 503 | + tasklet_schedule(&msg_dpc); | |
| 504 | + } | |
| 513 | 505 | |
| 506 | + if (handled) | |
| 514 | 507 | return IRQ_HANDLED; |
| 515 | − } else { | |
| 508 | + else | |
| 516 | 509 | return IRQ_NONE; |
| 517 | − } | |
| 518 | 510 | } |
| 519 | 511 | |
| 520 | 512 | /* |
| @@ -538,26 +530,20 @@ static int vmbus_bus_init(int irq) · 17 unmodified lines | ||
| 538 | 530 | return ret; |
| 539 | 531 | } |
| 540 | 532 | |
| 541 | − /* Initialize the bus context */ | |
| 542 | 533 | tasklet_init(&msg_dpc, vmbus_on_msg_dpc, 0); |
| 543 | 534 | tasklet_init(&event_dpc, vmbus_on_event, 0); |
| 544 | 535 | |
| 545 | − /* Now, register the bus with LDM */ | |
| 546 | 536 | ret = bus_register(&hv_bus); |
| 547 | 537 | if (ret) |
| 548 | − return ret; | |
| 538 | + goto err_cleanup; | |
| 549 | 539 | |
| 550 | − /* Get the interrupt resource */ | |
| 551 | 540 | ret = request_irq(irq, vmbus_isr, IRQF_SAMPLE_RANDOM, |
| 552 | 541 | driver_name, hv_acpi_dev); |
| 553 | 542 | |
| 554 | 543 | if (ret != 0) { |
| 555 | 544 | pr_err("Unable to request IRQ %d\n", |
| 556 | 545 | irq); |
| 557 | − | |
| 558 | − bus_unregister(&hv_bus); | |
| 559 | − | |
| 560 | − return ret; | |
| 546 | + goto err_unregister; | |
| 561 | 547 | } |
| 562 | 548 | |
| 563 | 549 | vector = IRQ0_VECTOR + irq; |
| @@ -568,76 +554,81 @@ static int vmbus_bus_init(int irq) · 4 unmodified lines | ||
| 568 | 554 | */ |
| 569 | 555 | on_each_cpu(hv_synic_init, (void *)&vector, 1); |
| 570 | 556 | ret = vmbus_connect(); |
| 571 | − if (ret) { | |
| 572 | − free_irq(irq, hv_acpi_dev); | |
| 573 | − bus_unregister(&hv_bus); | |
| 574 | − return ret; | |
| 575 | − } | |
| 576 | − | |
| 557 | + if (ret) | |
| 558 | + goto err_irq; | |
| 577 | 559 | |
| 578 | 560 | vmbus_request_offers(); |
| 579 | 561 | |
| 580 | 562 | return 0; |
| 563 | + | |
| 564 | +err_irq: | |
| 565 | + free_irq(irq, hv_acpi_dev); | |
| 566 | + | |
| 567 | +err_unregister: | |
| 568 | + bus_unregister(&hv_bus); | |
| 569 | + | |
| 570 | +err_cleanup: | |
| 571 | + hv_cleanup(); | |
| 572 | + | |
| 573 | + return ret; | |
| 581 | 574 | } |
| 582 | 575 | |
| 583 | 576 | /** |
| 584 | − * vmbus_child_driver_register() - Register a vmbus's child driver | |
| 585 | − * @drv: Pointer to driver structure you want to register | |
| 586 | − * | |
| 577 | + * __vmbus_child_driver_register - Register a vmbus's driver | |
| 578 | + * @drv: Pointer to driver structure you want to register | |
| 579 | + * @owner: owner module of the drv | |
| 580 | + * @mod_name: module name string | |
| 587 | 581 | * |
| 588 | 582 | * Registers the given driver with Linux through the 'driver_register()' call |
| 589 | − * And sets up the hyper-v vmbus handling for this driver. | |
| 583 | + * and sets up the hyper-v vmbus handling for this driver. | |
| 590 | 584 | * It will return the state of the 'driver_register()' call. |
| 591 | 585 | * |
| 592 | − * Mainly used by Hyper-V drivers. | |
| 593 | 586 | */ |
| 594 | −int vmbus_child_driver_register(struct device_driver *drv) | |
| 587 | +int __vmbus_driver_register(struct hv_driver *hv_driver, struct module *owner, const char *mod_name) | |
| 595 | 588 | { |
| 596 | 589 | int ret; |
| 597 | 590 | |
| 598 | − pr_info("child driver registering - name %s\n", drv->name); | |
| 591 | + pr_info("registering driver %s\n", hv_driver->name); | |
| 599 | 592 | |
| 600 | − /* The child driver on this vmbus */ | |
| 601 | − drv->bus = &hv_bus; | |
| 593 | + hv_driver->driver.name = hv_driver->name; | |
| 594 | + hv_driver->driver.owner = owner; | |
| 595 | + hv_driver->driver.mod_name = mod_name; | |
| 596 | + hv_driver->driver.bus = &hv_bus; | |
| 602 | 597 | |
| 603 | − ret = driver_register(drv); | |
| 598 | + ret = driver_register(&hv_driver->driver); | |
| 604 | 599 | |
| 605 | 600 | vmbus_request_offers(); |
| 606 | 601 | |
| 607 | 602 | return ret; |
| 608 | 603 | } |
| 609 | −EXPORT_SYMBOL(vmbus_child_driver_register); | |
| 604 | +EXPORT_SYMBOL_GPL(__vmbus_driver_register); | |
| 610 | 605 | |
| 611 | 606 | /** |
| 612 | − * vmbus_child_driver_unregister() - Unregister a vmbus's child driver | |
| 613 | − * @drv: Pointer to driver structure you want to un-register | |
| 614 | − * | |
| 615 | − * | |
| 616 | − * Un-register the given driver with Linux through the 'driver_unregister()' | |
| 617 | − * call. And ungegisters the driver from the Hyper-V vmbus handler. | |
| 607 | + * vmbus_driver_unregister() - Unregister a vmbus's driver | |
| 608 | + * @drv: Pointer to driver structure you want to un-register | |
| 618 | 609 | * |
| 619 | − * Mainly used by Hyper-V drivers. | |
| 610 | + * Un-register the given driver that was previous registered with a call to | |
| 611 | + * vmbus_driver_register() | |
| 620 | 612 | */ |
| 621 | −void vmbus_child_driver_unregister(struct device_driver *drv) | |
| 613 | +void vmbus_driver_unregister(struct hv_driver *hv_driver) | |
| 622 | 614 | { |
| 623 | − pr_info("child driver unregistering - name %s\n", drv->name); | |
| 615 | + pr_info("unregistering driver %s\n", hv_driver->name); | |
| 624 | 616 | |
| 625 | − driver_unregister(drv); | |
| 617 | + driver_unregister(&hv_driver->driver); | |
| 626 | 618 | |
| 627 | 619 | } |
| 628 | −EXPORT_SYMBOL(vmbus_child_driver_unregister); | |
| 620 | +EXPORT_SYMBOL_GPL(vmbus_driver_unregister); | |
| 629 | 621 | |
| 630 | 622 | /* |
| 631 | − * vmbus_child_device_create - Creates and registers a new child device | |
| 623 | + * vmbus_device_create - Creates and registers a new child device | |
| 632 | 624 | * on the vmbus. |
| 633 | 625 | */ |
| 634 | −struct hv_device *vmbus_child_device_create(struct hv_guid *type, | |
| 635 | − struct hv_guid *instance, | |
| 626 | +struct hv_device *vmbus_device_create(uuid_le *type, | |
| 627 | + uuid_le *instance, | |
| 636 | 628 | struct vmbus_channel *channel) |
| 637 | 629 | { |
| 638 | 630 | struct hv_device *child_device_obj; |
| 639 | 631 | |
| 640 | − /* Allocate the new child device */ | |
| 641 | 632 | child_device_obj = kzalloc(sizeof(struct hv_device), GFP_KERNEL); |
| 642 | 633 | if (!child_device_obj) { |
| 643 | 634 | 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, · 1 unmodified line | ||
| 645 | 636 | } |
| 646 | 637 | |
| 647 | 638 | child_device_obj->channel = channel; |
| 648 | − memcpy(&child_device_obj->dev_type, type, sizeof(struct hv_guid)); | |
| 639 | + memcpy(&child_device_obj->dev_type, type, sizeof(uuid_le)); | |
| 649 | 640 | memcpy(&child_device_obj->dev_instance, instance, |
| 650 | − sizeof(struct hv_guid)); | |
| 641 | + sizeof(uuid_le)); | |
| 651 | 642 | |
| 652 | 643 | |
| 653 | 644 | return child_device_obj; |
| 654 | 645 | } |
| 655 | 646 | |
| 656 | 647 | /* |
| 657 | − * vmbus_child_device_register - Register the child device | |
| 648 | + * vmbus_device_register - Register the child device | |
| 658 | 649 | */ |
| 659 | −int vmbus_child_device_register(struct hv_device *child_device_obj) | |
| 650 | +int vmbus_device_register(struct hv_device *child_device_obj) | |
| 660 | 651 | { |
| 661 | 652 | int ret = 0; |
| 662 | 653 | |
| 663 | 654 | static atomic_t device_num = ATOMIC_INIT(0); |
| 664 | 655 | |
| 665 | − /* Set the device name. Otherwise, device_register() will fail. */ | |
| 666 | 656 | dev_set_name(&child_device_obj->device, "vmbus_0_%d", |
| 667 | 657 | atomic_inc_return(&device_num)); |
| 668 | 658 | |
| 669 | − /* The new device belongs to this bus */ | |
| 670 | − child_device_obj->device.bus = &hv_bus; /* device->dev.bus; */ | |
| 659 | + child_device_obj->device.bus = &hv_bus; | |
| 671 | 660 | child_device_obj->device.parent = &hv_acpi_dev->dev; |
| 672 | 661 | child_device_obj->device.release = vmbus_device_release; |
| 673 | 662 | |
| @@ -687,10 +676,10 @@ int vmbus_child_device_register(struct hv_device *child_device_obj) · 13 unmodified lines | ||
| 687 | 676 | } |
| 688 | 677 | |
| 689 | 678 | /* |
| 690 | − * vmbus_child_device_unregister - Remove the specified child device | |
| 679 | + * vmbus_device_unregister - Remove the specified child device | |
| 691 | 680 | * from the vmbus. |
| 692 | 681 | */ |
| 693 | −void vmbus_child_device_unregister(struct hv_device *device_obj) | |
| 682 | +void vmbus_device_unregister(struct hv_device *device_obj) | |
| 694 | 683 | { |
| 695 | 684 | /* |
| 696 | 685 | * Kick off the process of unregistering the device. |
| @@ -727,9 +716,8 @@ static int vmbus_acpi_add(struct acpi_device *device) · 30 unmodified lines | ||
| 727 | 716 | |
| 728 | 717 | hv_acpi_dev = device; |
| 729 | 718 | |
| 730 | − result = | |
| 731 | − acpi_walk_resources(device->handle, METHOD_NAME__CRS, | |
| 732 | − vmbus_walk_resources, &irq); | |
| 719 | + result = acpi_walk_resources(device->handle, METHOD_NAME__CRS, | |
| 720 | + vmbus_walk_resources, &irq); | |
| 733 | 721 | |
| 734 | 722 | if (ACPI_FAILURE(result)) { |
| 735 | 723 | complete(&probe_event); |
| @@ -754,21 +742,9 @@ static struct acpi_driver vmbus_acpi_driver = { · 18 unmodified lines | ||
| 754 | 742 | }, |
| 755 | 743 | }; |
| 756 | 744 | |
| 757 | −/* | |
| 758 | − * We use a PCI table to determine if we should autoload this driver This is | |
| 759 | − * needed by distro tools to determine if the hyperv drivers should be | |
| 760 | − * installed and/or configured. We don't do anything else with the table, but | |
| 761 | − * it needs to be present. | |
| 762 | − */ | |
| 763 | −static const struct pci_device_id microsoft_hv_pci_table[] = { | |
| 764 | − { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */ | |
| 765 | − { 0 } | |
| 766 | −}; | |
| 767 | −MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table); | |
| 768 | − | |
| 769 | 745 | static int __init hv_acpi_init(void) |
| 770 | 746 | { |
| 771 | − int ret; | |
| 747 | + int ret, t; | |
| 772 | 748 | |
| 773 | 749 | init_completion(&probe_event); |
| 774 | 750 | |
| @@ -781,22 +757,30 @@ static int __init hv_acpi_init(void) · 6 unmodified lines | ||
| 781 | 757 | if (ret) |
| 782 | 758 | return ret; |
| 783 | 759 | |
| 784 | − wait_for_completion(&probe_event); | |
| 760 | + t = wait_for_completion_timeout(&probe_event, 5*HZ); | |
| 761 | + if (t == 0) { | |
| 762 | + ret = -ETIMEDOUT; | |
| 763 | + goto cleanup; | |
| 764 | + } | |
| 785 | 765 | |
| 786 | 766 | if (irq <= 0) { |
| 787 | − acpi_bus_unregister_driver(&vmbus_acpi_driver); | |
| 788 | − return -ENODEV; | |
| 767 | + ret = -ENODEV; | |
| 768 | + goto cleanup; | |
| 789 | 769 | } |
| 790 | 770 | |
| 791 | 771 | ret = vmbus_bus_init(irq); |
| 792 | 772 | if (ret) |
| 793 | − acpi_bus_unregister_driver(&vmbus_acpi_driver); | |
| 773 | + goto cleanup; | |
| 774 | + | |
| 775 | + return 0; | |
| 776 | + | |
| 777 | +cleanup: | |
| 778 | + acpi_bus_unregister_driver(&vmbus_acpi_driver); | |
| 794 | 779 | return ret; |
| 795 | 780 | } |
| 796 | 781 | |
| 797 | 782 | |
| 798 | 783 | MODULE_LICENSE("GPL"); |
| 799 | 784 | MODULE_VERSION(HV_DRV_VERSION); |
| 800 | −module_param(vmbus_loglevel, int, S_IRUGO|S_IWUSR); | |
| 801 | 785 | |
| 802 | 786 | module_init(hv_acpi_init); |
| @@ -46,8 +46,6 @@ source "drivers/staging/wlan-ng/Kconfig" · 45 unmodified lines | ||
| 46 | 46 | |
| 47 | 47 | source "drivers/staging/echo/Kconfig" |
| 48 | 48 | |
| 49 | − | |
| 50 | − | |
| 51 | 49 | source "drivers/staging/comedi/Kconfig" |
| 52 | 50 | |
| 53 | 51 | source "drivers/staging/olpc_dcon/Kconfig" |
| @@ -66,6 +64,8 @@ source "drivers/staging/rtl8712/Kconfig" · 12 unmodified lines | ||
| 66 | 64 | |
| 67 | 65 | source "drivers/staging/rts_pstor/Kconfig" |
| 68 | 66 | |
| 67 | +source "drivers/staging/rts5139/Kconfig" | |
| 68 | + | |
| 69 | 69 | source "drivers/staging/frontier/Kconfig" |
| 70 | 70 | |
| 71 | 71 | source "drivers/staging/pohmelfs/Kconfig" |
| @@ -15,8 +15,6 @@ obj-$(CONFIG_USBIP_CORE) += usbip/ · 14 unmodified lines | ||
| 15 | 15 | obj-$(CONFIG_W35UND) += winbond/ |
| 16 | 16 | obj-$(CONFIG_PRISM2_USB) += wlan-ng/ |
| 17 | 17 | obj-$(CONFIG_ECHO) += echo/ |
| 18 | − | |
| 19 | − | |
| 20 | 18 | obj-$(CONFIG_COMEDI) += comedi/ |
| 21 | 19 | obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/ |
| 22 | 20 | obj-$(CONFIG_ASUS_OLED) += asus_oled/ |
| @@ -26,6 +24,7 @@ obj-$(CONFIG_RTL8192U) += rtl8192u/ · 3 unmodified lines | ||
| 26 | 24 | obj-$(CONFIG_RTL8192E) += rtl8192e/ |
| 27 | 25 | obj-$(CONFIG_R8712U) += rtl8712/ |
| 28 | 26 | obj-$(CONFIG_RTS_PSTOR) += rts_pstor/ |
| 27 | +obj-$(CONFIG_RTS5139) += rts5139/ | |
| 29 | 28 | obj-$(CONFIG_SPECTRA) += spectra/ |
| 30 | 29 | obj-$(CONFIG_TRANZPORT) += frontier/ |
| 31 | 30 | obj-$(CONFIG_POHMELFS) += pohmelfs/ |
| @@ -28,6 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <linux/string.h> |
| 29 | 29 | #include <linux/firmware.h> |
| 30 | 30 | #include <linux/slab.h> |
| 31 | +#include <linux/module.h> | |
| 31 | 32 | #include "altera.h" |
| 32 | 33 | #include "altera-exprt.h" |
| 33 | 34 | #include "altera-jtag.h" |
| @@ -2384,7 +2385,7 @@ static int altera_get_act_info(u8 *p, · 2350 unmodified lines | ||
| 2384 | 2385 | act_proc_attribute = |
| 2385 | 2386 | (p[proc_table + (13 * act_proc_id) + 8] & 0x03); |
| 2386 | 2387 | |
| 2387 | − procptr = (struct altera_procinfo *) | |
| 2388 | + procptr = | |
| 2388 | 2389 | kzalloc(sizeof(struct altera_procinfo), |
| 2389 | 2390 | GFP_KERNEL); |
| 2390 | 2391 | |
| @@ -34,7 +34,7 @@ static int bcm_char_open(struct inode *inode, struct file * filp) · 33 unmodified lines | ||
| 34 | 34 | /* Store the Adapter structure */ |
| 35 | 35 | filp->private_data = pTarang; |
| 36 | 36 | |
| 37 | − /*Start Queuing the control response Packets*/ | |
| 37 | + /* Start Queuing the control response Packets */ | |
| 38 | 38 | atomic_inc(&Adapter->ApplicationRunning); |
| 39 | 39 | |
| 40 | 40 | nonseekable_open(inode, filp); |
| @@ -84,7 +84,7 @@ static int bcm_char_release(struct inode *inode, struct file *filp) · 43 unmodified lines | ||
| 84 | 84 | |
| 85 | 85 | up(&Adapter->RxAppControlQueuelock); |
| 86 | 86 | |
| 87 | − /*Stop Queuing the control response Packets*/ | |
| 87 | + /* Stop Queuing the control response Packets */ | |
| 88 | 88 | atomic_dec(&Adapter->ApplicationRunning); |
| 89 | 89 | |
| 90 | 90 | kfree(pTarang); |
| @@ -100,8 +100,8 @@ static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size, · 9 unmodified lines | ||
| 100 | 100 | PPER_TARANG_DATA pTarang = filp->private_data; |
| 101 | 101 | PMINI_ADAPTER Adapter = pTarang->Adapter; |
| 102 | 102 | struct sk_buff *Packet = NULL; |
| 103 | − ssize_t PktLen = 0; | |
| 104 | − int wait_ret_val = 0; | |
| 103 | + ssize_t PktLen = 0; | |
| 104 | + int wait_ret_val = 0; | |
| 105 | 105 | unsigned long ret = 0; |
| 106 | 106 | |
| 107 | 107 | wait_ret_val = wait_event_interruptible(Adapter->process_read_wait_queue, |
| @@ -157,1942 +157,1824 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) · 49 unmodified lines | ||
| 157 | 157 | { |
| 158 | 158 | PPER_TARANG_DATA pTarang = filp->private_data; |
| 159 | 159 | void __user *argp = (void __user *)arg; |
| 160 | − PMINI_ADAPTER Adapter = pTarang->Adapter; | |
| 161 | − INT Status = STATUS_FAILURE; | |
| 160 | + PMINI_ADAPTER Adapter = pTarang->Adapter; | |
| 161 | + INT Status = STATUS_FAILURE; | |
| 162 | 162 | int timeout = 0; |
| 163 | − IOCTL_BUFFER IoBuffer; | |
| 163 | + IOCTL_BUFFER IoBuffer; | |
| 164 | 164 | |
| 165 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX", cmd, arg); | |
| 165 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX", cmd, arg); | |
| 166 | 166 | |
| 167 | − if(_IOC_TYPE(cmd) != BCM_IOCTL) | |
| 167 | + if (_IOC_TYPE(cmd) != BCM_IOCTL) | |
| 168 | 168 | return -EFAULT; |
| 169 | − if(_IOC_DIR(cmd) & _IOC_READ) | |
| 169 | + if (_IOC_DIR(cmd) & _IOC_READ) | |
| 170 | 170 | Status = !access_ok(VERIFY_WRITE, argp, _IOC_SIZE(cmd)); |
| 171 | 171 | else if (_IOC_DIR(cmd) & _IOC_WRITE) |
| 172 | − Status = !access_ok(VERIFY_READ, argp, _IOC_SIZE(cmd)); | |
| 172 | + Status = !access_ok(VERIFY_READ, argp, _IOC_SIZE(cmd)); | |
| 173 | 173 | else if (_IOC_NONE == (_IOC_DIR(cmd) & _IOC_NONE)) |
| 174 | − Status = STATUS_SUCCESS; | |
| 174 | + Status = STATUS_SUCCESS; | |
| 175 | 175 | |
| 176 | − if(Status) | |
| 176 | + if (Status) | |
| 177 | 177 | return -EFAULT; |
| 178 | 178 | |
| 179 | − if(Adapter->device_removed) | |
| 180 | − { | |
| 179 | + if (Adapter->device_removed) | |
| 181 | 180 | return -EFAULT; |
| 182 | − } | |
| 183 | 181 | |
| 184 | − if(FALSE == Adapter->fw_download_done) | |
| 185 | − { | |
| 186 | − switch (cmd) | |
| 187 | − { | |
| 188 | − case IOCTL_MAC_ADDR_REQ: | |
| 189 | − case IOCTL_LINK_REQ: | |
| 190 | − case IOCTL_CM_REQUEST: | |
| 191 | − case IOCTL_SS_INFO_REQ: | |
| 192 | − case IOCTL_SEND_CONTROL_MESSAGE: | |
| 193 | − case IOCTL_IDLE_REQ: | |
| 194 | − case IOCTL_BCM_GPIO_SET_REQUEST: | |
| 195 | − case IOCTL_BCM_GPIO_STATUS_REQUEST: | |
| 196 | − return -EACCES; | |
| 197 | − default: | |
| 198 | − break; | |
| 182 | + if (FALSE == Adapter->fw_download_done) { | |
| 183 | + switch (cmd) { | |
| 184 | + case IOCTL_MAC_ADDR_REQ: | |
| 185 | + case IOCTL_LINK_REQ: | |
| 186 | + case IOCTL_CM_REQUEST: | |
| 187 | + case IOCTL_SS_INFO_REQ: | |
| 188 | + case IOCTL_SEND_CONTROL_MESSAGE: | |
| 189 | + case IOCTL_IDLE_REQ: | |
| 190 | + case IOCTL_BCM_GPIO_SET_REQUEST: | |
| 191 | + case IOCTL_BCM_GPIO_STATUS_REQUEST: | |
| 192 | + return -EACCES; | |
| 193 | + default: | |
| 194 | + break; | |
| 199 | 195 | } |
| 200 | 196 | } |
| 201 | 197 | |
| 202 | 198 | Status = vendorextnIoctl(Adapter, cmd, arg); |
| 203 | − if(Status != CONTINUE_COMMON_PATH ) | |
| 204 | − return Status; | |
| 205 | − | |
| 206 | − switch(cmd){ | |
| 207 | − // Rdms for Swin Idle... | |
| 208 | − case IOCTL_BCM_REGISTER_READ_PRIVATE: | |
| 209 | − { | |
| 210 | − RDM_BUFFER sRdmBuffer = {0}; | |
| 211 | − PCHAR temp_buff; | |
| 212 | − UINT Bufflen; | |
| 199 | + if (Status != CONTINUE_COMMON_PATH) | |
| 200 | + return Status; | |
| 201 | + | |
| 202 | + switch (cmd) { | |
| 203 | + /* Rdms for Swin Idle... */ | |
| 204 | + case IOCTL_BCM_REGISTER_READ_PRIVATE: { | |
| 205 | + RDM_BUFFER sRdmBuffer = {0}; | |
| 206 | + PCHAR temp_buff; | |
| 207 | + UINT Bufflen; | |
| 208 | + u16 temp_value; | |
| 209 | + | |
| 210 | + /* Copy Ioctl Buffer structure */ | |
| 211 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 212 | + return -EFAULT; | |
| 213 | 213 | |
| 214 | − /* Copy Ioctl Buffer structure */ | |
| 215 | − if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 216 | − return -EFAULT; | |
| 214 | + if (IoBuffer.InputLength > sizeof(sRdmBuffer)) | |
| 215 | + return -EINVAL; | |
| 217 | 216 | |
| 218 | − if (IoBuffer.InputLength > sizeof(sRdmBuffer)) | |
| 219 | − return -EINVAL; | |
| 217 | + if (copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 218 | + return -EFAULT; | |
| 220 | 219 | |
| 221 | − if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 222 | − return -EFAULT; | |
| 220 | + if (IoBuffer.OutputLength > USHRT_MAX || | |
| 221 | + IoBuffer.OutputLength == 0) { | |
| 222 | + return -EINVAL; | |
| 223 | + } | |
| 223 | 224 | |
| 224 | − /* FIXME: need to restrict BuffLen */ | |
| 225 | − Bufflen = IoBuffer.OutputLength + (4 - IoBuffer.OutputLength%4)%4; | |
| 226 | − temp_buff = kmalloc(Bufflen, GFP_KERNEL); | |
| 227 | − if(!temp_buff) | |
| 228 | − return -ENOMEM; | |
| 225 | + Bufflen = IoBuffer.OutputLength; | |
| 226 | + temp_value = 4 - (Bufflen % 4); | |
| 227 | + Bufflen += temp_value % 4; | |
| 229 | 228 | |
| 230 | − Status = rdmalt(Adapter, (UINT)sRdmBuffer.Register, | |
| 231 | − (PUINT)temp_buff, Bufflen); | |
| 232 | − if(Status == STATUS_SUCCESS) | |
| 233 | − { | |
| 234 | − if(copy_to_user(IoBuffer.OutputBuffer, temp_buff, IoBuffer.OutputLength)) | |
| 235 | − Status = -EFAULT; | |
| 236 | − } | |
| 229 | + temp_buff = kmalloc(Bufflen, GFP_KERNEL); | |
| 230 | + if (!temp_buff) | |
| 231 | + return -ENOMEM; | |
| 237 | 232 | |
| 238 | − kfree(temp_buff); | |
| 239 | − break; | |
| 233 | + Status = rdmalt(Adapter, (UINT)sRdmBuffer.Register, | |
| 234 | + (PUINT)temp_buff, Bufflen); | |
| 235 | + if (Status == STATUS_SUCCESS) { | |
| 236 | + if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, IoBuffer.OutputLength)) | |
| 237 | + Status = -EFAULT; | |
| 240 | 238 | } |
| 241 | − case IOCTL_BCM_REGISTER_WRITE_PRIVATE: | |
| 242 | − { | |
| 243 | − WRM_BUFFER sWrmBuffer = {0}; | |
| 244 | − UINT uiTempVar=0; | |
| 245 | − /* Copy Ioctl Buffer structure */ | |
| 246 | 239 | |
| 247 | − if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 248 | − return -EFAULT; | |
| 240 | + kfree(temp_buff); | |
| 241 | + break; | |
| 242 | + } | |
| 249 | 243 | |
| 250 | − if (IoBuffer.InputLength > sizeof(sWrmBuffer)) | |
| 251 | − return -EINVAL; | |
| 244 | + case IOCTL_BCM_REGISTER_WRITE_PRIVATE: { | |
| 245 | + WRM_BUFFER sWrmBuffer = {0}; | |
| 246 | + UINT uiTempVar = 0; | |
| 247 | + /* Copy Ioctl Buffer structure */ | |
| 252 | 248 | |
| 253 | − /* Get WrmBuffer structure */ | |
| 254 | − if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 255 | − return -EFAULT; | |
| 249 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 250 | + return -EFAULT; | |
| 251 | + | |
| 252 | + if (IoBuffer.InputLength > sizeof(sWrmBuffer)) | |
| 253 | + return -EINVAL; | |
| 256 | 254 | |
| 257 | − uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK; | |
| 258 | − if(!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) && | |
| 259 | − ((uiTempVar == EEPROM_REJECT_REG_1)|| | |
| 255 | + /* Get WrmBuffer structure */ | |
| 256 | + if (copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 257 | + return -EFAULT; | |
| 258 | + | |
| 259 | + uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK; | |
| 260 | + if (!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) && | |
| 261 | + ((uiTempVar == EEPROM_REJECT_REG_1) || | |
| 260 | 262 | (uiTempVar == EEPROM_REJECT_REG_2) || |
| 261 | 263 | (uiTempVar == EEPROM_REJECT_REG_3) || |
| 262 | − (uiTempVar == EEPROM_REJECT_REG_4))) | |
| 263 | − { | |
| 264 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); | |
| 265 | − return -EFAULT; | |
| 266 | − } | |
| 267 | − Status = wrmalt(Adapter, (UINT)sWrmBuffer.Register, | |
| 268 | − (PUINT)sWrmBuffer.Data, sizeof(ULONG)); | |
| 269 | − if(Status == STATUS_SUCCESS) | |
| 270 | − { | |
| 271 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"WRM Done\n"); | |
| 272 | − } | |
| 273 | − else | |
| 274 | − { | |
| 275 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n"); | |
| 276 | − Status = -EFAULT; | |
| 277 | − } | |
| 278 | − break; | |
| 264 | + (uiTempVar == EEPROM_REJECT_REG_4))) { | |
| 265 | + | |
| 266 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); | |
| 267 | + return -EFAULT; | |
| 279 | 268 | } |
| 280 | 269 | |
| 281 | − case IOCTL_BCM_REGISTER_READ: | |
| 282 | − case IOCTL_BCM_EEPROM_REGISTER_READ: | |
| 283 | − { | |
| 284 | − RDM_BUFFER sRdmBuffer = {0}; | |
| 285 | − PCHAR temp_buff = NULL; | |
| 286 | − UINT uiTempVar = 0; | |
| 287 | − if((Adapter->IdleMode == TRUE) || | |
| 288 | − (Adapter->bShutStatus ==TRUE) || | |
| 289 | − (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
| 290 | − { | |
| 291 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Rdms\n"); | |
| 292 | − return -EACCES; | |
| 293 | − } | |
| 294 | − /* Copy Ioctl Buffer structure */ | |
| 295 | − if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 296 | − return -EFAULT; | |
| 270 | + Status = wrmalt(Adapter, (UINT)sWrmBuffer.Register, | |
| 271 | + (PUINT)sWrmBuffer.Data, sizeof(ULONG)); | |
| 297 | 272 | |
| 298 | − if (IoBuffer.InputLength > sizeof(sRdmBuffer)) | |
| 299 | − return -EINVAL; | |
| 273 | + if (Status == STATUS_SUCCESS) { | |
| 274 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n"); | |
| 275 | + } else { | |
| 276 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n"); | |
| 277 | + Status = -EFAULT; | |
| 278 | + } | |
| 279 | + break; | |
| 280 | + } | |
| 300 | 281 | |
| 301 | − if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 302 | − return -EFAULT; | |
| 282 | + case IOCTL_BCM_REGISTER_READ: | |
| 283 | + case IOCTL_BCM_EEPROM_REGISTER_READ: { | |
| 284 | + RDM_BUFFER sRdmBuffer = {0}; | |
| 285 | + PCHAR temp_buff = NULL; | |
| 286 | + UINT uiTempVar = 0; | |
| 287 | + if ((Adapter->IdleMode == TRUE) || | |
| 288 | + (Adapter->bShutStatus == TRUE) || | |
| 289 | + (Adapter->bPreparingForLowPowerMode == TRUE)) { | |
| 290 | + | |
| 291 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Rdms\n"); | |
| 292 | + return -EACCES; | |
| 293 | + } | |
| 303 | 294 | |
| 304 | − /* FIXME: don't trust user supplied length */ | |
| 305 | − temp_buff = kmalloc(IoBuffer.OutputLength, GFP_KERNEL); | |
| 306 | − if(!temp_buff) | |
| 307 | − return STATUS_FAILURE; | |
| 295 | + /* Copy Ioctl Buffer structure */ | |
| 296 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 297 | + return -EFAULT; | |
| 308 | 298 | |
| 309 | − if((((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) || | |
| 310 | − ((ULONG)sRdmBuffer.Register & 0x3)) | |
| 311 | − { | |
| 312 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "RDM Done On invalid Address : %x Access Denied.\n", | |
| 313 | − (int)sRdmBuffer.Register); | |
| 314 | − return -EINVAL; | |
| 315 | − } | |
| 299 | + if (IoBuffer.InputLength > sizeof(sRdmBuffer)) | |
| 300 | + return -EINVAL; | |
| 301 | + | |
| 302 | + if (copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 303 | + return -EFAULT; | |
| 316 | 304 | |
| 317 | − uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK; | |
| 318 | − Status = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register, | |
| 319 | − (PUINT)temp_buff, IoBuffer.OutputLength); | |
| 320 | − if(Status == STATUS_SUCCESS) | |
| 321 | − if(copy_to_user(IoBuffer.OutputBuffer, temp_buff, IoBuffer.OutputLength)) | |
| 322 | − Status = -EFAULT; | |
| 305 | + /* FIXME: don't trust user supplied length */ | |
| 306 | + temp_buff = kmalloc(IoBuffer.OutputLength, GFP_KERNEL); | |
| 307 | + if (!temp_buff) | |
| 308 | + return STATUS_FAILURE; | |
| 309 | + | |
| 310 | + if ((((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) || | |
| 311 | + ((ULONG)sRdmBuffer.Register & 0x3)) { | |
| 312 | + | |
| 313 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM Done On invalid Address : %x Access Denied.\n", | |
| 314 | + (int)sRdmBuffer.Register); | |
| 323 | 315 | |
| 324 | 316 | kfree(temp_buff); |
| 325 | − break; | |
| 317 | + return -EINVAL; | |
| 326 | 318 | } |
| 327 | − case IOCTL_BCM_REGISTER_WRITE: | |
| 328 | − case IOCTL_BCM_EEPROM_REGISTER_WRITE: | |
| 329 | − { | |
| 330 | − WRM_BUFFER sWrmBuffer = {0}; | |
| 331 | − UINT uiTempVar=0; | |
| 332 | − if((Adapter->IdleMode == TRUE) || | |
| 333 | − (Adapter->bShutStatus ==TRUE) || | |
| 334 | − (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
| 335 | − { | |
| 336 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Wrms\n"); | |
| 337 | − return -EACCES; | |
| 338 | − } | |
| 339 | 319 | |
| 340 | − /* Copy Ioctl Buffer structure */ | |
| 341 | − if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 342 | − return -EFAULT; | |
| 320 | + uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK; | |
| 321 | + Status = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register, (PUINT)temp_buff, IoBuffer.OutputLength); | |
| 343 | 322 | |
| 344 | − if (IoBuffer.InputLength > sizeof(sWrmBuffer)) | |
| 345 | − return -EINVAL; | |
| 323 | + if (Status == STATUS_SUCCESS) | |
| 324 | + if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, IoBuffer.OutputLength)) | |
| 325 | + Status = -EFAULT; | |
| 346 | 326 | |
| 347 | − /* Get WrmBuffer structure */ | |
| 348 | − if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 349 | − return -EFAULT; | |
| 327 | + kfree(temp_buff); | |
| 328 | + break; | |
| 329 | + } | |
| 330 | + case IOCTL_BCM_REGISTER_WRITE: | |
| 331 | + case IOCTL_BCM_EEPROM_REGISTER_WRITE: { | |
| 332 | + WRM_BUFFER sWrmBuffer = {0}; | |
| 333 | + UINT uiTempVar = 0; | |
| 334 | + if ((Adapter->IdleMode == TRUE) || | |
| 335 | + (Adapter->bShutStatus == TRUE) || | |
| 336 | + (Adapter->bPreparingForLowPowerMode == TRUE)) { | |
| 337 | + | |
| 338 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Wrms\n"); | |
| 339 | + return -EACCES; | |
| 340 | + } | |
| 350 | 341 | |
| 351 | − if( (((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) || | |
| 352 | − ((ULONG)sWrmBuffer.Register & 0x3) ) | |
| 353 | − { | |
| 354 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n", | |
| 355 | − (int)sWrmBuffer.Register); | |
| 356 | − return -EINVAL; | |
| 357 | − } | |
| 342 | + /* Copy Ioctl Buffer structure */ | |
| 343 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 344 | + return -EFAULT; | |
| 345 | + | |
| 346 | + if (IoBuffer.InputLength > sizeof(sWrmBuffer)) | |
| 347 | + return -EINVAL; | |
| 348 | + | |
| 349 | + /* Get WrmBuffer structure */ | |
| 350 | + if (copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 351 | + return -EFAULT; | |
| 358 | 352 | |
| 359 | − uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK; | |
| 360 | − if(!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) && | |
| 361 | − ((uiTempVar == EEPROM_REJECT_REG_1)|| | |
| 353 | + if ((((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) || | |
| 354 | + ((ULONG)sWrmBuffer.Register & 0x3)) { | |
| 355 | + | |
| 356 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n", (int)sWrmBuffer.Register); | |
| 357 | + return -EINVAL; | |
| 358 | + } | |
| 359 | + | |
| 360 | + uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK; | |
| 361 | + if (!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) && | |
| 362 | + ((uiTempVar == EEPROM_REJECT_REG_1) || | |
| 362 | 363 | (uiTempVar == EEPROM_REJECT_REG_2) || |
| 363 | 364 | (uiTempVar == EEPROM_REJECT_REG_3) || |
| 364 | 365 | (uiTempVar == EEPROM_REJECT_REG_4)) && |
| 365 | − (cmd == IOCTL_BCM_REGISTER_WRITE)) | |
| 366 | − { | |
| 367 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); | |
| 366 | + (cmd == IOCTL_BCM_REGISTER_WRITE)) { | |
| 367 | + | |
| 368 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); | |
| 368 | 369 | return -EFAULT; |
| 369 | − } | |
| 370 | + } | |
| 370 | 371 | |
| 371 | − Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register, | |
| 372 | − (PUINT)sWrmBuffer.Data, sWrmBuffer.Length); | |
| 373 | − if(Status == STATUS_SUCCESS) | |
| 374 | − { | |
| 375 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n"); | |
| 376 | − } | |
| 377 | − else | |
| 378 | − { | |
| 379 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n"); | |
| 380 | − Status = -EFAULT; | |
| 381 | − } | |
| 372 | + Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register, | |
| 373 | + (PUINT)sWrmBuffer.Data, sWrmBuffer.Length); | |
| 374 | + | |
| 375 | + if (Status == STATUS_SUCCESS) { | |
| 376 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n"); | |
| 377 | + } else { | |
| 378 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n"); | |
| 379 | + Status = -EFAULT; | |
| 380 | + } | |
| 381 | + break; | |
| 382 | + } | |
| 383 | + case IOCTL_BCM_GPIO_SET_REQUEST: { | |
| 384 | + UCHAR ucResetValue[4]; | |
| 385 | + UINT value = 0; | |
| 386 | + UINT uiBit = 0; | |
| 387 | + UINT uiOperation = 0; | |
| 388 | + | |
| 389 | + GPIO_INFO gpio_info = {0}; | |
| 390 | + if ((Adapter->IdleMode == TRUE) || | |
| 391 | + (Adapter->bShutStatus == TRUE) || | |
| 392 | + (Adapter->bPreparingForLowPowerMode == TRUE)) { | |
| 393 | + | |
| 394 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "GPIO Can't be set/clear in Low power Mode"); | |
| 395 | + return -EACCES; | |
| 396 | + } | |
| 397 | + | |
| 398 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 399 | + return -EFAULT; | |
| 400 | + | |
| 401 | + if (IoBuffer.InputLength > sizeof(gpio_info)) | |
| 402 | + return -EINVAL; | |
| 403 | + | |
| 404 | + if (copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 405 | + return -EFAULT; | |
| 406 | + | |
| 407 | + uiBit = gpio_info.uiGpioNumber; | |
| 408 | + uiOperation = gpio_info.uiGpioValue; | |
| 409 | + value = (1<<uiBit); | |
| 410 | + | |
| 411 | + if (IsReqGpioIsLedInNVM(Adapter, value) == FALSE) { | |
| 412 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to LED !!!", value); | |
| 413 | + Status = -EINVAL; | |
| 382 | 414 | break; |
| 383 | 415 | } |
| 384 | − case IOCTL_BCM_GPIO_SET_REQUEST: | |
| 385 | − { | |
| 386 | − UCHAR ucResetValue[4]; | |
| 387 | − UINT value =0; | |
| 388 | − UINT uiBit = 0; | |
| 389 | − UINT uiOperation = 0; | |
| 390 | − | |
| 391 | − GPIO_INFO gpio_info = {0}; | |
| 392 | − if((Adapter->IdleMode == TRUE) || | |
| 393 | − (Adapter->bShutStatus ==TRUE) || | |
| 394 | − (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
| 395 | − { | |
| 396 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO Can't be set/clear in Low power Mode"); | |
| 397 | − return -EACCES; | |
| 398 | − } | |
| 399 | − if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 400 | − return -EFAULT; | |
| 401 | − if (IoBuffer.InputLength > sizeof(gpio_info)) | |
| 402 | − return -EINVAL; | |
| 403 | − if(copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 404 | − return -EFAULT; | |
| 405 | − uiBit = gpio_info.uiGpioNumber; | |
| 406 | − uiOperation = gpio_info.uiGpioValue; | |
| 407 | 416 | |
| 408 | − value= (1<<uiBit); | |
| 417 | + /* Set - setting 1 */ | |
| 418 | + if (uiOperation) { | |
| 419 | + /* Set the gpio output register */ | |
| 420 | + Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_SET_REG, (PUINT)(&value), sizeof(UINT)); | |
| 409 | 421 | |
| 410 | − if(IsReqGpioIsLedInNVM(Adapter,value) ==FALSE) | |
| 411 | − { | |
| 412 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to LED !!!",value); | |
| 413 | − Status = -EINVAL; | |
| 422 | + if (Status == STATUS_SUCCESS) { | |
| 423 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n"); | |
| 424 | + } else { | |
| 425 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to set the %dth GPIO\n", uiBit); | |
| 426 | + break; | |
| 427 | + } | |
| 428 | + } else { | |
| 429 | + /* Set the gpio output register */ | |
| 430 | + Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, (PUINT)(&value), sizeof(UINT)); | |
| 431 | + | |
| 432 | + if (Status == STATUS_SUCCESS) { | |
| 433 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n"); | |
| 434 | + } else { | |
| 435 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to clear the %dth GPIO\n", uiBit); | |
| 414 | 436 | break; |
| 415 | 437 | } |
| 438 | + } | |
| 416 | 439 | |
| 440 | + Status = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(UINT)); | |
| 417 | 441 | |
| 418 | − if(uiOperation)//Set - setting 1 | |
| 419 | − { | |
| 420 | − //Set the gpio output register | |
| 421 | − Status = wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_SET_REG , | |
| 422 | − (PUINT)(&value), sizeof(UINT)); | |
| 423 | − if(Status == STATUS_SUCCESS) | |
| 424 | − { | |
| 425 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n"); | |
| 426 | − } | |
| 427 | − else | |
| 428 | − { | |
| 429 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Failed to set the %dth GPIO \n",uiBit); | |
| 430 | − break; | |
| 431 | − } | |
| 432 | − } | |
| 433 | − else//Unset - setting 0 | |
| 434 | − { | |
| 435 | − //Set the gpio output register | |
| 436 | − Status = wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_CLR_REG , | |
| 437 | − (PUINT)(&value), sizeof(UINT)); | |
| 438 | − if(Status == STATUS_SUCCESS) | |
| 439 | − { | |
| 440 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Set the GPIO bit\n"); | |
| 441 | − } | |
| 442 | − else | |
| 443 | − { | |
| 444 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Failed to clear the %dth GPIO \n",uiBit); | |
| 445 | − break; | |
| 446 | − } | |
| 447 | − } | |
| 442 | + if (STATUS_SUCCESS != Status) { | |
| 443 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, | |
| 444 | + "GPIO_MODE_REGISTER read failed"); | |
| 445 | + break; | |
| 446 | + } | |
| 448 | 447 | |
| 449 | − Status = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, | |
| 448 | + /* Set the gpio mode register to output */ | |
| 449 | + *(UINT *)ucResetValue |= (1<<uiBit); | |
| 450 | + Status = wrmaltWithLock(Adapter, GPIO_MODE_REGISTER, | |
| 450 | 451 | (PUINT)ucResetValue, sizeof(UINT)); |
| 451 | − if (STATUS_SUCCESS != Status) | |
| 452 | − { | |
| 453 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO_MODE_REGISTER read failed"); | |
| 454 | − break; | |
| 455 | − } | |
| 456 | − //Set the gpio mode register to output | |
| 457 | − *(UINT*)ucResetValue |= (1<<uiBit); | |
| 458 | − Status = wrmaltWithLock(Adapter,GPIO_MODE_REGISTER , | |
| 459 | − (PUINT)ucResetValue, sizeof(UINT)); | |
| 460 | − if(Status == STATUS_SUCCESS) | |
| 461 | − { | |
| 462 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Set the GPIO to output Mode\n"); | |
| 463 | − } | |
| 464 | − else | |
| 465 | − { | |
| 466 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to put GPIO in Output Mode\n"); | |
| 467 | − break; | |
| 468 | − } | |
| 452 | + | |
| 453 | + if (Status == STATUS_SUCCESS) { | |
| 454 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO to output Mode\n"); | |
| 455 | + } else { | |
| 456 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to put GPIO in Output Mode\n"); | |
| 457 | + break; | |
| 469 | 458 | } |
| 470 | − break; | |
| 471 | − case BCM_LED_THREAD_STATE_CHANGE_REQ: | |
| 472 | − { | |
| 473 | − USER_THREAD_REQ threadReq = { 0 }; | |
| 474 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"User made LED thread InActive"); | |
| 475 | − | |
| 476 | − if((Adapter->IdleMode == TRUE) || | |
| 477 | − (Adapter->bShutStatus ==TRUE) || | |
| 478 | − (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
| 479 | − { | |
| 480 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO Can't be set/clear in Low power Mode"); | |
| 481 | − Status = -EACCES; | |
| 482 | − break; | |
| 459 | + } | |
| 460 | + break; | |
| 461 | + | |
| 462 | + case BCM_LED_THREAD_STATE_CHANGE_REQ: { | |
| 463 | + USER_THREAD_REQ threadReq = {0}; | |
| 464 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "User made LED thread InActive"); | |
| 465 | + | |
| 466 | + if ((Adapter->IdleMode == TRUE) || | |
| 467 | + (Adapter->bShutStatus == TRUE) || | |
| 468 | + (Adapter->bPreparingForLowPowerMode == TRUE)) { | |
| 469 | + | |
| 470 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "GPIO Can't be set/clear in Low power Mode"); | |
| 471 | + Status = -EACCES; | |
| 472 | + break; | |
| 473 | + } | |
| 474 | + | |
| 475 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 476 | + return -EFAULT; | |
| 477 | + | |
| 478 | + if (IoBuffer.InputLength > sizeof(threadReq)) | |
| 479 | + return -EINVAL; | |
| 480 | + | |
| 481 | + if (copy_from_user(&threadReq, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 482 | + return -EFAULT; | |
| 483 | + | |
| 484 | + /* if LED thread is running(Actively or Inactively) set it state to make inactive */ | |
| 485 | + if (Adapter->LEDInfo.led_thread_running) { | |
| 486 | + if (threadReq.ThreadState == LED_THREAD_ACTIVATION_REQ) { | |
| 487 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Activating thread req"); | |
| 488 | + Adapter->DriverState = LED_THREAD_ACTIVE; | |
| 489 | + } else { | |
| 490 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "DeActivating Thread req....."); | |
| 491 | + Adapter->DriverState = LED_THREAD_INACTIVE; | |
| 483 | 492 | } |
| 484 | 493 | |
| 485 | − if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 486 | − return -EFAULT; | |
| 494 | + /* signal thread. */ | |
| 495 | + wake_up(&Adapter->LEDInfo.notify_led_event); | |
| 496 | + } | |
| 497 | + } | |
| 498 | + break; | |
| 487 | 499 | |
| 488 | − if (IoBuffer.InputLength > sizeof(threadReq)) | |
| 489 | − return -EINVAL; | |
| 500 | + case IOCTL_BCM_GPIO_STATUS_REQUEST: { | |
| 501 | + ULONG uiBit = 0; | |
| 502 | + UCHAR ucRead[4]; | |
| 503 | + GPIO_INFO gpio_info = {0}; | |
| 490 | 504 | |
| 491 | − if (copy_from_user(&threadReq, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 492 | − return -EFAULT; | |
| 505 | + if ((Adapter->IdleMode == TRUE) || | |
| 506 | + (Adapter->bShutStatus == TRUE) || | |
| 507 | + (Adapter->bPreparingForLowPowerMode == TRUE)) | |
| 508 | + return -EACCES; | |
| 493 | 509 | |
| 494 | − //if LED thread is running(Actively or Inactively) set it state to make inactive | |
| 495 | − if(Adapter->LEDInfo.led_thread_running) | |
| 496 | − { | |
| 497 | − if(threadReq.ThreadState == LED_THREAD_ACTIVATION_REQ) | |
| 498 | − { | |
| 499 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Activating thread req"); | |
| 500 | − Adapter->DriverState = LED_THREAD_ACTIVE; | |
| 501 | − } | |
| 502 | − else | |
| 503 | − { | |
| 504 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DeActivating Thread req....."); | |
| 505 | − Adapter->DriverState = LED_THREAD_INACTIVE; | |
| 506 | − } | |
| 510 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 511 | + return -EFAULT; | |
| 507 | 512 | |
| 508 | − //signal thread. | |
| 509 | − wake_up(&Adapter->LEDInfo.notify_led_event); | |
| 513 | + if (IoBuffer.InputLength > sizeof(gpio_info)) | |
| 514 | + return -EINVAL; | |
| 515 | + | |
| 516 | + if (copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 517 | + return -EFAULT; | |
| 518 | + | |
| 519 | + uiBit = gpio_info.uiGpioNumber; | |
| 520 | + | |
| 521 | + /* Set the gpio output register */ | |
| 522 | + Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, | |
| 523 | + (PUINT)ucRead, sizeof(UINT)); | |
| 510 | 524 | |
| 525 | + if (Status != STATUS_SUCCESS) { | |
| 526 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM Failed\n"); | |
| 527 | + return Status; | |
| 528 | + } | |
| 529 | + } | |
| 530 | + break; | |
| 531 | + | |
| 532 | + case IOCTL_BCM_GPIO_MULTI_REQUEST: { | |
| 533 | + UCHAR ucResetValue[4]; | |
| 534 | + GPIO_MULTI_INFO gpio_multi_info[MAX_IDX]; | |
| 535 | + PGPIO_MULTI_INFO pgpio_multi_info = (PGPIO_MULTI_INFO)gpio_multi_info; | |
| 536 | + | |
| 537 | + memset(pgpio_multi_info, 0, MAX_IDX * sizeof(GPIO_MULTI_INFO)); | |
| 538 | + | |
| 539 | + if ((Adapter->IdleMode == TRUE) || | |
| 540 | + (Adapter->bShutStatus == TRUE) || | |
| 541 | + (Adapter->bPreparingForLowPowerMode == TRUE)) | |
| 542 | + return -EINVAL; | |
| 543 | + | |
| 544 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 545 | + return -EFAULT; | |
| 546 | + | |
| 547 | + if (IoBuffer.InputLength > sizeof(gpio_multi_info)) | |
| 548 | + return -EINVAL; | |
| 549 | + | |
| 550 | + if (copy_from_user(&gpio_multi_info, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 551 | + return -EFAULT; | |
| 552 | + | |
| 553 | + if (IsReqGpioIsLedInNVM(Adapter, pgpio_multi_info[WIMAX_IDX].uiGPIOMask) == FALSE) { | |
| 554 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, | |
| 555 | + "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!", | |
| 556 | + pgpio_multi_info[WIMAX_IDX].uiGPIOMask, Adapter->gpioBitMap); | |
| 557 | + Status = -EINVAL; | |
| 558 | + break; | |
| 559 | + } | |
| 560 | + | |
| 561 | + /* Set the gpio output register */ | |
| 562 | + if ((pgpio_multi_info[WIMAX_IDX].uiGPIOMask) & | |
| 563 | + (pgpio_multi_info[WIMAX_IDX].uiGPIOCommand)) { | |
| 564 | + /* Set 1's in GPIO OUTPUT REGISTER */ | |
| 565 | + *(UINT *)ucResetValue = pgpio_multi_info[WIMAX_IDX].uiGPIOMask & | |
| 566 | + pgpio_multi_info[WIMAX_IDX].uiGPIOCommand & | |
| 567 | + pgpio_multi_info[WIMAX_IDX].uiGPIOValue; | |
| 568 | + | |
| 569 | + if (*(UINT *) ucResetValue) | |
| 570 | + Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_SET_REG, | |
| 571 | + (PUINT)ucResetValue, sizeof(ULONG)); | |
| 572 | + | |
| 573 | + if (Status != STATUS_SUCCESS) { | |
| 574 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM to BCM_GPIO_OUTPUT_SET_REG Failed."); | |
| 575 | + return Status; | |
| 576 | + } | |
| 577 | + | |
| 578 | + /* Clear to 0's in GPIO OUTPUT REGISTER */ | |
| 579 | + *(UINT *)ucResetValue = (pgpio_multi_info[WIMAX_IDX].uiGPIOMask & | |
| 580 | + pgpio_multi_info[WIMAX_IDX].uiGPIOCommand & | |
| 581 | + (~(pgpio_multi_info[WIMAX_IDX].uiGPIOValue))); | |
| 582 | + | |
| 583 | + if (*(UINT *) ucResetValue) | |
| 584 | + Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, (PUINT)ucResetValue, sizeof(ULONG)); | |
| 585 | + | |
| 586 | + if (Status != STATUS_SUCCESS) { | |
| 587 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM to BCM_GPIO_OUTPUT_CLR_REG Failed."); | |
| 588 | + return Status; | |
| 511 | 589 | } |
| 512 | 590 | } |
| 513 | − break; | |
| 514 | − case IOCTL_BCM_GPIO_STATUS_REQUEST: | |
| 515 | − { | |
| 516 | − ULONG uiBit = 0; | |
| 517 | − UCHAR ucRead[4]; | |
| 518 | − GPIO_INFO gpio_info = {0}; | |
| 519 | − if((Adapter->IdleMode == TRUE) || | |
| 520 | − (Adapter->bShutStatus ==TRUE) || | |
| 521 | − (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
| 522 | − return -EACCES; | |
| 523 | − if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 524 | − return -EFAULT; | |
| 525 | − if (IoBuffer.InputLength > sizeof(gpio_info)) | |
| 526 | − return -EINVAL; | |
| 527 | − if(copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 528 | − return -EFAULT; | |
| 529 | − uiBit = gpio_info.uiGpioNumber; | |
| 530 | − //Set the gpio output register | |
| 531 | − Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, | |
| 532 | − (PUINT)ucRead, sizeof(UINT)); | |
| 533 | − if(Status != STATUS_SUCCESS) | |
| 534 | − { | |
| 535 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "RDM Failed\n"); | |
| 536 | − return Status; | |
| 537 | − } | |
| 538 | 591 | |
| 592 | + if (pgpio_multi_info[WIMAX_IDX].uiGPIOMask) { | |
| 593 | + Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, (PUINT)ucResetValue, sizeof(UINT)); | |
| 594 | + | |
| 595 | + if (Status != STATUS_SUCCESS) { | |
| 596 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM to GPIO_PIN_STATE_REGISTER Failed."); | |
| 597 | + return Status; | |
| 539 | 598 | } |
| 599 | + | |
| 600 | + pgpio_multi_info[WIMAX_IDX].uiGPIOValue = (*(UINT *)ucResetValue & | |
| 601 | + pgpio_multi_info[WIMAX_IDX].uiGPIOMask); | |
| 602 | + } | |
| 603 | + | |
| 604 | + Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_info, IoBuffer.OutputLength); | |
| 605 | + if (Status) { | |
| 606 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, | |
| 607 | + "Failed while copying Content to IOBufer for user space err:%d", Status); | |
| 540 | 608 | break; |
| 541 | − case IOCTL_BCM_GPIO_MULTI_REQUEST: | |
| 542 | − { | |
| 543 | − UCHAR ucResetValue[4]; | |
| 544 | − GPIO_MULTI_INFO gpio_multi_info[MAX_IDX]; | |
| 545 | − PGPIO_MULTI_INFO pgpio_multi_info = (PGPIO_MULTI_INFO)gpio_multi_info; | |
| 546 | − | |
| 547 | − memset( pgpio_multi_info, 0, MAX_IDX * sizeof( GPIO_MULTI_INFO)); | |
| 548 | − | |
| 549 | − if((Adapter->IdleMode == TRUE) || | |
| 550 | − (Adapter->bShutStatus ==TRUE) || | |
| 551 | − (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
| 552 | − return -EINVAL; | |
| 553 | − if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 554 | − return -EFAULT; | |
| 555 | − if (IoBuffer.InputLength > sizeof(gpio_multi_info)) | |
| 556 | − return -EINVAL; | |
| 557 | − if (copy_from_user(&gpio_multi_info, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 558 | − return -EFAULT; | |
| 609 | + } | |
| 610 | + } | |
| 611 | + break; | |
| 559 | 612 | |
| 560 | − if(IsReqGpioIsLedInNVM(Adapter,pgpio_multi_info[WIMAX_IDX].uiGPIOMask)== FALSE) | |
| 561 | − { | |
| 562 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",pgpio_multi_info[WIMAX_IDX].uiGPIOMask,Adapter->gpioBitMap); | |
| 563 | − Status = -EINVAL; | |
| 564 | − break; | |
| 565 | − } | |
| 613 | + case IOCTL_BCM_GPIO_MODE_REQUEST: { | |
| 614 | + UCHAR ucResetValue[4]; | |
| 615 | + GPIO_MULTI_MODE gpio_multi_mode[MAX_IDX]; | |
| 616 | + PGPIO_MULTI_MODE pgpio_multi_mode = (PGPIO_MULTI_MODE)gpio_multi_mode; | |
| 566 | 617 | |
| 567 | − /* Set the gpio output register */ | |
| 618 | + if ((Adapter->IdleMode == TRUE) || | |
| 619 | + (Adapter->bShutStatus == TRUE) || | |
| 620 | + (Adapter->bPreparingForLowPowerMode == TRUE)) | |
| 621 | + return -EINVAL; | |
| 568 | 622 | |
| 569 | − if( ( pgpio_multi_info[WIMAX_IDX].uiGPIOMask) & | |
| 570 | − ( pgpio_multi_info[WIMAX_IDX].uiGPIOCommand)) | |
| 571 | − { | |
| 572 | − /* Set 1's in GPIO OUTPUT REGISTER */ | |
| 573 | − *(UINT*) ucResetValue = pgpio_multi_info[WIMAX_IDX].uiGPIOMask & | |
| 574 | − pgpio_multi_info[WIMAX_IDX].uiGPIOCommand & | |
| 575 | − pgpio_multi_info[WIMAX_IDX].uiGPIOValue; | |
| 623 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 624 | + return -EFAULT; | |
| 576 | 625 | |
| 577 | − if( *(UINT*) ucResetValue) | |
| 578 | − Status = wrmaltWithLock( Adapter, BCM_GPIO_OUTPUT_SET_REG , (PUINT) ucResetValue, sizeof(ULONG)); | |
| 626 | + if (IoBuffer.InputLength > sizeof(gpio_multi_mode)) | |
| 627 | + return -EINVAL; | |
| 579 | 628 | |
| 580 | − if( Status != STATUS_SUCCESS) | |
| 581 | − { | |
| 582 | − BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to BCM_GPIO_OUTPUT_SET_REG Failed."); | |
| 583 | − return Status; | |
| 584 | − } | |
| 629 | + if (copy_from_user(&gpio_multi_mode, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 630 | + return -EFAULT; | |
| 585 | 631 | |
| 586 | − /* Clear to 0's in GPIO OUTPUT REGISTER */ | |
| 587 | − *(UINT*) ucResetValue = (pgpio_multi_info[WIMAX_IDX].uiGPIOMask & | |
| 588 | − pgpio_multi_info[WIMAX_IDX].uiGPIOCommand & | |
| 589 | − ( ~( pgpio_multi_info[WIMAX_IDX].uiGPIOValue))); | |
| 632 | + Status = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(UINT)); | |
| 590 | 633 | |
| 591 | − if( *(UINT*) ucResetValue) | |
| 592 | − Status = wrmaltWithLock( Adapter, BCM_GPIO_OUTPUT_CLR_REG , (PUINT) ucResetValue, sizeof(ULONG)); | |
| 634 | + if (STATUS_SUCCESS != Status) { | |
| 635 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read of GPIO_MODE_REGISTER failed"); | |
| 636 | + return Status; | |
| 637 | + } | |
| 593 | 638 | |
| 594 | − if( Status != STATUS_SUCCESS) | |
| 595 | − { | |
| 596 | − BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to BCM_GPIO_OUTPUT_CLR_REG Failed." ); | |
| 597 | − return Status; | |
| 598 | − } | |
| 599 | − } | |
| 639 | + /* Validating the request */ | |
| 640 | + if (IsReqGpioIsLedInNVM(Adapter, pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) == FALSE) { | |
| 641 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, | |
| 642 | + "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!", | |
| 643 | + pgpio_multi_mode[WIMAX_IDX].uiGPIOMask, Adapter->gpioBitMap); | |
| 644 | + Status = -EINVAL; | |
| 645 | + break; | |
| 646 | + } | |
| 600 | 647 | |
| 601 | − if( pgpio_multi_info[WIMAX_IDX].uiGPIOMask) | |
| 602 | − { | |
| 603 | − Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, (PUINT)ucResetValue, sizeof(UINT)); | |
| 648 | + if (pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) { | |
| 649 | + /* write all OUT's (1's) */ | |
| 650 | + *(UINT *) ucResetValue |= (pgpio_multi_mode[WIMAX_IDX].uiGPIOMode & | |
| 651 | + pgpio_multi_mode[WIMAX_IDX].uiGPIOMask); | |
| 652 | + | |
| 653 | + /* write all IN's (0's) */ | |
| 654 | + *(UINT *) ucResetValue &= ~((~pgpio_multi_mode[WIMAX_IDX].uiGPIOMode) & | |
| 655 | + pgpio_multi_mode[WIMAX_IDX].uiGPIOMask); | |
| 656 | + | |
| 657 | + /* Currently implemented return the modes of all GPIO's | |
| 658 | + * else needs to bit AND with mask | |
| 659 | + */ | |
| 660 | + pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT *)ucResetValue; | |
| 661 | + | |
| 662 | + Status = wrmaltWithLock(Adapter, GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(ULONG)); | |
| 663 | + if (Status == STATUS_SUCCESS) { | |
| 664 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, | |
| 665 | + "WRM to GPIO_MODE_REGISTER Done"); | |
| 666 | + } else { | |
| 667 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, | |
| 668 | + "WRM to GPIO_MODE_REGISTER Failed"); | |
| 669 | + Status = -EFAULT; | |
| 670 | + break; | |
| 671 | + } | |
| 672 | + } else { | |
| 673 | +/* if uiGPIOMask is 0 then return mode register configuration */ | |
| 674 | + pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT *)ucResetValue; | |
| 675 | + } | |
| 604 | 676 | |
| 605 | − if(Status != STATUS_SUCCESS) | |
| 606 | − { | |
| 607 | − BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"RDM to GPIO_PIN_STATE_REGISTER Failed."); | |
| 608 | − return Status; | |
| 609 | − } | |
| 677 | + Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_mode, IoBuffer.OutputLength); | |
| 678 | + if (Status) { | |
| 679 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, | |
| 680 | + "Failed while copying Content to IOBufer for user space err:%d", Status); | |
| 681 | + break; | |
| 682 | + } | |
| 683 | + } | |
| 684 | + break; | |
| 685 | + | |
| 686 | + case IOCTL_MAC_ADDR_REQ: | |
| 687 | + case IOCTL_LINK_REQ: | |
| 688 | + case IOCTL_CM_REQUEST: | |
| 689 | + case IOCTL_SS_INFO_REQ: | |
| 690 | + case IOCTL_SEND_CONTROL_MESSAGE: | |
| 691 | + case IOCTL_IDLE_REQ: { | |
| 692 | + PVOID pvBuffer = NULL; | |
| 693 | + | |
| 694 | + /* Copy Ioctl Buffer structure */ | |
| 695 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 696 | + return -EFAULT; | |
| 610 | 697 | |
| 611 | − pgpio_multi_info[WIMAX_IDX].uiGPIOValue = ( *(UINT*)ucResetValue & | |
| 612 | − pgpio_multi_info[WIMAX_IDX].uiGPIOMask); | |
| 613 | − } | |
| 698 | + if (IoBuffer.InputLength < sizeof(struct link_request)) | |
| 699 | + return -EINVAL; | |
| 614 | 700 | |
| 615 | − Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_info, IoBuffer.OutputLength); | |
| 616 | − if(Status) | |
| 617 | − { | |
| 618 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying Content to IOBufer for user space err:%d",Status); | |
| 619 | − break; | |
| 620 | − } | |
| 621 | − } | |
| 701 | + if (IoBuffer.InputLength > MAX_CNTL_PKT_SIZE) | |
| 702 | + return -EINVAL; | |
| 703 | + | |
| 704 | + pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL); | |
| 705 | + if (!pvBuffer) | |
| 706 | + return -ENOMEM; | |
| 707 | + | |
| 708 | + if (copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) { | |
| 709 | + Status = -EFAULT; | |
| 710 | + kfree(pvBuffer); | |
| 622 | 711 | break; |
| 623 | − case IOCTL_BCM_GPIO_MODE_REQUEST: | |
| 624 | − { | |
| 625 | − UCHAR ucResetValue[4]; | |
| 626 | − GPIO_MULTI_MODE gpio_multi_mode[MAX_IDX]; | |
| 627 | − PGPIO_MULTI_MODE pgpio_multi_mode = ( PGPIO_MULTI_MODE) gpio_multi_mode; | |
| 712 | + } | |
| 713 | + | |
| 714 | + down(&Adapter->LowPowerModeSync); | |
| 715 | + Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue, | |
| 716 | + !Adapter->bPreparingForLowPowerMode, | |
| 717 | + (1 * HZ)); | |
| 718 | + if (Status == -ERESTARTSYS) | |
| 719 | + goto cntrlEnd; | |
| 720 | + | |
| 721 | + if (Adapter->bPreparingForLowPowerMode) { | |
| 722 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, | |
| 723 | + "Preparing Idle Mode is still True - Hence Rejecting control message\n"); | |
| 724 | + Status = STATUS_FAILURE; | |
| 725 | + goto cntrlEnd; | |
| 726 | + } | |
| 727 | + Status = CopyBufferToControlPacket(Adapter, (PVOID)pvBuffer); | |
| 728 | + | |
| 729 | +cntrlEnd: | |
| 730 | + up(&Adapter->LowPowerModeSync); | |
| 731 | + kfree(pvBuffer); | |
| 732 | + break; | |
| 733 | + } | |
| 628 | 734 | |
| 629 | − if((Adapter->IdleMode == TRUE) || | |
| 630 | − (Adapter->bShutStatus ==TRUE) || | |
| 631 | − (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
| 632 | − return -EINVAL; | |
| 735 | + case IOCTL_BCM_BUFFER_DOWNLOAD_START: { | |
| 736 | + INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); | |
| 737 | + if (NVMAccess) { | |
| 738 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, | |
| 739 | + "IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n"); | |
| 740 | + return -EACCES; | |
| 741 | + } | |
| 633 | 742 | |
| 743 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, | |
| 744 | + "Starting the firmware download PID =0x%x!!!!\n", current->pid); | |
| 745 | + | |
| 746 | + if (!down_trylock(&Adapter->fw_download_sema)) { | |
| 747 | + Adapter->bBinDownloaded = FALSE; | |
| 748 | + Adapter->fw_download_process_pid = current->pid; | |
| 749 | + Adapter->bCfgDownloaded = FALSE; | |
| 750 | + Adapter->fw_download_done = FALSE; | |
| 751 | + netif_carrier_off(Adapter->dev); | |
| 752 | + netif_stop_queue(Adapter->dev); | |
| 753 | + Status = reset_card_proc(Adapter); | |
| 754 | + if (Status) { | |
| 755 | + pr_err(PFX "%s: reset_card_proc Failed!\n", Adapter->dev->name); | |
| 756 | + up(&Adapter->fw_download_sema); | |
| 757 | + up(&Adapter->NVMRdmWrmLock); | |
| 758 | + break; | |
| 759 | + } | |
| 760 | + mdelay(10); | |
| 761 | + } else { | |
| 762 | + Status = -EBUSY; | |
| 763 | + } | |
| 764 | + | |
| 765 | + up(&Adapter->NVMRdmWrmLock); | |
| 766 | + break; | |
| 767 | + } | |
| 768 | + | |
| 769 | + case IOCTL_BCM_BUFFER_DOWNLOAD: { | |
| 770 | + FIRMWARE_INFO *psFwInfo = NULL; | |
| 771 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid); | |
| 772 | + do { | |
| 773 | + if (!down_trylock(&Adapter->fw_download_sema)) { | |
| 774 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, | |
| 775 | + "Invalid way to download buffer. Use Start and then call this!!!\n"); | |
| 776 | + Status = -EINVAL; | |
| 777 | + break; | |
| 778 | + } | |
| 779 | + | |
| 780 | + /* Copy Ioctl Buffer structure */ | |
| 634 | 781 | if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) |
| 635 | 782 | return -EFAULT; |
| 636 | − if (IoBuffer.InputLength > sizeof(gpio_multi_mode)) | |
| 783 | + | |
| 784 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, | |
| 785 | + "Length for FW DLD is : %lx\n", IoBuffer.InputLength); | |
| 786 | + | |
| 787 | + if (IoBuffer.InputLength > sizeof(FIRMWARE_INFO)) | |
| 637 | 788 | return -EINVAL; |
| 638 | − if (copy_from_user(&gpio_multi_mode, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 789 | + | |
| 790 | + psFwInfo = kmalloc(sizeof(*psFwInfo), GFP_KERNEL); | |
| 791 | + if (!psFwInfo) | |
| 792 | + return -ENOMEM; | |
| 793 | + | |
| 794 | + if (copy_from_user(psFwInfo, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 639 | 795 | return -EFAULT; |
| 640 | 796 | |
| 641 | − Status = rdmaltWithLock( Adapter, ( UINT) GPIO_MODE_REGISTER, ( PUINT) ucResetValue, sizeof( UINT)); | |
| 642 | − if( STATUS_SUCCESS != Status) | |
| 643 | − { | |
| 644 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Read of GPIO_MODE_REGISTER failed"); | |
| 645 | − return Status; | |
| 646 | − } | |
| 797 | + if (!psFwInfo->pvMappedFirmwareAddress || | |
| 798 | + (psFwInfo->u32FirmwareLength == 0)) { | |
| 647 | 799 | |
| 648 | − //Validating the request | |
| 649 | − if(IsReqGpioIsLedInNVM(Adapter,pgpio_multi_mode[WIMAX_IDX].uiGPIOMask)== FALSE) | |
| 650 | − { | |
| 651 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",pgpio_multi_mode[WIMAX_IDX].uiGPIOMask,Adapter->gpioBitMap); | |
| 800 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Something else is wrong %lu\n", | |
| 801 | + psFwInfo->u32FirmwareLength); | |
| 652 | 802 | Status = -EINVAL; |
| 653 | 803 | break; |
| 654 | 804 | } |
| 655 | 805 | |
| 656 | − if( pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) | |
| 657 | − { | |
| 658 | − /* write all OUT's (1's) */ | |
| 659 | − *( UINT*) ucResetValue |= ( pgpio_multi_mode[WIMAX_IDX].uiGPIOMode & | |
| 660 | − pgpio_multi_mode[WIMAX_IDX].uiGPIOMask); | |
| 661 | − /* write all IN's (0's) */ | |
| 662 | − *( UINT*) ucResetValue &= ~( ( ~pgpio_multi_mode[WIMAX_IDX].uiGPIOMode) & | |
| 663 | − pgpio_multi_mode[WIMAX_IDX].uiGPIOMask); | |
| 664 | − | |
| 665 | − /* Currently implemented return the modes of all GPIO's | |
| 666 | − * else needs to bit AND with mask | |
| 667 | − * */ | |
| 668 | − pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT*)ucResetValue; | |
| 669 | − | |
| 670 | − Status = wrmaltWithLock( Adapter, GPIO_MODE_REGISTER , ( PUINT) ucResetValue, sizeof( ULONG)); | |
| 671 | − if( Status == STATUS_SUCCESS) | |
| 672 | − { | |
| 673 | − BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM to GPIO_MODE_REGISTER Done"); | |
| 674 | − } | |
| 806 | + Status = bcm_ioctl_fw_download(Adapter, psFwInfo); | |
| 807 | + | |
| 808 | + if (Status != STATUS_SUCCESS) { | |
| 809 | + if (psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR) | |
| 810 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "IOCTL: Configuration File Upload Failed\n"); | |
| 675 | 811 | else |
| 676 | − { | |
| 677 | − BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to GPIO_MODE_REGISTER Failed"); | |
| 678 | − Status = -EFAULT; | |
| 679 | − break; | |
| 812 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "IOCTL: Firmware File Upload Failed\n"); | |
| 813 | + | |
| 814 | + /* up(&Adapter->fw_download_sema); */ | |
| 815 | + | |
| 816 | + if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { | |
| 817 | + Adapter->DriverState = DRIVER_INIT; | |
| 818 | + Adapter->LEDInfo.bLedInitDone = FALSE; | |
| 819 | + wake_up(&Adapter->LEDInfo.notify_led_event); | |
| 680 | 820 | } |
| 681 | 821 | } |
| 682 | − else /* if uiGPIOMask is 0 then return mode register configuration */ | |
| 683 | − { | |
| 684 | − pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *( UINT*) ucResetValue; | |
| 685 | − } | |
| 686 | − Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_mode, IoBuffer.OutputLength); | |
| 687 | − if(Status) | |
| 688 | − { | |
| 689 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying Content to IOBufer for user space err:%d",Status); | |
| 822 | + break; | |
| 823 | + | |
| 824 | + } while (0); | |
| 825 | + | |
| 826 | + if (Status != STATUS_SUCCESS) | |
| 827 | + up(&Adapter->fw_download_sema); | |
| 828 | + | |
| 829 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "IOCTL: Firmware File Uploaded\n"); | |
| 830 | + kfree(psFwInfo); | |
| 831 | + break; | |
| 832 | + } | |
| 833 | + | |
| 834 | + case IOCTL_BCM_BUFFER_DOWNLOAD_STOP: { | |
| 835 | + INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); | |
| 836 | + | |
| 837 | + if (NVMAccess) { | |
| 838 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, | |
| 839 | + "FW download blocked as EEPROM Read/Write is in progress\n"); | |
| 840 | + up(&Adapter->fw_download_sema); | |
| 841 | + return -EACCES; | |
| 842 | + } | |
| 843 | + | |
| 844 | + if (down_trylock(&Adapter->fw_download_sema)) { | |
| 845 | + Adapter->bBinDownloaded = TRUE; | |
| 846 | + Adapter->bCfgDownloaded = TRUE; | |
| 847 | + atomic_set(&Adapter->CurrNumFreeTxDesc, 0); | |
| 848 | + Adapter->CurrNumRecvDescs = 0; | |
| 849 | + Adapter->downloadDDR = 0; | |
| 850 | + | |
| 851 | + /* setting the Mips to Run */ | |
| 852 | + Status = run_card_proc(Adapter); | |
| 853 | + | |
| 854 | + if (Status) { | |
| 855 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Firm Download Failed\n"); | |
| 856 | + up(&Adapter->fw_download_sema); | |
| 857 | + up(&Adapter->NVMRdmWrmLock); | |
| 690 | 858 | break; |
| 859 | + } else { | |
| 860 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, | |
| 861 | + DBG_LVL_ALL, "Firm Download Over...\n"); | |
| 691 | 862 | } |
| 863 | + | |
| 864 | + mdelay(10); | |
| 865 | + | |
| 866 | + /* Wait for MailBox Interrupt */ | |
| 867 | + if (StartInterruptUrb((PS_INTERFACE_ADAPTER)Adapter->pvInterfaceAdapter)) | |
| 868 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Unable to send interrupt...\n"); | |
| 869 | + | |
| 870 | + timeout = 5*HZ; | |
| 871 | + Adapter->waiting_to_fw_download_done = FALSE; | |
| 872 | + wait_event_timeout(Adapter->ioctl_fw_dnld_wait_queue, | |
| 873 | + Adapter->waiting_to_fw_download_done, timeout); | |
| 874 | + Adapter->fw_download_process_pid = INVALID_PID; | |
| 875 | + Adapter->fw_download_done = TRUE; | |
| 876 | + atomic_set(&Adapter->CurrNumFreeTxDesc, 0); | |
| 877 | + Adapter->CurrNumRecvDescs = 0; | |
| 878 | + Adapter->PrevNumRecvDescs = 0; | |
| 879 | + atomic_set(&Adapter->cntrlpktCnt, 0); | |
| 880 | + Adapter->LinkUpStatus = 0; | |
| 881 | + Adapter->LinkStatus = 0; | |
| 882 | + | |
| 883 | + if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { | |
| 884 | + Adapter->DriverState = FW_DOWNLOAD_DONE; | |
| 885 | + wake_up(&Adapter->LEDInfo.notify_led_event); | |
| 886 | + } | |
| 887 | + | |
| 888 | + if (!timeout) | |
| 889 | + Status = -ENODEV; | |
| 890 | + } else { | |
| 891 | + Status = -EINVAL; | |
| 692 | 892 | } |
| 893 | + | |
| 894 | + up(&Adapter->fw_download_sema); | |
| 895 | + up(&Adapter->NVMRdmWrmLock); | |
| 693 | 896 | break; |
| 897 | + } | |
| 694 | 898 | |
| 695 | − case IOCTL_MAC_ADDR_REQ: | |
| 696 | − case IOCTL_LINK_REQ: | |
| 697 | − case IOCTL_CM_REQUEST: | |
| 698 | − case IOCTL_SS_INFO_REQ: | |
| 699 | − case IOCTL_SEND_CONTROL_MESSAGE: | |
| 700 | − case IOCTL_IDLE_REQ: | |
| 701 | − { | |
| 702 | − PVOID pvBuffer=NULL; | |
| 899 | + case IOCTL_BE_BUCKET_SIZE: | |
| 900 | + Status = 0; | |
| 901 | + if (get_user(Adapter->BEBucketSize, (unsigned long __user *)arg)) | |
| 902 | + Status = -EFAULT; | |
| 903 | + break; | |
| 703 | 904 | |
| 704 | − /* Copy Ioctl Buffer structure */ | |
| 705 | − if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 706 | − return -EFAULT; | |
| 905 | + case IOCTL_RTPS_BUCKET_SIZE: | |
| 906 | + Status = 0; | |
| 907 | + if (get_user(Adapter->rtPSBucketSize, (unsigned long __user *)arg)) | |
| 908 | + Status = -EFAULT; | |
| 909 | + break; | |
| 707 | 910 | |
| 708 | − /* FIXME: don't accept any length from user */ | |
| 709 | − pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL); | |
| 710 | − if(!pvBuffer) | |
| 711 | − return -ENOMEM; | |
| 911 | + case IOCTL_CHIP_RESET: { | |
| 912 | + INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); | |
| 913 | + if (NVMAccess) { | |
| 914 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, " IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n"); | |
| 915 | + return -EACCES; | |
| 916 | + } | |
| 917 | + | |
| 918 | + down(&Adapter->RxAppControlQueuelock); | |
| 919 | + Status = reset_card_proc(Adapter); | |
| 920 | + flushAllAppQ(); | |
| 921 | + up(&Adapter->RxAppControlQueuelock); | |
| 922 | + up(&Adapter->NVMRdmWrmLock); | |
| 923 | + ResetCounters(Adapter); | |
| 924 | + break; | |
| 925 | + } | |
| 712 | 926 | |
| 713 | − if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 714 | − { | |
| 927 | + case IOCTL_QOS_THRESHOLD: { | |
| 928 | + USHORT uiLoopIndex; | |
| 929 | + | |
| 930 | + Status = 0; | |
| 931 | + for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) { | |
| 932 | + if (get_user(Adapter->PackInfo[uiLoopIndex].uiThreshold, | |
| 933 | + (unsigned long __user *)arg)) { | |
| 715 | 934 | Status = -EFAULT; |
| 716 | − kfree(pvBuffer); | |
| 717 | 935 | break; |
| 718 | 936 | } |
| 937 | + } | |
| 938 | + break; | |
| 939 | + } | |
| 719 | 940 | |
| 720 | − down(&Adapter->LowPowerModeSync); | |
| 721 | − Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue, | |
| 722 | − !Adapter->bPreparingForLowPowerMode, | |
| 723 | − (1 * HZ)); | |
| 724 | − if(Status == -ERESTARTSYS) | |
| 725 | − goto cntrlEnd; | |
| 726 | − | |
| 727 | − if(Adapter->bPreparingForLowPowerMode) | |
| 728 | − { | |
| 729 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Preparing Idle Mode is still True - Hence Rejecting control message\n"); | |
| 730 | − Status = STATUS_FAILURE ; | |
| 731 | − goto cntrlEnd ; | |
| 732 | − } | |
| 733 | − Status = CopyBufferToControlPacket(Adapter, (PVOID)pvBuffer); | |
| 734 | − cntrlEnd: | |
| 735 | − up(&Adapter->LowPowerModeSync); | |
| 736 | − kfree(pvBuffer); | |
| 941 | + case IOCTL_DUMP_PACKET_INFO: | |
| 942 | + DumpPackInfo(Adapter); | |
| 943 | + DumpPhsRules(&Adapter->stBCMPhsContext); | |
| 944 | + Status = STATUS_SUCCESS; | |
| 945 | + break; | |
| 946 | + | |
| 947 | + case IOCTL_GET_PACK_INFO: | |
| 948 | + if (copy_to_user(argp, &Adapter->PackInfo, sizeof(PacketInfo)*NO_OF_QUEUES)) | |
| 949 | + return -EFAULT; | |
| 950 | + Status = STATUS_SUCCESS; | |
| 951 | + break; | |
| 952 | + | |
| 953 | + case IOCTL_BCM_SWITCH_TRANSFER_MODE: { | |
| 954 | + UINT uiData = 0; | |
| 955 | + if (copy_from_user(&uiData, argp, sizeof(UINT))) | |
| 956 | + return -EFAULT; | |
| 957 | + | |
| 958 | + if (uiData) { | |
| 959 | + /* Allow All Packets */ | |
| 960 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: ETH_PACKET_TUNNELING_MODE\n"); | |
| 961 | + Adapter->TransferMode = ETH_PACKET_TUNNELING_MODE; | |
| 962 | + } else { | |
| 963 | + /* Allow IP only Packets */ | |
| 964 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: IP_PACKET_ONLY_MODE\n"); | |
| 965 | + Adapter->TransferMode = IP_PACKET_ONLY_MODE; | |
| 966 | + } | |
| 967 | + Status = STATUS_SUCCESS; | |
| 968 | + break; | |
| 969 | + } | |
| 970 | + | |
| 971 | + case IOCTL_BCM_GET_DRIVER_VERSION: { | |
| 972 | + /* Copy Ioctl Buffer structure */ | |
| 973 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 974 | + return -EFAULT; | |
| 975 | + | |
| 976 | + if (copy_to_user(IoBuffer.OutputBuffer, VER_FILEVERSION_STR, IoBuffer.OutputLength)) | |
| 977 | + return -EFAULT; | |
| 978 | + Status = STATUS_SUCCESS; | |
| 979 | + break; | |
| 980 | + } | |
| 981 | + | |
| 982 | + case IOCTL_BCM_GET_CURRENT_STATUS: { | |
| 983 | + LINK_STATE link_state; | |
| 984 | + | |
| 985 | + /* Copy Ioctl Buffer structure */ | |
| 986 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) { | |
| 987 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "copy_from_user failed..\n"); | |
| 988 | + Status = -EFAULT; | |
| 737 | 989 | break; |
| 738 | 990 | } |
| 739 | − case IOCTL_BCM_BUFFER_DOWNLOAD_START: | |
| 740 | − { | |
| 741 | − INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock) ; | |
| 742 | − if(NVMAccess) | |
| 743 | − { | |
| 744 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n"); | |
| 745 | − return -EACCES; | |
| 746 | − } | |
| 747 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid); | |
| 748 | − if(!down_trylock(&Adapter->fw_download_sema)) | |
| 749 | − { | |
| 750 | − Adapter->bBinDownloaded=FALSE; | |
| 751 | − Adapter->fw_download_process_pid=current->pid; | |
| 752 | − Adapter->bCfgDownloaded=FALSE; | |
| 753 | − Adapter->fw_download_done=FALSE; | |
| 754 | − netif_carrier_off(Adapter->dev); | |
| 755 | − netif_stop_queue(Adapter->dev); | |
| 756 | − Status = reset_card_proc(Adapter); | |
| 757 | − if(Status) | |
| 758 | − { | |
| 759 | − pr_err(PFX "%s: reset_card_proc Failed!\n", Adapter->dev->name); | |
| 760 | − up(&Adapter->fw_download_sema); | |
| 761 | − up(&Adapter->NVMRdmWrmLock); | |
| 762 | − break; | |
| 763 | − } | |
| 764 | − mdelay(10); | |
| 765 | − } | |
| 766 | − else | |
| 767 | − { | |
| 768 | 991 | |
| 769 | − Status = -EBUSY; | |
| 992 | + if (IoBuffer.OutputLength != sizeof(link_state)) { | |
| 993 | + Status = -EINVAL; | |
| 994 | + break; | |
| 995 | + } | |
| 770 | 996 | |
| 771 | − } | |
| 772 | − up(&Adapter->NVMRdmWrmLock); | |
| 997 | + memset(&link_state, 0, sizeof(link_state)); | |
| 998 | + link_state.bIdleMode = Adapter->IdleMode; | |
| 999 | + link_state.bShutdownMode = Adapter->bShutStatus; | |
| 1000 | + link_state.ucLinkStatus = Adapter->LinkStatus; | |
| 1001 | + | |
| 1002 | + if (copy_to_user(IoBuffer.OutputBuffer, &link_state, min_t(size_t, sizeof(link_state), IoBuffer.OutputLength))) { | |
| 1003 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy_to_user Failed..\n"); | |
| 1004 | + Status = -EFAULT; | |
| 773 | 1005 | break; |
| 774 | 1006 | } |
| 775 | − case IOCTL_BCM_BUFFER_DOWNLOAD: | |
| 776 | − { | |
| 777 | − FIRMWARE_INFO *psFwInfo = NULL; | |
| 778 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid); | |
| 779 | − do{ | |
| 780 | − if(!down_trylock(&Adapter->fw_download_sema)) | |
| 781 | − { | |
| 782 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid way to download buffer. Use Start and then call this!!!\n"); | |
| 783 | − Status=-EINVAL; | |
| 784 | − break; | |
| 785 | − } | |
| 1007 | + Status = STATUS_SUCCESS; | |
| 1008 | + break; | |
| 1009 | + } | |
| 786 | 1010 | |
| 787 | − /* Copy Ioctl Buffer structure */ | |
| 788 | − if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 789 | − return -EFAULT; | |
| 1011 | + case IOCTL_BCM_SET_MAC_TRACING: { | |
| 1012 | + UINT tracing_flag; | |
| 790 | 1013 | |
| 791 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Length for FW DLD is : %lx\n", | |
| 792 | − IoBuffer.InputLength); | |
| 1014 | + /* copy ioctl Buffer structure */ | |
| 1015 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1016 | + return -EFAULT; | |
| 793 | 1017 | |
| 794 | − if (IoBuffer.InputLength > sizeof(FIRMWARE_INFO)) | |
| 795 | − return -EINVAL; | |
| 1018 | + if (copy_from_user(&tracing_flag, IoBuffer.InputBuffer, sizeof(UINT))) | |
| 1019 | + return -EFAULT; | |
| 796 | 1020 | |
| 797 | − psFwInfo = kmalloc(sizeof(*psFwInfo), GFP_KERNEL); | |
| 798 | − if(!psFwInfo) | |
| 799 | − return -ENOMEM; | |
| 1021 | + if (tracing_flag) | |
| 1022 | + Adapter->pTarangs->MacTracingEnabled = TRUE; | |
| 1023 | + else | |
| 1024 | + Adapter->pTarangs->MacTracingEnabled = FALSE; | |
| 1025 | + break; | |
| 1026 | + } | |
| 800 | 1027 | |
| 801 | − if(copy_from_user(psFwInfo, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 802 | − return -EFAULT; | |
| 1028 | + case IOCTL_BCM_GET_DSX_INDICATION: { | |
| 1029 | + ULONG ulSFId = 0; | |
| 1030 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1031 | + return -EFAULT; | |
| 803 | 1032 | |
| 804 | − if(!psFwInfo->pvMappedFirmwareAddress || | |
| 805 | − (psFwInfo->u32FirmwareLength == 0)) | |
| 806 | − { | |
| 807 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Something else is wrong %lu\n", | |
| 808 | − psFwInfo->u32FirmwareLength); | |
| 809 | − Status = -EINVAL; | |
| 810 | − break; | |
| 811 | − } | |
| 812 | − Status = bcm_ioctl_fw_download(Adapter, psFwInfo); | |
| 813 | − if(Status != STATUS_SUCCESS) | |
| 814 | − { | |
| 815 | − if(psFwInfo->u32StartingAddress==CONFIG_BEGIN_ADDR) | |
| 816 | − { | |
| 817 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "IOCTL: Configuration File Upload Failed\n"); | |
| 818 | − } | |
| 819 | − else | |
| 820 | − { | |
| 821 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "IOCTL: Firmware File Upload Failed\n"); | |
| 822 | − } | |
| 823 | − //up(&Adapter->fw_download_sema); | |
| 1033 | + if (IoBuffer.OutputLength < sizeof(stLocalSFAddIndicationAlt)) { | |
| 1034 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, | |
| 1035 | + "Mismatch req: %lx needed is =0x%zx!!!", | |
| 1036 | + IoBuffer.OutputLength, sizeof(stLocalSFAddIndicationAlt)); | |
| 1037 | + return -EINVAL; | |
| 1038 | + } | |
| 824 | 1039 | |
| 825 | − if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) | |
| 826 | − { | |
| 827 | − Adapter->DriverState = DRIVER_INIT; | |
| 828 | − Adapter->LEDInfo.bLedInitDone = FALSE; | |
| 829 | − wake_up(&Adapter->LEDInfo.notify_led_event); | |
| 830 | − } | |
| 831 | − } | |
| 832 | − break ; | |
| 833 | − }while(0); | |
| 1040 | + if (copy_from_user(&ulSFId, IoBuffer.InputBuffer, sizeof(ulSFId))) | |
| 1041 | + return -EFAULT; | |
| 834 | 1042 | |
| 835 | − if(Status != STATUS_SUCCESS) | |
| 836 | − up(&Adapter->fw_download_sema); | |
| 837 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "IOCTL: Firmware File Uploaded\n"); | |
| 838 | − kfree(psFwInfo); | |
| 839 | − break; | |
| 840 | − } | |
| 841 | − case IOCTL_BCM_BUFFER_DOWNLOAD_STOP: | |
| 842 | − { | |
| 843 | − INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); | |
| 844 | − if(NVMAccess) | |
| 845 | − { | |
| 846 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " FW download blocked as EEPROM Read/Write is in progress\n"); | |
| 847 | − up(&Adapter->fw_download_sema); | |
| 848 | − return -EACCES; | |
| 849 | − } | |
| 850 | − if(down_trylock(&Adapter->fw_download_sema)) | |
| 851 | − { | |
| 852 | − Adapter->bBinDownloaded=TRUE; | |
| 853 | − Adapter->bCfgDownloaded=TRUE; | |
| 854 | − atomic_set(&Adapter->CurrNumFreeTxDesc, 0); | |
| 855 | − | |
| 856 | − Adapter->CurrNumRecvDescs=0; | |
| 857 | − Adapter->downloadDDR = 0; | |
| 858 | − | |
| 859 | − //setting the Mips to Run | |
| 860 | − Status = run_card_proc(Adapter); | |
| 861 | − if(Status) | |
| 862 | − { | |
| 863 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Firm Download Failed\n"); | |
| 864 | − up(&Adapter->fw_download_sema); | |
| 865 | − up(&Adapter->NVMRdmWrmLock); | |
| 866 | − break; | |
| 867 | − } | |
| 868 | − else | |
| 869 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Firm Download Over...\n"); | |
| 870 | − mdelay(10); | |
| 871 | − /* Wait for MailBox Interrupt */ | |
| 872 | − if(StartInterruptUrb((PS_INTERFACE_ADAPTER)Adapter->pvInterfaceAdapter)) | |
| 873 | − { | |
| 874 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Unable to send interrupt...\n"); | |
| 875 | − } | |
| 876 | − timeout = 5*HZ; | |
| 877 | − Adapter->waiting_to_fw_download_done = FALSE; | |
| 878 | − wait_event_timeout(Adapter->ioctl_fw_dnld_wait_queue, | |
| 879 | − Adapter->waiting_to_fw_download_done, timeout); | |
| 880 | − Adapter->fw_download_process_pid=INVALID_PID; | |
| 881 | − Adapter->fw_download_done=TRUE; | |
| 882 | − atomic_set(&Adapter->CurrNumFreeTxDesc, 0); | |
| 883 | − Adapter->CurrNumRecvDescs = 0; | |
| 884 | − Adapter->PrevNumRecvDescs = 0; | |
| 885 | − atomic_set(&Adapter->cntrlpktCnt,0); | |
| 886 | − Adapter->LinkUpStatus = 0; | |
| 887 | − Adapter->LinkStatus = 0; | |
| 888 | − | |
| 889 | − if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) | |
| 890 | − { | |
| 891 | − Adapter->DriverState = FW_DOWNLOAD_DONE; | |
| 892 | − wake_up(&Adapter->LEDInfo.notify_led_event); | |
| 893 | − } | |
| 1043 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Get DSX Data SF ID is =%lx\n", ulSFId); | |
| 1044 | + get_dsx_sf_data_to_application(Adapter, ulSFId, IoBuffer.OutputBuffer); | |
| 1045 | + Status = STATUS_SUCCESS; | |
| 1046 | + } | |
| 1047 | + break; | |
| 894 | 1048 | |
| 895 | − if(!timeout) | |
| 896 | − { | |
| 897 | − Status = -ENODEV; | |
| 898 | − } | |
| 899 | − } | |
| 900 | − else | |
| 901 | − { | |
| 902 | − Status = -EINVAL; | |
| 903 | − } | |
| 904 | − up(&Adapter->fw_download_sema); | |
| 905 | − up(&Adapter->NVMRdmWrmLock); | |
| 906 | − break; | |
| 1049 | + case IOCTL_BCM_GET_HOST_MIBS: { | |
| 1050 | + PVOID temp_buff; | |
| 1051 | + | |
| 1052 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1053 | + return -EFAULT; | |
| 1054 | + | |
| 1055 | + if (IoBuffer.OutputLength != sizeof(S_MIBS_HOST_STATS_MIBS)) { | |
| 1056 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, | |
| 1057 | + "Length Check failed %lu %zd\n", | |
| 1058 | + IoBuffer.OutputLength, sizeof(S_MIBS_HOST_STATS_MIBS)); | |
| 1059 | + return -EINVAL; | |
| 907 | 1060 | } |
| 908 | − case IOCTL_BE_BUCKET_SIZE: | |
| 909 | − Status = 0; | |
| 910 | − if (get_user(Adapter->BEBucketSize, (unsigned long __user *)arg)) | |
| 911 | − Status = -EFAULT; | |
| 912 | − break; | |
| 913 | 1061 | |
| 914 | − case IOCTL_RTPS_BUCKET_SIZE: | |
| 915 | − Status = 0; | |
| 916 | − if (get_user(Adapter->rtPSBucketSize, (unsigned long __user *)arg)) | |
| 1062 | + /* FIXME: HOST_STATS are too big for kmalloc (122048)! */ | |
| 1063 | + temp_buff = kzalloc(sizeof(S_MIBS_HOST_STATS_MIBS), GFP_KERNEL); | |
| 1064 | + if (!temp_buff) | |
| 1065 | + return STATUS_FAILURE; | |
| 1066 | + | |
| 1067 | + Status = ProcessGetHostMibs(Adapter, temp_buff); | |
| 1068 | + GetDroppedAppCntrlPktMibs(temp_buff, pTarang); | |
| 1069 | + | |
| 1070 | + if (Status != STATUS_FAILURE) | |
| 1071 | + if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, sizeof(S_MIBS_HOST_STATS_MIBS))) | |
| 917 | 1072 | Status = -EFAULT; |
| 918 | − break; | |
| 919 | − case IOCTL_CHIP_RESET: | |
| 920 | − { | |
| 921 | − INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); | |
| 922 | − if(NVMAccess) | |
| 923 | − { | |
| 924 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n"); | |
| 925 | − return -EACCES; | |
| 926 | − } | |
| 927 | − down(&Adapter->RxAppControlQueuelock); | |
| 928 | − Status = reset_card_proc(Adapter); | |
| 929 | − flushAllAppQ(); | |
| 930 | − up(&Adapter->RxAppControlQueuelock); | |
| 931 | − up(&Adapter->NVMRdmWrmLock); | |
| 932 | − ResetCounters(Adapter); | |
| 933 | − break; | |
| 1073 | + | |
| 1074 | + kfree(temp_buff); | |
| 1075 | + break; | |
| 1076 | + } | |
| 1077 | + | |
| 1078 | + case IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE: | |
| 1079 | + if ((FALSE == Adapter->bTriedToWakeUpFromlowPowerMode) && (TRUE == Adapter->IdleMode)) { | |
| 1080 | + Adapter->usIdleModePattern = ABORT_IDLE_MODE; | |
| 1081 | + Adapter->bWakeUpDevice = TRUE; | |
| 1082 | + wake_up(&Adapter->process_rx_cntrlpkt); | |
| 934 | 1083 | } |
| 935 | − case IOCTL_QOS_THRESHOLD: | |
| 936 | − { | |
| 937 | − USHORT uiLoopIndex; | |
| 938 | 1084 | |
| 939 | − Status = 0; | |
| 940 | − for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) { | |
| 941 | − if (get_user(Adapter->PackInfo[uiLoopIndex].uiThreshold, | |
| 942 | − (unsigned long __user *)arg)) { | |
| 943 | − Status = -EFAULT; | |
| 944 | − break; | |
| 945 | − } | |
| 946 | − } | |
| 1085 | + Status = STATUS_SUCCESS; | |
| 1086 | + break; | |
| 1087 | + | |
| 1088 | + case IOCTL_BCM_BULK_WRM: { | |
| 1089 | + PBULKWRM_BUFFER pBulkBuffer; | |
| 1090 | + UINT uiTempVar = 0; | |
| 1091 | + PCHAR pvBuffer = NULL; | |
| 1092 | + | |
| 1093 | + if ((Adapter->IdleMode == TRUE) || | |
| 1094 | + (Adapter->bShutStatus == TRUE) || | |
| 1095 | + (Adapter->bPreparingForLowPowerMode == TRUE)) { | |
| 1096 | + | |
| 1097 | + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle/Shutdown Mode, Blocking Wrms\n"); | |
| 1098 | + Status = -EACCES; | |
| 947 | 1099 | break; |
| 948 | 1100 | } |
| 949 | 1101 | |
| 950 | − case IOCTL_DUMP_PACKET_INFO: | |
| 1102 | + /* Copy Ioctl Buffer structure */ | |
| 1103 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1104 | + return -EFAULT; | |
| 951 | 1105 | |
| 952 | − DumpPackInfo(Adapter); | |
| 953 | − DumpPhsRules(&Adapter->stBCMPhsContext); | |
| 954 | − Status = STATUS_SUCCESS; | |
| 1106 | + /* FIXME: restrict length */ | |
| 1107 | + pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL); | |
| 1108 | + if (!pvBuffer) | |
| 1109 | + return -ENOMEM; | |
| 1110 | + | |
| 1111 | + /* Get WrmBuffer structure */ | |
| 1112 | + if (copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) { | |
| 1113 | + kfree(pvBuffer); | |
| 1114 | + Status = -EFAULT; | |
| 955 | 1115 | break; |
| 1116 | + } | |
| 956 | 1117 | |
| 957 | − case IOCTL_GET_PACK_INFO: | |
| 958 | − if(copy_to_user(argp, &Adapter->PackInfo, sizeof(PacketInfo)*NO_OF_QUEUES)) | |
| 959 | − return -EFAULT; | |
| 960 | − Status = STATUS_SUCCESS; | |
| 1118 | + pBulkBuffer = (PBULKWRM_BUFFER)pvBuffer; | |
| 1119 | + | |
| 1120 | + if (((ULONG)pBulkBuffer->Register & 0x0F000000) != 0x0F000000 || | |
| 1121 | + ((ULONG)pBulkBuffer->Register & 0x3)) { | |
| 1122 | + kfree(pvBuffer); | |
| 1123 | + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n", (int)pBulkBuffer->Register); | |
| 1124 | + Status = -EINVAL; | |
| 961 | 1125 | break; |
| 962 | − case IOCTL_BCM_SWITCH_TRANSFER_MODE: | |
| 963 | − { | |
| 964 | − UINT uiData = 0; | |
| 965 | − if(copy_from_user(&uiData, argp, sizeof(UINT))) | |
| 966 | − return -EFAULT; | |
| 1126 | + } | |
| 967 | 1127 | |
| 968 | − if(uiData) /* Allow All Packets */ | |
| 969 | − { | |
| 970 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: ETH_PACKET_TUNNELING_MODE\n"); | |
| 971 | − Adapter->TransferMode = ETH_PACKET_TUNNELING_MODE; | |
| 972 | − } | |
| 973 | − else /* Allow IP only Packets */ | |
| 974 | − { | |
| 975 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: IP_PACKET_ONLY_MODE\n"); | |
| 976 | − Adapter->TransferMode = IP_PACKET_ONLY_MODE; | |
| 977 | − } | |
| 978 | − Status = STATUS_SUCCESS; | |
| 1128 | + uiTempVar = pBulkBuffer->Register & EEPROM_REJECT_MASK; | |
| 1129 | + if (!((Adapter->pstargetparams->m_u32Customize)&VSG_MODE) && | |
| 1130 | + ((uiTempVar == EEPROM_REJECT_REG_1) || | |
| 1131 | + (uiTempVar == EEPROM_REJECT_REG_2) || | |
| 1132 | + (uiTempVar == EEPROM_REJECT_REG_3) || | |
| 1133 | + (uiTempVar == EEPROM_REJECT_REG_4)) && | |
| 1134 | + (cmd == IOCTL_BCM_REGISTER_WRITE)) { | |
| 1135 | + | |
| 1136 | + kfree(pvBuffer); | |
| 1137 | + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); | |
| 1138 | + Status = -EFAULT; | |
| 979 | 1139 | break; |
| 980 | 1140 | } |
| 981 | 1141 | |
| 982 | − case IOCTL_BCM_GET_DRIVER_VERSION: | |
| 983 | − { | |
| 984 | − /* Copy Ioctl Buffer structure */ | |
| 985 | − if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 986 | − return -EFAULT; | |
| 1142 | + if (pBulkBuffer->SwapEndian == FALSE) | |
| 1143 | + Status = wrmWithLock(Adapter, (UINT)pBulkBuffer->Register, (PCHAR)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG)); | |
| 1144 | + else | |
| 1145 | + Status = wrmaltWithLock(Adapter, (UINT)pBulkBuffer->Register, (PUINT)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG)); | |
| 1146 | + | |
| 1147 | + if (Status != STATUS_SUCCESS) | |
| 1148 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM Failed\n"); | |
| 1149 | + | |
| 1150 | + kfree(pvBuffer); | |
| 1151 | + break; | |
| 1152 | + } | |
| 1153 | + | |
| 1154 | + case IOCTL_BCM_GET_NVM_SIZE: | |
| 1155 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1156 | + return -EFAULT; | |
| 987 | 1157 | |
| 988 | − if(copy_to_user(IoBuffer.OutputBuffer, VER_FILEVERSION_STR, IoBuffer.OutputLength)) | |
| 1158 | + if (Adapter->eNVMType == NVM_EEPROM || Adapter->eNVMType == NVM_FLASH) { | |
| 1159 | + if (copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiNVMDSDSize, sizeof(UINT))) | |
| 989 | 1160 | return -EFAULT; |
| 990 | − Status = STATUS_SUCCESS; | |
| 991 | − break; | |
| 992 | 1161 | } |
| 993 | − case IOCTL_BCM_GET_CURRENT_STATUS: | |
| 994 | − { | |
| 995 | − LINK_STATE link_state; | |
| 996 | 1162 | |
| 997 | − /* Copy Ioctl Buffer structure */ | |
| 998 | − if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 999 | − { | |
| 1000 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user failed..\n"); | |
| 1001 | − Status = -EFAULT; | |
| 1002 | − break; | |
| 1003 | − } | |
| 1004 | − if (IoBuffer.OutputLength != sizeof(link_state)) { | |
| 1005 | − Status = -EINVAL; | |
| 1006 | − break; | |
| 1007 | − } | |
| 1163 | + Status = STATUS_SUCCESS; | |
| 1164 | + break; | |
| 1008 | 1165 | |
| 1009 | − memset(&link_state, 0, sizeof(link_state)); | |
| 1010 | − link_state.bIdleMode = Adapter->IdleMode; | |
| 1011 | − link_state.bShutdownMode = Adapter->bShutStatus; | |
| 1012 | − link_state.ucLinkStatus = Adapter->LinkStatus; | |
| 1166 | + case IOCTL_BCM_CAL_INIT: { | |
| 1167 | + UINT uiSectorSize = 0 ; | |
| 1168 | + if (Adapter->eNVMType == NVM_FLASH) { | |
| 1169 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1170 | + return -EFAULT; | |
| 1013 | 1171 | |
| 1014 | − if (copy_to_user(IoBuffer.OutputBuffer, &link_state, | |
| 1015 | − min_t(size_t, sizeof(link_state), IoBuffer.OutputLength))) | |
| 1016 | − { | |
| 1017 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_to_user Failed..\n"); | |
| 1018 | − Status = -EFAULT; | |
| 1019 | − break; | |
| 1172 | + if (copy_from_user(&uiSectorSize, IoBuffer.InputBuffer, sizeof(UINT))) | |
| 1173 | + return -EFAULT; | |
| 1174 | + | |
| 1175 | + if ((uiSectorSize < MIN_SECTOR_SIZE) || (uiSectorSize > MAX_SECTOR_SIZE)) { | |
| 1176 | + if (copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiSectorSize, | |
| 1177 | + sizeof(UINT))) | |
| 1178 | + return -EFAULT; | |
| 1179 | + } else { | |
| 1180 | + if (IsFlash2x(Adapter)) { | |
| 1181 | + if (copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiSectorSize, sizeof(UINT))) | |
| 1182 | + return -EFAULT; | |
| 1183 | + } else { | |
| 1184 | + if ((TRUE == Adapter->bShutStatus) || (TRUE == Adapter->IdleMode)) { | |
| 1185 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device is in Idle/Shutdown Mode\n"); | |
| 1186 | + return -EACCES; | |
| 1187 | + } | |
| 1188 | + | |
| 1189 | + Adapter->uiSectorSize = uiSectorSize; | |
| 1190 | + BcmUpdateSectorSize(Adapter, Adapter->uiSectorSize); | |
| 1191 | + } | |
| 1020 | 1192 | } |
| 1021 | 1193 | Status = STATUS_SUCCESS; |
| 1022 | − break; | |
| 1194 | + } else { | |
| 1195 | + Status = STATUS_FAILURE; | |
| 1023 | 1196 | } |
| 1024 | − case IOCTL_BCM_SET_MAC_TRACING: | |
| 1025 | − { | |
| 1026 | − UINT tracing_flag; | |
| 1027 | − | |
| 1028 | − /* copy ioctl Buffer structure */ | |
| 1029 | − if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1030 | − return -EFAULT; | |
| 1031 | − | |
| 1032 | − if(copy_from_user(&tracing_flag,IoBuffer.InputBuffer,sizeof(UINT))) | |
| 1033 | − return -EFAULT; | |
| 1034 | − | |
| 1035 | − if (tracing_flag) | |
| 1036 | − Adapter->pTarangs->MacTracingEnabled = TRUE; | |
| 1037 | − else | |
| 1038 | − Adapter->pTarangs->MacTracingEnabled = FALSE; | |
| 1039 | − break; | |
| 1040 | − } | |
| 1041 | − case IOCTL_BCM_GET_DSX_INDICATION: | |
| 1042 | − { | |
| 1043 | − ULONG ulSFId=0; | |
| 1044 | − if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1045 | − return -EFAULT; | |
| 1197 | + } | |
| 1198 | + break; | |
| 1046 | 1199 | |
| 1047 | − if(IoBuffer.OutputLength < sizeof(stLocalSFAddIndicationAlt)) | |
| 1048 | − { | |
| 1049 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, | |
| 1050 | − "Mismatch req: %lx needed is =0x%zx!!!", | |
| 1051 | − IoBuffer.OutputLength, sizeof(stLocalSFAddIndicationAlt)); | |
| 1052 | − return -EINVAL; | |
| 1053 | − } | |
| 1200 | + case IOCTL_BCM_SET_DEBUG: | |
| 1201 | +#ifdef DEBUG | |
| 1202 | + { | |
| 1203 | + USER_BCM_DBG_STATE sUserDebugState; | |
| 1054 | 1204 | |
| 1055 | − if(copy_from_user(&ulSFId, IoBuffer.InputBuffer, sizeof(ulSFId))) | |
| 1056 | − return -EFAULT; | |
| 1205 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "In SET_DEBUG ioctl\n"); | |
| 1206 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1207 | + return -EFAULT; | |
| 1208 | + | |
| 1209 | + if (copy_from_user(&sUserDebugState, IoBuffer.InputBuffer, sizeof(USER_BCM_DBG_STATE))) | |
| 1210 | + return -EFAULT; | |
| 1057 | 1211 | |
| 1058 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Get DSX Data SF ID is =%lx\n", ulSFId ); | |
| 1059 | − get_dsx_sf_data_to_application(Adapter, ulSFId, IoBuffer.OutputBuffer); | |
| 1060 | − Status=STATUS_SUCCESS; | |
| 1212 | + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "IOCTL_BCM_SET_DEBUG: OnOff=%d Type = 0x%x ", | |
| 1213 | + sUserDebugState.OnOff, sUserDebugState.Type); | |
| 1214 | + /* sUserDebugState.Subtype <<= 1; */ | |
| 1215 | + sUserDebugState.Subtype = 1 << sUserDebugState.Subtype; | |
| 1216 | + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "actual Subtype=0x%x\n", sUserDebugState.Subtype); | |
| 1217 | + | |
| 1218 | + /* Update new 'DebugState' in the Adapter */ | |
| 1219 | + Adapter->stDebugState.type |= sUserDebugState.Type; | |
| 1220 | + /* Subtype: A bitmap of 32 bits for Subtype per Type. | |
| 1221 | + * Valid indexes in 'subtype' array: 1,2,4,8 | |
| 1222 | + * corresponding to valid Type values. Hence we can use the 'Type' field | |
| 1223 | + * as the index value, ignoring the array entries 0,3,5,6,7 ! | |
| 1224 | + */ | |
| 1225 | + if (sUserDebugState.OnOff) | |
| 1226 | + Adapter->stDebugState.subtype[sUserDebugState.Type] |= sUserDebugState.Subtype; | |
| 1227 | + else | |
| 1228 | + Adapter->stDebugState.subtype[sUserDebugState.Type] &= ~sUserDebugState.Subtype; | |
| 1229 | + | |
| 1230 | + BCM_SHOW_DEBUG_BITMAP(Adapter); | |
| 1231 | + } | |
| 1232 | +#endif | |
| 1233 | + break; | |
| 1234 | + | |
| 1235 | + case IOCTL_BCM_NVM_READ: | |
| 1236 | + case IOCTL_BCM_NVM_WRITE: { | |
| 1237 | + NVM_READWRITE stNVMReadWrite; | |
| 1238 | + PUCHAR pReadData = NULL; | |
| 1239 | + ULONG ulDSDMagicNumInUsrBuff = 0; | |
| 1240 | + struct timeval tv0, tv1; | |
| 1241 | + memset(&tv0, 0, sizeof(struct timeval)); | |
| 1242 | + memset(&tv1, 0, sizeof(struct timeval)); | |
| 1243 | + if ((Adapter->eNVMType == NVM_FLASH) && (Adapter->uiFlashLayoutMajorVersion == 0)) { | |
| 1244 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "The Flash Control Section is Corrupted. Hence Rejection on NVM Read/Write\n"); | |
| 1245 | + Status = -EFAULT; | |
| 1246 | + break; | |
| 1061 | 1247 | } |
| 1062 | − break; | |
| 1063 | − case IOCTL_BCM_GET_HOST_MIBS: | |
| 1064 | − { | |
| 1065 | − PVOID temp_buff; | |
| 1066 | 1248 | |
| 1067 | − if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1068 | − return -EFAULT; | |
| 1249 | + if (IsFlash2x(Adapter)) { | |
| 1250 | + if ((Adapter->eActiveDSD != DSD0) && | |
| 1251 | + (Adapter->eActiveDSD != DSD1) && | |
| 1252 | + (Adapter->eActiveDSD != DSD2)) { | |
| 1069 | 1253 | |
| 1070 | − if(IoBuffer.OutputLength != sizeof(S_MIBS_HOST_STATS_MIBS)) | |
| 1071 | − { | |
| 1072 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, | |
| 1073 | − "Length Check failed %lu %zd\n", | |
| 1074 | − IoBuffer.OutputLength, sizeof(S_MIBS_HOST_STATS_MIBS)); | |
| 1075 | − return -EINVAL; | |
| 1254 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "No DSD is active..hence NVM Command is blocked"); | |
| 1255 | + return STATUS_FAILURE ; | |
| 1076 | 1256 | } |
| 1257 | + } | |
| 1077 | 1258 | |
| 1078 | − /* FIXME: HOST_STATS are too big for kmalloc (122048)! */ | |
| 1079 | − temp_buff = kzalloc(sizeof(S_MIBS_HOST_STATS_MIBS), GFP_KERNEL); | |
| 1080 | − if(!temp_buff) | |
| 1081 | − return STATUS_FAILURE; | |
| 1259 | + /* Copy Ioctl Buffer structure */ | |
| 1260 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1261 | + return -EFAULT; | |
| 1082 | 1262 | |
| 1083 | − Status = ProcessGetHostMibs(Adapter, temp_buff); | |
| 1084 | − GetDroppedAppCntrlPktMibs(temp_buff, pTarang); | |
| 1263 | + if (copy_from_user(&stNVMReadWrite, | |
| 1264 | + (IOCTL_BCM_NVM_READ == cmd) ? IoBuffer.OutputBuffer : IoBuffer.InputBuffer, | |
| 1265 | + sizeof(NVM_READWRITE))) | |
| 1266 | + return -EFAULT; | |
| 1085 | 1267 | |
| 1086 | − if (Status != STATUS_FAILURE) | |
| 1087 | − if(copy_to_user(IoBuffer.OutputBuffer, temp_buff, sizeof(S_MIBS_HOST_STATS_MIBS))) | |
| 1088 | − Status = -EFAULT; | |
| 1268 | + /* | |
| 1269 | + * Deny the access if the offset crosses the cal area limit. | |
| 1270 | + */ | |
| 1089 | 1271 | |
| 1090 | − kfree(temp_buff); | |
| 1272 | + if ((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) > Adapter->uiNVMDSDSize) { | |
| 1273 | + /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allow access beyond NVM Size: 0x%x 0x%x\n", stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes); */ | |
| 1274 | + Status = STATUS_FAILURE; | |
| 1091 | 1275 | break; |
| 1092 | 1276 | } |
| 1093 | 1277 | |
| 1094 | − case IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE: | |
| 1095 | − if((FALSE == Adapter->bTriedToWakeUpFromlowPowerMode) && (TRUE==Adapter->IdleMode)) | |
| 1096 | − { | |
| 1097 | − Adapter->usIdleModePattern = ABORT_IDLE_MODE; | |
| 1098 | − Adapter->bWakeUpDevice = TRUE; | |
| 1099 | − wake_up(&Adapter->process_rx_cntrlpkt); | |
| 1100 | − } | |
| 1101 | − Status = STATUS_SUCCESS; | |
| 1278 | + pReadData = kzalloc(stNVMReadWrite.uiNumBytes, GFP_KERNEL); | |
| 1279 | + if (!pReadData) | |
| 1280 | + return -ENOMEM; | |
| 1281 | + | |
| 1282 | + if (copy_from_user(pReadData, stNVMReadWrite.pBuffer, stNVMReadWrite.uiNumBytes)) { | |
| 1283 | + Status = -EFAULT; | |
| 1284 | + kfree(pReadData); | |
| 1102 | 1285 | break; |
| 1286 | + } | |
| 1103 | 1287 | |
| 1104 | − case IOCTL_BCM_BULK_WRM: | |
| 1105 | − { | |
| 1106 | − PBULKWRM_BUFFER pBulkBuffer; | |
| 1107 | − UINT uiTempVar=0; | |
| 1108 | − PCHAR pvBuffer = NULL; | |
| 1109 | − | |
| 1110 | − if((Adapter->IdleMode == TRUE) || | |
| 1111 | − (Adapter->bShutStatus ==TRUE) || | |
| 1112 | − (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
| 1113 | − { | |
| 1114 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle/Shutdown Mode, Blocking Wrms\n"); | |
| 1115 | − Status = -EACCES; | |
| 1116 | − break; | |
| 1117 | − } | |
| 1288 | + do_gettimeofday(&tv0); | |
| 1289 | + if (IOCTL_BCM_NVM_READ == cmd) { | |
| 1290 | + down(&Adapter->NVMRdmWrmLock); | |
| 1291 | + | |
| 1292 | + if ((Adapter->IdleMode == TRUE) || | |
| 1293 | + (Adapter->bShutStatus == TRUE) || | |
| 1294 | + (Adapter->bPreparingForLowPowerMode == TRUE)) { | |
| 1295 | + | |
| 1296 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n"); | |
| 1297 | + up(&Adapter->NVMRdmWrmLock); | |
| 1298 | + kfree(pReadData); | |
| 1299 | + return -EACCES; | |
| 1300 | + } | |
| 1301 | + | |
| 1302 | + Status = BeceemNVMRead(Adapter, (PUINT)pReadData, stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes); | |
| 1303 | + up(&Adapter->NVMRdmWrmLock); | |
| 1304 | + | |
| 1305 | + if (Status != STATUS_SUCCESS) { | |
| 1306 | + kfree(pReadData); | |
| 1307 | + return Status; | |
| 1308 | + } | |
| 1309 | + | |
| 1310 | + if (copy_to_user(stNVMReadWrite.pBuffer, pReadData, stNVMReadWrite.uiNumBytes)) { | |
| 1311 | + kfree(pReadData); | |
| 1312 | + Status = -EFAULT; | |
| 1313 | + } | |
| 1314 | + } else { | |
| 1315 | + down(&Adapter->NVMRdmWrmLock); | |
| 1118 | 1316 | |
| 1119 | − /* Copy Ioctl Buffer structure */ | |
| 1120 | − if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1121 | − return -EFAULT; | |
| 1317 | + if ((Adapter->IdleMode == TRUE) || | |
| 1318 | + (Adapter->bShutStatus == TRUE) || | |
| 1319 | + (Adapter->bPreparingForLowPowerMode == TRUE)) { | |
| 1122 | 1320 | |
| 1123 | − /* FIXME: restrict length */ | |
| 1124 | − pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL); | |
| 1125 | − if(!pvBuffer) | |
| 1126 | − return -ENOMEM; | |
| 1127 | − | |
| 1128 | − /* Get WrmBuffer structure */ | |
| 1129 | − if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) | |
| 1130 | − { | |
| 1131 | − kfree(pvBuffer); | |
| 1132 | − Status = -EFAULT; | |
| 1133 | − break; | |
| 1134 | − } | |
| 1321 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n"); | |
| 1322 | + up(&Adapter->NVMRdmWrmLock); | |
| 1323 | + kfree(pReadData); | |
| 1324 | + return -EACCES; | |
| 1325 | + } | |
| 1135 | 1326 | |
| 1136 | − pBulkBuffer = (PBULKWRM_BUFFER)pvBuffer; | |
| 1327 | + Adapter->bHeaderChangeAllowed = TRUE; | |
| 1328 | + if (IsFlash2x(Adapter)) { | |
| 1329 | + /* | |
| 1330 | + * New Requirement:- | |
| 1331 | + * DSD section updation will be allowed in two case:- | |
| 1332 | + * 1. if DSD sig is present in DSD header means dongle is ok and updation is fruitfull | |
| 1333 | + * 2. if point 1 failes then user buff should have DSD sig. this point ensures that if dongle is | |
| 1334 | + * corrupted then user space program first modify the DSD header with valid DSD sig so | |
| 1335 | + * that this as well as further write may be worthwhile. | |
| 1336 | + * | |
| 1337 | + * This restriction has been put assuming that if DSD sig is corrupted, DSD | |
| 1338 | + * data won't be considered valid. | |
| 1339 | + */ | |
| 1137 | 1340 | |
| 1138 | − if(((ULONG)pBulkBuffer->Register & 0x0F000000) != 0x0F000000 || | |
| 1139 | − ((ULONG)pBulkBuffer->Register & 0x3)) | |
| 1140 | − { | |
| 1141 | − kfree(pvBuffer); | |
| 1142 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,"WRM Done On invalid Address : %x Access Denied.\n",(int)pBulkBuffer->Register); | |
| 1143 | − Status = -EINVAL; | |
| 1144 | − break; | |
| 1145 | − } | |
| 1341 | + Status = BcmFlash2xCorruptSig(Adapter, Adapter->eActiveDSD); | |
| 1342 | + if (Status != STATUS_SUCCESS) { | |
| 1343 | + if (((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) != Adapter->uiNVMDSDSize) || | |
| 1344 | + (stNVMReadWrite.uiNumBytes < SIGNATURE_SIZE)) { | |
| 1146 | 1345 | |
| 1346 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "DSD Sig is present neither in Flash nor User provided Input.."); | |
| 1347 | + up(&Adapter->NVMRdmWrmLock); | |
| 1348 | + kfree(pReadData); | |
| 1349 | + return Status; | |
| 1350 | + } | |
| 1147 | 1351 | |
| 1148 | − uiTempVar = pBulkBuffer->Register & EEPROM_REJECT_MASK; | |
| 1149 | − if(!((Adapter->pstargetparams->m_u32Customize)&VSG_MODE) | |
| 1150 | − && ((uiTempVar == EEPROM_REJECT_REG_1)|| | |
| 1151 | − (uiTempVar == EEPROM_REJECT_REG_2) || | |
| 1152 | − (uiTempVar == EEPROM_REJECT_REG_3) || | |
| 1153 | − (uiTempVar == EEPROM_REJECT_REG_4)) && | |
| 1154 | − (cmd == IOCTL_BCM_REGISTER_WRITE)) | |
| 1155 | − { | |
| 1156 | − kfree(pvBuffer); | |
| 1157 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,"EEPROM Access Denied, not in VSG Mode\n"); | |
| 1158 | − Status = -EFAULT; | |
| 1159 | − break; | |
| 1352 | + ulDSDMagicNumInUsrBuff = ntohl(*(PUINT)(pReadData + stNVMReadWrite.uiNumBytes - SIGNATURE_SIZE)); | |
| 1353 | + if (ulDSDMagicNumInUsrBuff != DSD_IMAGE_MAGIC_NUMBER) { | |
| 1354 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "DSD Sig is present neither in Flash nor User provided Input.."); | |
| 1355 | + up(&Adapter->NVMRdmWrmLock); | |
| 1356 | + kfree(pReadData); | |
| 1357 | + return Status; | |
| 1358 | + } | |
| 1160 | 1359 | } |
| 1360 | + } | |
| 1161 | 1361 | |
| 1162 | − if(pBulkBuffer->SwapEndian == FALSE) | |
| 1163 | − Status = wrmWithLock(Adapter, (UINT)pBulkBuffer->Register, (PCHAR)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG)); | |
| 1164 | − else | |
| 1165 | − Status = wrmaltWithLock(Adapter, (UINT)pBulkBuffer->Register, (PUINT)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG)); | |
| 1166 | − | |
| 1167 | − if(Status != STATUS_SUCCESS) | |
| 1168 | − { | |
| 1169 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WRM Failed\n"); | |
| 1170 | − } | |
| 1362 | + Status = BeceemNVMWrite(Adapter, (PUINT)pReadData, stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes, stNVMReadWrite.bVerify); | |
| 1363 | + if (IsFlash2x(Adapter)) | |
| 1364 | + BcmFlash2xWriteSig(Adapter, Adapter->eActiveDSD); | |
| 1171 | 1365 | |
| 1172 | − kfree(pvBuffer); | |
| 1173 | − break; | |
| 1174 | − } | |
| 1366 | + Adapter->bHeaderChangeAllowed = FALSE; | |
| 1175 | 1367 | |
| 1176 | − case IOCTL_BCM_GET_NVM_SIZE: | |
| 1177 | − if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1178 | − return -EFAULT; | |
| 1368 | + up(&Adapter->NVMRdmWrmLock); | |
| 1179 | 1369 | |
| 1180 | − if(Adapter->eNVMType == NVM_EEPROM || Adapter->eNVMType == NVM_FLASH ) { | |
| 1181 | − if(copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiNVMDSDSize, sizeof(UINT))) | |
| 1182 | − return -EFAULT; | |
| 1370 | + if (Status != STATUS_SUCCESS) { | |
| 1371 | + kfree(pReadData); | |
| 1372 | + return Status; | |
| 1183 | 1373 | } |
| 1184 | − Status = STATUS_SUCCESS ; | |
| 1185 | − break; | |
| 1374 | + } | |
| 1186 | 1375 | |
| 1187 | − case IOCTL_BCM_CAL_INIT : | |
| 1376 | + do_gettimeofday(&tv1); | |
| 1377 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " timetaken by Write/read :%ld msec\n", (tv1.tv_sec - tv0.tv_sec)*1000 + (tv1.tv_usec - tv0.tv_usec)/1000); | |
| 1188 | 1378 | |
| 1189 | − { | |
| 1190 | − UINT uiSectorSize = 0 ; | |
| 1191 | − if(Adapter->eNVMType == NVM_FLASH) | |
| 1192 | − { | |
| 1193 | − if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1194 | − return -EFAULT; | |
| 1379 | + kfree(pReadData); | |
| 1380 | + Status = STATUS_SUCCESS; | |
| 1381 | + } | |
| 1382 | + break; | |
| 1383 | + | |
| 1384 | + case IOCTL_BCM_FLASH2X_SECTION_READ: { | |
| 1385 | + FLASH2X_READWRITE sFlash2xRead = {0}; | |
| 1386 | + PUCHAR pReadBuff = NULL ; | |
| 1387 | + UINT NOB = 0; | |
| 1388 | + UINT BuffSize = 0; | |
| 1389 | + UINT ReadBytes = 0; | |
| 1390 | + UINT ReadOffset = 0; | |
| 1391 | + void __user *OutPutBuff; | |
| 1392 | + | |
| 1393 | + if (IsFlash2x(Adapter) != TRUE) { | |
| 1394 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Does not have 2.x map"); | |
| 1395 | + return -EINVAL; | |
| 1396 | + } | |
| 1195 | 1397 | |
| 1196 | − if (copy_from_user(&uiSectorSize, IoBuffer.InputBuffer, sizeof(UINT))) | |
| 1197 | − return -EFAULT; | |
| 1398 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_READ Called"); | |
| 1399 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1400 | + return -EFAULT; | |
| 1198 | 1401 | |
| 1199 | − if((uiSectorSize < MIN_SECTOR_SIZE) || (uiSectorSize > MAX_SECTOR_SIZE)) | |
| 1200 | − { | |
| 1201 | − if (copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiSectorSize, | |
| 1202 | − sizeof(UINT))) | |
| 1203 | − return -EFAULT; | |
| 1204 | − } | |
| 1205 | − else | |
| 1206 | − { | |
| 1207 | − if(IsFlash2x(Adapter)) | |
| 1208 | − { | |
| 1209 | − if (copy_to_user(IoBuffer.OutputBuffer, | |
| 1210 | − &Adapter->uiSectorSize , | |
| 1211 | − sizeof(UINT))) | |
| 1212 | − return -EFAULT; | |
| 1213 | − } | |
| 1214 | − else | |
| 1215 | − { | |
| 1216 | − if((TRUE == Adapter->bShutStatus) || | |
| 1217 | − (TRUE == Adapter->IdleMode)) | |
| 1218 | − { | |
| 1219 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle/Shutdown Mode\n"); | |
| 1220 | − return -EACCES; | |
| 1221 | − } | |
| 1222 | − | |
| 1223 | − Adapter->uiSectorSize = uiSectorSize ; | |
| 1224 | − BcmUpdateSectorSize(Adapter,Adapter->uiSectorSize); | |
| 1225 | − } | |
| 1226 | − } | |
| 1227 | − Status = STATUS_SUCCESS ; | |
| 1228 | − } | |
| 1229 | − else | |
| 1230 | − { | |
| 1231 | − Status = STATUS_FAILURE; | |
| 1232 | − } | |
| 1233 | − } | |
| 1234 | − break; | |
| 1235 | − case IOCTL_BCM_SET_DEBUG : | |
| 1236 | −#ifdef DEBUG | |
| 1237 | − { | |
| 1238 | − USER_BCM_DBG_STATE sUserDebugState; | |
| 1402 | + /* Reading FLASH 2.x READ structure */ | |
| 1403 | + if (copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer, sizeof(FLASH2X_READWRITE))) | |
| 1404 | + return -EFAULT; | |
| 1239 | 1405 | |
| 1240 | −// BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Entered the ioctl %x \n", IOCTL_BCM_SET_DEBUG ); | |
| 1406 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.Section :%x", sFlash2xRead.Section); | |
| 1407 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.offset :%x", sFlash2xRead.offset); | |
| 1408 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.numOfBytes :%x", sFlash2xRead.numOfBytes); | |
| 1409 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.bVerify :%x\n", sFlash2xRead.bVerify); | |
| 1241 | 1410 | |
| 1242 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "In SET_DEBUG ioctl\n"); | |
| 1243 | − if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1244 | − return -EFAULT; | |
| 1411 | + /* This was internal to driver for raw read. now it has ben exposed to user space app. */ | |
| 1412 | + if (validateFlash2xReadWrite(Adapter, &sFlash2xRead) == FALSE) | |
| 1413 | + return STATUS_FAILURE; | |
| 1245 | 1414 | |
| 1246 | − if (copy_from_user(&sUserDebugState, IoBuffer.InputBuffer, sizeof(USER_BCM_DBG_STATE))) | |
| 1247 | − return -EFAULT; | |
| 1415 | + NOB = sFlash2xRead.numOfBytes; | |
| 1416 | + if (NOB > Adapter->uiSectorSize) | |
| 1417 | + BuffSize = Adapter->uiSectorSize; | |
| 1418 | + else | |
| 1419 | + BuffSize = NOB; | |
| 1248 | 1420 | |
| 1421 | + ReadOffset = sFlash2xRead.offset ; | |
| 1422 | + OutPutBuff = IoBuffer.OutputBuffer; | |
| 1423 | + pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL); | |
| 1249 | 1424 | |
| 1250 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "IOCTL_BCM_SET_DEBUG: OnOff=%d Type = 0x%x ", | |
| 1251 | − sUserDebugState.OnOff, sUserDebugState.Type); | |
| 1252 | − //sUserDebugState.Subtype <<= 1; | |
| 1253 | − sUserDebugState.Subtype = 1 << sUserDebugState.Subtype; | |
| 1254 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "actual Subtype=0x%x\n", sUserDebugState.Subtype); | |
| 1255 | − | |
| 1256 | − // Update new 'DebugState' in the Adapter | |
| 1257 | − Adapter->stDebugState.type |= sUserDebugState.Type; | |
| 1258 | − /* Subtype: A bitmap of 32 bits for Subtype per Type. | |
| 1259 | − * Valid indexes in 'subtype' array: 1,2,4,8 | |
| 1260 | − * corresponding to valid Type values. Hence we can use the 'Type' field | |
| 1261 | − * as the index value, ignoring the array entries 0,3,5,6,7 ! | |
| 1262 | − */ | |
| 1263 | − if (sUserDebugState.OnOff) | |
| 1264 | − Adapter->stDebugState.subtype[sUserDebugState.Type] |= sUserDebugState.Subtype; | |
| 1265 | − else | |
| 1266 | − Adapter->stDebugState.subtype[sUserDebugState.Type] &= ~sUserDebugState.Subtype; | |
| 1425 | + if (pReadBuff == NULL) { | |
| 1426 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed for Flash 2.x Read Structure"); | |
| 1427 | + return -ENOMEM; | |
| 1428 | + } | |
| 1429 | + down(&Adapter->NVMRdmWrmLock); | |
| 1267 | 1430 | |
| 1268 | − BCM_SHOW_DEBUG_BITMAP(Adapter); | |
| 1431 | + if ((Adapter->IdleMode == TRUE) || | |
| 1432 | + (Adapter->bShutStatus == TRUE) || | |
| 1433 | + (Adapter->bPreparingForLowPowerMode == TRUE)) { | |
| 1269 | 1434 | |
| 1270 | − } | |
| 1271 | −#endif | |
| 1272 | − break; | |
| 1273 | − case IOCTL_BCM_NVM_READ: | |
| 1274 | − case IOCTL_BCM_NVM_WRITE: | |
| 1275 | − { | |
| 1276 | − NVM_READWRITE stNVMReadWrite; | |
| 1277 | − PUCHAR pReadData = NULL; | |
| 1278 | − ULONG ulDSDMagicNumInUsrBuff = 0; | |
| 1279 | − struct timeval tv0, tv1; | |
| 1280 | − memset(&tv0,0,sizeof(struct timeval)); | |
| 1281 | − memset(&tv1,0,sizeof(struct timeval)); | |
| 1282 | − if((Adapter->eNVMType == NVM_FLASH) && (Adapter->uiFlashLayoutMajorVersion == 0)) | |
| 1283 | − { | |
| 1284 | − BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,"The Flash Control Section is Corrupted. Hence Rejection on NVM Read/Write\n"); | |
| 1285 | − Status = -EFAULT; | |
| 1286 | − break; | |
| 1287 | − } | |
| 1435 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n"); | |
| 1436 | + up(&Adapter->NVMRdmWrmLock); | |
| 1437 | + kfree(pReadBuff); | |
| 1438 | + return -EACCES; | |
| 1439 | + } | |
| 1288 | 1440 | |
| 1289 | − if(IsFlash2x(Adapter)) | |
| 1290 | − { | |
| 1291 | − if((Adapter->eActiveDSD != DSD0) && | |
| 1292 | − (Adapter->eActiveDSD != DSD1) && | |
| 1293 | − (Adapter->eActiveDSD != DSD2)) | |
| 1294 | − { | |
| 1295 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"No DSD is active..hence NVM Command is blocked"); | |
| 1296 | − return STATUS_FAILURE ; | |
| 1297 | − } | |
| 1298 | − } | |
| 1441 | + while (NOB) { | |
| 1442 | + if (NOB > Adapter->uiSectorSize) | |
| 1443 | + ReadBytes = Adapter->uiSectorSize; | |
| 1444 | + else | |
| 1445 | + ReadBytes = NOB; | |
| 1299 | 1446 | |
| 1300 | − /* Copy Ioctl Buffer structure */ | |
| 1447 | + /* Reading the data from Flash 2.x */ | |
| 1448 | + Status = BcmFlash2xBulkRead(Adapter, (PUINT)pReadBuff, sFlash2xRead.Section, ReadOffset, ReadBytes); | |
| 1449 | + if (Status) { | |
| 1450 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Flash 2x read err with Status :%d", Status); | |
| 1451 | + break; | |
| 1452 | + } | |
| 1301 | 1453 | |
| 1302 | − if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1303 | − return -EFAULT; | |
| 1454 | + BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, pReadBuff, ReadBytes); | |
| 1304 | 1455 | |
| 1305 | − if(copy_from_user(&stNVMReadWrite, | |
| 1306 | − (IOCTL_BCM_NVM_READ == cmd) ? IoBuffer.OutputBuffer : IoBuffer.InputBuffer, | |
| 1307 | − sizeof(NVM_READWRITE))) | |
| 1308 | − return -EFAULT; | |
| 1456 | + Status = copy_to_user(OutPutBuff, pReadBuff, ReadBytes); | |
| 1457 | + if (Status) { | |
| 1458 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Copy to use failed with status :%d", Status); | |
| 1459 | + break; | |
| 1460 | + } | |
| 1461 | + NOB = NOB - ReadBytes; | |
| 1462 | + if (NOB) { | |
| 1463 | + ReadOffset = ReadOffset + ReadBytes; | |
| 1464 | + OutPutBuff = OutPutBuff + ReadBytes ; | |
| 1465 | + } | |
| 1466 | + } | |
| 1309 | 1467 | |
| 1310 | − // | |
| 1311 | − // Deny the access if the offset crosses the cal area limit. | |
| 1312 | − // | |
| 1313 | − if((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) > Adapter->uiNVMDSDSize) | |
| 1314 | − { | |
| 1315 | − //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allow access beyond NVM Size: 0x%x 0x%x\n", stNVMReadWrite.uiOffset , | |
| 1316 | −// stNVMReadWrite.uiNumBytes); | |
| 1317 | − Status = STATUS_FAILURE; | |
| 1318 | − break; | |
| 1319 | − } | |
| 1468 | + up(&Adapter->NVMRdmWrmLock); | |
| 1469 | + kfree(pReadBuff); | |
| 1470 | + } | |
| 1471 | + break; | |
| 1472 | + | |
| 1473 | + case IOCTL_BCM_FLASH2X_SECTION_WRITE: { | |
| 1474 | + FLASH2X_READWRITE sFlash2xWrite = {0}; | |
| 1475 | + PUCHAR pWriteBuff; | |
| 1476 | + void __user *InputAddr; | |
| 1477 | + UINT NOB = 0; | |
| 1478 | + UINT BuffSize = 0; | |
| 1479 | + UINT WriteOffset = 0; | |
| 1480 | + UINT WriteBytes = 0; | |
| 1481 | + | |
| 1482 | + if (IsFlash2x(Adapter) != TRUE) { | |
| 1483 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Does not have 2.x map"); | |
| 1484 | + return -EINVAL; | |
| 1485 | + } | |
| 1320 | 1486 | |
| 1321 | − pReadData = kzalloc(stNVMReadWrite.uiNumBytes, GFP_KERNEL); | |
| 1322 | − if(!pReadData) | |
| 1323 | − return -ENOMEM; | |
| 1487 | + /* First make this False so that we can enable the Sector Permission Check in BeceemFlashBulkWrite */ | |
| 1488 | + Adapter->bAllDSDWriteAllow = FALSE; | |
| 1324 | 1489 | |
| 1325 | − if(copy_from_user(pReadData, stNVMReadWrite.pBuffer, | |
| 1326 | − stNVMReadWrite.uiNumBytes)) | |
| 1327 | − { | |
| 1328 | − Status = -EFAULT; | |
| 1329 | − kfree(pReadData); | |
| 1330 | − break; | |
| 1331 | − } | |
| 1490 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_WRITE Called"); | |
| 1332 | 1491 | |
| 1333 | − do_gettimeofday(&tv0); | |
| 1334 | − if(IOCTL_BCM_NVM_READ == cmd) | |
| 1335 | − { | |
| 1336 | − down(&Adapter->NVMRdmWrmLock); | |
| 1492 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1493 | + return -EFAULT; | |
| 1337 | 1494 | |
| 1338 | − if((Adapter->IdleMode == TRUE) || | |
| 1339 | − (Adapter->bShutStatus ==TRUE) || | |
| 1340 | − (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
| 1341 | − { | |
| 1342 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); | |
| 1343 | − up(&Adapter->NVMRdmWrmLock); | |
| 1344 | − kfree(pReadData); | |
| 1345 | − return -EACCES; | |
| 1346 | − } | |
| 1495 | + /* Reading FLASH 2.x READ structure */ | |
| 1496 | + if (copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer, sizeof(FLASH2X_READWRITE))) | |
| 1497 | + return -EFAULT; | |
| 1347 | 1498 | |
| 1348 | − Status = BeceemNVMRead(Adapter, (PUINT)pReadData, | |
| 1349 | − stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes); | |
| 1350 | − | |
| 1351 | − up(&Adapter->NVMRdmWrmLock); | |
| 1352 | − | |
| 1353 | − if(Status != STATUS_SUCCESS) | |
| 1354 | − { | |
| 1355 | − kfree(pReadData); | |
| 1356 | − return Status; | |
| 1357 | − } | |
| 1358 | − if(copy_to_user(stNVMReadWrite.pBuffer,pReadData, stNVMReadWrite.uiNumBytes)) | |
| 1359 | − { | |
| 1360 | − kfree(pReadData); | |
| 1361 | − Status = -EFAULT; | |
| 1362 | − } | |
| 1363 | − } | |
| 1364 | − else | |
| 1365 | − { | |
| 1499 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.Section :%x", sFlash2xWrite.Section); | |
| 1500 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.offset :%d", sFlash2xWrite.offset); | |
| 1501 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.numOfBytes :%x", sFlash2xWrite.numOfBytes); | |
| 1502 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.bVerify :%x\n", sFlash2xWrite.bVerify); | |
| 1366 | 1503 | |
| 1367 | − down(&Adapter->NVMRdmWrmLock); | |
| 1504 | + if ((sFlash2xWrite.Section != VSA0) && (sFlash2xWrite.Section != VSA1) && (sFlash2xWrite.Section != VSA2)) { | |
| 1505 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Only VSA write is allowed"); | |
| 1506 | + return -EINVAL; | |
| 1507 | + } | |
| 1368 | 1508 | |
| 1369 | − if((Adapter->IdleMode == TRUE) || | |
| 1370 | − (Adapter->bShutStatus ==TRUE) || | |
| 1371 | − (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
| 1372 | − { | |
| 1373 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); | |
| 1374 | − up(&Adapter->NVMRdmWrmLock); | |
| 1375 | − kfree(pReadData); | |
| 1376 | − return -EACCES; | |
| 1377 | − } | |
| 1509 | + if (validateFlash2xReadWrite(Adapter, &sFlash2xWrite) == FALSE) | |
| 1510 | + return STATUS_FAILURE; | |
| 1378 | 1511 | |
| 1379 | − Adapter->bHeaderChangeAllowed = TRUE ; | |
| 1380 | − if(IsFlash2x(Adapter)) | |
| 1381 | − { | |
| 1382 | − /* | |
| 1383 | − New Requirement:- | |
| 1384 | − DSD section updation will be allowed in two case:- | |
| 1385 | − 1. if DSD sig is present in DSD header means dongle is ok and updation is fruitfull | |
| 1386 | − 2. if point 1 failes then user buff should have DSD sig. this point ensures that if dongle is | |
| 1387 | − corrupted then user space program first modify the DSD header with valid DSD sig so | |
| 1388 | − that this as well as further write may be worthwhile. | |
| 1389 | − | |
| 1390 | − This restriction has been put assuming that if DSD sig is corrupted, DSD | |
| 1391 | − data won't be considered valid. | |
| 1392 | − | |
| 1393 | − | |
| 1394 | − */ | |
| 1395 | − Status = BcmFlash2xCorruptSig(Adapter,Adapter->eActiveDSD); | |
| 1396 | − if(Status != STATUS_SUCCESS) | |
| 1397 | − { | |
| 1398 | − if(( (stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) != Adapter->uiNVMDSDSize ) || | |
| 1399 | − (stNVMReadWrite.uiNumBytes < SIGNATURE_SIZE)) | |
| 1400 | − { | |
| 1401 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DSD Sig is present neither in Flash nor User provided Input.."); | |
| 1402 | − up(&Adapter->NVMRdmWrmLock); | |
| 1403 | − kfree(pReadData); | |
| 1404 | − return Status; | |
| 1405 | − } | |
| 1406 | − | |
| 1407 | − ulDSDMagicNumInUsrBuff = ntohl(*(PUINT)(pReadData + stNVMReadWrite.uiNumBytes - SIGNATURE_SIZE)); | |
| 1408 | − if(ulDSDMagicNumInUsrBuff != DSD_IMAGE_MAGIC_NUMBER) | |
| 1409 | − { | |
| 1410 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DSD Sig is present neither in Flash nor User provided Input.."); | |
| 1411 | − up(&Adapter->NVMRdmWrmLock); | |
| 1412 | − kfree(pReadData); | |
| 1413 | − return Status; | |
| 1414 | − } | |
| 1415 | − } | |
| 1416 | − } | |
| 1417 | − Status = BeceemNVMWrite(Adapter, (PUINT )pReadData, | |
| 1418 | − stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes, stNVMReadWrite.bVerify); | |
| 1419 | − if(IsFlash2x(Adapter)) | |
| 1420 | − BcmFlash2xWriteSig(Adapter,Adapter->eActiveDSD); | |
| 1512 | + InputAddr = sFlash2xWrite.pDataBuff; | |
| 1513 | + WriteOffset = sFlash2xWrite.offset; | |
| 1514 | + NOB = sFlash2xWrite.numOfBytes; | |
| 1421 | 1515 | |
| 1422 | − Adapter->bHeaderChangeAllowed = FALSE ; | |
| 1516 | + if (NOB > Adapter->uiSectorSize) | |
| 1517 | + BuffSize = Adapter->uiSectorSize; | |
| 1518 | + else | |
| 1519 | + BuffSize = NOB ; | |
| 1423 | 1520 | |
| 1424 | − up(&Adapter->NVMRdmWrmLock); | |
| 1521 | + pWriteBuff = kmalloc(BuffSize, GFP_KERNEL); | |
| 1425 | 1522 | |
| 1523 | + if (pWriteBuff == NULL) | |
| 1524 | + return -ENOMEM; | |
| 1426 | 1525 | |
| 1427 | − if(Status != STATUS_SUCCESS) | |
| 1428 | − { | |
| 1429 | − kfree(pReadData); | |
| 1430 | − return Status; | |
| 1431 | − } | |
| 1432 | − } | |
| 1433 | − do_gettimeofday(&tv1); | |
| 1434 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " timetaken by Write/read :%ld msec\n",(tv1.tv_sec - tv0.tv_sec)*1000 +(tv1.tv_usec - tv0.tv_usec)/1000); | |
| 1526 | + /* extracting the remainder of the given offset. */ | |
| 1527 | + WriteBytes = Adapter->uiSectorSize; | |
| 1528 | + if (WriteOffset % Adapter->uiSectorSize) | |
| 1529 | + WriteBytes = Adapter->uiSectorSize - (WriteOffset % Adapter->uiSectorSize); | |
| 1435 | 1530 | |
| 1531 | + if (NOB < WriteBytes) | |
| 1532 | + WriteBytes = NOB; | |
| 1436 | 1533 | |
| 1437 | − kfree(pReadData); | |
| 1438 | − Status = STATUS_SUCCESS; | |
| 1439 | − } | |
| 1440 | − break; | |
| 1441 | − case IOCTL_BCM_FLASH2X_SECTION_READ : | |
| 1442 | − { | |
| 1443 | − | |
| 1444 | − FLASH2X_READWRITE sFlash2xRead = {0}; | |
| 1445 | − PUCHAR pReadBuff = NULL ; | |
| 1446 | − UINT NOB = 0; | |
| 1447 | − UINT BuffSize = 0; | |
| 1448 | − UINT ReadBytes = 0; | |
| 1449 | − UINT ReadOffset = 0; | |
| 1450 | − void __user *OutPutBuff; | |
| 1451 | − | |
| 1452 | − if(IsFlash2x(Adapter) != TRUE) | |
| 1453 | − { | |
| 1454 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map"); | |
| 1455 | − return -EINVAL; | |
| 1456 | − } | |
| 1534 | + down(&Adapter->NVMRdmWrmLock); | |
| 1457 | 1535 | |
| 1458 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_READ Called"); | |
| 1459 | − if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1460 | − return -EFAULT; | |
| 1536 | + if ((Adapter->IdleMode == TRUE) || | |
| 1537 | + (Adapter->bShutStatus == TRUE) || | |
| 1538 | + (Adapter->bPreparingForLowPowerMode == TRUE)) { | |
| 1461 | 1539 | |
| 1462 | − //Reading FLASH 2.x READ structure | |
| 1463 | − if (copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer,sizeof(FLASH2X_READWRITE))) | |
| 1464 | − return -EFAULT; | |
| 1540 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n"); | |
| 1541 | + up(&Adapter->NVMRdmWrmLock); | |
| 1542 | + kfree(pWriteBuff); | |
| 1543 | + return -EACCES; | |
| 1544 | + } | |
| 1465 | 1545 | |
| 1546 | + BcmFlash2xCorruptSig(Adapter, sFlash2xWrite.Section); | |
| 1547 | + do { | |
| 1548 | + Status = copy_from_user(pWriteBuff, InputAddr, WriteBytes); | |
| 1549 | + if (Status) { | |
| 1550 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy to user failed with status :%d", Status); | |
| 1551 | + break; | |
| 1552 | + } | |
| 1553 | + BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, pWriteBuff, WriteBytes); | |
| 1466 | 1554 | |
| 1467 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.Section :%x" ,sFlash2xRead.Section); | |
| 1468 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.offset :%x" ,sFlash2xRead.offset); | |
| 1469 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.numOfBytes :%x" ,sFlash2xRead.numOfBytes); | |
| 1470 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.bVerify :%x\n" ,sFlash2xRead.bVerify); | |
| 1555 | + /* Writing the data from Flash 2.x */ | |
| 1556 | + Status = BcmFlash2xBulkWrite(Adapter, (PUINT)pWriteBuff, sFlash2xWrite.Section, WriteOffset, WriteBytes, sFlash2xWrite.bVerify); | |
| 1471 | 1557 | |
| 1472 | − //This was internal to driver for raw read. now it has ben exposed to user space app. | |
| 1473 | − if(validateFlash2xReadWrite(Adapter,&sFlash2xRead) == FALSE) | |
| 1474 | − return STATUS_FAILURE ; | |
| 1558 | + if (Status) { | |
| 1559 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash 2x read err with Status :%d", Status); | |
| 1560 | + break; | |
| 1561 | + } | |
| 1475 | 1562 | |
| 1476 | − NOB = sFlash2xRead.numOfBytes; | |
| 1477 | − if(NOB > Adapter->uiSectorSize ) | |
| 1478 | − BuffSize = Adapter->uiSectorSize; | |
| 1563 | + NOB = NOB - WriteBytes; | |
| 1564 | + if (NOB) { | |
| 1565 | + WriteOffset = WriteOffset + WriteBytes; | |
| 1566 | + InputAddr = InputAddr + WriteBytes; | |
| 1567 | + if (NOB > Adapter->uiSectorSize) | |
| 1568 | + WriteBytes = Adapter->uiSectorSize; | |
| 1479 | 1569 | else |
| 1480 | − BuffSize = NOB ; | |
| 1570 | + WriteBytes = NOB; | |
| 1571 | + } | |
| 1572 | + } while (NOB > 0); | |
| 1481 | 1573 | |
| 1482 | − ReadOffset = sFlash2xRead.offset ; | |
| 1483 | − OutPutBuff = IoBuffer.OutputBuffer; | |
| 1574 | + BcmFlash2xWriteSig(Adapter, sFlash2xWrite.Section); | |
| 1575 | + up(&Adapter->NVMRdmWrmLock); | |
| 1576 | + kfree(pWriteBuff); | |
| 1577 | + } | |
| 1578 | + break; | |
| 1484 | 1579 | |
| 1580 | + case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP: { | |
| 1581 | + PFLASH2X_BITMAP psFlash2xBitMap; | |
| 1582 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called"); | |
| 1485 | 1583 | |
| 1486 | − pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL); | |
| 1487 | − if(pReadBuff == NULL) | |
| 1488 | − { | |
| 1489 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure"); | |
| 1490 | − return -ENOMEM; | |
| 1491 | − } | |
| 1492 | − down(&Adapter->NVMRdmWrmLock); | |
| 1493 | − | |
| 1494 | − if((Adapter->IdleMode == TRUE) || | |
| 1495 | − (Adapter->bShutStatus ==TRUE) || | |
| 1496 | − (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
| 1497 | − { | |
| 1498 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); | |
| 1499 | − up(&Adapter->NVMRdmWrmLock); | |
| 1500 | − kfree(pReadBuff); | |
| 1501 | − return -EACCES; | |
| 1502 | − } | |
| 1584 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1585 | + return -EFAULT; | |
| 1503 | 1586 | |
| 1504 | − while(NOB) | |
| 1505 | − { | |
| 1587 | + if (IoBuffer.OutputLength != sizeof(FLASH2X_BITMAP)) | |
| 1588 | + return -EINVAL; | |
| 1506 | 1589 | |
| 1507 | − if(NOB > Adapter->uiSectorSize ) | |
| 1508 | − ReadBytes = Adapter->uiSectorSize; | |
| 1509 | − else | |
| 1510 | − ReadBytes = NOB; | |
| 1590 | + psFlash2xBitMap = kzalloc(sizeof(FLASH2X_BITMAP), GFP_KERNEL); | |
| 1591 | + if (psFlash2xBitMap == NULL) { | |
| 1592 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory is not available"); | |
| 1593 | + return -ENOMEM; | |
| 1594 | + } | |
| 1511 | 1595 | |
| 1596 | + /* Reading the Flash Sectio Bit map */ | |
| 1597 | + down(&Adapter->NVMRdmWrmLock); | |
| 1512 | 1598 | |
| 1513 | − //Reading the data from Flash 2.x | |
| 1599 | + if ((Adapter->IdleMode == TRUE) || | |
| 1600 | + (Adapter->bShutStatus == TRUE) || | |
| 1601 | + (Adapter->bPreparingForLowPowerMode == TRUE)) { | |
| 1514 | 1602 | |
| 1515 | − Status = BcmFlash2xBulkRead(Adapter,(PUINT)pReadBuff,sFlash2xRead.Section,ReadOffset,ReadBytes); | |
| 1516 | − if(Status) | |
| 1517 | − { | |
| 1518 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Flash 2x read err with Status :%d", Status); | |
| 1519 | − break ; | |
| 1520 | − } | |
| 1603 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n"); | |
| 1604 | + up(&Adapter->NVMRdmWrmLock); | |
| 1605 | + kfree(psFlash2xBitMap); | |
| 1606 | + return -EACCES; | |
| 1607 | + } | |
| 1521 | 1608 | |
| 1522 | − BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pReadBuff, ReadBytes); | |
| 1523 | − | |
| 1524 | − Status = copy_to_user(OutPutBuff, pReadBuff,ReadBytes); | |
| 1525 | − if(Status) | |
| 1526 | − { | |
| 1527 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Copy to use failed with status :%d", Status); | |
| 1528 | − break; | |
| 1529 | − } | |
| 1530 | − NOB = NOB - ReadBytes; | |
| 1531 | − if(NOB) | |
| 1532 | − { | |
| 1533 | − ReadOffset = ReadOffset + ReadBytes ; | |
| 1534 | − OutPutBuff = OutPutBuff + ReadBytes ; | |
| 1535 | − } | |
| 1609 | + BcmGetFlash2xSectionalBitMap(Adapter, psFlash2xBitMap); | |
| 1610 | + up(&Adapter->NVMRdmWrmLock); | |
| 1611 | + if (copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap, sizeof(FLASH2X_BITMAP))) | |
| 1612 | + Status = -EFAULT; | |
| 1536 | 1613 | |
| 1537 | − } | |
| 1538 | − up(&Adapter->NVMRdmWrmLock); | |
| 1539 | − kfree(pReadBuff); | |
| 1540 | − | |
| 1541 | − } | |
| 1542 | − break ; | |
| 1543 | − case IOCTL_BCM_FLASH2X_SECTION_WRITE : | |
| 1544 | − { | |
| 1545 | − FLASH2X_READWRITE sFlash2xWrite = {0}; | |
| 1546 | − PUCHAR pWriteBuff; | |
| 1547 | − void __user *InputAddr; | |
| 1548 | − UINT NOB = 0; | |
| 1549 | − UINT BuffSize = 0; | |
| 1550 | − UINT WriteOffset = 0; | |
| 1551 | − UINT WriteBytes = 0; | |
| 1552 | − | |
| 1553 | − if(IsFlash2x(Adapter) != TRUE) | |
| 1554 | − { | |
| 1555 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map"); | |
| 1556 | − return -EINVAL; | |
| 1557 | − } | |
| 1614 | + kfree(psFlash2xBitMap); | |
| 1615 | + } | |
| 1616 | + break; | |
| 1558 | 1617 | |
| 1559 | − //First make this False so that we can enable the Sector Permission Check in BeceemFlashBulkWrite | |
| 1560 | − Adapter->bAllDSDWriteAllow = FALSE; | |
| 1618 | + case IOCTL_BCM_SET_ACTIVE_SECTION: { | |
| 1619 | + FLASH2X_SECTION_VAL eFlash2xSectionVal = 0; | |
| 1620 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SET_ACTIVE_SECTION Called"); | |
| 1561 | 1621 | |
| 1622 | + if (IsFlash2x(Adapter) != TRUE) { | |
| 1623 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Does not have 2.x map"); | |
| 1624 | + return -EINVAL; | |
| 1625 | + } | |
| 1562 | 1626 | |
| 1563 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_FLASH2X_SECTION_WRITE Called"); | |
| 1564 | − if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1565 | − return -EFAULT; | |
| 1627 | + Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); | |
| 1628 | + if (Status) { | |
| 1629 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); | |
| 1630 | + return Status; | |
| 1631 | + } | |
| 1566 | 1632 | |
| 1567 | − //Reading FLASH 2.x READ structure | |
| 1568 | − if (copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer, sizeof(FLASH2X_READWRITE))) | |
| 1569 | − return -EFAULT; | |
| 1633 | + Status = copy_from_user(&eFlash2xSectionVal, IoBuffer.InputBuffer, sizeof(INT)); | |
| 1634 | + if (Status) { | |
| 1635 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed"); | |
| 1636 | + return Status; | |
| 1637 | + } | |
| 1570 | 1638 | |
| 1571 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.Section :%x" ,sFlash2xWrite.Section); | |
| 1572 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.offset :%d" ,sFlash2xWrite.offset); | |
| 1573 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.numOfBytes :%x" ,sFlash2xWrite.numOfBytes); | |
| 1574 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.bVerify :%x\n" ,sFlash2xWrite.bVerify); | |
| 1575 | − if((sFlash2xWrite.Section != VSA0) && (sFlash2xWrite.Section != VSA1) && | |
| 1576 | − (sFlash2xWrite.Section != VSA2) ) | |
| 1577 | − { | |
| 1578 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Only VSA write is allowed"); | |
| 1579 | − return -EINVAL; | |
| 1580 | − } | |
| 1639 | + down(&Adapter->NVMRdmWrmLock); | |
| 1581 | 1640 | |
| 1582 | − if(validateFlash2xReadWrite(Adapter,&sFlash2xWrite) == FALSE) | |
| 1583 | − return STATUS_FAILURE ; | |
| 1641 | + if ((Adapter->IdleMode == TRUE) || | |
| 1642 | + (Adapter->bShutStatus == TRUE) || | |
| 1643 | + (Adapter->bPreparingForLowPowerMode == TRUE)) { | |
| 1584 | 1644 | |
| 1585 | − InputAddr = sFlash2xWrite.pDataBuff; | |
| 1586 | − WriteOffset = sFlash2xWrite.offset ; | |
| 1587 | − NOB = sFlash2xWrite.numOfBytes; | |
| 1645 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n"); | |
| 1646 | + up(&Adapter->NVMRdmWrmLock); | |
| 1647 | + return -EACCES; | |
| 1648 | + } | |
| 1588 | 1649 | |
| 1589 | − if(NOB > Adapter->uiSectorSize ) | |
| 1590 | − BuffSize = Adapter->uiSectorSize; | |
| 1591 | − else | |
| 1592 | − BuffSize = NOB ; | |
| 1650 | + Status = BcmSetActiveSection(Adapter, eFlash2xSectionVal); | |
| 1651 | + if (Status) | |
| 1652 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Failed to make it's priority Highest. Status %d", Status); | |
| 1593 | 1653 | |
| 1594 | − pWriteBuff = kmalloc(BuffSize, GFP_KERNEL); | |
| 1595 | − if(pWriteBuff == NULL) | |
| 1596 | − return -ENOMEM; | |
| 1654 | + up(&Adapter->NVMRdmWrmLock); | |
| 1655 | + } | |
| 1656 | + break; | |
| 1597 | 1657 | |
| 1658 | + case IOCTL_BCM_IDENTIFY_ACTIVE_SECTION: { | |
| 1659 | + /* Right Now we are taking care of only DSD */ | |
| 1660 | + Adapter->bAllDSDWriteAllow = FALSE; | |
| 1661 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_IDENTIFY_ACTIVE_SECTION called"); | |
| 1662 | + Status = STATUS_SUCCESS; | |
| 1663 | + } | |
| 1664 | + break; | |
| 1598 | 1665 | |
| 1599 | − //extracting the remainder of the given offset. | |
| 1600 | − WriteBytes = Adapter->uiSectorSize ; | |
| 1601 | − if(WriteOffset % Adapter->uiSectorSize) | |
| 1602 | − WriteBytes =Adapter->uiSectorSize - (WriteOffset % Adapter->uiSectorSize); | |
| 1603 | − if(NOB < WriteBytes) | |
| 1604 | − WriteBytes = NOB; | |
| 1666 | + case IOCTL_BCM_COPY_SECTION: { | |
| 1667 | + FLASH2X_COPY_SECTION sCopySectStrut = {0}; | |
| 1668 | + Status = STATUS_SUCCESS; | |
| 1669 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_COPY_SECTION Called"); | |
| 1605 | 1670 | |
| 1606 | − down(&Adapter->NVMRdmWrmLock); | |
| 1671 | + Adapter->bAllDSDWriteAllow = FALSE; | |
| 1672 | + if (IsFlash2x(Adapter) != TRUE) { | |
| 1673 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Does not have 2.x map"); | |
| 1674 | + return -EINVAL; | |
| 1675 | + } | |
| 1607 | 1676 | |
| 1608 | − if((Adapter->IdleMode == TRUE) || | |
| 1609 | − (Adapter->bShutStatus ==TRUE) || | |
| 1610 | − (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
| 1611 | − { | |
| 1612 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); | |
| 1613 | − up(&Adapter->NVMRdmWrmLock); | |
| 1614 | − kfree(pWriteBuff); | |
| 1615 | − return -EACCES; | |
| 1616 | − } | |
| 1677 | + Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); | |
| 1678 | + if (Status) { | |
| 1679 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed Status :%d", Status); | |
| 1680 | + return Status; | |
| 1681 | + } | |
| 1617 | 1682 | |
| 1618 | − BcmFlash2xCorruptSig(Adapter,sFlash2xWrite.Section); | |
| 1619 | − do | |
| 1620 | − { | |
| 1621 | − Status = copy_from_user(pWriteBuff,InputAddr,WriteBytes); | |
| 1622 | − if(Status) | |
| 1623 | − { | |
| 1624 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy to user failed with status :%d", Status); | |
| 1625 | − break ; | |
| 1626 | − } | |
| 1627 | − BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pWriteBuff,WriteBytes); | |
| 1628 | − //Writing the data from Flash 2.x | |
| 1629 | − Status = BcmFlash2xBulkWrite(Adapter,(PUINT)pWriteBuff,sFlash2xWrite.Section,WriteOffset,WriteBytes,sFlash2xWrite.bVerify); | |
| 1630 | − | |
| 1631 | − if(Status) | |
| 1632 | − { | |
| 1633 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash 2x read err with Status :%d", Status); | |
| 1634 | − break ; | |
| 1635 | − } | |
| 1683 | + Status = copy_from_user(&sCopySectStrut, IoBuffer.InputBuffer, sizeof(FLASH2X_COPY_SECTION)); | |
| 1684 | + if (Status) { | |
| 1685 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of Copy_Section_Struct failed with Status :%d", Status); | |
| 1686 | + return Status; | |
| 1687 | + } | |
| 1636 | 1688 | |
| 1637 | − NOB = NOB - WriteBytes; | |
| 1638 | − if(NOB) | |
| 1639 | − { | |
| 1640 | − WriteOffset = WriteOffset + WriteBytes ; | |
| 1641 | − InputAddr = InputAddr + WriteBytes ; | |
| 1642 | − if(NOB > Adapter->uiSectorSize ) | |
| 1643 | − WriteBytes = Adapter->uiSectorSize; | |
| 1644 | − else | |
| 1645 | − WriteBytes = NOB; | |
| 1646 | − } | |
| 1689 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Source SEction :%x", sCopySectStrut.SrcSection); | |
| 1690 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Destination SEction :%x", sCopySectStrut.DstSection); | |
| 1691 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "offset :%x", sCopySectStrut.offset); | |
| 1692 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "NOB :%x", sCopySectStrut.numOfBytes); | |
| 1647 | 1693 | |
| 1694 | + if (IsSectionExistInFlash(Adapter, sCopySectStrut.SrcSection) == FALSE) { | |
| 1695 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source Section<%x> does not exixt in Flash ", sCopySectStrut.SrcSection); | |
| 1696 | + return -EINVAL; | |
| 1697 | + } | |
| 1648 | 1698 | |
| 1649 | − } while(NOB > 0); | |
| 1650 | − BcmFlash2xWriteSig(Adapter,sFlash2xWrite.Section); | |
| 1651 | − up(&Adapter->NVMRdmWrmLock); | |
| 1652 | − kfree(pWriteBuff); | |
| 1653 | − } | |
| 1654 | − break ; | |
| 1655 | − case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP : | |
| 1656 | − { | |
| 1699 | + if (IsSectionExistInFlash(Adapter, sCopySectStrut.DstSection) == FALSE) { | |
| 1700 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Destinatio Section<%x> does not exixt in Flash ", sCopySectStrut.DstSection); | |
| 1701 | + return -EINVAL; | |
| 1702 | + } | |
| 1657 | 1703 | |
| 1658 | − PFLASH2X_BITMAP psFlash2xBitMap; | |
| 1659 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called"); | |
| 1704 | + if (sCopySectStrut.SrcSection == sCopySectStrut.DstSection) { | |
| 1705 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Source and Destination section should be different"); | |
| 1706 | + return -EINVAL; | |
| 1707 | + } | |
| 1660 | 1708 | |
| 1661 | − if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1662 | − return -EFAULT; | |
| 1709 | + down(&Adapter->NVMRdmWrmLock); | |
| 1663 | 1710 | |
| 1664 | − if(IoBuffer.OutputLength != sizeof(FLASH2X_BITMAP)) | |
| 1665 | − return -EINVAL; | |
| 1711 | + if ((Adapter->IdleMode == TRUE) || | |
| 1712 | + (Adapter->bShutStatus == TRUE) || | |
| 1713 | + (Adapter->bPreparingForLowPowerMode == TRUE)) { | |
| 1666 | 1714 | |
| 1667 | − psFlash2xBitMap = kzalloc(sizeof(FLASH2X_BITMAP), GFP_KERNEL); | |
| 1668 | − if(psFlash2xBitMap == NULL) | |
| 1669 | − { | |
| 1670 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory is not available"); | |
| 1671 | − return -ENOMEM ; | |
| 1672 | − } | |
| 1673 | − //Reading the Flash Sectio Bit map | |
| 1674 | − down(&Adapter->NVMRdmWrmLock); | |
| 1675 | − | |
| 1676 | − if((Adapter->IdleMode == TRUE) || | |
| 1677 | − (Adapter->bShutStatus ==TRUE) || | |
| 1678 | − (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
| 1679 | − { | |
| 1680 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); | |
| 1681 | − up(&Adapter->NVMRdmWrmLock); | |
| 1682 | − kfree(psFlash2xBitMap); | |
| 1683 | − return -EACCES; | |
| 1684 | − } | |
| 1715 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n"); | |
| 1716 | + up(&Adapter->NVMRdmWrmLock); | |
| 1717 | + return -EACCES; | |
| 1718 | + } | |
| 1685 | 1719 | |
| 1686 | − BcmGetFlash2xSectionalBitMap(Adapter, psFlash2xBitMap); | |
| 1687 | − up(&Adapter->NVMRdmWrmLock); | |
| 1688 | − if (copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap, sizeof(FLASH2X_BITMAP))) | |
| 1689 | − Status = -EFAULT; | |
| 1690 | − | |
| 1691 | − kfree(psFlash2xBitMap); | |
| 1692 | − } | |
| 1693 | − break ; | |
| 1694 | − case IOCTL_BCM_SET_ACTIVE_SECTION : | |
| 1695 | − { | |
| 1696 | − FLASH2X_SECTION_VAL eFlash2xSectionVal = 0; | |
| 1697 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SET_ACTIVE_SECTION Called"); | |
| 1698 | − | |
| 1699 | − if(IsFlash2x(Adapter) != TRUE) | |
| 1700 | − { | |
| 1701 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map"); | |
| 1702 | − return -EINVAL; | |
| 1703 | − } | |
| 1720 | + if (sCopySectStrut.SrcSection == ISO_IMAGE1 || sCopySectStrut.SrcSection == ISO_IMAGE2) { | |
| 1721 | + if (IsNonCDLessDevice(Adapter)) { | |
| 1722 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device is Non-CDLess hence won't have ISO !!"); | |
| 1723 | + Status = -EINVAL; | |
| 1724 | + } else if (sCopySectStrut.numOfBytes == 0) { | |
| 1725 | + Status = BcmCopyISO(Adapter, sCopySectStrut); | |
| 1726 | + } else { | |
| 1727 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Partial Copy of ISO section is not Allowed.."); | |
| 1728 | + Status = STATUS_FAILURE; | |
| 1729 | + } | |
| 1730 | + up(&Adapter->NVMRdmWrmLock); | |
| 1731 | + return Status; | |
| 1732 | + } | |
| 1704 | 1733 | |
| 1705 | − Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); | |
| 1706 | − if(Status) | |
| 1707 | − { | |
| 1708 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); | |
| 1709 | − return Status; | |
| 1710 | − } | |
| 1734 | + Status = BcmCopySection(Adapter, sCopySectStrut.SrcSection, | |
| 1735 | + sCopySectStrut.DstSection, sCopySectStrut.offset, sCopySectStrut.numOfBytes); | |
| 1736 | + up(&Adapter->NVMRdmWrmLock); | |
| 1737 | + } | |
| 1738 | + break; | |
| 1711 | 1739 | |
| 1712 | − Status = copy_from_user(&eFlash2xSectionVal,IoBuffer.InputBuffer, sizeof(INT)); | |
| 1713 | − if(Status) | |
| 1714 | − { | |
| 1715 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed"); | |
| 1716 | − return Status; | |
| 1717 | − } | |
| 1740 | + case IOCTL_BCM_GET_FLASH_CS_INFO: { | |
| 1741 | + Status = STATUS_SUCCESS; | |
| 1742 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_GET_FLASH_CS_INFO Called"); | |
| 1718 | 1743 | |
| 1719 | − down(&Adapter->NVMRdmWrmLock); | |
| 1744 | + Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); | |
| 1745 | + if (Status) { | |
| 1746 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); | |
| 1747 | + break; | |
| 1748 | + } | |
| 1720 | 1749 | |
| 1721 | − if((Adapter->IdleMode == TRUE) || | |
| 1722 | − (Adapter->bShutStatus ==TRUE) || | |
| 1723 | − (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
| 1724 | − { | |
| 1725 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); | |
| 1726 | − up(&Adapter->NVMRdmWrmLock); | |
| 1727 | − return -EACCES; | |
| 1728 | − } | |
| 1750 | + if (Adapter->eNVMType != NVM_FLASH) { | |
| 1751 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Connected device does not have flash"); | |
| 1752 | + Status = -EINVAL; | |
| 1753 | + break; | |
| 1754 | + } | |
| 1729 | 1755 | |
| 1730 | − Status = BcmSetActiveSection(Adapter,eFlash2xSectionVal); | |
| 1731 | − if(Status) | |
| 1732 | − { | |
| 1733 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed to make it's priority Highest. Status %d", Status); | |
| 1734 | − } | |
| 1735 | − up(&Adapter->NVMRdmWrmLock); | |
| 1736 | − } | |
| 1737 | − break ; | |
| 1738 | − case IOCTL_BCM_IDENTIFY_ACTIVE_SECTION : | |
| 1739 | − { | |
| 1740 | − //Right Now we are taking care of only DSD | |
| 1741 | − Adapter->bAllDSDWriteAllow = FALSE ; | |
| 1742 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_BCM_IDENTIFY_ACTIVE_SECTION called"); | |
| 1743 | − | |
| 1744 | − Status = STATUS_SUCCESS ; | |
| 1745 | − } | |
| 1746 | − break ; | |
| 1747 | − case IOCTL_BCM_COPY_SECTION : | |
| 1748 | − { | |
| 1749 | − FLASH2X_COPY_SECTION sCopySectStrut = {0}; | |
| 1750 | − Status = STATUS_SUCCESS; | |
| 1751 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_COPY_SECTION Called"); | |
| 1752 | − | |
| 1753 | − Adapter->bAllDSDWriteAllow = FALSE ; | |
| 1754 | − if(IsFlash2x(Adapter) != TRUE) | |
| 1755 | − { | |
| 1756 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map"); | |
| 1757 | − return -EINVAL; | |
| 1758 | − } | |
| 1756 | + if (IsFlash2x(Adapter) == TRUE) { | |
| 1757 | + if (IoBuffer.OutputLength < sizeof(FLASH2X_CS_INFO)) | |
| 1758 | + return -EINVAL; | |
| 1759 | 1759 | |
| 1760 | − Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); | |
| 1761 | − if(Status) | |
| 1762 | − { | |
| 1763 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed Status :%d", Status); | |
| 1764 | − return Status; | |
| 1765 | − } | |
| 1760 | + if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlash2xCSInfo, sizeof(FLASH2X_CS_INFO))) | |
| 1761 | + return -EFAULT; | |
| 1762 | + } else { | |
| 1763 | + if (IoBuffer.OutputLength < sizeof(FLASH_CS_INFO)) | |
| 1764 | + return -EINVAL; | |
| 1766 | 1765 | |
| 1767 | − Status = copy_from_user(&sCopySectStrut, IoBuffer.InputBuffer, sizeof(FLASH2X_COPY_SECTION)); | |
| 1768 | − if(Status) | |
| 1769 | − { | |
| 1770 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of Copy_Section_Struct failed with Status :%d", Status); | |
| 1771 | − return Status; | |
| 1772 | − } | |
| 1773 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Source SEction :%x", sCopySectStrut.SrcSection); | |
| 1774 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Destination SEction :%x", sCopySectStrut.DstSection); | |
| 1775 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "offset :%x", sCopySectStrut.offset); | |
| 1776 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "NOB :%x", sCopySectStrut.numOfBytes); | |
| 1766 | + if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlashCSInfo, sizeof(FLASH_CS_INFO))) | |
| 1767 | + return -EFAULT; | |
| 1768 | + } | |
| 1769 | + } | |
| 1770 | + break; | |
| 1777 | 1771 | |
| 1772 | + case IOCTL_BCM_SELECT_DSD: { | |
| 1773 | + UINT SectOfset = 0; | |
| 1774 | + FLASH2X_SECTION_VAL eFlash2xSectionVal; | |
| 1775 | + eFlash2xSectionVal = NO_SECTION_VAL; | |
| 1776 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SELECT_DSD Called"); | |
| 1778 | 1777 | |
| 1779 | − if(IsSectionExistInFlash(Adapter,sCopySectStrut.SrcSection) == FALSE) | |
| 1780 | − { | |
| 1781 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source Section<%x> does not exixt in Flash ", sCopySectStrut.SrcSection); | |
| 1782 | − return -EINVAL; | |
| 1783 | − } | |
| 1778 | + if (IsFlash2x(Adapter) != TRUE) { | |
| 1779 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Does not have 2.x map"); | |
| 1780 | + return -EINVAL; | |
| 1781 | + } | |
| 1784 | 1782 | |
| 1785 | − if(IsSectionExistInFlash(Adapter,sCopySectStrut.DstSection) == FALSE) | |
| 1786 | − { | |
| 1787 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Destinatio Section<%x> does not exixt in Flash ", sCopySectStrut.DstSection); | |
| 1788 | − return -EINVAL; | |
| 1789 | − } | |
| 1783 | + Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); | |
| 1784 | + if (Status) { | |
| 1785 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); | |
| 1786 | + return Status; | |
| 1787 | + } | |
| 1788 | + Status = copy_from_user(&eFlash2xSectionVal, IoBuffer.InputBuffer, sizeof(INT)); | |
| 1789 | + if (Status) { | |
| 1790 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed"); | |
| 1791 | + return Status; | |
| 1792 | + } | |
| 1790 | 1793 | |
| 1791 | − if(sCopySectStrut.SrcSection == sCopySectStrut.DstSection) | |
| 1792 | − { | |
| 1793 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Source and Destination section should be different"); | |
| 1794 | − return -EINVAL; | |
| 1795 | − } | |
| 1794 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Read Section :%d", eFlash2xSectionVal); | |
| 1795 | + if ((eFlash2xSectionVal != DSD0) && | |
| 1796 | + (eFlash2xSectionVal != DSD1) && | |
| 1797 | + (eFlash2xSectionVal != DSD2)) { | |
| 1796 | 1798 | |
| 1797 | − down(&Adapter->NVMRdmWrmLock); | |
| 1799 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Passed section<%x> is not DSD section", eFlash2xSectionVal); | |
| 1800 | + return STATUS_FAILURE; | |
| 1801 | + } | |
| 1798 | 1802 | |
| 1799 | − if((Adapter->IdleMode == TRUE) || | |
| 1800 | − (Adapter->bShutStatus ==TRUE) || | |
| 1801 | − (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
| 1802 | − { | |
| 1803 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); | |
| 1804 | − up(&Adapter->NVMRdmWrmLock); | |
| 1805 | − return -EACCES; | |
| 1806 | − } | |
| 1803 | + SectOfset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal); | |
| 1804 | + if (SectOfset == INVALID_OFFSET) { | |
| 1805 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Provided Section val <%d> does not exixt in Flash 2.x", eFlash2xSectionVal); | |
| 1806 | + return -EINVAL; | |
| 1807 | + } | |
| 1807 | 1808 | |
| 1808 | − if(sCopySectStrut.SrcSection == ISO_IMAGE1 || sCopySectStrut.SrcSection == ISO_IMAGE2) | |
| 1809 | − { | |
| 1810 | − if(IsNonCDLessDevice(Adapter)) | |
| 1811 | − { | |
| 1812 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is Non-CDLess hence won't have ISO !!"); | |
| 1813 | − Status = -EINVAL ; | |
| 1814 | − } | |
| 1815 | − else if(sCopySectStrut.numOfBytes == 0) | |
| 1816 | − { | |
| 1817 | − Status = BcmCopyISO(Adapter,sCopySectStrut); | |
| 1818 | − } | |
| 1819 | − else | |
| 1820 | − { | |
| 1821 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Partial Copy of ISO section is not Allowed.."); | |
| 1822 | − Status = STATUS_FAILURE ; | |
| 1823 | − } | |
| 1824 | − up(&Adapter->NVMRdmWrmLock); | |
| 1825 | − return Status; | |
| 1826 | − } | |
| 1809 | + Adapter->bAllDSDWriteAllow = TRUE; | |
| 1810 | + Adapter->ulFlashCalStart = SectOfset; | |
| 1811 | + Adapter->eActiveDSD = eFlash2xSectionVal; | |
| 1812 | + } | |
| 1813 | + Status = STATUS_SUCCESS; | |
| 1814 | + break; | |
| 1815 | + | |
| 1816 | + case IOCTL_BCM_NVM_RAW_READ: { | |
| 1817 | + NVM_READWRITE stNVMRead; | |
| 1818 | + INT NOB ; | |
| 1819 | + INT BuffSize ; | |
| 1820 | + INT ReadOffset = 0; | |
| 1821 | + UINT ReadBytes = 0 ; | |
| 1822 | + PUCHAR pReadBuff; | |
| 1823 | + void __user *OutPutBuff; | |
| 1824 | + | |
| 1825 | + if (Adapter->eNVMType != NVM_FLASH) { | |
| 1826 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "NVM TYPE is not Flash"); | |
| 1827 | + return -EINVAL; | |
| 1828 | + } | |
| 1827 | 1829 | |
| 1828 | − Status = BcmCopySection(Adapter, sCopySectStrut.SrcSection, | |
| 1829 | − sCopySectStrut.DstSection,sCopySectStrut.offset,sCopySectStrut.numOfBytes); | |
| 1830 | − up(&Adapter->NVMRdmWrmLock); | |
| 1831 | − } | |
| 1832 | − break ; | |
| 1833 | − case IOCTL_BCM_GET_FLASH_CS_INFO : | |
| 1834 | − { | |
| 1835 | − Status = STATUS_SUCCESS; | |
| 1836 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_GET_FLASH_CS_INFO Called"); | |
| 1837 | − | |
| 1838 | − Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); | |
| 1839 | − if(Status) | |
| 1840 | − { | |
| 1841 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); | |
| 1842 | − break; | |
| 1843 | − } | |
| 1844 | − if(Adapter->eNVMType != NVM_FLASH) | |
| 1845 | − { | |
| 1846 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Connected device does not have flash"); | |
| 1847 | − Status = -EINVAL; | |
| 1848 | − break; | |
| 1849 | − } | |
| 1850 | − if(IsFlash2x(Adapter) == TRUE) | |
| 1851 | − { | |
| 1830 | + /* Copy Ioctl Buffer structure */ | |
| 1831 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) { | |
| 1832 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "copy_from_user 1 failed\n"); | |
| 1833 | + Status = -EFAULT; | |
| 1834 | + break; | |
| 1835 | + } | |
| 1852 | 1836 | |
| 1853 | − if(IoBuffer.OutputLength < sizeof(FLASH2X_CS_INFO)) | |
| 1854 | − return -EINVAL; | |
| 1837 | + if (copy_from_user(&stNVMRead, IoBuffer.OutputBuffer, sizeof(NVM_READWRITE))) | |
| 1838 | + return -EFAULT; | |
| 1855 | 1839 | |
| 1856 | − if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlash2xCSInfo, sizeof(FLASH2X_CS_INFO))) | |
| 1857 | − return -EFAULT; | |
| 1858 | − } | |
| 1859 | − else | |
| 1860 | − { | |
| 1861 | − if(IoBuffer.OutputLength < sizeof(FLASH_CS_INFO)) | |
| 1862 | − return -EINVAL; | |
| 1840 | + NOB = stNVMRead.uiNumBytes; | |
| 1841 | + /* In Raw-Read max Buff size : 64MB */ | |
| 1863 | 1842 | |
| 1864 | − if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlashCSInfo, sizeof(FLASH_CS_INFO))) | |
| 1865 | − return -EFAULT; | |
| 1843 | + if (NOB > DEFAULT_BUFF_SIZE) | |
| 1844 | + BuffSize = DEFAULT_BUFF_SIZE; | |
| 1845 | + else | |
| 1846 | + BuffSize = NOB; | |
| 1866 | 1847 | |
| 1867 | − } | |
| 1868 | − } | |
| 1869 | − break ; | |
| 1870 | − case IOCTL_BCM_SELECT_DSD : | |
| 1871 | − { | |
| 1872 | − UINT SectOfset = 0; | |
| 1873 | − FLASH2X_SECTION_VAL eFlash2xSectionVal; | |
| 1874 | − eFlash2xSectionVal = NO_SECTION_VAL ; | |
| 1875 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_SELECT_DSD Called"); | |
| 1876 | − | |
| 1877 | − if(IsFlash2x(Adapter) != TRUE) | |
| 1878 | − { | |
| 1879 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map"); | |
| 1880 | − return -EINVAL; | |
| 1881 | − } | |
| 1848 | + ReadOffset = stNVMRead.uiOffset; | |
| 1849 | + OutPutBuff = stNVMRead.pBuffer; | |
| 1882 | 1850 | |
| 1883 | − Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); | |
| 1884 | − if(Status) | |
| 1885 | − { | |
| 1886 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); | |
| 1887 | − return Status; | |
| 1888 | − } | |
| 1889 | − Status = copy_from_user(&eFlash2xSectionVal, IoBuffer.InputBuffer, sizeof(INT)); | |
| 1890 | − if(Status) | |
| 1891 | − { | |
| 1892 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed"); | |
| 1893 | − return Status; | |
| 1894 | − } | |
| 1851 | + pReadBuff = kzalloc(BuffSize , GFP_KERNEL); | |
| 1852 | + if (pReadBuff == NULL) { | |
| 1853 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed for Flash 2.x Read Structure"); | |
| 1854 | + Status = -ENOMEM; | |
| 1855 | + break; | |
| 1856 | + } | |
| 1857 | + down(&Adapter->NVMRdmWrmLock); | |
| 1895 | 1858 | |
| 1896 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Read Section :%d", eFlash2xSectionVal); | |
| 1897 | − if((eFlash2xSectionVal != DSD0) && | |
| 1898 | − (eFlash2xSectionVal != DSD1) && | |
| 1899 | − (eFlash2xSectionVal != DSD2) ) | |
| 1900 | − { | |
| 1901 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Passed section<%x> is not DSD section", eFlash2xSectionVal); | |
| 1902 | − return STATUS_FAILURE ; | |
| 1903 | − } | |
| 1859 | + if ((Adapter->IdleMode == TRUE) || | |
| 1860 | + (Adapter->bShutStatus == TRUE) || | |
| 1861 | + (Adapter->bPreparingForLowPowerMode == TRUE)) { | |
| 1904 | 1862 | |
| 1905 | − SectOfset= BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal); | |
| 1906 | − if(SectOfset == INVALID_OFFSET) | |
| 1907 | − { | |
| 1908 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Provided Section val <%d> does not exixt in Flash 2.x", eFlash2xSectionVal); | |
| 1909 | − return -EINVAL; | |
| 1910 | − } | |
| 1863 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n"); | |
| 1864 | + kfree(pReadBuff); | |
| 1865 | + up(&Adapter->NVMRdmWrmLock); | |
| 1866 | + return -EACCES; | |
| 1867 | + } | |
| 1911 | 1868 | |
| 1912 | − Adapter->bAllDSDWriteAllow = TRUE ; | |
| 1913 | − | |
| 1914 | − Adapter->ulFlashCalStart = SectOfset ; | |
| 1915 | − Adapter->eActiveDSD = eFlash2xSectionVal; | |
| 1916 | − } | |
| 1917 | − Status = STATUS_SUCCESS ; | |
| 1918 | − break; | |
| 1919 | − | |
| 1920 | − case IOCTL_BCM_NVM_RAW_READ : | |
| 1921 | − { | |
| 1922 | − | |
| 1923 | − NVM_READWRITE stNVMRead; | |
| 1924 | − INT NOB ; | |
| 1925 | − INT BuffSize ; | |
| 1926 | − INT ReadOffset = 0; | |
| 1927 | − UINT ReadBytes = 0 ; | |
| 1928 | − PUCHAR pReadBuff; | |
| 1929 | − void __user *OutPutBuff; | |
| 1930 | − | |
| 1931 | − if(Adapter->eNVMType != NVM_FLASH) | |
| 1932 | − { | |
| 1933 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"NVM TYPE is not Flash "); | |
| 1934 | − return -EINVAL ; | |
| 1935 | − } | |
| 1869 | + Adapter->bFlashRawRead = TRUE; | |
| 1936 | 1870 | |
| 1937 | − /* Copy Ioctl Buffer structure */ | |
| 1938 | − if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1939 | − { | |
| 1940 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user 1 failed\n"); | |
| 1941 | − Status = -EFAULT; | |
| 1942 | − break; | |
| 1943 | − } | |
| 1871 | + while (NOB) { | |
| 1872 | + if (NOB > DEFAULT_BUFF_SIZE) | |
| 1873 | + ReadBytes = DEFAULT_BUFF_SIZE; | |
| 1874 | + else | |
| 1875 | + ReadBytes = NOB; | |
| 1944 | 1876 | |
| 1945 | − if(copy_from_user(&stNVMRead, IoBuffer.OutputBuffer,sizeof(NVM_READWRITE))) | |
| 1946 | − return -EFAULT; | |
| 1877 | + /* Reading the data from Flash 2.x */ | |
| 1878 | + Status = BeceemNVMRead(Adapter, (PUINT)pReadBuff, ReadOffset, ReadBytes); | |
| 1879 | + if (Status) { | |
| 1880 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash 2x read err with Status :%d", Status); | |
| 1881 | + break; | |
| 1882 | + } | |
| 1947 | 1883 | |
| 1948 | − NOB = stNVMRead.uiNumBytes; | |
| 1949 | − //In Raw-Read max Buff size : 64MB | |
| 1884 | + BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, pReadBuff, ReadBytes); | |
| 1950 | 1885 | |
| 1951 | − if(NOB > DEFAULT_BUFF_SIZE) | |
| 1952 | − BuffSize = DEFAULT_BUFF_SIZE; | |
| 1953 | − else | |
| 1954 | − BuffSize = NOB ; | |
| 1886 | + Status = copy_to_user(OutPutBuff, pReadBuff, ReadBytes); | |
| 1887 | + if (Status) { | |
| 1888 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy to use failed with status :%d", Status); | |
| 1889 | + break; | |
| 1890 | + } | |
| 1891 | + NOB = NOB - ReadBytes; | |
| 1892 | + if (NOB) { | |
| 1893 | + ReadOffset = ReadOffset + ReadBytes; | |
| 1894 | + OutPutBuff = OutPutBuff + ReadBytes; | |
| 1895 | + } | |
| 1896 | + } | |
| 1897 | + Adapter->bFlashRawRead = FALSE; | |
| 1898 | + up(&Adapter->NVMRdmWrmLock); | |
| 1899 | + kfree(pReadBuff); | |
| 1900 | + break; | |
| 1901 | + } | |
| 1955 | 1902 | |
| 1956 | − ReadOffset = stNVMRead.uiOffset; | |
| 1957 | − OutPutBuff = stNVMRead.pBuffer; | |
| 1903 | + case IOCTL_BCM_CNTRLMSG_MASK: { | |
| 1904 | + ULONG RxCntrlMsgBitMask = 0; | |
| 1958 | 1905 | |
| 1959 | − pReadBuff = kzalloc(BuffSize , GFP_KERNEL); | |
| 1960 | − if(pReadBuff == NULL) | |
| 1961 | − { | |
| 1962 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure"); | |
| 1963 | − Status = -ENOMEM; | |
| 1964 | − break; | |
| 1965 | − } | |
| 1966 | − down(&Adapter->NVMRdmWrmLock); | |
| 1967 | − | |
| 1968 | − if((Adapter->IdleMode == TRUE) || | |
| 1969 | − (Adapter->bShutStatus ==TRUE) || | |
| 1970 | − (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
| 1971 | − { | |
| 1972 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); | |
| 1973 | − kfree(pReadBuff); | |
| 1974 | − up(&Adapter->NVMRdmWrmLock); | |
| 1975 | − return -EACCES; | |
| 1976 | − } | |
| 1906 | + /* Copy Ioctl Buffer structure */ | |
| 1907 | + Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); | |
| 1908 | + if (Status) { | |
| 1909 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "copy of Ioctl buffer is failed from user space"); | |
| 1910 | + Status = -EFAULT; | |
| 1911 | + break; | |
| 1912 | + } | |
| 1977 | 1913 | |
| 1978 | − Adapter->bFlashRawRead = TRUE ; | |
| 1979 | − while(NOB) | |
| 1980 | − { | |
| 1981 | − if(NOB > DEFAULT_BUFF_SIZE ) | |
| 1982 | − ReadBytes = DEFAULT_BUFF_SIZE; | |
| 1983 | − else | |
| 1984 | − ReadBytes = NOB; | |
| 1985 | − | |
| 1986 | − //Reading the data from Flash 2.x | |
| 1987 | − Status = BeceemNVMRead(Adapter,(PUINT)pReadBuff,ReadOffset,ReadBytes); | |
| 1988 | − if(Status) | |
| 1989 | − { | |
| 1990 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash 2x read err with Status :%d", Status); | |
| 1991 | − break; | |
| 1992 | − } | |
| 1914 | + if (IoBuffer.InputLength != sizeof(unsigned long)) { | |
| 1915 | + Status = -EINVAL; | |
| 1916 | + break; | |
| 1917 | + } | |
| 1993 | 1918 | |
| 1994 | − BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pReadBuff,ReadBytes); | |
| 1995 | − | |
| 1996 | − Status = copy_to_user(OutPutBuff, pReadBuff,ReadBytes); | |
| 1997 | − if(Status) | |
| 1998 | − { | |
| 1999 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy to use failed with status :%d", Status); | |
| 2000 | − break; | |
| 2001 | − } | |
| 2002 | − NOB = NOB - ReadBytes; | |
| 2003 | − if(NOB) | |
| 2004 | − { | |
| 2005 | − ReadOffset = ReadOffset + ReadBytes ; | |
| 2006 | − OutPutBuff = OutPutBuff + ReadBytes ; | |
| 2007 | − } | |
| 1919 | + Status = copy_from_user(&RxCntrlMsgBitMask, IoBuffer.InputBuffer, IoBuffer.InputLength); | |
| 1920 | + if (Status) { | |
| 1921 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "copy of control bit mask failed from user space"); | |
| 1922 | + Status = -EFAULT; | |
| 1923 | + break; | |
| 1924 | + } | |
| 1925 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\n Got user defined cntrl msg bit mask :%lx", RxCntrlMsgBitMask); | |
| 1926 | + pTarang->RxCntrlMsgBitMask = RxCntrlMsgBitMask; | |
| 1927 | + } | |
| 1928 | + break; | |
| 2008 | 1929 | |
| 2009 | − } | |
| 2010 | − Adapter->bFlashRawRead = FALSE ; | |
| 2011 | − up(&Adapter->NVMRdmWrmLock); | |
| 2012 | − kfree(pReadBuff); | |
| 2013 | − break ; | |
| 2014 | − } | |
| 2015 | − | |
| 2016 | − case IOCTL_BCM_CNTRLMSG_MASK: | |
| 2017 | − { | |
| 2018 | − ULONG RxCntrlMsgBitMask = 0 ; | |
| 2019 | − | |
| 2020 | − /* Copy Ioctl Buffer structure */ | |
| 2021 | − Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); | |
| 2022 | − if(Status) | |
| 2023 | − { | |
| 2024 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"copy of Ioctl buffer is failed from user space"); | |
| 2025 | − Status = -EFAULT; | |
| 2026 | − break; | |
| 2027 | − } | |
| 1930 | + case IOCTL_BCM_GET_DEVICE_DRIVER_INFO: { | |
| 1931 | + DEVICE_DRIVER_INFO DevInfo; | |
| 2028 | 1932 | |
| 2029 | − if (IoBuffer.InputLength != sizeof(unsigned long)) { | |
| 2030 | − Status = -EINVAL; | |
| 2031 | − break; | |
| 2032 | − } | |
| 1933 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n"); | |
| 2033 | 1934 | |
| 2034 | − Status = copy_from_user(&RxCntrlMsgBitMask, IoBuffer.InputBuffer, IoBuffer.InputLength); | |
| 2035 | − if(Status) | |
| 2036 | − { | |
| 2037 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"copy of control bit mask failed from user space"); | |
| 2038 | − Status = -EFAULT; | |
| 2039 | − break; | |
| 2040 | − } | |
| 2041 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\n Got user defined cntrl msg bit mask :%lx", RxCntrlMsgBitMask); | |
| 2042 | − pTarang->RxCntrlMsgBitMask = RxCntrlMsgBitMask ; | |
| 2043 | − } | |
| 2044 | − break; | |
| 2045 | − case IOCTL_BCM_GET_DEVICE_DRIVER_INFO: | |
| 2046 | − { | |
| 2047 | − DEVICE_DRIVER_INFO DevInfo; | |
| 2048 | − | |
| 2049 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n"); | |
| 2050 | − | |
| 2051 | − DevInfo.MaxRDMBufferSize = BUFFER_4K; | |
| 2052 | − DevInfo.u32DSDStartOffset = EEPROM_CALPARAM_START; | |
| 2053 | − DevInfo.u32RxAlignmentCorrection = 0; | |
| 2054 | − DevInfo.u32NVMType = Adapter->eNVMType; | |
| 2055 | − DevInfo.u32InterfaceType = BCM_USB; | |
| 2056 | − | |
| 2057 | − if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 2058 | − return -EFAULT; | |
| 1935 | + DevInfo.MaxRDMBufferSize = BUFFER_4K; | |
| 1936 | + DevInfo.u32DSDStartOffset = EEPROM_CALPARAM_START; | |
| 1937 | + DevInfo.u32RxAlignmentCorrection = 0; | |
| 1938 | + DevInfo.u32NVMType = Adapter->eNVMType; | |
| 1939 | + DevInfo.u32InterfaceType = BCM_USB; | |
| 2059 | 1940 | |
| 2060 | − if(IoBuffer.OutputLength < sizeof(DevInfo)) | |
| 2061 | − return -EINVAL; | |
| 1941 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1942 | + return -EFAULT; | |
| 2062 | 1943 | |
| 2063 | − if (copy_to_user(IoBuffer.OutputBuffer, &DevInfo, sizeof(DevInfo))) | |
| 2064 | − return -EFAULT; | |
| 2065 | − } | |
| 2066 | − break ; | |
| 1944 | + if (IoBuffer.OutputLength < sizeof(DevInfo)) | |
| 1945 | + return -EINVAL; | |
| 2067 | 1946 | |
| 2068 | − case IOCTL_BCM_TIME_SINCE_NET_ENTRY: | |
| 2069 | − { | |
| 2070 | − ST_TIME_ELAPSED stTimeElapsedSinceNetEntry = {0}; | |
| 1947 | + if (copy_to_user(IoBuffer.OutputBuffer, &DevInfo, sizeof(DevInfo))) | |
| 1948 | + return -EFAULT; | |
| 1949 | + } | |
| 1950 | + break; | |
| 2071 | 1951 | |
| 2072 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_BCM_TIME_SINCE_NET_ENTRY called"); | |
| 1952 | + case IOCTL_BCM_TIME_SINCE_NET_ENTRY: { | |
| 1953 | + ST_TIME_ELAPSED stTimeElapsedSinceNetEntry = {0}; | |
| 2073 | 1954 | |
| 2074 | − if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 2075 | − return -EFAULT; | |
| 1955 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_TIME_SINCE_NET_ENTRY called"); | |
| 2076 | 1956 | |
| 2077 | − if(IoBuffer.OutputLength < sizeof(ST_TIME_ELAPSED)) | |
| 2078 | − return -EINVAL; | |
| 1957 | + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) | |
| 1958 | + return -EFAULT; | |
| 2079 | 1959 | |
| 2080 | − stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = get_seconds() - Adapter->liTimeSinceLastNetEntry; | |
| 1960 | + if (IoBuffer.OutputLength < sizeof(ST_TIME_ELAPSED)) | |
| 1961 | + return -EINVAL; | |
| 2081 | 1962 | |
| 2082 | − if (copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry, sizeof(ST_TIME_ELAPSED))) | |
| 2083 | − return -EFAULT; | |
| 1963 | + stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = get_seconds() - Adapter->liTimeSinceLastNetEntry; | |
| 2084 | 1964 | |
| 2085 | − } | |
| 2086 | − break; | |
| 1965 | + if (copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry, sizeof(ST_TIME_ELAPSED))) | |
| 1966 | + return -EFAULT; | |
| 1967 | + } | |
| 1968 | + break; | |
| 2087 | 1969 | |
| 2088 | − case IOCTL_CLOSE_NOTIFICATION: | |
| 2089 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_CLOSE_NOTIFICATION"); | |
| 2090 | − break; | |
| 1970 | + case IOCTL_CLOSE_NOTIFICATION: | |
| 1971 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_CLOSE_NOTIFICATION"); | |
| 1972 | + break; | |
| 2091 | 1973 | |
| 2092 | − default: | |
| 2093 | − pr_info(DRV_NAME ": unknown ioctl cmd=%#x\n", cmd); | |
| 2094 | − Status = STATUS_FAILURE; | |
| 2095 | − break; | |
| 1974 | + default: | |
| 1975 | + pr_info(DRV_NAME ": unknown ioctl cmd=%#x\n", cmd); | |
| 1976 | + Status = STATUS_FAILURE; | |
| 1977 | + break; | |
| 2096 | 1978 | } |
| 2097 | 1979 | return Status; |
| 2098 | 1980 | } |
| @@ -2107,8 +1989,6 @@ static const struct file_operations bcm_fops = { · 8 unmodified lines | ||
| 2107 | 1989 | .llseek = no_llseek, |
| 2108 | 1990 | }; |
| 2109 | 1991 | |
| 2110 | −extern struct class *bcm_class; | |
| 2111 | − | |
| 2112 | 1992 | int register_control_device_interface(PMINI_ADAPTER Adapter) |
| 2113 | 1993 | { |
| 2114 | 1994 | |
| @@ -2122,8 +2002,8 @@ int register_control_device_interface(PMINI_ADAPTER Adapter) · 7 unmodified lines | ||
| 2122 | 2002 | } |
| 2123 | 2003 | |
| 2124 | 2004 | Adapter->pstCreatedClassDevice = device_create(bcm_class, NULL, |
| 2125 | − MKDEV(Adapter->major, 0), | |
| 2126 | − Adapter, DEV_NAME); | |
| 2005 | + MKDEV(Adapter->major, 0), | |
| 2006 | + Adapter, DEV_NAME); | |
| 2127 | 2007 | |
| 2128 | 2008 | if (IS_ERR(Adapter->pstCreatedClassDevice)) { |
| 2129 | 2009 | pr_err(DRV_NAME ": class device create failed\n"); |
| @@ -2141,3 +2021,4 @@ void unregister_control_device_interface(PMINI_ADAPTER Adapter) · 11 unmodified lines | ||
| 2141 | 2021 | unregister_chrdev(Adapter->major, DEV_NAME); |
| 2142 | 2022 | } |
| 2143 | 2023 | } |
| 2024 | + | |
| @@ -1,204 +1,183 @@ | ||
| 1 | 1 | #include "headers.h" |
| 2 | 2 | |
| 3 | − | |
| 4 | −int InterfaceFileDownload( PVOID arg, | |
| 5 | − struct file *flp, | |
| 6 | − unsigned int on_chip_loc) | |
| 3 | +int InterfaceFileDownload(PVOID arg, struct file *flp, unsigned int on_chip_loc) | |
| 7 | 4 | { |
| 8 | − // unsigned int reg=0; | |
| 9 | − mm_segment_t oldfs={0}; | |
| 10 | − int errno=0, len=0 /*,is_config_file = 0*/; | |
| 11 | − loff_t pos=0; | |
| 5 | + /* unsigned int reg = 0; */ | |
| 6 | + mm_segment_t oldfs = {0}; | |
| 7 | + int errno = 0, len = 0; /* ,is_config_file = 0 */ | |
| 8 | + loff_t pos = 0; | |
| 12 | 9 | PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg; |
| 13 | − //PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter; | |
| 14 | − char *buff=kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); | |
| 15 | − | |
| 16 | − if(!buff) | |
| 17 | − { | |
| 18 | − return -ENOMEM; | |
| 19 | − } | |
| 20 | − while(1) | |
| 21 | − { | |
| 22 | − oldfs=get_fs(); set_fs(get_ds()); | |
| 23 | − len=vfs_read(flp, (void __force __user *)buff, MAX_TRANSFER_CTRL_BYTE_USB, &pos); | |
| 24 | − set_fs(oldfs); | |
| 25 | − if(len<=0) | |
| 26 | − { | |
| 27 | − if(len<0) | |
| 28 | − { | |
| 29 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len < 0"); | |
| 30 | − errno=len; | |
| 31 | − } | |
| 32 | − else | |
| 33 | − { | |
| 34 | − errno = 0; | |
| 35 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got end of file!"); | |
| 36 | − } | |
| 37 | − break; | |
| 38 | − } | |
| 39 | − //BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, buff, MAX_TRANSFER_CTRL_BYTE_USB); | |
| 40 | − errno = InterfaceWRM(psIntfAdapter, on_chip_loc, buff, len) ; | |
| 41 | − if(errno) | |
| 42 | − { | |
| 43 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "WRM Failed! status: %d", errno); | |
| 44 | − break; | |
| 10 | + /* PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter; */ | |
| 11 | + char *buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); | |
| 12 | + | |
| 13 | + if (!buff) | |
| 14 | + return -ENOMEM; | |
| 45 | 15 | |
| 16 | + while (1) { | |
| 17 | + oldfs = get_fs(); | |
| 18 | + set_fs(get_ds()); | |
| 19 | + len = vfs_read(flp, (void __force __user *)buff, | |
| 20 | + MAX_TRANSFER_CTRL_BYTE_USB, &pos); | |
| 21 | + set_fs(oldfs); | |
| 22 | + if (len <= 0) { | |
| 23 | + if (len < 0) { | |
| 24 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, | |
| 25 | + DBG_TYPE_INITEXIT, MP_INIT, | |
| 26 | + DBG_LVL_ALL, "len < 0"); | |
| 27 | + errno = len; | |
| 28 | + } else { | |
| 29 | + errno = 0; | |
| 30 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, | |
| 31 | + DBG_TYPE_INITEXIT, MP_INIT, | |
| 32 | + DBG_LVL_ALL, | |
| 33 | + "Got end of file!"); | |
| 34 | + } | |
| 35 | + break; | |
| 46 | 36 | } |
| 47 | − on_chip_loc+=MAX_TRANSFER_CTRL_BYTE_USB; | |
| 48 | − }/* End of for(;;)*/ | |
| 37 | + /* BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_INITEXIT, MP_INIT, | |
| 38 | + * DBG_LVL_ALL, buff, | |
| 39 | + * MAX_TRANSFER_CTRL_BYTE_USB); | |
| 40 | + */ | |
| 41 | + errno = InterfaceWRM(psIntfAdapter, on_chip_loc, buff, len); | |
| 42 | + if (errno) { | |
| 43 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, | |
| 44 | + DBG_TYPE_PRINTK, 0, 0, | |
| 45 | + "WRM Failed! status: %d", errno); | |
| 46 | + break; | |
| 47 | + } | |
| 48 | + on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB; | |
| 49 | + } | |
| 49 | 50 | |
| 50 | 51 | kfree(buff); |
| 51 | − return errno; | |
| 52 | + return errno; | |
| 52 | 53 | } |
| 53 | 54 | |
| 54 | −int InterfaceFileReadbackFromChip( PVOID arg, | |
| 55 | − struct file *flp, | |
| 56 | − unsigned int on_chip_loc) | |
| 55 | +int InterfaceFileReadbackFromChip(PVOID arg, struct file *flp, unsigned int on_chip_loc) | |
| 57 | 56 | { |
| 58 | − char *buff, *buff_readback; | |
| 59 | − unsigned int reg=0; | |
| 60 | − mm_segment_t oldfs={0}; | |
| 61 | − int errno=0, len=0, is_config_file = 0; | |
| 62 | − loff_t pos=0; | |
| 63 | − static int fw_down = 0; | |
| 64 | − INT Status = STATUS_SUCCESS; | |
| 57 | + char *buff, *buff_readback; | |
| 58 | + unsigned int reg = 0; | |
| 59 | + mm_segment_t oldfs = {0}; | |
| 60 | + int errno = 0, len = 0, is_config_file = 0; | |
| 61 | + loff_t pos = 0; | |
| 62 | + static int fw_down; | |
| 63 | + INT Status = STATUS_SUCCESS; | |
| 65 | 64 | PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg; |
| 66 | 65 | |
| 67 | − buff=kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA); | |
| 68 | − buff_readback=kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA); | |
| 69 | − if(!buff || !buff_readback) | |
| 70 | − { | |
| 71 | − kfree(buff); | |
| 72 | − kfree(buff_readback); | |
| 66 | + buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA); | |
| 67 | + buff_readback = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA); | |
| 68 | + if (!buff || !buff_readback) { | |
| 69 | + kfree(buff); | |
| 70 | + kfree(buff_readback); | |
| 73 | 71 | |
| 74 | − return -ENOMEM; | |
| 75 | − } | |
| 72 | + return -ENOMEM; | |
| 73 | + } | |
| 76 | 74 | |
| 77 | − is_config_file = (on_chip_loc == CONFIG_BEGIN_ADDR)? 1:0; | |
| 75 | + is_config_file = (on_chip_loc == CONFIG_BEGIN_ADDR) ? 1 : 0; | |
| 78 | 76 | |
| 79 | 77 | memset(buff_readback, 0, MAX_TRANSFER_CTRL_BYTE_USB); |
| 80 | 78 | memset(buff, 0, MAX_TRANSFER_CTRL_BYTE_USB); |
| 81 | − while(1) | |
| 82 | − { | |
| 83 | − oldfs=get_fs(); set_fs(get_ds()); | |
| 84 | − len=vfs_read(flp, (void __force __user *)buff, MAX_TRANSFER_CTRL_BYTE_USB, &pos); | |
| 85 | − set_fs(oldfs); | |
| 86 | − fw_down++; | |
| 87 | − if(len<=0) | |
| 88 | − { | |
| 89 | − if(len<0) | |
| 90 | − { | |
| 91 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len < 0"); | |
| 92 | − errno=len; | |
| 93 | − } | |
| 94 | − else | |
| 95 | − { | |
| 96 | − errno = 0; | |
| 97 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got end of file!"); | |
| 98 | − } | |
| 99 | − break; | |
| 100 | − } | |
| 101 | − | |
| 79 | + while (1) { | |
| 80 | + oldfs = get_fs(); | |
| 81 | + set_fs(get_ds()); | |
| 82 | + len = vfs_read(flp, (void __force __user *)buff, MAX_TRANSFER_CTRL_BYTE_USB, &pos); | |
| 83 | + set_fs(oldfs); | |
| 84 | + fw_down++; | |
| 85 | + | |
| 86 | + if (len <= 0) { | |
| 87 | + if (len < 0) { | |
| 88 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len < 0"); | |
| 89 | + errno = len; | |
| 90 | + } else { | |
| 91 | + errno = 0; | |
| 92 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got end of file!"); | |
| 93 | + } | |
| 94 | + break; | |
| 95 | + } | |
| 102 | 96 | |
| 103 | 97 | Status = InterfaceRDM(psIntfAdapter, on_chip_loc, buff_readback, len); |
| 104 | − if(Status) | |
| 105 | − { | |
| 106 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "RDM of len %d Failed! %d", len, reg); | |
| 98 | + if (Status) { | |
| 99 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "RDM of len %d Failed! %d", len, reg); | |
| 107 | 100 | goto exit; |
| 108 | 101 | } |
| 109 | 102 | reg++; |
| 110 | − if((len-sizeof(unsigned int))<4) | |
| 111 | − { | |
| 112 | − if(memcmp(buff_readback, buff, len)) | |
| 113 | − { | |
| 114 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down); | |
| 115 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT,DBG_LVL_ALL,"Length is: %d",len); | |
| 103 | + if ((len-sizeof(unsigned int)) < 4) { | |
| 104 | + if (memcmp(buff_readback, buff, len)) { | |
| 105 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down); | |
| 106 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Length is: %d", len); | |
| 116 | 107 | Status = -EIO; |
| 117 | 108 | goto exit; |
| 118 | − } | |
| 119 | − } | |
| 120 | − else | |
| 121 | − { | |
| 122 | − len-=4; | |
| 123 | − while(len) | |
| 124 | − { | |
| 125 | − if(*(unsigned int*)&buff_readback[len] != *(unsigned int *)&buff[len]) | |
| 126 | − { | |
| 127 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down); | |
| 128 | − 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]); | |
| 129 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len); | |
| 109 | + } | |
| 110 | + } else { | |
| 111 | + len -= 4; | |
| 112 | + | |
| 113 | + while (len) { | |
| 114 | + if (*(unsigned int *)&buff_readback[len] != *(unsigned int *)&buff[len]) { | |
| 115 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down); | |
| 116 | + 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]); | |
| 117 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len); | |
| 130 | 118 | Status = -EIO; |
| 131 | 119 | goto exit; |
| 132 | − } | |
| 133 | − len-=4; | |
| 134 | − } | |
| 135 | − } | |
| 136 | − on_chip_loc+=MAX_TRANSFER_CTRL_BYTE_USB; | |
| 137 | − }/* End of while(1)*/ | |
| 120 | + } | |
| 121 | + len -= 4; | |
| 122 | + } | |
| 123 | + } | |
| 124 | + on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB; | |
| 125 | + } /* End of while(1) */ | |
| 126 | + | |
| 138 | 127 | exit: |
| 139 | − kfree(buff); | |
| 140 | − kfree(buff_readback); | |
| 128 | + kfree(buff); | |
| 129 | + kfree(buff_readback); | |
| 141 | 130 | return Status; |
| 142 | 131 | } |
| 143 | 132 | |
| 144 | −static int bcm_download_config_file(PMINI_ADAPTER Adapter, | |
| 145 | − FIRMWARE_INFO *psFwInfo) | |
| 133 | +static int bcm_download_config_file(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo) | |
| 146 | 134 | { |
| 147 | 135 | int retval = STATUS_SUCCESS; |
| 148 | 136 | B_UINT32 value = 0; |
| 149 | 137 | |
| 150 | − if(Adapter->pstargetparams == NULL) | |
| 151 | − { | |
| 152 | − if((Adapter->pstargetparams = | |
| 153 | − kmalloc(sizeof(STARGETPARAMS), GFP_KERNEL)) == NULL) | |
| 154 | − { | |
| 155 | − return -ENOMEM; | |
| 156 | − } | |
| 157 | − } | |
| 158 | − if(psFwInfo->u32FirmwareLength != sizeof(STARGETPARAMS)) | |
| 159 | − { | |
| 160 | − return -EIO; | |
| 138 | + if (Adapter->pstargetparams == NULL) { | |
| 139 | + Adapter->pstargetparams = kmalloc(sizeof(STARGETPARAMS), GFP_KERNEL); | |
| 140 | + if (Adapter->pstargetparams == NULL) | |
| 141 | + return -ENOMEM; | |
| 161 | 142 | } |
| 162 | − retval = copy_from_user(Adapter->pstargetparams, | |
| 163 | − psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength); | |
| 164 | − if(retval) | |
| 165 | − { | |
| 143 | + | |
| 144 | + if (psFwInfo->u32FirmwareLength != sizeof(STARGETPARAMS)) | |
| 145 | + return -EIO; | |
| 146 | + | |
| 147 | + retval = copy_from_user(Adapter->pstargetparams, psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength); | |
| 148 | + if (retval) { | |
| 166 | 149 | kfree(Adapter->pstargetparams); |
| 167 | 150 | Adapter->pstargetparams = NULL; |
| 168 | 151 | return -EFAULT; |
| 169 | 152 | } |
| 153 | + | |
| 170 | 154 | /* Parse the structure and then Download the Firmware */ |
| 171 | 155 | beceem_parse_target_struct(Adapter); |
| 172 | 156 | |
| 173 | − //Initializing the NVM. | |
| 157 | + /* Initializing the NVM. */ | |
| 174 | 158 | BcmInitNVM(Adapter); |
| 159 | + retval = InitLedSettings(Adapter); | |
| 175 | 160 | |
| 176 | − retval = InitLedSettings (Adapter); | |
| 177 | − | |
| 178 | − if(retval) | |
| 179 | − { | |
| 180 | − BCM_DEBUG_PRINT (Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "INIT LED Failed\n"); | |
| 161 | + if (retval) { | |
| 162 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "INIT LED Failed\n"); | |
| 181 | 163 | return retval; |
| 182 | 164 | } |
| 183 | 165 | |
| 184 | − if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) | |
| 185 | − { | |
| 166 | + if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { | |
| 186 | 167 | Adapter->LEDInfo.bLedInitDone = FALSE; |
| 187 | 168 | Adapter->DriverState = DRIVER_INIT; |
| 188 | 169 | wake_up(&Adapter->LEDInfo.notify_led_event); |
| 189 | 170 | } |
| 190 | 171 | |
| 191 | − if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) | |
| 192 | − { | |
| 172 | + if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { | |
| 193 | 173 | Adapter->DriverState = FW_DOWNLOAD; |
| 194 | 174 | wake_up(&Adapter->LEDInfo.notify_led_event); |
| 195 | 175 | } |
| 196 | 176 | |
| 197 | 177 | /* Initialize the DDR Controller */ |
| 198 | 178 | retval = ddr_init(Adapter); |
| 199 | − if(retval) | |
| 200 | − { | |
| 201 | − BCM_DEBUG_PRINT (Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "DDR Init Failed\n"); | |
| 179 | + if (retval) { | |
| 180 | + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "DDR Init Failed\n"); | |
| 202 | 181 | return retval; |
| 203 | 182 | } |
| 204 | 183 | |
| @@ -206,197 +185,166 @@ static int bcm_download_config_file(PMINI_ADAPTER Adapter, · 1 unmodified line | ||
| 206 | 185 | wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value)); |
| 207 | 186 | wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value)); |
| 208 | 187 | |
| 209 | − if(Adapter->eNVMType == NVM_FLASH) | |
| 210 | − { | |
| 188 | + if (Adapter->eNVMType == NVM_FLASH) { | |
| 211 | 189 | retval = PropagateCalParamsFromFlashToMemory(Adapter); |
| 212 | − if(retval) | |
| 213 | − { | |
| 214 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"propagaion of cal param failed with status :%d", retval); | |
| 190 | + if (retval) { | |
| 191 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "propagaion of cal param failed with status :%d", retval); | |
| 215 | 192 | return retval; |
| 216 | 193 | } |
| 217 | 194 | } |
| 218 | 195 | |
| 196 | + retval = buffDnldVerify(Adapter, (PUCHAR)Adapter->pstargetparams, sizeof(STARGETPARAMS), CONFIG_BEGIN_ADDR); | |
| 219 | 197 | |
| 220 | − retval =buffDnldVerify(Adapter,(PUCHAR)Adapter->pstargetparams,sizeof(STARGETPARAMS),CONFIG_BEGIN_ADDR); | |
| 221 | − | |
| 222 | − if(retval) | |
| 223 | − { | |
| 224 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "configuration file not downloaded properly"); | |
| 225 | − } | |
| 198 | + if (retval) | |
| 199 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "configuration file not downloaded properly"); | |
| 226 | 200 | else |
| 227 | 201 | Adapter->bCfgDownloaded = TRUE; |
| 228 | 202 | |
| 229 | − | |
| 230 | 203 | return retval; |
| 231 | 204 | } |
| 232 | −static int bcm_compare_buff_contents(unsigned char *readbackbuff, | |
| 233 | − unsigned char *buff,unsigned int len) | |
| 205 | + | |
| 206 | +static int bcm_compare_buff_contents(unsigned char *readbackbuff, unsigned char *buff, unsigned int len) | |
| 234 | 207 | { |
| 235 | 208 | int retval = STATUS_SUCCESS; |
| 236 | − PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
| 237 | − if((len-sizeof(unsigned int))<4) | |
| 238 | − { | |
| 239 | − if(memcmp(readbackbuff , buff, len)) | |
| 240 | − { | |
| 241 | − retval=-EINVAL; | |
| 242 | − } | |
| 243 | − } | |
| 244 | − else | |
| 245 | − { | |
| 246 | − len-=4; | |
| 247 | − while(len) | |
| 248 | − { | |
| 249 | − if(*(unsigned int*)&readbackbuff[len] != | |
| 250 | − *(unsigned int *)&buff[len]) | |
| 251 | − { | |
| 252 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper"); | |
| 253 | − 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]); | |
| 254 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len); | |
| 255 | − retval=-EINVAL; | |
| 209 | + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
| 210 | + if ((len-sizeof(unsigned int)) < 4) { | |
| 211 | + if (memcmp(readbackbuff , buff, len)) | |
| 212 | + retval = -EINVAL; | |
| 213 | + } else { | |
| 214 | + len -= 4; | |
| 215 | + | |
| 216 | + while (len) { | |
| 217 | + if (*(unsigned int *)&readbackbuff[len] != *(unsigned int *)&buff[len]) { | |
| 218 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper"); | |
| 219 | + 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]); | |
| 220 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len); | |
| 221 | + retval = -EINVAL; | |
| 256 | 222 | break; |
| 257 | 223 | } |
| 258 | − len-=4; | |
| 224 | + len -= 4; | |
| 259 | 225 | } |
| 260 | 226 | } |
| 261 | 227 | return retval; |
| 262 | 228 | } |
| 229 | + | |
| 263 | 230 | int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo) |
| 264 | 231 | { |
| 265 | 232 | int retval = STATUS_SUCCESS; |
| 266 | 233 | PUCHAR buff = NULL; |
| 267 | 234 | |
| 268 | − /* Config File is needed for the Driver to download the Config file and | |
| 269 | − Firmware. Check for the Config file to be first to be sent from the | |
| 270 | − Application | |
| 271 | − */ | |
| 272 | − atomic_set (&Adapter->uiMBupdate, FALSE); | |
| 273 | − if(!Adapter->bCfgDownloaded && | |
| 274 | − psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR) | |
| 275 | − { | |
| 276 | − /*Can't Download Firmware.*/ | |
| 277 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Download the config File first\n"); | |
| 235 | + /* Config File is needed for the Driver to download the Config file and | |
| 236 | + * Firmware. Check for the Config file to be first to be sent from the | |
| 237 | + * Application | |
| 238 | + */ | |
| 239 | + atomic_set(&Adapter->uiMBupdate, FALSE); | |
| 240 | + if (!Adapter->bCfgDownloaded && psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR) { | |
| 241 | + /* Can't Download Firmware. */ | |
| 242 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Download the config File first\n"); | |
| 278 | 243 | return -EINVAL; |
| 279 | 244 | } |
| 280 | 245 | |
| 281 | 246 | /* If Config File, Finish the DDR Settings and then Download CFG File */ |
| 282 | − if(psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR) | |
| 283 | − { | |
| 284 | − retval = bcm_download_config_file (Adapter, psFwInfo); | |
| 285 | − } | |
| 286 | − else | |
| 287 | − { | |
| 288 | − | |
| 289 | − buff = kzalloc(psFwInfo->u32FirmwareLength,GFP_KERNEL); | |
| 290 | − if(buff==NULL) | |
| 291 | − { | |
| 292 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Failed in allocation memory"); | |
| 247 | + if (psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR) { | |
| 248 | + retval = bcm_download_config_file(Adapter, psFwInfo); | |
| 249 | + } else { | |
| 250 | + buff = kzalloc(psFwInfo->u32FirmwareLength, GFP_KERNEL); | |
| 251 | + if (buff == NULL) { | |
| 252 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed in allocation memory"); | |
| 293 | 253 | return -ENOMEM; |
| 294 | 254 | } |
| 295 | − retval = copy_from_user(buff,psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength); | |
| 296 | − if(retval != STATUS_SUCCESS) | |
| 297 | − { | |
| 298 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copying buffer from user space failed"); | |
| 255 | + | |
| 256 | + retval = copy_from_user(buff, psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength); | |
| 257 | + if (retval != STATUS_SUCCESS) { | |
| 258 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copying buffer from user space failed"); | |
| 299 | 259 | retval = -EFAULT; |
| 300 | − goto error ; | |
| 260 | + goto error; | |
| 301 | 261 | } |
| 302 | 262 | |
| 303 | 263 | retval = buffDnldVerify(Adapter, |
| 304 | 264 | buff, |
| 305 | 265 | psFwInfo->u32FirmwareLength, |
| 306 | 266 | psFwInfo->u32StartingAddress); |
| 307 | − if(retval != STATUS_SUCCESS) | |
| 308 | − { | |
| 309 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"f/w download failed status :%d", retval); | |
| 267 | + | |
| 268 | + if (retval != STATUS_SUCCESS) { | |
| 269 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "f/w download failed status :%d", retval); | |
| 310 | 270 | goto error; |
| 311 | 271 | } |
| 312 | 272 | } |
| 273 | + | |
| 313 | 274 | error: |
| 314 | 275 | kfree(buff); |
| 315 | 276 | return retval; |
| 316 | 277 | } |
| 317 | 278 | |
| 318 | −static INT buffDnld(PMINI_ADAPTER Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, | |
| 319 | − ULONG u32StartingAddress) | |
| 279 | +static INT buffDnld(PMINI_ADAPTER Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, ULONG u32StartingAddress) | |
| 320 | 280 | { |
| 321 | − | |
| 322 | − unsigned int len = 0; | |
| 281 | + unsigned int len = 0; | |
| 323 | 282 | int retval = STATUS_SUCCESS; |
| 324 | 283 | len = u32FirmwareLength; |
| 325 | 284 | |
| 326 | − while(u32FirmwareLength) | |
| 327 | − { | |
| 328 | − len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); | |
| 329 | − retval = wrm (Adapter, u32StartingAddress, mappedbuffer, len); | |
| 330 | − if(retval) | |
| 331 | − { | |
| 332 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "wrm failed with status :%d", retval); | |
| 285 | + while (u32FirmwareLength) { | |
| 286 | + len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); | |
| 287 | + retval = wrm(Adapter, u32StartingAddress, mappedbuffer, len); | |
| 288 | + | |
| 289 | + if (retval) { | |
| 290 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "wrm failed with status :%d", retval); | |
| 333 | 291 | break; |
| 334 | 292 | } |
| 335 | − u32StartingAddress += len; | |
| 336 | − u32FirmwareLength -= len; | |
| 337 | − mappedbuffer +=len; | |
| 293 | + u32StartingAddress += len; | |
| 294 | + u32FirmwareLength -= len; | |
| 295 | + mappedbuffer += len; | |
| 338 | 296 | } |
| 339 | 297 | return retval; |
| 340 | − | |
| 341 | 298 | } |
| 342 | 299 | |
| 343 | −static INT buffRdbkVerify(PMINI_ADAPTER Adapter, | |
| 344 | − PUCHAR mappedbuffer, UINT u32FirmwareLength, | |
| 345 | − ULONG u32StartingAddress) | |
| 300 | +static INT buffRdbkVerify(PMINI_ADAPTER Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, ULONG u32StartingAddress) | |
| 346 | 301 | { |
| 347 | 302 | UINT len = u32FirmwareLength; |
| 348 | 303 | INT retval = STATUS_SUCCESS; |
| 349 | − PUCHAR readbackbuff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB,GFP_KERNEL); | |
| 304 | + PUCHAR readbackbuff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); | |
| 350 | 305 | |
| 351 | − if(NULL == readbackbuff) | |
| 352 | − { | |
| 353 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "MEMORY ALLOCATION FAILED"); | |
| 306 | + if (NULL == readbackbuff) { | |
| 307 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "MEMORY ALLOCATION FAILED"); | |
| 354 | 308 | return -ENOMEM; |
| 355 | 309 | } |
| 356 | − while (u32FirmwareLength && !retval) | |
| 357 | − { | |
| 358 | 310 | |
| 359 | − len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); | |
| 311 | + while (u32FirmwareLength && !retval) { | |
| 312 | + len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); | |
| 313 | + retval = rdm(Adapter, u32StartingAddress, readbackbuff, len); | |
| 360 | 314 | |
| 361 | − retval = rdm (Adapter, u32StartingAddress, readbackbuff, len); | |
| 362 | − if(retval) | |
| 363 | − { | |
| 364 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed with status %d" ,retval); | |
| 315 | + if (retval) { | |
| 316 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed with status %d", retval); | |
| 365 | 317 | break; |
| 366 | 318 | } |
| 367 | 319 | |
| 368 | − if (STATUS_SUCCESS != (retval = bcm_compare_buff_contents (readbackbuff, mappedbuffer, len))) | |
| 369 | − { | |
| 320 | + retval = bcm_compare_buff_contents(readbackbuff, mappedbuffer, len); | |
| 321 | + if (STATUS_SUCCESS != retval) | |
| 370 | 322 | break; |
| 371 | − } | |
| 372 | − u32StartingAddress += len; | |
| 373 | − u32FirmwareLength -= len; | |
| 374 | − mappedbuffer +=len; | |
| 375 | − }/* end of while (u32FirmwareLength && !retval) */ | |
| 323 | + | |
| 324 | + u32StartingAddress += len; | |
| 325 | + u32FirmwareLength -= len; | |
| 326 | + mappedbuffer += len; | |
| 327 | + | |
| 328 | + } /* end of while (u32FirmwareLength && !retval) */ | |
| 376 | 329 | kfree(readbackbuff); |
| 377 | 330 | return retval; |
| 378 | 331 | } |
| 379 | 332 | |
| 380 | −INT buffDnldVerify(PMINI_ADAPTER Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength, | |
| 381 | − unsigned long u32StartingAddress) | |
| 333 | +INT buffDnldVerify(PMINI_ADAPTER Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength, unsigned long u32StartingAddress) | |
| 382 | 334 | { |
| 383 | 335 | INT status = STATUS_SUCCESS; |
| 384 | 336 | |
| 385 | − status = buffDnld(Adapter,mappedbuffer,u32FirmwareLength,u32StartingAddress); | |
| 386 | − if(status != STATUS_SUCCESS) | |
| 387 | − { | |
| 388 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Buffer download failed"); | |
| 337 | + status = buffDnld(Adapter, mappedbuffer, u32FirmwareLength, u32StartingAddress); | |
| 338 | + if (status != STATUS_SUCCESS) { | |
| 339 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Buffer download failed"); | |
| 389 | 340 | goto error; |
| 390 | 341 | } |
| 391 | 342 | |
| 392 | − status= buffRdbkVerify(Adapter,mappedbuffer,u32FirmwareLength,u32StartingAddress); | |
| 393 | − if(status != STATUS_SUCCESS) | |
| 394 | − { | |
| 395 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Buffer readback verifier failed"); | |
| 343 | + status = buffRdbkVerify(Adapter, mappedbuffer, u32FirmwareLength, u32StartingAddress); | |
| 344 | + if (status != STATUS_SUCCESS) { | |
| 345 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Buffer readback verifier failed"); | |
| 396 | 346 | goto error; |
| 397 | 347 | } |
| 398 | 348 | error: |
| 399 | 349 | return status; |
| 400 | 350 | } |
| 401 | − | |
| 402 | − | |
| @@ -139,8 +139,7 @@ static void ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter) · 138 unmodified lines | ||
| 139 | 139 | BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1C2, 4, TRUE); |
| 140 | 140 | } |
| 141 | 141 | |
| 142 | −static int | |
| 143 | −usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) | |
| 142 | +static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) | |
| 144 | 143 | { |
| 145 | 144 | struct usb_device *udev = interface_to_usbdev(intf); |
| 146 | 145 | int retval; |
| @@ -281,8 +280,9 @@ static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter) · 134 unmodified lines | ||
| 281 | 280 | int i = 0; |
| 282 | 281 | |
| 283 | 282 | for (i = 0; i < MAXIMUM_USB_TCB; i++) { |
| 284 | − if ((psIntfAdapter->asUsbTcb[i].urb = | |
| 285 | − usb_alloc_urb(0, GFP_KERNEL)) == NULL) { | |
| 283 | + psIntfAdapter->asUsbTcb[i].urb = usb_alloc_urb(0, GFP_KERNEL); | |
| 284 | + | |
| 285 | + if (psIntfAdapter->asUsbTcb[i].urb == NULL) { | |
| 286 | 286 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, |
| 287 | 287 | "Can't allocate Tx urb for index %d\n", i); |
| 288 | 288 | return -ENOMEM; |
| @@ -290,14 +290,17 @@ static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter) · 1 unmodified line | ||
| 290 | 290 | } |
| 291 | 291 | |
| 292 | 292 | for (i = 0; i < MAXIMUM_USB_RCB; i++) { |
| 293 | − if ((psIntfAdapter->asUsbRcb[i].urb = | |
| 294 | − usb_alloc_urb(0, GFP_KERNEL)) == NULL) { | |
| 293 | + psIntfAdapter->asUsbRcb[i].urb = usb_alloc_urb(0, GFP_KERNEL); | |
| 294 | + | |
| 295 | + if (psIntfAdapter->asUsbRcb[i].urb == NULL) { | |
| 295 | 296 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, |
| 296 | 297 | "Can't allocate Rx urb for index %d\n", i); |
| 297 | 298 | return -ENOMEM; |
| 298 | 299 | } |
| 299 | − if ((psIntfAdapter->asUsbRcb[i].urb->transfer_buffer = | |
| 300 | − kmalloc(MAX_DATA_BUFFER_SIZE, GFP_KERNEL)) == NULL) { | |
| 300 | + | |
| 301 | + psIntfAdapter->asUsbRcb[i].urb->transfer_buffer = kmalloc(MAX_DATA_BUFFER_SIZE, GFP_KERNEL); | |
| 302 | + | |
| 303 | + if (psIntfAdapter->asUsbRcb[i].urb->transfer_buffer == NULL) { | |
| 301 | 304 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, |
| 302 | 305 | "Can't allocate Rx buffer for index %d\n", i); |
| 303 | 306 | return -ENOMEM; |
| @@ -389,32 +392,32 @@ static inline int bcm_usb_endpoint_xfer_isoc(const struct usb_endpoint_descripto · 85 unmodified lines | ||
| 389 | 392 | |
| 390 | 393 | static inline int bcm_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd) |
| 391 | 394 | { |
| 392 | − return (bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_in(epd)); | |
| 395 | + return bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_in(epd); | |
| 393 | 396 | } |
| 394 | 397 | |
| 395 | 398 | static inline int bcm_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd) |
| 396 | 399 | { |
| 397 | − return (bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_out(epd)); | |
| 400 | + return bcm_usb_endpoint_xfer_bulk(epd) && bcm_usb_endpoint_dir_out(epd); | |
| 398 | 401 | } |
| 399 | 402 | |
| 400 | 403 | static inline int bcm_usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd) |
| 401 | 404 | { |
| 402 | − return (bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_in(epd)); | |
| 405 | + return bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_in(epd); | |
| 403 | 406 | } |
| 404 | 407 | |
| 405 | 408 | static inline int bcm_usb_endpoint_is_int_out(const struct usb_endpoint_descriptor *epd) |
| 406 | 409 | { |
| 407 | − return (bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_out(epd)); | |
| 410 | + return bcm_usb_endpoint_xfer_int(epd) && bcm_usb_endpoint_dir_out(epd); | |
| 408 | 411 | } |
| 409 | 412 | |
| 410 | 413 | static inline int bcm_usb_endpoint_is_isoc_in(const struct usb_endpoint_descriptor *epd) |
| 411 | 414 | { |
| 412 | − return (bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_in(epd)); | |
| 415 | + return bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_in(epd); | |
| 413 | 416 | } |
| 414 | 417 | |
| 415 | 418 | static inline int bcm_usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor *epd) |
| 416 | 419 | { |
| 417 | − return (bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_out(epd)); | |
| 420 | + return bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_out(epd); | |
| 418 | 421 | } |
| 419 | 422 | |
| 420 | 423 | static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) |
| @@ -462,7 +465,7 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) · 41 unmodified lines | ||
| 462 | 465 | if (bBcm16 == TRUE) { |
| 463 | 466 | /* selecting alternate setting one as a default setting for High Speed modem. */ |
| 464 | 467 | if (psIntfAdapter->bHighSpeedDevice) |
| 465 | − retval= usb_set_interface(psIntfAdapter->udev, DEFAULT_SETTING_0, ALTERNATE_SETTING_1); | |
| 468 | + retval = usb_set_interface(psIntfAdapter->udev, DEFAULT_SETTING_0, ALTERNATE_SETTING_1); | |
| 466 | 469 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, |
| 467 | 470 | "BCM16 is applicable on this dongle\n"); |
| 468 | 471 | if (retval || (psIntfAdapter->bHighSpeedDevice == FALSE)) { |
| @@ -497,7 +500,7 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) · 28 unmodified lines | ||
| 497 | 500 | if ((psIntfAdapter->bHighSpeedDevice == FALSE) && bcm_usb_endpoint_is_bulk_out(endpoint)) { |
| 498 | 501 | /* Once BULK is selected in FS mode. Revert it back to INT. Else USB_IF will fail. */ |
| 499 | 502 | UINT _uiData = ntohl(EP2_CFG_INT); |
| 500 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, | |
| 503 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, | |
| 501 | 504 | "Reverting Bulk to INT as it is in Full Speed mode.\n"); |
| 502 | 505 | BeceemEEPROMBulkWrite(psIntfAdapter->psAdapter, (PUCHAR)&_uiData, 0x136, 4, TRUE); |
| 503 | 506 | } |
| @@ -579,7 +582,7 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) · 75 unmodified lines | ||
| 579 | 582 | psIntfAdapter->sIntrOut.int_out_size = buffer_size; |
| 580 | 583 | psIntfAdapter->sIntrOut.int_out_endpointAddr = endpoint->bEndpointAddress; |
| 581 | 584 | psIntfAdapter->sIntrOut.int_out_interval = endpoint->bInterval; |
| 582 | − psIntfAdapter->sIntrOut.int_out_buffer= kmalloc(buffer_size, GFP_KERNEL); | |
| 585 | + psIntfAdapter->sIntrOut.int_out_buffer = kmalloc(buffer_size, GFP_KERNEL); | |
| 583 | 586 | if (!psIntfAdapter->sIntrOut.int_out_buffer) { |
| 584 | 587 | dev_err(&psIntfAdapter->udev->dev, |
| 585 | 588 | "could not allocate interrupt_out_buffer\n"); |
| @@ -641,8 +644,8 @@ static int InterfaceSuspend(struct usb_interface *intf, pm_message_t message) · 55 unmodified lines | ||
| 641 | 644 | static int InterfaceResume(struct usb_interface *intf) |
| 642 | 645 | { |
| 643 | 646 | PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf); |
| 644 | − mdelay(100); | |
| 645 | 647 | |
| 648 | + mdelay(100); | |
| 646 | 649 | psIntfAdapter->bSuspended = FALSE; |
| 647 | 650 | |
| 648 | 651 | StartInterruptUrb(psIntfAdapter); |
| @@ -1,246 +1,219 @@ | ||
| 1 | 1 | #include "headers.h" |
| 2 | 2 | |
| 3 | −INT | |
| 4 | −InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, | |
| 5 | − UINT addr, | |
| 6 | − PVOID buff, | |
| 7 | − INT len) | |
| 3 | +INT InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, | |
| 4 | + UINT addr, | |
| 5 | + PVOID buff, | |
| 6 | + INT len) | |
| 8 | 7 | { |
| 9 | 8 | int retval = 0; |
| 10 | − USHORT usRetries = 0 ; | |
| 11 | − if(psIntfAdapter == NULL ) | |
| 12 | − { | |
| 13 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Interface Adapter is NULL"); | |
| 14 | − return -EINVAL ; | |
| 9 | + USHORT usRetries = 0; | |
| 10 | + | |
| 11 | + if (psIntfAdapter == NULL) { | |
| 12 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL"); | |
| 13 | + return -EINVAL; | |
| 15 | 14 | } |
| 16 | 15 | |
| 17 | − if(psIntfAdapter->psAdapter->device_removed == TRUE) | |
| 18 | − { | |
| 19 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Device got removed"); | |
| 16 | + if (psIntfAdapter->psAdapter->device_removed == TRUE) { | |
| 17 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Device got removed"); | |
| 20 | 18 | return -ENODEV; |
| 21 | 19 | } |
| 22 | 20 | |
| 23 | − if((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB)) | |
| 24 | − { | |
| 25 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL,"Currently Xaction is not allowed on the bus"); | |
| 21 | + if ((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB)) { | |
| 22 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "Currently Xaction is not allowed on the bus"); | |
| 26 | 23 | return -EACCES; |
| 27 | 24 | } |
| 28 | 25 | |
| 29 | − if(psIntfAdapter->bSuspended ==TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE) | |
| 30 | − { | |
| 31 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL,"Bus is in suspended states hence RDM not allowed.."); | |
| 26 | + if (psIntfAdapter->bSuspended == TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE) { | |
| 27 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "Bus is in suspended states hence RDM not allowed.."); | |
| 32 | 28 | return -EACCES; |
| 33 | 29 | } |
| 34 | − psIntfAdapter->psAdapter->DeviceAccess = TRUE ; | |
| 30 | + psIntfAdapter->psAdapter->DeviceAccess = TRUE; | |
| 31 | + | |
| 35 | 32 | do { |
| 36 | 33 | retval = usb_control_msg(psIntfAdapter->udev, |
| 37 | − usb_rcvctrlpipe(psIntfAdapter->udev,0), | |
| 38 | − 0x02, | |
| 39 | − 0xC2, | |
| 40 | − (addr & 0xFFFF), | |
| 41 | − ((addr >> 16) & 0xFFFF), | |
| 42 | − buff, | |
| 43 | − len, | |
| 44 | − 5000); | |
| 45 | − | |
| 46 | − usRetries++ ; | |
| 47 | − if(-ENODEV == retval) | |
| 48 | − { | |
| 49 | − psIntfAdapter->psAdapter->device_removed =TRUE; | |
| 34 | + usb_rcvctrlpipe(psIntfAdapter->udev, 0), | |
| 35 | + 0x02, | |
| 36 | + 0xC2, | |
| 37 | + (addr & 0xFFFF), | |
| 38 | + ((addr >> 16) & 0xFFFF), | |
| 39 | + buff, | |
| 40 | + len, | |
| 41 | + 5000); | |
| 42 | + | |
| 43 | + usRetries++; | |
| 44 | + if (-ENODEV == retval) { | |
| 45 | + psIntfAdapter->psAdapter->device_removed = TRUE; | |
| 50 | 46 | break; |
| 51 | 47 | } |
| 52 | 48 | |
| 53 | − }while((retval < 0) && (usRetries < MAX_RDM_WRM_RETIRES ) ); | |
| 49 | + } while ((retval < 0) && (usRetries < MAX_RDM_WRM_RETIRES)); | |
| 54 | 50 | |
| 55 | − if(retval < 0) | |
| 56 | − { | |
| 57 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM failed status :%d, retires :%d", retval,usRetries); | |
| 58 | − psIntfAdapter->psAdapter->DeviceAccess = FALSE ; | |
| 59 | − return retval; | |
| 60 | − } | |
| 61 | − else | |
| 62 | − { | |
| 63 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM sent %d", retval); | |
| 64 | − psIntfAdapter->psAdapter->DeviceAccess = FALSE ; | |
| 65 | − return STATUS_SUCCESS; | |
| 51 | + if (retval < 0) { | |
| 52 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM failed status :%d, retires :%d", retval, usRetries); | |
| 53 | + psIntfAdapter->psAdapter->DeviceAccess = FALSE; | |
| 54 | + return retval; | |
| 55 | + } else { | |
| 56 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM sent %d", retval); | |
| 57 | + psIntfAdapter->psAdapter->DeviceAccess = FALSE; | |
| 58 | + return STATUS_SUCCESS; | |
| 66 | 59 | } |
| 67 | 60 | } |
| 68 | 61 | |
| 69 | −INT | |
| 70 | −InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter, | |
| 71 | − UINT addr, | |
| 72 | − PVOID buff, | |
| 73 | − INT len) | |
| 62 | +INT InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter, | |
| 63 | + UINT addr, | |
| 64 | + PVOID buff, | |
| 65 | + INT len) | |
| 74 | 66 | { |
| 75 | 67 | int retval = 0; |
| 76 | − USHORT usRetries = 0 ; | |
| 68 | + USHORT usRetries = 0; | |
| 77 | 69 | |
| 78 | − if(psIntfAdapter == NULL ) | |
| 79 | − { | |
| 80 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL"); | |
| 70 | + if (psIntfAdapter == NULL) { | |
| 71 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL"); | |
| 81 | 72 | return -EINVAL; |
| 82 | 73 | } |
| 83 | − if(psIntfAdapter->psAdapter->device_removed == TRUE) | |
| 84 | − { | |
| 85 | 74 | |
| 86 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Device got removed"); | |
| 75 | + if (psIntfAdapter->psAdapter->device_removed == TRUE) { | |
| 76 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Device got removed"); | |
| 87 | 77 | return -ENODEV; |
| 88 | 78 | } |
| 89 | 79 | |
| 90 | − if((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB)) | |
| 91 | − { | |
| 92 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL,"Currently Xaction is not allowed on the bus..."); | |
| 80 | + if ((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB)) { | |
| 81 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "Currently Xaction is not allowed on the bus..."); | |
| 93 | 82 | return -EACCES; |
| 94 | 83 | } |
| 95 | 84 | |
| 96 | − if(psIntfAdapter->bSuspended ==TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE) | |
| 97 | − { | |
| 98 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL,"Bus is in suspended states hence RDM not allowed.."); | |
| 85 | + if (psIntfAdapter->bSuspended == TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE) { | |
| 86 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "Bus is in suspended states hence RDM not allowed.."); | |
| 99 | 87 | return -EACCES; |
| 100 | 88 | } |
| 101 | − psIntfAdapter->psAdapter->DeviceAccess = TRUE ; | |
| 102 | − do{ | |
| 89 | + | |
| 90 | + psIntfAdapter->psAdapter->DeviceAccess = TRUE; | |
| 91 | + | |
| 92 | + do { | |
| 103 | 93 | retval = usb_control_msg(psIntfAdapter->udev, |
| 104 | − usb_sndctrlpipe(psIntfAdapter->udev,0), | |
| 105 | − 0x01, | |
| 106 | − 0x42, | |
| 107 | − (addr & 0xFFFF), | |
| 108 | − ((addr >> 16) & 0xFFFF), | |
| 109 | − buff, | |
| 110 | − len, | |
| 111 | − 5000); | |
| 112 | − | |
| 113 | − usRetries++ ; | |
| 114 | − if(-ENODEV == retval) | |
| 115 | − { | |
| 116 | − psIntfAdapter->psAdapter->device_removed = TRUE ; | |
| 94 | + usb_sndctrlpipe(psIntfAdapter->udev, 0), | |
| 95 | + 0x01, | |
| 96 | + 0x42, | |
| 97 | + (addr & 0xFFFF), | |
| 98 | + ((addr >> 16) & 0xFFFF), | |
| 99 | + buff, | |
| 100 | + len, | |
| 101 | + 5000); | |
| 102 | + | |
| 103 | + usRetries++; | |
| 104 | + if (-ENODEV == retval) { | |
| 105 | + psIntfAdapter->psAdapter->device_removed = TRUE; | |
| 117 | 106 | break; |
| 118 | 107 | } |
| 119 | 108 | |
| 120 | − }while((retval < 0) && ( usRetries < MAX_RDM_WRM_RETIRES)); | |
| 109 | + } while ((retval < 0) && (usRetries < MAX_RDM_WRM_RETIRES)); | |
| 121 | 110 | |
| 122 | − if(retval < 0) | |
| 123 | − { | |
| 124 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM failed status :%d, retires :%d", retval, usRetries); | |
| 125 | − psIntfAdapter->psAdapter->DeviceAccess = FALSE ; | |
| 111 | + if (retval < 0) { | |
| 112 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM failed status :%d, retires :%d", retval, usRetries); | |
| 113 | + psIntfAdapter->psAdapter->DeviceAccess = FALSE; | |
| 126 | 114 | return retval; |
| 127 | − } | |
| 128 | − else | |
| 129 | − { | |
| 130 | − psIntfAdapter->psAdapter->DeviceAccess = FALSE ; | |
| 131 | − BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM sent %d", retval); | |
| 115 | + } else { | |
| 116 | + psIntfAdapter->psAdapter->DeviceAccess = FALSE; | |
| 117 | + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM sent %d", retval); | |
| 132 | 118 | return STATUS_SUCCESS; |
| 133 | − | |
| 134 | 119 | } |
| 135 | − | |
| 136 | 120 | } |
| 137 | 121 | |
| 138 | −INT | |
| 139 | −BcmRDM(PVOID arg, | |
| 140 | − UINT addr, | |
| 141 | − PVOID buff, | |
| 142 | − INT len) | |
| 122 | +INT BcmRDM(PVOID arg, | |
| 123 | + UINT addr, | |
| 124 | + PVOID buff, | |
| 125 | + INT len) | |
| 143 | 126 | { |
| 144 | 127 | return InterfaceRDM((PS_INTERFACE_ADAPTER)arg, addr, buff, len); |
| 145 | 128 | } |
| 146 | 129 | |
| 147 | −INT | |
| 148 | −BcmWRM(PVOID arg, | |
| 149 | − UINT addr, | |
| 150 | − PVOID buff, | |
| 151 | − INT len) | |
| 130 | +INT BcmWRM(PVOID arg, | |
| 131 | + UINT addr, | |
| 132 | + PVOID buff, | |
| 133 | + INT len) | |
| 152 | 134 | { |
| 153 | 135 | return InterfaceWRM((PS_INTERFACE_ADAPTER)arg, addr, buff, len); |
| 154 | 136 | } |
| 155 | 137 | |
| 156 | − | |
| 157 | − | |
| 158 | 138 | INT Bcm_clear_halt_of_endpoints(PMINI_ADAPTER Adapter) |
| 159 | 139 | { |
| 160 | 140 | PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter); |
| 161 | − INT status = STATUS_SUCCESS ; | |
| 141 | + INT status = STATUS_SUCCESS; | |
| 162 | 142 | |
| 163 | 143 | /* |
| 164 | − usb_clear_halt - tells device to clear endpoint halt/stall condition | |
| 165 | − @dev: device whose endpoint is halted | |
| 166 | − @pipe: endpoint "pipe" being cleared | |
| 167 | − @ Context: !in_interrupt () | |
| 168 | − | |
| 169 | − usb_clear_halt is the synchrnous call and returns 0 on success else returns with error code. | |
| 170 | − This is used to clear halt conditions for bulk and interrupt endpoints only. | |
| 171 | − Control and isochronous endpoints never halts. | |
| 172 | − | |
| 173 | − Any URBs queued for such an endpoint should normally be unlinked by the driver | |
| 174 | − before clearing the halt condition. | |
| 175 | − | |
| 176 | − */ | |
| 177 | − | |
| 178 | − //Killing all the submitted urbs to different end points. | |
| 144 | + * usb_clear_halt - tells device to clear endpoint halt/stall condition | |
| 145 | + * @dev: device whose endpoint is halted | |
| 146 | + * @pipe: endpoint "pipe" being cleared | |
| 147 | + * @ Context: !in_interrupt () | |
| 148 | + * | |
| 149 | + * usb_clear_halt is the synchrnous call and returns 0 on success else returns with error code. | |
| 150 | + * This is used to clear halt conditions for bulk and interrupt endpoints only. | |
| 151 | + * Control and isochronous endpoints never halts. | |
| 152 | + * | |
| 153 | + * Any URBs queued for such an endpoint should normally be unlinked by the driver | |
| 154 | + * before clearing the halt condition. | |
| 155 | + * | |
| 156 | + */ | |
| 157 | + | |
| 158 | + /* Killing all the submitted urbs to different end points. */ | |
| 179 | 159 | Bcm_kill_all_URBs(psIntfAdapter); |
| 180 | 160 | |
| 161 | + /* clear the halted/stalled state for every end point */ | |
| 162 | + status = usb_clear_halt(psIntfAdapter->udev, psIntfAdapter->sIntrIn.int_in_pipe); | |
| 163 | + if (status != STATUS_SUCCESS) | |
| 164 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Interrupt IN end point. :%d ", status); | |
| 181 | 165 | |
| 182 | − //clear the halted/stalled state for every end point | |
| 183 | − status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sIntrIn.int_in_pipe); | |
| 184 | − if(status != STATUS_SUCCESS) | |
| 185 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Interrupt IN end point. :%d ", status); | |
| 166 | + status = usb_clear_halt(psIntfAdapter->udev, psIntfAdapter->sBulkIn.bulk_in_pipe); | |
| 167 | + if (status != STATUS_SUCCESS) | |
| 168 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk IN end point. :%d ", status); | |
| 186 | 169 | |
| 187 | − status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sBulkIn.bulk_in_pipe); | |
| 188 | − if(status != STATUS_SUCCESS) | |
| 189 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk IN end point. :%d ", status); | |
| 170 | + status = usb_clear_halt(psIntfAdapter->udev, psIntfAdapter->sBulkOut.bulk_out_pipe); | |
| 171 | + if (status != STATUS_SUCCESS) | |
| 172 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk OUT end point. :%d ", status); | |
| 190 | 173 | |
| 191 | − status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sBulkOut.bulk_out_pipe); | |
| 192 | − if(status != STATUS_SUCCESS) | |
| 193 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk OUT end point. :%d ", status); | |
| 194 | − | |
| 195 | − return status ; | |
| 174 | + return status; | |
| 196 | 175 | } |
| 197 | 176 | |
| 198 | − | |
| 199 | 177 | VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter) |
| 200 | 178 | { |
| 201 | 179 | struct urb *tempUrb = NULL; |
| 202 | 180 | UINT i; |
| 203 | 181 | |
| 204 | − /** | |
| 205 | − * usb_kill_urb - cancel a transfer request and wait for it to finish | |
| 206 | − * @urb: pointer to URB describing a previously submitted request, | |
| 207 | − * returns nothing as it is void returned API. | |
| 208 | − * | |
| 209 | − * This routine cancels an in-progress request. It is guaranteed that | |
| 210 | − * upon return all completion handlers will have finished and the URB | |
| 211 | − * will be totally idle and available for reuse | |
| 212 | − | |
| 213 | − * This routine may not be used in an interrupt context (such as a bottom | |
| 214 | − * half or a completion handler), or when holding a spinlock, or in other | |
| 215 | − * situations where the caller can't schedule(). | |
| 216 | − * | |
| 217 | − **/ | |
| 182 | + /* | |
| 183 | + * usb_kill_urb - cancel a transfer request and wait for it to finish | |
| 184 | + * @urb: pointer to URB describing a previously submitted request, | |
| 185 | + * returns nothing as it is void returned API. | |
| 186 | + * | |
| 187 | + * This routine cancels an in-progress request. It is guaranteed that | |
| 188 | + * upon return all completion handlers will have finished and the URB | |
| 189 | + * will be totally idle and available for reuse | |
| 190 | + * | |
| 191 | + * This routine may not be used in an interrupt context (such as a bottom | |
| 192 | + * half or a completion handler), or when holding a spinlock, or in other | |
| 193 | + * situations where the caller can't schedule(). | |
| 194 | + * | |
| 195 | + */ | |
| 218 | 196 | |
| 219 | 197 | /* Cancel submitted Interrupt-URB's */ |
| 220 | − if(psIntfAdapter->psInterruptUrb != NULL) | |
| 221 | − { | |
| 222 | − if(psIntfAdapter->psInterruptUrb->status == -EINPROGRESS) | |
| 223 | − usb_kill_urb(psIntfAdapter->psInterruptUrb); | |
| 198 | + if (psIntfAdapter->psInterruptUrb != NULL) { | |
| 199 | + if (psIntfAdapter->psInterruptUrb->status == -EINPROGRESS) | |
| 200 | + usb_kill_urb(psIntfAdapter->psInterruptUrb); | |
| 224 | 201 | } |
| 225 | 202 | |
| 226 | 203 | /* Cancel All submitted TX URB's */ |
| 227 | − for(i = 0; i < MAXIMUM_USB_TCB; i++) | |
| 228 | − { | |
| 204 | + for (i = 0; i < MAXIMUM_USB_TCB; i++) { | |
| 229 | 205 | tempUrb = psIntfAdapter->asUsbTcb[i].urb; |
| 230 | − if(tempUrb) | |
| 231 | − { | |
| 232 | − if(tempUrb->status == -EINPROGRESS) | |
| 206 | + if (tempUrb) { | |
| 207 | + if (tempUrb->status == -EINPROGRESS) | |
| 233 | 208 | usb_kill_urb(tempUrb); |
| 234 | 209 | } |
| 235 | 210 | } |
| 236 | 211 | |
| 237 | − for(i = 0; i < MAXIMUM_USB_RCB; i++) | |
| 238 | − { | |
| 212 | + for (i = 0; i < MAXIMUM_USB_RCB; i++) { | |
| 239 | 213 | tempUrb = psIntfAdapter->asUsbRcb[i].urb; |
| 240 | − if(tempUrb) | |
| 241 | − { | |
| 242 | − if(tempUrb->status == -EINPROGRESS) | |
| 243 | − usb_kill_urb(tempUrb); | |
| 214 | + if (tempUrb) { | |
| 215 | + if (tempUrb->status == -EINPROGRESS) | |
| 216 | + usb_kill_urb(tempUrb); | |
| 244 | 217 | } |
| 245 | 218 | } |
| 246 | 219 | |
| @@ -253,13 +226,12 @@ VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter) · 6 unmodified lines | ||
| 253 | 226 | |
| 254 | 227 | VOID putUsbSuspend(struct work_struct *work) |
| 255 | 228 | { |
| 256 | − PS_INTERFACE_ADAPTER psIntfAdapter = NULL ; | |
| 257 | − struct usb_interface *intf = NULL ; | |
| 258 | − psIntfAdapter = container_of(work, S_INTERFACE_ADAPTER,usbSuspendWork); | |
| 259 | − intf=psIntfAdapter->interface ; | |
| 229 | + PS_INTERFACE_ADAPTER psIntfAdapter = NULL; | |
| 230 | + struct usb_interface *intf = NULL; | |
| 231 | + psIntfAdapter = container_of(work, S_INTERFACE_ADAPTER, usbSuspendWork); | |
| 232 | + intf = psIntfAdapter->interface; | |
| 260 | 233 | |
| 261 | − if(psIntfAdapter->bSuspended == FALSE) | |
| 234 | + if (psIntfAdapter->bSuspended == FALSE) | |
| 262 | 235 | usb_autopm_put_interface(intf); |
| 263 | − | |
| 264 | 236 | } |
| 265 | 237 | |
| @@ -1,17 +1,17 @@ | ||
| 1 | 1 | /************************************* |
| 2 | −* Macros.h | |
| 2 | +* Macros.h | |
| 3 | 3 | **************************************/ |
| 4 | −#ifndef __MACROS_H__ | |
| 4 | +#ifndef __MACROS_H__ | |
| 5 | 5 | #define __MACROS_H__ |
| 6 | 6 | |
| 7 | −#define TX_TIMER_PERIOD 10 //10 msec | |
| 7 | +#define TX_TIMER_PERIOD 10 /*10 msec*/ | |
| 8 | 8 | #define MAX_CLASSIFIERS 100 |
| 9 | −//#define MAX_CLASSIFIERS_PER_SF 20 | |
| 9 | +/* #define MAX_CLASSIFIERS_PER_SF 20 */ | |
| 10 | 10 | #define MAX_TARGET_DSX_BUFFERS 24 |
| 11 | 11 | |
| 12 | −#define MAX_CNTRL_PKTS 100 | |
| 13 | −#define MAX_DATA_PKTS 200 | |
| 14 | −#define MAX_ETH_SIZE 1536 | |
| 12 | +#define MAX_CNTRL_PKTS 100 | |
| 13 | +#define MAX_DATA_PKTS 200 | |
| 14 | +#define MAX_ETH_SIZE 1536 | |
| 15 | 15 | #define MAX_CNTL_PKT_SIZE 2048 |
| 16 | 16 | |
| 17 | 17 | #define MTU_SIZE 1400 |
| @@ -20,102 +20,102 @@ · 2 unmodified lines | ||
| 20 | 20 | #define MAC_ADDR_REGISTER 0xbf60d000 |
| 21 | 21 | |
| 22 | 22 | |
| 23 | −///////////Quality of Service/////////////////////////// | |
| 24 | −#define NO_OF_QUEUES 17 | |
| 25 | −#define HiPriority NO_OF_QUEUES-1 | |
| 26 | −#define LowPriority 0 | |
| 27 | −#define BE 2 | |
| 28 | −#define rtPS 4 | |
| 29 | −#define ERTPS 5 | |
| 30 | −#define UGS 6 | |
| 31 | − | |
| 32 | −#define BE_BUCKET_SIZE 1024*1024*100 //32kb | |
| 33 | −#define rtPS_BUCKET_SIZE 1024*1024*100 //8kb | |
| 34 | −#define MAX_ALLOWED_RATE 1024*1024*100 | |
| 35 | −#define TX_PACKET_THRESHOLD 10 | |
| 36 | −#define XSECONDS 1*HZ | |
| 37 | −#define DSC_ACTIVATE_REQUEST 248 | |
| 38 | −#define QUEUE_DEPTH_OFFSET 0x1fc01000 | |
| 39 | −#define MAX_DEVICE_DESC_SIZE 2040 | |
| 40 | −#define MAX_CTRL_QUEUE_LEN 100 | |
| 41 | −#define MAX_APP_QUEUE_LEN 200 | |
| 42 | −#define MAX_LATENCY_ALLOWED 0xFFFFFFFF | |
| 43 | −#define DEFAULT_UG_INTERVAL 250 | |
| 44 | −#define DEFAULT_UGI_FACTOR 4 | |
| 45 | − | |
| 46 | −#define DEFAULT_PERSFCOUNT 60 | |
| 47 | −#define MAX_CONNECTIONS 10 | |
| 48 | −#define MAX_CLASS_NAME_LENGTH 32 | |
| 49 | − | |
| 50 | −#define ETH_LENGTH_OF_ADDRESS 6 | |
| 51 | −#define MAX_MULTICAST_ADDRESSES 32 | |
| 52 | −#define IP_LENGTH_OF_ADDRESS 4 | |
| 53 | − | |
| 54 | −#define IP_PACKET_ONLY_MODE 0 | |
| 55 | −#define ETH_PACKET_TUNNELING_MODE 1 | |
| 56 | − | |
| 57 | −////////////Link Request////////////// | |
| 58 | −#define SET_MAC_ADDRESS_REQUEST 0 | |
| 59 | −#define SYNC_UP_REQUEST 1 | |
| 60 | −#define SYNCED_UP 2 | |
| 61 | −#define LINK_UP_REQUEST 3 | |
| 62 | −#define LINK_CONNECTED 4 | |
| 63 | −#define SYNC_UP_NOTIFICATION 2 | |
| 64 | −#define LINK_UP_NOTIFICATION 4 | |
| 23 | +/* Quality of Service */ | |
| 24 | +#define NO_OF_QUEUES 17 | |
| 25 | +#define HiPriority (NO_OF_QUEUES-1) | |
| 26 | +#define LowPriority 0 | |
| 27 | +#define BE 2 | |
| 28 | +#define rtPS 4 | |
| 29 | +#define ERTPS 5 | |
| 30 | +#define UGS 6 | |
| 31 | + | |
| 32 | +#define BE_BUCKET_SIZE (1024*1024*100) /* 32kb */ | |
| 33 | +#define rtPS_BUCKET_SIZE (1024*1024*100) /* 8kb */ | |
| 34 | +#define MAX_ALLOWED_RATE (1024*1024*100) | |
| 35 | +#define TX_PACKET_THRESHOLD 10 | |
| 36 | +#define XSECONDS (1*HZ) | |
| 37 | +#define DSC_ACTIVATE_REQUEST 248 | |
| 38 | +#define QUEUE_DEPTH_OFFSET 0x1fc01000 | |
| 39 | +#define MAX_DEVICE_DESC_SIZE 2040 | |
| 40 | +#define MAX_CTRL_QUEUE_LEN 100 | |
| 41 | +#define MAX_APP_QUEUE_LEN 200 | |
| 42 | +#define MAX_LATENCY_ALLOWED 0xFFFFFFFF | |
| 43 | +#define DEFAULT_UG_INTERVAL 250 | |
| 44 | +#define DEFAULT_UGI_FACTOR 4 | |
| 45 | + | |
| 46 | +#define DEFAULT_PERSFCOUNT 60 | |
| 47 | +#define MAX_CONNECTIONS 10 | |
| 48 | +#define MAX_CLASS_NAME_LENGTH 32 | |
| 49 | + | |
| 50 | +#define ETH_LENGTH_OF_ADDRESS 6 | |
| 51 | +#define MAX_MULTICAST_ADDRESSES 32 | |
| 52 | +#define IP_LENGTH_OF_ADDRESS 4 | |
| 53 | + | |
| 54 | +#define IP_PACKET_ONLY_MODE 0 | |
| 55 | +#define ETH_PACKET_TUNNELING_MODE 1 | |
| 56 | + | |
| 57 | +/* Link Request */ | |
| 58 | +#define SET_MAC_ADDRESS_REQUEST 0 | |
| 59 | +#define SYNC_UP_REQUEST 1 | |
| 60 | +#define SYNCED_UP 2 | |
| 61 | +#define LINK_UP_REQUEST 3 | |
| 62 | +#define LINK_CONNECTED 4 | |
| 63 | +#define SYNC_UP_NOTIFICATION 2 | |
| 64 | +#define LINK_UP_NOTIFICATION 4 | |
| 65 | 65 | |
| 66 | 66 | |
| 67 | 67 | #define LINK_NET_ENTRY 0x0002 |
| 68 | −#define HMC_STATUS 0x0004 | |
| 68 | +#define HMC_STATUS 0x0004 | |
| 69 | 69 | #define LINK_UP_CONTROL_REQ 0x83 |
| 70 | 70 | |
| 71 | 71 | #define STATS_POINTER_REQ_STATUS 0x86 |
| 72 | 72 | #define NETWORK_ENTRY_REQ_PAYLOAD 198 |
| 73 | −#define LINK_DOWN_REQ_PAYLOAD 226 | |
| 73 | +#define LINK_DOWN_REQ_PAYLOAD 226 | |
| 74 | 74 | #define SYNC_UP_REQ_PAYLOAD 228 |
| 75 | −#define STATISTICS_POINTER_REQ 237 | |
| 75 | +#define STATISTICS_POINTER_REQ 237 | |
| 76 | 76 | #define LINK_UP_REQ_PAYLOAD 245 |
| 77 | 77 | #define LINK_UP_ACK 246 |
| 78 | 78 | |
| 79 | 79 | #define STATS_MSG_SIZE 4 |
| 80 | 80 | #define INDEX_TO_DATA 4 |
| 81 | 81 | |
| 82 | −#define GO_TO_IDLE_MODE_PAYLOAD 210 | |
| 83 | −#define COME_UP_FROM_IDLE_MODE_PAYLOAD 211 | |
| 84 | −#define IDLE_MODE_SF_UPDATE_MSG 187 | |
| 82 | +#define GO_TO_IDLE_MODE_PAYLOAD 210 | |
| 83 | +#define COME_UP_FROM_IDLE_MODE_PAYLOAD 211 | |
| 84 | +#define IDLE_MODE_SF_UPDATE_MSG 187 | |
| 85 | 85 | |
| 86 | −#define SKB_RESERVE_ETHERNET_HEADER 16 | |
| 87 | −#define SKB_RESERVE_PHS_BYTES 32 | |
| 86 | +#define SKB_RESERVE_ETHERNET_HEADER 16 | |
| 87 | +#define SKB_RESERVE_PHS_BYTES 32 | |
| 88 | 88 | |
| 89 | −#define IP_PACKET_ONLY_MODE 0 | |
| 90 | −#define ETH_PACKET_TUNNELING_MODE 1 | |
| 89 | +#define IP_PACKET_ONLY_MODE 0 | |
| 90 | +#define ETH_PACKET_TUNNELING_MODE 1 | |
| 91 | 91 | |
| 92 | −#define ETH_CS_802_3 1 | |
| 93 | −#define ETH_CS_802_1Q_VLAN 3 | |
| 94 | −#define IPV4_CS 1 | |
| 95 | −#define IPV6_CS 2 | |
| 96 | −#define ETH_CS_MASK 0x3f | |
| 92 | +#define ETH_CS_802_3 1 | |
| 93 | +#define ETH_CS_802_1Q_VLAN 3 | |
| 94 | +#define IPV4_CS 1 | |
| 95 | +#define IPV6_CS 2 | |
| 96 | +#define ETH_CS_MASK 0x3f | |
| 97 | 97 | |
| 98 | 98 | /** \brief Validity bit maps for TLVs in packet classification rule */ |
| 99 | 99 | |
| 100 | −#define PKT_CLASSIFICATION_USER_PRIORITY_VALID 0 | |
| 101 | −#define PKT_CLASSIFICATION_VLANID_VALID 1 | |
| 100 | +#define PKT_CLASSIFICATION_USER_PRIORITY_VALID 0 | |
| 101 | +#define PKT_CLASSIFICATION_VLANID_VALID 1 | |
| 102 | 102 | |
| 103 | 103 | #ifndef MIN |
| 104 | −#define MIN(_a, _b) ((_a) < (_b)? (_a): (_b)) | |
| 104 | +#define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b)) | |
| 105 | 105 | #endif |
| 106 | 106 | |
| 107 | 107 | |
| 108 | 108 | /*Leader related terms */ |
| 109 | −#define LEADER_STATUS 0x00 | |
| 110 | −#define LEADER_STATUS_TCP_ACK 0x1 | |
| 111 | −#define LEADER_SIZE sizeof(LEADER) | |
| 112 | −#define MAC_ADDR_REQ_SIZE sizeof(PACKETTOSEND) | |
| 113 | −#define SS_INFO_REQ_SIZE sizeof(PACKETTOSEND) | |
| 114 | −#define CM_REQUEST_SIZE LEADER_SIZE + sizeof(stLocalSFChangeRequest) | |
| 115 | −#define IDLE_REQ_SIZE sizeof(PACKETTOSEND) | |
| 109 | +#define LEADER_STATUS 0x00 | |
| 110 | +#define LEADER_STATUS_TCP_ACK 0x1 | |
| 111 | +#define LEADER_SIZE sizeof(LEADER) | |
| 112 | +#define MAC_ADDR_REQ_SIZE sizeof(PACKETTOSEND) | |
| 113 | +#define SS_INFO_REQ_SIZE sizeof(PACKETTOSEND) | |
| 114 | +#define CM_REQUEST_SIZE (LEADER_SIZE + sizeof(stLocalSFChangeRequest)) | |
| 115 | +#define IDLE_REQ_SIZE sizeof(PACKETTOSEND) | |
| 116 | 116 | |
| 117 | 117 | |
| 118 | −#define MAX_TRANSFER_CTRL_BYTE_USB 2 * 1024 | |
| 118 | +#define MAX_TRANSFER_CTRL_BYTE_USB (2*1024) | |
| 119 | 119 | |
| 120 | 120 | #define GET_MAILBOX1_REG_REQUEST 0x87 |
| 121 | 121 | #define GET_MAILBOX1_REG_RESPONSE 0x67 |
| @@ -124,40 +124,40 @@ · 2 unmodified lines | ||
| 124 | 124 | #define TRANSMIT_NETWORK_DATA 0x00 |
| 125 | 125 | #define RECEIVED_NETWORK_DATA 0x20 |
| 126 | 126 | |
| 127 | −#define CM_RESPONSES 0xA0 | |
| 128 | −#define STATUS_RSP 0xA1 | |
| 129 | −#define LINK_CONTROL_RESP 0xA2 | |
| 130 | −#define IDLE_MODE_STATUS 0xA3 | |
| 131 | −#define STATS_POINTER_RESP 0xA6 | |
| 132 | −#define MGMT_MSG_INFO_SW_STATUS 0xA7 | |
| 133 | −#define AUTH_SS_HOST_MSG 0xA8 | |
| 134 | − | |
| 135 | −#define CM_DSA_ACK_PAYLOAD 247 | |
| 136 | −#define CM_DSC_ACK_PAYLOAD 248 | |
| 137 | −#define CM_DSD_ACK_PAYLOAD 249 | |
| 138 | −#define CM_DSDEACTVATE 250 | |
| 139 | −#define TOTAL_MASKED_ADDRESS_IN_BYTES 32 | |
| 140 | − | |
| 141 | −#define MAC_REQ 0 | |
| 142 | −#define LINK_RESP 1 | |
| 143 | −#define RSSI_INDICATION 2 | |
| 144 | − | |
| 145 | −#define SS_INFO 4 | |
| 146 | −#define STATISTICS_INFO 5 | |
| 147 | −#define CM_INDICATION 6 | |
| 148 | −#define PARAM_RESP 7 | |
| 149 | −#define BUFFER_1K 1024 | |
| 150 | −#define BUFFER_2K BUFFER_1K*2 | |
| 151 | −#define BUFFER_4K BUFFER_2K*2 | |
| 152 | −#define BUFFER_8K BUFFER_4K*2 | |
| 153 | −#define BUFFER_16K BUFFER_8K*2 | |
| 154 | −#define DOWNLINK_DIR 0 | |
| 155 | −#define UPLINK_DIR 1 | |
| 156 | − | |
| 157 | −#define BCM_SIGNATURE "BECEEM" | |
| 158 | − | |
| 159 | − | |
| 160 | −#define GPIO_OUTPUT_REGISTER 0x0F00003C | |
| 127 | +#define CM_RESPONSES 0xA0 | |
| 128 | +#define STATUS_RSP 0xA1 | |
| 129 | +#define LINK_CONTROL_RESP 0xA2 | |
| 130 | +#define IDLE_MODE_STATUS 0xA3 | |
| 131 | +#define STATS_POINTER_RESP 0xA6 | |
| 132 | +#define MGMT_MSG_INFO_SW_STATUS 0xA7 | |
| 133 | +#define AUTH_SS_HOST_MSG 0xA8 | |
| 134 | + | |
| 135 | +#define CM_DSA_ACK_PAYLOAD 247 | |
| 136 | +#define CM_DSC_ACK_PAYLOAD 248 | |
| 137 | +#define CM_DSD_ACK_PAYLOAD 249 | |
| 138 | +#define CM_DSDEACTVATE 250 | |
| 139 | +#define TOTAL_MASKED_ADDRESS_IN_BYTES 32 | |
| 140 | + | |
| 141 | +#define MAC_REQ 0 | |
| 142 | +#define LINK_RESP 1 | |
| 143 | +#define RSSI_INDICATION 2 | |
| 144 | + | |
| 145 | +#define SS_INFO 4 | |
| 146 | +#define STATISTICS_INFO 5 | |
| 147 | +#define CM_INDICATION 6 | |
| 148 | +#define PARAM_RESP 7 | |
| 149 | +#define BUFFER_1K 1024 | |
| 150 | +#define BUFFER_2K (BUFFER_1K*2) | |
| 151 | +#define BUFFER_4K (BUFFER_2K*2) | |
| 152 | +#define BUFFER_8K (BUFFER_4K*2) | |
| 153 | +#define BUFFER_16K (BUFFER_8K*2) | |
| 154 | +#define DOWNLINK_DIR 0 | |
| 155 | +#define UPLINK_DIR 1 | |
| 156 | + | |
| 157 | +#define BCM_SIGNATURE "BECEEM" | |
| 158 | + | |
| 159 | + | |
| 160 | +#define GPIO_OUTPUT_REGISTER 0x0F00003C | |
| 161 | 161 | #define BCM_GPIO_OUTPUT_SET_REG 0x0F000040 |
| 162 | 162 | #define BCM_GPIO_OUTPUT_CLR_REG 0x0F000044 |
| 163 | 163 | #define GPIO_MODE_REGISTER 0x0F000034 |
| @@ -165,44 +165,43 @@ · 1 unmodified line | ||
| 165 | 165 | |
| 166 | 166 | |
| 167 | 167 | typedef struct _LINK_STATE { |
| 168 | − UCHAR ucLinkStatus; | |
| 169 | − UCHAR bIdleMode; | |
| 170 | − UCHAR bShutdownMode; | |
| 171 | −}LINK_STATE, *PLINK_STATE; | |
| 168 | + UCHAR ucLinkStatus; | |
| 169 | + UCHAR bIdleMode; | |
| 170 | + UCHAR bShutdownMode; | |
| 171 | +} LINK_STATE, *PLINK_STATE; | |
| 172 | 172 | |
| 173 | 173 | |
| 174 | 174 | enum enLinkStatus { |
| 175 | − WAIT_FOR_SYNC = 1, | |
| 176 | − PHY_SYNC_ACHIVED = 2, | |
| 177 | − LINKUP_IN_PROGRESS = 3, | |
| 178 | − LINKUP_DONE = 4, | |
| 179 | − DREG_RECEIVED = 5, | |
| 180 | − LINK_STATUS_RESET_RECEIVED = 6, | |
| 181 | − PERIODIC_WAKE_UP_NOTIFICATION_FRM_FW = 7, | |
| 182 | − LINK_SHUTDOWN_REQ_FROM_FIRMWARE = 8, | |
| 183 | − COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW =9 | |
| 175 | + WAIT_FOR_SYNC = 1, | |
| 176 | + PHY_SYNC_ACHIVED = 2, | |
| 177 | + LINKUP_IN_PROGRESS = 3, | |
| 178 | + LINKUP_DONE = 4, | |
| 179 | + DREG_RECEIVED = 5, | |
| 180 | + LINK_STATUS_RESET_RECEIVED = 6, | |
| 181 | + PERIODIC_WAKE_UP_NOTIFICATION_FRM_FW = 7, | |
| 182 | + LINK_SHUTDOWN_REQ_FROM_FIRMWARE = 8, | |
| 183 | + COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW = 9 | |
| 184 | 184 | }; |
| 185 | 185 | |
| 186 | −typedef enum _E_PHS_DSC_ACTION | |
| 187 | −{ | |
| 188 | − eAddPHSRule=0, | |
| 186 | +typedef enum _E_PHS_DSC_ACTION { | |
| 187 | + eAddPHSRule = 0, | |
| 189 | 188 | eSetPHSRule, |
| 190 | 189 | eDeletePHSRule, |
| 191 | 190 | eDeleteAllPHSRules |
| 192 | −}E_PHS_DSC_ACTION; | |
| 191 | +} E_PHS_DSC_ACTION; | |
| 193 | 192 | |
| 194 | 193 | |
| 195 | −#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ 0x89 // Host to Mac | |
| 196 | −#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP 0xA9 // Mac to Host | |
| 197 | −#define MASK_DISABLE_HEADER_SUPPRESSION 0x10 //0b000010000 | |
| 198 | −#define MINIMUM_PENDING_DESCRIPTORS 5 | |
| 194 | +#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ 0x89 /* Host to Mac */ | |
| 195 | +#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP 0xA9 /* Mac to Host */ | |
| 196 | +#define MASK_DISABLE_HEADER_SUPPRESSION 0x10 /* 0b000010000 */ | |
| 197 | +#define MINIMUM_PENDING_DESCRIPTORS 5 | |
| 199 | 198 | |
| 200 | 199 | #define SHUTDOWN_HOSTINITIATED_REQUESTPAYLOAD 0xCC |
| 201 | 200 | #define SHUTDOWN_ACK_FROM_DRIVER 0x1 |
| 202 | 201 | #define SHUTDOWN_NACK_FROM_DRIVER 0x2 |
| 203 | 202 | |
| 204 | −#define LINK_SYNC_UP_SUBTYPE 0x0001 | |
| 205 | −#define LINK_SYNC_DOWN_SUBTYPE 0x0001 | |
| 203 | +#define LINK_SYNC_UP_SUBTYPE 0x0001 | |
| 204 | +#define LINK_SYNC_DOWN_SUBTYPE 0x0001 | |
| 206 | 205 | |
| 207 | 206 | |
| 208 | 207 | |
| @@ -226,9 +225,9 @@ typedef enum _E_PHS_DSC_ACTION · 17 unmodified lines | ||
| 226 | 225 | |
| 227 | 226 | #define MAX_PENDING_CTRL_PACKET (MAX_CTRL_QUEUE_LEN-10) |
| 228 | 227 | |
| 229 | −#define WIMAX_MAX_MTU (MTU_SIZE + ETH_HLEN) | |
| 228 | +#define WIMAX_MAX_MTU (MTU_SIZE + ETH_HLEN) | |
| 230 | 229 | #define AUTO_LINKUP_ENABLE 0x2 |
| 231 | −#define AUTO_SYNC_DISABLE 0x1 | |
| 230 | +#define AUTO_SYNC_DISABLE 0x1 | |
| 232 | 231 | #define AUTO_FIRM_DOWNLOAD 0x1 |
| 233 | 232 | #define SETTLE_DOWN_TIME 50 |
| 234 | 233 | |
| @@ -242,9 +241,9 @@ typedef enum _E_PHS_DSC_ACTION · 7 unmodified lines | ||
| 242 | 241 | #define TARGET_CAN_NOT_GO_TO_IDLE_MODE 3 |
| 243 | 242 | #define IDLE_MODE_PAYLOAD_LENGTH 8 |
| 244 | 243 | |
| 245 | −#define IP_HEADER(Buffer) ((IPHeaderFormat*)(Buffer)) | |
| 246 | −#define IPV4 4 | |
| 247 | −#define IP_VERSION(byte) (((byte&0xF0)>>4)) | |
| 244 | +#define IP_HEADER(Buffer) ((IPHeaderFormat *)(Buffer)) | |
| 245 | +#define IPV4 4 | |
| 246 | +#define IP_VERSION(byte) (((byte&0xF0)>>4)) | |
| 248 | 247 | |
| 249 | 248 | #define SET_MAC_ADDRESS 193 |
| 250 | 249 | #define SET_MAC_ADDRESS_RESPONSE 236 |
| @@ -263,15 +262,15 @@ typedef enum _E_PHS_DSC_ACTION · 12 unmodified lines | ||
| 263 | 262 | |
| 264 | 263 | #define INVALID_QUEUE_INDEX NO_OF_QUEUES |
| 265 | 264 | |
| 266 | −#define INVALID_PID (pid_t)-1 | |
| 267 | −#define DDR_80_MHZ 0 | |
| 268 | −#define DDR_100_MHZ 1 | |
| 269 | −#define DDR_120_MHZ 2 // Additional Frequency for T3LP | |
| 270 | −#define DDR_133_MHZ 3 | |
| 271 | −#define DDR_140_MHZ 4 // Not Used (Reserved for future) | |
| 272 | −#define DDR_160_MHZ 5 // Additional Frequency for T3LP | |
| 273 | −#define DDR_180_MHZ 6 // Not Used (Reserved for future) | |
| 274 | −#define DDR_200_MHZ 7 // Not Used (Reserved for future) | |
| 265 | +#define INVALID_PID ((pid_t)-1) | |
| 266 | +#define DDR_80_MHZ 0 | |
| 267 | +#define DDR_100_MHZ 1 | |
| 268 | +#define DDR_120_MHZ 2 /* Additional Frequency for T3LP */ | |
| 269 | +#define DDR_133_MHZ 3 | |
| 270 | +#define DDR_140_MHZ 4 /* Not Used (Reserved for future) */ | |
| 271 | +#define DDR_160_MHZ 5 /* Additional Frequency for T3LP */ | |
| 272 | +#define DDR_180_MHZ 6 /* Not Used (Reserved for future) */ | |
| 273 | +#define DDR_200_MHZ 7 /* Not Used (Reserved for future) */ | |
| 275 | 274 | |
| 276 | 275 | #define MIPS_200_MHZ 0 |
| 277 | 276 | #define MIPS_160_MHZ 1 |
| @@ -291,27 +290,27 @@ typedef enum _E_PHS_DSC_ACTION · 13 unmodified lines | ||
| 291 | 290 | #define EEPROM_REJECT_REG_3 0x0f003008 |
| 292 | 291 | #define EEPROM_REJECT_REG_4 0x0f003020 |
| 293 | 292 | #define EEPROM_REJECT_MASK 0x0fffffff |
| 294 | −#define VSG_MODE 0x3 | |
| 293 | +#define VSG_MODE 0x3 | |
| 295 | 294 | |
| 296 | 295 | /* Idle Mode Related Registers */ |
| 297 | 296 | #define DEBUG_INTERRUPT_GENERATOR_REGISTOR 0x0F00007C |
| 298 | −#define SW_ABORT_IDLEMODE_LOC 0x0FF01FFC | |
| 297 | +#define SW_ABORT_IDLEMODE_LOC 0x0FF01FFC | |
| 299 | 298 | |
| 300 | −#define SW_ABORT_IDLEMODE_PATTERN 0xd0ea1d1e | |
| 301 | −#define DEVICE_INT_OUT_EP_REG0 0x0F011870 | |
| 302 | −#define DEVICE_INT_OUT_EP_REG1 0x0F011874 | |
| 299 | +#define SW_ABORT_IDLEMODE_PATTERN 0xd0ea1d1e | |
| 300 | +#define DEVICE_INT_OUT_EP_REG0 0x0F011870 | |
| 301 | +#define DEVICE_INT_OUT_EP_REG1 0x0F011874 | |
| 303 | 302 | |
| 304 | 303 | #define BIN_FILE "/lib/firmware/macxvi200.bin" |
| 305 | 304 | #define CFG_FILE "/lib/firmware/macxvi.cfg" |
| 306 | 305 | #define SF_MAX_ALLOWED_PACKETS_TO_BACKUP 128 |
| 307 | −#define MIN_VAL(x,y) ((x)<(y)?(x):(y)) | |
| 306 | +#define MIN_VAL(x, y) ((x) < (y) ? (x) : (y)) | |
| 308 | 307 | #define MAC_ADDRESS_SIZE 6 |
| 309 | 308 | #define EEPROM_COMMAND_Q_REG 0x0F003018 |
| 310 | 309 | #define EEPROM_READ_DATA_Q_REG 0x0F003020 |
| 311 | −#define CHIP_ID_REG 0x0F000000 | |
| 312 | −#define GPIO_MODE_REG 0x0F000034 | |
| 313 | −#define GPIO_OUTPUT_REG 0x0F00003C | |
| 314 | −#define WIMAX_MAX_ALLOWED_RATE 1024*1024*50 | |
| 310 | +#define CHIP_ID_REG 0x0F000000 | |
| 311 | +#define GPIO_MODE_REG 0x0F000034 | |
| 312 | +#define GPIO_OUTPUT_REG 0x0F00003C | |
| 313 | +#define WIMAX_MAX_ALLOWED_RATE (1024*1024*50) | |
| 315 | 314 | |
| 316 | 315 | #define T3 0xbece0300 |
| 317 | 316 | #define TARGET_SFID_TXDESC_MAP_LOC 0xBFFFF400 |
| @@ -319,31 +318,29 @@ typedef enum _E_PHS_DSC_ACTION · 1 unmodified line | ||
| 319 | 318 | #define RWM_READ 0 |
| 320 | 319 | #define RWM_WRITE 1 |
| 321 | 320 | |
| 322 | −#define T3LPB 0xbece3300 | |
| 323 | −#define BCS220_2 0xbece3311 | |
| 324 | −#define BCS220_2BC 0xBECE3310 | |
| 325 | −#define BCS250_BC 0xbece3301 | |
| 326 | −#define BCS220_3 0xbece3321 | |
| 321 | +#define T3LPB 0xbece3300 | |
| 322 | +#define BCS220_2 0xbece3311 | |
| 323 | +#define BCS220_2BC 0xBECE3310 | |
| 324 | +#define BCS250_BC 0xbece3301 | |
| 325 | +#define BCS220_3 0xbece3321 | |
| 327 | 326 | |
| 328 | 327 | |
| 329 | −#define HPM_CONFIG_LDO145 0x0F000D54 | |
| 330 | −#define HPM_CONFIG_MSW 0x0F000D58 | |
| 328 | +#define HPM_CONFIG_LDO145 0x0F000D54 | |
| 329 | +#define HPM_CONFIG_MSW 0x0F000D58 | |
| 331 | 330 | |
| 332 | 331 | #define T3B 0xbece0310 |
| 333 | −typedef enum eNVM_TYPE | |
| 334 | −{ | |
| 332 | +typedef enum eNVM_TYPE { | |
| 335 | 333 | NVM_AUTODETECT = 0, |
| 336 | 334 | NVM_EEPROM, |
| 337 | 335 | NVM_FLASH, |
| 338 | 336 | NVM_UNKNOWN |
| 339 | −}NVM_TYPE; | |
| 337 | +} NVM_TYPE; | |
| 340 | 338 | |
| 341 | −typedef enum ePMU_MODES | |
| 342 | −{ | |
| 339 | +typedef enum ePMU_MODES { | |
| 343 | 340 | HYBRID_MODE_7C = 0, |
| 344 | 341 | INTERNAL_MODE_6 = 1, |
| 345 | 342 | HYBRID_MODE_6 = 2 |
| 346 | −}PMU_MODE; | |
| 343 | +} PMU_MODE; | |
| 347 | 344 | |
| 348 | 345 | #define MAX_RDM_WRM_RETIRES 1 |
| 349 | 346 | |
| @@ -360,4 +357,4 @@ enum eAbortPattern { · 10 unmodified lines | ||
| 360 | 357 | #define SKB_CB_LATENCY_OFFSET 1 |
| 361 | 358 | #define SKB_CB_TCPACK_OFFSET 2 |
| 362 | 359 | |
| 363 | −#endif //__MACROS_H__ | |
| 360 | +#endif /* __MACROS_H__ */ | |
| @@ -1,113 +1,94 @@ | ||
| 1 | 1 | #include "headers.h" |
| 2 | 2 | |
| 3 | −static int BcmFileDownload(PMINI_ADAPTER Adapter, const char *path, | |
| 4 | − unsigned int loc); | |
| 3 | +static int BcmFileDownload(PMINI_ADAPTER Adapter, const char *path, unsigned int loc); | |
| 5 | 4 | static VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter); |
| 6 | −static void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer); | |
| 5 | +static void HandleShutDownModeRequest(PMINI_ADAPTER Adapter, PUCHAR pucBuffer); | |
| 7 | 6 | static int bcm_parse_target_params(PMINI_ADAPTER Adapter); |
| 8 | −static void beceem_protocol_reset (PMINI_ADAPTER Adapter); | |
| 7 | +static void beceem_protocol_reset(PMINI_ADAPTER Adapter); | |
| 9 | 8 | |
| 10 | 9 | static VOID default_wimax_protocol_initialize(PMINI_ADAPTER Adapter) |
| 11 | 10 | { |
| 11 | + UINT uiLoopIndex; | |
| 12 | 12 | |
| 13 | − UINT uiLoopIndex; | |
| 14 | − | |
| 15 | − for(uiLoopIndex=0; uiLoopIndex < NO_OF_QUEUES-1; uiLoopIndex++) | |
| 16 | − { | |
| 17 | − Adapter->PackInfo[uiLoopIndex].uiThreshold=TX_PACKET_THRESHOLD; | |
| 18 | − Adapter->PackInfo[uiLoopIndex].uiMaxAllowedRate=MAX_ALLOWED_RATE; | |
| 19 | − Adapter->PackInfo[uiLoopIndex].uiMaxBucketSize=20*1024*1024; | |
| 20 | − } | |
| 21 | − | |
| 22 | − Adapter->BEBucketSize=BE_BUCKET_SIZE; | |
| 23 | − Adapter->rtPSBucketSize=rtPS_BUCKET_SIZE; | |
| 24 | − Adapter->LinkStatus=SYNC_UP_REQUEST; | |
| 25 | − Adapter->TransferMode=IP_PACKET_ONLY_MODE; | |
| 26 | − Adapter->usBestEffortQueueIndex=-1; | |
| 27 | − return; | |
| 28 | −} | |
| 13 | + for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES-1; uiLoopIndex++) { | |
| 14 | + Adapter->PackInfo[uiLoopIndex].uiThreshold = TX_PACKET_THRESHOLD; | |
| 15 | + Adapter->PackInfo[uiLoopIndex].uiMaxAllowedRate = MAX_ALLOWED_RATE; | |
| 16 | + Adapter->PackInfo[uiLoopIndex].uiMaxBucketSize = 20*1024*1024; | |
| 17 | + } | |
| 29 | 18 | |
| 19 | + Adapter->BEBucketSize = BE_BUCKET_SIZE; | |
| 20 | + Adapter->rtPSBucketSize = rtPS_BUCKET_SIZE; | |
| 21 | + Adapter->LinkStatus = SYNC_UP_REQUEST; | |
| 22 | + Adapter->TransferMode = IP_PACKET_ONLY_MODE; | |
| 23 | + Adapter->usBestEffortQueueIndex = -1; | |
| 24 | + return; | |
| 25 | +} | |
| 30 | 26 | |
| 31 | −INT | |
| 32 | −InitAdapter(PMINI_ADAPTER psAdapter) | |
| 27 | +INT InitAdapter(PMINI_ADAPTER psAdapter) | |
| 33 | 28 | { |
| 34 | − int i = 0; | |
| 35 | − INT Status = STATUS_SUCCESS ; | |
| 36 | − BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Initialising Adapter = %p", psAdapter); | |
| 29 | + int i = 0; | |
| 30 | + INT Status = STATUS_SUCCESS; | |
| 31 | + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Initialising Adapter = %p", psAdapter); | |
| 37 | 32 | |
| 38 | − if(psAdapter == NULL) | |
| 39 | − { | |
| 40 | − BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Adapter is NULL"); | |
| 33 | + if (psAdapter == NULL) { | |
| 34 | + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Adapter is NULL"); | |
| 41 | 35 | return -EINVAL; |
| 42 | 36 | } |
| 43 | 37 | |
| 44 | − sema_init(&psAdapter->NVMRdmWrmLock,1); | |
| 45 | −// psAdapter->ulFlashCalStart = FLASH_AUTO_INIT_BASE_ADDR; | |
| 46 | − | |
| 38 | + sema_init(&psAdapter->NVMRdmWrmLock, 1); | |
| 47 | 39 | sema_init(&psAdapter->rdmwrmsync, 1); |
| 48 | 40 | spin_lock_init(&psAdapter->control_queue_lock); |
| 49 | 41 | spin_lock_init(&psAdapter->txtransmitlock); |
| 50 | − sema_init(&psAdapter->RxAppControlQueuelock, 1); | |
| 51 | −// sema_init(&psAdapter->data_packet_queue_lock, 1); | |
| 52 | − sema_init(&psAdapter->fw_download_sema, 1); | |
| 53 | − sema_init(&psAdapter->LowPowerModeSync,1); | |
| 54 | − | |
| 55 | − // spin_lock_init(&psAdapter->sleeper_lock); | |
| 56 | − | |
| 57 | − for(i=0;i<NO_OF_QUEUES; i++) | |
| 58 | − spin_lock_init(&psAdapter->PackInfo[i].SFQueueLock); | |
| 59 | − i=0; | |
| 60 | − | |
| 61 | − init_waitqueue_head(&psAdapter->process_rx_cntrlpkt); | |
| 62 | − init_waitqueue_head(&psAdapter->tx_packet_wait_queue); | |
| 63 | − init_waitqueue_head(&psAdapter->process_read_wait_queue); | |
| 64 | − init_waitqueue_head(&psAdapter->ioctl_fw_dnld_wait_queue); | |
| 65 | − init_waitqueue_head(&psAdapter->lowpower_mode_wait_queue); | |
| 42 | + sema_init(&psAdapter->RxAppControlQueuelock, 1); | |
| 43 | + sema_init(&psAdapter->fw_download_sema, 1); | |
| 44 | + sema_init(&psAdapter->LowPowerModeSync, 1); | |
| 45 | + | |
| 46 | + for (i = 0; i < NO_OF_QUEUES; i++) | |
| 47 | + spin_lock_init(&psAdapter->PackInfo[i].SFQueueLock); | |
| 48 | + i = 0; | |
| 49 | + | |
| 50 | + init_waitqueue_head(&psAdapter->process_rx_cntrlpkt); | |
| 51 | + init_waitqueue_head(&psAdapter->tx_packet_wait_queue); | |
| 52 | + init_waitqueue_head(&psAdapter->process_read_wait_queue); | |
| 53 | + init_waitqueue_head(&psAdapter->ioctl_fw_dnld_wait_queue); | |
| 54 | + init_waitqueue_head(&psAdapter->lowpower_mode_wait_queue); | |
| 66 | 55 | psAdapter->waiting_to_fw_download_done = TRUE; |
| 67 | − //init_waitqueue_head(&psAdapter->device_wake_queue); | |
| 68 | − psAdapter->fw_download_done=FALSE; | |
| 69 | − | |
| 56 | + psAdapter->fw_download_done = FALSE; | |
| 70 | 57 | |
| 71 | 58 | default_wimax_protocol_initialize(psAdapter); |
| 72 | − for (i=0;i<MAX_CNTRL_PKTS;i++) | |
| 73 | − { | |
| 59 | + for (i = 0; i < MAX_CNTRL_PKTS; i++) { | |
| 74 | 60 | psAdapter->txctlpacket[i] = kmalloc(MAX_CNTL_PKT_SIZE, GFP_KERNEL); |
| 75 | − if(!psAdapter->txctlpacket[i]) | |
| 76 | − { | |
| 77 | − BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No More Cntl pkts got, max got is %d", i); | |
| 61 | + if (!psAdapter->txctlpacket[i]) { | |
| 62 | + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No More Cntl pkts got, max got is %d", i); | |
| 78 | 63 | return -ENOMEM; |
| 79 | 64 | } |
| 80 | 65 | } |
| 81 | − if(AllocAdapterDsxBuffer(psAdapter)) | |
| 82 | − { | |
| 83 | − BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to allocate DSX buffers"); | |
| 66 | + | |
| 67 | + if (AllocAdapterDsxBuffer(psAdapter)) { | |
| 68 | + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to allocate DSX buffers"); | |
| 84 | 69 | return -EINVAL; |
| 85 | 70 | } |
| 86 | 71 | |
| 87 | − //Initialize PHS interface | |
| 88 | − if(phs_init(&psAdapter->stBCMPhsContext,psAdapter)!=0) | |
| 89 | − { | |
| 90 | − BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"%s:%s:%d:Error PHS Init Failed=====>\n", __FILE__, __FUNCTION__, __LINE__); | |
| 72 | + /* Initialize PHS interface */ | |
| 73 | + if (phs_init(&psAdapter->stBCMPhsContext, psAdapter) != 0) { | |
| 74 | + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "%s:%s:%d:Error PHS Init Failed=====>\n", __FILE__, __func__, __LINE__); | |
| 91 | 75 | return -ENOMEM; |
| 92 | 76 | } |
| 93 | 77 | |
| 94 | 78 | Status = BcmAllocFlashCSStructure(psAdapter); |
| 95 | − if(Status) | |
| 96 | − { | |
| 97 | − BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Memory Allocation for Flash structure failed"); | |
| 98 | − return Status ; | |
| 79 | + if (Status) { | |
| 80 | + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Memory Allocation for Flash structure failed"); | |
| 81 | + return Status; | |
| 99 | 82 | } |
| 100 | 83 | |
| 101 | 84 | Status = vendorextnInit(psAdapter); |
| 102 | 85 | |
| 103 | − if(STATUS_SUCCESS != Status) | |
| 104 | − { | |
| 105 | − BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Vendor Init Failed"); | |
| 106 | − return Status ; | |
| 86 | + if (STATUS_SUCCESS != Status) { | |
| 87 | + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Vendor Init Failed"); | |
| 88 | + return Status; | |
| 107 | 89 | } |
| 108 | 90 | |
| 109 | − BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Adapter initialised"); | |
| 110 | − | |
| 91 | + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Adapter initialised"); | |
| 111 | 92 | |
| 112 | 93 | return STATUS_SUCCESS; |
| 113 | 94 | } |
| @@ -115,42 +96,37 @@ InitAdapter(PMINI_ADAPTER psAdapter) · 1 unmodified line | ||
| 115 | 96 | VOID AdapterFree(PMINI_ADAPTER Adapter) |
| 116 | 97 | { |
| 117 | 98 | int count; |
| 118 | − | |
| 119 | 99 | beceem_protocol_reset(Adapter); |
| 120 | − | |
| 121 | 100 | vendorextnExit(Adapter); |
| 122 | 101 | |
| 123 | − if(Adapter->control_packet_handler && !IS_ERR(Adapter->control_packet_handler)) | |
| 124 | − kthread_stop (Adapter->control_packet_handler); | |
| 102 | + if (Adapter->control_packet_handler && !IS_ERR(Adapter->control_packet_handler)) | |
| 103 | + kthread_stop(Adapter->control_packet_handler); | |
| 125 | 104 | |
| 126 | − if(Adapter->transmit_packet_thread && !IS_ERR(Adapter->transmit_packet_thread)) | |
| 127 | − kthread_stop (Adapter->transmit_packet_thread); | |
| 105 | + if (Adapter->transmit_packet_thread && !IS_ERR(Adapter->transmit_packet_thread)) | |
| 106 | + kthread_stop(Adapter->transmit_packet_thread); | |
| 128 | 107 | |
| 129 | 108 | wake_up(&Adapter->process_read_wait_queue); |
| 130 | 109 | |
| 131 | − if(Adapter->LEDInfo.led_thread_running & (BCM_LED_THREAD_RUNNING_ACTIVELY | BCM_LED_THREAD_RUNNING_INACTIVELY)) | |
| 132 | − kthread_stop (Adapter->LEDInfo.led_cntrl_threadid); | |
| 110 | + if (Adapter->LEDInfo.led_thread_running & (BCM_LED_THREAD_RUNNING_ACTIVELY | BCM_LED_THREAD_RUNNING_INACTIVELY)) | |
| 111 | + kthread_stop(Adapter->LEDInfo.led_cntrl_threadid); | |
| 133 | 112 | |
| 134 | 113 | unregister_networkdev(Adapter); |
| 135 | 114 | |
| 136 | 115 | /* FIXME: use proper wait_event and refcounting */ |
| 137 | − while(atomic_read(&Adapter->ApplicationRunning)) | |
| 138 | − { | |
| 139 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Waiting for Application to close.. %d\n",atomic_read(&Adapter->ApplicationRunning)); | |
| 116 | + while (atomic_read(&Adapter->ApplicationRunning)) { | |
| 117 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Waiting for Application to close.. %d\n", atomic_read(&Adapter->ApplicationRunning)); | |
| 140 | 118 | msleep(100); |
| 141 | 119 | } |
| 142 | 120 | unregister_control_device_interface(Adapter); |
| 143 | − | |
| 144 | 121 | kfree(Adapter->pstargetparams); |
| 145 | 122 | |
| 146 | − for (count =0;count < MAX_CNTRL_PKTS;count++) | |
| 123 | + for (count = 0; count < MAX_CNTRL_PKTS; count++) | |
| 147 | 124 | kfree(Adapter->txctlpacket[count]); |
| 148 | 125 | |
| 149 | 126 | FreeAdapterDsxBuffer(Adapter); |
| 150 | − | |
| 151 | 127 | kfree(Adapter->pvInterfaceAdapter); |
| 152 | 128 | |
| 153 | − //Free the PHS Interface | |
| 129 | + /* Free the PHS Interface */ | |
| 154 | 130 | PhsCleanup(&Adapter->stBCMPhsContext); |
| 155 | 131 | |
| 156 | 132 | BcmDeAllocFlashCSStructure(Adapter); |
| @@ -160,20 +136,18 @@ VOID AdapterFree(PMINI_ADAPTER Adapter) · 3 unmodified lines | ||
| 160 | 136 | |
| 161 | 137 | static int create_worker_threads(PMINI_ADAPTER psAdapter) |
| 162 | 138 | { |
| 163 | − // Rx Control Packets Processing | |
| 139 | + /* Rx Control Packets Processing */ | |
| 164 | 140 | psAdapter->control_packet_handler = kthread_run((int (*)(void *)) |
| 165 | 141 | control_packet_handler, psAdapter, "%s-rx", DRV_NAME); |
| 166 | − if(IS_ERR(psAdapter->control_packet_handler)) | |
| 167 | − { | |
| 142 | + if (IS_ERR(psAdapter->control_packet_handler)) { | |
| 168 | 143 | pr_notice(DRV_NAME ": could not create control thread\n"); |
| 169 | 144 | return PTR_ERR(psAdapter->control_packet_handler); |
| 170 | 145 | } |
| 171 | 146 | |
| 172 | − // Tx Thread | |
| 147 | + /* Tx Thread */ | |
| 173 | 148 | psAdapter->transmit_packet_thread = kthread_run((int (*)(void *)) |
| 174 | 149 | tx_pkt_handler, psAdapter, "%s-tx", DRV_NAME); |
| 175 | − if(IS_ERR (psAdapter->transmit_packet_thread)) | |
| 176 | − { | |
| 150 | + if (IS_ERR(psAdapter->transmit_packet_thread)) { | |
| 177 | 151 | pr_notice(DRV_NAME ": could not creat transmit thread\n"); |
| 178 | 152 | kthread_stop(psAdapter->control_packet_handler); |
| 179 | 153 | return PTR_ERR(psAdapter->transmit_packet_thread); |
| @@ -183,275 +157,248 @@ static int create_worker_threads(PMINI_ADAPTER psAdapter) · 3 unmodified lines | ||
| 183 | 157 | |
| 184 | 158 | static struct file *open_firmware_file(PMINI_ADAPTER Adapter, const char *path) |
| 185 | 159 | { |
| 186 | − struct file *flp=NULL; | |
| 187 | − mm_segment_t oldfs; | |
| 188 | − oldfs=get_fs(); | |
| 160 | + struct file *flp = NULL; | |
| 161 | + mm_segment_t oldfs; | |
| 162 | + oldfs = get_fs(); | |
| 189 | 163 | set_fs(get_ds()); |
| 190 | − flp=filp_open(path, O_RDONLY, S_IRWXU); | |
| 191 | − set_fs(oldfs); | |
| 192 | − if(IS_ERR(flp)) | |
| 193 | − { | |
| 194 | − pr_err(DRV_NAME "Unable To Open File %s, err %ld", | |
| 195 | − path, PTR_ERR(flp)); | |
| 196 | − flp = NULL; | |
| 197 | − } | |
| 198 | − | |
| 199 | − if(Adapter->device_removed) | |
| 200 | − flp = NULL; | |
| 201 | − | |
| 202 | − return flp; | |
| 203 | −} | |
| 164 | + flp = filp_open(path, O_RDONLY, S_IRWXU); | |
| 165 | + set_fs(oldfs); | |
| 166 | + if (IS_ERR(flp)) { | |
| 167 | + pr_err(DRV_NAME "Unable To Open File %s, err %ld", path, PTR_ERR(flp)); | |
| 168 | + flp = NULL; | |
| 169 | + } | |
| 204 | 170 | |
| 171 | + if (Adapter->device_removed) | |
| 172 | + flp = NULL; | |
| 205 | 173 | |
| 206 | −static int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */ | |
| 207 | − const char *path, /**< path to image file */ | |
| 208 | − unsigned int loc /**< Download Address on the chip*/ | |
| 209 | − ) | |
| 174 | + return flp; | |
| 175 | +} | |
| 176 | + | |
| 177 | +/* Arguments: | |
| 178 | + * Logical Adapter | |
| 179 | + * Path to image file | |
| 180 | + * Download Address on the chip | |
| 181 | + */ | |
| 182 | +static int BcmFileDownload(PMINI_ADAPTER Adapter, const char *path, unsigned int loc) | |
| 210 | 183 | { |
| 211 | − int errorno=0; | |
| 212 | − struct file *flp=NULL; | |
| 213 | − mm_segment_t oldfs; | |
| 214 | − struct timeval tv={0}; | |
| 215 | − | |
| 216 | − flp=open_firmware_file(Adapter, path); | |
| 217 | − if(!flp) | |
| 218 | − { | |
| 219 | − errorno = -ENOENT; | |
| 220 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Unable to Open %s\n", path); | |
| 221 | − goto exit_download; | |
| 222 | − } | |
| 223 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Opened file is = %s and length =0x%lx to be downloaded at =0x%x", path,(unsigned long)flp->f_dentry->d_inode->i_size, loc); | |
| 224 | − do_gettimeofday(&tv); | |
| 225 | − | |
| 226 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "download start %lx", ((tv.tv_sec * 1000) + | |
| 227 | − (tv.tv_usec/1000))); | |
| 228 | − if(Adapter->bcm_file_download(Adapter->pvInterfaceAdapter, flp, loc)) | |
| 229 | − { | |
| 230 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to download the firmware with error\ | |
| 231 | − %x!!!", -EIO); | |
| 232 | − errorno=-EIO; | |
| 233 | − goto exit_download; | |
| 234 | − } | |
| 235 | − oldfs=get_fs();set_fs(get_ds()); | |
| 236 | − vfs_llseek(flp, 0, 0); | |
| 237 | − set_fs(oldfs); | |
| 238 | − if(Adapter->bcm_file_readback_from_chip(Adapter->pvInterfaceAdapter, | |
| 239 | − flp, loc)) | |
| 240 | − { | |
| 241 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to read back firmware!"); | |
| 242 | − errorno=-EIO; | |
| 243 | − goto exit_download; | |
| 244 | − } | |
| 184 | + int errorno = 0; | |
| 185 | + struct file *flp = NULL; | |
| 186 | + mm_segment_t oldfs; | |
| 187 | + struct timeval tv = {0}; | |
| 188 | + | |
| 189 | + flp = open_firmware_file(Adapter, path); | |
| 190 | + if (!flp) { | |
| 191 | + errorno = -ENOENT; | |
| 192 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Unable to Open %s\n", path); | |
| 193 | + goto exit_download; | |
| 194 | + } | |
| 195 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Opened file is = %s and length =0x%lx to be downloaded at =0x%x", path, (unsigned long)flp->f_dentry->d_inode->i_size, loc); | |
| 196 | + do_gettimeofday(&tv); | |
| 197 | + | |
| 198 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "download start %lx", ((tv.tv_sec * 1000) + (tv.tv_usec / 1000))); | |
| 199 | + if (Adapter->bcm_file_download(Adapter->pvInterfaceAdapter, flp, loc)) { | |
| 200 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to download the firmware with error %x!!!", -EIO); | |
| 201 | + errorno = -EIO; | |
| 202 | + goto exit_download; | |
| 203 | + } | |
| 204 | + oldfs = get_fs(); | |
| 205 | + set_fs(get_ds()); | |
| 206 | + vfs_llseek(flp, 0, 0); | |
| 207 | + set_fs(oldfs); | |
| 208 | + if (Adapter->bcm_file_readback_from_chip(Adapter->pvInterfaceAdapter, flp, loc)) { | |
| 209 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed to read back firmware!"); | |
| 210 | + errorno = -EIO; | |
| 211 | + goto exit_download; | |
| 212 | + } | |
| 245 | 213 | |
| 246 | 214 | exit_download: |
| 247 | − oldfs=get_fs();set_fs(get_ds()); | |
| 248 | − if(flp && !(IS_ERR(flp))) | |
| 249 | − filp_close(flp, current->files); | |
| 250 | − set_fs(oldfs); | |
| 215 | + oldfs = get_fs(); | |
| 216 | + set_fs(get_ds()); | |
| 217 | + if (flp && !(IS_ERR(flp))) | |
| 218 | + filp_close(flp, current->files); | |
| 219 | + set_fs(oldfs); | |
| 251 | 220 | |
| 252 | − return errorno; | |
| 221 | + return errorno; | |
| 253 | 222 | } |
| 254 | 223 | |
| 255 | 224 | /** |
| 256 | −@ingroup ctrl_pkt_functions | |
| 257 | −This function copies the contents of given buffer | |
| 258 | −to the control packet and queues it for transmission. | |
| 259 | −@note Do not acquire the spinock, as it it already acquired. | |
| 260 | −@return SUCCESS/FAILURE. | |
| 261 | −*/ | |
| 262 | −INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter,/**<Logical Adapter*/ | |
| 263 | − PVOID ioBuffer/**<Control Packet Buffer*/ | |
| 264 | − ) | |
| 225 | + * @ingroup ctrl_pkt_functions | |
| 226 | + * This function copies the contents of given buffer | |
| 227 | + * to the control packet and queues it for transmission. | |
| 228 | + * @note Do not acquire the spinock, as it it already acquired. | |
| 229 | + * @return SUCCESS/FAILURE. | |
| 230 | + * Arguments: | |
| 231 | + * Logical Adapter | |
| 232 | + * Control Packet Buffer | |
| 233 | + */ | |
| 234 | +INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter, PVOID ioBuffer) | |
| 265 | 235 | { |
| 266 | − PLEADER pLeader=NULL; | |
| 267 | − INT Status=0; | |
| 268 | − unsigned char *ctrl_buff=NULL; | |
| 269 | − UINT pktlen=0; | |
| 270 | − PLINK_REQUEST pLinkReq = NULL; | |
| 271 | − PUCHAR pucAddIndication = NULL; | |
| 272 | − | |
| 273 | − BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "======>"); | |
| 274 | − if(!ioBuffer) | |
| 275 | − { | |
| 276 | − BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Got Null Buffer\n"); | |
| 236 | + PLEADER pLeader = NULL; | |
| 237 | + INT Status = 0; | |
| 238 | + unsigned char *ctrl_buff = NULL; | |
| 239 | + UINT pktlen = 0; | |
| 240 | + PLINK_REQUEST pLinkReq = NULL; | |
| 241 | + PUCHAR pucAddIndication = NULL; | |
| 242 | + | |
| 243 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "======>"); | |
| 244 | + if (!ioBuffer) { | |
| 245 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Got Null Buffer\n"); | |
| 277 | 246 | return -EINVAL; |
| 278 | 247 | } |
| 279 | 248 | |
| 280 | 249 | pLinkReq = (PLINK_REQUEST)ioBuffer; |
| 281 | − pLeader=(PLEADER)ioBuffer; //ioBuffer Contains sw_Status and Payload | |
| 250 | + pLeader = (PLEADER)ioBuffer; /* ioBuffer Contains sw_Status and Payload */ | |
| 282 | 251 | |
| 283 | − if(Adapter->bShutStatus == TRUE && | |
| 252 | + if (Adapter->bShutStatus == TRUE && | |
| 284 | 253 | pLinkReq->szData[0] == LINK_DOWN_REQ_PAYLOAD && |
| 285 | − pLinkReq->szData[1] == LINK_SYNC_UP_SUBTYPE) | |
| 286 | − { | |
| 287 | − //Got sync down in SHUTDOWN..we could not process this. | |
| 288 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "SYNC DOWN Request in Shut Down Mode..\n"); | |
| 254 | + pLinkReq->szData[1] == LINK_SYNC_UP_SUBTYPE) { | |
| 255 | + | |
| 256 | + /* Got sync down in SHUTDOWN..we could not process this. */ | |
| 257 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "SYNC DOWN Request in Shut Down Mode..\n"); | |
| 289 | 258 | return STATUS_FAILURE; |
| 290 | 259 | } |
| 291 | 260 | |
| 292 | − if((pLeader->Status == LINK_UP_CONTROL_REQ) && | |
| 261 | + if ((pLeader->Status == LINK_UP_CONTROL_REQ) && | |
| 293 | 262 | ((pLinkReq->szData[0] == LINK_UP_REQ_PAYLOAD && |
| 294 | − (pLinkReq->szData[1] == LINK_SYNC_UP_SUBTYPE)) ||//Sync Up Command | |
| 295 | − pLinkReq->szData[0] == NETWORK_ENTRY_REQ_PAYLOAD)) //Net Entry Command | |
| 296 | − { | |
| 297 | − if(Adapter->LinkStatus > PHY_SYNC_ACHIVED) | |
| 298 | − { | |
| 299 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL,"LinkStatus is Greater than PHY_SYN_ACHIEVED"); | |
| 263 | + (pLinkReq->szData[1] == LINK_SYNC_UP_SUBTYPE)) || /* Sync Up Command */ | |
| 264 | + pLinkReq->szData[0] == NETWORK_ENTRY_REQ_PAYLOAD)) /* Net Entry Command */ { | |
| 265 | + | |
| 266 | + if (Adapter->LinkStatus > PHY_SYNC_ACHIVED) { | |
| 267 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "LinkStatus is Greater than PHY_SYN_ACHIEVED"); | |
| 300 | 268 | return STATUS_FAILURE; |
| 301 | 269 | } |
| 302 | − if(TRUE == Adapter->bShutStatus) | |
| 303 | − { | |
| 304 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "SYNC UP IN SHUTDOWN..Device WakeUp\n"); | |
| 305 | − if(Adapter->bTriedToWakeUpFromlowPowerMode == FALSE) | |
| 306 | − { | |
| 307 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Waking up for the First Time..\n"); | |
| 308 | − Adapter->usIdleModePattern = ABORT_SHUTDOWN_MODE; // change it to 1 for current support. | |
| 270 | + | |
| 271 | + if (TRUE == Adapter->bShutStatus) { | |
| 272 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "SYNC UP IN SHUTDOWN..Device WakeUp\n"); | |
| 273 | + if (Adapter->bTriedToWakeUpFromlowPowerMode == FALSE) { | |
| 274 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Waking up for the First Time..\n"); | |
| 275 | + Adapter->usIdleModePattern = ABORT_SHUTDOWN_MODE; /* change it to 1 for current support. */ | |
| 309 | 276 | Adapter->bWakeUpDevice = TRUE; |
| 310 | 277 | wake_up(&Adapter->process_rx_cntrlpkt); |
| 278 | + Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue, !Adapter->bShutStatus, (5 * HZ)); | |
| 311 | 279 | |
| 312 | − Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue, | |
| 313 | − !Adapter->bShutStatus, (5 * HZ)); | |
| 314 | − | |
| 315 | − if(Status == -ERESTARTSYS) | |
| 280 | + if (Status == -ERESTARTSYS) | |
| 316 | 281 | return Status; |
| 317 | 282 | |
| 318 | − if(Adapter->bShutStatus) | |
| 319 | − { | |
| 320 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Shutdown Mode Wake up Failed - No Wake Up Received\n"); | |
| 283 | + if (Adapter->bShutStatus) { | |
| 284 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Shutdown Mode Wake up Failed - No Wake Up Received\n"); | |
| 321 | 285 | return STATUS_FAILURE; |
| 322 | 286 | } |
| 323 | − } | |
| 324 | − else | |
| 325 | − { | |
| 326 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Wakeup has been tried already...\n"); | |
| 287 | + } else { | |
| 288 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Wakeup has been tried already...\n"); | |
| 327 | 289 | } |
| 328 | 290 | } |
| 329 | − | |
| 330 | 291 | } |
| 331 | − if(TRUE == Adapter->IdleMode) | |
| 332 | − { | |
| 333 | − //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle mode ... hence \n"); | |
| 334 | − if(pLeader->Status == LINK_UP_CONTROL_REQ || pLeader->Status == 0x80 || | |
| 335 | − pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ ) | |
| 336 | 292 | |
| 337 | − { | |
| 338 | − if((pLeader->Status == LINK_UP_CONTROL_REQ) && (pLinkReq->szData[0]==LINK_DOWN_REQ_PAYLOAD)) | |
| 339 | − { | |
| 340 | − if((pLinkReq->szData[1] == LINK_SYNC_DOWN_SUBTYPE)) | |
| 341 | − { | |
| 342 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Link Down Sent in Idle Mode\n"); | |
| 343 | − Adapter->usIdleModePattern = ABORT_IDLE_SYNCDOWN;//LINK DOWN sent in Idle Mode | |
| 344 | − } | |
| 345 | − else | |
| 346 | − { | |
| 347 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL,"ABORT_IDLE_MODE pattern is being written\n"); | |
| 293 | + if (TRUE == Adapter->IdleMode) { | |
| 294 | + /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle mode ... hence\n"); */ | |
| 295 | + if (pLeader->Status == LINK_UP_CONTROL_REQ || pLeader->Status == 0x80 || | |
| 296 | + pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ) { | |
| 297 | + | |
| 298 | + if ((pLeader->Status == LINK_UP_CONTROL_REQ) && (pLinkReq->szData[0] == LINK_DOWN_REQ_PAYLOAD)) { | |
| 299 | + if ((pLinkReq->szData[1] == LINK_SYNC_DOWN_SUBTYPE)) { | |
| 300 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Link Down Sent in Idle Mode\n"); | |
| 301 | + Adapter->usIdleModePattern = ABORT_IDLE_SYNCDOWN; /* LINK DOWN sent in Idle Mode */ | |
| 302 | + } else { | |
| 303 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "ABORT_IDLE_MODE pattern is being written\n"); | |
| 348 | 304 | Adapter->usIdleModePattern = ABORT_IDLE_REG; |
| 349 | 305 | } |
| 350 | − } | |
| 351 | − else | |
| 352 | − { | |
| 353 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL,"ABORT_IDLE_MODE pattern is being written\n"); | |
| 354 | − Adapter->usIdleModePattern = ABORT_IDLE_MODE; | |
| 306 | + } else { | |
| 307 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "ABORT_IDLE_MODE pattern is being written\n"); | |
| 308 | + Adapter->usIdleModePattern = ABORT_IDLE_MODE; | |
| 355 | 309 | } |
| 356 | 310 | |
| 357 | 311 | /*Setting bIdleMode_tx_from_host to TRUE to indicate LED control thread to represent |
| 358 | − the wake up from idlemode is from host*/ | |
| 359 | − //Adapter->LEDInfo.bIdleMode_tx_from_host = TRUE; | |
| 312 | + * the wake up from idlemode is from host | |
| 313 | + */ | |
| 314 | + /* Adapter->LEDInfo.bIdleMode_tx_from_host = TRUE; */ | |
| 360 | 315 | Adapter->bWakeUpDevice = TRUE; |
| 361 | 316 | wake_up(&Adapter->process_rx_cntrlpkt); |
| 362 | 317 | |
| 363 | − | |
| 364 | − | |
| 365 | − if(LINK_DOWN_REQ_PAYLOAD == pLinkReq->szData[0]) | |
| 366 | − { | |
| 367 | − // We should not send DREG message down while in idlemode. | |
| 318 | + /* We should not send DREG message down while in idlemode. */ | |
| 319 | + if (LINK_DOWN_REQ_PAYLOAD == pLinkReq->szData[0]) | |
| 368 | 320 | return STATUS_SUCCESS; |
| 369 | − } | |
| 370 | 321 | |
| 371 | − Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue, | |
| 372 | − !Adapter->IdleMode, (5 * HZ)); | |
| 322 | + Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue, !Adapter->IdleMode, (5 * HZ)); | |
| 373 | 323 | |
| 374 | − if(Status == -ERESTARTSYS) | |
| 324 | + if (Status == -ERESTARTSYS) | |
| 375 | 325 | return Status; |
| 376 | 326 | |
| 377 | − if(Adapter->IdleMode) | |
| 378 | − { | |
| 379 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Idle Mode Wake up Failed - No Wake Up Received\n"); | |
| 327 | + if (Adapter->IdleMode) { | |
| 328 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Idle Mode Wake up Failed - No Wake Up Received\n"); | |
| 380 | 329 | return STATUS_FAILURE; |
| 381 | 330 | } |
| 382 | − } | |
| 383 | − else | |
| 331 | + } else { | |
| 384 | 332 | return STATUS_SUCCESS; |
| 333 | + } | |
| 385 | 334 | } |
| 386 | − //The Driver has to send control messages with a particular VCID | |
| 387 | − pLeader->Vcid = VCID_CONTROL_PACKET;//VCID for control packet. | |
| 335 | + | |
| 336 | + /* The Driver has to send control messages with a particular VCID */ | |
| 337 | + pLeader->Vcid = VCID_CONTROL_PACKET; /* VCID for control packet. */ | |
| 388 | 338 | |
| 389 | 339 | /* Allocate skb for Control Packet */ |
| 390 | 340 | pktlen = pLeader->PLength; |
| 391 | 341 | ctrl_buff = (char *)Adapter->txctlpacket[atomic_read(&Adapter->index_wr_txcntrlpkt)%MAX_CNTRL_PKTS]; |
| 392 | 342 | |
| 393 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Control packet to be taken =%d and address is =%pincoming address is =%p and packet len=%x", | |
| 394 | − atomic_read(&Adapter->index_wr_txcntrlpkt), ctrl_buff, ioBuffer, pktlen); | |
| 395 | − if(ctrl_buff) | |
| 396 | − { | |
| 397 | − if(pLeader) | |
| 398 | − { | |
| 399 | − if((pLeader->Status == 0x80) || | |
| 400 | − (pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ)) | |
| 401 | − { | |
| 343 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Control packet to be taken =%d and address is =%pincoming address is =%p and packet len=%x", | |
| 344 | + atomic_read(&Adapter->index_wr_txcntrlpkt), ctrl_buff, ioBuffer, pktlen); | |
| 345 | + if (ctrl_buff) { | |
| 346 | + if (pLeader) { | |
| 347 | + if ((pLeader->Status == 0x80) || | |
| 348 | + (pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ)) { | |
| 402 | 349 | /* |
| 403 | − //Restructure the DSX message to handle Multiple classifier Support | |
| 404 | − // Write the Service Flow param Structures directly to the target | |
| 405 | − //and embed the pointers in the DSX messages sent to target. | |
| 406 | − */ | |
| 407 | − //Lets store the current length of the control packet we are transmitting | |
| 350 | + * Restructure the DSX message to handle Multiple classifier Support | |
| 351 | + * Write the Service Flow param Structures directly to the target | |
| 352 | + * and embed the pointers in the DSX messages sent to target. | |
| 353 | + */ | |
| 354 | + /* Lets store the current length of the control packet we are transmitting */ | |
| 408 | 355 | pucAddIndication = (PUCHAR)ioBuffer + LEADER_SIZE; |
| 409 | 356 | pktlen = pLeader->PLength; |
| 410 | − Status = StoreCmControlResponseMessage(Adapter,pucAddIndication, &pktlen); | |
| 411 | − if(Status != 1) | |
| 412 | − { | |
| 413 | − ClearTargetDSXBuffer(Adapter,((stLocalSFAddIndicationAlt *)pucAddIndication)->u16TID, FALSE); | |
| 414 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, " Error Restoring The DSX Control Packet. Dsx Buffers on Target may not be Setup Properly "); | |
| 357 | + Status = StoreCmControlResponseMessage(Adapter, pucAddIndication, &pktlen); | |
| 358 | + if (Status != 1) { | |
| 359 | + ClearTargetDSXBuffer(Adapter, ((stLocalSFAddIndicationAlt *)pucAddIndication)->u16TID, FALSE); | |
| 360 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, " Error Restoring The DSX Control Packet. Dsx Buffers on Target may not be Setup Properly "); | |
| 415 | 361 | return STATUS_FAILURE; |
| 416 | 362 | } |
| 417 | 363 | /* |
| 418 | − //update the leader to use the new length | |
| 419 | − //The length of the control packet is length of message being sent + Leader length | |
| 420 | − */ | |
| 364 | + * update the leader to use the new length | |
| 365 | + * The length of the control packet is length of message being sent + Leader length | |
| 366 | + */ | |
| 421 | 367 | pLeader->PLength = pktlen; |
| 422 | 368 | } |
| 423 | 369 | } |
| 370 | + | |
| 371 | + if (pktlen + LEADER_SIZE > MAX_CNTL_PKT_SIZE) | |
| 372 | + return -EINVAL; | |
| 373 | + | |
| 424 | 374 | memset(ctrl_buff, 0, pktlen+LEADER_SIZE); |
| 425 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Copying the Control Packet Buffer with length=%d\n", pLeader->PLength); | |
| 426 | − *(PLEADER)ctrl_buff=*pLeader; | |
| 375 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Copying the Control Packet Buffer with length=%d\n", pLeader->PLength); | |
| 376 | + *(PLEADER)ctrl_buff = *pLeader; | |
| 427 | 377 | memcpy(ctrl_buff + LEADER_SIZE, ((PUCHAR)ioBuffer + LEADER_SIZE), pLeader->PLength); |
| 428 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Enqueuing the Control Packet"); | |
| 378 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Enqueuing the Control Packet"); | |
| 429 | 379 | |
| 430 | − /*Update the statistics counters */ | |
| 380 | + /* Update the statistics counters */ | |
| 431 | 381 | spin_lock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock); |
| 432 | − Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost+=pLeader->PLength; | |
| 382 | + Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost += pLeader->PLength; | |
| 433 | 383 | Adapter->PackInfo[HiPriority].uiCurrentPacketsOnHost++; |
| 434 | 384 | atomic_inc(&Adapter->TotalPacketCount); |
| 435 | 385 | spin_unlock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock); |
| 436 | − | |
| 437 | 386 | Adapter->PackInfo[HiPriority].bValid = TRUE; |
| 438 | 387 | |
| 439 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "CurrBytesOnHost: %x bValid: %x", | |
| 440 | − Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost, | |
| 441 | − Adapter->PackInfo[HiPriority].bValid); | |
| 442 | − Status=STATUS_SUCCESS; | |
| 388 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "CurrBytesOnHost: %x bValid: %x", | |
| 389 | + Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost, | |
| 390 | + Adapter->PackInfo[HiPriority].bValid); | |
| 391 | + Status = STATUS_SUCCESS; | |
| 443 | 392 | /*Queue the packet for transmission */ |
| 444 | 393 | atomic_inc(&Adapter->index_wr_txcntrlpkt); |
| 445 | − BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Calling transmit_packets"); | |
| 394 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Calling transmit_packets"); | |
| 446 | 395 | atomic_set(&Adapter->TxPktAvail, 1); |
| 447 | 396 | wake_up(&Adapter->tx_packet_wait_queue); |
| 397 | + } else { | |
| 398 | + Status = -ENOMEM; | |
| 399 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "mem allocation Failed"); | |
| 448 | 400 | } |
| 449 | − else | |
| 450 | − { | |
| 451 | − Status=-ENOMEM; | |
| 452 | − BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "mem allocation Failed"); | |
| 453 | − } | |
| 454 | − BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<===="); | |
| 401 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<===="); | |
| 455 | 402 | return Status; |
| 456 | 403 | } |
| 457 | 404 | |
| @@ -460,33 +407,30 @@ INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter,/**<Logical Adapter*/ · 2 unmodified lines | ||
| 460 | 407 | * Function - SendStatisticsPointerRequest() |
| 461 | 408 | * |
| 462 | 409 | * Description - This function builds and forwards the Statistics |
| 463 | −* Pointer Request control Packet. | |
| 410 | +* Pointer Request control Packet. | |
| 464 | 411 | * |
| 465 | 412 | * Parameters - Adapter : Pointer to Adapter structure. |
| 466 | −* - pstStatisticsPtrRequest : Pointer to link request. | |
| 413 | +* - pstStatisticsPtrRequest : Pointer to link request. | |
| 467 | 414 | * |
| 468 | 415 | * Returns - None. |
| 469 | 416 | *****************************************************************/ |
| 470 | −static VOID SendStatisticsPointerRequest(PMINI_ADAPTER Adapter, | |
| 471 | − PLINK_REQUEST pstStatisticsPtrRequest) | |
| 417 | +static VOID SendStatisticsPointerRequest(PMINI_ADAPTER Adapter, PLINK_REQUEST pstStatisticsPtrRequest) | |
| 472 | 418 | { |
| 473 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "======>"); | |
| 419 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "======>"); | |
| 474 | 420 | pstStatisticsPtrRequest->Leader.Status = STATS_POINTER_REQ_STATUS; |
| 475 | − pstStatisticsPtrRequest->Leader.PLength = sizeof(ULONG);//minimum 4 bytes | |
| 421 | + pstStatisticsPtrRequest->Leader.PLength = sizeof(ULONG); /* minimum 4 bytes */ | |
| 476 | 422 | pstStatisticsPtrRequest->szData[0] = STATISTICS_POINTER_REQ; |
| 477 | − | |
| 478 | − CopyBufferToControlPacket(Adapter,pstStatisticsPtrRequest); | |
| 479 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "<====="); | |
| 423 | + CopyBufferToControlPacket(Adapter, pstStatisticsPtrRequest); | |
| 424 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "<====="); | |
| 480 | 425 | return; |
| 481 | 426 | } |
| 482 | 427 | #endif |
| 483 | 428 | |
| 484 | − | |
| 485 | 429 | /****************************************************************** |
| 486 | 430 | * Function - LinkMessage() |
| 487 | 431 | * |
| 488 | 432 | * Description - This function builds the Sync-up and Link-up request |
| 489 | −* packet messages depending on the device Link status. | |
| 433 | +* packet messages depending on the device Link status. | |
| 490 | 434 | * |
| 491 | 435 | * Parameters - Adapter: Pointer to the Adapter structure. |
| 492 | 436 | * |
| @@ -494,102 +438,90 @@ static VOID SendStatisticsPointerRequest(PMINI_ADAPTER Adapter, · 1 unmodified line | ||
| 494 | 438 | *******************************************************************/ |
| 495 | 439 | VOID LinkMessage(PMINI_ADAPTER Adapter) |
| 496 | 440 | { |
| 497 | − PLINK_REQUEST pstLinkRequest=NULL; | |
| 498 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "=====>"); | |
| 499 | − if(Adapter->LinkStatus == SYNC_UP_REQUEST && Adapter->AutoSyncup) | |
| 500 | − { | |
| 441 | + PLINK_REQUEST pstLinkRequest = NULL; | |
| 442 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "=====>"); | |
| 443 | + if (Adapter->LinkStatus == SYNC_UP_REQUEST && Adapter->AutoSyncup) { | |
| 501 | 444 | pstLinkRequest = kzalloc(sizeof(LINK_REQUEST), GFP_ATOMIC); |
| 502 | − if(!pstLinkRequest) | |
| 503 | − { | |
| 504 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Can not allocate memory for Link request!"); | |
| 445 | + if (!pstLinkRequest) { | |
| 446 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Can not allocate memory for Link request!"); | |
| 505 | 447 | return; |
| 506 | 448 | } |
| 507 | − //sync up request... | |
| 508 | − Adapter->LinkStatus = WAIT_FOR_SYNC;// current link status | |
| 509 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Requesting For SyncUp..."); | |
| 510 | − pstLinkRequest->szData[0]=LINK_UP_REQ_PAYLOAD; | |
| 511 | − pstLinkRequest->szData[1]=LINK_SYNC_UP_SUBTYPE; | |
| 512 | − pstLinkRequest->Leader.Status=LINK_UP_CONTROL_REQ; | |
| 513 | − pstLinkRequest->Leader.PLength=sizeof(ULONG); | |
| 449 | + /* sync up request... */ | |
| 450 | + Adapter->LinkStatus = WAIT_FOR_SYNC; /* current link status */ | |
| 451 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Requesting For SyncUp..."); | |
| 452 | + pstLinkRequest->szData[0] = LINK_UP_REQ_PAYLOAD; | |
| 453 | + pstLinkRequest->szData[1] = LINK_SYNC_UP_SUBTYPE; | |
| 454 | + pstLinkRequest->Leader.Status = LINK_UP_CONTROL_REQ; | |
| 455 | + pstLinkRequest->Leader.PLength = sizeof(ULONG); | |
| 514 | 456 | Adapter->bSyncUpRequestSent = TRUE; |
| 515 | − } | |
| 516 | − else if(Adapter->LinkStatus == PHY_SYNC_ACHIVED && Adapter->AutoLinkUp) | |
| 517 | − { | |
| 457 | + | |
| 458 | + } else if (Adapter->LinkStatus == PHY_SYNC_ACHIVED && Adapter->AutoLinkUp) { | |
| 518 | 459 | pstLinkRequest = kzalloc(sizeof(LINK_REQUEST), GFP_ATOMIC); |
| 519 | − if(!pstLinkRequest) | |
| 520 | − { | |
| 521 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Can not allocate memory for Link request!"); | |
| 460 | + if (!pstLinkRequest) { | |
| 461 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Can not allocate memory for Link request!"); | |
| 522 | 462 | return; |
| 523 | 463 | } |
| 524 | − //LINK_UP_REQUEST | |
| 525 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Requesting For LinkUp..."); | |
| 526 | − pstLinkRequest->szData[0]=LINK_UP_REQ_PAYLOAD; | |
| 527 | − pstLinkRequest->szData[1]=LINK_NET_ENTRY; | |
| 528 | − pstLinkRequest->Leader.Status=LINK_UP_CONTROL_REQ; | |
| 529 | − pstLinkRequest->Leader.PLength=sizeof(ULONG); | |
| 530 | − } | |
| 531 | − if(pstLinkRequest) | |
| 532 | − { | |
| 533 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Calling CopyBufferToControlPacket"); | |
| 464 | + /* LINK_UP_REQUEST */ | |
| 465 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Requesting For LinkUp..."); | |
| 466 | + pstLinkRequest->szData[0] = LINK_UP_REQ_PAYLOAD; | |
| 467 | + pstLinkRequest->szData[1] = LINK_NET_ENTRY; | |
| 468 | + pstLinkRequest->Leader.Status = LINK_UP_CONTROL_REQ; | |
| 469 | + pstLinkRequest->Leader.PLength = sizeof(ULONG); | |
| 470 | + } | |
| 471 | + if (pstLinkRequest) { | |
| 472 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Calling CopyBufferToControlPacket"); | |
| 534 | 473 | CopyBufferToControlPacket(Adapter, pstLinkRequest); |
| 535 | 474 | kfree(pstLinkRequest); |
| 536 | 475 | } |
| 537 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "LinkMessage <====="); | |
| 476 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "LinkMessage <====="); | |
| 538 | 477 | return; |
| 539 | 478 | } |
| 540 | 479 | |
| 541 | − | |
| 542 | 480 | /********************************************************************** |
| 543 | 481 | * Function - StatisticsResponse() |
| 544 | 482 | * |
| 545 | 483 | * Description - This function handles the Statistics response packet. |
| 546 | 484 | * |
| 547 | 485 | * Parameters - Adapter : Pointer to the Adapter structure. |
| 548 | −* - pvBuffer: Starting address of Statistic response data. | |
| 486 | +* - pvBuffer: Starting address of Statistic response data. | |
| 549 | 487 | * |
| 550 | 488 | * Returns - None. |
| 551 | 489 | ************************************************************************/ |
| 552 | −VOID StatisticsResponse(PMINI_ADAPTER Adapter,PVOID pvBuffer) | |
| 490 | +VOID StatisticsResponse(PMINI_ADAPTER Adapter, PVOID pvBuffer) | |
| 553 | 491 | { |
| 554 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s====>",__FUNCTION__); | |
| 492 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s====>", __func__); | |
| 555 | 493 | Adapter->StatisticsPointer = ntohl(*(__be32 *)pvBuffer); |
| 556 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %x", (UINT)Adapter->StatisticsPointer); | |
| 557 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s <====",__FUNCTION__); | |
| 494 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %x", (UINT)Adapter->StatisticsPointer); | |
| 495 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s <====", __func__); | |
| 558 | 496 | return; |
| 559 | 497 | } |
| 560 | 498 | |
| 561 | − | |
| 562 | 499 | /********************************************************************** |
| 563 | 500 | * Function - LinkControlResponseMessage() |
| 564 | 501 | * |
| 565 | 502 | * Description - This function handles the Link response packets. |
| 566 | 503 | * |
| 567 | 504 | * Parameters - Adapter : Pointer to the Adapter structure. |
| 568 | −* - pucBuffer: Starting address of Link response data. | |
| 505 | +* - pucBuffer: Starting address of Link response data. | |
| 569 | 506 | * |
| 570 | 507 | * Returns - None. |
| 571 | 508 | ***********************************************************************/ |
| 572 | −VOID LinkControlResponseMessage(PMINI_ADAPTER Adapter,PUCHAR pucBuffer) | |
| 509 | +VOID LinkControlResponseMessage(PMINI_ADAPTER Adapter, PUCHAR pucBuffer) | |
| 573 | 510 | { |
| 574 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "=====>"); | |
| 511 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "=====>"); | |
| 575 | 512 | |
| 576 | − if(*pucBuffer==LINK_UP_ACK) | |
| 577 | − { | |
| 578 | − switch(*(pucBuffer+1)) | |
| 579 | − { | |
| 580 | − case PHY_SYNC_ACHIVED: //SYNCed UP | |
| 581 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "PHY_SYNC_ACHIVED"); | |
| 513 | + if (*pucBuffer == LINK_UP_ACK) { | |
| 514 | + switch (*(pucBuffer+1)) { | |
| 515 | + case PHY_SYNC_ACHIVED: /* SYNCed UP */ | |
| 516 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "PHY_SYNC_ACHIVED"); | |
| 582 | 517 | |
| 583 | − if(Adapter->LinkStatus == LINKUP_DONE) | |
| 584 | − { | |
| 518 | + if (Adapter->LinkStatus == LINKUP_DONE) | |
| 585 | 519 | beceem_protocol_reset(Adapter); |
| 586 | − } | |
| 587 | 520 | |
| 588 | − Adapter->usBestEffortQueueIndex=INVALID_QUEUE_INDEX ; | |
| 589 | − Adapter->LinkStatus=PHY_SYNC_ACHIVED; | |
| 521 | + Adapter->usBestEffortQueueIndex = INVALID_QUEUE_INDEX; | |
| 522 | + Adapter->LinkStatus = PHY_SYNC_ACHIVED; | |
| 590 | 523 | |
| 591 | − if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) | |
| 592 | − { | |
| 524 | + if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { | |
| 593 | 525 | Adapter->DriverState = NO_NETWORK_ENTRY; |
| 594 | 526 | wake_up(&Adapter->LEDInfo.notify_led_event); |
| 595 | 527 | } |
| @@ -597,161 +529,145 @@ VOID LinkControlResponseMessage(PMINI_ADAPTER Adapter,PUCHAR pucBuffer) · 1 unmodified line | ||
| 597 | 529 | LinkMessage(Adapter); |
| 598 | 530 | break; |
| 599 | 531 | |
| 600 | − case LINKUP_DONE: | |
| 601 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "LINKUP_DONE"); | |
| 602 | − Adapter->LinkStatus=LINKUP_DONE; | |
| 603 | − Adapter->bPHSEnabled = *(pucBuffer+3); | |
| 604 | − Adapter->bETHCSEnabled = *(pucBuffer+4) & ETH_CS_MASK; | |
| 605 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "PHS Support Status Received In LinkUp Ack : %x \n",Adapter->bPHSEnabled); | |
| 606 | − if((FALSE == Adapter->bShutStatus)&& | |
| 607 | − (FALSE == Adapter->IdleMode)) | |
| 608 | − { | |
| 609 | − if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) | |
| 610 | − { | |
| 611 | − Adapter->DriverState = NORMAL_OPERATION; | |
| 612 | − wake_up(&Adapter->LEDInfo.notify_led_event); | |
| 613 | − } | |
| 532 | + case LINKUP_DONE: | |
| 533 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "LINKUP_DONE"); | |
| 534 | + Adapter->LinkStatus = LINKUP_DONE; | |
| 535 | + Adapter->bPHSEnabled = *(pucBuffer+3); | |
| 536 | + Adapter->bETHCSEnabled = *(pucBuffer+4) & ETH_CS_MASK; | |
| 537 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "PHS Support Status Received In LinkUp Ack : %x\n", Adapter->bPHSEnabled); | |
| 538 | + | |
| 539 | + if ((FALSE == Adapter->bShutStatus) && (FALSE == Adapter->IdleMode)) { | |
| 540 | + if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { | |
| 541 | + Adapter->DriverState = NORMAL_OPERATION; | |
| 542 | + wake_up(&Adapter->LEDInfo.notify_led_event); | |
| 614 | 543 | } |
| 615 | − LinkMessage(Adapter); | |
| 616 | − break; | |
| 617 | − case WAIT_FOR_SYNC: | |
| 544 | + } | |
| 545 | + LinkMessage(Adapter); | |
| 546 | + break; | |
| 618 | 547 | |
| 619 | − /* | |
| 620 | − * Driver to ignore the DREG_RECEIVED | |
| 621 | − * WiMAX Application should handle this Message | |
| 622 | − */ | |
| 623 | − //Adapter->liTimeSinceLastNetEntry = 0; | |
| 624 | − Adapter->LinkUpStatus = 0; | |
| 625 | − Adapter->LinkStatus = 0; | |
| 626 | − Adapter->usBestEffortQueueIndex=INVALID_QUEUE_INDEX ; | |
| 627 | − Adapter->bTriedToWakeUpFromlowPowerMode = FALSE; | |
| 628 | − Adapter->IdleMode = FALSE; | |
| 629 | − beceem_protocol_reset(Adapter); | |
| 548 | + case WAIT_FOR_SYNC: | |
| 549 | + /* | |
| 550 | + * Driver to ignore the DREG_RECEIVED | |
| 551 | + * WiMAX Application should handle this Message | |
| 552 | + */ | |
| 553 | + /* Adapter->liTimeSinceLastNetEntry = 0; */ | |
| 554 | + Adapter->LinkUpStatus = 0; | |
| 555 | + Adapter->LinkStatus = 0; | |
| 556 | + Adapter->usBestEffortQueueIndex = INVALID_QUEUE_INDEX; | |
| 557 | + Adapter->bTriedToWakeUpFromlowPowerMode = FALSE; | |
| 558 | + Adapter->IdleMode = FALSE; | |
| 559 | + beceem_protocol_reset(Adapter); | |
| 630 | 560 | |
| 631 | − break; | |
| 632 | − case LINK_SHUTDOWN_REQ_FROM_FIRMWARE: | |
| 633 | − case COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW: | |
| 634 | − { | |
| 635 | − HandleShutDownModeRequest(Adapter, pucBuffer); | |
| 636 | − } | |
| 637 | − break; | |
| 638 | − default: | |
| 639 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "default case:LinkResponse %x",*(pucBuffer+1)); | |
| 640 | − break; | |
| 561 | + break; | |
| 562 | + case LINK_SHUTDOWN_REQ_FROM_FIRMWARE: | |
| 563 | + case COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW: | |
| 564 | + { | |
| 565 | + HandleShutDownModeRequest(Adapter, pucBuffer); | |
| 641 | 566 | } |
| 642 | − } | |
| 643 | − else if(SET_MAC_ADDRESS_RESPONSE==*pucBuffer) | |
| 644 | − { | |
| 567 | + break; | |
| 568 | + default: | |
| 569 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "default case:LinkResponse %x", *(pucBuffer + 1)); | |
| 570 | + break; | |
| 571 | + } | |
| 572 | + } else if (SET_MAC_ADDRESS_RESPONSE == *pucBuffer) { | |
| 645 | 573 | PUCHAR puMacAddr = (pucBuffer + 1); |
| 646 | − Adapter->LinkStatus=SYNC_UP_REQUEST; | |
| 647 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "MAC address response, sending SYNC_UP"); | |
| 574 | + Adapter->LinkStatus = SYNC_UP_REQUEST; | |
| 575 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "MAC address response, sending SYNC_UP"); | |
| 648 | 576 | LinkMessage(Adapter); |
| 649 | 577 | memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE); |
| 650 | 578 | } |
| 651 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "%s <=====",__FUNCTION__); | |
| 579 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "%s <=====", __func__); | |
| 652 | 580 | return; |
| 653 | 581 | } |
| 654 | 582 | |
| 655 | 583 | void SendIdleModeResponse(PMINI_ADAPTER Adapter) |
| 656 | 584 | { |
| 657 | − INT status = 0, NVMAccess = 0,lowPwrAbortMsg = 0; | |
| 585 | + INT status = 0, NVMAccess = 0, lowPwrAbortMsg = 0; | |
| 658 | 586 | struct timeval tv; |
| 659 | − CONTROL_MESSAGE stIdleResponse = {{0}}; | |
| 587 | + CONTROL_MESSAGE stIdleResponse = {{0} }; | |
| 660 | 588 | memset(&tv, 0, sizeof(tv)); |
| 661 | − stIdleResponse.Leader.Status = IDLE_MESSAGE; | |
| 589 | + stIdleResponse.Leader.Status = IDLE_MESSAGE; | |
| 662 | 590 | stIdleResponse.Leader.PLength = IDLE_MODE_PAYLOAD_LENGTH; |
| 663 | 591 | stIdleResponse.szData[0] = GO_TO_IDLE_MODE_PAYLOAD; |
| 664 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL," ============>"); | |
| 592 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, " ============>"); | |
| 665 | 593 | |
| 666 | 594 | /********************************* |
| 667 | − **down_trylock - | |
| 668 | − ** if [ semaphore is available ] | |
| 669 | − ** acquire semaphone and return value 0 ; | |
| 670 | − ** else | |
| 671 | − ** return non-zero value ; | |
| 672 | − ** | |
| 673 | − ***********************************/ | |
| 595 | + *down_trylock - | |
| 596 | + * if [ semaphore is available ] | |
| 597 | + * acquire semaphone and return value 0 ; | |
| 598 | + * else | |
| 599 | + * return non-zero value ; | |
| 600 | + * | |
| 601 | + ***********************************/ | |
| 674 | 602 | |
| 675 | 603 | NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); |
| 604 | + lowPwrAbortMsg = down_trylock(&Adapter->LowPowerModeSync); | |
| 676 | 605 | |
| 677 | − lowPwrAbortMsg= down_trylock(&Adapter->LowPowerModeSync); | |
| 678 | 606 | |
| 607 | + if ((NVMAccess || lowPwrAbortMsg || atomic_read(&Adapter->TotalPacketCount)) && | |
| 608 | + (Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)) { | |
| 679 | 609 | |
| 680 | − if((NVMAccess || lowPwrAbortMsg || atomic_read(&Adapter->TotalPacketCount)) && | |
| 681 | − (Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) ) | |
| 682 | − { | |
| 683 | − if(!NVMAccess) | |
| 610 | + if (!NVMAccess) | |
| 684 | 611 | up(&Adapter->NVMRdmWrmLock); |
| 685 | 612 | |
| 686 | − if(!lowPwrAbortMsg) | |
| 613 | + if (!lowPwrAbortMsg) | |
| 687 | 614 | up(&Adapter->LowPowerModeSync); |
| 688 | 615 | |
| 689 | − stIdleResponse.szData[1] = TARGET_CAN_NOT_GO_TO_IDLE_MODE;//NACK- device access is going on. | |
| 690 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "HOST IS NACKING Idle mode To F/W!!!!!!!!"); | |
| 616 | + stIdleResponse.szData[1] = TARGET_CAN_NOT_GO_TO_IDLE_MODE; /* NACK- device access is going on. */ | |
| 617 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "HOST IS NACKING Idle mode To F/W!!!!!!!!"); | |
| 691 | 618 | Adapter->bPreparingForLowPowerMode = FALSE; |
| 692 | − } | |
| 693 | − else | |
| 694 | − { | |
| 695 | − stIdleResponse.szData[1] = TARGET_CAN_GO_TO_IDLE_MODE; //2;//Idle ACK | |
| 619 | + } else { | |
| 620 | + stIdleResponse.szData[1] = TARGET_CAN_GO_TO_IDLE_MODE; /* 2; Idle ACK */ | |
| 696 | 621 | Adapter->StatisticsPointer = 0; |
| 697 | 622 | |
| 698 | 623 | /* Wait for the LED to TURN OFF before sending ACK response */ |
| 699 | − if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) | |
| 700 | − { | |
| 624 | + if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { | |
| 701 | 625 | INT iRetVal = 0; |
| 702 | 626 | |
| 703 | 627 | /* Wake the LED Thread with IDLEMODE_ENTER State */ |
| 704 | 628 | Adapter->DriverState = LOWPOWER_MODE_ENTER; |
| 705 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"LED Thread is Running..Hence Setting LED Event as IDLEMODE_ENTER jiffies:%ld",jiffies); | |
| 629 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "LED Thread is Running..Hence Setting LED Event as IDLEMODE_ENTER jiffies:%ld", jiffies); | |
| 706 | 630 | wake_up(&Adapter->LEDInfo.notify_led_event); |
| 707 | 631 | |
| 708 | 632 | /* Wait for 1 SEC for LED to OFF */ |
| 709 | − iRetVal = wait_event_timeout(Adapter->LEDInfo.idleModeSyncEvent, \ | |
| 710 | − Adapter->LEDInfo.bIdle_led_off, msecs_to_jiffies(1000)); | |
| 711 | − | |
| 633 | + iRetVal = wait_event_timeout(Adapter->LEDInfo.idleModeSyncEvent, Adapter->LEDInfo.bIdle_led_off, msecs_to_jiffies(1000)); | |
| 712 | 634 | |
| 713 | 635 | /* If Timed Out to Sync IDLE MODE Enter, do IDLE mode Exit and Send NACK to device */ |
| 714 | − if(iRetVal <= 0) | |
| 715 | − { | |
| 716 | − stIdleResponse.szData[1] = TARGET_CAN_NOT_GO_TO_IDLE_MODE;//NACK- device access is going on. | |
| 636 | + if (iRetVal <= 0) { | |
| 637 | + stIdleResponse.szData[1] = TARGET_CAN_NOT_GO_TO_IDLE_MODE; /* NACK- device access is going on. */ | |
| 717 | 638 | Adapter->DriverState = NORMAL_OPERATION; |
| 718 | 639 | wake_up(&Adapter->LEDInfo.notify_led_event); |
| 719 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "NACKING Idle mode as time out happen from LED side!!!!!!!!"); | |
| 640 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "NACKING Idle mode as time out happen from LED side!!!!!!!!"); | |
| 720 | 641 | } |
| 721 | 642 | } |
| 722 | − if(stIdleResponse.szData[1] == TARGET_CAN_GO_TO_IDLE_MODE) | |
| 723 | − { | |
| 724 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"ACKING IDLE MODE !!!!!!!!!"); | |
| 643 | + | |
| 644 | + if (stIdleResponse.szData[1] == TARGET_CAN_GO_TO_IDLE_MODE) { | |
| 645 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "ACKING IDLE MODE !!!!!!!!!"); | |
| 725 | 646 | down(&Adapter->rdmwrmsync); |
| 726 | 647 | Adapter->bPreparingForLowPowerMode = TRUE; |
| 727 | 648 | up(&Adapter->rdmwrmsync); |
| 728 | − //Killing all URBS. | |
| 729 | − if(Adapter->bDoSuspend == TRUE) | |
| 649 | + /* Killing all URBS. */ | |
| 650 | + if (Adapter->bDoSuspend == TRUE) | |
| 730 | 651 | Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); |
| 731 | − | |
| 732 | − } | |
| 733 | − else | |
| 734 | − { | |
| 652 | + } else { | |
| 735 | 653 | Adapter->bPreparingForLowPowerMode = FALSE; |
| 736 | 654 | } |
| 737 | 655 | |
| 738 | − if(!NVMAccess) | |
| 656 | + if (!NVMAccess) | |
| 739 | 657 | up(&Adapter->NVMRdmWrmLock); |
| 740 | 658 | |
| 741 | − if(!lowPwrAbortMsg) | |
| 659 | + if (!lowPwrAbortMsg) | |
| 742 | 660 | up(&Adapter->LowPowerModeSync); |
| 743 | − | |
| 744 | 661 | } |
| 745 | − status = CopyBufferToControlPacket(Adapter,&stIdleResponse); | |
| 746 | − if((status != STATUS_SUCCESS)) | |
| 747 | − { | |
| 748 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"fail to send the Idle mode Request \n"); | |
| 662 | + | |
| 663 | + status = CopyBufferToControlPacket(Adapter, &stIdleResponse); | |
| 664 | + if ((status != STATUS_SUCCESS)) { | |
| 665 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "fail to send the Idle mode Request\n"); | |
| 749 | 666 | Adapter->bPreparingForLowPowerMode = FALSE; |
| 750 | 667 | StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); |
| 751 | 668 | } |
| 752 | 669 | do_gettimeofday(&tv); |
| 753 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "IdleMode Msg submitter to Q :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000); | |
| 754 | − | |
| 670 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "IdleMode Msg submitter to Q :%ld ms", tv.tv_sec * 1000 + tv.tv_usec / 1000); | |
| 755 | 671 | } |
| 756 | 672 | |
| 757 | 673 | /****************************************************************** |
| @@ -765,307 +681,264 @@ void SendIdleModeResponse(PMINI_ADAPTER Adapter) · 7 unmodified lines | ||
| 765 | 681 | *******************************************************************/ |
| 766 | 682 | VOID DumpPackInfo(PMINI_ADAPTER Adapter) |
| 767 | 683 | { |
| 768 | − | |
| 769 | − UINT uiLoopIndex = 0; | |
| 684 | + UINT uiLoopIndex = 0; | |
| 770 | 685 | UINT uiIndex = 0; |
| 771 | 686 | UINT uiClsfrIndex = 0; |
| 772 | 687 | S_CLASSIFIER_RULE *pstClassifierEntry = NULL; |
| 773 | 688 | |
| 774 | − for(uiLoopIndex=0;uiLoopIndex<NO_OF_QUEUES;uiLoopIndex++) | |
| 775 | − { | |
| 776 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"*********** Showing Details Of Queue %d***** ******",uiLoopIndex); | |
| 777 | − if(FALSE == Adapter->PackInfo[uiLoopIndex].bValid) | |
| 778 | − { | |
| 779 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"bValid is FALSE for %X index\n",uiLoopIndex); | |
| 689 | + for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) { | |
| 690 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "*********** Showing Details Of Queue %d***** ******", uiLoopIndex); | |
| 691 | + if (FALSE == Adapter->PackInfo[uiLoopIndex].bValid) { | |
| 692 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bValid is FALSE for %X index\n", uiLoopIndex); | |
| 780 | 693 | continue; |
| 781 | 694 | } |
| 782 | 695 | |
| 783 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL," Dumping SF Rule Entry For SFID %lX \n",Adapter->PackInfo[uiLoopIndex].ulSFID); | |
| 784 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL," ucDirection %X \n",Adapter->PackInfo[uiLoopIndex].ucDirection); | |
| 785 | − if(Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6) | |
| 786 | − { | |
| 787 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"Ipv6 Service Flow \n"); | |
| 788 | − } | |
| 696 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, " Dumping SF Rule Entry For SFID %lX\n", Adapter->PackInfo[uiLoopIndex].ulSFID); | |
| 697 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, " ucDirection %X\n", Adapter->PackInfo[uiLoopIndex].ucDirection); | |
| 698 | + | |
| 699 | + if (Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6) | |
| 700 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Ipv6 Service Flow\n"); | |
| 789 | 701 | else |
| 790 | − { | |
| 791 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"Ipv4 Service Flow \n"); | |
| 792 | − } | |
| 793 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL," SF Traffic Priority %X \n",Adapter->PackInfo[uiLoopIndex].u8TrafficPriority); | |
| 702 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Ipv4 Service Flow\n"); | |
| 794 | 703 | |
| 795 | − for(uiClsfrIndex=0;uiClsfrIndex<MAX_CLASSIFIERS;uiClsfrIndex++) | |
| 796 | − { | |
| 704 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "SF Traffic Priority %X\n", Adapter->PackInfo[uiLoopIndex].u8TrafficPriority); | |
| 705 | + | |
| 706 | + for (uiClsfrIndex = 0; uiClsfrIndex < MAX_CLASSIFIERS; uiClsfrIndex++) { | |
| 797 | 707 | pstClassifierEntry = &Adapter->astClassifierTable[uiClsfrIndex]; |
| 798 | − if(!pstClassifierEntry->bUsed) | |
| 708 | + if (!pstClassifierEntry->bUsed) | |
| 799 | 709 | continue; |
| 800 | 710 | |
| 801 | − if(pstClassifierEntry->ulSFID != Adapter->PackInfo[uiLoopIndex].ulSFID) | |
| 711 | + if (pstClassifierEntry->ulSFID != Adapter->PackInfo[uiLoopIndex].ulSFID) | |
| 802 | 712 | continue; |
| 803 | 713 | |
| 804 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X Classifier Rule ID : %X\n",uiClsfrIndex,pstClassifierEntry->uiClassifierRuleIndex); | |
| 805 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X usVCID_Value : %X\n",uiClsfrIndex,pstClassifierEntry->usVCID_Value); | |
| 806 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X bProtocolValid : %X\n",uiClsfrIndex,pstClassifierEntry->bProtocolValid); | |
| 807 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X bTOSValid : %X\n",uiClsfrIndex,pstClassifierEntry->bTOSValid); | |
| 808 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X bDestIpValid : %X\n",uiClsfrIndex,pstClassifierEntry->bDestIpValid); | |
| 809 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tDumping Classifier Rule Entry For Index: %X bSrcIpValid : %X\n",uiClsfrIndex,pstClassifierEntry->bSrcIpValid); | |
| 810 | − | |
| 811 | − | |
| 812 | − for(uiIndex=0;uiIndex<MAX_PORT_RANGE;uiIndex++) | |
| 813 | − { | |
| 814 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tusSrcPortRangeLo:%X\n",pstClassifierEntry->usSrcPortRangeLo[uiIndex]); | |
| 815 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tusSrcPortRangeHi:%X\n",pstClassifierEntry->usSrcPortRangeHi[uiIndex]); | |
| 816 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tusDestPortRangeLo:%X\n",pstClassifierEntry->usDestPortRangeLo[uiIndex]); | |
| 817 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tusDestPortRangeHi:%X\n",pstClassifierEntry->usDestPortRangeHi[uiIndex]); | |
| 714 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tDumping Classifier Rule Entry For Index: %X Classifier Rule ID : %X\n", uiClsfrIndex, pstClassifierEntry->uiClassifierRuleIndex); | |
| 715 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tDumping Classifier Rule Entry For Index: %X usVCID_Value : %X\n", uiClsfrIndex, pstClassifierEntry->usVCID_Value); | |
| 716 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tDumping Classifier Rule Entry For Index: %X bProtocolValid : %X\n", uiClsfrIndex, pstClassifierEntry->bProtocolValid); | |
| 717 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tDumping Classifier Rule Entry For Index: %X bTOSValid : %X\n", uiClsfrIndex, pstClassifierEntry->bTOSValid); | |
| 718 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tDumping Classifier Rule Entry For Index: %X bDestIpValid : %X\n", uiClsfrIndex, pstClassifierEntry->bDestIpValid); | |
| 719 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tDumping Classifier Rule Entry For Index: %X bSrcIpValid : %X\n", uiClsfrIndex, pstClassifierEntry->bSrcIpValid); | |
| 720 | + | |
| 721 | + for (uiIndex = 0; uiIndex < MAX_PORT_RANGE; uiIndex++) { | |
| 722 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tusSrcPortRangeLo:%X\n", pstClassifierEntry->usSrcPortRangeLo[uiIndex]); | |
| 723 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tusSrcPortRangeHi:%X\n", pstClassifierEntry->usSrcPortRangeHi[uiIndex]); | |
| 724 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tusDestPortRangeLo:%X\n", pstClassifierEntry->usDestPortRangeLo[uiIndex]); | |
| 725 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tusDestPortRangeHi:%X\n", pstClassifierEntry->usDestPortRangeHi[uiIndex]); | |
| 818 | 726 | } |
| 819 | 727 | |
| 820 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL," \tucIPSourceAddressLength : 0x%x\n",pstClassifierEntry->ucIPSourceAddressLength); | |
| 821 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tucIPDestinationAddressLength : 0x%x\n",pstClassifierEntry->ucIPDestinationAddressLength); | |
| 822 | − for(uiIndex=0;uiIndex<pstClassifierEntry->ucIPSourceAddressLength;uiIndex++) | |
| 823 | − { | |
| 824 | − if(Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6) | |
| 825 | − { | |
| 826 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tIpv6 ulSrcIpAddr :\n"); | |
| 728 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tucIPSourceAddressLength : 0x%x\n", pstClassifierEntry->ucIPSourceAddressLength); | |
| 729 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tucIPDestinationAddressLength : 0x%x\n", pstClassifierEntry->ucIPDestinationAddressLength); | |
| 730 | + for (uiIndex = 0; uiIndex < pstClassifierEntry->ucIPSourceAddressLength; uiIndex++) { | |
| 731 | + if (Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6) { | |
| 732 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tIpv6 ulSrcIpAddr :\n"); | |
| 827 | 733 | DumpIpv6Address(pstClassifierEntry->stSrcIpAddress.ulIpv6Addr); |
| 828 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tIpv6 ulSrcIpMask :\n"); | |
| 734 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tIpv6 ulSrcIpMask :\n"); | |
| 829 | 735 | DumpIpv6Address(pstClassifierEntry->stSrcIpAddress.ulIpv6Mask); |
| 830 | − } | |
| 831 | − else | |
| 832 | − { | |
| 833 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tulSrcIpAddr:%lX\n",pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[uiIndex]); | |
| 834 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tulSrcIpMask:%lX\n",pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[uiIndex]); | |
| 736 | + } else { | |
| 737 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tulSrcIpAddr:%lX\n", pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[uiIndex]); | |
| 738 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tulSrcIpMask:%lX\n", pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[uiIndex]); | |
| 835 | 739 | } |
| 836 | 740 | } |
| 837 | − for(uiIndex=0;uiIndex<pstClassifierEntry->ucIPDestinationAddressLength;uiIndex++) | |
| 838 | − { | |
| 839 | − if(Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6) | |
| 840 | − { | |
| 841 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tIpv6 ulDestIpAddr :\n"); | |
| 741 | + | |
| 742 | + for (uiIndex = 0; uiIndex < pstClassifierEntry->ucIPDestinationAddressLength; uiIndex++) { | |
| 743 | + if (Adapter->PackInfo[uiLoopIndex].ucIpVersion == IPV6) { | |
| 744 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tIpv6 ulDestIpAddr :\n"); | |
| 842 | 745 | DumpIpv6Address(pstClassifierEntry->stDestIpAddress.ulIpv6Addr); |
| 843 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tIpv6 ulDestIpMask :\n"); | |
| 746 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tIpv6 ulDestIpMask :\n"); | |
| 844 | 747 | DumpIpv6Address(pstClassifierEntry->stDestIpAddress.ulIpv6Mask); |
| 845 | − | |
| 846 | − } | |
| 847 | − else | |
| 848 | − { | |
| 849 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tulDestIpAddr:%lX\n",pstClassifierEntry->stDestIpAddress.ulIpv4Addr[uiIndex]); | |
| 850 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tulDestIpMask:%lX\n",pstClassifierEntry->stDestIpAddress.ulIpv4Mask[uiIndex]); | |
| 748 | + } else { | |
| 749 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tulDestIpAddr:%lX\n", pstClassifierEntry->stDestIpAddress.ulIpv4Addr[uiIndex]); | |
| 750 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tulDestIpMask:%lX\n", pstClassifierEntry->stDestIpAddress.ulIpv4Mask[uiIndex]); | |
| 851 | 751 | } |
| 852 | 752 | } |
| 853 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tucProtocol:0x%X\n",pstClassifierEntry->ucProtocol[0]); | |
| 854 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"\tu8ClassifierRulePriority:%X\n",pstClassifierEntry->u8ClassifierRulePriority); | |
| 855 | − | |
| 856 | − | |
| 753 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tucProtocol:0x%X\n", pstClassifierEntry->ucProtocol[0]); | |
| 754 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\tu8ClassifierRulePriority:%X\n", pstClassifierEntry->u8ClassifierRulePriority); | |
| 857 | 755 | } |
| 858 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"ulSFID:%lX\n",Adapter->PackInfo[uiLoopIndex].ulSFID); | |
| 859 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"usVCID_Value:%X\n",Adapter->PackInfo[uiLoopIndex].usVCID_Value); | |
| 860 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"PhsEnabled: 0x%X\n",Adapter->PackInfo[uiLoopIndex].bHeaderSuppressionEnabled); | |
| 861 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiThreshold:%X\n",Adapter->PackInfo[uiLoopIndex].uiThreshold); | |
| 862 | − | |
| 863 | − | |
| 864 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"bValid:%X\n",Adapter->PackInfo[uiLoopIndex].bValid); | |
| 865 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"bActive:%X\n",Adapter->PackInfo[uiLoopIndex].bActive); | |
| 866 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"ActivateReqSent: %x", Adapter->PackInfo[uiLoopIndex].bActivateRequestSent); | |
| 867 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"u8QueueType:%X\n",Adapter->PackInfo[uiLoopIndex].u8QueueType); | |
| 868 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiMaxBucketSize:%X\n",Adapter->PackInfo[uiLoopIndex].uiMaxBucketSize); | |
| 869 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiPerSFTxResourceCount:%X\n",atomic_read(&Adapter->PackInfo[uiLoopIndex].uiPerSFTxResourceCount)); | |
| 870 | − //DumpDebug(DUMP_INFO,(" bCSSupport:%X\n",Adapter->PackInfo[uiLoopIndex].bCSSupport)); | |
| 871 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"CurrQueueDepthOnTarget: %x\n", Adapter->PackInfo[uiLoopIndex].uiCurrentQueueDepthOnTarget); | |
| 872 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiCurrentBytesOnHost:%X\n",Adapter->PackInfo[uiLoopIndex].uiCurrentBytesOnHost); | |
| 873 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiCurrentPacketsOnHost:%X\n",Adapter->PackInfo[uiLoopIndex].uiCurrentPacketsOnHost); | |
| 874 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiDroppedCountBytes:%X\n",Adapter->PackInfo[uiLoopIndex].uiDroppedCountBytes); | |
| 875 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiDroppedCountPackets:%X\n",Adapter->PackInfo[uiLoopIndex].uiDroppedCountPackets); | |
| 876 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiSentBytes:%X\n",Adapter->PackInfo[uiLoopIndex].uiSentBytes); | |
| 877 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiSentPackets:%X\n",Adapter->PackInfo[uiLoopIndex].uiSentPackets); | |
| 878 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiCurrentDrainRate:%X\n",Adapter->PackInfo[uiLoopIndex].uiCurrentDrainRate); | |
| 879 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiThisPeriodSentBytes:%X\n",Adapter->PackInfo[uiLoopIndex].uiThisPeriodSentBytes); | |
| 880 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"liDrainCalculated:%llX\n",Adapter->PackInfo[uiLoopIndex].liDrainCalculated); | |
| 881 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiCurrentTokenCount:%X\n",Adapter->PackInfo[uiLoopIndex].uiCurrentTokenCount); | |
| 882 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"liLastUpdateTokenAt:%llX\n",Adapter->PackInfo[uiLoopIndex].liLastUpdateTokenAt); | |
| 883 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiMaxAllowedRate:%X\n",Adapter->PackInfo[uiLoopIndex].uiMaxAllowedRate); | |
| 884 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"uiPendedLast:%X\n",Adapter->PackInfo[uiLoopIndex].uiPendedLast); | |
| 885 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"NumOfPacketsSent:%X\n",Adapter->PackInfo[uiLoopIndex].NumOfPacketsSent); | |
| 886 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Direction: %x\n", Adapter->PackInfo[uiLoopIndex].ucDirection); | |
| 887 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "CID: %x\n", Adapter->PackInfo[uiLoopIndex].usCID); | |
| 888 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ProtocolValid: %x\n", Adapter->PackInfo[uiLoopIndex].bProtocolValid); | |
| 889 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "TOSValid: %x\n", Adapter->PackInfo[uiLoopIndex].bTOSValid); | |
| 890 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "DestIpValid: %x\n", Adapter->PackInfo[uiLoopIndex].bDestIpValid); | |
| 891 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "SrcIpValid: %x\n", Adapter->PackInfo[uiLoopIndex].bSrcIpValid); | |
| 892 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ActiveSet: %x\n", Adapter->PackInfo[uiLoopIndex].bActiveSet); | |
| 893 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "AdmittedSet: %x\n", Adapter->PackInfo[uiLoopIndex].bAdmittedSet); | |
| 894 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "AuthzSet: %x\n", Adapter->PackInfo[uiLoopIndex].bAuthorizedSet); | |
| 895 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ClassifyPrority: %x\n", Adapter->PackInfo[uiLoopIndex].bClassifierPriority); | |
| 896 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiMaxLatency: %x\n",Adapter->PackInfo[uiLoopIndex].uiMaxLatency); | |
| 897 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ServiceClassName: %x %x %x %x\n",Adapter->PackInfo[uiLoopIndex].ucServiceClassName[0],Adapter->PackInfo[uiLoopIndex].ucServiceClassName[1],Adapter->PackInfo[uiLoopIndex].ucServiceClassName[2],Adapter->PackInfo[uiLoopIndex].ucServiceClassName[3]); | |
| 898 | −// BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bHeaderSuppressionEnabled :%X\n", Adapter->PackInfo[uiLoopIndex].bHeaderSuppressionEnabled); | |
| 899 | −// BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalTxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalTxBytes); | |
| 900 | −// BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalRxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalRxBytes); | |
| 901 | −// DumpDebug(DUMP_INFO,(" uiRanOutOfResCount:%X\n",Adapter->PackInfo[uiLoopIndex].uiRanOutOfResCount)); | |
| 902 | − } | |
| 903 | − | |
| 904 | − for(uiLoopIndex = 0 ; uiLoopIndex < MIBS_MAX_HIST_ENTRIES ; uiLoopIndex++) | |
| 905 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"Adapter->aRxPktSizeHist[%x] = %x\n",uiLoopIndex,Adapter->aRxPktSizeHist[uiLoopIndex]); | |
| 906 | − | |
| 907 | − for(uiLoopIndex = 0 ; uiLoopIndex < MIBS_MAX_HIST_ENTRIES ; uiLoopIndex++) | |
| 908 | − BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,"Adapter->aTxPktSizeHist[%x] = %x\n",uiLoopIndex,Adapter->aTxPktSizeHist[uiLoopIndex]); | |
| 909 | − | |
| 910 | − | |
| 756 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ulSFID:%lX\n", Adapter->PackInfo[uiLoopIndex].ulSFID); | |
| 757 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "usVCID_Value:%X\n", Adapter->PackInfo[uiLoopIndex].usVCID_Value); | |
| 758 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "PhsEnabled: 0x%X\n", Adapter->PackInfo[uiLoopIndex].bHeaderSuppressionEnabled); | |
| 759 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiThreshold:%X\n", Adapter->PackInfo[uiLoopIndex].uiThreshold); | |
| 760 | + | |
| 761 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bValid:%X\n", Adapter->PackInfo[uiLoopIndex].bValid); | |
| 762 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bActive:%X\n", Adapter->PackInfo[uiLoopIndex].bActive); | |
| 763 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ActivateReqSent: %x", Adapter->PackInfo[uiLoopIndex].bActivateRequestSent); | |
| 764 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "u8QueueType:%X\n", Adapter->PackInfo[uiLoopIndex].u8QueueType); | |
| 765 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiMaxBucketSize:%X\n", Adapter->PackInfo[uiLoopIndex].uiMaxBucketSize); | |
| 766 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiPerSFTxResourceCount:%X\n", atomic_read(&Adapter->PackInfo[uiLoopIndex].uiPerSFTxResourceCount)); | |
| 767 | + /* DumpDebug(DUMP_INFO,("bCSSupport:%X\n",Adapter->PackInfo[uiLoopIndex].bCSSupport)); */ | |
| 768 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "CurrQueueDepthOnTarget: %x\n", Adapter->PackInfo[uiLoopIndex].uiCurrentQueueDepthOnTarget); | |
| 769 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiCurrentBytesOnHost:%X\n", Adapter->PackInfo[uiLoopIndex].uiCurrentBytesOnHost); | |
| 770 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiCurrentPacketsOnHost:%X\n", Adapter->PackInfo[uiLoopIndex].uiCurrentPacketsOnHost); | |
| 771 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiDroppedCountBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiDroppedCountBytes); | |
| 772 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiDroppedCountPackets:%X\n", Adapter->PackInfo[uiLoopIndex].uiDroppedCountPackets); | |
| 773 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiSentBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiSentBytes); | |
| 774 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiSentPackets:%X\n", Adapter->PackInfo[uiLoopIndex].uiSentPackets); | |
| 775 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiCurrentDrainRate:%X\n", Adapter->PackInfo[uiLoopIndex].uiCurrentDrainRate); | |
| 776 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiThisPeriodSentBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiThisPeriodSentBytes); | |
| 777 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "liDrainCalculated:%llX\n", Adapter->PackInfo[uiLoopIndex].liDrainCalculated); | |
| 778 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiCurrentTokenCount:%X\n", Adapter->PackInfo[uiLoopIndex].uiCurrentTokenCount); | |
| 779 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "liLastUpdateTokenAt:%llX\n", Adapter->PackInfo[uiLoopIndex].liLastUpdateTokenAt); | |
| 780 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiMaxAllowedRate:%X\n", Adapter->PackInfo[uiLoopIndex].uiMaxAllowedRate); | |
| 781 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiPendedLast:%X\n", Adapter->PackInfo[uiLoopIndex].uiPendedLast); | |
| 782 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "NumOfPacketsSent:%X\n", Adapter->PackInfo[uiLoopIndex].NumOfPacketsSent); | |
| 783 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Direction: %x\n", Adapter->PackInfo[uiLoopIndex].ucDirection); | |
| 784 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "CID: %x\n", Adapter->PackInfo[uiLoopIndex].usCID); | |
| 785 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ProtocolValid: %x\n", Adapter->PackInfo[uiLoopIndex].bProtocolValid); | |
| 786 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "TOSValid: %x\n", Adapter->PackInfo[uiLoopIndex].bTOSValid); | |
| 787 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "DestIpValid: %x\n", Adapter->PackInfo[uiLoopIndex].bDestIpValid); | |
| 788 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "SrcIpValid: %x\n", Adapter->PackInfo[uiLoopIndex].bSrcIpValid); | |
| 789 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ActiveSet: %x\n", Adapter->PackInfo[uiLoopIndex].bActiveSet); | |
| 790 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "AdmittedSet: %x\n", Adapter->PackInfo[uiLoopIndex].bAdmittedSet); | |
| 791 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "AuthzSet: %x\n", Adapter->PackInfo[uiLoopIndex].bAuthorizedSet); | |
| 792 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ClassifyPrority: %x\n", Adapter->PackInfo[uiLoopIndex].bClassifierPriority); | |
| 793 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiMaxLatency: %x\n", Adapter->PackInfo[uiLoopIndex].uiMaxLatency); | |
| 794 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "ServiceClassName: %x %x %x %x\n", Adapter->PackInfo[uiLoopIndex].ucServiceClassName[0], Adapter->PackInfo[uiLoopIndex].ucServiceClassName[1], Adapter->PackInfo[uiLoopIndex].ucServiceClassName[2], Adapter->PackInfo[uiLoopIndex].ucServiceClassName[3]); | |
| 795 | +/* BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "bHeaderSuppressionEnabled :%X\n", Adapter->PackInfo[uiLoopIndex].bHeaderSuppressionEnabled); | |
| 796 | + * BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalTxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalTxBytes); | |
| 797 | + * BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "uiTotalRxBytes:%X\n", Adapter->PackInfo[uiLoopIndex].uiTotalRxBytes); | |
| 798 | + * DumpDebug(DUMP_INFO,(" uiRanOutOfResCount:%X\n",Adapter->PackInfo[uiLoopIndex].uiRanOutOfResCount)); | |
| 799 | + */ | |
| 800 | + } | |
| 801 | + | |
| 802 | + for (uiLoopIndex = 0; uiLoopIndex < MIBS_MAX_HIST_ENTRIES; uiLoopIndex++) | |
| 803 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Adapter->aRxPktSizeHist[%x] = %x\n", uiLoopIndex, Adapter->aRxPktSizeHist[uiLoopIndex]); | |
| 804 | + | |
| 805 | + for (uiLoopIndex = 0; uiLoopIndex < MIBS_MAX_HIST_ENTRIES; uiLoopIndex++) | |
| 806 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Adapter->aTxPktSizeHist[%x] = %x\n", uiLoopIndex, Adapter->aTxPktSizeHist[uiLoopIndex]); | |
| 911 | 807 | |
| 912 | 808 | return; |
| 913 | − | |
| 914 | − | |
| 915 | 809 | } |
| 916 | 810 | |
| 917 | 811 | int reset_card_proc(PMINI_ADAPTER ps_adapter) |
| 918 | 812 | { |
| 919 | 813 | int retval = STATUS_SUCCESS; |
| 920 | − | |
| 921 | − PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
| 814 | + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); | |
| 922 | 815 | PS_INTERFACE_ADAPTER psIntfAdapter = NULL; |
| 923 | 816 | unsigned int value = 0, uiResetValue = 0; |
| 924 | 817 | |
| 925 | − psIntfAdapter = ((PS_INTERFACE_ADAPTER)(ps_adapter->pvInterfaceAdapter)) ; | |
| 926 | − | |
| 818 | + psIntfAdapter = ((PS_INTERFACE_ADAPTER)(ps_adapter->pvInterfaceAdapter)); | |
| 927 | 819 | ps_adapter->bDDRInitDone = FALSE; |
| 928 | 820 | |
| 929 | − if(ps_adapter->chip_id >= T3LPB) | |
| 930 | − { | |
| 931 | − //SYS_CFG register is write protected hence for modifying this reg value, it should be read twice before | |
| 932 | − rdmalt(ps_adapter,SYS_CFG, &value, sizeof(value)); | |
| 933 | − rdmalt(ps_adapter,SYS_CFG, &value, sizeof(value)); | |
| 821 | + if (ps_adapter->chip_id >= T3LPB) { | |
| 822 | + /* SYS_CFG register is write protected hence for modifying this reg value, it should be read twice before */ | |
| 823 | + rdmalt(ps_adapter, SYS_CFG, &value, sizeof(value)); | |
| 824 | + rdmalt(ps_adapter, SYS_CFG, &value, sizeof(value)); | |
| 934 | 825 | |
| 935 | − //making bit[6...5] same as was before f/w download. this setting force the h/w to | |
| 936 | − //re-populated the SP RAM area with the string descriptor . | |
| 937 | − value = value | (ps_adapter->syscfgBefFwDld & 0x00000060) ; | |
| 826 | + /* making bit[6...5] same as was before f/w download. this setting force the h/w to */ | |
| 827 | + /* re-populated the SP RAM area with the string descriptor. */ | |
| 828 | + value = value | (ps_adapter->syscfgBefFwDld & 0x00000060); | |
| 938 | 829 | wrmalt(ps_adapter, SYS_CFG, &value, sizeof(value)); |
| 939 | 830 | } |
| 940 | 831 | |
| 941 | − //killing all submitted URBs. | |
| 942 | − psIntfAdapter->psAdapter->StopAllXaction = TRUE ; | |
| 832 | + /* killing all submitted URBs. */ | |
| 833 | + psIntfAdapter->psAdapter->StopAllXaction = TRUE; | |
| 943 | 834 | Bcm_kill_all_URBs(psIntfAdapter); |
| 944 | 835 | /* Reset the UMA-B Device */ |
| 945 | − if(ps_adapter->chip_id >= T3LPB) | |
| 946 | − { | |
| 947 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Reseting UMA-B \n"); | |
| 836 | + if (ps_adapter->chip_id >= T3LPB) { | |
| 837 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reseting UMA-B\n"); | |
| 948 | 838 | retval = usb_reset_device(psIntfAdapter->udev); |
| 839 | + psIntfAdapter->psAdapter->StopAllXaction = FALSE; | |
| 949 | 840 | |
| 950 | − psIntfAdapter->psAdapter->StopAllXaction = FALSE ; | |
| 951 | − | |
| 952 | − if(retval != STATUS_SUCCESS) | |
| 953 | − { | |
| 954 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Reset failed with ret value :%d", retval); | |
| 841 | + if (retval != STATUS_SUCCESS) { | |
| 842 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reset failed with ret value :%d", retval); | |
| 955 | 843 | goto err_exit; |
| 956 | 844 | } |
| 845 | + | |
| 957 | 846 | if (ps_adapter->chip_id == BCS220_2 || |
| 958 | 847 | ps_adapter->chip_id == BCS220_2BC || |
| 959 | 848 | ps_adapter->chip_id == BCS250_BC || |
| 960 | − ps_adapter->chip_id == BCS220_3) | |
| 961 | − { | |
| 962 | − retval = rdmalt(ps_adapter,HPM_CONFIG_LDO145, &value, sizeof(value)); | |
| 963 | − if( retval < 0) | |
| 964 | − { | |
| 965 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"read failed with status :%d",retval); | |
| 849 | + ps_adapter->chip_id == BCS220_3) { | |
| 850 | + | |
| 851 | + retval = rdmalt(ps_adapter, HPM_CONFIG_LDO145, &value, sizeof(value)); | |
| 852 | + if (retval < 0) { | |
| 853 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "read failed with status :%d", retval); | |
| 966 | 854 | goto err_exit; |
| 967 | 855 | } |
| 968 | − //setting 0th bit | |
| 856 | + /* setting 0th bit */ | |
| 969 | 857 | value |= (1<<0); |
| 970 | 858 | retval = wrmalt(ps_adapter, HPM_CONFIG_LDO145, &value, sizeof(value)); |
| 971 | − if( retval < 0) | |
| 972 | − { | |
| 973 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"write failed with status :%d",retval); | |
| 859 | + if (retval < 0) { | |
| 860 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "write failed with status :%d", retval); | |
| 974 | 861 | goto err_exit; |
| 975 | 862 | } |
| 976 | 863 | } |
| 977 | − | |
| 978 | − } | |
| 979 | − else | |
| 980 | − { | |
| 981 | − retval = rdmalt(ps_adapter,0x0f007018, &value, sizeof(value)); | |
| 982 | − if( retval < 0) { | |
| 983 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"read failed with status :%d",retval); | |
| 864 | + } else { | |
| 865 | + retval = rdmalt(ps_adapter, 0x0f007018, &value, sizeof(value)); | |
| 866 | + if (retval < 0) { | |
| 867 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "read failed with status :%d", retval); | |
| 984 | 868 | goto err_exit; |
| 985 | 869 | } |
| 986 | − value&=(~(1<<16)); | |
| 987 | − retval= wrmalt(ps_adapter, 0x0f007018, &value, sizeof(value)) ; | |
| 988 | − if( retval < 0) { | |
| 989 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"write failed with status :%d",retval); | |
| 870 | + value &= (~(1<<16)); | |
| 871 | + retval = wrmalt(ps_adapter, 0x0f007018, &value, sizeof(value)); | |
| 872 | + if (retval < 0) { | |
| 873 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "write failed with status :%d", retval); | |
| 990 | 874 | goto err_exit; |
| 991 | 875 | } |
| 992 | 876 | |
| 993 | − // Toggling the GPIO 8, 9 | |
| 877 | + /* Toggling the GPIO 8, 9 */ | |
| 994 | 878 | value = 0; |
| 995 | 879 | retval = wrmalt(ps_adapter, GPIO_OUTPUT_REGISTER, &value, sizeof(value)); |
| 996 | − if(retval < 0) { | |
| 997 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"write failed with status :%d",retval); | |
| 880 | + if (retval < 0) { | |
| 881 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "write failed with status :%d", retval); | |
| 998 | 882 | goto err_exit; |
| 999 | 883 | } |
| 1000 | 884 | value = 0x300; |
| 1001 | − retval = wrmalt(ps_adapter, GPIO_MODE_REGISTER, &value, sizeof(value)) ; | |
| 1002 | − if(retval < 0) { | |
| 1003 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"write failed with status :%d",retval); | |
| 885 | + retval = wrmalt(ps_adapter, GPIO_MODE_REGISTER, &value, sizeof(value)); | |
| 886 | + if (retval < 0) { | |
| 887 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "write failed with status :%d", retval); | |
| 1004 | 888 | goto err_exit; |
| 1005 | 889 | } |
| 1006 | 890 | mdelay(50); |
| 1007 | 891 | } |
| 1008 | 892 | |
| 1009 | − //ps_adapter->downloadDDR = false; | |
| 1010 | − | |
| 1011 | − if(ps_adapter->bFlashBoot) | |
| 1012 | − { | |
| 1013 | − //In flash boot mode MIPS state register has reverse polarity. | |
| 1014 | − // So just or with setting bit 30. | |
| 1015 | − //Make the MIPS in Reset state. | |
| 893 | + /* ps_adapter->downloadDDR = false; */ | |
| 894 | + if (ps_adapter->bFlashBoot) { | |
| 895 | + /* In flash boot mode MIPS state register has reverse polarity. | |
| 896 | + * So just or with setting bit 30. | |
| 897 | + * Make the MIPS in Reset state. | |
| 898 | + */ | |
| 1016 | 899 | rdmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &uiResetValue, sizeof(uiResetValue)); |
| 1017 | − | |
| 1018 | − uiResetValue |=(1<<30); | |
| 900 | + uiResetValue |= (1<<30); | |
| 1019 | 901 | wrmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &uiResetValue, sizeof(uiResetValue)); |
| 1020 | 902 | } |
| 1021 | 903 | |
| 1022 | − if(ps_adapter->chip_id >= T3LPB) | |
| 1023 | − { | |
| 904 | + if (ps_adapter->chip_id >= T3LPB) { | |
| 1024 | 905 | uiResetValue = 0; |
| 1025 | − // | |
| 1026 | − // WA for SYSConfig Issue. | |
| 1027 | − // Read SYSCFG Twice to make it writable. | |
| 1028 | − // | |
| 906 | + /* | |
| 907 | + * WA for SYSConfig Issue. | |
| 908 | + * Read SYSCFG Twice to make it writable. | |
| 909 | + */ | |
| 1029 | 910 | rdmalt(ps_adapter, SYS_CFG, &uiResetValue, sizeof(uiResetValue)); |
| 1030 | − if(uiResetValue & (1<<4)) | |
| 1031 | − { | |
| 911 | + if (uiResetValue & (1<<4)) { | |
| 1032 | 912 | uiResetValue = 0; |
| 1033 | − rdmalt(ps_adapter, SYS_CFG, &uiResetValue, sizeof(uiResetValue));//2nd read to make it writable. | |
| 913 | + rdmalt(ps_adapter, SYS_CFG, &uiResetValue, sizeof(uiResetValue)); /* 2nd read to make it writable. */ | |
| 1034 | 914 | uiResetValue &= (~(1<<4)); |
| 1035 | − wrmalt(ps_adapter,SYS_CFG, &uiResetValue, sizeof(uiResetValue)); | |
| 915 | + wrmalt(ps_adapter, SYS_CFG, &uiResetValue, sizeof(uiResetValue)); | |
| 1036 | 916 | } |
| 1037 | − | |
| 1038 | 917 | } |
| 1039 | 918 | uiResetValue = 0; |
| 1040 | 919 | wrmalt(ps_adapter, 0x0f01186c, &uiResetValue, sizeof(uiResetValue)); |
| 1041 | 920 | |
| 1042 | −err_exit : | |
| 1043 | − psIntfAdapter->psAdapter->StopAllXaction = FALSE ; | |
| 921 | +err_exit: | |
| 922 | + psIntfAdapter->psAdapter->StopAllXaction = FALSE; | |
| 1044 | 923 | return retval; |
| 1045 | 924 | } |
| 1046 | 925 | |
| 1047 | −int run_card_proc(PMINI_ADAPTER ps_adapter ) | |
| 926 | +int run_card_proc(PMINI_ADAPTER ps_adapter) | |
| 1048 | 927 | { |
| 1049 | − unsigned int value=0; | |
| 928 | + unsigned int value = 0; | |
| 1050 | 929 | { |
| 1051 | − | |
| 1052 | − if(rdmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &value, sizeof(value)) < 0) { | |
| 1053 | − BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"%s:%d\n", __FUNCTION__, __LINE__); | |
| 930 | + if (rdmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &value, sizeof(value)) < 0) { | |
| 931 | + BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "%s:%d\n", __func__, __LINE__); | |
| 1054 | 932 | return STATUS_FAILURE; |
| 1055 | 933 | } |
| 1056 | 934 | |
| 1057 | − if(ps_adapter->bFlashBoot) | |
| 1058 | − { | |
| 1059 | − | |
| 1060 | − value&=(~(1<<30)); | |
| 1061 | − } | |
| 935 | + if (ps_adapter->bFlashBoot) | |
| 936 | + value &= (~(1<<30)); | |
| 1062 | 937 | else |
| 1063 | − { | |
| 1064 | − value |=(1<<30); | |
| 1065 | − } | |
| 938 | + value |= (1<<30); | |
| 1066 | 939 | |
| 1067 | − if(wrmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &value, sizeof(value)) < 0) { | |
| 1068 | − BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"%s:%d\n", __FUNCTION__, __LINE__); | |
| 940 | + if (wrmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &value, sizeof(value)) < 0) { | |
| 941 | + BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "%s:%d\n", __func__, __LINE__); | |
| 1069 | 942 | return STATUS_FAILURE; |
| 1070 | 943 | } |
| 1071 | 944 | } |
| @@ -1074,104 +947,87 @@ int run_card_proc(PMINI_ADAPTER ps_adapter ) · 2 unmodified lines | ||
| 1074 | 947 | |
| 1075 | 948 | int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter) |
| 1076 | 949 | { |
| 1077 | − | |
| 1078 | 950 | int status; |
| 1079 | 951 | UINT value = 0; |
| 1080 | 952 | /* |
| 1081 | − * Create the threads first and then download the | |
| 1082 | − * Firm/DDR Settings.. | |
| 1083 | − */ | |
| 1084 | − | |
| 953 | + * Create the threads first and then download the | |
| 954 | + * Firm/DDR Settings.. | |
| 955 | + */ | |
| 1085 | 956 | status = create_worker_threads(ps_adapter); |
| 1086 | − if (status<0) | |
| 957 | + if (status < 0) | |
| 1087 | 958 | return status; |
| 1088 | 959 | |
| 1089 | − /* | |
| 1090 | − * For Downloading the Firm, parse the cfg file first. | |
| 1091 | − */ | |
| 1092 | − status = bcm_parse_target_params (ps_adapter); | |
| 1093 | − if(status){ | |
| 960 | + status = bcm_parse_target_params(ps_adapter); | |
| 961 | + if (status) | |
| 1094 | 962 | return status; |
| 1095 | − } | |
| 1096 | 963 | |
| 1097 | − if(ps_adapter->chip_id >= T3LPB) | |
| 1098 | − { | |
| 1099 | − rdmalt(ps_adapter, SYS_CFG, &value, sizeof (value)); | |
| 1100 | − ps_adapter->syscfgBefFwDld = value ; | |
| 1101 | − if((value & 0x60)== 0) | |
| 1102 | − { | |
| 964 | + if (ps_adapter->chip_id >= T3LPB) { | |
| 965 | + rdmalt(ps_adapter, SYS_CFG, &value, sizeof(value)); | |
| 966 | + ps_adapter->syscfgBefFwDld = value; | |
| 967 | + | |
| 968 | + if ((value & 0x60) == 0) | |
| 1103 | 969 | ps_adapter->bFlashBoot = TRUE; |
| 1104 | − } | |
| 1105 | 970 | } |
| 1106 | 971 | |
| 1107 | 972 | reset_card_proc(ps_adapter); |
| 1108 | 973 | |
| 1109 | − //Initializing the NVM. | |
| 974 | + /* Initializing the NVM. */ | |
| 1110 | 975 | BcmInitNVM(ps_adapter); |
| 1111 | 976 | status = ddr_init(ps_adapter); |
| 1112 | − if(status) | |
| 1113 | − { | |
| 977 | + if (status) { | |
| 1114 | 978 | pr_err(DRV_NAME "ddr_init Failed\n"); |
| 1115 | 979 | return status; |
| 1116 | 980 | } |
| 1117 | 981 | |
| 1118 | 982 | /* Download cfg file */ |
| 1119 | 983 | status = buffDnldVerify(ps_adapter, |
| 1120 | − (PUCHAR)ps_adapter->pstargetparams, | |
| 1121 | − sizeof(STARGETPARAMS), | |
| 1122 | − CONFIG_BEGIN_ADDR); | |
| 1123 | − if(status) | |
| 1124 | − { | |
| 1125 | − BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Error downloading CFG file"); | |
| 984 | + (PUCHAR)ps_adapter->pstargetparams, | |
| 985 | + sizeof(STARGETPARAMS), | |
| 986 | + CONFIG_BEGIN_ADDR); | |
| 987 | + if (status) { | |
| 988 | + BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Error downloading CFG file"); | |
| 1126 | 989 | goto OUT; |
| 1127 | 990 | } |
| 1128 | 991 | |
| 1129 | − if(register_networkdev(ps_adapter)) | |
| 1130 | − { | |
| 1131 | − BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Netdevice failed. Cleanup needs to be performed."); | |
| 992 | + if (register_networkdev(ps_adapter)) { | |
| 993 | + BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Netdevice failed. Cleanup needs to be performed."); | |
| 1132 | 994 | return -EIO; |
| 1133 | 995 | } |
| 1134 | 996 | |
| 1135 | − if(FALSE == ps_adapter->AutoFirmDld) | |
| 1136 | − { | |
| 1137 | − BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "AutoFirmDld Disabled in CFG File..\n"); | |
| 1138 | − //If Auto f/w download is disable, register the control interface, | |
| 1139 | − //register the control interface after the mailbox. | |
| 1140 | − if(register_control_device_interface(ps_adapter) < 0) | |
| 1141 | − { | |
| 1142 | − BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Control Device failed. Cleanup needs to be performed."); | |
| 997 | + if (FALSE == ps_adapter->AutoFirmDld) { | |
| 998 | + BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "AutoFirmDld Disabled in CFG File..\n"); | |
| 999 | + /* If Auto f/w download is disable, register the control interface, */ | |
| 1000 | + /* register the control interface after the mailbox. */ | |
| 1001 | + if (register_control_device_interface(ps_adapter) < 0) { | |
| 1002 | + BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Control Device failed. Cleanup needs to be performed."); | |
| 1143 | 1003 | return -EIO; |
| 1144 | 1004 | } |
| 1145 | − | |
| 1146 | 1005 | return STATUS_SUCCESS; |
| 1147 | 1006 | } |
| 1148 | 1007 | |
| 1149 | 1008 | /* |
| 1150 | − * Do the LED Settings here. It will be used by the Firmware Download | |
| 1151 | − * Thread. | |
| 1152 | − */ | |
| 1009 | + * Do the LED Settings here. It will be used by the Firmware Download | |
| 1010 | + * Thread. | |
| 1011 | + */ | |
| 1153 | 1012 | |
| 1154 | 1013 | /* |
| 1155 | − * 1. If the LED Settings fails, do not stop and do the Firmware download. | |
| 1156 | − * 2. This init would happened only if the cfg file is present, else | |
| 1157 | − * call from the ioctl context. | |
| 1158 | − */ | |
| 1159 | − | |
| 1160 | − status = InitLedSettings (ps_adapter); | |
| 1014 | + * 1. If the LED Settings fails, do not stop and do the Firmware download. | |
| 1015 | + * 2. This init would happened only if the cfg file is present, else | |
| 1016 | + * call from the ioctl context. | |
| 1017 | + */ | |
| 1161 | 1018 | |
| 1162 | − if(status) | |
| 1163 | − { | |
| 1164 | − BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_PRINTK, 0, 0,"INIT LED FAILED\n"); | |
| 1019 | + status = InitLedSettings(ps_adapter); | |
| 1020 | + if (status) { | |
| 1021 | + BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_PRINTK, 0, 0, "INIT LED FAILED\n"); | |
| 1165 | 1022 | return status; |
| 1166 | 1023 | } |
| 1167 | − if(ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) | |
| 1168 | − { | |
| 1024 | + | |
| 1025 | + if (ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { | |
| 1169 | 1026 | ps_adapter->DriverState = DRIVER_INIT; |
| 1170 | 1027 | wake_up(&ps_adapter->LEDInfo.notify_led_event); |
| 1171 | 1028 | } |
| 1172 | 1029 | |
| 1173 | − if(ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) | |
| 1174 | − { | |
| 1030 | + if (ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { | |
| 1175 | 1031 | ps_adapter->DriverState = FW_DOWNLOAD; |
| 1176 | 1032 | wake_up(&ps_adapter->LEDInfo.notify_led_event); |
| 1177 | 1033 | } |
| @@ -1180,37 +1036,32 @@ int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter) · 2 unmodified lines | ||
| 1180 | 1036 | wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value)); |
| 1181 | 1037 | wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value)); |
| 1182 | 1038 | |
| 1183 | − if(ps_adapter->eNVMType == NVM_FLASH) | |
| 1184 | − { | |
| 1039 | + if (ps_adapter->eNVMType == NVM_FLASH) { | |
| 1185 | 1040 | status = PropagateCalParamsFromFlashToMemory(ps_adapter); |
| 1186 | − if(status) | |
| 1187 | − { | |
| 1188 | − BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL," Propagation of Cal param failed .." ); | |
| 1041 | + if (status) { | |
| 1042 | + BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Propagation of Cal param failed .."); | |
| 1189 | 1043 | goto OUT; |
| 1190 | 1044 | } |
| 1191 | 1045 | } |
| 1192 | 1046 | |
| 1193 | 1047 | /* Download Firmare */ |
| 1194 | − if ((status = BcmFileDownload( ps_adapter, BIN_FILE, FIRMWARE_BEGIN_ADDR))) | |
| 1195 | − { | |
| 1196 | − BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No Firmware File is present... \n"); | |
| 1048 | + status = BcmFileDownload(ps_adapter, BIN_FILE, FIRMWARE_BEGIN_ADDR); | |
| 1049 | + if (status != 0) { | |
| 1050 | + BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No Firmware File is present...\n"); | |
| 1197 | 1051 | goto OUT; |
| 1198 | 1052 | } |
| 1199 | 1053 | |
| 1200 | 1054 | status = run_card_proc(ps_adapter); |
| 1201 | − if(status) | |
| 1202 | − { | |
| 1203 | − BCM_DEBUG_PRINT (ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "run_card_proc Failed\n"); | |
| 1055 | + if (status) { | |
| 1056 | + BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "run_card_proc Failed\n"); | |
| 1204 | 1057 | goto OUT; |
| 1205 | 1058 | } |
| 1206 | 1059 | |
| 1207 | − | |
| 1208 | 1060 | ps_adapter->fw_download_done = TRUE; |
| 1209 | 1061 | mdelay(10); |
| 1210 | 1062 | |
| 1211 | 1063 | OUT: |
| 1212 | − if(ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) | |
| 1213 | − { | |
| 1064 | + if (ps_adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { | |
| 1214 | 1065 | ps_adapter->DriverState = FW_DOWNLOAD_DONE; |
| 1215 | 1066 | wake_up(&ps_adapter->LEDInfo.notify_led_event); |
| 1216 | 1067 | } |
| @@ -1218,41 +1069,39 @@ OUT: · 1 unmodified line | ||
| 1218 | 1069 | return status; |
| 1219 | 1070 | } |
| 1220 | 1071 | |
| 1221 | − | |
| 1222 | 1072 | static int bcm_parse_target_params(PMINI_ADAPTER Adapter) |
| 1223 | 1073 | { |
| 1224 | − struct file *flp=NULL; | |
| 1225 | − mm_segment_t oldfs={0}; | |
| 1074 | + struct file *flp = NULL; | |
| 1075 | + mm_segment_t oldfs = {0}; | |
| 1226 | 1076 | char *buff; |
| 1227 | 1077 | int len = 0; |
| 1228 | − loff_t pos = 0; | |
| 1078 | + loff_t pos = 0; | |
| 1229 | 1079 | |
| 1230 | − buff=kmalloc(BUFFER_1K, GFP_KERNEL); | |
| 1231 | − if(!buff) | |
| 1232 | − { | |
| 1080 | + buff = kmalloc(BUFFER_1K, GFP_KERNEL); | |
| 1081 | + if (!buff) | |
| 1233 | 1082 | return -ENOMEM; |
| 1234 | − } | |
| 1235 | − if((Adapter->pstargetparams = | |
| 1236 | − kmalloc(sizeof(STARGETPARAMS), GFP_KERNEL)) == NULL) | |
| 1237 | − { | |
| 1083 | + | |
| 1084 | + Adapter->pstargetparams = kmalloc(sizeof(STARGETPARAMS), GFP_KERNEL); | |
| 1085 | + if (Adapter->pstargetparams == NULL) { | |
| 1238 | 1086 | kfree(buff); |
| 1239 | 1087 | return -ENOMEM; |
| 1240 | 1088 | } |
| 1241 | − flp=open_firmware_file(Adapter, CFG_FILE); | |
| 1242 | − if(!flp) { | |
| 1243 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "NOT ABLE TO OPEN THE %s FILE \n", CFG_FILE); | |
| 1089 | + | |
| 1090 | + flp = open_firmware_file(Adapter, CFG_FILE); | |
| 1091 | + if (!flp) { | |
| 1092 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "NOT ABLE TO OPEN THE %s FILE\n", CFG_FILE); | |
| 1244 | 1093 | kfree(buff); |
| 1245 | 1094 | kfree(Adapter->pstargetparams); |
| 1246 | 1095 | Adapter->pstargetparams = NULL; |
| 1247 | 1096 | return -ENOENT; |
| 1248 | 1097 | } |
| 1249 | − oldfs=get_fs(); set_fs(get_ds()); | |
| 1250 | − len=vfs_read(flp, (void __user __force *)buff, BUFFER_1K, &pos); | |
| 1098 | + oldfs = get_fs(); | |
| 1099 | + set_fs(get_ds()); | |
| 1100 | + len = vfs_read(flp, (void __user __force *)buff, BUFFER_1K, &pos); | |
| 1251 | 1101 | set_fs(oldfs); |
| 1252 | 1102 | |
| 1253 | − if(len != sizeof(STARGETPARAMS)) | |
| 1254 | − { | |
| 1255 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Mismatch in Target Param Structure!\n"); | |
| 1103 | + if (len != sizeof(STARGETPARAMS)) { | |
| 1104 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Mismatch in Target Param Structure!\n"); | |
| 1256 | 1105 | kfree(buff); |
| 1257 | 1106 | kfree(Adapter->pstargetparams); |
| 1258 | 1107 | Adapter->pstargetparams = NULL; |
| @@ -1266,122 +1115,97 @@ static int bcm_parse_target_params(PMINI_ADAPTER Adapter) · 7 unmodified lines | ||
| 1266 | 1115 | * Values in Adapter->pstargetparams are in network byte order |
| 1267 | 1116 | */ |
| 1268 | 1117 | memcpy(Adapter->pstargetparams, buff, sizeof(STARGETPARAMS)); |
| 1269 | − kfree (buff); | |
| 1118 | + kfree(buff); | |
| 1270 | 1119 | beceem_parse_target_struct(Adapter); |
| 1271 | 1120 | return STATUS_SUCCESS; |
| 1272 | 1121 | } |
| 1273 | 1122 | |
| 1274 | 1123 | void beceem_parse_target_struct(PMINI_ADAPTER Adapter) |
| 1275 | 1124 | { |
| 1276 | − UINT uiHostDrvrCfg6 =0, uiEEPROMFlag = 0; | |
| 1125 | + UINT uiHostDrvrCfg6 = 0, uiEEPROMFlag = 0; | |
| 1277 | 1126 | |
| 1278 | − if(ntohl(Adapter->pstargetparams->m_u32PhyParameter2) & AUTO_SYNC_DISABLE) | |
| 1279 | − { | |
| 1127 | + if (ntohl(Adapter->pstargetparams->m_u32PhyParameter2) & AUTO_SYNC_DISABLE) { | |
| 1280 | 1128 | pr_info(DRV_NAME ": AutoSyncup is Disabled\n"); |
| 1281 | 1129 | Adapter->AutoSyncup = FALSE; |
| 1282 | − } | |
| 1283 | − else | |
| 1284 | − { | |
| 1130 | + } else { | |
| 1285 | 1131 | pr_info(DRV_NAME ": AutoSyncup is Enabled\n"); |
| 1286 | − Adapter->AutoSyncup = TRUE; | |
| 1132 | + Adapter->AutoSyncup = TRUE; | |
| 1287 | 1133 | } |
| 1288 | 1134 | |
| 1289 | − if(ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_LINKUP_ENABLE) | |
| 1290 | − { | |
| 1135 | + if (ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_LINKUP_ENABLE) { | |
| 1291 | 1136 | pr_info(DRV_NAME ": Enabling autolink up"); |
| 1292 | 1137 | Adapter->AutoLinkUp = TRUE; |
| 1293 | − } | |
| 1294 | − else | |
| 1295 | − { | |
| 1138 | + } else { | |
| 1296 | 1139 | pr_info(DRV_NAME ": Disabling autolink up"); |
| 1297 | 1140 | Adapter->AutoLinkUp = FALSE; |
| 1298 | 1141 | } |
| 1299 | − // Setting the DDR Setting.. | |
| 1300 | − Adapter->DDRSetting = | |
| 1301 | − (ntohl(Adapter->pstargetparams->HostDrvrConfig6) >>8)&0x0F; | |
| 1302 | − Adapter->ulPowerSaveMode = | |
| 1303 | − (ntohl(Adapter->pstargetparams->HostDrvrConfig6)>>12)&0x0F; | |
| 1304 | − | |
| 1142 | + /* Setting the DDR Setting.. */ | |
| 1143 | + Adapter->DDRSetting = (ntohl(Adapter->pstargetparams->HostDrvrConfig6) >> 8)&0x0F; | |
| 1144 | + Adapter->ulPowerSaveMode = (ntohl(Adapter->pstargetparams->HostDrvrConfig6)>>12)&0x0F; | |
| 1305 | 1145 | pr_info(DRV_NAME ": DDR Setting: %x\n", Adapter->DDRSetting); |
| 1306 | 1146 | pr_info(DRV_NAME ": Power Save Mode: %lx\n", Adapter->ulPowerSaveMode); |
| 1307 | − if(ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_FIRM_DOWNLOAD) | |
| 1308 | − { | |
| 1309 | − pr_info(DRV_NAME ": Enabling Auto Firmware Download\n"); | |
| 1310 | − Adapter->AutoFirmDld = TRUE; | |
| 1311 | − } | |
| 1312 | − else | |
| 1313 | − { | |
| 1314 | − pr_info(DRV_NAME ": Disabling Auto Firmware Download\n"); | |
| 1315 | − Adapter->AutoFirmDld = FALSE; | |
| 1316 | − } | |
| 1147 | + if (ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_FIRM_DOWNLOAD) { | |
| 1148 | + pr_info(DRV_NAME ": Enabling Auto Firmware Download\n"); | |
| 1149 | + Adapter->AutoFirmDld = TRUE; | |
| 1150 | + } else { | |
| 1151 | + pr_info(DRV_NAME ": Disabling Auto Firmware Download\n"); | |
| 1152 | + Adapter->AutoFirmDld = FALSE; | |
| 1153 | + } | |
| 1317 | 1154 | uiHostDrvrCfg6 = ntohl(Adapter->pstargetparams->HostDrvrConfig6); |
| 1318 | 1155 | Adapter->bMipsConfig = (uiHostDrvrCfg6>>20)&0x01; |
| 1319 | − pr_info(DRV_NAME ": MIPSConfig : 0x%X\n",Adapter->bMipsConfig); | |
| 1320 | − //used for backward compatibility. | |
| 1156 | + pr_info(DRV_NAME ": MIPSConfig : 0x%X\n", Adapter->bMipsConfig); | |
| 1157 | + /* used for backward compatibility. */ | |
| 1321 | 1158 | Adapter->bDPLLConfig = (uiHostDrvrCfg6>>19)&0x01; |
| 1322 | − | |
| 1323 | − Adapter->PmuMode= (uiHostDrvrCfg6 >> 24 ) & 0x03; | |
| 1159 | + Adapter->PmuMode = (uiHostDrvrCfg6 >> 24) & 0x03; | |
| 1324 | 1160 | pr_info(DRV_NAME ": PMU MODE: %x", Adapter->PmuMode); |
| 1325 | 1161 | |
| 1326 | − if((uiHostDrvrCfg6 >> HOST_BUS_SUSPEND_BIT ) & (0x01)) | |
| 1327 | − { | |
| 1328 | − Adapter->bDoSuspend = TRUE; | |
| 1329 | − pr_info(DRV_NAME ": Making DoSuspend TRUE as per configFile"); | |
| 1330 | − } | |
| 1162 | + if ((uiHostDrvrCfg6 >> HOST_BUS_SUSPEND_BIT) & (0x01)) { | |
| 1163 | + Adapter->bDoSuspend = TRUE; | |
| 1164 | + pr_info(DRV_NAME ": Making DoSuspend TRUE as per configFile"); | |
| 1165 | + } | |
| 1331 | 1166 | |
| 1332 | 1167 | uiEEPROMFlag = ntohl(Adapter->pstargetparams->m_u32EEPROMFlag); |
| 1333 | − pr_info(DRV_NAME ": uiEEPROMFlag : 0x%X\n",uiEEPROMFlag); | |
| 1168 | + pr_info(DRV_NAME ": uiEEPROMFlag : 0x%X\n", uiEEPROMFlag); | |
| 1334 | 1169 | Adapter->eNVMType = (NVM_TYPE)((uiEEPROMFlag>>4)&0x3); |
| 1335 | − | |
| 1336 | 1170 | Adapter->bStatusWrite = (uiEEPROMFlag>>6)&0x1; |
| 1337 | − | |
| 1338 | 1171 | Adapter->uiSectorSizeInCFG = 1024*(0xFFFF & ntohl(Adapter->pstargetparams->HostDrvrConfig4)); |
| 1172 | + Adapter->bSectorSizeOverride = (bool) ((ntohl(Adapter->pstargetparams->HostDrvrConfig4))>>16)&0x1; | |
| 1339 | 1173 | |
| 1340 | − Adapter->bSectorSizeOverride =(bool) ((ntohl(Adapter->pstargetparams->HostDrvrConfig4))>>16)&0x1; | |
| 1341 | − | |
| 1342 | − if(ntohl(Adapter->pstargetparams->m_u32PowerSavingModeOptions) &0x01) | |
| 1174 | + if (ntohl(Adapter->pstargetparams->m_u32PowerSavingModeOptions) & 0x01) | |
| 1343 | 1175 | Adapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE; |
| 1344 | 1176 | |
| 1345 | − if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) | |
| 1177 | + if (Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) | |
| 1346 | 1178 | doPowerAutoCorrection(Adapter); |
| 1347 | − | |
| 1348 | 1179 | } |
| 1349 | 1180 | |
| 1350 | 1181 | static VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter) |
| 1351 | 1182 | { |
| 1352 | 1183 | UINT reporting_mode; |
| 1353 | 1184 | |
| 1354 | − reporting_mode = ntohl(psAdapter->pstargetparams->m_u32PowerSavingModeOptions) &0x02 ; | |
| 1185 | + reporting_mode = ntohl(psAdapter->pstargetparams->m_u32PowerSavingModeOptions) & 0x02; | |
| 1355 | 1186 | psAdapter->bIsAutoCorrectEnabled = !((char)(psAdapter->ulPowerSaveMode >> 3) & 0x1); |
| 1356 | 1187 | |
| 1357 | − if(reporting_mode == TRUE) | |
| 1358 | − { | |
| 1359 | − BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"can't do suspen/resume as reporting mode is enable"); | |
| 1188 | + if (reporting_mode == TRUE) { | |
| 1189 | + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "can't do suspen/resume as reporting mode is enable"); | |
| 1360 | 1190 | psAdapter->bDoSuspend = FALSE; |
| 1361 | 1191 | } |
| 1362 | 1192 | |
| 1363 | − if (psAdapter->bIsAutoCorrectEnabled && (psAdapter->chip_id >= T3LPB)) | |
| 1364 | − { | |
| 1365 | − //If reporting mode is enable, switch PMU to PMC | |
| 1193 | + if (psAdapter->bIsAutoCorrectEnabled && (psAdapter->chip_id >= T3LPB)) { | |
| 1194 | + /* If reporting mode is enable, switch PMU to PMC */ | |
| 1366 | 1195 | { |
| 1367 | 1196 | psAdapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PMU_CLOCK_GATING; |
| 1368 | − psAdapter->bDoSuspend =FALSE; | |
| 1369 | − | |
| 1197 | + psAdapter->bDoSuspend = FALSE; | |
| 1370 | 1198 | } |
| 1371 | 1199 | |
| 1372 | − //clearing space bit[15..12] | |
| 1200 | + /* clearing space bit[15..12] */ | |
| 1373 | 1201 | psAdapter->pstargetparams->HostDrvrConfig6 &= ~(htonl((0xF << 12))); |
| 1374 | − //placing the power save mode option | |
| 1202 | + /* placing the power save mode option */ | |
| 1375 | 1203 | psAdapter->pstargetparams->HostDrvrConfig6 |= htonl((psAdapter->ulPowerSaveMode << 12)); |
| 1376 | − | |
| 1377 | − } | |
| 1378 | − else if (psAdapter->bIsAutoCorrectEnabled == FALSE) | |
| 1379 | − { | |
| 1380 | − | |
| 1381 | − // remove the autocorrect disable bit set before dumping. | |
| 1204 | + } else if (psAdapter->bIsAutoCorrectEnabled == FALSE) { | |
| 1205 | + /* remove the autocorrect disable bit set before dumping. */ | |
| 1382 | 1206 | psAdapter->ulPowerSaveMode &= ~(1 << 3); |
| 1383 | 1207 | psAdapter->pstargetparams->HostDrvrConfig6 &= ~(htonl(1 << 15)); |
| 1384 | − BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Using Forced User Choice: %lx\n", psAdapter->ulPowerSaveMode); | |
| 1208 | + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Using Forced User Choice: %lx\n", psAdapter->ulPowerSaveMode); | |
| 1385 | 1209 | } |
| 1386 | 1210 | } |
| 1387 | 1211 | |
| @@ -1392,63 +1216,56 @@ static unsigned char *ReadMacAddrEEPROM(PMINI_ADAPTER Adapter, ulong dwAddress) · 4 unmodified lines | ||
| 1392 | 1216 | unsigned int temp = 0; |
| 1393 | 1217 | unsigned char *pucmacaddr = kmalloc(MAC_ADDRESS_SIZE, GFP_KERNEL); |
| 1394 | 1218 | |
| 1395 | − if(!pucmacaddr) | |
| 1396 | − { | |
| 1397 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "No Buffers to Read the EEPROM Address\n"); | |
| 1219 | + if (!pucmacaddr) { | |
| 1220 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "No Buffers to Read the EEPROM Address\n"); | |
| 1398 | 1221 | return NULL; |
| 1399 | 1222 | } |
| 1400 | 1223 | |
| 1401 | 1224 | dwAddress |= 0x5b000000; |
| 1402 | − status = wrmalt(Adapter, EEPROM_COMMAND_Q_REG, | |
| 1403 | − (PUINT)&dwAddress, sizeof(UINT)); | |
| 1404 | − if(status != STATUS_SUCCESS) | |
| 1405 | − { | |
| 1406 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm Failed..\n"); | |
| 1225 | + status = wrmalt(Adapter, EEPROM_COMMAND_Q_REG, (PUINT)&dwAddress, sizeof(UINT)); | |
| 1226 | + if (status != STATUS_SUCCESS) { | |
| 1227 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "wrm Failed..\n"); | |
| 1407 | 1228 | kfree(pucmacaddr); |
| 1408 | 1229 | pucmacaddr = NULL; |
| 1409 | 1230 | goto OUT; |
| 1410 | 1231 | } |
| 1411 | − for(i=0;i<MAC_ADDRESS_SIZE;i++) | |
| 1412 | − { | |
| 1413 | − status = rdmalt(Adapter, EEPROM_READ_DATA_Q_REG, &temp,sizeof(temp)); | |
| 1414 | − if(status != STATUS_SUCCESS) | |
| 1415 | − { | |
| 1416 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm Failed..\n"); | |
| 1232 | + | |
| 1233 | + for (i = 0; i < MAC_ADDRESS_SIZE; i++) { | |
| 1234 | + status = rdmalt(Adapter, EEPROM_READ_DATA_Q_REG, &temp, sizeof(temp)); | |
| 1235 | + if (status != STATUS_SUCCESS) { | |
| 1236 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "rdm Failed..\n"); | |
| 1417 | 1237 | kfree(pucmacaddr); |
| 1418 | 1238 | pucmacaddr = NULL; |
| 1419 | 1239 | goto OUT; |
| 1420 | 1240 | } |
| 1421 | 1241 | pucmacaddr[i] = temp & 0xff; |
| 1422 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"%x \n", pucmacaddr[i]); | |
| 1242 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "%x\n", pucmacaddr[i]); | |
| 1423 | 1243 | } |
| 1424 | 1244 | OUT: |
| 1425 | 1245 | return pucmacaddr; |
| 1426 | 1246 | } |
| 1427 | 1247 | #endif |
| 1428 | 1248 | |
| 1429 | − | |
| 1430 | 1249 | static void convertEndian(B_UINT8 rwFlag, PUINT puiBuffer, UINT uiByteCount) |
| 1431 | 1250 | { |
| 1432 | 1251 | UINT uiIndex = 0; |
| 1433 | 1252 | |
| 1434 | − if(RWM_WRITE == rwFlag) { | |
| 1435 | − for(uiIndex =0; uiIndex < (uiByteCount/sizeof(UINT)); uiIndex++) { | |
| 1253 | + if (RWM_WRITE == rwFlag) { | |
| 1254 | + for (uiIndex = 0; uiIndex < (uiByteCount/sizeof(UINT)); uiIndex++) | |
| 1436 | 1255 | puiBuffer[uiIndex] = htonl(puiBuffer[uiIndex]); |
| 1437 | − } | |
| 1438 | 1256 | } else { |
| 1439 | − for(uiIndex =0; uiIndex < (uiByteCount/sizeof(UINT)); uiIndex++) { | |
| 1257 | + for (uiIndex = 0; uiIndex < (uiByteCount/sizeof(UINT)); uiIndex++) | |
| 1440 | 1258 | puiBuffer[uiIndex] = ntohl(puiBuffer[uiIndex]); |
| 1441 | − } | |
| 1442 | 1259 | } |
| 1443 | 1260 | } |
| 1444 | 1261 | |
| 1445 | −#define CACHE_ADDRESS_MASK 0x80000000 | |
| 1446 | −#define UNCACHE_ADDRESS_MASK 0xa0000000 | |
| 1262 | +#define CACHE_ADDRESS_MASK 0x80000000 | |
| 1263 | +#define UNCACHE_ADDRESS_MASK 0xa0000000 | |
| 1447 | 1264 | |
| 1448 | 1265 | int rdm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) |
| 1449 | 1266 | { |
| 1450 | 1267 | return Adapter->interface_rdm(Adapter->pvInterfaceAdapter, |
| 1451 | − uiAddress, pucBuff, sSize); | |
| 1268 | + uiAddress, pucBuff, sSize); | |
| 1452 | 1269 | } |
| 1453 | 1270 | |
| 1454 | 1271 | int wrm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) |
| @@ -1456,112 +1273,103 @@ int wrm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) · 1 unmodified line | ||
| 1456 | 1273 | int iRetVal; |
| 1457 | 1274 | |
| 1458 | 1275 | iRetVal = Adapter->interface_wrm(Adapter->pvInterfaceAdapter, |
| 1459 | − uiAddress, pucBuff, sSize); | |
| 1460 | − | |
| 1461 | − | |
| 1276 | + uiAddress, pucBuff, sSize); | |
| 1462 | 1277 | return iRetVal; |
| 1463 | 1278 | } |
| 1464 | 1279 | |
| 1465 | −int wrmalt (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size) | |
| 1280 | +int wrmalt(PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size) | |
| 1466 | 1281 | { |
| 1467 | 1282 | convertEndian(RWM_WRITE, pucBuff, size); |
| 1468 | 1283 | return wrm(Adapter, uiAddress, (PUCHAR)pucBuff, size); |
| 1469 | 1284 | } |
| 1470 | 1285 | |
| 1471 | −int rdmalt (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size) | |
| 1286 | +int rdmalt(PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size) | |
| 1472 | 1287 | { |
| 1473 | − INT uiRetVal =0; | |
| 1288 | + INT uiRetVal = 0; | |
| 1474 | 1289 | |
| 1475 | − uiRetVal = rdm(Adapter,uiAddress,(PUCHAR)pucBuff,size); | |
| 1290 | + uiRetVal = rdm(Adapter, uiAddress, (PUCHAR)pucBuff, size); | |
| 1476 | 1291 | convertEndian(RWM_READ, (PUINT)pucBuff, size); |
| 1477 | 1292 | |
| 1478 | 1293 | return uiRetVal; |
| 1479 | 1294 | } |
| 1480 | 1295 | |
| 1481 | − | |
| 1482 | 1296 | int wrmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) |
| 1483 | 1297 | { |
| 1484 | − INT status = STATUS_SUCCESS ; | |
| 1298 | + INT status = STATUS_SUCCESS; | |
| 1485 | 1299 | down(&Adapter->rdmwrmsync); |
| 1486 | 1300 | |
| 1487 | − if((Adapter->IdleMode == TRUE) || | |
| 1488 | − (Adapter->bShutStatus ==TRUE) || | |
| 1489 | − (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
| 1490 | − { | |
| 1301 | + if ((Adapter->IdleMode == TRUE) || | |
| 1302 | + (Adapter->bShutStatus == TRUE) || | |
| 1303 | + (Adapter->bPreparingForLowPowerMode == TRUE)) { | |
| 1304 | + | |
| 1491 | 1305 | status = -EACCES; |
| 1492 | 1306 | goto exit; |
| 1493 | 1307 | } |
| 1494 | 1308 | |
| 1495 | − status =wrm(Adapter, uiAddress, pucBuff, sSize); | |
| 1496 | − | |
| 1309 | + status = wrm(Adapter, uiAddress, pucBuff, sSize); | |
| 1497 | 1310 | exit: |
| 1498 | 1311 | up(&Adapter->rdmwrmsync); |
| 1499 | − return status ; | |
| 1312 | + return status; | |
| 1500 | 1313 | } |
| 1501 | 1314 | |
| 1502 | −int wrmaltWithLock (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size) | |
| 1315 | +int wrmaltWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size) | |
| 1503 | 1316 | { |
| 1504 | 1317 | int iRetVal = STATUS_SUCCESS; |
| 1505 | 1318 | |
| 1506 | 1319 | down(&Adapter->rdmwrmsync); |
| 1507 | 1320 | |
| 1508 | − if((Adapter->IdleMode == TRUE) || | |
| 1509 | − (Adapter->bShutStatus ==TRUE) || | |
| 1510 | − (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
| 1511 | − { | |
| 1321 | + if ((Adapter->IdleMode == TRUE) || | |
| 1322 | + (Adapter->bShutStatus == TRUE) || | |
| 1323 | + (Adapter->bPreparingForLowPowerMode == TRUE)) { | |
| 1324 | + | |
| 1512 | 1325 | iRetVal = -EACCES; |
| 1513 | 1326 | goto exit; |
| 1514 | 1327 | } |
| 1515 | 1328 | |
| 1516 | − iRetVal = wrmalt(Adapter,uiAddress,pucBuff,size); | |
| 1517 | − | |
| 1329 | + iRetVal = wrmalt(Adapter, uiAddress, pucBuff, size); | |
| 1518 | 1330 | exit: |
| 1519 | 1331 | up(&Adapter->rdmwrmsync); |
| 1520 | 1332 | return iRetVal; |
| 1521 | 1333 | } |
| 1522 | 1334 | |
| 1523 | −int rdmaltWithLock (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size) | |
| 1335 | +int rdmaltWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size) | |
| 1524 | 1336 | { |
| 1525 | − INT uiRetVal =STATUS_SUCCESS; | |
| 1337 | + INT uiRetVal = STATUS_SUCCESS; | |
| 1526 | 1338 | |
| 1527 | 1339 | down(&Adapter->rdmwrmsync); |
| 1340 | + if ((Adapter->IdleMode == TRUE) || | |
| 1341 | + (Adapter->bShutStatus == TRUE) || | |
| 1342 | + (Adapter->bPreparingForLowPowerMode == TRUE)) { | |
| 1528 | 1343 | |
| 1529 | − if((Adapter->IdleMode == TRUE) || | |
| 1530 | − (Adapter->bShutStatus ==TRUE) || | |
| 1531 | − (Adapter->bPreparingForLowPowerMode ==TRUE)) | |
| 1532 | − { | |
| 1533 | 1344 | uiRetVal = -EACCES; |
| 1534 | 1345 | goto exit; |
| 1535 | 1346 | } |
| 1536 | 1347 | |
| 1537 | − uiRetVal = rdmalt(Adapter,uiAddress, pucBuff, size); | |
| 1538 | − | |
| 1348 | + uiRetVal = rdmalt(Adapter, uiAddress, pucBuff, size); | |
| 1539 | 1349 | exit: |
| 1540 | 1350 | up(&Adapter->rdmwrmsync); |
| 1541 | 1351 | return uiRetVal; |
| 1542 | 1352 | } |
| 1543 | 1353 | |
| 1544 | − | |
| 1545 | 1354 | static VOID HandleShutDownModeWakeup(PMINI_ADAPTER Adapter) |
| 1546 | 1355 | { |
| 1547 | − int clear_abort_pattern = 0,Status = 0; | |
| 1548 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n"); | |
| 1549 | − //target has woken up From Shut Down | |
| 1550 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Clearing Shut Down Software abort pattern\n"); | |
| 1551 | − Status = wrmalt(Adapter,SW_ABORT_IDLEMODE_LOC, (PUINT)&clear_abort_pattern, sizeof(clear_abort_pattern)); | |
| 1552 | − if(Status) | |
| 1553 | − { | |
| 1554 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL,"WRM to SW_ABORT_IDLEMODE_LOC failed with err:%d", Status); | |
| 1356 | + int clear_abort_pattern = 0, Status = 0; | |
| 1357 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n"); | |
| 1358 | + /* target has woken up From Shut Down */ | |
| 1359 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Clearing Shut Down Software abort pattern\n"); | |
| 1360 | + Status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, (PUINT)&clear_abort_pattern, sizeof(clear_abort_pattern)); | |
| 1361 | + if (Status) { | |
| 1362 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "WRM to SW_ABORT_IDLEMODE_LOC failed with err:%d", Status); | |
| 1555 | 1363 | return; |
| 1556 | 1364 | } |
| 1557 | − if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) | |
| 1558 | − { | |
| 1365 | + | |
| 1366 | + if (Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) { | |
| 1559 | 1367 | msleep(100); |
| 1560 | 1368 | InterfaceHandleShutdownModeWakeup(Adapter); |
| 1561 | 1369 | msleep(100); |
| 1562 | 1370 | } |
| 1563 | − if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) | |
| 1564 | − { | |
| 1371 | + | |
| 1372 | + if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { | |
| 1565 | 1373 | Adapter->DriverState = NO_NETWORK_ENTRY; |
| 1566 | 1374 | wake_up(&Adapter->LEDInfo.notify_led_event); |
| 1567 | 1375 | } |
| @@ -1569,55 +1377,49 @@ static VOID HandleShutDownModeWakeup(PMINI_ADAPTER Adapter) · 1 unmodified line | ||
| 1569 | 1377 | Adapter->bTriedToWakeUpFromlowPowerMode = FALSE; |
| 1570 | 1378 | Adapter->bShutStatus = FALSE; |
| 1571 | 1379 | wake_up(&Adapter->lowpower_mode_wait_queue); |
| 1572 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n"); | |
| 1380 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n"); | |
| 1573 | 1381 | } |
| 1574 | 1382 | |
| 1575 | 1383 | static VOID SendShutModeResponse(PMINI_ADAPTER Adapter) |
| 1576 | 1384 | { |
| 1577 | − CONTROL_MESSAGE stShutdownResponse; | |
| 1578 | − UINT NVMAccess = 0,lowPwrAbortMsg = 0; | |
| 1385 | + CONTROL_MESSAGE stShutdownResponse; | |
| 1386 | + UINT NVMAccess = 0, lowPwrAbortMsg = 0; | |
| 1579 | 1387 | UINT Status = 0; |
| 1580 | 1388 | |
| 1581 | − memset (&stShutdownResponse, 0, sizeof(CONTROL_MESSAGE)); | |
| 1389 | + memset(&stShutdownResponse, 0, sizeof(CONTROL_MESSAGE)); | |
| 1582 | 1390 | stShutdownResponse.Leader.Status = LINK_UP_CONTROL_REQ; |
| 1583 | − stShutdownResponse.Leader.PLength = 8;//8 bytes; | |
| 1391 | + stShutdownResponse.Leader.PLength = 8; /* 8 bytes; */ | |
| 1584 | 1392 | stShutdownResponse.szData[0] = LINK_UP_ACK; |
| 1585 | 1393 | stShutdownResponse.szData[1] = LINK_SHUTDOWN_REQ_FROM_FIRMWARE; |
| 1586 | 1394 | |
| 1587 | 1395 | /********************************* |
| 1588 | − **down_trylock - | |
| 1589 | − ** if [ semaphore is available ] | |
| 1590 | − ** acquire semaphone and return value 0 ; | |
| 1591 | − ** else | |
| 1592 | − ** return non-zero value ; | |
| 1593 | − ** | |
| 1594 | − ***********************************/ | |
| 1396 | + * down_trylock - | |
| 1397 | + * if [ semaphore is available ] | |
| 1398 | + * acquire semaphone and return value 0 ; | |
| 1399 | + * else | |
| 1400 | + * return non-zero value ; | |
| 1401 | + * | |
| 1402 | + ***********************************/ | |
| 1595 | 1403 | |
| 1596 | 1404 | NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); |
| 1405 | + lowPwrAbortMsg = down_trylock(&Adapter->LowPowerModeSync); | |
| 1597 | 1406 | |
| 1598 | − lowPwrAbortMsg= down_trylock(&Adapter->LowPowerModeSync); | |
| 1599 | − | |
| 1600 | − | |
| 1601 | − if(NVMAccess || lowPwrAbortMsg|| atomic_read(&Adapter->TotalPacketCount)) | |
| 1602 | − { | |
| 1603 | − if(!NVMAccess) | |
| 1407 | + if (NVMAccess || lowPwrAbortMsg || atomic_read(&Adapter->TotalPacketCount)) { | |
| 1408 | + if (!NVMAccess) | |
| 1604 | 1409 | up(&Adapter->NVMRdmWrmLock); |
| 1605 | 1410 | |
| 1606 | − if(!lowPwrAbortMsg) | |
| 1411 | + if (!lowPwrAbortMsg) | |
| 1607 | 1412 | up(&Adapter->LowPowerModeSync); |
| 1608 | 1413 | |
| 1609 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Device Access is going on NACK the Shut Down MODE\n"); | |
| 1610 | − stShutdownResponse.szData[2] = SHUTDOWN_NACK_FROM_DRIVER;//NACK- device access is going on. | |
| 1414 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Device Access is going on NACK the Shut Down MODE\n"); | |
| 1415 | + stShutdownResponse.szData[2] = SHUTDOWN_NACK_FROM_DRIVER; /* NACK- device access is going on. */ | |
| 1611 | 1416 | Adapter->bPreparingForLowPowerMode = FALSE; |
| 1612 | − } | |
| 1613 | − else | |
| 1614 | − { | |
| 1615 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Sending SHUTDOWN MODE ACK\n"); | |
| 1616 | − stShutdownResponse.szData[2] = SHUTDOWN_ACK_FROM_DRIVER;//ShutDown ACK | |
| 1417 | + } else { | |
| 1418 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Sending SHUTDOWN MODE ACK\n"); | |
| 1419 | + stShutdownResponse.szData[2] = SHUTDOWN_ACK_FROM_DRIVER; /* ShutDown ACK */ | |
| 1617 | 1420 | |
| 1618 | 1421 | /* Wait for the LED to TURN OFF before sending ACK response */ |
| 1619 | − if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) | |
| 1620 | − { | |
| 1422 | + if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { | |
| 1621 | 1423 | INT iRetVal = 0; |
| 1622 | 1424 | |
| 1623 | 1425 | /* Wake the LED Thread with LOWPOWER_MODE_ENTER State */ |
| @@ -1625,237 +1427,200 @@ static VOID SendShutModeResponse(PMINI_ADAPTER Adapter) · 1 unmodified line | ||
| 1625 | 1427 | wake_up(&Adapter->LEDInfo.notify_led_event); |
| 1626 | 1428 | |
| 1627 | 1429 | /* Wait for 1 SEC for LED to OFF */ |
| 1628 | − iRetVal = wait_event_timeout(Adapter->LEDInfo.idleModeSyncEvent,\ | |
| 1629 | − Adapter->LEDInfo.bIdle_led_off, msecs_to_jiffies(1000)); | |
| 1430 | + iRetVal = wait_event_timeout(Adapter->LEDInfo.idleModeSyncEvent, Adapter->LEDInfo.bIdle_led_off, msecs_to_jiffies(1000)); | |
| 1630 | 1431 | |
| 1631 | 1432 | /* If Timed Out to Sync IDLE MODE Enter, do IDLE mode Exit and Send NACK to device */ |
| 1632 | − if(iRetVal <= 0) | |
| 1633 | − { | |
| 1634 | − stShutdownResponse.szData[1] = SHUTDOWN_NACK_FROM_DRIVER;//NACK- device access is going on. | |
| 1635 | − | |
| 1433 | + if (iRetVal <= 0) { | |
| 1434 | + stShutdownResponse.szData[1] = SHUTDOWN_NACK_FROM_DRIVER; /* NACK- device access is going on. */ | |
| 1636 | 1435 | Adapter->DriverState = NO_NETWORK_ENTRY; |
| 1637 | 1436 | wake_up(&Adapter->LEDInfo.notify_led_event); |
| 1638 | 1437 | } |
| 1639 | 1438 | } |
| 1640 | 1439 | |
| 1641 | − if(stShutdownResponse.szData[2] == SHUTDOWN_ACK_FROM_DRIVER) | |
| 1642 | − { | |
| 1643 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL,"ACKING SHUTDOWN MODE !!!!!!!!!"); | |
| 1440 | + if (stShutdownResponse.szData[2] == SHUTDOWN_ACK_FROM_DRIVER) { | |
| 1441 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "ACKING SHUTDOWN MODE !!!!!!!!!"); | |
| 1644 | 1442 | down(&Adapter->rdmwrmsync); |
| 1645 | 1443 | Adapter->bPreparingForLowPowerMode = TRUE; |
| 1646 | 1444 | up(&Adapter->rdmwrmsync); |
| 1647 | − //Killing all URBS. | |
| 1648 | − if(Adapter->bDoSuspend == TRUE) | |
| 1445 | + /* Killing all URBS. */ | |
| 1446 | + if (Adapter->bDoSuspend == TRUE) | |
| 1649 | 1447 | Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); |
| 1650 | − } | |
| 1651 | − else | |
| 1652 | − { | |
| 1448 | + } else { | |
| 1653 | 1449 | Adapter->bPreparingForLowPowerMode = FALSE; |
| 1654 | 1450 | } |
| 1655 | 1451 | |
| 1656 | − if(!NVMAccess) | |
| 1452 | + if (!NVMAccess) | |
| 1657 | 1453 | up(&Adapter->NVMRdmWrmLock); |
| 1658 | 1454 | |
| 1659 | − if(!lowPwrAbortMsg) | |
| 1455 | + if (!lowPwrAbortMsg) | |
| 1660 | 1456 | up(&Adapter->LowPowerModeSync); |
| 1661 | 1457 | } |
| 1662 | − Status = CopyBufferToControlPacket(Adapter,&stShutdownResponse); | |
| 1663 | − if((Status != STATUS_SUCCESS)) | |
| 1664 | − { | |
| 1665 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL,"fail to send the Idle mode Request \n"); | |
| 1666 | − Adapter->bPreparingForLowPowerMode = FALSE; | |
| 1667 | 1458 | |
| 1459 | + Status = CopyBufferToControlPacket(Adapter, &stShutdownResponse); | |
| 1460 | + if ((Status != STATUS_SUCCESS)) { | |
| 1461 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "fail to send the Idle mode Request\n"); | |
| 1462 | + Adapter->bPreparingForLowPowerMode = FALSE; | |
| 1668 | 1463 | StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); |
| 1669 | 1464 | } |
| 1670 | 1465 | } |
| 1671 | 1466 | |
| 1672 | − | |
| 1673 | −static void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer) | |
| 1467 | +static void HandleShutDownModeRequest(PMINI_ADAPTER Adapter, PUCHAR pucBuffer) | |
| 1674 | 1468 | { |
| 1675 | 1469 | B_UINT32 uiResetValue = 0; |
| 1676 | 1470 | |
| 1677 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n"); | |
| 1471 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n"); | |
| 1678 | 1472 | |
| 1679 | − if(*(pucBuffer+1) == COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW) | |
| 1680 | − { | |
| 1473 | + if (*(pucBuffer+1) == COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW) { | |
| 1681 | 1474 | HandleShutDownModeWakeup(Adapter); |
| 1682 | − } | |
| 1683 | − else if(*(pucBuffer+1) == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) | |
| 1684 | − { | |
| 1685 | − //Target wants to go to Shut Down Mode | |
| 1686 | − //InterfacePrepareForShutdown(Adapter); | |
| 1687 | − if(Adapter->chip_id == BCS220_2 || | |
| 1688 | − Adapter->chip_id == BCS220_2BC || | |
| 1689 | − Adapter->chip_id == BCS250_BC || | |
| 1690 | − Adapter->chip_id == BCS220_3) | |
| 1691 | − { | |
| 1692 | − rdmalt(Adapter,HPM_CONFIG_MSW, &uiResetValue, 4); | |
| 1475 | + } else if (*(pucBuffer+1) == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) { | |
| 1476 | + /* Target wants to go to Shut Down Mode */ | |
| 1477 | + /* InterfacePrepareForShutdown(Adapter); */ | |
| 1478 | + if (Adapter->chip_id == BCS220_2 || | |
| 1479 | + Adapter->chip_id == BCS220_2BC || | |
| 1480 | + Adapter->chip_id == BCS250_BC || | |
| 1481 | + Adapter->chip_id == BCS220_3) { | |
| 1482 | + | |
| 1483 | + rdmalt(Adapter, HPM_CONFIG_MSW, &uiResetValue, 4); | |
| 1693 | 1484 | uiResetValue |= (1<<17); |
| 1694 | 1485 | wrmalt(Adapter, HPM_CONFIG_MSW, &uiResetValue, 4); |
| 1695 | 1486 | } |
| 1696 | 1487 | |
| 1697 | 1488 | SendShutModeResponse(Adapter); |
| 1698 | − BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL,"ShutDownModeResponse:Notification received: Sending the response(Ack/Nack)\n"); | |
| 1489 | + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "ShutDownModeResponse:Notification received: Sending the response(Ack/Nack)\n"); | |
| 1699 | 1490 | } |
| 1700 | 1491 | |
| 1701 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n"); | |
| 1492 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n"); | |
| 1702 | 1493 | return; |
| 1703 | − | |
| 1704 | 1494 | } |
| 1705 | 1495 | |
| 1706 | 1496 | VOID ResetCounters(PMINI_ADAPTER Adapter) |
| 1707 | 1497 | { |
| 1708 | − | |
| 1709 | − beceem_protocol_reset(Adapter); | |
| 1710 | − | |
| 1498 | + beceem_protocol_reset(Adapter); | |
| 1711 | 1499 | Adapter->CurrNumRecvDescs = 0; |
| 1712 | − Adapter->PrevNumRecvDescs = 0; | |
| 1713 | − Adapter->LinkUpStatus = 0; | |
| 1500 | + Adapter->PrevNumRecvDescs = 0; | |
| 1501 | + Adapter->LinkUpStatus = 0; | |
| 1714 | 1502 | Adapter->LinkStatus = 0; |
| 1715 | − atomic_set(&Adapter->cntrlpktCnt,0); | |
| 1716 | − atomic_set (&Adapter->TotalPacketCount,0); | |
| 1717 | − Adapter->fw_download_done=FALSE; | |
| 1503 | + atomic_set(&Adapter->cntrlpktCnt, 0); | |
| 1504 | + atomic_set(&Adapter->TotalPacketCount, 0); | |
| 1505 | + Adapter->fw_download_done = FALSE; | |
| 1718 | 1506 | Adapter->LinkStatus = 0; |
| 1719 | − Adapter->AutoLinkUp = FALSE; | |
| 1507 | + Adapter->AutoLinkUp = FALSE; | |
| 1720 | 1508 | Adapter->IdleMode = FALSE; |
| 1721 | 1509 | Adapter->bShutStatus = FALSE; |
| 1722 | − | |
| 1723 | 1510 | } |
| 1724 | −S_CLASSIFIER_RULE *GetFragIPClsEntry(PMINI_ADAPTER Adapter,USHORT usIpIdentification,ULONG SrcIP) | |
| 1511 | + | |
| 1512 | +S_CLASSIFIER_RULE *GetFragIPClsEntry(PMINI_ADAPTER Adapter, USHORT usIpIdentification, ULONG SrcIP) | |
| 1725 | 1513 | { |
| 1726 | − UINT uiIndex=0; | |
| 1727 | − for(uiIndex=0;uiIndex<MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES;uiIndex++) | |
| 1728 | − { | |
| 1729 | − if((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed)&& | |
| 1730 | − (Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification)&& | |
| 1731 | − (Adapter->astFragmentedPktClassifierTable[uiIndex].ulSrcIpAddress== SrcIP)&& | |
| 1514 | + UINT uiIndex = 0; | |
| 1515 | + for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) { | |
| 1516 | + if ((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) && | |
| 1517 | + (Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification) && | |
| 1518 | + (Adapter->astFragmentedPktClassifierTable[uiIndex].ulSrcIpAddress == SrcIP) && | |
| 1732 | 1519 | !Adapter->astFragmentedPktClassifierTable[uiIndex].bOutOfOrderFragment) |
| 1520 | + | |
| 1733 | 1521 | return Adapter->astFragmentedPktClassifierTable[uiIndex].pstMatchedClassifierEntry; |
| 1734 | 1522 | } |
| 1735 | 1523 | return NULL; |
| 1736 | 1524 | } |
| 1737 | 1525 | |
| 1738 | −void AddFragIPClsEntry(PMINI_ADAPTER Adapter,PS_FRAGMENTED_PACKET_INFO psFragPktInfo) | |
| 1526 | +void AddFragIPClsEntry(PMINI_ADAPTER Adapter, PS_FRAGMENTED_PACKET_INFO psFragPktInfo) | |
| 1739 | 1527 | { |
| 1740 | − UINT uiIndex=0; | |
| 1741 | − for(uiIndex=0;uiIndex<MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES;uiIndex++) | |
| 1742 | − { | |
| 1743 | − if(!Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) | |
| 1744 | − { | |
| 1745 | − memcpy(&Adapter->astFragmentedPktClassifierTable[uiIndex],psFragPktInfo,sizeof(S_FRAGMENTED_PACKET_INFO)); | |
| 1528 | + UINT uiIndex = 0; | |
| 1529 | + for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) { | |
| 1530 | + if (!Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) { | |
| 1531 | + memcpy(&Adapter->astFragmentedPktClassifierTable[uiIndex], psFragPktInfo, sizeof(S_FRAGMENTED_PACKET_INFO)); | |
| 1746 | 1532 | break; |
| 1747 | 1533 | } |
| 1748 | 1534 | } |
| 1749 | − | |
| 1750 | 1535 | } |
| 1751 | 1536 | |
| 1752 | −void DelFragIPClsEntry(PMINI_ADAPTER Adapter,USHORT usIpIdentification,ULONG SrcIp) | |
| 1537 | +void DelFragIPClsEntry(PMINI_ADAPTER Adapter, USHORT usIpIdentification, ULONG SrcIp) | |
| 1753 | 1538 | { |
| 1754 | − UINT uiIndex=0; | |
| 1755 | − for(uiIndex=0;uiIndex<MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES;uiIndex++) | |
| 1756 | − { | |
| 1757 | − if((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed)&& | |
| 1758 | − (Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification)&& | |
| 1759 | − (Adapter->astFragmentedPktClassifierTable[uiIndex].ulSrcIpAddress== SrcIp)) | |
| 1760 | − memset(&Adapter->astFragmentedPktClassifierTable[uiIndex],0,sizeof(S_FRAGMENTED_PACKET_INFO)); | |
| 1539 | + UINT uiIndex = 0; | |
| 1540 | + for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) { | |
| 1541 | + if ((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) && | |
| 1542 | + (Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification) && | |
| 1543 | + (Adapter->astFragmentedPktClassifierTable[uiIndex].ulSrcIpAddress == SrcIp)) | |
| 1544 | + | |
| 1545 | + memset(&Adapter->astFragmentedPktClassifierTable[uiIndex], 0, sizeof(S_FRAGMENTED_PACKET_INFO)); | |
| 1761 | 1546 | } |
| 1762 | 1547 | } |
| 1763 | 1548 | |
| 1764 | −void update_per_cid_rx (PMINI_ADAPTER Adapter) | |
| 1549 | +void update_per_cid_rx(PMINI_ADAPTER Adapter) | |
| 1765 | 1550 | { |
| 1766 | − UINT qindex = 0; | |
| 1551 | + UINT qindex = 0; | |
| 1767 | 1552 | |
| 1768 | − if((jiffies - Adapter->liDrainCalculated) < XSECONDS) | |
| 1553 | + if ((jiffies - Adapter->liDrainCalculated) < XSECONDS) | |
| 1769 | 1554 | return; |
| 1770 | 1555 | |
| 1771 | − for(qindex = 0; qindex < HiPriority; qindex++) | |
| 1772 | − { | |
| 1773 | − if(Adapter->PackInfo[qindex].ucDirection == 0) | |
| 1774 | − { | |
| 1556 | + for (qindex = 0; qindex < HiPriority; qindex++) { | |
| 1557 | + if (Adapter->PackInfo[qindex].ucDirection == 0) { | |
| 1775 | 1558 | Adapter->PackInfo[qindex].uiCurrentRxRate = |
| 1776 | 1559 | (Adapter->PackInfo[qindex].uiCurrentRxRate + |
| 1777 | − Adapter->PackInfo[qindex].uiThisPeriodRxBytes)/2; | |
| 1560 | + Adapter->PackInfo[qindex].uiThisPeriodRxBytes) / 2; | |
| 1778 | 1561 | |
| 1779 | 1562 | Adapter->PackInfo[qindex].uiThisPeriodRxBytes = 0; |
| 1780 | − } | |
| 1781 | − else | |
| 1782 | − { | |
| 1563 | + } else { | |
| 1783 | 1564 | Adapter->PackInfo[qindex].uiCurrentDrainRate = |
| 1784 | 1565 | (Adapter->PackInfo[qindex].uiCurrentDrainRate + |
| 1785 | − Adapter->PackInfo[qindex].uiThisPeriodSentBytes)/2; | |
| 1786 | − | |
| 1787 | − Adapter->PackInfo[qindex].uiThisPeriodSentBytes=0; | |
| 1566 | + Adapter->PackInfo[qindex].uiThisPeriodSentBytes) / 2; | |
| 1567 | + Adapter->PackInfo[qindex].uiThisPeriodSentBytes = 0; | |
| 1788 | 1568 | } |
| 1789 | 1569 | } |
| 1790 | − Adapter->liDrainCalculated=jiffies; | |
| 1570 | + Adapter->liDrainCalculated = jiffies; | |
| 1791 | 1571 | } |
| 1792 | −void update_per_sf_desc_cnts( PMINI_ADAPTER Adapter) | |
| 1572 | + | |
| 1573 | +void update_per_sf_desc_cnts(PMINI_ADAPTER Adapter) | |
| 1793 | 1574 | { |
| 1794 | 1575 | INT iIndex = 0; |
| 1795 | 1576 | u32 uibuff[MAX_TARGET_DSX_BUFFERS]; |
| 1796 | 1577 | |
| 1797 | − if(!atomic_read (&Adapter->uiMBupdate)) | |
| 1578 | + if (!atomic_read(&Adapter->uiMBupdate)) | |
| 1798 | 1579 | return; |
| 1799 | 1580 | |
| 1800 | − if(rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (PUINT)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS)<0) | |
| 1801 | − { | |
| 1802 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm failed\n"); | |
| 1581 | + if (rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (PUINT)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS) < 0) { | |
| 1582 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "rdm failed\n"); | |
| 1803 | 1583 | return; |
| 1804 | 1584 | } |
| 1805 | − for(iIndex = 0;iIndex < HiPriority; iIndex++) | |
| 1806 | − { | |
| 1807 | − if(Adapter->PackInfo[iIndex].bValid && Adapter->PackInfo[iIndex].ucDirection) | |
| 1808 | − { | |
| 1809 | − if(Adapter->PackInfo[iIndex].usVCID_Value < MAX_TARGET_DSX_BUFFERS) | |
| 1810 | − { | |
| 1585 | + | |
| 1586 | + for (iIndex = 0; iIndex < HiPriority; iIndex++) { | |
| 1587 | + if (Adapter->PackInfo[iIndex].bValid && Adapter->PackInfo[iIndex].ucDirection) { | |
| 1588 | + if (Adapter->PackInfo[iIndex].usVCID_Value < MAX_TARGET_DSX_BUFFERS) | |
| 1811 | 1589 | atomic_set(&Adapter->PackInfo[iIndex].uiPerSFTxResourceCount, uibuff[Adapter->PackInfo[iIndex].usVCID_Value]); |
| 1812 | − } | |
| 1813 | 1590 | else |
| 1814 | − { | |
| 1815 | − BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid VCID : %x \n", | |
| 1816 | − Adapter->PackInfo[iIndex].usVCID_Value); | |
| 1817 | − } | |
| 1591 | + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid VCID : %x\n", Adapter->PackInfo[iIndex].usVCID_Value); | |
| 1818 | 1592 | } |
| 1819 | 1593 | } |
| 1820 | − atomic_set (&Adapter->uiMBupdate, FALSE); | |
| 1594 | + atomic_set(&Adapter->uiMBupdate, FALSE); | |
| 1821 | 1595 | } |
| 1822 | 1596 | |
| 1823 | 1597 | void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex) |
| 1824 | 1598 | { |
| 1825 | − struct sk_buff* PacketToDrop=NULL; | |
| 1826 | − struct net_device_stats* netstats = &Adapter->dev->stats; | |
| 1827 | − | |
| 1599 | + struct sk_buff *PacketToDrop = NULL; | |
| 1600 | + struct net_device_stats *netstats = &Adapter->dev->stats; | |
| 1828 | 1601 | spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock); |
| 1829 | 1602 | |
| 1830 | − while(Adapter->PackInfo[iQIndex].FirstTxQueue && | |
| 1831 | − atomic_read(&Adapter->TotalPacketCount)) | |
| 1832 | − { | |
| 1603 | + while (Adapter->PackInfo[iQIndex].FirstTxQueue && atomic_read(&Adapter->TotalPacketCount)) { | |
| 1833 | 1604 | PacketToDrop = Adapter->PackInfo[iQIndex].FirstTxQueue; |
| 1834 | − if(PacketToDrop && PacketToDrop->len) | |
| 1835 | − { | |
| 1605 | + if (PacketToDrop && PacketToDrop->len) { | |
| 1836 | 1606 | netstats->tx_dropped++; |
| 1837 | − DEQUEUEPACKET(Adapter->PackInfo[iQIndex].FirstTxQueue, \ | |
| 1838 | − Adapter->PackInfo[iQIndex].LastTxQueue); | |
| 1839 | − | |
| 1607 | + DEQUEUEPACKET(Adapter->PackInfo[iQIndex].FirstTxQueue, Adapter->PackInfo[iQIndex].LastTxQueue); | |
| 1840 | 1608 | Adapter->PackInfo[iQIndex].uiCurrentPacketsOnHost--; |
| 1841 | 1609 | Adapter->PackInfo[iQIndex].uiCurrentBytesOnHost -= PacketToDrop->len; |
| 1842 | 1610 | |
| 1843 | − //Adding dropped statistics | |
| 1611 | + /* Adding dropped statistics */ | |
| 1844 | 1612 | Adapter->PackInfo[iQIndex].uiDroppedCountBytes += PacketToDrop->len; |
| 1845 | 1613 | Adapter->PackInfo[iQIndex].uiDroppedCountPackets++; |
| 1846 | − | |
| 1847 | 1614 | dev_kfree_skb(PacketToDrop); |
| 1848 | 1615 | atomic_dec(&Adapter->TotalPacketCount); |
| 1849 | 1616 | } |
| 1850 | 1617 | } |
| 1851 | 1618 | spin_unlock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock); |
| 1852 | − | |
| 1853 | 1619 | } |
| 1854 | 1620 | |
| 1855 | −static void beceem_protocol_reset (PMINI_ADAPTER Adapter) | |
| 1621 | +static void beceem_protocol_reset(PMINI_ADAPTER Adapter) | |
| 1856 | 1622 | { |
| 1857 | 1623 | int i; |
| 1858 | − | |
| 1859 | 1624 | if (netif_msg_link(Adapter)) |
| 1860 | 1625 | pr_notice(PFX "%s: protocol reset\n", Adapter->dev->name); |
| 1861 | 1626 | |
| @@ -1864,32 +1629,22 @@ static void beceem_protocol_reset (PMINI_ADAPTER Adapter) · 2 unmodified lines | ||
| 1864 | 1629 | |
| 1865 | 1630 | Adapter->IdleMode = FALSE; |
| 1866 | 1631 | Adapter->LinkUpStatus = FALSE; |
| 1867 | − ClearTargetDSXBuffer(Adapter,0, TRUE); | |
| 1868 | − //Delete All Classifier Rules | |
| 1632 | + ClearTargetDSXBuffer(Adapter, 0, TRUE); | |
| 1633 | + /* Delete All Classifier Rules */ | |
| 1869 | 1634 | |
| 1870 | − for(i = 0;i<HiPriority;i++) | |
| 1871 | − { | |
| 1872 | − DeleteAllClassifiersForSF(Adapter,i); | |
| 1873 | − } | |
| 1635 | + for (i = 0; i < HiPriority; i++) | |
| 1636 | + DeleteAllClassifiersForSF(Adapter, i); | |
| 1874 | 1637 | |
| 1875 | 1638 | flush_all_queues(Adapter); |
| 1876 | 1639 | |
| 1877 | − if(Adapter->TimerActive == TRUE) | |
| 1640 | + if (Adapter->TimerActive == TRUE) | |
| 1878 | 1641 | Adapter->TimerActive = FALSE; |
| 1879 | 1642 | |
| 1880 | − memset(Adapter->astFragmentedPktClassifierTable, 0, | |
| 1881 | − sizeof(S_FRAGMENTED_PACKET_INFO) * MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES); | |
| 1643 | + memset(Adapter->astFragmentedPktClassifierTable, 0, sizeof(S_FRAGMENTED_PACKET_INFO) * MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES); | |
| 1882 | 1644 | |
| 1883 | − for(i = 0;i<HiPriority;i++) | |
| 1884 | − { | |
| 1885 | − //resetting only the first size (S_MIBS_SERVICEFLOW_TABLE) for the SF. | |
| 1886 | − // It is same between MIBs and SF. | |
| 1887 | − memset(&Adapter->PackInfo[i].stMibsExtServiceFlowTable, | |
| 1888 | − 0, sizeof(S_MIBS_EXTSERVICEFLOW_PARAMETERS)); | |
| 1645 | + for (i = 0; i < HiPriority; i++) { | |
| 1646 | + /* resetting only the first size (S_MIBS_SERVICEFLOW_TABLE) for the SF. */ | |
| 1647 | + /* It is same between MIBs and SF. */ | |
| 1648 | + memset(&Adapter->PackInfo[i].stMibsExtServiceFlowTable, 0, sizeof(S_MIBS_EXTSERVICEFLOW_PARAMETERS)); | |
| 1889 | 1649 | } |
| 1890 | 1650 | } |
| 1891 | − | |
| 1892 | − | |
| 1893 | − | |
| 1894 | − | |
| 1895 | − | |
| @@ -74,4 +74,6 @@ · 73 unmodified lines | ||
| 74 | 74 | #define DRV_VERSION VER_FILEVERSION_STR |
| 75 | 75 | #define PFX DRV_NAME " " |
| 76 | 76 | |
| 77 | +extern struct class *bcm_class; | |
| 78 | + | |
| 77 | 79 | #endif |
| @@ -4013,7 +4013,8 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut) · 4012 unmodified lines | ||
| 4013 | 4013 | if(uiTotalDataToCopy < ISOLength) |
| 4014 | 4014 | { |
| 4015 | 4015 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature"); |
| 4016 | − return STATUS_FAILURE; | |
| 4016 | + Status = STATUS_FAILURE; | |
| 4017 | + goto out; | |
| 4017 | 4018 | } |
| 4018 | 4019 | |
| 4019 | 4020 | uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) - |
| @@ -4026,7 +4027,8 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut) · 6 unmodified lines | ||
| 4026 | 4027 | if(uiTotalDataToCopy < ISOLength) |
| 4027 | 4028 | { |
| 4028 | 4029 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size"); |
| 4029 | − return STATUS_FAILURE; | |
| 4030 | + Status = STATUS_FAILURE; | |
| 4031 | + goto out; | |
| 4030 | 4032 | } |
| 4031 | 4033 | |
| 4032 | 4034 | uiTotalDataToCopy = ISOLength; |
| @@ -4143,7 +4145,8 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut) · 110 unmodified lines | ||
| 4143 | 4145 | if(uiTotalDataToCopy < ISOLength) |
| 4144 | 4146 | { |
| 4145 | 4147 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature"); |
| 4146 | − return STATUS_FAILURE; | |
| 4148 | + Status = STATUS_FAILURE; | |
| 4149 | + goto out; | |
| 4147 | 4150 | } |
| 4148 | 4151 | |
| 4149 | 4152 | uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) - |
| @@ -4156,7 +4159,8 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut) · 6 unmodified lines | ||
| 4156 | 4159 | if(uiTotalDataToCopy < ISOLength) |
| 4157 | 4160 | { |
| 4158 | 4161 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size"); |
| 4159 | − return STATUS_FAILURE; | |
| 4162 | + Status = STATUS_FAILURE; | |
| 4163 | + goto out; | |
| 4160 | 4164 | } |
| 4161 | 4165 | |
| 4162 | 4166 | uiTotalDataToCopy = ISOLength; |
| @@ -4257,6 +4261,7 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut) · 94 unmodified lines | ||
| 4257 | 4261 | |
| 4258 | 4262 | } |
| 4259 | 4263 | |
| 4264 | +out: | |
| 4260 | 4265 | kfree(Buff); |
| 4261 | 4266 | |
| 4262 | 4267 | return Status; |
| @@ -1,40 +0,0 @@ | ||
| 1 | −config BRCMUTIL | |
| 2 | − tristate | |
| 3 | − default n | |
| 4 | − | |
| 5 | −config BRCMSMAC | |
| 6 | − tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver" | |
| 7 | − default n | |
| 8 | − depends on PCI | |
| 9 | − depends on WLAN && MAC80211 | |
| 10 | − depends on X86 || MIPS | |
| 11 | − select BRCMUTIL | |
| 12 | − select FW_LOADER | |
| 13 | − select CRC_CCITT | |
| 14 | − ---help--- | |
| 15 | − This module adds support for PCIe wireless adapters based on Broadcom | |
| 16 | − IEEE802.11n SoftMAC chipsets. If you choose to build a module, it'll | |
| 17 | − be called brcmsmac.ko. | |
| 18 | − | |
| 19 | −config BRCMFMAC | |
| 20 | − tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver" | |
| 21 | − default n | |
| 22 | − depends on MMC | |
| 23 | − depends on WLAN && CFG80211 | |
| 24 | − depends on X86 || MIPS | |
| 25 | − select BRCMUTIL | |
| 26 | − select FW_LOADER | |
| 27 | − select WIRELESS_EXT | |
| 28 | − select WEXT_PRIV | |
| 29 | − ---help--- | |
| 30 | − This module adds support for embedded wireless adapters based on | |
| 31 | − Broadcom IEEE802.11n FullMAC chipsets. This driver uses the kernel's | |
| 32 | − wireless extensions subsystem. If you choose to build a module, | |
| 33 | − it'll be called brcmfmac.ko. | |
| 34 | − | |
| 35 | −config BRCMDBG | |
| 36 | − bool "Broadcom driver debug functions" | |
| 37 | − default n | |
| 38 | − depends on BRCMSMAC || BRCMFMAC | |
| 39 | − ---help--- | |
| 40 | − Selecting this enables additional code for debug purposes. | |
| @@ -1,24 +0,0 @@ | ||
| 1 | −# | |
| 2 | −# Makefile fragment for Broadcom 802.11n Networking Device Driver | |
| 3 | −# | |
| 4 | −# Copyright (c) 2010 Broadcom Corporation | |
| 5 | −# | |
| 6 | −# Permission to use, copy, modify, and/or distribute this software for any | |
| 7 | −# purpose with or without fee is hereby granted, provided that the above | |
| 8 | −# copyright notice and this permission notice appear in all copies. | |
| 9 | −# | |
| 10 | −# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
| 11 | −# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
| 12 | −# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
| 13 | −# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 14 | −# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | |
| 15 | −# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
| 16 | −# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
| 17 | − | |
| 18 | −# common flags | |
| 19 | −subdir-ccflags-y := -DBCMDMA32 | |
| 20 | −subdir-ccflags-$(CONFIG_BRCMDBG) += -DBCMDBG | |
| 21 | − | |
| 22 | −obj-$(CONFIG_BRCMUTIL) += brcmutil/ | |
| 23 | −obj-$(CONFIG_BRCMFMAC) += brcmfmac/ | |
| 24 | −obj-$(CONFIG_BRCMSMAC) += brcmsmac/ | |
| @@ -1 +0,0 @@ | ||
| 1 | −refer to: http://linuxwireless.org/en/users/Drivers/brcm80211 | |
| @@ -1,13 +0,0 @@ | ||
| 1 | −To Do List for Broadcom Mac80211 driver before getting in mainline | |
| 2 | − | |
| 3 | −Bugs | |
| 4 | −==== | |
| 5 | −- none known at this moment | |
| 6 | − | |
| 7 | −brcmfmac | |
| 8 | −===================== | |
| 9 | −- ASSERTS deprecated in mainline, replace by warning + error handling | |
| 10 | − | |
| 11 | −brcm80211 info page | |
| 12 | −===================== | |
| 13 | −http://linuxwireless.org/en/users/Drivers/brcm80211 | |
| @@ -1,39 +0,0 @@ | ||
| 1 | −# | |
| 2 | −# Makefile fragment for Broadcom 802.11n Networking Device Driver | |
| 3 | −# | |
| 4 | −# Copyright (c) 2010 Broadcom Corporation | |
| 5 | −# | |
| 6 | −# Permission to use, copy, modify, and/or distribute this software for any | |
| 7 | −# purpose with or without fee is hereby granted, provided that the above | |
| 8 | −# copyright notice and this permission notice appear in all copies. | |
| 9 | −# | |
| 10 | −# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
| 11 | −# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
| 12 | −# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
| 13 | −# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 14 | −# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | |
| 15 | −# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
| 16 | −# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
| 17 | − | |
| 18 | −ccflags-y := \ | |
| 19 | − -DBRCMF_FIRSTREAD=64 \ | |
| 20 | − -DBRCMF_SDALIGN=64 \ | |
| 21 | − -DMAX_HDR_READ=64 | |
| 22 | − | |
| 23 | −ccflags-$(CONFIG_BRCMDBG) += -DSHOW_EVENTS | |
| 24 | − | |
| 25 | −ccflags-y += \ | |
| 26 | − -Idrivers/staging/brcm80211/brcmfmac \ | |
| 27 | − -Idrivers/staging/brcm80211/include | |
| 28 | − | |
| 29 | −DHDOFILES = \ | |
| 30 | − wl_cfg80211.o \ | |
| 31 | − dhd_cdc.o \ | |
| 32 | − dhd_common.o \ | |
| 33 | − dhd_sdio.o \ | |
| 34 | − dhd_linux.o \ | |
| 35 | − bcmsdh.o \ | |
| 36 | − bcmsdh_sdmmc.o | |
| 37 | − | |
| 38 | −obj-$(CONFIG_BRCMFMAC) += brcmfmac.o | |
| 39 | −brcmfmac-objs += $(DHDOFILES) | |
| @@ -1,32 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * Copyright (c) 2011 Broadcom Corporation | |
| 3 | − * | |
| 4 | − * Permission to use, copy, modify, and/or distribute this software for any | |
| 5 | − * purpose with or without fee is hereby granted, provided that the above | |
| 6 | − * copyright notice and this permission notice appear in all copies. | |
| 7 | − * | |
| 8 | − * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
| 9 | − * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
| 10 | − * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
| 11 | − * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 12 | − * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | |
| 13 | − * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
| 14 | − * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
| 15 | − */ | |
| 16 | − | |
| 17 | −#ifndef _bcmchip_h_ | |
| 18 | −#define _bcmchip_h_ | |
| 19 | − | |
| 20 | −/* bcm4329 */ | |
| 21 | −/* SDIO device core, ID 0x829 */ | |
| 22 | −#define BCM4329_CORE_BUS_BASE 0x18011000 | |
| 23 | −/* internal memory core, ID 0x80e */ | |
| 24 | −#define BCM4329_CORE_SOCRAM_BASE 0x18003000 | |
| 25 | −/* ARM Cortex M3 core, ID 0x82a */ | |
| 26 | −#define BCM4329_CORE_ARM_BASE 0x18002000 | |
| 27 | −#define BCM4329_RAMSIZE 0x48000 | |
| 28 | −/* firmware name */ | |
| 29 | −#define BCM4329_FW_NAME "brcm/bcm4329-fullmac-4.bin" | |
| 30 | −#define BCM4329_NV_NAME "brcm/bcm4329-fullmac-4.txt" | |
| 31 | − | |
| 32 | −#endif /* _bcmchip_h_ */ | |
| @@ -1,642 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * Copyright (c) 2010 Broadcom Corporation | |
| 3 | − * | |
| 4 | − * Permission to use, copy, modify, and/or distribute this software for any | |
| 5 | − * purpose with or without fee is hereby granted, provided that the above | |
| 6 | − * copyright notice and this permission notice appear in all copies. | |
| 7 | − * | |
| 8 | − * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
| 9 | − * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
| 10 | − * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
| 11 | − * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 12 | − * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | |
| 13 | − * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
| 14 | − * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
| 15 | − */ | |
| 16 | −/* ****************** SDIO CARD Interface Functions **************************/ | |
| 17 | − | |
| 18 | −#include <linux/types.h> | |
| 19 | −#include <linux/netdevice.h> | |
| 20 | −#include <linux/pci.h> | |
| 21 | −#include <linux/pci_ids.h> | |
| 22 | −#include <linux/sched.h> | |
| 23 | −#include <linux/completion.h> | |
| 24 | − | |
| 25 | −#include <defs.h> | |
| 26 | −#include <brcm_hw_ids.h> | |
| 27 | −#include <brcmu_utils.h> | |
| 28 | −#include <brcmu_wifi.h> | |
| 29 | −#include <soc.h> | |
| 30 | −#include "dhd.h" | |
| 31 | −#include "dhd_bus.h" | |
| 32 | −#include "sdio_host.h" | |
| 33 | − | |
| 34 | −#define SDIOH_API_ACCESS_RETRY_LIMIT 2 | |
| 35 | − | |
| 36 | −#define BRCMF_SD_ERROR_VAL 0x0001 /* Error */ | |
| 37 | −#define BRCMF_SD_INFO_VAL 0x0002 /* Info */ | |
| 38 | − | |
| 39 | − | |
| 40 | −#ifdef BCMDBG | |
| 41 | −#define BRCMF_SD_ERROR(x) \ | |
| 42 | − do { \ | |
| 43 | − if ((brcmf_sdio_msglevel & BRCMF_SD_ERROR_VAL) && \ | |
| 44 | − net_ratelimit()) \ | |
| 45 | − printk x; \ | |
| 46 | − } while (0) | |
| 47 | −#define BRCMF_SD_INFO(x) \ | |
| 48 | − do { \ | |
| 49 | − if ((brcmf_sdio_msglevel & BRCMF_SD_INFO_VAL) && \ | |
| 50 | − net_ratelimit()) \ | |
| 51 | − printk x; \ | |
| 52 | − } while (0) | |
| 53 | −#else /* BCMDBG */ | |
| 54 | −#define BRCMF_SD_ERROR(x) | |
| 55 | −#define BRCMF_SD_INFO(x) | |
| 56 | −#endif /* BCMDBG */ | |
| 57 | − | |
| 58 | −/* debugging macros */ | |
| 59 | −#define SDLX_MSG(x) | |
| 60 | − | |
| 61 | −#define SDIOH_CMD_TYPE_NORMAL 0 /* Normal command */ | |
| 62 | −#define SDIOH_CMD_TYPE_APPEND 1 /* Append command */ | |
| 63 | −#define SDIOH_CMD_TYPE_CUTTHRU 2 /* Cut-through command */ | |
| 64 | − | |
| 65 | −#define SDIOH_DATA_PIO 0 /* PIO mode */ | |
| 66 | −#define SDIOH_DATA_DMA 1 /* DMA mode */ | |
| 67 | − | |
| 68 | −struct brcmf_sdio_card { | |
| 69 | − bool init_success; /* underlying driver successfully attached */ | |
| 70 | − void *sdioh; /* handler for sdioh */ | |
| 71 | − u32 vendevid; /* Target Vendor and Device ID on SD bus */ | |
| 72 | − bool regfail; /* Save status of last | |
| 73 | − reg_read/reg_write call */ | |
| 74 | − u32 sbwad; /* Save backplane window address */ | |
| 75 | −}; | |
| 76 | − | |
| 77 | −/** | |
| 78 | − * SDIO Host Controller info | |
| 79 | − */ | |
| 80 | −struct sdio_hc { | |
| 81 | − struct sdio_hc *next; | |
| 82 | − struct device *dev; /* platform device handle */ | |
| 83 | − void *regs; /* SDIO Host Controller address */ | |
| 84 | − struct brcmf_sdio_card *card; | |
| 85 | − void *ch; | |
| 86 | − unsigned int oob_irq; | |
| 87 | − unsigned long oob_flags; /* OOB Host specifiction | |
| 88 | − as edge and etc */ | |
| 89 | − bool oob_irq_registered; | |
| 90 | −}; | |
| 91 | − | |
| 92 | −/* local copy of bcm sd handler */ | |
| 93 | −static struct brcmf_sdio_card *l_card; | |
| 94 | − | |
| 95 | −const uint brcmf_sdio_msglevel = BRCMF_SD_ERROR_VAL; | |
| 96 | − | |
| 97 | −static struct sdio_hc *sdhcinfo; | |
| 98 | − | |
| 99 | −/* driver info, initialized when brcmf_sdio_register is called */ | |
| 100 | −static struct brcmf_sdioh_driver drvinfo = { NULL, NULL }; | |
| 101 | − | |
| 102 | −/* Module parameters specific to each host-controller driver */ | |
| 103 | − | |
| 104 | −module_param(sd_msglevel, uint, 0); | |
| 105 | − | |
| 106 | −extern uint sd_f2_blocksize; | |
| 107 | −module_param(sd_f2_blocksize, int, 0); | |
| 108 | − | |
| 109 | −/* forward declarations */ | |
| 110 | −int brcmf_sdio_probe(struct device *dev); | |
| 111 | −EXPORT_SYMBOL(brcmf_sdio_probe); | |
| 112 | − | |
| 113 | −int brcmf_sdio_remove(struct device *dev); | |
| 114 | −EXPORT_SYMBOL(brcmf_sdio_remove); | |
| 115 | − | |
| 116 | −struct brcmf_sdio_card* | |
| 117 | −brcmf_sdcard_attach(void *cfghdl, u32 *regsva, uint irq) | |
| 118 | −{ | |
| 119 | − struct brcmf_sdio_card *card; | |
| 120 | − | |
| 121 | − card = kzalloc(sizeof(struct brcmf_sdio_card), GFP_ATOMIC); | |
| 122 | − if (card == NULL) { | |
| 123 | − BRCMF_SD_ERROR(("sdcard_attach: out of memory")); | |
| 124 | − return NULL; | |
| 125 | − } | |
| 126 | − | |
| 127 | − /* save the handler locally */ | |
| 128 | − l_card = card; | |
| 129 | − | |
| 130 | − card->sdioh = brcmf_sdioh_attach(cfghdl, irq); | |
| 131 | − if (!card->sdioh) { | |
| 132 | − brcmf_sdcard_detach(card); | |
| 133 | − return NULL; | |
| 134 | − } | |
| 135 | − | |
| 136 | − card->init_success = true; | |
| 137 | − | |
| 138 | − *regsva = SI_ENUM_BASE; | |
| 139 | − | |
| 140 | − /* Report the BAR, to fix if needed */ | |
| 141 | − card->sbwad = SI_ENUM_BASE; | |
| 142 | − return card; | |
| 143 | −} | |
| 144 | − | |
| 145 | −int brcmf_sdcard_detach(struct brcmf_sdio_card *card) | |
| 146 | −{ | |
| 147 | − if (card != NULL) { | |
| 148 | − if (card->sdioh) { | |
| 149 | − brcmf_sdioh_detach(card->sdioh); | |
| 150 | − card->sdioh = NULL; | |
| 151 | − } | |
| 152 | − kfree(card); | |
| 153 | − } | |
| 154 | − | |
| 155 | − l_card = NULL; | |
| 156 | − return 0; | |
| 157 | −} | |
| 158 | − | |
| 159 | −int | |
| 160 | −brcmf_sdcard_iovar_op(struct brcmf_sdio_card *card, const char *name, | |
| 161 | − void *params, int plen, void *arg, int len, bool set) | |
| 162 | −{ | |
| 163 | − return brcmf_sdioh_iovar_op(card->sdioh, name, params, plen, arg, | |
| 164 | − len, set); | |
| 165 | −} | |
| 166 | − | |
| 167 | −int brcmf_sdcard_intr_enable(struct brcmf_sdio_card *card) | |
| 168 | −{ | |
| 169 | − return brcmf_sdioh_interrupt_set(card->sdioh, true); | |
| 170 | −} | |
| 171 | − | |
| 172 | −int brcmf_sdcard_intr_disable(struct brcmf_sdio_card *card) | |
| 173 | −{ | |
| 174 | − return brcmf_sdioh_interrupt_set(card->sdioh, false); | |
| 175 | −} | |
| 176 | − | |
| 177 | −int brcmf_sdcard_intr_reg(struct brcmf_sdio_card *card, | |
| 178 | − void (*fn)(void *), void *argh) | |
| 179 | −{ | |
| 180 | − return brcmf_sdioh_interrupt_register(card->sdioh, fn, argh); | |
| 181 | −} | |
| 182 | − | |
| 183 | −int brcmf_sdcard_intr_dereg(struct brcmf_sdio_card *card) | |
| 184 | −{ | |
| 185 | − return brcmf_sdioh_interrupt_deregister(card->sdioh); | |
| 186 | −} | |
| 187 | − | |
| 188 | −u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_card *card, uint fnc_num, u32 addr, | |
| 189 | − int *err) | |
| 190 | −{ | |
| 191 | − int status; | |
| 192 | − s32 retry = 0; | |
| 193 | − u8 data = 0; | |
| 194 | − | |
| 195 | − if (!card) | |
| 196 | − card = l_card; | |
| 197 | − | |
| 198 | − do { | |
| 199 | − if (retry) /* wait for 1 ms till bus get settled down */ | |
| 200 | − udelay(1000); | |
| 201 | − status = | |
| 202 | − brcmf_sdioh_cfg_read(card->sdioh, fnc_num, addr, | |
| 203 | − (u8 *) &data); | |
| 204 | − } while (status != 0 | |
| 205 | − && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT)); | |
| 206 | − if (err) | |
| 207 | − *err = status; | |
| 208 | − | |
| 209 | − BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n", | |
| 210 | − __func__, fnc_num, addr, data)); | |
| 211 | − | |
| 212 | − return data; | |
| 213 | −} | |
| 214 | − | |
| 215 | −void | |
| 216 | −brcmf_sdcard_cfg_write(struct brcmf_sdio_card *card, uint fnc_num, u32 addr, | |
| 217 | − u8 data, int *err) | |
| 218 | −{ | |
| 219 | − int status; | |
| 220 | − s32 retry = 0; | |
| 221 | − | |
| 222 | − if (!card) | |
| 223 | − card = l_card; | |
| 224 | − | |
| 225 | − do { | |
| 226 | − if (retry) /* wait for 1 ms till bus get settled down */ | |
| 227 | − udelay(1000); | |
| 228 | − status = | |
| 229 | − brcmf_sdioh_cfg_write(card->sdioh, fnc_num, addr, | |
| 230 | − (u8 *) &data); | |
| 231 | − } while (status != 0 | |
| 232 | − && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT)); | |
| 233 | − if (err) | |
| 234 | − *err = status; | |
| 235 | − | |
| 236 | − BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n", | |
| 237 | − __func__, fnc_num, addr, data)); | |
| 238 | −} | |
| 239 | − | |
| 240 | −u32 brcmf_sdcard_cfg_read_word(struct brcmf_sdio_card *card, uint fnc_num, | |
| 241 | − u32 addr, int *err) | |
| 242 | −{ | |
| 243 | − int status; | |
| 244 | − u32 data = 0; | |
| 245 | − | |
| 246 | − if (!card) | |
| 247 | − card = l_card; | |
| 248 | − | |
| 249 | − status = brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL, | |
| 250 | − SDIOH_READ, fnc_num, addr, &data, 4); | |
| 251 | − | |
| 252 | − if (err) | |
| 253 | − *err = status; | |
| 254 | − | |
| 255 | − BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n", | |
| 256 | − __func__, fnc_num, addr, data)); | |
| 257 | − | |
| 258 | − return data; | |
| 259 | −} | |
| 260 | − | |
| 261 | −void | |
| 262 | −brcmf_sdcard_cfg_write_word(struct brcmf_sdio_card *card, uint fnc_num, | |
| 263 | − u32 addr, u32 data, int *err) | |
| 264 | −{ | |
| 265 | − int status; | |
| 266 | − | |
| 267 | − if (!card) | |
| 268 | − card = l_card; | |
| 269 | − | |
| 270 | − status = | |
| 271 | − brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL, | |
| 272 | − SDIOH_WRITE, fnc_num, addr, &data, 4); | |
| 273 | − | |
| 274 | − if (err) | |
| 275 | − *err = status; | |
| 276 | − | |
| 277 | − BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n", | |
| 278 | − __func__, fnc_num, addr, data)); | |
| 279 | −} | |
| 280 | − | |
| 281 | −int brcmf_sdcard_cis_read(struct brcmf_sdio_card *card, uint func, u8 * cis, | |
| 282 | − uint length) | |
| 283 | −{ | |
| 284 | − int status; | |
| 285 | − | |
| 286 | − u8 *tmp_buf, *tmp_ptr; | |
| 287 | − u8 *ptr; | |
| 288 | − bool ascii = func & ~0xf; | |
| 289 | − func &= 0x7; | |
| 290 | − | |
| 291 | − if (!card) | |
| 292 | − card = l_card; | |
| 293 | − | |
| 294 | − status = brcmf_sdioh_cis_read(card->sdioh, func, cis, length); | |
| 295 | − | |
| 296 | − if (ascii) { | |
| 297 | − /* Move binary bits to tmp and format them | |
| 298 | − into the provided buffer. */ | |
| 299 | − tmp_buf = kmalloc(length, GFP_ATOMIC); | |
| 300 | − if (tmp_buf == NULL) { | |
| 301 | − BRCMF_SD_ERROR(("%s: out of memory\n", __func__)); | |
| 302 | − return -ENOMEM; | |
| 303 | − } | |
| 304 | − memcpy(tmp_buf, cis, length); | |
| 305 | − for (tmp_ptr = tmp_buf, ptr = cis; ptr < (cis + length - 4); | |
| 306 | − tmp_ptr++) { | |
| 307 | − ptr += sprintf((char *)ptr, "%.2x ", *tmp_ptr & 0xff); | |
| 308 | − if ((((tmp_ptr - tmp_buf) + 1) & 0xf) == 0) | |
| 309 | − ptr += sprintf((char *)ptr, "\n"); | |
| 310 | − } | |
| 311 | − kfree(tmp_buf); | |
| 312 | − } | |
| 313 | − | |
| 314 | − return status; | |
| 315 | −} | |
| 316 | − | |
| 317 | −static int | |
| 318 | −brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_card *card, u32 address) | |
| 319 | −{ | |
| 320 | − int err = 0; | |
| 321 | − brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, | |
| 322 | − (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err); | |
| 323 | − if (!err) | |
| 324 | − brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, | |
| 325 | − SBSDIO_FUNC1_SBADDRMID, | |
| 326 | − (address >> 16) & SBSDIO_SBADDRMID_MASK, | |
| 327 | − &err); | |
| 328 | − if (!err) | |
| 329 | − brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, | |
| 330 | − SBSDIO_FUNC1_SBADDRHIGH, | |
| 331 | − (address >> 24) & SBSDIO_SBADDRHIGH_MASK, | |
| 332 | − &err); | |
| 333 | − | |
| 334 | − return err; | |
| 335 | −} | |
| 336 | − | |
| 337 | −u32 brcmf_sdcard_reg_read(struct brcmf_sdio_card *card, u32 addr, uint size) | |
| 338 | −{ | |
| 339 | − int status; | |
| 340 | − u32 word = 0; | |
| 341 | − uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; | |
| 342 | − | |
| 343 | − BRCMF_SD_INFO(("%s:fun = 1, addr = 0x%x, ", __func__, addr)); | |
| 344 | − | |
| 345 | − if (!card) | |
| 346 | − card = l_card; | |
| 347 | − | |
| 348 | − if (bar0 != card->sbwad) { | |
| 349 | − if (brcmf_sdcard_set_sbaddr_window(card, bar0)) | |
| 350 | − return 0xFFFFFFFF; | |
| 351 | − | |
| 352 | − card->sbwad = bar0; | |
| 353 | − } | |
| 354 | − | |
| 355 | − addr &= SBSDIO_SB_OFT_ADDR_MASK; | |
| 356 | − if (size == 4) | |
| 357 | − addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; | |
| 358 | − | |
| 359 | − status = brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL, | |
| 360 | − SDIOH_READ, SDIO_FUNC_1, addr, &word, size); | |
| 361 | − | |
| 362 | − card->regfail = (status != 0); | |
| 363 | − | |
| 364 | − BRCMF_SD_INFO(("u32data = 0x%x\n", word)); | |
| 365 | − | |
| 366 | − /* if ok, return appropriately masked word */ | |
| 367 | − if (status == 0) { | |
| 368 | − switch (size) { | |
| 369 | − case sizeof(u8): | |
| 370 | − return word & 0xff; | |
| 371 | − case sizeof(u16): | |
| 372 | − return word & 0xffff; | |
| 373 | − case sizeof(u32): | |
| 374 | − return word; | |
| 375 | − default: | |
| 376 | − card->regfail = true; | |
| 377 | − | |
| 378 | − } | |
| 379 | − } | |
| 380 | − | |
| 381 | − /* otherwise, bad sdio access or invalid size */ | |
| 382 | − BRCMF_SD_ERROR(("%s: error reading addr 0x%04x size %d\n", __func__, | |
| 383 | − addr, size)); | |
| 384 | − return 0xFFFFFFFF; | |
| 385 | −} | |
| 386 | − | |
| 387 | −u32 brcmf_sdcard_reg_write(struct brcmf_sdio_card *card, u32 addr, uint size, | |
| 388 | − u32 data) | |
| 389 | −{ | |
| 390 | − int status; | |
| 391 | − uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; | |
| 392 | − int err = 0; | |
| 393 | − | |
| 394 | − BRCMF_SD_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n", | |
| 395 | − __func__, addr, size * 8, data)); | |
| 396 | − | |
| 397 | − if (!card) | |
| 398 | − card = l_card; | |
| 399 | − | |
| 400 | − if (bar0 != card->sbwad) { | |
| 401 | − err = brcmf_sdcard_set_sbaddr_window(card, bar0); | |
| 402 | − if (err) | |
| 403 | − return err; | |
| 404 | − | |
| 405 | − card->sbwad = bar0; | |
| 406 | − } | |
| 407 | − | |
| 408 | − addr &= SBSDIO_SB_OFT_ADDR_MASK; | |
| 409 | − if (size == 4) | |
| 410 | − addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; | |
| 411 | − status = | |
| 412 | − brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL, | |
| 413 | − SDIOH_WRITE, SDIO_FUNC_1, addr, &data, size); | |
| 414 | − card->regfail = (status != 0); | |
| 415 | − | |
| 416 | − if (status == 0) | |
| 417 | − return 0; | |
| 418 | − | |
| 419 | − BRCMF_SD_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n", | |
| 420 | − __func__, data, addr, size)); | |
| 421 | − return 0xFFFFFFFF; | |
| 422 | −} | |
| 423 | − | |
| 424 | −bool brcmf_sdcard_regfail(struct brcmf_sdio_card *card) | |
| 425 | −{ | |
| 426 | − return card->regfail; | |
| 427 | −} | |
| 428 | − | |
| 429 | −int | |
| 430 | −brcmf_sdcard_recv_buf(struct brcmf_sdio_card *card, u32 addr, uint fn, | |
| 431 | − uint flags, | |
| 432 | − u8 *buf, uint nbytes, struct sk_buff *pkt, | |
| 433 | − void (*complete)(void *handle, int status, | |
| 434 | − bool sync_waiting), | |
| 435 | − void *handle) | |
| 436 | −{ | |
| 437 | − int status; | |
| 438 | − uint incr_fix; | |
| 439 | − uint width; | |
| 440 | − uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; | |
| 441 | − int err = 0; | |
| 442 | − | |
| 443 | − BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n", | |
| 444 | − __func__, fn, addr, nbytes)); | |
| 445 | − | |
| 446 | − /* Async not implemented yet */ | |
| 447 | − if (flags & SDIO_REQ_ASYNC) | |
| 448 | − return -ENOTSUPP; | |
| 449 | − | |
| 450 | − if (bar0 != card->sbwad) { | |
| 451 | − err = brcmf_sdcard_set_sbaddr_window(card, bar0); | |
| 452 | − if (err) | |
| 453 | − return err; | |
| 454 | − | |
| 455 | − card->sbwad = bar0; | |
| 456 | − } | |
| 457 | − | |
| 458 | − addr &= SBSDIO_SB_OFT_ADDR_MASK; | |
| 459 | − | |
| 460 | − incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC; | |
| 461 | − width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; | |
| 462 | − if (width == 4) | |
| 463 | − addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; | |
| 464 | − | |
| 465 | − status = brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO, | |
| 466 | − incr_fix, SDIOH_READ, fn, addr, width, nbytes, buf, pkt); | |
| 467 | − | |
| 468 | − return status; | |
| 469 | −} | |
| 470 | − | |
| 471 | −int | |
| 472 | −brcmf_sdcard_send_buf(struct brcmf_sdio_card *card, u32 addr, uint fn, | |
| 473 | − uint flags, u8 *buf, uint nbytes, void *pkt, | |
| 474 | − void (*complete)(void *handle, int status, | |
| 475 | − bool sync_waiting), | |
| 476 | − void *handle) | |
| 477 | −{ | |
| 478 | − uint incr_fix; | |
| 479 | − uint width; | |
| 480 | − uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; | |
| 481 | − int err = 0; | |
| 482 | − | |
| 483 | − BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n", | |
| 484 | − __func__, fn, addr, nbytes)); | |
| 485 | − | |
| 486 | − /* Async not implemented yet */ | |
| 487 | − if (flags & SDIO_REQ_ASYNC) | |
| 488 | − return -ENOTSUPP; | |
| 489 | − | |
| 490 | − if (bar0 != card->sbwad) { | |
| 491 | − err = brcmf_sdcard_set_sbaddr_window(card, bar0); | |
| 492 | − if (err) | |
| 493 | − return err; | |
| 494 | − | |
| 495 | − card->sbwad = bar0; | |
| 496 | − } | |
| 497 | − | |
| 498 | − addr &= SBSDIO_SB_OFT_ADDR_MASK; | |
| 499 | − | |
| 500 | − incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC; | |
| 501 | − width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; | |
| 502 | − if (width == 4) | |
| 503 | − addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; | |
| 504 | − | |
| 505 | − return brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO, | |
| 506 | − incr_fix, SDIOH_WRITE, fn, addr, width, nbytes, buf, pkt); | |
| 507 | −} | |
| 508 | − | |
| 509 | −int brcmf_sdcard_rwdata(struct brcmf_sdio_card *card, uint rw, u32 addr, | |
| 510 | − u8 *buf, uint nbytes) | |
| 511 | −{ | |
| 512 | − addr &= SBSDIO_SB_OFT_ADDR_MASK; | |
| 513 | − addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; | |
| 514 | − | |
| 515 | − return brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO, | |
| 516 | − SDIOH_DATA_INC, (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1, | |
| 517 | − addr, 4, nbytes, buf, NULL); | |
| 518 | −} | |
| 519 | − | |
| 520 | −int brcmf_sdcard_abort(struct brcmf_sdio_card *card, uint fn) | |
| 521 | −{ | |
| 522 | − return brcmf_sdioh_abort(card->sdioh, fn); | |
| 523 | −} | |
| 524 | − | |
| 525 | −int brcmf_sdcard_query_device(struct brcmf_sdio_card *card) | |
| 526 | −{ | |
| 527 | − card->vendevid = (PCI_VENDOR_ID_BROADCOM << 16) | 0; | |
| 528 | − return card->vendevid; | |
| 529 | −} | |
| 530 | − | |
| 531 | −u32 brcmf_sdcard_cur_sbwad(struct brcmf_sdio_card *card) | |
| 532 | −{ | |
| 533 | − if (!card) | |
| 534 | − card = l_card; | |
| 535 | − | |
| 536 | − return card->sbwad; | |
| 537 | −} | |
| 538 | − | |
| 539 | −int brcmf_sdio_probe(struct device *dev) | |
| 540 | −{ | |
| 541 | − struct sdio_hc *sdhc = NULL; | |
| 542 | − u32 regs = 0; | |
| 543 | − struct brcmf_sdio_card *card = NULL; | |
| 544 | − int irq = 0; | |
| 545 | − u32 vendevid; | |
| 546 | − unsigned long irq_flags = 0; | |
| 547 | − | |
| 548 | − /* allocate SDIO Host Controller state info */ | |
| 549 | − sdhc = kzalloc(sizeof(struct sdio_hc), GFP_ATOMIC); | |
| 550 | − if (!sdhc) { | |
| 551 | − SDLX_MSG(("%s: out of memory\n", __func__)); | |
| 552 | − goto err; | |
| 553 | − } | |
| 554 | − sdhc->dev = (void *)dev; | |
| 555 | − | |
| 556 | − card = brcmf_sdcard_attach((void *)0, ®s, irq); | |
| 557 | − if (!card) { | |
| 558 | − SDLX_MSG(("%s: attach failed\n", __func__)); | |
| 559 | − goto err; | |
| 560 | − } | |
| 561 | − | |
| 562 | − sdhc->card = card; | |
| 563 | − sdhc->oob_irq = irq; | |
| 564 | − sdhc->oob_flags = irq_flags; | |
| 565 | − sdhc->oob_irq_registered = false; /* to make sure.. */ | |
| 566 | − | |
| 567 | − /* chain SDIO Host Controller info together */ | |
| 568 | − sdhc->next = sdhcinfo; | |
| 569 | − sdhcinfo = sdhc; | |
| 570 | − /* Read the vendor/device ID from the CIS */ | |
| 571 | − vendevid = brcmf_sdcard_query_device(card); | |
| 572 | − | |
| 573 | − /* try to attach to the target device */ | |
| 574 | − sdhc->ch = drvinfo.attach((vendevid >> 16), (vendevid & 0xFFFF), | |
| 575 | − 0, 0, 0, 0, regs, card); | |
| 576 | − if (!sdhc->ch) { | |
| 577 | − SDLX_MSG(("%s: device attach failed\n", __func__)); | |
| 578 | − goto err; | |
| 579 | − } | |
| 580 | − | |
| 581 | − return 0; | |
| 582 | − | |
| 583 | − /* error handling */ | |
| 584 | −err: | |
| 585 | − if (sdhc) { | |
| 586 | − if (sdhc->card) | |
| 587 | − brcmf_sdcard_detach(sdhc->card); | |
| 588 | − kfree(sdhc); | |
| 589 | − } | |
| 590 | − | |
| 591 | − return -ENODEV; | |
| 592 | −} | |
| 593 | − | |
| 594 | −int brcmf_sdio_remove(struct device *dev) | |
| 595 | −{ | |
| 596 | − struct sdio_hc *sdhc, *prev; | |
| 597 | − | |
| 598 | − sdhc = sdhcinfo; | |
| 599 | − drvinfo.detach(sdhc->ch); | |
| 600 | − brcmf_sdcard_detach(sdhc->card); | |
| 601 | − /* find the SDIO Host Controller state for this pdev | |
| 602 | − and take it out from the list */ | |
| 603 | − for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) { | |
| 604 | − if (sdhc->dev == (void *)dev) { | |
| 605 | − if (prev) | |
| 606 | − prev->next = sdhc->next; | |
| 607 | − else | |
| 608 | − sdhcinfo = NULL; | |
| 609 | − break; | |
| 610 | − } | |
| 611 | − prev = sdhc; | |
| 612 | − } | |
| 613 | − if (!sdhc) { | |
| 614 | − SDLX_MSG(("%s: failed\n", __func__)); | |
| 615 | − return 0; | |
| 616 | − } | |
| 617 | − | |
| 618 | − /* release SDIO Host Controller info */ | |
| 619 | − kfree(sdhc); | |
| 620 | − return 0; | |
| 621 | −} | |
| 622 | − | |
| 623 | −int brcmf_sdio_register(struct brcmf_sdioh_driver *driver) | |
| 624 | −{ | |
| 625 | − drvinfo = *driver; | |
| 626 | − | |
| 627 | − SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n")); | |
| 628 | − return brcmf_sdio_function_init(); | |
| 629 | −} | |
| 630 | − | |
| 631 | −void brcmf_sdio_unregister(void) | |
| 632 | −{ | |
| 633 | − brcmf_sdio_function_cleanup(); | |
| 634 | −} | |
| 635 | − | |
| 636 | −void brcmf_sdio_wdtmr_enable(bool enable) | |
| 637 | −{ | |
| 638 | − if (enable) | |
| 639 | − brcmf_sdbrcm_wd_timer(sdhcinfo->ch, brcmf_watchdog_ms); | |
| 640 | − else | |
| 641 | − brcmf_sdbrcm_wd_timer(sdhcinfo->ch, 0); | |
| 642 | −} | |
| @@ -1,1196 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * Copyright (c) 2010 Broadcom Corporation | |
| 3 | − * | |
| 4 | − * Permission to use, copy, modify, and/or distribute this software for any | |
| 5 | − * purpose with or without fee is hereby granted, provided that the above | |
| 6 | − * copyright notice and this permission notice appear in all copies. | |
| 7 | − * | |
| 8 | − * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
| 9 | − * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
| 10 | − * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
| 11 | − * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 12 | − * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | |
| 13 | − * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
| 14 | − * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
| 15 | − */ | |
| 16 | −#include <linux/types.h> | |
| 17 | −#include <linux/netdevice.h> | |
| 18 | −#include <linux/mmc/sdio.h> | |
| 19 | −#include <linux/mmc/core.h> | |
| 20 | −#include <linux/mmc/sdio_func.h> | |
| 21 | −#include <linux/mmc/sdio_ids.h> | |
| 22 | −#include <linux/mmc/card.h> | |
| 23 | −#include <linux/suspend.h> | |
| 24 | −#include <linux/errno.h> | |
| 25 | −#include <linux/sched.h> /* request_irq() */ | |
| 26 | −#include <net/cfg80211.h> | |
| 27 | − | |
| 28 | −#include <defs.h> | |
| 29 | −#include <brcm_hw_ids.h> | |
| 30 | −#include <brcmu_utils.h> | |
| 31 | −#include <brcmu_wifi.h> | |
| 32 | −#include "sdio_host.h" | |
| 33 | −#include "dhd.h" | |
| 34 | −#include "dhd_dbg.h" | |
| 35 | −#include "wl_cfg80211.h" | |
| 36 | − | |
| 37 | −#define BLOCK_SIZE_64 64 | |
| 38 | −#define BLOCK_SIZE_512 512 | |
| 39 | −#define BLOCK_SIZE_4318 64 | |
| 40 | −#define BLOCK_SIZE_4328 512 | |
| 41 | − | |
| 42 | −/* private bus modes */ | |
| 43 | −#define SDIOH_MODE_SD4 2 | |
| 44 | − | |
| 45 | −#define CLIENT_INTR 0x100 /* Get rid of this! */ | |
| 46 | − | |
| 47 | −#if !defined(SDIO_VENDOR_ID_BROADCOM) | |
| 48 | −#define SDIO_VENDOR_ID_BROADCOM 0x02d0 | |
| 49 | −#endif /* !defined(SDIO_VENDOR_ID_BROADCOM) */ | |
| 50 | − | |
| 51 | −#define SDIO_DEVICE_ID_BROADCOM_DEFAULT 0x0000 | |
| 52 | − | |
| 53 | −#define DMA_ALIGN_MASK 0x03 | |
| 54 | − | |
| 55 | −#if !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) | |
| 56 | −#define SDIO_DEVICE_ID_BROADCOM_4325_SDGWB 0x0492 /* BCM94325SDGWB */ | |
| 57 | −#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) */ | |
| 58 | −#if !defined(SDIO_DEVICE_ID_BROADCOM_4325) | |
| 59 | −#define SDIO_DEVICE_ID_BROADCOM_4325 0x0493 | |
| 60 | −#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325) */ | |
| 61 | −#if !defined(SDIO_DEVICE_ID_BROADCOM_4329) | |
| 62 | −#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 | |
| 63 | −#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */ | |
| 64 | −#if !defined(SDIO_DEVICE_ID_BROADCOM_4319) | |
| 65 | −#define SDIO_DEVICE_ID_BROADCOM_4319 0x4319 | |
| 66 | −#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */ | |
| 67 | − | |
| 68 | −/* Common msglevel constants */ | |
| 69 | −#define SDH_ERROR_VAL 0x0001 /* Error */ | |
| 70 | −#define SDH_TRACE_VAL 0x0002 /* Trace */ | |
| 71 | −#define SDH_INFO_VAL 0x0004 /* Info */ | |
| 72 | −#define SDH_DEBUG_VAL 0x0008 /* Debug */ | |
| 73 | −#define SDH_DATA_VAL 0x0010 /* Data */ | |
| 74 | −#define SDH_CTRL_VAL 0x0020 /* Control Regs */ | |
| 75 | −#define SDH_LOG_VAL 0x0040 /* Enable bcmlog */ | |
| 76 | −#define SDH_DMA_VAL 0x0080 /* DMA */ | |
| 77 | − | |
| 78 | −#ifdef BCMDBG | |
| 79 | −#define sd_err(x) \ | |
| 80 | − do { \ | |
| 81 | − if ((sd_msglevel & SDH_ERROR_VAL) && net_ratelimit()) \ | |
| 82 | − printk x; \ | |
| 83 | − } while (0) | |
| 84 | −#define sd_trace(x) \ | |
| 85 | − do { \ | |
| 86 | − if ((sd_msglevel & SDH_TRACE_VAL) && net_ratelimit()) \ | |
| 87 | − printk x; \ | |
| 88 | − } while (0) | |
| 89 | −#define sd_info(x) \ | |
| 90 | − do { \ | |
| 91 | − if ((sd_msglevel & SDH_INFO_VAL) && net_ratelimit()) \ | |
| 92 | − printk x; \ | |
| 93 | − } while (0) | |
| 94 | −#define sd_debug(x) \ | |
| 95 | − do { \ | |
| 96 | − if ((sd_msglevel & SDH_DEBUG_VAL) && net_ratelimit()) \ | |
| 97 | − printk x; \ | |
| 98 | − } while (0) | |
| 99 | −#define sd_data(x) \ | |
| 100 | − do { \ | |
| 101 | − if ((sd_msglevel & SDH_DATA_VAL) && net_ratelimit()) \ | |
| 102 | − printk x; \ | |
| 103 | − } while (0) | |
| 104 | −#define sd_ctrl(x) \ | |
| 105 | − do { \ | |
| 106 | − if ((sd_msglevel & SDH_CTRL_VAL) && net_ratelimit()) \ | |
| 107 | − printk x; \ | |
| 108 | − } while (0) | |
| 109 | −#else | |
| 110 | −#define sd_err(x) | |
| 111 | −#define sd_trace(x) | |
| 112 | −#define sd_info(x) | |
| 113 | −#define sd_debug(x) | |
| 114 | −#define sd_data(x) | |
| 115 | −#define sd_ctrl(x) | |
| 116 | −#endif | |
| 117 | − | |
| 118 | −struct sdos_info { | |
| 119 | − struct sdioh_info *sd; | |
| 120 | − spinlock_t lock; | |
| 121 | −}; | |
| 122 | − | |
| 123 | −static void brcmf_sdioh_irqhandler(struct sdio_func *func); | |
| 124 | −static void brcmf_sdioh_irqhandler_f2(struct sdio_func *func); | |
| 125 | −static int brcmf_sdioh_get_cisaddr(struct sdioh_info *sd, u32 regaddr); | |
| 126 | −static int brcmf_ops_sdio_probe(struct sdio_func *func, | |
| 127 | − const struct sdio_device_id *id); | |
| 128 | −static void brcmf_ops_sdio_remove(struct sdio_func *func); | |
| 129 | − | |
| 130 | −#ifdef CONFIG_PM | |
| 131 | −static int brcmf_sdio_suspend(struct device *dev); | |
| 132 | −static int brcmf_sdio_resume(struct device *dev); | |
| 133 | −#endif /* CONFIG_PM */ | |
| 134 | − | |
| 135 | −uint sd_f2_blocksize = 512; /* Default blocksize */ | |
| 136 | − | |
| 137 | −uint sd_msglevel = 0x01; | |
| 138 | − | |
| 139 | −/* module param defaults */ | |
| 140 | −static int clockoverride; | |
| 141 | − | |
| 142 | −module_param(clockoverride, int, 0644); | |
| 143 | −MODULE_PARM_DESC(clockoverride, "SDIO card clock override"); | |
| 144 | − | |
| 145 | −struct brcmf_sdmmc_instance *gInstance; | |
| 146 | − | |
| 147 | −struct device sdmmc_dev; | |
| 148 | − | |
| 149 | −/* devices we support, null terminated */ | |
| 150 | −static const struct sdio_device_id brcmf_sdmmc_ids[] = { | |
| 151 | − {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_DEFAULT)}, | |
| 152 | − {SDIO_DEVICE | |
| 153 | − (SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325_SDGWB)}, | |
| 154 | − {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325)}, | |
| 155 | − {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)}, | |
| 156 | − {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4319)}, | |
| 157 | − { /* end: all zeroes */ }, | |
| 158 | −}; | |
| 159 | − | |
| 160 | −#ifdef CONFIG_PM | |
| 161 | −static const struct dev_pm_ops brcmf_sdio_pm_ops = { | |
| 162 | − .suspend = brcmf_sdio_suspend, | |
| 163 | − .resume = brcmf_sdio_resume, | |
| 164 | −}; | |
| 165 | −#endif /* CONFIG_PM */ | |
| 166 | − | |
| 167 | −static struct sdio_driver brcmf_sdmmc_driver = { | |
| 168 | − .probe = brcmf_ops_sdio_probe, | |
| 169 | − .remove = brcmf_ops_sdio_remove, | |
| 170 | − .name = "brcmfmac", | |
| 171 | − .id_table = brcmf_sdmmc_ids, | |
| 172 | −#ifdef CONFIG_PM | |
| 173 | − .drv = { | |
| 174 | − .pm = &brcmf_sdio_pm_ops, | |
| 175 | − }, | |
| 176 | −#endif /* CONFIG_PM */ | |
| 177 | −}; | |
| 178 | − | |
| 179 | −MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); | |
| 180 | − | |
| 181 | −BRCMF_PM_RESUME_WAIT_INIT(sdioh_request_byte_wait); | |
| 182 | −BRCMF_PM_RESUME_WAIT_INIT(sdioh_request_word_wait); | |
| 183 | −BRCMF_PM_RESUME_WAIT_INIT(sdioh_request_packet_wait); | |
| 184 | −BRCMF_PM_RESUME_WAIT_INIT(sdioh_request_buffer_wait); | |
| 185 | − | |
| 186 | −static int | |
| 187 | −brcmf_sdioh_card_regread(struct sdioh_info *sd, int func, u32 regaddr, | |
| 188 | − int regsize, u32 *data); | |
| 189 | − | |
| 190 | −static int brcmf_sdioh_enablefuncs(struct sdioh_info *sd) | |
| 191 | −{ | |
| 192 | − int err_ret; | |
| 193 | − u32 fbraddr; | |
| 194 | − u8 func; | |
| 195 | − | |
| 196 | − sd_trace(("%s\n", __func__)); | |
| 197 | − | |
| 198 | − /* Get the Card's common CIS address */ | |
| 199 | − sd->com_cis_ptr = brcmf_sdioh_get_cisaddr(sd, SDIO_CCCR_CIS); | |
| 200 | − sd->func_cis_ptr[0] = sd->com_cis_ptr; | |
| 201 | − sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __func__, | |
| 202 | − sd->com_cis_ptr)); | |
| 203 | − | |
| 204 | − /* Get the Card's function CIS (for each function) */ | |
| 205 | − for (fbraddr = SDIO_FBR_BASE(1), func = 1; | |
| 206 | − func <= sd->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) { | |
| 207 | − sd->func_cis_ptr[func] = | |
| 208 | − brcmf_sdioh_get_cisaddr(sd, SDIO_FBR_CIS + fbraddr); | |
| 209 | − sd_info(("%s: Function %d CIS Ptr = 0x%x\n", __func__, func, | |
| 210 | − sd->func_cis_ptr[func])); | |
| 211 | − } | |
| 212 | − | |
| 213 | − sd->func_cis_ptr[0] = sd->com_cis_ptr; | |
| 214 | − sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __func__, | |
| 215 | − sd->com_cis_ptr)); | |
| 216 | − | |
| 217 | − /* Enable Function 1 */ | |
| 218 | − sdio_claim_host(gInstance->func[1]); | |
| 219 | − err_ret = sdio_enable_func(gInstance->func[1]); | |
| 220 | − sdio_release_host(gInstance->func[1]); | |
| 221 | − if (err_ret) { | |
| 222 | − sd_err(("brcmf_sdioh_enablefuncs: Failed to enable F1 " | |
| 223 | − "Err: 0x%08x\n", err_ret)); | |
| 224 | − } | |
| 225 | − | |
| 226 | − return false; | |
| 227 | −} | |
| 228 | − | |
| 229 | −/* | |
| 230 | − * Public entry points & extern's | |
| 231 | − */ | |
| 232 | −struct sdioh_info *brcmf_sdioh_attach(void *bar0, uint irq) | |
| 233 | −{ | |
| 234 | − struct sdioh_info *sd; | |
| 235 | − int err_ret; | |
| 236 | − | |
| 237 | − sd_trace(("%s\n", __func__)); | |
| 238 | − | |
| 239 | − if (gInstance == NULL) { | |
| 240 | − sd_err(("%s: SDIO Device not present\n", __func__)); | |
| 241 | − return NULL; | |
| 242 | − } | |
| 243 | − | |
| 244 | − sd = kzalloc(sizeof(struct sdioh_info), GFP_ATOMIC); | |
| 245 | − if (sd == NULL) { | |
| 246 | − sd_err(("sdioh_attach: out of memory\n")); | |
| 247 | − return NULL; | |
| 248 | − } | |
| 249 | − if (brcmf_sdioh_osinit(sd) != 0) { | |
| 250 | − sd_err(("%s:sdioh_sdmmc_osinit() failed\n", __func__)); | |
| 251 | − kfree(sd); | |
| 252 | − return NULL; | |
| 253 | − } | |
| 254 | − | |
| 255 | − sd->num_funcs = 2; | |
| 256 | − sd->use_client_ints = true; | |
| 257 | − sd->client_block_size[0] = 64; | |
| 258 | − | |
| 259 | − gInstance->sd = sd; | |
| 260 | − | |
| 261 | − /* Claim host controller */ | |
| 262 | − sdio_claim_host(gInstance->func[1]); | |
| 263 | − | |
| 264 | − sd->client_block_size[1] = 64; | |
| 265 | − err_ret = sdio_set_block_size(gInstance->func[1], 64); | |
| 266 | − if (err_ret) | |
| 267 | − sd_err(("brcmf_sdioh_attach: Failed to set F1 blocksize\n")); | |
| 268 | − | |
| 269 | − /* Release host controller F1 */ | |
| 270 | − sdio_release_host(gInstance->func[1]); | |
| 271 | − | |
| 272 | − if (gInstance->func[2]) { | |
| 273 | − /* Claim host controller F2 */ | |
| 274 | − sdio_claim_host(gInstance->func[2]); | |
| 275 | − | |
| 276 | − sd->client_block_size[2] = sd_f2_blocksize; | |
| 277 | − err_ret = | |
| 278 | − sdio_set_block_size(gInstance->func[2], sd_f2_blocksize); | |
| 279 | − if (err_ret) | |
| 280 | − sd_err(("brcmf_sdioh_attach: Failed to set F2 blocksize" | |
| 281 | − " to %d\n", sd_f2_blocksize)); | |
| 282 | − | |
| 283 | − /* Release host controller F2 */ | |
| 284 | − sdio_release_host(gInstance->func[2]); | |
| 285 | − } | |
| 286 | − | |
| 287 | − brcmf_sdioh_enablefuncs(sd); | |
| 288 | − | |
| 289 | − sd_trace(("%s: Done\n", __func__)); | |
| 290 | − return sd; | |
| 291 | −} | |
| 292 | − | |
| 293 | −extern int brcmf_sdioh_detach(struct sdioh_info *sd) | |
| 294 | −{ | |
| 295 | − sd_trace(("%s\n", __func__)); | |
| 296 | − | |
| 297 | − if (sd) { | |
| 298 | − | |
| 299 | − /* Disable Function 2 */ | |
| 300 | − sdio_claim_host(gInstance->func[2]); | |
| 301 | − sdio_disable_func(gInstance->func[2]); | |
| 302 | − sdio_release_host(gInstance->func[2]); | |
| 303 | − | |
| 304 | − /* Disable Function 1 */ | |
| 305 | − sdio_claim_host(gInstance->func[1]); | |
| 306 | − sdio_disable_func(gInstance->func[1]); | |
| 307 | − sdio_release_host(gInstance->func[1]); | |
| 308 | − | |
| 309 | − /* deregister irq */ | |
| 310 | − brcmf_sdioh_osfree(sd); | |
| 311 | − | |
| 312 | − kfree(sd); | |
| 313 | − } | |
| 314 | − return 0; | |
| 315 | −} | |
| 316 | − | |
| 317 | −/* Configure callback to client when we receive client interrupt */ | |
| 318 | −extern int | |
| 319 | −brcmf_sdioh_interrupt_register(struct sdioh_info *sd, void (*fn)(void *), | |
| 320 | − void *argh) | |
| 321 | −{ | |
| 322 | − sd_trace(("%s: Entering\n", __func__)); | |
| 323 | − if (fn == NULL) { | |
| 324 | − sd_err(("%s: interrupt handler is NULL, not registering\n", | |
| 325 | − __func__)); | |
| 326 | − return -EINVAL; | |
| 327 | − } | |
| 328 | − | |
| 329 | − sd->intr_handler = fn; | |
| 330 | − sd->intr_handler_arg = argh; | |
| 331 | − sd->intr_handler_valid = true; | |
| 332 | − | |
| 333 | − /* register and unmask irq */ | |
| 334 | − if (gInstance->func[2]) { | |
| 335 | − sdio_claim_host(gInstance->func[2]); | |
| 336 | − sdio_claim_irq(gInstance->func[2], brcmf_sdioh_irqhandler_f2); | |
| 337 | − sdio_release_host(gInstance->func[2]); | |
| 338 | − } | |
| 339 | − | |
| 340 | − if (gInstance->func[1]) { | |
| 341 | − sdio_claim_host(gInstance->func[1]); | |
| 342 | − sdio_claim_irq(gInstance->func[1], brcmf_sdioh_irqhandler); | |
| 343 | − sdio_release_host(gInstance->func[1]); | |
| 344 | − } | |
| 345 | − | |
| 346 | − return 0; | |
| 347 | −} | |
| 348 | − | |
| 349 | −extern int brcmf_sdioh_interrupt_deregister(struct sdioh_info *sd) | |
| 350 | −{ | |
| 351 | − sd_trace(("%s: Entering\n", __func__)); | |
| 352 | − | |
| 353 | − if (gInstance->func[1]) { | |
| 354 | − /* register and unmask irq */ | |
| 355 | − sdio_claim_host(gInstance->func[1]); | |
| 356 | − sdio_release_irq(gInstance->func[1]); | |
| 357 | − sdio_release_host(gInstance->func[1]); | |
| 358 | − } | |
| 359 | − | |
| 360 | − if (gInstance->func[2]) { | |
| 361 | − /* Claim host controller F2 */ | |
| 362 | − sdio_claim_host(gInstance->func[2]); | |
| 363 | − sdio_release_irq(gInstance->func[2]); | |
| 364 | − /* Release host controller F2 */ | |
| 365 | − sdio_release_host(gInstance->func[2]); | |
| 366 | − } | |
| 367 | − | |
| 368 | − sd->intr_handler_valid = false; | |
| 369 | − sd->intr_handler = NULL; | |
| 370 | − sd->intr_handler_arg = NULL; | |
| 371 | − | |
| 372 | − return 0; | |
| 373 | −} | |
| 374 | − | |
| 375 | −/* IOVar table */ | |
| 376 | −enum { | |
| 377 | − IOV_MSGLEVEL = 1, | |
| 378 | − IOV_BLOCKSIZE, | |
| 379 | − IOV_USEINTS, | |
| 380 | − IOV_NUMINTS, | |
| 381 | − IOV_DEVREG, | |
| 382 | − IOV_HCIREGS, | |
| 383 | − IOV_RXCHAIN | |
| 384 | −}; | |
| 385 | − | |
| 386 | −const struct brcmu_iovar sdioh_iovars[] = { | |
| 387 | − {"sd_msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0}, | |
| 388 | − {"sd_blocksize", IOV_BLOCKSIZE, 0, IOVT_UINT32, 0},/* ((fn << 16) | | |
| 389 | − size) */ | |
| 390 | − {"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0}, | |
| 391 | − {"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0}, | |
| 392 | − {"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(struct brcmf_sdreg)} | |
| 393 | − , | |
| 394 | − {"sd_rxchain", IOV_RXCHAIN, 0, IOVT_BOOL, 0} | |
| 395 | − , | |
| 396 | − {NULL, 0, 0, 0, 0} | |
| 397 | −}; | |
| 398 | − | |
| 399 | −int | |
| 400 | −brcmf_sdioh_iovar_op(struct sdioh_info *si, const char *name, | |
| 401 | − void *params, int plen, void *arg, int len, bool set) | |
| 402 | −{ | |
| 403 | − const struct brcmu_iovar *vi = NULL; | |
| 404 | − int bcmerror = 0; | |
| 405 | − int val_size; | |
| 406 | − s32 int_val = 0; | |
| 407 | − bool bool_val; | |
| 408 | − u32 actionid; | |
| 409 | − | |
| 410 | − if (name == NULL || len <= 0) | |
| 411 | − return -EINVAL; | |
| 412 | − | |
| 413 | − /* Set does not take qualifiers */ | |
| 414 | − if (set && (params || plen)) | |
| 415 | − return -EINVAL; | |
| 416 | − | |
| 417 | − /* Get must have return space;*/ | |
| 418 | − if (!set && !(arg && len)) | |
| 419 | − return -EINVAL; | |
| 420 | − | |
| 421 | − sd_trace(("%s: Enter (%s %s)\n", __func__, (set ? "set" : "get"), | |
| 422 | − name)); | |
| 423 | − | |
| 424 | − vi = brcmu_iovar_lookup(sdioh_iovars, name); | |
| 425 | − if (vi == NULL) { | |
| 426 | − bcmerror = -ENOTSUPP; | |
| 427 | − goto exit; | |
| 428 | − } | |
| 429 | − | |
| 430 | − bcmerror = brcmu_iovar_lencheck(vi, arg, len, set); | |
| 431 | − if (bcmerror != 0) | |
| 432 | − goto exit; | |
| 433 | − | |
| 434 | − /* Set up params so get and set can share the convenience variables */ | |
| 435 | − if (params == NULL) { | |
| 436 | − params = arg; | |
| 437 | − plen = len; | |
| 438 | − } | |
| 439 | − | |
| 440 | − if (vi->type == IOVT_VOID) | |
| 441 | − val_size = 0; | |
| 442 | − else if (vi->type == IOVT_BUFFER) | |
| 443 | − val_size = len; | |
| 444 | − else | |
| 445 | − val_size = sizeof(int); | |
| 446 | − | |
| 447 | − if (plen >= (int)sizeof(int_val)) | |
| 448 | − memcpy(&int_val, params, sizeof(int_val)); | |
| 449 | − | |
| 450 | − bool_val = (int_val != 0) ? true : false; | |
| 451 | − | |
| 452 | − actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); | |
| 453 | − switch (actionid) { | |
| 454 | − case IOV_GVAL(IOV_MSGLEVEL): | |
| 455 | − int_val = (s32) sd_msglevel; | |
| 456 | − memcpy(arg, &int_val, val_size); | |
| 457 | − break; | |
| 458 | − | |
| 459 | − case IOV_SVAL(IOV_MSGLEVEL): | |
| 460 | − sd_msglevel = int_val; | |
| 461 | − break; | |
| 462 | − | |
| 463 | − case IOV_GVAL(IOV_BLOCKSIZE): | |
| 464 | − if ((u32) int_val > si->num_funcs) { | |
| 465 | − bcmerror = -EINVAL; | |
| 466 | − break; | |
| 467 | − } | |
| 468 | − int_val = (s32) si->client_block_size[int_val]; | |
| 469 | − memcpy(arg, &int_val, val_size); | |
| 470 | − break; | |
| 471 | − | |
| 472 | − case IOV_SVAL(IOV_BLOCKSIZE): | |
| 473 | − { | |
| 474 | − uint func = ((u32) int_val >> 16); | |
| 475 | − uint blksize = (u16) int_val; | |
| 476 | − uint maxsize; | |
| 477 | − | |
| 478 | − if (func > si->num_funcs) { | |
| 479 | − bcmerror = -EINVAL; | |
| 480 | − break; | |
| 481 | − } | |
| 482 | − | |
| 483 | − switch (func) { | |
| 484 | − case 0: | |
| 485 | − maxsize = 32; | |
| 486 | − break; | |
| 487 | − case 1: | |
| 488 | − maxsize = BLOCK_SIZE_4318; | |
| 489 | − break; | |
| 490 | − case 2: | |
| 491 | − maxsize = BLOCK_SIZE_4328; | |
| 492 | − break; | |
| 493 | − default: | |
| 494 | − maxsize = 0; | |
| 495 | − } | |
| 496 | − if (blksize > maxsize) { | |
| 497 | − bcmerror = -EINVAL; | |
| 498 | − break; | |
| 499 | − } | |
| 500 | − if (!blksize) | |
| 501 | − blksize = maxsize; | |
| 502 | − | |
| 503 | − /* Now set it */ | |
| 504 | − si->client_block_size[func] = blksize; | |
| 505 | − | |
| 506 | − break; | |
| 507 | − } | |
| 508 | − | |
| 509 | − case IOV_GVAL(IOV_RXCHAIN): | |
| 510 | − int_val = false; | |
| 511 | − memcpy(arg, &int_val, val_size); | |
| 512 | − break; | |
| 513 | − | |
| 514 | − case IOV_GVAL(IOV_USEINTS): | |
| 515 | − int_val = (s32) si->use_client_ints; | |
| 516 | − memcpy(arg, &int_val, val_size); | |
| 517 | − break; | |
| 518 | − | |
| 519 | − case IOV_SVAL(IOV_USEINTS): | |
| 520 | − si->use_client_ints = (bool) int_val; | |
| 521 | − if (si->use_client_ints) | |
| 522 | − si->intmask |= CLIENT_INTR; | |
| 523 | − else | |
| 524 | − si->intmask &= ~CLIENT_INTR; | |
| 525 | − | |
| 526 | − break; | |
| 527 | − | |
| 528 | − case IOV_GVAL(IOV_NUMINTS): | |
| 529 | − int_val = (s32) si->intrcount; | |
| 530 | − memcpy(arg, &int_val, val_size); | |
| 531 | − break; | |
| 532 | − | |
| 533 | − case IOV_GVAL(IOV_DEVREG): | |
| 534 | − { | |
| 535 | − struct brcmf_sdreg *sd_ptr = | |
| 536 | − (struct brcmf_sdreg *) params; | |
| 537 | − u8 data = 0; | |
| 538 | − | |
| 539 | − if (brcmf_sdioh_cfg_read | |
| 540 | − (si, sd_ptr->func, sd_ptr->offset, &data)) { | |
| 541 | − bcmerror = -EIO; | |
| 542 | − break; | |
| 543 | − } | |
| 544 | − | |
| 545 | − int_val = (int)data; | |
| 546 | − memcpy(arg, &int_val, sizeof(int_val)); | |
| 547 | − break; | |
| 548 | − } | |
| 549 | − | |
| 550 | − case IOV_SVAL(IOV_DEVREG): | |
| 551 | − { | |
| 552 | − struct brcmf_sdreg *sd_ptr = | |
| 553 | − (struct brcmf_sdreg *) params; | |
| 554 | − u8 data = (u8) sd_ptr->value; | |
| 555 | − | |
| 556 | − if (brcmf_sdioh_cfg_write | |
| 557 | − (si, sd_ptr->func, sd_ptr->offset, &data)) { | |
| 558 | − bcmerror = -EIO; | |
| 559 | − break; | |
| 560 | − } | |
| 561 | − break; | |
| 562 | − } | |
| 563 | − | |
| 564 | − default: | |
| 565 | − bcmerror = -ENOTSUPP; | |
| 566 | − break; | |
| 567 | − } | |
| 568 | −exit: | |
| 569 | − | |
| 570 | − return bcmerror; | |
| 571 | −} | |
| 572 | − | |
| 573 | −extern int | |
| 574 | −brcmf_sdioh_cfg_read(struct sdioh_info *sd, uint fnc_num, u32 addr, u8 *data) | |
| 575 | −{ | |
| 576 | − int status; | |
| 577 | − /* No lock needed since brcmf_sdioh_request_byte does locking */ | |
| 578 | − status = brcmf_sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data); | |
| 579 | − return status; | |
| 580 | −} | |
| 581 | − | |
| 582 | −extern int | |
| 583 | −brcmf_sdioh_cfg_write(struct sdioh_info *sd, uint fnc_num, u32 addr, u8 *data) | |
| 584 | −{ | |
| 585 | − /* No lock needed since brcmf_sdioh_request_byte does locking */ | |
| 586 | − int status; | |
| 587 | − status = brcmf_sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data); | |
| 588 | − return status; | |
| 589 | −} | |
| 590 | − | |
| 591 | −static int brcmf_sdioh_get_cisaddr(struct sdioh_info *sd, u32 regaddr) | |
| 592 | −{ | |
| 593 | − /* read 24 bits and return valid 17 bit addr */ | |
| 594 | − int i; | |
| 595 | − u32 scratch, regdata; | |
| 596 | − u8 *ptr = (u8 *)&scratch; | |
| 597 | − for (i = 0; i < 3; i++) { | |
| 598 | − if ((brcmf_sdioh_card_regread(sd, 0, regaddr, 1, ®data)) != | |
| 599 | − SUCCESS) | |
| 600 | − sd_err(("%s: Can't read!\n", __func__)); | |
| 601 | − | |
| 602 | − *ptr++ = (u8) regdata; | |
| 603 | − regaddr++; | |
| 604 | − } | |
| 605 | − | |
| 606 | − /* Only the lower 17-bits are valid */ | |
| 607 | − scratch = le32_to_cpu(scratch); | |
| 608 | − scratch &= 0x0001FFFF; | |
| 609 | − return scratch; | |
| 610 | −} | |
| 611 | − | |
| 612 | −extern int | |
| 613 | −brcmf_sdioh_cis_read(struct sdioh_info *sd, uint func, u8 *cisd, u32 length) | |
| 614 | −{ | |
| 615 | − u32 count; | |
| 616 | − int offset; | |
| 617 | − u32 foo; | |
| 618 | − u8 *cis = cisd; | |
| 619 | − | |
| 620 | − sd_trace(("%s: Func = %d\n", __func__, func)); | |
| 621 | − | |
| 622 | − if (!sd->func_cis_ptr[func]) { | |
| 623 | − memset(cis, 0, length); | |
| 624 | − sd_err(("%s: no func_cis_ptr[%d]\n", __func__, func)); | |
| 625 | − return -ENOTSUPP; | |
| 626 | − } | |
| 627 | − | |
| 628 | − sd_err(("%s: func_cis_ptr[%d]=0x%04x\n", __func__, func, | |
| 629 | − sd->func_cis_ptr[func])); | |
| 630 | − | |
| 631 | − for (count = 0; count < length; count++) { | |
| 632 | − offset = sd->func_cis_ptr[func] + count; | |
| 633 | − if (brcmf_sdioh_card_regread(sd, 0, offset, 1, &foo) < 0) { | |
| 634 | − sd_err(("%s: regread failed: Can't read CIS\n", | |
| 635 | − __func__)); | |
| 636 | − return -EIO; | |
| 637 | − } | |
| 638 | − | |
| 639 | − *cis = (u8) (foo & 0xff); | |
| 640 | − cis++; | |
| 641 | − } | |
| 642 | − | |
| 643 | − return 0; | |
| 644 | −} | |
| 645 | − | |
| 646 | −extern int | |
| 647 | −brcmf_sdioh_request_byte(struct sdioh_info *sd, uint rw, uint func, | |
| 648 | − uint regaddr, u8 *byte) | |
| 649 | −{ | |
| 650 | − int err_ret; | |
| 651 | − | |
| 652 | − sd_info(("%s: rw=%d, func=%d, addr=0x%05x\n", __func__, rw, func, | |
| 653 | − regaddr)); | |
| 654 | − | |
| 655 | − BRCMF_PM_RESUME_WAIT(sdioh_request_byte_wait); | |
| 656 | − BRCMF_PM_RESUME_RETURN_ERROR(-EIO); | |
| 657 | − if (rw) { /* CMD52 Write */ | |
| 658 | − if (func == 0) { | |
| 659 | − /* Can only directly write to some F0 registers. | |
| 660 | − * Handle F2 enable | |
| 661 | − * as a special case. | |
| 662 | − */ | |
| 663 | − if (regaddr == SDIO_CCCR_IOEx) { | |
| 664 | − if (gInstance->func[2]) { | |
| 665 | − sdio_claim_host(gInstance->func[2]); | |
| 666 | − if (*byte & SDIO_FUNC_ENABLE_2) { | |
| 667 | − /* Enable Function 2 */ | |
| 668 | − err_ret = | |
| 669 | − sdio_enable_func | |
| 670 | − (gInstance->func[2]); | |
| 671 | − if (err_ret) | |
| 672 | − sd_err(("request_byte: " | |
| 673 | − "enable F2 " | |
| 674 | − "failed:%d\n", | |
| 675 | − err_ret)); | |
| 676 | − } else { | |
| 677 | − /* Disable Function 2 */ | |
| 678 | − err_ret = | |
| 679 | − sdio_disable_func | |
| 680 | − (gInstance->func[2]); | |
| 681 | − if (err_ret) | |
| 682 | − sd_err(("request_byte: " | |
| 683 | − "Disab F2 " | |
| 684 | − "failed:%d\n", | |
| 685 | − err_ret)); | |
| 686 | − } | |
| 687 | − sdio_release_host(gInstance->func[2]); | |
| 688 | − } | |
| 689 | − } | |
| 690 | − /* to allow abort command through F1 */ | |
| 691 | − else if (regaddr == SDIO_CCCR_ABORT) { | |
| 692 | − sdio_claim_host(gInstance->func[func]); | |
| 693 | − /* | |
| 694 | − * this sdio_f0_writeb() can be replaced | |
| 695 | − * with another api | |
| 696 | − * depending upon MMC driver change. | |
| 697 | − * As of this time, this is temporaray one | |
| 698 | − */ | |
| 699 | − sdio_writeb(gInstance->func[func], *byte, | |
| 700 | − regaddr, &err_ret); | |
| 701 | − sdio_release_host(gInstance->func[func]); | |
| 702 | − } else if (regaddr < 0xF0) { | |
| 703 | − sd_err(("brcmf: F0 Wr:0x%02x: write " | |
| 704 | − "disallowed\n", regaddr)); | |
| 705 | − } else { | |
| 706 | − /* Claim host controller, perform F0 write, | |
| 707 | − and release */ | |
| 708 | − sdio_claim_host(gInstance->func[func]); | |
| 709 | − sdio_f0_writeb(gInstance->func[func], *byte, | |
| 710 | − regaddr, &err_ret); | |
| 711 | − sdio_release_host(gInstance->func[func]); | |
| 712 | − } | |
| 713 | − } else { | |
| 714 | − /* Claim host controller, perform Fn write, | |
| 715 | − and release */ | |
| 716 | − sdio_claim_host(gInstance->func[func]); | |
| 717 | − sdio_writeb(gInstance->func[func], *byte, regaddr, | |
| 718 | − &err_ret); | |
| 719 | − sdio_release_host(gInstance->func[func]); | |
| 720 | − } | |
| 721 | − } else { /* CMD52 Read */ | |
| 722 | − /* Claim host controller, perform Fn read, and release */ | |
| 723 | − sdio_claim_host(gInstance->func[func]); | |
| 724 | − | |
| 725 | − if (func == 0) { | |
| 726 | − *byte = | |
| 727 | − sdio_f0_readb(gInstance->func[func], regaddr, | |
| 728 | − &err_ret); | |
| 729 | − } else { | |
| 730 | − *byte = | |
| 731 | − sdio_readb(gInstance->func[func], regaddr, | |
| 732 | − &err_ret); | |
| 733 | − } | |
| 734 | − | |
| 735 | − sdio_release_host(gInstance->func[func]); | |
| 736 | − } | |
| 737 | − | |
| 738 | − if (err_ret) | |
| 739 | − sd_err(("brcmf: Failed to %s byte F%d:@0x%05x=%02x, " | |
| 740 | − "Err: %d\n", rw ? "Write" : "Read", func, regaddr, | |
| 741 | − *byte, err_ret)); | |
| 742 | − | |
| 743 | − return err_ret; | |
| 744 | −} | |
| 745 | − | |
| 746 | −extern int | |
| 747 | −brcmf_sdioh_request_word(struct sdioh_info *sd, uint cmd_type, uint rw, | |
| 748 | − uint func, uint addr, u32 *word, uint nbytes) | |
| 749 | −{ | |
| 750 | − int err_ret = -EIO; | |
| 751 | − | |
| 752 | − if (func == 0) { | |
| 753 | − sd_err(("%s: Only CMD52 allowed to F0.\n", __func__)); | |
| 754 | − return -EINVAL; | |
| 755 | − } | |
| 756 | − | |
| 757 | − sd_info(("%s: cmd_type=%d, rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", | |
| 758 | − __func__, cmd_type, rw, func, addr, nbytes)); | |
| 759 | − | |
| 760 | − BRCMF_PM_RESUME_WAIT(sdioh_request_word_wait); | |
| 761 | − BRCMF_PM_RESUME_RETURN_ERROR(-EIO); | |
| 762 | − /* Claim host controller */ | |
| 763 | − sdio_claim_host(gInstance->func[func]); | |
| 764 | − | |
| 765 | − if (rw) { /* CMD52 Write */ | |
| 766 | − if (nbytes == 4) { | |
| 767 | − sdio_writel(gInstance->func[func], *word, addr, | |
| 768 | − &err_ret); | |
| 769 | − } else if (nbytes == 2) { | |
| 770 | − sdio_writew(gInstance->func[func], (*word & 0xFFFF), | |
| 771 | − addr, &err_ret); | |
| 772 | − } else { | |
| 773 | − sd_err(("%s: Invalid nbytes: %d\n", __func__, nbytes)); | |
| 774 | − } | |
| 775 | − } else { /* CMD52 Read */ | |
| 776 | − if (nbytes == 4) { | |
| 777 | − *word = | |
| 778 | − sdio_readl(gInstance->func[func], addr, &err_ret); | |
| 779 | − } else if (nbytes == 2) { | |
| 780 | − *word = | |
| 781 | − sdio_readw(gInstance->func[func], addr, | |
| 782 | − &err_ret) & 0xFFFF; | |
| 783 | − } else { | |
| 784 | − sd_err(("%s: Invalid nbytes: %d\n", __func__, nbytes)); | |
| 785 | − } | |
| 786 | − } | |
| 787 | − | |
| 788 | − /* Release host controller */ | |
| 789 | − sdio_release_host(gInstance->func[func]); | |
| 790 | − | |
| 791 | − if (err_ret) { | |
| 792 | − sd_err(("brcmf: Failed to %s word, Err: 0x%08x\n", | |
| 793 | − rw ? "Write" : "Read", err_ret)); | |
| 794 | − } | |
| 795 | − | |
| 796 | − return err_ret; | |
| 797 | −} | |
| 798 | − | |
| 799 | −static int | |
| 800 | −brcmf_sdioh_request_packet(struct sdioh_info *sd, uint fix_inc, uint write, | |
| 801 | − uint func, uint addr, struct sk_buff *pkt) | |
| 802 | −{ | |
| 803 | − bool fifo = (fix_inc == SDIOH_DATA_FIX); | |
| 804 | − u32 SGCount = 0; | |
| 805 | − int err_ret = 0; | |
| 806 | − | |
| 807 | − struct sk_buff *pnext; | |
| 808 | − | |
| 809 | − sd_trace(("%s: Enter\n", __func__)); | |
| 810 | − | |
| 811 | − BRCMF_PM_RESUME_WAIT(sdioh_request_packet_wait); | |
| 812 | − BRCMF_PM_RESUME_RETURN_ERROR(-EIO); | |
| 813 | − | |
| 814 | − /* Claim host controller */ | |
| 815 | − sdio_claim_host(gInstance->func[func]); | |
| 816 | − for (pnext = pkt; pnext; pnext = pnext->next) { | |
| 817 | − uint pkt_len = pnext->len; | |
| 818 | − pkt_len += 3; | |
| 819 | − pkt_len &= 0xFFFFFFFC; | |
| 820 | − | |
| 821 | − if ((write) && (!fifo)) { | |
| 822 | − err_ret = sdio_memcpy_toio(gInstance->func[func], addr, | |
| 823 | − ((u8 *) (pnext->data)), | |
| 824 | − pkt_len); | |
| 825 | − } else if (write) { | |
| 826 | − err_ret = sdio_memcpy_toio(gInstance->func[func], addr, | |
| 827 | − ((u8 *) (pnext->data)), | |
| 828 | − pkt_len); | |
| 829 | − } else if (fifo) { | |
| 830 | − err_ret = sdio_readsb(gInstance->func[func], | |
| 831 | − ((u8 *) (pnext->data)), | |
| 832 | − addr, pkt_len); | |
| 833 | − } else { | |
| 834 | − err_ret = sdio_memcpy_fromio(gInstance->func[func], | |
| 835 | − ((u8 *) (pnext->data)), | |
| 836 | − addr, pkt_len); | |
| 837 | − } | |
| 838 | − | |
| 839 | − if (err_ret) { | |
| 840 | − sd_err(("%s: %s FAILED %p[%d], addr=0x%05x, pkt_len=%d," | |
| 841 | − "ERR=0x%08x\n", __func__, | |
| 842 | − (write) ? "TX" : "RX", | |
| 843 | − pnext, SGCount, addr, pkt_len, err_ret)); | |
| 844 | − } else { | |
| 845 | − sd_trace(("%s: %s xfr'd %p[%d], addr=0x%05x, len=%d\n", | |
| 846 | − __func__, | |
| 847 | − (write) ? "TX" : "RX", | |
| 848 | − pnext, SGCount, addr, pkt_len)); | |
| 849 | − } | |
| 850 | − | |
| 851 | − if (!fifo) | |
| 852 | − addr += pkt_len; | |
| 853 | − SGCount++; | |
| 854 | − | |
| 855 | − } | |
| 856 | − | |
| 857 | − /* Release host controller */ | |
| 858 | − sdio_release_host(gInstance->func[func]); | |
| 859 | − | |
| 860 | − sd_trace(("%s: Exit\n", __func__)); | |
| 861 | − return err_ret; | |
| 862 | −} | |
| 863 | − | |
| 864 | −/* | |
| 865 | − * This function takes a buffer or packet, and fixes everything up | |
| 866 | − * so that in the end, a DMA-able packet is created. | |
| 867 | − * | |
| 868 | − * A buffer does not have an associated packet pointer, | |
| 869 | − * and may or may not be aligned. | |
| 870 | − * A packet may consist of a single packet, or a packet chain. | |
| 871 | − * If it is a packet chain, then all the packets in the chain | |
| 872 | − * must be properly aligned. | |
| 873 | − * | |
| 874 | − * If the packet data is not aligned, then there may only be | |
| 875 | − * one packet, and in this case, it is copied to a new | |
| 876 | − * aligned packet. | |
| 877 | − * | |
| 878 | − */ | |
| 879 | −extern int | |
| 880 | −brcmf_sdioh_request_buffer(struct sdioh_info *sd, uint pio_dma, uint fix_inc, | |
| 881 | − uint write, uint func, uint addr, uint reg_width, | |
| 882 | − uint buflen_u, u8 *buffer, struct sk_buff *pkt) | |
| 883 | −{ | |
| 884 | − int Status; | |
| 885 | − struct sk_buff *mypkt = NULL; | |
| 886 | − | |
| 887 | − sd_trace(("%s: Enter\n", __func__)); | |
| 888 | − | |
| 889 | − BRCMF_PM_RESUME_WAIT(sdioh_request_buffer_wait); | |
| 890 | − BRCMF_PM_RESUME_RETURN_ERROR(-EIO); | |
| 891 | − /* Case 1: we don't have a packet. */ | |
| 892 | − if (pkt == NULL) { | |
| 893 | − sd_data(("%s: Creating new %s Packet, len=%d\n", | |
| 894 | − __func__, write ? "TX" : "RX", buflen_u)); | |
| 895 | − mypkt = brcmu_pkt_buf_get_skb(buflen_u); | |
| 896 | − if (!mypkt) { | |
| 897 | − sd_err(("%s: brcmu_pkt_buf_get_skb failed: len %d\n", | |
| 898 | − __func__, buflen_u)); | |
| 899 | − return -EIO; | |
| 900 | − } | |
| 901 | − | |
| 902 | − /* For a write, copy the buffer data into the packet. */ | |
| 903 | − if (write) | |
| 904 | − memcpy(mypkt->data, buffer, buflen_u); | |
| 905 | − | |
| 906 | − Status = brcmf_sdioh_request_packet(sd, fix_inc, write, func, | |
| 907 | − addr, mypkt); | |
| 908 | − | |
| 909 | − /* For a read, copy the packet data back to the buffer. */ | |
| 910 | − if (!write) | |
| 911 | − memcpy(buffer, mypkt->data, buflen_u); | |
| 912 | − | |
| 913 | − brcmu_pkt_buf_free_skb(mypkt); | |
| 914 | − } else if (((ulong) (pkt->data) & DMA_ALIGN_MASK) != 0) { | |
| 915 | − /* | |
| 916 | − * Case 2: We have a packet, but it is unaligned. | |
| 917 | − * In this case, we cannot have a chain (pkt->next == NULL) | |
| 918 | − */ | |
| 919 | − sd_data(("%s: Creating aligned %s Packet, len=%d\n", | |
| 920 | − __func__, write ? "TX" : "RX", pkt->len)); | |
| 921 | − mypkt = brcmu_pkt_buf_get_skb(pkt->len); | |
| 922 | − if (!mypkt) { | |
| 923 | − sd_err(("%s: brcmu_pkt_buf_get_skb failed: len %d\n", | |
| 924 | − __func__, pkt->len)); | |
| 925 | − return -EIO; | |
| 926 | − } | |
| 927 | − | |
| 928 | − /* For a write, copy the buffer data into the packet. */ | |
| 929 | − if (write) | |
| 930 | − memcpy(mypkt->data, pkt->data, pkt->len); | |
| 931 | − | |
| 932 | − Status = brcmf_sdioh_request_packet(sd, fix_inc, write, func, | |
| 933 | − addr, mypkt); | |
| 934 | − | |
| 935 | − /* For a read, copy the packet data back to the buffer. */ | |
| 936 | − if (!write) | |
| 937 | − memcpy(pkt->data, mypkt->data, mypkt->len); | |
| 938 | − | |
| 939 | − brcmu_pkt_buf_free_skb(mypkt); | |
| 940 | − } else { /* case 3: We have a packet and | |
| 941 | − it is aligned. */ | |
| 942 | − sd_data(("%s: Aligned %s Packet, direct DMA\n", | |
| 943 | − __func__, write ? "Tx" : "Rx")); | |
| 944 | − Status = brcmf_sdioh_request_packet(sd, fix_inc, write, func, | |
| 945 | − addr, pkt); | |
| 946 | − } | |
| 947 | − | |
| 948 | − return Status; | |
| 949 | −} | |
| 950 | − | |
| 951 | −/* this function performs "abort" for both of host & device */ | |
| 952 | −extern int brcmf_sdioh_abort(struct sdioh_info *sd, uint func) | |
| 953 | −{ | |
| 954 | − char t_func = (char)func; | |
| 955 | − sd_trace(("%s: Enter\n", __func__)); | |
| 956 | − | |
| 957 | − /* issue abort cmd52 command through F0 */ | |
| 958 | − brcmf_sdioh_request_byte(sd, SDIOH_WRITE, SDIO_FUNC_0, SDIO_CCCR_ABORT, | |
| 959 | − &t_func); | |
| 960 | − | |
| 961 | − sd_trace(("%s: Exit\n", __func__)); | |
| 962 | − return 0; | |
| 963 | −} | |
| 964 | − | |
| 965 | −/* Disable device interrupt */ | |
| 966 | −void brcmf_sdioh_dev_intr_off(struct sdioh_info *sd) | |
| 967 | −{ | |
| 968 | − sd_trace(("%s: %d\n", __func__, sd->use_client_ints)); | |
| 969 | − sd->intmask &= ~CLIENT_INTR; | |
| 970 | −} | |
| 971 | − | |
| 972 | −/* Enable device interrupt */ | |
| 973 | −void brcmf_sdioh_dev_intr_on(struct sdioh_info *sd) | |
| 974 | −{ | |
| 975 | − sd_trace(("%s: %d\n", __func__, sd->use_client_ints)); | |
| 976 | − sd->intmask |= CLIENT_INTR; | |
| 977 | −} | |
| 978 | − | |
| 979 | −/* Read client card reg */ | |
| 980 | −int | |
| 981 | −brcmf_sdioh_card_regread(struct sdioh_info *sd, int func, u32 regaddr, | |
| 982 | − int regsize, u32 *data) | |
| 983 | −{ | |
| 984 | − | |
| 985 | − if ((func == 0) || (regsize == 1)) { | |
| 986 | − u8 temp = 0; | |
| 987 | − | |
| 988 | − brcmf_sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp); | |
| 989 | − *data = temp; | |
| 990 | − *data &= 0xff; | |
| 991 | − sd_data(("%s: byte read data=0x%02x\n", __func__, *data)); | |
| 992 | − } else { | |
| 993 | − brcmf_sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, data, | |
| 994 | − regsize); | |
| 995 | − if (regsize == 2) | |
| 996 | − *data &= 0xffff; | |
| 997 | − | |
| 998 | − sd_data(("%s: word read data=0x%08x\n", __func__, *data)); | |
| 999 | − } | |
| 1000 | − | |
| 1001 | − return SUCCESS; | |
| 1002 | −} | |
| 1003 | − | |
| 1004 | −static void brcmf_sdioh_irqhandler(struct sdio_func *func) | |
| 1005 | −{ | |
| 1006 | − struct sdioh_info *sd; | |
| 1007 | − | |
| 1008 | − sd_trace(("brcmf: ***IRQHandler\n")); | |
| 1009 | − sd = gInstance->sd; | |
| 1010 | − | |
| 1011 | − sdio_release_host(gInstance->func[0]); | |
| 1012 | − | |
| 1013 | − if (sd->use_client_ints) { | |
| 1014 | − sd->intrcount++; | |
| 1015 | − (sd->intr_handler) (sd->intr_handler_arg); | |
| 1016 | − } else { | |
| 1017 | − sd_err(("brcmf: ***IRQHandler\n")); | |
| 1018 | − | |
| 1019 | − sd_err(("%s: Not ready for intr: enabled %d, handler %p\n", | |
| 1020 | − __func__, sd->client_intr_enabled, sd->intr_handler)); | |
| 1021 | − } | |
| 1022 | − | |
| 1023 | − sdio_claim_host(gInstance->func[0]); | |
| 1024 | −} | |
| 1025 | − | |
| 1026 | −/* interrupt handler for F2 (dummy handler) */ | |
| 1027 | −static void brcmf_sdioh_irqhandler_f2(struct sdio_func *func) | |
| 1028 | −{ | |
| 1029 | − struct sdioh_info *sd; | |
| 1030 | − | |
| 1031 | − sd_trace(("brcmf: ***IRQHandlerF2\n")); | |
| 1032 | − | |
| 1033 | − sd = gInstance->sd; | |
| 1034 | −} | |
| 1035 | − | |
| 1036 | −static int brcmf_ops_sdio_probe(struct sdio_func *func, | |
| 1037 | − const struct sdio_device_id *id) | |
| 1038 | −{ | |
| 1039 | − int ret = 0; | |
| 1040 | − static struct sdio_func sdio_func_0; | |
| 1041 | − sd_trace(("sdio_probe: %s Enter\n", __func__)); | |
| 1042 | − sd_trace(("sdio_probe: func->class=%x\n", func->class)); | |
| 1043 | − sd_trace(("sdio_vendor: 0x%04x\n", func->vendor)); | |
| 1044 | − sd_trace(("sdio_device: 0x%04x\n", func->device)); | |
| 1045 | − sd_trace(("Function#: 0x%04x\n", func->num)); | |
| 1046 | − | |
| 1047 | − if (func->num == 1) { | |
| 1048 | − sdio_func_0.num = 0; | |
| 1049 | − sdio_func_0.card = func->card; | |
| 1050 | − gInstance->func[0] = &sdio_func_0; | |
| 1051 | − if (func->device == 0x4) { /* 4318 */ | |
| 1052 | − gInstance->func[2] = NULL; | |
| 1053 | − sd_trace(("NIC found, calling brcmf_sdio_probe...\n")); | |
| 1054 | − ret = brcmf_sdio_probe(&sdmmc_dev); | |
| 1055 | − } | |
| 1056 | − } | |
| 1057 | − | |
| 1058 | − gInstance->func[func->num] = func; | |
| 1059 | − | |
| 1060 | − if (func->num == 2) { | |
| 1061 | − brcmf_cfg80211_sdio_func(func); | |
| 1062 | − sd_trace(("F2 found, calling brcmf_sdio_probe...\n")); | |
| 1063 | − ret = brcmf_sdio_probe(&sdmmc_dev); | |
| 1064 | − } | |
| 1065 | − | |
| 1066 | − return ret; | |
| 1067 | −} | |
| 1068 | − | |
| 1069 | −static void brcmf_ops_sdio_remove(struct sdio_func *func) | |
| 1070 | −{ | |
| 1071 | − sd_trace(("%s Enter\n", __func__)); | |
| 1072 | − sd_info(("func->class=%x\n", func->class)); | |
| 1073 | − sd_info(("sdio_vendor: 0x%04x\n", func->vendor)); | |
| 1074 | − sd_info(("sdio_device: 0x%04x\n", func->device)); | |
| 1075 | − sd_info(("Function#: 0x%04x\n", func->num)); | |
| 1076 | − | |
| 1077 | − if (func->num == 2) { | |
| 1078 | − sd_trace(("F2 found, calling brcmf_sdio_remove...\n")); | |
| 1079 | − brcmf_sdio_remove(&sdmmc_dev); | |
| 1080 | − } | |
| 1081 | −} | |
| 1082 | − | |
| 1083 | − | |
| 1084 | −#ifdef CONFIG_PM | |
| 1085 | −static int brcmf_sdio_suspend(struct device *dev) | |
| 1086 | −{ | |
| 1087 | − mmc_pm_flag_t sdio_flags; | |
| 1088 | − int ret = 0; | |
| 1089 | − | |
| 1090 | − sd_trace(("%s\n", __func__)); | |
| 1091 | − | |
| 1092 | − sdio_flags = sdio_get_host_pm_caps(gInstance->func[1]); | |
| 1093 | − if (!(sdio_flags & MMC_PM_KEEP_POWER)) { | |
| 1094 | − sd_err(("Host can't keep power while suspended\n")); | |
| 1095 | − return -EINVAL; | |
| 1096 | − } | |
| 1097 | − | |
| 1098 | − ret = sdio_set_host_pm_flags(gInstance->func[1], MMC_PM_KEEP_POWER); | |
| 1099 | − if (ret) { | |
| 1100 | − sd_err(("Failed to set pm_flags\n")); | |
| 1101 | − return ret; | |
| 1102 | − } | |
| 1103 | − | |
| 1104 | − brcmf_sdio_wdtmr_enable(false); | |
| 1105 | − | |
| 1106 | − return ret; | |
| 1107 | −} | |
| 1108 | − | |
| 1109 | −static int brcmf_sdio_resume(struct device *dev) | |
| 1110 | −{ | |
| 1111 | − brcmf_sdio_wdtmr_enable(true); | |
| 1112 | − return 0; | |
| 1113 | −} | |
| 1114 | −#endif /* CONFIG_PM */ | |
| 1115 | − | |
| 1116 | −int brcmf_sdioh_osinit(struct sdioh_info *sd) | |
| 1117 | −{ | |
| 1118 | − struct sdos_info *sdos; | |
| 1119 | − | |
| 1120 | − sdos = kmalloc(sizeof(struct sdos_info), GFP_ATOMIC); | |
| 1121 | − sd->sdos_info = (void *)sdos; | |
| 1122 | − if (sdos == NULL) | |
| 1123 | − return -ENOMEM; | |
| 1124 | − | |
| 1125 | − sdos->sd = sd; | |
| 1126 | − spin_lock_init(&sdos->lock); | |
| 1127 | − return 0; | |
| 1128 | −} | |
| 1129 | − | |
| 1130 | −void brcmf_sdioh_osfree(struct sdioh_info *sd) | |
| 1131 | −{ | |
| 1132 | − struct sdos_info *sdos; | |
| 1133 | − | |
| 1134 | − sdos = (struct sdos_info *)sd->sdos_info; | |
| 1135 | − kfree(sdos); | |
| 1136 | −} | |
| 1137 | − | |
| 1138 | −/* Interrupt enable/disable */ | |
| 1139 | −int brcmf_sdioh_interrupt_set(struct sdioh_info *sd, bool enable) | |
| 1140 | −{ | |
| 1141 | − unsigned long flags; | |
| 1142 | − struct sdos_info *sdos; | |
| 1143 | − | |
| 1144 | − sd_trace(("%s: %s\n", __func__, enable ? "Enabling" : "Disabling")); | |
| 1145 | − | |
| 1146 | − sdos = (struct sdos_info *)sd->sdos_info; | |
| 1147 | − | |
| 1148 | − if (enable && !(sd->intr_handler && sd->intr_handler_arg)) { | |
| 1149 | − sd_err(("%s: no handler registered, will not enable\n", | |
| 1150 | − __func__)); | |
| 1151 | − return -EINVAL; | |
| 1152 | − } | |
| 1153 | − | |
| 1154 | − /* Ensure atomicity for enable/disable calls */ | |
| 1155 | − spin_lock_irqsave(&sdos->lock, flags); | |
| 1156 | − | |
| 1157 | − sd->client_intr_enabled = enable; | |
| 1158 | − if (enable) | |
| 1159 | − brcmf_sdioh_dev_intr_on(sd); | |
| 1160 | − else | |
| 1161 | − brcmf_sdioh_dev_intr_off(sd); | |
| 1162 | − | |
| 1163 | − spin_unlock_irqrestore(&sdos->lock, flags); | |
| 1164 | − | |
| 1165 | − return 0; | |
| 1166 | −} | |
| 1167 | − | |
| 1168 | −/* | |
| 1169 | − * module init | |
| 1170 | −*/ | |
| 1171 | −int brcmf_sdio_function_init(void) | |
| 1172 | −{ | |
| 1173 | − int error = 0; | |
| 1174 | − sd_trace(("brcmf_sdio_function_init: %s Enter\n", __func__)); | |
| 1175 | − | |
| 1176 | − gInstance = kzalloc(sizeof(struct brcmf_sdmmc_instance), GFP_KERNEL); | |
| 1177 | − if (!gInstance) | |
| 1178 | − return -ENOMEM; | |
| 1179 | − | |
| 1180 | − memset(&sdmmc_dev, 0, sizeof(sdmmc_dev)); | |
| 1181 | − error = sdio_register_driver(&brcmf_sdmmc_driver); | |
| 1182 | − | |
| 1183 | − return error; | |
| 1184 | −} | |
| 1185 | − | |
| 1186 | −/* | |
| 1187 | − * module cleanup | |
| 1188 | −*/ | |
| 1189 | −void brcmf_sdio_function_cleanup(void) | |
| 1190 | −{ | |
| 1191 | − sd_trace(("%s Enter\n", __func__)); | |
| 1192 | − | |
| 1193 | − sdio_unregister_driver(&brcmf_sdmmc_driver); | |
| 1194 | − | |
| 1195 | − kfree(gInstance); | |
| 1196 | −} | |
| @@ -1,904 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * Copyright (c) 2010 Broadcom Corporation | |
| 3 | − * | |
| 4 | − * Permission to use, copy, modify, and/or distribute this software for any | |
| 5 | − * purpose with or without fee is hereby granted, provided that the above | |
| 6 | − * copyright notice and this permission notice appear in all copies. | |
| 7 | − * | |
| 8 | − * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
| 9 | − * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
| 10 | − * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
| 11 | − * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 12 | − * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | |
| 13 | − * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
| 14 | − * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
| 15 | − */ | |
| 16 | − | |
| 17 | −/**************** | |
| 18 | − * Common types * | |
| 19 | − */ | |
| 20 | − | |
| 21 | −#ifndef _BRCMF_H_ | |
| 22 | −#define _BRCMF_H_ | |
| 23 | − | |
| 24 | −#define BRCMF_VERSION_STR "4.218.248.5" | |
| 25 | − | |
| 26 | −#define BRCMF_C_IOCTL_SMLEN 256 /* "small" ioctl buffer required */ | |
| 27 | −#define BRCMF_C_IOCTL_MEDLEN 1536 /* "med" ioctl buffer required */ | |
| 28 | −#define BRCMF_C_IOCTL_MAXLEN 8192 | |
| 29 | − | |
| 30 | −#define BRCMF_C_UP 2 | |
| 31 | −#define BRCMF_C_SET_PROMISC 10 | |
| 32 | −#define BRCMF_C_GET_RATE 12 | |
| 33 | −#define BRCMF_C_GET_INFRA 19 | |
| 34 | −#define BRCMF_C_SET_INFRA 20 | |
| 35 | −#define BRCMF_C_GET_AUTH 21 | |
| 36 | −#define BRCMF_C_SET_AUTH 22 | |
| 37 | −#define BRCMF_C_GET_BSSID 23 | |
| 38 | −#define BRCMF_C_GET_SSID 25 | |
| 39 | −#define BRCMF_C_SET_SSID 26 | |
| 40 | −#define BRCMF_C_GET_CHANNEL 29 | |
| 41 | −#define BRCMF_C_GET_SRL 31 | |
| 42 | −#define BRCMF_C_GET_LRL 33 | |
| 43 | −#define BRCMF_C_GET_RADIO 37 | |
| 44 | −#define BRCMF_C_SET_RADIO 38 | |
| 45 | −#define BRCMF_C_GET_PHYTYPE 39 | |
| 46 | −#define BRCMF_C_SET_KEY 45 | |
| 47 | −#define BRCMF_C_SET_PASSIVE_SCAN 49 | |
| 48 | −#define BRCMF_C_SCAN 50 | |
| 49 | −#define BRCMF_C_SCAN_RESULTS 51 | |
| 50 | −#define BRCMF_C_DISASSOC 52 | |
| 51 | −#define BRCMF_C_REASSOC 53 | |
| 52 | −#define BRCMF_C_SET_ROAM_TRIGGER 55 | |
| 53 | −#define BRCMF_C_SET_ROAM_DELTA 57 | |
| 54 | −#define BRCMF_C_GET_DTIMPRD 77 | |
| 55 | −#define BRCMF_C_SET_COUNTRY 84 | |
| 56 | −#define BRCMF_C_GET_PM 85 | |
| 57 | −#define BRCMF_C_SET_PM 86 | |
| 58 | −#define BRCMF_C_GET_AP 117 | |
| 59 | −#define BRCMF_C_SET_AP 118 | |
| 60 | −#define BRCMF_C_GET_RSSI 127 | |
| 61 | −#define BRCMF_C_GET_WSEC 133 | |
| 62 | −#define BRCMF_C_SET_WSEC 134 | |
| 63 | −#define BRCMF_C_GET_PHY_NOISE 135 | |
| 64 | −#define BRCMF_C_GET_BSS_INFO 136 | |
| 65 | −#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185 | |
| 66 | −#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187 | |
| 67 | −#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201 | |
| 68 | −#define BRCMF_C_GET_VALID_CHANNELS 217 | |
| 69 | −#define BRCMF_C_GET_KEY_PRIMARY 235 | |
| 70 | −#define BRCMF_C_SET_KEY_PRIMARY 236 | |
| 71 | −#define BRCMF_C_SET_SCAN_PASSIVE_TIME 258 | |
| 72 | −#define BRCMF_C_GET_VAR 262 | |
| 73 | −#define BRCMF_C_SET_VAR 263 | |
| 74 | − | |
| 75 | −/* phy types (returned by WLC_GET_PHYTPE) */ | |
| 76 | −#define WLC_PHY_TYPE_A 0 | |
| 77 | −#define WLC_PHY_TYPE_B 1 | |
| 78 | −#define WLC_PHY_TYPE_G 2 | |
| 79 | −#define WLC_PHY_TYPE_N 4 | |
| 80 | −#define WLC_PHY_TYPE_LP 5 | |
| 81 | −#define WLC_PHY_TYPE_SSN 6 | |
| 82 | −#define WLC_PHY_TYPE_HT 7 | |
| 83 | −#define WLC_PHY_TYPE_LCN 8 | |
| 84 | −#define WLC_PHY_TYPE_NULL 0xf | |
| 85 | − | |
| 86 | −#define BRCMF_PKT_FILTER_FIXED_LEN offsetof(struct brcmf_pkt_filter, u) | |
| 87 | −#define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN \ | |
| 88 | − offsetof(struct brcmf_pkt_filter_pattern, mask_and_pattern) | |
| 89 | − | |
| 90 | −#define BRCMF_EVENTING_MASK_LEN 16 | |
| 91 | − | |
| 92 | −#define TOE_TX_CSUM_OL 0x00000001 | |
| 93 | −#define TOE_RX_CSUM_OL 0x00000002 | |
| 94 | − | |
| 95 | −/* maximum channels returned by the get valid channels iovar */ | |
| 96 | −#define WL_NUMCHANNELS 64 | |
| 97 | − | |
| 98 | −#define BRCMF_BSS_INFO_VERSION 108 /* current ver of brcmf_bss_info struct */ | |
| 99 | − | |
| 100 | −/* size of brcmf_scan_params not including variable length array */ | |
| 101 | −#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64 | |
| 102 | − | |
| 103 | −/* masks for channel and ssid count */ | |
| 104 | −#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff | |
| 105 | −#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16 | |
| 106 | − | |
| 107 | −#define BRCMF_SCAN_ACTION_START 1 | |
| 108 | −#define BRCMF_SCAN_ACTION_CONTINUE 2 | |
| 109 | −#define WL_SCAN_ACTION_ABORT 3 | |
| 110 | − | |
| 111 | −#define BRCMF_ISCAN_REQ_VERSION 1 | |
| 112 | − | |
| 113 | −/* brcmf_iscan_results status values */ | |
| 114 | −#define BRCMF_SCAN_RESULTS_SUCCESS 0 | |
| 115 | −#define BRCMF_SCAN_RESULTS_PARTIAL 1 | |
| 116 | −#define BRCMF_SCAN_RESULTS_PENDING 2 | |
| 117 | −#define BRCMF_SCAN_RESULTS_ABORTED 3 | |
| 118 | −#define BRCMF_SCAN_RESULTS_NO_MEM 4 | |
| 119 | − | |
| 120 | −#define WL_SOFT_KEY (1 << 0) /* Indicates this key is using soft encrypt */ | |
| 121 | −#define BRCMF_PRIMARY_KEY (1 << 1) /* primary (ie tx) key */ | |
| 122 | −#define WL_KF_RES_4 (1 << 4) /* Reserved for backward compat */ | |
| 123 | −#define WL_KF_RES_5 (1 << 5) /* Reserved for backward compat */ | |
| 124 | −#define WL_IBSS_PEER_GROUP_KEY (1 << 6) /* Indicates a group key for a IBSS PEER */ | |
| 125 | − | |
| 126 | −/* For supporting multiple interfaces */ | |
| 127 | −#define BRCMF_MAX_IFS 16 | |
| 128 | −#define BRCMF_DEL_IF -0xe | |
| 129 | −#define BRCMF_BAD_IF -0xf | |
| 130 | − | |
| 131 | −#define DOT11_BSSTYPE_ANY 2 | |
| 132 | −#define DOT11_MAX_DEFAULT_KEYS 4 | |
| 133 | − | |
| 134 | −#define BRCMF_EVENT_MSG_LINK 0x01 | |
| 135 | −#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02 | |
| 136 | −#define BRCMF_EVENT_MSG_GROUP 0x04 | |
| 137 | − | |
| 138 | −struct brcmf_event_msg { | |
| 139 | − u16 version; | |
| 140 | − u16 flags; | |
| 141 | − u32 event_type; | |
| 142 | − u32 status; | |
| 143 | − u32 reason; | |
| 144 | − u32 auth_type; | |
| 145 | − u32 datalen; | |
| 146 | − u8 addr[ETH_ALEN]; | |
| 147 | − char ifname[IFNAMSIZ]; | |
| 148 | −} __packed; | |
| 149 | − | |
| 150 | −struct brcm_ethhdr { | |
| 151 | − u16 subtype; | |
| 152 | − u16 length; | |
| 153 | − u8 version; | |
| 154 | − u8 oui[3]; | |
| 155 | − u16 usr_subtype; | |
| 156 | −} __packed; | |
| 157 | − | |
| 158 | −struct brcmf_event { | |
| 159 | − struct ethhdr eth; | |
| 160 | − struct brcm_ethhdr hdr; | |
| 161 | − struct brcmf_event_msg msg; | |
| 162 | −} __packed; | |
| 163 | − | |
| 164 | −struct dngl_stats { | |
| 165 | − unsigned long rx_packets; /* total packets received */ | |
| 166 | − unsigned long tx_packets; /* total packets transmitted */ | |
| 167 | − unsigned long rx_bytes; /* total bytes received */ | |
| 168 | − unsigned long tx_bytes; /* total bytes transmitted */ | |
| 169 | − unsigned long rx_errors; /* bad packets received */ | |
| 170 | − unsigned long tx_errors; /* packet transmit problems */ | |
| 171 | − unsigned long rx_dropped; /* packets dropped by dongle */ | |
| 172 | − unsigned long tx_dropped; /* packets dropped by dongle */ | |
| 173 | − unsigned long multicast; /* multicast packets received */ | |
| 174 | −}; | |
| 175 | − | |
| 176 | −#define BRCMF_E_SET_SSID 0 | |
| 177 | −#define BRCMF_E_JOIN 1 | |
| 178 | −#define BRCMF_E_START 2 | |
| 179 | −#define BRCMF_E_AUTH 3 | |
| 180 | −#define BRCMF_E_AUTH_IND 4 | |
| 181 | −#define BRCMF_E_DEAUTH 5 | |
| 182 | −#define BRCMF_E_DEAUTH_IND 6 | |
| 183 | −#define BRCMF_E_ASSOC 7 | |
| 184 | −#define BRCMF_E_ASSOC_IND 8 | |
| 185 | −#define BRCMF_E_REASSOC 9 | |
| 186 | −#define BRCMF_E_REASSOC_IND 10 | |
| 187 | −#define BRCMF_E_DISASSOC 11 | |
| 188 | −#define BRCMF_E_DISASSOC_IND 12 | |
| 189 | −#define BRCMF_E_QUIET_START 13 | |
| 190 | −#define BRCMF_E_QUIET_END 14 | |
| 191 | −#define BRCMF_E_BEACON_RX 15 | |
| 192 | −#define BRCMF_E_LINK 16 | |
| 193 | −#define BRCMF_E_MIC_ERROR 17 | |
| 194 | −#define BRCMF_E_NDIS_LINK 18 | |
| 195 | −#define BRCMF_E_ROAM 19 | |
| 196 | −#define BRCMF_E_TXFAIL 20 | |
| 197 | −#define BRCMF_E_PMKID_CACHE 21 | |
| 198 | −#define BRCMF_E_RETROGRADE_TSF 22 | |
| 199 | −#define BRCMF_E_PRUNE 23 | |
| 200 | −#define BRCMF_E_AUTOAUTH 24 | |
| 201 | −#define BRCMF_E_EAPOL_MSG 25 | |
| 202 | −#define BRCMF_E_SCAN_COMPLETE 26 | |
| 203 | −#define BRCMF_E_ADDTS_IND 27 | |
| 204 | −#define BRCMF_E_DELTS_IND 28 | |
| 205 | −#define BRCMF_E_BCNSENT_IND 29 | |
| 206 | −#define BRCMF_E_BCNRX_MSG 30 | |
| 207 | −#define BRCMF_E_BCNLOST_MSG 31 | |
| 208 | −#define BRCMF_E_ROAM_PREP 32 | |
| 209 | −#define BRCMF_E_PFN_NET_FOUND 33 | |
| 210 | −#define BRCMF_E_PFN_NET_LOST 34 | |
| 211 | −#define BRCMF_E_RESET_COMPLETE 35 | |
| 212 | −#define BRCMF_E_JOIN_START 36 | |
| 213 | −#define BRCMF_E_ROAM_START 37 | |
| 214 | −#define BRCMF_E_ASSOC_START 38 | |
| 215 | −#define BRCMF_E_IBSS_ASSOC 39 | |
| 216 | −#define BRCMF_E_RADIO 40 | |
| 217 | −#define BRCMF_E_PSM_WATCHDOG 41 | |
| 218 | −#define BRCMF_E_PROBREQ_MSG 44 | |
| 219 | −#define BRCMF_E_SCAN_CONFIRM_IND 45 | |
| 220 | −#define BRCMF_E_PSK_SUP 46 | |
| 221 | −#define BRCMF_E_COUNTRY_CODE_CHANGED 47 | |
| 222 | −#define BRCMF_E_EXCEEDED_MEDIUM_TIME 48 | |
| 223 | −#define BRCMF_E_ICV_ERROR 49 | |
| 224 | −#define BRCMF_E_UNICAST_DECODE_ERROR 50 | |
| 225 | −#define BRCMF_E_MULTICAST_DECODE_ERROR 51 | |
| 226 | −#define BRCMF_E_TRACE 52 | |
| 227 | −#define BRCMF_E_IF 54 | |
| 228 | −#define BRCMF_E_RSSI 56 | |
| 229 | −#define BRCMF_E_PFN_SCAN_COMPLETE 57 | |
| 230 | −#define BRCMF_E_EXTLOG_MSG 58 | |
| 231 | −#define BRCMF_E_ACTION_FRAME 59 | |
| 232 | −#define BRCMF_E_ACTION_FRAME_COMPLETE 60 | |
| 233 | −#define BRCMF_E_PRE_ASSOC_IND 61 | |
| 234 | −#define BRCMF_E_PRE_REASSOC_IND 62 | |
| 235 | −#define BRCMF_E_CHANNEL_ADOPTED 63 | |
| 236 | −#define BRCMF_E_AP_STARTED 64 | |
| 237 | −#define BRCMF_E_DFS_AP_STOP 65 | |
| 238 | −#define BRCMF_E_DFS_AP_RESUME 66 | |
| 239 | −#define BRCMF_E_RESERVED1 67 | |
| 240 | −#define BRCMF_E_RESERVED2 68 | |
| 241 | −#define BRCMF_E_ESCAN_RESULT 69 | |
| 242 | −#define BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70 | |
| 243 | −#define BRCMF_E_DCS_REQUEST 73 | |
| 244 | − | |
| 245 | −#define BRCMF_E_FIFO_CREDIT_MAP 74 | |
| 246 | − | |
| 247 | −#define BRCMF_E_LAST 75 | |
| 248 | − | |
| 249 | −#define BRCMF_E_STATUS_SUCCESS 0 | |
| 250 | −#define BRCMF_E_STATUS_FAIL 1 | |
| 251 | −#define BRCMF_E_STATUS_TIMEOUT 2 | |
| 252 | −#define BRCMF_E_STATUS_NO_NETWORKS 3 | |
| 253 | −#define BRCMF_E_STATUS_ABORT 4 | |
| 254 | −#define BRCMF_E_STATUS_NO_ACK 5 | |
| 255 | −#define BRCMF_E_STATUS_UNSOLICITED 6 | |
| 256 | −#define BRCMF_E_STATUS_ATTEMPT 7 | |
| 257 | −#define BRCMF_E_STATUS_PARTIAL 8 | |
| 258 | −#define BRCMF_E_STATUS_NEWSCAN 9 | |
| 259 | −#define BRCMF_E_STATUS_NEWASSOC 10 | |
| 260 | −#define BRCMF_E_STATUS_11HQUIET 11 | |
| 261 | −#define BRCMF_E_STATUS_SUPPRESS 12 | |
| 262 | −#define BRCMF_E_STATUS_NOCHANS 13 | |
| 263 | −#define BRCMF_E_STATUS_CS_ABORT 15 | |
| 264 | −#define BRCMF_E_STATUS_ERROR 16 | |
| 265 | − | |
| 266 | −#define BRCMF_E_REASON_INITIAL_ASSOC 0 | |
| 267 | −#define BRCMF_E_REASON_LOW_RSSI 1 | |
| 268 | −#define BRCMF_E_REASON_DEAUTH 2 | |
| 269 | −#define BRCMF_E_REASON_DISASSOC 3 | |
| 270 | −#define BRCMF_E_REASON_BCNS_LOST 4 | |
| 271 | −#define BRCMF_E_REASON_MINTXRATE 9 | |
| 272 | −#define BRCMF_E_REASON_TXFAIL 10 | |
| 273 | − | |
| 274 | −#define BRCMF_E_REASON_FAST_ROAM_FAILED 5 | |
| 275 | −#define BRCMF_E_REASON_DIRECTED_ROAM 6 | |
| 276 | −#define BRCMF_E_REASON_TSPEC_REJECTED 7 | |
| 277 | −#define BRCMF_E_REASON_BETTER_AP 8 | |
| 278 | − | |
| 279 | −#define BRCMF_E_PRUNE_ENCR_MISMATCH 1 | |
| 280 | −#define BRCMF_E_PRUNE_BCAST_BSSID 2 | |
| 281 | −#define BRCMF_E_PRUNE_MAC_DENY 3 | |
| 282 | −#define BRCMF_E_PRUNE_MAC_NA 4 | |
| 283 | −#define BRCMF_E_PRUNE_REG_PASSV 5 | |
| 284 | −#define BRCMF_E_PRUNE_SPCT_MGMT 6 | |
| 285 | −#define BRCMF_E_PRUNE_RADAR 7 | |
| 286 | −#define BRCMF_E_RSN_MISMATCH 8 | |
| 287 | −#define BRCMF_E_PRUNE_NO_COMMON_RATES 9 | |
| 288 | −#define BRCMF_E_PRUNE_BASIC_RATES 10 | |
| 289 | −#define BRCMF_E_PRUNE_CIPHER_NA 12 | |
| 290 | −#define BRCMF_E_PRUNE_KNOWN_STA 13 | |
| 291 | −#define BRCMF_E_PRUNE_WDS_PEER 15 | |
| 292 | −#define BRCMF_E_PRUNE_QBSS_LOAD 16 | |
| 293 | −#define BRCMF_E_PRUNE_HOME_AP 17 | |
| 294 | − | |
| 295 | −#define BRCMF_E_SUP_OTHER 0 | |
| 296 | −#define BRCMF_E_SUP_DECRYPT_KEY_DATA 1 | |
| 297 | −#define BRCMF_E_SUP_BAD_UCAST_WEP128 2 | |
| 298 | −#define BRCMF_E_SUP_BAD_UCAST_WEP40 3 | |
| 299 | −#define BRCMF_E_SUP_UNSUP_KEY_LEN 4 | |
| 300 | −#define BRCMF_E_SUP_PW_KEY_CIPHER 5 | |
| 301 | −#define BRCMF_E_SUP_MSG3_TOO_MANY_IE 6 | |
| 302 | −#define BRCMF_E_SUP_MSG3_IE_MISMATCH 7 | |
| 303 | −#define BRCMF_E_SUP_NO_INSTALL_FLAG 8 | |
| 304 | −#define BRCMF_E_SUP_MSG3_NO_GTK 9 | |
| 305 | −#define BRCMF_E_SUP_GRP_KEY_CIPHER 10 | |
| 306 | −#define BRCMF_E_SUP_GRP_MSG1_NO_GTK 11 | |
| 307 | −#define BRCMF_E_SUP_GTK_DECRYPT_FAIL 12 | |
| 308 | −#define BRCMF_E_SUP_SEND_FAIL 13 | |
| 309 | −#define BRCMF_E_SUP_DEAUTH 14 | |
| 310 | − | |
| 311 | −#define BRCMF_E_IF_ADD 1 | |
| 312 | −#define BRCMF_E_IF_DEL 2 | |
| 313 | −#define BRCMF_E_IF_CHANGE 3 | |
| 314 | − | |
| 315 | −#define BRCMF_E_IF_ROLE_STA 0 | |
| 316 | −#define BRCMF_E_IF_ROLE_AP 1 | |
| 317 | −#define BRCMF_E_IF_ROLE_WDS 2 | |
| 318 | − | |
| 319 | −#define BRCMF_E_LINK_BCN_LOSS 1 | |
| 320 | −#define BRCMF_E_LINK_DISASSOC 2 | |
| 321 | −#define BRCMF_E_LINK_ASSOC_REC 3 | |
| 322 | −#define BRCMF_E_LINK_BSSCFG_DIS 4 | |
| 323 | − | |
| 324 | −/* The level of bus communication with the dongle */ | |
| 325 | −enum brcmf_bus_state { | |
| 326 | − BRCMF_BUS_DOWN, /* Not ready for frame transfers */ | |
| 327 | − BRCMF_BUS_LOAD, /* Download access only (CPU reset) */ | |
| 328 | − BRCMF_BUS_DATA /* Ready for frame transfers */ | |
| 329 | −}; | |
| 330 | − | |
| 331 | −/* Pattern matching filter. Specifies an offset within received packets to | |
| 332 | − * start matching, the pattern to match, the size of the pattern, and a bitmask | |
| 333 | − * that indicates which bits within the pattern should be matched. | |
| 334 | − */ | |
| 335 | −struct brcmf_pkt_filter_pattern { | |
| 336 | − u32 offset; /* Offset within received packet to start pattern matching. | |
| 337 | − * Offset '0' is the first byte of the ethernet header. | |
| 338 | − */ | |
| 339 | − u32 size_bytes; /* Size of the pattern. Bitmask must be the same size. */ | |
| 340 | − u8 mask_and_pattern[1]; /* Variable length mask and pattern data. mask starts | |
| 341 | − * at offset 0. Pattern immediately follows mask. | |
| 342 | − */ | |
| 343 | −}; | |
| 344 | − | |
| 345 | −/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */ | |
| 346 | −struct brcmf_pkt_filter { | |
| 347 | − u32 id; /* Unique filter id, specified by app. */ | |
| 348 | − u32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */ | |
| 349 | − u32 negate_match; /* Negate the result of filter matches */ | |
| 350 | − union { /* Filter definitions */ | |
| 351 | − struct brcmf_pkt_filter_pattern pattern; /* Filter pattern */ | |
| 352 | − } u; | |
| 353 | −}; | |
| 354 | − | |
| 355 | −/* IOVAR "pkt_filter_enable" parameter. */ | |
| 356 | −struct brcmf_pkt_filter_enable { | |
| 357 | − u32 id; /* Unique filter id */ | |
| 358 | − u32 enable; /* Enable/disable bool */ | |
| 359 | −}; | |
| 360 | − | |
| 361 | −/* BSS info structure | |
| 362 | − * Applications MUST CHECK ie_offset field and length field to access IEs and | |
| 363 | − * next bss_info structure in a vector (in struct brcmf_scan_results) | |
| 364 | − */ | |
| 365 | −struct brcmf_bss_info { | |
| 366 | − u32 version; /* version field */ | |
| 367 | − u32 length; /* byte length of data in this record, | |
| 368 | − * starting at version and including IEs | |
| 369 | − */ | |
| 370 | − u8 BSSID[ETH_ALEN]; | |
| 371 | − u16 beacon_period; /* units are Kusec */ | |
| 372 | − u16 capability; /* Capability information */ | |
| 373 | − u8 SSID_len; | |
| 374 | − u8 SSID[32]; | |
| 375 | − struct { | |
| 376 | − uint count; /* # rates in this set */ | |
| 377 | − u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ | |
| 378 | − } rateset; /* supported rates */ | |
| 379 | − chanspec_t chanspec; /* chanspec for bss */ | |
| 380 | − u16 atim_window; /* units are Kusec */ | |
| 381 | − u8 dtim_period; /* DTIM period */ | |
| 382 | − s16 RSSI; /* receive signal strength (in dBm) */ | |
| 383 | − s8 phy_noise; /* noise (in dBm) */ | |
| 384 | − | |
| 385 | − u8 n_cap; /* BSS is 802.11N Capable */ | |
| 386 | − u32 nbss_cap; /* 802.11N BSS Capabilities (based on HT_CAP_*) */ | |
| 387 | − u8 ctl_ch; /* 802.11N BSS control channel number */ | |
| 388 | − u32 reserved32[1]; /* Reserved for expansion of BSS properties */ | |
| 389 | − u8 flags; /* flags */ | |
| 390 | − u8 reserved[3]; /* Reserved for expansion of BSS properties */ | |
| 391 | − u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ | |
| 392 | − | |
| 393 | − u16 ie_offset; /* offset at which IEs start, from beginning */ | |
| 394 | − u32 ie_length; /* byte length of Information Elements */ | |
| 395 | − s16 SNR; /* average SNR of during frame reception */ | |
| 396 | − /* Add new fields here */ | |
| 397 | − /* variable length Information Elements */ | |
| 398 | −}; | |
| 399 | − | |
| 400 | −struct brcmf_ssid { | |
| 401 | − u32 SSID_len; | |
| 402 | − unsigned char SSID[32]; | |
| 403 | −}; | |
| 404 | − | |
| 405 | −struct brcmf_scan_params { | |
| 406 | − struct brcmf_ssid ssid; /* default: {0, ""} */ | |
| 407 | − u8 bssid[ETH_ALEN]; /* default: bcast */ | |
| 408 | − s8 bss_type; /* default: any, | |
| 409 | − * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT | |
| 410 | − */ | |
| 411 | − u8 scan_type; /* flags, 0 use default */ | |
| 412 | − s32 nprobes; /* -1 use default, number of probes per channel */ | |
| 413 | − s32 active_time; /* -1 use default, dwell time per channel for | |
| 414 | − * active scanning | |
| 415 | − */ | |
| 416 | − s32 passive_time; /* -1 use default, dwell time per channel | |
| 417 | − * for passive scanning | |
| 418 | − */ | |
| 419 | − s32 home_time; /* -1 use default, dwell time for the home channel | |
| 420 | − * between channel scans | |
| 421 | − */ | |
| 422 | − s32 channel_num; /* count of channels and ssids that follow | |
| 423 | − * | |
| 424 | − * low half is count of channels in | |
| 425 | − * channel_list, 0 means default (use all | |
| 426 | − * available channels) | |
| 427 | − * | |
| 428 | − * high half is entries in struct brcmf_ssid | |
| 429 | − * array that follows channel_list, aligned for | |
| 430 | − * s32 (4 bytes) meaning an odd channel count | |
| 431 | − * implies a 2-byte pad between end of | |
| 432 | − * channel_list and first ssid | |
| 433 | − * | |
| 434 | − * if ssid count is zero, single ssid in the | |
| 435 | − * fixed parameter portion is assumed, otherwise | |
| 436 | − * ssid in the fixed portion is ignored | |
| 437 | − */ | |
| 438 | − u16 channel_list[1]; /* list of chanspecs */ | |
| 439 | −}; | |
| 440 | − | |
| 441 | −/* incremental scan struct */ | |
| 442 | −struct brcmf_iscan_params { | |
| 443 | − u32 version; | |
| 444 | − u16 action; | |
| 445 | − u16 scan_duration; | |
| 446 | − struct brcmf_scan_params params; | |
| 447 | −}; | |
| 448 | − | |
| 449 | −/* 3 fields + size of brcmf_scan_params, not including variable length array */ | |
| 450 | −#define BRCMF_ISCAN_PARAMS_FIXED_SIZE \ | |
| 451 | − (offsetof(struct brcmf_iscan_params, params) + \ | |
| 452 | − sizeof(struct brcmf_ssid)) | |
| 453 | − | |
| 454 | −struct brcmf_scan_results { | |
| 455 | − u32 buflen; | |
| 456 | − u32 version; | |
| 457 | − u32 count; | |
| 458 | − struct brcmf_bss_info bss_info[1]; | |
| 459 | −}; | |
| 460 | − | |
| 461 | −/* used for association with a specific BSSID and chanspec list */ | |
| 462 | −struct brcmf_assoc_params { | |
| 463 | − u8 bssid[ETH_ALEN]; /* 00:00:00:00:00:00: broadcast scan */ | |
| 464 | − s32 chanspec_num; /* 0: all available channels, | |
| 465 | − * otherwise count of chanspecs in chanspec_list | |
| 466 | − */ | |
| 467 | − chanspec_t chanspec_list[1]; /* list of chanspecs */ | |
| 468 | −}; | |
| 469 | −#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \ | |
| 470 | − (sizeof(struct brcmf_assoc_params) - sizeof(chanspec_t)) | |
| 471 | − | |
| 472 | −/* used for join with or without a specific bssid and channel list */ | |
| 473 | −struct brcmf_join_params { | |
| 474 | − struct brcmf_ssid ssid; | |
| 475 | − struct brcmf_assoc_params params; | |
| 476 | −}; | |
| 477 | − | |
| 478 | −/* size of brcmf_scan_results not including variable length array */ | |
| 479 | −#define BRCMF_SCAN_RESULTS_FIXED_SIZE \ | |
| 480 | − (sizeof(struct brcmf_scan_results) - sizeof(struct brcmf_bss_info)) | |
| 481 | − | |
| 482 | −/* incremental scan results struct */ | |
| 483 | −struct brcmf_iscan_results { | |
| 484 | − u32 status; | |
| 485 | − struct brcmf_scan_results results; | |
| 486 | −}; | |
| 487 | − | |
| 488 | −/* size of brcmf_iscan_results not including variable length array */ | |
| 489 | −#define BRCMF_ISCAN_RESULTS_FIXED_SIZE \ | |
| 490 | − (BRCMF_SCAN_RESULTS_FIXED_SIZE + \ | |
| 491 | − offsetof(struct brcmf_iscan_results, results)) | |
| 492 | − | |
| 493 | −struct brcmf_wsec_key { | |
| 494 | − u32 index; /* key index */ | |
| 495 | − u32 len; /* key length */ | |
| 496 | − u8 data[WLAN_MAX_KEY_LEN]; /* key data */ | |
| 497 | − u32 pad_1[18]; | |
| 498 | − u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ | |
| 499 | − u32 flags; /* misc flags */ | |
| 500 | − u32 pad_2[2]; | |
| 501 | − int pad_3; | |
| 502 | − int iv_initialized; /* has IV been initialized already? */ | |
| 503 | − int pad_4; | |
| 504 | − /* Rx IV */ | |
| 505 | − struct { | |
| 506 | − u32 hi; /* upper 32 bits of IV */ | |
| 507 | − u16 lo; /* lower 16 bits of IV */ | |
| 508 | − } rxiv; | |
| 509 | − u32 pad_5[2]; | |
| 510 | − u8 ea[ETH_ALEN]; /* per station */ | |
| 511 | −}; | |
| 512 | − | |
| 513 | −/* Used to get specific STA parameters */ | |
| 514 | −struct brcmf_scb_val { | |
| 515 | − u32 val; | |
| 516 | − u8 ea[ETH_ALEN]; | |
| 517 | −}; | |
| 518 | − | |
| 519 | −/* channel encoding */ | |
| 520 | −struct brcmf_channel_info { | |
| 521 | − int hw_channel; | |
| 522 | − int target_channel; | |
| 523 | − int scan_channel; | |
| 524 | −}; | |
| 525 | − | |
| 526 | −/* Linux network driver ioctl encoding */ | |
| 527 | −struct brcmf_ioctl { | |
| 528 | − uint cmd; /* common ioctl definition */ | |
| 529 | − void *buf; /* pointer to user buffer */ | |
| 530 | − uint len; /* length of user buffer */ | |
| 531 | − u8 set; /* get or set request (optional) */ | |
| 532 | − uint used; /* bytes read or written (optional) */ | |
| 533 | − uint needed; /* bytes needed (optional) */ | |
| 534 | −}; | |
| 535 | − | |
| 536 | −/* Forward decls for struct brcmf_pub (see below) */ | |
| 537 | −struct brcmf_bus; /* device bus info */ | |
| 538 | −struct brcmf_proto; /* device communication protocol info */ | |
| 539 | −struct brcmf_info; /* device driver info */ | |
| 540 | − | |
| 541 | −/* Common structure for module and instance linkage */ | |
| 542 | −struct brcmf_pub { | |
| 543 | − /* Linkage ponters */ | |
| 544 | − struct brcmf_bus *bus; | |
| 545 | − struct brcmf_proto *prot; | |
| 546 | − struct brcmf_info *info; | |
| 547 | − | |
| 548 | − /* Internal brcmf items */ | |
| 549 | − bool up; /* Driver up/down (to OS) */ | |
| 550 | − bool txoff; /* Transmit flow-controlled */ | |
| 551 | − bool dongle_reset; /* true = DEVRESET put dongle into reset */ | |
| 552 | − enum brcmf_bus_state busstate; | |
| 553 | − uint hdrlen; /* Total BRCMF header length (proto + bus) */ | |
| 554 | − uint maxctl; /* Max size rxctl request from proto to bus */ | |
| 555 | − uint rxsz; /* Rx buffer size bus module should use */ | |
| 556 | − u8 wme_dp; /* wme discard priority */ | |
| 557 | − | |
| 558 | − /* Dongle media info */ | |
| 559 | − bool iswl; /* Dongle-resident driver is wl */ | |
| 560 | − unsigned long drv_version; /* Version of dongle-resident driver */ | |
| 561 | − u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */ | |
| 562 | − struct dngl_stats dstats; /* Stats for dongle-based data */ | |
| 563 | − | |
| 564 | − /* Additional stats for the bus level */ | |
| 565 | − unsigned long tx_packets; /* Data packets sent to dongle */ | |
| 566 | − unsigned long tx_multicast; /* Multicast data packets sent to dongle */ | |
| 567 | − unsigned long tx_errors; /* Errors in sending data to dongle */ | |
| 568 | − unsigned long tx_ctlpkts; /* Control packets sent to dongle */ | |
| 569 | − unsigned long tx_ctlerrs; /* Errors sending control frames to dongle */ | |
| 570 | − unsigned long rx_packets; /* Packets sent up the network interface */ | |
| 571 | − unsigned long rx_multicast; /* Multicast packets sent up the network | |
| 572 | − interface */ | |
| 573 | − unsigned long rx_errors; /* Errors processing rx data packets */ | |
| 574 | − unsigned long rx_ctlpkts; /* Control frames processed from dongle */ | |
| 575 | − unsigned long rx_ctlerrs; /* Errors in processing rx control frames */ | |
| 576 | − unsigned long rx_dropped; /* Packets dropped locally (no memory) */ | |
| 577 | − unsigned long rx_flushed; /* Packets flushed due to | |
| 578 | − unscheduled sendup thread */ | |
| 579 | − unsigned long wd_dpc_sched; /* Number of times dpc scheduled by | |
| 580 | − watchdog timer */ | |
| 581 | − | |
| 582 | − unsigned long rx_readahead_cnt; /* Number of packets where header read-ahead | |
| 583 | − was used. */ | |
| 584 | − unsigned long tx_realloc; /* Number of tx packets we had to realloc for | |
| 585 | − headroom */ | |
| 586 | − unsigned long fc_packets; /* Number of flow control pkts recvd */ | |
| 587 | − | |
| 588 | − /* Last error return */ | |
| 589 | − int bcmerror; | |
| 590 | − uint tickcnt; | |
| 591 | − | |
| 592 | − /* Last error from dongle */ | |
| 593 | − int dongle_error; | |
| 594 | − | |
| 595 | − /* Suspend disable flag flag */ | |
| 596 | − int suspend_disable_flag; /* "1" to disable all extra powersaving | |
| 597 | − during suspend */ | |
| 598 | − int in_suspend; /* flag set to 1 when early suspend called */ | |
| 599 | − int dtim_skip; /* dtim skip , default 0 means wake each dtim */ | |
| 600 | − | |
| 601 | − /* Pkt filter defination */ | |
| 602 | − char *pktfilter[100]; | |
| 603 | − int pktfilter_count; | |
| 604 | − | |
| 605 | − u8 country_code[BRCM_CNTRY_BUF_SZ]; | |
| 606 | − char eventmask[BRCMF_EVENTING_MASK_LEN]; | |
| 607 | − | |
| 608 | −}; | |
| 609 | − | |
| 610 | −struct brcmf_if_event { | |
| 611 | − u8 ifidx; | |
| 612 | − u8 action; | |
| 613 | − u8 flags; | |
| 614 | − u8 bssidx; | |
| 615 | −}; | |
| 616 | − | |
| 617 | −struct brcmf_timeout { | |
| 618 | − u32 limit; /* Expiration time (usec) */ | |
| 619 | − u32 increment; /* Current expiration increment (usec) */ | |
| 620 | − u32 elapsed; /* Current elapsed time (usec) */ | |
| 621 | − u32 tick; /* O/S tick time (usec) */ | |
| 622 | −}; | |
| 623 | − | |
| 624 | −struct bcmevent_name { | |
| 625 | − uint event; | |
| 626 | − const char *name; | |
| 627 | −}; | |
| 628 | − | |
| 629 | −#if defined(CONFIG_PM_SLEEP) | |
| 630 | −extern atomic_t brcmf_mmc_suspend; | |
| 631 | −#define BRCMF_PM_RESUME_WAIT_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a); | |
| 632 | −#define _BRCMF_PM_RESUME_WAIT(a, b) do { \ | |
| 633 | − int retry = 0; \ | |
| 634 | − while (atomic_read(&brcmf_mmc_suspend) && retry++ != b) { \ | |
| 635 | − wait_event_timeout(a, false, HZ/100); \ | |
| 636 | − } \ | |
| 637 | − } while (0) | |
| 638 | −#define BRCMF_PM_RESUME_WAIT(a) _BRCMF_PM_RESUME_WAIT(a, 30) | |
| 639 | −#define BRCMF_PM_RESUME_RETURN_ERROR(a) \ | |
| 640 | − do { if (atomic_read(&brcmf_mmc_suspend)) return a; } while (0) | |
| 641 | − | |
| 642 | −#define BRCMF_SPINWAIT_SLEEP_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a); | |
| 643 | −#define BRCMF_SPINWAIT_SLEEP(a, exp, us) do { \ | |
| 644 | − uint countdown = (us) + 9999; \ | |
| 645 | − while ((exp) && (countdown >= 10000)) { \ | |
| 646 | − wait_event_timeout(a, false, HZ/100); \ | |
| 647 | − countdown -= 10000; \ | |
| 648 | − } \ | |
| 649 | − } while (0) | |
| 650 | − | |
| 651 | −#else | |
| 652 | − | |
| 653 | −#define BRCMF_PM_RESUME_WAIT_INIT(a) | |
| 654 | −#define BRCMF_PM_RESUME_WAIT(a) | |
| 655 | −#define BRCMF_PM_RESUME_RETURN_ERROR(a) | |
| 656 | − | |
| 657 | −#define BRCMF_SPINWAIT_SLEEP_INIT(a) | |
| 658 | −#define BRCMF_SPINWAIT_SLEEP(a, exp, us) do { \ | |
| 659 | − uint countdown = (us) + 9; \ | |
| 660 | − while ((exp) && (countdown >= 10)) { \ | |
| 661 | − udelay(10); \ | |
| 662 | − countdown -= 10; \ | |
| 663 | − } \ | |
| 664 | − } while (0) | |
| 665 | − | |
| 666 | −#endif /* defined(CONFIG_PM_SLEEP) */ | |
| 667 | − | |
| 668 | −/* | |
| 669 | − * Insmod parameters for debug/test | |
| 670 | − */ | |
| 671 | − | |
| 672 | −/* Use interrupts */ | |
| 673 | −extern uint brcmf_intr; | |
| 674 | − | |
| 675 | −/* Use polling */ | |
| 676 | −extern uint brcmf_poll; | |
| 677 | − | |
| 678 | −/* ARP offload agent mode */ | |
| 679 | −extern uint brcmf_arp_mode; | |
| 680 | − | |
| 681 | −/* ARP offload enable */ | |
| 682 | −extern uint brcmf_arp_enable; | |
| 683 | − | |
| 684 | −/* Pkt filte enable control */ | |
| 685 | −extern uint brcmf_pkt_filter_enable; | |
| 686 | − | |
| 687 | −/* Pkt filter init setup */ | |
| 688 | −extern uint brcmf_pkt_filter_init; | |
| 689 | − | |
| 690 | −/* Pkt filter mode control */ | |
| 691 | −extern uint brcmf_master_mode; | |
| 692 | − | |
| 693 | −/* Roaming mode control */ | |
| 694 | −extern uint brcmf_roam; | |
| 695 | − | |
| 696 | −/* Roaming mode control */ | |
| 697 | −extern uint brcmf_radio_up; | |
| 698 | − | |
| 699 | −/* Initial idletime ticks (may be -1 for immediate idle, 0 for no idle) */ | |
| 700 | −extern int brcmf_idletime; | |
| 701 | −#define BRCMF_IDLETIME_TICKS 1 | |
| 702 | − | |
| 703 | −/* SDIO Drive Strength */ | |
| 704 | −extern uint brcmf_sdiod_drive_strength; | |
| 705 | − | |
| 706 | −/* Override to force tx queueing all the time */ | |
| 707 | −extern uint brcmf_force_tx_queueing; | |
| 708 | − | |
| 709 | −#ifdef SDTEST | |
| 710 | −/* Echo packet generator (SDIO), pkts/s */ | |
| 711 | −extern uint brcmf_pktgen; | |
| 712 | − | |
| 713 | −/* Echo packet len (0 => sawtooth, max 1800) */ | |
| 714 | −extern uint brcmf_pktgen_len; | |
| 715 | −#define BRCMF_MAX_PKTGEN_LEN 1800 | |
| 716 | −#endif | |
| 717 | − | |
| 718 | −extern const struct bcmevent_name bcmevent_names[]; | |
| 719 | −extern const int bcmevent_names_size; | |
| 720 | − | |
| 721 | − | |
| 722 | −static inline void MUTEX_LOCK_INIT(struct brcmf_pub *drvr) | |
| 723 | −{ | |
| 724 | −} | |
| 725 | − | |
| 726 | −static inline void MUTEX_LOCK(struct brcmf_pub *drvr) | |
| 727 | −{ | |
| 728 | −} | |
| 729 | − | |
| 730 | −static inline void MUTEX_UNLOCK(struct brcmf_pub *drvr) | |
| 731 | −{ | |
| 732 | −} | |
| 733 | − | |
| 734 | −static inline void MUTEX_LOCK_SOFTAP_SET_INIT(struct brcmf_pub *drvr) | |
| 735 | −{ | |
| 736 | −} | |
| 737 | − | |
| 738 | −static inline void MUTEX_LOCK_SOFTAP_SET(struct brcmf_pub *drvr) | |
| 739 | −{ | |
| 740 | −} | |
| 741 | − | |
| 742 | −static inline void MUTEX_UNLOCK_SOFTAP_SET(struct brcmf_pub *drvr) | |
| 743 | −{ | |
| 744 | −} | |
| 745 | − | |
| 746 | −static inline void MUTEX_LOCK_WL_SCAN_SET_INIT(void) | |
| 747 | −{ | |
| 748 | −} | |
| 749 | − | |
| 750 | −static inline void MUTEX_LOCK_WL_SCAN_SET(void) | |
| 751 | −{ | |
| 752 | −} | |
| 753 | − | |
| 754 | −static inline void MUTEX_UNLOCK_WL_SCAN_SET(void) | |
| 755 | −{ | |
| 756 | −} | |
| 757 | − | |
| 758 | −/* Indication from bus module regarding presence/insertion of dongle. | |
| 759 | − * Return struct brcmf_pub pointer, used as handle to OS module in later calls. | |
| 760 | − * Returned structure should have bus and prot pointers filled in. | |
| 761 | − * bus_hdrlen specifies required headroom for bus module header. | |
| 762 | − */ | |
| 763 | −extern struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, | |
| 764 | − uint bus_hdrlen); | |
| 765 | −extern int brcmf_net_attach(struct brcmf_pub *drvr, int idx); | |
| 766 | −extern int brcmf_netdev_wait_pend8021x(struct net_device *dev); | |
| 767 | − | |
| 768 | −/* Indication from bus module regarding removal/absence of dongle */ | |
| 769 | −extern void brcmf_detach(struct brcmf_pub *drvr); | |
| 770 | − | |
| 771 | −/* Indication from bus module to change flow-control state */ | |
| 772 | −extern void brcmf_txflowcontrol(struct brcmf_pub *drvr, int ifidx, bool on); | |
| 773 | − | |
| 774 | −extern bool brcmf_c_prec_enq(struct brcmf_pub *drvr, struct pktq *q, | |
| 775 | − struct sk_buff *pkt, int prec); | |
| 776 | − | |
| 777 | −/* Receive frame for delivery to OS. Callee disposes of rxp. */ | |
| 778 | −extern void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, | |
| 779 | − struct sk_buff *rxp, int numpkt); | |
| 780 | − | |
| 781 | −/* Return pointer to interface name */ | |
| 782 | −extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx); | |
| 783 | − | |
| 784 | −/* Notify tx completion */ | |
| 785 | −extern void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp, | |
| 786 | − bool success); | |
| 787 | − | |
| 788 | −/* Query ioctl */ | |
| 789 | −extern int brcmf_proto_cdc_query_ioctl(struct brcmf_pub *drvr, int ifidx, | |
| 790 | − uint cmd, void *buf, uint len); | |
| 791 | − | |
| 792 | −/* OS independent layer functions */ | |
| 793 | −extern int brcmf_os_proto_block(struct brcmf_pub *drvr); | |
| 794 | −extern int brcmf_os_proto_unblock(struct brcmf_pub *drvr); | |
| 795 | −extern int brcmf_os_ioctl_resp_wait(struct brcmf_pub *drvr, uint *condition, | |
| 796 | − bool *pending); | |
| 797 | −extern int brcmf_os_ioctl_resp_wake(struct brcmf_pub *drvr); | |
| 798 | −extern unsigned int brcmf_os_get_ioctl_resp_timeout(void); | |
| 799 | −extern void brcmf_os_set_ioctl_resp_timeout(unsigned int timeout_msec); | |
| 800 | −#ifdef BCMDBG | |
| 801 | −extern int brcmf_write_to_file(struct brcmf_pub *drvr, u8 *buf, int size); | |
| 802 | −#endif /* BCMDBG */ | |
| 803 | − | |
| 804 | −extern void brcmf_timeout_start(struct brcmf_timeout *tmo, uint usec); | |
| 805 | −extern int brcmf_timeout_expired(struct brcmf_timeout *tmo); | |
| 806 | − | |
| 807 | −extern int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name); | |
| 808 | −extern int brcmf_c_host_event(struct brcmf_info *drvr_priv, int *idx, | |
| 809 | − void *pktdata, struct brcmf_event_msg *, | |
| 810 | − void **data_ptr); | |
| 811 | − | |
| 812 | −extern void brcmf_c_init(void); | |
| 813 | − | |
| 814 | −extern int brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, void *handle, | |
| 815 | − char *name, u8 *mac_addr, u32 flags, u8 bssidx); | |
| 816 | −extern void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx); | |
| 817 | − | |
| 818 | −/* Send packet to dongle via data channel */ | |
| 819 | −extern int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx,\ | |
| 820 | − struct sk_buff *pkt); | |
| 821 | − | |
| 822 | −extern int brcmf_bus_devreset(struct brcmf_pub *drvr, u8 flag); | |
| 823 | −extern int brcmf_bus_start(struct brcmf_pub *drvr); | |
| 824 | − | |
| 825 | −extern void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg); | |
| 826 | −extern void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, | |
| 827 | − int enable, int master_mode); | |
| 828 | − | |
| 829 | −/* Linux network driver ioctl encoding */ | |
| 830 | −struct brcmf_c_ioctl { | |
| 831 | − uint cmd; /* common ioctl definition */ | |
| 832 | − void *buf; /* pointer to user buffer */ | |
| 833 | − uint len; /* length of user buffer */ | |
| 834 | − bool set; /* get or set request (optional) */ | |
| 835 | − uint used; /* bytes read or written (optional) */ | |
| 836 | − uint needed; /* bytes needed (optional) */ | |
| 837 | − uint driver; /* to identify target driver */ | |
| 838 | −}; | |
| 839 | − | |
| 840 | −/* per-driver magic numbers */ | |
| 841 | −#define BRCMF_IOCTL_MAGIC 0x00444944 | |
| 842 | − | |
| 843 | −/* bump this number if you change the ioctl interface */ | |
| 844 | −#define BRCMF_IOCTL_VERSION 1 | |
| 845 | −#define BRCMF_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */ | |
| 846 | − | |
| 847 | −/* common ioctl definitions */ | |
| 848 | −#define BRCMF_GET_MAGIC 0 | |
| 849 | −#define BRCMF_GET_VERSION 1 | |
| 850 | −#define BRCMF_GET_VAR 2 | |
| 851 | −#define BRCMF_SET_VAR 3 | |
| 852 | − | |
| 853 | −/* message levels */ | |
| 854 | −#define BRCMF_ERROR_VAL 0x0001 | |
| 855 | −#define BRCMF_TRACE_VAL 0x0002 | |
| 856 | −#define BRCMF_INFO_VAL 0x0004 | |
| 857 | −#define BRCMF_DATA_VAL 0x0008 | |
| 858 | −#define BRCMF_CTL_VAL 0x0010 | |
| 859 | −#define BRCMF_TIMER_VAL 0x0020 | |
| 860 | −#define BRCMF_HDRS_VAL 0x0040 | |
| 861 | −#define BRCMF_BYTES_VAL 0x0080 | |
| 862 | −#define BRCMF_INTR_VAL 0x0100 | |
| 863 | −#define BRCMF_GLOM_VAL 0x0400 | |
| 864 | −#define BRCMF_EVENT_VAL 0x0800 | |
| 865 | −#define BRCMF_BTA_VAL 0x1000 | |
| 866 | −#define BRCMF_ISCAN_VAL 0x2000 | |
| 867 | − | |
| 868 | −#ifdef SDTEST | |
| 869 | −/* For pktgen iovar */ | |
| 870 | −struct brcmf_pktgen { | |
| 871 | − uint version; /* To allow structure change tracking */ | |
| 872 | − uint freq; /* Max ticks between tx/rx attempts */ | |
| 873 | − uint count; /* Test packets to send/rcv each attempt */ | |
| 874 | − uint print; /* Print counts every <print> attempts */ | |
| 875 | − uint total; /* Total packets (or bursts) */ | |
| 876 | − uint minlen; /* Minimum length of packets to send */ | |
| 877 | − uint maxlen; /* Maximum length of packets to send */ | |
| 878 | − uint numsent; /* Count of test packets sent */ | |
| 879 | − uint numrcvd; /* Count of test packets received */ | |
| 880 | − uint numfail; /* Count of test send failures */ | |
| 881 | − uint mode; /* Test mode (type of test packets) */ | |
| 882 | − uint stop; /* Stop after this many tx failures */ | |
| 883 | −}; | |
| 884 | − | |
| 885 | −/* Version in case structure changes */ | |
| 886 | −#define BRCMF_PKTGEN_VERSION 2 | |
| 887 | − | |
| 888 | −/* Type of test packets to use */ | |
| 889 | −#define BRCMF_PKTGEN_ECHO 1 /* Send echo requests */ | |
| 890 | −#define BRCMF_PKTGEN_SEND 2 /* Send discard packets */ | |
| 891 | −#define BRCMF_PKTGEN_RXBURST 3 /* Request dongle send N packets */ | |
| 892 | −#define BRCMF_PKTGEN_RECV 4 /* Continuous rx from continuous | |
| 893 | − tx dongle */ | |
| 894 | −#endif /* SDTEST */ | |
| 895 | − | |
| 896 | −/* Enter idle immediately (no timeout) */ | |
| 897 | −#define BRCMF_IDLE_IMMEDIATE (-1) | |
| 898 | − | |
| 899 | −/* Values for idleclock iovar: other values are the sd_divisor to use | |
| 900 | − when idle */ | |
| 901 | −#define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change | |
| 902 | − when idle */ | |
| 903 | − | |
| 904 | −#endif /* _BRCMF_H_ */ | |
| @@ -1,78 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * Copyright (c) 2010 Broadcom Corporation | |
| 3 | − * | |
| 4 | − * Permission to use, copy, modify, and/or distribute this software for any | |
| 5 | − * purpose with or without fee is hereby granted, provided that the above | |
| 6 | − * copyright notice and this permission notice appear in all copies. | |
| 7 | − * | |
| 8 | − * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
| 9 | − * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
| 10 | − * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
| 11 | − * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 12 | − * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | |
| 13 | − * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
| 14 | − * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
| 15 | − */ | |
| 16 | − | |
| 17 | −#ifndef _BRCMF_BUS_H_ | |
| 18 | −#define _BRCMF_BUS_H_ | |
| 19 | − | |
| 20 | −/* Packet alignment for most efficient SDIO (can change based on platform) */ | |
| 21 | −#ifndef BRCMF_SDALIGN | |
| 22 | −#define BRCMF_SDALIGN 32 | |
| 23 | −#endif | |
| 24 | −#if !ISPOWEROF2(BRCMF_SDALIGN) | |
| 25 | −#error BRCMF_SDALIGN is not a power of 2! | |
| 26 | −#endif | |
| 27 | − | |
| 28 | −/* | |
| 29 | − * Exported from brcmf bus module (brcmf_usb, brcmf_sdio) | |
| 30 | − */ | |
| 31 | − | |
| 32 | −/* dongle ram module parameter */ | |
| 33 | −extern int brcmf_dongle_memsize; | |
| 34 | − | |
| 35 | −/* Tx/Rx bounds module parameters */ | |
| 36 | −extern uint brcmf_txbound; | |
| 37 | −extern uint brcmf_rxbound; | |
| 38 | − | |
| 39 | −/* Watchdog timer interval */ | |
| 40 | −extern uint brcmf_watchdog_ms; | |
| 41 | − | |
| 42 | −/* Indicate (dis)interest in finding dongles. */ | |
| 43 | −extern int brcmf_bus_register(void); | |
| 44 | −extern void brcmf_bus_unregister(void); | |
| 45 | − | |
| 46 | −/* Stop bus module: clear pending frames, disable data flow */ | |
| 47 | −extern void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus, bool enforce_mutex); | |
| 48 | − | |
| 49 | −/* Initialize bus module: prepare for communication w/dongle */ | |
| 50 | −extern int brcmf_sdbrcm_bus_init(struct brcmf_pub *drvr, bool enforce_mutex); | |
| 51 | − | |
| 52 | −/* Send a data frame to the dongle. Callee disposes of txp. */ | |
| 53 | −extern int brcmf_sdbrcm_bus_txdata(struct brcmf_bus *bus, struct sk_buff *txp); | |
| 54 | − | |
| 55 | −/* Send/receive a control message to/from the dongle. | |
| 56 | − * Expects caller to enforce a single outstanding transaction. | |
| 57 | − */ | |
| 58 | −extern int | |
| 59 | −brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen); | |
| 60 | − | |
| 61 | −extern int | |
| 62 | −brcmf_sdbrcm_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen); | |
| 63 | − | |
| 64 | −/* Check for and handle local prot-specific iovar commands */ | |
| 65 | −extern int brcmf_sdbrcm_bus_iovar_op(struct brcmf_pub *drvr, const char *name, | |
| 66 | − void *params, int plen, void *arg, int len, | |
| 67 | − bool set); | |
| 68 | − | |
| 69 | −/* Add bus dump output to a buffer */ | |
| 70 | −extern void brcmf_sdbrcm_bus_dump(struct brcmf_pub *drvr, | |
| 71 | − struct brcmu_strbuf *strbuf); | |
| 72 | − | |
| 73 | −/* Clear any bus counters */ | |
| 74 | −extern void brcmf_bus_clearcounts(struct brcmf_pub *drvr); | |
| 75 | − | |
| 76 | −extern void brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick); | |
| 77 | − | |
| 78 | −#endif /* _BRCMF_BUS_H_ */ | |
| @@ -1,502 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * Copyright (c) 2010 Broadcom Corporation | |
| 3 | − * | |
| 4 | − * Permission to use, copy, modify, and/or distribute this software for any | |
| 5 | − * purpose with or without fee is hereby granted, provided that the above | |
| 6 | − * copyright notice and this permission notice appear in all copies. | |
| 7 | − * | |
| 8 | − * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
| 9 | − * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
| 10 | − * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
| 11 | − * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 12 | − * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | |
| 13 | − * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
| 14 | − * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
| 15 | − */ | |
| 16 | − | |
| 17 | −#include <linux/types.h> | |
| 18 | −#include <linux/netdevice.h> | |
| 19 | −#include <linux/sched.h> | |
| 20 | −#include <defs.h> | |
| 21 | − | |
| 22 | −#include <brcmu_utils.h> | |
| 23 | −#include <brcmu_wifi.h> | |
| 24 | − | |
| 25 | −#include "dhd.h" | |
| 26 | −#include "dhd_proto.h" | |
| 27 | −#include "dhd_bus.h" | |
| 28 | −#include "dhd_dbg.h" | |
| 29 | − | |
| 30 | −struct brcmf_proto_cdc_ioctl { | |
| 31 | − u32 cmd; /* ioctl command value */ | |
| 32 | − u32 len; /* lower 16: output buflen; | |
| 33 | − * upper 16: input buflen (excludes header) */ | |
| 34 | − u32 flags; /* flag defns given below */ | |
| 35 | − u32 status; /* status code returned from the device */ | |
| 36 | −}; | |
| 37 | − | |
| 38 | −/* Max valid buffer size that can be sent to the dongle */ | |
| 39 | −#define CDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN) | |
| 40 | − | |
| 41 | −/* CDC flag definitions */ | |
| 42 | −#define CDCF_IOC_ERROR 0x01 /* 1=ioctl cmd failed */ | |
| 43 | −#define CDCF_IOC_SET 0x02 /* 0=get, 1=set cmd */ | |
| 44 | −#define CDCF_IOC_IF_MASK 0xF000 /* I/F index */ | |
| 45 | −#define CDCF_IOC_IF_SHIFT 12 | |
| 46 | −#define CDCF_IOC_ID_MASK 0xFFFF0000 /* id an ioctl pairing */ | |
| 47 | −#define CDCF_IOC_ID_SHIFT 16 /* ID Mask shift bits */ | |
| 48 | −#define CDC_IOC_ID(flags) \ | |
| 49 | − (((flags) & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT) | |
| 50 | −#define CDC_SET_IF_IDX(hdr, idx) \ | |
| 51 | − ((hdr)->flags = (((hdr)->flags & ~CDCF_IOC_IF_MASK) | \ | |
| 52 | − ((idx) << CDCF_IOC_IF_SHIFT))) | |
| 53 | − | |
| 54 | −/* | |
| 55 | − * BDC header - Broadcom specific extension of CDC. | |
| 56 | − * Used on data packets to convey priority across USB. | |
| 57 | − */ | |
| 58 | −#define BDC_HEADER_LEN 4 | |
| 59 | −#define BDC_PROTO_VER 1 /* Protocol version */ | |
| 60 | −#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */ | |
| 61 | −#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */ | |
| 62 | −#define BDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */ | |
| 63 | −#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */ | |
| 64 | −#define BDC_PRIORITY_MASK 0x7 | |
| 65 | −#define BDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */ | |
| 66 | −#define BDC_FLAG2_IF_SHIFT 0 | |
| 67 | − | |
| 68 | −#define BDC_GET_IF_IDX(hdr) \ | |
| 69 | − ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT)) | |
| 70 | −#define BDC_SET_IF_IDX(hdr, idx) \ | |
| 71 | − ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \ | |
| 72 | − ((idx) << BDC_FLAG2_IF_SHIFT))) | |
| 73 | − | |
| 74 | −struct brcmf_proto_bdc_header { | |
| 75 | − u8 flags; | |
| 76 | − u8 priority; /* 802.1d Priority, 4:7 flow control info for usb */ | |
| 77 | − u8 flags2; | |
| 78 | − u8 rssi; | |
| 79 | −}; | |
| 80 | − | |
| 81 | − | |
| 82 | −#define RETRIES 2 /* # of retries to retrieve matching ioctl response */ | |
| 83 | −#define BUS_HEADER_LEN (16+BRCMF_SDALIGN) /* Must be atleast SDPCM_RESERVE | |
| 84 | − * (amount of header tha might be added) | |
| 85 | − * plus any space that might be needed | |
| 86 | − * for alignment padding. | |
| 87 | − */ | |
| 88 | −#define ROUND_UP_MARGIN 2048 /* Biggest SDIO block size possible for | |
| 89 | − * round off at the end of buffer | |
| 90 | − */ | |
| 91 | − | |
| 92 | −struct brcmf_proto { | |
| 93 | − u16 reqid; | |
| 94 | − u8 pending; | |
| 95 | − u32 lastcmd; | |
| 96 | − u8 bus_header[BUS_HEADER_LEN]; | |
| 97 | − struct brcmf_proto_cdc_ioctl msg; | |
| 98 | − unsigned char buf[BRCMF_C_IOCTL_MAXLEN + ROUND_UP_MARGIN]; | |
| 99 | −}; | |
| 100 | − | |
| 101 | −static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr) | |
| 102 | −{ | |
| 103 | − struct brcmf_proto *prot = drvr->prot; | |
| 104 | − int len = le32_to_cpu(prot->msg.len) + | |
| 105 | − sizeof(struct brcmf_proto_cdc_ioctl); | |
| 106 | − | |
| 107 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 108 | − | |
| 109 | − /* NOTE : cdc->msg.len holds the desired length of the buffer to be | |
| 110 | − * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area | |
| 111 | − * is actually sent to the dongle | |
| 112 | − */ | |
| 113 | − if (len > CDC_MAX_MSG_SIZE) | |
| 114 | − len = CDC_MAX_MSG_SIZE; | |
| 115 | − | |
| 116 | − /* Send request */ | |
| 117 | − return brcmf_sdbrcm_bus_txctl(drvr->bus, (unsigned char *)&prot->msg, | |
| 118 | − len); | |
| 119 | −} | |
| 120 | − | |
| 121 | −static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len) | |
| 122 | −{ | |
| 123 | − int ret; | |
| 124 | − struct brcmf_proto *prot = drvr->prot; | |
| 125 | − | |
| 126 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 127 | − | |
| 128 | − do { | |
| 129 | − ret = brcmf_sdbrcm_bus_rxctl(drvr->bus, | |
| 130 | − (unsigned char *)&prot->msg, | |
| 131 | − len + sizeof(struct brcmf_proto_cdc_ioctl)); | |
| 132 | − if (ret < 0) | |
| 133 | − break; | |
| 134 | − } while (CDC_IOC_ID(le32_to_cpu(prot->msg.flags)) != id); | |
| 135 | − | |
| 136 | − return ret; | |
| 137 | −} | |
| 138 | − | |
| 139 | −int | |
| 140 | −brcmf_proto_cdc_query_ioctl(struct brcmf_pub *drvr, int ifidx, uint cmd, | |
| 141 | − void *buf, uint len) | |
| 142 | −{ | |
| 143 | − struct brcmf_proto *prot = drvr->prot; | |
| 144 | − struct brcmf_proto_cdc_ioctl *msg = &prot->msg; | |
| 145 | − void *info; | |
| 146 | − int ret = 0, retries = 0; | |
| 147 | − u32 id, flags = 0; | |
| 148 | − | |
| 149 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 150 | − BRCMF_CTL(("%s: cmd %d len %d\n", __func__, cmd, len)); | |
| 151 | − | |
| 152 | − /* Respond "bcmerror" and "bcmerrorstr" with local cache */ | |
| 153 | − if (cmd == BRCMF_C_GET_VAR && buf) { | |
| 154 | − if (!strcmp((char *)buf, "bcmerrorstr")) { | |
| 155 | − strncpy((char *)buf, "bcm_error", | |
| 156 | − BCME_STRLEN); | |
| 157 | − goto done; | |
| 158 | − } else if (!strcmp((char *)buf, "bcmerror")) { | |
| 159 | − *(int *)buf = drvr->dongle_error; | |
| 160 | − goto done; | |
| 161 | − } | |
| 162 | − } | |
| 163 | − | |
| 164 | − memset(msg, 0, sizeof(struct brcmf_proto_cdc_ioctl)); | |
| 165 | − | |
| 166 | − msg->cmd = cpu_to_le32(cmd); | |
| 167 | − msg->len = cpu_to_le32(len); | |
| 168 | − msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT); | |
| 169 | − CDC_SET_IF_IDX(msg, ifidx); | |
| 170 | − msg->flags = cpu_to_le32(msg->flags); | |
| 171 | − | |
| 172 | − if (buf) | |
| 173 | − memcpy(prot->buf, buf, len); | |
| 174 | − | |
| 175 | − ret = brcmf_proto_cdc_msg(drvr); | |
| 176 | − if (ret < 0) { | |
| 177 | − BRCMF_ERROR(("brcmf_proto_cdc_query_ioctl: brcmf_proto_cdc_msg " | |
| 178 | − "failed w/status %d\n", ret)); | |
| 179 | − goto done; | |
| 180 | − } | |
| 181 | − | |
| 182 | −retry: | |
| 183 | − /* wait for interrupt and get first fragment */ | |
| 184 | − ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len); | |
| 185 | − if (ret < 0) | |
| 186 | − goto done; | |
| 187 | − | |
| 188 | − flags = le32_to_cpu(msg->flags); | |
| 189 | − id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT; | |
| 190 | − | |
| 191 | − if ((id < prot->reqid) && (++retries < RETRIES)) | |
| 192 | − goto retry; | |
| 193 | − if (id != prot->reqid) { | |
| 194 | − BRCMF_ERROR(("%s: %s: unexpected request id %d (expected %d)\n", | |
| 195 | − brcmf_ifname(drvr, ifidx), __func__, id, | |
| 196 | − prot->reqid)); | |
| 197 | − ret = -EINVAL; | |
| 198 | − goto done; | |
| 199 | − } | |
| 200 | − | |
| 201 | − /* Check info buffer */ | |
| 202 | − info = (void *)&msg[1]; | |
| 203 | − | |
| 204 | − /* Copy info buffer */ | |
| 205 | − if (buf) { | |
| 206 | − if (ret < (int)len) | |
| 207 | − len = ret; | |
| 208 | − memcpy(buf, info, len); | |
| 209 | − } | |
| 210 | − | |
| 211 | − /* Check the ERROR flag */ | |
| 212 | − if (flags & CDCF_IOC_ERROR) { | |
| 213 | − ret = le32_to_cpu(msg->status); | |
| 214 | − /* Cache error from dongle */ | |
| 215 | − drvr->dongle_error = ret; | |
| 216 | − } | |
| 217 | − | |
| 218 | −done: | |
| 219 | − return ret; | |
| 220 | −} | |
| 221 | − | |
| 222 | −int brcmf_proto_cdc_set_ioctl(struct brcmf_pub *drvr, int ifidx, uint cmd, | |
| 223 | − void *buf, uint len) | |
| 224 | −{ | |
| 225 | − struct brcmf_proto *prot = drvr->prot; | |
| 226 | − struct brcmf_proto_cdc_ioctl *msg = &prot->msg; | |
| 227 | − int ret = 0; | |
| 228 | − u32 flags, id; | |
| 229 | − | |
| 230 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 231 | − BRCMF_CTL(("%s: cmd %d len %d\n", __func__, cmd, len)); | |
| 232 | − | |
| 233 | − memset(msg, 0, sizeof(struct brcmf_proto_cdc_ioctl)); | |
| 234 | − | |
| 235 | − msg->cmd = cpu_to_le32(cmd); | |
| 236 | − msg->len = cpu_to_le32(len); | |
| 237 | − msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT) | CDCF_IOC_SET; | |
| 238 | − CDC_SET_IF_IDX(msg, ifidx); | |
| 239 | − msg->flags = cpu_to_le32(msg->flags); | |
| 240 | − | |
| 241 | − if (buf) | |
| 242 | − memcpy(prot->buf, buf, len); | |
| 243 | − | |
| 244 | − ret = brcmf_proto_cdc_msg(drvr); | |
| 245 | − if (ret < 0) | |
| 246 | − goto done; | |
| 247 | − | |
| 248 | − ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len); | |
| 249 | − if (ret < 0) | |
| 250 | − goto done; | |
| 251 | − | |
| 252 | − flags = le32_to_cpu(msg->flags); | |
| 253 | − id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT; | |
| 254 | − | |
| 255 | − if (id != prot->reqid) { | |
| 256 | − BRCMF_ERROR(("%s: %s: unexpected request id %d (expected %d)\n", | |
| 257 | − brcmf_ifname(drvr, ifidx), __func__, id, | |
| 258 | − prot->reqid)); | |
| 259 | − ret = -EINVAL; | |
| 260 | − goto done; | |
| 261 | − } | |
| 262 | − | |
| 263 | − /* Check the ERROR flag */ | |
| 264 | − if (flags & CDCF_IOC_ERROR) { | |
| 265 | − ret = le32_to_cpu(msg->status); | |
| 266 | − /* Cache error from dongle */ | |
| 267 | − drvr->dongle_error = ret; | |
| 268 | − } | |
| 269 | − | |
| 270 | −done: | |
| 271 | − return ret; | |
| 272 | −} | |
| 273 | − | |
| 274 | −int | |
| 275 | −brcmf_proto_ioctl(struct brcmf_pub *drvr, int ifidx, struct brcmf_ioctl *ioc, | |
| 276 | − void *buf, int len) | |
| 277 | −{ | |
| 278 | − struct brcmf_proto *prot = drvr->prot; | |
| 279 | − int ret = -1; | |
| 280 | − | |
| 281 | − if (drvr->busstate == BRCMF_BUS_DOWN) { | |
| 282 | − BRCMF_ERROR(("%s : bus is down. we have nothing to do\n", | |
| 283 | − __func__)); | |
| 284 | − return ret; | |
| 285 | − } | |
| 286 | − brcmf_os_proto_block(drvr); | |
| 287 | − | |
| 288 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 289 | − | |
| 290 | − if (len > BRCMF_C_IOCTL_MAXLEN) | |
| 291 | − goto done; | |
| 292 | − | |
| 293 | − if (prot->pending == true) { | |
| 294 | − BRCMF_TRACE(("CDC packet is pending!!!! cmd=0x%x (%lu) " | |
| 295 | − "lastcmd=0x%x (%lu)\n", | |
| 296 | − ioc->cmd, (unsigned long)ioc->cmd, prot->lastcmd, | |
| 297 | − (unsigned long)prot->lastcmd)); | |
| 298 | − if ((ioc->cmd == BRCMF_C_SET_VAR) || | |
| 299 | − (ioc->cmd == BRCMF_C_GET_VAR)) | |
| 300 | − BRCMF_TRACE(("iovar cmd=%s\n", (char *)buf)); | |
| 301 | − | |
| 302 | − goto done; | |
| 303 | − } | |
| 304 | − | |
| 305 | − prot->pending = true; | |
| 306 | − prot->lastcmd = ioc->cmd; | |
| 307 | − if (ioc->set) | |
| 308 | − ret = brcmf_proto_cdc_set_ioctl(drvr, ifidx, ioc->cmd, | |
| 309 | − buf, len); | |
| 310 | − else { | |
| 311 | − ret = brcmf_proto_cdc_query_ioctl(drvr, ifidx, ioc->cmd, | |
| 312 | − buf, len); | |
| 313 | − if (ret > 0) | |
| 314 | − ioc->used = ret - sizeof(struct brcmf_proto_cdc_ioctl); | |
| 315 | − } | |
| 316 | − | |
| 317 | − /* Too many programs assume ioctl() returns 0 on success */ | |
| 318 | − if (ret >= 0) | |
| 319 | − ret = 0; | |
| 320 | − else { | |
| 321 | − struct brcmf_proto_cdc_ioctl *msg = &prot->msg; | |
| 322 | − /* len == needed when set/query fails from dongle */ | |
| 323 | − ioc->needed = le32_to_cpu(msg->len); | |
| 324 | − } | |
| 325 | − | |
| 326 | − /* Intercept the wme_dp ioctl here */ | |
| 327 | − if (!ret && ioc->cmd == BRCMF_C_SET_VAR && | |
| 328 | − !strcmp(buf, "wme_dp")) { | |
| 329 | − int slen, val = 0; | |
| 330 | − | |
| 331 | − slen = strlen("wme_dp") + 1; | |
| 332 | − if (len >= (int)(slen + sizeof(int))) | |
| 333 | − memcpy(&val, (char *)buf + slen, sizeof(int)); | |
| 334 | − drvr->wme_dp = (u8) le32_to_cpu(val); | |
| 335 | − } | |
| 336 | − | |
| 337 | − prot->pending = false; | |
| 338 | − | |
| 339 | −done: | |
| 340 | − brcmf_os_proto_unblock(drvr); | |
| 341 | − | |
| 342 | − return ret; | |
| 343 | −} | |
| 344 | − | |
| 345 | −#define PKTSUMNEEDED(skb) \ | |
| 346 | − (((struct sk_buff *)(skb))->ip_summed == CHECKSUM_PARTIAL) | |
| 347 | −#define PKTSETSUMGOOD(skb, x) \ | |
| 348 | − (((struct sk_buff *)(skb))->ip_summed = \ | |
| 349 | − ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE)) | |
| 350 | − | |
| 351 | −void brcmf_proto_dump(struct brcmf_pub *drvr, struct brcmu_strbuf *strbuf) | |
| 352 | −{ | |
| 353 | − brcmu_bprintf(strbuf, "Protocol CDC: reqid %d\n", drvr->prot->reqid); | |
| 354 | −} | |
| 355 | − | |
| 356 | −void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, | |
| 357 | − struct sk_buff *pktbuf) | |
| 358 | −{ | |
| 359 | − struct brcmf_proto_bdc_header *h; | |
| 360 | − | |
| 361 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 362 | − | |
| 363 | − /* Push BDC header used to convey priority for buses that don't */ | |
| 364 | − | |
| 365 | − skb_push(pktbuf, BDC_HEADER_LEN); | |
| 366 | − | |
| 367 | − h = (struct brcmf_proto_bdc_header *)(pktbuf->data); | |
| 368 | − | |
| 369 | − h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); | |
| 370 | − if (PKTSUMNEEDED(pktbuf)) | |
| 371 | − h->flags |= BDC_FLAG_SUM_NEEDED; | |
| 372 | − | |
| 373 | − h->priority = (pktbuf->priority & BDC_PRIORITY_MASK); | |
| 374 | − h->flags2 = 0; | |
| 375 | − h->rssi = 0; | |
| 376 | − BDC_SET_IF_IDX(h, ifidx); | |
| 377 | −} | |
| 378 | − | |
| 379 | −int brcmf_proto_hdrpull(struct brcmf_pub *drvr, int *ifidx, | |
| 380 | − struct sk_buff *pktbuf) | |
| 381 | −{ | |
| 382 | − struct brcmf_proto_bdc_header *h; | |
| 383 | − | |
| 384 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 385 | − | |
| 386 | − /* Pop BDC header used to convey priority for buses that don't */ | |
| 387 | − | |
| 388 | − if (pktbuf->len < BDC_HEADER_LEN) { | |
| 389 | − BRCMF_ERROR(("%s: rx data too short (%d < %d)\n", __func__, | |
| 390 | − pktbuf->len, BDC_HEADER_LEN)); | |
| 391 | − return -EBADE; | |
| 392 | − } | |
| 393 | − | |
| 394 | − h = (struct brcmf_proto_bdc_header *)(pktbuf->data); | |
| 395 | − | |
| 396 | − *ifidx = BDC_GET_IF_IDX(h); | |
| 397 | − if (*ifidx >= BRCMF_MAX_IFS) { | |
| 398 | − BRCMF_ERROR(("%s: rx data ifnum out of range (%d)\n", | |
| 399 | − __func__, *ifidx)); | |
| 400 | − return -EBADE; | |
| 401 | − } | |
| 402 | − | |
| 403 | − if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != | |
| 404 | − BDC_PROTO_VER) { | |
| 405 | − BRCMF_ERROR(("%s: non-BDC packet received, flags 0x%x\n", | |
| 406 | − brcmf_ifname(drvr, *ifidx), h->flags)); | |
| 407 | − return -EBADE; | |
| 408 | − } | |
| 409 | − | |
| 410 | − if (h->flags & BDC_FLAG_SUM_GOOD) { | |
| 411 | − BRCMF_INFO(("%s: BDC packet received with good rx-csum, " | |
| 412 | − "flags 0x%x\n", | |
| 413 | − brcmf_ifname(drvr, *ifidx), h->flags)); | |
| 414 | − PKTSETSUMGOOD(pktbuf, true); | |
| 415 | − } | |
| 416 | − | |
| 417 | − pktbuf->priority = h->priority & BDC_PRIORITY_MASK; | |
| 418 | − | |
| 419 | − skb_pull(pktbuf, BDC_HEADER_LEN); | |
| 420 | − | |
| 421 | − return 0; | |
| 422 | −} | |
| 423 | − | |
| 424 | −int brcmf_proto_attach(struct brcmf_pub *drvr) | |
| 425 | −{ | |
| 426 | − struct brcmf_proto *cdc; | |
| 427 | − | |
| 428 | − cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC); | |
| 429 | − if (!cdc) { | |
| 430 | − BRCMF_ERROR(("%s: kmalloc failed\n", __func__)); | |
| 431 | − goto fail; | |
| 432 | − } | |
| 433 | − | |
| 434 | − /* ensure that the msg buf directly follows the cdc msg struct */ | |
| 435 | − if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) { | |
| 436 | − BRCMF_ERROR(("struct brcmf_proto is not correctly defined\n")); | |
| 437 | − goto fail; | |
| 438 | − } | |
| 439 | − | |
| 440 | − drvr->prot = cdc; | |
| 441 | − drvr->hdrlen += BDC_HEADER_LEN; | |
| 442 | − drvr->maxctl = BRCMF_C_IOCTL_MAXLEN + | |
| 443 | − sizeof(struct brcmf_proto_cdc_ioctl) + ROUND_UP_MARGIN; | |
| 444 | − return 0; | |
| 445 | − | |
| 446 | −fail: | |
| 447 | − kfree(cdc); | |
| 448 | − return -ENOMEM; | |
| 449 | −} | |
| 450 | − | |
| 451 | −/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */ | |
| 452 | −void brcmf_proto_detach(struct brcmf_pub *drvr) | |
| 453 | −{ | |
| 454 | − kfree(drvr->prot); | |
| 455 | − drvr->prot = NULL; | |
| 456 | −} | |
| 457 | − | |
| 458 | −void brcmf_proto_dstats(struct brcmf_pub *drvr) | |
| 459 | −{ | |
| 460 | − /* No stats from dongle added yet, copy bus stats */ | |
| 461 | − drvr->dstats.tx_packets = drvr->tx_packets; | |
| 462 | − drvr->dstats.tx_errors = drvr->tx_errors; | |
| 463 | − drvr->dstats.rx_packets = drvr->rx_packets; | |
| 464 | − drvr->dstats.rx_errors = drvr->rx_errors; | |
| 465 | − drvr->dstats.rx_dropped = drvr->rx_dropped; | |
| 466 | − drvr->dstats.multicast = drvr->rx_multicast; | |
| 467 | − return; | |
| 468 | −} | |
| 469 | − | |
| 470 | −int brcmf_proto_init(struct brcmf_pub *drvr) | |
| 471 | −{ | |
| 472 | − int ret = 0; | |
| 473 | − char buf[128]; | |
| 474 | − | |
| 475 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 476 | − | |
| 477 | − brcmf_os_proto_block(drvr); | |
| 478 | − | |
| 479 | − /* Get the device MAC address */ | |
| 480 | − strcpy(buf, "cur_etheraddr"); | |
| 481 | − ret = brcmf_proto_cdc_query_ioctl(drvr, 0, BRCMF_C_GET_VAR, | |
| 482 | − buf, sizeof(buf)); | |
| 483 | − if (ret < 0) { | |
| 484 | − brcmf_os_proto_unblock(drvr); | |
| 485 | − return ret; | |
| 486 | − } | |
| 487 | − memcpy(drvr->mac, buf, ETH_ALEN); | |
| 488 | − | |
| 489 | − brcmf_os_proto_unblock(drvr); | |
| 490 | − | |
| 491 | − ret = brcmf_c_preinit_ioctls(drvr); | |
| 492 | − | |
| 493 | − /* Always assumes wl for now */ | |
| 494 | − drvr->iswl = true; | |
| 495 | − | |
| 496 | − return ret; | |
| 497 | −} | |
| 498 | − | |
| 499 | −void brcmf_proto_stop(struct brcmf_pub *drvr) | |
| 500 | −{ | |
| 501 | − /* Nothing to do for CDC */ | |
| 502 | −} | |
| @@ -1,1196 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * Copyright (c) 2010 Broadcom Corporation | |
| 3 | − * | |
| 4 | − * Permission to use, copy, modify, and/or distribute this software for any | |
| 5 | − * purpose with or without fee is hereby granted, provided that the above | |
| 6 | − * copyright notice and this permission notice appear in all copies. | |
| 7 | − * | |
| 8 | − * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
| 9 | − * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
| 10 | − * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
| 11 | − * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 12 | − * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | |
| 13 | − * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
| 14 | − * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
| 15 | − */ | |
| 16 | −#include <linux/kernel.h> | |
| 17 | −#include <linux/string.h> | |
| 18 | −#include <linux/sched.h> | |
| 19 | −#include <linux/netdevice.h> | |
| 20 | −#include <asm/unaligned.h> | |
| 21 | −#include <defs.h> | |
| 22 | −#include <brcmu_wifi.h> | |
| 23 | −#include <brcmu_utils.h> | |
| 24 | −#include "dhd.h" | |
| 25 | −#include "dhd_bus.h" | |
| 26 | −#include "dhd_proto.h" | |
| 27 | −#include "dhd_dbg.h" | |
| 28 | − | |
| 29 | −#define BRCM_OUI "\x00\x10\x18" | |
| 30 | −#define DOT11_OUI_LEN 3 | |
| 31 | −#define BCMILCP_BCM_SUBTYPE_EVENT 1 | |
| 32 | −#define PKTFILTER_BUF_SIZE 2048 | |
| 33 | − | |
| 34 | −int brcmf_msg_level; | |
| 35 | − | |
| 36 | −#define MSGTRACE_VERSION 1 | |
| 37 | − | |
| 38 | −#ifdef BCMDBG | |
| 39 | −const char brcmf_version[] = | |
| 40 | −"Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on " __DATE__ | |
| 41 | −" at " __TIME__; | |
| 42 | −#else | |
| 43 | −const char brcmf_version[] = "Dongle Host Driver, version " BRCMF_VERSION_STR; | |
| 44 | −#endif | |
| 45 | − | |
| 46 | −/* IOVar table */ | |
| 47 | −enum { | |
| 48 | − IOV_VERSION = 1, | |
| 49 | − IOV_MSGLEVEL, | |
| 50 | − IOV_BCMERRORSTR, | |
| 51 | − IOV_BCMERROR, | |
| 52 | − IOV_DUMP, | |
| 53 | − IOV_CLEARCOUNTS, | |
| 54 | − IOV_LOGDUMP, | |
| 55 | − IOV_LOGCAL, | |
| 56 | − IOV_LOGSTAMP, | |
| 57 | − IOV_GPIOOB, | |
| 58 | − IOV_IOCTLTIMEOUT, | |
| 59 | − IOV_LAST | |
| 60 | −}; | |
| 61 | − | |
| 62 | −const struct brcmu_iovar brcmf_iovars[] = { | |
| 63 | − {"version", IOV_VERSION, 0, IOVT_BUFFER, sizeof(brcmf_version)} | |
| 64 | − , | |
| 65 | −#ifdef BCMDBG | |
| 66 | − {"msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0} | |
| 67 | − , | |
| 68 | −#endif /* BCMDBG */ | |
| 69 | − {"bcmerrorstr", IOV_BCMERRORSTR, 0, IOVT_BUFFER, BCME_STRLEN} | |
| 70 | − , | |
| 71 | − {"bcmerror", IOV_BCMERROR, 0, IOVT_INT8, 0} | |
| 72 | − , | |
| 73 | − {"dump", IOV_DUMP, 0, IOVT_BUFFER, BRCMF_IOCTL_MAXLEN} | |
| 74 | − , | |
| 75 | − {"clearcounts", IOV_CLEARCOUNTS, 0, IOVT_VOID, 0} | |
| 76 | − , | |
| 77 | − {"gpioob", IOV_GPIOOB, 0, IOVT_UINT32, 0} | |
| 78 | − , | |
| 79 | − {"ioctl_timeout", IOV_IOCTLTIMEOUT, 0, IOVT_UINT32, 0} | |
| 80 | − , | |
| 81 | − {NULL, 0, 0, 0, 0} | |
| 82 | −}; | |
| 83 | − | |
| 84 | −/* Message trace header */ | |
| 85 | −struct msgtrace_hdr { | |
| 86 | − u8 version; | |
| 87 | − u8 spare; | |
| 88 | − u16 len; /* Len of the trace */ | |
| 89 | − u32 seqnum; /* Sequence number of message. Useful | |
| 90 | − * if the messsage has been lost | |
| 91 | − * because of DMA error or a bus reset | |
| 92 | − * (ex: SDIO Func2) | |
| 93 | − */ | |
| 94 | − u32 discarded_bytes; /* Number of discarded bytes because of | |
| 95 | − trace overflow */ | |
| 96 | − u32 discarded_printf; /* Number of discarded printf | |
| 97 | − because of trace overflow */ | |
| 98 | −} __packed; | |
| 99 | − | |
| 100 | −void brcmf_c_init(void) | |
| 101 | −{ | |
| 102 | − /* Init global variables at run-time, not as part of the declaration. | |
| 103 | − * This is required to support init/de-init of the driver. | |
| 104 | − * Initialization | |
| 105 | − * of globals as part of the declaration results in non-deterministic | |
| 106 | − * behaviour since the value of the globals may be different on the | |
| 107 | − * first time that the driver is initialized vs subsequent | |
| 108 | − * initializations. | |
| 109 | − */ | |
| 110 | − brcmf_msg_level = BRCMF_ERROR_VAL; | |
| 111 | −} | |
| 112 | − | |
| 113 | −static int brcmf_c_dump(struct brcmf_pub *drvr, char *buf, int buflen) | |
| 114 | −{ | |
| 115 | − struct brcmu_strbuf b; | |
| 116 | − struct brcmu_strbuf *strbuf = &b; | |
| 117 | − | |
| 118 | − brcmu_binit(strbuf, buf, buflen); | |
| 119 | − | |
| 120 | − /* Base info */ | |
| 121 | − brcmu_bprintf(strbuf, "%s\n", brcmf_version); | |
| 122 | − brcmu_bprintf(strbuf, "\n"); | |
| 123 | − brcmu_bprintf(strbuf, "pub.up %d pub.txoff %d pub.busstate %d\n", | |
| 124 | − drvr->up, drvr->txoff, drvr->busstate); | |
| 125 | − brcmu_bprintf(strbuf, "pub.hdrlen %d pub.maxctl %d pub.rxsz %d\n", | |
| 126 | − drvr->hdrlen, drvr->maxctl, drvr->rxsz); | |
| 127 | − brcmu_bprintf(strbuf, "pub.iswl %d pub.drv_version %ld pub.mac %pM\n", | |
| 128 | − drvr->iswl, drvr->drv_version, &drvr->mac); | |
| 129 | − brcmu_bprintf(strbuf, "pub.bcmerror %d tickcnt %d\n", drvr->bcmerror, | |
| 130 | − drvr->tickcnt); | |
| 131 | − | |
| 132 | − brcmu_bprintf(strbuf, "dongle stats:\n"); | |
| 133 | − brcmu_bprintf(strbuf, | |
| 134 | − "tx_packets %ld tx_bytes %ld tx_errors %ld tx_dropped %ld\n", | |
| 135 | − drvr->dstats.tx_packets, drvr->dstats.tx_bytes, | |
| 136 | − drvr->dstats.tx_errors, drvr->dstats.tx_dropped); | |
| 137 | − brcmu_bprintf(strbuf, | |
| 138 | − "rx_packets %ld rx_bytes %ld rx_errors %ld rx_dropped %ld\n", | |
| 139 | − drvr->dstats.rx_packets, drvr->dstats.rx_bytes, | |
| 140 | − drvr->dstats.rx_errors, drvr->dstats.rx_dropped); | |
| 141 | − brcmu_bprintf(strbuf, "multicast %ld\n", drvr->dstats.multicast); | |
| 142 | − | |
| 143 | − brcmu_bprintf(strbuf, "bus stats:\n"); | |
| 144 | − brcmu_bprintf(strbuf, "tx_packets %ld tx_multicast %ld tx_errors %ld\n", | |
| 145 | − drvr->tx_packets, drvr->tx_multicast, drvr->tx_errors); | |
| 146 | − brcmu_bprintf(strbuf, "tx_ctlpkts %ld tx_ctlerrs %ld\n", | |
| 147 | − drvr->tx_ctlpkts, drvr->tx_ctlerrs); | |
| 148 | − brcmu_bprintf(strbuf, "rx_packets %ld rx_multicast %ld rx_errors %ld\n", | |
| 149 | − drvr->rx_packets, drvr->rx_multicast, drvr->rx_errors); | |
| 150 | − brcmu_bprintf(strbuf, | |
| 151 | − "rx_ctlpkts %ld rx_ctlerrs %ld rx_dropped %ld rx_flushed %ld\n", | |
| 152 | − drvr->rx_ctlpkts, drvr->rx_ctlerrs, drvr->rx_dropped, | |
| 153 | − drvr->rx_flushed); | |
| 154 | − brcmu_bprintf(strbuf, | |
| 155 | − "rx_readahead_cnt %ld tx_realloc %ld fc_packets %ld\n", | |
| 156 | − drvr->rx_readahead_cnt, drvr->tx_realloc, drvr->fc_packets); | |
| 157 | − brcmu_bprintf(strbuf, "wd_dpc_sched %ld\n", drvr->wd_dpc_sched); | |
| 158 | − brcmu_bprintf(strbuf, "\n"); | |
| 159 | − | |
| 160 | − /* Add any prot info */ | |
| 161 | − brcmf_proto_dump(drvr, strbuf); | |
| 162 | − brcmu_bprintf(strbuf, "\n"); | |
| 163 | − | |
| 164 | − /* Add any bus info */ | |
| 165 | − brcmf_sdbrcm_bus_dump(drvr, strbuf); | |
| 166 | − | |
| 167 | − return !strbuf->size ? -EOVERFLOW : 0; | |
| 168 | −} | |
| 169 | − | |
| 170 | −static int | |
| 171 | −brcmf_c_doiovar(struct brcmf_pub *drvr, const struct brcmu_iovar *vi, | |
| 172 | − u32 actionid, const char *name, void *params, int plen, | |
| 173 | − void *arg, int len, int val_size) | |
| 174 | −{ | |
| 175 | − int bcmerror = 0; | |
| 176 | − s32 int_val = 0; | |
| 177 | − | |
| 178 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 179 | − | |
| 180 | − bcmerror = brcmu_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid)); | |
| 181 | − if (bcmerror != 0) | |
| 182 | − goto exit; | |
| 183 | − | |
| 184 | − if (plen >= (int)sizeof(int_val)) | |
| 185 | − memcpy(&int_val, params, sizeof(int_val)); | |
| 186 | − | |
| 187 | − switch (actionid) { | |
| 188 | − case IOV_GVAL(IOV_VERSION): | |
| 189 | − /* Need to have checked buffer length */ | |
| 190 | − strncpy((char *)arg, brcmf_version, len); | |
| 191 | − break; | |
| 192 | − | |
| 193 | − case IOV_GVAL(IOV_MSGLEVEL): | |
| 194 | − int_val = (s32) brcmf_msg_level; | |
| 195 | − memcpy(arg, &int_val, val_size); | |
| 196 | − break; | |
| 197 | − | |
| 198 | − case IOV_SVAL(IOV_MSGLEVEL): | |
| 199 | − brcmf_msg_level = int_val; | |
| 200 | − break; | |
| 201 | − | |
| 202 | − case IOV_GVAL(IOV_BCMERRORSTR): | |
| 203 | − strncpy((char *)arg, "bcm_error", | |
| 204 | − BCME_STRLEN); | |
| 205 | − ((char *)arg)[BCME_STRLEN - 1] = 0x00; | |
| 206 | − break; | |
| 207 | − | |
| 208 | − case IOV_GVAL(IOV_BCMERROR): | |
| 209 | − int_val = (s32) drvr->bcmerror; | |
| 210 | − memcpy(arg, &int_val, val_size); | |
| 211 | − break; | |
| 212 | − | |
| 213 | − case IOV_GVAL(IOV_DUMP): | |
| 214 | − bcmerror = brcmf_c_dump(drvr, arg, len); | |
| 215 | − break; | |
| 216 | − | |
| 217 | − case IOV_SVAL(IOV_CLEARCOUNTS): | |
| 218 | − drvr->tx_packets = drvr->rx_packets = 0; | |
| 219 | − drvr->tx_errors = drvr->rx_errors = 0; | |
| 220 | − drvr->tx_ctlpkts = drvr->rx_ctlpkts = 0; | |
| 221 | − drvr->tx_ctlerrs = drvr->rx_ctlerrs = 0; | |
| 222 | − drvr->rx_dropped = 0; | |
| 223 | − drvr->rx_readahead_cnt = 0; | |
| 224 | − drvr->tx_realloc = 0; | |
| 225 | − drvr->wd_dpc_sched = 0; | |
| 226 | − memset(&drvr->dstats, 0, sizeof(drvr->dstats)); | |
| 227 | − brcmf_bus_clearcounts(drvr); | |
| 228 | − break; | |
| 229 | − | |
| 230 | − case IOV_GVAL(IOV_IOCTLTIMEOUT):{ | |
| 231 | − int_val = (s32) brcmf_os_get_ioctl_resp_timeout(); | |
| 232 | − memcpy(arg, &int_val, sizeof(int_val)); | |
| 233 | − break; | |
| 234 | − } | |
| 235 | − | |
| 236 | − case IOV_SVAL(IOV_IOCTLTIMEOUT):{ | |
| 237 | − if (int_val <= 0) | |
| 238 | − bcmerror = -EINVAL; | |
| 239 | − else | |
| 240 | − brcmf_os_set_ioctl_resp_timeout((unsigned int) | |
| 241 | − int_val); | |
| 242 | − break; | |
| 243 | − } | |
| 244 | − | |
| 245 | − default: | |
| 246 | − bcmerror = -ENOTSUPP; | |
| 247 | − break; | |
| 248 | − } | |
| 249 | − | |
| 250 | −exit: | |
| 251 | − return bcmerror; | |
| 252 | −} | |
| 253 | − | |
| 254 | −bool brcmf_c_prec_enq(struct brcmf_pub *drvr, struct pktq *q, | |
| 255 | − struct sk_buff *pkt, int prec) | |
| 256 | −{ | |
| 257 | − struct sk_buff *p; | |
| 258 | − int eprec = -1; /* precedence to evict from */ | |
| 259 | − bool discard_oldest; | |
| 260 | − | |
| 261 | − /* Fast case, precedence queue is not full and we are also not | |
| 262 | − * exceeding total queue length | |
| 263 | − */ | |
| 264 | − if (!pktq_pfull(q, prec) && !pktq_full(q)) { | |
| 265 | − brcmu_pktq_penq(q, prec, pkt); | |
| 266 | − return true; | |
| 267 | − } | |
| 268 | − | |
| 269 | − /* Determine precedence from which to evict packet, if any */ | |
| 270 | − if (pktq_pfull(q, prec)) | |
| 271 | − eprec = prec; | |
| 272 | − else if (pktq_full(q)) { | |
| 273 | − p = brcmu_pktq_peek_tail(q, &eprec); | |
| 274 | − if (eprec > prec) | |
| 275 | − return false; | |
| 276 | − } | |
| 277 | − | |
| 278 | − /* Evict if needed */ | |
| 279 | − if (eprec >= 0) { | |
| 280 | − /* Detect queueing to unconfigured precedence */ | |
| 281 | − discard_oldest = AC_BITMAP_TST(drvr->wme_dp, eprec); | |
| 282 | − if (eprec == prec && !discard_oldest) | |
| 283 | − return false; /* refuse newer (incoming) packet */ | |
| 284 | − /* Evict packet according to discard policy */ | |
| 285 | − p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) : | |
| 286 | − brcmu_pktq_pdeq_tail(q, eprec); | |
| 287 | − if (p == NULL) { | |
| 288 | − BRCMF_ERROR(("%s: brcmu_pktq_penq() failed, oldest %d.", | |
| 289 | − __func__, discard_oldest)); | |
| 290 | − } | |
| 291 | − brcmu_pkt_buf_free_skb(p); | |
| 292 | − } | |
| 293 | − | |
| 294 | − /* Enqueue */ | |
| 295 | − p = brcmu_pktq_penq(q, prec, pkt); | |
| 296 | − if (p == NULL) { | |
| 297 | − BRCMF_ERROR(("%s: brcmu_pktq_penq() failed.", __func__)); | |
| 298 | − } | |
| 299 | − | |
| 300 | − return p != NULL; | |
| 301 | −} | |
| 302 | − | |
| 303 | −static int | |
| 304 | −brcmf_c_iovar_op(struct brcmf_pub *drvr, const char *name, | |
| 305 | − void *params, int plen, void *arg, int len, bool set) | |
| 306 | −{ | |
| 307 | − int bcmerror = 0; | |
| 308 | − int val_size; | |
| 309 | − const struct brcmu_iovar *vi = NULL; | |
| 310 | − u32 actionid; | |
| 311 | − | |
| 312 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 313 | − | |
| 314 | − if (name == NULL || len <= 0) | |
| 315 | − return -EINVAL; | |
| 316 | − | |
| 317 | − /* Set does not take qualifiers */ | |
| 318 | − if (set && (params || plen)) | |
| 319 | − return -EINVAL; | |
| 320 | − | |
| 321 | − /* Get must have return space;*/ | |
| 322 | − if (!set && !(arg && len)) | |
| 323 | − return -EINVAL; | |
| 324 | − | |
| 325 | − vi = brcmu_iovar_lookup(brcmf_iovars, name); | |
| 326 | − if (vi == NULL) { | |
| 327 | − bcmerror = -ENOTSUPP; | |
| 328 | − goto exit; | |
| 329 | − } | |
| 330 | − | |
| 331 | − BRCMF_CTL(("%s: %s %s, len %d plen %d\n", __func__, | |
| 332 | − name, (set ? "set" : "get"), len, plen)); | |
| 333 | − | |
| 334 | − /* set up 'params' pointer in case this is a set command so that | |
| 335 | − * the convenience int and bool code can be common to set and get | |
| 336 | − */ | |
| 337 | − if (params == NULL) { | |
| 338 | − params = arg; | |
| 339 | − plen = len; | |
| 340 | − } | |
| 341 | − | |
| 342 | − if (vi->type == IOVT_VOID) | |
| 343 | − val_size = 0; | |
| 344 | − else if (vi->type == IOVT_BUFFER) | |
| 345 | − val_size = len; | |
| 346 | − else | |
| 347 | − /* all other types are integer sized */ | |
| 348 | − val_size = sizeof(int); | |
| 349 | − | |
| 350 | − actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); | |
| 351 | − bcmerror = | |
| 352 | − brcmf_c_doiovar(drvr, vi, actionid, name, params, plen, arg, len, | |
| 353 | − val_size); | |
| 354 | − | |
| 355 | −exit: | |
| 356 | − return bcmerror; | |
| 357 | −} | |
| 358 | − | |
| 359 | −int brcmf_c_ioctl(struct brcmf_pub *drvr, struct brcmf_c_ioctl *ioc, void *buf, | |
| 360 | − uint buflen) | |
| 361 | −{ | |
| 362 | − int bcmerror = 0; | |
| 363 | − | |
| 364 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 365 | − | |
| 366 | − if (!buf) | |
| 367 | − return -EINVAL; | |
| 368 | − | |
| 369 | − switch (ioc->cmd) { | |
| 370 | − case BRCMF_GET_MAGIC: | |
| 371 | − if (buflen < sizeof(int)) | |
| 372 | − bcmerror = -EOVERFLOW; | |
| 373 | − else | |
| 374 | − *(int *)buf = BRCMF_IOCTL_MAGIC; | |
| 375 | − break; | |
| 376 | − | |
| 377 | − case BRCMF_GET_VERSION: | |
| 378 | − if (buflen < sizeof(int)) | |
| 379 | − bcmerror = -EOVERFLOW; | |
| 380 | − else | |
| 381 | − *(int *)buf = BRCMF_IOCTL_VERSION; | |
| 382 | − break; | |
| 383 | − | |
| 384 | − case BRCMF_GET_VAR: | |
| 385 | − case BRCMF_SET_VAR:{ | |
| 386 | − char *arg; | |
| 387 | − uint arglen; | |
| 388 | − | |
| 389 | − /* scan past the name to any arguments */ | |
| 390 | − for (arg = buf, arglen = buflen; *arg && arglen; | |
| 391 | − arg++, arglen--) | |
| 392 | − ; | |
| 393 | − | |
| 394 | − if (*arg) { | |
| 395 | − bcmerror = -EOVERFLOW; | |
| 396 | − break; | |
| 397 | − } | |
| 398 | − | |
| 399 | − /* account for the NUL terminator */ | |
| 400 | − arg++, arglen--; | |
| 401 | − | |
| 402 | − /* call with the appropriate arguments */ | |
| 403 | − if (ioc->cmd == BRCMF_GET_VAR) | |
| 404 | − bcmerror = brcmf_c_iovar_op(drvr, buf, arg, | |
| 405 | − arglen, buf, buflen, IOV_GET); | |
| 406 | − else | |
| 407 | − bcmerror = | |
| 408 | − brcmf_c_iovar_op(drvr, buf, NULL, 0, arg, | |
| 409 | − arglen, IOV_SET); | |
| 410 | − if (bcmerror != -ENOTSUPP) | |
| 411 | − break; | |
| 412 | − | |
| 413 | − /* if still not found, try bus module */ | |
| 414 | − if (ioc->cmd == BRCMF_GET_VAR) | |
| 415 | − bcmerror = brcmf_sdbrcm_bus_iovar_op(drvr, | |
| 416 | − buf, arg, arglen, buf, buflen, | |
| 417 | − IOV_GET); | |
| 418 | − else | |
| 419 | − bcmerror = brcmf_sdbrcm_bus_iovar_op(drvr, | |
| 420 | − buf, NULL, 0, arg, arglen, | |
| 421 | − IOV_SET); | |
| 422 | − | |
| 423 | − break; | |
| 424 | − } | |
| 425 | − | |
| 426 | − default: | |
| 427 | − bcmerror = -ENOTSUPP; | |
| 428 | − } | |
| 429 | − | |
| 430 | − return bcmerror; | |
| 431 | −} | |
| 432 | − | |
| 433 | −#ifdef SHOW_EVENTS | |
| 434 | −static void | |
| 435 | −brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) | |
| 436 | −{ | |
| 437 | − uint i, status, reason; | |
| 438 | − bool group = false, flush_txq = false, link = false; | |
| 439 | − char *auth_str, *event_name; | |
| 440 | − unsigned char *buf; | |
| 441 | − char err_msg[256], eabuf[ETHER_ADDR_STR_LEN]; | |
| 442 | − static struct { | |
| 443 | − uint event; | |
| 444 | − char *event_name; | |
| 445 | − } event_names[] = { | |
| 446 | − { | |
| 447 | − BRCMF_E_SET_SSID, "SET_SSID"}, { | |
| 448 | − BRCMF_E_JOIN, "JOIN"}, { | |
| 449 | − BRCMF_E_START, "START"}, { | |
| 450 | − BRCMF_E_AUTH, "AUTH"}, { | |
| 451 | − BRCMF_E_AUTH_IND, "AUTH_IND"}, { | |
| 452 | − BRCMF_E_DEAUTH, "DEAUTH"}, { | |
| 453 | − BRCMF_E_DEAUTH_IND, "DEAUTH_IND"}, { | |
| 454 | − BRCMF_E_ASSOC, "ASSOC"}, { | |
| 455 | − BRCMF_E_ASSOC_IND, "ASSOC_IND"}, { | |
| 456 | − BRCMF_E_REASSOC, "REASSOC"}, { | |
| 457 | − BRCMF_E_REASSOC_IND, "REASSOC_IND"}, { | |
| 458 | − BRCMF_E_DISASSOC, "DISASSOC"}, { | |
| 459 | − BRCMF_E_DISASSOC_IND, "DISASSOC_IND"}, { | |
| 460 | − BRCMF_E_QUIET_START, "START_QUIET"}, { | |
| 461 | − BRCMF_E_QUIET_END, "END_QUIET"}, { | |
| 462 | − BRCMF_E_BEACON_RX, "BEACON_RX"}, { | |
| 463 | − BRCMF_E_LINK, "LINK"}, { | |
| 464 | − BRCMF_E_MIC_ERROR, "MIC_ERROR"}, { | |
| 465 | − BRCMF_E_NDIS_LINK, "NDIS_LINK"}, { | |
| 466 | − BRCMF_E_ROAM, "ROAM"}, { | |
| 467 | − BRCMF_E_TXFAIL, "TXFAIL"}, { | |
| 468 | − BRCMF_E_PMKID_CACHE, "PMKID_CACHE"}, { | |
| 469 | − BRCMF_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, { | |
| 470 | − BRCMF_E_PRUNE, "PRUNE"}, { | |
| 471 | − BRCMF_E_AUTOAUTH, "AUTOAUTH"}, { | |
| 472 | − BRCMF_E_EAPOL_MSG, "EAPOL_MSG"}, { | |
| 473 | − BRCMF_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, { | |
| 474 | − BRCMF_E_ADDTS_IND, "ADDTS_IND"}, { | |
| 475 | − BRCMF_E_DELTS_IND, "DELTS_IND"}, { | |
| 476 | − BRCMF_E_BCNSENT_IND, "BCNSENT_IND"}, { | |
| 477 | − BRCMF_E_BCNRX_MSG, "BCNRX_MSG"}, { | |
| 478 | − BRCMF_E_BCNLOST_MSG, "BCNLOST_MSG"}, { | |
| 479 | − BRCMF_E_ROAM_PREP, "ROAM_PREP"}, { | |
| 480 | − BRCMF_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, { | |
| 481 | − BRCMF_E_PFN_NET_LOST, "PNO_NET_LOST"}, { | |
| 482 | − BRCMF_E_RESET_COMPLETE, "RESET_COMPLETE"}, { | |
| 483 | − BRCMF_E_JOIN_START, "JOIN_START"}, { | |
| 484 | − BRCMF_E_ROAM_START, "ROAM_START"}, { | |
| 485 | − BRCMF_E_ASSOC_START, "ASSOC_START"}, { | |
| 486 | − BRCMF_E_IBSS_ASSOC, "IBSS_ASSOC"}, { | |
| 487 | − BRCMF_E_RADIO, "RADIO"}, { | |
| 488 | − BRCMF_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, { | |
| 489 | − BRCMF_E_PROBREQ_MSG, "PROBREQ_MSG"}, { | |
| 490 | − BRCMF_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, { | |
| 491 | − BRCMF_E_PSK_SUP, "PSK_SUP"}, { | |
| 492 | − BRCMF_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, { | |
| 493 | − BRCMF_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, { | |
| 494 | − BRCMF_E_ICV_ERROR, "ICV_ERROR"}, { | |
| 495 | − BRCMF_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, { | |
| 496 | − BRCMF_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, { | |
| 497 | − BRCMF_E_TRACE, "TRACE"}, { | |
| 498 | − BRCMF_E_ACTION_FRAME, "ACTION FRAME"}, { | |
| 499 | − BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, { | |
| 500 | − BRCMF_E_IF, "IF"}, { | |
| 501 | − BRCMF_E_RSSI, "RSSI"}, { | |
| 502 | − BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"} | |
| 503 | − }; | |
| 504 | − uint event_type, flags, auth_type, datalen; | |
| 505 | − event_type = be32_to_cpu(event->event_type); | |
| 506 | − flags = be16_to_cpu(event->flags); | |
| 507 | − status = be32_to_cpu(event->status); | |
| 508 | − reason = be32_to_cpu(event->reason); | |
| 509 | − auth_type = be32_to_cpu(event->auth_type); | |
| 510 | − datalen = be32_to_cpu(event->datalen); | |
| 511 | − /* debug dump of event messages */ | |
| 512 | − sprintf(eabuf, "%pM", event->addr); | |
| 513 | − | |
| 514 | − event_name = "UNKNOWN"; | |
| 515 | − for (i = 0; i < ARRAY_SIZE(event_names); i++) { | |
| 516 | − if (event_names[i].event == event_type) | |
| 517 | − event_name = event_names[i].event_name; | |
| 518 | − } | |
| 519 | − | |
| 520 | − BRCMF_EVENT(("EVENT: %s, event ID = %d\n", event_name, event_type)); | |
| 521 | − BRCMF_EVENT(("flags 0x%04x, status %d, reason %d, auth_type %d" | |
| 522 | − " MAC %s\n", flags, status, reason, auth_type, eabuf)); | |
| 523 | − | |
| 524 | − if (flags & BRCMF_EVENT_MSG_LINK) | |
| 525 | − link = true; | |
| 526 | − if (flags & BRCMF_EVENT_MSG_GROUP) | |
| 527 | − group = true; | |
| 528 | − if (flags & BRCMF_EVENT_MSG_FLUSHTXQ) | |
| 529 | − flush_txq = true; | |
| 530 | − | |
| 531 | − switch (event_type) { | |
| 532 | − case BRCMF_E_START: | |
| 533 | − case BRCMF_E_DEAUTH: | |
| 534 | − case BRCMF_E_DISASSOC: | |
| 535 | − BRCMF_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); | |
| 536 | − break; | |
| 537 | − | |
| 538 | − case BRCMF_E_ASSOC_IND: | |
| 539 | − case BRCMF_E_REASSOC_IND: | |
| 540 | − BRCMF_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); | |
| 541 | − break; | |
| 542 | − | |
| 543 | − case BRCMF_E_ASSOC: | |
| 544 | − case BRCMF_E_REASSOC: | |
| 545 | − if (status == BRCMF_E_STATUS_SUCCESS) { | |
| 546 | − BRCMF_EVENT(("MACEVENT: %s, MAC %s, SUCCESS\n", | |
| 547 | − event_name, eabuf)); | |
| 548 | − } else if (status == BRCMF_E_STATUS_TIMEOUT) { | |
| 549 | − BRCMF_EVENT(("MACEVENT: %s, MAC %s, TIMEOUT\n", | |
| 550 | − event_name, eabuf)); | |
| 551 | − } else if (status == BRCMF_E_STATUS_FAIL) { | |
| 552 | − BRCMF_EVENT(("MACEVENT: %s, MAC %s, FAILURE," | |
| 553 | − " reason %d\n", event_name, eabuf, | |
| 554 | − (int)reason)); | |
| 555 | − } else { | |
| 556 | − BRCMF_EVENT(("MACEVENT: %s, MAC %s, unexpected status " | |
| 557 | − "%d\n", event_name, eabuf, (int)status)); | |
| 558 | − } | |
| 559 | − break; | |
| 560 | − | |
| 561 | − case BRCMF_E_DEAUTH_IND: | |
| 562 | − case BRCMF_E_DISASSOC_IND: | |
| 563 | − BRCMF_EVENT(("MACEVENT: %s, MAC %s, reason %d\n", event_name, | |
| 564 | − eabuf, (int)reason)); | |
| 565 | − break; | |
| 566 | − | |
| 567 | − case BRCMF_E_AUTH: | |
| 568 | − case BRCMF_E_AUTH_IND: | |
| 569 | − if (auth_type == WLAN_AUTH_OPEN) | |
| 570 | − auth_str = "Open System"; | |
| 571 | − else if (auth_type == WLAN_AUTH_SHARED_KEY) | |
| 572 | − auth_str = "Shared Key"; | |
| 573 | − else { | |
| 574 | − sprintf(err_msg, "AUTH unknown: %d", (int)auth_type); | |
| 575 | − auth_str = err_msg; | |
| 576 | − } | |
| 577 | − if (event_type == BRCMF_E_AUTH_IND) { | |
| 578 | − BRCMF_EVENT(("MACEVENT: %s, MAC %s, %s\n", event_name, | |
| 579 | − eabuf, auth_str)); | |
| 580 | − } else if (status == BRCMF_E_STATUS_SUCCESS) { | |
| 581 | − BRCMF_EVENT(("MACEVENT: %s, MAC %s, %s, SUCCESS\n", | |
| 582 | − event_name, eabuf, auth_str)); | |
| 583 | − } else if (status == BRCMF_E_STATUS_TIMEOUT) { | |
| 584 | − BRCMF_EVENT(("MACEVENT: %s, MAC %s, %s, TIMEOUT\n", | |
| 585 | − event_name, eabuf, auth_str)); | |
| 586 | − } else if (status == BRCMF_E_STATUS_FAIL) { | |
| 587 | − BRCMF_EVENT(("MACEVENT: %s, MAC %s, %s, FAILURE, " | |
| 588 | − "reason %d\n", | |
| 589 | − event_name, eabuf, auth_str, (int)reason)); | |
| 590 | − } | |
| 591 | − | |
| 592 | − break; | |
| 593 | − | |
| 594 | − case BRCMF_E_JOIN: | |
| 595 | − case BRCMF_E_ROAM: | |
| 596 | − case BRCMF_E_SET_SSID: | |
| 597 | − if (status == BRCMF_E_STATUS_SUCCESS) { | |
| 598 | − BRCMF_EVENT(("MACEVENT: %s, MAC %s\n", event_name, | |
| 599 | − eabuf)); | |
| 600 | − } else if (status == BRCMF_E_STATUS_FAIL) { | |
| 601 | − BRCMF_EVENT(("MACEVENT: %s, failed\n", event_name)); | |
| 602 | − } else if (status == BRCMF_E_STATUS_NO_NETWORKS) { | |
| 603 | − BRCMF_EVENT(("MACEVENT: %s, no networks found\n", | |
| 604 | − event_name)); | |
| 605 | − } else { | |
| 606 | − BRCMF_EVENT(("MACEVENT: %s, unexpected status %d\n", | |
| 607 | − event_name, (int)status)); | |
| 608 | − } | |
| 609 | − break; | |
| 610 | − | |
| 611 | − case BRCMF_E_BEACON_RX: | |
| 612 | − if (status == BRCMF_E_STATUS_SUCCESS) { | |
| 613 | − BRCMF_EVENT(("MACEVENT: %s, SUCCESS\n", event_name)); | |
| 614 | − } else if (status == BRCMF_E_STATUS_FAIL) { | |
| 615 | − BRCMF_EVENT(("MACEVENT: %s, FAIL\n", event_name)); | |
| 616 | − } else { | |
| 617 | − BRCMF_EVENT(("MACEVENT: %s, status %d\n", event_name, | |
| 618 | − status)); | |
| 619 | − } | |
| 620 | − break; | |
| 621 | − | |
| 622 | − case BRCMF_E_LINK: | |
| 623 | − BRCMF_EVENT(("MACEVENT: %s %s\n", event_name, | |
| 624 | − link ? "UP" : "DOWN")); | |
| 625 | − break; | |
| 626 | − | |
| 627 | − case BRCMF_E_MIC_ERROR: | |
| 628 | − BRCMF_EVENT(("MACEVENT: %s, MAC %s, Group %d, Flush %d\n", | |
| 629 | − event_name, eabuf, group, flush_txq)); | |
| 630 | − break; | |
| 631 | − | |
| 632 | − case BRCMF_E_ICV_ERROR: | |
| 633 | − case BRCMF_E_UNICAST_DECODE_ERROR: | |
| 634 | − case BRCMF_E_MULTICAST_DECODE_ERROR: | |
| 635 | − BRCMF_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); | |
| 636 | − break; | |
| 637 | − | |
| 638 | − case BRCMF_E_TXFAIL: | |
| 639 | − BRCMF_EVENT(("MACEVENT: %s, RA %s\n", event_name, eabuf)); | |
| 640 | − break; | |
| 641 | − | |
| 642 | − case BRCMF_E_SCAN_COMPLETE: | |
| 643 | − case BRCMF_E_PMKID_CACHE: | |
| 644 | − BRCMF_EVENT(("MACEVENT: %s\n", event_name)); | |
| 645 | − break; | |
| 646 | − | |
| 647 | − case BRCMF_E_PFN_NET_FOUND: | |
| 648 | − case BRCMF_E_PFN_NET_LOST: | |
| 649 | − case BRCMF_E_PFN_SCAN_COMPLETE: | |
| 650 | − BRCMF_EVENT(("PNOEVENT: %s\n", event_name)); | |
| 651 | − break; | |
| 652 | − | |
| 653 | − case BRCMF_E_PSK_SUP: | |
| 654 | − case BRCMF_E_PRUNE: | |
| 655 | − BRCMF_EVENT(("MACEVENT: %s, status %d, reason %d\n", | |
| 656 | − event_name, (int)status, (int)reason)); | |
| 657 | − break; | |
| 658 | − | |
| 659 | − case BRCMF_E_TRACE: | |
| 660 | − { | |
| 661 | − static u32 seqnum_prev; | |
| 662 | − struct msgtrace_hdr hdr; | |
| 663 | − u32 nblost; | |
| 664 | − char *s, *p; | |
| 665 | − | |
| 666 | − buf = (unsigned char *) event_data; | |
| 667 | − memcpy(&hdr, buf, sizeof(struct msgtrace_hdr)); | |
| 668 | − | |
| 669 | − if (hdr.version != MSGTRACE_VERSION) { | |
| 670 | − BRCMF_ERROR( | |
| 671 | − ("\nMACEVENT: %s [unsupported version --> " | |
| 672 | − "brcmf version:%d dongle version:%d]\n", | |
| 673 | − event_name, MSGTRACE_VERSION, hdr.version) | |
| 674 | − ); | |
| 675 | − /* Reset datalen to avoid display below */ | |
| 676 | − datalen = 0; | |
| 677 | − break; | |
| 678 | − } | |
| 679 | − | |
| 680 | − /* There are 2 bytes available at the end of data */ | |
| 681 | − *(buf + sizeof(struct msgtrace_hdr) | |
| 682 | − + be16_to_cpu(hdr.len)) = '\0'; | |
| 683 | − | |
| 684 | − if (be32_to_cpu(hdr.discarded_bytes) | |
| 685 | − || be32_to_cpu(hdr.discarded_printf)) { | |
| 686 | − BRCMF_ERROR( | |
| 687 | − ("\nWLC_E_TRACE: [Discarded traces in dongle -->" | |
| 688 | − "discarded_bytes %d discarded_printf %d]\n", | |
| 689 | − be32_to_cpu(hdr.discarded_bytes), | |
| 690 | − be32_to_cpu(hdr.discarded_printf))); | |
| 691 | − } | |
| 692 | − | |
| 693 | − nblost = be32_to_cpu(hdr.seqnum) - seqnum_prev - 1; | |
| 694 | − if (nblost > 0) { | |
| 695 | − BRCMF_ERROR( | |
| 696 | − ("\nWLC_E_TRACE: [Event lost --> seqnum %d nblost %d\n", | |
| 697 | − be32_to_cpu(hdr.seqnum), nblost)); | |
| 698 | − } | |
| 699 | − seqnum_prev = be32_to_cpu(hdr.seqnum); | |
| 700 | − | |
| 701 | − /* Display the trace buffer. Advance from \n to \n to | |
| 702 | − * avoid display big | |
| 703 | − * printf (issue with Linux printk ) | |
| 704 | − */ | |
| 705 | − p = (char *)&buf[sizeof(struct msgtrace_hdr)]; | |
| 706 | − while ((s = strstr(p, "\n")) != NULL) { | |
| 707 | − *s = '\0'; | |
| 708 | − printk(KERN_DEBUG"%s\n", p); | |
| 709 | − p = s + 1; | |
| 710 | − } | |
| 711 | − printk(KERN_DEBUG "%s\n", p); | |
| 712 | − | |
| 713 | − /* Reset datalen to avoid display below */ | |
| 714 | − datalen = 0; | |
| 715 | − } | |
| 716 | − break; | |
| 717 | − | |
| 718 | − case BRCMF_E_RSSI: | |
| 719 | − BRCMF_EVENT(("MACEVENT: %s %d\n", event_name, | |
| 720 | − be32_to_cpu(*((int *)event_data)))); | |
| 721 | − break; | |
| 722 | − | |
| 723 | − default: | |
| 724 | − BRCMF_EVENT(("MACEVENT: %s %d, MAC %s, status %d, reason %d, " | |
| 725 | − "auth %d\n", event_name, event_type, eabuf, | |
| 726 | − (int)status, (int)reason, (int)auth_type)); | |
| 727 | − break; | |
| 728 | − } | |
| 729 | − | |
| 730 | − /* show any appended data */ | |
| 731 | − if (datalen) { | |
| 732 | − buf = (unsigned char *) event_data; | |
| 733 | − BRCMF_EVENT((" data (%d) : ", datalen)); | |
| 734 | − for (i = 0; i < datalen; i++) | |
| 735 | − BRCMF_EVENT((" 0x%02x ", *buf++)); | |
| 736 | − BRCMF_EVENT(("\n")); | |
| 737 | − } | |
| 738 | −} | |
| 739 | −#endif /* SHOW_EVENTS */ | |
| 740 | − | |
| 741 | −int | |
| 742 | −brcmf_c_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata, | |
| 743 | − struct brcmf_event_msg *event, void **data_ptr) | |
| 744 | −{ | |
| 745 | − /* check whether packet is a BRCM event pkt */ | |
| 746 | − struct brcmf_event *pvt_data = (struct brcmf_event *) pktdata; | |
| 747 | − char *event_data; | |
| 748 | − u32 type, status; | |
| 749 | − u16 flags; | |
| 750 | − int evlen; | |
| 751 | − | |
| 752 | − if (memcmp(BRCM_OUI, &pvt_data->hdr.oui[0], DOT11_OUI_LEN)) { | |
| 753 | − BRCMF_ERROR(("%s: mismatched OUI, bailing\n", __func__)); | |
| 754 | − return -EBADE; | |
| 755 | − } | |
| 756 | − | |
| 757 | − /* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */ | |
| 758 | − if (get_unaligned_be16(&pvt_data->hdr.usr_subtype) != | |
| 759 | − BCMILCP_BCM_SUBTYPE_EVENT) { | |
| 760 | − BRCMF_ERROR(("%s: mismatched subtype, bailing\n", __func__)); | |
| 761 | − return -EBADE; | |
| 762 | − } | |
| 763 | − | |
| 764 | − *data_ptr = &pvt_data[1]; | |
| 765 | − event_data = *data_ptr; | |
| 766 | − | |
| 767 | − /* memcpy since BRCM event pkt may be unaligned. */ | |
| 768 | − memcpy(event, &pvt_data->msg, sizeof(struct brcmf_event_msg)); | |
| 769 | − | |
| 770 | − type = get_unaligned_be32(&event->event_type); | |
| 771 | − flags = get_unaligned_be16(&event->flags); | |
| 772 | − status = get_unaligned_be32(&event->status); | |
| 773 | − evlen = get_unaligned_be32(&event->datalen) + | |
| 774 | − sizeof(struct brcmf_event); | |
| 775 | − | |
| 776 | − switch (type) { | |
| 777 | − case BRCMF_E_IF: | |
| 778 | − { | |
| 779 | − struct brcmf_if_event *ifevent = | |
| 780 | − (struct brcmf_if_event *) event_data; | |
| 781 | − BRCMF_TRACE(("%s: if event\n", __func__)); | |
| 782 | − | |
| 783 | − if (ifevent->ifidx > 0 && | |
| 784 | − ifevent->ifidx < BRCMF_MAX_IFS) { | |
| 785 | − if (ifevent->action == BRCMF_E_IF_ADD) | |
| 786 | − brcmf_add_if(drvr_priv, ifevent->ifidx, | |
| 787 | − NULL, event->ifname, | |
| 788 | − pvt_data->eth.h_dest, | |
| 789 | − ifevent->flags, | |
| 790 | − ifevent->bssidx); | |
| 791 | − else | |
| 792 | − brcmf_del_if(drvr_priv, ifevent->ifidx); | |
| 793 | − } else { | |
| 794 | − BRCMF_ERROR(("%s: Invalid ifidx %d for %s\n", | |
| 795 | − __func__, ifevent->ifidx, | |
| 796 | − event->ifname)); | |
| 797 | − } | |
| 798 | − } | |
| 799 | − /* send up the if event: btamp user needs it */ | |
| 800 | − *ifidx = brcmf_ifname2idx(drvr_priv, event->ifname); | |
| 801 | − break; | |
| 802 | − | |
| 803 | − /* These are what external supplicant/authenticator wants */ | |
| 804 | − case BRCMF_E_LINK: | |
| 805 | − case BRCMF_E_ASSOC_IND: | |
| 806 | − case BRCMF_E_REASSOC_IND: | |
| 807 | − case BRCMF_E_DISASSOC_IND: | |
| 808 | − case BRCMF_E_MIC_ERROR: | |
| 809 | − default: | |
| 810 | − /* Fall through: this should get _everything_ */ | |
| 811 | − | |
| 812 | − *ifidx = brcmf_ifname2idx(drvr_priv, event->ifname); | |
| 813 | − BRCMF_TRACE(("%s: MAC event %d, flags %x, status %x\n", | |
| 814 | − __func__, type, flags, status)); | |
| 815 | − | |
| 816 | − /* put it back to BRCMF_E_NDIS_LINK */ | |
| 817 | − if (type == BRCMF_E_NDIS_LINK) { | |
| 818 | − u32 temp; | |
| 819 | − | |
| 820 | − temp = get_unaligned_be32(&event->event_type); | |
| 821 | − BRCMF_TRACE(("Converted to WLC_E_LINK type %d\n", | |
| 822 | − temp)); | |
| 823 | − | |
| 824 | − temp = be32_to_cpu(BRCMF_E_NDIS_LINK); | |
| 825 | − memcpy((void *)(&pvt_data->msg.event_type), &temp, | |
| 826 | − sizeof(pvt_data->msg.event_type)); | |
| 827 | − } | |
| 828 | − break; | |
| 829 | − } | |
| 830 | − | |
| 831 | −#ifdef SHOW_EVENTS | |
| 832 | − brcmf_c_show_host_event(event, event_data); | |
| 833 | −#endif /* SHOW_EVENTS */ | |
| 834 | − | |
| 835 | − return 0; | |
| 836 | −} | |
| 837 | − | |
| 838 | −/* Convert user's input in hex pattern to byte-size mask */ | |
| 839 | −static int brcmf_c_pattern_atoh(char *src, char *dst) | |
| 840 | −{ | |
| 841 | − int i; | |
| 842 | − if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) { | |
| 843 | − BRCMF_ERROR(("Mask invalid format. Needs to start with 0x\n")); | |
| 844 | − return -1; | |
| 845 | − } | |
| 846 | − src = src + 2; /* Skip past 0x */ | |
| 847 | − if (strlen(src) % 2 != 0) { | |
| 848 | − BRCMF_ERROR(("Mask invalid format. Length must be even.\n")); | |
| 849 | − return -1; | |
| 850 | − } | |
| 851 | − for (i = 0; *src != '\0'; i++) { | |
| 852 | − char num[3]; | |
| 853 | − strncpy(num, src, 2); | |
| 854 | − num[2] = '\0'; | |
| 855 | − dst[i] = (u8) simple_strtoul(num, NULL, 16); | |
| 856 | − src += 2; | |
| 857 | − } | |
| 858 | − return i; | |
| 859 | −} | |
| 860 | − | |
| 861 | −void | |
| 862 | −brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable, | |
| 863 | − int master_mode) | |
| 864 | −{ | |
| 865 | − char *argv[8]; | |
| 866 | − int i = 0; | |
| 867 | − const char *str; | |
| 868 | − int buf_len; | |
| 869 | − int str_len; | |
| 870 | − char *arg_save = 0, *arg_org = 0; | |
| 871 | − int rc; | |
| 872 | − char buf[128]; | |
| 873 | − struct brcmf_pkt_filter_enable enable_parm; | |
| 874 | − struct brcmf_pkt_filter_enable *pkt_filterp; | |
| 875 | − | |
| 876 | − arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC); | |
| 877 | − if (!arg_save) { | |
| 878 | − BRCMF_ERROR(("%s: kmalloc failed\n", __func__)); | |
| 879 | − goto fail; | |
| 880 | − } | |
| 881 | − arg_org = arg_save; | |
| 882 | − memcpy(arg_save, arg, strlen(arg) + 1); | |
| 883 | − | |
| 884 | − argv[i] = strsep(&arg_save, " "); | |
| 885 | − | |
| 886 | − i = 0; | |
| 887 | − if (NULL == argv[i]) { | |
| 888 | − BRCMF_ERROR(("No args provided\n")); | |
| 889 | − goto fail; | |
| 890 | − } | |
| 891 | − | |
| 892 | − str = "pkt_filter_enable"; | |
| 893 | − str_len = strlen(str); | |
| 894 | − strncpy(buf, str, str_len); | |
| 895 | − buf[str_len] = '\0'; | |
| 896 | − buf_len = str_len + 1; | |
| 897 | − | |
| 898 | − pkt_filterp = (struct brcmf_pkt_filter_enable *) (buf + str_len + 1); | |
| 899 | − | |
| 900 | − /* Parse packet filter id. */ | |
| 901 | − enable_parm.id = simple_strtoul(argv[i], NULL, 0); | |
| 902 | − | |
| 903 | − /* Parse enable/disable value. */ | |
| 904 | − enable_parm.enable = enable; | |
| 905 | − | |
| 906 | − buf_len += sizeof(enable_parm); | |
| 907 | − memcpy((char *)pkt_filterp, &enable_parm, sizeof(enable_parm)); | |
| 908 | − | |
| 909 | − /* Enable/disable the specified filter. */ | |
| 910 | − rc = brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len); | |
| 911 | − rc = rc >= 0 ? 0 : rc; | |
| 912 | − if (rc) | |
| 913 | − BRCMF_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", | |
| 914 | − __func__, arg, rc)); | |
| 915 | − else | |
| 916 | − BRCMF_TRACE(("%s: successfully added pktfilter %s\n", | |
| 917 | − __func__, arg)); | |
| 918 | − | |
| 919 | − /* Contorl the master mode */ | |
| 920 | − brcmu_mkiovar("pkt_filter_mode", (char *)&master_mode, 4, buf, | |
| 921 | − sizeof(buf)); | |
| 922 | − rc = brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, buf, | |
| 923 | − sizeof(buf)); | |
| 924 | − rc = rc >= 0 ? 0 : rc; | |
| 925 | − if (rc) | |
| 926 | − BRCMF_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", | |
| 927 | − __func__, arg, rc)); | |
| 928 | − | |
| 929 | −fail: | |
| 930 | − kfree(arg_org); | |
| 931 | −} | |
| 932 | − | |
| 933 | −void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg) | |
| 934 | −{ | |
| 935 | − const char *str; | |
| 936 | − struct brcmf_pkt_filter pkt_filter; | |
| 937 | − struct brcmf_pkt_filter *pkt_filterp; | |
| 938 | − int buf_len; | |
| 939 | − int str_len; | |
| 940 | − int rc; | |
| 941 | − u32 mask_size; | |
| 942 | − u32 pattern_size; | |
| 943 | − char *argv[8], *buf = 0; | |
| 944 | − int i = 0; | |
| 945 | − char *arg_save = 0, *arg_org = 0; | |
| 946 | − | |
| 947 | − arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC); | |
| 948 | − if (!arg_save) { | |
| 949 | − BRCMF_ERROR(("%s: kmalloc failed\n", __func__)); | |
| 950 | − goto fail; | |
| 951 | − } | |
| 952 | − | |
| 953 | − arg_org = arg_save; | |
| 954 | − | |
| 955 | − buf = kmalloc(PKTFILTER_BUF_SIZE, GFP_ATOMIC); | |
| 956 | − if (!buf) { | |
| 957 | − BRCMF_ERROR(("%s: kmalloc failed\n", __func__)); | |
| 958 | − goto fail; | |
| 959 | − } | |
| 960 | − | |
| 961 | − strcpy(arg_save, arg); | |
| 962 | − | |
| 963 | − argv[i] = strsep(&arg_save, " "); | |
| 964 | − while (argv[i++]) | |
| 965 | − argv[i] = strsep(&arg_save, " "); | |
| 966 | − | |
| 967 | − i = 0; | |
| 968 | − if (NULL == argv[i]) { | |
| 969 | − BRCMF_ERROR(("No args provided\n")); | |
| 970 | − goto fail; | |
| 971 | − } | |
| 972 | − | |
| 973 | − str = "pkt_filter_add"; | |
| 974 | − strcpy(buf, str); | |
| 975 | − str_len = strlen(str); | |
| 976 | − buf_len = str_len + 1; | |
| 977 | − | |
| 978 | − pkt_filterp = (struct brcmf_pkt_filter *) (buf + str_len + 1); | |
| 979 | − | |
| 980 | − /* Parse packet filter id. */ | |
| 981 | − pkt_filter.id = simple_strtoul(argv[i], NULL, 0); | |
| 982 | − | |
| 983 | − if (NULL == argv[++i]) { | |
| 984 | − BRCMF_ERROR(("Polarity not provided\n")); | |
| 985 | − goto fail; | |
| 986 | − } | |
| 987 | − | |
| 988 | − /* Parse filter polarity. */ | |
| 989 | − pkt_filter.negate_match = simple_strtoul(argv[i], NULL, 0); | |
| 990 | − | |
| 991 | − if (NULL == argv[++i]) { | |
| 992 | − BRCMF_ERROR(("Filter type not provided\n")); | |
| 993 | − goto fail; | |
| 994 | − } | |
| 995 | − | |
| 996 | − /* Parse filter type. */ | |
| 997 | − pkt_filter.type = simple_strtoul(argv[i], NULL, 0); | |
| 998 | − | |
| 999 | − if (NULL == argv[++i]) { | |
| 1000 | − BRCMF_ERROR(("Offset not provided\n")); | |
| 1001 | − goto fail; | |
| 1002 | − } | |
| 1003 | − | |
| 1004 | − /* Parse pattern filter offset. */ | |
| 1005 | − pkt_filter.u.pattern.offset = simple_strtoul(argv[i], NULL, 0); | |
| 1006 | − | |
| 1007 | − if (NULL == argv[++i]) { | |
| 1008 | − BRCMF_ERROR(("Bitmask not provided\n")); | |
| 1009 | − goto fail; | |
| 1010 | − } | |
| 1011 | − | |
| 1012 | − /* Parse pattern filter mask. */ | |
| 1013 | − mask_size = | |
| 1014 | − brcmf_c_pattern_atoh | |
| 1015 | − (argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern); | |
| 1016 | − | |
| 1017 | − if (NULL == argv[++i]) { | |
| 1018 | − BRCMF_ERROR(("Pattern not provided\n")); | |
| 1019 | − goto fail; | |
| 1020 | − } | |
| 1021 | − | |
| 1022 | − /* Parse pattern filter pattern. */ | |
| 1023 | − pattern_size = | |
| 1024 | − brcmf_c_pattern_atoh(argv[i], | |
| 1025 | − (char *)&pkt_filterp->u.pattern. | |
| 1026 | − mask_and_pattern[mask_size]); | |
| 1027 | − | |
| 1028 | − if (mask_size != pattern_size) { | |
| 1029 | − BRCMF_ERROR(("Mask and pattern not the same size\n")); | |
| 1030 | − goto fail; | |
| 1031 | − } | |
| 1032 | − | |
| 1033 | − pkt_filter.u.pattern.size_bytes = mask_size; | |
| 1034 | − buf_len += BRCMF_PKT_FILTER_FIXED_LEN; | |
| 1035 | − buf_len += (BRCMF_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size); | |
| 1036 | − | |
| 1037 | − /* Keep-alive attributes are set in local | |
| 1038 | − * variable (keep_alive_pkt), and | |
| 1039 | − ** then memcpy'ed into buffer (keep_alive_pktp) since there is no | |
| 1040 | − ** guarantee that the buffer is properly aligned. | |
| 1041 | − */ | |
| 1042 | − memcpy((char *)pkt_filterp, | |
| 1043 | − &pkt_filter, | |
| 1044 | − BRCMF_PKT_FILTER_FIXED_LEN + BRCMF_PKT_FILTER_PATTERN_FIXED_LEN); | |
| 1045 | − | |
| 1046 | − rc = brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len); | |
| 1047 | − rc = rc >= 0 ? 0 : rc; | |
| 1048 | − | |
| 1049 | − if (rc) | |
| 1050 | − BRCMF_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", | |
| 1051 | − __func__, arg, rc)); | |
| 1052 | − else | |
| 1053 | − BRCMF_TRACE(("%s: successfully added pktfilter %s\n", | |
| 1054 | − __func__, arg)); | |
| 1055 | − | |
| 1056 | −fail: | |
| 1057 | − kfree(arg_org); | |
| 1058 | − | |
| 1059 | − kfree(buf); | |
| 1060 | −} | |
| 1061 | − | |
| 1062 | −void brcmf_c_arp_offload_set(struct brcmf_pub *drvr, int arp_mode) | |
| 1063 | −{ | |
| 1064 | − char iovbuf[32]; | |
| 1065 | − int retcode; | |
| 1066 | − | |
| 1067 | − brcmu_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf)); | |
| 1068 | − retcode = brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, | |
| 1069 | − iovbuf, sizeof(iovbuf)); | |
| 1070 | − retcode = retcode >= 0 ? 0 : retcode; | |
| 1071 | − if (retcode) | |
| 1072 | − BRCMF_TRACE(("%s: failed to set ARP offload mode to 0x%x, " | |
| 1073 | − "retcode = %d\n", __func__, arp_mode, retcode)); | |
| 1074 | − else | |
| 1075 | − BRCMF_TRACE(("%s: successfully set ARP offload mode to 0x%x\n", | |
| 1076 | − __func__, arp_mode)); | |
| 1077 | −} | |
| 1078 | − | |
| 1079 | −void brcmf_c_arp_offload_enable(struct brcmf_pub *drvr, int arp_enable) | |
| 1080 | −{ | |
| 1081 | − char iovbuf[32]; | |
| 1082 | − int retcode; | |
| 1083 | − | |
| 1084 | − brcmu_mkiovar("arpoe", (char *)&arp_enable, 4, iovbuf, sizeof(iovbuf)); | |
| 1085 | − retcode = brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, | |
| 1086 | − iovbuf, sizeof(iovbuf)); | |
| 1087 | − retcode = retcode >= 0 ? 0 : retcode; | |
| 1088 | − if (retcode) | |
| 1089 | − BRCMF_TRACE(("%s: failed to enabe ARP offload to %d, " | |
| 1090 | − "retcode = %d\n", __func__, arp_enable, retcode)); | |
| 1091 | − else | |
| 1092 | − BRCMF_TRACE(("%s: successfully enabed ARP offload to %d\n", | |
| 1093 | − __func__, arp_enable)); | |
| 1094 | −} | |
| 1095 | − | |
| 1096 | −int brcmf_c_preinit_ioctls(struct brcmf_pub *drvr) | |
| 1097 | −{ | |
| 1098 | − char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; /* Room for | |
| 1099 | − "event_msgs" + '\0' + bitvec */ | |
| 1100 | − uint up = 0; | |
| 1101 | − char buf[128], *ptr; | |
| 1102 | − uint power_mode = PM_FAST; | |
| 1103 | − u32 dongle_align = BRCMF_SDALIGN; | |
| 1104 | − u32 glom = 0; | |
| 1105 | − uint bcn_timeout = 3; | |
| 1106 | − int scan_assoc_time = 40; | |
| 1107 | − int scan_unassoc_time = 40; | |
| 1108 | − int i; | |
| 1109 | − | |
| 1110 | − brcmf_os_proto_block(drvr); | |
| 1111 | − | |
| 1112 | − /* Set Country code */ | |
| 1113 | − if (drvr->country_code[0] != 0) { | |
| 1114 | − if (brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_COUNTRY, | |
| 1115 | − drvr->country_code, | |
| 1116 | − sizeof(drvr->country_code)) < 0) { | |
| 1117 | − BRCMF_ERROR(("%s: country code setting failed\n", | |
| 1118 | − __func__)); | |
| 1119 | − } | |
| 1120 | − } | |
| 1121 | − | |
| 1122 | − /* query for 'ver' to get version info from firmware */ | |
| 1123 | − memset(buf, 0, sizeof(buf)); | |
| 1124 | − ptr = buf; | |
| 1125 | − brcmu_mkiovar("ver", 0, 0, buf, sizeof(buf)); | |
| 1126 | − brcmf_proto_cdc_query_ioctl(drvr, 0, BRCMF_C_GET_VAR, buf, sizeof(buf)); | |
| 1127 | − strsep(&ptr, "\n"); | |
| 1128 | − /* Print fw version info */ | |
| 1129 | − BRCMF_ERROR(("Firmware version = %s\n", buf)); | |
| 1130 | − | |
| 1131 | − /* Set PowerSave mode */ | |
| 1132 | − brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_PM, (char *)&power_mode, | |
| 1133 | − sizeof(power_mode)); | |
| 1134 | − | |
| 1135 | − /* Match Host and Dongle rx alignment */ | |
| 1136 | − brcmu_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf, | |
| 1137 | − sizeof(iovbuf)); | |
| 1138 | − brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, iovbuf, | |
| 1139 | − sizeof(iovbuf)); | |
| 1140 | − | |
| 1141 | − /* disable glom option per default */ | |
| 1142 | − brcmu_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf)); | |
| 1143 | − brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, iovbuf, | |
| 1144 | − sizeof(iovbuf)); | |
| 1145 | − | |
| 1146 | − /* Setup timeout if Beacons are lost and roam is off to report | |
| 1147 | − link down */ | |
| 1148 | − brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, | |
| 1149 | − sizeof(iovbuf)); | |
| 1150 | − brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, iovbuf, | |
| 1151 | − sizeof(iovbuf)); | |
| 1152 | − | |
| 1153 | − /* Enable/Disable build-in roaming to allowed ext supplicant to take | |
| 1154 | − of romaing */ | |
| 1155 | − brcmu_mkiovar("roam_off", (char *)&brcmf_roam, 4, | |
| 1156 | − iovbuf, sizeof(iovbuf)); | |
| 1157 | − brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, iovbuf, | |
| 1158 | − sizeof(iovbuf)); | |
| 1159 | − | |
| 1160 | − /* Force STA UP */ | |
| 1161 | − if (brcmf_radio_up) | |
| 1162 | − brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_UP, (char *)&up, | |
| 1163 | − sizeof(up)); | |
| 1164 | − | |
| 1165 | − /* Setup event_msgs */ | |
| 1166 | − brcmu_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN, | |
| 1167 | − iovbuf, sizeof(iovbuf)); | |
| 1168 | − brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, iovbuf, | |
| 1169 | − sizeof(iovbuf)); | |
| 1170 | − | |
| 1171 | − brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_SCAN_CHANNEL_TIME, | |
| 1172 | − (char *)&scan_assoc_time, sizeof(scan_assoc_time)); | |
| 1173 | − brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_SCAN_UNASSOC_TIME, | |
| 1174 | − (char *)&scan_unassoc_time, sizeof(scan_unassoc_time)); | |
| 1175 | − | |
| 1176 | − /* Set and enable ARP offload feature */ | |
| 1177 | − if (brcmf_arp_enable) | |
| 1178 | − brcmf_c_arp_offload_set(drvr, brcmf_arp_mode); | |
| 1179 | − brcmf_c_arp_offload_enable(drvr, brcmf_arp_enable); | |
| 1180 | − | |
| 1181 | − /* Set up pkt filter */ | |
| 1182 | − if (brcmf_pkt_filter_enable) { | |
| 1183 | − for (i = 0; i < drvr->pktfilter_count; i++) { | |
| 1184 | − brcmf_c_pktfilter_offload_set(drvr, | |
| 1185 | − drvr->pktfilter[i]); | |
| 1186 | − brcmf_c_pktfilter_offload_enable(drvr, | |
| 1187 | − drvr->pktfilter[i], | |
| 1188 | − brcmf_pkt_filter_init, | |
| 1189 | − brcmf_master_mode); | |
| 1190 | − } | |
| 1191 | − } | |
| 1192 | − | |
| 1193 | − brcmf_os_proto_unblock(drvr); | |
| 1194 | − | |
| 1195 | − return 0; | |
| 1196 | −} | |
| @@ -1,70 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * Copyright (c) 2010 Broadcom Corporation | |
| 3 | − * | |
| 4 | − * Permission to use, copy, modify, and/or distribute this software for any | |
| 5 | − * purpose with or without fee is hereby granted, provided that the above | |
| 6 | − * copyright notice and this permission notice appear in all copies. | |
| 7 | − * | |
| 8 | − * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
| 9 | − * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
| 10 | − * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
| 11 | − * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 12 | − * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | |
| 13 | − * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
| 14 | − * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
| 15 | − */ | |
| 16 | − | |
| 17 | −#ifndef _BRCMF_DBG_H_ | |
| 18 | −#define _BRCMF_DBG_H_ | |
| 19 | − | |
| 20 | −#if defined(BCMDBG) | |
| 21 | − | |
| 22 | −#define BRCMF_ERROR(args) \ | |
| 23 | − do {if ((brcmf_msg_level & BRCMF_ERROR_VAL) && (net_ratelimit())) \ | |
| 24 | − printk args; } while (0) | |
| 25 | −#define BRCMF_TRACE(args) do {if (brcmf_msg_level & BRCMF_TRACE_VAL) \ | |
| 26 | − printk args; } while (0) | |
| 27 | −#define BRCMF_INFO(args) do {if (brcmf_msg_level & BRCMF_INFO_VAL) \ | |
| 28 | − printk args; } while (0) | |
| 29 | −#define BRCMF_DATA(args) do {if (brcmf_msg_level & BRCMF_DATA_VAL) \ | |
| 30 | − printk args; } while (0) | |
| 31 | −#define BRCMF_CTL(args) do {if (brcmf_msg_level & BRCMF_CTL_VAL) \ | |
| 32 | − printk args; } while (0) | |
| 33 | −#define BRCMF_TIMER(args) do {if (brcmf_msg_level & BRCMF_TIMER_VAL) \ | |
| 34 | − printk args; } while (0) | |
| 35 | −#define BRCMF_INTR(args) do {if (brcmf_msg_level & BRCMF_INTR_VAL) \ | |
| 36 | − printk args; } while (0) | |
| 37 | −#define BRCMF_GLOM(args) do {if (brcmf_msg_level & BRCMF_GLOM_VAL) \ | |
| 38 | − printk args; } while (0) | |
| 39 | −#define BRCMF_EVENT(args) do {if (brcmf_msg_level & BRCMF_EVENT_VAL) \ | |
| 40 | − printk args; } while (0) | |
| 41 | − | |
| 42 | −#define BRCMF_DATA_ON() (brcmf_msg_level & BRCMF_DATA_VAL) | |
| 43 | −#define BRCMF_CTL_ON() (brcmf_msg_level & BRCMF_CTL_VAL) | |
| 44 | −#define BRCMF_HDRS_ON() (brcmf_msg_level & BRCMF_HDRS_VAL) | |
| 45 | −#define BRCMF_BYTES_ON() (brcmf_msg_level & BRCMF_BYTES_VAL) | |
| 46 | −#define BRCMF_GLOM_ON() (brcmf_msg_level & BRCMF_GLOM_VAL) | |
| 47 | − | |
| 48 | −#else /* (defined BCMDBG) || (defined BCMDBG) */ | |
| 49 | − | |
| 50 | −#define BRCMF_ERROR(args) do {if (net_ratelimit()) printk args; } while (0) | |
| 51 | −#define BRCMF_TRACE(args) | |
| 52 | −#define BRCMF_INFO(args) | |
| 53 | −#define BRCMF_DATA(args) | |
| 54 | −#define BRCMF_CTL(args) | |
| 55 | −#define BRCMF_TIMER(args) | |
| 56 | −#define BRCMF_INTR(args) | |
| 57 | −#define BRCMF_GLOM(args) | |
| 58 | −#define BRCMF_EVENT(args) | |
| 59 | − | |
| 60 | −#define BRCMF_DATA_ON() 0 | |
| 61 | −#define BRCMF_CTL_ON() 0 | |
| 62 | −#define BRCMF_HDRS_ON() 0 | |
| 63 | −#define BRCMF_BYTES_ON() 0 | |
| 64 | −#define BRCMF_GLOM_ON() 0 | |
| 65 | − | |
| 66 | −#endif /* defined(BCMDBG) */ | |
| 67 | − | |
| 68 | −extern int brcmf_msg_level; | |
| 69 | − | |
| 70 | −#endif /* _BRCMF_DBG_H_ */ | |
| @@ -1,1736 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * Copyright (c) 2010 Broadcom Corporation | |
| 3 | − * | |
| 4 | − * Permission to use, copy, modify, and/or distribute this software for any | |
| 5 | − * purpose with or without fee is hereby granted, provided that the above | |
| 6 | − * copyright notice and this permission notice appear in all copies. | |
| 7 | − * | |
| 8 | − * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
| 9 | − * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
| 10 | − * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
| 11 | − * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 12 | − * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | |
| 13 | − * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
| 14 | − * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
| 15 | − */ | |
| 16 | − | |
| 17 | −#include <linux/init.h> | |
| 18 | −#include <linux/kernel.h> | |
| 19 | −#include <linux/kthread.h> | |
| 20 | −#include <linux/slab.h> | |
| 21 | −#include <linux/skbuff.h> | |
| 22 | −#include <linux/netdevice.h> | |
| 23 | −#include <linux/etherdevice.h> | |
| 24 | −#include <linux/mmc/sdio_func.h> | |
| 25 | −#include <linux/random.h> | |
| 26 | −#include <linux/spinlock.h> | |
| 27 | −#include <linux/ethtool.h> | |
| 28 | −#include <linux/fcntl.h> | |
| 29 | −#include <linux/fs.h> | |
| 30 | −#include <linux/uaccess.h> | |
| 31 | −#include <linux/interrupt.h> | |
| 32 | −#include <linux/hardirq.h> | |
| 33 | −#include <net/cfg80211.h> | |
| 34 | −#include <defs.h> | |
| 35 | −#include <brcmu_utils.h> | |
| 36 | −#include <brcmu_wifi.h> | |
| 37 | − | |
| 38 | −#include "dhd.h" | |
| 39 | −#include "dhd_bus.h" | |
| 40 | −#include "dhd_proto.h" | |
| 41 | −#include "dhd_dbg.h" | |
| 42 | −#include "wl_cfg80211.h" | |
| 43 | −#include "bcmchip.h" | |
| 44 | − | |
| 45 | −#if defined(CONFIG_PM_SLEEP) | |
| 46 | −#include <linux/suspend.h> | |
| 47 | −atomic_t brcmf_mmc_suspend; | |
| 48 | −#endif /* defined(CONFIG_PM_SLEEP) */ | |
| 49 | − | |
| 50 | −MODULE_AUTHOR("Broadcom Corporation"); | |
| 51 | −MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver."); | |
| 52 | −MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards"); | |
| 53 | −MODULE_LICENSE("Dual BSD/GPL"); | |
| 54 | − | |
| 55 | − | |
| 56 | −/* Interface control information */ | |
| 57 | −struct brcmf_if { | |
| 58 | − struct brcmf_info *info; /* back pointer to brcmf_info */ | |
| 59 | − /* OS/stack specifics */ | |
| 60 | − struct net_device *net; | |
| 61 | − struct net_device_stats stats; | |
| 62 | − int idx; /* iface idx in dongle */ | |
| 63 | − int state; /* interface state */ | |
| 64 | − uint subunit; /* subunit */ | |
| 65 | − u8 mac_addr[ETH_ALEN]; /* assigned MAC address */ | |
| 66 | − bool attached; /* Delayed attachment when unset */ | |
| 67 | − bool txflowcontrol; /* Per interface flow control indicator */ | |
| 68 | − char name[IFNAMSIZ]; /* linux interface name */ | |
| 69 | −}; | |
| 70 | − | |
| 71 | −/* Local private structure (extension of pub) */ | |
| 72 | −struct brcmf_info { | |
| 73 | − struct brcmf_pub pub; | |
| 74 | − | |
| 75 | − /* OS/stack specifics */ | |
| 76 | − struct brcmf_if *iflist[BRCMF_MAX_IFS]; | |
| 77 | − | |
| 78 | − struct semaphore proto_sem; | |
| 79 | − wait_queue_head_t ioctl_resp_wait; | |
| 80 | − | |
| 81 | − /* Thread to issue ioctl for multicast */ | |
| 82 | − struct task_struct *sysioc_tsk; | |
| 83 | − struct semaphore sysioc_sem; | |
| 84 | − bool set_multicast; | |
| 85 | − bool set_macaddress; | |
| 86 | − u8 macvalue[ETH_ALEN]; | |
| 87 | − atomic_t pend_8021x_cnt; | |
| 88 | −}; | |
| 89 | − | |
| 90 | −/* Error bits */ | |
| 91 | −module_param(brcmf_msg_level, int, 0); | |
| 92 | − | |
| 93 | −/* Spawn a thread for system ioctls (set mac, set mcast) */ | |
| 94 | −uint brcmf_sysioc = true; | |
| 95 | −module_param(brcmf_sysioc, uint, 0); | |
| 96 | − | |
| 97 | −/* ARP offload agent mode : Enable ARP Host Auto-Reply | |
| 98 | −and ARP Peer Auto-Reply */ | |
| 99 | −uint brcmf_arp_mode = 0xb; | |
| 100 | −module_param(brcmf_arp_mode, uint, 0); | |
| 101 | − | |
| 102 | −/* ARP offload enable */ | |
| 103 | −uint brcmf_arp_enable = true; | |
| 104 | −module_param(brcmf_arp_enable, uint, 0); | |
| 105 | − | |
| 106 | −/* Global Pkt filter enable control */ | |
| 107 | −uint brcmf_pkt_filter_enable = true; | |
| 108 | −module_param(brcmf_pkt_filter_enable, uint, 0); | |
| 109 | − | |
| 110 | −/* Pkt filter init setup */ | |
| 111 | −uint brcmf_pkt_filter_init; | |
| 112 | −module_param(brcmf_pkt_filter_init, uint, 0); | |
| 113 | − | |
| 114 | −/* Pkt filter mode control */ | |
| 115 | −uint brcmf_master_mode = true; | |
| 116 | −module_param(brcmf_master_mode, uint, 0); | |
| 117 | − | |
| 118 | −module_param(brcmf_dongle_memsize, int, 0); | |
| 119 | − | |
| 120 | −/* Contorl fw roaming */ | |
| 121 | −uint brcmf_roam = 1; | |
| 122 | − | |
| 123 | −/* Control radio state */ | |
| 124 | −uint brcmf_radio_up = 1; | |
| 125 | − | |
| 126 | −/* Network inteface name */ | |
| 127 | −char iface_name[IFNAMSIZ] = "wlan"; | |
| 128 | −module_param_string(iface_name, iface_name, IFNAMSIZ, 0); | |
| 129 | − | |
| 130 | −/* The following are specific to the SDIO dongle */ | |
| 131 | − | |
| 132 | −/* IOCTL response timeout */ | |
| 133 | −int brcmf_ioctl_timeout_msec = IOCTL_RESP_TIMEOUT; | |
| 134 | − | |
| 135 | −/* Idle timeout for backplane clock */ | |
| 136 | −int brcmf_idletime = BRCMF_IDLETIME_TICKS; | |
| 137 | −module_param(brcmf_idletime, int, 0); | |
| 138 | − | |
| 139 | −/* Use polling */ | |
| 140 | −uint brcmf_poll; | |
| 141 | −module_param(brcmf_poll, uint, 0); | |
| 142 | − | |
| 143 | −/* Use interrupts */ | |
| 144 | −uint brcmf_intr = true; | |
| 145 | −module_param(brcmf_intr, uint, 0); | |
| 146 | − | |
| 147 | −/* SDIO Drive Strength (in milliamps) */ | |
| 148 | −uint brcmf_sdiod_drive_strength = 6; | |
| 149 | −module_param(brcmf_sdiod_drive_strength, uint, 0); | |
| 150 | − | |
| 151 | −/* Tx/Rx bounds */ | |
| 152 | −module_param(brcmf_txbound, uint, 0); | |
| 153 | −module_param(brcmf_rxbound, uint, 0); | |
| 154 | − | |
| 155 | −#ifdef SDTEST | |
| 156 | −/* Echo packet generator (pkts/s) */ | |
| 157 | −uint brcmf_pktgen; | |
| 158 | −module_param(brcmf_pktgen, uint, 0); | |
| 159 | − | |
| 160 | −/* Echo packet len (0 => sawtooth, max 2040) */ | |
| 161 | −uint brcmf_pktgen_len; | |
| 162 | −module_param(brcmf_pktgen_len, uint, 0); | |
| 163 | −#endif | |
| 164 | − | |
| 165 | −static int brcmf_toe_get(struct brcmf_info *drvr_priv, int idx, u32 *toe_ol); | |
| 166 | −static int brcmf_toe_set(struct brcmf_info *drvr_priv, int idx, u32 toe_ol); | |
| 167 | −static int brcmf_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata, | |
| 168 | − struct brcmf_event_msg *event_ptr, | |
| 169 | − void **data_ptr); | |
| 170 | − | |
| 171 | −/* | |
| 172 | − * Generalized timeout mechanism. Uses spin sleep with exponential | |
| 173 | − * back-off until | |
| 174 | − * the sleep time reaches one jiffy, then switches over to task delay. Usage: | |
| 175 | − * | |
| 176 | − * brcmf_timeout_start(&tmo, usec); | |
| 177 | − * while (!brcmf_timeout_expired(&tmo)) | |
| 178 | − * if (poll_something()) | |
| 179 | − * break; | |
| 180 | − * if (brcmf_timeout_expired(&tmo)) | |
| 181 | − * fatal(); | |
| 182 | − */ | |
| 183 | − | |
| 184 | −void brcmf_timeout_start(struct brcmf_timeout *tmo, uint usec) | |
| 185 | −{ | |
| 186 | − tmo->limit = usec; | |
| 187 | − tmo->increment = 0; | |
| 188 | − tmo->elapsed = 0; | |
| 189 | − tmo->tick = 1000000 / HZ; | |
| 190 | −} | |
| 191 | − | |
| 192 | −int brcmf_timeout_expired(struct brcmf_timeout *tmo) | |
| 193 | −{ | |
| 194 | − /* Does nothing the first call */ | |
| 195 | − if (tmo->increment == 0) { | |
| 196 | − tmo->increment = 1; | |
| 197 | − return 0; | |
| 198 | − } | |
| 199 | − | |
| 200 | − if (tmo->elapsed >= tmo->limit) | |
| 201 | − return 1; | |
| 202 | − | |
| 203 | − /* Add the delay that's about to take place */ | |
| 204 | − tmo->elapsed += tmo->increment; | |
| 205 | − | |
| 206 | − if (tmo->increment < tmo->tick) { | |
| 207 | − udelay(tmo->increment); | |
| 208 | − tmo->increment *= 2; | |
| 209 | − if (tmo->increment > tmo->tick) | |
| 210 | − tmo->increment = tmo->tick; | |
| 211 | − } else { | |
| 212 | − wait_queue_head_t delay_wait; | |
| 213 | − DECLARE_WAITQUEUE(wait, current); | |
| 214 | − int pending; | |
| 215 | − init_waitqueue_head(&delay_wait); | |
| 216 | − add_wait_queue(&delay_wait, &wait); | |
| 217 | − set_current_state(TASK_INTERRUPTIBLE); | |
| 218 | − schedule_timeout(1); | |
| 219 | − pending = signal_pending(current); | |
| 220 | − remove_wait_queue(&delay_wait, &wait); | |
| 221 | − set_current_state(TASK_RUNNING); | |
| 222 | − if (pending) | |
| 223 | − return 1; /* Interrupted */ | |
| 224 | − } | |
| 225 | − | |
| 226 | − return 0; | |
| 227 | −} | |
| 228 | − | |
| 229 | −static int brcmf_net2idx(struct brcmf_info *drvr_priv, struct net_device *net) | |
| 230 | −{ | |
| 231 | − int i = 0; | |
| 232 | − | |
| 233 | − while (i < BRCMF_MAX_IFS) { | |
| 234 | − if (drvr_priv->iflist[i] && (drvr_priv->iflist[i]->net == net)) | |
| 235 | − return i; | |
| 236 | − i++; | |
| 237 | − } | |
| 238 | − | |
| 239 | − return BRCMF_BAD_IF; | |
| 240 | −} | |
| 241 | − | |
| 242 | −int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name) | |
| 243 | −{ | |
| 244 | − int i = BRCMF_MAX_IFS; | |
| 245 | − | |
| 246 | − if (name == NULL || *name == '\0') | |
| 247 | − return 0; | |
| 248 | − | |
| 249 | − while (--i > 0) | |
| 250 | − if (drvr_priv->iflist[i] | |
| 251 | − && !strncmp(drvr_priv->iflist[i]->name, name, IFNAMSIZ)) | |
| 252 | − break; | |
| 253 | − | |
| 254 | − BRCMF_TRACE(("%s: return idx %d for \"%s\"\n", __func__, i, name)); | |
| 255 | − | |
| 256 | − return i; /* default - the primary interface */ | |
| 257 | −} | |
| 258 | − | |
| 259 | −char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) | |
| 260 | −{ | |
| 261 | − struct brcmf_info *drvr_priv = drvr->info; | |
| 262 | − | |
| 263 | − if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) { | |
| 264 | − BRCMF_ERROR(("%s: ifidx %d out of range\n", __func__, ifidx)); | |
| 265 | − return "<if_bad>"; | |
| 266 | − } | |
| 267 | − | |
| 268 | − if (drvr_priv->iflist[ifidx] == NULL) { | |
| 269 | − BRCMF_ERROR(("%s: null i/f %d\n", __func__, ifidx)); | |
| 270 | − return "<if_null>"; | |
| 271 | − } | |
| 272 | − | |
| 273 | − if (drvr_priv->iflist[ifidx]->net) | |
| 274 | − return drvr_priv->iflist[ifidx]->net->name; | |
| 275 | − | |
| 276 | − return "<if_none>"; | |
| 277 | −} | |
| 278 | − | |
| 279 | −static void _brcmf_set_multicast_list(struct brcmf_info *drvr_priv, int ifidx) | |
| 280 | −{ | |
| 281 | − struct net_device *dev; | |
| 282 | − struct netdev_hw_addr *ha; | |
| 283 | − u32 allmulti, cnt; | |
| 284 | − | |
| 285 | − struct brcmf_ioctl ioc; | |
| 286 | − char *buf, *bufp; | |
| 287 | − uint buflen; | |
| 288 | − int ret; | |
| 289 | − | |
| 290 | − dev = drvr_priv->iflist[ifidx]->net; | |
| 291 | − cnt = netdev_mc_count(dev); | |
| 292 | − | |
| 293 | − /* Determine initial value of allmulti flag */ | |
| 294 | − allmulti = (dev->flags & IFF_ALLMULTI) ? true : false; | |
| 295 | − | |
| 296 | − /* Send down the multicast list first. */ | |
| 297 | − | |
| 298 | − buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN); | |
| 299 | − bufp = buf = kmalloc(buflen, GFP_ATOMIC); | |
| 300 | − if (!bufp) { | |
| 301 | − BRCMF_ERROR(("%s: out of memory for mcast_list, cnt %d\n", | |
| 302 | − brcmf_ifname(&drvr_priv->pub, ifidx), cnt)); | |
| 303 | − return; | |
| 304 | − } | |
| 305 | − | |
| 306 | − strcpy(bufp, "mcast_list"); | |
| 307 | − bufp += strlen("mcast_list") + 1; | |
| 308 | − | |
| 309 | − cnt = cpu_to_le32(cnt); | |
| 310 | − memcpy(bufp, &cnt, sizeof(cnt)); | |
| 311 | − bufp += sizeof(cnt); | |
| 312 | − | |
| 313 | − netdev_for_each_mc_addr(ha, dev) { | |
| 314 | − if (!cnt) | |
| 315 | − break; | |
| 316 | − memcpy(bufp, ha->addr, ETH_ALEN); | |
| 317 | − bufp += ETH_ALEN; | |
| 318 | − cnt--; | |
| 319 | − } | |
| 320 | − | |
| 321 | − memset(&ioc, 0, sizeof(ioc)); | |
| 322 | − ioc.cmd = BRCMF_C_SET_VAR; | |
| 323 | − ioc.buf = buf; | |
| 324 | − ioc.len = buflen; | |
| 325 | − ioc.set = true; | |
| 326 | − | |
| 327 | − ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len); | |
| 328 | − if (ret < 0) { | |
| 329 | − BRCMF_ERROR(("%s: set mcast_list failed, cnt %d\n", | |
| 330 | − brcmf_ifname(&drvr_priv->pub, ifidx), cnt)); | |
| 331 | − allmulti = cnt ? true : allmulti; | |
| 332 | − } | |
| 333 | − | |
| 334 | − kfree(buf); | |
| 335 | − | |
| 336 | − /* Now send the allmulti setting. This is based on the setting in the | |
| 337 | − * net_device flags, but might be modified above to be turned on if we | |
| 338 | − * were trying to set some addresses and dongle rejected it... | |
| 339 | − */ | |
| 340 | − | |
| 341 | − buflen = sizeof("allmulti") + sizeof(allmulti); | |
| 342 | − buf = kmalloc(buflen, GFP_ATOMIC); | |
| 343 | − if (!buf) { | |
| 344 | − BRCMF_ERROR(("%s: out of memory for allmulti\n", | |
| 345 | − brcmf_ifname(&drvr_priv->pub, ifidx))); | |
| 346 | − return; | |
| 347 | − } | |
| 348 | − allmulti = cpu_to_le32(allmulti); | |
| 349 | − | |
| 350 | − if (!brcmu_mkiovar | |
| 351 | − ("allmulti", (void *)&allmulti, sizeof(allmulti), buf, buflen)) { | |
| 352 | − BRCMF_ERROR(("%s: mkiovar failed for allmulti, datalen %d " | |
| 353 | − "buflen %u\n", | |
| 354 | − brcmf_ifname(&drvr_priv->pub, ifidx), | |
| 355 | − (int)sizeof(allmulti), buflen)); | |
| 356 | − kfree(buf); | |
| 357 | − return; | |
| 358 | − } | |
| 359 | − | |
| 360 | − memset(&ioc, 0, sizeof(ioc)); | |
| 361 | − ioc.cmd = BRCMF_C_SET_VAR; | |
| 362 | − ioc.buf = buf; | |
| 363 | − ioc.len = buflen; | |
| 364 | − ioc.set = true; | |
| 365 | − | |
| 366 | − ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len); | |
| 367 | − if (ret < 0) { | |
| 368 | − BRCMF_ERROR(("%s: set allmulti %d failed\n", | |
| 369 | − brcmf_ifname(&drvr_priv->pub, ifidx), | |
| 370 | − le32_to_cpu(allmulti))); | |
| 371 | − } | |
| 372 | − | |
| 373 | − kfree(buf); | |
| 374 | − | |
| 375 | − /* Finally, pick up the PROMISC flag as well, like the NIC | |
| 376 | − driver does */ | |
| 377 | − | |
| 378 | − allmulti = (dev->flags & IFF_PROMISC) ? true : false; | |
| 379 | − allmulti = cpu_to_le32(allmulti); | |
| 380 | − | |
| 381 | − memset(&ioc, 0, sizeof(ioc)); | |
| 382 | − ioc.cmd = BRCMF_C_SET_PROMISC; | |
| 383 | − ioc.buf = &allmulti; | |
| 384 | − ioc.len = sizeof(allmulti); | |
| 385 | − ioc.set = true; | |
| 386 | − | |
| 387 | − ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len); | |
| 388 | − if (ret < 0) { | |
| 389 | − BRCMF_ERROR(("%s: set promisc %d failed\n", | |
| 390 | − brcmf_ifname(&drvr_priv->pub, ifidx), | |
| 391 | − le32_to_cpu(allmulti))); | |
| 392 | − } | |
| 393 | −} | |
| 394 | − | |
| 395 | −static int _brcmf_set_mac_address(struct brcmf_info *drvr_priv, int ifidx, u8 *addr) | |
| 396 | −{ | |
| 397 | − char buf[32]; | |
| 398 | − struct brcmf_ioctl ioc; | |
| 399 | − int ret; | |
| 400 | − | |
| 401 | − BRCMF_TRACE(("%s enter\n", __func__)); | |
| 402 | − if (!brcmu_mkiovar | |
| 403 | − ("cur_etheraddr", (char *)addr, ETH_ALEN, buf, 32)) { | |
| 404 | − BRCMF_ERROR(("%s: mkiovar failed for cur_etheraddr\n", | |
| 405 | − brcmf_ifname(&drvr_priv->pub, ifidx))); | |
| 406 | − return -1; | |
| 407 | − } | |
| 408 | − memset(&ioc, 0, sizeof(ioc)); | |
| 409 | − ioc.cmd = BRCMF_C_SET_VAR; | |
| 410 | − ioc.buf = buf; | |
| 411 | − ioc.len = 32; | |
| 412 | − ioc.set = true; | |
| 413 | − | |
| 414 | − ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len); | |
| 415 | − if (ret < 0) { | |
| 416 | − BRCMF_ERROR(("%s: set cur_etheraddr failed\n", | |
| 417 | − brcmf_ifname(&drvr_priv->pub, ifidx))); | |
| 418 | − } else { | |
| 419 | − memcpy(drvr_priv->iflist[ifidx]->net->dev_addr, addr, ETH_ALEN); | |
| 420 | − } | |
| 421 | − | |
| 422 | − return ret; | |
| 423 | −} | |
| 424 | − | |
| 425 | −#ifdef SOFTAP | |
| 426 | −extern struct net_device *ap_net_dev; | |
| 427 | −#endif | |
| 428 | − | |
| 429 | −/* Virtual interfaces only ((ifp && ifp->info && ifp->idx == true) */ | |
| 430 | −static void brcmf_op_if(struct brcmf_if *ifp) | |
| 431 | −{ | |
| 432 | − struct brcmf_info *drvr_priv; | |
| 433 | − int ret = 0, err = 0; | |
| 434 | − | |
| 435 | − drvr_priv = ifp->info; | |
| 436 | − | |
| 437 | − BRCMF_TRACE(("%s: idx %d, state %d\n", __func__, ifp->idx, ifp->state)); | |
| 438 | − | |
| 439 | − switch (ifp->state) { | |
| 440 | − case BRCMF_E_IF_ADD: | |
| 441 | − /* | |
| 442 | − * Delete the existing interface before overwriting it | |
| 443 | − * in case we missed the BRCMF_E_IF_DEL event. | |
| 444 | − */ | |
| 445 | − if (ifp->net != NULL) { | |
| 446 | − BRCMF_ERROR(("%s: ERROR: netdev:%s already exists, " | |
| 447 | − "try free & unregister\n", | |
| 448 | − __func__, ifp->net->name)); | |
| 449 | − netif_stop_queue(ifp->net); | |
| 450 | − unregister_netdev(ifp->net); | |
| 451 | − free_netdev(ifp->net); | |
| 452 | − } | |
| 453 | − /* Allocate etherdev, including space for private structure */ | |
| 454 | − ifp->net = alloc_etherdev(sizeof(drvr_priv)); | |
| 455 | − if (!ifp->net) { | |
| 456 | − BRCMF_ERROR(("%s: OOM - alloc_etherdev\n", __func__)); | |
| 457 | − ret = -ENOMEM; | |
| 458 | − } | |
| 459 | − if (ret == 0) { | |
| 460 | − strcpy(ifp->net->name, ifp->name); | |
| 461 | − memcpy(netdev_priv(ifp->net), &drvr_priv, sizeof(drvr_priv)); | |
| 462 | − err = brcmf_net_attach(&drvr_priv->pub, ifp->idx); | |
| 463 | − if (err != 0) { | |
| 464 | − BRCMF_ERROR(("%s: brcmf_net_attach failed, " | |
| 465 | − "err %d\n", | |
| 466 | − __func__, err)); | |
| 467 | − ret = -EOPNOTSUPP; | |
| 468 | − } else { | |
| 469 | −#ifdef SOFTAP | |
| 470 | − /* semaphore that the soft AP CODE | |
| 471 | − waits on */ | |
| 472 | − extern struct semaphore ap_eth_sema; | |
| 473 | − | |
| 474 | − /* save ptr to wl0.1 netdev for use | |
| 475 | − in wl_iw.c */ | |
| 476 | − ap_net_dev = ifp->net; | |
| 477 | − /* signal to the SOFTAP 'sleeper' thread, | |
| 478 | − wl0.1 is ready */ | |
| 479 | − up(&ap_eth_sema); | |
| 480 | −#endif | |
| 481 | − BRCMF_TRACE(("\n ==== pid:%x, net_device for " | |
| 482 | − "if:%s created ===\n\n", | |
| 483 | − current->pid, ifp->net->name)); | |
| 484 | − ifp->state = 0; | |
| 485 | − } | |
| 486 | − } | |
| 487 | − break; | |
| 488 | − case BRCMF_E_IF_DEL: | |
| 489 | − if (ifp->net != NULL) { | |
| 490 | − BRCMF_TRACE(("\n%s: got 'WLC_E_IF_DEL' state\n", | |
| 491 | − __func__)); | |
| 492 | − netif_stop_queue(ifp->net); | |
| 493 | − unregister_netdev(ifp->net); | |
| 494 | − ret = BRCMF_DEL_IF; /* Make sure the free_netdev() | |
| 495 | − is called */ | |
| 496 | − } | |
| 497 | − break; | |
| 498 | − default: | |
| 499 | − BRCMF_ERROR(("%s: bad op %d\n", __func__, ifp->state)); | |
| 500 | − break; | |
| 501 | − } | |
| 502 | − | |
| 503 | − if (ret < 0) { | |
| 504 | − if (ifp->net) | |
| 505 | − free_netdev(ifp->net); | |
| 506 | − | |
| 507 | − drvr_priv->iflist[ifp->idx] = NULL; | |
| 508 | − kfree(ifp); | |
| 509 | −#ifdef SOFTAP | |
| 510 | − if (ifp->net == ap_net_dev) | |
| 511 | − ap_net_dev = NULL; /* NULL SOFTAP global | |
| 512 | − wl0.1 as well */ | |
| 513 | −#endif /* SOFTAP */ | |
| 514 | − } | |
| 515 | −} | |
| 516 | − | |
| 517 | −static int _brcmf_sysioc_thread(void *data) | |
| 518 | −{ | |
| 519 | − struct brcmf_info *drvr_priv = (struct brcmf_info *) data; | |
| 520 | − int i; | |
| 521 | −#ifdef SOFTAP | |
| 522 | − bool in_ap = false; | |
| 523 | −#endif | |
| 524 | − | |
| 525 | − allow_signal(SIGTERM); | |
| 526 | − | |
| 527 | − while (down_interruptible(&drvr_priv->sysioc_sem) == 0) { | |
| 528 | − if (kthread_should_stop()) | |
| 529 | − break; | |
| 530 | − for (i = 0; i < BRCMF_MAX_IFS; i++) { | |
| 531 | − struct brcmf_if *ifentry = drvr_priv->iflist[i]; | |
| 532 | − if (ifentry) { | |
| 533 | −#ifdef SOFTAP | |
| 534 | − in_ap = (ap_net_dev != NULL); | |
| 535 | −#endif /* SOFTAP */ | |
| 536 | − if (ifentry->state) | |
| 537 | − brcmf_op_if(ifentry); | |
| 538 | −#ifdef SOFTAP | |
| 539 | − if (drvr_priv->iflist[i] == NULL) { | |
| 540 | − BRCMF_TRACE(("\n\n %s: interface %d " | |
| 541 | − "removed!\n", __func__, | |
| 542 | − i)); | |
| 543 | − continue; | |
| 544 | − } | |
| 545 | − | |
| 546 | − if (in_ap && drvr_priv->set_macaddress) { | |
| 547 | − BRCMF_TRACE(("attempt to set MAC for" | |
| 548 | − " %s in AP Mode," | |
| 549 | − " blocked.\n", | |
| 550 | − ifentry->net->name)); | |
| 551 | − drvr_priv->set_macaddress = false; | |
| 552 | − continue; | |
| 553 | − } | |
| 554 | − | |
| 555 | − if (in_ap && drvr_priv->set_multicast) { | |
| 556 | − BRCMF_TRACE(("attempt to set MULTICAST " | |
| 557 | − "list for %s in AP Mode, " | |
| 558 | − "blocked.\n", | |
| 559 | − ifentry->net->name)); | |
| 560 | − drvr_priv->set_multicast = false; | |
| 561 | − continue; | |
| 562 | − } | |
| 563 | −#endif /* SOFTAP */ | |
| 564 | − if (drvr_priv->set_multicast) { | |
| 565 | − drvr_priv->set_multicast = false; | |
| 566 | − _brcmf_set_multicast_list(drvr_priv, i); | |
| 567 | − } | |
| 568 | − if (drvr_priv->set_macaddress) { | |
| 569 | − drvr_priv->set_macaddress = false; | |
| 570 | − _brcmf_set_mac_address(drvr_priv, i, | |
| 571 | − drvr_priv->macvalue); | |
| 572 | − } | |
| 573 | − } | |
| 574 | − } | |
| 575 | − } | |
| 576 | − return 0; | |
| 577 | −} | |
| 578 | − | |
| 579 | −static int brcmf_netdev_set_mac_address(struct net_device *dev, void *addr) | |
| 580 | −{ | |
| 581 | − int ret = 0; | |
| 582 | − | |
| 583 | − struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(dev); | |
| 584 | − struct sockaddr *sa = (struct sockaddr *)addr; | |
| 585 | − int ifidx; | |
| 586 | − | |
| 587 | − ifidx = brcmf_net2idx(drvr_priv, dev); | |
| 588 | − if (ifidx == BRCMF_BAD_IF) | |
| 589 | − return -1; | |
| 590 | − | |
| 591 | − memcpy(&drvr_priv->macvalue, sa->sa_data, ETH_ALEN); | |
| 592 | − drvr_priv->set_macaddress = true; | |
| 593 | − up(&drvr_priv->sysioc_sem); | |
| 594 | − | |
| 595 | − return ret; | |
| 596 | −} | |
| 597 | − | |
| 598 | −static void brcmf_netdev_set_multicast_list(struct net_device *dev) | |
| 599 | −{ | |
| 600 | − struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(dev); | |
| 601 | − int ifidx; | |
| 602 | − | |
| 603 | − ifidx = brcmf_net2idx(drvr_priv, dev); | |
| 604 | − if (ifidx == BRCMF_BAD_IF) | |
| 605 | − return; | |
| 606 | − | |
| 607 | − drvr_priv->set_multicast = true; | |
| 608 | − up(&drvr_priv->sysioc_sem); | |
| 609 | −} | |
| 610 | − | |
| 611 | −int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf) | |
| 612 | −{ | |
| 613 | − struct brcmf_info *drvr_priv = drvr->info; | |
| 614 | − | |
| 615 | − /* Reject if down */ | |
| 616 | − if (!drvr->up || (drvr->busstate == BRCMF_BUS_DOWN)) | |
| 617 | − return -ENODEV; | |
| 618 | − | |
| 619 | − /* Update multicast statistic */ | |
| 620 | − if (pktbuf->len >= ETH_ALEN) { | |
| 621 | − u8 *pktdata = (u8 *) (pktbuf->data); | |
| 622 | − struct ethhdr *eh = (struct ethhdr *)pktdata; | |
| 623 | − | |
| 624 | − if (is_multicast_ether_addr(eh->h_dest)) | |
| 625 | − drvr->tx_multicast++; | |
| 626 | − if (ntohs(eh->h_proto) == ETH_P_PAE) | |
| 627 | − atomic_inc(&drvr_priv->pend_8021x_cnt); | |
| 628 | − } | |
| 629 | − | |
| 630 | − /* If the protocol uses a data header, apply it */ | |
| 631 | − brcmf_proto_hdrpush(drvr, ifidx, pktbuf); | |
| 632 | − | |
| 633 | − /* Use bus module to send data frame */ | |
| 634 | − return brcmf_sdbrcm_bus_txdata(drvr->bus, pktbuf); | |
| 635 | −} | |
| 636 | − | |
| 637 | −static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *net) | |
| 638 | −{ | |
| 639 | − int ret; | |
| 640 | − struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net); | |
| 641 | − int ifidx; | |
| 642 | − | |
| 643 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 644 | − | |
| 645 | − /* Reject if down */ | |
| 646 | − if (!drvr_priv->pub.up || (drvr_priv->pub.busstate == BRCMF_BUS_DOWN)) { | |
| 647 | − BRCMF_ERROR(("%s: xmit rejected pub.up=%d busstate=%d\n", | |
| 648 | − __func__, drvr_priv->pub.up, | |
| 649 | − drvr_priv->pub.busstate)); | |
| 650 | − netif_stop_queue(net); | |
| 651 | − return -ENODEV; | |
| 652 | − } | |
| 653 | − | |
| 654 | − ifidx = brcmf_net2idx(drvr_priv, net); | |
| 655 | − if (ifidx == BRCMF_BAD_IF) { | |
| 656 | − BRCMF_ERROR(("%s: bad ifidx %d\n", __func__, ifidx)); | |
| 657 | − netif_stop_queue(net); | |
| 658 | − return -ENODEV; | |
| 659 | − } | |
| 660 | − | |
| 661 | − /* Make sure there's enough room for any header */ | |
| 662 | − if (skb_headroom(skb) < drvr_priv->pub.hdrlen) { | |
| 663 | − struct sk_buff *skb2; | |
| 664 | − | |
| 665 | − BRCMF_INFO(("%s: insufficient headroom\n", | |
| 666 | − brcmf_ifname(&drvr_priv->pub, ifidx))); | |
| 667 | − drvr_priv->pub.tx_realloc++; | |
| 668 | − skb2 = skb_realloc_headroom(skb, drvr_priv->pub.hdrlen); | |
| 669 | − dev_kfree_skb(skb); | |
| 670 | − skb = skb2; | |
| 671 | − if (skb == NULL) { | |
| 672 | − BRCMF_ERROR(("%s: skb_realloc_headroom failed\n", | |
| 673 | − brcmf_ifname(&drvr_priv->pub, ifidx))); | |
| 674 | − ret = -ENOMEM; | |
| 675 | − goto done; | |
| 676 | − } | |
| 677 | − } | |
| 678 | − | |
| 679 | − ret = brcmf_sendpkt(&drvr_priv->pub, ifidx, skb); | |
| 680 | − | |
| 681 | −done: | |
| 682 | − if (ret) | |
| 683 | − drvr_priv->pub.dstats.tx_dropped++; | |
| 684 | − else | |
| 685 | − drvr_priv->pub.tx_packets++; | |
| 686 | − | |
| 687 | − /* Return ok: we always eat the packet */ | |
| 688 | − return 0; | |
| 689 | −} | |
| 690 | − | |
| 691 | −void brcmf_txflowcontrol(struct brcmf_pub *drvr, int ifidx, bool state) | |
| 692 | −{ | |
| 693 | − struct net_device *net; | |
| 694 | − struct brcmf_info *drvr_priv = drvr->info; | |
| 695 | − | |
| 696 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 697 | − | |
| 698 | − drvr->txoff = state; | |
| 699 | − net = drvr_priv->iflist[ifidx]->net; | |
| 700 | − if (state == ON) | |
| 701 | − netif_stop_queue(net); | |
| 702 | − else | |
| 703 | − netif_wake_queue(net); | |
| 704 | −} | |
| 705 | − | |
| 706 | −void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, struct sk_buff *skb, | |
| 707 | − int numpkt) | |
| 708 | −{ | |
| 709 | − struct brcmf_info *drvr_priv = drvr->info; | |
| 710 | − unsigned char *eth; | |
| 711 | − uint len; | |
| 712 | − void *data; | |
| 713 | − struct sk_buff *pnext, *save_pktbuf; | |
| 714 | − int i; | |
| 715 | − struct brcmf_if *ifp; | |
| 716 | − struct brcmf_event_msg event; | |
| 717 | − | |
| 718 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 719 | − | |
| 720 | − save_pktbuf = skb; | |
| 721 | − | |
| 722 | − for (i = 0; skb && i < numpkt; i++, skb = pnext) { | |
| 723 | − | |
| 724 | − pnext = skb->next; | |
| 725 | − skb->next = NULL; | |
| 726 | − | |
| 727 | − /* Get the protocol, maintain skb around eth_type_trans() | |
| 728 | − * The main reason for this hack is for the limitation of | |
| 729 | − * Linux 2.4 where 'eth_type_trans' uses the | |
| 730 | − * 'net->hard_header_len' | |
| 731 | − * to perform skb_pull inside vs ETH_HLEN. Since to avoid | |
| 732 | − * coping of the packet coming from the network stack to add | |
| 733 | − * BDC, Hardware header etc, during network interface | |
| 734 | − * registration | |
| 735 | − * we set the 'net->hard_header_len' to ETH_HLEN + extra space | |
| 736 | − * required | |
| 737 | − * for BDC, Hardware header etc. and not just the ETH_HLEN | |
| 738 | − */ | |
| 739 | − eth = skb->data; | |
| 740 | − len = skb->len; | |
| 741 | − | |
| 742 | − ifp = drvr_priv->iflist[ifidx]; | |
| 743 | − if (ifp == NULL) | |
| 744 | − ifp = drvr_priv->iflist[0]; | |
| 745 | − | |
| 746 | − skb->dev = ifp->net; | |
| 747 | − skb->protocol = eth_type_trans(skb, skb->dev); | |
| 748 | − | |
| 749 | − if (skb->pkt_type == PACKET_MULTICAST) | |
| 750 | − drvr_priv->pub.rx_multicast++; | |
| 751 | − | |
| 752 | − skb->data = eth; | |
| 753 | − skb->len = len; | |
| 754 | − | |
| 755 | − /* Strip header, count, deliver upward */ | |
| 756 | − skb_pull(skb, ETH_HLEN); | |
| 757 | − | |
| 758 | − /* Process special event packets and then discard them */ | |
| 759 | − if (ntohs(skb->protocol) == ETH_P_LINK_CTL) | |
| 760 | − brcmf_host_event(drvr_priv, &ifidx, | |
| 761 | − skb_mac_header(skb), | |
| 762 | − &event, &data); | |
| 763 | − | |
| 764 | − if (drvr_priv->iflist[ifidx] && | |
| 765 | − !drvr_priv->iflist[ifidx]->state) | |
| 766 | − ifp = drvr_priv->iflist[ifidx]; | |
| 767 | − | |
| 768 | − if (ifp->net) | |
| 769 | − ifp->net->last_rx = jiffies; | |
| 770 | − | |
| 771 | − drvr->dstats.rx_bytes += skb->len; | |
| 772 | − drvr->rx_packets++; /* Local count */ | |
| 773 | − | |
| 774 | − if (in_interrupt()) { | |
| 775 | − netif_rx(skb); | |
| 776 | − } else { | |
| 777 | − /* If the receive is not processed inside an ISR, | |
| 778 | − * the softirqd must be woken explicitly to service | |
| 779 | − * the NET_RX_SOFTIRQ. In 2.6 kernels, this is handled | |
| 780 | − * by netif_rx_ni(), but in earlier kernels, we need | |
| 781 | − * to do it manually. | |
| 782 | − */ | |
| 783 | − netif_rx_ni(skb); | |
| 784 | − } | |
| 785 | − } | |
| 786 | −} | |
| 787 | − | |
| 788 | −void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp, bool success) | |
| 789 | −{ | |
| 790 | − uint ifidx; | |
| 791 | − struct brcmf_info *drvr_priv = drvr->info; | |
| 792 | − struct ethhdr *eh; | |
| 793 | − u16 type; | |
| 794 | − | |
| 795 | − brcmf_proto_hdrpull(drvr, &ifidx, txp); | |
| 796 | − | |
| 797 | − eh = (struct ethhdr *)(txp->data); | |
| 798 | − type = ntohs(eh->h_proto); | |
| 799 | − | |
| 800 | − if (type == ETH_P_PAE) | |
| 801 | − atomic_dec(&drvr_priv->pend_8021x_cnt); | |
| 802 | − | |
| 803 | −} | |
| 804 | − | |
| 805 | −static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *net) | |
| 806 | −{ | |
| 807 | − struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net); | |
| 808 | − struct brcmf_if *ifp; | |
| 809 | − int ifidx; | |
| 810 | − | |
| 811 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 812 | − | |
| 813 | − ifidx = brcmf_net2idx(drvr_priv, net); | |
| 814 | − if (ifidx == BRCMF_BAD_IF) | |
| 815 | − return NULL; | |
| 816 | − | |
| 817 | − ifp = drvr_priv->iflist[ifidx]; | |
| 818 | − | |
| 819 | − if (drvr_priv->pub.up) { | |
| 820 | − /* Use the protocol to get dongle stats */ | |
| 821 | − brcmf_proto_dstats(&drvr_priv->pub); | |
| 822 | − } | |
| 823 | − | |
| 824 | − /* Copy dongle stats to net device stats */ | |
| 825 | − ifp->stats.rx_packets = drvr_priv->pub.dstats.rx_packets; | |
| 826 | − ifp->stats.tx_packets = drvr_priv->pub.dstats.tx_packets; | |
| 827 | − ifp->stats.rx_bytes = drvr_priv->pub.dstats.rx_bytes; | |
| 828 | − ifp->stats.tx_bytes = drvr_priv->pub.dstats.tx_bytes; | |
| 829 | − ifp->stats.rx_errors = drvr_priv->pub.dstats.rx_errors; | |
| 830 | − ifp->stats.tx_errors = drvr_priv->pub.dstats.tx_errors; | |
| 831 | − ifp->stats.rx_dropped = drvr_priv->pub.dstats.rx_dropped; | |
| 832 | − ifp->stats.tx_dropped = drvr_priv->pub.dstats.tx_dropped; | |
| 833 | − ifp->stats.multicast = drvr_priv->pub.dstats.multicast; | |
| 834 | − | |
| 835 | − return &ifp->stats; | |
| 836 | −} | |
| 837 | − | |
| 838 | −/* Retrieve current toe component enables, which are kept | |
| 839 | − as a bitmap in toe_ol iovar */ | |
| 840 | −static int brcmf_toe_get(struct brcmf_info *drvr_priv, int ifidx, u32 *toe_ol) | |
| 841 | −{ | |
| 842 | − struct brcmf_ioctl ioc; | |
| 843 | − char buf[32]; | |
| 844 | − int ret; | |
| 845 | − | |
| 846 | − memset(&ioc, 0, sizeof(ioc)); | |
| 847 | − | |
| 848 | − ioc.cmd = BRCMF_C_GET_VAR; | |
| 849 | − ioc.buf = buf; | |
| 850 | − ioc.len = (uint) sizeof(buf); | |
| 851 | − ioc.set = false; | |
| 852 | − | |
| 853 | − strcpy(buf, "toe_ol"); | |
| 854 | − ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len); | |
| 855 | − if (ret < 0) { | |
| 856 | − /* Check for older dongle image that doesn't support toe_ol */ | |
| 857 | − if (ret == -EIO) { | |
| 858 | − BRCMF_ERROR(("%s: toe not supported by device\n", | |
| 859 | − brcmf_ifname(&drvr_priv->pub, ifidx))); | |
| 860 | − return -EOPNOTSUPP; | |
| 861 | − } | |
| 862 | − | |
| 863 | − BRCMF_INFO(("%s: could not get toe_ol: ret=%d\n", | |
| 864 | − brcmf_ifname(&drvr_priv->pub, ifidx), ret)); | |
| 865 | − return ret; | |
| 866 | − } | |
| 867 | − | |
| 868 | − memcpy(toe_ol, buf, sizeof(u32)); | |
| 869 | − return 0; | |
| 870 | −} | |
| 871 | − | |
| 872 | −/* Set current toe component enables in toe_ol iovar, | |
| 873 | − and set toe global enable iovar */ | |
| 874 | −static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol) | |
| 875 | −{ | |
| 876 | − struct brcmf_ioctl ioc; | |
| 877 | − char buf[32]; | |
| 878 | − int toe, ret; | |
| 879 | − | |
| 880 | − memset(&ioc, 0, sizeof(ioc)); | |
| 881 | − | |
| 882 | − ioc.cmd = BRCMF_C_SET_VAR; | |
| 883 | − ioc.buf = buf; | |
| 884 | − ioc.len = (uint) sizeof(buf); | |
| 885 | − ioc.set = true; | |
| 886 | − | |
| 887 | − /* Set toe_ol as requested */ | |
| 888 | − | |
| 889 | − strcpy(buf, "toe_ol"); | |
| 890 | − memcpy(&buf[sizeof("toe_ol")], &toe_ol, sizeof(u32)); | |
| 891 | − | |
| 892 | − ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len); | |
| 893 | − if (ret < 0) { | |
| 894 | − BRCMF_ERROR(("%s: could not set toe_ol: ret=%d\n", | |
| 895 | − brcmf_ifname(&drvr_priv->pub, ifidx), ret)); | |
| 896 | − return ret; | |
| 897 | − } | |
| 898 | − | |
| 899 | − /* Enable toe globally only if any components are enabled. */ | |
| 900 | − | |
| 901 | − toe = (toe_ol != 0); | |
| 902 | − | |
| 903 | − strcpy(buf, "toe"); | |
| 904 | − memcpy(&buf[sizeof("toe")], &toe, sizeof(u32)); | |
| 905 | − | |
| 906 | − ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len); | |
| 907 | − if (ret < 0) { | |
| 908 | − BRCMF_ERROR(("%s: could not set toe: ret=%d\n", | |
| 909 | − brcmf_ifname(&drvr_priv->pub, ifidx), ret)); | |
| 910 | − return ret; | |
| 911 | − } | |
| 912 | − | |
| 913 | − return 0; | |
| 914 | −} | |
| 915 | − | |
| 916 | −static void brcmf_ethtool_get_drvinfo(struct net_device *net, | |
| 917 | − struct ethtool_drvinfo *info) | |
| 918 | −{ | |
| 919 | − struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net); | |
| 920 | − | |
| 921 | − sprintf(info->driver, KBUILD_MODNAME); | |
| 922 | − sprintf(info->version, "%lu", drvr_priv->pub.drv_version); | |
| 923 | − sprintf(info->fw_version, "%s", BCM4329_FW_NAME); | |
| 924 | − sprintf(info->bus_info, "%s", | |
| 925 | − dev_name(&brcmf_cfg80211_get_sdio_func()->dev)); | |
| 926 | −} | |
| 927 | − | |
| 928 | −struct ethtool_ops brcmf_ethtool_ops = { | |
| 929 | − .get_drvinfo = brcmf_ethtool_get_drvinfo | |
| 930 | −}; | |
| 931 | − | |
| 932 | −static int brcmf_ethtool(struct brcmf_info *drvr_priv, void *uaddr) | |
| 933 | −{ | |
| 934 | − struct ethtool_drvinfo info; | |
| 935 | − char drvname[sizeof(info.driver)]; | |
| 936 | − u32 cmd; | |
| 937 | − struct ethtool_value edata; | |
| 938 | − u32 toe_cmpnt, csum_dir; | |
| 939 | − int ret; | |
| 940 | − | |
| 941 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 942 | − | |
| 943 | − /* all ethtool calls start with a cmd word */ | |
| 944 | − if (copy_from_user(&cmd, uaddr, sizeof(u32))) | |
| 945 | − return -EFAULT; | |
| 946 | − | |
| 947 | − switch (cmd) { | |
| 948 | − case ETHTOOL_GDRVINFO: | |
| 949 | − /* Copy out any request driver name */ | |
| 950 | − if (copy_from_user(&info, uaddr, sizeof(info))) | |
| 951 | − return -EFAULT; | |
| 952 | − strncpy(drvname, info.driver, sizeof(info.driver)); | |
| 953 | − drvname[sizeof(info.driver) - 1] = '\0'; | |
| 954 | − | |
| 955 | − /* clear struct for return */ | |
| 956 | − memset(&info, 0, sizeof(info)); | |
| 957 | − info.cmd = cmd; | |
| 958 | − | |
| 959 | − /* if requested, identify ourselves */ | |
| 960 | − if (strcmp(drvname, "?dhd") == 0) { | |
| 961 | − sprintf(info.driver, "dhd"); | |
| 962 | − strcpy(info.version, BRCMF_VERSION_STR); | |
| 963 | − } | |
| 964 | − | |
| 965 | − /* otherwise, require dongle to be up */ | |
| 966 | − else if (!drvr_priv->pub.up) { | |
| 967 | − BRCMF_ERROR(("%s: dongle is not up\n", __func__)); | |
| 968 | − return -ENODEV; | |
| 969 | − } | |
| 970 | − | |
| 971 | − /* finally, report dongle driver type */ | |
| 972 | − else if (drvr_priv->pub.iswl) | |
| 973 | − sprintf(info.driver, "wl"); | |
| 974 | − else | |
| 975 | − sprintf(info.driver, "xx"); | |
| 976 | − | |
| 977 | − sprintf(info.version, "%lu", drvr_priv->pub.drv_version); | |
| 978 | − if (copy_to_user(uaddr, &info, sizeof(info))) | |
| 979 | − return -EFAULT; | |
| 980 | − BRCMF_CTL(("%s: given %*s, returning %s\n", __func__, | |
| 981 | − (int)sizeof(drvname), drvname, info.driver)); | |
| 982 | − break; | |
| 983 | − | |
| 984 | − /* Get toe offload components from dongle */ | |
| 985 | − case ETHTOOL_GRXCSUM: | |
| 986 | − case ETHTOOL_GTXCSUM: | |
| 987 | − ret = brcmf_toe_get(drvr_priv, 0, &toe_cmpnt); | |
| 988 | − if (ret < 0) | |
| 989 | − return ret; | |
| 990 | − | |
| 991 | − csum_dir = | |
| 992 | − (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL; | |
| 993 | − | |
| 994 | − edata.cmd = cmd; | |
| 995 | − edata.data = (toe_cmpnt & csum_dir) ? 1 : 0; | |
| 996 | − | |
| 997 | − if (copy_to_user(uaddr, &edata, sizeof(edata))) | |
| 998 | − return -EFAULT; | |
| 999 | − break; | |
| 1000 | − | |
| 1001 | − /* Set toe offload components in dongle */ | |
| 1002 | − case ETHTOOL_SRXCSUM: | |
| 1003 | − case ETHTOOL_STXCSUM: | |
| 1004 | − if (copy_from_user(&edata, uaddr, sizeof(edata))) | |
| 1005 | − return -EFAULT; | |
| 1006 | − | |
| 1007 | − /* Read the current settings, update and write back */ | |
| 1008 | − ret = brcmf_toe_get(drvr_priv, 0, &toe_cmpnt); | |
| 1009 | − if (ret < 0) | |
| 1010 | − return ret; | |
| 1011 | − | |
| 1012 | − csum_dir = | |
| 1013 | − (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL; | |
| 1014 | − | |
| 1015 | − if (edata.data != 0) | |
| 1016 | − toe_cmpnt |= csum_dir; | |
| 1017 | − else | |
| 1018 | − toe_cmpnt &= ~csum_dir; | |
| 1019 | − | |
| 1020 | − ret = brcmf_toe_set(drvr_priv, 0, toe_cmpnt); | |
| 1021 | − if (ret < 0) | |
| 1022 | − return ret; | |
| 1023 | − | |
| 1024 | − /* If setting TX checksum mode, tell Linux the new mode */ | |
| 1025 | − if (cmd == ETHTOOL_STXCSUM) { | |
| 1026 | − if (edata.data) | |
| 1027 | − drvr_priv->iflist[0]->net->features |= | |
| 1028 | − NETIF_F_IP_CSUM; | |
| 1029 | − else | |
| 1030 | − drvr_priv->iflist[0]->net->features &= | |
| 1031 | − ~NETIF_F_IP_CSUM; | |
| 1032 | − } | |
| 1033 | − | |
| 1034 | − break; | |
| 1035 | − | |
| 1036 | − default: | |
| 1037 | − return -EOPNOTSUPP; | |
| 1038 | − } | |
| 1039 | − | |
| 1040 | − return 0; | |
| 1041 | −} | |
| 1042 | − | |
| 1043 | −static int brcmf_netdev_ioctl_entry(struct net_device *net, struct ifreq *ifr, | |
| 1044 | − int cmd) | |
| 1045 | −{ | |
| 1046 | − struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net); | |
| 1047 | − struct brcmf_c_ioctl ioc; | |
| 1048 | − int bcmerror = 0; | |
| 1049 | − int buflen = 0; | |
| 1050 | − void *buf = NULL; | |
| 1051 | − uint driver = 0; | |
| 1052 | − int ifidx; | |
| 1053 | − bool is_set_key_cmd; | |
| 1054 | − | |
| 1055 | − ifidx = brcmf_net2idx(drvr_priv, net); | |
| 1056 | − BRCMF_TRACE(("%s: ifidx %d, cmd 0x%04x\n", __func__, ifidx, cmd)); | |
| 1057 | − | |
| 1058 | − if (ifidx == BRCMF_BAD_IF) | |
| 1059 | − return -1; | |
| 1060 | − | |
| 1061 | − if (cmd == SIOCETHTOOL) | |
| 1062 | − return brcmf_ethtool(drvr_priv, (void *)ifr->ifr_data); | |
| 1063 | − | |
| 1064 | − if (cmd != SIOCDEVPRIVATE) | |
| 1065 | − return -EOPNOTSUPP; | |
| 1066 | − | |
| 1067 | − memset(&ioc, 0, sizeof(ioc)); | |
| 1068 | − | |
| 1069 | − /* Copy the ioc control structure part of ioctl request */ | |
| 1070 | − if (copy_from_user(&ioc, ifr->ifr_data, sizeof(struct brcmf_ioctl))) { | |
| 1071 | − bcmerror = -EINVAL; | |
| 1072 | − goto done; | |
| 1073 | − } | |
| 1074 | − | |
| 1075 | − /* Copy out any buffer passed */ | |
| 1076 | − if (ioc.buf) { | |
| 1077 | − buflen = min_t(int, ioc.len, BRCMF_IOCTL_MAXLEN); | |
| 1078 | − /* optimization for direct ioctl calls from kernel */ | |
| 1079 | − /* | |
| 1080 | − if (segment_eq(get_fs(), KERNEL_DS)) { | |
| 1081 | − buf = ioc.buf; | |
| 1082 | − } else { | |
| 1083 | − */ | |
| 1084 | − { | |
| 1085 | − buf = kmalloc(buflen, GFP_ATOMIC); | |
| 1086 | − if (!buf) { | |
| 1087 | − bcmerror = -ENOMEM; | |
| 1088 | − goto done; | |
| 1089 | − } | |
| 1090 | − if (copy_from_user(buf, ioc.buf, buflen)) { | |
| 1091 | − bcmerror = -EINVAL; | |
| 1092 | − goto done; | |
| 1093 | − } | |
| 1094 | − } | |
| 1095 | − } | |
| 1096 | − | |
| 1097 | − /* To differentiate read 4 more byes */ | |
| 1098 | − if ((copy_from_user(&driver, (char *)ifr->ifr_data + | |
| 1099 | − sizeof(struct brcmf_ioctl), sizeof(uint)) != 0)) { | |
| 1100 | − bcmerror = -EINVAL; | |
| 1101 | − goto done; | |
| 1102 | − } | |
| 1103 | − | |
| 1104 | − if (!capable(CAP_NET_ADMIN)) { | |
| 1105 | − bcmerror = -EPERM; | |
| 1106 | − goto done; | |
| 1107 | − } | |
| 1108 | − | |
| 1109 | − /* check for local brcmf ioctl and handle it */ | |
| 1110 | − if (driver == BRCMF_IOCTL_MAGIC) { | |
| 1111 | − bcmerror = brcmf_c_ioctl((void *)&drvr_priv->pub, &ioc, buf, buflen); | |
| 1112 | − if (bcmerror) | |
| 1113 | − drvr_priv->pub.bcmerror = bcmerror; | |
| 1114 | − goto done; | |
| 1115 | − } | |
| 1116 | − | |
| 1117 | − /* send to dongle (must be up, and wl) */ | |
| 1118 | − if ((drvr_priv->pub.busstate != BRCMF_BUS_DATA)) { | |
| 1119 | − BRCMF_ERROR(("%s DONGLE_DOWN,__func__\n", __func__)); | |
| 1120 | − bcmerror = -EIO; | |
| 1121 | − goto done; | |
| 1122 | − } | |
| 1123 | − | |
| 1124 | − if (!drvr_priv->pub.iswl) { | |
| 1125 | − bcmerror = -EIO; | |
| 1126 | − goto done; | |
| 1127 | − } | |
| 1128 | − | |
| 1129 | − /* | |
| 1130 | − * Intercept BRCMF_C_SET_KEY IOCTL - serialize M4 send and | |
| 1131 | − * set key IOCTL to prevent M4 encryption. | |
| 1132 | − */ | |
| 1133 | − is_set_key_cmd = ((ioc.cmd == BRCMF_C_SET_KEY) || | |
| 1134 | − ((ioc.cmd == BRCMF_C_SET_VAR) && | |
| 1135 | − !(strncmp("wsec_key", ioc.buf, 9))) || | |
| 1136 | − ((ioc.cmd == BRCMF_C_SET_VAR) && | |
| 1137 | − !(strncmp("bsscfg:wsec_key", ioc.buf, 15)))); | |
| 1138 | − if (is_set_key_cmd) | |
| 1139 | − brcmf_netdev_wait_pend8021x(net); | |
| 1140 | − | |
| 1141 | − bcmerror = | |
| 1142 | − brcmf_proto_ioctl(&drvr_priv->pub, ifidx, (struct brcmf_ioctl *)&ioc, | |
| 1143 | − buf, buflen); | |
| 1144 | − | |
| 1145 | −done: | |
| 1146 | − if (!bcmerror && buf && ioc.buf) { | |
| 1147 | − if (copy_to_user(ioc.buf, buf, buflen)) | |
| 1148 | − bcmerror = -EFAULT; | |
| 1149 | − } | |
| 1150 | − | |
| 1151 | − kfree(buf); | |
| 1152 | − | |
| 1153 | − if (bcmerror > 0) | |
| 1154 | − bcmerror = 0; | |
| 1155 | − | |
| 1156 | − return bcmerror; | |
| 1157 | −} | |
| 1158 | − | |
| 1159 | −static int brcmf_netdev_stop(struct net_device *net) | |
| 1160 | −{ | |
| 1161 | −#if !defined(IGNORE_ETH0_DOWN) | |
| 1162 | − struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net); | |
| 1163 | − | |
| 1164 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 1165 | − brcmf_cfg80211_down(); | |
| 1166 | − if (drvr_priv->pub.up == 0) | |
| 1167 | − return 0; | |
| 1168 | − | |
| 1169 | − /* Set state and stop OS transmissions */ | |
| 1170 | − drvr_priv->pub.up = 0; | |
| 1171 | − netif_stop_queue(net); | |
| 1172 | −#else | |
| 1173 | − BRCMF_ERROR(("BYPASS %s:due to BRCM compilation: under investigation\n", | |
| 1174 | − __func__)); | |
| 1175 | −#endif /* !defined(IGNORE_ETH0_DOWN) */ | |
| 1176 | − | |
| 1177 | − return 0; | |
| 1178 | −} | |
| 1179 | − | |
| 1180 | −static int brcmf_netdev_open(struct net_device *net) | |
| 1181 | −{ | |
| 1182 | − struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net); | |
| 1183 | − u32 toe_ol; | |
| 1184 | − int ifidx = brcmf_net2idx(drvr_priv, net); | |
| 1185 | − s32 ret = 0; | |
| 1186 | − | |
| 1187 | − BRCMF_TRACE(("%s: ifidx %d\n", __func__, ifidx)); | |
| 1188 | − | |
| 1189 | − if (ifidx == 0) { /* do it only for primary eth0 */ | |
| 1190 | − | |
| 1191 | − /* try to bring up bus */ | |
| 1192 | − ret = brcmf_bus_start(&drvr_priv->pub); | |
| 1193 | − if (ret != 0) { | |
| 1194 | − BRCMF_ERROR(("%s: failed with code %d\n", | |
| 1195 | − __func__, ret)); | |
| 1196 | − return -1; | |
| 1197 | − } | |
| 1198 | − atomic_set(&drvr_priv->pend_8021x_cnt, 0); | |
| 1199 | − | |
| 1200 | − memcpy(net->dev_addr, drvr_priv->pub.mac, ETH_ALEN); | |
| 1201 | − | |
| 1202 | − /* Get current TOE mode from dongle */ | |
| 1203 | − if (brcmf_toe_get(drvr_priv, ifidx, &toe_ol) >= 0 | |
| 1204 | − && (toe_ol & TOE_TX_CSUM_OL) != 0) | |
| 1205 | − drvr_priv->iflist[ifidx]->net->features |= | |
| 1206 | − NETIF_F_IP_CSUM; | |
| 1207 | − else | |
| 1208 | − drvr_priv->iflist[ifidx]->net->features &= | |
| 1209 | − ~NETIF_F_IP_CSUM; | |
| 1210 | − } | |
| 1211 | − /* Allow transmit calls */ | |
| 1212 | − netif_start_queue(net); | |
| 1213 | − drvr_priv->pub.up = 1; | |
| 1214 | − if (unlikely(brcmf_cfg80211_up())) { | |
| 1215 | − BRCMF_ERROR(("%s: failed to bring up cfg80211\n", | |
| 1216 | − __func__)); | |
| 1217 | − return -1; | |
| 1218 | − } | |
| 1219 | − | |
| 1220 | − return ret; | |
| 1221 | −} | |
| 1222 | − | |
| 1223 | −int | |
| 1224 | −brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, void *handle, char *name, | |
| 1225 | − u8 *mac_addr, u32 flags, u8 bssidx) | |
| 1226 | −{ | |
| 1227 | − struct brcmf_if *ifp; | |
| 1228 | − | |
| 1229 | − BRCMF_TRACE(("%s: idx %d, handle->%p\n", __func__, ifidx, handle)); | |
| 1230 | − | |
| 1231 | − ifp = drvr_priv->iflist[ifidx]; | |
| 1232 | − if (!ifp) { | |
| 1233 | − ifp = kmalloc(sizeof(struct brcmf_if), GFP_ATOMIC); | |
| 1234 | − if (!ifp) { | |
| 1235 | − BRCMF_ERROR(("%s: OOM - struct brcmf_if\n", __func__)); | |
| 1236 | − return -ENOMEM; | |
| 1237 | − } | |
| 1238 | − } | |
| 1239 | − | |
| 1240 | − memset(ifp, 0, sizeof(struct brcmf_if)); | |
| 1241 | − ifp->info = drvr_priv; | |
| 1242 | − drvr_priv->iflist[ifidx] = ifp; | |
| 1243 | − strlcpy(ifp->name, name, IFNAMSIZ); | |
| 1244 | − if (mac_addr != NULL) | |
| 1245 | − memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); | |
| 1246 | − | |
| 1247 | − if (handle == NULL) { | |
| 1248 | − ifp->state = BRCMF_E_IF_ADD; | |
| 1249 | − ifp->idx = ifidx; | |
| 1250 | − up(&drvr_priv->sysioc_sem); | |
| 1251 | − } else | |
| 1252 | − ifp->net = (struct net_device *)handle; | |
| 1253 | − | |
| 1254 | − return 0; | |
| 1255 | −} | |
| 1256 | − | |
| 1257 | −void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx) | |
| 1258 | −{ | |
| 1259 | − struct brcmf_if *ifp; | |
| 1260 | − | |
| 1261 | − BRCMF_TRACE(("%s: idx %d\n", __func__, ifidx)); | |
| 1262 | − | |
| 1263 | − ifp = drvr_priv->iflist[ifidx]; | |
| 1264 | − if (!ifp) { | |
| 1265 | − BRCMF_ERROR(("%s: Null interface\n", __func__)); | |
| 1266 | − return; | |
| 1267 | − } | |
| 1268 | − | |
| 1269 | − ifp->state = BRCMF_E_IF_DEL; | |
| 1270 | − ifp->idx = ifidx; | |
| 1271 | − up(&drvr_priv->sysioc_sem); | |
| 1272 | −} | |
| 1273 | − | |
| 1274 | −struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen) | |
| 1275 | −{ | |
| 1276 | − struct brcmf_info *drvr_priv = NULL; | |
| 1277 | − struct net_device *net; | |
| 1278 | − | |
| 1279 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 1280 | − | |
| 1281 | − /* Allocate etherdev, including space for private structure */ | |
| 1282 | − net = alloc_etherdev(sizeof(drvr_priv)); | |
| 1283 | − if (!net) { | |
| 1284 | − BRCMF_ERROR(("%s: OOM - alloc_etherdev\n", __func__)); | |
| 1285 | − goto fail; | |
| 1286 | − } | |
| 1287 | − | |
| 1288 | − /* Allocate primary brcmf_info */ | |
| 1289 | − drvr_priv = kzalloc(sizeof(struct brcmf_info), GFP_ATOMIC); | |
| 1290 | − if (!drvr_priv) { | |
| 1291 | − BRCMF_ERROR(("%s: OOM - alloc brcmf_info\n", __func__)); | |
| 1292 | − goto fail; | |
| 1293 | − } | |
| 1294 | − | |
| 1295 | − /* | |
| 1296 | − * Save the brcmf_info into the priv | |
| 1297 | − */ | |
| 1298 | − memcpy(netdev_priv(net), &drvr_priv, sizeof(drvr_priv)); | |
| 1299 | − | |
| 1300 | − /* Set network interface name if it was provided as module parameter */ | |
| 1301 | − if (iface_name[0]) { | |
| 1302 | − int len; | |
| 1303 | − char ch; | |
| 1304 | − strncpy(net->name, iface_name, IFNAMSIZ); | |
| 1305 | − net->name[IFNAMSIZ - 1] = 0; | |
| 1306 | − len = strlen(net->name); | |
| 1307 | − ch = net->name[len - 1]; | |
| 1308 | − if ((ch > '9' || ch < '0') && (len < IFNAMSIZ - 2)) | |
| 1309 | − strcat(net->name, "%d"); | |
| 1310 | − } | |
| 1311 | − | |
| 1312 | − if (brcmf_add_if(drvr_priv, 0, (void *)net, net->name, NULL, 0, 0) == | |
| 1313 | − BRCMF_BAD_IF) | |
| 1314 | − goto fail; | |
| 1315 | − | |
| 1316 | − net->netdev_ops = NULL; | |
| 1317 | − sema_init(&drvr_priv->proto_sem, 1); | |
| 1318 | − /* Initialize other structure content */ | |
| 1319 | − init_waitqueue_head(&drvr_priv->ioctl_resp_wait); | |
| 1320 | − | |
| 1321 | − /* Link to info module */ | |
| 1322 | − drvr_priv->pub.info = drvr_priv; | |
| 1323 | − | |
| 1324 | − /* Link to bus module */ | |
| 1325 | − drvr_priv->pub.bus = bus; | |
| 1326 | − drvr_priv->pub.hdrlen = bus_hdrlen; | |
| 1327 | − | |
| 1328 | − /* Attach and link in the protocol */ | |
| 1329 | − if (brcmf_proto_attach(&drvr_priv->pub) != 0) { | |
| 1330 | − BRCMF_ERROR(("brcmf_prot_attach failed\n")); | |
| 1331 | − goto fail; | |
| 1332 | − } | |
| 1333 | − | |
| 1334 | − /* Attach and link in the cfg80211 */ | |
| 1335 | − if (unlikely(brcmf_cfg80211_attach(net, &drvr_priv->pub))) { | |
| 1336 | − BRCMF_ERROR(("wl_cfg80211_attach failed\n")); | |
| 1337 | − goto fail; | |
| 1338 | − } | |
| 1339 | − | |
| 1340 | − if (brcmf_sysioc) { | |
| 1341 | − sema_init(&drvr_priv->sysioc_sem, 0); | |
| 1342 | − drvr_priv->sysioc_tsk = kthread_run(_brcmf_sysioc_thread, drvr_priv, | |
| 1343 | − "_brcmf_sysioc"); | |
| 1344 | − if (IS_ERR(drvr_priv->sysioc_tsk)) { | |
| 1345 | − printk(KERN_WARNING | |
| 1346 | − "_brcmf_sysioc thread failed to start\n"); | |
| 1347 | − drvr_priv->sysioc_tsk = NULL; | |
| 1348 | − } | |
| 1349 | − } else | |
| 1350 | − drvr_priv->sysioc_tsk = NULL; | |
| 1351 | − | |
| 1352 | − /* | |
| 1353 | − * Save the brcmf_info into the priv | |
| 1354 | − */ | |
| 1355 | − memcpy(netdev_priv(net), &drvr_priv, sizeof(drvr_priv)); | |
| 1356 | − | |
| 1357 | −#if defined(CONFIG_PM_SLEEP) | |
| 1358 | − atomic_set(&brcmf_mmc_suspend, false); | |
| 1359 | −#endif /* defined(CONFIG_PM_SLEEP) */ | |
| 1360 | − return &drvr_priv->pub; | |
| 1361 | − | |
| 1362 | −fail: | |
| 1363 | − if (net) | |
| 1364 | − free_netdev(net); | |
| 1365 | − if (drvr_priv) | |
| 1366 | − brcmf_detach(&drvr_priv->pub); | |
| 1367 | − | |
| 1368 | − return NULL; | |
| 1369 | −} | |
| 1370 | − | |
| 1371 | −int brcmf_bus_start(struct brcmf_pub *drvr) | |
| 1372 | −{ | |
| 1373 | − int ret = -1; | |
| 1374 | − struct brcmf_info *drvr_priv = drvr->info; | |
| 1375 | − /* Room for "event_msgs" + '\0' + bitvec */ | |
| 1376 | − char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; | |
| 1377 | − | |
| 1378 | − BRCMF_TRACE(("%s:\n", __func__)); | |
| 1379 | − | |
| 1380 | − /* Bring up the bus */ | |
| 1381 | − ret = brcmf_sdbrcm_bus_init(&drvr_priv->pub, true); | |
| 1382 | − if (ret != 0) { | |
| 1383 | − BRCMF_ERROR(("%s, brcmf_sdbrcm_bus_init failed %d\n", __func__, | |
| 1384 | − ret)); | |
| 1385 | − return ret; | |
| 1386 | − } | |
| 1387 | − | |
| 1388 | − /* If bus is not ready, can't come up */ | |
| 1389 | − if (drvr_priv->pub.busstate != BRCMF_BUS_DATA) { | |
| 1390 | − BRCMF_ERROR(("%s failed bus is not ready\n", __func__)); | |
| 1391 | − return -ENODEV; | |
| 1392 | − } | |
| 1393 | − | |
| 1394 | − brcmu_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN, | |
| 1395 | − iovbuf, sizeof(iovbuf)); | |
| 1396 | − brcmf_proto_cdc_query_ioctl(drvr, 0, BRCMF_C_GET_VAR, iovbuf, | |
| 1397 | − sizeof(iovbuf)); | |
| 1398 | − memcpy(drvr->eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN); | |
| 1399 | − | |
| 1400 | − setbit(drvr->eventmask, BRCMF_E_SET_SSID); | |
| 1401 | − setbit(drvr->eventmask, BRCMF_E_PRUNE); | |
| 1402 | − setbit(drvr->eventmask, BRCMF_E_AUTH); | |
| 1403 | − setbit(drvr->eventmask, BRCMF_E_REASSOC); | |
| 1404 | − setbit(drvr->eventmask, BRCMF_E_REASSOC_IND); | |
| 1405 | − setbit(drvr->eventmask, BRCMF_E_DEAUTH_IND); | |
| 1406 | − setbit(drvr->eventmask, BRCMF_E_DISASSOC_IND); | |
| 1407 | − setbit(drvr->eventmask, BRCMF_E_DISASSOC); | |
| 1408 | − setbit(drvr->eventmask, BRCMF_E_JOIN); | |
| 1409 | − setbit(drvr->eventmask, BRCMF_E_ASSOC_IND); | |
| 1410 | − setbit(drvr->eventmask, BRCMF_E_PSK_SUP); | |
| 1411 | − setbit(drvr->eventmask, BRCMF_E_LINK); | |
| 1412 | − setbit(drvr->eventmask, BRCMF_E_NDIS_LINK); | |
| 1413 | − setbit(drvr->eventmask, BRCMF_E_MIC_ERROR); | |
| 1414 | − setbit(drvr->eventmask, BRCMF_E_PMKID_CACHE); | |
| 1415 | − setbit(drvr->eventmask, BRCMF_E_TXFAIL); | |
| 1416 | − setbit(drvr->eventmask, BRCMF_E_JOIN_START); | |
| 1417 | − setbit(drvr->eventmask, BRCMF_E_SCAN_COMPLETE); | |
| 1418 | − | |
| 1419 | −/* enable dongle roaming event */ | |
| 1420 | − | |
| 1421 | − drvr->pktfilter_count = 1; | |
| 1422 | − /* Setup filter to allow only unicast */ | |
| 1423 | − drvr->pktfilter[0] = "100 0 0 0 0x01 0x00"; | |
| 1424 | − | |
| 1425 | − /* Bus is ready, do any protocol initialization */ | |
| 1426 | − ret = brcmf_proto_init(&drvr_priv->pub); | |
| 1427 | − if (ret < 0) | |
| 1428 | − return ret; | |
| 1429 | − | |
| 1430 | − return 0; | |
| 1431 | −} | |
| 1432 | − | |
| 1433 | −static struct net_device_ops brcmf_netdev_ops_pri = { | |
| 1434 | − .ndo_open = brcmf_netdev_open, | |
| 1435 | − .ndo_stop = brcmf_netdev_stop, | |
| 1436 | − .ndo_get_stats = brcmf_netdev_get_stats, | |
| 1437 | − .ndo_do_ioctl = brcmf_netdev_ioctl_entry, | |
| 1438 | − .ndo_start_xmit = brcmf_netdev_start_xmit, | |
| 1439 | − .ndo_set_mac_address = brcmf_netdev_set_mac_address, | |
| 1440 | − .ndo_set_rx_mode = brcmf_netdev_set_multicast_list, | |
| 1441 | −}; | |
| 1442 | − | |
| 1443 | −int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) | |
| 1444 | −{ | |
| 1445 | − struct brcmf_info *drvr_priv = drvr->info; | |
| 1446 | − struct net_device *net; | |
| 1447 | − u8 temp_addr[ETH_ALEN] = { | |
| 1448 | − 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33}; | |
| 1449 | − | |
| 1450 | − BRCMF_TRACE(("%s: ifidx %d\n", __func__, ifidx)); | |
| 1451 | − | |
| 1452 | − net = drvr_priv->iflist[ifidx]->net; | |
| 1453 | − net->netdev_ops = &brcmf_netdev_ops_pri; | |
| 1454 | − | |
| 1455 | − /* | |
| 1456 | − * We have to use the primary MAC for virtual interfaces | |
| 1457 | − */ | |
| 1458 | − if (ifidx != 0) { | |
| 1459 | − /* for virtual interfaces use the primary MAC */ | |
| 1460 | − memcpy(temp_addr, drvr_priv->pub.mac, ETH_ALEN); | |
| 1461 | − | |
| 1462 | − } | |
| 1463 | − | |
| 1464 | − if (ifidx == 1) { | |
| 1465 | − BRCMF_TRACE(("%s ACCESS POINT MAC:\n", __func__)); | |
| 1466 | − /* ACCESSPOINT INTERFACE CASE */ | |
| 1467 | − temp_addr[0] |= 0X02; /* set bit 2 , | |
| 1468 | − - Locally Administered address */ | |
| 1469 | − | |
| 1470 | − } | |
| 1471 | − net->hard_header_len = ETH_HLEN + drvr_priv->pub.hdrlen; | |
| 1472 | − net->ethtool_ops = &brcmf_ethtool_ops; | |
| 1473 | − | |
| 1474 | − drvr_priv->pub.rxsz = net->mtu + net->hard_header_len + | |
| 1475 | − drvr_priv->pub.hdrlen; | |
| 1476 | − | |
| 1477 | − memcpy(net->dev_addr, temp_addr, ETH_ALEN); | |
| 1478 | − | |
| 1479 | − if (register_netdev(net) != 0) { | |
| 1480 | − BRCMF_ERROR(("%s: couldn't register the net device\n", | |
| 1481 | − __func__)); | |
| 1482 | − goto fail; | |
| 1483 | − } | |
| 1484 | − | |
| 1485 | − BRCMF_INFO(("%s: Broadcom Dongle Host Driver\n", net->name)); | |
| 1486 | − | |
| 1487 | − return 0; | |
| 1488 | − | |
| 1489 | −fail: | |
| 1490 | − net->netdev_ops = NULL; | |
| 1491 | − return -EBADE; | |
| 1492 | −} | |
| 1493 | − | |
| 1494 | −static void brcmf_bus_detach(struct brcmf_pub *drvr) | |
| 1495 | −{ | |
| 1496 | − struct brcmf_info *drvr_priv; | |
| 1497 | − | |
| 1498 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 1499 | − | |
| 1500 | − if (drvr) { | |
| 1501 | − drvr_priv = drvr->info; | |
| 1502 | − if (drvr_priv) { | |
| 1503 | − /* Stop the protocol module */ | |
| 1504 | − brcmf_proto_stop(&drvr_priv->pub); | |
| 1505 | − | |
| 1506 | − /* Stop the bus module */ | |
| 1507 | − brcmf_sdbrcm_bus_stop(drvr_priv->pub.bus, true); | |
| 1508 | − } | |
| 1509 | − } | |
| 1510 | −} | |
| 1511 | − | |
| 1512 | −void brcmf_detach(struct brcmf_pub *drvr) | |
| 1513 | −{ | |
| 1514 | − struct brcmf_info *drvr_priv; | |
| 1515 | − | |
| 1516 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 1517 | − | |
| 1518 | − if (drvr) { | |
| 1519 | − drvr_priv = drvr->info; | |
| 1520 | − if (drvr_priv) { | |
| 1521 | − struct brcmf_if *ifp; | |
| 1522 | − int i; | |
| 1523 | − | |
| 1524 | − for (i = 1; i < BRCMF_MAX_IFS; i++) | |
| 1525 | − if (drvr_priv->iflist[i]) | |
| 1526 | − brcmf_del_if(drvr_priv, i); | |
| 1527 | − | |
| 1528 | − ifp = drvr_priv->iflist[0]; | |
| 1529 | − if (ifp->net->netdev_ops == &brcmf_netdev_ops_pri) { | |
| 1530 | − brcmf_netdev_stop(ifp->net); | |
| 1531 | − unregister_netdev(ifp->net); | |
| 1532 | − } | |
| 1533 | − | |
| 1534 | − if (drvr_priv->sysioc_tsk) { | |
| 1535 | − send_sig(SIGTERM, drvr_priv->sysioc_tsk, 1); | |
| 1536 | − kthread_stop(drvr_priv->sysioc_tsk); | |
| 1537 | − drvr_priv->sysioc_tsk = NULL; | |
| 1538 | − } | |
| 1539 | − | |
| 1540 | − brcmf_bus_detach(drvr); | |
| 1541 | − | |
| 1542 | − if (drvr->prot) | |
| 1543 | − brcmf_proto_detach(drvr); | |
| 1544 | − | |
| 1545 | − brcmf_cfg80211_detach(); | |
| 1546 | − | |
| 1547 | − free_netdev(ifp->net); | |
| 1548 | − kfree(ifp); | |
| 1549 | − kfree(drvr_priv); | |
| 1550 | − } | |
| 1551 | − } | |
| 1552 | −} | |
| 1553 | − | |
| 1554 | −static void __exit brcmf_module_cleanup(void) | |
| 1555 | −{ | |
| 1556 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 1557 | − | |
| 1558 | − brcmf_bus_unregister(); | |
| 1559 | −} | |
| 1560 | − | |
| 1561 | −static int __init brcmf_module_init(void) | |
| 1562 | −{ | |
| 1563 | − int error; | |
| 1564 | − | |
| 1565 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 1566 | − | |
| 1567 | − error = brcmf_bus_register(); | |
| 1568 | − | |
| 1569 | − if (error) { | |
| 1570 | − BRCMF_ERROR(("%s: brcmf_bus_register failed\n", __func__)); | |
| 1571 | − goto failed; | |
| 1572 | − } | |
| 1573 | − return 0; | |
| 1574 | − | |
| 1575 | −failed: | |
| 1576 | − return -EINVAL; | |
| 1577 | −} | |
| 1578 | − | |
| 1579 | −module_init(brcmf_module_init); | |
| 1580 | −module_exit(brcmf_module_cleanup); | |
| 1581 | − | |
| 1582 | −int brcmf_os_proto_block(struct brcmf_pub *drvr) | |
| 1583 | −{ | |
| 1584 | − struct brcmf_info *drvr_priv = drvr->info; | |
| 1585 | − | |
| 1586 | − if (drvr_priv) { | |
| 1587 | − down(&drvr_priv->proto_sem); | |
| 1588 | − return 1; | |
| 1589 | − } | |
| 1590 | − return 0; | |
| 1591 | −} | |
| 1592 | − | |
| 1593 | −int brcmf_os_proto_unblock(struct brcmf_pub *drvr) | |
| 1594 | −{ | |
| 1595 | − struct brcmf_info *drvr_priv = drvr->info; | |
| 1596 | − | |
| 1597 | − if (drvr_priv) { | |
| 1598 | − up(&drvr_priv->proto_sem); | |
| 1599 | − return 1; | |
| 1600 | − } | |
| 1601 | − | |
| 1602 | − return 0; | |
| 1603 | −} | |
| 1604 | − | |
| 1605 | −unsigned int brcmf_os_get_ioctl_resp_timeout(void) | |
| 1606 | −{ | |
| 1607 | − return (unsigned int)brcmf_ioctl_timeout_msec; | |
| 1608 | −} | |
| 1609 | − | |
| 1610 | −void brcmf_os_set_ioctl_resp_timeout(unsigned int timeout_msec) | |
| 1611 | −{ | |
| 1612 | − brcmf_ioctl_timeout_msec = (int)timeout_msec; | |
| 1613 | −} | |
| 1614 | − | |
| 1615 | −int brcmf_os_ioctl_resp_wait(struct brcmf_pub *drvr, uint *condition, | |
| 1616 | − bool *pending) | |
| 1617 | −{ | |
| 1618 | − struct brcmf_info *drvr_priv = drvr->info; | |
| 1619 | − DECLARE_WAITQUEUE(wait, current); | |
| 1620 | − int timeout = brcmf_ioctl_timeout_msec; | |
| 1621 | − | |
| 1622 | − /* Convert timeout in millsecond to jiffies */ | |
| 1623 | − timeout = timeout * HZ / 1000; | |
| 1624 | − | |
| 1625 | − /* Wait until control frame is available */ | |
| 1626 | − add_wait_queue(&drvr_priv->ioctl_resp_wait, &wait); | |
| 1627 | − set_current_state(TASK_INTERRUPTIBLE); | |
| 1628 | − | |
| 1629 | − while (!(*condition) && (!signal_pending(current) && timeout)) | |
| 1630 | − timeout = schedule_timeout(timeout); | |
| 1631 | − | |
| 1632 | − if (signal_pending(current)) | |
| 1633 | − *pending = true; | |
| 1634 | − | |
| 1635 | − set_current_state(TASK_RUNNING); | |
| 1636 | − remove_wait_queue(&drvr_priv->ioctl_resp_wait, &wait); | |
| 1637 | − | |
| 1638 | − return timeout; | |
| 1639 | −} | |
| 1640 | − | |
| 1641 | −int brcmf_os_ioctl_resp_wake(struct brcmf_pub *drvr) | |
| 1642 | −{ | |
| 1643 | − struct brcmf_info *drvr_priv = drvr->info; | |
| 1644 | − | |
| 1645 | − if (waitqueue_active(&drvr_priv->ioctl_resp_wait)) | |
| 1646 | − wake_up_interruptible(&drvr_priv->ioctl_resp_wait); | |
| 1647 | − | |
| 1648 | − return 0; | |
| 1649 | −} | |
| 1650 | − | |
| 1651 | −static int brcmf_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata, | |
| 1652 | − struct brcmf_event_msg *event, void **data) | |
| 1653 | −{ | |
| 1654 | − int bcmerror = 0; | |
| 1655 | − | |
| 1656 | − bcmerror = brcmf_c_host_event(drvr_priv, ifidx, pktdata, event, data); | |
| 1657 | − if (bcmerror != 0) | |
| 1658 | − return bcmerror; | |
| 1659 | − | |
| 1660 | − if (drvr_priv->iflist[*ifidx]->net) | |
| 1661 | − brcmf_cfg80211_event(drvr_priv->iflist[*ifidx]->net, | |
| 1662 | − event, *data); | |
| 1663 | − | |
| 1664 | − return bcmerror; | |
| 1665 | −} | |
| 1666 | − | |
| 1667 | −int brcmf_netdev_reset(struct net_device *dev, u8 flag) | |
| 1668 | −{ | |
| 1669 | − struct brcmf_info *drvr_priv = *(struct brcmf_info **)netdev_priv(dev); | |
| 1670 | − | |
| 1671 | − brcmf_bus_devreset(&drvr_priv->pub, flag); | |
| 1672 | − | |
| 1673 | − return 1; | |
| 1674 | −} | |
| 1675 | − | |
| 1676 | −static int brcmf_get_pend_8021x_cnt(struct brcmf_info *drvr_priv) | |
| 1677 | −{ | |
| 1678 | − return atomic_read(&drvr_priv->pend_8021x_cnt); | |
| 1679 | −} | |
| 1680 | − | |
| 1681 | −#define MAX_WAIT_FOR_8021X_TX 10 | |
| 1682 | − | |
| 1683 | −int brcmf_netdev_wait_pend8021x(struct net_device *dev) | |
| 1684 | −{ | |
| 1685 | − struct brcmf_info *drvr_priv = *(struct brcmf_info **)netdev_priv(dev); | |
| 1686 | − int timeout = 10 * HZ / 1000; | |
| 1687 | − int ntimes = MAX_WAIT_FOR_8021X_TX; | |
| 1688 | − int pend = brcmf_get_pend_8021x_cnt(drvr_priv); | |
| 1689 | − | |
| 1690 | − while (ntimes && pend) { | |
| 1691 | − if (pend) { | |
| 1692 | − set_current_state(TASK_INTERRUPTIBLE); | |
| 1693 | − schedule_timeout(timeout); | |
| 1694 | − set_current_state(TASK_RUNNING); | |
| 1695 | − ntimes--; | |
| 1696 | − } | |
| 1697 | − pend = brcmf_get_pend_8021x_cnt(drvr_priv); | |
| 1698 | − } | |
| 1699 | − return pend; | |
| 1700 | −} | |
| 1701 | − | |
| 1702 | −#ifdef BCMDBG | |
| 1703 | −int brcmf_write_to_file(struct brcmf_pub *drvr, u8 *buf, int size) | |
| 1704 | −{ | |
| 1705 | − int ret = 0; | |
| 1706 | − struct file *fp; | |
| 1707 | − mm_segment_t old_fs; | |
| 1708 | − loff_t pos = 0; | |
| 1709 | − | |
| 1710 | − /* change to KERNEL_DS address limit */ | |
| 1711 | − old_fs = get_fs(); | |
| 1712 | − set_fs(KERNEL_DS); | |
| 1713 | − | |
| 1714 | − /* open file to write */ | |
| 1715 | − fp = filp_open("/tmp/mem_dump", O_WRONLY | O_CREAT, 0640); | |
| 1716 | − if (!fp) { | |
| 1717 | − BRCMF_ERROR(("%s: open file error\n", __func__)); | |
| 1718 | − ret = -1; | |
| 1719 | − goto exit; | |
| 1720 | − } | |
| 1721 | − | |
| 1722 | − /* Write buf to file */ | |
| 1723 | − fp->f_op->write(fp, buf, size, &pos); | |
| 1724 | − | |
| 1725 | −exit: | |
| 1726 | − /* free buf before return */ | |
| 1727 | − kfree(buf); | |
| 1728 | − /* close file before return */ | |
| 1729 | − if (fp) | |
| 1730 | − filp_close(fp, current->files); | |
| 1731 | − /* restore previous address limit */ | |
| 1732 | − set_fs(old_fs); | |
| 1733 | − | |
| 1734 | − return ret; | |
| 1735 | −} | |
| 1736 | −#endif /* BCMDBG */ | |
| @@ -1,75 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * Copyright (c) 2010 Broadcom Corporation | |
| 3 | − * | |
| 4 | − * Permission to use, copy, modify, and/or distribute this software for any | |
| 5 | − * purpose with or without fee is hereby granted, provided that the above | |
| 6 | − * copyright notice and this permission notice appear in all copies. | |
| 7 | − * | |
| 8 | − * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
| 9 | − * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
| 10 | − * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
| 11 | − * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 12 | − * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | |
| 13 | − * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
| 14 | − * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
| 15 | − */ | |
| 16 | − | |
| 17 | −#ifndef _BRCMF_PROTO_H_ | |
| 18 | −#define _BRCMF_PROTO_H_ | |
| 19 | − | |
| 20 | −#ifndef IOCTL_RESP_TIMEOUT | |
| 21 | −#define IOCTL_RESP_TIMEOUT 2000 /* In milli second */ | |
| 22 | −#endif | |
| 23 | − | |
| 24 | −#ifndef IOCTL_CHIP_ACTIVE_TIMEOUT | |
| 25 | −#define IOCTL_CHIP_ACTIVE_TIMEOUT 10 /* In milli second */ | |
| 26 | −#endif | |
| 27 | − | |
| 28 | −/* | |
| 29 | − * Exported from the brcmf protocol module (brcmf_cdc) | |
| 30 | − */ | |
| 31 | − | |
| 32 | −/* Linkage, sets prot link and updates hdrlen in pub */ | |
| 33 | −extern int brcmf_proto_attach(struct brcmf_pub *drvr); | |
| 34 | − | |
| 35 | −/* Unlink, frees allocated protocol memory (including brcmf_proto) */ | |
| 36 | −extern void brcmf_proto_detach(struct brcmf_pub *drvr); | |
| 37 | − | |
| 38 | −/* Initialize protocol: sync w/dongle state. | |
| 39 | − * Sets dongle media info (iswl, drv_version, mac address). | |
| 40 | − */ | |
| 41 | −extern int brcmf_proto_init(struct brcmf_pub *drvr); | |
| 42 | − | |
| 43 | −/* Stop protocol: sync w/dongle state. */ | |
| 44 | −extern void brcmf_proto_stop(struct brcmf_pub *drvr); | |
| 45 | − | |
| 46 | −/* Add any protocol-specific data header. | |
| 47 | − * Caller must reserve prot_hdrlen prepend space. | |
| 48 | − */ | |
| 49 | −extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, | |
| 50 | − struct sk_buff *txp); | |
| 51 | − | |
| 52 | −/* Remove any protocol-specific data header. */ | |
| 53 | −extern int brcmf_proto_hdrpull(struct brcmf_pub *, int *ifidx, | |
| 54 | − struct sk_buff *rxp); | |
| 55 | − | |
| 56 | −/* Use protocol to issue ioctl to dongle */ | |
| 57 | −extern int brcmf_proto_ioctl(struct brcmf_pub *drvr, int ifidx, | |
| 58 | − struct brcmf_ioctl *ioc, void *buf, int len); | |
| 59 | − | |
| 60 | −/* Add prot dump output to a buffer */ | |
| 61 | −extern void brcmf_proto_dump(struct brcmf_pub *drvr, | |
| 62 | − struct brcmu_strbuf *strbuf); | |
| 63 | − | |
| 64 | −/* Update local copy of dongle statistics */ | |
| 65 | −extern void brcmf_proto_dstats(struct brcmf_pub *drvr); | |
| 66 | − | |
| 67 | −extern int brcmf_c_ioctl(struct brcmf_pub *drvr, struct brcmf_c_ioctl *ioc, | |
| 68 | − void *buf, uint buflen); | |
| 69 | − | |
| 70 | −extern int brcmf_c_preinit_ioctls(struct brcmf_pub *drvr); | |
| 71 | − | |
| 72 | −extern int brcmf_proto_cdc_set_ioctl(struct brcmf_pub *drvr, int ifidx, | |
| 73 | − uint cmd, void *buf, uint len); | |
| 74 | − | |
| 75 | −#endif /* _BRCMF_PROTO_H_ */ | |
| @@ -1,6772 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * Copyright (c) 2010 Broadcom Corporation | |
| 3 | − * | |
| 4 | − * Permission to use, copy, modify, and/or distribute this software for any | |
| 5 | − * purpose with or without fee is hereby granted, provided that the above | |
| 6 | − * copyright notice and this permission notice appear in all copies. | |
| 7 | − * | |
| 8 | − * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
| 9 | − * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
| 10 | − * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
| 11 | − * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| 12 | − * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | |
| 13 | − * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
| 14 | − * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
| 15 | − */ | |
| 16 | − | |
| 17 | −#include <linux/types.h> | |
| 18 | −#include <linux/kernel.h> | |
| 19 | −#include <linux/kthread.h> | |
| 20 | −#include <linux/printk.h> | |
| 21 | −#include <linux/pci_ids.h> | |
| 22 | −#include <linux/netdevice.h> | |
| 23 | −#include <linux/interrupt.h> | |
| 24 | −#include <linux/sched.h> | |
| 25 | −#include <linux/mmc/sdio.h> | |
| 26 | −#include <linux/mmc/sdio_func.h> | |
| 27 | −#include <linux/semaphore.h> | |
| 28 | −#include <linux/firmware.h> | |
| 29 | −#include <asm/unaligned.h> | |
| 30 | −#include <defs.h> | |
| 31 | −#include <brcmu_wifi.h> | |
| 32 | −#include <brcmu_utils.h> | |
| 33 | −#include <brcm_hw_ids.h> | |
| 34 | −#include <soc.h> | |
| 35 | −#include "sdio_host.h" | |
| 36 | − | |
| 37 | −/* register access macros */ | |
| 38 | −#ifndef __BIG_ENDIAN | |
| 39 | −#ifndef __mips__ | |
| 40 | −#define R_REG(r, typ) \ | |
| 41 | − brcmf_sdcard_reg_read(NULL, (r), sizeof(typ)) | |
| 42 | −#else /* __mips__ */ | |
| 43 | −#define R_REG(r, typ) \ | |
| 44 | − ({ \ | |
| 45 | − __typeof(*(r)) __osl_v; \ | |
| 46 | − __asm__ __volatile__("sync"); \ | |
| 47 | − __osl_v = brcmf_sdcard_reg_read(NULL, (r),\ | |
| 48 | − sizeof(typ)); \ | |
| 49 | − __asm__ __volatile__("sync"); \ | |
| 50 | − __osl_v; \ | |
| 51 | − }) | |
| 52 | −#endif /* __mips__ */ | |
| 53 | − | |
| 54 | −#else /* __BIG_ENDIAN */ | |
| 55 | −#define R_REG(r, typ) \ | |
| 56 | − brcmf_sdcard_reg_read(NULL, (r), sizeof(typ)) | |
| 57 | −#endif /* __BIG_ENDIAN */ | |
| 58 | − | |
| 59 | −#define OR_REG(r, v, typ) \ | |
| 60 | − brcmf_sdcard_reg_write(NULL, (r), sizeof(typ), R_REG(r, typ) | (v)) | |
| 61 | − | |
| 62 | −#ifdef BCMDBG | |
| 63 | − | |
| 64 | −/* ARM trap handling */ | |
| 65 | − | |
| 66 | −/* Trap types defined by ARM (see arminc.h) */ | |
| 67 | − | |
| 68 | −#if defined(__ARM_ARCH_4T__) | |
| 69 | −#define MAX_TRAP_TYPE (TR_FIQ + 1) | |
| 70 | −#elif defined(__ARM_ARCH_7M__) | |
| 71 | −#define MAX_TRAP_TYPE (TR_ISR + ARMCM3_NUMINTS) | |
| 72 | −#endif /* __ARM_ARCH_7M__ */ | |
| 73 | − | |
| 74 | −/* The trap structure is defined here as offsets for assembly */ | |
| 75 | −#define TR_TYPE 0x00 | |
| 76 | −#define TR_EPC 0x04 | |
| 77 | −#define TR_CPSR 0x08 | |
| 78 | −#define TR_SPSR 0x0c | |
| 79 | −#define TR_REGS 0x10 | |
| 80 | −#define TR_REG(n) (TR_REGS + (n) * 4) | |
| 81 | −#define TR_SP TR_REG(13) | |
| 82 | −#define TR_LR TR_REG(14) | |
| 83 | −#define TR_PC TR_REG(15) | |
| 84 | − | |
| 85 | −#define TRAP_T_SIZE 80 | |
| 86 | − | |
| 87 | −struct brcmf_trap { | |
| 88 | − u32 type; | |
| 89 | − u32 epc; | |
| 90 | − u32 cpsr; | |
| 91 | − u32 spsr; | |
| 92 | − u32 r0; | |
| 93 | − u32 r1; | |
| 94 | − u32 r2; | |
| 95 | − u32 r3; | |
| 96 | − u32 r4; | |
| 97 | − u32 r5; | |
| 98 | − u32 r6; | |
| 99 | − u32 r7; | |
| 100 | − u32 r8; | |
| 101 | − u32 r9; | |
| 102 | − u32 r10; | |
| 103 | − u32 r11; | |
| 104 | − u32 r12; | |
| 105 | − u32 r13; | |
| 106 | − u32 r14; | |
| 107 | − u32 pc; | |
| 108 | −}; | |
| 109 | − | |
| 110 | −#define CBUF_LEN (128) | |
| 111 | − | |
| 112 | −struct rte_log { | |
| 113 | − u32 buf; /* Can't be pointer on (64-bit) hosts */ | |
| 114 | − uint buf_size; | |
| 115 | − uint idx; | |
| 116 | − char *_buf_compat; /* Redundant pointer for backward compat. */ | |
| 117 | −}; | |
| 118 | − | |
| 119 | −struct rte_console { | |
| 120 | − /* Virtual UART | |
| 121 | − * When there is no UART (e.g. Quickturn), | |
| 122 | − * the host should write a complete | |
| 123 | − * input line directly into cbuf and then write | |
| 124 | − * the length into vcons_in. | |
| 125 | − * This may also be used when there is a real UART | |
| 126 | − * (at risk of conflicting with | |
| 127 | − * the real UART). vcons_out is currently unused. | |
| 128 | − */ | |
| 129 | − volatile uint vcons_in; | |
| 130 | − volatile uint vcons_out; | |
| 131 | − | |
| 132 | − /* Output (logging) buffer | |
| 133 | − * Console output is written to a ring buffer log_buf at index log_idx. | |
| 134 | − * The host may read the output when it sees log_idx advance. | |
| 135 | − * Output will be lost if the output wraps around faster than the host | |
| 136 | − * polls. | |
| 137 | − */ | |
| 138 | − struct rte_log log; | |
| 139 | − | |
| 140 | − /* Console input line buffer | |
| 141 | − * Characters are read one at a time into cbuf | |
| 142 | − * until <CR> is received, then | |
| 143 | − * the buffer is processed as a command line. | |
| 144 | − * Also used for virtual UART. | |
| 145 | − */ | |
| 146 | − uint cbuf_idx; | |
| 147 | − char cbuf[CBUF_LEN]; | |
| 148 | −}; | |
| 149 | − | |
| 150 | −#endif /* BCMDBG */ | |
| 151 | −#include <chipcommon.h> | |
| 152 | − | |
| 153 | −#include "dhd.h" | |
| 154 | −#include "dhd_bus.h" | |
| 155 | −#include "dhd_proto.h" | |
| 156 | −#include "dhd_dbg.h" | |
| 157 | −#include <bcmchip.h> | |
| 158 | − | |
| 159 | −#define TXQLEN 2048 /* bulk tx queue length */ | |
| 160 | −#define TXHI (TXQLEN - 256) /* turn on flow control above TXHI */ | |
| 161 | −#define TXLOW (TXHI - 256) /* turn off flow control below TXLOW */ | |
| 162 | −#define PRIOMASK 7 | |
| 163 | − | |
| 164 | −#define TXRETRIES 2 /* # of retries for tx frames */ | |
| 165 | − | |
| 166 | −#define BRCMF_RXBOUND 50 /* Default for max rx frames in | |
| 167 | − one scheduling */ | |
| 168 | − | |
| 169 | −#define BRCMF_TXBOUND 20 /* Default for max tx frames in | |
| 170 | − one scheduling */ | |
| 171 | − | |
| 172 | −#define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */ | |
| 173 | − | |
| 174 | −#define MEMBLOCK 2048 /* Block size used for downloading | |
| 175 | − of dongle image */ | |
| 176 | −#define MAX_DATA_BUF (32 * 1024) /* Must be large enough to hold | |
| 177 | − biggest possible glom */ | |
| 178 | − | |
| 179 | −#ifndef BRCMF_FIRSTREAD | |
| 180 | −#define BRCMF_FIRSTREAD 32 | |
| 181 | −#endif | |
| 182 | − | |
| 183 | −#if !ISPOWEROF2(BRCMF_FIRSTREAD) | |
| 184 | −#error BRCMF_FIRSTREAD is not a power of 2! | |
| 185 | −#endif | |
| 186 | − | |
| 187 | −/* SBSDIO_DEVICE_CTL */ | |
| 188 | −#define SBSDIO_DEVCTL_SETBUSY 0x01 /* 1: device will assert busy signal when | |
| 189 | − * receiving CMD53 | |
| 190 | − */ | |
| 191 | −#define SBSDIO_DEVCTL_SPI_INTR_SYNC 0x02 /* 1: assertion of sdio interrupt is | |
| 192 | − * synchronous to the sdio clock | |
| 193 | − */ | |
| 194 | −#define SBSDIO_DEVCTL_CA_INT_ONLY 0x04 /* 1: mask all interrupts to host | |
| 195 | − * except the chipActive (rev 8) | |
| 196 | − */ | |
| 197 | −#define SBSDIO_DEVCTL_PADS_ISO 0x08 /* 1: isolate internal sdio signals, put | |
| 198 | − * external pads in tri-state; requires | |
| 199 | − * sdio bus power cycle to clear (rev 9) | |
| 200 | − */ | |
| 201 | −#define SBSDIO_DEVCTL_SB_RST_CTL 0x30 /* Force SD->SB reset mapping (rev 11) */ | |
| 202 | −#define SBSDIO_DEVCTL_RST_CORECTL 0x00 /* Determined by CoreControl bit */ | |
| 203 | −#define SBSDIO_DEVCTL_RST_BPRESET 0x10 /* Force backplane reset */ | |
| 204 | −#define SBSDIO_DEVCTL_RST_NOBPRESET 0x20 /* Force no backplane reset */ | |
| 205 | − | |
| 206 | −/* SBSDIO_FUNC1_CHIPCLKCSR */ | |
| 207 | −#define SBSDIO_FORCE_ALP 0x01 /* Force ALP request to backplane */ | |
| 208 | −#define SBSDIO_FORCE_HT 0x02 /* Force HT request to backplane */ | |
| 209 | −#define SBSDIO_FORCE_ILP 0x04 /* Force ILP request to backplane */ | |
| 210 | −#define SBSDIO_ALP_AVAIL_REQ 0x08 /* Make ALP ready (power up xtal) */ | |
| 211 | −#define SBSDIO_HT_AVAIL_REQ 0x10 /* Make HT ready (power up PLL) */ | |
| 212 | −#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20 /* Squelch clock requests from HW */ | |
| 213 | −#define SBSDIO_ALP_AVAIL 0x40 /* Status: ALP is ready */ | |
| 214 | −#define SBSDIO_HT_AVAIL 0x80 /* Status: HT is ready */ | |
| 215 | − | |
| 216 | −#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL) | |
| 217 | −#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS) | |
| 218 | −#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS) | |
| 219 | −#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval)) | |
| 220 | −#define SBSDIO_CLKAV(regval, alponly) (SBSDIO_ALPAV(regval) && \ | |
| 221 | − (alponly ? 1 : SBSDIO_HTAV(regval))) | |
| 222 | −/* direct(mapped) cis space */ | |
| 223 | −#define SBSDIO_CIS_BASE_COMMON 0x1000 /* MAPPED common CIS address */ | |
| 224 | −#define SBSDIO_CIS_SIZE_LIMIT 0x200 /* maximum bytes in one CIS */ | |
| 225 | −#define SBSDIO_CIS_OFT_ADDR_MASK 0x1FFFF /* cis offset addr is < 17 bits */ | |
| 226 | − | |
| 227 | −#define SBSDIO_CIS_MANFID_TUPLE_LEN 6 /* manfid tuple length, include tuple, | |
| 228 | − * link bytes | |
| 229 | − */ | |
| 230 | − | |
| 231 | −/* intstatus */ | |
| 232 | −#define I_SMB_SW0 (1 << 0) /* To SB Mail S/W interrupt 0 */ | |
| 233 | −#define I_SMB_SW1 (1 << 1) /* To SB Mail S/W interrupt 1 */ | |
| 234 | −#define I_SMB_SW2 (1 << 2) /* To SB Mail S/W interrupt 2 */ | |
| 235 | −#define I_SMB_SW3 (1 << 3) /* To SB Mail S/W interrupt 3 */ | |
| 236 | −#define I_SMB_SW_MASK 0x0000000f /* To SB Mail S/W interrupts mask */ | |
| 237 | −#define I_SMB_SW_SHIFT 0 /* To SB Mail S/W interrupts shift */ | |
| 238 | −#define I_HMB_SW0 (1 << 4) /* To Host Mail S/W interrupt 0 */ | |
| 239 | −#define I_HMB_SW1 (1 << 5) /* To Host Mail S/W interrupt 1 */ | |
| 240 | −#define I_HMB_SW2 (1 << 6) /* To Host Mail S/W interrupt 2 */ | |
| 241 | −#define I_HMB_SW3 (1 << 7) /* To Host Mail S/W interrupt 3 */ | |
| 242 | −#define I_HMB_SW_MASK 0x000000f0 /* To Host Mail S/W interrupts mask */ | |
| 243 | −#define I_HMB_SW_SHIFT 4 /* To Host Mail S/W interrupts shift */ | |
| 244 | −#define I_WR_OOSYNC (1 << 8) /* Write Frame Out Of Sync */ | |
| 245 | −#define I_RD_OOSYNC (1 << 9) /* Read Frame Out Of Sync */ | |
| 246 | −#define I_PC (1 << 10) /* descriptor error */ | |
| 247 | −#define I_PD (1 << 11) /* data error */ | |
| 248 | −#define I_DE (1 << 12) /* Descriptor protocol Error */ | |
| 249 | −#define I_RU (1 << 13) /* Receive descriptor Underflow */ | |
| 250 | −#define I_RO (1 << 14) /* Receive fifo Overflow */ | |
| 251 | −#define I_XU (1 << 15) /* Transmit fifo Underflow */ | |
| 252 | −#define I_RI (1 << 16) /* Receive Interrupt */ | |
| 253 | −#define I_BUSPWR (1 << 17) /* SDIO Bus Power Change (rev 9) */ | |
| 254 | −#define I_XMTDATA_AVAIL (1 << 23) /* bits in fifo */ | |
| 255 | −#define I_XI (1 << 24) /* Transmit Interrupt */ | |
| 256 | −#define I_RF_TERM (1 << 25) /* Read Frame Terminate */ | |
| 257 | −#define I_WF_TERM (1 << 26) /* Write Frame Terminate */ | |
| 258 | −#define I_PCMCIA_XU (1 << 27) /* PCMCIA Transmit FIFO Underflow */ | |
| 259 | −#define I_SBINT (1 << 28) /* sbintstatus Interrupt */ | |
| 260 | −#define I_CHIPACTIVE (1 << 29) /* chip from doze to active state */ | |
| 261 | −#define I_SRESET (1 << 30) /* CCCR RES interrupt */ | |
| 262 | −#define I_IOE2 (1U << 31) /* CCCR IOE2 Bit Changed */ | |
| 263 | −#define I_ERRORS (I_PC | I_PD | I_DE | I_RU | I_RO | I_XU) | |
| 264 | −#define I_DMA (I_RI | I_XI | I_ERRORS) | |
| 265 | − | |
| 266 | −/* corecontrol */ | |
| 267 | −#define CC_CISRDY (1 << 0) /* CIS Ready */ | |
| 268 | −#define CC_BPRESEN (1 << 1) /* CCCR RES signal */ | |
| 269 | −#define CC_F2RDY (1 << 2) /* set CCCR IOR2 bit */ | |
| 270 | −#define CC_CLRPADSISO (1 << 3) /* clear SDIO pads isolation */ | |
| 271 | −#define CC_XMTDATAAVAIL_MODE (1 << 4) | |
| 272 | −#define CC_XMTDATAAVAIL_CTRL (1 << 5) | |
| 273 | − | |
| 274 | −/* SDA_FRAMECTRL */ | |
| 275 | −#define SFC_RF_TERM (1 << 0) /* Read Frame Terminate */ | |
| 276 | −#define SFC_WF_TERM (1 << 1) /* Write Frame Terminate */ | |
| 277 | −#define SFC_CRC4WOOS (1 << 2) /* CRC error for write out of sync */ | |
| 278 | −#define SFC_ABORTALL (1 << 3) /* Abort all in-progress frames */ | |
| 279 | − | |
| 280 | −/* HW frame tag */ | |
| 281 | −#define SDPCM_FRAMETAG_LEN 4 /* 2 bytes len, 2 bytes check val */ | |
| 282 | − | |
| 283 | −/* Total length of frame header for dongle protocol */ | |
| 284 | −#define SDPCM_HDRLEN (SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN) | |
| 285 | −#ifdef SDTEST | |
| 286 | −#define SDPCM_RESERVE (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + BRCMF_SDALIGN) | |
| 287 | −#else | |
| 288 | −#define SDPCM_RESERVE (SDPCM_HDRLEN + BRCMF_SDALIGN) | |
| 289 | −#endif | |
| 290 | − | |
| 291 | −/* | |
| 292 | − * Software allocation of To SB Mailbox resources | |
| 293 | − */ | |
| 294 | − | |
| 295 | −/* tosbmailbox bits corresponding to intstatus bits */ | |
| 296 | −#define SMB_NAK (1 << 0) /* Frame NAK */ | |
| 297 | −#define SMB_INT_ACK (1 << 1) /* Host Interrupt ACK */ | |
| 298 | −#define SMB_USE_OOB (1 << 2) /* Use OOB Wakeup */ | |
| 299 | −#define SMB_DEV_INT (1 << 3) /* Miscellaneous Interrupt */ | |
| 300 | − | |
| 301 | −/* tosbmailboxdata */ | |
| 302 | −#define SMB_DATA_VERSION_SHIFT 16 /* host protocol version */ | |
| 303 | − | |
| 304 | −/* | |
| 305 | − * Software allocation of To Host Mailbox resources | |
| 306 | − */ | |
| 307 | − | |
| 308 | −/* intstatus bits */ | |
| 309 | −#define I_HMB_FC_STATE I_HMB_SW0 /* Flow Control State */ | |
| 310 | −#define I_HMB_FC_CHANGE I_HMB_SW1 /* Flow Control State Changed */ | |
| 311 | −#define I_HMB_FRAME_IND I_HMB_SW2 /* Frame Indication */ | |
| 312 | −#define I_HMB_HOST_INT I_HMB_SW3 /* Miscellaneous Interrupt */ | |
| 313 | − | |
| 314 | −/* tohostmailboxdata */ | |
| 315 | −#define HMB_DATA_NAKHANDLED 1 /* retransmit NAK'd frame */ | |
| 316 | −#define HMB_DATA_DEVREADY 2 /* talk to host after enable */ | |
| 317 | −#define HMB_DATA_FC 4 /* per prio flowcontrol update flag */ | |
| 318 | −#define HMB_DATA_FWREADY 8 /* fw ready for protocol activity */ | |
| 319 | − | |
| 320 | −#define HMB_DATA_FCDATA_MASK 0xff000000 | |
| 321 | −#define HMB_DATA_FCDATA_SHIFT 24 | |
| 322 | − | |
| 323 | −#define HMB_DATA_VERSION_MASK 0x00ff0000 | |
| 324 | −#define HMB_DATA_VERSION_SHIFT 16 | |
| 325 | − | |
| 326 | −/* | |
| 327 | − * Software-defined protocol header | |
| 328 | − */ | |
| 329 | − | |
| 330 | −/* Current protocol version */ | |
| 331 | −#define SDPCM_PROT_VERSION 4 | |
| 332 | − | |
| 333 | −/* SW frame header */ | |
| 334 | −#define SDPCM_PACKET_SEQUENCE(p) (((u8 *)p)[0] & 0xff) | |
| 335 | − | |
| 336 | −#define SDPCM_CHANNEL_MASK 0x00000f00 | |
| 337 | −#define SDPCM_CHANNEL_SHIFT 8 | |
| 338 | −#define SDPCM_PACKET_CHANNEL(p) (((u8 *)p)[1] & 0x0f) | |
| 339 | − | |
| 340 | −#define SDPCM_NEXTLEN_OFFSET 2 | |
| 341 | − | |
| 342 | −/* Data Offset from SOF (HW Tag, SW Tag, Pad) */ | |
| 343 | −#define SDPCM_DOFFSET_OFFSET 3 /* Data Offset */ | |
| 344 | −#define SDPCM_DOFFSET_VALUE(p) (((u8 *)p)[SDPCM_DOFFSET_OFFSET] & 0xff) | |
| 345 | −#define SDPCM_DOFFSET_MASK 0xff000000 | |
| 346 | −#define SDPCM_DOFFSET_SHIFT 24 | |
| 347 | −#define SDPCM_FCMASK_OFFSET 4 /* Flow control */ | |
| 348 | −#define SDPCM_FCMASK_VALUE(p) (((u8 *)p)[SDPCM_FCMASK_OFFSET] & 0xff) | |
| 349 | −#define SDPCM_WINDOW_OFFSET 5 /* Credit based fc */ | |
| 350 | −#define SDPCM_WINDOW_VALUE(p) (((u8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff) | |
| 351 | − | |
| 352 | −#define SDPCM_SWHEADER_LEN 8 /* SW header is 64 bits */ | |
| 353 | − | |
| 354 | −/* logical channel numbers */ | |
| 355 | −#define SDPCM_CONTROL_CHANNEL 0 /* Control channel Id */ | |
| 356 | −#define SDPCM_EVENT_CHANNEL 1 /* Asyc Event Indication Channel Id */ | |
| 357 | −#define SDPCM_DATA_CHANNEL 2 /* Data Xmit/Recv Channel Id */ | |
| 358 | −#define SDPCM_GLOM_CHANNEL 3 /* For coalesced packets */ | |
| 359 | −#define SDPCM_TEST_CHANNEL 15 /* Reserved for test/debug packets */ | |
| 360 | − | |
| 361 | −#define SDPCM_SEQUENCE_WRAP 256 /* wrap-around val for 8bit frame seq */ | |
| 362 | − | |
| 363 | −#define SDPCM_GLOMDESC(p) (((u8 *)p)[1] & 0x80) | |
| 364 | − | |
| 365 | −/* For TEST_CHANNEL packets, define another 4-byte header */ | |
| 366 | −#define SDPCM_TEST_HDRLEN 4 /* | |
| 367 | − * Generally: Cmd(1), Ext(1), Len(2); | |
| 368 | − * Semantics of Ext byte depend on | |
| 369 | − * command. Len is current or requested | |
| 370 | − * frame length, not including test | |
| 371 | − * header; sent little-endian. | |
| 372 | − */ | |
| 373 | −#define SDPCM_TEST_DISCARD 0x01 /* Receiver discards. Ext:pattern id. */ | |
| 374 | −#define SDPCM_TEST_ECHOREQ 0x02 /* Echo request. Ext:pattern id. */ | |
| 375 | −#define SDPCM_TEST_ECHORSP 0x03 /* Echo response. Ext:pattern id. */ | |
| 376 | −#define SDPCM_TEST_BURST 0x04 /* | |
| 377 | − * Receiver to send a burst. | |
| 378 | − * Ext is a frame count | |
| 379 | − */ | |
| 380 | −#define SDPCM_TEST_SEND 0x05 /* | |
| 381 | − * Receiver sets send mode. | |
| 382 | − * Ext is boolean on/off | |
| 383 | − */ | |
| 384 | − | |
| 385 | −/* Handy macro for filling in datagen packets with a pattern */ | |
| 386 | −#define SDPCM_TEST_FILL(byteno, id) ((u8)(id + byteno)) | |
| 387 | − | |
| 388 | −/* | |
| 389 | − * Shared structure between dongle and the host. | |
| 390 | − * The structure contains pointers to trap or assert information. | |
| 391 | − */ | |
| 392 | −#define SDPCM_SHARED_VERSION 0x0002 | |
| 393 | −#define SDPCM_SHARED_VERSION_MASK 0x00FF | |
| 394 | −#define SDPCM_SHARED_ASSERT_BUILT 0x0100 | |
| 395 | −#define SDPCM_SHARED_ASSERT 0x0200 | |
| 396 | −#define SDPCM_SHARED_TRAP 0x0400 | |
| 397 | − | |
| 398 | − | |
| 399 | −/* Space for header read, limit for data packets */ | |
| 400 | −#ifndef MAX_HDR_READ | |
| 401 | −#define MAX_HDR_READ 32 | |
| 402 | −#endif | |
| 403 | −#if !ISPOWEROF2(MAX_HDR_READ) | |
| 404 | −#error MAX_HDR_READ is not a power of 2! | |
| 405 | −#endif | |
| 406 | − | |
| 407 | −#define MAX_RX_DATASZ 2048 | |
| 408 | − | |
| 409 | −/* Maximum milliseconds to wait for F2 to come up */ | |
| 410 | −#define BRCMF_WAIT_F2RDY 3000 | |
| 411 | − | |
| 412 | −/* Bump up limit on waiting for HT to account for first startup; | |
| 413 | − * if the image is doing a CRC calculation before programming the PMU | |
| 414 | − * for HT availability, it could take a couple hundred ms more, so | |
| 415 | − * max out at a 1 second (1000000us). | |
| 416 | − */ | |
| 417 | −#if (PMU_MAX_TRANSITION_DLY <= 1000000) | |
| 418 | −#undef PMU_MAX_TRANSITION_DLY | |
| 419 | −#define PMU_MAX_TRANSITION_DLY 1000000 | |
| 420 | −#endif | |
| 421 | − | |
| 422 | −/* Value for ChipClockCSR during initial setup */ | |
| 423 | −#define BRCMF_INIT_CLKCTL1 (SBSDIO_FORCE_HW_CLKREQ_OFF | \ | |
| 424 | − SBSDIO_ALP_AVAIL_REQ) | |
| 425 | − | |
| 426 | −/* Flags for SDH calls */ | |
| 427 | −#define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED) | |
| 428 | − | |
| 429 | −/* sbimstate */ | |
| 430 | −#define SBIM_IBE 0x20000 /* inbanderror */ | |
| 431 | −#define SBIM_TO 0x40000 /* timeout */ | |
| 432 | −#define SBIM_BY 0x01800000 /* busy (sonics >= 2.3) */ | |
| 433 | −#define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */ | |
| 434 | − | |
| 435 | −/* sbtmstatelow */ | |
| 436 | −#define SBTML_RESET 0x0001 /* reset */ | |
| 437 | −#define SBTML_REJ_MASK 0x0006 /* reject field */ | |
| 438 | −#define SBTML_REJ 0x0002 /* reject */ | |
| 439 | −#define SBTML_TMPREJ 0x0004 /* temporary reject, for error recovery */ | |
| 440 | − | |
| 441 | −#define SBTML_SICF_SHIFT 16 /* Shift to locate the SI control flags in sbtml */ | |
| 442 | − | |
| 443 | −/* sbtmstatehigh */ | |
| 444 | −#define SBTMH_SERR 0x0001 /* serror */ | |
| 445 | −#define SBTMH_INT 0x0002 /* interrupt */ | |
| 446 | −#define SBTMH_BUSY 0x0004 /* busy */ | |
| 447 | −#define SBTMH_TO 0x0020 /* timeout (sonics >= 2.3) */ | |
| 448 | − | |
| 449 | −#define SBTMH_SISF_SHIFT 16 /* Shift to locate the SI status flags in sbtmh */ | |
| 450 | − | |
| 451 | −/* sbidlow */ | |
| 452 | −#define SBIDL_INIT 0x80 /* initiator */ | |
| 453 | − | |
| 454 | −/* sbidhigh */ | |
| 455 | −#define SBIDH_RC_MASK 0x000f /* revision code */ | |
| 456 | −#define SBIDH_RCE_MASK 0x7000 /* revision code extension field */ | |
| 457 | −#define SBIDH_RCE_SHIFT 8 | |
| 458 | −#define SBCOREREV(sbidh) \ | |
| 459 | − ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK)) | |
| 460 | −#define SBIDH_CC_MASK 0x8ff0 /* core code */ | |
| 461 | −#define SBIDH_CC_SHIFT 4 | |
| 462 | −#define SBIDH_VC_MASK 0xffff0000 /* vendor code */ | |
| 463 | −#define SBIDH_VC_SHIFT 16 | |
| 464 | − | |
| 465 | −/* | |
| 466 | − * Conversion of 802.1D priority to precedence level | |
| 467 | − */ | |
| 468 | −#define PRIO2PREC(prio) \ | |
| 469 | − (((prio) == PRIO_8021D_NONE || (prio) == PRIO_8021D_BE) ? \ | |
| 470 | − ((prio^2)) : (prio)) | |
| 471 | − | |
| 472 | −BRCMF_SPINWAIT_SLEEP_INIT(sdioh_spinwait_sleep); | |
| 473 | − | |
| 474 | −/* | |
| 475 | − * Core reg address translation. | |
| 476 | − * Both macro's returns a 32 bits byte address on the backplane bus. | |
| 477 | − */ | |
| 478 | −#define CORE_CC_REG(base, field) (base + offsetof(chipcregs_t, field)) | |
| 479 | −#define CORE_BUS_REG(base, field) \ | |
| 480 | − (base + offsetof(struct sdpcmd_regs, field)) | |
| 481 | −#define CORE_SB(base, field) \ | |
| 482 | − (base + SBCONFIGOFF + offsetof(struct sbconfig, field)) | |
| 483 | − | |
| 484 | −/* core registers */ | |
| 485 | −struct sdpcmd_regs { | |
| 486 | − u32 corecontrol; /* 0x00, rev8 */ | |
| 487 | − u32 corestatus; /* rev8 */ | |
| 488 | − u32 PAD[1]; | |
| 489 | − u32 biststatus; /* rev8 */ | |
| 490 | − | |
| 491 | − /* PCMCIA access */ | |
| 492 | − u16 pcmciamesportaladdr; /* 0x010, rev8 */ | |
| 493 | − u16 PAD[1]; | |
| 494 | − u16 pcmciamesportalmask; /* rev8 */ | |
| 495 | − u16 PAD[1]; | |
| 496 | − u16 pcmciawrframebc; /* rev8 */ | |
| 497 | − u16 PAD[1]; | |
| 498 | − u16 pcmciaunderflowtimer; /* rev8 */ | |
| 499 | − u16 PAD[1]; | |
| 500 | − | |
| 501 | − /* interrupt */ | |
| 502 | − u32 intstatus; /* 0x020, rev8 */ | |
| 503 | − u32 hostintmask; /* rev8 */ | |
| 504 | − u32 intmask; /* rev8 */ | |
| 505 | − u32 sbintstatus; /* rev8 */ | |
| 506 | − u32 sbintmask; /* rev8 */ | |
| 507 | − u32 funcintmask; /* rev4 */ | |
| 508 | − u32 PAD[2]; | |
| 509 | − u32 tosbmailbox; /* 0x040, rev8 */ | |
| 510 | − u32 tohostmailbox; /* rev8 */ | |
| 511 | − u32 tosbmailboxdata; /* rev8 */ | |
| 512 | − u32 tohostmailboxdata; /* rev8 */ | |
| 513 | − | |
| 514 | − /* synchronized access to registers in SDIO clock domain */ | |
| 515 | − u32 sdioaccess; /* 0x050, rev8 */ | |
| 516 | − u32 PAD[3]; | |
| 517 | − | |
| 518 | − /* PCMCIA frame control */ | |
| 519 | − u8 pcmciaframectrl; /* 0x060, rev8 */ | |
| 520 | − u8 PAD[3]; | |
| 521 | − u8 pcmciawatermark; /* rev8 */ | |
| 522 | − u8 PAD[155]; | |
| 523 | − | |
| 524 | − /* interrupt batching control */ | |
| 525 | − u32 intrcvlazy; /* 0x100, rev8 */ | |
| 526 | − u32 PAD[3]; | |
| 527 | − | |
| 528 | − /* counters */ | |
| 529 | − u32 cmd52rd; /* 0x110, rev8 */ | |
| 530 | − u32 cmd52wr; /* rev8 */ | |
| 531 | − u32 cmd53rd; /* rev8 */ | |
| 532 | − u32 cmd53wr; /* rev8 */ | |
| 533 | − u32 abort; /* rev8 */ | |
| 534 | − u32 datacrcerror; /* rev8 */ | |
| 535 | − u32 rdoutofsync; /* rev8 */ | |
| 536 | − u32 wroutofsync; /* rev8 */ | |
| 537 | − u32 writebusy; /* rev8 */ | |
| 538 | − u32 readwait; /* rev8 */ | |
| 539 | − u32 readterm; /* rev8 */ | |
| 540 | − u32 writeterm; /* rev8 */ | |
| 541 | − u32 PAD[40]; | |
| 542 | − u32 clockctlstatus; /* rev8 */ | |
| 543 | − u32 PAD[7]; | |
| 544 | − | |
| 545 | − u32 PAD[128]; /* DMA engines */ | |
| 546 | − | |
| 547 | − /* SDIO/PCMCIA CIS region */ | |
| 548 | − char cis[512]; /* 0x400-0x5ff, rev6 */ | |
| 549 | − | |
| 550 | − /* PCMCIA function control registers */ | |
| 551 | − char pcmciafcr[256]; /* 0x600-6ff, rev6 */ | |
| 552 | − u16 PAD[55]; | |
| 553 | − | |
| 554 | − /* PCMCIA backplane access */ | |
| 555 | − u16 backplanecsr; /* 0x76E, rev6 */ | |
| 556 | − u16 backplaneaddr0; /* rev6 */ | |
| 557 | − u16 backplaneaddr1; /* rev6 */ | |
| 558 | − u16 backplaneaddr2; /* rev6 */ | |
| 559 | − u16 backplaneaddr3; /* rev6 */ | |
| 560 | − u16 backplanedata0; /* rev6 */ | |
| 561 | − u16 backplanedata1; /* rev6 */ | |
| 562 | − u16 backplanedata2; /* rev6 */ | |
| 563 | − u16 backplanedata3; /* rev6 */ | |
| 564 | − u16 PAD[31]; | |
| 565 | − | |
| 566 | − /* sprom "size" & "blank" info */ | |
| 567 | − u16 spromstatus; /* 0x7BE, rev2 */ | |
| 568 | − u32 PAD[464]; | |
| 569 | − | |
| 570 | − u16 PAD[0x80]; | |
| 571 | −}; | |
| 572 | − | |
| 573 | −#ifdef BCMDBG | |
| 574 | −/* Device console log buffer state */ | |
| 575 | −struct brcmf_console { | |
| 576 | − uint count; /* Poll interval msec counter */ | |
| 577 | − uint log_addr; /* Log struct address (fixed) */ | |
| 578 | − struct rte_log log; /* Log struct (host copy) */ | |
| 579 | − uint bufsize; /* Size of log buffer */ | |
| 580 | − u8 *buf; /* Log buffer (host copy) */ | |
| 581 | − uint last; /* Last buffer read index */ | |
| 582 | −}; | |
| 583 | −#endif /* BCMDBG */ | |
| 584 | − | |
| 585 | −struct sdpcm_shared { | |
| 586 | − u32 flags; | |
| 587 | − u32 trap_addr; | |
| 588 | − u32 assert_exp_addr; | |
| 589 | − u32 assert_file_addr; | |
| 590 | − u32 assert_line; | |
| 591 | − u32 console_addr; /* Address of struct rte_console */ | |
| 592 | − u32 msgtrace_addr; | |
| 593 | − u8 tag[32]; | |
| 594 | −}; | |
| 595 | − | |
| 596 | − | |
| 597 | −/* misc chip info needed by some of the routines */ | |
| 598 | −struct chip_info { | |
| 599 | − u32 chip; | |
| 600 | − u32 chiprev; | |
| 601 | − u32 cccorebase; | |
| 602 | − u32 ccrev; | |
| 603 | − u32 cccaps; | |
| 604 | − u32 buscorebase; /* 32 bits backplane bus address */ | |
| 605 | − u32 buscorerev; | |
| 606 | − u32 buscoretype; | |
| 607 | − u32 ramcorebase; | |
| 608 | − u32 armcorebase; | |
| 609 | − u32 pmurev; | |
| 610 | − u32 ramsize; | |
| 611 | −}; | |
| 612 | − | |
| 613 | −/* Private data for SDIO bus interaction */ | |
| 614 | −struct brcmf_bus { | |
| 615 | − struct brcmf_pub *drvr; | |
| 616 | − | |
| 617 | − struct brcmf_sdio_card *card; /* Handle for sdio card calls */ | |
| 618 | − struct chip_info *ci; /* Chip info struct */ | |
| 619 | − char *vars; /* Variables (from CIS and/or other) */ | |
| 620 | − uint varsz; /* Size of variables buffer */ | |
| 621 | − | |
| 622 | − u32 ramsize; /* Size of RAM in SOCRAM (bytes) */ | |
| 623 | − u32 orig_ramsize; /* Size of RAM in SOCRAM (bytes) */ | |
| 624 | − | |
| 625 | − u32 bus; /* gSPI or SDIO bus */ | |
| 626 | − u32 hostintmask; /* Copy of Host Interrupt Mask */ | |
| 627 | − u32 intstatus; /* Intstatus bits (events) pending */ | |
| 628 | − bool dpc_sched; /* Indicates DPC schedule (intrpt rcvd) */ | |
| 629 | − bool fcstate; /* State of dongle flow-control */ | |
| 630 | − | |
| 631 | − u16 cl_devid; /* cached devid for brcmf_sdio_probe_attach() */ | |
| 632 | − | |
| 633 | − uint blocksize; /* Block size of SDIO transfers */ | |
| 634 | − uint roundup; /* Max roundup limit */ | |
| 635 | − | |
| 636 | − struct pktq txq; /* Queue length used for flow-control */ | |
| 637 | − u8 flowcontrol; /* per prio flow control bitmask */ | |
| 638 | − u8 tx_seq; /* Transmit sequence number (next) */ | |
| 639 | − u8 tx_max; /* Maximum transmit sequence allowed */ | |
| 640 | − | |
| 641 | − u8 hdrbuf[MAX_HDR_READ + BRCMF_SDALIGN]; | |
| 642 | − u8 *rxhdr; /* Header of current rx frame (in hdrbuf) */ | |
| 643 | − u16 nextlen; /* Next Read Len from last header */ | |
| 644 | − u8 rx_seq; /* Receive sequence number (expected) */ | |
| 645 | − bool rxskip; /* Skip receive (awaiting NAK ACK) */ | |
| 646 | − | |
| 647 | − struct sk_buff *glomd; /* Packet containing glomming descriptor */ | |
| 648 | − struct sk_buff *glom; /* Packet chain for glommed superframe */ | |
| 649 | − uint glomerr; /* Glom packet read errors */ | |
| 650 | − | |
| 651 | − u8 *rxbuf; /* Buffer for receiving control packets */ | |
| 652 | − uint rxblen; /* Allocated length of rxbuf */ | |
| 653 | − u8 *rxctl; /* Aligned pointer into rxbuf */ | |
| 654 | − u8 *databuf; /* Buffer for receiving big glom packet */ | |
| 655 | − u8 *dataptr; /* Aligned pointer into databuf */ | |
| 656 | − uint rxlen; /* Length of valid data in buffer */ | |
| 657 | − | |
| 658 | − u8 sdpcm_ver; /* Bus protocol reported by dongle */ | |
| 659 | − | |
| 660 | − bool intr; /* Use interrupts */ | |
| 661 | − bool poll; /* Use polling */ | |
| 662 | − bool ipend; /* Device interrupt is pending */ | |
| 663 | − bool intdis; /* Interrupts disabled by isr */ | |
| 664 | − uint intrcount; /* Count of device interrupt callbacks */ | |
| 665 | − uint lastintrs; /* Count as of last watchdog timer */ | |
| 666 | − uint spurious; /* Count of spurious interrupts */ | |
| 667 | − uint pollrate; /* Ticks between device polls */ | |
| 668 | − uint polltick; /* Tick counter */ | |
| 669 | − uint pollcnt; /* Count of active polls */ | |
| 670 | − | |
| 671 | −#ifdef BCMDBG | |
| 672 | − struct brcmf_console console; /* Console output polling support */ | |
| 673 | − uint console_addr; /* Console address from shared struct */ | |
| 674 | −#endif /* BCMDBG */ | |
| 675 | − | |
| 676 | − uint regfails; /* Count of R_REG failures */ | |
| 677 | − | |
| 678 | − uint clkstate; /* State of sd and backplane clock(s) */ | |
| 679 | − bool activity; /* Activity flag for clock down */ | |
| 680 | − s32 idletime; /* Control for activity timeout */ | |
| 681 | − s32 idlecount; /* Activity timeout counter */ | |
| 682 | − s32 idleclock; /* How to set bus driver when idle */ | |
| 683 | − s32 sd_rxchain; | |
| 684 | − bool use_rxchain; /* If brcmf should use PKT chains */ | |
| 685 | − bool sleeping; /* Is SDIO bus sleeping? */ | |
| 686 | − bool rxflow_mode; /* Rx flow control mode */ | |
| 687 | − bool rxflow; /* Is rx flow control on */ | |
| 688 | − bool alp_only; /* Don't use HT clock (ALP only) */ | |
| 689 | −/* Field to decide if rx of control frames happen in rxbuf or lb-pool */ | |
| 690 | − bool usebufpool; | |
| 691 | − | |
| 692 | −#ifdef SDTEST | |
| 693 | − /* external loopback */ | |
| 694 | − bool ext_loop; | |
| 695 | − u8 loopid; | |
| 696 | − | |
| 697 | − /* pktgen configuration */ | |
| 698 | − uint pktgen_freq; /* Ticks between bursts */ | |
| 699 | − uint pktgen_count; /* Packets to send each burst */ | |
| 700 | − uint pktgen_print; /* Bursts between count displays */ | |
| 701 | − uint pktgen_total; /* Stop after this many */ | |
| 702 | − uint pktgen_minlen; /* Minimum packet data len */ | |
| 703 | − uint pktgen_maxlen; /* Maximum packet data len */ | |
| 704 | − uint pktgen_mode; /* Configured mode: tx, rx, or echo */ | |
| 705 | − uint pktgen_stop; /* Number of tx failures causing stop */ | |
| 706 | − | |
| 707 | − /* active pktgen fields */ | |
| 708 | − uint pktgen_tick; /* Tick counter for bursts */ | |
| 709 | − uint pktgen_ptick; /* Burst counter for printing */ | |
| 710 | − uint pktgen_sent; /* Number of test packets generated */ | |
| 711 | − uint pktgen_rcvd; /* Number of test packets received */ | |
| 712 | − uint pktgen_fail; /* Number of failed send attempts */ | |
| 713 | − u16 pktgen_len; /* Length of next packet to send */ | |
| 714 | −#endif /* SDTEST */ | |
| 715 | − | |
| 716 | − /* Some additional counters */ | |
| 717 | − uint tx_sderrs; /* Count of tx attempts with sd errors */ | |
| 718 | − uint fcqueued; /* Tx packets that got queued */ | |
| 719 | − uint rxrtx; /* Count of rtx requests (NAK to dongle) */ | |
| 720 | − uint rx_toolong; /* Receive frames too long to receive */ | |
| 721 | − uint rxc_errors; /* SDIO errors when reading control frames */ | |
| 722 | − uint rx_hdrfail; /* SDIO errors on header reads */ | |
| 723 | − uint rx_badhdr; /* Bad received headers (roosync?) */ | |
| 724 | − uint rx_badseq; /* Mismatched rx sequence number */ | |
| 725 | − uint fc_rcvd; /* Number of flow-control events received */ | |
| 726 | − uint fc_xoff; /* Number which turned on flow-control */ | |
| 727 | − uint fc_xon; /* Number which turned off flow-control */ | |
| 728 | − uint rxglomfail; /* Failed deglom attempts */ | |
| 729 | − uint rxglomframes; /* Number of glom frames (superframes) */ | |
| 730 | − uint rxglompkts; /* Number of packets from glom frames */ | |
| 731 | − uint f2rxhdrs; /* Number of header reads */ | |
| 732 | − uint f2rxdata; /* Number of frame data reads */ | |
| 733 | − uint f2txdata; /* Number of f2 frame writes */ | |
| 734 | − uint f1regdata; /* Number of f1 register accesses */ | |
| 735 | − | |
| 736 | − u8 *ctrl_frame_buf; | |
| 737 | − u32 ctrl_frame_len; | |
| 738 | − bool ctrl_frame_stat; | |
| 739 | − | |
| 740 | − spinlock_t txqlock; | |
| 741 | − wait_queue_head_t ctrl_wait; | |
| 742 | − | |
| 743 | − struct timer_list timer; | |
| 744 | − struct completion watchdog_wait; | |
| 745 | − struct task_struct *watchdog_tsk; | |
| 746 | − bool wd_timer_valid; | |
| 747 | − | |
| 748 | − struct tasklet_struct tasklet; | |
| 749 | − struct task_struct *dpc_tsk; | |
| 750 | − struct completion dpc_wait; | |
| 751 | − | |
| 752 | − bool threads_only; | |
| 753 | − struct semaphore sdsem; | |
| 754 | − spinlock_t sdlock; | |
| 755 | − | |
| 756 | − const char *fw_name; | |
| 757 | − const struct firmware *firmware; | |
| 758 | − const char *nv_name; | |
| 759 | − u32 fw_ptr; | |
| 760 | −}; | |
| 761 | − | |
| 762 | −struct sbconfig { | |
| 763 | − u32 PAD[2]; | |
| 764 | − u32 sbipsflag; /* initiator port ocp slave flag */ | |
| 765 | − u32 PAD[3]; | |
| 766 | − u32 sbtpsflag; /* target port ocp slave flag */ | |
| 767 | − u32 PAD[11]; | |
| 768 | − u32 sbtmerrloga; /* (sonics >= 2.3) */ | |
| 769 | − u32 PAD; | |
| 770 | − u32 sbtmerrlog; /* (sonics >= 2.3) */ | |
| 771 | − u32 PAD[3]; | |
| 772 | − u32 sbadmatch3; /* address match3 */ | |
| 773 | − u32 PAD; | |
| 774 | − u32 sbadmatch2; /* address match2 */ | |
| 775 | − u32 PAD; | |
| 776 | − u32 sbadmatch1; /* address match1 */ | |
| 777 | − u32 PAD[7]; | |
| 778 | − u32 sbimstate; /* initiator agent state */ | |
| 779 | − u32 sbintvec; /* interrupt mask */ | |
| 780 | − u32 sbtmstatelow; /* target state */ | |
| 781 | − u32 sbtmstatehigh; /* target state */ | |
| 782 | − u32 sbbwa0; /* bandwidth allocation table0 */ | |
| 783 | − u32 PAD; | |
| 784 | − u32 sbimconfiglow; /* initiator configuration */ | |
| 785 | − u32 sbimconfighigh; /* initiator configuration */ | |
| 786 | − u32 sbadmatch0; /* address match0 */ | |
| 787 | − u32 PAD; | |
| 788 | − u32 sbtmconfiglow; /* target configuration */ | |
| 789 | − u32 sbtmconfighigh; /* target configuration */ | |
| 790 | − u32 sbbconfig; /* broadcast configuration */ | |
| 791 | − u32 PAD; | |
| 792 | − u32 sbbstate; /* broadcast state */ | |
| 793 | − u32 PAD[3]; | |
| 794 | − u32 sbactcnfg; /* activate configuration */ | |
| 795 | − u32 PAD[3]; | |
| 796 | − u32 sbflagst; /* current sbflags */ | |
| 797 | − u32 PAD[3]; | |
| 798 | − u32 sbidlow; /* identification */ | |
| 799 | − u32 sbidhigh; /* identification */ | |
| 800 | −}; | |
| 801 | − | |
| 802 | −/* clkstate */ | |
| 803 | −#define CLK_NONE 0 | |
| 804 | −#define CLK_SDONLY 1 | |
| 805 | −#define CLK_PENDING 2 /* Not used yet */ | |
| 806 | −#define CLK_AVAIL 3 | |
| 807 | − | |
| 808 | −#define BRCMF_NOPMU(brcmf) (false) | |
| 809 | − | |
| 810 | −#ifdef BCMDBG | |
| 811 | −static int qcount[NUMPRIO]; | |
| 812 | −static int tx_packets[NUMPRIO]; | |
| 813 | −#endif /* BCMDBG */ | |
| 814 | − | |
| 815 | −/* Deferred transmit */ | |
| 816 | −uint brcmf_deferred_tx = 1; | |
| 817 | −module_param(brcmf_deferred_tx, uint, 0); | |
| 818 | − | |
| 819 | −/* Watchdog thread priority, -1 to use kernel timer */ | |
| 820 | −int brcmf_watchdog_prio = 97; | |
| 821 | −module_param(brcmf_watchdog_prio, int, 0); | |
| 822 | − | |
| 823 | −/* Watchdog interval */ | |
| 824 | −uint brcmf_watchdog_ms = 10; | |
| 825 | −module_param(brcmf_watchdog_ms, uint, 0); | |
| 826 | − | |
| 827 | −/* DPC thread priority, -1 to use tasklet */ | |
| 828 | −int brcmf_dpc_prio = 98; | |
| 829 | −module_param(brcmf_dpc_prio, int, 0); | |
| 830 | − | |
| 831 | −#ifdef BCMDBG | |
| 832 | −/* Console poll interval */ | |
| 833 | −uint brcmf_console_ms; | |
| 834 | −module_param(brcmf_console_ms, uint, 0); | |
| 835 | −#endif /* BCMDBG */ | |
| 836 | − | |
| 837 | −/* Tx/Rx bounds */ | |
| 838 | −uint brcmf_txbound; | |
| 839 | −uint brcmf_rxbound; | |
| 840 | −uint brcmf_txminmax; | |
| 841 | − | |
| 842 | −/* override the RAM size if possible */ | |
| 843 | −#define DONGLE_MIN_MEMSIZE (128 * 1024) | |
| 844 | −int brcmf_dongle_memsize; | |
| 845 | − | |
| 846 | −static bool brcmf_alignctl; | |
| 847 | − | |
| 848 | −static bool sd1idle; | |
| 849 | − | |
| 850 | −static bool retrydata; | |
| 851 | −#define RETRYCHAN(chan) (((chan) == SDPCM_EVENT_CHANNEL) || retrydata) | |
| 852 | − | |
| 853 | −static const uint watermark = 8; | |
| 854 | −static const uint firstread = BRCMF_FIRSTREAD; | |
| 855 | − | |
| 856 | −/* Retry count for register access failures */ | |
| 857 | −static const uint retry_limit = 2; | |
| 858 | − | |
| 859 | −/* Force even SD lengths (some host controllers mess up on odd bytes) */ | |
| 860 | −static bool forcealign; | |
| 861 | − | |
| 862 | −#define ALIGNMENT 4 | |
| 863 | − | |
| 864 | −#define PKTALIGN(_p, _len, _align) \ | |
| 865 | − do { \ | |
| 866 | − uint datalign; \ | |
| 867 | − datalign = (unsigned long)((_p)->data); \ | |
| 868 | − datalign = roundup(datalign, (_align)) - datalign; \ | |
| 869 | − if (datalign) \ | |
| 870 | − skb_pull((_p), datalign); \ | |
| 871 | − __skb_trim((_p), (_len)); \ | |
| 872 | − } while (0) | |
| 873 | − | |
| 874 | −/* Limit on rounding up frames */ | |
| 875 | −static const uint max_roundup = 512; | |
| 876 | − | |
| 877 | −/* Try doing readahead */ | |
| 878 | −static bool brcmf_readahead; | |
| 879 | − | |
| 880 | −/* To check if there's window offered */ | |
| 881 | −#define DATAOK(bus) \ | |
| 882 | − (((u8)(bus->tx_max - bus->tx_seq) != 0) && \ | |
| 883 | − (((u8)(bus->tx_max - bus->tx_seq) & 0x80) == 0)) | |
| 884 | − | |
| 885 | −/* | |
| 886 | − * Reads a register in the SDIO hardware block. This block occupies a series of | |
| 887 | − * adresses on the 32 bit backplane bus. | |
| 888 | − */ | |
| 889 | −static void | |
| 890 | −r_sdreg32(struct brcmf_bus *bus, u32 *regvar, u32 reg_offset, u32 *retryvar) | |
| 891 | −{ | |
| 892 | − *retryvar = 0; | |
| 893 | − do { | |
| 894 | − *regvar = R_REG(bus->ci->buscorebase + reg_offset, u32); | |
| 895 | − } while (brcmf_sdcard_regfail(bus->card) && | |
| 896 | − (++(*retryvar) <= retry_limit)); | |
| 897 | − if (*retryvar) { | |
| 898 | − bus->regfails += (*retryvar-1); | |
| 899 | − if (*retryvar > retry_limit) { | |
| 900 | − BRCMF_ERROR(("FAILED READ %Xh\n", reg_offset)); | |
| 901 | − *regvar = 0; | |
| 902 | − } | |
| 903 | − } | |
| 904 | −} | |
| 905 | − | |
| 906 | −static void | |
| 907 | −w_sdreg32(struct brcmf_bus *bus, u32 regval, u32 reg_offset, u32 *retryvar) | |
| 908 | −{ | |
| 909 | − *retryvar = 0; | |
| 910 | − do { | |
| 911 | − brcmf_sdcard_reg_write(NULL, bus->ci->buscorebase + reg_offset, | |
| 912 | − sizeof(u32), regval); | |
| 913 | − } while (brcmf_sdcard_regfail(bus->card) && | |
| 914 | − (++(*retryvar) <= retry_limit)); | |
| 915 | − if (*retryvar) { | |
| 916 | − bus->regfails += (*retryvar-1); | |
| 917 | − if (*retryvar > retry_limit) | |
| 918 | − BRCMF_ERROR(("FAILED REGISTER WRITE" | |
| 919 | − " %Xh\n", reg_offset)); | |
| 920 | − } | |
| 921 | −} | |
| 922 | − | |
| 923 | −#define BRCMF_BUS SDIO_BUS | |
| 924 | − | |
| 925 | −#define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND) | |
| 926 | − | |
| 927 | −#define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE) | |
| 928 | − | |
| 929 | −#ifdef SDTEST | |
| 930 | −static void brcmf_sdbrcm_checkdied(struct brcmf_bus *bus, void *pkt, uint seq); | |
| 931 | −static void brcmf_sdbrcm_sdtest_set(struct brcmf_bus *bus, bool start); | |
| 932 | −#endif | |
| 933 | − | |
| 934 | −#ifdef BCMDBG | |
| 935 | −static int brcmf_sdbrcm_bus_console_in(struct brcmf_pub *drvr, | |
| 936 | − unsigned char *msg, uint msglen); | |
| 937 | −static int brcmf_sdbrcm_checkdied(struct brcmf_bus *bus, u8 *data, uint size); | |
| 938 | −static int brcmf_sdbrcm_mem_dump(struct brcmf_bus *bus); | |
| 939 | −#endif /* BCMDBG */ | |
| 940 | −static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter); | |
| 941 | − | |
| 942 | −static void brcmf_sdbrcm_release(struct brcmf_bus *bus); | |
| 943 | −static void brcmf_sdbrcm_release_malloc(struct brcmf_bus *bus); | |
| 944 | −static void brcmf_sdbrcm_disconnect(void *ptr); | |
| 945 | −static bool brcmf_sdbrcm_chipmatch(u16 chipid); | |
| 946 | −static bool brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, void *card, | |
| 947 | − u32 regsva, u16 devid); | |
| 948 | −static bool brcmf_sdbrcm_probe_malloc(struct brcmf_bus *bus, void *card); | |
| 949 | −static bool brcmf_sdbrcm_probe_init(struct brcmf_bus *bus, void *card); | |
| 950 | −static void brcmf_sdbrcm_release_dongle(struct brcmf_bus *bus); | |
| 951 | − | |
| 952 | −static uint brcmf_process_nvram_vars(char *varbuf, uint len); | |
| 953 | − | |
| 954 | −static void brcmf_sdbrcm_setmemsize(struct brcmf_bus *bus, int mem_size); | |
| 955 | −static int brcmf_sdbrcm_send_buf(struct brcmf_bus *bus, u32 addr, uint fn, | |
| 956 | − uint flags, u8 *buf, uint nbytes, | |
| 957 | − struct sk_buff *pkt, | |
| 958 | − void (*complete)(void *handle, int status, | |
| 959 | − bool sync_waiting), | |
| 960 | − void *handle); | |
| 961 | − | |
| 962 | −static bool brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus, void *card); | |
| 963 | −static int _brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus); | |
| 964 | − | |
| 965 | −static int brcmf_sdbrcm_download_code_file(struct brcmf_bus *bus); | |
| 966 | −static int brcmf_sdbrcm_download_nvram(struct brcmf_bus *bus); | |
| 967 | − | |
| 968 | −static void | |
| 969 | −brcmf_sdbrcm_chip_disablecore(struct brcmf_sdio_card *card, u32 corebase); | |
| 970 | − | |
| 971 | −static int brcmf_sdbrcm_chip_attach(struct brcmf_bus *bus, u32 regs); | |
| 972 | − | |
| 973 | −static void | |
| 974 | −brcmf_sdbrcm_chip_resetcore(struct brcmf_sdio_card *card, u32 corebase); | |
| 975 | − | |
| 976 | −static void brcmf_sdbrcm_sdiod_drive_strength_init(struct brcmf_bus *bus, | |
| 977 | − u32 drivestrength); | |
| 978 | −static void brcmf_sdbrcm_chip_detach(struct brcmf_bus *bus); | |
| 979 | −static void brcmf_sdbrcm_wait_for_event(struct brcmf_bus *bus, bool *lockvar); | |
| 980 | −static void brcmf_sdbrcm_wait_event_wakeup(struct brcmf_bus *bus); | |
| 981 | −static void brcmf_sdbrcm_watchdog(unsigned long data); | |
| 982 | −static int brcmf_sdbrcm_watchdog_thread(void *data); | |
| 983 | −static int brcmf_sdbrcm_dpc_thread(void *data); | |
| 984 | −static void brcmf_sdbrcm_dpc_tasklet(unsigned long data); | |
| 985 | −static void brcmf_sdbrcm_sched_dpc(struct brcmf_bus *bus); | |
| 986 | −static void brcmf_sdbrcm_sdlock(struct brcmf_bus *bus); | |
| 987 | −static void brcmf_sdbrcm_sdunlock(struct brcmf_bus *bus); | |
| 988 | −static int brcmf_sdbrcm_get_image(char *buf, int len, struct brcmf_bus *bus); | |
| 989 | − | |
| 990 | −/* Packet free applicable unconditionally for sdio and sdspi. | |
| 991 | − * Conditional if bufpool was present for gspi bus. | |
| 992 | − */ | |
| 993 | −static void brcmf_sdbrcm_pktfree2(struct brcmf_bus *bus, struct sk_buff *pkt) | |
| 994 | −{ | |
| 995 | − if ((bus->bus != SPI_BUS) || bus->usebufpool) | |
| 996 | − brcmu_pkt_buf_free_skb(pkt); | |
| 997 | −} | |
| 998 | − | |
| 999 | −static void brcmf_sdbrcm_setmemsize(struct brcmf_bus *bus, int mem_size) | |
| 1000 | −{ | |
| 1001 | − s32 min_size = DONGLE_MIN_MEMSIZE; | |
| 1002 | − /* Restrict the memsize to user specified limit */ | |
| 1003 | − BRCMF_ERROR(("user: Restrict the dongle ram size to %d, min %d\n", | |
| 1004 | − brcmf_dongle_memsize, min_size)); | |
| 1005 | − if ((brcmf_dongle_memsize > min_size) && | |
| 1006 | − (brcmf_dongle_memsize < (s32) bus->orig_ramsize)) | |
| 1007 | − bus->ramsize = brcmf_dongle_memsize; | |
| 1008 | −} | |
| 1009 | − | |
| 1010 | −static int brcmf_sdbrcm_set_siaddr_window(struct brcmf_bus *bus, u32 address) | |
| 1011 | −{ | |
| 1012 | − int err = 0; | |
| 1013 | − brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, | |
| 1014 | − (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err); | |
| 1015 | − if (!err) | |
| 1016 | − brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, | |
| 1017 | − SBSDIO_FUNC1_SBADDRMID, | |
| 1018 | − (address >> 16) & SBSDIO_SBADDRMID_MASK, &err); | |
| 1019 | − if (!err) | |
| 1020 | − brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, | |
| 1021 | − SBSDIO_FUNC1_SBADDRHIGH, | |
| 1022 | − (address >> 24) & SBSDIO_SBADDRHIGH_MASK, | |
| 1023 | − &err); | |
| 1024 | − return err; | |
| 1025 | −} | |
| 1026 | − | |
| 1027 | −/* Turn backplane clock on or off */ | |
| 1028 | −static int brcmf_sdbrcm_htclk(struct brcmf_bus *bus, bool on, bool pendok) | |
| 1029 | −{ | |
| 1030 | − int err; | |
| 1031 | − u8 clkctl, clkreq, devctl; | |
| 1032 | − struct brcmf_sdio_card *card; | |
| 1033 | − | |
| 1034 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 1035 | − | |
| 1036 | − clkctl = 0; | |
| 1037 | − card = bus->card; | |
| 1038 | − | |
| 1039 | − if (on) { | |
| 1040 | − /* Request HT Avail */ | |
| 1041 | − clkreq = | |
| 1042 | − bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ; | |
| 1043 | − | |
| 1044 | − if ((bus->ci->chip == BCM4329_CHIP_ID) | |
| 1045 | − && (bus->ci->chiprev == 0)) | |
| 1046 | − clkreq |= SBSDIO_FORCE_ALP; | |
| 1047 | − | |
| 1048 | − brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, | |
| 1049 | − SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); | |
| 1050 | − if (err) { | |
| 1051 | − BRCMF_ERROR(("%s: HT Avail request error: %d\n", | |
| 1052 | − __func__, err)); | |
| 1053 | − return -EBADE; | |
| 1054 | − } | |
| 1055 | − | |
| 1056 | − if (pendok && ((bus->ci->buscoretype == PCMCIA_CORE_ID) | |
| 1057 | − && (bus->ci->buscorerev == 9))) { | |
| 1058 | − u32 dummy, retries; | |
| 1059 | − r_sdreg32(bus, &dummy, | |
| 1060 | − offsetof(struct sdpcmd_regs, clockctlstatus), | |
| 1061 | − &retries); | |
| 1062 | − } | |
| 1063 | − | |
| 1064 | − /* Check current status */ | |
| 1065 | − clkctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, | |
| 1066 | − SBSDIO_FUNC1_CHIPCLKCSR, &err); | |
| 1067 | − if (err) { | |
| 1068 | − BRCMF_ERROR(("%s: HT Avail read error: %d\n", | |
| 1069 | − __func__, err)); | |
| 1070 | − return -EBADE; | |
| 1071 | − } | |
| 1072 | − | |
| 1073 | − /* Go to pending and await interrupt if appropriate */ | |
| 1074 | − if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) { | |
| 1075 | − /* Allow only clock-available interrupt */ | |
| 1076 | − devctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, | |
| 1077 | − SBSDIO_DEVICE_CTL, &err); | |
| 1078 | − if (err) { | |
| 1079 | − BRCMF_ERROR(("%s: Devctl error setting CA:" | |
| 1080 | − " %d\n", __func__, err)); | |
| 1081 | − return -EBADE; | |
| 1082 | − } | |
| 1083 | − | |
| 1084 | − devctl |= SBSDIO_DEVCTL_CA_INT_ONLY; | |
| 1085 | − brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, | |
| 1086 | − SBSDIO_DEVICE_CTL, devctl, &err); | |
| 1087 | − BRCMF_INFO(("CLKCTL: set PENDING\n")); | |
| 1088 | − bus->clkstate = CLK_PENDING; | |
| 1089 | − | |
| 1090 | − return 0; | |
| 1091 | − } else if (bus->clkstate == CLK_PENDING) { | |
| 1092 | − /* Cancel CA-only interrupt filter */ | |
| 1093 | − devctl = | |
| 1094 | − brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, | |
| 1095 | − SBSDIO_DEVICE_CTL, &err); | |
| 1096 | − devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; | |
| 1097 | − brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, | |
| 1098 | − SBSDIO_DEVICE_CTL, devctl, &err); | |
| 1099 | − } | |
| 1100 | − | |
| 1101 | − /* Otherwise, wait here (polling) for HT Avail */ | |
| 1102 | − if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { | |
| 1103 | − BRCMF_SPINWAIT_SLEEP(sdioh_spinwait_sleep, | |
| 1104 | − ((clkctl = | |
| 1105 | − brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, | |
| 1106 | − SBSDIO_FUNC1_CHIPCLKCSR, | |
| 1107 | − &err)), | |
| 1108 | − !SBSDIO_CLKAV(clkctl, bus->alp_only)), | |
| 1109 | − PMU_MAX_TRANSITION_DLY); | |
| 1110 | − } | |
| 1111 | − if (err) { | |
| 1112 | − BRCMF_ERROR(("%s: HT Avail request error: %d\n", | |
| 1113 | − __func__, err)); | |
| 1114 | − return -EBADE; | |
| 1115 | − } | |
| 1116 | − if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { | |
| 1117 | − BRCMF_ERROR(("%s: HT Avail timeout (%d): " | |
| 1118 | − "clkctl 0x%02x\n", __func__, | |
| 1119 | − PMU_MAX_TRANSITION_DLY, clkctl)); | |
| 1120 | − return -EBADE; | |
| 1121 | − } | |
| 1122 | − | |
| 1123 | − /* Mark clock available */ | |
| 1124 | − bus->clkstate = CLK_AVAIL; | |
| 1125 | − BRCMF_INFO(("CLKCTL: turned ON\n")); | |
| 1126 | − | |
| 1127 | −#if defined(BCMDBG) | |
| 1128 | − if (bus->alp_only != true) { | |
| 1129 | − if (SBSDIO_ALPONLY(clkctl)) { | |
| 1130 | − BRCMF_ERROR(("%s: HT Clock should be on.\n", | |
| 1131 | − __func__)); | |
| 1132 | − } | |
| 1133 | − } | |
| 1134 | −#endif /* defined (BCMDBG) */ | |
| 1135 | − | |
| 1136 | − bus->activity = true; | |
| 1137 | − } else { | |
| 1138 | − clkreq = 0; | |
| 1139 | − | |
| 1140 | − if (bus->clkstate == CLK_PENDING) { | |
| 1141 | − /* Cancel CA-only interrupt filter */ | |
| 1142 | − devctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, | |
| 1143 | − SBSDIO_DEVICE_CTL, &err); | |
| 1144 | − devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; | |
| 1145 | − brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, | |
| 1146 | − SBSDIO_DEVICE_CTL, devctl, &err); | |
| 1147 | − } | |
| 1148 | − | |
| 1149 | − bus->clkstate = CLK_SDONLY; | |
| 1150 | − brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, | |
| 1151 | − SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); | |
| 1152 | − BRCMF_INFO(("CLKCTL: turned OFF\n")); | |
| 1153 | − if (err) { | |
| 1154 | − BRCMF_ERROR(("%s: Failed access turning clock off:" | |
| 1155 | − " %d\n", __func__, err)); | |
| 1156 | − return -EBADE; | |
| 1157 | − } | |
| 1158 | − } | |
| 1159 | − return 0; | |
| 1160 | −} | |
| 1161 | − | |
| 1162 | −/* Change idle/active SD state */ | |
| 1163 | −static int brcmf_sdbrcm_sdclk(struct brcmf_bus *bus, bool on) | |
| 1164 | −{ | |
| 1165 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 1166 | − | |
| 1167 | − if (on) | |
| 1168 | − bus->clkstate = CLK_SDONLY; | |
| 1169 | − else | |
| 1170 | − bus->clkstate = CLK_NONE; | |
| 1171 | − | |
| 1172 | − return 0; | |
| 1173 | −} | |
| 1174 | − | |
| 1175 | −/* Transition SD and backplane clock readiness */ | |
| 1176 | −static int brcmf_sdbrcm_clkctl(struct brcmf_bus *bus, uint target, bool pendok) | |
| 1177 | −{ | |
| 1178 | −#ifdef BCMDBG | |
| 1179 | − uint oldstate = bus->clkstate; | |
| 1180 | −#endif /* BCMDBG */ | |
| 1181 | − | |
| 1182 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 1183 | − | |
| 1184 | − /* Early exit if we're already there */ | |
| 1185 | − if (bus->clkstate == target) { | |
| 1186 | − if (target == CLK_AVAIL) { | |
| 1187 | − brcmf_sdbrcm_wd_timer(bus, brcmf_watchdog_ms); | |
| 1188 | − bus->activity = true; | |
| 1189 | − } | |
| 1190 | − return 0; | |
| 1191 | − } | |
| 1192 | − | |
| 1193 | − switch (target) { | |
| 1194 | − case CLK_AVAIL: | |
| 1195 | − /* Make sure SD clock is available */ | |
| 1196 | − if (bus->clkstate == CLK_NONE) | |
| 1197 | − brcmf_sdbrcm_sdclk(bus, true); | |
| 1198 | − /* Now request HT Avail on the backplane */ | |
| 1199 | − brcmf_sdbrcm_htclk(bus, true, pendok); | |
| 1200 | − brcmf_sdbrcm_wd_timer(bus, brcmf_watchdog_ms); | |
| 1201 | − bus->activity = true; | |
| 1202 | − break; | |
| 1203 | − | |
| 1204 | − case CLK_SDONLY: | |
| 1205 | − /* Remove HT request, or bring up SD clock */ | |
| 1206 | − if (bus->clkstate == CLK_NONE) | |
| 1207 | − brcmf_sdbrcm_sdclk(bus, true); | |
| 1208 | − else if (bus->clkstate == CLK_AVAIL) | |
| 1209 | − brcmf_sdbrcm_htclk(bus, false, false); | |
| 1210 | − else | |
| 1211 | − BRCMF_ERROR(("brcmf_sdbrcm_clkctl: request for %d -> %d" | |
| 1212 | − "\n", bus->clkstate, target)); | |
| 1213 | − brcmf_sdbrcm_wd_timer(bus, brcmf_watchdog_ms); | |
| 1214 | − break; | |
| 1215 | − | |
| 1216 | − case CLK_NONE: | |
| 1217 | − /* Make sure to remove HT request */ | |
| 1218 | − if (bus->clkstate == CLK_AVAIL) | |
| 1219 | − brcmf_sdbrcm_htclk(bus, false, false); | |
| 1220 | − /* Now remove the SD clock */ | |
| 1221 | − brcmf_sdbrcm_sdclk(bus, false); | |
| 1222 | − brcmf_sdbrcm_wd_timer(bus, 0); | |
| 1223 | − break; | |
| 1224 | − } | |
| 1225 | −#ifdef BCMDBG | |
| 1226 | − BRCMF_INFO(("brcmf_sdbrcm_clkctl: %d -> %d\n", | |
| 1227 | − oldstate, bus->clkstate)); | |
| 1228 | −#endif /* BCMDBG */ | |
| 1229 | − | |
| 1230 | − return 0; | |
| 1231 | −} | |
| 1232 | − | |
| 1233 | −int brcmf_sdbrcm_bussleep(struct brcmf_bus *bus, bool sleep) | |
| 1234 | −{ | |
| 1235 | − struct brcmf_sdio_card *card = bus->card; | |
| 1236 | − uint retries = 0; | |
| 1237 | − | |
| 1238 | − BRCMF_INFO(("brcmf_sdbrcm_bussleep: request %s (currently %s)\n", | |
| 1239 | − (sleep ? "SLEEP" : "WAKE"), | |
| 1240 | − (bus->sleeping ? "SLEEP" : "WAKE"))); | |
| 1241 | − | |
| 1242 | − /* Done if we're already in the requested state */ | |
| 1243 | − if (sleep == bus->sleeping) | |
| 1244 | − return 0; | |
| 1245 | − | |
| 1246 | − /* Going to sleep: set the alarm and turn off the lights... */ | |
| 1247 | − if (sleep) { | |
| 1248 | − /* Don't sleep if something is pending */ | |
| 1249 | − if (bus->dpc_sched || bus->rxskip || pktq_len(&bus->txq)) | |
| 1250 | − return -EBUSY; | |
| 1251 | − | |
| 1252 | − /* Disable SDIO interrupts (no longer interested) */ | |
| 1253 | − brcmf_sdcard_intr_disable(bus->card); | |
| 1254 | − | |
| 1255 | − /* Make sure the controller has the bus up */ | |
| 1256 | − brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | |
| 1257 | − | |
| 1258 | − /* Tell device to start using OOB wakeup */ | |
| 1259 | − w_sdreg32(bus, SMB_USE_OOB, | |
| 1260 | − offsetof(struct sdpcmd_regs, tosbmailbox), &retries); | |
| 1261 | − if (retries > retry_limit) | |
| 1262 | − BRCMF_ERROR(("CANNOT SIGNAL CHIP, " | |
| 1263 | − "WILL NOT WAKE UP!!\n")); | |
| 1264 | − | |
| 1265 | − /* Turn off our contribution to the HT clock request */ | |
| 1266 | − brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); | |
| 1267 | − | |
| 1268 | − brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, | |
| 1269 | − SBSDIO_FUNC1_CHIPCLKCSR, | |
| 1270 | − SBSDIO_FORCE_HW_CLKREQ_OFF, NULL); | |
| 1271 | − | |
| 1272 | − /* Isolate the bus */ | |
| 1273 | − if (bus->ci->chip != BCM4329_CHIP_ID | |
| 1274 | − && bus->ci->chip != BCM4319_CHIP_ID) { | |
| 1275 | − brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, | |
| 1276 | − SBSDIO_DEVICE_CTL, | |
| 1277 | − SBSDIO_DEVCTL_PADS_ISO, NULL); | |
| 1278 | − } | |
| 1279 | − | |
| 1280 | − /* Change state */ | |
| 1281 | − bus->sleeping = true; | |
| 1282 | − | |
| 1283 | − } else { | |
| 1284 | − /* Waking up: bus power up is ok, set local state */ | |
| 1285 | − | |
| 1286 | − brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, | |
| 1287 | − SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); | |
| 1288 | − | |
| 1289 | − /* Force pad isolation off if possible | |
| 1290 | − (in case power never toggled) */ | |
| 1291 | − if ((bus->ci->buscoretype == PCMCIA_CORE_ID) | |
| 1292 | − && (bus->ci->buscorerev >= 10)) | |
| 1293 | − brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, | |
| 1294 | − SBSDIO_DEVICE_CTL, 0, NULL); | |
| 1295 | − | |
| 1296 | − /* Make sure the controller has the bus up */ | |
| 1297 | − brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | |
| 1298 | − | |
| 1299 | − /* Send misc interrupt to indicate OOB not needed */ | |
| 1300 | − w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, tosbmailboxdata), | |
| 1301 | − &retries); | |
| 1302 | − if (retries <= retry_limit) | |
| 1303 | − w_sdreg32(bus, SMB_DEV_INT, | |
| 1304 | − offsetof(struct sdpcmd_regs, tosbmailbox), | |
| 1305 | − &retries); | |
| 1306 | − | |
| 1307 | − if (retries > retry_limit) | |
| 1308 | − BRCMF_ERROR(("CANNOT SIGNAL CHIP TO CLEAR OOB!!\n")); | |
| 1309 | − | |
| 1310 | − /* Make sure we have SD bus access */ | |
| 1311 | − brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); | |
| 1312 | − | |
| 1313 | − /* Change state */ | |
| 1314 | − bus->sleeping = false; | |
| 1315 | − | |
| 1316 | − /* Enable interrupts again */ | |
| 1317 | − if (bus->intr && (bus->drvr->busstate == BRCMF_BUS_DATA)) { | |
| 1318 | − bus->intdis = false; | |
| 1319 | − brcmf_sdcard_intr_enable(bus->card); | |
| 1320 | − } | |
| 1321 | − } | |
| 1322 | − | |
| 1323 | − return 0; | |
| 1324 | −} | |
| 1325 | − | |
| 1326 | −#define BUS_WAKE(bus) \ | |
| 1327 | − do { \ | |
| 1328 | − if ((bus)->sleeping) \ | |
| 1329 | − brcmf_sdbrcm_bussleep((bus), false); \ | |
| 1330 | − } while (0); | |
| 1331 | − | |
| 1332 | −/* Writes a HW/SW header into the packet and sends it. */ | |
| 1333 | −/* Assumes: (a) header space already there, (b) caller holds lock */ | |
| 1334 | −static int brcmf_sdbrcm_txpkt(struct brcmf_bus *bus, struct sk_buff *pkt, uint chan, | |
| 1335 | − bool free_pkt) | |
| 1336 | −{ | |
| 1337 | − int ret; | |
| 1338 | − u8 *frame; | |
| 1339 | − u16 len, pad = 0; | |
| 1340 | − u32 swheader; | |
| 1341 | − uint retries = 0; | |
| 1342 | − struct brcmf_sdio_card *card; | |
| 1343 | − struct sk_buff *new; | |
| 1344 | − int i; | |
| 1345 | − | |
| 1346 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 1347 | − | |
| 1348 | − card = bus->card; | |
| 1349 | − | |
| 1350 | − if (bus->drvr->dongle_reset) { | |
| 1351 | − ret = -EPERM; | |
| 1352 | − goto done; | |
| 1353 | − } | |
| 1354 | − | |
| 1355 | − frame = (u8 *) (pkt->data); | |
| 1356 | − | |
| 1357 | − /* Add alignment padding, allocate new packet if needed */ | |
| 1358 | − pad = ((unsigned long)frame % BRCMF_SDALIGN); | |
| 1359 | − if (pad) { | |
| 1360 | − if (skb_headroom(pkt) < pad) { | |
| 1361 | − BRCMF_INFO(("%s: insufficient headroom %d for %d pad\n", | |
| 1362 | − __func__, skb_headroom(pkt), pad)); | |
| 1363 | − bus->drvr->tx_realloc++; | |
| 1364 | − new = brcmu_pkt_buf_get_skb(pkt->len + BRCMF_SDALIGN); | |
| 1365 | − if (!new) { | |
| 1366 | − BRCMF_ERROR(("%s: couldn't allocate new " | |
| 1367 | − "%d-byte packet\n", __func__, | |
| 1368 | − pkt->len + BRCMF_SDALIGN)); | |
| 1369 | − ret = -ENOMEM; | |
| 1370 | − goto done; | |
| 1371 | − } | |
| 1372 | − | |
| 1373 | − PKTALIGN(new, pkt->len, BRCMF_SDALIGN); | |
| 1374 | − memcpy(new->data, pkt->data, pkt->len); | |
| 1375 | − if (free_pkt) | |
| 1376 | − brcmu_pkt_buf_free_skb(pkt); | |
| 1377 | − /* free the pkt if canned one is not used */ | |
| 1378 | − free_pkt = true; | |
| 1379 | − pkt = new; | |
| 1380 | − frame = (u8 *) (pkt->data); | |
| 1381 | − /* precondition: (frame % BRCMF_SDALIGN) == 0) */ | |
| 1382 | − pad = 0; | |
| 1383 | − } else { | |
| 1384 | − skb_push(pkt, pad); | |
| 1385 | − frame = (u8 *) (pkt->data); | |
| 1386 | − /* precondition: pad + SDPCM_HDRLEN <= pkt->len */ | |
| 1387 | − memset(frame, 0, pad + SDPCM_HDRLEN); | |
| 1388 | − } | |
| 1389 | − } | |
| 1390 | − /* precondition: pad < BRCMF_SDALIGN */ | |
| 1391 | − | |
| 1392 | − /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ | |
| 1393 | − len = (u16) (pkt->len); | |
| 1394 | − *(u16 *) frame = cpu_to_le16(len); | |
| 1395 | − *(((u16 *) frame) + 1) = cpu_to_le16(~len); | |
| 1396 | − | |
| 1397 | − /* Software tag: channel, sequence number, data offset */ | |
| 1398 | − swheader = | |
| 1399 | − ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) | bus->tx_seq | | |
| 1400 | − (((pad + | |
| 1401 | − SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK); | |
| 1402 | − | |
| 1403 | − put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN); | |
| 1404 | − put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); | |
| 1405 | − | |
| 1406 | −#ifdef BCMDBG | |
| 1407 | − tx_packets[pkt->priority]++; | |
| 1408 | − if (BRCMF_BYTES_ON() && | |
| 1409 | − (((BRCMF_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) || | |
| 1410 | − (BRCMF_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) { | |
| 1411 | − printk(KERN_DEBUG "Tx Frame:\n"); | |
| 1412 | − print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, frame, len); | |
| 1413 | − } else if (BRCMF_HDRS_ON()) { | |
| 1414 | − printk(KERN_DEBUG "TxHdr:\n"); | |
| 1415 | − print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, | |
| 1416 | − frame, min_t(u16, len, 16)); | |
| 1417 | − } | |
| 1418 | −#endif | |
| 1419 | − | |
| 1420 | − /* Raise len to next SDIO block to eliminate tail command */ | |
| 1421 | − if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { | |
| 1422 | − u16 pad = bus->blocksize - (len % bus->blocksize); | |
| 1423 | − if ((pad <= bus->roundup) && (pad < bus->blocksize)) | |
| 1424 | − len += pad; | |
| 1425 | − } else if (len % BRCMF_SDALIGN) { | |
| 1426 | − len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN); | |
| 1427 | − } | |
| 1428 | − | |
| 1429 | − /* Some controllers have trouble with odd bytes -- round to even */ | |
| 1430 | − if (forcealign && (len & (ALIGNMENT - 1))) { | |
| 1431 | − len = roundup(len, ALIGNMENT); | |
| 1432 | − } | |
| 1433 | − | |
| 1434 | − do { | |
| 1435 | − ret = brcmf_sdbrcm_send_buf(bus, brcmf_sdcard_cur_sbwad(card), | |
| 1436 | − SDIO_FUNC_2, F2SYNC, frame, len, pkt, NULL, NULL); | |
| 1437 | − bus->f2txdata++; | |
| 1438 | − | |
| 1439 | − if (ret < 0) { | |
| 1440 | − /* On failure, abort the command | |
| 1441 | − and terminate the frame */ | |
| 1442 | − BRCMF_INFO(("%s: sdio error %d, abort command and " | |
| 1443 | − "terminate frame.\n", __func__, ret)); | |
| 1444 | − bus->tx_sderrs++; | |
| 1445 | − | |
| 1446 | − brcmf_sdcard_abort(card, SDIO_FUNC_2); | |
| 1447 | − brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, | |
| 1448 | − SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, | |
| 1449 | − NULL); | |
| 1450 | − bus->f1regdata++; | |
| 1451 | − | |
| 1452 | − for (i = 0; i < 3; i++) { | |
| 1453 | − u8 hi, lo; | |
| 1454 | − hi = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, | |
| 1455 | − SBSDIO_FUNC1_WFRAMEBCHI, | |
| 1456 | − NULL); | |
| 1457 | − lo = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, | |
| 1458 | − SBSDIO_FUNC1_WFRAMEBCLO, | |
| 1459 | − NULL); | |
| 1460 | − bus->f1regdata += 2; | |
| 1461 | − if ((hi == 0) && (lo == 0)) | |
| 1462 | − break; | |
| 1463 | − } | |
| 1464 | − | |
| 1465 | − } | |
| 1466 | − if (ret == 0) | |
| 1467 | − bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; | |
| 1468 | − | |
| 1469 | − } while ((ret < 0) && retrydata && retries++ < TXRETRIES); | |
| 1470 | − | |
| 1471 | −done: | |
| 1472 | − /* restore pkt buffer pointer before calling tx complete routine */ | |
| 1473 | − skb_pull(pkt, SDPCM_HDRLEN + pad); | |
| 1474 | − brcmf_sdbrcm_sdunlock(bus); | |
| 1475 | − brcmf_txcomplete(bus->drvr, pkt, ret != 0); | |
| 1476 | − brcmf_sdbrcm_sdlock(bus); | |
| 1477 | − | |
| 1478 | − if (free_pkt) | |
| 1479 | − brcmu_pkt_buf_free_skb(pkt); | |
| 1480 | − | |
| 1481 | − return ret; | |
| 1482 | −} | |
| 1483 | − | |
| 1484 | −int brcmf_sdbrcm_bus_txdata(struct brcmf_bus *bus, struct sk_buff *pkt) | |
| 1485 | −{ | |
| 1486 | − int ret = -EBADE; | |
| 1487 | − uint datalen, prec; | |
| 1488 | − | |
| 1489 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 1490 | − | |
| 1491 | − datalen = pkt->len; | |
| 1492 | − | |
| 1493 | −#ifdef SDTEST | |
| 1494 | − /* Push the test header if doing loopback */ | |
| 1495 | − if (bus->ext_loop) { | |
| 1496 | − u8 *data; | |
| 1497 | − skb_push(pkt, SDPCM_TEST_HDRLEN); | |
| 1498 | − data = pkt->data; | |
| 1499 | − *data++ = SDPCM_TEST_ECHOREQ; | |
| 1500 | − *data++ = (u8) bus->loopid++; | |
| 1501 | − *data++ = (datalen >> 0); | |
| 1502 | − *data++ = (datalen >> 8); | |
| 1503 | − datalen += SDPCM_TEST_HDRLEN; | |
| 1504 | − } | |
| 1505 | −#endif /* SDTEST */ | |
| 1506 | − | |
| 1507 | − /* Add space for the header */ | |
| 1508 | − skb_push(pkt, SDPCM_HDRLEN); | |
| 1509 | − /* precondition: IS_ALIGNED((unsigned long)(pkt->data), 2) */ | |
| 1510 | − | |
| 1511 | − prec = PRIO2PREC((pkt->priority & PRIOMASK)); | |
| 1512 | − | |
| 1513 | − /* Check for existing queue, current flow-control, | |
| 1514 | − pending event, or pending clock */ | |
| 1515 | − if (brcmf_deferred_tx || bus->fcstate || pktq_len(&bus->txq) | |
| 1516 | − || bus->dpc_sched || (!DATAOK(bus)) | |
| 1517 | − || (bus->flowcontrol & NBITVAL(prec)) | |
| 1518 | − || (bus->clkstate != CLK_AVAIL)) { | |
| 1519 | − BRCMF_TRACE(("%s: deferring pktq len %d\n", __func__, | |
| 1520 | − pktq_len(&bus->txq))); | |
| 1521 | − bus->fcqueued++; | |
| 1522 | − | |
| 1523 | − /* Priority based enq */ | |
| 1524 | − spin_lock_bh(&bus->txqlock); | |
| 1525 | − if (brcmf_c_prec_enq(bus->drvr, &bus->txq, pkt, prec) == false) { | |
| 1526 | − skb_pull(pkt, SDPCM_HDRLEN); | |
| 1527 | − brcmf_txcomplete(bus->drvr, pkt, false); | |
| 1528 | − brcmu_pkt_buf_free_skb(pkt); | |
| 1529 | − BRCMF_ERROR(("%s: out of bus->txq !!!\n", __func__)); | |
| 1530 | − ret = -ENOSR; | |
| 1531 | − } else { | |
| 1532 | − ret = 0; | |
| 1533 | − } | |
| 1534 | − spin_unlock_bh(&bus->txqlock); | |
| 1535 | − | |
| 1536 | − if (pktq_len(&bus->txq) >= TXHI) | |
| 1537 | − brcmf_txflowcontrol(bus->drvr, 0, ON); | |
| 1538 | − | |
| 1539 | −#ifdef BCMDBG | |
| 1540 | − if (pktq_plen(&bus->txq, prec) > qcount[prec]) | |
| 1541 | − qcount[prec] = pktq_plen(&bus->txq, prec); | |
| 1542 | −#endif | |
| 1543 | − /* Schedule DPC if needed to send queued packet(s) */ | |
| 1544 | − if (brcmf_deferred_tx && !bus->dpc_sched) { | |
| 1545 | − bus->dpc_sched = true; | |
| 1546 | − brcmf_sdbrcm_sched_dpc(bus); | |
| 1547 | − } | |
| 1548 | − } else { | |
| 1549 | − /* Lock: we're about to use shared data/code (and SDIO) */ | |
| 1550 | − brcmf_sdbrcm_sdlock(bus); | |
| 1551 | − | |
| 1552 | − /* Otherwise, send it now */ | |
| 1553 | − BUS_WAKE(bus); | |
| 1554 | − /* Make sure back plane ht clk is on, no pending allowed */ | |
| 1555 | − brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, true); | |
| 1556 | − | |
| 1557 | −#ifndef SDTEST | |
| 1558 | − BRCMF_TRACE(("%s: calling txpkt\n", __func__)); | |
| 1559 | − ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true); | |
| 1560 | −#else | |
| 1561 | − ret = brcmf_sdbrcm_txpkt(bus, pkt, | |
| 1562 | − (bus->ext_loop ? SDPCM_TEST_CHANNEL : | |
| 1563 | − SDPCM_DATA_CHANNEL), true); | |
| 1564 | −#endif | |
| 1565 | − if (ret) | |
| 1566 | − bus->drvr->tx_errors++; | |
| 1567 | − else | |
| 1568 | − bus->drvr->dstats.tx_bytes += datalen; | |
| 1569 | − | |
| 1570 | − if (bus->idletime == BRCMF_IDLE_IMMEDIATE && | |
| 1571 | − !bus->dpc_sched) { | |
| 1572 | − bus->activity = false; | |
| 1573 | − brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); | |
| 1574 | − } | |
| 1575 | − | |
| 1576 | − brcmf_sdbrcm_sdunlock(bus); | |
| 1577 | − } | |
| 1578 | − | |
| 1579 | − return ret; | |
| 1580 | −} | |
| 1581 | − | |
| 1582 | −static uint brcmf_sdbrcm_sendfromq(struct brcmf_bus *bus, uint maxframes) | |
| 1583 | −{ | |
| 1584 | − struct sk_buff *pkt; | |
| 1585 | − u32 intstatus = 0; | |
| 1586 | − uint retries = 0; | |
| 1587 | − int ret = 0, prec_out; | |
| 1588 | − uint cnt = 0; | |
| 1589 | − uint datalen; | |
| 1590 | − u8 tx_prec_map; | |
| 1591 | − | |
| 1592 | − struct brcmf_pub *drvr = bus->drvr; | |
| 1593 | − | |
| 1594 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 1595 | − | |
| 1596 | − tx_prec_map = ~bus->flowcontrol; | |
| 1597 | − | |
| 1598 | − /* Send frames until the limit or some other event */ | |
| 1599 | − for (cnt = 0; (cnt < maxframes) && DATAOK(bus); cnt++) { | |
| 1600 | − spin_lock_bh(&bus->txqlock); | |
| 1601 | − pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out); | |
| 1602 | − if (pkt == NULL) { | |
| 1603 | − spin_unlock_bh(&bus->txqlock); | |
| 1604 | − break; | |
| 1605 | − } | |
| 1606 | − spin_unlock_bh(&bus->txqlock); | |
| 1607 | − datalen = pkt->len - SDPCM_HDRLEN; | |
| 1608 | − | |
| 1609 | −#ifndef SDTEST | |
| 1610 | − ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true); | |
| 1611 | −#else | |
| 1612 | − ret = brcmf_sdbrcm_txpkt(bus, pkt, | |
| 1613 | − (bus->ext_loop ? SDPCM_TEST_CHANNEL : | |
| 1614 | − SDPCM_DATA_CHANNEL), true); | |
| 1615 | −#endif | |
| 1616 | − if (ret) | |
| 1617 | − bus->drvr->tx_errors++; | |
| 1618 | − else | |
| 1619 | − bus->drvr->dstats.tx_bytes += datalen; | |
| 1620 | − | |
| 1621 | − /* In poll mode, need to check for other events */ | |
| 1622 | − if (!bus->intr && cnt) { | |
| 1623 | − /* Check device status, signal pending interrupt */ | |
| 1624 | − r_sdreg32(bus, &intstatus, | |
| 1625 | − offsetof(struct sdpcmd_regs, intstatus), | |
| 1626 | − &retries); | |
| 1627 | − bus->f2txdata++; | |
| 1628 | − if (brcmf_sdcard_regfail(bus->card)) | |
| 1629 | − break; | |
| 1630 | − if (intstatus & bus->hostintmask) | |
| 1631 | − bus->ipend = true; | |
| 1632 | − } | |
| 1633 | − } | |
| 1634 | − | |
| 1635 | − /* Deflow-control stack if needed */ | |
| 1636 | − if (drvr->up && (drvr->busstate == BRCMF_BUS_DATA) && | |
| 1637 | − drvr->txoff && (pktq_len(&bus->txq) < TXLOW)) | |
| 1638 | − brcmf_txflowcontrol(drvr, 0, OFF); | |
| 1639 | − | |
| 1640 | − return cnt; | |
| 1641 | −} | |
| 1642 | − | |
| 1643 | −int | |
| 1644 | −brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen) | |
| 1645 | −{ | |
| 1646 | − u8 *frame; | |
| 1647 | − u16 len; | |
| 1648 | − u32 swheader; | |
| 1649 | − uint retries = 0; | |
| 1650 | − struct brcmf_sdio_card *card = bus->card; | |
| 1651 | − u8 doff = 0; | |
| 1652 | − int ret = -1; | |
| 1653 | − int i; | |
| 1654 | − | |
| 1655 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 1656 | − | |
| 1657 | − if (bus->drvr->dongle_reset) | |
| 1658 | − return -EIO; | |
| 1659 | − | |
| 1660 | − /* Back the pointer to make a room for bus header */ | |
| 1661 | − frame = msg - SDPCM_HDRLEN; | |
| 1662 | − len = (msglen += SDPCM_HDRLEN); | |
| 1663 | − | |
| 1664 | − /* Add alignment padding (optional for ctl frames) */ | |
| 1665 | − if (brcmf_alignctl) { | |
| 1666 | − doff = ((unsigned long)frame % BRCMF_SDALIGN); | |
| 1667 | − if (doff) { | |
| 1668 | − frame -= doff; | |
| 1669 | − len += doff; | |
| 1670 | − msglen += doff; | |
| 1671 | − memset(frame, 0, doff + SDPCM_HDRLEN); | |
| 1672 | − } | |
| 1673 | − /* precondition: doff < BRCMF_SDALIGN */ | |
| 1674 | − } | |
| 1675 | − doff += SDPCM_HDRLEN; | |
| 1676 | − | |
| 1677 | − /* Round send length to next SDIO block */ | |
| 1678 | − if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { | |
| 1679 | − u16 pad = bus->blocksize - (len % bus->blocksize); | |
| 1680 | − if ((pad <= bus->roundup) && (pad < bus->blocksize)) | |
| 1681 | − len += pad; | |
| 1682 | − } else if (len % BRCMF_SDALIGN) { | |
| 1683 | − len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN); | |
| 1684 | − } | |
| 1685 | − | |
| 1686 | − /* Satisfy length-alignment requirements */ | |
| 1687 | − if (forcealign && (len & (ALIGNMENT - 1))) | |
| 1688 | − len = roundup(len, ALIGNMENT); | |
| 1689 | − | |
| 1690 | − /* precondition: IS_ALIGNED((unsigned long)frame, 2) */ | |
| 1691 | − | |
| 1692 | − /* Need to lock here to protect txseq and SDIO tx calls */ | |
| 1693 | − brcmf_sdbrcm_sdlock(bus); | |
| 1694 | − | |
| 1695 | − BUS_WAKE(bus); | |
| 1696 | − | |
| 1697 | − /* Make sure backplane clock is on */ | |
| 1698 | − brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | |
| 1699 | − | |
| 1700 | − /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ | |
| 1701 | − *(u16 *) frame = cpu_to_le16((u16) msglen); | |
| 1702 | − *(((u16 *) frame) + 1) = cpu_to_le16(~msglen); | |
| 1703 | − | |
| 1704 | − /* Software tag: channel, sequence number, data offset */ | |
| 1705 | − swheader = | |
| 1706 | − ((SDPCM_CONTROL_CHANNEL << SDPCM_CHANNEL_SHIFT) & | |
| 1707 | − SDPCM_CHANNEL_MASK) | |
| 1708 | − | bus->tx_seq | ((doff << SDPCM_DOFFSET_SHIFT) & | |
| 1709 | − SDPCM_DOFFSET_MASK); | |
| 1710 | − put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN); | |
| 1711 | − put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); | |
| 1712 | − | |
| 1713 | − if (!DATAOK(bus)) { | |
| 1714 | − BRCMF_INFO(("%s: No bus credit bus->tx_max %d," | |
| 1715 | − " bus->tx_seq %d\n", __func__, | |
| 1716 | − bus->tx_max, bus->tx_seq)); | |
| 1717 | − bus->ctrl_frame_stat = true; | |
| 1718 | − /* Send from dpc */ | |
| 1719 | − bus->ctrl_frame_buf = frame; | |
| 1720 | − bus->ctrl_frame_len = len; | |
| 1721 | − | |
| 1722 | − brcmf_sdbrcm_wait_for_event(bus, &bus->ctrl_frame_stat); | |
| 1723 | − | |
| 1724 | − if (bus->ctrl_frame_stat == false) { | |
| 1725 | − BRCMF_INFO(("%s: ctrl_frame_stat == false\n", | |
| 1726 | − __func__)); | |
| 1727 | − ret = 0; | |
| 1728 | − } else { | |
| 1729 | − BRCMF_INFO(("%s: ctrl_frame_stat == true\n", __func__)); | |
| 1730 | − ret = -1; | |
| 1731 | − } | |
| 1732 | − } | |
| 1733 | − | |
| 1734 | − if (ret == -1) { | |
| 1735 | −#ifdef BCMDBG | |
| 1736 | − if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) { | |
| 1737 | − printk(KERN_DEBUG "Tx Frame:\n"); | |
| 1738 | − print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, | |
| 1739 | − frame, len); | |
| 1740 | − } else if (BRCMF_HDRS_ON()) { | |
| 1741 | − printk(KERN_DEBUG "TxHdr:\n"); | |
| 1742 | − print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, | |
| 1743 | − frame, min_t(u16, len, 16)); | |
| 1744 | − } | |
| 1745 | −#endif | |
| 1746 | − | |
| 1747 | − do { | |
| 1748 | − bus->ctrl_frame_stat = false; | |
| 1749 | − ret = brcmf_sdbrcm_send_buf(bus, | |
| 1750 | − brcmf_sdcard_cur_sbwad(card), SDIO_FUNC_2, | |
| 1751 | − F2SYNC, frame, len, NULL, NULL, NULL); | |
| 1752 | − | |
| 1753 | − if (ret < 0) { | |
| 1754 | − /* On failure, abort the command and | |
| 1755 | − terminate the frame */ | |
| 1756 | − BRCMF_INFO(("%s: sdio error %d, abort command " | |
| 1757 | − "and terminate frame.\n", | |
| 1758 | − __func__, ret)); | |
| 1759 | − bus->tx_sderrs++; | |
| 1760 | − | |
| 1761 | − brcmf_sdcard_abort(card, SDIO_FUNC_2); | |
| 1762 | − | |
| 1763 | − brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, | |
| 1764 | − SBSDIO_FUNC1_FRAMECTRL, | |
| 1765 | − SFC_WF_TERM, NULL); | |
| 1766 | − bus->f1regdata++; | |
| 1767 | − | |
| 1768 | − for (i = 0; i < 3; i++) { | |
| 1769 | − u8 hi, lo; | |
| 1770 | − hi = brcmf_sdcard_cfg_read(card, | |
| 1771 | − SDIO_FUNC_1, | |
| 1772 | − SBSDIO_FUNC1_WFRAMEBCHI, | |
| 1773 | − NULL); | |
| 1774 | − lo = brcmf_sdcard_cfg_read(card, | |
| 1775 | − SDIO_FUNC_1, | |
| 1776 | − SBSDIO_FUNC1_WFRAMEBCLO, | |
| 1777 | − NULL); | |
| 1778 | − bus->f1regdata += 2; | |
| 1779 | − if ((hi == 0) && (lo == 0)) | |
| 1780 | − break; | |
| 1781 | − } | |
| 1782 | − | |
| 1783 | − } | |
| 1784 | − if (ret == 0) { | |
| 1785 | − bus->tx_seq = | |
| 1786 | − (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; | |
| 1787 | − } | |
| 1788 | − } while ((ret < 0) && retries++ < TXRETRIES); | |
| 1789 | − } | |
| 1790 | − | |
| 1791 | − if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) && !bus->dpc_sched) { | |
| 1792 | − bus->activity = false; | |
| 1793 | − brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); | |
| 1794 | − } | |
| 1795 | − | |
| 1796 | − brcmf_sdbrcm_sdunlock(bus); | |
| 1797 | − | |
| 1798 | − if (ret) | |
| 1799 | − bus->drvr->tx_ctlerrs++; | |
| 1800 | − else | |
| 1801 | − bus->drvr->tx_ctlpkts++; | |
| 1802 | − | |
| 1803 | − return ret ? -EIO : 0; | |
| 1804 | −} | |
| 1805 | − | |
| 1806 | −int brcmf_sdbrcm_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen) | |
| 1807 | −{ | |
| 1808 | − int timeleft; | |
| 1809 | − uint rxlen = 0; | |
| 1810 | − bool pending; | |
| 1811 | − | |
| 1812 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 1813 | − | |
| 1814 | − if (bus->drvr->dongle_reset) | |
| 1815 | − return -EIO; | |
| 1816 | − | |
| 1817 | − /* Wait until control frame is available */ | |
| 1818 | − timeleft = brcmf_os_ioctl_resp_wait(bus->drvr, &bus->rxlen, &pending); | |
| 1819 | − | |
| 1820 | − brcmf_sdbrcm_sdlock(bus); | |
| 1821 | − rxlen = bus->rxlen; | |
| 1822 | − memcpy(msg, bus->rxctl, min(msglen, rxlen)); | |
| 1823 | − bus->rxlen = 0; | |
| 1824 | − brcmf_sdbrcm_sdunlock(bus); | |
| 1825 | − | |
| 1826 | − if (rxlen) { | |
| 1827 | − BRCMF_CTL(("%s: resumed on rxctl frame, got %d expected %d\n", | |
| 1828 | − __func__, rxlen, msglen)); | |
| 1829 | − } else if (timeleft == 0) { | |
| 1830 | − BRCMF_ERROR(("%s: resumed on timeout\n", __func__)); | |
| 1831 | −#ifdef BCMDBG | |
| 1832 | − brcmf_sdbrcm_sdlock(bus); | |
| 1833 | − brcmf_sdbrcm_checkdied(bus, NULL, 0); | |
| 1834 | − brcmf_sdbrcm_sdunlock(bus); | |
| 1835 | −#endif /* BCMDBG */ | |
| 1836 | − } else if (pending == true) { | |
| 1837 | − BRCMF_CTL(("%s: cancelled\n", __func__)); | |
| 1838 | − return -ERESTARTSYS; | |
| 1839 | − } else { | |
| 1840 | − BRCMF_CTL(("%s: resumed for unknown reason?\n", __func__)); | |
| 1841 | −#ifdef BCMDBG | |
| 1842 | − brcmf_sdbrcm_sdlock(bus); | |
| 1843 | − brcmf_sdbrcm_checkdied(bus, NULL, 0); | |
| 1844 | − brcmf_sdbrcm_sdunlock(bus); | |
| 1845 | −#endif /* BCMDBG */ | |
| 1846 | − } | |
| 1847 | − | |
| 1848 | − if (rxlen) | |
| 1849 | − bus->drvr->rx_ctlpkts++; | |
| 1850 | − else | |
| 1851 | − bus->drvr->rx_ctlerrs++; | |
| 1852 | − | |
| 1853 | − return rxlen ? (int)rxlen : -ETIMEDOUT; | |
| 1854 | −} | |
| 1855 | − | |
| 1856 | −/* IOVar table */ | |
| 1857 | −enum { | |
| 1858 | − IOV_INTR = 1, | |
| 1859 | − IOV_POLLRATE, | |
| 1860 | − IOV_SDREG, | |
| 1861 | − IOV_SBREG, | |
| 1862 | − IOV_SDCIS, | |
| 1863 | − IOV_MEMBYTES, | |
| 1864 | − IOV_MEMSIZE, | |
| 1865 | −#ifdef BCMDBG | |
| 1866 | − IOV_CHECKDIED, | |
| 1867 | − IOV_CONS, | |
| 1868 | − IOV_DCONSOLE_POLL, | |
| 1869 | −#endif | |
| 1870 | − IOV_DOWNLOAD, | |
| 1871 | − IOV_FORCEEVEN, | |
| 1872 | − IOV_SDIOD_DRIVE, | |
| 1873 | − IOV_READAHEAD, | |
| 1874 | − IOV_SDRXCHAIN, | |
| 1875 | − IOV_ALIGNCTL, | |
| 1876 | − IOV_SDALIGN, | |
| 1877 | − IOV_DEVRESET, | |
| 1878 | − IOV_CPU, | |
| 1879 | −#ifdef SDTEST | |
| 1880 | − IOV_PKTGEN, | |
| 1881 | − IOV_EXTLOOP, | |
| 1882 | −#endif /* SDTEST */ | |
| 1883 | − IOV_SPROM, | |
| 1884 | − IOV_TXBOUND, | |
| 1885 | − IOV_RXBOUND, | |
| 1886 | − IOV_TXMINMAX, | |
| 1887 | − IOV_IDLETIME, | |
| 1888 | − IOV_IDLECLOCK, | |
| 1889 | − IOV_SD1IDLE, | |
| 1890 | − IOV_SLEEP, | |
| 1891 | − IOV_WDTICK, | |
| 1892 | − IOV_VARS | |
| 1893 | −}; | |
| 1894 | − | |
| 1895 | −const struct brcmu_iovar brcmf_sdio_iovars[] = { | |
| 1896 | − {"intr", IOV_INTR, 0, IOVT_BOOL, 0}, | |
| 1897 | − {"sleep", IOV_SLEEP, 0, IOVT_BOOL, 0}, | |
| 1898 | − {"pollrate", IOV_POLLRATE, 0, IOVT_UINT32, 0}, | |
| 1899 | − {"idletime", IOV_IDLETIME, 0, IOVT_INT32, 0}, | |
| 1900 | − {"idleclock", IOV_IDLECLOCK, 0, IOVT_INT32, 0}, | |
| 1901 | − {"sd1idle", IOV_SD1IDLE, 0, IOVT_BOOL, 0}, | |
| 1902 | − {"membytes", IOV_MEMBYTES, 0, IOVT_BUFFER, 2 * sizeof(int)}, | |
| 1903 | − {"memsize", IOV_MEMSIZE, 0, IOVT_UINT32, 0}, | |
| 1904 | − {"download", IOV_DOWNLOAD, 0, IOVT_BOOL, 0}, | |
| 1905 | − {"vars", IOV_VARS, 0, IOVT_BUFFER, 0}, | |
| 1906 | − {"sdiod_drive", IOV_SDIOD_DRIVE, 0, IOVT_UINT32, 0}, | |
| 1907 | − {"readahead", IOV_READAHEAD, 0, IOVT_BOOL, 0}, | |
| 1908 | − {"sdrxchain", IOV_SDRXCHAIN, 0, IOVT_BOOL, 0}, | |
| 1909 | − {"alignctl", IOV_ALIGNCTL, 0, IOVT_BOOL, 0}, | |
| 1910 | − {"sdalign", IOV_SDALIGN, 0, IOVT_BOOL, 0}, | |
| 1911 | − {"devreset", IOV_DEVRESET, 0, IOVT_BOOL, 0}, | |
| 1912 | − {"wdtick", IOV_WDTICK, 0, IOVT_UINT32, 0}, | |
| 1913 | −#ifdef BCMDBG | |
| 1914 | − {"cons", IOV_CONS, 0, IOVT_BUFFER, 0} | |
| 1915 | − , | |
| 1916 | − {"dconpoll", IOV_DCONSOLE_POLL, 0, IOVT_UINT32, 0} | |
| 1917 | − , | |
| 1918 | − {"sdreg", IOV_SDREG, 0, IOVT_BUFFER, sizeof(struct brcmf_sdreg)} | |
| 1919 | − , | |
| 1920 | − {"sbreg", IOV_SBREG, 0, IOVT_BUFFER, sizeof(struct brcmf_sdreg)} | |
| 1921 | − , | |
| 1922 | − {"sd_cis", IOV_SDCIS, 0, IOVT_BUFFER, BRCMF_IOCTL_MAXLEN} | |
| 1923 | − , | |
| 1924 | − {"forcealign", IOV_FORCEEVEN, 0, IOVT_BOOL, 0} | |
| 1925 | − , | |
| 1926 | − {"txbound", IOV_TXBOUND, 0, IOVT_UINT32, 0} | |
| 1927 | − , | |
| 1928 | − {"rxbound", IOV_RXBOUND, 0, IOVT_UINT32, 0} | |
| 1929 | − , | |
| 1930 | − {"txminmax", IOV_TXMINMAX, 0, IOVT_UINT32, 0} | |
| 1931 | − , | |
| 1932 | − {"cpu", IOV_CPU, 0, IOVT_BOOL, 0} | |
| 1933 | − , | |
| 1934 | − {"checkdied", IOV_CHECKDIED, 0, IOVT_BUFFER, 0} | |
| 1935 | − , | |
| 1936 | −#endif /* BCMDBG */ | |
| 1937 | −#ifdef SDTEST | |
| 1938 | − {"extloop", IOV_EXTLOOP, 0, IOVT_BOOL, 0} | |
| 1939 | − , | |
| 1940 | − {"pktgen", IOV_PKTGEN, 0, IOVT_BUFFER, sizeof(struct brcmf_pktgen)} | |
| 1941 | − , | |
| 1942 | −#endif /* SDTEST */ | |
| 1943 | − | |
| 1944 | − {NULL, 0, 0, 0, 0} | |
| 1945 | −}; | |
| 1946 | − | |
| 1947 | −static void | |
| 1948 | −brcmf_dump_pct(struct brcmu_strbuf *strbuf, char *desc, uint num, uint div) | |
| 1949 | −{ | |
| 1950 | − uint q1, q2; | |
| 1951 | − | |
| 1952 | − if (!div) { | |
| 1953 | − brcmu_bprintf(strbuf, "%s N/A", desc); | |
| 1954 | − } else { | |
| 1955 | − q1 = num / div; | |
| 1956 | − q2 = (100 * (num - (q1 * div))) / div; | |
| 1957 | − brcmu_bprintf(strbuf, "%s %d.%02d", desc, q1, q2); | |
| 1958 | − } | |
| 1959 | −} | |
| 1960 | − | |
| 1961 | −void brcmf_sdbrcm_bus_dump(struct brcmf_pub *drvr, struct brcmu_strbuf *strbuf) | |
| 1962 | −{ | |
| 1963 | − struct brcmf_bus *bus = drvr->bus; | |
| 1964 | − | |
| 1965 | − brcmu_bprintf(strbuf, "Bus SDIO structure:\n"); | |
| 1966 | − brcmu_bprintf(strbuf, | |
| 1967 | − "hostintmask 0x%08x intstatus 0x%08x sdpcm_ver %d\n", | |
| 1968 | − bus->hostintmask, bus->intstatus, bus->sdpcm_ver); | |
| 1969 | − brcmu_bprintf(strbuf, | |
| 1970 | − "fcstate %d qlen %d tx_seq %d, max %d, rxskip %d rxlen %d rx_seq %d\n", | |
| 1971 | − bus->fcstate, pktq_len(&bus->txq), bus->tx_seq, bus->tx_max, | |
| 1972 | − bus->rxskip, bus->rxlen, bus->rx_seq); | |
| 1973 | − brcmu_bprintf(strbuf, "intr %d intrcount %d lastintrs %d spurious %d\n", | |
| 1974 | − bus->intr, bus->intrcount, bus->lastintrs, bus->spurious); | |
| 1975 | − brcmu_bprintf(strbuf, "pollrate %d pollcnt %d regfails %d\n", | |
| 1976 | − bus->pollrate, bus->pollcnt, bus->regfails); | |
| 1977 | − | |
| 1978 | − brcmu_bprintf(strbuf, "\nAdditional counters:\n"); | |
| 1979 | − brcmu_bprintf(strbuf, | |
| 1980 | − "tx_sderrs %d fcqueued %d rxrtx %d rx_toolong %d rxc_errors %d\n", | |
| 1981 | − bus->tx_sderrs, bus->fcqueued, bus->rxrtx, bus->rx_toolong, | |
| 1982 | − bus->rxc_errors); | |
| 1983 | − brcmu_bprintf(strbuf, "rx_hdrfail %d badhdr %d badseq %d\n", | |
| 1984 | − bus->rx_hdrfail, bus->rx_badhdr, bus->rx_badseq); | |
| 1985 | − brcmu_bprintf(strbuf, "fc_rcvd %d, fc_xoff %d, fc_xon %d\n", | |
| 1986 | − bus->fc_rcvd, bus->fc_xoff, bus->fc_xon); | |
| 1987 | − brcmu_bprintf(strbuf, "rxglomfail %d, rxglomframes %d, rxglompkts %d\n", | |
| 1988 | − bus->rxglomfail, bus->rxglomframes, bus->rxglompkts); | |
| 1989 | − brcmu_bprintf(strbuf, "f2rx (hdrs/data) %d (%d/%d), f2tx %d f1regs" | |
| 1990 | − " %d\n", | |
| 1991 | − (bus->f2rxhdrs + bus->f2rxdata), bus->f2rxhdrs, | |
| 1992 | − bus->f2rxdata, bus->f2txdata, bus->f1regdata); | |
| 1993 | − { | |
| 1994 | − brcmf_dump_pct(strbuf, "\nRx: pkts/f2rd", bus->drvr->rx_packets, | |
| 1995 | − (bus->f2rxhdrs + bus->f2rxdata)); | |
| 1996 | − brcmf_dump_pct(strbuf, ", pkts/f1sd", bus->drvr->rx_packets, | |
| 1997 | − bus->f1regdata); | |
| 1998 | − brcmf_dump_pct(strbuf, ", pkts/sd", bus->drvr->rx_packets, | |
| 1999 | − (bus->f2rxhdrs + bus->f2rxdata + bus->f1regdata)); | |
| 2000 | − brcmf_dump_pct(strbuf, ", pkts/int", bus->drvr->rx_packets, | |
| 2001 | − bus->intrcount); | |
| 2002 | − brcmu_bprintf(strbuf, "\n"); | |
| 2003 | − | |
| 2004 | − brcmf_dump_pct(strbuf, "Rx: glom pct", (100 * bus->rxglompkts), | |
| 2005 | − bus->drvr->rx_packets); | |
| 2006 | − brcmf_dump_pct(strbuf, ", pkts/glom", bus->rxglompkts, | |
| 2007 | − bus->rxglomframes); | |
| 2008 | − brcmu_bprintf(strbuf, "\n"); | |
| 2009 | − | |
| 2010 | − brcmf_dump_pct(strbuf, "Tx: pkts/f2wr", bus->drvr->tx_packets, | |
| 2011 | − bus->f2txdata); | |
| 2012 | − brcmf_dump_pct(strbuf, ", pkts/f1sd", bus->drvr->tx_packets, | |
| 2013 | − bus->f1regdata); | |
| 2014 | − brcmf_dump_pct(strbuf, ", pkts/sd", bus->drvr->tx_packets, | |
| 2015 | − (bus->f2txdata + bus->f1regdata)); | |
| 2016 | − brcmf_dump_pct(strbuf, ", pkts/int", bus->drvr->tx_packets, | |
| 2017 | − bus->intrcount); | |
| 2018 | − brcmu_bprintf(strbuf, "\n"); | |
| 2019 | − | |
| 2020 | − brcmf_dump_pct(strbuf, "Total: pkts/f2rw", | |
| 2021 | − (bus->drvr->tx_packets + bus->drvr->rx_packets), | |
| 2022 | − (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata)); | |
| 2023 | − brcmf_dump_pct(strbuf, ", pkts/f1sd", | |
| 2024 | − (bus->drvr->tx_packets + bus->drvr->rx_packets), | |
| 2025 | − bus->f1regdata); | |
| 2026 | − brcmf_dump_pct(strbuf, ", pkts/sd", | |
| 2027 | − (bus->drvr->tx_packets + bus->drvr->rx_packets), | |
| 2028 | − (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata + | |
| 2029 | − bus->f1regdata)); | |
| 2030 | − brcmf_dump_pct(strbuf, ", pkts/int", | |
| 2031 | − (bus->drvr->tx_packets + bus->drvr->rx_packets), | |
| 2032 | − bus->intrcount); | |
| 2033 | − brcmu_bprintf(strbuf, "\n\n"); | |
| 2034 | − } | |
| 2035 | − | |
| 2036 | −#ifdef SDTEST | |
| 2037 | − if (bus->pktgen_count) { | |
| 2038 | − brcmu_bprintf(strbuf, "pktgen config and count:\n"); | |
| 2039 | − brcmu_bprintf(strbuf, | |
| 2040 | − "freq %d count %d print %d total %d min %d len %d\n", | |
| 2041 | − bus->pktgen_freq, bus->pktgen_count, | |
| 2042 | − bus->pktgen_print, bus->pktgen_total, | |
| 2043 | − bus->pktgen_minlen, bus->pktgen_maxlen); | |
| 2044 | − brcmu_bprintf(strbuf, "send attempts %d rcvd %d fail %d\n", | |
| 2045 | − bus->pktgen_sent, bus->pktgen_rcvd, | |
| 2046 | − bus->pktgen_fail); | |
| 2047 | − } | |
| 2048 | −#endif /* SDTEST */ | |
| 2049 | −#ifdef BCMDBG | |
| 2050 | − brcmu_bprintf(strbuf, "dpc_sched %d host interrupt%spending\n", | |
| 2051 | − bus->dpc_sched, " not "); | |
| 2052 | − brcmu_bprintf(strbuf, "blocksize %d roundup %d\n", bus->blocksize, | |
| 2053 | − bus->roundup); | |
| 2054 | −#endif /* BCMDBG */ | |
| 2055 | − brcmu_bprintf(strbuf, | |
| 2056 | − "clkstate %d activity %d idletime %d idlecount %d sleeping %d\n", | |
| 2057 | − bus->clkstate, bus->activity, bus->idletime, bus->idlecount, | |
| 2058 | − bus->sleeping); | |
| 2059 | −} | |
| 2060 | − | |
| 2061 | −void brcmf_bus_clearcounts(struct brcmf_pub *drvr) | |
| 2062 | −{ | |
| 2063 | − struct brcmf_bus *bus = (struct brcmf_bus *) drvr->bus; | |
| 2064 | − | |
| 2065 | − bus->intrcount = bus->lastintrs = bus->spurious = bus->regfails = 0; | |
| 2066 | − bus->rxrtx = bus->rx_toolong = bus->rxc_errors = 0; | |
| 2067 | − bus->rx_hdrfail = bus->rx_badhdr = bus->rx_badseq = 0; | |
| 2068 | − bus->tx_sderrs = bus->fc_rcvd = bus->fc_xoff = bus->fc_xon = 0; | |
| 2069 | − bus->rxglomfail = bus->rxglomframes = bus->rxglompkts = 0; | |
| 2070 | − bus->f2rxhdrs = bus->f2rxdata = bus->f2txdata = bus->f1regdata = 0; | |
| 2071 | −} | |
| 2072 | − | |
| 2073 | −#ifdef SDTEST | |
| 2074 | −static int brcmf_sdbrcm_pktgen_get(struct brcmf_bus *bus, u8 *arg) | |
| 2075 | −{ | |
| 2076 | − struct brcmf_pktgen pktgen; | |
| 2077 | − | |
| 2078 | − pktgen.version = BRCMF_PKTGEN_VERSION; | |
| 2079 | − pktgen.freq = bus->pktgen_freq; | |
| 2080 | − pktgen.count = bus->pktgen_count; | |
| 2081 | − pktgen.print = bus->pktgen_print; | |
| 2082 | − pktgen.total = bus->pktgen_total; | |
| 2083 | − pktgen.minlen = bus->pktgen_minlen; | |
| 2084 | − pktgen.maxlen = bus->pktgen_maxlen; | |
| 2085 | − pktgen.numsent = bus->pktgen_sent; | |
| 2086 | − pktgen.numrcvd = bus->pktgen_rcvd; | |
| 2087 | − pktgen.numfail = bus->pktgen_fail; | |
| 2088 | − pktgen.mode = bus->pktgen_mode; | |
| 2089 | − pktgen.stop = bus->pktgen_stop; | |
| 2090 | − | |
| 2091 | − memcpy(arg, &pktgen, sizeof(pktgen)); | |
| 2092 | − | |
| 2093 | − return 0; | |
| 2094 | −} | |
| 2095 | − | |
| 2096 | −static int brcmf_sdbrcm_pktgen_set(struct brcmf_bus *bus, u8 *arg) | |
| 2097 | −{ | |
| 2098 | − struct brcmf_pktgen pktgen; | |
| 2099 | − uint oldcnt, oldmode; | |
| 2100 | − | |
| 2101 | − memcpy(&pktgen, arg, sizeof(pktgen)); | |
| 2102 | − if (pktgen.version != BRCMF_PKTGEN_VERSION) | |
| 2103 | − return -EINVAL; | |
| 2104 | − | |
| 2105 | − oldcnt = bus->pktgen_count; | |
| 2106 | − oldmode = bus->pktgen_mode; | |
| 2107 | − | |
| 2108 | − bus->pktgen_freq = pktgen.freq; | |
| 2109 | − bus->pktgen_count = pktgen.count; | |
| 2110 | − bus->pktgen_print = pktgen.print; | |
| 2111 | − bus->pktgen_total = pktgen.total; | |
| 2112 | − bus->pktgen_minlen = pktgen.minlen; | |
| 2113 | − bus->pktgen_maxlen = pktgen.maxlen; | |
| 2114 | − bus->pktgen_mode = pktgen.mode; | |
| 2115 | − bus->pktgen_stop = pktgen.stop; | |
| 2116 | − | |
| 2117 | − bus->pktgen_tick = bus->pktgen_ptick = 0; | |
| 2118 | − bus->pktgen_len = max(bus->pktgen_len, bus->pktgen_minlen); | |
| 2119 | − bus->pktgen_len = min(bus->pktgen_len, bus->pktgen_maxlen); | |
| 2120 | − | |
| 2121 | − /* Clear counts for a new pktgen (mode change, or was stopped) */ | |
| 2122 | − if (bus->pktgen_count && (!oldcnt || oldmode != bus->pktgen_mode)) | |
| 2123 | − bus->pktgen_sent = bus->pktgen_rcvd = bus->pktgen_fail = 0; | |
| 2124 | − | |
| 2125 | − return 0; | |
| 2126 | −} | |
| 2127 | −#endif /* SDTEST */ | |
| 2128 | − | |
| 2129 | −static int | |
| 2130 | −brcmf_sdbrcm_membytes(struct brcmf_bus *bus, bool write, u32 address, u8 *data, | |
| 2131 | − uint size) | |
| 2132 | −{ | |
| 2133 | − int bcmerror = 0; | |
| 2134 | − u32 sdaddr; | |
| 2135 | − uint dsize; | |
| 2136 | − | |
| 2137 | − /* Determine initial transfer parameters */ | |
| 2138 | − sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK; | |
| 2139 | − if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK) | |
| 2140 | − dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr); | |
| 2141 | − else | |
| 2142 | − dsize = size; | |
| 2143 | − | |
| 2144 | − /* Set the backplane window to include the start address */ | |
| 2145 | − bcmerror = brcmf_sdbrcm_set_siaddr_window(bus, address); | |
| 2146 | − if (bcmerror) { | |
| 2147 | − BRCMF_ERROR(("%s: window change failed\n", __func__)); | |
| 2148 | − goto xfer_done; | |
| 2149 | − } | |
| 2150 | − | |
| 2151 | − /* Do the transfer(s) */ | |
| 2152 | − while (size) { | |
| 2153 | − BRCMF_INFO(("%s: %s %d bytes at offset 0x%08x in window" | |
| 2154 | − " 0x%08x\n", __func__, (write ? "write" : "read"), | |
| 2155 | − dsize, sdaddr, (address & SBSDIO_SBWINDOW_MASK))); | |
| 2156 | − bcmerror = | |
| 2157 | − brcmf_sdcard_rwdata(bus->card, write, sdaddr, data, dsize); | |
| 2158 | − if (bcmerror) { | |
| 2159 | − BRCMF_ERROR(("%s: membytes transfer failed\n", | |
| 2160 | − __func__)); | |
| 2161 | − break; | |
| 2162 | − } | |
| 2163 | − | |
| 2164 | − /* Adjust for next transfer (if any) */ | |
| 2165 | − size -= dsize; | |
| 2166 | − if (size) { | |
| 2167 | − data += dsize; | |
| 2168 | − address += dsize; | |
| 2169 | − bcmerror = brcmf_sdbrcm_set_siaddr_window(bus, address); | |
| 2170 | − if (bcmerror) { | |
| 2171 | − BRCMF_ERROR(("%s: window change failed\n", | |
| 2172 | − __func__)); | |
| 2173 | − break; | |
| 2174 | − } | |
| 2175 | − sdaddr = 0; | |
| 2176 | − dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size); | |
| 2177 | − } | |
| 2178 | − } | |
| 2179 | − | |
| 2180 | −xfer_done: | |
| 2181 | − /* Return the window to backplane enumeration space for core access */ | |
| 2182 | − if (brcmf_sdbrcm_set_siaddr_window(bus, | |
| 2183 | − brcmf_sdcard_cur_sbwad(bus->card))) { | |
| 2184 | − BRCMF_ERROR(("%s: FAILED to set window back to 0x%x\n", | |
| 2185 | − __func__, brcmf_sdcard_cur_sbwad(bus->card))); | |
| 2186 | − } | |
| 2187 | − | |
| 2188 | − return bcmerror; | |
| 2189 | −} | |
| 2190 | − | |
| 2191 | −#ifdef BCMDBG | |
| 2192 | −static int brcmf_sdbrcm_readshared(struct brcmf_bus *bus, struct sdpcm_shared *sh) | |
| 2193 | −{ | |
| 2194 | − u32 addr; | |
| 2195 | − int rv; | |
| 2196 | − | |
| 2197 | − /* Read last word in memory to determine address of | |
| 2198 | − sdpcm_shared structure */ | |
| 2199 | − rv = brcmf_sdbrcm_membytes(bus, false, bus->ramsize - 4, (u8 *)&addr, | |
| 2200 | − 4); | |
| 2201 | − if (rv < 0) | |
| 2202 | − return rv; | |
| 2203 | − | |
| 2204 | − addr = le32_to_cpu(addr); | |
| 2205 | − | |
| 2206 | − BRCMF_INFO(("sdpcm_shared address 0x%08X\n", addr)); | |
| 2207 | − | |
| 2208 | − /* | |
| 2209 | − * Check if addr is valid. | |
| 2210 | − * NVRAM length at the end of memory should have been overwritten. | |
| 2211 | − */ | |
| 2212 | − if (addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff)) { | |
| 2213 | − BRCMF_ERROR(("%s: address (0x%08x) of sdpcm_shared invalid\n", | |
| 2214 | − __func__, addr)); | |
| 2215 | − return -EBADE; | |
| 2216 | − } | |
| 2217 | − | |
| 2218 | − /* Read rte_shared structure */ | |
| 2219 | − rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *) sh, | |
| 2220 | − sizeof(struct sdpcm_shared)); | |
| 2221 | − if (rv < 0) | |
| 2222 | − return rv; | |
| 2223 | − | |
| 2224 | − /* Endianness */ | |
| 2225 | − sh->flags = le32_to_cpu(sh->flags); | |
| 2226 | − sh->trap_addr = le32_to_cpu(sh->trap_addr); | |
| 2227 | − sh->assert_exp_addr = le32_to_cpu(sh->assert_exp_addr); | |
| 2228 | − sh->assert_file_addr = le32_to_cpu(sh->assert_file_addr); | |
| 2229 | − sh->assert_line = le32_to_cpu(sh->assert_line); | |
| 2230 | − sh->console_addr = le32_to_cpu(sh->console_addr); | |
| 2231 | − sh->msgtrace_addr = le32_to_cpu(sh->msgtrace_addr); | |
| 2232 | − | |
| 2233 | − if ((sh->flags & SDPCM_SHARED_VERSION_MASK) != SDPCM_SHARED_VERSION) { | |
| 2234 | − BRCMF_ERROR(("%s: sdpcm_shared version %d in brcmf " | |
| 2235 | − "is different than sdpcm_shared version %d in dongle\n", | |
| 2236 | − __func__, SDPCM_SHARED_VERSION, | |
| 2237 | − sh->flags & SDPCM_SHARED_VERSION_MASK)); | |
| 2238 | − return -EBADE; | |
| 2239 | − } | |
| 2240 | − | |
| 2241 | − return 0; | |
| 2242 | −} | |
| 2243 | − | |
| 2244 | −static int brcmf_sdbrcm_checkdied(struct brcmf_bus *bus, u8 *data, uint size) | |
| 2245 | −{ | |
| 2246 | − int bcmerror = 0; | |
| 2247 | − uint msize = 512; | |
| 2248 | − char *mbuffer = NULL; | |
| 2249 | − uint maxstrlen = 256; | |
| 2250 | − char *str = NULL; | |
| 2251 | − struct brcmf_trap tr; | |
| 2252 | − struct sdpcm_shared sdpcm_shared; | |
| 2253 | − struct brcmu_strbuf strbuf; | |
| 2254 | − | |
| 2255 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 2256 | − | |
| 2257 | − if (data == NULL) { | |
| 2258 | − /* | |
| 2259 | − * Called after a rx ctrl timeout. "data" is NULL. | |
| 2260 | − * allocate memory to trace the trap or assert. | |
| 2261 | − */ | |
| 2262 | − size = msize; | |
| 2263 | − mbuffer = data = kmalloc(msize, GFP_ATOMIC); | |
| 2264 | − if (mbuffer == NULL) { | |
| 2265 | − BRCMF_ERROR(("%s: kmalloc(%d) failed\n", __func__, | |
| 2266 | − msize)); | |
| 2267 | − bcmerror = -ENOMEM; | |
| 2268 | − goto done; | |
| 2269 | − } | |
| 2270 | − } | |
| 2271 | − | |
| 2272 | − str = kmalloc(maxstrlen, GFP_ATOMIC); | |
| 2273 | − if (str == NULL) { | |
| 2274 | − BRCMF_ERROR(("%s: kmalloc(%d) failed\n", __func__, maxstrlen)); | |
| 2275 | − bcmerror = -ENOMEM; | |
| 2276 | − goto done; | |
| 2277 | − } | |
| 2278 | − | |
| 2279 | − bcmerror = brcmf_sdbrcm_readshared(bus, &sdpcm_shared); | |
| 2280 | − if (bcmerror < 0) | |
| 2281 | − goto done; | |
| 2282 | − | |
| 2283 | − brcmu_binit(&strbuf, data, size); | |
| 2284 | − | |
| 2285 | − brcmu_bprintf(&strbuf, | |
| 2286 | − "msgtrace address : 0x%08X\nconsole address : 0x%08X\n", | |
| 2287 | − sdpcm_shared.msgtrace_addr, sdpcm_shared.console_addr); | |
| 2288 | − | |
| 2289 | − if ((sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT) == 0) { | |
| 2290 | − /* NOTE: Misspelled assert is intentional - DO NOT FIX. | |
| 2291 | − * (Avoids conflict with real asserts for programmatic | |
| 2292 | − * parsing of output.) | |
| 2293 | − */ | |
| 2294 | − brcmu_bprintf(&strbuf, "Assrt not built in dongle\n"); | |
| 2295 | − } | |
| 2296 | − | |
| 2297 | − if ((sdpcm_shared.flags & (SDPCM_SHARED_ASSERT | SDPCM_SHARED_TRAP)) == | |
| 2298 | − 0) { | |
| 2299 | − /* NOTE: Misspelled assert is intentional - DO NOT FIX. | |
| 2300 | − * (Avoids conflict with real asserts for programmatic | |
| 2301 | − * parsing of output.) | |
| 2302 | − */ | |
| 2303 | − brcmu_bprintf(&strbuf, "No trap%s in dongle", | |
| 2304 | − (sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT) | |
| 2305 | − ? "/assrt" : ""); | |
| 2306 | − } else { | |
| 2307 | − if (sdpcm_shared.flags & SDPCM_SHARED_ASSERT) { | |
| 2308 | − /* Download assert */ | |
| 2309 | − brcmu_bprintf(&strbuf, "Dongle assert"); | |
| 2310 | − if (sdpcm_shared.assert_exp_addr != 0) { | |
| 2311 | − str[0] = '\0'; | |
| 2312 | − bcmerror = brcmf_sdbrcm_membytes(bus, false, | |
| 2313 | − sdpcm_shared.assert_exp_addr, | |
| 2314 | − (u8 *) str, maxstrlen); | |
| 2315 | − if (bcmerror < 0) | |
| 2316 | − goto done; | |
| 2317 | − | |
| 2318 | − str[maxstrlen - 1] = '\0'; | |
| 2319 | − brcmu_bprintf(&strbuf, " expr \"%s\"", str); | |
| 2320 | − } | |
| 2321 | − | |
| 2322 | − if (sdpcm_shared.assert_file_addr != 0) { | |
| 2323 | − str[0] = '\0'; | |
| 2324 | − bcmerror = brcmf_sdbrcm_membytes(bus, false, | |
| 2325 | − sdpcm_shared.assert_file_addr, | |
| 2326 | − (u8 *) str, maxstrlen); | |
| 2327 | − if (bcmerror < 0) | |
| 2328 | − goto done; | |
| 2329 | − | |
| 2330 | − str[maxstrlen - 1] = '\0'; | |
| 2331 | − brcmu_bprintf(&strbuf, " file \"%s\"", str); | |
| 2332 | − } | |
| 2333 | − | |
| 2334 | − brcmu_bprintf(&strbuf, " line %d ", | |
| 2335 | − sdpcm_shared.assert_line); | |
| 2336 | − } | |
| 2337 | − | |
| 2338 | − if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) { | |
| 2339 | − bcmerror = brcmf_sdbrcm_membytes(bus, false, | |
| 2340 | − sdpcm_shared.trap_addr, (u8 *)&tr, | |
| 2341 | − sizeof(struct brcmf_trap)); | |
| 2342 | − if (bcmerror < 0) | |
| 2343 | − goto done; | |
| 2344 | − | |
| 2345 | − brcmu_bprintf(&strbuf, | |
| 2346 | − "Dongle trap type 0x%x @ epc 0x%x, cpsr 0x%x, spsr 0x%x, sp 0x%x," | |
| 2347 | − "lp 0x%x, rpc 0x%x Trap offset 0x%x, " | |
| 2348 | − "r0 0x%x, r1 0x%x, r2 0x%x, r3 0x%x, r4 0x%x, r5 0x%x, r6 0x%x, r7 0x%x\n", | |
| 2349 | − tr.type, tr.epc, tr.cpsr, tr.spsr, tr.r13, | |
| 2350 | − tr.r14, tr.pc, sdpcm_shared.trap_addr, | |
| 2351 | − tr.r0, tr.r1, tr.r2, tr.r3, tr.r4, tr.r5, | |
| 2352 | − tr.r6, tr.r7); | |
| 2353 | − } | |
| 2354 | − } | |
| 2355 | − | |
| 2356 | − if (sdpcm_shared.flags & (SDPCM_SHARED_ASSERT | SDPCM_SHARED_TRAP)) | |
| 2357 | − BRCMF_ERROR(("%s: %s\n", __func__, strbuf.origbuf)); | |
| 2358 | − | |
| 2359 | −#ifdef BCMDBG | |
| 2360 | − if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) { | |
| 2361 | − /* Mem dump to a file on device */ | |
| 2362 | − brcmf_sdbrcm_mem_dump(bus); | |
| 2363 | − } | |
| 2364 | −#endif /* BCMDBG */ | |
| 2365 | − | |
| 2366 | −done: | |
| 2367 | − kfree(mbuffer); | |
| 2368 | − kfree(str); | |
| 2369 | − | |
| 2370 | − return bcmerror; | |
| 2371 | −} | |
| 2372 | − | |
| 2373 | −static int brcmf_sdbrcm_mem_dump(struct brcmf_bus *bus) | |
| 2374 | −{ | |
| 2375 | − int ret = 0; | |
| 2376 | − int size; /* Full mem size */ | |
| 2377 | − int start = 0; /* Start address */ | |
| 2378 | − int read_size = 0; /* Read size of each iteration */ | |
| 2379 | − u8 *buf = NULL, *databuf = NULL; | |
| 2380 | − | |
| 2381 | − /* Get full mem size */ | |
| 2382 | − size = bus->ramsize; | |
| 2383 | − buf = kmalloc(size, GFP_ATOMIC); | |
| 2384 | − if (!buf) { | |
| 2385 | − BRCMF_ERROR(("%s: Out of memory (%d bytes)\n", __func__, size)); | |
| 2386 | − return -1; | |
| 2387 | − } | |
| 2388 | − | |
| 2389 | − /* Read mem content */ | |
| 2390 | − printk(KERN_DEBUG "Dump dongle memory"); | |
| 2391 | − databuf = buf; | |
| 2392 | − while (size) { | |
| 2393 | − read_size = min(MEMBLOCK, size); | |
| 2394 | − ret = brcmf_sdbrcm_membytes(bus, false, start, databuf, | |
| 2395 | − read_size); | |
| 2396 | − if (ret) { | |
| 2397 | − BRCMF_ERROR(("%s: Error membytes %d\n", __func__, ret)); | |
| 2398 | − kfree(buf); | |
| 2399 | − return -1; | |
| 2400 | − } | |
| 2401 | − printk("."); | |
| 2402 | − | |
| 2403 | − /* Decrement size and increment start address */ | |
| 2404 | − size -= read_size; | |
| 2405 | − start += read_size; | |
| 2406 | − databuf += read_size; | |
| 2407 | − } | |
| 2408 | − printk(KERN_DEBUG "Done\n"); | |
| 2409 | − | |
| 2410 | − /* free buf before return !!! */ | |
| 2411 | − if (brcmf_write_to_file(bus->drvr, buf, bus->ramsize)) { | |
| 2412 | − BRCMF_ERROR(("%s: Error writing to files\n", __func__)); | |
| 2413 | − return -1; | |
| 2414 | − } | |
| 2415 | − | |
| 2416 | − /* buf free handled in brcmf_write_to_file, not here */ | |
| 2417 | − return 0; | |
| 2418 | −} | |
| 2419 | − | |
| 2420 | −#define CONSOLE_LINE_MAX 192 | |
| 2421 | − | |
| 2422 | −static int brcmf_sdbrcm_readconsole(struct brcmf_bus *bus) | |
| 2423 | −{ | |
| 2424 | − struct brcmf_console *c = &bus->console; | |
| 2425 | − u8 line[CONSOLE_LINE_MAX], ch; | |
| 2426 | − u32 n, idx, addr; | |
| 2427 | − int rv; | |
| 2428 | − | |
| 2429 | − /* Don't do anything until FWREADY updates console address */ | |
| 2430 | − if (bus->console_addr == 0) | |
| 2431 | − return 0; | |
| 2432 | − | |
| 2433 | − /* Read console log struct */ | |
| 2434 | − addr = bus->console_addr + offsetof(struct rte_console, log); | |
| 2435 | − rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&c->log, | |
| 2436 | − sizeof(c->log)); | |
| 2437 | − if (rv < 0) | |
| 2438 | − return rv; | |
| 2439 | − | |
| 2440 | − /* Allocate console buffer (one time only) */ | |
| 2441 | − if (c->buf == NULL) { | |
| 2442 | − c->bufsize = le32_to_cpu(c->log.buf_size); | |
| 2443 | − c->buf = kmalloc(c->bufsize, GFP_ATOMIC); | |
| 2444 | − if (c->buf == NULL) | |
| 2445 | − return -ENOMEM; | |
| 2446 | − } | |
| 2447 | − | |
| 2448 | − idx = le32_to_cpu(c->log.idx); | |
| 2449 | − | |
| 2450 | − /* Protect against corrupt value */ | |
| 2451 | − if (idx > c->bufsize) | |
| 2452 | − return -EBADE; | |
| 2453 | − | |
| 2454 | − /* Skip reading the console buffer if the index pointer | |
| 2455 | − has not moved */ | |
| 2456 | − if (idx == c->last) | |
| 2457 | − return 0; | |
| 2458 | − | |
| 2459 | − /* Read the console buffer */ | |
| 2460 | − addr = le32_to_cpu(c->log.buf); | |
| 2461 | − rv = brcmf_sdbrcm_membytes(bus, false, addr, c->buf, c->bufsize); | |
| 2462 | − if (rv < 0) | |
| 2463 | − return rv; | |
| 2464 | − | |
| 2465 | − while (c->last != idx) { | |
| 2466 | − for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) { | |
| 2467 | − if (c->last == idx) { | |
| 2468 | − /* This would output a partial line. | |
| 2469 | − * Instead, back up | |
| 2470 | − * the buffer pointer and output this | |
| 2471 | − * line next time around. | |
| 2472 | − */ | |
| 2473 | − if (c->last >= n) | |
| 2474 | − c->last -= n; | |
| 2475 | − else | |
| 2476 | − c->last = c->bufsize - n; | |
| 2477 | − goto break2; | |
| 2478 | − } | |
| 2479 | − ch = c->buf[c->last]; | |
| 2480 | − c->last = (c->last + 1) % c->bufsize; | |
| 2481 | − if (ch == '\n') | |
| 2482 | − break; | |
| 2483 | − line[n] = ch; | |
| 2484 | − } | |
| 2485 | − | |
| 2486 | − if (n > 0) { | |
| 2487 | − if (line[n - 1] == '\r') | |
| 2488 | − n--; | |
| 2489 | − line[n] = 0; | |
| 2490 | − printk(KERN_DEBUG "CONSOLE: %s\n", line); | |
| 2491 | − } | |
| 2492 | − } | |
| 2493 | −break2: | |
| 2494 | − | |
| 2495 | − return 0; | |
| 2496 | −} | |
| 2497 | −#endif /* BCMDBG */ | |
| 2498 | − | |
| 2499 | −int brcmf_sdbrcm_downloadvars(struct brcmf_bus *bus, void *arg, int len) | |
| 2500 | −{ | |
| 2501 | − int bcmerror = 0; | |
| 2502 | − | |
| 2503 | − BRCMF_TRACE(("%s: Enter\n", __func__)); | |
| 2504 | − | |
| 2505 | − /* Basic sanity checks */ | |
| 2506 | − if (bus->drvr->up) { | |
| 2507 | − bcmerror = -EISCONN; | |
| 2508 | − goto err; | |
| 2509 | − } | |
| 2510 | − if (!len) { | |
| 2511 | − bcmerror = -EOVERFLOW; | |
| 2512 | − goto err; | |
| 2513 | − } | |
| 2514 | − | |
| 2515 | − /* Free the old ones and replace with passed variables */ | |
| 2516 | − kfree(bus->vars); | |
| 2517 | − | |
| 2518 | − bus->vars = kmalloc(len, GFP_ATOMIC); | |
| 2519 | − bus->varsz = bus->vars ? len : 0; | |
| 2520 | − if (bus->vars == NULL) { | |
| 2521 | − bcmerror = -ENOMEM; | |
| 2522 | − goto err; | |
| 2523 | − } | |
| 2524 | − | |
| 2525 | − /* Copy the passed variables, which should include the | |
| 2526 | − terminating double-null */ | |
| 2527 | − memcpy(bus->vars, arg, bus->varsz); | |
| 2528 | −err: | |
| 2529 | − return bcmerror; | |
| 2530 | −} | |
| 2531 | − | |
| 2532 | −static int | |
| 2533 | −brcmf_sdbrcm_doiovar(struct brcmf_bus *bus, const struct brcmu_iovar *vi, u32 actionid, | |
| 2534 | − const char *name, void *params, int plen, void *arg, int len, | |
| 2535 | − int val_size) | |
| 2536 | −{ | |
| 2537 | − int bcmerror = 0; | |
| 2538 | − s32 int_val = 0; | |
| 2539 | − bool bool_val = 0; | |
| 2540 | − | |
| 2541 | − BRCMF_TRACE(("%s: Enter, action %d name %s params %p plen %d arg %p " | |
| 2542 | − "len %d val_size %d\n", __func__, actionid, name, params, | |
| 2543 | − plen, arg, len, val_size)); | |
| 2544 | − | |
| 2545 | − bcmerror = brcmu_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid)); | |
| 2546 | − if (bcmerror != 0) | |
| 2547 | − goto exit; | |
| 2548 | − | |
| 2549 | − if (plen >= (int)sizeof(int_val)) | |
| 2550 | − memcpy(&int_val, params, sizeof(int_val)); | |
| 2551 | − | |
| 2552 | − bool_val = (int_val != 0) ? true : false; | |
| 2553 | − | |
| 2554 | − /* Some ioctls use the bus */ | |
| 2555 | − brcmf_sdbrcm_sdlock(bus); | |
| 2556 | − | |
| 2557 | − /* Check if dongle is in reset. If so, only allow DEVRESET iovars */ | |
| 2558 | − if (bus->drvr->dongle_reset && !(actionid == IOV_SVAL(IOV_DEVRESET) || | |
| 2559 | − actionid == IOV_GVAL(IOV_DEVRESET))) { | |
| 2560 | − bcmerror = -EPERM; | |
| 2561 | − goto exit; | |
| 2562 | − } | |
| 2563 | − | |
| 2564 | − /* Handle sleep stuff before any clock mucking */ | |
| 2565 | − if (vi->varid == IOV_SLEEP) { | |
| 2566 | − if (IOV_ISSET(actionid)) { | |
| 2567 | − bcmerror = brcmf_sdbrcm_bussleep(bus, bool_val); | |
| 2568 | − } else { | |
| 2569 | − int_val = (s32) bus->sleeping; | |
| 2570 | − memcpy(arg, &int_val, val_size); | |
| 2571 | − } | |
| 2572 | − goto exit; | |
| 2573 | − } | |
| 2574 | − | |
| 2575 | − /* Request clock to allow SDIO accesses */ | |
| 2576 | − if (!bus->drvr->dongle_reset) { | |
| 2577 | − BUS_WAKE(bus); | |
| 2578 | − brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | |
| 2579 | − } | |
| 2580 | − | |
| 2581 | − switch (actionid) { | |
| 2582 | − case IOV_GVAL(IOV_INTR): | |
| 2583 | − int_val = (s32) bus->intr; | |
| 2584 | − memcpy(arg, &int_val, val_size); | |
| 2585 | − break; | |
| 2586 | − | |
| 2587 | − case IOV_SVAL(IOV_INTR): | |
| 2588 | − bus->intr = bool_val; | |
| 2589 | − bus->intdis = false; | |
| 2590 | − if (bus->drvr->up) { | |
| 2591 | − BRCMF_INTR(("%s: %s SDIO interrupts\n", __func__, | |
| 2592 | − bus->intr ? "enable" : "disable")); | |
| 2593 | − if (bus->intr) { | |
| 2594 | − brcmf_sdcard_intr_enable(bus->card); | |
| 2595 | − } else { | |
| 2596 | − brcmf_sdcard_intr_disable(bus->card); | |
| 2597 | − } | |
| 2598 | − } | |
| 2599 | − break; | |
| 2600 | − | |
| 2601 | − case IOV_GVAL(IOV_POLLRATE): | |
| 2602 | − int_val = (s32) bus->pollrate; | |
| 2603 | − memcpy(arg, &int_val, val_size); | |
| 2604 | − break; | |
| 2605 | − | |
| 2606 | − case IOV_SVAL(IOV_POLLRATE): | |
| 2607 | − bus->pollrate = (uint) int_val; | |
| 2608 | − bus->poll = (bus->pollrate != 0); | |
| 2609 | − break; | |
| 2610 | − | |
| 2611 | − case IOV_GVAL(IOV_IDLETIME): | |
| 2612 | − int_val = bus->idletime; | |
| 2613 | − memcpy(arg, &int_val, val_size); | |
| 2614 | − break; | |
| 2615 | − | |
| 2616 | − case IOV_SVAL(IOV_IDLETIME): | |
| 2617 | − if ((int_val < 0) && (int_val != BRCMF_IDLE_IMMEDIATE)) | |
| 2618 | − bcmerror = -EINVAL; | |
| 2619 | − else | |
| 2620 | − bus->idletime = int_val; | |
| 2621 | − break; | |
| 2622 | − | |
| 2623 | − case IOV_GVAL(IOV_IDLECLOCK): | |
4149 more lines aren’t shown here.
This diff is large: its 348 lines aren’t shown here.
This diff is large: its 4153 lines aren’t shown here.
This diff is large: its 357 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 2280 lines aren’t shown here.
This diff is large: its 585 lines aren’t shown here.
This diff is large: its 276 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 1220 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 312 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 3594 lines aren’t shown here.
This diff is large: its 175 lines aren’t shown here.
This diff is large: its 1560 lines aren’t shown here.
This diff is large: its 133 lines aren’t shown here.
This diff is large: its 1776 lines aren’t shown here.
This diff is large: its 1918 lines aren’t shown here.
This diff is large: its 251 lines aren’t shown here.
This diff is large: its 1940 lines aren’t shown here.
This diff is large: its 109 lines aren’t shown here.
This diff is large: its 6103 lines aren’t shown here.
This diff is large: its 1026 lines aren’t shown here.
This diff is large: its 851 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 546 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 3226 lines aren’t shown here.
This diff is large: its 295 lines aren’t shown here.
This diff is large: its 1236 lines aren’t shown here.
This diff is large: its 5295 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 29083 lines aren’t shown here.
This diff is large: its 295 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 1534 lines aren’t shown here.
This diff is large: its 168 lines aren’t shown here.
This diff is large: its 3639 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 10630 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 219 lines aren’t shown here.
This diff is large: its 165 lines aren’t shown here.
This diff is large: its 475 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 666 lines aren’t shown here.
This diff is large: its 499 lines aren’t shown here.
This diff is large: its 174 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 1238 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 478 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 400 lines aren’t shown here.
This diff is large: its 116 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 788 lines aren’t shown here.
This diff is large: its 132 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 302 lines aren’t shown here.
This diff is large: its 244 lines aren’t shown here.
This diff is large: its 282 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 2881 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 585 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 112 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 557 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 174 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 1834 lines aren’t shown here.
This diff is large: its 137 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 267 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 1435 lines aren’t shown here.
This diff is large: its 408 lines aren’t shown here.
This diff is large: its 655 lines aren’t shown here.
This diff is large: its 980 lines aren’t shown here.
This diff is large: its 459 lines aren’t shown here.
This diff is large: its 181 lines aren’t shown here.
This diff is large: its 1153 lines aren’t shown here.
This diff is large: its 244 lines aren’t shown here.
This diff is large: its 798 lines aren’t shown here.
This diff is large: its 151 lines aren’t shown here.
This diff is large: its 5515 lines aren’t shown here.
This diff is large: its 1731 lines aren’t shown here.
This diff is large: its 244 lines aren’t shown here.
This diff is large: its 127 lines aren’t shown here.
This diff is large: its 849 lines aren’t shown here.
This diff is large: its 481 lines aren’t shown here.
This diff is large: its 687 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 178 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 166 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 126 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 150 lines aren’t shown here.
This diff is large: its 147 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 1027 lines aren’t shown here.
This diff is large: its 1031 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 335 lines aren’t shown here.
This diff is large: its 731 lines aren’t shown here.
This diff is large: its 278 lines aren’t shown here.
This diff is large: its 417 lines aren’t shown here.
This diff is large: its 565 lines aren’t shown here.
This diff is large: its 1078 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 1055 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 221 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 120 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 597 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 390 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 265 lines aren’t shown here.
This diff is large: its 314 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 283 lines aren’t shown here.
This diff is large: its 288 lines aren’t shown here.
This diff is large: its 214 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 813 lines aren’t shown here.
This diff is large: its 587 lines aren’t shown here.
This diff is large: its 1180 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 998 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 1309 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 158 lines aren’t shown here.
This diff is large: its 132 lines aren’t shown here.
This diff is large: its 282 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 197 lines aren’t shown here.
This diff is large: its 133 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 451 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 174 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 675 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 461 lines aren’t shown here.
This diff is large: its 184 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 144 lines aren’t shown here.
This diff is large: its 152 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 1010 lines aren’t shown here.
This diff is large: its 180 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 658 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 566 lines aren’t shown here.
This diff is large: its 157 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 166 lines aren’t shown here.
This diff is large: its 229 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 677 lines aren’t shown here.
This diff is large: its 560 lines aren’t shown here.
This diff is large: its 808 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 464 lines aren’t shown here.
This diff is large: its 582 lines aren’t shown here.
This diff is large: its 183 lines aren’t shown here.
This diff is large: its 218 lines aren’t shown here.
This diff is large: its 162 lines aren’t shown here.
This diff is large: its 223 lines aren’t shown here.
This diff is large: its 391 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 197 lines aren’t shown here.
This diff is large: its 186 lines aren’t shown here.
This diff is large: its 213 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 167 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 411 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 442 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 218 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 546 lines aren’t shown here.
This diff is large: its 109 lines aren’t shown here.
This diff is large: its 207 lines aren’t shown here.
This diff is large: its 191 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 815 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 903 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 636 lines aren’t shown here.
This diff is large: its 1322 lines aren’t shown here.
This diff is large: its 597 lines aren’t shown here.
This diff is large: its 365 lines aren’t shown here.
This diff is large: its 191 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 174 lines aren’t shown here.
This diff is large: its 632 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 416 lines aren’t shown here.
This diff is large: its 210 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 167 lines aren’t shown here.
This diff is large: its 139 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 189 lines aren’t shown here.
This diff is large: its 178 lines aren’t shown here.
This diff is large: its 337 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 289 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 188 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 208 lines aren’t shown here.
This diff is large: its 188 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 1897 lines aren’t shown here.
This diff is large: its 206 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 141 lines aren’t shown here.
This diff is large: its 132 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 297 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 328 lines aren’t shown here.
This diff is large: its 1155 lines aren’t shown here.
This diff is large: its 266 lines aren’t shown here.
This diff is large: its 184 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 483 lines aren’t shown here.
This diff is large: its 169 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 217 lines aren’t shown here.
This diff is large: its 156 lines aren’t shown here.
This diff is large: its 219 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 2637 lines aren’t shown here.
This diff is large: its 353 lines aren’t shown here.
This diff is large: its 2677 lines aren’t shown here.
This diff is large: its 3279 lines aren’t shown here.
This diff is large: its 956 lines aren’t shown here.
This diff is large: its 873 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 677 lines aren’t shown here.
This diff is large: its 484 lines aren’t shown here.
This diff is large: its 1733 lines aren’t shown here.
This diff is large: its 583 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 628 lines aren’t shown here.
This diff is large: its 340 lines aren’t shown here.
This diff is large: its 142 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 411 lines aren’t shown here.
This diff is large: its 307 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 678 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 1149 lines aren’t shown here.
This diff is large: its 419 lines aren’t shown here.
This diff is large: its 160 lines aren’t shown here.
This diff is large: its 5040 lines aren’t shown here.
This diff is large: its 2396 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 2555 lines aren’t shown here.
This diff is large: its 229 lines aren’t shown here.
This diff is large: its 349 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 701 lines aren’t shown here.
This diff is large: its 3337 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 1638 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 853 lines aren’t shown here.
This diff is large: its 1164 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 445 lines aren’t shown here.
This diff is large: its 208 lines aren’t shown here.
This diff is large: its 352 lines aren’t shown here.
This diff is large: its 2226 lines aren’t shown here.
This diff is large: its 132 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 567 lines aren’t shown here.
This diff is large: its 476 lines aren’t shown here.
This diff is large: its 1076 lines aren’t shown here.
This diff is large: its 445 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 549 lines aren’t shown here.
This diff is large: its 305 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 3199 lines aren’t shown here.
This diff is large: its 1125 lines aren’t shown here.
This diff is large: its 247 lines aren’t shown here.
This diff is large: its 1109 lines aren’t shown here.
This diff is large: its 300 lines aren’t shown here.
This diff is large: its 2996 lines aren’t shown here.
This diff is large: its 325 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 137 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 311 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 1334 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 3145 lines aren’t shown here.
This diff is large: its 239 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 393 lines aren’t shown here.
This diff is large: its 605 lines aren’t shown here.
This diff is large: its 243 lines aren’t shown here.
This diff is large: its 161 lines aren’t shown here.
This diff is large: its 290 lines aren’t shown here.
This diff is large: its 2721 lines aren’t shown here.
This diff is large: its 3742 lines aren’t shown here.
This diff is large: its 757 lines aren’t shown here.
This diff is large: its 968 lines aren’t shown here.
This diff is large: its 877 lines aren’t shown here.
This diff is large: its 123 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 106 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 367 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 240 lines aren’t shown here.
This diff is large: its 127 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 772 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 4192 lines aren’t shown here.
This diff is large: its 264 lines aren’t shown here.
This diff is large: its 643 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 968 lines aren’t shown here.
This diff is large: its 206 lines aren’t shown here.
This diff is large: its 987 lines aren’t shown here.
This diff is large: its 882 lines aren’t shown here.
This diff is large: its 1168 lines aren’t shown here.
This diff is larger than a page shows: the files after these aren’t listed. Clone the repository to see all of it.