qcacmn: MLO Mcast Support for ML-Reconfig
1.Add check in Tx completion path to handle mcast packets from all ML partner vdevs 2.Handle cases where a ML mcast vdev can be deleted and started as NON-ML vdev and viceversa by adding reset ML mcast conf. 3.Optimized Register configurations for Mcast at Init/Delete and Start/Stop AP Change-Id: Iab8a5a081e2e0377509574d362754d32c5b83df2 CRs-Fixed: 3350350
This commit is contained in:

committed by
Madan Koyyalamudi

parent
3bae1f975c
commit
069ca18f58
@@ -1462,6 +1462,7 @@ enum cdp_pdev_bpr_param {
|
|||||||
* @CDP_SKIP_BAR_UPDATE_AP: enable/disable bar
|
* @CDP_SKIP_BAR_UPDATE_AP: enable/disable bar
|
||||||
* @CDP_UPDATE_DSCP_TO_TID_MAP: Set DSCP to TID map id
|
* @CDP_UPDATE_DSCP_TO_TID_MAP: Set DSCP to TID map id
|
||||||
* @CDP_SET_MCAST_VDEV: Set primary mcast vdev
|
* @CDP_SET_MCAST_VDEV: Set primary mcast vdev
|
||||||
|
* @CDP_RESET_MLO_MCAST_VDEV: Reset mlo mcast vdev settings
|
||||||
* @CDP_SET_MCAST_VDEV_HW_UPDATE: Not in use
|
* @CDP_SET_MCAST_VDEV_HW_UPDATE: Not in use
|
||||||
* @CDP_DROP_3ADDR_MCAST: enable/disable drop 3addr multicast flag
|
* @CDP_DROP_3ADDR_MCAST: enable/disable drop 3addr multicast flag
|
||||||
* @CDP_ENABLE_WRAP: qwrap ap
|
* @CDP_ENABLE_WRAP: qwrap ap
|
||||||
@@ -1505,6 +1506,7 @@ enum cdp_vdev_param_type {
|
|||||||
#endif
|
#endif
|
||||||
CDP_UPDATE_DSCP_TO_TID_MAP,
|
CDP_UPDATE_DSCP_TO_TID_MAP,
|
||||||
CDP_SET_MCAST_VDEV,
|
CDP_SET_MCAST_VDEV,
|
||||||
|
CDP_RESET_MLO_MCAST_VDEV,
|
||||||
CDP_SET_MCAST_VDEV_HW_UPDATE,
|
CDP_SET_MCAST_VDEV_HW_UPDATE,
|
||||||
CDP_DROP_3ADDR_MCAST,
|
CDP_DROP_3ADDR_MCAST,
|
||||||
CDP_ENABLE_WRAP,
|
CDP_ENABLE_WRAP,
|
||||||
|
@@ -674,14 +674,12 @@ dp_mlo_mcast_init(struct dp_soc *soc, struct dp_vdev *vdev)
|
|||||||
|
|
||||||
be_vdev->mcast_primary = false;
|
be_vdev->mcast_primary = false;
|
||||||
be_vdev->seq_num = 0;
|
be_vdev->seq_num = 0;
|
||||||
dp_tx_mcast_mlo_reinject_routing_set(soc,
|
|
||||||
(void *)&be_vdev->mcast_primary);
|
hal_tx_mcast_mlo_reinject_routing_set(
|
||||||
|
soc->hal_soc,
|
||||||
|
HAL_TX_MCAST_MLO_REINJECT_TQM_NOTIFY);
|
||||||
|
|
||||||
if (vdev->opmode == wlan_op_mode_ap) {
|
if (vdev->opmode == wlan_op_mode_ap) {
|
||||||
if (vdev->mlo_vdev)
|
|
||||||
hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc,
|
|
||||||
vdev->vdev_id,
|
|
||||||
HAL_TX_MCAST_CTRL_DROP);
|
|
||||||
else
|
|
||||||
hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc,
|
hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc,
|
||||||
vdev->vdev_id,
|
vdev->vdev_id,
|
||||||
HAL_TX_MCAST_CTRL_FW_EXCEPTION);
|
HAL_TX_MCAST_CTRL_FW_EXCEPTION);
|
||||||
@@ -2000,22 +1998,16 @@ static void dp_reconfig_tx_vdev_mcast_ctrl_be(struct dp_soc *soc,
|
|||||||
hal_tx_vdev_mcast_ctrl_set(hal_soc, vdev_id,
|
hal_tx_vdev_mcast_ctrl_set(hal_soc, vdev_id,
|
||||||
HAL_TX_MCAST_CTRL_MEC_NOTIFY);
|
HAL_TX_MCAST_CTRL_MEC_NOTIFY);
|
||||||
} else if (vdev->opmode == wlan_op_mode_ap) {
|
} else if (vdev->opmode == wlan_op_mode_ap) {
|
||||||
|
hal_tx_mcast_mlo_reinject_routing_set(
|
||||||
|
hal_soc,
|
||||||
|
HAL_TX_MCAST_MLO_REINJECT_TQM_NOTIFY);
|
||||||
if (vdev->mlo_vdev) {
|
if (vdev->mlo_vdev) {
|
||||||
if (be_vdev->mcast_primary) {
|
hal_tx_vdev_mcast_ctrl_set(
|
||||||
hal_tx_vdev_mcast_ctrl_set(hal_soc, vdev_id,
|
hal_soc,
|
||||||
|
vdev_id,
|
||||||
HAL_TX_MCAST_CTRL_NO_SPECIAL);
|
HAL_TX_MCAST_CTRL_NO_SPECIAL);
|
||||||
|
} else {
|
||||||
hal_tx_vdev_mcast_ctrl_set(hal_soc,
|
hal_tx_vdev_mcast_ctrl_set(hal_soc,
|
||||||
vdev_id + 128,
|
|
||||||
HAL_TX_MCAST_CTRL_FW_EXCEPTION);
|
|
||||||
dp_mcast_mlo_iter_ptnr_soc(be_soc,
|
|
||||||
dp_tx_mcast_mlo_reinject_routing_set,
|
|
||||||
(void *)&be_vdev->mcast_primary);
|
|
||||||
} else {
|
|
||||||
hal_tx_vdev_mcast_ctrl_set(hal_soc, vdev_id,
|
|
||||||
HAL_TX_MCAST_CTRL_DROP);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc,
|
|
||||||
vdev_id,
|
vdev_id,
|
||||||
HAL_TX_MCAST_CTRL_FW_EXCEPTION);
|
HAL_TX_MCAST_CTRL_FW_EXCEPTION);
|
||||||
}
|
}
|
||||||
@@ -2052,34 +2044,40 @@ static void dp_mlo_mcast_reset_pri_mcast(struct dp_vdev_be *be_vdev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void dp_txrx_set_mlo_mcast_primary_vdev_param_be(
|
static void dp_txrx_set_mlo_mcast_primary_vdev_param_be(
|
||||||
struct dp_vdev_be *be_vdev,
|
struct dp_vdev *vdev,
|
||||||
cdp_config_param_type val)
|
cdp_config_param_type val)
|
||||||
{
|
{
|
||||||
|
struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
|
||||||
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(
|
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(
|
||||||
be_vdev->vdev.pdev->soc);
|
be_vdev->vdev.pdev->soc);
|
||||||
hal_soc_handle_t hal_soc = be_vdev->vdev.pdev->soc->hal_soc;
|
|
||||||
uint8_t vdev_id = be_vdev->vdev.vdev_id;
|
|
||||||
|
|
||||||
be_vdev->mcast_primary = val.cdp_vdev_param_mcast_vdev;
|
be_vdev->mcast_primary = val.cdp_vdev_param_mcast_vdev;
|
||||||
|
vdev->mlo_vdev = true;
|
||||||
|
hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc,
|
||||||
|
vdev->vdev_id,
|
||||||
|
HAL_TX_MCAST_CTRL_NO_SPECIAL);
|
||||||
|
|
||||||
if (be_vdev->mcast_primary) {
|
if (be_vdev->mcast_primary) {
|
||||||
hal_tx_vdev_mcast_ctrl_set(hal_soc, vdev_id,
|
|
||||||
HAL_TX_MCAST_CTRL_NO_SPECIAL);
|
|
||||||
hal_tx_vdev_mcast_ctrl_set(hal_soc, vdev_id + 128,
|
|
||||||
HAL_TX_MCAST_CTRL_FW_EXCEPTION);
|
|
||||||
dp_mcast_mlo_iter_ptnr_soc(be_soc,
|
|
||||||
dp_tx_mcast_mlo_reinject_routing_set,
|
|
||||||
(void *)&be_vdev->mcast_primary);
|
|
||||||
dp_mcast_mlo_iter_ptnr_vdev(be_soc, be_vdev,
|
dp_mcast_mlo_iter_ptnr_vdev(be_soc, be_vdev,
|
||||||
dp_mlo_mcast_reset_pri_mcast,
|
dp_mlo_mcast_reset_pri_mcast,
|
||||||
(void *)&be_vdev->mcast_primary,
|
(void *)&be_vdev->mcast_primary,
|
||||||
DP_MOD_ID_TX_MCAST);
|
DP_MOD_ID_TX_MCAST);
|
||||||
} else {
|
|
||||||
hal_tx_vdev_mcast_ctrl_set(hal_soc, vdev_id,
|
|
||||||
HAL_TX_MCAST_CTRL_DROP);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dp_txrx_reset_mlo_mcast_primary_vdev_param_be(
|
||||||
|
struct dp_vdev *vdev,
|
||||||
|
cdp_config_param_type val)
|
||||||
|
{
|
||||||
|
struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
|
||||||
|
|
||||||
|
be_vdev->mcast_primary = false;
|
||||||
|
vdev->mlo_vdev = false;
|
||||||
|
hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc,
|
||||||
|
vdev->vdev_id,
|
||||||
|
HAL_TX_MCAST_CTRL_FW_EXCEPTION);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dp_txrx_get_vdev_mcast_param_be() - Target specific ops for getting vdev
|
* dp_txrx_get_vdev_mcast_param_be() - Target specific ops for getting vdev
|
||||||
* params related to multicast
|
* params related to multicast
|
||||||
@@ -2105,7 +2103,13 @@ QDF_STATUS dp_txrx_get_vdev_mcast_param_be(struct dp_soc *soc,
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void dp_txrx_set_mlo_mcast_primary_vdev_param_be(
|
static void dp_txrx_set_mlo_mcast_primary_vdev_param_be(
|
||||||
struct dp_vdev_be *be_vdev,
|
struct dp_vdev *vdev,
|
||||||
|
cdp_config_param_type val)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dp_txrx_reset_mlo_mcast_primary_vdev_param_be(
|
||||||
|
struct dp_vdev *vdev,
|
||||||
cdp_config_param_type val)
|
cdp_config_param_type val)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -2165,7 +2169,10 @@ QDF_STATUS dp_txrx_set_vdev_param_be(struct dp_soc *soc,
|
|||||||
dp_tx_update_bank_profile(be_soc, be_vdev);
|
dp_tx_update_bank_profile(be_soc, be_vdev);
|
||||||
break;
|
break;
|
||||||
case CDP_SET_MCAST_VDEV:
|
case CDP_SET_MCAST_VDEV:
|
||||||
dp_txrx_set_mlo_mcast_primary_vdev_param_be(be_vdev, val);
|
dp_txrx_set_mlo_mcast_primary_vdev_param_be(vdev, val);
|
||||||
|
break;
|
||||||
|
case CDP_RESET_MLO_MCAST_VDEV:
|
||||||
|
dp_txrx_reset_mlo_mcast_primary_vdev_param_be(vdev, val);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dp_warn("invalid param %d", param);
|
dp_warn("invalid param %d", param);
|
||||||
@@ -2273,6 +2280,7 @@ dp_initialize_arch_ops_be_mcast_mlo(struct dp_arch_ops *arch_ops)
|
|||||||
{
|
{
|
||||||
arch_ops->dp_tx_mcast_handler = dp_tx_mlo_mcast_handler_be;
|
arch_ops->dp_tx_mcast_handler = dp_tx_mlo_mcast_handler_be;
|
||||||
arch_ops->dp_rx_mcast_handler = dp_rx_mlo_igmp_handler;
|
arch_ops->dp_rx_mcast_handler = dp_rx_mlo_igmp_handler;
|
||||||
|
arch_ops->dp_tx_is_mcast_primary = dp_tx_mlo_is_mcast_primary_be;
|
||||||
}
|
}
|
||||||
#else /* WLAN_MCAST_MLO */
|
#else /* WLAN_MCAST_MLO */
|
||||||
static inline void
|
static inline void
|
||||||
|
@@ -685,21 +685,6 @@ dp_tx_mlo_mcast_multipass_handler(struct dp_soc *soc, struct dp_vdev *vdev,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void dp_tx_mcast_mlo_reinject_routing_set(struct dp_soc *soc, void *arg)
|
|
||||||
{
|
|
||||||
hal_soc_handle_t hal_soc = soc->hal_soc;
|
|
||||||
uint8_t *cmd = (uint8_t *)arg;
|
|
||||||
|
|
||||||
if (*cmd)
|
|
||||||
hal_tx_mcast_mlo_reinject_routing_set(
|
|
||||||
hal_soc,
|
|
||||||
HAL_TX_MCAST_MLO_REINJECT_TQM_NOTIFY);
|
|
||||||
else
|
|
||||||
hal_tx_mcast_mlo_reinject_routing_set(
|
|
||||||
hal_soc,
|
|
||||||
HAL_TX_MCAST_MLO_REINJECT_FW_NOTIFY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
dp_tx_mlo_mcast_pkt_send(struct dp_vdev_be *be_vdev,
|
dp_tx_mlo_mcast_pkt_send(struct dp_vdev_be *be_vdev,
|
||||||
struct dp_vdev *ptnr_vdev,
|
struct dp_vdev *ptnr_vdev,
|
||||||
@@ -770,6 +755,17 @@ void dp_tx_mlo_mcast_handler_be(struct dp_soc *soc,
|
|||||||
else
|
else
|
||||||
be_vdev->seq_num++;
|
be_vdev->seq_num++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool dp_tx_mlo_is_mcast_primary_be(struct dp_soc *soc,
|
||||||
|
struct dp_vdev *vdev)
|
||||||
|
{
|
||||||
|
struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
|
||||||
|
|
||||||
|
if (be_vdev->mcast_primary)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
static inline void
|
static inline void
|
||||||
dp_tx_vdev_id_set_hal_tx_desc(uint32_t *hal_tx_desc_cached,
|
dp_tx_vdev_id_set_hal_tx_desc(uint32_t *hal_tx_desc_cached,
|
||||||
@@ -786,6 +782,12 @@ void dp_tx_mlo_mcast_handler_be(struct dp_soc *soc,
|
|||||||
qdf_nbuf_t nbuf)
|
qdf_nbuf_t nbuf)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool dp_tx_mlo_is_mcast_primary_be(struct dp_soc *soc,
|
||||||
|
struct dp_vdev *vdev)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SAWF
|
#ifdef CONFIG_SAWF
|
||||||
|
@@ -240,6 +240,17 @@ int dp_ppeds_tx_comp_handler(struct dp_soc_be *be_soc, uint32_t quota);
|
|||||||
void dp_tx_mlo_mcast_handler_be(struct dp_soc *soc,
|
void dp_tx_mlo_mcast_handler_be(struct dp_soc *soc,
|
||||||
struct dp_vdev *vdev,
|
struct dp_vdev *vdev,
|
||||||
qdf_nbuf_t nbuf);
|
qdf_nbuf_t nbuf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_tx_mlo_is_mcast_primary_be() - Function to check for primary mcast vdev
|
||||||
|
* @soc: Handle to DP Soc structure
|
||||||
|
* @vdev: DP vdev handle
|
||||||
|
*
|
||||||
|
* Return: True if vdev is mcast primary
|
||||||
|
* False for all othercase
|
||||||
|
*/
|
||||||
|
bool dp_tx_mlo_is_mcast_primary_be(struct dp_soc *soc,
|
||||||
|
struct dp_vdev *vdev);
|
||||||
#ifdef WLAN_MCAST_MLO
|
#ifdef WLAN_MCAST_MLO
|
||||||
#ifdef WLAN_MLO_MULTI_CHIP
|
#ifdef WLAN_MLO_MULTI_CHIP
|
||||||
/**
|
/**
|
||||||
@@ -253,15 +264,6 @@ void dp_tx_mlo_mcast_handler_be(struct dp_soc *soc,
|
|||||||
void dp_tx_mlo_mcast_pkt_send(struct dp_vdev_be *be_vdev,
|
void dp_tx_mlo_mcast_pkt_send(struct dp_vdev_be *be_vdev,
|
||||||
struct dp_vdev *ptnr_vdev,
|
struct dp_vdev *ptnr_vdev,
|
||||||
void *arg);
|
void *arg);
|
||||||
|
|
||||||
/**
|
|
||||||
* dp_tx_mcast_mlo_reinject_routing_set() - mlo mcast reinject routing handler
|
|
||||||
* @be_vdev: Handle to DP be_vdev structure
|
|
||||||
* @cmd: cmd to set TQM/FW based reinjection
|
|
||||||
*
|
|
||||||
* Return: None
|
|
||||||
*/
|
|
||||||
void dp_tx_mcast_mlo_reinject_routing_set(struct dp_soc *soc, void *arg);
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@@ -7036,30 +7036,12 @@ static inline void dp_vdev_register_rx_eapol(struct dp_vdev *vdev,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WLAN_FEATURE_11BE_MLO
|
#ifdef WLAN_FEATURE_11BE_MLO
|
||||||
#if defined(WLAN_MLO_MULTI_CHIP) && defined(WLAN_MCAST_MLO)
|
|
||||||
static inline void dp_vdev_save_mld_info(struct dp_vdev *vdev,
|
|
||||||
struct cdp_vdev_info *vdev_info)
|
|
||||||
{
|
|
||||||
if (qdf_is_macaddr_zero((struct qdf_mac_addr *)vdev_info->mld_mac_addr))
|
|
||||||
vdev->mlo_vdev = false;
|
|
||||||
else
|
|
||||||
vdev->mlo_vdev = true;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static inline void dp_vdev_save_mld_info(struct dp_vdev *vdev,
|
|
||||||
struct cdp_vdev_info *vdev_info)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
static inline void dp_vdev_save_mld_addr(struct dp_vdev *vdev,
|
static inline void dp_vdev_save_mld_addr(struct dp_vdev *vdev,
|
||||||
struct cdp_vdev_info *vdev_info)
|
struct cdp_vdev_info *vdev_info)
|
||||||
{
|
{
|
||||||
if (vdev_info->mld_mac_addr)
|
if (vdev_info->mld_mac_addr)
|
||||||
qdf_mem_copy(&vdev->mld_mac_addr.raw[0],
|
qdf_mem_copy(&vdev->mld_mac_addr.raw[0],
|
||||||
vdev_info->mld_mac_addr, QDF_MAC_ADDR_SIZE);
|
vdev_info->mld_mac_addr, QDF_MAC_ADDR_SIZE);
|
||||||
|
|
||||||
dp_vdev_save_mld_info(vdev, vdev_info);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static inline void dp_vdev_save_mld_addr(struct dp_vdev *vdev,
|
static inline void dp_vdev_save_mld_addr(struct dp_vdev *vdev,
|
||||||
|
@@ -5470,7 +5470,8 @@ dp_tx_mcast_reinject_handler(struct dp_soc *soc, struct dp_tx_desc_s *desc)
|
|||||||
struct dp_vdev *vdev = NULL;
|
struct dp_vdev *vdev = NULL;
|
||||||
|
|
||||||
if (desc->tx_status == HAL_TX_TQM_RR_MULTICAST_DROP) {
|
if (desc->tx_status == HAL_TX_TQM_RR_MULTICAST_DROP) {
|
||||||
if (!soc->arch_ops.dp_tx_mcast_handler)
|
if (!soc->arch_ops.dp_tx_mcast_handler ||
|
||||||
|
!soc->arch_ops.dp_tx_is_mcast_primary)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
vdev = dp_vdev_get_ref_by_id(soc, desc->vdev_id,
|
vdev = dp_vdev_get_ref_by_id(soc, desc->vdev_id,
|
||||||
@@ -5481,6 +5482,11 @@ dp_tx_mcast_reinject_handler(struct dp_soc *soc, struct dp_tx_desc_s *desc)
|
|||||||
desc->id);
|
desc->id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(soc->arch_ops.dp_tx_is_mcast_primary(soc, vdev))) {
|
||||||
|
dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_REINJECT);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
DP_STATS_INC_PKT(vdev, tx_i.reinject_pkts, 1,
|
DP_STATS_INC_PKT(vdev, tx_i.reinject_pkts, 1,
|
||||||
qdf_nbuf_len(desc->nbuf));
|
qdf_nbuf_len(desc->nbuf));
|
||||||
soc->arch_ops.dp_tx_mcast_handler(soc, vdev, desc->nbuf);
|
soc->arch_ops.dp_tx_mcast_handler(soc, vdev, desc->nbuf);
|
||||||
|
@@ -1971,6 +1971,8 @@ struct dp_arch_ops {
|
|||||||
qdf_nbuf_t nbuf);
|
qdf_nbuf_t nbuf);
|
||||||
bool (*dp_rx_mcast_handler)(struct dp_soc *soc, struct dp_vdev *vdev,
|
bool (*dp_rx_mcast_handler)(struct dp_soc *soc, struct dp_vdev *vdev,
|
||||||
struct dp_txrx_peer *peer, qdf_nbuf_t nbuf);
|
struct dp_txrx_peer *peer, qdf_nbuf_t nbuf);
|
||||||
|
bool (*dp_tx_is_mcast_primary)(struct dp_soc *soc,
|
||||||
|
struct dp_vdev *vdev);
|
||||||
#endif
|
#endif
|
||||||
struct dp_soc * (*dp_soc_get_by_idle_bm_id)(struct dp_soc *soc,
|
struct dp_soc * (*dp_soc_get_by_idle_bm_id)(struct dp_soc *soc,
|
||||||
uint8_t bm_id);
|
uint8_t bm_id);
|
||||||
|
Reference in New Issue
Block a user