// SPDX-License-Identifier: GPL-2.0
/******************************************************************************
*
* Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
*
******************************************************************************/
#define _RTW_CMD_C_
#include <osdep_service.h>
#include <drv_types.h>
#include <recv_osdep.h>
#include <mlme_osdep.h>
#include <rtw_mlme_ext.h>
/*
* Caller and the rtw_cmd_thread can protect cmd_q by spin_lock.
* No irqsave is necessary.
*/
int rtw_init_cmd_priv(struct cmd_priv *pcmdpriv)
{
init_completion(&pcmdpriv->cmd_queue_comp);
init_completion(&pcmdpriv->terminate_cmdthread_comp);
_rtw_init_queue(&pcmdpriv->cmd_queue);
return _SUCCESS;
}
/*
* Calling Context:
*
* rtw_enqueue_cmd can only be called between kernel thread,
* since only spin_lock is used.
*
* ISR/Call-Back functions can't call this sub-function.
*/
static int _rtw_enqueue_cmd(struct __queue *queue, struct cmd_obj *obj)
{
unsigned long irqL;
if (!obj)
goto exit;
spin_lock_irqsave(&queue->lock, irqL);
list_add_tail(&obj->list, &queue->queue);
spin_unlock_irqrestore(&queue->lock, irqL);
exit:
return _SUCCESS;
}
struct cmd_obj *rtw_dequeue_cmd(struct __queue *queue)
{
unsigned long irqL;
struct cmd_obj *obj;
spin_lock_irqsave(&queue->lock, irqL);
obj = list_first_entry_or_null(&queue->queue, struct cmd_obj, list);
if (obj)
list_del_init(&obj->list);
spin_unlock_irqrestore(&queue->lock, irqL);
return obj;
}
static int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
{
u8 bAllow = false; /* set to true to allow enqueuing cmd when hw_init_completed is false */
/* To decide allow or not */
if ((pcmdpriv->padapter->pwrctrlpriv.bHWPwrPindetect) &&
(!pcmdpriv->padapter->registrypriv.usbss_enable)) {
if (cmd_obj->cmdcode == _Set_Drv_Extra_CMD_) {
struct drvextra_cmd_parm *pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)cmd_obj->parmbuf;
if (pdrvextra_cmd_parm->ec_id == POWER_SAVING_CTRL_WK_CID)
bAllow = true;
}
}
if (cmd_obj->cmdcode == _SetChannelPlan_CMD_)
bAllow = true;
if ((!pcmdpriv->padapter->hw_init_completed && !bAllow) ||
!pcmdpriv->cmdthd_running) /* com_thread not running */
return _FAIL;
return _SUCCESS;
}
u32 rtw_enqueue_cmd(