diff options
author | Michael Chan <mchan@broadcom.com> | 2010-06-24 10:58:41 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-25 23:37:20 -0400 |
commit | b177a5d5d876965b42788f3a05197ef385c84dcf (patch) | |
tree | f3aefc91f4416c2057a7e98eee11ef0db77d6591 /drivers/net/cnic.c | |
parent | 644b9d4f8b8d74f4d87f14dede5e331555d3e701 (diff) |
cnic: Further unify kcq handling code.
This eliminates some of the duplicate code for the various devices
that require the same basic kcq handling.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/cnic.c')
-rw-r--r-- | drivers/net/cnic.c | 71 |
1 files changed, 34 insertions, 37 deletions
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index fabdb7868c94..5ecf0bcf372d 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c | |||
@@ -2223,16 +2223,12 @@ static void cnic_chk_pkt_rings(struct cnic_local *cp) | |||
2223 | clear_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags); | 2223 | clear_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags); |
2224 | } | 2224 | } |
2225 | 2225 | ||
2226 | static int cnic_service_bnx2(void *data, void *status_blk) | 2226 | static u32 cnic_service_bnx2_queues(struct cnic_dev *dev) |
2227 | { | 2227 | { |
2228 | struct cnic_dev *dev = data; | ||
2229 | struct cnic_local *cp = dev->cnic_priv; | 2228 | struct cnic_local *cp = dev->cnic_priv; |
2230 | u32 status_idx = *cp->kcq1.status_idx_ptr; | 2229 | u32 status_idx = (u16) *cp->kcq1.status_idx_ptr; |
2231 | int kcqe_cnt; | 2230 | int kcqe_cnt; |
2232 | 2231 | ||
2233 | if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags))) | ||
2234 | return status_idx; | ||
2235 | |||
2236 | cp->kwq_con_idx = *cp->kwq_con_idx_ptr; | 2232 | cp->kwq_con_idx = *cp->kwq_con_idx_ptr; |
2237 | 2233 | ||
2238 | while ((kcqe_cnt = cnic_get_kcqes(dev, &cp->kcq1))) { | 2234 | while ((kcqe_cnt = cnic_get_kcqes(dev, &cp->kcq1))) { |
@@ -2242,7 +2238,7 @@ static int cnic_service_bnx2(void *data, void *status_blk) | |||
2242 | /* Tell compiler that status_blk fields can change. */ | 2238 | /* Tell compiler that status_blk fields can change. */ |
2243 | barrier(); | 2239 | barrier(); |
2244 | if (status_idx != *cp->kcq1.status_idx_ptr) { | 2240 | if (status_idx != *cp->kcq1.status_idx_ptr) { |
2245 | status_idx = *cp->kcq1.status_idx_ptr; | 2241 | status_idx = (u16) *cp->kcq1.status_idx_ptr; |
2246 | cp->kwq_con_idx = *cp->kwq_con_idx_ptr; | 2242 | cp->kwq_con_idx = *cp->kwq_con_idx_ptr; |
2247 | } else | 2243 | } else |
2248 | break; | 2244 | break; |
@@ -2251,37 +2247,29 @@ static int cnic_service_bnx2(void *data, void *status_blk) | |||
2251 | CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx); | 2247 | CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx); |
2252 | 2248 | ||
2253 | cnic_chk_pkt_rings(cp); | 2249 | cnic_chk_pkt_rings(cp); |
2250 | |||
2254 | return status_idx; | 2251 | return status_idx; |
2255 | } | 2252 | } |
2256 | 2253 | ||
2257 | static void cnic_service_bnx2_msix(unsigned long data) | 2254 | static int cnic_service_bnx2(void *data, void *status_blk) |
2258 | { | 2255 | { |
2259 | struct cnic_dev *dev = (struct cnic_dev *) data; | 2256 | struct cnic_dev *dev = data; |
2260 | struct cnic_local *cp = dev->cnic_priv; | 2257 | struct cnic_local *cp = dev->cnic_priv; |
2261 | struct status_block_msix *status_blk = cp->status_blk.bnx2; | ||
2262 | u32 status_idx = *cp->kcq1.status_idx_ptr; | 2258 | u32 status_idx = *cp->kcq1.status_idx_ptr; |
2263 | int kcqe_cnt; | ||
2264 | |||
2265 | cp->kwq_con_idx = status_blk->status_cmd_consumer_index; | ||
2266 | 2259 | ||
2267 | while ((kcqe_cnt = cnic_get_kcqes(dev, &cp->kcq1))) { | 2260 | if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags))) |
2268 | 2261 | return status_idx; | |
2269 | service_kcqes(dev, kcqe_cnt); | ||
2270 | 2262 | ||
2271 | /* Tell compiler that status_blk fields can change. */ | 2263 | return cnic_service_bnx2_queues(dev); |
2272 | barrier(); | 2264 | } |
2273 | if (status_idx != *cp->kcq1.status_idx_ptr) { | ||
2274 | status_idx = *cp->kcq1.status_idx_ptr; | ||
2275 | cp->kwq_con_idx = status_blk->status_cmd_consumer_index; | ||
2276 | } else | ||
2277 | break; | ||
2278 | } | ||
2279 | 2265 | ||
2280 | CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx); | 2266 | static void cnic_service_bnx2_msix(unsigned long data) |
2267 | { | ||
2268 | struct cnic_dev *dev = (struct cnic_dev *) data; | ||
2269 | struct cnic_local *cp = dev->cnic_priv; | ||
2281 | 2270 | ||
2282 | cnic_chk_pkt_rings(cp); | 2271 | cp->last_status_idx = cnic_service_bnx2_queues(dev); |
2283 | 2272 | ||
2284 | cp->last_status_idx = status_idx; | ||
2285 | CNIC_WR(dev, BNX2_PCICFG_INT_ACK_CMD, cp->int_num | | 2273 | CNIC_WR(dev, BNX2_PCICFG_INT_ACK_CMD, cp->int_num | |
2286 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | cp->last_status_idx); | 2274 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | cp->last_status_idx); |
2287 | } | 2275 | } |
@@ -2338,27 +2326,35 @@ static void cnic_ack_bnx2x_msix(struct cnic_dev *dev) | |||
2338 | IGU_INT_DISABLE, 0); | 2326 | IGU_INT_DISABLE, 0); |
2339 | } | 2327 | } |
2340 | 2328 | ||
2341 | static void cnic_service_bnx2x_bh(unsigned long data) | 2329 | static u32 cnic_service_bnx2x_kcq(struct cnic_dev *dev, struct kcq_info *info) |
2342 | { | 2330 | { |
2343 | struct cnic_dev *dev = (struct cnic_dev *) data; | 2331 | u32 last_status = *info->status_idx_ptr; |
2344 | struct cnic_local *cp = dev->cnic_priv; | ||
2345 | u32 status_idx = *cp->kcq1.status_idx_ptr; | ||
2346 | int kcqe_cnt; | 2332 | int kcqe_cnt; |
2347 | 2333 | ||
2348 | if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags))) | 2334 | while ((kcqe_cnt = cnic_get_kcqes(dev, info))) { |
2349 | return; | ||
2350 | |||
2351 | while ((kcqe_cnt = cnic_get_kcqes(dev, &cp->kcq1))) { | ||
2352 | 2335 | ||
2353 | service_kcqes(dev, kcqe_cnt); | 2336 | service_kcqes(dev, kcqe_cnt); |
2354 | 2337 | ||
2355 | /* Tell compiler that sblk fields can change. */ | 2338 | /* Tell compiler that sblk fields can change. */ |
2356 | barrier(); | 2339 | barrier(); |
2357 | if (status_idx == *cp->kcq1.status_idx_ptr) | 2340 | if (last_status == *info->status_idx_ptr) |
2358 | break; | 2341 | break; |
2359 | 2342 | ||
2360 | status_idx = *cp->kcq1.status_idx_ptr; | 2343 | last_status = *info->status_idx_ptr; |
2361 | } | 2344 | } |
2345 | return last_status; | ||
2346 | } | ||
2347 | |||
2348 | static void cnic_service_bnx2x_bh(unsigned long data) | ||
2349 | { | ||
2350 | struct cnic_dev *dev = (struct cnic_dev *) data; | ||
2351 | struct cnic_local *cp = dev->cnic_priv; | ||
2352 | u32 status_idx; | ||
2353 | |||
2354 | if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags))) | ||
2355 | return; | ||
2356 | |||
2357 | status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq1); | ||
2362 | 2358 | ||
2363 | CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx + MAX_KCQ_IDX); | 2359 | CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx + MAX_KCQ_IDX); |
2364 | cnic_ack_bnx2x_int(dev, cp->status_blk_num, CSTORM_ID, | 2360 | cnic_ack_bnx2x_int(dev, cp->status_blk_num, CSTORM_ID, |
@@ -3786,6 +3782,7 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev) | |||
3786 | cp->kcq1.hw_prod_idx_ptr = | 3782 | cp->kcq1.hw_prod_idx_ptr = |
3787 | (u16 *) &msblk->status_completion_producer_index; | 3783 | (u16 *) &msblk->status_completion_producer_index; |
3788 | cp->kcq1.status_idx_ptr = (u16 *) &msblk->status_idx; | 3784 | cp->kcq1.status_idx_ptr = (u16 *) &msblk->status_idx; |
3785 | cp->kwq_con_idx_ptr = (u16 *) &msblk->status_cmd_consumer_index; | ||
3789 | cp->int_num = sb_id << BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT; | 3786 | cp->int_num = sb_id << BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT; |
3790 | cnic_ctx_wr(dev, kwq_cid_addr, L5_KRNLQ_HOST_QIDX, sb); | 3787 | cnic_ctx_wr(dev, kwq_cid_addr, L5_KRNLQ_HOST_QIDX, sb); |
3791 | cnic_ctx_wr(dev, kcq_cid_addr, L5_KRNLQ_HOST_QIDX, sb); | 3788 | cnic_ctx_wr(dev, kcq_cid_addr, L5_KRNLQ_HOST_QIDX, sb); |