diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2012-09-18 21:53:34 -0400 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2012-09-18 21:56:25 -0400 |
commit | 450783747f42dfa3883920acfad4acdd93ce69af (patch) | |
tree | e6b4b03dedec04576730c456494b36b3f27d97d5 | |
parent | 25ce200215666956d96d1a62a20c75a2f3b9d38e (diff) |
sfc: Avoid generating over-length MC_CMD_FLUSH_RX_QUEUES request
MCDI supports requests up to 252 bytes long, which is only enough to
pass 63 RX queue IDs to MC_CMD_FLUSH_RX_QUEUES. However a VF may have
up to 64 RX queues, and if we try to flush them all we will generate
an over-length request and BUG() in efx_mcdi_copyin(). Currently
all VF drivers limit themselves to 32 RX queues, so reducing the
limit to 63 does no harm.
Also add a BUILD_BUG_ON in efx_mcdi_flush_rxqs() so we remember to
deal with the same problem there if EFX_MAX_CHANNELS is increased.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
-rw-r--r-- | drivers/net/ethernet/sfc/mcdi.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/siena_sriov.c | 7 |
2 files changed, 10 insertions, 0 deletions
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index e855f4cddb4e..aea43cbd0520 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c | |||
@@ -1195,6 +1195,9 @@ int efx_mcdi_flush_rxqs(struct efx_nic *efx) | |||
1195 | __le32 *qid; | 1195 | __le32 *qid; |
1196 | int rc, count; | 1196 | int rc, count; |
1197 | 1197 | ||
1198 | BUILD_BUG_ON(EFX_MAX_CHANNELS > | ||
1199 | MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MAXNUM); | ||
1200 | |||
1198 | qid = kmalloc(EFX_MAX_CHANNELS * sizeof(*qid), GFP_KERNEL); | 1201 | qid = kmalloc(EFX_MAX_CHANNELS * sizeof(*qid), GFP_KERNEL); |
1199 | if (qid == NULL) | 1202 | if (qid == NULL) |
1200 | return -ENOMEM; | 1203 | return -ENOMEM; |
diff --git a/drivers/net/ethernet/sfc/siena_sriov.c b/drivers/net/ethernet/sfc/siena_sriov.c index 9cb3b84ecae9..a8f48a455849 100644 --- a/drivers/net/ethernet/sfc/siena_sriov.c +++ b/drivers/net/ethernet/sfc/siena_sriov.c | |||
@@ -21,6 +21,9 @@ | |||
21 | /* Number of longs required to track all the VIs in a VF */ | 21 | /* Number of longs required to track all the VIs in a VF */ |
22 | #define VI_MASK_LENGTH BITS_TO_LONGS(1 << EFX_VI_SCALE_MAX) | 22 | #define VI_MASK_LENGTH BITS_TO_LONGS(1 << EFX_VI_SCALE_MAX) |
23 | 23 | ||
24 | /* Maximum number of RX queues supported */ | ||
25 | #define VF_MAX_RX_QUEUES 63 | ||
26 | |||
24 | /** | 27 | /** |
25 | * enum efx_vf_tx_filter_mode - TX MAC filtering behaviour | 28 | * enum efx_vf_tx_filter_mode - TX MAC filtering behaviour |
26 | * @VF_TX_FILTER_OFF: Disabled | 29 | * @VF_TX_FILTER_OFF: Disabled |
@@ -578,6 +581,7 @@ static int efx_vfdi_init_rxq(struct efx_vf *vf) | |||
578 | efx_oword_t reg; | 581 | efx_oword_t reg; |
579 | 582 | ||
580 | if (bad_vf_index(efx, vf_evq) || bad_vf_index(efx, vf_rxq) || | 583 | if (bad_vf_index(efx, vf_evq) || bad_vf_index(efx, vf_rxq) || |
584 | vf_rxq >= VF_MAX_RX_QUEUES || | ||
581 | bad_buf_count(buf_count, EFX_MAX_DMAQ_SIZE)) { | 585 | bad_buf_count(buf_count, EFX_MAX_DMAQ_SIZE)) { |
582 | if (net_ratelimit()) | 586 | if (net_ratelimit()) |
583 | netif_err(efx, hw, efx->net_dev, | 587 | netif_err(efx, hw, efx->net_dev, |
@@ -683,6 +687,9 @@ static int efx_vfdi_fini_all_queues(struct efx_vf *vf) | |||
683 | __le32 *rxqs; | 687 | __le32 *rxqs; |
684 | int rc; | 688 | int rc; |
685 | 689 | ||
690 | BUILD_BUG_ON(VF_MAX_RX_QUEUES > | ||
691 | MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MAXNUM); | ||
692 | |||
686 | rxqs = kmalloc(count * sizeof(*rxqs), GFP_KERNEL); | 693 | rxqs = kmalloc(count * sizeof(*rxqs), GFP_KERNEL); |
687 | if (rxqs == NULL) | 694 | if (rxqs == NULL) |
688 | return VFDI_RC_ENOMEM; | 695 | return VFDI_RC_ENOMEM; |