示例#1
0
/*----------------------------------------------------------------
* prism2sta_mlmerequest
*
* wlan command message handler.  All we do here is pass the message
* over to the prism2sta_mgmt_handler.
*
* Arguments:
*	wlandev		wlan device structure
*	msg		wlan command message
* Returns:
*	0		success
*	<0		successful acceptance of message, but we're
*			waiting for an async process to finish before
*			we're done with the msg.  When the asynch
*			process is done, we'll call the p80211
*			function p80211req_confirm() .
*	>0		An error occurred while we were handling
*			the message.
*
* Side effects:
*
* Call context:
*	process thread
----------------------------------------------------------------*/
static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg)
{
	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;

	int result = 0;

	switch (msg->msgcode) {
	case DIDmsg_dot11req_mibget:
		pr_debug("Received mibget request\n");
		result = prism2mgmt_mibset_mibget(wlandev, msg);
		break;
	case DIDmsg_dot11req_mibset:
		pr_debug("Received mibset request\n");
		result = prism2mgmt_mibset_mibget(wlandev, msg);
		break;
	case DIDmsg_dot11req_scan:
		pr_debug("Received scan request\n");
		result = prism2mgmt_scan(wlandev, msg);
		break;
	case DIDmsg_dot11req_scan_results:
		pr_debug("Received scan_results request\n");
		result = prism2mgmt_scan_results(wlandev, msg);
		break;
	case DIDmsg_dot11req_start:
		pr_debug("Received mlme start request\n");
		result = prism2mgmt_start(wlandev, msg);
		break;
		
	case DIDmsg_p2req_readpda:
		pr_debug("Received mlme readpda request\n");
		result = prism2mgmt_readpda(wlandev, msg);
		break;
	case DIDmsg_p2req_ramdl_state:
		pr_debug("Received mlme ramdl_state request\n");
		result = prism2mgmt_ramdl_state(wlandev, msg);
		break;
	case DIDmsg_p2req_ramdl_write:
		pr_debug("Received mlme ramdl_write request\n");
		result = prism2mgmt_ramdl_write(wlandev, msg);
		break;
	case DIDmsg_p2req_flashdl_state:
		pr_debug("Received mlme flashdl_state request\n");
		result = prism2mgmt_flashdl_state(wlandev, msg);
		break;
	case DIDmsg_p2req_flashdl_write:
		pr_debug("Received mlme flashdl_write request\n");
		result = prism2mgmt_flashdl_write(wlandev, msg);
		break;
		
	case DIDmsg_lnxreq_hostwep:
		break;		
	case DIDmsg_lnxreq_ifstate:
		{
			p80211msg_lnxreq_ifstate_t *ifstatemsg;
			pr_debug("Received mlme ifstate request\n");
			ifstatemsg = (p80211msg_lnxreq_ifstate_t *) msg;
			result =
			    prism2sta_ifstate(wlandev,
					      ifstatemsg->ifstate.data);
			ifstatemsg->resultcode.status =
			    P80211ENUM_msgitem_status_data_ok;
			ifstatemsg->resultcode.data = result;
			result = 0;
		}
		break;
	case DIDmsg_lnxreq_wlansniff:
		pr_debug("Received mlme wlansniff request\n");
		result = prism2mgmt_wlansniff(wlandev, msg);
		break;
	case DIDmsg_lnxreq_autojoin:
		pr_debug("Received mlme autojoin request\n");
		result = prism2mgmt_autojoin(wlandev, msg);
		break;
	case DIDmsg_lnxreq_commsquality:{
			p80211msg_lnxreq_commsquality_t *qualmsg;

			pr_debug("Received commsquality request\n");

			qualmsg = (p80211msg_lnxreq_commsquality_t *) msg;

			qualmsg->link.status =
			    P80211ENUM_msgitem_status_data_ok;
			qualmsg->level.status =
			    P80211ENUM_msgitem_status_data_ok;
			qualmsg->noise.status =
			    P80211ENUM_msgitem_status_data_ok;

			qualmsg->link.data = le16_to_cpu(hw->qual.CQ_currBSS);
			qualmsg->level.data = le16_to_cpu(hw->qual.ASL_currBSS);
			qualmsg->noise.data = le16_to_cpu(hw->qual.ANL_currFC);

			break;
		}
	default:
		printk(KERN_WARNING "Unknown mgmt request message 0x%08x",
		       msg->msgcode);
		break;
	}

	return result;
}
示例#2
0
/*----------------------------------------------------------------
* writeimage
*
* Takes the chunks, builds p80211 messages and sends them down
* to the driver for writing to the card.
*
* Arguments:
*	wlandev		device
*	fchunk		Array of image chunks
*	nfchunks	Number of image chunks
*
* Returns:
*	0	success
*	~0	failure
----------------------------------------------------------------*/
int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk,
	       unsigned int nfchunks)
{
	int result = 0;
	struct p80211msg_p2req_ramdl_state *rstmsg;
	struct p80211msg_p2req_ramdl_write *rwrmsg;
	u32 resultcode;
	int i;
	int j;
	unsigned int nwrites;
	u32 curroff;
	u32 currlen;
	u32 currdaddr;

	rstmsg = kmalloc(sizeof(*rstmsg), GFP_KERNEL);
	rwrmsg = kmalloc(sizeof(*rwrmsg), GFP_KERNEL);
	if (!rstmsg || !rwrmsg) {
		kfree(rstmsg);
		kfree(rwrmsg);
		printk(KERN_ERR
		       "writeimage: no memory for firmware download, "
		       "aborting download\n");
		return -ENOMEM;
	}

	/* Initialize the messages */
	memset(rstmsg, 0, sizeof(*rstmsg));
	strcpy(rstmsg->devname, wlandev->name);
	rstmsg->msgcode = DIDmsg_p2req_ramdl_state;
	rstmsg->msglen = sizeof(*rstmsg);
	rstmsg->enable.did = DIDmsg_p2req_ramdl_state_enable;
	rstmsg->exeaddr.did = DIDmsg_p2req_ramdl_state_exeaddr;
	rstmsg->resultcode.did = DIDmsg_p2req_ramdl_state_resultcode;
	rstmsg->enable.status = P80211ENUM_msgitem_status_data_ok;
	rstmsg->exeaddr.status = P80211ENUM_msgitem_status_data_ok;
	rstmsg->resultcode.status = P80211ENUM_msgitem_status_no_value;
	rstmsg->enable.len = sizeof(u32);
	rstmsg->exeaddr.len = sizeof(u32);
	rstmsg->resultcode.len = sizeof(u32);

	memset(rwrmsg, 0, sizeof(*rwrmsg));
	strcpy(rwrmsg->devname, wlandev->name);
	rwrmsg->msgcode = DIDmsg_p2req_ramdl_write;
	rwrmsg->msglen = sizeof(*rwrmsg);
	rwrmsg->addr.did = DIDmsg_p2req_ramdl_write_addr;
	rwrmsg->len.did = DIDmsg_p2req_ramdl_write_len;
	rwrmsg->data.did = DIDmsg_p2req_ramdl_write_data;
	rwrmsg->resultcode.did = DIDmsg_p2req_ramdl_write_resultcode;
	rwrmsg->addr.status = P80211ENUM_msgitem_status_data_ok;
	rwrmsg->len.status = P80211ENUM_msgitem_status_data_ok;
	rwrmsg->data.status = P80211ENUM_msgitem_status_data_ok;
	rwrmsg->resultcode.status = P80211ENUM_msgitem_status_no_value;
	rwrmsg->addr.len = sizeof(u32);
	rwrmsg->len.len = sizeof(u32);
	rwrmsg->data.len = WRITESIZE_MAX;
	rwrmsg->resultcode.len = sizeof(u32);

	/* Send xxx_state(enable) */
	pr_debug("Sending dl_state(enable) message.\n");
	rstmsg->enable.data = P80211ENUM_truth_true;
	rstmsg->exeaddr.data = startaddr;

	result = prism2mgmt_ramdl_state(wlandev, rstmsg);
	if (result) {
		printk(KERN_ERR
		       "writeimage state enable failed w/ result=%d, "
		       "aborting download\n", result);
		goto free_result;
	}
	resultcode = rstmsg->resultcode.data;
	if (resultcode != P80211ENUM_resultcode_success) {
		printk(KERN_ERR
		       "writeimage()->xxxdl_state msg indicates failure, "
		       "w/ resultcode=%d, aborting download.\n", resultcode);
		result = 1;
		goto free_result;
	}

	/* Now, loop through the data chunks and send WRITESIZE_MAX data */
	for (i = 0; i < nfchunks; i++) {
		nwrites = fchunk[i].len / WRITESIZE_MAX;
		nwrites += (fchunk[i].len % WRITESIZE_MAX) ? 1 : 0;
		curroff = 0;
		for (j = 0; j < nwrites; j++) {
			/* TODO Move this to a separate function */
			int lenleft = fchunk[i].len - (WRITESIZE_MAX * j);
			if (fchunk[i].len > WRITESIZE_MAX)
				currlen = WRITESIZE_MAX;
			else
				currlen = lenleft;
			curroff = j * WRITESIZE_MAX;
			currdaddr = fchunk[i].addr + curroff;
			/* Setup the message */
			rwrmsg->addr.data = currdaddr;
			rwrmsg->len.data = currlen;
			memcpy(rwrmsg->data.data,
			       fchunk[i].data + curroff, currlen);

			/* Send flashdl_write(pda) */
			pr_debug
			    ("Sending xxxdl_write message addr=%06x len=%d.\n",
			     currdaddr, currlen);

			result = prism2mgmt_ramdl_write(wlandev, rwrmsg);

			/* Check the results */
			if (result) {
				printk(KERN_ERR
				       "writeimage chunk write failed w/ result=%d, "
				       "aborting download\n", result);
				goto free_result;
			}
			resultcode = rstmsg->resultcode.data;
			if (resultcode != P80211ENUM_resultcode_success) {
				printk(KERN_ERR
				       "writeimage()->xxxdl_write msg indicates failure, "
				       "w/ resultcode=%d, aborting download.\n",
				       resultcode);
				result = 1;
				goto free_result;
			}

		}
	}

	/* Send xxx_state(disable) */
	pr_debug("Sending dl_state(disable) message.\n");
	rstmsg->enable.data = P80211ENUM_truth_false;
	rstmsg->exeaddr.data = 0;

	result = prism2mgmt_ramdl_state(wlandev, rstmsg);
	if (result) {
		printk(KERN_ERR
		       "writeimage state disable failed w/ result=%d, "
		       "aborting download\n", result);
		goto free_result;
	}
	resultcode = rstmsg->resultcode.data;
	if (resultcode != P80211ENUM_resultcode_success) {
		printk(KERN_ERR
		       "writeimage()->xxxdl_state msg indicates failure, "
		       "w/ resultcode=%d, aborting download.\n", resultcode);
		result = 1;
		goto free_result;
	}

free_result:
	kfree(rstmsg);
	kfree(rwrmsg);
	return result;
}
int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk,
	       unsigned int nfchunks)
{
	int result = 0;
	struct p80211msg_p2req_ramdl_state rstatemsg;
	struct p80211msg_p2req_ramdl_write rwritemsg;
	struct p80211msg *msgp;
	u32 resultcode;
	int i;
	int j;
	unsigned int nwrites;
	u32 curroff;
	u32 currlen;
	u32 currdaddr;

	
	memset(&rstatemsg, 0, sizeof(rstatemsg));
	strcpy(rstatemsg.devname, wlandev->name);
	rstatemsg.msgcode = DIDmsg_p2req_ramdl_state;
	rstatemsg.msglen = sizeof(rstatemsg);
	rstatemsg.enable.did = DIDmsg_p2req_ramdl_state_enable;
	rstatemsg.exeaddr.did = DIDmsg_p2req_ramdl_state_exeaddr;
	rstatemsg.resultcode.did = DIDmsg_p2req_ramdl_state_resultcode;
	rstatemsg.enable.status = P80211ENUM_msgitem_status_data_ok;
	rstatemsg.exeaddr.status = P80211ENUM_msgitem_status_data_ok;
	rstatemsg.resultcode.status = P80211ENUM_msgitem_status_no_value;
	rstatemsg.enable.len = sizeof(u32);
	rstatemsg.exeaddr.len = sizeof(u32);
	rstatemsg.resultcode.len = sizeof(u32);

	memset(&rwritemsg, 0, sizeof(rwritemsg));
	strcpy(rwritemsg.devname, wlandev->name);
	rwritemsg.msgcode = DIDmsg_p2req_ramdl_write;
	rwritemsg.msglen = sizeof(rwritemsg);
	rwritemsg.addr.did = DIDmsg_p2req_ramdl_write_addr;
	rwritemsg.len.did = DIDmsg_p2req_ramdl_write_len;
	rwritemsg.data.did = DIDmsg_p2req_ramdl_write_data;
	rwritemsg.resultcode.did = DIDmsg_p2req_ramdl_write_resultcode;
	rwritemsg.addr.status = P80211ENUM_msgitem_status_data_ok;
	rwritemsg.len.status = P80211ENUM_msgitem_status_data_ok;
	rwritemsg.data.status = P80211ENUM_msgitem_status_data_ok;
	rwritemsg.resultcode.status = P80211ENUM_msgitem_status_no_value;
	rwritemsg.addr.len = sizeof(u32);
	rwritemsg.len.len = sizeof(u32);
	rwritemsg.data.len = WRITESIZE_MAX;
	rwritemsg.resultcode.len = sizeof(u32);

	
	pr_debug("Sending dl_state(enable) message.\n");
	rstatemsg.enable.data = P80211ENUM_truth_true;
	rstatemsg.exeaddr.data = startaddr;

	msgp = (struct p80211msg *) &rstatemsg;
	result = prism2mgmt_ramdl_state(wlandev, msgp);
	if (result) {
		printk(KERN_ERR
		       "writeimage state enable failed w/ result=%d, "
		       "aborting download\n", result);
		return result;
	}
	resultcode = rstatemsg.resultcode.data;
	if (resultcode != P80211ENUM_resultcode_success) {
		printk(KERN_ERR
		       "writeimage()->xxxdl_state msg indicates failure, "
		       "w/ resultcode=%d, aborting download.\n", resultcode);
		return 1;
	}

	
	for (i = 0; i < nfchunks; i++) {
		nwrites = fchunk[i].len / WRITESIZE_MAX;
		nwrites += (fchunk[i].len % WRITESIZE_MAX) ? 1 : 0;
		curroff = 0;
		for (j = 0; j < nwrites; j++) {
			
			int lenleft = fchunk[i].len - (WRITESIZE_MAX * j);
			if (fchunk[i].len > WRITESIZE_MAX)
				currlen = WRITESIZE_MAX;
			else
				currlen = lenleft;
			curroff = j * WRITESIZE_MAX;
			currdaddr = fchunk[i].addr + curroff;
			
			rwritemsg.addr.data = currdaddr;
			rwritemsg.len.data = currlen;
			memcpy(rwritemsg.data.data,
			       fchunk[i].data + curroff, currlen);

			
			pr_debug
			    ("Sending xxxdl_write message addr=%06x len=%d.\n",
			     currdaddr, currlen);

			msgp = (struct p80211msg *) &rwritemsg;
			result = prism2mgmt_ramdl_write(wlandev, msgp);

			
			if (result) {
				printk(KERN_ERR
				       "writeimage chunk write failed w/ result=%d, "
				       "aborting download\n", result);
				return result;
			}
			resultcode = rstatemsg.resultcode.data;
			if (resultcode != P80211ENUM_resultcode_success) {
				printk(KERN_ERR
				       "writeimage()->xxxdl_write msg indicates failure, "
				       "w/ resultcode=%d, aborting download.\n",
				       resultcode);
				return 1;
			}

		}
	}

	
	pr_debug("Sending dl_state(disable) message.\n");
	rstatemsg.enable.data = P80211ENUM_truth_false;
	rstatemsg.exeaddr.data = 0;

	msgp = (struct p80211msg *) &rstatemsg;
	result = prism2mgmt_ramdl_state(wlandev, msgp);
	if (result) {
		printk(KERN_ERR
		       "writeimage state disable failed w/ result=%d, "
		       "aborting download\n", result);
		return result;
	}
	resultcode = rstatemsg.resultcode.data;
	if (resultcode != P80211ENUM_resultcode_success) {
		printk(KERN_ERR
		       "writeimage()->xxxdl_state msg indicates failure, "
		       "w/ resultcode=%d, aborting download.\n", resultcode);
		return 1;
	}
	return result;
}
示例#4
0
/*----------------------------------------------------------------
* writeimage
*
* Takes the chunks, builds p80211 messages and sends them down
* to the driver for writing to the card.
*
* Arguments:
*	wlandev		device
*	fchunk		Array of image chunks
*	nfchunks	Number of image chunks
*
* Returns:
*	0	success
*	~0	failure
----------------------------------------------------------------*/
int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk,
	       unsigned int nfchunks)
{
	int result = 0;
	p80211msg_p2req_ramdl_state_t rstatemsg;
	p80211msg_p2req_ramdl_write_t rwritemsg;
	p80211msg_t *msgp;
	u32 resultcode;
	int i;
	int j;
	unsigned int nwrites;
	u32 curroff;
	u32 currlen;
	u32 currdaddr;

	/* Initialize the messages */
	memset(&rstatemsg, 0, sizeof(rstatemsg));
	strcpy(rstatemsg.devname, wlandev->name);
	rstatemsg.msgcode = DIDmsg_p2req_ramdl_state;
	rstatemsg.msglen = sizeof(rstatemsg);
	rstatemsg.enable.did = DIDmsg_p2req_ramdl_state_enable;
	rstatemsg.exeaddr.did = DIDmsg_p2req_ramdl_state_exeaddr;
	rstatemsg.resultcode.did = DIDmsg_p2req_ramdl_state_resultcode;
	rstatemsg.enable.status = P80211ENUM_msgitem_status_data_ok;
	rstatemsg.exeaddr.status = P80211ENUM_msgitem_status_data_ok;
	rstatemsg.resultcode.status = P80211ENUM_msgitem_status_no_value;
	rstatemsg.enable.len = sizeof(u32);
	rstatemsg.exeaddr.len = sizeof(u32);
	rstatemsg.resultcode.len = sizeof(u32);

	memset(&rwritemsg, 0, sizeof(rwritemsg));
	strcpy(rwritemsg.devname, wlandev->name);
	rwritemsg.msgcode = DIDmsg_p2req_ramdl_write;
	rwritemsg.msglen = sizeof(rwritemsg);
	rwritemsg.addr.did = DIDmsg_p2req_ramdl_write_addr;
	rwritemsg.len.did = DIDmsg_p2req_ramdl_write_len;
	rwritemsg.data.did = DIDmsg_p2req_ramdl_write_data;
	rwritemsg.resultcode.did = DIDmsg_p2req_ramdl_write_resultcode;
	rwritemsg.addr.status = P80211ENUM_msgitem_status_data_ok;
	rwritemsg.len.status = P80211ENUM_msgitem_status_data_ok;
	rwritemsg.data.status = P80211ENUM_msgitem_status_data_ok;
	rwritemsg.resultcode.status = P80211ENUM_msgitem_status_no_value;
	rwritemsg.addr.len = sizeof(u32);
	rwritemsg.len.len = sizeof(u32);
	rwritemsg.data.len = WRITESIZE_MAX;
	rwritemsg.resultcode.len = sizeof(u32);

	/* Send xxx_state(enable) */
	pr_debug("Sending dl_state(enable) message.\n");
	rstatemsg.enable.data = P80211ENUM_truth_true;
	rstatemsg.exeaddr.data = startaddr;

	msgp = (p80211msg_t *) & rstatemsg;
	result = prism2mgmt_ramdl_state(wlandev, msgp);
	if (result) {
		printk(KERN_ERR
		       "writeimage state enable failed w/ result=%d, "
		       "aborting download\n", result);
		return result;
	}
	resultcode = rstatemsg.resultcode.data;
	if (resultcode != P80211ENUM_resultcode_success) {
		printk(KERN_ERR
		       "writeimage()->xxxdl_state msg indicates failure, "
		       "w/ resultcode=%d, aborting download.\n", resultcode);
		return 1;
	}

	/* Now, loop through the data chunks and send WRITESIZE_MAX data */
	for (i = 0; i < nfchunks; i++) {
		nwrites = fchunk[i].len / WRITESIZE_MAX;
		nwrites += (fchunk[i].len % WRITESIZE_MAX) ? 1 : 0;
		curroff = 0;
		for (j = 0; j < nwrites; j++) {
			currlen =
			    (fchunk[i].len - (WRITESIZE_MAX * j)) >
			    WRITESIZE_MAX ? WRITESIZE_MAX : (fchunk[i].len -
							     (WRITESIZE_MAX *
							      j));
			curroff = j * WRITESIZE_MAX;
			currdaddr = fchunk[i].addr + curroff;
			/* Setup the message */
			rwritemsg.addr.data = currdaddr;
			rwritemsg.len.data = currlen;
			memcpy(rwritemsg.data.data,
			       fchunk[i].data + curroff, currlen);

			/* Send flashdl_write(pda) */
			pr_debug
			    ("Sending xxxdl_write message addr=%06x len=%d.\n",
			     currdaddr, currlen);

			msgp = (p80211msg_t *) & rwritemsg;
			result = prism2mgmt_ramdl_write(wlandev, msgp);

			/* Check the results */
			if (result) {
				printk(KERN_ERR
				       "writeimage chunk write failed w/ result=%d, "
				       "aborting download\n", result);
				return result;
			}
			resultcode = rstatemsg.resultcode.data;
			if (resultcode != P80211ENUM_resultcode_success) {
				printk(KERN_ERR
				       "writeimage()->xxxdl_write msg indicates failure, "
				       "w/ resultcode=%d, aborting download.\n",
				       resultcode);
				return 1;
			}

		}
	}

	/* Send xxx_state(disable) */
	pr_debug("Sending dl_state(disable) message.\n");
	rstatemsg.enable.data = P80211ENUM_truth_false;
	rstatemsg.exeaddr.data = 0;

	msgp = (p80211msg_t *) & rstatemsg;
	result = prism2mgmt_ramdl_state(wlandev, msgp);
	if (result) {
		printk(KERN_ERR
		       "writeimage state disable failed w/ result=%d, "
		       "aborting download\n", result);
		return result;
	}
	resultcode = rstatemsg.resultcode.data;
	if (resultcode != P80211ENUM_resultcode_success) {
		printk(KERN_ERR
		       "writeimage()->xxxdl_state msg indicates failure, "
		       "w/ resultcode=%d, aborting download.\n", resultcode);
		return 1;
	}
	return result;
}