diff options
Diffstat (limited to 'drivers/infiniband')
| -rw-r--r-- | drivers/infiniband/core/cma.c | 2 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/cm.c | 4 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mlx4/main.c | 21 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mlx4/mlx4_ib.h | 8 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mlx4/qp.c | 21 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ocrdma/ocrdma.h | 2 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ocrdma/ocrdma_abi.h | 5 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ocrdma/ocrdma_hw.c | 27 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ocrdma/ocrdma_main.c | 64 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ocrdma/ocrdma_sli.h | 5 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 17 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ocrdma/ocrdma_verbs.h | 1 | ||||
| -rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_ib.c | 12 |
13 files changed, 100 insertions, 89 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 55d5642eb10a..2e826f9702c6 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
| @@ -1184,7 +1184,7 @@ static void cma_set_req_event_data(struct rdma_cm_event *event, | |||
| 1184 | 1184 | ||
| 1185 | static int cma_check_req_qp_type(struct rdma_cm_id *id, struct ib_cm_event *ib_event) | 1185 | static int cma_check_req_qp_type(struct rdma_cm_id *id, struct ib_cm_event *ib_event) |
| 1186 | { | 1186 | { |
| 1187 | return (((ib_event->event == IB_CM_REQ_RECEIVED) || | 1187 | return (((ib_event->event == IB_CM_REQ_RECEIVED) && |
| 1188 | (ib_event->param.req_rcvd.qp_type == id->qp_type)) || | 1188 | (ib_event->param.req_rcvd.qp_type == id->qp_type)) || |
| 1189 | ((ib_event->event == IB_CM_SIDR_REQ_RECEIVED) && | 1189 | ((ib_event->event == IB_CM_SIDR_REQ_RECEIVED) && |
| 1190 | (id->qp_type == IB_QPT_UD)) || | 1190 | (id->qp_type == IB_QPT_UD)) || |
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 55ab284e22f2..b18870c455ad 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c | |||
| @@ -1593,6 +1593,10 @@ static int import_ep(struct c4iw_ep *ep, __be32 peer_ip, struct dst_entry *dst, | |||
| 1593 | struct net_device *pdev; | 1593 | struct net_device *pdev; |
| 1594 | 1594 | ||
| 1595 | pdev = ip_dev_find(&init_net, peer_ip); | 1595 | pdev = ip_dev_find(&init_net, peer_ip); |
| 1596 | if (!pdev) { | ||
| 1597 | err = -ENODEV; | ||
| 1598 | goto out; | ||
| 1599 | } | ||
| 1596 | ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, | 1600 | ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, |
| 1597 | n, pdev, 0); | 1601 | n, pdev, 0); |
| 1598 | if (!ep->l2t) | 1602 | if (!ep->l2t) |
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index ee1c577238f7..3530c41fcd1f 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
| @@ -140,7 +140,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, | |||
| 140 | props->max_mr_size = ~0ull; | 140 | props->max_mr_size = ~0ull; |
| 141 | props->page_size_cap = dev->dev->caps.page_size_cap; | 141 | props->page_size_cap = dev->dev->caps.page_size_cap; |
| 142 | props->max_qp = dev->dev->caps.num_qps - dev->dev->caps.reserved_qps; | 142 | props->max_qp = dev->dev->caps.num_qps - dev->dev->caps.reserved_qps; |
| 143 | props->max_qp_wr = dev->dev->caps.max_wqes; | 143 | props->max_qp_wr = dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE; |
| 144 | props->max_sge = min(dev->dev->caps.max_sq_sg, | 144 | props->max_sge = min(dev->dev->caps.max_sq_sg, |
| 145 | dev->dev->caps.max_rq_sg); | 145 | dev->dev->caps.max_rq_sg); |
| 146 | props->max_cq = dev->dev->caps.num_cqs - dev->dev->caps.reserved_cqs; | 146 | props->max_cq = dev->dev->caps.num_cqs - dev->dev->caps.reserved_cqs; |
| @@ -1084,12 +1084,9 @@ static void mlx4_ib_alloc_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) | |||
| 1084 | int total_eqs = 0; | 1084 | int total_eqs = 0; |
| 1085 | int i, j, eq; | 1085 | int i, j, eq; |
| 1086 | 1086 | ||
| 1087 | /* Init eq table */ | 1087 | /* Legacy mode or comp_pool is not large enough */ |
| 1088 | ibdev->eq_table = NULL; | 1088 | if (dev->caps.comp_pool == 0 || |
| 1089 | ibdev->eq_added = 0; | 1089 | dev->caps.num_ports > dev->caps.comp_pool) |
| 1090 | |||
| 1091 | /* Legacy mode? */ | ||
| 1092 | if (dev->caps.comp_pool == 0) | ||
| 1093 | return; | 1090 | return; |
| 1094 | 1091 | ||
| 1095 | eq_per_port = rounddown_pow_of_two(dev->caps.comp_pool/ | 1092 | eq_per_port = rounddown_pow_of_two(dev->caps.comp_pool/ |
| @@ -1135,7 +1132,10 @@ static void mlx4_ib_alloc_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) | |||
| 1135 | static void mlx4_ib_free_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) | 1132 | static void mlx4_ib_free_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) |
| 1136 | { | 1133 | { |
| 1137 | int i; | 1134 | int i; |
| 1138 | int total_eqs; | 1135 | |
| 1136 | /* no additional eqs were added */ | ||
| 1137 | if (!ibdev->eq_table) | ||
| 1138 | return; | ||
| 1139 | 1139 | ||
| 1140 | /* Reset the advertised EQ number */ | 1140 | /* Reset the advertised EQ number */ |
| 1141 | ibdev->ib_dev.num_comp_vectors = dev->caps.num_comp_vectors; | 1141 | ibdev->ib_dev.num_comp_vectors = dev->caps.num_comp_vectors; |
| @@ -1148,12 +1148,7 @@ static void mlx4_ib_free_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) | |||
| 1148 | mlx4_release_eq(dev, ibdev->eq_table[i]); | 1148 | mlx4_release_eq(dev, ibdev->eq_table[i]); |
| 1149 | } | 1149 | } |
| 1150 | 1150 | ||
| 1151 | total_eqs = dev->caps.num_comp_vectors + ibdev->eq_added; | ||
| 1152 | memset(ibdev->eq_table, 0, total_eqs * sizeof(int)); | ||
| 1153 | kfree(ibdev->eq_table); | 1151 | kfree(ibdev->eq_table); |
| 1154 | |||
| 1155 | ibdev->eq_table = NULL; | ||
| 1156 | ibdev->eq_added = 0; | ||
| 1157 | } | 1152 | } |
| 1158 | 1153 | ||
| 1159 | static void *mlx4_ib_add(struct mlx4_dev *dev) | 1154 | static void *mlx4_ib_add(struct mlx4_dev *dev) |
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h index e62297cc77cc..ff36655d23d3 100644 --- a/drivers/infiniband/hw/mlx4/mlx4_ib.h +++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h | |||
| @@ -44,6 +44,14 @@ | |||
| 44 | #include <linux/mlx4/device.h> | 44 | #include <linux/mlx4/device.h> |
| 45 | #include <linux/mlx4/doorbell.h> | 45 | #include <linux/mlx4/doorbell.h> |
| 46 | 46 | ||
| 47 | enum { | ||
| 48 | MLX4_IB_SQ_MIN_WQE_SHIFT = 6, | ||
| 49 | MLX4_IB_MAX_HEADROOM = 2048 | ||
| 50 | }; | ||
| 51 | |||
| 52 | #define MLX4_IB_SQ_HEADROOM(shift) ((MLX4_IB_MAX_HEADROOM >> (shift)) + 1) | ||
| 53 | #define MLX4_IB_SQ_MAX_SPARE (MLX4_IB_SQ_HEADROOM(MLX4_IB_SQ_MIN_WQE_SHIFT)) | ||
| 54 | |||
| 47 | struct mlx4_ib_ucontext { | 55 | struct mlx4_ib_ucontext { |
| 48 | struct ib_ucontext ibucontext; | 56 | struct ib_ucontext ibucontext; |
| 49 | struct mlx4_uar uar; | 57 | struct mlx4_uar uar; |
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index ceb33327091a..8d4ed24aef93 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
| @@ -310,8 +310,8 @@ static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, | |||
| 310 | int is_user, int has_rq, struct mlx4_ib_qp *qp) | 310 | int is_user, int has_rq, struct mlx4_ib_qp *qp) |
| 311 | { | 311 | { |
| 312 | /* Sanity check RQ size before proceeding */ | 312 | /* Sanity check RQ size before proceeding */ |
| 313 | if (cap->max_recv_wr > dev->dev->caps.max_wqes || | 313 | if (cap->max_recv_wr > dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE || |
| 314 | cap->max_recv_sge > dev->dev->caps.max_rq_sg) | 314 | cap->max_recv_sge > min(dev->dev->caps.max_sq_sg, dev->dev->caps.max_rq_sg)) |
| 315 | return -EINVAL; | 315 | return -EINVAL; |
| 316 | 316 | ||
| 317 | if (!has_rq) { | 317 | if (!has_rq) { |
| @@ -329,8 +329,17 @@ static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, | |||
| 329 | qp->rq.wqe_shift = ilog2(qp->rq.max_gs * sizeof (struct mlx4_wqe_data_seg)); | 329 | qp->rq.wqe_shift = ilog2(qp->rq.max_gs * sizeof (struct mlx4_wqe_data_seg)); |
| 330 | } | 330 | } |
| 331 | 331 | ||
| 332 | cap->max_recv_wr = qp->rq.max_post = qp->rq.wqe_cnt; | 332 | /* leave userspace return values as they were, so as not to break ABI */ |
| 333 | cap->max_recv_sge = qp->rq.max_gs; | 333 | if (is_user) { |
| 334 | cap->max_recv_wr = qp->rq.max_post = qp->rq.wqe_cnt; | ||
| 335 | cap->max_recv_sge = qp->rq.max_gs; | ||
| 336 | } else { | ||
| 337 | cap->max_recv_wr = qp->rq.max_post = | ||
| 338 | min(dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE, qp->rq.wqe_cnt); | ||
| 339 | cap->max_recv_sge = min(qp->rq.max_gs, | ||
| 340 | min(dev->dev->caps.max_sq_sg, | ||
| 341 | dev->dev->caps.max_rq_sg)); | ||
| 342 | } | ||
| 334 | 343 | ||
| 335 | return 0; | 344 | return 0; |
| 336 | } | 345 | } |
| @@ -341,8 +350,8 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, | |||
| 341 | int s; | 350 | int s; |
| 342 | 351 | ||
| 343 | /* Sanity check SQ size before proceeding */ | 352 | /* Sanity check SQ size before proceeding */ |
| 344 | if (cap->max_send_wr > dev->dev->caps.max_wqes || | 353 | if (cap->max_send_wr > (dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE) || |
| 345 | cap->max_send_sge > dev->dev->caps.max_sq_sg || | 354 | cap->max_send_sge > min(dev->dev->caps.max_sq_sg, dev->dev->caps.max_rq_sg) || |
| 346 | cap->max_inline_data + send_wqe_overhead(type, qp->flags) + | 355 | cap->max_inline_data + send_wqe_overhead(type, qp->flags) + |
| 347 | sizeof (struct mlx4_wqe_inline_seg) > dev->dev->caps.max_sq_desc_sz) | 356 | sizeof (struct mlx4_wqe_inline_seg) > dev->dev->caps.max_sq_desc_sz) |
| 348 | return -EINVAL; | 357 | return -EINVAL; |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h index 85a69c958559..48970af23679 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma.h | |||
| @@ -61,6 +61,7 @@ struct ocrdma_dev_attr { | |||
| 61 | u32 max_inline_data; | 61 | u32 max_inline_data; |
| 62 | int max_send_sge; | 62 | int max_send_sge; |
| 63 | int max_recv_sge; | 63 | int max_recv_sge; |
| 64 | int max_srq_sge; | ||
| 64 | int max_mr; | 65 | int max_mr; |
| 65 | u64 max_mr_size; | 66 | u64 max_mr_size; |
| 66 | u32 max_num_mr_pbl; | 67 | u32 max_num_mr_pbl; |
| @@ -231,7 +232,6 @@ struct ocrdma_qp_hwq_info { | |||
| 231 | u32 entry_size; | 232 | u32 entry_size; |
| 232 | u32 max_cnt; | 233 | u32 max_cnt; |
| 233 | u32 max_wqe_idx; | 234 | u32 max_wqe_idx; |
| 234 | u32 free_delta; | ||
| 235 | u16 dbid; /* qid, where to ring the doorbell. */ | 235 | u16 dbid; /* qid, where to ring the doorbell. */ |
| 236 | u32 len; | 236 | u32 len; |
| 237 | dma_addr_t pa; | 237 | dma_addr_t pa; |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_abi.h b/drivers/infiniband/hw/ocrdma/ocrdma_abi.h index a411a4e3193d..517ab20b727c 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_abi.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma_abi.h | |||
| @@ -101,8 +101,6 @@ struct ocrdma_create_qp_uresp { | |||
| 101 | u32 rsvd1; | 101 | u32 rsvd1; |
| 102 | u32 num_wqe_allocated; | 102 | u32 num_wqe_allocated; |
| 103 | u32 num_rqe_allocated; | 103 | u32 num_rqe_allocated; |
| 104 | u32 free_wqe_delta; | ||
| 105 | u32 free_rqe_delta; | ||
| 106 | u32 db_sq_offset; | 104 | u32 db_sq_offset; |
| 107 | u32 db_rq_offset; | 105 | u32 db_rq_offset; |
| 108 | u32 db_shift; | 106 | u32 db_shift; |
| @@ -126,8 +124,7 @@ struct ocrdma_create_srq_uresp { | |||
| 126 | u32 db_rq_offset; | 124 | u32 db_rq_offset; |
| 127 | u32 db_shift; | 125 | u32 db_shift; |
| 128 | 126 | ||
| 129 | u32 free_rqe_delta; | 127 | u64 rsvd2; |
| 130 | u32 rsvd2; | ||
| 131 | u64 rsvd3; | 128 | u64 rsvd3; |
| 132 | } __packed; | 129 | } __packed; |
| 133 | 130 | ||
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c index 9b204b1ba336..71942af4fce9 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c | |||
| @@ -732,7 +732,7 @@ static void ocrdma_dispatch_ibevent(struct ocrdma_dev *dev, | |||
| 732 | break; | 732 | break; |
| 733 | case OCRDMA_SRQ_LIMIT_EVENT: | 733 | case OCRDMA_SRQ_LIMIT_EVENT: |
| 734 | ib_evt.element.srq = &qp->srq->ibsrq; | 734 | ib_evt.element.srq = &qp->srq->ibsrq; |
| 735 | ib_evt.event = IB_EVENT_QP_LAST_WQE_REACHED; | 735 | ib_evt.event = IB_EVENT_SRQ_LIMIT_REACHED; |
| 736 | srq_event = 1; | 736 | srq_event = 1; |
| 737 | qp_event = 0; | 737 | qp_event = 0; |
| 738 | break; | 738 | break; |
| @@ -990,8 +990,6 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev, | |||
| 990 | struct ocrdma_dev_attr *attr, | 990 | struct ocrdma_dev_attr *attr, |
| 991 | struct ocrdma_mbx_query_config *rsp) | 991 | struct ocrdma_mbx_query_config *rsp) |
| 992 | { | 992 | { |
| 993 | int max_q_mem; | ||
| 994 | |||
| 995 | attr->max_pd = | 993 | attr->max_pd = |
| 996 | (rsp->max_pd_ca_ack_delay & OCRDMA_MBX_QUERY_CFG_MAX_PD_MASK) >> | 994 | (rsp->max_pd_ca_ack_delay & OCRDMA_MBX_QUERY_CFG_MAX_PD_MASK) >> |
| 997 | OCRDMA_MBX_QUERY_CFG_MAX_PD_SHIFT; | 995 | OCRDMA_MBX_QUERY_CFG_MAX_PD_SHIFT; |
| @@ -1004,6 +1002,9 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev, | |||
| 1004 | attr->max_recv_sge = (rsp->max_write_send_sge & | 1002 | attr->max_recv_sge = (rsp->max_write_send_sge & |
| 1005 | OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK) >> | 1003 | OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK) >> |
| 1006 | OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT; | 1004 | OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT; |
| 1005 | attr->max_srq_sge = (rsp->max_srq_rqe_sge & | ||
| 1006 | OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_MASK) >> | ||
| 1007 | OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_OFFSET; | ||
| 1007 | attr->max_ord_per_qp = (rsp->max_ird_ord_per_qp & | 1008 | attr->max_ord_per_qp = (rsp->max_ird_ord_per_qp & |
| 1008 | OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK) >> | 1009 | OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK) >> |
| 1009 | OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT; | 1010 | OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT; |
| @@ -1037,18 +1038,15 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev, | |||
| 1037 | attr->max_inline_data = | 1038 | attr->max_inline_data = |
| 1038 | attr->wqe_size - (sizeof(struct ocrdma_hdr_wqe) + | 1039 | attr->wqe_size - (sizeof(struct ocrdma_hdr_wqe) + |
| 1039 | sizeof(struct ocrdma_sge)); | 1040 | sizeof(struct ocrdma_sge)); |
| 1040 | max_q_mem = OCRDMA_Q_PAGE_BASE_SIZE << (OCRDMA_MAX_Q_PAGE_SIZE_CNT - 1); | ||
| 1041 | /* hw can queue one less then the configured size, | ||
| 1042 | * so publish less by one to stack. | ||
| 1043 | */ | ||
| 1044 | if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { | 1041 | if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { |
| 1045 | dev->attr.max_wqe = max_q_mem / dev->attr.wqe_size; | ||
| 1046 | attr->ird = 1; | 1042 | attr->ird = 1; |
| 1047 | attr->ird_page_size = OCRDMA_MIN_Q_PAGE_SIZE; | 1043 | attr->ird_page_size = OCRDMA_MIN_Q_PAGE_SIZE; |
| 1048 | attr->num_ird_pages = MAX_OCRDMA_IRD_PAGES; | 1044 | attr->num_ird_pages = MAX_OCRDMA_IRD_PAGES; |
| 1049 | } else | 1045 | } |
| 1050 | dev->attr.max_wqe = (max_q_mem / dev->attr.wqe_size) - 1; | 1046 | dev->attr.max_wqe = rsp->max_wqes_rqes_per_q >> |
| 1051 | dev->attr.max_rqe = (max_q_mem / dev->attr.rqe_size) - 1; | 1047 | OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET; |
| 1048 | dev->attr.max_rqe = rsp->max_wqes_rqes_per_q & | ||
| 1049 | OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_MASK; | ||
| 1052 | } | 1050 | } |
| 1053 | 1051 | ||
| 1054 | static int ocrdma_check_fw_config(struct ocrdma_dev *dev, | 1052 | static int ocrdma_check_fw_config(struct ocrdma_dev *dev, |
| @@ -1990,19 +1988,12 @@ static void ocrdma_get_create_qp_rsp(struct ocrdma_create_qp_rsp *rsp, | |||
| 1990 | max_wqe_allocated = 1 << max_wqe_allocated; | 1988 | max_wqe_allocated = 1 << max_wqe_allocated; |
| 1991 | max_rqe_allocated = 1 << ((u16)rsp->max_wqe_rqe); | 1989 | max_rqe_allocated = 1 << ((u16)rsp->max_wqe_rqe); |
| 1992 | 1990 | ||
| 1993 | if (qp->dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { | ||
| 1994 | qp->sq.free_delta = 0; | ||
| 1995 | qp->rq.free_delta = 1; | ||
| 1996 | } else | ||
| 1997 | qp->sq.free_delta = 1; | ||
| 1998 | |||
| 1999 | qp->sq.max_cnt = max_wqe_allocated; | 1991 | qp->sq.max_cnt = max_wqe_allocated; |
| 2000 | qp->sq.max_wqe_idx = max_wqe_allocated - 1; | 1992 | qp->sq.max_wqe_idx = max_wqe_allocated - 1; |
| 2001 | 1993 | ||
| 2002 | if (!attrs->srq) { | 1994 | if (!attrs->srq) { |
| 2003 | qp->rq.max_cnt = max_rqe_allocated; | 1995 | qp->rq.max_cnt = max_rqe_allocated; |
| 2004 | qp->rq.max_wqe_idx = max_rqe_allocated - 1; | 1996 | qp->rq.max_wqe_idx = max_rqe_allocated - 1; |
| 2005 | qp->rq.free_delta = 1; | ||
| 2006 | } | 1997 | } |
| 2007 | } | 1998 | } |
| 2008 | 1999 | ||
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c index a20d16eaae71..b050e629e9c3 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | *******************************************************************/ | 26 | *******************************************************************/ |
| 27 | 27 | ||
| 28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
| 29 | #include <linux/version.h> | ||
| 30 | #include <linux/idr.h> | 29 | #include <linux/idr.h> |
| 31 | #include <rdma/ib_verbs.h> | 30 | #include <rdma/ib_verbs.h> |
| 32 | #include <rdma/ib_user_verbs.h> | 31 | #include <rdma/ib_user_verbs.h> |
| @@ -98,13 +97,11 @@ static void ocrdma_build_sgid_mac(union ib_gid *sgid, unsigned char *mac_addr, | |||
| 98 | sgid->raw[15] = mac_addr[5]; | 97 | sgid->raw[15] = mac_addr[5]; |
| 99 | } | 98 | } |
| 100 | 99 | ||
| 101 | static void ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, | 100 | static bool ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, |
| 102 | bool is_vlan, u16 vlan_id) | 101 | bool is_vlan, u16 vlan_id) |
| 103 | { | 102 | { |
| 104 | int i; | 103 | int i; |
| 105 | bool found = false; | ||
| 106 | union ib_gid new_sgid; | 104 | union ib_gid new_sgid; |
| 107 | int free_idx = OCRDMA_MAX_SGID; | ||
| 108 | unsigned long flags; | 105 | unsigned long flags; |
| 109 | 106 | ||
| 110 | memset(&ocrdma_zero_sgid, 0, sizeof(union ib_gid)); | 107 | memset(&ocrdma_zero_sgid, 0, sizeof(union ib_gid)); |
| @@ -116,23 +113,19 @@ static void ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, | |||
| 116 | if (!memcmp(&dev->sgid_tbl[i], &ocrdma_zero_sgid, | 113 | if (!memcmp(&dev->sgid_tbl[i], &ocrdma_zero_sgid, |
| 117 | sizeof(union ib_gid))) { | 114 | sizeof(union ib_gid))) { |
| 118 | /* found free entry */ | 115 | /* found free entry */ |
| 119 | if (!found) { | 116 | memcpy(&dev->sgid_tbl[i], &new_sgid, |
| 120 | free_idx = i; | 117 | sizeof(union ib_gid)); |
| 121 | found = true; | 118 | spin_unlock_irqrestore(&dev->sgid_lock, flags); |
| 122 | break; | 119 | return true; |
| 123 | } | ||
| 124 | } else if (!memcmp(&dev->sgid_tbl[i], &new_sgid, | 120 | } else if (!memcmp(&dev->sgid_tbl[i], &new_sgid, |
| 125 | sizeof(union ib_gid))) { | 121 | sizeof(union ib_gid))) { |
| 126 | /* entry already present, no addition is required. */ | 122 | /* entry already present, no addition is required. */ |
| 127 | spin_unlock_irqrestore(&dev->sgid_lock, flags); | 123 | spin_unlock_irqrestore(&dev->sgid_lock, flags); |
| 128 | return; | 124 | return false; |
| 129 | } | 125 | } |
| 130 | } | 126 | } |
| 131 | /* if entry doesn't exist and if table has some space, add entry */ | ||
| 132 | if (found) | ||
| 133 | memcpy(&dev->sgid_tbl[free_idx], &new_sgid, | ||
| 134 | sizeof(union ib_gid)); | ||
| 135 | spin_unlock_irqrestore(&dev->sgid_lock, flags); | 127 | spin_unlock_irqrestore(&dev->sgid_lock, flags); |
| 128 | return false; | ||
| 136 | } | 129 | } |
| 137 | 130 | ||
| 138 | static bool ocrdma_del_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, | 131 | static bool ocrdma_del_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, |
| @@ -168,7 +161,8 @@ static void ocrdma_add_default_sgid(struct ocrdma_dev *dev) | |||
| 168 | ocrdma_get_guid(dev, &sgid->raw[8]); | 161 | ocrdma_get_guid(dev, &sgid->raw[8]); |
| 169 | } | 162 | } |
| 170 | 163 | ||
| 171 | static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) | 164 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) |
| 165 | static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) | ||
| 172 | { | 166 | { |
| 173 | struct net_device *netdev, *tmp; | 167 | struct net_device *netdev, *tmp; |
| 174 | u16 vlan_id; | 168 | u16 vlan_id; |
| @@ -176,8 +170,6 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) | |||
| 176 | 170 | ||
| 177 | netdev = dev->nic_info.netdev; | 171 | netdev = dev->nic_info.netdev; |
| 178 | 172 | ||
| 179 | ocrdma_add_default_sgid(dev); | ||
| 180 | |||
| 181 | rcu_read_lock(); | 173 | rcu_read_lock(); |
| 182 | for_each_netdev_rcu(&init_net, tmp) { | 174 | for_each_netdev_rcu(&init_net, tmp) { |
| 183 | if (netdev == tmp || vlan_dev_real_dev(tmp) == netdev) { | 175 | if (netdev == tmp || vlan_dev_real_dev(tmp) == netdev) { |
| @@ -195,10 +187,23 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) | |||
| 195 | } | 187 | } |
| 196 | } | 188 | } |
| 197 | rcu_read_unlock(); | 189 | rcu_read_unlock(); |
| 190 | } | ||
| 191 | #else | ||
| 192 | static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) | ||
| 193 | { | ||
| 194 | |||
| 195 | } | ||
| 196 | #endif /* VLAN */ | ||
| 197 | |||
| 198 | static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) | ||
| 199 | { | ||
| 200 | ocrdma_add_default_sgid(dev); | ||
| 201 | ocrdma_add_vlan_sgids(dev); | ||
| 198 | return 0; | 202 | return 0; |
| 199 | } | 203 | } |
| 200 | 204 | ||
| 201 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 205 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) || \ |
| 206 | defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | ||
| 202 | 207 | ||
| 203 | static int ocrdma_inet6addr_event(struct notifier_block *notifier, | 208 | static int ocrdma_inet6addr_event(struct notifier_block *notifier, |
| 204 | unsigned long event, void *ptr) | 209 | unsigned long event, void *ptr) |
| @@ -209,6 +214,7 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier, | |||
| 209 | struct ib_event gid_event; | 214 | struct ib_event gid_event; |
| 210 | struct ocrdma_dev *dev; | 215 | struct ocrdma_dev *dev; |
| 211 | bool found = false; | 216 | bool found = false; |
| 217 | bool updated = false; | ||
| 212 | bool is_vlan = false; | 218 | bool is_vlan = false; |
| 213 | u16 vid = 0; | 219 | u16 vid = 0; |
| 214 | 220 | ||
| @@ -234,23 +240,21 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier, | |||
| 234 | mutex_lock(&dev->dev_lock); | 240 | mutex_lock(&dev->dev_lock); |
| 235 | switch (event) { | 241 | switch (event) { |
| 236 | case NETDEV_UP: | 242 | case NETDEV_UP: |
| 237 | ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid); | 243 | updated = ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid); |
| 238 | break; | 244 | break; |
| 239 | case NETDEV_DOWN: | 245 | case NETDEV_DOWN: |
| 240 | found = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid); | 246 | updated = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid); |
| 241 | if (found) { | ||
| 242 | /* found the matching entry, notify | ||
| 243 | * the consumers about it | ||
| 244 | */ | ||
| 245 | gid_event.device = &dev->ibdev; | ||
| 246 | gid_event.element.port_num = 1; | ||
| 247 | gid_event.event = IB_EVENT_GID_CHANGE; | ||
| 248 | ib_dispatch_event(&gid_event); | ||
| 249 | } | ||
| 250 | break; | 247 | break; |
| 251 | default: | 248 | default: |
| 252 | break; | 249 | break; |
| 253 | } | 250 | } |
| 251 | if (updated) { | ||
| 252 | /* GID table updated, notify the consumers about it */ | ||
| 253 | gid_event.device = &dev->ibdev; | ||
| 254 | gid_event.element.port_num = 1; | ||
| 255 | gid_event.event = IB_EVENT_GID_CHANGE; | ||
| 256 | ib_dispatch_event(&gid_event); | ||
| 257 | } | ||
| 254 | mutex_unlock(&dev->dev_lock); | 258 | mutex_unlock(&dev->dev_lock); |
| 255 | return NOTIFY_OK; | 259 | return NOTIFY_OK; |
| 256 | } | 260 | } |
| @@ -259,7 +263,7 @@ static struct notifier_block ocrdma_inet6addr_notifier = { | |||
| 259 | .notifier_call = ocrdma_inet6addr_event | 263 | .notifier_call = ocrdma_inet6addr_event |
| 260 | }; | 264 | }; |
| 261 | 265 | ||
| 262 | #endif /* IPV6 */ | 266 | #endif /* IPV6 and VLAN */ |
| 263 | 267 | ||
| 264 | static enum rdma_link_layer ocrdma_link_layer(struct ib_device *device, | 268 | static enum rdma_link_layer ocrdma_link_layer(struct ib_device *device, |
| 265 | u8 port_num) | 269 | u8 port_num) |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h index 7fd80cc0f037..c75cbdfa87e7 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h | |||
| @@ -418,6 +418,9 @@ enum { | |||
| 418 | 418 | ||
| 419 | OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT = 0, | 419 | OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT = 0, |
| 420 | OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK = 0xFFFF, | 420 | OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK = 0xFFFF, |
| 421 | OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_SHIFT = 16, | ||
| 422 | OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_MASK = 0xFFFF << | ||
| 423 | OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_SHIFT, | ||
| 421 | 424 | ||
| 422 | OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT = 0, | 425 | OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT = 0, |
| 423 | OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK = 0xFFFF, | 426 | OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK = 0xFFFF, |
| @@ -458,7 +461,7 @@ enum { | |||
| 458 | OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET, | 461 | OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET, |
| 459 | OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_OFFSET = 0, | 462 | OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_OFFSET = 0, |
| 460 | OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_MASK = 0xFFFF << | 463 | OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_MASK = 0xFFFF << |
| 461 | OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET, | 464 | OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_OFFSET, |
| 462 | 465 | ||
| 463 | OCRDMA_MBX_QUERY_CFG_MAX_CQ_OFFSET = 16, | 466 | OCRDMA_MBX_QUERY_CFG_MAX_CQ_OFFSET = 16, |
| 464 | OCRDMA_MBX_QUERY_CFG_MAX_CQ_MASK = 0xFFFF << | 467 | OCRDMA_MBX_QUERY_CFG_MAX_CQ_MASK = 0xFFFF << |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index e9f74d1b48f6..2e2e7aecc990 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | |||
| @@ -53,7 +53,7 @@ int ocrdma_query_gid(struct ib_device *ibdev, u8 port, | |||
| 53 | 53 | ||
| 54 | dev = get_ocrdma_dev(ibdev); | 54 | dev = get_ocrdma_dev(ibdev); |
| 55 | memset(sgid, 0, sizeof(*sgid)); | 55 | memset(sgid, 0, sizeof(*sgid)); |
| 56 | if (index > OCRDMA_MAX_SGID) | 56 | if (index >= OCRDMA_MAX_SGID) |
| 57 | return -EINVAL; | 57 | return -EINVAL; |
| 58 | 58 | ||
| 59 | memcpy(sgid, &dev->sgid_tbl[index], sizeof(*sgid)); | 59 | memcpy(sgid, &dev->sgid_tbl[index], sizeof(*sgid)); |
| @@ -83,8 +83,8 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr) | |||
| 83 | IB_DEVICE_SHUTDOWN_PORT | | 83 | IB_DEVICE_SHUTDOWN_PORT | |
| 84 | IB_DEVICE_SYS_IMAGE_GUID | | 84 | IB_DEVICE_SYS_IMAGE_GUID | |
| 85 | IB_DEVICE_LOCAL_DMA_LKEY; | 85 | IB_DEVICE_LOCAL_DMA_LKEY; |
| 86 | attr->max_sge = dev->attr.max_send_sge; | 86 | attr->max_sge = min(dev->attr.max_send_sge, dev->attr.max_srq_sge); |
| 87 | attr->max_sge_rd = dev->attr.max_send_sge; | 87 | attr->max_sge_rd = 0; |
| 88 | attr->max_cq = dev->attr.max_cq; | 88 | attr->max_cq = dev->attr.max_cq; |
| 89 | attr->max_cqe = dev->attr.max_cqe; | 89 | attr->max_cqe = dev->attr.max_cqe; |
| 90 | attr->max_mr = dev->attr.max_mr; | 90 | attr->max_mr = dev->attr.max_mr; |
| @@ -97,7 +97,7 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr) | |||
| 97 | min(dev->attr.max_ord_per_qp, dev->attr.max_ird_per_qp); | 97 | min(dev->attr.max_ord_per_qp, dev->attr.max_ird_per_qp); |
| 98 | attr->max_qp_init_rd_atom = dev->attr.max_ord_per_qp; | 98 | attr->max_qp_init_rd_atom = dev->attr.max_ord_per_qp; |
| 99 | attr->max_srq = (dev->attr.max_qp - 1); | 99 | attr->max_srq = (dev->attr.max_qp - 1); |
| 100 | attr->max_srq_sge = attr->max_sge; | 100 | attr->max_srq_sge = attr->max_srq_sge; |
| 101 | attr->max_srq_wr = dev->attr.max_rqe; | 101 | attr->max_srq_wr = dev->attr.max_rqe; |
| 102 | attr->local_ca_ack_delay = dev->attr.local_ca_ack_delay; | 102 | attr->local_ca_ack_delay = dev->attr.local_ca_ack_delay; |
| 103 | attr->max_fast_reg_page_list_len = 0; | 103 | attr->max_fast_reg_page_list_len = 0; |
| @@ -940,8 +940,6 @@ static int ocrdma_copy_qp_uresp(struct ocrdma_qp *qp, | |||
| 940 | uresp.db_rq_offset = OCRDMA_DB_RQ_OFFSET; | 940 | uresp.db_rq_offset = OCRDMA_DB_RQ_OFFSET; |
| 941 | uresp.db_shift = 16; | 941 | uresp.db_shift = 16; |
| 942 | } | 942 | } |
| 943 | uresp.free_wqe_delta = qp->sq.free_delta; | ||
| 944 | uresp.free_rqe_delta = qp->rq.free_delta; | ||
| 945 | 943 | ||
| 946 | if (qp->dpp_enabled) { | 944 | if (qp->dpp_enabled) { |
| 947 | uresp.dpp_credit = dpp_credit_lmt; | 945 | uresp.dpp_credit = dpp_credit_lmt; |
| @@ -1307,8 +1305,6 @@ static int ocrdma_hwq_free_cnt(struct ocrdma_qp_hwq_info *q) | |||
| 1307 | free_cnt = (q->max_cnt - q->head) + q->tail; | 1305 | free_cnt = (q->max_cnt - q->head) + q->tail; |
| 1308 | else | 1306 | else |
| 1309 | free_cnt = q->tail - q->head; | 1307 | free_cnt = q->tail - q->head; |
| 1310 | if (q->free_delta) | ||
| 1311 | free_cnt -= q->free_delta; | ||
| 1312 | return free_cnt; | 1308 | return free_cnt; |
| 1313 | } | 1309 | } |
| 1314 | 1310 | ||
| @@ -1501,7 +1497,6 @@ static int ocrdma_copy_srq_uresp(struct ocrdma_srq *srq, struct ib_udata *udata) | |||
| 1501 | (srq->pd->id * srq->dev->nic_info.db_page_size); | 1497 | (srq->pd->id * srq->dev->nic_info.db_page_size); |
| 1502 | uresp.db_page_size = srq->dev->nic_info.db_page_size; | 1498 | uresp.db_page_size = srq->dev->nic_info.db_page_size; |
| 1503 | uresp.num_rqe_allocated = srq->rq.max_cnt; | 1499 | uresp.num_rqe_allocated = srq->rq.max_cnt; |
| 1504 | uresp.free_rqe_delta = 1; | ||
| 1505 | if (srq->dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { | 1500 | if (srq->dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { |
| 1506 | uresp.db_rq_offset = OCRDMA_DB_GEN2_RQ1_OFFSET; | 1501 | uresp.db_rq_offset = OCRDMA_DB_GEN2_RQ1_OFFSET; |
| 1507 | uresp.db_shift = 24; | 1502 | uresp.db_shift = 24; |
| @@ -2306,8 +2301,10 @@ static bool ocrdma_poll_err_rcqe(struct ocrdma_qp *qp, struct ocrdma_cqe *cqe, | |||
| 2306 | *stop = true; | 2301 | *stop = true; |
| 2307 | expand = false; | 2302 | expand = false; |
| 2308 | } | 2303 | } |
| 2309 | } else | 2304 | } else { |
| 2305 | *polled = true; | ||
| 2310 | expand = ocrdma_update_err_rcqe(ibwc, cqe, qp, status); | 2306 | expand = ocrdma_update_err_rcqe(ibwc, cqe, qp, status); |
| 2307 | } | ||
| 2311 | return expand; | 2308 | return expand; |
| 2312 | } | 2309 | } |
| 2313 | 2310 | ||
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h index e6483439f25f..633f03d80274 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h | |||
| @@ -28,7 +28,6 @@ | |||
| 28 | #ifndef __OCRDMA_VERBS_H__ | 28 | #ifndef __OCRDMA_VERBS_H__ |
| 29 | #define __OCRDMA_VERBS_H__ | 29 | #define __OCRDMA_VERBS_H__ |
| 30 | 30 | ||
| 31 | #include <linux/version.h> | ||
| 32 | int ocrdma_post_send(struct ib_qp *, struct ib_send_wr *, | 31 | int ocrdma_post_send(struct ib_qp *, struct ib_send_wr *, |
| 33 | struct ib_send_wr **bad_wr); | 32 | struct ib_send_wr **bad_wr); |
| 34 | int ocrdma_post_recv(struct ib_qp *, struct ib_recv_wr *, | 33 | int ocrdma_post_recv(struct ib_qp *, struct ib_recv_wr *, |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 5c1bc995e560..f10221f40803 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
| @@ -123,7 +123,7 @@ static void ipoib_ud_skb_put_frags(struct ipoib_dev_priv *priv, | |||
| 123 | 123 | ||
| 124 | skb_frag_size_set(frag, size); | 124 | skb_frag_size_set(frag, size); |
| 125 | skb->data_len += size; | 125 | skb->data_len += size; |
| 126 | skb->truesize += size; | 126 | skb->truesize += PAGE_SIZE; |
| 127 | } else | 127 | } else |
| 128 | skb_put(skb, length); | 128 | skb_put(skb, length); |
| 129 | 129 | ||
| @@ -156,14 +156,18 @@ static struct sk_buff *ipoib_alloc_rx_skb(struct net_device *dev, int id) | |||
| 156 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 156 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 157 | struct sk_buff *skb; | 157 | struct sk_buff *skb; |
| 158 | int buf_size; | 158 | int buf_size; |
| 159 | int tailroom; | ||
| 159 | u64 *mapping; | 160 | u64 *mapping; |
| 160 | 161 | ||
| 161 | if (ipoib_ud_need_sg(priv->max_ib_mtu)) | 162 | if (ipoib_ud_need_sg(priv->max_ib_mtu)) { |
| 162 | buf_size = IPOIB_UD_HEAD_SIZE; | 163 | buf_size = IPOIB_UD_HEAD_SIZE; |
| 163 | else | 164 | tailroom = 128; /* reserve some tailroom for IP/TCP headers */ |
| 165 | } else { | ||
| 164 | buf_size = IPOIB_UD_BUF_SIZE(priv->max_ib_mtu); | 166 | buf_size = IPOIB_UD_BUF_SIZE(priv->max_ib_mtu); |
| 167 | tailroom = 0; | ||
| 168 | } | ||
| 165 | 169 | ||
| 166 | skb = dev_alloc_skb(buf_size + 4); | 170 | skb = dev_alloc_skb(buf_size + tailroom + 4); |
| 167 | if (unlikely(!skb)) | 171 | if (unlikely(!skb)) |
| 168 | return NULL; | 172 | return NULL; |
| 169 | 173 | ||
