diff options
author | Jiri Kosina <jkosina@suse.cz> | 2008-05-06 10:57:55 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2008-05-06 10:57:55 -0400 |
commit | 7022b15e2a9f878fd5184586064c63352c3dd225 (patch) | |
tree | 5365c2f5bc82ae1946636ee8d5cd5d3b7e804f1b /drivers/infiniband | |
parent | aaad2b0c757f3e6e02552cb0bdcd91a5ec0d6305 (diff) | |
parent | a15306365a16380f3bafee9e181ba01231d4acd7 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/infiniband')
55 files changed, 1237 insertions, 701 deletions
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index 4e3128ff73c1..fe78f7d25099 100644 --- a/drivers/infiniband/core/umem.c +++ b/drivers/infiniband/core/umem.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/dma-mapping.h> | 38 | #include <linux/dma-mapping.h> |
39 | #include <linux/sched.h> | 39 | #include <linux/sched.h> |
40 | #include <linux/hugetlb.h> | 40 | #include <linux/hugetlb.h> |
41 | #include <linux/dma-attrs.h> | ||
41 | 42 | ||
42 | #include "uverbs.h" | 43 | #include "uverbs.h" |
43 | 44 | ||
@@ -72,9 +73,10 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d | |||
72 | * @addr: userspace virtual address to start at | 73 | * @addr: userspace virtual address to start at |
73 | * @size: length of region to pin | 74 | * @size: length of region to pin |
74 | * @access: IB_ACCESS_xxx flags for memory being pinned | 75 | * @access: IB_ACCESS_xxx flags for memory being pinned |
76 | * @dmasync: flush in-flight DMA when the memory region is written | ||
75 | */ | 77 | */ |
76 | struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, | 78 | struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, |
77 | size_t size, int access) | 79 | size_t size, int access, int dmasync) |
78 | { | 80 | { |
79 | struct ib_umem *umem; | 81 | struct ib_umem *umem; |
80 | struct page **page_list; | 82 | struct page **page_list; |
@@ -87,6 +89,10 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, | |||
87 | int ret; | 89 | int ret; |
88 | int off; | 90 | int off; |
89 | int i; | 91 | int i; |
92 | DEFINE_DMA_ATTRS(attrs); | ||
93 | |||
94 | if (dmasync) | ||
95 | dma_set_attr(DMA_ATTR_WRITE_BARRIER, &attrs); | ||
90 | 96 | ||
91 | if (!can_do_mlock()) | 97 | if (!can_do_mlock()) |
92 | return ERR_PTR(-EPERM); | 98 | return ERR_PTR(-EPERM); |
@@ -174,10 +180,11 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, | |||
174 | sg_set_page(&chunk->page_list[i], page_list[i + off], PAGE_SIZE, 0); | 180 | sg_set_page(&chunk->page_list[i], page_list[i + off], PAGE_SIZE, 0); |
175 | } | 181 | } |
176 | 182 | ||
177 | chunk->nmap = ib_dma_map_sg(context->device, | 183 | chunk->nmap = ib_dma_map_sg_attrs(context->device, |
178 | &chunk->page_list[0], | 184 | &chunk->page_list[0], |
179 | chunk->nents, | 185 | chunk->nents, |
180 | DMA_BIDIRECTIONAL); | 186 | DMA_BIDIRECTIONAL, |
187 | &attrs); | ||
181 | if (chunk->nmap <= 0) { | 188 | if (chunk->nmap <= 0) { |
182 | for (i = 0; i < chunk->nents; ++i) | 189 | for (i = 0; i < chunk->nents; ++i) |
183 | put_page(sg_page(&chunk->page_list[i])); | 190 | put_page(sg_page(&chunk->page_list[i])); |
diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c index 6af2c0f79a67..2acf9b62cf99 100644 --- a/drivers/infiniband/hw/amso1100/c2_provider.c +++ b/drivers/infiniband/hw/amso1100/c2_provider.c | |||
@@ -452,7 +452,7 @@ static struct ib_mr *c2_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, | |||
452 | return ERR_PTR(-ENOMEM); | 452 | return ERR_PTR(-ENOMEM); |
453 | c2mr->pd = c2pd; | 453 | c2mr->pd = c2pd; |
454 | 454 | ||
455 | c2mr->umem = ib_umem_get(pd->uobject->context, start, length, acc); | 455 | c2mr->umem = ib_umem_get(pd->uobject->context, start, length, acc, 0); |
456 | if (IS_ERR(c2mr->umem)) { | 456 | if (IS_ERR(c2mr->umem)) { |
457 | err = PTR_ERR(c2mr->umem); | 457 | err = PTR_ERR(c2mr->umem); |
458 | kfree(c2mr); | 458 | kfree(c2mr); |
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c index 66eb7030aea8..5fd8506a8657 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.c +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c | |||
@@ -359,9 +359,10 @@ static void insert_recv_cqe(struct t3_wq *wq, struct t3_cq *cq) | |||
359 | cq->sw_wptr++; | 359 | cq->sw_wptr++; |
360 | } | 360 | } |
361 | 361 | ||
362 | void cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count) | 362 | int cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count) |
363 | { | 363 | { |
364 | u32 ptr; | 364 | u32 ptr; |
365 | int flushed = 0; | ||
365 | 366 | ||
366 | PDBG("%s wq %p cq %p\n", __func__, wq, cq); | 367 | PDBG("%s wq %p cq %p\n", __func__, wq, cq); |
367 | 368 | ||
@@ -369,8 +370,11 @@ void cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count) | |||
369 | PDBG("%s rq_rptr %u rq_wptr %u skip count %u\n", __func__, | 370 | PDBG("%s rq_rptr %u rq_wptr %u skip count %u\n", __func__, |
370 | wq->rq_rptr, wq->rq_wptr, count); | 371 | wq->rq_rptr, wq->rq_wptr, count); |
371 | ptr = wq->rq_rptr + count; | 372 | ptr = wq->rq_rptr + count; |
372 | while (ptr++ != wq->rq_wptr) | 373 | while (ptr++ != wq->rq_wptr) { |
373 | insert_recv_cqe(wq, cq); | 374 | insert_recv_cqe(wq, cq); |
375 | flushed++; | ||
376 | } | ||
377 | return flushed; | ||
374 | } | 378 | } |
375 | 379 | ||
376 | static void insert_sq_cqe(struct t3_wq *wq, struct t3_cq *cq, | 380 | static void insert_sq_cqe(struct t3_wq *wq, struct t3_cq *cq, |
@@ -394,9 +398,10 @@ static void insert_sq_cqe(struct t3_wq *wq, struct t3_cq *cq, | |||
394 | cq->sw_wptr++; | 398 | cq->sw_wptr++; |
395 | } | 399 | } |
396 | 400 | ||
397 | void cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count) | 401 | int cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count) |
398 | { | 402 | { |
399 | __u32 ptr; | 403 | __u32 ptr; |
404 | int flushed = 0; | ||
400 | struct t3_swsq *sqp = wq->sq + Q_PTR2IDX(wq->sq_rptr, wq->sq_size_log2); | 405 | struct t3_swsq *sqp = wq->sq + Q_PTR2IDX(wq->sq_rptr, wq->sq_size_log2); |
401 | 406 | ||
402 | ptr = wq->sq_rptr + count; | 407 | ptr = wq->sq_rptr + count; |
@@ -405,7 +410,9 @@ void cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count) | |||
405 | insert_sq_cqe(wq, cq, sqp); | 410 | insert_sq_cqe(wq, cq, sqp); |
406 | sqp++; | 411 | sqp++; |
407 | ptr++; | 412 | ptr++; |
413 | flushed++; | ||
408 | } | 414 | } |
415 | return flushed; | ||
409 | } | 416 | } |
410 | 417 | ||
411 | /* | 418 | /* |
@@ -456,7 +463,8 @@ void cxio_count_scqes(struct t3_cq *cq, struct t3_wq *wq, int *count) | |||
456 | ptr = cq->sw_rptr; | 463 | ptr = cq->sw_rptr; |
457 | while (!Q_EMPTY(ptr, cq->sw_wptr)) { | 464 | while (!Q_EMPTY(ptr, cq->sw_wptr)) { |
458 | cqe = cq->sw_queue + (Q_PTR2IDX(ptr, cq->size_log2)); | 465 | cqe = cq->sw_queue + (Q_PTR2IDX(ptr, cq->size_log2)); |
459 | if ((SQ_TYPE(*cqe) || (CQE_OPCODE(*cqe) == T3_READ_RESP)) && | 466 | if ((SQ_TYPE(*cqe) || |
467 | ((CQE_OPCODE(*cqe) == T3_READ_RESP) && wq->oldest_read)) && | ||
460 | (CQE_QPID(*cqe) == wq->qpid)) | 468 | (CQE_QPID(*cqe) == wq->qpid)) |
461 | (*count)++; | 469 | (*count)++; |
462 | ptr++; | 470 | ptr++; |
@@ -829,7 +837,8 @@ int cxio_rdma_init(struct cxio_rdev *rdev_p, struct t3_rdma_init_attr *attr) | |||
829 | wqe->mpaattrs = attr->mpaattrs; | 837 | wqe->mpaattrs = attr->mpaattrs; |
830 | wqe->qpcaps = attr->qpcaps; | 838 | wqe->qpcaps = attr->qpcaps; |
831 | wqe->ulpdu_size = cpu_to_be16(attr->tcp_emss); | 839 | wqe->ulpdu_size = cpu_to_be16(attr->tcp_emss); |
832 | wqe->flags = cpu_to_be32(attr->flags); | 840 | wqe->rqe_count = cpu_to_be16(attr->rqe_count); |
841 | wqe->flags_rtr_type = cpu_to_be16(attr->flags|V_RTR_TYPE(attr->rtr_type)); | ||
833 | wqe->ord = cpu_to_be32(attr->ord); | 842 | wqe->ord = cpu_to_be32(attr->ord); |
834 | wqe->ird = cpu_to_be32(attr->ird); | 843 | wqe->ird = cpu_to_be32(attr->ird); |
835 | wqe->qp_dma_addr = cpu_to_be64(attr->qp_dma_addr); | 844 | wqe->qp_dma_addr = cpu_to_be64(attr->qp_dma_addr); |
@@ -1135,6 +1144,18 @@ int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe, | |||
1135 | if (RQ_TYPE(*hw_cqe) && (CQE_OPCODE(*hw_cqe) == T3_READ_RESP)) { | 1144 | if (RQ_TYPE(*hw_cqe) && (CQE_OPCODE(*hw_cqe) == T3_READ_RESP)) { |
1136 | 1145 | ||
1137 | /* | 1146 | /* |
1147 | * If this is an unsolicited read response, then the read | ||
1148 | * was generated by the kernel driver as part of peer-2-peer | ||
1149 | * connection setup. So ignore the completion. | ||
1150 | */ | ||
1151 | if (!wq->oldest_read) { | ||
1152 | if (CQE_STATUS(*hw_cqe)) | ||
1153 | wq->error = 1; | ||
1154 | ret = -1; | ||
1155 | goto skip_cqe; | ||
1156 | } | ||
1157 | |||
1158 | /* | ||
1138 | * Don't write to the HWCQ, so create a new read req CQE | 1159 | * Don't write to the HWCQ, so create a new read req CQE |
1139 | * in local memory. | 1160 | * in local memory. |
1140 | */ | 1161 | */ |
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h index 99543d634704..69ab08ebc680 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.h +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h | |||
@@ -53,6 +53,7 @@ | |||
53 | #define T3_MAX_PBL_SIZE 256 | 53 | #define T3_MAX_PBL_SIZE 256 |
54 | #define T3_MAX_RQ_SIZE 1024 | 54 | #define T3_MAX_RQ_SIZE 1024 |
55 | #define T3_MAX_NUM_STAG (1<<15) | 55 | #define T3_MAX_NUM_STAG (1<<15) |
56 | #define T3_MAX_MR_SIZE 0x100000000ULL | ||
56 | 57 | ||
57 | #define T3_STAG_UNSET 0xffffffff | 58 | #define T3_STAG_UNSET 0xffffffff |
58 | 59 | ||
@@ -172,8 +173,8 @@ u32 cxio_hal_get_pdid(struct cxio_hal_resource *rscp); | |||
172 | void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid); | 173 | void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid); |
173 | int __init cxio_hal_init(void); | 174 | int __init cxio_hal_init(void); |
174 | void __exit cxio_hal_exit(void); | 175 | void __exit cxio_hal_exit(void); |
175 | void cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count); | 176 | int cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count); |
176 | void cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count); | 177 | int cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count); |
177 | void cxio_count_rcqes(struct t3_cq *cq, struct t3_wq *wq, int *count); | 178 | void cxio_count_rcqes(struct t3_cq *cq, struct t3_wq *wq, int *count); |
178 | void cxio_count_scqes(struct t3_cq *cq, struct t3_wq *wq, int *count); | 179 | void cxio_count_scqes(struct t3_cq *cq, struct t3_wq *wq, int *count); |
179 | void cxio_flush_hw_cq(struct t3_cq *cq); | 180 | void cxio_flush_hw_cq(struct t3_cq *cq); |
diff --git a/drivers/infiniband/hw/cxgb3/cxio_wr.h b/drivers/infiniband/hw/cxgb3/cxio_wr.h index 969d4d928455..f1a25a821a45 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_wr.h +++ b/drivers/infiniband/hw/cxgb3/cxio_wr.h | |||
@@ -278,6 +278,17 @@ enum t3_qp_caps { | |||
278 | uP_RI_QP_STAG0_ENABLE = 0x10 | 278 | uP_RI_QP_STAG0_ENABLE = 0x10 |
279 | } __attribute__ ((packed)); | 279 | } __attribute__ ((packed)); |
280 | 280 | ||
281 | enum rdma_init_rtr_types { | ||
282 | RTR_READ = 1, | ||
283 | RTR_WRITE = 2, | ||
284 | RTR_SEND = 3, | ||
285 | }; | ||
286 | |||
287 | #define S_RTR_TYPE 2 | ||
288 | #define M_RTR_TYPE 0x3 | ||
289 | #define V_RTR_TYPE(x) ((x) << S_RTR_TYPE) | ||
290 | #define G_RTR_TYPE(x) ((((x) >> S_RTR_TYPE)) & M_RTR_TYPE) | ||
291 | |||
281 | struct t3_rdma_init_attr { | 292 | struct t3_rdma_init_attr { |
282 | u32 tid; | 293 | u32 tid; |
283 | u32 qpid; | 294 | u32 qpid; |
@@ -293,7 +304,9 @@ struct t3_rdma_init_attr { | |||
293 | u32 ird; | 304 | u32 ird; |
294 | u64 qp_dma_addr; | 305 | u64 qp_dma_addr; |
295 | u32 qp_dma_size; | 306 | u32 qp_dma_size; |
296 | u32 flags; | 307 | enum rdma_init_rtr_types rtr_type; |
308 | u16 flags; | ||
309 | u16 rqe_count; | ||
297 | u32 irs; | 310 | u32 irs; |
298 | }; | 311 | }; |
299 | 312 | ||
@@ -309,8 +322,8 @@ struct t3_rdma_init_wr { | |||
309 | u8 mpaattrs; /* 5 */ | 322 | u8 mpaattrs; /* 5 */ |
310 | u8 qpcaps; | 323 | u8 qpcaps; |
311 | __be16 ulpdu_size; | 324 | __be16 ulpdu_size; |
312 | __be32 flags; /* bits 31-1 - reservered */ | 325 | __be16 flags_rtr_type; |
313 | /* bit 0 - set if RECV posted */ | 326 | __be16 rqe_count; |
314 | __be32 ord; /* 6 */ | 327 | __be32 ord; /* 6 */ |
315 | __be32 ird; | 328 | __be32 ird; |
316 | __be64 qp_dma_addr; /* 7 */ | 329 | __be64 qp_dma_addr; /* 7 */ |
@@ -324,7 +337,7 @@ struct t3_genbit { | |||
324 | }; | 337 | }; |
325 | 338 | ||
326 | enum rdma_init_wr_flags { | 339 | enum rdma_init_wr_flags { |
327 | RECVS_POSTED = (1<<0), | 340 | MPA_INITIATOR = (1<<0), |
328 | PRIV_QP = (1<<1), | 341 | PRIV_QP = (1<<1), |
329 | }; | 342 | }; |
330 | 343 | ||
diff --git a/drivers/infiniband/hw/cxgb3/iwch.c b/drivers/infiniband/hw/cxgb3/iwch.c index 6ba4138c8ec3..71554eacb13c 100644 --- a/drivers/infiniband/hw/cxgb3/iwch.c +++ b/drivers/infiniband/hw/cxgb3/iwch.c | |||
@@ -83,6 +83,7 @@ static void rnic_init(struct iwch_dev *rnicp) | |||
83 | rnicp->attr.max_phys_buf_entries = T3_MAX_PBL_SIZE; | 83 | rnicp->attr.max_phys_buf_entries = T3_MAX_PBL_SIZE; |
84 | rnicp->attr.max_pds = T3_MAX_NUM_PD - 1; | 84 | rnicp->attr.max_pds = T3_MAX_NUM_PD - 1; |
85 | rnicp->attr.mem_pgsizes_bitmask = 0x7FFF; /* 4KB-128MB */ | 85 | rnicp->attr.mem_pgsizes_bitmask = 0x7FFF; /* 4KB-128MB */ |
86 | rnicp->attr.max_mr_size = T3_MAX_MR_SIZE; | ||
86 | rnicp->attr.can_resize_wq = 0; | 87 | rnicp->attr.can_resize_wq = 0; |
87 | rnicp->attr.max_rdma_reads_per_qp = 8; | 88 | rnicp->attr.max_rdma_reads_per_qp = 8; |
88 | rnicp->attr.max_rdma_read_resources = | 89 | rnicp->attr.max_rdma_read_resources = |
diff --git a/drivers/infiniband/hw/cxgb3/iwch.h b/drivers/infiniband/hw/cxgb3/iwch.h index 9ad9b1e7c8c1..d2409a505e8d 100644 --- a/drivers/infiniband/hw/cxgb3/iwch.h +++ b/drivers/infiniband/hw/cxgb3/iwch.h | |||
@@ -66,6 +66,7 @@ struct iwch_rnic_attributes { | |||
66 | * size (4k)^i. Phys block list mode unsupported. | 66 | * size (4k)^i. Phys block list mode unsupported. |
67 | */ | 67 | */ |
68 | u32 mem_pgsizes_bitmask; | 68 | u32 mem_pgsizes_bitmask; |
69 | u64 max_mr_size; | ||
69 | u8 can_resize_wq; | 70 | u8 can_resize_wq; |
70 | 71 | ||
71 | /* | 72 | /* |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index 72ca360c3dbc..c325c44807e8 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c | |||
@@ -63,10 +63,14 @@ static char *states[] = { | |||
63 | NULL, | 63 | NULL, |
64 | }; | 64 | }; |
65 | 65 | ||
66 | static int ep_timeout_secs = 10; | 66 | int peer2peer = 0; |
67 | module_param(peer2peer, int, 0644); | ||
68 | MODULE_PARM_DESC(peer2peer, "Support peer2peer ULPs (default=0)"); | ||
69 | |||
70 | static int ep_timeout_secs = 60; | ||
67 | module_param(ep_timeout_secs, int, 0644); | 71 | module_param(ep_timeout_secs, int, 0644); |
68 | MODULE_PARM_DESC(ep_timeout_secs, "CM Endpoint operation timeout " | 72 | MODULE_PARM_DESC(ep_timeout_secs, "CM Endpoint operation timeout " |
69 | "in seconds (default=10)"); | 73 | "in seconds (default=60)"); |
70 | 74 | ||
71 | static int mpa_rev = 1; | 75 | static int mpa_rev = 1; |
72 | module_param(mpa_rev, int, 0644); | 76 | module_param(mpa_rev, int, 0644); |
@@ -125,6 +129,12 @@ static void start_ep_timer(struct iwch_ep *ep) | |||
125 | static void stop_ep_timer(struct iwch_ep *ep) | 129 | static void stop_ep_timer(struct iwch_ep *ep) |
126 | { | 130 | { |
127 | PDBG("%s ep %p\n", __func__, ep); | 131 | PDBG("%s ep %p\n", __func__, ep); |
132 | if (!timer_pending(&ep->timer)) { | ||
133 | printk(KERN_ERR "%s timer stopped when its not running! ep %p state %u\n", | ||
134 | __func__, ep, ep->com.state); | ||
135 | WARN_ON(1); | ||
136 | return; | ||
137 | } | ||
128 | del_timer_sync(&ep->timer); | 138 | del_timer_sync(&ep->timer); |
129 | put_ep(&ep->com); | 139 | put_ep(&ep->com); |
130 | } | 140 | } |
@@ -508,7 +518,7 @@ static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb) | |||
508 | skb_reset_transport_header(skb); | 518 | skb_reset_transport_header(skb); |
509 | len = skb->len; | 519 | len = skb->len; |
510 | req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); | 520 | req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); |
511 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)); | 521 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)|F_WR_COMPL); |
512 | req->wr_lo = htonl(V_WR_TID(ep->hwtid)); | 522 | req->wr_lo = htonl(V_WR_TID(ep->hwtid)); |
513 | req->len = htonl(len); | 523 | req->len = htonl(len); |
514 | req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | | 524 | req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | |
@@ -559,7 +569,7 @@ static int send_mpa_reject(struct iwch_ep *ep, const void *pdata, u8 plen) | |||
559 | set_arp_failure_handler(skb, arp_failure_discard); | 569 | set_arp_failure_handler(skb, arp_failure_discard); |
560 | skb_reset_transport_header(skb); | 570 | skb_reset_transport_header(skb); |
561 | req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); | 571 | req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); |
562 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)); | 572 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)|F_WR_COMPL); |
563 | req->wr_lo = htonl(V_WR_TID(ep->hwtid)); | 573 | req->wr_lo = htonl(V_WR_TID(ep->hwtid)); |
564 | req->len = htonl(mpalen); | 574 | req->len = htonl(mpalen); |
565 | req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | | 575 | req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | |
@@ -611,7 +621,7 @@ static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen) | |||
611 | skb_reset_transport_header(skb); | 621 | skb_reset_transport_header(skb); |
612 | len = skb->len; | 622 | len = skb->len; |
613 | req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); | 623 | req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); |
614 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)); | 624 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)|F_WR_COMPL); |
615 | req->wr_lo = htonl(V_WR_TID(ep->hwtid)); | 625 | req->wr_lo = htonl(V_WR_TID(ep->hwtid)); |
616 | req->len = htonl(len); | 626 | req->len = htonl(len); |
617 | req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | | 627 | req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | |
@@ -879,6 +889,7 @@ static void process_mpa_reply(struct iwch_ep *ep, struct sk_buff *skb) | |||
879 | * the MPA header is valid. | 889 | * the MPA header is valid. |
880 | */ | 890 | */ |
881 | state_set(&ep->com, FPDU_MODE); | 891 | state_set(&ep->com, FPDU_MODE); |
892 | ep->mpa_attr.initiator = 1; | ||
882 | ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0; | 893 | ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0; |
883 | ep->mpa_attr.recv_marker_enabled = markers_enabled; | 894 | ep->mpa_attr.recv_marker_enabled = markers_enabled; |
884 | ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0; | 895 | ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0; |
@@ -901,8 +912,14 @@ static void process_mpa_reply(struct iwch_ep *ep, struct sk_buff *skb) | |||
901 | /* bind QP and TID with INIT_WR */ | 912 | /* bind QP and TID with INIT_WR */ |
902 | err = iwch_modify_qp(ep->com.qp->rhp, | 913 | err = iwch_modify_qp(ep->com.qp->rhp, |
903 | ep->com.qp, mask, &attrs, 1); | 914 | ep->com.qp, mask, &attrs, 1); |
904 | if (!err) | 915 | if (err) |
905 | goto out; | 916 | goto err; |
917 | |||
918 | if (peer2peer && iwch_rqes_posted(ep->com.qp) == 0) { | ||
919 | iwch_post_zb_read(ep->com.qp); | ||
920 | } | ||
921 | |||
922 | goto out; | ||
906 | err: | 923 | err: |
907 | abort_connection(ep, skb, GFP_KERNEL); | 924 | abort_connection(ep, skb, GFP_KERNEL); |
908 | out: | 925 | out: |
@@ -995,6 +1012,7 @@ static void process_mpa_request(struct iwch_ep *ep, struct sk_buff *skb) | |||
995 | * If we get here we have accumulated the entire mpa | 1012 | * If we get here we have accumulated the entire mpa |
996 | * start reply message including private data. | 1013 | * start reply message including private data. |
997 | */ | 1014 | */ |
1015 | ep->mpa_attr.initiator = 0; | ||
998 | ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0; | 1016 | ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0; |
999 | ep->mpa_attr.recv_marker_enabled = markers_enabled; | 1017 | ep->mpa_attr.recv_marker_enabled = markers_enabled; |
1000 | ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0; | 1018 | ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0; |
@@ -1065,17 +1083,33 @@ static int tx_ack(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1065 | 1083 | ||
1066 | PDBG("%s ep %p credits %u\n", __func__, ep, credits); | 1084 | PDBG("%s ep %p credits %u\n", __func__, ep, credits); |
1067 | 1085 | ||
1068 | if (credits == 0) | 1086 | if (credits == 0) { |
1087 | PDBG(KERN_ERR "%s 0 credit ack ep %p state %u\n", | ||
1088 | __func__, ep, state_read(&ep->com)); | ||
1069 | return CPL_RET_BUF_DONE; | 1089 | return CPL_RET_BUF_DONE; |
1090 | } | ||
1091 | |||
1070 | BUG_ON(credits != 1); | 1092 | BUG_ON(credits != 1); |
1071 | BUG_ON(ep->mpa_skb == NULL); | ||
1072 | kfree_skb(ep->mpa_skb); | ||
1073 | ep->mpa_skb = NULL; | ||
1074 | dst_confirm(ep->dst); | 1093 | dst_confirm(ep->dst); |
1075 | if (state_read(&ep->com) == MPA_REP_SENT) { | 1094 | if (!ep->mpa_skb) { |
1076 | ep->com.rpl_done = 1; | 1095 | PDBG("%s rdma_init wr_ack ep %p state %u\n", |
1077 | PDBG("waking up ep %p\n", ep); | 1096 | __func__, ep, state_read(&ep->com)); |
1078 | wake_up(&ep->com.waitq); | 1097 | if (ep->mpa_attr.initiator) { |
1098 | PDBG("%s initiator ep %p state %u\n", | ||
1099 | __func__, ep, state_read(&ep->com)); | ||
1100 | if (peer2peer) | ||
1101 | iwch_post_zb_read(ep->com.qp); | ||
1102 | } else { | ||
1103 | PDBG("%s responder ep %p state %u\n", | ||
1104 | __func__, ep, state_read(&ep->com)); | ||
1105 | ep->com.rpl_done = 1; | ||
1106 | wake_up(&ep->com.waitq); | ||
1107 | } | ||
1108 | } else { | ||
1109 | PDBG("%s lsm ack ep %p state %u freeing skb\n", | ||
1110 | __func__, ep, state_read(&ep->com)); | ||
1111 | kfree_skb(ep->mpa_skb); | ||
1112 | ep->mpa_skb = NULL; | ||
1079 | } | 1113 | } |
1080 | return CPL_RET_BUF_DONE; | 1114 | return CPL_RET_BUF_DONE; |
1081 | } | 1115 | } |
@@ -1083,8 +1117,11 @@ static int tx_ack(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1083 | static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | 1117 | static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) |
1084 | { | 1118 | { |
1085 | struct iwch_ep *ep = ctx; | 1119 | struct iwch_ep *ep = ctx; |
1120 | unsigned long flags; | ||
1121 | int release = 0; | ||
1086 | 1122 | ||
1087 | PDBG("%s ep %p\n", __func__, ep); | 1123 | PDBG("%s ep %p\n", __func__, ep); |
1124 | BUG_ON(!ep); | ||
1088 | 1125 | ||
1089 | /* | 1126 | /* |
1090 | * We get 2 abort replies from the HW. The first one must | 1127 | * We get 2 abort replies from the HW. The first one must |
@@ -1095,9 +1132,22 @@ static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1095 | return CPL_RET_BUF_DONE; | 1132 | return CPL_RET_BUF_DONE; |
1096 | } | 1133 | } |
1097 | 1134 | ||
1098 | close_complete_upcall(ep); | 1135 | spin_lock_irqsave(&ep->com.lock, flags); |
1099 | state_set(&ep->com, DEAD); | 1136 | switch (ep->com.state) { |
1100 | release_ep_resources(ep); | 1137 | case ABORTING: |
1138 | close_complete_upcall(ep); | ||
1139 | __state_set(&ep->com, DEAD); | ||
1140 | release = 1; | ||
1141 | break; | ||
1142 | default: | ||
1143 | printk(KERN_ERR "%s ep %p state %d\n", | ||
1144 | __func__, ep, ep->com.state); | ||
1145 | break; | ||
1146 | } | ||
1147 | spin_unlock_irqrestore(&ep->com.lock, flags); | ||
1148 | |||
1149 | if (release) | ||
1150 | release_ep_resources(ep); | ||
1101 | return CPL_RET_BUF_DONE; | 1151 | return CPL_RET_BUF_DONE; |
1102 | } | 1152 | } |
1103 | 1153 | ||
@@ -1470,7 +1520,8 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1470 | struct sk_buff *rpl_skb; | 1520 | struct sk_buff *rpl_skb; |
1471 | struct iwch_qp_attributes attrs; | 1521 | struct iwch_qp_attributes attrs; |
1472 | int ret; | 1522 | int ret; |
1473 | int state; | 1523 | int release = 0; |
1524 | unsigned long flags; | ||
1474 | 1525 | ||
1475 | if (is_neg_adv_abort(req->status)) { | 1526 | if (is_neg_adv_abort(req->status)) { |
1476 | PDBG("%s neg_adv_abort ep %p tid %d\n", __func__, ep, | 1527 | PDBG("%s neg_adv_abort ep %p tid %d\n", __func__, ep, |
@@ -1488,9 +1539,9 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1488 | return CPL_RET_BUF_DONE; | 1539 | return CPL_RET_BUF_DONE; |
1489 | } | 1540 | } |
1490 | 1541 | ||
1491 | state = state_read(&ep->com); | 1542 | spin_lock_irqsave(&ep->com.lock, flags); |
1492 | PDBG("%s ep %p state %u\n", __func__, ep, state); | 1543 | PDBG("%s ep %p state %u\n", __func__, ep, ep->com.state); |
1493 | switch (state) { | 1544 | switch (ep->com.state) { |
1494 | case CONNECTING: | 1545 | case CONNECTING: |
1495 | break; | 1546 | break; |
1496 | case MPA_REQ_WAIT: | 1547 | case MPA_REQ_WAIT: |
@@ -1536,21 +1587,25 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1536 | break; | 1587 | break; |
1537 | case DEAD: | 1588 | case DEAD: |
1538 | PDBG("%s PEER_ABORT IN DEAD STATE!!!!\n", __func__); | 1589 | PDBG("%s PEER_ABORT IN DEAD STATE!!!!\n", __func__); |
1590 | spin_unlock_irqrestore(&ep->com.lock, flags); | ||
1539 | return CPL_RET_BUF_DONE; | 1591 | return CPL_RET_BUF_DONE; |
1540 | default: | 1592 | default: |
1541 | BUG_ON(1); | 1593 | BUG_ON(1); |
1542 | break; | 1594 | break; |
1543 | } | 1595 | } |
1544 | dst_confirm(ep->dst); | 1596 | dst_confirm(ep->dst); |
1597 | if (ep->com.state != ABORTING) { | ||
1598 | __state_set(&ep->com, DEAD); | ||
1599 | release = 1; | ||
1600 | } | ||
1601 | spin_unlock_irqrestore(&ep->com.lock, flags); | ||
1545 | 1602 | ||
1546 | rpl_skb = get_skb(skb, sizeof(*rpl), GFP_KERNEL); | 1603 | rpl_skb = get_skb(skb, sizeof(*rpl), GFP_KERNEL); |
1547 | if (!rpl_skb) { | 1604 | if (!rpl_skb) { |
1548 | printk(KERN_ERR MOD "%s - cannot allocate skb!\n", | 1605 | printk(KERN_ERR MOD "%s - cannot allocate skb!\n", |
1549 | __func__); | 1606 | __func__); |
1550 | dst_release(ep->dst); | 1607 | release = 1; |
1551 | l2t_release(L2DATA(ep->com.tdev), ep->l2t); | 1608 | goto out; |
1552 | put_ep(&ep->com); | ||
1553 | return CPL_RET_BUF_DONE; | ||
1554 | } | 1609 | } |
1555 | rpl_skb->priority = CPL_PRIORITY_DATA; | 1610 | rpl_skb->priority = CPL_PRIORITY_DATA; |
1556 | rpl = (struct cpl_abort_rpl *) skb_put(rpl_skb, sizeof(*rpl)); | 1611 | rpl = (struct cpl_abort_rpl *) skb_put(rpl_skb, sizeof(*rpl)); |
@@ -1559,10 +1614,9 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1559 | OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid)); | 1614 | OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid)); |
1560 | rpl->cmd = CPL_ABORT_NO_RST; | 1615 | rpl->cmd = CPL_ABORT_NO_RST; |
1561 | cxgb3_ofld_send(ep->com.tdev, rpl_skb); | 1616 | cxgb3_ofld_send(ep->com.tdev, rpl_skb); |
1562 | if (state != ABORTING) { | 1617 | out: |
1563 | state_set(&ep->com, DEAD); | 1618 | if (release) |
1564 | release_ep_resources(ep); | 1619 | release_ep_resources(ep); |
1565 | } | ||
1566 | return CPL_RET_BUF_DONE; | 1620 | return CPL_RET_BUF_DONE; |
1567 | } | 1621 | } |
1568 | 1622 | ||
@@ -1596,8 +1650,8 @@ static int close_con_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1596 | release = 1; | 1650 | release = 1; |
1597 | break; | 1651 | break; |
1598 | case ABORTING: | 1652 | case ABORTING: |
1599 | break; | ||
1600 | case DEAD: | 1653 | case DEAD: |
1654 | break; | ||
1601 | default: | 1655 | default: |
1602 | BUG_ON(1); | 1656 | BUG_ON(1); |
1603 | break; | 1657 | break; |
@@ -1661,15 +1715,18 @@ static void ep_timeout(unsigned long arg) | |||
1661 | struct iwch_ep *ep = (struct iwch_ep *)arg; | 1715 | struct iwch_ep *ep = (struct iwch_ep *)arg; |
1662 | struct iwch_qp_attributes attrs; | 1716 | struct iwch_qp_attributes attrs; |
1663 | unsigned long flags; | 1717 | unsigned long flags; |
1718 | int abort = 1; | ||
1664 | 1719 | ||
1665 | spin_lock_irqsave(&ep->com.lock, flags); | 1720 | spin_lock_irqsave(&ep->com.lock, flags); |
1666 | PDBG("%s ep %p tid %u state %d\n", __func__, ep, ep->hwtid, | 1721 | PDBG("%s ep %p tid %u state %d\n", __func__, ep, ep->hwtid, |
1667 | ep->com.state); | 1722 | ep->com.state); |
1668 | switch (ep->com.state) { | 1723 | switch (ep->com.state) { |
1669 | case MPA_REQ_SENT: | 1724 | case MPA_REQ_SENT: |
1725 | __state_set(&ep->com, ABORTING); | ||
1670 | connect_reply_upcall(ep, -ETIMEDOUT); | 1726 | connect_reply_upcall(ep, -ETIMEDOUT); |
1671 | break; | 1727 | break; |
1672 | case MPA_REQ_WAIT: | 1728 | case MPA_REQ_WAIT: |
1729 | __state_set(&ep->com, ABORTING); | ||
1673 | break; | 1730 | break; |
1674 | case CLOSING: | 1731 | case CLOSING: |
1675 | case MORIBUND: | 1732 | case MORIBUND: |
@@ -1679,13 +1736,17 @@ static void ep_timeout(unsigned long arg) | |||
1679 | ep->com.qp, IWCH_QP_ATTR_NEXT_STATE, | 1736 | ep->com.qp, IWCH_QP_ATTR_NEXT_STATE, |
1680 | &attrs, 1); | 1737 | &attrs, 1); |
1681 | } | 1738 | } |
1739 | __state_set(&ep->com, ABORTING); | ||
1682 | break; | 1740 | break; |
1683 | default: | 1741 | default: |
1684 | BUG(); | 1742 | printk(KERN_ERR "%s unexpected state ep %p state %u\n", |
1743 | __func__, ep, ep->com.state); | ||
1744 | WARN_ON(1); | ||
1745 | abort = 0; | ||
1685 | } | 1746 | } |
1686 | __state_set(&ep->com, CLOSING); | ||
1687 | spin_unlock_irqrestore(&ep->com.lock, flags); | 1747 | spin_unlock_irqrestore(&ep->com.lock, flags); |
1688 | abort_connection(ep, NULL, GFP_ATOMIC); | 1748 | if (abort) |
1749 | abort_connection(ep, NULL, GFP_ATOMIC); | ||
1689 | put_ep(&ep->com); | 1750 | put_ep(&ep->com); |
1690 | } | 1751 | } |
1691 | 1752 | ||
@@ -1762,16 +1823,19 @@ int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
1762 | if (err) | 1823 | if (err) |
1763 | goto err; | 1824 | goto err; |
1764 | 1825 | ||
1826 | /* if needed, wait for wr_ack */ | ||
1827 | if (iwch_rqes_posted(qp)) { | ||
1828 | wait_event(ep->com.waitq, ep->com.rpl_done); | ||
1829 | err = ep->com.rpl_err; | ||
1830 | if (err) | ||
1831 | goto err; | ||
1832 | } | ||
1833 | |||
1765 | err = send_mpa_reply(ep, conn_param->private_data, | 1834 | err = send_mpa_reply(ep, conn_param->private_data, |
1766 | conn_param->private_data_len); | 1835 | conn_param->private_data_len); |
1767 | if (err) | 1836 | if (err) |
1768 | goto err; | 1837 | goto err; |
1769 | 1838 | ||
1770 | /* wait for wr_ack */ | ||
1771 | wait_event(ep->com.waitq, ep->com.rpl_done); | ||
1772 | err = ep->com.rpl_err; | ||
1773 | if (err) | ||
1774 | goto err; | ||
1775 | 1839 | ||
1776 | state_set(&ep->com, FPDU_MODE); | 1840 | state_set(&ep->com, FPDU_MODE); |
1777 | established_upcall(ep); | 1841 | established_upcall(ep); |
@@ -1968,40 +2032,39 @@ int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp) | |||
1968 | PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep, | 2032 | PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep, |
1969 | states[ep->com.state], abrupt); | 2033 | states[ep->com.state], abrupt); |
1970 | 2034 | ||
1971 | if (ep->com.state == DEAD) { | ||
1972 | PDBG("%s already dead ep %p\n", __func__, ep); | ||
1973 | goto out; | ||
1974 | } | ||
1975 | |||
1976 | if (abrupt) { | ||
1977 | if (ep->com.state != ABORTING) { | ||
1978 | ep->com.state = ABORTING; | ||
1979 | close = 1; | ||
1980 | } | ||
1981 | goto out; | ||
1982 | } | ||
1983 | |||
1984 | switch (ep->com.state) { | 2035 | switch (ep->com.state) { |
1985 | case MPA_REQ_WAIT: | 2036 | case MPA_REQ_WAIT: |
1986 | case MPA_REQ_SENT: | 2037 | case MPA_REQ_SENT: |
1987 | case MPA_REQ_RCVD: | 2038 | case MPA_REQ_RCVD: |
1988 | case MPA_REP_SENT: | 2039 | case MPA_REP_SENT: |
1989 | case FPDU_MODE: | 2040 | case FPDU_MODE: |
1990 | start_ep_timer(ep); | ||
1991 | ep->com.state = CLOSING; | ||
1992 | close = 1; | 2041 | close = 1; |
2042 | if (abrupt) | ||
2043 | ep->com.state = ABORTING; | ||
2044 | else { | ||
2045 | ep->com.state = CLOSING; | ||
2046 | start_ep_timer(ep); | ||
2047 | } | ||
1993 | break; | 2048 | break; |
1994 | case CLOSING: | 2049 | case CLOSING: |
1995 | ep->com.state = MORIBUND; | ||
1996 | close = 1; | 2050 | close = 1; |
2051 | if (abrupt) { | ||
2052 | stop_ep_timer(ep); | ||
2053 | ep->com.state = ABORTING; | ||
2054 | } else | ||
2055 | ep->com.state = MORIBUND; | ||
1997 | break; | 2056 | break; |
1998 | case MORIBUND: | 2057 | case MORIBUND: |
2058 | case ABORTING: | ||
2059 | case DEAD: | ||
2060 | PDBG("%s ignoring disconnect ep %p state %u\n", | ||
2061 | __func__, ep, ep->com.state); | ||
1999 | break; | 2062 | break; |
2000 | default: | 2063 | default: |
2001 | BUG(); | 2064 | BUG(); |
2002 | break; | 2065 | break; |
2003 | } | 2066 | } |
2004 | out: | 2067 | |
2005 | spin_unlock_irqrestore(&ep->com.lock, flags); | 2068 | spin_unlock_irqrestore(&ep->com.lock, flags); |
2006 | if (close) { | 2069 | if (close) { |
2007 | if (abrupt) | 2070 | if (abrupt) |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.h b/drivers/infiniband/hw/cxgb3/iwch_cm.h index 2bb7fbdb3ff4..d7c7e09f0996 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.h +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.h | |||
@@ -56,6 +56,7 @@ | |||
56 | #define put_ep(ep) { \ | 56 | #define put_ep(ep) { \ |
57 | PDBG("put_ep (via %s:%u) ep %p refcnt %d\n", __func__, __LINE__, \ | 57 | PDBG("put_ep (via %s:%u) ep %p refcnt %d\n", __func__, __LINE__, \ |
58 | ep, atomic_read(&((ep)->kref.refcount))); \ | 58 | ep, atomic_read(&((ep)->kref.refcount))); \ |
59 | WARN_ON(atomic_read(&((ep)->kref.refcount)) < 1); \ | ||
59 | kref_put(&((ep)->kref), __free_ep); \ | 60 | kref_put(&((ep)->kref), __free_ep); \ |
60 | } | 61 | } |
61 | 62 | ||
@@ -225,5 +226,6 @@ int iwch_ep_redirect(void *ctx, struct dst_entry *old, struct dst_entry *new, st | |||
225 | 226 | ||
226 | int __init iwch_cm_init(void); | 227 | int __init iwch_cm_init(void); |
227 | void __exit iwch_cm_term(void); | 228 | void __exit iwch_cm_term(void); |
229 | extern int peer2peer; | ||
228 | 230 | ||
229 | #endif /* _IWCH_CM_H_ */ | 231 | #endif /* _IWCH_CM_H_ */ |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index ab4695c1dd56..d07d3a377b5f 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c | |||
@@ -602,7 +602,7 @@ static struct ib_mr *iwch_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, | |||
602 | if (!mhp) | 602 | if (!mhp) |
603 | return ERR_PTR(-ENOMEM); | 603 | return ERR_PTR(-ENOMEM); |
604 | 604 | ||
605 | mhp->umem = ib_umem_get(pd->uobject->context, start, length, acc); | 605 | mhp->umem = ib_umem_get(pd->uobject->context, start, length, acc, 0); |
606 | if (IS_ERR(mhp->umem)) { | 606 | if (IS_ERR(mhp->umem)) { |
607 | err = PTR_ERR(mhp->umem); | 607 | err = PTR_ERR(mhp->umem); |
608 | kfree(mhp); | 608 | kfree(mhp); |
@@ -998,7 +998,7 @@ static int iwch_query_device(struct ib_device *ibdev, | |||
998 | props->device_cap_flags = dev->device_cap_flags; | 998 | props->device_cap_flags = dev->device_cap_flags; |
999 | props->vendor_id = (u32)dev->rdev.rnic_info.pdev->vendor; | 999 | props->vendor_id = (u32)dev->rdev.rnic_info.pdev->vendor; |
1000 | props->vendor_part_id = (u32)dev->rdev.rnic_info.pdev->device; | 1000 | props->vendor_part_id = (u32)dev->rdev.rnic_info.pdev->device; |
1001 | props->max_mr_size = ~0ull; | 1001 | props->max_mr_size = dev->attr.max_mr_size; |
1002 | props->max_qp = dev->attr.max_qps; | 1002 | props->max_qp = dev->attr.max_qps; |
1003 | props->max_qp_wr = dev->attr.max_wrs; | 1003 | props->max_qp_wr = dev->attr.max_wrs; |
1004 | props->max_sge = dev->attr.max_sge_per_wr; | 1004 | props->max_sge = dev->attr.max_sge_per_wr; |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.h b/drivers/infiniband/hw/cxgb3/iwch_provider.h index 61356f91109d..db5100d27ca2 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.h +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.h | |||
@@ -118,6 +118,7 @@ enum IWCH_QP_FLAGS { | |||
118 | }; | 118 | }; |
119 | 119 | ||
120 | struct iwch_mpa_attributes { | 120 | struct iwch_mpa_attributes { |
121 | u8 initiator; | ||
121 | u8 recv_marker_enabled; | 122 | u8 recv_marker_enabled; |
122 | u8 xmit_marker_enabled; /* iWARP: enable inbound Read Resp. */ | 123 | u8 xmit_marker_enabled; /* iWARP: enable inbound Read Resp. */ |
123 | u8 crc_enabled; | 124 | u8 crc_enabled; |
@@ -322,6 +323,7 @@ enum iwch_qp_query_flags { | |||
322 | IWCH_QP_QUERY_TEST_USERWRITE = 0x32 /* Test special */ | 323 | IWCH_QP_QUERY_TEST_USERWRITE = 0x32 /* Test special */ |
323 | }; | 324 | }; |
324 | 325 | ||
326 | u16 iwch_rqes_posted(struct iwch_qp *qhp); | ||
325 | int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | 327 | int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, |
326 | struct ib_send_wr **bad_wr); | 328 | struct ib_send_wr **bad_wr); |
327 | int iwch_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, | 329 | int iwch_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, |
@@ -331,6 +333,7 @@ int iwch_bind_mw(struct ib_qp *qp, | |||
331 | struct ib_mw_bind *mw_bind); | 333 | struct ib_mw_bind *mw_bind); |
332 | int iwch_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc); | 334 | int iwch_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc); |
333 | int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg); | 335 | int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg); |
336 | int iwch_post_zb_read(struct iwch_qp *qhp); | ||
334 | int iwch_register_device(struct iwch_dev *dev); | 337 | int iwch_register_device(struct iwch_dev *dev); |
335 | void iwch_unregister_device(struct iwch_dev *dev); | 338 | void iwch_unregister_device(struct iwch_dev *dev); |
336 | int iwch_quiesce_qps(struct iwch_cq *chp); | 339 | int iwch_quiesce_qps(struct iwch_cq *chp); |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c index 8891c3b0a3d5..79dbe5beae52 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_qp.c +++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c | |||
@@ -586,6 +586,36 @@ static inline void build_term_codes(struct respQ_msg_t *rsp_msg, | |||
586 | } | 586 | } |
587 | } | 587 | } |
588 | 588 | ||
589 | int iwch_post_zb_read(struct iwch_qp *qhp) | ||
590 | { | ||
591 | union t3_wr *wqe; | ||
592 | struct sk_buff *skb; | ||
593 | u8 flit_cnt = sizeof(struct t3_rdma_read_wr) >> 3; | ||
594 | |||
595 | PDBG("%s enter\n", __func__); | ||
596 | skb = alloc_skb(40, GFP_KERNEL); | ||
597 | if (!skb) { | ||
598 | printk(KERN_ERR "%s cannot send zb_read!!\n", __func__); | ||
599 | return -ENOMEM; | ||
600 | } | ||
601 | wqe = (union t3_wr *)skb_put(skb, sizeof(struct t3_rdma_read_wr)); | ||
602 | memset(wqe, 0, sizeof(struct t3_rdma_read_wr)); | ||
603 | wqe->read.rdmaop = T3_READ_REQ; | ||
604 | wqe->read.reserved[0] = 0; | ||
605 | wqe->read.reserved[1] = 0; | ||
606 | wqe->read.reserved[2] = 0; | ||
607 | wqe->read.rem_stag = cpu_to_be32(1); | ||
608 | wqe->read.rem_to = cpu_to_be64(1); | ||
609 | wqe->read.local_stag = cpu_to_be32(1); | ||
610 | wqe->read.local_len = cpu_to_be32(0); | ||
611 | wqe->read.local_to = cpu_to_be64(1); | ||
612 | wqe->send.wrh.op_seop_flags = cpu_to_be32(V_FW_RIWR_OP(T3_WR_READ)); | ||
613 | wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid)| | ||
614 | V_FW_RIWR_LEN(flit_cnt)); | ||
615 | skb->priority = CPL_PRIORITY_DATA; | ||
616 | return cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb); | ||
617 | } | ||
618 | |||
589 | /* | 619 | /* |
590 | * This posts a TERMINATE with layer=RDMA, type=catastrophic. | 620 | * This posts a TERMINATE with layer=RDMA, type=catastrophic. |
591 | */ | 621 | */ |
@@ -625,6 +655,7 @@ static void __flush_qp(struct iwch_qp *qhp, unsigned long *flag) | |||
625 | { | 655 | { |
626 | struct iwch_cq *rchp, *schp; | 656 | struct iwch_cq *rchp, *schp; |
627 | int count; | 657 | int count; |
658 | int flushed; | ||
628 | 659 | ||
629 | rchp = get_chp(qhp->rhp, qhp->attr.rcq); | 660 | rchp = get_chp(qhp->rhp, qhp->attr.rcq); |
630 | schp = get_chp(qhp->rhp, qhp->attr.scq); | 661 | schp = get_chp(qhp->rhp, qhp->attr.scq); |
@@ -639,20 +670,22 @@ static void __flush_qp(struct iwch_qp *qhp, unsigned long *flag) | |||
639 | spin_lock(&qhp->lock); | 670 | spin_lock(&qhp->lock); |
640 | cxio_flush_hw_cq(&rchp->cq); | 671 | cxio_flush_hw_cq(&rchp->cq); |
641 | cxio_count_rcqes(&rchp->cq, &qhp->wq, &count); | 672 | cxio_count_rcqes(&rchp->cq, &qhp->wq, &count); |
642 | cxio_flush_rq(&qhp->wq, &rchp->cq, count); | 673 | flushed = cxio_flush_rq(&qhp->wq, &rchp->cq, count); |
643 | spin_unlock(&qhp->lock); | 674 | spin_unlock(&qhp->lock); |
644 | spin_unlock_irqrestore(&rchp->lock, *flag); | 675 | spin_unlock_irqrestore(&rchp->lock, *flag); |
645 | (*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context); | 676 | if (flushed) |
677 | (*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context); | ||
646 | 678 | ||
647 | /* locking heirarchy: cq lock first, then qp lock. */ | 679 | /* locking heirarchy: cq lock first, then qp lock. */ |
648 | spin_lock_irqsave(&schp->lock, *flag); | 680 | spin_lock_irqsave(&schp->lock, *flag); |
649 | spin_lock(&qhp->lock); | 681 | spin_lock(&qhp->lock); |
650 | cxio_flush_hw_cq(&schp->cq); | 682 | cxio_flush_hw_cq(&schp->cq); |
651 | cxio_count_scqes(&schp->cq, &qhp->wq, &count); | 683 | cxio_count_scqes(&schp->cq, &qhp->wq, &count); |
652 | cxio_flush_sq(&qhp->wq, &schp->cq, count); | 684 | flushed = cxio_flush_sq(&qhp->wq, &schp->cq, count); |
653 | spin_unlock(&qhp->lock); | 685 | spin_unlock(&qhp->lock); |
654 | spin_unlock_irqrestore(&schp->lock, *flag); | 686 | spin_unlock_irqrestore(&schp->lock, *flag); |
655 | (*schp->ibcq.comp_handler)(&schp->ibcq, schp->ibcq.cq_context); | 687 | if (flushed) |
688 | (*schp->ibcq.comp_handler)(&schp->ibcq, schp->ibcq.cq_context); | ||
656 | 689 | ||
657 | /* deref */ | 690 | /* deref */ |
658 | if (atomic_dec_and_test(&qhp->refcnt)) | 691 | if (atomic_dec_and_test(&qhp->refcnt)) |
@@ -671,11 +704,18 @@ static void flush_qp(struct iwch_qp *qhp, unsigned long *flag) | |||
671 | 704 | ||
672 | 705 | ||
673 | /* | 706 | /* |
674 | * Return non zero if at least one RECV was pre-posted. | 707 | * Return count of RECV WRs posted |
675 | */ | 708 | */ |
676 | static int rqes_posted(struct iwch_qp *qhp) | 709 | u16 iwch_rqes_posted(struct iwch_qp *qhp) |
677 | { | 710 | { |
678 | return fw_riwrh_opcode((struct fw_riwrh *)qhp->wq.queue) == T3_WR_RCV; | 711 | union t3_wr *wqe = qhp->wq.queue; |
712 | u16 count = 0; | ||
713 | while ((count+1) != 0 && fw_riwrh_opcode((struct fw_riwrh *)wqe) == T3_WR_RCV) { | ||
714 | count++; | ||
715 | wqe++; | ||
716 | } | ||
717 | PDBG("%s qhp %p count %u\n", __func__, qhp, count); | ||
718 | return count; | ||
679 | } | 719 | } |
680 | 720 | ||
681 | static int rdma_init(struct iwch_dev *rhp, struct iwch_qp *qhp, | 721 | static int rdma_init(struct iwch_dev *rhp, struct iwch_qp *qhp, |
@@ -716,8 +756,17 @@ static int rdma_init(struct iwch_dev *rhp, struct iwch_qp *qhp, | |||
716 | init_attr.ird = qhp->attr.max_ird; | 756 | init_attr.ird = qhp->attr.max_ird; |
717 | init_attr.qp_dma_addr = qhp->wq.dma_addr; | 757 | init_attr.qp_dma_addr = qhp->wq.dma_addr; |
718 | init_attr.qp_dma_size = (1UL << qhp->wq.size_log2); | 758 | init_attr.qp_dma_size = (1UL << qhp->wq.size_log2); |
719 | init_attr.flags = rqes_posted(qhp) ? RECVS_POSTED : 0; | 759 | init_attr.rqe_count = iwch_rqes_posted(qhp); |
760 | init_attr.flags = qhp->attr.mpa_attr.initiator ? MPA_INITIATOR : 0; | ||
720 | init_attr.flags |= capable(CAP_NET_BIND_SERVICE) ? PRIV_QP : 0; | 761 | init_attr.flags |= capable(CAP_NET_BIND_SERVICE) ? PRIV_QP : 0; |
762 | if (peer2peer) { | ||
763 | init_attr.rtr_type = RTR_READ; | ||
764 | if (init_attr.ord == 0 && qhp->attr.mpa_attr.initiator) | ||
765 | init_attr.ord = 1; | ||
766 | if (init_attr.ird == 0 && !qhp->attr.mpa_attr.initiator) | ||
767 | init_attr.ird = 1; | ||
768 | } else | ||
769 | init_attr.rtr_type = 0; | ||
721 | init_attr.irs = qhp->ep->rcv_seq; | 770 | init_attr.irs = qhp->ep->rcv_seq; |
722 | PDBG("%s init_attr.rq_addr 0x%x init_attr.rq_size = %d " | 771 | PDBG("%s init_attr.rq_addr 0x%x init_attr.rq_size = %d " |
723 | "flags 0x%x qpcaps 0x%x\n", __func__, | 772 | "flags 0x%x qpcaps 0x%x\n", __func__, |
@@ -832,8 +881,8 @@ int iwch_modify_qp(struct iwch_dev *rhp, struct iwch_qp *qhp, | |||
832 | abort=0; | 881 | abort=0; |
833 | disconnect = 1; | 882 | disconnect = 1; |
834 | ep = qhp->ep; | 883 | ep = qhp->ep; |
884 | get_ep(&ep->com); | ||
835 | } | 885 | } |
836 | flush_qp(qhp, &flag); | ||
837 | break; | 886 | break; |
838 | case IWCH_QP_STATE_TERMINATE: | 887 | case IWCH_QP_STATE_TERMINATE: |
839 | qhp->attr.state = IWCH_QP_STATE_TERMINATE; | 888 | qhp->attr.state = IWCH_QP_STATE_TERMINATE; |
@@ -848,6 +897,7 @@ int iwch_modify_qp(struct iwch_dev *rhp, struct iwch_qp *qhp, | |||
848 | abort=1; | 897 | abort=1; |
849 | disconnect = 1; | 898 | disconnect = 1; |
850 | ep = qhp->ep; | 899 | ep = qhp->ep; |
900 | get_ep(&ep->com); | ||
851 | } | 901 | } |
852 | goto err; | 902 | goto err; |
853 | break; | 903 | break; |
@@ -863,6 +913,7 @@ int iwch_modify_qp(struct iwch_dev *rhp, struct iwch_qp *qhp, | |||
863 | } | 913 | } |
864 | switch (attrs->next_state) { | 914 | switch (attrs->next_state) { |
865 | case IWCH_QP_STATE_IDLE: | 915 | case IWCH_QP_STATE_IDLE: |
916 | flush_qp(qhp, &flag); | ||
866 | qhp->attr.state = IWCH_QP_STATE_IDLE; | 917 | qhp->attr.state = IWCH_QP_STATE_IDLE; |
867 | qhp->attr.llp_stream_handle = NULL; | 918 | qhp->attr.llp_stream_handle = NULL; |
868 | put_ep(&qhp->ep->com); | 919 | put_ep(&qhp->ep->com); |
@@ -929,8 +980,10 @@ out: | |||
929 | * on the EP. This can be a normal close (RTS->CLOSING) or | 980 | * on the EP. This can be a normal close (RTS->CLOSING) or |
930 | * an abnormal close (RTS/CLOSING->ERROR). | 981 | * an abnormal close (RTS/CLOSING->ERROR). |
931 | */ | 982 | */ |
932 | if (disconnect) | 983 | if (disconnect) { |
933 | iwch_ep_disconnect(ep, abort, GFP_KERNEL); | 984 | iwch_ep_disconnect(ep, abort, GFP_KERNEL); |
985 | put_ep(&ep->com); | ||
986 | } | ||
934 | 987 | ||
935 | /* | 988 | /* |
936 | * If free is 1, then we've disassociated the EP from the QP | 989 | * If free is 1, then we've disassociated the EP from the QP |
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h index 0d13fe0a260b..00bab60f6de4 100644 --- a/drivers/infiniband/hw/ehca/ehca_classes.h +++ b/drivers/infiniband/hw/ehca/ehca_classes.h | |||
@@ -66,6 +66,7 @@ struct ehca_av; | |||
66 | #include "ehca_irq.h" | 66 | #include "ehca_irq.h" |
67 | 67 | ||
68 | #define EHCA_EQE_CACHE_SIZE 20 | 68 | #define EHCA_EQE_CACHE_SIZE 20 |
69 | #define EHCA_MAX_NUM_QUEUES 0xffff | ||
69 | 70 | ||
70 | struct ehca_eqe_cache_entry { | 71 | struct ehca_eqe_cache_entry { |
71 | struct ehca_eqe *eqe; | 72 | struct ehca_eqe *eqe; |
@@ -127,6 +128,8 @@ struct ehca_shca { | |||
127 | /* MR pgsize: bit 0-3 means 4K, 64K, 1M, 16M respectively */ | 128 | /* MR pgsize: bit 0-3 means 4K, 64K, 1M, 16M respectively */ |
128 | u32 hca_cap_mr_pgsize; | 129 | u32 hca_cap_mr_pgsize; |
129 | int max_mtu; | 130 | int max_mtu; |
131 | atomic_t num_cqs; | ||
132 | atomic_t num_qps; | ||
130 | }; | 133 | }; |
131 | 134 | ||
132 | struct ehca_pd { | 135 | struct ehca_pd { |
@@ -160,6 +163,7 @@ struct ehca_qp { | |||
160 | }; | 163 | }; |
161 | u32 qp_type; | 164 | u32 qp_type; |
162 | enum ehca_ext_qp_type ext_type; | 165 | enum ehca_ext_qp_type ext_type; |
166 | enum ib_qp_state state; | ||
163 | struct ipz_queue ipz_squeue; | 167 | struct ipz_queue ipz_squeue; |
164 | struct ipz_queue ipz_rqueue; | 168 | struct ipz_queue ipz_rqueue; |
165 | struct h_galpas galpas; | 169 | struct h_galpas galpas; |
@@ -343,6 +347,8 @@ extern int ehca_use_hp_mr; | |||
343 | extern int ehca_scaling_code; | 347 | extern int ehca_scaling_code; |
344 | extern int ehca_lock_hcalls; | 348 | extern int ehca_lock_hcalls; |
345 | extern int ehca_nr_ports; | 349 | extern int ehca_nr_ports; |
350 | extern int ehca_max_cq; | ||
351 | extern int ehca_max_qp; | ||
346 | 352 | ||
347 | struct ipzu_queue_resp { | 353 | struct ipzu_queue_resp { |
348 | u32 qe_size; /* queue entry size */ | 354 | u32 qe_size; /* queue entry size */ |
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c index ec0cfcf3073f..5540b276a33c 100644 --- a/drivers/infiniband/hw/ehca/ehca_cq.c +++ b/drivers/infiniband/hw/ehca/ehca_cq.c | |||
@@ -132,10 +132,19 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, | |||
132 | if (cqe >= 0xFFFFFFFF - 64 - additional_cqe) | 132 | if (cqe >= 0xFFFFFFFF - 64 - additional_cqe) |
133 | return ERR_PTR(-EINVAL); | 133 | return ERR_PTR(-EINVAL); |
134 | 134 | ||
135 | if (!atomic_add_unless(&shca->num_cqs, 1, ehca_max_cq)) { | ||
136 | ehca_err(device, "Unable to create CQ, max number of %i " | ||
137 | "CQs reached.", ehca_max_cq); | ||
138 | ehca_err(device, "To increase the maximum number of CQs " | ||
139 | "use the number_of_cqs module parameter.\n"); | ||
140 | return ERR_PTR(-ENOSPC); | ||
141 | } | ||
142 | |||
135 | my_cq = kmem_cache_zalloc(cq_cache, GFP_KERNEL); | 143 | my_cq = kmem_cache_zalloc(cq_cache, GFP_KERNEL); |
136 | if (!my_cq) { | 144 | if (!my_cq) { |
137 | ehca_err(device, "Out of memory for ehca_cq struct device=%p", | 145 | ehca_err(device, "Out of memory for ehca_cq struct device=%p", |
138 | device); | 146 | device); |
147 | atomic_dec(&shca->num_cqs); | ||
139 | return ERR_PTR(-ENOMEM); | 148 | return ERR_PTR(-ENOMEM); |
140 | } | 149 | } |
141 | 150 | ||
@@ -305,6 +314,7 @@ create_cq_exit2: | |||
305 | create_cq_exit1: | 314 | create_cq_exit1: |
306 | kmem_cache_free(cq_cache, my_cq); | 315 | kmem_cache_free(cq_cache, my_cq); |
307 | 316 | ||
317 | atomic_dec(&shca->num_cqs); | ||
308 | return cq; | 318 | return cq; |
309 | } | 319 | } |
310 | 320 | ||
@@ -359,6 +369,7 @@ int ehca_destroy_cq(struct ib_cq *cq) | |||
359 | ipz_queue_dtor(NULL, &my_cq->ipz_queue); | 369 | ipz_queue_dtor(NULL, &my_cq->ipz_queue); |
360 | kmem_cache_free(cq_cache, my_cq); | 370 | kmem_cache_free(cq_cache, my_cq); |
361 | 371 | ||
372 | atomic_dec(&shca->num_cqs); | ||
362 | return 0; | 373 | return 0; |
363 | } | 374 | } |
364 | 375 | ||
diff --git a/drivers/infiniband/hw/ehca/ehca_eq.c b/drivers/infiniband/hw/ehca/ehca_eq.c index b4ac617a70e6..49660dfa1867 100644 --- a/drivers/infiniband/hw/ehca/ehca_eq.c +++ b/drivers/infiniband/hw/ehca/ehca_eq.c | |||
@@ -54,7 +54,8 @@ int ehca_create_eq(struct ehca_shca *shca, | |||
54 | struct ehca_eq *eq, | 54 | struct ehca_eq *eq, |
55 | const enum ehca_eq_type type, const u32 length) | 55 | const enum ehca_eq_type type, const u32 length) |
56 | { | 56 | { |
57 | u64 ret; | 57 | int ret; |
58 | u64 h_ret; | ||
58 | u32 nr_pages; | 59 | u32 nr_pages; |
59 | u32 i; | 60 | u32 i; |
60 | void *vpage; | 61 | void *vpage; |
@@ -73,15 +74,15 @@ int ehca_create_eq(struct ehca_shca *shca, | |||
73 | return -EINVAL; | 74 | return -EINVAL; |
74 | } | 75 | } |
75 | 76 | ||
76 | ret = hipz_h_alloc_resource_eq(shca->ipz_hca_handle, | 77 | h_ret = hipz_h_alloc_resource_eq(shca->ipz_hca_handle, |
77 | &eq->pf, | 78 | &eq->pf, |
78 | type, | 79 | type, |
79 | length, | 80 | length, |
80 | &eq->ipz_eq_handle, | 81 | &eq->ipz_eq_handle, |
81 | &eq->length, | 82 | &eq->length, |
82 | &nr_pages, &eq->ist); | 83 | &nr_pages, &eq->ist); |
83 | 84 | ||
84 | if (ret != H_SUCCESS) { | 85 | if (h_ret != H_SUCCESS) { |
85 | ehca_err(ib_dev, "Can't allocate EQ/NEQ. eq=%p", eq); | 86 | ehca_err(ib_dev, "Can't allocate EQ/NEQ. eq=%p", eq); |
86 | return -EINVAL; | 87 | return -EINVAL; |
87 | } | 88 | } |
@@ -97,24 +98,22 @@ int ehca_create_eq(struct ehca_shca *shca, | |||
97 | u64 rpage; | 98 | u64 rpage; |
98 | 99 | ||
99 | vpage = ipz_qpageit_get_inc(&eq->ipz_queue); | 100 | vpage = ipz_qpageit_get_inc(&eq->ipz_queue); |
100 | if (!vpage) { | 101 | if (!vpage) |
101 | ret = H_RESOURCE; | ||
102 | goto create_eq_exit2; | 102 | goto create_eq_exit2; |
103 | } | ||
104 | 103 | ||
105 | rpage = virt_to_abs(vpage); | 104 | rpage = virt_to_abs(vpage); |
106 | ret = hipz_h_register_rpage_eq(shca->ipz_hca_handle, | 105 | h_ret = hipz_h_register_rpage_eq(shca->ipz_hca_handle, |
107 | eq->ipz_eq_handle, | 106 | eq->ipz_eq_handle, |
108 | &eq->pf, | 107 | &eq->pf, |
109 | 0, 0, rpage, 1); | 108 | 0, 0, rpage, 1); |
110 | 109 | ||
111 | if (i == (nr_pages - 1)) { | 110 | if (i == (nr_pages - 1)) { |
112 | /* last page */ | 111 | /* last page */ |
113 | vpage = ipz_qpageit_get_inc(&eq->ipz_queue); | 112 | vpage = ipz_qpageit_get_inc(&eq->ipz_queue); |
114 | if (ret != H_SUCCESS || vpage) | 113 | if (h_ret != H_SUCCESS || vpage) |
115 | goto create_eq_exit2; | 114 | goto create_eq_exit2; |
116 | } else { | 115 | } else { |
117 | if (ret != H_PAGE_REGISTERED || !vpage) | 116 | if (h_ret != H_PAGE_REGISTERED || !vpage) |
118 | goto create_eq_exit2; | 117 | goto create_eq_exit2; |
119 | } | 118 | } |
120 | } | 119 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c index 2515cbde7e65..bc3b37d2070f 100644 --- a/drivers/infiniband/hw/ehca/ehca_hca.c +++ b/drivers/infiniband/hw/ehca/ehca_hca.c | |||
@@ -101,7 +101,6 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) | |||
101 | props->max_ee = limit_uint(rblock->max_rd_ee_context); | 101 | props->max_ee = limit_uint(rblock->max_rd_ee_context); |
102 | props->max_rdd = limit_uint(rblock->max_rd_domain); | 102 | props->max_rdd = limit_uint(rblock->max_rd_domain); |
103 | props->max_fmr = limit_uint(rblock->max_mr); | 103 | props->max_fmr = limit_uint(rblock->max_mr); |
104 | props->local_ca_ack_delay = limit_uint(rblock->local_ca_ack_delay); | ||
105 | props->max_qp_rd_atom = limit_uint(rblock->max_rr_qp); | 104 | props->max_qp_rd_atom = limit_uint(rblock->max_rr_qp); |
106 | props->max_ee_rd_atom = limit_uint(rblock->max_rr_ee_context); | 105 | props->max_ee_rd_atom = limit_uint(rblock->max_rr_ee_context); |
107 | props->max_res_rd_atom = limit_uint(rblock->max_rr_hca); | 106 | props->max_res_rd_atom = limit_uint(rblock->max_rr_hca); |
@@ -115,7 +114,7 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) | |||
115 | } | 114 | } |
116 | 115 | ||
117 | props->max_pkeys = 16; | 116 | props->max_pkeys = 16; |
118 | props->local_ca_ack_delay = limit_uint(rblock->local_ca_ack_delay); | 117 | props->local_ca_ack_delay = min_t(u8, rblock->local_ca_ack_delay, 255); |
119 | props->max_raw_ipv6_qp = limit_uint(rblock->max_raw_ipv6_qp); | 118 | props->max_raw_ipv6_qp = limit_uint(rblock->max_raw_ipv6_qp); |
120 | props->max_raw_ethy_qp = limit_uint(rblock->max_raw_ethy_qp); | 119 | props->max_raw_ethy_qp = limit_uint(rblock->max_raw_ethy_qp); |
121 | props->max_mcast_grp = limit_uint(rblock->max_mcast_grp); | 120 | props->max_mcast_grp = limit_uint(rblock->max_mcast_grp); |
@@ -136,7 +135,7 @@ query_device1: | |||
136 | return ret; | 135 | return ret; |
137 | } | 136 | } |
138 | 137 | ||
139 | static int map_mtu(struct ehca_shca *shca, u32 fw_mtu) | 138 | static enum ib_mtu map_mtu(struct ehca_shca *shca, u32 fw_mtu) |
140 | { | 139 | { |
141 | switch (fw_mtu) { | 140 | switch (fw_mtu) { |
142 | case 0x1: | 141 | case 0x1: |
@@ -156,7 +155,7 @@ static int map_mtu(struct ehca_shca *shca, u32 fw_mtu) | |||
156 | } | 155 | } |
157 | } | 156 | } |
158 | 157 | ||
159 | static int map_number_of_vls(struct ehca_shca *shca, u32 vl_cap) | 158 | static u8 map_number_of_vls(struct ehca_shca *shca, u32 vl_cap) |
160 | { | 159 | { |
161 | switch (vl_cap) { | 160 | switch (vl_cap) { |
162 | case 0x1: | 161 | case 0x1: |
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index b5ca94c6b8d9..ca5eb0cb628c 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c | |||
@@ -633,7 +633,7 @@ static inline int find_next_online_cpu(struct ehca_comp_pool *pool) | |||
633 | unsigned long flags; | 633 | unsigned long flags; |
634 | 634 | ||
635 | WARN_ON_ONCE(!in_interrupt()); | 635 | WARN_ON_ONCE(!in_interrupt()); |
636 | if (ehca_debug_level) | 636 | if (ehca_debug_level >= 3) |
637 | ehca_dmp(&cpu_online_map, sizeof(cpumask_t), ""); | 637 | ehca_dmp(&cpu_online_map, sizeof(cpumask_t), ""); |
638 | 638 | ||
639 | spin_lock_irqsave(&pool->last_cpu_lock, flags); | 639 | spin_lock_irqsave(&pool->last_cpu_lock, flags); |
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 65b3362cdb9b..482103eb6eac 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c | |||
@@ -50,7 +50,7 @@ | |||
50 | #include "ehca_tools.h" | 50 | #include "ehca_tools.h" |
51 | #include "hcp_if.h" | 51 | #include "hcp_if.h" |
52 | 52 | ||
53 | #define HCAD_VERSION "0025" | 53 | #define HCAD_VERSION "0026" |
54 | 54 | ||
55 | MODULE_LICENSE("Dual BSD/GPL"); | 55 | MODULE_LICENSE("Dual BSD/GPL"); |
56 | MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>"); | 56 | MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>"); |
@@ -60,7 +60,6 @@ MODULE_VERSION(HCAD_VERSION); | |||
60 | static int ehca_open_aqp1 = 0; | 60 | static int ehca_open_aqp1 = 0; |
61 | static int ehca_hw_level = 0; | 61 | static int ehca_hw_level = 0; |
62 | static int ehca_poll_all_eqs = 1; | 62 | static int ehca_poll_all_eqs = 1; |
63 | static int ehca_mr_largepage = 1; | ||
64 | 63 | ||
65 | int ehca_debug_level = 0; | 64 | int ehca_debug_level = 0; |
66 | int ehca_nr_ports = 2; | 65 | int ehca_nr_ports = 2; |
@@ -69,47 +68,52 @@ int ehca_port_act_time = 30; | |||
69 | int ehca_static_rate = -1; | 68 | int ehca_static_rate = -1; |
70 | int ehca_scaling_code = 0; | 69 | int ehca_scaling_code = 0; |
71 | int ehca_lock_hcalls = -1; | 70 | int ehca_lock_hcalls = -1; |
72 | 71 | int ehca_max_cq = -1; | |
73 | module_param_named(open_aqp1, ehca_open_aqp1, int, S_IRUGO); | 72 | int ehca_max_qp = -1; |
74 | module_param_named(debug_level, ehca_debug_level, int, S_IRUGO); | 73 | |
75 | module_param_named(hw_level, ehca_hw_level, int, S_IRUGO); | 74 | module_param_named(open_aqp1, ehca_open_aqp1, bool, S_IRUGO); |
76 | module_param_named(nr_ports, ehca_nr_ports, int, S_IRUGO); | 75 | module_param_named(debug_level, ehca_debug_level, int, S_IRUGO); |
77 | module_param_named(use_hp_mr, ehca_use_hp_mr, int, S_IRUGO); | 76 | module_param_named(hw_level, ehca_hw_level, int, S_IRUGO); |
78 | module_param_named(port_act_time, ehca_port_act_time, int, S_IRUGO); | 77 | module_param_named(nr_ports, ehca_nr_ports, int, S_IRUGO); |
79 | module_param_named(poll_all_eqs, ehca_poll_all_eqs, int, S_IRUGO); | 78 | module_param_named(use_hp_mr, ehca_use_hp_mr, bool, S_IRUGO); |
80 | module_param_named(static_rate, ehca_static_rate, int, S_IRUGO); | 79 | module_param_named(port_act_time, ehca_port_act_time, int, S_IRUGO); |
81 | module_param_named(scaling_code, ehca_scaling_code, int, S_IRUGO); | 80 | module_param_named(poll_all_eqs, ehca_poll_all_eqs, bool, S_IRUGO); |
82 | module_param_named(mr_largepage, ehca_mr_largepage, int, S_IRUGO); | 81 | module_param_named(static_rate, ehca_static_rate, int, S_IRUGO); |
82 | module_param_named(scaling_code, ehca_scaling_code, bool, S_IRUGO); | ||
83 | module_param_named(lock_hcalls, ehca_lock_hcalls, bool, S_IRUGO); | 83 | module_param_named(lock_hcalls, ehca_lock_hcalls, bool, S_IRUGO); |
84 | module_param_named(number_of_cqs, ehca_max_cq, int, S_IRUGO); | ||
85 | module_param_named(number_of_qps, ehca_max_qp, int, S_IRUGO); | ||
84 | 86 | ||
85 | MODULE_PARM_DESC(open_aqp1, | 87 | MODULE_PARM_DESC(open_aqp1, |
86 | "AQP1 on startup (0: no (default), 1: yes)"); | 88 | "Open AQP1 on startup (default: no)"); |
87 | MODULE_PARM_DESC(debug_level, | 89 | MODULE_PARM_DESC(debug_level, |
88 | "debug level" | 90 | "Amount of debug output (0: none (default), 1: traces, " |
89 | " (0: no debug traces (default), 1: with debug traces)"); | 91 | "2: some dumps, 3: lots)"); |
90 | MODULE_PARM_DESC(hw_level, | 92 | MODULE_PARM_DESC(hw_level, |
91 | "hardware level" | 93 | "Hardware level (0: autosensing (default), " |
92 | " (0: autosensing (default), 1: v. 0.20, 2: v. 0.21)"); | 94 | "0x10..0x14: eHCA, 0x20..0x23: eHCA2)"); |
93 | MODULE_PARM_DESC(nr_ports, | 95 | MODULE_PARM_DESC(nr_ports, |
94 | "number of connected ports (-1: autodetect, 1: port one only, " | 96 | "number of connected ports (-1: autodetect, 1: port one only, " |
95 | "2: two ports (default)"); | 97 | "2: two ports (default)"); |
96 | MODULE_PARM_DESC(use_hp_mr, | 98 | MODULE_PARM_DESC(use_hp_mr, |
97 | "high performance MRs (0: no (default), 1: yes)"); | 99 | "Use high performance MRs (default: no)"); |
98 | MODULE_PARM_DESC(port_act_time, | 100 | MODULE_PARM_DESC(port_act_time, |
99 | "time to wait for port activation (default: 30 sec)"); | 101 | "Time to wait for port activation (default: 30 sec)"); |
100 | MODULE_PARM_DESC(poll_all_eqs, | 102 | MODULE_PARM_DESC(poll_all_eqs, |
101 | "polls all event queues periodically" | 103 | "Poll all event queues periodically (default: yes)"); |
102 | " (0: no, 1: yes (default))"); | ||
103 | MODULE_PARM_DESC(static_rate, | 104 | MODULE_PARM_DESC(static_rate, |
104 | "set permanent static rate (default: disabled)"); | 105 | "Set permanent static rate (default: no static rate)"); |
105 | MODULE_PARM_DESC(scaling_code, | 106 | MODULE_PARM_DESC(scaling_code, |
106 | "set scaling code (0: disabled/default, 1: enabled)"); | 107 | "Enable scaling code (default: no)"); |
107 | MODULE_PARM_DESC(mr_largepage, | ||
108 | "use large page for MR (0: use PAGE_SIZE (default), " | ||
109 | "1: use large page depending on MR size"); | ||
110 | MODULE_PARM_DESC(lock_hcalls, | 108 | MODULE_PARM_DESC(lock_hcalls, |
111 | "serialize all hCalls made by the driver " | 109 | "Serialize all hCalls made by the driver " |
112 | "(default: autodetect)"); | 110 | "(default: autodetect)"); |
111 | MODULE_PARM_DESC(number_of_cqs, | ||
112 | "Max number of CQs which can be allocated " | ||
113 | "(default: autodetect)"); | ||
114 | MODULE_PARM_DESC(number_of_qps, | ||
115 | "Max number of QPs which can be allocated " | ||
116 | "(default: autodetect)"); | ||
113 | 117 | ||
114 | DEFINE_RWLOCK(ehca_qp_idr_lock); | 118 | DEFINE_RWLOCK(ehca_qp_idr_lock); |
115 | DEFINE_RWLOCK(ehca_cq_idr_lock); | 119 | DEFINE_RWLOCK(ehca_cq_idr_lock); |
@@ -275,6 +279,7 @@ static int ehca_sense_attributes(struct ehca_shca *shca) | |||
275 | u64 h_ret; | 279 | u64 h_ret; |
276 | struct hipz_query_hca *rblock; | 280 | struct hipz_query_hca *rblock; |
277 | struct hipz_query_port *port; | 281 | struct hipz_query_port *port; |
282 | const char *loc_code; | ||
278 | 283 | ||
279 | static const u32 pgsize_map[] = { | 284 | static const u32 pgsize_map[] = { |
280 | HCA_CAP_MR_PGSIZE_4K, 0x1000, | 285 | HCA_CAP_MR_PGSIZE_4K, 0x1000, |
@@ -283,6 +288,12 @@ static int ehca_sense_attributes(struct ehca_shca *shca) | |||
283 | HCA_CAP_MR_PGSIZE_16M, 0x1000000, | 288 | HCA_CAP_MR_PGSIZE_16M, 0x1000000, |
284 | }; | 289 | }; |
285 | 290 | ||
291 | ehca_gen_dbg("Probing adapter %s...", | ||
292 | shca->ofdev->node->full_name); | ||
293 | loc_code = of_get_property(shca->ofdev->node, "ibm,loc-code", NULL); | ||
294 | if (loc_code) | ||
295 | ehca_gen_dbg(" ... location lode=%s", loc_code); | ||
296 | |||
286 | rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL); | 297 | rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL); |
287 | if (!rblock) { | 298 | if (!rblock) { |
288 | ehca_gen_err("Cannot allocate rblock memory."); | 299 | ehca_gen_err("Cannot allocate rblock memory."); |
@@ -350,10 +361,27 @@ static int ehca_sense_attributes(struct ehca_shca *shca) | |||
350 | 361 | ||
351 | /* translate supported MR page sizes; always support 4K */ | 362 | /* translate supported MR page sizes; always support 4K */ |
352 | shca->hca_cap_mr_pgsize = EHCA_PAGESIZE; | 363 | shca->hca_cap_mr_pgsize = EHCA_PAGESIZE; |
353 | if (ehca_mr_largepage) { /* support extra sizes only if enabled */ | 364 | for (i = 0; i < ARRAY_SIZE(pgsize_map); i += 2) |
354 | for (i = 0; i < ARRAY_SIZE(pgsize_map); i += 2) | 365 | if (rblock->memory_page_size_supported & pgsize_map[i]) |
355 | if (rblock->memory_page_size_supported & pgsize_map[i]) | 366 | shca->hca_cap_mr_pgsize |= pgsize_map[i + 1]; |
356 | shca->hca_cap_mr_pgsize |= pgsize_map[i + 1]; | 367 | |
368 | /* Set maximum number of CQs and QPs to calculate EQ size */ | ||
369 | if (ehca_max_qp == -1) | ||
370 | ehca_max_qp = min_t(int, rblock->max_qp, EHCA_MAX_NUM_QUEUES); | ||
371 | else if (ehca_max_qp < 1 || ehca_max_qp > rblock->max_qp) { | ||
372 | ehca_gen_err("Requested number of QPs is out of range (1 - %i) " | ||
373 | "specified by HW", rblock->max_qp); | ||
374 | ret = -EINVAL; | ||
375 | goto sense_attributes1; | ||
376 | } | ||
377 | |||
378 | if (ehca_max_cq == -1) | ||
379 | ehca_max_cq = min_t(int, rblock->max_cq, EHCA_MAX_NUM_QUEUES); | ||
380 | else if (ehca_max_cq < 1 || ehca_max_cq > rblock->max_cq) { | ||
381 | ehca_gen_err("Requested number of CQs is out of range (1 - %i) " | ||
382 | "specified by HW", rblock->max_cq); | ||
383 | ret = -EINVAL; | ||
384 | goto sense_attributes1; | ||
357 | } | 385 | } |
358 | 386 | ||
359 | /* query max MTU from first port -- it's the same for all ports */ | 387 | /* query max MTU from first port -- it's the same for all ports */ |
@@ -567,8 +595,7 @@ static int ehca_destroy_aqp1(struct ehca_sport *sport) | |||
567 | 595 | ||
568 | static ssize_t ehca_show_debug_level(struct device_driver *ddp, char *buf) | 596 | static ssize_t ehca_show_debug_level(struct device_driver *ddp, char *buf) |
569 | { | 597 | { |
570 | return snprintf(buf, PAGE_SIZE, "%d\n", | 598 | return snprintf(buf, PAGE_SIZE, "%d\n", ehca_debug_level); |
571 | ehca_debug_level); | ||
572 | } | 599 | } |
573 | 600 | ||
574 | static ssize_t ehca_store_debug_level(struct device_driver *ddp, | 601 | static ssize_t ehca_store_debug_level(struct device_driver *ddp, |
@@ -657,14 +684,6 @@ static ssize_t ehca_show_adapter_handle(struct device *dev, | |||
657 | } | 684 | } |
658 | static DEVICE_ATTR(adapter_handle, S_IRUGO, ehca_show_adapter_handle, NULL); | 685 | static DEVICE_ATTR(adapter_handle, S_IRUGO, ehca_show_adapter_handle, NULL); |
659 | 686 | ||
660 | static ssize_t ehca_show_mr_largepage(struct device *dev, | ||
661 | struct device_attribute *attr, | ||
662 | char *buf) | ||
663 | { | ||
664 | return sprintf(buf, "%d\n", ehca_mr_largepage); | ||
665 | } | ||
666 | static DEVICE_ATTR(mr_largepage, S_IRUGO, ehca_show_mr_largepage, NULL); | ||
667 | |||
668 | static struct attribute *ehca_dev_attrs[] = { | 687 | static struct attribute *ehca_dev_attrs[] = { |
669 | &dev_attr_adapter_handle.attr, | 688 | &dev_attr_adapter_handle.attr, |
670 | &dev_attr_num_ports.attr, | 689 | &dev_attr_num_ports.attr, |
@@ -681,7 +700,6 @@ static struct attribute *ehca_dev_attrs[] = { | |||
681 | &dev_attr_cur_mw.attr, | 700 | &dev_attr_cur_mw.attr, |
682 | &dev_attr_max_pd.attr, | 701 | &dev_attr_max_pd.attr, |
683 | &dev_attr_max_ah.attr, | 702 | &dev_attr_max_ah.attr, |
684 | &dev_attr_mr_largepage.attr, | ||
685 | NULL | 703 | NULL |
686 | }; | 704 | }; |
687 | 705 | ||
@@ -695,7 +713,7 @@ static int __devinit ehca_probe(struct of_device *dev, | |||
695 | struct ehca_shca *shca; | 713 | struct ehca_shca *shca; |
696 | const u64 *handle; | 714 | const u64 *handle; |
697 | struct ib_pd *ibpd; | 715 | struct ib_pd *ibpd; |
698 | int ret, i; | 716 | int ret, i, eq_size; |
699 | 717 | ||
700 | handle = of_get_property(dev->node, "ibm,hca-handle", NULL); | 718 | handle = of_get_property(dev->node, "ibm,hca-handle", NULL); |
701 | if (!handle) { | 719 | if (!handle) { |
@@ -716,6 +734,8 @@ static int __devinit ehca_probe(struct of_device *dev, | |||
716 | return -ENOMEM; | 734 | return -ENOMEM; |
717 | } | 735 | } |
718 | mutex_init(&shca->modify_mutex); | 736 | mutex_init(&shca->modify_mutex); |
737 | atomic_set(&shca->num_cqs, 0); | ||
738 | atomic_set(&shca->num_qps, 0); | ||
719 | for (i = 0; i < ARRAY_SIZE(shca->sport); i++) | 739 | for (i = 0; i < ARRAY_SIZE(shca->sport); i++) |
720 | spin_lock_init(&shca->sport[i].mod_sqp_lock); | 740 | spin_lock_init(&shca->sport[i].mod_sqp_lock); |
721 | 741 | ||
@@ -735,8 +755,9 @@ static int __devinit ehca_probe(struct of_device *dev, | |||
735 | goto probe1; | 755 | goto probe1; |
736 | } | 756 | } |
737 | 757 | ||
758 | eq_size = 2 * ehca_max_cq + 4 * ehca_max_qp; | ||
738 | /* create event queues */ | 759 | /* create event queues */ |
739 | ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, 2048); | 760 | ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, eq_size); |
740 | if (ret) { | 761 | if (ret) { |
741 | ehca_err(&shca->ib_device, "Cannot create EQ."); | 762 | ehca_err(&shca->ib_device, "Cannot create EQ."); |
742 | goto probe1; | 763 | goto probe1; |
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c index f26997fc00f8..f974367cad40 100644 --- a/drivers/infiniband/hw/ehca/ehca_mrmw.c +++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c | |||
@@ -323,7 +323,7 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, | |||
323 | } | 323 | } |
324 | 324 | ||
325 | e_mr->umem = ib_umem_get(pd->uobject->context, start, length, | 325 | e_mr->umem = ib_umem_get(pd->uobject->context, start, length, |
326 | mr_access_flags); | 326 | mr_access_flags, 0); |
327 | if (IS_ERR(e_mr->umem)) { | 327 | if (IS_ERR(e_mr->umem)) { |
328 | ib_mr = (void *)e_mr->umem; | 328 | ib_mr = (void *)e_mr->umem; |
329 | goto reg_user_mr_exit1; | 329 | goto reg_user_mr_exit1; |
@@ -1794,8 +1794,9 @@ static int ehca_check_kpages_per_ate(struct scatterlist *page_list, | |||
1794 | int t; | 1794 | int t; |
1795 | for (t = start_idx; t <= end_idx; t++) { | 1795 | for (t = start_idx; t <= end_idx; t++) { |
1796 | u64 pgaddr = page_to_pfn(sg_page(&page_list[t])) << PAGE_SHIFT; | 1796 | u64 pgaddr = page_to_pfn(sg_page(&page_list[t])) << PAGE_SHIFT; |
1797 | ehca_gen_dbg("chunk_page=%lx value=%016lx", pgaddr, | 1797 | if (ehca_debug_level >= 3) |
1798 | *(u64 *)abs_to_virt(phys_to_abs(pgaddr))); | 1798 | ehca_gen_dbg("chunk_page=%lx value=%016lx", pgaddr, |
1799 | *(u64 *)abs_to_virt(phys_to_abs(pgaddr))); | ||
1799 | if (pgaddr - PAGE_SIZE != *prev_pgaddr) { | 1800 | if (pgaddr - PAGE_SIZE != *prev_pgaddr) { |
1800 | ehca_gen_err("uncontiguous page found pgaddr=%lx " | 1801 | ehca_gen_err("uncontiguous page found pgaddr=%lx " |
1801 | "prev_pgaddr=%lx page_list_i=%x", | 1802 | "prev_pgaddr=%lx page_list_i=%x", |
@@ -1862,10 +1863,13 @@ static int ehca_set_pagebuf_user2(struct ehca_mr_pginfo *pginfo, | |||
1862 | pgaddr & | 1863 | pgaddr & |
1863 | ~(pginfo->hwpage_size - 1)); | 1864 | ~(pginfo->hwpage_size - 1)); |
1864 | } | 1865 | } |
1865 | ehca_gen_dbg("kpage=%lx chunk_page=%lx " | 1866 | if (ehca_debug_level >= 3) { |
1866 | "value=%016lx", *kpage, pgaddr, | 1867 | u64 val = *(u64 *)abs_to_virt( |
1867 | *(u64 *)abs_to_virt( | 1868 | phys_to_abs(pgaddr)); |
1868 | phys_to_abs(pgaddr))); | 1869 | ehca_gen_dbg("kpage=%lx chunk_page=%lx " |
1870 | "value=%016lx", | ||
1871 | *kpage, pgaddr, val); | ||
1872 | } | ||
1869 | prev_pgaddr = pgaddr; | 1873 | prev_pgaddr = pgaddr; |
1870 | i++; | 1874 | i++; |
1871 | pginfo->kpage_cnt++; | 1875 | pginfo->kpage_cnt++; |
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index 3eb14a52cbf2..18fba92fa7ae 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c | |||
@@ -421,8 +421,18 @@ static struct ehca_qp *internal_create_qp( | |||
421 | u32 swqe_size = 0, rwqe_size = 0, ib_qp_num; | 421 | u32 swqe_size = 0, rwqe_size = 0, ib_qp_num; |
422 | unsigned long flags; | 422 | unsigned long flags; |
423 | 423 | ||
424 | if (init_attr->create_flags) | 424 | if (!atomic_add_unless(&shca->num_qps, 1, ehca_max_qp)) { |
425 | ehca_err(pd->device, "Unable to create QP, max number of %i " | ||
426 | "QPs reached.", ehca_max_qp); | ||
427 | ehca_err(pd->device, "To increase the maximum number of QPs " | ||
428 | "use the number_of_qps module parameter.\n"); | ||
429 | return ERR_PTR(-ENOSPC); | ||
430 | } | ||
431 | |||
432 | if (init_attr->create_flags) { | ||
433 | atomic_dec(&shca->num_qps); | ||
425 | return ERR_PTR(-EINVAL); | 434 | return ERR_PTR(-EINVAL); |
435 | } | ||
426 | 436 | ||
427 | memset(&parms, 0, sizeof(parms)); | 437 | memset(&parms, 0, sizeof(parms)); |
428 | qp_type = init_attr->qp_type; | 438 | qp_type = init_attr->qp_type; |
@@ -431,6 +441,7 @@ static struct ehca_qp *internal_create_qp( | |||
431 | init_attr->sq_sig_type != IB_SIGNAL_ALL_WR) { | 441 | init_attr->sq_sig_type != IB_SIGNAL_ALL_WR) { |
432 | ehca_err(pd->device, "init_attr->sg_sig_type=%x not allowed", | 442 | ehca_err(pd->device, "init_attr->sg_sig_type=%x not allowed", |
433 | init_attr->sq_sig_type); | 443 | init_attr->sq_sig_type); |
444 | atomic_dec(&shca->num_qps); | ||
434 | return ERR_PTR(-EINVAL); | 445 | return ERR_PTR(-EINVAL); |
435 | } | 446 | } |
436 | 447 | ||
@@ -455,6 +466,7 @@ static struct ehca_qp *internal_create_qp( | |||
455 | 466 | ||
456 | if (is_llqp && has_srq) { | 467 | if (is_llqp && has_srq) { |
457 | ehca_err(pd->device, "LLQPs can't have an SRQ"); | 468 | ehca_err(pd->device, "LLQPs can't have an SRQ"); |
469 | atomic_dec(&shca->num_qps); | ||
458 | return ERR_PTR(-EINVAL); | 470 | return ERR_PTR(-EINVAL); |
459 | } | 471 | } |
460 | 472 | ||
@@ -466,6 +478,7 @@ static struct ehca_qp *internal_create_qp( | |||
466 | ehca_err(pd->device, "no more than three SGEs " | 478 | ehca_err(pd->device, "no more than three SGEs " |
467 | "supported for SRQ pd=%p max_sge=%x", | 479 | "supported for SRQ pd=%p max_sge=%x", |
468 | pd, init_attr->cap.max_recv_sge); | 480 | pd, init_attr->cap.max_recv_sge); |
481 | atomic_dec(&shca->num_qps); | ||
469 | return ERR_PTR(-EINVAL); | 482 | return ERR_PTR(-EINVAL); |
470 | } | 483 | } |
471 | } | 484 | } |
@@ -477,6 +490,7 @@ static struct ehca_qp *internal_create_qp( | |||
477 | qp_type != IB_QPT_SMI && | 490 | qp_type != IB_QPT_SMI && |
478 | qp_type != IB_QPT_GSI) { | 491 | qp_type != IB_QPT_GSI) { |
479 | ehca_err(pd->device, "wrong QP Type=%x", qp_type); | 492 | ehca_err(pd->device, "wrong QP Type=%x", qp_type); |
493 | atomic_dec(&shca->num_qps); | ||
480 | return ERR_PTR(-EINVAL); | 494 | return ERR_PTR(-EINVAL); |
481 | } | 495 | } |
482 | 496 | ||
@@ -490,6 +504,7 @@ static struct ehca_qp *internal_create_qp( | |||
490 | "or max_rq_wr=%x for RC LLQP", | 504 | "or max_rq_wr=%x for RC LLQP", |
491 | init_attr->cap.max_send_wr, | 505 | init_attr->cap.max_send_wr, |
492 | init_attr->cap.max_recv_wr); | 506 | init_attr->cap.max_recv_wr); |
507 | atomic_dec(&shca->num_qps); | ||
493 | return ERR_PTR(-EINVAL); | 508 | return ERR_PTR(-EINVAL); |
494 | } | 509 | } |
495 | break; | 510 | break; |
@@ -497,6 +512,7 @@ static struct ehca_qp *internal_create_qp( | |||
497 | if (!EHCA_BMASK_GET(HCA_CAP_UD_LL_QP, shca->hca_cap)) { | 512 | if (!EHCA_BMASK_GET(HCA_CAP_UD_LL_QP, shca->hca_cap)) { |
498 | ehca_err(pd->device, "UD LLQP not supported " | 513 | ehca_err(pd->device, "UD LLQP not supported " |
499 | "by this adapter"); | 514 | "by this adapter"); |
515 | atomic_dec(&shca->num_qps); | ||
500 | return ERR_PTR(-ENOSYS); | 516 | return ERR_PTR(-ENOSYS); |
501 | } | 517 | } |
502 | if (!(init_attr->cap.max_send_sge <= 5 | 518 | if (!(init_attr->cap.max_send_sge <= 5 |
@@ -508,20 +524,22 @@ static struct ehca_qp *internal_create_qp( | |||
508 | "or max_recv_sge=%x for UD LLQP", | 524 | "or max_recv_sge=%x for UD LLQP", |
509 | init_attr->cap.max_send_sge, | 525 | init_attr->cap.max_send_sge, |
510 | init_attr->cap.max_recv_sge); | 526 | init_attr->cap.max_recv_sge); |
527 | atomic_dec(&shca->num_qps); | ||
511 | return ERR_PTR(-EINVAL); | 528 | return ERR_PTR(-EINVAL); |
512 | } else if (init_attr->cap.max_send_wr > 255) { | 529 | } else if (init_attr->cap.max_send_wr > 255) { |
513 | ehca_err(pd->device, | 530 | ehca_err(pd->device, |
514 | "Invalid Number of " | 531 | "Invalid Number of " |
515 | "max_send_wr=%x for UD QP_TYPE=%x", | 532 | "max_send_wr=%x for UD QP_TYPE=%x", |
516 | init_attr->cap.max_send_wr, qp_type); | 533 | init_attr->cap.max_send_wr, qp_type); |
534 | atomic_dec(&shca->num_qps); | ||
517 | return ERR_PTR(-EINVAL); | 535 | return ERR_PTR(-EINVAL); |
518 | } | 536 | } |
519 | break; | 537 | break; |
520 | default: | 538 | default: |
521 | ehca_err(pd->device, "unsupported LL QP Type=%x", | 539 | ehca_err(pd->device, "unsupported LL QP Type=%x", |
522 | qp_type); | 540 | qp_type); |
541 | atomic_dec(&shca->num_qps); | ||
523 | return ERR_PTR(-EINVAL); | 542 | return ERR_PTR(-EINVAL); |
524 | break; | ||
525 | } | 543 | } |
526 | } else { | 544 | } else { |
527 | int max_sge = (qp_type == IB_QPT_UD || qp_type == IB_QPT_SMI | 545 | int max_sge = (qp_type == IB_QPT_UD || qp_type == IB_QPT_SMI |
@@ -533,6 +551,7 @@ static struct ehca_qp *internal_create_qp( | |||
533 | "send_sge=%x recv_sge=%x max_sge=%x", | 551 | "send_sge=%x recv_sge=%x max_sge=%x", |
534 | init_attr->cap.max_send_sge, | 552 | init_attr->cap.max_send_sge, |
535 | init_attr->cap.max_recv_sge, max_sge); | 553 | init_attr->cap.max_recv_sge, max_sge); |
554 | atomic_dec(&shca->num_qps); | ||
536 | return ERR_PTR(-EINVAL); | 555 | return ERR_PTR(-EINVAL); |
537 | } | 556 | } |
538 | } | 557 | } |
@@ -543,6 +562,7 @@ static struct ehca_qp *internal_create_qp( | |||
543 | my_qp = kmem_cache_zalloc(qp_cache, GFP_KERNEL); | 562 | my_qp = kmem_cache_zalloc(qp_cache, GFP_KERNEL); |
544 | if (!my_qp) { | 563 | if (!my_qp) { |
545 | ehca_err(pd->device, "pd=%p not enough memory to alloc qp", pd); | 564 | ehca_err(pd->device, "pd=%p not enough memory to alloc qp", pd); |
565 | atomic_dec(&shca->num_qps); | ||
546 | return ERR_PTR(-ENOMEM); | 566 | return ERR_PTR(-ENOMEM); |
547 | } | 567 | } |
548 | 568 | ||
@@ -550,6 +570,7 @@ static struct ehca_qp *internal_create_qp( | |||
550 | spin_lock_init(&my_qp->spinlock_r); | 570 | spin_lock_init(&my_qp->spinlock_r); |
551 | my_qp->qp_type = qp_type; | 571 | my_qp->qp_type = qp_type; |
552 | my_qp->ext_type = parms.ext_type; | 572 | my_qp->ext_type = parms.ext_type; |
573 | my_qp->state = IB_QPS_RESET; | ||
553 | 574 | ||
554 | if (init_attr->recv_cq) | 575 | if (init_attr->recv_cq) |
555 | my_qp->recv_cq = | 576 | my_qp->recv_cq = |
@@ -822,6 +843,7 @@ create_qp_exit1: | |||
822 | 843 | ||
823 | create_qp_exit0: | 844 | create_qp_exit0: |
824 | kmem_cache_free(qp_cache, my_qp); | 845 | kmem_cache_free(qp_cache, my_qp); |
846 | atomic_dec(&shca->num_qps); | ||
825 | return ERR_PTR(ret); | 847 | return ERR_PTR(ret); |
826 | } | 848 | } |
827 | 849 | ||
@@ -965,7 +987,7 @@ static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca, | |||
965 | qp_num, bad_send_wqe_p); | 987 | qp_num, bad_send_wqe_p); |
966 | /* convert wqe pointer to vadr */ | 988 | /* convert wqe pointer to vadr */ |
967 | bad_send_wqe_v = abs_to_virt((u64)bad_send_wqe_p); | 989 | bad_send_wqe_v = abs_to_virt((u64)bad_send_wqe_p); |
968 | if (ehca_debug_level) | 990 | if (ehca_debug_level >= 2) |
969 | ehca_dmp(bad_send_wqe_v, 32, "qp_num=%x bad_wqe", qp_num); | 991 | ehca_dmp(bad_send_wqe_v, 32, "qp_num=%x bad_wqe", qp_num); |
970 | squeue = &my_qp->ipz_squeue; | 992 | squeue = &my_qp->ipz_squeue; |
971 | if (ipz_queue_abs_to_offset(squeue, (u64)bad_send_wqe_p, &q_ofs)) { | 993 | if (ipz_queue_abs_to_offset(squeue, (u64)bad_send_wqe_p, &q_ofs)) { |
@@ -978,7 +1000,7 @@ static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca, | |||
978 | wqe = (struct ehca_wqe *)ipz_qeit_calc(squeue, q_ofs); | 1000 | wqe = (struct ehca_wqe *)ipz_qeit_calc(squeue, q_ofs); |
979 | *bad_wqe_cnt = 0; | 1001 | *bad_wqe_cnt = 0; |
980 | while (wqe->optype != 0xff && wqe->wqef != 0xff) { | 1002 | while (wqe->optype != 0xff && wqe->wqef != 0xff) { |
981 | if (ehca_debug_level) | 1003 | if (ehca_debug_level >= 2) |
982 | ehca_dmp(wqe, 32, "qp_num=%x wqe", qp_num); | 1004 | ehca_dmp(wqe, 32, "qp_num=%x wqe", qp_num); |
983 | wqe->nr_of_data_seg = 0; /* suppress data access */ | 1005 | wqe->nr_of_data_seg = 0; /* suppress data access */ |
984 | wqe->wqef = WQEF_PURGE; /* WQE to be purged */ | 1006 | wqe->wqef = WQEF_PURGE; /* WQE to be purged */ |
@@ -1450,7 +1472,7 @@ static int internal_modify_qp(struct ib_qp *ibqp, | |||
1450 | /* no support for max_send/recv_sge yet */ | 1472 | /* no support for max_send/recv_sge yet */ |
1451 | } | 1473 | } |
1452 | 1474 | ||
1453 | if (ehca_debug_level) | 1475 | if (ehca_debug_level >= 2) |
1454 | ehca_dmp(mqpcb, 4*70, "qp_num=%x", ibqp->qp_num); | 1476 | ehca_dmp(mqpcb, 4*70, "qp_num=%x", ibqp->qp_num); |
1455 | 1477 | ||
1456 | h_ret = hipz_h_modify_qp(shca->ipz_hca_handle, | 1478 | h_ret = hipz_h_modify_qp(shca->ipz_hca_handle, |
@@ -1508,6 +1530,8 @@ static int internal_modify_qp(struct ib_qp *ibqp, | |||
1508 | if (attr_mask & IB_QP_QKEY) | 1530 | if (attr_mask & IB_QP_QKEY) |
1509 | my_qp->qkey = attr->qkey; | 1531 | my_qp->qkey = attr->qkey; |
1510 | 1532 | ||
1533 | my_qp->state = qp_new_state; | ||
1534 | |||
1511 | modify_qp_exit2: | 1535 | modify_qp_exit2: |
1512 | if (squeue_locked) { /* this means: sqe -> rts */ | 1536 | if (squeue_locked) { /* this means: sqe -> rts */ |
1513 | spin_unlock_irqrestore(&my_qp->spinlock_s, flags); | 1537 | spin_unlock_irqrestore(&my_qp->spinlock_s, flags); |
@@ -1763,7 +1787,7 @@ int ehca_query_qp(struct ib_qp *qp, | |||
1763 | if (qp_init_attr) | 1787 | if (qp_init_attr) |
1764 | *qp_init_attr = my_qp->init_attr; | 1788 | *qp_init_attr = my_qp->init_attr; |
1765 | 1789 | ||
1766 | if (ehca_debug_level) | 1790 | if (ehca_debug_level >= 2) |
1767 | ehca_dmp(qpcb, 4*70, "qp_num=%x", qp->qp_num); | 1791 | ehca_dmp(qpcb, 4*70, "qp_num=%x", qp->qp_num); |
1768 | 1792 | ||
1769 | query_qp_exit1: | 1793 | query_qp_exit1: |
@@ -1811,7 +1835,7 @@ int ehca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, | |||
1811 | goto modify_srq_exit0; | 1835 | goto modify_srq_exit0; |
1812 | } | 1836 | } |
1813 | 1837 | ||
1814 | if (ehca_debug_level) | 1838 | if (ehca_debug_level >= 2) |
1815 | ehca_dmp(mqpcb, 4*70, "qp_num=%x", my_qp->real_qp_num); | 1839 | ehca_dmp(mqpcb, 4*70, "qp_num=%x", my_qp->real_qp_num); |
1816 | 1840 | ||
1817 | h_ret = hipz_h_modify_qp(shca->ipz_hca_handle, my_qp->ipz_qp_handle, | 1841 | h_ret = hipz_h_modify_qp(shca->ipz_hca_handle, my_qp->ipz_qp_handle, |
@@ -1864,7 +1888,7 @@ int ehca_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr) | |||
1864 | srq_attr->srq_limit = EHCA_BMASK_GET( | 1888 | srq_attr->srq_limit = EHCA_BMASK_GET( |
1865 | MQPCB_CURR_SRQ_LIMIT, qpcb->curr_srq_limit); | 1889 | MQPCB_CURR_SRQ_LIMIT, qpcb->curr_srq_limit); |
1866 | 1890 | ||
1867 | if (ehca_debug_level) | 1891 | if (ehca_debug_level >= 2) |
1868 | ehca_dmp(qpcb, 4*70, "qp_num=%x", my_qp->real_qp_num); | 1892 | ehca_dmp(qpcb, 4*70, "qp_num=%x", my_qp->real_qp_num); |
1869 | 1893 | ||
1870 | query_srq_exit1: | 1894 | query_srq_exit1: |
@@ -1945,6 +1969,7 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp, | |||
1945 | if (HAS_SQ(my_qp)) | 1969 | if (HAS_SQ(my_qp)) |
1946 | ipz_queue_dtor(my_pd, &my_qp->ipz_squeue); | 1970 | ipz_queue_dtor(my_pd, &my_qp->ipz_squeue); |
1947 | kmem_cache_free(qp_cache, my_qp); | 1971 | kmem_cache_free(qp_cache, my_qp); |
1972 | atomic_dec(&shca->num_qps); | ||
1948 | return 0; | 1973 | return 0; |
1949 | } | 1974 | } |
1950 | 1975 | ||
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c index a20bbf466188..bbe0436f4f75 100644 --- a/drivers/infiniband/hw/ehca/ehca_reqs.c +++ b/drivers/infiniband/hw/ehca/ehca_reqs.c | |||
@@ -81,7 +81,7 @@ static inline int ehca_write_rwqe(struct ipz_queue *ipz_rqueue, | |||
81 | recv_wr->sg_list[cnt_ds].length; | 81 | recv_wr->sg_list[cnt_ds].length; |
82 | } | 82 | } |
83 | 83 | ||
84 | if (ehca_debug_level) { | 84 | if (ehca_debug_level >= 3) { |
85 | ehca_gen_dbg("RECEIVE WQE written into ipz_rqueue=%p", | 85 | ehca_gen_dbg("RECEIVE WQE written into ipz_rqueue=%p", |
86 | ipz_rqueue); | 86 | ipz_rqueue); |
87 | ehca_dmp(wqe_p, 16*(6 + wqe_p->nr_of_data_seg), "recv wqe"); | 87 | ehca_dmp(wqe_p, 16*(6 + wqe_p->nr_of_data_seg), "recv wqe"); |
@@ -281,7 +281,7 @@ static inline int ehca_write_swqe(struct ehca_qp *qp, | |||
281 | return -EINVAL; | 281 | return -EINVAL; |
282 | } | 282 | } |
283 | 283 | ||
284 | if (ehca_debug_level) { | 284 | if (ehca_debug_level >= 3) { |
285 | ehca_gen_dbg("SEND WQE written into queue qp=%p ", qp); | 285 | ehca_gen_dbg("SEND WQE written into queue qp=%p ", qp); |
286 | ehca_dmp( wqe_p, 16*(6 + wqe_p->nr_of_data_seg), "send wqe"); | 286 | ehca_dmp( wqe_p, 16*(6 + wqe_p->nr_of_data_seg), "send wqe"); |
287 | } | 287 | } |
@@ -421,6 +421,11 @@ int ehca_post_send(struct ib_qp *qp, | |||
421 | int ret = 0; | 421 | int ret = 0; |
422 | unsigned long flags; | 422 | unsigned long flags; |
423 | 423 | ||
424 | if (unlikely(my_qp->state != IB_QPS_RTS)) { | ||
425 | ehca_err(qp->device, "QP not in RTS state qpn=%x", qp->qp_num); | ||
426 | return -EINVAL; | ||
427 | } | ||
428 | |||
424 | /* LOCK the QUEUE */ | 429 | /* LOCK the QUEUE */ |
425 | spin_lock_irqsave(&my_qp->spinlock_s, flags); | 430 | spin_lock_irqsave(&my_qp->spinlock_s, flags); |
426 | 431 | ||
@@ -454,13 +459,14 @@ int ehca_post_send(struct ib_qp *qp, | |||
454 | goto post_send_exit0; | 459 | goto post_send_exit0; |
455 | } | 460 | } |
456 | wqe_cnt++; | 461 | wqe_cnt++; |
457 | ehca_dbg(qp->device, "ehca_qp=%p qp_num=%x wqe_cnt=%d", | ||
458 | my_qp, qp->qp_num, wqe_cnt); | ||
459 | } /* eof for cur_send_wr */ | 462 | } /* eof for cur_send_wr */ |
460 | 463 | ||
461 | post_send_exit0: | 464 | post_send_exit0: |
462 | iosync(); /* serialize GAL register access */ | 465 | iosync(); /* serialize GAL register access */ |
463 | hipz_update_sqa(my_qp, wqe_cnt); | 466 | hipz_update_sqa(my_qp, wqe_cnt); |
467 | if (unlikely(ret || ehca_debug_level >= 2)) | ||
468 | ehca_dbg(qp->device, "ehca_qp=%p qp_num=%x wqe_cnt=%d ret=%i", | ||
469 | my_qp, qp->qp_num, wqe_cnt, ret); | ||
464 | my_qp->message_count += wqe_cnt; | 470 | my_qp->message_count += wqe_cnt; |
465 | spin_unlock_irqrestore(&my_qp->spinlock_s, flags); | 471 | spin_unlock_irqrestore(&my_qp->spinlock_s, flags); |
466 | return ret; | 472 | return ret; |
@@ -520,13 +526,14 @@ static int internal_post_recv(struct ehca_qp *my_qp, | |||
520 | goto post_recv_exit0; | 526 | goto post_recv_exit0; |
521 | } | 527 | } |
522 | wqe_cnt++; | 528 | wqe_cnt++; |
523 | ehca_dbg(dev, "ehca_qp=%p qp_num=%x wqe_cnt=%d", | ||
524 | my_qp, my_qp->real_qp_num, wqe_cnt); | ||
525 | } /* eof for cur_recv_wr */ | 529 | } /* eof for cur_recv_wr */ |
526 | 530 | ||
527 | post_recv_exit0: | 531 | post_recv_exit0: |
528 | iosync(); /* serialize GAL register access */ | 532 | iosync(); /* serialize GAL register access */ |
529 | hipz_update_rqa(my_qp, wqe_cnt); | 533 | hipz_update_rqa(my_qp, wqe_cnt); |
534 | if (unlikely(ret || ehca_debug_level >= 2)) | ||
535 | ehca_dbg(dev, "ehca_qp=%p qp_num=%x wqe_cnt=%d ret=%i", | ||
536 | my_qp, my_qp->real_qp_num, wqe_cnt, ret); | ||
530 | spin_unlock_irqrestore(&my_qp->spinlock_r, flags); | 537 | spin_unlock_irqrestore(&my_qp->spinlock_r, flags); |
531 | return ret; | 538 | return ret; |
532 | } | 539 | } |
@@ -570,16 +577,17 @@ static inline int ehca_poll_cq_one(struct ib_cq *cq, struct ib_wc *wc) | |||
570 | struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq); | 577 | struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq); |
571 | struct ehca_cqe *cqe; | 578 | struct ehca_cqe *cqe; |
572 | struct ehca_qp *my_qp; | 579 | struct ehca_qp *my_qp; |
573 | int cqe_count = 0; | 580 | int cqe_count = 0, is_error; |
574 | 581 | ||
575 | poll_cq_one_read_cqe: | 582 | poll_cq_one_read_cqe: |
576 | cqe = (struct ehca_cqe *) | 583 | cqe = (struct ehca_cqe *) |
577 | ipz_qeit_get_inc_valid(&my_cq->ipz_queue); | 584 | ipz_qeit_get_inc_valid(&my_cq->ipz_queue); |
578 | if (!cqe) { | 585 | if (!cqe) { |
579 | ret = -EAGAIN; | 586 | ret = -EAGAIN; |
580 | ehca_dbg(cq->device, "Completion queue is empty ehca_cq=%p " | 587 | if (ehca_debug_level >= 3) |
581 | "cq_num=%x ret=%i", my_cq, my_cq->cq_number, ret); | 588 | ehca_dbg(cq->device, "Completion queue is empty " |
582 | goto poll_cq_one_exit0; | 589 | "my_cq=%p cq_num=%x", my_cq, my_cq->cq_number); |
590 | goto poll_cq_one_exit0; | ||
583 | } | 591 | } |
584 | 592 | ||
585 | /* prevents loads being reordered across this point */ | 593 | /* prevents loads being reordered across this point */ |
@@ -609,7 +617,7 @@ poll_cq_one_read_cqe: | |||
609 | ehca_dbg(cq->device, | 617 | ehca_dbg(cq->device, |
610 | "Got CQE with purged bit qp_num=%x src_qp=%x", | 618 | "Got CQE with purged bit qp_num=%x src_qp=%x", |
611 | cqe->local_qp_number, cqe->remote_qp_number); | 619 | cqe->local_qp_number, cqe->remote_qp_number); |
612 | if (ehca_debug_level) | 620 | if (ehca_debug_level >= 2) |
613 | ehca_dmp(cqe, 64, "qp_num=%x src_qp=%x", | 621 | ehca_dmp(cqe, 64, "qp_num=%x src_qp=%x", |
614 | cqe->local_qp_number, | 622 | cqe->local_qp_number, |
615 | cqe->remote_qp_number); | 623 | cqe->remote_qp_number); |
@@ -622,11 +630,13 @@ poll_cq_one_read_cqe: | |||
622 | } | 630 | } |
623 | } | 631 | } |
624 | 632 | ||
625 | /* tracing cqe */ | 633 | is_error = cqe->status & WC_STATUS_ERROR_BIT; |
626 | if (unlikely(ehca_debug_level)) { | 634 | |
635 | /* trace error CQEs if debug_level >= 1, trace all CQEs if >= 3 */ | ||
636 | if (unlikely(ehca_debug_level >= 3 || (ehca_debug_level && is_error))) { | ||
627 | ehca_dbg(cq->device, | 637 | ehca_dbg(cq->device, |
628 | "Received COMPLETION ehca_cq=%p cq_num=%x -----", | 638 | "Received %sCOMPLETION ehca_cq=%p cq_num=%x -----", |
629 | my_cq, my_cq->cq_number); | 639 | is_error ? "ERROR " : "", my_cq, my_cq->cq_number); |
630 | ehca_dmp(cqe, 64, "ehca_cq=%p cq_num=%x", | 640 | ehca_dmp(cqe, 64, "ehca_cq=%p cq_num=%x", |
631 | my_cq, my_cq->cq_number); | 641 | my_cq, my_cq->cq_number); |
632 | ehca_dbg(cq->device, | 642 | ehca_dbg(cq->device, |
@@ -649,8 +659,9 @@ poll_cq_one_read_cqe: | |||
649 | /* update also queue adder to throw away this entry!!! */ | 659 | /* update also queue adder to throw away this entry!!! */ |
650 | goto poll_cq_one_exit0; | 660 | goto poll_cq_one_exit0; |
651 | } | 661 | } |
662 | |||
652 | /* eval ib_wc_status */ | 663 | /* eval ib_wc_status */ |
653 | if (unlikely(cqe->status & WC_STATUS_ERROR_BIT)) { | 664 | if (unlikely(is_error)) { |
654 | /* complete with errors */ | 665 | /* complete with errors */ |
655 | map_ib_wc_status(cqe->status, &wc->status); | 666 | map_ib_wc_status(cqe->status, &wc->status); |
656 | wc->vendor_err = wc->status; | 667 | wc->vendor_err = wc->status; |
@@ -671,14 +682,6 @@ poll_cq_one_read_cqe: | |||
671 | wc->imm_data = cpu_to_be32(cqe->immediate_data); | 682 | wc->imm_data = cpu_to_be32(cqe->immediate_data); |
672 | wc->sl = cqe->service_level; | 683 | wc->sl = cqe->service_level; |
673 | 684 | ||
674 | if (unlikely(wc->status != IB_WC_SUCCESS)) | ||
675 | ehca_dbg(cq->device, | ||
676 | "ehca_cq=%p cq_num=%x WARNING unsuccessful cqe " | ||
677 | "OPType=%x status=%x qp_num=%x src_qp=%x wr_id=%lx " | ||
678 | "cqe=%p", my_cq, my_cq->cq_number, cqe->optype, | ||
679 | cqe->status, cqe->local_qp_number, | ||
680 | cqe->remote_qp_number, cqe->work_request_id, cqe); | ||
681 | |||
682 | poll_cq_one_exit0: | 685 | poll_cq_one_exit0: |
683 | if (cqe_count > 0) | 686 | if (cqe_count > 0) |
684 | hipz_update_feca(my_cq, cqe_count); | 687 | hipz_update_feca(my_cq, cqe_count); |
diff --git a/drivers/infiniband/hw/ehca/ehca_uverbs.c b/drivers/infiniband/hw/ehca/ehca_uverbs.c index 1b07f2beafaf..e43ed8f8a0c8 100644 --- a/drivers/infiniband/hw/ehca/ehca_uverbs.c +++ b/drivers/infiniband/hw/ehca/ehca_uverbs.c | |||
@@ -211,8 +211,7 @@ static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp, | |||
211 | break; | 211 | break; |
212 | 212 | ||
213 | case 1: /* qp rqueue_addr */ | 213 | case 1: /* qp rqueue_addr */ |
214 | ehca_dbg(qp->ib_qp.device, "qp_num=%x rqueue", | 214 | ehca_dbg(qp->ib_qp.device, "qp_num=%x rq", qp->ib_qp.qp_num); |
215 | qp->ib_qp.qp_num); | ||
216 | ret = ehca_mmap_queue(vma, &qp->ipz_rqueue, | 215 | ret = ehca_mmap_queue(vma, &qp->ipz_rqueue, |
217 | &qp->mm_count_rqueue); | 216 | &qp->mm_count_rqueue); |
218 | if (unlikely(ret)) { | 217 | if (unlikely(ret)) { |
@@ -224,8 +223,7 @@ static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp, | |||
224 | break; | 223 | break; |
225 | 224 | ||
226 | case 2: /* qp squeue_addr */ | 225 | case 2: /* qp squeue_addr */ |
227 | ehca_dbg(qp->ib_qp.device, "qp_num=%x squeue", | 226 | ehca_dbg(qp->ib_qp.device, "qp_num=%x sq", qp->ib_qp.qp_num); |
228 | qp->ib_qp.qp_num); | ||
229 | ret = ehca_mmap_queue(vma, &qp->ipz_squeue, | 227 | ret = ehca_mmap_queue(vma, &qp->ipz_squeue, |
230 | &qp->mm_count_squeue); | 228 | &qp->mm_count_squeue); |
231 | if (unlikely(ret)) { | 229 | if (unlikely(ret)) { |
diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c index 7029aa653751..5245e13c3a30 100644 --- a/drivers/infiniband/hw/ehca/hcp_if.c +++ b/drivers/infiniband/hw/ehca/hcp_if.c | |||
@@ -123,8 +123,9 @@ static long ehca_plpar_hcall_norets(unsigned long opcode, | |||
123 | int i, sleep_msecs; | 123 | int i, sleep_msecs; |
124 | unsigned long flags = 0; | 124 | unsigned long flags = 0; |
125 | 125 | ||
126 | ehca_gen_dbg("opcode=%lx " HCALL7_REGS_FORMAT, | 126 | if (unlikely(ehca_debug_level >= 2)) |
127 | opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7); | 127 | ehca_gen_dbg("opcode=%lx " HCALL7_REGS_FORMAT, |
128 | opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7); | ||
128 | 129 | ||
129 | for (i = 0; i < 5; i++) { | 130 | for (i = 0; i < 5; i++) { |
130 | /* serialize hCalls to work around firmware issue */ | 131 | /* serialize hCalls to work around firmware issue */ |
@@ -148,7 +149,8 @@ static long ehca_plpar_hcall_norets(unsigned long opcode, | |||
148 | opcode, ret, arg1, arg2, arg3, | 149 | opcode, ret, arg1, arg2, arg3, |
149 | arg4, arg5, arg6, arg7); | 150 | arg4, arg5, arg6, arg7); |
150 | else | 151 | else |
151 | ehca_gen_dbg("opcode=%lx ret=%li", opcode, ret); | 152 | if (unlikely(ehca_debug_level >= 2)) |
153 | ehca_gen_dbg("opcode=%lx ret=%li", opcode, ret); | ||
152 | 154 | ||
153 | return ret; | 155 | return ret; |
154 | } | 156 | } |
@@ -172,8 +174,10 @@ static long ehca_plpar_hcall9(unsigned long opcode, | |||
172 | int i, sleep_msecs; | 174 | int i, sleep_msecs; |
173 | unsigned long flags = 0; | 175 | unsigned long flags = 0; |
174 | 176 | ||
175 | ehca_gen_dbg("INPUT -- opcode=%lx " HCALL9_REGS_FORMAT, opcode, | 177 | if (unlikely(ehca_debug_level >= 2)) |
176 | arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); | 178 | ehca_gen_dbg("INPUT -- opcode=%lx " HCALL9_REGS_FORMAT, opcode, |
179 | arg1, arg2, arg3, arg4, arg5, | ||
180 | arg6, arg7, arg8, arg9); | ||
177 | 181 | ||
178 | for (i = 0; i < 5; i++) { | 182 | for (i = 0; i < 5; i++) { |
179 | /* serialize hCalls to work around firmware issue */ | 183 | /* serialize hCalls to work around firmware issue */ |
@@ -201,7 +205,7 @@ static long ehca_plpar_hcall9(unsigned long opcode, | |||
201 | ret, outs[0], outs[1], outs[2], outs[3], | 205 | ret, outs[0], outs[1], outs[2], outs[3], |
202 | outs[4], outs[5], outs[6], outs[7], | 206 | outs[4], outs[5], outs[6], outs[7], |
203 | outs[8]); | 207 | outs[8]); |
204 | } else | 208 | } else if (unlikely(ehca_debug_level >= 2)) |
205 | ehca_gen_dbg("OUTPUT -- ret=%li " HCALL9_REGS_FORMAT, | 209 | ehca_gen_dbg("OUTPUT -- ret=%li " HCALL9_REGS_FORMAT, |
206 | ret, outs[0], outs[1], outs[2], outs[3], | 210 | ret, outs[0], outs[1], outs[2], outs[3], |
207 | outs[4], outs[5], outs[6], outs[7], | 211 | outs[4], outs[5], outs[6], outs[7], |
@@ -381,7 +385,7 @@ u64 hipz_h_query_port(const struct ipz_adapter_handle adapter_handle, | |||
381 | r_cb, /* r6 */ | 385 | r_cb, /* r6 */ |
382 | 0, 0, 0, 0); | 386 | 0, 0, 0, 0); |
383 | 387 | ||
384 | if (ehca_debug_level) | 388 | if (ehca_debug_level >= 2) |
385 | ehca_dmp(query_port_response_block, 64, "response_block"); | 389 | ehca_dmp(query_port_response_block, 64, "response_block"); |
386 | 390 | ||
387 | return ret; | 391 | return ret; |
@@ -731,9 +735,6 @@ u64 hipz_h_alloc_resource_mr(const struct ipz_adapter_handle adapter_handle, | |||
731 | u64 ret; | 735 | u64 ret; |
732 | u64 outs[PLPAR_HCALL9_BUFSIZE]; | 736 | u64 outs[PLPAR_HCALL9_BUFSIZE]; |
733 | 737 | ||
734 | ehca_gen_dbg("kernel PAGE_SIZE=%x access_ctrl=%016x " | ||
735 | "vaddr=%lx length=%lx", | ||
736 | (u32)PAGE_SIZE, access_ctrl, vaddr, length); | ||
737 | ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs, | 738 | ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs, |
738 | adapter_handle.handle, /* r4 */ | 739 | adapter_handle.handle, /* r4 */ |
739 | 5, /* r5 */ | 740 | 5, /* r5 */ |
@@ -758,7 +759,7 @@ u64 hipz_h_register_rpage_mr(const struct ipz_adapter_handle adapter_handle, | |||
758 | { | 759 | { |
759 | u64 ret; | 760 | u64 ret; |
760 | 761 | ||
761 | if (unlikely(ehca_debug_level >= 2)) { | 762 | if (unlikely(ehca_debug_level >= 3)) { |
762 | if (count > 1) { | 763 | if (count > 1) { |
763 | u64 *kpage; | 764 | u64 *kpage; |
764 | int i; | 765 | int i; |
diff --git a/drivers/infiniband/hw/ipath/ipath_mr.c b/drivers/infiniband/hw/ipath/ipath_mr.c index db4ba92f79fc..9d343b7c2f3b 100644 --- a/drivers/infiniband/hw/ipath/ipath_mr.c +++ b/drivers/infiniband/hw/ipath/ipath_mr.c | |||
@@ -195,7 +195,8 @@ struct ib_mr *ipath_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, | |||
195 | goto bail; | 195 | goto bail; |
196 | } | 196 | } |
197 | 197 | ||
198 | umem = ib_umem_get(pd->uobject->context, start, length, mr_access_flags); | 198 | umem = ib_umem_get(pd->uobject->context, start, length, |
199 | mr_access_flags, 0); | ||
199 | if (IS_ERR(umem)) | 200 | if (IS_ERR(umem)) |
200 | return (void *) umem; | 201 | return (void *) umem; |
201 | 202 | ||
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c index 3557e7edc9b6..4521319b1406 100644 --- a/drivers/infiniband/hw/mlx4/cq.c +++ b/drivers/infiniband/hw/mlx4/cq.c | |||
@@ -137,7 +137,7 @@ static int mlx4_ib_get_cq_umem(struct mlx4_ib_dev *dev, struct ib_ucontext *cont | |||
137 | int err; | 137 | int err; |
138 | 138 | ||
139 | *umem = ib_umem_get(context, buf_addr, cqe * sizeof (struct mlx4_cqe), | 139 | *umem = ib_umem_get(context, buf_addr, cqe * sizeof (struct mlx4_cqe), |
140 | IB_ACCESS_LOCAL_WRITE); | 140 | IB_ACCESS_LOCAL_WRITE, 1); |
141 | if (IS_ERR(*umem)) | 141 | if (IS_ERR(*umem)) |
142 | return PTR_ERR(*umem); | 142 | return PTR_ERR(*umem); |
143 | 143 | ||
@@ -204,7 +204,7 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev, int entries, int vector | |||
204 | 204 | ||
205 | uar = &to_mucontext(context)->uar; | 205 | uar = &to_mucontext(context)->uar; |
206 | } else { | 206 | } else { |
207 | err = mlx4_ib_db_alloc(dev, &cq->db, 1); | 207 | err = mlx4_db_alloc(dev->dev, &cq->db, 1); |
208 | if (err) | 208 | if (err) |
209 | goto err_cq; | 209 | goto err_cq; |
210 | 210 | ||
@@ -221,7 +221,7 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev, int entries, int vector | |||
221 | } | 221 | } |
222 | 222 | ||
223 | err = mlx4_cq_alloc(dev->dev, entries, &cq->buf.mtt, uar, | 223 | err = mlx4_cq_alloc(dev->dev, entries, &cq->buf.mtt, uar, |
224 | cq->db.dma, &cq->mcq); | 224 | cq->db.dma, &cq->mcq, 0); |
225 | if (err) | 225 | if (err) |
226 | goto err_dbmap; | 226 | goto err_dbmap; |
227 | 227 | ||
@@ -246,11 +246,11 @@ err_mtt: | |||
246 | if (context) | 246 | if (context) |
247 | ib_umem_release(cq->umem); | 247 | ib_umem_release(cq->umem); |
248 | else | 248 | else |
249 | mlx4_ib_free_cq_buf(dev, &cq->buf, entries); | 249 | mlx4_ib_free_cq_buf(dev, &cq->buf, cq->ibcq.cqe); |
250 | 250 | ||
251 | err_db: | 251 | err_db: |
252 | if (!context) | 252 | if (!context) |
253 | mlx4_ib_db_free(dev, &cq->db); | 253 | mlx4_db_free(dev->dev, &cq->db); |
254 | 254 | ||
255 | err_cq: | 255 | err_cq: |
256 | kfree(cq); | 256 | kfree(cq); |
@@ -434,8 +434,8 @@ int mlx4_ib_destroy_cq(struct ib_cq *cq) | |||
434 | mlx4_ib_db_unmap_user(to_mucontext(cq->uobject->context), &mcq->db); | 434 | mlx4_ib_db_unmap_user(to_mucontext(cq->uobject->context), &mcq->db); |
435 | ib_umem_release(mcq->umem); | 435 | ib_umem_release(mcq->umem); |
436 | } else { | 436 | } else { |
437 | mlx4_ib_free_cq_buf(dev, &mcq->buf, cq->cqe + 1); | 437 | mlx4_ib_free_cq_buf(dev, &mcq->buf, cq->cqe); |
438 | mlx4_ib_db_free(dev, &mcq->db); | 438 | mlx4_db_free(dev->dev, &mcq->db); |
439 | } | 439 | } |
440 | 440 | ||
441 | kfree(mcq); | 441 | kfree(mcq); |
diff --git a/drivers/infiniband/hw/mlx4/doorbell.c b/drivers/infiniband/hw/mlx4/doorbell.c index 1c36087aef14..8aee4233b388 100644 --- a/drivers/infiniband/hw/mlx4/doorbell.c +++ b/drivers/infiniband/hw/mlx4/doorbell.c | |||
@@ -34,124 +34,6 @@ | |||
34 | 34 | ||
35 | #include "mlx4_ib.h" | 35 | #include "mlx4_ib.h" |
36 | 36 | ||
37 | struct mlx4_ib_db_pgdir { | ||
38 | struct list_head list; | ||
39 | DECLARE_BITMAP(order0, MLX4_IB_DB_PER_PAGE); | ||
40 | DECLARE_BITMAP(order1, MLX4_IB_DB_PER_PAGE / 2); | ||
41 | unsigned long *bits[2]; | ||
42 | __be32 *db_page; | ||
43 | dma_addr_t db_dma; | ||
44 | }; | ||
45 | |||
46 | static struct mlx4_ib_db_pgdir *mlx4_ib_alloc_db_pgdir(struct mlx4_ib_dev *dev) | ||
47 | { | ||
48 | struct mlx4_ib_db_pgdir *pgdir; | ||
49 | |||
50 | pgdir = kzalloc(sizeof *pgdir, GFP_KERNEL); | ||
51 | if (!pgdir) | ||
52 | return NULL; | ||
53 | |||
54 | bitmap_fill(pgdir->order1, MLX4_IB_DB_PER_PAGE / 2); | ||
55 | pgdir->bits[0] = pgdir->order0; | ||
56 | pgdir->bits[1] = pgdir->order1; | ||
57 | pgdir->db_page = dma_alloc_coherent(dev->ib_dev.dma_device, | ||
58 | PAGE_SIZE, &pgdir->db_dma, | ||
59 | GFP_KERNEL); | ||
60 | if (!pgdir->db_page) { | ||
61 | kfree(pgdir); | ||
62 | return NULL; | ||
63 | } | ||
64 | |||
65 | return pgdir; | ||
66 | } | ||
67 | |||
68 | static int mlx4_ib_alloc_db_from_pgdir(struct mlx4_ib_db_pgdir *pgdir, | ||
69 | struct mlx4_ib_db *db, int order) | ||
70 | { | ||
71 | int o; | ||
72 | int i; | ||
73 | |||
74 | for (o = order; o <= 1; ++o) { | ||
75 | i = find_first_bit(pgdir->bits[o], MLX4_IB_DB_PER_PAGE >> o); | ||
76 | if (i < MLX4_IB_DB_PER_PAGE >> o) | ||
77 | goto found; | ||
78 | } | ||
79 | |||
80 | return -ENOMEM; | ||
81 | |||
82 | found: | ||
83 | clear_bit(i, pgdir->bits[o]); | ||
84 | |||
85 | i <<= o; | ||
86 | |||
87 | if (o > order) | ||
88 | set_bit(i ^ 1, pgdir->bits[order]); | ||
89 | |||
90 | db->u.pgdir = pgdir; | ||
91 | db->index = i; | ||
92 | db->db = pgdir->db_page + db->index; | ||
93 | db->dma = pgdir->db_dma + db->index * 4; | ||
94 | db->order = order; | ||
95 | |||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | int mlx4_ib_db_alloc(struct mlx4_ib_dev *dev, struct mlx4_ib_db *db, int order) | ||
100 | { | ||
101 | struct mlx4_ib_db_pgdir *pgdir; | ||
102 | int ret = 0; | ||
103 | |||
104 | mutex_lock(&dev->pgdir_mutex); | ||
105 | |||
106 | list_for_each_entry(pgdir, &dev->pgdir_list, list) | ||
107 | if (!mlx4_ib_alloc_db_from_pgdir(pgdir, db, order)) | ||
108 | goto out; | ||
109 | |||
110 | pgdir = mlx4_ib_alloc_db_pgdir(dev); | ||
111 | if (!pgdir) { | ||
112 | ret = -ENOMEM; | ||
113 | goto out; | ||
114 | } | ||
115 | |||
116 | list_add(&pgdir->list, &dev->pgdir_list); | ||
117 | |||
118 | /* This should never fail -- we just allocated an empty page: */ | ||
119 | WARN_ON(mlx4_ib_alloc_db_from_pgdir(pgdir, db, order)); | ||
120 | |||
121 | out: | ||
122 | mutex_unlock(&dev->pgdir_mutex); | ||
123 | |||
124 | return ret; | ||
125 | } | ||
126 | |||
127 | void mlx4_ib_db_free(struct mlx4_ib_dev *dev, struct mlx4_ib_db *db) | ||
128 | { | ||
129 | int o; | ||
130 | int i; | ||
131 | |||
132 | mutex_lock(&dev->pgdir_mutex); | ||
133 | |||
134 | o = db->order; | ||
135 | i = db->index; | ||
136 | |||
137 | if (db->order == 0 && test_bit(i ^ 1, db->u.pgdir->order0)) { | ||
138 | clear_bit(i ^ 1, db->u.pgdir->order0); | ||
139 | ++o; | ||
140 | } | ||
141 | |||
142 | i >>= o; | ||
143 | set_bit(i, db->u.pgdir->bits[o]); | ||
144 | |||
145 | if (bitmap_full(db->u.pgdir->order1, MLX4_IB_DB_PER_PAGE / 2)) { | ||
146 | dma_free_coherent(dev->ib_dev.dma_device, PAGE_SIZE, | ||
147 | db->u.pgdir->db_page, db->u.pgdir->db_dma); | ||
148 | list_del(&db->u.pgdir->list); | ||
149 | kfree(db->u.pgdir); | ||
150 | } | ||
151 | |||
152 | mutex_unlock(&dev->pgdir_mutex); | ||
153 | } | ||
154 | |||
155 | struct mlx4_ib_user_db_page { | 37 | struct mlx4_ib_user_db_page { |
156 | struct list_head list; | 38 | struct list_head list; |
157 | struct ib_umem *umem; | 39 | struct ib_umem *umem; |
@@ -160,7 +42,7 @@ struct mlx4_ib_user_db_page { | |||
160 | }; | 42 | }; |
161 | 43 | ||
162 | int mlx4_ib_db_map_user(struct mlx4_ib_ucontext *context, unsigned long virt, | 44 | int mlx4_ib_db_map_user(struct mlx4_ib_ucontext *context, unsigned long virt, |
163 | struct mlx4_ib_db *db) | 45 | struct mlx4_db *db) |
164 | { | 46 | { |
165 | struct mlx4_ib_user_db_page *page; | 47 | struct mlx4_ib_user_db_page *page; |
166 | struct ib_umem_chunk *chunk; | 48 | struct ib_umem_chunk *chunk; |
@@ -181,7 +63,7 @@ int mlx4_ib_db_map_user(struct mlx4_ib_ucontext *context, unsigned long virt, | |||
181 | page->user_virt = (virt & PAGE_MASK); | 63 | page->user_virt = (virt & PAGE_MASK); |
182 | page->refcnt = 0; | 64 | page->refcnt = 0; |
183 | page->umem = ib_umem_get(&context->ibucontext, virt & PAGE_MASK, | 65 | page->umem = ib_umem_get(&context->ibucontext, virt & PAGE_MASK, |
184 | PAGE_SIZE, 0); | 66 | PAGE_SIZE, 0, 0); |
185 | if (IS_ERR(page->umem)) { | 67 | if (IS_ERR(page->umem)) { |
186 | err = PTR_ERR(page->umem); | 68 | err = PTR_ERR(page->umem); |
187 | kfree(page); | 69 | kfree(page); |
@@ -202,7 +84,7 @@ out: | |||
202 | return err; | 84 | return err; |
203 | } | 85 | } |
204 | 86 | ||
205 | void mlx4_ib_db_unmap_user(struct mlx4_ib_ucontext *context, struct mlx4_ib_db *db) | 87 | void mlx4_ib_db_unmap_user(struct mlx4_ib_ucontext *context, struct mlx4_db *db) |
206 | { | 88 | { |
207 | mutex_lock(&context->db_page_mutex); | 89 | mutex_lock(&context->db_page_mutex); |
208 | 90 | ||
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 4d9b5ac42202..4d61e32866c6 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
@@ -557,9 +557,6 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) | |||
557 | goto err_uar; | 557 | goto err_uar; |
558 | MLX4_INIT_DOORBELL_LOCK(&ibdev->uar_lock); | 558 | MLX4_INIT_DOORBELL_LOCK(&ibdev->uar_lock); |
559 | 559 | ||
560 | INIT_LIST_HEAD(&ibdev->pgdir_list); | ||
561 | mutex_init(&ibdev->pgdir_mutex); | ||
562 | |||
563 | ibdev->dev = dev; | 560 | ibdev->dev = dev; |
564 | 561 | ||
565 | strlcpy(ibdev->ib_dev.name, "mlx4_%d", IB_DEVICE_NAME_MAX); | 562 | strlcpy(ibdev->ib_dev.name, "mlx4_%d", IB_DEVICE_NAME_MAX); |
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h index 9e637323c155..5cf994794d25 100644 --- a/drivers/infiniband/hw/mlx4/mlx4_ib.h +++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h | |||
@@ -43,24 +43,6 @@ | |||
43 | #include <linux/mlx4/device.h> | 43 | #include <linux/mlx4/device.h> |
44 | #include <linux/mlx4/doorbell.h> | 44 | #include <linux/mlx4/doorbell.h> |
45 | 45 | ||
46 | enum { | ||
47 | MLX4_IB_DB_PER_PAGE = PAGE_SIZE / 4 | ||
48 | }; | ||
49 | |||
50 | struct mlx4_ib_db_pgdir; | ||
51 | struct mlx4_ib_user_db_page; | ||
52 | |||
53 | struct mlx4_ib_db { | ||
54 | __be32 *db; | ||
55 | union { | ||
56 | struct mlx4_ib_db_pgdir *pgdir; | ||
57 | struct mlx4_ib_user_db_page *user_page; | ||
58 | } u; | ||
59 | dma_addr_t dma; | ||
60 | int index; | ||
61 | int order; | ||
62 | }; | ||
63 | |||
64 | struct mlx4_ib_ucontext { | 46 | struct mlx4_ib_ucontext { |
65 | struct ib_ucontext ibucontext; | 47 | struct ib_ucontext ibucontext; |
66 | struct mlx4_uar uar; | 48 | struct mlx4_uar uar; |
@@ -88,7 +70,7 @@ struct mlx4_ib_cq { | |||
88 | struct mlx4_cq mcq; | 70 | struct mlx4_cq mcq; |
89 | struct mlx4_ib_cq_buf buf; | 71 | struct mlx4_ib_cq_buf buf; |
90 | struct mlx4_ib_cq_resize *resize_buf; | 72 | struct mlx4_ib_cq_resize *resize_buf; |
91 | struct mlx4_ib_db db; | 73 | struct mlx4_db db; |
92 | spinlock_t lock; | 74 | spinlock_t lock; |
93 | struct mutex resize_mutex; | 75 | struct mutex resize_mutex; |
94 | struct ib_umem *umem; | 76 | struct ib_umem *umem; |
@@ -127,7 +109,7 @@ struct mlx4_ib_qp { | |||
127 | struct mlx4_qp mqp; | 109 | struct mlx4_qp mqp; |
128 | struct mlx4_buf buf; | 110 | struct mlx4_buf buf; |
129 | 111 | ||
130 | struct mlx4_ib_db db; | 112 | struct mlx4_db db; |
131 | struct mlx4_ib_wq rq; | 113 | struct mlx4_ib_wq rq; |
132 | 114 | ||
133 | u32 doorbell_qpn; | 115 | u32 doorbell_qpn; |
@@ -154,7 +136,7 @@ struct mlx4_ib_srq { | |||
154 | struct ib_srq ibsrq; | 136 | struct ib_srq ibsrq; |
155 | struct mlx4_srq msrq; | 137 | struct mlx4_srq msrq; |
156 | struct mlx4_buf buf; | 138 | struct mlx4_buf buf; |
157 | struct mlx4_ib_db db; | 139 | struct mlx4_db db; |
158 | u64 *wrid; | 140 | u64 *wrid; |
159 | spinlock_t lock; | 141 | spinlock_t lock; |
160 | int head; | 142 | int head; |
@@ -175,9 +157,6 @@ struct mlx4_ib_dev { | |||
175 | struct mlx4_dev *dev; | 157 | struct mlx4_dev *dev; |
176 | void __iomem *uar_map; | 158 | void __iomem *uar_map; |
177 | 159 | ||
178 | struct list_head pgdir_list; | ||
179 | struct mutex pgdir_mutex; | ||
180 | |||
181 | struct mlx4_uar priv_uar; | 160 | struct mlx4_uar priv_uar; |
182 | u32 priv_pdn; | 161 | u32 priv_pdn; |
183 | MLX4_DECLARE_DOORBELL_LOCK(uar_lock); | 162 | MLX4_DECLARE_DOORBELL_LOCK(uar_lock); |
@@ -248,11 +227,9 @@ static inline struct mlx4_ib_ah *to_mah(struct ib_ah *ibah) | |||
248 | return container_of(ibah, struct mlx4_ib_ah, ibah); | 227 | return container_of(ibah, struct mlx4_ib_ah, ibah); |
249 | } | 228 | } |
250 | 229 | ||
251 | int mlx4_ib_db_alloc(struct mlx4_ib_dev *dev, struct mlx4_ib_db *db, int order); | ||
252 | void mlx4_ib_db_free(struct mlx4_ib_dev *dev, struct mlx4_ib_db *db); | ||
253 | int mlx4_ib_db_map_user(struct mlx4_ib_ucontext *context, unsigned long virt, | 230 | int mlx4_ib_db_map_user(struct mlx4_ib_ucontext *context, unsigned long virt, |
254 | struct mlx4_ib_db *db); | 231 | struct mlx4_db *db); |
255 | void mlx4_ib_db_unmap_user(struct mlx4_ib_ucontext *context, struct mlx4_ib_db *db); | 232 | void mlx4_ib_db_unmap_user(struct mlx4_ib_ucontext *context, struct mlx4_db *db); |
256 | 233 | ||
257 | struct ib_mr *mlx4_ib_get_dma_mr(struct ib_pd *pd, int acc); | 234 | struct ib_mr *mlx4_ib_get_dma_mr(struct ib_pd *pd, int acc); |
258 | int mlx4_ib_umem_write_mtt(struct mlx4_ib_dev *dev, struct mlx4_mtt *mtt, | 235 | int mlx4_ib_umem_write_mtt(struct mlx4_ib_dev *dev, struct mlx4_mtt *mtt, |
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c index fe2c2e94a5f8..68e92485fc76 100644 --- a/drivers/infiniband/hw/mlx4/mr.c +++ b/drivers/infiniband/hw/mlx4/mr.c | |||
@@ -132,7 +132,8 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, | |||
132 | if (!mr) | 132 | if (!mr) |
133 | return ERR_PTR(-ENOMEM); | 133 | return ERR_PTR(-ENOMEM); |
134 | 134 | ||
135 | mr->umem = ib_umem_get(pd->uobject->context, start, length, access_flags); | 135 | mr->umem = ib_umem_get(pd->uobject->context, start, length, |
136 | access_flags, 0); | ||
136 | if (IS_ERR(mr->umem)) { | 137 | if (IS_ERR(mr->umem)) { |
137 | err = PTR_ERR(mr->umem); | 138 | err = PTR_ERR(mr->umem); |
138 | goto err_free; | 139 | goto err_free; |
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index b75efae7e449..8e02ecfec188 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
@@ -482,7 +482,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, | |||
482 | goto err; | 482 | goto err; |
483 | 483 | ||
484 | qp->umem = ib_umem_get(pd->uobject->context, ucmd.buf_addr, | 484 | qp->umem = ib_umem_get(pd->uobject->context, ucmd.buf_addr, |
485 | qp->buf_size, 0); | 485 | qp->buf_size, 0, 0); |
486 | if (IS_ERR(qp->umem)) { | 486 | if (IS_ERR(qp->umem)) { |
487 | err = PTR_ERR(qp->umem); | 487 | err = PTR_ERR(qp->umem); |
488 | goto err; | 488 | goto err; |
@@ -514,7 +514,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, | |||
514 | goto err; | 514 | goto err; |
515 | 515 | ||
516 | if (!init_attr->srq) { | 516 | if (!init_attr->srq) { |
517 | err = mlx4_ib_db_alloc(dev, &qp->db, 0); | 517 | err = mlx4_db_alloc(dev->dev, &qp->db, 0); |
518 | if (err) | 518 | if (err) |
519 | goto err; | 519 | goto err; |
520 | 520 | ||
@@ -580,7 +580,7 @@ err_buf: | |||
580 | 580 | ||
581 | err_db: | 581 | err_db: |
582 | if (!pd->uobject && !init_attr->srq) | 582 | if (!pd->uobject && !init_attr->srq) |
583 | mlx4_ib_db_free(dev, &qp->db); | 583 | mlx4_db_free(dev->dev, &qp->db); |
584 | 584 | ||
585 | err: | 585 | err: |
586 | return err; | 586 | return err; |
@@ -666,7 +666,7 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp, | |||
666 | kfree(qp->rq.wrid); | 666 | kfree(qp->rq.wrid); |
667 | mlx4_buf_free(dev->dev, qp->buf_size, &qp->buf); | 667 | mlx4_buf_free(dev->dev, qp->buf_size, &qp->buf); |
668 | if (!qp->ibqp.srq) | 668 | if (!qp->ibqp.srq) |
669 | mlx4_ib_db_free(dev, &qp->db); | 669 | mlx4_db_free(dev->dev, &qp->db); |
670 | } | 670 | } |
671 | } | 671 | } |
672 | 672 | ||
diff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index beaa3b06cf58..12d6bc6f8007 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c | |||
@@ -109,7 +109,7 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd, | |||
109 | } | 109 | } |
110 | 110 | ||
111 | srq->umem = ib_umem_get(pd->uobject->context, ucmd.buf_addr, | 111 | srq->umem = ib_umem_get(pd->uobject->context, ucmd.buf_addr, |
112 | buf_size, 0); | 112 | buf_size, 0, 0); |
113 | if (IS_ERR(srq->umem)) { | 113 | if (IS_ERR(srq->umem)) { |
114 | err = PTR_ERR(srq->umem); | 114 | err = PTR_ERR(srq->umem); |
115 | goto err_srq; | 115 | goto err_srq; |
@@ -129,7 +129,7 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd, | |||
129 | if (err) | 129 | if (err) |
130 | goto err_mtt; | 130 | goto err_mtt; |
131 | } else { | 131 | } else { |
132 | err = mlx4_ib_db_alloc(dev, &srq->db, 0); | 132 | err = mlx4_db_alloc(dev->dev, &srq->db, 0); |
133 | if (err) | 133 | if (err) |
134 | goto err_srq; | 134 | goto err_srq; |
135 | 135 | ||
@@ -200,7 +200,7 @@ err_buf: | |||
200 | 200 | ||
201 | err_db: | 201 | err_db: |
202 | if (!pd->uobject) | 202 | if (!pd->uobject) |
203 | mlx4_ib_db_free(dev, &srq->db); | 203 | mlx4_db_free(dev->dev, &srq->db); |
204 | 204 | ||
205 | err_srq: | 205 | err_srq: |
206 | kfree(srq); | 206 | kfree(srq); |
@@ -267,7 +267,7 @@ int mlx4_ib_destroy_srq(struct ib_srq *srq) | |||
267 | kfree(msrq->wrid); | 267 | kfree(msrq->wrid); |
268 | mlx4_buf_free(dev->dev, msrq->msrq.max << msrq->msrq.wqe_shift, | 268 | mlx4_buf_free(dev->dev, msrq->msrq.max << msrq->msrq.wqe_shift, |
269 | &msrq->buf); | 269 | &msrq->buf); |
270 | mlx4_ib_db_free(dev, &msrq->db); | 270 | mlx4_db_free(dev->dev, &msrq->db); |
271 | } | 271 | } |
272 | 272 | ||
273 | kfree(msrq); | 273 | kfree(msrq); |
diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c index 3538da16e3fe..820205dec560 100644 --- a/drivers/infiniband/hw/mthca/mthca_mr.c +++ b/drivers/infiniband/hw/mthca/mthca_mr.c | |||
@@ -818,15 +818,9 @@ int mthca_arbel_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list, | |||
818 | 818 | ||
819 | void mthca_tavor_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr) | 819 | void mthca_tavor_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr) |
820 | { | 820 | { |
821 | u32 key; | ||
822 | |||
823 | if (!fmr->maps) | 821 | if (!fmr->maps) |
824 | return; | 822 | return; |
825 | 823 | ||
826 | key = tavor_key_to_hw_index(fmr->ibmr.lkey); | ||
827 | key &= dev->limits.num_mpts - 1; | ||
828 | fmr->ibmr.lkey = fmr->ibmr.rkey = tavor_hw_index_to_key(key); | ||
829 | |||
830 | fmr->maps = 0; | 824 | fmr->maps = 0; |
831 | 825 | ||
832 | writeb(MTHCA_MPT_STATUS_SW, fmr->mem.tavor.mpt); | 826 | writeb(MTHCA_MPT_STATUS_SW, fmr->mem.tavor.mpt); |
@@ -834,16 +828,9 @@ void mthca_tavor_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr) | |||
834 | 828 | ||
835 | void mthca_arbel_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr) | 829 | void mthca_arbel_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr) |
836 | { | 830 | { |
837 | u32 key; | ||
838 | |||
839 | if (!fmr->maps) | 831 | if (!fmr->maps) |
840 | return; | 832 | return; |
841 | 833 | ||
842 | key = arbel_key_to_hw_index(fmr->ibmr.lkey); | ||
843 | key &= dev->limits.num_mpts - 1; | ||
844 | key = adjust_key(dev, key); | ||
845 | fmr->ibmr.lkey = fmr->ibmr.rkey = arbel_hw_index_to_key(key); | ||
846 | |||
847 | fmr->maps = 0; | 834 | fmr->maps = 0; |
848 | 835 | ||
849 | *(u8 *) fmr->mem.arbel.mpt = MTHCA_MPT_STATUS_SW; | 836 | *(u8 *) fmr->mem.arbel.mpt = MTHCA_MPT_STATUS_SW; |
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 696e1f302332..be34f99ca625 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #include <rdma/ib_smi.h> | 39 | #include <rdma/ib_smi.h> |
40 | #include <rdma/ib_umem.h> | 40 | #include <rdma/ib_umem.h> |
41 | #include <rdma/ib_user_verbs.h> | 41 | #include <rdma/ib_user_verbs.h> |
42 | |||
43 | #include <linux/sched.h> | ||
42 | #include <linux/mm.h> | 44 | #include <linux/mm.h> |
43 | 45 | ||
44 | #include "mthca_dev.h" | 46 | #include "mthca_dev.h" |
@@ -367,6 +369,8 @@ static struct ib_ucontext *mthca_alloc_ucontext(struct ib_device *ibdev, | |||
367 | return ERR_PTR(-EFAULT); | 369 | return ERR_PTR(-EFAULT); |
368 | } | 370 | } |
369 | 371 | ||
372 | context->reg_mr_warned = 0; | ||
373 | |||
370 | return &context->ibucontext; | 374 | return &context->ibucontext; |
371 | } | 375 | } |
372 | 376 | ||
@@ -1006,17 +1010,31 @@ static struct ib_mr *mthca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, | |||
1006 | struct mthca_dev *dev = to_mdev(pd->device); | 1010 | struct mthca_dev *dev = to_mdev(pd->device); |
1007 | struct ib_umem_chunk *chunk; | 1011 | struct ib_umem_chunk *chunk; |
1008 | struct mthca_mr *mr; | 1012 | struct mthca_mr *mr; |
1013 | struct mthca_reg_mr ucmd; | ||
1009 | u64 *pages; | 1014 | u64 *pages; |
1010 | int shift, n, len; | 1015 | int shift, n, len; |
1011 | int i, j, k; | 1016 | int i, j, k; |
1012 | int err = 0; | 1017 | int err = 0; |
1013 | int write_mtt_size; | 1018 | int write_mtt_size; |
1014 | 1019 | ||
1020 | if (udata->inlen - sizeof (struct ib_uverbs_cmd_hdr) < sizeof ucmd) { | ||
1021 | if (!to_mucontext(pd->uobject->context)->reg_mr_warned) { | ||
1022 | mthca_warn(dev, "Process '%s' did not pass in MR attrs.\n", | ||
1023 | current->comm); | ||
1024 | mthca_warn(dev, " Update libmthca to fix this.\n"); | ||
1025 | } | ||
1026 | ++to_mucontext(pd->uobject->context)->reg_mr_warned; | ||
1027 | ucmd.mr_attrs = 0; | ||
1028 | } else if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) | ||
1029 | return ERR_PTR(-EFAULT); | ||
1030 | |||
1015 | mr = kmalloc(sizeof *mr, GFP_KERNEL); | 1031 | mr = kmalloc(sizeof *mr, GFP_KERNEL); |
1016 | if (!mr) | 1032 | if (!mr) |
1017 | return ERR_PTR(-ENOMEM); | 1033 | return ERR_PTR(-ENOMEM); |
1018 | 1034 | ||
1019 | mr->umem = ib_umem_get(pd->uobject->context, start, length, acc); | 1035 | mr->umem = ib_umem_get(pd->uobject->context, start, length, acc, |
1036 | ucmd.mr_attrs & MTHCA_MR_DMASYNC); | ||
1037 | |||
1020 | if (IS_ERR(mr->umem)) { | 1038 | if (IS_ERR(mr->umem)) { |
1021 | err = PTR_ERR(mr->umem); | 1039 | err = PTR_ERR(mr->umem); |
1022 | goto err; | 1040 | goto err; |
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.h b/drivers/infiniband/hw/mthca/mthca_provider.h index 262616c8ebb6..934bf9544037 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.h +++ b/drivers/infiniband/hw/mthca/mthca_provider.h | |||
@@ -67,6 +67,7 @@ struct mthca_ucontext { | |||
67 | struct ib_ucontext ibucontext; | 67 | struct ib_ucontext ibucontext; |
68 | struct mthca_uar uar; | 68 | struct mthca_uar uar; |
69 | struct mthca_user_db_table *db_tab; | 69 | struct mthca_user_db_table *db_tab; |
70 | int reg_mr_warned; | ||
70 | }; | 71 | }; |
71 | 72 | ||
72 | struct mthca_mtt; | 73 | struct mthca_mtt; |
diff --git a/drivers/infiniband/hw/mthca/mthca_user.h b/drivers/infiniband/hw/mthca/mthca_user.h index 02cc0a766f3a..e1262c942db8 100644 --- a/drivers/infiniband/hw/mthca/mthca_user.h +++ b/drivers/infiniband/hw/mthca/mthca_user.h | |||
@@ -61,6 +61,16 @@ struct mthca_alloc_pd_resp { | |||
61 | __u32 reserved; | 61 | __u32 reserved; |
62 | }; | 62 | }; |
63 | 63 | ||
64 | struct mthca_reg_mr { | ||
65 | /* | ||
66 | * Mark the memory region with a DMA attribute that causes | ||
67 | * in-flight DMA to be flushed when the region is written to: | ||
68 | */ | ||
69 | #define MTHCA_MR_DMASYNC 0x1 | ||
70 | __u32 mr_attrs; | ||
71 | __u32 reserved; | ||
72 | }; | ||
73 | |||
64 | struct mthca_create_cq { | 74 | struct mthca_create_cq { |
65 | __u32 lkey; | 75 | __u32 lkey; |
66 | __u32 pdn; | 76 | __u32 pdn; |
diff --git a/drivers/infiniband/hw/nes/Kconfig b/drivers/infiniband/hw/nes/Kconfig index 2aeb7ac972a9..d449eb6ec78e 100644 --- a/drivers/infiniband/hw/nes/Kconfig +++ b/drivers/infiniband/hw/nes/Kconfig | |||
@@ -2,6 +2,7 @@ config INFINIBAND_NES | |||
2 | tristate "NetEffect RNIC Driver" | 2 | tristate "NetEffect RNIC Driver" |
3 | depends on PCI && INET && INFINIBAND | 3 | depends on PCI && INET && INFINIBAND |
4 | select LIBCRC32C | 4 | select LIBCRC32C |
5 | select INET_LRO | ||
5 | ---help--- | 6 | ---help--- |
6 | This is a low-level driver for NetEffect RDMA enabled | 7 | This is a low-level driver for NetEffect RDMA enabled |
7 | Network Interface Cards (RNIC). | 8 | Network Interface Cards (RNIC). |
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index b046262ed638..9f7364a9096d 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c | |||
@@ -91,6 +91,10 @@ unsigned int nes_debug_level = 0; | |||
91 | module_param_named(debug_level, nes_debug_level, uint, 0644); | 91 | module_param_named(debug_level, nes_debug_level, uint, 0644); |
92 | MODULE_PARM_DESC(debug_level, "Enable debug output level"); | 92 | MODULE_PARM_DESC(debug_level, "Enable debug output level"); |
93 | 93 | ||
94 | unsigned int nes_lro_max_aggr = NES_LRO_MAX_AGGR; | ||
95 | module_param(nes_lro_max_aggr, int, NES_LRO_MAX_AGGR); | ||
96 | MODULE_PARM_DESC(nes_mro_max_aggr, " nic LRO MAX packet aggregation"); | ||
97 | |||
94 | LIST_HEAD(nes_adapter_list); | 98 | LIST_HEAD(nes_adapter_list); |
95 | static LIST_HEAD(nes_dev_list); | 99 | static LIST_HEAD(nes_dev_list); |
96 | 100 | ||
@@ -139,8 +143,9 @@ static int nes_inetaddr_event(struct notifier_block *notifier, | |||
139 | 143 | ||
140 | addr = ntohl(ifa->ifa_address); | 144 | addr = ntohl(ifa->ifa_address); |
141 | mask = ntohl(ifa->ifa_mask); | 145 | mask = ntohl(ifa->ifa_mask); |
142 | nes_debug(NES_DBG_NETDEV, "nes_inetaddr_event: ip address %08X, netmask %08X.\n", | 146 | nes_debug(NES_DBG_NETDEV, "nes_inetaddr_event: ip address " NIPQUAD_FMT |
143 | addr, mask); | 147 | ", netmask " NIPQUAD_FMT ".\n", |
148 | HIPQUAD(addr), HIPQUAD(mask)); | ||
144 | list_for_each_entry(nesdev, &nes_dev_list, list) { | 149 | list_for_each_entry(nesdev, &nes_dev_list, list) { |
145 | nes_debug(NES_DBG_NETDEV, "Nesdev list entry = 0x%p. (%s)\n", | 150 | nes_debug(NES_DBG_NETDEV, "Nesdev list entry = 0x%p. (%s)\n", |
146 | nesdev, nesdev->netdev[0]->name); | 151 | nesdev, nesdev->netdev[0]->name); |
@@ -353,13 +358,11 @@ struct ib_qp *nes_get_qp(struct ib_device *device, int qpn) | |||
353 | */ | 358 | */ |
354 | static void nes_print_macaddr(struct net_device *netdev) | 359 | static void nes_print_macaddr(struct net_device *netdev) |
355 | { | 360 | { |
356 | nes_debug(NES_DBG_INIT, "%s: MAC %02X:%02X:%02X:%02X:%02X:%02X, IRQ %u\n", | 361 | DECLARE_MAC_BUF(mac); |
357 | netdev->name, | ||
358 | netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2], | ||
359 | netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5], | ||
360 | netdev->irq); | ||
361 | } | ||
362 | 362 | ||
363 | nes_debug(NES_DBG_INIT, "%s: %s, IRQ %u\n", | ||
364 | netdev->name, print_mac(mac, netdev->dev_addr), netdev->irq); | ||
365 | } | ||
363 | 366 | ||
364 | /** | 367 | /** |
365 | * nes_interrupt - handle interrupts | 368 | * nes_interrupt - handle interrupts |
diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h index cdf2e9ad62f7..1f9f7bf73862 100644 --- a/drivers/infiniband/hw/nes/nes.h +++ b/drivers/infiniband/hw/nes/nes.h | |||
@@ -173,6 +173,7 @@ extern int disable_mpa_crc; | |||
173 | extern unsigned int send_first; | 173 | extern unsigned int send_first; |
174 | extern unsigned int nes_drv_opt; | 174 | extern unsigned int nes_drv_opt; |
175 | extern unsigned int nes_debug_level; | 175 | extern unsigned int nes_debug_level; |
176 | extern unsigned int nes_lro_max_aggr; | ||
176 | 177 | ||
177 | extern struct list_head nes_adapter_list; | 178 | extern struct list_head nes_adapter_list; |
178 | 179 | ||
@@ -535,8 +536,8 @@ int nes_register_ofa_device(struct nes_ib_device *); | |||
535 | int nes_read_eeprom_values(struct nes_device *, struct nes_adapter *); | 536 | int nes_read_eeprom_values(struct nes_device *, struct nes_adapter *); |
536 | void nes_write_1G_phy_reg(struct nes_device *, u8, u8, u16); | 537 | void nes_write_1G_phy_reg(struct nes_device *, u8, u8, u16); |
537 | void nes_read_1G_phy_reg(struct nes_device *, u8, u8, u16 *); | 538 | void nes_read_1G_phy_reg(struct nes_device *, u8, u8, u16 *); |
538 | void nes_write_10G_phy_reg(struct nes_device *, u16, u8, u16); | 539 | void nes_write_10G_phy_reg(struct nes_device *, u16, u8, u16, u16); |
539 | void nes_read_10G_phy_reg(struct nes_device *, u16, u8); | 540 | void nes_read_10G_phy_reg(struct nes_device *, u8, u8, u16); |
540 | struct nes_cqp_request *nes_get_cqp_request(struct nes_device *); | 541 | struct nes_cqp_request *nes_get_cqp_request(struct nes_device *); |
541 | void nes_post_cqp_request(struct nes_device *, struct nes_cqp_request *, int); | 542 | void nes_post_cqp_request(struct nes_device *, struct nes_cqp_request *, int); |
542 | int nes_arp_table(struct nes_device *, u32, u8 *, u32); | 543 | int nes_arp_table(struct nes_device *, u32, u8 *, u32); |
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index d0738623bcf3..9a4b40fae40d 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c | |||
@@ -594,7 +594,7 @@ static void nes_cm_timer_tick(unsigned long pass) | |||
594 | continue; | 594 | continue; |
595 | } | 595 | } |
596 | /* this seems like the correct place, but leave send entry unprotected */ | 596 | /* this seems like the correct place, but leave send entry unprotected */ |
597 | // spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); | 597 | /* spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); */ |
598 | atomic_inc(&send_entry->skb->users); | 598 | atomic_inc(&send_entry->skb->users); |
599 | cm_packets_retrans++; | 599 | cm_packets_retrans++; |
600 | nes_debug(NES_DBG_CM, "Retransmitting send_entry %p for node %p," | 600 | nes_debug(NES_DBG_CM, "Retransmitting send_entry %p for node %p," |
@@ -852,8 +852,8 @@ static struct nes_cm_node *find_node(struct nes_cm_core *cm_core, | |||
852 | /* get a handle on the hte */ | 852 | /* get a handle on the hte */ |
853 | hte = &cm_core->connected_nodes; | 853 | hte = &cm_core->connected_nodes; |
854 | 854 | ||
855 | nes_debug(NES_DBG_CM, "Searching for an owner node:%x:%x from core %p->%p\n", | 855 | nes_debug(NES_DBG_CM, "Searching for an owner node: " NIPQUAD_FMT ":%x from core %p->%p\n", |
856 | loc_addr, loc_port, cm_core, hte); | 856 | HIPQUAD(loc_addr), loc_port, cm_core, hte); |
857 | 857 | ||
858 | /* walk list and find cm_node associated with this session ID */ | 858 | /* walk list and find cm_node associated with this session ID */ |
859 | spin_lock_irqsave(&cm_core->ht_lock, flags); | 859 | spin_lock_irqsave(&cm_core->ht_lock, flags); |
@@ -902,8 +902,8 @@ static struct nes_cm_listener *find_listener(struct nes_cm_core *cm_core, | |||
902 | } | 902 | } |
903 | spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); | 903 | spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); |
904 | 904 | ||
905 | nes_debug(NES_DBG_CM, "Unable to find listener- %x:%x\n", | 905 | nes_debug(NES_DBG_CM, "Unable to find listener for " NIPQUAD_FMT ":%x\n", |
906 | dst_addr, dst_port); | 906 | HIPQUAD(dst_addr), dst_port); |
907 | 907 | ||
908 | /* no listener */ | 908 | /* no listener */ |
909 | return NULL; | 909 | return NULL; |
@@ -1054,6 +1054,7 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core, | |||
1054 | int arpindex = 0; | 1054 | int arpindex = 0; |
1055 | struct nes_device *nesdev; | 1055 | struct nes_device *nesdev; |
1056 | struct nes_adapter *nesadapter; | 1056 | struct nes_adapter *nesadapter; |
1057 | DECLARE_MAC_BUF(mac); | ||
1057 | 1058 | ||
1058 | /* create an hte and cm_node for this instance */ | 1059 | /* create an hte and cm_node for this instance */ |
1059 | cm_node = kzalloc(sizeof(*cm_node), GFP_ATOMIC); | 1060 | cm_node = kzalloc(sizeof(*cm_node), GFP_ATOMIC); |
@@ -1066,8 +1067,9 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core, | |||
1066 | cm_node->loc_port = cm_info->loc_port; | 1067 | cm_node->loc_port = cm_info->loc_port; |
1067 | cm_node->rem_port = cm_info->rem_port; | 1068 | cm_node->rem_port = cm_info->rem_port; |
1068 | cm_node->send_write0 = send_first; | 1069 | cm_node->send_write0 = send_first; |
1069 | nes_debug(NES_DBG_CM, "Make node addresses : loc = %x:%x, rem = %x:%x\n", | 1070 | nes_debug(NES_DBG_CM, "Make node addresses : loc = " NIPQUAD_FMT ":%x, rem = " NIPQUAD_FMT ":%x\n", |
1070 | cm_node->loc_addr, cm_node->loc_port, cm_node->rem_addr, cm_node->rem_port); | 1071 | HIPQUAD(cm_node->loc_addr), cm_node->loc_port, |
1072 | HIPQUAD(cm_node->rem_addr), cm_node->rem_port); | ||
1071 | cm_node->listener = listener; | 1073 | cm_node->listener = listener; |
1072 | cm_node->netdev = nesvnic->netdev; | 1074 | cm_node->netdev = nesvnic->netdev; |
1073 | cm_node->cm_id = cm_info->cm_id; | 1075 | cm_node->cm_id = cm_info->cm_id; |
@@ -1116,11 +1118,8 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core, | |||
1116 | 1118 | ||
1117 | /* copy the mac addr to node context */ | 1119 | /* copy the mac addr to node context */ |
1118 | memcpy(cm_node->rem_mac, nesadapter->arp_table[arpindex].mac_addr, ETH_ALEN); | 1120 | memcpy(cm_node->rem_mac, nesadapter->arp_table[arpindex].mac_addr, ETH_ALEN); |
1119 | nes_debug(NES_DBG_CM, "Remote mac addr from arp table:%02x," | 1121 | nes_debug(NES_DBG_CM, "Remote mac addr from arp table: %s\n", |
1120 | " %02x, %02x, %02x, %02x, %02x\n", | 1122 | print_mac(mac, cm_node->rem_mac)); |
1121 | cm_node->rem_mac[0], cm_node->rem_mac[1], | ||
1122 | cm_node->rem_mac[2], cm_node->rem_mac[3], | ||
1123 | cm_node->rem_mac[4], cm_node->rem_mac[5]); | ||
1124 | 1123 | ||
1125 | add_hte_node(cm_core, cm_node); | 1124 | add_hte_node(cm_core, cm_node); |
1126 | atomic_inc(&cm_nodes_created); | 1125 | atomic_inc(&cm_nodes_created); |
@@ -1336,7 +1335,7 @@ static int process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1336 | cm_node->loc_addr, cm_node->loc_port, | 1335 | cm_node->loc_addr, cm_node->loc_port, |
1337 | cm_node->rem_addr, cm_node->rem_port, | 1336 | cm_node->rem_addr, cm_node->rem_port, |
1338 | cm_node->state, atomic_read(&cm_node->ref_count)); | 1337 | cm_node->state, atomic_read(&cm_node->ref_count)); |
1339 | // create event | 1338 | /* create event */ |
1340 | cm_node->state = NES_CM_STATE_CLOSED; | 1339 | cm_node->state = NES_CM_STATE_CLOSED; |
1341 | 1340 | ||
1342 | create_event(cm_node, NES_CM_EVENT_ABORTED); | 1341 | create_event(cm_node, NES_CM_EVENT_ABORTED); |
@@ -1670,7 +1669,7 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core, | |||
1670 | if (!cm_node) | 1669 | if (!cm_node) |
1671 | return NULL; | 1670 | return NULL; |
1672 | 1671 | ||
1673 | // set our node side to client (active) side | 1672 | /* set our node side to client (active) side */ |
1674 | cm_node->tcp_cntxt.client = 1; | 1673 | cm_node->tcp_cntxt.client = 1; |
1675 | cm_node->tcp_cntxt.rcv_wscale = NES_CM_DEFAULT_RCV_WND_SCALE; | 1674 | cm_node->tcp_cntxt.rcv_wscale = NES_CM_DEFAULT_RCV_WND_SCALE; |
1676 | 1675 | ||
@@ -1695,7 +1694,7 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core, | |||
1695 | loopbackremotenode->mpa_frame_size = mpa_frame_size - | 1694 | loopbackremotenode->mpa_frame_size = mpa_frame_size - |
1696 | sizeof(struct ietf_mpa_frame); | 1695 | sizeof(struct ietf_mpa_frame); |
1697 | 1696 | ||
1698 | // we are done handling this state, set node to a TSA state | 1697 | /* we are done handling this state, set node to a TSA state */ |
1699 | cm_node->state = NES_CM_STATE_TSA; | 1698 | cm_node->state = NES_CM_STATE_TSA; |
1700 | cm_node->tcp_cntxt.rcv_nxt = loopbackremotenode->tcp_cntxt.loc_seq_num; | 1699 | cm_node->tcp_cntxt.rcv_nxt = loopbackremotenode->tcp_cntxt.loc_seq_num; |
1701 | loopbackremotenode->tcp_cntxt.rcv_nxt = cm_node->tcp_cntxt.loc_seq_num; | 1700 | loopbackremotenode->tcp_cntxt.rcv_nxt = cm_node->tcp_cntxt.loc_seq_num; |
@@ -1850,8 +1849,10 @@ static int mini_cm_recv_pkt(struct nes_cm_core *cm_core, struct nes_vnic *nesvni | |||
1850 | nfo.rem_addr = ntohl(iph->saddr); | 1849 | nfo.rem_addr = ntohl(iph->saddr); |
1851 | nfo.rem_port = ntohs(tcph->source); | 1850 | nfo.rem_port = ntohs(tcph->source); |
1852 | 1851 | ||
1853 | nes_debug(NES_DBG_CM, "Received packet: dest=0x%08X:0x%04X src=0x%08X:0x%04X\n", | 1852 | nes_debug(NES_DBG_CM, "Received packet: dest=" NIPQUAD_FMT |
1854 | iph->daddr, tcph->dest, iph->saddr, tcph->source); | 1853 | ":0x%04X src=" NIPQUAD_FMT ":0x%04X\n", |
1854 | NIPQUAD(iph->daddr), tcph->dest, | ||
1855 | NIPQUAD(iph->saddr), tcph->source); | ||
1855 | 1856 | ||
1856 | /* note: this call is going to increment cm_node ref count */ | 1857 | /* note: this call is going to increment cm_node ref count */ |
1857 | cm_node = find_node(cm_core, | 1858 | cm_node = find_node(cm_core, |
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index aa53aab91bf8..8dc70f9bad2f 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/ip.h> | 38 | #include <linux/ip.h> |
39 | #include <linux/tcp.h> | 39 | #include <linux/tcp.h> |
40 | #include <linux/if_vlan.h> | 40 | #include <linux/if_vlan.h> |
41 | #include <linux/inet_lro.h> | ||
41 | 42 | ||
42 | #include "nes.h" | 43 | #include "nes.h" |
43 | 44 | ||
@@ -636,6 +637,15 @@ static unsigned int nes_reset_adapter_ne020(struct nes_device *nesdev, u8 *OneG_ | |||
636 | nes_debug(NES_DBG_INIT, "Did not see full soft reset done.\n"); | 637 | nes_debug(NES_DBG_INIT, "Did not see full soft reset done.\n"); |
637 | return 0; | 638 | return 0; |
638 | } | 639 | } |
640 | |||
641 | i = 0; | ||
642 | while ((nes_read_indexed(nesdev, NES_IDX_INT_CPU_STATUS) != 0x80) && i++ < 10000) | ||
643 | mdelay(1); | ||
644 | if (i >= 10000) { | ||
645 | printk(KERN_ERR PFX "Internal CPU not ready, status = %02X\n", | ||
646 | nes_read_indexed(nesdev, NES_IDX_INT_CPU_STATUS)); | ||
647 | return 0; | ||
648 | } | ||
639 | } | 649 | } |
640 | 650 | ||
641 | /* port reset */ | 651 | /* port reset */ |
@@ -684,17 +694,6 @@ static unsigned int nes_reset_adapter_ne020(struct nes_device *nesdev, u8 *OneG_ | |||
684 | } | 694 | } |
685 | } | 695 | } |
686 | 696 | ||
687 | |||
688 | |||
689 | i = 0; | ||
690 | while ((nes_read_indexed(nesdev, NES_IDX_INT_CPU_STATUS) != 0x80) && i++ < 10000) | ||
691 | mdelay(1); | ||
692 | if (i >= 10000) { | ||
693 | printk(KERN_ERR PFX "Internal CPU not ready, status = %02X\n", | ||
694 | nes_read_indexed(nesdev, NES_IDX_INT_CPU_STATUS)); | ||
695 | return 0; | ||
696 | } | ||
697 | |||
698 | return port_count; | 697 | return port_count; |
699 | } | 698 | } |
700 | 699 | ||
@@ -834,7 +833,7 @@ static void nes_init_csr_ne020(struct nes_device *nesdev, u8 hw_rev, u8 port_cou | |||
834 | nes_write_indexed(nesdev, 0x00000900, 0x20000001); | 833 | nes_write_indexed(nesdev, 0x00000900, 0x20000001); |
835 | nes_write_indexed(nesdev, 0x000060C0, 0x0000028e); | 834 | nes_write_indexed(nesdev, 0x000060C0, 0x0000028e); |
836 | nes_write_indexed(nesdev, 0x000060C8, 0x00000020); | 835 | nes_write_indexed(nesdev, 0x000060C8, 0x00000020); |
837 | // | 836 | |
838 | nes_write_indexed(nesdev, 0x000001EC, 0x7b2625a0); | 837 | nes_write_indexed(nesdev, 0x000001EC, 0x7b2625a0); |
839 | /* nes_write_indexed(nesdev, 0x000001EC, 0x5f2625a0); */ | 838 | /* nes_write_indexed(nesdev, 0x000001EC, 0x5f2625a0); */ |
840 | 839 | ||
@@ -1209,11 +1208,16 @@ int nes_init_phy(struct nes_device *nesdev) | |||
1209 | { | 1208 | { |
1210 | struct nes_adapter *nesadapter = nesdev->nesadapter; | 1209 | struct nes_adapter *nesadapter = nesdev->nesadapter; |
1211 | u32 counter = 0; | 1210 | u32 counter = 0; |
1211 | u32 sds_common_control0; | ||
1212 | u32 mac_index = nesdev->mac_index; | 1212 | u32 mac_index = nesdev->mac_index; |
1213 | u32 tx_config; | 1213 | u32 tx_config = 0; |
1214 | u16 phy_data; | 1214 | u16 phy_data; |
1215 | u32 temp_phy_data = 0; | ||
1216 | u32 temp_phy_data2 = 0; | ||
1217 | u32 i = 0; | ||
1215 | 1218 | ||
1216 | if (nesadapter->OneG_Mode) { | 1219 | if ((nesadapter->OneG_Mode) && |
1220 | (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) { | ||
1217 | nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index); | 1221 | nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index); |
1218 | if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_1G) { | 1222 | if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_1G) { |
1219 | printk(PFX "%s: Programming mdc config for 1G\n", __func__); | 1223 | printk(PFX "%s: Programming mdc config for 1G\n", __func__); |
@@ -1225,7 +1229,7 @@ int nes_init_phy(struct nes_device *nesdev) | |||
1225 | nes_read_1G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index], &phy_data); | 1229 | nes_read_1G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index], &phy_data); |
1226 | nes_debug(NES_DBG_PHY, "Phy data from register 1 phy address %u = 0x%X.\n", | 1230 | nes_debug(NES_DBG_PHY, "Phy data from register 1 phy address %u = 0x%X.\n", |
1227 | nesadapter->phy_index[mac_index], phy_data); | 1231 | nesadapter->phy_index[mac_index], phy_data); |
1228 | nes_write_1G_phy_reg(nesdev, 23, nesadapter->phy_index[mac_index], 0xb000); | 1232 | nes_write_1G_phy_reg(nesdev, 23, nesadapter->phy_index[mac_index], 0xb000); |
1229 | 1233 | ||
1230 | /* Reset the PHY */ | 1234 | /* Reset the PHY */ |
1231 | nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], 0x8000); | 1235 | nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], 0x8000); |
@@ -1279,12 +1283,126 @@ int nes_init_phy(struct nes_device *nesdev) | |||
1279 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data); | 1283 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data); |
1280 | nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data | 0x0300); | 1284 | nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data | 0x0300); |
1281 | } else { | 1285 | } else { |
1282 | if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) { | 1286 | if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) || |
1287 | (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) { | ||
1283 | /* setup 10G MDIO operation */ | 1288 | /* setup 10G MDIO operation */ |
1284 | tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); | 1289 | tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); |
1285 | tx_config |= 0x14; | 1290 | tx_config |= 0x14; |
1286 | nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); | 1291 | nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); |
1287 | } | 1292 | } |
1293 | if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) { | ||
1294 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee); | ||
1295 | |||
1296 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1297 | mdelay(10); | ||
1298 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee); | ||
1299 | temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1300 | |||
1301 | /* | ||
1302 | * if firmware is already running (like from a | ||
1303 | * driver un-load/load, don't do anything. | ||
1304 | */ | ||
1305 | if (temp_phy_data == temp_phy_data2) { | ||
1306 | /* configure QT2505 AMCC PHY */ | ||
1307 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0x0000, 0x8000); | ||
1308 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0000); | ||
1309 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc302, 0x0044); | ||
1310 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc318, 0x0052); | ||
1311 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc319, 0x0008); | ||
1312 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc31a, 0x0098); | ||
1313 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0026, 0x0E00); | ||
1314 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0027, 0x0000); | ||
1315 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0028, 0xA528); | ||
1316 | |||
1317 | /* | ||
1318 | * remove micro from reset; chip boots from ROM, | ||
1319 | * uploads EEPROM f/w image, uC executes f/w | ||
1320 | */ | ||
1321 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0002); | ||
1322 | |||
1323 | /* | ||
1324 | * wait for heart beat to start to | ||
1325 | * know loading is done | ||
1326 | */ | ||
1327 | counter = 0; | ||
1328 | do { | ||
1329 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee); | ||
1330 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1331 | if (counter++ > 1000) { | ||
1332 | nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from heartbeat check <this is bad!!!> \n"); | ||
1333 | break; | ||
1334 | } | ||
1335 | mdelay(100); | ||
1336 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee); | ||
1337 | temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1338 | } while ((temp_phy_data2 == temp_phy_data)); | ||
1339 | |||
1340 | /* | ||
1341 | * wait for tracking to start to know | ||
1342 | * f/w is good to go | ||
1343 | */ | ||
1344 | counter = 0; | ||
1345 | do { | ||
1346 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7fd); | ||
1347 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1348 | if (counter++ > 1000) { | ||
1349 | nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from status check <this is bad!!!> \n"); | ||
1350 | break; | ||
1351 | } | ||
1352 | mdelay(1000); | ||
1353 | /* | ||
1354 | * nes_debug(NES_DBG_PHY, "AMCC PHY- phy_status not ready yet = 0x%02X\n", | ||
1355 | * temp_phy_data); | ||
1356 | */ | ||
1357 | } while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70)); | ||
1358 | |||
1359 | /* set LOS Control invert RXLOSB_I_PADINV */ | ||
1360 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd003, 0x0000); | ||
1361 | /* set LOS Control to mask of RXLOSB_I */ | ||
1362 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc314, 0x0042); | ||
1363 | /* set LED1 to input mode (LED1 and LED2 share same LED) */ | ||
1364 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd006, 0x0007); | ||
1365 | /* set LED2 to RX link_status and activity */ | ||
1366 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd007, 0x000A); | ||
1367 | /* set LED3 to RX link_status */ | ||
1368 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd008, 0x0009); | ||
1369 | |||
1370 | /* | ||
1371 | * reset the res-calibration on t2 | ||
1372 | * serdes; ensures it is stable after | ||
1373 | * the amcc phy is stable | ||
1374 | */ | ||
1375 | |||
1376 | sds_common_control0 = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0); | ||
1377 | sds_common_control0 |= 0x1; | ||
1378 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0); | ||
1379 | |||
1380 | /* release the res-calibration reset */ | ||
1381 | sds_common_control0 &= 0xfffffffe; | ||
1382 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0); | ||
1383 | |||
1384 | i = 0; | ||
1385 | while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040) | ||
1386 | && (i++ < 5000)) { | ||
1387 | /* mdelay(1); */ | ||
1388 | } | ||
1389 | |||
1390 | /* | ||
1391 | * wait for link train done before moving on, | ||
1392 | * or will get an interupt storm | ||
1393 | */ | ||
1394 | counter = 0; | ||
1395 | do { | ||
1396 | temp_phy_data = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | ||
1397 | (0x200 * (nesdev->mac_index & 1))); | ||
1398 | if (counter++ > 1000) { | ||
1399 | nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from link train wait <this is bad, link didnt train!!!>\n"); | ||
1400 | break; | ||
1401 | } | ||
1402 | mdelay(1); | ||
1403 | } while (((temp_phy_data & 0x0f1f0000) != 0x0f0f0000)); | ||
1404 | } | ||
1405 | } | ||
1288 | } | 1406 | } |
1289 | return 0; | 1407 | return 0; |
1290 | } | 1408 | } |
@@ -1377,6 +1495,25 @@ static void nes_rq_wqes_timeout(unsigned long parm) | |||
1377 | } | 1495 | } |
1378 | 1496 | ||
1379 | 1497 | ||
1498 | static int nes_lro_get_skb_hdr(struct sk_buff *skb, void **iphdr, | ||
1499 | void **tcph, u64 *hdr_flags, void *priv) | ||
1500 | { | ||
1501 | unsigned int ip_len; | ||
1502 | struct iphdr *iph; | ||
1503 | skb_reset_network_header(skb); | ||
1504 | iph = ip_hdr(skb); | ||
1505 | if (iph->protocol != IPPROTO_TCP) | ||
1506 | return -1; | ||
1507 | ip_len = ip_hdrlen(skb); | ||
1508 | skb_set_transport_header(skb, ip_len); | ||
1509 | *tcph = tcp_hdr(skb); | ||
1510 | |||
1511 | *hdr_flags = LRO_IPV4 | LRO_TCP; | ||
1512 | *iphdr = iph; | ||
1513 | return 0; | ||
1514 | } | ||
1515 | |||
1516 | |||
1380 | /** | 1517 | /** |
1381 | * nes_init_nic_qp | 1518 | * nes_init_nic_qp |
1382 | */ | 1519 | */ |
@@ -1522,10 +1659,10 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev) | |||
1522 | } | 1659 | } |
1523 | 1660 | ||
1524 | u64temp = (u64)nesvnic->nic.sq_pbase; | 1661 | u64temp = (u64)nesvnic->nic.sq_pbase; |
1525 | nic_context->context_words[NES_NIC_CTX_SQ_LOW_IDX] = cpu_to_le32((u32)u64temp); | 1662 | nic_context->context_words[NES_NIC_CTX_SQ_LOW_IDX] = cpu_to_le32((u32)u64temp); |
1526 | nic_context->context_words[NES_NIC_CTX_SQ_HIGH_IDX] = cpu_to_le32((u32)(u64temp >> 32)); | 1663 | nic_context->context_words[NES_NIC_CTX_SQ_HIGH_IDX] = cpu_to_le32((u32)(u64temp >> 32)); |
1527 | u64temp = (u64)nesvnic->nic.rq_pbase; | 1664 | u64temp = (u64)nesvnic->nic.rq_pbase; |
1528 | nic_context->context_words[NES_NIC_CTX_RQ_LOW_IDX] = cpu_to_le32((u32)u64temp); | 1665 | nic_context->context_words[NES_NIC_CTX_RQ_LOW_IDX] = cpu_to_le32((u32)u64temp); |
1529 | nic_context->context_words[NES_NIC_CTX_RQ_HIGH_IDX] = cpu_to_le32((u32)(u64temp >> 32)); | 1666 | nic_context->context_words[NES_NIC_CTX_RQ_HIGH_IDX] = cpu_to_le32((u32)(u64temp >> 32)); |
1530 | 1667 | ||
1531 | cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_CREATE_QP | | 1668 | cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_CREATE_QP | |
@@ -1577,7 +1714,7 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev) | |||
1577 | nic_rqe = &nesvnic->nic.rq_vbase[counter]; | 1714 | nic_rqe = &nesvnic->nic.rq_vbase[counter]; |
1578 | nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_1_0_IDX] = cpu_to_le32(nesvnic->max_frame_size); | 1715 | nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_1_0_IDX] = cpu_to_le32(nesvnic->max_frame_size); |
1579 | nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_3_2_IDX] = 0; | 1716 | nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_3_2_IDX] = 0; |
1580 | nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX] = cpu_to_le32((u32)pmem); | 1717 | nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX] = cpu_to_le32((u32)pmem); |
1581 | nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX] = cpu_to_le32((u32)((u64)pmem >> 32)); | 1718 | nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX] = cpu_to_le32((u32)((u64)pmem >> 32)); |
1582 | nesvnic->nic.rx_skb[counter] = skb; | 1719 | nesvnic->nic.rx_skb[counter] = skb; |
1583 | } | 1720 | } |
@@ -1594,15 +1731,21 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev) | |||
1594 | nesvnic->rq_wqes_timer.function = nes_rq_wqes_timeout; | 1731 | nesvnic->rq_wqes_timer.function = nes_rq_wqes_timeout; |
1595 | nesvnic->rq_wqes_timer.data = (unsigned long)nesvnic; | 1732 | nesvnic->rq_wqes_timer.data = (unsigned long)nesvnic; |
1596 | nes_debug(NES_DBG_INIT, "NAPI support Enabled\n"); | 1733 | nes_debug(NES_DBG_INIT, "NAPI support Enabled\n"); |
1597 | |||
1598 | if (nesdev->nesadapter->et_use_adaptive_rx_coalesce) | 1734 | if (nesdev->nesadapter->et_use_adaptive_rx_coalesce) |
1599 | { | 1735 | { |
1600 | nes_nic_init_timer(nesdev); | 1736 | nes_nic_init_timer(nesdev); |
1601 | if (netdev->mtu > 1500) | 1737 | if (netdev->mtu > 1500) |
1602 | jumbomode = 1; | 1738 | jumbomode = 1; |
1603 | nes_nic_init_timer_defaults(nesdev, jumbomode); | 1739 | nes_nic_init_timer_defaults(nesdev, jumbomode); |
1604 | } | 1740 | } |
1605 | 1741 | nesvnic->lro_mgr.max_aggr = NES_LRO_MAX_AGGR; | |
1742 | nesvnic->lro_mgr.max_desc = NES_MAX_LRO_DESCRIPTORS; | ||
1743 | nesvnic->lro_mgr.lro_arr = nesvnic->lro_desc; | ||
1744 | nesvnic->lro_mgr.get_skb_header = nes_lro_get_skb_hdr; | ||
1745 | nesvnic->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID; | ||
1746 | nesvnic->lro_mgr.dev = netdev; | ||
1747 | nesvnic->lro_mgr.ip_summed = CHECKSUM_UNNECESSARY; | ||
1748 | nesvnic->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY; | ||
1606 | return 0; | 1749 | return 0; |
1607 | } | 1750 | } |
1608 | 1751 | ||
@@ -1622,8 +1765,8 @@ void nes_destroy_nic_qp(struct nes_vnic *nesvnic) | |||
1622 | 1765 | ||
1623 | /* Free remaining NIC receive buffers */ | 1766 | /* Free remaining NIC receive buffers */ |
1624 | while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) { | 1767 | while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) { |
1625 | nic_rqe = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail]; | 1768 | nic_rqe = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail]; |
1626 | wqe_frag = (u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX]); | 1769 | wqe_frag = (u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX]); |
1627 | wqe_frag |= ((u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX])) << 32; | 1770 | wqe_frag |= ((u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX])) << 32; |
1628 | pci_unmap_single(nesdev->pcidev, (dma_addr_t)wqe_frag, | 1771 | pci_unmap_single(nesdev->pcidev, (dma_addr_t)wqe_frag, |
1629 | nesvnic->max_frame_size, PCI_DMA_FROMDEVICE); | 1772 | nesvnic->max_frame_size, PCI_DMA_FROMDEVICE); |
@@ -1706,17 +1849,17 @@ int nes_napi_isr(struct nes_device *nesdev) | |||
1706 | /* iff NIC, process here, else wait for DPC */ | 1849 | /* iff NIC, process here, else wait for DPC */ |
1707 | if ((int_stat) && ((int_stat & 0x0000ff00) == int_stat)) { | 1850 | if ((int_stat) && ((int_stat & 0x0000ff00) == int_stat)) { |
1708 | nesdev->napi_isr_ran = 0; | 1851 | nesdev->napi_isr_ran = 0; |
1709 | nes_write32(nesdev->regs+NES_INT_STAT, | 1852 | nes_write32(nesdev->regs + NES_INT_STAT, |
1710 | (int_stat & | 1853 | (int_stat & |
1711 | ~(NES_INT_INTF|NES_INT_TIMER|NES_INT_MAC0|NES_INT_MAC1|NES_INT_MAC2|NES_INT_MAC3))); | 1854 | ~(NES_INT_INTF | NES_INT_TIMER | NES_INT_MAC0 | NES_INT_MAC1 | NES_INT_MAC2 | NES_INT_MAC3))); |
1712 | 1855 | ||
1713 | /* Process the CEQs */ | 1856 | /* Process the CEQs */ |
1714 | nes_process_ceq(nesdev, &nesdev->nesadapter->ceq[nesdev->nic_ceq_index]); | 1857 | nes_process_ceq(nesdev, &nesdev->nesadapter->ceq[nesdev->nic_ceq_index]); |
1715 | 1858 | ||
1716 | if (unlikely((((nesadapter->et_rx_coalesce_usecs_irq) && | 1859 | if (unlikely((((nesadapter->et_rx_coalesce_usecs_irq) && |
1717 | (!nesadapter->et_use_adaptive_rx_coalesce)) || | 1860 | (!nesadapter->et_use_adaptive_rx_coalesce)) || |
1718 | ((nesadapter->et_use_adaptive_rx_coalesce) && | 1861 | ((nesadapter->et_use_adaptive_rx_coalesce) && |
1719 | (nesdev->deepcq_count > nesadapter->et_pkt_rate_low)))) ) { | 1862 | (nesdev->deepcq_count > nesadapter->et_pkt_rate_low))))) { |
1720 | if ((nesdev->int_req & NES_INT_TIMER) == 0) { | 1863 | if ((nesdev->int_req & NES_INT_TIMER) == 0) { |
1721 | /* Enable Periodic timer interrupts */ | 1864 | /* Enable Periodic timer interrupts */ |
1722 | nesdev->int_req |= NES_INT_TIMER; | 1865 | nesdev->int_req |= NES_INT_TIMER; |
@@ -1794,12 +1937,12 @@ void nes_dpc(unsigned long param) | |||
1794 | } | 1937 | } |
1795 | 1938 | ||
1796 | if (int_stat) { | 1939 | if (int_stat) { |
1797 | if (int_stat & ~(NES_INT_INTF|NES_INT_TIMER|NES_INT_MAC0| | 1940 | if (int_stat & ~(NES_INT_INTF | NES_INT_TIMER | NES_INT_MAC0| |
1798 | NES_INT_MAC1|NES_INT_MAC2|NES_INT_MAC3)) { | 1941 | NES_INT_MAC1|NES_INT_MAC2 | NES_INT_MAC3)) { |
1799 | /* Ack the interrupts */ | 1942 | /* Ack the interrupts */ |
1800 | nes_write32(nesdev->regs+NES_INT_STAT, | 1943 | nes_write32(nesdev->regs+NES_INT_STAT, |
1801 | (int_stat & ~(NES_INT_INTF|NES_INT_TIMER|NES_INT_MAC0| | 1944 | (int_stat & ~(NES_INT_INTF | NES_INT_TIMER | NES_INT_MAC0| |
1802 | NES_INT_MAC1|NES_INT_MAC2|NES_INT_MAC3))); | 1945 | NES_INT_MAC1 | NES_INT_MAC2 | NES_INT_MAC3))); |
1803 | } | 1946 | } |
1804 | 1947 | ||
1805 | temp_int_stat = int_stat; | 1948 | temp_int_stat = int_stat; |
@@ -1864,8 +2007,8 @@ void nes_dpc(unsigned long param) | |||
1864 | } | 2007 | } |
1865 | } | 2008 | } |
1866 | /* Don't use the interface interrupt bit stay in loop */ | 2009 | /* Don't use the interface interrupt bit stay in loop */ |
1867 | int_stat &= ~NES_INT_INTF|NES_INT_TIMER|NES_INT_MAC0| | 2010 | int_stat &= ~NES_INT_INTF | NES_INT_TIMER | NES_INT_MAC0 | |
1868 | NES_INT_MAC1|NES_INT_MAC2|NES_INT_MAC3; | 2011 | NES_INT_MAC1 | NES_INT_MAC2 | NES_INT_MAC3; |
1869 | } while ((int_stat != 0) && (loop_counter++ < MAX_DPC_ITERATIONS)); | 2012 | } while ((int_stat != 0) && (loop_counter++ < MAX_DPC_ITERATIONS)); |
1870 | 2013 | ||
1871 | if (timer_ints == 1) { | 2014 | if (timer_ints == 1) { |
@@ -1876,9 +2019,9 @@ void nes_dpc(unsigned long param) | |||
1876 | nesdev->timer_only_int_count = 0; | 2019 | nesdev->timer_only_int_count = 0; |
1877 | nesdev->int_req &= ~NES_INT_TIMER; | 2020 | nesdev->int_req &= ~NES_INT_TIMER; |
1878 | nes_write32(nesdev->regs + NES_INTF_INT_MASK, ~(nesdev->intf_int_req)); | 2021 | nes_write32(nesdev->regs + NES_INTF_INT_MASK, ~(nesdev->intf_int_req)); |
1879 | nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req); | 2022 | nes_write32(nesdev->regs + NES_INT_MASK, ~nesdev->int_req); |
1880 | } else { | 2023 | } else { |
1881 | nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff|(~nesdev->int_req)); | 2024 | nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff | (~nesdev->int_req)); |
1882 | } | 2025 | } |
1883 | } else { | 2026 | } else { |
1884 | if (unlikely(nesadapter->et_use_adaptive_rx_coalesce)) | 2027 | if (unlikely(nesadapter->et_use_adaptive_rx_coalesce)) |
@@ -1886,7 +2029,7 @@ void nes_dpc(unsigned long param) | |||
1886 | nes_nic_init_timer(nesdev); | 2029 | nes_nic_init_timer(nesdev); |
1887 | } | 2030 | } |
1888 | nesdev->timer_only_int_count = 0; | 2031 | nesdev->timer_only_int_count = 0; |
1889 | nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff|(~nesdev->int_req)); | 2032 | nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff | (~nesdev->int_req)); |
1890 | } | 2033 | } |
1891 | } else { | 2034 | } else { |
1892 | nesdev->timer_only_int_count = 0; | 2035 | nesdev->timer_only_int_count = 0; |
@@ -1935,7 +2078,7 @@ static void nes_process_ceq(struct nes_device *nesdev, struct nes_hw_ceq *ceq) | |||
1935 | do { | 2078 | do { |
1936 | if (le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_HIGH_IDX]) & | 2079 | if (le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_HIGH_IDX]) & |
1937 | NES_CEQE_VALID) { | 2080 | NES_CEQE_VALID) { |
1938 | u64temp = (((u64)(le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_HIGH_IDX])))<<32) | | 2081 | u64temp = (((u64)(le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_HIGH_IDX]))) << 32) | |
1939 | ((u64)(le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_LOW_IDX]))); | 2082 | ((u64)(le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_LOW_IDX]))); |
1940 | u64temp <<= 1; | 2083 | u64temp <<= 1; |
1941 | cq = *((struct nes_hw_cq **)&u64temp); | 2084 | cq = *((struct nes_hw_cq **)&u64temp); |
@@ -1963,7 +2106,7 @@ static void nes_process_ceq(struct nes_device *nesdev, struct nes_hw_ceq *ceq) | |||
1963 | */ | 2106 | */ |
1964 | static void nes_process_aeq(struct nes_device *nesdev, struct nes_hw_aeq *aeq) | 2107 | static void nes_process_aeq(struct nes_device *nesdev, struct nes_hw_aeq *aeq) |
1965 | { | 2108 | { |
1966 | // u64 u64temp; | 2109 | /* u64 u64temp; */ |
1967 | u32 head; | 2110 | u32 head; |
1968 | u32 aeq_size; | 2111 | u32 aeq_size; |
1969 | u32 aeqe_misc; | 2112 | u32 aeqe_misc; |
@@ -1982,8 +2125,10 @@ static void nes_process_aeq(struct nes_device *nesdev, struct nes_hw_aeq *aeq) | |||
1982 | if (aeqe_misc & (NES_AEQE_QP|NES_AEQE_CQ)) { | 2125 | if (aeqe_misc & (NES_AEQE_QP|NES_AEQE_CQ)) { |
1983 | if (aeqe_cq_id >= NES_FIRST_QPN) { | 2126 | if (aeqe_cq_id >= NES_FIRST_QPN) { |
1984 | /* dealing with an accelerated QP related AE */ | 2127 | /* dealing with an accelerated QP related AE */ |
1985 | // u64temp = (((u64)(le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])))<<32) | | 2128 | /* |
1986 | // ((u64)(le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]))); | 2129 | * u64temp = (((u64)(le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX]))) << 32) | |
2130 | * ((u64)(le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]))); | ||
2131 | */ | ||
1987 | nes_process_iwarp_aeqe(nesdev, (struct nes_hw_aeqe *)aeqe); | 2132 | nes_process_iwarp_aeqe(nesdev, (struct nes_hw_aeqe *)aeqe); |
1988 | } else { | 2133 | } else { |
1989 | /* TODO: dealing with a CQP related AE */ | 2134 | /* TODO: dealing with a CQP related AE */ |
@@ -2083,6 +2228,8 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
2083 | u32 u32temp; | 2228 | u32 u32temp; |
2084 | u16 phy_data; | 2229 | u16 phy_data; |
2085 | u16 temp_phy_data; | 2230 | u16 temp_phy_data; |
2231 | u32 pcs_val = 0x0f0f0000; | ||
2232 | u32 pcs_mask = 0x0f1f0000; | ||
2086 | 2233 | ||
2087 | spin_lock_irqsave(&nesadapter->phy_lock, flags); | 2234 | spin_lock_irqsave(&nesadapter->phy_lock, flags); |
2088 | if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) { | 2235 | if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) { |
@@ -2146,13 +2293,30 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
2146 | nes_debug(NES_DBG_PHY, "Eth SERDES Common Status: 0=0x%08X, 1=0x%08X\n", | 2293 | nes_debug(NES_DBG_PHY, "Eth SERDES Common Status: 0=0x%08X, 1=0x%08X\n", |
2147 | nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0), | 2294 | nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0), |
2148 | nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0+0x200)); | 2295 | nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0+0x200)); |
2149 | pcs_control_status = nes_read_indexed(nesdev, | 2296 | |
2150 | NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index&1)*0x200)); | 2297 | if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_PUMA_1G) { |
2151 | pcs_control_status = nes_read_indexed(nesdev, | 2298 | switch (mac_index) { |
2152 | NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index&1)*0x200)); | 2299 | case 1: |
2300 | case 3: | ||
2301 | pcs_control_status = nes_read_indexed(nesdev, | ||
2302 | NES_IDX_PHY_PCS_CONTROL_STATUS0 + 0x200); | ||
2303 | break; | ||
2304 | default: | ||
2305 | pcs_control_status = nes_read_indexed(nesdev, | ||
2306 | NES_IDX_PHY_PCS_CONTROL_STATUS0); | ||
2307 | break; | ||
2308 | } | ||
2309 | } else { | ||
2310 | pcs_control_status = nes_read_indexed(nesdev, | ||
2311 | NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index & 1) * 0x200)); | ||
2312 | pcs_control_status = nes_read_indexed(nesdev, | ||
2313 | NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index & 1) * 0x200)); | ||
2314 | } | ||
2315 | |||
2153 | nes_debug(NES_DBG_PHY, "PCS PHY Control/Status%u: 0x%08X\n", | 2316 | nes_debug(NES_DBG_PHY, "PCS PHY Control/Status%u: 0x%08X\n", |
2154 | mac_index, pcs_control_status); | 2317 | mac_index, pcs_control_status); |
2155 | if (nesadapter->OneG_Mode) { | 2318 | if ((nesadapter->OneG_Mode) && |
2319 | (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) { | ||
2156 | u32temp = 0x01010000; | 2320 | u32temp = 0x01010000; |
2157 | if (nesadapter->port_count > 2) { | 2321 | if (nesadapter->port_count > 2) { |
2158 | u32temp |= 0x02020000; | 2322 | u32temp |= 0x02020000; |
@@ -2161,24 +2325,59 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
2161 | phy_data = 0; | 2325 | phy_data = 0; |
2162 | nes_debug(NES_DBG_PHY, "PCS says the link is down\n"); | 2326 | nes_debug(NES_DBG_PHY, "PCS says the link is down\n"); |
2163 | } | 2327 | } |
2164 | } else if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) { | ||
2165 | nes_read_10G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index]); | ||
2166 | temp_phy_data = (u16)nes_read_indexed(nesdev, | ||
2167 | NES_IDX_MAC_MDIO_CONTROL); | ||
2168 | u32temp = 20; | ||
2169 | do { | ||
2170 | nes_read_10G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index]); | ||
2171 | phy_data = (u16)nes_read_indexed(nesdev, | ||
2172 | NES_IDX_MAC_MDIO_CONTROL); | ||
2173 | if ((phy_data == temp_phy_data) || (!(--u32temp))) | ||
2174 | break; | ||
2175 | temp_phy_data = phy_data; | ||
2176 | } while (1); | ||
2177 | nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n", | ||
2178 | __func__, phy_data, nesadapter->mac_link_down ? "DOWN" : "UP"); | ||
2179 | |||
2180 | } else { | 2328 | } else { |
2181 | phy_data = (0x0f0f0000 == (pcs_control_status & 0x0f1f0000)) ? 4 : 0; | 2329 | switch (nesadapter->phy_type[mac_index]) { |
2330 | case NES_PHY_TYPE_IRIS: | ||
2331 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1); | ||
2332 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
2333 | u32temp = 20; | ||
2334 | do { | ||
2335 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1); | ||
2336 | phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
2337 | if ((phy_data == temp_phy_data) || (!(--u32temp))) | ||
2338 | break; | ||
2339 | temp_phy_data = phy_data; | ||
2340 | } while (1); | ||
2341 | nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n", | ||
2342 | __func__, phy_data, nesadapter->mac_link_down[mac_index] ? "DOWN" : "UP"); | ||
2343 | break; | ||
2344 | |||
2345 | case NES_PHY_TYPE_ARGUS: | ||
2346 | /* clear the alarms */ | ||
2347 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0x0008); | ||
2348 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc001); | ||
2349 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc002); | ||
2350 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc005); | ||
2351 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc006); | ||
2352 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9003); | ||
2353 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9004); | ||
2354 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9005); | ||
2355 | /* check link status */ | ||
2356 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1); | ||
2357 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
2358 | u32temp = 100; | ||
2359 | do { | ||
2360 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1); | ||
2361 | |||
2362 | phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
2363 | if ((phy_data == temp_phy_data) || (!(--u32temp))) | ||
2364 | break; | ||
2365 | temp_phy_data = phy_data; | ||
2366 | } while (1); | ||
2367 | nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n", | ||
2368 | __func__, phy_data, nesadapter->mac_link_down ? "DOWN" : "UP"); | ||
2369 | break; | ||
2370 | |||
2371 | case NES_PHY_TYPE_PUMA_1G: | ||
2372 | if (mac_index < 2) | ||
2373 | pcs_val = pcs_mask = 0x01010000; | ||
2374 | else | ||
2375 | pcs_val = pcs_mask = 0x02020000; | ||
2376 | /* fall through */ | ||
2377 | default: | ||
2378 | phy_data = (pcs_val == (pcs_control_status & pcs_mask)) ? 0x4 : 0x0; | ||
2379 | break; | ||
2380 | } | ||
2182 | } | 2381 | } |
2183 | 2382 | ||
2184 | if (phy_data & 0x0004) { | 2383 | if (phy_data & 0x0004) { |
@@ -2187,8 +2386,8 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
2187 | nes_debug(NES_DBG_PHY, "The Link is UP!!. linkup was %d\n", | 2386 | nes_debug(NES_DBG_PHY, "The Link is UP!!. linkup was %d\n", |
2188 | nesvnic->linkup); | 2387 | nesvnic->linkup); |
2189 | if (nesvnic->linkup == 0) { | 2388 | if (nesvnic->linkup == 0) { |
2190 | printk(PFX "The Link is now up for port %u, netdev %p.\n", | 2389 | printk(PFX "The Link is now up for port %s, netdev %p.\n", |
2191 | mac_index, nesvnic->netdev); | 2390 | nesvnic->netdev->name, nesvnic->netdev); |
2192 | if (netif_queue_stopped(nesvnic->netdev)) | 2391 | if (netif_queue_stopped(nesvnic->netdev)) |
2193 | netif_start_queue(nesvnic->netdev); | 2392 | netif_start_queue(nesvnic->netdev); |
2194 | nesvnic->linkup = 1; | 2393 | nesvnic->linkup = 1; |
@@ -2201,8 +2400,8 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
2201 | nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n", | 2400 | nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n", |
2202 | nesvnic->linkup); | 2401 | nesvnic->linkup); |
2203 | if (nesvnic->linkup == 1) { | 2402 | if (nesvnic->linkup == 1) { |
2204 | printk(PFX "The Link is now down for port %u, netdev %p.\n", | 2403 | printk(PFX "The Link is now down for port %s, netdev %p.\n", |
2205 | mac_index, nesvnic->netdev); | 2404 | nesvnic->netdev->name, nesvnic->netdev); |
2206 | if (!(netif_queue_stopped(nesvnic->netdev))) | 2405 | if (!(netif_queue_stopped(nesvnic->netdev))) |
2207 | netif_stop_queue(nesvnic->netdev); | 2406 | netif_stop_queue(nesvnic->netdev); |
2208 | nesvnic->linkup = 0; | 2407 | nesvnic->linkup = 0; |
@@ -2256,10 +2455,13 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) | |||
2256 | u16 pkt_type; | 2455 | u16 pkt_type; |
2257 | u16 rqes_processed = 0; | 2456 | u16 rqes_processed = 0; |
2258 | u8 sq_cqes = 0; | 2457 | u8 sq_cqes = 0; |
2458 | u8 nes_use_lro = 0; | ||
2259 | 2459 | ||
2260 | head = cq->cq_head; | 2460 | head = cq->cq_head; |
2261 | cq_size = cq->cq_size; | 2461 | cq_size = cq->cq_size; |
2262 | cq->cqes_pending = 1; | 2462 | cq->cqes_pending = 1; |
2463 | if (nesvnic->netdev->features & NETIF_F_LRO) | ||
2464 | nes_use_lro = 1; | ||
2263 | do { | 2465 | do { |
2264 | if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_NIC_CQE_MISC_IDX]) & | 2466 | if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_NIC_CQE_MISC_IDX]) & |
2265 | NES_NIC_CQE_VALID) { | 2467 | NES_NIC_CQE_VALID) { |
@@ -2274,8 +2476,10 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) | |||
2274 | /* bump past the vlan tag */ | 2476 | /* bump past the vlan tag */ |
2275 | wqe_fragment_length++; | 2477 | wqe_fragment_length++; |
2276 | if (le16_to_cpu(wqe_fragment_length[wqe_fragment_index]) != 0) { | 2478 | if (le16_to_cpu(wqe_fragment_length[wqe_fragment_index]) != 0) { |
2277 | u64temp = (u64) le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX+wqe_fragment_index*2]); | 2479 | u64temp = (u64) le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX + |
2278 | u64temp += ((u64)le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX+wqe_fragment_index*2]))<<32; | 2480 | wqe_fragment_index * 2]); |
2481 | u64temp += ((u64)le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX + | ||
2482 | wqe_fragment_index * 2])) << 32; | ||
2279 | bus_address = (dma_addr_t)u64temp; | 2483 | bus_address = (dma_addr_t)u64temp; |
2280 | if (test_and_clear_bit(nesnic->sq_tail, nesnic->first_frag_overflow)) { | 2484 | if (test_and_clear_bit(nesnic->sq_tail, nesnic->first_frag_overflow)) { |
2281 | pci_unmap_single(nesdev->pcidev, | 2485 | pci_unmap_single(nesdev->pcidev, |
@@ -2285,8 +2489,10 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) | |||
2285 | } | 2489 | } |
2286 | for (; wqe_fragment_index < 5; wqe_fragment_index++) { | 2490 | for (; wqe_fragment_index < 5; wqe_fragment_index++) { |
2287 | if (wqe_fragment_length[wqe_fragment_index]) { | 2491 | if (wqe_fragment_length[wqe_fragment_index]) { |
2288 | u64temp = le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX+wqe_fragment_index*2]); | 2492 | u64temp = le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX + |
2289 | u64temp += ((u64)le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX+wqe_fragment_index*2]))<<32; | 2493 | wqe_fragment_index * 2]); |
2494 | u64temp += ((u64)le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX | ||
2495 | + wqe_fragment_index * 2])) <<32; | ||
2290 | bus_address = (dma_addr_t)u64temp; | 2496 | bus_address = (dma_addr_t)u64temp; |
2291 | pci_unmap_page(nesdev->pcidev, | 2497 | pci_unmap_page(nesdev->pcidev, |
2292 | bus_address, | 2498 | bus_address, |
@@ -2333,7 +2539,7 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) | |||
2333 | if (atomic_read(&nesvnic->rx_skbs_needed) > (nesvnic->nic.rq_size>>1)) { | 2539 | if (atomic_read(&nesvnic->rx_skbs_needed) > (nesvnic->nic.rq_size>>1)) { |
2334 | nes_write32(nesdev->regs+NES_CQE_ALLOC, | 2540 | nes_write32(nesdev->regs+NES_CQE_ALLOC, |
2335 | cq->cq_number | (cqe_count << 16)); | 2541 | cq->cq_number | (cqe_count << 16)); |
2336 | // nesadapter->tune_timer.cq_count += cqe_count; | 2542 | /* nesadapter->tune_timer.cq_count += cqe_count; */ |
2337 | nesdev->currcq_count += cqe_count; | 2543 | nesdev->currcq_count += cqe_count; |
2338 | cqe_count = 0; | 2544 | cqe_count = 0; |
2339 | nes_replenish_nic_rq(nesvnic); | 2545 | nes_replenish_nic_rq(nesvnic); |
@@ -2381,9 +2587,16 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) | |||
2381 | >> 16); | 2587 | >> 16); |
2382 | nes_debug(NES_DBG_CQ, "%s: Reporting stripped VLAN packet. Tag = 0x%04X\n", | 2588 | nes_debug(NES_DBG_CQ, "%s: Reporting stripped VLAN packet. Tag = 0x%04X\n", |
2383 | nesvnic->netdev->name, vlan_tag); | 2589 | nesvnic->netdev->name, vlan_tag); |
2384 | nes_vlan_rx(rx_skb, nesvnic->vlan_grp, vlan_tag); | 2590 | if (nes_use_lro) |
2591 | lro_vlan_hwaccel_receive_skb(&nesvnic->lro_mgr, rx_skb, | ||
2592 | nesvnic->vlan_grp, vlan_tag, NULL); | ||
2593 | else | ||
2594 | nes_vlan_rx(rx_skb, nesvnic->vlan_grp, vlan_tag); | ||
2385 | } else { | 2595 | } else { |
2386 | nes_netif_rx(rx_skb); | 2596 | if (nes_use_lro) |
2597 | lro_receive_skb(&nesvnic->lro_mgr, rx_skb, NULL); | ||
2598 | else | ||
2599 | nes_netif_rx(rx_skb); | ||
2387 | } | 2600 | } |
2388 | } | 2601 | } |
2389 | 2602 | ||
@@ -2401,7 +2614,7 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) | |||
2401 | /* Replenish Nic CQ */ | 2614 | /* Replenish Nic CQ */ |
2402 | nes_write32(nesdev->regs+NES_CQE_ALLOC, | 2615 | nes_write32(nesdev->regs+NES_CQE_ALLOC, |
2403 | cq->cq_number | (cqe_count << 16)); | 2616 | cq->cq_number | (cqe_count << 16)); |
2404 | // nesdev->nesadapter->tune_timer.cq_count += cqe_count; | 2617 | /* nesdev->nesadapter->tune_timer.cq_count += cqe_count; */ |
2405 | nesdev->currcq_count += cqe_count; | 2618 | nesdev->currcq_count += cqe_count; |
2406 | cqe_count = 0; | 2619 | cqe_count = 0; |
2407 | } | 2620 | } |
@@ -2415,26 +2628,27 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) | |||
2415 | 2628 | ||
2416 | } while (1); | 2629 | } while (1); |
2417 | 2630 | ||
2631 | if (nes_use_lro) | ||
2632 | lro_flush_all(&nesvnic->lro_mgr); | ||
2418 | if (sq_cqes) { | 2633 | if (sq_cqes) { |
2419 | barrier(); | 2634 | barrier(); |
2420 | /* restart the queue if it had been stopped */ | 2635 | /* restart the queue if it had been stopped */ |
2421 | if (netif_queue_stopped(nesvnic->netdev)) | 2636 | if (netif_queue_stopped(nesvnic->netdev)) |
2422 | netif_wake_queue(nesvnic->netdev); | 2637 | netif_wake_queue(nesvnic->netdev); |
2423 | } | 2638 | } |
2424 | |||
2425 | cq->cq_head = head; | 2639 | cq->cq_head = head; |
2426 | /* nes_debug(NES_DBG_CQ, "CQ%u Processed = %u cqes, new head = %u.\n", | 2640 | /* nes_debug(NES_DBG_CQ, "CQ%u Processed = %u cqes, new head = %u.\n", |
2427 | cq->cq_number, cqe_count, cq->cq_head); */ | 2641 | cq->cq_number, cqe_count, cq->cq_head); */ |
2428 | cq->cqe_allocs_pending = cqe_count; | 2642 | cq->cqe_allocs_pending = cqe_count; |
2429 | if (unlikely(nesadapter->et_use_adaptive_rx_coalesce)) | 2643 | if (unlikely(nesadapter->et_use_adaptive_rx_coalesce)) |
2430 | { | 2644 | { |
2431 | // nesdev->nesadapter->tune_timer.cq_count += cqe_count; | 2645 | /* nesdev->nesadapter->tune_timer.cq_count += cqe_count; */ |
2432 | nesdev->currcq_count += cqe_count; | 2646 | nesdev->currcq_count += cqe_count; |
2433 | nes_nic_tune_timer(nesdev); | 2647 | nes_nic_tune_timer(nesdev); |
2434 | } | 2648 | } |
2435 | if (atomic_read(&nesvnic->rx_skbs_needed)) | 2649 | if (atomic_read(&nesvnic->rx_skbs_needed)) |
2436 | nes_replenish_nic_rq(nesvnic); | 2650 | nes_replenish_nic_rq(nesvnic); |
2437 | } | 2651 | } |
2438 | 2652 | ||
2439 | 2653 | ||
2440 | /** | 2654 | /** |
@@ -2463,7 +2677,7 @@ static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq) | |||
2463 | 2677 | ||
2464 | if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX]) & NES_CQE_VALID) { | 2678 | if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX]) & NES_CQE_VALID) { |
2465 | u64temp = (((u64)(le32_to_cpu(cq->cq_vbase[head]. | 2679 | u64temp = (((u64)(le32_to_cpu(cq->cq_vbase[head]. |
2466 | cqe_words[NES_CQE_COMP_COMP_CTX_HIGH_IDX])))<<32) | | 2680 | cqe_words[NES_CQE_COMP_COMP_CTX_HIGH_IDX]))) << 32) | |
2467 | ((u64)(le32_to_cpu(cq->cq_vbase[head]. | 2681 | ((u64)(le32_to_cpu(cq->cq_vbase[head]. |
2468 | cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]))); | 2682 | cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]))); |
2469 | cqp = *((struct nes_hw_cqp **)&u64temp); | 2683 | cqp = *((struct nes_hw_cqp **)&u64temp); |
@@ -2480,7 +2694,7 @@ static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq) | |||
2480 | } | 2694 | } |
2481 | 2695 | ||
2482 | u64temp = (((u64)(le32_to_cpu(nesdev->cqp.sq_vbase[cqp->sq_tail]. | 2696 | u64temp = (((u64)(le32_to_cpu(nesdev->cqp.sq_vbase[cqp->sq_tail]. |
2483 | wqe_words[NES_CQP_WQE_COMP_SCRATCH_HIGH_IDX])))<<32) | | 2697 | wqe_words[NES_CQP_WQE_COMP_SCRATCH_HIGH_IDX]))) << 32) | |
2484 | ((u64)(le32_to_cpu(nesdev->cqp.sq_vbase[cqp->sq_tail]. | 2698 | ((u64)(le32_to_cpu(nesdev->cqp.sq_vbase[cqp->sq_tail]. |
2485 | wqe_words[NES_CQP_WQE_COMP_SCRATCH_LOW_IDX]))); | 2699 | wqe_words[NES_CQP_WQE_COMP_SCRATCH_LOW_IDX]))); |
2486 | cqp_request = *((struct nes_cqp_request **)&u64temp); | 2700 | cqp_request = *((struct nes_cqp_request **)&u64temp); |
@@ -2517,7 +2731,7 @@ static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq) | |||
2517 | } else { | 2731 | } else { |
2518 | nes_debug(NES_DBG_CQP, "CQP request %p (opcode 0x%02X) freed.\n", | 2732 | nes_debug(NES_DBG_CQP, "CQP request %p (opcode 0x%02X) freed.\n", |
2519 | cqp_request, | 2733 | cqp_request, |
2520 | le32_to_cpu(cqp_request->cqp_wqe.wqe_words[NES_CQP_WQE_OPCODE_IDX])&0x3f); | 2734 | le32_to_cpu(cqp_request->cqp_wqe.wqe_words[NES_CQP_WQE_OPCODE_IDX]) & 0x3f); |
2521 | if (cqp_request->dynamic) { | 2735 | if (cqp_request->dynamic) { |
2522 | kfree(cqp_request); | 2736 | kfree(cqp_request); |
2523 | } else { | 2737 | } else { |
@@ -2531,7 +2745,7 @@ static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq) | |||
2531 | } | 2745 | } |
2532 | 2746 | ||
2533 | cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX] = 0; | 2747 | cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX] = 0; |
2534 | nes_write32(nesdev->regs+NES_CQE_ALLOC, cq->cq_number | (1 << 16)); | 2748 | nes_write32(nesdev->regs + NES_CQE_ALLOC, cq->cq_number | (1 << 16)); |
2535 | if (++cqp->sq_tail >= cqp->sq_size) | 2749 | if (++cqp->sq_tail >= cqp->sq_size) |
2536 | cqp->sq_tail = 0; | 2750 | cqp->sq_tail = 0; |
2537 | 2751 | ||
@@ -2600,13 +2814,13 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, | |||
2600 | nes_debug(NES_DBG_AEQ, "\n"); | 2814 | nes_debug(NES_DBG_AEQ, "\n"); |
2601 | aeq_info = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_MISC_IDX]); | 2815 | aeq_info = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_MISC_IDX]); |
2602 | if ((NES_AEQE_INBOUND_RDMA&aeq_info) || (!(NES_AEQE_QP&aeq_info))) { | 2816 | if ((NES_AEQE_INBOUND_RDMA&aeq_info) || (!(NES_AEQE_QP&aeq_info))) { |
2603 | context = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]); | 2817 | context = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]); |
2604 | context += ((u64)le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])) << 32; | 2818 | context += ((u64)le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])) << 32; |
2605 | } else { | 2819 | } else { |
2606 | aeqe_context = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]); | 2820 | aeqe_context = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]); |
2607 | aeqe_context += ((u64)le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])) << 32; | 2821 | aeqe_context += ((u64)le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])) << 32; |
2608 | context = (unsigned long)nesadapter->qp_table[le32_to_cpu( | 2822 | context = (unsigned long)nesadapter->qp_table[le32_to_cpu( |
2609 | aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX])-NES_FIRST_QPN]; | 2823 | aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]) - NES_FIRST_QPN]; |
2610 | BUG_ON(!context); | 2824 | BUG_ON(!context); |
2611 | } | 2825 | } |
2612 | 2826 | ||
@@ -2619,7 +2833,6 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, | |||
2619 | le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]), aeqe, | 2833 | le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]), aeqe, |
2620 | nes_tcp_state_str[tcp_state], nes_iwarp_state_str[iwarp_state]); | 2834 | nes_tcp_state_str[tcp_state], nes_iwarp_state_str[iwarp_state]); |
2621 | 2835 | ||
2622 | |||
2623 | switch (async_event_id) { | 2836 | switch (async_event_id) { |
2624 | case NES_AEQE_AEID_LLP_FIN_RECEIVED: | 2837 | case NES_AEQE_AEID_LLP_FIN_RECEIVED: |
2625 | nesqp = *((struct nes_qp **)&context); | 2838 | nesqp = *((struct nes_qp **)&context); |
@@ -3023,7 +3236,7 @@ void nes_manage_arp_cache(struct net_device *netdev, unsigned char *mac_addr, | |||
3023 | cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] |= cpu_to_le32(NES_CQP_ARP_VALID); | 3236 | cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] |= cpu_to_le32(NES_CQP_ARP_VALID); |
3024 | cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_ADDR_LOW_IDX] = cpu_to_le32( | 3237 | cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_ADDR_LOW_IDX] = cpu_to_le32( |
3025 | (((u32)mac_addr[2]) << 24) | (((u32)mac_addr[3]) << 16) | | 3238 | (((u32)mac_addr[2]) << 24) | (((u32)mac_addr[3]) << 16) | |
3026 | (((u32)mac_addr[4]) << 8) | (u32)mac_addr[5]); | 3239 | (((u32)mac_addr[4]) << 8) | (u32)mac_addr[5]); |
3027 | cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_HIGH_IDX] = cpu_to_le32( | 3240 | cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_HIGH_IDX] = cpu_to_le32( |
3028 | (((u32)mac_addr[0]) << 16) | (u32)mac_addr[1]); | 3241 | (((u32)mac_addr[0]) << 16) | (u32)mac_addr[1]); |
3029 | } else { | 3242 | } else { |
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index b7e2844f096b..745bf94f3f07 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h | |||
@@ -33,8 +33,12 @@ | |||
33 | #ifndef __NES_HW_H | 33 | #ifndef __NES_HW_H |
34 | #define __NES_HW_H | 34 | #define __NES_HW_H |
35 | 35 | ||
36 | #define NES_PHY_TYPE_1G 2 | 36 | #include <linux/inet_lro.h> |
37 | #define NES_PHY_TYPE_IRIS 3 | 37 | |
38 | #define NES_PHY_TYPE_1G 2 | ||
39 | #define NES_PHY_TYPE_IRIS 3 | ||
40 | #define NES_PHY_TYPE_ARGUS 4 | ||
41 | #define NES_PHY_TYPE_PUMA_1G 5 | ||
38 | #define NES_PHY_TYPE_PUMA_10G 6 | 42 | #define NES_PHY_TYPE_PUMA_10G 6 |
39 | 43 | ||
40 | #define NES_MULTICAST_PF_MAX 8 | 44 | #define NES_MULTICAST_PF_MAX 8 |
@@ -905,7 +909,7 @@ struct nes_hw_qp { | |||
905 | }; | 909 | }; |
906 | 910 | ||
907 | struct nes_hw_cq { | 911 | struct nes_hw_cq { |
908 | struct nes_hw_cqe volatile *cq_vbase; /* PCI memory for host rings */ | 912 | struct nes_hw_cqe *cq_vbase; /* PCI memory for host rings */ |
909 | void (*ce_handler)(struct nes_device *nesdev, struct nes_hw_cq *cq); | 913 | void (*ce_handler)(struct nes_device *nesdev, struct nes_hw_cq *cq); |
910 | dma_addr_t cq_pbase; /* PCI memory for host rings */ | 914 | dma_addr_t cq_pbase; /* PCI memory for host rings */ |
911 | u16 cq_head; | 915 | u16 cq_head; |
@@ -965,7 +969,7 @@ struct nes_arp_entry { | |||
965 | #define NES_NIC_CQ_DOWNWARD_TREND 16 | 969 | #define NES_NIC_CQ_DOWNWARD_TREND 16 |
966 | 970 | ||
967 | struct nes_hw_tune_timer { | 971 | struct nes_hw_tune_timer { |
968 | //u16 cq_count; | 972 | /* u16 cq_count; */ |
969 | u16 threshold_low; | 973 | u16 threshold_low; |
970 | u16 threshold_target; | 974 | u16 threshold_target; |
971 | u16 threshold_high; | 975 | u16 threshold_high; |
@@ -982,8 +986,10 @@ struct nes_hw_tune_timer { | |||
982 | #define NES_TIMER_INT_LIMIT 2 | 986 | #define NES_TIMER_INT_LIMIT 2 |
983 | #define NES_TIMER_INT_LIMIT_DYNAMIC 10 | 987 | #define NES_TIMER_INT_LIMIT_DYNAMIC 10 |
984 | #define NES_TIMER_ENABLE_LIMIT 4 | 988 | #define NES_TIMER_ENABLE_LIMIT 4 |
985 | #define NES_MAX_LINK_INTERRUPTS 128 | 989 | #define NES_MAX_LINK_INTERRUPTS 128 |
986 | #define NES_MAX_LINK_CHECK 200 | 990 | #define NES_MAX_LINK_CHECK 200 |
991 | #define NES_MAX_LRO_DESCRIPTORS 32 | ||
992 | #define NES_LRO_MAX_AGGR 64 | ||
987 | 993 | ||
988 | struct nes_adapter { | 994 | struct nes_adapter { |
989 | u64 fw_ver; | 995 | u64 fw_ver; |
@@ -1183,6 +1189,9 @@ struct nes_vnic { | |||
1183 | u8 of_device_registered; | 1189 | u8 of_device_registered; |
1184 | u8 rdma_enabled; | 1190 | u8 rdma_enabled; |
1185 | u8 rx_checksum_disabled; | 1191 | u8 rx_checksum_disabled; |
1192 | u32 lro_max_aggr; | ||
1193 | struct net_lro_mgr lro_mgr; | ||
1194 | struct net_lro_desc lro_desc[NES_MAX_LRO_DESCRIPTORS]; | ||
1186 | }; | 1195 | }; |
1187 | 1196 | ||
1188 | struct nes_ib_device { | 1197 | struct nes_ib_device { |
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index 01cd0effc492..1b0938c87774 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c | |||
@@ -185,12 +185,13 @@ static int nes_netdev_open(struct net_device *netdev) | |||
185 | nic_active |= nic_active_bit; | 185 | nic_active |= nic_active_bit; |
186 | nes_write_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON, nic_active); | 186 | nes_write_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON, nic_active); |
187 | 187 | ||
188 | macaddr_high = ((u16)netdev->dev_addr[0]) << 8; | 188 | macaddr_high = ((u16)netdev->dev_addr[0]) << 8; |
189 | macaddr_high += (u16)netdev->dev_addr[1]; | 189 | macaddr_high += (u16)netdev->dev_addr[1]; |
190 | macaddr_low = ((u32)netdev->dev_addr[2]) << 24; | 190 | |
191 | macaddr_low += ((u32)netdev->dev_addr[3]) << 16; | 191 | macaddr_low = ((u32)netdev->dev_addr[2]) << 24; |
192 | macaddr_low += ((u32)netdev->dev_addr[4]) << 8; | 192 | macaddr_low += ((u32)netdev->dev_addr[3]) << 16; |
193 | macaddr_low += (u32)netdev->dev_addr[5]; | 193 | macaddr_low += ((u32)netdev->dev_addr[4]) << 8; |
194 | macaddr_low += (u32)netdev->dev_addr[5]; | ||
194 | 195 | ||
195 | /* Program the various MAC regs */ | 196 | /* Program the various MAC regs */ |
196 | for (i = 0; i < NES_MAX_PORT_COUNT; i++) { | 197 | for (i = 0; i < NES_MAX_PORT_COUNT; i++) { |
@@ -451,7 +452,7 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
451 | __le16 *wqe_fragment_length; | 452 | __le16 *wqe_fragment_length; |
452 | u32 nr_frags; | 453 | u32 nr_frags; |
453 | u32 original_first_length; | 454 | u32 original_first_length; |
454 | // u64 *wqe_fragment_address; | 455 | /* u64 *wqe_fragment_address; */ |
455 | /* first fragment (0) is used by copy buffer */ | 456 | /* first fragment (0) is used by copy buffer */ |
456 | u16 wqe_fragment_index=1; | 457 | u16 wqe_fragment_index=1; |
457 | u16 hoffset; | 458 | u16 hoffset; |
@@ -461,11 +462,12 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
461 | u32 old_head; | 462 | u32 old_head; |
462 | u32 wqe_misc; | 463 | u32 wqe_misc; |
463 | 464 | ||
464 | /* nes_debug(NES_DBG_NIC_TX, "%s Request to tx NIC packet length %u, headlen %u," | 465 | /* |
465 | " (%u frags), tso_size=%u\n", | 466 | * nes_debug(NES_DBG_NIC_TX, "%s Request to tx NIC packet length %u, headlen %u," |
466 | netdev->name, skb->len, skb_headlen(skb), | 467 | * " (%u frags), tso_size=%u\n", |
467 | skb_shinfo(skb)->nr_frags, skb_is_gso(skb)); | 468 | * netdev->name, skb->len, skb_headlen(skb), |
468 | */ | 469 | * skb_shinfo(skb)->nr_frags, skb_is_gso(skb)); |
470 | */ | ||
469 | 471 | ||
470 | if (!netif_carrier_ok(netdev)) | 472 | if (!netif_carrier_ok(netdev)) |
471 | return NETDEV_TX_OK; | 473 | return NETDEV_TX_OK; |
@@ -787,22 +789,20 @@ static int nes_netdev_set_mac_address(struct net_device *netdev, void *p) | |||
787 | int i; | 789 | int i; |
788 | u32 macaddr_low; | 790 | u32 macaddr_low; |
789 | u16 macaddr_high; | 791 | u16 macaddr_high; |
792 | DECLARE_MAC_BUF(mac); | ||
790 | 793 | ||
791 | if (!is_valid_ether_addr(mac_addr->sa_data)) | 794 | if (!is_valid_ether_addr(mac_addr->sa_data)) |
792 | return -EADDRNOTAVAIL; | 795 | return -EADDRNOTAVAIL; |
793 | 796 | ||
794 | memcpy(netdev->dev_addr, mac_addr->sa_data, netdev->addr_len); | 797 | memcpy(netdev->dev_addr, mac_addr->sa_data, netdev->addr_len); |
795 | printk(PFX "%s: Address length = %d, Address = %02X%02X%02X%02X%02X%02X..\n", | 798 | printk(PFX "%s: Address length = %d, Address = %s\n", |
796 | __func__, netdev->addr_len, | 799 | __func__, netdev->addr_len, print_mac(mac, mac_addr->sa_data)); |
797 | mac_addr->sa_data[0], mac_addr->sa_data[1], | 800 | macaddr_high = ((u16)netdev->dev_addr[0]) << 8; |
798 | mac_addr->sa_data[2], mac_addr->sa_data[3], | ||
799 | mac_addr->sa_data[4], mac_addr->sa_data[5]); | ||
800 | macaddr_high = ((u16)netdev->dev_addr[0]) << 8; | ||
801 | macaddr_high += (u16)netdev->dev_addr[1]; | 801 | macaddr_high += (u16)netdev->dev_addr[1]; |
802 | macaddr_low = ((u32)netdev->dev_addr[2]) << 24; | 802 | macaddr_low = ((u32)netdev->dev_addr[2]) << 24; |
803 | macaddr_low += ((u32)netdev->dev_addr[3]) << 16; | 803 | macaddr_low += ((u32)netdev->dev_addr[3]) << 16; |
804 | macaddr_low += ((u32)netdev->dev_addr[4]) << 8; | 804 | macaddr_low += ((u32)netdev->dev_addr[4]) << 8; |
805 | macaddr_low += (u32)netdev->dev_addr[5]; | 805 | macaddr_low += (u32)netdev->dev_addr[5]; |
806 | 806 | ||
807 | for (i = 0; i < NES_MAX_PORT_COUNT; i++) { | 807 | for (i = 0; i < NES_MAX_PORT_COUNT; i++) { |
808 | if (nesvnic->qp_nic_index[i] == 0xf) { | 808 | if (nesvnic->qp_nic_index[i] == 0xf) { |
@@ -878,17 +878,17 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) | |||
878 | if (mc_nic_index < 0) | 878 | if (mc_nic_index < 0) |
879 | mc_nic_index = nesvnic->nic_index; | 879 | mc_nic_index = nesvnic->nic_index; |
880 | if (multicast_addr) { | 880 | if (multicast_addr) { |
881 | nes_debug(NES_DBG_NIC_RX, "Assigning MC Address = %02X%02X%02X%02X%02X%02X to register 0x%04X nic_idx=%d\n", | 881 | DECLARE_MAC_BUF(mac); |
882 | multicast_addr->dmi_addr[0], multicast_addr->dmi_addr[1], | 882 | nes_debug(NES_DBG_NIC_RX, "Assigning MC Address %s to register 0x%04X nic_idx=%d\n", |
883 | multicast_addr->dmi_addr[2], multicast_addr->dmi_addr[3], | 883 | print_mac(mac, multicast_addr->dmi_addr), |
884 | multicast_addr->dmi_addr[4], multicast_addr->dmi_addr[5], | 884 | perfect_filter_register_address+(mc_index * 8), |
885 | perfect_filter_register_address+(mc_index * 8), mc_nic_index); | 885 | mc_nic_index); |
886 | macaddr_high = ((u16)multicast_addr->dmi_addr[0]) << 8; | 886 | macaddr_high = ((u16)multicast_addr->dmi_addr[0]) << 8; |
887 | macaddr_high += (u16)multicast_addr->dmi_addr[1]; | 887 | macaddr_high += (u16)multicast_addr->dmi_addr[1]; |
888 | macaddr_low = ((u32)multicast_addr->dmi_addr[2]) << 24; | 888 | macaddr_low = ((u32)multicast_addr->dmi_addr[2]) << 24; |
889 | macaddr_low += ((u32)multicast_addr->dmi_addr[3]) << 16; | 889 | macaddr_low += ((u32)multicast_addr->dmi_addr[3]) << 16; |
890 | macaddr_low += ((u32)multicast_addr->dmi_addr[4]) << 8; | 890 | macaddr_low += ((u32)multicast_addr->dmi_addr[4]) << 8; |
891 | macaddr_low += (u32)multicast_addr->dmi_addr[5]; | 891 | macaddr_low += (u32)multicast_addr->dmi_addr[5]; |
892 | nes_write_indexed(nesdev, | 892 | nes_write_indexed(nesdev, |
893 | perfect_filter_register_address+(mc_index * 8), | 893 | perfect_filter_register_address+(mc_index * 8), |
894 | macaddr_low); | 894 | macaddr_low); |
@@ -912,23 +912,23 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) | |||
912 | /** | 912 | /** |
913 | * nes_netdev_change_mtu | 913 | * nes_netdev_change_mtu |
914 | */ | 914 | */ |
915 | static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu) | 915 | static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu) |
916 | { | 916 | { |
917 | struct nes_vnic *nesvnic = netdev_priv(netdev); | 917 | struct nes_vnic *nesvnic = netdev_priv(netdev); |
918 | struct nes_device *nesdev = nesvnic->nesdev; | 918 | struct nes_device *nesdev = nesvnic->nesdev; |
919 | int ret = 0; | 919 | int ret = 0; |
920 | u8 jumbomode=0; | 920 | u8 jumbomode = 0; |
921 | 921 | ||
922 | if ((new_mtu < ETH_ZLEN) || (new_mtu > max_mtu)) | 922 | if ((new_mtu < ETH_ZLEN) || (new_mtu > max_mtu)) |
923 | return -EINVAL; | 923 | return -EINVAL; |
924 | 924 | ||
925 | netdev->mtu = new_mtu; | 925 | netdev->mtu = new_mtu; |
926 | nesvnic->max_frame_size = new_mtu + VLAN_ETH_HLEN; | 926 | nesvnic->max_frame_size = new_mtu + VLAN_ETH_HLEN; |
927 | 927 | ||
928 | if (netdev->mtu > 1500) { | 928 | if (netdev->mtu > 1500) { |
929 | jumbomode=1; | 929 | jumbomode=1; |
930 | } | 930 | } |
931 | nes_nic_init_timer_defaults(nesdev, jumbomode); | 931 | nes_nic_init_timer_defaults(nesdev, jumbomode); |
932 | 932 | ||
933 | if (netif_running(netdev)) { | 933 | if (netif_running(netdev)) { |
934 | nes_netdev_stop(netdev); | 934 | nes_netdev_stop(netdev); |
@@ -938,8 +938,7 @@ static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu) | |||
938 | return ret; | 938 | return ret; |
939 | } | 939 | } |
940 | 940 | ||
941 | #define NES_ETHTOOL_STAT_COUNT 55 | 941 | static const char nes_ethtool_stringset[][ETH_GSTRING_LEN] = { |
942 | static const char nes_ethtool_stringset[NES_ETHTOOL_STAT_COUNT][ETH_GSTRING_LEN] = { | ||
943 | "Link Change Interrupts", | 942 | "Link Change Interrupts", |
944 | "Linearized SKBs", | 943 | "Linearized SKBs", |
945 | "T/GSO Requests", | 944 | "T/GSO Requests", |
@@ -995,8 +994,12 @@ static const char nes_ethtool_stringset[NES_ETHTOOL_STAT_COUNT][ETH_GSTRING_LEN] | |||
995 | "CQ Depth 32", | 994 | "CQ Depth 32", |
996 | "CQ Depth 128", | 995 | "CQ Depth 128", |
997 | "CQ Depth 256", | 996 | "CQ Depth 256", |
997 | "LRO aggregated", | ||
998 | "LRO flushed", | ||
999 | "LRO no_desc", | ||
998 | }; | 1000 | }; |
999 | 1001 | ||
1002 | #define NES_ETHTOOL_STAT_COUNT ARRAY_SIZE(nes_ethtool_stringset) | ||
1000 | 1003 | ||
1001 | /** | 1004 | /** |
1002 | * nes_netdev_get_rx_csum | 1005 | * nes_netdev_get_rx_csum |
@@ -1191,6 +1194,9 @@ static void nes_netdev_get_ethtool_stats(struct net_device *netdev, | |||
1191 | target_stat_values[52] = int_mod_cq_depth_32; | 1194 | target_stat_values[52] = int_mod_cq_depth_32; |
1192 | target_stat_values[53] = int_mod_cq_depth_128; | 1195 | target_stat_values[53] = int_mod_cq_depth_128; |
1193 | target_stat_values[54] = int_mod_cq_depth_256; | 1196 | target_stat_values[54] = int_mod_cq_depth_256; |
1197 | target_stat_values[55] = nesvnic->lro_mgr.stats.aggregated; | ||
1198 | target_stat_values[56] = nesvnic->lro_mgr.stats.flushed; | ||
1199 | target_stat_values[57] = nesvnic->lro_mgr.stats.no_desc; | ||
1194 | 1200 | ||
1195 | } | 1201 | } |
1196 | 1202 | ||
@@ -1221,14 +1227,14 @@ static int nes_netdev_set_coalesce(struct net_device *netdev, | |||
1221 | struct ethtool_coalesce *et_coalesce) | 1227 | struct ethtool_coalesce *et_coalesce) |
1222 | { | 1228 | { |
1223 | struct nes_vnic *nesvnic = netdev_priv(netdev); | 1229 | struct nes_vnic *nesvnic = netdev_priv(netdev); |
1224 | struct nes_device *nesdev = nesvnic->nesdev; | 1230 | struct nes_device *nesdev = nesvnic->nesdev; |
1225 | struct nes_adapter *nesadapter = nesdev->nesadapter; | 1231 | struct nes_adapter *nesadapter = nesdev->nesadapter; |
1226 | struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer; | 1232 | struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer; |
1227 | unsigned long flags; | 1233 | unsigned long flags; |
1228 | 1234 | ||
1229 | spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags); | 1235 | spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags); |
1230 | if (et_coalesce->rx_max_coalesced_frames_low) { | 1236 | if (et_coalesce->rx_max_coalesced_frames_low) { |
1231 | shared_timer->threshold_low = et_coalesce->rx_max_coalesced_frames_low; | 1237 | shared_timer->threshold_low = et_coalesce->rx_max_coalesced_frames_low; |
1232 | } | 1238 | } |
1233 | if (et_coalesce->rx_max_coalesced_frames_irq) { | 1239 | if (et_coalesce->rx_max_coalesced_frames_irq) { |
1234 | shared_timer->threshold_target = et_coalesce->rx_max_coalesced_frames_irq; | 1240 | shared_timer->threshold_target = et_coalesce->rx_max_coalesced_frames_irq; |
@@ -1248,14 +1254,14 @@ static int nes_netdev_set_coalesce(struct net_device *netdev, | |||
1248 | nesadapter->et_rx_coalesce_usecs_irq = et_coalesce->rx_coalesce_usecs_irq; | 1254 | nesadapter->et_rx_coalesce_usecs_irq = et_coalesce->rx_coalesce_usecs_irq; |
1249 | if (et_coalesce->use_adaptive_rx_coalesce) { | 1255 | if (et_coalesce->use_adaptive_rx_coalesce) { |
1250 | nesadapter->et_use_adaptive_rx_coalesce = 1; | 1256 | nesadapter->et_use_adaptive_rx_coalesce = 1; |
1251 | nesadapter->timer_int_limit = NES_TIMER_INT_LIMIT_DYNAMIC; | 1257 | nesadapter->timer_int_limit = NES_TIMER_INT_LIMIT_DYNAMIC; |
1252 | nesadapter->et_rx_coalesce_usecs_irq = 0; | 1258 | nesadapter->et_rx_coalesce_usecs_irq = 0; |
1253 | if (et_coalesce->pkt_rate_low) { | 1259 | if (et_coalesce->pkt_rate_low) { |
1254 | nesadapter->et_pkt_rate_low = et_coalesce->pkt_rate_low; | 1260 | nesadapter->et_pkt_rate_low = et_coalesce->pkt_rate_low; |
1255 | } | 1261 | } |
1256 | } else { | 1262 | } else { |
1257 | nesadapter->et_use_adaptive_rx_coalesce = 0; | 1263 | nesadapter->et_use_adaptive_rx_coalesce = 0; |
1258 | nesadapter->timer_int_limit = NES_TIMER_INT_LIMIT; | 1264 | nesadapter->timer_int_limit = NES_TIMER_INT_LIMIT; |
1259 | if (nesadapter->et_rx_coalesce_usecs_irq) { | 1265 | if (nesadapter->et_rx_coalesce_usecs_irq) { |
1260 | nes_write32(nesdev->regs+NES_PERIODIC_CONTROL, | 1266 | nes_write32(nesdev->regs+NES_PERIODIC_CONTROL, |
1261 | 0x80000000 | ((u32)(nesadapter->et_rx_coalesce_usecs_irq*8))); | 1267 | 0x80000000 | ((u32)(nesadapter->et_rx_coalesce_usecs_irq*8))); |
@@ -1272,28 +1278,28 @@ static int nes_netdev_get_coalesce(struct net_device *netdev, | |||
1272 | struct ethtool_coalesce *et_coalesce) | 1278 | struct ethtool_coalesce *et_coalesce) |
1273 | { | 1279 | { |
1274 | struct nes_vnic *nesvnic = netdev_priv(netdev); | 1280 | struct nes_vnic *nesvnic = netdev_priv(netdev); |
1275 | struct nes_device *nesdev = nesvnic->nesdev; | 1281 | struct nes_device *nesdev = nesvnic->nesdev; |
1276 | struct nes_adapter *nesadapter = nesdev->nesadapter; | 1282 | struct nes_adapter *nesadapter = nesdev->nesadapter; |
1277 | struct ethtool_coalesce temp_et_coalesce; | 1283 | struct ethtool_coalesce temp_et_coalesce; |
1278 | struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer; | 1284 | struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer; |
1279 | unsigned long flags; | 1285 | unsigned long flags; |
1280 | 1286 | ||
1281 | memset(&temp_et_coalesce, 0, sizeof(temp_et_coalesce)); | 1287 | memset(&temp_et_coalesce, 0, sizeof(temp_et_coalesce)); |
1282 | temp_et_coalesce.rx_coalesce_usecs_irq = nesadapter->et_rx_coalesce_usecs_irq; | 1288 | temp_et_coalesce.rx_coalesce_usecs_irq = nesadapter->et_rx_coalesce_usecs_irq; |
1283 | temp_et_coalesce.use_adaptive_rx_coalesce = nesadapter->et_use_adaptive_rx_coalesce; | 1289 | temp_et_coalesce.use_adaptive_rx_coalesce = nesadapter->et_use_adaptive_rx_coalesce; |
1284 | temp_et_coalesce.rate_sample_interval = nesadapter->et_rate_sample_interval; | 1290 | temp_et_coalesce.rate_sample_interval = nesadapter->et_rate_sample_interval; |
1285 | temp_et_coalesce.pkt_rate_low = nesadapter->et_pkt_rate_low; | 1291 | temp_et_coalesce.pkt_rate_low = nesadapter->et_pkt_rate_low; |
1286 | spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags); | 1292 | spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags); |
1287 | temp_et_coalesce.rx_max_coalesced_frames_low = shared_timer->threshold_low; | 1293 | temp_et_coalesce.rx_max_coalesced_frames_low = shared_timer->threshold_low; |
1288 | temp_et_coalesce.rx_max_coalesced_frames_irq = shared_timer->threshold_target; | 1294 | temp_et_coalesce.rx_max_coalesced_frames_irq = shared_timer->threshold_target; |
1289 | temp_et_coalesce.rx_max_coalesced_frames_high = shared_timer->threshold_high; | 1295 | temp_et_coalesce.rx_max_coalesced_frames_high = shared_timer->threshold_high; |
1290 | temp_et_coalesce.rx_coalesce_usecs_low = shared_timer->timer_in_use_min; | 1296 | temp_et_coalesce.rx_coalesce_usecs_low = shared_timer->timer_in_use_min; |
1291 | temp_et_coalesce.rx_coalesce_usecs_high = shared_timer->timer_in_use_max; | 1297 | temp_et_coalesce.rx_coalesce_usecs_high = shared_timer->timer_in_use_max; |
1292 | if (nesadapter->et_use_adaptive_rx_coalesce) { | 1298 | if (nesadapter->et_use_adaptive_rx_coalesce) { |
1293 | temp_et_coalesce.rx_coalesce_usecs_irq = shared_timer->timer_in_use; | 1299 | temp_et_coalesce.rx_coalesce_usecs_irq = shared_timer->timer_in_use; |
1294 | } | 1300 | } |
1295 | spin_unlock_irqrestore(&nesadapter->periodic_timer_lock, flags); | 1301 | spin_unlock_irqrestore(&nesadapter->periodic_timer_lock, flags); |
1296 | memcpy(et_coalesce, &temp_et_coalesce, sizeof(*et_coalesce)); | 1302 | memcpy(et_coalesce, &temp_et_coalesce, sizeof(*et_coalesce)); |
1297 | return 0; | 1303 | return 0; |
1298 | } | 1304 | } |
1299 | 1305 | ||
@@ -1372,30 +1378,38 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd | |||
1372 | u16 phy_data; | 1378 | u16 phy_data; |
1373 | 1379 | ||
1374 | et_cmd->duplex = DUPLEX_FULL; | 1380 | et_cmd->duplex = DUPLEX_FULL; |
1375 | et_cmd->port = PORT_MII; | 1381 | et_cmd->port = PORT_MII; |
1382 | |||
1376 | if (nesadapter->OneG_Mode) { | 1383 | if (nesadapter->OneG_Mode) { |
1377 | et_cmd->supported = SUPPORTED_1000baseT_Full|SUPPORTED_Autoneg; | ||
1378 | et_cmd->advertising = ADVERTISED_1000baseT_Full|ADVERTISED_Autoneg; | ||
1379 | et_cmd->speed = SPEED_1000; | 1384 | et_cmd->speed = SPEED_1000; |
1380 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], | 1385 | if (nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) { |
1381 | &phy_data); | 1386 | et_cmd->supported = SUPPORTED_1000baseT_Full; |
1382 | if (phy_data&0x1000) { | 1387 | et_cmd->advertising = ADVERTISED_1000baseT_Full; |
1383 | et_cmd->autoneg = AUTONEG_ENABLE; | 1388 | et_cmd->autoneg = AUTONEG_DISABLE; |
1389 | et_cmd->transceiver = XCVR_INTERNAL; | ||
1390 | et_cmd->phy_address = nesdev->mac_index; | ||
1384 | } else { | 1391 | } else { |
1385 | et_cmd->autoneg = AUTONEG_DISABLE; | 1392 | et_cmd->supported = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg; |
1393 | et_cmd->advertising = ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg; | ||
1394 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], &phy_data); | ||
1395 | if (phy_data & 0x1000) | ||
1396 | et_cmd->autoneg = AUTONEG_ENABLE; | ||
1397 | else | ||
1398 | et_cmd->autoneg = AUTONEG_DISABLE; | ||
1399 | et_cmd->transceiver = XCVR_EXTERNAL; | ||
1400 | et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index]; | ||
1386 | } | 1401 | } |
1387 | et_cmd->transceiver = XCVR_EXTERNAL; | ||
1388 | et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index]; | ||
1389 | } else { | 1402 | } else { |
1390 | if (nesadapter->phy_type[nesvnic->logical_port] == NES_PHY_TYPE_IRIS) { | 1403 | if ((nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_IRIS) || |
1404 | (nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_ARGUS)) { | ||
1391 | et_cmd->transceiver = XCVR_EXTERNAL; | 1405 | et_cmd->transceiver = XCVR_EXTERNAL; |
1392 | et_cmd->port = PORT_FIBRE; | 1406 | et_cmd->port = PORT_FIBRE; |
1393 | et_cmd->supported = SUPPORTED_FIBRE; | 1407 | et_cmd->supported = SUPPORTED_FIBRE; |
1394 | et_cmd->advertising = ADVERTISED_FIBRE; | 1408 | et_cmd->advertising = ADVERTISED_FIBRE; |
1395 | et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index]; | 1409 | et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index]; |
1396 | } else { | 1410 | } else { |
1397 | et_cmd->transceiver = XCVR_INTERNAL; | 1411 | et_cmd->transceiver = XCVR_INTERNAL; |
1398 | et_cmd->supported = SUPPORTED_10000baseT_Full; | 1412 | et_cmd->supported = SUPPORTED_10000baseT_Full; |
1399 | et_cmd->advertising = ADVERTISED_10000baseT_Full; | 1413 | et_cmd->advertising = ADVERTISED_10000baseT_Full; |
1400 | et_cmd->phy_address = nesdev->mac_index; | 1414 | et_cmd->phy_address = nesdev->mac_index; |
1401 | } | 1415 | } |
@@ -1418,14 +1432,15 @@ static int nes_netdev_set_settings(struct net_device *netdev, struct ethtool_cmd | |||
1418 | struct nes_adapter *nesadapter = nesdev->nesadapter; | 1432 | struct nes_adapter *nesadapter = nesdev->nesadapter; |
1419 | u16 phy_data; | 1433 | u16 phy_data; |
1420 | 1434 | ||
1421 | if (nesadapter->OneG_Mode) { | 1435 | if ((nesadapter->OneG_Mode) && |
1436 | (nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_PUMA_1G)) { | ||
1422 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], | 1437 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], |
1423 | &phy_data); | 1438 | &phy_data); |
1424 | if (et_cmd->autoneg) { | 1439 | if (et_cmd->autoneg) { |
1425 | /* Turn on Full duplex, Autoneg, and restart autonegotiation */ | 1440 | /* Turn on Full duplex, Autoneg, and restart autonegotiation */ |
1426 | phy_data |= 0x1300; | 1441 | phy_data |= 0x1300; |
1427 | } else { | 1442 | } else { |
1428 | // Turn off autoneg | 1443 | /* Turn off autoneg */ |
1429 | phy_data &= ~0x1000; | 1444 | phy_data &= ~0x1000; |
1430 | } | 1445 | } |
1431 | nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], | 1446 | nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], |
@@ -1456,6 +1471,8 @@ static struct ethtool_ops nes_ethtool_ops = { | |||
1456 | .set_sg = ethtool_op_set_sg, | 1471 | .set_sg = ethtool_op_set_sg, |
1457 | .get_tso = ethtool_op_get_tso, | 1472 | .get_tso = ethtool_op_get_tso, |
1458 | .set_tso = ethtool_op_set_tso, | 1473 | .set_tso = ethtool_op_set_tso, |
1474 | .get_flags = ethtool_op_get_flags, | ||
1475 | .set_flags = ethtool_op_set_flags, | ||
1459 | }; | 1476 | }; |
1460 | 1477 | ||
1461 | 1478 | ||
@@ -1609,27 +1626,34 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
1609 | list_add_tail(&nesvnic->list, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]); | 1626 | list_add_tail(&nesvnic->list, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]); |
1610 | 1627 | ||
1611 | if ((nesdev->netdev_count == 0) && | 1628 | if ((nesdev->netdev_count == 0) && |
1612 | (PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index)) { | 1629 | ((PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index) || |
1613 | nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using register index 0x%04X\n", | 1630 | ((nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) && |
1614 | NES_IDX_PHY_PCS_CONTROL_STATUS0+(0x200*(nesvnic->logical_port&1))); | 1631 | (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) || |
1632 | ((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) { | ||
1633 | /* | ||
1634 | * nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using register index 0x%04X\n", | ||
1635 | * NES_IDX_PHY_PCS_CONTROL_STATUS0 + (0x200 * (nesvnic->logical_port & 1))); | ||
1636 | */ | ||
1615 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | 1637 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + |
1616 | (0x200*(nesvnic->logical_port&1))); | 1638 | (0x200 * (nesdev->mac_index & 1))); |
1617 | u32temp |= 0x00200000; | 1639 | if (nesdev->nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_PUMA_1G) { |
1618 | nes_write_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | 1640 | u32temp |= 0x00200000; |
1619 | (0x200*(nesvnic->logical_port&1)), u32temp); | 1641 | nes_write_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + |
1642 | (0x200 * (nesdev->mac_index & 1)), u32temp); | ||
1643 | } | ||
1644 | |||
1620 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | 1645 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + |
1621 | (0x200*(nesvnic->logical_port&1)) ); | 1646 | (0x200 * (nesdev->mac_index & 1))); |
1647 | |||
1622 | if ((u32temp&0x0f1f0000) == 0x0f0f0000) { | 1648 | if ((u32temp&0x0f1f0000) == 0x0f0f0000) { |
1623 | if (nesdev->nesadapter->phy_type[nesvnic->logical_port] == NES_PHY_TYPE_IRIS) { | 1649 | if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_IRIS) { |
1624 | nes_init_phy(nesdev); | 1650 | nes_init_phy(nesdev); |
1625 | nes_read_10G_phy_reg(nesdev, 1, | 1651 | nes_read_10G_phy_reg(nesdev, nesdev->nesadapter->phy_index[nesdev->mac_index], 1, 1); |
1626 | nesdev->nesadapter->phy_index[nesvnic->logical_port]); | ||
1627 | temp_phy_data = (u16)nes_read_indexed(nesdev, | 1652 | temp_phy_data = (u16)nes_read_indexed(nesdev, |
1628 | NES_IDX_MAC_MDIO_CONTROL); | 1653 | NES_IDX_MAC_MDIO_CONTROL); |
1629 | u32temp = 20; | 1654 | u32temp = 20; |
1630 | do { | 1655 | do { |
1631 | nes_read_10G_phy_reg(nesdev, 1, | 1656 | nes_read_10G_phy_reg(nesdev, nesdev->nesadapter->phy_index[nesdev->mac_index], 1, 1); |
1632 | nesdev->nesadapter->phy_index[nesvnic->logical_port]); | ||
1633 | phy_data = (u16)nes_read_indexed(nesdev, | 1657 | phy_data = (u16)nes_read_indexed(nesdev, |
1634 | NES_IDX_MAC_MDIO_CONTROL); | 1658 | NES_IDX_MAC_MDIO_CONTROL); |
1635 | if ((phy_data == temp_phy_data) || (!(--u32temp))) | 1659 | if ((phy_data == temp_phy_data) || (!(--u32temp))) |
@@ -1646,6 +1670,14 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
1646 | nes_debug(NES_DBG_INIT, "The Link is UP!!.\n"); | 1670 | nes_debug(NES_DBG_INIT, "The Link is UP!!.\n"); |
1647 | nesvnic->linkup = 1; | 1671 | nesvnic->linkup = 1; |
1648 | } | 1672 | } |
1673 | } else if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) { | ||
1674 | nes_debug(NES_DBG_INIT, "mac_index=%d, logical_port=%d, u32temp=0x%04X, PCI_FUNC=%d\n", | ||
1675 | nesdev->mac_index, nesvnic->logical_port, u32temp, PCI_FUNC(nesdev->pcidev->devfn)); | ||
1676 | if (((nesdev->mac_index < 2) && ((u32temp&0x01010000) == 0x01010000)) || | ||
1677 | ((nesdev->mac_index > 1) && ((u32temp&0x02020000) == 0x02020000))) { | ||
1678 | nes_debug(NES_DBG_INIT, "The Link is UP!!.\n"); | ||
1679 | nesvnic->linkup = 1; | ||
1680 | } | ||
1649 | } | 1681 | } |
1650 | /* clear the MAC interrupt status, assumes direct logical to physical mapping */ | 1682 | /* clear the MAC interrupt status, assumes direct logical to physical mapping */ |
1651 | u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); | 1683 | u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); |
diff --git a/drivers/infiniband/hw/nes/nes_utils.c b/drivers/infiniband/hw/nes/nes_utils.c index f9db07c2717d..fe83d1b2b177 100644 --- a/drivers/infiniband/hw/nes/nes_utils.c +++ b/drivers/infiniband/hw/nes/nes_utils.c | |||
@@ -444,15 +444,13 @@ void nes_read_1G_phy_reg(struct nes_device *nesdev, u8 phy_reg, u8 phy_addr, u16 | |||
444 | /** | 444 | /** |
445 | * nes_write_10G_phy_reg | 445 | * nes_write_10G_phy_reg |
446 | */ | 446 | */ |
447 | void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg, | 447 | void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_addr, u8 dev_addr, u16 phy_reg, |
448 | u8 phy_addr, u16 data) | 448 | u16 data) |
449 | { | 449 | { |
450 | u32 dev_addr; | ||
451 | u32 port_addr; | 450 | u32 port_addr; |
452 | u32 u32temp; | 451 | u32 u32temp; |
453 | u32 counter; | 452 | u32 counter; |
454 | 453 | ||
455 | dev_addr = 1; | ||
456 | port_addr = phy_addr; | 454 | port_addr = phy_addr; |
457 | 455 | ||
458 | /* set address */ | 456 | /* set address */ |
@@ -492,14 +490,12 @@ void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg, | |||
492 | * This routine only issues the read, the data must be read | 490 | * This routine only issues the read, the data must be read |
493 | * separately. | 491 | * separately. |
494 | */ | 492 | */ |
495 | void nes_read_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg, u8 phy_addr) | 493 | void nes_read_10G_phy_reg(struct nes_device *nesdev, u8 phy_addr, u8 dev_addr, u16 phy_reg) |
496 | { | 494 | { |
497 | u32 dev_addr; | ||
498 | u32 port_addr; | 495 | u32 port_addr; |
499 | u32 u32temp; | 496 | u32 u32temp; |
500 | u32 counter; | 497 | u32 counter; |
501 | 498 | ||
502 | dev_addr = 1; | ||
503 | port_addr = phy_addr; | 499 | port_addr = phy_addr; |
504 | 500 | ||
505 | /* set address */ | 501 | /* set address */ |
@@ -660,7 +656,9 @@ int nes_arp_table(struct nes_device *nesdev, u32 ip_addr, u8 *mac_addr, u32 acti | |||
660 | 656 | ||
661 | /* DELETE or RESOLVE */ | 657 | /* DELETE or RESOLVE */ |
662 | if (arp_index == nesadapter->arp_table_size) { | 658 | if (arp_index == nesadapter->arp_table_size) { |
663 | nes_debug(NES_DBG_NETDEV, "mac address not in ARP table - cannot delete or resolve\n"); | 659 | nes_debug(NES_DBG_NETDEV, "MAC for " NIPQUAD_FMT " not in ARP table - cannot %s\n", |
660 | HIPQUAD(ip_addr), | ||
661 | action == NES_ARP_RESOLVE ? "resolve" : "delete"); | ||
664 | return -1; | 662 | return -1; |
665 | } | 663 | } |
666 | 664 | ||
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index f9a5d4390892..99b3c4ae86eb 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c | |||
@@ -1266,7 +1266,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, | |||
1266 | sq_size = init_attr->cap.max_send_wr; | 1266 | sq_size = init_attr->cap.max_send_wr; |
1267 | rq_size = init_attr->cap.max_recv_wr; | 1267 | rq_size = init_attr->cap.max_recv_wr; |
1268 | 1268 | ||
1269 | // check if the encoded sizes are OK or not... | 1269 | /* check if the encoded sizes are OK or not... */ |
1270 | sq_encoded_size = nes_get_encoded_size(&sq_size); | 1270 | sq_encoded_size = nes_get_encoded_size(&sq_size); |
1271 | rq_encoded_size = nes_get_encoded_size(&rq_size); | 1271 | rq_encoded_size = nes_get_encoded_size(&rq_size); |
1272 | 1272 | ||
@@ -1976,7 +1976,7 @@ static int nes_destroy_cq(struct ib_cq *ib_cq) | |||
1976 | 1976 | ||
1977 | if (nescq->cq_mem_size) | 1977 | if (nescq->cq_mem_size) |
1978 | pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, | 1978 | pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, |
1979 | (void *)nescq->hw_cq.cq_vbase, nescq->hw_cq.cq_pbase); | 1979 | nescq->hw_cq.cq_vbase, nescq->hw_cq.cq_pbase); |
1980 | kfree(nescq); | 1980 | kfree(nescq); |
1981 | 1981 | ||
1982 | return ret; | 1982 | return ret; |
@@ -2377,7 +2377,7 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, | |||
2377 | u8 single_page = 1; | 2377 | u8 single_page = 1; |
2378 | u8 stag_key; | 2378 | u8 stag_key; |
2379 | 2379 | ||
2380 | region = ib_umem_get(pd->uobject->context, start, length, acc); | 2380 | region = ib_umem_get(pd->uobject->context, start, length, acc, 0); |
2381 | if (IS_ERR(region)) { | 2381 | if (IS_ERR(region)) { |
2382 | return (struct ib_mr *)region; | 2382 | return (struct ib_mr *)region; |
2383 | } | 2383 | } |
@@ -3610,6 +3610,12 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) | |||
3610 | while (cqe_count < num_entries) { | 3610 | while (cqe_count < num_entries) { |
3611 | if (le32_to_cpu(nescq->hw_cq.cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX]) & | 3611 | if (le32_to_cpu(nescq->hw_cq.cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX]) & |
3612 | NES_CQE_VALID) { | 3612 | NES_CQE_VALID) { |
3613 | /* | ||
3614 | * Make sure we read CQ entry contents *after* | ||
3615 | * we've checked the valid bit. | ||
3616 | */ | ||
3617 | rmb(); | ||
3618 | |||
3613 | cqe = nescq->hw_cq.cq_vbase[head]; | 3619 | cqe = nescq->hw_cq.cq_vbase[head]; |
3614 | nescq->hw_cq.cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX] = 0; | 3620 | nescq->hw_cq.cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX] = 0; |
3615 | u32temp = le32_to_cpu(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]); | 3621 | u32temp = le32_to_cpu(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 73b2b176ad0e..ca126fc2b853 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -56,11 +56,11 @@ | |||
56 | /* constants */ | 56 | /* constants */ |
57 | 57 | ||
58 | enum { | 58 | enum { |
59 | IPOIB_PACKET_SIZE = 2048, | ||
60 | IPOIB_BUF_SIZE = IPOIB_PACKET_SIZE + IB_GRH_BYTES, | ||
61 | |||
62 | IPOIB_ENCAP_LEN = 4, | 59 | IPOIB_ENCAP_LEN = 4, |
63 | 60 | ||
61 | IPOIB_UD_HEAD_SIZE = IB_GRH_BYTES + IPOIB_ENCAP_LEN, | ||
62 | IPOIB_UD_RX_SG = 2, /* max buffer needed for 4K mtu */ | ||
63 | |||
64 | IPOIB_CM_MTU = 0x10000 - 0x10, /* padding to align header to 16 */ | 64 | IPOIB_CM_MTU = 0x10000 - 0x10, /* padding to align header to 16 */ |
65 | IPOIB_CM_BUF_SIZE = IPOIB_CM_MTU + IPOIB_ENCAP_LEN, | 65 | IPOIB_CM_BUF_SIZE = IPOIB_CM_MTU + IPOIB_ENCAP_LEN, |
66 | IPOIB_CM_HEAD_SIZE = IPOIB_CM_BUF_SIZE % PAGE_SIZE, | 66 | IPOIB_CM_HEAD_SIZE = IPOIB_CM_BUF_SIZE % PAGE_SIZE, |
@@ -95,6 +95,8 @@ enum { | |||
95 | IPOIB_MCAST_FLAG_SENDONLY = 1, | 95 | IPOIB_MCAST_FLAG_SENDONLY = 1, |
96 | IPOIB_MCAST_FLAG_BUSY = 2, /* joining or already joined */ | 96 | IPOIB_MCAST_FLAG_BUSY = 2, /* joining or already joined */ |
97 | IPOIB_MCAST_FLAG_ATTACHED = 3, | 97 | IPOIB_MCAST_FLAG_ATTACHED = 3, |
98 | |||
99 | MAX_SEND_CQE = 16, | ||
98 | }; | 100 | }; |
99 | 101 | ||
100 | #define IPOIB_OP_RECV (1ul << 31) | 102 | #define IPOIB_OP_RECV (1ul << 31) |
@@ -139,7 +141,7 @@ struct ipoib_mcast { | |||
139 | 141 | ||
140 | struct ipoib_rx_buf { | 142 | struct ipoib_rx_buf { |
141 | struct sk_buff *skb; | 143 | struct sk_buff *skb; |
142 | u64 mapping; | 144 | u64 mapping[IPOIB_UD_RX_SG]; |
143 | }; | 145 | }; |
144 | 146 | ||
145 | struct ipoib_tx_buf { | 147 | struct ipoib_tx_buf { |
@@ -285,7 +287,8 @@ struct ipoib_dev_priv { | |||
285 | u16 pkey_index; | 287 | u16 pkey_index; |
286 | struct ib_pd *pd; | 288 | struct ib_pd *pd; |
287 | struct ib_mr *mr; | 289 | struct ib_mr *mr; |
288 | struct ib_cq *cq; | 290 | struct ib_cq *recv_cq; |
291 | struct ib_cq *send_cq; | ||
289 | struct ib_qp *qp; | 292 | struct ib_qp *qp; |
290 | u32 qkey; | 293 | u32 qkey; |
291 | 294 | ||
@@ -294,6 +297,7 @@ struct ipoib_dev_priv { | |||
294 | 297 | ||
295 | unsigned int admin_mtu; | 298 | unsigned int admin_mtu; |
296 | unsigned int mcast_mtu; | 299 | unsigned int mcast_mtu; |
300 | unsigned int max_ib_mtu; | ||
297 | 301 | ||
298 | struct ipoib_rx_buf *rx_ring; | 302 | struct ipoib_rx_buf *rx_ring; |
299 | 303 | ||
@@ -304,6 +308,10 @@ struct ipoib_dev_priv { | |||
304 | struct ib_sge tx_sge[MAX_SKB_FRAGS + 1]; | 308 | struct ib_sge tx_sge[MAX_SKB_FRAGS + 1]; |
305 | struct ib_send_wr tx_wr; | 309 | struct ib_send_wr tx_wr; |
306 | unsigned tx_outstanding; | 310 | unsigned tx_outstanding; |
311 | struct ib_wc send_wc[MAX_SEND_CQE]; | ||
312 | |||
313 | struct ib_recv_wr rx_wr; | ||
314 | struct ib_sge rx_sge[IPOIB_UD_RX_SG]; | ||
307 | 315 | ||
308 | struct ib_wc ibwc[IPOIB_NUM_WC]; | 316 | struct ib_wc ibwc[IPOIB_NUM_WC]; |
309 | 317 | ||
@@ -326,6 +334,7 @@ struct ipoib_dev_priv { | |||
326 | #endif | 334 | #endif |
327 | int hca_caps; | 335 | int hca_caps; |
328 | struct ipoib_ethtool_st ethtool; | 336 | struct ipoib_ethtool_st ethtool; |
337 | struct timer_list poll_timer; | ||
329 | }; | 338 | }; |
330 | 339 | ||
331 | struct ipoib_ah { | 340 | struct ipoib_ah { |
@@ -366,6 +375,14 @@ struct ipoib_neigh { | |||
366 | struct list_head list; | 375 | struct list_head list; |
367 | }; | 376 | }; |
368 | 377 | ||
378 | #define IPOIB_UD_MTU(ib_mtu) (ib_mtu - IPOIB_ENCAP_LEN) | ||
379 | #define IPOIB_UD_BUF_SIZE(ib_mtu) (ib_mtu + IB_GRH_BYTES) | ||
380 | |||
381 | static inline int ipoib_ud_need_sg(unsigned int ib_mtu) | ||
382 | { | ||
383 | return IPOIB_UD_BUF_SIZE(ib_mtu) > PAGE_SIZE; | ||
384 | } | ||
385 | |||
369 | /* | 386 | /* |
370 | * We stash a pointer to our private neighbour information after our | 387 | * We stash a pointer to our private neighbour information after our |
371 | * hardware address in neigh->ha. The ALIGN() expression here makes | 388 | * hardware address in neigh->ha. The ALIGN() expression here makes |
@@ -388,6 +405,7 @@ extern struct workqueue_struct *ipoib_workqueue; | |||
388 | 405 | ||
389 | int ipoib_poll(struct napi_struct *napi, int budget); | 406 | int ipoib_poll(struct napi_struct *napi, int budget); |
390 | void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr); | 407 | void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr); |
408 | void ipoib_send_comp_handler(struct ib_cq *cq, void *dev_ptr); | ||
391 | 409 | ||
392 | struct ipoib_ah *ipoib_create_ah(struct net_device *dev, | 410 | struct ipoib_ah *ipoib_create_ah(struct net_device *dev, |
393 | struct ib_pd *pd, struct ib_ah_attr *attr); | 411 | struct ib_pd *pd, struct ib_ah_attr *attr); |
@@ -650,7 +668,6 @@ static inline int ipoib_register_debugfs(void) { return 0; } | |||
650 | static inline void ipoib_unregister_debugfs(void) { } | 668 | static inline void ipoib_unregister_debugfs(void) { } |
651 | #endif | 669 | #endif |
652 | 670 | ||
653 | |||
654 | #define ipoib_printk(level, priv, format, arg...) \ | 671 | #define ipoib_printk(level, priv, format, arg...) \ |
655 | printk(level "%s: " format, ((struct ipoib_dev_priv *) priv)->dev->name , ## arg) | 672 | printk(level "%s: " format, ((struct ipoib_dev_priv *) priv)->dev->name , ## arg) |
656 | #define ipoib_warn(priv, format, arg...) \ | 673 | #define ipoib_warn(priv, format, arg...) \ |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 9db7b0bd9134..97e67d36378f 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |||
@@ -249,8 +249,8 @@ static struct ib_qp *ipoib_cm_create_rx_qp(struct net_device *dev, | |||
249 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 249 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
250 | struct ib_qp_init_attr attr = { | 250 | struct ib_qp_init_attr attr = { |
251 | .event_handler = ipoib_cm_rx_event_handler, | 251 | .event_handler = ipoib_cm_rx_event_handler, |
252 | .send_cq = priv->cq, /* For drain WR */ | 252 | .send_cq = priv->recv_cq, /* For drain WR */ |
253 | .recv_cq = priv->cq, | 253 | .recv_cq = priv->recv_cq, |
254 | .srq = priv->cm.srq, | 254 | .srq = priv->cm.srq, |
255 | .cap.max_send_wr = 1, /* For drain WR */ | 255 | .cap.max_send_wr = 1, /* For drain WR */ |
256 | .cap.max_send_sge = 1, /* FIXME: 0 Seems not to work */ | 256 | .cap.max_send_sge = 1, /* FIXME: 0 Seems not to work */ |
@@ -951,8 +951,8 @@ static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ipoib_ | |||
951 | { | 951 | { |
952 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 952 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
953 | struct ib_qp_init_attr attr = { | 953 | struct ib_qp_init_attr attr = { |
954 | .send_cq = priv->cq, | 954 | .send_cq = priv->recv_cq, |
955 | .recv_cq = priv->cq, | 955 | .recv_cq = priv->recv_cq, |
956 | .srq = priv->cm.srq, | 956 | .srq = priv->cm.srq, |
957 | .cap.max_send_wr = ipoib_sendq_size, | 957 | .cap.max_send_wr = ipoib_sendq_size, |
958 | .cap.max_send_sge = 1, | 958 | .cap.max_send_sge = 1, |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c index 9a47428366c9..10279b79c44d 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c | |||
@@ -71,7 +71,7 @@ static int ipoib_set_coalesce(struct net_device *dev, | |||
71 | coal->rx_max_coalesced_frames > 0xffff) | 71 | coal->rx_max_coalesced_frames > 0xffff) |
72 | return -EINVAL; | 72 | return -EINVAL; |
73 | 73 | ||
74 | ret = ib_modify_cq(priv->cq, coal->rx_max_coalesced_frames, | 74 | ret = ib_modify_cq(priv->recv_cq, coal->rx_max_coalesced_frames, |
75 | coal->rx_coalesce_usecs); | 75 | coal->rx_coalesce_usecs); |
76 | if (ret && ret != -ENOSYS) { | 76 | if (ret && ret != -ENOSYS) { |
77 | ipoib_warn(priv, "failed modifying CQ (%d)\n", ret); | 77 | ipoib_warn(priv, "failed modifying CQ (%d)\n", ret); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 0205eb7c1bd3..f429bce24c20 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
@@ -89,28 +89,59 @@ void ipoib_free_ah(struct kref *kref) | |||
89 | spin_unlock_irqrestore(&priv->lock, flags); | 89 | spin_unlock_irqrestore(&priv->lock, flags); |
90 | } | 90 | } |
91 | 91 | ||
92 | static void ipoib_ud_dma_unmap_rx(struct ipoib_dev_priv *priv, | ||
93 | u64 mapping[IPOIB_UD_RX_SG]) | ||
94 | { | ||
95 | if (ipoib_ud_need_sg(priv->max_ib_mtu)) { | ||
96 | ib_dma_unmap_single(priv->ca, mapping[0], IPOIB_UD_HEAD_SIZE, | ||
97 | DMA_FROM_DEVICE); | ||
98 | ib_dma_unmap_page(priv->ca, mapping[1], PAGE_SIZE, | ||
99 | DMA_FROM_DEVICE); | ||
100 | } else | ||
101 | ib_dma_unmap_single(priv->ca, mapping[0], | ||
102 | IPOIB_UD_BUF_SIZE(priv->max_ib_mtu), | ||
103 | DMA_FROM_DEVICE); | ||
104 | } | ||
105 | |||
106 | static void ipoib_ud_skb_put_frags(struct ipoib_dev_priv *priv, | ||
107 | struct sk_buff *skb, | ||
108 | unsigned int length) | ||
109 | { | ||
110 | if (ipoib_ud_need_sg(priv->max_ib_mtu)) { | ||
111 | skb_frag_t *frag = &skb_shinfo(skb)->frags[0]; | ||
112 | unsigned int size; | ||
113 | /* | ||
114 | * There is only two buffers needed for max_payload = 4K, | ||
115 | * first buf size is IPOIB_UD_HEAD_SIZE | ||
116 | */ | ||
117 | skb->tail += IPOIB_UD_HEAD_SIZE; | ||
118 | skb->len += length; | ||
119 | |||
120 | size = length - IPOIB_UD_HEAD_SIZE; | ||
121 | |||
122 | frag->size = size; | ||
123 | skb->data_len += size; | ||
124 | skb->truesize += size; | ||
125 | } else | ||
126 | skb_put(skb, length); | ||
127 | |||
128 | } | ||
129 | |||
92 | static int ipoib_ib_post_receive(struct net_device *dev, int id) | 130 | static int ipoib_ib_post_receive(struct net_device *dev, int id) |
93 | { | 131 | { |
94 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 132 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
95 | struct ib_sge list; | ||
96 | struct ib_recv_wr param; | ||
97 | struct ib_recv_wr *bad_wr; | 133 | struct ib_recv_wr *bad_wr; |
98 | int ret; | 134 | int ret; |
99 | 135 | ||
100 | list.addr = priv->rx_ring[id].mapping; | 136 | priv->rx_wr.wr_id = id | IPOIB_OP_RECV; |
101 | list.length = IPOIB_BUF_SIZE; | 137 | priv->rx_sge[0].addr = priv->rx_ring[id].mapping[0]; |
102 | list.lkey = priv->mr->lkey; | 138 | priv->rx_sge[1].addr = priv->rx_ring[id].mapping[1]; |
103 | 139 | ||
104 | param.next = NULL; | ||
105 | param.wr_id = id | IPOIB_OP_RECV; | ||
106 | param.sg_list = &list; | ||
107 | param.num_sge = 1; | ||
108 | 140 | ||
109 | ret = ib_post_recv(priv->qp, ¶m, &bad_wr); | 141 | ret = ib_post_recv(priv->qp, &priv->rx_wr, &bad_wr); |
110 | if (unlikely(ret)) { | 142 | if (unlikely(ret)) { |
111 | ipoib_warn(priv, "receive failed for buf %d (%d)\n", id, ret); | 143 | ipoib_warn(priv, "receive failed for buf %d (%d)\n", id, ret); |
112 | ib_dma_unmap_single(priv->ca, priv->rx_ring[id].mapping, | 144 | ipoib_ud_dma_unmap_rx(priv, priv->rx_ring[id].mapping); |
113 | IPOIB_BUF_SIZE, DMA_FROM_DEVICE); | ||
114 | dev_kfree_skb_any(priv->rx_ring[id].skb); | 145 | dev_kfree_skb_any(priv->rx_ring[id].skb); |
115 | priv->rx_ring[id].skb = NULL; | 146 | priv->rx_ring[id].skb = NULL; |
116 | } | 147 | } |
@@ -118,15 +149,21 @@ static int ipoib_ib_post_receive(struct net_device *dev, int id) | |||
118 | return ret; | 149 | return ret; |
119 | } | 150 | } |
120 | 151 | ||
121 | static int ipoib_alloc_rx_skb(struct net_device *dev, int id) | 152 | static struct sk_buff *ipoib_alloc_rx_skb(struct net_device *dev, int id) |
122 | { | 153 | { |
123 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 154 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
124 | struct sk_buff *skb; | 155 | struct sk_buff *skb; |
125 | u64 addr; | 156 | int buf_size; |
157 | u64 *mapping; | ||
126 | 158 | ||
127 | skb = dev_alloc_skb(IPOIB_BUF_SIZE + 4); | 159 | if (ipoib_ud_need_sg(priv->max_ib_mtu)) |
128 | if (!skb) | 160 | buf_size = IPOIB_UD_HEAD_SIZE; |
129 | return -ENOMEM; | 161 | else |
162 | buf_size = IPOIB_UD_BUF_SIZE(priv->max_ib_mtu); | ||
163 | |||
164 | skb = dev_alloc_skb(buf_size + 4); | ||
165 | if (unlikely(!skb)) | ||
166 | return NULL; | ||
130 | 167 | ||
131 | /* | 168 | /* |
132 | * IB will leave a 40 byte gap for a GRH and IPoIB adds a 4 byte | 169 | * IB will leave a 40 byte gap for a GRH and IPoIB adds a 4 byte |
@@ -135,17 +172,32 @@ static int ipoib_alloc_rx_skb(struct net_device *dev, int id) | |||
135 | */ | 172 | */ |
136 | skb_reserve(skb, 4); | 173 | skb_reserve(skb, 4); |
137 | 174 | ||
138 | addr = ib_dma_map_single(priv->ca, skb->data, IPOIB_BUF_SIZE, | 175 | mapping = priv->rx_ring[id].mapping; |
139 | DMA_FROM_DEVICE); | 176 | mapping[0] = ib_dma_map_single(priv->ca, skb->data, buf_size, |
140 | if (unlikely(ib_dma_mapping_error(priv->ca, addr))) { | 177 | DMA_FROM_DEVICE); |
141 | dev_kfree_skb_any(skb); | 178 | if (unlikely(ib_dma_mapping_error(priv->ca, mapping[0]))) |
142 | return -EIO; | 179 | goto error; |
180 | |||
181 | if (ipoib_ud_need_sg(priv->max_ib_mtu)) { | ||
182 | struct page *page = alloc_page(GFP_ATOMIC); | ||
183 | if (!page) | ||
184 | goto partial_error; | ||
185 | skb_fill_page_desc(skb, 0, page, 0, PAGE_SIZE); | ||
186 | mapping[1] = | ||
187 | ib_dma_map_page(priv->ca, skb_shinfo(skb)->frags[0].page, | ||
188 | 0, PAGE_SIZE, DMA_FROM_DEVICE); | ||
189 | if (unlikely(ib_dma_mapping_error(priv->ca, mapping[1]))) | ||
190 | goto partial_error; | ||
143 | } | 191 | } |
144 | 192 | ||
145 | priv->rx_ring[id].skb = skb; | 193 | priv->rx_ring[id].skb = skb; |
146 | priv->rx_ring[id].mapping = addr; | 194 | return skb; |
147 | 195 | ||
148 | return 0; | 196 | partial_error: |
197 | ib_dma_unmap_single(priv->ca, mapping[0], buf_size, DMA_FROM_DEVICE); | ||
198 | error: | ||
199 | dev_kfree_skb_any(skb); | ||
200 | return NULL; | ||
149 | } | 201 | } |
150 | 202 | ||
151 | static int ipoib_ib_post_receives(struct net_device *dev) | 203 | static int ipoib_ib_post_receives(struct net_device *dev) |
@@ -154,7 +206,7 @@ static int ipoib_ib_post_receives(struct net_device *dev) | |||
154 | int i; | 206 | int i; |
155 | 207 | ||
156 | for (i = 0; i < ipoib_recvq_size; ++i) { | 208 | for (i = 0; i < ipoib_recvq_size; ++i) { |
157 | if (ipoib_alloc_rx_skb(dev, i)) { | 209 | if (!ipoib_alloc_rx_skb(dev, i)) { |
158 | ipoib_warn(priv, "failed to allocate receive buffer %d\n", i); | 210 | ipoib_warn(priv, "failed to allocate receive buffer %d\n", i); |
159 | return -ENOMEM; | 211 | return -ENOMEM; |
160 | } | 212 | } |
@@ -172,7 +224,7 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) | |||
172 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 224 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
173 | unsigned int wr_id = wc->wr_id & ~IPOIB_OP_RECV; | 225 | unsigned int wr_id = wc->wr_id & ~IPOIB_OP_RECV; |
174 | struct sk_buff *skb; | 226 | struct sk_buff *skb; |
175 | u64 addr; | 227 | u64 mapping[IPOIB_UD_RX_SG]; |
176 | 228 | ||
177 | ipoib_dbg_data(priv, "recv completion: id %d, status: %d\n", | 229 | ipoib_dbg_data(priv, "recv completion: id %d, status: %d\n", |
178 | wr_id, wc->status); | 230 | wr_id, wc->status); |
@@ -184,15 +236,13 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) | |||
184 | } | 236 | } |
185 | 237 | ||
186 | skb = priv->rx_ring[wr_id].skb; | 238 | skb = priv->rx_ring[wr_id].skb; |
187 | addr = priv->rx_ring[wr_id].mapping; | ||
188 | 239 | ||
189 | if (unlikely(wc->status != IB_WC_SUCCESS)) { | 240 | if (unlikely(wc->status != IB_WC_SUCCESS)) { |
190 | if (wc->status != IB_WC_WR_FLUSH_ERR) | 241 | if (wc->status != IB_WC_WR_FLUSH_ERR) |
191 | ipoib_warn(priv, "failed recv event " | 242 | ipoib_warn(priv, "failed recv event " |
192 | "(status=%d, wrid=%d vend_err %x)\n", | 243 | "(status=%d, wrid=%d vend_err %x)\n", |
193 | wc->status, wr_id, wc->vendor_err); | 244 | wc->status, wr_id, wc->vendor_err); |
194 | ib_dma_unmap_single(priv->ca, addr, | 245 | ipoib_ud_dma_unmap_rx(priv, priv->rx_ring[wr_id].mapping); |
195 | IPOIB_BUF_SIZE, DMA_FROM_DEVICE); | ||
196 | dev_kfree_skb_any(skb); | 246 | dev_kfree_skb_any(skb); |
197 | priv->rx_ring[wr_id].skb = NULL; | 247 | priv->rx_ring[wr_id].skb = NULL; |
198 | return; | 248 | return; |
@@ -205,11 +255,14 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) | |||
205 | if (wc->slid == priv->local_lid && wc->src_qp == priv->qp->qp_num) | 255 | if (wc->slid == priv->local_lid && wc->src_qp == priv->qp->qp_num) |
206 | goto repost; | 256 | goto repost; |
207 | 257 | ||
258 | memcpy(mapping, priv->rx_ring[wr_id].mapping, | ||
259 | IPOIB_UD_RX_SG * sizeof *mapping); | ||
260 | |||
208 | /* | 261 | /* |
209 | * If we can't allocate a new RX buffer, dump | 262 | * If we can't allocate a new RX buffer, dump |
210 | * this packet and reuse the old buffer. | 263 | * this packet and reuse the old buffer. |
211 | */ | 264 | */ |
212 | if (unlikely(ipoib_alloc_rx_skb(dev, wr_id))) { | 265 | if (unlikely(!ipoib_alloc_rx_skb(dev, wr_id))) { |
213 | ++dev->stats.rx_dropped; | 266 | ++dev->stats.rx_dropped; |
214 | goto repost; | 267 | goto repost; |
215 | } | 268 | } |
@@ -217,9 +270,9 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) | |||
217 | ipoib_dbg_data(priv, "received %d bytes, SLID 0x%04x\n", | 270 | ipoib_dbg_data(priv, "received %d bytes, SLID 0x%04x\n", |
218 | wc->byte_len, wc->slid); | 271 | wc->byte_len, wc->slid); |
219 | 272 | ||
220 | ib_dma_unmap_single(priv->ca, addr, IPOIB_BUF_SIZE, DMA_FROM_DEVICE); | 273 | ipoib_ud_dma_unmap_rx(priv, mapping); |
274 | ipoib_ud_skb_put_frags(priv, skb, wc->byte_len); | ||
221 | 275 | ||
222 | skb_put(skb, wc->byte_len); | ||
223 | skb_pull(skb, IB_GRH_BYTES); | 276 | skb_pull(skb, IB_GRH_BYTES); |
224 | 277 | ||
225 | skb->protocol = ((struct ipoib_header *) skb->data)->proto; | 278 | skb->protocol = ((struct ipoib_header *) skb->data)->proto; |
@@ -311,7 +364,6 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) | |||
311 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 364 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
312 | unsigned int wr_id = wc->wr_id; | 365 | unsigned int wr_id = wc->wr_id; |
313 | struct ipoib_tx_buf *tx_req; | 366 | struct ipoib_tx_buf *tx_req; |
314 | unsigned long flags; | ||
315 | 367 | ||
316 | ipoib_dbg_data(priv, "send completion: id %d, status: %d\n", | 368 | ipoib_dbg_data(priv, "send completion: id %d, status: %d\n", |
317 | wr_id, wc->status); | 369 | wr_id, wc->status); |
@@ -331,13 +383,11 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) | |||
331 | 383 | ||
332 | dev_kfree_skb_any(tx_req->skb); | 384 | dev_kfree_skb_any(tx_req->skb); |
333 | 385 | ||
334 | spin_lock_irqsave(&priv->tx_lock, flags); | ||
335 | ++priv->tx_tail; | 386 | ++priv->tx_tail; |
336 | if (unlikely(--priv->tx_outstanding == ipoib_sendq_size >> 1) && | 387 | if (unlikely(--priv->tx_outstanding == ipoib_sendq_size >> 1) && |
337 | netif_queue_stopped(dev) && | 388 | netif_queue_stopped(dev) && |
338 | test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) | 389 | test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) |
339 | netif_wake_queue(dev); | 390 | netif_wake_queue(dev); |
340 | spin_unlock_irqrestore(&priv->tx_lock, flags); | ||
341 | 391 | ||
342 | if (wc->status != IB_WC_SUCCESS && | 392 | if (wc->status != IB_WC_SUCCESS && |
343 | wc->status != IB_WC_WR_FLUSH_ERR) | 393 | wc->status != IB_WC_WR_FLUSH_ERR) |
@@ -346,6 +396,17 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) | |||
346 | wc->status, wr_id, wc->vendor_err); | 396 | wc->status, wr_id, wc->vendor_err); |
347 | } | 397 | } |
348 | 398 | ||
399 | static int poll_tx(struct ipoib_dev_priv *priv) | ||
400 | { | ||
401 | int n, i; | ||
402 | |||
403 | n = ib_poll_cq(priv->send_cq, MAX_SEND_CQE, priv->send_wc); | ||
404 | for (i = 0; i < n; ++i) | ||
405 | ipoib_ib_handle_tx_wc(priv->dev, priv->send_wc + i); | ||
406 | |||
407 | return n == MAX_SEND_CQE; | ||
408 | } | ||
409 | |||
349 | int ipoib_poll(struct napi_struct *napi, int budget) | 410 | int ipoib_poll(struct napi_struct *napi, int budget) |
350 | { | 411 | { |
351 | struct ipoib_dev_priv *priv = container_of(napi, struct ipoib_dev_priv, napi); | 412 | struct ipoib_dev_priv *priv = container_of(napi, struct ipoib_dev_priv, napi); |
@@ -361,7 +422,7 @@ poll_more: | |||
361 | int max = (budget - done); | 422 | int max = (budget - done); |
362 | 423 | ||
363 | t = min(IPOIB_NUM_WC, max); | 424 | t = min(IPOIB_NUM_WC, max); |
364 | n = ib_poll_cq(priv->cq, t, priv->ibwc); | 425 | n = ib_poll_cq(priv->recv_cq, t, priv->ibwc); |
365 | 426 | ||
366 | for (i = 0; i < n; i++) { | 427 | for (i = 0; i < n; i++) { |
367 | struct ib_wc *wc = priv->ibwc + i; | 428 | struct ib_wc *wc = priv->ibwc + i; |
@@ -372,12 +433,8 @@ poll_more: | |||
372 | ipoib_cm_handle_rx_wc(dev, wc); | 433 | ipoib_cm_handle_rx_wc(dev, wc); |
373 | else | 434 | else |
374 | ipoib_ib_handle_rx_wc(dev, wc); | 435 | ipoib_ib_handle_rx_wc(dev, wc); |
375 | } else { | 436 | } else |
376 | if (wc->wr_id & IPOIB_OP_CM) | 437 | ipoib_cm_handle_tx_wc(priv->dev, wc); |
377 | ipoib_cm_handle_tx_wc(dev, wc); | ||
378 | else | ||
379 | ipoib_ib_handle_tx_wc(dev, wc); | ||
380 | } | ||
381 | } | 438 | } |
382 | 439 | ||
383 | if (n != t) | 440 | if (n != t) |
@@ -386,7 +443,7 @@ poll_more: | |||
386 | 443 | ||
387 | if (done < budget) { | 444 | if (done < budget) { |
388 | netif_rx_complete(dev, napi); | 445 | netif_rx_complete(dev, napi); |
389 | if (unlikely(ib_req_notify_cq(priv->cq, | 446 | if (unlikely(ib_req_notify_cq(priv->recv_cq, |
390 | IB_CQ_NEXT_COMP | | 447 | IB_CQ_NEXT_COMP | |
391 | IB_CQ_REPORT_MISSED_EVENTS)) && | 448 | IB_CQ_REPORT_MISSED_EVENTS)) && |
392 | netif_rx_reschedule(dev, napi)) | 449 | netif_rx_reschedule(dev, napi)) |
@@ -404,6 +461,26 @@ void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr) | |||
404 | netif_rx_schedule(dev, &priv->napi); | 461 | netif_rx_schedule(dev, &priv->napi); |
405 | } | 462 | } |
406 | 463 | ||
464 | static void drain_tx_cq(struct net_device *dev) | ||
465 | { | ||
466 | struct ipoib_dev_priv *priv = netdev_priv(dev); | ||
467 | unsigned long flags; | ||
468 | |||
469 | spin_lock_irqsave(&priv->tx_lock, flags); | ||
470 | while (poll_tx(priv)) | ||
471 | ; /* nothing */ | ||
472 | |||
473 | if (netif_queue_stopped(dev)) | ||
474 | mod_timer(&priv->poll_timer, jiffies + 1); | ||
475 | |||
476 | spin_unlock_irqrestore(&priv->tx_lock, flags); | ||
477 | } | ||
478 | |||
479 | void ipoib_send_comp_handler(struct ib_cq *cq, void *dev_ptr) | ||
480 | { | ||
481 | drain_tx_cq((struct net_device *)dev_ptr); | ||
482 | } | ||
483 | |||
407 | static inline int post_send(struct ipoib_dev_priv *priv, | 484 | static inline int post_send(struct ipoib_dev_priv *priv, |
408 | unsigned int wr_id, | 485 | unsigned int wr_id, |
409 | struct ib_ah *address, u32 qpn, | 486 | struct ib_ah *address, u32 qpn, |
@@ -498,23 +575,34 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
498 | else | 575 | else |
499 | priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM; | 576 | priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM; |
500 | 577 | ||
578 | if (++priv->tx_outstanding == ipoib_sendq_size) { | ||
579 | ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n"); | ||
580 | if (ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP)) | ||
581 | ipoib_warn(priv, "request notify on send CQ failed\n"); | ||
582 | netif_stop_queue(dev); | ||
583 | } | ||
584 | |||
501 | if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1), | 585 | if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1), |
502 | address->ah, qpn, tx_req, phead, hlen))) { | 586 | address->ah, qpn, tx_req, phead, hlen))) { |
503 | ipoib_warn(priv, "post_send failed\n"); | 587 | ipoib_warn(priv, "post_send failed\n"); |
504 | ++dev->stats.tx_errors; | 588 | ++dev->stats.tx_errors; |
589 | --priv->tx_outstanding; | ||
505 | ipoib_dma_unmap_tx(priv->ca, tx_req); | 590 | ipoib_dma_unmap_tx(priv->ca, tx_req); |
506 | dev_kfree_skb_any(skb); | 591 | dev_kfree_skb_any(skb); |
592 | if (netif_queue_stopped(dev)) | ||
593 | netif_wake_queue(dev); | ||
507 | } else { | 594 | } else { |
508 | dev->trans_start = jiffies; | 595 | dev->trans_start = jiffies; |
509 | 596 | ||
510 | address->last_send = priv->tx_head; | 597 | address->last_send = priv->tx_head; |
511 | ++priv->tx_head; | 598 | ++priv->tx_head; |
599 | skb_orphan(skb); | ||
512 | 600 | ||
513 | if (++priv->tx_outstanding == ipoib_sendq_size) { | ||
514 | ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n"); | ||
515 | netif_stop_queue(dev); | ||
516 | } | ||
517 | } | 601 | } |
602 | |||
603 | if (unlikely(priv->tx_outstanding > MAX_SEND_CQE)) | ||
604 | while (poll_tx(priv)) | ||
605 | ; /* nothing */ | ||
518 | } | 606 | } |
519 | 607 | ||
520 | static void __ipoib_reap_ah(struct net_device *dev) | 608 | static void __ipoib_reap_ah(struct net_device *dev) |
@@ -548,6 +636,11 @@ void ipoib_reap_ah(struct work_struct *work) | |||
548 | round_jiffies_relative(HZ)); | 636 | round_jiffies_relative(HZ)); |
549 | } | 637 | } |
550 | 638 | ||
639 | static void ipoib_ib_tx_timer_func(unsigned long ctx) | ||
640 | { | ||
641 | drain_tx_cq((struct net_device *)ctx); | ||
642 | } | ||
643 | |||
551 | int ipoib_ib_dev_open(struct net_device *dev) | 644 | int ipoib_ib_dev_open(struct net_device *dev) |
552 | { | 645 | { |
553 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 646 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
@@ -584,6 +677,10 @@ int ipoib_ib_dev_open(struct net_device *dev) | |||
584 | queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, | 677 | queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, |
585 | round_jiffies_relative(HZ)); | 678 | round_jiffies_relative(HZ)); |
586 | 679 | ||
680 | init_timer(&priv->poll_timer); | ||
681 | priv->poll_timer.function = ipoib_ib_tx_timer_func; | ||
682 | priv->poll_timer.data = (unsigned long)dev; | ||
683 | |||
587 | set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags); | 684 | set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags); |
588 | 685 | ||
589 | return 0; | 686 | return 0; |
@@ -661,7 +758,7 @@ void ipoib_drain_cq(struct net_device *dev) | |||
661 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 758 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
662 | int i, n; | 759 | int i, n; |
663 | do { | 760 | do { |
664 | n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc); | 761 | n = ib_poll_cq(priv->recv_cq, IPOIB_NUM_WC, priv->ibwc); |
665 | for (i = 0; i < n; ++i) { | 762 | for (i = 0; i < n; ++i) { |
666 | /* | 763 | /* |
667 | * Convert any successful completions to flush | 764 | * Convert any successful completions to flush |
@@ -676,14 +773,13 @@ void ipoib_drain_cq(struct net_device *dev) | |||
676 | ipoib_cm_handle_rx_wc(dev, priv->ibwc + i); | 773 | ipoib_cm_handle_rx_wc(dev, priv->ibwc + i); |
677 | else | 774 | else |
678 | ipoib_ib_handle_rx_wc(dev, priv->ibwc + i); | 775 | ipoib_ib_handle_rx_wc(dev, priv->ibwc + i); |
679 | } else { | 776 | } else |
680 | if (priv->ibwc[i].wr_id & IPOIB_OP_CM) | 777 | ipoib_cm_handle_tx_wc(dev, priv->ibwc + i); |
681 | ipoib_cm_handle_tx_wc(dev, priv->ibwc + i); | ||
682 | else | ||
683 | ipoib_ib_handle_tx_wc(dev, priv->ibwc + i); | ||
684 | } | ||
685 | } | 778 | } |
686 | } while (n == IPOIB_NUM_WC); | 779 | } while (n == IPOIB_NUM_WC); |
780 | |||
781 | while (poll_tx(priv)) | ||
782 | ; /* nothing */ | ||
687 | } | 783 | } |
688 | 784 | ||
689 | int ipoib_ib_dev_stop(struct net_device *dev, int flush) | 785 | int ipoib_ib_dev_stop(struct net_device *dev, int flush) |
@@ -733,10 +829,8 @@ int ipoib_ib_dev_stop(struct net_device *dev, int flush) | |||
733 | rx_req = &priv->rx_ring[i]; | 829 | rx_req = &priv->rx_ring[i]; |
734 | if (!rx_req->skb) | 830 | if (!rx_req->skb) |
735 | continue; | 831 | continue; |
736 | ib_dma_unmap_single(priv->ca, | 832 | ipoib_ud_dma_unmap_rx(priv, |
737 | rx_req->mapping, | 833 | priv->rx_ring[i].mapping); |
738 | IPOIB_BUF_SIZE, | ||
739 | DMA_FROM_DEVICE); | ||
740 | dev_kfree_skb_any(rx_req->skb); | 834 | dev_kfree_skb_any(rx_req->skb); |
741 | rx_req->skb = NULL; | 835 | rx_req->skb = NULL; |
742 | } | 836 | } |
@@ -752,6 +846,7 @@ int ipoib_ib_dev_stop(struct net_device *dev, int flush) | |||
752 | ipoib_dbg(priv, "All sends and receives done.\n"); | 846 | ipoib_dbg(priv, "All sends and receives done.\n"); |
753 | 847 | ||
754 | timeout: | 848 | timeout: |
849 | del_timer_sync(&priv->poll_timer); | ||
755 | qp_attr.qp_state = IB_QPS_RESET; | 850 | qp_attr.qp_state = IB_QPS_RESET; |
756 | if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE)) | 851 | if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE)) |
757 | ipoib_warn(priv, "Failed to modify QP to RESET state\n"); | 852 | ipoib_warn(priv, "Failed to modify QP to RESET state\n"); |
@@ -775,7 +870,7 @@ timeout: | |||
775 | msleep(1); | 870 | msleep(1); |
776 | } | 871 | } |
777 | 872 | ||
778 | ib_req_notify_cq(priv->cq, IB_CQ_NEXT_COMP); | 873 | ib_req_notify_cq(priv->recv_cq, IB_CQ_NEXT_COMP); |
779 | 874 | ||
780 | return 0; | 875 | return 0; |
781 | } | 876 | } |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index bd07f02cf02b..2442090ac8d1 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -195,7 +195,7 @@ static int ipoib_change_mtu(struct net_device *dev, int new_mtu) | |||
195 | return 0; | 195 | return 0; |
196 | } | 196 | } |
197 | 197 | ||
198 | if (new_mtu > IPOIB_PACKET_SIZE - IPOIB_ENCAP_LEN) | 198 | if (new_mtu > IPOIB_UD_MTU(priv->max_ib_mtu)) |
199 | return -EINVAL; | 199 | return -EINVAL; |
200 | 200 | ||
201 | priv->admin_mtu = new_mtu; | 201 | priv->admin_mtu = new_mtu; |
@@ -971,10 +971,6 @@ static void ipoib_setup(struct net_device *dev) | |||
971 | NETIF_F_LLTX | | 971 | NETIF_F_LLTX | |
972 | NETIF_F_HIGHDMA); | 972 | NETIF_F_HIGHDMA); |
973 | 973 | ||
974 | /* MTU will be reset when mcast join happens */ | ||
975 | dev->mtu = IPOIB_PACKET_SIZE - IPOIB_ENCAP_LEN; | ||
976 | priv->mcast_mtu = priv->admin_mtu = dev->mtu; | ||
977 | |||
978 | memcpy(dev->broadcast, ipv4_bcast_addr, INFINIBAND_ALEN); | 974 | memcpy(dev->broadcast, ipv4_bcast_addr, INFINIBAND_ALEN); |
979 | 975 | ||
980 | netif_carrier_off(dev); | 976 | netif_carrier_off(dev); |
@@ -1107,6 +1103,7 @@ static struct net_device *ipoib_add_port(const char *format, | |||
1107 | { | 1103 | { |
1108 | struct ipoib_dev_priv *priv; | 1104 | struct ipoib_dev_priv *priv; |
1109 | struct ib_device_attr *device_attr; | 1105 | struct ib_device_attr *device_attr; |
1106 | struct ib_port_attr attr; | ||
1110 | int result = -ENOMEM; | 1107 | int result = -ENOMEM; |
1111 | 1108 | ||
1112 | priv = ipoib_intf_alloc(format); | 1109 | priv = ipoib_intf_alloc(format); |
@@ -1115,6 +1112,18 @@ static struct net_device *ipoib_add_port(const char *format, | |||
1115 | 1112 | ||
1116 | SET_NETDEV_DEV(priv->dev, hca->dma_device); | 1113 | SET_NETDEV_DEV(priv->dev, hca->dma_device); |
1117 | 1114 | ||
1115 | if (!ib_query_port(hca, port, &attr)) | ||
1116 | priv->max_ib_mtu = ib_mtu_enum_to_int(attr.max_mtu); | ||
1117 | else { | ||
1118 | printk(KERN_WARNING "%s: ib_query_port %d failed\n", | ||
1119 | hca->name, port); | ||
1120 | goto device_init_failed; | ||
1121 | } | ||
1122 | |||
1123 | /* MTU will be reset when mcast join happens */ | ||
1124 | priv->dev->mtu = IPOIB_UD_MTU(priv->max_ib_mtu); | ||
1125 | priv->mcast_mtu = priv->admin_mtu = priv->dev->mtu; | ||
1126 | |||
1118 | result = ib_query_pkey(hca, port, 0, &priv->pkey); | 1127 | result = ib_query_pkey(hca, port, 0, &priv->pkey); |
1119 | if (result) { | 1128 | if (result) { |
1120 | printk(KERN_WARNING "%s: ib_query_pkey port %d failed (ret = %d)\n", | 1129 | printk(KERN_WARNING "%s: ib_query_pkey port %d failed (ret = %d)\n", |
@@ -1289,7 +1298,8 @@ static int __init ipoib_init_module(void) | |||
1289 | 1298 | ||
1290 | ipoib_sendq_size = roundup_pow_of_two(ipoib_sendq_size); | 1299 | ipoib_sendq_size = roundup_pow_of_two(ipoib_sendq_size); |
1291 | ipoib_sendq_size = min(ipoib_sendq_size, IPOIB_MAX_QUEUE_SIZE); | 1300 | ipoib_sendq_size = min(ipoib_sendq_size, IPOIB_MAX_QUEUE_SIZE); |
1292 | ipoib_sendq_size = max(ipoib_sendq_size, IPOIB_MIN_QUEUE_SIZE); | 1301 | ipoib_sendq_size = max(ipoib_sendq_size, max(2 * MAX_SEND_CQE, |
1302 | IPOIB_MIN_QUEUE_SIZE)); | ||
1293 | #ifdef CONFIG_INFINIBAND_IPOIB_CM | 1303 | #ifdef CONFIG_INFINIBAND_IPOIB_CM |
1294 | ipoib_max_conn_qp = min(ipoib_max_conn_qp, IPOIB_CM_MAX_CONN_QP); | 1304 | ipoib_max_conn_qp = min(ipoib_max_conn_qp, IPOIB_CM_MAX_CONN_QP); |
1295 | #endif | 1305 | #endif |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 31a53c5bcb13..d00a2c174aee 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -567,8 +567,7 @@ void ipoib_mcast_join_task(struct work_struct *work) | |||
567 | return; | 567 | return; |
568 | } | 568 | } |
569 | 569 | ||
570 | priv->mcast_mtu = ib_mtu_enum_to_int(priv->broadcast->mcmember.mtu) - | 570 | priv->mcast_mtu = IPOIB_UD_MTU(ib_mtu_enum_to_int(priv->broadcast->mcmember.mtu)); |
571 | IPOIB_ENCAP_LEN; | ||
572 | 571 | ||
573 | if (!ipoib_cm_admin_enabled(dev)) | 572 | if (!ipoib_cm_admin_enabled(dev)) |
574 | dev->mtu = min(priv->mcast_mtu, priv->admin_mtu); | 573 | dev->mtu = min(priv->mcast_mtu, priv->admin_mtu); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 8a20e3742c43..8766d29ce3b7 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c | |||
@@ -150,7 +150,7 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca) | |||
150 | .max_send_wr = ipoib_sendq_size, | 150 | .max_send_wr = ipoib_sendq_size, |
151 | .max_recv_wr = ipoib_recvq_size, | 151 | .max_recv_wr = ipoib_recvq_size, |
152 | .max_send_sge = 1, | 152 | .max_send_sge = 1, |
153 | .max_recv_sge = 1 | 153 | .max_recv_sge = IPOIB_UD_RX_SG |
154 | }, | 154 | }, |
155 | .sq_sig_type = IB_SIGNAL_ALL_WR, | 155 | .sq_sig_type = IB_SIGNAL_ALL_WR, |
156 | .qp_type = IB_QPT_UD | 156 | .qp_type = IB_QPT_UD |
@@ -171,26 +171,34 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca) | |||
171 | goto out_free_pd; | 171 | goto out_free_pd; |
172 | } | 172 | } |
173 | 173 | ||
174 | size = ipoib_sendq_size + ipoib_recvq_size + 1; | 174 | size = ipoib_recvq_size + 1; |
175 | ret = ipoib_cm_dev_init(dev); | 175 | ret = ipoib_cm_dev_init(dev); |
176 | if (!ret) { | 176 | if (!ret) { |
177 | size += ipoib_sendq_size; | ||
177 | if (ipoib_cm_has_srq(dev)) | 178 | if (ipoib_cm_has_srq(dev)) |
178 | size += ipoib_recvq_size + 1; /* 1 extra for rx_drain_qp */ | 179 | size += ipoib_recvq_size + 1; /* 1 extra for rx_drain_qp */ |
179 | else | 180 | else |
180 | size += ipoib_recvq_size * ipoib_max_conn_qp; | 181 | size += ipoib_recvq_size * ipoib_max_conn_qp; |
181 | } | 182 | } |
182 | 183 | ||
183 | priv->cq = ib_create_cq(priv->ca, ipoib_ib_completion, NULL, dev, size, 0); | 184 | priv->recv_cq = ib_create_cq(priv->ca, ipoib_ib_completion, NULL, dev, size, 0); |
184 | if (IS_ERR(priv->cq)) { | 185 | if (IS_ERR(priv->recv_cq)) { |
185 | printk(KERN_WARNING "%s: failed to create CQ\n", ca->name); | 186 | printk(KERN_WARNING "%s: failed to create receive CQ\n", ca->name); |
186 | goto out_free_mr; | 187 | goto out_free_mr; |
187 | } | 188 | } |
188 | 189 | ||
189 | if (ib_req_notify_cq(priv->cq, IB_CQ_NEXT_COMP)) | 190 | priv->send_cq = ib_create_cq(priv->ca, ipoib_send_comp_handler, NULL, |
190 | goto out_free_cq; | 191 | dev, ipoib_sendq_size, 0); |
192 | if (IS_ERR(priv->send_cq)) { | ||
193 | printk(KERN_WARNING "%s: failed to create send CQ\n", ca->name); | ||
194 | goto out_free_recv_cq; | ||
195 | } | ||
196 | |||
197 | if (ib_req_notify_cq(priv->recv_cq, IB_CQ_NEXT_COMP)) | ||
198 | goto out_free_send_cq; | ||
191 | 199 | ||
192 | init_attr.send_cq = priv->cq; | 200 | init_attr.send_cq = priv->send_cq; |
193 | init_attr.recv_cq = priv->cq; | 201 | init_attr.recv_cq = priv->recv_cq; |
194 | 202 | ||
195 | if (priv->hca_caps & IB_DEVICE_UD_TSO) | 203 | if (priv->hca_caps & IB_DEVICE_UD_TSO) |
196 | init_attr.create_flags = IB_QP_CREATE_IPOIB_UD_LSO; | 204 | init_attr.create_flags = IB_QP_CREATE_IPOIB_UD_LSO; |
@@ -201,7 +209,7 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca) | |||
201 | priv->qp = ib_create_qp(priv->pd, &init_attr); | 209 | priv->qp = ib_create_qp(priv->pd, &init_attr); |
202 | if (IS_ERR(priv->qp)) { | 210 | if (IS_ERR(priv->qp)) { |
203 | printk(KERN_WARNING "%s: failed to create QP\n", ca->name); | 211 | printk(KERN_WARNING "%s: failed to create QP\n", ca->name); |
204 | goto out_free_cq; | 212 | goto out_free_send_cq; |
205 | } | 213 | } |
206 | 214 | ||
207 | priv->dev->dev_addr[1] = (priv->qp->qp_num >> 16) & 0xff; | 215 | priv->dev->dev_addr[1] = (priv->qp->qp_num >> 16) & 0xff; |
@@ -215,10 +223,26 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca) | |||
215 | priv->tx_wr.sg_list = priv->tx_sge; | 223 | priv->tx_wr.sg_list = priv->tx_sge; |
216 | priv->tx_wr.send_flags = IB_SEND_SIGNALED; | 224 | priv->tx_wr.send_flags = IB_SEND_SIGNALED; |
217 | 225 | ||
226 | priv->rx_sge[0].lkey = priv->mr->lkey; | ||
227 | if (ipoib_ud_need_sg(priv->max_ib_mtu)) { | ||
228 | priv->rx_sge[0].length = IPOIB_UD_HEAD_SIZE; | ||
229 | priv->rx_sge[1].length = PAGE_SIZE; | ||
230 | priv->rx_sge[1].lkey = priv->mr->lkey; | ||
231 | priv->rx_wr.num_sge = IPOIB_UD_RX_SG; | ||
232 | } else { | ||
233 | priv->rx_sge[0].length = IPOIB_UD_BUF_SIZE(priv->max_ib_mtu); | ||
234 | priv->rx_wr.num_sge = 1; | ||
235 | } | ||
236 | priv->rx_wr.next = NULL; | ||
237 | priv->rx_wr.sg_list = priv->rx_sge; | ||
238 | |||
218 | return 0; | 239 | return 0; |
219 | 240 | ||
220 | out_free_cq: | 241 | out_free_send_cq: |
221 | ib_destroy_cq(priv->cq); | 242 | ib_destroy_cq(priv->send_cq); |
243 | |||
244 | out_free_recv_cq: | ||
245 | ib_destroy_cq(priv->recv_cq); | ||
222 | 246 | ||
223 | out_free_mr: | 247 | out_free_mr: |
224 | ib_dereg_mr(priv->mr); | 248 | ib_dereg_mr(priv->mr); |
@@ -241,8 +265,11 @@ void ipoib_transport_dev_cleanup(struct net_device *dev) | |||
241 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | 265 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); |
242 | } | 266 | } |
243 | 267 | ||
244 | if (ib_destroy_cq(priv->cq)) | 268 | if (ib_destroy_cq(priv->send_cq)) |
245 | ipoib_warn(priv, "ib_cq_destroy failed\n"); | 269 | ipoib_warn(priv, "ib_cq_destroy (send) failed\n"); |
270 | |||
271 | if (ib_destroy_cq(priv->recv_cq)) | ||
272 | ipoib_warn(priv, "ib_cq_destroy (recv) failed\n"); | ||
246 | 273 | ||
247 | ipoib_cm_dev_cleanup(dev); | 274 | ipoib_cm_dev_cleanup(dev); |
248 | 275 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c index 293f5b892e3f..1cdb5cfb0ff1 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c | |||
@@ -89,6 +89,10 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) | |||
89 | goto err; | 89 | goto err; |
90 | } | 90 | } |
91 | 91 | ||
92 | priv->max_ib_mtu = ppriv->max_ib_mtu; | ||
93 | /* MTU will be reset when mcast join happens */ | ||
94 | priv->dev->mtu = IPOIB_UD_MTU(priv->max_ib_mtu); | ||
95 | priv->mcast_mtu = priv->admin_mtu = priv->dev->mtu; | ||
92 | set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags); | 96 | set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags); |
93 | 97 | ||
94 | priv->pkey = pkey; | 98 | priv->pkey = pkey; |
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index be1b9fbd416d..aeb58cae9a3f 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c | |||
@@ -473,13 +473,15 @@ iscsi_iser_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *s | |||
473 | stats->r2t_pdus = conn->r2t_pdus_cnt; /* always 0 */ | 473 | stats->r2t_pdus = conn->r2t_pdus_cnt; /* always 0 */ |
474 | stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt; | 474 | stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt; |
475 | stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt; | 475 | stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt; |
476 | stats->custom_length = 3; | 476 | stats->custom_length = 4; |
477 | strcpy(stats->custom[0].desc, "qp_tx_queue_full"); | 477 | strcpy(stats->custom[0].desc, "qp_tx_queue_full"); |
478 | stats->custom[0].value = 0; /* TB iser_conn->qp_tx_queue_full; */ | 478 | stats->custom[0].value = 0; /* TB iser_conn->qp_tx_queue_full; */ |
479 | strcpy(stats->custom[1].desc, "fmr_map_not_avail"); | 479 | strcpy(stats->custom[1].desc, "fmr_map_not_avail"); |
480 | stats->custom[1].value = 0; /* TB iser_conn->fmr_map_not_avail */; | 480 | stats->custom[1].value = 0; /* TB iser_conn->fmr_map_not_avail */; |
481 | strcpy(stats->custom[2].desc, "eh_abort_cnt"); | 481 | strcpy(stats->custom[2].desc, "eh_abort_cnt"); |
482 | stats->custom[2].value = conn->eh_abort_cnt; | 482 | stats->custom[2].value = conn->eh_abort_cnt; |
483 | strcpy(stats->custom[3].desc, "fmr_unalign_cnt"); | ||
484 | stats->custom[3].value = conn->fmr_unalign_cnt; | ||
483 | } | 485 | } |
484 | 486 | ||
485 | static int | 487 | static int |
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index 1ee867b1b341..a8c1b300e34d 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h | |||
@@ -71,6 +71,13 @@ | |||
71 | 71 | ||
72 | #define iser_dbg(fmt, arg...) \ | 72 | #define iser_dbg(fmt, arg...) \ |
73 | do { \ | 73 | do { \ |
74 | if (iser_debug_level > 1) \ | ||
75 | printk(KERN_DEBUG PFX "%s:" fmt,\ | ||
76 | __func__ , ## arg); \ | ||
77 | } while (0) | ||
78 | |||
79 | #define iser_warn(fmt, arg...) \ | ||
80 | do { \ | ||
74 | if (iser_debug_level > 0) \ | 81 | if (iser_debug_level > 0) \ |
75 | printk(KERN_DEBUG PFX "%s:" fmt,\ | 82 | printk(KERN_DEBUG PFX "%s:" fmt,\ |
76 | __func__ , ## arg); \ | 83 | __func__ , ## arg); \ |
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c index 4a17743a639f..cac50c4dc159 100644 --- a/drivers/infiniband/ulp/iser/iser_memory.c +++ b/drivers/infiniband/ulp/iser/iser_memory.c | |||
@@ -334,8 +334,11 @@ static void iser_data_buf_dump(struct iser_data_buf *data, | |||
334 | struct scatterlist *sg; | 334 | struct scatterlist *sg; |
335 | int i; | 335 | int i; |
336 | 336 | ||
337 | if (iser_debug_level == 0) | ||
338 | return; | ||
339 | |||
337 | for_each_sg(sgl, sg, data->dma_nents, i) | 340 | for_each_sg(sgl, sg, data->dma_nents, i) |
338 | iser_err("sg[%d] dma_addr:0x%lX page:0x%p " | 341 | iser_warn("sg[%d] dma_addr:0x%lX page:0x%p " |
339 | "off:0x%x sz:0x%x dma_len:0x%x\n", | 342 | "off:0x%x sz:0x%x dma_len:0x%x\n", |
340 | i, (unsigned long)ib_sg_dma_address(ibdev, sg), | 343 | i, (unsigned long)ib_sg_dma_address(ibdev, sg), |
341 | sg_page(sg), sg->offset, | 344 | sg_page(sg), sg->offset, |
@@ -420,6 +423,7 @@ void iser_dma_unmap_task_data(struct iscsi_iser_cmd_task *iser_ctask) | |||
420 | int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask, | 423 | int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask, |
421 | enum iser_data_dir cmd_dir) | 424 | enum iser_data_dir cmd_dir) |
422 | { | 425 | { |
426 | struct iscsi_conn *iscsi_conn = iser_ctask->iser_conn->iscsi_conn; | ||
423 | struct iser_conn *ib_conn = iser_ctask->iser_conn->ib_conn; | 427 | struct iser_conn *ib_conn = iser_ctask->iser_conn->ib_conn; |
424 | struct iser_device *device = ib_conn->device; | 428 | struct iser_device *device = ib_conn->device; |
425 | struct ib_device *ibdev = device->ib_device; | 429 | struct ib_device *ibdev = device->ib_device; |
@@ -434,7 +438,8 @@ int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask, | |||
434 | 438 | ||
435 | aligned_len = iser_data_buf_aligned_len(mem, ibdev); | 439 | aligned_len = iser_data_buf_aligned_len(mem, ibdev); |
436 | if (aligned_len != mem->dma_nents) { | 440 | if (aligned_len != mem->dma_nents) { |
437 | iser_err("rdma alignment violation %d/%d aligned\n", | 441 | iscsi_conn->fmr_unalign_cnt++; |
442 | iser_warn("rdma alignment violation %d/%d aligned\n", | ||
438 | aligned_len, mem->size); | 443 | aligned_len, mem->size); |
439 | iser_data_buf_dump(mem, ibdev); | 444 | iser_data_buf_dump(mem, ibdev); |
440 | 445 | ||