/*---------------------------------------------------------------- * 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; }
/*---------------------------------------------------------------- * 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; }
/*---------------------------------------------------------------- * 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; }