|
@@ -2025,6 +2025,8 @@ ol_txrx_vdev_attach(struct cdp_pdev *ppdev,
|
|
|
vdev->tx_fl_hwm = 0;
|
|
|
vdev->rx = NULL;
|
|
|
vdev->wait_on_peer_id = OL_TXRX_INVALID_LOCAL_PEER_ID;
|
|
|
+ qdf_mem_zero(&vdev->last_peer_mac_addr,
|
|
|
+ sizeof(union ol_txrx_align_mac_addr_t));
|
|
|
qdf_spinlock_create(&vdev->flow_control_lock);
|
|
|
vdev->osif_flow_control_cb = NULL;
|
|
|
vdev->osif_fc_ctx = NULL;
|
|
@@ -2379,6 +2381,8 @@ ol_txrx_peer_attach(struct cdp_vdev *pvdev, uint8_t *peer_mac_addr)
|
|
|
bool wait_on_deletion = false;
|
|
|
unsigned long rc;
|
|
|
struct ol_txrx_pdev_t *pdev;
|
|
|
+ bool cmp_wait_mac = false;
|
|
|
+ uint8_t zero_mac_addr[QDF_MAC_ADDR_SIZE] = { 0, 0, 0, 0, 0, 0 };
|
|
|
|
|
|
/* preconditions */
|
|
|
TXRX_ASSERT2(vdev);
|
|
@@ -2387,6 +2391,10 @@ ol_txrx_peer_attach(struct cdp_vdev *pvdev, uint8_t *peer_mac_addr)
|
|
|
pdev = vdev->pdev;
|
|
|
TXRX_ASSERT2(pdev);
|
|
|
|
|
|
+ if (qdf_mem_cmp(&zero_mac_addr, &vdev->last_peer_mac_addr,
|
|
|
+ QDF_MAC_ADDR_SIZE))
|
|
|
+ cmp_wait_mac = true;
|
|
|
+
|
|
|
qdf_spin_lock_bh(&pdev->peer_ref_mutex);
|
|
|
/* check for duplicate exsisting peer */
|
|
|
TAILQ_FOREACH(temp_peer, &vdev->peer_list, peer_list_elem) {
|
|
@@ -2402,14 +2410,40 @@ ol_txrx_peer_attach(struct cdp_vdev *pvdev, uint8_t *peer_mac_addr)
|
|
|
vdev->wait_on_peer_id = temp_peer->local_id;
|
|
|
qdf_event_reset(&vdev->wait_delete_comp);
|
|
|
wait_on_deletion = true;
|
|
|
+ break;
|
|
|
} else {
|
|
|
qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
|
|
|
return NULL;
|
|
|
}
|
|
|
}
|
|
|
+ if (cmp_wait_mac && !ol_txrx_peer_find_mac_addr_cmp(
|
|
|
+ &temp_peer->mac_addr,
|
|
|
+ &vdev->last_peer_mac_addr)) {
|
|
|
+ ol_txrx_info(
|
|
|
+ "vdev_id %d (%02x:%02x:%02x:%02x:%02x:%02x) old peer exsist.\n",
|
|
|
+ vdev->vdev_id,
|
|
|
+ vdev->last_peer_mac_addr.raw[0],
|
|
|
+ vdev->last_peer_mac_addr.raw[1],
|
|
|
+ vdev->last_peer_mac_addr.raw[2],
|
|
|
+ vdev->last_peer_mac_addr.raw[3],
|
|
|
+ vdev->last_peer_mac_addr.raw[4],
|
|
|
+ vdev->last_peer_mac_addr.raw[5]);
|
|
|
+ if (qdf_atomic_read(&temp_peer->delete_in_progress)) {
|
|
|
+ vdev->wait_on_peer_id = temp_peer->local_id;
|
|
|
+ qdf_event_reset(&vdev->wait_delete_comp);
|
|
|
+ wait_on_deletion = true;
|
|
|
+ break;
|
|
|
+ } else {
|
|
|
+ qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
|
|
|
+ ol_txrx_err("peer not found");
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
|
|
|
|
|
|
+ qdf_mem_zero(&vdev->last_peer_mac_addr,
|
|
|
+ sizeof(union ol_txrx_align_mac_addr_t));
|
|
|
if (wait_on_deletion) {
|
|
|
/* wait for peer deletion */
|
|
|
rc = qdf_wait_single_event(&vdev->wait_delete_comp,
|
|
@@ -3387,6 +3421,12 @@ static void ol_txrx_peer_detach(void *ppeer)
|
|
|
*/
|
|
|
qdf_atomic_set(&peer->delete_in_progress, 1);
|
|
|
|
|
|
+ if (vdev->opmode == wlan_op_mode_sta) {
|
|
|
+ qdf_mem_copy(&peer->vdev->last_peer_mac_addr,
|
|
|
+ &peer->mac_addr,
|
|
|
+ sizeof(union ol_txrx_align_mac_addr_t));
|
|
|
+ }
|
|
|
+
|
|
|
/*
|
|
|
* Create a timer to track unmap events when the sta peer gets deleted.
|
|
|
*/
|