예제 #1
0
파일: if_usb.c 프로젝트: nocl/linux-libre
static int if_usb_reset_device(struct if_usb_card *cardp)
{
	struct cmd_ds_802_11_reset *cmd = cardp->ep_out_buf + 4;
	int ret;

	lbtf_deb_enter(LBTF_DEB_USB);

	*(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);

	cmd->hdr.command = cpu_to_le16(CMD_802_11_RESET);
	cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_802_11_reset));
	cmd->hdr.result = cpu_to_le16(0);
	cmd->hdr.seqnum = cpu_to_le16(0x5a5a);
	cmd->action = cpu_to_le16(CMD_ACT_HALT);
	usb_tx_block(cardp, cardp->ep_out_buf,
		     4 + sizeof(struct cmd_ds_802_11_reset), 0);

	msleep(100);
	ret = usb_reset_device(cardp->udev);
	msleep(100);

	lbtf_deb_leave_args(LBTF_DEB_USB, "ret %d", ret);

	return ret;
}
예제 #2
0
static int if_usb_reset_device(struct if_usb_card *cardp)
{
	struct cmd_ds_command *cmd = cardp->ep_out_buf + 4;
	int ret;

	lbs_deb_enter(LBS_DEB_USB);

	*(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);

	cmd->command = cpu_to_le16(CMD_802_11_RESET);
	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_reset) + S_DS_GEN);
	cmd->result = cpu_to_le16(0);
	cmd->seqnum = cpu_to_le16(0x5a5a);
	cmd->params.reset.action = cpu_to_le16(CMD_ACT_HALT);
	usb_tx_block(cardp, cardp->ep_out_buf, 4 + S_DS_GEN + sizeof(struct cmd_ds_802_11_reset));

	msleep(100);
	ret = usb_reset_device(cardp->udev);
	msleep(100);

#ifdef CONFIG_OLPC
	if (ret && machine_is_olpc())
		if_usb_reset_olpc_card(NULL);
#endif

	lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);

	return ret;
}
예제 #3
0
/**
 *  @brief This function downloads data to FW
 *  @param priv		pointer to wlan_private structure
 *  @param type		type of data
 *  @param buf		pointer to data buffer
 *  @param len		number of bytes
 *  @return 	   	0 or -1
 */
static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb)
{
	int ret = -1;
	u32 tmp;
	struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;

	lbs_deb_usbd(&cardp->udev->dev,"*** type = %u\n", type);
	lbs_deb_usbd(&cardp->udev->dev,"size after = %d\n", nb);

	if (type == MVMS_CMD) {
		tmp = cpu_to_le32(CMD_TYPE_REQUEST);
		priv->dnld_sent = DNLD_CMD_SENT;
		memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
		       MESSAGE_HEADER_LEN);

	} else {
		tmp = cpu_to_le32(CMD_TYPE_DATA);
		priv->dnld_sent = DNLD_DATA_SENT;
		memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
		       MESSAGE_HEADER_LEN);
	}

	memcpy((cardp->bulk_out_buffer + MESSAGE_HEADER_LEN), payload, nb);

	ret =
	    usb_tx_block(priv, cardp->bulk_out_buffer, nb + MESSAGE_HEADER_LEN);

	return ret;
}
예제 #4
0
/**
 *  if_usb_send_fw_pkt -  This function downloads the FW
 *
 *  @priv	pointer to struct lbtf_private
 *
 *  Returns: 0
 */
static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
{
	struct fwdata *fwdata = cardp->ep_out_buf;
	u8 *firmware = (u8 *) cardp->fw->data;

	lbtf_deb_enter(LBTF_DEB_FW);

	/* If we got a CRC failure on the last block, back
	   up and retry it */
	if (!cardp->CRC_OK) {
		cardp->totalbytes = cardp->fwlastblksent;
		cardp->fwseqnum--;
	}

	lbtf_deb_usb2(&cardp->udev->dev, "totalbytes = %d\n",
		     cardp->totalbytes);

	/* struct fwdata (which we sent to the card) has an
	   extra __le32 field in between the header and the data,
	   which is not in the struct fwheader in the actual
	   firmware binary. Insert the seqnum in the middle... */
	memcpy(&fwdata->hdr, &firmware[cardp->totalbytes],
	       sizeof(struct fwheader));

	cardp->fwlastblksent = cardp->totalbytes;
	cardp->totalbytes += sizeof(struct fwheader);

	memcpy(fwdata->data, &firmware[cardp->totalbytes],
	       le32_to_cpu(fwdata->hdr.datalength));

	lbtf_deb_usb2(&cardp->udev->dev, "Data length = %d\n",
		     le32_to_cpu(fwdata->hdr.datalength));

	fwdata->seqnum = cpu_to_le32(++cardp->fwseqnum);
	cardp->totalbytes += le32_to_cpu(fwdata->hdr.datalength);

	usb_tx_block(cardp, cardp->ep_out_buf, sizeof(struct fwdata) +
		     le32_to_cpu(fwdata->hdr.datalength), 0);

	if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) {
		lbtf_deb_usb2(&cardp->udev->dev, "There are data to follow\n");
		lbtf_deb_usb2(&cardp->udev->dev, "seqnum = %d totalbytes = %d\n",
			     cardp->fwseqnum, cardp->totalbytes);
	} else if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
		lbtf_deb_usb2(&cardp->udev->dev, "Host has finished FW downloading\n");
		lbtf_deb_usb2(&cardp->udev->dev, "Donwloading FW JUMP BLOCK\n");

		/* Host has finished FW downloading
		 * Donwloading FW JUMP BLOCK
		 */
		cardp->fwfinalblk = 1;
	}

	lbtf_deb_usb2(&cardp->udev->dev, "Firmware download done; size %d\n",
		     cardp->totalbytes);

	lbtf_deb_leave(LBTF_DEB_FW);
	return 0;
}
예제 #5
0
static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
{
	struct fwdata *fwdata = cardp->ep_out_buf;
	u8 *firmware = (u8 *) cardp->fw->data;

	lbtf_deb_enter(LBTF_DEB_FW);

	if (!cardp->CRC_OK) {
		cardp->totalbytes = cardp->fwlastblksent;
		cardp->fwseqnum--;
	}

	lbtf_deb_usb2(&cardp->udev->dev, "totalbytes = %d\n",
		     cardp->totalbytes);

	memcpy(&fwdata->hdr, &firmware[cardp->totalbytes],
	       sizeof(struct fwheader));

	cardp->fwlastblksent = cardp->totalbytes;
	cardp->totalbytes += sizeof(struct fwheader);

	memcpy(fwdata->data, &firmware[cardp->totalbytes],
	       le32_to_cpu(fwdata->hdr.datalength));

	lbtf_deb_usb2(&cardp->udev->dev, "Data length = %d\n",
		     le32_to_cpu(fwdata->hdr.datalength));

	fwdata->seqnum = cpu_to_le32(++cardp->fwseqnum);
	cardp->totalbytes += le32_to_cpu(fwdata->hdr.datalength);

	usb_tx_block(cardp, cardp->ep_out_buf, sizeof(struct fwdata) +
		     le32_to_cpu(fwdata->hdr.datalength), 0);

	if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) {
		lbtf_deb_usb2(&cardp->udev->dev, "There are data to follow\n");
		lbtf_deb_usb2(&cardp->udev->dev,
			"seqnum = %d totalbytes = %d\n",
			cardp->fwseqnum, cardp->totalbytes);
	} else if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
		lbtf_deb_usb2(&cardp->udev->dev,
			"Host has finished FW downloading\n");
		lbtf_deb_usb2(&cardp->udev->dev, "Donwloading FW JUMP BLOCK\n");

		cardp->fwfinalblk = 1;
	}

	lbtf_deb_usb2(&cardp->udev->dev, "Firmware download done; size %d\n",
		     cardp->totalbytes);

	lbtf_deb_leave(LBTF_DEB_FW);
	return 0;
}
예제 #6
0
/**
 *  if_usb_send_fw_pkt -  This function downloads the FW
 *
 *  @priv	pointer to struct lbtf_private
 *
 *  Returns: 0
 */
static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
{
	struct fwdata *fwdata = cardp->ep_out_buf;
	u8 *firmware = (u8 *) cardp->fw->data;

	/* If we got a CRC failure on the last block, back
	   up and retry it */
	if (!cardp->CRC_OK) {
		cardp->totalbytes = cardp->fwlastblksent;
		cardp->fwseqnum--;
	}

	/* struct fwdata (which we sent to the card) has an
	   extra __le32 field in between the header and the data,
	   which is not in the struct fwheader in the actual
	   firmware binary. Insert the seqnum in the middle... */
	memcpy(&fwdata->hdr, &firmware[cardp->totalbytes],
	       sizeof(struct fwheader));

	cardp->fwlastblksent = cardp->totalbytes;
	cardp->totalbytes += sizeof(struct fwheader);

	memcpy(fwdata->data, &firmware[cardp->totalbytes],
	       le32_to_cpu(fwdata->hdr.datalength));

	fwdata->seqnum = cpu_to_le32(++cardp->fwseqnum);
	cardp->totalbytes += le32_to_cpu(fwdata->hdr.datalength);

	usb_tx_block(cardp, cardp->ep_out_buf, sizeof(struct fwdata) +
		     le32_to_cpu(fwdata->hdr.datalength), 0);

	if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK))
		/* Host has finished FW downloading
		 * Donwloading FW JUMP BLOCK
		 */
		cardp->fwfinalblk = 1;

	return 0;
}
예제 #7
0
/**
 *  @brief  This function download FW
 *  @param priv		pointer to wlan_private
 *  @return 	   	0
 */
static int if_prog_firmware(wlan_private * priv)
{
	struct usb_card_rec *cardp = priv->card;
	struct FWData *fwdata;
	struct fwheader *fwheader;
	u8 *firmware = priv->firmware->data;

	fwdata = kmalloc(sizeof(struct FWData), GFP_ATOMIC);

	if (!fwdata)
		return -1;

	fwheader = &fwdata->fwheader;

	if (!cardp->CRC_OK) {
		cardp->totalbytes = cardp->fwlastblksent;
		cardp->fwseqnum = cardp->lastseqnum - 1;
	}

	/*
	lbs_deb_usbd(&cardp->udev->dev, "totalbytes = %d\n",
		    cardp->totalbytes);
	*/

	memcpy(fwheader, &firmware[cardp->totalbytes],
	       sizeof(struct fwheader));

	cardp->fwlastblksent = cardp->totalbytes;
	cardp->totalbytes += sizeof(struct fwheader);

	/* lbs_deb_usbd(&cardp->udev->dev,"Copy Data\n"); */
	memcpy(fwdata->data, &firmware[cardp->totalbytes],
	       le32_to_cpu(fwdata->fwheader.datalength));

	/*
	lbs_deb_usbd(&cardp->udev->dev,
		    "Data length = %d\n", le32_to_cpu(fwdata->fwheader.datalength));
	*/

	cardp->fwseqnum = cardp->fwseqnum + 1;

	fwdata->seqnum = cpu_to_le32(cardp->fwseqnum);
	cardp->lastseqnum = cardp->fwseqnum;
	cardp->totalbytes += le32_to_cpu(fwdata->fwheader.datalength);

	if (fwheader->dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) {
		/*
		lbs_deb_usbd(&cardp->udev->dev, "There are data to follow\n");
		lbs_deb_usbd(&cardp->udev->dev,
			    "seqnum = %d totalbytes = %d\n", cardp->fwseqnum,
			    cardp->totalbytes);
		*/
		memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
		usb_tx_block(priv, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);

	} else if (fwdata->fwheader.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
		/*
		lbs_deb_usbd(&cardp->udev->dev,
			    "Host has finished FW downloading\n");
		lbs_deb_usbd(&cardp->udev->dev,
			    "Donwloading FW JUMP BLOCK\n");
		*/
		memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
		usb_tx_block(priv, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
		cardp->fwfinalblk = 1;
	}

	/*
	lbs_deb_usbd(&cardp->udev->dev,
		    "The firmware download is done size is %d\n",
		    cardp->totalbytes);
	*/

	kfree(fwdata);

	return 0;
}