Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/next/external/cache/sources/wl/dhd/ucode_download.c
Views: 3960
/*1* Ucode download related utility functions2*3* $Copyright Open Broadcom Corporation$4*5* $Id: ucode_download.c 297277 2011-11-18 14:10:09Z $6*/78#include <unistd.h>9#include <errno.h>10#include <trxhdr.h>11#include <bcmendian.h>12#include <wlu_common.h>1314#define DEVPRESENT_DELAY 10000 /* in microsecs */15#define DEVPRESENT_RETRIES 1001617extern int wl_validatedev(void *dev_handle);1819int20dload_generic_data(void *wl, uint16 dload_type, unsigned char *dload_buf, int len)21{22struct wl_dload_data *dload_ptr = (struct wl_dload_data *)dload_buf;23int err = 0;24int actual_data_offset;25char *buf;2627actual_data_offset = OFFSETOF(struct wl_dload_data, data);28dload_ptr->flag = (DLOAD_HANDLER_VER << DLOAD_FLAG_VER_SHIFT);29dload_ptr->flag |= DL_CRC_NOT_INUSE;30dload_ptr->dload_type = dload_type;31dload_ptr->len = htod32(len - actual_data_offset);32dload_ptr->crc = 0;3334len = len + 8 - (len%8);3536buf = malloc(WLC_IOCTL_MEDLEN);37if (buf) {38bzero(buf, WLC_IOCTL_MEDLEN);39err = wlu_iovar_setbuf(wl, "generic_dload", dload_buf, len, buf,40WLC_IOCTL_MEDLEN);41}42free(buf);43return err;44}4546int47dload_ucode_part(void *wl, uint8 ucode_type, uint32 datalen, unsigned char *org_buf)48{49int num_chunks, chunk_len, cumulative_len = 0;50int size2alloc, ucode_chunk_len = 0;51unsigned char *new_buf;52struct wl_ucode_info *ucode_ptr;53int err = 0, ucode_offset, chunk_offset;5455ucode_offset = OFFSETOF(wl_dload_data_t, data);56chunk_offset = OFFSETOF(wl_ucode_info_t, data_chunk);5758err = wlu_iovar_getint(wl, "ucdload_chunk_len",59&ucode_chunk_len);60if (err) {61printf("err in getting ucode chunk len, exiting\n");62return err;63}6465num_chunks = datalen/ucode_chunk_len;66if (datalen % ucode_chunk_len != 0)67num_chunks++;68size2alloc = ucode_offset + chunk_offset + ucode_chunk_len;6970/* single chunk buffer */71new_buf = (unsigned char *)malloc(size2alloc);72memset(new_buf, 0, size2alloc);73ucode_ptr = (struct wl_ucode_info *)((uint8 *)new_buf+ucode_offset);74ucode_ptr->ucode_type = ucode_type;75ucode_ptr->num_chunks = num_chunks;76do {77if (datalen >= ucode_chunk_len)78chunk_len = ucode_chunk_len;79else80chunk_len = datalen;81memset(new_buf+ucode_offset+chunk_offset, 0, size2alloc-ucode_offset-chunk_offset);82ucode_ptr->chunk_len = htod32(chunk_len);83ucode_ptr->chunk_num++;84memcpy(&ucode_ptr->data_chunk[0], org_buf + cumulative_len, chunk_len);85cumulative_len += chunk_len;86err = dload_generic_data(wl, DL_TYPE_UCODE, new_buf, size2alloc);87if (err) {88printf("error while writing %s to the memory\n",89(ucode_type == UCODE_FW)? "ucode" : "initvals");90break;91}92datalen = datalen - chunk_len;93} while (datalen > 0);94free(new_buf);9596return err;97}9899static int100check_ucode_file(unsigned char *headers)101{102struct trx_header *trx;103int actual_data_len = -1;104105/* Extract trx header */106trx = (struct trx_header *)headers;107if (trx->magic != TRX_MAGIC) {108printf("Error: trx bad hdr\n");109goto err;110}111actual_data_len = ROUNDUP(trx->offsets[0], 4) + ROUNDUP(trx->offsets[1], 4);112err:113return actual_data_len;114}115116int117proc_ucode_download(char* fw_filename, void *dev_handle)118{119FILE *fp = NULL;120int ret = 0, loopcnt = 0;121struct trx_header main_trx_hdr, *ucode_trx_hdr;122uint32 maintrx_hdr_len, tmp_len;123uint32 fw_size, second_offset, ucode_trx_offset;124long ucode_pos;125unsigned long ucode_info_len = 0, status;126unsigned char *ucodetrx_buf, *initvals_ptr;127int ucode_len, initvals_len;128int ucdload_status = 0;129int is_devpresent;130131/* read the file and push blocks down to memory */132if ((fp = fopen(fw_filename, "rb")) == NULL) {133fprintf(stderr, "%s: unable to open %s: %s\n",134__FUNCTION__, fw_filename, strerror(errno));135ret = -1;136goto exit;137}138139maintrx_hdr_len = sizeof(struct trx_header);140tmp_len = fread(&main_trx_hdr, sizeof(uint8), maintrx_hdr_len, fp);141142if (tmp_len == maintrx_hdr_len) {143if (main_trx_hdr.magic == TRX_MAGIC) {144fw_size = main_trx_hdr.offsets[0];145second_offset = main_trx_hdr.offsets[2];146147if (second_offset == maintrx_hdr_len) {148second_offset = 0;149}150ucode_trx_offset = maintrx_hdr_len +151ROUNDUP(fw_size, 4) + ROUNDUP(second_offset, 4);152ucode_pos = fseek(fp, ucode_trx_offset, SEEK_SET);153BCM_REFERENCE(ucode_pos);154155if ((ucode_trx_hdr = malloc(sizeof(struct trx_header)))156== NULL) {157printf("Unable to allocate %d bytes!\n", maintrx_hdr_len);158ret = -ENOMEM;159goto exit;160}161162/* Read ONLY the firmware-file-header into the new_buffer */163status = fread(ucode_trx_hdr, sizeof(uint8),164maintrx_hdr_len, fp);165if (status < sizeof(struct trx_header)) {166printf("Short read in hdr read for %s!\n", fw_filename);167ret = -EINVAL;168goto exit;169}170171if ((ucode_info_len = check_ucode_file(172(unsigned char *)ucode_trx_hdr)) <= 0) {173printf("not a valid ucode.trx\n");174ret = -1;175goto exit;176}177178ucodetrx_buf = (unsigned char *)malloc(ucode_info_len *179sizeof(char));180tmp_len = fread(ucodetrx_buf, sizeof(uint8),181ucode_info_len, fp);182if (ucode_info_len > 0) {183ucode_len = ucode_trx_hdr->offsets[0];184initvals_ptr = ucodetrx_buf +185ROUNDUP(ucode_trx_hdr->offsets[0], 4);186initvals_len = ucode_trx_hdr->offsets[1];187}188free(ucode_trx_hdr);189190init_cmd_batchingmode();191do {192is_devpresent = wl_validatedev(dev_handle);193loopcnt++;194/* in USB after dongle fw starts running wl interface195might not appear in the list of interfaces immediately, hence try196after some delay of 10ms197*/198if (!is_devpresent)199usleep(DEVPRESENT_DELAY);200else {201/* below iovar to verify if the for foundout202interface has already ucode been downloaded203*/204ret = wlu_iovar_getint(dev_handle, "ucdload_status",205&ucdload_status);206if (ret) {207printf("err in ucdload_status, exiting\n");208goto exit;209}210if (ucdload_status) {211/* Number of 'wl' interfaces to skip212in the next round of going thru wl_find213*/214printf("ucode is already downloaded\n");215}216}217/* usb seems to take some time to come up, hence the218loop value of 100219*/220} while (loopcnt < DEVPRESENT_RETRIES && !is_devpresent);221222if (loopcnt < DEVPRESENT_RETRIES) {223/* download the ucode fw */224ret = dload_ucode_part(dev_handle, UCODE_FW, ucode_len,225ucodetrx_buf);226if (ret) {227printf("error while downloading ucode, exiting\n");228goto exit;229}230/* download the initvals to the dongle */231ret = dload_ucode_part(dev_handle, INIT_VALS,232initvals_len, initvals_ptr);233234if (ret) {235printf("error while downloading initvals, exiting\n");236goto exit;237}238}239else {240printf("wl device is not present\n");241}242free(ucodetrx_buf);243}244}245246exit:247if (fp)248fclose(fp);249return ret;250}251252253