Commit 9c95dce9 authored by Vinayak Kariappa Chettimada's avatar Vinayak Kariappa Chettimada Committed by Alberto Escolar
Browse files

Bluetooth: Controller: Fix incorrect use of rx buffer in Tx ISR



Do not enqueue node rx buffers for generating invalid ISO
data from Tx ISR while supplying the node rx buffer to
Radio. This causes node rx pool corruption and also MIC
failures in the central ISO LLL.

Signed-off-by: default avatarVinayak Kariappa Chettimada <vich@nordicsemi.no>
parent 038c89b2
Loading
Loading
Loading
Loading
+36 −83
Original line number Diff line number Diff line
@@ -540,7 +540,6 @@ static void isr_tx(void *param)
						      &data_chan_prn_s,
						      &data_chan_remap_idx);
	} else {
		struct lll_conn_iso_stream *old_cis_lll;
		struct lll_conn_iso_stream *next_cis_lll;
		struct lll_conn_iso_group *cig_lll;
		struct lll_conn *next_conn_lll;
@@ -552,7 +551,6 @@ static void isr_tx(void *param)
		uint16_t cis_handle;
		uint32_t start_us;
		memq_link_t *link;
		uint8_t bn;

		/* Calculate channel for next CIS */
		cig_lll = ull_conn_iso_lll_group_get_by_stream(cis_lll);
@@ -585,7 +583,6 @@ static void isr_tx(void *param)
		start_us = radio_tmr_start_us(1U, subevent_us);
		LL_ASSERT(start_us == (subevent_us + 1U));

		old_cis_lll = cis_lll;
		cis_lll = next_cis_lll;

		/* Tx Ack stale ISO Data */
@@ -618,49 +615,6 @@ static void isr_tx(void *param)
				break;
			}
		} while (link);

		cis_lll = old_cis_lll;

		/* Generate ISO Data Invalid Status */
		bn = bn_rx;
		while (bn <= cis_lll->rx.bn) {
			struct node_rx_iso_meta *iso_meta;
			struct node_rx_pdu *node_rx;

			/* Ensure there is always one free for reception of
			 * ISO PDU by the radio h/w DMA, hence peek for two
			 * available ISO PDU when using one for generating
			 * invalid ISO data.
			 */
			node_rx = ull_iso_pdu_rx_alloc_peek(2U);
			if (!node_rx) {
				break;
			}

			node_rx->hdr.type = NODE_RX_TYPE_ISO_PDU;
			node_rx->hdr.handle = cis_lll->handle;
			iso_meta = &node_rx->hdr.rx_iso_meta;
			iso_meta->payload_number = (cis_lll->event_count *
						    cis_lll->rx.bn) + (bn - 1U);
			iso_meta->timestamp =
				HAL_TICKER_TICKS_TO_US(radio_tmr_start_get()) +
				radio_tmr_ready_restore();
			iso_meta->timestamp %=
				HAL_TICKER_TICKS_TO_US(BIT(HAL_TICKER_CNTR_MSBIT + 1U));
			iso_meta->status = 1U;

			ull_iso_pdu_rx_alloc();
			iso_rx_put(node_rx->hdr.link, node_rx);

			bn++;
		}

#if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL)
		if (bn != bn_rx) {
			iso_rx_sched();
		}
#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */

	}
}

@@ -823,6 +777,7 @@ isr_rx_next_subevent:
		struct lll_conn_iso_group *cig_lll;
		struct lll_conn *next_conn_lll;
		uint8_t phy;
		uint8_t bn;

		/* Fetch next CIS */
		/* TODO: Use a new ull_conn_iso_lll_stream_get_active_by_group()
@@ -864,7 +819,6 @@ isr_rx_next_subevent:
			uint32_t subevent_us;
			uint32_t start_us;
			memq_link_t *link;
			uint8_t bn;

			/* Event counter value,  0-15 bit of cisEventCounter */
			event_counter = next_cis_lll->event_count;
@@ -918,6 +872,7 @@ isr_rx_next_subevent:
			} while (link);

			cis_lll = old_cis_lll;
		}

		/* Generate ISO Data Invalid Status */
		bn = bn_rx;
@@ -959,8 +914,6 @@ isr_rx_next_subevent:
		}
#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */

		}

		/* Reset indices for the next CIS */
		se_curr = 0U; /* isr_prepare_subevent() will increase se_curr */
		bn_tx = 1U;