/* * This function initializes the firmware. * * The following operations are performed sequentially - * - Allocate adapter structure * - Initialize the adapter structure * - Initialize the private structure * - Add BSS priority tables to the adapter structure * - For each interface, send the init commands to firmware * - Send the first command in command pending queue, if available */ int mwifiex_init_fw(struct mwifiex_adapter *adapter) { int ret; struct mwifiex_private *priv; u8 i, first_sta = true; int is_cmd_pend_q_empty; unsigned long flags; adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING; /* Allocate memory for member of adapter structure */ ret = mwifiex_allocate_adapter(adapter); if (ret) return -1; /* Initialize adapter structure */ mwifiex_init_adapter(adapter); for (i = 0; i < adapter->priv_num; i++) { if (adapter->priv[i]) { priv = adapter->priv[i]; /* Initialize private structure */ ret = mwifiex_init_priv(priv); if (ret) return -1; } } if (adapter->if_ops.init_fw_port) { if (adapter->if_ops.init_fw_port(adapter)) return -1; } for (i = 0; i < adapter->priv_num; i++) { if (adapter->priv[i]) { ret = mwifiex_sta_init_cmd(adapter->priv[i], first_sta); if (ret == -1) return -1; first_sta = false; } } spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_q); spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); if (!is_cmd_pend_q_empty) { /* Send the first command in queue and return */ if (mwifiex_main_process(adapter) != -1) ret = -EINPROGRESS; } else { adapter->hw_status = MWIFIEX_HW_STATUS_READY; } return ret; }
/* * This is the main work queue function. * * It handles the main process, which in turn handles the complete * driver operations. */ static void mwifiex_main_work_queue(struct work_struct *work) { struct mwifiex_adapter *adapter = container_of(work, struct mwifiex_adapter, main_work); if (adapter->surprise_removed) return; mwifiex_main_process(adapter); }
/* * SDIO interrupt handler. * * This function reads the interrupt status from firmware and handles * the interrupt in current thread (ksdioirqd) right away. */ static void mwifiex_sdio_interrupt(struct sdio_func *func) { struct mwifiex_adapter *adapter; struct sdio_mmc_card *card; card = sdio_get_drvdata(func); if (!card || !card->adapter) { pr_debug("int: func=%p card=%p adapter=%p\n", func, card, card ? card->adapter : NULL); return; } adapter = card->adapter; if (adapter->surprise_removed) return; if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP) adapter->ps_state = PS_STATE_AWAKE; mwifiex_interrupt_status(adapter); mwifiex_main_process(adapter); }