mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-14 08:36:12 -04:00
Merge "qcacmn: Fix deadlock in dp_delete_pending_vdev() API"
This commit is contained in:
commit
a647143904
2 changed files with 188 additions and 28 deletions
|
|
@ -4648,40 +4648,44 @@ static void dp_reset_and_release_peer_mem(struct dp_soc *soc,
|
|||
qdf_mem_free(peer);
|
||||
}
|
||||
|
||||
static void dp_delete_pending_vdev(struct dp_pdev *pdev, uint32_t vdev_id)
|
||||
/**
|
||||
* dp_delete_pending_vdev() - check and process vdev delete
|
||||
* @pdev: DP specific pdev pointer
|
||||
* @vdev: DP specific vdev pointer
|
||||
* @vdev_id: vdev id corresponding to vdev
|
||||
*
|
||||
* This API does following:
|
||||
* 1) It releases tx flow pools buffers as vdev is
|
||||
* going down and no peers are associated.
|
||||
* 2) It also detaches vdev before cleaning vdev (struct dp_vdev) memory
|
||||
*/
|
||||
static void dp_delete_pending_vdev(struct dp_pdev *pdev, struct dp_vdev *vdev,
|
||||
uint8_t vdev_id)
|
||||
{
|
||||
struct dp_vdev *vdev = NULL;
|
||||
ol_txrx_vdev_delete_cb vdev_delete_cb = NULL;
|
||||
void *vdev_delete_context = NULL;
|
||||
|
||||
qdf_spin_lock_bh(&pdev->vdev_list_lock);
|
||||
TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
|
||||
if (vdev->vdev_id == vdev_id)
|
||||
break;
|
||||
}
|
||||
if (!vdev) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"vdev is NULL");
|
||||
} else if (vdev->delete.pending) {
|
||||
vdev_delete_cb = vdev->delete.callback;
|
||||
vdev_delete_context = vdev->delete.context;
|
||||
vdev_delete_cb = vdev->delete.callback;
|
||||
vdev_delete_context = vdev->delete.context;
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH,
|
||||
FL("deleting vdev object %pK (%pM)- its last peer is done"),
|
||||
vdev, vdev->mac_addr.raw);
|
||||
/* all peers are gone, go ahead and delete it */
|
||||
dp_tx_flow_pool_unmap_handler(pdev, vdev_id,
|
||||
FLOW_TYPE_VDEV, vdev_id);
|
||||
dp_tx_vdev_detach(vdev);
|
||||
TAILQ_REMOVE(&pdev->vdev_list, vdev, vdev_list_elem);
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH,
|
||||
FL("deleting vdev object %pK (%pM)"),
|
||||
vdev, vdev->mac_addr.raw);
|
||||
qdf_mem_free(vdev);
|
||||
vdev = NULL;
|
||||
}
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH,
|
||||
FL("deleting vdev object %pK (%pM)- its last peer is done"),
|
||||
vdev, vdev->mac_addr.raw);
|
||||
/* all peers are gone, go ahead and delete it */
|
||||
dp_tx_flow_pool_unmap_handler(pdev, vdev_id,
|
||||
FLOW_TYPE_VDEV, vdev_id);
|
||||
dp_tx_vdev_detach(vdev);
|
||||
|
||||
qdf_spin_lock_bh(&pdev->vdev_list_lock);
|
||||
TAILQ_REMOVE(&pdev->vdev_list, vdev, vdev_list_elem);
|
||||
qdf_spin_unlock_bh(&pdev->vdev_list_lock);
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH,
|
||||
FL("deleting vdev object %pK (%pM)"),
|
||||
vdev, vdev->mac_addr.raw);
|
||||
qdf_mem_free(vdev);
|
||||
vdev = NULL;
|
||||
|
||||
if (vdev_delete_cb)
|
||||
vdev_delete_cb(vdev_delete_context);
|
||||
}
|
||||
|
|
@ -4701,6 +4705,7 @@ void dp_peer_unref_delete(void *peer_handle)
|
|||
int found = 0;
|
||||
uint16_t peer_id;
|
||||
uint16_t vdev_id;
|
||||
bool delete_vdev;
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
|
||||
"%s: peer %pK ref_cnt(before decrement): %d\n", __func__,
|
||||
|
|
@ -4762,6 +4767,11 @@ void dp_peer_unref_delete(void *peer_handle)
|
|||
|
||||
/* check whether the parent vdev has no peers left */
|
||||
if (TAILQ_EMPTY(&vdev->peer_list)) {
|
||||
/*
|
||||
* capture vdev delete pending flag's status
|
||||
* while holding peer_ref_mutex lock
|
||||
*/
|
||||
delete_vdev = vdev->delete.pending;
|
||||
/*
|
||||
* Now that there are no references to the peer, we can
|
||||
* release the peer reference lock.
|
||||
|
|
@ -4771,7 +4781,8 @@ void dp_peer_unref_delete(void *peer_handle)
|
|||
* Check if the parent vdev was waiting for its peers
|
||||
* to be deleted, in order for it to be deleted too.
|
||||
*/
|
||||
dp_delete_pending_vdev(pdev, vdev_id);
|
||||
if (delete_vdev)
|
||||
dp_delete_pending_vdev(pdev, vdev, vdev_id);
|
||||
} else {
|
||||
qdf_spin_unlock_bh(&soc->peer_ref_mutex);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6116,10 +6116,159 @@ enum qca_wlan_vendor_attr_wifi_test_config {
|
|||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP = 22,
|
||||
|
||||
/* Nested attribute values required to setup the TWT session.
|
||||
* enum qca_wlan_vendor_attr_twt_setup provides the necessary
|
||||
* information to set up the session. It contains broadcast flags,
|
||||
* set_up flags, trigger value, flow type, flow ID, wake interval
|
||||
* exponent, protection, target wake time, wake duration, wake interval
|
||||
* mantissa. These nested attributes are used to setup a host triggered
|
||||
* TWT session.
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP = 23,
|
||||
|
||||
/* This nested attribute is used to terminate the current TWT session.
|
||||
* It does not currently carry any attributes.
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE = 24,
|
||||
|
||||
/* This nested attribute is used to suspend the current TWT session.
|
||||
* It does not currently carry any attributes.
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SUSPEND = 25,
|
||||
|
||||
/* Nested attribute values to indicate the request for resume.
|
||||
* This attribute is used to resume the TWT session.
|
||||
* enum qca_wlan_vendor_attr_twt_resume provides the necessary
|
||||
* parameters required to resume the TWT session.
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_RESUME = 26,
|
||||
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX =
|
||||
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_AFTER_LAST - 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_wlan_vendor_attr_twt_setup: Represents attributes for
|
||||
* TWT (Target Wake Time) setup request. These attributes are sent as part of
|
||||
* %QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP and
|
||||
* %QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST: Flag attribute.
|
||||
* Disable (flag attribute not present) - Individual TWT
|
||||
* Enable (flag attribute present) - Broadcast TWT.
|
||||
* Individual means the session is between the STA and the AP.
|
||||
* This session is established using a separate negotiation between
|
||||
* STA and AP.
|
||||
* Broadcast means the session is across multiple STAs and an AP. The
|
||||
* configuration parameters are announced in Beacon frames by the AP.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE: Required (u8).
|
||||
* Unsigned 8-bit qca_wlan_vendor_twt_setup_req_type to
|
||||
* specify the TWT request type
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER: Flag attribute
|
||||
* Enable (flag attribute present) - TWT with trigger support.
|
||||
* Disable (flag attribute not present) - TWT without trigger support.
|
||||
* Trigger means the AP will send the trigger frame to allow STA to send data.
|
||||
* Without trigger, the STA will wait for the MU EDCA timer before
|
||||
* transmitting the data.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE: Required (u8)
|
||||
* 0 - Announced TWT - In this mode, STA may skip few service periods to
|
||||
* save more power. If STA wants to wake up, it will send a PS-POLL/QoS
|
||||
* NULL frame to AP.
|
||||
* 1 - Unannounced TWT - The STA will wakeup during every SP.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID: Optional (u8)
|
||||
* Flow ID is the unique identifier for each TWT session.
|
||||
* Currently this is not required and dialog ID will be set to zero.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP: Required (u8)
|
||||
* This attribute (exp) is used along with the mantissa to derive the
|
||||
* wake interval using the following formula:
|
||||
* pow(2,exp) = wake_intvl_us/wake_intvl_mantis
|
||||
* Wake interval is the interval between 2 successive SP.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION: Flag attribute
|
||||
* Enable (flag attribute present) - Protection required.
|
||||
* Disable (flag attribute not present) - Protection not required.
|
||||
* If protection is enabled, then the AP will use protection
|
||||
* mechanism using RTS/CTS to self to reserve the airtime.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME: Optional (u32)
|
||||
* This attribute is used as the SP offset which is the offset from
|
||||
* TSF after which the wake happens. The units are in microseconds. If
|
||||
* this attribute is not provided, then the value will be set to zero.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION: Required (u32)
|
||||
* This is the duration of the service period. The units are in TU.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA: Required (u32)
|
||||
* This attribute is used to configure wake interval mantissa.
|
||||
* The units are in TU.
|
||||
*/
|
||||
enum qca_wlan_vendor_attr_twt_setup {
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_INVALID = 0,
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST = 1,
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE = 2,
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER = 3,
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE = 4,
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID = 5,
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP = 6,
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION = 7,
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME = 8,
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION = 9,
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA = 10,
|
||||
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX =
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_AFTER_LAST - 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_wlan_vendor_attr_twt_resume: Represents attributes for
|
||||
* TWT (Target Wake Time) resume request. These attributes are sent as part of
|
||||
* %QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_RESUME and
|
||||
* %QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT: Optional (u8)
|
||||
* This attribute is used as the SP offset which is the offset from
|
||||
* TSF after which the wake happens. The units are in microseconds.
|
||||
* If this attribute is not provided, then the value will be set to
|
||||
* zero.
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT_SIZE: Required (u32)
|
||||
* This attribute represents the next TWT subfield size.
|
||||
*/
|
||||
enum qca_wlan_vendor_attr_twt_resume {
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_RESUME_INVALID = 0,
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT = 1,
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT_SIZE = 2,
|
||||
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_RESUME_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_RESUME_MAX =
|
||||
QCA_WLAN_VENDOR_ATTR_TWT_RESUME_AFTER_LAST - 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_wlan_vendor_twt_setup_req_type - Required (u8)
|
||||
* Represents the setup type being requested for TWT.
|
||||
* @QCA_WLAN_VENDOR_TWT_SETUP_REQUEST: STA is not specifying all the TWT
|
||||
* parameters but relying on AP to fill the parameters during the negotiation.
|
||||
* @QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST: STA will provide all the suggested
|
||||
* values which the AP may accept or AP may provide alternative parameters
|
||||
* which the STA may accept.
|
||||
* @QCA_WLAN_VENDOR_TWT_SETUP_DEMAND: STA is not willing to accept any
|
||||
* alternate parameters than the requested ones.
|
||||
*/
|
||||
enum qca_wlan_vendor_twt_setup_req_type {
|
||||
QCA_WLAN_VENDOR_TWT_SETUP_REQUEST = 1,
|
||||
QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST = 2,
|
||||
QCA_WLAN_VENDOR_TWT_SETUP_DEMAND = 3,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue