static int mlxsw_pci_rdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox, struct mlxsw_pci_queue *q) { struct mlxsw_pci_queue_elem_info *elem_info; u8 sdq_count = mlxsw_pci_sdq_count(mlxsw_pci); int i; int err; q->producer_counter = 0; q->consumer_counter = 0; /* Set CQ of same number of this RDQ with base * above SDQ count as the lower ones are assigned to SDQs. */ mlxsw_cmd_mbox_sw2hw_dq_cq_set(mbox, sdq_count + q->num); mlxsw_cmd_mbox_sw2hw_dq_log2_dq_sz_set(mbox, 3); /* 8 pages */ for (i = 0; i < MLXSW_PCI_AQ_PAGES; i++) { dma_addr_t mapaddr = __mlxsw_pci_queue_page_get(q, i); mlxsw_cmd_mbox_sw2hw_dq_pa_set(mbox, i, mapaddr); } err = mlxsw_cmd_sw2hw_rdq(mlxsw_pci->core, mbox, q->num); if (err) return err; mlxsw_pci_queue_doorbell_producer_ring(mlxsw_pci, q); for (i = 0; i < q->count; i++) { elem_info = mlxsw_pci_queue_elem_info_producer_get(q); BUG_ON(!elem_info); err = mlxsw_pci_rdq_skb_alloc(mlxsw_pci, elem_info); if (err) goto rollback; /* Everything is set up, ring doorbell to pass elem to HW */ q->producer_counter++; mlxsw_pci_queue_doorbell_producer_ring(mlxsw_pci, q); } return 0; rollback: for (i--; i >= 0; i--) { elem_info = mlxsw_pci_queue_elem_info_get(q, i); mlxsw_pci_rdq_skb_free(mlxsw_pci, elem_info); } mlxsw_cmd_hw2sw_rdq(mlxsw_pci->core, q->num); return err; }
static int mlxsw_pci_sdq_dbg_read(struct seq_file *file, void *data) { struct mlxsw_pci *mlxsw_pci = dev_get_drvdata(file->private); struct mlxsw_pci_queue *q; int i; static const char hdr[] = "NUM PROD_COUNT CONS_COUNT COUNT\n"; seq_printf(file, hdr); for (i = 0; i < mlxsw_pci_sdq_count(mlxsw_pci); i++) { q = mlxsw_pci_sdq_get(mlxsw_pci, i); spin_lock_bh(&q->lock); seq_printf(file, "%3d %10d %10d %5d\n", i, q->producer_counter, q->consumer_counter, q->count); spin_unlock_bh(&q->lock); } return 0; }