static bool dbus_usb_device_exists(void *bus) { usb_info_t *usbinfo = BUS_INFO(bus, usb_info_t); void *osinfo; bootrom_id_t id; DBUSTRACE(("%s\n", __FUNCTION__)); if (usbinfo == NULL) return FALSE; osinfo = usbinfo->usbosl_info; ASSERT(osinfo); id.chip = 0xDEAD; /* Query device to see if we get a response */ dbus_usbos_dl_cmd(osinfo, DL_GETVER, &id, sizeof(bootrom_id_t)); usbinfo->pub->attrib.devid = id.chip; if (id.chip == 0xDEAD) return FALSE; else return TRUE; }
static int dbus_usb_dlstart(void *bus, uint8 *fw, int len) { usb_info_t *usbinfo = BUS_INFO(bus, usb_info_t); int err; DBUSTRACE(("%s\n", __FUNCTION__)); if (usbinfo == NULL) return DBUS_ERR; if (USB_DEV_ISBAD(usbinfo)) return DBUS_ERR; err = dbus_usb_rdl_dwnld_state(usbinfo); if (DBUS_OK == err) { err = dbus_usb_dl_writeimage(usbinfo, fw, len); if (err == DBUS_OK) usbinfo->pub->busstate = DBUS_STATE_DL_DONE; else usbinfo->pub->busstate = DBUS_STATE_DL_PENDING; } else usbinfo->pub->busstate = DBUS_STATE_DL_PENDING; return err; }
static void dbus_usb_get_revinfo(void *bus, uint32 *chipid, uint32 *chiprev) { usb_info_t *usbinfo = BUS_INFO(bus, usb_info_t); *chipid = usbinfo->pub->attrib.devid; *chiprev = usbinfo->pub->attrib.chiprev; }
static bool dbus_usb_sleep_resume_state(void *bus) { void *osinfo; usb_info_t *usbinfo = BUS_INFO(bus, usb_info_t); if (usbinfo == NULL) return FALSE; osinfo = usbinfo->usbosl_info; ASSERT(osinfo); return (dbus_usbos_intf_pnp(osinfo, DBUS_PNP_HSIC_SATE) != 0 ? TRUE : FALSE); }
static int dbus_usb_dlrun(void *bus) { usb_info_t *usbinfo = BUS_INFO(bus, usb_info_t); void *osinfo; rdl_state_t state; int err = DBUS_OK; DBUSTRACE(("%s\n", __FUNCTION__)); if (usbinfo == NULL) return DBUS_ERR; if (USB_DEV_ISBAD(usbinfo)) return DBUS_ERR; osinfo = usbinfo->usbosl_info; ASSERT(osinfo); /* Check we are runnable */ dbus_usbos_dl_cmd(osinfo, DL_GETSTATE, &state, sizeof(rdl_state_t)); state.state = ltoh32(state.state); state.bytes = ltoh32(state.bytes); /* Start the image */ if (state.state == DL_RUNNABLE) { DBUSTRACE(("%s: Issue DL_GO\n", __FUNCTION__)); dbus_usbos_dl_cmd(osinfo, DL_GO, &state, sizeof(rdl_state_t)); /* FIX: Need this for 4326 for some reason * Same issue under both Linux/Windows */ if (usbinfo->pub->attrib.devid == TEST_CHIP) dbus_usbos_wait(osinfo, USB_DLGO_SPINWAIT); dbus_usb_resetcfg(usbinfo); /* The Donlge may go for re-enumeration. */ } else { DBUSERR(("%s: Dongle not runnable\n", __FUNCTION__)); err = DBUS_ERR; } return err; }
static bool dbus_usb_dlneeded(void *bus) { usb_info_t *usbinfo = BUS_INFO(bus, usb_info_t); void *osinfo; bootrom_id_t id; bool dl_needed = TRUE; DBUSTRACE(("%s\n", __FUNCTION__)); if (usbinfo == NULL) return FALSE; osinfo = usbinfo->usbosl_info; ASSERT(osinfo); /* Check if firmware downloaded already by querying runtime ID */ id.chip = 0xDEAD; dbus_usbos_dl_cmd(osinfo, DL_GETVER, &id, sizeof(bootrom_id_t)); id.chip = ltoh32(id.chip); id.chiprev = ltoh32(id.chiprev); if (FALSE == dbus_usb_update_chipinfo(usbinfo, id.chip)) { dl_needed = FALSE; goto exit; } DBUSERR(("%s: chip 0x%x rev 0x%x\n", __FUNCTION__, id.chip, id.chiprev)); if (id.chip == POSTBOOT_ID) { /* This code is needed to support two enumerations on USB1.1 scenario */ DBUSERR(("%s: Firmware already downloaded\n", __FUNCTION__)); dbus_usbos_dl_cmd(osinfo, DL_RESETCFG, &id, sizeof(bootrom_id_t)); dl_needed = FALSE; if (usbinfo->pub->busstate == DBUS_STATE_DL_PENDING) usbinfo->pub->busstate = DBUS_STATE_DL_DONE; } else { usbinfo->pub->attrib.devid = id.chip; usbinfo->pub->attrib.chiprev = id.chiprev; } exit: return dl_needed; }
static int dbus_usb_sleep(void *bus, bool state) { int err = DBUS_OK; void *osinfo; usb_info_t *usbinfo = BUS_INFO(bus, usb_info_t); if (usbinfo == NULL) return DBUS_ERR; osinfo = usbinfo->usbosl_info; ASSERT(osinfo); if (state) { err = dbus_usbos_intf_pnp(osinfo, DBUS_PNP_SLEEP); } else { err = dbus_usbos_intf_pnp(osinfo, DBUS_PNP_RESUME); } 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; 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_GVAL(IOV_HSIC_SLEEP): bool_val = dbus_usb_sleep_resume_state(BUS_INFO(bus, usb_info_t)); bcopy(&bool_val, arg, val_size); break; case IOV_SVAL(IOV_HSIC_SLEEP): bcmerror = dbus_usb_sleep(BUS_INFO(bus, usb_info_t), bool_val); break; case IOV_GVAL(IOV_HSIC_AUTOSLEEP): bool_val = dbus_usb_autosleep_state(BUS_INFO(bus, usb_info_t)); bcopy(&bool_val, arg, val_size); break; case IOV_SVAL(IOV_HSIC_AUTOSLEEP): bcmerror = dbus_usb_autosleep(BUS_INFO(bus, usb_info_t), bool_val); 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; }
void dbus_bus_fw_get(void *bus, uint8 **fw, int *fwlen, int *decomp) { usb_info_t *usbinfo = BUS_INFO(bus, usb_info_t); unsigned int devid; unsigned int crev; devid = usbinfo->pub->attrib.devid; crev = usbinfo->pub->attrib.chiprev; *fw = NULL; *fwlen = 0; switch (devid) { case 0x4323: case 0x43231: case BCM4322_CHIP_ID: #ifdef EMBED_IMAGE_4322 *fw = (uint8 *) dlarray_4322; *fwlen = sizeof(dlarray_4322); *decomp = 1; #endif /* EMBED_IMAGE_4322 */ break; case BCM43236_CHIP_ID: case BCM43235_CHIP_ID: case BCM43234_CHIP_ID: case BCM43238_CHIP_ID: { if (crev == 3 || crev == 2) { #ifdef EMBED_IMAGE_43236b *fw = (uint8 *)dlarray_43236b; *fwlen = sizeof(dlarray_43236b); #elif defined(EMBED_IMAGE_43236b0) *fw = (uint8 *)dlarray_43236b0; *fwlen = sizeof(dlarray_43236b0); #elif defined(EMBED_IMAGE_GENERIC) *fw = (uint8 *)dlarray; *fwlen = sizeof(dlarray); #endif } else if (crev == 1) { #ifdef EMBED_IMAGE_43236a1 *fw = (uint8 *)dlarray_43236a1; *fwlen = sizeof(dlarray_43236a1); #endif } else { #ifdef EMBED_IMAGE_43236a0 *fw = (uint8 *)dlarray_43236a0; *fwlen = sizeof(dlarray_43236a0); #endif } } break; case BCM4319_CHIP_ID: #ifdef EMBED_IMAGE_4319usb *fw = (uint8 *)dlarray_4319usb; *fwlen = sizeof(dlarray_4319usb); #endif break; default: #ifdef EMBED_IMAGE_GENERIC *fw = (uint8 *)dlarray; *fwlen = sizeof(dlarray); #endif break; } }