int rwl_var_getbuf(void *wl, const char *iovar, void *param, int param_len, void **bufptr) { int len, error; memset((char*)g_rwl_aligned_buf, 0, WLC_IOCTL_MAXLEN); strcpy(g_rwl_aligned_buf, iovar); /* include the null */ len = strlen(iovar) + 1; if (param_len) memcpy(&g_rwl_aligned_buf[len], param, param_len); *bufptr = g_rwl_aligned_buf; /* When user wants to execute local CMD being in remote wifi mode, * rwl_wifi_swap_remote_type fucntion is used to change the remote types. */ rwl_wifi_swap_remote_type(remote_type); error = wl_get(wl, WLC_GET_VAR, &g_rwl_aligned_buf[0], WLC_IOCTL_MAXLEN); /* revert back to the old remote type */ rwl_wifi_swap_remote_type(remote_type); return error; }
/* * Configures local channel for finding server. * Server call this fucntion for getting its current channel, * client uses this fucntion for setting its channel to new channel. */ static int rwl_wifi_config_channel(void *wl, int cmd, int *channel) { int error; channel_info_t ci; /* Get functionality is used only by server */ if (cmd == WLC_GET_CHANNEL) { memset((char*)&ci, 0, sizeof(ci)); if ((error = wl_get(wl, cmd, &ci, sizeof(channel_info_t)))) return error; ci.hw_channel = dtoh32(ci.hw_channel); ci.scan_channel = dtoh32(ci.scan_channel); ci.target_channel = dtoh32(ci.target_channel); if (ci.scan_channel) printf("Scan in progress.\n"); *channel = ci.hw_channel; } if (cmd == WLC_SET_CHANNEL) { /* Set functionality is used by the client */ ci.target_channel = *channel; /* When user wants to execute local CMD being in remote wifi mode, * rwl_wifi_swap_remote_type fucntion is used to change the remote types. */ rwl_wifi_swap_remote_type(remote_type); error = wl_set(wl, cmd, &ci.target_channel, sizeof(int)); /* rever it back to same old remote type */ rwl_wifi_swap_remote_type(remote_type); } return error; }
/* now IOCTL GET commands shall call wlu_get() instead of wl_get() so that the commands * can be batched when needed */ int wlu_get(void *wl, int cmd, void *cmdbuf, int len) { if (cmd_batching_mode) { if (!WL_SEQ_CMDS_GET_IOCTL_FILTER(cmd)) { printf("IOCTL GET command %d is not supported in batching mode\n", cmd); return BCME_UNSUPPORTED; } } return wl_get(wl, cmd, cmdbuf, len); }
/* Verify the wl adapter found. * This is called by dhd_find to check if it supports wl * The reason for checking wl adapter is that we can still send remote dhd commands over * wifi transport. The function is copied from wlu.c. */ int wl_check(void *wl) { int ret; int val = 0; if (!dhd_check (wl)) return 0; /* * If dhd_check() fails then go for a regular wl driver verification */ if ((ret = wl_get(wl, WLC_GET_MAGIC, &val, sizeof(int))) < 0) return ret; if (val != WLC_IOCTL_MAGIC) return BCME_ERROR; if ((ret = wl_get(wl, WLC_GET_VERSION, &val, sizeof(int))) < 0) return ret; if (val > WLC_IOCTL_VERSION) { fprintf(stderr, "Version mismatch, please upgrade\n"); return BCME_ERROR; } return 0; }
/* This function gets the command send by the client from the dongle driver */ int rwl_var_getbuf(void* wl, const char* iovar, void* param, int param_len, void** buf_ptr) { int len; memset(rwl_buf, 0, WLC_IOCTL_MAXLEN); strcpy((char*)rwl_buf, iovar); /* include the null */ len = strlen(iovar) + 1; if (param_len) memcpy(&rwl_buf[len], param, param_len); *buf_ptr = rwl_buf; return wl_get(wl, WLC_GET_VAR, &rwl_buf[0], WLC_IOCTL_MAXLEN); }
int wlmDeviceImageRead(char* byteStream, unsigned int len, WLM_IMAGE_TYPE imageType) { srom_rw_t *srt; cis_rw_t *cish; char buf[WLC_IOCTL_MAXLEN] = {0}; unsigned int numRead = 0; if (byteStream == NULL) { printf("wlmDeviceImageRead: Buffer is invalid!\n"); return FALSE; } if (len > SROM_MAX) { printf("wlmDeviceImageRead: byteStream should be less than %d bytes!\n", SROM_MAX); return FALSE; } if (len & 1) { printf("wlmDeviceImageRead: Invalid byte count %d, must be even\n", len); return FALSE; } switch (imageType) { case WLM_TYPE_SROM: if (len < 2*SROM4_WORDS) { printf("wlmDeviceImageRead: Buffer not large enough!\n"); return FALSE; } srt = (srom_rw_t *)buf; srt->byteoff = 0; srt->nbytes = htod32(2 * SROM4_WORDS); /* strlen("cisdump ") = 9 */ if (wlu_get(irh, WLC_GET_SROM, buf, 9 + (len < SROM_MAX ? len : SROM_MAX)) < 0) { printf("wlmDeviceImageRead: %s\n", wlmLastError()); return FALSE; } memcpy(byteStream, buf + 8, srt->nbytes); numRead = srt->nbytes; break; case WLM_TYPE_OTP: strcpy(buf, "cisdump"); /* strlen("cisdump ") = 9 */ if (wl_get(irh, WLC_GET_VAR, buf, 9 + (len < SROM_MAX ? len : SROM_MAX)) < 0) { printf("wlmDeviceImageRead: %s\n", wlmLastError()); return FALSE; } cish = (cis_rw_t *)buf; cish->source = dtoh32(cish->source); cish->byteoff = dtoh32(cish->byteoff); cish->nbytes = dtoh32(cish->nbytes); if (len < cish->nbytes) { printf("wlmDeviceImageRead: Buffer not large enough!\n"); return FALSE; } memcpy(byteStream, buf + sizeof(cis_rw_t), cish->nbytes); numRead = cish->nbytes; break; case WLM_TYPE_AUTO: numRead = wlmDeviceImageRead(byteStream, len, WLM_TYPE_SROM); if (!numRead) { numRead = wlmDeviceImageRead(byteStream, len, WLM_TYPE_OTP); printf("wlmDeviceImageRead: %s\n", wlmLastError()); return FALSE; } break; default: printf("wlmDeviceImageRead: Invalid image type!\n"); return FALSE; } return numRead; }
/* dhd_get/dhd_set is called by several functions in dhdu.c. This used to call dhd_ioctl * directly. However now we need to execute the dhd commands remotely. * So we make use of wl pipes to execute this. * wl_get or wl_set functions also check if it is a local command hence they in turn * call dhd_ioctl if required. Name wl_get/wl_set is retained because these functions are * also called by wlu_pipe.c wlu_client_shared.c */ int dhd_get(void *dhd, int cmd, void *buf, int len) { return wl_get(dhd, cmd, buf, len); }