aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cnic.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2010-06-24 10:58:40 -0400
committerDavid S. Miller <davem@davemloft.net>2010-06-25 23:37:20 -0400
commit644b9d4f8b8d74f4d87f14dede5e331555d3e701 (patch)
treeb490000b7e9f80e2914abe926c3877f68e81a291 /drivers/net/cnic.c
parente6c2889478f04b30e5a71d753734644c579472fa (diff)
cnic: Restructure kcq processing.
By doing more work in the common function cnic_get_kcqes(), and making full use of the kcq_info structure. 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.c76
1 files changed, 22 insertions, 54 deletions
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index c1f0d16dd47a..fabdb7868c94 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -2141,18 +2141,20 @@ static u16 cnic_bnx2x_hw_idx(u16 idx)
2141 return idx; 2141 return idx;
2142} 2142}
2143 2143
2144static int cnic_get_kcqes(struct cnic_dev *dev, u16 hw_prod, u16 *sw_prod) 2144static int cnic_get_kcqes(struct cnic_dev *dev, struct kcq_info *info)
2145{ 2145{
2146 struct cnic_local *cp = dev->cnic_priv; 2146 struct cnic_local *cp = dev->cnic_priv;
2147 u16 i, ri, last; 2147 u16 i, ri, hw_prod, last;
2148 struct kcqe *kcqe; 2148 struct kcqe *kcqe;
2149 int kcqe_cnt = 0, last_cnt = 0; 2149 int kcqe_cnt = 0, last_cnt = 0;
2150 2150
2151 i = ri = last = *sw_prod; 2151 i = ri = last = info->sw_prod_idx;
2152 ri &= MAX_KCQ_IDX; 2152 ri &= MAX_KCQ_IDX;
2153 hw_prod = *info->hw_prod_idx_ptr;
2154 hw_prod = cp->hw_idx(hw_prod);
2153 2155
2154 while ((i != hw_prod) && (kcqe_cnt < MAX_COMPLETED_KCQE)) { 2156 while ((i != hw_prod) && (kcqe_cnt < MAX_COMPLETED_KCQE)) {
2155 kcqe = &cp->kcq1.kcq[KCQ_PG(ri)][KCQ_IDX(ri)]; 2157 kcqe = &info->kcq[KCQ_PG(ri)][KCQ_IDX(ri)];
2156 cp->completed_kcq[kcqe_cnt++] = kcqe; 2158 cp->completed_kcq[kcqe_cnt++] = kcqe;
2157 i = cp->next_idx(i); 2159 i = cp->next_idx(i);
2158 ri = i & MAX_KCQ_IDX; 2160 ri = i & MAX_KCQ_IDX;
@@ -2162,7 +2164,7 @@ static int cnic_get_kcqes(struct cnic_dev *dev, u16 hw_prod, u16 *sw_prod)
2162 } 2164 }
2163 } 2165 }
2164 2166
2165 *sw_prod = last; 2167 info->sw_prod_idx = last;
2166 return last_cnt; 2168 return last_cnt;
2167} 2169}
2168 2170
@@ -2224,10 +2226,8 @@ static void cnic_chk_pkt_rings(struct cnic_local *cp)
2224static int cnic_service_bnx2(void *data, void *status_blk) 2226static int cnic_service_bnx2(void *data, void *status_blk)
2225{ 2227{
2226 struct cnic_dev *dev = data; 2228 struct cnic_dev *dev = data;
2227 struct status_block *sblk = status_blk;
2228 struct cnic_local *cp = dev->cnic_priv; 2229 struct cnic_local *cp = dev->cnic_priv;
2229 u32 status_idx = sblk->status_idx; 2230 u32 status_idx = *cp->kcq1.status_idx_ptr;
2230 u16 hw_prod, sw_prod;
2231 int kcqe_cnt; 2231 int kcqe_cnt;
2232 2232
2233 if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags))) 2233 if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags)))
@@ -2235,29 +2235,20 @@ static int cnic_service_bnx2(void *data, void *status_blk)
2235 2235
2236 cp->kwq_con_idx = *cp->kwq_con_idx_ptr; 2236 cp->kwq_con_idx = *cp->kwq_con_idx_ptr;
2237 2237
2238 hw_prod = sblk->status_completion_producer_index; 2238 while ((kcqe_cnt = cnic_get_kcqes(dev, &cp->kcq1))) {
2239 sw_prod = cp->kcq1.sw_prod_idx;
2240 while (sw_prod != hw_prod) {
2241 kcqe_cnt = cnic_get_kcqes(dev, hw_prod, &sw_prod);
2242 if (kcqe_cnt == 0)
2243 goto done;
2244 2239
2245 service_kcqes(dev, kcqe_cnt); 2240 service_kcqes(dev, kcqe_cnt);
2246 2241
2247 /* Tell compiler that status_blk fields can change. */ 2242 /* Tell compiler that status_blk fields can change. */
2248 barrier(); 2243 barrier();
2249 if (status_idx != sblk->status_idx) { 2244 if (status_idx != *cp->kcq1.status_idx_ptr) {
2250 status_idx = sblk->status_idx; 2245 status_idx = *cp->kcq1.status_idx_ptr;
2251 cp->kwq_con_idx = *cp->kwq_con_idx_ptr; 2246 cp->kwq_con_idx = *cp->kwq_con_idx_ptr;
2252 hw_prod = sblk->status_completion_producer_index;
2253 } else 2247 } else
2254 break; 2248 break;
2255 } 2249 }
2256 2250
2257done: 2251 CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx);
2258 CNIC_WR16(dev, cp->kcq1.io_addr, sw_prod);
2259
2260 cp->kcq1.sw_prod_idx = sw_prod;
2261 2252
2262 cnic_chk_pkt_rings(cp); 2253 cnic_chk_pkt_rings(cp);
2263 return status_idx; 2254 return status_idx;
@@ -2268,34 +2259,25 @@ static void cnic_service_bnx2_msix(unsigned long data)
2268 struct cnic_dev *dev = (struct cnic_dev *) data; 2259 struct cnic_dev *dev = (struct cnic_dev *) data;
2269 struct cnic_local *cp = dev->cnic_priv; 2260 struct cnic_local *cp = dev->cnic_priv;
2270 struct status_block_msix *status_blk = cp->status_blk.bnx2; 2261 struct status_block_msix *status_blk = cp->status_blk.bnx2;
2271 u32 status_idx = status_blk->status_idx; 2262 u32 status_idx = *cp->kcq1.status_idx_ptr;
2272 u16 hw_prod, sw_prod;
2273 int kcqe_cnt; 2263 int kcqe_cnt;
2274 2264
2275 cp->kwq_con_idx = status_blk->status_cmd_consumer_index; 2265 cp->kwq_con_idx = status_blk->status_cmd_consumer_index;
2276 2266
2277 hw_prod = status_blk->status_completion_producer_index; 2267 while ((kcqe_cnt = cnic_get_kcqes(dev, &cp->kcq1))) {
2278 sw_prod = cp->kcq1.sw_prod_idx;
2279 while (sw_prod != hw_prod) {
2280 kcqe_cnt = cnic_get_kcqes(dev, hw_prod, &sw_prod);
2281 if (kcqe_cnt == 0)
2282 goto done;
2283 2268
2284 service_kcqes(dev, kcqe_cnt); 2269 service_kcqes(dev, kcqe_cnt);
2285 2270
2286 /* Tell compiler that status_blk fields can change. */ 2271 /* Tell compiler that status_blk fields can change. */
2287 barrier(); 2272 barrier();
2288 if (status_idx != status_blk->status_idx) { 2273 if (status_idx != *cp->kcq1.status_idx_ptr) {
2289 status_idx = status_blk->status_idx; 2274 status_idx = *cp->kcq1.status_idx_ptr;
2290 cp->kwq_con_idx = status_blk->status_cmd_consumer_index; 2275 cp->kwq_con_idx = status_blk->status_cmd_consumer_index;
2291 hw_prod = status_blk->status_completion_producer_index;
2292 } else 2276 } else
2293 break; 2277 break;
2294 } 2278 }
2295 2279
2296done: 2280 CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx);
2297 CNIC_WR16(dev, cp->kcq1.io_addr, sw_prod);
2298 cp->kcq1.sw_prod_idx = sw_prod;
2299 2281
2300 cnic_chk_pkt_rings(cp); 2282 cnic_chk_pkt_rings(cp);
2301 2283
@@ -2360,41 +2342,27 @@ static void cnic_service_bnx2x_bh(unsigned long data)
2360{ 2342{
2361 struct cnic_dev *dev = (struct cnic_dev *) data; 2343 struct cnic_dev *dev = (struct cnic_dev *) data;
2362 struct cnic_local *cp = dev->cnic_priv; 2344 struct cnic_local *cp = dev->cnic_priv;
2363 u16 hw_prod, sw_prod; 2345 u32 status_idx = *cp->kcq1.status_idx_ptr;
2364 struct cstorm_status_block_c *sblk =
2365 &cp->status_blk.bnx2x->c_status_block;
2366 u32 status_idx = sblk->status_block_index;
2367 int kcqe_cnt; 2346 int kcqe_cnt;
2368 2347
2369 if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags))) 2348 if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags)))
2370 return; 2349 return;
2371 2350
2372 hw_prod = sblk->index_values[HC_INDEX_C_ISCSI_EQ_CONS]; 2351 while ((kcqe_cnt = cnic_get_kcqes(dev, &cp->kcq1))) {
2373 hw_prod = cp->hw_idx(hw_prod);
2374 sw_prod = cp->kcq1.sw_prod_idx;
2375 while (sw_prod != hw_prod) {
2376 kcqe_cnt = cnic_get_kcqes(dev, hw_prod, &sw_prod);
2377 if (kcqe_cnt == 0)
2378 goto done;
2379 2352
2380 service_kcqes(dev, kcqe_cnt); 2353 service_kcqes(dev, kcqe_cnt);
2381 2354
2382 /* Tell compiler that sblk fields can change. */ 2355 /* Tell compiler that sblk fields can change. */
2383 barrier(); 2356 barrier();
2384 if (status_idx == sblk->status_block_index) 2357 if (status_idx == *cp->kcq1.status_idx_ptr)
2385 break; 2358 break;
2386 2359
2387 status_idx = sblk->status_block_index; 2360 status_idx = *cp->kcq1.status_idx_ptr;
2388 hw_prod = sblk->index_values[HC_INDEX_C_ISCSI_EQ_CONS];
2389 hw_prod = cp->hw_idx(hw_prod);
2390 } 2361 }
2391 2362
2392done: 2363 CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx + MAX_KCQ_IDX);
2393 CNIC_WR16(dev, cp->kcq1.io_addr, sw_prod + MAX_KCQ_IDX);
2394 cnic_ack_bnx2x_int(dev, cp->status_blk_num, CSTORM_ID, 2364 cnic_ack_bnx2x_int(dev, cp->status_blk_num, CSTORM_ID,
2395 status_idx, IGU_INT_ENABLE, 1); 2365 status_idx, IGU_INT_ENABLE, 1);
2396
2397 cp->kcq1.sw_prod_idx = sw_prod;
2398} 2366}
2399 2367
2400static int cnic_service_bnx2x(void *data, void *status_blk) 2368static int cnic_service_bnx2x(void *data, void *status_blk)