Commit 0197b087ed6384760656f1e4a620a3e92d8dc0b0
Committed by
David S. Miller
1 parent
107c3f4d42
cnic: Fix lost interrupt on bnx2x
We service 2 queues (kcq1 and kcq2) in cnic_service_bnx2x_bh(). If the status block index has changed when servicing the kcq2, we must go back and check kcq1. The latest status block index will be used to acknowledge the interrupt, and without looping back to check kcq1, we may miss events on kcq1. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 1 changed file with 17 additions and 8 deletions Side-by-side Diff
drivers/net/cnic.c
... | ... | @@ -2914,26 +2914,35 @@ |
2914 | 2914 | { |
2915 | 2915 | struct cnic_dev *dev = (struct cnic_dev *) data; |
2916 | 2916 | struct cnic_local *cp = dev->cnic_priv; |
2917 | - u32 status_idx; | |
2917 | + u32 status_idx, new_status_idx; | |
2918 | 2918 | |
2919 | 2919 | if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags))) |
2920 | 2920 | return; |
2921 | 2921 | |
2922 | - status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq1); | |
2922 | + while (1) { | |
2923 | + status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq1); | |
2923 | 2924 | |
2924 | - CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx + MAX_KCQ_IDX); | |
2925 | + CNIC_WR16(dev, cp->kcq1.io_addr, | |
2926 | + cp->kcq1.sw_prod_idx + MAX_KCQ_IDX); | |
2925 | 2927 | |
2926 | - if (BNX2X_CHIP_IS_E2(cp->chip_id)) { | |
2927 | - status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq2); | |
2928 | + if (!BNX2X_CHIP_IS_E2(cp->chip_id)) { | |
2929 | + cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, USTORM_ID, | |
2930 | + status_idx, IGU_INT_ENABLE, 1); | |
2931 | + break; | |
2932 | + } | |
2928 | 2933 | |
2934 | + new_status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq2); | |
2935 | + | |
2936 | + if (new_status_idx != status_idx) | |
2937 | + continue; | |
2938 | + | |
2929 | 2939 | CNIC_WR16(dev, cp->kcq2.io_addr, cp->kcq2.sw_prod_idx + |
2930 | 2940 | MAX_KCQ_IDX); |
2931 | 2941 | |
2932 | 2942 | cnic_ack_igu_sb(dev, cp->bnx2x_igu_sb_id, IGU_SEG_ACCESS_DEF, |
2933 | 2943 | status_idx, IGU_INT_ENABLE, 1); |
2934 | - } else { | |
2935 | - cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, USTORM_ID, | |
2936 | - status_idx, IGU_INT_ENABLE, 1); | |
2944 | + | |
2945 | + break; | |
2937 | 2946 | } |
2938 | 2947 | } |
2939 | 2948 |