示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
0
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);
}
示例#5
0
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;
}
示例#6
0
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;
}
示例#7
0
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;
}
示例#8
0
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;
}
示例#9
0
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;
	}
}