aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRasesh Mody <rmody@brocade.com>2012-12-11 07:24:51 -0500
committerDavid S. Miller <davem@davemloft.net>2012-12-11 18:25:47 -0500
commit5216562a2ccd037d0eb85a2e8bbfd6315e3f1bb5 (patch)
tree6c22d90daca6d7684f97fdbe331ced936569beaa
parent5e46631fdb1e5611969c1e61106a59a3b38af078 (diff)
bna: Tx and Rx Optimizations
Change details: - Have contiguous queue pages for TxQ, RxQ and CQ. Data structure and QPT changes related to contiguous queue pages - Optimized Tx and Rx unmap structures. Tx and Rx fast path changes due to unmap data structure changes - Re-factored Tx and Rx fastpath routines as per the new queue data structures - Implemented bnad_txq_wi_prepare() to program the opcode, flags, frame_len and num_vectors in the work item - Reduced Max TxQ and RxQ depth to 2048 while default value for Tx/Rx queue depth is unaltered (512) Signed-off-by: Rasesh Mody <rmody@brocade.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/brocade/bna/bna.h2
-rw-r--r--drivers/net/ethernet/brocade/bna/bna_tx_rx.c109
-rw-r--r--drivers/net/ethernet/brocade/bna/bna_types.h9
-rw-r--r--drivers/net/ethernet/brocade/bna/bnad.c688
-rw-r--r--drivers/net/ethernet/brocade/bna/bnad.h41
5 files changed, 380 insertions, 469 deletions
diff --git a/drivers/net/ethernet/brocade/bna/bna.h b/drivers/net/ethernet/brocade/bna/bna.h
index ede532b4e9db..25dae757e9c4 100644
--- a/drivers/net/ethernet/brocade/bna/bna.h
+++ b/drivers/net/ethernet/brocade/bna/bna.h
@@ -138,6 +138,8 @@ do { \
138#define BNA_QE_INDX_ADD(_qe_idx, _qe_num, _q_depth) \ 138#define BNA_QE_INDX_ADD(_qe_idx, _qe_num, _q_depth) \
139 ((_qe_idx) = ((_qe_idx) + (_qe_num)) & ((_q_depth) - 1)) 139 ((_qe_idx) = ((_qe_idx) + (_qe_num)) & ((_q_depth) - 1))
140 140
141#define BNA_QE_INDX_INC(_idx, _q_depth) BNA_QE_INDX_ADD(_idx, 1, _q_depth)
142
141#define BNA_Q_INDEX_CHANGE(_old_idx, _updated_idx, _q_depth) \ 143#define BNA_Q_INDEX_CHANGE(_old_idx, _updated_idx, _q_depth) \
142 (((_updated_idx) - (_old_idx)) & ((_q_depth) - 1)) 144 (((_updated_idx) - (_old_idx)) & ((_q_depth) - 1))
143 145
diff --git a/drivers/net/ethernet/brocade/bna/bna_tx_rx.c b/drivers/net/ethernet/brocade/bna/bna_tx_rx.c
index 71144b396e02..bb5467bd3090 100644
--- a/drivers/net/ethernet/brocade/bna/bna_tx_rx.c
+++ b/drivers/net/ethernet/brocade/bna/bna_tx_rx.c
@@ -1908,6 +1908,9 @@ bna_rxq_qpt_setup(struct bna_rxq *rxq,
1908 struct bna_mem_descr *swqpt_mem, 1908 struct bna_mem_descr *swqpt_mem,
1909 struct bna_mem_descr *page_mem) 1909 struct bna_mem_descr *page_mem)
1910{ 1910{
1911 u8 *kva;
1912 u64 dma;
1913 struct bna_dma_addr bna_dma;
1911 int i; 1914 int i;
1912 1915
1913 rxq->qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb; 1916 rxq->qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
@@ -1917,13 +1920,21 @@ bna_rxq_qpt_setup(struct bna_rxq *rxq,
1917 rxq->qpt.page_size = page_size; 1920 rxq->qpt.page_size = page_size;
1918 1921
1919 rxq->rcb->sw_qpt = (void **) swqpt_mem->kva; 1922 rxq->rcb->sw_qpt = (void **) swqpt_mem->kva;
1923 rxq->rcb->sw_q = page_mem->kva;
1924
1925 kva = page_mem->kva;
1926 BNA_GET_DMA_ADDR(&page_mem->dma, dma);
1920 1927
1921 for (i = 0; i < rxq->qpt.page_count; i++) { 1928 for (i = 0; i < rxq->qpt.page_count; i++) {
1922 rxq->rcb->sw_qpt[i] = page_mem[i].kva; 1929 rxq->rcb->sw_qpt[i] = kva;
1930 kva += PAGE_SIZE;
1931
1932 BNA_SET_DMA_ADDR(dma, &bna_dma);
1923 ((struct bna_dma_addr *)rxq->qpt.kv_qpt_ptr)[i].lsb = 1933 ((struct bna_dma_addr *)rxq->qpt.kv_qpt_ptr)[i].lsb =
1924 page_mem[i].dma.lsb; 1934 bna_dma.lsb;
1925 ((struct bna_dma_addr *)rxq->qpt.kv_qpt_ptr)[i].msb = 1935 ((struct bna_dma_addr *)rxq->qpt.kv_qpt_ptr)[i].msb =
1926 page_mem[i].dma.msb; 1936 bna_dma.msb;
1937 dma += PAGE_SIZE;
1927 } 1938 }
1928} 1939}
1929 1940
@@ -1935,6 +1946,9 @@ bna_rxp_cqpt_setup(struct bna_rxp *rxp,
1935 struct bna_mem_descr *swqpt_mem, 1946 struct bna_mem_descr *swqpt_mem,
1936 struct bna_mem_descr *page_mem) 1947 struct bna_mem_descr *page_mem)
1937{ 1948{
1949 u8 *kva;
1950 u64 dma;
1951 struct bna_dma_addr bna_dma;
1938 int i; 1952 int i;
1939 1953
1940 rxp->cq.qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb; 1954 rxp->cq.qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
@@ -1944,14 +1958,21 @@ bna_rxp_cqpt_setup(struct bna_rxp *rxp,
1944 rxp->cq.qpt.page_size = page_size; 1958 rxp->cq.qpt.page_size = page_size;
1945 1959
1946 rxp->cq.ccb->sw_qpt = (void **) swqpt_mem->kva; 1960 rxp->cq.ccb->sw_qpt = (void **) swqpt_mem->kva;
1961 rxp->cq.ccb->sw_q = page_mem->kva;
1962
1963 kva = page_mem->kva;
1964 BNA_GET_DMA_ADDR(&page_mem->dma, dma);
1947 1965
1948 for (i = 0; i < rxp->cq.qpt.page_count; i++) { 1966 for (i = 0; i < rxp->cq.qpt.page_count; i++) {
1949 rxp->cq.ccb->sw_qpt[i] = page_mem[i].kva; 1967 rxp->cq.ccb->sw_qpt[i] = kva;
1968 kva += PAGE_SIZE;
1950 1969
1970 BNA_SET_DMA_ADDR(dma, &bna_dma);
1951 ((struct bna_dma_addr *)rxp->cq.qpt.kv_qpt_ptr)[i].lsb = 1971 ((struct bna_dma_addr *)rxp->cq.qpt.kv_qpt_ptr)[i].lsb =
1952 page_mem[i].dma.lsb; 1972 bna_dma.lsb;
1953 ((struct bna_dma_addr *)rxp->cq.qpt.kv_qpt_ptr)[i].msb = 1973 ((struct bna_dma_addr *)rxp->cq.qpt.kv_qpt_ptr)[i].msb =
1954 page_mem[i].dma.msb; 1974 bna_dma.msb;
1975 dma += PAGE_SIZE;
1955 } 1976 }
1956} 1977}
1957 1978
@@ -2250,8 +2271,8 @@ bna_rx_res_req(struct bna_rx_config *q_cfg, struct bna_res_info *res_info)
2250 res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_type = BNA_RES_T_MEM; 2271 res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_type = BNA_RES_T_MEM;
2251 mem_info = &res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info; 2272 mem_info = &res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info;
2252 mem_info->mem_type = BNA_MEM_T_DMA; 2273 mem_info->mem_type = BNA_MEM_T_DMA;
2253 mem_info->len = PAGE_SIZE; 2274 mem_info->len = PAGE_SIZE * cpage_count;
2254 mem_info->num = cpage_count * q_cfg->num_paths; 2275 mem_info->num = q_cfg->num_paths;
2255 2276
2256 res_info[BNA_RX_RES_MEM_T_DQPT].res_type = BNA_RES_T_MEM; 2277 res_info[BNA_RX_RES_MEM_T_DQPT].res_type = BNA_RES_T_MEM;
2257 mem_info = &res_info[BNA_RX_RES_MEM_T_DQPT].res_u.mem_info; 2278 mem_info = &res_info[BNA_RX_RES_MEM_T_DQPT].res_u.mem_info;
@@ -2268,8 +2289,8 @@ bna_rx_res_req(struct bna_rx_config *q_cfg, struct bna_res_info *res_info)
2268 res_info[BNA_RX_RES_MEM_T_DPAGE].res_type = BNA_RES_T_MEM; 2289 res_info[BNA_RX_RES_MEM_T_DPAGE].res_type = BNA_RES_T_MEM;
2269 mem_info = &res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info; 2290 mem_info = &res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info;
2270 mem_info->mem_type = BNA_MEM_T_DMA; 2291 mem_info->mem_type = BNA_MEM_T_DMA;
2271 mem_info->len = PAGE_SIZE; 2292 mem_info->len = PAGE_SIZE * dpage_count;
2272 mem_info->num = dpage_count * q_cfg->num_paths; 2293 mem_info->num = q_cfg->num_paths;
2273 2294
2274 res_info[BNA_RX_RES_MEM_T_HQPT].res_type = BNA_RES_T_MEM; 2295 res_info[BNA_RX_RES_MEM_T_HQPT].res_type = BNA_RES_T_MEM;
2275 mem_info = &res_info[BNA_RX_RES_MEM_T_HQPT].res_u.mem_info; 2296 mem_info = &res_info[BNA_RX_RES_MEM_T_HQPT].res_u.mem_info;
@@ -2286,8 +2307,8 @@ bna_rx_res_req(struct bna_rx_config *q_cfg, struct bna_res_info *res_info)
2286 res_info[BNA_RX_RES_MEM_T_HPAGE].res_type = BNA_RES_T_MEM; 2307 res_info[BNA_RX_RES_MEM_T_HPAGE].res_type = BNA_RES_T_MEM;
2287 mem_info = &res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info; 2308 mem_info = &res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info;
2288 mem_info->mem_type = BNA_MEM_T_DMA; 2309 mem_info->mem_type = BNA_MEM_T_DMA;
2289 mem_info->len = (hpage_count ? PAGE_SIZE : 0); 2310 mem_info->len = PAGE_SIZE * hpage_count;
2290 mem_info->num = (hpage_count ? (hpage_count * q_cfg->num_paths) : 0); 2311 mem_info->num = (hpage_count ? q_cfg->num_paths : 0);
2291 2312
2292 res_info[BNA_RX_RES_MEM_T_IBIDX].res_type = BNA_RES_T_MEM; 2313 res_info[BNA_RX_RES_MEM_T_IBIDX].res_type = BNA_RES_T_MEM;
2293 mem_info = &res_info[BNA_RX_RES_MEM_T_IBIDX].res_u.mem_info; 2314 mem_info = &res_info[BNA_RX_RES_MEM_T_IBIDX].res_u.mem_info;
@@ -2332,7 +2353,7 @@ bna_rx_create(struct bna *bna, struct bnad *bnad,
2332 struct bna_mem_descr *dsqpt_mem; 2353 struct bna_mem_descr *dsqpt_mem;
2333 struct bna_mem_descr *hpage_mem; 2354 struct bna_mem_descr *hpage_mem;
2334 struct bna_mem_descr *dpage_mem; 2355 struct bna_mem_descr *dpage_mem;
2335 int i, cpage_idx = 0, dpage_idx = 0, hpage_idx = 0; 2356 int i;
2336 int dpage_count, hpage_count, rcb_idx; 2357 int dpage_count, hpage_count, rcb_idx;
2337 2358
2338 if (!bna_rx_res_check(rx_mod, rx_cfg)) 2359 if (!bna_rx_res_check(rx_mod, rx_cfg))
@@ -2352,14 +2373,14 @@ bna_rx_create(struct bna *bna, struct bnad *bnad,
2352 hpage_mem = &res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info.mdl[0]; 2373 hpage_mem = &res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info.mdl[0];
2353 dpage_mem = &res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info.mdl[0]; 2374 dpage_mem = &res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info.mdl[0];
2354 2375
2355 page_count = res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info.num / 2376 page_count = res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info.len /
2356 rx_cfg->num_paths; 2377 PAGE_SIZE;
2357 2378
2358 dpage_count = res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info.num / 2379 dpage_count = res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info.len /
2359 rx_cfg->num_paths; 2380 PAGE_SIZE;
2360 2381
2361 hpage_count = res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info.num / 2382 hpage_count = res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info.len /
2362 rx_cfg->num_paths; 2383 PAGE_SIZE;
2363 2384
2364 rx = bna_rx_get(rx_mod, rx_cfg->rx_type); 2385 rx = bna_rx_get(rx_mod, rx_cfg->rx_type);
2365 rx->bna = bna; 2386 rx->bna = bna;
@@ -2446,10 +2467,7 @@ bna_rx_create(struct bna *bna, struct bnad *bnad,
2446 q0->rx_packets_with_error = q0->rxbuf_alloc_failed = 0; 2467 q0->rx_packets_with_error = q0->rxbuf_alloc_failed = 0;
2447 2468
2448 bna_rxq_qpt_setup(q0, rxp, dpage_count, PAGE_SIZE, 2469 bna_rxq_qpt_setup(q0, rxp, dpage_count, PAGE_SIZE,
2449 &dqpt_mem[i], &dsqpt_mem[i], &dpage_mem[dpage_idx]); 2470 &dqpt_mem[i], &dsqpt_mem[i], &dpage_mem[i]);
2450 q0->rcb->page_idx = dpage_idx;
2451 q0->rcb->page_count = dpage_count;
2452 dpage_idx += dpage_count;
2453 2471
2454 if (rx->rcb_setup_cbfn) 2472 if (rx->rcb_setup_cbfn)
2455 rx->rcb_setup_cbfn(bnad, q0->rcb); 2473 rx->rcb_setup_cbfn(bnad, q0->rcb);
@@ -2475,10 +2493,7 @@ bna_rx_create(struct bna *bna, struct bnad *bnad,
2475 2493
2476 bna_rxq_qpt_setup(q1, rxp, hpage_count, PAGE_SIZE, 2494 bna_rxq_qpt_setup(q1, rxp, hpage_count, PAGE_SIZE,
2477 &hqpt_mem[i], &hsqpt_mem[i], 2495 &hqpt_mem[i], &hsqpt_mem[i],
2478 &hpage_mem[hpage_idx]); 2496 &hpage_mem[i]);
2479 q1->rcb->page_idx = hpage_idx;
2480 q1->rcb->page_count = hpage_count;
2481 hpage_idx += hpage_count;
2482 2497
2483 if (rx->rcb_setup_cbfn) 2498 if (rx->rcb_setup_cbfn)
2484 rx->rcb_setup_cbfn(bnad, q1->rcb); 2499 rx->rcb_setup_cbfn(bnad, q1->rcb);
@@ -2510,10 +2525,7 @@ bna_rx_create(struct bna *bna, struct bnad *bnad,
2510 rxp->cq.ccb->id = i; 2525 rxp->cq.ccb->id = i;
2511 2526
2512 bna_rxp_cqpt_setup(rxp, page_count, PAGE_SIZE, 2527 bna_rxp_cqpt_setup(rxp, page_count, PAGE_SIZE,
2513 &cqpt_mem[i], &cswqpt_mem[i], &cpage_mem[cpage_idx]); 2528 &cqpt_mem[i], &cswqpt_mem[i], &cpage_mem[i]);
2514 rxp->cq.ccb->page_idx = cpage_idx;
2515 rxp->cq.ccb->page_count = page_count;
2516 cpage_idx += page_count;
2517 2529
2518 if (rx->ccb_setup_cbfn) 2530 if (rx->ccb_setup_cbfn)
2519 rx->ccb_setup_cbfn(bnad, rxp->cq.ccb); 2531 rx->ccb_setup_cbfn(bnad, rxp->cq.ccb);
@@ -3230,6 +3242,9 @@ bna_txq_qpt_setup(struct bna_txq *txq, int page_count, int page_size,
3230 struct bna_mem_descr *swqpt_mem, 3242 struct bna_mem_descr *swqpt_mem,
3231 struct bna_mem_descr *page_mem) 3243 struct bna_mem_descr *page_mem)
3232{ 3244{
3245 u8 *kva;
3246 u64 dma;
3247 struct bna_dma_addr bna_dma;
3233 int i; 3248 int i;
3234 3249
3235 txq->qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb; 3250 txq->qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
@@ -3239,14 +3254,21 @@ bna_txq_qpt_setup(struct bna_txq *txq, int page_count, int page_size,
3239 txq->qpt.page_size = page_size; 3254 txq->qpt.page_size = page_size;
3240 3255
3241 txq->tcb->sw_qpt = (void **) swqpt_mem->kva; 3256 txq->tcb->sw_qpt = (void **) swqpt_mem->kva;
3257 txq->tcb->sw_q = page_mem->kva;
3258
3259 kva = page_mem->kva;
3260 BNA_GET_DMA_ADDR(&page_mem->dma, dma);
3242 3261
3243 for (i = 0; i < page_count; i++) { 3262 for (i = 0; i < page_count; i++) {
3244 txq->tcb->sw_qpt[i] = page_mem[i].kva; 3263 txq->tcb->sw_qpt[i] = kva;
3264 kva += PAGE_SIZE;
3245 3265
3266 BNA_SET_DMA_ADDR(dma, &bna_dma);
3246 ((struct bna_dma_addr *)txq->qpt.kv_qpt_ptr)[i].lsb = 3267 ((struct bna_dma_addr *)txq->qpt.kv_qpt_ptr)[i].lsb =
3247 page_mem[i].dma.lsb; 3268 bna_dma.lsb;
3248 ((struct bna_dma_addr *)txq->qpt.kv_qpt_ptr)[i].msb = 3269 ((struct bna_dma_addr *)txq->qpt.kv_qpt_ptr)[i].msb =
3249 page_mem[i].dma.msb; 3270 bna_dma.msb;
3271 dma += PAGE_SIZE;
3250 } 3272 }
3251} 3273}
3252 3274
@@ -3430,8 +3452,8 @@ bna_tx_res_req(int num_txq, int txq_depth, struct bna_res_info *res_info)
3430 res_info[BNA_TX_RES_MEM_T_PAGE].res_type = BNA_RES_T_MEM; 3452 res_info[BNA_TX_RES_MEM_T_PAGE].res_type = BNA_RES_T_MEM;
3431 mem_info = &res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info; 3453 mem_info = &res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info;
3432 mem_info->mem_type = BNA_MEM_T_DMA; 3454 mem_info->mem_type = BNA_MEM_T_DMA;
3433 mem_info->len = PAGE_SIZE; 3455 mem_info->len = PAGE_SIZE * page_count;
3434 mem_info->num = num_txq * page_count; 3456 mem_info->num = num_txq;
3435 3457
3436 res_info[BNA_TX_RES_MEM_T_IBIDX].res_type = BNA_RES_T_MEM; 3458 res_info[BNA_TX_RES_MEM_T_IBIDX].res_type = BNA_RES_T_MEM;
3437 mem_info = &res_info[BNA_TX_RES_MEM_T_IBIDX].res_u.mem_info; 3459 mem_info = &res_info[BNA_TX_RES_MEM_T_IBIDX].res_u.mem_info;
@@ -3457,14 +3479,11 @@ bna_tx_create(struct bna *bna, struct bnad *bnad,
3457 struct bna_txq *txq; 3479 struct bna_txq *txq;
3458 struct list_head *qe; 3480 struct list_head *qe;
3459 int page_count; 3481 int page_count;
3460 int page_size;
3461 int page_idx;
3462 int i; 3482 int i;
3463 3483
3464 intr_info = &res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info; 3484 intr_info = &res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info;
3465 page_count = (res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info.num) / 3485 page_count = (res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info.len) /
3466 tx_cfg->num_txq; 3486 PAGE_SIZE;
3467 page_size = res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info.len;
3468 3487
3469 /** 3488 /**
3470 * Get resources 3489 * Get resources
@@ -3529,7 +3548,6 @@ bna_tx_create(struct bna *bna, struct bnad *bnad,
3529 /* TxQ */ 3548 /* TxQ */
3530 3549
3531 i = 0; 3550 i = 0;
3532 page_idx = 0;
3533 list_for_each(qe, &tx->txq_q) { 3551 list_for_each(qe, &tx->txq_q) {
3534 txq = (struct bna_txq *)qe; 3552 txq = (struct bna_txq *)qe;
3535 txq->tcb = (struct bna_tcb *) 3553 txq->tcb = (struct bna_tcb *)
@@ -3569,14 +3587,11 @@ bna_tx_create(struct bna *bna, struct bnad *bnad,
3569 txq->tcb->id = i; 3587 txq->tcb->id = i;
3570 3588
3571 /* QPT, SWQPT, Pages */ 3589 /* QPT, SWQPT, Pages */
3572 bna_txq_qpt_setup(txq, page_count, page_size, 3590 bna_txq_qpt_setup(txq, page_count, PAGE_SIZE,
3573 &res_info[BNA_TX_RES_MEM_T_QPT].res_u.mem_info.mdl[i], 3591 &res_info[BNA_TX_RES_MEM_T_QPT].res_u.mem_info.mdl[i],
3574 &res_info[BNA_TX_RES_MEM_T_SWQPT].res_u.mem_info.mdl[i], 3592 &res_info[BNA_TX_RES_MEM_T_SWQPT].res_u.mem_info.mdl[i],
3575 &res_info[BNA_TX_RES_MEM_T_PAGE]. 3593 &res_info[BNA_TX_RES_MEM_T_PAGE].
3576 res_u.mem_info.mdl[page_idx]); 3594 res_u.mem_info.mdl[i]);
3577 txq->tcb->page_idx = page_idx;
3578 txq->tcb->page_count = page_count;
3579 page_idx += page_count;
3580 3595
3581 /* Callback to bnad for setting up TCB */ 3596 /* Callback to bnad for setting up TCB */
3582 if (tx->tcb_setup_cbfn) 3597 if (tx->tcb_setup_cbfn)
diff --git a/drivers/net/ethernet/brocade/bna/bna_types.h b/drivers/net/ethernet/brocade/bna/bna_types.h
index d3eb8bddfb2a..dc50f7836b6d 100644
--- a/drivers/net/ethernet/brocade/bna/bna_types.h
+++ b/drivers/net/ethernet/brocade/bna/bna_types.h
@@ -430,6 +430,7 @@ struct bna_ib {
430struct bna_tcb { 430struct bna_tcb {
431 /* Fast path */ 431 /* Fast path */
432 void **sw_qpt; 432 void **sw_qpt;
433 void *sw_q;
433 void *unmap_q; 434 void *unmap_q;
434 u32 producer_index; 435 u32 producer_index;
435 u32 consumer_index; 436 u32 consumer_index;
@@ -437,8 +438,6 @@ struct bna_tcb {
437 u32 q_depth; 438 u32 q_depth;
438 void __iomem *q_dbell; 439 void __iomem *q_dbell;
439 struct bna_ib_dbell *i_dbell; 440 struct bna_ib_dbell *i_dbell;
440 int page_idx;
441 int page_count;
442 /* Control path */ 441 /* Control path */
443 struct bna_txq *txq; 442 struct bna_txq *txq;
444 struct bnad *bnad; 443 struct bnad *bnad;
@@ -563,13 +562,12 @@ struct bna_tx_mod {
563struct bna_rcb { 562struct bna_rcb {
564 /* Fast path */ 563 /* Fast path */
565 void **sw_qpt; 564 void **sw_qpt;
565 void *sw_q;
566 void *unmap_q; 566 void *unmap_q;
567 u32 producer_index; 567 u32 producer_index;
568 u32 consumer_index; 568 u32 consumer_index;
569 u32 q_depth; 569 u32 q_depth;
570 void __iomem *q_dbell; 570 void __iomem *q_dbell;
571 int page_idx;
572 int page_count;
573 /* Control path */ 571 /* Control path */
574 struct bna_rxq *rxq; 572 struct bna_rxq *rxq;
575 struct bna_ccb *ccb; 573 struct bna_ccb *ccb;
@@ -626,6 +624,7 @@ struct bna_pkt_rate {
626struct bna_ccb { 624struct bna_ccb {
627 /* Fast path */ 625 /* Fast path */
628 void **sw_qpt; 626 void **sw_qpt;
627 void *sw_q;
629 u32 producer_index; 628 u32 producer_index;
630 volatile u32 *hw_producer_index; 629 volatile u32 *hw_producer_index;
631 u32 q_depth; 630 u32 q_depth;
@@ -633,8 +632,6 @@ struct bna_ccb {
633 struct bna_rcb *rcb[2]; 632 struct bna_rcb *rcb[2];
634 void *ctrl; /* For bnad */ 633 void *ctrl; /* For bnad */
635 struct bna_pkt_rate pkt_rate; 634 struct bna_pkt_rate pkt_rate;
636 int page_idx;
637 int page_count;
638 635
639 /* Control path */ 636 /* Control path */
640 struct bna_cq *cq; 637 struct bna_cq *cq;
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c
index 092c4c5b8ffa..35a301330e5d 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.c
+++ b/drivers/net/ethernet/brocade/bna/bnad.c
@@ -61,23 +61,17 @@ static const u8 bnad_bcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
61/* 61/*
62 * Local MACROS 62 * Local MACROS
63 */ 63 */
64#define BNAD_TX_UNMAPQ_DEPTH (bnad->txq_depth * 2)
65
66#define BNAD_RX_UNMAPQ_DEPTH (bnad->rxq_depth)
67
68#define BNAD_GET_MBOX_IRQ(_bnad) \ 64#define BNAD_GET_MBOX_IRQ(_bnad) \
69 (((_bnad)->cfg_flags & BNAD_CF_MSIX) ? \ 65 (((_bnad)->cfg_flags & BNAD_CF_MSIX) ? \
70 ((_bnad)->msix_table[BNAD_MAILBOX_MSIX_INDEX].vector) : \ 66 ((_bnad)->msix_table[BNAD_MAILBOX_MSIX_INDEX].vector) : \
71 ((_bnad)->pcidev->irq)) 67 ((_bnad)->pcidev->irq))
72 68
73#define BNAD_FILL_UNMAPQ_MEM_REQ(_res_info, _num, _depth) \ 69#define BNAD_FILL_UNMAPQ_MEM_REQ(_res_info, _num, _size) \
74do { \ 70do { \
75 (_res_info)->res_type = BNA_RES_T_MEM; \ 71 (_res_info)->res_type = BNA_RES_T_MEM; \
76 (_res_info)->res_u.mem_info.mem_type = BNA_MEM_T_KVA; \ 72 (_res_info)->res_u.mem_info.mem_type = BNA_MEM_T_KVA; \
77 (_res_info)->res_u.mem_info.num = (_num); \ 73 (_res_info)->res_u.mem_info.num = (_num); \
78 (_res_info)->res_u.mem_info.len = \ 74 (_res_info)->res_u.mem_info.len = (_size); \
79 sizeof(struct bnad_unmap_q) + \
80 (sizeof(struct bnad_skb_unmap) * ((_depth) - 1)); \
81} while (0) 75} while (0)
82 76
83static void 77static void
@@ -103,48 +97,58 @@ bnad_remove_from_list(struct bnad *bnad)
103static void 97static void
104bnad_cq_cleanup(struct bnad *bnad, struct bna_ccb *ccb) 98bnad_cq_cleanup(struct bnad *bnad, struct bna_ccb *ccb)
105{ 99{
106 struct bna_cq_entry *cmpl, *next_cmpl; 100 struct bna_cq_entry *cmpl;
107 unsigned int wi_range, wis = 0, ccb_prod = 0;
108 int i; 101 int i;
109 102
110 BNA_CQ_QPGE_PTR_GET(ccb_prod, ccb->sw_qpt, cmpl,
111 wi_range);
112
113 for (i = 0; i < ccb->q_depth; i++) { 103 for (i = 0; i < ccb->q_depth; i++) {
114 wis++; 104 cmpl = &((struct bna_cq_entry *)ccb->sw_q)[i];
115 if (likely(--wi_range))
116 next_cmpl = cmpl + 1;
117 else {
118 BNA_QE_INDX_ADD(ccb_prod, wis, ccb->q_depth);
119 wis = 0;
120 BNA_CQ_QPGE_PTR_GET(ccb_prod, ccb->sw_qpt,
121 next_cmpl, wi_range);
122 }
123 cmpl->valid = 0; 105 cmpl->valid = 0;
124 cmpl = next_cmpl;
125 } 106 }
126} 107}
127 108
109/* Tx Datapath functions */
110
111
112/* Caller should ensure that the entry at unmap_q[index] is valid */
128static u32 113static u32
129bnad_pci_unmap_skb(struct device *pdev, struct bnad_skb_unmap *array, 114bnad_tx_buff_unmap(struct bnad *bnad,
130 u32 index, u32 depth, struct sk_buff *skb, u32 frag) 115 struct bnad_tx_unmap *unmap_q,
116 u32 q_depth, u32 index)
131{ 117{
132 int j; 118 struct bnad_tx_unmap *unmap;
133 array[index].skb = NULL; 119 struct sk_buff *skb;
134 120 int vector, nvecs;
135 dma_unmap_single(pdev, dma_unmap_addr(&array[index], dma_addr), 121
136 skb_headlen(skb), DMA_TO_DEVICE); 122 unmap = &unmap_q[index];
137 dma_unmap_addr_set(&array[index], dma_addr, 0); 123 nvecs = unmap->nvecs;
138 BNA_QE_INDX_ADD(index, 1, depth); 124
125 skb = unmap->skb;
126 unmap->skb = NULL;
127 unmap->nvecs = 0;
128 dma_unmap_single(&bnad->pcidev->dev,
129 dma_unmap_addr(&unmap->vectors[0], dma_addr),
130 skb_headlen(skb), DMA_TO_DEVICE);
131 dma_unmap_addr_set(&unmap->vectors[0], dma_addr, 0);
132 nvecs--;
133
134 vector = 0;
135 while (nvecs) {
136 vector++;
137 if (vector == BFI_TX_MAX_VECTORS_PER_WI) {
138 vector = 0;
139 BNA_QE_INDX_INC(index, q_depth);
140 unmap = &unmap_q[index];
141 }
139 142
140 for (j = 0; j < frag; j++) { 143 dma_unmap_page(&bnad->pcidev->dev,
141 dma_unmap_page(pdev, dma_unmap_addr(&array[index], dma_addr), 144 dma_unmap_addr(&unmap->vectors[vector], dma_addr),
142 skb_frag_size(&skb_shinfo(skb)->frags[j]), 145 skb_shinfo(skb)->frags[nvecs].size, DMA_TO_DEVICE);
143 DMA_TO_DEVICE); 146 dma_unmap_addr_set(&unmap->vectors[vector], dma_addr, 0);
144 dma_unmap_addr_set(&array[index], dma_addr, 0); 147 nvecs--;
145 BNA_QE_INDX_ADD(index, 1, depth);
146 } 148 }
147 149
150 BNA_QE_INDX_INC(index, q_depth);
151
148 return index; 152 return index;
149} 153}
150 154
@@ -154,79 +158,64 @@ bnad_pci_unmap_skb(struct device *pdev, struct bnad_skb_unmap *array,
154 * so DMA unmap & freeing is fine. 158 * so DMA unmap & freeing is fine.
155 */ 159 */
156static void 160static void
157bnad_txq_cleanup(struct bnad *bnad, 161bnad_txq_cleanup(struct bnad *bnad, struct bna_tcb *tcb)
158 struct bna_tcb *tcb)
159{ 162{
160 u32 unmap_cons; 163 struct bnad_tx_unmap *unmap_q = tcb->unmap_q;
161 struct bnad_unmap_q *unmap_q = tcb->unmap_q; 164 struct sk_buff *skb;
162 struct bnad_skb_unmap *unmap_array; 165 int i;
163 struct sk_buff *skb = NULL;
164 int q;
165
166 unmap_array = unmap_q->unmap_array;
167 166
168 for (q = 0; q < unmap_q->q_depth; q++) { 167 for (i = 0; i < tcb->q_depth; i++) {
169 skb = unmap_array[q].skb; 168 skb = unmap_q[i].skb;
170 if (!skb) 169 if (!skb)
171 continue; 170 continue;
172 171 bnad_tx_buff_unmap(bnad, unmap_q, tcb->q_depth, i);
173 unmap_cons = q;
174 unmap_cons = bnad_pci_unmap_skb(&bnad->pcidev->dev, unmap_array,
175 unmap_cons, unmap_q->q_depth, skb,
176 skb_shinfo(skb)->nr_frags);
177 172
178 dev_kfree_skb_any(skb); 173 dev_kfree_skb_any(skb);
179 } 174 }
180} 175}
181 176
182/* Data Path Handlers */
183
184/* 177/*
185 * bnad_txcmpl_process : Frees the Tx bufs on Tx completion 178 * bnad_txcmpl_process : Frees the Tx bufs on Tx completion
186 * Can be called in a) Interrupt context 179 * Can be called in a) Interrupt context
187 * b) Sending context 180 * b) Sending context
188 */ 181 */
189static u32 182static u32
190bnad_txcmpl_process(struct bnad *bnad, 183bnad_txcmpl_process(struct bnad *bnad, struct bna_tcb *tcb)
191 struct bna_tcb *tcb)
192{ 184{
193 u32 unmap_cons, sent_packets = 0, sent_bytes = 0; 185 u32 sent_packets = 0, sent_bytes = 0;
194 u16 wis, updated_hw_cons; 186 u32 wis, unmap_wis, hw_cons, cons, q_depth;
195 struct bnad_unmap_q *unmap_q = tcb->unmap_q; 187 struct bnad_tx_unmap *unmap_q = tcb->unmap_q;
196 struct bnad_skb_unmap *unmap_array; 188 struct bnad_tx_unmap *unmap;
197 struct sk_buff *skb; 189 struct sk_buff *skb;
198 190
199 /* Just return if TX is stopped */ 191 /* Just return if TX is stopped */
200 if (!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags)) 192 if (!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))
201 return 0; 193 return 0;
202 194
203 updated_hw_cons = *(tcb->hw_consumer_index); 195 hw_cons = *(tcb->hw_consumer_index);
204 196 cons = tcb->consumer_index;
205 wis = BNA_Q_INDEX_CHANGE(tcb->consumer_index, 197 q_depth = tcb->q_depth;
206 updated_hw_cons, tcb->q_depth);
207 198
199 wis = BNA_Q_INDEX_CHANGE(cons, hw_cons, q_depth);
208 BUG_ON(!(wis <= BNA_QE_IN_USE_CNT(tcb, tcb->q_depth))); 200 BUG_ON(!(wis <= BNA_QE_IN_USE_CNT(tcb, tcb->q_depth)));
209 201
210 unmap_array = unmap_q->unmap_array;
211 unmap_cons = unmap_q->consumer_index;
212
213 while (wis) { 202 while (wis) {
214 skb = unmap_array[unmap_cons].skb; 203 unmap = &unmap_q[cons];
204
205 skb = unmap->skb;
215 206
216 sent_packets++; 207 sent_packets++;
217 sent_bytes += skb->len; 208 sent_bytes += skb->len;
218 wis -= BNA_TXQ_WI_NEEDED(1 + skb_shinfo(skb)->nr_frags);
219 209
220 unmap_cons = bnad_pci_unmap_skb(&bnad->pcidev->dev, unmap_array, 210 unmap_wis = BNA_TXQ_WI_NEEDED(unmap->nvecs);
221 unmap_cons, unmap_q->q_depth, skb, 211 wis -= unmap_wis;
222 skb_shinfo(skb)->nr_frags);
223 212
213 cons = bnad_tx_buff_unmap(bnad, unmap_q, q_depth, cons);
224 dev_kfree_skb_any(skb); 214 dev_kfree_skb_any(skb);
225 } 215 }
226 216
227 /* Update consumer pointers. */ 217 /* Update consumer pointers. */
228 tcb->consumer_index = updated_hw_cons; 218 tcb->consumer_index = hw_cons;
229 unmap_q->consumer_index = unmap_cons;
230 219
231 tcb->txq->tx_packets += sent_packets; 220 tcb->txq->tx_packets += sent_packets;
232 tcb->txq->tx_bytes += sent_bytes; 221 tcb->txq->tx_bytes += sent_bytes;
@@ -278,110 +267,79 @@ bnad_msix_tx(int irq, void *data)
278} 267}
279 268
280static void 269static void
281bnad_rcb_cleanup(struct bnad *bnad, struct bna_rcb *rcb)
282{
283 struct bnad_unmap_q *unmap_q = rcb->unmap_q;
284
285 rcb->producer_index = 0;
286 rcb->consumer_index = 0;
287
288 unmap_q->producer_index = 0;
289 unmap_q->consumer_index = 0;
290}
291
292static void
293bnad_rxq_cleanup(struct bnad *bnad, struct bna_rcb *rcb) 270bnad_rxq_cleanup(struct bnad *bnad, struct bna_rcb *rcb)
294{ 271{
295 struct bnad_unmap_q *unmap_q; 272 struct bnad_rx_unmap *unmap_q = rcb->unmap_q;
296 struct bnad_skb_unmap *unmap_array;
297 struct sk_buff *skb; 273 struct sk_buff *skb;
298 int unmap_cons; 274 int i;
275
276 for (i = 0; i < rcb->q_depth; i++) {
277 struct bnad_rx_unmap *unmap = &unmap_q[i];
299 278
300 unmap_q = rcb->unmap_q; 279 skb = unmap->skb;
301 unmap_array = unmap_q->unmap_array;
302 for (unmap_cons = 0; unmap_cons < unmap_q->q_depth; unmap_cons++) {
303 skb = unmap_array[unmap_cons].skb;
304 if (!skb) 280 if (!skb)
305 continue; 281 continue;
306 unmap_array[unmap_cons].skb = NULL; 282
283 unmap->skb = NULL;
307 dma_unmap_single(&bnad->pcidev->dev, 284 dma_unmap_single(&bnad->pcidev->dev,
308 dma_unmap_addr(&unmap_array[unmap_cons], 285 dma_unmap_addr(&unmap->vector, dma_addr),
309 dma_addr), 286 unmap->vector.len, DMA_FROM_DEVICE);
310 rcb->rxq->buffer_size, 287 dma_unmap_addr_set(&unmap->vector, dma_addr, 0);
311 DMA_FROM_DEVICE); 288 unmap->vector.len = 0;
312 dev_kfree_skb(skb); 289 dev_kfree_skb_any(skb);
313 } 290 }
314 bnad_rcb_cleanup(bnad, rcb);
315} 291}
316 292
293/* Allocate and post BNAD_RXQ_REFILL_THRESHOLD_SHIFT buffers at a time */
317static void 294static void
318bnad_rxq_post(struct bnad *bnad, struct bna_rcb *rcb) 295bnad_rxq_post(struct bnad *bnad, struct bna_rcb *rcb)
319{ 296{
320 u16 to_alloc, alloced, unmap_prod, wi_range; 297 u32 to_alloc, alloced, prod, q_depth, buff_sz;
321 struct bnad_unmap_q *unmap_q = rcb->unmap_q; 298 struct bnad_rx_unmap *unmap_q = rcb->unmap_q;
322 struct bnad_skb_unmap *unmap_array; 299 struct bnad_rx_unmap *unmap;
323 struct bna_rxq_entry *rxent; 300 struct bna_rxq_entry *rxent;
324 struct sk_buff *skb; 301 struct sk_buff *skb;
325 dma_addr_t dma_addr; 302 dma_addr_t dma_addr;
326 303
304 buff_sz = rcb->rxq->buffer_size;
327 alloced = 0; 305 alloced = 0;
328 to_alloc = 306 to_alloc = BNA_QE_FREE_CNT(rcb, rcb->q_depth);
329 BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth); 307 if (!(to_alloc >> BNAD_RXQ_REFILL_THRESHOLD_SHIFT))
330 308 return;
331 unmap_array = unmap_q->unmap_array;
332 unmap_prod = unmap_q->producer_index;
333 309
334 BNA_RXQ_QPGE_PTR_GET(unmap_prod, rcb->sw_qpt, rxent, wi_range); 310 prod = rcb->producer_index;
311 q_depth = rcb->q_depth;
335 312
336 while (to_alloc--) { 313 while (to_alloc--) {
337 if (!wi_range)
338 BNA_RXQ_QPGE_PTR_GET(unmap_prod, rcb->sw_qpt, rxent,
339 wi_range);
340 skb = netdev_alloc_skb_ip_align(bnad->netdev, 314 skb = netdev_alloc_skb_ip_align(bnad->netdev,
341 rcb->rxq->buffer_size); 315 buff_sz);
342 if (unlikely(!skb)) { 316 if (unlikely(!skb)) {
343 BNAD_UPDATE_CTR(bnad, rxbuf_alloc_failed); 317 BNAD_UPDATE_CTR(bnad, rxbuf_alloc_failed);
344 rcb->rxq->rxbuf_alloc_failed++; 318 rcb->rxq->rxbuf_alloc_failed++;
345 goto finishing; 319 goto finishing;
346 } 320 }
347 unmap_array[unmap_prod].skb = skb;
348 dma_addr = dma_map_single(&bnad->pcidev->dev, skb->data, 321 dma_addr = dma_map_single(&bnad->pcidev->dev, skb->data,
349 rcb->rxq->buffer_size, 322 buff_sz, DMA_FROM_DEVICE);
350 DMA_FROM_DEVICE); 323 rxent = &((struct bna_rxq_entry *)rcb->sw_q)[prod];
351 dma_unmap_addr_set(&unmap_array[unmap_prod], dma_addr,
352 dma_addr);
353 BNA_SET_DMA_ADDR(dma_addr, &rxent->host_addr);
354 BNA_QE_INDX_ADD(unmap_prod, 1, unmap_q->q_depth);
355 324
356 rxent++; 325 BNA_SET_DMA_ADDR(dma_addr, &rxent->host_addr);
357 wi_range--; 326 unmap = &unmap_q[prod];
327 unmap->skb = skb;
328 dma_unmap_addr_set(&unmap->vector, dma_addr, dma_addr);
329 unmap->vector.len = buff_sz;
330 BNA_QE_INDX_INC(prod, q_depth);
358 alloced++; 331 alloced++;
359 } 332 }
360 333
361finishing: 334finishing:
362 if (likely(alloced)) { 335 if (likely(alloced)) {
363 unmap_q->producer_index = unmap_prod; 336 rcb->producer_index = prod;
364 rcb->producer_index = unmap_prod;
365 smp_mb(); 337 smp_mb();
366 if (likely(test_bit(BNAD_RXQ_POST_OK, &rcb->flags))) 338 if (likely(test_bit(BNAD_RXQ_POST_OK, &rcb->flags)))
367 bna_rxq_prod_indx_doorbell(rcb); 339 bna_rxq_prod_indx_doorbell(rcb);
368 } 340 }
369} 341}
370 342
371static inline void
372bnad_refill_rxq(struct bnad *bnad, struct bna_rcb *rcb)
373{
374 struct bnad_unmap_q *unmap_q = rcb->unmap_q;
375
376 if (!test_and_set_bit(BNAD_RXQ_REFILL, &rcb->flags)) {
377 if (BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth)
378 >> BNAD_RXQ_REFILL_THRESHOLD_SHIFT)
379 bnad_rxq_post(bnad, rcb);
380 smp_mb__before_clear_bit();
381 clear_bit(BNAD_RXQ_REFILL, &rcb->flags);
382 }
383}
384
385#define flags_cksum_prot_mask (BNA_CQ_EF_IPV4 | BNA_CQ_EF_L3_CKSUM_OK | \ 343#define flags_cksum_prot_mask (BNA_CQ_EF_IPV4 | BNA_CQ_EF_L3_CKSUM_OK | \
386 BNA_CQ_EF_IPV6 | \ 344 BNA_CQ_EF_IPV6 | \
387 BNA_CQ_EF_TCP | BNA_CQ_EF_UDP | \ 345 BNA_CQ_EF_TCP | BNA_CQ_EF_UDP | \
@@ -399,21 +357,21 @@ bnad_refill_rxq(struct bnad *bnad, struct bna_rcb *rcb)
399static u32 357static u32
400bnad_cq_process(struct bnad *bnad, struct bna_ccb *ccb, int budget) 358bnad_cq_process(struct bnad *bnad, struct bna_ccb *ccb, int budget)
401{ 359{
402 struct bna_cq_entry *cmpl, *next_cmpl; 360 struct bna_cq_entry *cq, *cmpl, *next_cmpl;
403 struct bna_rcb *rcb = NULL; 361 struct bna_rcb *rcb = NULL;
404 unsigned int wi_range, packets = 0, wis = 0; 362 struct bnad_rx_unmap *unmap_q, *unmap;
405 struct bnad_unmap_q *unmap_q; 363 unsigned int packets = 0;
406 struct bnad_skb_unmap *unmap_array, *curr_ua;
407 struct sk_buff *skb; 364 struct sk_buff *skb;
408 u32 flags, unmap_cons, masked_flags; 365 u32 flags, masked_flags;
409 struct bna_pkt_rate *pkt_rt = &ccb->pkt_rate; 366 struct bna_pkt_rate *pkt_rt = &ccb->pkt_rate;
410 struct bnad_rx_ctrl *rx_ctrl = (struct bnad_rx_ctrl *)(ccb->ctrl); 367 struct bnad_rx_ctrl *rx_ctrl = (struct bnad_rx_ctrl *)(ccb->ctrl);
411 368
412 prefetch(bnad->netdev); 369 prefetch(bnad->netdev);
413 BNA_CQ_QPGE_PTR_GET(ccb->producer_index, ccb->sw_qpt, cmpl, 370
414 wi_range); 371 cq = ccb->sw_q;
415 BUG_ON(!(wi_range <= ccb->q_depth)); 372 cmpl = &cq[ccb->producer_index];
416 while (cmpl->valid && packets < budget) { 373
374 while (cmpl->valid && (packets < budget)) {
417 packets++; 375 packets++;
418 BNA_UPDATE_PKT_CNT(pkt_rt, ntohs(cmpl->length)); 376 BNA_UPDATE_PKT_CNT(pkt_rt, ntohs(cmpl->length));
419 377
@@ -423,33 +381,19 @@ bnad_cq_process(struct bnad *bnad, struct bna_ccb *ccb, int budget)
423 rcb = ccb->rcb[0]; 381 rcb = ccb->rcb[0];
424 382
425 unmap_q = rcb->unmap_q; 383 unmap_q = rcb->unmap_q;
426 unmap_array = unmap_q->unmap_array; 384 unmap = &unmap_q[rcb->consumer_index];
427 unmap_cons = unmap_q->consumer_index;
428 385
429 curr_ua = &unmap_array[unmap_cons]; 386 skb = unmap->skb;
430
431 skb = curr_ua->skb;
432 BUG_ON(!(skb)); 387 BUG_ON(!(skb));
433 curr_ua->skb = NULL; 388 unmap->skb = NULL;
434 dma_unmap_single(&bnad->pcidev->dev, 389 dma_unmap_single(&bnad->pcidev->dev,
435 dma_unmap_addr(curr_ua, dma_addr), 390 dma_unmap_addr(&unmap->vector, dma_addr),
436 rcb->rxq->buffer_size, 391 unmap->vector.len, DMA_FROM_DEVICE);
437 DMA_FROM_DEVICE); 392 unmap->vector.len = 0;
438 BNA_QE_INDX_ADD(unmap_q->consumer_index, 1, unmap_q->q_depth); 393 BNA_QE_INDX_INC(rcb->consumer_index, rcb->q_depth);
439 394 BNA_QE_INDX_INC(ccb->producer_index, ccb->q_depth);
440 /* Should be more efficient ? Performance ? */ 395 next_cmpl = &cq[ccb->producer_index];
441 BNA_QE_INDX_ADD(rcb->consumer_index, 1, rcb->q_depth); 396
442
443 wis++;
444 if (likely(--wi_range))
445 next_cmpl = cmpl + 1;
446 else {
447 BNA_QE_INDX_ADD(ccb->producer_index, wis, ccb->q_depth);
448 wis = 0;
449 BNA_CQ_QPGE_PTR_GET(ccb->producer_index, ccb->sw_qpt,
450 next_cmpl, wi_range);
451 BUG_ON(!(wi_range <= ccb->q_depth));
452 }
453 prefetch(next_cmpl); 397 prefetch(next_cmpl);
454 398
455 flags = ntohl(cmpl->flags); 399 flags = ntohl(cmpl->flags);
@@ -493,16 +437,12 @@ next:
493 cmpl = next_cmpl; 437 cmpl = next_cmpl;
494 } 438 }
495 439
496 BNA_QE_INDX_ADD(ccb->producer_index, wis, ccb->q_depth);
497
498 if (likely(test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags))) 440 if (likely(test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags)))
499 bna_ib_ack_disable_irq(ccb->i_dbell, packets); 441 bna_ib_ack_disable_irq(ccb->i_dbell, packets);
500 442
501 bnad_refill_rxq(bnad, ccb->rcb[0]); 443 bnad_rxq_post(bnad, ccb->rcb[0]);
502 if (ccb->rcb[1]) 444 if (ccb->rcb[1])
503 bnad_refill_rxq(bnad, ccb->rcb[1]); 445 bnad_rxq_post(bnad, ccb->rcb[1]);
504
505 clear_bit(BNAD_FP_IN_RX_PATH, &rx_ctrl->flags);
506 446
507 return packets; 447 return packets;
508} 448}
@@ -777,12 +717,9 @@ bnad_cb_tcb_setup(struct bnad *bnad, struct bna_tcb *tcb)
777{ 717{
778 struct bnad_tx_info *tx_info = 718 struct bnad_tx_info *tx_info =
779 (struct bnad_tx_info *)tcb->txq->tx->priv; 719 (struct bnad_tx_info *)tcb->txq->tx->priv;
780 struct bnad_unmap_q *unmap_q = tcb->unmap_q;
781 720
721 tcb->priv = tcb;
782 tx_info->tcb[tcb->id] = tcb; 722 tx_info->tcb[tcb->id] = tcb;
783 unmap_q->producer_index = 0;
784 unmap_q->consumer_index = 0;
785 unmap_q->q_depth = BNAD_TX_UNMAPQ_DEPTH;
786} 723}
787 724
788static void 725static void
@@ -796,16 +733,6 @@ bnad_cb_tcb_destroy(struct bnad *bnad, struct bna_tcb *tcb)
796} 733}
797 734
798static void 735static void
799bnad_cb_rcb_setup(struct bnad *bnad, struct bna_rcb *rcb)
800{
801 struct bnad_unmap_q *unmap_q = rcb->unmap_q;
802
803 unmap_q->producer_index = 0;
804 unmap_q->consumer_index = 0;
805 unmap_q->q_depth = BNAD_RX_UNMAPQ_DEPTH;
806}
807
808static void
809bnad_cb_ccb_setup(struct bnad *bnad, struct bna_ccb *ccb) 736bnad_cb_ccb_setup(struct bnad *bnad, struct bna_ccb *ccb)
810{ 737{
811 struct bnad_rx_info *rx_info = 738 struct bnad_rx_info *rx_info =
@@ -891,10 +818,9 @@ bnad_tx_cleanup(struct delayed_work *work)
891 struct bnad_tx_info *tx_info = 818 struct bnad_tx_info *tx_info =
892 container_of(work, struct bnad_tx_info, tx_cleanup_work); 819 container_of(work, struct bnad_tx_info, tx_cleanup_work);
893 struct bnad *bnad = NULL; 820 struct bnad *bnad = NULL;
894 struct bnad_unmap_q *unmap_q;
895 struct bna_tcb *tcb; 821 struct bna_tcb *tcb;
896 unsigned long flags; 822 unsigned long flags;
897 uint32_t i, pending = 0; 823 u32 i, pending = 0;
898 824
899 for (i = 0; i < BNAD_MAX_TXQ_PER_TX; i++) { 825 for (i = 0; i < BNAD_MAX_TXQ_PER_TX; i++) {
900 tcb = tx_info->tcb[i]; 826 tcb = tx_info->tcb[i];
@@ -910,10 +836,6 @@ bnad_tx_cleanup(struct delayed_work *work)
910 836
911 bnad_txq_cleanup(bnad, tcb); 837 bnad_txq_cleanup(bnad, tcb);
912 838
913 unmap_q = tcb->unmap_q;
914 unmap_q->producer_index = 0;
915 unmap_q->consumer_index = 0;
916
917 smp_mb__before_clear_bit(); 839 smp_mb__before_clear_bit();
918 clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags); 840 clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
919 } 841 }
@@ -929,7 +851,6 @@ bnad_tx_cleanup(struct delayed_work *work)
929 spin_unlock_irqrestore(&bnad->bna_lock, flags); 851 spin_unlock_irqrestore(&bnad->bna_lock, flags);
930} 852}
931 853
932
933static void 854static void
934bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tx *tx) 855bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tx *tx)
935{ 856{
@@ -978,7 +899,7 @@ bnad_rx_cleanup(void *work)
978 struct bnad_rx_ctrl *rx_ctrl; 899 struct bnad_rx_ctrl *rx_ctrl;
979 struct bnad *bnad = NULL; 900 struct bnad *bnad = NULL;
980 unsigned long flags; 901 unsigned long flags;
981 uint32_t i; 902 u32 i;
982 903
983 for (i = 0; i < BNAD_MAX_RXP_PER_RX; i++) { 904 for (i = 0; i < BNAD_MAX_RXP_PER_RX; i++) {
984 rx_ctrl = &rx_info->rx_ctrl[i]; 905 rx_ctrl = &rx_info->rx_ctrl[i];
@@ -1035,7 +956,6 @@ bnad_cb_rx_post(struct bnad *bnad, struct bna_rx *rx)
1035 struct bna_ccb *ccb; 956 struct bna_ccb *ccb;
1036 struct bna_rcb *rcb; 957 struct bna_rcb *rcb;
1037 struct bnad_rx_ctrl *rx_ctrl; 958 struct bnad_rx_ctrl *rx_ctrl;
1038 struct bnad_unmap_q *unmap_q;
1039 int i; 959 int i;
1040 int j; 960 int j;
1041 961
@@ -1054,17 +974,7 @@ bnad_cb_rx_post(struct bnad *bnad, struct bna_rx *rx)
1054 974
1055 set_bit(BNAD_RXQ_STARTED, &rcb->flags); 975 set_bit(BNAD_RXQ_STARTED, &rcb->flags);
1056 set_bit(BNAD_RXQ_POST_OK, &rcb->flags); 976 set_bit(BNAD_RXQ_POST_OK, &rcb->flags);
1057 unmap_q = rcb->unmap_q; 977 bnad_rxq_post(bnad, rcb);
1058
1059 /* Now allocate & post buffers for this RCB */
1060 /* !!Allocation in callback context */
1061 if (!test_and_set_bit(BNAD_RXQ_REFILL, &rcb->flags)) {
1062 if (BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth)
1063 >> BNAD_RXQ_REFILL_THRESHOLD_SHIFT)
1064 bnad_rxq_post(bnad, rcb);
1065 smp_mb__before_clear_bit();
1066 clear_bit(BNAD_RXQ_REFILL, &rcb->flags);
1067 }
1068 } 978 }
1069 } 979 }
1070} 980}
@@ -1788,10 +1698,9 @@ bnad_setup_tx(struct bnad *bnad, u32 tx_id)
1788 spin_unlock_irqrestore(&bnad->bna_lock, flags); 1698 spin_unlock_irqrestore(&bnad->bna_lock, flags);
1789 1699
1790 /* Fill Unmap Q memory requirements */ 1700 /* Fill Unmap Q memory requirements */
1791 BNAD_FILL_UNMAPQ_MEM_REQ( 1701 BNAD_FILL_UNMAPQ_MEM_REQ(&res_info[BNA_TX_RES_MEM_T_UNMAPQ],
1792 &res_info[BNA_TX_RES_MEM_T_UNMAPQ], 1702 bnad->num_txq_per_tx, (sizeof(struct bnad_tx_unmap) *
1793 bnad->num_txq_per_tx, 1703 bnad->txq_depth));
1794 BNAD_TX_UNMAPQ_DEPTH);
1795 1704
1796 /* Allocate resources */ 1705 /* Allocate resources */
1797 err = bnad_tx_res_alloc(bnad, res_info, tx_id); 1706 err = bnad_tx_res_alloc(bnad, res_info, tx_id);
@@ -1929,7 +1838,7 @@ bnad_setup_rx(struct bnad *bnad, u32 rx_id)
1929 &res_info[BNA_RX_RES_T_INTR].res_u.intr_info; 1838 &res_info[BNA_RX_RES_T_INTR].res_u.intr_info;
1930 struct bna_rx_config *rx_config = &bnad->rx_config[rx_id]; 1839 struct bna_rx_config *rx_config = &bnad->rx_config[rx_id];
1931 static const struct bna_rx_event_cbfn rx_cbfn = { 1840 static const struct bna_rx_event_cbfn rx_cbfn = {
1932 .rcb_setup_cbfn = bnad_cb_rcb_setup, 1841 .rcb_setup_cbfn = NULL,
1933 .rcb_destroy_cbfn = NULL, 1842 .rcb_destroy_cbfn = NULL,
1934 .ccb_setup_cbfn = bnad_cb_ccb_setup, 1843 .ccb_setup_cbfn = bnad_cb_ccb_setup,
1935 .ccb_destroy_cbfn = bnad_cb_ccb_destroy, 1844 .ccb_destroy_cbfn = bnad_cb_ccb_destroy,
@@ -1951,11 +1860,10 @@ bnad_setup_rx(struct bnad *bnad, u32 rx_id)
1951 spin_unlock_irqrestore(&bnad->bna_lock, flags); 1860 spin_unlock_irqrestore(&bnad->bna_lock, flags);
1952 1861
1953 /* Fill Unmap Q memory requirements */ 1862 /* Fill Unmap Q memory requirements */
1954 BNAD_FILL_UNMAPQ_MEM_REQ( 1863 BNAD_FILL_UNMAPQ_MEM_REQ(&res_info[BNA_RX_RES_MEM_T_UNMAPQ],
1955 &res_info[BNA_RX_RES_MEM_T_UNMAPQ], 1864 rx_config->num_paths + ((rx_config->rxp_type == BNA_RXP_SINGLE)
1956 rx_config->num_paths + 1865 ? 0 : rx_config->num_paths), (bnad->rxq_depth *
1957 ((rx_config->rxp_type == BNA_RXP_SINGLE) ? 0 : 1866 sizeof(struct bnad_rx_unmap)));
1958 rx_config->num_paths), BNAD_RX_UNMAPQ_DEPTH);
1959 1867
1960 /* Allocate resource */ 1868 /* Allocate resource */
1961 err = bnad_rx_res_alloc(bnad, res_info, rx_id); 1869 err = bnad_rx_res_alloc(bnad, res_info, rx_id);
@@ -2536,125 +2444,34 @@ bnad_stop(struct net_device *netdev)
2536} 2444}
2537 2445
2538/* TX */ 2446/* TX */
2539/* 2447/* Returns 0 for success */
2540 * bnad_start_xmit : Netdev entry point for Transmit 2448static int
2541 * Called under lock held by net_device 2449bnad_txq_wi_prepare(struct bnad *bnad, struct bna_tcb *tcb,
2542 */ 2450 struct sk_buff *skb, struct bna_txq_entry *txqent)
2543static netdev_tx_t
2544bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
2545{ 2451{
2546 struct bnad *bnad = netdev_priv(netdev); 2452 u16 flags = 0;
2547 u32 txq_id = 0; 2453 u32 gso_size;
2548 struct bna_tcb *tcb = bnad->tx_info[0].tcb[txq_id]; 2454 u16 vlan_tag = 0;
2549
2550 u16 txq_prod, vlan_tag = 0;
2551 u32 unmap_prod, wis, wis_used, wi_range;
2552 u32 vectors, vect_id, i, acked;
2553 int err;
2554 unsigned int len;
2555 u32 gso_size;
2556
2557 struct bnad_unmap_q *unmap_q = tcb->unmap_q;
2558 dma_addr_t dma_addr;
2559 struct bna_txq_entry *txqent;
2560 u16 flags;
2561
2562 if (unlikely(skb->len <= ETH_HLEN)) {
2563 dev_kfree_skb(skb);
2564 BNAD_UPDATE_CTR(bnad, tx_skb_too_short);
2565 return NETDEV_TX_OK;
2566 }
2567 if (unlikely(skb_headlen(skb) > BFI_TX_MAX_DATA_PER_VECTOR)) {
2568 dev_kfree_skb(skb);
2569 BNAD_UPDATE_CTR(bnad, tx_skb_headlen_too_long);
2570 return NETDEV_TX_OK;
2571 }
2572 if (unlikely(skb_headlen(skb) == 0)) {
2573 dev_kfree_skb(skb);
2574 BNAD_UPDATE_CTR(bnad, tx_skb_headlen_zero);
2575 return NETDEV_TX_OK;
2576 }
2577
2578 /*
2579 * Takes care of the Tx that is scheduled between clearing the flag
2580 * and the netif_tx_stop_all_queues() call.
2581 */
2582 if (unlikely(!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))) {
2583 dev_kfree_skb(skb);
2584 BNAD_UPDATE_CTR(bnad, tx_skb_stopping);
2585 return NETDEV_TX_OK;
2586 }
2587
2588 vectors = 1 + skb_shinfo(skb)->nr_frags;
2589 if (unlikely(vectors > BFI_TX_MAX_VECTORS_PER_PKT)) {
2590 dev_kfree_skb(skb);
2591 BNAD_UPDATE_CTR(bnad, tx_skb_max_vectors);
2592 return NETDEV_TX_OK;
2593 }
2594 wis = BNA_TXQ_WI_NEEDED(vectors); /* 4 vectors per work item */
2595 acked = 0;
2596 if (unlikely(wis > BNA_QE_FREE_CNT(tcb, tcb->q_depth) ||
2597 vectors > BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth))) {
2598 if ((u16) (*tcb->hw_consumer_index) !=
2599 tcb->consumer_index &&
2600 !test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) {
2601 acked = bnad_txcmpl_process(bnad, tcb);
2602 if (likely(test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags)))
2603 bna_ib_ack(tcb->i_dbell, acked);
2604 smp_mb__before_clear_bit();
2605 clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
2606 } else {
2607 netif_stop_queue(netdev);
2608 BNAD_UPDATE_CTR(bnad, netif_queue_stop);
2609 }
2610
2611 smp_mb();
2612 /*
2613 * Check again to deal with race condition between
2614 * netif_stop_queue here, and netif_wake_queue in
2615 * interrupt handler which is not inside netif tx lock.
2616 */
2617 if (likely
2618 (wis > BNA_QE_FREE_CNT(tcb, tcb->q_depth) ||
2619 vectors > BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth))) {
2620 BNAD_UPDATE_CTR(bnad, netif_queue_stop);
2621 return NETDEV_TX_BUSY;
2622 } else {
2623 netif_wake_queue(netdev);
2624 BNAD_UPDATE_CTR(bnad, netif_queue_wakeup);
2625 }
2626 }
2627
2628 unmap_prod = unmap_q->producer_index;
2629 flags = 0;
2630
2631 txq_prod = tcb->producer_index;
2632 BNA_TXQ_QPGE_PTR_GET(txq_prod, tcb->sw_qpt, txqent, wi_range);
2633 txqent->hdr.wi.reserved = 0;
2634 txqent->hdr.wi.num_vectors = vectors;
2635 2455
2636 if (vlan_tx_tag_present(skb)) { 2456 if (vlan_tx_tag_present(skb)) {
2637 vlan_tag = (u16) vlan_tx_tag_get(skb); 2457 vlan_tag = (u16)vlan_tx_tag_get(skb);
2638 flags |= (BNA_TXQ_WI_CF_INS_PRIO | BNA_TXQ_WI_CF_INS_VLAN); 2458 flags |= (BNA_TXQ_WI_CF_INS_PRIO | BNA_TXQ_WI_CF_INS_VLAN);
2639 } 2459 }
2640 if (test_bit(BNAD_RF_CEE_RUNNING, &bnad->run_flags)) { 2460 if (test_bit(BNAD_RF_CEE_RUNNING, &bnad->run_flags)) {
2641 vlan_tag = 2461 vlan_tag = ((tcb->priority & 0x7) << VLAN_PRIO_SHIFT)
2642 (tcb->priority & 0x7) << 13 | (vlan_tag & 0x1fff); 2462 | (vlan_tag & 0x1fff);
2643 flags |= (BNA_TXQ_WI_CF_INS_PRIO | BNA_TXQ_WI_CF_INS_VLAN); 2463 flags |= (BNA_TXQ_WI_CF_INS_PRIO | BNA_TXQ_WI_CF_INS_VLAN);
2644 } 2464 }
2645
2646 txqent->hdr.wi.vlan_tag = htons(vlan_tag); 2465 txqent->hdr.wi.vlan_tag = htons(vlan_tag);
2647 2466
2648 if (skb_is_gso(skb)) { 2467 if (skb_is_gso(skb)) {
2649 gso_size = skb_shinfo(skb)->gso_size; 2468 gso_size = skb_shinfo(skb)->gso_size;
2650 2469 if (unlikely(gso_size > bnad->netdev->mtu)) {
2651 if (unlikely(gso_size > netdev->mtu)) {
2652 dev_kfree_skb(skb);
2653 BNAD_UPDATE_CTR(bnad, tx_skb_mss_too_long); 2470 BNAD_UPDATE_CTR(bnad, tx_skb_mss_too_long);
2654 return NETDEV_TX_OK; 2471 return -EINVAL;
2655 } 2472 }
2656 if (unlikely((gso_size + skb_transport_offset(skb) + 2473 if (unlikely((gso_size + skb_transport_offset(skb) +
2657 tcp_hdrlen(skb)) >= skb->len)) { 2474 tcp_hdrlen(skb)) >= skb->len)) {
2658 txqent->hdr.wi.opcode = 2475 txqent->hdr.wi.opcode =
2659 __constant_htons(BNA_TXQ_WI_SEND); 2476 __constant_htons(BNA_TXQ_WI_SEND);
2660 txqent->hdr.wi.lso_mss = 0; 2477 txqent->hdr.wi.lso_mss = 0;
@@ -2665,25 +2482,22 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
2665 txqent->hdr.wi.lso_mss = htons(gso_size); 2482 txqent->hdr.wi.lso_mss = htons(gso_size);
2666 } 2483 }
2667 2484
2668 err = bnad_tso_prepare(bnad, skb); 2485 if (bnad_tso_prepare(bnad, skb)) {
2669 if (unlikely(err)) {
2670 dev_kfree_skb(skb);
2671 BNAD_UPDATE_CTR(bnad, tx_skb_tso_prepare); 2486 BNAD_UPDATE_CTR(bnad, tx_skb_tso_prepare);
2672 return NETDEV_TX_OK; 2487 return -EINVAL;
2673 } 2488 }
2489
2674 flags |= (BNA_TXQ_WI_CF_IP_CKSUM | BNA_TXQ_WI_CF_TCP_CKSUM); 2490 flags |= (BNA_TXQ_WI_CF_IP_CKSUM | BNA_TXQ_WI_CF_TCP_CKSUM);
2675 txqent->hdr.wi.l4_hdr_size_n_offset = 2491 txqent->hdr.wi.l4_hdr_size_n_offset =
2676 htons(BNA_TXQ_WI_L4_HDR_N_OFFSET 2492 htons(BNA_TXQ_WI_L4_HDR_N_OFFSET(
2677 (tcp_hdrlen(skb) >> 2, 2493 tcp_hdrlen(skb) >> 2, skb_transport_offset(skb)));
2678 skb_transport_offset(skb))); 2494 } else {
2679 } else {
2680 txqent->hdr.wi.opcode = __constant_htons(BNA_TXQ_WI_SEND); 2495 txqent->hdr.wi.opcode = __constant_htons(BNA_TXQ_WI_SEND);
2681 txqent->hdr.wi.lso_mss = 0; 2496 txqent->hdr.wi.lso_mss = 0;
2682 2497
2683 if (unlikely(skb->len > (netdev->mtu + ETH_HLEN))) { 2498 if (unlikely(skb->len > (bnad->netdev->mtu + ETH_HLEN))) {
2684 dev_kfree_skb(skb);
2685 BNAD_UPDATE_CTR(bnad, tx_skb_non_tso_too_long); 2499 BNAD_UPDATE_CTR(bnad, tx_skb_non_tso_too_long);
2686 return NETDEV_TX_OK; 2500 return -EINVAL;
2687 } 2501 }
2688 2502
2689 if (skb->ip_summed == CHECKSUM_PARTIAL) { 2503 if (skb->ip_summed == CHECKSUM_PARTIAL) {
@@ -2691,11 +2505,13 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
2691 2505
2692 if (skb->protocol == __constant_htons(ETH_P_IP)) 2506 if (skb->protocol == __constant_htons(ETH_P_IP))
2693 proto = ip_hdr(skb)->protocol; 2507 proto = ip_hdr(skb)->protocol;
2508#ifdef NETIF_F_IPV6_CSUM
2694 else if (skb->protocol == 2509 else if (skb->protocol ==
2695 __constant_htons(ETH_P_IPV6)) { 2510 __constant_htons(ETH_P_IPV6)) {
2696 /* nexthdr may not be TCP immediately. */ 2511 /* nexthdr may not be TCP immediately. */
2697 proto = ipv6_hdr(skb)->nexthdr; 2512 proto = ipv6_hdr(skb)->nexthdr;
2698 } 2513 }
2514#endif
2699 if (proto == IPPROTO_TCP) { 2515 if (proto == IPPROTO_TCP) {
2700 flags |= BNA_TXQ_WI_CF_TCP_CKSUM; 2516 flags |= BNA_TXQ_WI_CF_TCP_CKSUM;
2701 txqent->hdr.wi.l4_hdr_size_n_offset = 2517 txqent->hdr.wi.l4_hdr_size_n_offset =
@@ -2705,12 +2521,11 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
2705 BNAD_UPDATE_CTR(bnad, tcpcsum_offload); 2521 BNAD_UPDATE_CTR(bnad, tcpcsum_offload);
2706 2522
2707 if (unlikely(skb_headlen(skb) < 2523 if (unlikely(skb_headlen(skb) <
2708 skb_transport_offset(skb) + tcp_hdrlen(skb))) { 2524 skb_transport_offset(skb) +
2709 dev_kfree_skb(skb); 2525 tcp_hdrlen(skb))) {
2710 BNAD_UPDATE_CTR(bnad, tx_skb_tcp_hdr); 2526 BNAD_UPDATE_CTR(bnad, tx_skb_tcp_hdr);
2711 return NETDEV_TX_OK; 2527 return -EINVAL;
2712 } 2528 }
2713
2714 } else if (proto == IPPROTO_UDP) { 2529 } else if (proto == IPPROTO_UDP) {
2715 flags |= BNA_TXQ_WI_CF_UDP_CKSUM; 2530 flags |= BNA_TXQ_WI_CF_UDP_CKSUM;
2716 txqent->hdr.wi.l4_hdr_size_n_offset = 2531 txqent->hdr.wi.l4_hdr_size_n_offset =
@@ -2719,51 +2534,149 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
2719 2534
2720 BNAD_UPDATE_CTR(bnad, udpcsum_offload); 2535 BNAD_UPDATE_CTR(bnad, udpcsum_offload);
2721 if (unlikely(skb_headlen(skb) < 2536 if (unlikely(skb_headlen(skb) <
2722 skb_transport_offset(skb) + 2537 skb_transport_offset(skb) +
2723 sizeof(struct udphdr))) { 2538 sizeof(struct udphdr))) {
2724 dev_kfree_skb(skb);
2725 BNAD_UPDATE_CTR(bnad, tx_skb_udp_hdr); 2539 BNAD_UPDATE_CTR(bnad, tx_skb_udp_hdr);
2726 return NETDEV_TX_OK; 2540 return -EINVAL;
2727 } 2541 }
2728 } else { 2542 } else {
2729 dev_kfree_skb(skb); 2543
2730 BNAD_UPDATE_CTR(bnad, tx_skb_csum_err); 2544 BNAD_UPDATE_CTR(bnad, tx_skb_csum_err);
2731 return NETDEV_TX_OK; 2545 return -EINVAL;
2732 } 2546 }
2733 } else { 2547 } else
2734 txqent->hdr.wi.l4_hdr_size_n_offset = 0; 2548 txqent->hdr.wi.l4_hdr_size_n_offset = 0;
2735 }
2736 } 2549 }
2737 2550
2738 txqent->hdr.wi.flags = htons(flags); 2551 txqent->hdr.wi.flags = htons(flags);
2739
2740 txqent->hdr.wi.frame_length = htonl(skb->len); 2552 txqent->hdr.wi.frame_length = htonl(skb->len);
2741 2553
2742 unmap_q->unmap_array[unmap_prod].skb = skb; 2554 return 0;
2555}
2556
2557/*
2558 * bnad_start_xmit : Netdev entry point for Transmit
2559 * Called under lock held by net_device
2560 */
2561static netdev_tx_t
2562bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
2563{
2564 struct bnad *bnad = netdev_priv(netdev);
2565 u32 txq_id = 0;
2566 struct bna_tcb *tcb = NULL;
2567 struct bnad_tx_unmap *unmap_q, *unmap, *head_unmap;
2568 u32 prod, q_depth, vect_id;
2569 u32 wis, vectors, len;
2570 int i;
2571 dma_addr_t dma_addr;
2572 struct bna_txq_entry *txqent;
2573
2743 len = skb_headlen(skb); 2574 len = skb_headlen(skb);
2744 txqent->vector[0].length = htons(len);
2745 dma_addr = dma_map_single(&bnad->pcidev->dev, skb->data,
2746 skb_headlen(skb), DMA_TO_DEVICE);
2747 dma_unmap_addr_set(&unmap_q->unmap_array[unmap_prod], dma_addr,
2748 dma_addr);
2749 2575
2750 BNA_SET_DMA_ADDR(dma_addr, &txqent->vector[0].host_addr); 2576 /* Sanity checks for the skb */
2751 BNA_QE_INDX_ADD(unmap_prod, 1, unmap_q->q_depth); 2577
2578 if (unlikely(skb->len <= ETH_HLEN)) {
2579 dev_kfree_skb(skb);
2580 BNAD_UPDATE_CTR(bnad, tx_skb_too_short);
2581 return NETDEV_TX_OK;
2582 }
2583 if (unlikely(len > BFI_TX_MAX_DATA_PER_VECTOR)) {
2584 dev_kfree_skb(skb);
2585 BNAD_UPDATE_CTR(bnad, tx_skb_headlen_zero);
2586 return NETDEV_TX_OK;
2587 }
2588 if (unlikely(len == 0)) {
2589 dev_kfree_skb(skb);
2590 BNAD_UPDATE_CTR(bnad, tx_skb_headlen_zero);
2591 return NETDEV_TX_OK;
2592 }
2593
2594 tcb = bnad->tx_info[0].tcb[txq_id];
2595 q_depth = tcb->q_depth;
2596 prod = tcb->producer_index;
2752 2597
2753 vect_id = 0; 2598 unmap_q = tcb->unmap_q;
2754 wis_used = 1;
2755 2599
2756 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 2600 /*
2601 * Takes care of the Tx that is scheduled between clearing the flag
2602 * and the netif_tx_stop_all_queues() call.
2603 */
2604 if (unlikely(!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))) {
2605 dev_kfree_skb(skb);
2606 BNAD_UPDATE_CTR(bnad, tx_skb_stopping);
2607 return NETDEV_TX_OK;
2608 }
2609
2610 vectors = 1 + skb_shinfo(skb)->nr_frags;
2611 wis = BNA_TXQ_WI_NEEDED(vectors); /* 4 vectors per work item */
2612
2613 if (unlikely(vectors > BFI_TX_MAX_VECTORS_PER_PKT)) {
2614 dev_kfree_skb(skb);
2615 BNAD_UPDATE_CTR(bnad, tx_skb_max_vectors);
2616 return NETDEV_TX_OK;
2617 }
2618
2619 /* Check for available TxQ resources */
2620 if (unlikely(wis > BNA_QE_FREE_CNT(tcb, q_depth))) {
2621 if ((*tcb->hw_consumer_index != tcb->consumer_index) &&
2622 !test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) {
2623 u32 sent;
2624 sent = bnad_txcmpl_process(bnad, tcb);
2625 if (likely(test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags)))
2626 bna_ib_ack(tcb->i_dbell, sent);
2627 smp_mb__before_clear_bit();
2628 clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
2629 } else {
2630 netif_stop_queue(netdev);
2631 BNAD_UPDATE_CTR(bnad, netif_queue_stop);
2632 }
2633
2634 smp_mb();
2635 /*
2636 * Check again to deal with race condition between
2637 * netif_stop_queue here, and netif_wake_queue in
2638 * interrupt handler which is not inside netif tx lock.
2639 */
2640 if (likely(wis > BNA_QE_FREE_CNT(tcb, q_depth))) {
2641 BNAD_UPDATE_CTR(bnad, netif_queue_stop);
2642 return NETDEV_TX_BUSY;
2643 } else {
2644 netif_wake_queue(netdev);
2645 BNAD_UPDATE_CTR(bnad, netif_queue_wakeup);
2646 }
2647 }
2648
2649 txqent = &((struct bna_txq_entry *)tcb->sw_q)[prod];
2650 head_unmap = &unmap_q[prod];
2651
2652 /* Program the opcode, flags, frame_len, num_vectors in WI */
2653 if (bnad_txq_wi_prepare(bnad, tcb, skb, txqent)) {
2654 dev_kfree_skb(skb);
2655 return NETDEV_TX_OK;
2656 }
2657 txqent->hdr.wi.reserved = 0;
2658 txqent->hdr.wi.num_vectors = vectors;
2659
2660 head_unmap->skb = skb;
2661 head_unmap->nvecs = 0;
2662
2663 /* Program the vectors */
2664 unmap = head_unmap;
2665 dma_addr = dma_map_single(&bnad->pcidev->dev, skb->data,
2666 len, DMA_TO_DEVICE);
2667 BNA_SET_DMA_ADDR(dma_addr, &txqent->vector[0].host_addr);
2668 txqent->vector[0].length = htons(len);
2669 dma_unmap_addr_set(&unmap->vectors[0], dma_addr, dma_addr);
2670 head_unmap->nvecs++;
2671
2672 for (i = 0, vect_id = 0; i < vectors - 1; i++) {
2757 const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; 2673 const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
2758 u16 size = skb_frag_size(frag); 2674 u16 size = skb_frag_size(frag);
2759 2675
2760 if (unlikely(size == 0)) { 2676 if (unlikely(size == 0)) {
2761 unmap_prod = unmap_q->producer_index; 2677 /* Undo the changes starting at tcb->producer_index */
2762 2678 bnad_tx_buff_unmap(bnad, unmap_q, q_depth,
2763 unmap_prod = bnad_pci_unmap_skb(&bnad->pcidev->dev, 2679 tcb->producer_index);
2764 unmap_q->unmap_array,
2765 unmap_prod, unmap_q->q_depth, skb,
2766 i);
2767 dev_kfree_skb(skb); 2680 dev_kfree_skb(skb);
2768 BNAD_UPDATE_CTR(bnad, tx_skb_frag_zero); 2681 BNAD_UPDATE_CTR(bnad, tx_skb_frag_zero);
2769 return NETDEV_TX_OK; 2682 return NETDEV_TX_OK;
@@ -2771,47 +2684,35 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
2771 2684
2772 len += size; 2685 len += size;
2773 2686
2774 if (++vect_id == BFI_TX_MAX_VECTORS_PER_WI) { 2687 vect_id++;
2688 if (vect_id == BFI_TX_MAX_VECTORS_PER_WI) {
2775 vect_id = 0; 2689 vect_id = 0;
2776 if (--wi_range) 2690 BNA_QE_INDX_INC(prod, q_depth);
2777 txqent++; 2691 txqent = &((struct bna_txq_entry *)tcb->sw_q)[prod];
2778 else {
2779 BNA_QE_INDX_ADD(txq_prod, wis_used,
2780 tcb->q_depth);
2781 wis_used = 0;
2782 BNA_TXQ_QPGE_PTR_GET(txq_prod, tcb->sw_qpt,
2783 txqent, wi_range);
2784 }
2785 wis_used++;
2786 txqent->hdr.wi_ext.opcode = 2692 txqent->hdr.wi_ext.opcode =
2787 __constant_htons(BNA_TXQ_WI_EXTENSION); 2693 __constant_htons(BNA_TXQ_WI_EXTENSION);
2694 unmap = &unmap_q[prod];
2788 } 2695 }
2789 2696
2790 BUG_ON(!(size <= BFI_TX_MAX_DATA_PER_VECTOR));
2791 txqent->vector[vect_id].length = htons(size);
2792 dma_addr = skb_frag_dma_map(&bnad->pcidev->dev, frag, 2697 dma_addr = skb_frag_dma_map(&bnad->pcidev->dev, frag,
2793 0, size, DMA_TO_DEVICE); 2698 0, size, DMA_TO_DEVICE);
2794 dma_unmap_addr_set(&unmap_q->unmap_array[unmap_prod], dma_addr,
2795 dma_addr);
2796 BNA_SET_DMA_ADDR(dma_addr, &txqent->vector[vect_id].host_addr); 2699 BNA_SET_DMA_ADDR(dma_addr, &txqent->vector[vect_id].host_addr);
2797 BNA_QE_INDX_ADD(unmap_prod, 1, unmap_q->q_depth); 2700 txqent->vector[vect_id].length = htons(size);
2701 dma_unmap_addr_set(&unmap->vectors[vect_id], dma_addr,
2702 dma_addr);
2703 head_unmap->nvecs++;
2798 } 2704 }
2799 2705
2800 if (unlikely(len != skb->len)) { 2706 if (unlikely(len != skb->len)) {
2801 unmap_prod = unmap_q->producer_index; 2707 /* Undo the changes starting at tcb->producer_index */
2802 2708 bnad_tx_buff_unmap(bnad, unmap_q, q_depth, tcb->producer_index);
2803 unmap_prod = bnad_pci_unmap_skb(&bnad->pcidev->dev,
2804 unmap_q->unmap_array, unmap_prod,
2805 unmap_q->q_depth, skb,
2806 skb_shinfo(skb)->nr_frags);
2807 dev_kfree_skb(skb); 2709 dev_kfree_skb(skb);
2808 BNAD_UPDATE_CTR(bnad, tx_skb_len_mismatch); 2710 BNAD_UPDATE_CTR(bnad, tx_skb_len_mismatch);
2809 return NETDEV_TX_OK; 2711 return NETDEV_TX_OK;
2810 } 2712 }
2811 2713
2812 unmap_q->producer_index = unmap_prod; 2714 BNA_QE_INDX_INC(prod, q_depth);
2813 BNA_QE_INDX_ADD(txq_prod, wis_used, tcb->q_depth); 2715 tcb->producer_index = prod;
2814 tcb->producer_index = txq_prod;
2815 2716
2816 smp_mb(); 2717 smp_mb();
2817 2718
@@ -3333,7 +3234,6 @@ bnad_pci_probe(struct pci_dev *pdev,
3333 if (err) 3234 if (err)
3334 goto res_free; 3235 goto res_free;
3335 3236
3336
3337 /* Set up timers */ 3237 /* Set up timers */
3338 setup_timer(&bnad->bna.ioceth.ioc.ioc_timer, bnad_ioc_timeout, 3238 setup_timer(&bnad->bna.ioceth.ioc.ioc_timer, bnad_ioc_timeout,
3339 ((unsigned long)bnad)); 3239 ((unsigned long)bnad));
diff --git a/drivers/net/ethernet/brocade/bna/bnad.h b/drivers/net/ethernet/brocade/bna/bnad.h
index 367b3a1eff0e..670a0790a183 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.h
+++ b/drivers/net/ethernet/brocade/bna/bnad.h
@@ -83,12 +83,9 @@ struct bnad_rx_ctrl {
83 83
84#define BNAD_IOCETH_TIMEOUT 10000 84#define BNAD_IOCETH_TIMEOUT 10000
85 85
86#define BNAD_MAX_Q_DEPTH 0x10000 86#define BNAD_MIN_Q_DEPTH 512
87#define BNAD_MIN_Q_DEPTH 0x200 87#define BNAD_MAX_RXQ_DEPTH 2048
88 88#define BNAD_MAX_TXQ_DEPTH 2048
89#define BNAD_MAX_RXQ_DEPTH (BNAD_MAX_Q_DEPTH / bnad_rxqs_per_cq)
90/* keeping MAX TX and RX Q depth equal */
91#define BNAD_MAX_TXQ_DEPTH BNAD_MAX_RXQ_DEPTH
92 89
93#define BNAD_JUMBO_MTU 9000 90#define BNAD_JUMBO_MTU 9000
94 91
@@ -101,9 +98,8 @@ struct bnad_rx_ctrl {
101#define BNAD_TXQ_TX_STARTED 1 98#define BNAD_TXQ_TX_STARTED 1
102 99
103/* Bit positions for rcb->flags */ 100/* Bit positions for rcb->flags */
104#define BNAD_RXQ_REFILL 0 101#define BNAD_RXQ_STARTED 0
105#define BNAD_RXQ_STARTED 1 102#define BNAD_RXQ_POST_OK 1
106#define BNAD_RXQ_POST_OK 2
107 103
108/* Resource limits */ 104/* Resource limits */
109#define BNAD_NUM_TXQ (bnad->num_tx * bnad->num_txq_per_tx) 105#define BNAD_NUM_TXQ (bnad->num_tx * bnad->num_txq_per_tx)
@@ -221,18 +217,24 @@ struct bnad_rx_info {
221 struct work_struct rx_cleanup_work; 217 struct work_struct rx_cleanup_work;
222} ____cacheline_aligned; 218} ____cacheline_aligned;
223 219
224/* Unmap queues for Tx / Rx cleanup */ 220struct bnad_tx_vector {
225struct bnad_skb_unmap { 221 DEFINE_DMA_UNMAP_ADDR(dma_addr);
222};
223
224struct bnad_tx_unmap {
226 struct sk_buff *skb; 225 struct sk_buff *skb;
226 u32 nvecs;
227 struct bnad_tx_vector vectors[BFI_TX_MAX_VECTORS_PER_WI];
228};
229
230struct bnad_rx_vector {
227 DEFINE_DMA_UNMAP_ADDR(dma_addr); 231 DEFINE_DMA_UNMAP_ADDR(dma_addr);
232 u32 len;
228}; 233};
229 234
230struct bnad_unmap_q { 235struct bnad_rx_unmap {
231 u32 producer_index; 236 struct sk_buff *skb;
232 u32 consumer_index; 237 struct bnad_rx_vector vector;
233 u32 q_depth;
234 /* This should be the last one */
235 struct bnad_skb_unmap unmap_array[1];
236}; 238};
237 239
238/* Bit mask values for bnad->cfg_flags */ 240/* Bit mask values for bnad->cfg_flags */
@@ -252,11 +254,6 @@ struct bnad_unmap_q {
252#define BNAD_RF_STATS_TIMER_RUNNING 5 254#define BNAD_RF_STATS_TIMER_RUNNING 5
253#define BNAD_RF_TX_PRIO_SET 6 255#define BNAD_RF_TX_PRIO_SET 6
254 256
255
256/* Define for Fast Path flags */
257/* Defined as bit positions */
258#define BNAD_FP_IN_RX_PATH 0
259
260struct bnad { 257struct bnad {
261 struct net_device *netdev; 258 struct net_device *netdev;
262 u32 id; 259 u32 id;