"Dongle Host Driver, version " BRCMF_VERSION_STR;
#endif
-/* IOVar table */
-enum {
- IOV_VERSION = 1,
- IOV_MSGLEVEL,
- IOV_BCMERRORSTR,
- IOV_BCMERROR,
- IOV_DUMP,
- IOV_CLEARCOUNTS,
- IOV_LOGDUMP,
- IOV_LOGCAL,
- IOV_LOGSTAMP,
- IOV_GPIOOB,
- IOV_LAST
-};
-
-static const struct brcmu_iovar brcmf_iovars[] = {
- {"version", IOV_VERSION, 0, IOVT_BUFFER, sizeof(brcmf_version)}
- ,
-#ifdef BCMDBG
- {"msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0}
- ,
-#endif /* BCMDBG */
- {"bcmerrorstr", IOV_BCMERRORSTR, 0, IOVT_BUFFER, BCME_STRLEN}
- ,
- {"bcmerror", IOV_BCMERROR, 0, IOVT_INT8, 0}
- ,
- {"dump", IOV_DUMP, 0, IOVT_BUFFER, BRCMF_IOCTL_MAXLEN}
- ,
- {"clearcounts", IOV_CLEARCOUNTS, 0, IOVT_VOID, 0}
- ,
- {"gpioob", IOV_GPIOOB, 0, IOVT_UINT32, 0}
- ,
- {NULL, 0, 0, 0, 0}
-};
-
/* Message trace header */
struct msgtrace_hdr {
u8 version;
brcmf_msg_level = BRCMF_ERROR_VAL;
}
-static int brcmf_c_dump(struct brcmf_pub *drvr, char *buf, int buflen)
-{
- struct brcmu_strbuf b;
- struct brcmu_strbuf *strbuf = &b;
-
- brcmu_binit(strbuf, buf, buflen);
-
- /* Base info */
- brcmu_bprintf(strbuf, "%s\n", brcmf_version);
- brcmu_bprintf(strbuf, "\n");
- brcmu_bprintf(strbuf, "pub.up %d pub.txoff %d pub.busstate %d\n",
- drvr->up, drvr->txoff, drvr->busstate);
- brcmu_bprintf(strbuf, "pub.hdrlen %d pub.maxctl %d pub.rxsz %d\n",
- drvr->hdrlen, drvr->maxctl, drvr->rxsz);
- brcmu_bprintf(strbuf, "pub.iswl %d pub.drv_version %ld pub.mac %pM\n",
- drvr->iswl, drvr->drv_version, &drvr->mac);
- brcmu_bprintf(strbuf, "pub.bcmerror %d tickcnt %d\n", drvr->bcmerror,
- drvr->tickcnt);
-
- brcmu_bprintf(strbuf, "dongle stats:\n");
- brcmu_bprintf(strbuf,
- "tx_packets %ld tx_bytes %ld tx_errors %ld tx_dropped %ld\n",
- drvr->dstats.tx_packets, drvr->dstats.tx_bytes,
- drvr->dstats.tx_errors, drvr->dstats.tx_dropped);
- brcmu_bprintf(strbuf,
- "rx_packets %ld rx_bytes %ld rx_errors %ld rx_dropped %ld\n",
- drvr->dstats.rx_packets, drvr->dstats.rx_bytes,
- drvr->dstats.rx_errors, drvr->dstats.rx_dropped);
- brcmu_bprintf(strbuf, "multicast %ld\n", drvr->dstats.multicast);
-
- brcmu_bprintf(strbuf, "bus stats:\n");
- brcmu_bprintf(strbuf, "tx_packets %ld tx_multicast %ld tx_errors %ld\n",
- drvr->tx_packets, drvr->tx_multicast, drvr->tx_errors);
- brcmu_bprintf(strbuf, "tx_ctlpkts %ld tx_ctlerrs %ld\n",
- drvr->tx_ctlpkts, drvr->tx_ctlerrs);
- brcmu_bprintf(strbuf, "rx_packets %ld rx_multicast %ld rx_errors %ld\n",
- drvr->rx_packets, drvr->rx_multicast, drvr->rx_errors);
- brcmu_bprintf(strbuf,
- "rx_ctlpkts %ld rx_ctlerrs %ld rx_dropped %ld rx_flushed %ld\n",
- drvr->rx_ctlpkts, drvr->rx_ctlerrs, drvr->rx_dropped,
- drvr->rx_flushed);
- brcmu_bprintf(strbuf,
- "rx_readahead_cnt %ld tx_realloc %ld fc_packets %ld\n",
- drvr->rx_readahead_cnt, drvr->tx_realloc, drvr->fc_packets);
- brcmu_bprintf(strbuf, "wd_dpc_sched %ld\n", drvr->wd_dpc_sched);
- brcmu_bprintf(strbuf, "\n");
-
- /* Add any prot info */
- brcmf_proto_dump(drvr, strbuf);
- brcmu_bprintf(strbuf, "\n");
-
- /* Add any bus info */
- brcmf_sdbrcm_bus_dump(drvr, strbuf);
-
- return !strbuf->size ? -EOVERFLOW : 0;
-}
-
-static int
-brcmf_c_doiovar(struct brcmf_pub *drvr, const struct brcmu_iovar *vi,
- u32 actionid, const char *name, void *params, int plen,
- void *arg, int len, int val_size)
-{
- int bcmerror = 0;
- s32 int_val = 0;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- bcmerror = brcmu_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid));
- if (bcmerror != 0)
- goto exit;
-
- if (plen >= (int)sizeof(int_val))
- memcpy(&int_val, params, sizeof(int_val));
-
- switch (actionid) {
- case IOV_GVAL(IOV_VERSION):
- /* Need to have checked buffer length */
- strncpy((char *)arg, brcmf_version, len);
- break;
-
- case IOV_GVAL(IOV_MSGLEVEL):
- int_val = (s32) brcmf_msg_level;
- memcpy(arg, &int_val, val_size);
- break;
-
- case IOV_SVAL(IOV_MSGLEVEL):
- brcmf_msg_level = int_val;
- break;
-
- case IOV_GVAL(IOV_BCMERRORSTR):
- strncpy((char *)arg, "bcm_error",
- BCME_STRLEN);
- ((char *)arg)[BCME_STRLEN - 1] = 0x00;
- break;
-
- case IOV_GVAL(IOV_BCMERROR):
- int_val = (s32) drvr->bcmerror;
- memcpy(arg, &int_val, val_size);
- break;
-
- case IOV_GVAL(IOV_DUMP):
- bcmerror = brcmf_c_dump(drvr, arg, len);
- break;
-
- case IOV_SVAL(IOV_CLEARCOUNTS):
- drvr->tx_packets = drvr->rx_packets = 0;
- drvr->tx_errors = drvr->rx_errors = 0;
- drvr->tx_ctlpkts = drvr->rx_ctlpkts = 0;
- drvr->tx_ctlerrs = drvr->rx_ctlerrs = 0;
- drvr->rx_dropped = 0;
- drvr->rx_readahead_cnt = 0;
- drvr->tx_realloc = 0;
- drvr->wd_dpc_sched = 0;
- memset(&drvr->dstats, 0, sizeof(drvr->dstats));
- brcmf_bus_clearcounts(drvr);
- break;
-
- default:
- bcmerror = -ENOTSUPP;
- break;
- }
-
-exit:
- return bcmerror;
-}
-
bool brcmf_c_prec_enq(struct brcmf_pub *drvr, struct pktq *q,
struct sk_buff *pkt, int prec)
{
return p != NULL;
}
-static int
-brcmf_c_iovar_op(struct brcmf_pub *drvr, const char *name,
- void *params, int plen, void *arg, int len, bool set)
-{
- int bcmerror = 0;
- int val_size;
- const struct brcmu_iovar *vi = NULL;
- u32 actionid;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- if (name == NULL || len < 0)
- return -EINVAL;
-
- /* Set does not take qualifiers */
- if (set && (params || plen))
- return -EINVAL;
-
- /* Get must have return space;*/
- if (!set && !(arg && len))
- return -EINVAL;
-
- vi = brcmu_iovar_lookup(brcmf_iovars, name);
- if (vi == NULL) {
- bcmerror = -ENOTSUPP;
- goto exit;
- }
-
- brcmf_dbg(CTL, "%s %s, len %d plen %d\n",
- name, set ? "set" : "get", len, plen);
-
- /* set up 'params' pointer in case this is a set command so that
- * the convenience int and bool code can be common to set and get
- */
- if (params == NULL) {
- params = arg;
- plen = len;
- }
-
- if (vi->type == IOVT_VOID)
- val_size = 0;
- else if (vi->type == IOVT_BUFFER)
- val_size = len;
- else
- /* all other types are integer sized */
- val_size = sizeof(int);
-
- actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
- bcmerror =
- brcmf_c_doiovar(drvr, vi, actionid, name, params, plen, arg, len,
- val_size);
-
-exit:
- return bcmerror;
-}
-
-int brcmf_c_ioctl(struct brcmf_pub *drvr, struct brcmf_c_ioctl *ioc, void *buf,
- uint buflen)
-{
- int bcmerror = 0;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- if (!buf)
- return -EINVAL;
-
- switch (ioc->cmd) {
- case BRCMF_GET_MAGIC:
- if (buflen < sizeof(int))
- bcmerror = -EOVERFLOW;
- else
- *(int *)buf = BRCMF_IOCTL_MAGIC;
- break;
-
- case BRCMF_GET_VERSION:
- if (buflen < sizeof(int))
- bcmerror = -EOVERFLOW;
- else
- *(int *)buf = BRCMF_IOCTL_VERSION;
- break;
-
- case BRCMF_GET_VAR:
- case BRCMF_SET_VAR:{
- char *arg;
- uint arglen;
-
- /* scan past the name to any arguments */
- for (arg = buf, arglen = buflen; *arg && arglen;
- arg++, arglen--)
- ;
-
- if (*arg) {
- bcmerror = -EOVERFLOW;
- break;
- }
-
- /* account for the NUL terminator */
- arg++, arglen--;
-
- /* call with the appropriate arguments */
- if (ioc->cmd == BRCMF_GET_VAR)
- bcmerror = brcmf_c_iovar_op(drvr, buf, arg,
- arglen, buf, buflen, IOV_GET);
- else
- bcmerror =
- brcmf_c_iovar_op(drvr, buf, NULL, 0, arg,
- arglen, IOV_SET);
- if (bcmerror != -ENOTSUPP)
- break;
-
- /* if still not found, try bus module */
- if (ioc->cmd == BRCMF_GET_VAR)
- bcmerror = brcmf_sdbrcm_bus_iovar_op(drvr,
- buf, arg, arglen, buf, buflen,
- IOV_GET);
- else
- bcmerror = brcmf_sdbrcm_bus_iovar_op(drvr,
- buf, NULL, 0, arg, arglen,
- IOV_SET);
-
- break;
- }
-
- default:
- bcmerror = -ENOTSUPP;
- }
-
- return bcmerror;
-}
-
#ifdef BCMDBG
static void
brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
#define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE)
#ifdef BCMDBG
-static int brcmf_sdbrcm_bus_console_in(struct brcmf_pub *drvr,
- unsigned char *msg, uint msglen);
static int brcmf_sdbrcm_checkdied(struct brcmf_bus *bus, u8 *data, uint size);
static int brcmf_sdbrcm_mem_dump(struct brcmf_bus *bus);
#endif /* BCMDBG */
return rxlen ? (int)rxlen : -ETIMEDOUT;
}
-/* IOVar table */
-enum {
- IOV_INTR = 1,
- IOV_POLLRATE,
- IOV_SDREG,
- IOV_SBREG,
- IOV_SDCIS,
- IOV_MEMBYTES,
- IOV_MEMSIZE,
-#ifdef BCMDBG
- IOV_CHECKDIED,
- IOV_CONS,
- IOV_DCONSOLE_POLL,
-#endif
- IOV_DOWNLOAD,
- IOV_FORCEEVEN,
- IOV_SDIOD_DRIVE,
- IOV_READAHEAD,
- IOV_SDRXCHAIN,
- IOV_ALIGNCTL,
- IOV_SDALIGN,
- IOV_DEVRESET,
- IOV_TXBOUND,
- IOV_RXBOUND,
- IOV_TXMINMAX,
- IOV_IDLETIME,
- IOV_IDLECLOCK,
- IOV_SLEEP,
- IOV_WDTICK,
- IOV_IOCTLTIMEOUT,
- IOV_VARS
-};
-
-static const struct brcmu_iovar brcmf_sdio_iovars[] = {
- {"intr", IOV_INTR, 0, IOVT_BOOL, 0},
- {"sleep", IOV_SLEEP, 0, IOVT_BOOL, 0},
- {"pollrate", IOV_POLLRATE, 0, IOVT_UINT32, 0},
- {"idletime", IOV_IDLETIME, 0, IOVT_INT32, 0},
- {"idleclock", IOV_IDLECLOCK, 0, IOVT_INT32, 0},
- {"membytes", IOV_MEMBYTES, 0, IOVT_BUFFER, 2 * sizeof(int)},
- {"memsize", IOV_MEMSIZE, 0, IOVT_UINT32, 0},
- {"download", IOV_DOWNLOAD, 0, IOVT_BOOL, 0},
- {"vars", IOV_VARS, 0, IOVT_BUFFER, 0},
- {"sdiod_drive", IOV_SDIOD_DRIVE, 0, IOVT_UINT32, 0},
- {"readahead", IOV_READAHEAD, 0, IOVT_BOOL, 0},
- {"sdrxchain", IOV_SDRXCHAIN, 0, IOVT_BOOL, 0},
- {"alignctl", IOV_ALIGNCTL, 0, IOVT_BOOL, 0},
- {"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}
- ,
- {"dconpoll", IOV_DCONSOLE_POLL, 0, IOVT_UINT32, 0}
- ,
- {"sdreg", IOV_SDREG, 0, IOVT_BUFFER, sizeof(struct brcmf_sdreg)}
- ,
- {"sbreg", IOV_SBREG, 0, IOVT_BUFFER, sizeof(struct brcmf_sdreg)}
- ,
- {"sd_cis", IOV_SDCIS, 0, IOVT_BUFFER, BRCMF_IOCTL_MAXLEN}
- ,
- {"forcealign", IOV_FORCEEVEN, 0, IOVT_BOOL, 0}
- ,
- {"txbound", IOV_TXBOUND, 0, IOVT_UINT32, 0}
- ,
- {"rxbound", IOV_RXBOUND, 0, IOVT_UINT32, 0}
- ,
- {"txminmax", IOV_TXMINMAX, 0, IOVT_UINT32, 0}
- ,
- {"checkdied", IOV_CHECKDIED, 0, IOVT_BUFFER, 0}
- ,
-#endif /* BCMDBG */
-
- {NULL, 0, 0, 0, 0}
-};
-
-static void
-brcmf_dump_pct(struct brcmu_strbuf *strbuf, char *desc, uint num, uint div)
-{
- uint q1, q2;
-
- if (!div) {
- brcmu_bprintf(strbuf, "%s N/A", desc);
- } else {
- q1 = num / div;
- q2 = (100 * (num - (q1 * div))) / div;
- brcmu_bprintf(strbuf, "%s %d.%02d", desc, q1, q2);
- }
-}
-
-void brcmf_sdbrcm_bus_dump(struct brcmf_pub *drvr, struct brcmu_strbuf *strbuf)
-{
- struct brcmf_bus *bus = drvr->bus;
-
- brcmu_bprintf(strbuf, "Bus SDIO structure:\n");
- brcmu_bprintf(strbuf,
- "hostintmask 0x%08x intstatus 0x%08x sdpcm_ver %d\n",
- bus->hostintmask, bus->intstatus, bus->sdpcm_ver);
- brcmu_bprintf(strbuf,
- "fcstate %d qlen %d tx_seq %d, max %d, rxskip %d rxlen %d rx_seq %d\n",
- bus->fcstate, pktq_len(&bus->txq), bus->tx_seq, bus->tx_max,
- bus->rxskip, bus->rxlen, bus->rx_seq);
- brcmu_bprintf(strbuf, "intr %d intrcount %d lastintrs %d spurious %d\n",
- bus->intr, bus->intrcount, bus->lastintrs, bus->spurious);
- brcmu_bprintf(strbuf, "pollrate %d pollcnt %d regfails %d\n",
- bus->pollrate, bus->pollcnt, bus->regfails);
-
- brcmu_bprintf(strbuf, "\nAdditional counters:\n");
- brcmu_bprintf(strbuf,
- "tx_sderrs %d fcqueued %d rxrtx %d rx_toolong %d rxc_errors %d\n",
- bus->tx_sderrs, bus->fcqueued, bus->rxrtx, bus->rx_toolong,
- bus->rxc_errors);
- brcmu_bprintf(strbuf, "rx_hdrfail %d badhdr %d badseq %d\n",
- bus->rx_hdrfail, bus->rx_badhdr, bus->rx_badseq);
- brcmu_bprintf(strbuf, "fc_rcvd %d, fc_xoff %d, fc_xon %d\n",
- bus->fc_rcvd, bus->fc_xoff, bus->fc_xon);
- brcmu_bprintf(strbuf, "rxglomfail %d, rxglomframes %d, rxglompkts %d\n",
- bus->rxglomfail, bus->rxglomframes, bus->rxglompkts);
- brcmu_bprintf(strbuf, "f2rx (hdrs/data) %d (%d/%d), f2tx %d f1regs"
- " %d\n",
- (bus->f2rxhdrs + bus->f2rxdata), bus->f2rxhdrs,
- bus->f2rxdata, bus->f2txdata, bus->f1regdata);
- {
- brcmf_dump_pct(strbuf, "\nRx: pkts/f2rd", bus->drvr->rx_packets,
- (bus->f2rxhdrs + bus->f2rxdata));
- brcmf_dump_pct(strbuf, ", pkts/f1sd", bus->drvr->rx_packets,
- bus->f1regdata);
- brcmf_dump_pct(strbuf, ", pkts/sd", bus->drvr->rx_packets,
- (bus->f2rxhdrs + bus->f2rxdata + bus->f1regdata));
- brcmf_dump_pct(strbuf, ", pkts/int", bus->drvr->rx_packets,
- bus->intrcount);
- brcmu_bprintf(strbuf, "\n");
-
- brcmf_dump_pct(strbuf, "Rx: glom pct", (100 * bus->rxglompkts),
- bus->drvr->rx_packets);
- brcmf_dump_pct(strbuf, ", pkts/glom", bus->rxglompkts,
- bus->rxglomframes);
- brcmu_bprintf(strbuf, "\n");
-
- brcmf_dump_pct(strbuf, "Tx: pkts/f2wr", bus->drvr->tx_packets,
- bus->f2txdata);
- brcmf_dump_pct(strbuf, ", pkts/f1sd", bus->drvr->tx_packets,
- bus->f1regdata);
- brcmf_dump_pct(strbuf, ", pkts/sd", bus->drvr->tx_packets,
- (bus->f2txdata + bus->f1regdata));
- brcmf_dump_pct(strbuf, ", pkts/int", bus->drvr->tx_packets,
- bus->intrcount);
- brcmu_bprintf(strbuf, "\n");
-
- brcmf_dump_pct(strbuf, "Total: pkts/f2rw",
- (bus->drvr->tx_packets + bus->drvr->rx_packets),
- (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata));
- brcmf_dump_pct(strbuf, ", pkts/f1sd",
- (bus->drvr->tx_packets + bus->drvr->rx_packets),
- bus->f1regdata);
- brcmf_dump_pct(strbuf, ", pkts/sd",
- (bus->drvr->tx_packets + bus->drvr->rx_packets),
- (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata +
- bus->f1regdata));
- brcmf_dump_pct(strbuf, ", pkts/int",
- (bus->drvr->tx_packets + bus->drvr->rx_packets),
- bus->intrcount);
- brcmu_bprintf(strbuf, "\n\n");
- }
-
-#ifdef BCMDBG
- brcmu_bprintf(strbuf, "dpc_sched %d host interrupt%spending\n",
- bus->dpc_sched, " not ");
- brcmu_bprintf(strbuf, "blocksize %d roundup %d\n", bus->blocksize,
- bus->roundup);
-#endif /* BCMDBG */
- brcmu_bprintf(strbuf,
- "clkstate %d activity %d idletime %d idlecount %d sleeping %d\n",
- bus->clkstate, bus->activity, bus->idletime, bus->idlecount,
- bus->sleeping);
-}
-
-void brcmf_bus_clearcounts(struct brcmf_pub *drvr)
-{
- struct brcmf_bus *bus = (struct brcmf_bus *) drvr->bus;
-
- bus->intrcount = bus->lastintrs = bus->spurious = bus->regfails = 0;
- bus->rxrtx = bus->rx_toolong = bus->rxc_errors = 0;
- bus->rx_hdrfail = bus->rx_badhdr = bus->rx_badseq = 0;
- bus->tx_sderrs = bus->fc_rcvd = bus->fc_xoff = bus->fc_xon = 0;
- bus->rxglomfail = bus->rxglomframes = bus->rxglompkts = 0;
- bus->f2rxhdrs = bus->f2rxdata = bus->f2txdata = bus->f1regdata = 0;
-}
-
static int
brcmf_sdbrcm_membytes(struct brcmf_bus *bus, bool write, u32 address, u8 *data,
uint size)
return bcmerror;
}
-static int brcmf_sdbrcm_doiovar(struct brcmf_bus *bus,
- const struct brcmu_iovar *vi, u32 actionid,
- const char *name, void *params, int plen,
- void *arg, int len, int val_size)
-{
- int bcmerror = 0;
- s32 int_val = 0;
- bool bool_val = 0;
-
- brcmf_dbg(TRACE, "Enter, action %d name %s params %p plen %d arg %p len %d val_size %d\n",
- actionid, name, params, plen, arg, len, val_size);
-
- bcmerror = brcmu_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid));
- if (bcmerror != 0)
- goto exit;
-
- if (plen >= (int)sizeof(int_val))
- memcpy(&int_val, params, sizeof(int_val));
-
- bool_val = (int_val != 0) ? true : false;
-
- /* Some ioctls use the bus */
- brcmf_sdbrcm_sdlock(bus);
-
- /* Check if dongle is in reset. If so, only allow DEVRESET iovars */
- if (bus->drvr->dongle_reset && !(actionid == IOV_SVAL(IOV_DEVRESET) ||
- actionid == IOV_GVAL(IOV_DEVRESET))) {
- bcmerror = -EPERM;
- goto exit;
- }
-
- /* Handle sleep stuff before any clock mucking */
- if (vi->varid == IOV_SLEEP) {
- if (IOV_ISSET(actionid)) {
- bcmerror = brcmf_sdbrcm_bussleep(bus, bool_val);
- } else {
- int_val = (s32) bus->sleeping;
- memcpy(arg, &int_val, val_size);
- }
- goto exit;
- }
-
- /* Request clock to allow SDIO accesses */
- if (!bus->drvr->dongle_reset) {
- bus_wake(bus);
- brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
- }
-
- switch (actionid) {
- case IOV_GVAL(IOV_INTR):
- int_val = (s32) bus->intr;
- memcpy(arg, &int_val, val_size);
- break;
-
- case IOV_SVAL(IOV_INTR):
- bus->intr = bool_val;
- break;
-
- case IOV_GVAL(IOV_POLLRATE):
- int_val = (s32) bus->pollrate;
- memcpy(arg, &int_val, val_size);
- break;
-
- case IOV_SVAL(IOV_POLLRATE):
- bus->pollrate = (uint) int_val;
- bus->poll = (bus->pollrate != 0);
- break;
-
- case IOV_GVAL(IOV_IDLETIME):
- int_val = bus->idletime;
- memcpy(arg, &int_val, val_size);
- break;
-
- case IOV_SVAL(IOV_IDLETIME):
- if ((int_val < 0) && (int_val != BRCMF_IDLE_IMMEDIATE))
- bcmerror = -EINVAL;
- else
- bus->idletime = int_val;
- break;
-
- case IOV_GVAL(IOV_IDLECLOCK):
- int_val = (s32) bus->idleclock;
- memcpy(arg, &int_val, val_size);
- break;
-
- case IOV_SVAL(IOV_IDLECLOCK):
- bus->idleclock = int_val;
- break;
-
- case IOV_SVAL(IOV_MEMBYTES):
- case IOV_GVAL(IOV_MEMBYTES):
- {
- u32 address;
- uint size, dsize;
- u8 *data;
-
- bool set = (actionid == IOV_SVAL(IOV_MEMBYTES));
-
- address = (u32) int_val;
- memcpy(&int_val, (char *)params + sizeof(int_val),
- sizeof(int_val));
- size = (uint) int_val;
-
- /* Do some validation */
- dsize = set ? plen - (2 * sizeof(int)) : len;
- if (dsize < size) {
- brcmf_dbg(ERROR, "error on %s membytes, addr 0x%08x size %d dsize %d\n",
- set ? "set" : "get",
- address, size, dsize);
- bcmerror = -EINVAL;
- break;
- }
-
- brcmf_dbg(INFO, "Request to %s %d bytes at address 0x%08x\n",
- set ? "write" : "read", size, address);
-
- /* If we know about SOCRAM, check for a fit */
- if ((bus->orig_ramsize) &&
- ((address > bus->orig_ramsize)
- || (address + size > bus->orig_ramsize))) {
- brcmf_dbg(ERROR, "ramsize 0x%08x doesn't have %d bytes at 0x%08x\n",
- bus->orig_ramsize, size, address);
- bcmerror = -EINVAL;
- break;
- }
-
- /* Generate the actual data pointer */
- data =
- set ? (u8 *) params +
- 2 * sizeof(int) : (u8 *) arg;
-
- /* Call to do the transfer */
- bcmerror = brcmf_sdbrcm_membytes(bus, set, address,
- data, size);
-
- break;
- }
-
- case IOV_GVAL(IOV_MEMSIZE):
- int_val = (s32) bus->ramsize;
- memcpy(arg, &int_val, val_size);
- break;
-
- case IOV_GVAL(IOV_SDIOD_DRIVE):
- int_val = (s32) brcmf_sdiod_drive_strength;
- memcpy(arg, &int_val, val_size);
- break;
-
- case IOV_SVAL(IOV_SDIOD_DRIVE):
- brcmf_sdiod_drive_strength = int_val;
- brcmf_sdbrcm_sdiod_drive_strength_init(bus,
- brcmf_sdiod_drive_strength);
- break;
-
- case IOV_SVAL(IOV_DOWNLOAD):
- bcmerror = brcmf_sdbrcm_download_state(bus, bool_val);
- break;
-
- case IOV_SVAL(IOV_VARS):
- bcmerror = brcmf_sdbrcm_downloadvars(bus, arg, len);
- break;
-
- case IOV_GVAL(IOV_READAHEAD):
- int_val = (s32) brcmf_readahead;
- memcpy(arg, &int_val, val_size);
- break;
-
- case IOV_SVAL(IOV_READAHEAD):
- if (bool_val && !brcmf_readahead)
- bus->nextlen = 0;
- brcmf_readahead = bool_val;
- break;
-
- case IOV_GVAL(IOV_SDRXCHAIN):
- int_val = (s32) bus->use_rxchain;
- memcpy(arg, &int_val, val_size);
- break;
-
- case IOV_SVAL(IOV_SDRXCHAIN):
- if (bool_val && !bus->sd_rxchain)
- bcmerror = -ENOTSUPP;
- else
- bus->use_rxchain = bool_val;
- break;
- case IOV_GVAL(IOV_ALIGNCTL):
- int_val = (s32) brcmf_alignctl;
- memcpy(arg, &int_val, val_size);
- break;
-
- case IOV_SVAL(IOV_ALIGNCTL):
- brcmf_alignctl = bool_val;
- break;
-
- case IOV_GVAL(IOV_SDALIGN):
- int_val = BRCMF_SDALIGN;
- memcpy(arg, &int_val, val_size);
- break;
-
-#ifdef BCMDBG
- case IOV_GVAL(IOV_VARS):
- if (bus->varsz < (uint) len)
- memcpy(arg, bus->vars, bus->varsz);
- else
- bcmerror = -EOVERFLOW;
- break;
-#endif /* BCMDBG */
-
-#ifdef BCMDBG
- case IOV_GVAL(IOV_DCONSOLE_POLL):
- int_val = (s32) brcmf_console_ms;
- memcpy(arg, &int_val, val_size);
- break;
-
- case IOV_SVAL(IOV_DCONSOLE_POLL):
- brcmf_console_ms = (uint) int_val;
- break;
-
- case IOV_SVAL(IOV_CONS):
- if (len > 0)
- bcmerror = brcmf_sdbrcm_bus_console_in(bus->drvr,
- arg, len - 1);
- break;
-
- case IOV_GVAL(IOV_SDREG):
- {
- struct brcmf_sdreg *sd_ptr;
- u32 addr, size;
-
- sd_ptr = (struct brcmf_sdreg *) params;
-
- addr = bus->ci->buscorebase + sd_ptr->offset;
- size = sd_ptr->func;
- int_val = (s32) brcmf_sdcard_reg_read(bus->sdiodev,
- addr, size);
- if (brcmf_sdcard_regfail(bus->sdiodev))
- bcmerror = -EIO;
- memcpy(arg, &int_val, sizeof(s32));
- break;
- }
-
- case IOV_SVAL(IOV_SDREG):
- {
- struct brcmf_sdreg *sd_ptr;
- u32 addr, size;
-
- sd_ptr = (struct brcmf_sdreg *) params;
-
- addr = bus->ci->buscorebase + sd_ptr->offset;
- size = sd_ptr->func;
- brcmf_sdcard_reg_write(bus->sdiodev, addr, size,
- sd_ptr->value);
- if (brcmf_sdcard_regfail(bus->sdiodev))
- bcmerror = -EIO;
- break;
- }
-
- /* Same as above, but offset is not backplane
- (not SDIO core) */
- case IOV_GVAL(IOV_SBREG):
- {
- struct brcmf_sdreg sdreg;
- u32 addr, size;
-
- memcpy(&sdreg, params, sizeof(sdreg));
-
- addr = SI_ENUM_BASE + sdreg.offset;
- size = sdreg.func;
- int_val = (s32) brcmf_sdcard_reg_read(bus->sdiodev,
- addr, size);
- if (brcmf_sdcard_regfail(bus->sdiodev))
- bcmerror = -EIO;
- memcpy(arg, &int_val, sizeof(s32));
- break;
- }
-
- case IOV_SVAL(IOV_SBREG):
- {
- struct brcmf_sdreg sdreg;
- u32 addr, size;
-
- memcpy(&sdreg, params, sizeof(sdreg));
-
- addr = SI_ENUM_BASE + sdreg.offset;
- size = sdreg.func;
- brcmf_sdcard_reg_write(bus->sdiodev, addr, size,
- sdreg.value);
- if (brcmf_sdcard_regfail(bus->sdiodev))
- bcmerror = -EIO;
- break;
- }
-
- case IOV_GVAL(IOV_SDCIS):
- {
- *(char *)arg = 0;
-
- strcat(arg, "\nFunc 0\n");
- brcmf_sdcard_cis_read(bus->sdiodev, 0x10,
- (u8 *) arg + strlen(arg),
- SBSDIO_CIS_SIZE_LIMIT);
- strcat(arg, "\nFunc 1\n");
- brcmf_sdcard_cis_read(bus->sdiodev, 0x11,
- (u8 *) arg + strlen(arg),
- SBSDIO_CIS_SIZE_LIMIT);
- strcat(arg, "\nFunc 2\n");
- brcmf_sdcard_cis_read(bus->sdiodev, 0x12,
- (u8 *) arg + strlen(arg),
- SBSDIO_CIS_SIZE_LIMIT);
- break;
- }
-
- case IOV_GVAL(IOV_FORCEEVEN):
- int_val = (s32) forcealign;
- memcpy(arg, &int_val, val_size);
- break;
-
- case IOV_SVAL(IOV_FORCEEVEN):
- forcealign = bool_val;
- break;
-
- case IOV_GVAL(IOV_TXBOUND):
- int_val = (s32) brcmf_txbound;
- memcpy(arg, &int_val, val_size);
- break;
-
- case IOV_SVAL(IOV_TXBOUND):
- brcmf_txbound = (uint) int_val;
- break;
-
- case IOV_GVAL(IOV_RXBOUND):
- int_val = (s32) brcmf_rxbound;
- memcpy(arg, &int_val, val_size);
- break;
-
- case IOV_SVAL(IOV_RXBOUND):
- brcmf_rxbound = (uint) int_val;
- break;
-
- case IOV_GVAL(IOV_TXMINMAX):
- int_val = (s32) brcmf_txminmax;
- memcpy(arg, &int_val, val_size);
- break;
-
- case IOV_SVAL(IOV_TXMINMAX):
- brcmf_txminmax = (uint) int_val;
- break;
-#endif /* BCMDBG */
-
- case IOV_SVAL(IOV_DEVRESET):
- brcmf_dbg(TRACE, "Called set IOV_DEVRESET=%d dongle_reset=%d busstate=%d\n",
- bool_val, bus->drvr->dongle_reset,
- bus->drvr->busstate);
-
- brcmf_bus_devreset(bus->drvr, (u8) bool_val);
-
- break;
-
- case IOV_GVAL(IOV_DEVRESET):
- brcmf_dbg(TRACE, "Called get IOV_DEVRESET\n");
-
- /* Get its status */
- int_val = (bool) bus->drvr->dongle_reset;
- memcpy(arg, &int_val, val_size);
-
- break;
-
- case IOV_GVAL(IOV_WDTICK):
- int_val = (s32) brcmf_watchdog_ms;
- memcpy(arg, &int_val, val_size);
- break;
-
- case IOV_SVAL(IOV_WDTICK):
- if (!bus->drvr->up) {
- bcmerror = -ENOLINK;
- 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;
- }
-
-exit:
- if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) && !bus->dpc_sched) {
- bus->activity = false;
- brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
- }
-
- brcmf_sdbrcm_sdunlock(bus);
-
- if (actionid == IOV_SVAL(IOV_DEVRESET) && bool_val == false)
- brcmf_c_preinit_ioctls(bus->drvr);
-
- return bcmerror;
-}
-
static int brcmf_sdbrcm_write_vars(struct brcmf_bus *bus)
{
int bcmerror = 0;
return bcmerror;
}
-int
-brcmf_sdbrcm_bus_iovar_op(struct brcmf_pub *drvr, const char *name,
- void *params, int plen, void *arg, int len, bool set)
-{
- struct brcmf_bus *bus = drvr->bus;
- const struct brcmu_iovar *vi = NULL;
- int bcmerror = 0;
- int val_size;
- u32 actionid;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- if (name == NULL || len < 0)
- return -EINVAL;
-
- /* Set does not take qualifiers */
- if (set && (params || plen))
- return -EINVAL;
-
- /* Get must have return space;*/
- if (!set && !(arg && len))
- return -EINVAL;
-
- /* Look up var locally; if not found pass to host driver */
- vi = brcmu_iovar_lookup(brcmf_sdio_iovars, name);
- if (vi == NULL) {
- brcmf_sdbrcm_sdlock(bus);
-
- bus_wake(bus);
-
- /* Turn on clock in case SD command needs backplane */
- brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
-
- bcmerror = brcmf_sdcard_iovar_op(bus->sdiodev, name, params,
- plen, arg, len, set);
-
- if (bus->idletime == BRCMF_IDLE_IMMEDIATE &&
- !bus->dpc_sched) {
- bus->activity = false;
- brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
- }
-
- brcmf_sdbrcm_sdunlock(bus);
- goto exit;
- }
-
- brcmf_dbg(CTL, "%s %s, len %d plen %d\n",
- name, set ? "set" : "get", len, plen);
-
- /* set up 'params' pointer in case this is a set command so that
- * the convenience int and bool code can be common to set and get
- */
- if (params == NULL) {
- params = arg;
- plen = len;
- }
-
- if (vi->type == IOVT_VOID)
- val_size = 0;
- else if (vi->type == IOVT_BUFFER)
- val_size = len;
- else
- /* all other types are integer sized */
- val_size = sizeof(int);
-
- actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
- bcmerror = brcmf_sdbrcm_doiovar(bus, vi, actionid, name, params, plen,
- arg, len, val_size);
-
-exit:
- return bcmerror;
-}
-
void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus, bool enforce_mutex)
{
u32 local_hostintmask;
return bus->ipend;
}
-#ifdef BCMDBG
-static int brcmf_sdbrcm_bus_console_in(struct brcmf_pub *drvr,
- unsigned char *msg, uint msglen)
-{
- struct brcmf_bus *bus = drvr->bus;
- u32 addr, val;
- int rv;
- struct sk_buff *pkt;
-
- /* Address could be zero if CONSOLE := 0 in dongle Makefile */
- if (bus->console_addr == 0)
- return -ENOTSUPP;
-
- /* Exclusive bus access */
- brcmf_sdbrcm_sdlock(bus);
-
- /* Don't allow input if dongle is in reset */
- if (bus->drvr->dongle_reset) {
- brcmf_sdbrcm_sdunlock(bus);
- return -EPERM;
- }
-
- /* Request clock to allow SDIO accesses */
- bus_wake(bus);
- /* No pend allowed since txpkt is called later, ht clk has to be on */
- brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
-
- /* Zero cbuf_index */
- addr = bus->console_addr + offsetof(struct rte_console, cbuf_idx);
- val = cpu_to_le32(0);
- rv = brcmf_sdbrcm_membytes(bus, true, addr, (u8 *)&val, sizeof(val));
- if (rv < 0)
- goto done;
-
- /* Write message into cbuf */
- addr = bus->console_addr + offsetof(struct rte_console, cbuf);
- rv = brcmf_sdbrcm_membytes(bus, true, addr, (u8 *)msg, msglen);
- if (rv < 0)
- goto done;
-
- /* Write length into vcons_in */
- addr = bus->console_addr + offsetof(struct rte_console, vcons_in);
- val = cpu_to_le32(msglen);
- rv = brcmf_sdbrcm_membytes(bus, true, addr, (u8 *)&val, sizeof(val));
- if (rv < 0)
- goto done;
-
- /* Bump dongle by sending an empty event pkt.
- * sdpcm_sendup (RX) checks for virtual console input.
- */
- pkt = brcmu_pkt_buf_get_skb(4 + SDPCM_RESERVE);
- if ((pkt != NULL) && bus->clkstate == CLK_AVAIL)
- brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_EVENT_CHANNEL, true);
-
-done:
- if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) && !bus->dpc_sched) {
- bus->activity = false;
- brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
- }
-
- brcmf_sdbrcm_sdunlock(bus);
-
- return rv;
-}
-#endif /* BCMDBG */
-
static bool brcmf_sdbrcm_chipmatch(u16 chipid)
{
if (chipid == BCM4329_CHIP_ID)