X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-linux.git;a=blobdiff_plain;f=drivers%2Fnet%2Fethernet%2Fmellanox%2Fmlxsw%2Fpci.c;h=de69e719dc9d96ffa149f50c2744325ce68053d6;hp=cef866c37648ca0c93d4f109eb9d4f3671fcd890;hb=1b1050cdc5cdde43177b375b5f22dc070d45d8f8;hpb=378e4e98258ad92097bfdf795dbef8b49cf52a34 diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c index cef866c37648..de69e719dc9d 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/pci.c +++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c @@ -57,6 +57,7 @@ static const char mlxsw_pci_driver_name[] = "mlxsw_pci"; static const struct pci_device_id mlxsw_pci_id_table[] = { {PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SWITCHX2), 0}, + {PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SPECTRUM), 0}, {0, } }; @@ -67,6 +68,8 @@ static const char *mlxsw_pci_device_kind_get(const struct pci_device_id *id) switch (id->device) { case PCI_DEVICE_ID_MELLANOX_SWITCHX2: return MLXSW_DEVICE_KIND_SWITCHX2; + case PCI_DEVICE_ID_MELLANOX_SPECTRUM: + return MLXSW_DEVICE_KIND_SPECTRUM; default: BUG(); } @@ -171,8 +174,8 @@ struct mlxsw_pci { struct msix_entry msix_entry; struct mlxsw_core *core; struct { - u16 num_pages; struct mlxsw_pci_mem_item *items; + unsigned int count; } fw_area; struct { struct mlxsw_pci_mem_item out_mbox; @@ -431,8 +434,7 @@ static int mlxsw_pci_wqe_frag_map(struct mlxsw_pci *mlxsw_pci, char *wqe, mapaddr = pci_map_single(pdev, frag_data, frag_len, direction); if (unlikely(pci_dma_mapping_error(pdev, mapaddr))) { - if (net_ratelimit()) - dev_err(&pdev->dev, "failed to dma map tx frag\n"); + dev_err_ratelimited(&pdev->dev, "failed to dma map tx frag\n"); return -EIO; } mlxsw_pci_wqe_address_set(wqe, index, mapaddr); @@ -497,6 +499,7 @@ 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; @@ -504,9 +507,9 @@ static int mlxsw_pci_rdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox, q->consumer_counter = 0; /* Set CQ of same number of this RDQ with base - * above MLXSW_PCI_SDQS_MAX as the lower ones are assigned to SDQs. + * above SDQ count as the lower ones are assigned to SDQs. */ - mlxsw_cmd_mbox_sw2hw_dq_cq_set(mbox, q->num + MLXSW_PCI_SDQS_COUNT); + 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); @@ -699,8 +702,8 @@ static void mlxsw_pci_cqe_rdq_handle(struct mlxsw_pci *mlxsw_pci, put_new_skb: memset(wqe, 0, q->elem_size); err = mlxsw_pci_rdq_skb_alloc(mlxsw_pci, elem_info); - if (err && net_ratelimit()) - dev_dbg(&pdev->dev, "Failed to alloc skb for RDQ\n"); + if (err) + dev_dbg_ratelimited(&pdev->dev, "Failed to alloc skb for RDQ\n"); /* Everything is set up, ring doorbell to pass elem to HW */ q->producer_counter++; mlxsw_pci_queue_doorbell_producer_ring(mlxsw_pci, q); @@ -830,7 +833,8 @@ static void mlxsw_pci_eq_tasklet(unsigned long data) { struct mlxsw_pci_queue *q = (struct mlxsw_pci_queue *) data; struct mlxsw_pci *mlxsw_pci = q->pci; - unsigned long active_cqns[BITS_TO_LONGS(MLXSW_PCI_CQS_COUNT)]; + u8 cq_count = mlxsw_pci_cq_count(mlxsw_pci); + unsigned long active_cqns[BITS_TO_LONGS(MLXSW_PCI_CQS_MAX)]; char *eqe; u8 cqn; bool cq_handle = false; @@ -866,7 +870,7 @@ static void mlxsw_pci_eq_tasklet(unsigned long data) if (!cq_handle) return; - for_each_set_bit(cqn, active_cqns, MLXSW_PCI_CQS_COUNT) { + for_each_set_bit(cqn, active_cqns, cq_count) { q = mlxsw_pci_cq_get(mlxsw_pci, cqn); mlxsw_pci_queue_tasklet_schedule(q); } @@ -1067,10 +1071,8 @@ static int mlxsw_pci_aqs_init(struct mlxsw_pci *mlxsw_pci, char *mbox) num_eqs = mlxsw_cmd_mbox_query_aq_cap_max_num_eqs_get(mbox); eq_log2sz = mlxsw_cmd_mbox_query_aq_cap_log_max_eq_sz_get(mbox); - if ((num_sdqs != MLXSW_PCI_SDQS_COUNT) || - (num_rdqs != MLXSW_PCI_RDQS_COUNT) || - (num_cqs != MLXSW_PCI_CQS_COUNT) || - (num_eqs != MLXSW_PCI_EQS_COUNT)) { + if (num_sdqs + num_rdqs > num_cqs || + num_cqs > MLXSW_PCI_CQS_MAX || num_eqs != MLXSW_PCI_EQS_COUNT) { dev_err(&pdev->dev, "Unsupported number of queues\n"); return -EINVAL; } @@ -1215,6 +1217,14 @@ static int mlxsw_pci_config_profile(struct mlxsw_pci *mlxsw_pci, char *mbox, mbox, profile->max_flood_tables); mlxsw_cmd_mbox_config_profile_max_vid_flood_tables_set( mbox, profile->max_vid_flood_tables); + mlxsw_cmd_mbox_config_profile_max_fid_offset_flood_tables_set( + mbox, profile->max_fid_offset_flood_tables); + mlxsw_cmd_mbox_config_profile_fid_offset_flood_table_size_set( + mbox, profile->fid_offset_flood_table_size); + mlxsw_cmd_mbox_config_profile_max_fid_flood_tables_set( + mbox, profile->max_fid_flood_tables); + mlxsw_cmd_mbox_config_profile_fid_flood_table_size_set( + mbox, profile->fid_flood_table_size); } if (profile->used_flood_mode) { mlxsw_cmd_mbox_config_profile_set_flood_mode_set( @@ -1272,6 +1282,7 @@ static int mlxsw_pci_fw_area_init(struct mlxsw_pci *mlxsw_pci, char *mbox, u16 num_pages) { struct mlxsw_pci_mem_item *mem_item; + int nent = 0; int i; int err; @@ -1279,7 +1290,7 @@ static int mlxsw_pci_fw_area_init(struct mlxsw_pci *mlxsw_pci, char *mbox, GFP_KERNEL); if (!mlxsw_pci->fw_area.items) return -ENOMEM; - mlxsw_pci->fw_area.num_pages = num_pages; + mlxsw_pci->fw_area.count = num_pages; mlxsw_cmd_mbox_zero(mbox); for (i = 0; i < num_pages; i++) { @@ -1293,13 +1304,22 @@ static int mlxsw_pci_fw_area_init(struct mlxsw_pci *mlxsw_pci, char *mbox, err = -ENOMEM; goto err_alloc; } - mlxsw_cmd_mbox_map_fa_pa_set(mbox, i, mem_item->mapaddr); - mlxsw_cmd_mbox_map_fa_log2size_set(mbox, i, 0); /* 1 page */ + mlxsw_cmd_mbox_map_fa_pa_set(mbox, nent, mem_item->mapaddr); + mlxsw_cmd_mbox_map_fa_log2size_set(mbox, nent, 0); /* 1 page */ + if (++nent == MLXSW_CMD_MAP_FA_VPM_ENTRIES_MAX) { + err = mlxsw_cmd_map_fa(mlxsw_pci->core, mbox, nent); + if (err) + goto err_cmd_map_fa; + nent = 0; + mlxsw_cmd_mbox_zero(mbox); + } } - err = mlxsw_cmd_map_fa(mlxsw_pci->core, mbox, num_pages); - if (err) - goto err_cmd_map_fa; + if (nent) { + err = mlxsw_cmd_map_fa(mlxsw_pci->core, mbox, nent); + if (err) + goto err_cmd_map_fa; + } return 0; @@ -1322,7 +1342,7 @@ static void mlxsw_pci_fw_area_fini(struct mlxsw_pci *mlxsw_pci) mlxsw_cmd_unmap_fa(mlxsw_pci->core); - for (i = 0; i < mlxsw_pci->fw_area.num_pages; i++) { + for (i = 0; i < mlxsw_pci->fw_area.count; i++) { mem_item = &mlxsw_pci->fw_area.items[i]; pci_free_consistent(mlxsw_pci->pdev, mem_item->size, @@ -1642,8 +1662,9 @@ static int mlxsw_pci_cmd_exec(void *bus_priv, u16 opcode, u8 opcode_mod, CIR_OUT_PARAM_LO)); memcpy(out_mbox + sizeof(tmp), &tmp, sizeof(tmp)); } - } else if (!err && out_mbox) + } else if (!err && out_mbox) { memcpy(out_mbox, mlxsw_pci->cmd.out_mbox.buf, out_mbox_size); + } mutex_unlock(&mlxsw_pci->cmd.lock);