示例#1
0
static int
dbus_usb_resetcfg(usb_info_t *usbinfo)
{
    void *osinfo;
    bootrom_id_t id;
    uint16 wait = 0, wait_time;

    DBUSTRACE(("%s\n", __FUNCTION__));

    if (usbinfo == NULL)
        return DBUS_ERR;

    osinfo = usbinfo->usbosl_info;
    ASSERT(osinfo);

    /* Give dongle chance to boot */
    wait_time = USB_SFLASH_DLIMAGE_SPINWAIT;
    while (wait < USB_SFLASH_DLIMAGE_LIMIT) {
        dbus_usbos_wait(osinfo, wait_time);

        wait += wait_time;

        id.chip = 0xDEAD;       /* Get the ID */
        dbus_usbos_dl_cmd(osinfo, DL_GETVER, &id, sizeof(bootrom_id_t));
        id.chip = ltoh32(id.chip);

        if (id.chip == POSTBOOT_ID)
            break;
    }

    if (id.chip == POSTBOOT_ID) {
        DBUSERR(("%s: download done %d ms postboot chip 0x%x/rev 0x%x\n",
                 __FUNCTION__, wait, id.chip, id.chiprev));

        dbus_usbos_dl_cmd(osinfo, DL_RESETCFG, &id, sizeof(bootrom_id_t));

        dbus_usbos_wait(osinfo, USB_RESETCFG_SPINWAIT);
        return DBUS_OK;
    } else {
        DBUSERR(("%s: Cannot talk to Dongle. Firmware is not UP, %d ms \n",
                 __FUNCTION__, wait));
        return DBUS_ERR;
    }

    return DBUS_OK;
}
示例#2
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;
}
示例#3
0
文件: dbus_usb.c 项目: cilynx/dd-wrt
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) {
		DBUSERR(("%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);

		err = dbus_usb_resetcfg(usbinfo);
	} else {
		DBUSERR(("%s: Dongle not runnable\n", __FUNCTION__));
		err = DBUS_ERR;
	}

	return err;
}
示例#4
0
static int
dbus_dldr_ioctl(struct inode *inode, struct file *filp,
	unsigned int cmd, unsigned long arg)
{
	int access_ok = 1, err = 0;
	unsigned int size;
	void *val = NULL;
	uint8 *buf = (uint8 *) arg;
	void *parms;
	char *name;
	int len = 0;

	size = _IOC_SIZE(cmd);
	if (_IOC_DIR(cmd) & _IOC_READ)
		access_ok = access_ok(VERIFY_WRITE, (void*) arg, size);
	else if (_IOC_DIR(cmd) & _IOC_WRITE)
		access_ok = access_ok(VERIFY_READ, (void*) arg, size);

	if (!access_ok)
		return -EFAULT;

	down(&g_probe_info.dlsem);

	switch (cmd) {
	case DBUS_GET_VAR:
		name = (char *)arg;
		parms = buf + strlen(buf) + 1;
		err = probe_iovar((const char *)name,
			parms, 0, (void *) arg, 0 /* len */, FALSE, &val, &len);

		if (val != NULL) {
			if (copy_to_user((void *)arg, val, len))
				err = -EFAULT;
		}
	break;

	case DBUS_SET_VAR:
		name = (char *)arg;
		parms = buf + strlen(buf) + 1;
		err = probe_iovar((const char *)name,
			parms, 0, (void *) arg, 0 /* len */, TRUE, NULL, NULL);
	break;

	default:
		DBUSERR(("Unhandled char ioctl: %d\n", cmd));
		err = -EINVAL;
	break;
	}

	if (err)
		err = -EFAULT;

	up(&g_probe_info.dlsem);

	return err;
}
示例#5
0
static bool
dbus_usb_update_chipinfo(usb_info_t *usbinfo, uint32 chip)
{
	bool retval = TRUE;
	/* based on the CHIP Id, store the ram size which is needed for NVRAM download. */
	switch (chip) {

		case 0x4319:
			usbinfo->rdlram_size = RDL_RAM_SIZE_4319;
			usbinfo->rdlram_base_addr = RDL_RAM_BASE_4319;
			break;

		case 0x4329:
			usbinfo->rdlram_size = RDL_RAM_SIZE_4329;
			usbinfo->rdlram_base_addr = RDL_RAM_BASE_4329;
			break;

		case 43234:
		case 43235:
		case 43236:
			usbinfo->rdlram_size = RDL_RAM_SIZE_43236;
			usbinfo->rdlram_base_addr = RDL_RAM_BASE_43236;
			break;

		case 0x4328:
			usbinfo->rdlram_size = RDL_RAM_SIZE_4328;
			usbinfo->rdlram_base_addr = RDL_RAM_BASE_4328;
			break;

		case 0x4322:
			usbinfo->rdlram_size = RDL_RAM_SIZE_4322;
			usbinfo->rdlram_base_addr = RDL_RAM_BASE_4322;
			break;

		case POSTBOOT_ID:
			break;

		default:
			DBUSERR(("%s: Chip 0x%x Ram size is not known\n", __FUNCTION__, chip));
			retval = FALSE;
			break;

	}

	return retval;
}
示例#6
0
int
dbus_bus_osl_register(int vid, int pid, probe_cb_t prcb,
	disconnect_cb_t discb, void *prarg, dbus_intf_t **intf, void *param1, void *param2)
{
	probe_info_t *pinfo = &g_probe_info;
	int err;

	probe_cb = prcb;
	disconnect_cb = discb;
	probe_arg = prarg;

	*intf = &dbus_sdos_intf;

	bzero(pinfo, sizeof(probe_info_t));
#ifdef CDEV_IOC_IF
	/* To support async probe callback when an image is downloadeda,
	 * we need access to the driver before net interface is brought up.
	 * Under Linux, we can create a download channel using char dev node interface.
	 */
	if (register_chrdev(CHARDEV_MAJOR, CHARDEV_NAME CHARDEV_SUFFIX, &dbus_dldr_fops))
		DBUSERR(("register_chrdev failed\n"));
	else
		init_MUTEX(&g_probe_info.dlsem);
#endif

	g_probe_info.dpc_pid = -1;
	err = bcmsdh_register(&sdh_driver);
	if (err == 0)
		err = DBUS_OK;
	else
		err = DBUS_ERR;

	if (delay_eth != 0) {
		sema_init(&g_probe_info.sem, 0);
		init_completion(&g_probe_info.dpc_exited);
		g_probe_info.dpc_pid = kernel_thread(dhd_probe_thread, &g_probe_info, 0);
	} else {
		g_probe_info.dpc_pid = -1;
	}

	return err;
}
示例#7
0
static int
dbus_usb_rdl_dwnld_state(usb_info_t *usbinfo)
{
    void *osinfo = usbinfo->usbosl_info;
    rdl_state_t state;
    int err = DBUS_OK;

    /* 1) Prepare USB boot loader for runtime image */
    dbus_usbos_dl_cmd(osinfo, DL_START, &state, sizeof(rdl_state_t));

    state.state = ltoh32(state.state);
    state.bytes = ltoh32(state.bytes);

    /* 2) Check we are in the Waiting state */
    if (state.state != DL_WAITING) {
        DBUSERR(("%s: Failed to DL_START\n", __FUNCTION__));
        err = DBUS_ERR;
        goto fail;
    }

fail:
    return err;
}
示例#8
0
static int
dbus_usb_dl_writeimage(usb_info_t *usbinfo, uint8 *fw, int fwlen)
{
    osl_t *osh = usbinfo->pub->osh;
    void *osinfo = usbinfo->usbosl_info;
    unsigned int sendlen, sent, dllen;
    char *bulkchunk = NULL, *dlpos;
    rdl_state_t state;
    int err = DBUS_OK;
    bootrom_id_t id;
    uint16 wait, wait_time;

    bulkchunk = MALLOC(osh, RDL_CHUNK);
    if (bulkchunk == NULL) {
        err = DBUS_ERR;
        goto fail;
    }

    sent = 0;
    dlpos = fw;
    dllen = fwlen;

    /* Get chip id and rev */
    id.chip = usbinfo->pub->attrib.devid;
    id.chiprev = usbinfo->pub->attrib.chiprev;

    DBUSTRACE(("enter %s: fwlen=%d\n", __FUNCTION__, fwlen));

    dbus_usbos_dl_cmd(osinfo, DL_GETSTATE, &state, sizeof(rdl_state_t));

    /* 3) Load the image */
    while ((sent < dllen)) {
        /* Wait until the usb device reports it received all the bytes we sent */

        if (sent < dllen) {
            if ((dllen-sent) < RDL_CHUNK)
                sendlen = dllen-sent;
            else
                sendlen = RDL_CHUNK;

            /* simply avoid having to send a ZLP by ensuring we never have an even
             * multiple of 64
             */
            if (!(sendlen % 64))
                sendlen -= 4;

            /* send data */
            memcpy(bulkchunk, dlpos, sendlen);
            if (!dbus_usbos_dl_send_bulk(osinfo, bulkchunk, sendlen)) {
                err = DBUS_ERR;
                goto fail;
            }

            dlpos += sendlen;
            sent += sendlen;
            DBUSTRACE(("%s: sendlen %d\n", __FUNCTION__, sendlen));
        }

        /* 43236a0 bootloader runs from sflash, which is slower than rom
         * Wait for downloaded image crc check to complete in the dongle
         */
        wait = 0;
        wait_time = USB_SFLASH_DLIMAGE_SPINWAIT;
        while (!dbus_usbos_dl_cmd(osinfo, DL_GETSTATE, &state,
                                  sizeof(rdl_state_t))) {
            if ((id.chip == 43236) && (id.chiprev == 0)) {
                DBUSERR(("%s: 43236a0 SFlash delay, waiting for dongle crc check "
                         "completion!!!\n", __FUNCTION__));
                dbus_usbos_wait(osinfo, wait_time);
                wait += wait_time;
                if (wait >= USB_SFLASH_DLIMAGE_LIMIT) {
                    DBUSERR(("%s: DL_GETSTATE Failed xxxx\n", __FUNCTION__));
                    err = DBUS_ERR;
                    goto fail;
                    break;
                }
            } else {
                DBUSERR(("%s: DL_GETSTATE Failed xxxx\n", __FUNCTION__));
                err = DBUS_ERR;
                goto fail;
            }
        }

        state.state = ltoh32(state.state);
        state.bytes = ltoh32(state.bytes);

        /* restart if an error is reported */
        if ((state.state == DL_BAD_HDR) || (state.state == DL_BAD_CRC)) {
            DBUSERR(("%s: Bad Hdr or Bad CRC state %d\n", __FUNCTION__, state.state));
            err = DBUS_ERR;
            goto fail;
        }

    }
fail:
    if (bulkchunk)
        MFREE(osh, bulkchunk, RDL_CHUNK);

    return err;
}