Hello Ricardo, On Tue, Apr 5, 2022 at 2:29 AM Martinez, Ricardo <ricardo.martinez@xxxxxxxxxxxxxxx> wrote: > On 3/6/2022 6:58 PM, Sergey Ryazanov wrote: >> On Thu, Feb 24, 2022 at 1:35 AM Ricardo Martinez >> <ricardo.martinez@xxxxxxxxxxxxxxx> wrote: >>> From: Haijun Liu <haijun.liu@xxxxxxxxxxxx> >>> >>> Data Path Modem AP Interface (DPMAIF) HIF layer provides methods >>> for initialization, ISR, control and event handling of TX/RX flows. >>> >>> DPMAIF TX >>> Exposes the `dmpaif_tx_send_skb` function which can be used by the >>> network device to transmit packets. >>> The uplink data management uses a Descriptor Ring Buffer (DRB). >>> First DRB entry is a message type that will be followed by 1 or more >>> normal DRB entries. Message type DRB will hold the skb information >>> and each normal DRB entry holds a pointer to the skb payload. >>> >>> DPMAIF RX >>> The downlink buffer management uses Buffer Address Table (BAT) and >>> Packet Information Table (PIT) rings. >>> The BAT ring holds the address of skb data buffer for the HW to use, >>> while the PIT contains metadata about a whole network packet including >>> a reference to the BAT entry holding the data buffer address. >>> The driver reads the PIT and BAT entries written by the modem, when >>> reaching a threshold, the driver will reload the PIT and BAT rings. > ... >>> +static int t7xx_dpmaif_add_skb_to_ring(struct dpmaif_ctrl *dpmaif_ctrl, struct sk_buff *skb) >>> +{ >>> + unsigned short cur_idx, drb_wr_idx_backup; >>> ... >>> + txq = &dpmaif_ctrl->txq[skb_cb->txq_number]; >>> ... >>> + cur_idx = txq->drb_wr_idx; >>> + drb_wr_idx_backup = cur_idx; >>> ... >>> + for (wr_cnt = 0; wr_cnt < payload_cnt; wr_cnt++) { >>> ... >>> + bus_addr = dma_map_single(dpmaif_ctrl->dev, data_addr, data_len, DMA_TO_DEVICE); >>> + if (dma_mapping_error(dpmaif_ctrl->dev, bus_addr)) { >>> + dev_err(dpmaif_ctrl->dev, "DMA mapping fail\n"); >>> + atomic_set(&txq->tx_processing, 0); >>> + >>> + spin_lock_irqsave(&txq->tx_lock, flags); >>> + txq->drb_wr_idx = drb_wr_idx_backup; >>> + spin_unlock_irqrestore(&txq->tx_lock, flags); >> >> What is the purpose of locking here? > > The intention is to protect against concurrent access of drb_wr_idx by t7xx_txq_drb_wr_available() t7xx_txq_drb_wr_available() only reads the drb_wr_idx field, why would you serialize that concurrent read? >>> + return -ENOMEM; >>> + } >>> ... >>> + } >>> ... >>> +} -- Sergey