diff options
75 files changed, 3124 insertions, 1185 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 20c4c8bac9d7..9b8291f4c211 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
| @@ -295,16 +295,6 @@ Who: linuxppc-dev@ozlabs.org | |||
| 295 | 295 | ||
| 296 | --------------------------- | 296 | --------------------------- |
| 297 | 297 | ||
| 298 | What: mthca driver's MSI support | ||
| 299 | When: January 2008 | ||
| 300 | Files: drivers/infiniband/hw/mthca/*.[ch] | ||
| 301 | Why: All mthca hardware also supports MSI-X, which provides | ||
| 302 | strictly more functionality than MSI. So there is no point in | ||
| 303 | having both MSI-X and MSI support in the driver. | ||
| 304 | Who: Roland Dreier <rolandd@cisco.com> | ||
| 305 | |||
| 306 | --------------------------- | ||
| 307 | |||
| 308 | What: sk98lin network driver | 298 | What: sk98lin network driver |
| 309 | When: Feburary 2008 | 299 | When: Feburary 2008 |
| 310 | Why: In kernel tree version of driver is unmaintained. Sk98lin driver | 300 | Why: In kernel tree version of driver is unmaintained. Sk98lin driver |
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 2e39236d189f..c0150147d347 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2004-2006 Intel Corporation. All rights reserved. | 2 | * Copyright (c) 2004-2007 Intel Corporation. All rights reserved. |
| 3 | * Copyright (c) 2004 Topspin Corporation. All rights reserved. | 3 | * Copyright (c) 2004 Topspin Corporation. All rights reserved. |
| 4 | * Copyright (c) 2004, 2005 Voltaire Corporation. All rights reserved. | 4 | * Copyright (c) 2004, 2005 Voltaire Corporation. All rights reserved. |
| 5 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. | 5 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. |
| @@ -37,12 +37,14 @@ | |||
| 37 | 37 | ||
| 38 | #include <linux/completion.h> | 38 | #include <linux/completion.h> |
| 39 | #include <linux/dma-mapping.h> | 39 | #include <linux/dma-mapping.h> |
| 40 | #include <linux/device.h> | ||
| 40 | #include <linux/err.h> | 41 | #include <linux/err.h> |
| 41 | #include <linux/idr.h> | 42 | #include <linux/idr.h> |
| 42 | #include <linux/interrupt.h> | 43 | #include <linux/interrupt.h> |
| 43 | #include <linux/random.h> | 44 | #include <linux/random.h> |
| 44 | #include <linux/rbtree.h> | 45 | #include <linux/rbtree.h> |
| 45 | #include <linux/spinlock.h> | 46 | #include <linux/spinlock.h> |
| 47 | #include <linux/sysfs.h> | ||
| 46 | #include <linux/workqueue.h> | 48 | #include <linux/workqueue.h> |
| 47 | 49 | ||
| 48 | #include <rdma/ib_cache.h> | 50 | #include <rdma/ib_cache.h> |
| @@ -78,17 +80,94 @@ static struct ib_cm { | |||
| 78 | struct workqueue_struct *wq; | 80 | struct workqueue_struct *wq; |
| 79 | } cm; | 81 | } cm; |
| 80 | 82 | ||
| 83 | /* Counter indexes ordered by attribute ID */ | ||
| 84 | enum { | ||
| 85 | CM_REQ_COUNTER, | ||
| 86 | CM_MRA_COUNTER, | ||
| 87 | CM_REJ_COUNTER, | ||
| 88 | CM_REP_COUNTER, | ||
| 89 | CM_RTU_COUNTER, | ||
| 90 | CM_DREQ_COUNTER, | ||
| 91 | CM_DREP_COUNTER, | ||
| 92 | CM_SIDR_REQ_COUNTER, | ||
| 93 | CM_SIDR_REP_COUNTER, | ||
| 94 | CM_LAP_COUNTER, | ||
| 95 | CM_APR_COUNTER, | ||
| 96 | CM_ATTR_COUNT, | ||
| 97 | CM_ATTR_ID_OFFSET = 0x0010, | ||
| 98 | }; | ||
| 99 | |||
| 100 | enum { | ||
| 101 | CM_XMIT, | ||
| 102 | CM_XMIT_RETRIES, | ||
| 103 | CM_RECV, | ||
| 104 | CM_RECV_DUPLICATES, | ||
| 105 | CM_COUNTER_GROUPS | ||
| 106 | }; | ||
| 107 | |||
| 108 | static char const counter_group_names[CM_COUNTER_GROUPS] | ||
| 109 | [sizeof("cm_rx_duplicates")] = { | ||
| 110 | "cm_tx_msgs", "cm_tx_retries", | ||
| 111 | "cm_rx_msgs", "cm_rx_duplicates" | ||
| 112 | }; | ||
| 113 | |||
| 114 | struct cm_counter_group { | ||
| 115 | struct kobject obj; | ||
| 116 | atomic_long_t counter[CM_ATTR_COUNT]; | ||
| 117 | }; | ||
| 118 | |||
| 119 | struct cm_counter_attribute { | ||
| 120 | struct attribute attr; | ||
| 121 | int index; | ||
| 122 | }; | ||
| 123 | |||
| 124 | #define CM_COUNTER_ATTR(_name, _index) \ | ||
| 125 | struct cm_counter_attribute cm_##_name##_counter_attr = { \ | ||
| 126 | .attr = { .name = __stringify(_name), .mode = 0444, .owner = THIS_MODULE }, \ | ||
| 127 | .index = _index \ | ||
| 128 | } | ||
| 129 | |||
| 130 | static CM_COUNTER_ATTR(req, CM_REQ_COUNTER); | ||
| 131 | static CM_COUNTER_ATTR(mra, CM_MRA_COUNTER); | ||
| 132 | static CM_COUNTER_ATTR(rej, CM_REJ_COUNTER); | ||
| 133 | static CM_COUNTER_ATTR(rep, CM_REP_COUNTER); | ||
| 134 | static CM_COUNTER_ATTR(rtu, CM_RTU_COUNTER); | ||
| 135 | static CM_COUNTER_ATTR(dreq, CM_DREQ_COUNTER); | ||
| 136 | static CM_COUNTER_ATTR(drep, CM_DREP_COUNTER); | ||
| 137 | static CM_COUNTER_ATTR(sidr_req, CM_SIDR_REQ_COUNTER); | ||
| 138 | static CM_COUNTER_ATTR(sidr_rep, CM_SIDR_REP_COUNTER); | ||
| 139 | static CM_COUNTER_ATTR(lap, CM_LAP_COUNTER); | ||
| 140 | static CM_COUNTER_ATTR(apr, CM_APR_COUNTER); | ||
| 141 | |||
| 142 | static struct attribute *cm_counter_default_attrs[] = { | ||
| 143 | &cm_req_counter_attr.attr, | ||
| 144 | &cm_mra_counter_attr.attr, | ||
| 145 | &cm_rej_counter_attr.attr, | ||
| 146 | &cm_rep_counter_attr.attr, | ||
| 147 | &cm_rtu_counter_attr.attr, | ||
| 148 | &cm_dreq_counter_attr.attr, | ||
| 149 | &cm_drep_counter_attr.attr, | ||
| 150 | &cm_sidr_req_counter_attr.attr, | ||
| 151 | &cm_sidr_rep_counter_attr.attr, | ||
| 152 | &cm_lap_counter_attr.attr, | ||
| 153 | &cm_apr_counter_attr.attr, | ||
| 154 | NULL | ||
| 155 | }; | ||
| 156 | |||
| 81 | struct cm_port { | 157 | struct cm_port { |
| 82 | struct cm_device *cm_dev; | 158 | struct cm_device *cm_dev; |
| 83 | struct ib_mad_agent *mad_agent; | 159 | struct ib_mad_agent *mad_agent; |
| 160 | struct kobject port_obj; | ||
| 84 | u8 port_num; | 161 | u8 port_num; |
| 162 | struct cm_counter_group counter_group[CM_COUNTER_GROUPS]; | ||
| 85 | }; | 163 | }; |
| 86 | 164 | ||
| 87 | struct cm_device { | 165 | struct cm_device { |
| 88 | struct list_head list; | 166 | struct list_head list; |
| 89 | struct ib_device *device; | 167 | struct ib_device *device; |
| 168 | struct kobject dev_obj; | ||
| 90 | u8 ack_delay; | 169 | u8 ack_delay; |
| 91 | struct cm_port port[0]; | 170 | struct cm_port *port[0]; |
| 92 | }; | 171 | }; |
| 93 | 172 | ||
| 94 | struct cm_av { | 173 | struct cm_av { |
| @@ -278,7 +357,7 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av) | |||
| 278 | list_for_each_entry(cm_dev, &cm.device_list, list) { | 357 | list_for_each_entry(cm_dev, &cm.device_list, list) { |
| 279 | if (!ib_find_cached_gid(cm_dev->device, &path->sgid, | 358 | if (!ib_find_cached_gid(cm_dev->device, &path->sgid, |
| 280 | &p, NULL)) { | 359 | &p, NULL)) { |
| 281 | port = &cm_dev->port[p-1]; | 360 | port = cm_dev->port[p-1]; |
| 282 | break; | 361 | break; |
| 283 | } | 362 | } |
| 284 | } | 363 | } |
| @@ -1270,6 +1349,9 @@ static void cm_dup_req_handler(struct cm_work *work, | |||
| 1270 | struct ib_mad_send_buf *msg = NULL; | 1349 | struct ib_mad_send_buf *msg = NULL; |
| 1271 | int ret; | 1350 | int ret; |
| 1272 | 1351 | ||
| 1352 | atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES]. | ||
| 1353 | counter[CM_REQ_COUNTER]); | ||
| 1354 | |||
| 1273 | /* Quick state check to discard duplicate REQs. */ | 1355 | /* Quick state check to discard duplicate REQs. */ |
| 1274 | if (cm_id_priv->id.state == IB_CM_REQ_RCVD) | 1356 | if (cm_id_priv->id.state == IB_CM_REQ_RCVD) |
| 1275 | return; | 1357 | return; |
| @@ -1616,6 +1698,8 @@ static void cm_dup_rep_handler(struct cm_work *work) | |||
| 1616 | if (!cm_id_priv) | 1698 | if (!cm_id_priv) |
| 1617 | return; | 1699 | return; |
| 1618 | 1700 | ||
| 1701 | atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES]. | ||
| 1702 | counter[CM_REP_COUNTER]); | ||
| 1619 | ret = cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg); | 1703 | ret = cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg); |
| 1620 | if (ret) | 1704 | if (ret) |
| 1621 | goto deref; | 1705 | goto deref; |
| @@ -1781,6 +1865,8 @@ static int cm_rtu_handler(struct cm_work *work) | |||
| 1781 | if (cm_id_priv->id.state != IB_CM_REP_SENT && | 1865 | if (cm_id_priv->id.state != IB_CM_REP_SENT && |
| 1782 | cm_id_priv->id.state != IB_CM_MRA_REP_RCVD) { | 1866 | cm_id_priv->id.state != IB_CM_MRA_REP_RCVD) { |
| 1783 | spin_unlock_irq(&cm_id_priv->lock); | 1867 | spin_unlock_irq(&cm_id_priv->lock); |
| 1868 | atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES]. | ||
| 1869 | counter[CM_RTU_COUNTER]); | ||
| 1784 | goto out; | 1870 | goto out; |
| 1785 | } | 1871 | } |
| 1786 | cm_id_priv->id.state = IB_CM_ESTABLISHED; | 1872 | cm_id_priv->id.state = IB_CM_ESTABLISHED; |
| @@ -1958,6 +2044,8 @@ static int cm_dreq_handler(struct cm_work *work) | |||
| 1958 | cm_id_priv = cm_acquire_id(dreq_msg->remote_comm_id, | 2044 | cm_id_priv = cm_acquire_id(dreq_msg->remote_comm_id, |
| 1959 | dreq_msg->local_comm_id); | 2045 | dreq_msg->local_comm_id); |
| 1960 | if (!cm_id_priv) { | 2046 | if (!cm_id_priv) { |
| 2047 | atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES]. | ||
| 2048 | counter[CM_DREQ_COUNTER]); | ||
| 1961 | cm_issue_drep(work->port, work->mad_recv_wc); | 2049 | cm_issue_drep(work->port, work->mad_recv_wc); |
| 1962 | return -EINVAL; | 2050 | return -EINVAL; |
| 1963 | } | 2051 | } |
| @@ -1977,6 +2065,8 @@ static int cm_dreq_handler(struct cm_work *work) | |||
| 1977 | case IB_CM_MRA_REP_RCVD: | 2065 | case IB_CM_MRA_REP_RCVD: |
| 1978 | break; | 2066 | break; |
| 1979 | case IB_CM_TIMEWAIT: | 2067 | case IB_CM_TIMEWAIT: |
| 2068 | atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES]. | ||
| 2069 | counter[CM_DREQ_COUNTER]); | ||
| 1980 | if (cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg)) | 2070 | if (cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg)) |
| 1981 | goto unlock; | 2071 | goto unlock; |
| 1982 | 2072 | ||
| @@ -1988,6 +2078,10 @@ static int cm_dreq_handler(struct cm_work *work) | |||
| 1988 | if (ib_post_send_mad(msg, NULL)) | 2078 | if (ib_post_send_mad(msg, NULL)) |
| 1989 | cm_free_msg(msg); | 2079 | cm_free_msg(msg); |
| 1990 | goto deref; | 2080 | goto deref; |
| 2081 | case IB_CM_DREQ_RCVD: | ||
| 2082 | atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES]. | ||
| 2083 | counter[CM_DREQ_COUNTER]); | ||
| 2084 | goto unlock; | ||
| 1991 | default: | 2085 | default: |
| 1992 | goto unlock; | 2086 | goto unlock; |
| 1993 | } | 2087 | } |
| @@ -2339,10 +2433,20 @@ static int cm_mra_handler(struct cm_work *work) | |||
| 2339 | if (cm_mra_get_msg_mraed(mra_msg) != CM_MSG_RESPONSE_OTHER || | 2433 | if (cm_mra_get_msg_mraed(mra_msg) != CM_MSG_RESPONSE_OTHER || |
| 2340 | cm_id_priv->id.lap_state != IB_CM_LAP_SENT || | 2434 | cm_id_priv->id.lap_state != IB_CM_LAP_SENT || |
| 2341 | ib_modify_mad(cm_id_priv->av.port->mad_agent, | 2435 | ib_modify_mad(cm_id_priv->av.port->mad_agent, |
| 2342 | cm_id_priv->msg, timeout)) | 2436 | cm_id_priv->msg, timeout)) { |
| 2437 | if (cm_id_priv->id.lap_state == IB_CM_MRA_LAP_RCVD) | ||
| 2438 | atomic_long_inc(&work->port-> | ||
| 2439 | counter_group[CM_RECV_DUPLICATES]. | ||
| 2440 | counter[CM_MRA_COUNTER]); | ||
| 2343 | goto out; | 2441 | goto out; |
| 2442 | } | ||
| 2344 | cm_id_priv->id.lap_state = IB_CM_MRA_LAP_RCVD; | 2443 | cm_id_priv->id.lap_state = IB_CM_MRA_LAP_RCVD; |
| 2345 | break; | 2444 | break; |
| 2445 | case IB_CM_MRA_REQ_RCVD: | ||
| 2446 | case IB_CM_MRA_REP_RCVD: | ||
| 2447 | atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES]. | ||
| 2448 | counter[CM_MRA_COUNTER]); | ||
| 2449 | /* fall through */ | ||
| 2346 | default: | 2450 | default: |
| 2347 | goto out; | 2451 | goto out; |
| 2348 | } | 2452 | } |
| @@ -2502,6 +2606,8 @@ static int cm_lap_handler(struct cm_work *work) | |||
| 2502 | case IB_CM_LAP_IDLE: | 2606 | case IB_CM_LAP_IDLE: |
| 2503 | break; | 2607 | break; |
| 2504 | case IB_CM_MRA_LAP_SENT: | 2608 | case IB_CM_MRA_LAP_SENT: |
| 2609 | atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES]. | ||
| 2610 | counter[CM_LAP_COUNTER]); | ||
| 2505 | if (cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg)) | 2611 | if (cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg)) |
| 2506 | goto unlock; | 2612 | goto unlock; |
| 2507 | 2613 | ||
| @@ -2515,6 +2621,10 @@ static int cm_lap_handler(struct cm_work *work) | |||
| 2515 | if (ib_post_send_mad(msg, NULL)) | 2621 | if (ib_post_send_mad(msg, NULL)) |
| 2516 | cm_free_msg(msg); | 2622 | cm_free_msg(msg); |
| 2517 | goto deref; | 2623 | goto deref; |
| 2624 | case IB_CM_LAP_RCVD: | ||
| 2625 | atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES]. | ||
| 2626 | counter[CM_LAP_COUNTER]); | ||
| 2627 | goto unlock; | ||
| 2518 | default: | 2628 | default: |
| 2519 | goto unlock; | 2629 | goto unlock; |
| 2520 | } | 2630 | } |
| @@ -2796,6 +2906,8 @@ static int cm_sidr_req_handler(struct cm_work *work) | |||
| 2796 | cur_cm_id_priv = cm_insert_remote_sidr(cm_id_priv); | 2906 | cur_cm_id_priv = cm_insert_remote_sidr(cm_id_priv); |
| 2797 | if (cur_cm_id_priv) { | 2907 | if (cur_cm_id_priv) { |
| 2798 | spin_unlock_irq(&cm.lock); | 2908 | spin_unlock_irq(&cm.lock); |
| 2909 | atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES]. | ||
| 2910 | counter[CM_SIDR_REQ_COUNTER]); | ||
| 2799 | goto out; /* Duplicate message. */ | 2911 | goto out; /* Duplicate message. */ |
| 2800 | } | 2912 | } |
| 2801 | cm_id_priv->id.state = IB_CM_SIDR_REQ_RCVD; | 2913 | cm_id_priv->id.state = IB_CM_SIDR_REQ_RCVD; |
| @@ -2990,6 +3102,27 @@ static void cm_send_handler(struct ib_mad_agent *mad_agent, | |||
| 2990 | struct ib_mad_send_wc *mad_send_wc) | 3102 | struct ib_mad_send_wc *mad_send_wc) |
| 2991 | { | 3103 | { |
| 2992 | struct ib_mad_send_buf *msg = mad_send_wc->send_buf; | 3104 | struct ib_mad_send_buf *msg = mad_send_wc->send_buf; |
| 3105 | struct cm_port *port; | ||
| 3106 | u16 attr_index; | ||
| 3107 | |||
| 3108 | port = mad_agent->context; | ||
| 3109 | attr_index = be16_to_cpu(((struct ib_mad_hdr *) | ||
| 3110 | msg->mad)->attr_id) - CM_ATTR_ID_OFFSET; | ||
| 3111 | |||
| 3112 | /* | ||
| 3113 | * If the send was in response to a received message (context[0] is not | ||
| 3114 | * set to a cm_id), and is not a REJ, then it is a send that was | ||
| 3115 | * manually retried. | ||
| 3116 | */ | ||
| 3117 | if (!msg->context[0] && (attr_index != CM_REJ_COUNTER)) | ||
| 3118 | msg->retries = 1; | ||
| 3119 | |||
| 3120 | atomic_long_add(1 + msg->retries, | ||
| 3121 | &port->counter_group[CM_XMIT].counter[attr_index]); | ||
| 3122 | if (msg->retries) | ||
| 3123 | atomic_long_add(msg->retries, | ||
| 3124 | &port->counter_group[CM_XMIT_RETRIES]. | ||
| 3125 | counter[attr_index]); | ||
| 2993 | 3126 | ||
| 2994 | switch (mad_send_wc->status) { | 3127 | switch (mad_send_wc->status) { |
| 2995 | case IB_WC_SUCCESS: | 3128 | case IB_WC_SUCCESS: |
| @@ -3148,8 +3281,10 @@ EXPORT_SYMBOL(ib_cm_notify); | |||
| 3148 | static void cm_recv_handler(struct ib_mad_agent *mad_agent, | 3281 | static void cm_recv_handler(struct ib_mad_agent *mad_agent, |
| 3149 | struct ib_mad_recv_wc *mad_recv_wc) | 3282 | struct ib_mad_recv_wc *mad_recv_wc) |
| 3150 | { | 3283 | { |
| 3284 | struct cm_port *port = mad_agent->context; | ||
| 3151 | struct cm_work *work; | 3285 | struct cm_work *work; |
| 3152 | enum ib_cm_event_type event; | 3286 | enum ib_cm_event_type event; |
| 3287 | u16 attr_id; | ||
| 3153 | int paths = 0; | 3288 | int paths = 0; |
| 3154 | 3289 | ||
| 3155 | switch (mad_recv_wc->recv_buf.mad->mad_hdr.attr_id) { | 3290 | switch (mad_recv_wc->recv_buf.mad->mad_hdr.attr_id) { |
| @@ -3194,6 +3329,10 @@ static void cm_recv_handler(struct ib_mad_agent *mad_agent, | |||
| 3194 | return; | 3329 | return; |
| 3195 | } | 3330 | } |
| 3196 | 3331 | ||
| 3332 | attr_id = be16_to_cpu(mad_recv_wc->recv_buf.mad->mad_hdr.attr_id); | ||
| 3333 | atomic_long_inc(&port->counter_group[CM_RECV]. | ||
| 3334 | counter[attr_id - CM_ATTR_ID_OFFSET]); | ||
| 3335 | |||
| 3197 | work = kmalloc(sizeof *work + sizeof(struct ib_sa_path_rec) * paths, | 3336 | work = kmalloc(sizeof *work + sizeof(struct ib_sa_path_rec) * paths, |
| 3198 | GFP_KERNEL); | 3337 | GFP_KERNEL); |
| 3199 | if (!work) { | 3338 | if (!work) { |
| @@ -3204,7 +3343,7 @@ static void cm_recv_handler(struct ib_mad_agent *mad_agent, | |||
| 3204 | INIT_DELAYED_WORK(&work->work, cm_work_handler); | 3343 | INIT_DELAYED_WORK(&work->work, cm_work_handler); |
| 3205 | work->cm_event.event = event; | 3344 | work->cm_event.event = event; |
| 3206 | work->mad_recv_wc = mad_recv_wc; | 3345 | work->mad_recv_wc = mad_recv_wc; |
| 3207 | work->port = (struct cm_port *)mad_agent->context; | 3346 | work->port = port; |
| 3208 | queue_delayed_work(cm.wq, &work->work, 0); | 3347 | queue_delayed_work(cm.wq, &work->work, 0); |
| 3209 | } | 3348 | } |
| 3210 | 3349 | ||
| @@ -3379,6 +3518,108 @@ static void cm_get_ack_delay(struct cm_device *cm_dev) | |||
| 3379 | cm_dev->ack_delay = attr.local_ca_ack_delay; | 3518 | cm_dev->ack_delay = attr.local_ca_ack_delay; |
| 3380 | } | 3519 | } |
| 3381 | 3520 | ||
| 3521 | static ssize_t cm_show_counter(struct kobject *obj, struct attribute *attr, | ||
| 3522 | char *buf) | ||
| 3523 | { | ||
| 3524 | struct cm_counter_group *group; | ||
| 3525 | struct cm_counter_attribute *cm_attr; | ||
| 3526 | |||
| 3527 | group = container_of(obj, struct cm_counter_group, obj); | ||
| 3528 | cm_attr = container_of(attr, struct cm_counter_attribute, attr); | ||
| 3529 | |||
| 3530 | return sprintf(buf, "%ld\n", | ||
| 3531 | atomic_long_read(&group->counter[cm_attr->index])); | ||
| 3532 | } | ||
| 3533 | |||
| 3534 | static struct sysfs_ops cm_counter_ops = { | ||
| 3535 | .show = cm_show_counter | ||
| 3536 | }; | ||
| 3537 | |||
| 3538 | static struct kobj_type cm_counter_obj_type = { | ||
| 3539 | .sysfs_ops = &cm_counter_ops, | ||
| 3540 | .default_attrs = cm_counter_default_attrs | ||
| 3541 | }; | ||
| 3542 | |||
| 3543 | static void cm_release_port_obj(struct kobject *obj) | ||
| 3544 | { | ||
| 3545 | struct cm_port *cm_port; | ||
| 3546 | |||
| 3547 | printk(KERN_ERR "free cm port\n"); | ||
| 3548 | |||
| 3549 | cm_port = container_of(obj, struct cm_port, port_obj); | ||
| 3550 | kfree(cm_port); | ||
| 3551 | } | ||
| 3552 | |||
| 3553 | static struct kobj_type cm_port_obj_type = { | ||
| 3554 | .release = cm_release_port_obj | ||
| 3555 | }; | ||
| 3556 | |||
| 3557 | static void cm_release_dev_obj(struct kobject *obj) | ||
| 3558 | { | ||
| 3559 | struct cm_device *cm_dev; | ||
| 3560 | |||
| 3561 | printk(KERN_ERR "free cm dev\n"); | ||
| 3562 | |||
| 3563 | cm_dev = container_of(obj, struct cm_device, dev_obj); | ||
| 3564 | kfree(cm_dev); | ||
| 3565 | } | ||
| 3566 | |||
| 3567 | static struct kobj_type cm_dev_obj_type = { | ||
| 3568 | .release = cm_release_dev_obj | ||
| 3569 | }; | ||
| 3570 | |||
| 3571 | struct class cm_class = { | ||
| 3572 | .name = "infiniband_cm", | ||
| 3573 | }; | ||
| 3574 | EXPORT_SYMBOL(cm_class); | ||
| 3575 | |||
| 3576 | static void cm_remove_fs_obj(struct kobject *obj) | ||
| 3577 | { | ||
| 3578 | kobject_put(obj->parent); | ||
| 3579 | kobject_put(obj); | ||
| 3580 | } | ||
| 3581 | |||
| 3582 | static int cm_create_port_fs(struct cm_port *port) | ||
| 3583 | { | ||
| 3584 | int i, ret; | ||
| 3585 | |||
| 3586 | ret = kobject_init_and_add(&port->port_obj, &cm_port_obj_type, | ||
| 3587 | kobject_get(&port->cm_dev->dev_obj), | ||
| 3588 | "%d", port->port_num); | ||
| 3589 | if (ret) { | ||
| 3590 | kfree(port); | ||
| 3591 | return ret; | ||
| 3592 | } | ||
| 3593 | |||
| 3594 | for (i = 0; i < CM_COUNTER_GROUPS; i++) { | ||
| 3595 | ret = kobject_init_and_add(&port->counter_group[i].obj, | ||
| 3596 | &cm_counter_obj_type, | ||
| 3597 | kobject_get(&port->port_obj), | ||
| 3598 | "%s", counter_group_names[i]); | ||
| 3599 | if (ret) | ||
| 3600 | goto error; | ||
| 3601 | } | ||
| 3602 | |||
| 3603 | return 0; | ||
| 3604 | |||
| 3605 | error: | ||
| 3606 | while (i--) | ||
| 3607 | cm_remove_fs_obj(&port->counter_group[i].obj); | ||
| 3608 | cm_remove_fs_obj(&port->port_obj); | ||
| 3609 | return ret; | ||
| 3610 | |||
| 3611 | } | ||
| 3612 | |||
| 3613 | static void cm_remove_port_fs(struct cm_port *port) | ||
| 3614 | { | ||
| 3615 | int i; | ||
| 3616 | |||
| 3617 | for (i = 0; i < CM_COUNTER_GROUPS; i++) | ||
| 3618 | cm_remove_fs_obj(&port->counter_group[i].obj); | ||
| 3619 | |||
| 3620 | cm_remove_fs_obj(&port->port_obj); | ||
| 3621 | } | ||
| 3622 | |||
| 3382 | static void cm_add_one(struct ib_device *device) | 3623 | static void cm_add_one(struct ib_device *device) |
| 3383 | { | 3624 | { |
| 3384 | struct cm_device *cm_dev; | 3625 | struct cm_device *cm_dev; |
| @@ -3397,7 +3638,7 @@ static void cm_add_one(struct ib_device *device) | |||
| 3397 | if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB) | 3638 | if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB) |
| 3398 | return; | 3639 | return; |
| 3399 | 3640 | ||
| 3400 | cm_dev = kmalloc(sizeof(*cm_dev) + sizeof(*port) * | 3641 | cm_dev = kzalloc(sizeof(*cm_dev) + sizeof(*port) * |
| 3401 | device->phys_port_cnt, GFP_KERNEL); | 3642 | device->phys_port_cnt, GFP_KERNEL); |
| 3402 | if (!cm_dev) | 3643 | if (!cm_dev) |
| 3403 | return; | 3644 | return; |
| @@ -3405,11 +3646,27 @@ static void cm_add_one(struct ib_device *device) | |||
| 3405 | cm_dev->device = device; | 3646 | cm_dev->device = device; |
| 3406 | cm_get_ack_delay(cm_dev); | 3647 | cm_get_ack_delay(cm_dev); |
| 3407 | 3648 | ||
| 3649 | ret = kobject_init_and_add(&cm_dev->dev_obj, &cm_dev_obj_type, | ||
| 3650 | &cm_class.subsys.kobj, "%s", device->name); | ||
| 3651 | if (ret) { | ||
| 3652 | kfree(cm_dev); | ||
| 3653 | return; | ||
| 3654 | } | ||
| 3655 | |||
| 3408 | set_bit(IB_MGMT_METHOD_SEND, reg_req.method_mask); | 3656 | set_bit(IB_MGMT_METHOD_SEND, reg_req.method_mask); |
| 3409 | for (i = 1; i <= device->phys_port_cnt; i++) { | 3657 | for (i = 1; i <= device->phys_port_cnt; i++) { |
| 3410 | port = &cm_dev->port[i-1]; | 3658 | port = kzalloc(sizeof *port, GFP_KERNEL); |
| 3659 | if (!port) | ||
| 3660 | goto error1; | ||
| 3661 | |||
| 3662 | cm_dev->port[i-1] = port; | ||
| 3411 | port->cm_dev = cm_dev; | 3663 | port->cm_dev = cm_dev; |
| 3412 | port->port_num = i; | 3664 | port->port_num = i; |
| 3665 | |||
| 3666 | ret = cm_create_port_fs(port); | ||
| 3667 | if (ret) | ||
| 3668 | goto error1; | ||
| 3669 | |||
| 3413 | port->mad_agent = ib_register_mad_agent(device, i, | 3670 | port->mad_agent = ib_register_mad_agent(device, i, |
| 3414 | IB_QPT_GSI, | 3671 | IB_QPT_GSI, |
| 3415 | ®_req, | 3672 | ®_req, |
| @@ -3418,11 +3675,11 @@ static void cm_add_one(struct ib_device *device) | |||
| 3418 | cm_recv_handler, | 3675 | cm_recv_handler, |
| 3419 | port); | 3676 | port); |
| 3420 | if (IS_ERR(port->mad_agent)) | 3677 | if (IS_ERR(port->mad_agent)) |
| 3421 | goto error1; | 3678 | goto error2; |
| 3422 | 3679 | ||
| 3423 | ret = ib_modify_port(device, i, 0, &port_modify); | 3680 | ret = ib_modify_port(device, i, 0, &port_modify); |
| 3424 | if (ret) | 3681 | if (ret) |
| 3425 | goto error2; | 3682 | goto error3; |
| 3426 | } | 3683 | } |
| 3427 | ib_set_client_data(device, &cm_client, cm_dev); | 3684 | ib_set_client_data(device, &cm_client, cm_dev); |
| 3428 | 3685 | ||
| @@ -3431,17 +3688,20 @@ static void cm_add_one(struct ib_device *device) | |||
| 3431 | write_unlock_irqrestore(&cm.device_lock, flags); | 3688 | write_unlock_irqrestore(&cm.device_lock, flags); |
| 3432 | return; | 3689 | return; |
| 3433 | 3690 | ||
| 3434 | error2: | 3691 | error3: |
| 3435 | ib_unregister_mad_agent(port->mad_agent); | 3692 | ib_unregister_mad_agent(port->mad_agent); |
| 3693 | error2: | ||
| 3694 | cm_remove_port_fs(port); | ||
| 3436 | error1: | 3695 | error1: |
| 3437 | port_modify.set_port_cap_mask = 0; | 3696 | port_modify.set_port_cap_mask = 0; |
| 3438 | port_modify.clr_port_cap_mask = IB_PORT_CM_SUP; | 3697 | port_modify.clr_port_cap_mask = IB_PORT_CM_SUP; |
| 3439 | while (--i) { | 3698 | while (--i) { |
| 3440 | port = &cm_dev->port[i-1]; | 3699 | port = cm_dev->port[i-1]; |
| 3441 | ib_modify_port(device, port->port_num, 0, &port_modify); | 3700 | ib_modify_port(device, port->port_num, 0, &port_modify); |
| 3442 | ib_unregister_mad_agent(port->mad_agent); | 3701 | ib_unregister_mad_agent(port->mad_agent); |
| 3702 | cm_remove_port_fs(port); | ||
| 3443 | } | 3703 | } |
| 3444 | kfree(cm_dev); | 3704 | cm_remove_fs_obj(&cm_dev->dev_obj); |
| 3445 | } | 3705 | } |
| 3446 | 3706 | ||
| 3447 | static void cm_remove_one(struct ib_device *device) | 3707 | static void cm_remove_one(struct ib_device *device) |
| @@ -3463,11 +3723,12 @@ static void cm_remove_one(struct ib_device *device) | |||
| 3463 | write_unlock_irqrestore(&cm.device_lock, flags); | 3723 | write_unlock_irqrestore(&cm.device_lock, flags); |
| 3464 | 3724 | ||
| 3465 | for (i = 1; i <= device->phys_port_cnt; i++) { | 3725 | for (i = 1; i <= device->phys_port_cnt; i++) { |
| 3466 | port = &cm_dev->port[i-1]; | 3726 | port = cm_dev->port[i-1]; |
| 3467 | ib_modify_port(device, port->port_num, 0, &port_modify); | 3727 | ib_modify_port(device, port->port_num, 0, &port_modify); |
| 3468 | ib_unregister_mad_agent(port->mad_agent); | 3728 | ib_unregister_mad_agent(port->mad_agent); |
| 3729 | cm_remove_port_fs(port); | ||
| 3469 | } | 3730 | } |
| 3470 | kfree(cm_dev); | 3731 | cm_remove_fs_obj(&cm_dev->dev_obj); |
| 3471 | } | 3732 | } |
| 3472 | 3733 | ||
| 3473 | static int __init ib_cm_init(void) | 3734 | static int __init ib_cm_init(void) |
| @@ -3488,17 +3749,25 @@ static int __init ib_cm_init(void) | |||
| 3488 | idr_pre_get(&cm.local_id_table, GFP_KERNEL); | 3749 | idr_pre_get(&cm.local_id_table, GFP_KERNEL); |
| 3489 | INIT_LIST_HEAD(&cm.timewait_list); | 3750 | INIT_LIST_HEAD(&cm.timewait_list); |
| 3490 | 3751 | ||
| 3491 | cm.wq = create_workqueue("ib_cm"); | 3752 | ret = class_register(&cm_class); |
| 3492 | if (!cm.wq) | 3753 | if (ret) |
| 3493 | return -ENOMEM; | 3754 | return -ENOMEM; |
| 3494 | 3755 | ||
| 3756 | cm.wq = create_workqueue("ib_cm"); | ||
| 3757 | if (!cm.wq) { | ||
| 3758 | ret = -ENOMEM; | ||
| 3759 | goto error1; | ||
| 3760 | } | ||
| 3761 | |||
| 3495 | ret = ib_register_client(&cm_client); | 3762 | ret = ib_register_client(&cm_client); |
| 3496 | if (ret) | 3763 | if (ret) |
| 3497 | goto error; | 3764 | goto error2; |
| 3498 | 3765 | ||
| 3499 | return 0; | 3766 | return 0; |
| 3500 | error: | 3767 | error2: |
| 3501 | destroy_workqueue(cm.wq); | 3768 | destroy_workqueue(cm.wq); |
| 3769 | error1: | ||
| 3770 | class_unregister(&cm_class); | ||
| 3502 | return ret; | 3771 | return ret; |
| 3503 | } | 3772 | } |
| 3504 | 3773 | ||
| @@ -3519,6 +3788,7 @@ static void __exit ib_cm_cleanup(void) | |||
| 3519 | } | 3788 | } |
| 3520 | 3789 | ||
| 3521 | ib_unregister_client(&cm_client); | 3790 | ib_unregister_client(&cm_client); |
| 3791 | class_unregister(&cm_class); | ||
| 3522 | idr_destroy(&cm.local_id_table); | 3792 | idr_destroy(&cm.local_id_table); |
| 3523 | } | 3793 | } |
| 3524 | 3794 | ||
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 0751697ef984..637efead97a0 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
| @@ -488,7 +488,8 @@ void rdma_destroy_qp(struct rdma_cm_id *id) | |||
| 488 | } | 488 | } |
| 489 | EXPORT_SYMBOL(rdma_destroy_qp); | 489 | EXPORT_SYMBOL(rdma_destroy_qp); |
| 490 | 490 | ||
| 491 | static int cma_modify_qp_rtr(struct rdma_id_private *id_priv) | 491 | static int cma_modify_qp_rtr(struct rdma_id_private *id_priv, |
| 492 | struct rdma_conn_param *conn_param) | ||
| 492 | { | 493 | { |
| 493 | struct ib_qp_attr qp_attr; | 494 | struct ib_qp_attr qp_attr; |
| 494 | int qp_attr_mask, ret; | 495 | int qp_attr_mask, ret; |
| @@ -514,13 +515,16 @@ static int cma_modify_qp_rtr(struct rdma_id_private *id_priv) | |||
| 514 | if (ret) | 515 | if (ret) |
| 515 | goto out; | 516 | goto out; |
| 516 | 517 | ||
| 518 | if (conn_param) | ||
| 519 | qp_attr.max_dest_rd_atomic = conn_param->responder_resources; | ||
| 517 | ret = ib_modify_qp(id_priv->id.qp, &qp_attr, qp_attr_mask); | 520 | ret = ib_modify_qp(id_priv->id.qp, &qp_attr, qp_attr_mask); |
| 518 | out: | 521 | out: |
| 519 | mutex_unlock(&id_priv->qp_mutex); | 522 | mutex_unlock(&id_priv->qp_mutex); |
| 520 | return ret; | 523 | return ret; |
| 521 | } | 524 | } |
| 522 | 525 | ||
| 523 | static int cma_modify_qp_rts(struct rdma_id_private *id_priv) | 526 | static int cma_modify_qp_rts(struct rdma_id_private *id_priv, |
| 527 | struct rdma_conn_param *conn_param) | ||
| 524 | { | 528 | { |
| 525 | struct ib_qp_attr qp_attr; | 529 | struct ib_qp_attr qp_attr; |
| 526 | int qp_attr_mask, ret; | 530 | int qp_attr_mask, ret; |
| @@ -536,6 +540,8 @@ static int cma_modify_qp_rts(struct rdma_id_private *id_priv) | |||
| 536 | if (ret) | 540 | if (ret) |
| 537 | goto out; | 541 | goto out; |
| 538 | 542 | ||
| 543 | if (conn_param) | ||
| 544 | qp_attr.max_rd_atomic = conn_param->initiator_depth; | ||
| 539 | ret = ib_modify_qp(id_priv->id.qp, &qp_attr, qp_attr_mask); | 545 | ret = ib_modify_qp(id_priv->id.qp, &qp_attr, qp_attr_mask); |
| 540 | out: | 546 | out: |
| 541 | mutex_unlock(&id_priv->qp_mutex); | 547 | mutex_unlock(&id_priv->qp_mutex); |
| @@ -866,11 +872,11 @@ static int cma_rep_recv(struct rdma_id_private *id_priv) | |||
| 866 | { | 872 | { |
| 867 | int ret; | 873 | int ret; |
| 868 | 874 | ||
| 869 | ret = cma_modify_qp_rtr(id_priv); | 875 | ret = cma_modify_qp_rtr(id_priv, NULL); |
| 870 | if (ret) | 876 | if (ret) |
| 871 | goto reject; | 877 | goto reject; |
| 872 | 878 | ||
| 873 | ret = cma_modify_qp_rts(id_priv); | 879 | ret = cma_modify_qp_rts(id_priv, NULL); |
| 874 | if (ret) | 880 | if (ret) |
| 875 | goto reject; | 881 | goto reject; |
| 876 | 882 | ||
| @@ -1122,8 +1128,10 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) | |||
| 1122 | cm_id->cm_handler = cma_ib_handler; | 1128 | cm_id->cm_handler = cma_ib_handler; |
| 1123 | 1129 | ||
| 1124 | ret = conn_id->id.event_handler(&conn_id->id, &event); | 1130 | ret = conn_id->id.event_handler(&conn_id->id, &event); |
| 1125 | if (!ret) | 1131 | if (!ret) { |
| 1132 | cma_enable_remove(conn_id); | ||
| 1126 | goto out; | 1133 | goto out; |
| 1134 | } | ||
| 1127 | 1135 | ||
| 1128 | /* Destroy the CM ID by returning a non-zero value. */ | 1136 | /* Destroy the CM ID by returning a non-zero value. */ |
| 1129 | conn_id->cm_id.ib = NULL; | 1137 | conn_id->cm_id.ib = NULL; |
| @@ -1262,6 +1270,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, | |||
| 1262 | struct net_device *dev = NULL; | 1270 | struct net_device *dev = NULL; |
| 1263 | struct rdma_cm_event event; | 1271 | struct rdma_cm_event event; |
| 1264 | int ret; | 1272 | int ret; |
| 1273 | struct ib_device_attr attr; | ||
| 1265 | 1274 | ||
| 1266 | listen_id = cm_id->context; | 1275 | listen_id = cm_id->context; |
| 1267 | if (cma_disable_remove(listen_id, CMA_LISTEN)) | 1276 | if (cma_disable_remove(listen_id, CMA_LISTEN)) |
| @@ -1311,10 +1320,19 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, | |||
| 1311 | sin = (struct sockaddr_in *) &new_cm_id->route.addr.dst_addr; | 1320 | sin = (struct sockaddr_in *) &new_cm_id->route.addr.dst_addr; |
| 1312 | *sin = iw_event->remote_addr; | 1321 | *sin = iw_event->remote_addr; |
| 1313 | 1322 | ||
| 1323 | ret = ib_query_device(conn_id->id.device, &attr); | ||
| 1324 | if (ret) { | ||
| 1325 | cma_enable_remove(conn_id); | ||
| 1326 | rdma_destroy_id(new_cm_id); | ||
| 1327 | goto out; | ||
| 1328 | } | ||
| 1329 | |||
| 1314 | memset(&event, 0, sizeof event); | 1330 | memset(&event, 0, sizeof event); |
| 1315 | event.event = RDMA_CM_EVENT_CONNECT_REQUEST; | 1331 | event.event = RDMA_CM_EVENT_CONNECT_REQUEST; |
| 1316 | event.param.conn.private_data = iw_event->private_data; | 1332 | event.param.conn.private_data = iw_event->private_data; |
| 1317 | event.param.conn.private_data_len = iw_event->private_data_len; | 1333 | event.param.conn.private_data_len = iw_event->private_data_len; |
| 1334 | event.param.conn.initiator_depth = attr.max_qp_init_rd_atom; | ||
| 1335 | event.param.conn.responder_resources = attr.max_qp_rd_atom; | ||
| 1318 | ret = conn_id->id.event_handler(&conn_id->id, &event); | 1336 | ret = conn_id->id.event_handler(&conn_id->id, &event); |
| 1319 | if (ret) { | 1337 | if (ret) { |
| 1320 | /* User wants to destroy the CM ID */ | 1338 | /* User wants to destroy the CM ID */ |
| @@ -2272,7 +2290,7 @@ static int cma_connect_iw(struct rdma_id_private *id_priv, | |||
| 2272 | sin = (struct sockaddr_in*) &id_priv->id.route.addr.dst_addr; | 2290 | sin = (struct sockaddr_in*) &id_priv->id.route.addr.dst_addr; |
| 2273 | cm_id->remote_addr = *sin; | 2291 | cm_id->remote_addr = *sin; |
| 2274 | 2292 | ||
| 2275 | ret = cma_modify_qp_rtr(id_priv); | 2293 | ret = cma_modify_qp_rtr(id_priv, conn_param); |
| 2276 | if (ret) | 2294 | if (ret) |
| 2277 | goto out; | 2295 | goto out; |
| 2278 | 2296 | ||
| @@ -2335,25 +2353,15 @@ static int cma_accept_ib(struct rdma_id_private *id_priv, | |||
| 2335 | struct rdma_conn_param *conn_param) | 2353 | struct rdma_conn_param *conn_param) |
| 2336 | { | 2354 | { |
| 2337 | struct ib_cm_rep_param rep; | 2355 | struct ib_cm_rep_param rep; |
| 2338 | struct ib_qp_attr qp_attr; | 2356 | int ret; |
| 2339 | int qp_attr_mask, ret; | ||
| 2340 | |||
| 2341 | if (id_priv->id.qp) { | ||
| 2342 | ret = cma_modify_qp_rtr(id_priv); | ||
| 2343 | if (ret) | ||
| 2344 | goto out; | ||
| 2345 | 2357 | ||
| 2346 | qp_attr.qp_state = IB_QPS_RTS; | 2358 | ret = cma_modify_qp_rtr(id_priv, conn_param); |
| 2347 | ret = ib_cm_init_qp_attr(id_priv->cm_id.ib, &qp_attr, | 2359 | if (ret) |
| 2348 | &qp_attr_mask); | 2360 | goto out; |
| 2349 | if (ret) | ||
| 2350 | goto out; | ||
| 2351 | 2361 | ||
| 2352 | qp_attr.max_rd_atomic = conn_param->initiator_depth; | 2362 | ret = cma_modify_qp_rts(id_priv, conn_param); |
| 2353 | ret = ib_modify_qp(id_priv->id.qp, &qp_attr, qp_attr_mask); | 2363 | if (ret) |
| 2354 | if (ret) | 2364 | goto out; |
| 2355 | goto out; | ||
| 2356 | } | ||
| 2357 | 2365 | ||
| 2358 | memset(&rep, 0, sizeof rep); | 2366 | memset(&rep, 0, sizeof rep); |
| 2359 | rep.qp_num = id_priv->qp_num; | 2367 | rep.qp_num = id_priv->qp_num; |
| @@ -2378,7 +2386,7 @@ static int cma_accept_iw(struct rdma_id_private *id_priv, | |||
| 2378 | struct iw_cm_conn_param iw_param; | 2386 | struct iw_cm_conn_param iw_param; |
| 2379 | int ret; | 2387 | int ret; |
| 2380 | 2388 | ||
| 2381 | ret = cma_modify_qp_rtr(id_priv); | 2389 | ret = cma_modify_qp_rtr(id_priv, conn_param); |
| 2382 | if (ret) | 2390 | if (ret) |
| 2383 | return ret; | 2391 | return ret; |
| 2384 | 2392 | ||
| @@ -2598,11 +2606,9 @@ static void cma_set_mgid(struct rdma_id_private *id_priv, | |||
| 2598 | /* IPv6 address is an SA assigned MGID. */ | 2606 | /* IPv6 address is an SA assigned MGID. */ |
| 2599 | memcpy(mgid, &sin6->sin6_addr, sizeof *mgid); | 2607 | memcpy(mgid, &sin6->sin6_addr, sizeof *mgid); |
| 2600 | } else { | 2608 | } else { |
| 2601 | ip_ib_mc_map(sin->sin_addr.s_addr, mc_map); | 2609 | ip_ib_mc_map(sin->sin_addr.s_addr, dev_addr->broadcast, mc_map); |
| 2602 | if (id_priv->id.ps == RDMA_PS_UDP) | 2610 | if (id_priv->id.ps == RDMA_PS_UDP) |
| 2603 | mc_map[7] = 0x01; /* Use RDMA CM signature */ | 2611 | mc_map[7] = 0x01; /* Use RDMA CM signature */ |
| 2604 | mc_map[8] = ib_addr_get_pkey(dev_addr) >> 8; | ||
| 2605 | mc_map[9] = (unsigned char) ib_addr_get_pkey(dev_addr); | ||
| 2606 | *mgid = *(union ib_gid *) (mc_map + 4); | 2612 | *mgid = *(union ib_gid *) (mc_map + 4); |
| 2607 | } | 2613 | } |
| 2608 | } | 2614 | } |
diff --git a/drivers/infiniband/core/fmr_pool.c b/drivers/infiniband/core/fmr_pool.c index e8d5f6b64998..6c7aa59794d4 100644 --- a/drivers/infiniband/core/fmr_pool.c +++ b/drivers/infiniband/core/fmr_pool.c | |||
| @@ -139,7 +139,7 @@ static inline struct ib_pool_fmr *ib_fmr_cache_lookup(struct ib_fmr_pool *pool, | |||
| 139 | static void ib_fmr_batch_release(struct ib_fmr_pool *pool) | 139 | static void ib_fmr_batch_release(struct ib_fmr_pool *pool) |
| 140 | { | 140 | { |
| 141 | int ret; | 141 | int ret; |
| 142 | struct ib_pool_fmr *fmr; | 142 | struct ib_pool_fmr *fmr, *next; |
| 143 | LIST_HEAD(unmap_list); | 143 | LIST_HEAD(unmap_list); |
| 144 | LIST_HEAD(fmr_list); | 144 | LIST_HEAD(fmr_list); |
| 145 | 145 | ||
| @@ -158,6 +158,20 @@ static void ib_fmr_batch_release(struct ib_fmr_pool *pool) | |||
| 158 | #endif | 158 | #endif |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | /* | ||
| 162 | * The free_list may hold FMRs that have been put there | ||
| 163 | * because they haven't reached the max_remap count. | ||
| 164 | * Invalidate their mapping as well. | ||
| 165 | */ | ||
| 166 | list_for_each_entry_safe(fmr, next, &pool->free_list, list) { | ||
| 167 | if (fmr->remap_count == 0) | ||
| 168 | continue; | ||
| 169 | hlist_del_init(&fmr->cache_node); | ||
| 170 | fmr->remap_count = 0; | ||
| 171 | list_add_tail(&fmr->fmr->list, &fmr_list); | ||
| 172 | list_move(&fmr->list, &unmap_list); | ||
| 173 | } | ||
| 174 | |||
| 161 | list_splice(&pool->dirty_list, &unmap_list); | 175 | list_splice(&pool->dirty_list, &unmap_list); |
| 162 | INIT_LIST_HEAD(&pool->dirty_list); | 176 | INIT_LIST_HEAD(&pool->dirty_list); |
| 163 | pool->dirty_len = 0; | 177 | pool->dirty_len = 0; |
| @@ -182,8 +196,7 @@ static int ib_fmr_cleanup_thread(void *pool_ptr) | |||
| 182 | struct ib_fmr_pool *pool = pool_ptr; | 196 | struct ib_fmr_pool *pool = pool_ptr; |
| 183 | 197 | ||
| 184 | do { | 198 | do { |
| 185 | if (pool->dirty_len >= pool->dirty_watermark || | 199 | if (atomic_read(&pool->flush_ser) - atomic_read(&pool->req_ser) < 0) { |
| 186 | atomic_read(&pool->flush_ser) - atomic_read(&pool->req_ser) < 0) { | ||
| 187 | ib_fmr_batch_release(pool); | 200 | ib_fmr_batch_release(pool); |
| 188 | 201 | ||
| 189 | atomic_inc(&pool->flush_ser); | 202 | atomic_inc(&pool->flush_ser); |
| @@ -194,8 +207,7 @@ static int ib_fmr_cleanup_thread(void *pool_ptr) | |||
| 194 | } | 207 | } |
| 195 | 208 | ||
| 196 | set_current_state(TASK_INTERRUPTIBLE); | 209 | set_current_state(TASK_INTERRUPTIBLE); |
| 197 | if (pool->dirty_len < pool->dirty_watermark && | 210 | if (atomic_read(&pool->flush_ser) - atomic_read(&pool->req_ser) >= 0 && |
| 198 | atomic_read(&pool->flush_ser) - atomic_read(&pool->req_ser) >= 0 && | ||
| 199 | !kthread_should_stop()) | 211 | !kthread_should_stop()) |
| 200 | schedule(); | 212 | schedule(); |
| 201 | __set_current_state(TASK_RUNNING); | 213 | __set_current_state(TASK_RUNNING); |
| @@ -369,11 +381,6 @@ void ib_destroy_fmr_pool(struct ib_fmr_pool *pool) | |||
| 369 | 381 | ||
| 370 | i = 0; | 382 | i = 0; |
| 371 | list_for_each_entry_safe(fmr, tmp, &pool->free_list, list) { | 383 | list_for_each_entry_safe(fmr, tmp, &pool->free_list, list) { |
| 372 | if (fmr->remap_count) { | ||
| 373 | INIT_LIST_HEAD(&fmr_list); | ||
| 374 | list_add_tail(&fmr->fmr->list, &fmr_list); | ||
| 375 | ib_unmap_fmr(&fmr_list); | ||
| 376 | } | ||
| 377 | ib_dealloc_fmr(fmr->fmr); | 384 | ib_dealloc_fmr(fmr->fmr); |
| 378 | list_del(&fmr->list); | 385 | list_del(&fmr->list); |
| 379 | kfree(fmr); | 386 | kfree(fmr); |
| @@ -511,8 +518,10 @@ int ib_fmr_pool_unmap(struct ib_pool_fmr *fmr) | |||
| 511 | list_add_tail(&fmr->list, &pool->free_list); | 518 | list_add_tail(&fmr->list, &pool->free_list); |
| 512 | } else { | 519 | } else { |
| 513 | list_add_tail(&fmr->list, &pool->dirty_list); | 520 | list_add_tail(&fmr->list, &pool->dirty_list); |
| 514 | ++pool->dirty_len; | 521 | if (++pool->dirty_len >= pool->dirty_watermark) { |
| 515 | wake_up_process(pool->thread); | 522 | atomic_inc(&pool->req_ser); |
| 523 | wake_up_process(pool->thread); | ||
| 524 | } | ||
| 516 | } | 525 | } |
| 517 | } | 526 | } |
| 518 | 527 | ||
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 6f4287716ab1..fbe16d5250a4 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
| @@ -701,7 +701,8 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, | |||
| 701 | } | 701 | } |
| 702 | 702 | ||
| 703 | /* Check to post send on QP or process locally */ | 703 | /* Check to post send on QP or process locally */ |
| 704 | if (smi_check_local_smp(smp, device) == IB_SMI_DISCARD) | 704 | if (smi_check_local_smp(smp, device) == IB_SMI_DISCARD && |
| 705 | smi_check_local_returning_smp(smp, device) == IB_SMI_DISCARD) | ||
| 705 | goto out; | 706 | goto out; |
| 706 | 707 | ||
| 707 | local = kmalloc(sizeof *local, GFP_ATOMIC); | 708 | local = kmalloc(sizeof *local, GFP_ATOMIC); |
| @@ -752,8 +753,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, | |||
| 752 | port_priv = ib_get_mad_port(mad_agent_priv->agent.device, | 753 | port_priv = ib_get_mad_port(mad_agent_priv->agent.device, |
| 753 | mad_agent_priv->agent.port_num); | 754 | mad_agent_priv->agent.port_num); |
| 754 | if (port_priv) { | 755 | if (port_priv) { |
| 755 | mad_priv->mad.mad.mad_hdr.tid = | 756 | memcpy(&mad_priv->mad.mad, smp, sizeof(struct ib_mad)); |
| 756 | ((struct ib_mad *)smp)->mad_hdr.tid; | ||
| 757 | recv_mad_agent = find_mad_agent(port_priv, | 757 | recv_mad_agent = find_mad_agent(port_priv, |
| 758 | &mad_priv->mad.mad); | 758 | &mad_priv->mad.mad); |
| 759 | } | 759 | } |
| @@ -1100,7 +1100,9 @@ int ib_post_send_mad(struct ib_mad_send_buf *send_buf, | |||
| 1100 | mad_send_wr->tid = ((struct ib_mad_hdr *) send_buf->mad)->tid; | 1100 | mad_send_wr->tid = ((struct ib_mad_hdr *) send_buf->mad)->tid; |
| 1101 | /* Timeout will be updated after send completes */ | 1101 | /* Timeout will be updated after send completes */ |
| 1102 | mad_send_wr->timeout = msecs_to_jiffies(send_buf->timeout_ms); | 1102 | mad_send_wr->timeout = msecs_to_jiffies(send_buf->timeout_ms); |
| 1103 | mad_send_wr->retries = send_buf->retries; | 1103 | mad_send_wr->max_retries = send_buf->retries; |
| 1104 | mad_send_wr->retries_left = send_buf->retries; | ||
| 1105 | send_buf->retries = 0; | ||
| 1104 | /* Reference for work request to QP + response */ | 1106 | /* Reference for work request to QP + response */ |
| 1105 | mad_send_wr->refcount = 1 + (mad_send_wr->timeout > 0); | 1107 | mad_send_wr->refcount = 1 + (mad_send_wr->timeout > 0); |
| 1106 | mad_send_wr->status = IB_WC_SUCCESS; | 1108 | mad_send_wr->status = IB_WC_SUCCESS; |
| @@ -1931,15 +1933,6 @@ local: | |||
| 1931 | if (port_priv->device->process_mad) { | 1933 | if (port_priv->device->process_mad) { |
| 1932 | int ret; | 1934 | int ret; |
| 1933 | 1935 | ||
| 1934 | if (!response) { | ||
| 1935 | printk(KERN_ERR PFX "No memory for response MAD\n"); | ||
| 1936 | /* | ||
| 1937 | * Is it better to assume that | ||
| 1938 | * it wouldn't be processed ? | ||
| 1939 | */ | ||
| 1940 | goto out; | ||
| 1941 | } | ||
| 1942 | |||
| 1943 | ret = port_priv->device->process_mad(port_priv->device, 0, | 1936 | ret = port_priv->device->process_mad(port_priv->device, 0, |
| 1944 | port_priv->port_num, | 1937 | port_priv->port_num, |
| 1945 | wc, &recv->grh, | 1938 | wc, &recv->grh, |
| @@ -2282,8 +2275,6 @@ static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv) | |||
| 2282 | 2275 | ||
| 2283 | /* Empty wait list to prevent receives from finding a request */ | 2276 | /* Empty wait list to prevent receives from finding a request */ |
| 2284 | list_splice_init(&mad_agent_priv->wait_list, &cancel_list); | 2277 | list_splice_init(&mad_agent_priv->wait_list, &cancel_list); |
| 2285 | /* Empty local completion list as well */ | ||
| 2286 | list_splice_init(&mad_agent_priv->local_list, &cancel_list); | ||
| 2287 | spin_unlock_irqrestore(&mad_agent_priv->lock, flags); | 2278 | spin_unlock_irqrestore(&mad_agent_priv->lock, flags); |
| 2288 | 2279 | ||
| 2289 | /* Report all cancelled requests */ | 2280 | /* Report all cancelled requests */ |
| @@ -2445,9 +2436,12 @@ static int retry_send(struct ib_mad_send_wr_private *mad_send_wr) | |||
| 2445 | { | 2436 | { |
| 2446 | int ret; | 2437 | int ret; |
| 2447 | 2438 | ||
| 2448 | if (!mad_send_wr->retries--) | 2439 | if (!mad_send_wr->retries_left) |
| 2449 | return -ETIMEDOUT; | 2440 | return -ETIMEDOUT; |
| 2450 | 2441 | ||
| 2442 | mad_send_wr->retries_left--; | ||
| 2443 | mad_send_wr->send_buf.retries++; | ||
| 2444 | |||
| 2451 | mad_send_wr->timeout = msecs_to_jiffies(mad_send_wr->send_buf.timeout_ms); | 2445 | mad_send_wr->timeout = msecs_to_jiffies(mad_send_wr->send_buf.timeout_ms); |
| 2452 | 2446 | ||
| 2453 | if (mad_send_wr->mad_agent_priv->agent.rmpp_version) { | 2447 | if (mad_send_wr->mad_agent_priv->agent.rmpp_version) { |
diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h index 9be5cc00a3a9..8b75010016ec 100644 --- a/drivers/infiniband/core/mad_priv.h +++ b/drivers/infiniband/core/mad_priv.h | |||
| @@ -131,7 +131,8 @@ struct ib_mad_send_wr_private { | |||
| 131 | struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG]; | 131 | struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG]; |
| 132 | __be64 tid; | 132 | __be64 tid; |
| 133 | unsigned long timeout; | 133 | unsigned long timeout; |
| 134 | int retries; | 134 | int max_retries; |
| 135 | int retries_left; | ||
| 135 | int retry; | 136 | int retry; |
| 136 | int refcount; | 137 | int refcount; |
| 137 | enum ib_wc_status status; | 138 | enum ib_wc_status status; |
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c index d43bc62005b3..a5e2a310f312 100644 --- a/drivers/infiniband/core/mad_rmpp.c +++ b/drivers/infiniband/core/mad_rmpp.c | |||
| @@ -684,7 +684,7 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent, | |||
| 684 | 684 | ||
| 685 | if (seg_num > mad_send_wr->last_ack) { | 685 | if (seg_num > mad_send_wr->last_ack) { |
| 686 | adjust_last_ack(mad_send_wr, seg_num); | 686 | adjust_last_ack(mad_send_wr, seg_num); |
| 687 | mad_send_wr->retries = mad_send_wr->send_buf.retries; | 687 | mad_send_wr->retries_left = mad_send_wr->max_retries; |
| 688 | } | 688 | } |
| 689 | mad_send_wr->newwin = newwin; | 689 | mad_send_wr->newwin = newwin; |
| 690 | if (mad_send_wr->last_ack == mad_send_wr->send_buf.seg_count) { | 690 | if (mad_send_wr->last_ack == mad_send_wr->send_buf.seg_count) { |
diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/multicast.c index 1bc1fe605282..107f170c57cd 100644 --- a/drivers/infiniband/core/multicast.c +++ b/drivers/infiniband/core/multicast.c | |||
| @@ -73,11 +73,20 @@ struct mcast_device { | |||
| 73 | }; | 73 | }; |
| 74 | 74 | ||
| 75 | enum mcast_state { | 75 | enum mcast_state { |
| 76 | MCAST_IDLE, | ||
| 77 | MCAST_JOINING, | 76 | MCAST_JOINING, |
| 78 | MCAST_MEMBER, | 77 | MCAST_MEMBER, |
| 78 | MCAST_ERROR, | ||
| 79 | }; | ||
| 80 | |||
| 81 | enum mcast_group_state { | ||
| 82 | MCAST_IDLE, | ||
| 79 | MCAST_BUSY, | 83 | MCAST_BUSY, |
| 80 | MCAST_ERROR | 84 | MCAST_GROUP_ERROR, |
| 85 | MCAST_PKEY_EVENT | ||
| 86 | }; | ||
| 87 | |||
| 88 | enum { | ||
| 89 | MCAST_INVALID_PKEY_INDEX = 0xFFFF | ||
| 81 | }; | 90 | }; |
| 82 | 91 | ||
| 83 | struct mcast_member; | 92 | struct mcast_member; |
| @@ -93,9 +102,10 @@ struct mcast_group { | |||
| 93 | struct mcast_member *last_join; | 102 | struct mcast_member *last_join; |
| 94 | int members[3]; | 103 | int members[3]; |
| 95 | atomic_t refcount; | 104 | atomic_t refcount; |
| 96 | enum mcast_state state; | 105 | enum mcast_group_state state; |
| 97 | struct ib_sa_query *query; | 106 | struct ib_sa_query *query; |
| 98 | int query_id; | 107 | int query_id; |
| 108 | u16 pkey_index; | ||
| 99 | }; | 109 | }; |
| 100 | 110 | ||
| 101 | struct mcast_member { | 111 | struct mcast_member { |
| @@ -378,9 +388,19 @@ static int fail_join(struct mcast_group *group, struct mcast_member *member, | |||
| 378 | static void process_group_error(struct mcast_group *group) | 388 | static void process_group_error(struct mcast_group *group) |
| 379 | { | 389 | { |
| 380 | struct mcast_member *member; | 390 | struct mcast_member *member; |
| 381 | int ret; | 391 | int ret = 0; |
| 392 | u16 pkey_index; | ||
| 393 | |||
| 394 | if (group->state == MCAST_PKEY_EVENT) | ||
| 395 | ret = ib_find_pkey(group->port->dev->device, | ||
| 396 | group->port->port_num, | ||
| 397 | be16_to_cpu(group->rec.pkey), &pkey_index); | ||
| 382 | 398 | ||
| 383 | spin_lock_irq(&group->lock); | 399 | spin_lock_irq(&group->lock); |
| 400 | if (group->state == MCAST_PKEY_EVENT && !ret && | ||
| 401 | group->pkey_index == pkey_index) | ||
| 402 | goto out; | ||
| 403 | |||
| 384 | while (!list_empty(&group->active_list)) { | 404 | while (!list_empty(&group->active_list)) { |
| 385 | member = list_entry(group->active_list.next, | 405 | member = list_entry(group->active_list.next, |
| 386 | struct mcast_member, list); | 406 | struct mcast_member, list); |
| @@ -399,6 +419,7 @@ static void process_group_error(struct mcast_group *group) | |||
| 399 | } | 419 | } |
| 400 | 420 | ||
| 401 | group->rec.join_state = 0; | 421 | group->rec.join_state = 0; |
| 422 | out: | ||
| 402 | group->state = MCAST_BUSY; | 423 | group->state = MCAST_BUSY; |
| 403 | spin_unlock_irq(&group->lock); | 424 | spin_unlock_irq(&group->lock); |
| 404 | } | 425 | } |
| @@ -415,9 +436,9 @@ static void mcast_work_handler(struct work_struct *work) | |||
| 415 | retest: | 436 | retest: |
| 416 | spin_lock_irq(&group->lock); | 437 | spin_lock_irq(&group->lock); |
| 417 | while (!list_empty(&group->pending_list) || | 438 | while (!list_empty(&group->pending_list) || |
| 418 | (group->state == MCAST_ERROR)) { | 439 | (group->state != MCAST_BUSY)) { |
| 419 | 440 | ||
| 420 | if (group->state == MCAST_ERROR) { | 441 | if (group->state != MCAST_BUSY) { |
| 421 | spin_unlock_irq(&group->lock); | 442 | spin_unlock_irq(&group->lock); |
| 422 | process_group_error(group); | 443 | process_group_error(group); |
| 423 | goto retest; | 444 | goto retest; |
| @@ -494,12 +515,19 @@ static void join_handler(int status, struct ib_sa_mcmember_rec *rec, | |||
| 494 | void *context) | 515 | void *context) |
| 495 | { | 516 | { |
| 496 | struct mcast_group *group = context; | 517 | struct mcast_group *group = context; |
| 518 | u16 pkey_index = MCAST_INVALID_PKEY_INDEX; | ||
| 497 | 519 | ||
| 498 | if (status) | 520 | if (status) |
| 499 | process_join_error(group, status); | 521 | process_join_error(group, status); |
| 500 | else { | 522 | else { |
| 523 | ib_find_pkey(group->port->dev->device, group->port->port_num, | ||
| 524 | be16_to_cpu(rec->pkey), &pkey_index); | ||
| 525 | |||
| 501 | spin_lock_irq(&group->port->lock); | 526 | spin_lock_irq(&group->port->lock); |
| 502 | group->rec = *rec; | 527 | group->rec = *rec; |
| 528 | if (group->state == MCAST_BUSY && | ||
| 529 | group->pkey_index == MCAST_INVALID_PKEY_INDEX) | ||
| 530 | group->pkey_index = pkey_index; | ||
| 503 | if (!memcmp(&mgid0, &group->rec.mgid, sizeof mgid0)) { | 531 | if (!memcmp(&mgid0, &group->rec.mgid, sizeof mgid0)) { |
| 504 | rb_erase(&group->node, &group->port->table); | 532 | rb_erase(&group->node, &group->port->table); |
| 505 | mcast_insert(group->port, group, 1); | 533 | mcast_insert(group->port, group, 1); |
| @@ -539,6 +567,7 @@ static struct mcast_group *acquire_group(struct mcast_port *port, | |||
| 539 | 567 | ||
| 540 | group->port = port; | 568 | group->port = port; |
| 541 | group->rec.mgid = *mgid; | 569 | group->rec.mgid = *mgid; |
| 570 | group->pkey_index = MCAST_INVALID_PKEY_INDEX; | ||
| 542 | INIT_LIST_HEAD(&group->pending_list); | 571 | INIT_LIST_HEAD(&group->pending_list); |
| 543 | INIT_LIST_HEAD(&group->active_list); | 572 | INIT_LIST_HEAD(&group->active_list); |
| 544 | INIT_WORK(&group->work, mcast_work_handler); | 573 | INIT_WORK(&group->work, mcast_work_handler); |
| @@ -707,7 +736,8 @@ int ib_init_ah_from_mcmember(struct ib_device *device, u8 port_num, | |||
| 707 | } | 736 | } |
| 708 | EXPORT_SYMBOL(ib_init_ah_from_mcmember); | 737 | EXPORT_SYMBOL(ib_init_ah_from_mcmember); |
| 709 | 738 | ||
| 710 | static void mcast_groups_lost(struct mcast_port *port) | 739 | static void mcast_groups_event(struct mcast_port *port, |
| 740 | enum mcast_group_state state) | ||
| 711 | { | 741 | { |
| 712 | struct mcast_group *group; | 742 | struct mcast_group *group; |
| 713 | struct rb_node *node; | 743 | struct rb_node *node; |
| @@ -721,7 +751,8 @@ static void mcast_groups_lost(struct mcast_port *port) | |||
| 721 | atomic_inc(&group->refcount); | 751 | atomic_inc(&group->refcount); |
| 722 | queue_work(mcast_wq, &group->work); | 752 | queue_work(mcast_wq, &group->work); |
| 723 | } | 753 | } |
| 724 | group->state = MCAST_ERROR; | 754 | if (group->state != MCAST_GROUP_ERROR) |
| 755 | group->state = state; | ||
| 725 | spin_unlock(&group->lock); | 756 | spin_unlock(&group->lock); |
| 726 | } | 757 | } |
| 727 | spin_unlock_irqrestore(&port->lock, flags); | 758 | spin_unlock_irqrestore(&port->lock, flags); |
| @@ -731,16 +762,20 @@ static void mcast_event_handler(struct ib_event_handler *handler, | |||
| 731 | struct ib_event *event) | 762 | struct ib_event *event) |
| 732 | { | 763 | { |
| 733 | struct mcast_device *dev; | 764 | struct mcast_device *dev; |
| 765 | int index; | ||
| 734 | 766 | ||
| 735 | dev = container_of(handler, struct mcast_device, event_handler); | 767 | dev = container_of(handler, struct mcast_device, event_handler); |
| 768 | index = event->element.port_num - dev->start_port; | ||
| 736 | 769 | ||
| 737 | switch (event->event) { | 770 | switch (event->event) { |
| 738 | case IB_EVENT_PORT_ERR: | 771 | case IB_EVENT_PORT_ERR: |
| 739 | case IB_EVENT_LID_CHANGE: | 772 | case IB_EVENT_LID_CHANGE: |
| 740 | case IB_EVENT_SM_CHANGE: | 773 | case IB_EVENT_SM_CHANGE: |
| 741 | case IB_EVENT_CLIENT_REREGISTER: | 774 | case IB_EVENT_CLIENT_REREGISTER: |
| 742 | mcast_groups_lost(&dev->port[event->element.port_num - | 775 | mcast_groups_event(&dev->port[index], MCAST_GROUP_ERROR); |
| 743 | dev->start_port]); | 776 | break; |
| 777 | case IB_EVENT_PKEY_CHANGE: | ||
| 778 | mcast_groups_event(&dev->port[index], MCAST_PKEY_EVENT); | ||
| 744 | break; | 779 | break; |
| 745 | default: | 780 | default: |
| 746 | break; | 781 | break; |
diff --git a/drivers/infiniband/core/smi.h b/drivers/infiniband/core/smi.h index 1cfc2984434f..aff96bac49b4 100644 --- a/drivers/infiniband/core/smi.h +++ b/drivers/infiniband/core/smi.h | |||
| @@ -59,7 +59,8 @@ extern enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp, | |||
| 59 | u8 node_type, int port_num); | 59 | u8 node_type, int port_num); |
| 60 | 60 | ||
| 61 | /* | 61 | /* |
| 62 | * Return 1 if the SMP should be handled by the local SMA/SM via process_mad | 62 | * Return IB_SMI_HANDLE if the SMP should be handled by the local SMA/SM |
| 63 | * via process_mad | ||
| 63 | */ | 64 | */ |
| 64 | static inline enum smi_action smi_check_local_smp(struct ib_smp *smp, | 65 | static inline enum smi_action smi_check_local_smp(struct ib_smp *smp, |
| 65 | struct ib_device *device) | 66 | struct ib_device *device) |
| @@ -71,4 +72,19 @@ static inline enum smi_action smi_check_local_smp(struct ib_smp *smp, | |||
| 71 | (smp->hop_ptr == smp->hop_cnt + 1)) ? | 72 | (smp->hop_ptr == smp->hop_cnt + 1)) ? |
| 72 | IB_SMI_HANDLE : IB_SMI_DISCARD); | 73 | IB_SMI_HANDLE : IB_SMI_DISCARD); |
| 73 | } | 74 | } |
| 75 | |||
| 76 | /* | ||
| 77 | * Return IB_SMI_HANDLE if the SMP should be handled by the local SMA/SM | ||
| 78 | * via process_mad | ||
| 79 | */ | ||
| 80 | static inline enum smi_action smi_check_local_returning_smp(struct ib_smp *smp, | ||
| 81 | struct ib_device *device) | ||
| 82 | { | ||
| 83 | /* C14-13:3 -- We're at the end of the DR segment of path */ | ||
| 84 | /* C14-13:4 -- Hop Pointer == 0 -> give to SM */ | ||
| 85 | return ((device->process_mad && | ||
| 86 | ib_get_smp_direction(smp) && | ||
| 87 | !smp->hop_ptr) ? IB_SMI_HANDLE : IB_SMI_DISCARD); | ||
| 88 | } | ||
| 89 | |||
| 74 | #endif /* __SMI_H_ */ | 90 | #endif /* __SMI_H_ */ |
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index 424983f5b1ee..4291ab42a5b9 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c | |||
| @@ -106,6 +106,9 @@ enum { | |||
| 106 | IB_UCM_MAX_DEVICES = 32 | 106 | IB_UCM_MAX_DEVICES = 32 |
| 107 | }; | 107 | }; |
| 108 | 108 | ||
| 109 | /* ib_cm and ib_user_cm modules share /sys/class/infiniband_cm */ | ||
| 110 | extern struct class cm_class; | ||
| 111 | |||
| 109 | #define IB_UCM_BASE_DEV MKDEV(IB_UCM_MAJOR, IB_UCM_BASE_MINOR) | 112 | #define IB_UCM_BASE_DEV MKDEV(IB_UCM_MAJOR, IB_UCM_BASE_MINOR) |
| 110 | 113 | ||
| 111 | static void ib_ucm_add_one(struct ib_device *device); | 114 | static void ib_ucm_add_one(struct ib_device *device); |
| @@ -1199,7 +1202,7 @@ static int ib_ucm_close(struct inode *inode, struct file *filp) | |||
| 1199 | return 0; | 1202 | return 0; |
| 1200 | } | 1203 | } |
| 1201 | 1204 | ||
| 1202 | static void ib_ucm_release_class_dev(struct class_device *class_dev) | 1205 | static void ucm_release_class_dev(struct class_device *class_dev) |
| 1203 | { | 1206 | { |
| 1204 | struct ib_ucm_device *dev; | 1207 | struct ib_ucm_device *dev; |
| 1205 | 1208 | ||
| @@ -1217,11 +1220,6 @@ static const struct file_operations ucm_fops = { | |||
| 1217 | .poll = ib_ucm_poll, | 1220 | .poll = ib_ucm_poll, |
| 1218 | }; | 1221 | }; |
| 1219 | 1222 | ||
| 1220 | static struct class ucm_class = { | ||
| 1221 | .name = "infiniband_cm", | ||
| 1222 | .release = ib_ucm_release_class_dev | ||
| 1223 | }; | ||
| 1224 | |||
| 1225 | static ssize_t show_ibdev(struct class_device *class_dev, char *buf) | 1223 | static ssize_t show_ibdev(struct class_device *class_dev, char *buf) |
| 1226 | { | 1224 | { |
| 1227 | struct ib_ucm_device *dev; | 1225 | struct ib_ucm_device *dev; |
| @@ -1257,9 +1255,10 @@ static void ib_ucm_add_one(struct ib_device *device) | |||
| 1257 | if (cdev_add(&ucm_dev->dev, IB_UCM_BASE_DEV + ucm_dev->devnum, 1)) | 1255 | if (cdev_add(&ucm_dev->dev, IB_UCM_BASE_DEV + ucm_dev->devnum, 1)) |
| 1258 | goto err; | 1256 | goto err; |
| 1259 | 1257 | ||
| 1260 | ucm_dev->class_dev.class = &ucm_class; | 1258 | ucm_dev->class_dev.class = &cm_class; |
| 1261 | ucm_dev->class_dev.dev = device->dma_device; | 1259 | ucm_dev->class_dev.dev = device->dma_device; |
| 1262 | ucm_dev->class_dev.devt = ucm_dev->dev.dev; | 1260 | ucm_dev->class_dev.devt = ucm_dev->dev.dev; |
| 1261 | ucm_dev->class_dev.release = ucm_release_class_dev; | ||
| 1263 | snprintf(ucm_dev->class_dev.class_id, BUS_ID_SIZE, "ucm%d", | 1262 | snprintf(ucm_dev->class_dev.class_id, BUS_ID_SIZE, "ucm%d", |
| 1264 | ucm_dev->devnum); | 1263 | ucm_dev->devnum); |
| 1265 | if (class_device_register(&ucm_dev->class_dev)) | 1264 | if (class_device_register(&ucm_dev->class_dev)) |
| @@ -1306,40 +1305,34 @@ static int __init ib_ucm_init(void) | |||
| 1306 | "infiniband_cm"); | 1305 | "infiniband_cm"); |
| 1307 | if (ret) { | 1306 | if (ret) { |
| 1308 | printk(KERN_ERR "ucm: couldn't register device number\n"); | 1307 | printk(KERN_ERR "ucm: couldn't register device number\n"); |
| 1309 | goto err; | 1308 | goto error1; |
| 1310 | } | 1309 | } |
| 1311 | 1310 | ||
| 1312 | ret = class_register(&ucm_class); | 1311 | ret = class_create_file(&cm_class, &class_attr_abi_version); |
| 1313 | if (ret) { | ||
| 1314 | printk(KERN_ERR "ucm: couldn't create class infiniband_cm\n"); | ||
| 1315 | goto err_chrdev; | ||
| 1316 | } | ||
| 1317 | |||
| 1318 | ret = class_create_file(&ucm_class, &class_attr_abi_version); | ||
| 1319 | if (ret) { | 1312 | if (ret) { |
| 1320 | printk(KERN_ERR "ucm: couldn't create abi_version attribute\n"); | 1313 | printk(KERN_ERR "ucm: couldn't create abi_version attribute\n"); |
| 1321 | goto err_class; | 1314 | goto error2; |
| 1322 | } | 1315 | } |
| 1323 | 1316 | ||
| 1324 | ret = ib_register_client(&ucm_client); | 1317 | ret = ib_register_client(&ucm_client); |
| 1325 | if (ret) { | 1318 | if (ret) { |
| 1326 | printk(KERN_ERR "ucm: couldn't register client\n"); | 1319 | printk(KERN_ERR "ucm: couldn't register client\n"); |
| 1327 | goto err_class; | 1320 | goto error3; |
| 1328 | } | 1321 | } |
| 1329 | return 0; | 1322 | return 0; |
| 1330 | 1323 | ||
| 1331 | err_class: | 1324 | error3: |
| 1332 | class_unregister(&ucm_class); | 1325 | class_remove_file(&cm_class, &class_attr_abi_version); |
| 1333 | err_chrdev: | 1326 | error2: |
| 1334 | unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES); | 1327 | unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES); |
| 1335 | err: | 1328 | error1: |
| 1336 | return ret; | 1329 | return ret; |
| 1337 | } | 1330 | } |
| 1338 | 1331 | ||
| 1339 | static void __exit ib_ucm_cleanup(void) | 1332 | static void __exit ib_ucm_cleanup(void) |
| 1340 | { | 1333 | { |
| 1341 | ib_unregister_client(&ucm_client); | 1334 | ib_unregister_client(&ucm_client); |
| 1342 | class_unregister(&ucm_class); | 1335 | class_remove_file(&cm_class, &class_attr_abi_version); |
| 1343 | unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES); | 1336 | unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES); |
| 1344 | idr_destroy(&ctx_id_table); | 1337 | idr_destroy(&ctx_id_table); |
| 1345 | } | 1338 | } |
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 90d675ad9ec8..15937eb38aae 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | */ | 31 | */ |
| 32 | 32 | ||
| 33 | #include <linux/completion.h> | 33 | #include <linux/completion.h> |
| 34 | #include <linux/file.h> | ||
| 34 | #include <linux/mutex.h> | 35 | #include <linux/mutex.h> |
| 35 | #include <linux/poll.h> | 36 | #include <linux/poll.h> |
| 36 | #include <linux/idr.h> | 37 | #include <linux/idr.h> |
| @@ -991,6 +992,96 @@ out: | |||
| 991 | return ret; | 992 | return ret; |
| 992 | } | 993 | } |
| 993 | 994 | ||
| 995 | static void ucma_lock_files(struct ucma_file *file1, struct ucma_file *file2) | ||
| 996 | { | ||
| 997 | /* Acquire mutex's based on pointer comparison to prevent deadlock. */ | ||
| 998 | if (file1 < file2) { | ||
| 999 | mutex_lock(&file1->mut); | ||
| 1000 | mutex_lock(&file2->mut); | ||
| 1001 | } else { | ||
| 1002 | mutex_lock(&file2->mut); | ||
| 1003 | mutex_lock(&file1->mut); | ||
| 1004 | } | ||
| 1005 | } | ||
| 1006 | |||
| 1007 | static void ucma_unlock_files(struct ucma_file *file1, struct ucma_file *file2) | ||
| 1008 | { | ||
| 1009 | if (file1 < file2) { | ||
| 1010 | mutex_unlock(&file2->mut); | ||
| 1011 | mutex_unlock(&file1->mut); | ||
| 1012 | } else { | ||
| 1013 | mutex_unlock(&file1->mut); | ||
| 1014 | mutex_unlock(&file2->mut); | ||
| 1015 | } | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | static void ucma_move_events(struct ucma_context *ctx, struct ucma_file *file) | ||
| 1019 | { | ||
| 1020 | struct ucma_event *uevent, *tmp; | ||
| 1021 | |||
| 1022 | list_for_each_entry_safe(uevent, tmp, &ctx->file->event_list, list) | ||
| 1023 | if (uevent->ctx == ctx) | ||
| 1024 | list_move_tail(&uevent->list, &file->event_list); | ||
| 1025 | } | ||
| 1026 | |||
| 1027 | static ssize_t ucma_migrate_id(struct ucma_file *new_file, | ||
| 1028 | const char __user *inbuf, | ||
| 1029 | int in_len, int out_len) | ||
| 1030 | { | ||
| 1031 | struct rdma_ucm_migrate_id cmd; | ||
| 1032 | struct rdma_ucm_migrate_resp resp; | ||
| 1033 | struct ucma_context *ctx; | ||
| 1034 | struct file *filp; | ||
| 1035 | struct ucma_file *cur_file; | ||
| 1036 | int ret = 0; | ||
| 1037 | |||
| 1038 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | ||
| 1039 | return -EFAULT; | ||
| 1040 | |||
| 1041 | /* Get current fd to protect against it being closed */ | ||
| 1042 | filp = fget(cmd.fd); | ||
| 1043 | if (!filp) | ||
| 1044 | return -ENOENT; | ||
| 1045 | |||
| 1046 | /* Validate current fd and prevent destruction of id. */ | ||
| 1047 | ctx = ucma_get_ctx(filp->private_data, cmd.id); | ||
| 1048 | if (IS_ERR(ctx)) { | ||
| 1049 | ret = PTR_ERR(ctx); | ||
| 1050 | goto file_put; | ||
| 1051 | } | ||
| 1052 | |||
| 1053 | cur_file = ctx->file; | ||
| 1054 | if (cur_file == new_file) { | ||
| 1055 | resp.events_reported = ctx->events_reported; | ||
| 1056 | goto response; | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | /* | ||
| 1060 | * Migrate events between fd's, maintaining order, and avoiding new | ||
| 1061 | * events being added before existing events. | ||
| 1062 | */ | ||
| 1063 | ucma_lock_files(cur_file, new_file); | ||
| 1064 | mutex_lock(&mut); | ||
| 1065 | |||
| 1066 | list_move_tail(&ctx->list, &new_file->ctx_list); | ||
| 1067 | ucma_move_events(ctx, new_file); | ||
| 1068 | ctx->file = new_file; | ||
| 1069 | resp.events_reported = ctx->events_reported; | ||
| 1070 | |||
| 1071 | mutex_unlock(&mut); | ||
| 1072 | ucma_unlock_files(cur_file, new_file); | ||
| 1073 | |||
| 1074 | response: | ||
| 1075 | if (copy_to_user((void __user *)(unsigned long)cmd.response, | ||
| 1076 | &resp, sizeof(resp))) | ||
| 1077 | ret = -EFAULT; | ||
| 1078 | |||
| 1079 | ucma_put_ctx(ctx); | ||
| 1080 | file_put: | ||
| 1081 | fput(filp); | ||
| 1082 | return ret; | ||
| 1083 | } | ||
| 1084 | |||
| 994 | static ssize_t (*ucma_cmd_table[])(struct ucma_file *file, | 1085 | static ssize_t (*ucma_cmd_table[])(struct ucma_file *file, |
| 995 | const char __user *inbuf, | 1086 | const char __user *inbuf, |
| 996 | int in_len, int out_len) = { | 1087 | int in_len, int out_len) = { |
| @@ -1012,6 +1103,7 @@ static ssize_t (*ucma_cmd_table[])(struct ucma_file *file, | |||
| 1012 | [RDMA_USER_CM_CMD_NOTIFY] = ucma_notify, | 1103 | [RDMA_USER_CM_CMD_NOTIFY] = ucma_notify, |
| 1013 | [RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast, | 1104 | [RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast, |
| 1014 | [RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast, | 1105 | [RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast, |
| 1106 | [RDMA_USER_CM_CMD_MIGRATE_ID] = ucma_migrate_id | ||
| 1015 | }; | 1107 | }; |
| 1016 | 1108 | ||
| 1017 | static ssize_t ucma_write(struct file *filp, const char __user *buf, | 1109 | static ssize_t ucma_write(struct file *filp, const char __user *buf, |
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index b53eac4611de..4e915104ac4c 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | * Copyright (c) 2004 Topspin Communications. All rights reserved. | 2 | * Copyright (c) 2004 Topspin Communications. All rights reserved. |
| 3 | * Copyright (c) 2005 Voltaire, Inc. All rights reserved. | 3 | * Copyright (c) 2005 Voltaire, Inc. All rights reserved. |
| 4 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. | 4 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. |
| 5 | * Copyright (c) 2008 Cisco. All rights reserved. | ||
| 5 | * | 6 | * |
| 6 | * This software is available to you under a choice of one of two | 7 | * This software is available to you under a choice of one of two |
| 7 | * licenses. You may choose to be licensed under the terms of the GNU | 8 | * licenses. You may choose to be licensed under the terms of the GNU |
| @@ -42,7 +43,7 @@ | |||
| 42 | #include <linux/cdev.h> | 43 | #include <linux/cdev.h> |
| 43 | #include <linux/dma-mapping.h> | 44 | #include <linux/dma-mapping.h> |
| 44 | #include <linux/poll.h> | 45 | #include <linux/poll.h> |
| 45 | #include <linux/rwsem.h> | 46 | #include <linux/mutex.h> |
| 46 | #include <linux/kref.h> | 47 | #include <linux/kref.h> |
| 47 | #include <linux/compat.h> | 48 | #include <linux/compat.h> |
| 48 | 49 | ||
| @@ -94,7 +95,7 @@ struct ib_umad_port { | |||
| 94 | struct class_device *sm_class_dev; | 95 | struct class_device *sm_class_dev; |
| 95 | struct semaphore sm_sem; | 96 | struct semaphore sm_sem; |
| 96 | 97 | ||
| 97 | struct rw_semaphore mutex; | 98 | struct mutex file_mutex; |
| 98 | struct list_head file_list; | 99 | struct list_head file_list; |
| 99 | 100 | ||
| 100 | struct ib_device *ib_dev; | 101 | struct ib_device *ib_dev; |
| @@ -110,11 +111,11 @@ struct ib_umad_device { | |||
| 110 | }; | 111 | }; |
| 111 | 112 | ||
| 112 | struct ib_umad_file { | 113 | struct ib_umad_file { |
| 114 | struct mutex mutex; | ||
| 113 | struct ib_umad_port *port; | 115 | struct ib_umad_port *port; |
| 114 | struct list_head recv_list; | 116 | struct list_head recv_list; |
| 115 | struct list_head send_list; | 117 | struct list_head send_list; |
| 116 | struct list_head port_list; | 118 | struct list_head port_list; |
| 117 | spinlock_t recv_lock; | ||
| 118 | spinlock_t send_lock; | 119 | spinlock_t send_lock; |
| 119 | wait_queue_head_t recv_wait; | 120 | wait_queue_head_t recv_wait; |
| 120 | struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS]; | 121 | struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS]; |
| @@ -156,7 +157,7 @@ static int hdr_size(struct ib_umad_file *file) | |||
| 156 | sizeof (struct ib_user_mad_hdr_old); | 157 | sizeof (struct ib_user_mad_hdr_old); |
| 157 | } | 158 | } |
| 158 | 159 | ||
| 159 | /* caller must hold port->mutex at least for reading */ | 160 | /* caller must hold file->mutex */ |
| 160 | static struct ib_mad_agent *__get_agent(struct ib_umad_file *file, int id) | 161 | static struct ib_mad_agent *__get_agent(struct ib_umad_file *file, int id) |
| 161 | { | 162 | { |
| 162 | return file->agents_dead ? NULL : file->agent[id]; | 163 | return file->agents_dead ? NULL : file->agent[id]; |
| @@ -168,32 +169,30 @@ static int queue_packet(struct ib_umad_file *file, | |||
| 168 | { | 169 | { |
| 169 | int ret = 1; | 170 | int ret = 1; |
| 170 | 171 | ||
| 171 | down_read(&file->port->mutex); | 172 | mutex_lock(&file->mutex); |
| 172 | 173 | ||
| 173 | for (packet->mad.hdr.id = 0; | 174 | for (packet->mad.hdr.id = 0; |
| 174 | packet->mad.hdr.id < IB_UMAD_MAX_AGENTS; | 175 | packet->mad.hdr.id < IB_UMAD_MAX_AGENTS; |
| 175 | packet->mad.hdr.id++) | 176 | packet->mad.hdr.id++) |
| 176 | if (agent == __get_agent(file, packet->mad.hdr.id)) { | 177 | if (agent == __get_agent(file, packet->mad.hdr.id)) { |
| 177 | spin_lock_irq(&file->recv_lock); | ||
| 178 | list_add_tail(&packet->list, &file->recv_list); | 178 | list_add_tail(&packet->list, &file->recv_list); |
| 179 | spin_unlock_irq(&file->recv_lock); | ||
| 180 | wake_up_interruptible(&file->recv_wait); | 179 | wake_up_interruptible(&file->recv_wait); |
| 181 | ret = 0; | 180 | ret = 0; |
| 182 | break; | 181 | break; |
| 183 | } | 182 | } |
| 184 | 183 | ||
| 185 | up_read(&file->port->mutex); | 184 | mutex_unlock(&file->mutex); |
| 186 | 185 | ||
| 187 | return ret; | 186 | return ret; |
| 188 | } | 187 | } |
| 189 | 188 | ||
| 190 | static void dequeue_send(struct ib_umad_file *file, | 189 | static void dequeue_send(struct ib_umad_file *file, |
| 191 | struct ib_umad_packet *packet) | 190 | struct ib_umad_packet *packet) |
| 192 | { | 191 | { |
| 193 | spin_lock_irq(&file->send_lock); | 192 | spin_lock_irq(&file->send_lock); |
| 194 | list_del(&packet->list); | 193 | list_del(&packet->list); |
| 195 | spin_unlock_irq(&file->send_lock); | 194 | spin_unlock_irq(&file->send_lock); |
| 196 | } | 195 | } |
| 197 | 196 | ||
| 198 | static void send_handler(struct ib_mad_agent *agent, | 197 | static void send_handler(struct ib_mad_agent *agent, |
| 199 | struct ib_mad_send_wc *send_wc) | 198 | struct ib_mad_send_wc *send_wc) |
| @@ -341,10 +340,10 @@ static ssize_t ib_umad_read(struct file *filp, char __user *buf, | |||
| 341 | if (count < hdr_size(file)) | 340 | if (count < hdr_size(file)) |
| 342 | return -EINVAL; | 341 | return -EINVAL; |
| 343 | 342 | ||
| 344 | spin_lock_irq(&file->recv_lock); | 343 | mutex_lock(&file->mutex); |
| 345 | 344 | ||
| 346 | while (list_empty(&file->recv_list)) { | 345 | while (list_empty(&file->recv_list)) { |
| 347 | spin_unlock_irq(&file->recv_lock); | 346 | mutex_unlock(&file->mutex); |
| 348 | 347 | ||
| 349 | if (filp->f_flags & O_NONBLOCK) | 348 | if (filp->f_flags & O_NONBLOCK) |
| 350 | return -EAGAIN; | 349 | return -EAGAIN; |
| @@ -353,13 +352,13 @@ static ssize_t ib_umad_read(struct file *filp, char __user *buf, | |||
| 353 | !list_empty(&file->recv_list))) | 352 | !list_empty(&file->recv_list))) |
| 354 | return -ERESTARTSYS; | 353 | return -ERESTARTSYS; |
| 355 | 354 | ||
| 356 | spin_lock_irq(&file->recv_lock); | 355 | mutex_lock(&file->mutex); |
| 357 | } | 356 | } |
| 358 | 357 | ||
| 359 | packet = list_entry(file->recv_list.next, struct ib_umad_packet, list); | 358 | packet = list_entry(file->recv_list.next, struct ib_umad_packet, list); |
| 360 | list_del(&packet->list); | 359 | list_del(&packet->list); |
| 361 | 360 | ||
| 362 | spin_unlock_irq(&file->recv_lock); | 361 | mutex_unlock(&file->mutex); |
| 363 | 362 | ||
| 364 | if (packet->recv_wc) | 363 | if (packet->recv_wc) |
| 365 | ret = copy_recv_mad(file, buf, packet, count); | 364 | ret = copy_recv_mad(file, buf, packet, count); |
| @@ -368,9 +367,9 @@ static ssize_t ib_umad_read(struct file *filp, char __user *buf, | |||
| 368 | 367 | ||
| 369 | if (ret < 0) { | 368 | if (ret < 0) { |
| 370 | /* Requeue packet */ | 369 | /* Requeue packet */ |
| 371 | spin_lock_irq(&file->recv_lock); | 370 | mutex_lock(&file->mutex); |
| 372 | list_add(&packet->list, &file->recv_list); | 371 | list_add(&packet->list, &file->recv_list); |
| 373 | spin_unlock_irq(&file->recv_lock); | 372 | mutex_unlock(&file->mutex); |
| 374 | } else { | 373 | } else { |
| 375 | if (packet->recv_wc) | 374 | if (packet->recv_wc) |
| 376 | ib_free_recv_mad(packet->recv_wc); | 375 | ib_free_recv_mad(packet->recv_wc); |
| @@ -481,7 +480,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
| 481 | goto err; | 480 | goto err; |
| 482 | } | 481 | } |
| 483 | 482 | ||
| 484 | down_read(&file->port->mutex); | 483 | mutex_lock(&file->mutex); |
| 485 | 484 | ||
| 486 | agent = __get_agent(file, packet->mad.hdr.id); | 485 | agent = __get_agent(file, packet->mad.hdr.id); |
| 487 | if (!agent) { | 486 | if (!agent) { |
| @@ -577,7 +576,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
| 577 | if (ret) | 576 | if (ret) |
| 578 | goto err_send; | 577 | goto err_send; |
| 579 | 578 | ||
| 580 | up_read(&file->port->mutex); | 579 | mutex_unlock(&file->mutex); |
| 581 | return count; | 580 | return count; |
| 582 | 581 | ||
| 583 | err_send: | 582 | err_send: |
| @@ -587,7 +586,7 @@ err_msg: | |||
| 587 | err_ah: | 586 | err_ah: |
| 588 | ib_destroy_ah(ah); | 587 | ib_destroy_ah(ah); |
| 589 | err_up: | 588 | err_up: |
| 590 | up_read(&file->port->mutex); | 589 | mutex_unlock(&file->mutex); |
| 591 | err: | 590 | err: |
| 592 | kfree(packet); | 591 | kfree(packet); |
| 593 | return ret; | 592 | return ret; |
| @@ -613,11 +612,12 @@ static int ib_umad_reg_agent(struct ib_umad_file *file, void __user *arg, | |||
| 613 | { | 612 | { |
| 614 | struct ib_user_mad_reg_req ureq; | 613 | struct ib_user_mad_reg_req ureq; |
| 615 | struct ib_mad_reg_req req; | 614 | struct ib_mad_reg_req req; |
| 616 | struct ib_mad_agent *agent; | 615 | struct ib_mad_agent *agent = NULL; |
| 617 | int agent_id; | 616 | int agent_id; |
| 618 | int ret; | 617 | int ret; |
| 619 | 618 | ||
| 620 | down_write(&file->port->mutex); | 619 | mutex_lock(&file->port->file_mutex); |
| 620 | mutex_lock(&file->mutex); | ||
| 621 | 621 | ||
| 622 | if (!file->port->ib_dev) { | 622 | if (!file->port->ib_dev) { |
| 623 | ret = -EPIPE; | 623 | ret = -EPIPE; |
| @@ -666,13 +666,13 @@ found: | |||
| 666 | send_handler, recv_handler, file); | 666 | send_handler, recv_handler, file); |
| 667 | if (IS_ERR(agent)) { | 667 | if (IS_ERR(agent)) { |
| 668 | ret = PTR_ERR(agent); | 668 | ret = PTR_ERR(agent); |
| 669 | agent = NULL; | ||
| 669 | goto out; | 670 | goto out; |
| 670 | } | 671 | } |
| 671 | 672 | ||
| 672 | if (put_user(agent_id, | 673 | if (put_user(agent_id, |
| 673 | (u32 __user *) (arg + offsetof(struct ib_user_mad_reg_req, id)))) { | 674 | (u32 __user *) (arg + offsetof(struct ib_user_mad_reg_req, id)))) { |
| 674 | ret = -EFAULT; | 675 | ret = -EFAULT; |
| 675 | ib_unregister_mad_agent(agent); | ||
| 676 | goto out; | 676 | goto out; |
| 677 | } | 677 | } |
| 678 | 678 | ||
| @@ -690,7 +690,13 @@ found: | |||
| 690 | ret = 0; | 690 | ret = 0; |
| 691 | 691 | ||
| 692 | out: | 692 | out: |
| 693 | up_write(&file->port->mutex); | 693 | mutex_unlock(&file->mutex); |
| 694 | |||
| 695 | if (ret && agent) | ||
| 696 | ib_unregister_mad_agent(agent); | ||
| 697 | |||
| 698 | mutex_unlock(&file->port->file_mutex); | ||
| 699 | |||
| 694 | return ret; | 700 | return ret; |
| 695 | } | 701 | } |
| 696 | 702 | ||
| @@ -703,7 +709,8 @@ static int ib_umad_unreg_agent(struct ib_umad_file *file, u32 __user *arg) | |||
| 703 | if (get_user(id, arg)) | 709 | if (get_user(id, arg)) |
| 704 | return -EFAULT; | 710 | return -EFAULT; |
| 705 | 711 | ||
| 706 | down_write(&file->port->mutex); | 712 | mutex_lock(&file->port->file_mutex); |
| 713 | mutex_lock(&file->mutex); | ||
| 707 | 714 | ||
| 708 | if (id < 0 || id >= IB_UMAD_MAX_AGENTS || !__get_agent(file, id)) { | 715 | if (id < 0 || id >= IB_UMAD_MAX_AGENTS || !__get_agent(file, id)) { |
| 709 | ret = -EINVAL; | 716 | ret = -EINVAL; |
| @@ -714,11 +721,13 @@ static int ib_umad_unreg_agent(struct ib_umad_file *file, u32 __user *arg) | |||
| 714 | file->agent[id] = NULL; | 721 | file->agent[id] = NULL; |
| 715 | 722 | ||
| 716 | out: | 723 | out: |
| 717 | up_write(&file->port->mutex); | 724 | mutex_unlock(&file->mutex); |
| 718 | 725 | ||
| 719 | if (agent) | 726 | if (agent) |
| 720 | ib_unregister_mad_agent(agent); | 727 | ib_unregister_mad_agent(agent); |
| 721 | 728 | ||
| 729 | mutex_unlock(&file->port->file_mutex); | ||
| 730 | |||
| 722 | return ret; | 731 | return ret; |
| 723 | } | 732 | } |
| 724 | 733 | ||
| @@ -726,12 +735,12 @@ static long ib_umad_enable_pkey(struct ib_umad_file *file) | |||
| 726 | { | 735 | { |
| 727 | int ret = 0; | 736 | int ret = 0; |
| 728 | 737 | ||
| 729 | down_write(&file->port->mutex); | 738 | mutex_lock(&file->mutex); |
| 730 | if (file->already_used) | 739 | if (file->already_used) |
| 731 | ret = -EINVAL; | 740 | ret = -EINVAL; |
| 732 | else | 741 | else |
| 733 | file->use_pkey_index = 1; | 742 | file->use_pkey_index = 1; |
| 734 | up_write(&file->port->mutex); | 743 | mutex_unlock(&file->mutex); |
| 735 | 744 | ||
| 736 | return ret; | 745 | return ret; |
| 737 | } | 746 | } |
| @@ -783,7 +792,7 @@ static int ib_umad_open(struct inode *inode, struct file *filp) | |||
| 783 | if (!port) | 792 | if (!port) |
| 784 | return -ENXIO; | 793 | return -ENXIO; |
| 785 | 794 | ||
| 786 | down_write(&port->mutex); | 795 | mutex_lock(&port->file_mutex); |
| 787 | 796 | ||
| 788 | if (!port->ib_dev) { | 797 | if (!port->ib_dev) { |
| 789 | ret = -ENXIO; | 798 | ret = -ENXIO; |
| @@ -797,7 +806,7 @@ static int ib_umad_open(struct inode *inode, struct file *filp) | |||
| 797 | goto out; | 806 | goto out; |
| 798 | } | 807 | } |
| 799 | 808 | ||
| 800 | spin_lock_init(&file->recv_lock); | 809 | mutex_init(&file->mutex); |
| 801 | spin_lock_init(&file->send_lock); | 810 | spin_lock_init(&file->send_lock); |
| 802 | INIT_LIST_HEAD(&file->recv_list); | 811 | INIT_LIST_HEAD(&file->recv_list); |
| 803 | INIT_LIST_HEAD(&file->send_list); | 812 | INIT_LIST_HEAD(&file->send_list); |
| @@ -809,7 +818,7 @@ static int ib_umad_open(struct inode *inode, struct file *filp) | |||
| 809 | list_add_tail(&file->port_list, &port->file_list); | 818 | list_add_tail(&file->port_list, &port->file_list); |
| 810 | 819 | ||
| 811 | out: | 820 | out: |
| 812 | up_write(&port->mutex); | 821 | mutex_unlock(&port->file_mutex); |
| 813 | return ret; | 822 | return ret; |
| 814 | } | 823 | } |
| 815 | 824 | ||
| @@ -821,7 +830,8 @@ static int ib_umad_close(struct inode *inode, struct file *filp) | |||
| 821 | int already_dead; | 830 | int already_dead; |
| 822 | int i; | 831 | int i; |
| 823 | 832 | ||
| 824 | down_write(&file->port->mutex); | 833 | mutex_lock(&file->port->file_mutex); |
| 834 | mutex_lock(&file->mutex); | ||
| 825 | 835 | ||
| 826 | already_dead = file->agents_dead; | 836 | already_dead = file->agents_dead; |
| 827 | file->agents_dead = 1; | 837 | file->agents_dead = 1; |
| @@ -834,14 +844,14 @@ static int ib_umad_close(struct inode *inode, struct file *filp) | |||
| 834 | 844 | ||
| 835 | list_del(&file->port_list); | 845 | list_del(&file->port_list); |
| 836 | 846 | ||
| 837 | downgrade_write(&file->port->mutex); | 847 | mutex_unlock(&file->mutex); |
| 838 | 848 | ||
| 839 | if (!already_dead) | 849 | if (!already_dead) |
| 840 | for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i) | 850 | for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i) |
| 841 | if (file->agent[i]) | 851 | if (file->agent[i]) |
| 842 | ib_unregister_mad_agent(file->agent[i]); | 852 | ib_unregister_mad_agent(file->agent[i]); |
| 843 | 853 | ||
| 844 | up_read(&file->port->mutex); | 854 | mutex_unlock(&file->port->file_mutex); |
| 845 | 855 | ||
| 846 | kfree(file); | 856 | kfree(file); |
| 847 | kref_put(&dev->ref, ib_umad_release_dev); | 857 | kref_put(&dev->ref, ib_umad_release_dev); |
| @@ -914,10 +924,10 @@ static int ib_umad_sm_close(struct inode *inode, struct file *filp) | |||
| 914 | }; | 924 | }; |
| 915 | int ret = 0; | 925 | int ret = 0; |
| 916 | 926 | ||
| 917 | down_write(&port->mutex); | 927 | mutex_lock(&port->file_mutex); |
| 918 | if (port->ib_dev) | 928 | if (port->ib_dev) |
| 919 | ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props); | 929 | ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props); |
| 920 | up_write(&port->mutex); | 930 | mutex_unlock(&port->file_mutex); |
| 921 | 931 | ||
| 922 | up(&port->sm_sem); | 932 | up(&port->sm_sem); |
| 923 | 933 | ||
| @@ -981,7 +991,7 @@ static int ib_umad_init_port(struct ib_device *device, int port_num, | |||
| 981 | port->ib_dev = device; | 991 | port->ib_dev = device; |
| 982 | port->port_num = port_num; | 992 | port->port_num = port_num; |
| 983 | init_MUTEX(&port->sm_sem); | 993 | init_MUTEX(&port->sm_sem); |
| 984 | init_rwsem(&port->mutex); | 994 | mutex_init(&port->file_mutex); |
| 985 | INIT_LIST_HEAD(&port->file_list); | 995 | INIT_LIST_HEAD(&port->file_list); |
| 986 | 996 | ||
| 987 | port->dev = cdev_alloc(); | 997 | port->dev = cdev_alloc(); |
| @@ -1052,6 +1062,7 @@ err_cdev: | |||
| 1052 | static void ib_umad_kill_port(struct ib_umad_port *port) | 1062 | static void ib_umad_kill_port(struct ib_umad_port *port) |
| 1053 | { | 1063 | { |
| 1054 | struct ib_umad_file *file; | 1064 | struct ib_umad_file *file; |
| 1065 | int already_dead; | ||
| 1055 | int id; | 1066 | int id; |
| 1056 | 1067 | ||
| 1057 | class_set_devdata(port->class_dev, NULL); | 1068 | class_set_devdata(port->class_dev, NULL); |
| @@ -1067,42 +1078,22 @@ static void ib_umad_kill_port(struct ib_umad_port *port) | |||
| 1067 | umad_port[port->dev_num] = NULL; | 1078 | umad_port[port->dev_num] = NULL; |
| 1068 | spin_unlock(&port_lock); | 1079 | spin_unlock(&port_lock); |
| 1069 | 1080 | ||
| 1070 | down_write(&port->mutex); | 1081 | mutex_lock(&port->file_mutex); |
| 1071 | 1082 | ||
| 1072 | port->ib_dev = NULL; | 1083 | port->ib_dev = NULL; |
| 1073 | 1084 | ||
| 1074 | /* | 1085 | list_for_each_entry(file, &port->file_list, port_list) { |
| 1075 | * Now go through the list of files attached to this port and | 1086 | mutex_lock(&file->mutex); |
| 1076 | * unregister all of their MAD agents. We need to hold | 1087 | already_dead = file->agents_dead; |
| 1077 | * port->mutex while doing this to avoid racing with | ||
| 1078 | * ib_umad_close(), but we can't hold the mutex for writing | ||
| 1079 | * while calling ib_unregister_mad_agent(), since that might | ||
| 1080 | * deadlock by calling back into queue_packet(). So we | ||
| 1081 | * downgrade our lock to a read lock, and then drop and | ||
| 1082 | * reacquire the write lock for the next iteration. | ||
| 1083 | * | ||
| 1084 | * We do list_del_init() on the file's list_head so that the | ||
| 1085 | * list_del in ib_umad_close() is still OK, even after the | ||
| 1086 | * file is removed from the list. | ||
| 1087 | */ | ||
| 1088 | while (!list_empty(&port->file_list)) { | ||
| 1089 | file = list_entry(port->file_list.next, struct ib_umad_file, | ||
| 1090 | port_list); | ||
| 1091 | |||
| 1092 | file->agents_dead = 1; | 1088 | file->agents_dead = 1; |
| 1093 | list_del_init(&file->port_list); | 1089 | mutex_unlock(&file->mutex); |
| 1094 | |||
| 1095 | downgrade_write(&port->mutex); | ||
| 1096 | 1090 | ||
| 1097 | for (id = 0; id < IB_UMAD_MAX_AGENTS; ++id) | 1091 | for (id = 0; id < IB_UMAD_MAX_AGENTS; ++id) |
| 1098 | if (file->agent[id]) | 1092 | if (file->agent[id]) |
| 1099 | ib_unregister_mad_agent(file->agent[id]); | 1093 | ib_unregister_mad_agent(file->agent[id]); |
| 1100 | |||
| 1101 | up_read(&port->mutex); | ||
| 1102 | down_write(&port->mutex); | ||
| 1103 | } | 1094 | } |
| 1104 | 1095 | ||
| 1105 | up_write(&port->mutex); | 1096 | mutex_unlock(&port->file_mutex); |
| 1106 | 1097 | ||
| 1107 | clear_bit(port->dev_num, dev_map); | 1098 | clear_bit(port->dev_num, dev_map); |
| 1108 | } | 1099 | } |
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c index eec6a30840ca..03c5ff62889a 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.c +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c | |||
| @@ -179,7 +179,7 @@ int cxio_create_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq) | |||
| 179 | setup.size = 1UL << cq->size_log2; | 179 | setup.size = 1UL << cq->size_log2; |
| 180 | setup.credits = 65535; | 180 | setup.credits = 65535; |
| 181 | setup.credit_thres = 1; | 181 | setup.credit_thres = 1; |
| 182 | if (rdev_p->t3cdev_p->type == T3B) | 182 | if (rdev_p->t3cdev_p->type != T3A) |
| 183 | setup.ovfl_mode = 0; | 183 | setup.ovfl_mode = 0; |
| 184 | else | 184 | else |
| 185 | setup.ovfl_mode = 1; | 185 | setup.ovfl_mode = 1; |
| @@ -584,7 +584,7 @@ static int cxio_hal_ctrl_qp_write_mem(struct cxio_rdev *rdev_p, u32 addr, | |||
| 584 | { | 584 | { |
| 585 | u32 i, nr_wqe, copy_len; | 585 | u32 i, nr_wqe, copy_len; |
| 586 | u8 *copy_data; | 586 | u8 *copy_data; |
| 587 | u8 wr_len, utx_len; /* lenght in 8 byte flit */ | 587 | u8 wr_len, utx_len; /* length in 8 byte flit */ |
| 588 | enum t3_wr_flags flag; | 588 | enum t3_wr_flags flag; |
| 589 | __be64 *wqe; | 589 | __be64 *wqe; |
| 590 | u64 utx_cmd; | 590 | u64 utx_cmd; |
diff --git a/drivers/infiniband/hw/cxgb3/cxio_wr.h b/drivers/infiniband/hw/cxgb3/cxio_wr.h index c84d4ac49355..969d4d928455 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_wr.h +++ b/drivers/infiniband/hw/cxgb3/cxio_wr.h | |||
| @@ -315,7 +315,7 @@ struct t3_rdma_init_wr { | |||
| 315 | __be32 ird; | 315 | __be32 ird; |
| 316 | __be64 qp_dma_addr; /* 7 */ | 316 | __be64 qp_dma_addr; /* 7 */ |
| 317 | __be32 qp_dma_size; /* 8 */ | 317 | __be32 qp_dma_size; /* 8 */ |
| 318 | u32 irs; | 318 | __be32 irs; |
| 319 | }; | 319 | }; |
| 320 | 320 | ||
| 321 | struct t3_genbit { | 321 | struct t3_genbit { |
| @@ -324,7 +324,8 @@ struct t3_genbit { | |||
| 324 | }; | 324 | }; |
| 325 | 325 | ||
| 326 | enum rdma_init_wr_flags { | 326 | enum rdma_init_wr_flags { |
| 327 | RECVS_POSTED = 1, | 327 | RECVS_POSTED = (1<<0), |
| 328 | PRIV_QP = (1<<1), | ||
| 328 | }; | 329 | }; |
| 329 | 330 | ||
| 330 | union t3_wr { | 331 | union t3_wr { |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index 20ba372dd182..f8cb0fe748c3 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c | |||
| @@ -1118,7 +1118,7 @@ static int act_open_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
| 1118 | status2errno(rpl->status)); | 1118 | status2errno(rpl->status)); |
| 1119 | connect_reply_upcall(ep, status2errno(rpl->status)); | 1119 | connect_reply_upcall(ep, status2errno(rpl->status)); |
| 1120 | state_set(&ep->com, DEAD); | 1120 | state_set(&ep->com, DEAD); |
| 1121 | if (ep->com.tdev->type == T3B && act_open_has_tid(rpl->status)) | 1121 | if (ep->com.tdev->type != T3A && act_open_has_tid(rpl->status)) |
| 1122 | release_tid(ep->com.tdev, GET_TID(rpl), NULL); | 1122 | release_tid(ep->com.tdev, GET_TID(rpl), NULL); |
| 1123 | cxgb3_free_atid(ep->com.tdev, ep->atid); | 1123 | cxgb3_free_atid(ep->com.tdev, ep->atid); |
| 1124 | dst_release(ep->dst); | 1124 | dst_release(ep->dst); |
| @@ -1249,7 +1249,7 @@ static void reject_cr(struct t3cdev *tdev, u32 hwtid, __be32 peer_ip, | |||
| 1249 | skb_trim(skb, sizeof(struct cpl_tid_release)); | 1249 | skb_trim(skb, sizeof(struct cpl_tid_release)); |
| 1250 | skb_get(skb); | 1250 | skb_get(skb); |
| 1251 | 1251 | ||
| 1252 | if (tdev->type == T3B) | 1252 | if (tdev->type != T3A) |
| 1253 | release_tid(tdev, hwtid, skb); | 1253 | release_tid(tdev, hwtid, skb); |
| 1254 | else { | 1254 | else { |
| 1255 | struct cpl_pass_accept_rpl *rpl; | 1255 | struct cpl_pass_accept_rpl *rpl; |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_mem.c b/drivers/infiniband/hw/cxgb3/iwch_mem.c index a6c2c4ba29e6..73bfd1656f86 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_mem.c +++ b/drivers/infiniband/hw/cxgb3/iwch_mem.c | |||
| @@ -122,6 +122,13 @@ int build_phys_page_list(struct ib_phys_buf *buffer_list, | |||
| 122 | *total_size += buffer_list[i].size; | 122 | *total_size += buffer_list[i].size; |
| 123 | if (i > 0) | 123 | if (i > 0) |
| 124 | mask |= buffer_list[i].addr; | 124 | mask |= buffer_list[i].addr; |
| 125 | else | ||
| 126 | mask |= buffer_list[i].addr & PAGE_MASK; | ||
| 127 | if (i != num_phys_buf - 1) | ||
| 128 | mask |= buffer_list[i].addr + buffer_list[i].size; | ||
| 129 | else | ||
| 130 | mask |= (buffer_list[i].addr + buffer_list[i].size + | ||
| 131 | PAGE_SIZE - 1) & PAGE_MASK; | ||
| 125 | } | 132 | } |
| 126 | 133 | ||
| 127 | if (*total_size > 0xFFFFFFFFULL) | 134 | if (*total_size > 0xFFFFFFFFULL) |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index b5436ca92e68..df1838f8f94d 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include <linux/list.h> | 39 | #include <linux/list.h> |
| 40 | #include <linux/spinlock.h> | 40 | #include <linux/spinlock.h> |
| 41 | #include <linux/ethtool.h> | 41 | #include <linux/ethtool.h> |
| 42 | #include <linux/rtnetlink.h> | ||
| 42 | 43 | ||
| 43 | #include <asm/io.h> | 44 | #include <asm/io.h> |
| 44 | #include <asm/irq.h> | 45 | #include <asm/irq.h> |
| @@ -645,7 +646,7 @@ static struct ib_mr *iwch_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, | |||
| 645 | if (err) | 646 | if (err) |
| 646 | goto err; | 647 | goto err; |
| 647 | 648 | ||
| 648 | if (udata && t3b_device(rhp)) { | 649 | if (udata && !t3a_device(rhp)) { |
| 649 | uresp.pbl_addr = (mhp->attr.pbl_addr - | 650 | uresp.pbl_addr = (mhp->attr.pbl_addr - |
| 650 | rhp->rdev.rnic_info.pbl_base) >> 3; | 651 | rhp->rdev.rnic_info.pbl_base) >> 3; |
| 651 | PDBG("%s user resp pbl_addr 0x%x\n", __FUNCTION__, | 652 | PDBG("%s user resp pbl_addr 0x%x\n", __FUNCTION__, |
| @@ -1053,7 +1054,9 @@ static ssize_t show_fw_ver(struct class_device *cdev, char *buf) | |||
| 1053 | struct net_device *lldev = dev->rdev.t3cdev_p->lldev; | 1054 | struct net_device *lldev = dev->rdev.t3cdev_p->lldev; |
| 1054 | 1055 | ||
| 1055 | PDBG("%s class dev 0x%p\n", __FUNCTION__, cdev); | 1056 | PDBG("%s class dev 0x%p\n", __FUNCTION__, cdev); |
| 1057 | rtnl_lock(); | ||
| 1056 | lldev->ethtool_ops->get_drvinfo(lldev, &info); | 1058 | lldev->ethtool_ops->get_drvinfo(lldev, &info); |
| 1059 | rtnl_unlock(); | ||
| 1057 | return sprintf(buf, "%s\n", info.fw_version); | 1060 | return sprintf(buf, "%s\n", info.fw_version); |
| 1058 | } | 1061 | } |
| 1059 | 1062 | ||
| @@ -1065,7 +1068,9 @@ static ssize_t show_hca(struct class_device *cdev, char *buf) | |||
| 1065 | struct net_device *lldev = dev->rdev.t3cdev_p->lldev; | 1068 | struct net_device *lldev = dev->rdev.t3cdev_p->lldev; |
| 1066 | 1069 | ||
| 1067 | PDBG("%s class dev 0x%p\n", __FUNCTION__, cdev); | 1070 | PDBG("%s class dev 0x%p\n", __FUNCTION__, cdev); |
| 1071 | rtnl_lock(); | ||
| 1068 | lldev->ethtool_ops->get_drvinfo(lldev, &info); | 1072 | lldev->ethtool_ops->get_drvinfo(lldev, &info); |
| 1073 | rtnl_unlock(); | ||
| 1069 | return sprintf(buf, "%s\n", info.driver); | 1074 | return sprintf(buf, "%s\n", info.driver); |
| 1070 | } | 1075 | } |
| 1071 | 1076 | ||
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c index dd89b6b91f9c..ea2cdd73dd85 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_qp.c +++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c | |||
| @@ -208,36 +208,19 @@ static int iwch_sgl2pbl_map(struct iwch_dev *rhp, struct ib_sge *sg_list, | |||
| 208 | static int iwch_build_rdma_recv(struct iwch_dev *rhp, union t3_wr *wqe, | 208 | static int iwch_build_rdma_recv(struct iwch_dev *rhp, union t3_wr *wqe, |
| 209 | struct ib_recv_wr *wr) | 209 | struct ib_recv_wr *wr) |
| 210 | { | 210 | { |
| 211 | int i, err = 0; | 211 | int i; |
| 212 | u32 pbl_addr[4]; | ||
| 213 | u8 page_size[4]; | ||
| 214 | if (wr->num_sge > T3_MAX_SGE) | 212 | if (wr->num_sge > T3_MAX_SGE) |
| 215 | return -EINVAL; | 213 | return -EINVAL; |
| 216 | err = iwch_sgl2pbl_map(rhp, wr->sg_list, wr->num_sge, pbl_addr, | ||
| 217 | page_size); | ||
| 218 | if (err) | ||
| 219 | return err; | ||
| 220 | wqe->recv.pagesz[0] = page_size[0]; | ||
| 221 | wqe->recv.pagesz[1] = page_size[1]; | ||
| 222 | wqe->recv.pagesz[2] = page_size[2]; | ||
| 223 | wqe->recv.pagesz[3] = page_size[3]; | ||
| 224 | wqe->recv.num_sgle = cpu_to_be32(wr->num_sge); | 214 | wqe->recv.num_sgle = cpu_to_be32(wr->num_sge); |
| 225 | for (i = 0; i < wr->num_sge; i++) { | 215 | for (i = 0; i < wr->num_sge; i++) { |
| 226 | wqe->recv.sgl[i].stag = cpu_to_be32(wr->sg_list[i].lkey); | 216 | wqe->recv.sgl[i].stag = cpu_to_be32(wr->sg_list[i].lkey); |
| 227 | wqe->recv.sgl[i].len = cpu_to_be32(wr->sg_list[i].length); | 217 | wqe->recv.sgl[i].len = cpu_to_be32(wr->sg_list[i].length); |
| 228 | 218 | wqe->recv.sgl[i].to = cpu_to_be64(wr->sg_list[i].addr); | |
| 229 | /* to in the WQE == the offset into the page */ | ||
| 230 | wqe->recv.sgl[i].to = cpu_to_be64(((u32) wr->sg_list[i].addr) % | ||
| 231 | (1UL << (12 + page_size[i]))); | ||
| 232 | |||
| 233 | /* pbl_addr is the adapters address in the PBL */ | ||
| 234 | wqe->recv.pbl_addr[i] = cpu_to_be32(pbl_addr[i]); | ||
| 235 | } | 219 | } |
| 236 | for (; i < T3_MAX_SGE; i++) { | 220 | for (; i < T3_MAX_SGE; i++) { |
| 237 | wqe->recv.sgl[i].stag = 0; | 221 | wqe->recv.sgl[i].stag = 0; |
| 238 | wqe->recv.sgl[i].len = 0; | 222 | wqe->recv.sgl[i].len = 0; |
| 239 | wqe->recv.sgl[i].to = 0; | 223 | wqe->recv.sgl[i].to = 0; |
| 240 | wqe->recv.pbl_addr[i] = 0; | ||
| 241 | } | 224 | } |
| 242 | return 0; | 225 | return 0; |
| 243 | } | 226 | } |
| @@ -659,6 +642,7 @@ static void __flush_qp(struct iwch_qp *qhp, unsigned long *flag) | |||
| 659 | cxio_flush_rq(&qhp->wq, &rchp->cq, count); | 642 | cxio_flush_rq(&qhp->wq, &rchp->cq, count); |
| 660 | spin_unlock(&qhp->lock); | 643 | spin_unlock(&qhp->lock); |
| 661 | spin_unlock_irqrestore(&rchp->lock, *flag); | 644 | spin_unlock_irqrestore(&rchp->lock, *flag); |
| 645 | (*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context); | ||
| 662 | 646 | ||
| 663 | /* locking heirarchy: cq lock first, then qp lock. */ | 647 | /* locking heirarchy: cq lock first, then qp lock. */ |
| 664 | spin_lock_irqsave(&schp->lock, *flag); | 648 | spin_lock_irqsave(&schp->lock, *flag); |
| @@ -668,6 +652,7 @@ static void __flush_qp(struct iwch_qp *qhp, unsigned long *flag) | |||
| 668 | cxio_flush_sq(&qhp->wq, &schp->cq, count); | 652 | cxio_flush_sq(&qhp->wq, &schp->cq, count); |
| 669 | spin_unlock(&qhp->lock); | 653 | spin_unlock(&qhp->lock); |
| 670 | spin_unlock_irqrestore(&schp->lock, *flag); | 654 | spin_unlock_irqrestore(&schp->lock, *flag); |
| 655 | (*schp->ibcq.comp_handler)(&schp->ibcq, schp->ibcq.cq_context); | ||
| 671 | 656 | ||
| 672 | /* deref */ | 657 | /* deref */ |
| 673 | if (atomic_dec_and_test(&qhp->refcnt)) | 658 | if (atomic_dec_and_test(&qhp->refcnt)) |
| @@ -678,7 +663,7 @@ static void __flush_qp(struct iwch_qp *qhp, unsigned long *flag) | |||
| 678 | 663 | ||
| 679 | static void flush_qp(struct iwch_qp *qhp, unsigned long *flag) | 664 | static void flush_qp(struct iwch_qp *qhp, unsigned long *flag) |
| 680 | { | 665 | { |
| 681 | if (t3b_device(qhp->rhp)) | 666 | if (qhp->ibqp.uobject) |
| 682 | cxio_set_wq_in_error(&qhp->wq); | 667 | cxio_set_wq_in_error(&qhp->wq); |
| 683 | else | 668 | else |
| 684 | __flush_qp(qhp, flag); | 669 | __flush_qp(qhp, flag); |
| @@ -732,6 +717,7 @@ static int rdma_init(struct iwch_dev *rhp, struct iwch_qp *qhp, | |||
| 732 | init_attr.qp_dma_addr = qhp->wq.dma_addr; | 717 | init_attr.qp_dma_addr = qhp->wq.dma_addr; |
| 733 | init_attr.qp_dma_size = (1UL << qhp->wq.size_log2); | 718 | init_attr.qp_dma_size = (1UL << qhp->wq.size_log2); |
| 734 | init_attr.flags = rqes_posted(qhp) ? RECVS_POSTED : 0; | 719 | init_attr.flags = rqes_posted(qhp) ? RECVS_POSTED : 0; |
| 720 | init_attr.flags |= capable(CAP_NET_BIND_SERVICE) ? PRIV_QP : 0; | ||
| 735 | init_attr.irs = qhp->ep->rcv_seq; | 721 | init_attr.irs = qhp->ep->rcv_seq; |
| 736 | PDBG("%s init_attr.rq_addr 0x%x init_attr.rq_size = %d " | 722 | PDBG("%s init_attr.rq_addr 0x%x init_attr.rq_size = %d " |
| 737 | "flags 0x%x qpcaps 0x%x\n", __FUNCTION__, | 723 | "flags 0x%x qpcaps 0x%x\n", __FUNCTION__, |
| @@ -847,10 +833,11 @@ int iwch_modify_qp(struct iwch_dev *rhp, struct iwch_qp *qhp, | |||
| 847 | disconnect = 1; | 833 | disconnect = 1; |
| 848 | ep = qhp->ep; | 834 | ep = qhp->ep; |
| 849 | } | 835 | } |
| 836 | flush_qp(qhp, &flag); | ||
| 850 | break; | 837 | break; |
| 851 | case IWCH_QP_STATE_TERMINATE: | 838 | case IWCH_QP_STATE_TERMINATE: |
| 852 | qhp->attr.state = IWCH_QP_STATE_TERMINATE; | 839 | qhp->attr.state = IWCH_QP_STATE_TERMINATE; |
| 853 | if (t3b_device(qhp->rhp)) | 840 | if (qhp->ibqp.uobject) |
| 854 | cxio_set_wq_in_error(&qhp->wq); | 841 | cxio_set_wq_in_error(&qhp->wq); |
| 855 | if (!internal) | 842 | if (!internal) |
| 856 | terminate = 1; | 843 | terminate = 1; |
diff --git a/drivers/infiniband/hw/ehca/ehca_av.c b/drivers/infiniband/hw/ehca/ehca_av.c index f7782c882ab4..194c1c30cf63 100644 --- a/drivers/infiniband/hw/ehca/ehca_av.c +++ b/drivers/infiniband/hw/ehca/ehca_av.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * IBM eServer eHCA Infiniband device driver for Linux on POWER | 2 | * IBM eServer eHCA Infiniband device driver for Linux on POWER |
| 3 | * | 3 | * |
| 4 | * adress vector functions | 4 | * address vector functions |
| 5 | * | 5 | * |
| 6 | * Authors: Hoang-Nam Nguyen <hnguyen@de.ibm.com> | 6 | * Authors: Hoang-Nam Nguyen <hnguyen@de.ibm.com> |
| 7 | * Khadija Souissi <souissik@de.ibm.com> | 7 | * Khadija Souissi <souissik@de.ibm.com> |
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h index 74d2b72a11d8..f281d16040f5 100644 --- a/drivers/infiniband/hw/ehca/ehca_classes.h +++ b/drivers/infiniband/hw/ehca/ehca_classes.h | |||
| @@ -94,7 +94,11 @@ struct ehca_sma_attr { | |||
| 94 | 94 | ||
| 95 | struct ehca_sport { | 95 | struct ehca_sport { |
| 96 | struct ib_cq *ibcq_aqp1; | 96 | struct ib_cq *ibcq_aqp1; |
| 97 | struct ib_qp *ibqp_aqp1; | 97 | struct ib_qp *ibqp_sqp[2]; |
| 98 | /* lock to serialze modify_qp() calls for sqp in normal | ||
| 99 | * and irq path (when event PORT_ACTIVE is received first time) | ||
| 100 | */ | ||
| 101 | spinlock_t mod_sqp_lock; | ||
| 98 | enum ib_port_state port_state; | 102 | enum ib_port_state port_state; |
| 99 | struct ehca_sma_attr saved_attr; | 103 | struct ehca_sma_attr saved_attr; |
| 100 | }; | 104 | }; |
| @@ -141,6 +145,14 @@ enum ehca_ext_qp_type { | |||
| 141 | EQPT_SRQ = 3, | 145 | EQPT_SRQ = 3, |
| 142 | }; | 146 | }; |
| 143 | 147 | ||
| 148 | /* struct to cache modify_qp()'s parms for GSI/SMI qp */ | ||
| 149 | struct ehca_mod_qp_parm { | ||
| 150 | int mask; | ||
| 151 | struct ib_qp_attr attr; | ||
| 152 | }; | ||
| 153 | |||
| 154 | #define EHCA_MOD_QP_PARM_MAX 4 | ||
| 155 | |||
| 144 | struct ehca_qp { | 156 | struct ehca_qp { |
| 145 | union { | 157 | union { |
| 146 | struct ib_qp ib_qp; | 158 | struct ib_qp ib_qp; |
| @@ -164,10 +176,18 @@ struct ehca_qp { | |||
| 164 | struct ehca_cq *recv_cq; | 176 | struct ehca_cq *recv_cq; |
| 165 | unsigned int sqerr_purgeflag; | 177 | unsigned int sqerr_purgeflag; |
| 166 | struct hlist_node list_entries; | 178 | struct hlist_node list_entries; |
| 179 | /* array to cache modify_qp()'s parms for GSI/SMI qp */ | ||
| 180 | struct ehca_mod_qp_parm *mod_qp_parm; | ||
| 181 | int mod_qp_parm_idx; | ||
| 167 | /* mmap counter for resources mapped into user space */ | 182 | /* mmap counter for resources mapped into user space */ |
| 168 | u32 mm_count_squeue; | 183 | u32 mm_count_squeue; |
| 169 | u32 mm_count_rqueue; | 184 | u32 mm_count_rqueue; |
| 170 | u32 mm_count_galpa; | 185 | u32 mm_count_galpa; |
| 186 | /* unsolicited ack circumvention */ | ||
| 187 | int unsol_ack_circ; | ||
| 188 | int mtu_shift; | ||
| 189 | u32 message_count; | ||
| 190 | u32 packet_count; | ||
| 171 | }; | 191 | }; |
| 172 | 192 | ||
| 173 | #define IS_SRQ(qp) (qp->ext_type == EQPT_SRQ) | 193 | #define IS_SRQ(qp) (qp->ext_type == EQPT_SRQ) |
| @@ -323,6 +343,7 @@ extern int ehca_port_act_time; | |||
| 323 | extern int ehca_use_hp_mr; | 343 | extern int ehca_use_hp_mr; |
| 324 | extern int ehca_scaling_code; | 344 | extern int ehca_scaling_code; |
| 325 | extern int ehca_lock_hcalls; | 345 | extern int ehca_lock_hcalls; |
| 346 | extern int ehca_nr_ports; | ||
| 326 | 347 | ||
| 327 | struct ipzu_queue_resp { | 348 | struct ipzu_queue_resp { |
| 328 | u32 qe_size; /* queue entry size */ | 349 | u32 qe_size; /* queue entry size */ |
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c index 79c25f51c21e..0467c158d4a9 100644 --- a/drivers/infiniband/hw/ehca/ehca_cq.c +++ b/drivers/infiniband/hw/ehca/ehca_cq.c | |||
| @@ -246,7 +246,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, | |||
| 246 | } else { | 246 | } else { |
| 247 | if (h_ret != H_PAGE_REGISTERED) { | 247 | if (h_ret != H_PAGE_REGISTERED) { |
| 248 | ehca_err(device, "Registration of page failed " | 248 | ehca_err(device, "Registration of page failed " |
| 249 | "ehca_cq=%p cq_num=%x h_ret=%li" | 249 | "ehca_cq=%p cq_num=%x h_ret=%li " |
| 250 | "counter=%i act_pages=%i", | 250 | "counter=%i act_pages=%i", |
| 251 | my_cq, my_cq->cq_number, | 251 | my_cq, my_cq->cq_number, |
| 252 | h_ret, counter, param.act_pages); | 252 | h_ret, counter, param.act_pages); |
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index 3f617b27b954..863b34fa9ff9 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c | |||
| @@ -62,6 +62,7 @@ | |||
| 62 | #define NEQE_PORT_NUMBER EHCA_BMASK_IBM( 8, 15) | 62 | #define NEQE_PORT_NUMBER EHCA_BMASK_IBM( 8, 15) |
| 63 | #define NEQE_PORT_AVAILABILITY EHCA_BMASK_IBM(16, 16) | 63 | #define NEQE_PORT_AVAILABILITY EHCA_BMASK_IBM(16, 16) |
| 64 | #define NEQE_DISRUPTIVE EHCA_BMASK_IBM(16, 16) | 64 | #define NEQE_DISRUPTIVE EHCA_BMASK_IBM(16, 16) |
| 65 | #define NEQE_SPECIFIC_EVENT EHCA_BMASK_IBM(16, 23) | ||
| 65 | 66 | ||
| 66 | #define ERROR_DATA_LENGTH EHCA_BMASK_IBM(52, 63) | 67 | #define ERROR_DATA_LENGTH EHCA_BMASK_IBM(52, 63) |
| 67 | #define ERROR_DATA_TYPE EHCA_BMASK_IBM( 0, 7) | 68 | #define ERROR_DATA_TYPE EHCA_BMASK_IBM( 0, 7) |
| @@ -354,17 +355,34 @@ static void parse_ec(struct ehca_shca *shca, u64 eqe) | |||
| 354 | { | 355 | { |
| 355 | u8 ec = EHCA_BMASK_GET(NEQE_EVENT_CODE, eqe); | 356 | u8 ec = EHCA_BMASK_GET(NEQE_EVENT_CODE, eqe); |
| 356 | u8 port = EHCA_BMASK_GET(NEQE_PORT_NUMBER, eqe); | 357 | u8 port = EHCA_BMASK_GET(NEQE_PORT_NUMBER, eqe); |
| 358 | u8 spec_event; | ||
| 359 | struct ehca_sport *sport = &shca->sport[port - 1]; | ||
| 360 | unsigned long flags; | ||
| 357 | 361 | ||
| 358 | switch (ec) { | 362 | switch (ec) { |
| 359 | case 0x30: /* port availability change */ | 363 | case 0x30: /* port availability change */ |
| 360 | if (EHCA_BMASK_GET(NEQE_PORT_AVAILABILITY, eqe)) { | 364 | if (EHCA_BMASK_GET(NEQE_PORT_AVAILABILITY, eqe)) { |
| 361 | shca->sport[port - 1].port_state = IB_PORT_ACTIVE; | 365 | int suppress_event; |
| 366 | /* replay modify_qp for sqps */ | ||
| 367 | spin_lock_irqsave(&sport->mod_sqp_lock, flags); | ||
| 368 | suppress_event = !sport->ibqp_sqp[IB_QPT_GSI]; | ||
| 369 | if (sport->ibqp_sqp[IB_QPT_SMI]) | ||
| 370 | ehca_recover_sqp(sport->ibqp_sqp[IB_QPT_SMI]); | ||
| 371 | if (!suppress_event) | ||
| 372 | ehca_recover_sqp(sport->ibqp_sqp[IB_QPT_GSI]); | ||
| 373 | spin_unlock_irqrestore(&sport->mod_sqp_lock, flags); | ||
| 374 | |||
| 375 | /* AQP1 was destroyed, ignore this event */ | ||
| 376 | if (suppress_event) | ||
| 377 | break; | ||
| 378 | |||
| 379 | sport->port_state = IB_PORT_ACTIVE; | ||
| 362 | dispatch_port_event(shca, port, IB_EVENT_PORT_ACTIVE, | 380 | dispatch_port_event(shca, port, IB_EVENT_PORT_ACTIVE, |
| 363 | "is active"); | 381 | "is active"); |
| 364 | ehca_query_sma_attr(shca, port, | 382 | ehca_query_sma_attr(shca, port, |
| 365 | &shca->sport[port - 1].saved_attr); | 383 | &sport->saved_attr); |
| 366 | } else { | 384 | } else { |
| 367 | shca->sport[port - 1].port_state = IB_PORT_DOWN; | 385 | sport->port_state = IB_PORT_DOWN; |
| 368 | dispatch_port_event(shca, port, IB_EVENT_PORT_ERR, | 386 | dispatch_port_event(shca, port, IB_EVENT_PORT_ERR, |
| 369 | "is inactive"); | 387 | "is inactive"); |
| 370 | } | 388 | } |
| @@ -378,11 +396,11 @@ static void parse_ec(struct ehca_shca *shca, u64 eqe) | |||
| 378 | ehca_warn(&shca->ib_device, "disruptive port " | 396 | ehca_warn(&shca->ib_device, "disruptive port " |
| 379 | "%d configuration change", port); | 397 | "%d configuration change", port); |
| 380 | 398 | ||
| 381 | shca->sport[port - 1].port_state = IB_PORT_DOWN; | 399 | sport->port_state = IB_PORT_DOWN; |
| 382 | dispatch_port_event(shca, port, IB_EVENT_PORT_ERR, | 400 | dispatch_port_event(shca, port, IB_EVENT_PORT_ERR, |
| 383 | "is inactive"); | 401 | "is inactive"); |
| 384 | 402 | ||
| 385 | shca->sport[port - 1].port_state = IB_PORT_ACTIVE; | 403 | sport->port_state = IB_PORT_ACTIVE; |
| 386 | dispatch_port_event(shca, port, IB_EVENT_PORT_ACTIVE, | 404 | dispatch_port_event(shca, port, IB_EVENT_PORT_ACTIVE, |
| 387 | "is active"); | 405 | "is active"); |
| 388 | } else | 406 | } else |
| @@ -394,6 +412,16 @@ static void parse_ec(struct ehca_shca *shca, u64 eqe) | |||
| 394 | case 0x33: /* trace stopped */ | 412 | case 0x33: /* trace stopped */ |
| 395 | ehca_err(&shca->ib_device, "Traced stopped."); | 413 | ehca_err(&shca->ib_device, "Traced stopped."); |
| 396 | break; | 414 | break; |
| 415 | case 0x34: /* util async event */ | ||
| 416 | spec_event = EHCA_BMASK_GET(NEQE_SPECIFIC_EVENT, eqe); | ||
| 417 | if (spec_event == 0x80) /* client reregister required */ | ||
| 418 | dispatch_port_event(shca, port, | ||
| 419 | IB_EVENT_CLIENT_REREGISTER, | ||
| 420 | "client reregister req."); | ||
| 421 | else | ||
| 422 | ehca_warn(&shca->ib_device, "Unknown util async " | ||
| 423 | "event %x on port %x", spec_event, port); | ||
| 424 | break; | ||
| 397 | default: | 425 | default: |
| 398 | ehca_err(&shca->ib_device, "Unknown event code: %x on %s.", | 426 | ehca_err(&shca->ib_device, "Unknown event code: %x on %s.", |
| 399 | ec, shca->ib_device.name); | 427 | ec, shca->ib_device.name); |
diff --git a/drivers/infiniband/hw/ehca/ehca_iverbs.h b/drivers/infiniband/hw/ehca/ehca_iverbs.h index 5485799cdc8d..c469bfde2708 100644 --- a/drivers/infiniband/hw/ehca/ehca_iverbs.h +++ b/drivers/infiniband/hw/ehca/ehca_iverbs.h | |||
| @@ -200,4 +200,6 @@ void ehca_free_fw_ctrlblock(void *ptr); | |||
| 200 | #define ehca_free_fw_ctrlblock(ptr) free_page((unsigned long)(ptr)) | 200 | #define ehca_free_fw_ctrlblock(ptr) free_page((unsigned long)(ptr)) |
| 201 | #endif | 201 | #endif |
| 202 | 202 | ||
| 203 | void ehca_recover_sqp(struct ib_qp *sqp); | ||
| 204 | |||
| 203 | #endif | 205 | #endif |
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index c9e32b46387f..84c9b7b8669b 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c | |||
| @@ -90,7 +90,8 @@ MODULE_PARM_DESC(hw_level, | |||
| 90 | "hardware level" | 90 | "hardware level" |
| 91 | " (0: autosensing (default), 1: v. 0.20, 2: v. 0.21)"); | 91 | " (0: autosensing (default), 1: v. 0.20, 2: v. 0.21)"); |
| 92 | MODULE_PARM_DESC(nr_ports, | 92 | MODULE_PARM_DESC(nr_ports, |
| 93 | "number of connected ports (default: 2)"); | 93 | "number of connected ports (-1: autodetect, 1: port one only, " |
| 94 | "2: two ports (default)"); | ||
| 94 | MODULE_PARM_DESC(use_hp_mr, | 95 | MODULE_PARM_DESC(use_hp_mr, |
| 95 | "high performance MRs (0: no (default), 1: yes)"); | 96 | "high performance MRs (0: no (default), 1: yes)"); |
| 96 | MODULE_PARM_DESC(port_act_time, | 97 | MODULE_PARM_DESC(port_act_time, |
| @@ -511,7 +512,7 @@ static int ehca_create_aqp1(struct ehca_shca *shca, u32 port) | |||
| 511 | } | 512 | } |
| 512 | sport->ibcq_aqp1 = ibcq; | 513 | sport->ibcq_aqp1 = ibcq; |
| 513 | 514 | ||
| 514 | if (sport->ibqp_aqp1) { | 515 | if (sport->ibqp_sqp[IB_QPT_GSI]) { |
| 515 | ehca_err(&shca->ib_device, "AQP1 QP is already created."); | 516 | ehca_err(&shca->ib_device, "AQP1 QP is already created."); |
| 516 | ret = -EPERM; | 517 | ret = -EPERM; |
| 517 | goto create_aqp1; | 518 | goto create_aqp1; |
| @@ -537,7 +538,7 @@ static int ehca_create_aqp1(struct ehca_shca *shca, u32 port) | |||
| 537 | ret = PTR_ERR(ibqp); | 538 | ret = PTR_ERR(ibqp); |
| 538 | goto create_aqp1; | 539 | goto create_aqp1; |
| 539 | } | 540 | } |
| 540 | sport->ibqp_aqp1 = ibqp; | 541 | sport->ibqp_sqp[IB_QPT_GSI] = ibqp; |
| 541 | 542 | ||
| 542 | return 0; | 543 | return 0; |
| 543 | 544 | ||
| @@ -550,7 +551,7 @@ static int ehca_destroy_aqp1(struct ehca_sport *sport) | |||
| 550 | { | 551 | { |
| 551 | int ret; | 552 | int ret; |
| 552 | 553 | ||
| 553 | ret = ib_destroy_qp(sport->ibqp_aqp1); | 554 | ret = ib_destroy_qp(sport->ibqp_sqp[IB_QPT_GSI]); |
| 554 | if (ret) { | 555 | if (ret) { |
| 555 | ehca_gen_err("Cannot destroy AQP1 QP. ret=%i", ret); | 556 | ehca_gen_err("Cannot destroy AQP1 QP. ret=%i", ret); |
| 556 | return ret; | 557 | return ret; |
| @@ -693,7 +694,7 @@ static int __devinit ehca_probe(struct of_device *dev, | |||
| 693 | struct ehca_shca *shca; | 694 | struct ehca_shca *shca; |
| 694 | const u64 *handle; | 695 | const u64 *handle; |
| 695 | struct ib_pd *ibpd; | 696 | struct ib_pd *ibpd; |
| 696 | int ret; | 697 | int ret, i; |
| 697 | 698 | ||
| 698 | handle = of_get_property(dev->node, "ibm,hca-handle", NULL); | 699 | handle = of_get_property(dev->node, "ibm,hca-handle", NULL); |
| 699 | if (!handle) { | 700 | if (!handle) { |
| @@ -714,6 +715,8 @@ static int __devinit ehca_probe(struct of_device *dev, | |||
| 714 | return -ENOMEM; | 715 | return -ENOMEM; |
| 715 | } | 716 | } |
| 716 | mutex_init(&shca->modify_mutex); | 717 | mutex_init(&shca->modify_mutex); |
| 718 | for (i = 0; i < ARRAY_SIZE(shca->sport); i++) | ||
| 719 | spin_lock_init(&shca->sport[i].mod_sqp_lock); | ||
| 717 | 720 | ||
| 718 | shca->ofdev = dev; | 721 | shca->ofdev = dev; |
| 719 | shca->ipz_hca_handle.handle = *handle; | 722 | shca->ipz_hca_handle.handle = *handle; |
| @@ -934,7 +937,7 @@ void ehca_poll_eqs(unsigned long data) | |||
| 934 | ehca_process_eq(shca, 0); | 937 | ehca_process_eq(shca, 0); |
| 935 | } | 938 | } |
| 936 | } | 939 | } |
| 937 | mod_timer(&poll_eqs_timer, jiffies + HZ); | 940 | mod_timer(&poll_eqs_timer, round_jiffies(jiffies + HZ)); |
| 938 | spin_unlock(&shca_list_lock); | 941 | spin_unlock(&shca_list_lock); |
| 939 | } | 942 | } |
| 940 | 943 | ||
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index eff5fb55604b..1012f15a7140 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c | |||
| @@ -592,10 +592,8 @@ static struct ehca_qp *internal_create_qp( | |||
| 592 | goto create_qp_exit1; | 592 | goto create_qp_exit1; |
| 593 | } | 593 | } |
| 594 | 594 | ||
| 595 | if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) | 595 | /* Always signal by WQE so we can hide circ. WQEs */ |
| 596 | parms.sigtype = HCALL_SIGT_EVERY; | 596 | parms.sigtype = HCALL_SIGT_BY_WQE; |
| 597 | else | ||
| 598 | parms.sigtype = HCALL_SIGT_BY_WQE; | ||
| 599 | 597 | ||
| 600 | /* UD_AV CIRCUMVENTION */ | 598 | /* UD_AV CIRCUMVENTION */ |
| 601 | max_send_sge = init_attr->cap.max_send_sge; | 599 | max_send_sge = init_attr->cap.max_send_sge; |
| @@ -618,6 +616,10 @@ static struct ehca_qp *internal_create_qp( | |||
| 618 | parms.squeue.max_sge = max_send_sge; | 616 | parms.squeue.max_sge = max_send_sge; |
| 619 | parms.rqueue.max_sge = max_recv_sge; | 617 | parms.rqueue.max_sge = max_recv_sge; |
| 620 | 618 | ||
| 619 | /* RC QPs need one more SWQE for unsolicited ack circumvention */ | ||
| 620 | if (qp_type == IB_QPT_RC) | ||
| 621 | parms.squeue.max_wr++; | ||
| 622 | |||
| 621 | if (EHCA_BMASK_GET(HCA_CAP_MINI_QP, shca->hca_cap)) { | 623 | if (EHCA_BMASK_GET(HCA_CAP_MINI_QP, shca->hca_cap)) { |
| 622 | if (HAS_SQ(my_qp)) | 624 | if (HAS_SQ(my_qp)) |
| 623 | ehca_determine_small_queue( | 625 | ehca_determine_small_queue( |
| @@ -650,6 +652,8 @@ static struct ehca_qp *internal_create_qp( | |||
| 650 | parms.squeue.act_nr_sges = 1; | 652 | parms.squeue.act_nr_sges = 1; |
| 651 | parms.rqueue.act_nr_sges = 1; | 653 | parms.rqueue.act_nr_sges = 1; |
| 652 | } | 654 | } |
| 655 | /* hide the extra WQE */ | ||
| 656 | parms.squeue.act_nr_wqes--; | ||
| 653 | break; | 657 | break; |
| 654 | case IB_QPT_UD: | 658 | case IB_QPT_UD: |
| 655 | case IB_QPT_GSI: | 659 | case IB_QPT_GSI: |
| @@ -729,12 +733,31 @@ static struct ehca_qp *internal_create_qp( | |||
| 729 | init_attr->cap.max_send_wr = parms.squeue.act_nr_wqes; | 733 | init_attr->cap.max_send_wr = parms.squeue.act_nr_wqes; |
| 730 | my_qp->init_attr = *init_attr; | 734 | my_qp->init_attr = *init_attr; |
| 731 | 735 | ||
| 736 | if (qp_type == IB_QPT_SMI || qp_type == IB_QPT_GSI) { | ||
| 737 | shca->sport[init_attr->port_num - 1].ibqp_sqp[qp_type] = | ||
| 738 | &my_qp->ib_qp; | ||
| 739 | if (ehca_nr_ports < 0) { | ||
| 740 | /* alloc array to cache subsequent modify qp parms | ||
| 741 | * for autodetect mode | ||
| 742 | */ | ||
| 743 | my_qp->mod_qp_parm = | ||
| 744 | kzalloc(EHCA_MOD_QP_PARM_MAX * | ||
| 745 | sizeof(*my_qp->mod_qp_parm), | ||
| 746 | GFP_KERNEL); | ||
| 747 | if (!my_qp->mod_qp_parm) { | ||
| 748 | ehca_err(pd->device, | ||
| 749 | "Could not alloc mod_qp_parm"); | ||
| 750 | goto create_qp_exit4; | ||
| 751 | } | ||
| 752 | } | ||
| 753 | } | ||
| 754 | |||
| 732 | /* NOTE: define_apq0() not supported yet */ | 755 | /* NOTE: define_apq0() not supported yet */ |
| 733 | if (qp_type == IB_QPT_GSI) { | 756 | if (qp_type == IB_QPT_GSI) { |
| 734 | h_ret = ehca_define_sqp(shca, my_qp, init_attr); | 757 | h_ret = ehca_define_sqp(shca, my_qp, init_attr); |
| 735 | if (h_ret != H_SUCCESS) { | 758 | if (h_ret != H_SUCCESS) { |
| 736 | ret = ehca2ib_return_code(h_ret); | 759 | ret = ehca2ib_return_code(h_ret); |
| 737 | goto create_qp_exit4; | 760 | goto create_qp_exit5; |
| 738 | } | 761 | } |
| 739 | } | 762 | } |
| 740 | 763 | ||
| @@ -743,7 +766,7 @@ static struct ehca_qp *internal_create_qp( | |||
| 743 | if (ret) { | 766 | if (ret) { |
| 744 | ehca_err(pd->device, | 767 | ehca_err(pd->device, |
| 745 | "Couldn't assign qp to send_cq ret=%i", ret); | 768 | "Couldn't assign qp to send_cq ret=%i", ret); |
| 746 | goto create_qp_exit4; | 769 | goto create_qp_exit5; |
| 747 | } | 770 | } |
| 748 | } | 771 | } |
| 749 | 772 | ||
| @@ -769,12 +792,18 @@ static struct ehca_qp *internal_create_qp( | |||
| 769 | if (ib_copy_to_udata(udata, &resp, sizeof resp)) { | 792 | if (ib_copy_to_udata(udata, &resp, sizeof resp)) { |
| 770 | ehca_err(pd->device, "Copy to udata failed"); | 793 | ehca_err(pd->device, "Copy to udata failed"); |
| 771 | ret = -EINVAL; | 794 | ret = -EINVAL; |
| 772 | goto create_qp_exit4; | 795 | goto create_qp_exit6; |
| 773 | } | 796 | } |
| 774 | } | 797 | } |
| 775 | 798 | ||
| 776 | return my_qp; | 799 | return my_qp; |
| 777 | 800 | ||
| 801 | create_qp_exit6: | ||
| 802 | ehca_cq_unassign_qp(my_qp->send_cq, my_qp->real_qp_num); | ||
| 803 | |||
| 804 | create_qp_exit5: | ||
| 805 | kfree(my_qp->mod_qp_parm); | ||
| 806 | |||
| 778 | create_qp_exit4: | 807 | create_qp_exit4: |
| 779 | if (HAS_RQ(my_qp)) | 808 | if (HAS_RQ(my_qp)) |
| 780 | ipz_queue_dtor(my_pd, &my_qp->ipz_rqueue); | 809 | ipz_queue_dtor(my_pd, &my_qp->ipz_rqueue); |
| @@ -858,7 +887,7 @@ struct ib_srq *ehca_create_srq(struct ib_pd *pd, | |||
| 858 | update_mask, | 887 | update_mask, |
| 859 | mqpcb, my_qp->galpas.kernel); | 888 | mqpcb, my_qp->galpas.kernel); |
| 860 | if (hret != H_SUCCESS) { | 889 | if (hret != H_SUCCESS) { |
| 861 | ehca_err(pd->device, "Could not modify SRQ to INIT" | 890 | ehca_err(pd->device, "Could not modify SRQ to INIT " |
| 862 | "ehca_qp=%p qp_num=%x h_ret=%li", | 891 | "ehca_qp=%p qp_num=%x h_ret=%li", |
| 863 | my_qp, my_qp->real_qp_num, hret); | 892 | my_qp, my_qp->real_qp_num, hret); |
| 864 | goto create_srq2; | 893 | goto create_srq2; |
| @@ -872,7 +901,7 @@ struct ib_srq *ehca_create_srq(struct ib_pd *pd, | |||
| 872 | update_mask, | 901 | update_mask, |
| 873 | mqpcb, my_qp->galpas.kernel); | 902 | mqpcb, my_qp->galpas.kernel); |
| 874 | if (hret != H_SUCCESS) { | 903 | if (hret != H_SUCCESS) { |
| 875 | ehca_err(pd->device, "Could not enable SRQ" | 904 | ehca_err(pd->device, "Could not enable SRQ " |
| 876 | "ehca_qp=%p qp_num=%x h_ret=%li", | 905 | "ehca_qp=%p qp_num=%x h_ret=%li", |
| 877 | my_qp, my_qp->real_qp_num, hret); | 906 | my_qp, my_qp->real_qp_num, hret); |
| 878 | goto create_srq2; | 907 | goto create_srq2; |
| @@ -886,7 +915,7 @@ struct ib_srq *ehca_create_srq(struct ib_pd *pd, | |||
| 886 | update_mask, | 915 | update_mask, |
| 887 | mqpcb, my_qp->galpas.kernel); | 916 | mqpcb, my_qp->galpas.kernel); |
| 888 | if (hret != H_SUCCESS) { | 917 | if (hret != H_SUCCESS) { |
| 889 | ehca_err(pd->device, "Could not modify SRQ to RTR" | 918 | ehca_err(pd->device, "Could not modify SRQ to RTR " |
| 890 | "ehca_qp=%p qp_num=%x h_ret=%li", | 919 | "ehca_qp=%p qp_num=%x h_ret=%li", |
| 891 | my_qp, my_qp->real_qp_num, hret); | 920 | my_qp, my_qp->real_qp_num, hret); |
| 892 | goto create_srq2; | 921 | goto create_srq2; |
| @@ -992,7 +1021,7 @@ static int internal_modify_qp(struct ib_qp *ibqp, | |||
| 992 | unsigned long flags = 0; | 1021 | unsigned long flags = 0; |
| 993 | 1022 | ||
| 994 | /* do query_qp to obtain current attr values */ | 1023 | /* do query_qp to obtain current attr values */ |
| 995 | mqpcb = ehca_alloc_fw_ctrlblock(GFP_KERNEL); | 1024 | mqpcb = ehca_alloc_fw_ctrlblock(GFP_ATOMIC); |
| 996 | if (!mqpcb) { | 1025 | if (!mqpcb) { |
| 997 | ehca_err(ibqp->device, "Could not get zeroed page for mqpcb " | 1026 | ehca_err(ibqp->device, "Could not get zeroed page for mqpcb " |
| 998 | "ehca_qp=%p qp_num=%x ", my_qp, ibqp->qp_num); | 1027 | "ehca_qp=%p qp_num=%x ", my_qp, ibqp->qp_num); |
| @@ -1180,6 +1209,8 @@ static int internal_modify_qp(struct ib_qp *ibqp, | |||
| 1180 | update_mask |= EHCA_BMASK_SET(MQPCB_MASK_PRIM_P_KEY_IDX, 1); | 1209 | update_mask |= EHCA_BMASK_SET(MQPCB_MASK_PRIM_P_KEY_IDX, 1); |
| 1181 | } | 1210 | } |
| 1182 | if (attr_mask & IB_QP_PORT) { | 1211 | if (attr_mask & IB_QP_PORT) { |
| 1212 | struct ehca_sport *sport; | ||
| 1213 | struct ehca_qp *aqp1; | ||
| 1183 | if (attr->port_num < 1 || attr->port_num > shca->num_ports) { | 1214 | if (attr->port_num < 1 || attr->port_num > shca->num_ports) { |
| 1184 | ret = -EINVAL; | 1215 | ret = -EINVAL; |
| 1185 | ehca_err(ibqp->device, "Invalid port=%x. " | 1216 | ehca_err(ibqp->device, "Invalid port=%x. " |
| @@ -1188,6 +1219,29 @@ static int internal_modify_qp(struct ib_qp *ibqp, | |||
| 1188 | shca->num_ports); | 1219 | shca->num_ports); |
| 1189 | goto modify_qp_exit2; | 1220 | goto modify_qp_exit2; |
| 1190 | } | 1221 | } |
| 1222 | sport = &shca->sport[attr->port_num - 1]; | ||
| 1223 | if (!sport->ibqp_sqp[IB_QPT_GSI]) { | ||
| 1224 | /* should not occur */ | ||
| 1225 | ret = -EFAULT; | ||
| 1226 | ehca_err(ibqp->device, "AQP1 was not created for " | ||
| 1227 | "port=%x", attr->port_num); | ||
| 1228 | goto modify_qp_exit2; | ||
| 1229 | } | ||
| 1230 | aqp1 = container_of(sport->ibqp_sqp[IB_QPT_GSI], | ||
| 1231 | struct ehca_qp, ib_qp); | ||
| 1232 | if (ibqp->qp_type != IB_QPT_GSI && | ||
| 1233 | ibqp->qp_type != IB_QPT_SMI && | ||
| 1234 | aqp1->mod_qp_parm) { | ||
| 1235 | /* | ||
| 1236 | * firmware will reject this modify_qp() because | ||
| 1237 | * port is not activated/initialized fully | ||
| 1238 | */ | ||
| 1239 | ret = -EFAULT; | ||
| 1240 | ehca_warn(ibqp->device, "Couldn't modify qp port=%x: " | ||
| 1241 | "either port is being activated (try again) " | ||
| 1242 | "or cabling issue", attr->port_num); | ||
| 1243 | goto modify_qp_exit2; | ||
| 1244 | } | ||
| 1191 | mqpcb->prim_phys_port = attr->port_num; | 1245 | mqpcb->prim_phys_port = attr->port_num; |
| 1192 | update_mask |= EHCA_BMASK_SET(MQPCB_MASK_PRIM_PHYS_PORT, 1); | 1246 | update_mask |= EHCA_BMASK_SET(MQPCB_MASK_PRIM_PHYS_PORT, 1); |
| 1193 | } | 1247 | } |
| @@ -1244,6 +1298,8 @@ static int internal_modify_qp(struct ib_qp *ibqp, | |||
| 1244 | } | 1298 | } |
| 1245 | 1299 | ||
| 1246 | if (attr_mask & IB_QP_PATH_MTU) { | 1300 | if (attr_mask & IB_QP_PATH_MTU) { |
| 1301 | /* store ld(MTU) */ | ||
| 1302 | my_qp->mtu_shift = attr->path_mtu + 7; | ||
| 1247 | mqpcb->path_mtu = attr->path_mtu; | 1303 | mqpcb->path_mtu = attr->path_mtu; |
| 1248 | update_mask |= EHCA_BMASK_SET(MQPCB_MASK_PATH_MTU, 1); | 1304 | update_mask |= EHCA_BMASK_SET(MQPCB_MASK_PATH_MTU, 1); |
| 1249 | } | 1305 | } |
| @@ -1467,6 +1523,8 @@ modify_qp_exit1: | |||
| 1467 | int ehca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, | 1523 | int ehca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, |
| 1468 | struct ib_udata *udata) | 1524 | struct ib_udata *udata) |
| 1469 | { | 1525 | { |
| 1526 | struct ehca_shca *shca = container_of(ibqp->device, struct ehca_shca, | ||
| 1527 | ib_device); | ||
| 1470 | struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp); | 1528 | struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp); |
| 1471 | struct ehca_pd *my_pd = container_of(my_qp->ib_qp.pd, struct ehca_pd, | 1529 | struct ehca_pd *my_pd = container_of(my_qp->ib_qp.pd, struct ehca_pd, |
| 1472 | ib_pd); | 1530 | ib_pd); |
| @@ -1479,9 +1537,100 @@ int ehca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, | |||
| 1479 | return -EINVAL; | 1537 | return -EINVAL; |
| 1480 | } | 1538 | } |
| 1481 | 1539 | ||
| 1540 | /* The if-block below caches qp_attr to be modified for GSI and SMI | ||
| 1541 | * qps during the initialization by ib_mad. When the respective port | ||
| 1542 | * is activated, ie we got an event PORT_ACTIVE, we'll replay the | ||
| 1543 | * cached modify calls sequence, see ehca_recover_sqs() below. | ||
| 1544 | * Why that is required: | ||
| 1545 | * 1) If one port is connected, older code requires that port one | ||
| 1546 | * to be connected and module option nr_ports=1 to be given by | ||
| 1547 | * user, which is very inconvenient for end user. | ||
| 1548 | * 2) Firmware accepts modify_qp() only if respective port has become | ||
| 1549 | * active. Older code had a wait loop of 30sec create_qp()/ | ||
| 1550 | * define_aqp1(), which is not appropriate in practice. This | ||
| 1551 | * code now removes that wait loop, see define_aqp1(), and always | ||
| 1552 | * reports all ports to ib_mad resp. users. Only activated ports | ||
| 1553 | * will then usable for the users. | ||
| 1554 | */ | ||
| 1555 | if (ibqp->qp_type == IB_QPT_GSI || ibqp->qp_type == IB_QPT_SMI) { | ||
| 1556 | int port = my_qp->init_attr.port_num; | ||
| 1557 | struct ehca_sport *sport = &shca->sport[port - 1]; | ||
| 1558 | unsigned long flags; | ||
| 1559 | spin_lock_irqsave(&sport->mod_sqp_lock, flags); | ||
| 1560 | /* cache qp_attr only during init */ | ||
| 1561 | if (my_qp->mod_qp_parm) { | ||
| 1562 | struct ehca_mod_qp_parm *p; | ||
| 1563 | if (my_qp->mod_qp_parm_idx >= EHCA_MOD_QP_PARM_MAX) { | ||
| 1564 | ehca_err(&shca->ib_device, | ||
| 1565 | "mod_qp_parm overflow state=%x port=%x" | ||
| 1566 | " type=%x", attr->qp_state, | ||
| 1567 | my_qp->init_attr.port_num, | ||
| 1568 | ibqp->qp_type); | ||
| 1569 | spin_unlock_irqrestore(&sport->mod_sqp_lock, | ||
| 1570 | flags); | ||
| 1571 | return -EINVAL; | ||
| 1572 | } | ||
| 1573 | p = &my_qp->mod_qp_parm[my_qp->mod_qp_parm_idx]; | ||
| 1574 | p->mask = attr_mask; | ||
| 1575 | p->attr = *attr; | ||
| 1576 | my_qp->mod_qp_parm_idx++; | ||
| 1577 | ehca_dbg(&shca->ib_device, | ||
| 1578 | "Saved qp_attr for state=%x port=%x type=%x", | ||
| 1579 | attr->qp_state, my_qp->init_attr.port_num, | ||
| 1580 | ibqp->qp_type); | ||
| 1581 | spin_unlock_irqrestore(&sport->mod_sqp_lock, flags); | ||
| 1582 | return 0; | ||
| 1583 | } | ||
| 1584 | spin_unlock_irqrestore(&sport->mod_sqp_lock, flags); | ||
| 1585 | } | ||
| 1586 | |||
| 1482 | return internal_modify_qp(ibqp, attr, attr_mask, 0); | 1587 | return internal_modify_qp(ibqp, attr, attr_mask, 0); |
| 1483 | } | 1588 | } |
| 1484 | 1589 | ||
| 1590 | void ehca_recover_sqp(struct ib_qp *sqp) | ||
| 1591 | { | ||
| 1592 | struct ehca_qp *my_sqp = container_of(sqp, struct ehca_qp, ib_qp); | ||
| 1593 | int port = my_sqp->init_attr.port_num; | ||
| 1594 | struct ib_qp_attr attr; | ||
| 1595 | struct ehca_mod_qp_parm *qp_parm; | ||
| 1596 | int i, qp_parm_idx, ret; | ||
| 1597 | unsigned long flags, wr_cnt; | ||
| 1598 | |||
| 1599 | if (!my_sqp->mod_qp_parm) | ||
| 1600 | return; | ||
| 1601 | ehca_dbg(sqp->device, "SQP port=%x qp_num=%x", port, sqp->qp_num); | ||
| 1602 | |||
| 1603 | qp_parm = my_sqp->mod_qp_parm; | ||
| 1604 | qp_parm_idx = my_sqp->mod_qp_parm_idx; | ||
| 1605 | for (i = 0; i < qp_parm_idx; i++) { | ||
| 1606 | attr = qp_parm[i].attr; | ||
| 1607 | ret = internal_modify_qp(sqp, &attr, qp_parm[i].mask, 0); | ||
| 1608 | if (ret) { | ||
| 1609 | ehca_err(sqp->device, "Could not modify SQP port=%x " | ||
| 1610 | "qp_num=%x ret=%x", port, sqp->qp_num, ret); | ||
| 1611 | goto free_qp_parm; | ||
| 1612 | } | ||
| 1613 | ehca_dbg(sqp->device, "SQP port=%x qp_num=%x in state=%x", | ||
| 1614 | port, sqp->qp_num, attr.qp_state); | ||
| 1615 | } | ||
| 1616 | |||
| 1617 | /* re-trigger posted recv wrs */ | ||
| 1618 | wr_cnt = my_sqp->ipz_rqueue.current_q_offset / | ||
| 1619 | my_sqp->ipz_rqueue.qe_size; | ||
| 1620 | if (wr_cnt) { | ||
| 1621 | spin_lock_irqsave(&my_sqp->spinlock_r, flags); | ||
| 1622 | hipz_update_rqa(my_sqp, wr_cnt); | ||
| 1623 | spin_unlock_irqrestore(&my_sqp->spinlock_r, flags); | ||
| 1624 | ehca_dbg(sqp->device, "doorbell port=%x qp_num=%x wr_cnt=%lx", | ||
| 1625 | port, sqp->qp_num, wr_cnt); | ||
| 1626 | } | ||
| 1627 | |||
| 1628 | free_qp_parm: | ||
| 1629 | kfree(qp_parm); | ||
| 1630 | /* this prevents subsequent calls to modify_qp() to cache qp_attr */ | ||
| 1631 | my_sqp->mod_qp_parm = NULL; | ||
| 1632 | } | ||
| 1633 | |||
| 1485 | int ehca_query_qp(struct ib_qp *qp, | 1634 | int ehca_query_qp(struct ib_qp *qp, |
| 1486 | struct ib_qp_attr *qp_attr, | 1635 | struct ib_qp_attr *qp_attr, |
| 1487 | int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr) | 1636 | int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr) |
| @@ -1769,6 +1918,7 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp, | |||
| 1769 | struct ehca_shca *shca = container_of(dev, struct ehca_shca, ib_device); | 1918 | struct ehca_shca *shca = container_of(dev, struct ehca_shca, ib_device); |
| 1770 | struct ehca_pd *my_pd = container_of(my_qp->ib_qp.pd, struct ehca_pd, | 1919 | struct ehca_pd *my_pd = container_of(my_qp->ib_qp.pd, struct ehca_pd, |
| 1771 | ib_pd); | 1920 | ib_pd); |
| 1921 | struct ehca_sport *sport = &shca->sport[my_qp->init_attr.port_num - 1]; | ||
| 1772 | u32 cur_pid = current->tgid; | 1922 | u32 cur_pid = current->tgid; |
| 1773 | u32 qp_num = my_qp->real_qp_num; | 1923 | u32 qp_num = my_qp->real_qp_num; |
| 1774 | int ret; | 1924 | int ret; |
| @@ -1815,6 +1965,14 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp, | |||
| 1815 | port_num = my_qp->init_attr.port_num; | 1965 | port_num = my_qp->init_attr.port_num; |
| 1816 | qp_type = my_qp->init_attr.qp_type; | 1966 | qp_type = my_qp->init_attr.qp_type; |
| 1817 | 1967 | ||
| 1968 | if (qp_type == IB_QPT_SMI || qp_type == IB_QPT_GSI) { | ||
| 1969 | spin_lock_irqsave(&sport->mod_sqp_lock, flags); | ||
| 1970 | kfree(my_qp->mod_qp_parm); | ||
| 1971 | my_qp->mod_qp_parm = NULL; | ||
| 1972 | shca->sport[port_num - 1].ibqp_sqp[qp_type] = NULL; | ||
| 1973 | spin_unlock_irqrestore(&sport->mod_sqp_lock, flags); | ||
| 1974 | } | ||
| 1975 | |||
| 1818 | /* no support for IB_QPT_SMI yet */ | 1976 | /* no support for IB_QPT_SMI yet */ |
| 1819 | if (qp_type == IB_QPT_GSI) { | 1977 | if (qp_type == IB_QPT_GSI) { |
| 1820 | struct ib_event event; | 1978 | struct ib_event event; |
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c index ea91360835d3..3aacc8cf1e44 100644 --- a/drivers/infiniband/hw/ehca/ehca_reqs.c +++ b/drivers/infiniband/hw/ehca/ehca_reqs.c | |||
| @@ -50,6 +50,9 @@ | |||
| 50 | #include "hcp_if.h" | 50 | #include "hcp_if.h" |
| 51 | #include "hipz_fns.h" | 51 | #include "hipz_fns.h" |
| 52 | 52 | ||
| 53 | /* in RC traffic, insert an empty RDMA READ every this many packets */ | ||
| 54 | #define ACK_CIRC_THRESHOLD 2000000 | ||
| 55 | |||
| 53 | static inline int ehca_write_rwqe(struct ipz_queue *ipz_rqueue, | 56 | static inline int ehca_write_rwqe(struct ipz_queue *ipz_rqueue, |
| 54 | struct ehca_wqe *wqe_p, | 57 | struct ehca_wqe *wqe_p, |
| 55 | struct ib_recv_wr *recv_wr) | 58 | struct ib_recv_wr *recv_wr) |
| @@ -81,7 +84,7 @@ static inline int ehca_write_rwqe(struct ipz_queue *ipz_rqueue, | |||
| 81 | if (ehca_debug_level) { | 84 | if (ehca_debug_level) { |
| 82 | ehca_gen_dbg("RECEIVE WQE written into ipz_rqueue=%p", | 85 | ehca_gen_dbg("RECEIVE WQE written into ipz_rqueue=%p", |
| 83 | ipz_rqueue); | 86 | ipz_rqueue); |
| 84 | ehca_dmp( wqe_p, 16*(6 + wqe_p->nr_of_data_seg), "recv wqe"); | 87 | ehca_dmp(wqe_p, 16*(6 + wqe_p->nr_of_data_seg), "recv wqe"); |
| 85 | } | 88 | } |
| 86 | 89 | ||
| 87 | return 0; | 90 | return 0; |
| @@ -135,7 +138,8 @@ static void trace_send_wr_ud(const struct ib_send_wr *send_wr) | |||
| 135 | 138 | ||
| 136 | static inline int ehca_write_swqe(struct ehca_qp *qp, | 139 | static inline int ehca_write_swqe(struct ehca_qp *qp, |
| 137 | struct ehca_wqe *wqe_p, | 140 | struct ehca_wqe *wqe_p, |
| 138 | const struct ib_send_wr *send_wr) | 141 | const struct ib_send_wr *send_wr, |
| 142 | int hidden) | ||
| 139 | { | 143 | { |
| 140 | u32 idx; | 144 | u32 idx; |
| 141 | u64 dma_length; | 145 | u64 dma_length; |
| @@ -176,7 +180,9 @@ static inline int ehca_write_swqe(struct ehca_qp *qp, | |||
| 176 | 180 | ||
| 177 | wqe_p->wr_flag = 0; | 181 | wqe_p->wr_flag = 0; |
| 178 | 182 | ||
| 179 | if (send_wr->send_flags & IB_SEND_SIGNALED) | 183 | if ((send_wr->send_flags & IB_SEND_SIGNALED || |
| 184 | qp->init_attr.sq_sig_type == IB_SIGNAL_ALL_WR) | ||
| 185 | && !hidden) | ||
| 180 | wqe_p->wr_flag |= WQE_WRFLAG_REQ_SIGNAL_COM; | 186 | wqe_p->wr_flag |= WQE_WRFLAG_REQ_SIGNAL_COM; |
| 181 | 187 | ||
| 182 | if (send_wr->opcode == IB_WR_SEND_WITH_IMM || | 188 | if (send_wr->opcode == IB_WR_SEND_WITH_IMM || |
| @@ -199,7 +205,7 @@ static inline int ehca_write_swqe(struct ehca_qp *qp, | |||
| 199 | 205 | ||
| 200 | wqe_p->destination_qp_number = send_wr->wr.ud.remote_qpn << 8; | 206 | wqe_p->destination_qp_number = send_wr->wr.ud.remote_qpn << 8; |
| 201 | wqe_p->local_ee_context_qkey = remote_qkey; | 207 | wqe_p->local_ee_context_qkey = remote_qkey; |
| 202 | if (!send_wr->wr.ud.ah) { | 208 | if (unlikely(!send_wr->wr.ud.ah)) { |
| 203 | ehca_gen_err("wr.ud.ah is NULL. qp=%p", qp); | 209 | ehca_gen_err("wr.ud.ah is NULL. qp=%p", qp); |
| 204 | return -EINVAL; | 210 | return -EINVAL; |
| 205 | } | 211 | } |
| @@ -255,6 +261,15 @@ static inline int ehca_write_swqe(struct ehca_qp *qp, | |||
| 255 | } /* eof idx */ | 261 | } /* eof idx */ |
| 256 | wqe_p->u.nud.atomic_1st_op_dma_len = dma_length; | 262 | wqe_p->u.nud.atomic_1st_op_dma_len = dma_length; |
| 257 | 263 | ||
| 264 | /* unsolicited ack circumvention */ | ||
| 265 | if (send_wr->opcode == IB_WR_RDMA_READ) { | ||
| 266 | /* on RDMA read, switch on and reset counters */ | ||
| 267 | qp->message_count = qp->packet_count = 0; | ||
| 268 | qp->unsol_ack_circ = 1; | ||
| 269 | } else | ||
| 270 | /* else estimate #packets */ | ||
| 271 | qp->packet_count += (dma_length >> qp->mtu_shift) + 1; | ||
| 272 | |||
| 258 | break; | 273 | break; |
| 259 | 274 | ||
| 260 | default: | 275 | default: |
| @@ -355,13 +370,49 @@ static inline void map_ib_wc_status(u32 cqe_status, | |||
| 355 | *wc_status = IB_WC_SUCCESS; | 370 | *wc_status = IB_WC_SUCCESS; |
| 356 | } | 371 | } |
| 357 | 372 | ||
| 373 | static inline int post_one_send(struct ehca_qp *my_qp, | ||
| 374 | struct ib_send_wr *cur_send_wr, | ||
| 375 | struct ib_send_wr **bad_send_wr, | ||
| 376 | int hidden) | ||
| 377 | { | ||
| 378 | struct ehca_wqe *wqe_p; | ||
| 379 | int ret; | ||
| 380 | u64 start_offset = my_qp->ipz_squeue.current_q_offset; | ||
| 381 | |||
| 382 | /* get pointer next to free WQE */ | ||
| 383 | wqe_p = ipz_qeit_get_inc(&my_qp->ipz_squeue); | ||
| 384 | if (unlikely(!wqe_p)) { | ||
| 385 | /* too many posted work requests: queue overflow */ | ||
| 386 | if (bad_send_wr) | ||
| 387 | *bad_send_wr = cur_send_wr; | ||
| 388 | ehca_err(my_qp->ib_qp.device, "Too many posted WQEs " | ||
| 389 | "qp_num=%x", my_qp->ib_qp.qp_num); | ||
| 390 | return -ENOMEM; | ||
| 391 | } | ||
| 392 | /* write a SEND WQE into the QUEUE */ | ||
| 393 | ret = ehca_write_swqe(my_qp, wqe_p, cur_send_wr, hidden); | ||
| 394 | /* | ||
| 395 | * if something failed, | ||
| 396 | * reset the free entry pointer to the start value | ||
| 397 | */ | ||
| 398 | if (unlikely(ret)) { | ||
| 399 | my_qp->ipz_squeue.current_q_offset = start_offset; | ||
| 400 | if (bad_send_wr) | ||
| 401 | *bad_send_wr = cur_send_wr; | ||
| 402 | ehca_err(my_qp->ib_qp.device, "Could not write WQE " | ||
| 403 | "qp_num=%x", my_qp->ib_qp.qp_num); | ||
| 404 | return -EINVAL; | ||
| 405 | } | ||
| 406 | |||
| 407 | return 0; | ||
| 408 | } | ||
| 409 | |||
| 358 | int ehca_post_send(struct ib_qp *qp, | 410 | int ehca_post_send(struct ib_qp *qp, |
| 359 | struct ib_send_wr *send_wr, | 411 | struct ib_send_wr *send_wr, |
| 360 | struct ib_send_wr **bad_send_wr) | 412 | struct ib_send_wr **bad_send_wr) |
| 361 | { | 413 | { |
| 362 | struct ehca_qp *my_qp = container_of(qp, struct ehca_qp, ib_qp); | 414 | struct ehca_qp *my_qp = container_of(qp, struct ehca_qp, ib_qp); |
| 363 | struct ib_send_wr *cur_send_wr; | 415 | struct ib_send_wr *cur_send_wr; |
| 364 | struct ehca_wqe *wqe_p; | ||
| 365 | int wqe_cnt = 0; | 416 | int wqe_cnt = 0; |
| 366 | int ret = 0; | 417 | int ret = 0; |
| 367 | unsigned long flags; | 418 | unsigned long flags; |
| @@ -369,37 +420,33 @@ int ehca_post_send(struct ib_qp *qp, | |||
| 369 | /* LOCK the QUEUE */ | 420 | /* LOCK the QUEUE */ |
| 370 | spin_lock_irqsave(&my_qp->spinlock_s, flags); | 421 | spin_lock_irqsave(&my_qp->spinlock_s, flags); |
| 371 | 422 | ||
| 423 | /* Send an empty extra RDMA read if: | ||
| 424 | * 1) there has been an RDMA read on this connection before | ||
| 425 | * 2) no RDMA read occurred for ACK_CIRC_THRESHOLD link packets | ||
| 426 | * 3) we can be sure that any previous extra RDMA read has been | ||
| 427 | * processed so we don't overflow the SQ | ||
| 428 | */ | ||
| 429 | if (unlikely(my_qp->unsol_ack_circ && | ||
| 430 | my_qp->packet_count > ACK_CIRC_THRESHOLD && | ||
| 431 | my_qp->message_count > my_qp->init_attr.cap.max_send_wr)) { | ||
| 432 | /* insert an empty RDMA READ to fix up the remote QP state */ | ||
| 433 | struct ib_send_wr circ_wr; | ||
| 434 | memset(&circ_wr, 0, sizeof(circ_wr)); | ||
| 435 | circ_wr.opcode = IB_WR_RDMA_READ; | ||
| 436 | post_one_send(my_qp, &circ_wr, NULL, 1); /* ignore retcode */ | ||
| 437 | wqe_cnt++; | ||
| 438 | ehca_dbg(qp->device, "posted circ wr qp_num=%x", qp->qp_num); | ||
| 439 | my_qp->message_count = my_qp->packet_count = 0; | ||
| 440 | } | ||
| 441 | |||
| 372 | /* loop processes list of send reqs */ | 442 | /* loop processes list of send reqs */ |
| 373 | for (cur_send_wr = send_wr; cur_send_wr != NULL; | 443 | for (cur_send_wr = send_wr; cur_send_wr != NULL; |
| 374 | cur_send_wr = cur_send_wr->next) { | 444 | cur_send_wr = cur_send_wr->next) { |
| 375 | u64 start_offset = my_qp->ipz_squeue.current_q_offset; | 445 | ret = post_one_send(my_qp, cur_send_wr, bad_send_wr, 0); |
| 376 | /* get pointer next to free WQE */ | ||
| 377 | wqe_p = ipz_qeit_get_inc(&my_qp->ipz_squeue); | ||
| 378 | if (unlikely(!wqe_p)) { | ||
| 379 | /* too many posted work requests: queue overflow */ | ||
| 380 | if (bad_send_wr) | ||
| 381 | *bad_send_wr = cur_send_wr; | ||
| 382 | if (wqe_cnt == 0) { | ||
| 383 | ret = -ENOMEM; | ||
| 384 | ehca_err(qp->device, "Too many posted WQEs " | ||
| 385 | "qp_num=%x", qp->qp_num); | ||
| 386 | } | ||
| 387 | goto post_send_exit0; | ||
| 388 | } | ||
| 389 | /* write a SEND WQE into the QUEUE */ | ||
| 390 | ret = ehca_write_swqe(my_qp, wqe_p, cur_send_wr); | ||
| 391 | /* | ||
| 392 | * if something failed, | ||
| 393 | * reset the free entry pointer to the start value | ||
| 394 | */ | ||
| 395 | if (unlikely(ret)) { | 446 | if (unlikely(ret)) { |
| 396 | my_qp->ipz_squeue.current_q_offset = start_offset; | 447 | /* if one or more WQEs were successful, don't fail */ |
| 397 | *bad_send_wr = cur_send_wr; | 448 | if (wqe_cnt) |
| 398 | if (wqe_cnt == 0) { | 449 | ret = 0; |
| 399 | ret = -EINVAL; | ||
| 400 | ehca_err(qp->device, "Could not write WQE " | ||
| 401 | "qp_num=%x", qp->qp_num); | ||
| 402 | } | ||
| 403 | goto post_send_exit0; | 450 | goto post_send_exit0; |
| 404 | } | 451 | } |
| 405 | wqe_cnt++; | 452 | wqe_cnt++; |
| @@ -410,6 +457,7 @@ int ehca_post_send(struct ib_qp *qp, | |||
| 410 | post_send_exit0: | 457 | post_send_exit0: |
| 411 | iosync(); /* serialize GAL register access */ | 458 | iosync(); /* serialize GAL register access */ |
| 412 | hipz_update_sqa(my_qp, wqe_cnt); | 459 | hipz_update_sqa(my_qp, wqe_cnt); |
| 460 | my_qp->message_count += wqe_cnt; | ||
| 413 | spin_unlock_irqrestore(&my_qp->spinlock_s, flags); | 461 | spin_unlock_irqrestore(&my_qp->spinlock_s, flags); |
| 414 | return ret; | 462 | return ret; |
| 415 | } | 463 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_sqp.c b/drivers/infiniband/hw/ehca/ehca_sqp.c index f0792e5fbd02..79e72b25b252 100644 --- a/drivers/infiniband/hw/ehca/ehca_sqp.c +++ b/drivers/infiniband/hw/ehca/ehca_sqp.c | |||
| @@ -40,11 +40,8 @@ | |||
| 40 | */ | 40 | */ |
| 41 | 41 | ||
| 42 | 42 | ||
| 43 | #include <linux/module.h> | ||
| 44 | #include <linux/err.h> | ||
| 45 | #include "ehca_classes.h" | 43 | #include "ehca_classes.h" |
| 46 | #include "ehca_tools.h" | 44 | #include "ehca_tools.h" |
| 47 | #include "ehca_qes.h" | ||
| 48 | #include "ehca_iverbs.h" | 45 | #include "ehca_iverbs.h" |
| 49 | #include "hcp_if.h" | 46 | #include "hcp_if.h" |
| 50 | 47 | ||
| @@ -93,6 +90,9 @@ u64 ehca_define_sqp(struct ehca_shca *shca, | |||
| 93 | return H_PARAMETER; | 90 | return H_PARAMETER; |
| 94 | } | 91 | } |
| 95 | 92 | ||
| 93 | if (ehca_nr_ports < 0) /* autodetect mode */ | ||
| 94 | return H_SUCCESS; | ||
| 95 | |||
| 96 | for (counter = 0; | 96 | for (counter = 0; |
| 97 | shca->sport[port - 1].port_state != IB_PORT_ACTIVE && | 97 | shca->sport[port - 1].port_state != IB_PORT_ACTIVE && |
| 98 | counter < ehca_port_act_time; | 98 | counter < ehca_port_act_time; |
diff --git a/drivers/infiniband/hw/ipath/ipath_common.h b/drivers/infiniband/hw/ipath/ipath_common.h index 851df8a75e79..414621095540 100644 --- a/drivers/infiniband/hw/ipath/ipath_common.h +++ b/drivers/infiniband/hw/ipath/ipath_common.h | |||
| @@ -82,6 +82,16 @@ | |||
| 82 | #define IPATH_IB_LINK_EXTERNAL 7 /* normal, disable local loopback */ | 82 | #define IPATH_IB_LINK_EXTERNAL 7 /* normal, disable local loopback */ |
| 83 | 83 | ||
| 84 | /* | 84 | /* |
| 85 | * These 3 values (SDR and DDR may be ORed for auto-speed | ||
| 86 | * negotiation) are used for the 3rd argument to path_f_set_ib_cfg | ||
| 87 | * with cmd IPATH_IB_CFG_SPD_ENB, by direct calls or via sysfs. They | ||
| 88 | * are also the the possible values for ipath_link_speed_enabled and active | ||
| 89 | * The values were chosen to match values used within the IB spec. | ||
| 90 | */ | ||
| 91 | #define IPATH_IB_SDR 1 | ||
| 92 | #define IPATH_IB_DDR 2 | ||
| 93 | |||
| 94 | /* | ||
| 85 | * stats maintained by the driver. For now, at least, this is global | 95 | * stats maintained by the driver. For now, at least, this is global |
| 86 | * to all minor devices. | 96 | * to all minor devices. |
| 87 | */ | 97 | */ |
| @@ -433,8 +443,9 @@ struct ipath_user_info { | |||
| 433 | #define IPATH_CMD_UNUSED_2 26 | 443 | #define IPATH_CMD_UNUSED_2 26 |
| 434 | #define IPATH_CMD_PIOAVAILUPD 27 /* force an update of PIOAvail reg */ | 444 | #define IPATH_CMD_PIOAVAILUPD 27 /* force an update of PIOAvail reg */ |
| 435 | #define IPATH_CMD_POLL_TYPE 28 /* set the kind of polling we want */ | 445 | #define IPATH_CMD_POLL_TYPE 28 /* set the kind of polling we want */ |
| 446 | #define IPATH_CMD_ARMLAUNCH_CTRL 29 /* armlaunch detection control */ | ||
| 436 | 447 | ||
| 437 | #define IPATH_CMD_MAX 28 | 448 | #define IPATH_CMD_MAX 29 |
| 438 | 449 | ||
| 439 | /* | 450 | /* |
| 440 | * Poll types | 451 | * Poll types |
| @@ -477,6 +488,8 @@ struct ipath_cmd { | |||
| 477 | __u64 port_info; | 488 | __u64 port_info; |
| 478 | /* enable/disable receipt of packets */ | 489 | /* enable/disable receipt of packets */ |
| 479 | __u32 recv_ctrl; | 490 | __u32 recv_ctrl; |
| 491 | /* enable/disable armlaunch errors (non-zero to enable) */ | ||
| 492 | __u32 armlaunch_ctrl; | ||
| 480 | /* partition key to set */ | 493 | /* partition key to set */ |
| 481 | __u16 part_key; | 494 | __u16 part_key; |
| 482 | /* user address of __u32 bitmask of active slaves */ | 495 | /* user address of __u32 bitmask of active slaves */ |
| @@ -579,7 +592,7 @@ struct ipath_flash { | |||
| 579 | struct infinipath_counters { | 592 | struct infinipath_counters { |
| 580 | __u64 LBIntCnt; | 593 | __u64 LBIntCnt; |
| 581 | __u64 LBFlowStallCnt; | 594 | __u64 LBFlowStallCnt; |
| 582 | __u64 Reserved1; | 595 | __u64 TxSDmaDescCnt; /* was Reserved1 */ |
| 583 | __u64 TxUnsupVLErrCnt; | 596 | __u64 TxUnsupVLErrCnt; |
| 584 | __u64 TxDataPktCnt; | 597 | __u64 TxDataPktCnt; |
| 585 | __u64 TxFlowPktCnt; | 598 | __u64 TxFlowPktCnt; |
| @@ -615,12 +628,26 @@ struct infinipath_counters { | |||
| 615 | __u64 RxP6HdrEgrOvflCnt; | 628 | __u64 RxP6HdrEgrOvflCnt; |
| 616 | __u64 RxP7HdrEgrOvflCnt; | 629 | __u64 RxP7HdrEgrOvflCnt; |
| 617 | __u64 RxP8HdrEgrOvflCnt; | 630 | __u64 RxP8HdrEgrOvflCnt; |
| 618 | __u64 Reserved6; | 631 | __u64 RxP9HdrEgrOvflCnt; /* was Reserved6 */ |
| 619 | __u64 Reserved7; | 632 | __u64 RxP10HdrEgrOvflCnt; /* was Reserved7 */ |
| 633 | __u64 RxP11HdrEgrOvflCnt; /* new for IBA7220 */ | ||
| 634 | __u64 RxP12HdrEgrOvflCnt; /* new for IBA7220 */ | ||
| 635 | __u64 RxP13HdrEgrOvflCnt; /* new for IBA7220 */ | ||
| 636 | __u64 RxP14HdrEgrOvflCnt; /* new for IBA7220 */ | ||
| 637 | __u64 RxP15HdrEgrOvflCnt; /* new for IBA7220 */ | ||
| 638 | __u64 RxP16HdrEgrOvflCnt; /* new for IBA7220 */ | ||
| 620 | __u64 IBStatusChangeCnt; | 639 | __u64 IBStatusChangeCnt; |
| 621 | __u64 IBLinkErrRecoveryCnt; | 640 | __u64 IBLinkErrRecoveryCnt; |
| 622 | __u64 IBLinkDownedCnt; | 641 | __u64 IBLinkDownedCnt; |
| 623 | __u64 IBSymbolErrCnt; | 642 | __u64 IBSymbolErrCnt; |
| 643 | /* The following are new for IBA7220 */ | ||
| 644 | __u64 RxVL15DroppedPktCnt; | ||
| 645 | __u64 RxOtherLocalPhyErrCnt; | ||
| 646 | __u64 PcieRetryBufDiagQwordCnt; | ||
| 647 | __u64 ExcessBufferOvflCnt; | ||
| 648 | __u64 LocalLinkIntegrityErrCnt; | ||
| 649 | __u64 RxVlErrCnt; | ||
| 650 | __u64 RxDlidFltrCnt; | ||
| 624 | }; | 651 | }; |
| 625 | 652 | ||
| 626 | /* | 653 | /* |
diff --git a/drivers/infiniband/hw/ipath/ipath_cq.c b/drivers/infiniband/hw/ipath/ipath_cq.c index d1380c7a1703..a03bd28d9b48 100644 --- a/drivers/infiniband/hw/ipath/ipath_cq.c +++ b/drivers/infiniband/hw/ipath/ipath_cq.c | |||
| @@ -421,7 +421,7 @@ int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata) | |||
| 421 | else | 421 | else |
| 422 | n = head - tail; | 422 | n = head - tail; |
| 423 | if (unlikely((u32)cqe < n)) { | 423 | if (unlikely((u32)cqe < n)) { |
| 424 | ret = -EOVERFLOW; | 424 | ret = -EINVAL; |
| 425 | goto bail_unlock; | 425 | goto bail_unlock; |
| 426 | } | 426 | } |
| 427 | for (n = 0; tail != head; n++) { | 427 | for (n = 0; tail != head; n++) { |
diff --git a/drivers/infiniband/hw/ipath/ipath_debug.h b/drivers/infiniband/hw/ipath/ipath_debug.h index 19c56e6491eb..d6f69532d83f 100644 --- a/drivers/infiniband/hw/ipath/ipath_debug.h +++ b/drivers/infiniband/hw/ipath/ipath_debug.h | |||
| @@ -55,7 +55,7 @@ | |||
| 55 | #define __IPATH_PKTDBG 0x80 /* print packet data */ | 55 | #define __IPATH_PKTDBG 0x80 /* print packet data */ |
| 56 | /* print process startup (init)/exit messages */ | 56 | /* print process startup (init)/exit messages */ |
| 57 | #define __IPATH_PROCDBG 0x100 | 57 | #define __IPATH_PROCDBG 0x100 |
| 58 | /* print mmap/nopage stuff, not using VDBG any more */ | 58 | /* print mmap/fault stuff, not using VDBG any more */ |
| 59 | #define __IPATH_MMDBG 0x200 | 59 | #define __IPATH_MMDBG 0x200 |
| 60 | #define __IPATH_ERRPKTDBG 0x400 | 60 | #define __IPATH_ERRPKTDBG 0x400 |
| 61 | #define __IPATH_USER_SEND 0x1000 /* use user mode send */ | 61 | #define __IPATH_USER_SEND 0x1000 /* use user mode send */ |
| @@ -81,7 +81,7 @@ | |||
| 81 | #define __IPATH_VERBDBG 0x0 /* very verbose debug */ | 81 | #define __IPATH_VERBDBG 0x0 /* very verbose debug */ |
| 82 | #define __IPATH_PKTDBG 0x0 /* print packet data */ | 82 | #define __IPATH_PKTDBG 0x0 /* print packet data */ |
| 83 | #define __IPATH_PROCDBG 0x0 /* process startup (init)/exit messages */ | 83 | #define __IPATH_PROCDBG 0x0 /* process startup (init)/exit messages */ |
| 84 | /* print mmap/nopage stuff, not using VDBG any more */ | 84 | /* print mmap/fault stuff, not using VDBG any more */ |
| 85 | #define __IPATH_MMDBG 0x0 | 85 | #define __IPATH_MMDBG 0x0 |
| 86 | #define __IPATH_EPKTDBG 0x0 /* print ethernet packet data */ | 86 | #define __IPATH_EPKTDBG 0x0 /* print ethernet packet data */ |
| 87 | #define __IPATH_IPATHDBG 0x0 /* Ethernet (IPATH) table dump on */ | 87 | #define __IPATH_IPATHDBG 0x0 /* Ethernet (IPATH) table dump on */ |
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index fc355981bbab..d5ff6ca2db30 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c | |||
| @@ -334,6 +334,8 @@ static void ipath_verify_pioperf(struct ipath_devdata *dd) | |||
| 334 | udelay(1); | 334 | udelay(1); |
| 335 | } | 335 | } |
| 336 | 336 | ||
| 337 | ipath_disable_armlaunch(dd); | ||
| 338 | |||
| 337 | writeq(0, piobuf); /* length 0, no dwords actually sent */ | 339 | writeq(0, piobuf); /* length 0, no dwords actually sent */ |
| 338 | ipath_flush_wc(); | 340 | ipath_flush_wc(); |
| 339 | 341 | ||
| @@ -365,6 +367,7 @@ static void ipath_verify_pioperf(struct ipath_devdata *dd) | |||
| 365 | done: | 367 | done: |
| 366 | /* disarm piobuf, so it's available again */ | 368 | /* disarm piobuf, so it's available again */ |
| 367 | ipath_disarm_piobufs(dd, pbnum, 1); | 369 | ipath_disarm_piobufs(dd, pbnum, 1); |
| 370 | ipath_enable_armlaunch(dd); | ||
| 368 | } | 371 | } |
| 369 | 372 | ||
| 370 | static int __devinit ipath_init_one(struct pci_dev *pdev, | 373 | static int __devinit ipath_init_one(struct pci_dev *pdev, |
| @@ -803,31 +806,37 @@ void ipath_disarm_piobufs(struct ipath_devdata *dd, unsigned first, | |||
| 803 | unsigned cnt) | 806 | unsigned cnt) |
| 804 | { | 807 | { |
| 805 | unsigned i, last = first + cnt; | 808 | unsigned i, last = first + cnt; |
| 806 | u64 sendctrl, sendorig; | 809 | unsigned long flags; |
| 807 | 810 | ||
| 808 | ipath_cdbg(PKT, "disarm %u PIObufs first=%u\n", cnt, first); | 811 | ipath_cdbg(PKT, "disarm %u PIObufs first=%u\n", cnt, first); |
| 809 | sendorig = dd->ipath_sendctrl; | ||
| 810 | for (i = first; i < last; i++) { | 812 | for (i = first; i < last; i++) { |
| 811 | sendctrl = sendorig | INFINIPATH_S_DISARM | | 813 | spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); |
| 812 | (i << INFINIPATH_S_DISARMPIOBUF_SHIFT); | 814 | /* |
| 815 | * The disarm-related bits are write-only, so it | ||
| 816 | * is ok to OR them in with our copy of sendctrl | ||
| 817 | * while we hold the lock. | ||
| 818 | */ | ||
| 813 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | 819 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, |
| 814 | sendctrl); | 820 | dd->ipath_sendctrl | INFINIPATH_S_DISARM | |
| 821 | (i << INFINIPATH_S_DISARMPIOBUF_SHIFT)); | ||
| 822 | /* can't disarm bufs back-to-back per iba7220 spec */ | ||
| 823 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | ||
| 824 | spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); | ||
| 815 | } | 825 | } |
| 816 | 826 | ||
| 817 | /* | 827 | /* |
| 818 | * Write it again with current value, in case ipath_sendctrl changed | 828 | * Disable PIOAVAILUPD, then re-enable, reading scratch in |
| 819 | * while we were looping; no critical bits that would require | ||
| 820 | * locking. | ||
| 821 | * | ||
| 822 | * disable PIOAVAILUPD, then re-enable, reading scratch in | ||
| 823 | * between. This seems to avoid a chip timing race that causes | 829 | * between. This seems to avoid a chip timing race that causes |
| 824 | * pioavail updates to memory to stop. | 830 | * pioavail updates to memory to stop. We xor as we don't |
| 831 | * know the state of the bit when we're called. | ||
| 825 | */ | 832 | */ |
| 833 | spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); | ||
| 826 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | 834 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, |
| 827 | sendorig & ~INFINIPATH_S_PIOBUFAVAILUPD); | 835 | dd->ipath_sendctrl ^ INFINIPATH_S_PIOBUFAVAILUPD); |
| 828 | sendorig = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | 836 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); |
| 829 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | 837 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, |
| 830 | dd->ipath_sendctrl); | 838 | dd->ipath_sendctrl); |
| 839 | spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); | ||
| 831 | } | 840 | } |
| 832 | 841 | ||
| 833 | /** | 842 | /** |
| @@ -1003,12 +1012,10 @@ static void get_rhf_errstring(u32 err, char *msg, size_t len) | |||
| 1003 | * ipath_get_egrbuf - get an eager buffer | 1012 | * ipath_get_egrbuf - get an eager buffer |
| 1004 | * @dd: the infinipath device | 1013 | * @dd: the infinipath device |
| 1005 | * @bufnum: the eager buffer to get | 1014 | * @bufnum: the eager buffer to get |
| 1006 | * @err: unused | ||
| 1007 | * | 1015 | * |
| 1008 | * must only be called if ipath_pd[port] is known to be allocated | 1016 | * must only be called if ipath_pd[port] is known to be allocated |
| 1009 | */ | 1017 | */ |
| 1010 | static inline void *ipath_get_egrbuf(struct ipath_devdata *dd, u32 bufnum, | 1018 | static inline void *ipath_get_egrbuf(struct ipath_devdata *dd, u32 bufnum) |
| 1011 | int err) | ||
| 1012 | { | 1019 | { |
| 1013 | return dd->ipath_port0_skbinfo ? | 1020 | return dd->ipath_port0_skbinfo ? |
| 1014 | (void *) dd->ipath_port0_skbinfo[bufnum].skb->data : NULL; | 1021 | (void *) dd->ipath_port0_skbinfo[bufnum].skb->data : NULL; |
| @@ -1100,13 +1107,14 @@ static void ipath_rcv_hdrerr(struct ipath_devdata *dd, | |||
| 1100 | 1107 | ||
| 1101 | /* | 1108 | /* |
| 1102 | * ipath_kreceive - receive a packet | 1109 | * ipath_kreceive - receive a packet |
| 1103 | * @dd: the infinipath device | 1110 | * @pd: the infinipath port |
| 1104 | * | 1111 | * |
| 1105 | * called from interrupt handler for errors or receive interrupt | 1112 | * called from interrupt handler for errors or receive interrupt |
| 1106 | */ | 1113 | */ |
| 1107 | void ipath_kreceive(struct ipath_devdata *dd) | 1114 | void ipath_kreceive(struct ipath_portdata *pd) |
| 1108 | { | 1115 | { |
| 1109 | u64 *rc; | 1116 | u64 *rc; |
| 1117 | struct ipath_devdata *dd = pd->port_dd; | ||
| 1110 | void *ebuf; | 1118 | void *ebuf; |
| 1111 | const u32 rsize = dd->ipath_rcvhdrentsize; /* words */ | 1119 | const u32 rsize = dd->ipath_rcvhdrentsize; /* words */ |
| 1112 | const u32 maxcnt = dd->ipath_rcvhdrcnt * rsize; /* words */ | 1120 | const u32 maxcnt = dd->ipath_rcvhdrcnt * rsize; /* words */ |
| @@ -1121,8 +1129,8 @@ void ipath_kreceive(struct ipath_devdata *dd) | |||
| 1121 | goto bail; | 1129 | goto bail; |
| 1122 | } | 1130 | } |
| 1123 | 1131 | ||
| 1124 | l = dd->ipath_port0head; | 1132 | l = pd->port_head; |
| 1125 | hdrqtail = (u32) le64_to_cpu(*dd->ipath_hdrqtailptr); | 1133 | hdrqtail = ipath_get_rcvhdrtail(pd); |
| 1126 | if (l == hdrqtail) | 1134 | if (l == hdrqtail) |
| 1127 | goto bail; | 1135 | goto bail; |
| 1128 | 1136 | ||
| @@ -1131,7 +1139,7 @@ reloop: | |||
| 1131 | u32 qp; | 1139 | u32 qp; |
| 1132 | u8 *bthbytes; | 1140 | u8 *bthbytes; |
| 1133 | 1141 | ||
| 1134 | rc = (u64 *) (dd->ipath_pd[0]->port_rcvhdrq + (l << 2)); | 1142 | rc = (u64 *) (pd->port_rcvhdrq + (l << 2)); |
| 1135 | hdr = (struct ipath_message_header *)&rc[1]; | 1143 | hdr = (struct ipath_message_header *)&rc[1]; |
| 1136 | /* | 1144 | /* |
| 1137 | * could make a network order version of IPATH_KD_QP, and | 1145 | * could make a network order version of IPATH_KD_QP, and |
| @@ -1156,7 +1164,7 @@ reloop: | |||
| 1156 | etail = ipath_hdrget_index((__le32 *) rc); | 1164 | etail = ipath_hdrget_index((__le32 *) rc); |
| 1157 | if (tlen > sizeof(*hdr) || | 1165 | if (tlen > sizeof(*hdr) || |
| 1158 | etype == RCVHQ_RCV_TYPE_NON_KD) | 1166 | etype == RCVHQ_RCV_TYPE_NON_KD) |
| 1159 | ebuf = ipath_get_egrbuf(dd, etail, 0); | 1167 | ebuf = ipath_get_egrbuf(dd, etail); |
| 1160 | } | 1168 | } |
| 1161 | 1169 | ||
| 1162 | /* | 1170 | /* |
| @@ -1191,7 +1199,7 @@ reloop: | |||
| 1191 | be32_to_cpu(hdr->bth[0]) & 0xff); | 1199 | be32_to_cpu(hdr->bth[0]) & 0xff); |
| 1192 | else { | 1200 | else { |
| 1193 | /* | 1201 | /* |
| 1194 | * error packet, type of error unknown. | 1202 | * error packet, type of error unknown. |
| 1195 | * Probably type 3, but we don't know, so don't | 1203 | * Probably type 3, but we don't know, so don't |
| 1196 | * even try to print the opcode, etc. | 1204 | * even try to print the opcode, etc. |
| 1197 | */ | 1205 | */ |
| @@ -1241,7 +1249,7 @@ reloop: | |||
| 1241 | * earlier packets, we "almost" guarantee we have covered | 1249 | * earlier packets, we "almost" guarantee we have covered |
| 1242 | * that case. | 1250 | * that case. |
| 1243 | */ | 1251 | */ |
| 1244 | u32 hqtail = (u32)le64_to_cpu(*dd->ipath_hdrqtailptr); | 1252 | u32 hqtail = ipath_get_rcvhdrtail(pd); |
| 1245 | if (hqtail != hdrqtail) { | 1253 | if (hqtail != hdrqtail) { |
| 1246 | hdrqtail = hqtail; | 1254 | hdrqtail = hqtail; |
| 1247 | reloop = 1; /* loop 1 extra time at most */ | 1255 | reloop = 1; /* loop 1 extra time at most */ |
| @@ -1251,7 +1259,7 @@ reloop: | |||
| 1251 | 1259 | ||
| 1252 | pkttot += i; | 1260 | pkttot += i; |
| 1253 | 1261 | ||
| 1254 | dd->ipath_port0head = l; | 1262 | pd->port_head = l; |
| 1255 | 1263 | ||
| 1256 | if (pkttot > ipath_stats.sps_maxpkts_call) | 1264 | if (pkttot > ipath_stats.sps_maxpkts_call) |
| 1257 | ipath_stats.sps_maxpkts_call = pkttot; | 1265 | ipath_stats.sps_maxpkts_call = pkttot; |
| @@ -1335,14 +1343,9 @@ static void ipath_update_pio_bufs(struct ipath_devdata *dd) | |||
| 1335 | /* | 1343 | /* |
| 1336 | * Chip Errata: bug 6641; even and odd qwords>3 are swapped | 1344 | * Chip Errata: bug 6641; even and odd qwords>3 are swapped |
| 1337 | */ | 1345 | */ |
| 1338 | if (i > 3) { | 1346 | if (i > 3 && (dd->ipath_flags & IPATH_SWAP_PIOBUFS)) |
| 1339 | if (i & 1) | 1347 | piov = le64_to_cpu(dd->ipath_pioavailregs_dma[i ^ 1]); |
| 1340 | piov = le64_to_cpu( | 1348 | else |
| 1341 | dd->ipath_pioavailregs_dma[i - 1]); | ||
| 1342 | else | ||
| 1343 | piov = le64_to_cpu( | ||
| 1344 | dd->ipath_pioavailregs_dma[i + 1]); | ||
| 1345 | } else | ||
| 1346 | piov = le64_to_cpu(dd->ipath_pioavailregs_dma[i]); | 1349 | piov = le64_to_cpu(dd->ipath_pioavailregs_dma[i]); |
| 1347 | pchg = _IPATH_ALL_CHECKBITS & | 1350 | pchg = _IPATH_ALL_CHECKBITS & |
| 1348 | ~(dd->ipath_pioavailshadow[i] ^ piov); | 1351 | ~(dd->ipath_pioavailshadow[i] ^ piov); |
| @@ -1601,7 +1604,8 @@ int ipath_create_rcvhdrq(struct ipath_devdata *dd, | |||
| 1601 | 1604 | ||
| 1602 | /* clear for security and sanity on each use */ | 1605 | /* clear for security and sanity on each use */ |
| 1603 | memset(pd->port_rcvhdrq, 0, pd->port_rcvhdrq_size); | 1606 | memset(pd->port_rcvhdrq, 0, pd->port_rcvhdrq_size); |
| 1604 | memset(pd->port_rcvhdrtail_kvaddr, 0, PAGE_SIZE); | 1607 | if (pd->port_rcvhdrtail_kvaddr) |
| 1608 | memset(pd->port_rcvhdrtail_kvaddr, 0, PAGE_SIZE); | ||
| 1605 | 1609 | ||
| 1606 | /* | 1610 | /* |
| 1607 | * tell chip each time we init it, even if we are re-using previous | 1611 | * tell chip each time we init it, even if we are re-using previous |
| @@ -1617,77 +1621,6 @@ bail: | |||
| 1617 | return ret; | 1621 | return ret; |
| 1618 | } | 1622 | } |
| 1619 | 1623 | ||
| 1620 | int ipath_waitfor_complete(struct ipath_devdata *dd, ipath_kreg reg_id, | ||
| 1621 | u64 bits_to_wait_for, u64 * valp) | ||
| 1622 | { | ||
| 1623 | unsigned long timeout; | ||
| 1624 | u64 lastval, val; | ||
| 1625 | int ret; | ||
| 1626 | |||
| 1627 | lastval = ipath_read_kreg64(dd, reg_id); | ||
| 1628 | /* wait a ridiculously long time */ | ||
| 1629 | timeout = jiffies + msecs_to_jiffies(5); | ||
| 1630 | do { | ||
| 1631 | val = ipath_read_kreg64(dd, reg_id); | ||
| 1632 | /* set so they have something, even on failures. */ | ||
| 1633 | *valp = val; | ||
| 1634 | if ((val & bits_to_wait_for) == bits_to_wait_for) { | ||
| 1635 | ret = 0; | ||
| 1636 | break; | ||
| 1637 | } | ||
| 1638 | if (val != lastval) | ||
| 1639 | ipath_cdbg(VERBOSE, "Changed from %llx to %llx, " | ||
| 1640 | "waiting for %llx bits\n", | ||
| 1641 | (unsigned long long) lastval, | ||
| 1642 | (unsigned long long) val, | ||
| 1643 | (unsigned long long) bits_to_wait_for); | ||
| 1644 | cond_resched(); | ||
| 1645 | if (time_after(jiffies, timeout)) { | ||
| 1646 | ipath_dbg("Didn't get bits %llx in register 0x%x, " | ||
| 1647 | "got %llx\n", | ||
| 1648 | (unsigned long long) bits_to_wait_for, | ||
| 1649 | reg_id, (unsigned long long) *valp); | ||
| 1650 | ret = -ENODEV; | ||
| 1651 | break; | ||
| 1652 | } | ||
| 1653 | } while (1); | ||
| 1654 | |||
| 1655 | return ret; | ||
| 1656 | } | ||
| 1657 | |||
| 1658 | /** | ||
| 1659 | * ipath_waitfor_mdio_cmdready - wait for last command to complete | ||
| 1660 | * @dd: the infinipath device | ||
| 1661 | * | ||
| 1662 | * Like ipath_waitfor_complete(), but we wait for the CMDVALID bit to go | ||
| 1663 | * away indicating the last command has completed. It doesn't return data | ||
| 1664 | */ | ||
| 1665 | int ipath_waitfor_mdio_cmdready(struct ipath_devdata *dd) | ||
| 1666 | { | ||
| 1667 | unsigned long timeout; | ||
| 1668 | u64 val; | ||
| 1669 | int ret; | ||
| 1670 | |||
| 1671 | /* wait a ridiculously long time */ | ||
| 1672 | timeout = jiffies + msecs_to_jiffies(5); | ||
| 1673 | do { | ||
| 1674 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_mdio); | ||
| 1675 | if (!(val & IPATH_MDIO_CMDVALID)) { | ||
| 1676 | ret = 0; | ||
| 1677 | break; | ||
| 1678 | } | ||
| 1679 | cond_resched(); | ||
| 1680 | if (time_after(jiffies, timeout)) { | ||
| 1681 | ipath_dbg("CMDVALID stuck in mdio reg? (%llx)\n", | ||
| 1682 | (unsigned long long) val); | ||
| 1683 | ret = -ENODEV; | ||
| 1684 | break; | ||
| 1685 | } | ||
| 1686 | } while (1); | ||
| 1687 | |||
| 1688 | return ret; | ||
| 1689 | } | ||
| 1690 | |||
| 1691 | 1624 | ||
| 1692 | /* | 1625 | /* |
| 1693 | * Flush all sends that might be in the ready to send state, as well as any | 1626 | * Flush all sends that might be in the ready to send state, as well as any |
| @@ -2056,6 +1989,8 @@ void ipath_set_led_override(struct ipath_devdata *dd, unsigned int val) | |||
| 2056 | */ | 1989 | */ |
| 2057 | void ipath_shutdown_device(struct ipath_devdata *dd) | 1990 | void ipath_shutdown_device(struct ipath_devdata *dd) |
| 2058 | { | 1991 | { |
| 1992 | unsigned long flags; | ||
| 1993 | |||
| 2059 | ipath_dbg("Shutting down the device\n"); | 1994 | ipath_dbg("Shutting down the device\n"); |
| 2060 | 1995 | ||
| 2061 | dd->ipath_flags |= IPATH_LINKUNK; | 1996 | dd->ipath_flags |= IPATH_LINKUNK; |
| @@ -2076,9 +2011,13 @@ void ipath_shutdown_device(struct ipath_devdata *dd) | |||
| 2076 | * gracefully stop all sends allowing any in progress to trickle out | 2011 | * gracefully stop all sends allowing any in progress to trickle out |
| 2077 | * first. | 2012 | * first. |
| 2078 | */ | 2013 | */ |
| 2079 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 0ULL); | 2014 | spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); |
| 2015 | dd->ipath_sendctrl = 0; | ||
| 2016 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl); | ||
| 2080 | /* flush it */ | 2017 | /* flush it */ |
| 2081 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | 2018 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); |
| 2019 | spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); | ||
| 2020 | |||
| 2082 | /* | 2021 | /* |
| 2083 | * enough for anything that's going to trickle out to have actually | 2022 | * enough for anything that's going to trickle out to have actually |
| 2084 | * done so. | 2023 | * done so. |
| @@ -2335,5 +2274,34 @@ int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv) | |||
| 2335 | } | 2274 | } |
| 2336 | return 0; | 2275 | return 0; |
| 2337 | } | 2276 | } |
| 2277 | |||
| 2278 | /* | ||
| 2279 | * Disable and enable the armlaunch error. Used for PIO bandwidth testing on | ||
| 2280 | * the 7220, which is count-based, rather than trigger-based. Safe for the | ||
| 2281 | * driver check, since it's at init. Not completely safe when used for | ||
| 2282 | * user-mode checking, since some error checking can be lost, but not | ||
| 2283 | * particularly risky, and only has problematic side-effects in the face of | ||
| 2284 | * very buggy user code. There is no reference counting, but that's also | ||
| 2285 | * fine, given the intended use. | ||
| 2286 | */ | ||
| 2287 | void ipath_enable_armlaunch(struct ipath_devdata *dd) | ||
| 2288 | { | ||
| 2289 | dd->ipath_lasterror &= ~INFINIPATH_E_SPIOARMLAUNCH; | ||
| 2290 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, | ||
| 2291 | INFINIPATH_E_SPIOARMLAUNCH); | ||
| 2292 | dd->ipath_errormask |= INFINIPATH_E_SPIOARMLAUNCH; | ||
| 2293 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, | ||
| 2294 | dd->ipath_errormask); | ||
| 2295 | } | ||
| 2296 | |||
| 2297 | void ipath_disable_armlaunch(struct ipath_devdata *dd) | ||
| 2298 | { | ||
| 2299 | /* so don't re-enable if already set */ | ||
| 2300 | dd->ipath_maskederrs &= ~INFINIPATH_E_SPIOARMLAUNCH; | ||
| 2301 | dd->ipath_errormask &= ~INFINIPATH_E_SPIOARMLAUNCH; | ||
| 2302 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, | ||
| 2303 | dd->ipath_errormask); | ||
| 2304 | } | ||
| 2305 | |||
| 2338 | module_init(infinipath_init); | 2306 | module_init(infinipath_init); |
| 2339 | module_exit(infinipath_cleanup); | 2307 | module_exit(infinipath_cleanup); |
diff --git a/drivers/infiniband/hw/ipath/ipath_eeprom.c b/drivers/infiniband/hw/ipath/ipath_eeprom.c index e7c25dbbcdc9..e28a42f53769 100644 --- a/drivers/infiniband/hw/ipath/ipath_eeprom.c +++ b/drivers/infiniband/hw/ipath/ipath_eeprom.c | |||
| @@ -510,10 +510,10 @@ int ipath_eeprom_read(struct ipath_devdata *dd, u8 eeprom_offset, | |||
| 510 | { | 510 | { |
| 511 | int ret; | 511 | int ret; |
| 512 | 512 | ||
| 513 | ret = down_interruptible(&dd->ipath_eep_sem); | 513 | ret = mutex_lock_interruptible(&dd->ipath_eep_lock); |
| 514 | if (!ret) { | 514 | if (!ret) { |
| 515 | ret = ipath_eeprom_internal_read(dd, eeprom_offset, buff, len); | 515 | ret = ipath_eeprom_internal_read(dd, eeprom_offset, buff, len); |
| 516 | up(&dd->ipath_eep_sem); | 516 | mutex_unlock(&dd->ipath_eep_lock); |
| 517 | } | 517 | } |
| 518 | 518 | ||
| 519 | return ret; | 519 | return ret; |
| @@ -524,10 +524,10 @@ int ipath_eeprom_write(struct ipath_devdata *dd, u8 eeprom_offset, | |||
| 524 | { | 524 | { |
| 525 | int ret; | 525 | int ret; |
| 526 | 526 | ||
| 527 | ret = down_interruptible(&dd->ipath_eep_sem); | 527 | ret = mutex_lock_interruptible(&dd->ipath_eep_lock); |
| 528 | if (!ret) { | 528 | if (!ret) { |
| 529 | ret = ipath_eeprom_internal_write(dd, eeprom_offset, buff, len); | 529 | ret = ipath_eeprom_internal_write(dd, eeprom_offset, buff, len); |
| 530 | up(&dd->ipath_eep_sem); | 530 | mutex_unlock(&dd->ipath_eep_lock); |
| 531 | } | 531 | } |
| 532 | 532 | ||
| 533 | return ret; | 533 | return ret; |
| @@ -574,7 +574,7 @@ void ipath_get_eeprom_info(struct ipath_devdata *dd) | |||
| 574 | struct ipath_devdata *dd0 = ipath_lookup(0); | 574 | struct ipath_devdata *dd0 = ipath_lookup(0); |
| 575 | 575 | ||
| 576 | if (t && dd0->ipath_nguid > 1 && t <= dd0->ipath_nguid) { | 576 | if (t && dd0->ipath_nguid > 1 && t <= dd0->ipath_nguid) { |
| 577 | u8 *bguid, oguid; | 577 | u8 oguid; |
| 578 | dd->ipath_guid = dd0->ipath_guid; | 578 | dd->ipath_guid = dd0->ipath_guid; |
| 579 | bguid = (u8 *) & dd->ipath_guid; | 579 | bguid = (u8 *) & dd->ipath_guid; |
| 580 | 580 | ||
| @@ -616,9 +616,9 @@ void ipath_get_eeprom_info(struct ipath_devdata *dd) | |||
| 616 | goto bail; | 616 | goto bail; |
| 617 | } | 617 | } |
| 618 | 618 | ||
| 619 | down(&dd->ipath_eep_sem); | 619 | mutex_lock(&dd->ipath_eep_lock); |
| 620 | eep_stat = ipath_eeprom_internal_read(dd, 0, buf, len); | 620 | eep_stat = ipath_eeprom_internal_read(dd, 0, buf, len); |
| 621 | up(&dd->ipath_eep_sem); | 621 | mutex_unlock(&dd->ipath_eep_lock); |
| 622 | 622 | ||
| 623 | if (eep_stat) { | 623 | if (eep_stat) { |
| 624 | ipath_dev_err(dd, "Failed reading GUID from eeprom\n"); | 624 | ipath_dev_err(dd, "Failed reading GUID from eeprom\n"); |
| @@ -674,7 +674,6 @@ void ipath_get_eeprom_info(struct ipath_devdata *dd) | |||
| 674 | * elsewhere for backward-compatibility. | 674 | * elsewhere for backward-compatibility. |
| 675 | */ | 675 | */ |
| 676 | char *snp = dd->ipath_serial; | 676 | char *snp = dd->ipath_serial; |
| 677 | int len; | ||
| 678 | memcpy(snp, ifp->if_sprefix, sizeof ifp->if_sprefix); | 677 | memcpy(snp, ifp->if_sprefix, sizeof ifp->if_sprefix); |
| 679 | snp[sizeof ifp->if_sprefix] = '\0'; | 678 | snp[sizeof ifp->if_sprefix] = '\0'; |
| 680 | len = strlen(snp); | 679 | len = strlen(snp); |
| @@ -764,14 +763,14 @@ int ipath_update_eeprom_log(struct ipath_devdata *dd) | |||
| 764 | /* Grab semaphore and read current EEPROM. If we get an | 763 | /* Grab semaphore and read current EEPROM. If we get an |
| 765 | * error, let go, but if not, keep it until we finish write. | 764 | * error, let go, but if not, keep it until we finish write. |
| 766 | */ | 765 | */ |
| 767 | ret = down_interruptible(&dd->ipath_eep_sem); | 766 | ret = mutex_lock_interruptible(&dd->ipath_eep_lock); |
| 768 | if (ret) { | 767 | if (ret) { |
| 769 | ipath_dev_err(dd, "Unable to acquire EEPROM for logging\n"); | 768 | ipath_dev_err(dd, "Unable to acquire EEPROM for logging\n"); |
| 770 | goto free_bail; | 769 | goto free_bail; |
| 771 | } | 770 | } |
| 772 | ret = ipath_eeprom_internal_read(dd, 0, buf, len); | 771 | ret = ipath_eeprom_internal_read(dd, 0, buf, len); |
| 773 | if (ret) { | 772 | if (ret) { |
| 774 | up(&dd->ipath_eep_sem); | 773 | mutex_unlock(&dd->ipath_eep_lock); |
| 775 | ipath_dev_err(dd, "Unable read EEPROM for logging\n"); | 774 | ipath_dev_err(dd, "Unable read EEPROM for logging\n"); |
| 776 | goto free_bail; | 775 | goto free_bail; |
| 777 | } | 776 | } |
| @@ -779,7 +778,7 @@ int ipath_update_eeprom_log(struct ipath_devdata *dd) | |||
| 779 | 778 | ||
| 780 | csum = flash_csum(ifp, 0); | 779 | csum = flash_csum(ifp, 0); |
| 781 | if (csum != ifp->if_csum) { | 780 | if (csum != ifp->if_csum) { |
| 782 | up(&dd->ipath_eep_sem); | 781 | mutex_unlock(&dd->ipath_eep_lock); |
| 783 | ipath_dev_err(dd, "EEPROM cks err (0x%02X, S/B 0x%02X)\n", | 782 | ipath_dev_err(dd, "EEPROM cks err (0x%02X, S/B 0x%02X)\n", |
| 784 | csum, ifp->if_csum); | 783 | csum, ifp->if_csum); |
| 785 | ret = 1; | 784 | ret = 1; |
| @@ -849,7 +848,7 @@ int ipath_update_eeprom_log(struct ipath_devdata *dd) | |||
| 849 | csum = flash_csum(ifp, 1); | 848 | csum = flash_csum(ifp, 1); |
| 850 | ret = ipath_eeprom_internal_write(dd, 0, buf, hi_water + 1); | 849 | ret = ipath_eeprom_internal_write(dd, 0, buf, hi_water + 1); |
| 851 | } | 850 | } |
| 852 | up(&dd->ipath_eep_sem); | 851 | mutex_unlock(&dd->ipath_eep_lock); |
| 853 | if (ret) | 852 | if (ret) |
| 854 | ipath_dev_err(dd, "Failed updating EEPROM\n"); | 853 | ipath_dev_err(dd, "Failed updating EEPROM\n"); |
| 855 | 854 | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c index 5de3243a47c3..7e025c8e01b6 100644 --- a/drivers/infiniband/hw/ipath/ipath_file_ops.c +++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c | |||
| @@ -169,7 +169,7 @@ static int ipath_get_base_info(struct file *fp, | |||
| 169 | kinfo->spi_piocnt = dd->ipath_pbufsport; | 169 | kinfo->spi_piocnt = dd->ipath_pbufsport; |
| 170 | kinfo->spi_piobufbase = (u64) pd->port_piobufs; | 170 | kinfo->spi_piobufbase = (u64) pd->port_piobufs; |
| 171 | kinfo->__spi_uregbase = (u64) dd->ipath_uregbase + | 171 | kinfo->__spi_uregbase = (u64) dd->ipath_uregbase + |
| 172 | dd->ipath_palign * pd->port_port; | 172 | dd->ipath_ureg_align * pd->port_port; |
| 173 | } else if (master) { | 173 | } else if (master) { |
| 174 | kinfo->spi_piocnt = (dd->ipath_pbufsport / subport_cnt) + | 174 | kinfo->spi_piocnt = (dd->ipath_pbufsport / subport_cnt) + |
| 175 | (dd->ipath_pbufsport % subport_cnt); | 175 | (dd->ipath_pbufsport % subport_cnt); |
| @@ -186,7 +186,7 @@ static int ipath_get_base_info(struct file *fp, | |||
| 186 | } | 186 | } |
| 187 | if (shared) { | 187 | if (shared) { |
| 188 | kinfo->spi_port_uregbase = (u64) dd->ipath_uregbase + | 188 | kinfo->spi_port_uregbase = (u64) dd->ipath_uregbase + |
| 189 | dd->ipath_palign * pd->port_port; | 189 | dd->ipath_ureg_align * pd->port_port; |
| 190 | kinfo->spi_port_rcvegrbuf = kinfo->spi_rcv_egrbufs; | 190 | kinfo->spi_port_rcvegrbuf = kinfo->spi_rcv_egrbufs; |
| 191 | kinfo->spi_port_rcvhdr_base = kinfo->spi_rcvhdr_base; | 191 | kinfo->spi_port_rcvhdr_base = kinfo->spi_rcvhdr_base; |
| 192 | kinfo->spi_port_rcvhdr_tailaddr = kinfo->spi_rcvhdr_tailaddr; | 192 | kinfo->spi_port_rcvhdr_tailaddr = kinfo->spi_rcvhdr_tailaddr; |
| @@ -742,11 +742,12 @@ static int ipath_manage_rcvq(struct ipath_portdata *pd, unsigned subport, | |||
| 742 | * updated and correct itself, even in the face of software | 742 | * updated and correct itself, even in the face of software |
| 743 | * bugs. | 743 | * bugs. |
| 744 | */ | 744 | */ |
| 745 | *(volatile u64 *)pd->port_rcvhdrtail_kvaddr = 0; | 745 | if (pd->port_rcvhdrtail_kvaddr) |
| 746 | set_bit(INFINIPATH_R_PORTENABLE_SHIFT + pd->port_port, | 746 | ipath_clear_rcvhdrtail(pd); |
| 747 | set_bit(dd->ipath_r_portenable_shift + pd->port_port, | ||
| 747 | &dd->ipath_rcvctrl); | 748 | &dd->ipath_rcvctrl); |
| 748 | } else | 749 | } else |
| 749 | clear_bit(INFINIPATH_R_PORTENABLE_SHIFT + pd->port_port, | 750 | clear_bit(dd->ipath_r_portenable_shift + pd->port_port, |
| 750 | &dd->ipath_rcvctrl); | 751 | &dd->ipath_rcvctrl); |
| 751 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | 752 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, |
| 752 | dd->ipath_rcvctrl); | 753 | dd->ipath_rcvctrl); |
| @@ -881,7 +882,7 @@ static int ipath_create_user_egr(struct ipath_portdata *pd) | |||
| 881 | 882 | ||
| 882 | egrcnt = dd->ipath_rcvegrcnt; | 883 | egrcnt = dd->ipath_rcvegrcnt; |
| 883 | /* TID number offset for this port */ | 884 | /* TID number offset for this port */ |
| 884 | egroff = pd->port_port * egrcnt; | 885 | egroff = (pd->port_port - 1) * egrcnt + dd->ipath_p0_rcvegrcnt; |
| 885 | egrsize = dd->ipath_rcvegrbufsize; | 886 | egrsize = dd->ipath_rcvegrbufsize; |
| 886 | ipath_cdbg(VERBOSE, "Allocating %d egr buffers, at egrtid " | 887 | ipath_cdbg(VERBOSE, "Allocating %d egr buffers, at egrtid " |
| 887 | "offset %x, egrsize %u\n", egrcnt, egroff, egrsize); | 888 | "offset %x, egrsize %u\n", egrcnt, egroff, egrsize); |
| @@ -1049,11 +1050,6 @@ static int mmap_piobufs(struct vm_area_struct *vma, | |||
| 1049 | 1050 | ||
| 1050 | phys = dd->ipath_physaddr + piobufs; | 1051 | phys = dd->ipath_physaddr + piobufs; |
| 1051 | 1052 | ||
| 1052 | /* | ||
| 1053 | * Don't mark this as non-cached, or we don't get the | ||
| 1054 | * write combining behavior we want on the PIO buffers! | ||
| 1055 | */ | ||
| 1056 | |||
| 1057 | #if defined(__powerpc__) | 1053 | #if defined(__powerpc__) |
| 1058 | /* There isn't a generic way to specify writethrough mappings */ | 1054 | /* There isn't a generic way to specify writethrough mappings */ |
| 1059 | pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; | 1055 | pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; |
| @@ -1120,33 +1116,24 @@ bail: | |||
| 1120 | } | 1116 | } |
| 1121 | 1117 | ||
| 1122 | /* | 1118 | /* |
| 1123 | * ipath_file_vma_nopage - handle a VMA page fault. | 1119 | * ipath_file_vma_fault - handle a VMA page fault. |
| 1124 | */ | 1120 | */ |
| 1125 | static struct page *ipath_file_vma_nopage(struct vm_area_struct *vma, | 1121 | static int ipath_file_vma_fault(struct vm_area_struct *vma, |
| 1126 | unsigned long address, int *type) | 1122 | struct vm_fault *vmf) |
| 1127 | { | 1123 | { |
| 1128 | unsigned long offset = address - vma->vm_start; | 1124 | struct page *page; |
| 1129 | struct page *page = NOPAGE_SIGBUS; | ||
| 1130 | void *pageptr; | ||
| 1131 | 1125 | ||
| 1132 | /* | 1126 | page = vmalloc_to_page((void *)(vmf->pgoff << PAGE_SHIFT)); |
| 1133 | * Convert the vmalloc address into a struct page. | ||
| 1134 | */ | ||
| 1135 | pageptr = (void *)(offset + (vma->vm_pgoff << PAGE_SHIFT)); | ||
| 1136 | page = vmalloc_to_page(pageptr); | ||
| 1137 | if (!page) | 1127 | if (!page) |
| 1138 | goto out; | 1128 | return VM_FAULT_SIGBUS; |
| 1139 | |||
| 1140 | /* Increment the reference count. */ | ||
| 1141 | get_page(page); | 1129 | get_page(page); |
| 1142 | if (type) | 1130 | vmf->page = page; |
| 1143 | *type = VM_FAULT_MINOR; | 1131 | |
| 1144 | out: | 1132 | return 0; |
| 1145 | return page; | ||
| 1146 | } | 1133 | } |
| 1147 | 1134 | ||
| 1148 | static struct vm_operations_struct ipath_file_vm_ops = { | 1135 | static struct vm_operations_struct ipath_file_vm_ops = { |
| 1149 | .nopage = ipath_file_vma_nopage, | 1136 | .fault = ipath_file_vma_fault, |
| 1150 | }; | 1137 | }; |
| 1151 | 1138 | ||
| 1152 | static int mmap_kvaddr(struct vm_area_struct *vma, u64 pgaddr, | 1139 | static int mmap_kvaddr(struct vm_area_struct *vma, u64 pgaddr, |
| @@ -1284,7 +1271,7 @@ static int ipath_mmap(struct file *fp, struct vm_area_struct *vma) | |||
| 1284 | goto bail; | 1271 | goto bail; |
| 1285 | } | 1272 | } |
| 1286 | 1273 | ||
| 1287 | ureg = dd->ipath_uregbase + dd->ipath_palign * pd->port_port; | 1274 | ureg = dd->ipath_uregbase + dd->ipath_ureg_align * pd->port_port; |
| 1288 | if (!pd->port_subport_cnt) { | 1275 | if (!pd->port_subport_cnt) { |
| 1289 | /* port is not shared */ | 1276 | /* port is not shared */ |
| 1290 | piocnt = dd->ipath_pbufsport; | 1277 | piocnt = dd->ipath_pbufsport; |
| @@ -1400,7 +1387,10 @@ static unsigned int ipath_poll_next(struct ipath_portdata *pd, | |||
| 1400 | pollflag = ipath_poll_hdrqfull(pd); | 1387 | pollflag = ipath_poll_hdrqfull(pd); |
| 1401 | 1388 | ||
| 1402 | head = ipath_read_ureg32(dd, ur_rcvhdrhead, pd->port_port); | 1389 | head = ipath_read_ureg32(dd, ur_rcvhdrhead, pd->port_port); |
| 1403 | tail = *(volatile u64 *)pd->port_rcvhdrtail_kvaddr; | 1390 | if (pd->port_rcvhdrtail_kvaddr) |
| 1391 | tail = ipath_get_rcvhdrtail(pd); | ||
| 1392 | else | ||
| 1393 | tail = ipath_read_ureg32(dd, ur_rcvhdrtail, pd->port_port); | ||
| 1404 | 1394 | ||
| 1405 | if (head != tail) | 1395 | if (head != tail) |
| 1406 | pollflag |= POLLIN | POLLRDNORM; | 1396 | pollflag |= POLLIN | POLLRDNORM; |
| @@ -1410,7 +1400,7 @@ static unsigned int ipath_poll_next(struct ipath_portdata *pd, | |||
| 1410 | /* flush waiting flag so we don't miss an event */ | 1400 | /* flush waiting flag so we don't miss an event */ |
| 1411 | wmb(); | 1401 | wmb(); |
| 1412 | 1402 | ||
| 1413 | set_bit(pd->port_port + INFINIPATH_R_INTRAVAIL_SHIFT, | 1403 | set_bit(pd->port_port + dd->ipath_r_intravail_shift, |
| 1414 | &dd->ipath_rcvctrl); | 1404 | &dd->ipath_rcvctrl); |
| 1415 | 1405 | ||
| 1416 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | 1406 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, |
| @@ -1790,6 +1780,7 @@ static int find_shared_port(struct file *fp, | |||
| 1790 | } | 1780 | } |
| 1791 | port_fp(fp) = pd; | 1781 | port_fp(fp) = pd; |
| 1792 | subport_fp(fp) = pd->port_cnt++; | 1782 | subport_fp(fp) = pd->port_cnt++; |
| 1783 | pd->port_subpid[subport_fp(fp)] = current->pid; | ||
| 1793 | tidcursor_fp(fp) = 0; | 1784 | tidcursor_fp(fp) = 0; |
| 1794 | pd->active_slaves |= 1 << subport_fp(fp); | 1785 | pd->active_slaves |= 1 << subport_fp(fp); |
| 1795 | ipath_cdbg(PROC, | 1786 | ipath_cdbg(PROC, |
| @@ -1920,8 +1911,7 @@ static int ipath_do_user_init(struct file *fp, | |||
| 1920 | */ | 1911 | */ |
| 1921 | head32 = ipath_read_ureg32(dd, ur_rcvegrindextail, pd->port_port); | 1912 | head32 = ipath_read_ureg32(dd, ur_rcvegrindextail, pd->port_port); |
| 1922 | ipath_write_ureg(dd, ur_rcvegrindexhead, head32, pd->port_port); | 1913 | ipath_write_ureg(dd, ur_rcvegrindexhead, head32, pd->port_port); |
| 1923 | dd->ipath_lastegrheads[pd->port_port] = -1; | 1914 | pd->port_lastrcvhdrqtail = -1; |
| 1924 | dd->ipath_lastrcvhdrqtails[pd->port_port] = -1; | ||
| 1925 | ipath_cdbg(VERBOSE, "Wrote port%d egrhead %x from tail regs\n", | 1915 | ipath_cdbg(VERBOSE, "Wrote port%d egrhead %x from tail regs\n", |
| 1926 | pd->port_port, head32); | 1916 | pd->port_port, head32); |
| 1927 | pd->port_tidcursor = 0; /* start at beginning after open */ | 1917 | pd->port_tidcursor = 0; /* start at beginning after open */ |
| @@ -1941,11 +1931,13 @@ static int ipath_do_user_init(struct file *fp, | |||
| 1941 | * We explictly set the in-memory copy to 0 beforehand, so we don't | 1931 | * We explictly set the in-memory copy to 0 beforehand, so we don't |
| 1942 | * have to wait to be sure the DMA update has happened. | 1932 | * have to wait to be sure the DMA update has happened. |
| 1943 | */ | 1933 | */ |
| 1944 | *(volatile u64 *)pd->port_rcvhdrtail_kvaddr = 0ULL; | 1934 | if (pd->port_rcvhdrtail_kvaddr) |
| 1945 | set_bit(INFINIPATH_R_PORTENABLE_SHIFT + pd->port_port, | 1935 | ipath_clear_rcvhdrtail(pd); |
| 1936 | set_bit(dd->ipath_r_portenable_shift + pd->port_port, | ||
| 1946 | &dd->ipath_rcvctrl); | 1937 | &dd->ipath_rcvctrl); |
| 1947 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | 1938 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, |
| 1948 | dd->ipath_rcvctrl & ~INFINIPATH_R_TAILUPD); | 1939 | dd->ipath_rcvctrl & |
| 1940 | ~(1ULL << dd->ipath_r_tailupd_shift)); | ||
| 1949 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | 1941 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, |
| 1950 | dd->ipath_rcvctrl); | 1942 | dd->ipath_rcvctrl); |
| 1951 | /* Notify any waiting slaves */ | 1943 | /* Notify any waiting slaves */ |
| @@ -2022,6 +2014,7 @@ static int ipath_close(struct inode *in, struct file *fp) | |||
| 2022 | * the slave(s) don't wait for receive data forever. | 2014 | * the slave(s) don't wait for receive data forever. |
| 2023 | */ | 2015 | */ |
| 2024 | pd->active_slaves &= ~(1 << fd->subport); | 2016 | pd->active_slaves &= ~(1 << fd->subport); |
| 2017 | pd->port_subpid[fd->subport] = 0; | ||
| 2025 | mutex_unlock(&ipath_mutex); | 2018 | mutex_unlock(&ipath_mutex); |
| 2026 | goto bail; | 2019 | goto bail; |
| 2027 | } | 2020 | } |
| @@ -2054,9 +2047,9 @@ static int ipath_close(struct inode *in, struct file *fp) | |||
| 2054 | if (dd->ipath_kregbase) { | 2047 | if (dd->ipath_kregbase) { |
| 2055 | int i; | 2048 | int i; |
| 2056 | /* atomically clear receive enable port and intr avail. */ | 2049 | /* atomically clear receive enable port and intr avail. */ |
| 2057 | clear_bit(INFINIPATH_R_PORTENABLE_SHIFT + port, | 2050 | clear_bit(dd->ipath_r_portenable_shift + port, |
| 2058 | &dd->ipath_rcvctrl); | 2051 | &dd->ipath_rcvctrl); |
| 2059 | clear_bit(pd->port_port + INFINIPATH_R_INTRAVAIL_SHIFT, | 2052 | clear_bit(pd->port_port + dd->ipath_r_intravail_shift, |
| 2060 | &dd->ipath_rcvctrl); | 2053 | &dd->ipath_rcvctrl); |
| 2061 | ipath_write_kreg( dd, dd->ipath_kregs->kr_rcvctrl, | 2054 | ipath_write_kreg( dd, dd->ipath_kregs->kr_rcvctrl, |
| 2062 | dd->ipath_rcvctrl); | 2055 | dd->ipath_rcvctrl); |
| @@ -2149,11 +2142,15 @@ static int ipath_get_slave_info(struct ipath_portdata *pd, | |||
| 2149 | 2142 | ||
| 2150 | static int ipath_force_pio_avail_update(struct ipath_devdata *dd) | 2143 | static int ipath_force_pio_avail_update(struct ipath_devdata *dd) |
| 2151 | { | 2144 | { |
| 2152 | u64 reg = dd->ipath_sendctrl; | 2145 | unsigned long flags; |
| 2153 | 2146 | ||
| 2154 | clear_bit(IPATH_S_PIOBUFAVAILUPD, ®); | 2147 | spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); |
| 2155 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, reg); | 2148 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, |
| 2149 | dd->ipath_sendctrl & ~INFINIPATH_S_PIOBUFAVAILUPD); | ||
| 2150 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | ||
| 2156 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl); | 2151 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl); |
| 2152 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | ||
| 2153 | spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); | ||
| 2157 | 2154 | ||
| 2158 | return 0; | 2155 | return 0; |
| 2159 | } | 2156 | } |
| @@ -2227,6 +2224,11 @@ static ssize_t ipath_write(struct file *fp, const char __user *data, | |||
| 2227 | dest = &cmd.cmd.poll_type; | 2224 | dest = &cmd.cmd.poll_type; |
| 2228 | src = &ucmd->cmd.poll_type; | 2225 | src = &ucmd->cmd.poll_type; |
| 2229 | break; | 2226 | break; |
| 2227 | case IPATH_CMD_ARMLAUNCH_CTRL: | ||
| 2228 | copy = sizeof(cmd.cmd.armlaunch_ctrl); | ||
| 2229 | dest = &cmd.cmd.armlaunch_ctrl; | ||
| 2230 | src = &ucmd->cmd.armlaunch_ctrl; | ||
| 2231 | break; | ||
| 2230 | default: | 2232 | default: |
| 2231 | ret = -EINVAL; | 2233 | ret = -EINVAL; |
| 2232 | goto bail; | 2234 | goto bail; |
| @@ -2302,6 +2304,12 @@ static ssize_t ipath_write(struct file *fp, const char __user *data, | |||
| 2302 | case IPATH_CMD_POLL_TYPE: | 2304 | case IPATH_CMD_POLL_TYPE: |
| 2303 | pd->poll_type = cmd.cmd.poll_type; | 2305 | pd->poll_type = cmd.cmd.poll_type; |
| 2304 | break; | 2306 | break; |
| 2307 | case IPATH_CMD_ARMLAUNCH_CTRL: | ||
| 2308 | if (cmd.cmd.armlaunch_ctrl) | ||
| 2309 | ipath_enable_armlaunch(pd->port_dd); | ||
| 2310 | else | ||
| 2311 | ipath_disable_armlaunch(pd->port_dd); | ||
| 2312 | break; | ||
| 2305 | } | 2313 | } |
| 2306 | 2314 | ||
| 2307 | if (ret >= 0) | 2315 | if (ret >= 0) |
diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c index 262c25db05cd..23faba9d21eb 100644 --- a/drivers/infiniband/hw/ipath/ipath_fs.c +++ b/drivers/infiniband/hw/ipath/ipath_fs.c | |||
| @@ -108,21 +108,16 @@ static const struct file_operations atomic_stats_ops = { | |||
| 108 | .read = atomic_stats_read, | 108 | .read = atomic_stats_read, |
| 109 | }; | 109 | }; |
| 110 | 110 | ||
| 111 | #define NUM_COUNTERS sizeof(struct infinipath_counters) / sizeof(u64) | ||
| 112 | |||
| 113 | static ssize_t atomic_counters_read(struct file *file, char __user *buf, | 111 | static ssize_t atomic_counters_read(struct file *file, char __user *buf, |
| 114 | size_t count, loff_t *ppos) | 112 | size_t count, loff_t *ppos) |
| 115 | { | 113 | { |
| 116 | u64 counters[NUM_COUNTERS]; | 114 | struct infinipath_counters counters; |
| 117 | u16 i; | ||
| 118 | struct ipath_devdata *dd; | 115 | struct ipath_devdata *dd; |
| 119 | 116 | ||
| 120 | dd = file->f_path.dentry->d_inode->i_private; | 117 | dd = file->f_path.dentry->d_inode->i_private; |
| 118 | dd->ipath_f_read_counters(dd, &counters); | ||
| 121 | 119 | ||
| 122 | for (i = 0; i < NUM_COUNTERS; i++) | 120 | return simple_read_from_buffer(buf, count, ppos, &counters, |
| 123 | counters[i] = ipath_snap_cntr(dd, i); | ||
| 124 | |||
| 125 | return simple_read_from_buffer(buf, count, ppos, counters, | ||
| 126 | sizeof counters); | 121 | sizeof counters); |
| 127 | } | 122 | } |
| 128 | 123 | ||
| @@ -243,8 +238,7 @@ static int create_device_files(struct super_block *sb, | |||
| 243 | 238 | ||
| 244 | snprintf(unit, sizeof unit, "%02d", dd->ipath_unit); | 239 | snprintf(unit, sizeof unit, "%02d", dd->ipath_unit); |
| 245 | ret = create_file(unit, S_IFDIR|S_IRUGO|S_IXUGO, sb->s_root, &dir, | 240 | ret = create_file(unit, S_IFDIR|S_IRUGO|S_IXUGO, sb->s_root, &dir, |
| 246 | (struct file_operations *) &simple_dir_operations, | 241 | &simple_dir_operations, dd); |
| 247 | dd); | ||
| 248 | if (ret) { | 242 | if (ret) { |
| 249 | printk(KERN_ERR "create_file(%s) failed: %d\n", unit, ret); | 243 | printk(KERN_ERR "create_file(%s) failed: %d\n", unit, ret); |
| 250 | goto bail; | 244 | goto bail; |
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6110.c b/drivers/infiniband/hw/ipath/ipath_iba6110.c index ddbebe4bdb27..9e2ced3cdc5e 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba6110.c +++ b/drivers/infiniband/hw/ipath/ipath_iba6110.c | |||
| @@ -148,10 +148,57 @@ struct _infinipath_do_not_use_kernel_regs { | |||
| 148 | unsigned long long ReservedSW2[4]; | 148 | unsigned long long ReservedSW2[4]; |
| 149 | }; | 149 | }; |
| 150 | 150 | ||
| 151 | #define IPATH_KREG_OFFSET(field) (offsetof(struct \ | 151 | struct _infinipath_do_not_use_counters { |
| 152 | _infinipath_do_not_use_kernel_regs, field) / sizeof(u64)) | 152 | __u64 LBIntCnt; |
| 153 | __u64 LBFlowStallCnt; | ||
| 154 | __u64 Reserved1; | ||
| 155 | __u64 TxUnsupVLErrCnt; | ||
| 156 | __u64 TxDataPktCnt; | ||
| 157 | __u64 TxFlowPktCnt; | ||
| 158 | __u64 TxDwordCnt; | ||
| 159 | __u64 TxLenErrCnt; | ||
| 160 | __u64 TxMaxMinLenErrCnt; | ||
| 161 | __u64 TxUnderrunCnt; | ||
| 162 | __u64 TxFlowStallCnt; | ||
| 163 | __u64 TxDroppedPktCnt; | ||
| 164 | __u64 RxDroppedPktCnt; | ||
| 165 | __u64 RxDataPktCnt; | ||
| 166 | __u64 RxFlowPktCnt; | ||
| 167 | __u64 RxDwordCnt; | ||
| 168 | __u64 RxLenErrCnt; | ||
| 169 | __u64 RxMaxMinLenErrCnt; | ||
| 170 | __u64 RxICRCErrCnt; | ||
| 171 | __u64 RxVCRCErrCnt; | ||
| 172 | __u64 RxFlowCtrlErrCnt; | ||
| 173 | __u64 RxBadFormatCnt; | ||
| 174 | __u64 RxLinkProblemCnt; | ||
| 175 | __u64 RxEBPCnt; | ||
| 176 | __u64 RxLPCRCErrCnt; | ||
| 177 | __u64 RxBufOvflCnt; | ||
| 178 | __u64 RxTIDFullErrCnt; | ||
| 179 | __u64 RxTIDValidErrCnt; | ||
| 180 | __u64 RxPKeyMismatchCnt; | ||
| 181 | __u64 RxP0HdrEgrOvflCnt; | ||
| 182 | __u64 RxP1HdrEgrOvflCnt; | ||
| 183 | __u64 RxP2HdrEgrOvflCnt; | ||
| 184 | __u64 RxP3HdrEgrOvflCnt; | ||
| 185 | __u64 RxP4HdrEgrOvflCnt; | ||
| 186 | __u64 RxP5HdrEgrOvflCnt; | ||
| 187 | __u64 RxP6HdrEgrOvflCnt; | ||
| 188 | __u64 RxP7HdrEgrOvflCnt; | ||
| 189 | __u64 RxP8HdrEgrOvflCnt; | ||
| 190 | __u64 Reserved6; | ||
| 191 | __u64 Reserved7; | ||
| 192 | __u64 IBStatusChangeCnt; | ||
| 193 | __u64 IBLinkErrRecoveryCnt; | ||
| 194 | __u64 IBLinkDownedCnt; | ||
| 195 | __u64 IBSymbolErrCnt; | ||
| 196 | }; | ||
| 197 | |||
| 198 | #define IPATH_KREG_OFFSET(field) (offsetof( \ | ||
| 199 | struct _infinipath_do_not_use_kernel_regs, field) / sizeof(u64)) | ||
| 153 | #define IPATH_CREG_OFFSET(field) (offsetof( \ | 200 | #define IPATH_CREG_OFFSET(field) (offsetof( \ |
| 154 | struct infinipath_counters, field) / sizeof(u64)) | 201 | struct _infinipath_do_not_use_counters, field) / sizeof(u64)) |
| 155 | 202 | ||
| 156 | static const struct ipath_kregs ipath_ht_kregs = { | 203 | static const struct ipath_kregs ipath_ht_kregs = { |
| 157 | .kr_control = IPATH_KREG_OFFSET(Control), | 204 | .kr_control = IPATH_KREG_OFFSET(Control), |
| @@ -282,6 +329,9 @@ static const struct ipath_cregs ipath_ht_cregs = { | |||
| 282 | #define INFINIPATH_HWE_HTAPLL_RFSLIP 0x1000000000000000ULL | 329 | #define INFINIPATH_HWE_HTAPLL_RFSLIP 0x1000000000000000ULL |
| 283 | #define INFINIPATH_HWE_SERDESPLLFAILED 0x2000000000000000ULL | 330 | #define INFINIPATH_HWE_SERDESPLLFAILED 0x2000000000000000ULL |
| 284 | 331 | ||
| 332 | #define IBA6110_IBCS_LINKTRAININGSTATE_MASK 0xf | ||
| 333 | #define IBA6110_IBCS_LINKSTATE_SHIFT 4 | ||
| 334 | |||
| 285 | /* kr_extstatus bits */ | 335 | /* kr_extstatus bits */ |
| 286 | #define INFINIPATH_EXTS_FREQSEL 0x2 | 336 | #define INFINIPATH_EXTS_FREQSEL 0x2 |
| 287 | #define INFINIPATH_EXTS_SERDESSEL 0x4 | 337 | #define INFINIPATH_EXTS_SERDESSEL 0x4 |
| @@ -296,6 +346,12 @@ static const struct ipath_cregs ipath_ht_cregs = { | |||
| 296 | #define INFINIPATH_RT_BUFSIZE_MASK 0x3FFFULL | 346 | #define INFINIPATH_RT_BUFSIZE_MASK 0x3FFFULL |
| 297 | #define INFINIPATH_RT_BUFSIZE_SHIFT 48 | 347 | #define INFINIPATH_RT_BUFSIZE_SHIFT 48 |
| 298 | 348 | ||
| 349 | #define INFINIPATH_R_INTRAVAIL_SHIFT 16 | ||
| 350 | #define INFINIPATH_R_TAILUPD_SHIFT 31 | ||
| 351 | |||
| 352 | /* kr_xgxsconfig bits */ | ||
| 353 | #define INFINIPATH_XGXS_RESET 0x7ULL | ||
| 354 | |||
| 299 | /* | 355 | /* |
| 300 | * masks and bits that are different in different chips, or present only | 356 | * masks and bits that are different in different chips, or present only |
| 301 | * in one | 357 | * in one |
| @@ -652,7 +708,6 @@ static int ipath_ht_boardname(struct ipath_devdata *dd, char *name, | |||
| 652 | "with ID %u\n", boardrev); | 708 | "with ID %u\n", boardrev); |
| 653 | snprintf(name, namelen, "Unknown_InfiniPath_QHT7xxx_%u", | 709 | snprintf(name, namelen, "Unknown_InfiniPath_QHT7xxx_%u", |
| 654 | boardrev); | 710 | boardrev); |
| 655 | ret = 1; | ||
| 656 | break; | 711 | break; |
| 657 | } | 712 | } |
| 658 | if (n) | 713 | if (n) |
| @@ -686,6 +741,13 @@ static int ipath_ht_boardname(struct ipath_devdata *dd, char *name, | |||
| 686 | dd->ipath_htspeed); | 741 | dd->ipath_htspeed); |
| 687 | ret = 0; | 742 | ret = 0; |
| 688 | 743 | ||
| 744 | /* | ||
| 745 | * set here, not in ipath_init_*_funcs because we have to do | ||
| 746 | * it after we can read chip registers. | ||
| 747 | */ | ||
| 748 | dd->ipath_ureg_align = | ||
| 749 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_pagealign); | ||
| 750 | |||
| 689 | bail: | 751 | bail: |
| 690 | return ret; | 752 | return ret; |
| 691 | } | 753 | } |
| @@ -969,7 +1031,8 @@ static int ipath_setup_ht_config(struct ipath_devdata *dd, | |||
| 969 | do { | 1031 | do { |
| 970 | u8 cap_type; | 1032 | u8 cap_type; |
| 971 | 1033 | ||
| 972 | /* the HT capability type byte is 3 bytes after the | 1034 | /* |
| 1035 | * The HT capability type byte is 3 bytes after the | ||
| 973 | * capability byte. | 1036 | * capability byte. |
| 974 | */ | 1037 | */ |
| 975 | if (pci_read_config_byte(pdev, pos + 3, &cap_type)) { | 1038 | if (pci_read_config_byte(pdev, pos + 3, &cap_type)) { |
| @@ -982,6 +1045,8 @@ static int ipath_setup_ht_config(struct ipath_devdata *dd, | |||
| 982 | } while ((pos = pci_find_next_capability(pdev, pos, | 1045 | } while ((pos = pci_find_next_capability(pdev, pos, |
| 983 | PCI_CAP_ID_HT))); | 1046 | PCI_CAP_ID_HT))); |
| 984 | 1047 | ||
| 1048 | dd->ipath_flags |= IPATH_SWAP_PIOBUFS; | ||
| 1049 | |||
| 985 | bail: | 1050 | bail: |
| 986 | return ret; | 1051 | return ret; |
| 987 | } | 1052 | } |
| @@ -1074,11 +1139,55 @@ static void ipath_setup_ht_setextled(struct ipath_devdata *dd, | |||
| 1074 | 1139 | ||
| 1075 | static void ipath_init_ht_variables(struct ipath_devdata *dd) | 1140 | static void ipath_init_ht_variables(struct ipath_devdata *dd) |
| 1076 | { | 1141 | { |
| 1142 | /* | ||
| 1143 | * setup the register offsets, since they are different for each | ||
| 1144 | * chip | ||
| 1145 | */ | ||
| 1146 | dd->ipath_kregs = &ipath_ht_kregs; | ||
| 1147 | dd->ipath_cregs = &ipath_ht_cregs; | ||
| 1148 | |||
| 1077 | dd->ipath_gpio_sda_num = _IPATH_GPIO_SDA_NUM; | 1149 | dd->ipath_gpio_sda_num = _IPATH_GPIO_SDA_NUM; |
| 1078 | dd->ipath_gpio_scl_num = _IPATH_GPIO_SCL_NUM; | 1150 | dd->ipath_gpio_scl_num = _IPATH_GPIO_SCL_NUM; |
| 1079 | dd->ipath_gpio_sda = IPATH_GPIO_SDA; | 1151 | dd->ipath_gpio_sda = IPATH_GPIO_SDA; |
| 1080 | dd->ipath_gpio_scl = IPATH_GPIO_SCL; | 1152 | dd->ipath_gpio_scl = IPATH_GPIO_SCL; |
| 1081 | 1153 | ||
| 1154 | /* | ||
| 1155 | * Fill in data for field-values that change in newer chips. | ||
| 1156 | * We dynamically specify only the mask for LINKTRAININGSTATE | ||
| 1157 | * and only the shift for LINKSTATE, as they are the only ones | ||
| 1158 | * that change. Also precalculate the 3 link states of interest | ||
| 1159 | * and the combined mask. | ||
| 1160 | */ | ||
| 1161 | dd->ibcs_ls_shift = IBA6110_IBCS_LINKSTATE_SHIFT; | ||
| 1162 | dd->ibcs_lts_mask = IBA6110_IBCS_LINKTRAININGSTATE_MASK; | ||
| 1163 | dd->ibcs_mask = (INFINIPATH_IBCS_LINKSTATE_MASK << | ||
| 1164 | dd->ibcs_ls_shift) | dd->ibcs_lts_mask; | ||
| 1165 | dd->ib_init = (INFINIPATH_IBCS_LT_STATE_LINKUP << | ||
| 1166 | INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | | ||
| 1167 | (INFINIPATH_IBCS_L_STATE_INIT << dd->ibcs_ls_shift); | ||
| 1168 | dd->ib_arm = (INFINIPATH_IBCS_LT_STATE_LINKUP << | ||
| 1169 | INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | | ||
| 1170 | (INFINIPATH_IBCS_L_STATE_ARM << dd->ibcs_ls_shift); | ||
| 1171 | dd->ib_active = (INFINIPATH_IBCS_LT_STATE_LINKUP << | ||
| 1172 | INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | | ||
| 1173 | (INFINIPATH_IBCS_L_STATE_ACTIVE << dd->ibcs_ls_shift); | ||
| 1174 | |||
| 1175 | /* | ||
| 1176 | * Fill in data for ibcc field-values that change in newer chips. | ||
| 1177 | * We dynamically specify only the mask for LINKINITCMD | ||
| 1178 | * and only the shift for LINKCMD and MAXPKTLEN, as they are | ||
| 1179 | * the only ones that change. | ||
| 1180 | */ | ||
| 1181 | dd->ibcc_lic_mask = INFINIPATH_IBCC_LINKINITCMD_MASK; | ||
| 1182 | dd->ibcc_lc_shift = INFINIPATH_IBCC_LINKCMD_SHIFT; | ||
| 1183 | dd->ibcc_mpl_shift = INFINIPATH_IBCC_MAXPKTLEN_SHIFT; | ||
| 1184 | |||
| 1185 | /* Fill in shifts for RcvCtrl. */ | ||
| 1186 | dd->ipath_r_portenable_shift = INFINIPATH_R_PORTENABLE_SHIFT; | ||
| 1187 | dd->ipath_r_intravail_shift = INFINIPATH_R_INTRAVAIL_SHIFT; | ||
| 1188 | dd->ipath_r_tailupd_shift = INFINIPATH_R_TAILUPD_SHIFT; | ||
| 1189 | dd->ipath_r_portcfg_shift = 0; /* Not on IBA6110 */ | ||
| 1190 | |||
| 1082 | dd->ipath_i_bitsextant = | 1191 | dd->ipath_i_bitsextant = |
| 1083 | (INFINIPATH_I_RCVURG_MASK << INFINIPATH_I_RCVURG_SHIFT) | | 1192 | (INFINIPATH_I_RCVURG_MASK << INFINIPATH_I_RCVURG_SHIFT) | |
| 1084 | (INFINIPATH_I_RCVAVAIL_MASK << | 1193 | (INFINIPATH_I_RCVAVAIL_MASK << |
| @@ -1135,6 +1244,8 @@ static void ipath_init_ht_variables(struct ipath_devdata *dd) | |||
| 1135 | 1244 | ||
| 1136 | dd->ipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK; | 1245 | dd->ipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK; |
| 1137 | dd->ipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK; | 1246 | dd->ipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK; |
| 1247 | dd->ipath_i_rcvavail_shift = INFINIPATH_I_RCVAVAIL_SHIFT; | ||
| 1248 | dd->ipath_i_rcvurg_shift = INFINIPATH_I_RCVURG_SHIFT; | ||
| 1138 | 1249 | ||
| 1139 | /* | 1250 | /* |
| 1140 | * EEPROM error log 0 is TXE Parity errors. 1 is RXE Parity. | 1251 | * EEPROM error log 0 is TXE Parity errors. 1 is RXE Parity. |
| @@ -1148,9 +1259,17 @@ static void ipath_init_ht_variables(struct ipath_devdata *dd) | |||
| 1148 | INFINIPATH_HWE_RXEMEMPARITYERR_MASK << | 1259 | INFINIPATH_HWE_RXEMEMPARITYERR_MASK << |
| 1149 | INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT; | 1260 | INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT; |
| 1150 | 1261 | ||
| 1151 | dd->ipath_eep_st_masks[2].errs_to_log = | 1262 | dd->ipath_eep_st_masks[2].errs_to_log = INFINIPATH_E_RESET; |
| 1152 | INFINIPATH_E_INVALIDADDR | INFINIPATH_E_RESET; | ||
| 1153 | 1263 | ||
| 1264 | dd->delay_mult = 2; /* SDR, 4X, can't change */ | ||
| 1265 | |||
| 1266 | dd->ipath_link_width_supported = IB_WIDTH_1X | IB_WIDTH_4X; | ||
| 1267 | dd->ipath_link_speed_supported = IPATH_IB_SDR; | ||
| 1268 | dd->ipath_link_width_enabled = IB_WIDTH_4X; | ||
| 1269 | dd->ipath_link_speed_enabled = dd->ipath_link_speed_supported; | ||
| 1270 | /* these can't change for this chip, so set once */ | ||
| 1271 | dd->ipath_link_width_active = dd->ipath_link_width_enabled; | ||
| 1272 | dd->ipath_link_speed_active = dd->ipath_link_speed_enabled; | ||
| 1154 | } | 1273 | } |
| 1155 | 1274 | ||
| 1156 | /** | 1275 | /** |
| @@ -1205,14 +1324,16 @@ static void ipath_ht_init_hwerrors(struct ipath_devdata *dd) | |||
| 1205 | val &= ~INFINIPATH_HWE_HTCMISCERR4; | 1324 | val &= ~INFINIPATH_HWE_HTCMISCERR4; |
| 1206 | 1325 | ||
| 1207 | /* | 1326 | /* |
| 1208 | * PLL ignored because MDIO interface has a logic problem | 1327 | * PLL ignored because unused MDIO interface has a logic problem |
| 1209 | * for reads, on Comstock and Ponderosa. BRINGUP | ||
| 1210 | */ | 1328 | */ |
| 1211 | if (dd->ipath_boardrev == 4 || dd->ipath_boardrev == 9) | 1329 | if (dd->ipath_boardrev == 4 || dd->ipath_boardrev == 9) |
| 1212 | val &= ~INFINIPATH_HWE_SERDESPLLFAILED; | 1330 | val &= ~INFINIPATH_HWE_SERDESPLLFAILED; |
| 1213 | dd->ipath_hwerrmask = val; | 1331 | dd->ipath_hwerrmask = val; |
| 1214 | } | 1332 | } |
| 1215 | 1333 | ||
| 1334 | |||
| 1335 | |||
| 1336 | |||
| 1216 | /** | 1337 | /** |
| 1217 | * ipath_ht_bringup_serdes - bring up the serdes | 1338 | * ipath_ht_bringup_serdes - bring up the serdes |
| 1218 | * @dd: the infinipath device | 1339 | * @dd: the infinipath device |
| @@ -1284,16 +1405,6 @@ static int ipath_ht_bringup_serdes(struct ipath_devdata *dd) | |||
| 1284 | } | 1405 | } |
| 1285 | 1406 | ||
| 1286 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig); | 1407 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig); |
| 1287 | if (((val >> INFINIPATH_XGXS_MDIOADDR_SHIFT) & | ||
| 1288 | INFINIPATH_XGXS_MDIOADDR_MASK) != 3) { | ||
| 1289 | val &= ~(INFINIPATH_XGXS_MDIOADDR_MASK << | ||
| 1290 | INFINIPATH_XGXS_MDIOADDR_SHIFT); | ||
| 1291 | /* | ||
| 1292 | * we use address 3 | ||
| 1293 | */ | ||
| 1294 | val |= 3ULL << INFINIPATH_XGXS_MDIOADDR_SHIFT; | ||
| 1295 | change = 1; | ||
| 1296 | } | ||
| 1297 | if (val & INFINIPATH_XGXS_RESET) { | 1408 | if (val & INFINIPATH_XGXS_RESET) { |
| 1298 | /* normally true after boot */ | 1409 | /* normally true after boot */ |
| 1299 | val &= ~INFINIPATH_XGXS_RESET; | 1410 | val &= ~INFINIPATH_XGXS_RESET; |
| @@ -1329,21 +1440,6 @@ static int ipath_ht_bringup_serdes(struct ipath_devdata *dd) | |||
| 1329 | (unsigned long long) | 1440 | (unsigned long long) |
| 1330 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig)); | 1441 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig)); |
| 1331 | 1442 | ||
| 1332 | if (!ipath_waitfor_mdio_cmdready(dd)) { | ||
| 1333 | ipath_write_kreg(dd, dd->ipath_kregs->kr_mdio, | ||
| 1334 | ipath_mdio_req(IPATH_MDIO_CMD_READ, 31, | ||
| 1335 | IPATH_MDIO_CTRL_XGXS_REG_8, | ||
| 1336 | 0)); | ||
| 1337 | if (ipath_waitfor_complete(dd, dd->ipath_kregs->kr_mdio, | ||
| 1338 | IPATH_MDIO_DATAVALID, &val)) | ||
| 1339 | ipath_dbg("Never got MDIO data for XGXS status " | ||
| 1340 | "read\n"); | ||
| 1341 | else | ||
| 1342 | ipath_cdbg(VERBOSE, "MDIO Read reg8, " | ||
| 1343 | "'bank' 31 %x\n", (u32) val); | ||
| 1344 | } else | ||
| 1345 | ipath_dbg("Never got MDIO cmdready for XGXS status read\n"); | ||
| 1346 | |||
| 1347 | return ret; /* for now, say we always succeeded */ | 1443 | return ret; /* for now, say we always succeeded */ |
| 1348 | } | 1444 | } |
| 1349 | 1445 | ||
| @@ -1396,6 +1492,7 @@ static void ipath_ht_put_tid(struct ipath_devdata *dd, | |||
| 1396 | pa |= lenvalid | INFINIPATH_RT_VALID; | 1492 | pa |= lenvalid | INFINIPATH_RT_VALID; |
| 1397 | } | 1493 | } |
| 1398 | } | 1494 | } |
| 1495 | |||
| 1399 | writeq(pa, tidptr); | 1496 | writeq(pa, tidptr); |
| 1400 | } | 1497 | } |
| 1401 | 1498 | ||
| @@ -1526,8 +1623,7 @@ static int ipath_ht_early_init(struct ipath_devdata *dd) | |||
| 1526 | } | 1623 | } |
| 1527 | 1624 | ||
| 1528 | ipath_get_eeprom_info(dd); | 1625 | ipath_get_eeprom_info(dd); |
| 1529 | if (dd->ipath_boardrev == 5 && dd->ipath_serial[0] == '1' && | 1626 | if (dd->ipath_boardrev == 5) { |
| 1530 | dd->ipath_serial[1] == '2' && dd->ipath_serial[2] == '8') { | ||
| 1531 | /* | 1627 | /* |
| 1532 | * Later production QHT7040 has same changes as QHT7140, so | 1628 | * Later production QHT7040 has same changes as QHT7140, so |
| 1533 | * can use GPIO interrupts. They have serial #'s starting | 1629 | * can use GPIO interrupts. They have serial #'s starting |
| @@ -1602,6 +1698,210 @@ static void ipath_ht_free_irq(struct ipath_devdata *dd) | |||
| 1602 | dd->ipath_intconfig = 0; | 1698 | dd->ipath_intconfig = 0; |
| 1603 | } | 1699 | } |
| 1604 | 1700 | ||
| 1701 | static struct ipath_message_header * | ||
| 1702 | ipath_ht_get_msgheader(struct ipath_devdata *dd, __le32 *rhf_addr) | ||
| 1703 | { | ||
| 1704 | return (struct ipath_message_header *) | ||
| 1705 | &rhf_addr[sizeof(u64) / sizeof(u32)]; | ||
| 1706 | } | ||
| 1707 | |||
| 1708 | static void ipath_ht_config_ports(struct ipath_devdata *dd, ushort cfgports) | ||
| 1709 | { | ||
| 1710 | dd->ipath_portcnt = | ||
| 1711 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_portcnt); | ||
| 1712 | dd->ipath_p0_rcvegrcnt = | ||
| 1713 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvegrcnt); | ||
| 1714 | } | ||
| 1715 | |||
| 1716 | static void ipath_ht_read_counters(struct ipath_devdata *dd, | ||
| 1717 | struct infinipath_counters *cntrs) | ||
| 1718 | { | ||
| 1719 | cntrs->LBIntCnt = | ||
| 1720 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(LBIntCnt)); | ||
| 1721 | cntrs->LBFlowStallCnt = | ||
| 1722 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(LBFlowStallCnt)); | ||
| 1723 | cntrs->TxSDmaDescCnt = 0; | ||
| 1724 | cntrs->TxUnsupVLErrCnt = | ||
| 1725 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxUnsupVLErrCnt)); | ||
| 1726 | cntrs->TxDataPktCnt = | ||
| 1727 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxDataPktCnt)); | ||
| 1728 | cntrs->TxFlowPktCnt = | ||
| 1729 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxFlowPktCnt)); | ||
| 1730 | cntrs->TxDwordCnt = | ||
| 1731 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxDwordCnt)); | ||
| 1732 | cntrs->TxLenErrCnt = | ||
| 1733 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxLenErrCnt)); | ||
| 1734 | cntrs->TxMaxMinLenErrCnt = | ||
| 1735 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxMaxMinLenErrCnt)); | ||
| 1736 | cntrs->TxUnderrunCnt = | ||
| 1737 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxUnderrunCnt)); | ||
| 1738 | cntrs->TxFlowStallCnt = | ||
| 1739 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxFlowStallCnt)); | ||
| 1740 | cntrs->TxDroppedPktCnt = | ||
| 1741 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxDroppedPktCnt)); | ||
| 1742 | cntrs->RxDroppedPktCnt = | ||
| 1743 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxDroppedPktCnt)); | ||
| 1744 | cntrs->RxDataPktCnt = | ||
| 1745 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxDataPktCnt)); | ||
| 1746 | cntrs->RxFlowPktCnt = | ||
| 1747 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxFlowPktCnt)); | ||
| 1748 | cntrs->RxDwordCnt = | ||
| 1749 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxDwordCnt)); | ||
| 1750 | cntrs->RxLenErrCnt = | ||
| 1751 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxLenErrCnt)); | ||
| 1752 | cntrs->RxMaxMinLenErrCnt = | ||
| 1753 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxMaxMinLenErrCnt)); | ||
| 1754 | cntrs->RxICRCErrCnt = | ||
| 1755 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxICRCErrCnt)); | ||
| 1756 | cntrs->RxVCRCErrCnt = | ||
| 1757 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxVCRCErrCnt)); | ||
| 1758 | cntrs->RxFlowCtrlErrCnt = | ||
| 1759 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxFlowCtrlErrCnt)); | ||
| 1760 | cntrs->RxBadFormatCnt = | ||
| 1761 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxBadFormatCnt)); | ||
| 1762 | cntrs->RxLinkProblemCnt = | ||
| 1763 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxLinkProblemCnt)); | ||
| 1764 | cntrs->RxEBPCnt = | ||
| 1765 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxEBPCnt)); | ||
| 1766 | cntrs->RxLPCRCErrCnt = | ||
| 1767 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxLPCRCErrCnt)); | ||
| 1768 | cntrs->RxBufOvflCnt = | ||
| 1769 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxBufOvflCnt)); | ||
| 1770 | cntrs->RxTIDFullErrCnt = | ||
| 1771 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxTIDFullErrCnt)); | ||
| 1772 | cntrs->RxTIDValidErrCnt = | ||
| 1773 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxTIDValidErrCnt)); | ||
| 1774 | cntrs->RxPKeyMismatchCnt = | ||
| 1775 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxPKeyMismatchCnt)); | ||
| 1776 | cntrs->RxP0HdrEgrOvflCnt = | ||
| 1777 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP0HdrEgrOvflCnt)); | ||
| 1778 | cntrs->RxP1HdrEgrOvflCnt = | ||
| 1779 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP1HdrEgrOvflCnt)); | ||
| 1780 | cntrs->RxP2HdrEgrOvflCnt = | ||
| 1781 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP2HdrEgrOvflCnt)); | ||
| 1782 | cntrs->RxP3HdrEgrOvflCnt = | ||
| 1783 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP3HdrEgrOvflCnt)); | ||
| 1784 | cntrs->RxP4HdrEgrOvflCnt = | ||
| 1785 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP4HdrEgrOvflCnt)); | ||
| 1786 | cntrs->RxP5HdrEgrOvflCnt = | ||
| 1787 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP5HdrEgrOvflCnt)); | ||
| 1788 | cntrs->RxP6HdrEgrOvflCnt = | ||
| 1789 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP6HdrEgrOvflCnt)); | ||
| 1790 | cntrs->RxP7HdrEgrOvflCnt = | ||
| 1791 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP7HdrEgrOvflCnt)); | ||
| 1792 | cntrs->RxP8HdrEgrOvflCnt = | ||
| 1793 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP8HdrEgrOvflCnt)); | ||
| 1794 | cntrs->RxP9HdrEgrOvflCnt = 0; | ||
| 1795 | cntrs->RxP10HdrEgrOvflCnt = 0; | ||
| 1796 | cntrs->RxP11HdrEgrOvflCnt = 0; | ||
| 1797 | cntrs->RxP12HdrEgrOvflCnt = 0; | ||
| 1798 | cntrs->RxP13HdrEgrOvflCnt = 0; | ||
| 1799 | cntrs->RxP14HdrEgrOvflCnt = 0; | ||
| 1800 | cntrs->RxP15HdrEgrOvflCnt = 0; | ||
| 1801 | cntrs->RxP16HdrEgrOvflCnt = 0; | ||
| 1802 | cntrs->IBStatusChangeCnt = | ||
| 1803 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(IBStatusChangeCnt)); | ||
| 1804 | cntrs->IBLinkErrRecoveryCnt = | ||
| 1805 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(IBLinkErrRecoveryCnt)); | ||
| 1806 | cntrs->IBLinkDownedCnt = | ||
| 1807 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(IBLinkDownedCnt)); | ||
| 1808 | cntrs->IBSymbolErrCnt = | ||
| 1809 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(IBSymbolErrCnt)); | ||
| 1810 | cntrs->RxVL15DroppedPktCnt = 0; | ||
| 1811 | cntrs->RxOtherLocalPhyErrCnt = 0; | ||
| 1812 | cntrs->PcieRetryBufDiagQwordCnt = 0; | ||
| 1813 | cntrs->ExcessBufferOvflCnt = dd->ipath_overrun_thresh_errs; | ||
| 1814 | cntrs->LocalLinkIntegrityErrCnt = | ||
| 1815 | (dd->ipath_flags & IPATH_GPIO_ERRINTRS) ? | ||
| 1816 | dd->ipath_lli_errs : dd->ipath_lli_errors; | ||
| 1817 | cntrs->RxVlErrCnt = 0; | ||
| 1818 | cntrs->RxDlidFltrCnt = 0; | ||
| 1819 | } | ||
| 1820 | |||
| 1821 | |||
| 1822 | /* no interrupt fallback for these chips */ | ||
| 1823 | static int ipath_ht_nointr_fallback(struct ipath_devdata *dd) | ||
| 1824 | { | ||
| 1825 | return 0; | ||
| 1826 | } | ||
| 1827 | |||
| 1828 | |||
| 1829 | /* | ||
| 1830 | * reset the XGXS (between serdes and IBC). Slightly less intrusive | ||
| 1831 | * than resetting the IBC or external link state, and useful in some | ||
| 1832 | * cases to cause some retraining. To do this right, we reset IBC | ||
| 1833 | * as well. | ||
| 1834 | */ | ||
| 1835 | static void ipath_ht_xgxs_reset(struct ipath_devdata *dd) | ||
| 1836 | { | ||
| 1837 | u64 val, prev_val; | ||
| 1838 | |||
| 1839 | prev_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig); | ||
| 1840 | val = prev_val | INFINIPATH_XGXS_RESET; | ||
| 1841 | prev_val &= ~INFINIPATH_XGXS_RESET; /* be sure */ | ||
| 1842 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, | ||
| 1843 | dd->ipath_control & ~INFINIPATH_C_LINKENABLE); | ||
| 1844 | ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val); | ||
| 1845 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); | ||
| 1846 | ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, prev_val); | ||
| 1847 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, | ||
| 1848 | dd->ipath_control); | ||
| 1849 | } | ||
| 1850 | |||
| 1851 | |||
| 1852 | static int ipath_ht_get_ib_cfg(struct ipath_devdata *dd, int which) | ||
| 1853 | { | ||
| 1854 | int ret; | ||
| 1855 | |||
| 1856 | switch (which) { | ||
| 1857 | case IPATH_IB_CFG_LWID: | ||
| 1858 | ret = dd->ipath_link_width_active; | ||
| 1859 | break; | ||
| 1860 | case IPATH_IB_CFG_SPD: | ||
| 1861 | ret = dd->ipath_link_speed_active; | ||
| 1862 | break; | ||
| 1863 | case IPATH_IB_CFG_LWID_ENB: | ||
| 1864 | ret = dd->ipath_link_width_enabled; | ||
| 1865 | break; | ||
| 1866 | case IPATH_IB_CFG_SPD_ENB: | ||
| 1867 | ret = dd->ipath_link_speed_enabled; | ||
| 1868 | break; | ||
| 1869 | default: | ||
| 1870 | ret = -ENOTSUPP; | ||
| 1871 | break; | ||
| 1872 | } | ||
| 1873 | return ret; | ||
| 1874 | } | ||
| 1875 | |||
| 1876 | |||
| 1877 | /* we assume range checking is already done, if needed */ | ||
| 1878 | static int ipath_ht_set_ib_cfg(struct ipath_devdata *dd, int which, u32 val) | ||
| 1879 | { | ||
| 1880 | int ret = 0; | ||
| 1881 | |||
| 1882 | if (which == IPATH_IB_CFG_LWID_ENB) | ||
| 1883 | dd->ipath_link_width_enabled = val; | ||
| 1884 | else if (which == IPATH_IB_CFG_SPD_ENB) | ||
| 1885 | dd->ipath_link_speed_enabled = val; | ||
| 1886 | else | ||
| 1887 | ret = -ENOTSUPP; | ||
| 1888 | return ret; | ||
| 1889 | } | ||
| 1890 | |||
| 1891 | |||
| 1892 | static void ipath_ht_config_jint(struct ipath_devdata *dd, u16 a, u16 b) | ||
| 1893 | { | ||
| 1894 | } | ||
| 1895 | |||
| 1896 | |||
| 1897 | static int ipath_ht_ib_updown(struct ipath_devdata *dd, int ibup, u64 ibcs) | ||
| 1898 | { | ||
| 1899 | ipath_setup_ht_setextled(dd, ipath_ib_linkstate(dd, ibcs), | ||
| 1900 | ipath_ib_linktrstate(dd, ibcs)); | ||
| 1901 | return 0; | ||
| 1902 | } | ||
| 1903 | |||
| 1904 | |||
| 1605 | /** | 1905 | /** |
| 1606 | * ipath_init_iba6110_funcs - set up the chip-specific function pointers | 1906 | * ipath_init_iba6110_funcs - set up the chip-specific function pointers |
| 1607 | * @dd: the infinipath device | 1907 | * @dd: the infinipath device |
| @@ -1626,22 +1926,19 @@ void ipath_init_iba6110_funcs(struct ipath_devdata *dd) | |||
| 1626 | dd->ipath_f_setextled = ipath_setup_ht_setextled; | 1926 | dd->ipath_f_setextled = ipath_setup_ht_setextled; |
| 1627 | dd->ipath_f_get_base_info = ipath_ht_get_base_info; | 1927 | dd->ipath_f_get_base_info = ipath_ht_get_base_info; |
| 1628 | dd->ipath_f_free_irq = ipath_ht_free_irq; | 1928 | dd->ipath_f_free_irq = ipath_ht_free_irq; |
| 1629 | |||
| 1630 | /* | ||
| 1631 | * initialize chip-specific variables | ||
| 1632 | */ | ||
| 1633 | dd->ipath_f_tidtemplate = ipath_ht_tidtemplate; | 1929 | dd->ipath_f_tidtemplate = ipath_ht_tidtemplate; |
| 1930 | dd->ipath_f_intr_fallback = ipath_ht_nointr_fallback; | ||
| 1931 | dd->ipath_f_get_msgheader = ipath_ht_get_msgheader; | ||
| 1932 | dd->ipath_f_config_ports = ipath_ht_config_ports; | ||
| 1933 | dd->ipath_f_read_counters = ipath_ht_read_counters; | ||
| 1934 | dd->ipath_f_xgxs_reset = ipath_ht_xgxs_reset; | ||
| 1935 | dd->ipath_f_get_ib_cfg = ipath_ht_get_ib_cfg; | ||
| 1936 | dd->ipath_f_set_ib_cfg = ipath_ht_set_ib_cfg; | ||
| 1937 | dd->ipath_f_config_jint = ipath_ht_config_jint; | ||
| 1938 | dd->ipath_f_ib_updown = ipath_ht_ib_updown; | ||
| 1634 | 1939 | ||
| 1635 | /* | 1940 | /* |
| 1636 | * setup the register offsets, since they are different for each | 1941 | * initialize chip-specific variables |
| 1637 | * chip | ||
| 1638 | */ | ||
| 1639 | dd->ipath_kregs = &ipath_ht_kregs; | ||
| 1640 | dd->ipath_cregs = &ipath_ht_cregs; | ||
| 1641 | |||
| 1642 | /* | ||
| 1643 | * do very early init that is needed before ipath_f_bus is | ||
| 1644 | * called | ||
| 1645 | */ | 1942 | */ |
| 1646 | ipath_init_ht_variables(dd); | 1943 | ipath_init_ht_variables(dd); |
| 1647 | } | 1944 | } |
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c index 0103d6f4847b..c7a2f50824c0 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba6120.c +++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c | |||
| @@ -145,10 +145,57 @@ struct _infinipath_do_not_use_kernel_regs { | |||
| 145 | unsigned long long Reserved12; | 145 | unsigned long long Reserved12; |
| 146 | }; | 146 | }; |
| 147 | 147 | ||
| 148 | #define IPATH_KREG_OFFSET(field) (offsetof(struct \ | 148 | struct _infinipath_do_not_use_counters { |
| 149 | _infinipath_do_not_use_kernel_regs, field) / sizeof(u64)) | 149 | __u64 LBIntCnt; |
| 150 | __u64 LBFlowStallCnt; | ||
| 151 | __u64 Reserved1; | ||
| 152 | __u64 TxUnsupVLErrCnt; | ||
| 153 | __u64 TxDataPktCnt; | ||
| 154 | __u64 TxFlowPktCnt; | ||
| 155 | __u64 TxDwordCnt; | ||
| 156 | __u64 TxLenErrCnt; | ||
| 157 | __u64 TxMaxMinLenErrCnt; | ||
| 158 | __u64 TxUnderrunCnt; | ||
| 159 | __u64 TxFlowStallCnt; | ||
| 160 | __u64 TxDroppedPktCnt; | ||
| 161 | __u64 RxDroppedPktCnt; | ||
| 162 | __u64 RxDataPktCnt; | ||
| 163 | __u64 RxFlowPktCnt; | ||
| 164 | __u64 RxDwordCnt; | ||
| 165 | __u64 RxLenErrCnt; | ||
| 166 | __u64 RxMaxMinLenErrCnt; | ||
| 167 | __u64 RxICRCErrCnt; | ||
| 168 | __u64 RxVCRCErrCnt; | ||
| 169 | __u64 RxFlowCtrlErrCnt; | ||
| 170 | __u64 RxBadFormatCnt; | ||
| 171 | __u64 RxLinkProblemCnt; | ||
| 172 | __u64 RxEBPCnt; | ||
| 173 | __u64 RxLPCRCErrCnt; | ||
| 174 | __u64 RxBufOvflCnt; | ||
| 175 | __u64 RxTIDFullErrCnt; | ||
| 176 | __u64 RxTIDValidErrCnt; | ||
| 177 | __u64 RxPKeyMismatchCnt; | ||
| 178 | __u64 RxP0HdrEgrOvflCnt; | ||
| 179 | __u64 RxP1HdrEgrOvflCnt; | ||
| 180 | __u64 RxP2HdrEgrOvflCnt; | ||
| 181 | __u64 RxP3HdrEgrOvflCnt; | ||
| 182 | __u64 RxP4HdrEgrOvflCnt; | ||
| 183 | __u64 RxP5HdrEgrOvflCnt; | ||
| 184 | __u64 RxP6HdrEgrOvflCnt; | ||
| 185 | __u64 RxP7HdrEgrOvflCnt; | ||
| 186 | __u64 RxP8HdrEgrOvflCnt; | ||
| 187 | __u64 Reserved6; | ||
| 188 | __u64 Reserved7; | ||
| 189 | __u64 IBStatusChangeCnt; | ||
| 190 | __u64 IBLinkErrRecoveryCnt; | ||
| 191 | __u64 IBLinkDownedCnt; | ||
| 192 | __u64 IBSymbolErrCnt; | ||
| 193 | }; | ||
| 194 | |||
| 195 | #define IPATH_KREG_OFFSET(field) (offsetof( \ | ||
| 196 | struct _infinipath_do_not_use_kernel_regs, field) / sizeof(u64)) | ||
| 150 | #define IPATH_CREG_OFFSET(field) (offsetof( \ | 197 | #define IPATH_CREG_OFFSET(field) (offsetof( \ |
| 151 | struct infinipath_counters, field) / sizeof(u64)) | 198 | struct _infinipath_do_not_use_counters, field) / sizeof(u64)) |
| 152 | 199 | ||
| 153 | static const struct ipath_kregs ipath_pe_kregs = { | 200 | static const struct ipath_kregs ipath_pe_kregs = { |
| 154 | .kr_control = IPATH_KREG_OFFSET(Control), | 201 | .kr_control = IPATH_KREG_OFFSET(Control), |
| @@ -282,6 +329,9 @@ static const struct ipath_cregs ipath_pe_cregs = { | |||
| 282 | #define INFINIPATH_HWE_PCIE0PLLFAILED 0x0800000000000000ULL | 329 | #define INFINIPATH_HWE_PCIE0PLLFAILED 0x0800000000000000ULL |
| 283 | #define INFINIPATH_HWE_SERDESPLLFAILED 0x1000000000000000ULL | 330 | #define INFINIPATH_HWE_SERDESPLLFAILED 0x1000000000000000ULL |
| 284 | 331 | ||
| 332 | #define IBA6120_IBCS_LINKTRAININGSTATE_MASK 0xf | ||
| 333 | #define IBA6120_IBCS_LINKSTATE_SHIFT 4 | ||
| 334 | |||
| 285 | /* kr_extstatus bits */ | 335 | /* kr_extstatus bits */ |
| 286 | #define INFINIPATH_EXTS_FREQSEL 0x2 | 336 | #define INFINIPATH_EXTS_FREQSEL 0x2 |
| 287 | #define INFINIPATH_EXTS_SERDESSEL 0x4 | 337 | #define INFINIPATH_EXTS_SERDESSEL 0x4 |
| @@ -296,6 +346,9 @@ static const struct ipath_cregs ipath_pe_cregs = { | |||
| 296 | #define IPATH_GPIO_SCL (1ULL << \ | 346 | #define IPATH_GPIO_SCL (1ULL << \ |
| 297 | (_IPATH_GPIO_SCL_NUM+INFINIPATH_EXTC_GPIOOE_SHIFT)) | 347 | (_IPATH_GPIO_SCL_NUM+INFINIPATH_EXTC_GPIOOE_SHIFT)) |
| 298 | 348 | ||
| 349 | #define INFINIPATH_R_INTRAVAIL_SHIFT 16 | ||
| 350 | #define INFINIPATH_R_TAILUPD_SHIFT 31 | ||
| 351 | |||
| 299 | /* 6120 specific hardware errors... */ | 352 | /* 6120 specific hardware errors... */ |
| 300 | static const struct ipath_hwerror_msgs ipath_6120_hwerror_msgs[] = { | 353 | static const struct ipath_hwerror_msgs ipath_6120_hwerror_msgs[] = { |
| 301 | INFINIPATH_HWE_MSG(PCIEPOISONEDTLP, "PCIe Poisoned TLP"), | 354 | INFINIPATH_HWE_MSG(PCIEPOISONEDTLP, "PCIe Poisoned TLP"), |
| @@ -320,10 +373,28 @@ static const struct ipath_hwerror_msgs ipath_6120_hwerror_msgs[] = { | |||
| 320 | INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC) \ | 373 | INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC) \ |
| 321 | << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) | 374 | << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) |
| 322 | 375 | ||
| 323 | static int ipath_pe_txe_recover(struct ipath_devdata *); | ||
| 324 | static void ipath_pe_put_tid_2(struct ipath_devdata *, u64 __iomem *, | 376 | static void ipath_pe_put_tid_2(struct ipath_devdata *, u64 __iomem *, |
| 325 | u32, unsigned long); | 377 | u32, unsigned long); |
| 326 | 378 | ||
| 379 | /* | ||
| 380 | * On platforms using this chip, and not having ordered WC stores, we | ||
| 381 | * can get TXE parity errors due to speculative reads to the PIO buffers, | ||
| 382 | * and this, due to a chip bug can result in (many) false parity error | ||
| 383 | * reports. So it's a debug print on those, and an info print on systems | ||
| 384 | * where the speculative reads don't occur. | ||
| 385 | */ | ||
| 386 | static void ipath_pe_txe_recover(struct ipath_devdata *dd) | ||
| 387 | { | ||
| 388 | if (ipath_unordered_wc()) | ||
| 389 | ipath_dbg("Recovering from TXE PIO parity error\n"); | ||
| 390 | else { | ||
| 391 | ++ipath_stats.sps_txeparity; | ||
| 392 | dev_info(&dd->pcidev->dev, | ||
| 393 | "Recovering from TXE PIO parity error\n"); | ||
| 394 | } | ||
| 395 | } | ||
| 396 | |||
| 397 | |||
| 327 | /** | 398 | /** |
| 328 | * ipath_pe_handle_hwerrors - display hardware errors. | 399 | * ipath_pe_handle_hwerrors - display hardware errors. |
| 329 | * @dd: the infinipath device | 400 | * @dd: the infinipath device |
| @@ -403,35 +474,11 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg, | |||
| 403 | * occur if a processor speculative read is done to the PIO | 474 | * occur if a processor speculative read is done to the PIO |
| 404 | * buffer while we are sending a packet, for example. | 475 | * buffer while we are sending a packet, for example. |
| 405 | */ | 476 | */ |
| 406 | if ((hwerrs & TXE_PIO_PARITY) && ipath_pe_txe_recover(dd)) | 477 | if (hwerrs & TXE_PIO_PARITY) { |
| 478 | ipath_pe_txe_recover(dd); | ||
| 407 | hwerrs &= ~TXE_PIO_PARITY; | 479 | hwerrs &= ~TXE_PIO_PARITY; |
| 408 | if (hwerrs) { | 480 | } |
| 409 | /* | 481 | if (!hwerrs) { |
| 410 | * if any set that we aren't ignoring only make the | ||
| 411 | * complaint once, in case it's stuck or recurring, | ||
| 412 | * and we get here multiple times | ||
| 413 | * Force link down, so switch knows, and | ||
| 414 | * LEDs are turned off | ||
| 415 | */ | ||
| 416 | if (dd->ipath_flags & IPATH_INITTED) { | ||
| 417 | ipath_set_linkstate(dd, IPATH_IB_LINKDOWN); | ||
| 418 | ipath_setup_pe_setextled(dd, | ||
| 419 | INFINIPATH_IBCS_L_STATE_DOWN, | ||
| 420 | INFINIPATH_IBCS_LT_STATE_DISABLED); | ||
| 421 | ipath_dev_err(dd, "Fatal Hardware Error (freeze " | ||
| 422 | "mode), no longer usable, SN %.16s\n", | ||
| 423 | dd->ipath_serial); | ||
| 424 | isfatal = 1; | ||
| 425 | } | ||
| 426 | /* | ||
| 427 | * Mark as having had an error for driver, and also | ||
| 428 | * for /sys and status word mapped to user programs. | ||
| 429 | * This marks unit as not usable, until reset | ||
| 430 | */ | ||
| 431 | *dd->ipath_statusp &= ~IPATH_STATUS_IB_READY; | ||
| 432 | *dd->ipath_statusp |= IPATH_STATUS_HWERROR; | ||
| 433 | dd->ipath_flags &= ~IPATH_INITTED; | ||
| 434 | } else { | ||
| 435 | static u32 freeze_cnt; | 482 | static u32 freeze_cnt; |
| 436 | 483 | ||
| 437 | freeze_cnt++; | 484 | freeze_cnt++; |
| @@ -485,7 +532,7 @@ static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg, | |||
| 485 | 532 | ||
| 486 | if (hwerrs & INFINIPATH_HWE_SERDESPLLFAILED) { | 533 | if (hwerrs & INFINIPATH_HWE_SERDESPLLFAILED) { |
| 487 | /* | 534 | /* |
| 488 | * If it occurs, it is left masked since the eternal | 535 | * If it occurs, it is left masked since the external |
| 489 | * interface is unused | 536 | * interface is unused |
| 490 | */ | 537 | */ |
| 491 | dd->ipath_hwerrmask &= ~INFINIPATH_HWE_SERDESPLLFAILED; | 538 | dd->ipath_hwerrmask &= ~INFINIPATH_HWE_SERDESPLLFAILED; |
| @@ -563,6 +610,14 @@ static int ipath_pe_boardname(struct ipath_devdata *dd, char *name, | |||
| 563 | dd->ipath_f_put_tid = ipath_pe_put_tid_2; | 610 | dd->ipath_f_put_tid = ipath_pe_put_tid_2; |
| 564 | } | 611 | } |
| 565 | 612 | ||
| 613 | |||
| 614 | /* | ||
| 615 | * set here, not in ipath_init_*_funcs because we have to do | ||
| 616 | * it after we can read chip registers. | ||
| 617 | */ | ||
| 618 | dd->ipath_ureg_align = | ||
| 619 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_pagealign); | ||
| 620 | |||
| 566 | return ret; | 621 | return ret; |
| 567 | } | 622 | } |
| 568 | 623 | ||
| @@ -667,17 +722,8 @@ static int ipath_pe_bringup_serdes(struct ipath_devdata *dd) | |||
| 667 | 722 | ||
| 668 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig); | 723 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig); |
| 669 | prev_val = val; | 724 | prev_val = val; |
| 670 | if (((val >> INFINIPATH_XGXS_MDIOADDR_SHIFT) & | 725 | if (val & INFINIPATH_XGXS_RESET) |
| 671 | INFINIPATH_XGXS_MDIOADDR_MASK) != 3) { | ||
| 672 | val &= | ||
| 673 | ~(INFINIPATH_XGXS_MDIOADDR_MASK << | ||
| 674 | INFINIPATH_XGXS_MDIOADDR_SHIFT); | ||
| 675 | /* MDIO address 3 */ | ||
| 676 | val |= 3ULL << INFINIPATH_XGXS_MDIOADDR_SHIFT; | ||
| 677 | } | ||
| 678 | if (val & INFINIPATH_XGXS_RESET) { | ||
| 679 | val &= ~INFINIPATH_XGXS_RESET; | 726 | val &= ~INFINIPATH_XGXS_RESET; |
| 680 | } | ||
| 681 | if (((val >> INFINIPATH_XGXS_RX_POL_SHIFT) & | 727 | if (((val >> INFINIPATH_XGXS_RX_POL_SHIFT) & |
| 682 | INFINIPATH_XGXS_RX_POL_MASK) != dd->ipath_rx_pol_inv ) { | 728 | INFINIPATH_XGXS_RX_POL_MASK) != dd->ipath_rx_pol_inv ) { |
| 683 | /* need to compensate for Tx inversion in partner */ | 729 | /* need to compensate for Tx inversion in partner */ |
| @@ -707,21 +753,6 @@ static int ipath_pe_bringup_serdes(struct ipath_devdata *dd) | |||
| 707 | (unsigned long long) | 753 | (unsigned long long) |
| 708 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig)); | 754 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig)); |
| 709 | 755 | ||
| 710 | if (!ipath_waitfor_mdio_cmdready(dd)) { | ||
| 711 | ipath_write_kreg( | ||
| 712 | dd, dd->ipath_kregs->kr_mdio, | ||
| 713 | ipath_mdio_req(IPATH_MDIO_CMD_READ, 31, | ||
| 714 | IPATH_MDIO_CTRL_XGXS_REG_8, 0)); | ||
| 715 | if (ipath_waitfor_complete(dd, dd->ipath_kregs->kr_mdio, | ||
| 716 | IPATH_MDIO_DATAVALID, &val)) | ||
| 717 | ipath_dbg("Never got MDIO data for XGXS " | ||
| 718 | "status read\n"); | ||
| 719 | else | ||
| 720 | ipath_cdbg(VERBOSE, "MDIO Read reg8, " | ||
| 721 | "'bank' 31 %x\n", (u32) val); | ||
| 722 | } else | ||
| 723 | ipath_dbg("Never got MDIO cmdready for XGXS status read\n"); | ||
| 724 | |||
| 725 | return ret; | 756 | return ret; |
| 726 | } | 757 | } |
| 727 | 758 | ||
| @@ -902,12 +933,27 @@ static int ipath_setup_pe_config(struct ipath_devdata *dd, | |||
| 902 | else | 933 | else |
| 903 | ipath_dev_err(dd, "Can't find PCI Express " | 934 | ipath_dev_err(dd, "Can't find PCI Express " |
| 904 | "capability!\n"); | 935 | "capability!\n"); |
| 936 | |||
| 937 | dd->ipath_link_width_supported = IB_WIDTH_1X | IB_WIDTH_4X; | ||
| 938 | dd->ipath_link_speed_supported = IPATH_IB_SDR; | ||
| 939 | dd->ipath_link_width_enabled = IB_WIDTH_4X; | ||
| 940 | dd->ipath_link_speed_enabled = dd->ipath_link_speed_supported; | ||
| 941 | /* these can't change for this chip, so set once */ | ||
| 942 | dd->ipath_link_width_active = dd->ipath_link_width_enabled; | ||
| 943 | dd->ipath_link_speed_active = dd->ipath_link_speed_enabled; | ||
| 905 | return 0; | 944 | return 0; |
| 906 | } | 945 | } |
| 907 | 946 | ||
| 908 | static void ipath_init_pe_variables(struct ipath_devdata *dd) | 947 | static void ipath_init_pe_variables(struct ipath_devdata *dd) |
| 909 | { | 948 | { |
| 910 | /* | 949 | /* |
| 950 | * setup the register offsets, since they are different for each | ||
| 951 | * chip | ||
| 952 | */ | ||
| 953 | dd->ipath_kregs = &ipath_pe_kregs; | ||
| 954 | dd->ipath_cregs = &ipath_pe_cregs; | ||
| 955 | |||
| 956 | /* | ||
| 911 | * bits for selecting i2c direction and values, | 957 | * bits for selecting i2c direction and values, |
| 912 | * used for I2C serial flash | 958 | * used for I2C serial flash |
| 913 | */ | 959 | */ |
| @@ -916,6 +962,43 @@ static void ipath_init_pe_variables(struct ipath_devdata *dd) | |||
| 916 | dd->ipath_gpio_sda = IPATH_GPIO_SDA; | 962 | dd->ipath_gpio_sda = IPATH_GPIO_SDA; |
| 917 | dd->ipath_gpio_scl = IPATH_GPIO_SCL; | 963 | dd->ipath_gpio_scl = IPATH_GPIO_SCL; |
| 918 | 964 | ||
| 965 | /* | ||
| 966 | * Fill in data for field-values that change in newer chips. | ||
| 967 | * We dynamically specify only the mask for LINKTRAININGSTATE | ||
| 968 | * and only the shift for LINKSTATE, as they are the only ones | ||
| 969 | * that change. Also precalculate the 3 link states of interest | ||
| 970 | * and the combined mask. | ||
| 971 | */ | ||
| 972 | dd->ibcs_ls_shift = IBA6120_IBCS_LINKSTATE_SHIFT; | ||
| 973 | dd->ibcs_lts_mask = IBA6120_IBCS_LINKTRAININGSTATE_MASK; | ||
| 974 | dd->ibcs_mask = (INFINIPATH_IBCS_LINKSTATE_MASK << | ||
| 975 | dd->ibcs_ls_shift) | dd->ibcs_lts_mask; | ||
| 976 | dd->ib_init = (INFINIPATH_IBCS_LT_STATE_LINKUP << | ||
| 977 | INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | | ||
| 978 | (INFINIPATH_IBCS_L_STATE_INIT << dd->ibcs_ls_shift); | ||
| 979 | dd->ib_arm = (INFINIPATH_IBCS_LT_STATE_LINKUP << | ||
| 980 | INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | | ||
| 981 | (INFINIPATH_IBCS_L_STATE_ARM << dd->ibcs_ls_shift); | ||
| 982 | dd->ib_active = (INFINIPATH_IBCS_LT_STATE_LINKUP << | ||
| 983 | INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | | ||
| 984 | (INFINIPATH_IBCS_L_STATE_ACTIVE << dd->ibcs_ls_shift); | ||
| 985 | |||
| 986 | /* | ||
| 987 | * Fill in data for ibcc field-values that change in newer chips. | ||
| 988 | * We dynamically specify only the mask for LINKINITCMD | ||
| 989 | * and only the shift for LINKCMD and MAXPKTLEN, as they are | ||
| 990 | * the only ones that change. | ||
| 991 | */ | ||
| 992 | dd->ibcc_lic_mask = INFINIPATH_IBCC_LINKINITCMD_MASK; | ||
| 993 | dd->ibcc_lc_shift = INFINIPATH_IBCC_LINKCMD_SHIFT; | ||
| 994 | dd->ibcc_mpl_shift = INFINIPATH_IBCC_MAXPKTLEN_SHIFT; | ||
| 995 | |||
| 996 | /* Fill in shifts for RcvCtrl. */ | ||
| 997 | dd->ipath_r_portenable_shift = INFINIPATH_R_PORTENABLE_SHIFT; | ||
| 998 | dd->ipath_r_intravail_shift = INFINIPATH_R_INTRAVAIL_SHIFT; | ||
| 999 | dd->ipath_r_tailupd_shift = INFINIPATH_R_TAILUPD_SHIFT; | ||
| 1000 | dd->ipath_r_portcfg_shift = 0; /* Not on IBA6120 */ | ||
| 1001 | |||
| 919 | /* variables for sanity checking interrupt and errors */ | 1002 | /* variables for sanity checking interrupt and errors */ |
| 920 | dd->ipath_hwe_bitsextant = | 1003 | dd->ipath_hwe_bitsextant = |
| 921 | (INFINIPATH_HWE_RXEMEMPARITYERR_MASK << | 1004 | (INFINIPATH_HWE_RXEMEMPARITYERR_MASK << |
| @@ -963,6 +1046,8 @@ static void ipath_init_pe_variables(struct ipath_devdata *dd) | |||
| 963 | 1046 | ||
| 964 | dd->ipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK; | 1047 | dd->ipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK; |
| 965 | dd->ipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK; | 1048 | dd->ipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK; |
| 1049 | dd->ipath_i_rcvavail_shift = INFINIPATH_I_RCVAVAIL_SHIFT; | ||
| 1050 | dd->ipath_i_rcvurg_shift = INFINIPATH_I_RCVURG_SHIFT; | ||
| 966 | 1051 | ||
| 967 | /* | 1052 | /* |
| 968 | * EEPROM error log 0 is TXE Parity errors. 1 is RXE Parity. | 1053 | * EEPROM error log 0 is TXE Parity errors. 1 is RXE Parity. |
| @@ -984,6 +1069,7 @@ static void ipath_init_pe_variables(struct ipath_devdata *dd) | |||
| 984 | INFINIPATH_E_INVALIDADDR | INFINIPATH_E_RESET; | 1069 | INFINIPATH_E_INVALIDADDR | INFINIPATH_E_RESET; |
| 985 | 1070 | ||
| 986 | 1071 | ||
| 1072 | dd->delay_mult = 2; /* SDR, 4X, can't change */ | ||
| 987 | } | 1073 | } |
| 988 | 1074 | ||
| 989 | /* setup the MSI stuff again after a reset. I'd like to just call | 1075 | /* setup the MSI stuff again after a reset. I'd like to just call |
| @@ -1289,6 +1375,9 @@ static int ipath_pe_early_init(struct ipath_devdata *dd) | |||
| 1289 | */ | 1375 | */ |
| 1290 | dd->ipath_rcvhdrentsize = 24; | 1376 | dd->ipath_rcvhdrentsize = 24; |
| 1291 | dd->ipath_rcvhdrsize = IPATH_DFLT_RCVHDRSIZE; | 1377 | dd->ipath_rcvhdrsize = IPATH_DFLT_RCVHDRSIZE; |
| 1378 | dd->ipath_rhf_offset = 0; | ||
| 1379 | dd->ipath_egrtidbase = (u64 __iomem *) | ||
| 1380 | ((char __iomem *) dd->ipath_kregbase + dd->ipath_rcvegrbase); | ||
| 1292 | 1381 | ||
| 1293 | /* | 1382 | /* |
| 1294 | * To truly support a 4KB MTU (for usermode), we need to | 1383 | * To truly support a 4KB MTU (for usermode), we need to |
| @@ -1359,34 +1448,204 @@ static void ipath_pe_free_irq(struct ipath_devdata *dd) | |||
| 1359 | dd->ipath_irq = 0; | 1448 | dd->ipath_irq = 0; |
| 1360 | } | 1449 | } |
| 1361 | 1450 | ||
| 1451 | |||
| 1452 | static struct ipath_message_header * | ||
| 1453 | ipath_pe_get_msgheader(struct ipath_devdata *dd, __le32 *rhf_addr) | ||
| 1454 | { | ||
| 1455 | return (struct ipath_message_header *) | ||
| 1456 | &rhf_addr[sizeof(u64) / sizeof(u32)]; | ||
| 1457 | } | ||
| 1458 | |||
| 1459 | static void ipath_pe_config_ports(struct ipath_devdata *dd, ushort cfgports) | ||
| 1460 | { | ||
| 1461 | dd->ipath_portcnt = | ||
| 1462 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_portcnt); | ||
| 1463 | dd->ipath_p0_rcvegrcnt = | ||
| 1464 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvegrcnt); | ||
| 1465 | } | ||
| 1466 | |||
| 1467 | static void ipath_pe_read_counters(struct ipath_devdata *dd, | ||
| 1468 | struct infinipath_counters *cntrs) | ||
| 1469 | { | ||
| 1470 | cntrs->LBIntCnt = | ||
| 1471 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(LBIntCnt)); | ||
| 1472 | cntrs->LBFlowStallCnt = | ||
| 1473 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(LBFlowStallCnt)); | ||
| 1474 | cntrs->TxSDmaDescCnt = 0; | ||
| 1475 | cntrs->TxUnsupVLErrCnt = | ||
| 1476 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxUnsupVLErrCnt)); | ||
| 1477 | cntrs->TxDataPktCnt = | ||
| 1478 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxDataPktCnt)); | ||
| 1479 | cntrs->TxFlowPktCnt = | ||
| 1480 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxFlowPktCnt)); | ||
| 1481 | cntrs->TxDwordCnt = | ||
| 1482 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxDwordCnt)); | ||
| 1483 | cntrs->TxLenErrCnt = | ||
| 1484 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxLenErrCnt)); | ||
| 1485 | cntrs->TxMaxMinLenErrCnt = | ||
| 1486 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxMaxMinLenErrCnt)); | ||
| 1487 | cntrs->TxUnderrunCnt = | ||
| 1488 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxUnderrunCnt)); | ||
| 1489 | cntrs->TxFlowStallCnt = | ||
| 1490 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxFlowStallCnt)); | ||
| 1491 | cntrs->TxDroppedPktCnt = | ||
| 1492 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxDroppedPktCnt)); | ||
| 1493 | cntrs->RxDroppedPktCnt = | ||
| 1494 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxDroppedPktCnt)); | ||
| 1495 | cntrs->RxDataPktCnt = | ||
| 1496 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxDataPktCnt)); | ||
| 1497 | cntrs->RxFlowPktCnt = | ||
| 1498 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxFlowPktCnt)); | ||
| 1499 | cntrs->RxDwordCnt = | ||
| 1500 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxDwordCnt)); | ||
| 1501 | cntrs->RxLenErrCnt = | ||
| 1502 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxLenErrCnt)); | ||
| 1503 | cntrs->RxMaxMinLenErrCnt = | ||
| 1504 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxMaxMinLenErrCnt)); | ||
| 1505 | cntrs->RxICRCErrCnt = | ||
| 1506 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxICRCErrCnt)); | ||
| 1507 | cntrs->RxVCRCErrCnt = | ||
| 1508 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxVCRCErrCnt)); | ||
| 1509 | cntrs->RxFlowCtrlErrCnt = | ||
| 1510 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxFlowCtrlErrCnt)); | ||
| 1511 | cntrs->RxBadFormatCnt = | ||
| 1512 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxBadFormatCnt)); | ||
| 1513 | cntrs->RxLinkProblemCnt = | ||
| 1514 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxLinkProblemCnt)); | ||
| 1515 | cntrs->RxEBPCnt = | ||
| 1516 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxEBPCnt)); | ||
| 1517 | cntrs->RxLPCRCErrCnt = | ||
| 1518 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxLPCRCErrCnt)); | ||
| 1519 | cntrs->RxBufOvflCnt = | ||
| 1520 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxBufOvflCnt)); | ||
| 1521 | cntrs->RxTIDFullErrCnt = | ||
| 1522 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxTIDFullErrCnt)); | ||
| 1523 | cntrs->RxTIDValidErrCnt = | ||
| 1524 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxTIDValidErrCnt)); | ||
| 1525 | cntrs->RxPKeyMismatchCnt = | ||
| 1526 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxPKeyMismatchCnt)); | ||
| 1527 | cntrs->RxP0HdrEgrOvflCnt = | ||
| 1528 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP0HdrEgrOvflCnt)); | ||
| 1529 | cntrs->RxP1HdrEgrOvflCnt = | ||
| 1530 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP1HdrEgrOvflCnt)); | ||
| 1531 | cntrs->RxP2HdrEgrOvflCnt = | ||
| 1532 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP2HdrEgrOvflCnt)); | ||
| 1533 | cntrs->RxP3HdrEgrOvflCnt = | ||
| 1534 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP3HdrEgrOvflCnt)); | ||
| 1535 | cntrs->RxP4HdrEgrOvflCnt = | ||
| 1536 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP4HdrEgrOvflCnt)); | ||
| 1537 | cntrs->RxP5HdrEgrOvflCnt = 0; | ||
| 1538 | cntrs->RxP6HdrEgrOvflCnt = 0; | ||
| 1539 | cntrs->RxP7HdrEgrOvflCnt = 0; | ||
| 1540 | cntrs->RxP8HdrEgrOvflCnt = 0; | ||
| 1541 | cntrs->RxP9HdrEgrOvflCnt = 0; | ||
| 1542 | cntrs->RxP10HdrEgrOvflCnt = 0; | ||
| 1543 | cntrs->RxP11HdrEgrOvflCnt = 0; | ||
| 1544 | cntrs->RxP12HdrEgrOvflCnt = 0; | ||
| 1545 | cntrs->RxP13HdrEgrOvflCnt = 0; | ||
| 1546 | cntrs->RxP14HdrEgrOvflCnt = 0; | ||
| 1547 | cntrs->RxP15HdrEgrOvflCnt = 0; | ||
| 1548 | cntrs->RxP16HdrEgrOvflCnt = 0; | ||
| 1549 | cntrs->IBStatusChangeCnt = | ||
| 1550 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(IBStatusChangeCnt)); | ||
| 1551 | cntrs->IBLinkErrRecoveryCnt = | ||
| 1552 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(IBLinkErrRecoveryCnt)); | ||
| 1553 | cntrs->IBLinkDownedCnt = | ||
| 1554 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(IBLinkDownedCnt)); | ||
| 1555 | cntrs->IBSymbolErrCnt = | ||
| 1556 | ipath_snap_cntr(dd, IPATH_CREG_OFFSET(IBSymbolErrCnt)); | ||
| 1557 | cntrs->RxVL15DroppedPktCnt = 0; | ||
| 1558 | cntrs->RxOtherLocalPhyErrCnt = 0; | ||
| 1559 | cntrs->PcieRetryBufDiagQwordCnt = 0; | ||
| 1560 | cntrs->ExcessBufferOvflCnt = dd->ipath_overrun_thresh_errs; | ||
| 1561 | cntrs->LocalLinkIntegrityErrCnt = dd->ipath_lli_errs; | ||
| 1562 | cntrs->RxVlErrCnt = 0; | ||
| 1563 | cntrs->RxDlidFltrCnt = 0; | ||
| 1564 | } | ||
| 1565 | |||
| 1566 | |||
| 1567 | /* no interrupt fallback for these chips */ | ||
| 1568 | static int ipath_pe_nointr_fallback(struct ipath_devdata *dd) | ||
| 1569 | { | ||
| 1570 | return 0; | ||
| 1571 | } | ||
| 1572 | |||
| 1573 | |||
| 1362 | /* | 1574 | /* |
| 1363 | * On platforms using this chip, and not having ordered WC stores, we | 1575 | * reset the XGXS (between serdes and IBC). Slightly less intrusive |
| 1364 | * can get TXE parity errors due to speculative reads to the PIO buffers, | 1576 | * than resetting the IBC or external link state, and useful in some |
| 1365 | * and this, due to a chip bug can result in (many) false parity error | 1577 | * cases to cause some retraining. To do this right, we reset IBC |
| 1366 | * reports. So it's a debug print on those, and an info print on systems | 1578 | * as well. |
| 1367 | * where the speculative reads don't occur. | ||
| 1368 | * Because we can get lots of false errors, we have no upper limit | ||
| 1369 | * on recovery attempts on those platforms. | ||
| 1370 | */ | 1579 | */ |
| 1371 | static int ipath_pe_txe_recover(struct ipath_devdata *dd) | 1580 | static void ipath_pe_xgxs_reset(struct ipath_devdata *dd) |
| 1372 | { | 1581 | { |
| 1373 | if (ipath_unordered_wc()) | 1582 | u64 val, prev_val; |
| 1374 | ipath_dbg("Recovering from TXE PIO parity error\n"); | 1583 | |
| 1375 | else { | 1584 | prev_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig); |
| 1376 | int cnt = ++ipath_stats.sps_txeparity; | 1585 | val = prev_val | INFINIPATH_XGXS_RESET; |
| 1377 | if (cnt >= IPATH_MAX_PARITY_ATTEMPTS) { | 1586 | prev_val &= ~INFINIPATH_XGXS_RESET; /* be sure */ |
| 1378 | if (cnt == IPATH_MAX_PARITY_ATTEMPTS) | 1587 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, |
| 1379 | ipath_dev_err(dd, | 1588 | dd->ipath_control & ~INFINIPATH_C_LINKENABLE); |
| 1380 | "Too many attempts to recover from " | 1589 | ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val); |
| 1381 | "TXE parity, giving up\n"); | 1590 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); |
| 1382 | return 0; | 1591 | ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, prev_val); |
| 1383 | } | 1592 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, |
| 1384 | dev_info(&dd->pcidev->dev, | 1593 | dd->ipath_control); |
| 1385 | "Recovering from TXE PIO parity error\n"); | 1594 | } |
| 1595 | |||
| 1596 | |||
| 1597 | static int ipath_pe_get_ib_cfg(struct ipath_devdata *dd, int which) | ||
| 1598 | { | ||
| 1599 | int ret; | ||
| 1600 | |||
| 1601 | switch (which) { | ||
| 1602 | case IPATH_IB_CFG_LWID: | ||
| 1603 | ret = dd->ipath_link_width_active; | ||
| 1604 | break; | ||
| 1605 | case IPATH_IB_CFG_SPD: | ||
| 1606 | ret = dd->ipath_link_speed_active; | ||
| 1607 | break; | ||
| 1608 | case IPATH_IB_CFG_LWID_ENB: | ||
| 1609 | ret = dd->ipath_link_width_enabled; | ||
| 1610 | break; | ||
| 1611 | case IPATH_IB_CFG_SPD_ENB: | ||
| 1612 | ret = dd->ipath_link_speed_enabled; | ||
| 1613 | break; | ||
| 1614 | default: | ||
| 1615 | ret = -ENOTSUPP; | ||
| 1616 | break; | ||
| 1386 | } | 1617 | } |
| 1387 | return 1; | 1618 | return ret; |
| 1619 | } | ||
| 1620 | |||
| 1621 | |||
| 1622 | /* we assume range checking is already done, if needed */ | ||
| 1623 | static int ipath_pe_set_ib_cfg(struct ipath_devdata *dd, int which, u32 val) | ||
| 1624 | { | ||
| 1625 | int ret = 0; | ||
| 1626 | |||
| 1627 | if (which == IPATH_IB_CFG_LWID_ENB) | ||
| 1628 | dd->ipath_link_width_enabled = val; | ||
| 1629 | else if (which == IPATH_IB_CFG_SPD_ENB) | ||
| 1630 | dd->ipath_link_speed_enabled = val; | ||
| 1631 | else | ||
| 1632 | ret = -ENOTSUPP; | ||
| 1633 | return ret; | ||
| 1388 | } | 1634 | } |
| 1389 | 1635 | ||
| 1636 | static void ipath_pe_config_jint(struct ipath_devdata *dd, u16 a, u16 b) | ||
| 1637 | { | ||
| 1638 | } | ||
| 1639 | |||
| 1640 | |||
| 1641 | static int ipath_pe_ib_updown(struct ipath_devdata *dd, int ibup, u64 ibcs) | ||
| 1642 | { | ||
| 1643 | ipath_setup_pe_setextled(dd, ipath_ib_linkstate(dd, ibcs), | ||
| 1644 | ipath_ib_linktrstate(dd, ibcs)); | ||
| 1645 | return 0; | ||
| 1646 | } | ||
| 1647 | |||
| 1648 | |||
| 1390 | /** | 1649 | /** |
| 1391 | * ipath_init_iba6120_funcs - set up the chip-specific function pointers | 1650 | * ipath_init_iba6120_funcs - set up the chip-specific function pointers |
| 1392 | * @dd: the infinipath device | 1651 | * @dd: the infinipath device |
| @@ -1407,7 +1666,7 @@ void ipath_init_iba6120_funcs(struct ipath_devdata *dd) | |||
| 1407 | dd->ipath_f_bringup_serdes = ipath_pe_bringup_serdes; | 1666 | dd->ipath_f_bringup_serdes = ipath_pe_bringup_serdes; |
| 1408 | dd->ipath_f_clear_tids = ipath_pe_clear_tids; | 1667 | dd->ipath_f_clear_tids = ipath_pe_clear_tids; |
| 1409 | /* | 1668 | /* |
| 1410 | * this may get changed after we read the chip revision, | 1669 | * _f_put_tid may get changed after we read the chip revision, |
| 1411 | * but we start with the safe version for all revs | 1670 | * but we start with the safe version for all revs |
| 1412 | */ | 1671 | */ |
| 1413 | dd->ipath_f_put_tid = ipath_pe_put_tid; | 1672 | dd->ipath_f_put_tid = ipath_pe_put_tid; |
| @@ -1415,17 +1674,19 @@ void ipath_init_iba6120_funcs(struct ipath_devdata *dd) | |||
| 1415 | dd->ipath_f_setextled = ipath_setup_pe_setextled; | 1674 | dd->ipath_f_setextled = ipath_setup_pe_setextled; |
| 1416 | dd->ipath_f_get_base_info = ipath_pe_get_base_info; | 1675 | dd->ipath_f_get_base_info = ipath_pe_get_base_info; |
| 1417 | dd->ipath_f_free_irq = ipath_pe_free_irq; | 1676 | dd->ipath_f_free_irq = ipath_pe_free_irq; |
| 1418 | |||
| 1419 | /* initialize chip-specific variables */ | ||
| 1420 | dd->ipath_f_tidtemplate = ipath_pe_tidtemplate; | 1677 | dd->ipath_f_tidtemplate = ipath_pe_tidtemplate; |
| 1678 | dd->ipath_f_intr_fallback = ipath_pe_nointr_fallback; | ||
| 1679 | dd->ipath_f_xgxs_reset = ipath_pe_xgxs_reset; | ||
| 1680 | dd->ipath_f_get_msgheader = ipath_pe_get_msgheader; | ||
| 1681 | dd->ipath_f_config_ports = ipath_pe_config_ports; | ||
| 1682 | dd->ipath_f_read_counters = ipath_pe_read_counters; | ||
| 1683 | dd->ipath_f_get_ib_cfg = ipath_pe_get_ib_cfg; | ||
| 1684 | dd->ipath_f_set_ib_cfg = ipath_pe_set_ib_cfg; | ||
| 1685 | dd->ipath_f_config_jint = ipath_pe_config_jint; | ||
| 1686 | dd->ipath_f_ib_updown = ipath_pe_ib_updown; | ||
| 1421 | 1687 | ||
| 1422 | /* | ||
| 1423 | * setup the register offsets, since they are different for each | ||
| 1424 | * chip | ||
| 1425 | */ | ||
| 1426 | dd->ipath_kregs = &ipath_pe_kregs; | ||
| 1427 | dd->ipath_cregs = &ipath_pe_cregs; | ||
| 1428 | 1688 | ||
| 1689 | /* initialize chip-specific variables */ | ||
| 1429 | ipath_init_pe_variables(dd); | 1690 | ipath_init_pe_variables(dd); |
| 1430 | } | 1691 | } |
| 1431 | 1692 | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c index 9dd0bacf8461..4471674975cd 100644 --- a/drivers/infiniband/hw/ipath/ipath_init_chip.c +++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c | |||
| @@ -91,7 +91,7 @@ static int create_port0_egr(struct ipath_devdata *dd) | |||
| 91 | struct ipath_skbinfo *skbinfo; | 91 | struct ipath_skbinfo *skbinfo; |
| 92 | int ret; | 92 | int ret; |
| 93 | 93 | ||
| 94 | egrcnt = dd->ipath_rcvegrcnt; | 94 | egrcnt = dd->ipath_p0_rcvegrcnt; |
| 95 | 95 | ||
| 96 | skbinfo = vmalloc(sizeof(*dd->ipath_port0_skbinfo) * egrcnt); | 96 | skbinfo = vmalloc(sizeof(*dd->ipath_port0_skbinfo) * egrcnt); |
| 97 | if (skbinfo == NULL) { | 97 | if (skbinfo == NULL) { |
| @@ -244,8 +244,7 @@ static int init_chip_first(struct ipath_devdata *dd, | |||
| 244 | * cfgports. We do still check and report a difference, if | 244 | * cfgports. We do still check and report a difference, if |
| 245 | * not same (should be impossible). | 245 | * not same (should be impossible). |
| 246 | */ | 246 | */ |
| 247 | dd->ipath_portcnt = | 247 | dd->ipath_f_config_ports(dd, ipath_cfgports); |
| 248 | ipath_read_kreg32(dd, dd->ipath_kregs->kr_portcnt); | ||
| 249 | if (!ipath_cfgports) | 248 | if (!ipath_cfgports) |
| 250 | dd->ipath_cfgports = dd->ipath_portcnt; | 249 | dd->ipath_cfgports = dd->ipath_portcnt; |
| 251 | else if (ipath_cfgports <= dd->ipath_portcnt) { | 250 | else if (ipath_cfgports <= dd->ipath_portcnt) { |
| @@ -272,22 +271,7 @@ static int init_chip_first(struct ipath_devdata *dd, | |||
| 272 | goto done; | 271 | goto done; |
| 273 | } | 272 | } |
| 274 | 273 | ||
| 275 | dd->ipath_lastegrheads = kzalloc(sizeof(*dd->ipath_lastegrheads) | ||
| 276 | * dd->ipath_cfgports, | ||
| 277 | GFP_KERNEL); | ||
| 278 | dd->ipath_lastrcvhdrqtails = | ||
| 279 | kzalloc(sizeof(*dd->ipath_lastrcvhdrqtails) | ||
| 280 | * dd->ipath_cfgports, GFP_KERNEL); | ||
| 281 | |||
| 282 | if (!dd->ipath_lastegrheads || !dd->ipath_lastrcvhdrqtails) { | ||
| 283 | ipath_dev_err(dd, "Unable to allocate head arrays, " | ||
| 284 | "failing\n"); | ||
| 285 | ret = -ENOMEM; | ||
| 286 | goto done; | ||
| 287 | } | ||
| 288 | |||
| 289 | pd = create_portdata0(dd); | 274 | pd = create_portdata0(dd); |
| 290 | |||
| 291 | if (!pd) { | 275 | if (!pd) { |
| 292 | ipath_dev_err(dd, "Unable to allocate portdata for port " | 276 | ipath_dev_err(dd, "Unable to allocate portdata for port " |
| 293 | "0, failing\n"); | 277 | "0, failing\n"); |
| @@ -345,10 +329,10 @@ static int init_chip_first(struct ipath_devdata *dd, | |||
| 345 | dd->ipath_piobcnt2k, dd->ipath_pio2kbase); | 329 | dd->ipath_piobcnt2k, dd->ipath_pio2kbase); |
| 346 | 330 | ||
| 347 | spin_lock_init(&dd->ipath_tid_lock); | 331 | spin_lock_init(&dd->ipath_tid_lock); |
| 348 | 332 | spin_lock_init(&dd->ipath_sendctrl_lock); | |
| 349 | spin_lock_init(&dd->ipath_gpio_lock); | 333 | spin_lock_init(&dd->ipath_gpio_lock); |
| 350 | spin_lock_init(&dd->ipath_eep_st_lock); | 334 | spin_lock_init(&dd->ipath_eep_st_lock); |
| 351 | sema_init(&dd->ipath_eep_sem, 1); | 335 | mutex_init(&dd->ipath_eep_lock); |
| 352 | 336 | ||
| 353 | done: | 337 | done: |
| 354 | *pdp = pd; | 338 | *pdp = pd; |
| @@ -372,9 +356,9 @@ static int init_chip_reset(struct ipath_devdata *dd, | |||
| 372 | *pdp = dd->ipath_pd[0]; | 356 | *pdp = dd->ipath_pd[0]; |
| 373 | /* ensure chip does no sends or receives while we re-initialize */ | 357 | /* ensure chip does no sends or receives while we re-initialize */ |
| 374 | dd->ipath_control = dd->ipath_sendctrl = dd->ipath_rcvctrl = 0U; | 358 | dd->ipath_control = dd->ipath_sendctrl = dd->ipath_rcvctrl = 0U; |
| 375 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, 0); | 359 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, dd->ipath_rcvctrl); |
| 376 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 0); | 360 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl); |
| 377 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, 0); | 361 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, dd->ipath_control); |
| 378 | 362 | ||
| 379 | rtmp = ipath_read_kreg32(dd, dd->ipath_kregs->kr_portcnt); | 363 | rtmp = ipath_read_kreg32(dd, dd->ipath_kregs->kr_portcnt); |
| 380 | if (dd->ipath_portcnt != rtmp) | 364 | if (dd->ipath_portcnt != rtmp) |
| @@ -487,6 +471,7 @@ static void enable_chip(struct ipath_devdata *dd, | |||
| 487 | struct ipath_portdata *pd, int reinit) | 471 | struct ipath_portdata *pd, int reinit) |
| 488 | { | 472 | { |
| 489 | u32 val; | 473 | u32 val; |
| 474 | unsigned long flags; | ||
| 490 | int i; | 475 | int i; |
| 491 | 476 | ||
| 492 | if (!reinit) | 477 | if (!reinit) |
| @@ -495,19 +480,21 @@ static void enable_chip(struct ipath_devdata *dd, | |||
| 495 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | 480 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, |
| 496 | dd->ipath_rcvctrl); | 481 | dd->ipath_rcvctrl); |
| 497 | 482 | ||
| 483 | spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); | ||
| 498 | /* Enable PIO send, and update of PIOavail regs to memory. */ | 484 | /* Enable PIO send, and update of PIOavail regs to memory. */ |
| 499 | dd->ipath_sendctrl = INFINIPATH_S_PIOENABLE | | 485 | dd->ipath_sendctrl = INFINIPATH_S_PIOENABLE | |
| 500 | INFINIPATH_S_PIOBUFAVAILUPD; | 486 | INFINIPATH_S_PIOBUFAVAILUPD; |
| 501 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | 487 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl); |
| 502 | dd->ipath_sendctrl); | 488 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); |
| 489 | spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); | ||
| 503 | 490 | ||
| 504 | /* | 491 | /* |
| 505 | * enable port 0 receive, and receive interrupt. other ports | 492 | * enable port 0 receive, and receive interrupt. other ports |
| 506 | * done as user opens and inits them. | 493 | * done as user opens and inits them. |
| 507 | */ | 494 | */ |
| 508 | dd->ipath_rcvctrl = INFINIPATH_R_TAILUPD | | 495 | dd->ipath_rcvctrl = (1ULL << dd->ipath_r_tailupd_shift) | |
| 509 | (1ULL << INFINIPATH_R_PORTENABLE_SHIFT) | | 496 | (1ULL << dd->ipath_r_portenable_shift) | |
| 510 | (1ULL << INFINIPATH_R_INTRAVAIL_SHIFT); | 497 | (1ULL << dd->ipath_r_intravail_shift); |
| 511 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, | 498 | ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, |
| 512 | dd->ipath_rcvctrl); | 499 | dd->ipath_rcvctrl); |
| 513 | 500 | ||
| @@ -523,12 +510,11 @@ static void enable_chip(struct ipath_devdata *dd, | |||
| 523 | */ | 510 | */ |
| 524 | val = ipath_read_ureg32(dd, ur_rcvegrindextail, 0); | 511 | val = ipath_read_ureg32(dd, ur_rcvegrindextail, 0); |
| 525 | (void)ipath_write_ureg(dd, ur_rcvegrindexhead, val, 0); | 512 | (void)ipath_write_ureg(dd, ur_rcvegrindexhead, val, 0); |
| 526 | dd->ipath_port0head = ipath_read_ureg32(dd, ur_rcvhdrtail, 0); | ||
| 527 | 513 | ||
| 528 | /* Initialize so we interrupt on next packet received */ | 514 | /* Initialize so we interrupt on next packet received */ |
| 529 | (void)ipath_write_ureg(dd, ur_rcvhdrhead, | 515 | (void)ipath_write_ureg(dd, ur_rcvhdrhead, |
| 530 | dd->ipath_rhdrhead_intr_off | | 516 | dd->ipath_rhdrhead_intr_off | |
| 531 | dd->ipath_port0head, 0); | 517 | dd->ipath_pd[0]->port_head, 0); |
| 532 | 518 | ||
| 533 | /* | 519 | /* |
| 534 | * by now pioavail updates to memory should have occurred, so | 520 | * by now pioavail updates to memory should have occurred, so |
| @@ -542,12 +528,8 @@ static void enable_chip(struct ipath_devdata *dd, | |||
| 542 | /* | 528 | /* |
| 543 | * Chip Errata bug 6641; even and odd qwords>3 are swapped. | 529 | * Chip Errata bug 6641; even and odd qwords>3 are swapped. |
| 544 | */ | 530 | */ |
| 545 | if (i > 3) { | 531 | if (i > 3 && (dd->ipath_flags & IPATH_SWAP_PIOBUFS)) |
| 546 | if (i & 1) | 532 | val = dd->ipath_pioavailregs_dma[i ^ 1]; |
| 547 | val = dd->ipath_pioavailregs_dma[i - 1]; | ||
| 548 | else | ||
| 549 | val = dd->ipath_pioavailregs_dma[i + 1]; | ||
| 550 | } | ||
| 551 | else | 533 | else |
| 552 | val = dd->ipath_pioavailregs_dma[i]; | 534 | val = dd->ipath_pioavailregs_dma[i]; |
| 553 | dd->ipath_pioavailshadow[i] = le64_to_cpu(val); | 535 | dd->ipath_pioavailshadow[i] = le64_to_cpu(val); |
| @@ -690,12 +672,13 @@ done: | |||
| 690 | */ | 672 | */ |
| 691 | int ipath_init_chip(struct ipath_devdata *dd, int reinit) | 673 | int ipath_init_chip(struct ipath_devdata *dd, int reinit) |
| 692 | { | 674 | { |
| 693 | int ret = 0, i; | 675 | int ret = 0; |
| 694 | u32 val32, kpiobufs; | 676 | u32 val32, kpiobufs; |
| 695 | u32 piobufs, uports; | 677 | u32 piobufs, uports; |
| 696 | u64 val; | 678 | u64 val; |
| 697 | struct ipath_portdata *pd = NULL; /* keep gcc4 happy */ | 679 | struct ipath_portdata *pd = NULL; /* keep gcc4 happy */ |
| 698 | gfp_t gfp_flags = GFP_USER | __GFP_COMP; | 680 | gfp_t gfp_flags = GFP_USER | __GFP_COMP; |
| 681 | unsigned long flags; | ||
| 699 | 682 | ||
| 700 | ret = init_housekeeping(dd, &pd, reinit); | 683 | ret = init_housekeeping(dd, &pd, reinit); |
| 701 | if (ret) | 684 | if (ret) |
| @@ -746,7 +729,7 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) | |||
| 746 | kpiobufs = ipath_kpiobufs; | 729 | kpiobufs = ipath_kpiobufs; |
| 747 | 730 | ||
| 748 | if (kpiobufs + (uports * IPATH_MIN_USER_PORT_BUFCNT) > piobufs) { | 731 | if (kpiobufs + (uports * IPATH_MIN_USER_PORT_BUFCNT) > piobufs) { |
| 749 | i = (int) piobufs - | 732 | int i = (int) piobufs - |
| 750 | (int) (uports * IPATH_MIN_USER_PORT_BUFCNT); | 733 | (int) (uports * IPATH_MIN_USER_PORT_BUFCNT); |
| 751 | if (i < 0) | 734 | if (i < 0) |
| 752 | i = 0; | 735 | i = 0; |
| @@ -827,8 +810,12 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) | |||
| 827 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, | 810 | ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, |
| 828 | ~0ULL&~INFINIPATH_HWE_MEMBISTFAILED); | 811 | ~0ULL&~INFINIPATH_HWE_MEMBISTFAILED); |
| 829 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, 0ULL); | 812 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, 0ULL); |
| 830 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | 813 | |
| 831 | INFINIPATH_S_PIOENABLE); | 814 | spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); |
| 815 | dd->ipath_sendctrl = INFINIPATH_S_PIOENABLE; | ||
| 816 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl); | ||
| 817 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | ||
| 818 | spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); | ||
| 832 | 819 | ||
| 833 | /* | 820 | /* |
| 834 | * before error clears, since we expect serdes pll errors during | 821 | * before error clears, since we expect serdes pll errors during |
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c index c61f9da2964a..92e58c921522 100644 --- a/drivers/infiniband/hw/ipath/ipath_intr.c +++ b/drivers/infiniband/hw/ipath/ipath_intr.c | |||
| @@ -683,7 +683,7 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs) | |||
| 683 | for (i = 0; i < dd->ipath_cfgports; i++) { | 683 | for (i = 0; i < dd->ipath_cfgports; i++) { |
| 684 | struct ipath_portdata *pd = dd->ipath_pd[i]; | 684 | struct ipath_portdata *pd = dd->ipath_pd[i]; |
| 685 | if (i == 0) { | 685 | if (i == 0) { |
| 686 | hd = dd->ipath_port0head; | 686 | hd = pd->port_head; |
| 687 | tl = (u32) le64_to_cpu( | 687 | tl = (u32) le64_to_cpu( |
| 688 | *dd->ipath_hdrqtailptr); | 688 | *dd->ipath_hdrqtailptr); |
| 689 | } else if (pd && pd->port_cnt && | 689 | } else if (pd && pd->port_cnt && |
| @@ -693,7 +693,7 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs) | |||
| 693 | * except kernel | 693 | * except kernel |
| 694 | */ | 694 | */ |
| 695 | tl = *(u64 *) pd->port_rcvhdrtail_kvaddr; | 695 | tl = *(u64 *) pd->port_rcvhdrtail_kvaddr; |
| 696 | if (tl == dd->ipath_lastrcvhdrqtails[i]) | 696 | if (tl == pd->port_lastrcvhdrqtail) |
| 697 | continue; | 697 | continue; |
| 698 | hd = ipath_read_ureg32(dd, ur_rcvhdrhead, | 698 | hd = ipath_read_ureg32(dd, ur_rcvhdrhead, |
| 699 | i); | 699 | i); |
| @@ -703,7 +703,7 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs) | |||
| 703 | (!hd && tl == dd->ipath_hdrqlast)) { | 703 | (!hd && tl == dd->ipath_hdrqlast)) { |
| 704 | if (i == 0) | 704 | if (i == 0) |
| 705 | chkerrpkts = 1; | 705 | chkerrpkts = 1; |
| 706 | dd->ipath_lastrcvhdrqtails[i] = tl; | 706 | pd->port_lastrcvhdrqtail = tl; |
| 707 | pd->port_hdrqfull++; | 707 | pd->port_hdrqfull++; |
| 708 | /* flush hdrqfull so that poll() sees it */ | 708 | /* flush hdrqfull so that poll() sees it */ |
| 709 | wmb(); | 709 | wmb(); |
| @@ -712,6 +712,8 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs) | |||
| 712 | } | 712 | } |
| 713 | } | 713 | } |
| 714 | if (errs & INFINIPATH_E_RRCVEGRFULL) { | 714 | if (errs & INFINIPATH_E_RRCVEGRFULL) { |
| 715 | struct ipath_portdata *pd = dd->ipath_pd[0]; | ||
| 716 | |||
| 715 | /* | 717 | /* |
| 716 | * since this is of less importance and not likely to | 718 | * since this is of less importance and not likely to |
| 717 | * happen without also getting hdrfull, only count | 719 | * happen without also getting hdrfull, only count |
| @@ -719,7 +721,7 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs) | |||
| 719 | * vs user) | 721 | * vs user) |
| 720 | */ | 722 | */ |
| 721 | ipath_stats.sps_etidfull++; | 723 | ipath_stats.sps_etidfull++; |
| 722 | if (dd->ipath_port0head != | 724 | if (pd->port_head != |
| 723 | (u32) le64_to_cpu(*dd->ipath_hdrqtailptr)) | 725 | (u32) le64_to_cpu(*dd->ipath_hdrqtailptr)) |
| 724 | chkerrpkts = 1; | 726 | chkerrpkts = 1; |
| 725 | } | 727 | } |
| @@ -795,6 +797,7 @@ void ipath_clear_freeze(struct ipath_devdata *dd) | |||
| 795 | { | 797 | { |
| 796 | int i, im; | 798 | int i, im; |
| 797 | __le64 val; | 799 | __le64 val; |
| 800 | unsigned long flags; | ||
| 798 | 801 | ||
| 799 | /* disable error interrupts, to avoid confusion */ | 802 | /* disable error interrupts, to avoid confusion */ |
| 800 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, 0ULL); | 803 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, 0ULL); |
| @@ -813,11 +816,14 @@ void ipath_clear_freeze(struct ipath_devdata *dd) | |||
| 813 | dd->ipath_control); | 816 | dd->ipath_control); |
| 814 | 817 | ||
| 815 | /* ensure pio avail updates continue */ | 818 | /* ensure pio avail updates continue */ |
| 819 | spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); | ||
| 816 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | 820 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, |
| 817 | dd->ipath_sendctrl & ~INFINIPATH_S_PIOBUFAVAILUPD); | 821 | dd->ipath_sendctrl & ~INFINIPATH_S_PIOBUFAVAILUPD); |
| 818 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | 822 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); |
| 819 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | 823 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, |
| 820 | dd->ipath_sendctrl); | 824 | dd->ipath_sendctrl); |
| 825 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | ||
| 826 | spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); | ||
| 821 | 827 | ||
| 822 | /* | 828 | /* |
| 823 | * We just enabled pioavailupdate, so dma copy is almost certainly | 829 | * We just enabled pioavailupdate, so dma copy is almost certainly |
| @@ -825,8 +831,8 @@ void ipath_clear_freeze(struct ipath_devdata *dd) | |||
| 825 | */ | 831 | */ |
| 826 | for (i = 0; i < dd->ipath_pioavregs; i++) { | 832 | for (i = 0; i < dd->ipath_pioavregs; i++) { |
| 827 | /* deal with 6110 chip bug */ | 833 | /* deal with 6110 chip bug */ |
| 828 | im = i > 3 ? ((i&1) ? i-1 : i+1) : i; | 834 | im = i > 3 ? i ^ 1 : i; |
| 829 | val = ipath_read_kreg64(dd, (0x1000/sizeof(u64))+im); | 835 | val = ipath_read_kreg64(dd, (0x1000 / sizeof(u64)) + im); |
| 830 | dd->ipath_pioavailregs_dma[i] = dd->ipath_pioavailshadow[i] | 836 | dd->ipath_pioavailregs_dma[i] = dd->ipath_pioavailshadow[i] |
| 831 | = le64_to_cpu(val); | 837 | = le64_to_cpu(val); |
| 832 | } | 838 | } |
| @@ -849,7 +855,7 @@ void ipath_clear_freeze(struct ipath_devdata *dd) | |||
| 849 | 855 | ||
| 850 | /* this is separate to allow for better optimization of ipath_intr() */ | 856 | /* this is separate to allow for better optimization of ipath_intr() */ |
| 851 | 857 | ||
| 852 | static void ipath_bad_intr(struct ipath_devdata *dd, u32 * unexpectp) | 858 | static noinline void ipath_bad_intr(struct ipath_devdata *dd, u32 *unexpectp) |
| 853 | { | 859 | { |
| 854 | /* | 860 | /* |
| 855 | * sometimes happen during driver init and unload, don't want | 861 | * sometimes happen during driver init and unload, don't want |
| @@ -877,7 +883,7 @@ static void ipath_bad_intr(struct ipath_devdata *dd, u32 * unexpectp) | |||
| 877 | dd->ipath_f_free_irq(dd); | 883 | dd->ipath_f_free_irq(dd); |
| 878 | } | 884 | } |
| 879 | } | 885 | } |
| 880 | if (ipath_read_kreg32(dd, dd->ipath_kregs->kr_intmask)) { | 886 | if (ipath_read_ireg(dd, dd->ipath_kregs->kr_intmask)) { |
| 881 | ipath_dev_err(dd, "%u unexpected interrupts, " | 887 | ipath_dev_err(dd, "%u unexpected interrupts, " |
| 882 | "disabling interrupts completely\n", | 888 | "disabling interrupts completely\n", |
| 883 | *unexpectp); | 889 | *unexpectp); |
| @@ -892,7 +898,7 @@ static void ipath_bad_intr(struct ipath_devdata *dd, u32 * unexpectp) | |||
| 892 | "ignoring\n"); | 898 | "ignoring\n"); |
| 893 | } | 899 | } |
| 894 | 900 | ||
| 895 | static void ipath_bad_regread(struct ipath_devdata *dd) | 901 | static noinline void ipath_bad_regread(struct ipath_devdata *dd) |
| 896 | { | 902 | { |
| 897 | static int allbits; | 903 | static int allbits; |
| 898 | 904 | ||
| @@ -920,31 +926,9 @@ static void ipath_bad_regread(struct ipath_devdata *dd) | |||
| 920 | } | 926 | } |
| 921 | } | 927 | } |
| 922 | 928 | ||
| 923 | static void handle_port_pioavail(struct ipath_devdata *dd) | ||
| 924 | { | ||
| 925 | u32 i; | ||
| 926 | /* | ||
| 927 | * start from port 1, since for now port 0 is never using | ||
| 928 | * wait_event for PIO | ||
| 929 | */ | ||
| 930 | for (i = 1; dd->ipath_portpiowait && i < dd->ipath_cfgports; i++) { | ||
| 931 | struct ipath_portdata *pd = dd->ipath_pd[i]; | ||
| 932 | |||
| 933 | if (pd && pd->port_cnt && | ||
| 934 | dd->ipath_portpiowait & (1U << i)) { | ||
| 935 | clear_bit(i, &dd->ipath_portpiowait); | ||
| 936 | if (test_bit(IPATH_PORT_WAITING_PIO, | ||
| 937 | &pd->port_flag)) { | ||
| 938 | clear_bit(IPATH_PORT_WAITING_PIO, | ||
| 939 | &pd->port_flag); | ||
| 940 | wake_up_interruptible(&pd->port_wait); | ||
| 941 | } | ||
| 942 | } | ||
| 943 | } | ||
| 944 | } | ||
| 945 | |||
| 946 | static void handle_layer_pioavail(struct ipath_devdata *dd) | 929 | static void handle_layer_pioavail(struct ipath_devdata *dd) |
| 947 | { | 930 | { |
| 931 | unsigned long flags; | ||
| 948 | int ret; | 932 | int ret; |
| 949 | 933 | ||
| 950 | ret = ipath_ib_piobufavail(dd->verbs_dev); | 934 | ret = ipath_ib_piobufavail(dd->verbs_dev); |
| @@ -953,9 +937,12 @@ static void handle_layer_pioavail(struct ipath_devdata *dd) | |||
| 953 | 937 | ||
| 954 | return; | 938 | return; |
| 955 | set: | 939 | set: |
| 956 | set_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl); | 940 | spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); |
| 941 | dd->ipath_sendctrl |= INFINIPATH_S_PIOINTBUFAVAIL; | ||
| 957 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | 942 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, |
| 958 | dd->ipath_sendctrl); | 943 | dd->ipath_sendctrl); |
| 944 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | ||
| 945 | spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); | ||
| 959 | } | 946 | } |
| 960 | 947 | ||
| 961 | /* | 948 | /* |
| @@ -969,7 +956,15 @@ static void handle_urcv(struct ipath_devdata *dd, u32 istat) | |||
| 969 | int i; | 956 | int i; |
| 970 | int rcvdint = 0; | 957 | int rcvdint = 0; |
| 971 | 958 | ||
| 972 | /* test_bit below needs this... */ | 959 | /* |
| 960 | * test_and_clear_bit(IPATH_PORT_WAITING_RCV) and | ||
| 961 | * test_and_clear_bit(IPATH_PORT_WAITING_URG) below | ||
| 962 | * would both like timely updates of the bits so that | ||
| 963 | * we don't pass them by unnecessarily. the rmb() | ||
| 964 | * here ensures that we see them promptly -- the | ||
| 965 | * corresponding wmb()'s are in ipath_poll_urgent() | ||
| 966 | * and ipath_poll_next()... | ||
| 967 | */ | ||
| 973 | rmb(); | 968 | rmb(); |
| 974 | portr = ((istat >> INFINIPATH_I_RCVAVAIL_SHIFT) & | 969 | portr = ((istat >> INFINIPATH_I_RCVAVAIL_SHIFT) & |
| 975 | dd->ipath_i_rcvavail_mask) | 970 | dd->ipath_i_rcvavail_mask) |
| @@ -980,7 +975,7 @@ static void handle_urcv(struct ipath_devdata *dd, u32 istat) | |||
| 980 | if (portr & (1 << i) && pd && pd->port_cnt) { | 975 | if (portr & (1 << i) && pd && pd->port_cnt) { |
| 981 | if (test_and_clear_bit(IPATH_PORT_WAITING_RCV, | 976 | if (test_and_clear_bit(IPATH_PORT_WAITING_RCV, |
| 982 | &pd->port_flag)) { | 977 | &pd->port_flag)) { |
| 983 | clear_bit(i + INFINIPATH_R_INTRAVAIL_SHIFT, | 978 | clear_bit(i + dd->ipath_r_intravail_shift, |
| 984 | &dd->ipath_rcvctrl); | 979 | &dd->ipath_rcvctrl); |
| 985 | wake_up_interruptible(&pd->port_wait); | 980 | wake_up_interruptible(&pd->port_wait); |
| 986 | rcvdint = 1; | 981 | rcvdint = 1; |
| @@ -1039,7 +1034,7 @@ irqreturn_t ipath_intr(int irq, void *data) | |||
| 1039 | goto bail; | 1034 | goto bail; |
| 1040 | } | 1035 | } |
| 1041 | 1036 | ||
| 1042 | istat = ipath_read_kreg32(dd, dd->ipath_kregs->kr_intstatus); | 1037 | istat = ipath_read_ireg(dd, dd->ipath_kregs->kr_intstatus); |
| 1043 | 1038 | ||
| 1044 | if (unlikely(!istat)) { | 1039 | if (unlikely(!istat)) { |
| 1045 | ipath_stats.sps_nullintr++; | 1040 | ipath_stats.sps_nullintr++; |
| @@ -1180,7 +1175,7 @@ irqreturn_t ipath_intr(int irq, void *data) | |||
| 1180 | * for receive are at the bottom. | 1175 | * for receive are at the bottom. |
| 1181 | */ | 1176 | */ |
| 1182 | if (chk0rcv) { | 1177 | if (chk0rcv) { |
| 1183 | ipath_kreceive(dd); | 1178 | ipath_kreceive(dd->ipath_pd[0]); |
| 1184 | istat &= ~port0rbits; | 1179 | istat &= ~port0rbits; |
| 1185 | } | 1180 | } |
| 1186 | 1181 | ||
| @@ -1191,12 +1186,14 @@ irqreturn_t ipath_intr(int irq, void *data) | |||
| 1191 | handle_urcv(dd, istat); | 1186 | handle_urcv(dd, istat); |
| 1192 | 1187 | ||
| 1193 | if (istat & INFINIPATH_I_SPIOBUFAVAIL) { | 1188 | if (istat & INFINIPATH_I_SPIOBUFAVAIL) { |
| 1194 | clear_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl); | 1189 | unsigned long flags; |
| 1190 | |||
| 1191 | spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); | ||
| 1192 | dd->ipath_sendctrl &= ~INFINIPATH_S_PIOINTBUFAVAIL; | ||
| 1195 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | 1193 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, |
| 1196 | dd->ipath_sendctrl); | 1194 | dd->ipath_sendctrl); |
| 1197 | 1195 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | |
| 1198 | if (dd->ipath_portpiowait) | 1196 | spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); |
| 1199 | handle_port_pioavail(dd); | ||
| 1200 | 1197 | ||
| 1201 | handle_layer_pioavail(dd); | 1198 | handle_layer_pioavail(dd); |
| 1202 | } | 1199 | } |
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h index bb1dc075f1d1..4cc0f95ea877 100644 --- a/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/drivers/infiniband/hw/ipath/ipath_kernel.h | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | #include <linux/interrupt.h> | 41 | #include <linux/interrupt.h> |
| 42 | #include <linux/pci.h> | 42 | #include <linux/pci.h> |
| 43 | #include <linux/dma-mapping.h> | 43 | #include <linux/dma-mapping.h> |
| 44 | #include <linux/mutex.h> | ||
| 44 | #include <asm/io.h> | 45 | #include <asm/io.h> |
| 45 | #include <rdma/ib_verbs.h> | 46 | #include <rdma/ib_verbs.h> |
| 46 | 47 | ||
| @@ -140,6 +141,11 @@ struct ipath_portdata { | |||
| 140 | u32 port_pionowait; | 141 | u32 port_pionowait; |
| 141 | /* total number of rcvhdrqfull errors */ | 142 | /* total number of rcvhdrqfull errors */ |
| 142 | u32 port_hdrqfull; | 143 | u32 port_hdrqfull; |
| 144 | /* | ||
| 145 | * Used to suppress multiple instances of same | ||
| 146 | * port staying stuck at same point. | ||
| 147 | */ | ||
| 148 | u32 port_lastrcvhdrqtail; | ||
| 143 | /* saved total number of rcvhdrqfull errors for poll edge trigger */ | 149 | /* saved total number of rcvhdrqfull errors for poll edge trigger */ |
| 144 | u32 port_hdrqfull_poll; | 150 | u32 port_hdrqfull_poll; |
| 145 | /* total number of polled urgent packets */ | 151 | /* total number of polled urgent packets */ |
| @@ -148,6 +154,7 @@ struct ipath_portdata { | |||
| 148 | u32 port_urgent_poll; | 154 | u32 port_urgent_poll; |
| 149 | /* pid of process using this port */ | 155 | /* pid of process using this port */ |
| 150 | pid_t port_pid; | 156 | pid_t port_pid; |
| 157 | pid_t port_subpid[INFINIPATH_MAX_SUBPORT]; | ||
| 151 | /* same size as task_struct .comm[] */ | 158 | /* same size as task_struct .comm[] */ |
| 152 | char port_comm[16]; | 159 | char port_comm[16]; |
| 153 | /* pkeys set by this use of this port */ | 160 | /* pkeys set by this use of this port */ |
| @@ -166,6 +173,8 @@ struct ipath_portdata { | |||
| 166 | u32 active_slaves; | 173 | u32 active_slaves; |
| 167 | /* Type of packets or conditions we want to poll for */ | 174 | /* Type of packets or conditions we want to poll for */ |
| 168 | u16 poll_type; | 175 | u16 poll_type; |
| 176 | /* port rcvhdrq head offset */ | ||
| 177 | u32 port_head; | ||
| 169 | }; | 178 | }; |
| 170 | 179 | ||
| 171 | struct sk_buff; | 180 | struct sk_buff; |
| @@ -182,6 +191,22 @@ struct ipath_skbinfo { | |||
| 182 | dma_addr_t phys; | 191 | dma_addr_t phys; |
| 183 | }; | 192 | }; |
| 184 | 193 | ||
| 194 | /* | ||
| 195 | * Possible IB config parameters for ipath_f_get/set_ib_cfg() | ||
| 196 | */ | ||
| 197 | #define IPATH_IB_CFG_LIDLMC 0 /* Get/set LID (LS16b) and Mask (MS16b) */ | ||
| 198 | #define IPATH_IB_CFG_HRTBT 1 /* Get/set Heartbeat off/enable/auto */ | ||
| 199 | #define IPATH_IB_HRTBT_ON 3 /* Heartbeat enabled, sent every 100msec */ | ||
| 200 | #define IPATH_IB_HRTBT_OFF 0 /* Heartbeat off */ | ||
| 201 | #define IPATH_IB_CFG_LWID_ENB 2 /* Get/set allowed Link-width */ | ||
| 202 | #define IPATH_IB_CFG_LWID 3 /* Get currently active Link-width */ | ||
| 203 | #define IPATH_IB_CFG_SPD_ENB 4 /* Get/set allowed Link speeds */ | ||
| 204 | #define IPATH_IB_CFG_SPD 5 /* Get current Link spd */ | ||
| 205 | #define IPATH_IB_CFG_RXPOL_ENB 6 /* Get/set Auto-RX-polarity enable */ | ||
| 206 | #define IPATH_IB_CFG_LREV_ENB 7 /* Get/set Auto-Lane-reversal enable */ | ||
| 207 | #define IPATH_IB_CFG_LINKLATENCY 8 /* Get Auto-Lane-reversal enable */ | ||
| 208 | |||
| 209 | |||
| 185 | struct ipath_devdata { | 210 | struct ipath_devdata { |
| 186 | struct list_head ipath_list; | 211 | struct list_head ipath_list; |
| 187 | 212 | ||
| @@ -222,6 +247,8 @@ struct ipath_devdata { | |||
| 222 | struct _ipath_layer ipath_layer; | 247 | struct _ipath_layer ipath_layer; |
| 223 | /* setup intr */ | 248 | /* setup intr */ |
| 224 | int (*ipath_f_intrsetup)(struct ipath_devdata *); | 249 | int (*ipath_f_intrsetup)(struct ipath_devdata *); |
| 250 | /* fallback to alternate interrupt type if possible */ | ||
| 251 | int (*ipath_f_intr_fallback)(struct ipath_devdata *); | ||
| 225 | /* setup on-chip bus config */ | 252 | /* setup on-chip bus config */ |
| 226 | int (*ipath_f_bus)(struct ipath_devdata *, struct pci_dev *); | 253 | int (*ipath_f_bus)(struct ipath_devdata *, struct pci_dev *); |
| 227 | /* hard reset chip */ | 254 | /* hard reset chip */ |
| @@ -244,6 +271,18 @@ struct ipath_devdata { | |||
| 244 | int (*ipath_f_get_base_info)(struct ipath_portdata *, void *); | 271 | int (*ipath_f_get_base_info)(struct ipath_portdata *, void *); |
| 245 | /* free irq */ | 272 | /* free irq */ |
| 246 | void (*ipath_f_free_irq)(struct ipath_devdata *); | 273 | void (*ipath_f_free_irq)(struct ipath_devdata *); |
| 274 | struct ipath_message_header *(*ipath_f_get_msgheader) | ||
| 275 | (struct ipath_devdata *, __le32 *); | ||
| 276 | void (*ipath_f_config_ports)(struct ipath_devdata *, ushort); | ||
| 277 | int (*ipath_f_get_ib_cfg)(struct ipath_devdata *, int); | ||
| 278 | int (*ipath_f_set_ib_cfg)(struct ipath_devdata *, int, u32); | ||
| 279 | void (*ipath_f_config_jint)(struct ipath_devdata *, u16 , u16); | ||
| 280 | void (*ipath_f_read_counters)(struct ipath_devdata *, | ||
| 281 | struct infinipath_counters *); | ||
| 282 | void (*ipath_f_xgxs_reset)(struct ipath_devdata *); | ||
| 283 | /* per chip actions needed for IB Link up/down changes */ | ||
| 284 | int (*ipath_f_ib_updown)(struct ipath_devdata *, int, u64); | ||
| 285 | |||
| 247 | struct ipath_ibdev *verbs_dev; | 286 | struct ipath_ibdev *verbs_dev; |
| 248 | struct timer_list verbs_timer; | 287 | struct timer_list verbs_timer; |
| 249 | /* total dwords sent (summed from counter) */ | 288 | /* total dwords sent (summed from counter) */ |
| @@ -313,22 +352,12 @@ struct ipath_devdata { | |||
| 313 | * supports, less gives more pio bufs/port, etc. | 352 | * supports, less gives more pio bufs/port, etc. |
| 314 | */ | 353 | */ |
| 315 | u32 ipath_cfgports; | 354 | u32 ipath_cfgports; |
| 316 | /* port0 rcvhdrq head offset */ | ||
| 317 | u32 ipath_port0head; | ||
| 318 | /* count of port 0 hdrqfull errors */ | 355 | /* count of port 0 hdrqfull errors */ |
| 319 | u32 ipath_p0_hdrqfull; | 356 | u32 ipath_p0_hdrqfull; |
| 357 | /* port 0 number of receive eager buffers */ | ||
| 358 | u32 ipath_p0_rcvegrcnt; | ||
| 320 | 359 | ||
| 321 | /* | 360 | /* |
| 322 | * (*cfgports) used to suppress multiple instances of same | ||
| 323 | * port staying stuck at same point | ||
| 324 | */ | ||
| 325 | u32 *ipath_lastrcvhdrqtails; | ||
| 326 | /* | ||
| 327 | * (*cfgports) used to suppress multiple instances of same | ||
| 328 | * port staying stuck at same point | ||
| 329 | */ | ||
| 330 | u32 *ipath_lastegrheads; | ||
| 331 | /* | ||
| 332 | * index of last piobuffer we used. Speeds up searching, by | 361 | * index of last piobuffer we used. Speeds up searching, by |
| 333 | * starting at this point. Doesn't matter if multiple cpu's use and | 362 | * starting at this point. Doesn't matter if multiple cpu's use and |
| 334 | * update, last updater is only write that matters. Whenever it | 363 | * update, last updater is only write that matters. Whenever it |
| @@ -367,14 +396,15 @@ struct ipath_devdata { | |||
| 367 | unsigned long ipath_wc_len; | 396 | unsigned long ipath_wc_len; |
| 368 | /* ref count for each pkey */ | 397 | /* ref count for each pkey */ |
| 369 | atomic_t ipath_pkeyrefs[4]; | 398 | atomic_t ipath_pkeyrefs[4]; |
| 370 | /* shadow copy of all exptids physaddr; used only by funcsim */ | ||
| 371 | u64 *ipath_tidsimshadow; | ||
| 372 | /* shadow copy of struct page *'s for exp tid pages */ | 399 | /* shadow copy of struct page *'s for exp tid pages */ |
| 373 | struct page **ipath_pageshadow; | 400 | struct page **ipath_pageshadow; |
| 374 | /* shadow copy of dma handles for exp tid pages */ | 401 | /* shadow copy of dma handles for exp tid pages */ |
| 375 | dma_addr_t *ipath_physshadow; | 402 | dma_addr_t *ipath_physshadow; |
| 376 | /* lock to workaround chip bug 9437 */ | 403 | u64 __iomem *ipath_egrtidbase; |
| 404 | /* lock to workaround chip bug 9437 and others */ | ||
| 405 | spinlock_t ipath_kernel_tid_lock; | ||
| 377 | spinlock_t ipath_tid_lock; | 406 | spinlock_t ipath_tid_lock; |
| 407 | spinlock_t ipath_sendctrl_lock; | ||
| 378 | 408 | ||
| 379 | /* | 409 | /* |
| 380 | * IPATH_STATUS_*, | 410 | * IPATH_STATUS_*, |
| @@ -395,6 +425,8 @@ struct ipath_devdata { | |||
| 395 | void *ipath_dummy_hdrq; /* used after port close */ | 425 | void *ipath_dummy_hdrq; /* used after port close */ |
| 396 | dma_addr_t ipath_dummy_hdrq_phys; | 426 | dma_addr_t ipath_dummy_hdrq_phys; |
| 397 | 427 | ||
| 428 | unsigned long ipath_ureg_align; /* user register alignment */ | ||
| 429 | |||
| 398 | /* | 430 | /* |
| 399 | * Shadow copies of registers; size indicates read access size. | 431 | * Shadow copies of registers; size indicates read access size. |
| 400 | * Most of them are readonly, but some are write-only register, | 432 | * Most of them are readonly, but some are write-only register, |
| @@ -456,8 +488,6 @@ struct ipath_devdata { | |||
| 456 | unsigned long ipath_rcvctrl; | 488 | unsigned long ipath_rcvctrl; |
| 457 | /* shadow kr_sendctrl */ | 489 | /* shadow kr_sendctrl */ |
| 458 | unsigned long ipath_sendctrl; | 490 | unsigned long ipath_sendctrl; |
| 459 | /* ports waiting for PIOavail intr */ | ||
| 460 | unsigned long ipath_portpiowait; | ||
| 461 | unsigned long ipath_lastcancel; /* to not count armlaunch after cancel */ | 491 | unsigned long ipath_lastcancel; /* to not count armlaunch after cancel */ |
| 462 | 492 | ||
| 463 | /* value we put in kr_rcvhdrcnt */ | 493 | /* value we put in kr_rcvhdrcnt */ |
| @@ -550,12 +580,26 @@ struct ipath_devdata { | |||
| 550 | u8 ipath_minrev; | 580 | u8 ipath_minrev; |
| 551 | /* board rev, from ipath_revision */ | 581 | /* board rev, from ipath_revision */ |
| 552 | u8 ipath_boardrev; | 582 | u8 ipath_boardrev; |
| 583 | |||
| 584 | u8 ipath_r_portenable_shift; | ||
| 585 | u8 ipath_r_intravail_shift; | ||
| 586 | u8 ipath_r_tailupd_shift; | ||
| 587 | u8 ipath_r_portcfg_shift; | ||
| 588 | |||
| 553 | /* unit # of this chip, if present */ | 589 | /* unit # of this chip, if present */ |
| 554 | int ipath_unit; | 590 | int ipath_unit; |
| 555 | /* saved for restore after reset */ | 591 | /* saved for restore after reset */ |
| 556 | u8 ipath_pci_cacheline; | 592 | u8 ipath_pci_cacheline; |
| 557 | /* LID mask control */ | 593 | /* LID mask control */ |
| 558 | u8 ipath_lmc; | 594 | u8 ipath_lmc; |
| 595 | /* link width supported */ | ||
| 596 | u8 ipath_link_width_supported; | ||
| 597 | /* link speed supported */ | ||
| 598 | u8 ipath_link_speed_supported; | ||
| 599 | u8 ipath_link_width_enabled; | ||
| 600 | u8 ipath_link_speed_enabled; | ||
| 601 | u8 ipath_link_width_active; | ||
| 602 | u8 ipath_link_speed_active; | ||
| 559 | /* Rx Polarity inversion (compensate for ~tx on partner) */ | 603 | /* Rx Polarity inversion (compensate for ~tx on partner) */ |
| 560 | u8 ipath_rx_pol_inv; | 604 | u8 ipath_rx_pol_inv; |
| 561 | 605 | ||
| @@ -590,6 +634,8 @@ struct ipath_devdata { | |||
| 590 | */ | 634 | */ |
| 591 | u32 ipath_i_rcvavail_mask; | 635 | u32 ipath_i_rcvavail_mask; |
| 592 | u32 ipath_i_rcvurg_mask; | 636 | u32 ipath_i_rcvurg_mask; |
| 637 | u16 ipath_i_rcvurg_shift; | ||
| 638 | u16 ipath_i_rcvavail_shift; | ||
| 593 | 639 | ||
| 594 | /* | 640 | /* |
| 595 | * Register bits for selecting i2c direction and values, used for | 641 | * Register bits for selecting i2c direction and values, used for |
| @@ -603,6 +649,29 @@ struct ipath_devdata { | |||
| 603 | /* lock for doing RMW of shadows/regs for ExtCtrl and GPIO */ | 649 | /* lock for doing RMW of shadows/regs for ExtCtrl and GPIO */ |
| 604 | spinlock_t ipath_gpio_lock; | 650 | spinlock_t ipath_gpio_lock; |
| 605 | 651 | ||
| 652 | /* | ||
| 653 | * IB link and linktraining states and masks that vary per chip in | ||
| 654 | * some way. Set at init, to avoid each IB status change interrupt | ||
| 655 | */ | ||
| 656 | u8 ibcs_ls_shift; | ||
| 657 | u8 ibcs_lts_mask; | ||
| 658 | u32 ibcs_mask; | ||
| 659 | u32 ib_init; | ||
| 660 | u32 ib_arm; | ||
| 661 | u32 ib_active; | ||
| 662 | |||
| 663 | u16 ipath_rhf_offset; /* offset of RHF within receive header entry */ | ||
| 664 | |||
| 665 | /* | ||
| 666 | * shift/mask for linkcmd, linkinitcmd, maxpktlen in ibccontol | ||
| 667 | * reg. Changes for IBA7220 | ||
| 668 | */ | ||
| 669 | u8 ibcc_lic_mask; /* LinkInitCmd */ | ||
| 670 | u8 ibcc_lc_shift; /* LinkCmd */ | ||
| 671 | u8 ibcc_mpl_shift; /* Maxpktlen */ | ||
| 672 | |||
| 673 | u8 delay_mult; | ||
| 674 | |||
| 606 | /* used to override LED behavior */ | 675 | /* used to override LED behavior */ |
| 607 | u8 ipath_led_override; /* Substituted for normal value, if non-zero */ | 676 | u8 ipath_led_override; /* Substituted for normal value, if non-zero */ |
| 608 | u16 ipath_led_override_timeoff; /* delta to next timer event */ | 677 | u16 ipath_led_override_timeoff; /* delta to next timer event */ |
| @@ -616,7 +685,7 @@ struct ipath_devdata { | |||
| 616 | /* control access to actual counters, timer */ | 685 | /* control access to actual counters, timer */ |
| 617 | spinlock_t ipath_eep_st_lock; | 686 | spinlock_t ipath_eep_st_lock; |
| 618 | /* control high-level access to EEPROM */ | 687 | /* control high-level access to EEPROM */ |
| 619 | struct semaphore ipath_eep_sem; | 688 | struct mutex ipath_eep_lock; |
| 620 | /* Below inc'd by ipath_snap_cntrs(), locked by ipath_eep_st_lock */ | 689 | /* Below inc'd by ipath_snap_cntrs(), locked by ipath_eep_st_lock */ |
| 621 | uint64_t ipath_traffic_wds; | 690 | uint64_t ipath_traffic_wds; |
| 622 | /* active time is kept in seconds, but logged in hours */ | 691 | /* active time is kept in seconds, but logged in hours */ |
| @@ -630,6 +699,10 @@ struct ipath_devdata { | |||
| 630 | * each of the counters to increment. | 699 | * each of the counters to increment. |
| 631 | */ | 700 | */ |
| 632 | struct ipath_eep_log_mask ipath_eep_st_masks[IPATH_EEP_LOG_CNT]; | 701 | struct ipath_eep_log_mask ipath_eep_st_masks[IPATH_EEP_LOG_CNT]; |
| 702 | |||
| 703 | /* interrupt mitigation reload register info */ | ||
| 704 | u16 ipath_jint_idle_ticks; /* idle clock ticks */ | ||
| 705 | u16 ipath_jint_max_packets; /* max packets across all ports */ | ||
| 633 | }; | 706 | }; |
| 634 | 707 | ||
| 635 | /* Private data for file operations */ | 708 | /* Private data for file operations */ |
| @@ -690,7 +763,7 @@ void ipath_free_pddata(struct ipath_devdata *, struct ipath_portdata *); | |||
| 690 | 763 | ||
| 691 | int ipath_parse_ushort(const char *str, unsigned short *valp); | 764 | int ipath_parse_ushort(const char *str, unsigned short *valp); |
| 692 | 765 | ||
| 693 | void ipath_kreceive(struct ipath_devdata *); | 766 | void ipath_kreceive(struct ipath_portdata *); |
| 694 | int ipath_setrcvhdrsize(struct ipath_devdata *, unsigned); | 767 | int ipath_setrcvhdrsize(struct ipath_devdata *, unsigned); |
| 695 | int ipath_reset_device(int); | 768 | int ipath_reset_device(int); |
| 696 | void ipath_get_faststats(unsigned long); | 769 | void ipath_get_faststats(unsigned long); |
| @@ -698,6 +771,8 @@ int ipath_set_linkstate(struct ipath_devdata *, u8); | |||
| 698 | int ipath_set_mtu(struct ipath_devdata *, u16); | 771 | int ipath_set_mtu(struct ipath_devdata *, u16); |
| 699 | int ipath_set_lid(struct ipath_devdata *, u32, u8); | 772 | int ipath_set_lid(struct ipath_devdata *, u32, u8); |
| 700 | int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv); | 773 | int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv); |
| 774 | void ipath_enable_armlaunch(struct ipath_devdata *); | ||
| 775 | void ipath_disable_armlaunch(struct ipath_devdata *); | ||
| 701 | 776 | ||
| 702 | /* for use in system calls, where we want to know device type, etc. */ | 777 | /* for use in system calls, where we want to know device type, etc. */ |
| 703 | #define port_fp(fp) ((struct ipath_filedata *)(fp)->private_data)->pd | 778 | #define port_fp(fp) ((struct ipath_filedata *)(fp)->private_data)->pd |
| @@ -744,9 +819,15 @@ int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv); | |||
| 744 | * are 64bit */ | 819 | * are 64bit */ |
| 745 | #define IPATH_32BITCOUNTERS 0x20000 | 820 | #define IPATH_32BITCOUNTERS 0x20000 |
| 746 | /* can miss port0 rx interrupts */ | 821 | /* can miss port0 rx interrupts */ |
| 822 | /* Interrupt register is 64 bits */ | ||
| 823 | #define IPATH_INTREG_64 0x40000 | ||
| 747 | #define IPATH_DISABLED 0x80000 /* administratively disabled */ | 824 | #define IPATH_DISABLED 0x80000 /* administratively disabled */ |
| 748 | /* Use GPIO interrupts for new counters */ | 825 | /* Use GPIO interrupts for new counters */ |
| 749 | #define IPATH_GPIO_ERRINTRS 0x100000 | 826 | #define IPATH_GPIO_ERRINTRS 0x100000 |
| 827 | #define IPATH_SWAP_PIOBUFS 0x200000 | ||
| 828 | /* Suppress heartbeat, even if turning off loopback */ | ||
| 829 | #define IPATH_NO_HRTBT 0x1000000 | ||
| 830 | #define IPATH_HAS_MULT_IB_SPEED 0x8000000 | ||
| 750 | 831 | ||
| 751 | /* Bits in GPIO for the added interrupts */ | 832 | /* Bits in GPIO for the added interrupts */ |
| 752 | #define IPATH_GPIO_PORT0_BIT 2 | 833 | #define IPATH_GPIO_PORT0_BIT 2 |
| @@ -758,8 +839,6 @@ int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv); | |||
| 758 | /* portdata flag bit offsets */ | 839 | /* portdata flag bit offsets */ |
| 759 | /* waiting for a packet to arrive */ | 840 | /* waiting for a packet to arrive */ |
| 760 | #define IPATH_PORT_WAITING_RCV 2 | 841 | #define IPATH_PORT_WAITING_RCV 2 |
| 761 | /* waiting for a PIO buffer to be available */ | ||
| 762 | #define IPATH_PORT_WAITING_PIO 3 | ||
| 763 | /* master has not finished initializing */ | 842 | /* master has not finished initializing */ |
| 764 | #define IPATH_PORT_MASTER_UNINIT 4 | 843 | #define IPATH_PORT_MASTER_UNINIT 4 |
| 765 | /* waiting for an urgent packet to arrive */ | 844 | /* waiting for an urgent packet to arrive */ |
| @@ -767,8 +846,6 @@ int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv); | |||
| 767 | 846 | ||
| 768 | /* free up any allocated data at closes */ | 847 | /* free up any allocated data at closes */ |
| 769 | void ipath_free_data(struct ipath_portdata *dd); | 848 | void ipath_free_data(struct ipath_portdata *dd); |
| 770 | int ipath_waitfor_mdio_cmdready(struct ipath_devdata *); | ||
| 771 | int ipath_waitfor_complete(struct ipath_devdata *, ipath_kreg, u64, u64 *); | ||
| 772 | u32 __iomem *ipath_getpiobuf(struct ipath_devdata *, u32 *); | 849 | u32 __iomem *ipath_getpiobuf(struct ipath_devdata *, u32 *); |
| 773 | void ipath_init_iba6120_funcs(struct ipath_devdata *); | 850 | void ipath_init_iba6120_funcs(struct ipath_devdata *); |
| 774 | void ipath_init_iba6110_funcs(struct ipath_devdata *); | 851 | void ipath_init_iba6110_funcs(struct ipath_devdata *); |
| @@ -792,33 +869,6 @@ void ipath_set_led_override(struct ipath_devdata *dd, unsigned int val); | |||
| 792 | */ | 869 | */ |
| 793 | #define IPATH_DFLT_RCVHDRSIZE 9 | 870 | #define IPATH_DFLT_RCVHDRSIZE 9 |
| 794 | 871 | ||
| 795 | #define IPATH_MDIO_CMD_WRITE 1 | ||
| 796 | #define IPATH_MDIO_CMD_READ 2 | ||
| 797 | #define IPATH_MDIO_CLD_DIV 25 /* to get 2.5 Mhz mdio clock */ | ||
| 798 | #define IPATH_MDIO_CMDVALID 0x40000000 /* bit 30 */ | ||
| 799 | #define IPATH_MDIO_DATAVALID 0x80000000 /* bit 31 */ | ||
| 800 | #define IPATH_MDIO_CTRL_STD 0x0 | ||
| 801 | |||
| 802 | static inline u64 ipath_mdio_req(int cmd, int dev, int reg, int data) | ||
| 803 | { | ||
| 804 | return (((u64) IPATH_MDIO_CLD_DIV) << 32) | | ||
| 805 | (cmd << 26) | | ||
| 806 | (dev << 21) | | ||
| 807 | (reg << 16) | | ||
| 808 | (data & 0xFFFF); | ||
| 809 | } | ||
| 810 | |||
| 811 | /* signal and fifo status, in bank 31 */ | ||
| 812 | #define IPATH_MDIO_CTRL_XGXS_REG_8 0x8 | ||
| 813 | /* controls loopback, redundancy */ | ||
| 814 | #define IPATH_MDIO_CTRL_8355_REG_1 0x10 | ||
| 815 | /* premph, encdec, etc. */ | ||
| 816 | #define IPATH_MDIO_CTRL_8355_REG_2 0x11 | ||
| 817 | /* Kchars, etc. */ | ||
| 818 | #define IPATH_MDIO_CTRL_8355_REG_6 0x15 | ||
| 819 | #define IPATH_MDIO_CTRL_8355_REG_9 0x18 | ||
| 820 | #define IPATH_MDIO_CTRL_8355_REG_10 0x1D | ||
| 821 | |||
| 822 | int ipath_get_user_pages(unsigned long, size_t, struct page **); | 872 | int ipath_get_user_pages(unsigned long, size_t, struct page **); |
| 823 | void ipath_release_user_pages(struct page **, size_t); | 873 | void ipath_release_user_pages(struct page **, size_t); |
| 824 | void ipath_release_user_pages_on_close(struct page **, size_t); | 874 | void ipath_release_user_pages_on_close(struct page **, size_t); |
| @@ -863,7 +913,7 @@ static inline u32 ipath_read_ureg32(const struct ipath_devdata *dd, | |||
| 863 | return readl(regno + (u64 __iomem *) | 913 | return readl(regno + (u64 __iomem *) |
| 864 | (dd->ipath_uregbase + | 914 | (dd->ipath_uregbase + |
| 865 | (char __iomem *)dd->ipath_kregbase + | 915 | (char __iomem *)dd->ipath_kregbase + |
| 866 | dd->ipath_palign * port)); | 916 | dd->ipath_ureg_align * port)); |
| 867 | } | 917 | } |
| 868 | 918 | ||
| 869 | /** | 919 | /** |
| @@ -880,7 +930,7 @@ static inline void ipath_write_ureg(const struct ipath_devdata *dd, | |||
| 880 | { | 930 | { |
| 881 | u64 __iomem *ubase = (u64 __iomem *) | 931 | u64 __iomem *ubase = (u64 __iomem *) |
| 882 | (dd->ipath_uregbase + (char __iomem *) dd->ipath_kregbase + | 932 | (dd->ipath_uregbase + (char __iomem *) dd->ipath_kregbase + |
| 883 | dd->ipath_palign * port); | 933 | dd->ipath_ureg_align * port); |
| 884 | if (dd->ipath_kregbase) | 934 | if (dd->ipath_kregbase) |
| 885 | writeq(value, &ubase[regno]); | 935 | writeq(value, &ubase[regno]); |
| 886 | } | 936 | } |
| @@ -930,6 +980,53 @@ static inline u32 ipath_read_creg32(const struct ipath_devdata *dd, | |||
| 930 | (char __iomem *)dd->ipath_kregbase)); | 980 | (char __iomem *)dd->ipath_kregbase)); |
| 931 | } | 981 | } |
| 932 | 982 | ||
| 983 | static inline void ipath_write_creg(const struct ipath_devdata *dd, | ||
| 984 | ipath_creg regno, u64 value) | ||
| 985 | { | ||
| 986 | if (dd->ipath_kregbase) | ||
| 987 | writeq(value, regno + (u64 __iomem *) | ||
| 988 | (dd->ipath_cregbase + | ||
| 989 | (char __iomem *)dd->ipath_kregbase)); | ||
| 990 | } | ||
| 991 | |||
| 992 | static inline void ipath_clear_rcvhdrtail(const struct ipath_portdata *pd) | ||
| 993 | { | ||
| 994 | *((u64 *) pd->port_rcvhdrtail_kvaddr) = 0ULL; | ||
| 995 | } | ||
| 996 | |||
| 997 | static inline u32 ipath_get_rcvhdrtail(const struct ipath_portdata *pd) | ||
| 998 | { | ||
| 999 | return (u32) le64_to_cpu(*((volatile __le64 *) | ||
| 1000 | pd->port_rcvhdrtail_kvaddr)); | ||
| 1001 | } | ||
| 1002 | |||
| 1003 | static inline u64 ipath_read_ireg(const struct ipath_devdata *dd, ipath_kreg r) | ||
| 1004 | { | ||
| 1005 | return (dd->ipath_flags & IPATH_INTREG_64) ? | ||
| 1006 | ipath_read_kreg64(dd, r) : ipath_read_kreg32(dd, r); | ||
| 1007 | } | ||
| 1008 | |||
| 1009 | /* | ||
| 1010 | * from contents of IBCStatus (or a saved copy), return linkstate | ||
| 1011 | * Report ACTIVE_DEFER as ACTIVE, because we treat them the same | ||
| 1012 | * everywhere, anyway (and should be, for almost all purposes). | ||
| 1013 | */ | ||
| 1014 | static inline u32 ipath_ib_linkstate(struct ipath_devdata *dd, u64 ibcs) | ||
| 1015 | { | ||
| 1016 | u32 state = (u32)(ibcs >> dd->ibcs_ls_shift) & | ||
| 1017 | INFINIPATH_IBCS_LINKSTATE_MASK; | ||
| 1018 | if (state == INFINIPATH_IBCS_L_STATE_ACT_DEFER) | ||
| 1019 | state = INFINIPATH_IBCS_L_STATE_ACTIVE; | ||
| 1020 | return state; | ||
| 1021 | } | ||
| 1022 | |||
| 1023 | /* from contents of IBCStatus (or a saved copy), return linktrainingstate */ | ||
| 1024 | static inline u32 ipath_ib_linktrstate(struct ipath_devdata *dd, u64 ibcs) | ||
| 1025 | { | ||
| 1026 | return (u32)(ibcs >> INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) & | ||
| 1027 | dd->ibcs_lts_mask; | ||
| 1028 | } | ||
| 1029 | |||
| 933 | /* | 1030 | /* |
| 934 | * sysfs interface. | 1031 | * sysfs interface. |
| 935 | */ | 1032 | */ |
diff --git a/drivers/infiniband/hw/ipath/ipath_keys.c b/drivers/infiniband/hw/ipath/ipath_keys.c index 85a4aefc6c03..8f32b17a5eed 100644 --- a/drivers/infiniband/hw/ipath/ipath_keys.c +++ b/drivers/infiniband/hw/ipath/ipath_keys.c | |||
| @@ -128,9 +128,8 @@ int ipath_lkey_ok(struct ipath_qp *qp, struct ipath_sge *isge, | |||
| 128 | int ret; | 128 | int ret; |
| 129 | 129 | ||
| 130 | /* | 130 | /* |
| 131 | * We use LKEY == zero to mean a physical kmalloc() address. | 131 | * We use LKEY == zero for kernel virtual addresses |
| 132 | * This is a bit of a hack since we rely on dma_map_single() | 132 | * (see ipath_get_dma_mr and ipath_dma.c). |
| 133 | * being reversible by calling bus_to_virt(). | ||
| 134 | */ | 133 | */ |
| 135 | if (sge->lkey == 0) { | 134 | if (sge->lkey == 0) { |
| 136 | struct ipath_pd *pd = to_ipd(qp->ibqp.pd); | 135 | struct ipath_pd *pd = to_ipd(qp->ibqp.pd); |
diff --git a/drivers/infiniband/hw/ipath/ipath_mad.c b/drivers/infiniband/hw/ipath/ipath_mad.c index 3d1432d1e3f4..d98d5f103700 100644 --- a/drivers/infiniband/hw/ipath/ipath_mad.c +++ b/drivers/infiniband/hw/ipath/ipath_mad.c | |||
| @@ -934,6 +934,7 @@ static int recv_pma_get_portsamplescontrol(struct ib_perf *pmp, | |||
| 934 | struct ib_pma_portsamplescontrol *p = | 934 | struct ib_pma_portsamplescontrol *p = |
| 935 | (struct ib_pma_portsamplescontrol *)pmp->data; | 935 | (struct ib_pma_portsamplescontrol *)pmp->data; |
| 936 | struct ipath_ibdev *dev = to_idev(ibdev); | 936 | struct ipath_ibdev *dev = to_idev(ibdev); |
| 937 | struct ipath_cregs const *crp = dev->dd->ipath_cregs; | ||
| 937 | unsigned long flags; | 938 | unsigned long flags; |
| 938 | u8 port_select = p->port_select; | 939 | u8 port_select = p->port_select; |
| 939 | 940 | ||
| @@ -955,7 +956,10 @@ static int recv_pma_get_portsamplescontrol(struct ib_perf *pmp, | |||
| 955 | p->counter_width = 4; /* 32 bit counters */ | 956 | p->counter_width = 4; /* 32 bit counters */ |
| 956 | p->counter_mask0_9 = COUNTER_MASK0_9; | 957 | p->counter_mask0_9 = COUNTER_MASK0_9; |
| 957 | spin_lock_irqsave(&dev->pending_lock, flags); | 958 | spin_lock_irqsave(&dev->pending_lock, flags); |
| 958 | p->sample_status = dev->pma_sample_status; | 959 | if (crp->cr_psstat) |
| 960 | p->sample_status = ipath_read_creg32(dev->dd, crp->cr_psstat); | ||
| 961 | else | ||
| 962 | p->sample_status = dev->pma_sample_status; | ||
| 959 | p->sample_start = cpu_to_be32(dev->pma_sample_start); | 963 | p->sample_start = cpu_to_be32(dev->pma_sample_start); |
| 960 | p->sample_interval = cpu_to_be32(dev->pma_sample_interval); | 964 | p->sample_interval = cpu_to_be32(dev->pma_sample_interval); |
| 961 | p->tag = cpu_to_be16(dev->pma_tag); | 965 | p->tag = cpu_to_be16(dev->pma_tag); |
| @@ -975,8 +979,9 @@ static int recv_pma_set_portsamplescontrol(struct ib_perf *pmp, | |||
| 975 | struct ib_pma_portsamplescontrol *p = | 979 | struct ib_pma_portsamplescontrol *p = |
| 976 | (struct ib_pma_portsamplescontrol *)pmp->data; | 980 | (struct ib_pma_portsamplescontrol *)pmp->data; |
| 977 | struct ipath_ibdev *dev = to_idev(ibdev); | 981 | struct ipath_ibdev *dev = to_idev(ibdev); |
| 982 | struct ipath_cregs const *crp = dev->dd->ipath_cregs; | ||
| 978 | unsigned long flags; | 983 | unsigned long flags; |
| 979 | u32 start; | 984 | u8 status; |
| 980 | int ret; | 985 | int ret; |
| 981 | 986 | ||
| 982 | if (pmp->attr_mod != 0 || | 987 | if (pmp->attr_mod != 0 || |
| @@ -986,59 +991,67 @@ static int recv_pma_set_portsamplescontrol(struct ib_perf *pmp, | |||
| 986 | goto bail; | 991 | goto bail; |
| 987 | } | 992 | } |
| 988 | 993 | ||
| 989 | start = be32_to_cpu(p->sample_start); | 994 | spin_lock_irqsave(&dev->pending_lock, flags); |
| 990 | if (start != 0) { | 995 | if (crp->cr_psstat) |
| 991 | spin_lock_irqsave(&dev->pending_lock, flags); | 996 | status = ipath_read_creg32(dev->dd, crp->cr_psstat); |
| 992 | if (dev->pma_sample_status == IB_PMA_SAMPLE_STATUS_DONE) { | 997 | else |
| 993 | dev->pma_sample_status = | 998 | status = dev->pma_sample_status; |
| 994 | IB_PMA_SAMPLE_STATUS_STARTED; | 999 | if (status == IB_PMA_SAMPLE_STATUS_DONE) { |
| 995 | dev->pma_sample_start = start; | 1000 | dev->pma_sample_start = be32_to_cpu(p->sample_start); |
| 996 | dev->pma_sample_interval = | 1001 | dev->pma_sample_interval = be32_to_cpu(p->sample_interval); |
| 997 | be32_to_cpu(p->sample_interval); | 1002 | dev->pma_tag = be16_to_cpu(p->tag); |
| 998 | dev->pma_tag = be16_to_cpu(p->tag); | 1003 | dev->pma_counter_select[0] = p->counter_select[0]; |
| 999 | if (p->counter_select[0]) | 1004 | dev->pma_counter_select[1] = p->counter_select[1]; |
| 1000 | dev->pma_counter_select[0] = | 1005 | dev->pma_counter_select[2] = p->counter_select[2]; |
| 1001 | p->counter_select[0]; | 1006 | dev->pma_counter_select[3] = p->counter_select[3]; |
| 1002 | if (p->counter_select[1]) | 1007 | dev->pma_counter_select[4] = p->counter_select[4]; |
| 1003 | dev->pma_counter_select[1] = | 1008 | if (crp->cr_psstat) { |
| 1004 | p->counter_select[1]; | 1009 | ipath_write_creg(dev->dd, crp->cr_psinterval, |
| 1005 | if (p->counter_select[2]) | 1010 | dev->pma_sample_interval); |
| 1006 | dev->pma_counter_select[2] = | 1011 | ipath_write_creg(dev->dd, crp->cr_psstart, |
| 1007 | p->counter_select[2]; | 1012 | dev->pma_sample_start); |
| 1008 | if (p->counter_select[3]) | 1013 | } else |
| 1009 | dev->pma_counter_select[3] = | 1014 | dev->pma_sample_status = IB_PMA_SAMPLE_STATUS_STARTED; |
| 1010 | p->counter_select[3]; | ||
| 1011 | if (p->counter_select[4]) | ||
| 1012 | dev->pma_counter_select[4] = | ||
| 1013 | p->counter_select[4]; | ||
| 1014 | } | ||
| 1015 | spin_unlock_irqrestore(&dev->pending_lock, flags); | ||
| 1016 | } | 1015 | } |
| 1016 | spin_unlock_irqrestore(&dev->pending_lock, flags); | ||
| 1017 | |||
| 1017 | ret = recv_pma_get_portsamplescontrol(pmp, ibdev, port); | 1018 | ret = recv_pma_get_portsamplescontrol(pmp, ibdev, port); |
| 1018 | 1019 | ||
| 1019 | bail: | 1020 | bail: |
| 1020 | return ret; | 1021 | return ret; |
| 1021 | } | 1022 | } |
| 1022 | 1023 | ||
| 1023 | static u64 get_counter(struct ipath_ibdev *dev, __be16 sel) | 1024 | static u64 get_counter(struct ipath_ibdev *dev, |
| 1025 | struct ipath_cregs const *crp, | ||
| 1026 | __be16 sel) | ||
| 1024 | { | 1027 | { |
| 1025 | u64 ret; | 1028 | u64 ret; |
| 1026 | 1029 | ||
| 1027 | switch (sel) { | 1030 | switch (sel) { |
| 1028 | case IB_PMA_PORT_XMIT_DATA: | 1031 | case IB_PMA_PORT_XMIT_DATA: |
| 1029 | ret = dev->ipath_sword; | 1032 | ret = (crp->cr_psxmitdatacount) ? |
| 1033 | ipath_read_creg32(dev->dd, crp->cr_psxmitdatacount) : | ||
| 1034 | dev->ipath_sword; | ||
| 1030 | break; | 1035 | break; |
| 1031 | case IB_PMA_PORT_RCV_DATA: | 1036 | case IB_PMA_PORT_RCV_DATA: |
| 1032 | ret = dev->ipath_rword; | 1037 | ret = (crp->cr_psrcvdatacount) ? |
| 1038 | ipath_read_creg32(dev->dd, crp->cr_psrcvdatacount) : | ||
| 1039 | dev->ipath_rword; | ||
| 1033 | break; | 1040 | break; |
| 1034 | case IB_PMA_PORT_XMIT_PKTS: | 1041 | case IB_PMA_PORT_XMIT_PKTS: |
| 1035 | ret = dev->ipath_spkts; | 1042 | ret = (crp->cr_psxmitpktscount) ? |
| 1043 | ipath_read_creg32(dev->dd, crp->cr_psxmitpktscount) : | ||
| 1044 | dev->ipath_spkts; | ||
| 1036 | break; | 1045 | break; |
| 1037 | case IB_PMA_PORT_RCV_PKTS: | 1046 | case IB_PMA_PORT_RCV_PKTS: |
| 1038 | ret = dev->ipath_rpkts; | 1047 | ret = (crp->cr_psrcvpktscount) ? |
| 1048 | ipath_read_creg32(dev->dd, crp->cr_psrcvpktscount) : | ||
| 1049 | dev->ipath_rpkts; | ||
| 1039 | break; | 1050 | break; |
| 1040 | case IB_PMA_PORT_XMIT_WAIT: | 1051 | case IB_PMA_PORT_XMIT_WAIT: |
| 1041 | ret = dev->ipath_xmit_wait; | 1052 | ret = (crp->cr_psxmitwaitcount) ? |
| 1053 | ipath_read_creg32(dev->dd, crp->cr_psxmitwaitcount) : | ||
| 1054 | dev->ipath_xmit_wait; | ||
| 1042 | break; | 1055 | break; |
| 1043 | default: | 1056 | default: |
| 1044 | ret = 0; | 1057 | ret = 0; |
| @@ -1053,14 +1066,21 @@ static int recv_pma_get_portsamplesresult(struct ib_perf *pmp, | |||
| 1053 | struct ib_pma_portsamplesresult *p = | 1066 | struct ib_pma_portsamplesresult *p = |
| 1054 | (struct ib_pma_portsamplesresult *)pmp->data; | 1067 | (struct ib_pma_portsamplesresult *)pmp->data; |
| 1055 | struct ipath_ibdev *dev = to_idev(ibdev); | 1068 | struct ipath_ibdev *dev = to_idev(ibdev); |
| 1069 | struct ipath_cregs const *crp = dev->dd->ipath_cregs; | ||
| 1070 | u8 status; | ||
| 1056 | int i; | 1071 | int i; |
| 1057 | 1072 | ||
| 1058 | memset(pmp->data, 0, sizeof(pmp->data)); | 1073 | memset(pmp->data, 0, sizeof(pmp->data)); |
| 1059 | p->tag = cpu_to_be16(dev->pma_tag); | 1074 | p->tag = cpu_to_be16(dev->pma_tag); |
| 1060 | p->sample_status = cpu_to_be16(dev->pma_sample_status); | 1075 | if (crp->cr_psstat) |
| 1076 | status = ipath_read_creg32(dev->dd, crp->cr_psstat); | ||
| 1077 | else | ||
| 1078 | status = dev->pma_sample_status; | ||
| 1079 | p->sample_status = cpu_to_be16(status); | ||
| 1061 | for (i = 0; i < ARRAY_SIZE(dev->pma_counter_select); i++) | 1080 | for (i = 0; i < ARRAY_SIZE(dev->pma_counter_select); i++) |
| 1062 | p->counter[i] = cpu_to_be32( | 1081 | p->counter[i] = (status != IB_PMA_SAMPLE_STATUS_DONE) ? 0 : |
| 1063 | get_counter(dev, dev->pma_counter_select[i])); | 1082 | cpu_to_be32( |
| 1083 | get_counter(dev, crp, dev->pma_counter_select[i])); | ||
| 1064 | 1084 | ||
| 1065 | return reply((struct ib_smp *) pmp); | 1085 | return reply((struct ib_smp *) pmp); |
| 1066 | } | 1086 | } |
| @@ -1071,16 +1091,23 @@ static int recv_pma_get_portsamplesresult_ext(struct ib_perf *pmp, | |||
| 1071 | struct ib_pma_portsamplesresult_ext *p = | 1091 | struct ib_pma_portsamplesresult_ext *p = |
| 1072 | (struct ib_pma_portsamplesresult_ext *)pmp->data; | 1092 | (struct ib_pma_portsamplesresult_ext *)pmp->data; |
| 1073 | struct ipath_ibdev *dev = to_idev(ibdev); | 1093 | struct ipath_ibdev *dev = to_idev(ibdev); |
| 1094 | struct ipath_cregs const *crp = dev->dd->ipath_cregs; | ||
| 1095 | u8 status; | ||
| 1074 | int i; | 1096 | int i; |
| 1075 | 1097 | ||
| 1076 | memset(pmp->data, 0, sizeof(pmp->data)); | 1098 | memset(pmp->data, 0, sizeof(pmp->data)); |
| 1077 | p->tag = cpu_to_be16(dev->pma_tag); | 1099 | p->tag = cpu_to_be16(dev->pma_tag); |
| 1078 | p->sample_status = cpu_to_be16(dev->pma_sample_status); | 1100 | if (crp->cr_psstat) |
| 1101 | status = ipath_read_creg32(dev->dd, crp->cr_psstat); | ||
| 1102 | else | ||
| 1103 | status = dev->pma_sample_status; | ||
| 1104 | p->sample_status = cpu_to_be16(status); | ||
| 1079 | /* 64 bits */ | 1105 | /* 64 bits */ |
| 1080 | p->extended_width = __constant_cpu_to_be32(0x80000000); | 1106 | p->extended_width = __constant_cpu_to_be32(0x80000000); |
| 1081 | for (i = 0; i < ARRAY_SIZE(dev->pma_counter_select); i++) | 1107 | for (i = 0; i < ARRAY_SIZE(dev->pma_counter_select); i++) |
| 1082 | p->counter[i] = cpu_to_be64( | 1108 | p->counter[i] = (status != IB_PMA_SAMPLE_STATUS_DONE) ? 0 : |
| 1083 | get_counter(dev, dev->pma_counter_select[i])); | 1109 | cpu_to_be64( |
| 1110 | get_counter(dev, crp, dev->pma_counter_select[i])); | ||
| 1084 | 1111 | ||
| 1085 | return reply((struct ib_smp *) pmp); | 1112 | return reply((struct ib_smp *) pmp); |
| 1086 | } | 1113 | } |
| @@ -1113,6 +1140,8 @@ static int recv_pma_get_portcounters(struct ib_perf *pmp, | |||
| 1113 | dev->z_local_link_integrity_errors; | 1140 | dev->z_local_link_integrity_errors; |
| 1114 | cntrs.excessive_buffer_overrun_errors -= | 1141 | cntrs.excessive_buffer_overrun_errors -= |
| 1115 | dev->z_excessive_buffer_overrun_errors; | 1142 | dev->z_excessive_buffer_overrun_errors; |
| 1143 | cntrs.vl15_dropped -= dev->z_vl15_dropped; | ||
| 1144 | cntrs.vl15_dropped += dev->n_vl15_dropped; | ||
| 1116 | 1145 | ||
| 1117 | memset(pmp->data, 0, sizeof(pmp->data)); | 1146 | memset(pmp->data, 0, sizeof(pmp->data)); |
| 1118 | 1147 | ||
| @@ -1156,10 +1185,10 @@ static int recv_pma_get_portcounters(struct ib_perf *pmp, | |||
| 1156 | cntrs.excessive_buffer_overrun_errors = 0xFUL; | 1185 | cntrs.excessive_buffer_overrun_errors = 0xFUL; |
| 1157 | p->lli_ebor_errors = (cntrs.local_link_integrity_errors << 4) | | 1186 | p->lli_ebor_errors = (cntrs.local_link_integrity_errors << 4) | |
| 1158 | cntrs.excessive_buffer_overrun_errors; | 1187 | cntrs.excessive_buffer_overrun_errors; |
| 1159 | if (dev->n_vl15_dropped > 0xFFFFUL) | 1188 | if (cntrs.vl15_dropped > 0xFFFFUL) |
| 1160 | p->vl15_dropped = __constant_cpu_to_be16(0xFFFF); | 1189 | p->vl15_dropped = __constant_cpu_to_be16(0xFFFF); |
| 1161 | else | 1190 | else |
| 1162 | p->vl15_dropped = cpu_to_be16((u16)dev->n_vl15_dropped); | 1191 | p->vl15_dropped = cpu_to_be16((u16)cntrs.vl15_dropped); |
| 1163 | if (cntrs.port_xmit_data > 0xFFFFFFFFUL) | 1192 | if (cntrs.port_xmit_data > 0xFFFFFFFFUL) |
| 1164 | p->port_xmit_data = __constant_cpu_to_be32(0xFFFFFFFF); | 1193 | p->port_xmit_data = __constant_cpu_to_be32(0xFFFFFFFF); |
| 1165 | else | 1194 | else |
| @@ -1262,8 +1291,10 @@ static int recv_pma_set_portcounters(struct ib_perf *pmp, | |||
| 1262 | dev->z_excessive_buffer_overrun_errors = | 1291 | dev->z_excessive_buffer_overrun_errors = |
| 1263 | cntrs.excessive_buffer_overrun_errors; | 1292 | cntrs.excessive_buffer_overrun_errors; |
| 1264 | 1293 | ||
| 1265 | if (p->counter_select & IB_PMA_SEL_PORT_VL15_DROPPED) | 1294 | if (p->counter_select & IB_PMA_SEL_PORT_VL15_DROPPED) { |
| 1266 | dev->n_vl15_dropped = 0; | 1295 | dev->n_vl15_dropped = 0; |
| 1296 | dev->z_vl15_dropped = cntrs.vl15_dropped; | ||
| 1297 | } | ||
| 1267 | 1298 | ||
| 1268 | if (p->counter_select & IB_PMA_SEL_PORT_XMIT_DATA) | 1299 | if (p->counter_select & IB_PMA_SEL_PORT_XMIT_DATA) |
| 1269 | dev->z_port_xmit_data = cntrs.port_xmit_data; | 1300 | dev->z_port_xmit_data = cntrs.port_xmit_data; |
| @@ -1434,7 +1465,7 @@ static int process_subn(struct ib_device *ibdev, int mad_flags, | |||
| 1434 | * before checking for other consumers. | 1465 | * before checking for other consumers. |
| 1435 | * Just tell the caller to process it normally. | 1466 | * Just tell the caller to process it normally. |
| 1436 | */ | 1467 | */ |
| 1437 | ret = IB_MAD_RESULT_FAILURE; | 1468 | ret = IB_MAD_RESULT_SUCCESS; |
| 1438 | goto bail; | 1469 | goto bail; |
| 1439 | default: | 1470 | default: |
| 1440 | smp->status |= IB_SMP_UNSUP_METHOD; | 1471 | smp->status |= IB_SMP_UNSUP_METHOD; |
| @@ -1516,7 +1547,7 @@ static int process_perf(struct ib_device *ibdev, u8 port_num, | |||
| 1516 | * before checking for other consumers. | 1547 | * before checking for other consumers. |
| 1517 | * Just tell the caller to process it normally. | 1548 | * Just tell the caller to process it normally. |
| 1518 | */ | 1549 | */ |
| 1519 | ret = IB_MAD_RESULT_FAILURE; | 1550 | ret = IB_MAD_RESULT_SUCCESS; |
| 1520 | goto bail; | 1551 | goto bail; |
| 1521 | default: | 1552 | default: |
| 1522 | pmp->status |= IB_SMP_UNSUP_METHOD; | 1553 | pmp->status |= IB_SMP_UNSUP_METHOD; |
diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c index b997ff88401b..80dc623cee40 100644 --- a/drivers/infiniband/hw/ipath/ipath_qp.c +++ b/drivers/infiniband/hw/ipath/ipath_qp.c | |||
| @@ -387,8 +387,8 @@ int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err) | |||
| 387 | struct ib_wc wc; | 387 | struct ib_wc wc; |
| 388 | int ret = 0; | 388 | int ret = 0; |
| 389 | 389 | ||
| 390 | ipath_dbg("QP%d/%d in error state\n", | 390 | ipath_dbg("QP%d/%d in error state (%d)\n", |
| 391 | qp->ibqp.qp_num, qp->remote_qpn); | 391 | qp->ibqp.qp_num, qp->remote_qpn, err); |
| 392 | 392 | ||
| 393 | spin_lock(&dev->pending_lock); | 393 | spin_lock(&dev->pending_lock); |
| 394 | /* XXX What if its already removed by the timeout code? */ | 394 | /* XXX What if its already removed by the timeout code? */ |
| @@ -855,8 +855,6 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd, | |||
| 855 | * See ipath_mmap() for details. | 855 | * See ipath_mmap() for details. |
| 856 | */ | 856 | */ |
| 857 | if (udata && udata->outlen >= sizeof(__u64)) { | 857 | if (udata && udata->outlen >= sizeof(__u64)) { |
| 858 | int err; | ||
| 859 | |||
| 860 | if (!qp->r_rq.wq) { | 858 | if (!qp->r_rq.wq) { |
| 861 | __u64 offset = 0; | 859 | __u64 offset = 0; |
| 862 | 860 | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c index 120a61b03bc4..459e46e2c016 100644 --- a/drivers/infiniband/hw/ipath/ipath_rc.c +++ b/drivers/infiniband/hw/ipath/ipath_rc.c | |||
| @@ -647,6 +647,7 @@ static void send_rc_ack(struct ipath_qp *qp) | |||
| 647 | 647 | ||
| 648 | queue_ack: | 648 | queue_ack: |
| 649 | spin_lock_irqsave(&qp->s_lock, flags); | 649 | spin_lock_irqsave(&qp->s_lock, flags); |
| 650 | dev->n_rc_qacks++; | ||
| 650 | qp->s_flags |= IPATH_S_ACK_PENDING; | 651 | qp->s_flags |= IPATH_S_ACK_PENDING; |
| 651 | qp->s_nak_state = qp->r_nak_state; | 652 | qp->s_nak_state = qp->r_nak_state; |
| 652 | qp->s_ack_psn = qp->r_ack_psn; | 653 | qp->s_ack_psn = qp->r_ack_psn; |
| @@ -798,11 +799,13 @@ bail: | |||
| 798 | 799 | ||
| 799 | static inline void update_last_psn(struct ipath_qp *qp, u32 psn) | 800 | static inline void update_last_psn(struct ipath_qp *qp, u32 psn) |
| 800 | { | 801 | { |
| 801 | if (qp->s_wait_credit) { | 802 | if (qp->s_last_psn != psn) { |
| 802 | qp->s_wait_credit = 0; | 803 | qp->s_last_psn = psn; |
| 803 | tasklet_hi_schedule(&qp->s_task); | 804 | if (qp->s_wait_credit) { |
| 805 | qp->s_wait_credit = 0; | ||
| 806 | tasklet_hi_schedule(&qp->s_task); | ||
| 807 | } | ||
| 804 | } | 808 | } |
| 805 | qp->s_last_psn = psn; | ||
| 806 | } | 809 | } |
| 807 | 810 | ||
| 808 | /** | 811 | /** |
| @@ -1653,13 +1656,6 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, | |||
| 1653 | case OP(SEND_FIRST): | 1656 | case OP(SEND_FIRST): |
| 1654 | if (!ipath_get_rwqe(qp, 0)) { | 1657 | if (!ipath_get_rwqe(qp, 0)) { |
| 1655 | rnr_nak: | 1658 | rnr_nak: |
| 1656 | /* | ||
| 1657 | * A RNR NAK will ACK earlier sends and RDMA writes. | ||
| 1658 | * Don't queue the NAK if a RDMA read or atomic | ||
| 1659 | * is pending though. | ||
| 1660 | */ | ||
| 1661 | if (qp->r_nak_state) | ||
| 1662 | goto done; | ||
| 1663 | qp->r_nak_state = IB_RNR_NAK | qp->r_min_rnr_timer; | 1659 | qp->r_nak_state = IB_RNR_NAK | qp->r_min_rnr_timer; |
| 1664 | qp->r_ack_psn = qp->r_psn; | 1660 | qp->r_ack_psn = qp->r_psn; |
| 1665 | goto send_ack; | 1661 | goto send_ack; |
diff --git a/drivers/infiniband/hw/ipath/ipath_registers.h b/drivers/infiniband/hw/ipath/ipath_registers.h index 708eba3165d7..6d2a17f9c1da 100644 --- a/drivers/infiniband/hw/ipath/ipath_registers.h +++ b/drivers/infiniband/hw/ipath/ipath_registers.h | |||
| @@ -82,8 +82,7 @@ | |||
| 82 | 82 | ||
| 83 | /* kr_rcvctrl bits */ | 83 | /* kr_rcvctrl bits */ |
| 84 | #define INFINIPATH_R_PORTENABLE_SHIFT 0 | 84 | #define INFINIPATH_R_PORTENABLE_SHIFT 0 |
| 85 | #define INFINIPATH_R_INTRAVAIL_SHIFT 16 | 85 | #define INFINIPATH_R_QPMAP_ENABLE (1ULL << 38) |
| 86 | #define INFINIPATH_R_TAILUPD 0x80000000 | ||
| 87 | 86 | ||
| 88 | /* kr_intstatus, kr_intclear, kr_intmask bits */ | 87 | /* kr_intstatus, kr_intclear, kr_intmask bits */ |
| 89 | #define INFINIPATH_I_RCVURG_SHIFT 0 | 88 | #define INFINIPATH_I_RCVURG_SHIFT 0 |
| @@ -272,20 +271,6 @@ | |||
| 272 | #define INFINIPATH_EXTC_LEDGBLOK_ON 0x00000002ULL | 271 | #define INFINIPATH_EXTC_LEDGBLOK_ON 0x00000002ULL |
| 273 | #define INFINIPATH_EXTC_LEDGBLERR_OFF 0x00000001ULL | 272 | #define INFINIPATH_EXTC_LEDGBLERR_OFF 0x00000001ULL |
| 274 | 273 | ||
| 275 | /* kr_mdio bits */ | ||
| 276 | #define INFINIPATH_MDIO_CLKDIV_MASK 0x7FULL | ||
| 277 | #define INFINIPATH_MDIO_CLKDIV_SHIFT 32 | ||
| 278 | #define INFINIPATH_MDIO_COMMAND_MASK 0x7ULL | ||
| 279 | #define INFINIPATH_MDIO_COMMAND_SHIFT 26 | ||
| 280 | #define INFINIPATH_MDIO_DEVADDR_MASK 0x1FULL | ||
| 281 | #define INFINIPATH_MDIO_DEVADDR_SHIFT 21 | ||
| 282 | #define INFINIPATH_MDIO_REGADDR_MASK 0x1FULL | ||
| 283 | #define INFINIPATH_MDIO_REGADDR_SHIFT 16 | ||
| 284 | #define INFINIPATH_MDIO_DATA_MASK 0xFFFFULL | ||
| 285 | #define INFINIPATH_MDIO_DATA_SHIFT 0 | ||
| 286 | #define INFINIPATH_MDIO_CMDVALID 0x0000000040000000ULL | ||
| 287 | #define INFINIPATH_MDIO_RDDATAVALID 0x0000000080000000ULL | ||
| 288 | |||
| 289 | /* kr_partitionkey bits */ | 274 | /* kr_partitionkey bits */ |
| 290 | #define INFINIPATH_PKEY_SIZE 16 | 275 | #define INFINIPATH_PKEY_SIZE 16 |
| 291 | #define INFINIPATH_PKEY_MASK 0xFFFF | 276 | #define INFINIPATH_PKEY_MASK 0xFFFF |
| @@ -303,8 +288,6 @@ | |||
| 303 | 288 | ||
| 304 | /* kr_xgxsconfig bits */ | 289 | /* kr_xgxsconfig bits */ |
| 305 | #define INFINIPATH_XGXS_RESET 0x7ULL | 290 | #define INFINIPATH_XGXS_RESET 0x7ULL |
| 306 | #define INFINIPATH_XGXS_MDIOADDR_MASK 0xfULL | ||
| 307 | #define INFINIPATH_XGXS_MDIOADDR_SHIFT 4 | ||
| 308 | #define INFINIPATH_XGXS_RX_POL_SHIFT 19 | 291 | #define INFINIPATH_XGXS_RX_POL_SHIFT 19 |
| 309 | #define INFINIPATH_XGXS_RX_POL_MASK 0xfULL | 292 | #define INFINIPATH_XGXS_RX_POL_MASK 0xfULL |
| 310 | 293 | ||
| @@ -470,6 +453,20 @@ struct ipath_cregs { | |||
| 470 | ipath_creg cr_unsupvlcnt; | 453 | ipath_creg cr_unsupvlcnt; |
| 471 | ipath_creg cr_wordrcvcnt; | 454 | ipath_creg cr_wordrcvcnt; |
| 472 | ipath_creg cr_wordsendcnt; | 455 | ipath_creg cr_wordsendcnt; |
| 456 | ipath_creg cr_vl15droppedpktcnt; | ||
| 457 | ipath_creg cr_rxotherlocalphyerrcnt; | ||
| 458 | ipath_creg cr_excessbufferovflcnt; | ||
| 459 | ipath_creg cr_locallinkintegrityerrcnt; | ||
| 460 | ipath_creg cr_rxvlerrcnt; | ||
| 461 | ipath_creg cr_rxdlidfltrcnt; | ||
| 462 | ipath_creg cr_psstat; | ||
| 463 | ipath_creg cr_psstart; | ||
| 464 | ipath_creg cr_psinterval; | ||
| 465 | ipath_creg cr_psrcvdatacount; | ||
| 466 | ipath_creg cr_psrcvpktscount; | ||
| 467 | ipath_creg cr_psxmitdatacount; | ||
| 468 | ipath_creg cr_psxmitpktscount; | ||
| 469 | ipath_creg cr_psxmitwaitcount; | ||
| 473 | }; | 470 | }; |
| 474 | 471 | ||
| 475 | #endif /* _IPATH_REGISTERS_H */ | 472 | #endif /* _IPATH_REGISTERS_H */ |
diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c b/drivers/infiniband/hw/ipath/ipath_ruc.c index 54c61a972de2..a59bdbd0ed87 100644 --- a/drivers/infiniband/hw/ipath/ipath_ruc.c +++ b/drivers/infiniband/hw/ipath/ipath_ruc.c | |||
| @@ -98,11 +98,15 @@ void ipath_insert_rnr_queue(struct ipath_qp *qp) | |||
| 98 | while (qp->s_rnr_timeout >= nqp->s_rnr_timeout) { | 98 | while (qp->s_rnr_timeout >= nqp->s_rnr_timeout) { |
| 99 | qp->s_rnr_timeout -= nqp->s_rnr_timeout; | 99 | qp->s_rnr_timeout -= nqp->s_rnr_timeout; |
| 100 | l = l->next; | 100 | l = l->next; |
| 101 | if (l->next == &dev->rnrwait) | 101 | if (l->next == &dev->rnrwait) { |
| 102 | nqp = NULL; | ||
| 102 | break; | 103 | break; |
| 104 | } | ||
| 103 | nqp = list_entry(l->next, struct ipath_qp, | 105 | nqp = list_entry(l->next, struct ipath_qp, |
| 104 | timerwait); | 106 | timerwait); |
| 105 | } | 107 | } |
| 108 | if (nqp) | ||
| 109 | nqp->s_rnr_timeout -= qp->s_rnr_timeout; | ||
| 106 | list_add(&qp->timerwait, l); | 110 | list_add(&qp->timerwait, l); |
| 107 | } | 111 | } |
| 108 | spin_unlock_irqrestore(&dev->pending_lock, flags); | 112 | spin_unlock_irqrestore(&dev->pending_lock, flags); |
| @@ -479,9 +483,14 @@ done: | |||
| 479 | 483 | ||
| 480 | static void want_buffer(struct ipath_devdata *dd) | 484 | static void want_buffer(struct ipath_devdata *dd) |
| 481 | { | 485 | { |
| 482 | set_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl); | 486 | unsigned long flags; |
| 487 | |||
| 488 | spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); | ||
| 489 | dd->ipath_sendctrl |= INFINIPATH_S_PIOINTBUFAVAIL; | ||
| 483 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | 490 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, |
| 484 | dd->ipath_sendctrl); | 491 | dd->ipath_sendctrl); |
| 492 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | ||
| 493 | spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); | ||
| 485 | } | 494 | } |
| 486 | 495 | ||
| 487 | /** | 496 | /** |
diff --git a/drivers/infiniband/hw/ipath/ipath_srq.c b/drivers/infiniband/hw/ipath/ipath_srq.c index 2fef36f4b675..f772102e4713 100644 --- a/drivers/infiniband/hw/ipath/ipath_srq.c +++ b/drivers/infiniband/hw/ipath/ipath_srq.c | |||
| @@ -94,8 +94,8 @@ bail: | |||
| 94 | /** | 94 | /** |
| 95 | * ipath_create_srq - create a shared receive queue | 95 | * ipath_create_srq - create a shared receive queue |
| 96 | * @ibpd: the protection domain of the SRQ to create | 96 | * @ibpd: the protection domain of the SRQ to create |
| 97 | * @attr: the attributes of the SRQ | 97 | * @srq_init_attr: the attributes of the SRQ |
| 98 | * @udata: not used by the InfiniPath verbs driver | 98 | * @udata: data from libipathverbs when creating a user SRQ |
| 99 | */ | 99 | */ |
| 100 | struct ib_srq *ipath_create_srq(struct ib_pd *ibpd, | 100 | struct ib_srq *ipath_create_srq(struct ib_pd *ibpd, |
| 101 | struct ib_srq_init_attr *srq_init_attr, | 101 | struct ib_srq_init_attr *srq_init_attr, |
diff --git a/drivers/infiniband/hw/ipath/ipath_stats.c b/drivers/infiniband/hw/ipath/ipath_stats.c index f0271415cd5b..d2725cd11bdc 100644 --- a/drivers/infiniband/hw/ipath/ipath_stats.c +++ b/drivers/infiniband/hw/ipath/ipath_stats.c | |||
| @@ -133,15 +133,16 @@ bail: | |||
| 133 | static void ipath_qcheck(struct ipath_devdata *dd) | 133 | static void ipath_qcheck(struct ipath_devdata *dd) |
| 134 | { | 134 | { |
| 135 | static u64 last_tot_hdrqfull; | 135 | static u64 last_tot_hdrqfull; |
| 136 | struct ipath_portdata *pd = dd->ipath_pd[0]; | ||
| 136 | size_t blen = 0; | 137 | size_t blen = 0; |
| 137 | char buf[128]; | 138 | char buf[128]; |
| 138 | 139 | ||
| 139 | *buf = 0; | 140 | *buf = 0; |
| 140 | if (dd->ipath_pd[0]->port_hdrqfull != dd->ipath_p0_hdrqfull) { | 141 | if (pd->port_hdrqfull != dd->ipath_p0_hdrqfull) { |
| 141 | blen = snprintf(buf, sizeof buf, "port 0 hdrqfull %u", | 142 | blen = snprintf(buf, sizeof buf, "port 0 hdrqfull %u", |
| 142 | dd->ipath_pd[0]->port_hdrqfull - | 143 | pd->port_hdrqfull - |
| 143 | dd->ipath_p0_hdrqfull); | 144 | dd->ipath_p0_hdrqfull); |
| 144 | dd->ipath_p0_hdrqfull = dd->ipath_pd[0]->port_hdrqfull; | 145 | dd->ipath_p0_hdrqfull = pd->port_hdrqfull; |
| 145 | } | 146 | } |
| 146 | if (ipath_stats.sps_etidfull != dd->ipath_last_tidfull) { | 147 | if (ipath_stats.sps_etidfull != dd->ipath_last_tidfull) { |
| 147 | blen += snprintf(buf + blen, sizeof buf - blen, | 148 | blen += snprintf(buf + blen, sizeof buf - blen, |
| @@ -173,7 +174,7 @@ static void ipath_qcheck(struct ipath_devdata *dd) | |||
| 173 | if (blen) | 174 | if (blen) |
| 174 | ipath_dbg("%s\n", buf); | 175 | ipath_dbg("%s\n", buf); |
| 175 | 176 | ||
| 176 | if (dd->ipath_port0head != (u32) | 177 | if (pd->port_head != (u32) |
| 177 | le64_to_cpu(*dd->ipath_hdrqtailptr)) { | 178 | le64_to_cpu(*dd->ipath_hdrqtailptr)) { |
| 178 | if (dd->ipath_lastport0rcv_cnt == | 179 | if (dd->ipath_lastport0rcv_cnt == |
| 179 | ipath_stats.sps_port0pkts) { | 180 | ipath_stats.sps_port0pkts) { |
| @@ -181,7 +182,7 @@ static void ipath_qcheck(struct ipath_devdata *dd) | |||
| 181 | "port0 hd=%llx tl=%x; port0pkts %llx\n", | 182 | "port0 hd=%llx tl=%x; port0pkts %llx\n", |
| 182 | (unsigned long long) | 183 | (unsigned long long) |
| 183 | le64_to_cpu(*dd->ipath_hdrqtailptr), | 184 | le64_to_cpu(*dd->ipath_hdrqtailptr), |
| 184 | dd->ipath_port0head, | 185 | pd->port_head, |
| 185 | (unsigned long long) | 186 | (unsigned long long) |
| 186 | ipath_stats.sps_port0pkts); | 187 | ipath_stats.sps_port0pkts); |
| 187 | } | 188 | } |
| @@ -237,7 +238,7 @@ static void ipath_chk_errormask(struct ipath_devdata *dd) | |||
| 237 | void ipath_get_faststats(unsigned long opaque) | 238 | void ipath_get_faststats(unsigned long opaque) |
| 238 | { | 239 | { |
| 239 | struct ipath_devdata *dd = (struct ipath_devdata *) opaque; | 240 | struct ipath_devdata *dd = (struct ipath_devdata *) opaque; |
| 240 | u32 val; | 241 | int i; |
| 241 | static unsigned cnt; | 242 | static unsigned cnt; |
| 242 | unsigned long flags; | 243 | unsigned long flags; |
| 243 | u64 traffic_wds; | 244 | u64 traffic_wds; |
| @@ -321,12 +322,11 @@ void ipath_get_faststats(unsigned long opaque) | |||
| 321 | 322 | ||
| 322 | /* limit qfull messages to ~one per minute per port */ | 323 | /* limit qfull messages to ~one per minute per port */ |
| 323 | if ((++cnt & 0x10)) { | 324 | if ((++cnt & 0x10)) { |
| 324 | for (val = dd->ipath_cfgports - 1; ((int)val) >= 0; | 325 | for (i = (int) dd->ipath_cfgports; --i >= 0; ) { |
| 325 | val--) { | 326 | struct ipath_portdata *pd = dd->ipath_pd[i]; |
| 326 | if (dd->ipath_lastegrheads[val] != -1) | 327 | |
| 327 | dd->ipath_lastegrheads[val] = -1; | 328 | if (pd && pd->port_lastrcvhdrqtail != -1) |
| 328 | if (dd->ipath_lastrcvhdrqtails[val] != -1) | 329 | pd->port_lastrcvhdrqtail = -1; |
| 329 | dd->ipath_lastrcvhdrqtails[val] = -1; | ||
| 330 | } | 330 | } |
| 331 | } | 331 | } |
| 332 | 332 | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_sysfs.c b/drivers/infiniband/hw/ipath/ipath_sysfs.c index aa27ca9f03b1..56dfc8a2344c 100644 --- a/drivers/infiniband/hw/ipath/ipath_sysfs.c +++ b/drivers/infiniband/hw/ipath/ipath_sysfs.c | |||
| @@ -363,6 +363,60 @@ static ssize_t show_unit(struct device *dev, | |||
| 363 | return scnprintf(buf, PAGE_SIZE, "%u\n", dd->ipath_unit); | 363 | return scnprintf(buf, PAGE_SIZE, "%u\n", dd->ipath_unit); |
| 364 | } | 364 | } |
| 365 | 365 | ||
| 366 | static ssize_t show_jint_max_packets(struct device *dev, | ||
| 367 | struct device_attribute *attr, | ||
| 368 | char *buf) | ||
| 369 | { | ||
| 370 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 371 | |||
| 372 | return scnprintf(buf, PAGE_SIZE, "%hu\n", dd->ipath_jint_max_packets); | ||
| 373 | } | ||
| 374 | |||
| 375 | static ssize_t store_jint_max_packets(struct device *dev, | ||
| 376 | struct device_attribute *attr, | ||
| 377 | const char *buf, | ||
| 378 | size_t count) | ||
| 379 | { | ||
| 380 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 381 | u16 v = 0; | ||
| 382 | int ret; | ||
| 383 | |||
| 384 | ret = ipath_parse_ushort(buf, &v); | ||
| 385 | if (ret < 0) | ||
| 386 | ipath_dev_err(dd, "invalid jint_max_packets.\n"); | ||
| 387 | else | ||
| 388 | dd->ipath_f_config_jint(dd, dd->ipath_jint_idle_ticks, v); | ||
| 389 | |||
| 390 | return ret; | ||
| 391 | } | ||
| 392 | |||
| 393 | static ssize_t show_jint_idle_ticks(struct device *dev, | ||
| 394 | struct device_attribute *attr, | ||
| 395 | char *buf) | ||
| 396 | { | ||
| 397 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 398 | |||
| 399 | return scnprintf(buf, PAGE_SIZE, "%hu\n", dd->ipath_jint_idle_ticks); | ||
| 400 | } | ||
| 401 | |||
| 402 | static ssize_t store_jint_idle_ticks(struct device *dev, | ||
| 403 | struct device_attribute *attr, | ||
| 404 | const char *buf, | ||
| 405 | size_t count) | ||
| 406 | { | ||
| 407 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 408 | u16 v = 0; | ||
| 409 | int ret; | ||
| 410 | |||
| 411 | ret = ipath_parse_ushort(buf, &v); | ||
| 412 | if (ret < 0) | ||
| 413 | ipath_dev_err(dd, "invalid jint_idle_ticks.\n"); | ||
| 414 | else | ||
| 415 | dd->ipath_f_config_jint(dd, v, dd->ipath_jint_max_packets); | ||
| 416 | |||
| 417 | return ret; | ||
| 418 | } | ||
| 419 | |||
| 366 | #define DEVICE_COUNTER(name, attr) \ | 420 | #define DEVICE_COUNTER(name, attr) \ |
| 367 | static ssize_t show_counter_##name(struct device *dev, \ | 421 | static ssize_t show_counter_##name(struct device *dev, \ |
| 368 | struct device_attribute *attr, \ | 422 | struct device_attribute *attr, \ |
| @@ -670,6 +724,257 @@ static ssize_t show_logged_errs(struct device *dev, | |||
| 670 | return count; | 724 | return count; |
| 671 | } | 725 | } |
| 672 | 726 | ||
| 727 | /* | ||
| 728 | * New sysfs entries to control various IB config. These all turn into | ||
| 729 | * accesses via ipath_f_get/set_ib_cfg. | ||
| 730 | * | ||
| 731 | * Get/Set heartbeat enable. Or of 1=enabled, 2=auto | ||
| 732 | */ | ||
| 733 | static ssize_t show_hrtbt_enb(struct device *dev, | ||
| 734 | struct device_attribute *attr, | ||
| 735 | char *buf) | ||
| 736 | { | ||
| 737 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 738 | int ret; | ||
| 739 | |||
| 740 | ret = dd->ipath_f_get_ib_cfg(dd, IPATH_IB_CFG_HRTBT); | ||
| 741 | if (ret >= 0) | ||
| 742 | ret = scnprintf(buf, PAGE_SIZE, "%d\n", ret); | ||
| 743 | return ret; | ||
| 744 | } | ||
| 745 | |||
| 746 | static ssize_t store_hrtbt_enb(struct device *dev, | ||
| 747 | struct device_attribute *attr, | ||
| 748 | const char *buf, | ||
| 749 | size_t count) | ||
| 750 | { | ||
| 751 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 752 | int ret, r; | ||
| 753 | u16 val; | ||
| 754 | |||
| 755 | ret = ipath_parse_ushort(buf, &val); | ||
| 756 | if (ret >= 0 && val > 3) | ||
| 757 | ret = -EINVAL; | ||
| 758 | if (ret < 0) { | ||
| 759 | ipath_dev_err(dd, "attempt to set invalid Heartbeat enable\n"); | ||
| 760 | goto bail; | ||
| 761 | } | ||
| 762 | |||
| 763 | /* | ||
| 764 | * Set the "intentional" heartbeat enable per either of | ||
| 765 | * "Enable" and "Auto", as these are normally set together. | ||
| 766 | * This bit is consulted when leaving loopback mode, | ||
| 767 | * because entering loopback mode overrides it and automatically | ||
| 768 | * disables heartbeat. | ||
| 769 | */ | ||
| 770 | r = dd->ipath_f_set_ib_cfg(dd, IPATH_IB_CFG_HRTBT, val); | ||
| 771 | if (r < 0) | ||
| 772 | ret = r; | ||
| 773 | else if (val == IPATH_IB_HRTBT_OFF) | ||
| 774 | dd->ipath_flags |= IPATH_NO_HRTBT; | ||
| 775 | else | ||
| 776 | dd->ipath_flags &= ~IPATH_NO_HRTBT; | ||
| 777 | |||
| 778 | bail: | ||
| 779 | return ret; | ||
| 780 | } | ||
| 781 | |||
| 782 | /* | ||
| 783 | * Get/Set Link-widths enabled. Or of 1=1x, 2=4x (this is human/IB centric, | ||
| 784 | * _not_ the particular encoding of any given chip) | ||
| 785 | */ | ||
| 786 | static ssize_t show_lwid_enb(struct device *dev, | ||
| 787 | struct device_attribute *attr, | ||
| 788 | char *buf) | ||
| 789 | { | ||
| 790 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 791 | int ret; | ||
| 792 | |||
| 793 | ret = dd->ipath_f_get_ib_cfg(dd, IPATH_IB_CFG_LWID_ENB); | ||
| 794 | if (ret >= 0) | ||
| 795 | ret = scnprintf(buf, PAGE_SIZE, "%d\n", ret); | ||
| 796 | return ret; | ||
| 797 | } | ||
| 798 | |||
| 799 | static ssize_t store_lwid_enb(struct device *dev, | ||
| 800 | struct device_attribute *attr, | ||
| 801 | const char *buf, | ||
| 802 | size_t count) | ||
| 803 | { | ||
| 804 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 805 | int ret, r; | ||
| 806 | u16 val; | ||
| 807 | |||
| 808 | ret = ipath_parse_ushort(buf, &val); | ||
| 809 | if (ret >= 0 && (val == 0 || val > 3)) | ||
| 810 | ret = -EINVAL; | ||
| 811 | if (ret < 0) { | ||
| 812 | ipath_dev_err(dd, | ||
| 813 | "attempt to set invalid Link Width (enable)\n"); | ||
| 814 | goto bail; | ||
| 815 | } | ||
| 816 | |||
| 817 | r = dd->ipath_f_set_ib_cfg(dd, IPATH_IB_CFG_LWID_ENB, val); | ||
| 818 | if (r < 0) | ||
| 819 | ret = r; | ||
| 820 | |||
| 821 | bail: | ||
| 822 | return ret; | ||
| 823 | } | ||
| 824 | |||
| 825 | /* Get current link width */ | ||
| 826 | static ssize_t show_lwid(struct device *dev, | ||
| 827 | struct device_attribute *attr, | ||
| 828 | char *buf) | ||
| 829 | |||
| 830 | { | ||
| 831 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 832 | int ret; | ||
| 833 | |||
| 834 | ret = dd->ipath_f_get_ib_cfg(dd, IPATH_IB_CFG_LWID); | ||
| 835 | if (ret >= 0) | ||
| 836 | ret = scnprintf(buf, PAGE_SIZE, "%d\n", ret); | ||
| 837 | return ret; | ||
| 838 | } | ||
| 839 | |||
| 840 | /* | ||
| 841 | * Get/Set Link-speeds enabled. Or of 1=SDR 2=DDR. | ||
| 842 | */ | ||
| 843 | static ssize_t show_spd_enb(struct device *dev, | ||
| 844 | struct device_attribute *attr, | ||
| 845 | char *buf) | ||
| 846 | { | ||
| 847 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 848 | int ret; | ||
| 849 | |||
| 850 | ret = dd->ipath_f_get_ib_cfg(dd, IPATH_IB_CFG_SPD_ENB); | ||
| 851 | if (ret >= 0) | ||
| 852 | ret = scnprintf(buf, PAGE_SIZE, "%d\n", ret); | ||
| 853 | return ret; | ||
| 854 | } | ||
| 855 | |||
| 856 | static ssize_t store_spd_enb(struct device *dev, | ||
| 857 | struct device_attribute *attr, | ||
| 858 | const char *buf, | ||
| 859 | size_t count) | ||
| 860 | { | ||
| 861 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 862 | int ret, r; | ||
| 863 | u16 val; | ||
| 864 | |||
| 865 | ret = ipath_parse_ushort(buf, &val); | ||
| 866 | if (ret >= 0 && (val == 0 || val > (IPATH_IB_SDR | IPATH_IB_DDR))) | ||
| 867 | ret = -EINVAL; | ||
| 868 | if (ret < 0) { | ||
| 869 | ipath_dev_err(dd, | ||
| 870 | "attempt to set invalid Link Speed (enable)\n"); | ||
| 871 | goto bail; | ||
| 872 | } | ||
| 873 | |||
| 874 | r = dd->ipath_f_set_ib_cfg(dd, IPATH_IB_CFG_SPD_ENB, val); | ||
| 875 | if (r < 0) | ||
| 876 | ret = r; | ||
| 877 | |||
| 878 | bail: | ||
| 879 | return ret; | ||
| 880 | } | ||
| 881 | |||
| 882 | /* Get current link speed */ | ||
| 883 | static ssize_t show_spd(struct device *dev, | ||
| 884 | struct device_attribute *attr, | ||
| 885 | char *buf) | ||
| 886 | { | ||
| 887 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 888 | int ret; | ||
| 889 | |||
| 890 | ret = dd->ipath_f_get_ib_cfg(dd, IPATH_IB_CFG_SPD); | ||
| 891 | if (ret >= 0) | ||
| 892 | ret = scnprintf(buf, PAGE_SIZE, "%d\n", ret); | ||
| 893 | return ret; | ||
| 894 | } | ||
| 895 | |||
| 896 | /* | ||
| 897 | * Get/Set RX polarity-invert enable. 0=no, 1=yes. | ||
| 898 | */ | ||
| 899 | static ssize_t show_rx_polinv_enb(struct device *dev, | ||
| 900 | struct device_attribute *attr, | ||
| 901 | char *buf) | ||
| 902 | { | ||
| 903 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 904 | int ret; | ||
| 905 | |||
| 906 | ret = dd->ipath_f_get_ib_cfg(dd, IPATH_IB_CFG_RXPOL_ENB); | ||
| 907 | if (ret >= 0) | ||
| 908 | ret = scnprintf(buf, PAGE_SIZE, "%d\n", ret); | ||
| 909 | return ret; | ||
| 910 | } | ||
| 911 | |||
| 912 | static ssize_t store_rx_polinv_enb(struct device *dev, | ||
| 913 | struct device_attribute *attr, | ||
| 914 | const char *buf, | ||
| 915 | size_t count) | ||
| 916 | { | ||
| 917 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 918 | int ret, r; | ||
| 919 | u16 val; | ||
| 920 | |||
| 921 | ret = ipath_parse_ushort(buf, &val); | ||
| 922 | if (ret < 0 || val > 1) | ||
| 923 | goto invalid; | ||
| 924 | |||
| 925 | r = dd->ipath_f_set_ib_cfg(dd, IPATH_IB_CFG_RXPOL_ENB, val); | ||
| 926 | if (r < 0) { | ||
| 927 | ret = r; | ||
| 928 | goto bail; | ||
| 929 | } | ||
| 930 | |||
| 931 | goto bail; | ||
| 932 | invalid: | ||
| 933 | ipath_dev_err(dd, "attempt to set invalid Rx Polarity (enable)\n"); | ||
| 934 | bail: | ||
| 935 | return ret; | ||
| 936 | } | ||
| 937 | /* | ||
| 938 | * Get/Set RX lane-reversal enable. 0=no, 1=yes. | ||
| 939 | */ | ||
| 940 | static ssize_t show_lanerev_enb(struct device *dev, | ||
| 941 | struct device_attribute *attr, | ||
| 942 | char *buf) | ||
| 943 | { | ||
| 944 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 945 | int ret; | ||
| 946 | |||
| 947 | ret = dd->ipath_f_get_ib_cfg(dd, IPATH_IB_CFG_LREV_ENB); | ||
| 948 | if (ret >= 0) | ||
| 949 | ret = scnprintf(buf, PAGE_SIZE, "%d\n", ret); | ||
| 950 | return ret; | ||
| 951 | } | ||
| 952 | |||
| 953 | static ssize_t store_lanerev_enb(struct device *dev, | ||
| 954 | struct device_attribute *attr, | ||
| 955 | const char *buf, | ||
| 956 | size_t count) | ||
| 957 | { | ||
| 958 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
| 959 | int ret, r; | ||
| 960 | u16 val; | ||
| 961 | |||
| 962 | ret = ipath_parse_ushort(buf, &val); | ||
| 963 | if (ret >= 0 && val > 1) { | ||
| 964 | ret = -EINVAL; | ||
| 965 | ipath_dev_err(dd, | ||
| 966 | "attempt to set invalid Lane reversal (enable)\n"); | ||
| 967 | goto bail; | ||
| 968 | } | ||
| 969 | |||
| 970 | r = dd->ipath_f_set_ib_cfg(dd, IPATH_IB_CFG_LREV_ENB, val); | ||
| 971 | if (r < 0) | ||
| 972 | ret = r; | ||
| 973 | |||
| 974 | bail: | ||
| 975 | return ret; | ||
| 976 | } | ||
| 977 | |||
| 673 | static DRIVER_ATTR(num_units, S_IRUGO, show_num_units, NULL); | 978 | static DRIVER_ATTR(num_units, S_IRUGO, show_num_units, NULL); |
| 674 | static DRIVER_ATTR(version, S_IRUGO, show_version, NULL); | 979 | static DRIVER_ATTR(version, S_IRUGO, show_version, NULL); |
| 675 | 980 | ||
| @@ -706,6 +1011,10 @@ static DEVICE_ATTR(unit, S_IRUGO, show_unit, NULL); | |||
| 706 | static DEVICE_ATTR(rx_pol_inv, S_IWUSR, NULL, store_rx_pol_inv); | 1011 | static DEVICE_ATTR(rx_pol_inv, S_IWUSR, NULL, store_rx_pol_inv); |
| 707 | static DEVICE_ATTR(led_override, S_IWUSR, NULL, store_led_override); | 1012 | static DEVICE_ATTR(led_override, S_IWUSR, NULL, store_led_override); |
| 708 | static DEVICE_ATTR(logged_errors, S_IRUGO, show_logged_errs, NULL); | 1013 | static DEVICE_ATTR(logged_errors, S_IRUGO, show_logged_errs, NULL); |
| 1014 | static DEVICE_ATTR(jint_max_packets, S_IWUSR | S_IRUGO, | ||
| 1015 | show_jint_max_packets, store_jint_max_packets); | ||
| 1016 | static DEVICE_ATTR(jint_idle_ticks, S_IWUSR | S_IRUGO, | ||
| 1017 | show_jint_idle_ticks, store_jint_idle_ticks); | ||
| 709 | 1018 | ||
| 710 | static struct attribute *dev_attributes[] = { | 1019 | static struct attribute *dev_attributes[] = { |
| 711 | &dev_attr_guid.attr, | 1020 | &dev_attr_guid.attr, |
| @@ -732,6 +1041,34 @@ static struct attribute_group dev_attr_group = { | |||
| 732 | .attrs = dev_attributes | 1041 | .attrs = dev_attributes |
| 733 | }; | 1042 | }; |
| 734 | 1043 | ||
| 1044 | static DEVICE_ATTR(hrtbt_enable, S_IWUSR | S_IRUGO, show_hrtbt_enb, | ||
| 1045 | store_hrtbt_enb); | ||
| 1046 | static DEVICE_ATTR(link_width_enable, S_IWUSR | S_IRUGO, show_lwid_enb, | ||
| 1047 | store_lwid_enb); | ||
| 1048 | static DEVICE_ATTR(link_width, S_IRUGO, show_lwid, NULL); | ||
| 1049 | static DEVICE_ATTR(link_speed_enable, S_IWUSR | S_IRUGO, show_spd_enb, | ||
| 1050 | store_spd_enb); | ||
| 1051 | static DEVICE_ATTR(link_speed, S_IRUGO, show_spd, NULL); | ||
| 1052 | static DEVICE_ATTR(rx_pol_inv_enable, S_IWUSR | S_IRUGO, show_rx_polinv_enb, | ||
| 1053 | store_rx_polinv_enb); | ||
| 1054 | static DEVICE_ATTR(rx_lane_rev_enable, S_IWUSR | S_IRUGO, show_lanerev_enb, | ||
| 1055 | store_lanerev_enb); | ||
| 1056 | |||
| 1057 | static struct attribute *dev_ibcfg_attributes[] = { | ||
| 1058 | &dev_attr_hrtbt_enable.attr, | ||
| 1059 | &dev_attr_link_width_enable.attr, | ||
| 1060 | &dev_attr_link_width.attr, | ||
| 1061 | &dev_attr_link_speed_enable.attr, | ||
| 1062 | &dev_attr_link_speed.attr, | ||
| 1063 | &dev_attr_rx_pol_inv_enable.attr, | ||
| 1064 | &dev_attr_rx_lane_rev_enable.attr, | ||
| 1065 | NULL | ||
| 1066 | }; | ||
| 1067 | |||
| 1068 | static struct attribute_group dev_ibcfg_attr_group = { | ||
| 1069 | .attrs = dev_ibcfg_attributes | ||
| 1070 | }; | ||
| 1071 | |||
| 735 | /** | 1072 | /** |
| 736 | * ipath_expose_reset - create a device reset file | 1073 | * ipath_expose_reset - create a device reset file |
| 737 | * @dev: the device structure | 1074 | * @dev: the device structure |
| @@ -770,6 +1107,26 @@ int ipath_device_create_group(struct device *dev, struct ipath_devdata *dd) | |||
| 770 | if (ret) | 1107 | if (ret) |
| 771 | goto bail_attrs; | 1108 | goto bail_attrs; |
| 772 | 1109 | ||
| 1110 | if (dd->ipath_flags & IPATH_HAS_MULT_IB_SPEED) { | ||
| 1111 | ret = device_create_file(dev, &dev_attr_jint_idle_ticks); | ||
| 1112 | if (ret) | ||
| 1113 | goto bail_counter; | ||
| 1114 | ret = device_create_file(dev, &dev_attr_jint_max_packets); | ||
| 1115 | if (ret) | ||
| 1116 | goto bail_idle; | ||
| 1117 | |||
| 1118 | ret = sysfs_create_group(&dev->kobj, &dev_ibcfg_attr_group); | ||
| 1119 | if (ret) | ||
| 1120 | goto bail_max; | ||
| 1121 | } | ||
| 1122 | |||
| 1123 | return 0; | ||
| 1124 | |||
| 1125 | bail_max: | ||
| 1126 | device_remove_file(dev, &dev_attr_jint_max_packets); | ||
| 1127 | bail_idle: | ||
| 1128 | device_remove_file(dev, &dev_attr_jint_idle_ticks); | ||
| 1129 | bail_counter: | ||
| 773 | sysfs_remove_group(&dev->kobj, &dev_counter_attr_group); | 1130 | sysfs_remove_group(&dev->kobj, &dev_counter_attr_group); |
| 774 | bail_attrs: | 1131 | bail_attrs: |
| 775 | sysfs_remove_group(&dev->kobj, &dev_attr_group); | 1132 | sysfs_remove_group(&dev->kobj, &dev_attr_group); |
| @@ -780,6 +1137,13 @@ bail: | |||
| 780 | void ipath_device_remove_group(struct device *dev, struct ipath_devdata *dd) | 1137 | void ipath_device_remove_group(struct device *dev, struct ipath_devdata *dd) |
| 781 | { | 1138 | { |
| 782 | sysfs_remove_group(&dev->kobj, &dev_counter_attr_group); | 1139 | sysfs_remove_group(&dev->kobj, &dev_counter_attr_group); |
| 1140 | |||
| 1141 | if (dd->ipath_flags & IPATH_HAS_MULT_IB_SPEED) { | ||
| 1142 | sysfs_remove_group(&dev->kobj, &dev_ibcfg_attr_group); | ||
| 1143 | device_remove_file(dev, &dev_attr_jint_idle_ticks); | ||
| 1144 | device_remove_file(dev, &dev_attr_jint_max_packets); | ||
| 1145 | } | ||
| 1146 | |||
| 783 | sysfs_remove_group(&dev->kobj, &dev_attr_group); | 1147 | sysfs_remove_group(&dev->kobj, &dev_attr_group); |
| 784 | 1148 | ||
| 785 | device_remove_file(dev, &dev_attr_reset); | 1149 | device_remove_file(dev, &dev_attr_reset); |
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c index b3df6f3c705e..de67eed08ed0 100644 --- a/drivers/infiniband/hw/ipath/ipath_ud.c +++ b/drivers/infiniband/hw/ipath/ipath_ud.c | |||
| @@ -301,8 +301,6 @@ int ipath_make_ud_req(struct ipath_qp *qp) | |||
| 301 | 301 | ||
| 302 | /* header size in 32-bit words LRH+BTH+DETH = (8+12+8)/4. */ | 302 | /* header size in 32-bit words LRH+BTH+DETH = (8+12+8)/4. */ |
| 303 | qp->s_hdrwords = 7; | 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; | 304 | qp->s_cur_size = wqe->length; |
| 307 | qp->s_cur_sge = &qp->s_sge; | 305 | qp->s_cur_sge = &qp->s_sge; |
| 308 | qp->s_wqe = wqe; | 306 | qp->s_wqe = wqe; |
| @@ -327,6 +325,7 @@ int ipath_make_ud_req(struct ipath_qp *qp) | |||
| 327 | ohdr = &qp->s_hdr.u.oth; | 325 | ohdr = &qp->s_hdr.u.oth; |
| 328 | } | 326 | } |
| 329 | if (wqe->wr.opcode == IB_WR_SEND_WITH_IMM) { | 327 | if (wqe->wr.opcode == IB_WR_SEND_WITH_IMM) { |
| 328 | qp->s_hdrwords++; | ||
| 330 | ohdr->u.ud.imm_data = wqe->wr.imm_data; | 329 | ohdr->u.ud.imm_data = wqe->wr.imm_data; |
| 331 | bth0 = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE << 24; | 330 | bth0 = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE << 24; |
| 332 | } else | 331 | } else |
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c index c4c998446c7b..32d8f882e56c 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/drivers/infiniband/hw/ipath/ipath_verbs.c | |||
| @@ -943,7 +943,7 @@ bail: | |||
| 943 | * ipath_verbs_send - send a packet | 943 | * ipath_verbs_send - send a packet |
| 944 | * @qp: the QP to send on | 944 | * @qp: the QP to send on |
| 945 | * @hdr: the packet header | 945 | * @hdr: the packet header |
| 946 | * @hdrwords: the number of words in the header | 946 | * @hdrwords: the number of 32-bit words in the header |
| 947 | * @ss: the SGE to send | 947 | * @ss: the SGE to send |
| 948 | * @len: the length of the packet in bytes | 948 | * @len: the length of the packet in bytes |
| 949 | */ | 949 | */ |
| @@ -955,7 +955,10 @@ int ipath_verbs_send(struct ipath_qp *qp, struct ipath_ib_header *hdr, | |||
| 955 | int ret; | 955 | int ret; |
| 956 | u32 dwords = (len + 3) >> 2; | 956 | u32 dwords = (len + 3) >> 2; |
| 957 | 957 | ||
| 958 | /* +1 is for the qword padding of pbc */ | 958 | /* |
| 959 | * Calculate the send buffer trigger address. | ||
| 960 | * The +1 counts for the pbc control dword following the pbc length. | ||
| 961 | */ | ||
| 959 | plen = hdrwords + dwords + 1; | 962 | plen = hdrwords + dwords + 1; |
| 960 | 963 | ||
| 961 | /* Drop non-VL15 packets if we are not in the active state */ | 964 | /* Drop non-VL15 packets if we are not in the active state */ |
| @@ -1130,20 +1133,34 @@ static int ipath_query_device(struct ib_device *ibdev, | |||
| 1130 | return 0; | 1133 | return 0; |
| 1131 | } | 1134 | } |
| 1132 | 1135 | ||
| 1133 | const u8 ipath_cvt_physportstate[16] = { | 1136 | const u8 ipath_cvt_physportstate[32] = { |
| 1134 | [INFINIPATH_IBCS_LT_STATE_DISABLED] = 3, | 1137 | [INFINIPATH_IBCS_LT_STATE_DISABLED] = IB_PHYSPORTSTATE_DISABLED, |
| 1135 | [INFINIPATH_IBCS_LT_STATE_LINKUP] = 5, | 1138 | [INFINIPATH_IBCS_LT_STATE_LINKUP] = IB_PHYSPORTSTATE_LINKUP, |
| 1136 | [INFINIPATH_IBCS_LT_STATE_POLLACTIVE] = 2, | 1139 | [INFINIPATH_IBCS_LT_STATE_POLLACTIVE] = IB_PHYSPORTSTATE_POLL, |
| 1137 | [INFINIPATH_IBCS_LT_STATE_POLLQUIET] = 2, | 1140 | [INFINIPATH_IBCS_LT_STATE_POLLQUIET] = IB_PHYSPORTSTATE_POLL, |
| 1138 | [INFINIPATH_IBCS_LT_STATE_SLEEPDELAY] = 1, | 1141 | [INFINIPATH_IBCS_LT_STATE_SLEEPDELAY] = IB_PHYSPORTSTATE_SLEEP, |
| 1139 | [INFINIPATH_IBCS_LT_STATE_SLEEPQUIET] = 1, | 1142 | [INFINIPATH_IBCS_LT_STATE_SLEEPQUIET] = IB_PHYSPORTSTATE_SLEEP, |
| 1140 | [INFINIPATH_IBCS_LT_STATE_CFGDEBOUNCE] = 4, | 1143 | [INFINIPATH_IBCS_LT_STATE_CFGDEBOUNCE] = |
| 1141 | [INFINIPATH_IBCS_LT_STATE_CFGRCVFCFG] = 4, | 1144 | IB_PHYSPORTSTATE_CFG_TRAIN, |
| 1142 | [INFINIPATH_IBCS_LT_STATE_CFGWAITRMT] = 4, | 1145 | [INFINIPATH_IBCS_LT_STATE_CFGRCVFCFG] = |
| 1143 | [INFINIPATH_IBCS_LT_STATE_CFGIDLE] = 4, | 1146 | IB_PHYSPORTSTATE_CFG_TRAIN, |
| 1144 | [INFINIPATH_IBCS_LT_STATE_RECOVERRETRAIN] = 6, | 1147 | [INFINIPATH_IBCS_LT_STATE_CFGWAITRMT] = |
| 1145 | [INFINIPATH_IBCS_LT_STATE_RECOVERWAITRMT] = 6, | 1148 | IB_PHYSPORTSTATE_CFG_TRAIN, |
| 1146 | [INFINIPATH_IBCS_LT_STATE_RECOVERIDLE] = 6, | 1149 | [INFINIPATH_IBCS_LT_STATE_CFGIDLE] = IB_PHYSPORTSTATE_CFG_TRAIN, |
| 1150 | [INFINIPATH_IBCS_LT_STATE_RECOVERRETRAIN] = | ||
| 1151 | IB_PHYSPORTSTATE_LINK_ERR_RECOVER, | ||
| 1152 | [INFINIPATH_IBCS_LT_STATE_RECOVERWAITRMT] = | ||
| 1153 | IB_PHYSPORTSTATE_LINK_ERR_RECOVER, | ||
| 1154 | [INFINIPATH_IBCS_LT_STATE_RECOVERIDLE] = | ||
| 1155 | IB_PHYSPORTSTATE_LINK_ERR_RECOVER, | ||
| 1156 | [0x10] = IB_PHYSPORTSTATE_CFG_TRAIN, | ||
| 1157 | [0x11] = IB_PHYSPORTSTATE_CFG_TRAIN, | ||
| 1158 | [0x12] = IB_PHYSPORTSTATE_CFG_TRAIN, | ||
| 1159 | [0x13] = IB_PHYSPORTSTATE_CFG_TRAIN, | ||
| 1160 | [0x14] = IB_PHYSPORTSTATE_CFG_TRAIN, | ||
| 1161 | [0x15] = IB_PHYSPORTSTATE_CFG_TRAIN, | ||
| 1162 | [0x16] = IB_PHYSPORTSTATE_CFG_TRAIN, | ||
| 1163 | [0x17] = IB_PHYSPORTSTATE_CFG_TRAIN | ||
| 1147 | }; | 1164 | }; |
| 1148 | 1165 | ||
| 1149 | u32 ipath_get_cr_errpkey(struct ipath_devdata *dd) | 1166 | u32 ipath_get_cr_errpkey(struct ipath_devdata *dd) |
| @@ -1168,8 +1185,9 @@ static int ipath_query_port(struct ib_device *ibdev, | |||
| 1168 | ibcstat = dd->ipath_lastibcstat; | 1185 | ibcstat = dd->ipath_lastibcstat; |
| 1169 | props->state = ((ibcstat >> 4) & 0x3) + 1; | 1186 | props->state = ((ibcstat >> 4) & 0x3) + 1; |
| 1170 | /* See phys_state_show() */ | 1187 | /* See phys_state_show() */ |
| 1171 | props->phys_state = ipath_cvt_physportstate[ | 1188 | props->phys_state = /* MEA: assumes shift == 0 */ |
| 1172 | dd->ipath_lastibcstat & 0xf]; | 1189 | ipath_cvt_physportstate[dd->ipath_lastibcstat & |
| 1190 | dd->ibcs_lts_mask]; | ||
| 1173 | props->port_cap_flags = dev->port_cap_flags; | 1191 | props->port_cap_flags = dev->port_cap_flags; |
| 1174 | props->gid_tbl_len = 1; | 1192 | props->gid_tbl_len = 1; |
| 1175 | props->max_msg_sz = 0x80000000; | 1193 | props->max_msg_sz = 0x80000000; |
| @@ -1641,6 +1659,7 @@ int ipath_register_ib_device(struct ipath_devdata *dd) | |||
| 1641 | cntrs.local_link_integrity_errors; | 1659 | cntrs.local_link_integrity_errors; |
| 1642 | idev->z_excessive_buffer_overrun_errors = | 1660 | idev->z_excessive_buffer_overrun_errors = |
| 1643 | cntrs.excessive_buffer_overrun_errors; | 1661 | cntrs.excessive_buffer_overrun_errors; |
| 1662 | idev->z_vl15_dropped = cntrs.vl15_dropped; | ||
| 1644 | 1663 | ||
| 1645 | /* | 1664 | /* |
| 1646 | * The system image GUID is supposed to be the same for all | 1665 | * The system image GUID is supposed to be the same for all |
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h index 6ccb54f104a3..3d59736b49b2 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.h +++ b/drivers/infiniband/hw/ipath/ipath_verbs.h | |||
| @@ -554,6 +554,7 @@ struct ipath_ibdev { | |||
| 554 | u32 z_pkey_violations; /* starting count for PMA */ | 554 | u32 z_pkey_violations; /* starting count for PMA */ |
| 555 | u32 z_local_link_integrity_errors; /* starting count for PMA */ | 555 | u32 z_local_link_integrity_errors; /* starting count for PMA */ |
| 556 | u32 z_excessive_buffer_overrun_errors; /* starting count for PMA */ | 556 | u32 z_excessive_buffer_overrun_errors; /* starting count for PMA */ |
| 557 | u32 z_vl15_dropped; /* starting count for PMA */ | ||
| 557 | u32 n_rc_resends; | 558 | u32 n_rc_resends; |
| 558 | u32 n_rc_acks; | 559 | u32 n_rc_acks; |
| 559 | u32 n_rc_qacks; | 560 | u32 n_rc_qacks; |
| @@ -598,6 +599,7 @@ struct ipath_verbs_counters { | |||
| 598 | u64 port_rcv_packets; | 599 | u64 port_rcv_packets; |
| 599 | u32 local_link_integrity_errors; | 600 | u32 local_link_integrity_errors; |
| 600 | u32 excessive_buffer_overrun_errors; | 601 | u32 excessive_buffer_overrun_errors; |
| 602 | u32 vl15_dropped; | ||
| 601 | }; | 603 | }; |
| 602 | 604 | ||
| 603 | static inline struct ipath_mr *to_imr(struct ib_mr *ibmr) | 605 | static inline struct ipath_mr *to_imr(struct ib_mr *ibmr) |
| @@ -830,7 +832,17 @@ unsigned ipath_get_pkey(struct ipath_devdata *, unsigned); | |||
| 830 | 832 | ||
| 831 | extern const enum ib_wc_opcode ib_ipath_wc_opcode[]; | 833 | extern const enum ib_wc_opcode ib_ipath_wc_opcode[]; |
| 832 | 834 | ||
| 835 | /* | ||
| 836 | * Below converts HCA-specific LinkTrainingState to IB PhysPortState | ||
| 837 | * values. | ||
| 838 | */ | ||
| 833 | extern const u8 ipath_cvt_physportstate[]; | 839 | extern const u8 ipath_cvt_physportstate[]; |
| 840 | #define IB_PHYSPORTSTATE_SLEEP 1 | ||
| 841 | #define IB_PHYSPORTSTATE_POLL 2 | ||
| 842 | #define IB_PHYSPORTSTATE_DISABLED 3 | ||
| 843 | #define IB_PHYSPORTSTATE_CFG_TRAIN 4 | ||
| 844 | #define IB_PHYSPORTSTATE_LINKUP 5 | ||
| 845 | #define IB_PHYSPORTSTATE_LINK_ERR_RECOVER 6 | ||
| 834 | 846 | ||
| 835 | extern const int ib_ipath_state_ops[]; | 847 | extern const int ib_ipath_state_ops[]; |
| 836 | 848 | ||
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c index 9d32c49cc651..7950aa6e8184 100644 --- a/drivers/infiniband/hw/mlx4/cq.c +++ b/drivers/infiniband/hw/mlx4/cq.c | |||
| @@ -313,6 +313,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq, | |||
| 313 | struct mlx4_ib_srq *srq; | 313 | struct mlx4_ib_srq *srq; |
| 314 | int is_send; | 314 | int is_send; |
| 315 | int is_error; | 315 | int is_error; |
| 316 | u32 g_mlpath_rqpn; | ||
| 316 | u16 wqe_ctr; | 317 | u16 wqe_ctr; |
| 317 | 318 | ||
| 318 | cqe = next_cqe_sw(cq); | 319 | cqe = next_cqe_sw(cq); |
| @@ -426,10 +427,10 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq, | |||
| 426 | 427 | ||
| 427 | wc->slid = be16_to_cpu(cqe->rlid); | 428 | wc->slid = be16_to_cpu(cqe->rlid); |
| 428 | wc->sl = cqe->sl >> 4; | 429 | wc->sl = cqe->sl >> 4; |
| 429 | wc->src_qp = be32_to_cpu(cqe->g_mlpath_rqpn) & 0xffffff; | 430 | g_mlpath_rqpn = be32_to_cpu(cqe->g_mlpath_rqpn); |
| 430 | wc->dlid_path_bits = (be32_to_cpu(cqe->g_mlpath_rqpn) >> 24) & 0x7f; | 431 | wc->src_qp = g_mlpath_rqpn & 0xffffff; |
| 431 | wc->wc_flags |= be32_to_cpu(cqe->g_mlpath_rqpn) & 0x80000000 ? | 432 | wc->dlid_path_bits = (g_mlpath_rqpn >> 24) & 0x7f; |
| 432 | IB_WC_GRH : 0; | 433 | wc->wc_flags |= g_mlpath_rqpn & 0x80000000 ? IB_WC_GRH : 0; |
| 433 | wc->pkey_index = be32_to_cpu(cqe->immed_rss_invalid) & 0x7f; | 434 | wc->pkey_index = be32_to_cpu(cqe->immed_rss_invalid) & 0x7f; |
| 434 | } | 435 | } |
| 435 | 436 | ||
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index 15aa32eb78b6..7bbdd1f4e6c7 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h | |||
| @@ -60,13 +60,12 @@ | |||
| 60 | enum { | 60 | enum { |
| 61 | MTHCA_FLAG_DDR_HIDDEN = 1 << 1, | 61 | MTHCA_FLAG_DDR_HIDDEN = 1 << 1, |
| 62 | MTHCA_FLAG_SRQ = 1 << 2, | 62 | MTHCA_FLAG_SRQ = 1 << 2, |
| 63 | MTHCA_FLAG_MSI = 1 << 3, | 63 | MTHCA_FLAG_MSI_X = 1 << 3, |
| 64 | MTHCA_FLAG_MSI_X = 1 << 4, | 64 | MTHCA_FLAG_NO_LAM = 1 << 4, |
| 65 | MTHCA_FLAG_NO_LAM = 1 << 5, | 65 | MTHCA_FLAG_FMR = 1 << 5, |
| 66 | MTHCA_FLAG_FMR = 1 << 6, | 66 | MTHCA_FLAG_MEMFREE = 1 << 6, |
| 67 | MTHCA_FLAG_MEMFREE = 1 << 7, | 67 | MTHCA_FLAG_PCIE = 1 << 7, |
| 68 | MTHCA_FLAG_PCIE = 1 << 8, | 68 | MTHCA_FLAG_SINAI_OPT = 1 << 8 |
| 69 | MTHCA_FLAG_SINAI_OPT = 1 << 9 | ||
| 70 | }; | 69 | }; |
| 71 | 70 | ||
| 72 | enum { | 71 | enum { |
diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c index b29de51b7f35..b60eb5df96e8 100644 --- a/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/drivers/infiniband/hw/mthca/mthca_eq.c | |||
| @@ -827,8 +827,7 @@ int mthca_init_eq_table(struct mthca_dev *dev) | |||
| 827 | if (err) | 827 | if (err) |
| 828 | goto err_out_free; | 828 | goto err_out_free; |
| 829 | 829 | ||
| 830 | if (dev->mthca_flags & MTHCA_FLAG_MSI || | 830 | if (dev->mthca_flags & MTHCA_FLAG_MSI_X) { |
| 831 | dev->mthca_flags & MTHCA_FLAG_MSI_X) { | ||
| 832 | dev->eq_table.clr_mask = 0; | 831 | dev->eq_table.clr_mask = 0; |
| 833 | } else { | 832 | } else { |
| 834 | dev->eq_table.clr_mask = | 833 | dev->eq_table.clr_mask = |
| @@ -839,8 +838,7 @@ int mthca_init_eq_table(struct mthca_dev *dev) | |||
| 839 | 838 | ||
| 840 | dev->eq_table.arm_mask = 0; | 839 | dev->eq_table.arm_mask = 0; |
| 841 | 840 | ||
| 842 | intr = (dev->mthca_flags & MTHCA_FLAG_MSI) ? | 841 | intr = dev->eq_table.inta_pin; |
| 843 | 128 : dev->eq_table.inta_pin; | ||
| 844 | 842 | ||
| 845 | err = mthca_create_eq(dev, dev->limits.num_cqs + MTHCA_NUM_SPARE_EQE, | 843 | err = mthca_create_eq(dev, dev->limits.num_cqs + MTHCA_NUM_SPARE_EQE, |
| 846 | (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 128 : intr, | 844 | (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 128 : intr, |
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 60de6f93869e..5cf8250d4e16 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c | |||
| @@ -65,14 +65,9 @@ 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 | ||
| 68 | static int msi = 0; | ||
| 69 | module_param(msi, int, 0444); | ||
| 70 | MODULE_PARM_DESC(msi, "attempt to use MSI if nonzero (deprecated, use MSI-X instead)"); | ||
| 71 | |||
| 72 | #else /* CONFIG_PCI_MSI */ | 68 | #else /* CONFIG_PCI_MSI */ |
| 73 | 69 | ||
| 74 | #define msi_x (0) | 70 | #define msi_x (0) |
| 75 | #define msi (0) | ||
| 76 | 71 | ||
| 77 | #endif /* CONFIG_PCI_MSI */ | 72 | #endif /* CONFIG_PCI_MSI */ |
| 78 | 73 | ||
| @@ -816,13 +811,11 @@ static int mthca_setup_hca(struct mthca_dev *dev) | |||
| 816 | 811 | ||
| 817 | err = mthca_NOP(dev, &status); | 812 | err = mthca_NOP(dev, &status); |
| 818 | if (err || status) { | 813 | if (err || status) { |
| 819 | if (dev->mthca_flags & (MTHCA_FLAG_MSI | MTHCA_FLAG_MSI_X)) { | 814 | if (dev->mthca_flags & MTHCA_FLAG_MSI_X) { |
| 820 | mthca_warn(dev, "NOP command failed to generate interrupt " | 815 | mthca_warn(dev, "NOP command failed to generate interrupt " |
| 821 | "(IRQ %d).\n", | 816 | "(IRQ %d).\n", |
| 822 | dev->mthca_flags & MTHCA_FLAG_MSI_X ? | 817 | dev->eq_table.eq[MTHCA_EQ_CMD].msi_x_vector); |
| 823 | dev->eq_table.eq[MTHCA_EQ_CMD].msi_x_vector : | 818 | mthca_warn(dev, "Trying again with MSI-X disabled.\n"); |
| 824 | dev->pdev->irq); | ||
| 825 | mthca_warn(dev, "Trying again with MSI/MSI-X disabled.\n"); | ||
| 826 | } else { | 819 | } else { |
| 827 | mthca_err(dev, "NOP command failed to generate interrupt " | 820 | mthca_err(dev, "NOP command failed to generate interrupt " |
| 828 | "(IRQ %d), aborting.\n", | 821 | "(IRQ %d), aborting.\n", |
| @@ -1005,7 +998,7 @@ static struct { | |||
| 1005 | .flags = 0 }, | 998 | .flags = 0 }, |
| 1006 | [ARBEL_COMPAT] = { .latest_fw = MTHCA_FW_VER(4, 8, 200), | 999 | [ARBEL_COMPAT] = { .latest_fw = MTHCA_FW_VER(4, 8, 200), |
| 1007 | .flags = MTHCA_FLAG_PCIE }, | 1000 | .flags = MTHCA_FLAG_PCIE }, |
| 1008 | [ARBEL_NATIVE] = { .latest_fw = MTHCA_FW_VER(5, 2, 0), | 1001 | [ARBEL_NATIVE] = { .latest_fw = MTHCA_FW_VER(5, 3, 0), |
| 1009 | .flags = MTHCA_FLAG_MEMFREE | | 1002 | .flags = MTHCA_FLAG_MEMFREE | |
| 1010 | MTHCA_FLAG_PCIE }, | 1003 | MTHCA_FLAG_PCIE }, |
| 1011 | [SINAI] = { .latest_fw = MTHCA_FW_VER(1, 2, 0), | 1004 | [SINAI] = { .latest_fw = MTHCA_FW_VER(1, 2, 0), |
| @@ -1128,29 +1121,12 @@ static int __mthca_init_one(struct pci_dev *pdev, int hca_type) | |||
| 1128 | 1121 | ||
| 1129 | if (msi_x && !mthca_enable_msi_x(mdev)) | 1122 | if (msi_x && !mthca_enable_msi_x(mdev)) |
| 1130 | mdev->mthca_flags |= MTHCA_FLAG_MSI_X; | 1123 | 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 | 1124 | ||
| 1147 | err = mthca_setup_hca(mdev); | 1125 | err = mthca_setup_hca(mdev); |
| 1148 | if (err == -EBUSY && (mdev->mthca_flags & (MTHCA_FLAG_MSI | MTHCA_FLAG_MSI_X))) { | 1126 | if (err == -EBUSY && (mdev->mthca_flags & MTHCA_FLAG_MSI_X)) { |
| 1149 | if (mdev->mthca_flags & MTHCA_FLAG_MSI_X) | 1127 | if (mdev->mthca_flags & MTHCA_FLAG_MSI_X) |
| 1150 | pci_disable_msix(pdev); | 1128 | pci_disable_msix(pdev); |
| 1151 | if (mdev->mthca_flags & MTHCA_FLAG_MSI) | 1129 | mdev->mthca_flags &= ~MTHCA_FLAG_MSI_X; |
| 1152 | pci_disable_msi(pdev); | ||
| 1153 | mdev->mthca_flags &= ~(MTHCA_FLAG_MSI_X | MTHCA_FLAG_MSI); | ||
| 1154 | 1130 | ||
| 1155 | err = mthca_setup_hca(mdev); | 1131 | err = mthca_setup_hca(mdev); |
| 1156 | } | 1132 | } |
| @@ -1192,8 +1168,6 @@ err_cleanup: | |||
| 1192 | err_close: | 1168 | err_close: |
| 1193 | if (mdev->mthca_flags & MTHCA_FLAG_MSI_X) | 1169 | if (mdev->mthca_flags & MTHCA_FLAG_MSI_X) |
| 1194 | pci_disable_msix(pdev); | 1170 | pci_disable_msix(pdev); |
| 1195 | if (mdev->mthca_flags & MTHCA_FLAG_MSI) | ||
| 1196 | pci_disable_msi(pdev); | ||
| 1197 | 1171 | ||
| 1198 | mthca_close_hca(mdev); | 1172 | mthca_close_hca(mdev); |
| 1199 | 1173 | ||
| @@ -1246,8 +1220,6 @@ static void __mthca_remove_one(struct pci_dev *pdev) | |||
| 1246 | 1220 | ||
| 1247 | if (mdev->mthca_flags & MTHCA_FLAG_MSI_X) | 1221 | if (mdev->mthca_flags & MTHCA_FLAG_MSI_X) |
| 1248 | pci_disable_msix(pdev); | 1222 | pci_disable_msix(pdev); |
| 1249 | if (mdev->mthca_flags & MTHCA_FLAG_MSI) | ||
| 1250 | pci_disable_msi(pdev); | ||
| 1251 | 1223 | ||
| 1252 | ib_dealloc_device(&mdev->ib_dev); | 1224 | ib_dealloc_device(&mdev->ib_dev); |
| 1253 | mthca_release_regions(pdev, mdev->mthca_flags & | 1225 | mthca_release_regions(pdev, mdev->mthca_flags & |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index eb7edab0e836..fe250c60607d 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
| @@ -56,42 +56,43 @@ | |||
| 56 | /* constants */ | 56 | /* constants */ |
| 57 | 57 | ||
| 58 | enum { | 58 | enum { |
| 59 | IPOIB_PACKET_SIZE = 2048, | 59 | IPOIB_PACKET_SIZE = 2048, |
| 60 | IPOIB_BUF_SIZE = IPOIB_PACKET_SIZE + IB_GRH_BYTES, | 60 | IPOIB_BUF_SIZE = IPOIB_PACKET_SIZE + IB_GRH_BYTES, |
| 61 | 61 | ||
| 62 | IPOIB_ENCAP_LEN = 4, | 62 | IPOIB_ENCAP_LEN = 4, |
| 63 | 63 | ||
| 64 | IPOIB_CM_MTU = 0x10000 - 0x10, /* padding to align header to 16 */ | 64 | IPOIB_CM_MTU = 0x10000 - 0x10, /* padding to align header to 16 */ |
| 65 | IPOIB_CM_BUF_SIZE = IPOIB_CM_MTU + IPOIB_ENCAP_LEN, | 65 | IPOIB_CM_BUF_SIZE = IPOIB_CM_MTU + IPOIB_ENCAP_LEN, |
| 66 | IPOIB_CM_HEAD_SIZE = IPOIB_CM_BUF_SIZE % PAGE_SIZE, | 66 | IPOIB_CM_HEAD_SIZE = IPOIB_CM_BUF_SIZE % PAGE_SIZE, |
| 67 | IPOIB_CM_RX_SG = ALIGN(IPOIB_CM_BUF_SIZE, PAGE_SIZE) / PAGE_SIZE, | 67 | IPOIB_CM_RX_SG = ALIGN(IPOIB_CM_BUF_SIZE, PAGE_SIZE) / PAGE_SIZE, |
| 68 | IPOIB_RX_RING_SIZE = 128, | 68 | IPOIB_RX_RING_SIZE = 128, |
| 69 | IPOIB_TX_RING_SIZE = 64, | 69 | IPOIB_TX_RING_SIZE = 64, |
| 70 | IPOIB_MAX_QUEUE_SIZE = 8192, | 70 | IPOIB_MAX_QUEUE_SIZE = 8192, |
| 71 | IPOIB_MIN_QUEUE_SIZE = 2, | 71 | IPOIB_MIN_QUEUE_SIZE = 2, |
| 72 | IPOIB_CM_MAX_CONN_QP = 4096, | ||
| 72 | 73 | ||
| 73 | IPOIB_NUM_WC = 4, | 74 | IPOIB_NUM_WC = 4, |
| 74 | 75 | ||
| 75 | IPOIB_MAX_PATH_REC_QUEUE = 3, | 76 | IPOIB_MAX_PATH_REC_QUEUE = 3, |
| 76 | IPOIB_MAX_MCAST_QUEUE = 3, | 77 | IPOIB_MAX_MCAST_QUEUE = 3, |
| 77 | 78 | ||
| 78 | IPOIB_FLAG_OPER_UP = 0, | 79 | IPOIB_FLAG_OPER_UP = 0, |
| 79 | IPOIB_FLAG_INITIALIZED = 1, | 80 | IPOIB_FLAG_INITIALIZED = 1, |
| 80 | IPOIB_FLAG_ADMIN_UP = 2, | 81 | IPOIB_FLAG_ADMIN_UP = 2, |
| 81 | IPOIB_PKEY_ASSIGNED = 3, | 82 | IPOIB_PKEY_ASSIGNED = 3, |
| 82 | IPOIB_PKEY_STOP = 4, | 83 | IPOIB_PKEY_STOP = 4, |
| 83 | IPOIB_FLAG_SUBINTERFACE = 5, | 84 | IPOIB_FLAG_SUBINTERFACE = 5, |
| 84 | IPOIB_MCAST_RUN = 6, | 85 | IPOIB_MCAST_RUN = 6, |
| 85 | IPOIB_STOP_REAPER = 7, | 86 | IPOIB_STOP_REAPER = 7, |
| 86 | IPOIB_MCAST_STARTED = 8, | 87 | IPOIB_MCAST_STARTED = 8, |
| 87 | IPOIB_FLAG_ADMIN_CM = 9, | 88 | IPOIB_FLAG_ADMIN_CM = 9, |
| 88 | IPOIB_FLAG_UMCAST = 10, | 89 | IPOIB_FLAG_UMCAST = 10, |
| 89 | 90 | ||
| 90 | IPOIB_MAX_BACKOFF_SECONDS = 16, | 91 | IPOIB_MAX_BACKOFF_SECONDS = 16, |
| 91 | 92 | ||
| 92 | IPOIB_MCAST_FLAG_FOUND = 0, /* used in set_multicast_list */ | 93 | IPOIB_MCAST_FLAG_FOUND = 0, /* used in set_multicast_list */ |
| 93 | IPOIB_MCAST_FLAG_SENDONLY = 1, | 94 | IPOIB_MCAST_FLAG_SENDONLY = 1, |
| 94 | IPOIB_MCAST_FLAG_BUSY = 2, /* joining or already joined */ | 95 | IPOIB_MCAST_FLAG_BUSY = 2, /* joining or already joined */ |
| 95 | IPOIB_MCAST_FLAG_ATTACHED = 3, | 96 | IPOIB_MCAST_FLAG_ATTACHED = 3, |
| 96 | }; | 97 | }; |
| 97 | 98 | ||
| @@ -117,7 +118,7 @@ struct ipoib_pseudoheader { | |||
| 117 | struct ipoib_mcast { | 118 | struct ipoib_mcast { |
| 118 | struct ib_sa_mcmember_rec mcmember; | 119 | struct ib_sa_mcmember_rec mcmember; |
| 119 | struct ib_sa_multicast *mc; | 120 | struct ib_sa_multicast *mc; |
| 120 | struct ipoib_ah *ah; | 121 | struct ipoib_ah *ah; |
| 121 | 122 | ||
| 122 | struct rb_node rb_node; | 123 | struct rb_node rb_node; |
| 123 | struct list_head list; | 124 | struct list_head list; |
| @@ -186,27 +187,29 @@ enum ipoib_cm_state { | |||
| 186 | }; | 187 | }; |
| 187 | 188 | ||
| 188 | struct ipoib_cm_rx { | 189 | struct ipoib_cm_rx { |
| 189 | struct ib_cm_id *id; | 190 | struct ib_cm_id *id; |
| 190 | struct ib_qp *qp; | 191 | struct ib_qp *qp; |
| 191 | struct list_head list; | 192 | struct ipoib_cm_rx_buf *rx_ring; |
| 192 | struct net_device *dev; | 193 | struct list_head list; |
| 193 | unsigned long jiffies; | 194 | struct net_device *dev; |
| 194 | enum ipoib_cm_state state; | 195 | unsigned long jiffies; |
| 196 | enum ipoib_cm_state state; | ||
| 197 | int recv_count; | ||
| 195 | }; | 198 | }; |
| 196 | 199 | ||
| 197 | struct ipoib_cm_tx { | 200 | struct ipoib_cm_tx { |
| 198 | struct ib_cm_id *id; | 201 | struct ib_cm_id *id; |
| 199 | struct ib_qp *qp; | 202 | struct ib_qp *qp; |
| 200 | struct list_head list; | 203 | struct list_head list; |
| 201 | struct net_device *dev; | 204 | struct net_device *dev; |
| 202 | struct ipoib_neigh *neigh; | 205 | struct ipoib_neigh *neigh; |
| 203 | struct ipoib_path *path; | 206 | struct ipoib_path *path; |
| 204 | struct ipoib_tx_buf *tx_ring; | 207 | struct ipoib_tx_buf *tx_ring; |
| 205 | unsigned tx_head; | 208 | unsigned tx_head; |
| 206 | unsigned tx_tail; | 209 | unsigned tx_tail; |
| 207 | unsigned long flags; | 210 | unsigned long flags; |
| 208 | u32 mtu; | 211 | u32 mtu; |
| 209 | struct ib_wc ibwc[IPOIB_NUM_WC]; | 212 | struct ib_wc ibwc[IPOIB_NUM_WC]; |
| 210 | }; | 213 | }; |
| 211 | 214 | ||
| 212 | struct ipoib_cm_rx_buf { | 215 | struct ipoib_cm_rx_buf { |
| @@ -215,25 +218,28 @@ struct ipoib_cm_rx_buf { | |||
| 215 | }; | 218 | }; |
| 216 | 219 | ||
| 217 | struct ipoib_cm_dev_priv { | 220 | struct ipoib_cm_dev_priv { |
| 218 | struct ib_srq *srq; | 221 | struct ib_srq *srq; |
| 219 | struct ipoib_cm_rx_buf *srq_ring; | 222 | struct ipoib_cm_rx_buf *srq_ring; |
| 220 | struct ib_cm_id *id; | 223 | struct ib_cm_id *id; |
| 221 | struct list_head passive_ids; /* state: LIVE */ | 224 | struct list_head passive_ids; /* state: LIVE */ |
| 222 | struct list_head rx_error_list; /* state: ERROR */ | 225 | struct list_head rx_error_list; /* state: ERROR */ |
| 223 | struct list_head rx_flush_list; /* state: FLUSH, drain not started */ | 226 | struct list_head rx_flush_list; /* state: FLUSH, drain not started */ |
| 224 | struct list_head rx_drain_list; /* state: FLUSH, drain started */ | 227 | struct list_head rx_drain_list; /* state: FLUSH, drain started */ |
| 225 | struct list_head rx_reap_list; /* state: FLUSH, drain done */ | 228 | struct list_head rx_reap_list; /* state: FLUSH, drain done */ |
| 226 | struct work_struct start_task; | 229 | struct work_struct start_task; |
| 227 | struct work_struct reap_task; | 230 | struct work_struct reap_task; |
| 228 | struct work_struct skb_task; | 231 | struct work_struct skb_task; |
| 229 | struct work_struct rx_reap_task; | 232 | struct work_struct rx_reap_task; |
| 230 | struct delayed_work stale_task; | 233 | struct delayed_work stale_task; |
| 231 | struct sk_buff_head skb_queue; | 234 | struct sk_buff_head skb_queue; |
| 232 | struct list_head start_list; | 235 | struct list_head start_list; |
| 233 | struct list_head reap_list; | 236 | struct list_head reap_list; |
| 234 | struct ib_wc ibwc[IPOIB_NUM_WC]; | 237 | struct ib_wc ibwc[IPOIB_NUM_WC]; |
| 235 | struct ib_sge rx_sge[IPOIB_CM_RX_SG]; | 238 | struct ib_sge rx_sge[IPOIB_CM_RX_SG]; |
| 236 | struct ib_recv_wr rx_wr; | 239 | struct ib_recv_wr rx_wr; |
| 240 | int nonsrq_conn_qp; | ||
| 241 | int max_cm_mtu; | ||
| 242 | int num_frags; | ||
| 237 | }; | 243 | }; |
| 238 | 244 | ||
| 239 | /* | 245 | /* |
| @@ -269,30 +275,30 @@ struct ipoib_dev_priv { | |||
| 269 | struct work_struct pkey_event_task; | 275 | struct work_struct pkey_event_task; |
| 270 | 276 | ||
| 271 | struct ib_device *ca; | 277 | struct ib_device *ca; |
| 272 | u8 port; | 278 | u8 port; |
| 273 | u16 pkey; | 279 | u16 pkey; |
| 274 | u16 pkey_index; | 280 | u16 pkey_index; |
| 275 | struct ib_pd *pd; | 281 | struct ib_pd *pd; |
| 276 | struct ib_mr *mr; | 282 | struct ib_mr *mr; |
| 277 | struct ib_cq *cq; | 283 | struct ib_cq *cq; |
| 278 | struct ib_qp *qp; | 284 | struct ib_qp *qp; |
| 279 | u32 qkey; | 285 | u32 qkey; |
| 280 | 286 | ||
| 281 | union ib_gid local_gid; | 287 | union ib_gid local_gid; |
| 282 | u16 local_lid; | 288 | u16 local_lid; |
| 283 | 289 | ||
| 284 | unsigned int admin_mtu; | 290 | unsigned int admin_mtu; |
| 285 | unsigned int mcast_mtu; | 291 | unsigned int mcast_mtu; |
| 286 | 292 | ||
| 287 | struct ipoib_rx_buf *rx_ring; | 293 | struct ipoib_rx_buf *rx_ring; |
| 288 | 294 | ||
| 289 | spinlock_t tx_lock; | 295 | spinlock_t tx_lock; |
| 290 | struct ipoib_tx_buf *tx_ring; | 296 | struct ipoib_tx_buf *tx_ring; |
| 291 | unsigned tx_head; | 297 | unsigned tx_head; |
| 292 | unsigned tx_tail; | 298 | unsigned tx_tail; |
| 293 | struct ib_sge tx_sge; | 299 | struct ib_sge tx_sge; |
| 294 | struct ib_send_wr tx_wr; | 300 | struct ib_send_wr tx_wr; |
| 295 | unsigned tx_outstanding; | 301 | unsigned tx_outstanding; |
| 296 | 302 | ||
| 297 | struct ib_wc ibwc[IPOIB_NUM_WC]; | 303 | struct ib_wc ibwc[IPOIB_NUM_WC]; |
| 298 | 304 | ||
| @@ -317,10 +323,10 @@ struct ipoib_dev_priv { | |||
| 317 | 323 | ||
| 318 | struct ipoib_ah { | 324 | struct ipoib_ah { |
| 319 | struct net_device *dev; | 325 | struct net_device *dev; |
| 320 | struct ib_ah *ah; | 326 | struct ib_ah *ah; |
| 321 | struct list_head list; | 327 | struct list_head list; |
| 322 | struct kref ref; | 328 | struct kref ref; |
| 323 | unsigned last_send; | 329 | unsigned last_send; |
| 324 | }; | 330 | }; |
| 325 | 331 | ||
| 326 | struct ipoib_path { | 332 | struct ipoib_path { |
| @@ -331,11 +337,11 @@ struct ipoib_path { | |||
| 331 | 337 | ||
| 332 | struct list_head neigh_list; | 338 | struct list_head neigh_list; |
| 333 | 339 | ||
| 334 | int query_id; | 340 | int query_id; |
| 335 | struct ib_sa_query *query; | 341 | struct ib_sa_query *query; |
| 336 | struct completion done; | 342 | struct completion done; |
| 337 | 343 | ||
| 338 | struct rb_node rb_node; | 344 | struct rb_node rb_node; |
| 339 | struct list_head list; | 345 | struct list_head list; |
| 340 | }; | 346 | }; |
| 341 | 347 | ||
| @@ -344,7 +350,7 @@ struct ipoib_neigh { | |||
| 344 | #ifdef CONFIG_INFINIBAND_IPOIB_CM | 350 | #ifdef CONFIG_INFINIBAND_IPOIB_CM |
| 345 | struct ipoib_cm_tx *cm; | 351 | struct ipoib_cm_tx *cm; |
| 346 | #endif | 352 | #endif |
| 347 | union ib_gid dgid; | 353 | union ib_gid dgid; |
| 348 | struct sk_buff_head queue; | 354 | struct sk_buff_head queue; |
| 349 | 355 | ||
| 350 | struct neighbour *neighbour; | 356 | struct neighbour *neighbour; |
| @@ -455,12 +461,14 @@ void ipoib_drain_cq(struct net_device *dev); | |||
| 455 | 461 | ||
| 456 | #ifdef CONFIG_INFINIBAND_IPOIB_CM | 462 | #ifdef CONFIG_INFINIBAND_IPOIB_CM |
| 457 | 463 | ||
| 458 | #define IPOIB_FLAGS_RC 0x80 | 464 | #define IPOIB_FLAGS_RC 0x80 |
| 459 | #define IPOIB_FLAGS_UC 0x40 | 465 | #define IPOIB_FLAGS_UC 0x40 |
| 460 | 466 | ||
| 461 | /* We don't support UC connections at the moment */ | 467 | /* We don't support UC connections at the moment */ |
| 462 | #define IPOIB_CM_SUPPORTED(ha) (ha[0] & (IPOIB_FLAGS_RC)) | 468 | #define IPOIB_CM_SUPPORTED(ha) (ha[0] & (IPOIB_FLAGS_RC)) |
| 463 | 469 | ||
| 470 | extern int ipoib_max_conn_qp; | ||
| 471 | |||
| 464 | static inline int ipoib_cm_admin_enabled(struct net_device *dev) | 472 | static inline int ipoib_cm_admin_enabled(struct net_device *dev) |
| 465 | { | 473 | { |
| 466 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 474 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| @@ -491,6 +499,18 @@ static inline void ipoib_cm_set(struct ipoib_neigh *neigh, struct ipoib_cm_tx *t | |||
| 491 | neigh->cm = tx; | 499 | neigh->cm = tx; |
| 492 | } | 500 | } |
| 493 | 501 | ||
| 502 | static inline int ipoib_cm_has_srq(struct net_device *dev) | ||
| 503 | { | ||
| 504 | struct ipoib_dev_priv *priv = netdev_priv(dev); | ||
| 505 | return !!priv->cm.srq; | ||
| 506 | } | ||
| 507 | |||
| 508 | static inline unsigned int ipoib_cm_max_mtu(struct net_device *dev) | ||
| 509 | { | ||
| 510 | struct ipoib_dev_priv *priv = netdev_priv(dev); | ||
| 511 | return priv->cm.max_cm_mtu; | ||
| 512 | } | ||
| 513 | |||
| 494 | void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_tx *tx); | 514 | void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_tx *tx); |
| 495 | int ipoib_cm_dev_open(struct net_device *dev); | 515 | int ipoib_cm_dev_open(struct net_device *dev); |
| 496 | void ipoib_cm_dev_stop(struct net_device *dev); | 516 | void ipoib_cm_dev_stop(struct net_device *dev); |
| @@ -500,7 +520,7 @@ void ipoib_cm_dev_cleanup(struct net_device *dev); | |||
| 500 | struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path *path, | 520 | struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path *path, |
| 501 | struct ipoib_neigh *neigh); | 521 | struct ipoib_neigh *neigh); |
| 502 | void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx); | 522 | void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx); |
| 503 | void ipoib_cm_skb_too_long(struct net_device* dev, struct sk_buff *skb, | 523 | void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb, |
| 504 | unsigned int mtu); | 524 | unsigned int mtu); |
| 505 | void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc); | 525 | void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc); |
| 506 | void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc); | 526 | void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc); |
| @@ -508,6 +528,8 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc); | |||
| 508 | 528 | ||
| 509 | struct ipoib_cm_tx; | 529 | struct ipoib_cm_tx; |
| 510 | 530 | ||
| 531 | #define ipoib_max_conn_qp 0 | ||
| 532 | |||
| 511 | static inline int ipoib_cm_admin_enabled(struct net_device *dev) | 533 | static inline int ipoib_cm_admin_enabled(struct net_device *dev) |
| 512 | { | 534 | { |
| 513 | return 0; | 535 | return 0; |
| @@ -533,6 +555,16 @@ static inline void ipoib_cm_set(struct ipoib_neigh *neigh, struct ipoib_cm_tx *t | |||
| 533 | { | 555 | { |
| 534 | } | 556 | } |
| 535 | 557 | ||
| 558 | static inline int ipoib_cm_has_srq(struct net_device *dev) | ||
| 559 | { | ||
| 560 | return 0; | ||
| 561 | } | ||
| 562 | |||
| 563 | static inline unsigned int ipoib_cm_max_mtu(struct net_device *dev) | ||
| 564 | { | ||
| 565 | return 0; | ||
| 566 | } | ||
| 567 | |||
| 536 | static inline | 568 | static inline |
| 537 | void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_tx *tx) | 569 | void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_tx *tx) |
| 538 | { | 570 | { |
| @@ -582,7 +614,7 @@ int ipoib_cm_add_mode_attr(struct net_device *dev) | |||
| 582 | return 0; | 614 | return 0; |
| 583 | } | 615 | } |
| 584 | 616 | ||
| 585 | static inline void ipoib_cm_skb_too_long(struct net_device* dev, struct sk_buff *skb, | 617 | static inline void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb, |
| 586 | unsigned int mtu) | 618 | unsigned int mtu) |
| 587 | { | 619 | { |
| 588 | dev_kfree_skb_any(skb); | 620 | dev_kfree_skb_any(skb); |
| @@ -624,12 +656,12 @@ extern struct ib_sa_client ipoib_sa_client; | |||
| 624 | extern int ipoib_debug_level; | 656 | extern int ipoib_debug_level; |
| 625 | 657 | ||
| 626 | #define ipoib_dbg(priv, format, arg...) \ | 658 | #define ipoib_dbg(priv, format, arg...) \ |
| 627 | do { \ | 659 | do { \ |
| 628 | if (ipoib_debug_level > 0) \ | 660 | if (ipoib_debug_level > 0) \ |
| 629 | ipoib_printk(KERN_DEBUG, priv, format , ## arg); \ | 661 | ipoib_printk(KERN_DEBUG, priv, format , ## arg); \ |
| 630 | } while (0) | 662 | } while (0) |
| 631 | #define ipoib_dbg_mcast(priv, format, arg...) \ | 663 | #define ipoib_dbg_mcast(priv, format, arg...) \ |
| 632 | do { \ | 664 | do { \ |
| 633 | if (mcast_debug_level > 0) \ | 665 | if (mcast_debug_level > 0) \ |
| 634 | ipoib_printk(KERN_DEBUG, priv, format , ## arg); \ | 666 | ipoib_printk(KERN_DEBUG, priv, format , ## arg); \ |
| 635 | } while (0) | 667 | } while (0) |
| @@ -642,7 +674,7 @@ extern int ipoib_debug_level; | |||
| 642 | 674 | ||
| 643 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG_DATA | 675 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG_DATA |
| 644 | #define ipoib_dbg_data(priv, format, arg...) \ | 676 | #define ipoib_dbg_data(priv, format, arg...) \ |
| 645 | do { \ | 677 | do { \ |
| 646 | if (data_debug_level > 0) \ | 678 | if (data_debug_level > 0) \ |
| 647 | ipoib_printk(KERN_DEBUG, priv, format , ## arg); \ | 679 | ipoib_printk(KERN_DEBUG, priv, format , ## arg); \ |
| 648 | } while (0) | 680 | } while (0) |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 059cf92b60a5..1818f958c250 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |||
| @@ -39,6 +39,15 @@ | |||
| 39 | #include <linux/icmpv6.h> | 39 | #include <linux/icmpv6.h> |
| 40 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
| 41 | 41 | ||
| 42 | #include "ipoib.h" | ||
| 43 | |||
| 44 | int ipoib_max_conn_qp = 128; | ||
| 45 | |||
| 46 | module_param_named(max_nonsrq_conn_qp, ipoib_max_conn_qp, int, 0444); | ||
| 47 | MODULE_PARM_DESC(max_nonsrq_conn_qp, | ||
| 48 | "Max number of connected-mode QPs per interface " | ||
| 49 | "(applied only if shared receive queue is not available)"); | ||
| 50 | |||
| 42 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG_DATA | 51 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG_DATA |
| 43 | static int data_debug_level; | 52 | static int data_debug_level; |
| 44 | 53 | ||
| @@ -47,8 +56,6 @@ MODULE_PARM_DESC(cm_data_debug_level, | |||
| 47 | "Enable data path debug tracing for connected mode if > 0"); | 56 | "Enable data path debug tracing for connected mode if > 0"); |
| 48 | #endif | 57 | #endif |
| 49 | 58 | ||
| 50 | #include "ipoib.h" | ||
| 51 | |||
| 52 | #define IPOIB_CM_IETF_ID 0x1000000000000000ULL | 59 | #define IPOIB_CM_IETF_ID 0x1000000000000000ULL |
| 53 | 60 | ||
| 54 | #define IPOIB_CM_RX_UPDATE_TIME (256 * HZ) | 61 | #define IPOIB_CM_RX_UPDATE_TIME (256 * HZ) |
| @@ -81,7 +88,7 @@ static void ipoib_cm_dma_unmap_rx(struct ipoib_dev_priv *priv, int frags, | |||
| 81 | ib_dma_unmap_single(priv->ca, mapping[i + 1], PAGE_SIZE, DMA_FROM_DEVICE); | 88 | ib_dma_unmap_single(priv->ca, mapping[i + 1], PAGE_SIZE, DMA_FROM_DEVICE); |
| 82 | } | 89 | } |
| 83 | 90 | ||
| 84 | static int ipoib_cm_post_receive(struct net_device *dev, int id) | 91 | static int ipoib_cm_post_receive_srq(struct net_device *dev, int id) |
| 85 | { | 92 | { |
| 86 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 93 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 87 | struct ib_recv_wr *bad_wr; | 94 | struct ib_recv_wr *bad_wr; |
| @@ -89,13 +96,13 @@ static int ipoib_cm_post_receive(struct net_device *dev, int id) | |||
| 89 | 96 | ||
| 90 | priv->cm.rx_wr.wr_id = id | IPOIB_OP_CM | IPOIB_OP_RECV; | 97 | priv->cm.rx_wr.wr_id = id | IPOIB_OP_CM | IPOIB_OP_RECV; |
| 91 | 98 | ||
| 92 | for (i = 0; i < IPOIB_CM_RX_SG; ++i) | 99 | for (i = 0; i < priv->cm.num_frags; ++i) |
| 93 | priv->cm.rx_sge[i].addr = priv->cm.srq_ring[id].mapping[i]; | 100 | priv->cm.rx_sge[i].addr = priv->cm.srq_ring[id].mapping[i]; |
| 94 | 101 | ||
| 95 | ret = ib_post_srq_recv(priv->cm.srq, &priv->cm.rx_wr, &bad_wr); | 102 | ret = ib_post_srq_recv(priv->cm.srq, &priv->cm.rx_wr, &bad_wr); |
| 96 | if (unlikely(ret)) { | 103 | if (unlikely(ret)) { |
| 97 | ipoib_warn(priv, "post srq failed for buf %d (%d)\n", id, ret); | 104 | ipoib_warn(priv, "post srq failed for buf %d (%d)\n", id, ret); |
| 98 | ipoib_cm_dma_unmap_rx(priv, IPOIB_CM_RX_SG - 1, | 105 | ipoib_cm_dma_unmap_rx(priv, priv->cm.num_frags - 1, |
| 99 | priv->cm.srq_ring[id].mapping); | 106 | priv->cm.srq_ring[id].mapping); |
| 100 | dev_kfree_skb_any(priv->cm.srq_ring[id].skb); | 107 | dev_kfree_skb_any(priv->cm.srq_ring[id].skb); |
| 101 | priv->cm.srq_ring[id].skb = NULL; | 108 | priv->cm.srq_ring[id].skb = NULL; |
| @@ -104,7 +111,33 @@ static int ipoib_cm_post_receive(struct net_device *dev, int id) | |||
| 104 | return ret; | 111 | return ret; |
| 105 | } | 112 | } |
| 106 | 113 | ||
| 107 | static struct sk_buff *ipoib_cm_alloc_rx_skb(struct net_device *dev, int id, int frags, | 114 | static int ipoib_cm_post_receive_nonsrq(struct net_device *dev, |
| 115 | struct ipoib_cm_rx *rx, int id) | ||
| 116 | { | ||
| 117 | struct ipoib_dev_priv *priv = netdev_priv(dev); | ||
| 118 | struct ib_recv_wr *bad_wr; | ||
| 119 | int i, ret; | ||
| 120 | |||
| 121 | priv->cm.rx_wr.wr_id = id | IPOIB_OP_CM | IPOIB_OP_RECV; | ||
| 122 | |||
| 123 | for (i = 0; i < IPOIB_CM_RX_SG; ++i) | ||
| 124 | priv->cm.rx_sge[i].addr = rx->rx_ring[id].mapping[i]; | ||
| 125 | |||
| 126 | ret = ib_post_recv(rx->qp, &priv->cm.rx_wr, &bad_wr); | ||
| 127 | if (unlikely(ret)) { | ||
| 128 | ipoib_warn(priv, "post recv failed for buf %d (%d)\n", id, ret); | ||
| 129 | ipoib_cm_dma_unmap_rx(priv, IPOIB_CM_RX_SG - 1, | ||
| 130 | rx->rx_ring[id].mapping); | ||
| 131 | dev_kfree_skb_any(rx->rx_ring[id].skb); | ||
| 132 | rx->rx_ring[id].skb = NULL; | ||
| 133 | } | ||
| 134 | |||
| 135 | return ret; | ||
| 136 | } | ||
| 137 | |||
| 138 | static struct sk_buff *ipoib_cm_alloc_rx_skb(struct net_device *dev, | ||
| 139 | struct ipoib_cm_rx_buf *rx_ring, | ||
| 140 | int id, int frags, | ||
| 108 | u64 mapping[IPOIB_CM_RX_SG]) | 141 | u64 mapping[IPOIB_CM_RX_SG]) |
| 109 | { | 142 | { |
| 110 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 143 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| @@ -141,7 +174,7 @@ static struct sk_buff *ipoib_cm_alloc_rx_skb(struct net_device *dev, int id, int | |||
| 141 | goto partial_error; | 174 | goto partial_error; |
| 142 | } | 175 | } |
| 143 | 176 | ||
| 144 | priv->cm.srq_ring[id].skb = skb; | 177 | rx_ring[id].skb = skb; |
| 145 | return skb; | 178 | return skb; |
| 146 | 179 | ||
| 147 | partial_error: | 180 | partial_error: |
| @@ -155,7 +188,23 @@ partial_error: | |||
| 155 | return NULL; | 188 | return NULL; |
| 156 | } | 189 | } |
| 157 | 190 | ||
| 158 | static void ipoib_cm_start_rx_drain(struct ipoib_dev_priv* priv) | 191 | static void ipoib_cm_free_rx_ring(struct net_device *dev, |
| 192 | struct ipoib_cm_rx_buf *rx_ring) | ||
| 193 | { | ||
| 194 | struct ipoib_dev_priv *priv = netdev_priv(dev); | ||
| 195 | int i; | ||
| 196 | |||
| 197 | for (i = 0; i < ipoib_recvq_size; ++i) | ||
| 198 | if (rx_ring[i].skb) { | ||
| 199 | ipoib_cm_dma_unmap_rx(priv, IPOIB_CM_RX_SG - 1, | ||
| 200 | rx_ring[i].mapping); | ||
| 201 | dev_kfree_skb_any(rx_ring[i].skb); | ||
| 202 | } | ||
| 203 | |||
| 204 | kfree(rx_ring); | ||
| 205 | } | ||
| 206 | |||
| 207 | static void ipoib_cm_start_rx_drain(struct ipoib_dev_priv *priv) | ||
| 159 | { | 208 | { |
| 160 | struct ib_send_wr *bad_wr; | 209 | struct ib_send_wr *bad_wr; |
| 161 | struct ipoib_cm_rx *p; | 210 | struct ipoib_cm_rx *p; |
| @@ -208,12 +257,18 @@ static struct ib_qp *ipoib_cm_create_rx_qp(struct net_device *dev, | |||
| 208 | .qp_type = IB_QPT_RC, | 257 | .qp_type = IB_QPT_RC, |
| 209 | .qp_context = p, | 258 | .qp_context = p, |
| 210 | }; | 259 | }; |
| 260 | |||
| 261 | if (!ipoib_cm_has_srq(dev)) { | ||
| 262 | attr.cap.max_recv_wr = ipoib_recvq_size; | ||
| 263 | attr.cap.max_recv_sge = IPOIB_CM_RX_SG; | ||
| 264 | } | ||
| 265 | |||
| 211 | return ib_create_qp(priv->pd, &attr); | 266 | return ib_create_qp(priv->pd, &attr); |
| 212 | } | 267 | } |
| 213 | 268 | ||
| 214 | static int ipoib_cm_modify_rx_qp(struct net_device *dev, | 269 | static int ipoib_cm_modify_rx_qp(struct net_device *dev, |
| 215 | struct ib_cm_id *cm_id, struct ib_qp *qp, | 270 | struct ib_cm_id *cm_id, struct ib_qp *qp, |
| 216 | unsigned psn) | 271 | unsigned psn) |
| 217 | { | 272 | { |
| 218 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 273 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 219 | struct ib_qp_attr qp_attr; | 274 | struct ib_qp_attr qp_attr; |
| @@ -266,6 +321,60 @@ static int ipoib_cm_modify_rx_qp(struct net_device *dev, | |||
| 266 | return 0; | 321 | return 0; |
| 267 | } | 322 | } |
| 268 | 323 | ||
| 324 | static int ipoib_cm_nonsrq_init_rx(struct net_device *dev, struct ib_cm_id *cm_id, | ||
| 325 | struct ipoib_cm_rx *rx) | ||
| 326 | { | ||
| 327 | struct ipoib_dev_priv *priv = netdev_priv(dev); | ||
| 328 | int ret; | ||
| 329 | int i; | ||
| 330 | |||
| 331 | rx->rx_ring = kcalloc(ipoib_recvq_size, sizeof *rx->rx_ring, GFP_KERNEL); | ||
| 332 | if (!rx->rx_ring) | ||
| 333 | return -ENOMEM; | ||
| 334 | |||
| 335 | spin_lock_irq(&priv->lock); | ||
| 336 | |||
| 337 | if (priv->cm.nonsrq_conn_qp >= ipoib_max_conn_qp) { | ||
| 338 | spin_unlock_irq(&priv->lock); | ||
| 339 | ib_send_cm_rej(cm_id, IB_CM_REJ_NO_QP, NULL, 0, NULL, 0); | ||
| 340 | ret = -EINVAL; | ||
| 341 | goto err_free; | ||
| 342 | } else | ||
| 343 | ++priv->cm.nonsrq_conn_qp; | ||
| 344 | |||
| 345 | spin_unlock_irq(&priv->lock); | ||
| 346 | |||
| 347 | for (i = 0; i < ipoib_recvq_size; ++i) { | ||
| 348 | if (!ipoib_cm_alloc_rx_skb(dev, rx->rx_ring, i, IPOIB_CM_RX_SG - 1, | ||
| 349 | rx->rx_ring[i].mapping)) { | ||
| 350 | ipoib_warn(priv, "failed to allocate receive buffer %d\n", i); | ||
| 351 | ret = -ENOMEM; | ||
| 352 | goto err_count; | ||
| 353 | } | ||
| 354 | ret = ipoib_cm_post_receive_nonsrq(dev, rx, i); | ||
| 355 | if (ret) { | ||
| 356 | ipoib_warn(priv, "ipoib_cm_post_receive_nonsrq " | ||
| 357 | "failed for buf %d\n", i); | ||
| 358 | ret = -EIO; | ||
| 359 | goto err_count; | ||
| 360 | } | ||
| 361 | } | ||
| 362 | |||
| 363 | rx->recv_count = ipoib_recvq_size; | ||
| 364 | |||
| 365 | return 0; | ||
| 366 | |||
| 367 | err_count: | ||
| 368 | spin_lock_irq(&priv->lock); | ||
| 369 | --priv->cm.nonsrq_conn_qp; | ||
| 370 | spin_unlock_irq(&priv->lock); | ||
| 371 | |||
| 372 | err_free: | ||
| 373 | ipoib_cm_free_rx_ring(dev, rx->rx_ring); | ||
| 374 | |||
| 375 | return ret; | ||
| 376 | } | ||
| 377 | |||
| 269 | static int ipoib_cm_send_rep(struct net_device *dev, struct ib_cm_id *cm_id, | 378 | static int ipoib_cm_send_rep(struct net_device *dev, struct ib_cm_id *cm_id, |
| 270 | struct ib_qp *qp, struct ib_cm_req_event_param *req, | 379 | struct ib_qp *qp, struct ib_cm_req_event_param *req, |
| 271 | unsigned psn) | 380 | unsigned psn) |
| @@ -281,7 +390,7 @@ static int ipoib_cm_send_rep(struct net_device *dev, struct ib_cm_id *cm_id, | |||
| 281 | rep.private_data_len = sizeof data; | 390 | rep.private_data_len = sizeof data; |
| 282 | rep.flow_control = 0; | 391 | rep.flow_control = 0; |
| 283 | rep.rnr_retry_count = req->rnr_retry_count; | 392 | rep.rnr_retry_count = req->rnr_retry_count; |
| 284 | rep.srq = 1; | 393 | rep.srq = ipoib_cm_has_srq(dev); |
| 285 | rep.qp_num = qp->qp_num; | 394 | rep.qp_num = qp->qp_num; |
| 286 | rep.starting_psn = psn; | 395 | rep.starting_psn = psn; |
| 287 | return ib_send_cm_rep(cm_id, &rep); | 396 | return ib_send_cm_rep(cm_id, &rep); |
| @@ -317,6 +426,12 @@ static int ipoib_cm_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *even | |||
| 317 | if (ret) | 426 | if (ret) |
| 318 | goto err_modify; | 427 | goto err_modify; |
| 319 | 428 | ||
| 429 | if (!ipoib_cm_has_srq(dev)) { | ||
| 430 | ret = ipoib_cm_nonsrq_init_rx(dev, cm_id, p); | ||
| 431 | if (ret) | ||
| 432 | goto err_modify; | ||
| 433 | } | ||
| 434 | |||
| 320 | spin_lock_irq(&priv->lock); | 435 | spin_lock_irq(&priv->lock); |
| 321 | queue_delayed_work(ipoib_workqueue, | 436 | queue_delayed_work(ipoib_workqueue, |
| 322 | &priv->cm.stale_task, IPOIB_CM_RX_DELAY); | 437 | &priv->cm.stale_task, IPOIB_CM_RX_DELAY); |
| @@ -401,12 +516,14 @@ static void skb_put_frags(struct sk_buff *skb, unsigned int hdr_space, | |||
| 401 | void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) | 516 | void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) |
| 402 | { | 517 | { |
| 403 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 518 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 519 | struct ipoib_cm_rx_buf *rx_ring; | ||
| 404 | unsigned int wr_id = wc->wr_id & ~(IPOIB_OP_CM | IPOIB_OP_RECV); | 520 | unsigned int wr_id = wc->wr_id & ~(IPOIB_OP_CM | IPOIB_OP_RECV); |
| 405 | struct sk_buff *skb, *newskb; | 521 | struct sk_buff *skb, *newskb; |
| 406 | struct ipoib_cm_rx *p; | 522 | struct ipoib_cm_rx *p; |
| 407 | unsigned long flags; | 523 | unsigned long flags; |
| 408 | u64 mapping[IPOIB_CM_RX_SG]; | 524 | u64 mapping[IPOIB_CM_RX_SG]; |
| 409 | int frags; | 525 | int frags; |
| 526 | int has_srq; | ||
| 410 | 527 | ||
| 411 | ipoib_dbg_data(priv, "cm recv completion: id %d, status: %d\n", | 528 | ipoib_dbg_data(priv, "cm recv completion: id %d, status: %d\n", |
| 412 | wr_id, wc->status); | 529 | wr_id, wc->status); |
| @@ -424,18 +541,32 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) | |||
| 424 | return; | 541 | return; |
| 425 | } | 542 | } |
| 426 | 543 | ||
| 427 | skb = priv->cm.srq_ring[wr_id].skb; | 544 | p = wc->qp->qp_context; |
| 545 | |||
| 546 | has_srq = ipoib_cm_has_srq(dev); | ||
| 547 | rx_ring = has_srq ? priv->cm.srq_ring : p->rx_ring; | ||
| 548 | |||
| 549 | skb = rx_ring[wr_id].skb; | ||
| 428 | 550 | ||
| 429 | if (unlikely(wc->status != IB_WC_SUCCESS)) { | 551 | if (unlikely(wc->status != IB_WC_SUCCESS)) { |
| 430 | ipoib_dbg(priv, "cm recv error " | 552 | ipoib_dbg(priv, "cm recv error " |
| 431 | "(status=%d, wrid=%d vend_err %x)\n", | 553 | "(status=%d, wrid=%d vend_err %x)\n", |
| 432 | wc->status, wr_id, wc->vendor_err); | 554 | wc->status, wr_id, wc->vendor_err); |
| 433 | ++dev->stats.rx_dropped; | 555 | ++dev->stats.rx_dropped; |
| 434 | goto repost; | 556 | if (has_srq) |
| 557 | goto repost; | ||
| 558 | else { | ||
| 559 | if (!--p->recv_count) { | ||
| 560 | spin_lock_irqsave(&priv->lock, flags); | ||
| 561 | list_move(&p->list, &priv->cm.rx_reap_list); | ||
| 562 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 563 | queue_work(ipoib_workqueue, &priv->cm.rx_reap_task); | ||
| 564 | } | ||
| 565 | return; | ||
| 566 | } | ||
| 435 | } | 567 | } |
| 436 | 568 | ||
| 437 | if (unlikely(!(wr_id & IPOIB_CM_RX_UPDATE_MASK))) { | 569 | if (unlikely(!(wr_id & IPOIB_CM_RX_UPDATE_MASK))) { |
| 438 | p = wc->qp->qp_context; | ||
| 439 | if (p && time_after_eq(jiffies, p->jiffies + IPOIB_CM_RX_UPDATE_TIME)) { | 570 | if (p && time_after_eq(jiffies, p->jiffies + IPOIB_CM_RX_UPDATE_TIME)) { |
| 440 | spin_lock_irqsave(&priv->lock, flags); | 571 | spin_lock_irqsave(&priv->lock, flags); |
| 441 | p->jiffies = jiffies; | 572 | p->jiffies = jiffies; |
| @@ -450,7 +581,7 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) | |||
| 450 | frags = PAGE_ALIGN(wc->byte_len - min(wc->byte_len, | 581 | frags = PAGE_ALIGN(wc->byte_len - min(wc->byte_len, |
| 451 | (unsigned)IPOIB_CM_HEAD_SIZE)) / PAGE_SIZE; | 582 | (unsigned)IPOIB_CM_HEAD_SIZE)) / PAGE_SIZE; |
| 452 | 583 | ||
| 453 | newskb = ipoib_cm_alloc_rx_skb(dev, wr_id, frags, mapping); | 584 | newskb = ipoib_cm_alloc_rx_skb(dev, rx_ring, wr_id, frags, mapping); |
| 454 | if (unlikely(!newskb)) { | 585 | if (unlikely(!newskb)) { |
| 455 | /* | 586 | /* |
| 456 | * If we can't allocate a new RX buffer, dump | 587 | * If we can't allocate a new RX buffer, dump |
| @@ -461,8 +592,8 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) | |||
| 461 | goto repost; | 592 | goto repost; |
| 462 | } | 593 | } |
| 463 | 594 | ||
| 464 | ipoib_cm_dma_unmap_rx(priv, frags, priv->cm.srq_ring[wr_id].mapping); | 595 | ipoib_cm_dma_unmap_rx(priv, frags, rx_ring[wr_id].mapping); |
| 465 | memcpy(priv->cm.srq_ring[wr_id].mapping, mapping, (frags + 1) * sizeof *mapping); | 596 | memcpy(rx_ring[wr_id].mapping, mapping, (frags + 1) * sizeof *mapping); |
| 466 | 597 | ||
| 467 | ipoib_dbg_data(priv, "received %d bytes, SLID 0x%04x\n", | 598 | ipoib_dbg_data(priv, "received %d bytes, SLID 0x%04x\n", |
| 468 | wc->byte_len, wc->slid); | 599 | wc->byte_len, wc->slid); |
| @@ -483,9 +614,17 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) | |||
| 483 | netif_receive_skb(skb); | 614 | netif_receive_skb(skb); |
| 484 | 615 | ||
| 485 | repost: | 616 | repost: |
| 486 | if (unlikely(ipoib_cm_post_receive(dev, wr_id))) | 617 | if (has_srq) { |
| 487 | ipoib_warn(priv, "ipoib_cm_post_receive failed " | 618 | if (unlikely(ipoib_cm_post_receive_srq(dev, wr_id))) |
| 488 | "for buf %d\n", wr_id); | 619 | ipoib_warn(priv, "ipoib_cm_post_receive_srq failed " |
| 620 | "for buf %d\n", wr_id); | ||
| 621 | } else { | ||
| 622 | if (unlikely(ipoib_cm_post_receive_nonsrq(dev, p, wr_id))) { | ||
| 623 | --p->recv_count; | ||
| 624 | ipoib_warn(priv, "ipoib_cm_post_receive_nonsrq failed " | ||
| 625 | "for buf %d\n", wr_id); | ||
| 626 | } | ||
| 627 | } | ||
| 489 | } | 628 | } |
| 490 | 629 | ||
| 491 | static inline int post_send(struct ipoib_dev_priv *priv, | 630 | static inline int post_send(struct ipoib_dev_priv *priv, |
| @@ -495,10 +634,10 @@ static inline int post_send(struct ipoib_dev_priv *priv, | |||
| 495 | { | 634 | { |
| 496 | struct ib_send_wr *bad_wr; | 635 | struct ib_send_wr *bad_wr; |
| 497 | 636 | ||
| 498 | priv->tx_sge.addr = addr; | 637 | priv->tx_sge.addr = addr; |
| 499 | priv->tx_sge.length = len; | 638 | priv->tx_sge.length = len; |
| 500 | 639 | ||
| 501 | priv->tx_wr.wr_id = wr_id | IPOIB_OP_CM; | 640 | priv->tx_wr.wr_id = wr_id | IPOIB_OP_CM; |
| 502 | 641 | ||
| 503 | return ib_post_send(tx->qp, &priv->tx_wr, &bad_wr); | 642 | return ib_post_send(tx->qp, &priv->tx_wr, &bad_wr); |
| 504 | } | 643 | } |
| @@ -540,7 +679,7 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ | |||
| 540 | tx_req->mapping = addr; | 679 | tx_req->mapping = addr; |
| 541 | 680 | ||
| 542 | if (unlikely(post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1), | 681 | if (unlikely(post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1), |
| 543 | addr, skb->len))) { | 682 | addr, skb->len))) { |
| 544 | ipoib_warn(priv, "post_send failed\n"); | 683 | ipoib_warn(priv, "post_send failed\n"); |
| 545 | ++dev->stats.tx_errors; | 684 | ++dev->stats.tx_errors; |
| 546 | ib_dma_unmap_single(priv->ca, addr, skb->len, DMA_TO_DEVICE); | 685 | ib_dma_unmap_single(priv->ca, addr, skb->len, DMA_TO_DEVICE); |
| @@ -657,10 +796,33 @@ err_cm: | |||
| 657 | return ret; | 796 | return ret; |
| 658 | } | 797 | } |
| 659 | 798 | ||
| 799 | static void ipoib_cm_free_rx_reap_list(struct net_device *dev) | ||
| 800 | { | ||
| 801 | struct ipoib_dev_priv *priv = netdev_priv(dev); | ||
| 802 | struct ipoib_cm_rx *rx, *n; | ||
| 803 | LIST_HEAD(list); | ||
| 804 | |||
| 805 | spin_lock_irq(&priv->lock); | ||
| 806 | list_splice_init(&priv->cm.rx_reap_list, &list); | ||
| 807 | spin_unlock_irq(&priv->lock); | ||
| 808 | |||
| 809 | list_for_each_entry_safe(rx, n, &list, list) { | ||
| 810 | ib_destroy_cm_id(rx->id); | ||
| 811 | ib_destroy_qp(rx->qp); | ||
| 812 | if (!ipoib_cm_has_srq(dev)) { | ||
| 813 | ipoib_cm_free_rx_ring(priv->dev, rx->rx_ring); | ||
| 814 | spin_lock_irq(&priv->lock); | ||
| 815 | --priv->cm.nonsrq_conn_qp; | ||
| 816 | spin_unlock_irq(&priv->lock); | ||
| 817 | } | ||
| 818 | kfree(rx); | ||
| 819 | } | ||
| 820 | } | ||
| 821 | |||
| 660 | void ipoib_cm_dev_stop(struct net_device *dev) | 822 | void ipoib_cm_dev_stop(struct net_device *dev) |
| 661 | { | 823 | { |
| 662 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 824 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 663 | struct ipoib_cm_rx *p, *n; | 825 | struct ipoib_cm_rx *p; |
| 664 | unsigned long begin; | 826 | unsigned long begin; |
| 665 | LIST_HEAD(list); | 827 | LIST_HEAD(list); |
| 666 | int ret; | 828 | int ret; |
| @@ -706,15 +868,9 @@ void ipoib_cm_dev_stop(struct net_device *dev) | |||
| 706 | spin_lock_irq(&priv->lock); | 868 | spin_lock_irq(&priv->lock); |
| 707 | } | 869 | } |
| 708 | 870 | ||
| 709 | list_splice_init(&priv->cm.rx_reap_list, &list); | ||
| 710 | |||
| 711 | spin_unlock_irq(&priv->lock); | 871 | spin_unlock_irq(&priv->lock); |
| 712 | 872 | ||
| 713 | list_for_each_entry_safe(p, n, &list, list) { | 873 | ipoib_cm_free_rx_reap_list(dev); |
| 714 | ib_destroy_cm_id(p->id); | ||
| 715 | ib_destroy_qp(p->qp); | ||
| 716 | kfree(p); | ||
| 717 | } | ||
| 718 | 874 | ||
| 719 | cancel_delayed_work(&priv->cm.stale_task); | 875 | cancel_delayed_work(&priv->cm.stale_task); |
| 720 | } | 876 | } |
| @@ -799,7 +955,7 @@ static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ipoib_ | |||
| 799 | .sq_sig_type = IB_SIGNAL_ALL_WR, | 955 | .sq_sig_type = IB_SIGNAL_ALL_WR, |
| 800 | .qp_type = IB_QPT_RC, | 956 | .qp_type = IB_QPT_RC, |
| 801 | .qp_context = tx | 957 | .qp_context = tx |
| 802 | }; | 958 | }; |
| 803 | 959 | ||
| 804 | return ib_create_qp(priv->pd, &attr); | 960 | return ib_create_qp(priv->pd, &attr); |
| 805 | } | 961 | } |
| @@ -816,28 +972,28 @@ static int ipoib_cm_send_req(struct net_device *dev, | |||
| 816 | data.qpn = cpu_to_be32(priv->qp->qp_num); | 972 | data.qpn = cpu_to_be32(priv->qp->qp_num); |
| 817 | data.mtu = cpu_to_be32(IPOIB_CM_BUF_SIZE); | 973 | data.mtu = cpu_to_be32(IPOIB_CM_BUF_SIZE); |
| 818 | 974 | ||
| 819 | req.primary_path = pathrec; | 975 | req.primary_path = pathrec; |
| 820 | req.alternate_path = NULL; | 976 | req.alternate_path = NULL; |
| 821 | req.service_id = cpu_to_be64(IPOIB_CM_IETF_ID | qpn); | 977 | req.service_id = cpu_to_be64(IPOIB_CM_IETF_ID | qpn); |
| 822 | req.qp_num = qp->qp_num; | 978 | req.qp_num = qp->qp_num; |
| 823 | req.qp_type = qp->qp_type; | 979 | req.qp_type = qp->qp_type; |
| 824 | req.private_data = &data; | 980 | req.private_data = &data; |
| 825 | req.private_data_len = sizeof data; | 981 | req.private_data_len = sizeof data; |
| 826 | req.flow_control = 0; | 982 | req.flow_control = 0; |
| 827 | 983 | ||
| 828 | req.starting_psn = 0; /* FIXME */ | 984 | req.starting_psn = 0; /* FIXME */ |
| 829 | 985 | ||
| 830 | /* | 986 | /* |
| 831 | * Pick some arbitrary defaults here; we could make these | 987 | * Pick some arbitrary defaults here; we could make these |
| 832 | * module parameters if anyone cared about setting them. | 988 | * module parameters if anyone cared about setting them. |
| 833 | */ | 989 | */ |
| 834 | req.responder_resources = 4; | 990 | req.responder_resources = 4; |
| 835 | req.remote_cm_response_timeout = 20; | 991 | req.remote_cm_response_timeout = 20; |
| 836 | req.local_cm_response_timeout = 20; | 992 | req.local_cm_response_timeout = 20; |
| 837 | req.retry_count = 0; /* RFC draft warns against retries */ | 993 | req.retry_count = 0; /* RFC draft warns against retries */ |
| 838 | req.rnr_retry_count = 0; /* RFC draft warns against retries */ | 994 | req.rnr_retry_count = 0; /* RFC draft warns against retries */ |
| 839 | req.max_cm_retries = 15; | 995 | req.max_cm_retries = 15; |
| 840 | req.srq = 1; | 996 | req.srq = ipoib_cm_has_srq(dev); |
| 841 | return ib_send_cm_req(id, &req); | 997 | return ib_send_cm_req(id, &req); |
| 842 | } | 998 | } |
| 843 | 999 | ||
| @@ -1150,7 +1306,7 @@ static void ipoib_cm_skb_reap(struct work_struct *work) | |||
| 1150 | spin_unlock_irq(&priv->tx_lock); | 1306 | spin_unlock_irq(&priv->tx_lock); |
| 1151 | } | 1307 | } |
| 1152 | 1308 | ||
| 1153 | void ipoib_cm_skb_too_long(struct net_device* dev, struct sk_buff *skb, | 1309 | void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb, |
| 1154 | unsigned int mtu) | 1310 | unsigned int mtu) |
| 1155 | { | 1311 | { |
| 1156 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 1312 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| @@ -1166,20 +1322,8 @@ void ipoib_cm_skb_too_long(struct net_device* dev, struct sk_buff *skb, | |||
| 1166 | 1322 | ||
| 1167 | static void ipoib_cm_rx_reap(struct work_struct *work) | 1323 | static void ipoib_cm_rx_reap(struct work_struct *work) |
| 1168 | { | 1324 | { |
| 1169 | struct ipoib_dev_priv *priv = container_of(work, struct ipoib_dev_priv, | 1325 | ipoib_cm_free_rx_reap_list(container_of(work, struct ipoib_dev_priv, |
| 1170 | cm.rx_reap_task); | 1326 | cm.rx_reap_task)->dev); |
| 1171 | struct ipoib_cm_rx *p, *n; | ||
| 1172 | LIST_HEAD(list); | ||
| 1173 | |||
| 1174 | spin_lock_irq(&priv->lock); | ||
| 1175 | list_splice_init(&priv->cm.rx_reap_list, &list); | ||
| 1176 | spin_unlock_irq(&priv->lock); | ||
| 1177 | |||
| 1178 | list_for_each_entry_safe(p, n, &list, list) { | ||
| 1179 | ib_destroy_cm_id(p->id); | ||
| 1180 | ib_destroy_qp(p->qp); | ||
| 1181 | kfree(p); | ||
| 1182 | } | ||
| 1183 | } | 1327 | } |
| 1184 | 1328 | ||
| 1185 | static void ipoib_cm_stale_task(struct work_struct *work) | 1329 | static void ipoib_cm_stale_task(struct work_struct *work) |
| @@ -1212,7 +1356,7 @@ static void ipoib_cm_stale_task(struct work_struct *work) | |||
| 1212 | } | 1356 | } |
| 1213 | 1357 | ||
| 1214 | 1358 | ||
| 1215 | static ssize_t show_mode(struct device *d, struct device_attribute *attr, | 1359 | static ssize_t show_mode(struct device *d, struct device_attribute *attr, |
| 1216 | char *buf) | 1360 | char *buf) |
| 1217 | { | 1361 | { |
| 1218 | struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(d)); | 1362 | struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(d)); |
| @@ -1255,16 +1399,40 @@ int ipoib_cm_add_mode_attr(struct net_device *dev) | |||
| 1255 | return device_create_file(&dev->dev, &dev_attr_mode); | 1399 | return device_create_file(&dev->dev, &dev_attr_mode); |
| 1256 | } | 1400 | } |
| 1257 | 1401 | ||
| 1258 | int ipoib_cm_dev_init(struct net_device *dev) | 1402 | static void ipoib_cm_create_srq(struct net_device *dev, int max_sge) |
| 1259 | { | 1403 | { |
| 1260 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 1404 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 1261 | struct ib_srq_init_attr srq_init_attr = { | 1405 | struct ib_srq_init_attr srq_init_attr = { |
| 1262 | .attr = { | 1406 | .attr = { |
| 1263 | .max_wr = ipoib_recvq_size, | 1407 | .max_wr = ipoib_recvq_size, |
| 1264 | .max_sge = IPOIB_CM_RX_SG | 1408 | .max_sge = max_sge |
| 1265 | } | 1409 | } |
| 1266 | }; | 1410 | }; |
| 1267 | int ret, i; | 1411 | |
| 1412 | priv->cm.srq = ib_create_srq(priv->pd, &srq_init_attr); | ||
| 1413 | if (IS_ERR(priv->cm.srq)) { | ||
| 1414 | if (PTR_ERR(priv->cm.srq) != -ENOSYS) | ||
| 1415 | printk(KERN_WARNING "%s: failed to allocate SRQ, error %ld\n", | ||
| 1416 | priv->ca->name, PTR_ERR(priv->cm.srq)); | ||
| 1417 | priv->cm.srq = NULL; | ||
| 1418 | return; | ||
| 1419 | } | ||
| 1420 | |||
| 1421 | priv->cm.srq_ring = kzalloc(ipoib_recvq_size * sizeof *priv->cm.srq_ring, | ||
| 1422 | GFP_KERNEL); | ||
| 1423 | if (!priv->cm.srq_ring) { | ||
| 1424 | printk(KERN_WARNING "%s: failed to allocate CM SRQ ring (%d entries)\n", | ||
| 1425 | priv->ca->name, ipoib_recvq_size); | ||
| 1426 | ib_destroy_srq(priv->cm.srq); | ||
| 1427 | priv->cm.srq = NULL; | ||
| 1428 | } | ||
| 1429 | } | ||
| 1430 | |||
| 1431 | int ipoib_cm_dev_init(struct net_device *dev) | ||
| 1432 | { | ||
| 1433 | struct ipoib_dev_priv *priv = netdev_priv(dev); | ||
| 1434 | int i, ret; | ||
| 1435 | struct ib_device_attr attr; | ||
| 1268 | 1436 | ||
| 1269 | INIT_LIST_HEAD(&priv->cm.passive_ids); | 1437 | INIT_LIST_HEAD(&priv->cm.passive_ids); |
| 1270 | INIT_LIST_HEAD(&priv->cm.reap_list); | 1438 | INIT_LIST_HEAD(&priv->cm.reap_list); |
| @@ -1281,43 +1449,53 @@ int ipoib_cm_dev_init(struct net_device *dev) | |||
| 1281 | 1449 | ||
| 1282 | skb_queue_head_init(&priv->cm.skb_queue); | 1450 | skb_queue_head_init(&priv->cm.skb_queue); |
| 1283 | 1451 | ||
| 1284 | priv->cm.srq = ib_create_srq(priv->pd, &srq_init_attr); | 1452 | ret = ib_query_device(priv->ca, &attr); |
| 1285 | if (IS_ERR(priv->cm.srq)) { | 1453 | if (ret) { |
| 1286 | ret = PTR_ERR(priv->cm.srq); | 1454 | printk(KERN_WARNING "ib_query_device() failed with %d\n", ret); |
| 1287 | priv->cm.srq = NULL; | ||
| 1288 | return ret; | 1455 | return ret; |
| 1289 | } | 1456 | } |
| 1290 | 1457 | ||
| 1291 | priv->cm.srq_ring = kzalloc(ipoib_recvq_size * sizeof *priv->cm.srq_ring, | 1458 | ipoib_dbg(priv, "max_srq_sge=%d\n", attr.max_srq_sge); |
| 1292 | GFP_KERNEL); | 1459 | |
| 1293 | if (!priv->cm.srq_ring) { | 1460 | attr.max_srq_sge = min_t(int, IPOIB_CM_RX_SG, attr.max_srq_sge); |
| 1294 | printk(KERN_WARNING "%s: failed to allocate CM ring (%d entries)\n", | 1461 | ipoib_cm_create_srq(dev, attr.max_srq_sge); |
| 1295 | priv->ca->name, ipoib_recvq_size); | 1462 | if (ipoib_cm_has_srq(dev)) { |
| 1296 | ipoib_cm_dev_cleanup(dev); | 1463 | priv->cm.max_cm_mtu = attr.max_srq_sge * PAGE_SIZE - 0x10; |
| 1297 | return -ENOMEM; | 1464 | priv->cm.num_frags = attr.max_srq_sge; |
| 1465 | ipoib_dbg(priv, "max_cm_mtu = 0x%x, num_frags=%d\n", | ||
| 1466 | priv->cm.max_cm_mtu, priv->cm.num_frags); | ||
| 1467 | } else { | ||
| 1468 | priv->cm.max_cm_mtu = IPOIB_CM_MTU; | ||
| 1469 | priv->cm.num_frags = IPOIB_CM_RX_SG; | ||
| 1298 | } | 1470 | } |
| 1299 | 1471 | ||
| 1300 | for (i = 0; i < IPOIB_CM_RX_SG; ++i) | 1472 | for (i = 0; i < priv->cm.num_frags; ++i) |
| 1301 | priv->cm.rx_sge[i].lkey = priv->mr->lkey; | 1473 | priv->cm.rx_sge[i].lkey = priv->mr->lkey; |
| 1302 | 1474 | ||
| 1303 | priv->cm.rx_sge[0].length = IPOIB_CM_HEAD_SIZE; | 1475 | priv->cm.rx_sge[0].length = IPOIB_CM_HEAD_SIZE; |
| 1304 | for (i = 1; i < IPOIB_CM_RX_SG; ++i) | 1476 | for (i = 1; i < priv->cm.num_frags; ++i) |
| 1305 | priv->cm.rx_sge[i].length = PAGE_SIZE; | 1477 | priv->cm.rx_sge[i].length = PAGE_SIZE; |
| 1306 | priv->cm.rx_wr.next = NULL; | 1478 | priv->cm.rx_wr.next = NULL; |
| 1307 | priv->cm.rx_wr.sg_list = priv->cm.rx_sge; | 1479 | priv->cm.rx_wr.sg_list = priv->cm.rx_sge; |
| 1308 | priv->cm.rx_wr.num_sge = IPOIB_CM_RX_SG; | 1480 | priv->cm.rx_wr.num_sge = priv->cm.num_frags; |
| 1481 | |||
| 1482 | if (ipoib_cm_has_srq(dev)) { | ||
| 1483 | for (i = 0; i < ipoib_recvq_size; ++i) { | ||
| 1484 | if (!ipoib_cm_alloc_rx_skb(dev, priv->cm.srq_ring, i, | ||
| 1485 | priv->cm.num_frags - 1, | ||
| 1486 | priv->cm.srq_ring[i].mapping)) { | ||
| 1487 | ipoib_warn(priv, "failed to allocate " | ||
| 1488 | "receive buffer %d\n", i); | ||
| 1489 | ipoib_cm_dev_cleanup(dev); | ||
| 1490 | return -ENOMEM; | ||
| 1491 | } | ||
| 1309 | 1492 | ||
| 1310 | for (i = 0; i < ipoib_recvq_size; ++i) { | 1493 | if (ipoib_cm_post_receive_srq(dev, i)) { |
| 1311 | if (!ipoib_cm_alloc_rx_skb(dev, i, IPOIB_CM_RX_SG - 1, | 1494 | ipoib_warn(priv, "ipoib_cm_post_receive_srq " |
| 1312 | priv->cm.srq_ring[i].mapping)) { | 1495 | "failed for buf %d\n", i); |
| 1313 | ipoib_warn(priv, "failed to allocate receive buffer %d\n", i); | 1496 | ipoib_cm_dev_cleanup(dev); |
| 1314 | ipoib_cm_dev_cleanup(dev); | 1497 | return -EIO; |
| 1315 | return -ENOMEM; | 1498 | } |
| 1316 | } | ||
| 1317 | if (ipoib_cm_post_receive(dev, i)) { | ||
| 1318 | ipoib_warn(priv, "ipoib_ib_post_receive failed for buf %d\n", i); | ||
| 1319 | ipoib_cm_dev_cleanup(dev); | ||
| 1320 | return -EIO; | ||
| 1321 | } | 1499 | } |
| 1322 | } | 1500 | } |
| 1323 | 1501 | ||
| @@ -1328,7 +1506,7 @@ int ipoib_cm_dev_init(struct net_device *dev) | |||
| 1328 | void ipoib_cm_dev_cleanup(struct net_device *dev) | 1506 | void ipoib_cm_dev_cleanup(struct net_device *dev) |
| 1329 | { | 1507 | { |
| 1330 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 1508 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 1331 | int i, ret; | 1509 | int ret; |
| 1332 | 1510 | ||
| 1333 | if (!priv->cm.srq) | 1511 | if (!priv->cm.srq) |
| 1334 | return; | 1512 | return; |
| @@ -1342,13 +1520,7 @@ void ipoib_cm_dev_cleanup(struct net_device *dev) | |||
| 1342 | priv->cm.srq = NULL; | 1520 | priv->cm.srq = NULL; |
| 1343 | if (!priv->cm.srq_ring) | 1521 | if (!priv->cm.srq_ring) |
| 1344 | return; | 1522 | return; |
| 1345 | for (i = 0; i < ipoib_recvq_size; ++i) | 1523 | |
| 1346 | if (priv->cm.srq_ring[i].skb) { | 1524 | ipoib_cm_free_rx_ring(dev, priv->cm.srq_ring); |
| 1347 | ipoib_cm_dma_unmap_rx(priv, IPOIB_CM_RX_SG - 1, | ||
| 1348 | priv->cm.srq_ring[i].mapping); | ||
| 1349 | dev_kfree_skb_any(priv->cm.srq_ring[i].skb); | ||
| 1350 | priv->cm.srq_ring[i].skb = NULL; | ||
| 1351 | } | ||
| 1352 | kfree(priv->cm.srq_ring); | ||
| 1353 | priv->cm.srq_ring = NULL; | 1525 | priv->cm.srq_ring = NULL; |
| 1354 | } | 1526 | } |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c index 44c174182a82..8b882bbd1d05 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c | |||
| @@ -124,7 +124,7 @@ static int ipoib_mcg_seq_show(struct seq_file *file, void *iter_ptr) | |||
| 124 | return 0; | 124 | return 0; |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | static struct seq_operations ipoib_mcg_seq_ops = { | 127 | static const struct seq_operations ipoib_mcg_seq_ops = { |
| 128 | .start = ipoib_mcg_seq_start, | 128 | .start = ipoib_mcg_seq_start, |
| 129 | .next = ipoib_mcg_seq_next, | 129 | .next = ipoib_mcg_seq_next, |
| 130 | .stop = ipoib_mcg_seq_stop, | 130 | .stop = ipoib_mcg_seq_stop, |
| @@ -230,7 +230,7 @@ static int ipoib_path_seq_show(struct seq_file *file, void *iter_ptr) | |||
| 230 | return 0; | 230 | return 0; |
| 231 | } | 231 | } |
| 232 | 232 | ||
| 233 | static struct seq_operations ipoib_path_seq_ops = { | 233 | static const struct seq_operations ipoib_path_seq_ops = { |
| 234 | .start = ipoib_path_seq_start, | 234 | .start = ipoib_path_seq_start, |
| 235 | .next = ipoib_path_seq_next, | 235 | .next = ipoib_path_seq_next, |
| 236 | .stop = ipoib_path_seq_stop, | 236 | .stop = ipoib_path_seq_stop, |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 5063dd509ad2..52bc2bd5799a 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
| @@ -345,12 +345,12 @@ static inline int post_send(struct ipoib_dev_priv *priv, | |||
| 345 | { | 345 | { |
| 346 | struct ib_send_wr *bad_wr; | 346 | struct ib_send_wr *bad_wr; |
| 347 | 347 | ||
| 348 | priv->tx_sge.addr = addr; | 348 | priv->tx_sge.addr = addr; |
| 349 | priv->tx_sge.length = len; | 349 | priv->tx_sge.length = len; |
| 350 | 350 | ||
| 351 | priv->tx_wr.wr_id = wr_id; | 351 | priv->tx_wr.wr_id = wr_id; |
| 352 | priv->tx_wr.wr.ud.remote_qpn = qpn; | 352 | priv->tx_wr.wr.ud.remote_qpn = qpn; |
| 353 | priv->tx_wr.wr.ud.ah = address; | 353 | priv->tx_wr.wr.ud.ah = address; |
| 354 | 354 | ||
| 355 | return ib_post_send(priv->qp, &priv->tx_wr, &bad_wr); | 355 | return ib_post_send(priv->qp, &priv->tx_wr, &bad_wr); |
| 356 | } | 356 | } |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index c9f6077b615e..a082466f4a83 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
| @@ -182,17 +182,20 @@ static int ipoib_change_mtu(struct net_device *dev, int new_mtu) | |||
| 182 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 182 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 183 | 183 | ||
| 184 | /* dev->mtu > 2K ==> connected mode */ | 184 | /* dev->mtu > 2K ==> connected mode */ |
| 185 | if (ipoib_cm_admin_enabled(dev) && new_mtu <= IPOIB_CM_MTU) { | 185 | if (ipoib_cm_admin_enabled(dev)) { |
| 186 | if (new_mtu > ipoib_cm_max_mtu(dev)) | ||
| 187 | return -EINVAL; | ||
| 188 | |||
| 186 | if (new_mtu > priv->mcast_mtu) | 189 | if (new_mtu > priv->mcast_mtu) |
| 187 | ipoib_warn(priv, "mtu > %d will cause multicast packet drops.\n", | 190 | ipoib_warn(priv, "mtu > %d will cause multicast packet drops.\n", |
| 188 | priv->mcast_mtu); | 191 | priv->mcast_mtu); |
| 192 | |||
| 189 | dev->mtu = new_mtu; | 193 | dev->mtu = new_mtu; |
| 190 | return 0; | 194 | return 0; |
| 191 | } | 195 | } |
| 192 | 196 | ||
| 193 | if (new_mtu > IPOIB_PACKET_SIZE - IPOIB_ENCAP_LEN) { | 197 | if (new_mtu > IPOIB_PACKET_SIZE - IPOIB_ENCAP_LEN) |
| 194 | return -EINVAL; | 198 | return -EINVAL; |
| 195 | } | ||
| 196 | 199 | ||
| 197 | priv->admin_mtu = new_mtu; | 200 | priv->admin_mtu = new_mtu; |
| 198 | 201 | ||
| @@ -474,8 +477,8 @@ static struct ipoib_path *path_rec_create(struct net_device *dev, void *gid) | |||
| 474 | INIT_LIST_HEAD(&path->neigh_list); | 477 | INIT_LIST_HEAD(&path->neigh_list); |
| 475 | 478 | ||
| 476 | memcpy(path->pathrec.dgid.raw, gid, sizeof (union ib_gid)); | 479 | memcpy(path->pathrec.dgid.raw, gid, sizeof (union ib_gid)); |
| 477 | path->pathrec.sgid = priv->local_gid; | 480 | path->pathrec.sgid = priv->local_gid; |
| 478 | path->pathrec.pkey = cpu_to_be16(priv->pkey); | 481 | path->pathrec.pkey = cpu_to_be16(priv->pkey); |
| 479 | path->pathrec.numb_path = 1; | 482 | path->pathrec.numb_path = 1; |
| 480 | path->pathrec.traffic_class = priv->broadcast->mcmember.traffic_class; | 483 | path->pathrec.traffic_class = priv->broadcast->mcmember.traffic_class; |
| 481 | 484 | ||
| @@ -669,16 +672,6 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 669 | if (unlikely(!spin_trylock_irqsave(&priv->tx_lock, flags))) | 672 | if (unlikely(!spin_trylock_irqsave(&priv->tx_lock, flags))) |
| 670 | return NETDEV_TX_LOCKED; | 673 | return NETDEV_TX_LOCKED; |
| 671 | 674 | ||
| 672 | /* | ||
| 673 | * Check if our queue is stopped. Since we have the LLTX bit | ||
| 674 | * set, we can't rely on netif_stop_queue() preventing our | ||
| 675 | * xmit function from being called with a full queue. | ||
| 676 | */ | ||
| 677 | if (unlikely(netif_queue_stopped(dev))) { | ||
| 678 | spin_unlock_irqrestore(&priv->tx_lock, flags); | ||
| 679 | return NETDEV_TX_BUSY; | ||
| 680 | } | ||
| 681 | |||
| 682 | if (likely(skb->dst && skb->dst->neighbour)) { | 675 | if (likely(skb->dst && skb->dst->neighbour)) { |
| 683 | if (unlikely(!*to_ipoib_neigh(skb->dst->neighbour))) { | 676 | if (unlikely(!*to_ipoib_neigh(skb->dst->neighbour))) { |
| 684 | ipoib_path_lookup(skb, dev); | 677 | ipoib_path_lookup(skb, dev); |
| @@ -950,34 +943,34 @@ static void ipoib_setup(struct net_device *dev) | |||
| 950 | { | 943 | { |
| 951 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 944 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 952 | 945 | ||
| 953 | dev->open = ipoib_open; | 946 | dev->open = ipoib_open; |
| 954 | dev->stop = ipoib_stop; | 947 | dev->stop = ipoib_stop; |
| 955 | dev->change_mtu = ipoib_change_mtu; | 948 | dev->change_mtu = ipoib_change_mtu; |
| 956 | dev->hard_start_xmit = ipoib_start_xmit; | 949 | dev->hard_start_xmit = ipoib_start_xmit; |
| 957 | dev->tx_timeout = ipoib_timeout; | 950 | dev->tx_timeout = ipoib_timeout; |
| 958 | dev->header_ops = &ipoib_header_ops; | 951 | dev->header_ops = &ipoib_header_ops; |
| 959 | dev->set_multicast_list = ipoib_set_mcast_list; | 952 | dev->set_multicast_list = ipoib_set_mcast_list; |
| 960 | dev->neigh_setup = ipoib_neigh_setup_dev; | 953 | dev->neigh_setup = ipoib_neigh_setup_dev; |
| 961 | 954 | ||
| 962 | netif_napi_add(dev, &priv->napi, ipoib_poll, 100); | 955 | netif_napi_add(dev, &priv->napi, ipoib_poll, 100); |
| 963 | 956 | ||
| 964 | dev->watchdog_timeo = HZ; | 957 | dev->watchdog_timeo = HZ; |
| 965 | 958 | ||
| 966 | dev->flags |= IFF_BROADCAST | IFF_MULTICAST; | 959 | dev->flags |= IFF_BROADCAST | IFF_MULTICAST; |
| 967 | 960 | ||
| 968 | /* | 961 | /* |
| 969 | * We add in INFINIBAND_ALEN to allow for the destination | 962 | * We add in INFINIBAND_ALEN to allow for the destination |
| 970 | * address "pseudoheader" for skbs without neighbour struct. | 963 | * address "pseudoheader" for skbs without neighbour struct. |
| 971 | */ | 964 | */ |
| 972 | dev->hard_header_len = IPOIB_ENCAP_LEN + INFINIBAND_ALEN; | 965 | dev->hard_header_len = IPOIB_ENCAP_LEN + INFINIBAND_ALEN; |
| 973 | dev->addr_len = INFINIBAND_ALEN; | 966 | dev->addr_len = INFINIBAND_ALEN; |
| 974 | dev->type = ARPHRD_INFINIBAND; | 967 | dev->type = ARPHRD_INFINIBAND; |
| 975 | dev->tx_queue_len = ipoib_sendq_size * 2; | 968 | dev->tx_queue_len = ipoib_sendq_size * 2; |
| 976 | dev->features = NETIF_F_VLAN_CHALLENGED | NETIF_F_LLTX; | 969 | dev->features = NETIF_F_VLAN_CHALLENGED | NETIF_F_LLTX; |
| 977 | 970 | ||
| 978 | /* MTU will be reset when mcast join happens */ | 971 | /* MTU will be reset when mcast join happens */ |
| 979 | dev->mtu = IPOIB_PACKET_SIZE - IPOIB_ENCAP_LEN; | 972 | dev->mtu = IPOIB_PACKET_SIZE - IPOIB_ENCAP_LEN; |
| 980 | priv->mcast_mtu = priv->admin_mtu = dev->mtu; | 973 | priv->mcast_mtu = priv->admin_mtu = dev->mtu; |
| 981 | 974 | ||
| 982 | memcpy(dev->broadcast, ipv4_bcast_addr, INFINIBAND_ALEN); | 975 | memcpy(dev->broadcast, ipv4_bcast_addr, INFINIBAND_ALEN); |
| 983 | 976 | ||
| @@ -1268,6 +1261,9 @@ static int __init ipoib_init_module(void) | |||
| 1268 | ipoib_sendq_size = roundup_pow_of_two(ipoib_sendq_size); | 1261 | ipoib_sendq_size = roundup_pow_of_two(ipoib_sendq_size); |
| 1269 | ipoib_sendq_size = min(ipoib_sendq_size, IPOIB_MAX_QUEUE_SIZE); | 1262 | ipoib_sendq_size = min(ipoib_sendq_size, IPOIB_MAX_QUEUE_SIZE); |
| 1270 | ipoib_sendq_size = max(ipoib_sendq_size, IPOIB_MIN_QUEUE_SIZE); | 1263 | ipoib_sendq_size = max(ipoib_sendq_size, IPOIB_MIN_QUEUE_SIZE); |
| 1264 | #ifdef CONFIG_INFINIBAND_IPOIB_CM | ||
| 1265 | ipoib_max_conn_qp = min(ipoib_max_conn_qp, IPOIB_CM_MAX_CONN_QP); | ||
| 1266 | #endif | ||
| 1271 | 1267 | ||
| 1272 | ret = ipoib_register_debugfs(); | 1268 | ret = ipoib_register_debugfs(); |
| 1273 | if (ret) | 1269 | if (ret) |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 9bcfc7ad6aa6..2628339e3a99 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
| @@ -702,7 +702,7 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb) | |||
| 702 | 702 | ||
| 703 | out: | 703 | out: |
| 704 | if (mcast && mcast->ah) { | 704 | if (mcast && mcast->ah) { |
| 705 | if (skb->dst && | 705 | if (skb->dst && |
| 706 | skb->dst->neighbour && | 706 | skb->dst->neighbour && |
| 707 | !*to_ipoib_neigh(skb->dst->neighbour)) { | 707 | !*to_ipoib_neigh(skb->dst->neighbour)) { |
| 708 | struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb->dst->neighbour, | 708 | struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb->dst->neighbour, |
| @@ -710,7 +710,7 @@ out: | |||
| 710 | 710 | ||
| 711 | if (neigh) { | 711 | if (neigh) { |
| 712 | kref_get(&mcast->ah->ref); | 712 | kref_get(&mcast->ah->ref); |
| 713 | neigh->ah = mcast->ah; | 713 | neigh->ah = mcast->ah; |
| 714 | list_add_tail(&neigh->list, &mcast->neigh_list); | 714 | list_add_tail(&neigh->list, &mcast->neigh_list); |
| 715 | } | 715 | } |
| 716 | } | 716 | } |
| @@ -788,10 +788,6 @@ void ipoib_mcast_restart_task(struct work_struct *work) | |||
| 788 | 788 | ||
| 789 | memcpy(mgid.raw, mclist->dmi_addr + 4, sizeof mgid); | 789 | memcpy(mgid.raw, mclist->dmi_addr + 4, sizeof mgid); |
| 790 | 790 | ||
| 791 | /* Add in the P_Key */ | ||
| 792 | mgid.raw[4] = (priv->pkey >> 8) & 0xff; | ||
| 793 | mgid.raw[5] = priv->pkey & 0xff; | ||
| 794 | |||
| 795 | mcast = __ipoib_mcast_find(dev, &mgid); | 791 | mcast = __ipoib_mcast_find(dev, &mgid); |
| 796 | if (!mcast || test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) { | 792 | if (!mcast || test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) { |
| 797 | struct ipoib_mcast *nmcast; | 793 | struct ipoib_mcast *nmcast; |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 3c6e45db0ab5..433e99ac227b 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c | |||
| @@ -172,8 +172,12 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca) | |||
| 172 | 172 | ||
| 173 | size = ipoib_sendq_size + ipoib_recvq_size + 1; | 173 | size = ipoib_sendq_size + ipoib_recvq_size + 1; |
| 174 | ret = ipoib_cm_dev_init(dev); | 174 | ret = ipoib_cm_dev_init(dev); |
| 175 | if (!ret) | 175 | if (!ret) { |
| 176 | size += ipoib_recvq_size + 1 /* 1 extra for rx_drain_qp */; | 176 | if (ipoib_cm_has_srq(dev)) |
| 177 | size += ipoib_recvq_size + 1; /* 1 extra for rx_drain_qp */ | ||
| 178 | else | ||
| 179 | size += ipoib_recvq_size * ipoib_max_conn_qp; | ||
| 180 | } | ||
| 177 | 181 | ||
| 178 | priv->cq = ib_create_cq(priv->ca, ipoib_ib_completion, NULL, dev, size, 0); | 182 | priv->cq = ib_create_cq(priv->ca, ipoib_ib_completion, NULL, dev, size, 0); |
| 179 | if (IS_ERR(priv->cq)) { | 183 | if (IS_ERR(priv->cq)) { |
| @@ -197,12 +201,12 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca) | |||
| 197 | priv->dev->dev_addr[2] = (priv->qp->qp_num >> 8) & 0xff; | 201 | priv->dev->dev_addr[2] = (priv->qp->qp_num >> 8) & 0xff; |
| 198 | priv->dev->dev_addr[3] = (priv->qp->qp_num ) & 0xff; | 202 | priv->dev->dev_addr[3] = (priv->qp->qp_num ) & 0xff; |
| 199 | 203 | ||
| 200 | priv->tx_sge.lkey = priv->mr->lkey; | 204 | priv->tx_sge.lkey = priv->mr->lkey; |
| 201 | 205 | ||
| 202 | priv->tx_wr.opcode = IB_WR_SEND; | 206 | priv->tx_wr.opcode = IB_WR_SEND; |
| 203 | priv->tx_wr.sg_list = &priv->tx_sge; | 207 | priv->tx_wr.sg_list = &priv->tx_sge; |
| 204 | priv->tx_wr.num_sge = 1; | 208 | priv->tx_wr.num_sge = 1; |
| 205 | priv->tx_wr.send_flags = IB_SEND_SIGNALED; | 209 | priv->tx_wr.send_flags = IB_SEND_SIGNALED; |
| 206 | 210 | ||
| 207 | return 0; | 211 | return 0; |
| 208 | 212 | ||
diff --git a/drivers/infiniband/ulp/iser/Kconfig b/drivers/infiniband/ulp/iser/Kconfig index fe604c8d2996..77dedba829e6 100644 --- a/drivers/infiniband/ulp/iser/Kconfig +++ b/drivers/infiniband/ulp/iser/Kconfig | |||
| @@ -8,5 +8,5 @@ config INFINIBAND_ISER | |||
| 8 | that speak iSCSI over iSER over InfiniBand. | 8 | that speak iSCSI over iSER over InfiniBand. |
| 9 | 9 | ||
| 10 | The iSER protocol is defined by IETF. | 10 | The iSER protocol is defined by IETF. |
| 11 | See <http://www.ietf.org/internet-drafts/draft-ietf-ips-iser-05.txt> | 11 | See <http://www.ietf.org/rfc/rfc5046.txt> |
| 12 | and <http://www.infinibandta.org/members/spec/iser_annex_060418.pdf> | 12 | and <http://www.infinibandta.org/members/spec/Annex_iSER.PDF> |
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index bad8dacafd10..dfa5a4544187 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c | |||
| @@ -551,6 +551,7 @@ static struct scsi_host_template iscsi_iser_sht = { | |||
| 551 | .module = THIS_MODULE, | 551 | .module = THIS_MODULE, |
| 552 | .name = "iSCSI Initiator over iSER, v." DRV_VER, | 552 | .name = "iSCSI Initiator over iSER, v." DRV_VER, |
| 553 | .queuecommand = iscsi_queuecommand, | 553 | .queuecommand = iscsi_queuecommand, |
| 554 | .change_queue_depth = iscsi_change_queue_depth, | ||
| 554 | .can_queue = ISCSI_DEF_XMIT_CMDS_MAX - 1, | 555 | .can_queue = ISCSI_DEF_XMIT_CMDS_MAX - 1, |
| 555 | .sg_tablesize = ISCSI_ISER_SG_TABLESIZE, | 556 | .sg_tablesize = ISCSI_ISER_SG_TABLESIZE, |
| 556 | .max_sectors = 1024, | 557 | .max_sectors = 1024, |
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c index a6f2303ed14a..ba1b455949c0 100644 --- a/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/drivers/infiniband/ulp/iser/iser_initiator.c | |||
| @@ -561,7 +561,7 @@ void iser_rcv_completion(struct iser_desc *rx_desc, | |||
| 561 | if (opcode == ISCSI_OP_SCSI_CMD_RSP) { | 561 | if (opcode == ISCSI_OP_SCSI_CMD_RSP) { |
| 562 | itt = get_itt(hdr->itt); /* mask out cid and age bits */ | 562 | itt = get_itt(hdr->itt); /* mask out cid and age bits */ |
| 563 | if (!(itt < session->cmds_max)) | 563 | if (!(itt < session->cmds_max)) |
| 564 | iser_err("itt can't be matched to task!!!" | 564 | iser_err("itt can't be matched to task!!! " |
| 565 | "conn %p opcode %d cmds_max %d itt %d\n", | 565 | "conn %p opcode %d cmds_max %d itt %d\n", |
| 566 | conn->iscsi_conn,opcode,session->cmds_max,itt); | 566 | conn->iscsi_conn,opcode,session->cmds_max,itt); |
| 567 | /* use the mapping given with the cmds array indexed by itt */ | 567 | /* use the mapping given with the cmds array indexed by itt */ |
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index 654a4dce0236..714b8db02b29 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c | |||
| @@ -105,7 +105,7 @@ pd_err: | |||
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | /** | 107 | /** |
| 108 | * iser_free_device_ib_res - destory/dealloc/dereg the DMA MR, | 108 | * iser_free_device_ib_res - destroy/dealloc/dereg the DMA MR, |
| 109 | * CQ and PD created with the device associated with the adapator. | 109 | * CQ and PD created with the device associated with the adapator. |
| 110 | */ | 110 | */ |
| 111 | static void iser_free_device_ib_res(struct iser_device *device) | 111 | static void iser_free_device_ib_res(struct iser_device *device) |
| @@ -475,13 +475,11 @@ static int iser_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *eve | |||
| 475 | iser_disconnected_handler(cma_id); | 475 | iser_disconnected_handler(cma_id); |
| 476 | break; | 476 | break; |
| 477 | case RDMA_CM_EVENT_DEVICE_REMOVAL: | 477 | case RDMA_CM_EVENT_DEVICE_REMOVAL: |
| 478 | iser_err("Device removal is currently unsupported\n"); | ||
| 478 | BUG(); | 479 | BUG(); |
| 479 | break; | 480 | break; |
| 480 | case RDMA_CM_EVENT_CONNECT_RESPONSE: | ||
| 481 | BUG(); | ||
| 482 | break; | ||
| 483 | case RDMA_CM_EVENT_CONNECT_REQUEST: | ||
| 484 | default: | 481 | default: |
| 482 | iser_err("Unexpected RDMA CM event (%d)\n", event->event); | ||
| 485 | break; | 483 | break; |
| 486 | } | 484 | } |
| 487 | return ret; | 485 | return ret; |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index bdb6f8517401..f2d2c7e2c76b 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
| @@ -272,7 +272,8 @@ static void srp_path_rec_completion(int status, | |||
| 272 | 272 | ||
| 273 | target->status = status; | 273 | target->status = status; |
| 274 | if (status) | 274 | if (status) |
| 275 | printk(KERN_ERR PFX "Got failed path rec status %d\n", status); | 275 | shost_printk(KERN_ERR, target->scsi_host, |
| 276 | PFX "Got failed path rec status %d\n", status); | ||
| 276 | else | 277 | else |
| 277 | target->path = *pathrec; | 278 | target->path = *pathrec; |
| 278 | complete(&target->done); | 279 | complete(&target->done); |
| @@ -303,7 +304,8 @@ static int srp_lookup_path(struct srp_target_port *target) | |||
| 303 | wait_for_completion(&target->done); | 304 | wait_for_completion(&target->done); |
| 304 | 305 | ||
| 305 | if (target->status < 0) | 306 | if (target->status < 0) |
| 306 | printk(KERN_WARNING PFX "Path record query failed\n"); | 307 | shost_printk(KERN_WARNING, target->scsi_host, |
| 308 | PFX "Path record query failed\n"); | ||
| 307 | 309 | ||
| 308 | return target->status; | 310 | return target->status; |
| 309 | } | 311 | } |
| @@ -379,9 +381,10 @@ static int srp_send_req(struct srp_target_port *target) | |||
| 379 | * the second 8 bytes to the local node GUID. | 381 | * the second 8 bytes to the local node GUID. |
| 380 | */ | 382 | */ |
| 381 | if (srp_target_is_topspin(target)) { | 383 | if (srp_target_is_topspin(target)) { |
| 382 | printk(KERN_DEBUG PFX "Topspin/Cisco initiator port ID workaround " | 384 | shost_printk(KERN_DEBUG, target->scsi_host, |
| 383 | "activated for target GUID %016llx\n", | 385 | PFX "Topspin/Cisco initiator port ID workaround " |
| 384 | (unsigned long long) be64_to_cpu(target->ioc_guid)); | 386 | "activated for target GUID %016llx\n", |
| 387 | (unsigned long long) be64_to_cpu(target->ioc_guid)); | ||
| 385 | memset(req->priv.initiator_port_id, 0, 8); | 388 | memset(req->priv.initiator_port_id, 0, 8); |
| 386 | memcpy(req->priv.initiator_port_id + 8, | 389 | memcpy(req->priv.initiator_port_id + 8, |
| 387 | &target->srp_host->dev->dev->node_guid, 8); | 390 | &target->srp_host->dev->dev->node_guid, 8); |
| @@ -400,7 +403,8 @@ static void srp_disconnect_target(struct srp_target_port *target) | |||
| 400 | 403 | ||
| 401 | init_completion(&target->done); | 404 | init_completion(&target->done); |
| 402 | if (ib_send_cm_dreq(target->cm_id, NULL, 0)) { | 405 | if (ib_send_cm_dreq(target->cm_id, NULL, 0)) { |
| 403 | printk(KERN_DEBUG PFX "Sending CM DREQ failed\n"); | 406 | shost_printk(KERN_DEBUG, target->scsi_host, |
| 407 | PFX "Sending CM DREQ failed\n"); | ||
| 404 | return; | 408 | return; |
| 405 | } | 409 | } |
| 406 | wait_for_completion(&target->done); | 410 | wait_for_completion(&target->done); |
| @@ -568,7 +572,8 @@ static int srp_reconnect_target(struct srp_target_port *target) | |||
| 568 | return ret; | 572 | return ret; |
| 569 | 573 | ||
| 570 | err: | 574 | err: |
| 571 | printk(KERN_ERR PFX "reconnect failed (%d), removing target port.\n", ret); | 575 | shost_printk(KERN_ERR, target->scsi_host, |
| 576 | PFX "reconnect failed (%d), removing target port.\n", ret); | ||
| 572 | 577 | ||
| 573 | /* | 578 | /* |
| 574 | * We couldn't reconnect, so kill our target port off. | 579 | * We couldn't reconnect, so kill our target port off. |
| @@ -683,8 +688,9 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target, | |||
| 683 | 688 | ||
| 684 | if (scmnd->sc_data_direction != DMA_FROM_DEVICE && | 689 | if (scmnd->sc_data_direction != DMA_FROM_DEVICE && |
| 685 | scmnd->sc_data_direction != DMA_TO_DEVICE) { | 690 | scmnd->sc_data_direction != DMA_TO_DEVICE) { |
| 686 | printk(KERN_WARNING PFX "Unhandled data direction %d\n", | 691 | shost_printk(KERN_WARNING, target->scsi_host, |
| 687 | scmnd->sc_data_direction); | 692 | PFX "Unhandled data direction %d\n", |
| 693 | scmnd->sc_data_direction); | ||
| 688 | return -EINVAL; | 694 | return -EINVAL; |
| 689 | } | 695 | } |
| 690 | 696 | ||
| @@ -786,8 +792,9 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) | |||
| 786 | } else { | 792 | } else { |
| 787 | scmnd = req->scmnd; | 793 | scmnd = req->scmnd; |
| 788 | if (!scmnd) | 794 | if (!scmnd) |
| 789 | printk(KERN_ERR "Null scmnd for RSP w/tag %016llx\n", | 795 | shost_printk(KERN_ERR, target->scsi_host, |
| 790 | (unsigned long long) rsp->tag); | 796 | "Null scmnd for RSP w/tag %016llx\n", |
| 797 | (unsigned long long) rsp->tag); | ||
| 791 | scmnd->result = rsp->status; | 798 | scmnd->result = rsp->status; |
| 792 | 799 | ||
| 793 | if (rsp->flags & SRP_RSP_FLAG_SNSVALID) { | 800 | if (rsp->flags & SRP_RSP_FLAG_SNSVALID) { |
| @@ -831,7 +838,8 @@ static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) | |||
| 831 | if (0) { | 838 | if (0) { |
| 832 | int i; | 839 | int i; |
| 833 | 840 | ||
| 834 | printk(KERN_ERR PFX "recv completion, opcode 0x%02x\n", opcode); | 841 | shost_printk(KERN_ERR, target->scsi_host, |
| 842 | PFX "recv completion, opcode 0x%02x\n", opcode); | ||
| 835 | 843 | ||
| 836 | for (i = 0; i < wc->byte_len; ++i) { | 844 | for (i = 0; i < wc->byte_len; ++i) { |
| 837 | if (i % 8 == 0) | 845 | if (i % 8 == 0) |
| @@ -852,11 +860,13 @@ static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) | |||
| 852 | 860 | ||
| 853 | case SRP_T_LOGOUT: | 861 | case SRP_T_LOGOUT: |
| 854 | /* XXX Handle target logout */ | 862 | /* XXX Handle target logout */ |
| 855 | printk(KERN_WARNING PFX "Got target logout request\n"); | 863 | shost_printk(KERN_WARNING, target->scsi_host, |
| 864 | PFX "Got target logout request\n"); | ||
| 856 | break; | 865 | break; |
| 857 | 866 | ||
| 858 | default: | 867 | default: |
| 859 | printk(KERN_WARNING PFX "Unhandled SRP opcode 0x%02x\n", opcode); | 868 | shost_printk(KERN_WARNING, target->scsi_host, |
| 869 | PFX "Unhandled SRP opcode 0x%02x\n", opcode); | ||
| 860 | break; | 870 | break; |
| 861 | } | 871 | } |
| 862 | 872 | ||
| @@ -872,9 +882,10 @@ static void srp_completion(struct ib_cq *cq, void *target_ptr) | |||
| 872 | ib_req_notify_cq(cq, IB_CQ_NEXT_COMP); | 882 | ib_req_notify_cq(cq, IB_CQ_NEXT_COMP); |
| 873 | while (ib_poll_cq(cq, 1, &wc) > 0) { | 883 | while (ib_poll_cq(cq, 1, &wc) > 0) { |
| 874 | if (wc.status) { | 884 | if (wc.status) { |
| 875 | printk(KERN_ERR PFX "failed %s status %d\n", | 885 | shost_printk(KERN_ERR, target->scsi_host, |
| 876 | wc.wr_id & SRP_OP_RECV ? "receive" : "send", | 886 | PFX "failed %s status %d\n", |
| 877 | wc.status); | 887 | wc.wr_id & SRP_OP_RECV ? "receive" : "send", |
| 888 | wc.status); | ||
| 878 | target->qp_in_error = 1; | 889 | target->qp_in_error = 1; |
| 879 | break; | 890 | break; |
| 880 | } | 891 | } |
| @@ -930,13 +941,18 @@ static int srp_post_recv(struct srp_target_port *target) | |||
| 930 | * req_lim and tx_head. Lock cannot be dropped between call here and | 941 | * req_lim and tx_head. Lock cannot be dropped between call here and |
| 931 | * call to __srp_post_send(). | 942 | * call to __srp_post_send(). |
| 932 | */ | 943 | */ |
| 933 | static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target) | 944 | static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target, |
| 945 | enum srp_request_type req_type) | ||
| 934 | { | 946 | { |
| 947 | s32 min = (req_type == SRP_REQ_TASK_MGMT) ? 1 : 2; | ||
| 948 | |||
| 935 | if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE) | 949 | if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE) |
| 936 | return NULL; | 950 | return NULL; |
| 937 | 951 | ||
| 938 | if (unlikely(target->req_lim < 1)) | 952 | if (target->req_lim < min) { |
| 939 | ++target->zero_req_lim; | 953 | ++target->zero_req_lim; |
| 954 | return NULL; | ||
| 955 | } | ||
| 940 | 956 | ||
| 941 | return target->tx_ring[target->tx_head & SRP_SQ_SIZE]; | 957 | return target->tx_ring[target->tx_head & SRP_SQ_SIZE]; |
| 942 | } | 958 | } |
| @@ -993,7 +1009,7 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd, | |||
| 993 | return 0; | 1009 | return 0; |
| 994 | } | 1010 | } |
| 995 | 1011 | ||
| 996 | iu = __srp_get_tx_iu(target); | 1012 | iu = __srp_get_tx_iu(target, SRP_REQ_NORMAL); |
| 997 | if (!iu) | 1013 | if (!iu) |
| 998 | goto err; | 1014 | goto err; |
| 999 | 1015 | ||
| @@ -1022,12 +1038,13 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd, | |||
| 1022 | 1038 | ||
| 1023 | len = srp_map_data(scmnd, target, req); | 1039 | len = srp_map_data(scmnd, target, req); |
| 1024 | if (len < 0) { | 1040 | if (len < 0) { |
| 1025 | printk(KERN_ERR PFX "Failed to map data\n"); | 1041 | shost_printk(KERN_ERR, target->scsi_host, |
| 1042 | PFX "Failed to map data\n"); | ||
| 1026 | goto err; | 1043 | goto err; |
| 1027 | } | 1044 | } |
| 1028 | 1045 | ||
| 1029 | if (__srp_post_recv(target)) { | 1046 | if (__srp_post_recv(target)) { |
| 1030 | printk(KERN_ERR PFX "Recv failed\n"); | 1047 | shost_printk(KERN_ERR, target->scsi_host, PFX "Recv failed\n"); |
| 1031 | goto err_unmap; | 1048 | goto err_unmap; |
| 1032 | } | 1049 | } |
| 1033 | 1050 | ||
| @@ -1035,7 +1052,7 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd, | |||
| 1035 | DMA_TO_DEVICE); | 1052 | DMA_TO_DEVICE); |
| 1036 | 1053 | ||
| 1037 | if (__srp_post_send(target, iu, len)) { | 1054 | if (__srp_post_send(target, iu, len)) { |
| 1038 | printk(KERN_ERR PFX "Send failed\n"); | 1055 | shost_printk(KERN_ERR, target->scsi_host, PFX "Send failed\n"); |
| 1039 | goto err_unmap; | 1056 | goto err_unmap; |
| 1040 | } | 1057 | } |
| 1041 | 1058 | ||
| @@ -1090,6 +1107,7 @@ static void srp_cm_rej_handler(struct ib_cm_id *cm_id, | |||
| 1090 | struct ib_cm_event *event, | 1107 | struct ib_cm_event *event, |
| 1091 | struct srp_target_port *target) | 1108 | struct srp_target_port *target) |
| 1092 | { | 1109 | { |
| 1110 | struct Scsi_Host *shost = target->scsi_host; | ||
| 1093 | struct ib_class_port_info *cpi; | 1111 | struct ib_class_port_info *cpi; |
| 1094 | int opcode; | 1112 | int opcode; |
| 1095 | 1113 | ||
| @@ -1115,19 +1133,22 @@ static void srp_cm_rej_handler(struct ib_cm_id *cm_id, | |||
| 1115 | memcpy(target->path.dgid.raw, | 1133 | memcpy(target->path.dgid.raw, |
| 1116 | event->param.rej_rcvd.ari, 16); | 1134 | event->param.rej_rcvd.ari, 16); |
| 1117 | 1135 | ||
| 1118 | printk(KERN_DEBUG PFX "Topspin/Cisco redirect to target port GID %016llx%016llx\n", | 1136 | shost_printk(KERN_DEBUG, shost, |
| 1119 | (unsigned long long) be64_to_cpu(target->path.dgid.global.subnet_prefix), | 1137 | PFX "Topspin/Cisco redirect to target port GID %016llx%016llx\n", |
| 1120 | (unsigned long long) be64_to_cpu(target->path.dgid.global.interface_id)); | 1138 | (unsigned long long) be64_to_cpu(target->path.dgid.global.subnet_prefix), |
| 1139 | (unsigned long long) be64_to_cpu(target->path.dgid.global.interface_id)); | ||
| 1121 | 1140 | ||
| 1122 | target->status = SRP_PORT_REDIRECT; | 1141 | target->status = SRP_PORT_REDIRECT; |
| 1123 | } else { | 1142 | } else { |
| 1124 | printk(KERN_WARNING " REJ reason: IB_CM_REJ_PORT_REDIRECT\n"); | 1143 | shost_printk(KERN_WARNING, shost, |
| 1144 | " REJ reason: IB_CM_REJ_PORT_REDIRECT\n"); | ||
| 1125 | target->status = -ECONNRESET; | 1145 | target->status = -ECONNRESET; |
| 1126 | } | 1146 | } |
| 1127 | break; | 1147 | break; |
| 1128 | 1148 | ||
| 1129 | case IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID: | 1149 | case IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID: |
| 1130 | printk(KERN_WARNING " REJ reason: IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID\n"); | 1150 | shost_printk(KERN_WARNING, shost, |
| 1151 | " REJ reason: IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID\n"); | ||
| 1131 | target->status = -ECONNRESET; | 1152 | target->status = -ECONNRESET; |
| 1132 | break; | 1153 | break; |
| 1133 | 1154 | ||
| @@ -1138,20 +1159,21 @@ static void srp_cm_rej_handler(struct ib_cm_id *cm_id, | |||
| 1138 | u32 reason = be32_to_cpu(rej->reason); | 1159 | u32 reason = be32_to_cpu(rej->reason); |
| 1139 | 1160 | ||
| 1140 | if (reason == SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE) | 1161 | if (reason == SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE) |
| 1141 | printk(KERN_WARNING PFX | 1162 | shost_printk(KERN_WARNING, shost, |
| 1142 | "SRP_LOGIN_REJ: requested max_it_iu_len too large\n"); | 1163 | PFX "SRP_LOGIN_REJ: requested max_it_iu_len too large\n"); |
| 1143 | else | 1164 | else |
| 1144 | printk(KERN_WARNING PFX | 1165 | shost_printk(KERN_WARNING, shost, |
| 1145 | "SRP LOGIN REJECTED, reason 0x%08x\n", reason); | 1166 | PFX "SRP LOGIN REJECTED, reason 0x%08x\n", reason); |
| 1146 | } else | 1167 | } else |
| 1147 | printk(KERN_WARNING " REJ reason: IB_CM_REJ_CONSUMER_DEFINED," | 1168 | shost_printk(KERN_WARNING, shost, |
| 1148 | " opcode 0x%02x\n", opcode); | 1169 | " REJ reason: IB_CM_REJ_CONSUMER_DEFINED," |
| 1170 | " opcode 0x%02x\n", opcode); | ||
| 1149 | target->status = -ECONNRESET; | 1171 | target->status = -ECONNRESET; |
| 1150 | break; | 1172 | break; |
| 1151 | 1173 | ||
| 1152 | default: | 1174 | default: |
| 1153 | printk(KERN_WARNING " REJ reason 0x%x\n", | 1175 | shost_printk(KERN_WARNING, shost, " REJ reason 0x%x\n", |
| 1154 | event->param.rej_rcvd.reason); | 1176 | event->param.rej_rcvd.reason); |
| 1155 | target->status = -ECONNRESET; | 1177 | target->status = -ECONNRESET; |
| 1156 | } | 1178 | } |
| 1157 | } | 1179 | } |
| @@ -1166,7 +1188,8 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) | |||
| 1166 | 1188 | ||
| 1167 | switch (event->event) { | 1189 | switch (event->event) { |
| 1168 | case IB_CM_REQ_ERROR: | 1190 | case IB_CM_REQ_ERROR: |
| 1169 | printk(KERN_DEBUG PFX "Sending CM REQ failed\n"); | 1191 | shost_printk(KERN_DEBUG, target->scsi_host, |
| 1192 | PFX "Sending CM REQ failed\n"); | ||
| 1170 | comp = 1; | 1193 | comp = 1; |
| 1171 | target->status = -ECONNRESET; | 1194 | target->status = -ECONNRESET; |
| 1172 | break; | 1195 | break; |
| @@ -1184,7 +1207,8 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) | |||
| 1184 | target->scsi_host->can_queue = min(target->req_lim, | 1207 | target->scsi_host->can_queue = min(target->req_lim, |
| 1185 | target->scsi_host->can_queue); | 1208 | target->scsi_host->can_queue); |
| 1186 | } else { | 1209 | } else { |
| 1187 | printk(KERN_WARNING PFX "Unhandled RSP opcode %#x\n", opcode); | 1210 | shost_printk(KERN_WARNING, target->scsi_host, |
| 1211 | PFX "Unhandled RSP opcode %#x\n", opcode); | ||
| 1188 | target->status = -ECONNRESET; | 1212 | target->status = -ECONNRESET; |
| 1189 | break; | 1213 | break; |
| 1190 | } | 1214 | } |
| @@ -1230,20 +1254,23 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) | |||
| 1230 | break; | 1254 | break; |
| 1231 | 1255 | ||
| 1232 | case IB_CM_REJ_RECEIVED: | 1256 | case IB_CM_REJ_RECEIVED: |
| 1233 | printk(KERN_DEBUG PFX "REJ received\n"); | 1257 | shost_printk(KERN_DEBUG, target->scsi_host, PFX "REJ received\n"); |
| 1234 | comp = 1; | 1258 | comp = 1; |
| 1235 | 1259 | ||
| 1236 | srp_cm_rej_handler(cm_id, event, target); | 1260 | srp_cm_rej_handler(cm_id, event, target); |
| 1237 | break; | 1261 | break; |
| 1238 | 1262 | ||
| 1239 | case IB_CM_DREQ_RECEIVED: | 1263 | case IB_CM_DREQ_RECEIVED: |
| 1240 | printk(KERN_WARNING PFX "DREQ received - connection closed\n"); | 1264 | shost_printk(KERN_WARNING, target->scsi_host, |
| 1265 | PFX "DREQ received - connection closed\n"); | ||
| 1241 | if (ib_send_cm_drep(cm_id, NULL, 0)) | 1266 | if (ib_send_cm_drep(cm_id, NULL, 0)) |
| 1242 | printk(KERN_ERR PFX "Sending CM DREP failed\n"); | 1267 | shost_printk(KERN_ERR, target->scsi_host, |
| 1268 | PFX "Sending CM DREP failed\n"); | ||
| 1243 | break; | 1269 | break; |
| 1244 | 1270 | ||
| 1245 | case IB_CM_TIMEWAIT_EXIT: | 1271 | case IB_CM_TIMEWAIT_EXIT: |
| 1246 | printk(KERN_ERR PFX "connection closed\n"); | 1272 | shost_printk(KERN_ERR, target->scsi_host, |
| 1273 | PFX "connection closed\n"); | ||
| 1247 | 1274 | ||
| 1248 | comp = 1; | 1275 | comp = 1; |
| 1249 | target->status = 0; | 1276 | target->status = 0; |
| @@ -1255,7 +1282,8 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) | |||
| 1255 | break; | 1282 | break; |
| 1256 | 1283 | ||
| 1257 | default: | 1284 | default: |
| 1258 | printk(KERN_WARNING PFX "Unhandled CM event %d\n", event->event); | 1285 | shost_printk(KERN_WARNING, target->scsi_host, |
| 1286 | PFX "Unhandled CM event %d\n", event->event); | ||
| 1259 | break; | 1287 | break; |
| 1260 | } | 1288 | } |
| 1261 | 1289 | ||
| @@ -1283,7 +1311,7 @@ static int srp_send_tsk_mgmt(struct srp_target_port *target, | |||
| 1283 | 1311 | ||
| 1284 | init_completion(&req->done); | 1312 | init_completion(&req->done); |
| 1285 | 1313 | ||
| 1286 | iu = __srp_get_tx_iu(target); | 1314 | iu = __srp_get_tx_iu(target, SRP_REQ_TASK_MGMT); |
| 1287 | if (!iu) | 1315 | if (!iu) |
| 1288 | goto out; | 1316 | goto out; |
| 1289 | 1317 | ||
| @@ -1332,7 +1360,7 @@ static int srp_abort(struct scsi_cmnd *scmnd) | |||
| 1332 | struct srp_request *req; | 1360 | struct srp_request *req; |
| 1333 | int ret = SUCCESS; | 1361 | int ret = SUCCESS; |
| 1334 | 1362 | ||
| 1335 | printk(KERN_ERR "SRP abort called\n"); | 1363 | shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n"); |
| 1336 | 1364 | ||
| 1337 | if (target->qp_in_error) | 1365 | if (target->qp_in_error) |
| 1338 | return FAILED; | 1366 | return FAILED; |
| @@ -1362,7 +1390,7 @@ static int srp_reset_device(struct scsi_cmnd *scmnd) | |||
| 1362 | struct srp_target_port *target = host_to_target(scmnd->device->host); | 1390 | struct srp_target_port *target = host_to_target(scmnd->device->host); |
| 1363 | struct srp_request *req, *tmp; | 1391 | struct srp_request *req, *tmp; |
| 1364 | 1392 | ||
| 1365 | printk(KERN_ERR "SRP reset_device called\n"); | 1393 | shost_printk(KERN_ERR, target->scsi_host, "SRP reset_device called\n"); |
| 1366 | 1394 | ||
| 1367 | if (target->qp_in_error) | 1395 | if (target->qp_in_error) |
| 1368 | return FAILED; | 1396 | return FAILED; |
| @@ -1389,7 +1417,7 @@ static int srp_reset_host(struct scsi_cmnd *scmnd) | |||
| 1389 | struct srp_target_port *target = host_to_target(scmnd->device->host); | 1417 | struct srp_target_port *target = host_to_target(scmnd->device->host); |
| 1390 | int ret = FAILED; | 1418 | int ret = FAILED; |
| 1391 | 1419 | ||
| 1392 | printk(KERN_ERR PFX "SRP reset_host called\n"); | 1420 | shost_printk(KERN_ERR, target->scsi_host, PFX "SRP reset_host called\n"); |
| 1393 | 1421 | ||
| 1394 | if (!srp_reconnect_target(target)) | 1422 | if (!srp_reconnect_target(target)) |
| 1395 | ret = SUCCESS; | 1423 | ret = SUCCESS; |
| @@ -1543,6 +1571,7 @@ static struct scsi_host_template srp_template = { | |||
| 1543 | .this_id = -1, | 1571 | .this_id = -1, |
| 1544 | .cmd_per_lun = SRP_SQ_SIZE, | 1572 | .cmd_per_lun = SRP_SQ_SIZE, |
| 1545 | .use_clustering = ENABLE_CLUSTERING, | 1573 | .use_clustering = ENABLE_CLUSTERING, |
| 1574 | .use_sg_chaining = ENABLE_SG_CHAINING, | ||
| 1546 | .shost_attrs = srp_host_attrs | 1575 | .shost_attrs = srp_host_attrs |
| 1547 | }; | 1576 | }; |
| 1548 | 1577 | ||
| @@ -1814,8 +1843,9 @@ static ssize_t srp_create_target(struct class_device *class_dev, | |||
| 1814 | 1843 | ||
| 1815 | ib_get_cached_gid(host->dev->dev, host->port, 0, &target->path.sgid); | 1844 | ib_get_cached_gid(host->dev->dev, host->port, 0, &target->path.sgid); |
| 1816 | 1845 | ||
| 1817 | printk(KERN_DEBUG PFX "new target: id_ext %016llx ioc_guid %016llx pkey %04x " | 1846 | shost_printk(KERN_DEBUG, target->scsi_host, PFX |
| 1818 | "service_id %016llx dgid %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", | 1847 | "new target: id_ext %016llx ioc_guid %016llx pkey %04x " |
| 1848 | "service_id %016llx dgid %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", | ||
| 1819 | (unsigned long long) be64_to_cpu(target->id_ext), | 1849 | (unsigned long long) be64_to_cpu(target->id_ext), |
| 1820 | (unsigned long long) be64_to_cpu(target->ioc_guid), | 1850 | (unsigned long long) be64_to_cpu(target->ioc_guid), |
| 1821 | be16_to_cpu(target->path.pkey), | 1851 | be16_to_cpu(target->path.pkey), |
| @@ -1842,7 +1872,8 @@ static ssize_t srp_create_target(struct class_device *class_dev, | |||
| 1842 | target->qp_in_error = 0; | 1872 | target->qp_in_error = 0; |
| 1843 | ret = srp_connect_target(target); | 1873 | ret = srp_connect_target(target); |
| 1844 | if (ret) { | 1874 | if (ret) { |
| 1845 | printk(KERN_ERR PFX "Connection failed\n"); | 1875 | shost_printk(KERN_ERR, target->scsi_host, |
| 1876 | PFX "Connection failed\n"); | ||
| 1846 | goto err_cm_id; | 1877 | goto err_cm_id; |
| 1847 | } | 1878 | } |
| 1848 | 1879 | ||
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h index e3573e7038c4..4a3c1f37e4c2 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.h +++ b/drivers/infiniband/ulp/srp/ib_srp.h | |||
| @@ -79,6 +79,11 @@ enum srp_target_state { | |||
| 79 | SRP_TARGET_REMOVED | 79 | SRP_TARGET_REMOVED |
| 80 | }; | 80 | }; |
| 81 | 81 | ||
| 82 | enum srp_request_type { | ||
| 83 | SRP_REQ_NORMAL, | ||
| 84 | SRP_REQ_TASK_MGMT, | ||
| 85 | }; | ||
| 86 | |||
| 82 | struct srp_device { | 87 | struct srp_device { |
| 83 | struct list_head dev_list; | 88 | struct list_head dev_list; |
| 84 | struct ib_device *dev; | 89 | struct ib_device *dev; |
diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c index 50648738d679..535a4461d88c 100644 --- a/drivers/net/mlx4/fw.c +++ b/drivers/net/mlx4/fw.c | |||
| @@ -202,7 +202,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
| 202 | MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_EQ_OFFSET); | 202 | MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_EQ_OFFSET); |
| 203 | dev_cap->reserved_eqs = 1 << (field & 0xf); | 203 | dev_cap->reserved_eqs = 1 << (field & 0xf); |
| 204 | MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_EQ_OFFSET); | 204 | MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_EQ_OFFSET); |
| 205 | dev_cap->max_eqs = 1 << (field & 0x7); | 205 | dev_cap->max_eqs = 1 << (field & 0xf); |
| 206 | MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_MTT_OFFSET); | 206 | MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_MTT_OFFSET); |
| 207 | dev_cap->reserved_mtts = 1 << (field >> 4); | 207 | dev_cap->reserved_mtts = 1 << (field >> 4); |
| 208 | MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MRW_SZ_OFFSET); | 208 | MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MRW_SZ_OFFSET); |
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h index 448eccb20638..b24508abb850 100644 --- a/include/net/if_inet6.h +++ b/include/net/if_inet6.h | |||
| @@ -269,18 +269,21 @@ static inline void ipv6_arcnet_mc_map(const struct in6_addr *addr, char *buf) | |||
| 269 | buf[0] = 0x00; | 269 | buf[0] = 0x00; |
| 270 | } | 270 | } |
| 271 | 271 | ||
| 272 | static inline void ipv6_ib_mc_map(struct in6_addr *addr, char *buf) | 272 | static inline void ipv6_ib_mc_map(const struct in6_addr *addr, |
| 273 | const unsigned char *broadcast, char *buf) | ||
| 273 | { | 274 | { |
| 275 | unsigned char scope = broadcast[5] & 0xF; | ||
| 276 | |||
| 274 | buf[0] = 0; /* Reserved */ | 277 | buf[0] = 0; /* Reserved */ |
| 275 | buf[1] = 0xff; /* Multicast QPN */ | 278 | buf[1] = 0xff; /* Multicast QPN */ |
| 276 | buf[2] = 0xff; | 279 | buf[2] = 0xff; |
| 277 | buf[3] = 0xff; | 280 | buf[3] = 0xff; |
| 278 | buf[4] = 0xff; | 281 | buf[4] = 0xff; |
| 279 | buf[5] = 0x12; /* link local scope */ | 282 | buf[5] = 0x10 | scope; /* scope from broadcast address */ |
| 280 | buf[6] = 0x60; /* IPv6 signature */ | 283 | buf[6] = 0x60; /* IPv6 signature */ |
| 281 | buf[7] = 0x1b; | 284 | buf[7] = 0x1b; |
| 282 | buf[8] = 0; /* P_Key */ | 285 | buf[8] = broadcast[8]; /* P_Key */ |
| 283 | buf[9] = 0; | 286 | buf[9] = broadcast[9]; |
| 284 | memcpy(buf + 10, addr->s6_addr + 6, 10); | 287 | memcpy(buf + 10, addr->s6_addr + 6, 10); |
| 285 | } | 288 | } |
| 286 | #endif | 289 | #endif |
diff --git a/include/net/ip.h b/include/net/ip.h index 840dd91b513b..50c8889b1b8d 100644 --- a/include/net/ip.h +++ b/include/net/ip.h | |||
| @@ -266,20 +266,22 @@ static inline void ip_eth_mc_map(__be32 naddr, char *buf) | |||
| 266 | * Leave P_Key as 0 to be filled in by driver. | 266 | * Leave P_Key as 0 to be filled in by driver. |
| 267 | */ | 267 | */ |
| 268 | 268 | ||
| 269 | static inline void ip_ib_mc_map(__be32 naddr, char *buf) | 269 | static inline void ip_ib_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf) |
| 270 | { | 270 | { |
| 271 | __u32 addr; | 271 | __u32 addr; |
| 272 | unsigned char scope = broadcast[5] & 0xF; | ||
| 273 | |||
| 272 | buf[0] = 0; /* Reserved */ | 274 | buf[0] = 0; /* Reserved */ |
| 273 | buf[1] = 0xff; /* Multicast QPN */ | 275 | buf[1] = 0xff; /* Multicast QPN */ |
| 274 | buf[2] = 0xff; | 276 | buf[2] = 0xff; |
| 275 | buf[3] = 0xff; | 277 | buf[3] = 0xff; |
| 276 | addr = ntohl(naddr); | 278 | addr = ntohl(naddr); |
| 277 | buf[4] = 0xff; | 279 | buf[4] = 0xff; |
| 278 | buf[5] = 0x12; /* link local scope */ | 280 | buf[5] = 0x10 | scope; /* scope from broadcast address */ |
| 279 | buf[6] = 0x40; /* IPv4 signature */ | 281 | buf[6] = 0x40; /* IPv4 signature */ |
| 280 | buf[7] = 0x1b; | 282 | buf[7] = 0x1b; |
| 281 | buf[8] = 0; /* P_Key */ | 283 | buf[8] = broadcast[8]; /* P_Key */ |
| 282 | buf[9] = 0; | 284 | buf[9] = broadcast[9]; |
| 283 | buf[10] = 0; | 285 | buf[10] = 0; |
| 284 | buf[11] = 0; | 286 | buf[11] = 0; |
| 285 | buf[12] = 0; | 287 | buf[12] = 0; |
diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h index 8ec3799e42e1..7228c056b9e9 100644 --- a/include/rdma/ib_mad.h +++ b/include/rdma/ib_mad.h | |||
| @@ -230,7 +230,9 @@ struct ib_class_port_info | |||
| 230 | * @seg_count: The number of RMPP segments allocated for this send. | 230 | * @seg_count: The number of RMPP segments allocated for this send. |
| 231 | * @seg_size: Size of each RMPP segment. | 231 | * @seg_size: Size of each RMPP segment. |
| 232 | * @timeout_ms: Time to wait for a response. | 232 | * @timeout_ms: Time to wait for a response. |
| 233 | * @retries: Number of times to retry a request for a response. | 233 | * @retries: Number of times to retry a request for a response. For MADs |
| 234 | * using RMPP, this applies per window. On completion, returns the number | ||
| 235 | * of retries needed to complete the transfer. | ||
| 234 | * | 236 | * |
| 235 | * Users are responsible for initializing the MAD buffer itself, with the | 237 | * Users are responsible for initializing the MAD buffer itself, with the |
| 236 | * exception of any RMPP header. Additional segment buffer space allocated | 238 | * exception of any RMPP header. Additional segment buffer space allocated |
diff --git a/include/rdma/rdma_user_cm.h b/include/rdma/rdma_user_cm.h index 9749c1b34d00..c55705460b87 100644 --- a/include/rdma/rdma_user_cm.h +++ b/include/rdma/rdma_user_cm.h | |||
| @@ -60,7 +60,8 @@ enum { | |||
| 60 | RDMA_USER_CM_CMD_SET_OPTION, | 60 | RDMA_USER_CM_CMD_SET_OPTION, |
| 61 | RDMA_USER_CM_CMD_NOTIFY, | 61 | RDMA_USER_CM_CMD_NOTIFY, |
| 62 | RDMA_USER_CM_CMD_JOIN_MCAST, | 62 | RDMA_USER_CM_CMD_JOIN_MCAST, |
| 63 | RDMA_USER_CM_CMD_LEAVE_MCAST | 63 | RDMA_USER_CM_CMD_LEAVE_MCAST, |
| 64 | RDMA_USER_CM_CMD_MIGRATE_ID | ||
| 64 | }; | 65 | }; |
| 65 | 66 | ||
| 66 | /* | 67 | /* |
| @@ -230,4 +231,14 @@ struct rdma_ucm_set_option { | |||
| 230 | __u32 optlen; | 231 | __u32 optlen; |
| 231 | }; | 232 | }; |
| 232 | 233 | ||
| 234 | struct rdma_ucm_migrate_id { | ||
| 235 | __u64 response; | ||
| 236 | __u32 id; | ||
| 237 | __u32 fd; | ||
| 238 | }; | ||
| 239 | |||
| 240 | struct rdma_ucm_migrate_resp { | ||
| 241 | __u32 events_reported; | ||
| 242 | }; | ||
| 243 | |||
| 233 | #endif /* RDMA_USER_CM_H */ | 244 | #endif /* RDMA_USER_CM_H */ |
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 08174a2aa878..54a76b8b803a 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
| @@ -211,7 +211,7 @@ int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir) | |||
| 211 | ip_tr_mc_map(addr, haddr); | 211 | ip_tr_mc_map(addr, haddr); |
| 212 | return 0; | 212 | return 0; |
| 213 | case ARPHRD_INFINIBAND: | 213 | case ARPHRD_INFINIBAND: |
| 214 | ip_ib_mc_map(addr, haddr); | 214 | ip_ib_mc_map(addr, dev->broadcast, haddr); |
| 215 | return 0; | 215 | return 0; |
| 216 | default: | 216 | default: |
| 217 | if (dir) { | 217 | if (dir) { |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 777ed733b2d7..85947eae5bf7 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
| @@ -337,7 +337,7 @@ int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int d | |||
| 337 | ipv6_arcnet_mc_map(addr, buf); | 337 | ipv6_arcnet_mc_map(addr, buf); |
| 338 | return 0; | 338 | return 0; |
| 339 | case ARPHRD_INFINIBAND: | 339 | case ARPHRD_INFINIBAND: |
| 340 | ipv6_ib_mc_map(addr, buf); | 340 | ipv6_ib_mc_map(addr, dev->broadcast, buf); |
| 341 | return 0; | 341 | return 0; |
| 342 | default: | 342 | default: |
| 343 | if (dir) { | 343 | if (dir) { |
