diff options
Diffstat (limited to 'drivers/infiniband')
78 files changed, 2177 insertions, 1738 deletions
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index c5c33d35f87d..5381c80de10a 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c | |||
@@ -161,8 +161,7 @@ static void addr_send_arp(struct sockaddr_in *dst_in) | |||
161 | if (ip_route_output_key(&rt, &fl)) | 161 | if (ip_route_output_key(&rt, &fl)) |
162 | return; | 162 | return; |
163 | 163 | ||
164 | arp_send(ARPOP_REQUEST, ETH_P_ARP, rt->rt_gateway, rt->idev->dev, | 164 | neigh_event_send(rt->u.dst.neighbour, NULL); |
165 | rt->rt_src, NULL, rt->idev->dev->dev_addr, NULL); | ||
166 | ip_rt_put(rt); | 165 | ip_rt_put(rt); |
167 | } | 166 | } |
168 | 167 | ||
diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c index db2633e4aae6..ae7c2880e624 100644 --- a/drivers/infiniband/core/agent.c +++ b/drivers/infiniband/core/agent.c | |||
@@ -78,15 +78,14 @@ ib_get_agent_port(struct ib_device *device, int port_num) | |||
78 | return entry; | 78 | return entry; |
79 | } | 79 | } |
80 | 80 | ||
81 | int agent_send_response(struct ib_mad *mad, struct ib_grh *grh, | 81 | void agent_send_response(struct ib_mad *mad, struct ib_grh *grh, |
82 | struct ib_wc *wc, struct ib_device *device, | 82 | struct ib_wc *wc, struct ib_device *device, |
83 | int port_num, int qpn) | 83 | int port_num, int qpn) |
84 | { | 84 | { |
85 | struct ib_agent_port_private *port_priv; | 85 | struct ib_agent_port_private *port_priv; |
86 | struct ib_mad_agent *agent; | 86 | struct ib_mad_agent *agent; |
87 | struct ib_mad_send_buf *send_buf; | 87 | struct ib_mad_send_buf *send_buf; |
88 | struct ib_ah *ah; | 88 | struct ib_ah *ah; |
89 | int ret; | ||
90 | struct ib_mad_send_wr_private *mad_send_wr; | 89 | struct ib_mad_send_wr_private *mad_send_wr; |
91 | 90 | ||
92 | if (device->node_type == RDMA_NODE_IB_SWITCH) | 91 | if (device->node_type == RDMA_NODE_IB_SWITCH) |
@@ -96,23 +95,21 @@ int agent_send_response(struct ib_mad *mad, struct ib_grh *grh, | |||
96 | 95 | ||
97 | if (!port_priv) { | 96 | if (!port_priv) { |
98 | printk(KERN_ERR SPFX "Unable to find port agent\n"); | 97 | printk(KERN_ERR SPFX "Unable to find port agent\n"); |
99 | return -ENODEV; | 98 | return; |
100 | } | 99 | } |
101 | 100 | ||
102 | agent = port_priv->agent[qpn]; | 101 | agent = port_priv->agent[qpn]; |
103 | ah = ib_create_ah_from_wc(agent->qp->pd, wc, grh, port_num); | 102 | ah = ib_create_ah_from_wc(agent->qp->pd, wc, grh, port_num); |
104 | if (IS_ERR(ah)) { | 103 | if (IS_ERR(ah)) { |
105 | ret = PTR_ERR(ah); | 104 | printk(KERN_ERR SPFX "ib_create_ah_from_wc error\n"); |
106 | printk(KERN_ERR SPFX "ib_create_ah_from_wc error:%d\n", ret); | 105 | return; |
107 | return ret; | ||
108 | } | 106 | } |
109 | 107 | ||
110 | send_buf = ib_create_send_mad(agent, wc->src_qp, wc->pkey_index, 0, | 108 | send_buf = ib_create_send_mad(agent, wc->src_qp, wc->pkey_index, 0, |
111 | IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA, | 109 | IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA, |
112 | GFP_KERNEL); | 110 | GFP_KERNEL); |
113 | if (IS_ERR(send_buf)) { | 111 | if (IS_ERR(send_buf)) { |
114 | ret = PTR_ERR(send_buf); | 112 | printk(KERN_ERR SPFX "ib_create_send_mad error\n"); |
115 | printk(KERN_ERR SPFX "ib_create_send_mad error:%d\n", ret); | ||
116 | goto err1; | 113 | goto err1; |
117 | } | 114 | } |
118 | 115 | ||
@@ -126,16 +123,15 @@ int agent_send_response(struct ib_mad *mad, struct ib_grh *grh, | |||
126 | mad_send_wr->send_wr.wr.ud.port_num = port_num; | 123 | mad_send_wr->send_wr.wr.ud.port_num = port_num; |
127 | } | 124 | } |
128 | 125 | ||
129 | if ((ret = ib_post_send_mad(send_buf, NULL))) { | 126 | if (ib_post_send_mad(send_buf, NULL)) { |
130 | printk(KERN_ERR SPFX "ib_post_send_mad error:%d\n", ret); | 127 | printk(KERN_ERR SPFX "ib_post_send_mad error\n"); |
131 | goto err2; | 128 | goto err2; |
132 | } | 129 | } |
133 | return 0; | 130 | return; |
134 | err2: | 131 | err2: |
135 | ib_free_send_mad(send_buf); | 132 | ib_free_send_mad(send_buf); |
136 | err1: | 133 | err1: |
137 | ib_destroy_ah(ah); | 134 | ib_destroy_ah(ah); |
138 | return ret; | ||
139 | } | 135 | } |
140 | 136 | ||
141 | static void agent_send_handler(struct ib_mad_agent *mad_agent, | 137 | static void agent_send_handler(struct ib_mad_agent *mad_agent, |
diff --git a/drivers/infiniband/core/agent.h b/drivers/infiniband/core/agent.h index 86d72fab37b0..fb9ed1489f95 100644 --- a/drivers/infiniband/core/agent.h +++ b/drivers/infiniband/core/agent.h | |||
@@ -46,8 +46,8 @@ extern int ib_agent_port_open(struct ib_device *device, int port_num); | |||
46 | 46 | ||
47 | extern int ib_agent_port_close(struct ib_device *device, int port_num); | 47 | extern int ib_agent_port_close(struct ib_device *device, int port_num); |
48 | 48 | ||
49 | extern int agent_send_response(struct ib_mad *mad, struct ib_grh *grh, | 49 | extern void agent_send_response(struct ib_mad *mad, struct ib_grh *grh, |
50 | struct ib_wc *wc, struct ib_device *device, | 50 | struct ib_wc *wc, struct ib_device *device, |
51 | int port_num, int qpn); | 51 | int port_num, int qpn); |
52 | 52 | ||
53 | #endif /* __AGENT_H_ */ | 53 | #endif /* __AGENT_H_ */ |
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 4df269f5d9ac..2e39236d189f 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c | |||
@@ -2219,6 +2219,9 @@ int ib_send_cm_mra(struct ib_cm_id *cm_id, | |||
2219 | { | 2219 | { |
2220 | struct cm_id_private *cm_id_priv; | 2220 | struct cm_id_private *cm_id_priv; |
2221 | struct ib_mad_send_buf *msg; | 2221 | struct ib_mad_send_buf *msg; |
2222 | enum ib_cm_state cm_state; | ||
2223 | enum ib_cm_lap_state lap_state; | ||
2224 | enum cm_msg_response msg_response; | ||
2222 | void *data; | 2225 | void *data; |
2223 | unsigned long flags; | 2226 | unsigned long flags; |
2224 | int ret; | 2227 | int ret; |
@@ -2235,48 +2238,40 @@ int ib_send_cm_mra(struct ib_cm_id *cm_id, | |||
2235 | spin_lock_irqsave(&cm_id_priv->lock, flags); | 2238 | spin_lock_irqsave(&cm_id_priv->lock, flags); |
2236 | switch(cm_id_priv->id.state) { | 2239 | switch(cm_id_priv->id.state) { |
2237 | case IB_CM_REQ_RCVD: | 2240 | case IB_CM_REQ_RCVD: |
2238 | ret = cm_alloc_msg(cm_id_priv, &msg); | 2241 | cm_state = IB_CM_MRA_REQ_SENT; |
2239 | if (ret) | 2242 | lap_state = cm_id->lap_state; |
2240 | goto error1; | 2243 | msg_response = CM_MSG_RESPONSE_REQ; |
2241 | |||
2242 | cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv, | ||
2243 | CM_MSG_RESPONSE_REQ, service_timeout, | ||
2244 | private_data, private_data_len); | ||
2245 | ret = ib_post_send_mad(msg, NULL); | ||
2246 | if (ret) | ||
2247 | goto error2; | ||
2248 | cm_id->state = IB_CM_MRA_REQ_SENT; | ||
2249 | break; | 2244 | break; |
2250 | case IB_CM_REP_RCVD: | 2245 | case IB_CM_REP_RCVD: |
2251 | ret = cm_alloc_msg(cm_id_priv, &msg); | 2246 | cm_state = IB_CM_MRA_REP_SENT; |
2252 | if (ret) | 2247 | lap_state = cm_id->lap_state; |
2253 | goto error1; | 2248 | msg_response = CM_MSG_RESPONSE_REP; |
2254 | |||
2255 | cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv, | ||
2256 | CM_MSG_RESPONSE_REP, service_timeout, | ||
2257 | private_data, private_data_len); | ||
2258 | ret = ib_post_send_mad(msg, NULL); | ||
2259 | if (ret) | ||
2260 | goto error2; | ||
2261 | cm_id->state = IB_CM_MRA_REP_SENT; | ||
2262 | break; | 2249 | break; |
2263 | case IB_CM_ESTABLISHED: | 2250 | case IB_CM_ESTABLISHED: |
2251 | cm_state = cm_id->state; | ||
2252 | lap_state = IB_CM_MRA_LAP_SENT; | ||
2253 | msg_response = CM_MSG_RESPONSE_OTHER; | ||
2254 | break; | ||
2255 | default: | ||
2256 | ret = -EINVAL; | ||
2257 | goto error1; | ||
2258 | } | ||
2259 | |||
2260 | if (!(service_timeout & IB_CM_MRA_FLAG_DELAY)) { | ||
2264 | ret = cm_alloc_msg(cm_id_priv, &msg); | 2261 | ret = cm_alloc_msg(cm_id_priv, &msg); |
2265 | if (ret) | 2262 | if (ret) |
2266 | goto error1; | 2263 | goto error1; |
2267 | 2264 | ||
2268 | cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv, | 2265 | cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv, |
2269 | CM_MSG_RESPONSE_OTHER, service_timeout, | 2266 | msg_response, service_timeout, |
2270 | private_data, private_data_len); | 2267 | private_data, private_data_len); |
2271 | ret = ib_post_send_mad(msg, NULL); | 2268 | ret = ib_post_send_mad(msg, NULL); |
2272 | if (ret) | 2269 | if (ret) |
2273 | goto error2; | 2270 | goto error2; |
2274 | cm_id->lap_state = IB_CM_MRA_LAP_SENT; | ||
2275 | break; | ||
2276 | default: | ||
2277 | ret = -EINVAL; | ||
2278 | goto error1; | ||
2279 | } | 2271 | } |
2272 | |||
2273 | cm_id->state = cm_state; | ||
2274 | cm_id->lap_state = lap_state; | ||
2280 | cm_id_priv->service_timeout = service_timeout; | 2275 | cm_id_priv->service_timeout = service_timeout; |
2281 | cm_set_private_data(cm_id_priv, data, private_data_len); | 2276 | cm_set_private_data(cm_id_priv, data, private_data_len); |
2282 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); | 2277 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 9ffb9987450a..93644f82592c 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
@@ -52,6 +52,7 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
52 | 52 | ||
53 | #define CMA_CM_RESPONSE_TIMEOUT 20 | 53 | #define CMA_CM_RESPONSE_TIMEOUT 20 |
54 | #define CMA_MAX_CM_RETRIES 15 | 54 | #define CMA_MAX_CM_RETRIES 15 |
55 | #define CMA_CM_MRA_SETTING (IB_CM_MRA_FLAG_DELAY | 24) | ||
55 | 56 | ||
56 | static void cma_add_one(struct ib_device *device); | 57 | static void cma_add_one(struct ib_device *device); |
57 | static void cma_remove_one(struct ib_device *device); | 58 | static void cma_remove_one(struct ib_device *device); |
@@ -138,6 +139,7 @@ struct rdma_id_private { | |||
138 | u32 qkey; | 139 | u32 qkey; |
139 | u32 qp_num; | 140 | u32 qp_num; |
140 | u8 srq; | 141 | u8 srq; |
142 | u8 tos; | ||
141 | }; | 143 | }; |
142 | 144 | ||
143 | struct cma_multicast { | 145 | struct cma_multicast { |
@@ -1089,6 +1091,7 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) | |||
1089 | event.param.ud.private_data_len = | 1091 | event.param.ud.private_data_len = |
1090 | IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE - offset; | 1092 | IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE - offset; |
1091 | } else { | 1093 | } else { |
1094 | ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0); | ||
1092 | conn_id = cma_new_conn_id(&listen_id->id, ib_event); | 1095 | conn_id = cma_new_conn_id(&listen_id->id, ib_event); |
1093 | cma_set_req_event_data(&event, &ib_event->param.req_rcvd, | 1096 | cma_set_req_event_data(&event, &ib_event->param.req_rcvd, |
1094 | ib_event->private_data, offset); | 1097 | ib_event->private_data, offset); |
@@ -1474,6 +1477,15 @@ err: | |||
1474 | } | 1477 | } |
1475 | EXPORT_SYMBOL(rdma_listen); | 1478 | EXPORT_SYMBOL(rdma_listen); |
1476 | 1479 | ||
1480 | void rdma_set_service_type(struct rdma_cm_id *id, int tos) | ||
1481 | { | ||
1482 | struct rdma_id_private *id_priv; | ||
1483 | |||
1484 | id_priv = container_of(id, struct rdma_id_private, id); | ||
1485 | id_priv->tos = (u8) tos; | ||
1486 | } | ||
1487 | EXPORT_SYMBOL(rdma_set_service_type); | ||
1488 | |||
1477 | static void cma_query_handler(int status, struct ib_sa_path_rec *path_rec, | 1489 | static void cma_query_handler(int status, struct ib_sa_path_rec *path_rec, |
1478 | void *context) | 1490 | void *context) |
1479 | { | 1491 | { |
@@ -1498,23 +1510,37 @@ static void cma_query_handler(int status, struct ib_sa_path_rec *path_rec, | |||
1498 | static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms, | 1510 | static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms, |
1499 | struct cma_work *work) | 1511 | struct cma_work *work) |
1500 | { | 1512 | { |
1501 | struct rdma_dev_addr *addr = &id_priv->id.route.addr.dev_addr; | 1513 | struct rdma_addr *addr = &id_priv->id.route.addr; |
1502 | struct ib_sa_path_rec path_rec; | 1514 | struct ib_sa_path_rec path_rec; |
1515 | ib_sa_comp_mask comp_mask; | ||
1516 | struct sockaddr_in6 *sin6; | ||
1503 | 1517 | ||
1504 | memset(&path_rec, 0, sizeof path_rec); | 1518 | memset(&path_rec, 0, sizeof path_rec); |
1505 | ib_addr_get_sgid(addr, &path_rec.sgid); | 1519 | ib_addr_get_sgid(&addr->dev_addr, &path_rec.sgid); |
1506 | ib_addr_get_dgid(addr, &path_rec.dgid); | 1520 | ib_addr_get_dgid(&addr->dev_addr, &path_rec.dgid); |
1507 | path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(addr)); | 1521 | path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(&addr->dev_addr)); |
1508 | path_rec.numb_path = 1; | 1522 | path_rec.numb_path = 1; |
1509 | path_rec.reversible = 1; | 1523 | path_rec.reversible = 1; |
1524 | path_rec.service_id = cma_get_service_id(id_priv->id.ps, &addr->dst_addr); | ||
1525 | |||
1526 | comp_mask = IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID | | ||
1527 | IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH | | ||
1528 | IB_SA_PATH_REC_REVERSIBLE | IB_SA_PATH_REC_SERVICE_ID; | ||
1529 | |||
1530 | if (addr->src_addr.sa_family == AF_INET) { | ||
1531 | path_rec.qos_class = cpu_to_be16((u16) id_priv->tos); | ||
1532 | comp_mask |= IB_SA_PATH_REC_QOS_CLASS; | ||
1533 | } else { | ||
1534 | sin6 = (struct sockaddr_in6 *) &addr->src_addr; | ||
1535 | path_rec.traffic_class = (u8) (be32_to_cpu(sin6->sin6_flowinfo) >> 20); | ||
1536 | comp_mask |= IB_SA_PATH_REC_TRAFFIC_CLASS; | ||
1537 | } | ||
1510 | 1538 | ||
1511 | id_priv->query_id = ib_sa_path_rec_get(&sa_client, id_priv->id.device, | 1539 | id_priv->query_id = ib_sa_path_rec_get(&sa_client, id_priv->id.device, |
1512 | id_priv->id.port_num, &path_rec, | 1540 | id_priv->id.port_num, &path_rec, |
1513 | IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID | | 1541 | comp_mask, timeout_ms, |
1514 | IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH | | 1542 | GFP_KERNEL, cma_query_handler, |
1515 | IB_SA_PATH_REC_REVERSIBLE, | 1543 | work, &id_priv->query); |
1516 | timeout_ms, GFP_KERNEL, | ||
1517 | cma_query_handler, work, &id_priv->query); | ||
1518 | 1544 | ||
1519 | return (id_priv->query_id < 0) ? id_priv->query_id : 0; | 1545 | return (id_priv->query_id < 0) ? id_priv->query_id : 0; |
1520 | } | 1546 | } |
@@ -1866,13 +1892,14 @@ err1: | |||
1866 | static int cma_alloc_any_port(struct idr *ps, struct rdma_id_private *id_priv) | 1892 | static int cma_alloc_any_port(struct idr *ps, struct rdma_id_private *id_priv) |
1867 | { | 1893 | { |
1868 | struct rdma_bind_list *bind_list; | 1894 | struct rdma_bind_list *bind_list; |
1869 | int port, ret; | 1895 | int port, ret, low, high; |
1870 | 1896 | ||
1871 | bind_list = kzalloc(sizeof *bind_list, GFP_KERNEL); | 1897 | bind_list = kzalloc(sizeof *bind_list, GFP_KERNEL); |
1872 | if (!bind_list) | 1898 | if (!bind_list) |
1873 | return -ENOMEM; | 1899 | return -ENOMEM; |
1874 | 1900 | ||
1875 | retry: | 1901 | retry: |
1902 | /* FIXME: add proper port randomization per like inet_csk_get_port */ | ||
1876 | do { | 1903 | do { |
1877 | ret = idr_get_new_above(ps, bind_list, next_port, &port); | 1904 | ret = idr_get_new_above(ps, bind_list, next_port, &port); |
1878 | } while ((ret == -EAGAIN) && idr_pre_get(ps, GFP_KERNEL)); | 1905 | } while ((ret == -EAGAIN) && idr_pre_get(ps, GFP_KERNEL)); |
@@ -1880,18 +1907,19 @@ retry: | |||
1880 | if (ret) | 1907 | if (ret) |
1881 | goto err1; | 1908 | goto err1; |
1882 | 1909 | ||
1883 | if (port > sysctl_local_port_range[1]) { | 1910 | inet_get_local_port_range(&low, &high); |
1884 | if (next_port != sysctl_local_port_range[0]) { | 1911 | if (port > high) { |
1912 | if (next_port != low) { | ||
1885 | idr_remove(ps, port); | 1913 | idr_remove(ps, port); |
1886 | next_port = sysctl_local_port_range[0]; | 1914 | next_port = low; |
1887 | goto retry; | 1915 | goto retry; |
1888 | } | 1916 | } |
1889 | ret = -EADDRNOTAVAIL; | 1917 | ret = -EADDRNOTAVAIL; |
1890 | goto err2; | 1918 | goto err2; |
1891 | } | 1919 | } |
1892 | 1920 | ||
1893 | if (port == sysctl_local_port_range[1]) | 1921 | if (port == high) |
1894 | next_port = sysctl_local_port_range[0]; | 1922 | next_port = low; |
1895 | else | 1923 | else |
1896 | next_port = port + 1; | 1924 | next_port = port + 1; |
1897 | 1925 | ||
@@ -2769,12 +2797,12 @@ static void cma_remove_one(struct ib_device *device) | |||
2769 | 2797 | ||
2770 | static int cma_init(void) | 2798 | static int cma_init(void) |
2771 | { | 2799 | { |
2772 | int ret; | 2800 | int ret, low, high; |
2773 | 2801 | ||
2774 | get_random_bytes(&next_port, sizeof next_port); | 2802 | get_random_bytes(&next_port, sizeof next_port); |
2775 | next_port = ((unsigned int) next_port % | 2803 | inet_get_local_port_range(&low, &high); |
2776 | (sysctl_local_port_range[1] - sysctl_local_port_range[0])) + | 2804 | next_port = ((unsigned int) next_port % (high - low)) + low; |
2777 | sysctl_local_port_range[0]; | 2805 | |
2778 | cma_wq = create_singlethread_workqueue("rdma_cm"); | 2806 | cma_wq = create_singlethread_workqueue("rdma_cm"); |
2779 | if (!cma_wq) | 2807 | if (!cma_wq) |
2780 | return -ENOMEM; | 2808 | return -ENOMEM; |
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 3ada17c0f239..5ac5ffee05cb 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c | |||
@@ -120,12 +120,12 @@ static struct ib_device *__ib_device_get_by_name(const char *name) | |||
120 | 120 | ||
121 | static int alloc_name(char *name) | 121 | static int alloc_name(char *name) |
122 | { | 122 | { |
123 | long *inuse; | 123 | unsigned long *inuse; |
124 | char buf[IB_DEVICE_NAME_MAX]; | 124 | char buf[IB_DEVICE_NAME_MAX]; |
125 | struct ib_device *device; | 125 | struct ib_device *device; |
126 | int i; | 126 | int i; |
127 | 127 | ||
128 | inuse = (long *) get_zeroed_page(GFP_KERNEL); | 128 | inuse = (unsigned long *) get_zeroed_page(GFP_KERNEL); |
129 | if (!inuse) | 129 | if (!inuse) |
130 | return -ENOMEM; | 130 | return -ENOMEM; |
131 | 131 | ||
@@ -702,7 +702,7 @@ int ib_find_pkey(struct ib_device *device, | |||
702 | if (ret) | 702 | if (ret) |
703 | return ret; | 703 | return ret; |
704 | 704 | ||
705 | if (pkey == tmp_pkey) { | 705 | if ((pkey & 0x7fff) == (tmp_pkey & 0x7fff)) { |
706 | *index = i; | 706 | *index = i; |
707 | return 0; | 707 | return 0; |
708 | } | 708 | } |
diff --git a/drivers/infiniband/core/fmr_pool.c b/drivers/infiniband/core/fmr_pool.c index a06bcc65a871..d7f64525469b 100644 --- a/drivers/infiniband/core/fmr_pool.c +++ b/drivers/infiniband/core/fmr_pool.c | |||
@@ -152,7 +152,7 @@ static void ib_fmr_batch_release(struct ib_fmr_pool *pool) | |||
152 | 152 | ||
153 | #ifdef DEBUG | 153 | #ifdef DEBUG |
154 | if (fmr->ref_count !=0) { | 154 | if (fmr->ref_count !=0) { |
155 | printk(KERN_WARNING PFX "Unmapping FMR 0x%08x with ref count %d", | 155 | printk(KERN_WARNING PFX "Unmapping FMR 0x%08x with ref count %d\n", |
156 | fmr, fmr->ref_count); | 156 | fmr, fmr->ref_count); |
157 | } | 157 | } |
158 | #endif | 158 | #endif |
@@ -170,7 +170,7 @@ static void ib_fmr_batch_release(struct ib_fmr_pool *pool) | |||
170 | 170 | ||
171 | ret = ib_unmap_fmr(&fmr_list); | 171 | ret = ib_unmap_fmr(&fmr_list); |
172 | if (ret) | 172 | if (ret) |
173 | printk(KERN_WARNING PFX "ib_unmap_fmr returned %d", ret); | 173 | printk(KERN_WARNING PFX "ib_unmap_fmr returned %d\n", ret); |
174 | 174 | ||
175 | spin_lock_irq(&pool->pool_lock); | 175 | spin_lock_irq(&pool->pool_lock); |
176 | list_splice(&unmap_list, &pool->free_list); | 176 | list_splice(&unmap_list, &pool->free_list); |
@@ -235,13 +235,13 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd, | |||
235 | 235 | ||
236 | attr = kmalloc(sizeof *attr, GFP_KERNEL); | 236 | attr = kmalloc(sizeof *attr, GFP_KERNEL); |
237 | if (!attr) { | 237 | if (!attr) { |
238 | printk(KERN_WARNING PFX "couldn't allocate device attr struct"); | 238 | printk(KERN_WARNING PFX "couldn't allocate device attr struct\n"); |
239 | return ERR_PTR(-ENOMEM); | 239 | return ERR_PTR(-ENOMEM); |
240 | } | 240 | } |
241 | 241 | ||
242 | ret = ib_query_device(device, attr); | 242 | ret = ib_query_device(device, attr); |
243 | if (ret) { | 243 | if (ret) { |
244 | printk(KERN_WARNING PFX "couldn't query device: %d", ret); | 244 | printk(KERN_WARNING PFX "couldn't query device: %d\n", ret); |
245 | kfree(attr); | 245 | kfree(attr); |
246 | return ERR_PTR(ret); | 246 | return ERR_PTR(ret); |
247 | } | 247 | } |
@@ -255,7 +255,7 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd, | |||
255 | 255 | ||
256 | pool = kmalloc(sizeof *pool, GFP_KERNEL); | 256 | pool = kmalloc(sizeof *pool, GFP_KERNEL); |
257 | if (!pool) { | 257 | if (!pool) { |
258 | printk(KERN_WARNING PFX "couldn't allocate pool struct"); | 258 | printk(KERN_WARNING PFX "couldn't allocate pool struct\n"); |
259 | return ERR_PTR(-ENOMEM); | 259 | return ERR_PTR(-ENOMEM); |
260 | } | 260 | } |
261 | 261 | ||
@@ -272,7 +272,7 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd, | |||
272 | kmalloc(IB_FMR_HASH_SIZE * sizeof *pool->cache_bucket, | 272 | kmalloc(IB_FMR_HASH_SIZE * sizeof *pool->cache_bucket, |
273 | GFP_KERNEL); | 273 | GFP_KERNEL); |
274 | if (!pool->cache_bucket) { | 274 | if (!pool->cache_bucket) { |
275 | printk(KERN_WARNING PFX "Failed to allocate cache in pool"); | 275 | printk(KERN_WARNING PFX "Failed to allocate cache in pool\n"); |
276 | ret = -ENOMEM; | 276 | ret = -ENOMEM; |
277 | goto out_free_pool; | 277 | goto out_free_pool; |
278 | } | 278 | } |
@@ -296,7 +296,7 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd, | |||
296 | "ib_fmr(%s)", | 296 | "ib_fmr(%s)", |
297 | device->name); | 297 | device->name); |
298 | if (IS_ERR(pool->thread)) { | 298 | if (IS_ERR(pool->thread)) { |
299 | printk(KERN_WARNING PFX "couldn't start cleanup thread"); | 299 | printk(KERN_WARNING PFX "couldn't start cleanup thread\n"); |
300 | ret = PTR_ERR(pool->thread); | 300 | ret = PTR_ERR(pool->thread); |
301 | goto out_free_pool; | 301 | goto out_free_pool; |
302 | } | 302 | } |
@@ -314,7 +314,7 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd, | |||
314 | GFP_KERNEL); | 314 | GFP_KERNEL); |
315 | if (!fmr) { | 315 | if (!fmr) { |
316 | printk(KERN_WARNING PFX "failed to allocate fmr " | 316 | printk(KERN_WARNING PFX "failed to allocate fmr " |
317 | "struct for FMR %d", i); | 317 | "struct for FMR %d\n", i); |
318 | goto out_fail; | 318 | goto out_fail; |
319 | } | 319 | } |
320 | 320 | ||
@@ -326,7 +326,7 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd, | |||
326 | fmr->fmr = ib_alloc_fmr(pd, params->access, &fmr_attr); | 326 | fmr->fmr = ib_alloc_fmr(pd, params->access, &fmr_attr); |
327 | if (IS_ERR(fmr->fmr)) { | 327 | if (IS_ERR(fmr->fmr)) { |
328 | printk(KERN_WARNING PFX "fmr_create failed " | 328 | printk(KERN_WARNING PFX "fmr_create failed " |
329 | "for FMR %d", i); | 329 | "for FMR %d\n", i); |
330 | kfree(fmr); | 330 | kfree(fmr); |
331 | goto out_fail; | 331 | goto out_fail; |
332 | } | 332 | } |
@@ -381,7 +381,7 @@ void ib_destroy_fmr_pool(struct ib_fmr_pool *pool) | |||
381 | } | 381 | } |
382 | 382 | ||
383 | if (i < pool->pool_size) | 383 | if (i < pool->pool_size) |
384 | printk(KERN_WARNING PFX "pool still has %d regions registered", | 384 | printk(KERN_WARNING PFX "pool still has %d regions registered\n", |
385 | pool->pool_size - i); | 385 | pool->pool_size - i); |
386 | 386 | ||
387 | kfree(pool->cache_bucket); | 387 | kfree(pool->cache_bucket); |
@@ -518,7 +518,7 @@ int ib_fmr_pool_unmap(struct ib_pool_fmr *fmr) | |||
518 | 518 | ||
519 | #ifdef DEBUG | 519 | #ifdef DEBUG |
520 | if (fmr->ref_count < 0) | 520 | if (fmr->ref_count < 0) |
521 | printk(KERN_WARNING PFX "FMR %p has ref count %d < 0", | 521 | printk(KERN_WARNING PFX "FMR %p has ref count %d < 0\n", |
522 | fmr, fmr->ref_count); | 522 | fmr, fmr->ref_count); |
523 | #endif | 523 | #endif |
524 | 524 | ||
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index bc547f1d34ba..6f4287716ab1 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
@@ -1842,16 +1842,11 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, | |||
1842 | { | 1842 | { |
1843 | struct ib_mad_qp_info *qp_info; | 1843 | struct ib_mad_qp_info *qp_info; |
1844 | struct ib_mad_private_header *mad_priv_hdr; | 1844 | struct ib_mad_private_header *mad_priv_hdr; |
1845 | struct ib_mad_private *recv, *response; | 1845 | struct ib_mad_private *recv, *response = NULL; |
1846 | struct ib_mad_list_head *mad_list; | 1846 | struct ib_mad_list_head *mad_list; |
1847 | struct ib_mad_agent_private *mad_agent; | 1847 | struct ib_mad_agent_private *mad_agent; |
1848 | int port_num; | 1848 | int port_num; |
1849 | 1849 | ||
1850 | response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL); | ||
1851 | if (!response) | ||
1852 | printk(KERN_ERR PFX "ib_mad_recv_done_handler no memory " | ||
1853 | "for response buffer\n"); | ||
1854 | |||
1855 | mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id; | 1850 | mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id; |
1856 | qp_info = mad_list->mad_queue->qp_info; | 1851 | qp_info = mad_list->mad_queue->qp_info; |
1857 | dequeue_mad(mad_list); | 1852 | dequeue_mad(mad_list); |
@@ -1879,6 +1874,13 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, | |||
1879 | if (!validate_mad(&recv->mad.mad, qp_info->qp->qp_num)) | 1874 | if (!validate_mad(&recv->mad.mad, qp_info->qp->qp_num)) |
1880 | goto out; | 1875 | goto out; |
1881 | 1876 | ||
1877 | response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL); | ||
1878 | if (!response) { | ||
1879 | printk(KERN_ERR PFX "ib_mad_recv_done_handler no memory " | ||
1880 | "for response buffer\n"); | ||
1881 | goto out; | ||
1882 | } | ||
1883 | |||
1882 | if (port_priv->device->node_type == RDMA_NODE_IB_SWITCH) | 1884 | if (port_priv->device->node_type == RDMA_NODE_IB_SWITCH) |
1883 | port_num = wc->port_num; | 1885 | port_num = wc->port_num; |
1884 | else | 1886 | else |
@@ -1914,12 +1916,11 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, | |||
1914 | response->header.recv_wc.recv_buf.mad = &response->mad.mad; | 1916 | response->header.recv_wc.recv_buf.mad = &response->mad.mad; |
1915 | response->header.recv_wc.recv_buf.grh = &response->grh; | 1917 | response->header.recv_wc.recv_buf.grh = &response->grh; |
1916 | 1918 | ||
1917 | if (!agent_send_response(&response->mad.mad, | 1919 | agent_send_response(&response->mad.mad, |
1918 | &response->grh, wc, | 1920 | &response->grh, wc, |
1919 | port_priv->device, | 1921 | port_priv->device, |
1920 | smi_get_fwd_port(&recv->mad.smp), | 1922 | smi_get_fwd_port(&recv->mad.smp), |
1921 | qp_info->qp->qp_num)) | 1923 | qp_info->qp->qp_num); |
1922 | response = NULL; | ||
1923 | 1924 | ||
1924 | goto out; | 1925 | goto out; |
1925 | } | 1926 | } |
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c index 3663fd7022be..d43bc62005b3 100644 --- a/drivers/infiniband/core/mad_rmpp.c +++ b/drivers/infiniband/core/mad_rmpp.c | |||
@@ -163,8 +163,10 @@ static struct ib_mad_send_buf *alloc_response_msg(struct ib_mad_agent *agent, | |||
163 | hdr_len, 0, GFP_KERNEL); | 163 | hdr_len, 0, GFP_KERNEL); |
164 | if (IS_ERR(msg)) | 164 | if (IS_ERR(msg)) |
165 | ib_destroy_ah(ah); | 165 | ib_destroy_ah(ah); |
166 | else | 166 | else { |
167 | msg->ah = ah; | 167 | msg->ah = ah; |
168 | msg->context[0] = ah; | ||
169 | } | ||
168 | 170 | ||
169 | return msg; | 171 | return msg; |
170 | } | 172 | } |
@@ -197,9 +199,7 @@ static void ack_ds_ack(struct ib_mad_agent_private *agent, | |||
197 | 199 | ||
198 | void ib_rmpp_send_handler(struct ib_mad_send_wc *mad_send_wc) | 200 | void ib_rmpp_send_handler(struct ib_mad_send_wc *mad_send_wc) |
199 | { | 201 | { |
200 | struct ib_rmpp_mad *rmpp_mad = mad_send_wc->send_buf->mad; | 202 | if (mad_send_wc->send_buf->context[0] == mad_send_wc->send_buf->ah) |
201 | |||
202 | if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_ACK) | ||
203 | ib_destroy_ah(mad_send_wc->send_buf->ah); | 203 | ib_destroy_ah(mad_send_wc->send_buf->ah); |
204 | ib_free_send_mad(mad_send_wc->send_buf); | 204 | ib_free_send_mad(mad_send_wc->send_buf); |
205 | } | 205 | } |
diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/multicast.c index 15b4c4d3606d..1bc1fe605282 100644 --- a/drivers/infiniband/core/multicast.c +++ b/drivers/infiniband/core/multicast.c | |||
@@ -196,7 +196,7 @@ static void queue_join(struct mcast_member *member) | |||
196 | unsigned long flags; | 196 | unsigned long flags; |
197 | 197 | ||
198 | spin_lock_irqsave(&group->lock, flags); | 198 | spin_lock_irqsave(&group->lock, flags); |
199 | list_add(&member->list, &group->pending_list); | 199 | list_add_tail(&member->list, &group->pending_list); |
200 | if (group->state == MCAST_IDLE) { | 200 | if (group->state == MCAST_IDLE) { |
201 | group->state = MCAST_BUSY; | 201 | group->state = MCAST_BUSY; |
202 | atomic_inc(&group->refcount); | 202 | atomic_inc(&group->refcount); |
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 20ab6b3e484d..cf474ec27070 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c | |||
@@ -123,14 +123,10 @@ static u32 tid; | |||
123 | .field_name = "sa_path_rec:" #field | 123 | .field_name = "sa_path_rec:" #field |
124 | 124 | ||
125 | static const struct ib_field path_rec_table[] = { | 125 | static const struct ib_field path_rec_table[] = { |
126 | { RESERVED, | 126 | { PATH_REC_FIELD(service_id), |
127 | .offset_words = 0, | 127 | .offset_words = 0, |
128 | .offset_bits = 0, | 128 | .offset_bits = 0, |
129 | .size_bits = 32 }, | 129 | .size_bits = 64 }, |
130 | { RESERVED, | ||
131 | .offset_words = 1, | ||
132 | .offset_bits = 0, | ||
133 | .size_bits = 32 }, | ||
134 | { PATH_REC_FIELD(dgid), | 130 | { PATH_REC_FIELD(dgid), |
135 | .offset_words = 2, | 131 | .offset_words = 2, |
136 | .offset_bits = 0, | 132 | .offset_bits = 0, |
@@ -179,7 +175,7 @@ static const struct ib_field path_rec_table[] = { | |||
179 | .offset_words = 12, | 175 | .offset_words = 12, |
180 | .offset_bits = 16, | 176 | .offset_bits = 16, |
181 | .size_bits = 16 }, | 177 | .size_bits = 16 }, |
182 | { RESERVED, | 178 | { PATH_REC_FIELD(qos_class), |
183 | .offset_words = 13, | 179 | .offset_words = 13, |
184 | .offset_bits = 0, | 180 | .offset_bits = 0, |
185 | .size_bits = 12 }, | 181 | .size_bits = 12 }, |
@@ -385,9 +381,7 @@ static void update_sm_ah(struct work_struct *work) | |||
385 | 381 | ||
386 | new_ah->pkey_index = 0; | 382 | new_ah->pkey_index = 0; |
387 | if (ib_find_pkey(port->agent->device, port->port_num, | 383 | if (ib_find_pkey(port->agent->device, port->port_num, |
388 | IB_DEFAULT_PKEY_FULL, &new_ah->pkey_index) && | 384 | IB_DEFAULT_PKEY_FULL, &new_ah->pkey_index)) |
389 | ib_find_pkey(port->agent->device, port->port_num, | ||
390 | IB_DEFAULT_PKEY_PARTIAL, &new_ah->pkey_index)) | ||
391 | printk(KERN_ERR "Couldn't find index for default PKey\n"); | 385 | printk(KERN_ERR "Couldn't find index for default PKey\n"); |
392 | 386 | ||
393 | memset(&ah_attr, 0, sizeof ah_attr); | 387 | memset(&ah_attr, 0, sizeof ah_attr); |
@@ -533,7 +527,7 @@ static int alloc_mad(struct ib_sa_query *query, gfp_t gfp_mask) | |||
533 | query->sm_ah->pkey_index, | 527 | query->sm_ah->pkey_index, |
534 | 0, IB_MGMT_SA_HDR, IB_MGMT_SA_DATA, | 528 | 0, IB_MGMT_SA_HDR, IB_MGMT_SA_DATA, |
535 | gfp_mask); | 529 | gfp_mask); |
536 | if (!query->mad_buf) { | 530 | if (IS_ERR(query->mad_buf)) { |
537 | kref_put(&query->sm_ah->ref, free_sm_ah); | 531 | kref_put(&query->sm_ah->ref, free_sm_ah); |
538 | return -ENOMEM; | 532 | return -ENOMEM; |
539 | } | 533 | } |
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 70b77ae67422..3d4050681325 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c | |||
@@ -434,21 +434,18 @@ static void ib_device_release(struct class_device *cdev) | |||
434 | kfree(dev); | 434 | kfree(dev); |
435 | } | 435 | } |
436 | 436 | ||
437 | static int ib_device_uevent(struct class_device *cdev, char **envp, | 437 | static int ib_device_uevent(struct class_device *cdev, |
438 | int num_envp, char *buf, int size) | 438 | struct kobj_uevent_env *env) |
439 | { | 439 | { |
440 | struct ib_device *dev = container_of(cdev, struct ib_device, class_dev); | 440 | struct ib_device *dev = container_of(cdev, struct ib_device, class_dev); |
441 | int i = 0, len = 0; | ||
442 | 441 | ||
443 | if (add_uevent_var(envp, num_envp, &i, buf, size, &len, | 442 | if (add_uevent_var(env, "NAME=%s", dev->name)) |
444 | "NAME=%s", dev->name)) | ||
445 | return -ENOMEM; | 443 | return -ENOMEM; |
446 | 444 | ||
447 | /* | 445 | /* |
448 | * It would be nice to pass the node GUID with the event... | 446 | * It would be nice to pass the node GUID with the event... |
449 | */ | 447 | */ |
450 | 448 | ||
451 | envp[i] = NULL; | ||
452 | return 0; | 449 | return 0; |
453 | } | 450 | } |
454 | 451 | ||
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 53b4c94a7eb5..90d675ad9ec8 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c | |||
@@ -792,6 +792,78 @@ out: | |||
792 | return ret; | 792 | return ret; |
793 | } | 793 | } |
794 | 794 | ||
795 | static int ucma_set_option_id(struct ucma_context *ctx, int optname, | ||
796 | void *optval, size_t optlen) | ||
797 | { | ||
798 | int ret = 0; | ||
799 | |||
800 | switch (optname) { | ||
801 | case RDMA_OPTION_ID_TOS: | ||
802 | if (optlen != sizeof(u8)) { | ||
803 | ret = -EINVAL; | ||
804 | break; | ||
805 | } | ||
806 | rdma_set_service_type(ctx->cm_id, *((u8 *) optval)); | ||
807 | break; | ||
808 | default: | ||
809 | ret = -ENOSYS; | ||
810 | } | ||
811 | |||
812 | return ret; | ||
813 | } | ||
814 | |||
815 | static int ucma_set_option_level(struct ucma_context *ctx, int level, | ||
816 | int optname, void *optval, size_t optlen) | ||
817 | { | ||
818 | int ret; | ||
819 | |||
820 | switch (level) { | ||
821 | case RDMA_OPTION_ID: | ||
822 | ret = ucma_set_option_id(ctx, optname, optval, optlen); | ||
823 | break; | ||
824 | default: | ||
825 | ret = -ENOSYS; | ||
826 | } | ||
827 | |||
828 | return ret; | ||
829 | } | ||
830 | |||
831 | static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf, | ||
832 | int in_len, int out_len) | ||
833 | { | ||
834 | struct rdma_ucm_set_option cmd; | ||
835 | struct ucma_context *ctx; | ||
836 | void *optval; | ||
837 | int ret; | ||
838 | |||
839 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | ||
840 | return -EFAULT; | ||
841 | |||
842 | ctx = ucma_get_ctx(file, cmd.id); | ||
843 | if (IS_ERR(ctx)) | ||
844 | return PTR_ERR(ctx); | ||
845 | |||
846 | optval = kmalloc(cmd.optlen, GFP_KERNEL); | ||
847 | if (!optval) { | ||
848 | ret = -ENOMEM; | ||
849 | goto out1; | ||
850 | } | ||
851 | |||
852 | if (copy_from_user(optval, (void __user *) (unsigned long) cmd.optval, | ||
853 | cmd.optlen)) { | ||
854 | ret = -EFAULT; | ||
855 | goto out2; | ||
856 | } | ||
857 | |||
858 | ret = ucma_set_option_level(ctx, cmd.level, cmd.optname, optval, | ||
859 | cmd.optlen); | ||
860 | out2: | ||
861 | kfree(optval); | ||
862 | out1: | ||
863 | ucma_put_ctx(ctx); | ||
864 | return ret; | ||
865 | } | ||
866 | |||
795 | static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf, | 867 | static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf, |
796 | int in_len, int out_len) | 868 | int in_len, int out_len) |
797 | { | 869 | { |
@@ -936,7 +1008,7 @@ static ssize_t (*ucma_cmd_table[])(struct ucma_file *file, | |||
936 | [RDMA_USER_CM_CMD_INIT_QP_ATTR] = ucma_init_qp_attr, | 1008 | [RDMA_USER_CM_CMD_INIT_QP_ATTR] = ucma_init_qp_attr, |
937 | [RDMA_USER_CM_CMD_GET_EVENT] = ucma_get_event, | 1009 | [RDMA_USER_CM_CMD_GET_EVENT] = ucma_get_event, |
938 | [RDMA_USER_CM_CMD_GET_OPTION] = NULL, | 1010 | [RDMA_USER_CM_CMD_GET_OPTION] = NULL, |
939 | [RDMA_USER_CM_CMD_SET_OPTION] = NULL, | 1011 | [RDMA_USER_CM_CMD_SET_OPTION] = ucma_set_option, |
940 | [RDMA_USER_CM_CMD_NOTIFY] = ucma_notify, | 1012 | [RDMA_USER_CM_CMD_NOTIFY] = ucma_notify, |
941 | [RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast, | 1013 | [RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast, |
942 | [RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast, | 1014 | [RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast, |
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index 26d0470eef6e..2f54e29dc7a6 100644 --- a/drivers/infiniband/core/umem.c +++ b/drivers/infiniband/core/umem.c | |||
@@ -37,9 +37,15 @@ | |||
37 | #include <linux/mm.h> | 37 | #include <linux/mm.h> |
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 | 41 | ||
41 | #include "uverbs.h" | 42 | #include "uverbs.h" |
42 | 43 | ||
44 | #define IB_UMEM_MAX_PAGE_CHUNK \ | ||
45 | ((PAGE_SIZE - offsetof(struct ib_umem_chunk, page_list)) / \ | ||
46 | ((void *) &((struct ib_umem_chunk *) 0)->page_list[1] - \ | ||
47 | (void *) &((struct ib_umem_chunk *) 0)->page_list[0])) | ||
48 | |||
43 | static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int dirty) | 49 | static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int dirty) |
44 | { | 50 | { |
45 | struct ib_umem_chunk *chunk, *tmp; | 51 | struct ib_umem_chunk *chunk, *tmp; |
@@ -70,6 +76,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, | |||
70 | { | 76 | { |
71 | struct ib_umem *umem; | 77 | struct ib_umem *umem; |
72 | struct page **page_list; | 78 | struct page **page_list; |
79 | struct vm_area_struct **vma_list; | ||
73 | struct ib_umem_chunk *chunk; | 80 | struct ib_umem_chunk *chunk; |
74 | unsigned long locked; | 81 | unsigned long locked; |
75 | unsigned long lock_limit; | 82 | unsigned long lock_limit; |
@@ -99,6 +106,9 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, | |||
99 | */ | 106 | */ |
100 | umem->writable = !!(access & ~IB_ACCESS_REMOTE_READ); | 107 | umem->writable = !!(access & ~IB_ACCESS_REMOTE_READ); |
101 | 108 | ||
109 | /* We assume the memory is from hugetlb until proved otherwise */ | ||
110 | umem->hugetlb = 1; | ||
111 | |||
102 | INIT_LIST_HEAD(&umem->chunk_list); | 112 | INIT_LIST_HEAD(&umem->chunk_list); |
103 | 113 | ||
104 | page_list = (struct page **) __get_free_page(GFP_KERNEL); | 114 | page_list = (struct page **) __get_free_page(GFP_KERNEL); |
@@ -107,6 +117,14 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, | |||
107 | return ERR_PTR(-ENOMEM); | 117 | return ERR_PTR(-ENOMEM); |
108 | } | 118 | } |
109 | 119 | ||
120 | /* | ||
121 | * if we can't alloc the vma_list, it's not so bad; | ||
122 | * just assume the memory is not hugetlb memory | ||
123 | */ | ||
124 | vma_list = (struct vm_area_struct **) __get_free_page(GFP_KERNEL); | ||
125 | if (!vma_list) | ||
126 | umem->hugetlb = 0; | ||
127 | |||
110 | npages = PAGE_ALIGN(size + umem->offset) >> PAGE_SHIFT; | 128 | npages = PAGE_ALIGN(size + umem->offset) >> PAGE_SHIFT; |
111 | 129 | ||
112 | down_write(¤t->mm->mmap_sem); | 130 | down_write(¤t->mm->mmap_sem); |
@@ -126,7 +144,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, | |||
126 | ret = get_user_pages(current, current->mm, cur_base, | 144 | ret = get_user_pages(current, current->mm, cur_base, |
127 | min_t(int, npages, | 145 | min_t(int, npages, |
128 | PAGE_SIZE / sizeof (struct page *)), | 146 | PAGE_SIZE / sizeof (struct page *)), |
129 | 1, !umem->writable, page_list, NULL); | 147 | 1, !umem->writable, page_list, vma_list); |
130 | 148 | ||
131 | if (ret < 0) | 149 | if (ret < 0) |
132 | goto out; | 150 | goto out; |
@@ -147,6 +165,9 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, | |||
147 | 165 | ||
148 | chunk->nents = min_t(int, ret, IB_UMEM_MAX_PAGE_CHUNK); | 166 | chunk->nents = min_t(int, ret, IB_UMEM_MAX_PAGE_CHUNK); |
149 | for (i = 0; i < chunk->nents; ++i) { | 167 | for (i = 0; i < chunk->nents; ++i) { |
168 | if (vma_list && | ||
169 | !is_vm_hugetlb_page(vma_list[i + off])) | ||
170 | umem->hugetlb = 0; | ||
150 | chunk->page_list[i].page = page_list[i + off]; | 171 | chunk->page_list[i].page = page_list[i + off]; |
151 | chunk->page_list[i].offset = 0; | 172 | chunk->page_list[i].offset = 0; |
152 | chunk->page_list[i].length = PAGE_SIZE; | 173 | chunk->page_list[i].length = PAGE_SIZE; |
@@ -181,6 +202,8 @@ out: | |||
181 | current->mm->locked_vm = locked; | 202 | current->mm->locked_vm = locked; |
182 | 203 | ||
183 | up_write(¤t->mm->mmap_sem); | 204 | up_write(¤t->mm->mmap_sem); |
205 | if (vma_list) | ||
206 | free_page((unsigned long) vma_list); | ||
184 | free_page((unsigned long) page_list); | 207 | free_page((unsigned long) page_list); |
185 | 208 | ||
186 | return ret < 0 ? ERR_PTR(ret) : umem; | 209 | return ret < 0 ? ERR_PTR(ret) : umem; |
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index d97ded25c4ff..b53eac4611de 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/poll.h> | 44 | #include <linux/poll.h> |
45 | #include <linux/rwsem.h> | 45 | #include <linux/rwsem.h> |
46 | #include <linux/kref.h> | 46 | #include <linux/kref.h> |
47 | #include <linux/compat.h> | ||
47 | 48 | ||
48 | #include <asm/uaccess.h> | 49 | #include <asm/uaccess.h> |
49 | #include <asm/semaphore.h> | 50 | #include <asm/semaphore.h> |
@@ -118,6 +119,8 @@ struct ib_umad_file { | |||
118 | wait_queue_head_t recv_wait; | 119 | wait_queue_head_t recv_wait; |
119 | struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS]; | 120 | struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS]; |
120 | int agents_dead; | 121 | int agents_dead; |
122 | u8 use_pkey_index; | ||
123 | u8 already_used; | ||
121 | }; | 124 | }; |
122 | 125 | ||
123 | struct ib_umad_packet { | 126 | struct ib_umad_packet { |
@@ -147,6 +150,12 @@ static void ib_umad_release_dev(struct kref *ref) | |||
147 | kfree(dev); | 150 | kfree(dev); |
148 | } | 151 | } |
149 | 152 | ||
153 | static int hdr_size(struct ib_umad_file *file) | ||
154 | { | ||
155 | return file->use_pkey_index ? sizeof (struct ib_user_mad_hdr) : | ||
156 | sizeof (struct ib_user_mad_hdr_old); | ||
157 | } | ||
158 | |||
150 | /* caller must hold port->mutex at least for reading */ | 159 | /* caller must hold port->mutex at least for reading */ |
151 | static struct ib_mad_agent *__get_agent(struct ib_umad_file *file, int id) | 160 | static struct ib_mad_agent *__get_agent(struct ib_umad_file *file, int id) |
152 | { | 161 | { |
@@ -221,13 +230,13 @@ static void recv_handler(struct ib_mad_agent *agent, | |||
221 | packet->length = mad_recv_wc->mad_len; | 230 | packet->length = mad_recv_wc->mad_len; |
222 | packet->recv_wc = mad_recv_wc; | 231 | packet->recv_wc = mad_recv_wc; |
223 | 232 | ||
224 | packet->mad.hdr.status = 0; | 233 | packet->mad.hdr.status = 0; |
225 | packet->mad.hdr.length = sizeof (struct ib_user_mad) + | 234 | packet->mad.hdr.length = hdr_size(file) + mad_recv_wc->mad_len; |
226 | mad_recv_wc->mad_len; | 235 | packet->mad.hdr.qpn = cpu_to_be32(mad_recv_wc->wc->src_qp); |
227 | packet->mad.hdr.qpn = cpu_to_be32(mad_recv_wc->wc->src_qp); | 236 | packet->mad.hdr.lid = cpu_to_be16(mad_recv_wc->wc->slid); |
228 | packet->mad.hdr.lid = cpu_to_be16(mad_recv_wc->wc->slid); | 237 | packet->mad.hdr.sl = mad_recv_wc->wc->sl; |
229 | packet->mad.hdr.sl = mad_recv_wc->wc->sl; | 238 | packet->mad.hdr.path_bits = mad_recv_wc->wc->dlid_path_bits; |
230 | packet->mad.hdr.path_bits = mad_recv_wc->wc->dlid_path_bits; | 239 | packet->mad.hdr.pkey_index = mad_recv_wc->wc->pkey_index; |
231 | packet->mad.hdr.grh_present = !!(mad_recv_wc->wc->wc_flags & IB_WC_GRH); | 240 | packet->mad.hdr.grh_present = !!(mad_recv_wc->wc->wc_flags & IB_WC_GRH); |
232 | if (packet->mad.hdr.grh_present) { | 241 | if (packet->mad.hdr.grh_present) { |
233 | struct ib_ah_attr ah_attr; | 242 | struct ib_ah_attr ah_attr; |
@@ -253,8 +262,8 @@ err1: | |||
253 | ib_free_recv_mad(mad_recv_wc); | 262 | ib_free_recv_mad(mad_recv_wc); |
254 | } | 263 | } |
255 | 264 | ||
256 | static ssize_t copy_recv_mad(char __user *buf, struct ib_umad_packet *packet, | 265 | static ssize_t copy_recv_mad(struct ib_umad_file *file, char __user *buf, |
257 | size_t count) | 266 | struct ib_umad_packet *packet, size_t count) |
258 | { | 267 | { |
259 | struct ib_mad_recv_buf *recv_buf; | 268 | struct ib_mad_recv_buf *recv_buf; |
260 | int left, seg_payload, offset, max_seg_payload; | 269 | int left, seg_payload, offset, max_seg_payload; |
@@ -262,15 +271,15 @@ static ssize_t copy_recv_mad(char __user *buf, struct ib_umad_packet *packet, | |||
262 | /* We need enough room to copy the first (or only) MAD segment. */ | 271 | /* We need enough room to copy the first (or only) MAD segment. */ |
263 | recv_buf = &packet->recv_wc->recv_buf; | 272 | recv_buf = &packet->recv_wc->recv_buf; |
264 | if ((packet->length <= sizeof (*recv_buf->mad) && | 273 | if ((packet->length <= sizeof (*recv_buf->mad) && |
265 | count < sizeof (packet->mad) + packet->length) || | 274 | count < hdr_size(file) + packet->length) || |
266 | (packet->length > sizeof (*recv_buf->mad) && | 275 | (packet->length > sizeof (*recv_buf->mad) && |
267 | count < sizeof (packet->mad) + sizeof (*recv_buf->mad))) | 276 | count < hdr_size(file) + sizeof (*recv_buf->mad))) |
268 | return -EINVAL; | 277 | return -EINVAL; |
269 | 278 | ||
270 | if (copy_to_user(buf, &packet->mad, sizeof (packet->mad))) | 279 | if (copy_to_user(buf, &packet->mad, hdr_size(file))) |
271 | return -EFAULT; | 280 | return -EFAULT; |
272 | 281 | ||
273 | buf += sizeof (packet->mad); | 282 | buf += hdr_size(file); |
274 | seg_payload = min_t(int, packet->length, sizeof (*recv_buf->mad)); | 283 | seg_payload = min_t(int, packet->length, sizeof (*recv_buf->mad)); |
275 | if (copy_to_user(buf, recv_buf->mad, seg_payload)) | 284 | if (copy_to_user(buf, recv_buf->mad, seg_payload)) |
276 | return -EFAULT; | 285 | return -EFAULT; |
@@ -280,7 +289,7 @@ static ssize_t copy_recv_mad(char __user *buf, struct ib_umad_packet *packet, | |||
280 | * Multipacket RMPP MAD message. Copy remainder of message. | 289 | * Multipacket RMPP MAD message. Copy remainder of message. |
281 | * Note that last segment may have a shorter payload. | 290 | * Note that last segment may have a shorter payload. |
282 | */ | 291 | */ |
283 | if (count < sizeof (packet->mad) + packet->length) { | 292 | if (count < hdr_size(file) + packet->length) { |
284 | /* | 293 | /* |
285 | * The buffer is too small, return the first RMPP segment, | 294 | * The buffer is too small, return the first RMPP segment, |
286 | * which includes the RMPP message length. | 295 | * which includes the RMPP message length. |
@@ -300,18 +309,23 @@ static ssize_t copy_recv_mad(char __user *buf, struct ib_umad_packet *packet, | |||
300 | return -EFAULT; | 309 | return -EFAULT; |
301 | } | 310 | } |
302 | } | 311 | } |
303 | return sizeof (packet->mad) + packet->length; | 312 | return hdr_size(file) + packet->length; |
304 | } | 313 | } |
305 | 314 | ||
306 | static ssize_t copy_send_mad(char __user *buf, struct ib_umad_packet *packet, | 315 | static ssize_t copy_send_mad(struct ib_umad_file *file, char __user *buf, |
307 | size_t count) | 316 | struct ib_umad_packet *packet, size_t count) |
308 | { | 317 | { |
309 | ssize_t size = sizeof (packet->mad) + packet->length; | 318 | ssize_t size = hdr_size(file) + packet->length; |
310 | 319 | ||
311 | if (count < size) | 320 | if (count < size) |
312 | return -EINVAL; | 321 | return -EINVAL; |
313 | 322 | ||
314 | if (copy_to_user(buf, &packet->mad, size)) | 323 | if (copy_to_user(buf, &packet->mad, hdr_size(file))) |
324 | return -EFAULT; | ||
325 | |||
326 | buf += hdr_size(file); | ||
327 | |||
328 | if (copy_to_user(buf, packet->mad.data, packet->length)) | ||
315 | return -EFAULT; | 329 | return -EFAULT; |
316 | 330 | ||
317 | return size; | 331 | return size; |
@@ -324,7 +338,7 @@ static ssize_t ib_umad_read(struct file *filp, char __user *buf, | |||
324 | struct ib_umad_packet *packet; | 338 | struct ib_umad_packet *packet; |
325 | ssize_t ret; | 339 | ssize_t ret; |
326 | 340 | ||
327 | if (count < sizeof (struct ib_user_mad)) | 341 | if (count < hdr_size(file)) |
328 | return -EINVAL; | 342 | return -EINVAL; |
329 | 343 | ||
330 | spin_lock_irq(&file->recv_lock); | 344 | spin_lock_irq(&file->recv_lock); |
@@ -348,9 +362,9 @@ static ssize_t ib_umad_read(struct file *filp, char __user *buf, | |||
348 | spin_unlock_irq(&file->recv_lock); | 362 | spin_unlock_irq(&file->recv_lock); |
349 | 363 | ||
350 | if (packet->recv_wc) | 364 | if (packet->recv_wc) |
351 | ret = copy_recv_mad(buf, packet, count); | 365 | ret = copy_recv_mad(file, buf, packet, count); |
352 | else | 366 | else |
353 | ret = copy_send_mad(buf, packet, count); | 367 | ret = copy_send_mad(file, buf, packet, count); |
354 | 368 | ||
355 | if (ret < 0) { | 369 | if (ret < 0) { |
356 | /* Requeue packet */ | 370 | /* Requeue packet */ |
@@ -442,15 +456,14 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
442 | __be64 *tid; | 456 | __be64 *tid; |
443 | int ret, data_len, hdr_len, copy_offset, rmpp_active; | 457 | int ret, data_len, hdr_len, copy_offset, rmpp_active; |
444 | 458 | ||
445 | if (count < sizeof (struct ib_user_mad) + IB_MGMT_RMPP_HDR) | 459 | if (count < hdr_size(file) + IB_MGMT_RMPP_HDR) |
446 | return -EINVAL; | 460 | return -EINVAL; |
447 | 461 | ||
448 | packet = kzalloc(sizeof *packet + IB_MGMT_RMPP_HDR, GFP_KERNEL); | 462 | packet = kzalloc(sizeof *packet + IB_MGMT_RMPP_HDR, GFP_KERNEL); |
449 | if (!packet) | 463 | if (!packet) |
450 | return -ENOMEM; | 464 | return -ENOMEM; |
451 | 465 | ||
452 | if (copy_from_user(&packet->mad, buf, | 466 | if (copy_from_user(&packet->mad, buf, hdr_size(file))) { |
453 | sizeof (struct ib_user_mad) + IB_MGMT_RMPP_HDR)) { | ||
454 | ret = -EFAULT; | 467 | ret = -EFAULT; |
455 | goto err; | 468 | goto err; |
456 | } | 469 | } |
@@ -461,6 +474,13 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
461 | goto err; | 474 | goto err; |
462 | } | 475 | } |
463 | 476 | ||
477 | buf += hdr_size(file); | ||
478 | |||
479 | if (copy_from_user(packet->mad.data, buf, IB_MGMT_RMPP_HDR)) { | ||
480 | ret = -EFAULT; | ||
481 | goto err; | ||
482 | } | ||
483 | |||
464 | down_read(&file->port->mutex); | 484 | down_read(&file->port->mutex); |
465 | 485 | ||
466 | agent = __get_agent(file, packet->mad.hdr.id); | 486 | agent = __get_agent(file, packet->mad.hdr.id); |
@@ -500,11 +520,11 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
500 | IB_MGMT_RMPP_FLAG_ACTIVE; | 520 | IB_MGMT_RMPP_FLAG_ACTIVE; |
501 | } | 521 | } |
502 | 522 | ||
503 | data_len = count - sizeof (struct ib_user_mad) - hdr_len; | 523 | data_len = count - hdr_size(file) - hdr_len; |
504 | packet->msg = ib_create_send_mad(agent, | 524 | packet->msg = ib_create_send_mad(agent, |
505 | be32_to_cpu(packet->mad.hdr.qpn), | 525 | be32_to_cpu(packet->mad.hdr.qpn), |
506 | 0, rmpp_active, hdr_len, | 526 | packet->mad.hdr.pkey_index, rmpp_active, |
507 | data_len, GFP_KERNEL); | 527 | hdr_len, data_len, GFP_KERNEL); |
508 | if (IS_ERR(packet->msg)) { | 528 | if (IS_ERR(packet->msg)) { |
509 | ret = PTR_ERR(packet->msg); | 529 | ret = PTR_ERR(packet->msg); |
510 | goto err_ah; | 530 | goto err_ah; |
@@ -517,7 +537,6 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
517 | 537 | ||
518 | /* Copy MAD header. Any RMPP header is already in place. */ | 538 | /* Copy MAD header. Any RMPP header is already in place. */ |
519 | memcpy(packet->msg->mad, packet->mad.data, IB_MGMT_MAD_HDR); | 539 | memcpy(packet->msg->mad, packet->mad.data, IB_MGMT_MAD_HDR); |
520 | buf += sizeof (struct ib_user_mad); | ||
521 | 540 | ||
522 | if (!rmpp_active) { | 541 | if (!rmpp_active) { |
523 | if (copy_from_user(packet->msg->mad + copy_offset, | 542 | if (copy_from_user(packet->msg->mad + copy_offset, |
@@ -589,7 +608,8 @@ static unsigned int ib_umad_poll(struct file *filp, struct poll_table_struct *wa | |||
589 | return mask; | 608 | return mask; |
590 | } | 609 | } |
591 | 610 | ||
592 | static int ib_umad_reg_agent(struct ib_umad_file *file, unsigned long arg) | 611 | static int ib_umad_reg_agent(struct ib_umad_file *file, void __user *arg, |
612 | int compat_method_mask) | ||
593 | { | 613 | { |
594 | struct ib_user_mad_reg_req ureq; | 614 | struct ib_user_mad_reg_req ureq; |
595 | struct ib_mad_reg_req req; | 615 | struct ib_mad_reg_req req; |
@@ -604,7 +624,7 @@ static int ib_umad_reg_agent(struct ib_umad_file *file, unsigned long arg) | |||
604 | goto out; | 624 | goto out; |
605 | } | 625 | } |
606 | 626 | ||
607 | if (copy_from_user(&ureq, (void __user *) arg, sizeof ureq)) { | 627 | if (copy_from_user(&ureq, arg, sizeof ureq)) { |
608 | ret = -EFAULT; | 628 | ret = -EFAULT; |
609 | goto out; | 629 | goto out; |
610 | } | 630 | } |
@@ -625,8 +645,18 @@ found: | |||
625 | if (ureq.mgmt_class) { | 645 | if (ureq.mgmt_class) { |
626 | req.mgmt_class = ureq.mgmt_class; | 646 | req.mgmt_class = ureq.mgmt_class; |
627 | req.mgmt_class_version = ureq.mgmt_class_version; | 647 | req.mgmt_class_version = ureq.mgmt_class_version; |
628 | memcpy(req.method_mask, ureq.method_mask, sizeof req.method_mask); | 648 | memcpy(req.oui, ureq.oui, sizeof req.oui); |
629 | memcpy(req.oui, ureq.oui, sizeof req.oui); | 649 | |
650 | if (compat_method_mask) { | ||
651 | u32 *umm = (u32 *) ureq.method_mask; | ||
652 | int i; | ||
653 | |||
654 | for (i = 0; i < BITS_TO_LONGS(IB_MGMT_MAX_METHODS); ++i) | ||
655 | req.method_mask[i] = | ||
656 | umm[i * 2] | ((u64) umm[i * 2 + 1] << 32); | ||
657 | } else | ||
658 | memcpy(req.method_mask, ureq.method_mask, | ||
659 | sizeof req.method_mask); | ||
630 | } | 660 | } |
631 | 661 | ||
632 | agent = ib_register_mad_agent(file->port->ib_dev, file->port->port_num, | 662 | agent = ib_register_mad_agent(file->port->ib_dev, file->port->port_num, |
@@ -646,6 +676,16 @@ found: | |||
646 | goto out; | 676 | goto out; |
647 | } | 677 | } |
648 | 678 | ||
679 | if (!file->already_used) { | ||
680 | file->already_used = 1; | ||
681 | if (!file->use_pkey_index) { | ||
682 | printk(KERN_WARNING "user_mad: process %s did not enable " | ||
683 | "P_Key index support.\n", current->comm); | ||
684 | printk(KERN_WARNING "user_mad: Documentation/infiniband/user_mad.txt " | ||
685 | "has info on the new ABI.\n"); | ||
686 | } | ||
687 | } | ||
688 | |||
649 | file->agent[agent_id] = agent; | 689 | file->agent[agent_id] = agent; |
650 | ret = 0; | 690 | ret = 0; |
651 | 691 | ||
@@ -654,13 +694,13 @@ out: | |||
654 | return ret; | 694 | return ret; |
655 | } | 695 | } |
656 | 696 | ||
657 | static int ib_umad_unreg_agent(struct ib_umad_file *file, unsigned long arg) | 697 | static int ib_umad_unreg_agent(struct ib_umad_file *file, u32 __user *arg) |
658 | { | 698 | { |
659 | struct ib_mad_agent *agent = NULL; | 699 | struct ib_mad_agent *agent = NULL; |
660 | u32 id; | 700 | u32 id; |
661 | int ret = 0; | 701 | int ret = 0; |
662 | 702 | ||
663 | if (get_user(id, (u32 __user *) arg)) | 703 | if (get_user(id, arg)) |
664 | return -EFAULT; | 704 | return -EFAULT; |
665 | 705 | ||
666 | down_write(&file->port->mutex); | 706 | down_write(&file->port->mutex); |
@@ -682,18 +722,51 @@ out: | |||
682 | return ret; | 722 | return ret; |
683 | } | 723 | } |
684 | 724 | ||
725 | static long ib_umad_enable_pkey(struct ib_umad_file *file) | ||
726 | { | ||
727 | int ret = 0; | ||
728 | |||
729 | down_write(&file->port->mutex); | ||
730 | if (file->already_used) | ||
731 | ret = -EINVAL; | ||
732 | else | ||
733 | file->use_pkey_index = 1; | ||
734 | up_write(&file->port->mutex); | ||
735 | |||
736 | return ret; | ||
737 | } | ||
738 | |||
685 | static long ib_umad_ioctl(struct file *filp, unsigned int cmd, | 739 | static long ib_umad_ioctl(struct file *filp, unsigned int cmd, |
686 | unsigned long arg) | 740 | unsigned long arg) |
687 | { | 741 | { |
688 | switch (cmd) { | 742 | switch (cmd) { |
689 | case IB_USER_MAD_REGISTER_AGENT: | 743 | case IB_USER_MAD_REGISTER_AGENT: |
690 | return ib_umad_reg_agent(filp->private_data, arg); | 744 | return ib_umad_reg_agent(filp->private_data, (void __user *) arg, 0); |
745 | case IB_USER_MAD_UNREGISTER_AGENT: | ||
746 | return ib_umad_unreg_agent(filp->private_data, (__u32 __user *) arg); | ||
747 | case IB_USER_MAD_ENABLE_PKEY: | ||
748 | return ib_umad_enable_pkey(filp->private_data); | ||
749 | default: | ||
750 | return -ENOIOCTLCMD; | ||
751 | } | ||
752 | } | ||
753 | |||
754 | #ifdef CONFIG_COMPAT | ||
755 | static long ib_umad_compat_ioctl(struct file *filp, unsigned int cmd, | ||
756 | unsigned long arg) | ||
757 | { | ||
758 | switch (cmd) { | ||
759 | case IB_USER_MAD_REGISTER_AGENT: | ||
760 | return ib_umad_reg_agent(filp->private_data, compat_ptr(arg), 1); | ||
691 | case IB_USER_MAD_UNREGISTER_AGENT: | 761 | case IB_USER_MAD_UNREGISTER_AGENT: |
692 | return ib_umad_unreg_agent(filp->private_data, arg); | 762 | return ib_umad_unreg_agent(filp->private_data, compat_ptr(arg)); |
763 | case IB_USER_MAD_ENABLE_PKEY: | ||
764 | return ib_umad_enable_pkey(filp->private_data); | ||
693 | default: | 765 | default: |
694 | return -ENOIOCTLCMD; | 766 | return -ENOIOCTLCMD; |
695 | } | 767 | } |
696 | } | 768 | } |
769 | #endif | ||
697 | 770 | ||
698 | static int ib_umad_open(struct inode *inode, struct file *filp) | 771 | static int ib_umad_open(struct inode *inode, struct file *filp) |
699 | { | 772 | { |
@@ -782,7 +855,9 @@ static const struct file_operations umad_fops = { | |||
782 | .write = ib_umad_write, | 855 | .write = ib_umad_write, |
783 | .poll = ib_umad_poll, | 856 | .poll = ib_umad_poll, |
784 | .unlocked_ioctl = ib_umad_ioctl, | 857 | .unlocked_ioctl = ib_umad_ioctl, |
785 | .compat_ioctl = ib_umad_ioctl, | 858 | #ifdef CONFIG_COMPAT |
859 | .compat_ioctl = ib_umad_compat_ioctl, | ||
860 | #endif | ||
786 | .open = ib_umad_open, | 861 | .open = ib_umad_open, |
787 | .release = ib_umad_close | 862 | .release = ib_umad_close |
788 | }; | 863 | }; |
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index c33546f9e961..c75eb6c9bd49 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h | |||
@@ -148,7 +148,6 @@ void idr_remove_uobj(struct idr *idp, struct ib_uobject *uobj); | |||
148 | 148 | ||
149 | struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file, | 149 | struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file, |
150 | int is_async, int *fd); | 150 | int is_async, int *fd); |
151 | void ib_uverbs_release_event_file(struct kref *ref); | ||
152 | struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd); | 151 | struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd); |
153 | 152 | ||
154 | void ib_uverbs_release_ucq(struct ib_uverbs_file *file, | 153 | void ib_uverbs_release_ucq(struct ib_uverbs_file *file, |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 14d7ccd89195..7c2ac3905582 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -125,6 +125,14 @@ static void ib_uverbs_release_dev(struct kref *ref) | |||
125 | complete(&dev->comp); | 125 | complete(&dev->comp); |
126 | } | 126 | } |
127 | 127 | ||
128 | static void ib_uverbs_release_event_file(struct kref *ref) | ||
129 | { | ||
130 | struct ib_uverbs_event_file *file = | ||
131 | container_of(ref, struct ib_uverbs_event_file, ref); | ||
132 | |||
133 | kfree(file); | ||
134 | } | ||
135 | |||
128 | void ib_uverbs_release_ucq(struct ib_uverbs_file *file, | 136 | void ib_uverbs_release_ucq(struct ib_uverbs_file *file, |
129 | struct ib_uverbs_event_file *ev_file, | 137 | struct ib_uverbs_event_file *ev_file, |
130 | struct ib_ucq_object *uobj) | 138 | struct ib_ucq_object *uobj) |
@@ -331,14 +339,6 @@ static unsigned int ib_uverbs_event_poll(struct file *filp, | |||
331 | return pollflags; | 339 | return pollflags; |
332 | } | 340 | } |
333 | 341 | ||
334 | void ib_uverbs_release_event_file(struct kref *ref) | ||
335 | { | ||
336 | struct ib_uverbs_event_file *file = | ||
337 | container_of(ref, struct ib_uverbs_event_file, ref); | ||
338 | |||
339 | kfree(file); | ||
340 | } | ||
341 | |||
342 | static int ib_uverbs_event_fasync(int fd, struct file *filp, int on) | 342 | static int ib_uverbs_event_fasync(int fd, struct file *filp, int on) |
343 | { | 343 | { |
344 | struct ib_uverbs_event_file *file = filp->private_data; | 344 | struct ib_uverbs_event_file *file = filp->private_data; |
diff --git a/drivers/infiniband/hw/amso1100/c2.c b/drivers/infiniband/hw/amso1100/c2.c index 0aecea67f3e6..f283a9f0c23b 100644 --- a/drivers/infiniband/hw/amso1100/c2.c +++ b/drivers/infiniband/hw/amso1100/c2.c | |||
@@ -886,7 +886,6 @@ static struct net_device *c2_devinit(struct c2_dev *c2dev, | |||
886 | return NULL; | 886 | return NULL; |
887 | } | 887 | } |
888 | 888 | ||
889 | SET_MODULE_OWNER(netdev); | ||
890 | SET_NETDEV_DEV(netdev, &c2dev->pcidev->dev); | 889 | SET_NETDEV_DEV(netdev, &c2dev->pcidev->dev); |
891 | 890 | ||
892 | netdev->open = c2_up; | 891 | netdev->open = c2_up; |
diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c index 997cf1530762..7a6cece6ea9d 100644 --- a/drivers/infiniband/hw/amso1100/c2_provider.c +++ b/drivers/infiniband/hw/amso1100/c2_provider.c | |||
@@ -715,7 +715,6 @@ static int c2_pseudo_change_mtu(struct net_device *netdev, int new_mtu) | |||
715 | 715 | ||
716 | static void setup(struct net_device *netdev) | 716 | static void setup(struct net_device *netdev) |
717 | { | 717 | { |
718 | SET_MODULE_OWNER(netdev); | ||
719 | netdev->open = c2_pseudo_up; | 718 | netdev->open = c2_pseudo_up; |
720 | netdev->stop = c2_pseudo_down; | 719 | netdev->stop = c2_pseudo_down; |
721 | netdev->hard_start_xmit = c2_pseudo_xmit_frame; | 720 | netdev->hard_start_xmit = c2_pseudo_xmit_frame; |
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c index 1518b41482ae..eec6a30840ca 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.c +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/spinlock.h> | 37 | #include <linux/spinlock.h> |
38 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
39 | #include <linux/dma-mapping.h> | 39 | #include <linux/dma-mapping.h> |
40 | #include <net/net_namespace.h> | ||
40 | 41 | ||
41 | #include "cxio_resource.h" | 42 | #include "cxio_resource.h" |
42 | #include "cxio_hal.h" | 43 | #include "cxio_hal.h" |
@@ -894,7 +895,7 @@ int cxio_rdev_open(struct cxio_rdev *rdev_p) | |||
894 | if (cxio_hal_find_rdev_by_name(rdev_p->dev_name)) { | 895 | if (cxio_hal_find_rdev_by_name(rdev_p->dev_name)) { |
895 | return -EBUSY; | 896 | return -EBUSY; |
896 | } | 897 | } |
897 | netdev_p = dev_get_by_name(rdev_p->dev_name); | 898 | netdev_p = dev_get_by_name(&init_net, rdev_p->dev_name); |
898 | if (!netdev_p) { | 899 | if (!netdev_p) { |
899 | return -EINVAL; | 900 | return -EINVAL; |
900 | } | 901 | } |
@@ -916,7 +917,7 @@ int cxio_rdev_open(struct cxio_rdev *rdev_p) | |||
916 | PDBG("%s opening rnic dev %s\n", __FUNCTION__, rdev_p->dev_name); | 917 | PDBG("%s opening rnic dev %s\n", __FUNCTION__, rdev_p->dev_name); |
917 | memset(&rdev_p->ctrl_qp, 0, sizeof(rdev_p->ctrl_qp)); | 918 | memset(&rdev_p->ctrl_qp, 0, sizeof(rdev_p->ctrl_qp)); |
918 | if (!rdev_p->t3cdev_p) | 919 | if (!rdev_p->t3cdev_p) |
919 | rdev_p->t3cdev_p = T3CDEV(netdev_p); | 920 | rdev_p->t3cdev_p = dev2t3cdev(netdev_p); |
920 | rdev_p->t3cdev_p->ulp = (void *) rdev_p; | 921 | rdev_p->t3cdev_p->ulp = (void *) rdev_p; |
921 | err = rdev_p->t3cdev_p->ctl(rdev_p->t3cdev_p, RDMA_GET_PARAMS, | 922 | err = rdev_p->t3cdev_p->ctl(rdev_p->t3cdev_p, RDMA_GET_PARAMS, |
922 | &(rdev_p->rnic_info)); | 923 | &(rdev_p->rnic_info)); |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index 9574088f0d4e..20ba372dd182 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c | |||
@@ -63,37 +63,37 @@ static char *states[] = { | |||
63 | }; | 63 | }; |
64 | 64 | ||
65 | static int ep_timeout_secs = 10; | 65 | static int ep_timeout_secs = 10; |
66 | module_param(ep_timeout_secs, int, 0444); | 66 | module_param(ep_timeout_secs, int, 0644); |
67 | MODULE_PARM_DESC(ep_timeout_secs, "CM Endpoint operation timeout " | 67 | MODULE_PARM_DESC(ep_timeout_secs, "CM Endpoint operation timeout " |
68 | "in seconds (default=10)"); | 68 | "in seconds (default=10)"); |
69 | 69 | ||
70 | static int mpa_rev = 1; | 70 | static int mpa_rev = 1; |
71 | module_param(mpa_rev, int, 0444); | 71 | module_param(mpa_rev, int, 0644); |
72 | MODULE_PARM_DESC(mpa_rev, "MPA Revision, 0 supports amso1100, " | 72 | MODULE_PARM_DESC(mpa_rev, "MPA Revision, 0 supports amso1100, " |
73 | "1 is spec compliant. (default=1)"); | 73 | "1 is spec compliant. (default=1)"); |
74 | 74 | ||
75 | static int markers_enabled = 0; | 75 | static int markers_enabled = 0; |
76 | module_param(markers_enabled, int, 0444); | 76 | module_param(markers_enabled, int, 0644); |
77 | MODULE_PARM_DESC(markers_enabled, "Enable MPA MARKERS (default(0)=disabled)"); | 77 | MODULE_PARM_DESC(markers_enabled, "Enable MPA MARKERS (default(0)=disabled)"); |
78 | 78 | ||
79 | static int crc_enabled = 1; | 79 | static int crc_enabled = 1; |
80 | module_param(crc_enabled, int, 0444); | 80 | module_param(crc_enabled, int, 0644); |
81 | MODULE_PARM_DESC(crc_enabled, "Enable MPA CRC (default(1)=enabled)"); | 81 | MODULE_PARM_DESC(crc_enabled, "Enable MPA CRC (default(1)=enabled)"); |
82 | 82 | ||
83 | static int rcv_win = 256 * 1024; | 83 | static int rcv_win = 256 * 1024; |
84 | module_param(rcv_win, int, 0444); | 84 | module_param(rcv_win, int, 0644); |
85 | MODULE_PARM_DESC(rcv_win, "TCP receive window in bytes (default=256)"); | 85 | MODULE_PARM_DESC(rcv_win, "TCP receive window in bytes (default=256)"); |
86 | 86 | ||
87 | static int snd_win = 32 * 1024; | 87 | static int snd_win = 32 * 1024; |
88 | module_param(snd_win, int, 0444); | 88 | module_param(snd_win, int, 0644); |
89 | MODULE_PARM_DESC(snd_win, "TCP send window in bytes (default=32KB)"); | 89 | MODULE_PARM_DESC(snd_win, "TCP send window in bytes (default=32KB)"); |
90 | 90 | ||
91 | static unsigned int nocong = 0; | 91 | static unsigned int nocong = 0; |
92 | module_param(nocong, uint, 0444); | 92 | module_param(nocong, uint, 0644); |
93 | MODULE_PARM_DESC(nocong, "Turn off congestion control (default=0)"); | 93 | MODULE_PARM_DESC(nocong, "Turn off congestion control (default=0)"); |
94 | 94 | ||
95 | static unsigned int cong_flavor = 1; | 95 | static unsigned int cong_flavor = 1; |
96 | module_param(cong_flavor, uint, 0444); | 96 | module_param(cong_flavor, uint, 0644); |
97 | MODULE_PARM_DESC(cong_flavor, "TCP Congestion control flavor (default=1)"); | 97 | MODULE_PARM_DESC(cong_flavor, "TCP Congestion control flavor (default=1)"); |
98 | 98 | ||
99 | static void process_work(struct work_struct *work); | 99 | static void process_work(struct work_struct *work); |
@@ -139,7 +139,7 @@ static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb) | |||
139 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); | 139 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); |
140 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, hwtid)); | 140 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, hwtid)); |
141 | skb->priority = CPL_PRIORITY_SETUP; | 141 | skb->priority = CPL_PRIORITY_SETUP; |
142 | tdev->send(tdev, skb); | 142 | cxgb3_ofld_send(tdev, skb); |
143 | return; | 143 | return; |
144 | } | 144 | } |
145 | 145 | ||
@@ -161,7 +161,7 @@ int iwch_quiesce_tid(struct iwch_ep *ep) | |||
161 | req->val = cpu_to_be64(1 << S_TCB_RX_QUIESCE); | 161 | req->val = cpu_to_be64(1 << S_TCB_RX_QUIESCE); |
162 | 162 | ||
163 | skb->priority = CPL_PRIORITY_DATA; | 163 | skb->priority = CPL_PRIORITY_DATA; |
164 | ep->com.tdev->send(ep->com.tdev, skb); | 164 | cxgb3_ofld_send(ep->com.tdev, skb); |
165 | return 0; | 165 | return 0; |
166 | } | 166 | } |
167 | 167 | ||
@@ -183,7 +183,7 @@ int iwch_resume_tid(struct iwch_ep *ep) | |||
183 | req->val = 0; | 183 | req->val = 0; |
184 | 184 | ||
185 | skb->priority = CPL_PRIORITY_DATA; | 185 | skb->priority = CPL_PRIORITY_DATA; |
186 | ep->com.tdev->send(ep->com.tdev, skb); | 186 | cxgb3_ofld_send(ep->com.tdev, skb); |
187 | return 0; | 187 | return 0; |
188 | } | 188 | } |
189 | 189 | ||
@@ -784,7 +784,7 @@ static int update_rx_credits(struct iwch_ep *ep, u32 credits) | |||
784 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, ep->hwtid)); | 784 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, ep->hwtid)); |
785 | req->credit_dack = htonl(V_RX_CREDITS(credits) | V_RX_FORCE_ACK(1)); | 785 | req->credit_dack = htonl(V_RX_CREDITS(credits) | V_RX_FORCE_ACK(1)); |
786 | skb->priority = CPL_PRIORITY_ACK; | 786 | skb->priority = CPL_PRIORITY_ACK; |
787 | ep->com.tdev->send(ep->com.tdev, skb); | 787 | cxgb3_ofld_send(ep->com.tdev, skb); |
788 | return credits; | 788 | return credits; |
789 | } | 789 | } |
790 | 790 | ||
@@ -1152,7 +1152,7 @@ static int listen_start(struct iwch_listen_ep *ep) | |||
1152 | req->opt1 = htonl(V_CONN_POLICY(CPL_CONN_POLICY_ASK)); | 1152 | req->opt1 = htonl(V_CONN_POLICY(CPL_CONN_POLICY_ASK)); |
1153 | 1153 | ||
1154 | skb->priority = 1; | 1154 | skb->priority = 1; |
1155 | ep->com.tdev->send(ep->com.tdev, skb); | 1155 | cxgb3_ofld_send(ep->com.tdev, skb); |
1156 | return 0; | 1156 | return 0; |
1157 | } | 1157 | } |
1158 | 1158 | ||
@@ -1186,7 +1186,7 @@ static int listen_stop(struct iwch_listen_ep *ep) | |||
1186 | req->cpu_idx = 0; | 1186 | req->cpu_idx = 0; |
1187 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, ep->stid)); | 1187 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, ep->stid)); |
1188 | skb->priority = 1; | 1188 | skb->priority = 1; |
1189 | ep->com.tdev->send(ep->com.tdev, skb); | 1189 | cxgb3_ofld_send(ep->com.tdev, skb); |
1190 | return 0; | 1190 | return 0; |
1191 | } | 1191 | } |
1192 | 1192 | ||
@@ -1264,7 +1264,7 @@ static void reject_cr(struct t3cdev *tdev, u32 hwtid, __be32 peer_ip, | |||
1264 | rpl->opt0l_status = htonl(CPL_PASS_OPEN_REJECT); | 1264 | rpl->opt0l_status = htonl(CPL_PASS_OPEN_REJECT); |
1265 | rpl->opt2 = 0; | 1265 | rpl->opt2 = 0; |
1266 | rpl->rsvd = rpl->opt2; | 1266 | rpl->rsvd = rpl->opt2; |
1267 | tdev->send(tdev, skb); | 1267 | cxgb3_ofld_send(tdev, skb); |
1268 | } | 1268 | } |
1269 | } | 1269 | } |
1270 | 1270 | ||
@@ -1557,7 +1557,7 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1557 | rpl->wr.wr_lo = htonl(V_WR_TID(ep->hwtid)); | 1557 | rpl->wr.wr_lo = htonl(V_WR_TID(ep->hwtid)); |
1558 | OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid)); | 1558 | OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid)); |
1559 | rpl->cmd = CPL_ABORT_NO_RST; | 1559 | rpl->cmd = CPL_ABORT_NO_RST; |
1560 | ep->com.tdev->send(ep->com.tdev, rpl_skb); | 1560 | cxgb3_ofld_send(ep->com.tdev, rpl_skb); |
1561 | if (state != ABORTING) { | 1561 | if (state != ABORTING) { |
1562 | state_set(&ep->com, DEAD); | 1562 | state_set(&ep->com, DEAD); |
1563 | release_ep_resources(ep); | 1563 | release_ep_resources(ep); |
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h index b5e960305316..0f7a55d35ea7 100644 --- a/drivers/infiniband/hw/ehca/ehca_classes.h +++ b/drivers/infiniband/hw/ehca/ehca_classes.h | |||
@@ -53,6 +53,7 @@ struct ehca_pd; | |||
53 | struct ehca_av; | 53 | struct ehca_av; |
54 | 54 | ||
55 | #include <linux/wait.h> | 55 | #include <linux/wait.h> |
56 | #include <linux/mutex.h> | ||
56 | 57 | ||
57 | #include <rdma/ib_verbs.h> | 58 | #include <rdma/ib_verbs.h> |
58 | #include <rdma/ib_user_verbs.h> | 59 | #include <rdma/ib_user_verbs.h> |
@@ -99,10 +100,10 @@ struct ehca_sport { | |||
99 | struct ehca_sma_attr saved_attr; | 100 | struct ehca_sma_attr saved_attr; |
100 | }; | 101 | }; |
101 | 102 | ||
102 | #define HCA_CAP_MR_PGSIZE_4K 1 | 103 | #define HCA_CAP_MR_PGSIZE_4K 0x80000000 |
103 | #define HCA_CAP_MR_PGSIZE_64K 2 | 104 | #define HCA_CAP_MR_PGSIZE_64K 0x40000000 |
104 | #define HCA_CAP_MR_PGSIZE_1M 4 | 105 | #define HCA_CAP_MR_PGSIZE_1M 0x20000000 |
105 | #define HCA_CAP_MR_PGSIZE_16M 8 | 106 | #define HCA_CAP_MR_PGSIZE_16M 0x10000000 |
106 | 107 | ||
107 | struct ehca_shca { | 108 | struct ehca_shca { |
108 | struct ib_device ib_device; | 109 | struct ib_device ib_device; |
@@ -337,6 +338,8 @@ struct ehca_create_cq_resp { | |||
337 | u32 cq_number; | 338 | u32 cq_number; |
338 | u32 token; | 339 | u32 token; |
339 | struct ipzu_queue_resp ipz_queue; | 340 | struct ipzu_queue_resp ipz_queue; |
341 | u32 fw_handle_ofs; | ||
342 | u32 dummy; | ||
340 | }; | 343 | }; |
341 | 344 | ||
342 | struct ehca_create_qp_resp { | 345 | struct ehca_create_qp_resp { |
@@ -347,7 +350,8 @@ struct ehca_create_qp_resp { | |||
347 | u32 qkey; | 350 | u32 qkey; |
348 | /* qp_num assigned by ehca: sqp0/1 may have got different numbers */ | 351 | /* qp_num assigned by ehca: sqp0/1 may have got different numbers */ |
349 | u32 real_qp_num; | 352 | u32 real_qp_num; |
350 | u32 dummy; /* padding for 8 byte alignment */ | 353 | u32 fw_handle_ofs; |
354 | u32 dummy; | ||
351 | struct ipzu_queue_resp ipz_squeue; | 355 | struct ipzu_queue_resp ipz_squeue; |
352 | struct ipzu_queue_resp ipz_rqueue; | 356 | struct ipzu_queue_resp ipz_rqueue; |
353 | }; | 357 | }; |
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c index 81aff36101ba..79c25f51c21e 100644 --- a/drivers/infiniband/hw/ehca/ehca_cq.c +++ b/drivers/infiniband/hw/ehca/ehca_cq.c | |||
@@ -166,7 +166,6 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, | |||
166 | write_lock_irqsave(&ehca_cq_idr_lock, flags); | 166 | write_lock_irqsave(&ehca_cq_idr_lock, flags); |
167 | ret = idr_get_new(&ehca_cq_idr, my_cq, &my_cq->token); | 167 | ret = idr_get_new(&ehca_cq_idr, my_cq, &my_cq->token); |
168 | write_unlock_irqrestore(&ehca_cq_idr_lock, flags); | 168 | write_unlock_irqrestore(&ehca_cq_idr_lock, flags); |
169 | |||
170 | } while (ret == -EAGAIN); | 169 | } while (ret == -EAGAIN); |
171 | 170 | ||
172 | if (ret) { | 171 | if (ret) { |
@@ -176,6 +175,12 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, | |||
176 | goto create_cq_exit1; | 175 | goto create_cq_exit1; |
177 | } | 176 | } |
178 | 177 | ||
178 | if (my_cq->token > 0x1FFFFFF) { | ||
179 | cq = ERR_PTR(-ENOMEM); | ||
180 | ehca_err(device, "Invalid number of cq. device=%p", device); | ||
181 | goto create_cq_exit2; | ||
182 | } | ||
183 | |||
179 | /* | 184 | /* |
180 | * CQs maximum depth is 4GB-64, but we need additional 20 as buffer | 185 | * CQs maximum depth is 4GB-64, but we need additional 20 as buffer |
181 | * for receiving errors CQEs. | 186 | * for receiving errors CQEs. |
@@ -185,7 +190,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, | |||
185 | 190 | ||
186 | if (h_ret != H_SUCCESS) { | 191 | if (h_ret != H_SUCCESS) { |
187 | ehca_err(device, "hipz_h_alloc_resource_cq() failed " | 192 | ehca_err(device, "hipz_h_alloc_resource_cq() failed " |
188 | "h_ret=%lx device=%p", h_ret, device); | 193 | "h_ret=%li device=%p", h_ret, device); |
189 | cq = ERR_PTR(ehca2ib_return_code(h_ret)); | 194 | cq = ERR_PTR(ehca2ib_return_code(h_ret)); |
190 | goto create_cq_exit2; | 195 | goto create_cq_exit2; |
191 | } | 196 | } |
@@ -193,7 +198,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, | |||
193 | ipz_rc = ipz_queue_ctor(NULL, &my_cq->ipz_queue, param.act_pages, | 198 | ipz_rc = ipz_queue_ctor(NULL, &my_cq->ipz_queue, param.act_pages, |
194 | EHCA_PAGESIZE, sizeof(struct ehca_cqe), 0, 0); | 199 | EHCA_PAGESIZE, sizeof(struct ehca_cqe), 0, 0); |
195 | if (!ipz_rc) { | 200 | if (!ipz_rc) { |
196 | ehca_err(device, "ipz_queue_ctor() failed ipz_rc=%x device=%p", | 201 | ehca_err(device, "ipz_queue_ctor() failed ipz_rc=%i device=%p", |
197 | ipz_rc, device); | 202 | ipz_rc, device); |
198 | cq = ERR_PTR(-EINVAL); | 203 | cq = ERR_PTR(-EINVAL); |
199 | goto create_cq_exit3; | 204 | goto create_cq_exit3; |
@@ -221,7 +226,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, | |||
221 | 226 | ||
222 | if (h_ret < H_SUCCESS) { | 227 | if (h_ret < H_SUCCESS) { |
223 | ehca_err(device, "hipz_h_register_rpage_cq() failed " | 228 | ehca_err(device, "hipz_h_register_rpage_cq() failed " |
224 | "ehca_cq=%p cq_num=%x h_ret=%lx counter=%i " | 229 | "ehca_cq=%p cq_num=%x h_ret=%li counter=%i " |
225 | "act_pages=%i", my_cq, my_cq->cq_number, | 230 | "act_pages=%i", my_cq, my_cq->cq_number, |
226 | h_ret, counter, param.act_pages); | 231 | h_ret, counter, param.act_pages); |
227 | cq = ERR_PTR(-EINVAL); | 232 | cq = ERR_PTR(-EINVAL); |
@@ -233,7 +238,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, | |||
233 | if ((h_ret != H_SUCCESS) || vpage) { | 238 | if ((h_ret != H_SUCCESS) || vpage) { |
234 | ehca_err(device, "Registration of pages not " | 239 | ehca_err(device, "Registration of pages not " |
235 | "complete ehca_cq=%p cq_num=%x " | 240 | "complete ehca_cq=%p cq_num=%x " |
236 | "h_ret=%lx", my_cq, my_cq->cq_number, | 241 | "h_ret=%li", my_cq, my_cq->cq_number, |
237 | h_ret); | 242 | h_ret); |
238 | cq = ERR_PTR(-EAGAIN); | 243 | cq = ERR_PTR(-EAGAIN); |
239 | goto create_cq_exit4; | 244 | goto create_cq_exit4; |
@@ -241,7 +246,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, | |||
241 | } else { | 246 | } else { |
242 | if (h_ret != H_PAGE_REGISTERED) { | 247 | if (h_ret != H_PAGE_REGISTERED) { |
243 | ehca_err(device, "Registration of page failed " | 248 | ehca_err(device, "Registration of page failed " |
244 | "ehca_cq=%p cq_num=%x h_ret=%lx" | 249 | "ehca_cq=%p cq_num=%x h_ret=%li" |
245 | "counter=%i act_pages=%i", | 250 | "counter=%i act_pages=%i", |
246 | my_cq, my_cq->cq_number, | 251 | my_cq, my_cq->cq_number, |
247 | h_ret, counter, param.act_pages); | 252 | h_ret, counter, param.act_pages); |
@@ -276,6 +281,8 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, | |||
276 | resp.ipz_queue.queue_length = ipz_queue->queue_length; | 281 | resp.ipz_queue.queue_length = ipz_queue->queue_length; |
277 | resp.ipz_queue.pagesize = ipz_queue->pagesize; | 282 | resp.ipz_queue.pagesize = ipz_queue->pagesize; |
278 | resp.ipz_queue.toggle_state = ipz_queue->toggle_state; | 283 | resp.ipz_queue.toggle_state = ipz_queue->toggle_state; |
284 | resp.fw_handle_ofs = (u32) | ||
285 | (my_cq->galpas.user.fw_handle & (PAGE_SIZE - 1)); | ||
279 | if (ib_copy_to_udata(udata, &resp, sizeof(resp))) { | 286 | if (ib_copy_to_udata(udata, &resp, sizeof(resp))) { |
280 | ehca_err(device, "Copy to udata failed."); | 287 | ehca_err(device, "Copy to udata failed."); |
281 | goto create_cq_exit4; | 288 | goto create_cq_exit4; |
@@ -291,7 +298,7 @@ create_cq_exit3: | |||
291 | h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 1); | 298 | h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 1); |
292 | if (h_ret != H_SUCCESS) | 299 | if (h_ret != H_SUCCESS) |
293 | ehca_err(device, "hipz_h_destroy_cq() failed ehca_cq=%p " | 300 | ehca_err(device, "hipz_h_destroy_cq() failed ehca_cq=%p " |
294 | "cq_num=%x h_ret=%lx", my_cq, my_cq->cq_number, h_ret); | 301 | "cq_num=%x h_ret=%li", my_cq, my_cq->cq_number, h_ret); |
295 | 302 | ||
296 | create_cq_exit2: | 303 | create_cq_exit2: |
297 | write_lock_irqsave(&ehca_cq_idr_lock, flags); | 304 | write_lock_irqsave(&ehca_cq_idr_lock, flags); |
@@ -355,7 +362,7 @@ int ehca_destroy_cq(struct ib_cq *cq) | |||
355 | cq_num); | 362 | cq_num); |
356 | } | 363 | } |
357 | if (h_ret != H_SUCCESS) { | 364 | if (h_ret != H_SUCCESS) { |
358 | ehca_err(device, "hipz_h_destroy_cq() failed h_ret=%lx " | 365 | ehca_err(device, "hipz_h_destroy_cq() failed h_ret=%li " |
359 | "ehca_cq=%p cq_num=%x", h_ret, my_cq, cq_num); | 366 | "ehca_cq=%p cq_num=%x", h_ret, my_cq, cq_num); |
360 | return ehca2ib_return_code(h_ret); | 367 | return ehca2ib_return_code(h_ret); |
361 | } | 368 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c index fc19ef9fd963..4aa3ffa6a19f 100644 --- a/drivers/infiniband/hw/ehca/ehca_hca.c +++ b/drivers/infiniband/hw/ehca/ehca_hca.c | |||
@@ -82,33 +82,37 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) | |||
82 | props->vendor_id = rblock->vendor_id >> 8; | 82 | props->vendor_id = rblock->vendor_id >> 8; |
83 | props->vendor_part_id = rblock->vendor_part_id >> 16; | 83 | props->vendor_part_id = rblock->vendor_part_id >> 16; |
84 | props->hw_ver = rblock->hw_ver; | 84 | props->hw_ver = rblock->hw_ver; |
85 | props->max_qp = min_t(int, rblock->max_qp, INT_MAX); | 85 | props->max_qp = min_t(unsigned, rblock->max_qp, INT_MAX); |
86 | props->max_qp_wr = min_t(int, rblock->max_wqes_wq, INT_MAX); | 86 | props->max_qp_wr = min_t(unsigned, rblock->max_wqes_wq, INT_MAX); |
87 | props->max_sge = min_t(int, rblock->max_sge, INT_MAX); | 87 | props->max_sge = min_t(unsigned, rblock->max_sge, INT_MAX); |
88 | props->max_sge_rd = min_t(int, rblock->max_sge_rd, INT_MAX); | 88 | props->max_sge_rd = min_t(unsigned, rblock->max_sge_rd, INT_MAX); |
89 | props->max_cq = min_t(int, rblock->max_cq, INT_MAX); | 89 | props->max_cq = min_t(unsigned, rblock->max_cq, INT_MAX); |
90 | props->max_cqe = min_t(int, rblock->max_cqe, INT_MAX); | 90 | props->max_cqe = min_t(unsigned, rblock->max_cqe, INT_MAX); |
91 | props->max_mr = min_t(int, rblock->max_mr, INT_MAX); | 91 | props->max_mr = min_t(unsigned, rblock->max_mr, INT_MAX); |
92 | props->max_mw = min_t(int, rblock->max_mw, INT_MAX); | 92 | props->max_mw = min_t(unsigned, rblock->max_mw, INT_MAX); |
93 | props->max_pd = min_t(int, rblock->max_pd, INT_MAX); | 93 | props->max_pd = min_t(unsigned, rblock->max_pd, INT_MAX); |
94 | props->max_ah = min_t(int, rblock->max_ah, INT_MAX); | 94 | props->max_ah = min_t(unsigned, rblock->max_ah, INT_MAX); |
95 | props->max_fmr = min_t(int, rblock->max_mr, INT_MAX); | 95 | props->max_fmr = min_t(unsigned, rblock->max_mr, INT_MAX); |
96 | props->max_srq = 0; | 96 | |
97 | props->max_srq_wr = 0; | 97 | if (EHCA_BMASK_GET(HCA_CAP_SRQ, shca->hca_cap)) { |
98 | props->max_srq_sge = 0; | 98 | props->max_srq = props->max_qp; |
99 | props->max_srq_wr = props->max_qp_wr; | ||
100 | props->max_srq_sge = 3; | ||
101 | } | ||
102 | |||
99 | props->max_pkeys = 16; | 103 | props->max_pkeys = 16; |
100 | props->local_ca_ack_delay | 104 | props->local_ca_ack_delay |
101 | = rblock->local_ca_ack_delay; | 105 | = rblock->local_ca_ack_delay; |
102 | props->max_raw_ipv6_qp | 106 | props->max_raw_ipv6_qp |
103 | = min_t(int, rblock->max_raw_ipv6_qp, INT_MAX); | 107 | = min_t(unsigned, rblock->max_raw_ipv6_qp, INT_MAX); |
104 | props->max_raw_ethy_qp | 108 | props->max_raw_ethy_qp |
105 | = min_t(int, rblock->max_raw_ethy_qp, INT_MAX); | 109 | = min_t(unsigned, rblock->max_raw_ethy_qp, INT_MAX); |
106 | props->max_mcast_grp | 110 | props->max_mcast_grp |
107 | = min_t(int, rblock->max_mcast_grp, INT_MAX); | 111 | = min_t(unsigned, rblock->max_mcast_grp, INT_MAX); |
108 | props->max_mcast_qp_attach | 112 | props->max_mcast_qp_attach |
109 | = min_t(int, rblock->max_mcast_qp_attach, INT_MAX); | 113 | = min_t(unsigned, rblock->max_mcast_qp_attach, INT_MAX); |
110 | props->max_total_mcast_qp_attach | 114 | props->max_total_mcast_qp_attach |
111 | = min_t(int, rblock->max_total_mcast_qp_attach, INT_MAX); | 115 | = min_t(unsigned, rblock->max_total_mcast_qp_attach, INT_MAX); |
112 | 116 | ||
113 | /* translate device capabilities */ | 117 | /* translate device capabilities */ |
114 | props->device_cap_flags = IB_DEVICE_SYS_IMAGE_GUID | | 118 | props->device_cap_flags = IB_DEVICE_SYS_IMAGE_GUID | |
@@ -348,7 +352,7 @@ int ehca_modify_port(struct ib_device *ibdev, | |||
348 | hret = hipz_h_modify_port(shca->ipz_hca_handle, port, | 352 | hret = hipz_h_modify_port(shca->ipz_hca_handle, port, |
349 | cap, props->init_type, port_modify_mask); | 353 | cap, props->init_type, port_modify_mask); |
350 | if (hret != H_SUCCESS) { | 354 | if (hret != H_SUCCESS) { |
351 | ehca_err(&shca->ib_device, "Modify port failed hret=%lx", | 355 | ehca_err(&shca->ib_device, "Modify port failed h_ret=%li", |
352 | hret); | 356 | hret); |
353 | ret = -EINVAL; | 357 | ret = -EINVAL; |
354 | } | 358 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index ee06d8bd7396..3f617b27b954 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c | |||
@@ -69,9 +69,6 @@ | |||
69 | static void queue_comp_task(struct ehca_cq *__cq); | 69 | static void queue_comp_task(struct ehca_cq *__cq); |
70 | 70 | ||
71 | static struct ehca_comp_pool *pool; | 71 | static struct ehca_comp_pool *pool; |
72 | #ifdef CONFIG_HOTPLUG_CPU | ||
73 | static struct notifier_block comp_pool_callback_nb; | ||
74 | #endif | ||
75 | 72 | ||
76 | static inline void comp_event_callback(struct ehca_cq *cq) | 73 | static inline void comp_event_callback(struct ehca_cq *cq) |
77 | { | 74 | { |
@@ -175,41 +172,55 @@ error_data1: | |||
175 | 172 | ||
176 | } | 173 | } |
177 | 174 | ||
178 | static void qp_event_callback(struct ehca_shca *shca, u64 eqe, | 175 | static void dispatch_qp_event(struct ehca_shca *shca, struct ehca_qp *qp, |
179 | enum ib_event_type event_type, int fatal) | 176 | enum ib_event_type event_type) |
180 | { | 177 | { |
181 | struct ib_event event; | 178 | struct ib_event event; |
182 | struct ehca_qp *qp; | ||
183 | u32 token = EHCA_BMASK_GET(EQE_QP_TOKEN, eqe); | ||
184 | |||
185 | read_lock(&ehca_qp_idr_lock); | ||
186 | qp = idr_find(&ehca_qp_idr, token); | ||
187 | read_unlock(&ehca_qp_idr_lock); | ||
188 | |||
189 | |||
190 | if (!qp) | ||
191 | return; | ||
192 | |||
193 | if (fatal) | ||
194 | ehca_error_data(shca, qp, qp->ipz_qp_handle.handle); | ||
195 | 179 | ||
196 | event.device = &shca->ib_device; | 180 | event.device = &shca->ib_device; |
181 | event.event = event_type; | ||
197 | 182 | ||
198 | if (qp->ext_type == EQPT_SRQ) { | 183 | if (qp->ext_type == EQPT_SRQ) { |
199 | if (!qp->ib_srq.event_handler) | 184 | if (!qp->ib_srq.event_handler) |
200 | return; | 185 | return; |
201 | 186 | ||
202 | event.event = fatal ? IB_EVENT_SRQ_ERR : event_type; | ||
203 | event.element.srq = &qp->ib_srq; | 187 | event.element.srq = &qp->ib_srq; |
204 | qp->ib_srq.event_handler(&event, qp->ib_srq.srq_context); | 188 | qp->ib_srq.event_handler(&event, qp->ib_srq.srq_context); |
205 | } else { | 189 | } else { |
206 | if (!qp->ib_qp.event_handler) | 190 | if (!qp->ib_qp.event_handler) |
207 | return; | 191 | return; |
208 | 192 | ||
209 | event.event = event_type; | ||
210 | event.element.qp = &qp->ib_qp; | 193 | event.element.qp = &qp->ib_qp; |
211 | qp->ib_qp.event_handler(&event, qp->ib_qp.qp_context); | 194 | qp->ib_qp.event_handler(&event, qp->ib_qp.qp_context); |
212 | } | 195 | } |
196 | } | ||
197 | |||
198 | static void qp_event_callback(struct ehca_shca *shca, u64 eqe, | ||
199 | enum ib_event_type event_type, int fatal) | ||
200 | { | ||
201 | struct ehca_qp *qp; | ||
202 | u32 token = EHCA_BMASK_GET(EQE_QP_TOKEN, eqe); | ||
203 | |||
204 | read_lock(&ehca_qp_idr_lock); | ||
205 | qp = idr_find(&ehca_qp_idr, token); | ||
206 | read_unlock(&ehca_qp_idr_lock); | ||
207 | |||
208 | if (!qp) | ||
209 | return; | ||
210 | |||
211 | if (fatal) | ||
212 | ehca_error_data(shca, qp, qp->ipz_qp_handle.handle); | ||
213 | |||
214 | dispatch_qp_event(shca, qp, fatal && qp->ext_type == EQPT_SRQ ? | ||
215 | IB_EVENT_SRQ_ERR : event_type); | ||
216 | |||
217 | /* | ||
218 | * eHCA only processes one WQE at a time for SRQ base QPs, | ||
219 | * so the last WQE has been processed as soon as the QP enters | ||
220 | * error state. | ||
221 | */ | ||
222 | if (fatal && qp->ext_type == EQPT_SRQBASE) | ||
223 | dispatch_qp_event(shca, qp, IB_EVENT_QP_LAST_WQE_REACHED); | ||
213 | 224 | ||
214 | return; | 225 | return; |
215 | } | 226 | } |
@@ -280,8 +291,8 @@ static void parse_identifier(struct ehca_shca *shca, u64 eqe) | |||
280 | case 0x11: /* unaffiliated access error */ | 291 | case 0x11: /* unaffiliated access error */ |
281 | ehca_err(&shca->ib_device, "Unaffiliated access error."); | 292 | ehca_err(&shca->ib_device, "Unaffiliated access error."); |
282 | break; | 293 | break; |
283 | case 0x12: /* path migrating error */ | 294 | case 0x12: /* path migrating */ |
284 | ehca_err(&shca->ib_device, "Path migration error."); | 295 | ehca_err(&shca->ib_device, "Path migrating."); |
285 | break; | 296 | break; |
286 | case 0x13: /* interface trace stopped */ | 297 | case 0x13: /* interface trace stopped */ |
287 | ehca_err(&shca->ib_device, "Interface trace stopped."); | 298 | ehca_err(&shca->ib_device, "Interface trace stopped."); |
@@ -746,9 +757,7 @@ static void destroy_comp_task(struct ehca_comp_pool *pool, | |||
746 | kthread_stop(task); | 757 | kthread_stop(task); |
747 | } | 758 | } |
748 | 759 | ||
749 | #ifdef CONFIG_HOTPLUG_CPU | 760 | static void __cpuinit take_over_work(struct ehca_comp_pool *pool, int cpu) |
750 | static void take_over_work(struct ehca_comp_pool *pool, | ||
751 | int cpu) | ||
752 | { | 761 | { |
753 | struct ehca_cpu_comp_task *cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu); | 762 | struct ehca_cpu_comp_task *cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu); |
754 | LIST_HEAD(list); | 763 | LIST_HEAD(list); |
@@ -771,9 +780,9 @@ static void take_over_work(struct ehca_comp_pool *pool, | |||
771 | 780 | ||
772 | } | 781 | } |
773 | 782 | ||
774 | static int comp_pool_callback(struct notifier_block *nfb, | 783 | static int __cpuinit comp_pool_callback(struct notifier_block *nfb, |
775 | unsigned long action, | 784 | unsigned long action, |
776 | void *hcpu) | 785 | void *hcpu) |
777 | { | 786 | { |
778 | unsigned int cpu = (unsigned long)hcpu; | 787 | unsigned int cpu = (unsigned long)hcpu; |
779 | struct ehca_cpu_comp_task *cct; | 788 | struct ehca_cpu_comp_task *cct; |
@@ -819,7 +828,11 @@ static int comp_pool_callback(struct notifier_block *nfb, | |||
819 | 828 | ||
820 | return NOTIFY_OK; | 829 | return NOTIFY_OK; |
821 | } | 830 | } |
822 | #endif | 831 | |
832 | static struct notifier_block comp_pool_callback_nb __cpuinitdata = { | ||
833 | .notifier_call = comp_pool_callback, | ||
834 | .priority = 0, | ||
835 | }; | ||
823 | 836 | ||
824 | int ehca_create_comp_pool(void) | 837 | int ehca_create_comp_pool(void) |
825 | { | 838 | { |
@@ -850,11 +863,7 @@ int ehca_create_comp_pool(void) | |||
850 | } | 863 | } |
851 | } | 864 | } |
852 | 865 | ||
853 | #ifdef CONFIG_HOTPLUG_CPU | 866 | register_hotcpu_notifier(&comp_pool_callback_nb); |
854 | comp_pool_callback_nb.notifier_call = comp_pool_callback; | ||
855 | comp_pool_callback_nb.priority = 0; | ||
856 | register_cpu_notifier(&comp_pool_callback_nb); | ||
857 | #endif | ||
858 | 867 | ||
859 | printk(KERN_INFO "eHCA scaling code enabled\n"); | 868 | printk(KERN_INFO "eHCA scaling code enabled\n"); |
860 | 869 | ||
@@ -868,9 +877,7 @@ void ehca_destroy_comp_pool(void) | |||
868 | if (!ehca_scaling_code) | 877 | if (!ehca_scaling_code) |
869 | return; | 878 | return; |
870 | 879 | ||
871 | #ifdef CONFIG_HOTPLUG_CPU | 880 | unregister_hotcpu_notifier(&comp_pool_callback_nb); |
872 | unregister_cpu_notifier(&comp_pool_callback_nb); | ||
873 | #endif | ||
874 | 881 | ||
875 | for (i = 0; i < NR_CPUS; i++) { | 882 | for (i = 0; i < NR_CPUS; i++) { |
876 | if (cpu_online(i)) | 883 | if (cpu_online(i)) |
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 99036b65bb84..403467f66fe6 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c | |||
@@ -49,10 +49,12 @@ | |||
49 | #include "ehca_tools.h" | 49 | #include "ehca_tools.h" |
50 | #include "hcp_if.h" | 50 | #include "hcp_if.h" |
51 | 51 | ||
52 | #define HCAD_VERSION "0024" | ||
53 | |||
52 | MODULE_LICENSE("Dual BSD/GPL"); | 54 | MODULE_LICENSE("Dual BSD/GPL"); |
53 | MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>"); | 55 | MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>"); |
54 | MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver"); | 56 | MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver"); |
55 | MODULE_VERSION("SVNEHCA_0023"); | 57 | MODULE_VERSION(HCAD_VERSION); |
56 | 58 | ||
57 | int ehca_open_aqp1 = 0; | 59 | int ehca_open_aqp1 = 0; |
58 | int ehca_debug_level = 0; | 60 | int ehca_debug_level = 0; |
@@ -65,16 +67,16 @@ int ehca_static_rate = -1; | |||
65 | int ehca_scaling_code = 0; | 67 | int ehca_scaling_code = 0; |
66 | int ehca_mr_largepage = 0; | 68 | int ehca_mr_largepage = 0; |
67 | 69 | ||
68 | module_param_named(open_aqp1, ehca_open_aqp1, int, 0); | 70 | module_param_named(open_aqp1, ehca_open_aqp1, int, S_IRUGO); |
69 | module_param_named(debug_level, ehca_debug_level, int, 0); | 71 | module_param_named(debug_level, ehca_debug_level, int, S_IRUGO); |
70 | module_param_named(hw_level, ehca_hw_level, int, 0); | 72 | module_param_named(hw_level, ehca_hw_level, int, S_IRUGO); |
71 | module_param_named(nr_ports, ehca_nr_ports, int, 0); | 73 | module_param_named(nr_ports, ehca_nr_ports, int, S_IRUGO); |
72 | module_param_named(use_hp_mr, ehca_use_hp_mr, int, 0); | 74 | module_param_named(use_hp_mr, ehca_use_hp_mr, int, S_IRUGO); |
73 | module_param_named(port_act_time, ehca_port_act_time, int, 0); | 75 | module_param_named(port_act_time, ehca_port_act_time, int, S_IRUGO); |
74 | module_param_named(poll_all_eqs, ehca_poll_all_eqs, int, 0); | 76 | module_param_named(poll_all_eqs, ehca_poll_all_eqs, int, S_IRUGO); |
75 | module_param_named(static_rate, ehca_static_rate, int, 0); | 77 | module_param_named(static_rate, ehca_static_rate, int, S_IRUGO); |
76 | module_param_named(scaling_code, ehca_scaling_code, int, 0); | 78 | module_param_named(scaling_code, ehca_scaling_code, int, S_IRUGO); |
77 | module_param_named(mr_largepage, ehca_mr_largepage, int, 0); | 79 | module_param_named(mr_largepage, ehca_mr_largepage, int, S_IRUGO); |
78 | 80 | ||
79 | MODULE_PARM_DESC(open_aqp1, | 81 | MODULE_PARM_DESC(open_aqp1, |
80 | "AQP1 on startup (0: no (default), 1: yes)"); | 82 | "AQP1 on startup (0: no (default), 1: yes)"); |
@@ -273,7 +275,7 @@ int ehca_sense_attributes(struct ehca_shca *shca) | |||
273 | 275 | ||
274 | h_ret = hipz_h_query_hca(shca->ipz_hca_handle, rblock); | 276 | h_ret = hipz_h_query_hca(shca->ipz_hca_handle, rblock); |
275 | if (h_ret != H_SUCCESS) { | 277 | if (h_ret != H_SUCCESS) { |
276 | ehca_gen_err("Cannot query device properties. h_ret=%lx", | 278 | ehca_gen_err("Cannot query device properties. h_ret=%li", |
277 | h_ret); | 279 | h_ret); |
278 | ret = -EPERM; | 280 | ret = -EPERM; |
279 | goto sense_attributes1; | 281 | goto sense_attributes1; |
@@ -332,7 +334,7 @@ int ehca_sense_attributes(struct ehca_shca *shca) | |||
332 | port = (struct hipz_query_port *)rblock; | 334 | port = (struct hipz_query_port *)rblock; |
333 | h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port); | 335 | h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port); |
334 | if (h_ret != H_SUCCESS) { | 336 | if (h_ret != H_SUCCESS) { |
335 | ehca_gen_err("Cannot query port properties. h_ret=%lx", | 337 | ehca_gen_err("Cannot query port properties. h_ret=%li", |
336 | h_ret); | 338 | h_ret); |
337 | ret = -EPERM; | 339 | ret = -EPERM; |
338 | goto sense_attributes1; | 340 | goto sense_attributes1; |
@@ -380,7 +382,7 @@ int ehca_init_device(struct ehca_shca *shca) | |||
380 | strlcpy(shca->ib_device.name, "ehca%d", IB_DEVICE_NAME_MAX); | 382 | strlcpy(shca->ib_device.name, "ehca%d", IB_DEVICE_NAME_MAX); |
381 | shca->ib_device.owner = THIS_MODULE; | 383 | shca->ib_device.owner = THIS_MODULE; |
382 | 384 | ||
383 | shca->ib_device.uverbs_abi_ver = 7; | 385 | shca->ib_device.uverbs_abi_ver = 8; |
384 | shca->ib_device.uverbs_cmd_mask = | 386 | shca->ib_device.uverbs_cmd_mask = |
385 | (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) | | 387 | (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) | |
386 | (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) | | 388 | (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) | |
@@ -526,13 +528,13 @@ static int ehca_destroy_aqp1(struct ehca_sport *sport) | |||
526 | 528 | ||
527 | ret = ib_destroy_qp(sport->ibqp_aqp1); | 529 | ret = ib_destroy_qp(sport->ibqp_aqp1); |
528 | if (ret) { | 530 | if (ret) { |
529 | ehca_gen_err("Cannot destroy AQP1 QP. ret=%x", ret); | 531 | ehca_gen_err("Cannot destroy AQP1 QP. ret=%i", ret); |
530 | return ret; | 532 | return ret; |
531 | } | 533 | } |
532 | 534 | ||
533 | ret = ib_destroy_cq(sport->ibcq_aqp1); | 535 | ret = ib_destroy_cq(sport->ibcq_aqp1); |
534 | if (ret) | 536 | if (ret) |
535 | ehca_gen_err("Cannot destroy AQP1 CQ. ret=%x", ret); | 537 | ehca_gen_err("Cannot destroy AQP1 CQ. ret=%i", ret); |
536 | 538 | ||
537 | return ret; | 539 | return ret; |
538 | } | 540 | } |
@@ -728,7 +730,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev, | |||
728 | ret = ehca_reg_internal_maxmr(shca, shca->pd, &shca->maxmr); | 730 | ret = ehca_reg_internal_maxmr(shca, shca->pd, &shca->maxmr); |
729 | 731 | ||
730 | if (ret) { | 732 | if (ret) { |
731 | ehca_err(&shca->ib_device, "Cannot create internal MR ret=%x", | 733 | ehca_err(&shca->ib_device, "Cannot create internal MR ret=%i", |
732 | ret); | 734 | ret); |
733 | goto probe5; | 735 | goto probe5; |
734 | } | 736 | } |
@@ -736,7 +738,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev, | |||
736 | ret = ib_register_device(&shca->ib_device); | 738 | ret = ib_register_device(&shca->ib_device); |
737 | if (ret) { | 739 | if (ret) { |
738 | ehca_err(&shca->ib_device, | 740 | ehca_err(&shca->ib_device, |
739 | "ib_register_device() failed ret=%x", ret); | 741 | "ib_register_device() failed ret=%i", ret); |
740 | goto probe6; | 742 | goto probe6; |
741 | } | 743 | } |
742 | 744 | ||
@@ -777,7 +779,7 @@ probe8: | |||
777 | ret = ehca_destroy_aqp1(&shca->sport[0]); | 779 | ret = ehca_destroy_aqp1(&shca->sport[0]); |
778 | if (ret) | 780 | if (ret) |
779 | ehca_err(&shca->ib_device, | 781 | ehca_err(&shca->ib_device, |
780 | "Cannot destroy AQP1 for port 1. ret=%x", ret); | 782 | "Cannot destroy AQP1 for port 1. ret=%i", ret); |
781 | 783 | ||
782 | probe7: | 784 | probe7: |
783 | ib_unregister_device(&shca->ib_device); | 785 | ib_unregister_device(&shca->ib_device); |
@@ -826,7 +828,7 @@ static int __devexit ehca_remove(struct ibmebus_dev *dev) | |||
826 | if (ret) | 828 | if (ret) |
827 | ehca_err(&shca->ib_device, | 829 | ehca_err(&shca->ib_device, |
828 | "Cannot destroy AQP1 for port %x " | 830 | "Cannot destroy AQP1 for port %x " |
829 | "ret=%x", ret, i); | 831 | "ret=%i", ret, i); |
830 | } | 832 | } |
831 | } | 833 | } |
832 | 834 | ||
@@ -835,20 +837,20 @@ static int __devexit ehca_remove(struct ibmebus_dev *dev) | |||
835 | ret = ehca_dereg_internal_maxmr(shca); | 837 | ret = ehca_dereg_internal_maxmr(shca); |
836 | if (ret) | 838 | if (ret) |
837 | ehca_err(&shca->ib_device, | 839 | ehca_err(&shca->ib_device, |
838 | "Cannot destroy internal MR. ret=%x", ret); | 840 | "Cannot destroy internal MR. ret=%i", ret); |
839 | 841 | ||
840 | ret = ehca_dealloc_pd(&shca->pd->ib_pd); | 842 | ret = ehca_dealloc_pd(&shca->pd->ib_pd); |
841 | if (ret) | 843 | if (ret) |
842 | ehca_err(&shca->ib_device, | 844 | ehca_err(&shca->ib_device, |
843 | "Cannot destroy internal PD. ret=%x", ret); | 845 | "Cannot destroy internal PD. ret=%i", ret); |
844 | 846 | ||
845 | ret = ehca_destroy_eq(shca, &shca->eq); | 847 | ret = ehca_destroy_eq(shca, &shca->eq); |
846 | if (ret) | 848 | if (ret) |
847 | ehca_err(&shca->ib_device, "Cannot destroy EQ. ret=%x", ret); | 849 | ehca_err(&shca->ib_device, "Cannot destroy EQ. ret=%i", ret); |
848 | 850 | ||
849 | ret = ehca_destroy_eq(shca, &shca->neq); | 851 | ret = ehca_destroy_eq(shca, &shca->neq); |
850 | if (ret) | 852 | if (ret) |
851 | ehca_err(&shca->ib_device, "Canot destroy NEQ. ret=%x", ret); | 853 | ehca_err(&shca->ib_device, "Canot destroy NEQ. ret=%i", ret); |
852 | 854 | ||
853 | ib_dealloc_device(&shca->ib_device); | 855 | ib_dealloc_device(&shca->ib_device); |
854 | 856 | ||
@@ -909,7 +911,7 @@ int __init ehca_module_init(void) | |||
909 | int ret; | 911 | int ret; |
910 | 912 | ||
911 | printk(KERN_INFO "eHCA Infiniband Device Driver " | 913 | printk(KERN_INFO "eHCA Infiniband Device Driver " |
912 | "(Rel.: SVNEHCA_0023)\n"); | 914 | "(Version " HCAD_VERSION ")\n"); |
913 | 915 | ||
914 | ret = ehca_create_comp_pool(); | 916 | ret = ehca_create_comp_pool(); |
915 | if (ret) { | 917 | if (ret) { |
diff --git a/drivers/infiniband/hw/ehca/ehca_mcast.c b/drivers/infiniband/hw/ehca/ehca_mcast.c index 32a870660bfe..e3ef0264ccc6 100644 --- a/drivers/infiniband/hw/ehca/ehca_mcast.c +++ b/drivers/infiniband/hw/ehca/ehca_mcast.c | |||
@@ -88,7 +88,7 @@ int ehca_attach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
88 | if (h_ret != H_SUCCESS) | 88 | if (h_ret != H_SUCCESS) |
89 | ehca_err(ibqp->device, | 89 | ehca_err(ibqp->device, |
90 | "ehca_qp=%p qp_num=%x hipz_h_attach_mcqp() failed " | 90 | "ehca_qp=%p qp_num=%x hipz_h_attach_mcqp() failed " |
91 | "h_ret=%lx", my_qp, ibqp->qp_num, h_ret); | 91 | "h_ret=%li", my_qp, ibqp->qp_num, h_ret); |
92 | 92 | ||
93 | return ehca2ib_return_code(h_ret); | 93 | return ehca2ib_return_code(h_ret); |
94 | } | 94 | } |
@@ -125,7 +125,7 @@ int ehca_detach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | |||
125 | if (h_ret != H_SUCCESS) | 125 | if (h_ret != H_SUCCESS) |
126 | ehca_err(ibqp->device, | 126 | ehca_err(ibqp->device, |
127 | "ehca_qp=%p qp_num=%x hipz_h_detach_mcqp() failed " | 127 | "ehca_qp=%p qp_num=%x hipz_h_detach_mcqp() failed " |
128 | "h_ret=%lx", my_qp, ibqp->qp_num, h_ret); | 128 | "h_ret=%li", my_qp, ibqp->qp_num, h_ret); |
129 | 129 | ||
130 | return ehca2ib_return_code(h_ret); | 130 | return ehca2ib_return_code(h_ret); |
131 | } | 131 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c index d97eda3e1da0..da88738265ed 100644 --- a/drivers/infiniband/hw/ehca/ehca_mrmw.c +++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c | |||
@@ -51,6 +51,7 @@ | |||
51 | 51 | ||
52 | #define NUM_CHUNKS(length, chunk_size) \ | 52 | #define NUM_CHUNKS(length, chunk_size) \ |
53 | (((length) + (chunk_size - 1)) / (chunk_size)) | 53 | (((length) + (chunk_size - 1)) / (chunk_size)) |
54 | |||
54 | /* max number of rpages (per hcall register_rpages) */ | 55 | /* max number of rpages (per hcall register_rpages) */ |
55 | #define MAX_RPAGES 512 | 56 | #define MAX_RPAGES 512 |
56 | 57 | ||
@@ -64,6 +65,11 @@ enum ehca_mr_pgsize { | |||
64 | EHCA_MR_PGSIZE16M = 0x1000000L | 65 | EHCA_MR_PGSIZE16M = 0x1000000L |
65 | }; | 66 | }; |
66 | 67 | ||
68 | #define EHCA_MR_PGSHIFT4K 12 | ||
69 | #define EHCA_MR_PGSHIFT64K 16 | ||
70 | #define EHCA_MR_PGSHIFT1M 20 | ||
71 | #define EHCA_MR_PGSHIFT16M 24 | ||
72 | |||
67 | static u32 ehca_encode_hwpage_size(u32 pgsize) | 73 | static u32 ehca_encode_hwpage_size(u32 pgsize) |
68 | { | 74 | { |
69 | u32 idx = 0; | 75 | u32 idx = 0; |
@@ -159,7 +165,7 @@ struct ib_mr *ehca_get_dma_mr(struct ib_pd *pd, int mr_access_flags) | |||
159 | 165 | ||
160 | get_dma_mr_exit0: | 166 | get_dma_mr_exit0: |
161 | if (IS_ERR(ib_mr)) | 167 | if (IS_ERR(ib_mr)) |
162 | ehca_err(&shca->ib_device, "rc=%lx pd=%p mr_access_flags=%x ", | 168 | ehca_err(&shca->ib_device, "h_ret=%li pd=%p mr_access_flags=%x", |
163 | PTR_ERR(ib_mr), pd, mr_access_flags); | 169 | PTR_ERR(ib_mr), pd, mr_access_flags); |
164 | return ib_mr; | 170 | return ib_mr; |
165 | } /* end ehca_get_dma_mr() */ | 171 | } /* end ehca_get_dma_mr() */ |
@@ -271,7 +277,7 @@ reg_phys_mr_exit1: | |||
271 | ehca_mr_delete(e_mr); | 277 | ehca_mr_delete(e_mr); |
272 | reg_phys_mr_exit0: | 278 | reg_phys_mr_exit0: |
273 | if (IS_ERR(ib_mr)) | 279 | if (IS_ERR(ib_mr)) |
274 | ehca_err(pd->device, "rc=%lx pd=%p phys_buf_array=%p " | 280 | ehca_err(pd->device, "h_ret=%li pd=%p phys_buf_array=%p " |
275 | "num_phys_buf=%x mr_access_flags=%x iova_start=%p", | 281 | "num_phys_buf=%x mr_access_flags=%x iova_start=%p", |
276 | PTR_ERR(ib_mr), pd, phys_buf_array, | 282 | PTR_ERR(ib_mr), pd, phys_buf_array, |
277 | num_phys_buf, mr_access_flags, iova_start); | 283 | num_phys_buf, mr_access_flags, iova_start); |
@@ -347,17 +353,16 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, | |||
347 | /* select proper hw_pgsize */ | 353 | /* select proper hw_pgsize */ |
348 | if (ehca_mr_largepage && | 354 | if (ehca_mr_largepage && |
349 | (shca->hca_cap_mr_pgsize & HCA_CAP_MR_PGSIZE_16M)) { | 355 | (shca->hca_cap_mr_pgsize & HCA_CAP_MR_PGSIZE_16M)) { |
350 | if (length <= EHCA_MR_PGSIZE4K | 356 | int page_shift = PAGE_SHIFT; |
351 | && PAGE_SIZE == EHCA_MR_PGSIZE4K) | 357 | if (e_mr->umem->hugetlb) { |
352 | hwpage_size = EHCA_MR_PGSIZE4K; | 358 | /* determine page_shift, clamp between 4K and 16M */ |
353 | else if (length <= EHCA_MR_PGSIZE64K) | 359 | page_shift = (fls64(length - 1) + 3) & ~3; |
354 | hwpage_size = EHCA_MR_PGSIZE64K; | 360 | page_shift = min(max(page_shift, EHCA_MR_PGSHIFT4K), |
355 | else if (length <= EHCA_MR_PGSIZE1M) | 361 | EHCA_MR_PGSHIFT16M); |
356 | hwpage_size = EHCA_MR_PGSIZE1M; | 362 | } |
357 | else | 363 | hwpage_size = 1UL << page_shift; |
358 | hwpage_size = EHCA_MR_PGSIZE16M; | ||
359 | } else | 364 | } else |
360 | hwpage_size = EHCA_MR_PGSIZE4K; | 365 | hwpage_size = EHCA_MR_PGSIZE4K; /* ehca1 only supports 4k */ |
361 | ehca_dbg(pd->device, "hwpage_size=%lx", hwpage_size); | 366 | ehca_dbg(pd->device, "hwpage_size=%lx", hwpage_size); |
362 | 367 | ||
363 | reg_user_mr_fallback: | 368 | reg_user_mr_fallback: |
@@ -403,8 +408,7 @@ reg_user_mr_exit1: | |||
403 | ehca_mr_delete(e_mr); | 408 | ehca_mr_delete(e_mr); |
404 | reg_user_mr_exit0: | 409 | reg_user_mr_exit0: |
405 | if (IS_ERR(ib_mr)) | 410 | if (IS_ERR(ib_mr)) |
406 | ehca_err(pd->device, "rc=%lx pd=%p mr_access_flags=%x" | 411 | ehca_err(pd->device, "rc=%li pd=%p mr_access_flags=%x udata=%p", |
407 | " udata=%p", | ||
408 | PTR_ERR(ib_mr), pd, mr_access_flags, udata); | 412 | PTR_ERR(ib_mr), pd, mr_access_flags, udata); |
409 | return ib_mr; | 413 | return ib_mr; |
410 | } /* end ehca_reg_user_mr() */ | 414 | } /* end ehca_reg_user_mr() */ |
@@ -565,7 +569,7 @@ rereg_phys_mr_exit1: | |||
565 | spin_unlock_irqrestore(&e_mr->mrlock, sl_flags); | 569 | spin_unlock_irqrestore(&e_mr->mrlock, sl_flags); |
566 | rereg_phys_mr_exit0: | 570 | rereg_phys_mr_exit0: |
567 | if (ret) | 571 | if (ret) |
568 | ehca_err(mr->device, "ret=%x mr=%p mr_rereg_mask=%x pd=%p " | 572 | ehca_err(mr->device, "ret=%i mr=%p mr_rereg_mask=%x pd=%p " |
569 | "phys_buf_array=%p num_phys_buf=%x mr_access_flags=%x " | 573 | "phys_buf_array=%p num_phys_buf=%x mr_access_flags=%x " |
570 | "iova_start=%p", | 574 | "iova_start=%p", |
571 | ret, mr, mr_rereg_mask, pd, phys_buf_array, | 575 | ret, mr, mr_rereg_mask, pd, phys_buf_array, |
@@ -607,7 +611,7 @@ int ehca_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr) | |||
607 | 611 | ||
608 | h_ret = hipz_h_query_mr(shca->ipz_hca_handle, e_mr, &hipzout); | 612 | h_ret = hipz_h_query_mr(shca->ipz_hca_handle, e_mr, &hipzout); |
609 | if (h_ret != H_SUCCESS) { | 613 | if (h_ret != H_SUCCESS) { |
610 | ehca_err(mr->device, "hipz_mr_query failed, h_ret=%lx mr=%p " | 614 | ehca_err(mr->device, "hipz_mr_query failed, h_ret=%li mr=%p " |
611 | "hca_hndl=%lx mr_hndl=%lx lkey=%x", | 615 | "hca_hndl=%lx mr_hndl=%lx lkey=%x", |
612 | h_ret, mr, shca->ipz_hca_handle.handle, | 616 | h_ret, mr, shca->ipz_hca_handle.handle, |
613 | e_mr->ipz_mr_handle.handle, mr->lkey); | 617 | e_mr->ipz_mr_handle.handle, mr->lkey); |
@@ -625,7 +629,7 @@ query_mr_exit1: | |||
625 | spin_unlock_irqrestore(&e_mr->mrlock, sl_flags); | 629 | spin_unlock_irqrestore(&e_mr->mrlock, sl_flags); |
626 | query_mr_exit0: | 630 | query_mr_exit0: |
627 | if (ret) | 631 | if (ret) |
628 | ehca_err(mr->device, "ret=%x mr=%p mr_attr=%p", | 632 | ehca_err(mr->device, "ret=%i mr=%p mr_attr=%p", |
629 | ret, mr, mr_attr); | 633 | ret, mr, mr_attr); |
630 | return ret; | 634 | return ret; |
631 | } /* end ehca_query_mr() */ | 635 | } /* end ehca_query_mr() */ |
@@ -667,7 +671,7 @@ int ehca_dereg_mr(struct ib_mr *mr) | |||
667 | /* TODO: BUSY: MR still has bound window(s) */ | 671 | /* TODO: BUSY: MR still has bound window(s) */ |
668 | h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_mr); | 672 | h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_mr); |
669 | if (h_ret != H_SUCCESS) { | 673 | if (h_ret != H_SUCCESS) { |
670 | ehca_err(mr->device, "hipz_free_mr failed, h_ret=%lx shca=%p " | 674 | ehca_err(mr->device, "hipz_free_mr failed, h_ret=%li shca=%p " |
671 | "e_mr=%p hca_hndl=%lx mr_hndl=%lx mr->lkey=%x", | 675 | "e_mr=%p hca_hndl=%lx mr_hndl=%lx mr->lkey=%x", |
672 | h_ret, shca, e_mr, shca->ipz_hca_handle.handle, | 676 | h_ret, shca, e_mr, shca->ipz_hca_handle.handle, |
673 | e_mr->ipz_mr_handle.handle, mr->lkey); | 677 | e_mr->ipz_mr_handle.handle, mr->lkey); |
@@ -683,7 +687,7 @@ int ehca_dereg_mr(struct ib_mr *mr) | |||
683 | 687 | ||
684 | dereg_mr_exit0: | 688 | dereg_mr_exit0: |
685 | if (ret) | 689 | if (ret) |
686 | ehca_err(mr->device, "ret=%x mr=%p", ret, mr); | 690 | ehca_err(mr->device, "ret=%i mr=%p", ret, mr); |
687 | return ret; | 691 | return ret; |
688 | } /* end ehca_dereg_mr() */ | 692 | } /* end ehca_dereg_mr() */ |
689 | 693 | ||
@@ -708,7 +712,7 @@ struct ib_mw *ehca_alloc_mw(struct ib_pd *pd) | |||
708 | h_ret = hipz_h_alloc_resource_mw(shca->ipz_hca_handle, e_mw, | 712 | h_ret = hipz_h_alloc_resource_mw(shca->ipz_hca_handle, e_mw, |
709 | e_pd->fw_pd, &hipzout); | 713 | e_pd->fw_pd, &hipzout); |
710 | if (h_ret != H_SUCCESS) { | 714 | if (h_ret != H_SUCCESS) { |
711 | ehca_err(pd->device, "hipz_mw_allocate failed, h_ret=%lx " | 715 | ehca_err(pd->device, "hipz_mw_allocate failed, h_ret=%li " |
712 | "shca=%p hca_hndl=%lx mw=%p", | 716 | "shca=%p hca_hndl=%lx mw=%p", |
713 | h_ret, shca, shca->ipz_hca_handle.handle, e_mw); | 717 | h_ret, shca, shca->ipz_hca_handle.handle, e_mw); |
714 | ib_mw = ERR_PTR(ehca2ib_return_code(h_ret)); | 718 | ib_mw = ERR_PTR(ehca2ib_return_code(h_ret)); |
@@ -723,7 +727,7 @@ alloc_mw_exit1: | |||
723 | ehca_mw_delete(e_mw); | 727 | ehca_mw_delete(e_mw); |
724 | alloc_mw_exit0: | 728 | alloc_mw_exit0: |
725 | if (IS_ERR(ib_mw)) | 729 | if (IS_ERR(ib_mw)) |
726 | ehca_err(pd->device, "rc=%lx pd=%p", PTR_ERR(ib_mw), pd); | 730 | ehca_err(pd->device, "h_ret=%li pd=%p", PTR_ERR(ib_mw), pd); |
727 | return ib_mw; | 731 | return ib_mw; |
728 | } /* end ehca_alloc_mw() */ | 732 | } /* end ehca_alloc_mw() */ |
729 | 733 | ||
@@ -750,7 +754,7 @@ int ehca_dealloc_mw(struct ib_mw *mw) | |||
750 | 754 | ||
751 | h_ret = hipz_h_free_resource_mw(shca->ipz_hca_handle, e_mw); | 755 | h_ret = hipz_h_free_resource_mw(shca->ipz_hca_handle, e_mw); |
752 | if (h_ret != H_SUCCESS) { | 756 | if (h_ret != H_SUCCESS) { |
753 | ehca_err(mw->device, "hipz_free_mw failed, h_ret=%lx shca=%p " | 757 | ehca_err(mw->device, "hipz_free_mw failed, h_ret=%li shca=%p " |
754 | "mw=%p rkey=%x hca_hndl=%lx mw_hndl=%lx", | 758 | "mw=%p rkey=%x hca_hndl=%lx mw_hndl=%lx", |
755 | h_ret, shca, mw, mw->rkey, shca->ipz_hca_handle.handle, | 759 | h_ret, shca, mw, mw->rkey, shca->ipz_hca_handle.handle, |
756 | e_mw->ipz_mw_handle.handle); | 760 | e_mw->ipz_mw_handle.handle); |
@@ -846,10 +850,6 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd, | |||
846 | alloc_fmr_exit1: | 850 | alloc_fmr_exit1: |
847 | ehca_mr_delete(e_fmr); | 851 | ehca_mr_delete(e_fmr); |
848 | alloc_fmr_exit0: | 852 | alloc_fmr_exit0: |
849 | if (IS_ERR(ib_fmr)) | ||
850 | ehca_err(pd->device, "rc=%lx pd=%p mr_access_flags=%x " | ||
851 | "fmr_attr=%p", PTR_ERR(ib_fmr), pd, | ||
852 | mr_access_flags, fmr_attr); | ||
853 | return ib_fmr; | 853 | return ib_fmr; |
854 | } /* end ehca_alloc_fmr() */ | 854 | } /* end ehca_alloc_fmr() */ |
855 | 855 | ||
@@ -916,7 +916,7 @@ int ehca_map_phys_fmr(struct ib_fmr *fmr, | |||
916 | 916 | ||
917 | map_phys_fmr_exit0: | 917 | map_phys_fmr_exit0: |
918 | if (ret) | 918 | if (ret) |
919 | ehca_err(fmr->device, "ret=%x fmr=%p page_list=%p list_len=%x " | 919 | ehca_err(fmr->device, "ret=%i fmr=%p page_list=%p list_len=%x " |
920 | "iova=%lx", ret, fmr, page_list, list_len, iova); | 920 | "iova=%lx", ret, fmr, page_list, list_len, iova); |
921 | return ret; | 921 | return ret; |
922 | } /* end ehca_map_phys_fmr() */ | 922 | } /* end ehca_map_phys_fmr() */ |
@@ -979,7 +979,7 @@ int ehca_unmap_fmr(struct list_head *fmr_list) | |||
979 | 979 | ||
980 | unmap_fmr_exit0: | 980 | unmap_fmr_exit0: |
981 | if (ret) | 981 | if (ret) |
982 | ehca_gen_err("ret=%x fmr_list=%p num_fmr=%x unmap_fmr_cnt=%x", | 982 | ehca_gen_err("ret=%i fmr_list=%p num_fmr=%x unmap_fmr_cnt=%x", |
983 | ret, fmr_list, num_fmr, unmap_fmr_cnt); | 983 | ret, fmr_list, num_fmr, unmap_fmr_cnt); |
984 | return ret; | 984 | return ret; |
985 | } /* end ehca_unmap_fmr() */ | 985 | } /* end ehca_unmap_fmr() */ |
@@ -1003,7 +1003,7 @@ int ehca_dealloc_fmr(struct ib_fmr *fmr) | |||
1003 | 1003 | ||
1004 | h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_fmr); | 1004 | h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_fmr); |
1005 | if (h_ret != H_SUCCESS) { | 1005 | if (h_ret != H_SUCCESS) { |
1006 | ehca_err(fmr->device, "hipz_free_mr failed, h_ret=%lx e_fmr=%p " | 1006 | ehca_err(fmr->device, "hipz_free_mr failed, h_ret=%li e_fmr=%p " |
1007 | "hca_hndl=%lx fmr_hndl=%lx fmr->lkey=%x", | 1007 | "hca_hndl=%lx fmr_hndl=%lx fmr->lkey=%x", |
1008 | h_ret, e_fmr, shca->ipz_hca_handle.handle, | 1008 | h_ret, e_fmr, shca->ipz_hca_handle.handle, |
1009 | e_fmr->ipz_mr_handle.handle, fmr->lkey); | 1009 | e_fmr->ipz_mr_handle.handle, fmr->lkey); |
@@ -1016,7 +1016,7 @@ int ehca_dealloc_fmr(struct ib_fmr *fmr) | |||
1016 | 1016 | ||
1017 | free_fmr_exit0: | 1017 | free_fmr_exit0: |
1018 | if (ret) | 1018 | if (ret) |
1019 | ehca_err(&shca->ib_device, "ret=%x fmr=%p", ret, fmr); | 1019 | ehca_err(&shca->ib_device, "ret=%i fmr=%p", ret, fmr); |
1020 | return ret; | 1020 | return ret; |
1021 | } /* end ehca_dealloc_fmr() */ | 1021 | } /* end ehca_dealloc_fmr() */ |
1022 | 1022 | ||
@@ -1046,7 +1046,7 @@ int ehca_reg_mr(struct ehca_shca *shca, | |||
1046 | (u64)iova_start, size, hipz_acl, | 1046 | (u64)iova_start, size, hipz_acl, |
1047 | e_pd->fw_pd, &hipzout); | 1047 | e_pd->fw_pd, &hipzout); |
1048 | if (h_ret != H_SUCCESS) { | 1048 | if (h_ret != H_SUCCESS) { |
1049 | ehca_err(&shca->ib_device, "hipz_alloc_mr failed, h_ret=%lx " | 1049 | ehca_err(&shca->ib_device, "hipz_alloc_mr failed, h_ret=%li " |
1050 | "hca_hndl=%lx", h_ret, shca->ipz_hca_handle.handle); | 1050 | "hca_hndl=%lx", h_ret, shca->ipz_hca_handle.handle); |
1051 | ret = ehca2ib_return_code(h_ret); | 1051 | ret = ehca2ib_return_code(h_ret); |
1052 | goto ehca_reg_mr_exit0; | 1052 | goto ehca_reg_mr_exit0; |
@@ -1072,9 +1072,9 @@ int ehca_reg_mr(struct ehca_shca *shca, | |||
1072 | ehca_reg_mr_exit1: | 1072 | ehca_reg_mr_exit1: |
1073 | h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_mr); | 1073 | h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_mr); |
1074 | if (h_ret != H_SUCCESS) { | 1074 | if (h_ret != H_SUCCESS) { |
1075 | ehca_err(&shca->ib_device, "h_ret=%lx shca=%p e_mr=%p " | 1075 | ehca_err(&shca->ib_device, "h_ret=%li shca=%p e_mr=%p " |
1076 | "iova_start=%p size=%lx acl=%x e_pd=%p lkey=%x " | 1076 | "iova_start=%p size=%lx acl=%x e_pd=%p lkey=%x " |
1077 | "pginfo=%p num_kpages=%lx num_hwpages=%lx ret=%x", | 1077 | "pginfo=%p num_kpages=%lx num_hwpages=%lx ret=%i", |
1078 | h_ret, shca, e_mr, iova_start, size, acl, e_pd, | 1078 | h_ret, shca, e_mr, iova_start, size, acl, e_pd, |
1079 | hipzout.lkey, pginfo, pginfo->num_kpages, | 1079 | hipzout.lkey, pginfo, pginfo->num_kpages, |
1080 | pginfo->num_hwpages, ret); | 1080 | pginfo->num_hwpages, ret); |
@@ -1083,7 +1083,7 @@ ehca_reg_mr_exit1: | |||
1083 | } | 1083 | } |
1084 | ehca_reg_mr_exit0: | 1084 | ehca_reg_mr_exit0: |
1085 | if (ret) | 1085 | if (ret) |
1086 | ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p " | 1086 | ehca_err(&shca->ib_device, "ret=%i shca=%p e_mr=%p " |
1087 | "iova_start=%p size=%lx acl=%x e_pd=%p pginfo=%p " | 1087 | "iova_start=%p size=%lx acl=%x e_pd=%p pginfo=%p " |
1088 | "num_kpages=%lx num_hwpages=%lx", | 1088 | "num_kpages=%lx num_hwpages=%lx", |
1089 | ret, shca, e_mr, iova_start, size, acl, e_pd, pginfo, | 1089 | ret, shca, e_mr, iova_start, size, acl, e_pd, pginfo, |
@@ -1127,7 +1127,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca, | |||
1127 | ret = ehca_set_pagebuf(pginfo, rnum, kpage); | 1127 | ret = ehca_set_pagebuf(pginfo, rnum, kpage); |
1128 | if (ret) { | 1128 | if (ret) { |
1129 | ehca_err(&shca->ib_device, "ehca_set_pagebuf " | 1129 | ehca_err(&shca->ib_device, "ehca_set_pagebuf " |
1130 | "bad rc, ret=%x rnum=%x kpage=%p", | 1130 | "bad rc, ret=%i rnum=%x kpage=%p", |
1131 | ret, rnum, kpage); | 1131 | ret, rnum, kpage); |
1132 | goto ehca_reg_mr_rpages_exit1; | 1132 | goto ehca_reg_mr_rpages_exit1; |
1133 | } | 1133 | } |
@@ -1155,7 +1155,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca, | |||
1155 | */ | 1155 | */ |
1156 | if (h_ret != H_SUCCESS) { | 1156 | if (h_ret != H_SUCCESS) { |
1157 | ehca_err(&shca->ib_device, "last " | 1157 | ehca_err(&shca->ib_device, "last " |
1158 | "hipz_reg_rpage_mr failed, h_ret=%lx " | 1158 | "hipz_reg_rpage_mr failed, h_ret=%li " |
1159 | "e_mr=%p i=%x hca_hndl=%lx mr_hndl=%lx" | 1159 | "e_mr=%p i=%x hca_hndl=%lx mr_hndl=%lx" |
1160 | " lkey=%x", h_ret, e_mr, i, | 1160 | " lkey=%x", h_ret, e_mr, i, |
1161 | shca->ipz_hca_handle.handle, | 1161 | shca->ipz_hca_handle.handle, |
@@ -1167,7 +1167,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca, | |||
1167 | ret = 0; | 1167 | ret = 0; |
1168 | } else if (h_ret != H_PAGE_REGISTERED) { | 1168 | } else if (h_ret != H_PAGE_REGISTERED) { |
1169 | ehca_err(&shca->ib_device, "hipz_reg_rpage_mr failed, " | 1169 | ehca_err(&shca->ib_device, "hipz_reg_rpage_mr failed, " |
1170 | "h_ret=%lx e_mr=%p i=%x lkey=%x hca_hndl=%lx " | 1170 | "h_ret=%li e_mr=%p i=%x lkey=%x hca_hndl=%lx " |
1171 | "mr_hndl=%lx", h_ret, e_mr, i, | 1171 | "mr_hndl=%lx", h_ret, e_mr, i, |
1172 | e_mr->ib.ib_mr.lkey, | 1172 | e_mr->ib.ib_mr.lkey, |
1173 | shca->ipz_hca_handle.handle, | 1173 | shca->ipz_hca_handle.handle, |
@@ -1183,7 +1183,7 @@ ehca_reg_mr_rpages_exit1: | |||
1183 | ehca_free_fw_ctrlblock(kpage); | 1183 | ehca_free_fw_ctrlblock(kpage); |
1184 | ehca_reg_mr_rpages_exit0: | 1184 | ehca_reg_mr_rpages_exit0: |
1185 | if (ret) | 1185 | if (ret) |
1186 | ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p pginfo=%p " | 1186 | ehca_err(&shca->ib_device, "ret=%i shca=%p e_mr=%p pginfo=%p " |
1187 | "num_kpages=%lx num_hwpages=%lx", ret, shca, e_mr, | 1187 | "num_kpages=%lx num_hwpages=%lx", ret, shca, e_mr, |
1188 | pginfo, pginfo->num_kpages, pginfo->num_hwpages); | 1188 | pginfo, pginfo->num_kpages, pginfo->num_hwpages); |
1189 | return ret; | 1189 | return ret; |
@@ -1244,7 +1244,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca, | |||
1244 | * (MW bound or MR is shared) | 1244 | * (MW bound or MR is shared) |
1245 | */ | 1245 | */ |
1246 | ehca_warn(&shca->ib_device, "hipz_h_reregister_pmr failed " | 1246 | ehca_warn(&shca->ib_device, "hipz_h_reregister_pmr failed " |
1247 | "(Rereg1), h_ret=%lx e_mr=%p", h_ret, e_mr); | 1247 | "(Rereg1), h_ret=%li e_mr=%p", h_ret, e_mr); |
1248 | *pginfo = pginfo_save; | 1248 | *pginfo = pginfo_save; |
1249 | ret = -EAGAIN; | 1249 | ret = -EAGAIN; |
1250 | } else if ((u64 *)hipzout.vaddr != iova_start) { | 1250 | } else if ((u64 *)hipzout.vaddr != iova_start) { |
@@ -1273,7 +1273,7 @@ ehca_rereg_mr_rereg1_exit1: | |||
1273 | ehca_free_fw_ctrlblock(kpage); | 1273 | ehca_free_fw_ctrlblock(kpage); |
1274 | ehca_rereg_mr_rereg1_exit0: | 1274 | ehca_rereg_mr_rereg1_exit0: |
1275 | if ( ret && (ret != -EAGAIN) ) | 1275 | if ( ret && (ret != -EAGAIN) ) |
1276 | ehca_err(&shca->ib_device, "ret=%x lkey=%x rkey=%x " | 1276 | ehca_err(&shca->ib_device, "ret=%i lkey=%x rkey=%x " |
1277 | "pginfo=%p num_kpages=%lx num_hwpages=%lx", | 1277 | "pginfo=%p num_kpages=%lx num_hwpages=%lx", |
1278 | ret, *lkey, *rkey, pginfo, pginfo->num_kpages, | 1278 | ret, *lkey, *rkey, pginfo, pginfo->num_kpages, |
1279 | pginfo->num_hwpages); | 1279 | pginfo->num_hwpages); |
@@ -1334,7 +1334,7 @@ int ehca_rereg_mr(struct ehca_shca *shca, | |||
1334 | h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_mr); | 1334 | h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_mr); |
1335 | if (h_ret != H_SUCCESS) { | 1335 | if (h_ret != H_SUCCESS) { |
1336 | ehca_err(&shca->ib_device, "hipz_free_mr failed, " | 1336 | ehca_err(&shca->ib_device, "hipz_free_mr failed, " |
1337 | "h_ret=%lx e_mr=%p hca_hndl=%lx mr_hndl=%lx " | 1337 | "h_ret=%li e_mr=%p hca_hndl=%lx mr_hndl=%lx " |
1338 | "mr->lkey=%x", | 1338 | "mr->lkey=%x", |
1339 | h_ret, e_mr, shca->ipz_hca_handle.handle, | 1339 | h_ret, e_mr, shca->ipz_hca_handle.handle, |
1340 | e_mr->ipz_mr_handle.handle, | 1340 | e_mr->ipz_mr_handle.handle, |
@@ -1366,7 +1366,7 @@ int ehca_rereg_mr(struct ehca_shca *shca, | |||
1366 | 1366 | ||
1367 | ehca_rereg_mr_exit0: | 1367 | ehca_rereg_mr_exit0: |
1368 | if (ret) | 1368 | if (ret) |
1369 | ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p " | 1369 | ehca_err(&shca->ib_device, "ret=%i shca=%p e_mr=%p " |
1370 | "iova_start=%p size=%lx acl=%x e_pd=%p pginfo=%p " | 1370 | "iova_start=%p size=%lx acl=%x e_pd=%p pginfo=%p " |
1371 | "num_kpages=%lx lkey=%x rkey=%x rereg_1_hcall=%x " | 1371 | "num_kpages=%lx lkey=%x rkey=%x rereg_1_hcall=%x " |
1372 | "rereg_3_hcall=%x", ret, shca, e_mr, iova_start, size, | 1372 | "rereg_3_hcall=%x", ret, shca, e_mr, iova_start, size, |
@@ -1410,7 +1410,7 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca, | |||
1410 | * FMRs are not shared and no MW bound to FMRs | 1410 | * FMRs are not shared and no MW bound to FMRs |
1411 | */ | 1411 | */ |
1412 | ehca_err(&shca->ib_device, "hipz_reregister_pmr failed " | 1412 | ehca_err(&shca->ib_device, "hipz_reregister_pmr failed " |
1413 | "(Rereg1), h_ret=%lx e_fmr=%p hca_hndl=%lx " | 1413 | "(Rereg1), h_ret=%li e_fmr=%p hca_hndl=%lx " |
1414 | "mr_hndl=%lx lkey=%x lkey_out=%x", | 1414 | "mr_hndl=%lx lkey=%x lkey_out=%x", |
1415 | h_ret, e_fmr, shca->ipz_hca_handle.handle, | 1415 | h_ret, e_fmr, shca->ipz_hca_handle.handle, |
1416 | e_fmr->ipz_mr_handle.handle, | 1416 | e_fmr->ipz_mr_handle.handle, |
@@ -1422,7 +1422,7 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca, | |||
1422 | h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_fmr); | 1422 | h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_fmr); |
1423 | if (h_ret != H_SUCCESS) { | 1423 | if (h_ret != H_SUCCESS) { |
1424 | ehca_err(&shca->ib_device, "hipz_free_mr failed, " | 1424 | ehca_err(&shca->ib_device, "hipz_free_mr failed, " |
1425 | "h_ret=%lx e_fmr=%p hca_hndl=%lx mr_hndl=%lx " | 1425 | "h_ret=%li e_fmr=%p hca_hndl=%lx mr_hndl=%lx " |
1426 | "lkey=%x", | 1426 | "lkey=%x", |
1427 | h_ret, e_fmr, shca->ipz_hca_handle.handle, | 1427 | h_ret, e_fmr, shca->ipz_hca_handle.handle, |
1428 | e_fmr->ipz_mr_handle.handle, | 1428 | e_fmr->ipz_mr_handle.handle, |
@@ -1457,7 +1457,7 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca, | |||
1457 | 1457 | ||
1458 | ehca_unmap_one_fmr_exit0: | 1458 | ehca_unmap_one_fmr_exit0: |
1459 | if (ret) | 1459 | if (ret) |
1460 | ehca_err(&shca->ib_device, "ret=%x tmp_lkey=%x tmp_rkey=%x " | 1460 | ehca_err(&shca->ib_device, "ret=%i tmp_lkey=%x tmp_rkey=%x " |
1461 | "fmr_max_pages=%x", | 1461 | "fmr_max_pages=%x", |
1462 | ret, tmp_lkey, tmp_rkey, e_fmr->fmr_max_pages); | 1462 | ret, tmp_lkey, tmp_rkey, e_fmr->fmr_max_pages); |
1463 | return ret; | 1463 | return ret; |
@@ -1486,7 +1486,7 @@ int ehca_reg_smr(struct ehca_shca *shca, | |||
1486 | (u64)iova_start, hipz_acl, e_pd->fw_pd, | 1486 | (u64)iova_start, hipz_acl, e_pd->fw_pd, |
1487 | &hipzout); | 1487 | &hipzout); |
1488 | if (h_ret != H_SUCCESS) { | 1488 | if (h_ret != H_SUCCESS) { |
1489 | ehca_err(&shca->ib_device, "hipz_reg_smr failed, h_ret=%lx " | 1489 | ehca_err(&shca->ib_device, "hipz_reg_smr failed, h_ret=%li " |
1490 | "shca=%p e_origmr=%p e_newmr=%p iova_start=%p acl=%x " | 1490 | "shca=%p e_origmr=%p e_newmr=%p iova_start=%p acl=%x " |
1491 | "e_pd=%p hca_hndl=%lx mr_hndl=%lx lkey=%x", | 1491 | "e_pd=%p hca_hndl=%lx mr_hndl=%lx lkey=%x", |
1492 | h_ret, shca, e_origmr, e_newmr, iova_start, acl, e_pd, | 1492 | h_ret, shca, e_origmr, e_newmr, iova_start, acl, e_pd, |
@@ -1510,7 +1510,7 @@ int ehca_reg_smr(struct ehca_shca *shca, | |||
1510 | 1510 | ||
1511 | ehca_reg_smr_exit0: | 1511 | ehca_reg_smr_exit0: |
1512 | if (ret) | 1512 | if (ret) |
1513 | ehca_err(&shca->ib_device, "ret=%x shca=%p e_origmr=%p " | 1513 | ehca_err(&shca->ib_device, "ret=%i shca=%p e_origmr=%p " |
1514 | "e_newmr=%p iova_start=%p acl=%x e_pd=%p", | 1514 | "e_newmr=%p iova_start=%p acl=%x e_pd=%p", |
1515 | ret, shca, e_origmr, e_newmr, iova_start, acl, e_pd); | 1515 | ret, shca, e_origmr, e_newmr, iova_start, acl, e_pd); |
1516 | return ret; | 1516 | return ret; |
@@ -1585,7 +1585,7 @@ ehca_reg_internal_maxmr_exit1: | |||
1585 | ehca_mr_delete(e_mr); | 1585 | ehca_mr_delete(e_mr); |
1586 | ehca_reg_internal_maxmr_exit0: | 1586 | ehca_reg_internal_maxmr_exit0: |
1587 | if (ret) | 1587 | if (ret) |
1588 | ehca_err(&shca->ib_device, "ret=%x shca=%p e_pd=%p e_maxmr=%p", | 1588 | ehca_err(&shca->ib_device, "ret=%i shca=%p e_pd=%p e_maxmr=%p", |
1589 | ret, shca, e_pd, e_maxmr); | 1589 | ret, shca, e_pd, e_maxmr); |
1590 | return ret; | 1590 | return ret; |
1591 | } /* end ehca_reg_internal_maxmr() */ | 1591 | } /* end ehca_reg_internal_maxmr() */ |
@@ -1612,7 +1612,7 @@ int ehca_reg_maxmr(struct ehca_shca *shca, | |||
1612 | (u64)iova_start, hipz_acl, e_pd->fw_pd, | 1612 | (u64)iova_start, hipz_acl, e_pd->fw_pd, |
1613 | &hipzout); | 1613 | &hipzout); |
1614 | if (h_ret != H_SUCCESS) { | 1614 | if (h_ret != H_SUCCESS) { |
1615 | ehca_err(&shca->ib_device, "hipz_reg_smr failed, h_ret=%lx " | 1615 | ehca_err(&shca->ib_device, "hipz_reg_smr failed, h_ret=%li " |
1616 | "e_origmr=%p hca_hndl=%lx mr_hndl=%lx lkey=%x", | 1616 | "e_origmr=%p hca_hndl=%lx mr_hndl=%lx lkey=%x", |
1617 | h_ret, e_origmr, shca->ipz_hca_handle.handle, | 1617 | h_ret, e_origmr, shca->ipz_hca_handle.handle, |
1618 | e_origmr->ipz_mr_handle.handle, | 1618 | e_origmr->ipz_mr_handle.handle, |
@@ -1653,7 +1653,7 @@ int ehca_dereg_internal_maxmr(struct ehca_shca *shca) | |||
1653 | ret = ehca_dereg_mr(&e_maxmr->ib.ib_mr); | 1653 | ret = ehca_dereg_mr(&e_maxmr->ib.ib_mr); |
1654 | if (ret) { | 1654 | if (ret) { |
1655 | ehca_err(&shca->ib_device, "dereg internal max-MR failed, " | 1655 | ehca_err(&shca->ib_device, "dereg internal max-MR failed, " |
1656 | "ret=%x e_maxmr=%p shca=%p lkey=%x", | 1656 | "ret=%i e_maxmr=%p shca=%p lkey=%x", |
1657 | ret, e_maxmr, shca, e_maxmr->ib.ib_mr.lkey); | 1657 | ret, e_maxmr, shca, e_maxmr->ib.ib_mr.lkey); |
1658 | shca->maxmr = e_maxmr; | 1658 | shca->maxmr = e_maxmr; |
1659 | goto ehca_dereg_internal_maxmr_exit0; | 1659 | goto ehca_dereg_internal_maxmr_exit0; |
@@ -1663,7 +1663,7 @@ int ehca_dereg_internal_maxmr(struct ehca_shca *shca) | |||
1663 | 1663 | ||
1664 | ehca_dereg_internal_maxmr_exit0: | 1664 | ehca_dereg_internal_maxmr_exit0: |
1665 | if (ret) | 1665 | if (ret) |
1666 | ehca_err(&shca->ib_device, "ret=%x shca=%p shca->maxmr=%p", | 1666 | ehca_err(&shca->ib_device, "ret=%i shca=%p shca->maxmr=%p", |
1667 | ret, shca, shca->maxmr); | 1667 | ret, shca, shca->maxmr); |
1668 | return ret; | 1668 | return ret; |
1669 | } /* end ehca_dereg_internal_maxmr() */ | 1669 | } /* end ehca_dereg_internal_maxmr() */ |
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index b178cba96345..e2bd62be11e7 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c | |||
@@ -273,6 +273,7 @@ static inline void queue2resp(struct ipzu_queue_resp *resp, | |||
273 | resp->queue_length = queue->queue_length; | 273 | resp->queue_length = queue->queue_length; |
274 | resp->pagesize = queue->pagesize; | 274 | resp->pagesize = queue->pagesize; |
275 | resp->toggle_state = queue->toggle_state; | 275 | resp->toggle_state = queue->toggle_state; |
276 | resp->offset = queue->offset; | ||
276 | } | 277 | } |
277 | 278 | ||
278 | /* | 279 | /* |
@@ -309,7 +310,7 @@ static inline int init_qp_queue(struct ehca_shca *shca, | |||
309 | } | 310 | } |
310 | 311 | ||
311 | if (!ipz_rc) { | 312 | if (!ipz_rc) { |
312 | ehca_err(ib_dev, "Cannot allocate page for queue. ipz_rc=%x", | 313 | ehca_err(ib_dev, "Cannot allocate page for queue. ipz_rc=%i", |
313 | ipz_rc); | 314 | ipz_rc); |
314 | return -EBUSY; | 315 | return -EBUSY; |
315 | } | 316 | } |
@@ -333,7 +334,7 @@ static inline int init_qp_queue(struct ehca_shca *shca, | |||
333 | if (cnt == (nr_q_pages - 1)) { /* last page! */ | 334 | if (cnt == (nr_q_pages - 1)) { /* last page! */ |
334 | if (h_ret != expected_hret) { | 335 | if (h_ret != expected_hret) { |
335 | ehca_err(ib_dev, "hipz_qp_register_rpage() " | 336 | ehca_err(ib_dev, "hipz_qp_register_rpage() " |
336 | "h_ret= %lx ", h_ret); | 337 | "h_ret=%li", h_ret); |
337 | ret = ehca2ib_return_code(h_ret); | 338 | ret = ehca2ib_return_code(h_ret); |
338 | goto init_qp_queue1; | 339 | goto init_qp_queue1; |
339 | } | 340 | } |
@@ -347,7 +348,7 @@ static inline int init_qp_queue(struct ehca_shca *shca, | |||
347 | } else { | 348 | } else { |
348 | if (h_ret != H_PAGE_REGISTERED) { | 349 | if (h_ret != H_PAGE_REGISTERED) { |
349 | ehca_err(ib_dev, "hipz_qp_register_rpage() " | 350 | ehca_err(ib_dev, "hipz_qp_register_rpage() " |
350 | "h_ret= %lx ", h_ret); | 351 | "h_ret=%li", h_ret); |
351 | ret = ehca2ib_return_code(h_ret); | 352 | ret = ehca2ib_return_code(h_ret); |
352 | goto init_qp_queue1; | 353 | goto init_qp_queue1; |
353 | } | 354 | } |
@@ -512,7 +513,7 @@ static struct ehca_qp *internal_create_qp( | |||
512 | } else if (init_attr->cap.max_send_wr > 255) { | 513 | } else if (init_attr->cap.max_send_wr > 255) { |
513 | ehca_err(pd->device, | 514 | ehca_err(pd->device, |
514 | "Invalid Number of " | 515 | "Invalid Number of " |
515 | "ax_send_wr=%x for UD QP_TYPE=%x", | 516 | "max_send_wr=%x for UD QP_TYPE=%x", |
516 | init_attr->cap.max_send_wr, qp_type); | 517 | init_attr->cap.max_send_wr, qp_type); |
517 | return ERR_PTR(-EINVAL); | 518 | return ERR_PTR(-EINVAL); |
518 | } | 519 | } |
@@ -523,6 +524,18 @@ static struct ehca_qp *internal_create_qp( | |||
523 | return ERR_PTR(-EINVAL); | 524 | return ERR_PTR(-EINVAL); |
524 | break; | 525 | break; |
525 | } | 526 | } |
527 | } else { | ||
528 | int max_sge = (qp_type == IB_QPT_UD || qp_type == IB_QPT_SMI | ||
529 | || qp_type == IB_QPT_GSI) ? 250 : 252; | ||
530 | |||
531 | if (init_attr->cap.max_send_sge > max_sge | ||
532 | || init_attr->cap.max_recv_sge > max_sge) { | ||
533 | ehca_err(pd->device, "Invalid number of SGEs requested " | ||
534 | "send_sge=%x recv_sge=%x max_sge=%x", | ||
535 | init_attr->cap.max_send_sge, | ||
536 | init_attr->cap.max_recv_sge, max_sge); | ||
537 | return ERR_PTR(-EINVAL); | ||
538 | } | ||
526 | } | 539 | } |
527 | 540 | ||
528 | if (pd->uobject && udata) | 541 | if (pd->uobject && udata) |
@@ -556,7 +569,6 @@ static struct ehca_qp *internal_create_qp( | |||
556 | write_lock_irqsave(&ehca_qp_idr_lock, flags); | 569 | write_lock_irqsave(&ehca_qp_idr_lock, flags); |
557 | ret = idr_get_new(&ehca_qp_idr, my_qp, &my_qp->token); | 570 | ret = idr_get_new(&ehca_qp_idr, my_qp, &my_qp->token); |
558 | write_unlock_irqrestore(&ehca_qp_idr_lock, flags); | 571 | write_unlock_irqrestore(&ehca_qp_idr_lock, flags); |
559 | |||
560 | } while (ret == -EAGAIN); | 572 | } while (ret == -EAGAIN); |
561 | 573 | ||
562 | if (ret) { | 574 | if (ret) { |
@@ -565,11 +577,17 @@ static struct ehca_qp *internal_create_qp( | |||
565 | goto create_qp_exit0; | 577 | goto create_qp_exit0; |
566 | } | 578 | } |
567 | 579 | ||
580 | if (my_qp->token > 0x1FFFFFF) { | ||
581 | ret = -EINVAL; | ||
582 | ehca_err(pd->device, "Invalid number of qp"); | ||
583 | goto create_qp_exit1; | ||
584 | } | ||
585 | |||
568 | parms.servicetype = ibqptype2servicetype(qp_type); | 586 | parms.servicetype = ibqptype2servicetype(qp_type); |
569 | if (parms.servicetype < 0) { | 587 | if (parms.servicetype < 0) { |
570 | ret = -EINVAL; | 588 | ret = -EINVAL; |
571 | ehca_err(pd->device, "Invalid qp_type=%x", qp_type); | 589 | ehca_err(pd->device, "Invalid qp_type=%x", qp_type); |
572 | goto create_qp_exit0; | 590 | goto create_qp_exit1; |
573 | } | 591 | } |
574 | 592 | ||
575 | if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) | 593 | if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) |
@@ -598,19 +616,20 @@ static struct ehca_qp *internal_create_qp( | |||
598 | parms.squeue.max_sge = max_send_sge; | 616 | parms.squeue.max_sge = max_send_sge; |
599 | parms.rqueue.max_sge = max_recv_sge; | 617 | parms.rqueue.max_sge = max_recv_sge; |
600 | 618 | ||
601 | if (EHCA_BMASK_GET(HCA_CAP_MINI_QP, shca->hca_cap) | 619 | if (EHCA_BMASK_GET(HCA_CAP_MINI_QP, shca->hca_cap)) { |
602 | && !(context && udata)) { /* no small QP support in userspace ATM */ | 620 | if (HAS_SQ(my_qp)) |
603 | ehca_determine_small_queue( | 621 | ehca_determine_small_queue( |
604 | &parms.squeue, max_send_sge, is_llqp); | 622 | &parms.squeue, max_send_sge, is_llqp); |
605 | ehca_determine_small_queue( | 623 | if (HAS_RQ(my_qp)) |
606 | &parms.rqueue, max_recv_sge, is_llqp); | 624 | ehca_determine_small_queue( |
625 | &parms.rqueue, max_recv_sge, is_llqp); | ||
607 | parms.qp_storage = | 626 | parms.qp_storage = |
608 | (parms.squeue.is_small || parms.rqueue.is_small); | 627 | (parms.squeue.is_small || parms.rqueue.is_small); |
609 | } | 628 | } |
610 | 629 | ||
611 | h_ret = hipz_h_alloc_resource_qp(shca->ipz_hca_handle, &parms); | 630 | h_ret = hipz_h_alloc_resource_qp(shca->ipz_hca_handle, &parms); |
612 | if (h_ret != H_SUCCESS) { | 631 | if (h_ret != H_SUCCESS) { |
613 | ehca_err(pd->device, "h_alloc_resource_qp() failed h_ret=%lx", | 632 | ehca_err(pd->device, "h_alloc_resource_qp() failed h_ret=%li", |
614 | h_ret); | 633 | h_ret); |
615 | ret = ehca2ib_return_code(h_ret); | 634 | ret = ehca2ib_return_code(h_ret); |
616 | goto create_qp_exit1; | 635 | goto create_qp_exit1; |
@@ -664,7 +683,7 @@ static struct ehca_qp *internal_create_qp( | |||
664 | &parms.squeue, swqe_size); | 683 | &parms.squeue, swqe_size); |
665 | if (ret) { | 684 | if (ret) { |
666 | ehca_err(pd->device, "Couldn't initialize squeue " | 685 | ehca_err(pd->device, "Couldn't initialize squeue " |
667 | "and pages ret=%x", ret); | 686 | "and pages ret=%i", ret); |
668 | goto create_qp_exit2; | 687 | goto create_qp_exit2; |
669 | } | 688 | } |
670 | } | 689 | } |
@@ -675,7 +694,7 @@ static struct ehca_qp *internal_create_qp( | |||
675 | H_SUCCESS, &parms.rqueue, rwqe_size); | 694 | H_SUCCESS, &parms.rqueue, rwqe_size); |
676 | if (ret) { | 695 | if (ret) { |
677 | ehca_err(pd->device, "Couldn't initialize rqueue " | 696 | ehca_err(pd->device, "Couldn't initialize rqueue " |
678 | "and pages ret=%x", ret); | 697 | "and pages ret=%i", ret); |
679 | goto create_qp_exit3; | 698 | goto create_qp_exit3; |
680 | } | 699 | } |
681 | } | 700 | } |
@@ -712,8 +731,6 @@ static struct ehca_qp *internal_create_qp( | |||
712 | if (qp_type == IB_QPT_GSI) { | 731 | if (qp_type == IB_QPT_GSI) { |
713 | h_ret = ehca_define_sqp(shca, my_qp, init_attr); | 732 | h_ret = ehca_define_sqp(shca, my_qp, init_attr); |
714 | if (h_ret != H_SUCCESS) { | 733 | if (h_ret != H_SUCCESS) { |
715 | ehca_err(pd->device, "ehca_define_sqp() failed rc=%lx", | ||
716 | h_ret); | ||
717 | ret = ehca2ib_return_code(h_ret); | 734 | ret = ehca2ib_return_code(h_ret); |
718 | goto create_qp_exit4; | 735 | goto create_qp_exit4; |
719 | } | 736 | } |
@@ -723,7 +740,7 @@ static struct ehca_qp *internal_create_qp( | |||
723 | ret = ehca_cq_assign_qp(my_qp->send_cq, my_qp); | 740 | ret = ehca_cq_assign_qp(my_qp->send_cq, my_qp); |
724 | if (ret) { | 741 | if (ret) { |
725 | ehca_err(pd->device, | 742 | ehca_err(pd->device, |
726 | "Couldn't assign qp to send_cq ret=%x", ret); | 743 | "Couldn't assign qp to send_cq ret=%i", ret); |
727 | goto create_qp_exit4; | 744 | goto create_qp_exit4; |
728 | } | 745 | } |
729 | } | 746 | } |
@@ -739,12 +756,13 @@ static struct ehca_qp *internal_create_qp( | |||
739 | resp.ext_type = my_qp->ext_type; | 756 | resp.ext_type = my_qp->ext_type; |
740 | resp.qkey = my_qp->qkey; | 757 | resp.qkey = my_qp->qkey; |
741 | resp.real_qp_num = my_qp->real_qp_num; | 758 | resp.real_qp_num = my_qp->real_qp_num; |
742 | resp.ipz_rqueue.offset = my_qp->ipz_rqueue.offset; | 759 | |
743 | resp.ipz_squeue.offset = my_qp->ipz_squeue.offset; | ||
744 | if (HAS_SQ(my_qp)) | 760 | if (HAS_SQ(my_qp)) |
745 | queue2resp(&resp.ipz_squeue, &my_qp->ipz_squeue); | 761 | queue2resp(&resp.ipz_squeue, &my_qp->ipz_squeue); |
746 | if (HAS_RQ(my_qp)) | 762 | if (HAS_RQ(my_qp)) |
747 | queue2resp(&resp.ipz_rqueue, &my_qp->ipz_rqueue); | 763 | queue2resp(&resp.ipz_rqueue, &my_qp->ipz_rqueue); |
764 | resp.fw_handle_ofs = (u32) | ||
765 | (my_qp->galpas.user.fw_handle & (PAGE_SIZE - 1)); | ||
748 | 766 | ||
749 | if (ib_copy_to_udata(udata, &resp, sizeof resp)) { | 767 | if (ib_copy_to_udata(udata, &resp, sizeof resp)) { |
750 | ehca_err(pd->device, "Copy to udata failed"); | 768 | ehca_err(pd->device, "Copy to udata failed"); |
@@ -839,7 +857,7 @@ struct ib_srq *ehca_create_srq(struct ib_pd *pd, | |||
839 | mqpcb, my_qp->galpas.kernel); | 857 | mqpcb, my_qp->galpas.kernel); |
840 | if (hret != H_SUCCESS) { | 858 | if (hret != H_SUCCESS) { |
841 | ehca_err(pd->device, "Could not modify SRQ to INIT" | 859 | ehca_err(pd->device, "Could not modify SRQ to INIT" |
842 | "ehca_qp=%p qp_num=%x hret=%lx", | 860 | "ehca_qp=%p qp_num=%x h_ret=%li", |
843 | my_qp, my_qp->real_qp_num, hret); | 861 | my_qp, my_qp->real_qp_num, hret); |
844 | goto create_srq2; | 862 | goto create_srq2; |
845 | } | 863 | } |
@@ -853,7 +871,7 @@ struct ib_srq *ehca_create_srq(struct ib_pd *pd, | |||
853 | mqpcb, my_qp->galpas.kernel); | 871 | mqpcb, my_qp->galpas.kernel); |
854 | if (hret != H_SUCCESS) { | 872 | if (hret != H_SUCCESS) { |
855 | ehca_err(pd->device, "Could not enable SRQ" | 873 | ehca_err(pd->device, "Could not enable SRQ" |
856 | "ehca_qp=%p qp_num=%x hret=%lx", | 874 | "ehca_qp=%p qp_num=%x h_ret=%li", |
857 | my_qp, my_qp->real_qp_num, hret); | 875 | my_qp, my_qp->real_qp_num, hret); |
858 | goto create_srq2; | 876 | goto create_srq2; |
859 | } | 877 | } |
@@ -867,11 +885,13 @@ struct ib_srq *ehca_create_srq(struct ib_pd *pd, | |||
867 | mqpcb, my_qp->galpas.kernel); | 885 | mqpcb, my_qp->galpas.kernel); |
868 | if (hret != H_SUCCESS) { | 886 | if (hret != H_SUCCESS) { |
869 | ehca_err(pd->device, "Could not modify SRQ to RTR" | 887 | ehca_err(pd->device, "Could not modify SRQ to RTR" |
870 | "ehca_qp=%p qp_num=%x hret=%lx", | 888 | "ehca_qp=%p qp_num=%x h_ret=%li", |
871 | my_qp, my_qp->real_qp_num, hret); | 889 | my_qp, my_qp->real_qp_num, hret); |
872 | goto create_srq2; | 890 | goto create_srq2; |
873 | } | 891 | } |
874 | 892 | ||
893 | ehca_free_fw_ctrlblock(mqpcb); | ||
894 | |||
875 | return &my_qp->ib_srq; | 895 | return &my_qp->ib_srq; |
876 | 896 | ||
877 | create_srq2: | 897 | create_srq2: |
@@ -905,7 +925,7 @@ static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca, | |||
905 | &bad_send_wqe_p, NULL, 2); | 925 | &bad_send_wqe_p, NULL, 2); |
906 | if (h_ret != H_SUCCESS) { | 926 | if (h_ret != H_SUCCESS) { |
907 | ehca_err(&shca->ib_device, "hipz_h_disable_and_get_wqe() failed" | 927 | ehca_err(&shca->ib_device, "hipz_h_disable_and_get_wqe() failed" |
908 | " ehca_qp=%p qp_num=%x h_ret=%lx", | 928 | " ehca_qp=%p qp_num=%x h_ret=%li", |
909 | my_qp, qp_num, h_ret); | 929 | my_qp, qp_num, h_ret); |
910 | return ehca2ib_return_code(h_ret); | 930 | return ehca2ib_return_code(h_ret); |
911 | } | 931 | } |
@@ -983,7 +1003,7 @@ static int internal_modify_qp(struct ib_qp *ibqp, | |||
983 | mqpcb, my_qp->galpas.kernel); | 1003 | mqpcb, my_qp->galpas.kernel); |
984 | if (h_ret != H_SUCCESS) { | 1004 | if (h_ret != H_SUCCESS) { |
985 | ehca_err(ibqp->device, "hipz_h_query_qp() failed " | 1005 | ehca_err(ibqp->device, "hipz_h_query_qp() failed " |
986 | "ehca_qp=%p qp_num=%x h_ret=%lx", | 1006 | "ehca_qp=%p qp_num=%x h_ret=%li", |
987 | my_qp, ibqp->qp_num, h_ret); | 1007 | my_qp, ibqp->qp_num, h_ret); |
988 | ret = ehca2ib_return_code(h_ret); | 1008 | ret = ehca2ib_return_code(h_ret); |
989 | goto modify_qp_exit1; | 1009 | goto modify_qp_exit1; |
@@ -1019,7 +1039,7 @@ static int internal_modify_qp(struct ib_qp *ibqp, | |||
1019 | ibqp, &smiqp_attr, smiqp_attr_mask, 1); | 1039 | ibqp, &smiqp_attr, smiqp_attr_mask, 1); |
1020 | if (smirc) { | 1040 | if (smirc) { |
1021 | ehca_err(ibqp->device, "SMI RESET -> INIT failed. " | 1041 | ehca_err(ibqp->device, "SMI RESET -> INIT failed. " |
1022 | "ehca_modify_qp() rc=%x", smirc); | 1042 | "ehca_modify_qp() rc=%i", smirc); |
1023 | ret = H_PARAMETER; | 1043 | ret = H_PARAMETER; |
1024 | goto modify_qp_exit1; | 1044 | goto modify_qp_exit1; |
1025 | } | 1045 | } |
@@ -1121,7 +1141,7 @@ static int internal_modify_qp(struct ib_qp *ibqp, | |||
1121 | ret = prepare_sqe_rts(my_qp, shca, &bad_wqe_cnt); | 1141 | ret = prepare_sqe_rts(my_qp, shca, &bad_wqe_cnt); |
1122 | if (ret) { | 1142 | if (ret) { |
1123 | ehca_err(ibqp->device, "prepare_sqe_rts() failed " | 1143 | ehca_err(ibqp->device, "prepare_sqe_rts() failed " |
1124 | "ehca_qp=%p qp_num=%x ret=%x", | 1144 | "ehca_qp=%p qp_num=%x ret=%i", |
1125 | my_qp, ibqp->qp_num, ret); | 1145 | my_qp, ibqp->qp_num, ret); |
1126 | goto modify_qp_exit2; | 1146 | goto modify_qp_exit2; |
1127 | } | 1147 | } |
@@ -1147,6 +1167,13 @@ static int internal_modify_qp(struct ib_qp *ibqp, | |||
1147 | } | 1167 | } |
1148 | 1168 | ||
1149 | if (attr_mask & IB_QP_PKEY_INDEX) { | 1169 | if (attr_mask & IB_QP_PKEY_INDEX) { |
1170 | if (attr->pkey_index >= 16) { | ||
1171 | ret = -EINVAL; | ||
1172 | ehca_err(ibqp->device, "Invalid pkey_index=%x. " | ||
1173 | "ehca_qp=%p qp_num=%x max_pkey_index=f", | ||
1174 | attr->pkey_index, my_qp, ibqp->qp_num); | ||
1175 | goto modify_qp_exit2; | ||
1176 | } | ||
1150 | mqpcb->prim_p_key_idx = attr->pkey_index; | 1177 | mqpcb->prim_p_key_idx = attr->pkey_index; |
1151 | update_mask |= EHCA_BMASK_SET(MQPCB_MASK_PRIM_P_KEY_IDX, 1); | 1178 | update_mask |= EHCA_BMASK_SET(MQPCB_MASK_PRIM_P_KEY_IDX, 1); |
1152 | } | 1179 | } |
@@ -1255,50 +1282,78 @@ static int internal_modify_qp(struct ib_qp *ibqp, | |||
1255 | int ehca_mult = ib_rate_to_mult( | 1282 | int ehca_mult = ib_rate_to_mult( |
1256 | shca->sport[my_qp->init_attr.port_num].rate); | 1283 | shca->sport[my_qp->init_attr.port_num].rate); |
1257 | 1284 | ||
1285 | if (attr->alt_port_num < 1 | ||
1286 | || attr->alt_port_num > shca->num_ports) { | ||
1287 | ret = -EINVAL; | ||
1288 | ehca_err(ibqp->device, "Invalid alt_port=%x. " | ||
1289 | "ehca_qp=%p qp_num=%x num_ports=%x", | ||
1290 | attr->alt_port_num, my_qp, ibqp->qp_num, | ||
1291 | shca->num_ports); | ||
1292 | goto modify_qp_exit2; | ||
1293 | } | ||
1294 | mqpcb->alt_phys_port = attr->alt_port_num; | ||
1295 | |||
1296 | if (attr->alt_pkey_index >= 16) { | ||
1297 | ret = -EINVAL; | ||
1298 | ehca_err(ibqp->device, "Invalid alt_pkey_index=%x. " | ||
1299 | "ehca_qp=%p qp_num=%x max_pkey_index=f", | ||
1300 | attr->pkey_index, my_qp, ibqp->qp_num); | ||
1301 | goto modify_qp_exit2; | ||
1302 | } | ||
1303 | mqpcb->alt_p_key_idx = attr->alt_pkey_index; | ||
1304 | |||
1305 | mqpcb->timeout_al = attr->alt_timeout; | ||
1258 | mqpcb->dlid_al = attr->alt_ah_attr.dlid; | 1306 | mqpcb->dlid_al = attr->alt_ah_attr.dlid; |
1259 | update_mask |= EHCA_BMASK_SET(MQPCB_MASK_DLID_AL, 1); | ||
1260 | mqpcb->source_path_bits_al = attr->alt_ah_attr.src_path_bits; | 1307 | mqpcb->source_path_bits_al = attr->alt_ah_attr.src_path_bits; |
1261 | update_mask |= | ||
1262 | EHCA_BMASK_SET(MQPCB_MASK_SOURCE_PATH_BITS_AL, 1); | ||
1263 | mqpcb->service_level_al = attr->alt_ah_attr.sl; | 1308 | mqpcb->service_level_al = attr->alt_ah_attr.sl; |
1264 | update_mask |= EHCA_BMASK_SET(MQPCB_MASK_SERVICE_LEVEL_AL, 1); | ||
1265 | 1309 | ||
1266 | if (ah_mult < ehca_mult) | 1310 | if (ah_mult > 0 && ah_mult < ehca_mult) |
1267 | mqpcb->max_static_rate = (ah_mult > 0) ? | 1311 | mqpcb->max_static_rate_al = (ehca_mult - 1) / ah_mult; |
1268 | ((ehca_mult - 1) / ah_mult) : 0; | ||
1269 | else | 1312 | else |
1270 | mqpcb->max_static_rate_al = 0; | 1313 | mqpcb->max_static_rate_al = 0; |
1271 | 1314 | ||
1272 | update_mask |= EHCA_BMASK_SET(MQPCB_MASK_MAX_STATIC_RATE_AL, 1); | 1315 | /* OpenIB doesn't support alternate retry counts - copy them */ |
1316 | mqpcb->retry_count_al = mqpcb->retry_count; | ||
1317 | mqpcb->rnr_retry_count_al = mqpcb->rnr_retry_count; | ||
1318 | |||
1319 | update_mask |= EHCA_BMASK_SET(MQPCB_MASK_ALT_PHYS_PORT, 1) | ||
1320 | | EHCA_BMASK_SET(MQPCB_MASK_ALT_P_KEY_IDX, 1) | ||
1321 | | EHCA_BMASK_SET(MQPCB_MASK_TIMEOUT_AL, 1) | ||
1322 | | EHCA_BMASK_SET(MQPCB_MASK_DLID_AL, 1) | ||
1323 | | EHCA_BMASK_SET(MQPCB_MASK_SOURCE_PATH_BITS_AL, 1) | ||
1324 | | EHCA_BMASK_SET(MQPCB_MASK_SERVICE_LEVEL_AL, 1) | ||
1325 | | EHCA_BMASK_SET(MQPCB_MASK_MAX_STATIC_RATE_AL, 1) | ||
1326 | | EHCA_BMASK_SET(MQPCB_MASK_RETRY_COUNT_AL, 1) | ||
1327 | | EHCA_BMASK_SET(MQPCB_MASK_RNR_RETRY_COUNT_AL, 1); | ||
1328 | |||
1329 | /* | ||
1330 | * Always supply the GRH flag, even if it's zero, to give the | ||
1331 | * hypervisor a clear "yes" or "no" instead of a "perhaps" | ||
1332 | */ | ||
1333 | update_mask |= EHCA_BMASK_SET(MQPCB_MASK_SEND_GRH_FLAG_AL, 1); | ||
1273 | 1334 | ||
1274 | /* | 1335 | /* |
1275 | * only if GRH is TRUE we might consider SOURCE_GID_IDX | 1336 | * only if GRH is TRUE we might consider SOURCE_GID_IDX |
1276 | * and DEST_GID otherwise phype will return H_ATTR_PARM!!! | 1337 | * and DEST_GID otherwise phype will return H_ATTR_PARM!!! |
1277 | */ | 1338 | */ |
1278 | if (attr->alt_ah_attr.ah_flags == IB_AH_GRH) { | 1339 | if (attr->alt_ah_attr.ah_flags == IB_AH_GRH) { |
1279 | mqpcb->send_grh_flag_al = 1 << 31; | 1340 | mqpcb->send_grh_flag_al = 1; |
1280 | update_mask |= | ||
1281 | EHCA_BMASK_SET(MQPCB_MASK_SEND_GRH_FLAG_AL, 1); | ||
1282 | mqpcb->source_gid_idx_al = | ||
1283 | attr->alt_ah_attr.grh.sgid_index; | ||
1284 | update_mask |= | ||
1285 | EHCA_BMASK_SET(MQPCB_MASK_SOURCE_GID_IDX_AL, 1); | ||
1286 | 1341 | ||
1287 | for (cnt = 0; cnt < 16; cnt++) | 1342 | for (cnt = 0; cnt < 16; cnt++) |
1288 | mqpcb->dest_gid_al.byte[cnt] = | 1343 | mqpcb->dest_gid_al.byte[cnt] = |
1289 | attr->alt_ah_attr.grh.dgid.raw[cnt]; | 1344 | attr->alt_ah_attr.grh.dgid.raw[cnt]; |
1290 | 1345 | mqpcb->source_gid_idx_al = | |
1291 | update_mask |= | 1346 | attr->alt_ah_attr.grh.sgid_index; |
1292 | EHCA_BMASK_SET(MQPCB_MASK_DEST_GID_AL, 1); | ||
1293 | mqpcb->flow_label_al = attr->alt_ah_attr.grh.flow_label; | 1347 | mqpcb->flow_label_al = attr->alt_ah_attr.grh.flow_label; |
1294 | update_mask |= | ||
1295 | EHCA_BMASK_SET(MQPCB_MASK_FLOW_LABEL_AL, 1); | ||
1296 | mqpcb->hop_limit_al = attr->alt_ah_attr.grh.hop_limit; | 1348 | mqpcb->hop_limit_al = attr->alt_ah_attr.grh.hop_limit; |
1297 | update_mask |= | ||
1298 | EHCA_BMASK_SET(MQPCB_MASK_HOP_LIMIT_AL, 1); | ||
1299 | mqpcb->traffic_class_al = | 1349 | mqpcb->traffic_class_al = |
1300 | attr->alt_ah_attr.grh.traffic_class; | 1350 | attr->alt_ah_attr.grh.traffic_class; |
1351 | |||
1301 | update_mask |= | 1352 | update_mask |= |
1353 | EHCA_BMASK_SET(MQPCB_MASK_SOURCE_GID_IDX_AL, 1) | ||
1354 | | EHCA_BMASK_SET(MQPCB_MASK_DEST_GID_AL, 1) | ||
1355 | | EHCA_BMASK_SET(MQPCB_MASK_FLOW_LABEL_AL, 1) | ||
1356 | | EHCA_BMASK_SET(MQPCB_MASK_HOP_LIMIT_AL, 1) | | ||
1302 | EHCA_BMASK_SET(MQPCB_MASK_TRAFFIC_CLASS_AL, 1); | 1357 | EHCA_BMASK_SET(MQPCB_MASK_TRAFFIC_CLASS_AL, 1); |
1303 | } | 1358 | } |
1304 | } | 1359 | } |
@@ -1320,7 +1375,14 @@ static int internal_modify_qp(struct ib_qp *ibqp, | |||
1320 | } | 1375 | } |
1321 | 1376 | ||
1322 | if (attr_mask & IB_QP_PATH_MIG_STATE) { | 1377 | if (attr_mask & IB_QP_PATH_MIG_STATE) { |
1323 | mqpcb->path_migration_state = attr->path_mig_state; | 1378 | if (attr->path_mig_state != IB_MIG_REARM |
1379 | && attr->path_mig_state != IB_MIG_MIGRATED) { | ||
1380 | ret = -EINVAL; | ||
1381 | ehca_err(ibqp->device, "Invalid mig_state=%x", | ||
1382 | attr->path_mig_state); | ||
1383 | goto modify_qp_exit2; | ||
1384 | } | ||
1385 | mqpcb->path_migration_state = attr->path_mig_state + 1; | ||
1324 | update_mask |= | 1386 | update_mask |= |
1325 | EHCA_BMASK_SET(MQPCB_MASK_PATH_MIGRATION_STATE, 1); | 1387 | EHCA_BMASK_SET(MQPCB_MASK_PATH_MIGRATION_STATE, 1); |
1326 | } | 1388 | } |
@@ -1346,7 +1408,7 @@ static int internal_modify_qp(struct ib_qp *ibqp, | |||
1346 | 1408 | ||
1347 | if (h_ret != H_SUCCESS) { | 1409 | if (h_ret != H_SUCCESS) { |
1348 | ret = ehca2ib_return_code(h_ret); | 1410 | ret = ehca2ib_return_code(h_ret); |
1349 | ehca_err(ibqp->device, "hipz_h_modify_qp() failed rc=%lx " | 1411 | ehca_err(ibqp->device, "hipz_h_modify_qp() failed h_ret=%li " |
1350 | "ehca_qp=%p qp_num=%x", h_ret, my_qp, ibqp->qp_num); | 1412 | "ehca_qp=%p qp_num=%x", h_ret, my_qp, ibqp->qp_num); |
1351 | goto modify_qp_exit2; | 1413 | goto modify_qp_exit2; |
1352 | } | 1414 | } |
@@ -1379,7 +1441,7 @@ static int internal_modify_qp(struct ib_qp *ibqp, | |||
1379 | ret = ehca2ib_return_code(h_ret); | 1441 | ret = ehca2ib_return_code(h_ret); |
1380 | ehca_err(ibqp->device, "ENABLE in context of " | 1442 | ehca_err(ibqp->device, "ENABLE in context of " |
1381 | "RESET_2_INIT failed! Maybe you didn't get " | 1443 | "RESET_2_INIT failed! Maybe you didn't get " |
1382 | "a LID h_ret=%lx ehca_qp=%p qp_num=%x", | 1444 | "a LID h_ret=%li ehca_qp=%p qp_num=%x", |
1383 | h_ret, my_qp, ibqp->qp_num); | 1445 | h_ret, my_qp, ibqp->qp_num); |
1384 | goto modify_qp_exit2; | 1446 | goto modify_qp_exit2; |
1385 | } | 1447 | } |
@@ -1467,7 +1529,7 @@ int ehca_query_qp(struct ib_qp *qp, | |||
1467 | if (h_ret != H_SUCCESS) { | 1529 | if (h_ret != H_SUCCESS) { |
1468 | ret = ehca2ib_return_code(h_ret); | 1530 | ret = ehca2ib_return_code(h_ret); |
1469 | ehca_err(qp->device, "hipz_h_query_qp() failed " | 1531 | ehca_err(qp->device, "hipz_h_query_qp() failed " |
1470 | "ehca_qp=%p qp_num=%x h_ret=%lx", | 1532 | "ehca_qp=%p qp_num=%x h_ret=%li", |
1471 | my_qp, qp->qp_num, h_ret); | 1533 | my_qp, qp->qp_num, h_ret); |
1472 | goto query_qp_exit1; | 1534 | goto query_qp_exit1; |
1473 | } | 1535 | } |
@@ -1488,7 +1550,7 @@ int ehca_query_qp(struct ib_qp *qp, | |||
1488 | 1550 | ||
1489 | qp_attr->qkey = qpcb->qkey; | 1551 | qp_attr->qkey = qpcb->qkey; |
1490 | qp_attr->path_mtu = qpcb->path_mtu; | 1552 | qp_attr->path_mtu = qpcb->path_mtu; |
1491 | qp_attr->path_mig_state = qpcb->path_migration_state; | 1553 | qp_attr->path_mig_state = qpcb->path_migration_state - 1; |
1492 | qp_attr->rq_psn = qpcb->receive_psn; | 1554 | qp_attr->rq_psn = qpcb->receive_psn; |
1493 | qp_attr->sq_psn = qpcb->send_psn; | 1555 | qp_attr->sq_psn = qpcb->send_psn; |
1494 | qp_attr->min_rnr_timer = qpcb->min_rnr_nak_timer_field; | 1556 | qp_attr->min_rnr_timer = qpcb->min_rnr_nak_timer_field; |
@@ -1642,7 +1704,7 @@ int ehca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, | |||
1642 | 1704 | ||
1643 | if (h_ret != H_SUCCESS) { | 1705 | if (h_ret != H_SUCCESS) { |
1644 | ret = ehca2ib_return_code(h_ret); | 1706 | ret = ehca2ib_return_code(h_ret); |
1645 | ehca_err(ibsrq->device, "hipz_h_modify_qp() failed rc=%lx " | 1707 | ehca_err(ibsrq->device, "hipz_h_modify_qp() failed h_ret=%li " |
1646 | "ehca_qp=%p qp_num=%x", | 1708 | "ehca_qp=%p qp_num=%x", |
1647 | h_ret, my_qp, my_qp->real_qp_num); | 1709 | h_ret, my_qp, my_qp->real_qp_num); |
1648 | } | 1710 | } |
@@ -1685,12 +1747,13 @@ int ehca_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr) | |||
1685 | if (h_ret != H_SUCCESS) { | 1747 | if (h_ret != H_SUCCESS) { |
1686 | ret = ehca2ib_return_code(h_ret); | 1748 | ret = ehca2ib_return_code(h_ret); |
1687 | ehca_err(srq->device, "hipz_h_query_qp() failed " | 1749 | ehca_err(srq->device, "hipz_h_query_qp() failed " |
1688 | "ehca_qp=%p qp_num=%x h_ret=%lx", | 1750 | "ehca_qp=%p qp_num=%x h_ret=%li", |
1689 | my_qp, my_qp->real_qp_num, h_ret); | 1751 | my_qp, my_qp->real_qp_num, h_ret); |
1690 | goto query_srq_exit1; | 1752 | goto query_srq_exit1; |
1691 | } | 1753 | } |
1692 | 1754 | ||
1693 | srq_attr->max_wr = qpcb->max_nr_outst_recv_wr - 1; | 1755 | srq_attr->max_wr = qpcb->max_nr_outst_recv_wr - 1; |
1756 | srq_attr->max_sge = qpcb->actual_nr_sges_in_rq_wqe; | ||
1694 | srq_attr->srq_limit = EHCA_BMASK_GET( | 1757 | srq_attr->srq_limit = EHCA_BMASK_GET( |
1695 | MQPCB_CURR_SRQ_LIMIT, qpcb->curr_srq_limit); | 1758 | MQPCB_CURR_SRQ_LIMIT, qpcb->curr_srq_limit); |
1696 | 1759 | ||
@@ -1735,7 +1798,7 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp, | |||
1735 | ret = ehca_cq_unassign_qp(my_qp->send_cq, qp_num); | 1798 | ret = ehca_cq_unassign_qp(my_qp->send_cq, qp_num); |
1736 | if (ret) { | 1799 | if (ret) { |
1737 | ehca_err(dev, "Couldn't unassign qp from " | 1800 | ehca_err(dev, "Couldn't unassign qp from " |
1738 | "send_cq ret=%x qp_num=%x cq_num=%x", ret, | 1801 | "send_cq ret=%i qp_num=%x cq_num=%x", ret, |
1739 | qp_num, my_qp->send_cq->cq_number); | 1802 | qp_num, my_qp->send_cq->cq_number); |
1740 | return ret; | 1803 | return ret; |
1741 | } | 1804 | } |
@@ -1747,7 +1810,7 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp, | |||
1747 | 1810 | ||
1748 | h_ret = hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp); | 1811 | h_ret = hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp); |
1749 | if (h_ret != H_SUCCESS) { | 1812 | if (h_ret != H_SUCCESS) { |
1750 | ehca_err(dev, "hipz_h_destroy_qp() failed rc=%lx " | 1813 | ehca_err(dev, "hipz_h_destroy_qp() failed h_ret=%li " |
1751 | "ehca_qp=%p qp_num=%x", h_ret, my_qp, qp_num); | 1814 | "ehca_qp=%p qp_num=%x", h_ret, my_qp, qp_num); |
1752 | return ehca2ib_return_code(h_ret); | 1815 | return ehca2ib_return_code(h_ret); |
1753 | } | 1816 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c index 94eed70fedf5..ea91360835d3 100644 --- a/drivers/infiniband/hw/ehca/ehca_reqs.c +++ b/drivers/infiniband/hw/ehca/ehca_reqs.c | |||
@@ -526,7 +526,7 @@ poll_cq_one_read_cqe: | |||
526 | if (!cqe) { | 526 | if (!cqe) { |
527 | ret = -EAGAIN; | 527 | ret = -EAGAIN; |
528 | ehca_dbg(cq->device, "Completion queue is empty ehca_cq=%p " | 528 | ehca_dbg(cq->device, "Completion queue is empty ehca_cq=%p " |
529 | "cq_num=%x ret=%x", my_cq, my_cq->cq_number, ret); | 529 | "cq_num=%x ret=%i", my_cq, my_cq->cq_number, ret); |
530 | goto poll_cq_one_exit0; | 530 | goto poll_cq_one_exit0; |
531 | } | 531 | } |
532 | 532 | ||
diff --git a/drivers/infiniband/hw/ehca/ehca_sqp.c b/drivers/infiniband/hw/ehca/ehca_sqp.c index 9f16e9c79394..f0792e5fbd02 100644 --- a/drivers/infiniband/hw/ehca/ehca_sqp.c +++ b/drivers/infiniband/hw/ehca/ehca_sqp.c | |||
@@ -82,7 +82,7 @@ u64 ehca_define_sqp(struct ehca_shca *shca, | |||
82 | 82 | ||
83 | if (ret != H_SUCCESS) { | 83 | if (ret != H_SUCCESS) { |
84 | ehca_err(&shca->ib_device, | 84 | ehca_err(&shca->ib_device, |
85 | "Can't define AQP1 for port %x. rc=%lx", | 85 | "Can't define AQP1 for port %x. h_ret=%li", |
86 | port, ret); | 86 | port, ret); |
87 | return ret; | 87 | return ret; |
88 | } | 88 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_tools.h b/drivers/infiniband/hw/ehca/ehca_tools.h index 57c77a715f46..4a8346a2bc9e 100644 --- a/drivers/infiniband/hw/ehca/ehca_tools.h +++ b/drivers/infiniband/hw/ehca/ehca_tools.h | |||
@@ -73,40 +73,37 @@ extern int ehca_debug_level; | |||
73 | if (unlikely(ehca_debug_level)) \ | 73 | if (unlikely(ehca_debug_level)) \ |
74 | dev_printk(KERN_DEBUG, (ib_dev)->dma_device, \ | 74 | dev_printk(KERN_DEBUG, (ib_dev)->dma_device, \ |
75 | "PU%04x EHCA_DBG:%s " format "\n", \ | 75 | "PU%04x EHCA_DBG:%s " format "\n", \ |
76 | get_paca()->paca_index, __FUNCTION__, \ | 76 | raw_smp_processor_id(), __FUNCTION__, \ |
77 | ## arg); \ | 77 | ## arg); \ |
78 | } while (0) | 78 | } while (0) |
79 | 79 | ||
80 | #define ehca_info(ib_dev, format, arg...) \ | 80 | #define ehca_info(ib_dev, format, arg...) \ |
81 | dev_info((ib_dev)->dma_device, "PU%04x EHCA_INFO:%s " format "\n", \ | 81 | dev_info((ib_dev)->dma_device, "PU%04x EHCA_INFO:%s " format "\n", \ |
82 | get_paca()->paca_index, __FUNCTION__, ## arg) | 82 | raw_smp_processor_id(), __FUNCTION__, ## arg) |
83 | 83 | ||
84 | #define ehca_warn(ib_dev, format, arg...) \ | 84 | #define ehca_warn(ib_dev, format, arg...) \ |
85 | dev_warn((ib_dev)->dma_device, "PU%04x EHCA_WARN:%s " format "\n", \ | 85 | dev_warn((ib_dev)->dma_device, "PU%04x EHCA_WARN:%s " format "\n", \ |
86 | get_paca()->paca_index, __FUNCTION__, ## arg) | 86 | raw_smp_processor_id(), __FUNCTION__, ## arg) |
87 | 87 | ||
88 | #define ehca_err(ib_dev, format, arg...) \ | 88 | #define ehca_err(ib_dev, format, arg...) \ |
89 | dev_err((ib_dev)->dma_device, "PU%04x EHCA_ERR:%s " format "\n", \ | 89 | dev_err((ib_dev)->dma_device, "PU%04x EHCA_ERR:%s " format "\n", \ |
90 | get_paca()->paca_index, __FUNCTION__, ## arg) | 90 | raw_smp_processor_id(), __FUNCTION__, ## arg) |
91 | 91 | ||
92 | /* use this one only if no ib_dev available */ | 92 | /* use this one only if no ib_dev available */ |
93 | #define ehca_gen_dbg(format, arg...) \ | 93 | #define ehca_gen_dbg(format, arg...) \ |
94 | do { \ | 94 | do { \ |
95 | if (unlikely(ehca_debug_level)) \ | 95 | if (unlikely(ehca_debug_level)) \ |
96 | printk(KERN_DEBUG "PU%04x EHCA_DBG:%s " format "\n", \ | 96 | printk(KERN_DEBUG "PU%04x EHCA_DBG:%s " format "\n", \ |
97 | get_paca()->paca_index, __FUNCTION__, ## arg); \ | 97 | raw_smp_processor_id(), __FUNCTION__, ## arg); \ |
98 | } while (0) | 98 | } while (0) |
99 | 99 | ||
100 | #define ehca_gen_warn(format, arg...) \ | 100 | #define ehca_gen_warn(format, arg...) \ |
101 | do { \ | 101 | printk(KERN_INFO "PU%04x EHCA_WARN:%s " format "\n", \ |
102 | if (unlikely(ehca_debug_level)) \ | 102 | raw_smp_processor_id(), __FUNCTION__, ## arg) |
103 | printk(KERN_INFO "PU%04x EHCA_WARN:%s " format "\n", \ | ||
104 | get_paca()->paca_index, __FUNCTION__, ## arg); \ | ||
105 | } while (0) | ||
106 | 103 | ||
107 | #define ehca_gen_err(format, arg...) \ | 104 | #define ehca_gen_err(format, arg...) \ |
108 | printk(KERN_ERR "PU%04x EHCA_ERR:%s " format "\n", \ | 105 | printk(KERN_ERR "PU%04x EHCA_ERR:%s " format "\n", \ |
109 | get_paca()->paca_index, __FUNCTION__, ## arg) | 106 | raw_smp_processor_id(), __FUNCTION__, ## arg) |
110 | 107 | ||
111 | /** | 108 | /** |
112 | * ehca_dmp - printk a memory block, whose length is n*8 bytes. | 109 | * ehca_dmp - printk a memory block, whose length is n*8 bytes. |
diff --git a/drivers/infiniband/hw/ehca/ehca_uverbs.c b/drivers/infiniband/hw/ehca/ehca_uverbs.c index 4bc687fdf531..5234d6c15c49 100644 --- a/drivers/infiniband/hw/ehca/ehca_uverbs.c +++ b/drivers/infiniband/hw/ehca/ehca_uverbs.c | |||
@@ -109,7 +109,7 @@ static int ehca_mmap_fw(struct vm_area_struct *vma, struct h_galpas *galpas, | |||
109 | u64 vsize, physical; | 109 | u64 vsize, physical; |
110 | 110 | ||
111 | vsize = vma->vm_end - vma->vm_start; | 111 | vsize = vma->vm_end - vma->vm_start; |
112 | if (vsize != EHCA_PAGESIZE) { | 112 | if (vsize < EHCA_PAGESIZE) { |
113 | ehca_gen_err("invalid vsize=%lx", vma->vm_end - vma->vm_start); | 113 | ehca_gen_err("invalid vsize=%lx", vma->vm_end - vma->vm_start); |
114 | return -EINVAL; | 114 | return -EINVAL; |
115 | } | 115 | } |
@@ -118,10 +118,10 @@ static int ehca_mmap_fw(struct vm_area_struct *vma, struct h_galpas *galpas, | |||
118 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 118 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
119 | ehca_gen_dbg("vsize=%lx physical=%lx", vsize, physical); | 119 | ehca_gen_dbg("vsize=%lx physical=%lx", vsize, physical); |
120 | /* VM_IO | VM_RESERVED are set by remap_pfn_range() */ | 120 | /* VM_IO | VM_RESERVED are set by remap_pfn_range() */ |
121 | ret = remap_pfn_range(vma, vma->vm_start, physical >> PAGE_SHIFT, | 121 | ret = remap_4k_pfn(vma, vma->vm_start, physical >> EHCA_PAGESHIFT, |
122 | vsize, vma->vm_page_prot); | 122 | vma->vm_page_prot); |
123 | if (unlikely(ret)) { | 123 | if (unlikely(ret)) { |
124 | ehca_gen_err("remap_pfn_range() failed ret=%x", ret); | 124 | ehca_gen_err("remap_pfn_range() failed ret=%i", ret); |
125 | return -ENOMEM; | 125 | return -ENOMEM; |
126 | } | 126 | } |
127 | 127 | ||
@@ -146,7 +146,7 @@ static int ehca_mmap_queue(struct vm_area_struct *vma, struct ipz_queue *queue, | |||
146 | page = virt_to_page(virt_addr); | 146 | page = virt_to_page(virt_addr); |
147 | ret = vm_insert_page(vma, start, page); | 147 | ret = vm_insert_page(vma, start, page); |
148 | if (unlikely(ret)) { | 148 | if (unlikely(ret)) { |
149 | ehca_gen_err("vm_insert_page() failed rc=%x", ret); | 149 | ehca_gen_err("vm_insert_page() failed rc=%i", ret); |
150 | return ret; | 150 | return ret; |
151 | } | 151 | } |
152 | start += PAGE_SIZE; | 152 | start += PAGE_SIZE; |
@@ -164,23 +164,23 @@ static int ehca_mmap_cq(struct vm_area_struct *vma, struct ehca_cq *cq, | |||
164 | int ret; | 164 | int ret; |
165 | 165 | ||
166 | switch (rsrc_type) { | 166 | switch (rsrc_type) { |
167 | case 1: /* galpa fw handle */ | 167 | case 0: /* galpa fw handle */ |
168 | ehca_dbg(cq->ib_cq.device, "cq_num=%x fw", cq->cq_number); | 168 | ehca_dbg(cq->ib_cq.device, "cq_num=%x fw", cq->cq_number); |
169 | ret = ehca_mmap_fw(vma, &cq->galpas, &cq->mm_count_galpa); | 169 | ret = ehca_mmap_fw(vma, &cq->galpas, &cq->mm_count_galpa); |
170 | if (unlikely(ret)) { | 170 | if (unlikely(ret)) { |
171 | ehca_err(cq->ib_cq.device, | 171 | ehca_err(cq->ib_cq.device, |
172 | "ehca_mmap_fw() failed rc=%x cq_num=%x", | 172 | "ehca_mmap_fw() failed rc=%i cq_num=%x", |
173 | ret, cq->cq_number); | 173 | ret, cq->cq_number); |
174 | return ret; | 174 | return ret; |
175 | } | 175 | } |
176 | break; | 176 | break; |
177 | 177 | ||
178 | case 2: /* cq queue_addr */ | 178 | case 1: /* cq queue_addr */ |
179 | ehca_dbg(cq->ib_cq.device, "cq_num=%x queue", cq->cq_number); | 179 | ehca_dbg(cq->ib_cq.device, "cq_num=%x queue", cq->cq_number); |
180 | ret = ehca_mmap_queue(vma, &cq->ipz_queue, &cq->mm_count_queue); | 180 | ret = ehca_mmap_queue(vma, &cq->ipz_queue, &cq->mm_count_queue); |
181 | if (unlikely(ret)) { | 181 | if (unlikely(ret)) { |
182 | ehca_err(cq->ib_cq.device, | 182 | ehca_err(cq->ib_cq.device, |
183 | "ehca_mmap_queue() failed rc=%x cq_num=%x", | 183 | "ehca_mmap_queue() failed rc=%i cq_num=%x", |
184 | ret, cq->cq_number); | 184 | ret, cq->cq_number); |
185 | return ret; | 185 | return ret; |
186 | } | 186 | } |
@@ -201,38 +201,38 @@ static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp, | |||
201 | int ret; | 201 | int ret; |
202 | 202 | ||
203 | switch (rsrc_type) { | 203 | switch (rsrc_type) { |
204 | case 1: /* galpa fw handle */ | 204 | case 0: /* galpa fw handle */ |
205 | ehca_dbg(qp->ib_qp.device, "qp_num=%x fw", qp->ib_qp.qp_num); | 205 | ehca_dbg(qp->ib_qp.device, "qp_num=%x fw", qp->ib_qp.qp_num); |
206 | ret = ehca_mmap_fw(vma, &qp->galpas, &qp->mm_count_galpa); | 206 | ret = ehca_mmap_fw(vma, &qp->galpas, &qp->mm_count_galpa); |
207 | if (unlikely(ret)) { | 207 | if (unlikely(ret)) { |
208 | ehca_err(qp->ib_qp.device, | 208 | ehca_err(qp->ib_qp.device, |
209 | "remap_pfn_range() failed ret=%x qp_num=%x", | 209 | "remap_pfn_range() failed ret=%i qp_num=%x", |
210 | ret, qp->ib_qp.qp_num); | 210 | ret, qp->ib_qp.qp_num); |
211 | return -ENOMEM; | 211 | return -ENOMEM; |
212 | } | 212 | } |
213 | break; | 213 | break; |
214 | 214 | ||
215 | case 2: /* qp rqueue_addr */ | 215 | case 1: /* qp rqueue_addr */ |
216 | ehca_dbg(qp->ib_qp.device, "qp_num=%x rqueue", | 216 | ehca_dbg(qp->ib_qp.device, "qp_num=%x rqueue", |
217 | qp->ib_qp.qp_num); | 217 | qp->ib_qp.qp_num); |
218 | ret = ehca_mmap_queue(vma, &qp->ipz_rqueue, | 218 | ret = ehca_mmap_queue(vma, &qp->ipz_rqueue, |
219 | &qp->mm_count_rqueue); | 219 | &qp->mm_count_rqueue); |
220 | if (unlikely(ret)) { | 220 | if (unlikely(ret)) { |
221 | ehca_err(qp->ib_qp.device, | 221 | ehca_err(qp->ib_qp.device, |
222 | "ehca_mmap_queue(rq) failed rc=%x qp_num=%x", | 222 | "ehca_mmap_queue(rq) failed rc=%i qp_num=%x", |
223 | ret, qp->ib_qp.qp_num); | 223 | ret, qp->ib_qp.qp_num); |
224 | return ret; | 224 | return ret; |
225 | } | 225 | } |
226 | break; | 226 | break; |
227 | 227 | ||
228 | case 3: /* qp squeue_addr */ | 228 | case 2: /* qp squeue_addr */ |
229 | ehca_dbg(qp->ib_qp.device, "qp_num=%x squeue", | 229 | ehca_dbg(qp->ib_qp.device, "qp_num=%x squeue", |
230 | qp->ib_qp.qp_num); | 230 | qp->ib_qp.qp_num); |
231 | ret = ehca_mmap_queue(vma, &qp->ipz_squeue, | 231 | ret = ehca_mmap_queue(vma, &qp->ipz_squeue, |
232 | &qp->mm_count_squeue); | 232 | &qp->mm_count_squeue); |
233 | if (unlikely(ret)) { | 233 | if (unlikely(ret)) { |
234 | ehca_err(qp->ib_qp.device, | 234 | ehca_err(qp->ib_qp.device, |
235 | "ehca_mmap_queue(sq) failed rc=%x qp_num=%x", | 235 | "ehca_mmap_queue(sq) failed rc=%i qp_num=%x", |
236 | ret, qp->ib_qp.qp_num); | 236 | ret, qp->ib_qp.qp_num); |
237 | return ret; | 237 | return ret; |
238 | } | 238 | } |
@@ -249,10 +249,10 @@ static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp, | |||
249 | 249 | ||
250 | int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) | 250 | int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) |
251 | { | 251 | { |
252 | u64 fileoffset = vma->vm_pgoff << PAGE_SHIFT; | 252 | u64 fileoffset = vma->vm_pgoff; |
253 | u32 idr_handle = fileoffset >> 32; | 253 | u32 idr_handle = fileoffset & 0x1FFFFFF; |
254 | u32 q_type = (fileoffset >> 28) & 0xF; /* CQ, QP,... */ | 254 | u32 q_type = (fileoffset >> 27) & 0x1; /* CQ, QP,... */ |
255 | u32 rsrc_type = (fileoffset >> 24) & 0xF; /* sq,rq,cmnd_window */ | 255 | u32 rsrc_type = (fileoffset >> 25) & 0x3; /* sq,rq,cmnd_window */ |
256 | u32 cur_pid = current->tgid; | 256 | u32 cur_pid = current->tgid; |
257 | u32 ret; | 257 | u32 ret; |
258 | struct ehca_cq *cq; | 258 | struct ehca_cq *cq; |
@@ -261,7 +261,7 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) | |||
261 | struct ib_uobject *uobject; | 261 | struct ib_uobject *uobject; |
262 | 262 | ||
263 | switch (q_type) { | 263 | switch (q_type) { |
264 | case 1: /* CQ */ | 264 | case 0: /* CQ */ |
265 | read_lock(&ehca_cq_idr_lock); | 265 | read_lock(&ehca_cq_idr_lock); |
266 | cq = idr_find(&ehca_cq_idr, idr_handle); | 266 | cq = idr_find(&ehca_cq_idr, idr_handle); |
267 | read_unlock(&ehca_cq_idr_lock); | 267 | read_unlock(&ehca_cq_idr_lock); |
@@ -283,13 +283,13 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) | |||
283 | ret = ehca_mmap_cq(vma, cq, rsrc_type); | 283 | ret = ehca_mmap_cq(vma, cq, rsrc_type); |
284 | if (unlikely(ret)) { | 284 | if (unlikely(ret)) { |
285 | ehca_err(cq->ib_cq.device, | 285 | ehca_err(cq->ib_cq.device, |
286 | "ehca_mmap_cq() failed rc=%x cq_num=%x", | 286 | "ehca_mmap_cq() failed rc=%i cq_num=%x", |
287 | ret, cq->cq_number); | 287 | ret, cq->cq_number); |
288 | return ret; | 288 | return ret; |
289 | } | 289 | } |
290 | break; | 290 | break; |
291 | 291 | ||
292 | case 2: /* QP */ | 292 | case 1: /* QP */ |
293 | read_lock(&ehca_qp_idr_lock); | 293 | read_lock(&ehca_qp_idr_lock); |
294 | qp = idr_find(&ehca_qp_idr, idr_handle); | 294 | qp = idr_find(&ehca_qp_idr, idr_handle); |
295 | read_unlock(&ehca_qp_idr_lock); | 295 | read_unlock(&ehca_qp_idr_lock); |
@@ -313,7 +313,7 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) | |||
313 | ret = ehca_mmap_qp(vma, qp, rsrc_type); | 313 | ret = ehca_mmap_qp(vma, qp, rsrc_type); |
314 | if (unlikely(ret)) { | 314 | if (unlikely(ret)) { |
315 | ehca_err(qp->ib_qp.device, | 315 | ehca_err(qp->ib_qp.device, |
316 | "ehca_mmap_qp() failed rc=%x qp_num=%x", | 316 | "ehca_mmap_qp() failed rc=%i qp_num=%x", |
317 | ret, qp->ib_qp.qp_num); | 317 | ret, qp->ib_qp.qp_num); |
318 | return ret; | 318 | return ret; |
319 | } | 319 | } |
diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c index 24f454162f24..c16a21374bb5 100644 --- a/drivers/infiniband/hw/ehca/hcp_if.c +++ b/drivers/infiniband/hw/ehca/hcp_if.c | |||
@@ -84,6 +84,10 @@ | |||
84 | #define H_MP_SHUTDOWN EHCA_BMASK_IBM(48, 48) | 84 | #define H_MP_SHUTDOWN EHCA_BMASK_IBM(48, 48) |
85 | #define H_MP_RESET_QKEY_CTR EHCA_BMASK_IBM(49, 49) | 85 | #define H_MP_RESET_QKEY_CTR EHCA_BMASK_IBM(49, 49) |
86 | 86 | ||
87 | #define HCALL4_REGS_FORMAT "r4=%lx r5=%lx r6=%lx r7=%lx" | ||
88 | #define HCALL7_REGS_FORMAT HCALL4_REGS_FORMAT " r8=%lx r9=%lx r10=%lx" | ||
89 | #define HCALL9_REGS_FORMAT HCALL7_REGS_FORMAT " r11=%lx r12=%lx" | ||
90 | |||
87 | static DEFINE_SPINLOCK(hcall_lock); | 91 | static DEFINE_SPINLOCK(hcall_lock); |
88 | 92 | ||
89 | static u32 get_longbusy_msecs(int longbusy_rc) | 93 | static u32 get_longbusy_msecs(int longbusy_rc) |
@@ -116,16 +120,28 @@ static long ehca_plpar_hcall_norets(unsigned long opcode, | |||
116 | unsigned long arg7) | 120 | unsigned long arg7) |
117 | { | 121 | { |
118 | long ret; | 122 | long ret; |
119 | int i, sleep_msecs; | 123 | int i, sleep_msecs, do_lock; |
124 | unsigned long flags; | ||
120 | 125 | ||
121 | ehca_gen_dbg("opcode=%lx arg1=%lx arg2=%lx arg3=%lx arg4=%lx " | 126 | ehca_gen_dbg("opcode=%lx " HCALL7_REGS_FORMAT, |
122 | "arg5=%lx arg6=%lx arg7=%lx", | ||
123 | opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7); | 127 | opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7); |
124 | 128 | ||
129 | /* lock H_FREE_RESOURCE(MR) against itself and H_ALLOC_RESOURCE(MR) */ | ||
130 | if ((opcode == H_FREE_RESOURCE) && (arg7 == 5)) { | ||
131 | arg7 = 0; /* better not upset firmware */ | ||
132 | do_lock = 1; | ||
133 | } | ||
134 | |||
125 | for (i = 0; i < 5; i++) { | 135 | for (i = 0; i < 5; i++) { |
136 | if (do_lock) | ||
137 | spin_lock_irqsave(&hcall_lock, flags); | ||
138 | |||
126 | ret = plpar_hcall_norets(opcode, arg1, arg2, arg3, arg4, | 139 | ret = plpar_hcall_norets(opcode, arg1, arg2, arg3, arg4, |
127 | arg5, arg6, arg7); | 140 | arg5, arg6, arg7); |
128 | 141 | ||
142 | if (do_lock) | ||
143 | spin_unlock_irqrestore(&hcall_lock, flags); | ||
144 | |||
129 | if (H_IS_LONG_BUSY(ret)) { | 145 | if (H_IS_LONG_BUSY(ret)) { |
130 | sleep_msecs = get_longbusy_msecs(ret); | 146 | sleep_msecs = get_longbusy_msecs(ret); |
131 | msleep_interruptible(sleep_msecs); | 147 | msleep_interruptible(sleep_msecs); |
@@ -133,16 +149,13 @@ static long ehca_plpar_hcall_norets(unsigned long opcode, | |||
133 | } | 149 | } |
134 | 150 | ||
135 | if (ret < H_SUCCESS) | 151 | if (ret < H_SUCCESS) |
136 | ehca_gen_err("opcode=%lx ret=%lx" | 152 | ehca_gen_err("opcode=%lx ret=%li " HCALL7_REGS_FORMAT, |
137 | " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" | 153 | opcode, ret, arg1, arg2, arg3, |
138 | " arg5=%lx arg6=%lx arg7=%lx ", | 154 | arg4, arg5, arg6, arg7); |
139 | opcode, ret, | 155 | else |
140 | arg1, arg2, arg3, arg4, arg5, | 156 | ehca_gen_dbg("opcode=%lx ret=%li", opcode, ret); |
141 | arg6, arg7); | ||
142 | |||
143 | ehca_gen_dbg("opcode=%lx ret=%lx", opcode, ret); | ||
144 | return ret; | ||
145 | 157 | ||
158 | return ret; | ||
146 | } | 159 | } |
147 | 160 | ||
148 | return H_BUSY; | 161 | return H_BUSY; |
@@ -161,25 +174,24 @@ static long ehca_plpar_hcall9(unsigned long opcode, | |||
161 | unsigned long arg9) | 174 | unsigned long arg9) |
162 | { | 175 | { |
163 | long ret; | 176 | long ret; |
164 | int i, sleep_msecs, lock_is_set = 0; | 177 | int i, sleep_msecs, do_lock; |
165 | unsigned long flags = 0; | 178 | unsigned long flags = 0; |
166 | 179 | ||
167 | ehca_gen_dbg("opcode=%lx arg1=%lx arg2=%lx arg3=%lx arg4=%lx " | 180 | ehca_gen_dbg("INPUT -- opcode=%lx " HCALL9_REGS_FORMAT, opcode, |
168 | "arg5=%lx arg6=%lx arg7=%lx arg8=%lx arg9=%lx", | 181 | arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); |
169 | opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7, | 182 | |
170 | arg8, arg9); | 183 | /* lock H_ALLOC_RESOURCE(MR) against itself and H_FREE_RESOURCE(MR) */ |
184 | do_lock = ((opcode == H_ALLOC_RESOURCE) && (arg2 == 5)); | ||
171 | 185 | ||
172 | for (i = 0; i < 5; i++) { | 186 | for (i = 0; i < 5; i++) { |
173 | if ((opcode == H_ALLOC_RESOURCE) && (arg2 == 5)) { | 187 | if (do_lock) |
174 | spin_lock_irqsave(&hcall_lock, flags); | 188 | spin_lock_irqsave(&hcall_lock, flags); |
175 | lock_is_set = 1; | ||
176 | } | ||
177 | 189 | ||
178 | ret = plpar_hcall9(opcode, outs, | 190 | ret = plpar_hcall9(opcode, outs, |
179 | arg1, arg2, arg3, arg4, arg5, | 191 | arg1, arg2, arg3, arg4, arg5, |
180 | arg6, arg7, arg8, arg9); | 192 | arg6, arg7, arg8, arg9); |
181 | 193 | ||
182 | if (lock_is_set) | 194 | if (do_lock) |
183 | spin_unlock_irqrestore(&hcall_lock, flags); | 195 | spin_unlock_irqrestore(&hcall_lock, flags); |
184 | 196 | ||
185 | if (H_IS_LONG_BUSY(ret)) { | 197 | if (H_IS_LONG_BUSY(ret)) { |
@@ -188,26 +200,19 @@ static long ehca_plpar_hcall9(unsigned long opcode, | |||
188 | continue; | 200 | continue; |
189 | } | 201 | } |
190 | 202 | ||
191 | if (ret < H_SUCCESS) | 203 | if (ret < H_SUCCESS) { |
192 | ehca_gen_err("opcode=%lx ret=%lx" | 204 | ehca_gen_err("INPUT -- opcode=%lx " HCALL9_REGS_FORMAT, |
193 | " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" | 205 | opcode, arg1, arg2, arg3, arg4, arg5, |
194 | " arg5=%lx arg6=%lx arg7=%lx arg8=%lx" | 206 | arg6, arg7, arg8, arg9); |
195 | " arg9=%lx" | 207 | ehca_gen_err("OUTPUT -- ret=%li " HCALL9_REGS_FORMAT, |
196 | " out1=%lx out2=%lx out3=%lx out4=%lx" | 208 | ret, outs[0], outs[1], outs[2], outs[3], |
197 | " out5=%lx out6=%lx out7=%lx out8=%lx" | 209 | outs[4], outs[5], outs[6], outs[7], |
198 | " out9=%lx", | 210 | outs[8]); |
199 | opcode, ret, | 211 | } else |
200 | arg1, arg2, arg3, arg4, arg5, | 212 | ehca_gen_dbg("OUTPUT -- ret=%li " HCALL9_REGS_FORMAT, |
201 | arg6, arg7, arg8, arg9, | 213 | ret, outs[0], outs[1], outs[2], outs[3], |
202 | outs[0], outs[1], outs[2], outs[3], | ||
203 | outs[4], outs[5], outs[6], outs[7], | 214 | outs[4], outs[5], outs[6], outs[7], |
204 | outs[8]); | 215 | outs[8]); |
205 | |||
206 | ehca_gen_dbg("opcode=%lx ret=%lx out1=%lx out2=%lx out3=%lx " | ||
207 | "out4=%lx out5=%lx out6=%lx out7=%lx out8=%lx " | ||
208 | "out9=%lx", | ||
209 | opcode, ret, outs[0], outs[1], outs[2], outs[3], | ||
210 | outs[4], outs[5], outs[6], outs[7], outs[8]); | ||
211 | return ret; | 216 | return ret; |
212 | } | 217 | } |
213 | 218 | ||
@@ -247,7 +252,7 @@ u64 hipz_h_alloc_resource_eq(const struct ipz_adapter_handle adapter_handle, | |||
247 | *eq_ist = (u32)outs[5]; | 252 | *eq_ist = (u32)outs[5]; |
248 | 253 | ||
249 | if (ret == H_NOT_ENOUGH_RESOURCES) | 254 | if (ret == H_NOT_ENOUGH_RESOURCES) |
250 | ehca_gen_err("Not enough resource - ret=%lx ", ret); | 255 | ehca_gen_err("Not enough resource - ret=%li ", ret); |
251 | 256 | ||
252 | return ret; | 257 | return ret; |
253 | } | 258 | } |
@@ -285,7 +290,7 @@ u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle, | |||
285 | hcp_galpas_ctor(&cq->galpas, outs[5], outs[6]); | 290 | hcp_galpas_ctor(&cq->galpas, outs[5], outs[6]); |
286 | 291 | ||
287 | if (ret == H_NOT_ENOUGH_RESOURCES) | 292 | if (ret == H_NOT_ENOUGH_RESOURCES) |
288 | ehca_gen_err("Not enough resources. ret=%lx", ret); | 293 | ehca_gen_err("Not enough resources. ret=%li", ret); |
289 | 294 | ||
290 | return ret; | 295 | return ret; |
291 | } | 296 | } |
@@ -360,7 +365,7 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle, | |||
360 | hcp_galpas_ctor(&parms->galpas, outs[6], outs[6]); | 365 | hcp_galpas_ctor(&parms->galpas, outs[6], outs[6]); |
361 | 366 | ||
362 | if (ret == H_NOT_ENOUGH_RESOURCES) | 367 | if (ret == H_NOT_ENOUGH_RESOURCES) |
363 | ehca_gen_err("Not enough resources. ret=%lx", ret); | 368 | ehca_gen_err("Not enough resources. ret=%li", ret); |
364 | 369 | ||
365 | return ret; | 370 | return ret; |
366 | } | 371 | } |
@@ -555,7 +560,7 @@ u64 hipz_h_modify_qp(const struct ipz_adapter_handle adapter_handle, | |||
555 | 0, 0, 0, 0, 0); | 560 | 0, 0, 0, 0, 0); |
556 | 561 | ||
557 | if (ret == H_NOT_ENOUGH_RESOURCES) | 562 | if (ret == H_NOT_ENOUGH_RESOURCES) |
558 | ehca_gen_err("Insufficient resources ret=%lx", ret); | 563 | ehca_gen_err("Insufficient resources ret=%li", ret); |
559 | 564 | ||
560 | return ret; | 565 | return ret; |
561 | } | 566 | } |
@@ -591,7 +596,7 @@ u64 hipz_h_destroy_qp(const struct ipz_adapter_handle adapter_handle, | |||
591 | qp->ipz_qp_handle.handle, /* r6 */ | 596 | qp->ipz_qp_handle.handle, /* r6 */ |
592 | 0, 0, 0, 0, 0, 0); | 597 | 0, 0, 0, 0, 0, 0); |
593 | if (ret == H_HARDWARE) | 598 | if (ret == H_HARDWARE) |
594 | ehca_gen_err("HCA not operational. ret=%lx", ret); | 599 | ehca_gen_err("HCA not operational. ret=%li", ret); |
595 | 600 | ||
596 | ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE, | 601 | ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE, |
597 | adapter_handle.handle, /* r4 */ | 602 | adapter_handle.handle, /* r4 */ |
@@ -599,7 +604,7 @@ u64 hipz_h_destroy_qp(const struct ipz_adapter_handle adapter_handle, | |||
599 | 0, 0, 0, 0, 0); | 604 | 0, 0, 0, 0, 0); |
600 | 605 | ||
601 | if (ret == H_RESOURCE) | 606 | if (ret == H_RESOURCE) |
602 | ehca_gen_err("Resource still in use. ret=%lx", ret); | 607 | ehca_gen_err("Resource still in use. ret=%li", ret); |
603 | 608 | ||
604 | return ret; | 609 | return ret; |
605 | } | 610 | } |
@@ -634,7 +639,7 @@ u64 hipz_h_define_aqp1(const struct ipz_adapter_handle adapter_handle, | |||
634 | *bma_qp_nr = (u32)outs[1]; | 639 | *bma_qp_nr = (u32)outs[1]; |
635 | 640 | ||
636 | if (ret == H_ALIAS_EXIST) | 641 | if (ret == H_ALIAS_EXIST) |
637 | ehca_gen_err("AQP1 already exists. ret=%lx", ret); | 642 | ehca_gen_err("AQP1 already exists. ret=%li", ret); |
638 | 643 | ||
639 | return ret; | 644 | return ret; |
640 | } | 645 | } |
@@ -656,7 +661,7 @@ u64 hipz_h_attach_mcqp(const struct ipz_adapter_handle adapter_handle, | |||
656 | 0, 0); | 661 | 0, 0); |
657 | 662 | ||
658 | if (ret == H_NOT_ENOUGH_RESOURCES) | 663 | if (ret == H_NOT_ENOUGH_RESOURCES) |
659 | ehca_gen_err("Not enough resources. ret=%lx", ret); | 664 | ehca_gen_err("Not enough resources. ret=%li", ret); |
660 | 665 | ||
661 | return ret; | 666 | return ret; |
662 | } | 667 | } |
@@ -695,7 +700,7 @@ u64 hipz_h_destroy_cq(const struct ipz_adapter_handle adapter_handle, | |||
695 | 0, 0, 0, 0); | 700 | 0, 0, 0, 0); |
696 | 701 | ||
697 | if (ret == H_RESOURCE) | 702 | if (ret == H_RESOURCE) |
698 | ehca_gen_err("H_FREE_RESOURCE failed ret=%lx ", ret); | 703 | ehca_gen_err("H_FREE_RESOURCE failed ret=%li ", ret); |
699 | 704 | ||
700 | return ret; | 705 | return ret; |
701 | } | 706 | } |
@@ -717,7 +722,7 @@ u64 hipz_h_destroy_eq(const struct ipz_adapter_handle adapter_handle, | |||
717 | 0, 0, 0, 0, 0); | 722 | 0, 0, 0, 0, 0); |
718 | 723 | ||
719 | if (ret == H_RESOURCE) | 724 | if (ret == H_RESOURCE) |
720 | ehca_gen_err("Resource in use. ret=%lx ", ret); | 725 | ehca_gen_err("Resource in use. ret=%li ", ret); |
721 | 726 | ||
722 | return ret; | 727 | return ret; |
723 | } | 728 | } |
@@ -816,7 +821,7 @@ u64 hipz_h_free_resource_mr(const struct ipz_adapter_handle adapter_handle, | |||
816 | return ehca_plpar_hcall_norets(H_FREE_RESOURCE, | 821 | return ehca_plpar_hcall_norets(H_FREE_RESOURCE, |
817 | adapter_handle.handle, /* r4 */ | 822 | adapter_handle.handle, /* r4 */ |
818 | mr->ipz_mr_handle.handle, /* r5 */ | 823 | mr->ipz_mr_handle.handle, /* r5 */ |
819 | 0, 0, 0, 0, 0); | 824 | 0, 0, 0, 0, 5); |
820 | } | 825 | } |
821 | 826 | ||
822 | u64 hipz_h_reregister_pmr(const struct ipz_adapter_handle adapter_handle, | 827 | u64 hipz_h_reregister_pmr(const struct ipz_adapter_handle adapter_handle, |
diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.c b/drivers/infiniband/hw/ehca/ipz_pt_fn.c index a090c679c397..661f8db62706 100644 --- a/drivers/infiniband/hw/ehca/ipz_pt_fn.c +++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.c | |||
@@ -158,6 +158,7 @@ static int alloc_small_queue_page(struct ipz_queue *queue, struct ehca_pd *pd) | |||
158 | 158 | ||
159 | queue->queue_pages[0] = (void *)(page->page | (bit << (order + 9))); | 159 | queue->queue_pages[0] = (void *)(page->page | (bit << (order + 9))); |
160 | queue->small_page = page; | 160 | queue->small_page = page; |
161 | queue->offset = bit << (order + 9); | ||
161 | return 1; | 162 | return 1; |
162 | 163 | ||
163 | out: | 164 | out: |
@@ -172,7 +173,7 @@ static void free_small_queue_page(struct ipz_queue *queue, struct ehca_pd *pd) | |||
172 | unsigned long bit; | 173 | unsigned long bit; |
173 | int free_page = 0; | 174 | int free_page = 0; |
174 | 175 | ||
175 | bit = ((unsigned long)queue->queue_pages[0] & PAGE_MASK) | 176 | bit = ((unsigned long)queue->queue_pages[0] & ~PAGE_MASK) |
176 | >> (order + 9); | 177 | >> (order + 9); |
177 | 178 | ||
178 | mutex_lock(&pd->lock); | 179 | mutex_lock(&pd->lock); |
diff --git a/drivers/infiniband/hw/ipath/ipath_common.h b/drivers/infiniband/hw/ipath/ipath_common.h index 6ad822c35930..851df8a75e79 100644 --- a/drivers/infiniband/hw/ipath/ipath_common.h +++ b/drivers/infiniband/hw/ipath/ipath_common.h | |||
@@ -189,6 +189,8 @@ typedef enum _ipath_ureg { | |||
189 | #define IPATH_RUNTIME_RCVHDR_COPY 0x8 | 189 | #define IPATH_RUNTIME_RCVHDR_COPY 0x8 |
190 | #define IPATH_RUNTIME_MASTER 0x10 | 190 | #define IPATH_RUNTIME_MASTER 0x10 |
191 | /* 0x20 and 0x40 are no longer used, but are reserved for ABI compatibility */ | 191 | /* 0x20 and 0x40 are no longer used, but are reserved for ABI compatibility */ |
192 | #define IPATH_RUNTIME_FORCE_PIOAVAIL 0x400 | ||
193 | #define IPATH_RUNTIME_PIO_REGSWAPPED 0x800 | ||
192 | 194 | ||
193 | /* | 195 | /* |
194 | * This structure is returned by ipath_userinit() immediately after | 196 | * This structure is returned by ipath_userinit() immediately after |
@@ -350,7 +352,7 @@ struct ipath_base_info { | |||
350 | * may not be implemented; the user code must deal with this if it | 352 | * may not be implemented; the user code must deal with this if it |
351 | * cares, or it must abort after initialization reports the difference. | 353 | * cares, or it must abort after initialization reports the difference. |
352 | */ | 354 | */ |
353 | #define IPATH_USER_SWMINOR 5 | 355 | #define IPATH_USER_SWMINOR 6 |
354 | 356 | ||
355 | #define IPATH_USER_SWVERSION ((IPATH_USER_SWMAJOR<<16) | IPATH_USER_SWMINOR) | 357 | #define IPATH_USER_SWVERSION ((IPATH_USER_SWMAJOR<<16) | IPATH_USER_SWMINOR) |
356 | 358 | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_cq.c b/drivers/infiniband/hw/ipath/ipath_cq.c index a6f04d27ec57..645ed71fd797 100644 --- a/drivers/infiniband/hw/ipath/ipath_cq.c +++ b/drivers/infiniband/hw/ipath/ipath_cq.c | |||
@@ -76,22 +76,25 @@ void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int solicited) | |||
76 | } | 76 | } |
77 | return; | 77 | return; |
78 | } | 78 | } |
79 | wc->queue[head].wr_id = entry->wr_id; | 79 | if (cq->ip) { |
80 | wc->queue[head].status = entry->status; | 80 | wc->uqueue[head].wr_id = entry->wr_id; |
81 | wc->queue[head].opcode = entry->opcode; | 81 | wc->uqueue[head].status = entry->status; |
82 | wc->queue[head].vendor_err = entry->vendor_err; | 82 | wc->uqueue[head].opcode = entry->opcode; |
83 | wc->queue[head].byte_len = entry->byte_len; | 83 | wc->uqueue[head].vendor_err = entry->vendor_err; |
84 | wc->queue[head].imm_data = (__u32 __force)entry->imm_data; | 84 | wc->uqueue[head].byte_len = entry->byte_len; |
85 | wc->queue[head].qp_num = entry->qp->qp_num; | 85 | wc->uqueue[head].imm_data = (__u32 __force)entry->imm_data; |
86 | wc->queue[head].src_qp = entry->src_qp; | 86 | wc->uqueue[head].qp_num = entry->qp->qp_num; |
87 | wc->queue[head].wc_flags = entry->wc_flags; | 87 | wc->uqueue[head].src_qp = entry->src_qp; |
88 | wc->queue[head].pkey_index = entry->pkey_index; | 88 | wc->uqueue[head].wc_flags = entry->wc_flags; |
89 | wc->queue[head].slid = entry->slid; | 89 | wc->uqueue[head].pkey_index = entry->pkey_index; |
90 | wc->queue[head].sl = entry->sl; | 90 | wc->uqueue[head].slid = entry->slid; |
91 | wc->queue[head].dlid_path_bits = entry->dlid_path_bits; | 91 | wc->uqueue[head].sl = entry->sl; |
92 | wc->queue[head].port_num = entry->port_num; | 92 | wc->uqueue[head].dlid_path_bits = entry->dlid_path_bits; |
93 | /* Make sure queue entry is written before the head index. */ | 93 | wc->uqueue[head].port_num = entry->port_num; |
94 | smp_wmb(); | 94 | /* Make sure entry is written before the head index. */ |
95 | smp_wmb(); | ||
96 | } else | ||
97 | wc->kqueue[head] = *entry; | ||
95 | wc->head = next; | 98 | wc->head = next; |
96 | 99 | ||
97 | if (cq->notify == IB_CQ_NEXT_COMP || | 100 | if (cq->notify == IB_CQ_NEXT_COMP || |
@@ -130,6 +133,12 @@ int ipath_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) | |||
130 | int npolled; | 133 | int npolled; |
131 | u32 tail; | 134 | u32 tail; |
132 | 135 | ||
136 | /* The kernel can only poll a kernel completion queue */ | ||
137 | if (cq->ip) { | ||
138 | npolled = -EINVAL; | ||
139 | goto bail; | ||
140 | } | ||
141 | |||
133 | spin_lock_irqsave(&cq->lock, flags); | 142 | spin_lock_irqsave(&cq->lock, flags); |
134 | 143 | ||
135 | wc = cq->queue; | 144 | wc = cq->queue; |
@@ -137,31 +146,10 @@ int ipath_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) | |||
137 | if (tail > (u32) cq->ibcq.cqe) | 146 | if (tail > (u32) cq->ibcq.cqe) |
138 | tail = (u32) cq->ibcq.cqe; | 147 | tail = (u32) cq->ibcq.cqe; |
139 | for (npolled = 0; npolled < num_entries; ++npolled, ++entry) { | 148 | for (npolled = 0; npolled < num_entries; ++npolled, ++entry) { |
140 | struct ipath_qp *qp; | ||
141 | |||
142 | if (tail == wc->head) | 149 | if (tail == wc->head) |
143 | break; | 150 | break; |
144 | /* Make sure entry is read after head index is read. */ | 151 | /* The kernel doesn't need a RMB since it has the lock. */ |
145 | smp_rmb(); | 152 | *entry = wc->kqueue[tail]; |
146 | qp = ipath_lookup_qpn(&to_idev(cq->ibcq.device)->qp_table, | ||
147 | wc->queue[tail].qp_num); | ||
148 | entry->qp = &qp->ibqp; | ||
149 | if (atomic_dec_and_test(&qp->refcount)) | ||
150 | wake_up(&qp->wait); | ||
151 | |||
152 | entry->wr_id = wc->queue[tail].wr_id; | ||
153 | entry->status = wc->queue[tail].status; | ||
154 | entry->opcode = wc->queue[tail].opcode; | ||
155 | entry->vendor_err = wc->queue[tail].vendor_err; | ||
156 | entry->byte_len = wc->queue[tail].byte_len; | ||
157 | entry->imm_data = wc->queue[tail].imm_data; | ||
158 | entry->src_qp = wc->queue[tail].src_qp; | ||
159 | entry->wc_flags = wc->queue[tail].wc_flags; | ||
160 | entry->pkey_index = wc->queue[tail].pkey_index; | ||
161 | entry->slid = wc->queue[tail].slid; | ||
162 | entry->sl = wc->queue[tail].sl; | ||
163 | entry->dlid_path_bits = wc->queue[tail].dlid_path_bits; | ||
164 | entry->port_num = wc->queue[tail].port_num; | ||
165 | if (tail >= cq->ibcq.cqe) | 153 | if (tail >= cq->ibcq.cqe) |
166 | tail = 0; | 154 | tail = 0; |
167 | else | 155 | else |
@@ -171,6 +159,7 @@ int ipath_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) | |||
171 | 159 | ||
172 | spin_unlock_irqrestore(&cq->lock, flags); | 160 | spin_unlock_irqrestore(&cq->lock, flags); |
173 | 161 | ||
162 | bail: | ||
174 | return npolled; | 163 | return npolled; |
175 | } | 164 | } |
176 | 165 | ||
@@ -215,6 +204,7 @@ struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, int comp_vec | |||
215 | struct ipath_cq *cq; | 204 | struct ipath_cq *cq; |
216 | struct ipath_cq_wc *wc; | 205 | struct ipath_cq_wc *wc; |
217 | struct ib_cq *ret; | 206 | struct ib_cq *ret; |
207 | u32 sz; | ||
218 | 208 | ||
219 | if (entries < 1 || entries > ib_ipath_max_cqes) { | 209 | if (entries < 1 || entries > ib_ipath_max_cqes) { |
220 | ret = ERR_PTR(-EINVAL); | 210 | ret = ERR_PTR(-EINVAL); |
@@ -235,7 +225,12 @@ struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, int comp_vec | |||
235 | * We need to use vmalloc() in order to support mmap and large | 225 | * We need to use vmalloc() in order to support mmap and large |
236 | * numbers of entries. | 226 | * numbers of entries. |
237 | */ | 227 | */ |
238 | wc = vmalloc_user(sizeof(*wc) + sizeof(struct ib_wc) * entries); | 228 | sz = sizeof(*wc); |
229 | if (udata && udata->outlen >= sizeof(__u64)) | ||
230 | sz += sizeof(struct ib_uverbs_wc) * (entries + 1); | ||
231 | else | ||
232 | sz += sizeof(struct ib_wc) * (entries + 1); | ||
233 | wc = vmalloc_user(sz); | ||
239 | if (!wc) { | 234 | if (!wc) { |
240 | ret = ERR_PTR(-ENOMEM); | 235 | ret = ERR_PTR(-ENOMEM); |
241 | goto bail_cq; | 236 | goto bail_cq; |
@@ -247,9 +242,8 @@ struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, int comp_vec | |||
247 | */ | 242 | */ |
248 | if (udata && udata->outlen >= sizeof(__u64)) { | 243 | if (udata && udata->outlen >= sizeof(__u64)) { |
249 | int err; | 244 | int err; |
250 | u32 s = sizeof *wc + sizeof(struct ib_wc) * entries; | ||
251 | 245 | ||
252 | cq->ip = ipath_create_mmap_info(dev, s, context, wc); | 246 | cq->ip = ipath_create_mmap_info(dev, sz, context, wc); |
253 | if (!cq->ip) { | 247 | if (!cq->ip) { |
254 | ret = ERR_PTR(-ENOMEM); | 248 | ret = ERR_PTR(-ENOMEM); |
255 | goto bail_wc; | 249 | goto bail_wc; |
@@ -380,6 +374,7 @@ int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata) | |||
380 | struct ipath_cq_wc *wc; | 374 | struct ipath_cq_wc *wc; |
381 | u32 head, tail, n; | 375 | u32 head, tail, n; |
382 | int ret; | 376 | int ret; |
377 | u32 sz; | ||
383 | 378 | ||
384 | if (cqe < 1 || cqe > ib_ipath_max_cqes) { | 379 | if (cqe < 1 || cqe > ib_ipath_max_cqes) { |
385 | ret = -EINVAL; | 380 | ret = -EINVAL; |
@@ -389,7 +384,12 @@ int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata) | |||
389 | /* | 384 | /* |
390 | * Need to use vmalloc() if we want to support large #s of entries. | 385 | * Need to use vmalloc() if we want to support large #s of entries. |
391 | */ | 386 | */ |
392 | wc = vmalloc_user(sizeof(*wc) + sizeof(struct ib_wc) * cqe); | 387 | sz = sizeof(*wc); |
388 | if (udata && udata->outlen >= sizeof(__u64)) | ||
389 | sz += sizeof(struct ib_uverbs_wc) * (cqe + 1); | ||
390 | else | ||
391 | sz += sizeof(struct ib_wc) * (cqe + 1); | ||
392 | wc = vmalloc_user(sz); | ||
393 | if (!wc) { | 393 | if (!wc) { |
394 | ret = -ENOMEM; | 394 | ret = -ENOMEM; |
395 | goto bail; | 395 | goto bail; |
@@ -430,7 +430,10 @@ int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata) | |||
430 | goto bail; | 430 | goto bail; |
431 | } | 431 | } |
432 | for (n = 0; tail != head; n++) { | 432 | for (n = 0; tail != head; n++) { |
433 | wc->queue[n] = old_wc->queue[tail]; | 433 | if (cq->ip) |
434 | wc->uqueue[n] = old_wc->uqueue[tail]; | ||
435 | else | ||
436 | wc->kqueue[n] = old_wc->kqueue[tail]; | ||
434 | if (tail == (u32) cq->ibcq.cqe) | 437 | if (tail == (u32) cq->ibcq.cqe) |
435 | tail = 0; | 438 | tail = 0; |
436 | else | 439 | else |
@@ -447,9 +450,8 @@ int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata) | |||
447 | if (cq->ip) { | 450 | if (cq->ip) { |
448 | struct ipath_ibdev *dev = to_idev(ibcq->device); | 451 | struct ipath_ibdev *dev = to_idev(ibcq->device); |
449 | struct ipath_mmap_info *ip = cq->ip; | 452 | struct ipath_mmap_info *ip = cq->ip; |
450 | u32 s = sizeof *wc + sizeof(struct ib_wc) * cqe; | ||
451 | 453 | ||
452 | ipath_update_mmap_info(dev, ip, s, wc); | 454 | ipath_update_mmap_info(dev, ip, sz, wc); |
453 | spin_lock_irq(&dev->pending_lock); | 455 | spin_lock_irq(&dev->pending_lock); |
454 | if (list_empty(&ip->pending_mmaps)) | 456 | if (list_empty(&ip->pending_mmaps)) |
455 | list_add(&ip->pending_mmaps, &dev->pending_mmaps); | 457 | list_add(&ip->pending_mmaps, &dev->pending_mmaps); |
diff --git a/drivers/infiniband/hw/ipath/ipath_diag.c b/drivers/infiniband/hw/ipath/ipath_diag.c index cf25cdab02f9..4137c7770f1b 100644 --- a/drivers/infiniband/hw/ipath/ipath_diag.c +++ b/drivers/infiniband/hw/ipath/ipath_diag.c | |||
@@ -446,19 +446,21 @@ static ssize_t ipath_diagpkt_write(struct file *fp, | |||
446 | dd->ipath_unit, plen - 1, pbufn); | 446 | dd->ipath_unit, plen - 1, pbufn); |
447 | 447 | ||
448 | if (dp.pbc_wd == 0) | 448 | if (dp.pbc_wd == 0) |
449 | /* Legacy operation, use computed pbc_wd */ | ||
450 | dp.pbc_wd = plen; | 449 | dp.pbc_wd = plen; |
451 | |||
452 | /* we have to flush after the PBC for correctness on some cpus | ||
453 | * or WC buffer can be written out of order */ | ||
454 | writeq(dp.pbc_wd, piobuf); | 450 | writeq(dp.pbc_wd, piobuf); |
455 | ipath_flush_wc(); | 451 | /* |
456 | /* copy all by the trigger word, then flush, so it's written | 452 | * Copy all by the trigger word, then flush, so it's written |
457 | * to chip before trigger word, then write trigger word, then | 453 | * to chip before trigger word, then write trigger word, then |
458 | * flush again, so packet is sent. */ | 454 | * flush again, so packet is sent. |
459 | __iowrite32_copy(piobuf + 2, tmpbuf, clen - 1); | 455 | */ |
460 | ipath_flush_wc(); | 456 | if (dd->ipath_flags & IPATH_PIO_FLUSH_WC) { |
461 | __raw_writel(tmpbuf[clen - 1], piobuf + clen + 1); | 457 | ipath_flush_wc(); |
458 | __iowrite32_copy(piobuf + 2, tmpbuf, clen - 1); | ||
459 | ipath_flush_wc(); | ||
460 | __raw_writel(tmpbuf[clen - 1], piobuf + clen + 1); | ||
461 | } else | ||
462 | __iowrite32_copy(piobuf + 2, tmpbuf, clen); | ||
463 | |||
462 | ipath_flush_wc(); | 464 | ipath_flush_wc(); |
463 | 465 | ||
464 | ret = sizeof(dp); | 466 | ret = sizeof(dp); |
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index 6ccba365a24c..1f152ded1e3c 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/spinlock.h> | 34 | #include <linux/spinlock.h> |
35 | #include <linux/idr.h> | 35 | #include <linux/idr.h> |
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | #include <linux/io.h> | ||
37 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
38 | #include <linux/netdevice.h> | 39 | #include <linux/netdevice.h> |
39 | #include <linux/vmalloc.h> | 40 | #include <linux/vmalloc.h> |
@@ -280,6 +281,89 @@ void __attribute__((weak)) ipath_disable_wc(struct ipath_devdata *dd) | |||
280 | { | 281 | { |
281 | } | 282 | } |
282 | 283 | ||
284 | /* | ||
285 | * Perform a PIO buffer bandwidth write test, to verify proper system | ||
286 | * configuration. Even when all the setup calls work, occasionally | ||
287 | * BIOS or other issues can prevent write combining from working, or | ||
288 | * can cause other bandwidth problems to the chip. | ||
289 | * | ||
290 | * This test simply writes the same buffer over and over again, and | ||
291 | * measures close to the peak bandwidth to the chip (not testing | ||
292 | * data bandwidth to the wire). On chips that use an address-based | ||
293 | * trigger to send packets to the wire, this is easy. On chips that | ||
294 | * use a count to trigger, we want to make sure that the packet doesn't | ||
295 | * go out on the wire, or trigger flow control checks. | ||
296 | */ | ||
297 | static void ipath_verify_pioperf(struct ipath_devdata *dd) | ||
298 | { | ||
299 | u32 pbnum, cnt, lcnt; | ||
300 | u32 __iomem *piobuf; | ||
301 | u32 *addr; | ||
302 | u64 msecs, emsecs; | ||
303 | |||
304 | piobuf = ipath_getpiobuf(dd, &pbnum); | ||
305 | if (!piobuf) { | ||
306 | dev_info(&dd->pcidev->dev, | ||
307 | "No PIObufs for checking perf, skipping\n"); | ||
308 | return; | ||
309 | } | ||
310 | |||
311 | /* | ||
312 | * Enough to give us a reasonable test, less than piobuf size, and | ||
313 | * likely multiple of store buffer length. | ||
314 | */ | ||
315 | cnt = 1024; | ||
316 | |||
317 | addr = vmalloc(cnt); | ||
318 | if (!addr) { | ||
319 | dev_info(&dd->pcidev->dev, | ||
320 | "Couldn't get memory for checking PIO perf," | ||
321 | " skipping\n"); | ||
322 | goto done; | ||
323 | } | ||
324 | |||
325 | preempt_disable(); /* we want reasonably accurate elapsed time */ | ||
326 | msecs = 1 + jiffies_to_msecs(jiffies); | ||
327 | for (lcnt = 0; lcnt < 10000U; lcnt++) { | ||
328 | /* wait until we cross msec boundary */ | ||
329 | if (jiffies_to_msecs(jiffies) >= msecs) | ||
330 | break; | ||
331 | udelay(1); | ||
332 | } | ||
333 | |||
334 | writeq(0, piobuf); /* length 0, no dwords actually sent */ | ||
335 | ipath_flush_wc(); | ||
336 | |||
337 | /* | ||
338 | * this is only roughly accurate, since even with preempt we | ||
339 | * still take interrupts that could take a while. Running for | ||
340 | * >= 5 msec seems to get us "close enough" to accurate values | ||
341 | */ | ||
342 | msecs = jiffies_to_msecs(jiffies); | ||
343 | for (emsecs = lcnt = 0; emsecs <= 5UL; lcnt++) { | ||
344 | __iowrite32_copy(piobuf + 64, addr, cnt >> 2); | ||
345 | emsecs = jiffies_to_msecs(jiffies) - msecs; | ||
346 | } | ||
347 | |||
348 | /* 1 GiB/sec, slightly over IB SDR line rate */ | ||
349 | if (lcnt < (emsecs * 1024U)) | ||
350 | ipath_dev_err(dd, | ||
351 | "Performance problem: bandwidth to PIO buffers is " | ||
352 | "only %u MiB/sec\n", | ||
353 | lcnt / (u32) emsecs); | ||
354 | else | ||
355 | ipath_dbg("PIO buffer bandwidth %u MiB/sec is OK\n", | ||
356 | lcnt / (u32) emsecs); | ||
357 | |||
358 | preempt_enable(); | ||
359 | |||
360 | vfree(addr); | ||
361 | |||
362 | done: | ||
363 | /* disarm piobuf, so it's available again */ | ||
364 | ipath_disarm_piobufs(dd, pbnum, 1); | ||
365 | } | ||
366 | |||
283 | static int __devinit ipath_init_one(struct pci_dev *pdev, | 367 | static int __devinit ipath_init_one(struct pci_dev *pdev, |
284 | const struct pci_device_id *ent) | 368 | const struct pci_device_id *ent) |
285 | { | 369 | { |
@@ -298,8 +382,6 @@ static int __devinit ipath_init_one(struct pci_dev *pdev, | |||
298 | 382 | ||
299 | ipath_cdbg(VERBOSE, "initializing unit #%u\n", dd->ipath_unit); | 383 | ipath_cdbg(VERBOSE, "initializing unit #%u\n", dd->ipath_unit); |
300 | 384 | ||
301 | read_bars(dd, pdev, &bar0, &bar1); | ||
302 | |||
303 | ret = pci_enable_device(pdev); | 385 | ret = pci_enable_device(pdev); |
304 | if (ret) { | 386 | if (ret) { |
305 | /* This can happen iff: | 387 | /* This can happen iff: |
@@ -445,9 +527,6 @@ static int __devinit ipath_init_one(struct pci_dev *pdev, | |||
445 | goto bail_regions; | 527 | goto bail_regions; |
446 | } | 528 | } |
447 | 529 | ||
448 | dd->ipath_deviceid = ent->device; /* save for later use */ | ||
449 | dd->ipath_vendorid = ent->vendor; | ||
450 | |||
451 | dd->ipath_pcirev = pdev->revision; | 530 | dd->ipath_pcirev = pdev->revision; |
452 | 531 | ||
453 | #if defined(__powerpc__) | 532 | #if defined(__powerpc__) |
@@ -515,6 +594,8 @@ static int __devinit ipath_init_one(struct pci_dev *pdev, | |||
515 | ret = 0; | 594 | ret = 0; |
516 | } | 595 | } |
517 | 596 | ||
597 | ipath_verify_pioperf(dd); | ||
598 | |||
518 | ipath_device_create_group(&pdev->dev, dd); | 599 | ipath_device_create_group(&pdev->dev, dd); |
519 | ipathfs_add_device(dd); | 600 | ipathfs_add_device(dd); |
520 | ipath_user_add(dd); | 601 | ipath_user_add(dd); |
@@ -2005,6 +2086,8 @@ void ipath_shutdown_device(struct ipath_devdata *dd) | |||
2005 | INFINIPATH_IBCC_LINKINITCMD_SHIFT); | 2086 | INFINIPATH_IBCC_LINKINITCMD_SHIFT); |
2006 | ipath_cancel_sends(dd, 0); | 2087 | ipath_cancel_sends(dd, 0); |
2007 | 2088 | ||
2089 | signal_ib_event(dd, IB_EVENT_PORT_ERR); | ||
2090 | |||
2008 | /* disable IBC */ | 2091 | /* disable IBC */ |
2009 | dd->ipath_control &= ~INFINIPATH_C_LINKENABLE; | 2092 | dd->ipath_control &= ~INFINIPATH_C_LINKENABLE; |
2010 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, | 2093 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, |
diff --git a/drivers/infiniband/hw/ipath/ipath_eeprom.c b/drivers/infiniband/hw/ipath/ipath_eeprom.c index b4503e9c1e95..bcfa3ccb555f 100644 --- a/drivers/infiniband/hw/ipath/ipath_eeprom.c +++ b/drivers/infiniband/hw/ipath/ipath_eeprom.c | |||
@@ -596,7 +596,11 @@ void ipath_get_eeprom_info(struct ipath_devdata *dd) | |||
596 | goto bail; | 596 | goto bail; |
597 | } | 597 | } |
598 | 598 | ||
599 | len = offsetof(struct ipath_flash, if_future); | 599 | /* |
600 | * read full flash, not just currently used part, since it may have | ||
601 | * been written with a newer definition | ||
602 | * */ | ||
603 | len = sizeof(struct ipath_flash); | ||
600 | buf = vmalloc(len); | 604 | buf = vmalloc(len); |
601 | if (!buf) { | 605 | if (!buf) { |
602 | ipath_dev_err(dd, "Couldn't allocate memory to read %u " | 606 | ipath_dev_err(dd, "Couldn't allocate memory to read %u " |
@@ -737,8 +741,10 @@ int ipath_update_eeprom_log(struct ipath_devdata *dd) | |||
737 | /* | 741 | /* |
738 | * The quick-check above determined that there is something worthy | 742 | * The quick-check above determined that there is something worthy |
739 | * of logging, so get current contents and do a more detailed idea. | 743 | * of logging, so get current contents and do a more detailed idea. |
744 | * read full flash, not just currently used part, since it may have | ||
745 | * been written with a newer definition | ||
740 | */ | 746 | */ |
741 | len = offsetof(struct ipath_flash, if_future); | 747 | len = sizeof(struct ipath_flash); |
742 | buf = vmalloc(len); | 748 | buf = vmalloc(len); |
743 | ret = 1; | 749 | ret = 1; |
744 | if (!buf) { | 750 | if (!buf) { |
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c index 33ab0d6b80ff..5de3243a47c3 100644 --- a/drivers/infiniband/hw/ipath/ipath_file_ops.c +++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c | |||
@@ -538,6 +538,9 @@ static int ipath_tid_free(struct ipath_portdata *pd, unsigned subport, | |||
538 | continue; | 538 | continue; |
539 | cnt++; | 539 | cnt++; |
540 | if (dd->ipath_pageshadow[porttid + tid]) { | 540 | if (dd->ipath_pageshadow[porttid + tid]) { |
541 | struct page *p; | ||
542 | p = dd->ipath_pageshadow[porttid + tid]; | ||
543 | dd->ipath_pageshadow[porttid + tid] = NULL; | ||
541 | ipath_cdbg(VERBOSE, "PID %u freeing TID %u\n", | 544 | ipath_cdbg(VERBOSE, "PID %u freeing TID %u\n", |
542 | pd->port_pid, tid); | 545 | pd->port_pid, tid); |
543 | dd->ipath_f_put_tid(dd, &tidbase[tid], | 546 | dd->ipath_f_put_tid(dd, &tidbase[tid], |
@@ -546,9 +549,7 @@ static int ipath_tid_free(struct ipath_portdata *pd, unsigned subport, | |||
546 | pci_unmap_page(dd->pcidev, | 549 | pci_unmap_page(dd->pcidev, |
547 | dd->ipath_physshadow[porttid + tid], | 550 | dd->ipath_physshadow[porttid + tid], |
548 | PAGE_SIZE, PCI_DMA_FROMDEVICE); | 551 | PAGE_SIZE, PCI_DMA_FROMDEVICE); |
549 | ipath_release_user_pages( | 552 | ipath_release_user_pages(&p, 1); |
550 | &dd->ipath_pageshadow[porttid + tid], 1); | ||
551 | dd->ipath_pageshadow[porttid + tid] = NULL; | ||
552 | ipath_stats.sps_pageunlocks++; | 553 | ipath_stats.sps_pageunlocks++; |
553 | } else | 554 | } else |
554 | ipath_dbg("Unused tid %u, ignoring\n", tid); | 555 | ipath_dbg("Unused tid %u, ignoring\n", tid); |
@@ -1341,6 +1342,19 @@ bail: | |||
1341 | return ret; | 1342 | return ret; |
1342 | } | 1343 | } |
1343 | 1344 | ||
1345 | static unsigned ipath_poll_hdrqfull(struct ipath_portdata *pd) | ||
1346 | { | ||
1347 | unsigned pollflag = 0; | ||
1348 | |||
1349 | if ((pd->poll_type & IPATH_POLL_TYPE_OVERFLOW) && | ||
1350 | pd->port_hdrqfull != pd->port_hdrqfull_poll) { | ||
1351 | pollflag |= POLLIN | POLLRDNORM; | ||
1352 | pd->port_hdrqfull_poll = pd->port_hdrqfull; | ||
1353 | } | ||
1354 | |||
1355 | return pollflag; | ||
1356 | } | ||
1357 | |||
1344 | static unsigned int ipath_poll_urgent(struct ipath_portdata *pd, | 1358 | static unsigned int ipath_poll_urgent(struct ipath_portdata *pd, |
1345 | struct file *fp, | 1359 | struct file *fp, |
1346 | struct poll_table_struct *pt) | 1360 | struct poll_table_struct *pt) |
@@ -1350,22 +1364,20 @@ static unsigned int ipath_poll_urgent(struct ipath_portdata *pd, | |||
1350 | 1364 | ||
1351 | dd = pd->port_dd; | 1365 | dd = pd->port_dd; |
1352 | 1366 | ||
1353 | if (test_bit(IPATH_PORT_WAITING_OVERFLOW, &pd->int_flag)) { | 1367 | /* variable access in ipath_poll_hdrqfull() needs this */ |
1354 | pollflag |= POLLERR; | 1368 | rmb(); |
1355 | clear_bit(IPATH_PORT_WAITING_OVERFLOW, &pd->int_flag); | 1369 | pollflag = ipath_poll_hdrqfull(pd); |
1356 | } | ||
1357 | 1370 | ||
1358 | if (test_bit(IPATH_PORT_WAITING_URG, &pd->int_flag)) { | 1371 | if (pd->port_urgent != pd->port_urgent_poll) { |
1359 | pollflag |= POLLIN | POLLRDNORM; | 1372 | pollflag |= POLLIN | POLLRDNORM; |
1360 | clear_bit(IPATH_PORT_WAITING_URG, &pd->int_flag); | 1373 | pd->port_urgent_poll = pd->port_urgent; |
1361 | } | 1374 | } |
1362 | 1375 | ||
1363 | if (!pollflag) { | 1376 | if (!pollflag) { |
1377 | /* this saves a spin_lock/unlock in interrupt handler... */ | ||
1364 | set_bit(IPATH_PORT_WAITING_URG, &pd->port_flag); | 1378 | set_bit(IPATH_PORT_WAITING_URG, &pd->port_flag); |
1365 | if (pd->poll_type & IPATH_POLL_TYPE_OVERFLOW) | 1379 | /* flush waiting flag so don't miss an event... */ |
1366 | set_bit(IPATH_PORT_WAITING_OVERFLOW, | 1380 | wmb(); |
1367 | &pd->port_flag); | ||
1368 | |||
1369 | poll_wait(fp, &pd->port_wait, pt); | 1381 | poll_wait(fp, &pd->port_wait, pt); |
1370 | } | 1382 | } |
1371 | 1383 | ||
@@ -1376,31 +1388,27 @@ static unsigned int ipath_poll_next(struct ipath_portdata *pd, | |||
1376 | struct file *fp, | 1388 | struct file *fp, |
1377 | struct poll_table_struct *pt) | 1389 | struct poll_table_struct *pt) |
1378 | { | 1390 | { |
1379 | u32 head, tail; | 1391 | u32 head; |
1392 | u32 tail; | ||
1380 | unsigned pollflag = 0; | 1393 | unsigned pollflag = 0; |
1381 | struct ipath_devdata *dd; | 1394 | struct ipath_devdata *dd; |
1382 | 1395 | ||
1383 | dd = pd->port_dd; | 1396 | dd = pd->port_dd; |
1384 | 1397 | ||
1398 | /* variable access in ipath_poll_hdrqfull() needs this */ | ||
1399 | rmb(); | ||
1400 | pollflag = ipath_poll_hdrqfull(pd); | ||
1401 | |||
1385 | head = ipath_read_ureg32(dd, ur_rcvhdrhead, pd->port_port); | 1402 | head = ipath_read_ureg32(dd, ur_rcvhdrhead, pd->port_port); |
1386 | tail = *(volatile u64 *)pd->port_rcvhdrtail_kvaddr; | 1403 | tail = *(volatile u64 *)pd->port_rcvhdrtail_kvaddr; |
1387 | 1404 | ||
1388 | if (test_bit(IPATH_PORT_WAITING_OVERFLOW, &pd->int_flag)) { | 1405 | if (head != tail) |
1389 | pollflag |= POLLERR; | ||
1390 | clear_bit(IPATH_PORT_WAITING_OVERFLOW, &pd->int_flag); | ||
1391 | } | ||
1392 | |||
1393 | if (tail != head || | ||
1394 | test_bit(IPATH_PORT_WAITING_RCV, &pd->int_flag)) { | ||
1395 | pollflag |= POLLIN | POLLRDNORM; | 1406 | pollflag |= POLLIN | POLLRDNORM; |
1396 | clear_bit(IPATH_PORT_WAITING_RCV, &pd->int_flag); | 1407 | else { |
1397 | } | 1408 | /* this saves a spin_lock/unlock in interrupt handler */ |
1398 | |||
1399 | if (!pollflag) { | ||
1400 | set_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag); | 1409 | set_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag); |
1401 | if (pd->poll_type & IPATH_POLL_TYPE_OVERFLOW) | 1410 | /* flush waiting flag so we don't miss an event */ |
1402 | set_bit(IPATH_PORT_WAITING_OVERFLOW, | 1411 | wmb(); |
1403 | &pd->port_flag); | ||
1404 | 1412 | ||
1405 | set_bit(pd->port_port + INFINIPATH_R_INTRAVAIL_SHIFT, | 1413 | set_bit(pd->port_port + INFINIPATH_R_INTRAVAIL_SHIFT, |
1406 | &dd->ipath_rcvctrl); | 1414 | &dd->ipath_rcvctrl); |
@@ -1917,6 +1925,12 @@ static int ipath_do_user_init(struct file *fp, | |||
1917 | ipath_cdbg(VERBOSE, "Wrote port%d egrhead %x from tail regs\n", | 1925 | ipath_cdbg(VERBOSE, "Wrote port%d egrhead %x from tail regs\n", |
1918 | pd->port_port, head32); | 1926 | pd->port_port, head32); |
1919 | pd->port_tidcursor = 0; /* start at beginning after open */ | 1927 | pd->port_tidcursor = 0; /* start at beginning after open */ |
1928 | |||
1929 | /* initialize poll variables... */ | ||
1930 | pd->port_urgent = 0; | ||
1931 | pd->port_urgent_poll = 0; | ||
1932 | pd->port_hdrqfull_poll = pd->port_hdrqfull; | ||
1933 | |||
1920 | /* | 1934 | /* |
1921 | * now enable the port; the tail registers will be written to memory | 1935 | * now enable the port; the tail registers will be written to memory |
1922 | * by the chip as soon as it sees the write to | 1936 | * by the chip as soon as it sees the write to |
@@ -2039,9 +2053,11 @@ static int ipath_close(struct inode *in, struct file *fp) | |||
2039 | 2053 | ||
2040 | if (dd->ipath_kregbase) { | 2054 | if (dd->ipath_kregbase) { |
2041 | int i; | 2055 | int i; |
2042 | /* atomically clear receive enable port. */ | 2056 | /* atomically clear receive enable port and intr avail. */ |
2043 | clear_bit(INFINIPATH_R_PORTENABLE_SHIFT + port, | 2057 | clear_bit(INFINIPATH_R_PORTENABLE_SHIFT + port, |
2044 | &dd->ipath_rcvctrl); | 2058 | &dd->ipath_rcvctrl); |
2059 | clear_bit(pd->port_port + INFINIPATH_R_INTRAVAIL_SHIFT, | ||
2060 | &dd->ipath_rcvctrl); | ||
2045 | ipath_write_kreg( dd, dd->ipath_kregs->kr_rcvctrl, | 2061 | ipath_write_kreg( dd, dd->ipath_kregs->kr_rcvctrl, |
2046 | dd->ipath_rcvctrl); | 2062 | dd->ipath_rcvctrl); |
2047 | /* and read back from chip to be sure that nothing | 2063 | /* and read back from chip to be sure that nothing |
diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c index 2e689b974e1f..262c25db05cd 100644 --- a/drivers/infiniband/hw/ipath/ipath_fs.c +++ b/drivers/infiniband/hw/ipath/ipath_fs.c | |||
@@ -130,175 +130,6 @@ static const struct file_operations atomic_counters_ops = { | |||
130 | .read = atomic_counters_read, | 130 | .read = atomic_counters_read, |
131 | }; | 131 | }; |
132 | 132 | ||
133 | static ssize_t atomic_node_info_read(struct file *file, char __user *buf, | ||
134 | size_t count, loff_t *ppos) | ||
135 | { | ||
136 | u32 nodeinfo[10]; | ||
137 | struct ipath_devdata *dd; | ||
138 | u64 guid; | ||
139 | |||
140 | dd = file->f_path.dentry->d_inode->i_private; | ||
141 | |||
142 | guid = be64_to_cpu(dd->ipath_guid); | ||
143 | |||
144 | nodeinfo[0] = /* BaseVersion is SMA */ | ||
145 | /* ClassVersion is SMA */ | ||
146 | (1 << 8) /* NodeType */ | ||
147 | | (1 << 0); /* NumPorts */ | ||
148 | nodeinfo[1] = (u32) (guid >> 32); | ||
149 | nodeinfo[2] = (u32) (guid & 0xffffffff); | ||
150 | /* PortGUID == SystemImageGUID for us */ | ||
151 | nodeinfo[3] = nodeinfo[1]; | ||
152 | /* PortGUID == SystemImageGUID for us */ | ||
153 | nodeinfo[4] = nodeinfo[2]; | ||
154 | /* PortGUID == NodeGUID for us */ | ||
155 | nodeinfo[5] = nodeinfo[3]; | ||
156 | /* PortGUID == NodeGUID for us */ | ||
157 | nodeinfo[6] = nodeinfo[4]; | ||
158 | nodeinfo[7] = (4 << 16) /* we support 4 pkeys */ | ||
159 | | (dd->ipath_deviceid << 0); | ||
160 | /* our chip version as 16 bits major, 16 bits minor */ | ||
161 | nodeinfo[8] = dd->ipath_minrev | (dd->ipath_majrev << 16); | ||
162 | nodeinfo[9] = (dd->ipath_unit << 24) | (dd->ipath_vendorid << 0); | ||
163 | |||
164 | return simple_read_from_buffer(buf, count, ppos, nodeinfo, | ||
165 | sizeof nodeinfo); | ||
166 | } | ||
167 | |||
168 | static const struct file_operations atomic_node_info_ops = { | ||
169 | .read = atomic_node_info_read, | ||
170 | }; | ||
171 | |||
172 | static ssize_t atomic_port_info_read(struct file *file, char __user *buf, | ||
173 | size_t count, loff_t *ppos) | ||
174 | { | ||
175 | u32 portinfo[13]; | ||
176 | u32 tmp, tmp2; | ||
177 | struct ipath_devdata *dd; | ||
178 | |||
179 | dd = file->f_path.dentry->d_inode->i_private; | ||
180 | |||
181 | /* so we only initialize non-zero fields. */ | ||
182 | memset(portinfo, 0, sizeof portinfo); | ||
183 | |||
184 | /* | ||
185 | * Notimpl yet M_Key (64) | ||
186 | * Notimpl yet GID (64) | ||
187 | */ | ||
188 | |||
189 | portinfo[4] = (dd->ipath_lid << 16); | ||
190 | |||
191 | /* | ||
192 | * Notimpl yet SMLID. | ||
193 | * CapabilityMask is 0, we don't support any of these | ||
194 | * DiagCode is 0; we don't store any diag info for now Notimpl yet | ||
195 | * M_KeyLeasePeriod (we don't support M_Key) | ||
196 | */ | ||
197 | |||
198 | /* LocalPortNum is whichever port number they ask for */ | ||
199 | portinfo[7] = (dd->ipath_unit << 24) | ||
200 | /* LinkWidthEnabled */ | ||
201 | | (2 << 16) | ||
202 | /* LinkWidthSupported (really 2, but not IB valid) */ | ||
203 | | (3 << 8) | ||
204 | /* LinkWidthActive */ | ||
205 | | (2 << 0); | ||
206 | tmp = dd->ipath_lastibcstat & IPATH_IBSTATE_MASK; | ||
207 | tmp2 = 5; | ||
208 | if (tmp == IPATH_IBSTATE_INIT) | ||
209 | tmp = 2; | ||
210 | else if (tmp == IPATH_IBSTATE_ARM) | ||
211 | tmp = 3; | ||
212 | else if (tmp == IPATH_IBSTATE_ACTIVE) | ||
213 | tmp = 4; | ||
214 | else { | ||
215 | tmp = 0; /* down */ | ||
216 | tmp2 = tmp & 0xf; | ||
217 | } | ||
218 | |||
219 | portinfo[8] = (1 << 28) /* LinkSpeedSupported */ | ||
220 | | (tmp << 24) /* PortState */ | ||
221 | | (tmp2 << 20) /* PortPhysicalState */ | ||
222 | | (2 << 16) | ||
223 | |||
224 | /* LinkDownDefaultState */ | ||
225 | /* M_KeyProtectBits == 0 */ | ||
226 | /* NotImpl yet LMC == 0 (we can support all values) */ | ||
227 | | (1 << 4) /* LinkSpeedActive */ | ||
228 | | (1 << 0); /* LinkSpeedEnabled */ | ||
229 | switch (dd->ipath_ibmtu) { | ||
230 | case 4096: | ||
231 | tmp = 5; | ||
232 | break; | ||
233 | case 2048: | ||
234 | tmp = 4; | ||
235 | break; | ||
236 | case 1024: | ||
237 | tmp = 3; | ||
238 | break; | ||
239 | case 512: | ||
240 | tmp = 2; | ||
241 | break; | ||
242 | case 256: | ||
243 | tmp = 1; | ||
244 | break; | ||
245 | default: /* oops, something is wrong */ | ||
246 | ipath_dbg("Problem, ipath_ibmtu 0x%x not a valid IB MTU, " | ||
247 | "treat as 2048\n", dd->ipath_ibmtu); | ||
248 | tmp = 4; | ||
249 | break; | ||
250 | } | ||
251 | portinfo[9] = (tmp << 28) | ||
252 | /* NeighborMTU */ | ||
253 | /* Notimpl MasterSMSL */ | ||
254 | | (1 << 20) | ||
255 | |||
256 | /* VLCap */ | ||
257 | /* Notimpl InitType (actually, an SMA decision) */ | ||
258 | /* VLHighLimit is 0 (only one VL) */ | ||
259 | ; /* VLArbitrationHighCap is 0 (only one VL) */ | ||
260 | /* | ||
261 | * Note: the chips support a maximum MTU of 4096, but the driver | ||
262 | * hasn't implemented this feature yet, so set the maximum | ||
263 | * to 2048. | ||
264 | */ | ||
265 | portinfo[10] = /* VLArbitrationLowCap is 0 (only one VL) */ | ||
266 | /* InitTypeReply is SMA decision */ | ||
267 | (4 << 16) /* MTUCap 2048 */ | ||
268 | | (7 << 13) /* VLStallCount */ | ||
269 | | (0x1f << 8) /* HOQLife */ | ||
270 | | (1 << 4) | ||
271 | |||
272 | /* OperationalVLs 0 */ | ||
273 | /* PartitionEnforcementInbound */ | ||
274 | /* PartitionEnforcementOutbound not enforced */ | ||
275 | /* FilterRawinbound not enforced */ | ||
276 | ; /* FilterRawOutbound not enforced */ | ||
277 | /* M_KeyViolations are not counted by hardware, SMA can count */ | ||
278 | tmp = ipath_read_creg32(dd, dd->ipath_cregs->cr_errpkey); | ||
279 | /* P_KeyViolations are counted by hardware. */ | ||
280 | portinfo[11] = ((tmp & 0xffff) << 0); | ||
281 | portinfo[12] = | ||
282 | /* Q_KeyViolations are not counted by hardware */ | ||
283 | (1 << 8) | ||
284 | |||
285 | /* GUIDCap */ | ||
286 | /* SubnetTimeOut handled by SMA */ | ||
287 | /* RespTimeValue handled by SMA */ | ||
288 | ; | ||
289 | /* LocalPhyErrors are programmed to max */ | ||
290 | portinfo[12] |= (0xf << 20) | ||
291 | | (0xf << 16) /* OverRunErrors are programmed to max */ | ||
292 | ; | ||
293 | |||
294 | return simple_read_from_buffer(buf, count, ppos, portinfo, | ||
295 | sizeof portinfo); | ||
296 | } | ||
297 | |||
298 | static const struct file_operations atomic_port_info_ops = { | ||
299 | .read = atomic_port_info_read, | ||
300 | }; | ||
301 | |||
302 | static ssize_t flash_read(struct file *file, char __user *buf, | 133 | static ssize_t flash_read(struct file *file, char __user *buf, |
303 | size_t count, loff_t *ppos) | 134 | size_t count, loff_t *ppos) |
304 | { | 135 | { |
@@ -427,22 +258,6 @@ static int create_device_files(struct super_block *sb, | |||
427 | goto bail; | 258 | goto bail; |
428 | } | 259 | } |
429 | 260 | ||
430 | ret = create_file("node_info", S_IFREG|S_IRUGO, dir, &tmp, | ||
431 | &atomic_node_info_ops, dd); | ||
432 | if (ret) { | ||
433 | printk(KERN_ERR "create_file(%s/node_info) " | ||
434 | "failed: %d\n", unit, ret); | ||
435 | goto bail; | ||
436 | } | ||
437 | |||
438 | ret = create_file("port_info", S_IFREG|S_IRUGO, dir, &tmp, | ||
439 | &atomic_port_info_ops, dd); | ||
440 | if (ret) { | ||
441 | printk(KERN_ERR "create_file(%s/port_info) " | ||
442 | "failed: %d\n", unit, ret); | ||
443 | goto bail; | ||
444 | } | ||
445 | |||
446 | ret = create_file("flash", S_IFREG|S_IWUSR|S_IRUGO, dir, &tmp, | 261 | ret = create_file("flash", S_IFREG|S_IWUSR|S_IRUGO, dir, &tmp, |
447 | &flash_ops, dd); | 262 | &flash_ops, dd); |
448 | if (ret) { | 263 | if (ret) { |
@@ -508,8 +323,6 @@ static int remove_device_files(struct super_block *sb, | |||
508 | } | 323 | } |
509 | 324 | ||
510 | remove_file(dir, "flash"); | 325 | remove_file(dir, "flash"); |
511 | remove_file(dir, "port_info"); | ||
512 | remove_file(dir, "node_info"); | ||
513 | remove_file(dir, "atomic_counters"); | 326 | remove_file(dir, "atomic_counters"); |
514 | d_delete(dir); | 327 | d_delete(dir); |
515 | ret = simple_rmdir(root->d_inode, dir); | 328 | ret = simple_rmdir(root->d_inode, dir); |
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6110.c b/drivers/infiniband/hw/ipath/ipath_iba6110.c index 650745d83fac..ddbebe4bdb27 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba6110.c +++ b/drivers/infiniband/hw/ipath/ipath_iba6110.c | |||
@@ -631,56 +631,35 @@ static int ipath_ht_boardname(struct ipath_devdata *dd, char *name, | |||
631 | { | 631 | { |
632 | char *n = NULL; | 632 | char *n = NULL; |
633 | u8 boardrev = dd->ipath_boardrev; | 633 | u8 boardrev = dd->ipath_boardrev; |
634 | int ret; | 634 | int ret = 0; |
635 | 635 | ||
636 | switch (boardrev) { | 636 | switch (boardrev) { |
637 | case 4: /* Ponderosa is one of the bringup boards */ | ||
638 | n = "Ponderosa"; | ||
639 | break; | ||
640 | case 5: | 637 | case 5: |
641 | /* | 638 | /* |
642 | * original production board; two production levels, with | 639 | * original production board; two production levels, with |
643 | * different serial number ranges. See ipath_ht_early_init() for | 640 | * different serial number ranges. See ipath_ht_early_init() for |
644 | * case where we enable IPATH_GPIO_INTR for later serial # range. | 641 | * case where we enable IPATH_GPIO_INTR for later serial # range. |
642 | * Original 112* serial number is no longer supported. | ||
645 | */ | 643 | */ |
646 | n = "InfiniPath_QHT7040"; | 644 | n = "InfiniPath_QHT7040"; |
647 | break; | 645 | break; |
648 | case 6: | ||
649 | n = "OEM_Board_3"; | ||
650 | break; | ||
651 | case 7: | 646 | case 7: |
652 | /* small form factor production board */ | 647 | /* small form factor production board */ |
653 | n = "InfiniPath_QHT7140"; | 648 | n = "InfiniPath_QHT7140"; |
654 | break; | 649 | break; |
655 | case 8: | ||
656 | n = "LS/X-1"; | ||
657 | break; | ||
658 | case 9: /* Comstock bringup test board */ | ||
659 | n = "Comstock"; | ||
660 | break; | ||
661 | case 10: | ||
662 | n = "OEM_Board_2"; | ||
663 | break; | ||
664 | case 11: | ||
665 | n = "InfiniPath_HT-470"; /* obsoleted */ | ||
666 | break; | ||
667 | case 12: | ||
668 | n = "OEM_Board_4"; | ||
669 | break; | ||
670 | default: /* don't know, just print the number */ | 650 | default: /* don't know, just print the number */ |
671 | ipath_dev_err(dd, "Don't yet know about board " | 651 | ipath_dev_err(dd, "Don't yet know about board " |
672 | "with ID %u\n", boardrev); | 652 | "with ID %u\n", boardrev); |
673 | snprintf(name, namelen, "Unknown_InfiniPath_QHT7xxx_%u", | 653 | snprintf(name, namelen, "Unknown_InfiniPath_QHT7xxx_%u", |
674 | boardrev); | 654 | boardrev); |
655 | ret = 1; | ||
675 | break; | 656 | break; |
676 | } | 657 | } |
677 | if (n) | 658 | if (n) |
678 | snprintf(name, namelen, "%s", n); | 659 | snprintf(name, namelen, "%s", n); |
679 | 660 | ||
680 | if (dd->ipath_boardrev != 6 && dd->ipath_boardrev != 7 && | 661 | if (ret) { |
681 | dd->ipath_boardrev != 11) { | ||
682 | ipath_dev_err(dd, "Unsupported InfiniPath board %s!\n", name); | 662 | ipath_dev_err(dd, "Unsupported InfiniPath board %s!\n", name); |
683 | ret = 1; | ||
684 | goto bail; | 663 | goto bail; |
685 | } | 664 | } |
686 | if (dd->ipath_majrev != 3 || (dd->ipath_minrev < 2 || | 665 | if (dd->ipath_majrev != 3 || (dd->ipath_minrev < 2 || |
@@ -1554,10 +1533,25 @@ static int ipath_ht_early_init(struct ipath_devdata *dd) | |||
1554 | * can use GPIO interrupts. They have serial #'s starting | 1533 | * can use GPIO interrupts. They have serial #'s starting |
1555 | * with 128, rather than 112. | 1534 | * with 128, rather than 112. |
1556 | */ | 1535 | */ |
1557 | dd->ipath_flags |= IPATH_GPIO_INTR; | 1536 | if (dd->ipath_serial[0] == '1' && |
1558 | } else | 1537 | dd->ipath_serial[1] == '2' && |
1559 | ipath_dev_err(dd, "Unsupported InfiniPath serial " | 1538 | dd->ipath_serial[2] == '8') |
1560 | "number %.16s!\n", dd->ipath_serial); | 1539 | dd->ipath_flags |= IPATH_GPIO_INTR; |
1540 | else { | ||
1541 | ipath_dev_err(dd, "Unsupported InfiniPath board " | ||
1542 | "(serial number %.16s)!\n", | ||
1543 | dd->ipath_serial); | ||
1544 | return 1; | ||
1545 | } | ||
1546 | } | ||
1547 | |||
1548 | if (dd->ipath_minrev >= 4) { | ||
1549 | /* Rev4+ reports extra errors via internal GPIO pins */ | ||
1550 | dd->ipath_flags |= IPATH_GPIO_ERRINTRS; | ||
1551 | dd->ipath_gpio_mask |= IPATH_GPIO_ERRINTR_MASK; | ||
1552 | ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask, | ||
1553 | dd->ipath_gpio_mask); | ||
1554 | } | ||
1561 | 1555 | ||
1562 | return 0; | 1556 | return 0; |
1563 | } | 1557 | } |
@@ -1592,7 +1586,10 @@ static int ipath_ht_get_base_info(struct ipath_portdata *pd, void *kbase) | |||
1592 | struct ipath_base_info *kinfo = kbase; | 1586 | struct ipath_base_info *kinfo = kbase; |
1593 | 1587 | ||
1594 | kinfo->spi_runtime_flags |= IPATH_RUNTIME_HT | | 1588 | kinfo->spi_runtime_flags |= IPATH_RUNTIME_HT | |
1595 | IPATH_RUNTIME_RCVHDR_COPY; | 1589 | IPATH_RUNTIME_PIO_REGSWAPPED; |
1590 | |||
1591 | if (pd->port_dd->ipath_minrev < 4) | ||
1592 | kinfo->spi_runtime_flags |= IPATH_RUNTIME_RCVHDR_COPY; | ||
1596 | 1593 | ||
1597 | return 0; | 1594 | return 0; |
1598 | } | 1595 | } |
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c index 5b6ac9a1a709..0103d6f4847b 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba6120.c +++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c | |||
@@ -1143,11 +1143,14 @@ static void ipath_pe_put_tid(struct ipath_devdata *dd, u64 __iomem *tidptr, | |||
1143 | pa |= 2 << 29; | 1143 | pa |= 2 << 29; |
1144 | } | 1144 | } |
1145 | 1145 | ||
1146 | /* workaround chip bug 9437 by writing each TID twice | 1146 | /* |
1147 | * and holding a spinlock around the writes, so they don't | 1147 | * Workaround chip bug 9437 by writing the scratch register |
1148 | * intermix with other TID (eager or expected) writes | 1148 | * before and after the TID, and with an io write barrier. |
1149 | * Unfortunately, this call can be done from interrupt level | 1149 | * We use a spinlock around the writes, so they can't intermix |
1150 | * for the port 0 eager TIDs, so we have to use irqsave | 1150 | * with other TID (eager or expected) writes (the chip bug |
1151 | * is triggered by back to back TID writes). Unfortunately, this | ||
1152 | * call can be done from interrupt level for the port 0 eager TIDs, | ||
1153 | * so we have to use irqsave locks. | ||
1151 | */ | 1154 | */ |
1152 | spin_lock_irqsave(&dd->ipath_tid_lock, flags); | 1155 | spin_lock_irqsave(&dd->ipath_tid_lock, flags); |
1153 | ipath_write_kreg(dd, dd->ipath_kregs->kr_scratch, 0xfeeddeaf); | 1156 | ipath_write_kreg(dd, dd->ipath_kregs->kr_scratch, 0xfeeddeaf); |
@@ -1273,6 +1276,8 @@ static void ipath_pe_tidtemplate(struct ipath_devdata *dd) | |||
1273 | static int ipath_pe_early_init(struct ipath_devdata *dd) | 1276 | static int ipath_pe_early_init(struct ipath_devdata *dd) |
1274 | { | 1277 | { |
1275 | dd->ipath_flags |= IPATH_4BYTE_TID; | 1278 | dd->ipath_flags |= IPATH_4BYTE_TID; |
1279 | if (ipath_unordered_wc()) | ||
1280 | dd->ipath_flags |= IPATH_PIO_FLUSH_WC; | ||
1276 | 1281 | ||
1277 | /* | 1282 | /* |
1278 | * For openfabrics, we need to be able to handle an IB header of | 1283 | * For openfabrics, we need to be able to handle an IB header of |
@@ -1343,7 +1348,8 @@ static int ipath_pe_get_base_info(struct ipath_portdata *pd, void *kbase) | |||
1343 | dd = pd->port_dd; | 1348 | dd = pd->port_dd; |
1344 | 1349 | ||
1345 | done: | 1350 | done: |
1346 | kinfo->spi_runtime_flags |= IPATH_RUNTIME_PCIE; | 1351 | kinfo->spi_runtime_flags |= IPATH_RUNTIME_PCIE | |
1352 | IPATH_RUNTIME_FORCE_PIOAVAIL | IPATH_RUNTIME_PIO_REGSWAPPED; | ||
1347 | return 0; | 1353 | return 0; |
1348 | } | 1354 | } |
1349 | 1355 | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c index b29fe7e9b11a..6a5dd5cd773d 100644 --- a/drivers/infiniband/hw/ipath/ipath_intr.c +++ b/drivers/infiniband/hw/ipath/ipath_intr.c | |||
@@ -275,6 +275,16 @@ static char *ib_linkstate(u32 linkstate) | |||
275 | return ret; | 275 | return ret; |
276 | } | 276 | } |
277 | 277 | ||
278 | void signal_ib_event(struct ipath_devdata *dd, enum ib_event_type ev) | ||
279 | { | ||
280 | struct ib_event event; | ||
281 | |||
282 | event.device = &dd->verbs_dev->ibdev; | ||
283 | event.element.port_num = 1; | ||
284 | event.event = ev; | ||
285 | ib_dispatch_event(&event); | ||
286 | } | ||
287 | |||
278 | static void handle_e_ibstatuschanged(struct ipath_devdata *dd, | 288 | static void handle_e_ibstatuschanged(struct ipath_devdata *dd, |
279 | ipath_err_t errs, int noprint) | 289 | ipath_err_t errs, int noprint) |
280 | { | 290 | { |
@@ -373,6 +383,8 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd, | |||
373 | dd->ipath_ibpollcnt = 0; /* some state other than 2 or 3 */ | 383 | dd->ipath_ibpollcnt = 0; /* some state other than 2 or 3 */ |
374 | ipath_stats.sps_iblink++; | 384 | ipath_stats.sps_iblink++; |
375 | if (ltstate != INFINIPATH_IBCS_LT_STATE_LINKUP) { | 385 | if (ltstate != INFINIPATH_IBCS_LT_STATE_LINKUP) { |
386 | if (dd->ipath_flags & IPATH_LINKACTIVE) | ||
387 | signal_ib_event(dd, IB_EVENT_PORT_ERR); | ||
376 | dd->ipath_flags |= IPATH_LINKDOWN; | 388 | dd->ipath_flags |= IPATH_LINKDOWN; |
377 | dd->ipath_flags &= ~(IPATH_LINKUNK | IPATH_LINKINIT | 389 | dd->ipath_flags &= ~(IPATH_LINKUNK | IPATH_LINKINIT |
378 | | IPATH_LINKACTIVE | | 390 | | IPATH_LINKACTIVE | |
@@ -405,7 +417,10 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd, | |||
405 | *dd->ipath_statusp |= | 417 | *dd->ipath_statusp |= |
406 | IPATH_STATUS_IB_READY | IPATH_STATUS_IB_CONF; | 418 | IPATH_STATUS_IB_READY | IPATH_STATUS_IB_CONF; |
407 | dd->ipath_f_setextled(dd, lstate, ltstate); | 419 | dd->ipath_f_setextled(dd, lstate, ltstate); |
420 | signal_ib_event(dd, IB_EVENT_PORT_ACTIVE); | ||
408 | } else if ((val & IPATH_IBSTATE_MASK) == IPATH_IBSTATE_INIT) { | 421 | } else if ((val & IPATH_IBSTATE_MASK) == IPATH_IBSTATE_INIT) { |
422 | if (dd->ipath_flags & IPATH_LINKACTIVE) | ||
423 | signal_ib_event(dd, IB_EVENT_PORT_ERR); | ||
409 | /* | 424 | /* |
410 | * set INIT and DOWN. Down is checked by most of the other | 425 | * set INIT and DOWN. Down is checked by most of the other |
411 | * code, but INIT is useful to know in a few places. | 426 | * code, but INIT is useful to know in a few places. |
@@ -418,6 +433,8 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd, | |||
418 | | IPATH_STATUS_IB_READY); | 433 | | IPATH_STATUS_IB_READY); |
419 | dd->ipath_f_setextled(dd, lstate, ltstate); | 434 | dd->ipath_f_setextled(dd, lstate, ltstate); |
420 | } else if ((val & IPATH_IBSTATE_MASK) == IPATH_IBSTATE_ARM) { | 435 | } else if ((val & IPATH_IBSTATE_MASK) == IPATH_IBSTATE_ARM) { |
436 | if (dd->ipath_flags & IPATH_LINKACTIVE) | ||
437 | signal_ib_event(dd, IB_EVENT_PORT_ERR); | ||
421 | dd->ipath_flags |= IPATH_LINKARMED; | 438 | dd->ipath_flags |= IPATH_LINKARMED; |
422 | dd->ipath_flags &= | 439 | dd->ipath_flags &= |
423 | ~(IPATH_LINKUNK | IPATH_LINKDOWN | IPATH_LINKINIT | | 440 | ~(IPATH_LINKUNK | IPATH_LINKDOWN | IPATH_LINKINIT | |
@@ -688,17 +705,9 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs) | |||
688 | chkerrpkts = 1; | 705 | chkerrpkts = 1; |
689 | dd->ipath_lastrcvhdrqtails[i] = tl; | 706 | dd->ipath_lastrcvhdrqtails[i] = tl; |
690 | pd->port_hdrqfull++; | 707 | pd->port_hdrqfull++; |
691 | if (test_bit(IPATH_PORT_WAITING_OVERFLOW, | 708 | /* flush hdrqfull so that poll() sees it */ |
692 | &pd->port_flag)) { | 709 | wmb(); |
693 | clear_bit( | 710 | wake_up_interruptible(&pd->port_wait); |
694 | IPATH_PORT_WAITING_OVERFLOW, | ||
695 | &pd->port_flag); | ||
696 | set_bit( | ||
697 | IPATH_PORT_WAITING_OVERFLOW, | ||
698 | &pd->int_flag); | ||
699 | wake_up_interruptible( | ||
700 | &pd->port_wait); | ||
701 | } | ||
702 | } | 711 | } |
703 | } | 712 | } |
704 | } | 713 | } |
@@ -960,6 +969,8 @@ static void handle_urcv(struct ipath_devdata *dd, u32 istat) | |||
960 | int i; | 969 | int i; |
961 | int rcvdint = 0; | 970 | int rcvdint = 0; |
962 | 971 | ||
972 | /* test_bit below needs this... */ | ||
973 | rmb(); | ||
963 | portr = ((istat >> INFINIPATH_I_RCVAVAIL_SHIFT) & | 974 | portr = ((istat >> INFINIPATH_I_RCVAVAIL_SHIFT) & |
964 | dd->ipath_i_rcvavail_mask) | 975 | dd->ipath_i_rcvavail_mask) |
965 | | ((istat >> INFINIPATH_I_RCVURG_SHIFT) & | 976 | | ((istat >> INFINIPATH_I_RCVURG_SHIFT) & |
@@ -967,22 +978,15 @@ static void handle_urcv(struct ipath_devdata *dd, u32 istat) | |||
967 | for (i = 1; i < dd->ipath_cfgports; i++) { | 978 | for (i = 1; i < dd->ipath_cfgports; i++) { |
968 | struct ipath_portdata *pd = dd->ipath_pd[i]; | 979 | struct ipath_portdata *pd = dd->ipath_pd[i]; |
969 | if (portr & (1 << i) && pd && pd->port_cnt) { | 980 | if (portr & (1 << i) && pd && pd->port_cnt) { |
970 | if (test_bit(IPATH_PORT_WAITING_RCV, | 981 | if (test_and_clear_bit(IPATH_PORT_WAITING_RCV, |
971 | &pd->port_flag)) { | 982 | &pd->port_flag)) { |
972 | clear_bit(IPATH_PORT_WAITING_RCV, | ||
973 | &pd->port_flag); | ||
974 | set_bit(IPATH_PORT_WAITING_RCV, | ||
975 | &pd->int_flag); | ||
976 | clear_bit(i + INFINIPATH_R_INTRAVAIL_SHIFT, | 983 | clear_bit(i + INFINIPATH_R_INTRAVAIL_SHIFT, |
977 | &dd->ipath_rcvctrl); | 984 | &dd->ipath_rcvctrl); |
978 | wake_up_interruptible(&pd->port_wait); | 985 | wake_up_interruptible(&pd->port_wait); |
979 | rcvdint = 1; | 986 | rcvdint = 1; |
980 | } else if (test_bit(IPATH_PORT_WAITING_URG, | 987 | } else if (test_and_clear_bit(IPATH_PORT_WAITING_URG, |
981 | &pd->port_flag)) { | 988 | &pd->port_flag)) { |
982 | clear_bit(IPATH_PORT_WAITING_URG, | 989 | pd->port_urgent++; |
983 | &pd->port_flag); | ||
984 | set_bit(IPATH_PORT_WAITING_URG, | ||
985 | &pd->int_flag); | ||
986 | wake_up_interruptible(&pd->port_wait); | 990 | wake_up_interruptible(&pd->port_wait); |
987 | } | 991 | } |
988 | } | 992 | } |
@@ -1085,8 +1089,8 @@ irqreturn_t ipath_intr(int irq, void *data) | |||
1085 | * GPIO_2 indicates (on some HT4xx boards) that a packet | 1089 | * GPIO_2 indicates (on some HT4xx boards) that a packet |
1086 | * has arrived for Port 0. Checking for this | 1090 | * has arrived for Port 0. Checking for this |
1087 | * is controlled by flag IPATH_GPIO_INTR. | 1091 | * is controlled by flag IPATH_GPIO_INTR. |
1088 | * GPIO_3..5 on IBA6120 Rev2 chips indicate errors | 1092 | * GPIO_3..5 on IBA6120 Rev2 and IBA6110 Rev4 chips indicate |
1089 | * that we need to count. Checking for this | 1093 | * errors that we need to count. Checking for this |
1090 | * is controlled by flag IPATH_GPIO_ERRINTRS. | 1094 | * is controlled by flag IPATH_GPIO_ERRINTRS. |
1091 | */ | 1095 | */ |
1092 | u32 gpiostatus; | 1096 | u32 gpiostatus; |
@@ -1137,10 +1141,8 @@ irqreturn_t ipath_intr(int irq, void *data) | |||
1137 | /* | 1141 | /* |
1138 | * Some unexpected bits remain. If they could have | 1142 | * Some unexpected bits remain. If they could have |
1139 | * caused the interrupt, complain and clear. | 1143 | * caused the interrupt, complain and clear. |
1140 | * MEA: this is almost certainly non-ideal. | 1144 | * To avoid repetition of this condition, also clear |
1141 | * we should look into auto-disable of unexpected | 1145 | * the mask. It is almost certainly due to error. |
1142 | * GPIO interrupts, possibly on a "three strikes" | ||
1143 | * basis. | ||
1144 | */ | 1146 | */ |
1145 | const u32 mask = (u32) dd->ipath_gpio_mask; | 1147 | const u32 mask = (u32) dd->ipath_gpio_mask; |
1146 | 1148 | ||
@@ -1148,6 +1150,10 @@ irqreturn_t ipath_intr(int irq, void *data) | |||
1148 | ipath_dbg("Unexpected GPIO IRQ bits %x\n", | 1150 | ipath_dbg("Unexpected GPIO IRQ bits %x\n", |
1149 | gpiostatus & mask); | 1151 | gpiostatus & mask); |
1150 | to_clear |= (gpiostatus & mask); | 1152 | to_clear |= (gpiostatus & mask); |
1153 | dd->ipath_gpio_mask &= ~(gpiostatus & mask); | ||
1154 | ipath_write_kreg(dd, | ||
1155 | dd->ipath_kregs->kr_gpio_mask, | ||
1156 | dd->ipath_gpio_mask); | ||
1151 | } | 1157 | } |
1152 | } | 1158 | } |
1153 | if (to_clear) { | 1159 | if (to_clear) { |
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h index 7a7966f7e4ff..8786dd7922e4 100644 --- a/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/drivers/infiniband/hw/ipath/ipath_kernel.h | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/pci.h> | 42 | #include <linux/pci.h> |
43 | #include <linux/dma-mapping.h> | 43 | #include <linux/dma-mapping.h> |
44 | #include <asm/io.h> | 44 | #include <asm/io.h> |
45 | #include <rdma/ib_verbs.h> | ||
45 | 46 | ||
46 | #include "ipath_common.h" | 47 | #include "ipath_common.h" |
47 | #include "ipath_debug.h" | 48 | #include "ipath_debug.h" |
@@ -139,6 +140,12 @@ struct ipath_portdata { | |||
139 | u32 port_pionowait; | 140 | u32 port_pionowait; |
140 | /* total number of rcvhdrqfull errors */ | 141 | /* total number of rcvhdrqfull errors */ |
141 | u32 port_hdrqfull; | 142 | u32 port_hdrqfull; |
143 | /* saved total number of rcvhdrqfull errors for poll edge trigger */ | ||
144 | u32 port_hdrqfull_poll; | ||
145 | /* total number of polled urgent packets */ | ||
146 | u32 port_urgent; | ||
147 | /* saved total number of polled urgent packets for poll edge trigger */ | ||
148 | u32 port_urgent_poll; | ||
142 | /* pid of process using this port */ | 149 | /* pid of process using this port */ |
143 | pid_t port_pid; | 150 | pid_t port_pid; |
144 | /* same size as task_struct .comm[] */ | 151 | /* same size as task_struct .comm[] */ |
@@ -724,6 +731,8 @@ int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv); | |||
724 | #define IPATH_LINKACTIVE 0x200 | 731 | #define IPATH_LINKACTIVE 0x200 |
725 | /* link current state is unknown */ | 732 | /* link current state is unknown */ |
726 | #define IPATH_LINKUNK 0x400 | 733 | #define IPATH_LINKUNK 0x400 |
734 | /* Write combining flush needed for PIO */ | ||
735 | #define IPATH_PIO_FLUSH_WC 0x1000 | ||
727 | /* no IB cable, or no device on IB cable */ | 736 | /* no IB cable, or no device on IB cable */ |
728 | #define IPATH_NOCABLE 0x4000 | 737 | #define IPATH_NOCABLE 0x4000 |
729 | /* Supports port zero per packet receive interrupts via | 738 | /* Supports port zero per packet receive interrupts via |
@@ -755,8 +764,6 @@ int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv); | |||
755 | #define IPATH_PORT_MASTER_UNINIT 4 | 764 | #define IPATH_PORT_MASTER_UNINIT 4 |
756 | /* waiting for an urgent packet to arrive */ | 765 | /* waiting for an urgent packet to arrive */ |
757 | #define IPATH_PORT_WAITING_URG 5 | 766 | #define IPATH_PORT_WAITING_URG 5 |
758 | /* waiting for a header overflow */ | ||
759 | #define IPATH_PORT_WAITING_OVERFLOW 6 | ||
760 | 767 | ||
761 | /* free up any allocated data at closes */ | 768 | /* free up any allocated data at closes */ |
762 | void ipath_free_data(struct ipath_portdata *dd); | 769 | void ipath_free_data(struct ipath_portdata *dd); |
@@ -769,6 +776,7 @@ void ipath_get_eeprom_info(struct ipath_devdata *); | |||
769 | int ipath_update_eeprom_log(struct ipath_devdata *dd); | 776 | int ipath_update_eeprom_log(struct ipath_devdata *dd); |
770 | void ipath_inc_eeprom_err(struct ipath_devdata *dd, u32 eidx, u32 incr); | 777 | void ipath_inc_eeprom_err(struct ipath_devdata *dd, u32 eidx, u32 incr); |
771 | u64 ipath_snap_cntr(struct ipath_devdata *, ipath_creg); | 778 | u64 ipath_snap_cntr(struct ipath_devdata *, ipath_creg); |
779 | void signal_ib_event(struct ipath_devdata *dd, enum ib_event_type ev); | ||
772 | 780 | ||
773 | /* | 781 | /* |
774 | * Set LED override, only the two LSBs have "public" meaning, but | 782 | * Set LED override, only the two LSBs have "public" meaning, but |
diff --git a/drivers/infiniband/hw/ipath/ipath_mad.c b/drivers/infiniband/hw/ipath/ipath_mad.c index d61c03044545..3d1432d1e3f4 100644 --- a/drivers/infiniband/hw/ipath/ipath_mad.c +++ b/drivers/infiniband/hw/ipath/ipath_mad.c | |||
@@ -245,7 +245,7 @@ static int recv_subn_get_portinfo(struct ib_smp *smp, | |||
245 | 245 | ||
246 | /* Only return the mkey if the protection field allows it. */ | 246 | /* Only return the mkey if the protection field allows it. */ |
247 | if (smp->method == IB_MGMT_METHOD_SET || dev->mkey == smp->mkey || | 247 | if (smp->method == IB_MGMT_METHOD_SET || dev->mkey == smp->mkey || |
248 | (dev->mkeyprot_resv_lmc >> 6) == 0) | 248 | dev->mkeyprot == 0) |
249 | pip->mkey = dev->mkey; | 249 | pip->mkey = dev->mkey; |
250 | pip->gid_prefix = dev->gid_prefix; | 250 | pip->gid_prefix = dev->gid_prefix; |
251 | lid = dev->dd->ipath_lid; | 251 | lid = dev->dd->ipath_lid; |
@@ -264,7 +264,7 @@ static int recv_subn_get_portinfo(struct ib_smp *smp, | |||
264 | pip->portphysstate_linkdown = | 264 | pip->portphysstate_linkdown = |
265 | (ipath_cvt_physportstate[ibcstat & 0xf] << 4) | | 265 | (ipath_cvt_physportstate[ibcstat & 0xf] << 4) | |
266 | (get_linkdowndefaultstate(dev->dd) ? 1 : 2); | 266 | (get_linkdowndefaultstate(dev->dd) ? 1 : 2); |
267 | pip->mkeyprot_resv_lmc = dev->mkeyprot_resv_lmc; | 267 | pip->mkeyprot_resv_lmc = (dev->mkeyprot << 6) | dev->dd->ipath_lmc; |
268 | pip->linkspeedactive_enabled = 0x11; /* 2.5Gbps, 2.5Gbps */ | 268 | pip->linkspeedactive_enabled = 0x11; /* 2.5Gbps, 2.5Gbps */ |
269 | switch (dev->dd->ipath_ibmtu) { | 269 | switch (dev->dd->ipath_ibmtu) { |
270 | case 4096: | 270 | case 4096: |
@@ -401,7 +401,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, | |||
401 | struct ib_port_info *pip = (struct ib_port_info *)smp->data; | 401 | struct ib_port_info *pip = (struct ib_port_info *)smp->data; |
402 | struct ib_event event; | 402 | struct ib_event event; |
403 | struct ipath_ibdev *dev; | 403 | struct ipath_ibdev *dev; |
404 | u32 flags; | 404 | struct ipath_devdata *dd; |
405 | char clientrereg = 0; | 405 | char clientrereg = 0; |
406 | u16 lid, smlid; | 406 | u16 lid, smlid; |
407 | u8 lwe; | 407 | u8 lwe; |
@@ -415,6 +415,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, | |||
415 | goto err; | 415 | goto err; |
416 | 416 | ||
417 | dev = to_idev(ibdev); | 417 | dev = to_idev(ibdev); |
418 | dd = dev->dd; | ||
418 | event.device = ibdev; | 419 | event.device = ibdev; |
419 | event.element.port_num = port; | 420 | event.element.port_num = port; |
420 | 421 | ||
@@ -423,11 +424,12 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, | |||
423 | dev->mkey_lease_period = be16_to_cpu(pip->mkey_lease_period); | 424 | dev->mkey_lease_period = be16_to_cpu(pip->mkey_lease_period); |
424 | 425 | ||
425 | lid = be16_to_cpu(pip->lid); | 426 | lid = be16_to_cpu(pip->lid); |
426 | if (lid != dev->dd->ipath_lid) { | 427 | if (dd->ipath_lid != lid || |
428 | dd->ipath_lmc != (pip->mkeyprot_resv_lmc & 7)) { | ||
427 | /* Must be a valid unicast LID address. */ | 429 | /* Must be a valid unicast LID address. */ |
428 | if (lid == 0 || lid >= IPATH_MULTICAST_LID_BASE) | 430 | if (lid == 0 || lid >= IPATH_MULTICAST_LID_BASE) |
429 | goto err; | 431 | goto err; |
430 | ipath_set_lid(dev->dd, lid, pip->mkeyprot_resv_lmc & 7); | 432 | ipath_set_lid(dd, lid, pip->mkeyprot_resv_lmc & 7); |
431 | event.event = IB_EVENT_LID_CHANGE; | 433 | event.event = IB_EVENT_LID_CHANGE; |
432 | ib_dispatch_event(&event); | 434 | ib_dispatch_event(&event); |
433 | } | 435 | } |
@@ -461,18 +463,18 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, | |||
461 | case 0: /* NOP */ | 463 | case 0: /* NOP */ |
462 | break; | 464 | break; |
463 | case 1: /* SLEEP */ | 465 | case 1: /* SLEEP */ |
464 | if (set_linkdowndefaultstate(dev->dd, 1)) | 466 | if (set_linkdowndefaultstate(dd, 1)) |
465 | goto err; | 467 | goto err; |
466 | break; | 468 | break; |
467 | case 2: /* POLL */ | 469 | case 2: /* POLL */ |
468 | if (set_linkdowndefaultstate(dev->dd, 0)) | 470 | if (set_linkdowndefaultstate(dd, 0)) |
469 | goto err; | 471 | goto err; |
470 | break; | 472 | break; |
471 | default: | 473 | default: |
472 | goto err; | 474 | goto err; |
473 | } | 475 | } |
474 | 476 | ||
475 | dev->mkeyprot_resv_lmc = pip->mkeyprot_resv_lmc; | 477 | dev->mkeyprot = pip->mkeyprot_resv_lmc >> 6; |
476 | dev->vl_high_limit = pip->vl_high_limit; | 478 | dev->vl_high_limit = pip->vl_high_limit; |
477 | 479 | ||
478 | switch ((pip->neighbormtu_mastersmsl >> 4) & 0xF) { | 480 | switch ((pip->neighbormtu_mastersmsl >> 4) & 0xF) { |
@@ -495,7 +497,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, | |||
495 | /* XXX We have already partially updated our state! */ | 497 | /* XXX We have already partially updated our state! */ |
496 | goto err; | 498 | goto err; |
497 | } | 499 | } |
498 | ipath_set_mtu(dev->dd, mtu); | 500 | ipath_set_mtu(dd, mtu); |
499 | 501 | ||
500 | dev->sm_sl = pip->neighbormtu_mastersmsl & 0xF; | 502 | dev->sm_sl = pip->neighbormtu_mastersmsl & 0xF; |
501 | 503 | ||
@@ -511,16 +513,16 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, | |||
511 | * later. | 513 | * later. |
512 | */ | 514 | */ |
513 | if (pip->pkey_violations == 0) | 515 | if (pip->pkey_violations == 0) |
514 | dev->z_pkey_violations = ipath_get_cr_errpkey(dev->dd); | 516 | dev->z_pkey_violations = ipath_get_cr_errpkey(dd); |
515 | 517 | ||
516 | if (pip->qkey_violations == 0) | 518 | if (pip->qkey_violations == 0) |
517 | dev->qkey_violations = 0; | 519 | dev->qkey_violations = 0; |
518 | 520 | ||
519 | ore = pip->localphyerrors_overrunerrors; | 521 | ore = pip->localphyerrors_overrunerrors; |
520 | if (set_phyerrthreshold(dev->dd, (ore >> 4) & 0xF)) | 522 | if (set_phyerrthreshold(dd, (ore >> 4) & 0xF)) |
521 | goto err; | 523 | goto err; |
522 | 524 | ||
523 | if (set_overrunthreshold(dev->dd, (ore & 0xF))) | 525 | if (set_overrunthreshold(dd, (ore & 0xF))) |
524 | goto err; | 526 | goto err; |
525 | 527 | ||
526 | dev->subnet_timeout = pip->clientrereg_resv_subnetto & 0x1F; | 528 | dev->subnet_timeout = pip->clientrereg_resv_subnetto & 0x1F; |
@@ -538,7 +540,6 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, | |||
538 | * is down or is being set to down. | 540 | * is down or is being set to down. |
539 | */ | 541 | */ |
540 | state = pip->linkspeed_portstate & 0xF; | 542 | state = pip->linkspeed_portstate & 0xF; |
541 | flags = dev->dd->ipath_flags; | ||
542 | lstate = (pip->portphysstate_linkdown >> 4) & 0xF; | 543 | lstate = (pip->portphysstate_linkdown >> 4) & 0xF; |
543 | if (lstate && !(state == IB_PORT_DOWN || state == IB_PORT_NOP)) | 544 | if (lstate && !(state == IB_PORT_DOWN || state == IB_PORT_NOP)) |
544 | goto err; | 545 | goto err; |
@@ -554,7 +555,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, | |||
554 | /* FALLTHROUGH */ | 555 | /* FALLTHROUGH */ |
555 | case IB_PORT_DOWN: | 556 | case IB_PORT_DOWN: |
556 | if (lstate == 0) | 557 | if (lstate == 0) |
557 | if (get_linkdowndefaultstate(dev->dd)) | 558 | if (get_linkdowndefaultstate(dd)) |
558 | lstate = IPATH_IB_LINKDOWN_SLEEP; | 559 | lstate = IPATH_IB_LINKDOWN_SLEEP; |
559 | else | 560 | else |
560 | lstate = IPATH_IB_LINKDOWN; | 561 | lstate = IPATH_IB_LINKDOWN; |
@@ -566,27 +567,13 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, | |||
566 | lstate = IPATH_IB_LINKDOWN_DISABLE; | 567 | lstate = IPATH_IB_LINKDOWN_DISABLE; |
567 | else | 568 | else |
568 | goto err; | 569 | goto err; |
569 | ipath_set_linkstate(dev->dd, lstate); | 570 | ipath_set_linkstate(dd, lstate); |
570 | if (flags & IPATH_LINKACTIVE) { | ||
571 | event.event = IB_EVENT_PORT_ERR; | ||
572 | ib_dispatch_event(&event); | ||
573 | } | ||
574 | break; | 571 | break; |
575 | case IB_PORT_ARMED: | 572 | case IB_PORT_ARMED: |
576 | if (!(flags & (IPATH_LINKINIT | IPATH_LINKACTIVE))) | 573 | ipath_set_linkstate(dd, IPATH_IB_LINKARM); |
577 | break; | ||
578 | ipath_set_linkstate(dev->dd, IPATH_IB_LINKARM); | ||
579 | if (flags & IPATH_LINKACTIVE) { | ||
580 | event.event = IB_EVENT_PORT_ERR; | ||
581 | ib_dispatch_event(&event); | ||
582 | } | ||
583 | break; | 574 | break; |
584 | case IB_PORT_ACTIVE: | 575 | case IB_PORT_ACTIVE: |
585 | if (!(flags & IPATH_LINKARMED)) | 576 | ipath_set_linkstate(dd, IPATH_IB_LINKACTIVE); |
586 | break; | ||
587 | ipath_set_linkstate(dev->dd, IPATH_IB_LINKACTIVE); | ||
588 | event.event = IB_EVENT_PORT_ACTIVE; | ||
589 | ib_dispatch_event(&event); | ||
590 | break; | 577 | break; |
591 | default: | 578 | default: |
592 | /* XXX We have already partially updated our state! */ | 579 | /* XXX We have already partially updated our state! */ |
@@ -1350,7 +1337,7 @@ static int process_subn(struct ib_device *ibdev, int mad_flags, | |||
1350 | if (dev->mkey_lease_timeout && jiffies >= dev->mkey_lease_timeout) { | 1337 | if (dev->mkey_lease_timeout && jiffies >= dev->mkey_lease_timeout) { |
1351 | /* Clear timeout and mkey protection field. */ | 1338 | /* Clear timeout and mkey protection field. */ |
1352 | dev->mkey_lease_timeout = 0; | 1339 | dev->mkey_lease_timeout = 0; |
1353 | dev->mkeyprot_resv_lmc &= 0x3F; | 1340 | dev->mkeyprot = 0; |
1354 | } | 1341 | } |
1355 | 1342 | ||
1356 | /* | 1343 | /* |
@@ -1361,7 +1348,7 @@ static int process_subn(struct ib_device *ibdev, int mad_flags, | |||
1361 | dev->mkey != smp->mkey && | 1348 | dev->mkey != smp->mkey && |
1362 | (smp->method == IB_MGMT_METHOD_SET || | 1349 | (smp->method == IB_MGMT_METHOD_SET || |
1363 | (smp->method == IB_MGMT_METHOD_GET && | 1350 | (smp->method == IB_MGMT_METHOD_GET && |
1364 | (dev->mkeyprot_resv_lmc >> 7) != 0))) { | 1351 | dev->mkeyprot >= 2))) { |
1365 | if (dev->mkey_violations != 0xFFFF) | 1352 | if (dev->mkey_violations != 0xFFFF) |
1366 | ++dev->mkey_violations; | 1353 | ++dev->mkey_violations; |
1367 | if (dev->mkey_lease_timeout || | 1354 | if (dev->mkey_lease_timeout || |
diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c index 1324b35ff1f8..6a41fdbc8e57 100644 --- a/drivers/infiniband/hw/ipath/ipath_qp.c +++ b/drivers/infiniband/hw/ipath/ipath_qp.c | |||
@@ -338,6 +338,7 @@ static void ipath_reset_qp(struct ipath_qp *qp) | |||
338 | qp->s_busy = 0; | 338 | qp->s_busy = 0; |
339 | qp->s_flags &= IPATH_S_SIGNAL_REQ_WR; | 339 | qp->s_flags &= IPATH_S_SIGNAL_REQ_WR; |
340 | qp->s_hdrwords = 0; | 340 | qp->s_hdrwords = 0; |
341 | qp->s_wqe = NULL; | ||
341 | qp->s_psn = 0; | 342 | qp->s_psn = 0; |
342 | qp->r_psn = 0; | 343 | qp->r_psn = 0; |
343 | qp->r_msn = 0; | 344 | qp->r_msn = 0; |
@@ -376,13 +377,15 @@ static void ipath_reset_qp(struct ipath_qp *qp) | |||
376 | * @err: the receive completion error to signal if a RWQE is active | 377 | * @err: the receive completion error to signal if a RWQE is active |
377 | * | 378 | * |
378 | * Flushes both send and receive work queues. | 379 | * Flushes both send and receive work queues. |
380 | * Returns true if last WQE event should be generated. | ||
379 | * The QP s_lock should be held and interrupts disabled. | 381 | * The QP s_lock should be held and interrupts disabled. |
380 | */ | 382 | */ |
381 | 383 | ||
382 | void ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err) | 384 | int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err) |
383 | { | 385 | { |
384 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | 386 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); |
385 | struct ib_wc wc; | 387 | struct ib_wc wc; |
388 | int ret = 0; | ||
386 | 389 | ||
387 | ipath_dbg("QP%d/%d in error state\n", | 390 | ipath_dbg("QP%d/%d in error state\n", |
388 | qp->ibqp.qp_num, qp->remote_qpn); | 391 | qp->ibqp.qp_num, qp->remote_qpn); |
@@ -453,7 +456,10 @@ void ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err) | |||
453 | wq->tail = tail; | 456 | wq->tail = tail; |
454 | 457 | ||
455 | spin_unlock(&qp->r_rq.lock); | 458 | spin_unlock(&qp->r_rq.lock); |
456 | } | 459 | } else if (qp->ibqp.event_handler) |
460 | ret = 1; | ||
461 | |||
462 | return ret; | ||
457 | } | 463 | } |
458 | 464 | ||
459 | /** | 465 | /** |
@@ -472,6 +478,7 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | |||
472 | struct ipath_qp *qp = to_iqp(ibqp); | 478 | struct ipath_qp *qp = to_iqp(ibqp); |
473 | enum ib_qp_state cur_state, new_state; | 479 | enum ib_qp_state cur_state, new_state; |
474 | unsigned long flags; | 480 | unsigned long flags; |
481 | int lastwqe = 0; | ||
475 | int ret; | 482 | int ret; |
476 | 483 | ||
477 | spin_lock_irqsave(&qp->s_lock, flags); | 484 | spin_lock_irqsave(&qp->s_lock, flags); |
@@ -531,7 +538,7 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | |||
531 | break; | 538 | break; |
532 | 539 | ||
533 | case IB_QPS_ERR: | 540 | case IB_QPS_ERR: |
534 | ipath_error_qp(qp, IB_WC_WR_FLUSH_ERR); | 541 | lastwqe = ipath_error_qp(qp, IB_WC_WR_FLUSH_ERR); |
535 | break; | 542 | break; |
536 | 543 | ||
537 | default: | 544 | default: |
@@ -590,6 +597,14 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | |||
590 | qp->state = new_state; | 597 | qp->state = new_state; |
591 | spin_unlock_irqrestore(&qp->s_lock, flags); | 598 | spin_unlock_irqrestore(&qp->s_lock, flags); |
592 | 599 | ||
600 | if (lastwqe) { | ||
601 | struct ib_event ev; | ||
602 | |||
603 | ev.device = qp->ibqp.device; | ||
604 | ev.element.qp = &qp->ibqp; | ||
605 | ev.event = IB_EVENT_QP_LAST_WQE_REACHED; | ||
606 | qp->ibqp.event_handler(&ev, qp->ibqp.qp_context); | ||
607 | } | ||
593 | ret = 0; | 608 | ret = 0; |
594 | goto bail; | 609 | goto bail; |
595 | 610 | ||
@@ -751,6 +766,9 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd, | |||
751 | switch (init_attr->qp_type) { | 766 | switch (init_attr->qp_type) { |
752 | case IB_QPT_UC: | 767 | case IB_QPT_UC: |
753 | case IB_QPT_RC: | 768 | case IB_QPT_RC: |
769 | case IB_QPT_UD: | ||
770 | case IB_QPT_SMI: | ||
771 | case IB_QPT_GSI: | ||
754 | sz = sizeof(struct ipath_sge) * | 772 | sz = sizeof(struct ipath_sge) * |
755 | init_attr->cap.max_send_sge + | 773 | init_attr->cap.max_send_sge + |
756 | sizeof(struct ipath_swqe); | 774 | sizeof(struct ipath_swqe); |
@@ -759,10 +777,6 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd, | |||
759 | ret = ERR_PTR(-ENOMEM); | 777 | ret = ERR_PTR(-ENOMEM); |
760 | goto bail; | 778 | goto bail; |
761 | } | 779 | } |
762 | /* FALLTHROUGH */ | ||
763 | case IB_QPT_UD: | ||
764 | case IB_QPT_SMI: | ||
765 | case IB_QPT_GSI: | ||
766 | sz = sizeof(*qp); | 780 | sz = sizeof(*qp); |
767 | if (init_attr->srq) { | 781 | if (init_attr->srq) { |
768 | struct ipath_srq *srq = to_isrq(init_attr->srq); | 782 | struct ipath_srq *srq = to_isrq(init_attr->srq); |
@@ -805,8 +819,7 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd, | |||
805 | spin_lock_init(&qp->r_rq.lock); | 819 | spin_lock_init(&qp->r_rq.lock); |
806 | atomic_set(&qp->refcount, 0); | 820 | atomic_set(&qp->refcount, 0); |
807 | init_waitqueue_head(&qp->wait); | 821 | init_waitqueue_head(&qp->wait); |
808 | tasklet_init(&qp->s_task, ipath_do_ruc_send, | 822 | tasklet_init(&qp->s_task, ipath_do_send, (unsigned long)qp); |
809 | (unsigned long)qp); | ||
810 | INIT_LIST_HEAD(&qp->piowait); | 823 | INIT_LIST_HEAD(&qp->piowait); |
811 | INIT_LIST_HEAD(&qp->timerwait); | 824 | INIT_LIST_HEAD(&qp->timerwait); |
812 | qp->state = IB_QPS_RESET; | 825 | qp->state = IB_QPS_RESET; |
diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c index 46744ea2babd..5c29b2bfea17 100644 --- a/drivers/infiniband/hw/ipath/ipath_rc.c +++ b/drivers/infiniband/hw/ipath/ipath_rc.c | |||
@@ -81,9 +81,8 @@ static void ipath_init_restart(struct ipath_qp *qp, struct ipath_swqe *wqe) | |||
81 | * Note that we are in the responder's side of the QP context. | 81 | * Note that we are in the responder's side of the QP context. |
82 | * Note the QP s_lock must be held. | 82 | * Note the QP s_lock must be held. |
83 | */ | 83 | */ |
84 | static int ipath_make_rc_ack(struct ipath_qp *qp, | 84 | static int ipath_make_rc_ack(struct ipath_ibdev *dev, struct ipath_qp *qp, |
85 | struct ipath_other_headers *ohdr, | 85 | struct ipath_other_headers *ohdr, u32 pmtu) |
86 | u32 pmtu, u32 *bth0p, u32 *bth2p) | ||
87 | { | 86 | { |
88 | struct ipath_ack_entry *e; | 87 | struct ipath_ack_entry *e; |
89 | u32 hwords; | 88 | u32 hwords; |
@@ -192,8 +191,7 @@ static int ipath_make_rc_ack(struct ipath_qp *qp, | |||
192 | } | 191 | } |
193 | qp->s_hdrwords = hwords; | 192 | qp->s_hdrwords = hwords; |
194 | qp->s_cur_size = len; | 193 | qp->s_cur_size = len; |
195 | *bth0p = bth0 | (1 << 22); /* Set M bit */ | 194 | ipath_make_ruc_header(dev, qp, ohdr, bth0, bth2); |
196 | *bth2p = bth2; | ||
197 | return 1; | 195 | return 1; |
198 | 196 | ||
199 | bail: | 197 | bail: |
@@ -203,32 +201,39 @@ bail: | |||
203 | /** | 201 | /** |
204 | * ipath_make_rc_req - construct a request packet (SEND, RDMA r/w, ATOMIC) | 202 | * ipath_make_rc_req - construct a request packet (SEND, RDMA r/w, ATOMIC) |
205 | * @qp: a pointer to the QP | 203 | * @qp: a pointer to the QP |
206 | * @ohdr: a pointer to the IB header being constructed | ||
207 | * @pmtu: the path MTU | ||
208 | * @bth0p: pointer to the BTH opcode word | ||
209 | * @bth2p: pointer to the BTH PSN word | ||
210 | * | 204 | * |
211 | * Return 1 if constructed; otherwise, return 0. | 205 | * Return 1 if constructed; otherwise, return 0. |
212 | * Note the QP s_lock must be held and interrupts disabled. | ||
213 | */ | 206 | */ |
214 | int ipath_make_rc_req(struct ipath_qp *qp, | 207 | int ipath_make_rc_req(struct ipath_qp *qp) |
215 | struct ipath_other_headers *ohdr, | ||
216 | u32 pmtu, u32 *bth0p, u32 *bth2p) | ||
217 | { | 208 | { |
218 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | 209 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); |
210 | struct ipath_other_headers *ohdr; | ||
219 | struct ipath_sge_state *ss; | 211 | struct ipath_sge_state *ss; |
220 | struct ipath_swqe *wqe; | 212 | struct ipath_swqe *wqe; |
221 | u32 hwords; | 213 | u32 hwords; |
222 | u32 len; | 214 | u32 len; |
223 | u32 bth0; | 215 | u32 bth0; |
224 | u32 bth2; | 216 | u32 bth2; |
217 | u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu); | ||
225 | char newreq; | 218 | char newreq; |
219 | unsigned long flags; | ||
220 | int ret = 0; | ||
221 | |||
222 | ohdr = &qp->s_hdr.u.oth; | ||
223 | if (qp->remote_ah_attr.ah_flags & IB_AH_GRH) | ||
224 | ohdr = &qp->s_hdr.u.l.oth; | ||
225 | |||
226 | /* | ||
227 | * The lock is needed to synchronize between the sending tasklet, | ||
228 | * the receive interrupt handler, and timeout resends. | ||
229 | */ | ||
230 | spin_lock_irqsave(&qp->s_lock, flags); | ||
226 | 231 | ||
227 | /* Sending responses has higher priority over sending requests. */ | 232 | /* Sending responses has higher priority over sending requests. */ |
228 | if ((qp->r_head_ack_queue != qp->s_tail_ack_queue || | 233 | if ((qp->r_head_ack_queue != qp->s_tail_ack_queue || |
229 | (qp->s_flags & IPATH_S_ACK_PENDING) || | 234 | (qp->s_flags & IPATH_S_ACK_PENDING) || |
230 | qp->s_ack_state != OP(ACKNOWLEDGE)) && | 235 | qp->s_ack_state != OP(ACKNOWLEDGE)) && |
231 | ipath_make_rc_ack(qp, ohdr, pmtu, bth0p, bth2p)) | 236 | ipath_make_rc_ack(dev, qp, ohdr, pmtu)) |
232 | goto done; | 237 | goto done; |
233 | 238 | ||
234 | if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK) || | 239 | if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK) || |
@@ -560,13 +565,12 @@ int ipath_make_rc_req(struct ipath_qp *qp, | |||
560 | qp->s_hdrwords = hwords; | 565 | qp->s_hdrwords = hwords; |
561 | qp->s_cur_sge = ss; | 566 | qp->s_cur_sge = ss; |
562 | qp->s_cur_size = len; | 567 | qp->s_cur_size = len; |
563 | *bth0p = bth0 | (qp->s_state << 24); | 568 | ipath_make_ruc_header(dev, qp, ohdr, bth0 | (qp->s_state << 24), bth2); |
564 | *bth2p = bth2; | ||
565 | done: | 569 | done: |
566 | return 1; | 570 | ret = 1; |
567 | |||
568 | bail: | 571 | bail: |
569 | return 0; | 572 | spin_unlock_irqrestore(&qp->s_lock, flags); |
573 | return ret; | ||
570 | } | 574 | } |
571 | 575 | ||
572 | /** | 576 | /** |
@@ -627,7 +631,7 @@ static void send_rc_ack(struct ipath_qp *qp) | |||
627 | /* | 631 | /* |
628 | * If we can send the ACK, clear the ACK state. | 632 | * If we can send the ACK, clear the ACK state. |
629 | */ | 633 | */ |
630 | if (ipath_verbs_send(dev->dd, hwords, (u32 *) &hdr, 0, NULL) == 0) { | 634 | if (ipath_verbs_send(qp, &hdr, hwords, NULL, 0) == 0) { |
631 | dev->n_unicast_xmit++; | 635 | dev->n_unicast_xmit++; |
632 | goto done; | 636 | goto done; |
633 | } | 637 | } |
@@ -757,7 +761,9 @@ void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc) | |||
757 | wc->vendor_err = 0; | 761 | wc->vendor_err = 0; |
758 | wc->byte_len = 0; | 762 | wc->byte_len = 0; |
759 | wc->qp = &qp->ibqp; | 763 | wc->qp = &qp->ibqp; |
764 | wc->imm_data = 0; | ||
760 | wc->src_qp = qp->remote_qpn; | 765 | wc->src_qp = qp->remote_qpn; |
766 | wc->wc_flags = 0; | ||
761 | wc->pkey_index = 0; | 767 | wc->pkey_index = 0; |
762 | wc->slid = qp->remote_ah_attr.dlid; | 768 | wc->slid = qp->remote_ah_attr.dlid; |
763 | wc->sl = qp->remote_ah_attr.sl; | 769 | wc->sl = qp->remote_ah_attr.sl; |
@@ -1041,7 +1047,9 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode, | |||
1041 | wc.vendor_err = 0; | 1047 | wc.vendor_err = 0; |
1042 | wc.byte_len = 0; | 1048 | wc.byte_len = 0; |
1043 | wc.qp = &qp->ibqp; | 1049 | wc.qp = &qp->ibqp; |
1050 | wc.imm_data = 0; | ||
1044 | wc.src_qp = qp->remote_qpn; | 1051 | wc.src_qp = qp->remote_qpn; |
1052 | wc.wc_flags = 0; | ||
1045 | wc.pkey_index = 0; | 1053 | wc.pkey_index = 0; |
1046 | wc.slid = qp->remote_ah_attr.dlid; | 1054 | wc.slid = qp->remote_ah_attr.dlid; |
1047 | wc.sl = qp->remote_ah_attr.sl; | 1055 | wc.sl = qp->remote_ah_attr.sl; |
@@ -1454,6 +1462,19 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev, | |||
1454 | goto send_ack; | 1462 | goto send_ack; |
1455 | } | 1463 | } |
1456 | /* | 1464 | /* |
1465 | * Try to send a simple ACK to work around a Mellanox bug | ||
1466 | * which doesn't accept a RDMA read response or atomic | ||
1467 | * response as an ACK for earlier SENDs or RDMA writes. | ||
1468 | */ | ||
1469 | if (qp->r_head_ack_queue == qp->s_tail_ack_queue && | ||
1470 | !(qp->s_flags & IPATH_S_ACK_PENDING) && | ||
1471 | qp->s_ack_state == OP(ACKNOWLEDGE)) { | ||
1472 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
1473 | qp->r_nak_state = 0; | ||
1474 | qp->r_ack_psn = qp->s_ack_queue[i].psn - 1; | ||
1475 | goto send_ack; | ||
1476 | } | ||
1477 | /* | ||
1457 | * Resend the RDMA read or atomic op which | 1478 | * Resend the RDMA read or atomic op which |
1458 | * ACKs this duplicate request. | 1479 | * ACKs this duplicate request. |
1459 | */ | 1480 | */ |
@@ -1476,11 +1497,21 @@ send_ack: | |||
1476 | static void ipath_rc_error(struct ipath_qp *qp, enum ib_wc_status err) | 1497 | static void ipath_rc_error(struct ipath_qp *qp, enum ib_wc_status err) |
1477 | { | 1498 | { |
1478 | unsigned long flags; | 1499 | unsigned long flags; |
1500 | int lastwqe; | ||
1479 | 1501 | ||
1480 | spin_lock_irqsave(&qp->s_lock, flags); | 1502 | spin_lock_irqsave(&qp->s_lock, flags); |
1481 | qp->state = IB_QPS_ERR; | 1503 | qp->state = IB_QPS_ERR; |
1482 | ipath_error_qp(qp, err); | 1504 | lastwqe = ipath_error_qp(qp, err); |
1483 | spin_unlock_irqrestore(&qp->s_lock, flags); | 1505 | spin_unlock_irqrestore(&qp->s_lock, flags); |
1506 | |||
1507 | if (lastwqe) { | ||
1508 | struct ib_event ev; | ||
1509 | |||
1510 | ev.device = qp->ibqp.device; | ||
1511 | ev.element.qp = &qp->ibqp; | ||
1512 | ev.event = IB_EVENT_QP_LAST_WQE_REACHED; | ||
1513 | qp->ibqp.event_handler(&ev, qp->ibqp.qp_context); | ||
1514 | } | ||
1484 | } | 1515 | } |
1485 | 1516 | ||
1486 | static inline void ipath_update_ack_queue(struct ipath_qp *qp, unsigned n) | 1517 | static inline void ipath_update_ack_queue(struct ipath_qp *qp, unsigned n) |
diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c b/drivers/infiniband/hw/ipath/ipath_ruc.c index c69c25239443..4b6b7ee8e5c1 100644 --- a/drivers/infiniband/hw/ipath/ipath_ruc.c +++ b/drivers/infiniband/hw/ipath/ipath_ruc.c | |||
@@ -31,6 +31,8 @@ | |||
31 | * SOFTWARE. | 31 | * SOFTWARE. |
32 | */ | 32 | */ |
33 | 33 | ||
34 | #include <linux/spinlock.h> | ||
35 | |||
34 | #include "ipath_verbs.h" | 36 | #include "ipath_verbs.h" |
35 | #include "ipath_kernel.h" | 37 | #include "ipath_kernel.h" |
36 | 38 | ||
@@ -106,27 +108,30 @@ void ipath_insert_rnr_queue(struct ipath_qp *qp) | |||
106 | spin_unlock_irqrestore(&dev->pending_lock, flags); | 108 | spin_unlock_irqrestore(&dev->pending_lock, flags); |
107 | } | 109 | } |
108 | 110 | ||
109 | static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe) | 111 | /** |
112 | * ipath_init_sge - Validate a RWQE and fill in the SGE state | ||
113 | * @qp: the QP | ||
114 | * | ||
115 | * Return 1 if OK. | ||
116 | */ | ||
117 | int ipath_init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe, | ||
118 | u32 *lengthp, struct ipath_sge_state *ss) | ||
110 | { | 119 | { |
111 | int user = to_ipd(qp->ibqp.pd)->user; | ||
112 | int i, j, ret; | 120 | int i, j, ret; |
113 | struct ib_wc wc; | 121 | struct ib_wc wc; |
114 | 122 | ||
115 | qp->r_len = 0; | 123 | *lengthp = 0; |
116 | for (i = j = 0; i < wqe->num_sge; i++) { | 124 | for (i = j = 0; i < wqe->num_sge; i++) { |
117 | if (wqe->sg_list[i].length == 0) | 125 | if (wqe->sg_list[i].length == 0) |
118 | continue; | 126 | continue; |
119 | /* Check LKEY */ | 127 | /* Check LKEY */ |
120 | if ((user && wqe->sg_list[i].lkey == 0) || | 128 | if (!ipath_lkey_ok(qp, j ? &ss->sg_list[j - 1] : &ss->sge, |
121 | !ipath_lkey_ok(qp, &qp->r_sg_list[j], &wqe->sg_list[i], | 129 | &wqe->sg_list[i], IB_ACCESS_LOCAL_WRITE)) |
122 | IB_ACCESS_LOCAL_WRITE)) | ||
123 | goto bad_lkey; | 130 | goto bad_lkey; |
124 | qp->r_len += wqe->sg_list[i].length; | 131 | *lengthp += wqe->sg_list[i].length; |
125 | j++; | 132 | j++; |
126 | } | 133 | } |
127 | qp->r_sge.sge = qp->r_sg_list[0]; | 134 | ss->num_sge = j; |
128 | qp->r_sge.sg_list = qp->r_sg_list + 1; | ||
129 | qp->r_sge.num_sge = j; | ||
130 | ret = 1; | 135 | ret = 1; |
131 | goto bail; | 136 | goto bail; |
132 | 137 | ||
@@ -172,6 +177,8 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only) | |||
172 | u32 tail; | 177 | u32 tail; |
173 | int ret; | 178 | int ret; |
174 | 179 | ||
180 | qp->r_sge.sg_list = qp->r_sg_list; | ||
181 | |||
175 | if (qp->ibqp.srq) { | 182 | if (qp->ibqp.srq) { |
176 | srq = to_isrq(qp->ibqp.srq); | 183 | srq = to_isrq(qp->ibqp.srq); |
177 | handler = srq->ibsrq.event_handler; | 184 | handler = srq->ibsrq.event_handler; |
@@ -199,7 +206,8 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only) | |||
199 | wqe = get_rwqe_ptr(rq, tail); | 206 | wqe = get_rwqe_ptr(rq, tail); |
200 | if (++tail >= rq->size) | 207 | if (++tail >= rq->size) |
201 | tail = 0; | 208 | tail = 0; |
202 | } while (!wr_id_only && !init_sge(qp, wqe)); | 209 | } while (!wr_id_only && !ipath_init_sge(qp, wqe, &qp->r_len, |
210 | &qp->r_sge)); | ||
203 | qp->r_wr_id = wqe->wr_id; | 211 | qp->r_wr_id = wqe->wr_id; |
204 | wq->tail = tail; | 212 | wq->tail = tail; |
205 | 213 | ||
@@ -239,9 +247,9 @@ bail: | |||
239 | 247 | ||
240 | /** | 248 | /** |
241 | * ipath_ruc_loopback - handle UC and RC lookback requests | 249 | * ipath_ruc_loopback - handle UC and RC lookback requests |
242 | * @sqp: the loopback QP | 250 | * @sqp: the sending QP |
243 | * | 251 | * |
244 | * This is called from ipath_do_uc_send() or ipath_do_rc_send() to | 252 | * This is called from ipath_do_send() to |
245 | * forward a WQE addressed to the same HCA. | 253 | * forward a WQE addressed to the same HCA. |
246 | * Note that although we are single threaded due to the tasklet, we still | 254 | * Note that although we are single threaded due to the tasklet, we still |
247 | * have to protect against post_send(). We don't have to worry about | 255 | * have to protect against post_send(). We don't have to worry about |
@@ -450,40 +458,18 @@ again: | |||
450 | wc.byte_len = wqe->length; | 458 | wc.byte_len = wqe->length; |
451 | wc.qp = &qp->ibqp; | 459 | wc.qp = &qp->ibqp; |
452 | wc.src_qp = qp->remote_qpn; | 460 | wc.src_qp = qp->remote_qpn; |
453 | /* XXX do we know which pkey matched? Only needed for GSI. */ | ||
454 | wc.pkey_index = 0; | 461 | wc.pkey_index = 0; |
455 | wc.slid = qp->remote_ah_attr.dlid; | 462 | wc.slid = qp->remote_ah_attr.dlid; |
456 | wc.sl = qp->remote_ah_attr.sl; | 463 | wc.sl = qp->remote_ah_attr.sl; |
457 | wc.dlid_path_bits = 0; | 464 | wc.dlid_path_bits = 0; |
465 | wc.port_num = 1; | ||
458 | /* Signal completion event if the solicited bit is set. */ | 466 | /* Signal completion event if the solicited bit is set. */ |
459 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, | 467 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, |
460 | wqe->wr.send_flags & IB_SEND_SOLICITED); | 468 | wqe->wr.send_flags & IB_SEND_SOLICITED); |
461 | 469 | ||
462 | send_comp: | 470 | send_comp: |
463 | sqp->s_rnr_retry = sqp->s_rnr_retry_cnt; | 471 | sqp->s_rnr_retry = sqp->s_rnr_retry_cnt; |
464 | 472 | ipath_send_complete(sqp, wqe, IB_WC_SUCCESS); | |
465 | if (!(sqp->s_flags & IPATH_S_SIGNAL_REQ_WR) || | ||
466 | (wqe->wr.send_flags & IB_SEND_SIGNALED)) { | ||
467 | wc.wr_id = wqe->wr.wr_id; | ||
468 | wc.status = IB_WC_SUCCESS; | ||
469 | wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; | ||
470 | wc.vendor_err = 0; | ||
471 | wc.byte_len = wqe->length; | ||
472 | wc.qp = &sqp->ibqp; | ||
473 | wc.src_qp = 0; | ||
474 | wc.pkey_index = 0; | ||
475 | wc.slid = 0; | ||
476 | wc.sl = 0; | ||
477 | wc.dlid_path_bits = 0; | ||
478 | wc.port_num = 0; | ||
479 | ipath_cq_enter(to_icq(sqp->ibqp.send_cq), &wc, 0); | ||
480 | } | ||
481 | |||
482 | /* Update s_last now that we are finished with the SWQE */ | ||
483 | spin_lock_irqsave(&sqp->s_lock, flags); | ||
484 | if (++sqp->s_last >= sqp->s_size) | ||
485 | sqp->s_last = 0; | ||
486 | spin_unlock_irqrestore(&sqp->s_lock, flags); | ||
487 | goto again; | 473 | goto again; |
488 | 474 | ||
489 | done: | 475 | done: |
@@ -491,13 +477,11 @@ done: | |||
491 | wake_up(&qp->wait); | 477 | wake_up(&qp->wait); |
492 | } | 478 | } |
493 | 479 | ||
494 | static int want_buffer(struct ipath_devdata *dd) | 480 | static void want_buffer(struct ipath_devdata *dd) |
495 | { | 481 | { |
496 | set_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl); | 482 | set_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl); |
497 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | 483 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, |
498 | dd->ipath_sendctrl); | 484 | dd->ipath_sendctrl); |
499 | |||
500 | return 0; | ||
501 | } | 485 | } |
502 | 486 | ||
503 | /** | 487 | /** |
@@ -507,14 +491,11 @@ static int want_buffer(struct ipath_devdata *dd) | |||
507 | * | 491 | * |
508 | * Called when we run out of PIO buffers. | 492 | * Called when we run out of PIO buffers. |
509 | */ | 493 | */ |
510 | static void ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev) | 494 | static void ipath_no_bufs_available(struct ipath_qp *qp, |
495 | struct ipath_ibdev *dev) | ||
511 | { | 496 | { |
512 | unsigned long flags; | 497 | unsigned long flags; |
513 | 498 | ||
514 | spin_lock_irqsave(&dev->pending_lock, flags); | ||
515 | if (list_empty(&qp->piowait)) | ||
516 | list_add_tail(&qp->piowait, &dev->piowait); | ||
517 | spin_unlock_irqrestore(&dev->pending_lock, flags); | ||
518 | /* | 499 | /* |
519 | * Note that as soon as want_buffer() is called and | 500 | * Note that as soon as want_buffer() is called and |
520 | * possibly before it returns, ipath_ib_piobufavail() | 501 | * possibly before it returns, ipath_ib_piobufavail() |
@@ -524,101 +505,14 @@ static void ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev | |||
524 | * We leave the busy flag set so that another post send doesn't | 505 | * We leave the busy flag set so that another post send doesn't |
525 | * try to put the same QP on the piowait list again. | 506 | * try to put the same QP on the piowait list again. |
526 | */ | 507 | */ |
508 | spin_lock_irqsave(&dev->pending_lock, flags); | ||
509 | list_add_tail(&qp->piowait, &dev->piowait); | ||
510 | spin_unlock_irqrestore(&dev->pending_lock, flags); | ||
527 | want_buffer(dev->dd); | 511 | want_buffer(dev->dd); |
528 | dev->n_piowait++; | 512 | dev->n_piowait++; |
529 | } | 513 | } |
530 | 514 | ||
531 | /** | 515 | /** |
532 | * ipath_post_ruc_send - post RC and UC sends | ||
533 | * @qp: the QP to post on | ||
534 | * @wr: the work request to send | ||
535 | */ | ||
536 | int ipath_post_ruc_send(struct ipath_qp *qp, struct ib_send_wr *wr) | ||
537 | { | ||
538 | struct ipath_swqe *wqe; | ||
539 | unsigned long flags; | ||
540 | u32 next; | ||
541 | int i, j; | ||
542 | int acc; | ||
543 | int ret; | ||
544 | |||
545 | /* | ||
546 | * Don't allow RDMA reads or atomic operations on UC or | ||
547 | * undefined operations. | ||
548 | * Make sure buffer is large enough to hold the result for atomics. | ||
549 | */ | ||
550 | if (qp->ibqp.qp_type == IB_QPT_UC) { | ||
551 | if ((unsigned) wr->opcode >= IB_WR_RDMA_READ) { | ||
552 | ret = -EINVAL; | ||
553 | goto bail; | ||
554 | } | ||
555 | } else if ((unsigned) wr->opcode > IB_WR_ATOMIC_FETCH_AND_ADD) { | ||
556 | ret = -EINVAL; | ||
557 | goto bail; | ||
558 | } else if (wr->opcode >= IB_WR_ATOMIC_CMP_AND_SWP && | ||
559 | (wr->num_sge == 0 || | ||
560 | wr->sg_list[0].length < sizeof(u64) || | ||
561 | wr->sg_list[0].addr & (sizeof(u64) - 1))) { | ||
562 | ret = -EINVAL; | ||
563 | goto bail; | ||
564 | } else if (wr->opcode >= IB_WR_RDMA_READ && !qp->s_max_rd_atomic) { | ||
565 | ret = -EINVAL; | ||
566 | goto bail; | ||
567 | } | ||
568 | /* IB spec says that num_sge == 0 is OK. */ | ||
569 | if (wr->num_sge > qp->s_max_sge) { | ||
570 | ret = -ENOMEM; | ||
571 | goto bail; | ||
572 | } | ||
573 | spin_lock_irqsave(&qp->s_lock, flags); | ||
574 | next = qp->s_head + 1; | ||
575 | if (next >= qp->s_size) | ||
576 | next = 0; | ||
577 | if (next == qp->s_last) { | ||
578 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
579 | ret = -EINVAL; | ||
580 | goto bail; | ||
581 | } | ||
582 | |||
583 | wqe = get_swqe_ptr(qp, qp->s_head); | ||
584 | wqe->wr = *wr; | ||
585 | wqe->ssn = qp->s_ssn++; | ||
586 | wqe->sg_list[0].mr = NULL; | ||
587 | wqe->sg_list[0].vaddr = NULL; | ||
588 | wqe->sg_list[0].length = 0; | ||
589 | wqe->sg_list[0].sge_length = 0; | ||
590 | wqe->length = 0; | ||
591 | acc = wr->opcode >= IB_WR_RDMA_READ ? IB_ACCESS_LOCAL_WRITE : 0; | ||
592 | for (i = 0, j = 0; i < wr->num_sge; i++) { | ||
593 | if (to_ipd(qp->ibqp.pd)->user && wr->sg_list[i].lkey == 0) { | ||
594 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
595 | ret = -EINVAL; | ||
596 | goto bail; | ||
597 | } | ||
598 | if (wr->sg_list[i].length == 0) | ||
599 | continue; | ||
600 | if (!ipath_lkey_ok(qp, &wqe->sg_list[j], &wr->sg_list[i], | ||
601 | acc)) { | ||
602 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
603 | ret = -EINVAL; | ||
604 | goto bail; | ||
605 | } | ||
606 | wqe->length += wr->sg_list[i].length; | ||
607 | j++; | ||
608 | } | ||
609 | wqe->wr.num_sge = j; | ||
610 | qp->s_head = next; | ||
611 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
612 | |||
613 | ipath_do_ruc_send((unsigned long) qp); | ||
614 | |||
615 | ret = 0; | ||
616 | |||
617 | bail: | ||
618 | return ret; | ||
619 | } | ||
620 | |||
621 | /** | ||
622 | * ipath_make_grh - construct a GRH header | 516 | * ipath_make_grh - construct a GRH header |
623 | * @dev: a pointer to the ipath device | 517 | * @dev: a pointer to the ipath device |
624 | * @hdr: a pointer to the GRH header being constructed | 518 | * @hdr: a pointer to the GRH header being constructed |
@@ -648,39 +542,66 @@ u32 ipath_make_grh(struct ipath_ibdev *dev, struct ib_grh *hdr, | |||
648 | return sizeof(struct ib_grh) / sizeof(u32); | 542 | return sizeof(struct ib_grh) / sizeof(u32); |
649 | } | 543 | } |
650 | 544 | ||
545 | void ipath_make_ruc_header(struct ipath_ibdev *dev, struct ipath_qp *qp, | ||
546 | struct ipath_other_headers *ohdr, | ||
547 | u32 bth0, u32 bth2) | ||
548 | { | ||
549 | u16 lrh0; | ||
550 | u32 nwords; | ||
551 | u32 extra_bytes; | ||
552 | |||
553 | /* Construct the header. */ | ||
554 | extra_bytes = -qp->s_cur_size & 3; | ||
555 | nwords = (qp->s_cur_size + extra_bytes) >> 2; | ||
556 | lrh0 = IPATH_LRH_BTH; | ||
557 | if (unlikely(qp->remote_ah_attr.ah_flags & IB_AH_GRH)) { | ||
558 | qp->s_hdrwords += ipath_make_grh(dev, &qp->s_hdr.u.l.grh, | ||
559 | &qp->remote_ah_attr.grh, | ||
560 | qp->s_hdrwords, nwords); | ||
561 | lrh0 = IPATH_LRH_GRH; | ||
562 | } | ||
563 | lrh0 |= qp->remote_ah_attr.sl << 4; | ||
564 | qp->s_hdr.lrh[0] = cpu_to_be16(lrh0); | ||
565 | qp->s_hdr.lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid); | ||
566 | qp->s_hdr.lrh[2] = cpu_to_be16(qp->s_hdrwords + nwords + SIZE_OF_CRC); | ||
567 | qp->s_hdr.lrh[3] = cpu_to_be16(dev->dd->ipath_lid); | ||
568 | bth0 |= ipath_get_pkey(dev->dd, qp->s_pkey_index); | ||
569 | bth0 |= extra_bytes << 20; | ||
570 | ohdr->bth[0] = cpu_to_be32(bth0 | (1 << 22)); | ||
571 | ohdr->bth[1] = cpu_to_be32(qp->remote_qpn); | ||
572 | ohdr->bth[2] = cpu_to_be32(bth2); | ||
573 | } | ||
574 | |||
651 | /** | 575 | /** |
652 | * ipath_do_ruc_send - perform a send on an RC or UC QP | 576 | * ipath_do_send - perform a send on a QP |
653 | * @data: contains a pointer to the QP | 577 | * @data: contains a pointer to the QP |
654 | * | 578 | * |
655 | * Process entries in the send work queue until credit or queue is | 579 | * Process entries in the send work queue until credit or queue is |
656 | * exhausted. Only allow one CPU to send a packet per QP (tasklet). | 580 | * exhausted. Only allow one CPU to send a packet per QP (tasklet). |
657 | * Otherwise, after we drop the QP s_lock, two threads could send | 581 | * Otherwise, two threads could send packets out of order. |
658 | * packets out of order. | ||
659 | */ | 582 | */ |
660 | void ipath_do_ruc_send(unsigned long data) | 583 | void ipath_do_send(unsigned long data) |
661 | { | 584 | { |
662 | struct ipath_qp *qp = (struct ipath_qp *)data; | 585 | struct ipath_qp *qp = (struct ipath_qp *)data; |
663 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | 586 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); |
664 | unsigned long flags; | 587 | int (*make_req)(struct ipath_qp *qp); |
665 | u16 lrh0; | ||
666 | u32 nwords; | ||
667 | u32 extra_bytes; | ||
668 | u32 bth0; | ||
669 | u32 bth2; | ||
670 | u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu); | ||
671 | struct ipath_other_headers *ohdr; | ||
672 | 588 | ||
673 | if (test_and_set_bit(IPATH_S_BUSY, &qp->s_busy)) | 589 | if (test_and_set_bit(IPATH_S_BUSY, &qp->s_busy)) |
674 | goto bail; | 590 | goto bail; |
675 | 591 | ||
676 | if (unlikely(qp->remote_ah_attr.dlid == dev->dd->ipath_lid)) { | 592 | if ((qp->ibqp.qp_type == IB_QPT_RC || |
593 | qp->ibqp.qp_type == IB_QPT_UC) && | ||
594 | qp->remote_ah_attr.dlid == dev->dd->ipath_lid) { | ||
677 | ipath_ruc_loopback(qp); | 595 | ipath_ruc_loopback(qp); |
678 | goto clear; | 596 | goto clear; |
679 | } | 597 | } |
680 | 598 | ||
681 | ohdr = &qp->s_hdr.u.oth; | 599 | if (qp->ibqp.qp_type == IB_QPT_RC) |
682 | if (qp->remote_ah_attr.ah_flags & IB_AH_GRH) | 600 | make_req = ipath_make_rc_req; |
683 | ohdr = &qp->s_hdr.u.l.oth; | 601 | else if (qp->ibqp.qp_type == IB_QPT_UC) |
602 | make_req = ipath_make_uc_req; | ||
603 | else | ||
604 | make_req = ipath_make_ud_req; | ||
684 | 605 | ||
685 | again: | 606 | again: |
686 | /* Check for a constructed packet to be sent. */ | 607 | /* Check for a constructed packet to be sent. */ |
@@ -689,9 +610,8 @@ again: | |||
689 | * If no PIO bufs are available, return. An interrupt will | 610 | * If no PIO bufs are available, return. An interrupt will |
690 | * call ipath_ib_piobufavail() when one is available. | 611 | * call ipath_ib_piobufavail() when one is available. |
691 | */ | 612 | */ |
692 | if (ipath_verbs_send(dev->dd, qp->s_hdrwords, | 613 | if (ipath_verbs_send(qp, &qp->s_hdr, qp->s_hdrwords, |
693 | (u32 *) &qp->s_hdr, qp->s_cur_size, | 614 | qp->s_cur_sge, qp->s_cur_size)) { |
694 | qp->s_cur_sge)) { | ||
695 | ipath_no_bufs_available(qp, dev); | 615 | ipath_no_bufs_available(qp, dev); |
696 | goto bail; | 616 | goto bail; |
697 | } | 617 | } |
@@ -700,54 +620,42 @@ again: | |||
700 | qp->s_hdrwords = 0; | 620 | qp->s_hdrwords = 0; |
701 | } | 621 | } |
702 | 622 | ||
703 | /* | 623 | if (make_req(qp)) |
704 | * The lock is needed to synchronize between setting | 624 | goto again; |
705 | * qp->s_ack_state, resend timer, and post_send(). | 625 | clear: |
706 | */ | 626 | clear_bit(IPATH_S_BUSY, &qp->s_busy); |
707 | spin_lock_irqsave(&qp->s_lock, flags); | 627 | bail:; |
708 | 628 | } | |
709 | if (!((qp->ibqp.qp_type == IB_QPT_RC) ? | ||
710 | ipath_make_rc_req(qp, ohdr, pmtu, &bth0, &bth2) : | ||
711 | ipath_make_uc_req(qp, ohdr, pmtu, &bth0, &bth2))) { | ||
712 | /* | ||
713 | * Clear the busy bit before unlocking to avoid races with | ||
714 | * adding new work queue items and then failing to process | ||
715 | * them. | ||
716 | */ | ||
717 | clear_bit(IPATH_S_BUSY, &qp->s_busy); | ||
718 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
719 | goto bail; | ||
720 | } | ||
721 | 629 | ||
722 | spin_unlock_irqrestore(&qp->s_lock, flags); | 630 | void ipath_send_complete(struct ipath_qp *qp, struct ipath_swqe *wqe, |
631 | enum ib_wc_status status) | ||
632 | { | ||
633 | u32 last = qp->s_last; | ||
723 | 634 | ||
724 | /* Construct the header. */ | 635 | if (++last == qp->s_size) |
725 | extra_bytes = (4 - qp->s_cur_size) & 3; | 636 | last = 0; |
726 | nwords = (qp->s_cur_size + extra_bytes) >> 2; | 637 | qp->s_last = last; |
727 | lrh0 = IPATH_LRH_BTH; | ||
728 | if (unlikely(qp->remote_ah_attr.ah_flags & IB_AH_GRH)) { | ||
729 | qp->s_hdrwords += ipath_make_grh(dev, &qp->s_hdr.u.l.grh, | ||
730 | &qp->remote_ah_attr.grh, | ||
731 | qp->s_hdrwords, nwords); | ||
732 | lrh0 = IPATH_LRH_GRH; | ||
733 | } | ||
734 | lrh0 |= qp->remote_ah_attr.sl << 4; | ||
735 | qp->s_hdr.lrh[0] = cpu_to_be16(lrh0); | ||
736 | qp->s_hdr.lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid); | ||
737 | qp->s_hdr.lrh[2] = cpu_to_be16(qp->s_hdrwords + nwords + | ||
738 | SIZE_OF_CRC); | ||
739 | qp->s_hdr.lrh[3] = cpu_to_be16(dev->dd->ipath_lid); | ||
740 | bth0 |= ipath_get_pkey(dev->dd, qp->s_pkey_index); | ||
741 | bth0 |= extra_bytes << 20; | ||
742 | ohdr->bth[0] = cpu_to_be32(bth0); | ||
743 | ohdr->bth[1] = cpu_to_be32(qp->remote_qpn); | ||
744 | ohdr->bth[2] = cpu_to_be32(bth2); | ||
745 | 638 | ||
746 | /* Check for more work to do. */ | 639 | /* See ch. 11.2.4.1 and 10.7.3.1 */ |
747 | goto again; | 640 | if (!(qp->s_flags & IPATH_S_SIGNAL_REQ_WR) || |
641 | (wqe->wr.send_flags & IB_SEND_SIGNALED) || | ||
642 | status != IB_WC_SUCCESS) { | ||
643 | struct ib_wc wc; | ||
748 | 644 | ||
749 | clear: | 645 | wc.wr_id = wqe->wr.wr_id; |
750 | clear_bit(IPATH_S_BUSY, &qp->s_busy); | 646 | wc.status = status; |
751 | bail: | 647 | wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; |
752 | return; | 648 | wc.vendor_err = 0; |
649 | wc.byte_len = wqe->length; | ||
650 | wc.imm_data = 0; | ||
651 | wc.qp = &qp->ibqp; | ||
652 | wc.src_qp = 0; | ||
653 | wc.wc_flags = 0; | ||
654 | wc.pkey_index = 0; | ||
655 | wc.slid = 0; | ||
656 | wc.sl = 0; | ||
657 | wc.dlid_path_bits = 0; | ||
658 | wc.port_num = 0; | ||
659 | ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 0); | ||
660 | } | ||
753 | } | 661 | } |
diff --git a/drivers/infiniband/hw/ipath/ipath_stats.c b/drivers/infiniband/hw/ipath/ipath_stats.c index bae4f56f7271..f0271415cd5b 100644 --- a/drivers/infiniband/hw/ipath/ipath_stats.c +++ b/drivers/infiniband/hw/ipath/ipath_stats.c | |||
@@ -55,7 +55,6 @@ u64 ipath_snap_cntr(struct ipath_devdata *dd, ipath_creg creg) | |||
55 | u64 val64; | 55 | u64 val64; |
56 | unsigned long t0, t1; | 56 | unsigned long t0, t1; |
57 | u64 ret; | 57 | u64 ret; |
58 | unsigned long flags; | ||
59 | 58 | ||
60 | t0 = jiffies; | 59 | t0 = jiffies; |
61 | /* If fast increment counters are only 32 bits, snapshot them, | 60 | /* If fast increment counters are only 32 bits, snapshot them, |
@@ -92,18 +91,12 @@ u64 ipath_snap_cntr(struct ipath_devdata *dd, ipath_creg creg) | |||
92 | if (creg == dd->ipath_cregs->cr_wordsendcnt) { | 91 | if (creg == dd->ipath_cregs->cr_wordsendcnt) { |
93 | if (val != dd->ipath_lastsword) { | 92 | if (val != dd->ipath_lastsword) { |
94 | dd->ipath_sword += val - dd->ipath_lastsword; | 93 | dd->ipath_sword += val - dd->ipath_lastsword; |
95 | spin_lock_irqsave(&dd->ipath_eep_st_lock, flags); | ||
96 | dd->ipath_traffic_wds += val - dd->ipath_lastsword; | ||
97 | spin_unlock_irqrestore(&dd->ipath_eep_st_lock, flags); | ||
98 | dd->ipath_lastsword = val; | 94 | dd->ipath_lastsword = val; |
99 | } | 95 | } |
100 | val64 = dd->ipath_sword; | 96 | val64 = dd->ipath_sword; |
101 | } else if (creg == dd->ipath_cregs->cr_wordrcvcnt) { | 97 | } else if (creg == dd->ipath_cregs->cr_wordrcvcnt) { |
102 | if (val != dd->ipath_lastrword) { | 98 | if (val != dd->ipath_lastrword) { |
103 | dd->ipath_rword += val - dd->ipath_lastrword; | 99 | dd->ipath_rword += val - dd->ipath_lastrword; |
104 | spin_lock_irqsave(&dd->ipath_eep_st_lock, flags); | ||
105 | dd->ipath_traffic_wds += val - dd->ipath_lastrword; | ||
106 | spin_unlock_irqrestore(&dd->ipath_eep_st_lock, flags); | ||
107 | dd->ipath_lastrword = val; | 100 | dd->ipath_lastrword = val; |
108 | } | 101 | } |
109 | val64 = dd->ipath_rword; | 102 | val64 = dd->ipath_rword; |
@@ -247,6 +240,7 @@ void ipath_get_faststats(unsigned long opaque) | |||
247 | u32 val; | 240 | u32 val; |
248 | static unsigned cnt; | 241 | static unsigned cnt; |
249 | unsigned long flags; | 242 | unsigned long flags; |
243 | u64 traffic_wds; | ||
250 | 244 | ||
251 | /* | 245 | /* |
252 | * don't access the chip while running diags, or memory diags can | 246 | * don't access the chip while running diags, or memory diags can |
@@ -262,12 +256,13 @@ void ipath_get_faststats(unsigned long opaque) | |||
262 | * exceeding a threshold, so we need to check the word-counts | 256 | * exceeding a threshold, so we need to check the word-counts |
263 | * even if they are 64-bit. | 257 | * even if they are 64-bit. |
264 | */ | 258 | */ |
265 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordsendcnt); | 259 | traffic_wds = ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordsendcnt) + |
266 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordrcvcnt); | 260 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordrcvcnt); |
267 | spin_lock_irqsave(&dd->ipath_eep_st_lock, flags); | 261 | spin_lock_irqsave(&dd->ipath_eep_st_lock, flags); |
268 | if (dd->ipath_traffic_wds >= IPATH_TRAFFIC_ACTIVE_THRESHOLD) | 262 | traffic_wds -= dd->ipath_traffic_wds; |
263 | dd->ipath_traffic_wds += traffic_wds; | ||
264 | if (traffic_wds >= IPATH_TRAFFIC_ACTIVE_THRESHOLD) | ||
269 | atomic_add(5, &dd->ipath_active_time); /* S/B #define */ | 265 | atomic_add(5, &dd->ipath_active_time); /* S/B #define */ |
270 | dd->ipath_traffic_wds = 0; | ||
271 | spin_unlock_irqrestore(&dd->ipath_eep_st_lock, flags); | 266 | spin_unlock_irqrestore(&dd->ipath_eep_st_lock, flags); |
272 | 267 | ||
273 | if (dd->ipath_flags & IPATH_32BITCOUNTERS) { | 268 | if (dd->ipath_flags & IPATH_32BITCOUNTERS) { |
diff --git a/drivers/infiniband/hw/ipath/ipath_sysfs.c b/drivers/infiniband/hw/ipath/ipath_sysfs.c index 16238cd3a036..e1ad7cfc21fd 100644 --- a/drivers/infiniband/hw/ipath/ipath_sysfs.c +++ b/drivers/infiniband/hw/ipath/ipath_sysfs.c | |||
@@ -163,6 +163,42 @@ static ssize_t show_boardversion(struct device *dev, | |||
163 | return scnprintf(buf, PAGE_SIZE, "%s", dd->ipath_boardversion); | 163 | return scnprintf(buf, PAGE_SIZE, "%s", dd->ipath_boardversion); |
164 | } | 164 | } |
165 | 165 | ||
166 | static ssize_t show_lmc(struct device *dev, | ||
167 | struct device_attribute *attr, | ||
168 | char *buf) | ||
169 | { | ||
170 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
171 | |||
172 | return scnprintf(buf, PAGE_SIZE, "%u\n", dd->ipath_lmc); | ||
173 | } | ||
174 | |||
175 | static ssize_t store_lmc(struct device *dev, | ||
176 | struct device_attribute *attr, | ||
177 | const char *buf, | ||
178 | size_t count) | ||
179 | { | ||
180 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
181 | u16 lmc = 0; | ||
182 | int ret; | ||
183 | |||
184 | ret = ipath_parse_ushort(buf, &lmc); | ||
185 | if (ret < 0) | ||
186 | goto invalid; | ||
187 | |||
188 | if (lmc > 7) { | ||
189 | ret = -EINVAL; | ||
190 | goto invalid; | ||
191 | } | ||
192 | |||
193 | ipath_set_lid(dd, dd->ipath_lid, lmc); | ||
194 | |||
195 | goto bail; | ||
196 | invalid: | ||
197 | ipath_dev_err(dd, "attempt to set invalid LMC %u\n", lmc); | ||
198 | bail: | ||
199 | return ret; | ||
200 | } | ||
201 | |||
166 | static ssize_t show_lid(struct device *dev, | 202 | static ssize_t show_lid(struct device *dev, |
167 | struct device_attribute *attr, | 203 | struct device_attribute *attr, |
168 | char *buf) | 204 | char *buf) |
@@ -190,7 +226,7 @@ static ssize_t store_lid(struct device *dev, | |||
190 | goto invalid; | 226 | goto invalid; |
191 | } | 227 | } |
192 | 228 | ||
193 | ipath_set_lid(dd, lid, 0); | 229 | ipath_set_lid(dd, lid, dd->ipath_lmc); |
194 | 230 | ||
195 | goto bail; | 231 | goto bail; |
196 | invalid: | 232 | invalid: |
@@ -648,6 +684,7 @@ static struct attribute_group driver_attr_group = { | |||
648 | }; | 684 | }; |
649 | 685 | ||
650 | static DEVICE_ATTR(guid, S_IWUSR | S_IRUGO, show_guid, store_guid); | 686 | static DEVICE_ATTR(guid, S_IWUSR | S_IRUGO, show_guid, store_guid); |
687 | static DEVICE_ATTR(lmc, S_IWUSR | S_IRUGO, show_lmc, store_lmc); | ||
651 | static DEVICE_ATTR(lid, S_IWUSR | S_IRUGO, show_lid, store_lid); | 688 | static DEVICE_ATTR(lid, S_IWUSR | S_IRUGO, show_lid, store_lid); |
652 | static DEVICE_ATTR(link_state, S_IWUSR, NULL, store_link_state); | 689 | static DEVICE_ATTR(link_state, S_IWUSR, NULL, store_link_state); |
653 | static DEVICE_ATTR(mlid, S_IWUSR | S_IRUGO, show_mlid, store_mlid); | 690 | static DEVICE_ATTR(mlid, S_IWUSR | S_IRUGO, show_mlid, store_mlid); |
@@ -667,6 +704,7 @@ static DEVICE_ATTR(logged_errors, S_IRUGO, show_logged_errs, NULL); | |||
667 | 704 | ||
668 | static struct attribute *dev_attributes[] = { | 705 | static struct attribute *dev_attributes[] = { |
669 | &dev_attr_guid.attr, | 706 | &dev_attr_guid.attr, |
707 | &dev_attr_lmc.attr, | ||
670 | &dev_attr_lid.attr, | 708 | &dev_attr_lid.attr, |
671 | &dev_attr_link_state.attr, | 709 | &dev_attr_link_state.attr, |
672 | &dev_attr_mlid.attr, | 710 | &dev_attr_mlid.attr, |
diff --git a/drivers/infiniband/hw/ipath/ipath_uc.c b/drivers/infiniband/hw/ipath/ipath_uc.c index 8380fbc50d2c..2dd8de20d221 100644 --- a/drivers/infiniband/hw/ipath/ipath_uc.c +++ b/drivers/infiniband/hw/ipath/ipath_uc.c | |||
@@ -37,72 +37,40 @@ | |||
37 | /* cut down ridiculously long IB macro names */ | 37 | /* cut down ridiculously long IB macro names */ |
38 | #define OP(x) IB_OPCODE_UC_##x | 38 | #define OP(x) IB_OPCODE_UC_##x |
39 | 39 | ||
40 | static void complete_last_send(struct ipath_qp *qp, struct ipath_swqe *wqe, | ||
41 | struct ib_wc *wc) | ||
42 | { | ||
43 | if (++qp->s_last == qp->s_size) | ||
44 | qp->s_last = 0; | ||
45 | if (!(qp->s_flags & IPATH_S_SIGNAL_REQ_WR) || | ||
46 | (wqe->wr.send_flags & IB_SEND_SIGNALED)) { | ||
47 | wc->wr_id = wqe->wr.wr_id; | ||
48 | wc->status = IB_WC_SUCCESS; | ||
49 | wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; | ||
50 | wc->vendor_err = 0; | ||
51 | wc->byte_len = wqe->length; | ||
52 | wc->qp = &qp->ibqp; | ||
53 | wc->src_qp = qp->remote_qpn; | ||
54 | wc->pkey_index = 0; | ||
55 | wc->slid = qp->remote_ah_attr.dlid; | ||
56 | wc->sl = qp->remote_ah_attr.sl; | ||
57 | wc->dlid_path_bits = 0; | ||
58 | wc->port_num = 0; | ||
59 | ipath_cq_enter(to_icq(qp->ibqp.send_cq), wc, 0); | ||
60 | } | ||
61 | } | ||
62 | |||
63 | /** | 40 | /** |
64 | * ipath_make_uc_req - construct a request packet (SEND, RDMA write) | 41 | * ipath_make_uc_req - construct a request packet (SEND, RDMA write) |
65 | * @qp: a pointer to the QP | 42 | * @qp: a pointer to the QP |
66 | * @ohdr: a pointer to the IB header being constructed | ||
67 | * @pmtu: the path MTU | ||
68 | * @bth0p: pointer to the BTH opcode word | ||
69 | * @bth2p: pointer to the BTH PSN word | ||
70 | * | 43 | * |
71 | * Return 1 if constructed; otherwise, return 0. | 44 | * Return 1 if constructed; otherwise, return 0. |
72 | * Note the QP s_lock must be held and interrupts disabled. | ||
73 | */ | 45 | */ |
74 | int ipath_make_uc_req(struct ipath_qp *qp, | 46 | int ipath_make_uc_req(struct ipath_qp *qp) |
75 | struct ipath_other_headers *ohdr, | ||
76 | u32 pmtu, u32 *bth0p, u32 *bth2p) | ||
77 | { | 47 | { |
48 | struct ipath_other_headers *ohdr; | ||
78 | struct ipath_swqe *wqe; | 49 | struct ipath_swqe *wqe; |
79 | u32 hwords; | 50 | u32 hwords; |
80 | u32 bth0; | 51 | u32 bth0; |
81 | u32 len; | 52 | u32 len; |
82 | struct ib_wc wc; | 53 | u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu); |
54 | int ret = 0; | ||
83 | 55 | ||
84 | if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)) | 56 | if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)) |
85 | goto done; | 57 | goto done; |
86 | 58 | ||
59 | ohdr = &qp->s_hdr.u.oth; | ||
60 | if (qp->remote_ah_attr.ah_flags & IB_AH_GRH) | ||
61 | ohdr = &qp->s_hdr.u.l.oth; | ||
62 | |||
87 | /* header size in 32-bit words LRH+BTH = (8+12)/4. */ | 63 | /* header size in 32-bit words LRH+BTH = (8+12)/4. */ |
88 | hwords = 5; | 64 | hwords = 5; |
89 | bth0 = 1 << 22; /* Set M bit */ | 65 | bth0 = 1 << 22; /* Set M bit */ |
90 | 66 | ||
91 | /* Get the next send request. */ | 67 | /* Get the next send request. */ |
92 | wqe = get_swqe_ptr(qp, qp->s_last); | 68 | wqe = get_swqe_ptr(qp, qp->s_cur); |
69 | qp->s_wqe = NULL; | ||
93 | switch (qp->s_state) { | 70 | switch (qp->s_state) { |
94 | default: | 71 | default: |
95 | /* | ||
96 | * Signal the completion of the last send | ||
97 | * (if there is one). | ||
98 | */ | ||
99 | if (qp->s_last != qp->s_tail) { | ||
100 | complete_last_send(qp, wqe, &wc); | ||
101 | wqe = get_swqe_ptr(qp, qp->s_last); | ||
102 | } | ||
103 | |||
104 | /* Check if send work queue is empty. */ | 72 | /* Check if send work queue is empty. */ |
105 | if (qp->s_tail == qp->s_head) | 73 | if (qp->s_cur == qp->s_head) |
106 | goto done; | 74 | goto done; |
107 | /* | 75 | /* |
108 | * Start a new request. | 76 | * Start a new request. |
@@ -131,6 +99,9 @@ int ipath_make_uc_req(struct ipath_qp *qp, | |||
131 | } | 99 | } |
132 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) | 100 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) |
133 | bth0 |= 1 << 23; | 101 | bth0 |= 1 << 23; |
102 | qp->s_wqe = wqe; | ||
103 | if (++qp->s_cur >= qp->s_size) | ||
104 | qp->s_cur = 0; | ||
134 | break; | 105 | break; |
135 | 106 | ||
136 | case IB_WR_RDMA_WRITE: | 107 | case IB_WR_RDMA_WRITE: |
@@ -157,13 +128,14 @@ int ipath_make_uc_req(struct ipath_qp *qp, | |||
157 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) | 128 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) |
158 | bth0 |= 1 << 23; | 129 | bth0 |= 1 << 23; |
159 | } | 130 | } |
131 | qp->s_wqe = wqe; | ||
132 | if (++qp->s_cur >= qp->s_size) | ||
133 | qp->s_cur = 0; | ||
160 | break; | 134 | break; |
161 | 135 | ||
162 | default: | 136 | default: |
163 | goto done; | 137 | goto done; |
164 | } | 138 | } |
165 | if (++qp->s_tail >= qp->s_size) | ||
166 | qp->s_tail = 0; | ||
167 | break; | 139 | break; |
168 | 140 | ||
169 | case OP(SEND_FIRST): | 141 | case OP(SEND_FIRST): |
@@ -185,6 +157,9 @@ int ipath_make_uc_req(struct ipath_qp *qp, | |||
185 | } | 157 | } |
186 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) | 158 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) |
187 | bth0 |= 1 << 23; | 159 | bth0 |= 1 << 23; |
160 | qp->s_wqe = wqe; | ||
161 | if (++qp->s_cur >= qp->s_size) | ||
162 | qp->s_cur = 0; | ||
188 | break; | 163 | break; |
189 | 164 | ||
190 | case OP(RDMA_WRITE_FIRST): | 165 | case OP(RDMA_WRITE_FIRST): |
@@ -207,18 +182,22 @@ int ipath_make_uc_req(struct ipath_qp *qp, | |||
207 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) | 182 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) |
208 | bth0 |= 1 << 23; | 183 | bth0 |= 1 << 23; |
209 | } | 184 | } |
185 | qp->s_wqe = wqe; | ||
186 | if (++qp->s_cur >= qp->s_size) | ||
187 | qp->s_cur = 0; | ||
210 | break; | 188 | break; |
211 | } | 189 | } |
212 | qp->s_len -= len; | 190 | qp->s_len -= len; |
213 | qp->s_hdrwords = hwords; | 191 | qp->s_hdrwords = hwords; |
214 | qp->s_cur_sge = &qp->s_sge; | 192 | qp->s_cur_sge = &qp->s_sge; |
215 | qp->s_cur_size = len; | 193 | qp->s_cur_size = len; |
216 | *bth0p = bth0 | (qp->s_state << 24); | 194 | ipath_make_ruc_header(to_idev(qp->ibqp.device), |
217 | *bth2p = qp->s_next_psn++ & IPATH_PSN_MASK; | 195 | qp, ohdr, bth0 | (qp->s_state << 24), |
218 | return 1; | 196 | qp->s_next_psn++ & IPATH_PSN_MASK); |
197 | ret = 1; | ||
219 | 198 | ||
220 | done: | 199 | done: |
221 | return 0; | 200 | return ret; |
222 | } | 201 | } |
223 | 202 | ||
224 | /** | 203 | /** |
@@ -485,6 +464,16 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, | |||
485 | 464 | ||
486 | case OP(RDMA_WRITE_LAST_WITH_IMMEDIATE): | 465 | case OP(RDMA_WRITE_LAST_WITH_IMMEDIATE): |
487 | rdma_last_imm: | 466 | rdma_last_imm: |
467 | if (header_in_data) { | ||
468 | wc.imm_data = *(__be32 *) data; | ||
469 | data += sizeof(__be32); | ||
470 | } else { | ||
471 | /* Immediate data comes after BTH */ | ||
472 | wc.imm_data = ohdr->u.imm_data; | ||
473 | } | ||
474 | hdrsize += 4; | ||
475 | wc.wc_flags = IB_WC_WITH_IMM; | ||
476 | |||
488 | /* Get the number of bytes the message was padded by. */ | 477 | /* Get the number of bytes the message was padded by. */ |
489 | pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3; | 478 | pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3; |
490 | /* Check for invalid length. */ | 479 | /* Check for invalid length. */ |
@@ -505,16 +494,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, | |||
505 | dev->n_pkt_drops++; | 494 | dev->n_pkt_drops++; |
506 | goto done; | 495 | goto done; |
507 | } | 496 | } |
508 | if (header_in_data) { | 497 | wc.byte_len = qp->r_len; |
509 | wc.imm_data = *(__be32 *) data; | ||
510 | data += sizeof(__be32); | ||
511 | } else { | ||
512 | /* Immediate data comes after BTH */ | ||
513 | wc.imm_data = ohdr->u.imm_data; | ||
514 | } | ||
515 | hdrsize += 4; | ||
516 | wc.wc_flags = IB_WC_WITH_IMM; | ||
517 | wc.byte_len = 0; | ||
518 | goto last_imm; | 498 | goto last_imm; |
519 | 499 | ||
520 | case OP(RDMA_WRITE_LAST): | 500 | case OP(RDMA_WRITE_LAST): |
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c index f9a3338a5fb7..16a2a938b520 100644 --- a/drivers/infiniband/hw/ipath/ipath_ud.c +++ b/drivers/infiniband/hw/ipath/ipath_ud.c | |||
@@ -36,68 +36,17 @@ | |||
36 | #include "ipath_verbs.h" | 36 | #include "ipath_verbs.h" |
37 | #include "ipath_kernel.h" | 37 | #include "ipath_kernel.h" |
38 | 38 | ||
39 | static int init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe, | ||
40 | u32 *lengthp, struct ipath_sge_state *ss) | ||
41 | { | ||
42 | int user = to_ipd(qp->ibqp.pd)->user; | ||
43 | int i, j, ret; | ||
44 | struct ib_wc wc; | ||
45 | |||
46 | *lengthp = 0; | ||
47 | for (i = j = 0; i < wqe->num_sge; i++) { | ||
48 | if (wqe->sg_list[i].length == 0) | ||
49 | continue; | ||
50 | /* Check LKEY */ | ||
51 | if ((user && wqe->sg_list[i].lkey == 0) || | ||
52 | !ipath_lkey_ok(qp, j ? &ss->sg_list[j - 1] : &ss->sge, | ||
53 | &wqe->sg_list[i], IB_ACCESS_LOCAL_WRITE)) | ||
54 | goto bad_lkey; | ||
55 | *lengthp += wqe->sg_list[i].length; | ||
56 | j++; | ||
57 | } | ||
58 | ss->num_sge = j; | ||
59 | ret = 1; | ||
60 | goto bail; | ||
61 | |||
62 | bad_lkey: | ||
63 | wc.wr_id = wqe->wr_id; | ||
64 | wc.status = IB_WC_LOC_PROT_ERR; | ||
65 | wc.opcode = IB_WC_RECV; | ||
66 | wc.vendor_err = 0; | ||
67 | wc.byte_len = 0; | ||
68 | wc.imm_data = 0; | ||
69 | wc.qp = &qp->ibqp; | ||
70 | wc.src_qp = 0; | ||
71 | wc.wc_flags = 0; | ||
72 | wc.pkey_index = 0; | ||
73 | wc.slid = 0; | ||
74 | wc.sl = 0; | ||
75 | wc.dlid_path_bits = 0; | ||
76 | wc.port_num = 0; | ||
77 | /* Signal solicited completion event. */ | ||
78 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1); | ||
79 | ret = 0; | ||
80 | bail: | ||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | /** | 39 | /** |
85 | * ipath_ud_loopback - handle send on loopback QPs | 40 | * ipath_ud_loopback - handle send on loopback QPs |
86 | * @sqp: the QP | 41 | * @sqp: the sending QP |
87 | * @ss: the SGE state | 42 | * @swqe: the send work request |
88 | * @length: the length of the data to send | ||
89 | * @wr: the work request | ||
90 | * @wc: the work completion entry | ||
91 | * | 43 | * |
92 | * This is called from ipath_post_ud_send() to forward a WQE addressed | 44 | * This is called from ipath_make_ud_req() to forward a WQE addressed |
93 | * to the same HCA. | 45 | * to the same HCA. |
94 | * Note that the receive interrupt handler may be calling ipath_ud_rcv() | 46 | * Note that the receive interrupt handler may be calling ipath_ud_rcv() |
95 | * while this is being called. | 47 | * while this is being called. |
96 | */ | 48 | */ |
97 | static void ipath_ud_loopback(struct ipath_qp *sqp, | 49 | static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_swqe *swqe) |
98 | struct ipath_sge_state *ss, | ||
99 | u32 length, struct ib_send_wr *wr, | ||
100 | struct ib_wc *wc) | ||
101 | { | 50 | { |
102 | struct ipath_ibdev *dev = to_idev(sqp->ibqp.device); | 51 | struct ipath_ibdev *dev = to_idev(sqp->ibqp.device); |
103 | struct ipath_qp *qp; | 52 | struct ipath_qp *qp; |
@@ -110,12 +59,18 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, | |||
110 | struct ipath_rwq *wq; | 59 | struct ipath_rwq *wq; |
111 | struct ipath_rwqe *wqe; | 60 | struct ipath_rwqe *wqe; |
112 | void (*handler)(struct ib_event *, void *); | 61 | void (*handler)(struct ib_event *, void *); |
62 | struct ib_wc wc; | ||
113 | u32 tail; | 63 | u32 tail; |
114 | u32 rlen; | 64 | u32 rlen; |
65 | u32 length; | ||
115 | 66 | ||
116 | qp = ipath_lookup_qpn(&dev->qp_table, wr->wr.ud.remote_qpn); | 67 | qp = ipath_lookup_qpn(&dev->qp_table, swqe->wr.wr.ud.remote_qpn); |
117 | if (!qp) | 68 | if (!qp) { |
118 | return; | 69 | dev->n_pkt_drops++; |
70 | goto send_comp; | ||
71 | } | ||
72 | |||
73 | rsge.sg_list = NULL; | ||
119 | 74 | ||
120 | /* | 75 | /* |
121 | * Check that the qkey matches (except for QP0, see 9.6.1.4.1). | 76 | * Check that the qkey matches (except for QP0, see 9.6.1.4.1). |
@@ -123,39 +78,34 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, | |||
123 | * qkey from the QP context instead of the WR (see 10.2.5). | 78 | * qkey from the QP context instead of the WR (see 10.2.5). |
124 | */ | 79 | */ |
125 | if (unlikely(qp->ibqp.qp_num && | 80 | if (unlikely(qp->ibqp.qp_num && |
126 | ((int) wr->wr.ud.remote_qkey < 0 | 81 | ((int) swqe->wr.wr.ud.remote_qkey < 0 ? |
127 | ? qp->qkey : wr->wr.ud.remote_qkey) != qp->qkey)) { | 82 | sqp->qkey : swqe->wr.wr.ud.remote_qkey) != qp->qkey)) { |
128 | /* XXX OK to lose a count once in a while. */ | 83 | /* XXX OK to lose a count once in a while. */ |
129 | dev->qkey_violations++; | 84 | dev->qkey_violations++; |
130 | dev->n_pkt_drops++; | 85 | dev->n_pkt_drops++; |
131 | goto done; | 86 | goto drop; |
132 | } | 87 | } |
133 | 88 | ||
134 | /* | 89 | /* |
135 | * A GRH is expected to preceed the data even if not | 90 | * A GRH is expected to preceed the data even if not |
136 | * present on the wire. | 91 | * present on the wire. |
137 | */ | 92 | */ |
138 | wc->byte_len = length + sizeof(struct ib_grh); | 93 | length = swqe->length; |
94 | wc.byte_len = length + sizeof(struct ib_grh); | ||
139 | 95 | ||
140 | if (wr->opcode == IB_WR_SEND_WITH_IMM) { | 96 | if (swqe->wr.opcode == IB_WR_SEND_WITH_IMM) { |
141 | wc->wc_flags = IB_WC_WITH_IMM; | 97 | wc.wc_flags = IB_WC_WITH_IMM; |
142 | wc->imm_data = wr->imm_data; | 98 | wc.imm_data = swqe->wr.imm_data; |
143 | } else { | 99 | } else { |
144 | wc->wc_flags = 0; | 100 | wc.wc_flags = 0; |
145 | wc->imm_data = 0; | 101 | wc.imm_data = 0; |
146 | } | 102 | } |
147 | 103 | ||
148 | if (wr->num_sge > 1) { | ||
149 | rsge.sg_list = kmalloc((wr->num_sge - 1) * | ||
150 | sizeof(struct ipath_sge), | ||
151 | GFP_ATOMIC); | ||
152 | } else | ||
153 | rsge.sg_list = NULL; | ||
154 | |||
155 | /* | 104 | /* |
156 | * Get the next work request entry to find where to put the data. | 105 | * This would be a lot simpler if we could call ipath_get_rwqe() |
157 | * Note that it is safe to drop the lock after changing rq->tail | 106 | * but that uses state that the receive interrupt handler uses |
158 | * since ipath_post_receive() won't fill the empty slot. | 107 | * so we would need to lock out receive interrupts while doing |
108 | * local loopback. | ||
159 | */ | 109 | */ |
160 | if (qp->ibqp.srq) { | 110 | if (qp->ibqp.srq) { |
161 | srq = to_isrq(qp->ibqp.srq); | 111 | srq = to_isrq(qp->ibqp.srq); |
@@ -167,32 +117,53 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, | |||
167 | rq = &qp->r_rq; | 117 | rq = &qp->r_rq; |
168 | } | 118 | } |
169 | 119 | ||
120 | if (rq->max_sge > 1) { | ||
121 | /* | ||
122 | * XXX We could use GFP_KERNEL if ipath_do_send() | ||
123 | * was always called from the tasklet instead of | ||
124 | * from ipath_post_send(). | ||
125 | */ | ||
126 | rsge.sg_list = kmalloc((rq->max_sge - 1) * | ||
127 | sizeof(struct ipath_sge), | ||
128 | GFP_ATOMIC); | ||
129 | if (!rsge.sg_list) { | ||
130 | dev->n_pkt_drops++; | ||
131 | goto drop; | ||
132 | } | ||
133 | } | ||
134 | |||
135 | /* | ||
136 | * Get the next work request entry to find where to put the data. | ||
137 | * Note that it is safe to drop the lock after changing rq->tail | ||
138 | * since ipath_post_receive() won't fill the empty slot. | ||
139 | */ | ||
170 | spin_lock_irqsave(&rq->lock, flags); | 140 | spin_lock_irqsave(&rq->lock, flags); |
171 | wq = rq->wq; | 141 | wq = rq->wq; |
172 | tail = wq->tail; | 142 | tail = wq->tail; |
173 | while (1) { | 143 | /* Validate tail before using it since it is user writable. */ |
174 | if (unlikely(tail == wq->head)) { | 144 | if (tail >= rq->size) |
175 | spin_unlock_irqrestore(&rq->lock, flags); | 145 | tail = 0; |
176 | dev->n_pkt_drops++; | 146 | if (unlikely(tail == wq->head)) { |
177 | goto bail_sge; | 147 | spin_unlock_irqrestore(&rq->lock, flags); |
178 | } | 148 | dev->n_pkt_drops++; |
179 | /* Make sure entry is read after head index is read. */ | 149 | goto drop; |
180 | smp_rmb(); | 150 | } |
181 | wqe = get_rwqe_ptr(rq, tail); | 151 | wqe = get_rwqe_ptr(rq, tail); |
182 | if (++tail >= rq->size) | 152 | if (!ipath_init_sge(qp, wqe, &rlen, &rsge)) { |
183 | tail = 0; | 153 | spin_unlock_irqrestore(&rq->lock, flags); |
184 | if (init_sge(qp, wqe, &rlen, &rsge)) | 154 | dev->n_pkt_drops++; |
185 | break; | 155 | goto drop; |
186 | wq->tail = tail; | ||
187 | } | 156 | } |
188 | /* Silently drop packets which are too big. */ | 157 | /* Silently drop packets which are too big. */ |
189 | if (wc->byte_len > rlen) { | 158 | if (wc.byte_len > rlen) { |
190 | spin_unlock_irqrestore(&rq->lock, flags); | 159 | spin_unlock_irqrestore(&rq->lock, flags); |
191 | dev->n_pkt_drops++; | 160 | dev->n_pkt_drops++; |
192 | goto bail_sge; | 161 | goto drop; |
193 | } | 162 | } |
163 | if (++tail >= rq->size) | ||
164 | tail = 0; | ||
194 | wq->tail = tail; | 165 | wq->tail = tail; |
195 | wc->wr_id = wqe->wr_id; | 166 | wc.wr_id = wqe->wr_id; |
196 | if (handler) { | 167 | if (handler) { |
197 | u32 n; | 168 | u32 n; |
198 | 169 | ||
@@ -221,13 +192,13 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, | |||
221 | } else | 192 | } else |
222 | spin_unlock_irqrestore(&rq->lock, flags); | 193 | spin_unlock_irqrestore(&rq->lock, flags); |
223 | 194 | ||
224 | ah_attr = &to_iah(wr->wr.ud.ah)->attr; | 195 | ah_attr = &to_iah(swqe->wr.wr.ud.ah)->attr; |
225 | if (ah_attr->ah_flags & IB_AH_GRH) { | 196 | if (ah_attr->ah_flags & IB_AH_GRH) { |
226 | ipath_copy_sge(&rsge, &ah_attr->grh, sizeof(struct ib_grh)); | 197 | ipath_copy_sge(&rsge, &ah_attr->grh, sizeof(struct ib_grh)); |
227 | wc->wc_flags |= IB_WC_GRH; | 198 | wc.wc_flags |= IB_WC_GRH; |
228 | } else | 199 | } else |
229 | ipath_skip_sge(&rsge, sizeof(struct ib_grh)); | 200 | ipath_skip_sge(&rsge, sizeof(struct ib_grh)); |
230 | sge = &ss->sge; | 201 | sge = swqe->sg_list; |
231 | while (length) { | 202 | while (length) { |
232 | u32 len = sge->length; | 203 | u32 len = sge->length; |
233 | 204 | ||
@@ -241,8 +212,8 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, | |||
241 | sge->length -= len; | 212 | sge->length -= len; |
242 | sge->sge_length -= len; | 213 | sge->sge_length -= len; |
243 | if (sge->sge_length == 0) { | 214 | if (sge->sge_length == 0) { |
244 | if (--ss->num_sge) | 215 | if (--swqe->wr.num_sge) |
245 | *sge = *ss->sg_list++; | 216 | sge++; |
246 | } else if (sge->length == 0 && sge->mr != NULL) { | 217 | } else if (sge->length == 0 && sge->mr != NULL) { |
247 | if (++sge->n >= IPATH_SEGSZ) { | 218 | if (++sge->n >= IPATH_SEGSZ) { |
248 | if (++sge->m >= sge->mr->mapsz) | 219 | if (++sge->m >= sge->mr->mapsz) |
@@ -256,123 +227,60 @@ static void ipath_ud_loopback(struct ipath_qp *sqp, | |||
256 | } | 227 | } |
257 | length -= len; | 228 | length -= len; |
258 | } | 229 | } |
259 | wc->status = IB_WC_SUCCESS; | 230 | wc.status = IB_WC_SUCCESS; |
260 | wc->opcode = IB_WC_RECV; | 231 | wc.opcode = IB_WC_RECV; |
261 | wc->vendor_err = 0; | 232 | wc.vendor_err = 0; |
262 | wc->qp = &qp->ibqp; | 233 | wc.qp = &qp->ibqp; |
263 | wc->src_qp = sqp->ibqp.qp_num; | 234 | wc.src_qp = sqp->ibqp.qp_num; |
264 | /* XXX do we know which pkey matched? Only needed for GSI. */ | 235 | /* XXX do we know which pkey matched? Only needed for GSI. */ |
265 | wc->pkey_index = 0; | 236 | wc.pkey_index = 0; |
266 | wc->slid = dev->dd->ipath_lid | | 237 | wc.slid = dev->dd->ipath_lid | |
267 | (ah_attr->src_path_bits & | 238 | (ah_attr->src_path_bits & |
268 | ((1 << (dev->mkeyprot_resv_lmc & 7)) - 1)); | 239 | ((1 << dev->dd->ipath_lmc) - 1)); |
269 | wc->sl = ah_attr->sl; | 240 | wc.sl = ah_attr->sl; |
270 | wc->dlid_path_bits = | 241 | wc.dlid_path_bits = |
271 | ah_attr->dlid & ((1 << (dev->mkeyprot_resv_lmc & 7)) - 1); | 242 | ah_attr->dlid & ((1 << dev->dd->ipath_lmc) - 1); |
243 | wc.port_num = 1; | ||
272 | /* Signal completion event if the solicited bit is set. */ | 244 | /* Signal completion event if the solicited bit is set. */ |
273 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), wc, | 245 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, |
274 | wr->send_flags & IB_SEND_SOLICITED); | 246 | swqe->wr.send_flags & IB_SEND_SOLICITED); |
275 | 247 | drop: | |
276 | bail_sge: | ||
277 | kfree(rsge.sg_list); | 248 | kfree(rsge.sg_list); |
278 | done: | ||
279 | if (atomic_dec_and_test(&qp->refcount)) | 249 | if (atomic_dec_and_test(&qp->refcount)) |
280 | wake_up(&qp->wait); | 250 | wake_up(&qp->wait); |
251 | send_comp: | ||
252 | ipath_send_complete(sqp, swqe, IB_WC_SUCCESS); | ||
281 | } | 253 | } |
282 | 254 | ||
283 | /** | 255 | /** |
284 | * ipath_post_ud_send - post a UD send on QP | 256 | * ipath_make_ud_req - construct a UD request packet |
285 | * @qp: the QP | 257 | * @qp: the QP |
286 | * @wr: the work request | ||
287 | * | 258 | * |
288 | * Note that we actually send the data as it is posted instead of putting | 259 | * Return 1 if constructed; otherwise, return 0. |
289 | * the request into a ring buffer. If we wanted to use a ring buffer, | ||
290 | * we would need to save a reference to the destination address in the SWQE. | ||
291 | */ | 260 | */ |
292 | int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr) | 261 | int ipath_make_ud_req(struct ipath_qp *qp) |
293 | { | 262 | { |
294 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | 263 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); |
295 | struct ipath_other_headers *ohdr; | 264 | struct ipath_other_headers *ohdr; |
296 | struct ib_ah_attr *ah_attr; | 265 | struct ib_ah_attr *ah_attr; |
297 | struct ipath_sge_state ss; | 266 | struct ipath_swqe *wqe; |
298 | struct ipath_sge *sg_list; | ||
299 | struct ib_wc wc; | ||
300 | u32 hwords; | ||
301 | u32 nwords; | 267 | u32 nwords; |
302 | u32 len; | ||
303 | u32 extra_bytes; | 268 | u32 extra_bytes; |
304 | u32 bth0; | 269 | u32 bth0; |
305 | u16 lrh0; | 270 | u16 lrh0; |
306 | u16 lid; | 271 | u16 lid; |
307 | int i; | 272 | int ret = 0; |
308 | int ret; | ||
309 | 273 | ||
310 | if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK)) { | 274 | if (unlikely(!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK))) |
311 | ret = 0; | ||
312 | goto bail; | 275 | goto bail; |
313 | } | ||
314 | 276 | ||
315 | if (wr->wr.ud.ah->pd != qp->ibqp.pd) { | 277 | if (qp->s_cur == qp->s_head) |
316 | ret = -EPERM; | ||
317 | goto bail; | 278 | goto bail; |
318 | } | ||
319 | 279 | ||
320 | /* IB spec says that num_sge == 0 is OK. */ | 280 | wqe = get_swqe_ptr(qp, qp->s_cur); |
321 | if (wr->num_sge > qp->s_max_sge) { | ||
322 | ret = -EINVAL; | ||
323 | goto bail; | ||
324 | } | ||
325 | |||
326 | if (wr->num_sge > 1) { | ||
327 | sg_list = kmalloc((qp->s_max_sge - 1) * sizeof(*sg_list), | ||
328 | GFP_ATOMIC); | ||
329 | if (!sg_list) { | ||
330 | ret = -ENOMEM; | ||
331 | goto bail; | ||
332 | } | ||
333 | } else | ||
334 | sg_list = NULL; | ||
335 | |||
336 | /* Check the buffer to send. */ | ||
337 | ss.sg_list = sg_list; | ||
338 | ss.sge.mr = NULL; | ||
339 | ss.sge.vaddr = NULL; | ||
340 | ss.sge.length = 0; | ||
341 | ss.sge.sge_length = 0; | ||
342 | ss.num_sge = 0; | ||
343 | len = 0; | ||
344 | for (i = 0; i < wr->num_sge; i++) { | ||
345 | /* Check LKEY */ | ||
346 | if (to_ipd(qp->ibqp.pd)->user && wr->sg_list[i].lkey == 0) { | ||
347 | ret = -EINVAL; | ||
348 | goto bail; | ||
349 | } | ||
350 | |||
351 | if (wr->sg_list[i].length == 0) | ||
352 | continue; | ||
353 | if (!ipath_lkey_ok(qp, ss.num_sge ? | ||
354 | sg_list + ss.num_sge - 1 : &ss.sge, | ||
355 | &wr->sg_list[i], 0)) { | ||
356 | ret = -EINVAL; | ||
357 | goto bail; | ||
358 | } | ||
359 | len += wr->sg_list[i].length; | ||
360 | ss.num_sge++; | ||
361 | } | ||
362 | /* Check for invalid packet size. */ | ||
363 | if (len > dev->dd->ipath_ibmtu) { | ||
364 | ret = -EINVAL; | ||
365 | goto bail; | ||
366 | } | ||
367 | extra_bytes = (4 - len) & 3; | ||
368 | nwords = (len + extra_bytes) >> 2; | ||
369 | 281 | ||
370 | /* Construct the header. */ | 282 | /* Construct the header. */ |
371 | ah_attr = &to_iah(wr->wr.ud.ah)->attr; | 283 | ah_attr = &to_iah(wqe->wr.wr.ud.ah)->attr; |
372 | if (ah_attr->dlid == 0) { | ||
373 | ret = -EINVAL; | ||
374 | goto bail; | ||
375 | } | ||
376 | if (ah_attr->dlid >= IPATH_MULTICAST_LID_BASE) { | 284 | if (ah_attr->dlid >= IPATH_MULTICAST_LID_BASE) { |
377 | if (ah_attr->dlid != IPATH_PERMISSIVE_LID) | 285 | if (ah_attr->dlid != IPATH_PERMISSIVE_LID) |
378 | dev->n_multicast_xmit++; | 286 | dev->n_multicast_xmit++; |
@@ -381,74 +289,63 @@ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr) | |||
381 | } else { | 289 | } else { |
382 | dev->n_unicast_xmit++; | 290 | dev->n_unicast_xmit++; |
383 | lid = ah_attr->dlid & | 291 | lid = ah_attr->dlid & |
384 | ~((1 << (dev->mkeyprot_resv_lmc & 7)) - 1); | 292 | ~((1 << dev->dd->ipath_lmc) - 1); |
385 | if (unlikely(lid == dev->dd->ipath_lid)) { | 293 | if (unlikely(lid == dev->dd->ipath_lid)) { |
386 | /* | 294 | ipath_ud_loopback(qp, wqe); |
387 | * Pass in an uninitialized ib_wc to save stack | ||
388 | * space. | ||
389 | */ | ||
390 | ipath_ud_loopback(qp, &ss, len, wr, &wc); | ||
391 | goto done; | 295 | goto done; |
392 | } | 296 | } |
393 | } | 297 | } |
298 | |||
299 | extra_bytes = -wqe->length & 3; | ||
300 | nwords = (wqe->length + extra_bytes) >> 2; | ||
301 | |||
302 | /* header size in 32-bit words LRH+BTH+DETH = (8+12+8)/4. */ | ||
303 | qp->s_hdrwords = 7; | ||
304 | if (wqe->wr.opcode == IB_WR_SEND_WITH_IMM) | ||
305 | qp->s_hdrwords++; | ||
306 | qp->s_cur_size = wqe->length; | ||
307 | qp->s_cur_sge = &qp->s_sge; | ||
308 | qp->s_wqe = wqe; | ||
309 | qp->s_sge.sge = wqe->sg_list[0]; | ||
310 | qp->s_sge.sg_list = wqe->sg_list + 1; | ||
311 | qp->s_sge.num_sge = wqe->wr.num_sge; | ||
312 | |||
394 | if (ah_attr->ah_flags & IB_AH_GRH) { | 313 | if (ah_attr->ah_flags & IB_AH_GRH) { |
395 | /* Header size in 32-bit words. */ | 314 | /* Header size in 32-bit words. */ |
396 | hwords = 17; | 315 | qp->s_hdrwords += ipath_make_grh(dev, &qp->s_hdr.u.l.grh, |
316 | &ah_attr->grh, | ||
317 | qp->s_hdrwords, nwords); | ||
397 | lrh0 = IPATH_LRH_GRH; | 318 | lrh0 = IPATH_LRH_GRH; |
398 | ohdr = &qp->s_hdr.u.l.oth; | 319 | ohdr = &qp->s_hdr.u.l.oth; |
399 | qp->s_hdr.u.l.grh.version_tclass_flow = | ||
400 | cpu_to_be32((6 << 28) | | ||
401 | (ah_attr->grh.traffic_class << 20) | | ||
402 | ah_attr->grh.flow_label); | ||
403 | qp->s_hdr.u.l.grh.paylen = | ||
404 | cpu_to_be16(((wr->opcode == | ||
405 | IB_WR_SEND_WITH_IMM ? 6 : 5) + | ||
406 | nwords + SIZE_OF_CRC) << 2); | ||
407 | /* next_hdr is defined by C8-7 in ch. 8.4.1 */ | ||
408 | qp->s_hdr.u.l.grh.next_hdr = 0x1B; | ||
409 | qp->s_hdr.u.l.grh.hop_limit = ah_attr->grh.hop_limit; | ||
410 | /* The SGID is 32-bit aligned. */ | ||
411 | qp->s_hdr.u.l.grh.sgid.global.subnet_prefix = | ||
412 | dev->gid_prefix; | ||
413 | qp->s_hdr.u.l.grh.sgid.global.interface_id = | ||
414 | dev->dd->ipath_guid; | ||
415 | qp->s_hdr.u.l.grh.dgid = ah_attr->grh.dgid; | ||
416 | /* | 320 | /* |
417 | * Don't worry about sending to locally attached multicast | 321 | * Don't worry about sending to locally attached multicast |
418 | * QPs. It is unspecified by the spec. what happens. | 322 | * QPs. It is unspecified by the spec. what happens. |
419 | */ | 323 | */ |
420 | } else { | 324 | } else { |
421 | /* Header size in 32-bit words. */ | 325 | /* Header size in 32-bit words. */ |
422 | hwords = 7; | ||
423 | lrh0 = IPATH_LRH_BTH; | 326 | lrh0 = IPATH_LRH_BTH; |
424 | ohdr = &qp->s_hdr.u.oth; | 327 | ohdr = &qp->s_hdr.u.oth; |
425 | } | 328 | } |
426 | if (wr->opcode == IB_WR_SEND_WITH_IMM) { | 329 | if (wqe->wr.opcode == IB_WR_SEND_WITH_IMM) { |
427 | ohdr->u.ud.imm_data = wr->imm_data; | 330 | ohdr->u.ud.imm_data = wqe->wr.imm_data; |
428 | wc.imm_data = wr->imm_data; | ||
429 | hwords += 1; | ||
430 | bth0 = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE << 24; | 331 | bth0 = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE << 24; |
431 | } else if (wr->opcode == IB_WR_SEND) { | 332 | } else |
432 | wc.imm_data = 0; | ||
433 | bth0 = IB_OPCODE_UD_SEND_ONLY << 24; | 333 | bth0 = IB_OPCODE_UD_SEND_ONLY << 24; |
434 | } else { | ||
435 | ret = -EINVAL; | ||
436 | goto bail; | ||
437 | } | ||
438 | lrh0 |= ah_attr->sl << 4; | 334 | lrh0 |= ah_attr->sl << 4; |
439 | if (qp->ibqp.qp_type == IB_QPT_SMI) | 335 | if (qp->ibqp.qp_type == IB_QPT_SMI) |
440 | lrh0 |= 0xF000; /* Set VL (see ch. 13.5.3.1) */ | 336 | lrh0 |= 0xF000; /* Set VL (see ch. 13.5.3.1) */ |
441 | qp->s_hdr.lrh[0] = cpu_to_be16(lrh0); | 337 | qp->s_hdr.lrh[0] = cpu_to_be16(lrh0); |
442 | qp->s_hdr.lrh[1] = cpu_to_be16(ah_attr->dlid); /* DEST LID */ | 338 | qp->s_hdr.lrh[1] = cpu_to_be16(ah_attr->dlid); /* DEST LID */ |
443 | qp->s_hdr.lrh[2] = cpu_to_be16(hwords + nwords + SIZE_OF_CRC); | 339 | qp->s_hdr.lrh[2] = cpu_to_be16(qp->s_hdrwords + nwords + |
340 | SIZE_OF_CRC); | ||
444 | lid = dev->dd->ipath_lid; | 341 | lid = dev->dd->ipath_lid; |
445 | if (lid) { | 342 | if (lid) { |
446 | lid |= ah_attr->src_path_bits & | 343 | lid |= ah_attr->src_path_bits & |
447 | ((1 << (dev->mkeyprot_resv_lmc & 7)) - 1); | 344 | ((1 << dev->dd->ipath_lmc) - 1); |
448 | qp->s_hdr.lrh[3] = cpu_to_be16(lid); | 345 | qp->s_hdr.lrh[3] = cpu_to_be16(lid); |
449 | } else | 346 | } else |
450 | qp->s_hdr.lrh[3] = IB_LID_PERMISSIVE; | 347 | qp->s_hdr.lrh[3] = IB_LID_PERMISSIVE; |
451 | if (wr->send_flags & IB_SEND_SOLICITED) | 348 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) |
452 | bth0 |= 1 << 23; | 349 | bth0 |= 1 << 23; |
453 | bth0 |= extra_bytes << 20; | 350 | bth0 |= extra_bytes << 20; |
454 | bth0 |= qp->ibqp.qp_type == IB_QPT_SMI ? IPATH_DEFAULT_P_KEY : | 351 | bth0 |= qp->ibqp.qp_type == IB_QPT_SMI ? IPATH_DEFAULT_P_KEY : |
@@ -460,38 +357,20 @@ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr) | |||
460 | ohdr->bth[1] = ah_attr->dlid >= IPATH_MULTICAST_LID_BASE && | 357 | ohdr->bth[1] = ah_attr->dlid >= IPATH_MULTICAST_LID_BASE && |
461 | ah_attr->dlid != IPATH_PERMISSIVE_LID ? | 358 | ah_attr->dlid != IPATH_PERMISSIVE_LID ? |
462 | __constant_cpu_to_be32(IPATH_MULTICAST_QPN) : | 359 | __constant_cpu_to_be32(IPATH_MULTICAST_QPN) : |
463 | cpu_to_be32(wr->wr.ud.remote_qpn); | 360 | cpu_to_be32(wqe->wr.wr.ud.remote_qpn); |
464 | /* XXX Could lose a PSN count but not worth locking */ | ||
465 | ohdr->bth[2] = cpu_to_be32(qp->s_next_psn++ & IPATH_PSN_MASK); | 361 | ohdr->bth[2] = cpu_to_be32(qp->s_next_psn++ & IPATH_PSN_MASK); |
466 | /* | 362 | /* |
467 | * Qkeys with the high order bit set mean use the | 363 | * Qkeys with the high order bit set mean use the |
468 | * qkey from the QP context instead of the WR (see 10.2.5). | 364 | * qkey from the QP context instead of the WR (see 10.2.5). |
469 | */ | 365 | */ |
470 | ohdr->u.ud.deth[0] = cpu_to_be32((int)wr->wr.ud.remote_qkey < 0 ? | 366 | ohdr->u.ud.deth[0] = cpu_to_be32((int)wqe->wr.wr.ud.remote_qkey < 0 ? |
471 | qp->qkey : wr->wr.ud.remote_qkey); | 367 | qp->qkey : wqe->wr.wr.ud.remote_qkey); |
472 | ohdr->u.ud.deth[1] = cpu_to_be32(qp->ibqp.qp_num); | 368 | ohdr->u.ud.deth[1] = cpu_to_be32(qp->ibqp.qp_num); |
473 | if (ipath_verbs_send(dev->dd, hwords, (u32 *) &qp->s_hdr, | ||
474 | len, &ss)) | ||
475 | dev->n_no_piobuf++; | ||
476 | 369 | ||
477 | done: | 370 | done: |
478 | /* Queue the completion status entry. */ | 371 | if (++qp->s_cur >= qp->s_size) |
479 | if (!(qp->s_flags & IPATH_S_SIGNAL_REQ_WR) || | 372 | qp->s_cur = 0; |
480 | (wr->send_flags & IB_SEND_SIGNALED)) { | 373 | ret = 1; |
481 | wc.wr_id = wr->wr_id; | ||
482 | wc.status = IB_WC_SUCCESS; | ||
483 | wc.vendor_err = 0; | ||
484 | wc.opcode = IB_WC_SEND; | ||
485 | wc.byte_len = len; | ||
486 | wc.qp = &qp->ibqp; | ||
487 | wc.src_qp = 0; | ||
488 | wc.wc_flags = 0; | ||
489 | /* XXX initialize other fields? */ | ||
490 | ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 0); | ||
491 | } | ||
492 | kfree(sg_list); | ||
493 | |||
494 | ret = 0; | ||
495 | 374 | ||
496 | bail: | 375 | bail: |
497 | return ret; | 376 | return ret; |
@@ -672,7 +551,8 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, | |||
672 | * Save the LMC lower bits if the destination LID is a unicast LID. | 551 | * Save the LMC lower bits if the destination LID is a unicast LID. |
673 | */ | 552 | */ |
674 | wc.dlid_path_bits = dlid >= IPATH_MULTICAST_LID_BASE ? 0 : | 553 | wc.dlid_path_bits = dlid >= IPATH_MULTICAST_LID_BASE ? 0 : |
675 | dlid & ((1 << (dev->mkeyprot_resv_lmc & 7)) - 1); | 554 | dlid & ((1 << dev->dd->ipath_lmc) - 1); |
555 | wc.port_num = 1; | ||
676 | /* Signal completion event if the solicited bit is set. */ | 556 | /* Signal completion event if the solicited bit is set. */ |
677 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, | 557 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, |
678 | (ohdr->bth[0] & | 558 | (ohdr->bth[0] & |
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c index 16aa61fd8085..74f77e7c2c1b 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/drivers/infiniband/hw/ipath/ipath_verbs.c | |||
@@ -230,6 +230,121 @@ void ipath_skip_sge(struct ipath_sge_state *ss, u32 length) | |||
230 | } | 230 | } |
231 | } | 231 | } |
232 | 232 | ||
233 | static void ipath_flush_wqe(struct ipath_qp *qp, struct ib_send_wr *wr) | ||
234 | { | ||
235 | struct ib_wc wc; | ||
236 | |||
237 | memset(&wc, 0, sizeof(wc)); | ||
238 | wc.wr_id = wr->wr_id; | ||
239 | wc.status = IB_WC_WR_FLUSH_ERR; | ||
240 | wc.opcode = ib_ipath_wc_opcode[wr->opcode]; | ||
241 | wc.qp = &qp->ibqp; | ||
242 | ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 1); | ||
243 | } | ||
244 | |||
245 | /** | ||
246 | * ipath_post_one_send - post one RC, UC, or UD send work request | ||
247 | * @qp: the QP to post on | ||
248 | * @wr: the work request to send | ||
249 | */ | ||
250 | static int ipath_post_one_send(struct ipath_qp *qp, struct ib_send_wr *wr) | ||
251 | { | ||
252 | struct ipath_swqe *wqe; | ||
253 | u32 next; | ||
254 | int i; | ||
255 | int j; | ||
256 | int acc; | ||
257 | int ret; | ||
258 | unsigned long flags; | ||
259 | |||
260 | spin_lock_irqsave(&qp->s_lock, flags); | ||
261 | |||
262 | /* Check that state is OK to post send. */ | ||
263 | if (unlikely(!(ib_ipath_state_ops[qp->state] & IPATH_POST_SEND_OK))) { | ||
264 | if (qp->state != IB_QPS_SQE && qp->state != IB_QPS_ERR) | ||
265 | goto bail_inval; | ||
266 | /* C10-96 says generate a flushed completion entry. */ | ||
267 | ipath_flush_wqe(qp, wr); | ||
268 | ret = 0; | ||
269 | goto bail; | ||
270 | } | ||
271 | |||
272 | /* IB spec says that num_sge == 0 is OK. */ | ||
273 | if (wr->num_sge > qp->s_max_sge) | ||
274 | goto bail_inval; | ||
275 | |||
276 | /* | ||
277 | * Don't allow RDMA reads or atomic operations on UC or | ||
278 | * undefined operations. | ||
279 | * Make sure buffer is large enough to hold the result for atomics. | ||
280 | */ | ||
281 | if (qp->ibqp.qp_type == IB_QPT_UC) { | ||
282 | if ((unsigned) wr->opcode >= IB_WR_RDMA_READ) | ||
283 | goto bail_inval; | ||
284 | } else if (qp->ibqp.qp_type == IB_QPT_UD) { | ||
285 | /* Check UD opcode */ | ||
286 | if (wr->opcode != IB_WR_SEND && | ||
287 | wr->opcode != IB_WR_SEND_WITH_IMM) | ||
288 | goto bail_inval; | ||
289 | /* Check UD destination address PD */ | ||
290 | if (qp->ibqp.pd != wr->wr.ud.ah->pd) | ||
291 | goto bail_inval; | ||
292 | } else if ((unsigned) wr->opcode > IB_WR_ATOMIC_FETCH_AND_ADD) | ||
293 | goto bail_inval; | ||
294 | else if (wr->opcode >= IB_WR_ATOMIC_CMP_AND_SWP && | ||
295 | (wr->num_sge == 0 || | ||
296 | wr->sg_list[0].length < sizeof(u64) || | ||
297 | wr->sg_list[0].addr & (sizeof(u64) - 1))) | ||
298 | goto bail_inval; | ||
299 | else if (wr->opcode >= IB_WR_RDMA_READ && !qp->s_max_rd_atomic) | ||
300 | goto bail_inval; | ||
301 | |||
302 | next = qp->s_head + 1; | ||
303 | if (next >= qp->s_size) | ||
304 | next = 0; | ||
305 | if (next == qp->s_last) | ||
306 | goto bail_inval; | ||
307 | |||
308 | wqe = get_swqe_ptr(qp, qp->s_head); | ||
309 | wqe->wr = *wr; | ||
310 | wqe->ssn = qp->s_ssn++; | ||
311 | wqe->length = 0; | ||
312 | if (wr->num_sge) { | ||
313 | acc = wr->opcode >= IB_WR_RDMA_READ ? | ||
314 | IB_ACCESS_LOCAL_WRITE : 0; | ||
315 | for (i = 0, j = 0; i < wr->num_sge; i++) { | ||
316 | u32 length = wr->sg_list[i].length; | ||
317 | int ok; | ||
318 | |||
319 | if (length == 0) | ||
320 | continue; | ||
321 | ok = ipath_lkey_ok(qp, &wqe->sg_list[j], | ||
322 | &wr->sg_list[i], acc); | ||
323 | if (!ok) | ||
324 | goto bail_inval; | ||
325 | wqe->length += length; | ||
326 | j++; | ||
327 | } | ||
328 | wqe->wr.num_sge = j; | ||
329 | } | ||
330 | if (qp->ibqp.qp_type == IB_QPT_UC || | ||
331 | qp->ibqp.qp_type == IB_QPT_RC) { | ||
332 | if (wqe->length > 0x80000000U) | ||
333 | goto bail_inval; | ||
334 | } else if (wqe->length > to_idev(qp->ibqp.device)->dd->ipath_ibmtu) | ||
335 | goto bail_inval; | ||
336 | qp->s_head = next; | ||
337 | |||
338 | ret = 0; | ||
339 | goto bail; | ||
340 | |||
341 | bail_inval: | ||
342 | ret = -EINVAL; | ||
343 | bail: | ||
344 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
345 | return ret; | ||
346 | } | ||
347 | |||
233 | /** | 348 | /** |
234 | * ipath_post_send - post a send on a QP | 349 | * ipath_post_send - post a send on a QP |
235 | * @ibqp: the QP to post the send on | 350 | * @ibqp: the QP to post the send on |
@@ -244,35 +359,17 @@ static int ipath_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
244 | struct ipath_qp *qp = to_iqp(ibqp); | 359 | struct ipath_qp *qp = to_iqp(ibqp); |
245 | int err = 0; | 360 | int err = 0; |
246 | 361 | ||
247 | /* Check that state is OK to post send. */ | ||
248 | if (!(ib_ipath_state_ops[qp->state] & IPATH_POST_SEND_OK)) { | ||
249 | *bad_wr = wr; | ||
250 | err = -EINVAL; | ||
251 | goto bail; | ||
252 | } | ||
253 | |||
254 | for (; wr; wr = wr->next) { | 362 | for (; wr; wr = wr->next) { |
255 | switch (qp->ibqp.qp_type) { | 363 | err = ipath_post_one_send(qp, wr); |
256 | case IB_QPT_UC: | ||
257 | case IB_QPT_RC: | ||
258 | err = ipath_post_ruc_send(qp, wr); | ||
259 | break; | ||
260 | |||
261 | case IB_QPT_SMI: | ||
262 | case IB_QPT_GSI: | ||
263 | case IB_QPT_UD: | ||
264 | err = ipath_post_ud_send(qp, wr); | ||
265 | break; | ||
266 | |||
267 | default: | ||
268 | err = -EINVAL; | ||
269 | } | ||
270 | if (err) { | 364 | if (err) { |
271 | *bad_wr = wr; | 365 | *bad_wr = wr; |
272 | break; | 366 | goto bail; |
273 | } | 367 | } |
274 | } | 368 | } |
275 | 369 | ||
370 | /* Try to do the send work in the caller's context. */ | ||
371 | ipath_do_send((unsigned long) qp); | ||
372 | |||
276 | bail: | 373 | bail: |
277 | return err; | 374 | return err; |
278 | } | 375 | } |
@@ -416,7 +513,7 @@ void ipath_ib_rcv(struct ipath_ibdev *dev, void *rhdr, void *data, | |||
416 | /* Check for a valid destination LID (see ch. 7.11.1). */ | 513 | /* Check for a valid destination LID (see ch. 7.11.1). */ |
417 | lid = be16_to_cpu(hdr->lrh[1]); | 514 | lid = be16_to_cpu(hdr->lrh[1]); |
418 | if (lid < IPATH_MULTICAST_LID_BASE) { | 515 | if (lid < IPATH_MULTICAST_LID_BASE) { |
419 | lid &= ~((1 << (dev->mkeyprot_resv_lmc & 7)) - 1); | 516 | lid &= ~((1 << dev->dd->ipath_lmc) - 1); |
420 | if (unlikely(lid != dev->dd->ipath_lid)) { | 517 | if (unlikely(lid != dev->dd->ipath_lid)) { |
421 | dev->rcv_errors++; | 518 | dev->rcv_errors++; |
422 | goto bail; | 519 | goto bail; |
@@ -631,7 +728,7 @@ static inline u32 clear_upper_bytes(u32 data, u32 n, u32 off) | |||
631 | #endif | 728 | #endif |
632 | 729 | ||
633 | static void copy_io(u32 __iomem *piobuf, struct ipath_sge_state *ss, | 730 | static void copy_io(u32 __iomem *piobuf, struct ipath_sge_state *ss, |
634 | u32 length) | 731 | u32 length, unsigned flush_wc) |
635 | { | 732 | { |
636 | u32 extra = 0; | 733 | u32 extra = 0; |
637 | u32 data = 0; | 734 | u32 data = 0; |
@@ -641,11 +738,11 @@ static void copy_io(u32 __iomem *piobuf, struct ipath_sge_state *ss, | |||
641 | u32 len = ss->sge.length; | 738 | u32 len = ss->sge.length; |
642 | u32 off; | 739 | u32 off; |
643 | 740 | ||
644 | BUG_ON(len == 0); | ||
645 | if (len > length) | 741 | if (len > length) |
646 | len = length; | 742 | len = length; |
647 | if (len > ss->sge.sge_length) | 743 | if (len > ss->sge.sge_length) |
648 | len = ss->sge.sge_length; | 744 | len = ss->sge.sge_length; |
745 | BUG_ON(len == 0); | ||
649 | /* If the source address is not aligned, try to align it. */ | 746 | /* If the source address is not aligned, try to align it. */ |
650 | off = (unsigned long)ss->sge.vaddr & (sizeof(u32) - 1); | 747 | off = (unsigned long)ss->sge.vaddr & (sizeof(u32) - 1); |
651 | if (off) { | 748 | if (off) { |
@@ -757,36 +854,25 @@ static void copy_io(u32 __iomem *piobuf, struct ipath_sge_state *ss, | |||
757 | } | 854 | } |
758 | /* Update address before sending packet. */ | 855 | /* Update address before sending packet. */ |
759 | update_sge(ss, length); | 856 | update_sge(ss, length); |
760 | /* must flush early everything before trigger word */ | 857 | if (flush_wc) { |
761 | ipath_flush_wc(); | 858 | /* must flush early everything before trigger word */ |
762 | __raw_writel(last, piobuf); | 859 | ipath_flush_wc(); |
763 | /* be sure trigger word is written */ | 860 | __raw_writel(last, piobuf); |
764 | ipath_flush_wc(); | 861 | /* be sure trigger word is written */ |
862 | ipath_flush_wc(); | ||
863 | } else | ||
864 | __raw_writel(last, piobuf); | ||
765 | } | 865 | } |
766 | 866 | ||
767 | /** | 867 | static int ipath_verbs_send_pio(struct ipath_qp *qp, u32 *hdr, u32 hdrwords, |
768 | * ipath_verbs_send - send a packet | 868 | struct ipath_sge_state *ss, u32 len, |
769 | * @dd: the infinipath device | 869 | u32 plen, u32 dwords) |
770 | * @hdrwords: the number of words in the header | ||
771 | * @hdr: the packet header | ||
772 | * @len: the length of the packet in bytes | ||
773 | * @ss: the SGE to send | ||
774 | */ | ||
775 | int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords, | ||
776 | u32 *hdr, u32 len, struct ipath_sge_state *ss) | ||
777 | { | 870 | { |
871 | struct ipath_devdata *dd = to_idev(qp->ibqp.device)->dd; | ||
778 | u32 __iomem *piobuf; | 872 | u32 __iomem *piobuf; |
779 | u32 plen; | 873 | unsigned flush_wc; |
780 | int ret; | 874 | int ret; |
781 | 875 | ||
782 | /* +1 is for the qword padding of pbc */ | ||
783 | plen = hdrwords + ((len + 3) >> 2) + 1; | ||
784 | if (unlikely((plen << 2) > dd->ipath_ibmaxlen)) { | ||
785 | ret = -EINVAL; | ||
786 | goto bail; | ||
787 | } | ||
788 | |||
789 | /* Get a PIO buffer to use. */ | ||
790 | piobuf = ipath_getpiobuf(dd, NULL); | 876 | piobuf = ipath_getpiobuf(dd, NULL); |
791 | if (unlikely(piobuf == NULL)) { | 877 | if (unlikely(piobuf == NULL)) { |
792 | ret = -EBUSY; | 878 | ret = -EBUSY; |
@@ -799,51 +885,90 @@ int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords, | |||
799 | * or WC buffer can be written out of order. | 885 | * or WC buffer can be written out of order. |
800 | */ | 886 | */ |
801 | writeq(plen, piobuf); | 887 | writeq(plen, piobuf); |
802 | ipath_flush_wc(); | ||
803 | piobuf += 2; | 888 | piobuf += 2; |
889 | |||
890 | flush_wc = dd->ipath_flags & IPATH_PIO_FLUSH_WC; | ||
804 | if (len == 0) { | 891 | if (len == 0) { |
805 | /* | 892 | /* |
806 | * If there is just the header portion, must flush before | 893 | * If there is just the header portion, must flush before |
807 | * writing last word of header for correctness, and after | 894 | * writing last word of header for correctness, and after |
808 | * the last header word (trigger word). | 895 | * the last header word (trigger word). |
809 | */ | 896 | */ |
810 | __iowrite32_copy(piobuf, hdr, hdrwords - 1); | 897 | if (flush_wc) { |
811 | ipath_flush_wc(); | 898 | ipath_flush_wc(); |
812 | __raw_writel(hdr[hdrwords - 1], piobuf + hdrwords - 1); | 899 | __iowrite32_copy(piobuf, hdr, hdrwords - 1); |
813 | ipath_flush_wc(); | 900 | ipath_flush_wc(); |
814 | ret = 0; | 901 | __raw_writel(hdr[hdrwords - 1], piobuf + hdrwords - 1); |
815 | goto bail; | 902 | ipath_flush_wc(); |
903 | } else | ||
904 | __iowrite32_copy(piobuf, hdr, hdrwords); | ||
905 | goto done; | ||
816 | } | 906 | } |
817 | 907 | ||
908 | if (flush_wc) | ||
909 | ipath_flush_wc(); | ||
818 | __iowrite32_copy(piobuf, hdr, hdrwords); | 910 | __iowrite32_copy(piobuf, hdr, hdrwords); |
819 | piobuf += hdrwords; | 911 | piobuf += hdrwords; |
820 | 912 | ||
821 | /* The common case is aligned and contained in one segment. */ | 913 | /* The common case is aligned and contained in one segment. */ |
822 | if (likely(ss->num_sge == 1 && len <= ss->sge.length && | 914 | if (likely(ss->num_sge == 1 && len <= ss->sge.length && |
823 | !((unsigned long)ss->sge.vaddr & (sizeof(u32) - 1)))) { | 915 | !((unsigned long)ss->sge.vaddr & (sizeof(u32) - 1)))) { |
824 | u32 w; | ||
825 | u32 *addr = (u32 *) ss->sge.vaddr; | 916 | u32 *addr = (u32 *) ss->sge.vaddr; |
826 | 917 | ||
827 | /* Update address before sending packet. */ | 918 | /* Update address before sending packet. */ |
828 | update_sge(ss, len); | 919 | update_sge(ss, len); |
829 | /* Need to round up for the last dword in the packet. */ | 920 | if (flush_wc) { |
830 | w = (len + 3) >> 2; | 921 | __iowrite32_copy(piobuf, addr, dwords - 1); |
831 | __iowrite32_copy(piobuf, addr, w - 1); | 922 | /* must flush early everything before trigger word */ |
832 | /* must flush early everything before trigger word */ | 923 | ipath_flush_wc(); |
833 | ipath_flush_wc(); | 924 | __raw_writel(addr[dwords - 1], piobuf + dwords - 1); |
834 | __raw_writel(addr[w - 1], piobuf + w - 1); | 925 | /* be sure trigger word is written */ |
835 | /* be sure trigger word is written */ | 926 | ipath_flush_wc(); |
836 | ipath_flush_wc(); | 927 | } else |
837 | ret = 0; | 928 | __iowrite32_copy(piobuf, addr, dwords); |
838 | goto bail; | 929 | goto done; |
839 | } | 930 | } |
840 | copy_io(piobuf, ss, len); | 931 | copy_io(piobuf, ss, len, flush_wc); |
932 | done: | ||
933 | if (qp->s_wqe) | ||
934 | ipath_send_complete(qp, qp->s_wqe, IB_WC_SUCCESS); | ||
841 | ret = 0; | 935 | ret = 0; |
842 | |||
843 | bail: | 936 | bail: |
844 | return ret; | 937 | return ret; |
845 | } | 938 | } |
846 | 939 | ||
940 | /** | ||
941 | * ipath_verbs_send - send a packet | ||
942 | * @qp: the QP to send on | ||
943 | * @hdr: the packet header | ||
944 | * @hdrwords: the number of words in the header | ||
945 | * @ss: the SGE to send | ||
946 | * @len: the length of the packet in bytes | ||
947 | */ | ||
948 | int ipath_verbs_send(struct ipath_qp *qp, struct ipath_ib_header *hdr, | ||
949 | u32 hdrwords, struct ipath_sge_state *ss, u32 len) | ||
950 | { | ||
951 | struct ipath_devdata *dd = to_idev(qp->ibqp.device)->dd; | ||
952 | u32 plen; | ||
953 | int ret; | ||
954 | u32 dwords = (len + 3) >> 2; | ||
955 | |||
956 | /* +1 is for the qword padding of pbc */ | ||
957 | plen = hdrwords + dwords + 1; | ||
958 | |||
959 | /* Drop non-VL15 packets if we are not in the active state */ | ||
960 | if (!(dd->ipath_flags & IPATH_LINKACTIVE) && | ||
961 | qp->ibqp.qp_type != IB_QPT_SMI) { | ||
962 | if (qp->s_wqe) | ||
963 | ipath_send_complete(qp, qp->s_wqe, IB_WC_SUCCESS); | ||
964 | ret = 0; | ||
965 | } else | ||
966 | ret = ipath_verbs_send_pio(qp, (u32 *) hdr, hdrwords, | ||
967 | ss, len, plen, dwords); | ||
968 | |||
969 | return ret; | ||
970 | } | ||
971 | |||
847 | int ipath_snapshot_counters(struct ipath_devdata *dd, u64 *swords, | 972 | int ipath_snapshot_counters(struct ipath_devdata *dd, u64 *swords, |
848 | u64 *rwords, u64 *spkts, u64 *rpkts, | 973 | u64 *rwords, u64 *spkts, u64 *rpkts, |
849 | u64 *xmit_wait) | 974 | u64 *xmit_wait) |
@@ -852,7 +977,6 @@ int ipath_snapshot_counters(struct ipath_devdata *dd, u64 *swords, | |||
852 | 977 | ||
853 | if (!(dd->ipath_flags & IPATH_INITTED)) { | 978 | if (!(dd->ipath_flags & IPATH_INITTED)) { |
854 | /* no hardware, freeze, etc. */ | 979 | /* no hardware, freeze, etc. */ |
855 | ipath_dbg("unit %u not usable\n", dd->ipath_unit); | ||
856 | ret = -EINVAL; | 980 | ret = -EINVAL; |
857 | goto bail; | 981 | goto bail; |
858 | } | 982 | } |
@@ -878,48 +1002,44 @@ bail: | |||
878 | int ipath_get_counters(struct ipath_devdata *dd, | 1002 | int ipath_get_counters(struct ipath_devdata *dd, |
879 | struct ipath_verbs_counters *cntrs) | 1003 | struct ipath_verbs_counters *cntrs) |
880 | { | 1004 | { |
1005 | struct ipath_cregs const *crp = dd->ipath_cregs; | ||
881 | int ret; | 1006 | int ret; |
882 | 1007 | ||
883 | if (!(dd->ipath_flags & IPATH_INITTED)) { | 1008 | if (!(dd->ipath_flags & IPATH_INITTED)) { |
884 | /* no hardware, freeze, etc. */ | 1009 | /* no hardware, freeze, etc. */ |
885 | ipath_dbg("unit %u not usable\n", dd->ipath_unit); | ||
886 | ret = -EINVAL; | 1010 | ret = -EINVAL; |
887 | goto bail; | 1011 | goto bail; |
888 | } | 1012 | } |
889 | cntrs->symbol_error_counter = | 1013 | cntrs->symbol_error_counter = |
890 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_ibsymbolerrcnt); | 1014 | ipath_snap_cntr(dd, crp->cr_ibsymbolerrcnt); |
891 | cntrs->link_error_recovery_counter = | 1015 | cntrs->link_error_recovery_counter = |
892 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_iblinkerrrecovcnt); | 1016 | ipath_snap_cntr(dd, crp->cr_iblinkerrrecovcnt); |
893 | /* | 1017 | /* |
894 | * The link downed counter counts when the other side downs the | 1018 | * The link downed counter counts when the other side downs the |
895 | * connection. We add in the number of times we downed the link | 1019 | * connection. We add in the number of times we downed the link |
896 | * due to local link integrity errors to compensate. | 1020 | * due to local link integrity errors to compensate. |
897 | */ | 1021 | */ |
898 | cntrs->link_downed_counter = | 1022 | cntrs->link_downed_counter = |
899 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_iblinkdowncnt); | 1023 | ipath_snap_cntr(dd, crp->cr_iblinkdowncnt); |
900 | cntrs->port_rcv_errors = | 1024 | cntrs->port_rcv_errors = |
901 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_rxdroppktcnt) + | 1025 | ipath_snap_cntr(dd, crp->cr_rxdroppktcnt) + |
902 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_rcvovflcnt) + | 1026 | ipath_snap_cntr(dd, crp->cr_rcvovflcnt) + |
903 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_portovflcnt) + | 1027 | ipath_snap_cntr(dd, crp->cr_portovflcnt) + |
904 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_err_rlencnt) + | 1028 | ipath_snap_cntr(dd, crp->cr_err_rlencnt) + |
905 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_invalidrlencnt) + | 1029 | ipath_snap_cntr(dd, crp->cr_invalidrlencnt) + |
906 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_erricrccnt) + | 1030 | ipath_snap_cntr(dd, crp->cr_errlinkcnt) + |
907 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_errvcrccnt) + | 1031 | ipath_snap_cntr(dd, crp->cr_erricrccnt) + |
908 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_errlpcrccnt) + | 1032 | ipath_snap_cntr(dd, crp->cr_errvcrccnt) + |
909 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_badformatcnt) + | 1033 | ipath_snap_cntr(dd, crp->cr_errlpcrccnt) + |
1034 | ipath_snap_cntr(dd, crp->cr_badformatcnt) + | ||
910 | dd->ipath_rxfc_unsupvl_errs; | 1035 | dd->ipath_rxfc_unsupvl_errs; |
911 | cntrs->port_rcv_remphys_errors = | 1036 | cntrs->port_rcv_remphys_errors = |
912 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_rcvebpcnt); | 1037 | ipath_snap_cntr(dd, crp->cr_rcvebpcnt); |
913 | cntrs->port_xmit_discards = | 1038 | cntrs->port_xmit_discards = ipath_snap_cntr(dd, crp->cr_unsupvlcnt); |
914 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_unsupvlcnt); | 1039 | cntrs->port_xmit_data = ipath_snap_cntr(dd, crp->cr_wordsendcnt); |
915 | cntrs->port_xmit_data = | 1040 | cntrs->port_rcv_data = ipath_snap_cntr(dd, crp->cr_wordrcvcnt); |
916 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordsendcnt); | 1041 | cntrs->port_xmit_packets = ipath_snap_cntr(dd, crp->cr_pktsendcnt); |
917 | cntrs->port_rcv_data = | 1042 | cntrs->port_rcv_packets = ipath_snap_cntr(dd, crp->cr_pktrcvcnt); |
918 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_wordrcvcnt); | ||
919 | cntrs->port_xmit_packets = | ||
920 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktsendcnt); | ||
921 | cntrs->port_rcv_packets = | ||
922 | ipath_snap_cntr(dd, dd->ipath_cregs->cr_pktrcvcnt); | ||
923 | cntrs->local_link_integrity_errors = | 1043 | cntrs->local_link_integrity_errors = |
924 | (dd->ipath_flags & IPATH_GPIO_ERRINTRS) ? | 1044 | (dd->ipath_flags & IPATH_GPIO_ERRINTRS) ? |
925 | dd->ipath_lli_errs : dd->ipath_lli_errors; | 1045 | dd->ipath_lli_errs : dd->ipath_lli_errors; |
@@ -1033,25 +1153,26 @@ static int ipath_query_port(struct ib_device *ibdev, | |||
1033 | u8 port, struct ib_port_attr *props) | 1153 | u8 port, struct ib_port_attr *props) |
1034 | { | 1154 | { |
1035 | struct ipath_ibdev *dev = to_idev(ibdev); | 1155 | struct ipath_ibdev *dev = to_idev(ibdev); |
1156 | struct ipath_devdata *dd = dev->dd; | ||
1036 | enum ib_mtu mtu; | 1157 | enum ib_mtu mtu; |
1037 | u16 lid = dev->dd->ipath_lid; | 1158 | u16 lid = dd->ipath_lid; |
1038 | u64 ibcstat; | 1159 | u64 ibcstat; |
1039 | 1160 | ||
1040 | memset(props, 0, sizeof(*props)); | 1161 | memset(props, 0, sizeof(*props)); |
1041 | props->lid = lid ? lid : __constant_be16_to_cpu(IB_LID_PERMISSIVE); | 1162 | props->lid = lid ? lid : __constant_be16_to_cpu(IB_LID_PERMISSIVE); |
1042 | props->lmc = dev->mkeyprot_resv_lmc & 7; | 1163 | props->lmc = dd->ipath_lmc; |
1043 | props->sm_lid = dev->sm_lid; | 1164 | props->sm_lid = dev->sm_lid; |
1044 | props->sm_sl = dev->sm_sl; | 1165 | props->sm_sl = dev->sm_sl; |
1045 | ibcstat = dev->dd->ipath_lastibcstat; | 1166 | ibcstat = dd->ipath_lastibcstat; |
1046 | props->state = ((ibcstat >> 4) & 0x3) + 1; | 1167 | props->state = ((ibcstat >> 4) & 0x3) + 1; |
1047 | /* See phys_state_show() */ | 1168 | /* See phys_state_show() */ |
1048 | props->phys_state = ipath_cvt_physportstate[ | 1169 | props->phys_state = ipath_cvt_physportstate[ |
1049 | dev->dd->ipath_lastibcstat & 0xf]; | 1170 | dd->ipath_lastibcstat & 0xf]; |
1050 | props->port_cap_flags = dev->port_cap_flags; | 1171 | props->port_cap_flags = dev->port_cap_flags; |
1051 | props->gid_tbl_len = 1; | 1172 | props->gid_tbl_len = 1; |
1052 | props->max_msg_sz = 0x80000000; | 1173 | props->max_msg_sz = 0x80000000; |
1053 | props->pkey_tbl_len = ipath_get_npkeys(dev->dd); | 1174 | props->pkey_tbl_len = ipath_get_npkeys(dd); |
1054 | props->bad_pkey_cntr = ipath_get_cr_errpkey(dev->dd) - | 1175 | props->bad_pkey_cntr = ipath_get_cr_errpkey(dd) - |
1055 | dev->z_pkey_violations; | 1176 | dev->z_pkey_violations; |
1056 | props->qkey_viol_cntr = dev->qkey_violations; | 1177 | props->qkey_viol_cntr = dev->qkey_violations; |
1057 | props->active_width = IB_WIDTH_4X; | 1178 | props->active_width = IB_WIDTH_4X; |
@@ -1061,12 +1182,12 @@ static int ipath_query_port(struct ib_device *ibdev, | |||
1061 | props->init_type_reply = 0; | 1182 | props->init_type_reply = 0; |
1062 | 1183 | ||
1063 | /* | 1184 | /* |
1064 | * Note: the chips support a maximum MTU of 4096, but the driver | 1185 | * Note: the chip supports a maximum MTU of 4096, but the driver |
1065 | * hasn't implemented this feature yet, so set the maximum value | 1186 | * hasn't implemented this feature yet, so set the maximum value |
1066 | * to 2048. | 1187 | * to 2048. |
1067 | */ | 1188 | */ |
1068 | props->max_mtu = IB_MTU_2048; | 1189 | props->max_mtu = IB_MTU_2048; |
1069 | switch (dev->dd->ipath_ibmtu) { | 1190 | switch (dd->ipath_ibmtu) { |
1070 | case 4096: | 1191 | case 4096: |
1071 | mtu = IB_MTU_4096; | 1192 | mtu = IB_MTU_4096; |
1072 | break; | 1193 | break; |
@@ -1415,9 +1536,7 @@ static int disable_timer(struct ipath_devdata *dd) | |||
1415 | { | 1536 | { |
1416 | /* Disable GPIO bit 2 interrupt */ | 1537 | /* Disable GPIO bit 2 interrupt */ |
1417 | if (dd->ipath_flags & IPATH_GPIO_INTR) { | 1538 | if (dd->ipath_flags & IPATH_GPIO_INTR) { |
1418 | u64 val; | ||
1419 | /* Disable GPIO bit 2 interrupt */ | 1539 | /* Disable GPIO bit 2 interrupt */ |
1420 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_gpio_mask); | ||
1421 | dd->ipath_gpio_mask &= ~((u64) (1 << IPATH_GPIO_PORT0_BIT)); | 1540 | dd->ipath_gpio_mask &= ~((u64) (1 << IPATH_GPIO_PORT0_BIT)); |
1422 | ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask, | 1541 | ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask, |
1423 | dd->ipath_gpio_mask); | 1542 | dd->ipath_gpio_mask); |
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h index 1a24c6a4a814..6ccb54f104a3 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.h +++ b/drivers/infiniband/hw/ipath/ipath_verbs.h | |||
@@ -42,6 +42,8 @@ | |||
42 | #include <rdma/ib_pack.h> | 42 | #include <rdma/ib_pack.h> |
43 | #include <rdma/ib_user_verbs.h> | 43 | #include <rdma/ib_user_verbs.h> |
44 | 44 | ||
45 | #include "ipath_kernel.h" | ||
46 | |||
45 | #define IPATH_MAX_RDMA_ATOMIC 4 | 47 | #define IPATH_MAX_RDMA_ATOMIC 4 |
46 | 48 | ||
47 | #define QPN_MAX (1 << 24) | 49 | #define QPN_MAX (1 << 24) |
@@ -59,6 +61,7 @@ | |||
59 | */ | 61 | */ |
60 | #define IB_CQ_NONE (IB_CQ_NEXT_COMP + 1) | 62 | #define IB_CQ_NONE (IB_CQ_NEXT_COMP + 1) |
61 | 63 | ||
64 | /* AETH NAK opcode values */ | ||
62 | #define IB_RNR_NAK 0x20 | 65 | #define IB_RNR_NAK 0x20 |
63 | #define IB_NAK_PSN_ERROR 0x60 | 66 | #define IB_NAK_PSN_ERROR 0x60 |
64 | #define IB_NAK_INVALID_REQUEST 0x61 | 67 | #define IB_NAK_INVALID_REQUEST 0x61 |
@@ -66,6 +69,7 @@ | |||
66 | #define IB_NAK_REMOTE_OPERATIONAL_ERROR 0x63 | 69 | #define IB_NAK_REMOTE_OPERATIONAL_ERROR 0x63 |
67 | #define IB_NAK_INVALID_RD_REQUEST 0x64 | 70 | #define IB_NAK_INVALID_RD_REQUEST 0x64 |
68 | 71 | ||
72 | /* Flags for checking QP state (see ib_ipath_state_ops[]) */ | ||
69 | #define IPATH_POST_SEND_OK 0x01 | 73 | #define IPATH_POST_SEND_OK 0x01 |
70 | #define IPATH_POST_RECV_OK 0x02 | 74 | #define IPATH_POST_RECV_OK 0x02 |
71 | #define IPATH_PROCESS_RECV_OK 0x04 | 75 | #define IPATH_PROCESS_RECV_OK 0x04 |
@@ -187,7 +191,11 @@ struct ipath_mmap_info { | |||
187 | struct ipath_cq_wc { | 191 | struct ipath_cq_wc { |
188 | u32 head; /* index of next entry to fill */ | 192 | u32 head; /* index of next entry to fill */ |
189 | u32 tail; /* index of next ib_poll_cq() entry */ | 193 | u32 tail; /* index of next ib_poll_cq() entry */ |
190 | struct ib_uverbs_wc queue[1]; /* this is actually size ibcq.cqe + 1 */ | 194 | union { |
195 | /* these are actually size ibcq.cqe + 1 */ | ||
196 | struct ib_uverbs_wc uqueue[0]; | ||
197 | struct ib_wc kqueue[0]; | ||
198 | }; | ||
191 | }; | 199 | }; |
192 | 200 | ||
193 | /* | 201 | /* |
@@ -239,7 +247,7 @@ struct ipath_mregion { | |||
239 | */ | 247 | */ |
240 | struct ipath_sge { | 248 | struct ipath_sge { |
241 | struct ipath_mregion *mr; | 249 | struct ipath_mregion *mr; |
242 | void *vaddr; /* current pointer into the segment */ | 250 | void *vaddr; /* kernel virtual address of segment */ |
243 | u32 sge_length; /* length of the SGE */ | 251 | u32 sge_length; /* length of the SGE */ |
244 | u32 length; /* remaining length of the segment */ | 252 | u32 length; /* remaining length of the segment */ |
245 | u16 m; /* current index: mr->map[m] */ | 253 | u16 m; /* current index: mr->map[m] */ |
@@ -407,6 +415,7 @@ struct ipath_qp { | |||
407 | u32 s_ssn; /* SSN of tail entry */ | 415 | u32 s_ssn; /* SSN of tail entry */ |
408 | u32 s_lsn; /* limit sequence number (credit) */ | 416 | u32 s_lsn; /* limit sequence number (credit) */ |
409 | struct ipath_swqe *s_wq; /* send work queue */ | 417 | struct ipath_swqe *s_wq; /* send work queue */ |
418 | struct ipath_swqe *s_wqe; | ||
410 | struct ipath_rq r_rq; /* receive work queue */ | 419 | struct ipath_rq r_rq; /* receive work queue */ |
411 | struct ipath_sge r_sg_list[0]; /* verified SGEs */ | 420 | struct ipath_sge r_sg_list[0]; /* verified SGEs */ |
412 | }; | 421 | }; |
@@ -492,7 +501,7 @@ struct ipath_ibdev { | |||
492 | int ib_unit; /* This is the device number */ | 501 | int ib_unit; /* This is the device number */ |
493 | u16 sm_lid; /* in host order */ | 502 | u16 sm_lid; /* in host order */ |
494 | u8 sm_sl; | 503 | u8 sm_sl; |
495 | u8 mkeyprot_resv_lmc; | 504 | u8 mkeyprot; |
496 | /* non-zero when timer is set */ | 505 | /* non-zero when timer is set */ |
497 | unsigned long mkey_lease_timeout; | 506 | unsigned long mkey_lease_timeout; |
498 | 507 | ||
@@ -667,7 +676,7 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd, | |||
667 | 676 | ||
668 | int ipath_destroy_qp(struct ib_qp *ibqp); | 677 | int ipath_destroy_qp(struct ib_qp *ibqp); |
669 | 678 | ||
670 | void ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err); | 679 | int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err); |
671 | 680 | ||
672 | int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | 681 | int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, |
673 | int attr_mask, struct ib_udata *udata); | 682 | int attr_mask, struct ib_udata *udata); |
@@ -683,8 +692,8 @@ void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc); | |||
683 | 692 | ||
684 | void ipath_get_credit(struct ipath_qp *qp, u32 aeth); | 693 | void ipath_get_credit(struct ipath_qp *qp, u32 aeth); |
685 | 694 | ||
686 | int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords, | 695 | int ipath_verbs_send(struct ipath_qp *qp, struct ipath_ib_header *hdr, |
687 | u32 *hdr, u32 len, struct ipath_sge_state *ss); | 696 | u32 hdrwords, struct ipath_sge_state *ss, u32 len); |
688 | 697 | ||
689 | void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int sig); | 698 | void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int sig); |
690 | 699 | ||
@@ -692,8 +701,6 @@ void ipath_copy_sge(struct ipath_sge_state *ss, void *data, u32 length); | |||
692 | 701 | ||
693 | void ipath_skip_sge(struct ipath_sge_state *ss, u32 length); | 702 | void ipath_skip_sge(struct ipath_sge_state *ss, u32 length); |
694 | 703 | ||
695 | int ipath_post_ruc_send(struct ipath_qp *qp, struct ib_send_wr *wr); | ||
696 | |||
697 | void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, | 704 | void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, |
698 | int has_grh, void *data, u32 tlen, struct ipath_qp *qp); | 705 | int has_grh, void *data, u32 tlen, struct ipath_qp *qp); |
699 | 706 | ||
@@ -733,6 +740,8 @@ int ipath_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr); | |||
733 | 740 | ||
734 | int ipath_destroy_srq(struct ib_srq *ibsrq); | 741 | int ipath_destroy_srq(struct ib_srq *ibsrq); |
735 | 742 | ||
743 | void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int sig); | ||
744 | |||
736 | int ipath_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry); | 745 | int ipath_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry); |
737 | 746 | ||
738 | struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, int comp_vector, | 747 | struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, int comp_vector, |
@@ -782,18 +791,28 @@ int ipath_mmap(struct ib_ucontext *context, struct vm_area_struct *vma); | |||
782 | 791 | ||
783 | void ipath_insert_rnr_queue(struct ipath_qp *qp); | 792 | void ipath_insert_rnr_queue(struct ipath_qp *qp); |
784 | 793 | ||
794 | int ipath_init_sge(struct ipath_qp *qp, struct ipath_rwqe *wqe, | ||
795 | u32 *lengthp, struct ipath_sge_state *ss); | ||
796 | |||
785 | int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only); | 797 | int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only); |
786 | 798 | ||
787 | u32 ipath_make_grh(struct ipath_ibdev *dev, struct ib_grh *hdr, | 799 | u32 ipath_make_grh(struct ipath_ibdev *dev, struct ib_grh *hdr, |
788 | struct ib_global_route *grh, u32 hwords, u32 nwords); | 800 | struct ib_global_route *grh, u32 hwords, u32 nwords); |
789 | 801 | ||
790 | void ipath_do_ruc_send(unsigned long data); | 802 | void ipath_make_ruc_header(struct ipath_ibdev *dev, struct ipath_qp *qp, |
803 | struct ipath_other_headers *ohdr, | ||
804 | u32 bth0, u32 bth2); | ||
805 | |||
806 | void ipath_do_send(unsigned long data); | ||
807 | |||
808 | void ipath_send_complete(struct ipath_qp *qp, struct ipath_swqe *wqe, | ||
809 | enum ib_wc_status status); | ||
810 | |||
811 | int ipath_make_rc_req(struct ipath_qp *qp); | ||
791 | 812 | ||
792 | int ipath_make_rc_req(struct ipath_qp *qp, struct ipath_other_headers *ohdr, | 813 | int ipath_make_uc_req(struct ipath_qp *qp); |
793 | u32 pmtu, u32 *bth0p, u32 *bth2p); | ||
794 | 814 | ||
795 | int ipath_make_uc_req(struct ipath_qp *qp, struct ipath_other_headers *ohdr, | 815 | int ipath_make_ud_req(struct ipath_qp *qp); |
796 | u32 pmtu, u32 *bth0p, u32 *bth2p); | ||
797 | 816 | ||
798 | int ipath_register_ib_device(struct ipath_devdata *); | 817 | int ipath_register_ib_device(struct ipath_devdata *); |
799 | 818 | ||
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c index 660b27aecae5..8bf44daf45ec 100644 --- a/drivers/infiniband/hw/mlx4/cq.c +++ b/drivers/infiniband/hw/mlx4/cq.c | |||
@@ -389,7 +389,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq, | |||
389 | wc->opcode = IB_WC_SEND; | 389 | wc->opcode = IB_WC_SEND; |
390 | break; | 390 | break; |
391 | case MLX4_OPCODE_RDMA_READ: | 391 | case MLX4_OPCODE_RDMA_READ: |
392 | wc->opcode = IB_WC_SEND; | 392 | wc->opcode = IB_WC_RDMA_READ; |
393 | wc->byte_len = be32_to_cpu(cqe->byte_cnt); | 393 | wc->byte_len = be32_to_cpu(cqe->byte_cnt); |
394 | break; | 394 | break; |
395 | case MLX4_OPCODE_ATOMIC_CS: | 395 | case MLX4_OPCODE_ATOMIC_CS: |
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index 333091787c5f..0ed02b7834da 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c | |||
@@ -109,7 +109,7 @@ int mlx4_MAD_IFC(struct mlx4_ib_dev *dev, int ignore_mkey, int ignore_bkey, | |||
109 | in_modifier, op_modifier, | 109 | in_modifier, op_modifier, |
110 | MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C); | 110 | MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C); |
111 | 111 | ||
112 | if (!err); | 112 | if (!err) |
113 | memcpy(response_mad, outmailbox->buf, 256); | 113 | memcpy(response_mad, outmailbox->buf, 256); |
114 | 114 | ||
115 | mlx4_free_cmd_mailbox(dev->dev, inmailbox); | 115 | mlx4_free_cmd_mailbox(dev->dev, inmailbox); |
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index dde8fe9af47e..d8287d9db41e 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
@@ -476,9 +476,48 @@ out: | |||
476 | return err; | 476 | return err; |
477 | } | 477 | } |
478 | 478 | ||
479 | static ssize_t show_hca(struct class_device *cdev, char *buf) | ||
480 | { | ||
481 | struct mlx4_ib_dev *dev = container_of(cdev, struct mlx4_ib_dev, ib_dev.class_dev); | ||
482 | return sprintf(buf, "MT%d\n", dev->dev->pdev->device); | ||
483 | } | ||
484 | |||
485 | static ssize_t show_fw_ver(struct class_device *cdev, char *buf) | ||
486 | { | ||
487 | struct mlx4_ib_dev *dev = container_of(cdev, struct mlx4_ib_dev, ib_dev.class_dev); | ||
488 | return sprintf(buf, "%d.%d.%d\n", (int) (dev->dev->caps.fw_ver >> 32), | ||
489 | (int) (dev->dev->caps.fw_ver >> 16) & 0xffff, | ||
490 | (int) dev->dev->caps.fw_ver & 0xffff); | ||
491 | } | ||
492 | |||
493 | static ssize_t show_rev(struct class_device *cdev, char *buf) | ||
494 | { | ||
495 | struct mlx4_ib_dev *dev = container_of(cdev, struct mlx4_ib_dev, ib_dev.class_dev); | ||
496 | return sprintf(buf, "%x\n", dev->dev->rev_id); | ||
497 | } | ||
498 | |||
499 | static ssize_t show_board(struct class_device *cdev, char *buf) | ||
500 | { | ||
501 | struct mlx4_ib_dev *dev = container_of(cdev, struct mlx4_ib_dev, ib_dev.class_dev); | ||
502 | return sprintf(buf, "%.*s\n", MLX4_BOARD_ID_LEN, dev->dev->board_id); | ||
503 | } | ||
504 | |||
505 | static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); | ||
506 | static CLASS_DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL); | ||
507 | static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL); | ||
508 | static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL); | ||
509 | |||
510 | static struct class_device_attribute *mlx4_class_attributes[] = { | ||
511 | &class_device_attr_hw_rev, | ||
512 | &class_device_attr_fw_ver, | ||
513 | &class_device_attr_hca_type, | ||
514 | &class_device_attr_board_id | ||
515 | }; | ||
516 | |||
479 | static void *mlx4_ib_add(struct mlx4_dev *dev) | 517 | static void *mlx4_ib_add(struct mlx4_dev *dev) |
480 | { | 518 | { |
481 | struct mlx4_ib_dev *ibdev; | 519 | struct mlx4_ib_dev *ibdev; |
520 | int i; | ||
482 | 521 | ||
483 | ibdev = (struct mlx4_ib_dev *) ib_alloc_device(sizeof *ibdev); | 522 | ibdev = (struct mlx4_ib_dev *) ib_alloc_device(sizeof *ibdev); |
484 | if (!ibdev) { | 523 | if (!ibdev) { |
@@ -568,6 +607,11 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) | |||
568 | ibdev->ib_dev.detach_mcast = mlx4_ib_mcg_detach; | 607 | ibdev->ib_dev.detach_mcast = mlx4_ib_mcg_detach; |
569 | ibdev->ib_dev.process_mad = mlx4_ib_process_mad; | 608 | ibdev->ib_dev.process_mad = mlx4_ib_process_mad; |
570 | 609 | ||
610 | ibdev->ib_dev.alloc_fmr = mlx4_ib_fmr_alloc; | ||
611 | ibdev->ib_dev.map_phys_fmr = mlx4_ib_map_phys_fmr; | ||
612 | ibdev->ib_dev.unmap_fmr = mlx4_ib_unmap_fmr; | ||
613 | ibdev->ib_dev.dealloc_fmr = mlx4_ib_fmr_dealloc; | ||
614 | |||
571 | if (init_node_data(ibdev)) | 615 | if (init_node_data(ibdev)) |
572 | goto err_map; | 616 | goto err_map; |
573 | 617 | ||
@@ -580,6 +624,12 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) | |||
580 | if (mlx4_ib_mad_init(ibdev)) | 624 | if (mlx4_ib_mad_init(ibdev)) |
581 | goto err_reg; | 625 | goto err_reg; |
582 | 626 | ||
627 | for (i = 0; i < ARRAY_SIZE(mlx4_class_attributes); ++i) { | ||
628 | if (class_device_create_file(&ibdev->ib_dev.class_dev, | ||
629 | mlx4_class_attributes[i])) | ||
630 | goto err_reg; | ||
631 | } | ||
632 | |||
583 | return ibdev; | 633 | return ibdev; |
584 | 634 | ||
585 | err_reg: | 635 | err_reg: |
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h index 705ff2fa237e..28697653a370 100644 --- a/drivers/infiniband/hw/mlx4/mlx4_ib.h +++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h | |||
@@ -93,6 +93,11 @@ struct mlx4_ib_mr { | |||
93 | struct ib_umem *umem; | 93 | struct ib_umem *umem; |
94 | }; | 94 | }; |
95 | 95 | ||
96 | struct mlx4_ib_fmr { | ||
97 | struct ib_fmr ibfmr; | ||
98 | struct mlx4_fmr mfmr; | ||
99 | }; | ||
100 | |||
96 | struct mlx4_ib_wq { | 101 | struct mlx4_ib_wq { |
97 | u64 *wrid; | 102 | u64 *wrid; |
98 | spinlock_t lock; | 103 | spinlock_t lock; |
@@ -199,6 +204,10 @@ static inline struct mlx4_ib_mr *to_mmr(struct ib_mr *ibmr) | |||
199 | return container_of(ibmr, struct mlx4_ib_mr, ibmr); | 204 | return container_of(ibmr, struct mlx4_ib_mr, ibmr); |
200 | } | 205 | } |
201 | 206 | ||
207 | static inline struct mlx4_ib_fmr *to_mfmr(struct ib_fmr *ibfmr) | ||
208 | { | ||
209 | return container_of(ibfmr, struct mlx4_ib_fmr, ibfmr); | ||
210 | } | ||
202 | static inline struct mlx4_ib_qp *to_mqp(struct ib_qp *ibqp) | 211 | static inline struct mlx4_ib_qp *to_mqp(struct ib_qp *ibqp) |
203 | { | 212 | { |
204 | return container_of(ibqp, struct mlx4_ib_qp, ibqp); | 213 | return container_of(ibqp, struct mlx4_ib_qp, ibqp); |
@@ -284,6 +293,13 @@ int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, | |||
284 | int mlx4_ib_mad_init(struct mlx4_ib_dev *dev); | 293 | int mlx4_ib_mad_init(struct mlx4_ib_dev *dev); |
285 | void mlx4_ib_mad_cleanup(struct mlx4_ib_dev *dev); | 294 | void mlx4_ib_mad_cleanup(struct mlx4_ib_dev *dev); |
286 | 295 | ||
296 | struct ib_fmr *mlx4_ib_fmr_alloc(struct ib_pd *pd, int mr_access_flags, | ||
297 | struct ib_fmr_attr *fmr_attr); | ||
298 | int mlx4_ib_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list, int npages, | ||
299 | u64 iova); | ||
300 | int mlx4_ib_unmap_fmr(struct list_head *fmr_list); | ||
301 | int mlx4_ib_fmr_dealloc(struct ib_fmr *fmr); | ||
302 | |||
287 | static inline int mlx4_ib_ah_grh_present(struct mlx4_ib_ah *ah) | 303 | static inline int mlx4_ib_ah_grh_present(struct mlx4_ib_ah *ah) |
288 | { | 304 | { |
289 | return !!(ah->av.g_slid & 0x80); | 305 | return !!(ah->av.g_slid & 0x80); |
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c index 85ae906f1d12..7dc91a3e712d 100644 --- a/drivers/infiniband/hw/mlx4/mr.c +++ b/drivers/infiniband/hw/mlx4/mr.c | |||
@@ -96,11 +96,10 @@ int mlx4_ib_umem_write_mtt(struct mlx4_ib_dev *dev, struct mlx4_mtt *mtt, | |||
96 | pages[i++] = sg_dma_address(&chunk->page_list[j]) + | 96 | pages[i++] = sg_dma_address(&chunk->page_list[j]) + |
97 | umem->page_size * k; | 97 | umem->page_size * k; |
98 | /* | 98 | /* |
99 | * Be friendly to WRITE_MTT firmware | 99 | * Be friendly to mlx4_write_mtt() and |
100 | * command, and pass it chunks of | 100 | * pass it chunks of appropriate size. |
101 | * appropriate size. | ||
102 | */ | 101 | */ |
103 | if (i == PAGE_SIZE / sizeof (u64) - 2) { | 102 | if (i == PAGE_SIZE / sizeof (u64)) { |
104 | err = mlx4_write_mtt(dev->dev, mtt, n, | 103 | err = mlx4_write_mtt(dev->dev, mtt, n, |
105 | i, pages); | 104 | i, pages); |
106 | if (err) | 105 | if (err) |
@@ -182,3 +181,96 @@ int mlx4_ib_dereg_mr(struct ib_mr *ibmr) | |||
182 | 181 | ||
183 | return 0; | 182 | return 0; |
184 | } | 183 | } |
184 | |||
185 | struct ib_fmr *mlx4_ib_fmr_alloc(struct ib_pd *pd, int acc, | ||
186 | struct ib_fmr_attr *fmr_attr) | ||
187 | { | ||
188 | struct mlx4_ib_dev *dev = to_mdev(pd->device); | ||
189 | struct mlx4_ib_fmr *fmr; | ||
190 | int err = -ENOMEM; | ||
191 | |||
192 | fmr = kmalloc(sizeof *fmr, GFP_KERNEL); | ||
193 | if (!fmr) | ||
194 | return ERR_PTR(-ENOMEM); | ||
195 | |||
196 | err = mlx4_fmr_alloc(dev->dev, to_mpd(pd)->pdn, convert_access(acc), | ||
197 | fmr_attr->max_pages, fmr_attr->max_maps, | ||
198 | fmr_attr->page_shift, &fmr->mfmr); | ||
199 | if (err) | ||
200 | goto err_free; | ||
201 | |||
202 | err = mlx4_mr_enable(to_mdev(pd->device)->dev, &fmr->mfmr.mr); | ||
203 | if (err) | ||
204 | goto err_mr; | ||
205 | |||
206 | fmr->ibfmr.rkey = fmr->ibfmr.lkey = fmr->mfmr.mr.key; | ||
207 | |||
208 | return &fmr->ibfmr; | ||
209 | |||
210 | err_mr: | ||
211 | mlx4_mr_free(to_mdev(pd->device)->dev, &fmr->mfmr.mr); | ||
212 | |||
213 | err_free: | ||
214 | kfree(fmr); | ||
215 | |||
216 | return ERR_PTR(err); | ||
217 | } | ||
218 | |||
219 | int mlx4_ib_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list, | ||
220 | int npages, u64 iova) | ||
221 | { | ||
222 | struct mlx4_ib_fmr *ifmr = to_mfmr(ibfmr); | ||
223 | struct mlx4_ib_dev *dev = to_mdev(ifmr->ibfmr.device); | ||
224 | |||
225 | return mlx4_map_phys_fmr(dev->dev, &ifmr->mfmr, page_list, npages, iova, | ||
226 | &ifmr->ibfmr.lkey, &ifmr->ibfmr.rkey); | ||
227 | } | ||
228 | |||
229 | int mlx4_ib_unmap_fmr(struct list_head *fmr_list) | ||
230 | { | ||
231 | struct ib_fmr *ibfmr; | ||
232 | int err; | ||
233 | struct mlx4_dev *mdev = NULL; | ||
234 | |||
235 | list_for_each_entry(ibfmr, fmr_list, list) { | ||
236 | if (mdev && to_mdev(ibfmr->device)->dev != mdev) | ||
237 | return -EINVAL; | ||
238 | mdev = to_mdev(ibfmr->device)->dev; | ||
239 | } | ||
240 | |||
241 | if (!mdev) | ||
242 | return 0; | ||
243 | |||
244 | list_for_each_entry(ibfmr, fmr_list, list) { | ||
245 | struct mlx4_ib_fmr *ifmr = to_mfmr(ibfmr); | ||
246 | |||
247 | mlx4_fmr_unmap(mdev, &ifmr->mfmr, &ifmr->ibfmr.lkey, &ifmr->ibfmr.rkey); | ||
248 | } | ||
249 | |||
250 | /* | ||
251 | * Make sure all MPT status updates are visible before issuing | ||
252 | * SYNC_TPT firmware command. | ||
253 | */ | ||
254 | wmb(); | ||
255 | |||
256 | err = mlx4_SYNC_TPT(mdev); | ||
257 | if (err) | ||
258 | printk(KERN_WARNING "mlx4_ib: SYNC_TPT error %d when " | ||
259 | "unmapping FMRs\n", err); | ||
260 | |||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | int mlx4_ib_fmr_dealloc(struct ib_fmr *ibfmr) | ||
265 | { | ||
266 | struct mlx4_ib_fmr *ifmr = to_mfmr(ibfmr); | ||
267 | struct mlx4_ib_dev *dev = to_mdev(ibfmr->device); | ||
268 | int err; | ||
269 | |||
270 | err = mlx4_fmr_free(dev->dev, &ifmr->mfmr); | ||
271 | |||
272 | if (!err) | ||
273 | kfree(ifmr); | ||
274 | |||
275 | return err; | ||
276 | } | ||
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index ba0428d872aa..31a480e5b0d0 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
@@ -1211,8 +1211,45 @@ static void set_datagram_seg(struct mlx4_wqe_datagram_seg *dseg, | |||
1211 | dseg->qkey = cpu_to_be32(wr->wr.ud.remote_qkey); | 1211 | dseg->qkey = cpu_to_be32(wr->wr.ud.remote_qkey); |
1212 | } | 1212 | } |
1213 | 1213 | ||
1214 | static void set_data_seg(struct mlx4_wqe_data_seg *dseg, | 1214 | static void set_mlx_icrc_seg(void *dseg) |
1215 | struct ib_sge *sg) | 1215 | { |
1216 | u32 *t = dseg; | ||
1217 | struct mlx4_wqe_inline_seg *iseg = dseg; | ||
1218 | |||
1219 | t[1] = 0; | ||
1220 | |||
1221 | /* | ||
1222 | * Need a barrier here before writing the byte_count field to | ||
1223 | * make sure that all the data is visible before the | ||
1224 | * byte_count field is set. Otherwise, if the segment begins | ||
1225 | * a new cacheline, the HCA prefetcher could grab the 64-byte | ||
1226 | * chunk and get a valid (!= * 0xffffffff) byte count but | ||
1227 | * stale data, and end up sending the wrong data. | ||
1228 | */ | ||
1229 | wmb(); | ||
1230 | |||
1231 | iseg->byte_count = cpu_to_be32((1 << 31) | 4); | ||
1232 | } | ||
1233 | |||
1234 | static void set_data_seg(struct mlx4_wqe_data_seg *dseg, struct ib_sge *sg) | ||
1235 | { | ||
1236 | dseg->lkey = cpu_to_be32(sg->lkey); | ||
1237 | dseg->addr = cpu_to_be64(sg->addr); | ||
1238 | |||
1239 | /* | ||
1240 | * Need a barrier here before writing the byte_count field to | ||
1241 | * make sure that all the data is visible before the | ||
1242 | * byte_count field is set. Otherwise, if the segment begins | ||
1243 | * a new cacheline, the HCA prefetcher could grab the 64-byte | ||
1244 | * chunk and get a valid (!= * 0xffffffff) byte count but | ||
1245 | * stale data, and end up sending the wrong data. | ||
1246 | */ | ||
1247 | wmb(); | ||
1248 | |||
1249 | dseg->byte_count = cpu_to_be32(sg->length); | ||
1250 | } | ||
1251 | |||
1252 | static void __set_data_seg(struct mlx4_wqe_data_seg *dseg, struct ib_sge *sg) | ||
1216 | { | 1253 | { |
1217 | dseg->byte_count = cpu_to_be32(sg->length); | 1254 | dseg->byte_count = cpu_to_be32(sg->length); |
1218 | dseg->lkey = cpu_to_be32(sg->lkey); | 1255 | dseg->lkey = cpu_to_be32(sg->lkey); |
@@ -1225,6 +1262,7 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
1225 | struct mlx4_ib_qp *qp = to_mqp(ibqp); | 1262 | struct mlx4_ib_qp *qp = to_mqp(ibqp); |
1226 | void *wqe; | 1263 | void *wqe; |
1227 | struct mlx4_wqe_ctrl_seg *ctrl; | 1264 | struct mlx4_wqe_ctrl_seg *ctrl; |
1265 | struct mlx4_wqe_data_seg *dseg; | ||
1228 | unsigned long flags; | 1266 | unsigned long flags; |
1229 | int nreq; | 1267 | int nreq; |
1230 | int err = 0; | 1268 | int err = 0; |
@@ -1324,22 +1362,27 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
1324 | break; | 1362 | break; |
1325 | } | 1363 | } |
1326 | 1364 | ||
1327 | for (i = 0; i < wr->num_sge; ++i) { | 1365 | /* |
1328 | set_data_seg(wqe, wr->sg_list + i); | 1366 | * Write data segments in reverse order, so as to |
1367 | * overwrite cacheline stamp last within each | ||
1368 | * cacheline. This avoids issues with WQE | ||
1369 | * prefetching. | ||
1370 | */ | ||
1329 | 1371 | ||
1330 | wqe += sizeof (struct mlx4_wqe_data_seg); | 1372 | dseg = wqe; |
1331 | size += sizeof (struct mlx4_wqe_data_seg) / 16; | 1373 | dseg += wr->num_sge - 1; |
1332 | } | 1374 | size += wr->num_sge * (sizeof (struct mlx4_wqe_data_seg) / 16); |
1333 | 1375 | ||
1334 | /* Add one more inline data segment for ICRC for MLX sends */ | 1376 | /* Add one more inline data segment for ICRC for MLX sends */ |
1335 | if (qp->ibqp.qp_type == IB_QPT_SMI || qp->ibqp.qp_type == IB_QPT_GSI) { | 1377 | if (unlikely(qp->ibqp.qp_type == IB_QPT_SMI || |
1336 | ((struct mlx4_wqe_inline_seg *) wqe)->byte_count = | 1378 | qp->ibqp.qp_type == IB_QPT_GSI)) { |
1337 | cpu_to_be32((1 << 31) | 4); | 1379 | set_mlx_icrc_seg(dseg + 1); |
1338 | ((u32 *) wqe)[1] = 0; | ||
1339 | wqe += sizeof (struct mlx4_wqe_data_seg); | ||
1340 | size += sizeof (struct mlx4_wqe_data_seg) / 16; | 1380 | size += sizeof (struct mlx4_wqe_data_seg) / 16; |
1341 | } | 1381 | } |
1342 | 1382 | ||
1383 | for (i = wr->num_sge - 1; i >= 0; --i, --dseg) | ||
1384 | set_data_seg(dseg, wr->sg_list + i); | ||
1385 | |||
1343 | ctrl->fence_size = (wr->send_flags & IB_SEND_FENCE ? | 1386 | ctrl->fence_size = (wr->send_flags & IB_SEND_FENCE ? |
1344 | MLX4_WQE_CTRL_FENCE : 0) | size; | 1387 | MLX4_WQE_CTRL_FENCE : 0) | size; |
1345 | 1388 | ||
@@ -1428,11 +1471,8 @@ int mlx4_ib_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr, | |||
1428 | 1471 | ||
1429 | scat = get_recv_wqe(qp, ind); | 1472 | scat = get_recv_wqe(qp, ind); |
1430 | 1473 | ||
1431 | for (i = 0; i < wr->num_sge; ++i) { | 1474 | for (i = 0; i < wr->num_sge; ++i) |
1432 | scat[i].byte_count = cpu_to_be32(wr->sg_list[i].length); | 1475 | __set_data_seg(scat + i, wr->sg_list + i); |
1433 | scat[i].lkey = cpu_to_be32(wr->sg_list[i].lkey); | ||
1434 | scat[i].addr = cpu_to_be64(wr->sg_list[i].addr); | ||
1435 | } | ||
1436 | 1476 | ||
1437 | if (i < qp->rq.max_gs) { | 1477 | if (i < qp->rq.max_gs) { |
1438 | scat[i].byte_count = 0; | 1478 | scat[i].byte_count = 0; |
diff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index 408748fb5285..e7e9a3d0dac3 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c | |||
@@ -251,7 +251,7 @@ int mlx4_ib_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr) | |||
251 | if (ret) | 251 | if (ret) |
252 | return ret; | 252 | return ret; |
253 | 253 | ||
254 | srq_attr->srq_limit = be16_to_cpu(limit_watermark); | 254 | srq_attr->srq_limit = limit_watermark; |
255 | srq_attr->max_wr = srq->msrq.max - 1; | 255 | srq_attr->max_wr = srq->msrq.max - 1; |
256 | srq_attr->max_sge = srq->msrq.max_gs; | 256 | srq_attr->max_sge = srq->msrq.max_gs; |
257 | 257 | ||
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index acc95892713a..6966f943f440 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c | |||
@@ -290,6 +290,12 @@ static int mthca_cmd_post(struct mthca_dev *dev, | |||
290 | err = mthca_cmd_post_hcr(dev, in_param, out_param, in_modifier, | 290 | err = mthca_cmd_post_hcr(dev, in_param, out_param, in_modifier, |
291 | op_modifier, op, token, event); | 291 | op_modifier, op, token, event); |
292 | 292 | ||
293 | /* | ||
294 | * Make sure that our HCR writes don't get mixed in with | ||
295 | * writes from another CPU starting a FW command. | ||
296 | */ | ||
297 | mmiowb(); | ||
298 | |||
293 | mutex_unlock(&dev->cmd.hcr_mutex); | 299 | mutex_unlock(&dev->cmd.hcr_mutex); |
294 | return err; | 300 | return err; |
295 | } | 301 | } |
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index 9bae3cc60603..15aa32eb78b6 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h | |||
@@ -83,7 +83,7 @@ enum { | |||
83 | MTHCA_QP_CONTEXT_SIZE = 0x200, | 83 | MTHCA_QP_CONTEXT_SIZE = 0x200, |
84 | MTHCA_RDB_ENTRY_SIZE = 0x20, | 84 | MTHCA_RDB_ENTRY_SIZE = 0x20, |
85 | MTHCA_AV_SIZE = 0x20, | 85 | MTHCA_AV_SIZE = 0x20, |
86 | MTHCA_MGM_ENTRY_SIZE = 0x40, | 86 | MTHCA_MGM_ENTRY_SIZE = 0x100, |
87 | 87 | ||
88 | /* Arbel FW gives us these, but we need them for Tavor */ | 88 | /* Arbel FW gives us these, but we need them for Tavor */ |
89 | MTHCA_MPT_ENTRY_SIZE = 0x40, | 89 | MTHCA_MPT_ENTRY_SIZE = 0x40, |
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 76fed7545c53..60de6f93869e 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c | |||
@@ -61,7 +61,7 @@ MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0"); | |||
61 | 61 | ||
62 | #ifdef CONFIG_PCI_MSI | 62 | #ifdef CONFIG_PCI_MSI |
63 | 63 | ||
64 | static int msi_x = 0; | 64 | static int msi_x = 1; |
65 | module_param(msi_x, int, 0444); | 65 | module_param(msi_x, int, 0444); |
66 | MODULE_PARM_DESC(msi_x, "attempt to use MSI-X if nonzero"); | 66 | MODULE_PARM_DESC(msi_x, "attempt to use MSI-X if nonzero"); |
67 | 67 | ||
@@ -137,40 +137,23 @@ static const char mthca_version[] __devinitdata = | |||
137 | 137 | ||
138 | static int mthca_tune_pci(struct mthca_dev *mdev) | 138 | static int mthca_tune_pci(struct mthca_dev *mdev) |
139 | { | 139 | { |
140 | int cap; | ||
141 | u16 val; | ||
142 | |||
143 | if (!tune_pci) | 140 | if (!tune_pci) |
144 | return 0; | 141 | return 0; |
145 | 142 | ||
146 | /* First try to max out Read Byte Count */ | 143 | /* First try to max out Read Byte Count */ |
147 | cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_PCIX); | 144 | if (pci_find_capability(mdev->pdev, PCI_CAP_ID_PCIX)) { |
148 | if (cap) { | 145 | if (pcix_set_mmrbc(mdev->pdev, pcix_get_max_mmrbc(mdev->pdev))) { |
149 | if (pci_read_config_word(mdev->pdev, cap + PCI_X_CMD, &val)) { | 146 | mthca_err(mdev, "Couldn't set PCI-X max read count, " |
150 | mthca_err(mdev, "Couldn't read PCI-X command register, " | 147 | "aborting.\n"); |
151 | "aborting.\n"); | ||
152 | return -ENODEV; | ||
153 | } | ||
154 | val = (val & ~PCI_X_CMD_MAX_READ) | (3 << 2); | ||
155 | if (pci_write_config_word(mdev->pdev, cap + PCI_X_CMD, val)) { | ||
156 | mthca_err(mdev, "Couldn't write PCI-X command register, " | ||
157 | "aborting.\n"); | ||
158 | return -ENODEV; | 148 | return -ENODEV; |
159 | } | 149 | } |
160 | } else if (!(mdev->mthca_flags & MTHCA_FLAG_PCIE)) | 150 | } else if (!(mdev->mthca_flags & MTHCA_FLAG_PCIE)) |
161 | mthca_info(mdev, "No PCI-X capability, not setting RBC.\n"); | 151 | mthca_info(mdev, "No PCI-X capability, not setting RBC.\n"); |
162 | 152 | ||
163 | cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_EXP); | 153 | if (pci_find_capability(mdev->pdev, PCI_CAP_ID_EXP)) { |
164 | if (cap) { | 154 | if (pcie_set_readrq(mdev->pdev, 4096)) { |
165 | if (pci_read_config_word(mdev->pdev, cap + PCI_EXP_DEVCTL, &val)) { | 155 | mthca_err(mdev, "Couldn't write PCI Express read request, " |
166 | mthca_err(mdev, "Couldn't read PCI Express device control " | 156 | "aborting.\n"); |
167 | "register, aborting.\n"); | ||
168 | return -ENODEV; | ||
169 | } | ||
170 | val = (val & ~PCI_EXP_DEVCTL_READRQ) | (5 << 12); | ||
171 | if (pci_write_config_word(mdev->pdev, cap + PCI_EXP_DEVCTL, val)) { | ||
172 | mthca_err(mdev, "Couldn't write PCI Express device control " | ||
173 | "register, aborting.\n"); | ||
174 | return -ENODEV; | 157 | return -ENODEV; |
175 | } | 158 | } |
176 | } else if (mdev->mthca_flags & MTHCA_FLAG_PCIE) | 159 | } else if (mdev->mthca_flags & MTHCA_FLAG_PCIE) |
@@ -833,14 +816,19 @@ static int mthca_setup_hca(struct mthca_dev *dev) | |||
833 | 816 | ||
834 | err = mthca_NOP(dev, &status); | 817 | err = mthca_NOP(dev, &status); |
835 | if (err || status) { | 818 | if (err || status) { |
836 | mthca_err(dev, "NOP command failed to generate interrupt (IRQ %d), aborting.\n", | 819 | if (dev->mthca_flags & (MTHCA_FLAG_MSI | MTHCA_FLAG_MSI_X)) { |
837 | dev->mthca_flags & MTHCA_FLAG_MSI_X ? | 820 | mthca_warn(dev, "NOP command failed to generate interrupt " |
838 | dev->eq_table.eq[MTHCA_EQ_CMD].msi_x_vector : | 821 | "(IRQ %d).\n", |
839 | dev->pdev->irq); | 822 | dev->mthca_flags & MTHCA_FLAG_MSI_X ? |
840 | if (dev->mthca_flags & (MTHCA_FLAG_MSI | MTHCA_FLAG_MSI_X)) | 823 | dev->eq_table.eq[MTHCA_EQ_CMD].msi_x_vector : |
841 | mthca_err(dev, "Try again with MSI/MSI-X disabled.\n"); | 824 | dev->pdev->irq); |
842 | else | 825 | mthca_warn(dev, "Trying again with MSI/MSI-X disabled.\n"); |
826 | } else { | ||
827 | mthca_err(dev, "NOP command failed to generate interrupt " | ||
828 | "(IRQ %d), aborting.\n", | ||
829 | dev->pdev->irq); | ||
843 | mthca_err(dev, "BIOS or ACPI interrupt routing problem?\n"); | 830 | mthca_err(dev, "BIOS or ACPI interrupt routing problem?\n"); |
831 | } | ||
844 | 832 | ||
845 | goto err_cmd_poll; | 833 | goto err_cmd_poll; |
846 | } | 834 | } |
@@ -1115,24 +1103,6 @@ static int __mthca_init_one(struct pci_dev *pdev, int hca_type) | |||
1115 | goto err_free_dev; | 1103 | goto err_free_dev; |
1116 | } | 1104 | } |
1117 | 1105 | ||
1118 | if (msi_x && !mthca_enable_msi_x(mdev)) | ||
1119 | mdev->mthca_flags |= MTHCA_FLAG_MSI_X; | ||
1120 | else if (msi) { | ||
1121 | static int warned; | ||
1122 | |||
1123 | if (!warned) { | ||
1124 | printk(KERN_WARNING PFX "WARNING: MSI support will be " | ||
1125 | "removed from the ib_mthca driver in January 2008.\n"); | ||
1126 | printk(KERN_WARNING " If you are using MSI and cannot " | ||
1127 | "switch to MSI-X, please tell " | ||
1128 | "<general@lists.openfabrics.org>.\n"); | ||
1129 | ++warned; | ||
1130 | } | ||
1131 | |||
1132 | if (!pci_enable_msi(pdev)) | ||
1133 | mdev->mthca_flags |= MTHCA_FLAG_MSI; | ||
1134 | } | ||
1135 | |||
1136 | if (mthca_cmd_init(mdev)) { | 1106 | if (mthca_cmd_init(mdev)) { |
1137 | mthca_err(mdev, "Failed to init command interface, aborting.\n"); | 1107 | mthca_err(mdev, "Failed to init command interface, aborting.\n"); |
1138 | goto err_free_dev; | 1108 | goto err_free_dev; |
@@ -1156,7 +1126,35 @@ static int __mthca_init_one(struct pci_dev *pdev, int hca_type) | |||
1156 | mthca_warn(mdev, "If you have problems, try updating your HCA FW.\n"); | 1126 | mthca_warn(mdev, "If you have problems, try updating your HCA FW.\n"); |
1157 | } | 1127 | } |
1158 | 1128 | ||
1129 | if (msi_x && !mthca_enable_msi_x(mdev)) | ||
1130 | mdev->mthca_flags |= MTHCA_FLAG_MSI_X; | ||
1131 | else if (msi) { | ||
1132 | static int warned; | ||
1133 | |||
1134 | if (!warned) { | ||
1135 | printk(KERN_WARNING PFX "WARNING: MSI support will be " | ||
1136 | "removed from the ib_mthca driver in January 2008.\n"); | ||
1137 | printk(KERN_WARNING " If you are using MSI and cannot " | ||
1138 | "switch to MSI-X, please tell " | ||
1139 | "<general@lists.openfabrics.org>.\n"); | ||
1140 | ++warned; | ||
1141 | } | ||
1142 | |||
1143 | if (!pci_enable_msi(pdev)) | ||
1144 | mdev->mthca_flags |= MTHCA_FLAG_MSI; | ||
1145 | } | ||
1146 | |||
1159 | err = mthca_setup_hca(mdev); | 1147 | err = mthca_setup_hca(mdev); |
1148 | if (err == -EBUSY && (mdev->mthca_flags & (MTHCA_FLAG_MSI | MTHCA_FLAG_MSI_X))) { | ||
1149 | if (mdev->mthca_flags & MTHCA_FLAG_MSI_X) | ||
1150 | pci_disable_msix(pdev); | ||
1151 | if (mdev->mthca_flags & MTHCA_FLAG_MSI) | ||
1152 | pci_disable_msi(pdev); | ||
1153 | mdev->mthca_flags &= ~(MTHCA_FLAG_MSI_X | MTHCA_FLAG_MSI); | ||
1154 | |||
1155 | err = mthca_setup_hca(mdev); | ||
1156 | } | ||
1157 | |||
1160 | if (err) | 1158 | if (err) |
1161 | goto err_close; | 1159 | goto err_close; |
1162 | 1160 | ||
@@ -1192,17 +1190,17 @@ err_cleanup: | |||
1192 | mthca_cleanup_uar_table(mdev); | 1190 | mthca_cleanup_uar_table(mdev); |
1193 | 1191 | ||
1194 | err_close: | 1192 | err_close: |
1193 | if (mdev->mthca_flags & MTHCA_FLAG_MSI_X) | ||
1194 | pci_disable_msix(pdev); | ||
1195 | if (mdev->mthca_flags & MTHCA_FLAG_MSI) | ||
1196 | pci_disable_msi(pdev); | ||
1197 | |||
1195 | mthca_close_hca(mdev); | 1198 | mthca_close_hca(mdev); |
1196 | 1199 | ||
1197 | err_cmd: | 1200 | err_cmd: |
1198 | mthca_cmd_cleanup(mdev); | 1201 | mthca_cmd_cleanup(mdev); |
1199 | 1202 | ||
1200 | err_free_dev: | 1203 | err_free_dev: |
1201 | if (mdev->mthca_flags & MTHCA_FLAG_MSI_X) | ||
1202 | pci_disable_msix(pdev); | ||
1203 | if (mdev->mthca_flags & MTHCA_FLAG_MSI) | ||
1204 | pci_disable_msi(pdev); | ||
1205 | |||
1206 | ib_dealloc_device(&mdev->ib_dev); | 1204 | ib_dealloc_device(&mdev->ib_dev); |
1207 | 1205 | ||
1208 | err_free_res: | 1206 | err_free_res: |
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c index 88d219e730ad..3f58c11a62b7 100644 --- a/drivers/infiniband/hw/mthca/mthca_srq.c +++ b/drivers/infiniband/hw/mthca/mthca_srq.c | |||
@@ -509,7 +509,7 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr, | |||
509 | for (nreq = 0; wr; wr = wr->next) { | 509 | for (nreq = 0; wr; wr = wr->next) { |
510 | ind = srq->first_free; | 510 | ind = srq->first_free; |
511 | 511 | ||
512 | if (ind < 0) { | 512 | if (unlikely(ind < 0)) { |
513 | mthca_err(dev, "SRQ %06x full\n", srq->srqn); | 513 | mthca_err(dev, "SRQ %06x full\n", srq->srqn); |
514 | err = -ENOMEM; | 514 | err = -ENOMEM; |
515 | *bad_wr = wr; | 515 | *bad_wr = wr; |
@@ -519,7 +519,7 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr, | |||
519 | wqe = get_wqe(srq, ind); | 519 | wqe = get_wqe(srq, ind); |
520 | next_ind = *wqe_to_link(wqe); | 520 | next_ind = *wqe_to_link(wqe); |
521 | 521 | ||
522 | if (next_ind < 0) { | 522 | if (unlikely(next_ind < 0)) { |
523 | mthca_err(dev, "SRQ %06x full\n", srq->srqn); | 523 | mthca_err(dev, "SRQ %06x full\n", srq->srqn); |
524 | err = -ENOMEM; | 524 | err = -ENOMEM; |
525 | *bad_wr = wr; | 525 | *bad_wr = wr; |
@@ -623,7 +623,7 @@ int mthca_arbel_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr, | |||
623 | for (nreq = 0; wr; ++nreq, wr = wr->next) { | 623 | for (nreq = 0; wr; ++nreq, wr = wr->next) { |
624 | ind = srq->first_free; | 624 | ind = srq->first_free; |
625 | 625 | ||
626 | if (ind < 0) { | 626 | if (unlikely(ind < 0)) { |
627 | mthca_err(dev, "SRQ %06x full\n", srq->srqn); | 627 | mthca_err(dev, "SRQ %06x full\n", srq->srqn); |
628 | err = -ENOMEM; | 628 | err = -ENOMEM; |
629 | *bad_wr = wr; | 629 | *bad_wr = wr; |
@@ -633,7 +633,7 @@ int mthca_arbel_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr, | |||
633 | wqe = get_wqe(srq, ind); | 633 | wqe = get_wqe(srq, ind); |
634 | next_ind = *wqe_to_link(wqe); | 634 | next_ind = *wqe_to_link(wqe); |
635 | 635 | ||
636 | if (next_ind < 0) { | 636 | if (unlikely(next_ind < 0)) { |
637 | mthca_err(dev, "SRQ %06x full\n", srq->srqn); | 637 | mthca_err(dev, "SRQ %06x full\n", srq->srqn); |
638 | err = -ENOMEM; | 638 | err = -ENOMEM; |
639 | *bad_wr = wr; | 639 | *bad_wr = wr; |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 285c143115cc..6545fa798b12 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -86,6 +86,7 @@ enum { | |||
86 | IPOIB_MCAST_STARTED = 8, | 86 | IPOIB_MCAST_STARTED = 8, |
87 | IPOIB_FLAG_NETIF_STOPPED = 9, | 87 | IPOIB_FLAG_NETIF_STOPPED = 9, |
88 | IPOIB_FLAG_ADMIN_CM = 10, | 88 | IPOIB_FLAG_ADMIN_CM = 10, |
89 | IPOIB_FLAG_UMCAST = 11, | ||
89 | 90 | ||
90 | IPOIB_MAX_BACKOFF_SECONDS = 16, | 91 | IPOIB_MAX_BACKOFF_SECONDS = 16, |
91 | 92 | ||
@@ -113,7 +114,27 @@ struct ipoib_pseudoheader { | |||
113 | u8 hwaddr[INFINIBAND_ALEN]; | 114 | u8 hwaddr[INFINIBAND_ALEN]; |
114 | }; | 115 | }; |
115 | 116 | ||
116 | struct ipoib_mcast; | 117 | /* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */ |
118 | struct ipoib_mcast { | ||
119 | struct ib_sa_mcmember_rec mcmember; | ||
120 | struct ib_sa_multicast *mc; | ||
121 | struct ipoib_ah *ah; | ||
122 | |||
123 | struct rb_node rb_node; | ||
124 | struct list_head list; | ||
125 | |||
126 | unsigned long created; | ||
127 | unsigned long backoff; | ||
128 | |||
129 | unsigned long flags; | ||
130 | unsigned char logcount; | ||
131 | |||
132 | struct list_head neigh_list; | ||
133 | |||
134 | struct sk_buff_head pkt_queue; | ||
135 | |||
136 | struct net_device *dev; | ||
137 | }; | ||
117 | 138 | ||
118 | struct ipoib_rx_buf { | 139 | struct ipoib_rx_buf { |
119 | struct sk_buff *skb; | 140 | struct sk_buff *skb; |
@@ -228,6 +249,8 @@ struct ipoib_dev_priv { | |||
228 | 249 | ||
229 | struct net_device *dev; | 250 | struct net_device *dev; |
230 | 251 | ||
252 | struct napi_struct napi; | ||
253 | |||
231 | unsigned long flags; | 254 | unsigned long flags; |
232 | 255 | ||
233 | struct mutex mcast_mutex; | 256 | struct mutex mcast_mutex; |
@@ -278,8 +301,6 @@ struct ipoib_dev_priv { | |||
278 | 301 | ||
279 | struct ib_event_handler event_handler; | 302 | struct ib_event_handler event_handler; |
280 | 303 | ||
281 | struct net_device_stats stats; | ||
282 | |||
283 | struct net_device *parent; | 304 | struct net_device *parent; |
284 | struct list_head child_intfs; | 305 | struct list_head child_intfs; |
285 | struct list_head list; | 306 | struct list_head list; |
@@ -351,7 +372,7 @@ extern struct workqueue_struct *ipoib_workqueue; | |||
351 | 372 | ||
352 | /* functions */ | 373 | /* functions */ |
353 | 374 | ||
354 | int ipoib_poll(struct net_device *dev, int *budget); | 375 | int ipoib_poll(struct napi_struct *napi, int budget); |
355 | void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr); | 376 | void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr); |
356 | 377 | ||
357 | struct ipoib_ah *ipoib_create_ah(struct net_device *dev, | 378 | struct ipoib_ah *ipoib_create_ah(struct net_device *dev, |
@@ -364,6 +385,7 @@ static inline void ipoib_put_ah(struct ipoib_ah *ah) | |||
364 | 385 | ||
365 | int ipoib_open(struct net_device *dev); | 386 | int ipoib_open(struct net_device *dev); |
366 | int ipoib_add_pkey_attr(struct net_device *dev); | 387 | int ipoib_add_pkey_attr(struct net_device *dev); |
388 | int ipoib_add_umcast_attr(struct net_device *dev); | ||
367 | 389 | ||
368 | void ipoib_send(struct net_device *dev, struct sk_buff *skb, | 390 | void ipoib_send(struct net_device *dev, struct sk_buff *skb, |
369 | struct ipoib_ah *address, u32 qpn); | 391 | struct ipoib_ah *address, u32 qpn); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 08b4676a3820..0a0dcb8fdfd1 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |||
@@ -430,7 +430,7 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) | |||
430 | ipoib_dbg(priv, "cm recv error " | 430 | ipoib_dbg(priv, "cm recv error " |
431 | "(status=%d, wrid=%d vend_err %x)\n", | 431 | "(status=%d, wrid=%d vend_err %x)\n", |
432 | wc->status, wr_id, wc->vendor_err); | 432 | wc->status, wr_id, wc->vendor_err); |
433 | ++priv->stats.rx_dropped; | 433 | ++dev->stats.rx_dropped; |
434 | goto repost; | 434 | goto repost; |
435 | } | 435 | } |
436 | 436 | ||
@@ -457,7 +457,7 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) | |||
457 | * this packet and reuse the old buffer. | 457 | * this packet and reuse the old buffer. |
458 | */ | 458 | */ |
459 | ipoib_dbg(priv, "failed to allocate receive buffer %d\n", wr_id); | 459 | ipoib_dbg(priv, "failed to allocate receive buffer %d\n", wr_id); |
460 | ++priv->stats.rx_dropped; | 460 | ++dev->stats.rx_dropped; |
461 | goto repost; | 461 | goto repost; |
462 | } | 462 | } |
463 | 463 | ||
@@ -474,8 +474,8 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) | |||
474 | skb_pull(skb, IPOIB_ENCAP_LEN); | 474 | skb_pull(skb, IPOIB_ENCAP_LEN); |
475 | 475 | ||
476 | dev->last_rx = jiffies; | 476 | dev->last_rx = jiffies; |
477 | ++priv->stats.rx_packets; | 477 | ++dev->stats.rx_packets; |
478 | priv->stats.rx_bytes += skb->len; | 478 | dev->stats.rx_bytes += skb->len; |
479 | 479 | ||
480 | skb->dev = dev; | 480 | skb->dev = dev; |
481 | /* XXX get correct PACKET_ type here */ | 481 | /* XXX get correct PACKET_ type here */ |
@@ -512,8 +512,8 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ | |||
512 | if (unlikely(skb->len > tx->mtu)) { | 512 | if (unlikely(skb->len > tx->mtu)) { |
513 | ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n", | 513 | ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n", |
514 | skb->len, tx->mtu); | 514 | skb->len, tx->mtu); |
515 | ++priv->stats.tx_dropped; | 515 | ++dev->stats.tx_dropped; |
516 | ++priv->stats.tx_errors; | 516 | ++dev->stats.tx_errors; |
517 | ipoib_cm_skb_too_long(dev, skb, tx->mtu - IPOIB_ENCAP_LEN); | 517 | ipoib_cm_skb_too_long(dev, skb, tx->mtu - IPOIB_ENCAP_LEN); |
518 | return; | 518 | return; |
519 | } | 519 | } |
@@ -532,7 +532,7 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ | |||
532 | tx_req->skb = skb; | 532 | tx_req->skb = skb; |
533 | addr = ib_dma_map_single(priv->ca, skb->data, skb->len, DMA_TO_DEVICE); | 533 | addr = ib_dma_map_single(priv->ca, skb->data, skb->len, DMA_TO_DEVICE); |
534 | if (unlikely(ib_dma_mapping_error(priv->ca, addr))) { | 534 | if (unlikely(ib_dma_mapping_error(priv->ca, addr))) { |
535 | ++priv->stats.tx_errors; | 535 | ++dev->stats.tx_errors; |
536 | dev_kfree_skb_any(skb); | 536 | dev_kfree_skb_any(skb); |
537 | return; | 537 | return; |
538 | } | 538 | } |
@@ -542,7 +542,7 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ | |||
542 | if (unlikely(post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1), | 542 | if (unlikely(post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1), |
543 | addr, skb->len))) { | 543 | addr, skb->len))) { |
544 | ipoib_warn(priv, "post_send failed\n"); | 544 | ipoib_warn(priv, "post_send failed\n"); |
545 | ++priv->stats.tx_errors; | 545 | ++dev->stats.tx_errors; |
546 | ib_dma_unmap_single(priv->ca, addr, skb->len, DMA_TO_DEVICE); | 546 | ib_dma_unmap_single(priv->ca, addr, skb->len, DMA_TO_DEVICE); |
547 | dev_kfree_skb_any(skb); | 547 | dev_kfree_skb_any(skb); |
548 | } else { | 548 | } else { |
@@ -580,8 +580,8 @@ static void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ipoib_cm_tx *tx | |||
580 | ib_dma_unmap_single(priv->ca, tx_req->mapping, tx_req->skb->len, DMA_TO_DEVICE); | 580 | ib_dma_unmap_single(priv->ca, tx_req->mapping, tx_req->skb->len, DMA_TO_DEVICE); |
581 | 581 | ||
582 | /* FIXME: is this right? Shouldn't we only increment on success? */ | 582 | /* FIXME: is this right? Shouldn't we only increment on success? */ |
583 | ++priv->stats.tx_packets; | 583 | ++dev->stats.tx_packets; |
584 | priv->stats.tx_bytes += tx_req->skb->len; | 584 | dev->stats.tx_bytes += tx_req->skb->len; |
585 | 585 | ||
586 | dev_kfree_skb_any(tx_req->skb); | 586 | dev_kfree_skb_any(tx_req->skb); |
587 | 587 | ||
@@ -810,14 +810,16 @@ static int ipoib_cm_rep_handler(struct ib_cm_id *cm_id, struct ib_cm_event *even | |||
810 | static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ib_cq *cq) | 810 | static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ib_cq *cq) |
811 | { | 811 | { |
812 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 812 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
813 | struct ib_qp_init_attr attr = {}; | 813 | struct ib_qp_init_attr attr = { |
814 | attr.recv_cq = priv->cq; | 814 | .send_cq = cq, |
815 | attr.srq = priv->cm.srq; | 815 | .recv_cq = priv->cq, |
816 | attr.cap.max_send_wr = ipoib_sendq_size; | 816 | .srq = priv->cm.srq, |
817 | attr.cap.max_send_sge = 1; | 817 | .cap.max_send_wr = ipoib_sendq_size, |
818 | attr.sq_sig_type = IB_SIGNAL_ALL_WR; | 818 | .cap.max_send_sge = 1, |
819 | attr.qp_type = IB_QPT_RC; | 819 | .sq_sig_type = IB_SIGNAL_ALL_WR, |
820 | attr.send_cq = cq; | 820 | .qp_type = IB_QPT_RC, |
821 | }; | ||
822 | |||
821 | return ib_create_qp(priv->pd, &attr); | 823 | return ib_create_qp(priv->pd, &attr); |
822 | } | 824 | } |
823 | 825 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 10944888cffd..1a77e79f6b43 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
@@ -208,7 +208,7 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) | |||
208 | * this packet and reuse the old buffer. | 208 | * this packet and reuse the old buffer. |
209 | */ | 209 | */ |
210 | if (unlikely(ipoib_alloc_rx_skb(dev, wr_id))) { | 210 | if (unlikely(ipoib_alloc_rx_skb(dev, wr_id))) { |
211 | ++priv->stats.rx_dropped; | 211 | ++dev->stats.rx_dropped; |
212 | goto repost; | 212 | goto repost; |
213 | } | 213 | } |
214 | 214 | ||
@@ -225,8 +225,8 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) | |||
225 | skb_pull(skb, IPOIB_ENCAP_LEN); | 225 | skb_pull(skb, IPOIB_ENCAP_LEN); |
226 | 226 | ||
227 | dev->last_rx = jiffies; | 227 | dev->last_rx = jiffies; |
228 | ++priv->stats.rx_packets; | 228 | ++dev->stats.rx_packets; |
229 | priv->stats.rx_bytes += skb->len; | 229 | dev->stats.rx_bytes += skb->len; |
230 | 230 | ||
231 | skb->dev = dev; | 231 | skb->dev = dev; |
232 | /* XXX get correct PACKET_ type here */ | 232 | /* XXX get correct PACKET_ type here */ |
@@ -260,8 +260,8 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) | |||
260 | ib_dma_unmap_single(priv->ca, tx_req->mapping, | 260 | ib_dma_unmap_single(priv->ca, tx_req->mapping, |
261 | tx_req->skb->len, DMA_TO_DEVICE); | 261 | tx_req->skb->len, DMA_TO_DEVICE); |
262 | 262 | ||
263 | ++priv->stats.tx_packets; | 263 | ++dev->stats.tx_packets; |
264 | priv->stats.tx_bytes += tx_req->skb->len; | 264 | dev->stats.tx_bytes += tx_req->skb->len; |
265 | 265 | ||
266 | dev_kfree_skb_any(tx_req->skb); | 266 | dev_kfree_skb_any(tx_req->skb); |
267 | 267 | ||
@@ -281,63 +281,58 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) | |||
281 | wc->status, wr_id, wc->vendor_err); | 281 | wc->status, wr_id, wc->vendor_err); |
282 | } | 282 | } |
283 | 283 | ||
284 | int ipoib_poll(struct net_device *dev, int *budget) | 284 | int ipoib_poll(struct napi_struct *napi, int budget) |
285 | { | 285 | { |
286 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 286 | struct ipoib_dev_priv *priv = container_of(napi, struct ipoib_dev_priv, napi); |
287 | int max = min(*budget, dev->quota); | 287 | struct net_device *dev = priv->dev; |
288 | int done; | 288 | int done; |
289 | int t; | 289 | int t; |
290 | int empty; | ||
291 | int n, i; | 290 | int n, i; |
292 | 291 | ||
293 | done = 0; | 292 | done = 0; |
294 | empty = 0; | ||
295 | 293 | ||
296 | while (max) { | 294 | poll_more: |
295 | while (done < budget) { | ||
296 | int max = (budget - done); | ||
297 | |||
297 | t = min(IPOIB_NUM_WC, max); | 298 | t = min(IPOIB_NUM_WC, max); |
298 | n = ib_poll_cq(priv->cq, t, priv->ibwc); | 299 | n = ib_poll_cq(priv->cq, t, priv->ibwc); |
299 | 300 | ||
300 | for (i = 0; i < n; ++i) { | 301 | for (i = 0; i < n; i++) { |
301 | struct ib_wc *wc = priv->ibwc + i; | 302 | struct ib_wc *wc = priv->ibwc + i; |
302 | 303 | ||
303 | if (wc->wr_id & IPOIB_CM_OP_SRQ) { | 304 | if (wc->wr_id & IPOIB_CM_OP_SRQ) { |
304 | ++done; | 305 | ++done; |
305 | --max; | ||
306 | ipoib_cm_handle_rx_wc(dev, wc); | 306 | ipoib_cm_handle_rx_wc(dev, wc); |
307 | } else if (wc->wr_id & IPOIB_OP_RECV) { | 307 | } else if (wc->wr_id & IPOIB_OP_RECV) { |
308 | ++done; | 308 | ++done; |
309 | --max; | ||
310 | ipoib_ib_handle_rx_wc(dev, wc); | 309 | ipoib_ib_handle_rx_wc(dev, wc); |
311 | } else | 310 | } else |
312 | ipoib_ib_handle_tx_wc(dev, wc); | 311 | ipoib_ib_handle_tx_wc(dev, wc); |
313 | } | 312 | } |
314 | 313 | ||
315 | if (n != t) { | 314 | if (n != t) |
316 | empty = 1; | ||
317 | break; | 315 | break; |
318 | } | ||
319 | } | 316 | } |
320 | 317 | ||
321 | dev->quota -= done; | 318 | if (done < budget) { |
322 | *budget -= done; | 319 | netif_rx_complete(dev, napi); |
323 | |||
324 | if (empty) { | ||
325 | netif_rx_complete(dev); | ||
326 | if (unlikely(ib_req_notify_cq(priv->cq, | 320 | if (unlikely(ib_req_notify_cq(priv->cq, |
327 | IB_CQ_NEXT_COMP | | 321 | IB_CQ_NEXT_COMP | |
328 | IB_CQ_REPORT_MISSED_EVENTS)) && | 322 | IB_CQ_REPORT_MISSED_EVENTS)) && |
329 | netif_rx_reschedule(dev, 0)) | 323 | netif_rx_reschedule(dev, napi)) |
330 | return 1; | 324 | goto poll_more; |
331 | |||
332 | return 0; | ||
333 | } | 325 | } |
334 | 326 | ||
335 | return 1; | 327 | return done; |
336 | } | 328 | } |
337 | 329 | ||
338 | void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr) | 330 | void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr) |
339 | { | 331 | { |
340 | netif_rx_schedule(dev_ptr); | 332 | struct net_device *dev = dev_ptr; |
333 | struct ipoib_dev_priv *priv = netdev_priv(dev); | ||
334 | |||
335 | netif_rx_schedule(dev, &priv->napi); | ||
341 | } | 336 | } |
342 | 337 | ||
343 | static inline int post_send(struct ipoib_dev_priv *priv, | 338 | static inline int post_send(struct ipoib_dev_priv *priv, |
@@ -367,8 +362,8 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
367 | if (unlikely(skb->len > priv->mcast_mtu + IPOIB_ENCAP_LEN)) { | 362 | if (unlikely(skb->len > priv->mcast_mtu + IPOIB_ENCAP_LEN)) { |
368 | ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n", | 363 | ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n", |
369 | skb->len, priv->mcast_mtu + IPOIB_ENCAP_LEN); | 364 | skb->len, priv->mcast_mtu + IPOIB_ENCAP_LEN); |
370 | ++priv->stats.tx_dropped; | 365 | ++dev->stats.tx_dropped; |
371 | ++priv->stats.tx_errors; | 366 | ++dev->stats.tx_errors; |
372 | ipoib_cm_skb_too_long(dev, skb, priv->mcast_mtu); | 367 | ipoib_cm_skb_too_long(dev, skb, priv->mcast_mtu); |
373 | return; | 368 | return; |
374 | } | 369 | } |
@@ -388,7 +383,7 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
388 | addr = ib_dma_map_single(priv->ca, skb->data, skb->len, | 383 | addr = ib_dma_map_single(priv->ca, skb->data, skb->len, |
389 | DMA_TO_DEVICE); | 384 | DMA_TO_DEVICE); |
390 | if (unlikely(ib_dma_mapping_error(priv->ca, addr))) { | 385 | if (unlikely(ib_dma_mapping_error(priv->ca, addr))) { |
391 | ++priv->stats.tx_errors; | 386 | ++dev->stats.tx_errors; |
392 | dev_kfree_skb_any(skb); | 387 | dev_kfree_skb_any(skb); |
393 | return; | 388 | return; |
394 | } | 389 | } |
@@ -397,7 +392,7 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
397 | if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1), | 392 | if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1), |
398 | address->ah, qpn, addr, skb->len))) { | 393 | address->ah, qpn, addr, skb->len))) { |
399 | ipoib_warn(priv, "post_send failed\n"); | 394 | ipoib_warn(priv, "post_send failed\n"); |
400 | ++priv->stats.tx_errors; | 395 | ++dev->stats.tx_errors; |
401 | ib_dma_unmap_single(priv->ca, addr, skb->len, DMA_TO_DEVICE); | 396 | ib_dma_unmap_single(priv->ca, addr, skb->len, DMA_TO_DEVICE); |
402 | dev_kfree_skb_any(skb); | 397 | dev_kfree_skb_any(skb); |
403 | } else { | 398 | } else { |
@@ -558,6 +553,14 @@ void ipoib_drain_cq(struct net_device *dev) | |||
558 | do { | 553 | do { |
559 | n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc); | 554 | n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc); |
560 | for (i = 0; i < n; ++i) { | 555 | for (i = 0; i < n; ++i) { |
556 | /* | ||
557 | * Convert any successful completions to flush | ||
558 | * errors to avoid passing packets up the | ||
559 | * stack after bringing the device down. | ||
560 | */ | ||
561 | if (priv->ibwc[i].status == IB_WC_SUCCESS) | ||
562 | priv->ibwc[i].status = IB_WC_WR_FLUSH_ERR; | ||
563 | |||
561 | if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ) | 564 | if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ) |
562 | ipoib_cm_handle_rx_wc(dev, priv->ibwc + i); | 565 | ipoib_cm_handle_rx_wc(dev, priv->ibwc + i); |
563 | else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV) | 566 | else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV) |
@@ -577,7 +580,6 @@ int ipoib_ib_dev_stop(struct net_device *dev, int flush) | |||
577 | int i; | 580 | int i; |
578 | 581 | ||
579 | clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags); | 582 | clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags); |
580 | netif_poll_disable(dev); | ||
581 | 583 | ||
582 | ipoib_cm_dev_stop(dev); | 584 | ipoib_cm_dev_stop(dev); |
583 | 585 | ||
@@ -660,7 +662,6 @@ timeout: | |||
660 | msleep(1); | 662 | msleep(1); |
661 | } | 663 | } |
662 | 664 | ||
663 | netif_poll_enable(dev); | ||
664 | ib_req_notify_cq(priv->cq, IB_CQ_NEXT_COMP); | 665 | ib_req_notify_cq(priv->cq, IB_CQ_NEXT_COMP); |
665 | 666 | ||
666 | return 0; | 667 | return 0; |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 894b1dcdf3eb..e072f3c32ce6 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -98,16 +98,20 @@ int ipoib_open(struct net_device *dev) | |||
98 | 98 | ||
99 | ipoib_dbg(priv, "bringing up interface\n"); | 99 | ipoib_dbg(priv, "bringing up interface\n"); |
100 | 100 | ||
101 | napi_enable(&priv->napi); | ||
101 | set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); | 102 | set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); |
102 | 103 | ||
103 | if (ipoib_pkey_dev_delay_open(dev)) | 104 | if (ipoib_pkey_dev_delay_open(dev)) |
104 | return 0; | 105 | return 0; |
105 | 106 | ||
106 | if (ipoib_ib_dev_open(dev)) | 107 | if (ipoib_ib_dev_open(dev)) { |
108 | napi_disable(&priv->napi); | ||
107 | return -EINVAL; | 109 | return -EINVAL; |
110 | } | ||
108 | 111 | ||
109 | if (ipoib_ib_dev_up(dev)) { | 112 | if (ipoib_ib_dev_up(dev)) { |
110 | ipoib_ib_dev_stop(dev, 1); | 113 | ipoib_ib_dev_stop(dev, 1); |
114 | napi_disable(&priv->napi); | ||
111 | return -EINVAL; | 115 | return -EINVAL; |
112 | } | 116 | } |
113 | 117 | ||
@@ -140,6 +144,7 @@ static int ipoib_stop(struct net_device *dev) | |||
140 | ipoib_dbg(priv, "stopping interface\n"); | 144 | ipoib_dbg(priv, "stopping interface\n"); |
141 | 145 | ||
142 | clear_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); | 146 | clear_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); |
147 | napi_disable(&priv->napi); | ||
143 | 148 | ||
144 | netif_stop_queue(dev); | 149 | netif_stop_queue(dev); |
145 | 150 | ||
@@ -468,9 +473,10 @@ static struct ipoib_path *path_rec_create(struct net_device *dev, void *gid) | |||
468 | INIT_LIST_HEAD(&path->neigh_list); | 473 | INIT_LIST_HEAD(&path->neigh_list); |
469 | 474 | ||
470 | memcpy(path->pathrec.dgid.raw, gid, sizeof (union ib_gid)); | 475 | memcpy(path->pathrec.dgid.raw, gid, sizeof (union ib_gid)); |
471 | path->pathrec.sgid = priv->local_gid; | 476 | path->pathrec.sgid = priv->local_gid; |
472 | path->pathrec.pkey = cpu_to_be16(priv->pkey); | 477 | path->pathrec.pkey = cpu_to_be16(priv->pkey); |
473 | path->pathrec.numb_path = 1; | 478 | path->pathrec.numb_path = 1; |
479 | path->pathrec.traffic_class = priv->broadcast->mcmember.traffic_class; | ||
474 | 480 | ||
475 | return path; | 481 | return path; |
476 | } | 482 | } |
@@ -491,6 +497,7 @@ static int path_rec_start(struct net_device *dev, | |||
491 | IB_SA_PATH_REC_DGID | | 497 | IB_SA_PATH_REC_DGID | |
492 | IB_SA_PATH_REC_SGID | | 498 | IB_SA_PATH_REC_SGID | |
493 | IB_SA_PATH_REC_NUMB_PATH | | 499 | IB_SA_PATH_REC_NUMB_PATH | |
500 | IB_SA_PATH_REC_TRAFFIC_CLASS | | ||
494 | IB_SA_PATH_REC_PKEY, | 501 | IB_SA_PATH_REC_PKEY, |
495 | 1000, GFP_ATOMIC, | 502 | 1000, GFP_ATOMIC, |
496 | path_rec_completion, | 503 | path_rec_completion, |
@@ -512,7 +519,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) | |||
512 | 519 | ||
513 | neigh = ipoib_neigh_alloc(skb->dst->neighbour); | 520 | neigh = ipoib_neigh_alloc(skb->dst->neighbour); |
514 | if (!neigh) { | 521 | if (!neigh) { |
515 | ++priv->stats.tx_dropped; | 522 | ++dev->stats.tx_dropped; |
516 | dev_kfree_skb_any(skb); | 523 | dev_kfree_skb_any(skb); |
517 | return; | 524 | return; |
518 | } | 525 | } |
@@ -577,7 +584,7 @@ err_list: | |||
577 | err_path: | 584 | err_path: |
578 | ipoib_neigh_free(dev, neigh); | 585 | ipoib_neigh_free(dev, neigh); |
579 | err_drop: | 586 | err_drop: |
580 | ++priv->stats.tx_dropped; | 587 | ++dev->stats.tx_dropped; |
581 | dev_kfree_skb_any(skb); | 588 | dev_kfree_skb_any(skb); |
582 | 589 | ||
583 | spin_unlock(&priv->lock); | 590 | spin_unlock(&priv->lock); |
@@ -626,7 +633,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, | |||
626 | } else | 633 | } else |
627 | __path_add(dev, path); | 634 | __path_add(dev, path); |
628 | } else { | 635 | } else { |
629 | ++priv->stats.tx_dropped; | 636 | ++dev->stats.tx_dropped; |
630 | dev_kfree_skb_any(skb); | 637 | dev_kfree_skb_any(skb); |
631 | } | 638 | } |
632 | 639 | ||
@@ -645,7 +652,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, | |||
645 | skb_push(skb, sizeof *phdr); | 652 | skb_push(skb, sizeof *phdr); |
646 | __skb_queue_tail(&path->queue, skb); | 653 | __skb_queue_tail(&path->queue, skb); |
647 | } else { | 654 | } else { |
648 | ++priv->stats.tx_dropped; | 655 | ++dev->stats.tx_dropped; |
649 | dev_kfree_skb_any(skb); | 656 | dev_kfree_skb_any(skb); |
650 | } | 657 | } |
651 | 658 | ||
@@ -713,7 +720,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
713 | __skb_queue_tail(&neigh->queue, skb); | 720 | __skb_queue_tail(&neigh->queue, skb); |
714 | spin_unlock(&priv->lock); | 721 | spin_unlock(&priv->lock); |
715 | } else { | 722 | } else { |
716 | ++priv->stats.tx_dropped; | 723 | ++dev->stats.tx_dropped; |
717 | dev_kfree_skb_any(skb); | 724 | dev_kfree_skb_any(skb); |
718 | } | 725 | } |
719 | } else { | 726 | } else { |
@@ -739,7 +746,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
739 | IPOIB_QPN(phdr->hwaddr), | 746 | IPOIB_QPN(phdr->hwaddr), |
740 | IPOIB_GID_RAW_ARG(phdr->hwaddr + 4)); | 747 | IPOIB_GID_RAW_ARG(phdr->hwaddr + 4)); |
741 | dev_kfree_skb_any(skb); | 748 | dev_kfree_skb_any(skb); |
742 | ++priv->stats.tx_dropped; | 749 | ++dev->stats.tx_dropped; |
743 | goto out; | 750 | goto out; |
744 | } | 751 | } |
745 | 752 | ||
@@ -753,13 +760,6 @@ out: | |||
753 | return NETDEV_TX_OK; | 760 | return NETDEV_TX_OK; |
754 | } | 761 | } |
755 | 762 | ||
756 | static struct net_device_stats *ipoib_get_stats(struct net_device *dev) | ||
757 | { | ||
758 | struct ipoib_dev_priv *priv = netdev_priv(dev); | ||
759 | |||
760 | return &priv->stats; | ||
761 | } | ||
762 | |||
763 | static void ipoib_timeout(struct net_device *dev) | 763 | static void ipoib_timeout(struct net_device *dev) |
764 | { | 764 | { |
765 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 765 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
@@ -775,7 +775,7 @@ static void ipoib_timeout(struct net_device *dev) | |||
775 | static int ipoib_hard_header(struct sk_buff *skb, | 775 | static int ipoib_hard_header(struct sk_buff *skb, |
776 | struct net_device *dev, | 776 | struct net_device *dev, |
777 | unsigned short type, | 777 | unsigned short type, |
778 | void *daddr, void *saddr, unsigned len) | 778 | const void *daddr, const void *saddr, unsigned len) |
779 | { | 779 | { |
780 | struct ipoib_header *header; | 780 | struct ipoib_header *header; |
781 | 781 | ||
@@ -856,11 +856,10 @@ struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour) | |||
856 | 856 | ||
857 | void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh) | 857 | void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh) |
858 | { | 858 | { |
859 | struct ipoib_dev_priv *priv = netdev_priv(dev); | ||
860 | struct sk_buff *skb; | 859 | struct sk_buff *skb; |
861 | *to_ipoib_neigh(neigh->neighbour) = NULL; | 860 | *to_ipoib_neigh(neigh->neighbour) = NULL; |
862 | while ((skb = __skb_dequeue(&neigh->queue))) { | 861 | while ((skb = __skb_dequeue(&neigh->queue))) { |
863 | ++priv->stats.tx_dropped; | 862 | ++dev->stats.tx_dropped; |
864 | dev_kfree_skb_any(skb); | 863 | dev_kfree_skb_any(skb); |
865 | } | 864 | } |
866 | if (ipoib_cm_get(neigh)) | 865 | if (ipoib_cm_get(neigh)) |
@@ -935,6 +934,10 @@ void ipoib_dev_cleanup(struct net_device *dev) | |||
935 | priv->tx_ring = NULL; | 934 | priv->tx_ring = NULL; |
936 | } | 935 | } |
937 | 936 | ||
937 | static const struct header_ops ipoib_header_ops = { | ||
938 | .create = ipoib_hard_header, | ||
939 | }; | ||
940 | |||
938 | static void ipoib_setup(struct net_device *dev) | 941 | static void ipoib_setup(struct net_device *dev) |
939 | { | 942 | { |
940 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 943 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
@@ -943,13 +946,12 @@ static void ipoib_setup(struct net_device *dev) | |||
943 | dev->stop = ipoib_stop; | 946 | dev->stop = ipoib_stop; |
944 | dev->change_mtu = ipoib_change_mtu; | 947 | dev->change_mtu = ipoib_change_mtu; |
945 | dev->hard_start_xmit = ipoib_start_xmit; | 948 | dev->hard_start_xmit = ipoib_start_xmit; |
946 | dev->get_stats = ipoib_get_stats; | ||
947 | dev->tx_timeout = ipoib_timeout; | 949 | dev->tx_timeout = ipoib_timeout; |
948 | dev->hard_header = ipoib_hard_header; | 950 | dev->header_ops = &ipoib_header_ops; |
949 | dev->set_multicast_list = ipoib_set_mcast_list; | 951 | dev->set_multicast_list = ipoib_set_mcast_list; |
950 | dev->neigh_setup = ipoib_neigh_setup_dev; | 952 | dev->neigh_setup = ipoib_neigh_setup_dev; |
951 | dev->poll = ipoib_poll; | 953 | |
952 | dev->weight = 100; | 954 | netif_napi_add(dev, &priv->napi, ipoib_poll, 100); |
953 | 955 | ||
954 | dev->watchdog_timeo = HZ; | 956 | dev->watchdog_timeo = HZ; |
955 | 957 | ||
@@ -973,8 +975,6 @@ static void ipoib_setup(struct net_device *dev) | |||
973 | 975 | ||
974 | netif_carrier_off(dev); | 976 | netif_carrier_off(dev); |
975 | 977 | ||
976 | SET_MODULE_OWNER(dev); | ||
977 | |||
978 | priv->dev = dev; | 978 | priv->dev = dev; |
979 | 979 | ||
980 | spin_lock_init(&priv->lock); | 980 | spin_lock_init(&priv->lock); |
@@ -1017,6 +1017,37 @@ static ssize_t show_pkey(struct device *dev, | |||
1017 | } | 1017 | } |
1018 | static DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL); | 1018 | static DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL); |
1019 | 1019 | ||
1020 | static ssize_t show_umcast(struct device *dev, | ||
1021 | struct device_attribute *attr, char *buf) | ||
1022 | { | ||
1023 | struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(dev)); | ||
1024 | |||
1025 | return sprintf(buf, "%d\n", test_bit(IPOIB_FLAG_UMCAST, &priv->flags)); | ||
1026 | } | ||
1027 | |||
1028 | static ssize_t set_umcast(struct device *dev, | ||
1029 | struct device_attribute *attr, | ||
1030 | const char *buf, size_t count) | ||
1031 | { | ||
1032 | struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(dev)); | ||
1033 | unsigned long umcast_val = simple_strtoul(buf, NULL, 0); | ||
1034 | |||
1035 | if (umcast_val > 0) { | ||
1036 | set_bit(IPOIB_FLAG_UMCAST, &priv->flags); | ||
1037 | ipoib_warn(priv, "ignoring multicast groups joined directly " | ||
1038 | "by userspace\n"); | ||
1039 | } else | ||
1040 | clear_bit(IPOIB_FLAG_UMCAST, &priv->flags); | ||
1041 | |||
1042 | return count; | ||
1043 | } | ||
1044 | static DEVICE_ATTR(umcast, S_IWUSR | S_IRUGO, show_umcast, set_umcast); | ||
1045 | |||
1046 | int ipoib_add_umcast_attr(struct net_device *dev) | ||
1047 | { | ||
1048 | return device_create_file(&dev->dev, &dev_attr_umcast); | ||
1049 | } | ||
1050 | |||
1020 | static ssize_t create_child(struct device *dev, | 1051 | static ssize_t create_child(struct device *dev, |
1021 | struct device_attribute *attr, | 1052 | struct device_attribute *attr, |
1022 | const char *buf, size_t count) | 1053 | const char *buf, size_t count) |
@@ -1083,7 +1114,7 @@ static struct net_device *ipoib_add_port(const char *format, | |||
1083 | if (result) { | 1114 | if (result) { |
1084 | printk(KERN_WARNING "%s: ib_query_pkey port %d failed (ret = %d)\n", | 1115 | printk(KERN_WARNING "%s: ib_query_pkey port %d failed (ret = %d)\n", |
1085 | hca->name, port, result); | 1116 | hca->name, port, result); |
1086 | goto alloc_mem_failed; | 1117 | goto device_init_failed; |
1087 | } | 1118 | } |
1088 | 1119 | ||
1089 | /* | 1120 | /* |
@@ -1099,7 +1130,7 @@ static struct net_device *ipoib_add_port(const char *format, | |||
1099 | if (result) { | 1130 | if (result) { |
1100 | printk(KERN_WARNING "%s: ib_query_gid port %d failed (ret = %d)\n", | 1131 | printk(KERN_WARNING "%s: ib_query_gid port %d failed (ret = %d)\n", |
1101 | hca->name, port, result); | 1132 | hca->name, port, result); |
1102 | goto alloc_mem_failed; | 1133 | goto device_init_failed; |
1103 | } else | 1134 | } else |
1104 | memcpy(priv->dev->dev_addr + 4, priv->local_gid.raw, sizeof (union ib_gid)); | 1135 | memcpy(priv->dev->dev_addr + 4, priv->local_gid.raw, sizeof (union ib_gid)); |
1105 | 1136 | ||
@@ -1134,6 +1165,8 @@ static struct net_device *ipoib_add_port(const char *format, | |||
1134 | goto sysfs_failed; | 1165 | goto sysfs_failed; |
1135 | if (ipoib_add_pkey_attr(priv->dev)) | 1166 | if (ipoib_add_pkey_attr(priv->dev)) |
1136 | goto sysfs_failed; | 1167 | goto sysfs_failed; |
1168 | if (ipoib_add_umcast_attr(priv->dev)) | ||
1169 | goto sysfs_failed; | ||
1137 | if (device_create_file(&priv->dev->dev, &dev_attr_create_child)) | 1170 | if (device_create_file(&priv->dev->dev, &dev_attr_create_child)) |
1138 | goto sysfs_failed; | 1171 | goto sysfs_failed; |
1139 | if (device_create_file(&priv->dev->dev, &dev_attr_delete_child)) | 1172 | if (device_create_file(&priv->dev->dev, &dev_attr_delete_child)) |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index aae367057a56..827820ec66d1 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -57,28 +57,6 @@ MODULE_PARM_DESC(mcast_debug_level, | |||
57 | 57 | ||
58 | static DEFINE_MUTEX(mcast_mutex); | 58 | static DEFINE_MUTEX(mcast_mutex); |
59 | 59 | ||
60 | /* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */ | ||
61 | struct ipoib_mcast { | ||
62 | struct ib_sa_mcmember_rec mcmember; | ||
63 | struct ib_sa_multicast *mc; | ||
64 | struct ipoib_ah *ah; | ||
65 | |||
66 | struct rb_node rb_node; | ||
67 | struct list_head list; | ||
68 | |||
69 | unsigned long created; | ||
70 | unsigned long backoff; | ||
71 | |||
72 | unsigned long flags; | ||
73 | unsigned char logcount; | ||
74 | |||
75 | struct list_head neigh_list; | ||
76 | |||
77 | struct sk_buff_head pkt_queue; | ||
78 | |||
79 | struct net_device *dev; | ||
80 | }; | ||
81 | |||
82 | struct ipoib_mcast_iter { | 60 | struct ipoib_mcast_iter { |
83 | struct net_device *dev; | 61 | struct net_device *dev; |
84 | union ib_gid mgid; | 62 | union ib_gid mgid; |
@@ -125,7 +103,7 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast) | |||
125 | } | 103 | } |
126 | 104 | ||
127 | spin_lock_irqsave(&priv->tx_lock, flags); | 105 | spin_lock_irqsave(&priv->tx_lock, flags); |
128 | priv->stats.tx_dropped += tx_dropped; | 106 | dev->stats.tx_dropped += tx_dropped; |
129 | spin_unlock_irqrestore(&priv->tx_lock, flags); | 107 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
130 | 108 | ||
131 | kfree(mcast); | 109 | kfree(mcast); |
@@ -320,7 +298,7 @@ ipoib_mcast_sendonly_join_complete(int status, | |||
320 | /* Flush out any queued packets */ | 298 | /* Flush out any queued packets */ |
321 | spin_lock_irq(&priv->tx_lock); | 299 | spin_lock_irq(&priv->tx_lock); |
322 | while (!skb_queue_empty(&mcast->pkt_queue)) { | 300 | while (!skb_queue_empty(&mcast->pkt_queue)) { |
323 | ++priv->stats.tx_dropped; | 301 | ++dev->stats.tx_dropped; |
324 | dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue)); | 302 | dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue)); |
325 | } | 303 | } |
326 | spin_unlock_irq(&priv->tx_lock); | 304 | spin_unlock_irq(&priv->tx_lock); |
@@ -675,7 +653,7 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb) | |||
675 | if (!test_bit(IPOIB_MCAST_STARTED, &priv->flags) || | 653 | if (!test_bit(IPOIB_MCAST_STARTED, &priv->flags) || |
676 | !priv->broadcast || | 654 | !priv->broadcast || |
677 | !test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) { | 655 | !test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) { |
678 | ++priv->stats.tx_dropped; | 656 | ++dev->stats.tx_dropped; |
679 | dev_kfree_skb_any(skb); | 657 | dev_kfree_skb_any(skb); |
680 | goto unlock; | 658 | goto unlock; |
681 | } | 659 | } |
@@ -690,7 +668,7 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb) | |||
690 | if (!mcast) { | 668 | if (!mcast) { |
691 | ipoib_warn(priv, "unable to allocate memory for " | 669 | ipoib_warn(priv, "unable to allocate memory for " |
692 | "multicast structure\n"); | 670 | "multicast structure\n"); |
693 | ++priv->stats.tx_dropped; | 671 | ++dev->stats.tx_dropped; |
694 | dev_kfree_skb_any(skb); | 672 | dev_kfree_skb_any(skb); |
695 | goto out; | 673 | goto out; |
696 | } | 674 | } |
@@ -705,7 +683,7 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb) | |||
705 | if (skb_queue_len(&mcast->pkt_queue) < IPOIB_MAX_MCAST_QUEUE) | 683 | if (skb_queue_len(&mcast->pkt_queue) < IPOIB_MAX_MCAST_QUEUE) |
706 | skb_queue_tail(&mcast->pkt_queue, skb); | 684 | skb_queue_tail(&mcast->pkt_queue, skb); |
707 | else { | 685 | else { |
708 | ++priv->stats.tx_dropped; | 686 | ++dev->stats.tx_dropped; |
709 | dev_kfree_skb_any(skb); | 687 | dev_kfree_skb_any(skb); |
710 | } | 688 | } |
711 | 689 | ||
@@ -783,6 +761,7 @@ void ipoib_mcast_restart_task(struct work_struct *work) | |||
783 | struct ipoib_mcast *mcast, *tmcast; | 761 | struct ipoib_mcast *mcast, *tmcast; |
784 | LIST_HEAD(remove_list); | 762 | LIST_HEAD(remove_list); |
785 | unsigned long flags; | 763 | unsigned long flags; |
764 | struct ib_sa_mcmember_rec rec; | ||
786 | 765 | ||
787 | ipoib_dbg_mcast(priv, "restarting multicast task\n"); | 766 | ipoib_dbg_mcast(priv, "restarting multicast task\n"); |
788 | 767 | ||
@@ -816,6 +795,14 @@ void ipoib_mcast_restart_task(struct work_struct *work) | |||
816 | if (!mcast || test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) { | 795 | if (!mcast || test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) { |
817 | struct ipoib_mcast *nmcast; | 796 | struct ipoib_mcast *nmcast; |
818 | 797 | ||
798 | /* ignore group which is directly joined by userspace */ | ||
799 | if (test_bit(IPOIB_FLAG_UMCAST, &priv->flags) && | ||
800 | !ib_sa_get_mcmember_rec(priv->ca, priv->port, &mgid, &rec)) { | ||
801 | ipoib_dbg_mcast(priv, "ignoring multicast entry for mgid " | ||
802 | IPOIB_GID_FMT "\n", IPOIB_GID_ARG(mgid)); | ||
803 | continue; | ||
804 | } | ||
805 | |||
819 | /* Not found or send-only group, let's add a new entry */ | 806 | /* Not found or send-only group, let's add a new entry */ |
820 | ipoib_dbg_mcast(priv, "adding multicast entry for mgid " | 807 | ipoib_dbg_mcast(priv, "adding multicast entry for mgid " |
821 | IPOIB_GID_FMT "\n", IPOIB_GID_ARG(mgid)); | 808 | IPOIB_GID_FMT "\n", IPOIB_GID_ARG(mgid)); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 982eb88e27ec..3c6e45db0ab5 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c | |||
@@ -185,7 +185,7 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca) | |||
185 | goto out_free_cq; | 185 | goto out_free_cq; |
186 | 186 | ||
187 | init_attr.send_cq = priv->cq; | 187 | init_attr.send_cq = priv->cq; |
188 | init_attr.recv_cq = priv->cq, | 188 | init_attr.recv_cq = priv->cq; |
189 | 189 | ||
190 | priv->qp = ib_create_qp(priv->pd, &init_attr); | 190 | priv->qp = ib_create_qp(priv->pd, &init_attr); |
191 | if (IS_ERR(priv->qp)) { | 191 | if (IS_ERR(priv->qp)) { |
@@ -211,6 +211,7 @@ out_free_cq: | |||
211 | 211 | ||
212 | out_free_mr: | 212 | out_free_mr: |
213 | ib_dereg_mr(priv->mr); | 213 | ib_dereg_mr(priv->mr); |
214 | ipoib_cm_dev_cleanup(dev); | ||
214 | 215 | ||
215 | out_free_pd: | 216 | out_free_pd: |
216 | ib_dealloc_pd(priv->pd); | 217 | ib_dealloc_pd(priv->pd); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c index 6762988439d1..293f5b892e3f 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c | |||
@@ -119,6 +119,8 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) | |||
119 | goto sysfs_failed; | 119 | goto sysfs_failed; |
120 | if (ipoib_add_pkey_attr(priv->dev)) | 120 | if (ipoib_add_pkey_attr(priv->dev)) |
121 | goto sysfs_failed; | 121 | goto sysfs_failed; |
122 | if (ipoib_add_umcast_attr(priv->dev)) | ||
123 | goto sysfs_failed; | ||
122 | 124 | ||
123 | if (device_create_file(&priv->dev->dev, &dev_attr_parent)) | 125 | if (device_create_file(&priv->dev->dev, &dev_attr_parent)) |
124 | goto sysfs_failed; | 126 | goto sysfs_failed; |
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c index 9ea5b9aaba7c..a6f2303ed14a 100644 --- a/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/drivers/infiniband/ulp/iser/iser_initiator.c | |||
@@ -34,8 +34,6 @@ | |||
34 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/mm.h> | 36 | #include <linux/mm.h> |
37 | #include <asm/io.h> | ||
38 | #include <asm/scatterlist.h> | ||
39 | #include <linux/scatterlist.h> | 37 | #include <linux/scatterlist.h> |
40 | #include <linux/kfifo.h> | 38 | #include <linux/kfifo.h> |
41 | #include <scsi/scsi_cmnd.h> | 39 | #include <scsi/scsi_cmnd.h> |
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c index 36cdf77ae92a..e05690e3592f 100644 --- a/drivers/infiniband/ulp/iser/iser_memory.c +++ b/drivers/infiniband/ulp/iser/iser_memory.c | |||
@@ -36,8 +36,6 @@ | |||
36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
37 | #include <linux/mm.h> | 37 | #include <linux/mm.h> |
38 | #include <linux/highmem.h> | 38 | #include <linux/highmem.h> |
39 | #include <asm/io.h> | ||
40 | #include <asm/scatterlist.h> | ||
41 | #include <linux/scatterlist.h> | 39 | #include <linux/scatterlist.h> |
42 | 40 | ||
43 | #include "iscsi_iser.h" | 41 | #include "iscsi_iser.h" |
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index d42ec0156eec..654a4dce0236 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c | |||
@@ -32,7 +32,6 @@ | |||
32 | * | 32 | * |
33 | * $Id: iser_verbs.c 7051 2006-05-10 12:29:11Z ogerlitz $ | 33 | * $Id: iser_verbs.c 7051 2006-05-10 12:29:11Z ogerlitz $ |
34 | */ | 34 | */ |
35 | #include <asm/io.h> | ||
36 | #include <linux/kernel.h> | 35 | #include <linux/kernel.h> |
37 | #include <linux/module.h> | 36 | #include <linux/module.h> |
38 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index e616c4fc6ff0..950228fb009f 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
@@ -76,16 +76,12 @@ module_param(topspin_workarounds, int, 0444); | |||
76 | MODULE_PARM_DESC(topspin_workarounds, | 76 | MODULE_PARM_DESC(topspin_workarounds, |
77 | "Enable workarounds for Topspin/Cisco SRP target bugs if != 0"); | 77 | "Enable workarounds for Topspin/Cisco SRP target bugs if != 0"); |
78 | 78 | ||
79 | static const u8 topspin_oui[3] = { 0x00, 0x05, 0xad }; | ||
80 | |||
81 | static int mellanox_workarounds = 1; | 79 | static int mellanox_workarounds = 1; |
82 | 80 | ||
83 | module_param(mellanox_workarounds, int, 0444); | 81 | module_param(mellanox_workarounds, int, 0444); |
84 | MODULE_PARM_DESC(mellanox_workarounds, | 82 | MODULE_PARM_DESC(mellanox_workarounds, |
85 | "Enable workarounds for Mellanox SRP target bugs if != 0"); | 83 | "Enable workarounds for Mellanox SRP target bugs if != 0"); |
86 | 84 | ||
87 | static const u8 mellanox_oui[3] = { 0x00, 0x02, 0xc9 }; | ||
88 | |||
89 | static void srp_add_one(struct ib_device *device); | 85 | static void srp_add_one(struct ib_device *device); |
90 | static void srp_remove_one(struct ib_device *device); | 86 | static void srp_remove_one(struct ib_device *device); |
91 | static void srp_completion(struct ib_cq *cq, void *target_ptr); | 87 | static void srp_completion(struct ib_cq *cq, void *target_ptr); |
@@ -111,6 +107,24 @@ static const char *srp_target_info(struct Scsi_Host *host) | |||
111 | return host_to_target(host)->target_name; | 107 | return host_to_target(host)->target_name; |
112 | } | 108 | } |
113 | 109 | ||
110 | static int srp_target_is_topspin(struct srp_target_port *target) | ||
111 | { | ||
112 | static const u8 topspin_oui[3] = { 0x00, 0x05, 0xad }; | ||
113 | static const u8 cisco_oui[3] = { 0x00, 0x1b, 0x0d }; | ||
114 | |||
115 | return topspin_workarounds && | ||
116 | (!memcmp(&target->ioc_guid, topspin_oui, sizeof topspin_oui) || | ||
117 | !memcmp(&target->ioc_guid, cisco_oui, sizeof cisco_oui)); | ||
118 | } | ||
119 | |||
120 | static int srp_target_is_mellanox(struct srp_target_port *target) | ||
121 | { | ||
122 | static const u8 mellanox_oui[3] = { 0x00, 0x02, 0xc9 }; | ||
123 | |||
124 | return mellanox_workarounds && | ||
125 | !memcmp(&target->ioc_guid, mellanox_oui, sizeof mellanox_oui); | ||
126 | } | ||
127 | |||
114 | static struct srp_iu *srp_alloc_iu(struct srp_host *host, size_t size, | 128 | static struct srp_iu *srp_alloc_iu(struct srp_host *host, size_t size, |
115 | gfp_t gfp_mask, | 129 | gfp_t gfp_mask, |
116 | enum dma_data_direction direction) | 130 | enum dma_data_direction direction) |
@@ -274,6 +288,7 @@ static int srp_lookup_path(struct srp_target_port *target) | |||
274 | target->srp_host->dev->dev, | 288 | target->srp_host->dev->dev, |
275 | target->srp_host->port, | 289 | target->srp_host->port, |
276 | &target->path, | 290 | &target->path, |
291 | IB_SA_PATH_REC_SERVICE_ID | | ||
277 | IB_SA_PATH_REC_DGID | | 292 | IB_SA_PATH_REC_DGID | |
278 | IB_SA_PATH_REC_SGID | | 293 | IB_SA_PATH_REC_SGID | |
279 | IB_SA_PATH_REC_NUMB_PATH | | 294 | IB_SA_PATH_REC_NUMB_PATH | |
@@ -363,7 +378,7 @@ static int srp_send_req(struct srp_target_port *target) | |||
363 | * zero out the first 8 bytes of our initiator port ID and set | 378 | * zero out the first 8 bytes of our initiator port ID and set |
364 | * the second 8 bytes to the local node GUID. | 379 | * the second 8 bytes to the local node GUID. |
365 | */ | 380 | */ |
366 | if (topspin_workarounds && !memcmp(&target->ioc_guid, topspin_oui, 3)) { | 381 | if (srp_target_is_topspin(target)) { |
367 | printk(KERN_DEBUG PFX "Topspin/Cisco initiator port ID workaround " | 382 | printk(KERN_DEBUG PFX "Topspin/Cisco initiator port ID workaround " |
368 | "activated for target GUID %016llx\n", | 383 | "activated for target GUID %016llx\n", |
369 | (unsigned long long) be64_to_cpu(target->ioc_guid)); | 384 | (unsigned long long) be64_to_cpu(target->ioc_guid)); |
@@ -589,8 +604,8 @@ static int srp_map_fmr(struct srp_target_port *target, struct scatterlist *scat, | |||
589 | if (!dev->fmr_pool) | 604 | if (!dev->fmr_pool) |
590 | return -ENODEV; | 605 | return -ENODEV; |
591 | 606 | ||
592 | if ((ib_sg_dma_address(ibdev, &scat[0]) & ~dev->fmr_page_mask) && | 607 | if (srp_target_is_mellanox(target) && |
593 | mellanox_workarounds && !memcmp(&target->ioc_guid, mellanox_oui, 3)) | 608 | (ib_sg_dma_address(ibdev, &scat[0]) & ~dev->fmr_page_mask)) |
594 | return -EINVAL; | 609 | return -EINVAL; |
595 | 610 | ||
596 | len = page_cnt = 0; | 611 | len = page_cnt = 0; |
@@ -1091,8 +1106,7 @@ static void srp_cm_rej_handler(struct ib_cm_id *cm_id, | |||
1091 | break; | 1106 | break; |
1092 | 1107 | ||
1093 | case IB_CM_REJ_PORT_REDIRECT: | 1108 | case IB_CM_REJ_PORT_REDIRECT: |
1094 | if (topspin_workarounds && | 1109 | if (srp_target_is_topspin(target)) { |
1095 | !memcmp(&target->ioc_guid, topspin_oui, 3)) { | ||
1096 | /* | 1110 | /* |
1097 | * Topspin/Cisco SRP gateways incorrectly send | 1111 | * Topspin/Cisco SRP gateways incorrectly send |
1098 | * reject reason code 25 when they mean 24 | 1112 | * reject reason code 25 when they mean 24 |
@@ -1695,6 +1709,7 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) | |||
1695 | goto out; | 1709 | goto out; |
1696 | } | 1710 | } |
1697 | target->service_id = cpu_to_be64(simple_strtoull(p, NULL, 16)); | 1711 | target->service_id = cpu_to_be64(simple_strtoull(p, NULL, 16)); |
1712 | target->path.service_id = target->service_id; | ||
1698 | kfree(p); | 1713 | kfree(p); |
1699 | break; | 1714 | break; |
1700 | 1715 | ||