diff options
author | Rasesh Mody <rmody@brocade.com> | 2012-12-11 07:24:51 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-12-11 18:25:47 -0500 |
commit | 5216562a2ccd037d0eb85a2e8bbfd6315e3f1bb5 (patch) | |
tree | 6c22d90daca6d7684f97fdbe331ced936569beaa | |
parent | 5e46631fdb1e5611969c1e61106a59a3b38af078 (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.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/brocade/bna/bna_tx_rx.c | 109 | ||||
-rw-r--r-- | drivers/net/ethernet/brocade/bna/bna_types.h | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/brocade/bna/bnad.c | 688 | ||||
-rw-r--r-- | drivers/net/ethernet/brocade/bna/bnad.h | 41 |
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 { | |||
430 | struct bna_tcb { | 430 | struct 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 { | |||
563 | struct bna_rcb { | 562 | struct 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 { | |||
626 | struct bna_ccb { | 624 | struct 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) \ |
74 | do { \ | 70 | do { \ |
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 | ||
83 | static void | 77 | static void |
@@ -103,48 +97,58 @@ bnad_remove_from_list(struct bnad *bnad) | |||
103 | static void | 97 | static void |
104 | bnad_cq_cleanup(struct bnad *bnad, struct bna_ccb *ccb) | 98 | bnad_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 */ | ||
128 | static u32 | 113 | static u32 |
129 | bnad_pci_unmap_skb(struct device *pdev, struct bnad_skb_unmap *array, | 114 | bnad_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 | */ |
156 | static void | 160 | static void |
157 | bnad_txq_cleanup(struct bnad *bnad, | 161 | bnad_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 | */ |
189 | static u32 | 182 | static u32 |
190 | bnad_txcmpl_process(struct bnad *bnad, | 183 | bnad_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 | ||
280 | static void | 269 | static void |
281 | bnad_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 | |||
292 | static void | ||
293 | bnad_rxq_cleanup(struct bnad *bnad, struct bna_rcb *rcb) | 270 | bnad_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 */ | ||
317 | static void | 294 | static void |
318 | bnad_rxq_post(struct bnad *bnad, struct bna_rcb *rcb) | 295 | bnad_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 | ||
361 | finishing: | 334 | finishing: |
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 | ||
371 | static inline void | ||
372 | bnad_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) | |||
399 | static u32 | 357 | static u32 |
400 | bnad_cq_process(struct bnad *bnad, struct bna_ccb *ccb, int budget) | 358 | bnad_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 | ||
788 | static void | 725 | static void |
@@ -796,16 +733,6 @@ bnad_cb_tcb_destroy(struct bnad *bnad, struct bna_tcb *tcb) | |||
796 | } | 733 | } |
797 | 734 | ||
798 | static void | 735 | static void |
799 | bnad_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 | |||
808 | static void | ||
809 | bnad_cb_ccb_setup(struct bnad *bnad, struct bna_ccb *ccb) | 736 | bnad_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 | |||
933 | static void | 854 | static void |
934 | bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tx *tx) | 855 | bnad_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 | 2448 | static int |
2541 | * Called under lock held by net_device | 2449 | bnad_txq_wi_prepare(struct bnad *bnad, struct bna_tcb *tcb, |
2542 | */ | 2450 | struct sk_buff *skb, struct bna_txq_entry *txqent) |
2543 | static netdev_tx_t | ||
2544 | bnad_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 | */ | ||
2561 | static netdev_tx_t | ||
2562 | bnad_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 */ | 220 | struct bnad_tx_vector { |
225 | struct bnad_skb_unmap { | 221 | DEFINE_DMA_UNMAP_ADDR(dma_addr); |
222 | }; | ||
223 | |||
224 | struct 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 | |||
230 | struct bnad_rx_vector { | ||
227 | DEFINE_DMA_UNMAP_ADDR(dma_addr); | 231 | DEFINE_DMA_UNMAP_ADDR(dma_addr); |
232 | u32 len; | ||
228 | }; | 233 | }; |
229 | 234 | ||
230 | struct bnad_unmap_q { | 235 | struct 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 | |||
260 | struct bnad { | 257 | struct bnad { |
261 | struct net_device *netdev; | 258 | struct net_device *netdev; |
262 | u32 id; | 259 | u32 id; |