aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cnic.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2010-06-24 10:58:41 -0400
committerDavid S. Miller <davem@davemloft.net>2010-06-25 23:37:20 -0400
commitb177a5d5d876965b42788f3a05197ef385c84dcf (patch)
treef3aefc91f4416c2057a7e98eee11ef0db77d6591 /drivers/net/cnic.c
parent644b9d4f8b8d74f4d87f14dede5e331555d3e701 (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.c71
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
2226static int cnic_service_bnx2(void *data, void *status_blk) 2226static 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
2257static void cnic_service_bnx2_msix(unsigned long data) 2254static 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); 2266static 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
2341static void cnic_service_bnx2x_bh(unsigned long data) 2329static 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
2348static 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);