static void sb_write_sbreg(si_info_t *sii, volatile uint32 *sbr, uint32 v) { si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info; uint8 tmp; volatile uint32 dummy; uint32 intr_val = 0; /* * compact flash only has 11 bits address, while we needs 12 bits address. * MEM_SEG will be OR'd with other 11 bits address in hardware, * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special */ if (PCMCIA(sii)) { INTR_OFF(sii, intr_val); tmp = 1; OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1); sbr = (volatile uint32 *)((uintptr)sbr & ~(1 << 11)); /* mask out bit 11 */ } if (BUSTYPE(sii->pub.bustype) == PCMCIA_BUS) { dummy = R_REG(sii->osh, sbr); BCM_REFERENCE(dummy); W_REG(sii->osh, (volatile uint16 *)sbr, (uint16)(v & 0xffff)); dummy = R_REG(sii->osh, sbr); BCM_REFERENCE(dummy); W_REG(sii->osh, ((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); } else
uint pcie_writereg(si_t *sih, sbpcieregs_t *pcieregs, uint addrtype, uint offset, uint val) { osl_t *osh = si_osh(sih); ASSERT(pcieregs != NULL); BCM_REFERENCE(osh); if ((BUSTYPE(sih->bustype) == SI_BUS) || PCIE_GEN1(sih)) { switch (addrtype) { case PCIE_CONFIGREGS: W_REG(osh, (&pcieregs->configaddr), offset); W_REG(osh, (&pcieregs->configdata), val); break; case PCIE_PCIEREGS: W_REG(osh, (&pcieregs->u.pcie1.pcieindaddr), offset); W_REG(osh, (&pcieregs->u.pcie1.pcieinddata), val); break; default: ASSERT(0); break; } } else if (PCIE_GEN2(sih)) { W_REG(osh, (&pcieregs->configaddr), offset); W_REG(osh, (&pcieregs->configdata), val); } return 0; }
/* * This function runs a set of commands before running the wi-fi server * This is avoids packet drops and improves performance. * We run the following wl commands * up, mpc 0, wsec 0, slow_timer 999999, fast_timer 999999, glacial_timer 999999 * legacylink 1, monitor 1. */ void remote_wifi_ser_init_cmds(void *wl) { int err; char bigbuf[RWL_WIFI_BUF_LEN]; uint len = 0, count; /* The array stores command, length and then data format */ remote_wifi_cmds_t wifi_cmds[] = { {WLC_UP, NULL, 0x0}, {WLC_SET_VAR, "mpc", 0}, {WLC_SET_WSEC, NULL, 0x0}, {WLC_SET_VAR, "slow_timer", 999999}, {WLC_SET_VAR, "fast_timer", 999999}, {WLC_SET_VAR, "glacial_timer", 999999}, {WLC_SET_MONITOR, NULL, 0x1}, {WLC_SET_PM, NULL, 0x0} }; for (count = 0; count < ARRAYSIZE(wifi_cmds); count++) { if (wifi_cmds[count].data == NULL) len = sizeof(int); else len = strlen(wifi_cmds[count].data) + 1 + sizeof(int); /* If the command length exceeds the buffer length continue * executing the next command */ if (len > sizeof(bigbuf)) { DPRINT_ERR(ERR, "Err: command len exceeds buf len. Check" "initialization cmds\n"); continue; } if (wifi_cmds[count].data != NULL) { strcpy(bigbuf, wifi_cmds[count].data); memcpy(&bigbuf[strlen(wifi_cmds[count].data)+1], (char*)&wifi_cmds[count].value, sizeof(int)); } else { memcpy(&bigbuf[0], (char*)&wifi_cmds[count].value, sizeof(int)); } #ifdef WIN32 /* Add OID base for NDIS commands */ err = (int)ir_setinformation(wl, wifi_cmds[count].cmd + WL_OID_BASE, bigbuf, &len); #endif if (wifi_cmds[count].cmd == WLC_UP) /* NULL needs to be passed to the driver if WL UP command needs to * be executed Otherwise driver hangs */ err = wl_ioctl(wl, wifi_cmds[count].cmd, NULL, 0, TRUE); else err = wl_ioctl(wl, wifi_cmds[count].cmd, (void*)&bigbuf, len, TRUE); rwl_sleep(INIT_CMD_SLEEP); } BCM_REFERENCE(err); }
/* Serialize ppr data of a bandwidth into the given buffer */ static uint ppr_serialize_block(const uint8 *pprbuf, uint8** buf, uint32 serflag) { uint ret = 0; #if (PPR_MAX_TX_CHAINS > 1) uint chain = serflag & PPR_MAX_TX_CHAIN_MASK; /* chain number in serialized block */ bool bf = (serflag & PPR_BEAMFORMING) != 0; #endif bcopy(pprbuf, *buf, PPR_CHAIN1_SIZE); *buf += PPR_CHAIN1_SIZE; ret += PPR_CHAIN1_SIZE; #if (PPR_MAX_TX_CHAINS > 1) BCM_REFERENCE(bf); if (chain > 1) { COPY_PPR_TOBUF(PPR_CHAIN2_FIRST, PPR_CHAIN2_SIZE); } #if (PPR_MAX_TX_CHAINS > 2) if (chain > 2) { COPY_PPR_TOBUF(PPR_CHAIN3_FIRST, PPR_CHAIN3_SIZE); } #endif #ifdef WL_BEAMFORMING if (bf) { COPY_PPR_TOBUF(PPR_BF_CHAIN2_FIRST, PPR_BF_CHAIN2_SIZE); } #if (PPR_MAX_TX_CHAINS > 2) if (bf && chain > 2) { COPY_PPR_TOBUF(PPR_BF_CHAIN3_FIRST, PPR_BF_CHAIN3_SIZE); } #endif #endif /* WL_BEAMFORMING */ #endif /* (PPR_MAX_TX_CHAINS > 1) */ return ret; }
/* Get a pointer to the power values for the given ofdm rate group for a given channel bandwidth */ static int8* ppr_get_ofdm_group(pprpbw_t* bw_pwrs, wl_tx_mode_t mode, wl_tx_chains_t tx_chains) { int8* group_pwrs = NULL; BCM_REFERENCE(mode); switch (tx_chains) { #if (PPR_MAX_TX_CHAINS > 1) #if (PPR_MAX_TX_CHAINS > 2) case WL_TX_CHAINS_3: #ifdef WL_BEAMFORMING if (mode == WL_TX_MODE_TXBF) group_pwrs = bw_pwrs->p_1x3txbf_ofdm; else #endif group_pwrs = bw_pwrs->p_1x3cdd_ofdm; break; #endif /* PPR_MAX_TX_CHAINS > 2 */ case WL_TX_CHAINS_2: #ifdef WL_BEAMFORMING if (mode == WL_TX_MODE_TXBF) group_pwrs = bw_pwrs->p_1x2txbf_ofdm; else #endif group_pwrs = bw_pwrs->p_1x2cdd_ofdm; break; #endif /* PPR_MAX_TX_CHAINS > 1 */ case WL_TX_CHAINS_1: group_pwrs = bw_pwrs->p_1x1ofdm; break; default: ASSERT(0); break; } return group_pwrs; }
static uint ppr_ser_size_by_flag(uint32 flag, wl_tx_bw_t bw) { uint ret = PPR_CHAIN1_SIZE; /* at least 1 chain rates should be there */ uint chain = flag & PPR_MAX_TX_CHAIN_MASK; bool bf = (flag & PPR_BEAMFORMING) != 0; BCM_REFERENCE(chain); BCM_REFERENCE(bf); #if (PPR_MAX_TX_CHAINS > 1) if (chain > 1) { ret += PPR_CHAIN2_SIZE; } #if (PPR_MAX_TX_CHAINS > 2) if (chain > 2) { ret += PPR_CHAIN3_SIZE; } #endif #ifdef WL_BEAMFORMING if (bf) { ret += PPR_BF_CHAIN2_SIZE; } #if (PPR_MAX_TX_CHAINS > 2) if (bf && chain > 2) { ret += PPR_BF_CHAIN3_SIZE; } #endif #endif /* WL_BEAMFORMING */ #endif /* PPR_MAX_TX_CHAINS > 1 */ switch (bw) { case WL_TX_BW_20: ret *= sizeof(ppr_bw_20_t)/sizeof(pprpbw_t); break; case WL_TX_BW_40: ret *= sizeof(ppr_bw_40_t)/sizeof(pprpbw_t); break; case WL_TX_BW_80: ret *= sizeof(ppr_bw_80_t)/sizeof(pprpbw_t); break; case WL_TX_BW_ALL: ret *= sizeof(ppr_bw_all_t)/sizeof(pprpbw_t); break; default: ASSERT(0); } return ret; }
/* Destructor routine for opaque PPR struct */ void ppr_delete(osl_t *osh, ppr_t* pprptr) { ASSERT((pprptr->ch_bw == WL_TX_BW_20) || (pprptr->ch_bw == WL_TX_BW_40) || (pprptr->ch_bw == WL_TX_BW_80) || (pprptr->ch_bw == WL_TX_BW_ALL)); #ifndef BCMDRIVER BCM_REFERENCE(osh); free(pprptr); #else MFREE(osh, pprptr, (uint)ppr_size(pprptr->ch_bw)); #endif }
void bcm_rpc_tp_watchdog(rpc_tp_info_t *rpcb) { static int old = 0; /* close agg periodically to avoid stale aggregation(include rpc_agg change) */ bcm_rpc_tp_tx_agg_release(rpcb); RPC_TP_AGG(("agg delta %d\n", (rpcb->tp_tx_agg_cnt_sf - old))); old = rpcb->tp_tx_agg_cnt_sf; BCM_REFERENCE(old); }
static void sb_write_sbreg(si_info_t *sii, volatile uint32 *sbr, uint32 v) { uint8 tmp; volatile uint32 dummy; uint32 intr_val = 0; if (PCMCIA(sii)) { INTR_OFF(sii, intr_val); tmp = 1; OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1); sbr = (volatile uint32 *)((uintptr)sbr & ~(1 << 11)); } if (BUSTYPE(sii->pub.bustype) == PCMCIA_BUS) { dummy = R_REG(sii->osh, sbr); BCM_REFERENCE(dummy); W_REG(sii->osh, (volatile uint16 *)sbr, (uint16)(v & 0xffff)); dummy = R_REG(sii->osh, sbr); BCM_REFERENCE(dummy); W_REG(sii->osh, ((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); } else
osl_t * osl_attach(void *pdev, uint bustype, bool pkttag) { osl_t *osh; osh = kmalloc(sizeof(osl_t), GFP_ATOMIC); ASSERT(osh); bzero(osh, sizeof(osl_t)); ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1)); osh->magic = OS_HANDLE_MAGIC; atomic_set(&osh->malloced, 0); osh->failed = 0; osh->dbgmem_list = NULL; spin_lock_init(&(osh->dbgmem_lock)); osh->pdev = pdev; osh->pub.pkttag = pkttag; osh->bustype = bustype; switch (bustype) { case PCI_BUS: case SI_BUS: case PCMCIA_BUS: osh->pub.mmbus = TRUE; break; case JTAG_BUS: case SDIO_BUS: case USB_BUS: case SPI_BUS: case RPC_BUS: osh->pub.mmbus = FALSE; break; default: ASSERT(FALSE); break; } spin_lock_init(&(osh->pktalloc_lock)); #ifdef BCMDBG if (pkttag) { struct sk_buff *skb; BCM_REFERENCE(skb); ASSERT(OSL_PKTTAG_SZ <= sizeof(skb->cb)); } #endif return osh; }
/* Constructor routine for opaque PPR struct */ ppr_t* ppr_create(osl_t *osh, wl_tx_bw_t bw) { ppr_t* pprptr; ASSERT((bw == WL_TX_BW_20) || (bw == WL_TX_BW_40) || (bw == WL_TX_BW_80) || (bw == WL_TX_BW_ALL)); #ifndef BCMDRIVER BCM_REFERENCE(osh); if ((pprptr = (ppr_t*)malloc((uint)ppr_size(bw))) != NULL) { #else if ((pprptr = (ppr_t*)MALLOC(osh, (uint)ppr_size(bw))) != NULL) { #endif ppr_init(pprptr, bw); } return pprptr; } /* Init flags in the memory block for serialization, the serializer will check * the flag to decide which ppr to be copied */ int ppr_init_ser_mem_by_bw(uint8* pbuf, wl_tx_bw_t bw, uint32 len) { ppr_ser_mem_flag_t *pmflag; if (pbuf == NULL || ppr_ser_size_by_bw(bw) > len) return BCME_BADARG; pmflag = (ppr_ser_mem_flag_t *)pbuf; pmflag->magic_word = HTON32(PPR_SER_MEM_WORD); pmflag->flag = HTON32(ppr_get_flag()); /* init the memory */ memset(pbuf + sizeof(*pmflag), (uint8)WL_RATE_DISABLED, len-sizeof(*pmflag)); return BCME_OK; }
inline void* MALLOCZ(void *o, size_t s) { BCM_REFERENCE(o); return calloc(1, s); }
/** * Translate non-xtlv 'wl counters' IOVar buffer received by old driver/FW to xtlv format. * Parameters: * cntbuf: pointer to non-xtlv 'wl counters' IOVar buffer received by old driver/FW. * Newly translated xtlv format is written to this pointer. * buflen: length of the "cntbuf" without any padding. * corerev: chip core revision of the driver/FW. */ int wl_cntbuf_to_xtlv_format(void *ctx, void *cntbuf, int buflen, uint32 corerev) { wl_cnt_wlc_t *wlccnt = NULL; uint32 *macstat = NULL; xtlv_desc_t xtlv_desc[3]; uint16 mcst_xtlv_id; int res = BCME_OK; wl_cnt_info_t *cntinfo = cntbuf; void *xtlvbuf_p = cntinfo->data; uint16 ver = cntinfo->version; uint16 xtlvbuflen = (uint16)buflen; uint16 src_max_idx; #ifdef BCMDRIVER osl_t *osh = ctx; #else BCM_REFERENCE(ctx); #endif if (ver == WL_CNT_T_VERSION) { /* Already in xtlv format. */ goto exit; } #ifdef BCMDRIVER wlccnt = MALLOC(osh, sizeof(*wlccnt)); macstat = MALLOC(osh, WL_CNT_MCST_STRUCT_SZ); #else wlccnt = (wl_cnt_wlc_t *)malloc(sizeof(*wlccnt)); macstat = (uint32 *)malloc(WL_CNT_MCST_STRUCT_SZ); #endif if (!wlccnt) { printf("wl_cntbuf_to_xtlv_format malloc fail!\n"); res = BCME_NOMEM; goto exit; } /* Check if the max idx in the struct exceeds the boundary of uint8 */ if (NUM_OF_CNT_IN_WL_CNT_VER_6_T > ((uint8)(-1) + 1) || NUM_OF_CNT_IN_WL_CNT_VER_11_T > ((uint8)(-1) + 1)) { printf("wlcntverXXt_to_wlcntwlct and src_max_idx need" " to be of uint16 instead of uint8\n"); res = BCME_ERROR; goto exit; } /* Exclude version and length fields in either wlc_cnt_ver_6_t or wlc_cnt_ver_11_t */ src_max_idx = (cntinfo->datalen - OFFSETOF(wl_cnt_info_t, data)) / sizeof(uint32); if (src_max_idx > (uint8)(-1)) { printf("wlcntverXXt_to_wlcntwlct and src_max_idx need" " to be of uint16 instead of uint8\n" "Try updating wl utility to the latest.\n"); res = BCME_ERROR; } /* Copy wlc layer counters to wl_cnt_wlc_t */ res = wl_copy_wlccnt(ver, (uint32 *)wlccnt, (uint32 *)cntinfo->data, (uint8)src_max_idx); if (res != BCME_OK) { printf("wl_copy_wlccnt fail!\n"); goto exit; } /* Copy macstat counters to wl_cnt_wlc_t */ if (ver == WL_CNT_VERSION_11) { res = wl_copy_macstat_ver11(macstat, (uint32 *)cntinfo->data); if (res != BCME_OK) { printf("wl_copy_macstat_ver11 fail!\n"); goto exit; } if (corerev >= 40) { mcst_xtlv_id = WL_CNT_XTLV_GE40_UCODE_V1; } else { mcst_xtlv_id = WL_CNT_XTLV_LT40_UCODE_V1; } } else { res = wl_copy_macstat_upto_ver10(ver, macstat, (uint32 *)cntinfo->data); if (res != BCME_OK) { printf("wl_copy_macstat_upto_ver10 fail!\n"); goto exit; } mcst_xtlv_id = WL_CNT_XTLV_CNTV_LE10_UCODE; } xtlv_desc[0].type = WL_CNT_XTLV_WLC; xtlv_desc[0].len = sizeof(*wlccnt); xtlv_desc[0].ptr = wlccnt; xtlv_desc[1].type = mcst_xtlv_id; xtlv_desc[1].len = WL_CNT_MCST_STRUCT_SZ; xtlv_desc[1].ptr = macstat; xtlv_desc[2].type = 0; xtlv_desc[2].len = 0; xtlv_desc[2].ptr = NULL; memset(cntbuf, 0, WL_CNTBUF_MAX_SIZE); res = bcm_pack_xtlv_buf_from_mem(&xtlvbuf_p, &xtlvbuflen, xtlv_desc, BCM_XTLV_OPTION_ALIGN32); cntinfo->datalen = (buflen - xtlvbuflen); exit: #ifdef BCMDRIVER if (wlccnt) { MFREE(osh, wlccnt, sizeof(*wlccnt)); } if (macstat) { MFREE(osh, macstat, WL_CNT_MCST_STRUCT_SZ); } #else if (wlccnt) { free(wlccnt); } if (macstat) { free(macstat); } #endif return res; }
static int dhd_wifi_platform_load_sdio(void) { int i; int err = 0; wifi_adapter_info_t *adapter; BCM_REFERENCE(i); BCM_REFERENCE(adapter); /* Sanity check on the module parameters * - Both watchdog and DPC as tasklets are ok * - If both watchdog and DPC are threads, TX must be deferred */ if (!(dhd_watchdog_prio < 0 && dhd_dpc_prio < 0) && !(dhd_watchdog_prio >= 0 && dhd_dpc_prio >= 0 && dhd_deferred_tx)) return -EINVAL; #if defined(BCMLXSDMMC) if (dhd_wifi_platdata == NULL) { DHD_ERROR(("DHD wifi platform data is required for Android build\n")); return -EINVAL; } sema_init(&dhd_registration_sem, 0); /* power up all adapters */ for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) { bool chip_up = FALSE; int retry = POWERUP_MAX_RETRY; struct semaphore dhd_chipup_sem; adapter = &dhd_wifi_platdata->adapters[i]; DHD_ERROR(("Power-up adapter '%s'\n", adapter->name)); DHD_INFO((" - irq %d [flags %d], firmware: %s, nvram: %s\n", adapter->irq_num, adapter->intr_flags, adapter->fw_path, adapter->nv_path)); DHD_INFO((" - bus type %d, bus num %d, slot num %d\n\n", adapter->bus_type, adapter->bus_num, adapter->slot_num)); do { sema_init(&dhd_chipup_sem, 0); err = dhd_bus_reg_sdio_notify(&dhd_chipup_sem); if (err) { DHD_ERROR(("%s dhd_bus_reg_sdio_notify fail(%d)\n\n", __FUNCTION__, err)); return err; } err = wifi_platform_set_power(adapter, TRUE, WIFI_TURNON_DELAY); if (err) { /* WL_REG_ON state unknown, Power off forcely */ wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY); continue; } else { wifi_platform_bus_enumerate(adapter, TRUE); err = 0; } if (down_timeout(&dhd_chipup_sem, msecs_to_jiffies(POWERUP_WAIT_MS)) == 0) { dhd_bus_unreg_sdio_notify(); chip_up = TRUE; break; } DHD_ERROR(("failed to power up %s, %d retry left\n", adapter->name, retry)); dhd_bus_unreg_sdio_notify(); wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY); wifi_platform_bus_enumerate(adapter, FALSE); } while (retry--); if (!chip_up) { DHD_ERROR(("failed to power up %s, max retry reached**\n", adapter->name)); return -ENODEV; } } err = dhd_bus_register(); if (err) { DHD_ERROR(("%s: sdio_register_driver failed\n", __FUNCTION__)); goto fail; } /* * Wait till MMC sdio_register_driver callback called and made driver attach. * It's needed to make sync up exit from dhd insmod and * Kernel MMC sdio device callback registration */ err = down_timeout(&dhd_registration_sem, msecs_to_jiffies(DHD_REGISTRATION_TIMEOUT)); if (err) { DHD_ERROR(("%s: sdio_register_driver timeout or error \n", __FUNCTION__)); dhd_bus_unregister(); goto fail; } return err; fail: /* power down all adapters */ for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) { adapter = &dhd_wifi_platdata->adapters[i]; wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY); wifi_platform_bus_enumerate(adapter, FALSE); } #else /* x86 bring-up PC needs no power-up operations */ err = dhd_bus_register(); #endif return err; }
static int dhd_wifi_platform_load_pcie(void) { int err = 0; int i; wifi_adapter_info_t *adapter; BCM_REFERENCE(i); BCM_REFERENCE(adapter); if (dhd_wifi_platdata == NULL) { err = dhd_bus_register(); } else { if (dhd_download_fw_on_driverload) { /* power up all adapters */ for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) { int retry = POWERUP_MAX_RETRY; adapter = &dhd_wifi_platdata->adapters[i]; DHD_ERROR(("Power-up adapter '%s'\n", adapter->name)); DHD_INFO((" - irq %d [flags %d], firmware: %s, nvram: %s\n", adapter->irq_num, adapter->intr_flags, adapter->fw_path, adapter->nv_path)); DHD_INFO((" - bus type %d, bus num %d, slot num %d\n\n", adapter->bus_type, adapter->bus_num, adapter->slot_num)); do { err = wifi_platform_set_power(adapter, TRUE, WIFI_TURNON_DELAY); if (err) { DHD_ERROR(("failed to power up %s," " %d retry left\n", adapter->name, retry)); /* WL_REG_ON state unknown, Power off forcely */ wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY); continue; } else { err = wifi_platform_bus_enumerate(adapter, TRUE); if (err) { DHD_ERROR(("failed to enumerate bus %s, " "%d retry left\n", adapter->name, retry)); wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY); } else { break; } } } while (retry--); if (!retry) { DHD_ERROR(("failed to power up %s, max retry reached**\n", adapter->name)); return -ENODEV; } } } err = dhd_bus_register(); if (err) { DHD_ERROR(("%s: pcie_register_driver failed\n", __FUNCTION__)); if (dhd_download_fw_on_driverload) { /* power down all adapters */ for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) { adapter = &dhd_wifi_platdata->adapters[i]; wifi_platform_bus_enumerate(adapter, FALSE); wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY); } } } } return err; }
static int dbus_usb_doiovar(usb_info_t *bus, const bcm_iovar_t *vi, uint32 actionid, const char *name, void *params, int plen, void *arg, int len, int val_size) { int bcmerror = 0; int32 int_val = 0; bool bool_val = 0; DBUSTRACE(("%s: Enter, action %d name %s params %p plen %d arg %p len %d val_size %d\n", __FUNCTION__, actionid, name, params, plen, arg, len, val_size)); if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid))) != 0) goto exit; if (plen >= (int)sizeof(int_val)) bcopy(params, &int_val, sizeof(int_val)); bool_val = (int_val != 0) ? TRUE : FALSE; switch (actionid) { case IOV_SVAL(IOV_MEMBYTES): case IOV_GVAL(IOV_MEMBYTES): { uint32 address; uint size, dsize; uint8 *data; bool set = (actionid == IOV_SVAL(IOV_MEMBYTES)); ASSERT(plen >= 2*sizeof(int)); address = (uint32)int_val; BCM_REFERENCE(address); bcopy((char *)params + sizeof(int_val), &int_val, sizeof(int_val)); size = (uint)int_val; /* Do some validation */ dsize = set ? plen - (2 * sizeof(int)) : len; if (dsize < size) { DBUSTRACE(("%s: error on %s membytes, addr 0x%08x size %d dsize %d\n", __FUNCTION__, (set ? "set" : "get"), address, size, dsize)); bcmerror = BCME_BADARG; break; } DBUSTRACE(("%s: Request to %s %d bytes at address 0x%08x\n", __FUNCTION__, (set ? "write" : "read"), size, address)); /* Generate the actual data pointer */ data = set ? (uint8*)params + 2 * sizeof(int): (uint8*)arg; /* Call to do the transfer */ bcmerror = dbus_usb_dl_writeimage(BUS_INFO(bus, usb_info_t), data, size); } break; case IOV_SVAL(IOV_SET_DOWNLOAD_STATE): if (bool_val == TRUE) { bcmerror = dbus_usb_dlneeded(bus); dbus_usb_rdl_dwnld_state(BUS_INFO(bus, usb_info_t)); } else { usb_info_t *usbinfo = BUS_INFO(bus, usb_info_t); bcmerror = dbus_usb_dlrun(bus); usbinfo->pub->busstate = DBUS_STATE_DL_DONE; } break; case IOV_SVAL(IOV_VARS): bcmerror = dhdusb_downloadvars(BUS_INFO(bus, usb_info_t), arg, len); break; default: bcmerror = BCME_UNSUPPORTED; break; } exit: return bcmerror; }
osl_t * osl_attach(void *pdev, uint bustype, bool pkttag) { osl_t *osh; osh = kmalloc(sizeof(osl_t), GFP_ATOMIC); ASSERT(osh); bzero(osh, sizeof(osl_t)); /* Check that error map has the right number of entries in it */ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1)); osh->magic = OS_HANDLE_MAGIC; atomic_set(&osh->malloced, 0); osh->failed = 0; osh->dbgmem_list = NULL; spin_lock_init(&(osh->dbgmem_lock)); osh->pdev = pdev; osh->pub.pkttag = pkttag; osh->bustype = bustype; switch (bustype) { case PCI_BUS: case SI_BUS: case PCMCIA_BUS: osh->pub.mmbus = TRUE; break; case JTAG_BUS: case SDIO_BUS: case USB_BUS: case SPI_BUS: case RPC_BUS: osh->pub.mmbus = FALSE; break; default: ASSERT(FALSE); break; } #if defined(DHD_USE_STATIC_BUF) if (!bcm_static_buf) { if (!(bcm_static_buf = (bcm_static_buf_t *)dhd_os_prealloc(osh, 3, STATIC_BUF_SIZE+ STATIC_BUF_TOTAL_LEN))) { printk("can not alloc static buf!\n"); } else printk("alloc static buf at %x!\n", (unsigned int)bcm_static_buf); sema_init(&bcm_static_buf->static_sem, 1); bcm_static_buf->buf_ptr = (unsigned char *)bcm_static_buf + STATIC_BUF_SIZE; } if (!bcm_static_skb) { int i; void *skb_buff_ptr = 0; bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048); skb_buff_ptr = dhd_os_prealloc(osh, 4, 0); bcopy(skb_buff_ptr, bcm_static_skb, sizeof(struct sk_buff *)*16); for (i = 0; i < STATIC_PKT_MAX_NUM * 2; i++) bcm_static_skb->pkt_use[i] = 0; sema_init(&bcm_static_skb->osl_pkt_sem, 1); } #endif /* DHD_USE_STATIC_BUF */ spin_lock_init(&(osh->pktalloc_lock)); #ifdef BCMDBG if (pkttag) { struct sk_buff *skb; BCM_REFERENCE(skb); ASSERT(OSL_PKTTAG_SZ <= sizeof(skb->cb)); } #endif return osh; }
inline void MFREE(void *o, void *p, size_t s) { BCM_REFERENCE(o); BCM_REFERENCE(s); free(p); }