/* * \brief execute a private command FROM KERNEL SPACE * * \context EXTERNAL (not driver) * * \param tPrivCmd command to execute * NOTE: the in/out buffers of the command MUST be in KERNEL space * * \return TI_OK upon success; TI_NOK upon failure */ static int KExecPrivCmd(TI_HANDLE hWlanDrvIf, ti_private_cmd_t tPrivCmd) { int rc; TWlanDrvIfObj *this = (TWlanDrvIfObj *) hWlanDrvIf; /* if command is async, or has output buffer - set as a GET command * (commands from user-space have this field set in IPC_STA_Private_Send()) */ tPrivCmd.flags = (tPrivCmd.out_buffer || IS_PARAM_ASYNC(tPrivCmd.cmd)) ? PRIVATE_CMD_GET_FLAG : PRIVATE_CMD_SET_FLAG; /* Call the Cmd module with the given user paramters */ rc = cmdHndlr_InsertCommand(this->tCommon.hCmdHndlr, SIOCIWFIRSTPRIV, 0, NULL /* not used by SIOCIWFIRSTPRIV */, 0, NULL /* not used by SIOCIWFIRSTPRIV */, 0, (TI_UINT32*)&tPrivCmd, NULL, CMD_WEXT_CMD_E); return rc; }
int wlanDrvWext_Handler (struct net_device *dev, struct iw_request_info *info, void *iw_req, void *extra) { int rc; TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev); ti_private_cmd_t my_command; struct iw_mlme mlme; struct iw_scan_req scanreq; void *copy_to_buf=NULL, *param3=NULL; os_memoryZero(drv, &my_command, sizeof(ti_private_cmd_t)); os_memoryZero(drv, &mlme, sizeof(struct iw_mlme)); os_memoryZero(drv, &scanreq, sizeof(struct iw_scan_req)); switch (info->cmd) { case SIOCIWFIRSTPRIV: { void *copy_from_buf; if (os_memoryCopyFromUser(drv, &my_command, ((union iwreq_data *)iw_req)->data.pointer, sizeof(ti_private_cmd_t))) { os_printf ("wlanDrvWext_Handler() os_memoryCopyFromUser FAILED !!!\n"); return TI_NOK; } if (IS_PARAM_FOR_MODULE(my_command.cmd, DRIVER_MODULE_PARAM)) { /* If it's a driver level command, handle it here and exit */ switch (my_command.cmd) { case DRIVER_INIT_PARAM: return wlanDrvIf_LoadFiles (drv, my_command.in_buffer); case DRIVER_START_PARAM: return wlanDrvIf_Open (dev); case DRIVER_STOP_PARAM: return wlanDrvIf_Stop (dev); case DRIVER_STATUS_PARAM: *(TI_UINT32 *)my_command.out_buffer = (drv->tCommon.eDriverState == DRV_STATE_RUNNING) ? TI_TRUE : TI_FALSE; return TI_OK; } } /* if we are still here handle a normal private command*/ if ((my_command.in_buffer) && (my_command.in_buffer_len)) { copy_from_buf = my_command.in_buffer; my_command.in_buffer = os_memoryAlloc(drv, my_command.in_buffer_len); if (os_memoryCopyFromUser(drv, my_command.in_buffer, copy_from_buf, my_command.in_buffer_len)) { os_printf ("wlanDrvWext_Handler() os_memoryCopyFromUser 1 FAILED !!!\n"); return TI_NOK; } } if ((my_command.out_buffer) && (my_command.out_buffer_len)) { copy_to_buf = my_command.out_buffer; my_command.out_buffer = os_memoryAlloc(drv, my_command.out_buffer_len); } param3 = &my_command; } break; case SIOCSIWMLME: { os_memoryCopyFromUser(drv, &mlme, ((union iwreq_data *)iw_req)->data.pointer, sizeof(struct iw_mlme)); param3 = &mlme; } break; case SIOCSIWSCAN: { if (((union iwreq_data *)iw_req)->data.pointer) { os_memoryCopyFromUser(drv, &scanreq, ((union iwreq_data *)iw_req)->data.pointer, sizeof(struct iw_scan_req)); param3 = &scanreq; } } break; case SIOCSIWGENIE: { TI_UINT16 ie_length = ((union iwreq_data *)iw_req)->data.length; TI_UINT8 *ie_content = ((union iwreq_data *)iw_req)->data.pointer; if ((ie_length == 0) && (ie_content == NULL)) { /* Do nothing, deleting the IE */ } else if ((ie_content != NULL) && (ie_length <= RSN_MAX_GENERIC_IE_LENGTH) && (ie_length > 0)) { /* One IE cannot be larger than RSN_MAX_GENERIC_IE_LENGTH bytes */ my_command.in_buffer = os_memoryAlloc(drv, ie_length); os_memoryCopyFromUser(drv, my_command.in_buffer, ie_content, ie_length ); param3 = my_command.in_buffer; } else { return TI_NOK; } } break; } /* If the friver is not running, return NOK */ if (drv->tCommon.eDriverState != DRV_STATE_RUNNING) { return TI_NOK; } /* Call the Cmd module with the given user paramters */ rc = (cmdHndlr_InsertCommand (drv->tCommon.hCmdHndlr, info->cmd, info->flags, iw_req, 0, extra, 0, param3, NULL)); /* Here we are after the command was completed */ if (my_command.in_buffer) { os_memoryFree (drv, my_command.in_buffer, my_command.in_buffer_len); } if (my_command.out_buffer) { if (os_memoryCopyToUser(drv, copy_to_buf, my_command.out_buffer, my_command.out_buffer_len)) { os_printf ("wlanDrvWext_Handler() os_memoryCopyToUser FAILED !!!\n"); rc = TI_NOK; } os_memoryFree (drv, my_command.out_buffer, my_command.out_buffer_len); } return rc; }