* (at risk of conflicting with
* the real UART). vcons_out is currently unused.
*/
- volatile uint vcons_in;
- volatile uint vcons_out;
+ uint vcons_in;
+ uint vcons_out;
/* Output (logging) buffer
* Console output is written to a ring buffer log_buf at index log_idx.
* Core reg address translation.
* Both macro's returns a 32 bits byte address on the backplane bus.
*/
-#define CORE_CC_REG(base, field) (base + offsetof(chipcregs_t, field))
+#define CORE_CC_REG(base, field) \
+ (base + offsetof(struct chipcregs, field))
#define CORE_BUS_REG(base, field) \
(base + offsetof(struct sdpcmd_regs, field))
#define CORE_SB(base, field) \
spinlock_t txqlock;
wait_queue_head_t ctrl_wait;
+ wait_queue_head_t ioctl_resp_wait;
struct timer_list timer;
struct completion watchdog_wait;
/* Tx/Rx bounds */
uint brcmf_txbound;
uint brcmf_rxbound;
+module_param(brcmf_txbound, uint, 0);
+module_param(brcmf_rxbound, uint, 0);
uint brcmf_txminmax;
+int brcmf_idletime = 1;
+module_param(brcmf_idletime, int, 0);
+
+/* SDIO Drive Strength (in milliamps) */
+uint brcmf_sdiod_drive_strength = 6;
+module_param(brcmf_sdiod_drive_strength, uint, 0);
+
+/* Use polling */
+uint brcmf_poll;
+module_param(brcmf_poll, uint, 0);
+
+/* Use interrupts */
+uint brcmf_intr = true;
+module_param(brcmf_intr, uint, 0);
+
+/* IOCTL response timeout */
+static int brcmf_ioctl_timeout_msec = IOCTL_RESP_TIMEOUT;
+
/* override the RAM size if possible */
#define DONGLE_MIN_MEMSIZE (128 * 1024)
int brcmf_dongle_memsize;
+module_param(brcmf_dongle_memsize, int, 0);
static bool brcmf_alignctl;
static void brcmf_sdbrcm_sdlock(struct brcmf_bus *bus);
static void brcmf_sdbrcm_sdunlock(struct brcmf_bus *bus);
static int brcmf_sdbrcm_get_image(char *buf, int len, struct brcmf_bus *bus);
+static int brcmf_sdbrcm_ioctl_resp_wait(struct brcmf_bus *bus, uint *condition,
+ bool *pending);
+static int brcmf_sdbrcm_ioctl_resp_wake(struct brcmf_bus *bus);
/* Packet free applicable unconditionally for sdio and sdspi.
* Conditional if bufpool was present for gspi bus.
#if defined(BCMDBG)
if (bus->alp_only != true) {
- if (SBSDIO_ALPONLY(clkctl)) {
+ if (SBSDIO_ALPONLY(clkctl))
BRCMF_ERROR(("%s: HT Clock should be on.\n",
__func__));
- }
}
#endif /* defined (BCMDBG) */
}
/* Some controllers have trouble with odd bytes -- round to even */
- if (forcealign && (len & (ALIGNMENT - 1))) {
+ if (forcealign && (len & (ALIGNMENT - 1)))
len = roundup(len, ALIGNMENT);
- }
do {
ret = brcmf_sdbrcm_send_buf(bus, brcmf_sdcard_cur_sbwad(card),
}
}
- if (ret == 0) {
+ if (ret == 0)
bus->tx_seq =
(bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
- }
+
} while ((ret < 0) && retries++ < TXRETRIES);
}
return -EIO;
/* Wait until control frame is available */
- timeleft = brcmf_os_ioctl_resp_wait(bus->drvr, &bus->rxlen, &pending);
+ timeleft = brcmf_sdbrcm_ioctl_resp_wait(bus, &bus->rxlen, &pending);
brcmf_sdbrcm_sdlock(bus);
rxlen = bus->rxlen;
IOV_SD1IDLE,
IOV_SLEEP,
IOV_WDTICK,
+ IOV_IOCTLTIMEOUT,
IOV_VARS
};
{"sdalign", IOV_SDALIGN, 0, IOVT_BOOL, 0},
{"devreset", IOV_DEVRESET, 0, IOVT_BOOL, 0},
{"wdtick", IOV_WDTICK, 0, IOVT_UINT32, 0},
+ {"ioctl_timeout", IOV_IOCTLTIMEOUT, 0, IOVT_UINT32, 0},
#ifdef BCMDBG
{"cons", IOV_CONS, 0, IOVT_BUFFER, 0}
,
xfer_done:
/* Return the window to backplane enumeration space for core access */
if (brcmf_sdbrcm_set_siaddr_window(bus,
- brcmf_sdcard_cur_sbwad(bus->card))) {
+ brcmf_sdcard_cur_sbwad(bus->card)))
BRCMF_ERROR(("%s: FAILED to set window back to 0x%x\n",
__func__, brcmf_sdcard_cur_sbwad(bus->card)));
- }
return bcmerror;
}
"msgtrace address : 0x%08X\nconsole address : 0x%08X\n",
sdpcm_shared.msgtrace_addr, sdpcm_shared.console_addr);
- if ((sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT) == 0) {
+ if ((sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT) == 0)
/* NOTE: Misspelled assert is intentional - DO NOT FIX.
* (Avoids conflict with real asserts for programmatic
* parsing of output.)
*/
brcmu_bprintf(&strbuf, "Assrt not built in dongle\n");
- }
if ((sdpcm_shared.flags & (SDPCM_SHARED_ASSERT | SDPCM_SHARED_TRAP)) ==
0) {
BRCMF_ERROR(("%s: %s\n", __func__, strbuf.origbuf));
#ifdef BCMDBG
- if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) {
+ if (sdpcm_shared.flags & SDPCM_SHARED_TRAP)
/* Mem dump to a file on device */
brcmf_sdbrcm_mem_dump(bus);
- }
+
#endif /* BCMDBG */
done:
if (bus->drvr->up) {
BRCMF_INTR(("%s: %s SDIO interrupts\n", __func__,
bus->intr ? "enable" : "disable"));
- if (bus->intr) {
+ if (bus->intr)
brcmf_sdcard_intr_enable(bus->card);
- } else {
+ else
brcmf_sdcard_intr_disable(bus->card);
- }
}
break;
brcmf_sdbrcm_wd_timer(bus, (uint) int_val);
break;
+ case IOV_GVAL(IOV_IOCTLTIMEOUT):{
+ int_val = brcmf_ioctl_timeout_msec;
+ memcpy(arg, &int_val, sizeof(int_val));
+ break;
+ }
+
+ case IOV_SVAL(IOV_IOCTLTIMEOUT):{
+ if (int_val <= 0)
+ bcmerror = -EINVAL;
+ else
+ brcmf_ioctl_timeout_msec = int_val;
+ break;
+ }
+
default:
bcmerror = -ENOTSUPP;
break;
varsize, varaddr));
}
/* Compare the org NVRAM with the one read from RAM */
- if (memcmp(vbuffer, nvram_ularray, varsize)) {
+ if (memcmp(vbuffer, nvram_ularray, varsize))
BRCMF_ERROR(("%s: Downloaded NVRAM image is "
"corrupted.\n", __func__));
- } else
+ else
BRCMF_ERROR(("%s: Download/Upload/Compare of"
" NVRAM ok.\n", __func__));
BRCMF_TRACE(("%s: Enter\n", __func__));
- if (name == NULL || len <= 0)
+ if (name == NULL || len < 0)
return -EINVAL;
/* Set does not take qualifiers */
SBSDIO_FUNC1_CHIPCLKCSR,
(saveclk | SBSDIO_FORCE_HT), &err);
}
- if (err) {
+ if (err)
BRCMF_ERROR(("%s: Failed to force clock for F2: err %d\n",
__func__, err));
- }
/* Turn off the bus (F2), free any pending packets */
BRCMF_INTR(("%s: disable SDIO interrupts\n", __func__));
/* Clear rx control and wake any waiters */
bus->rxlen = 0;
- brcmf_os_ioctl_resp_wake(bus->drvr);
+ brcmf_sdbrcm_ioctl_resp_wake(bus);
/* Reset some F2 state stuff */
bus->rxskip = false;
lastrbc = (hi << 8) + lo;
}
- if (!retries) {
+ if (!retries)
BRCMF_ERROR(("%s: count never zeroed: last 0x%04x\n",
__func__, lastrbc));
- } else {
+ else
BRCMF_INFO(("%s: flush took %d iterations\n", __func__,
(0xffff - retries)));
- }
if (rtx) {
bus->rxrtx++;
done:
/* Awake any waiters */
- brcmf_os_ioctl_resp_wake(bus->drvr);
+ brcmf_sdbrcm_ioctl_resp_wake(bus);
}
static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq)
if (pfirst->len == 0) {
brcmu_pkt_buf_free_skb(pfirst);
- if (plast) {
+ if (plast)
plast->next = pnext;
- } else {
+ else
save_pfirst = pnext;
- }
+
continue;
} else if (brcmf_proto_hdrpull(bus->drvr, &ifidx, pfirst)
!= 0) {
__func__));
bus->drvr->rx_errors++;
brcmu_pkt_buf_free_skb(pfirst);
- if (plast) {
+ if (plast)
plast->next = pnext;
- } else {
+ else
save_pfirst = pnext;
- }
+
continue;
}
HMB_DATA_NAKHANDLED |
HMB_DATA_FC |
HMB_DATA_FWREADY |
- HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK)) {
+ HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK))
BRCMF_ERROR(("Unknown mailbox data content: 0x%02x\n",
hmb_data));
- }
return intstatus;
}
spin_lock_init(&bus->txqlock);
init_waitqueue_head(&bus->ctrl_wait);
+ init_waitqueue_head(&bus->ioctl_resp_wait);
/* Set up the watchdog timer */
init_timer(&bus->timer);
default to use if supported */
if (brcmf_sdcard_iovar_op(card, "sd_rxchain", NULL, 0,
&bus->sd_rxchain, sizeof(s32),
- false) != 0) {
+ false) != 0)
bus->sd_rxchain = false;
- } else {
+ else
BRCMF_INFO(("%s: bus module (through sdiocard API) %s"
" chaining\n", __func__, bus->sd_rxchain
? "supports" : "does not support"));
- }
+
bus->use_rxchain = (bool) bus->sd_rxchain;
return true;
BRCMF_TRACE(("%s: Enter\n", __func__));
- if (bus) {
+ if (bus)
brcmf_sdbrcm_release(bus);
- }
BRCMF_TRACE(("%s: Disconnected\n", __func__));
}
}
/* External nvram takes precedence if specified */
- if (brcmf_sdbrcm_download_nvram(bus)) {
+ if (brcmf_sdbrcm_download_nvram(bus))
BRCMF_ERROR(("%s: dongle nvram file download failed\n",
__func__));
- }
/* Take arm out of reset */
if (brcmf_sdbrcm_download_state(bus, false)) {
MODULE_FIRMWARE(BCM4329_FW_NAME);
MODULE_FIRMWARE(BCM4329_NV_NAME);
+
+static int
+brcmf_sdbrcm_ioctl_resp_wait(struct brcmf_bus *bus, uint *condition, bool *pending)
+{
+ DECLARE_WAITQUEUE(wait, current);
+ int timeout = msecs_to_jiffies(brcmf_ioctl_timeout_msec);
+
+ /* Wait until control frame is available */
+ add_wait_queue(&bus->ioctl_resp_wait, &wait);
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ while (!(*condition) && (!signal_pending(current) && timeout))
+ timeout = schedule_timeout(timeout);
+
+ if (signal_pending(current))
+ *pending = true;
+
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&bus->ioctl_resp_wait, &wait);
+
+ return timeout;
+}
+
+static int brcmf_sdbrcm_ioctl_resp_wake(struct brcmf_bus *bus)
+{
+ if (waitqueue_active(&bus->ioctl_resp_wait))
+ wake_up_interruptible(&bus->ioctl_resp_wait);
+
+ return 0;
+}